http://linux.bkbits.net/linux-2.5 torvalds@ppc970.osdl.org|ChangeSet|20040626220909|23798 torvalds # This is a BitKeeper generated diff -Nru style patch. # # drivers/scsi/scsiiom.c # 2021/06/14 15:59:00-05:00 g.liakhovetski@gmx.de +1 -1 # tmscsim: 64-bit cleanup # # drivers/pci/hotplug/rpaphp_vio.c # 2004/06/08 15:53:59-07:00 lxiep@us.ibm.com +3 -3 # PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly # # drivers/pci/hotplug/rpaphp_slot.c # 2004/06/08 15:53:59-07:00 lxiep@us.ibm.com +113 -23 # PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly # # drivers/pci/hotplug/rpaphp_pci.c # 2004/06/08 15:53:59-07:00 lxiep@us.ibm.com +228 -100 # PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly # # net/core/dev.c # 2004/06/23 08:05:38-07:00 davem@nuts.davemloft.net +0 -0 # SCCS merged # # net/core/dev.c # 2004/06/22 10:05:28-07:00 torvalds@ppc970.osdl.org +0 -3 # Auto merged # # net/core/dev.c # 2004/06/22 09:28:45-07:00 torvalds@ppc970.osdl.org +3 -4 # Fix C99'ism that breaks older gcc's. # # Also clean it all up - use get_cpu()/put_cpu() instead of # playing games by hand with preemption. # # net/core/dev.c # 2004/06/21 09:32:30-07:00 akm@osdl.org +3 -4 # [NET]: Fix dev_queue_xmit build with older gcc. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/core/dev.c # 2004/06/20 17:35:52-07:00 akepner@sgi.com +40 -15 # [NET]: Lockless loopback patch (version 2). # # net/core/dev.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +81 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/core/dev.c # 2004/06/17 12:11:17-07:00 davem@nuts.davemloft.net +2 -0 # [NET]: In unregister_netdevice(), do synchronize_net() before final dev_put(). # # This way we make sure that all destination cache updates # to remove references to this device are seen by entire # system before final destruction of the device. # # include/linux/sysfs.h # 2004/06/03 10:27:09-07:00 mochel@digitalimplant.org +1 -1 # [sysfs] Add attr_name() macro # # include/linux/sysfs.h # 2004/06/02 17:01:56-07:00 mochel@digitalimplant.org +21 -0 # [Driver Model] Consolidate object attribute definition. # # drivers/base/class.c # 2004/06/10 02:35:56-07:00 greg@kroah.com +18 -18 # Driver Core: more whitespace fixups # # This catches the files I had to do by hand as Dmitry's patch differed from my tree. # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # drivers/base/class.c # 2004/06/03 10:41:22-07:00 mochel@digitalimplant.org +75 -6 # [Driver Model] Add default attributes for classes class devices. # # ChangeSet # 2004/06/26 14:16:14-07:00 torvalds@ppc970.osdl.org # Merge new serial additions # # include/linux/serial_core.h # 2004/06/26 14:16:08-07:00 torvalds@ppc970.osdl.org +1 -1 # Merge new serial additions # # drivers/serial/Kconfig # 2004/06/26 14:16:08-07:00 torvalds@ppc970.osdl.org +0 -0 # Merge new serial additions # # drivers/serial/Makefile # 2004/06/26 14:10:12-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # arch/ppc/Makefile # 2004/06/26 14:10:12-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # arch/ppc/Kconfig # 2004/06/26 14:10:12-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/26 09:06:27-07:00 hch@lst.de # [PATCH] ppc32: fix compilation # # PPC has an out of line and exported abs() that gives lots of nice and # wierd compilation erorrs. Also kill the duplicate cpu_online() in # asm-ppc/smp.h. # # include/asm-ppc/system.h # 2004/06/25 05:51:29-07:00 hch@lst.de +0 -1 # ppc32: fix compilation # # include/asm-ppc/smp.h # 2004/06/25 05:51:47-07:00 hch@lst.de +0 -2 # ppc32: fix compilation # # arch/ppc/kernel/ppc_ksyms.c # 2004/06/25 05:52:53-07:00 hch@lst.de +0 -3 # ppc32: fix compilation # # ChangeSet # 2004/06/26 08:52:06-07:00 torvalds@ppc970.osdl.org # Merge bk://bk.arm.linux.org.uk/linux-2.6-pcmcia # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # drivers/pcmcia/yenta_socket.c # 2004/06/26 08:52:02-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/pcmcia/i82365.c # 2004/06/26 08:52:02-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/ide/legacy/ide-cs.c # 2004/06/26 08:52:02-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/26 14:26:09+01:00 rmk@flint.arm.linux.org.uk # [ARM] Fix SA1100 build after timer changes. # # arch/arm/mach-sa1100/time.c # 2004/06/26 14:23:05+01:00 rmk@flint.arm.linux.org.uk +8 -1 # Add includes for time.c # # arch/arm/mach-sa1100/Makefile # 2004/06/26 14:23:05+01:00 rmk@flint.arm.linux.org.uk +1 -1 # Add time.o # # ChangeSet # 2004/06/26 09:31:02+01:00 rmk@flint.arm.linux.org.uk # [PCMCIA] Fix bogus align value # # 0 is not a valid alignment value for allocate_resource() # # drivers/pcmcia/rsrc_mgr.c # 2004/06/26 09:25:50+01:00 rmk@flint.arm.linux.org.uk +3 -3 # Fix bogus align value # # ChangeSet # 2004/06/25 14:55:04-07:00 miles@mctpc71.ucom.lsi.nec.co.jp # [PATCH] make CONFIG_SYSVIPC depend on CONFIG_MMU # # The sysv-ipc code uses mm/shmem.o, which in turn uses VM stuff and is # only compiled on MMU systems. # # Signed-off-by: Miles Bader # Signed-off-by: Linus Torvalds # # init/Kconfig # 2004/06/24 22:47:26-07:00 miles@mctpc71.ucom.lsi.nec.co.jp +1 -0 # make CONFIG_SYSVIPC depend on CONFIG_MMU # # ChangeSet # 2004/06/25 14:54:53-07:00 miles@mctpc71.ucom.lsi.nec.co.jp # [PATCH] v850: remove bogus __ARCH_WANT_ macro defs # # Signed-off-by: Miles Bader # Signed-off-by: Linus Torvalds # # include/asm-v850/unistd.h # 2004/06/24 21:56:41-07:00 miles@mctpc71.ucom.lsi.nec.co.jp +2 -4 # v850: remove bogus __ARCH_WANT_ macro defs # # ChangeSet # 2004/06/25 14:54:42-07:00 miles@mctpc71.ucom.lsi.nec.co.jp # [PATCH] v850: add find_next_bit # # [Since many archs use the same implementation of find_next_bit, it might # be nice to have `generic_find_next_bit' or something.] # # Signed-off-by: Miles Bader # Signed-off-by: Linus Torvalds # # include/asm-v850/bitops.h # 2004/06/24 22:24:08-07:00 miles@mctpc71.ucom.lsi.nec.co.jp +76 -0 # v850: add find_next_bit # # ChangeSet # 2004/06/25 14:54:31-07:00 miles@mctpc71.ucom.lsi.nec.co.jp # [PATCH] v850: add missing end-of-line backslash to vmlinux.lds.S # # Signed-off-by: Miles Bader # Signed-off-by: Linus Torvalds # # arch/v850/kernel/vmlinux.lds.S # 2004/06/24 01:20:36-07:00 miles@mctpc71.ucom.lsi.nec.co.jp +3 -3 # v850: add missing end-of-line backslash to vmlinux.lds.S # # ChangeSet # 2004/06/25 14:54:20-07:00 miles@mctpc71.ucom.lsi.nec.co.jp # [PATCH] v850: guard declaration of handle_IRQ_event with #ifdef !__ASSEMBLY__ # # Signed-off-by: Miles Bader # Signed-off-by: Linus Torvalds # # include/asm-v850/irq.h # 2004/06/24 01:20:36-07:00 miles@mctpc71.ucom.lsi.nec.co.jp +3 -6 # v850: guard declaration of handle_IRQ_event with #ifdef !__ASSEMBLY__ # # ChangeSet # 2004/06/25 11:34:10-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: limit max_sectors to 256 for PDC20265 # # PDC20265 seems to not like large LBA48 requests. # # Thanks to Adolfo Gonzalez Blazquez for help in debugging this problem. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/pci/pdc202xx_old.c # 2004/06/25 10:03:57-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +6 -0 # ide: limit max_sectors to 256 for PDC20265 # # ChangeSet # 2004/06/25 11:33:59-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: idle disk on resume # # From: Jens Axboe # # I need this patch to survive suspend on my powerbook, if the drive is # sleeping when suspend is entered. Otherwise it freezes on resume when it # tries to read from the drive. # # Acked by Ben. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-disk.c # 2004/06/25 09:49:26-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +13 -2 # ide: idle disk on resume # # ChangeSet # 2004/06/25 11:06:18-07:00 Andries.Brouwer@cwi.nl # [PATCH] isofs fixes # # This fixes two things. # # On the one hand we have the old "cruft" mount option, that sometimes was # enabled automatically, for ridiculously large files or CDROMs. But what # was ridiculous ten years ago, no longer is. So, only decide that # something is cruft when the user said so. # # On the other hand, sometimes we get negative sizes. That is caused by # assignments inode->i_size = isonum_733(), where the latter was declared # integer. I made it unsigned int, as the standard also does. # # (Someone with problems replied: # >> Could you test the below? # > Ok I did, the patch seems to work great! Thanks! # ) # # include/linux/iso_fs.h # 2004/06/24 09:13:00-07:00 Andries.Brouwer@cwi.nl +6 -6 # isofs fixes # # fs/isofs/inode.c # 2004/06/24 09:20:41-07:00 Andries.Brouwer@cwi.nl +3 -20 # isofs fixes # # ChangeSet # 2004/06/25 10:30:07-07:00 davem@nuts.davemloft.net # [SPARC64]: Update defconfig. # # arch/sparc64/defconfig # 2004/06/25 10:29:50-07:00 davem@nuts.davemloft.net +59 -40 # [SPARC64]: Update defconfig. # # ChangeSet # 2004/06/25 10:27:24-07:00 akpm@osdl.org # [SPARC64]: Make ___arch_swapXp() take a const pointer. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # include/asm-sparc64/byteorder.h # 2004/06/25 10:27:10-07:00 akpm@osdl.org +3 -3 # [SPARC64]: Make ___arch_swapXp() take a const pointer. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/25 10:26:12-07:00 akpm@osdl.org # [SPARC64]: Make find_next_bit take a const pointer. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # include/asm-sparc64/bitops.h # 2004/06/25 10:25:58-07:00 akpm@osdl.org +2 -1 # [SPARC64]: Make find_next_bit take a const pointer. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # arch/sparc64/lib/find_bit.c # 2004/06/25 10:25:58-07:00 akpm@osdl.org +3 -2 # [SPARC64]: Make find_next_bit take a const pointer. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/24 16:37:46-07:00 akpm@osdl.org # [PATCH] x86: fix up cpumask breakage # # We can't do # # &some_inline_function(); # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/smpboot.c # 2004/06/24 07:22:55-07:00 akpm@osdl.org +6 -2 # x86: fix up cpumask breakage # # ChangeSet # 2004/06/24 23:07:01+01:00 nico@org.rmk.(none) # [ARM PATCH] 1942/1: basic LCD support for the PXA270/Mainstone board # # Patch from Nicolas Pitre # # This is only basic support so the LCD pannel becomes usable # on Mainstone. No PXA270 specific capabilities were added. # The Mainstone defconfig also updated to enable LCD by default. # # arch/arm/mach-pxa/mainstone.c # 2004/06/22 22:48:10+01:00 nico@org.rmk.(none) +59 -0 # [PATCH] 1942/1: basic LCD support for the PXA270/Mainstone board # # arch/arm/configs/mainstone_defconfig # 2004/06/22 22:50:23+01:00 nico@org.rmk.(none) +27 -56 # [PATCH] 1942/1: basic LCD support for the PXA270/Mainstone board # # ChangeSet # 2004/06/24 13:44:11-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] symlink: fix missing 'depth' initialization # # Now we always care about one part of nameidata --- ->depth. And we need # to make sure it's always initialized. # # generic_readlink() was missing that part. # # fs/namei.c # 2004/06/24 09:07:24-07:00 viro@parcelfarce.linux.theplanet.co.uk +3 -1 # symlink: fix missing 'depth' initialization # # ChangeSet # 2004/06/24 12:45:29-07:00 greg@kroah.com # Merge kroah.com:/home/greg/linux/BK/bleed-2.6 # into kroah.com:/home/greg/linux/BK/pci-2.6 # # include/linux/pci_ids.h # 2004/06/24 12:45:23-07:00 greg@kroah.com +0 -0 # Auto merged # # arch/i386/pci/irq.c # 2004/06/24 12:45:23-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/06/24 12:42:24-07:00 davem@nuts.davemloft.net # [PKT_SCHED]: Fix typo in config help text, noticed by Geert. # # net/sched/Kconfig # 2004/06/24 12:42:06-07:00 davem@nuts.davemloft.net +2 -2 # [PKT_SCHED]: Fix typo in config help text, noticed by Geert. # # ChangeSet # 2004/06/24 12:40:07-07:00 akpm@osdl.org # [PKT_SCHED]: Fix pkt_sched.h warnings. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/sched/sch_tbf.c # 2004/06/24 12:39:52-07:00 akpm@osdl.org +1 -1 # [PKT_SCHED]: Fix pkt_sched.h warnings. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/sched/sch_red.c # 2004/06/24 12:39:52-07:00 akpm@osdl.org +1 -1 # [PKT_SCHED]: Fix pkt_sched.h warnings. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/sched/sch_htb.c # 2004/06/24 12:39:52-07:00 akpm@osdl.org +3 -3 # [PKT_SCHED]: Fix pkt_sched.h warnings. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/sched/sch_gred.c # 2004/06/24 12:39:52-07:00 akpm@osdl.org +2 -2 # [PKT_SCHED]: Fix pkt_sched.h warnings. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/sched/police.c # 2004/06/24 12:39:52-07:00 akpm@osdl.org +2 -2 # [PKT_SCHED]: Fix pkt_sched.h warnings. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/24 12:38:34-07:00 akpm@osdl.org # [NETFILTER]: ip_fw_compat_masq.c needs net/ip.h for IP_OFFSET. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_fw_compat_masq.c # 2004/06/24 12:38:19-07:00 akpm@osdl.org +1 -0 # [NETFILTER]: ip_fw_compat_masq.c needs net/ip.h for IP_OFFSET. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/24 12:37:50-07:00 akpm@osdl.org # [NET]: Fix warning in fc.c # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/802/fc.c # 2004/06/24 12:37:35-07:00 akpm@osdl.org +1 -1 # [NET]: Fix warning in fc.c # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/24 12:37:07-07:00 akpm@osdl.org # [NET]: Fix warning in tr.c # # A few things popped up when using current gcc cvs. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/802/tr.c # 2004/06/24 12:36:53-07:00 akpm@osdl.org +1 -1 # [NET]: Fix warning in tr.c # # A few things popped up when using current gcc cvs. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/24 12:14:03-07:00 davem@nuts.davemloft.net # Merge bk://kernel.bkbits.net/acme/net-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/ipv6/tcp_ipv6.c # 2004/06/24 12:13:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp_input.c # 2004/06/24 12:13:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp.c # 2004/06/24 12:13:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/24 11:57:36-07:00 torvalds@ppc970.osdl.org # Make bitops/cpumask functions be "const" where appropriate. # # include/linux/cpumask.h # 2004/06/24 11:57:31-07:00 torvalds@ppc970.osdl.org +7 -7 # Make bitops/cpumask functions be "const" where appropriate. # # include/linux/byteorder/swab.h # 2004/06/24 11:57:31-07:00 torvalds@ppc970.osdl.org +3 -3 # Make bitops/cpumask functions be "const" where appropriate. # # include/asm-s390/byteorder.h # 2004/06/24 11:57:31-07:00 torvalds@ppc970.osdl.org +3 -3 # Make bitops/cpumask functions be "const" where appropriate. # # include/asm-ppc64/bitops.h # 2004/06/24 11:57:31-07:00 torvalds@ppc970.osdl.org +3 -3 # Make bitops/cpumask functions be "const" where appropriate. # # arch/ppc64/kernel/bitops.c # 2004/06/24 11:57:30-07:00 torvalds@ppc970.osdl.org +6 -6 # Make bitops/cpumask functions be "const" where appropriate. # # ChangeSet # 2004/06/24 10:19:27-07:00 viro@www.linux.org.uk # [PATCH] symlink 9/9: jff2 # # jffs2 switched; leaks plugged. # # fs/jffs2/symlink.c # 2004/06/22 08:13:12-07:00 viro@www.linux.org.uk +14 -26 # symlink 9/9: jff2 # # ChangeSet # 2004/06/24 10:19:16-07:00 viro@www.linux.org.uk # [PATCH] symlink 8/9: befs # # befs switched; leaks plugged. # # fs/befs/linuxvfs.c # 2004/06/22 08:13:11-07:00 viro@www.linux.org.uk +18 -47 # symlink 8/9: befs # # ChangeSet # 2004/06/24 10:19:06-07:00 viro@www.linux.org.uk # [PATCH] symlink 7/9: shmfs # # shm switched (it almost belongs to SL3, but it does some extra stuff # after the link traversal). # # mm/shmem.c # 2004/06/22 08:13:11-07:00 viro@www.linux.org.uk +21 -26 # symlink 7/9: shmfs # # ChangeSet # 2004/06/24 10:18:55-07:00 viro@www.linux.org.uk # [PATCH] symlink 6/9: xfs # # xfs switched to new scheme; leaks plugged. # # fs/xfs/linux-2.6/xfs_iops.c # 2004/06/22 08:13:11-07:00 viro@www.linux.org.uk +20 -11 # symlink 6/9: xfs # # ChangeSet # 2004/06/24 10:18:44-07:00 viro@www.linux.org.uk # [PATCH] symlink 5/9: smbfs # # smbfs - switched from on-stack allocation of buffer for link body (!) to # __getname()/putname(); switched to new scheme. # # fs/smbfs/symlink.c # 2004/06/22 08:13:11-07:00 viro@www.linux.org.uk +25 -24 # symlink 5/9: smbfs # # fs/smbfs/proto.h # 2004/06/22 08:13:11-07:00 viro@www.linux.org.uk +0 -2 # symlink 5/9: smbfs # # ChangeSet # 2004/06/24 10:18:33-07:00 viro@www.linux.org.uk # [PATCH] symlink 4/9: simple filesystems # # cases that can simply reuse ext2 helpers (page_follow_link_light() and # page_put_link()). # # fs/sysv/inode.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -2 # symlink 4/9: simple filesystems # # fs/reiserfs/namei.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -2 # symlink 4/9: simple filesystems # # fs/minix/inode.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -2 # symlink 4/9: simple filesystems # # fs/ext3/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +8 -12 # symlink 4/9: simple filesystems # # fs/coda/cnode.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -2 # symlink 4/9: simple filesystems # # fs/affs/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -2 # symlink 4/9: simple filesystems # # ChangeSet # 2004/06/24 10:18:21-07:00 viro@www.linux.org.uk # [PATCH] symlink 3/9: trivial filesystems # # trivial cases - ones where we have no need to clean up after pathname # traversal (link body embedded into inode, etc.). # # Plugged leak in devfs_follow_link(), while we are at it. # # fs/ufs/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +4 -8 # symlink 3/9: trivial filesystems # # fs/sysv/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +4 -9 # symlink 3/9: trivial filesystems # # fs/proc/generic.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +4 -10 # symlink 3/9: trivial filesystems # # fs/jfs/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +4 -8 # symlink 3/9: trivial filesystems # # fs/freevxfs/vxfs_immed.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +4 -26 # symlink 3/9: trivial filesystems # # fs/devfs/base.c # 2004/06/22 08:17:02-07:00 viro@www.linux.org.uk +4 -22 # symlink 3/9: trivial filesystems # # fs/bad_inode.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -1 # symlink 3/9: trivial filesystems # # fs/autofs4/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -10 # symlink 3/9: trivial filesystems # # fs/autofs/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -8 # symlink 3/9: trivial filesystems # # ChangeSet # 2004/06/24 10:18:10-07:00 viro@www.linux.org.uk # [PATCH] symlink 2/9: ext2 conversion and helper functions # # ext2 conversion (helper functions for that one will be actually # used a lot by other filesystems, so to fs/namei.c they go) # # include/linux/fs.h # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +3 -0 # symlink 2/9: ext2 conversion and helper functions # # fs/namei.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +47 -2 # symlink 2/9: ext2 conversion and helper functions # # fs/ext2/symlink.c # 2004/06/22 08:13:10-07:00 viro@www.linux.org.uk +7 -11 # symlink 2/9: ext2 conversion and helper functions # # ChangeSet # 2004/06/24 10:17:59-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] symlink 1/9: infrastructure and explanation # # This patch-kit gets past the limit on nested symlinks, without # incompatible API changes _and_ with killing code duplication in most of # the readlink/follow_link pairs. And no, it's not the old ->getlink() # crap - procfs et.al. are not special-cased there. # # Here's how it works: # * ->follow_link() still does what it used to do - replaces # vfsmount/dentry in the nameidata it got from caller. However, it can # also leave a pathname to be resolved by caller. # * we add an array of char * into nameidata; we always work with # nd->saved_names[current->link_count]. nd_set_link() sets it, # nd_get_link() returns it. # * callers of ->follow_link() (all two of them) check if ->follow_link() # had left us something to do. If it had (return value was zero and # nd_get_link() is non-NULL), they do __vfs_follow_link() on that name. # Then they call a new method (->put_link()) that frees whatever has to # be freed, etc. # # Note that absolute majority of symlinks have "resolve a pathname" as # part of their ->follow_link(); they can do something else and some don't # do that at all, but having that pathname resolution is very, very # common. # # With that change we allow them to shift pathname resolution part to # caller. They don't have to - it's perfectly OK to do all work in # ->follow_link(). However, leaving the pathname resolution to caller # will # a) exclude foo_follow_link() stack frame from the picture # b) kill 2 stack frames - all callers are in fs/namei.c # and they can use inlined variant of vfs_follow_link(). # # That reduction of stack use is enough to push the limit on nested # symlinks from 5 to 8 (actually, even beyond that, but since 8 is common # for other Unices it will do fine). # # For those who have "pure" ->follow_link() (i.e. "find a string that # would be symlink contents and say nd_set_link(nd, string)") we also get # a common helper implementing ->readlink() - it just calls # ->follow_link() on a dummy nameidata, calls vfs_readlink() on result of # nd_get_link() and does ->put_link(). Using (or not using) it is up to # filesystem; it's a helper that can be used as a ->readlink() for many # filesystems, not a reimplementation of sys_readlink(). However, that's # _MANY_ filesystems - practically all of them. # # Note that we don't put any crap like "if this is a normal symlink, do # this; otherwise call ->follow_link() and let it do its magic" into # callers - all symlinks are handled the same way. Which was the main # problem with getlink proposal back then. # # That covers almost everything; the only cases left are nfs, ncpfs and # cifs. Those will go later - we are backwards compatible, so it's not a # problem. # # First patch: infrastructure - helpers allowing ->follow_link() to leave # a pathname to be traversed by caller + corresponding code in callers. # # include/linux/namei.h # 2004/06/22 08:13:10-07:00 viro@parcelfarce.linux.theplanet.co.uk +14 -0 # symlink 1/9: infrastructure and explanation # # include/linux/fs.h # 2004/06/22 08:13:10-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -0 # symlink 1/9: infrastructure and explanation # # fs/namei.c # 2004/06/22 08:13:10-07:00 viro@parcelfarce.linux.theplanet.co.uk +26 -3 # symlink 1/9: infrastructure and explanation # # ChangeSet # 2004/06/24 10:03:58-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: check_region removal - trm290.c # # Signed-off-by: Jesper Juhl # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/pci/trm290.c # 2004/06/23 15:55:00-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +4 -10 # ide: check_region removal - trm290.c # # ChangeSet # 2004/06/24 10:03:47-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: hpt36x/37x tuning fix # # From: Jonas Thornblad # # There is a problem in the hpt366.c driver where the function # ide_config_drive_speed(drive, speed) is called without using the correct # speed variable. The speed variable should use the value returned by # hpt3xx_ratefilter which decides the speed after checking against the bad # drives list. # # I believe the following patch fixes the problem. # # Slightly reworked by me - Bart. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/pci/hpt366.c # 2004/06/23 15:55:55-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +12 -20 # ide: hpt36x/37x tuning fix # # ChangeSet # 2004/06/24 10:03:36-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: reduce > 3kb call path in ide-cs # # - Reduce large stack usage in ide_config() by using kmalloc(), down # from 0x4a4 bytes to 0x64 bytes (x86-32). # - Little whitespace cleanup. # - Move function comment block to immediately above the function. # # Module loaded and unloaded, otherwise not tested (no hardware). # # Signed-off-by: Randy Dunlap # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/legacy/ide-cs.c # 2004/06/23 15:11:32-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +73 -57 # ide: reduce > 3kb call path in ide-cs # # ChangeSet # 2004/06/24 10:03:24-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: PIO-out setup fixes (CONFIG_IDE_TASKFILE_IO=n) # # - setup hwgroup->handler/timer in ->prehandler() (after checking # drive status) and in do_rw_taskfile() only send a command # - make pre_task_mulout_intr() transfer first data block itself # instead of calling ->handler() so we don't have to play tricks # with hwgroup->handler/timer in task_mulout_intr() # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 18:18:10-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +10 -29 # ide: PIO-out setup fixes (CONFIG_IDE_TASKFILE_IO=n) # # ChangeSet # 2004/06/24 10:03:13-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: use task_buffer[_multi]_sectors() in ide-taskfile.c # # - update rq counters directly in task_buffer_sectors() # - use task_buffer[_multi]_sectors() in taskfile PIO # handlers (CONFIG_IDE_TASKFILE_IO=n and flagged ones) so: # (a) rq->hard_cur_sectors is used for rq mapping # (b) in case of error valid rq->sector is reported # (c) we can s/rq->current_nr_sectors/rq->nr_sectors/ later # - uninline task_buffer_sectors() # - remove not needed !rq->bio code from ide_[un]map_buffer() # (it is used only for fs requests which are always bio based) # - remove no longer needed task_rq_offset() # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # include/linux/ide.h # 2004/06/18 18:03:39-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +2 -18 # ide: use task_buffer[_multi]_sectors() in ide-taskfile.c # # drivers/ide/ide-taskfile.c # 2004/06/18 18:11:58-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +24 -78 # ide: use task_buffer[_multi]_sectors() in ide-taskfile.c # # ChangeSet # 2004/06/24 10:03:02-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: don't clear rq->errors for REQ_DRIVE_TASKFILE requests # # REQ_DRIVE_TASKFILE requests aren't retried so don't clear rq->errors # in CONFIG_IDE_TASKFILE_IO=n PIO handlers and in CONFIG_IDE_TASKFILE_IO=y # PIO handlers clear rq->errors only for fs requests, flagged_* PIO # handlers were already okay. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 18:01:41-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +6 -11 # ide: don't clear rq->errors for REQ_DRIVE_TASKFILE requests # # ChangeSet # 2004/06/24 10:02:51-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: split task_sectors() and task_multi_sectors() # # - split __task_sectors() out of task_sectors() # - add bio and buffer versions of task[_multi]_sectors() # - use task_bio_sectors() instead of task_sectors() in pdc4030.c # - move task[_buffer]_sectors() to ide-taskfile.c # - uninline task[_multi]_sectors() # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # include/linux/ide.h # 2004/06/23 16:28:10-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +13 -23 # ide: split task_sectors() and task_multi_sectors() # # drivers/ide/legacy/pdc4030.c # 2004/06/23 16:08:35-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +2 -2 # ide: split task_sectors() and task_multi_sectors() # # drivers/ide/ide-taskfile.c # 2004/06/23 16:29:20-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +42 -3 # ide: split task_sectors() and task_multi_sectors() # # ChangeSet # 2004/06/24 10:02:40-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: add task_multi_sectors() to ide-taskfile.c # # Move common code from task_mulin_intr() and task_mulout_intr() # (CONFIG_IDE_TASKFILE_IO=y) to a task_multi_sectors() helper. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 17:58:42-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +22 -31 # ide: add task_multi_sectors() to ide-taskfile.c # # ChangeSet # 2004/06/24 10:02:29-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: remove DTF() debugging printks from ide-taskfile.c # # They are off by default and conflict with the future changes. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 17:57:52-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +0 -34 # ide: remove DTF() debugging printks from ide-taskfile.c # # ChangeSet # 2004/06/24 10:02:18-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: last IRQ fix for task_mulout_intr() (CONFIG_IDE_TASKFILE_IO=n) # # We should wait for the last IRQ after all data is sent. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 17:57:14-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +0 -7 # ide: last IRQ fix for task_mulout_intr() (CONFIG_IDE_TASKFILE_IO=n) # # ChangeSet # 2004/06/24 10:02:07-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: check drive->mult_count in flagged_taskfile() # # Check drive->mult_count in flagged_taskfile() and fail request early # if necessary so there is no need to do it later in the PIO handlers. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 17:56:06-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +8 -8 # ide: check drive->mult_count in flagged_taskfile() # # ChangeSet # 2004/06/24 10:01:56-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: PIO-in drive busy fix (CONFIG_IDE_TASKFILE_IO=y) # # If the drive times out the final status check we should fail the request # instead of setting another handler for the next IRQ. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 17:55:05-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +12 -16 # ide: PIO-in drive busy fix (CONFIG_IDE_TASKFILE_IO=y) # # ChangeSet # 2004/06/24 10:01:45-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: end request fix for CONFIG_IDE_TASKFILE_IO=y PIO handlers # # ide_end_drive_cmd() should only be called for "flagged" taskfiles # which have separate PIO handlers so use driver->end_request() instead. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 17:41:30-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +4 -4 # ide: end request fix for CONFIG_IDE_TASKFILE_IO=y PIO handlers # # ChangeSet # 2004/06/24 10:01:34-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide: remove redundant hwgroup->handler checks from ide-taskfile.c # # Remove checks for hwgroup->handler == NULL from task_[in,mulin,out]_intr() # (CONFIG_IDE_TASKFILE_IO=n versions). These functions can be called only from # ide_intr() or ide_timer_expiry() and both set hwgroup->handler to NULL first. # # Signed-off-by: Bartlomiej Zolnierkiewicz # Signed-off-by: Linus Torvalds # # drivers/ide/ide-taskfile.c # 2004/06/18 17:40:55-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +5 -14 # ide: remove redundant hwgroup->handler checks from ide-taskfile.c # # ChangeSet # 2004/06/24 09:56:16-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: scsi ->ioctl() annotation # # Low-level drivers' ->ioctl() gets a userland pointer from scsi_ioctl(); # prototype annotated, so is scsi_debug instance. # # include/scsi/scsi_host.h # 2004/06/22 07:53:36-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: scsi ->ioctl() annotation # # drivers/scsi/scsi_debug.h # 2004/06/22 07:53:16-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: scsi ->ioctl() annotation # # drivers/scsi/scsi_debug.c # 2004/06/22 07:53:21-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: scsi ->ioctl() annotation # # ChangeSet # 2004/06/24 09:56:05-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: trivial i2o annotations # # include/linux/i2o-dev.h # 2004/06/22 07:51:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +13 -13 # sparse: trivial i2o annotations # # drivers/message/i2o/i2o_config.c # 2004/06/22 07:51:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +25 -24 # sparse: trivial i2o annotations # # drivers/message/i2o/i2o_block.c # 2004/06/22 07:51:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +4 -3 # sparse: trivial i2o annotations # # ChangeSet # 2004/06/24 09:55:54-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: i2o fixed # # Fixes for direct dereferencing of userland pointers in i2o_config.c # # drivers/message/i2o/i2o_config.c # 2004/06/22 07:50:24-07:00 viro@parcelfarce.linux.theplanet.co.uk +6 -2 # sparse: i2o fixed # # ChangeSet # 2004/06/24 09:55:42-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: trivial drivers/isdn/* annotations # # drivers/isdn/i4l/isdn_x25iface.c # 2004/06/22 07:44:03-07:00 viro@parcelfarce.linux.theplanet.co.uk +2 -3 # sparse: trivial drivers/isdn/* annotations # # drivers/isdn/i4l/isdn_tty.c # 2004/06/22 07:44:03-07:00 viro@parcelfarce.linux.theplanet.co.uk +4 -4 # sparse: trivial drivers/isdn/* annotations # # drivers/isdn/i4l/isdn_net.h # 2004/06/22 07:44:03-07:00 viro@parcelfarce.linux.theplanet.co.uk +2 -2 # sparse: trivial drivers/isdn/* annotations # # drivers/isdn/i4l/isdn_net.c # 2004/06/22 07:44:03-07:00 viro@parcelfarce.linux.theplanet.co.uk +10 -11 # sparse: trivial drivers/isdn/* annotations # # drivers/isdn/i4l/isdn_common.c # 2004/06/22 07:44:03-07:00 viro@parcelfarce.linux.theplanet.co.uk +39 -39 # sparse: trivial drivers/isdn/* annotations # # drivers/isdn/capi/capi.c # 2004/06/22 07:44:03-07:00 viro@parcelfarce.linux.theplanet.co.uk +20 -22 # sparse: trivial drivers/isdn/* annotations # # ChangeSet # 2004/06/24 09:55:31-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] isdn_writebuf_stub() sanitized # # isdn_writebuf_stub() was always called for userland pointers. # # Killed the argument telling whether it's kernel or userland pointer, # killed dead code, updated callers. # # drivers/isdn/i4l/isdn_common.c # 2004/06/22 07:42:24-07:00 viro@parcelfarce.linux.theplanet.co.uk +3 -7 # isdn_writebuf_stub() sanitized # # ChangeSet # 2004/06/24 09:55:20-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: trivial annotations in drivers/char/* # # drivers/char/tipar.c # 2004/06/22 07:40:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +3 -3 # sparse: trivial annotations in drivers/char/* # # drivers/char/rocket.c # 2004/06/22 07:40:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +13 -12 # sparse: trivial annotations in drivers/char/* # # drivers/char/n_r3964.c # 2004/06/22 07:40:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -7 # sparse: trivial annotations in drivers/char/* # # drivers/char/n_hdlc.c # 2004/06/22 07:40:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +6 -6 # sparse: trivial annotations in drivers/char/* # # drivers/char/hpet.c # 2004/06/22 07:40:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +3 -3 # sparse: trivial annotations in drivers/char/* # # drivers/char/genrtc.c # 2004/06/22 07:40:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -9 # sparse: trivial annotations in drivers/char/* # # drivers/char/dtlk.c # 2004/06/22 07:40:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -7 # sparse: trivial annotations in drivers/char/* # # ChangeSet # 2004/06/24 09:55:09-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: trivial drivers/char/* annotation and format fixes # # - trivial annotation in several places in drivers/mtd # - a bunch of debugging printks switched from %x to %llx (they get 64bit # values) # - in doc200[01].c fixed type of (unused) last argument in their # doc_read_ecc(). # # include/linux/mtd/mtd.h # 2004/06/22 07:39:32-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/char/* annotation and format fixes # # drivers/mtd/mtdchar.c # 2004/06/22 07:39:20-07:00 viro@parcelfarce.linux.theplanet.co.uk +19 -23 # sparse: trivial drivers/char/* annotation and format fixes # # drivers/mtd/mtd_blkdevs.c # 2004/06/22 07:39:20-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/char/* annotation and format fixes # # drivers/mtd/devices/doc2001.c # 2004/06/22 07:39:20-07:00 viro@parcelfarce.linux.theplanet.co.uk +9 -4 # sparse: trivial drivers/char/* annotation and format fixes # # drivers/mtd/devices/doc2000.c # 2004/06/22 07:39:20-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -4 # sparse: trivial drivers/char/* annotation and format fixes # # drivers/mtd/chips/cfi_cmdset_0020.c # 2004/06/22 07:39:20-07:00 viro@parcelfarce.linux.theplanet.co.uk +4 -4 # sparse: trivial drivers/char/* annotation and format fixes # # drivers/mtd/chips/cfi_cmdset_0002.c # 2004/06/22 07:39:20-07:00 viro@parcelfarce.linux.theplanet.co.uk +4 -4 # sparse: trivial drivers/char/* annotation and format fixes # # drivers/mtd/chips/cfi_cmdset_0001.c # 2004/06/22 07:39:20-07:00 viro@parcelfarce.linux.theplanet.co.uk +2 -2 # sparse: trivial drivers/char/* annotation and format fixes # # ChangeSet # 2004/06/24 09:54:58-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: trivial drivers/net/* annotations # # drivers/net/wireless/strip.c # 2004/06/22 07:36:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +9 -9 # sparse: trivial drivers/net/* annotations # # drivers/net/wireless/ray_cs.c # 2004/06/22 07:36:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +2 -2 # sparse: trivial drivers/net/* annotations # # drivers/net/wireless/orinoco_tmd.c # 2004/06/22 07:36:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/net/* annotations # # drivers/net/wireless/orinoco_plx.c # 2004/06/22 07:36:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/net/* annotations # # drivers/net/wireless/orinoco_pci.c # 2004/06/22 07:36:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/net/* annotations # # drivers/net/wireless/atmel.c # 2004/06/22 07:36:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/net/* annotations # # drivers/net/wireless/arlan-proc.c # 2004/06/22 07:36:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -7 # sparse: trivial drivers/net/* annotations # # drivers/net/sunhme.c # 2004/06/22 07:37:13-07:00 viro@parcelfarce.linux.theplanet.co.uk +4 -2 # sparse: trivial drivers/net/* annotations # # drivers/net/sk98lin/h/skdrv2nd.h # 2004/06/22 07:36:50-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/net/* annotations # # drivers/net/pppox.c # 2004/06/22 07:37:13-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/net/* annotations # # drivers/net/pppoe.c # 2004/06/22 07:37:13-07:00 viro@parcelfarce.linux.theplanet.co.uk +4 -4 # sparse: trivial drivers/net/* annotations # # drivers/net/ppp_synctty.c # 2004/06/22 07:37:13-07:00 viro@parcelfarce.linux.theplanet.co.uk +18 -15 # sparse: trivial drivers/net/* annotations # # drivers/net/ppp_async.c # 2004/06/22 07:37:13-07:00 viro@parcelfarce.linux.theplanet.co.uk +18 -15 # sparse: trivial drivers/net/* annotations # # drivers/net/dgrs.h # 2004/06/22 07:37:13-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: trivial drivers/net/* annotations # # ChangeSet # 2004/06/24 09:54:48-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] make DVD ioctls that can legitimately fail quiet # # DVD_LU_SEND_{AGID,TITLE_KEY} can be legitimately rejected; in that case # we should not spew into logs. # # drivers/cdrom/cdrom.c # 2004/06/23 09:08:01-07:00 viro@parcelfarce.linux.theplanet.co.uk +2 -0 # make DVD ioctls that can legitimately fail quiet # # ChangeSet # 2004/06/24 09:50:56-07:00 Andries.Brouwer@cwi.nl # [PATCH] revert partition nonsense # # Updating my source to 2.6.7 I see that you applied some # nonsense garbage patch. Please undo. # # [ Note by Linus: the fact that DOS_EXTENDED_PARTITION is 5, and we're # iterating over slots 1-4 in the partition table, are two totally # unrelated things. Using the symbolic constant does indeed not make # any sense at all here, as Andries so eloquently points out. ] # # fs/partitions/msdos.c # 2004/05/22 10:38:00-07:00 Andries.Brouwer@cwi.nl +3 -3 # revert partition nonsense # # ChangeSet # 2004/06/24 09:50:46-07:00 benh@kernel.crashing.org # [PATCH] ppc64: Fix booting on LPAR machines with more than 1 CPU # # The exception rewrite contains a small bug that prevents bring up of CPUs # on logically partitioned machines. # # The kernel is trying to zero the backlink on the new stack while running # with relocation disabled, which potentially cause it to try to access an # address outside of the region allowed in real mode. This seem to be a # leftover from previous code as we also zero the backlink later after # turning off the MMU. # # This patch removes the offending bit. # # arch/ppc64/kernel/head.S # 2004/06/24 09:25:41-07:00 benh@kernel.crashing.org +0 -2 # ppc64: Fix booting on LPAR machines with more than 1 CPU # # ChangeSet # 2004/06/24 09:50:35-07:00 paulus@samba.org # [PATCH] Clean up head.S whitespace # # The whitespace in arch/ppc64/kernel/head.S is a bit all over the place. # This patch fixes it up. This patch changes nothing other than # whitespace. # # Signed-off-by: Paul Mackerras # Signed-off-by: Linus Torvalds # # arch/ppc64/kernel/head.S # 2004/06/06 20:35:10-07:00 paulus@samba.org +240 -240 # Clean up head.S whitespace # # ChangeSet # 2004/06/24 09:50:24-07:00 paulus@samba.org # [PATCH] Better memset # # Anton noticed in some traces that we were spending an awfully long time # doing a memset. The ppc64 memset is basically unchanged from the ppc32 # version, and it only does 4-byte stores and doesn't unroll the loop. # Here's a memset that performs a bit better. # # I have been using it for 3 weeks now, and Anton has tested it on a # variety of machines, without problems. # # Signed-off-by: Paul Mackerras # Signed-off-by: Linus Torvalds # # arch/ppc64/lib/string.S # 2004/05/29 04:39:26-07:00 paulus@samba.org +60 -19 # Better memset # # ChangeSet # 2004/06/24 09:50:13-07:00 paulus@samba.org # [PATCH] ppc64: clean up prom.c and related files # # Somebody back in the mists of time decided that call_prom and rtas_call # should return longs even though both of those bits of firmware run in # 32-bit mode and produce a 32-bit result. To make life more interesting, # the 32-bit result gets zero-extended to 64 bits, which makes checking # for a -1 return value more complicated than it should be. # # This patch changes call_prom and rtas_call to return an int, and makes # the corresponding changes to use ints for the variables used to hold # those return values. # # While I was doing this I finally got annoyed enough with the strings of # prom_print() and prom_print_hex() calls that we do to write a simple # prom_printf. I deliberately didn't use snprintf because the execution # environment is weird at this point - we aren't running at the address we # are linked at just yet - and I didn't want to inflict that on any code # outside this file. I also did a prom_debug() macro, which eliminated a # few ifdefs. # # There are also a bunch of other minor cleanups. This patch makes very # few algorithmic changes but does get rid of a lot of casts. :) # # I have been running with this patch for a couple of weeks, and Anton has # tested it too. # # Signed-off-by: Paul Mackerras # Signed-off-by: Linus Torvalds # # include/asm-ppc64/rtas.h # 2004/05/27 22:21:20-07:00 paulus@samba.org +2 -2 # ppc64: clean up prom.c and related files # # include/asm-ppc64/prom.h # 2004/05/27 18:37:20-07:00 paulus@samba.org +1 -1 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/xics.c # 2004/05/27 22:34:39-07:00 paulus@samba.org +18 -19 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/traps.c # 2004/06/07 22:31:36-07:00 paulus@samba.org +2 -2 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/smp.c # 2004/06/07 21:52:06-07:00 paulus@samba.org +1 -1 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/setup.c # 2004/05/27 21:02:20-07:00 paulus@samba.org +4 -5 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/scanlog.c # 2004/05/27 21:02:20-07:00 paulus@samba.org +6 -6 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/rtc.c # 2004/05/27 21:02:20-07:00 paulus@samba.org +4 -4 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/rtas_flash.c # 2004/05/27 21:02:21-07:00 paulus@samba.org +6 -6 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/rtas.c # 2004/06/07 22:55:07-07:00 paulus@samba.org +17 -35 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/rtas-proc.c # 2004/05/27 21:02:21-07:00 paulus@samba.org +2 -5 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/prom.c # 2004/06/03 16:10:15-07:00 paulus@samba.org +349 -539 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/pSeries_pci.c # 2004/05/27 21:02:22-07:00 paulus@samba.org +3 -2 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/pSeries_nvram.c # 2004/05/27 21:02:22-07:00 paulus@samba.org +4 -2 # ppc64: clean up prom.c and related files # # arch/ppc64/kernel/eeh.c # 2004/06/24 04:40:36-07:00 paulus@samba.org +4 -3 # ppc64: clean up prom.c and related files # # ChangeSet # 2004/06/24 09:50:02-07:00 roland@redhat.com # [PATCH] fix x86-64 ptrace access to 32-bit vsyscall page # # When I made get_user_pages support looking up a pte for the "gate" area, I # assumed it would be part of the kernel's fixed mappings. On x86-64 running # a 32-bit task, the 32-bit vsyscall DSO page still has no vma but has its # pte allocated in the user mm in the normal fashion. This patch makes it # use the generic page-table lookup calls rather than the shortcuts. # With this, ptrace on x86-64 can access a 32-bit process's vsyscall page. # # The behavior on x86 is unchanged. # # Signed-off-by: Roland McGrath # Signed-off-by: Linus Torvalds # # mm/memory.c # 2004/06/24 03:37:12-07:00 roland@redhat.com +8 -3 # fix x86-64 ptrace access to 32-bit vsyscall page # # ChangeSet # 2004/06/24 09:37:38-07:00 akpm@osdl.org # [PATCH] fix broken alpha build ptrace.c error # # From: Darren Williams # # include/asm/checksum.h:75: warning: `struct in6_addr' declared inside parameter list include/asm/checksum.h:75 # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-alpha/checksum.h # 2004/06/24 01:56:14-07:00 akpm@osdl.org +1 -0 # fix broken alpha build ptrace.c error # # ChangeSet # 2004/06/24 09:37:26-07:00 akpm@osdl.org # [PATCH] balanced_irq warning fix # # arch/i386/kernel/io_apic.c: In function `balanced_irq': # arch/i386/kernel/io_apic.c:582: warning: no return statement in function returning non-void # # and clean things up a bit # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/io_apic.c # 2004/06/24 01:56:14-07:00 akpm@osdl.org +11 -11 # balanced_irq warning fix # # ChangeSet # 2004/06/24 09:37:15-07:00 akpm@osdl.org # [PATCH] kswapd warning fix # # mm/vmscan.c: In function `kswapd': # mm/vmscan.c:1139: warning: no return statement in function returning non-void # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/vmscan.c # 2004/06/24 01:56:14-07:00 akpm@osdl.org +2 -1 # kswapd warning fix # # ChangeSet # 2004/06/24 09:37:04-07:00 akpm@osdl.org # [PATCH] md: XOR template selection redo # # From: NeilBrown # # From: Josh Litherland # # The XOR routine selection process is often confusing as it often doesn't # choose the routine that measures the fastest, as sometime one routine is # known to have better cache performance. # # This patch avoids the comparison when there is a known best choice, and # makes the report more meaningful. # # Signed-off-by: Neil Brown # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/xor.c # 2004/06/24 01:56:14-07:00 akpm@osdl.org +25 -14 # md: XOR template selection redo # # ChangeSet # 2004/06/24 09:36:53-07:00 akpm@osdl.org # [PATCH] md: Fix up handling for read error in raid1. # # From: NeilBrown # # There is severe bit-rot in this code, which is to say that it doesn't work # at all: an io error during read will do bad things. It should work better # with this patch. # # Signed-off-by: Neil Brown # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/raid1.c # 2004/06/24 01:56:14-07:00 akpm@osdl.org +7 -3 # md: Fix up handling for read error in raid1. # # ChangeSet # 2004/06/24 09:36:42-07:00 akpm@osdl.org # [PATCH] sh: Consolidate SystemH with other Renesas boards. # # From: Paul Mundt # # Nothing really interesting here, with the addition of several other Renesas # boards, we just move the systemh directory to the renesas one to fit in # better with the directory structure. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/sh/boards/renesas/systemh/setup.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +1 -1 # sh: Consolidate SystemH with other Renesas boards. # # arch/sh/boards/renesas/systemh/irq.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +2 -2 # sh: Consolidate SystemH with other Renesas boards. # # arch/sh/boards/renesas/systemh/io.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +6 -6 # sh: Consolidate SystemH with other Renesas boards. # # arch/sh/boards/renesas/systemh/Makefile # 2004/06/24 01:56:13-07:00 akpm@osdl.org +1 -1 # sh: Consolidate SystemH with other Renesas boards. # # ChangeSet # 2004/06/24 09:27:35-07:00 akpm@osdl.org # [PATCH] sh: merge. # # From: Paul Mundt # # This merges the remaining sh changes, random bug fixes, added syscalls, cache # fixups, etc. Nothing really eventful. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/bus-sh.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +65 -0 # sh: merge. # # arch/sh/ramdisk/ld.script # 2004/06/24 01:56:13-07:00 akpm@osdl.org +9 -0 # sh: merge. # # arch/sh/ramdisk/Makefile # 2004/06/24 01:56:13-07:00 akpm@osdl.org +19 -0 # sh: merge. # # arch/sh/kernel/cpu/bus.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +195 -0 # sh: merge. # # include/asm-sh/unistd.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +11 -1 # sh: merge. # # include/asm-sh/sigcontext.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +21 -1 # sh: merge. # # include/asm-sh/serial.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +0 -3 # sh: merge. # # include/asm-sh/processor.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +2 -1 # sh: merge. # # include/asm-sh/cpu-sh3/dac.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +3 -4 # sh: merge. # # include/asm-sh/cache.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +2 -1 # sh: merge. # # include/asm-sh/bus-sh.h # 2004/06/24 01:56:13-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/bus-sh.h # # arch/sh/tools/mach-types # 2004/06/24 01:56:13-07:00 akpm@osdl.org +3 -0 # sh: merge. # # arch/sh/ramdisk/ld.script # 2004/06/24 01:56:13-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/ramdisk/ld.script # # arch/sh/ramdisk/Makefile # 2004/06/24 01:56:13-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/ramdisk/Makefile # # arch/sh/mm/tlb-sh3.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +1 -1 # sh: merge. # # arch/sh/mm/cache-sh4.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +25 -31 # sh: merge. # # arch/sh/mm/cache-sh3.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +7 -7 # sh: merge. # # arch/sh/lib/delay.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +6 -0 # sh: merge. # # arch/sh/kernel/vmlinux.lds.S # 2004/06/24 01:56:13-07:00 akpm@osdl.org +8 -0 # sh: merge. # # arch/sh/kernel/traps.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +3 -3 # sh: merge. # # arch/sh/kernel/sh_ksyms.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +4 -0 # sh: merge. # # arch/sh/kernel/setup.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +19 -140 # sh: merge. # # arch/sh/kernel/ptrace.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +1 -8 # sh: merge. # # arch/sh/kernel/process.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +31 -4 # sh: merge. # # arch/sh/kernel/irq.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +43 -0 # sh: merge. # # arch/sh/kernel/io_generic.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +51 -7 # sh: merge. # # arch/sh/kernel/entry.S # 2004/06/24 01:56:13-07:00 akpm@osdl.org +9 -1 # sh: merge. # # arch/sh/kernel/cpu/init.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +34 -26 # sh: merge. # # arch/sh/kernel/cpu/bus.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/kernel/cpu/bus.c # # arch/sh/kernel/cpu/Makefile # 2004/06/24 01:56:13-07:00 akpm@osdl.org +1 -1 # sh: merge. # # arch/sh/boot/compressed/misc.c # 2004/06/24 01:56:13-07:00 akpm@osdl.org +18 -16 # sh: merge. # # arch/sh/boot/compressed/Makefile # 2004/06/24 01:56:13-07:00 akpm@osdl.org +4 -0 # sh: merge. # # arch/sh/Makefile # 2004/06/24 01:56:13-07:00 akpm@osdl.org +22 -6 # sh: merge. # # arch/sh/Kconfig # 2004/06/24 01:56:13-07:00 akpm@osdl.org +114 -12 # sh: merge. # # Documentation/sh/new-machine.txt # 2004/06/24 01:56:13-07:00 akpm@osdl.org +1 -7 # sh: merge. # # ChangeSet # 2004/06/24 09:27:23-07:00 akpm@osdl.org # [PATCH] sh: VoyagerGX companion chip support. # # From: Paul Mundt # # This adds support for the SM501/VoyagerGX companion chip, used by the # RTS7751R2D. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/sh/cchips/voyagergx/setup.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +37 -0 # sh: VoyagerGX companion chip support. # # arch/sh/cchips/voyagergx/irq.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +194 -0 # sh: VoyagerGX companion chip support. # # arch/sh/cchips/voyagergx/consistent.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +126 -0 # sh: VoyagerGX companion chip support. # # arch/sh/cchips/voyagergx/Makefile # 2004/06/24 01:56:12-07:00 akpm@osdl.org +8 -0 # sh: VoyagerGX companion chip support. # # arch/sh/cchips/voyagergx/setup.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/cchips/voyagergx/setup.c # # arch/sh/cchips/voyagergx/irq.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/cchips/voyagergx/irq.c # # arch/sh/cchips/voyagergx/consistent.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/cchips/voyagergx/consistent.c # # arch/sh/cchips/voyagergx/Makefile # 2004/06/24 01:56:12-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/cchips/voyagergx/Makefile # # arch/sh/cchips/Kconfig # 2004/06/24 01:56:12-07:00 akpm@osdl.org +13 -0 # sh: VoyagerGX companion chip support. # # ChangeSet # 2004/06/24 09:27:11-07:00 akpm@osdl.org # [PATCH] sh: SH7705/SH7300 subtype support, ST40 updates. # # From: Paul Mundt # # This adds support for the SH7705 and SH7300 subtypes and also updates some # ST40-specific FRQCR handling code. # # Signed-off-by: Alex Bennee # Signed-off-by: Hiroshi DOYU # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/ubc.h # 2004/06/24 01:56:12-07:00 akpm@osdl.org +2 -1 # sh: SH7705/SH7300 subtype support, ST40 updates. # # include/asm-sh/processor.h # 2004/06/24 01:56:12-07:00 akpm@osdl.org +2 -2 # sh: SH7705/SH7300 subtype support, ST40 updates. # # include/asm-sh/irq.h # 2004/06/24 01:56:12-07:00 akpm@osdl.org +270 -20 # sh: SH7705/SH7300 subtype support, ST40 updates. # # include/asm-sh/bugs.h # 2004/06/24 01:56:12-07:00 akpm@osdl.org +1 -1 # sh: SH7705/SH7300 subtype support, ST40 updates. # # arch/sh/kernel/time.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +175 -7 # sh: SH7705/SH7300 subtype support, ST40 updates. # # arch/sh/kernel/entry.S # 2004/06/24 01:56:12-07:00 akpm@osdl.org +3 -2 # sh: SH7705/SH7300 subtype support, ST40 updates. # # arch/sh/kernel/cpu/sh3/ex.S # 2004/06/24 01:56:12-07:00 akpm@osdl.org +77 -2 # sh: SH7705/SH7300 subtype support, ST40 updates. # # arch/sh/kernel/cpu/irq_ipr.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +30 -9 # sh: SH7705/SH7300 subtype support, ST40 updates. # # ChangeSet # 2004/06/24 09:27:00-07:00 akpm@osdl.org # [PATCH] sh: PCI updates # # From: Paul Mundt # # This updates the pci-auto code, as well as adding ops and fixups for the # RTS7751R2D board. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/sh/drivers/pci/ops-rts7751r2d.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +74 -0 # sh: PCI updates # # arch/sh/drivers/pci/fixups-rts7751r2d.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +32 -0 # sh: PCI updates # # arch/sh/drivers/pci/pci.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +1 -1 # sh: PCI updates # # arch/sh/drivers/pci/pci-sh7751.h # 2004/06/24 01:56:12-07:00 akpm@osdl.org +7 -0 # sh: PCI updates # # arch/sh/drivers/pci/pci-sh7751.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +23 -14 # sh: PCI updates # # arch/sh/drivers/pci/pci-auto.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +119 -100 # sh: PCI updates # # arch/sh/drivers/pci/ops-snapgear.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +2 -0 # sh: PCI updates # # arch/sh/drivers/pci/ops-rts7751r2d.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/drivers/pci/ops-rts7751r2d.c # # arch/sh/drivers/pci/fixups-rts7751r2d.c # 2004/06/24 01:56:12-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/drivers/pci/fixups-rts7751r2d.c # # arch/sh/drivers/pci/Makefile # 2004/06/24 01:56:12-07:00 akpm@osdl.org +1 -0 # sh: PCI updates # # ChangeSet # 2004/06/24 09:26:49-07:00 akpm@osdl.org # [PATCH] sh: Renesas RTS7751R2D board support. # # From: Paul Mundt # # This adds support for the Renesas Technology Sales RTS7751R2D board. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/rts7751r2d/voyagergx_reg.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +313 -0 # sh: Renesas RTS7751R2D board support. # # include/asm-sh/rts7751r2d/rts7751r2d.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +73 -0 # sh: Renesas RTS7751R2D board support. # # include/asm-sh/rts7751r2d/io.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +37 -0 # sh: Renesas RTS7751R2D board support. # # include/asm-sh/rts7751r2d/ide.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +8 -0 # sh: Renesas RTS7751R2D board support. # # arch/sh/configs/rts7751r2d_defconfig # 2004/06/24 01:56:11-07:00 akpm@osdl.org +809 -0 # sh: Renesas RTS7751R2D board support. # # arch/sh/boards/renesas/rts7751r2d/setup.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +31 -0 # sh: Renesas RTS7751R2D board support. # # arch/sh/boards/renesas/rts7751r2d/mach.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +68 -0 # sh: Renesas RTS7751R2D board support. # # arch/sh/boards/renesas/rts7751r2d/led.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +67 -0 # sh: Renesas RTS7751R2D board support. # # arch/sh/boards/renesas/rts7751r2d/irq.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +135 -0 # sh: Renesas RTS7751R2D board support. # # arch/sh/boards/renesas/rts7751r2d/Makefile # 2004/06/24 01:56:11-07:00 akpm@osdl.org +10 -0 # sh: Renesas RTS7751R2D board support. # # include/asm-sh/rts7751r2d/voyagergx_reg.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/rts7751r2d/voyagergx_reg.h # # include/asm-sh/rts7751r2d/rts7751r2d.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/rts7751r2d/rts7751r2d.h # # include/asm-sh/rts7751r2d/io.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/rts7751r2d/io.h # # include/asm-sh/rts7751r2d/ide.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/rts7751r2d/ide.h # # arch/sh/configs/rts7751r2d_defconfig # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/configs/rts7751r2d_defconfig # # arch/sh/boards/renesas/rts7751r2d/setup.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/rts7751r2d/setup.c # # arch/sh/boards/renesas/rts7751r2d/mach.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/rts7751r2d/mach.c # # arch/sh/boards/renesas/rts7751r2d/led.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/rts7751r2d/led.c # # arch/sh/boards/renesas/rts7751r2d/irq.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/rts7751r2d/irq.c # # arch/sh/boards/renesas/rts7751r2d/io.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +319 -0 # sh: Renesas RTS7751R2D board support. # # arch/sh/boards/renesas/rts7751r2d/Makefile # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/rts7751r2d/Makefile # # arch/sh/boards/renesas/rts7751r2d/io.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/rts7751r2d/io.c # # ChangeSet # 2004/06/24 09:26:37-07:00 akpm@osdl.org # [PATCH] sh: SolutionEngine 7300 board support. # # From: Paul Mundt # # This adds support for the SH7300 solution engine board (a forward port of the # 2.4 code). # # Signed-off-by: Hiroshi DOYU # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/se7300/se7300.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +61 -0 # sh: SolutionEngine 7300 board support. # # include/asm-sh/se7300/io.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +29 -0 # sh: SolutionEngine 7300 board support. # # arch/sh/configs/se7300_defconfig # 2004/06/24 01:56:11-07:00 akpm@osdl.org +461 -0 # sh: SolutionEngine 7300 board support. # # arch/sh/boards/se/7300/setup.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +66 -0 # sh: SolutionEngine 7300 board support. # # arch/sh/boards/se/7300/led.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +69 -0 # sh: SolutionEngine 7300 board support. # # arch/sh/boards/se/7300/irq.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +37 -0 # sh: SolutionEngine 7300 board support. # # arch/sh/boards/se/7300/io.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +261 -0 # sh: SolutionEngine 7300 board support. # # arch/sh/boards/se/7300/Makefile # 2004/06/24 01:56:11-07:00 akpm@osdl.org +7 -0 # sh: SolutionEngine 7300 board support. # # include/asm-sh/se7300/se7300.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/se7300/se7300.h # # include/asm-sh/se7300/io.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/se7300/io.h # # arch/sh/configs/se7300_defconfig # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/configs/se7300_defconfig # # arch/sh/boards/se/7300/setup.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/se/7300/setup.c # # arch/sh/boards/se/7300/led.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/se/7300/led.c # # arch/sh/boards/se/7300/irq.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/se/7300/irq.c # # arch/sh/boards/se/7300/io.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/se/7300/io.c # # arch/sh/boards/se/7300/Makefile # 2004/06/24 01:56:11-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/se/7300/Makefile # # ChangeSet # 2004/06/24 09:26:25-07:00 akpm@osdl.org # [PATCH] sh: sh-sci updates. # # From: Paul Mundt # # This adds support for the SH7300 as well as the SH5-101/103 processors as well # as specific board support for the RTS7751R2D. # # In addition to this, the sh early printk code is gutted so that we use the # generic CONFIG_EARLY_PRINTK interfaces instead. # # Signed-off-by: Hiroshi DOYU # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/serial/sh-sci.h # 2004/06/24 01:56:11-07:00 akpm@osdl.org +94 -4 # sh: sh-sci updates. # # drivers/serial/sh-sci.c # 2004/06/24 01:56:11-07:00 akpm@osdl.org +131 -32 # sh: sh-sci updates. # # ChangeSet # 2004/06/24 09:26:14-07:00 akpm@osdl.org # [PATCH] sh: ptep_get_and_clear() compile fix. # # From: Paul Mundt # # This fixes up a compile error occuring with ptep_get_and_clear() existing in # pgalloc.h. We move it to a somewhat more sensible location instead, and take # this opportunity to make some cleanups for use of generic code in the SH-3 # case, etc. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/pgtable.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +19 -25 # sh: ptep_get_and_clear() compile fix. # # include/asm-sh/pgalloc.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +3 -64 # sh: ptep_get_and_clear() compile fix. # # arch/sh/mm/pg-sh4.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +23 -4 # sh: ptep_get_and_clear() compile fix. # # ChangeSet # 2004/06/24 09:26:04-07:00 akpm@osdl.org # [PATCH] sh: IDE cleanup. # # From: Paul Mundt # # This does a bit of IDE cleanup (in preparation for the SuperH generic IDE host # driver). This also adds SuperH to the list of platforms that are interested # in CONFIG_IDE_MAX_HWIFS. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/ide.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +2 -63 # sh: IDE cleanup. # # include/asm-sh/hp6xx/ide.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +8 -0 # sh: IDE cleanup. # # drivers/ide/Kconfig # 2004/06/24 01:56:10-07:00 akpm@osdl.org +1 -1 # sh: IDE cleanup. # # include/asm-sh/hp6xx/ide.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/hp6xx/ide.h # # ChangeSet # 2004/06/24 09:25:52-07:00 akpm@osdl.org # [PATCH] sh: Renesas HS7751RVoIP board support. # # From: Paul Mundt # # This adds support for the Renesas Technology Sales HS7751RVoIP board. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/hs7751rvoip/io.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +39 -0 # sh: Renesas HS7751RVoIP board support. # # include/asm-sh/hs7751rvoip/ide.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +8 -0 # sh: Renesas HS7751RVoIP board support. # # include/asm-sh/hs7751rvoip/hs7751rvoip.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +47 -0 # sh: Renesas HS7751RVoIP board support. # # arch/sh/boards/renesas/hs7751rvoip/setup.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +89 -0 # sh: Renesas HS7751RVoIP board support. # # arch/sh/boards/renesas/hs7751rvoip/pci.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +150 -0 # sh: Renesas HS7751RVoIP board support. # # arch/sh/boards/renesas/hs7751rvoip/mach.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +55 -0 # sh: Renesas HS7751RVoIP board support. # # arch/sh/boards/renesas/hs7751rvoip/led.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +27 -0 # sh: Renesas HS7751RVoIP board support. # # arch/sh/boards/renesas/hs7751rvoip/irq.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +122 -0 # sh: Renesas HS7751RVoIP board support. # # arch/sh/boards/renesas/hs7751rvoip/io.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +310 -0 # sh: Renesas HS7751RVoIP board support. # # arch/sh/boards/renesas/hs7751rvoip/Makefile # 2004/06/24 01:56:10-07:00 akpm@osdl.org +12 -0 # sh: Renesas HS7751RVoIP board support. # # include/asm-sh/hs7751rvoip/io.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/hs7751rvoip/io.h # # include/asm-sh/hs7751rvoip/ide.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/hs7751rvoip/ide.h # # include/asm-sh/hs7751rvoip/hs7751rvoip.h # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/hs7751rvoip/hs7751rvoip.h # # arch/sh/boards/renesas/hs7751rvoip/setup.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/hs7751rvoip/setup.c # # arch/sh/boards/renesas/hs7751rvoip/pci.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/hs7751rvoip/pci.c # # arch/sh/boards/renesas/hs7751rvoip/mach.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/hs7751rvoip/mach.c # # arch/sh/boards/renesas/hs7751rvoip/led.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/hs7751rvoip/led.c # # arch/sh/boards/renesas/hs7751rvoip/irq.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/hs7751rvoip/irq.c # # arch/sh/boards/renesas/hs7751rvoip/io.c # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/hs7751rvoip/io.c # # arch/sh/boards/renesas/hs7751rvoip/Makefile # 2004/06/24 01:56:10-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/boards/renesas/hs7751rvoip/Makefile # # ChangeSet # 2004/06/24 09:25:41-07:00 akpm@osdl.org # [PATCH] sh: fixmap support. # # From: Paul Mundt # # This adds fixmap support for sh. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/pgtable.h # 2004/06/24 01:56:09-07:00 akpm@osdl.org +3 -2 # sh: fixmap support. # # include/asm-sh/fixmap.h # 2004/06/24 01:56:09-07:00 akpm@osdl.org +111 -0 # sh: fixmap support. # # arch/sh/mm/init.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +61 -1 # sh: fixmap support. # # include/asm-sh/fixmap.h # 2004/06/24 01:56:09-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/fixmap.h # # ChangeSet # 2004/06/24 09:25:29-07:00 akpm@osdl.org # [PATCH] sh: early printk() cleanup. # # From: Paul Mundt # # sh was using its own CONFIG_SH_EARLY_PRINTK, this is no longer necessary as we # can easily work with the generic CONFIG_EARLY_PRINTK. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/sh/kernel/early_printk.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +135 -0 # sh: early printk() cleanup. # # arch/sh/kernel/early_printk.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/kernel/early_printk.c # # arch/sh/kernel/Makefile # 2004/06/24 01:56:09-07:00 akpm@osdl.org +1 -0 # sh: early printk() cleanup. # # arch/sh/defconfig # 2004/06/24 01:56:09-07:00 akpm@osdl.org +1 -1 # sh: early printk() cleanup. # # ChangeSet # 2004/06/24 09:25:17-07:00 akpm@osdl.org # [PATCH] sh: DMA driver updates. # # From: Paul Mundt # # This updates the SuperH DMA driver, as well as cleaning up the registration # interface. # # We also drop the use of bitfields in dma-sh since things like the SH4-202, # 7751R, 7760, etc. all have a completely different set of register # definitions. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/dma.h # 2004/06/24 01:56:09-07:00 akpm@osdl.org +53 -18 # sh: DMA driver updates. # # include/asm-sh/cpu-sh4/dma.h # 2004/06/24 01:56:09-07:00 akpm@osdl.org +10 -0 # sh: DMA driver updates. # # arch/sh/drivers/dma/dma-sysfs.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +133 -0 # sh: DMA driver updates. # # arch/sh/drivers/dma/dma-sh.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +86 -78 # sh: DMA driver updates. # # arch/sh/drivers/dma/dma-isa.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +21 -8 # sh: DMA driver updates. # # arch/sh/drivers/dma/dma-api.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +134 -41 # sh: DMA driver updates. # # arch/sh/drivers/dma/Makefile # 2004/06/24 01:56:09-07:00 akpm@osdl.org +1 -0 # sh: DMA driver updates. # # arch/sh/drivers/dma/dma-sysfs.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/drivers/dma/dma-sysfs.c # # ChangeSet # 2004/06/24 09:25:06-07:00 akpm@osdl.org # [PATCH] sh: dma-mapping updates. # # From: Paul Mundt # # This updates the sh dma-mapping code, as well as doing some cleanup in the # consistent API. We also add a consistent_{alloc,free} to the machvec for # platforms that need special handling. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/machvec.h # 2004/06/24 01:56:09-07:00 akpm@osdl.org +4 -0 # sh: dma-mapping updates. # # include/asm-sh/dma-mapping.h # 2004/06/24 01:56:09-07:00 akpm@osdl.org +32 -0 # sh: dma-mapping updates. # # arch/sh/mm/consistent.c # 2004/06/24 01:56:09-07:00 akpm@osdl.org +21 -19 # sh: dma-mapping updates. # # ChangeSet # 2004/06/24 09:24:55-07:00 akpm@osdl.org # [PATCH] sh: SH-3 On-Chip ADC support # # From: Paul Mundt # # This adds support for the SH-3's on-chip ADC (which is needed by things like # the touchscreen, etc.). # # Signed-off-by: Andriy Skulysh # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-sh/cpu-sh3/adc.h # 2004/06/24 01:56:08-07:00 akpm@osdl.org +28 -0 # sh: SH-3 On-Chip ADC support # # include/asm-sh/adc.h # 2004/06/24 01:56:08-07:00 akpm@osdl.org +12 -0 # sh: SH-3 On-Chip ADC support # # include/asm-sh/hp6xx/hp6xx.h # 2004/06/24 01:56:08-07:00 akpm@osdl.org +15 -3 # sh: SH-3 On-Chip ADC support # # include/asm-sh/cpu-sh3/adc.h # 2004/06/24 01:56:08-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/cpu-sh3/adc.h # # include/asm-sh/adc.h # 2004/06/24 01:56:08-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/adc.h # # arch/sh/kernel/cpu/adc.c # 2004/06/24 01:56:08-07:00 akpm@osdl.org +36 -0 # sh: SH-3 On-Chip ADC support # # arch/sh/kernel/cpu/Makefile # 2004/06/24 01:56:08-07:00 akpm@osdl.org +1 -0 # sh: SH-3 On-Chip ADC support # # arch/sh/kernel/cpu/adc.c # 2004/06/24 01:56:08-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/sh/kernel/cpu/adc.c # # ChangeSet # 2004/06/24 09:24:44-07:00 akpm@osdl.org # [PATCH] oom killer: ignore free swapspace # # From: William Lee Irwin III # # During stress testing at Oracle to determine the maximum number of clients # 2.6 can service, it was discovered that the failure mode of excessive # numbers of clients was kernel deadlock. The following patch removes the # check if (nr_swap_pages > 0) from out_of_memory() as this heuristic fails # to detect memory exhaustion due to pinned allocations, directly causing the # aforementioned deadlock. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/oom_kill.c # 2004/06/24 01:56:08-07:00 akpm@osdl.org +0 -6 # oom killer: ignore free swapspace # # ChangeSet # 2004/06/24 09:24:33-07:00 akpm@osdl.org # [PATCH] hugetlb.c - fix try_to_free_low() # # From: "Chen, Kenneth W" # # Turn on CONFIG_HIGHMEM and CONFIG_HUGETLBFS. Try to config the hugetlb # pool: # # [root@quokka]# echo 100 > /proc/sys/vm/nr_hugepages # [root@quokka]# grep HugePage /proc/meminfo # HugePages_Total: 100 # HugePages_Free: 100 # # [root@quokka]# echo 20 > /proc/sys/vm/nr_hugepages # [root@quokka]# grep HugePage /proc/meminfo # HugePages_Total: 0 # HugePages_Free: 0 # # [root@quokka]# echo 100 > /proc/sys/vm/nr_hugepages # [root@quokka]# grep HugePage /proc/meminfo # HugePages_Total: 100 # HugePages_Free: 100 # # [root@quokka]# echo 0 > /proc/sys/vm/nr_hugepages # [root@quokka]# grep HugePage /proc/meminfo # HugePages_Total: 31 # HugePages_Free: 31 # # The argument "count" passed to try_to_free_low() is the config parameter # for desired hugetlb page pool size. But the implementation took that input # argument as number of pages to free. It also decrement the config # parameter as well. All give random behavior depend on how many hugetlb # pages are in normal/highmem zone. # # A two line fix in try_to_free_low() would be: # # - if (!--count) # - return 0; # + if (count >= nr_huge_pages) # + return count; # # But more appropriately, that function shouldn't return anything. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/hugetlb.c # 2004/06/24 01:56:08-07:00 akpm@osdl.org +6 -7 # hugetlb.c - fix try_to_free_low() # # ChangeSet # 2004/06/24 09:24:22-07:00 akpm@osdl.org # [PATCH] sparse: fixes for "assignment expression in conditional" in fs/* # # From: Mika Kukkonen # # Fix various sparse "assignment expression in conditional" warnings in fs/ # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/quota.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/lockd/svcshare.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/lockd/svclock.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +5 -5 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/lockd/host.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +2 -2 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/jfs/jfs_txnmgr.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/jfs/jfs_logmgr.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/jfs/jfs_extent.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/hpfs/alloc.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +2 -2 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/hfsplus/wrapper.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/hfsplus/bnode.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +5 -5 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/hfs/super.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/eventpoll.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/autofs4/waitq.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/autofs/waitq.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/afs/super.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # fs/affs/amigaffs.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -1 # sparse: fixes for "assignment expression in conditional" in fs/* # # ChangeSet # 2004/06/24 09:24:10-07:00 akpm@osdl.org # [PATCH] consolidate in-kernel configuration # # From: Andy Whitcroft # # Being able to recover the configuration from a kernel is very useful and it # would be nice to default this option to Yes. Currently, to have the config # available both from the image (using extract-ikconfig) and via /proc we # keep two copies of the original .config in the kernel. One in plain text # and one gzip compressed. This is not optimal. # # This patch removes the plain text version of the configuration and updates # the extraction tools to locate and use the gzip'd version of the file. # This has the added bonus of providing us with the exact same results in # both cases, the original .config; including the comments. # # Signed-off-by: Andy Whitcroft # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # scripts/extract-ikconfig # 2004/06/24 01:56:07-07:00 akpm@osdl.org +49 -38 # consolidate in-kernel configuration # # kernel/configs.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +19 -6 # consolidate in-kernel configuration # # kernel/Makefile # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -17 # consolidate in-kernel configuration # # ChangeSet # 2004/06/24 09:23:59-07:00 akpm@osdl.org # [PATCH] swsusp: shuffle cpu.c to make it usable for smp suspend # # From: Pavel Machek # # This moves fix_processor_context() so that additional prototype is not # needed, and adds context * to processor state saving functions, so that # they can be used on SMP. It should be done this way from the beggining. # # Signed-off-by: Pavel Machek # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/power/cpu.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +60 -49 # swsusp: shuffle cpu.c to make it usable for smp suspend # # ChangeSet # 2004/06/24 09:23:48-07:00 akpm@osdl.org # [PATCH] Prepare for SMP suspend # # From: Pavel Machek # # Its very bad idea to freeze migration threads, as it crashes machine upon # next call to "schedule()". In refrigerator, I had one "wake_up_process()" # too many. This fixes it. # # Signed-off-by: Pavel Machek # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sched.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +1 -0 # Prepare for SMP suspend # # kernel/power/process.c # 2004/06/24 01:56:07-07:00 akpm@osdl.org +0 -1 # Prepare for SMP suspend # # ChangeSet # 2004/06/24 09:23:37-07:00 akpm@osdl.org # [PATCH] swsusp minor docs updates # # From: Pavel Machek # # I shot myself in the foot with swsusp, so I guess documenting that # particular trap is right thing to do (tm). Somehow two copies of "radeon # hint" crept in; fix that, too. # # Signed-off-by: Pavel Machek # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # Documentation/power/video.txt # 2004/06/24 01:56:06-07:00 akpm@osdl.org +0 -4 # swsusp minor docs updates # # Documentation/power/swsusp.txt # 2004/06/24 01:56:06-07:00 akpm@osdl.org +3 -0 # swsusp minor docs updates # # ChangeSet # 2004/06/24 09:23:26-07:00 akpm@osdl.org # [PATCH] hugetlb.c: use safe iterator # # From: "Chen, Kenneth W" # # With list poisoning on by default from linux-2.6.7, it's easier than ever to # trigger the bug in try_to_free_low(). It ought to use the safe version of # list iterater. # # Signed-off-by: Ken Chen # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/hugetlb.c # 2004/06/24 01:56:06-07:00 akpm@osdl.org +2 -2 # hugetlb.c: use safe iterator # # ChangeSet # 2004/06/24 09:23:15-07:00 akpm@osdl.org # [PATCH] update ikconfig generator script # # From: "Randy.Dunlap" # # http://bugme.osdl.org/show_bug.cgi?id=2701 # # Current script has problems with some shells and utilities. Remove use of # 'echo' in the script. # # From: Roman Zippel # Signed-off-by: Randy Dunlap # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # scripts/mkconfigs # 2004/06/24 01:56:06-07:00 akpm@osdl.org +11 -11 # update ikconfig generator script # # ChangeSet # 2004/06/24 09:23:04-07:00 akpm@osdl.org # [PATCH] update ikconfig help text # # From: "Randy.Dunlap" # # Some elements of ikconfig have been removed, but the help text wasn't # updated to reflect those changes. # # Signed-off-by: Randy Dunlap # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # init/Kconfig # 2004/06/24 01:56:06-07:00 akpm@osdl.org +4 -10 # update ikconfig help text # # ChangeSet # 2004/06/24 09:22:53-07:00 akpm@osdl.org # [PATCH] cirrusfb: major update # # From: David Eger # # This patch brings the cirrusfb driver up to date with 2.6. cirrusfb has # suffered bit rot like you wouldn't believe (last updated... 2.3.x era?). # The driver will now compile again, and you can change to a high resolution # text mode with stty. Known defects: doesn't play nice with X, nor fbset. # # C = Cosmetic change # L = Logical change # A = API change # W = register Writing change # # (1-CA) fb_info and cirrusfb_info: # - mostly cosmetic, but a lot less confusing, and no more nasty casting. # # It used to be stylish to embed struct fb_info_gen (now struct fb_info) # as the first member of struct clgenfb_info (now struct cirrusfb_info), # and then you'd cast to the deisred struct. # Now we pass the size of our data structure to framebuffer_alloc(), # and we make fb_info and cirrusfb_info reference each other with # pointers (as in radeonfb). # # In the old code, there two declarations were common: # # clgenfb_info *fb_info; # clgenfb_info *info; # # since there's also a 'struct fb_info' now, I found this really confusing, # and unified usage as: # # cirrusfb_info *cinfo; # fb_info *info; # # This accounts for a lot of the search and replace cosmetic upgrade. # # (2-A) All of the FB knowledge of FB internals is gone in 2.6 # # (3-LW) revised maxclock numbers (cirrusfb_board_info_rec.maxclock[5]) # # In my quest to get fbset to work, I borrowed some maxclock data # from the X.Org tree for various chipsets. It didn't really seem # to help. oh well. # # (3-LA) upgraded PCI registration # # Instead of doing PCI walking from the driver, we hand off a # pci_device_id table to the PCI subsystem and just get called when # it finds a relevant board. # # (4-L) striking lots of __init and __initdata specifiers # # I was running into some things not working when I moved the call to # init_vgachip() from the driver registration to set_par(). I thought # perhaps this was due to some things being marked __init accidentally # so I axed said annotations. Turns out it was something else. See 5. # # (5-LA) delayed chip initialization, nasty double-set_par() pseudo-bug # # Tony says that the fb drivers shouldn't do any chipset initialization # until they get a set_par() call. This way, fb modules can be safely # unloaded if no one gets around to using them, and the vga_con -> fbcon # hand off is smoother, as fbcon can still grab the back-scroll data from # vga_con... # # In any case, moving the calls to init_vgachip() and fbgen_do_set_var() # from driver initialization to set_par() revealed that the cirrus # register-writing function needs to be called twice for a mode change to # work. I don't understand why. # # (6-LA) split clgen_decode_var() into the bits that check the var and the # bits that actually generate register information (par/regs) to write # # Adding modedb hooks here might actually fix fbset, i think... # # (7-LW) No longer write the palette in init_vgachip() nor in set_par(). # Someone else (fbcon?) seems to be making its own calls to setcolreg() # for us. # # (8-LW) setcolreg() -- while removing all of the console cruft, I had # to try to reconstitute the palette code. I think I got this right, # but I could be off -- the penguin boots in the correct colors at least ;-) # # (9-L) pan_display() - we don't do wrap, silly. that's only on the amiga. # # (10-L) pan+BLT - to make pan play nicely with copyarea()/fillrect() # I had to add a couple of calls to cirrusfb_WaitBLT() to make sure # the engine is idle. # # (11-LW) cirrusfb_blank() - I upgraded the switch here to use the new # VESA_* blanking mode constants. I think I translated the right # logic for the right blanking levels. # # # Signed-off-by: David Eger # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/fbmem.c # 2004/06/24 01:56:05-07:00 akpm@osdl.org +4 -4 # cirrusfb: major update # # drivers/video/cirrusfb.c # 2004/06/24 01:56:05-07:00 akpm@osdl.org +1228 -1556 # cirrusfb: major update # # drivers/video/Makefile # 2004/06/24 01:56:05-07:00 akpm@osdl.org +1 -1 # cirrusfb: major update # # drivers/video/Kconfig # 2004/06/24 01:56:05-07:00 akpm@osdl.org +1 -1 # cirrusfb: major update # # ChangeSet # 2004/06/24 09:22:42-07:00 akpm@osdl.org # [PATCH] h8300: delete obsolute header # # From: Yoshinori Sato # # - delete obsolute(unused) header file # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # BitKeeper/deleted/.del-h8300_ne.h~b7511d0a22156c44 # 2004/06/24 09:22:36-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-h8300/h8300_ne.h # # ChangeSet # 2004/06/24 09:22:31-07:00 akpm@osdl.org # [PATCH] zap_pte_range speedup # # From: Hugh Dickins # # zap_pte_range is wasting time marking anon pages accessed: its original # !PageSwapCache test should have been reinstated when page_mapping was # changed to return swapper_space; or more simply, just check !PageAnon. # # Signed-off-by: Hugh Dickins # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/memory.c # 2004/06/24 01:56:05-07:00 akpm@osdl.org +1 -1 # zap_pte_range speedup # # ChangeSet # 2004/06/24 09:22:20-07:00 akpm@osdl.org # [PATCH] drivers/media/video/tda9840.c: honour return code of i2c_add_driver() # # From: Michael Hunold # # i2c_add_driver() may actually fail, but my driver returns 0 regardless. # Thanks to Arthur Othieno for this obviously correct # patch. # # Signed-off-by: Michael Hunold # Signed-off-by: Arthur Othieno # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/video/tda9840.c # 2004/06/24 01:56:05-07:00 akpm@osdl.org +3 -5 # drivers/media/video/tda9840.c: honour return code of i2c_add_driver() # # ChangeSet # 2004/06/24 09:22:08-07:00 akpm@osdl.org # [PATCH] fix allocate_pgdat comments # # From: "Martin J. Bligh" # # From: Andy Whitcroft # # The comments for i386 allocate_pgdat indicate that the routine should be # modified to place the pgdat into node local memory. However, this has # already been done as the pgdat is placed at node_remap_start_vaddr. This # patch updates the comments to reflect this reality. # # Signed-off-by: Andy Whitcroft # Signed-off-by: Martin J. Bligh # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/mm/discontig.c # 2004/06/24 01:56:04-07:00 akpm@osdl.org +5 -2 # fix allocate_pgdat comments # # ChangeSet # 2004/06/24 09:21:57-07:00 akpm@osdl.org # [PATCH] SELinux: Extend and revise calls to secondary module # # From: Stephen Smalley # # This patch extends the set of calls to the secondary security module by # SELinux as well as revising a few existing calls to support other security # modules and to more cleanly stack with the capability module. Please # apply. # # Signed-off-by: Stephen Smalley # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # security/selinux/hooks.c # 2004/06/24 01:56:04-07:00 akpm@osdl.org +85 -9 # SELinux: Extend and revise calls to secondary module # # ChangeSet # 2004/06/24 09:21:46-07:00 akpm@osdl.org # [PATCH] (o)profile Documentation/basic_profiling.txt updates # # From: bert hubert # # Signed-off-by: bert hubert # Signed-off-by: John Levon # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # Documentation/basic_profiling.txt # 2004/06/24 01:56:04-07:00 akpm@osdl.org +22 -18 # (o)profile Documentation/basic_profiling.txt updates # # ChangeSet # 2004/06/24 09:21:35-07:00 akpm@osdl.org # [PATCH] Add PPC85xx MAINTAINERS entry # # From: Kumar Gala # # Added myself to the MAINTAINERS file for 85xx. Added an entry into the # CREDITS file for me. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # MAINTAINERS # 2004/06/24 01:56:04-07:00 akpm@osdl.org +7 -0 # Add PPC85xx MAINTAINERS entry # # CREDITS # 2004/06/24 01:56:04-07:00 akpm@osdl.org +6 -0 # Add PPC85xx MAINTAINERS entry # # ChangeSet # 2004/06/24 09:21:24-07:00 akpm@osdl.org # [PATCH] ppc64: fix POWER3 NUMA init # # From: Anton Blanchard # # We were passing in the hole size as kB not pages to free_area_init which # made the VM misbehave. This only hit on POWER3 because POWER4 and newer # places IO above all memory and so doesnt have a hole. # # Signed-off-by: Anton Blanchard # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/ppc64/mm/numa.c # 2004/06/24 01:56:03-07:00 akpm@osdl.org +1 -1 # ppc64: fix POWER3 NUMA init # # ChangeSet # 2004/06/24 09:21:13-07:00 akpm@osdl.org # [PATCH] fbdev: video mode change notify (fbset) # # From: "Antonino A. Daplas" # # This patch allows fbset to change the video mode and the console window # size via the notifier call chain. It will only notify fbcon of mode # changes from user space. Changes coming from upstream will be ignored. # # The code will only update the current console. # # Signed-off-by: Antonino Daplas # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/fb.h # 2004/06/24 01:56:03-07:00 akpm@osdl.org +2 -0 # fbdev: video mode change notify (fbset) # # drivers/video/fbmem.c # 2004/06/24 01:56:03-07:00 akpm@osdl.org +7 -1 # fbdev: video mode change notify (fbset) # # drivers/video/console/fbcon.c # 2004/06/24 01:56:03-07:00 akpm@osdl.org +53 -0 # fbdev: video mode change notify (fbset) # # ChangeSet # 2004/06/24 09:21:01-07:00 akpm@osdl.org # [PATCH] Core fbcon fixes # # From: "Antonino A. Daplas" # # This patch fixes the following bugs/regressions for fbcon: # # 1. Initialize and update global arrays used by fbcon during # initialization and and by set_con2fbmap code. # # 2. Fixed screen corruption (white rectangle) at initial mode setting # plaguing cards with VGA cores and with VGA console enabled. (vga16fb, # however, still shows remnants of previous text if boot logo is enabled) # # 3. Improved fbcon_startup/fbcon_init code. # # 4. Fixed set_con2fbmap code -- should support multiple devices mapped to # # Signed-off-by: Antonino A. Daplas # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/fb.h # 2004/06/24 01:56:03-07:00 akpm@osdl.org +1 -0 # Core fbcon fixes # # drivers/video/fbmem.c # 2004/06/24 01:56:03-07:00 akpm@osdl.org +11 -5 # Core fbcon fixes # # drivers/video/console/fbcon.c # 2004/06/24 01:56:03-07:00 akpm@osdl.org +260 -72 # Core fbcon fixes # # ChangeSet # 2004/06/24 09:20:50-07:00 akpm@osdl.org # [PATCH] SubmittingDrivers fix # # From: Jesper Juhl # # Here's a small patch that lists X.Org as well as XFree86 in # Documentation/SubmittingDrivers in the section talking about video drivers. # # Signed-off-by: Jesper Juhl # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # Documentation/SubmittingDrivers # 2004/06/24 01:56:03-07:00 akpm@osdl.org +2 -1 # SubmittingDrivers fix # # ChangeSet # 2004/06/24 09:20:39-07:00 akpm@osdl.org # [PATCH] OProfile: allow normal user to trigger sample dumps # # From: John Levon # # In 2.4, OProfile allowed normal users to trigger sample dumps (useful under # low sample load). The patch below, by Will Cohen, allows this for 2.6 too. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/oprofile.h # 2004/06/24 01:56:02-07:00 akpm@osdl.org +3 -0 # OProfile: allow normal user to trigger sample dumps # # drivers/oprofile/oprofilefs.c # 2004/06/24 01:56:02-07:00 akpm@osdl.org +19 -6 # OProfile: allow normal user to trigger sample dumps # # drivers/oprofile/oprofile_files.c # 2004/06/24 01:56:02-07:00 akpm@osdl.org +1 -1 # OProfile: allow normal user to trigger sample dumps # # ChangeSet # 2004/06/24 09:20:28-07:00 akpm@osdl.org # [PATCH] Fix early CPU vendor detection for non intel cpus # # From: Andi Kleen # # Early CPU detect can only work after the various sub CPU drivers have # registered their devices. # # Currently the vendor would be always 0, which is Intel. # # This prevents Athlons from being recognized as buggy PPros and fixes some # other workarounds for non Intel CPUs too. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/cpu/common.c # 2004/06/24 01:56:02-07:00 akpm@osdl.org +1 -1 # Fix early CPU vendor detection for non intel cpus # # ChangeSet # 2004/06/24 09:20:17-07:00 akpm@osdl.org # [PATCH] fix linker trouble with CONFIG_FB_RIVA_I2C=y and modular I2C # # From: Adrian Bunk # # > This version causes linker trouble with # > CONFIG_I2C=m # > CONFIG_I2C_ALGOBIT=m # > CONFIG_FB_RIVA_I2C=y # > # > CC init/version.o # > LD init/built-in.o # > LD .tmp_vmlinux1 # > drivers/built-in.o(.text+0xda101): In function `riva_setup_i2c_bus': # > : undefined reference to `i2c_bit_add_bus' # > drivers/built-in.o(.text+0xda218): In function `riva_delete_i2c_busses': # > : undefined reference to `i2c_bit_del_bus' # > drivers/built-in.o(.text+0xda237): In function `riva_delete_i2c_busses': # > : undefined reference to `i2c_bit_del_bus' # > drivers/built-in.o(.text+0xda2c9): In function `riva_do_probe_i2c_edid': # > : undefined reference to `i2c_transfer' # > make: *** [.tmp_vmlinux1] Error 1 # >... # # The problem is: # FB_RIVA=y # FB_RIVA_I2C=y # I2C=m # I2C_ALGOBIT=m # # The patch below fixes this. # # Besides this, it contains: # - help text by Antonino A. Daplas # - converted spaces to tabs # - it was forgotten that FB_RIVA_I2C requires I2C_ALGOBIT # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/Kconfig # 2004/06/24 01:56:02-07:00 akpm@osdl.org +3 -1 # fix linker trouble with CONFIG_FB_RIVA_I2C=y and modular I2C # # ChangeSet # 2004/06/24 09:20:06-07:00 akpm@osdl.org # [PATCH] Indydog update # # From: Ralf Baechle # # Forward port of the 2.4 driver with changes required for 2.6. # # Signed-off-by: Ralf Baechle # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/char/watchdog/indydog.c # 2004/06/24 01:56:02-07:00 akpm@osdl.org +45 -72 # Indydog update # # ChangeSet # 2004/06/24 09:19:53-07:00 akpm@osdl.org # [PATCH] MIPS Update # # From: Ralf Baechle # # MIPS update: # # - Further conversion of MIPS kernel configuration to reverse dependencies. # - Support for the PMC-Sierra Yosemite evaluation board. # - Merge arch/mips/mm-32 and arch/mips/mm-32 into arch/mips/mm. # - Partial support for the R8000 now that I finally have clearance for the # documentation previously covered by NDA. # - Make distclean fixes. # - Regenerate default configuration files against latest Kconfig files. # - Fix handling of data bus errors in modules. # - Make R4000 bug probing more bullet proof. # - Rewrite semaphore code folloing the PPC implementation to no longer # manipulate 2 32-bit quantities atomically using 64-bit instructions. # Occasionally this did cause problems due to struct semaphore not having # sufficient alignment. # - Make sys_pipe() code bullet proof against gcc 3.5 over-optimization. # - Fix possibly exploitable bug in IRIX compatibility statvfs(2). # - Make sched_clock() an outline function. # - Support for the MIPS 24K and 25K processors. # - Make functions static that aren't needed anywhere else. # - Factor out some more generic MIPS SMP code. # - Factor out common part of the GT-64240 code. # - Ocelot C now uses the generic MV-64340 interrupt handler code. # - Factor out common board support code # - More cleanup and bug fixes for the NEC VR41xx code. # - Start cleanup of hazard handling as required for MIPS32/64 V2 processors. # - Enforce minimal kmalloc alignment of 8 byte so 64-bit registers can be # stored into fields without exceptions. # - Speeling and warning fixes. # # Signed-off-by: Ralf Baechle # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-mips/vr41xx/vrc4173.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +43 -35 # MIPS Update # # include/asm-mips/vr41xx/vr41xx.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +127 -17 # MIPS Update # # include/asm-mips/vr41xx/tb0226.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +14 -40 # MIPS Update # # include/asm-mips/vr41xx/tb0219.h # 2004/06/24 09:19:45-07:00 akpm@osdl.org +42 -0 # # include/asm-mips/vr41xx/mpc30x.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +14 -40 # MIPS Update # # include/asm-mips/vr41xx/capcella.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +14 -40 # MIPS Update # # include/asm-mips/unistd.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +9 -6 # MIPS Update # # include/asm-mips/titan_dep.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +175 -6 # MIPS Update # # include/asm-mips/thread_info.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -0 # MIPS Update # # include/asm-mips/system.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +9 -12 # MIPS Update # # include/asm-mips/stackframe.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -0 # MIPS Update # # include/asm-mips/smp.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -8 # MIPS Update # # include/asm-mips/serial.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -19 # MIPS Update # # include/asm-mips/semaphore.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +60 -205 # MIPS Update # # include/asm-mips/processor.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -9 # MIPS Update # # include/asm-mips/pmon.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -0 # MIPS Update # # include/asm-mips/pgtable.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -2 # MIPS Update # # include/asm-mips/pgtable-bits.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +17 -1 # MIPS Update # # include/asm-mips/pgtable-64.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +22 -11 # MIPS Update # # include/asm-mips/pgtable-32.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +37 -35 # MIPS Update # # include/asm-mips/pci.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -0 # MIPS Update # # include/asm-mips/page.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -1 # MIPS Update # # include/asm-mips/module.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +17 -2 # MIPS Update # # include/asm-mips/mmu_context.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +8 -4 # MIPS Update # # include/asm-mips/mipsregs.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # include/asm-mips/mach-yosemite/cpu-feature-overrides.h # 2004/06/24 09:19:45-07:00 akpm@osdl.org +38 -0 # # include/asm-mips/hazards.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +113 -4 # MIPS Update # # include/asm-mips/gt64240.h # 2004/06/24 09:19:45-07:00 akpm@osdl.org +1264 -0 # # include/asm-mips/cache.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -0 # MIPS Update # # include/asm-mips/atomic.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +119 -11 # MIPS Update # # include/asm-mips/asmmacro.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -1 # MIPS Update # # arch/mips/vr41xx/zao-capcella/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -60 # MIPS Update # # arch/mips/vr41xx/victor-mpc30x/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -60 # MIPS Update # # arch/mips/vr41xx/tanbac-tb0229/tb0219.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +44 -0 # # arch/mips/vr41xx/tanbac-tb0229/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -65 # MIPS Update # # arch/mips/vr41xx/tanbac-tb0229/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/vr41xx/tanbac-tb0226/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -60 # MIPS Update # # arch/mips/vr41xx/common/vrc4173.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +307 -97 # MIPS Update # # arch/mips/vr41xx/common/serial.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/vr41xx/common/rtc.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -2 # MIPS Update # # arch/mips/vr41xx/common/pmu.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -2 # MIPS Update # # arch/mips/vr41xx/common/ksyms.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -2 # MIPS Update # # arch/mips/vr41xx/common/init.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -15 # MIPS Update # # arch/mips/vr41xx/common/icu.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +315 -178 # MIPS Update # # arch/mips/vr41xx/common/giu.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +200 -42 # MIPS Update # # arch/mips/vr41xx/common/cmu.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -1 # MIPS Update # # arch/mips/vr41xx/common/bcu.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +30 -30 # MIPS Update # # arch/mips/sgi-ip22/ip22-setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -0 # MIPS Update # # arch/mips/ramdisk/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/pmc-sierra/yosemite/setup.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -17 # MIPS Update # # arch/mips/pmc-sierra/yosemite/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +110 -67 # MIPS Update # # arch/mips/pmc-sierra/yosemite/py-console.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +130 -0 # # arch/mips/pmc-sierra/yosemite/prom.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +45 -99 # MIPS Update # # arch/mips/pmc-sierra/yosemite/irq.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +78 -169 # MIPS Update # # arch/mips/pmc-sierra/yosemite/irq-handler.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +36 -51 # MIPS Update # # arch/mips/pmc-sierra/yosemite/i2c-yosemite.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +26 -26 # MIPS Update # # arch/mips/pmc-sierra/yosemite/i2c-yosemite.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +188 -0 # # arch/mips/pmc-sierra/yosemite/dbg_io.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +184 -0 # # arch/mips/pmc-sierra/yosemite/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -4 # MIPS Update # # arch/mips/pci/pci-yosemite.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +37 -0 # # arch/mips/pci/pci-vr41xx.h # 2004/06/24 01:55:59-07:00 akpm@osdl.org +137 -150 # MIPS Update # # arch/mips/pci/pci-vr41xx.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +232 -174 # MIPS Update # # arch/mips/pci/ops-vr41xx.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +126 -0 # # arch/mips/pci/ops-titan-ht.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +125 -0 # # arch/mips/pci/ops-gt64240.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +149 -0 # # arch/mips/pci/fixup-tb0219.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +64 -0 # # arch/mips/pci/fixup-ocelot-g.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +35 -0 # # arch/mips/pci/fixup-ocelot-c.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +39 -0 # # arch/mips/pci/fixup-mpc30x.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +48 -0 # # arch/mips/pci/fixup-jaguar.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +42 -0 # # arch/mips/mm/tlb-r8k.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +253 -0 # # arch/mips/kernel/module.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +53 -0 # # include/asm-mips/vr41xx/tb0219.h # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-mips/vr41xx/tb0219.h # # include/asm-mips/mach-yosemite/cpu-feature-overrides.h # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-mips/mach-yosemite/cpu-feature-overrides.h # # include/asm-mips/gt64240.h # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-mips/gt64240.h # # arch/mips/vr41xx/tanbac-tb0229/tb0219.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/vr41xx/tanbac-tb0229/tb0219.c # # arch/mips/pmc-sierra/yosemite/py-console.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pmc-sierra/yosemite/py-console.c # # arch/mips/pmc-sierra/yosemite/i2c-yosemite.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c # # arch/mips/pmc-sierra/yosemite/dbg_io.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pmc-sierra/yosemite/dbg_io.c # # arch/mips/pci/pci.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/pci/pci-yosemite.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/pci-yosemite.c # # arch/mips/pci/pci-ocelot-g.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +63 -433 # MIPS Update # # arch/mips/pci/pci-ocelot-c.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +119 -40 # MIPS Update # # arch/mips/pci/ops-vr41xx.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/ops-vr41xx.c # # arch/mips/pci/ops-titan.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +16 -16 # MIPS Update # # arch/mips/pci/ops-titan-ht.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/ops-titan-ht.c # # arch/mips/pci/ops-msc.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -1 # MIPS Update # # arch/mips/pci/ops-gt64240.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/ops-gt64240.c # # arch/mips/pci/fixup-yosemite.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -13 # MIPS Update # # arch/mips/pci/fixup-tb0226.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +61 -56 # MIPS Update # # arch/mips/pci/fixup-tb0219.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/fixup-tb0219.c # # arch/mips/pci/fixup-ocelot-g.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/fixup-ocelot-g.c # # arch/mips/pci/fixup-ocelot-c.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/fixup-ocelot-c.c # # arch/mips/pci/fixup-mpc30x.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/fixup-mpc30x.c # # arch/mips/pci/fixup-jaguar.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/pci/fixup-jaguar.c # # arch/mips/pci/fixup-capcella.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +18 -10 # MIPS Update # # arch/mips/pci/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +9 -8 # MIPS Update # # arch/mips/momentum/ocelot_g/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +58 -58 # MIPS Update # # arch/mips/momentum/ocelot_g/prom.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -6 # MIPS Update # # arch/mips/momentum/ocelot_g/gt-irq.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +7 -89 # MIPS Update # # arch/mips/momentum/ocelot_g/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -2 # MIPS Update # # arch/mips/momentum/ocelot_c/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/momentum/ocelot_c/prom.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -1 # MIPS Update # # arch/mips/momentum/ocelot_c/irq.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -1 # MIPS Update # # arch/mips/momentum/ocelot_c/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -2 # MIPS Update # # arch/mips/momentum/jaguar_atx/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/momentum/jaguar_atx/prom.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -14 # MIPS Update # # arch/mips/mm/tlbex64-r4k.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -0 # MIPS Update # # arch/mips/mm/tlbex32-r4k.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -0 # MIPS Update # # arch/mips/mm/tlbex32-r3k.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -0 # MIPS Update # # arch/mips/mm/tlb64-glue-sb1.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -0 # MIPS Update # # arch/mips/mm/tlb64-glue-r4k.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -0 # MIPS Update # # arch/mips/mm/tlb-sb1.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/mm/tlb-r8k.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/mm/tlb-r8k.c # # arch/mips/mm/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +37 -2 # MIPS Update # # arch/mips/mips-boards/generic/printf.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -32 # MIPS Update # # arch/mips/mips-boards/generic/cmdline.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -2 # MIPS Update # # arch/mips/lib-64/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +17 -5 # MIPS Update # # arch/mips/lib-32/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +17 -5 # MIPS Update # # arch/mips/kernel/traps.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +17 -42 # MIPS Update # # arch/mips/kernel/time.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -0 # MIPS Update # # arch/mips/kernel/sysirix.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/kernel/syscall.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/kernel/setup.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +10 -4 # MIPS Update # # arch/mips/kernel/semaphore.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +109 -217 # MIPS Update # # arch/mips/kernel/scall64-o32.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -0 # MIPS Update # # arch/mips/kernel/scall64-n32.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -0 # MIPS Update # # arch/mips/kernel/scall64-64.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -0 # MIPS Update # # arch/mips/kernel/scall32-o32.S # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -0 # MIPS Update # # arch/mips/kernel/module.c # 2004/06/24 09:19:45-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/kernel/module.c # # arch/mips/kernel/module-elf64.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -11 # MIPS Update # # arch/mips/kernel/module-elf32.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +0 -11 # MIPS Update # # arch/mips/kernel/cpu-probe.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +23 -23 # MIPS Update # # arch/mips/kernel/cpu-bugs64.c # 2004/06/24 01:55:59-07:00 akpm@osdl.org +24 -16 # MIPS Update # # arch/mips/kernel/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -1 # MIPS Update # # arch/mips/defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -2 # MIPS Update # # arch/mips/configs/yosemite_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +71 -110 # MIPS Update # # arch/mips/configs/xxs1500_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -1 # MIPS Update # # arch/mips/configs/workpad_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -2 # MIPS Update # # arch/mips/configs/tb0229_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -5 # MIPS Update # # arch/mips/configs/tb0226_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -4 # MIPS Update # # arch/mips/configs/sead_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -1 # MIPS Update # # arch/mips/configs/sb1250-swarm_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +28 -6 # MIPS Update # # arch/mips/configs/rm200_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +13 -4 # MIPS Update # # arch/mips/configs/pb1550_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +8 -4 # MIPS Update # # arch/mips/configs/pb1500_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +8 -4 # MIPS Update # # arch/mips/configs/pb1100_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -1 # MIPS Update # # arch/mips/configs/pb1000_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -1 # MIPS Update # # arch/mips/configs/osprey_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -2 # MIPS Update # # arch/mips/configs/ocelot_g_defconfig # 2004/06/24 09:19:44-07:00 akpm@osdl.org +587 -0 # # arch/mips/configs/ocelot_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -1 # MIPS Update # # arch/mips/configs/ocelot_c_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +44 -6 # MIPS Update # # arch/mips/configs/mtx1_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -1 # MIPS Update # # arch/mips/configs/mpc30x_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -4 # MIPS Update # # arch/mips/configs/mirage_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -1 # MIPS Update # # arch/mips/configs/malta_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -3 # MIPS Update # # arch/mips/configs/lasat200_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -4 # MIPS Update # # arch/mips/configs/jmr3927_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -3 # MIPS Update # # arch/mips/configs/jaguar-atx_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -1 # MIPS Update # # arch/mips/configs/ivr_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -4 # MIPS Update # # arch/mips/configs/it8172_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -2 # MIPS Update # # arch/mips/configs/ip32_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -3 # MIPS Update # # arch/mips/configs/ip27_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -3 # MIPS Update # # arch/mips/configs/ip22_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -2 # MIPS Update # # arch/mips/configs/ev96100_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -1 # MIPS Update # # arch/mips/configs/ev64120_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -3 # MIPS Update # # arch/mips/configs/eagle_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -5 # MIPS Update # # arch/mips/configs/e55_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -3 # MIPS Update # # arch/mips/configs/decstation_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +2 -2 # MIPS Update # # arch/mips/configs/ddb5477_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +3 -4 # MIPS Update # # arch/mips/configs/ddb5476_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -4 # MIPS Update # # arch/mips/configs/db1500_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +8 -2 # MIPS Update # # arch/mips/configs/db1100_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -1 # MIPS Update # # arch/mips/configs/db1000_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +7 -1 # MIPS Update # # arch/mips/configs/cobalt_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +4 -4 # MIPS Update # # arch/mips/configs/capcella_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -6 # MIPS Update # # arch/mips/configs/bosporus_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +6 -1 # MIPS Update # # arch/mips/configs/atlas_defconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +5 -4 # MIPS Update # # arch/mips/boot/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +1 -1 # MIPS Update # # arch/mips/Makefile # 2004/06/24 01:55:59-07:00 akpm@osdl.org +7 -2 # MIPS Update # # arch/mips/Kconfig # 2004/06/24 01:55:59-07:00 akpm@osdl.org +62 -16 # MIPS Update # # arch/mips/configs/ocelot_g_defconfig # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/mips/configs/ocelot_g_defconfig # # BitKeeper/deleted/.del-tb0229.h~777eebdad95f784 # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-mips/vr41xx/tb0229.h # # BitKeeper/deleted/.del-reboot.c~c1d87dd8c206b546 # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/vr41xx/tanbac-tb0229/reboot.c # # BitKeeper/deleted/.del-pci-irq.c~30beb0d11c7eaa53 # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/momentum/ocelot_g/pci-irq.c # # BitKeeper/deleted/.del-gt64240.h~4ef5103c279a209 # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/momentum/ocelot_g/gt64240.h # # BitKeeper/deleted/.del-fixup-victor-mpc30x.c~c0792ffcde8ca687 # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/pci/fixup-victor-mpc30x.c # # BitKeeper/deleted/.del-fixup-tb0229.c~1fd3a246de94ddf1 # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/pci/fixup-tb0229.c # # BitKeeper/deleted/.del-fixup-mv64340.c~9f2f088dc300e2cc # 2004/06/24 09:19:44-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/pci/fixup-mv64340.c # # BitKeeper/deleted/.del-tlb-dbg-r4k.c~7ba420eaa5a312da # 2004/06/24 09:19:43-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/mm-64/tlb-dbg-r4k.c # # BitKeeper/deleted/.del-pci-irq.c~d5be00f093b1363a # 2004/06/24 09:19:43-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/momentum/ocelot_c/pci-irq.c # # BitKeeper/deleted/.del-gt64240_dep.h~6bf32fd1dcbb485c # 2004/06/24 09:19:43-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/momentum/ocelot_g/gt64240_dep.h # # BitKeeper/deleted/.del-Makefile~a1f1375a6d4de637 # 2004/06/24 09:19:43-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/mm-64/Makefile # # BitKeeper/deleted/.del-Makefile~864ffc0fb6b0fff # 2004/06/24 09:19:43-07:00 akpm@osdl.org +0 -0 # Delete: arch/mips/mm-32/Makefile # # ChangeSet # 2004/06/24 08:56:30-07:00 akpm@osdl.org # [PATCH] Dell laptop lockup fix for ALSA # # From: Alan Cox # # OSS avoids the Dell lockup by not hitting the problem register (which # apparently breaks resume on a Sony laptop). ALSA keeps a flag and uses pci # subvendor info to clear it for problem Dell laptops. Unfortunately there # is at least one other Dell laptop which is affected. This adds its sub # id's # # [Patch from Dan Williams @ Red Hat slightly reformatted by me] # # Signed-off-by: Alan Cox # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/pci/nm256/nm256.c # 2004/06/24 01:55:58-07:00 akpm@osdl.org +4 -0 # Dell laptop lockup fix for ALSA # # ChangeSet # 2004/06/24 08:56:19-07:00 akpm@osdl.org # [PATCH] mips: SGI A2 audio rewrite and 2.6 fixes # # From: Ralf Baechle # # Fix HAL2 audio driver for the SGI A2 audio subsystem and rewrite large # parts of it to finally work. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/oss/hal2.h # 2004/06/24 01:55:58-07:00 akpm@osdl.org +40 -120 # mips: SGI A2 audio rewrite and 2.6 fixes # # sound/oss/hal2.c # 2004/06/24 01:55:58-07:00 akpm@osdl.org +612 -549 # mips: SGI A2 audio rewrite and 2.6 fixes # # sound/oss/Kconfig # 2004/06/24 01:55:58-07:00 akpm@osdl.org +4 -1 # mips: SGI A2 audio rewrite and 2.6 fixes # # ChangeSet # 2004/06/24 08:56:08-07:00 akpm@osdl.org # [PATCH] make total_swap_pages a long # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/swapfile.c # 2004/06/24 01:55:58-07:00 akpm@osdl.org +1 -1 # make total_swap_pages a long # # include/linux/swap.h # 2004/06/24 01:55:58-07:00 akpm@osdl.org +1 -1 # make total_swap_pages a long # # ChangeSet # 2004/06/24 08:55:56-07:00 akpm@osdl.org # [PATCH] Make nr_swap_pages a long # # From: Anton Blanchard # # ../include/linux/swap.h:extern int nr_swap_pages; /* XXX: shouldn't this be ulong? --hch */ # # Sounds like it should be too me. Some of the code checks for nr_swap_pages # < 0 so I made it a long instead. I had to fix up the ppc64 show_mem() (Im # guessing there will be other trivial changes required in other 64bit archs, # I can find and fix those if you want). # # I also noticed that the ppc64 show_mem() used ints to store page counts. # We can overflow that, so make them unsigned long. # # Signed-off-by: Anton Blanchard # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/page_alloc.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # include/linux/swap.h # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/x86_64/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/um/kernel/mem.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/sparc64/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/sparc/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/sh/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/s390/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/ppc64/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +7 -7 # Make nr_swap_pages a long # # arch/ppc/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/parisc/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +2 -1 # Make nr_swap_pages a long # # arch/mips/mm/pgtable.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/m68k/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/m68k/atari/stram.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +2 -2 # Make nr_swap_pages a long # # arch/ia64/mm/discontig.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/ia64/mm/contig.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/i386/mm/pgtable.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/cris/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/arm26/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/arm/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/alpha/mm/numa.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # arch/alpha/mm/init.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +1 -1 # Make nr_swap_pages a long # # ChangeSet # 2004/06/24 08:55:44-07:00 akpm@osdl.org # [PATCH] nr_pagecache can go negative # # We use per-cpu counters for the system-wide pagecache accounting. The # counters spill into the global nr_pagecache atomic_t when they underflow or # overflow. # # Hence it is possible, under weird circumstances, for nr_pagecache to go # negative. Anton says he has hit this. # # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/pagemap.h # 2004/06/24 01:55:57-07:00 akpm@osdl.org +5 -1 # nr_pagecache can go negative # # ChangeSet # 2004/06/24 08:55:33-07:00 akpm@osdl.org # [PATCH] help text for FB_RIVA_I2C # # From: "Antonino A. Daplas" # # Signed-off-by: Antonino Daplas # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/Kconfig # 2004/06/24 01:55:57-07:00 akpm@osdl.org +7 -0 # help text for FB_RIVA_I2C # # ChangeSet # 2004/06/24 08:55:22-07:00 akpm@osdl.org # [PATCH] Support NetMOS based PCI cards providing serial and parallel ports # # From: Christoph Lameter # # Attached a patch to support a variety of PCI based serial and parallel port # I/O ports (typically labeled 222N-2 or 9835). # # I think this should go into 2.6.0 since it has been out there for a long # time and is just some additional driver support that somehow fell through # the cracks in 2.4.X. Tim Waugh submitted it in the 2.4.X series. # # See also http://winterwolf.co.uk/pciio # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/pci_ids.h # 2004/06/24 01:55:57-07:00 akpm@osdl.org +4 -0 # Support NetMOS based PCI cards providing serial and parallel ports # # drivers/parport/parport_serial.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +10 -0 # Support NetMOS based PCI cards providing serial and parallel ports # # drivers/parport/parport_pc.c # 2004/06/24 01:55:57-07:00 akpm@osdl.org +17 -0 # Support NetMOS based PCI cards providing serial and parallel ports # # drivers/parport/ChangeLog # 2004/06/24 01:55:57-07:00 akpm@osdl.org +4 -0 # Support NetMOS based PCI cards providing serial and parallel ports # # ChangeSet # 2004/06/24 08:55:11-07:00 akpm@osdl.org # [PATCH] abs() fixes # # OK, the pending abs() disaster has hit: # # drivers/usb/class/audio.c:404: warning: static declaration of 'abs' follows non-static declaration # # This is due to the declaration in kernel.h. AFAIK there's not even a matching # definition for that. # # The patch implements abs() as a macro in kernel.h and kills off various # private implementations. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/kernel.h # 2004/06/24 01:55:56-07:00 akpm@osdl.org +10 -1 # abs() fixes # # include/asm-ppc64/system.h # 2004/06/24 01:55:56-07:00 akpm@osdl.org +0 -2 # abs() fixes # # drivers/usb/class/audio.c # 2004/06/24 01:55:56-07:00 akpm@osdl.org +0 -14 # abs() fixes # # arch/ppc64/kernel/ppc_ksyms.c # 2004/06/24 01:55:56-07:00 akpm@osdl.org +0 -4 # abs() fixes # # ChangeSet # 2004/06/24 08:55:00-07:00 akpm@osdl.org # [PATCH] reduce function inlining in slab.c # # From: Manfred Spraul # # slab.c contains too many inline functions: # # - some functions that are not performance critical were inlined. Waste # of text size. # # - The debug code relies on __builtin_return_address(0) to keep track of # the callers. According to rmk, gcc didn't inline some functions as # expected and that resulted in useless debug output. This was probably # caused by the large debug-only inline functions. # # The attached patche removes most inline functions: # # - the empty on release/huge on debug inline functions were replaced with # empty macros on release/normal functions on debug. # # - spurious inline statements were removed. # # The code is down to 6 inline functions: three one-liners for struct # abstractions, one for a might_sleep_if test and two for the performance # critical __cache_alloc / __cache_free functions. # # Note: If an embedded arch wants to save a few bytes by uninlining # __cache_{free,alloc}: The right way to do that is to fold the functions # into kmem_cache_xy and then replace kmalloc with # kmem_cache_alloc(kmem_find_general_cachep(),). # # Signed-Off: Manfred Spraul # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/slab.c # 2004/06/24 01:55:56-07:00 akpm@osdl.org +37 -47 # reduce function inlining in slab.c # # ChangeSet # 2004/06/24 08:54:49-07:00 akpm@osdl.org # [PATCH] hwcache align kmalloc caches # # From: Manfred Spraul # # Reversing the patches that made all caches hw cacheline aligned had an # unintended side effect on the kmalloc caches: Before they had the # SLAB_HWCACHE_ALIGN flag set, now it's clear. This breaks one sgi driver - # it expects aligned caches. Additionally I think it's the right thing to # do: It costs virtually nothing (the caches are power-of-two sized) and # could reduce false sharing. # # Additionally, the patch adds back the documentation for the # SLAB_HWCACHE_ALIGN flag. # # Signed-Off: Manfred Spraul # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/slab.c # 2004/06/24 01:55:56-07:00 akpm@osdl.org +10 -4 # hwcache align kmalloc caches # # ChangeSet # 2004/06/24 08:54:38-07:00 akpm@osdl.org # [PATCH] tweak the buddy allocator for better I/O merging # # From: William Lee Irwin III # # Based on Arjan van de Ven's idea, with guidance and testing from James # Bottomley. # # The physical ordering of pages delivered to the IO subsystem is strongly # related to the order in which fragments are subdivided from larger blocks # of memory tracked by the page allocator. # # Consider a single MAX_ORDER block of memory in isolation acted on by a # sequence of order 0 allocations in an otherwise empty buddy system. # Subdividing the block beginning at the highest addresses will yield all the # pages of the block in reverse, and subdividing the block begining at the # lowest addresses will yield all the pages of the block in physical address # order. # # Empirical tests demonstrate this ordering is preserved, and that changing # the order of subdivision so that the lowest page is split off first # resolves the sglist merging difficulties encountered by driver authors at # Adaptec and others in James Bottomley's testing. # # James found that before this patch, there were 40 merges out of about 32K # segments. Afterward, there were 24007 merges out of 19513 segments, for a # merge rate of about 55%. Merges of 128 segments, the maximum allowed, were # observed afterward, where beforehand they never occurred. It also improves # dbench on my workstation and works fine there. # # Signed-off-by: William Lee Irwin III # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/page_alloc.c # 2004/06/24 01:55:56-07:00 akpm@osdl.org +17 -5 # tweak the buddy allocator for better I/O merging # # ChangeSet # 2004/06/24 08:54:26-07:00 akpm@osdl.org # [PATCH] Use fancy wakeups in wait.h # # Use the more SMP-friendly prepare_to_wait()/finish_wait() in wait_event() and # friends. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/wait.h # 2004/06/24 01:55:55-07:00 akpm@osdl.org +13 -24 # Use fancy wakeups in wait.h # # ChangeSet # 2004/06/24 08:54:15-07:00 akpm@osdl.org # [PATCH] dnotify.c: use inode->i_lock in place of dn_lock # # From: "Adam J. Richter" # # Replace the use of a global spinlock with the per-inode ->i_lock. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/dnotify.c # 2004/06/24 01:55:55-07:00 akpm@osdl.org +10 -10 # dnotify.c: use inode->i_lock in place of dn_lock # # ChangeSet # 2004/06/24 08:54:04-07:00 akpm@osdl.org # [PATCH] vm: vfs shrinkage tuning # # Some people want the dentry and inode caches shrink harder, others want them # shrunk more reluctantly. # # The patch adds /proc/sys/vm/vfs_cache_pressure, which tunes the vfs cache # versus pagecache scanning pressure. # # - at vfs_cache_pressure=0 we don't shrink dcache and icache at all. # # - at vfs_cache_pressure=100 there is no change in behaviour. # # - at vfs_cache_pressure > 100 we reclaim dentries and inodes harder. # # # The number of megabytes of slab left after a slocate.cron on my 256MB test # box: # # vfs_cache_pressure=100000 33480 # vfs_cache_pressure=10000 61996 # vfs_cache_pressure=1000 104056 # vfs_cache_pressure=200 166340 # vfs_cache_pressure=100 190200 # vfs_cache_pressure=50 206168 # # Of course, this just left more directory and inode pagecache behind instead of # vfs cache. Interestingly, on this machine the entire slocate run fits into # pagecache, but not into VFS caches. # # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sysctl.c # 2004/06/24 01:55:55-07:00 akpm@osdl.org +12 -0 # vm: vfs shrinkage tuning # # include/linux/sysctl.h # 2004/06/24 01:55:55-07:00 akpm@osdl.org +1 -0 # vm: vfs shrinkage tuning # # include/linux/dcache.h # 2004/06/24 01:55:55-07:00 akpm@osdl.org +2 -0 # vm: vfs shrinkage tuning # # fs/inode.c # 2004/06/24 01:55:55-07:00 akpm@osdl.org +1 -1 # vm: vfs shrinkage tuning # # fs/dcache.c # 2004/06/24 01:55:55-07:00 akpm@osdl.org +3 -2 # vm: vfs shrinkage tuning # # Documentation/sysctl/vm.txt # 2004/06/24 01:55:55-07:00 akpm@osdl.org +1 -1 # vm: vfs shrinkage tuning # # Documentation/filesystems/proc.txt # 2004/06/24 01:55:55-07:00 akpm@osdl.org +12 -0 # vm: vfs shrinkage tuning # # ChangeSet # 2004/06/24 08:53:52-07:00 akpm@osdl.org # [PATCH] vmscan.c: dont reclaim too many pages # # The shrink_zone() logic can, under some circumstances, cause far too many # pages to be reclaimed. Say, we're scanning at high priority and suddenly hit # a large number of reclaimable pages on the LRU. # # Change things so we bale out when SWAP_CLUSTER_MAX pages have been reclaimed. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/vmscan.c # 2004/06/24 01:55:55-07:00 akpm@osdl.org +8 -0 # vmscan.c: dont reclaim too many pages # # ChangeSet # 2004/06/24 08:53:40-07:00 akpm@osdl.org # [PATCH] vmscan.c scan rate fixes # # We've been futzing with the scan rates of the inactive and active lists far # too much, and it's still not right (Anton reports interrupt-off times of over # a second). # # - We have this logic in there from 2.4.early (at least) which tries to keep # the inactive list 1/3rd the size of the active list. Or something. # # I really cannot see any logic behind this, so toss it out and change the # arithmetic in there so that all pages on both lists have equal scan rates. # # - Chunk the work up so we never hold interrupts off for more that 32 pages # worth of scanning. # # - Make the per-zone scan-count accumulators unsigned long rather than # atomic_t. # # Mainly because atomic_t's could conceivably overflow, but also because # access to these counters is racy-by-design anyway. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/vmscan.c # 2004/06/24 01:55:54-07:00 akpm@osdl.org +32 -40 # vmscan.c scan rate fixes # # mm/page_alloc.c # 2004/06/24 01:55:54-07:00 akpm@osdl.org +2 -2 # vmscan.c scan rate fixes # # include/linux/mmzone.h # 2004/06/24 01:55:54-07:00 akpm@osdl.org +2 -2 # vmscan.c scan rate fixes # # ChangeSet # 2004/06/24 08:53:29-07:00 akpm@osdl.org # [PATCH] vmscan.c: shuffle things around # # Move all the data structure declarations, macros and variable definitions to # less surprising places. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/vmscan.c # 2004/06/24 01:55:54-07:00 akpm@osdl.org +45 -47 # vmscan.c: shuffle things around # # ChangeSet # 2004/06/24 08:53:18-07:00 akpm@osdl.org # [PATCH] Fix and Reenable MSI Support on x86_64 # # From: long # # MSI support for x86_64 is currently disabled in the kernel 2.6.x. Below is # the patch, which provides a fix and reenable it. # # In addition, the patch provides a info message during kernel boot if # configuring vector-base indexing. # # Cc: Andi Kleen # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-x86_64/msi.h # 2004/06/24 01:55:54-07:00 akpm@osdl.org +1 -6 # Fix and Reenable MSI Support on x86_64 # # include/asm-x86_64/hw_irq.h # 2004/06/24 01:55:54-07:00 akpm@osdl.org +1 -0 # Fix and Reenable MSI Support on x86_64 # # drivers/pci/Kconfig # 2004/06/24 01:55:54-07:00 akpm@osdl.org +1 -1 # Fix and Reenable MSI Support on x86_64 # # arch/x86_64/kernel/io_apic.c # 2004/06/24 01:55:54-07:00 akpm@osdl.org +18 -8 # Fix and Reenable MSI Support on x86_64 # # arch/x86_64/kernel/i8259.c # 2004/06/24 01:55:54-07:00 akpm@osdl.org +24 -0 # Fix and Reenable MSI Support on x86_64 # # arch/i386/kernel/io_apic.c # 2004/06/24 01:55:54-07:00 akpm@osdl.org +6 -1 # Fix and Reenable MSI Support on x86_64 # # ChangeSet # 2004/06/24 08:53:08-07:00 akpm@osdl.org # [PATCH] make irqaction use a cpu mask # # From: William Lee Irwin III # # The following patch makes irqaction's ->mask a cpumask as it was intended # to be and wraps up the rest of the sweep. Only struct irqaction is # usefully greppable, so there may be some assignments to ->mask missing # still. This removes more code than it adds. # # From: William Lee Irwin III # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/interrupt.h # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -1 # make irqaction use a cpu mask # # arch/x86_64/kernel/time.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/x86_64/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/x86_64/kernel/i8259.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/v850/kernel/time.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/v850/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/v850/kernel/fpga85e2c.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/um/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/sparc64/kernel/smp.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +0 -3 # make irqaction use a cpu mask # # arch/sparc64/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +10 -58 # make irqaction use a cpu mask # # arch/sparc/kernel/sun4d_irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/sparc/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/sh/kernel/time.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/sh/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/sh/cchips/hd6446x/hd64465/setup.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/sh/cchips/hd6446x/hd64461/setup.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/ppc64/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/ppc/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/parisc/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/vr41xx/common/icu.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/vr41xx/common/giu.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/vr4181/common/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/mips/tx4927/common/tx4927_irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/sibyte/sb1250/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/sgi-ip32/ip32-irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/mips/momentum/ocelot_c/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/mips/momentum/jaguar_atx/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/jmr3927/rbhma3100/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +4 -4 # make irqaction use a cpu mask # # arch/mips/gt64120/common/time.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/ddb5xxx/ddb5477/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/ddb5xxx/ddb5476/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/mips/ddb5xxx/ddb5074/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/baget/time.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/mips/baget/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/ia64/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/i386/mach-voyager/setup.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/i386/mach-default/setup.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # make irqaction use a cpu mask # # arch/i386/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/i386/kernel/i8259.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/cris/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/cris/arch-v10/kernel/time.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/arm26/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/arm/mach-clps7500/core.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/arm/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # arch/alpha/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -1 # make irqaction use a cpu mask # # ChangeSet # 2004/06/24 08:52:55-07:00 akpm@osdl.org # [PATCH] alpha: cpumask fixups # # From: William Lee Irwin III # # The cpumask patches broke alpha's build, even without the irqaction # patch, largely centering around cpu_possible_map. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-alpha/smp.h # 2004/06/24 01:55:53-07:00 akpm@osdl.org +1 -3 # alpha: cpumask fixups # # arch/alpha/kernel/sys_dp264.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +8 -9 # alpha: cpumask fixups # # arch/alpha/kernel/smp.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +17 -22 # alpha: cpumask fixups # # arch/alpha/kernel/setup.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # alpha: cpumask fixups # # arch/alpha/kernel/process.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +2 -2 # alpha: cpumask fixups # # arch/alpha/kernel/irq.c # 2004/06/24 01:55:53-07:00 akpm@osdl.org +11 -52 # alpha: cpumask fixups # # ChangeSet # 2004/06/24 08:52:44-07:00 akpm@osdl.org # [PATCH] clean up cpumask_t temporaries # # From: Rusty Russell # # Paul Jackson's cpumask tour-de-force allows us to get rid of those stupid # temporaries which we used to hold CPU_MASK_ALL to hand them to functions. # This used to break NR_CPUS > BITS_PER_LONG. # # Signed-off-by: Rusty Russell # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sched.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +2 -3 # clean up cpumask_t temporaries # # kernel/kthread.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -2 # clean up cpumask_t temporaries # # kernel/kmod.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -2 # clean up cpumask_t temporaries # # include/asm-i386/mach-summit/mach_apic.h # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -2 # clean up cpumask_t temporaries # # include/asm-i386/mach-numaq/mach_apic.h # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -2 # clean up cpumask_t temporaries # # arch/ppc64/kernel/xics.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +2 -4 # clean up cpumask_t temporaries # # arch/ppc64/kernel/rtasd.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -2 # clean up cpumask_t temporaries # # arch/ppc64/kernel/irq.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -2 # clean up cpumask_t temporaries # # ChangeSet # 2004/06/24 08:52:33-07:00 akpm@osdl.org # [PATCH] cpumask: comment, spacing tweaks # # From: Paul Jackson # # Tweak cpumask.h comments, spacing: # # - Add comments for cpu_present_map macros: num_present_cpus() and # cpu_present() # # - Remove comments for obsolete macros: cpu_set_online(), # cpu_set_offline() # # - Reorder a few comment lines, to match the code and confuse readers of # this patch # # - Tabify one chunk of code # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/cpumask.h # 2004/06/24 01:55:52-07:00 akpm@osdl.org +19 -15 # cpumask: comment, spacing tweaks # # ChangeSet # 2004/06/24 08:52:21-07:00 akpm@osdl.org # [PATCH] cpumask: optimize various uses of new cpumasks # # From: Paul Jackson # # Make use of for_each_cpu_mask() macro to simplify and optimize a couple of # sparc64 per-CPU loops. # # Optimize a bit of cpumask code for asm-i386/mach-es7000 # # Convert physids_complement() to use both args in the files # include/asm-i386/mpspec.h, include/asm-x86_64/mpspec.h. # # Remove cpumask hack from asm-x86_64/topology.h routine pcibus_to_cpumask(). # # Clarify and slightly optimize several cpumask manipulations in kernel/sched.c # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sched.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +7 -11 # cpumask: optimize various uses of new cpumasks # # include/asm-x86_64/topology.h # 2004/06/24 01:55:52-07:00 akpm@osdl.org +4 -2 # cpumask: optimize various uses of new cpumasks # # include/asm-x86_64/mpspec.h # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -1 # cpumask: optimize various uses of new cpumasks # # include/asm-i386/mpspec.h # 2004/06/24 01:55:52-07:00 akpm@osdl.org +1 -1 # cpumask: optimize various uses of new cpumasks # # include/asm-i386/mach-es7000/mach_ipi.h # 2004/06/24 01:55:52-07:00 akpm@osdl.org +2 -3 # cpumask: optimize various uses of new cpumasks # # arch/sparc64/kernel/smp.c # 2004/06/24 01:55:52-07:00 akpm@osdl.org +24 -42 # cpumask: optimize various uses of new cpumasks # # ChangeSet # 2004/06/24 08:52:10-07:00 akpm@osdl.org # [PATCH] cpumask: Remove no longer used obsolete macro emulation # # From: Paul Jackson # # Now that the emulation of the obsolete cpumask macros is no longer needed, # remove it from cpumask.h # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/cpumask.h # 2004/06/24 01:55:51-07:00 akpm@osdl.org +0 -12 # cpumask: Remove no longer used obsolete macro emulation # # ChangeSet # 2004/06/24 08:51:59-07:00 akpm@osdl.org # [PATCH] ppc64: cpu_online fix # # include/asm/smp.h:55:1: warning: "cpu_possible" redefined # include/asm/smp.h:54:1: warning: "cpu_online" redefined # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-ppc64/smp.h # 2004/06/24 01:55:51-07:00 akpm@osdl.org +0 -2 # ppc64: cpu_online fix # # ChangeSet # 2004/06/24 08:51:48-07:00 akpm@osdl.org # [PATCH] x86_64: cpu_online fix # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-x86_64/smp.h # 2004/06/24 01:55:51-07:00 akpm@osdl.org +0 -1 # x86_64: cpu_online fix # # ChangeSet # 2004/06/24 08:51:37-07:00 akpm@osdl.org # [PATCH] cpumask: remove obsolete cpumask macro uses - other archs # # From: Paul Jackson # # Remove by recoding other uses of the obsolete cpumask const, coerce and # promote macros. # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-x86_64/smp.h # 2004/06/24 01:55:51-07:00 akpm@osdl.org +2 -3 # cpumask: remove obsolete cpumask macro uses - other archs # # arch/x86_64/kernel/smp.c # 2004/06/24 01:55:51-07:00 akpm@osdl.org +1 -1 # cpumask: remove obsolete cpumask macro uses - other archs # # arch/x86_64/kernel/pci-gart.c # 2004/06/24 01:55:51-07:00 akpm@osdl.org +2 -2 # cpumask: remove obsolete cpumask macro uses - other archs # # arch/x86_64/kernel/io_apic.c # 2004/06/24 01:55:51-07:00 akpm@osdl.org +1 -1 # cpumask: remove obsolete cpumask macro uses - other archs # # arch/ppc64/kernel/rtasd.c # 2004/06/24 01:55:51-07:00 akpm@osdl.org +3 -3 # cpumask: remove obsolete cpumask macro uses - other archs # # arch/ppc64/kernel/open_pic.c # 2004/06/24 01:55:51-07:00 akpm@osdl.org +4 -4 # cpumask: remove obsolete cpumask macro uses - other archs # # ChangeSet # 2004/06/24 08:51:25-07:00 akpm@osdl.org # [PATCH] cpumask: remove obsolete cpumask macro uses - i386 arch # # From: Paul Jackson # # Remove by recoding i386 uses of the obsolete cpumask const, coerce and promote # macros. # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/mach-visws/mach_apic.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +2 -2 # cpumask: remove obsolete cpumask macro uses - i386 arch # # include/asm-i386/mach-summit/mach_apic.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +4 -4 # cpumask: remove obsolete cpumask macro uses - i386 arch # # include/asm-i386/mach-numaq/mach_apic.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +1 -1 # cpumask: remove obsolete cpumask macro uses - i386 arch # # include/asm-i386/mach-es7000/mach_apic.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +5 -5 # cpumask: remove obsolete cpumask macro uses - i386 arch # # include/asm-i386/mach-default/mach_apic.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +5 -5 # cpumask: remove obsolete cpumask macro uses - i386 arch # # include/asm-i386/mach-bigsmp/mach_apic.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +5 -5 # cpumask: remove obsolete cpumask macro uses - i386 arch # # include/asm-i386/genapic.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +1 -1 # cpumask: remove obsolete cpumask macro uses - i386 arch # # arch/i386/mach-voyager/voyager_smp.c # 2004/06/24 01:55:50-07:00 akpm@osdl.org +15 -15 # cpumask: remove obsolete cpumask macro uses - i386 arch # # arch/i386/kernel/smp.c # 2004/06/24 01:55:50-07:00 akpm@osdl.org +1 -1 # cpumask: remove obsolete cpumask macro uses - i386 arch # # arch/i386/kernel/io_apic.c # 2004/06/24 01:55:50-07:00 akpm@osdl.org +1 -1 # cpumask: remove obsolete cpumask macro uses - i386 arch # # ChangeSet # 2004/06/24 08:51:14-07:00 akpm@osdl.org # [PATCH] cpumask: remove 26 no longer used cpumask*.h files # # From: Paul Jackson # # With the cpumask rewrite in the previous patch, these various # include/asm-*/cpumask*.h headers are no longer used. # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # BitKeeper/deleted/.del-cpumask.h~a5bbafe984f5d0e6 # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-sparc/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~745e0907bd87604e # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-ppc/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~6ec2788c63d1687b # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-x86_64/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~580452f41482fe23 # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-sparc64/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~3b3abff5bcf38cc9 # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-sh/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~387b5d1b6127111b # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-um/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~1ed7ae938e67370 # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-v850/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~12d20004ea3a06a9 # 2004/06/24 08:51:08-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-s390/cpumask.h # # BitKeeper/deleted/.del-cpumask_up.h~5ae8a8bbe33655aa # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-generic/cpumask_up.h # # BitKeeper/deleted/.del-cpumask_const_value.h~37c848f3b2549e56 # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-generic/cpumask_const_value.h # # BitKeeper/deleted/.del-cpumask_const_reference.h~a6bcb3d0a8cd5572 # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-generic/cpumask_const_reference.h # # BitKeeper/deleted/.del-cpumask_array.h~d8dbb4ef332b6641 # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-generic/cpumask_array.h # # BitKeeper/deleted/.del-cpumask.h~ef85c5f62cd09ecc # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-ia64/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~d00e324a21611d5e # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-h8300/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~9c3000d85a9eb2c3 # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-m68knommu/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~95753b8b1b5eadfd # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-mips/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~8f5805a145d3479 # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-ppc64/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~691fe59423e88649 # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-m68k/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~36e5486b7d611984 # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-i386/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~3651679af4088f3f # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-generic/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~19435a516253afde # 2004/06/24 08:51:07-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-parisc/cpumask.h # # BitKeeper/deleted/.del-cpumask_arith.h~60abfed510eafce # 2004/06/24 08:51:06-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-generic/cpumask_arith.h # # BitKeeper/deleted/.del-cpumask.h~e7ecd1e7ac7c6566 # 2004/06/24 08:51:06-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-cris/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~cb61c8489d907dae # 2004/06/24 08:51:06-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-alpha/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~2e2628a36ae6cbb # 2004/06/24 08:51:06-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-arm/cpumask.h # # BitKeeper/deleted/.del-cpumask.h~2c95bed74d074fe0 # 2004/06/24 08:51:06-07:00 akpm@osdl.org +0 -0 # Delete: include/asm-arm26/cpumask.h # # ChangeSet # 2004/06/24 08:51:00-07:00 akpm@osdl.org # [PATCH] cpumask: rewrite cpumask.h - single bitmap based implementation # # From: Paul Jackson # # Major rewrite of cpumask to use a single implementation, as a struct-wrapped # bitmap. # # This patch leaves some 26 include/asm-*/cpumask*.h header files orphaned - to # be removed next patch. # # Some nine cpumask macros for const variants and to coerce and promote between # an unsigned long and a cpumask are obsolete. Simple emulation wrappers are # provided in this patch for these obsolete macros, which can be removed once # each of the 3 archs (i386, ppc64, x86_64) using them are recoded in follow-on # patches to not need them. # # The CPU_MASK_ALL macro now avoids leaving possible garbage one bits in any # unused portion of the high word. # # An inproved comment lists all available operators, for convenient browsing. # # From: Mikael Pettersson # # 2.6.7-rc3-mm1 changed CPU_MASK_NONE into something that isn't a valid # rvalue (it only works inside struct initializers). This caused compile-time # errors in perfctr in UP x86 builds. # # From: Arnd Bergmann # # cpumask-5-10-rewrite-cpumaskh-single-bitmap-based from 2.6.7-rc3-mm1 # causes include2/asm/smp.h:54:1: warning: "cpu_online" redefined # # Signed-off-by: Paul Jackson # Signed-off-by: Mikael Pettersson # Signed-off-by: Arnd Bergmann # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sched.c # 2004/06/24 01:55:50-07:00 akpm@osdl.org +5 -0 # cpumask: rewrite cpumask.h - single bitmap based implementation # # kernel/rcupdate.c # 2004/06/24 01:55:50-07:00 akpm@osdl.org +2 -5 # cpumask: rewrite cpumask.h - single bitmap based implementation # # include/linux/cpumask.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +360 -34 # cpumask: rewrite cpumask.h - single bitmap based implementation # # include/asm-s390/smp.h # 2004/06/24 01:55:50-07:00 akpm@osdl.org +0 -6 # cpumask: rewrite cpumask.h - single bitmap based implementation # # arch/sparc64/kernel/irq.c # 2004/06/24 01:55:50-07:00 akpm@osdl.org +4 -2 # cpumask: rewrite cpumask.h - single bitmap based implementation # # ChangeSet # 2004/06/24 08:50:51-07:00 akpm@osdl.org # [PATCH] cpumask: bitmap inlining and optimizations # # From: Paul Jackson # # These bitmap improvements make it a suitable basis for fully supporting # cpumask_t and nodemask_t. Inline macros with compile-time checks enable # generating tight code on both small and large systems (large meaning cpumask_t # requires more than one unsigned long's worth of bits). # # The existing bitmap_ macros in lib/bitmap.c are renamed to __bitmap_, # and wrappers for each bitmap_ are exposed in include/linux/bitmap.h # # This patch _includes_ Bill Irwins rewrite of the bitmap_shift operators to not # require a fixed length intermediate bitmap. # # Improved comments list each available operator for easy browsing. # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # lib/bitmap.c # 2004/06/24 01:55:49-07:00 akpm@osdl.org +47 -44 # cpumask: bitmap inlining and optimizations # # include/linux/bitmap.h # 2004/06/24 01:55:49-07:00 akpm@osdl.org +228 -36 # cpumask: bitmap inlining and optimizations # # ChangeSet # 2004/06/24 08:50:40-07:00 akpm@osdl.org # [PATCH] cpumask: bitmap cleanup preparation for cpumask overhaul # # From: Paul Jackson # # Document the bitmap bit model and handling of unused bits. # # Tighten up bitmap so it does not generate nonzero bits in the unused tail if # it is not given any on input. # # Add intersects, subset, xor and andnot operators. Change bitmap_complement to # take two operands. # # Add a couple of missing 'const' qualifiers on bitops test_bit and bitmap_equal # args. # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/mempolicy.c # 2004/06/24 01:55:49-07:00 akpm@osdl.org +5 -7 # cpumask: bitmap cleanup preparation for cpumask overhaul # # lib/bitmap.c # 2004/06/24 01:55:49-07:00 akpm@osdl.org +81 -6 # cpumask: bitmap cleanup preparation for cpumask overhaul # # include/linux/bitmap.h # 2004/06/24 01:55:49-07:00 akpm@osdl.org +10 -2 # cpumask: bitmap cleanup preparation for cpumask overhaul # # include/asm-x86_64/mpspec.h # 2004/06/24 01:55:49-07:00 akpm@osdl.org +1 -1 # cpumask: bitmap cleanup preparation for cpumask overhaul # # include/asm-i386/mpspec.h # 2004/06/24 01:55:49-07:00 akpm@osdl.org +1 -1 # cpumask: bitmap cleanup preparation for cpumask overhaul # # include/asm-generic/cpumask_array.h # 2004/06/24 01:55:49-07:00 akpm@osdl.org +1 -1 # cpumask: bitmap cleanup preparation for cpumask overhaul # # include/asm-generic/bitops.h # 2004/06/24 01:55:49-07:00 akpm@osdl.org +1 -1 # cpumask: bitmap cleanup preparation for cpumask overhaul # # arch/x86_64/kernel/smpboot.c # 2004/06/24 01:55:49-07:00 akpm@osdl.org +1 -1 # cpumask: bitmap cleanup preparation for cpumask overhaul # # ChangeSet # 2004/06/24 08:50:29-07:00 akpm@osdl.org # [PATCH] cpumask: make cpu_present_map real even on non-smp # # From: Paul Jackson # # This patch makes cpu_present_map a real map for all configurations, instead of # a constant for non-SMP. It also moves the definition of cpu_present_map out # of kernel/cpu.c into kernel/sched.c, because cpu.c isn't compiled into non-SMP # kernels. # # The pattern is that each of the possible, present and online cpu maps are # actual kernel global cpumask_t variables, for all configurations. They are # documented in include/linux/cpumask.h. Some of the UP (NR_CPUS=1) code # cheats, and hardcodes the assumption that the single bit position of these # maps is always set, as an optimization. # # Signed-off-by: Paul Jackson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sched.c # 2004/06/24 01:55:49-07:00 akpm@osdl.org +10 -0 # cpumask: make cpu_present_map real even on non-smp # # kernel/cpu.c # 2004/06/24 01:55:49-07:00 akpm@osdl.org +0 -8 # cpumask: make cpu_present_map real even on non-smp # # include/linux/cpumask.h # 2004/06/24 01:55:49-07:00 akpm@osdl.org +5 -8 # cpumask: make cpu_present_map real even on non-smp # # ChangeSet # 2004/06/24 08:50:18-07:00 akpm@osdl.org # [PATCH] rcu: avoid passing an argument to the callback function # # From: Dipankar Sarma # # This patch changes the call_rcu() API and avoids passing an argument to the # callback function as suggested by Rusty. Instead, it is assumed that the # user has embedded the rcu head into a structure that is useful in the # callback and the rcu_head pointer is passed to the callback. The callback # can use container_of() to get the pointer to its structure and work with # it. Together with the rcu-singly-link patch, it reduces the rcu_head size # by 50%. Considering that we use these in things like struct dentry and # struct dst_entry, this is good savings in space. # # An example : # # struct my_struct { # struct rcu_head rcu; # int x; # int y; # }; # # void my_rcu_callback(struct rcu_head *head) # { # struct my_struct *p = container_of(head, struct my_struct, rcu); # free(p); # } # # void my_delete(struct my_struct *p) # { # ... # call_rcu(&p->rcu, my_rcu_callback); # ... # } # # Signed-Off-By: Dipankar Sarma # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # security/selinux/netif.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +3 -3 # rcu: avoid passing an argument to the callback function # # net/sched/sch_generic.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +3 -3 # rcu: avoid passing an argument to the callback function # # net/ipv4/route.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +2 -2 # rcu: avoid passing an argument to the callback function # # net/decnet/dn_route.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +2 -2 # rcu: avoid passing an argument to the callback function # # net/bridge/br_if.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +9 -3 # rcu: avoid passing an argument to the callback function # # kernel/rcupdate.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +16 -10 # rcu: avoid passing an argument to the callback function # # kernel/auditsc.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +4 -3 # rcu: avoid passing an argument to the callback function # # ipc/util.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +20 -5 # rcu: avoid passing an argument to the callback function # # include/net/dst.h # 2004/06/24 01:55:48-07:00 akpm@osdl.org +6 -0 # rcu: avoid passing an argument to the callback function # # include/linux/rcupdate.h # 2004/06/24 01:55:48-07:00 akpm@osdl.org +4 -6 # rcu: avoid passing an argument to the callback function # # fs/dcache.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +3 -3 # rcu: avoid passing an argument to the callback function # # arch/ppc64/mm/tlb.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +4 -3 # rcu: avoid passing an argument to the callback function # # ChangeSet # 2004/06/24 08:50:06-07:00 akpm@osdl.org # [PATCH] reduce rcu_head size - core # # From: Dipankar Sarma # # This reduces the RCU head size by using a singly linked to maintain them. # The ordering of the callbacks is still maintained as before by using a tail # pointer for the next list. # # Signed-Off-By : Dipankar Sarma # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/rcupdate.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +21 -21 # reduce rcu_head size - core # # include/linux/rcupdate.h # 2004/06/24 01:55:48-07:00 akpm@osdl.org +13 -11 # reduce rcu_head size - core # # ChangeSet # 2004/06/24 08:49:55-07:00 akpm@osdl.org # [PATCH] rcu lock update: Code move & cleanup # # From: Manfred Spraul # # Step three for reducing cacheline trashing within rcupdate.c: # # Cleanup and code move from to kernel/rcupdate.c: Remove # internal details from the header file. # # Signed-off-by: Manfred Spraul # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/rcupdate.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +45 -36 # rcu lock update: Code move & cleanup # # include/linux/rcupdate.h # 2004/06/24 01:55:48-07:00 akpm@osdl.org +8 -19 # rcu lock update: Code move & cleanup # # ChangeSet # 2004/06/24 08:49:44-07:00 akpm@osdl.org # [PATCH] rcu lock update: Use a sequence lock for starting batches # # From: Manfred Spraul # # Step two for reducing cacheline trashing within rcupdate.c: # # rcu_process_callbacks always acquires rcu_ctrlblk.state.mutex and calls # rcu_start_batch, even if the batch is already running or already scheduled to # run. # # This can be avoided with a sequence lock: A sequence lock allows to read the # current batch number and next_pending atomically. If next_pending is already # set, then there is no need to acquire the global mutex. # # This means that for each grace period, there will be # # - one write access to the rcu_ctrlblk.batch cacheline # # - lots of read accesses to rcu_ctrlblk.batch (3-10*cpus_online()). Behavior # similar to the jiffies cacheline, shouldn't be a problem. # # - cpus_online()+1 write accesses to rcu_ctrlblk.state, all of them starting # with spin_lock(&rcu_ctrlblk.state.mutex). # # For large enough cpus_online() this will be a problem, but all except two # of the spin_lock calls only protect the rcu_cpu_mask bitmap, thus a # hierarchical bitmap would allow to split the write accesses to multiple # cachelines. # # Tested on an 8-way with reaim. Unfortunately it probably won't help with Jack # Steiner's 'ls' test since in this test only one cpu generates rcu entries. # # Signed-off-by: Manfred Spraul # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/rcupdate.c # 2004/06/24 01:55:48-07:00 akpm@osdl.org +21 -8 # rcu lock update: Use a sequence lock for starting batches # # include/linux/rcupdate.h # 2004/06/24 01:55:48-07:00 akpm@osdl.org +5 -1 # rcu lock update: Use a sequence lock for starting batches # # ChangeSet # 2004/06/24 08:49:33-07:00 akpm@osdl.org # [PATCH] rcu lock update: Add per-cpu batch counter # # From: Manfred Spraul # # Below is the one of my patches from my rcu lock update. Jack Steiner tested # the first one on a 512p and it resolved the rcu cache line trashing. All were # tested on osdl with STP. # # Step one for reducing cacheline trashing within rcupdate.c: # # The current code uses the rcu_cpu_mask bitmap both for keeping track of the # cpus that haven't gone through a quiescent state and for checking if a cpu # should look for quiescent states. The bitmap is frequently changed and the # check is done by polling - together this causes cache line trashing. # # If it's cheaper to access a (mostly) read-only cacheline than a cacheline that # is frequently dirtied, then it's possible to reduce the trashing by splitting # the rcu_cpu_mask bitmap into two cachelines: # # The patch adds a generation counter and moves it into a separate cacheline. # This allows to removes all accesses to rcu_cpumask (in the read-write # cacheline) from rcu_pending and at least 50% of the accesses from # rcu_check_quiescent_state. rcu_pending and all but one call per cpu to # rcu_check_quiescent_state access the read-only cacheline. Probably not enough # for 512p, but it's a start, just for 128 byte more memory use, without slowing # down rcu grace periods. Obviously the read-only cacheline is not really # read-only: it's written once per grace period to indicate that a new grace # period is running. # # Tests on an 8-way Pentium III with reaim showed some improvement: # # oprofile hits: # Reference: http://khack.osdl.org/stp/293075/ # Hits % # 23741 0.0994 rcu_pending # 19057 0.0798 rcu_check_quiescent_state # 6530 0.0273 rcu_check_callbacks # # Patched: http://khack.osdl.org/stp/293076/ # 8291 0.0579 rcu_pending # 5475 0.0382 rcu_check_quiescent_state # 3604 0.0252 rcu_check_callbacks # # The total runtime differs between both runs, thus the % number must # be compared: Around 50% faster. I've uninlined rcu_pending for the # test. # # Tested with reaim and kernbench. # # Description: # # - per-cpu quiescbatch and qs_pending fields introduced: quiescbatch contains # the number of the last quiescent period that the cpu has seen and qs_pending # is set if the cpu has not yet reported the quiescent state for the current # period. With these two fields a cpu can test if it should report a # quiescent state without having to look at the frequently written # rcu_cpu_mask bitmap. # # - curbatch split into two fields: rcu_ctrlblk.batch.completed and # rcu_ctrlblk.batch.cur. This makes it possible to figure out if a grace # period is running (completed != cur) without accessing the rcu_cpu_mask # bitmap. # # - rcu_ctrlblk.maxbatch removed and replaced with a true/false next_pending # flag: next_pending=1 means that another grace period should be started # immediately after the end of the current period. Previously, this was # achieved by maxbatch: curbatch==maxbatch means don't start, curbatch!= # maxbatch means start. A flag improves the readability: The only possible # values for maxbatch were curbatch and curbatch+1. # # - rcu_ctrlblk split into two cachelines for better performance. # # - common code from rcu_offline_cpu and rcu_check_quiescent_state merged into # cpu_quiet. # # - rcu_offline_cpu: replace spin_lock_irq with spin_lock_bh, there are no # accesses from irq context (and there are accesses to the spinlock with # enabled interrupts from tasklet context). # # - rcu_restart_cpu introduced, s390 should call it after changing nohz: # Theoretically the global batch counter could wrap around and end up at # RCU_quiescbatch(cpu). Then the cpu would not look for a quiescent state and # rcu would lock up. # # Signed-off-by: Manfred Spraul # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/rcupdate.c # 2004/06/24 01:55:47-07:00 akpm@osdl.org +88 -54 # rcu lock update: Add per-cpu batch counter # # include/linux/rcupdate.h # 2004/06/24 01:55:47-07:00 akpm@osdl.org +34 -14 # rcu lock update: Add per-cpu batch counter # # ChangeSet # 2004/06/24 08:49:21-07:00 akpm@osdl.org # [PATCH] Move saved_command_line to init/main.c # # From: Rusty Russell # # Currently every arch declares its own char saved_command_line[]. Make sure # every arch defines COMMAND_LINE_SIZE in asm/setup.h, and declare # saved_command_line in linux/init.h (init/main.c contains the definition). # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # init/main.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +57 -3 # Move saved_command_line to init/main.c # # include/linux/init.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +17 -5 # Move saved_command_line to init/main.c # # include/asm-x86_64/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -5 # Move saved_command_line to init/main.c # # include/asm-x86_64/bootsetup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # include/asm-v850/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +6 -0 # Move saved_command_line to init/main.c # # include/asm-um/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +6 -0 # Move saved_command_line to init/main.c # # include/asm-sparc64/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -0 # Move saved_command_line to init/main.c # # include/asm-sparc/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -0 # Move saved_command_line to init/main.c # # include/asm-sh/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +8 -0 # Move saved_command_line to init/main.c # # include/asm-ppc64/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -1 # Move saved_command_line to init/main.c # # include/asm-ppc64/machdep.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -2 # Move saved_command_line to init/main.c # # include/asm-ppc/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +3 -0 # Move saved_command_line to init/main.c # # include/asm-ppc/machdep.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # include/asm-parisc/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +4 -8 # Move saved_command_line to init/main.c # # include/asm-mips/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +8 -0 # Move saved_command_line to init/main.c # # include/asm-mips/bootinfo.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +2 -1 # Move saved_command_line to init/main.c # # include/asm-m68knommu/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +4 -0 # Move saved_command_line to init/main.c # # include/asm-m68k/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -0 # Move saved_command_line to init/main.c # # include/asm-ia64/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +6 -0 # Move saved_command_line to init/main.c # # include/asm-i386/param.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -0 # Move saved_command_line to init/main.c # # include/asm-h8300/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +6 -1 # Move saved_command_line to init/main.c # # include/asm-cris/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +3 -0 # Move saved_command_line to init/main.c # # include/asm-alpha/system.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # include/asm-alpha/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +6 -0 # Move saved_command_line to init/main.c # # fs/proc/proc_misc.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # fs/proc/kcore.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -2 # Move saved_command_line to init/main.c # # drivers/sbus/char/openprom.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/x86_64/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/v850/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +2 -2 # Move saved_command_line to init/main.c # # arch/um/kernel/user_util.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/sparc64/kernel/sparc64_ksyms.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -1 # Move saved_command_line to init/main.c # # arch/sparc64/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -2 # Move saved_command_line to init/main.c # # arch/sparc/kernel/sparc_ksyms.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -1 # Move saved_command_line to init/main.c # # arch/sparc/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -2 # Move saved_command_line to init/main.c # # arch/sh/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -2 # Move saved_command_line to init/main.c # # arch/s390/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/ppc/platforms/prep_setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/ppc/platforms/pplus.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -2 # Move saved_command_line to init/main.c # # arch/ppc/platforms/pmac_setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -2 # Move saved_command_line to init/main.c # # arch/ppc/platforms/lopec_setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # include/asm-v850/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-v850/setup.h # # include/asm-um/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-um/setup.h # # include/asm-sh/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-sh/setup.h # # include/asm-mips/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-mips/setup.h # # include/asm-ia64/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-ia64/setup.h # # include/asm-alpha/setup.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-alpha/setup.h # # arch/ppc64/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/ppc64/kernel/head.S # 2004/06/24 01:55:46-07:00 akpm@osdl.org +2 -1 # Move saved_command_line to init/main.c # # arch/ppc/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/parisc/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -2 # Move saved_command_line to init/main.c # # arch/mips/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/m68knommu/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +2 -2 # Move saved_command_line to init/main.c # # arch/m68k/q40/config.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/m68k/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/ia64/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -4 # Move saved_command_line to init/main.c # # arch/i386/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/i386/boot/compressed/misc.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +16 -15 # Move saved_command_line to init/main.c # # arch/h8300/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +2 -2 # Move saved_command_line to init/main.c # # arch/cris/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -3 # Move saved_command_line to init/main.c # # arch/arm26/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/arm/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # arch/alpha/kernel/setup.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +0 -1 # Move saved_command_line to init/main.c # # ChangeSet # 2004/06/24 08:49:07-07:00 akpm@osdl.org # [PATCH] jbd needs to wait for locked buffers # # From: Chris Mason # # jbd needs to wait for any io to complete on the buffer before changing the # end_io function. Using set_buffer_locked means that it can change the # end_io function while the page is in the middle of writeback, and the # writeback bit on the page will never get cleared. # # Since we set the buffer dirty earlier on, if the page was previously dirty, # pdflush or memory pressure might trigger a writepage call, which will race # with jbd's set_buffer_locked. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/jbd/commit.c # 2004/06/24 01:55:46-07:00 akpm@osdl.org +1 -1 # jbd needs to wait for locked buffers # # ChangeSet # 2004/06/24 08:48:56-07:00 akpm@osdl.org # [PATCH] Allow i386 to reenable interrupts on lock contention # # From: Zwane Mwaikambo # # Following up on Keith's code, I adapted the i386 code to allow enabling # interrupts during contested locks depending on previous interrupt # enable status. Obviously there will be a text increase (only for non # CONFIG_SPINLINE case), although it doesn't seem so bad, there will be an # increased exit latency when we attempt a lock acquisition after spinning # due to the extra instructions. How much this will affect performance I'm # not sure yet as I haven't had time to micro bench. # # text data bss dec hex filename # 2628024 921731 0 3549755 362a3b vmlinux-after # 2621369 921731 0 3543100 36103c vmlinux-before # 2618313 919222 0 3537535 35fa7f vmlinux-spinline # # The code has been stress tested on a 16x NUMAQ (courtesy OSDL). # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/spinlock.h # 2004/06/24 01:55:46-07:00 akpm@osdl.org +31 -1 # Allow i386 to reenable interrupts on lock contention # # ChangeSet # 2004/06/24 02:01:15-03:00 acme@conectiva.com.br # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv6/tcp_ipv6.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +29 -22 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv4/tcp_timer.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +1 -1 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv4/tcp_minisocks.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +1 -1 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv4/tcp_ipv4.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +10 -6 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv4/tcp_input.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +8 -8 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv4/tcp.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +36 -10 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv4/sysctl_net_ipv4.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +6 -6 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/ipv4/proc.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +2 -2 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # net/core/stream.c # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +13 -13 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # include/net/tcp.h # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +7 -0 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # include/net/sock.h # 2004/06/24 02:01:03-03:00 acme@conectiva.com.br +6 -6 # [NET] make the struct proto entries related to memory pressure be pointers # # This is needed because tcpv6_prot has to point to the same place tcp_prot points, # as they share the same accounting variables. # # This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, # thanks David! # # Signed-off-by: Arnaldo Carvalho de Melo # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/23 19:44:57-07:00 davem@nuts.davemloft.net # [ATM]: In proc_mpc_read, make length ssize_t. # # net/atm/mpoa_proc.c # 2004/06/23 19:44:39-07:00 davem@nuts.davemloft.net +1 -1 # [ATM]: In proc_mpc_read, make length ssize_t. # # ChangeSet # 2004/06/23 19:42:54-07:00 davem@nuts.davemloft.net # [NETFILTER]: Use correct size_t printk format string in ipt_addrtype.c # # net/ipv4/netfilter/ipt_addrtype.c # 2004/06/23 19:42:36-07:00 davem@nuts.davemloft.net +1 -1 # [NETFILTER]: Use correct size_t printk format string in ipt_addrtype.c # # ChangeSet # 2004/06/23 18:19:39-07:00 davem@nuts.davemloft.net # Merge nuts.davemloft.net:/disk1/BK/acme-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/ipv6/tcp_ipv6.c # 2004/06/23 18:19:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/sit.c # 2004/06/23 18:19:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/ip6_output.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ipmr.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ipcomp.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ip_input.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ip_gre.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/esp4.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ah4.c # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/skbuff.h # 2004/06/23 18:19:28-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/23 18:17:00-07:00 davem@nuts.davemloft.net # Merge nuts.davemloft.net:/disk1/BK/netnew-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/ipv6/sit.c # 2004/06/23 18:16:51-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ipmr.c # 2004/06/23 18:16:51-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ip_input.c # 2004/06/23 18:16:50-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ip_gre.c # 2004/06/23 18:16:50-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/skbuff.h # 2004/06/23 18:16:50-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/23 16:59:52-07:00 ossi@kde.org # [PATCH] PCI: (one more) PCI quirk for SMBus bridge on Asus P4 boards # # my board has one of those "clever" bioses that hide the smbus. this tiny # patch adds it to the Bad Guy List (TM). # # # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/quirks.c # 2004/05/23 20:25:49-07:00 ossi@kde.org +1 -0 # PCI: (one more) PCI quirk for SMBus bridge on Asus P4 boards # # ChangeSet # 2004/06/24 00:40:38+01:00 rmk@flint.arm.linux.org.uk # [ARM] Fix acornfb build error. # # drivers/video/acornfb.c # 2004/06/24 00:37:55+01:00 rmk@flint.arm.linux.org.uk +3 -1 # Fix acornfb build error. # # ChangeSet # 2004/06/24 00:23:46+01:00 rmk@flint.arm.linux.org.uk # [ARM] Fix Footbridge timer functions. # # arch/arm/mach-footbridge/time.c # 2004/06/24 00:21:20+01:00 rmk@flint.arm.linux.org.uk +3 -3 # Fix couple of typo's. # The ISA IRQ number is IRQ_ISA_TIMER. # # ChangeSet # 2004/06/24 00:15:06+01:00 rmk@flint.arm.linux.org.uk # [ARM] Fix EBSA110 timer functions. # # Unfortunately this broke in Deepak's merge. Fix it. # # arch/arm/mach-ebsa110/core.c # 2004/06/24 00:12:38+01:00 rmk@flint.arm.linux.org.uk +2 -1 # Needs linux/interrupt.h # ebsa110_time_init should be ebsa110_init_time, and can be static. # # BitKeeper/deleted/.del-time.c~80f13e5e859789c2 # 2004/06/24 00:06:48+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/mach-ebsa110/time.c # # ChangeSet # 2004/06/23 23:26:14+01:00 tony@com.rmk.(none) # [ARM PATCH] 1943/1: OMAP compile fix # # Patch from Tony Lindgren # # This patch fixes OMAP compile after the ARM timer changes # in cset 1.1821.5.3 and dma-mapping device address translation # in cset 1.1821.5.3. # # arch/arm/mach-omap/time.c # 2004/06/23 15:56:02+01:00 tony@com.rmk.(none) +5 -0 # [PATCH] 1943/1: OMAP compile fix # # arch/arm/mach-omap/bus.c # 2004/06/23 15:55:21+01:00 tony@com.rmk.(none) +0 -39 # [PATCH] 1943/1: OMAP compile fix # # ChangeSet # 2004/06/23 18:03:17-03:00 acme@conectiva.com.br # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/tcp_ipv6.c # 2004/06/23 18:03:04-03:00 acme@conectiva.com.br +2 -1 # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_output.c # 2004/06/23 18:03:03-03:00 acme@conectiva.com.br +1 -1 # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_ipv4.c # 2004/06/23 18:03:03-03:00 acme@conectiva.com.br +2 -1 # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_input.c # 2004/06/23 18:03:03-03:00 acme@conectiva.com.br +6 -10 # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/23 18:03:03-03:00 acme@conectiva.com.br +6 -6 # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/23 18:03:03-03:00 acme@conectiva.com.br +0 -46 # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/23 18:03:03-03:00 acme@conectiva.com.br +56 -0 # [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} # # Only new requirement was to add a max_header field to struct sock sk_prot # member. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/23 19:13:37+01:00 rmk@flint.arm.linux.org.uk # [ARM] Fix platform device registration. # # Since the platform device registration is now merged into the driver # model, remove it from the ARM specific code. # # arch/arm/mach-versatile/core.c # 2004/06/23 19:11:04+01:00 rmk@flint.arm.linux.org.uk +2 -2 # Use platform_device_register not platform_add_device # # arch/arm/mach-integrator/integrator_ap.c # 2004/06/23 19:11:04+01:00 rmk@flint.arm.linux.org.uk +1 -1 # Use platform_device_register not platform_add_device # # arch/arm/common/Makefile # 2004/06/23 19:11:04+01:00 rmk@flint.arm.linux.org.uk +0 -1 # Remove platform.o # # ChangeSet # 2004/06/23 10:55:18-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] bug in V-link handling (arch/i386/pci/irq.c) # # Via southbridges use register 0x3c of the on-board devices (USB and # AC97) to control interrupt routing for those. In drivers/pci/quirks.c we # set it correctly (dev->irq & 15). However, in pirq_enable_irq() where the # second half of that stuff lives, we forget to apply the mask. # # That's what causes problems with ioapic on via motherboards in 2.6. # One-liner below ACKed by Alan, verified on via-based boxen here, obviously # doesn't affect non-via ones (we only set interrupt_line_quirk for via # chipsets). # # arch/i386/pci/irq.c # 2004/06/22 12:40:53-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # bug in V-link handling (arch/i386/pci/irq.c) # # BitKeeper/deleted/.del-platform.c~ecafa76df502a094 # 2004/06/23 18:21:25+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/common/platform.c # # ChangeSet # 2004/06/23 18:09:17+01:00 rmk@flint.arm.linux.org.uk # [ARM] Fix Integrator/CP timer support. # # arch/arm/mach-integrator/time.c # 2004/06/23 18:04:47+01:00 rmk@flint.arm.linux.org.uk +0 -144 # Remove timer setup/interrupt support. # # arch/arm/mach-integrator/integrator_cp.c # 2004/06/23 18:04:47+01:00 rmk@flint.arm.linux.org.uk +2 -0 # Integrator/CP needs TIMER_CTRL_IE # # arch/arm/mach-integrator/core.c # 2004/06/23 18:04:47+01:00 rmk@flint.arm.linux.org.uk +139 -0 # Move timer support from time.c # # ChangeSet # 2004/06/23 09:43:03-07:00 davem@nuts.davemloft.net # Merge bk://kernel.bkbits.net/acme/net-2.6 # into nuts.davemloft.net:/disk1/BK/acme-2.6 # # net/ipv6/tcp_ipv6.c # 2004/06/23 09:42:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/sit.c # 2004/06/23 09:42:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/ip6_output.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp_input.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ipmr.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ipcomp.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ip_input.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ip_gre.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/esp4.c # 2004/06/23 09:42:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ah4.c # 2004/06/23 09:42:52-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/skbuff.h # 2004/06/23 09:42:52-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/23 08:05:47-07:00 davem@nuts.davemloft.net # Merge # # net/sched/Kconfig # 2004/06/23 08:04:20-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/core/skbuff.c # 2004/06/23 08:04:20-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/net/pkt_sched.h # 2004/06/23 08:04:19-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/skbuff.h # 2004/06/23 08:04:19-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/pkt_sched.h # 2004/06/23 08:04:19-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/netdevice.h # 2004/06/23 08:04:19-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/23 07:44:19-07:00 yoshfuji@linux-ipv6.org # [NETFILTER]: Fix iptable_raw.c build with older gcc. # # net/ipv4/netfilter/iptable_raw.c # 2004/06/23 07:44:05-07:00 yoshfuji@linux-ipv6.org +11 -5 # [NETFILTER]: Fix iptable_raw.c build with older gcc. # # ChangeSet # 2004/06/23 08:09:38+01:00 dwmw2@shinybook.infradead.org # WindRiver PowerQUICC III platform support cleanup. # # Respond to maintainer feedback -- remove unneeded setup for # the FEC port which doesn't exist; small cosmetic changes. # # Signed-off-by: Kumar Gala # # arch/ppc/platforms/85xx/sbc85xx.h # 2004/06/23 08:09:19+01:00 dwmw2@shinybook.infradead.org +0 -2 # Remove unneeded forward declaration of struct pci_dev; # # arch/ppc/platforms/85xx/sbc8560.c # 2004/06/23 08:09:19+01:00 dwmw2@shinybook.infradead.org +1 -21 # Slight cleanup; remove settings for the FEC which doesn't exist. # # ChangeSet # 2004/06/22 19:53:47-07:00 jbarnes@engr.sgi.com # [PATCH] ppc32: Support for new Apple laptop models # # This adds sound support for some of the newer PowerBooks. It appears # that this chip supports the AWACS sample rates, but has a snapper-style # mixer. Tested and works on my PowerBook5,4. # # Signed-off-by: Jesse Barnes # Signed-off-by: Linus Torvalds # # ChangeSet # 2004/06/22 19:52:14-07:00 paulus@samba.org # [PATCH] Handle altivec assist exception properly # # This is the PPC64 counterpart of the PPC32 Altivec assist exception # handler that went in recently. # # On PPC64 machines with Altivec (i.e. machines that use the PPC970 chip, # such as the G5 powermac), the altivec floating-point instructions can # operate in two modes: one where denormalized inputs or outputs are # truncated to zero, and one where they aren't. In the latter mode the # processor can take an exception when it encounters denormalized # floating-point inputs or outputs rather than dealing with them in # hardware. # # This patch adds code to deal properly with the exception, by emulating # the instruction that caused the exception. Previously the kernel just # switched the altivec unit into the truncate-to-zero mode, which works # but is a bit gross. Fortunately there are only a limited set of altivec # instructions which can generate the assist exception, so we don't have # to emulate the whole altivec instruction set. # # Note that Altivec is Motorola's name for the PowerPC vector/SIMD # instructions; IBM calls the same thing VMX, and currently only IBM makes # 64-bit PowerPC CPU chips. Nevertheless, I have used the term Altivec in # the PPC64 code for consistency with the PPC32 code. # # Signed-off-by: Paul Mackerras # Signed-off-by: Linus Torvalds # # ChangeSet # 2004/06/22 19:52:02-07:00 benh@kernel.crashing.org # [PATCH] radeonfb: Fix panel detection on some laptops # # The code in radeonfb looking for the BIOS image currently uses the BIOS # ROM if any, and falls back to the RAM image if not found. This is # unfortunatly not correct for a bunch of laptops where the real panel # data are only present in the RAM image. # # This works around this problem by preferring the RAM image on mobility # chipsets. This is definitely not the best workaround, we need some arch # support for linking the RAM image to the PCI ID (preferrably by having # the arch snapshot it during boot, isolating us completely from the # details of where this image is in memory). I'll see how we can get such # an improvement later. # # Signed-off-by: Benjamin Herrenschmidt # Signed-off-by: Linus Torvalds # # ChangeSet # 2004/06/22 19:51:52-07:00 benh@kernel.crashing.org # [PATCH] ppc32: Support for new Apple laptop models # # This adds support for newer Apple laptop models. It adds the basic # identification for the new motherboards and the cpufreq support for # models using the new 7447A CPU from Motorola. # # This is mostly the work of John Steele Scott with # some bits from Sebastian Henschel and some rework by # myself. Please apply, # # Signed-off-by: John Steele Scott # Signed-off-by: Sebastian Henschel # Signed-off-by: Benjamin Herrenschmidt # Signed-off-by: Linus Torvalds # # ChangeSet # 2004/06/22 19:51:41-07:00 benh@kernel.crashing.org # [PATCH] ppc32: oprofile support # # This adds basic oprofile support to ppc32. Originally from Anton # Blanchard, I just re-diffed it against current kernels. # # Signed-off-by: Anton Blanchard # Signed-off-by: Benjamin Herrenschmidt # Signed-off-by: Linus Torvalds # # ChangeSet # 2004/06/22 19:51:29-07:00 benh@kernel.crashing.org # [PATCH] ppc32: Cleanups & warning fixes of traps.c # # This cleans up arch/ppc/kernel/traps.c and vecemu.c to use the same # formatting style for all functions, and fixes 2 warnings in the altivec # floating point emulation code. No functional change. # # Signed-off-by: Benjamin Herrenschmidt # Signed-off-by: Linus Torvalds # # ChangeSet # 2004/06/23 01:20:40-03:00 acme@conectiva.com.br # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/tcp_ipv6.c # 2004/06/23 01:20:29-03:00 acme@conectiva.com.br +4 -4 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_timer.c # 2004/06/23 01:20:29-03:00 acme@conectiva.com.br +6 -6 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_output.c # 2004/06/23 01:20:29-03:00 acme@conectiva.com.br +1 -1 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_minisocks.c # 2004/06/23 01:20:29-03:00 acme@conectiva.com.br +1 -1 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_ipv4.c # 2004/06/23 01:20:29-03:00 acme@conectiva.com.br +24 -21 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_input.c # 2004/06/23 01:20:29-03:00 acme@conectiva.com.br +17 -17 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/23 01:20:29-03:00 acme@conectiva.com.br +15 -116 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/sysctl_net_ipv4.c # 2004/06/23 01:20:28-03:00 acme@conectiva.com.br +6 -6 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/proc.c # 2004/06/23 01:20:28-03:00 acme@conectiva.com.br +2 -2 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/23 01:20:28-03:00 acme@conectiva.com.br +97 -0 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/23 01:20:28-03:00 acme@conectiva.com.br +4 -28 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/23 01:20:28-03:00 acme@conectiva.com.br +33 -1 # [NET] Generalise tcp memory pressure handling # # Signed-off-by: Arnaldo Carvalho de Melo # # sound/ppc/pmac.c # 2004/06/22 14:40:39-07:00 jbarnes@engr.sgi.com +7 -0 # ppc32: Support for new Apple laptop models # # arch/ppc64/kernel/vector.S # 2004/06/22 19:52:07-07:00 paulus@samba.org +172 -0 # Handle altivec assist exception properly # # include/asm-ppc64/system.h # 2004/06/22 19:52:07-07:00 paulus@samba.org +1 -0 # Handle altivec assist exception properly # # arch/ppc64/kernel/vector.S # 2004/06/22 19:52:07-07:00 paulus@samba.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc64/kernel/vector.S # # arch/ppc64/kernel/vecemu.c # 2004/06/22 19:52:07-07:00 paulus@samba.org +346 -0 # Handle altivec assist exception properly # # arch/ppc64/kernel/traps.c # 2004/06/22 16:05:33-07:00 paulus@samba.org +32 -2 # Handle altivec assist exception properly # # arch/ppc64/kernel/Makefile # 2004/06/22 19:52:07-07:00 paulus@samba.org +2 -0 # Handle altivec assist exception properly # # arch/ppc64/kernel/vecemu.c # 2004/06/22 19:52:07-07:00 paulus@samba.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc64/kernel/vecemu.c # # drivers/video/aty/radeon_base.c # 2004/06/22 13:11:16-07:00 benh@kernel.crashing.org +16 -2 # radeonfb: Fix panel detection on some laptops # # include/asm-ppc/uninorth.h # 2004/06/22 13:04:07-07:00 benh@kernel.crashing.org +6 -0 # ppc32: Support for new Apple laptop models # # include/asm-ppc/reg.h # 2004/06/22 13:04:07-07:00 benh@kernel.crashing.org +1 -0 # ppc32: Support for new Apple laptop models # # include/asm-ppc/pmac_feature.h # 2004/06/22 13:04:07-07:00 benh@kernel.crashing.org +6 -0 # ppc32: Support for new Apple laptop models # # arch/ppc/platforms/pmac_feature.c # 2004/06/22 13:04:07-07:00 benh@kernel.crashing.org +32 -0 # ppc32: Support for new Apple laptop models # # arch/ppc/platforms/pmac_cpufreq.c # 2004/06/22 13:04:07-07:00 benh@kernel.crashing.org +193 -118 # ppc32: Support for new Apple laptop models # # arch/ppc/kernel/misc.S # 2004/06/22 13:04:07-07:00 benh@kernel.crashing.org +18 -0 # ppc32: Support for new Apple laptop models # # arch/ppc/oprofile/init.c # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +23 -0 # ppc32: oprofile support # # arch/ppc/oprofile/Makefile # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +9 -0 # ppc32: oprofile support # # arch/ppc/oprofile/Kconfig # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +23 -0 # ppc32: oprofile support # # arch/ppc/oprofile/init.c # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/oprofile/init.c # # arch/ppc/oprofile/Makefile # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/oprofile/Makefile # # arch/ppc/oprofile/Kconfig # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/oprofile/Kconfig # # arch/ppc/kernel/time.c # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +15 -7 # ppc32: oprofile support # # arch/ppc/Makefile # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +2 -0 # ppc32: oprofile support # # arch/ppc/Kconfig # 2004/06/22 12:05:08-07:00 benh@kernel.crashing.org +1 -0 # ppc32: oprofile support # # include/asm-ppc/processor.h # 2004/06/22 12:04:49-07:00 benh@kernel.crashing.org +2 -0 # ppc32: Cleanups & warning fixes of traps.c # # arch/ppc/kernel/vecemu.c # 2004/06/22 12:04:49-07:00 benh@kernel.crashing.org +1 -2 # ppc32: Cleanups & warning fixes of traps.c # # arch/ppc/kernel/traps.c # 2004/06/22 12:04:49-07:00 benh@kernel.crashing.org +18 -35 # ppc32: Cleanups & warning fixes of traps.c # # ChangeSet # 2004/06/22 20:42:16-04:00 jgarzik@pobox.com # [libata sata_sil] Re-fix mod15write bug # # Certain early SATA drives have problems with write requests whose # length satisfy the equation "sectors % 15 == 1", on the SiI 3112. # Other drives, and other SiI controllers, are not affected. # # The fix for this problem is to avoid such requests, in one of three # ways, for the affect drive+controller combos: # 1) Limit all writes to 15 sectors # 2) Use block layer features to avoid creating requests whose # length satisfies the above equation. # 3) When a request satisfies the above equation, split the request # into two writes, neither of which satisfies the equation. # # I chose fix #1, the most simple to implement. After discussion with # Silicon Image and others regarding the impact of this fix, I have # decided to remain with fix #1, and will not be implementing a # "better fix". This means that the affected SATA drives will see # decreased performance, but set of affected drives is small and will # never grow larger. # # Further, the complexity of implementing solution #2 or # solution #3 is rather large. # # When implementing lba48 'large request' support, I unintentionally # broke the fix for these affected drives. Kudos to Ricky Beam for # noticing this. # # This change restores the fix, by adding a flag ATA_DFLAG_LOCK_SECTORS # to indicate that the max_sectors value set by the low-level driver # should never be changed. # # include/linux/libata.h # 2004/06/22 20:42:10-04:00 jgarzik@pobox.com +1 -0 # [libata sata_sil] Re-fix mod15write bug # # Certain early SATA drives have problems with write requests whose # length satisfy the equation "sectors % 15 == 1", on the SiI 3112. # Other drives, and other SiI controllers, are not affected. # # The fix for this problem is to avoid such requests, in one of three # ways, for the affect drive+controller combos: # 1) Limit all writes to 15 sectors # 2) Use block layer features to avoid creating requests whose # length satisfies the above equation. # 3) When a request satisfies the above equation, split the request # into two writes, neither of which satisfies the equation. # # I chose fix #1, the most simple to implement. After discussion with # Silicon Image and others regarding the impact of this fix, I have # decided to remain with fix #1, and will not be implementing a # "better fix". This means that the affected SATA drives will see # decreased performance, but set of affected drives is small and will # never grow larger. # # Further, the complexity of implementing solution #2 or # solution #3 is rather large. # # When implementing lba48 'large request' support, I unintentionally # broke the fix for these affected drives. Kudos to Ricky Beam for # noticing this. # # This change restores the fix, by adding a flag ATA_DFLAG_LOCK_SECTORS # to indicate that the max_sectors value set by the low-level driver # should never be changed. # # drivers/scsi/sata_sil.c # 2004/06/22 20:42:10-04:00 jgarzik@pobox.com +1 -0 # [libata sata_sil] Re-fix mod15write bug # # Certain early SATA drives have problems with write requests whose # length satisfy the equation "sectors % 15 == 1", on the SiI 3112. # Other drives, and other SiI controllers, are not affected. # # The fix for this problem is to avoid such requests, in one of three # ways, for the affect drive+controller combos: # 1) Limit all writes to 15 sectors # 2) Use block layer features to avoid creating requests whose # length satisfies the above equation. # 3) When a request satisfies the above equation, split the request # into two writes, neither of which satisfies the equation. # # I chose fix #1, the most simple to implement. After discussion with # Silicon Image and others regarding the impact of this fix, I have # decided to remain with fix #1, and will not be implementing a # "better fix". This means that the affected SATA drives will see # decreased performance, but set of affected drives is small and will # never grow larger. # # Further, the complexity of implementing solution #2 or # solution #3 is rather large. # # When implementing lba48 'large request' support, I unintentionally # broke the fix for these affected drives. Kudos to Ricky Beam for # noticing this. # # This change restores the fix, by adding a flag ATA_DFLAG_LOCK_SECTORS # to indicate that the max_sectors value set by the low-level driver # should never be changed. # # drivers/scsi/libata-scsi.c # 2004/06/22 20:42:10-04:00 jgarzik@pobox.com +2 -1 # [libata sata_sil] Re-fix mod15write bug # # Certain early SATA drives have problems with write requests whose # length satisfy the equation "sectors % 15 == 1", on the SiI 3112. # Other drives, and other SiI controllers, are not affected. # # The fix for this problem is to avoid such requests, in one of three # ways, for the affect drive+controller combos: # 1) Limit all writes to 15 sectors # 2) Use block layer features to avoid creating requests whose # length satisfies the above equation. # 3) When a request satisfies the above equation, split the request # into two writes, neither of which satisfies the equation. # # I chose fix #1, the most simple to implement. After discussion with # Silicon Image and others regarding the impact of this fix, I have # decided to remain with fix #1, and will not be implementing a # "better fix". This means that the affected SATA drives will see # decreased performance, but set of affected drives is small and will # never grow larger. # # Further, the complexity of implementing solution #2 or # solution #3 is rather large. # # When implementing lba48 'large request' support, I unintentionally # broke the fix for these affected drives. Kudos to Ricky Beam for # noticing this. # # This change restores the fix, by adding a flag ATA_DFLAG_LOCK_SECTORS # to indicate that the max_sectors value set by the low-level driver # should never be changed. # # ChangeSet # 2004/06/23 01:07:38+01:00 dvrabel@com.rmk.(none) # [ARM PATCH] 1940/1: asm-arm/checksum.h - missing include # # Patch from David Vrabel # # Missing include (cf. include/asm-i386/checksum.h) in include/asm-arm/checksum.h. # # ChangeSet # 2004/06/22 17:07:21-07:00 shemminger@osdl.org # [BRIDGE]: Turn off debug message in bridge ioctl. # # Trivial patch to turn off a debug message. It seems some SNMP daemons just # periodically trying to look at MII state. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/bridge/br_ioctl.c # 2004/06/22 17:07:07-07:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Turn off debug message in bridge ioctl. # # Trivial patch to turn off a debug message. It seems some SNMP daemons just # periodically trying to look at MII state. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/22 17:06:32-07:00 shemminger@osdl.org # [IPV4]: ip_rt_ioctl argument is user pointer. # # The function ip_rt_ioctl expects a pointer to a user route structure, so define # it that way and cast as appropriate. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/ipv4/ipconfig.c # 2004/06/22 17:06:18-07:00 shemminger@osdl.org +2 -2 # [IPV4]: ip_rt_ioctl argument is user pointer. # # The function ip_rt_ioctl expects a pointer to a user route structure, so define # it that way and cast as appropriate. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/ipv4/fib_frontend.c # 2004/06/22 17:06:18-07:00 shemminger@osdl.org +1 -1 # [IPV4]: ip_rt_ioctl argument is user pointer. # # The function ip_rt_ioctl expects a pointer to a user route structure, so define # it that way and cast as appropriate. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/ipv4/af_inet.c # 2004/06/22 17:06:18-07:00 shemminger@osdl.org +1 -1 # [IPV4]: ip_rt_ioctl argument is user pointer. # # The function ip_rt_ioctl expects a pointer to a user route structure, so define # it that way and cast as appropriate. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # include/net/route.h # 2004/06/22 17:06:18-07:00 shemminger@osdl.org +1 -1 # [IPV4]: ip_rt_ioctl argument is user pointer. # # The function ip_rt_ioctl expects a pointer to a user route structure, so define # it that way and cast as appropriate. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # include/asm-arm/checksum.h # 2004/06/21 15:17:39+01:00 dvrabel@com.rmk.(none) +2 -0 # [PATCH] 1940/1: asm-arm/checksum.h - missing include # # ChangeSet # 2004/06/22 17:04:54-07:00 shemminger@osdl.org # [NET]: rtentry->rt_dev is __user. # # The device entry in the route ioctl's needs annotation. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # include/linux/route.h # 2004/06/22 17:04:40-07:00 shemminger@osdl.org +2 -2 # [NET]: rtentry->rt_dev is __user. # # The device entry in the route ioctl's needs annotation. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/23 01:03:51+01:00 icampbell@com.rmk.(none) # [ARM PATCH] 1939/1: SA1100 watchdog driver also works on PXA2xx # # Patch from Ian Campbell # # The SA1100 watchdog driver also works fine on the PXA2xx. Tested on # a PXA255 based platform. # # drivers/char/watchdog/sa1100_wdt.c # 2004/06/23 01:00:00+01:00 icampbell@com.rmk.(none) +4 -4 # [PATCH] 1939/1: SA1100 watchdog driver also works on PXA2xx # # drivers/char/watchdog/Kconfig # 2004/06/23 01:00:00+01:00 icampbell@com.rmk.(none) +6 -5 # [PATCH] 1939/1: SA1100 watchdog driver also works on PXA2xx # # ChangeSet # 2004/06/23 00:59:35+01:00 jelenz@edu.rmk.(none) # [ARM PATCH] 1936/1: Update collie fb entries to use new style initializers # # Patch from John Lenz # # Switches the collie framebuffer mach_info structure to use # the new initializers. # # Signed-off-by: John Lenz # # ChangeSet # 2004/06/22 16:59:02-07:00 shemminger@osdl.org # [PATCH] PCI: add id's for sk98 driver # # Redoing the sk98 driver to correct pci model. These are (most of) the entries # it uses. # # # Signed-off-by: Greg Kroah-Hartman # # include/linux/pci_ids.h # 2004/06/22 10:08:12-07:00 shemminger@osdl.org +12 -0 # PCI: add id's for sk98 driver # # ChangeSet # 2004/06/22 16:58:27-07:00 shemminger@osdl.org # [PATCH] PCI: fix out of order entry in pci_ids.h # # The last entry in pci_ids.h is out of order, someone wasn't reading the comment # to keep it sorted. # # Signed-off-by: Stephen Hemminger # Signed-off-by: Greg Kroah-Hartman # # include/linux/pci_ids.h # 2004/06/22 10:08:01-07:00 shemminger@osdl.org +6 -6 # PCI: fix out of order entry in pci_ids.h # # ChangeSet # 2004/06/22 16:57:48-07:00 shemminger@osdl.org # [PATCH] PCI: remove duplicate in pci_ids.h # # Get rid of duplicate entry, one is in the middle of the file with duplicate # at the end # # Signed-off-by: Stephen Hemminger # Signed-off-by: Greg Kroah-Hartman # # include/linux/pci_ids.h # 2004/06/22 10:07:49-07:00 shemminger@osdl.org +0 -3 # PCI: remove duplicate in pci_ids.h # # drivers/video/sa1100fb.c # 2004/06/22 01:00:00+01:00 jelenz@edu.rmk.(none) +8 -8 # [PATCH] 1936/1: Update collie fb entries to use new style initializers # # ChangeSet # 2004/06/22 16:57:06-07:00 roland@topspin.com # [PATCH] PCI: Fix MSI-X setup # # msix_capability_init() puts the offset of the MSI-X capability into # pos, then uses pos as a loop index to clear the MSI-X vector table, # and then tries to use pos as the offset again, which results in # writing the MSI-X enable bit off into space. # # This patch fixes that by adding a new loop index variable and using # that to clear the vector table. # # Signed-off-by: Roland Dreier # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/msi.c # 2004/06/21 21:30:05-07:00 roland@topspin.com +5 -5 # PCI: Fix MSI-X setup # # ChangeSet # 2004/06/23 00:55:42+01:00 jelenz@edu.rmk.(none) # [ARM PATCH] 1935/1: Fix bug in sa1111 driver # # Patch from John Lenz # # The __sa1111_probe function is declared __init, and it is called from # the sa1111_probe function, which is not declared __init. # # Signed-off-by: John Lenz # # ChangeSet # 2004/06/22 16:55:39-07:00 davem@nuts.davemloft.net # Merge bk://kernel.bkbits.net/acme/net-2.6 # into nuts.davemloft.net:/disk1/BK/netnew-2.6 # # net/ipv6/tcp_ipv6.c # 2004/06/22 16:55:30-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/ip6_output.c # 2004/06/22 16:55:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp.c # 2004/06/22 16:55:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ipcomp.c # 2004/06/22 16:55:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/esp4.c # 2004/06/22 16:55:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/ah4.c # 2004/06/22 16:55:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/skbuff.h # 2004/06/22 16:55:29-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # arch/arm/common/sa1111.c # 2004/06/22 01:00:00+01:00 jelenz@edu.rmk.(none) +1 -1 # [PATCH] 1935/1: Fix bug in sa1111 driver # # ChangeSet # 2004/06/23 00:48:22+01:00 icampbell@com.rmk.(none) # [ARM PATCH] 1933/1: Convert PXA serial driver to device model and implement suspend and resume # # Patch from Ian Campbell # # Patch 1848/1 removed the hack for preserving FFUART over sleep. # # This patch adds back that support in the correct place by converting # the PXA serial driver to use the driver model and hooking up the # suspend and resume methods. # # drivers/serial/pxa.c # 2004/06/22 01:00:00+01:00 icampbell@com.rmk.(none) +62 -11 # [PATCH] 1933/1: Convert PXA serial driver to device model and implement suspend and resume # # arch/arm/mach-pxa/generic.c # 2004/06/22 01:00:00+01:00 icampbell@com.rmk.(none) +16 -0 # [PATCH] 1933/1: Convert PXA serial driver to device model and implement suspend and resume # # ChangeSet # 2004/06/23 00:44:18+01:00 elf@com.rmk.(none) # [ARM PATCH] 1913/1: lh7a40x #3 (1/2) serial # # Patch from Marc Singer # # Serial console and port driver for the LH7a40x CPUs. The only change # made since the last patch was to change the PORT_ID (again). This # patch superceeds two serial driver patches. # # # include/linux/serial_core.h # 2004/06/05 11:30:48+01:00 elf@com.rmk.(none) +3 -0 # [PATCH] 1913/1: lh7a40x #3 (1/2) serial # # drivers/serial/Makefile # 2004/06/05 11:30:48+01:00 elf@com.rmk.(none) +1 -0 # [PATCH] 1913/1: lh7a40x #3 (1/2) serial # # drivers/serial/Kconfig # 2004/06/05 11:30:48+01:00 elf@com.rmk.(none) +23 -0 # [PATCH] 1913/1: lh7a40x #3 (1/2) serial # # drivers/serial/serial_lh7a40x.c # 2004/06/05 11:30:48+01:00 elf@com.rmk.(none) +708 -0 # [PATCH] 1913/1: lh7a40x #3 (1/2) serial # # drivers/serial/serial_lh7a40x.c # 2004/06/05 11:30:48+01:00 elf@com.rmk.(none) +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-serial/drivers/serial/serial_lh7a40x.c # # ChangeSet # 2004/06/22 16:28:44-07:00 greg@kroah.com # merge fixups. # # arch/i386/pci/irq.c # 2004/06/22 16:28:32-07:00 greg@kroah.com +0 -0 # merge fixups. # # arch/i386/kernel/dmi_scan.c # 2004/06/22 16:28:32-07:00 greg@kroah.com +8 -0 # merge fixups. # # ChangeSet # 2004/06/22 20:04:46-03:00 acme@conectiva.com.br # [NET] remove fill_page_desc, its just a copy of skb_fill_page_desc # # Also remove an unused inet_opt variable from ipv6 code. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/tcp_ipv6.c # 2004/06/22 20:04:35-03:00 acme@conectiva.com.br +0 -1 # [NET] remove fill_page_desc, its just a copy of skb_fill_page_desc # # Also remove an unused inet_opt variable from ipv6 code. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/22 20:04:35-03:00 acme@conectiva.com.br +2 -12 # [NET] remove fill_page_desc, its just a copy of skb_fill_page_desc # # Also remove an unused inet_opt variable from ipv6 code. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/linux/skbuff.h # 2004/06/22 20:04:35-03:00 acme@conectiva.com.br +7 -5 # [NET] remove fill_page_desc, its just a copy of skb_fill_page_desc # # Also remove an unused inet_opt variable from ipv6 code. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/22 23:54:18+01:00 rmk@flint.arm.linux.org.uk # Merge bk://dsaxena.bkbits.net/linux-2.6-for-rmk # into flint.arm.linux.org.uk:/usr/src/bk/linux-2.6-rmk # # arch/arm/mach-integrator/integrator_cp.c # 2004/06/22 23:53:14+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Auto merged # # ChangeSet # 2004/06/22 15:41:55-07:00 trini@kernel.crashing.org # [PPC32] Update CPM2 (MPC82xx/MPC85xx) code to use rheap for DP memory # Originally from: Rune Torgersen # Signed-off-by: Tom Rini # # include/asm-ppc/cpm2.h # 2004/06/22 15:41:45-07:00 trini@kernel.crashing.org +8 -4 # Update cpm2_dpalloc() to use the rheap infrastructure, and # we now have cpm2_dpfree() and friends. # # drivers/serial/cpm_uart/cpm_uart_cpm2.c # 2004/06/22 15:41:45-07:00 trini@kernel.crashing.org +8 -7 # Update to use the new cpm2_dpalloc() and cpm2_dpfree(). # # arch/ppc/syslib/cpm2_common.c # 2004/06/22 15:41:45-07:00 trini@kernel.crashing.org +102 -73 # Update cpm2_dpalloc() to use the rheap infrastructure, and # we now have cpm2_dpfree() and friends. # # arch/ppc/lib/Makefile # 2004/06/22 15:41:45-07:00 trini@kernel.crashing.org +1 -0 # Add rheap.o on CPM2. # # arch/ppc/8260_io/fcc_enet.c # 2004/06/22 15:41:45-07:00 trini@kernel.crashing.org +5 -18 # cpm2_hostalloc() is dead. At the point this driver runs, we can # just call kmalloc(). # # arch/ppc/8260_io/enet.c # 2004/06/22 15:41:45-07:00 trini@kernel.crashing.org +8 -7 # Updates for the new cpm2_dpalloc()/cpm2_dpram_offset(). # # ChangeSet # 2004/06/22 19:32:50-03:00 acme@conectiva.com.br # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/sctp/protocol.c # 2004/06/22 19:32:39-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/sit.c # 2004/06/22 19:32:39-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/xfrm4_tunnel.c # 2004/06/22 19:32:39-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/protocol.c # 2004/06/22 19:32:39-03:00 acme@conectiva.com.br +3 -3 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/ipmr.c # 2004/06/22 19:32:39-03:00 acme@conectiva.com.br +2 -2 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/ipcomp.c # 2004/06/22 19:32:39-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/ip_input.c # 2004/06/22 19:32:39-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/ip_gre.c # 2004/06/22 19:32:38-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/icmp.c # 2004/06/22 19:32:38-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/esp4.c # 2004/06/22 19:32:38-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/ah4.c # 2004/06/22 19:32:38-03:00 acme@conectiva.com.br +1 -1 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/af_inet.c # 2004/06/22 19:32:38-03:00 acme@conectiva.com.br +4 -4 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/protocol.h # 2004/06/22 19:32:38-03:00 acme@conectiva.com.br +5 -6 # [NET] rename struct inet_protocol to net_protocol # # The poor cousins will also have registration routines, etc. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/22 14:51:52-07:00 trini@kernel.crashing.org # [PPC32] Change how we handle DP memory on MPC8xx. # We now have a 'remote heap' implemented (see comments in # arch/ppc/lib/rheap.c) which manages this memory. # From Pantelis Antoniou . # Signed-off-by: Tom Rini # # include/asm-ppc/rheap.h # 2004/06/22 14:51:41-07:00 trini@kernel.crashing.org +85 -0 # # include/asm-ppc/rheap.h # 2004/06/22 14:51:41-07:00 trini@kernel.crashing.org +0 -0 # BitKeeper file /home/trini/work/kernel/pristine/for-linus-ppc/include/asm-ppc/rheap.h # # arch/ppc/lib/rheap.c # 2004/06/22 14:51:40-07:00 trini@kernel.crashing.org +692 -0 # # include/asm-ppc/commproc.h # 2004/06/22 14:51:40-07:00 trini@kernel.crashing.org +6 -1 # Change how we use the DP memory so that it can be freed by drivers # as well and properly managed. # # drivers/serial/cpm_uart/cpm_uart_cpm1.c # 2004/06/22 14:51:40-07:00 trini@kernel.crashing.org +7 -7 # Make use of the new dpalloc/dpfree routines. # # drivers/i2c/busses/i2c-rpx.c # 2004/06/22 14:51:40-07:00 trini@kernel.crashing.org +2 -1 # Convert to the new m8xx_cpm_dpalloc/cpm_dpram_offset set of calls. # # arch/ppc/lib/rheap.c # 2004/06/22 14:51:40-07:00 trini@kernel.crashing.org +0 -0 # BitKeeper file /home/trini/work/kernel/pristine/for-linus-ppc/arch/ppc/lib/rheap.c # # arch/ppc/lib/Makefile # 2004/06/22 14:51:40-07:00 trini@kernel.crashing.org +1 -0 # Add rheap.o on 8xx. # # arch/ppc/8xx_io/uart.c # 2004/06/22 14:51:40-07:00 trini@kernel.crashing.org +18 -14 # Convert to the new m8xx_cpm_dpalloc/cpm_dpram_offset set of calls. # # arch/ppc/8xx_io/enet.c # 2004/06/22 14:51:39-07:00 trini@kernel.crashing.org +11 -7 # Convert to the new m8xx_cpm_dpalloc/cpm_dpram_offset set of calls. # # arch/ppc/8xx_io/cs4218_tdm.c # 2004/06/22 14:51:39-07:00 trini@kernel.crashing.org +7 -5 # Convert to the new m8xx_cpm_dpalloc/cpm_dpram_offset set of calls. # # arch/ppc/8xx_io/commproc.c # 2004/06/22 14:51:39-07:00 trini@kernel.crashing.org +106 -34 # Change how we use the DP memory so that it can be freed by drivers # as well and properly managed. # # ChangeSet # 2004/06/22 14:07:48-07:00 akepner@sgi.com # [NET]: In loopback, make get_stats() get correct per-cpu stats. # # Signed-off-by: Arthur Kepner # Signed-off-by: David S. Miller # # drivers/net/loopback.c # 2004/06/22 14:07:33-07:00 akepner@sgi.com +1 -2 # [NET]: In loopback, make get_stats() get correct per-cpu stats. # # Signed-off-by: Arthur Kepner # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/22 13:54:22-07:00 davem@nuts.davemloft.net # [IPSEC]: In ESP, do not put scatterlist array on stack. # # Put it in per-esp data instead. Noticed by Linus. # # Signed-off-by: David S. Miller # # net/ipv6/esp6.c # 2004/06/22 13:53:57-07:00 davem@nuts.davemloft.net +6 -10 # [IPSEC]: In ESP, do not put scatterlist array on stack. # # Put it in per-esp data instead. Noticed by Linus. # # Signed-off-by: David S. Miller # # net/ipv4/esp4.c # 2004/06/22 13:53:57-07:00 davem@nuts.davemloft.net +6 -10 # [IPSEC]: In ESP, do not put scatterlist array on stack. # # Put it in per-esp data instead. Noticed by Linus. # # Signed-off-by: David S. Miller # # include/net/esp.h # 2004/06/22 13:53:57-07:00 davem@nuts.davemloft.net +5 -0 # [IPSEC]: In ESP, do not put scatterlist array on stack. # # Put it in per-esp data instead. Noticed by Linus. # # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/22 17:51:20-03:00 acme@conectiva.com.br # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # net/ipv6/tcp_ipv6.c # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +0 -4 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # net/ipv6/ip6_output.c # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +8 -8 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # net/ipv4/tcp_ipv4.c # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +0 -4 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # net/ipv4/tcp.c # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +2 -2 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # net/ipv4/ip_output.c # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +8 -8 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # net/core/sock.c # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +11 -0 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # include/net/sock.h # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +5 -1 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # include/linux/ip.h # 2004/06/22 17:51:09-03:00 acme@conectiva.com.br +0 -2 # [NET] Move sndmsg_page and sndmsg_off to struct sock # # Yeah, the poor cousins will use this as well :-) # # ChangeSet # 2004/06/22 12:59:56-07:00 davem@nuts.davemloft.net # Merge bk://kernel.bkbits.net/acme/net-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/ipv4/tcp_input.c # 2004/06/22 12:59:47-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp.c # 2004/06/22 12:59:46-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/22 10:20:50-07:00 torvalds@ppc970.osdl.org # Merge bk://gkernel.bkbits.net/libata-2.6 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # drivers/scsi/Makefile # 2004/06/22 10:20:47-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/Kconfig # 2004/06/22 10:20:47-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/ide/Kconfig # 2004/06/22 10:20:47-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/22 10:18:32-07:00 torvalds@ppc970.osdl.org # sparse: clean up warning in swapfile.c # # mm/swapfile.c # 2004/06/22 10:18:26-07:00 torvalds@ppc970.osdl.org +1 -1 # sparse: clean up warning in swapfile.c # # ChangeSet # 2004/06/22 10:05:31-07:00 torvalds@ppc970.osdl.org # Merge bk://kernel.bkbits.net/davem/net-2.6 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # ChangeSet # 2004/06/22 13:02:35-04:00 jgarzik@pobox.com # [blk carmel] s/carmel/sx8/ in the driver itself # # drivers/block/sx8.c # 2004/06/22 13:02:29-04:00 jgarzik@pobox.com +3 -3 # [blk carmel] s/carmel/sx8/ in the driver itself # # ChangeSet # 2004/06/22 09:28:50-07:00 torvalds@ppc970.osdl.org # Fix C99'ism that breaks older gcc's. # # Also clean it all up - use get_cpu()/put_cpu() instead of # playing games by hand with preemption. # # ChangeSet # 2004/06/22 09:25:34-07:00 khali@linux-fr.org # [PATCH] I2C: Drop out-of-date code in w83781d and w83627hf # # Here is a simple patch which drops some out-of-date code in the w83781d # and w83627hf i2c chip drivers. These bits are left over from the times # when chip drivers were setting default limits at init. # # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83781d.c # 2004/06/19 11:22:05-07:00 khali@linux-fr.org +2 -9 # I2C: Drop out-of-date code in w83781d and w83627hf # # drivers/i2c/chips/w83627hf.c # 2004/06/19 11:21:06-07:00 khali@linux-fr.org +1 -4 # I2C: Drop out-of-date code in w83781d and w83627hf # # ChangeSet # 2004/06/22 09:20:30-07:00 greg@kroah.com # [PATCH] USB: sparse fixups for devio.c # # drivers/usb/core/devio.c # 2004/06/22 02:09:36-07:00 greg@kroah.com +10 -9 # USB: sparse fixups for devio.c # # ChangeSet # 2004/06/22 08:27:43-07:00 rddunlap@osdl.org # [PATCH] sparse: make sys_quotactl() prototype match function # # Al missed this one in his sparse fixes # # Signed-off-by: Randy Dunlap # Signed-off-by: Linus Torvalds # # include/linux/syscalls.h # 2004/06/21 21:31:11-07:00 rddunlap@osdl.org +1 -1 # sparse: make sys_quotactl() prototype match function # # ChangeSet # 2004/06/22 08:27:32-07:00 rddunlap@osdl.org # [PATCH] Fix sparse warning in drivers/block/ll_rw_blk.c # # From: Mika Kukkonen # Signed-off-by: Randy Dunlap # Signed-off-by: Linus Torvalds # # drivers/block/ll_rw_blk.c # 2004/06/21 19:20:21-07:00 rddunlap@osdl.org +1 -1 # Fix sparse warning in drivers/block/ll_rw_blk.c # # ChangeSet # 2004/06/22 08:27:21-07:00 rddunlap@osdl.org # [PATCH] Fix sparse warning in fs/proc/base.c # # From: Mika Kukkonen # Signed-off-by: Randy Dunlap # Signed-off-by: Linus Torvalds # # fs/proc/base.c # 2004/06/19 22:42:40-07:00 rddunlap@osdl.org +6 -3 # Fix sparse warning in fs/proc/base.c # # ChangeSet # 2004/06/22 08:27:10-07:00 rddunlap@osdl.org # [PATCH] Fix sparse warning in fs/devfs/base.c # # From: Mika Kukkonen # Signed-off-by: Randy Dunlap # Signed-off-by: Linus Torvalds # # fs/devfs/base.c # 2004/06/19 22:30:39-07:00 rddunlap@osdl.org +2 -1 # Fix sparse warning in fs/devfs/base.c # # ChangeSet # 2004/06/22 16:23:52+01:00 rmk@flint.arm.linux.org.uk # [ARM] Correct MMCI clock rate on Integrator/CP. # # arch/arm/mach-integrator/integrator_cp.c # 2004/06/22 16:21:27+01:00 rmk@flint.arm.linux.org.uk +2 -2 # MMCI clock is 14.7456MHz not 33MHz. # # ChangeSet # 2004/06/22 14:55:39+01:00 rmk@flint.arm.linux.org.uk # [ARM] Move cpu_switch_mm() and cpu_get_pgd() to asm/proc-fns.h # # include/asm-arm/proc-fns.h # 2004/06/22 14:53:15+01:00 rmk@flint.arm.linux.org.uk +16 -0 # Move cpu_switch_mm() and cpu_get_pgd() to asm/proc-fns.h # # include/asm-arm/cpu-single.h # 2004/06/22 14:53:15+01:00 rmk@flint.arm.linux.org.uk +2 -19 # Move cpu_switch_mm() and cpu_get_pgd() to asm/proc-fns.h # # include/asm-arm/cpu-multi32.h # 2004/06/22 14:53:15+01:00 rmk@flint.arm.linux.org.uk +1 -16 # Move cpu_switch_mm() and cpu_get_pgd() to asm/proc-fns.h # # ChangeSet # 2004/06/22 03:52:32-03:00 acme@conectiva.com.br # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_timer.c # 2004/06/22 03:52:20-03:00 acme@conectiva.com.br +2 -2 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_output.c # 2004/06/22 03:52:20-03:00 acme@conectiva.com.br +19 -17 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_minisocks.c # 2004/06/22 03:52:19-03:00 acme@conectiva.com.br +1 -1 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_input.c # 2004/06/22 03:52:19-03:00 acme@conectiva.com.br +12 -13 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/22 03:52:19-03:00 acme@conectiva.com.br +10 -10 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/sock.c # 2004/06/22 03:52:19-03:00 acme@conectiva.com.br +2 -0 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/22 03:52:19-03:00 acme@conectiva.com.br +5 -12 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/22 03:52:19-03:00 acme@conectiva.com.br +8 -0 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/linux/tcp.h # 2004/06/22 03:52:19-03:00 acme@conectiva.com.br +0 -1 # [NET] move send_head from tcp private area to struct sock # # The poor cousins also need this, LLC will be the first to use it. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/22 02:12:28-04:00 jgarzik@pobox.com # [libata ata_piix] combined mode bug fix; improved ICH6 support # # drivers/scsi/ata_piix.c # 2004/06/22 02:12:22-04:00 jgarzik@pobox.com +14 -11 # [libata ata_piix] combined mode bug fix; improved ICH6 support # # ChangeSet # 2004/06/22 00:54:50-04:00 jgarzik@pobox.com # [libata] fix build error, minor cleanups # # include/linux/libata.h # 2004/06/22 00:54:44-04:00 jgarzik@pobox.com +0 -5 # [libata] fix build error, minor cleanups # # drivers/scsi/libata-core.c # 2004/06/22 00:54:44-04:00 jgarzik@pobox.com +2 -3 # [libata] fix build error, minor cleanups # # ChangeSet # 2004/06/21 21:39:50-07:00 torvalds@ppc970.osdl.org # Fix up permissions of some files that were not readable # by "other". The normal permissions for the kernel tree # should be -rw-r--r--. # # Documentation/scsi/ChangeLog.megaraid # 2004/06/21 21:36:23-07:00 torvalds@ppc970.osdl.org +0 -0 # Change mode to -rw-r--r-- # # Documentation/networking/netif-msg.txt # 2004/06/21 21:36:17-07:00 torvalds@ppc970.osdl.org +0 -0 # Change mode to -rw-r--r-- # # ChangeSet # 2004/06/22 00:36:09-04:00 jgarzik@pobox.com # [libata] move some code around # # Split ata_eng_timeout into the main part (ata_qc_timeout) # and the part called by the SCSI layer (ata_eng_timeout). # # Zero behavior changes. # # drivers/input/joystick/grip_mp.c # 2004/06/21 21:36:04-07:00 torvalds@ppc970.osdl.org +0 -0 # Change mode to -rw-r--r-- # # drivers/scsi/libata-core.c # 2004/06/22 00:36:02-04:00 jgarzik@pobox.com +42 -12 # [libata] move some code around # # Split ata_eng_timeout into the main part (ata_qc_timeout) # and the part called by the SCSI layer (ata_eng_timeout). # # Zero behavior changes. # # drivers/char/drm/drm_irq.h # 2004/06/21 21:35:57-07:00 torvalds@ppc970.osdl.org +0 -0 # Change mode to -rw-r--r-- # # drivers/char/agp/isoch.c # 2004/06/21 21:34:47-07:00 torvalds@ppc970.osdl.org +0 -0 # Change mode to -rw-r--r-- # # ChangeSet # 2004/06/22 01:20:08-03:00 acme@conectiva.com.br # [NET] generalise tcp_moderate_sndbuf # # Renaming it to sk_stream_moderate_sndbuf, further patches will move # all the tcp memory pressure handling support into net/core/stream.c # to make them usable by the poor cousins, starting with LLC. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/22 01:19:56-03:00 acme@conectiva.com.br +1 -1 # [NET] generalise tcp_moderate_sndbuf # # Renaming it to sk_stream_moderate_sndbuf, further patches will move # all the tcp memory pressure handling support into net/core/stream.c # to make them usable by the poor cousins, starting with LLC. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/22 01:19:56-03:00 acme@conectiva.com.br +2 -10 # [NET] generalise tcp_moderate_sndbuf # # Renaming it to sk_stream_moderate_sndbuf, further patches will move # all the tcp memory pressure handling support into net/core/stream.c # to make them usable by the poor cousins, starting with LLC. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/22 01:19:56-03:00 acme@conectiva.com.br +8 -0 # [NET] generalise tcp_moderate_sndbuf # # Renaming it to sk_stream_moderate_sndbuf, further patches will move # all the tcp memory pressure handling support into net/core/stream.c # to make them usable by the poor cousins, starting with LLC. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/21 23:47:16-04:00 bunk@fs.tum.de # [PATCH] 2.6.7-mm1: drivers/scsi/hosts.h -> scsi/scsi_host.h # # On Sun, Jun 20, 2004 at 05:46:32PM -0700, Andrew Morton wrote: # >... # > All 226 patches: # >... # > bk-libata.patch # >... # # drivers/scsi/hosts.h is obsolete, use scsi/scsi_host.h. # # Please apply # Adrian # # drivers/scsi/sata_nv.c # 2004/06/20 21:51:17-04:00 bunk@fs.tum.de +1 -1 # 2.6.7-mm1: drivers/scsi/hosts.h -> scsi/scsi_host.h # # ChangeSet # 2004/06/22 00:46:47-03:00 acme@conectiva.com.br # [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb # # Will be used by the poor cousins # # Signed-of-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_output.c # 2004/06/22 00:46:35-03:00 acme@conectiva.com.br +2 -2 # [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb # # Will be used by the poor cousins # # Signed-of-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_input.c # 2004/06/22 00:46:35-03:00 acme@conectiva.com.br +4 -6 # [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb # # Will be used by the poor cousins # # Signed-of-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/22 00:46:35-03:00 acme@conectiva.com.br +1 -1 # [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb # # Will be used by the poor cousins # # Signed-of-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/22 00:46:35-03:00 acme@conectiva.com.br +1 -9 # [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb # # Will be used by the poor cousins # # Signed-of-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/22 00:46:35-03:00 acme@conectiva.com.br +11 -0 # [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb # # Will be used by the poor cousins # # Signed-of-by: Arnaldo Carvalho de Melo # # include/linux/tcp.h # 2004/06/22 00:46:35-03:00 acme@conectiva.com.br +1 -1 # [NET] generalise tcp_free_skb, renaming it to sk_stream_free_skb # # Will be used by the poor cousins # # Signed-of-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/21 20:26:23-07:00 viro@www.linux.org.uk # [PATCH] sparse: the rest of ieee1394 annotation # # drivers/ieee1394/video1394.c # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +10 -9 # sparse: the rest of ieee1394 annotation # # drivers/ieee1394/dv1394.c # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +6 -5 # sparse: the rest of ieee1394 annotation # # drivers/ieee1394/amdtp.c # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +2 -2 # sparse: the rest of ieee1394 annotation # # ChangeSet # 2004/06/21 20:26:12-07:00 viro@www.linux.org.uk # [PATCH] sparse: hd.c annotation # # drivers/firmware/efivars.c # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +1 -1 # sparse: hd.c annotation # # ChangeSet # 2004/06/21 20:26:01-07:00 viro@www.linux.org.uk # [PATCH] sparse: quota annotation # # fs/quota.c # 2004/06/21 07:11:50-07:00 viro@www.linux.org.uk +2 -2 # sparse: quota annotation # # ChangeSet # 2004/06/21 20:25:50-07:00 viro@www.linux.org.uk # [PATCH] sparse: sock_fprog sanitized # # sock_fprog instances that had kernel pointer in ->filter (both of them - # in ppp_generic and isdn_ppp) replaced with explicit pairs len + kernel # pointer. Copying of userland sock_fprog (with its __user ->filter) # cleaned up and sanitized. # # Trivial annotation done in the rest of ->ioctl() in ppp_generic and # isdn_ppp. # # include/linux/isdn_ppp.h # 2004/06/21 07:11:52-07:00 viro@www.linux.org.uk +3 -2 # sparse: sock_fprog sanitized # # drivers/net/ppp_generic.c # 2004/06/21 07:11:52-07:00 viro@www.linux.org.uk +100 -70 # sparse: sock_fprog sanitized # # drivers/isdn/i4l/isdn_ppp.h # 2004/06/21 07:11:52-07:00 viro@www.linux.org.uk +2 -2 # sparse: sock_fprog sanitized # # drivers/isdn/i4l/isdn_ppp.c # 2004/06/21 07:11:52-07:00 viro@www.linux.org.uk +103 -82 # sparse: sock_fprog sanitized # # ChangeSet # 2004/06/21 20:25:39-07:00 viro@www.linux.org.uk # [PATCH] sparse: raw1394 annotation # # drivers/ieee1394/raw1394.h # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +5 -5 # sparse: raw1394 annotation # # drivers/ieee1394/raw1394.c # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +41 -48 # sparse: raw1394 annotation # # drivers/ieee1394/raw1394-private.h # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +2 -2 # sparse: raw1394 annotation # # ChangeSet # 2004/06/21 20:25:28-07:00 viro@www.linux.org.uk # [PATCH] sparse: drivers/net/wan annotation # # include/linux/if.h # 2004/06/21 07:22:34-07:00 viro@www.linux.org.uk +7 -7 # sparse: drivers/net/wan annotation # # drivers/net/wan/x25_asy.c # 2004/06/21 07:22:00-07:00 viro@www.linux.org.uk +1 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/pci200syn.c # 2004/06/21 07:21:53-07:00 viro@www.linux.org.uk +2 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/n2.c # 2004/06/21 07:21:44-07:00 viro@www.linux.org.uk +2 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/lmc/lmc_ioctl.h # 2004/06/21 07:22:15-07:00 viro@www.linux.org.uk +2 -2 # sparse: drivers/net/wan annotation # # drivers/net/wan/hdlc_raw_eth.c # 2004/06/21 07:21:35-07:00 viro@www.linux.org.uk +1 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/hdlc_raw.c # 2004/06/21 07:21:19-07:00 viro@www.linux.org.uk +1 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/hdlc_fr.c # 2004/06/21 07:21:15-07:00 viro@www.linux.org.uk +1 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/hdlc_cisco.c # 2004/06/21 07:21:08-07:00 viro@www.linux.org.uk +1 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/dscc4.c # 2004/06/21 07:20:51-07:00 viro@www.linux.org.uk +1 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/cosa.h # 2004/06/21 07:20:41-07:00 viro@www.linux.org.uk +1 -1 # sparse: drivers/net/wan annotation # # drivers/net/wan/cosa.c # 2004/06/21 07:20:40-07:00 viro@www.linux.org.uk +21 -20 # sparse: drivers/net/wan annotation # # drivers/net/wan/c101.c # 2004/06/21 07:20:33-07:00 viro@www.linux.org.uk +2 -1 # sparse: drivers/net/wan annotation # # ChangeSet # 2004/06/21 20:25:16-07:00 viro@www.linux.org.uk # [PATCH] sparse: efivars.c initializer fix # # drivers/ide/legacy/hd.c # 2004/06/21 07:11:51-07:00 viro@www.linux.org.uk +1 -1 # sparse: efivars.c initializer fix # # ChangeSet # 2004/06/21 20:25:05-07:00 viro@www.linux.org.uk # [PATCH] sparse: zlib stray extern removal # # lib/zlib_deflate/deflate.c # 2004/06/21 07:11:50-07:00 viro@www.linux.org.uk +1 -1 # sparse: zlib stray extern removal # # ChangeSet # 2004/06/21 20:24:54-07:00 viro@www.linux.org.uk # [PATCH] sparse: ncpfs/ioctl.c annotation # # include/linux/ncp_fs.h # 2004/06/21 07:11:50-07:00 viro@www.linux.org.uk +3 -3 # sparse: ncpfs/ioctl.c annotation # # fs/ncpfs/ioctl.c # 2004/06/21 07:11:50-07:00 viro@www.linux.org.uk +37 -45 # sparse: ncpfs/ioctl.c annotation # # ChangeSet # 2004/06/21 20:24:44-07:00 viro@www.linux.org.uk # [PATCH] ibmtr missing include # # drivers/net/tokenring/ibmtr.c # 2004/06/21 07:19:31-07:00 viro@www.linux.org.uk +1 -0 # ibmtr missing include # # ChangeSet # 2004/06/21 19:56:37-07:00 torvalds@ppc970.osdl.org # Merge bk://linux-acpi.bkbits.net/linux-acpi-release-2.6.7 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # arch/i386/kernel/mpparse.c # 2004/06/21 19:56:34-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/21 23:01:24-03:00 acme@conectiva.com.br # [NET] generalise tcp_error, renaming it to sk_stream_error # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/21 23:01:13-03:00 acme@conectiva.com.br +2 -11 # [NET] generalise tcp_error, renaming it to sk_stream_error # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/21 23:01:13-03:00 acme@conectiva.com.br +11 -0 # [NET] generalise tcp_error, renaming it to sk_stream_error # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/21 23:01:13-03:00 acme@conectiva.com.br +1 -0 # [NET] generalise tcp_error, renaming it to sk_stream_error # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/21 20:59:09-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/bk/linux-acpi-test-2.6.7 # # arch/x86_64/kernel/mpparse.c # 2004/06/21 20:59:06-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/mpparse.c # 2004/06/21 20:59:06-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/21 20:53:04-04:00 len.brown@intel.com # [ACPI] re-factor previous mpparse IRQ override fix (Linus Torvalds) # Reflect that only the dstirq depends on the dstapic. # # arch/x86_64/kernel/mpparse.c # 2004/06/21 20:52:49-04:00 len.brown@intel.com +13 -7 # re-factor previous patch to reflect that only the dstirq # depends on the dstapic # # arch/i386/kernel/mpparse.c # 2004/06/21 20:52:49-04:00 len.brown@intel.com +16 -8 # re-factor previous patch to reflect that only the dstirq # depends on the dstapic # # ChangeSet # 2004/06/21 17:04:23-07:00 greg@kroah.com # merge fixups. # # drivers/scsi/scsi_debug.c # 2004/06/21 17:04:10-07:00 greg@kroah.com +1 -1 # merge fixups. # # ChangeSet # 2004/06/21 16:04:04-07:00 hadi@zynx.com # [PKT_SCHED]: C99'ify act_police_ops. # # net/sched/police.c # 2004/06/21 16:03:41-07:00 hadi@zynx.com +13 -13 # [PKT_SCHED]: C99'ify act_police_ops. # # ChangeSet # 2004/06/21 15:14:21-07:00 greg@kroah.com # merge # # drivers/scsi/scsi_debug.c # 2004/06/21 15:14:13-07:00 greg@kroah.com +2 -7 # merge # # ChangeSet # 2004/06/21 14:39:33-07:00 kaber@trash.net # [NETFILTER]: ip_table_raw C99 initialization # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/iptable_raw.c # 2004/06/21 14:39:19-07:00 kaber@trash.net +58 -37 # [NETFILTER]: ip_table_raw C99 initialization # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:38:44-07:00 kaber@trash.net # [NETFILTER]: Add realm match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/sched/Kconfig # 2004/06/21 14:38:11-07:00 kaber@trash.net +2 -2 # [NETFILTER]: Add realm match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/Makefile # 2004/06/21 14:38:11-07:00 kaber@trash.net +1 -0 # [NETFILTER]: Add realm match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/Kconfig # 2004/06/21 14:38:11-07:00 kaber@trash.net +14 -0 # [NETFILTER]: Add realm match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_realm.c # 2004/06/21 14:37:59-07:00 kaber@trash.net +76 -0 # [NETFILTER]: Add realm match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_realm.c # 2004/06/21 14:37:59-07:00 kaber@trash.net +0 -0 # BitKeeper file /disk1/BK/nf-2.6/net/ipv4/netfilter/ipt_realm.c # # include/linux/netfilter_ipv4/ipt_realm.h # 2004/06/21 14:37:58-07:00 kaber@trash.net +10 -0 # [NETFILTER]: Add realm match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # include/linux/netfilter_ipv4/ipt_realm.h # 2004/06/21 14:37:58-07:00 kaber@trash.net +0 -0 # BitKeeper file /disk1/BK/nf-2.6/include/linux/netfilter_ipv4/ipt_realm.h # # kernel/module.c # 2004/06/21 14:37:39-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/scsi/scsi_transport_spi.c # 2004/06/21 14:37:38-07:00 greg@kroah.com +0 -1 # Auto merged # # MAINTAINERS # 2004/06/21 14:37:38-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/06/21 14:36:31-07:00 kaber@trash.net # [NETFILTER]: Add addrtype match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/Makefile # 2004/06/21 14:36:07-07:00 kaber@trash.net +1 -0 # [NETFILTER]: Add addrtype match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/Kconfig # 2004/06/21 14:36:07-07:00 kaber@trash.net +10 -0 # [NETFILTER]: Add addrtype match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_addrtype.c # 2004/06/21 14:35:54-07:00 kaber@trash.net +77 -0 # [NETFILTER]: Add addrtype match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_addrtype.c # 2004/06/21 14:35:54-07:00 kaber@trash.net +0 -0 # BitKeeper file /disk1/BK/nf-2.6/net/ipv4/netfilter/ipt_addrtype.c # # include/linux/netfilter_ipv4/ipt_addrtype.h # 2004/06/21 14:35:52-07:00 kaber@trash.net +11 -0 # [NETFILTER]: Add addrtype match # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # include/linux/netfilter_ipv4/ipt_addrtype.h # 2004/06/21 14:35:52-07:00 kaber@trash.net +0 -0 # BitKeeper file /disk1/BK/nf-2.6/include/linux/netfilter_ipv4/ipt_addrtype.h # # ChangeSet # 2004/06/21 14:34:20-07:00 kaber@trash.net # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv6/sit.c # 2004/06/21 14:34:06-07:00 kaber@trash.net +2 -14 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv6/ip6_tunnel.c # 2004/06/21 14:34:06-07:00 kaber@trash.net +1 -7 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_REJECT.c # 2004/06/21 14:34:06-07:00 kaber@trash.net +1 -5 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/ipmr.c # 2004/06/21 14:34:06-07:00 kaber@trash.net +3 -12 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/ipip.c # 2004/06/21 14:34:06-07:00 kaber@trash.net +2 -14 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/ip_input.c # 2004/06/21 14:34:06-07:00 kaber@trash.net +1 -5 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/ip_gre.c # 2004/06/21 14:34:06-07:00 kaber@trash.net +2 -14 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # include/linux/skbuff.h # 2004/06/21 14:34:06-07:00 kaber@trash.net +12 -3 # [NETFILTER]: Add new function 'nf_reset' to reset netfilter related skb-fields # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:33:48-07:00 kaber@trash.net # [NETFILTER]: Relax hook check in ipt_CLASSIFY # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_CLASSIFY.c # 2004/06/21 14:33:34-07:00 kaber@trash.net +7 -5 # [NETFILTER]: Relax hook check in ipt_CLASSIFY # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:33:13-07:00 kaber@trash.net # [NETFILTER]: Fix offset calculation in amanda conntrack helper # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_conntrack_amanda.c # 2004/06/21 14:32:59-07:00 kaber@trash.net +1 -1 # [NETFILTER]: Fix offset calculation in amanda conntrack helper # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:32:37-07:00 kaber@trash.net # [NETFILTER]: Fix expectation eviction order # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_nat_core.c # 2004/06/21 14:32:23-07:00 kaber@trash.net +1 -1 # [NETFILTER]: Fix expectation eviction order # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/06/21 14:32:23-07:00 kaber@trash.net +7 -16 # [NETFILTER]: Fix expectation eviction order # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:32:04-07:00 kaber@trash.net # [NETFILTER]: Don't reroute on nfmark change in mangle table when routing by nfmark is not enabled # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/iptable_mangle.c # 2004/06/21 14:31:50-07:00 kaber@trash.net +2 -0 # [NETFILTER]: Don't reroute on nfmark change in mangle table when routing by nfmark is not enabled # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:31:28-07:00 kaber@trash.net # [NETFILTER]: 'any' matching in ipt_helper # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_helper.c # 2004/06/21 14:31:14-07:00 kaber@trash.net +5 -6 # [NETFILTER]: 'any' matching in ipt_helper # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:30:52-07:00 kaber@trash.net # [NETFILTER]: Fix inverted matching in ipt_helper # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_helper.c # 2004/06/21 14:30:38-07:00 kaber@trash.net +5 -6 # [NETFILTER]: Fix inverted matching in ipt_helper # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:30:19-07:00 kaber@trash.net # [NETFILTER]: skip internal targets in iptables proc listing # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv6/netfilter/ip6_tables.c # 2004/06/21 14:30:05-07:00 kaber@trash.net +10 -1 # [NETFILTER]: skip internal targets in iptables proc listing # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_tables.c # 2004/06/21 14:30:05-07:00 kaber@trash.net +10 -1 # [NETFILTER]: skip internal targets in iptables proc listing # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:29:41-07:00 kaber@trash.net # [NETFILTER]: Change permissions of /proc/net/ip_conntrack to 0440 # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_conntrack_standalone.c # 2004/06/21 14:29:27-07:00 kaber@trash.net +1 -1 # [NETFILTER]: Change permissions of /proc/net/ip_conntrack to 0440 # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:28:57-07:00 kaber@trash.net # [NETFILTER]: complain about brokeness on SMP for pid, sid and command matching in ipt_owner # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv6/netfilter/ip6t_owner.c # 2004/06/21 14:28:43-07:00 kaber@trash.net +8 -1 # [NETFILTER]: complain about brokeness on SMP for pid, sid and command matching in ipt_owner # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ipt_owner.c # 2004/06/21 14:28:43-07:00 kaber@trash.net +9 -1 # [NETFILTER]: complain about brokeness on SMP for pid, sid and command matching in ipt_owner # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:28:23-07:00 kaber@trash.net # [NETFILTER]: Fix non-existant config option for IP_NF_ASSERT, fix some broken assertions # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_nat_core.c # 2004/06/21 14:28:09-07:00 kaber@trash.net +3 -2 # [NETFILTER]: Fix non-existant config option for IP_NF_ASSERT, fix some broken assertions # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/06/21 14:28:09-07:00 kaber@trash.net +1 -3 # [NETFILTER]: Fix non-existant config option for IP_NF_ASSERT, fix some broken assertions # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # include/linux/netfilter_ipv4/ip_conntrack.h # 2004/06/21 14:28:09-07:00 kaber@trash.net +1 -1 # [NETFILTER]: Fix non-existant config option for IP_NF_ASSERT, fix some broken assertions # # Signed-off-by: Patrick McHardy # Signed-off-by: Harald Welte # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 14:07:06-07:00 herbert@gondor.apana.org.au # [NET]: In sungem driver, keep track of rx buffer alloc size based upon MTU. # # drivers/net/sungem.h # 2004/06/21 14:06:52-07:00 herbert@gondor.apana.org.au +2 -1 # [NET]: In sungem driver, keep track of rx buffer alloc size based upon MTU. # # drivers/net/sungem.c # 2004/06/21 14:06:52-07:00 herbert@gondor.apana.org.au +8 -4 # [NET]: In sungem driver, keep track of rx buffer alloc size based upon MTU. # # ChangeSet # 2004/06/21 15:22:34-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/bk/linux-acpi-test-2.6.7 # # arch/x86_64/kernel/mpparse.c # 2004/06/21 15:22:31-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/mpparse.c # 2004/06/21 15:22:31-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/21 15:20:51-04:00 len.brown@intel.com # [ACPI] fix double timer interrupt mapping (Hans-Frieder Vogt) # caused by errant fix for OSDL 2835 # # arch/x86_64/kernel/mpparse.c # 2004/06/21 15:20:45-04:00 len.brown@intel.com +1 -1 # fix previous fix that caused double timer interrupts (Hans-Frieder Vogt) # # arch/i386/kernel/mpparse.c # 2004/06/21 15:20:45-04:00 len.brown@intel.com +1 -1 # fix previous fix that caused double timer interrupts (Hans-Frieder Vogt) # # ChangeSet # 2004/06/21 14:52:56-04:00 jgarzik@pobox.com # Rename 'carmel' block driver to 'sx8'. # # Requested by Promise. The hardware isn't widely deployed yet, # with almost all users being early evaluators, so this should be OK. # # drivers/block/Makefile # 2004/06/21 14:52:50-04:00 jgarzik@pobox.com +1 -1 # Rename 'carmel' block driver to 'sx8'. # # Requested by Promise. The hardware isn't widely deployed yet, # with almost all users being early evaluators, so this should be OK. # # drivers/block/Kconfig # 2004/06/21 14:52:50-04:00 jgarzik@pobox.com +4 -4 # Rename 'carmel' block driver to 'sx8'. # # Requested by Promise. The hardware isn't widely deployed yet, # with almost all users being early evaluators, so this should be OK. # # Documentation/devices.txt # 2004/06/21 14:52:50-04:00 jgarzik@pobox.com +14 -14 # Rename 'carmel' block driver to 'sx8'. # # Requested by Promise. The hardware isn't widely deployed yet, # with almost all users being early evaluators, so this should be OK. # # drivers/block/sx8.c # 2004/06/21 14:49:55-04:00 jgarzik@pobox.com +0 -0 # Rename: drivers/block/carmel.c -> drivers/block/sx8.c # # ChangeSet # 2004/06/21 11:29:18-07:00 trini@kernel.crashing.org # [PPC32] Add SysRq-G support to our KGDB stub. # From David Woodhouse . # # arch/ppc/kernel/ppc-stub.c # 2004/06/21 11:29:10-07:00 trini@kernel.crashing.org +22 -0 # Add SysRq-G support. # # ChangeSet # 2004/06/21 09:34:33-07:00 akpm@osdl.org # [NET]: Loopback, allocate per-cpu stats statically and fix cpu refcounting. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/loopback.c # 2004/06/21 09:34:19-07:00 akpm@osdl.org +18 -17 # [NET]: Loopback, allocate per-cpu stats statically and fix cpu refcounting. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 09:32:44-07:00 akm@osdl.org # [NET]: Fix dev_queue_xmit build with older gcc. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/21 13:14:12-03:00 acme@conectiva.com.br # [NET] generalise tcp_set_owner_r and tcp_rfree # # Will be used by the poor cousins # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_input.c # 2004/06/21 13:14:00-03:00 acme@conectiva.com.br +4 -4 # [NET] generalise tcp_set_owner_r and tcp_rfree # # Will be used by the poor cousins # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/21 13:14:00-03:00 acme@conectiva.com.br +0 -8 # [NET] generalise tcp_set_owner_r and tcp_rfree # # Will be used by the poor cousins # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/21 13:14:00-03:00 acme@conectiva.com.br +10 -0 # [NET] generalise tcp_set_owner_r and tcp_rfree # # Will be used by the poor cousins # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/21 13:14:00-03:00 acme@conectiva.com.br +0 -10 # [NET] generalise tcp_set_owner_r and tcp_rfree # # Will be used by the poor cousins # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/21 13:14:00-03:00 acme@conectiva.com.br +10 -0 # [NET] generalise tcp_set_owner_r and tcp_rfree # # Will be used by the poor cousins # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/21 17:12:14+01:00 dwmw2@shinybook.infradead.org # Merge # # arch/ppc/Kconfig # 2004/06/21 17:12:04+01:00 dwmw2@shinybook.infradead.org +0 -2 # SCCS merged # # include/linux/serial_core.h # 2004/06/21 17:08:20+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # include/asm-ppc/ppcboot.h # 2004/06/21 17:08:20+01:00 dwmw2@shinybook.infradead.org +0 -1 # Auto merged # # drivers/serial/Makefile # 2004/06/21 17:08:20+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # drivers/serial/Kconfig # 2004/06/21 17:08:20+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # arch/ppc/syslib/Makefile # 2004/06/21 17:08:20+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # arch/ppc/Makefile # 2004/06/21 17:08:20+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # ChangeSet # 2004/06/21 16:44:37+01:00 dwmw2@shinybook.infradead.org # Merge # # include/asm-ppc/ppcboot.h # 2004/06/21 16:44:26+01:00 dwmw2@shinybook.infradead.org +1 -2 # SCCS merged # # arch/ppc/Kconfig # 2004/06/21 16:44:06+01:00 dwmw2@shinybook.infradead.org +2 -4 # SCCS merged # # include/linux/serial_core.h # 2004/06/21 16:39:51+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # include/asm-ppc/io.h # 2004/06/21 16:39:51+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # drivers/serial/Makefile # 2004/06/21 16:39:51+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # drivers/serial/Kconfig # 2004/06/21 16:39:51+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # arch/ppc/syslib/Makefile # 2004/06/21 16:39:51+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # arch/ppc/Makefile # 2004/06/21 16:39:51+01:00 dwmw2@shinybook.infradead.org +0 -0 # Auto merged # # ChangeSet # 2004/06/21 16:37:32+01:00 dwmw2@shinybook.infradead.org # Update CPM UART driver according to feedback from Dan Malek. # Patch from Pantelis Antoniou # # drivers/serial/cpm_uart/cpm_uart_core.c # 2004/06/21 16:37:14+01:00 dwmw2@shinybook.infradead.org +261 -261 # Fix up criticism from Dan Malek. # # drivers/serial/cpm_uart/cpm_uart.h # 2004/06/21 16:37:14+01:00 dwmw2@shinybook.infradead.org +39 -36 # Fix up criticism from Dan Malek. # # ChangeSet # 2004/06/21 15:01:21+01:00 dwmw2@shinybook.infradead.org # Add support for MPC8560 CPU and WindRiver PowerQUICC III SBC8560 # # Signed-off-by: Kumar Gala # # arch/ppc/platforms/85xx/sbc85xx.h # 2004/06/21 15:00:59+01:00 dwmw2@shinybook.infradead.org +57 -0 # # arch/ppc/platforms/85xx/sbc85xx.h # 2004/06/21 15:00:59+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/85xx-2.6/arch/ppc/platforms/85xx/sbc85xx.h # # arch/ppc/platforms/85xx/sbc85xx.c # 2004/06/21 15:00:57+01:00 dwmw2@shinybook.infradead.org +215 -0 # # arch/ppc/platforms/85xx/sbc85xx.c # 2004/06/21 15:00:57+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/85xx-2.6/arch/ppc/platforms/85xx/sbc85xx.c # # arch/ppc/platforms/85xx/sbc8560.h # 2004/06/21 15:00:56+01:00 dwmw2@shinybook.infradead.org +48 -0 # # arch/ppc/platforms/85xx/sbc8560.h # 2004/06/21 15:00:56+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/85xx-2.6/arch/ppc/platforms/85xx/sbc8560.h # # arch/ppc/platforms/85xx/sbc8560.c # 2004/06/21 15:00:54+01:00 dwmw2@shinybook.infradead.org +269 -0 # # arch/ppc/platforms/85xx/sbc8560.c # 2004/06/21 15:00:54+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/85xx-2.6/arch/ppc/platforms/85xx/sbc8560.c # # arch/ppc/platforms/85xx/mpc8560.c # 2004/06/21 15:00:53+01:00 dwmw2@shinybook.infradead.org +74 -0 # # include/asm-ppc/mpc85xx.h # 2004/06/21 15:00:53+01:00 dwmw2@shinybook.infradead.org +3 -0 # Add sbc8560.h if CONFIG_SBC8560 # # arch/ppc/syslib/ppc85xx_setup.h # 2004/06/21 15:00:53+01:00 dwmw2@shinybook.infradead.org +3 -1 # Remove bogus and sometimes gratuitous BASE_BAUD definition. # # arch/ppc/syslib/ppc85xx_setup.c # 2004/06/21 15:00:53+01:00 dwmw2@shinybook.infradead.org +2 -0 # Include ppc85xx_setup.h for PCIX_COMMAND. # # arch/ppc/platforms/85xx/mpc8560.c # 2004/06/21 15:00:53+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/85xx-2.6/arch/ppc/platforms/85xx/mpc8560.c # # arch/ppc/platforms/85xx/Makefile # 2004/06/21 15:00:53+01:00 dwmw2@shinybook.infradead.org +2 -0 # Add SBC8560 and MPC8560 files # # arch/ppc/platforms/85xx/Kconfig # 2004/06/21 15:00:53+01:00 dwmw2@shinybook.infradead.org +12 -1 # Add WindRiver PowerQUICC III and MPC8560 options. # # ChangeSet # 2004/06/21 09:50:47+01:00 rmk@flint.arm.linux.org.uk # [PCMCIA] 06-ide # # IDE releases the PCMCIA resource to work around the need to have # two conflicting subsystems (IDE and PCMCIA) claim resources. # Since PCMCIA no longer marks its resouces busy, this work around # must be removed. # # drivers/ide/legacy/ide-cs.c # 2004/06/21 09:47:32+01:00 rmk@flint.arm.linux.org.uk +0 -5 # Remove PCMCIA/IDE resource workaround # # ChangeSet # 2004/06/20 23:44:05-07:00 axboe@suse.de # [PATCH] only clear ->last_merge when appropriate # # Make sure we only clear q->last_merge hint, if it matches the request # currently passed in. # # Signed-off-by: Jens Axboe # Signed-off-by: Linus Torvalds # # drivers/block/ll_rw_blk.c # 2004/06/20 23:39:06-07:00 axboe@suse.de +8 -4 # only clear ->last_merge when appropriate # # ChangeSet # 2004/06/20 20:46:32-07:00 sam@ravnborg.org # [PATCH] kbuild: add deb-pkg target # # To prepare kbuild for more kernel packaging formats move all packaging support # to scripts/package. # # In top-level Makefile introduce generic support for all package formats using # target names *-pkg. Included the old rpm target for backward compatibility. # # A new variable KBUILD_IMAGE is used to specify what kernel image will be part # of the final package, and is to be set by the arch specific makefile. # KBUILD_IMAGE may be overridden from command line or environment. KBUILD_IMAGE # will see wider usage later, mainly when installing kernel images. # # Introducing KBUILD_IMAGE allowed arch specific details to be deleted from the # mkspec and builddeb scripts. # # While in the process added the deb packet format. Script is From: Wichert # Akkerman # # To create a RPM packet use 'make rpm-pkg'. # To create a deb packet use 'make deb-pkg'. # Both targets are included in 'make help' # # Signed-off-by: Sam Ravnborg # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # scripts/package/mkspec # 2004/06/20 18:23:45-07:00 sam@ravnborg.org +7 -16 # kbuild: add deb-pkg target # # scripts/package/builddeb # 2004/06/20 20:46:25-07:00 sam@ravnborg.org +79 -0 # # scripts/package/Makefile # 2004/06/20 20:46:25-07:00 sam@ravnborg.org +71 -0 # # scripts/Makefile # 2004/06/20 18:23:45-07:00 sam@ravnborg.org +1 -1 # kbuild: add deb-pkg target # # arch/i386/Makefile # 2004/06/20 18:23:45-07:00 sam@ravnborg.org +7 -6 # kbuild: add deb-pkg target # # Makefile # 2004/06/20 18:23:45-07:00 sam@ravnborg.org +25 -37 # kbuild: add deb-pkg target # # scripts/package/builddeb # 2004/06/20 20:46:25-07:00 sam@ravnborg.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/scripts/package/builddeb # # scripts/package/Makefile # 2004/06/20 20:46:25-07:00 sam@ravnborg.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/scripts/package/Makefile # # ChangeSet # 2004/06/20 20:46:14-07:00 sam@ravnborg.org # [PATCH] Avoid rebuild of IKCFG when using O= # # When using a separate output directory the in-kernel config wiere rebuild # each time the kernel was compiled. Fix this by specifying correct path to # Makefile in the prerequisite to the ikconfig.h file. # # Signed-off-by: Sam Ravnborg # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/Makefile # 2004/06/20 18:23:45-07:00 sam@ravnborg.org +1 -1 # Avoid rebuild of IKCFG when using O= # # ChangeSet # 2004/06/20 20:46:03-07:00 sam@ravnborg.org # [PATCH] wanxl firware build fix # # allmodconfig and allyesconfig are currently failing because they select # wanxl firmware rebuild, and that requires an m68k assembler toolchain. # # Add a new generic option to the "Generic Driver Options" menu. The option # is defaul equals y and prevents us from building firmware unless really # needed. # # Firmware is usually provided in separate filer '_shipped', and there is no # need to rebuild them unless strictly required. First user is WanXL - which # otherwise required a m68k tool-set to compile. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/net/wan/Kconfig # 2004/06/20 18:23:45-07:00 sam@ravnborg.org +1 -1 # wanxl firware build fix # # drivers/base/Kconfig # 2004/06/20 18:23:45-07:00 sam@ravnborg.org +9 -0 # wanxl firware build fix # # ChangeSet # 2004/06/20 20:45:52-07:00 geert@linux-m68k.org # [PATCH] Fix idr.h comment # # Fix path in header file. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/idr.h # 2004/06/20 18:23:45-07:00 geert@linux-m68k.org +1 -1 # Fix idr.h comment # # ChangeSet # 2004/06/20 20:45:41-07:00 juhl-lkml@dif.dk # [PATCH] Fix warning in tdfxfb.c # # drivers/video/tdfxfb.c:1104: warning: initialization discards qualifiers from pointer target type # # Signed-off-by: Jesper Juhl # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/tdfxfb.c # 2004/06/20 18:23:45-07:00 juhl-lkml@dif.dk +1 -1 # Fix warning in tdfxfb.c # # ChangeSet # 2004/06/20 20:45:30-07:00 nickpiggin@yahoo.com.au # [PATCH] lindent rwsem # # Lindent rwsem.c and rwsem-spinlock.c and fix a few things by hand. Also # added a couple of comments for the memory barriers. Added the __sched # annotation that was left out of rwsem-spinlock.c. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # lib/rwsem.c # 2004/06/20 18:23:45-07:00 nickpiggin@yahoo.com.au +59 -50 # lindent rwsem # # lib/rwsem-spinlock.c # 2004/06/20 18:23:45-07:00 nickpiggin@yahoo.com.au +51 -46 # lindent rwsem # # ChangeSet # 2004/06/20 20:45:19-07:00 akpm@osdl.org # [PATCH] jfs warning fix # # On ppc64, s64 is `long'. # # In file included from fs/jfs/jfs_xtree.h:25, # from fs/jfs/jfs_incore.h:26, # from fs/jfs/super.c:29: # fs/jfs/jfs_btree.h: In function `BT_STACK_DUMP': # fs/jfs/jfs_btree.h:151: warning: long long unsigned int format, s64 arg (arg 2) # # Cc: Dave Kleikamp # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/jfs/jfs_btree.h # 2004/06/20 18:23:45-07:00 akpm@osdl.org +1 -1 # jfs warning fix # # ChangeSet # 2004/06/20 20:45:08-07:00 ralf@linux-mips.org # [PATCH] Add M48T35 RTC driver # # Add M48T35 RTC driver for the SGI IP27 aka Origin 200, Origin 2000 and # Onyx 2. # # Signed-off-by: Ralf Baechle # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/char/ip27-rtc.c # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +327 -0 # Add M48T35 RTC driver # # drivers/char/Makefile # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +1 -0 # Add M48T35 RTC driver # # drivers/char/Kconfig # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +11 -0 # Add M48T35 RTC driver # # drivers/char/ip27-rtc.c # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/char/ip27-rtc.c # # ChangeSet # 2004/06/20 20:44:57-07:00 ralf@linux-mips.org # [PATCH] Cobalt LCD Driver update # # Mostly reformatting to get the sometimes random formatting style of the LCD # driver to something Linux compliant. Use module_init/exit for module # initialization and cleanup. # # Signed-off-by: Ralf Baechle # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/char/lcd.h # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +184 -0 # Cobalt LCD Driver update # # drivers/char/lcd.h # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/char/lcd.h # # drivers/char/lcd.c # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +375 -327 # Cobalt LCD Driver update # # drivers/char/Makefile # 2004/06/20 18:30:54-07:00 ralf@linux-mips.org +1 -0 # Cobalt LCD Driver update # # drivers/char/Kconfig # 2004/06/20 18:30:54-07:00 ralf@linux-mips.org +7 -0 # Cobalt LCD Driver update # # arch/mips/configs/cobalt_defconfig # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +1 -1 # Cobalt LCD Driver update # # arch/mips/Kconfig # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +0 -5 # Cobalt LCD Driver update # # ChangeSet # 2004/06/20 20:44:45-07:00 ralf@linux-mips.org # [PATCH] DS1286 cleanups # # Remove #ifdef'ed hooks for the DS1286 driver through the kernel. While # cleaning make it work as a module also and add back the core of the driver # got lost when drivers/sgi/ was shredded. # # Signed-off-by: Ralf Baechle # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/ds1286.h # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +54 -0 # DS1286 cleanups # # include/linux/ds1286.h # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/linux/ds1286.h # # fs/proc/proc_misc.c # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +0 -15 # DS1286 cleanups # # drivers/char/misc.c # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +0 -4 # DS1286 cleanups # # drivers/char/ds1286.c # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +578 -0 # DS1286 cleanups # # drivers/char/Makefile # 2004/06/20 18:30:55-07:00 ralf@linux-mips.org +1 -0 # DS1286 cleanups # # drivers/char/Kconfig # 2004/06/20 18:30:55-07:00 ralf@linux-mips.org +11 -0 # DS1286 cleanups # # arch/mips/defconfig # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +1 -1 # DS1286 cleanups # # arch/mips/configs/ip22_defconfig # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +1 -1 # DS1286 cleanups # # drivers/char/ds1286.c # 2004/06/20 18:23:44-07:00 ralf@linux-mips.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/char/ds1286.c # # ChangeSet # 2004/06/20 20:44:34-07:00 ralf@linux-mips.org # [PATCH] mips: remove old junk # # Remove old, unused initialization stuff. # # Signed-off-by: Ralf Baechle # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/char/misc.c # 2004/06/20 18:30:55-07:00 ralf@linux-mips.org +0 -13 # mips: remove old junk # # ChangeSet # 2004/06/20 20:44:23-07:00 bjoern@j3e.de # [PATCH] NLS support for ASCII # # I created an ASCII NSL module manually based on the ISO-8859-1 NLS module. # # This might be of use for people who do not want any charset conversion to # take place. fs modules like vfat for example then could be forced to # display any non-ASCII character in the uni_xlate escaped form. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/nls/nls_ascii.c # 2004/06/20 18:23:44-07:00 bjoern@j3e.de +167 -0 # NLS support for ASCII # # fs/nls/nls_ascii.c # 2004/06/20 18:23:44-07:00 bjoern@j3e.de +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/fs/nls/nls_ascii.c # # fs/nls/Makefile # 2004/06/20 18:23:44-07:00 bjoern@j3e.de +1 -0 # NLS support for ASCII # # fs/nls/Kconfig # 2004/06/20 18:23:44-07:00 bjoern@j3e.de +8 -0 # NLS support for ASCII # # ChangeSet # 2004/06/20 20:44:11-07:00 emoenke@gwdg.de # [PATCH] CREDITS update # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # CREDITS # 2004/06/20 18:23:44-07:00 emoenke@gwdg.de +2 -2 # CREDITS update # # ChangeSet # 2004/06/20 20:44:00-07:00 akpm@osdl.org # [PATCH] move as documentation # # Move the anticipatory scheduler documentation into Documentation/block. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # Documentation/block/as-iosched.txt # 2004/06/20 18:23:43-07:00 akpm@osdl.org +1 -1 # move as documentation # # ChangeSet # 2004/06/20 23:57:54-03:00 acme@conectiva.com.br # [NET] generalise wait_for_tcp_memory # # Renaming it to sk_stream_wait_memory # # Signed-off-by: Arnaldo Carvalho de Melo # # net/sctp/socket.c # 2004/06/20 23:57:40-03:00 acme@conectiva.com.br +1 -1 # [NET] generalise wait_for_tcp_memory # # Renaming it to sk_stream_wait_memory # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/20 23:57:40-03:00 acme@conectiva.com.br +2 -63 # [NET] generalise wait_for_tcp_memory # # Renaming it to sk_stream_wait_memory # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/20 23:57:40-03:00 acme@conectiva.com.br +63 -0 # [NET] generalise wait_for_tcp_memory # # Renaming it to sk_stream_wait_memory # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/20 23:57:40-03:00 acme@conectiva.com.br +1 -0 # [NET] generalise wait_for_tcp_memory # # Renaming it to sk_stream_wait_memory # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/20 23:47:17-03:00 acme@conectiva.com.br # [NET] introduce sk_stream_wait_close, from tcp code # # Will be used by the poor cousins. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/20 23:46:55-03:00 acme@conectiva.com.br +1 -27 # [NET] introduce sk_stream_wait_close, from tcp code # # Will be used by the poor cousins. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/20 23:46:55-03:00 acme@conectiva.com.br +28 -0 # [NET] introduce sk_stream_wait_close, from tcp code # # Will be used by the poor cousins. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/20 23:46:55-03:00 acme@conectiva.com.br +1 -0 # [NET] introduce sk_stream_wait_close, from tcp code # # Will be used by the poor cousins. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/20 23:33:23-03:00 acme@conectiva.com.br # [NET] generalise wait_for_tcp_connect # # This will be used by the poor cousins, look, for instance, at # x25_wait_for_connection_establishment :-) # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_input.c # 2004/06/20 23:33:12-03:00 acme@conectiva.com.br +1 -1 # [NET] generalise wait_for_tcp_connect # # This will be used by the poor cousins, look, for instance, at # x25_wait_for_connection_establishment :-) # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/20 23:33:12-03:00 acme@conectiva.com.br +4 -39 # [NET] generalise wait_for_tcp_connect # # This will be used by the poor cousins, look, for instance, at # x25_wait_for_connection_establishment :-) # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/20 23:33:12-03:00 acme@conectiva.com.br +37 -0 # [NET] generalise wait_for_tcp_connect # # This will be used by the poor cousins, look, for instance, at # x25_wait_for_connection_establishment :-) # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/sock.c # 2004/06/20 23:33:12-03:00 acme@conectiva.com.br +1 -0 # [NET] generalise wait_for_tcp_connect # # This will be used by the poor cousins, look, for instance, at # x25_wait_for_connection_establishment :-) # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/20 23:33:12-03:00 acme@conectiva.com.br +4 -0 # [NET] generalise wait_for_tcp_connect # # This will be used by the poor cousins, look, for instance, at # x25_wait_for_connection_establishment :-) # # Signed-off-by: Arnaldo Carvalho de Melo # # include/linux/tcp.h # 2004/06/20 23:33:12-03:00 acme@conectiva.com.br +0 -2 # [NET] generalise wait_for_tcp_connect # # This will be used by the poor cousins, look, for instance, at # x25_wait_for_connection_establishment :-) # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/20 18:58:22-07:00 axboe@suse.de # [PATCH] deadline I/O scheduler documentation # # Document the deadline scheduler and its tunables. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # Documentation/block/deadline-iosched.txt # 2004/06/20 18:23:43-07:00 axboe@suse.de +78 -0 # deadline I/O scheduler documentation # # Documentation/block/deadline-iosched.txt # 2004/06/20 18:23:43-07:00 axboe@suse.de +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/block/deadline-iosched.txt # # ChangeSet # 2004/06/20 18:58:10-07:00 juhl-lkml@dif.dk # [PATCH] isp16 check_region() removal # # Convert check_region to request_region and clean up some parentheses in # return statements for drivers/cdrom/isp16.c. # # Signed-off-by: Jesper Juhl # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/cdrom/isp16.c # 2004/06/20 18:23:43-07:00 juhl-lkml@dif.dk +27 -18 # isp16 check_region() removal # # ChangeSet # 2004/06/20 18:57:59-07:00 ak@suse.de # [PATCH] NUMA API updates # # This patch three issues in NUMA API # # - When 1 was passed to set_mempolicy or mbind as maxnodes argument # get_nodes could corrupt the stack and cause a crash. Fix that. # # - Remove the restriction to do interleaving only for order 0. Together # with the patch that went in previously to use interleaving policy at boot # time this should give back the original behaviour of distributing the big # hash tables. # # - Fix some bad white space in comments # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/mempolicy.c # 2004/06/20 18:23:43-07:00 ak@suse.de +13 -10 # NUMA API updates # # ChangeSet # 2004/06/20 18:57:48-07:00 mason@suse.com # [PATCH] fix possible stack corruption during reiserfs_file_write # # With preallocation turned on, reiserfs_allocate_blocks_for_region wasn't # sending a large enough array to hold all the blocks it was asking the block # allocator to find. This can result in stack corruption. # # The fix is to kmalloc an array to hold the blocks, making sure to allocate # something large enough. # # There was also a recent optimization to force the allocator to find a free # region large enough to hold the entire preallocation size. This was # sometimes causing more blocks to be allocated then had been requested, # which would also overflow the array. Something more elegant is required # here, until then just disable the optimization. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/reiserfs/file.c # 2004/06/20 18:23:43-07:00 mason@suse.com +15 -10 # fix possible stack corruption during reiserfs_file_write # # fs/reiserfs/bitmap.c # 2004/06/20 18:23:43-07:00 mason@suse.com +1 -4 # fix possible stack corruption during reiserfs_file_write # # ChangeSet # 2004/06/20 18:57:37-07:00 fabian.frederick@skynet.be # [PATCH] sparse annotation for sys_quotactl() # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/quota.c # 2004/06/20 18:23:43-07:00 fabian.frederick@skynet.be +1 -1 # sparse annotation for sys_quotactl() # # ChangeSet # 2004/06/20 18:57:26-07:00 hugh@veritas.com # [PATCH] mprotect propagate anon_vma # # When mprotect shifts the boundary between vmas (merging the reprotected # area into the vma before or the vma after), make sure that the expanding # vma has anon_vma if the shrinking vma had, to cover anon pages imported. # Thanks to Andrea for alerting us to this oversight. # # Cc: # Signed-off-by: Hugh Dickins # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/mmap.c # 2004/06/20 18:23:42-07:00 hugh@veritas.com +14 -1 # mprotect propagate anon_vma # # ChangeSet # 2004/06/20 18:57:15-07:00 jbarnes@engr.sgi.com # [PATCH] export sys_ioctl to modules # # Small patch to export sys_ioctl if CONFIG_COMPAT is set. This allows # platforms to implement 32 bit compatibility ioctl handlers in modules. # # Submitted-by: Jesse Barnes # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/ioctl.c # 2004/06/20 18:23:42-07:00 jbarnes@engr.sgi.com +10 -0 # export sys_ioctl to modules # # arch/x86_64/kernel/x8664_ksyms.c # 2004/06/20 18:23:42-07:00 jbarnes@engr.sgi.com +0 -1 # export sys_ioctl to modules # # arch/sparc64/kernel/sparc64_ksyms.c # 2004/06/20 18:23:42-07:00 jbarnes@engr.sgi.com +0 -1 # export sys_ioctl to modules # # arch/s390/kernel/s390_ksyms.c # 2004/06/20 18:23:42-07:00 jbarnes@engr.sgi.com +0 -1 # export sys_ioctl to modules # # arch/ppc64/kernel/ppc_ksyms.c # 2004/06/20 18:23:42-07:00 jbarnes@engr.sgi.com +0 -1 # export sys_ioctl to modules # # ChangeSet # 2004/06/20 18:57:04-07:00 hch@lst.de # [PATCH] fix isdn to not assume mem*io return values # # These are defined like the normal ISO C mem* routines although x86 happens # to return void by accident. Fix isdn to not assume a return value. # # Sent to the isdn list, but as usual I didn't get any reply. # # The patch is from the Debian kernel package and really old. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/isdn/sc/shmem.c # 2004/06/20 18:23:42-07:00 hch@lst.de +12 -21 # fix isdn to not assume mem*io return values # # drivers/isdn/sc/packet.c # 2004/06/20 18:23:42-07:00 hch@lst.de +2 -2 # fix isdn to not assume mem*io return values # # drivers/isdn/sc/message.c # 2004/06/20 18:23:42-07:00 hch@lst.de +0 -1 # fix isdn to not assume mem*io return values # # ChangeSet # 2004/06/20 18:56:53-07:00 kraxel@bytesex.org # [PATCH] v4l: radio-zoltrix fix. # # From: Paul Focke # # I recently upgraded from 2.4 to kernel 2.6 & noticed that the zoltrix radio # driver was not working. Seems like a little typo. I tested this on my system # and it's working fine now. I doubt there are any other linux users in the # world who still use this card ;-) # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/radio/radio-zoltrix.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +1 -1 # v4l: radio-zoltrix fix. # # ChangeSet # 2004/06/20 18:56:42-07:00 kraxel@bytesex.org # [PATCH] v4l: cx88 driver update # # This is a update for the cx88 tv card driver. Changes: # # * finally make it build with gcc 2.95 ;) # # * add new tv cards. # # * plenty of fixes for the TV sound code. # # * use v4l2 API for communication with tuner + tda9887 # # * misc other minor stuff. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/video/cx88/cx88.h # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +21 -13 # v4l: cx88 driver update # # drivers/media/video/cx88/cx88-video.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +99 -76 # v4l: cx88 driver update # # drivers/media/video/cx88/cx88-vbi.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +5 -8 # v4l: cx88 driver update # # drivers/media/video/cx88/cx88-tvaudio.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +240 -157 # v4l: cx88 driver update # # drivers/media/video/cx88/cx88-reg.h # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +10 -0 # v4l: cx88 driver update # # drivers/media/video/cx88/cx88-i2c.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +0 -2 # v4l: cx88 driver update # # drivers/media/video/cx88/cx88-cards.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +162 -14 # v4l: cx88 driver update # # ChangeSet # 2004/06/20 18:56:31-07:00 kraxel@bytesex.org # [PATCH] saa7134 driver update # # This is an update for the saa7134 driver. Changes: # # # * add support for more TV cards, as usual ;) # # * add support for image cropping. # # * use v4l2 API to talk to the tuner chips (thus it depends on the # tuner/tda9887 patch). # # * fixes for the audio carrier scan. # # * make transport stream packet size configurable. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/video/saa7134/saa7134.h # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +5 -1 # saa7134 driver update # # drivers/media/video/saa7134/saa7134-video.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +114 -87 # saa7134 driver update # # drivers/media/video/saa7134/saa7134-tvaudio.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +103 -69 # saa7134 driver update # # drivers/media/video/saa7134/saa7134-ts.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +17 -10 # saa7134 driver update # # drivers/media/video/saa7134/saa7134-oss.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +3 -2 # saa7134 driver update # # drivers/media/video/saa7134/saa7134-input.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +65 -3 # saa7134 driver update # # drivers/media/video/saa7134/saa7134-core.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +12 -4 # saa7134 driver update # # drivers/media/video/saa7134/saa7134-cards.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +102 -20 # saa7134 driver update # # drivers/media/video/saa7134/saa6752hs.c # 2004/06/20 18:23:42-07:00 kraxel@bytesex.org +0 -1 # saa7134 driver update # # ChangeSet # 2004/06/20 18:56:19-07:00 kraxel@bytesex.org # [PATCH] v4l: IR input driver update. # # This patch updates the ir-kbd-gpio and ir-kbd-i2c drivers. Nothing major, # just some keytable fixes and support for more hardware. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/video/ir-kbd-i2c.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +106 -16 # v4l: IR input driver update. # # drivers/media/video/ir-kbd-gpio.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +41 -41 # v4l: IR input driver update. # # ChangeSet # 2004/06/20 18:56:08-07:00 kraxel@bytesex.org # [PATCH] v4l: bttv driver update # # This is a update of the bttv driver. Changes: # # * some card-specific fixes + new cards. # # * separate buffer switching for video frames and vbi data, that should make # bttv less sensitive to high irq latencies. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/video/bttvp.h # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +8 -5 # v4l: bttv driver update # # drivers/media/video/bttv.h # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +2 -0 # v4l: bttv driver update # # drivers/media/video/bttv-vbi.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +4 -1 # v4l: bttv driver update # # drivers/media/video/bttv-risc.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +18 -10 # v4l: bttv driver update # # drivers/media/video/bttv-driver.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +95 -36 # v4l: bttv driver update # # drivers/media/video/bttv-cards.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +92 -3 # v4l: bttv driver update # # ChangeSet # 2004/06/20 18:55:57-07:00 kraxel@bytesex.org # [PATCH] v4l: tuner + tda9887 updates # # This is a big update for the tuner and tda9887 modules which are used for TV # card tuning. # # The tda9887 module is basically completely rewritten and understands all the # config bits now instead of having just some fixed config presets. Some of # these config bits can be changed by insmod options now. # # The other big change is that both modules allow to use the V4L2 API for # inter-module communication (i.e. when bttv/saa7134/... pass through the # tuning ioctls to the modules). That allows to specify the TV norm more # precisely (not just PAL but PAL-I, PAL-BG, ...), which is needed in some cases # to make TV audio work correctly. Using the old v4l1 API is still possible so # this shouldn't break any users of these two modules. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/video/tuner.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +173 -68 # v4l: tuner + tda9887 updates # # drivers/media/video/tda9887.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +414 -202 # v4l: tuner + tda9887 updates # # ChangeSet # 2004/06/20 18:55:46-07:00 kraxel@bytesex.org # [PATCH] v4l: ir-common update # # Some minor changes for the ir-common module: Update for the RC5 keytable and # increase the IR_KEYTAB_SIZE #define. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/media/ir-common.h # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +1 -1 # v4l: ir-common update # # drivers/media/common/ir-common.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +2 -2 # v4l: ir-common update # # ChangeSet # 2004/06/20 18:55:35-07:00 kraxel@bytesex.org # [PATCH] v4l: msp3400 cleanup. # # This patch has some cleanups for the msp3400 module: Balance is used directly # now instead of maintaining the state as left/right volume and calculate the # balance from that. The msp3400 did that only for historical reasons and it # isn't needed any more ... # # Credits for that go to Perry Gilfillan. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/media/video/msp3400.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +29 -33 # v4l: msp3400 cleanup. # # ChangeSet # 2004/06/20 18:55:24-07:00 kraxel@bytesex.org # [PATCH] v4l: video-buf fixes. # # This patch has some minor bugfixes for the video-buf module. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/media/video-buf.h # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +0 -2 # v4l: video-buf fixes. # # drivers/media/video/video-buf.c # 2004/06/20 18:23:41-07:00 kraxel@bytesex.org +11 -4 # v4l: video-buf fixes. # # ChangeSet # 2004/06/20 18:55:13-07:00 kraxel@bytesex.org # [PATCH] v4l: video-buf magic numbers # # This patch adds some magic IDs and checks for them to the data structs of the # video-buf module. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/media/video-buf.h # 2004/06/20 18:30:58-07:00 kraxel@bytesex.org +4 -0 # v4l: video-buf magic numbers # # drivers/media/video/video-buf.c # 2004/06/20 18:30:58-07:00 kraxel@bytesex.org +26 -6 # v4l: video-buf magic numbers # # ChangeSet # 2004/06/20 18:55:02-07:00 kraxel@bytesex.org # [PATCH] v4l: update video-buf for per-frame input switching. # # This patch updates the video-buf module to support the per-frame input # switching added by the v4l2 API patch. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/media/video-buf.h # 2004/06/20 18:30:58-07:00 kraxel@bytesex.org +5 -1 # v4l: update video-buf for per-frame input switching. # # drivers/media/video/video-buf.c # 2004/06/20 18:30:58-07:00 kraxel@bytesex.org +14 -0 # v4l: update video-buf for per-frame input switching. # # ChangeSet # 2004/06/20 18:54:51-07:00 kraxel@bytesex.org # [PATCH] v4l: v4l2 API updates # # This patch has some minor updates to v4l2 API: # # * A new pixel format (V4L2_PIX_FMT_SBGGR8). # # * Adds some #defines for tv norms for convenience. # # * Allow to specify the video source to capture from on a per-frame basis. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/videodev2.h # 2004/06/20 18:23:40-07:00 kraxel@bytesex.org +12 -5 # v4l: v4l2 API updates # # ChangeSet # 2004/06/20 18:54:40-07:00 axboe@suse.de # [PATCH] iommu max segment size # # This patch is from James, I've changed it slightly only. # # The problem is that some IOMMU implementations have a maximum limit to the # size of the number of contiguously mappable pages (admittedly, this limit # is mostly in the resource management algorithms rather than the IOMMUs # themselves). # # This patch adds this concept to the bio layer via the parameter # # BIO_VMERGE_MAX_SIZE # # which architectures can define in asm/io.h (if undefined, we assume it to # be infinite, which is current behaviour). # # While adding this, I noticed several places where bio was making incorrect # assumptions about virtual mergeability (none of which was a bug: bio was # overestimating rather than underestimating). # # - The worst offender was bio_add_page(), which seemed never to check for # virtual mergeability # # - I also fixed blk_hw_contig_segments() not to check the QUEUE_CLUSTER # flag, and not to check the phys segment boundary. # # In order to track the hw segment size across bios, I had to introduce two # extra bio parameters: bi_hw_front_size and bi_hw_back_size which store the # sizes of the front and back hw contiguous segments (and which will be equal # if there's only one hw segment). When the bio is merged into a request, # these fields are updated with the total hw contig size so they can always # be used to assess if the merger would violate the BIO_VMERGE_MAX_SIZE # parameter. # # Signed-Off-By: Jens Axboe # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/bio.h # 2004/06/20 18:23:40-07:00 axboe@suse.de +18 -0 # iommu max segment size # # fs/bio.c # 2004/06/20 18:23:40-07:00 axboe@suse.de +11 -3 # iommu max segment size # # drivers/block/ll_rw_blk.c # 2004/06/20 18:23:40-07:00 axboe@suse.de +80 -24 # iommu max segment size # # ChangeSet # 2004/06/20 18:54:29-07:00 dcn@sgi.com # [PATCH] add wait_event_interruptible_exclusive() macro # # This patch defines a macro that does exactly what # wait_event_interruptible() does except that it adds the current task to the # wait queue as an exclusive task (i.e., sets the WQ_FLAG_EXCLUSIVE flag) # rather than as a non-exclusive task as wait_event_interruptible() does. # # This allows one to do a wake_up_nr() to wake up a specific number of tasks. # I'm in the process of submitting a patch to linux-ia64 that requires this # capability. (Its subject line is "[PATCH 3/4] SGI Altix cross partition # functionality".) # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/wait.h # 2004/06/20 18:23:40-07:00 dcn@sgi.com +30 -1 # add wait_event_interruptible_exclusive() macro # # ChangeSet # 2004/06/20 18:54:18-07:00 mika@osdl.org # [PATCH] Uninline machine_specific_memory_setup() # # Cleanup arch/i386/kernel/setup.c a little bit by: # # * un-inlining machine_specific_memory_setup() (it's implementations are # pretty big to be inlined anyway) # # * remove setup_memory_region() by moving the code inside setup_arch() # # I would also recommend BK-renaming all four files # (include/asm-i386/*/setup_arch_post.h) to ".c" and moving them into # arch/i386/*/, but that obviously is not needed in anyway. But IMHO they # are clearly ".c" files, not ".h" files. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/mach-voyager/setup_arch_post.h # 2004/06/20 18:23:40-07:00 mika@osdl.org +1 -1 # Uninline machine_specific_memory_setup() # # include/asm-i386/mach-visws/setup_arch_post.h # 2004/06/20 18:23:40-07:00 mika@osdl.org +1 -1 # Uninline machine_specific_memory_setup() # # include/asm-i386/mach-default/setup_arch_post.h # 2004/06/20 18:23:40-07:00 mika@osdl.org +1 -1 # Uninline machine_specific_memory_setup() # # arch/i386/kernel/setup.c # 2004/06/20 18:23:40-07:00 mika@osdl.org +6 -12 # Uninline machine_specific_memory_setup() # # ChangeSet # 2004/06/20 18:54:07-07:00 mark@alpha.dyndns.org # [PATCH] Add ovcamchip driver # # This patch adds a new driver for the OmniVision OV6xx0 and OV7xx0 series of # CMOS image sensors. It is currently used by the w9968cf USB webcam driver, # which is already in mainline 2.6. Up until now it had to be compiled # outside the kernel tree, which is clearly suboptimal. # # It is also used by version 2 of the ov511 USB webcam driver, which will be # merged in the near future. That will reduce some code duplication, since # the existing ov511 has much of this code built-in. # # This was previously submitted to Linux-USB-Devel, and I have fixed the # concerns that came up at that time. # # Developer's Certificate of Origin 1.0 # # By making a contribution to this project, I certify that: # # (a) The contribution was created in whole or in part by me and I # have the right to submit it under the open source license # indicated in the file; or # # (b) The contribution is based upon previous work that, to the best # of my knowledge, is covered under an appropriate open source # license and I have the right under that license to submit that # work with modifications, whether created in whole or in part # by me, under the same open source license (unless I am # by me, under the same open source license (unless I am # permitted to submit under a different license), as indicated # in the file; or # # (c) The contribution was provided directly to me by some other # person who certified (a), (b) or (c) and I have not modified # it. # # Signed-off-by: Mark McClelland # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/media/ovcamchip.h # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +104 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/ovcamchip_priv.h # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +87 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/ovcamchip_core.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +446 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/ov7x20.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +455 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/ov7x10.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +335 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/ov76be.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +303 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/ov6x30.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +374 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/ov6x20.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +415 -0 # Add ovcamchip driver # # drivers/media/video/ovcamchip/Makefile # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +4 -0 # Add ovcamchip driver # # include/media/ovcamchip.h # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/media/ovcamchip.h # # drivers/media/video/ovcamchip/ovcamchip_priv.h # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/ovcamchip_priv.h # # drivers/media/video/ovcamchip/ovcamchip_core.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/ovcamchip_core.c # # drivers/media/video/ovcamchip/ov7x20.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/ov7x20.c # # drivers/media/video/ovcamchip/ov7x10.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/ov7x10.c # # drivers/media/video/ovcamchip/ov76be.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/ov76be.c # # drivers/media/video/ovcamchip/ov6x30.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/ov6x30.c # # drivers/media/video/ovcamchip/ov6x20.c # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/ov6x20.c # # drivers/media/video/ovcamchip/Makefile # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/media/video/ovcamchip/Makefile # # drivers/media/video/Makefile # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +1 -0 # Add ovcamchip driver # # drivers/media/video/Kconfig # 2004/06/20 18:23:40-07:00 mark@alpha.dyndns.org +11 -0 # Add ovcamchip driver # # ChangeSet # 2004/06/20 18:53:55-07:00 akpm@osdl.org # [PATCH] swapoff: activate pages # # People like to use swapoff/swapon as a way of restoring their VM to a # predictable "preconditional" state. # # Problem is, swapoff leaves mapped anon/pagecache pages on the inactive list, # so they immediately get swapped out again when swapspace becomes available. # # Let's move these pages onto the active list to the VM has to again decide # whether to swap them out. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/swapfile.c # 2004/06/20 18:21:45-07:00 akpm@osdl.org +7 -0 # swapoff: activate pages # # ChangeSet # 2004/06/20 18:53:44-07:00 shaggy@austin.ibm.com # [PATCH] jfs build fix # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/jfs/jfs_dtree.c # 2004/06/20 18:21:45-07:00 shaggy@austin.ibm.com +2 -1 # jfs build fix # # ChangeSet # 2004/06/20 18:53:33-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] airo.c broke # # But Al fixed it again. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/net/wireless/airo.c # 2004/06/20 18:21:44-07:00 viro@parcelfarce.linux.theplanet.co.uk +2 -0 # airo.c broke # # ChangeSet # 2004/06/20 18:53:22-07:00 paulkf@microgate.com # [PATCH] ppp_synctty.c receive/write_wakeup fix # # Allow receive and write_wakeup callbacks to be called at hard interrupt # context and/or with interrupts disabled (removes softirq warning). # # This mirrors changes by Paul Mackerras to ppp_async.c for the same purpose. # Patch has been previously posted for comments and has been tested with # success by multiple persons. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/net/ppp_synctty.c # 2004/06/20 18:20:58-07:00 paulkf@microgate.com +92 -69 # ppp_synctty.c receive/write_wakeup fix # # ChangeSet # 2004/06/20 18:53:11-07:00 cesarb@nitnet.com.br # [PATCH] O_NOATIME support # # This patch adds support for the O_NOATIME open flag (GNU extension): # # int O_NOATIME Macro # If this bit is set, read will not update the access time of the file. # See File Times. This is used by programs that do backups, so that # backing a file up does not count as reading it. Only the owner of the # file or the superuser may use this bit. # # It is useful if you want to do something with the file atime (for instance, # moving files that have not been accessed in a while to somewhere else, or # something like Debian's popularity-contest) but you also want to read all # files periodically (for instance, tripwire or debsums). # # Currently, the program that reads all files periodically has to use utimes, # which can race with the atime update: # # A B # open # fstat # read # open # read # close # close # utimes # # And the file still has the old atime, instead of the new one from when B # did the read from it. This problem does not happen if A uses O_NOATIME # instead of utimes to preserve the atime. # # This patch adds the O_NOATIME constant for all architectures, but it would # also be possible to add it one architecture at a time by defining it to 0 # when not defined in asm-*. # # Based on patch by Marek Michalkiewicz at # http://www.uwsg.iu.edu/hypermail/linux/kernel/9811.2/0118.html # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/fs.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +2 -1 # O_NOATIME support # # include/asm-x86_64/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-v850/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-sparc64/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-sparc/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-sh/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-s390/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-ppc64/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-ppc/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-parisc/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-mips/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-m68k/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-ia64/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-i386/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-h8300/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-cris/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-arm26/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-arm/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # include/asm-alpha/fcntl.h # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +1 -0 # O_NOATIME support # # fs/namei.c # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +5 -0 # O_NOATIME support # # fs/fcntl.c # 2004/06/20 18:20:57-07:00 cesarb@nitnet.com.br +6 -1 # O_NOATIME support # # ChangeSet # 2004/06/20 18:52:59-07:00 dhowells@redhat.com # [PATCH] Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # Here's a patch to allocate memory for big system hash tables with the # bootmem allocator rather than with main page allocator. # # It is needed for three reasons: # # (1) So that the size can be bigger than MAX_ORDER. IBM have done some # testing on their big PPC64 systems (64GB of RAM) with linux-2.4 and found # that they get better performance if the sizes of the inode cache hash, # dentry cache hash, buffer head hash and page cache hash are increased # beyond MAX_ORDER (order 11). # # Now the main allocator can't allocate anything larger than MAX_ORDER, but # the bootmem allocator can. # # In 2.6 it appears that only the inode and dentry hashes remain of those # four, but there are other hash tables that could use this service. # # (2) Changing MAX_ORDER appears to have a number of effects beyond just # limiting the maximum size that can be allocated in one go. # # (3) Should someone want a hash table in which each bucket isn't a power of # two in size, memory will be wasted as the chunk of memory allocated will # be a power of two in size (to hold a power of two number of buckets). # # On the other hand, using the bootmem allocator means the allocation # will only take up sufficient pages to hold it, rather than the next power # of two up. # # Admittedly, this point doesn't apply to the dentry and inode hashes, # but it might to another hash table that might want to use this service. # # # I've coelesced the meat of the inode and dentry allocation routines into # one such routine in mm/page_alloc.c that the the respective initialisation # functions now call before mem_init() is called. # # This routine gets it's approximation of memory size by counting up the # ZONE_NORMAL and ZONE_DMA pages (and ZONE_HIGHMEM if requested) in all the # nodes passed to the main allocator by paging_init() (or wherever the arch # does it). It does not use max_low_pfn as that doesn't seem to be available # on all archs, and it doesn't use num_physpages since that includes highmem # pages not available to the kernel for allocating data structures upon - # which may not be appropriate when calculating hash table size. # # On the off chance that the size of each hash bucket may not be exactly a # power of two, the routine will only allocate as many pages as is necessary # to ensure that the number of buckets is exactly a power of two, rather than # allocating the smallest power-of-two sized chunk of memory that will hold # the same array of buckets. # # The maximum size of any single hash table is given by # MAX_SYS_HASH_TABLE_ORDER, as is now defined in linux/mmzone.h. # # Signed-off-by: Paul Mackerras # Signed-off-by: David Howells # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/page_alloc.c # 2004/06/20 18:20:10-07:00 dhowells@redhat.com +73 -0 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # init/main.c # 2004/06/20 18:19:55-07:00 dhowells@redhat.com +1 -0 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # include/linux/mmzone.h # 2004/06/20 18:19:55-07:00 dhowells@redhat.com +12 -0 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # include/linux/kernel.h # 2004/06/20 18:20:10-07:00 dhowells@redhat.com +9 -0 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # include/linux/fs.h # 2004/06/20 18:31:00-07:00 dhowells@redhat.com +7 -4 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # include/linux/bootmem.h # 2004/06/20 18:19:55-07:00 dhowells@redhat.com +8 -0 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # fs/inode.c # 2004/06/20 18:20:10-07:00 dhowells@redhat.com +18 -42 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # fs/dcache.c # 2004/06/20 18:20:10-07:00 dhowells@redhat.com +24 -44 # Permit inode & dentry hash tables to be allocated > MAX_ORDER size # # ChangeSet # 2004/06/20 18:52:48-07:00 daniel.ritz@gmx.ch # [PATCH] pcmcia: enable read prefetch on o2micro bridges to fix HDSP # # enable read prefetching on O2micro bridges. It fixes the problems # seen with the RME Hammerfall DSP. # Thanks to Eric Still from O2micro for the input. # # Cc: Russell King # Signed-off-by: Daniel Ritz # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/pcmcia/yenta_socket.c # 2004/06/20 18:19:18-07:00 daniel.ritz@gmx.ch +9 -1 # pcmcia: enable read prefetch on o2micro bridges to fix HDSP # # drivers/pcmcia/o2micro.h # 2004/06/20 18:19:18-07:00 daniel.ritz@gmx.ch +26 -0 # pcmcia: enable read prefetch on o2micro bridges to fix HDSP # # drivers/pcmcia/i82365.c # 2004/06/20 18:19:18-07:00 daniel.ritz@gmx.ch +0 -1 # pcmcia: enable read prefetch on o2micro bridges to fix HDSP # # ChangeSet # 2004/06/20 18:52:36-07:00 pazke@donpac.ru # [PATCH] use new DMI API for HP Pavilion # # Example code for the new DMI APU - port HP Pavilion irq workaround to new # DMI probing. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/pci/visws.c # 2004/06/20 18:17:56-07:00 pazke@donpac.ru +0 -2 # use new DMI API for HP Pavilion # # arch/i386/pci/irq.c # 2004/06/20 18:19:08-07:00 pazke@donpac.ru +31 -1 # use new DMI API for HP Pavilion # # arch/i386/kernel/dmi_scan.c # 2004/06/20 18:18:45-07:00 pazke@donpac.ru +0 -25 # use new DMI API for HP Pavilion # # ChangeSet # 2004/06/20 18:52:25-07:00 pazke@donpac.ru # [PATCH] export DMI check functions # # This patch creates and exports 2 functions which can be used by the rest of # kernel code to perform DMI data checks: # # - dmi_check_system() function checks system DMI data against given blacklist # table and on each match runs corresponding callback function; # # - dmi_get_system_info() function returns DMI data value. Useful for people # wanting more complex DMI data check than simple string match. # # Also filling unused match entries with NO_MATCH made optional, but existing # NO_MATCH occurences are left intact, so people are free to continue dmi_scan.c # patching without massive reject problems. # # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/dmi.h # 2004/06/20 18:17:49-07:00 pazke@donpac.ru +47 -0 # export DMI check functions # # include/linux/dmi.h # 2004/06/20 18:17:49-07:00 pazke@donpac.ru +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/linux/dmi.h # # arch/i386/kernel/dmi_scan.c # 2004/06/20 18:31:01-07:00 pazke@donpac.ru +55 -56 # export DMI check functions # # ChangeSet # 2004/06/20 18:52:14-07:00 akpm@osdl.org # [PATCH] ppc64: eeh.h warning-fix # # In file included from include/asm/io.h:365, # from drivers/video/kyro/STG4000Reg.h:23, # from drivers/video/kyro/STG4000Ramdac.c:16: # include/asm/eeh.h:58: warning: `struct device_node' declared inside parameter list # include/asm/eeh.h:58: warning: its scope is only this definition or declaration, which is probably not what you want # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-ppc64/eeh.h # 2004/06/20 18:15:35-07:00 akpm@osdl.org +1 -0 # ppc64: eeh.h warning-fix # # ChangeSet # 2004/06/20 18:52:03-07:00 akpm@osdl.org # [PATCH] ppc64 CONFIG_ALTIVEC=n build fix # # With CONFIG_ALTIVEC=n, flush_altivec_to_thread() has no implementation. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-ppc64/system.h # 2004/06/20 18:15:35-07:00 akpm@osdl.org +9 -1 # ppc64 CONFIG_ALTIVEC=n build fix # # ChangeSet # 2004/06/20 18:27:13-07:00 dsaxena@omelas.(none) # Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk # into omelas.(none):/home/dsaxena/src/linux-2.6-for-rmk # # BitKeeper/deleted/.del-core.c~9e662b6895b788f2 # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # BitKeeper/deleted/.del-core.c~714a718aec4a2c30 # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/kernel/entry-armv.S # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/common/Makefile # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/Makefile # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/Kconfig # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # BitKeeper/deleted/.del-time.h~e839fe4bcd9e4cf9 # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # BitKeeper/deleted/.del-time.h~730e38fa47912a2c # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # BitKeeper/deleted/.del-core.c~9e662b6895b788f2 # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Merge rename: arch/arm/mach-ftvpci/core.c -> BitKeeper/deleted/.del-core.c~9e662b6895b788f2 # # BitKeeper/deleted/.del-core.c~714a718aec4a2c30 # 2004/06/20 18:27:07-07:00 dsaxena@omelas.(none) +0 -0 # Merge rename: arch/arm/mach-tbox/core.c -> BitKeeper/deleted/.del-core.c~714a718aec4a2c30 # # ChangeSet # 2004/06/20 17:40:34-07:00 akpm@osdl.org # [SPARC64]: bug.h needs compiler.h # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # include/asm-sparc64/bug.h # 2004/06/20 17:40:08-07:00 akpm@osdl.org +2 -0 # [SPARC64]: bug.h needs compiler.h # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/20 17:36:21-07:00 akepner@sgi.com # [NET]: Lockless loopback patch (version 2). # # net/sched/sch_generic.c # 2004/06/20 17:35:53-07:00 akepner@sgi.com +29 -14 # [NET]: Lockless loopback patch (version 2). # # net/sched/sch_api.c # 2004/06/20 17:35:53-07:00 akepner@sgi.com +3 -0 # [NET]: Lockless loopback patch (version 2). # # include/net/pkt_sched.h # 2004/06/20 17:35:52-07:00 akepner@sgi.com +2 -0 # [NET]: Lockless loopback patch (version 2). # # include/linux/netdevice.h # 2004/06/20 17:35:52-07:00 akepner@sgi.com +1 -0 # [NET]: Lockless loopback patch (version 2). # # drivers/net/loopback.c # 2004/06/20 17:35:52-07:00 akepner@sgi.com +33 -8 # [NET]: Lockless loopback patch (version 2). # # ChangeSet # 2004/06/20 17:06:07-07:00 davem@nuts.davemloft.net # Merge bk://kernel.bkbits.net/acme/net-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/ipv4/tcp.c # 2004/06/20 17:05:59-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/20 20:54:15-03:00 acme@conectiva.com.br # [NET] move tcp_memory_free to sk_stream_memory_free # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/20 20:54:04-03:00 acme@conectiva.com.br +5 -10 # [NET] move tcp_memory_free to sk_stream_memory_free # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/20 20:54:04-03:00 acme@conectiva.com.br +5 -0 # [NET] move tcp_memory_free to sk_stream_memory_free # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/20 16:38:03-07:00 davem@nuts.davemloft.net # Merge bk://kernel.bkbits.net/acme/net-2.6-1.1768 # into nuts.davemloft.net:/disk1/BK/acme-2.6 # # net/ipv6/udp.c # 2004/06/20 16:37:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/tcp_ipv6.c # 2004/06/20 16:37:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/raw.c # 2004/06/20 16:37:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/ndisc.c # 2004/06/20 16:37:54-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv6/mcast.c # 2004/06/20 16:37:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/tcp.c # 2004/06/20 16:37:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/06/20 16:37:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/skbuff.h # 2004/06/20 16:37:53-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/20 19:45:03-03:00 acme@conectiva.com.br # [NET] move skb_can_coalesce to skbuff.h # # This one also removes the duplicate can_coalesce in tcp.c and makes it # use skb_can_coalesce. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/20 19:44:45-03:00 acme@conectiva.com.br +2 -13 # [NET] move skb_can_coalesce to skbuff.h # # This one also removes the duplicate can_coalesce in tcp.c and makes it # use skb_can_coalesce. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/ip_output.c # 2004/06/20 19:44:45-03:00 acme@conectiva.com.br +0 -11 # [NET] move skb_can_coalesce to skbuff.h # # This one also removes the duplicate can_coalesce in tcp.c and makes it # use skb_can_coalesce. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/linux/skbuff.h # 2004/06/20 19:44:45-03:00 acme@conectiva.com.br +12 -0 # [NET] move skb_can_coalesce to skbuff.h # # This one also removes the duplicate can_coalesce in tcp.c and makes it # use skb_can_coalesce. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/20 14:18:46-07:00 hadi@zynx.com # [NET]: Fix module refcounting of TC actions. # # net/sched/sch_prio.c # 2004/06/20 14:18:14-07:00 hadi@zynx.com +2 -1 # [NET]: Fix module refcounting of TC actions. # # net/sched/police.c # 2004/06/20 14:18:14-07:00 hadi@zynx.com +15 -12 # [NET]: Fix module refcounting of TC actions. # # net/sched/cls_u32.c # 2004/06/20 14:18:14-07:00 hadi@zynx.com +12 -13 # [NET]: Fix module refcounting of TC actions. # # net/sched/act_api.c # 2004/06/20 14:18:14-07:00 hadi@zynx.com +54 -16 # [NET]: Fix module refcounting of TC actions. # # net/sched/Kconfig # 2004/06/20 14:18:14-07:00 hadi@zynx.com +8 -4 # [NET]: Fix module refcounting of TC actions. # # include/net/pkt_sched.h # 2004/06/20 14:18:14-07:00 hadi@zynx.com +10 -5 # [NET]: Fix module refcounting of TC actions. # # include/net/pkt_act.h # 2004/06/20 14:18:14-07:00 hadi@zynx.com +7 -7 # [NET]: Fix module refcounting of TC actions. # # include/linux/pkt_sched.h # 2004/06/20 14:18:14-07:00 hadi@zynx.com +6 -0 # [NET]: Fix module refcounting of TC actions. # # include/linux/pkt_cls.h # 2004/06/20 14:18:14-07:00 hadi@zynx.com +19 -8 # [NET]: Fix module refcounting of TC actions. # # ChangeSet # 2004/06/20 22:01:26+01:00 rmk@flint.arm.linux.org.uk # [PCMCIA] 05-nonbusy # # When allocating memory and IO resources, do not mark them busy. # This allows drivers themselves to claim and mark the regions busy, # as they are supposed to. # # drivers/pcmcia/rsrc_mgr.c # 2004/06/20 21:56:51+01:00 rmk@flint.arm.linux.org.uk +3 -3 # Don't mark PCMCIA resources busy. # # ChangeSet # 2004/06/20 21:53:25+01:00 rmk@flint.arm.linux.org.uk # [PCMCIA] 04-memres # # Make find_mem_region() return a struct resource. We preserve # pccard_mem_map's sys_start and sys_stop elements for the moment # since socket drivers are relying on this information for setting # up their windows. # # include/pcmcia/ss.h # 2004/06/20 21:51:20+01:00 rmk@flint.arm.linux.org.uk +1 -0 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/yenta_socket.c # 2004/06/20 21:51:20+01:00 rmk@flint.arm.linux.org.uk +2 -2 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/tcic.c # 2004/06/20 21:51:19+01:00 rmk@flint.arm.linux.org.uk +2 -2 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/rsrc_mgr.c # 2004/06/20 21:51:19+01:00 rmk@flint.arm.linux.org.uk +10 -8 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/pd6729.c # 2004/06/20 21:51:19+01:00 rmk@flint.arm.linux.org.uk +2 -2 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/i82365.c # 2004/06/20 21:51:19+01:00 rmk@flint.arm.linux.org.uk +2 -2 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/i82092.c # 2004/06/20 21:51:18+01:00 rmk@flint.arm.linux.org.uk +2 -2 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/cs_internal.h # 2004/06/20 21:51:18+01:00 rmk@flint.arm.linux.org.uk +1 -1 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/cs.c # 2004/06/20 21:51:18+01:00 rmk@flint.arm.linux.org.uk +19 -11 # Convert find_mem_region to return a struct resource. # # drivers/pcmcia/cistpl.c # 2004/06/20 21:51:18+01:00 rmk@flint.arm.linux.org.uk +13 -11 # Convert find_mem_region to return a struct resource. # # ChangeSet # 2004/06/20 12:32:43-07:00 davem@nuts.davemloft.net # [SPARC64]: Check _TIF_SYSCALL_SUCCESS before syscall return value. # # We might have to clear the flag, and if we do not # then subsequent syscalls can get confused. # # Bug easily triggered by suspending emacs in a pty # and then resuming, select() returns due to a pending # signal but because _TIF_SYSCALL_SUCCESS is erroneously # set by a previous syscall -514 ends up slipping into # userspace. Oops. # # arch/sparc64/kernel/entry.S # 2004/06/20 12:32:28-07:00 davem@nuts.davemloft.net +18 -16 # [SPARC64]: Check _TIF_SYSCALL_SUCCESS before syscall return value. # # We might have to clear the flag, and if we do not # then subsequent syscalls can get confused. # # Bug easily triggered by suspending emacs in a pty # and then resuming, select() returns due to a pending # signal but because _TIF_SYSCALL_SUCCESS is erroneously # set by a previous syscall -514 ends up slipping into # userspace. Oops. # # ChangeSet # 2004/06/20 10:39:30-07:00 geert@linux-m68k.org # [PATCH] m68k: I/O abstraction updates # # M68k I/O abstraction updates: # - Make I/O ports and addresses `unsigned long' # - Add casts to make operations warning-compatible with other archs # - Add {in,out}[wl]_p() and {in,out}l(), which are needed for some drivers # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # include/asm-m68k/io.h # 2004/04/12 04:56:00-07:00 geert@linux-m68k.org +32 -14 # m68k: I/O abstraction updates # # ChangeSet # 2004/06/20 10:39:19-07:00 geert@linux-m68k.org # [PATCH] m68k: atomic op fixups # # M68k: Add missing atomic operations (from Roman Zippel and me) and replace # `__inline__' by `inline' while we're at it. # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # include/asm-m68k/atomic.h # 2004/06/20 02:09:03-07:00 geert@linux-m68k.org +91 -7 # m68k: atomic op fixups # # ChangeSet # 2004/06/20 10:39:08-07:00 geert@linux-m68k.org # [PATCH] m68k: Mac IOP fix # # Mac IOP: Fix copy-and-paste bug (found by OPERA, reported by Zhenmin Li, # confirmed by Brad Boyer) # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # arch/m68k/mac/iop.c # 2004/05/26 05:49:09-07:00 geert@linux-m68k.org +1 -1 # m68k: Mac IOP fix # # ChangeSet # 2004/06/20 10:38:57-07:00 geert@linux-m68k.org # [PATCH] m68k: sparse infrastructure # # M68k: Make sparse work # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # arch/m68k/Makefile # 2004/06/20 01:49:05-07:00 geert@linux-m68k.org +2 -0 # m68k: sparse infrastructure # # ChangeSet # 2004/06/20 10:38:46-07:00 geert@linux-m68k.org # [PATCH] m68k: Mac Sonic Ethernet # # Mac Sonic Ethernet: Kill duplicate `MODULE_LICENSE("GPL");' (already defined in # included sonic.c) which causes a compile failure # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # drivers/net/macsonic.c # 2004/05/04 13:42:38-07:00 geert@linux-m68k.org +0 -1 # m68k: Mac Sonic Ethernet # # ChangeSet # 2004/06/20 10:38:35-07:00 geert@linux-m68k.org # [PATCH] affs remount fixes # # AFFS: Fix oops on write after remount (from Roman Zippel): # - Allocate/free bitmap as necessary # - Remove last uses of SF_READONLY # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # include/linux/affs_fs_sb.h # 2004/06/18 02:18:33-07:00 geert@linux-m68k.org +0 -1 # affs remount fixes # # include/linux/affs_fs.h # 2004/06/18 02:18:33-07:00 geert@linux-m68k.org +2 -1 # affs remount fixes # # fs/affs/super.c # 2004/06/18 02:17:49-07:00 geert@linux-m68k.org +12 -14 # affs remount fixes # # fs/affs/bitmap.c # 2004/06/18 02:17:49-07:00 geert@linux-m68k.org +21 -8 # affs remount fixes # # fs/affs/amigaffs.c # 2004/06/18 02:17:49-07:00 geert@linux-m68k.org +0 -1 # affs remount fixes # # ChangeSet # 2004/06/20 10:38:24-07:00 geert@linux-m68k.org # [PATCH] m68k: use set_page_count() # # M68k: From 2.6.7-rc1 on, it's no longer allowed to access page->count directly # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # arch/m68k/mm/memory.c # 2004/05/24 06:55:41-07:00 geert@linux-m68k.org +1 -1 # m68k: use set_page_count() # # ChangeSet # 2004/06/20 10:38:13-07:00 geert@linux-m68k.org # [PATCH] m68k: bus error handling # # M68k: Allow to catch a bus error via the exception mechanism (from Roman # Zippel) # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # arch/m68k/kernel/traps.c # 2004/05/23 01:55:54-07:00 geert@linux-m68k.org +4 -3 # m68k: bus error handling # # ChangeSet # 2004/06/20 10:38:02-07:00 geert@linux-m68k.org # [PATCH] m68k: new gcc optimizations # # M68k compiler updates from Roman Zippel: # - Fix various lvalue warnings from newer gcc # - Remove unnecessary volatile declarations # - Change some constraints from "a" to "m" to generate slightly better code # - Use "o" constraint for bitfield instructions # - Use generic bitmap functions for some of the ext2/minix bitmap functions # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # include/asm-m68k/string.h # 2004/05/23 01:56:37-07:00 geert@linux-m68k.org +8 -9 # m68k: new gcc optimizations # # include/asm-m68k/page.h # 2004/05/23 01:56:37-07:00 geert@linux-m68k.org +8 -10 # m68k: new gcc optimizations # # include/asm-m68k/bitops.h # 2004/05/23 10:50:20-07:00 geert@linux-m68k.org +54 -103 # m68k: new gcc optimizations # # include/asm-m68k/atomic.h # 2004/05/23 01:56:37-07:00 geert@linux-m68k.org +16 -12 # m68k: new gcc optimizations # # ChangeSet # 2004/06/20 10:37:51-07:00 geert@linux-m68k.org # [PATCH] m68k: handle new gcc's # # M68k: Fixes for when compiling with modern gcc (from Roman Zippel): # - Avoid warning 'use of memory input without lvalue in asm operand 0 is # deprecated' of newer gcc # - Replace some '%/' with offical '%%' to escape a '%' # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # include/asm-m68k/ucontext.h # 2004/05/23 01:56:37-07:00 geert@linux-m68k.org +2 -4 # m68k: handle new gcc's # # arch/m68k/kernel/signal.c # 2004/05/23 01:55:54-07:00 geert@linux-m68k.org +17 -17 # m68k: handle new gcc's # # ChangeSet # 2004/06/20 10:37:41-07:00 geert@linux-m68k.org # [PATCH] m68k: IFPSP060 update # # IFPSP060: Make sure that the destination address of a misaligned cas access is # properly mapped in, so the kernel won't oops in the emulation handler (from # Roman Zippel). # # Signed-off-by: Geert Uytterhoeven # Signed-off-by: Linus Torvalds # # arch/m68k/ifpsp060/iskeleton.S # 2004/05/23 01:55:54-07:00 geert@linux-m68k.org +47 -5 # m68k: IFPSP060 update # # ChangeSet # 2004/06/20 09:59:33-07:00 hirofumi@mail.parknet.co.jp # [PATCH] FAT: don't use "utf8" charset and NLS_DEFAULT # # Recently, some distributors have set "utf8" to NLS_DEFAULT, therefore, # FAT uses the "iocharset=utf8" as default. But, since "iocharset=utf8" # doesn't provide the function (lower <-> upper conversion) which FAT # needs, so FAT can't provide suitable behavior. # # This patch does: # # - doesn't recognize "utf8" as "iocharset" # - doesn't use NLS_DEFAULT as default "iocharset" # - instead of NLS_DEFAULT, adds FAT_DEFAULT_CODEPAGE and # FAT_DEFAULT_IOCHARSET # # NOTE: the following looks like buggy, so it's not recommended # # "codepage=437,iocharset=iso8859-1,utf8" # # however, some utf8 file name can handle. (in this case, it uses the # table of iso8859-1 for lower <-> upper conversion) # # # Sign-off-by: Jesse Barnes # Sign-off-by: OGAWA Hirofumi # Sign-off-by: Linus Torvalds # # fs/fat/inode.c # 2004/06/19 11:30:39-07:00 hirofumi@mail.parknet.co.jp +46 -42 # FAT: don't use "utf8" charset and NLS_DEFAULT # # fs/Kconfig # 2004/06/19 11:30:39-07:00 hirofumi@mail.parknet.co.jp +19 -0 # FAT: don't use "utf8" charset and NLS_DEFAULT # # ChangeSet # 2004/06/20 09:56:58-07:00 torvalds@ppc970.osdl.org # Follow 2.4.x semantics for in-kernel signal sending. # # kernel/signal.c # 2004/06/20 09:56:52-07:00 torvalds@ppc970.osdl.org +7 -0 # Follow 2.4.x semantics for in-kernel signal sending. # # ChangeSet # 2004/06/20 09:33:28-07:00 arjanv@redhat.com # [PATCH] fix amd64 boot breakage # # This fixes a bug that prevent my amd64 box from booting; # numa_default_policy was __init however it's called like this in # init/main.c: # # free_initmem(); # unlock_kernel(); # system_state = SYSTEM_RUNNING; # numa_default_policy(); # # # eg after free_initmem(). This resulted in it being reused/freed and that # gives a nasty oops. # # mm/mempolicy.c # 2004/06/20 02:29:33-07:00 arjanv@redhat.com +1 -1 # fix amd64 boot breakage # # ChangeSet # 2004/06/20 07:00:13-05:00 stevef@steveft21.ltcsamba # Do not kill cifsd thread until last smb session on tcp session is # SMBulogged off. Fixes umounting bug (pointed out by Nick Millington) # when multiple mounts with different userids are mounted to the same # server from the client. # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/connect.c # 2004/06/20 06:59:52-05:00 stevef@steveft21.ltcsamba +18 -10 # Do not kill cifsd thread until last smb session on tcp session is # SMBulogged off. # # fs/cifs/cifssmb.c # 2004/06/20 06:59:51-05:00 stevef@steveft21.ltcsamba +1 -0 # return unique error, when last smb session on a tcp session is logged off. # # fs/cifs/CHANGES # 2004/06/20 06:59:51-05:00 stevef@steveft21.ltcsamba +3 -0 # update cifs change log # # fs/cifs/AUTHORS # 2004/06/20 06:59:51-05:00 stevef@steveft21.ltcsamba +1 -1 # update list of contributors of bug reports # # ChangeSet # 2004/06/20 03:03:06-03:00 acme@toy.kerneljanitors.org # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/ip6_checksum.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +94 -0 # # net/ipv6/udp.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/tcp_ipv6.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/raw.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +2 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/ndisc.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/mcast.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/icmp.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_output.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +0 -64 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -48 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/netfilter/ipt_MASQUERADE.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/netfilter/ip_nat_standalone.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/netfilter/ip_fw_compat_redir.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/netfilter/ip_conntrack_standalone.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/skbuff.c # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +76 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +24 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/ip6_checksum.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +0 -0 # BitKeeper file /home/acme/bk/net-2.6/include/net/ip6_checksum.h # # include/net/ip.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/checksum.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +1 -69 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # include/linux/skbuff.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +24 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # include/linux/errqueue.h # 2004/06/20 03:02:54-03:00 acme@toy.kerneljanitors.org +4 -0 # [NET] generalise tcp_add_data, skb_split and tcp_copy_to_page # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/19 21:20:36-07:00 akpm@osdl.org # [NET]: Fix warning in farsync WAN driver. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/wan/farsync.c # 2004/06/19 21:20:21-07:00 akpm@osdl.org +1 -1 # [NET]: Fix warning in farsync WAN driver. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/19 16:47:14-07:00 yoshfuji@linux-ipv6.org # [ECONET]: Fix some warnings. # # net/econet/af_econet.c # 2004/06/19 16:46:52-07:00 yoshfuji@linux-ipv6.org +10 -4 # [ECONET]: Fix some warnings. # # ChangeSet # 2004/06/19 17:45:27-04:00 ralf@linux-mips.org # [PATCH] hdlcdrv needs to stop queueing # # We better stop the queue in the close call. # # Signed-off-by: Ralf Baechle # # drivers/net/hamradio/hdlcdrv.c # 2004/05/10 10:13:02-04:00 ralf@linux-mips.org +2 -0 # hdlcdrv needs to stop queueing # # ChangeSet # 2004/06/19 17:45:19-04:00 ralf@linux-mips.org # [PATCH] Cosmetic cleanups to sb1250-mac.c # # Signed-off-by: Ralf Baechle # # drivers/net/sb1250-mac.c # 2004/06/09 08:33:56-04:00 ralf@linux-mips.org +2 -2 # Cosmetic cleanups to sb1250-mac.c # # ChangeSet # 2004/06/19 17:45:10-04:00 ralf@linux-mips.org # [PATCH] Reformat # # Pure microcosmetic. # # Signed-off-by: Ralf Baechle # # drivers/net/tc35815.c # 2004/04/21 20:35:51-04:00 ralf@linux-mips.org +1 -1 # Reformat # # ChangeSet # 2004/06/19 17:45:01-04:00 ralf@linux-mips.org # [PATCH] Use netdev_priv in sgiseeq # # The combined allocation of of receive and transmit rings and driver data # so far made the use of netdev_priv impossible. Split the allocation # and use netdev_priv to access the non-ring driver_private data. # # Signed-off-by: Ralf Baechle # # drivers/net/sgiseeq.c # 2004/05/10 10:13:02-04:00 ralf@linux-mips.org +75 -70 # Use netdev_priv in sgiseeq # # ChangeSet # 2004/06/19 17:41:19-04:00 arjanv@redhat.com # [PATCH] sk98lin pci id # # drivers/net/sk98lin/h/skdrv2nd.h # 2004/06/18 20:00:00-04:00 arjanv@redhat.com +2 -1 # sk98lin pci id # # ChangeSet # 2004/06/19 17:36:14-04:00 ryan@michonline.com # [PATCH] orinoco.c rate limit lost information frame message # # Rate limit a (apparently) harmless warning in orinoco.c # # (My laptop remained connected with active X applications running over # ssh while this message was hitting every second, since I patched my # driver to include this the problem hasn't recurred.) # # Signed-Off-By: Ryan Anderson # # drivers/net/wireless/orinoco.c # 2004/06/13 17:20:20-04:00 ryan@michonline.com +2 -1 # orinoco.c rate limit lost information frame message # # ChangeSet # 2004/06/19 17:12:57-04:00 brazilnut@us.ibm.com # [PATCH] pcnet32: cleanup IRQ limitation. # # Cleanup pcnet32 IRQ handling based on suggestions from Ralf Baechle # , and Brian Murphy # # Tested by myself and Brian Murphy. # # Please also apply to 2.4.27-pre6. # # Signed-off-by: Don Fry # # drivers/net/pcnet32.c # 2004/06/17 09:14:53-04:00 brazilnut@us.ibm.com +12 -14 # pcnet32: cleanup IRQ limitation. # # ChangeSet # 2004/06/19 17:12:48-04:00 brazilnut@us.ibm.com # [PATCH] pcnet32: recover after rx hang. # # This patch fixes a receive hang that occasionally occurs after a Tx # FIFO underrun. The receive dma remains in a hung state sometimes. The # transmit operations continue to occur, but no receive activity. # # This was reproduced on several ppc64 systems and the fix has been verified # there. The patch has been tested as well on an ia32 system, which did # not experience the hang because it did not have fifo underruns, which is # a preqrequisite for the hang. The memory barriers decreased the frequency # of occurrence. The final change to reset the chip instead of just stopping # it eliminated the last hangs. # # Please also apply against 2.4.7 (with offset of -1), tested ia32. # # Signed-off by: brazilnut@us.ibm.com # # drivers/net/pcnet32.c # 2004/06/15 06:00:17-04:00 brazilnut@us.ibm.com +30 -10 # pcnet32: recover after rx hang. # # ChangeSet # 2004/06/19 17:12:39-04:00 brazilnut@us.ibm.com # [PATCH] pcnet32: discard oversize rx packets # # This patch will discard received frames that are larger than one buffer. # This has been tested on ia32 and ppc64 systems. # # Please also apply to 2.4.7 (with offset of -3), tested ia32. # # Signed-off by: brazilnut@us.ibm.com # # drivers/net/pcnet32.c # 2004/06/15 05:36:43-04:00 brazilnut@us.ibm.com +10 -3 # pcnet32: discard oversize rx packets # # ChangeSet # 2004/06/19 17:09:31-04:00 davem@redhat.com # [PATCH] hamachi DMA # # Let's get this thing not using bus_to_virt() anymore, # as follows. # # Signed-off-by: David S. Miller # # ===== drivers/net/hamachi.c 1.35 vs edited ===== # # drivers/net/hamachi.c # 2004/06/16 14:15:20-04:00 davem@redhat.com +1 -3 # hamachi DMA # # ChangeSet # 2004/06/19 17:08:21-04:00 fenlason@redhat.com # [PATCH] sunhme patch # # Without this patch, insmod-ing the sunhme module crashes on my fc2 # box. # # -- JF # # drivers/net/sunhme.c # 2004/06/16 20:29:23-04:00 fenlason@redhat.com +2 -1 # hme patch # # ChangeSet # 2004/06/19 17:07:34-04:00 jeb.j.cramer@intel.com # [PATCH] e1000 management reset fix # # * Resetting the adapter blew away management settings. So we save the # important bits before performing a reset. # # drivers/net/e1000/e1000_main.c # 2004/06/18 20:00:00-04:00 jeb.j.cramer@intel.com +9 -1 # e1000 management reset fix # # drivers/net/e1000/e1000_hw.h # 2004/06/18 20:00:00-04:00 jeb.j.cramer@intel.com +2 -0 # e1000 management reset fix # # drivers/net/e1000/e1000_hw.c # 2004/06/18 20:00:00-04:00 jeb.j.cramer@intel.com +35 -0 # e1000 management reset fix # # drivers/net/e1000/e1000.h # 2004/06/18 20:00:00-04:00 jeb.j.cramer@intel.com +1 -0 # e1000 management reset fix # # ChangeSet # 2004/06/19 17:07:25-04:00 shemminger@osdl.org # [PATCH] convert sk fddi driver to ANSI C # # Sparse does not handle K&R at all, and I think I saw Linus saying that # he has no intention of adding it to sparse while ago. So here is a blob # of patch to convert drivers/net/skfp/* from K&R to ANSI-C. Compile # tested with "make allmodconfig" on x86, as I obviously don't have the # HW. # # Mika # # Signed-off-by: Stephen Hemminger # # drivers/net/skfp/srf.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +11 -23 # convert sk fddi driver to ANSI C # # drivers/net/skfp/smttimer.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +9 -26 # convert sk fddi driver to ANSI C # # drivers/net/skfp/smtparse.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +9 -17 # convert sk fddi driver to ANSI C # # drivers/net/skfp/smtinit.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +5 -6 # convert sk fddi driver to ANSI C # # drivers/net/skfp/smtdef.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +10 -21 # convert sk fddi driver to ANSI C # # drivers/net/skfp/smt.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +142 -265 # convert sk fddi driver to ANSI C # # drivers/net/skfp/skfddi.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +2 -15 # convert sk fddi driver to ANSI C # # drivers/net/skfp/rmt.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +25 -45 # convert sk fddi driver to ANSI C # # drivers/net/skfp/queue.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +6 -18 # convert sk fddi driver to ANSI C # # drivers/net/skfp/pmf.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +24 -54 # convert sk fddi driver to ANSI C # # drivers/net/skfp/pcmplc.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +47 -117 # convert sk fddi driver to ANSI C # # drivers/net/skfp/lnkstat.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +5 -10 # convert sk fddi driver to ANSI C # # drivers/net/skfp/hwt.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +9 -18 # convert sk fddi driver to ANSI C # # drivers/net/skfp/hwmtm.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +99 -122 # convert sk fddi driver to ANSI C # # drivers/net/skfp/h/smtstate.h # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +6 -0 # convert sk fddi driver to ANSI C # # drivers/net/skfp/h/cmtdef.h # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +144 -178 # convert sk fddi driver to ANSI C # # drivers/net/skfp/fplustm.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +61 -129 # convert sk fddi driver to ANSI C # # drivers/net/skfp/ess.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +21 -41 # convert sk fddi driver to ANSI C # # drivers/net/skfp/ecm.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +11 -22 # convert sk fddi driver to ANSI C # # drivers/net/skfp/drvfbi.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +49 -132 # convert sk fddi driver to ANSI C # # drivers/net/skfp/cfm.c # 2004/06/17 17:49:49-04:00 shemminger@osdl.org +10 -25 # convert sk fddi driver to ANSI C # # ChangeSet # 2004/06/19 17:06:09-04:00 akpm@osdl.org # [PATCH] H8/300: smc9194 driver # # From: Yoshinori Sato # # - H8/300 target support # - fixed irq support # - high address (>0xffff) i/o fix # # Signed-off-by: Andrew Morton # # drivers/net/smc9194.c # 2004/06/18 01:19:59-04:00 akpm@osdl.org +65 -9 # H8/300: smc9194 driver # # ChangeSet # 2004/06/19 17:04:50-04:00 herbert@gondor.apana.org.au # [PATCH] Re: linux-2.6.7 Equalizer Load-balancer. eql.c. local non-privileged DoS # # Vitaly V. Bursov wrote: # > # > there are multiple vulns in drivers/net/eql.c # > # > if there is no such device, dev_get_by_name returns NULL and everything dies. # > Exploiting this is trivial. # # Thanks for the report. This patch should fix them. # # Signed-off-by: Herbert Xu # # Cheers, # -- # Visit Openswan at http://www.openswan.org/ # Email: Herbert Xu ~{PmV>HI~} # Home Page: http://gondor.apana.org.au/~herbert/ # PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt # -- # ===== drivers/net/eql.c 1.13 vs edited ===== # # drivers/net/eql.c # 2004/06/18 07:30:49-04:00 herbert@gondor.apana.org.au +4 -0 # Re: linux-2.6.7 Equalizer Load-balancer. eql.c. local non-privileged DoS # # ChangeSet # 2004/06/19 17:00:28-04:00 achirica@telefonica.net # [wireless airo] Clean initialization of Mini-PCI cards even from suspend # # drivers/net/wireless/airo.c # 2004/06/18 16:56:26-04:00 achirica@telefonica.net +28 -12 # Clean initialization of Mini-PCI cards even from suspend # # ChangeSet # 2004/06/19 21:26:48+01:00 rmk@flint.arm.linux.org.uk # [PCMCIA] 03-memwin # # Eliminate win->base and win->size elements from window_t. # window_t contains struct pccard_mem_map, which contains a # copy of these (sys_start, sys_stop) in a slightly different # form. # # include/pcmcia/ss.h # 2004/06/19 21:24:14+01:00 rmk@flint.arm.linux.org.uk +0 -2 # Eliminate win->base and win->size elements from window_t. # # drivers/pcmcia/cs.c # 2004/06/19 21:24:13+01:00 rmk@flint.arm.linux.org.uk +4 -6 # Eliminate win->base and win->size elements from window_t. # # ChangeSet # 2004/06/19 21:17:11+01:00 rmk@flint.arm.linux.org.uk # [PCMCIA] 02-validatemem # # Move validate_mem() so we don't recurse. We call this function from # the DS_GET_FIRST_TUPLE and DS_VALIDATE_CIS calls, which are the the # first two functions which may be called by cardmgr or cardctl which # require CIS access. # # drivers/pcmcia/rsrc_mgr.c # 2004/06/19 21:14:36+01:00 rmk@flint.arm.linux.org.uk +15 -6 # Create pcmcia_validate_mem() which only validates memory when the # module parameters allow, and a card has been inserted. # # drivers/pcmcia/ds.c # 2004/06/19 21:14:35+01:00 rmk@flint.arm.linux.org.uk +2 -0 # Add pcmcia_validate_mem() to DS_GET_FIRST_TUPLE and DS_VALIDATE_CIS. # # drivers/pcmcia/cs_internal.h # 2004/06/19 21:14:35+01:00 rmk@flint.arm.linux.org.uk +1 -1 # New function pcmcia_validate_mem() replaces validate_mem() # # drivers/pcmcia/cistpl.c # 2004/06/19 21:14:35+01:00 rmk@flint.arm.linux.org.uk +0 -1 # Remove validate_mem() to prevent recursion. # # ChangeSet # 2004/06/19 12:48:23-07:00 davem@nuts.davemloft.net # [IPV6]: Export necessary xfrm6_tunnel functions. # # net/ipv6/xfrm6_tunnel.c # 2004/06/19 12:48:05-07:00 davem@nuts.davemloft.net +11 -0 # [IPV6]: Export necessary xfrm6_tunnel functions. # # ChangeSet # 2004/06/19 11:55:24-07:00 yoshfuji@linux-ipv6.org # [NET]: Fix some userland header bustage. # # include/linux/netfilter_ipv6/ip6_tables.h # 2004/06/19 11:55:10-07:00 yoshfuji@linux-ipv6.org +3 -0 # [NET]: Fix some userland header bustage. # # include/linux/netfilter_ipv4/ip_tables.h # 2004/06/19 11:55:10-07:00 yoshfuji@linux-ipv6.org +2 -1 # [NET]: Fix some userland header bustage. # # include/linux/netfilter_arp/arp_tables.h # 2004/06/19 11:55:10-07:00 yoshfuji@linux-ipv6.org +1 -1 # [NET]: Fix some userland header bustage. # # include/linux/netfilter.h # 2004/06/19 11:55:10-07:00 yoshfuji@linux-ipv6.org +1 -0 # [NET]: Fix some userland header bustage. # # ChangeSet # 2004/06/19 11:36:58-07:00 akpm@osdl.org # [NET]: Fix econet build bustage. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/econet/af_econet.c # 2004/06/19 11:36:43-07:00 akpm@osdl.org +2 -2 # [NET]: Fix econet build bustage. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/19 18:20:47+01:00 dwmw2@dwmw2.baythorne.internal # Merge # # include/asm-ppc/ppcboot.h # 2004/06/19 18:20:42+01:00 dwmw2@dwmw2.baythorne.internal +1 -2 # SCCS merged # # arch/ppc/Kconfig # 2004/06/19 18:20:06+01:00 dwmw2@dwmw2.baythorne.internal +3 -5 # SCCS merged # # include/linux/serial_core.h # 2004/06/19 18:17:05+01:00 dwmw2@dwmw2.baythorne.internal +0 -0 # Auto merged # # drivers/serial/Makefile # 2004/06/19 18:17:05+01:00 dwmw2@dwmw2.baythorne.internal +0 -0 # Auto merged # # drivers/serial/Kconfig # 2004/06/19 18:17:05+01:00 dwmw2@dwmw2.baythorne.internal +0 -0 # Auto merged # # arch/ppc/syslib/Makefile # 2004/06/19 18:17:05+01:00 dwmw2@dwmw2.baythorne.internal +0 -0 # Auto merged # # arch/ppc/Makefile # 2004/06/19 18:17:05+01:00 dwmw2@dwmw2.baythorne.internal +0 -0 # Auto merged # # ChangeSet # 2004/06/19 18:12:59+01:00 rmk@flint.arm.linux.org.uk # [PCMCIA] Add Cirrus PD6729 PCMCIA bridge support. # # Patch from Komuro, cleaned up by Russell King. # # drivers/pcmcia/pd6729.h # 2004/06/19 18:10:40+01:00 rmk@flint.arm.linux.org.uk +28 -0 # # drivers/pcmcia/pd6729.h # 2004/06/19 18:10:40+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-pcmcia/drivers/pcmcia/pd6729.h # # drivers/pcmcia/pd6729.c # 2004/06/19 18:10:25+01:00 rmk@flint.arm.linux.org.uk +732 -0 # # drivers/pcmcia/pd6729.c # 2004/06/19 18:10:25+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-pcmcia/drivers/pcmcia/pd6729.c # # drivers/pcmcia/Makefile # 2004/06/19 18:10:25+01:00 rmk@flint.arm.linux.org.uk +1 -0 # Add Cirrus PD6729 support. # # drivers/pcmcia/Kconfig # 2004/06/19 18:10:24+01:00 rmk@flint.arm.linux.org.uk +7 -0 # Add Cirrus PD6729 support. # # ChangeSet # 2004/06/19 07:50:55-07:00 mikulas@artax.karlin.mff.cuni.cz # [PATCH] HPFS fixes for 2.6.7 kernel # # This contains hpfs fixes from my source ported to 2.6.7 kernel: # # updates: # - allocator fragments files less # - OS/2 Warp Server filesystem can be mounted read/only # - added reschedule points so that it doesn't hog CPU # # bug fixes: # - filesystem error message when syncing or fsyncing deleted file (or when # system just writes it on its own) # - filesystem error on extremly fragmented files # - corrupted disk structures could possibly corrupt memory # # fs/hpfs/super.c # 2004/06/18 18:13:55-07:00 mikulas@artax.karlin.mff.cuni.cz +1 -0 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/map.c # 2004/06/18 18:09:05-07:00 mikulas@artax.karlin.mff.cuni.cz +4 -2 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/inode.c # 2004/06/18 18:13:20-07:00 mikulas@artax.karlin.mff.cuni.cz +9 -7 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/hpfs_fn.h # 2004/06/18 18:01:00-07:00 mikulas@artax.karlin.mff.cuni.cz +3 -2 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/hpfs.h # 2004/06/18 17:58:08-07:00 mikulas@artax.karlin.mff.cuni.cz +1 -1 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/ea.c # 2004/06/18 17:57:50-07:00 mikulas@artax.karlin.mff.cuni.cz +3 -5 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/buffer.c # 2004/06/18 17:55:53-07:00 mikulas@artax.karlin.mff.cuni.cz +8 -0 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/anode.c # 2004/06/18 17:49:38-07:00 mikulas@artax.karlin.mff.cuni.cz +1 -2 # HPFS fixes for 2.6.7 kernel # # fs/hpfs/alloc.c # 2004/06/18 18:44:32-07:00 mikulas@artax.karlin.mff.cuni.cz +44 -26 # HPFS fixes for 2.6.7 kernel # # Documentation/filesystems/hpfs.txt # 2004/06/18 18:17:43-07:00 mikulas@artax.karlin.mff.cuni.cz +10 -2 # HPFS fixes for 2.6.7 kernel # # ChangeSet # 2004/06/19 07:50:44-07:00 akpm@osdl.org # [PATCH] mptctl.c build fix # # drivers/message/fusion/mptctl.c:89:24: asm/compat.h: No such file or directory # # Signed-off-by: Andrew Morton # # drivers/message/fusion/mptctl.c # 2004/06/19 00:22:47-07:00 akpm@osdl.org +1 -1 # mptctl.c build fix # # ChangeSet # 2004/06/19 07:49:02-07:00 torvalds@ppc970.osdl.org # Merge http://lia64.bkbits.net/to-linus-2.5 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # include/asm-ia64/pgtable.h # 2004/06/19 07:48:59-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # arch/ia64/kernel/iosapic.c # 2004/06/19 07:48:59-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # arch/ia64/ia32/ia32_entry.S # 2004/06/19 07:48:59-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/18 21:52:08-07:00 yanmin.zhang@intel.com # [PATCH] ia64: fix free_huge_page() call in hugetlb_prefault() # # In base kernel 2.6.7, there is bug in function hugetlb_prefault(). The # call to free_huge_page() is incorrect and should be replaced with a call # to page_cache_release(). # # Signed-off-by: David Mosberger # # arch/ia64/mm/hugetlbpage.c # 2004/06/18 00:26:02-07:00 yanmin.zhang@intel.com +1 -1 # ia64: fix free_huge_page() call in hugetlb_prefault() # # ChangeSet # 2004/06/18 21:49:12-07:00 eranian@hpl.hp.com # [PATCH] ia64: perfmon stack consumption fix # # This patch moves the pfm_ovfl_arg_t structure from the kernel stack # into the pfm_context_t structure. This minimizes kernel stack space # consumption. # # Signed-off-by: Stephane Eranian # Signed-off-by: David Mosberger # # arch/ia64/kernel/perfmon.c # 2004/06/18 09:17:04-07:00 eranian@hpl.hp.com +20 -18 # ia64: perfmon stack consumption fix # # ChangeSet # 2004/06/18 21:45:35-07:00 ashok.raj@intel.com # [PATCH] ia64: move move_irq() from iosapic.c to irq.c # # This patch moves move_irq() from ioaspic.c to irq.c to make this common # for ia64 subarches. # # Signed-off-by: Ashok Raj # Signed-off-by: David Mosberger # # include/asm-ia64/irq.h # 2004/06/18 15:22:57-07:00 ashok.raj@intel.com +6 -0 # ia64: move move_irq() from iosapic.c to irq.c # # arch/ia64/kernel/irq.c # 2004/06/18 15:22:57-07:00 ashok.raj@intel.com +16 -0 # ia64: move move_irq() from iosapic.c to irq.c # # arch/ia64/kernel/iosapic.c # 2004/06/18 15:22:57-07:00 ashok.raj@intel.com +0 -16 # ia64: move move_irq() from iosapic.c to irq.c # # ChangeSet # 2004/06/18 21:42:42-07:00 arun.sharma@intel.com # [PATCH] ia64: fix ia32 partial-page map support for overlapping mmaps # # - Handle the overlapping mmaps in the MAP_FIXED case # - Handle unmaps correctly i.e. call __ia32_delete_pp_range() # - There are now three clear entry points into the pp manipulation code # - ia32_set_pp # - ia32_unset_pp # - ia32_compare_pp # - Rename internal functions to __ia32_*pp_* # - Grab mmap_sem just once at the main entry point # # Signed-off-by: Gordon Jin # Signed-off-by: Arun Sharma # Signed-off-by: David Mosberger # # arch/ia64/ia32/sys_ia32.c # 2004/06/18 04:55:20-07:00 arun.sharma@intel.com +184 -134 # ia64: fix ia32 partial-page map support for overlapping mmaps # # ChangeSet # 2004/06/18 23:02:41-05:00 stevef@smfhome1.smfdom # check better for free files on writepage retry # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/file.c # 2004/06/18 23:02:34-05:00 stevef@smfhome1.smfdom +21 -7 # check better for free files on writepage retry # # ChangeSet # 2004/06/18 22:01:37-05:00 stevef@smfhome1.smfdom # Do not send junk in bcc area of oplock break SMB Lock request, and always let oplock break release # through even if requests are ahead of it waiting for responses to complete. # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/transport.c # 2004/06/18 22:01:30-05:00 stevef@smfhome1.smfdom +20 -15 # do not count oplock breaks against in flight count # # fs/cifs/connect.c # 2004/06/18 22:01:30-05:00 stevef@smfhome1.smfdom +1 -1 # do not reset inFlight count on reconnection so it does not go negative # # fs/cifs/cifssmb.c # 2004/06/18 22:01:30-05:00 stevef@smfhome1.smfdom +14 -8 # Do not send junk in bcc area of oplock break SMB Lock request # # fs/cifs/CHANGES # 2004/06/18 22:01:30-05:00 stevef@smfhome1.smfdom +2 -1 # update cifs vfs change log for 1.19 # # ChangeSet # 2004/06/18 18:26:37-07:00 rddunlap@osdl.org # [PATCH] sparse: lib/string.c sparse fix # # A classic.. # # lib/string.c:165:19: warning: assignment expression in conditional # # From: Mika Kukkonen # Signed-off-by: Randy Dunlap # # lib/string.c # 2004/06/09 12:58:48-07:00 rddunlap@osdl.org +1 -1 # sparse: lib/string.c sparse fix # # ChangeSet # 2004/06/18 18:26:26-07:00 rddunlap@osdl.org # [PATCH] sparse: kernel/module.c sparse fix # # Add __user annotation for !CONFIG_MODULE_UNLOAD case. # # From: Mika Kukkonen # Signed-off-by: Randy Dunlap # # kernel/module.c # 2004/06/09 13:11:44-07:00 rddunlap@osdl.org +1 -1 # sparse: kernel/module.c sparse fix # # ChangeSet # 2004/06/18 16:46:25-07:00 viro@www.linux.org.uk # [PATCH] sparse: drivers/video/sis annotation # # drivers/video/sis/sis_main.c # 2004/06/18 09:43:52-07:00 viro@www.linux.org.uk +16 -15 # sparse: drivers/video/sis annotation # # ChangeSet # 2004/06/18 16:37:47-07:00 viro@www.linux.org.uk # [PATCH] sparse: drivers/video/aty annotation # # drivers/video/aty/radeon_base.c # 2004/06/18 09:36:48-07:00 viro@www.linux.org.uk +4 -4 # sparse: drivers/video/aty annotation # # ChangeSet # 2004/06/18 16:35:56-07:00 torvalds@ppc970.osdl.org # Merge ppc970.osdl.org:/home/torvalds/v2.6/v2.6.7 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # include/linux/ipmi.h # 2004/06/18 16:35:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # include/linux/fb.h # 2004/06/18 16:35:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # fs/binfmt_aout.c # 2004/06/18 16:35:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/video/fbmem.c # 2004/06/18 16:35:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/char/ipmi/ipmi_watchdog.c # 2004/06/18 16:35:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/char/ipmi/ipmi_devintf.c # 2004/06/18 16:35:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/18 16:35:04-07:00 viro@www.linux.org.uk # [PATCH] sparse: autofs annotation # # fs/autofs/root.c # 2004/06/18 11:14:07-07:00 viro@www.linux.org.uk +7 -6 # sparse: autofs annotation # # ChangeSet # 2004/06/18 16:34:54-07:00 viro@www.linux.org.uk # [PATCH] sparse: synclinkmp annotation # # drivers/char/synclinkmp.c # 2004/06/18 11:19:11-07:00 viro@www.linux.org.uk +22 -21 # sparse: synclinkmp annotation # # ChangeSet # 2004/06/18 16:34:45-07:00 viro@www.linux.org.uk # [PATCH] sparse: cyclades annotation # # drivers/char/cyclades.c # 2004/06/18 11:16:10-07:00 viro@www.linux.org.uk +29 -30 # sparse: cyclades annotation # # ChangeSet # 2004/06/18 16:34:35-07:00 viro@www.linux.org.uk # [PATCH] sparse: ipmi annotation # # include/linux/ipmi.h # 2004/06/18 11:18:12-07:00 viro@www.linux.org.uk +2 -2 # sparse: ipmi annotation # # drivers/char/ipmi/ipmi_watchdog.c # 2004/06/18 11:18:46-07:00 viro@www.linux.org.uk +10 -13 # sparse: ipmi annotation # # drivers/char/ipmi/ipmi_devintf.c # 2004/06/18 11:18:33-07:00 viro@www.linux.org.uk +14 -13 # sparse: ipmi annotation # # ChangeSet # 2004/06/18 16:34:24-07:00 viro@www.linux.org.uk # [PATCH] sparse: amd64 bits # # - added define of __x86_64__ to sparse arguments on amd64 # - switched amd64 uaccess.h to __chk_user_ptr() # # include/asm-x86_64/uaccess.h # 2004/06/18 11:15:18-07:00 viro@www.linux.org.uk +34 -44 # sparse: amd64 bits # # arch/x86_64/Makefile # 2004/06/18 11:15:02-07:00 viro@www.linux.org.uk +2 -0 # sparse: amd64 bits # # ChangeSet # 2004/06/18 16:34:14-07:00 viro@www.linux.org.uk # [PATCH] sparse: applicom annotation # # drivers/char/applicom.c # 2004/06/18 11:19:50-07:00 viro@www.linux.org.uk +10 -9 # sparse: applicom annotation # # ChangeSet # 2004/06/18 16:34:03-07:00 viro@www.linux.org.uk # [PATCH] sparse: udf cleanups # # removed bogus externs from declarations in fs/udf/* # # fs/udf/misc.c # 2004/06/18 11:12:57-07:00 viro@www.linux.org.uk +6 -6 # sparse: udf cleanups # # fs/udf/crc.c # 2004/06/18 11:12:52-07:00 viro@www.linux.org.uk +1 -1 # sparse: udf cleanups # # ChangeSet # 2004/06/18 16:33:52-07:00 viro@www.linux.org.uk # [PATCH] sparse: drivers/video/matrox annotation # # drivers/video/matrox/matroxfb_crtc2.c # 2004/06/18 11:08:45-07:00 viro@www.linux.org.uk +5 -5 # sparse: drivers/video/matrox annotation # # drivers/video/matrox/matroxfb_base.c # 2004/06/18 11:08:34-07:00 viro@www.linux.org.uk +16 -15 # sparse: drivers/video/matrox annotation # # ChangeSet # 2004/06/18 16:33:41-07:00 viro@www.linux.org.uk # [PATCH] sparse: drivers/video/kyro annotation # # drivers/video/kyro/fbdev.c # 2004/06/18 11:07:54-07:00 viro@www.linux.org.uk +6 -6 # sparse: drivers/video/kyro annotation # # ChangeSet # 2004/06/18 16:33:31-07:00 viro@www.linux.org.uk # [PATCH] sparse: drivers/video partial annotation # # misc annotation in drivers/video/* (nowhere near complete) # # include/linux/fb.h # 2004/06/18 11:11:09-07:00 viro@www.linux.org.uk +2 -2 # sparse: drivers/video partial annotation # # drivers/video/sstfb.c # 2004/06/18 11:10:17-07:00 viro@www.linux.org.uk +2 -2 # sparse: drivers/video partial annotation # # drivers/video/radeonfb.c # 2004/06/18 11:10:06-07:00 viro@www.linux.org.uk +2 -2 # sparse: drivers/video partial annotation # # drivers/video/imsttfb.c # 2004/06/18 11:10:31-07:00 viro@www.linux.org.uk +10 -9 # sparse: drivers/video partial annotation # # drivers/video/fbmem.c # 2004/06/18 11:10:53-07:00 viro@www.linux.org.uk +2 -2 # sparse: drivers/video partial annotation # # ChangeSet # 2004/06/18 16:33:20-07:00 viro@www.linux.org.uk # [PATCH] sparse: nfs partial annotation # # include/linux/nfs4_mount.h # 2004/06/18 11:11:45-07:00 viro@www.linux.org.uk +3 -3 # sparse: nfs partial annotation # # fs/nfs/idmap.c # 2004/06/18 11:12:29-07:00 viro@www.linux.org.uk +6 -5 # sparse: nfs partial annotation # # fs/nfs/direct.c # 2004/06/18 11:12:14-07:00 viro@www.linux.org.uk +1 -1 # sparse: nfs partial annotation # # ChangeSet # 2004/06/18 16:33:09-07:00 viro@www.linux.org.uk # [PATCH] sparse: mwave annotation # # drivers/char/mwave/tp3780i.h # 2004/06/18 11:17:27-07:00 viro@www.linux.org.uk +2 -2 # sparse: mwave annotation # # drivers/char/mwave/tp3780i.c # 2004/06/18 11:17:27-07:00 viro@www.linux.org.uk +2 -2 # sparse: mwave annotation # # drivers/char/mwave/mwavedd.c # 2004/06/18 11:17:27-07:00 viro@www.linux.org.uk +17 -20 # sparse: mwave annotation # # drivers/char/mwave/3780i.h # 2004/06/18 11:17:27-07:00 viro@www.linux.org.uk +5 -5 # sparse: mwave annotation # # drivers/char/mwave/3780i.c # 2004/06/18 11:17:27-07:00 viro@www.linux.org.uk +10 -10 # sparse: mwave annotation # # ChangeSet # 2004/06/18 16:32:59-07:00 viro@www.linux.org.uk # [PATCH] sparse: binfmt_aout annotation # # fs/binfmt_aout.c # 2004/06/18 11:13:43-07:00 viro@www.linux.org.uk +13 -12 # sparse: binfmt_aout annotation # # ChangeSet # 2004/06/18 14:14:17-07:00 akpm@osdl.org # [NET]: Fix eql.c failed dev_get_by_name() return value check. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/eql.c # 2004/06/18 14:14:03-07:00 akpm@osdl.org +5 -1 # [NET]: Fix eql.c failed dev_get_by_name() return value check. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/18 14:12:29-07:00 yoshfuji@linux-ipv6.org # [IPV6]: Fix autoconf description in ip-sysctl.txt. # # Documentation/networking/ip-sysctl.txt # 2004/06/18 14:12:15-07:00 yoshfuji@linux-ipv6.org +4 -2 # [IPV6]: Fix autoconf description in ip-sysctl.txt. # # ChangeSet # 2004/06/18 14:11:36-07:00 wli@holomorphy.com # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/irda/irda_device.c # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +2 -2 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # include/net/irda/irda_device.h # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +3 -1 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/w83977af_ir.h # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +3 -0 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/w83977af_ir.c # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +19 -12 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/via-ircc.h # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +3 -0 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/via-ircc.c # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +18 -10 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/smsc-ircc2.c # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +20 -11 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/nsc-ircc.h # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +3 -0 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/nsc-ircc.c # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +19 -11 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/ali-ircc.h # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +3 -0 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # drivers/net/irda/ali-ircc.c # 2004/06/18 14:11:22-07:00 wli@holomorphy.com +19 -11 # [IRDA]: Remove usage of isa_virt_to_bus() # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/18 14:09:17-07:00 dlstevens@us.ibm.com # [IPV6]: Handle user asking for any device in mcast calls. # # net/ipv6/mcast.c # 2004/06/18 14:09:03-07:00 dlstevens@us.ibm.com +1 -1 # [IPV6]: Handle user asking for any device in mcast calls. # # ChangeSet # 2004/06/18 13:54:52-07:00 shemminger@osdl.org # [PKT_SCHED]: Add loss option to network delay scheduler. # # This enhances the network simulation scheduler to do simple random loss. # # The loss parameter is a simple 32 bit value such that 0 means no loss, and # 0xffffffff is always drop. I have a new version of the tc command which takes # care of conversion from percent to this value. # # Same patch for 2.4 and 2.6 # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/sched/sch_delay.c # 2004/06/18 13:54:39-07:00 shemminger@osdl.org +9 -0 # [PKT_SCHED]: Add loss option to network delay scheduler. # # This enhances the network simulation scheduler to do simple random loss. # # The loss parameter is a simple 32 bit value such that 0 means no loss, and # 0xffffffff is always drop. I have a new version of the tc command which takes # care of conversion from percent to this value. # # Same patch for 2.4 and 2.6 # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # include/linux/pkt_sched.h # 2004/06/18 13:54:39-07:00 shemminger@osdl.org +2 -1 # [PKT_SCHED]: Add loss option to network delay scheduler. # # This enhances the network simulation scheduler to do simple random loss. # # The loss parameter is a simple 32 bit value such that 0 means no loss, and # 0xffffffff is always drop. I have a new version of the tc command which takes # care of conversion from percent to this value. # # Same patch for 2.4 and 2.6 # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/18 13:51:42-07:00 davem@nuts.davemloft.net # [PKT_SCHED]: Do not check netif_queue_stopped() in dequeue ops, races with driver. # # Based upon a patch from Stephen Hemminger. # Signed-off-by: David S. Miller # # net/sched/sch_tbf.c # 2004/06/18 13:51:18-07:00 davem@nuts.davemloft.net +5 -7 # [PKT_SCHED]: Do not check netif_queue_stopped() in dequeue ops, races with driver. # # Based upon a patch from Stephen Hemminger. # # Signed-off-by: David S. Miller # # net/sched/sch_htb.c # 2004/06/18 13:51:18-07:00 davem@nuts.davemloft.net +0 -1 # [PKT_SCHED]: Do not check netif_queue_stopped() in dequeue ops, races with driver. # # Based upon a patch from Stephen Hemminger. # # Signed-off-by: David S. Miller # # net/sched/sch_hfsc.c # 2004/06/18 13:51:18-07:00 davem@nuts.davemloft.net +1 -2 # [PKT_SCHED]: Do not check netif_queue_stopped() in dequeue ops, races with driver. # # Based upon a patch from Stephen Hemminger. # # Signed-off-by: David S. Miller # # net/sched/sch_delay.c # 2004/06/18 13:51:18-07:00 davem@nuts.davemloft.net +5 -7 # [PKT_SCHED]: Do not check netif_queue_stopped() in dequeue ops, races with driver. # # Based upon a patch from Stephen Hemminger. # # Signed-off-by: David S. Miller # # net/sched/sch_cbq.c # 2004/06/18 13:51:18-07:00 davem@nuts.davemloft.net +1 -1 # [PKT_SCHED]: Do not check netif_queue_stopped() in dequeue ops, races with driver. # # Based upon a patch from Stephen Hemminger. # # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/18 13:50:35-07:00 torvalds@ppc970.osdl.org # sparse: fix up fusion/mptctl.c after merge # # drivers/message/fusion/mptctl.c # 2004/06/18 13:50:29-07:00 torvalds@ppc970.osdl.org +8 -7 # sparse: fix up fusion/mptctl.c after merge # # ChangeSet # 2004/06/18 13:46:11-07:00 torvalds@ppc970.osdl.org # Merge # # drivers/message/fusion/mptctl.c # 2004/06/18 13:46:06-07:00 torvalds@ppc970.osdl.org +0 -2 # Merge # # drivers/scsi/scsi_syms.c # 2004/06/18 13:44:28-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/scsi_ioctl.c # 2004/06/18 13:44:28-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/fdomain.c # 2004/06/18 13:44:28-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/fd_mcs.c # 2004/06/18 13:44:28-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/18 13:43:51-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: drivers/message/fusion annotations and fixes # # Sigh... First of all, LSI folks have very quaint idea of existing # platforms and word sizes on those. Their definitions of U32 and S32 # should really be reserved for posterity (preferably chiseled into the # rock they have between the ears), but kernel is the wrong place for # that. Fixed. # # mptctl_do_mpt_command() was always called on userland pointers; # kernel/userland argument removed along with dead code, function # annotated, callers updated. # # The rest is trivial annotations in mptctl.c and in its ioctl structures # - nothing fancy there. # # drivers/message/fusion/mptctl.h # 2004/06/18 08:09:14-07:00 viro@parcelfarce.linux.theplanet.co.uk +5 -5 # sparse: drivers/message/fusion annotations and fixes # # drivers/message/fusion/mptctl.c # 2004/06/18 08:09:16-07:00 viro@parcelfarce.linux.theplanet.co.uk +68 -77 # sparse: drivers/message/fusion annotations and fixes # # drivers/message/fusion/lsi/mpi_type.h # 2004/06/18 08:09:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +6 -11 # sparse: drivers/message/fusion annotations and fixes # # ChangeSet # 2004/06/18 13:43:40-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] crapectomy - last users of kernel_scsi_ioctl() gone # # Last 3 users of kernel_scsi_ioctl() eliminated; two of them used to read # partition table by issuing a READ6 via ioctl (instead of just calling # scsi_bios_ptable() as every other ->biosparam() instance does). # # The last one was doing a very quaint access to fields of scsi_device by # issuing SCSI_IOCLT_GET_LUN and then shuffling bits in the result. Down # with that insanity... # # ChangeSet # 2004/06/18 13:40:49-07:00 shemminger@osdl.org # [PKT_SCHED]: Delay scheduler should retry if requeue fails. # # If delay scheduler decides not to send the packet right away, it requeues # it. If the requeue fails, it should go and look again rather than waking # up prematurely. # # Same patch should apply to both 2.6 and 2.4 # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/sched/sch_delay.c # 2004/06/18 13:40:35-07:00 shemminger@osdl.org +9 -5 # [PKT_SCHED]: Delay scheduler should retry if requeue fails. # # If delay scheduler decides not to send the packet right away, it requeues # it. If the requeue fails, it should go and look again rather than waking # up prematurely. # # Same patch should apply to both 2.6 and 2.4 # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # include/scsi/scsi_ioctl.h # 2004/06/18 07:38:19-07:00 viro@parcelfarce.linux.theplanet.co.uk +0 -1 # crapectomy - last users of kernel_scsi_ioctl() gone # # drivers/scsi/scsi_syms.c # 2004/06/18 07:36:48-07:00 viro@parcelfarce.linux.theplanet.co.uk +0 -1 # crapectomy - last users of kernel_scsi_ioctl() gone # # drivers/scsi/scsi_ioctl.c # 2004/06/18 07:36:38-07:00 viro@parcelfarce.linux.theplanet.co.uk +0 -16 # crapectomy - last users of kernel_scsi_ioctl() gone # # drivers/scsi/pcmcia/nsp_cs.c # 2004/06/18 07:37:49-07:00 viro@parcelfarce.linux.theplanet.co.uk +4 -4 # crapectomy - last users of kernel_scsi_ioctl() gone # # drivers/scsi/fdomain.c # 2004/06/18 07:37:05-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -16 # crapectomy - last users of kernel_scsi_ioctl() gone # # drivers/scsi/fd_mcs.c # 2004/06/18 07:37:16-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -14 # crapectomy - last users of kernel_scsi_ioctl() gone # # ChangeSet # 2004/06/18 13:37:04-07:00 rmk+lkml@arm.linux.org.uk # [PATCH] Couple of sysfs patches # # On Wed, Jun 16, 2004 at 05:51:03PM -0500, Dmitry Torokhov wrote: # > What about freeing the resources? Can it be put in platform_device_unregister # > or is it release handler task? I'd put it in unregister because when I call # > unregister I expect device be half-dead and release as much resources as it # > can. # # # Here's the updated patch - to be applied on top of the # platform_get_resource() patch sent previously. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/18 13:36:39-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: ibmasmfs annotations # # Trivial annotations + couple of missing (void) in prototypes # # include/linux/device.h # 2004/06/10 12:15:03-07:00 rmk+lkml@arm.linux.org.uk +0 -1 # Couple of sysfs patches # # drivers/base/platform.c # 2004/06/18 13:24:02-07:00 rmk+lkml@arm.linux.org.uk +52 -39 # Couple of sysfs patches # # drivers/misc/ibmasm/ibmasmfs.c # 2004/06/18 08:05:56-07:00 viro@parcelfarce.linux.theplanet.co.uk +14 -14 # sparse: ibmasmfs annotations # # ChangeSet # 2004/06/18 13:36:27-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: ide-tape annotation # # drivers/ide/ide-tape.c # 2004/06/18 08:04:58-07:00 viro@parcelfarce.linux.theplanet.co.uk +11 -9 # sparse: ide-tape annotation # # ChangeSet # 2004/06/18 13:36:16-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: drivers/input annotations # # Trivial annotations in drivers/input # # drivers/input/tsdev.c # 2004/06/18 08:04:18-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: drivers/input annotations # # drivers/input/misc/uinput.c # 2004/06/18 08:04:24-07:00 viro@parcelfarce.linux.theplanet.co.uk +3 -3 # sparse: drivers/input annotations # # drivers/input/joydev.c # 2004/06/18 08:04:15-07:00 viro@parcelfarce.linux.theplanet.co.uk +21 -20 # sparse: drivers/input annotations # # ChangeSet # 2004/06/18 13:36:05-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: drivers/char/watchdog annotation # # Trivial annotations in drivers/char/watchdog/* # # drivers/char/watchdog/wdt_pci.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +9 -7 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +9 -7 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/wafer5823wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -7 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/w83877f_wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/w83627hf_wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/softdog.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -5 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/scx200_wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/sc520_wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/sc1200wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +9 -7 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/sbc60xxwdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/pcwd_usb.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +11 -9 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/pcwd_pci.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +11 -9 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/mixcomwd.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +5 -4 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/machzwd.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +5 -4 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/ib700wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -5 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/i8xx_tco.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/eurotechwdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +9 -8 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/cpu5wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +5 -4 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/alim7101_wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/alim1535_wdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/advantechwdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -6 # sparse: drivers/char/watchdog annotation # # drivers/char/watchdog/acquirewdt.c # 2004/06/18 07:43:25-07:00 viro@parcelfarce.linux.theplanet.co.uk +7 -5 # sparse: drivers/char/watchdog annotation # # ChangeSet # 2004/06/18 13:35:54-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: ixj annotated # # drivers/telephony (aka ixj.c) annotated, IXJ_CADENCE split into kernel # and userland variants, ioctl structures got __user on pointers. # # include/linux/ixjuser.h # 2004/06/18 07:40:16-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: ixj annotated # # drivers/telephony/ixj.h # 2004/06/18 07:39:46-07:00 viro@parcelfarce.linux.theplanet.co.uk +8 -2 # sparse: ixj annotated # # drivers/telephony/ixj.c # 2004/06/18 07:39:48-07:00 viro@parcelfarce.linux.theplanet.co.uk +61 -45 # sparse: ixj annotated # # ChangeSet # 2004/06/18 13:35:42-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: vm86.c annotated # # vm86.c annotated; vm86old(2) and vm86(2) switched to explicit # # int (struct pt_regs regs) # # format. # # arch/i386/kernel/vm86.c # 2004/06/18 07:35:47-07:00 viro@parcelfarce.linux.theplanet.co.uk +19 -13 # sparse: vm86.c annotated # # ChangeSet # 2004/06/18 13:35:31-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: rt_sigsuspend/sigaltstack sanitized # # rt_sigsuspend() and sigaltstack() prototype changed; instead of # playing games with casts of argument address to struct pt_regs * and # digging through it, we declare them as # # int (struct pt_regs regs) # # instead. # # arch/i386/kernel/signal.c # 2004/06/18 07:35:29-07:00 viro@parcelfarce.linux.theplanet.co.uk +9 -9 # sparse: rt_sigsuspend/sigaltstack sanitized # # ChangeSet # 2004/06/18 13:35:20-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] sparse: i387 math-emu annotation # # arch/i386/math-emu/* annotated. # # arch/i386/math-emu/reg_ld_str.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +75 -75 # sparse: i387 math-emu annotation # # arch/i386/math-emu/reg_compare.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +6 -6 # sparse: i387 math-emu annotation # # arch/i386/math-emu/load_store.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +26 -26 # sparse: i387 math-emu annotation # # arch/i386/math-emu/get_address.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +15 -15 # sparse: i387 math-emu annotation # # arch/i386/math-emu/fpu_system.h # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: i387 math-emu annotation # # arch/i386/math-emu/fpu_proto.h # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +21 -21 # sparse: i387 math-emu annotation # # arch/i386/math-emu/fpu_etc.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +1 -1 # sparse: i387 math-emu annotation # # arch/i386/math-emu/fpu_entry.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +17 -16 # sparse: i387 math-emu annotation # # arch/i386/math-emu/fpu_aux.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +10 -10 # sparse: i387 math-emu annotation # # arch/i386/math-emu/fpu_arith.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +18 -18 # sparse: i387 math-emu annotation # # arch/i386/math-emu/errors.c # 2004/06/18 07:30:41-07:00 viro@parcelfarce.linux.theplanet.co.uk +5 -5 # sparse: i387 math-emu annotation # # ChangeSet # 2004/06/18 13:18:34-07:00 shemminger@osdl.org # [PKT_SCHED]: Delay scheduler enqueue always succeeds. # # If underlying fifo enqueue fails, return the status not 0. # Same patch should apply to both 2.6 and 2.4 # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/sched/sch_delay.c # 2004/06/18 13:18:20-07:00 shemminger@osdl.org +1 -1 # [PKT_SCHED]: Delay scheduler enqueue always succeeds. # # If underlying fifo enqueue fails, return the status not 0. # Same patch should apply to both 2.6 and 2.4 # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/18 13:15:58-07:00 shemminger@osdl.org # [BRIDGE]: Kill sysfs hotplug avoidance hacks. # # The whole effort to avoid hotplug was misguided. If it is really a problem # (which it doesn't appear to be) then it can more easily be addressed by smarter # hotplug scripts in user space. # # This patch gets rid of the whole subsystem hack for bridge kobjects. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/bridge/br_sysfs_if.c # 2004/06/18 13:15:34-07:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Kill sysfs hotplug avoidance hacks. # # The whole effort to avoid hotplug was misguided. If it is really a problem # (which it doesn't appear to be) then it can more easily be addressed by smarter # hotplug scripts in user space. # # This patch gets rid of the whole subsystem hack for bridge kobjects. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/bridge/br_sysfs_br.c # 2004/06/18 13:15:34-07:00 shemminger@osdl.org +1 -18 # [BRIDGE]: Kill sysfs hotplug avoidance hacks. # # The whole effort to avoid hotplug was misguided. If it is really a problem # (which it doesn't appear to be) then it can more easily be addressed by smarter # hotplug scripts in user space. # # This patch gets rid of the whole subsystem hack for bridge kobjects. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/bridge/br_private.h # 2004/06/18 13:15:34-07:00 shemminger@osdl.org +0 -5 # [BRIDGE]: Kill sysfs hotplug avoidance hacks. # # The whole effort to avoid hotplug was misguided. If it is really a problem # (which it doesn't appear to be) then it can more easily be addressed by smarter # hotplug scripts in user space. # # This patch gets rid of the whole subsystem hack for bridge kobjects. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/bridge/br.c # 2004/06/18 13:15:34-07:00 shemminger@osdl.org +0 -3 # [BRIDGE]: Kill sysfs hotplug avoidance hacks. # # The whole effort to avoid hotplug was misguided. If it is really a problem # (which it doesn't appear to be) then it can more easily be addressed by smarter # hotplug scripts in user space. # # This patch gets rid of the whole subsystem hack for bridge kobjects. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/18 19:53:46+01:00 rmk@flint.arm.linux.org.uk # [ARM] Remove NexusPCI/FTVPCI platform. # # This platform is no longer maintained, and its maintainer says that # the hardware is obsolete and out of circulation. # # arch/arm/common/Makefile # 2004/06/18 19:51:33+01:00 rmk@flint.arm.linux.org.uk +0 -1 # Remove FTVPCI PCI host driver. # # arch/arm/Makefile # 2004/06/18 19:51:33+01:00 rmk@flint.arm.linux.org.uk +0 -2 # Remove FTVPCI. # # arch/arm/Kconfig # 2004/06/18 19:51:32+01:00 rmk@flint.arm.linux.org.uk +4 -9 # Remove FTVPCI. # # ChangeSet # 2004/06/18 19:45:27+01:00 rmk@flint.arm.linux.org.uk # [ARM] Remove TBOX. # # This platform is no longer maintained, and its maintainer says that # the hardware is obsolete and out of circulation. # # ChangeSet # 2004/06/18 11:43:35-07:00 torvalds@ppc970.osdl.org # Merge bk://kernel.bkbits.net/davem/net-2.6 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # security/selinux/ss/services.c # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/ss/policydb.c # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/include/security.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/include/flask.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/include/class_to_string.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/include/av_permissions.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/include/av_perm_to_string.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/include/av_inherit.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/hooks.c # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/selinux/Makefile # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # security/dummy.c # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # net/netlink/af_netlink.c # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # include/linux/security.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # include/asm-ppc64/system.h # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # Documentation/filesystems/proc.txt # 2004/06/18 11:43:31-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # arch/arm/Makefile # 2004/06/18 19:42:57+01:00 rmk@flint.arm.linux.org.uk +0 -1 # Remove TBOX. # # BitKeeper/deleted/.del-plx90x0.c~6e00d8c4651bebd # 2004/06/18 19:22:53+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/common/plx90x0.c # # BitKeeper/deleted/.del-Makefile~743b0b21d18f48a3 # 2004/06/18 19:21:48+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/mach-tbox/Makefile # # BitKeeper/deleted/.del-Makefile~1bcec227c3749c2b # 2004/06/18 19:21:42+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/mach-ftvpci/Makefile # # BitKeeper/deleted/.del-vmalloc.h~6fe84d89a4fe0487 # 2004/06/18 19:20:44+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/vmalloc.h # # BitKeeper/deleted/.del-uncompress.h~d86deb706ce0af8c # 2004/06/18 19:20:41+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/uncompress.h # # BitKeeper/deleted/.del-timex.h~e40ee87eef3b5d82 # 2004/06/18 19:20:39+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/timex.h # # BitKeeper/deleted/.del-time.h~730e38fa47912a2c # 2004/06/18 19:20:37+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/time.h # # BitKeeper/deleted/.del-system.h~13cdaece381624c5 # 2004/06/18 19:20:34+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/system.h # # BitKeeper/deleted/.del-param.h~43f147e81e4d4aa # 2004/06/18 19:20:32+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/param.h # # BitKeeper/deleted/.del-memory.h~a8036cb472d809fd # 2004/06/18 19:20:31+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/memory.h # # BitKeeper/deleted/.del-irqs.h~4b397f62f210ba4a # 2004/06/18 19:20:29+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/irqs.h # # BitKeeper/deleted/.del-io.h~dad3ba234da9ed44 # 2004/06/18 19:20:28+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/io.h # # BitKeeper/deleted/.del-hardware.h~e2ae6d2a73466d92 # 2004/06/18 19:20:26+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/hardware.h # # BitKeeper/deleted/.del-dma.h~7c79d144ee7126 # 2004/06/18 19:20:25+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-nexuspci/dma.h # # BitKeeper/deleted/.del-vmalloc.h~9cc411fb2236e832 # 2004/06/18 19:20:24+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/vmalloc.h # # BitKeeper/deleted/.del-uncompress.h~ba1125271f695d9a # 2004/06/18 19:20:22+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/uncompress.h # # BitKeeper/deleted/.del-timex.h~21cf937463373e34 # 2004/06/18 19:20:20+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/timex.h # # BitKeeper/deleted/.del-time.h~e839fe4bcd9e4cf9 # 2004/06/18 19:20:18+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/time.h # # BitKeeper/deleted/.del-system.h~cd0858e052bb3f86 # 2004/06/18 19:20:16+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/system.h # # BitKeeper/deleted/.del-serial.h~4a4898b286343b2a # 2004/06/18 19:20:15+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/serial.h # # BitKeeper/deleted/.del-param.h~220f433111a13232 # 2004/06/18 19:20:13+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/param.h # # BitKeeper/deleted/.del-memory.h~32316a4b360340b5 # 2004/06/18 19:20:11+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/memory.h # # BitKeeper/deleted/.del-irqs.h~f8419d051722d58a # 2004/06/18 19:20:09+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/irqs.h # # BitKeeper/deleted/.del-io.h~62e0d6286c3e19bc # 2004/06/18 19:20:08+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/io.h # # BitKeeper/deleted/.del-hardware.h~7238d94368669e11 # 2004/06/18 19:20:05+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/hardware.h # # BitKeeper/deleted/.del-dma.h~4cb7553c767afee5 # 2004/06/18 19:20:03+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: include/asm-arm/arch-tbox/dma.h # # BitKeeper/deleted/.del-core.c~714a718aec4a2c30 # 2004/06/18 19:20:01+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/mach-tbox/core.c # # BitKeeper/deleted/.del-pci.c~550e56da56112be2 # 2004/06/18 19:19:59+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/mach-ftvpci/pci.c # # BitKeeper/deleted/.del-leds.c~78050371c0248352 # 2004/06/18 19:19:58+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/mach-ftvpci/leds.c # # BitKeeper/deleted/.del-core.c~9e662b6895b788f2 # 2004/06/18 19:19:57+01:00 rmk@flint.arm.linux.org.uk +0 -0 # Delete: arch/arm/mach-ftvpci/core.c # # ChangeSet # 2004/06/18 12:43:06-05:00 stevef@stevef95.austin.ibm.com # Merge bk://cifs.bkbits.net/linux-2.5cifs # into stevef95.austin.ibm.com:/home/stevef/linux-2.5cifs # # fs/Kconfig # 2004/06/18 12:42:54-05:00 stevef@stevef95.austin.ibm.com +0 -1 # Auto merged # # ChangeSet # 2004/06/18 10:32:19-07:00 greg@kroah.com # Merge kroah.com:/home/greg/linux/BK/bleed-2.6 # into kroah.com:/home/greg/linux/BK/usb-2.6 # # drivers/usb/storage/scsiglue.c # 2004/06/18 10:32:14-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/06/18 10:06:37-07:00 torvalds@ppc970.osdl.org # Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.6 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # include/linux/pci_ids.h # 2004/06/18 10:06:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/sr.c # 2004/06/18 10:06:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/ide-scsi.c # 2004/06/18 10:06:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/Makefile # 2004/06/18 10:06:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/scsi/Kconfig # 2004/06/18 10:06:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # BitKeeper/deleted/.del-scsi_pc98.c~63183f0558d43fc2 # 2004/06/18 10:06:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # BitKeeper/deleted/.del-pc980155.c~e29865f8a9a6ed50 # 2004/06/18 10:06:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # MAINTAINERS # 2004/06/18 10:06:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # BitKeeper/deleted/.del-scsi_pc98.c~63183f0558d43fc2 # 2004/06/18 10:06:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Merge rename: drivers/scsi/scsi_pc98.c -> BitKeeper/deleted/.del-scsi_pc98.c~63183f0558d43fc2 # # BitKeeper/deleted/.del-pc980155.c~e29865f8a9a6ed50 # 2004/06/18 10:06:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Merge rename: drivers/scsi/pc980155.c -> BitKeeper/deleted/.del-pc980155.c~e29865f8a9a6ed50 # # ChangeSet # 2004/06/18 10:04:39-07:00 greg@kroah.com # USB: mark pwc driver broken again, as it still is :( # # drivers/usb/media/Kconfig # 2004/06/18 03:03:21-07:00 greg@kroah.com +1 -1 # USB: mark pwc driver broken again, as it still is :( # # ChangeSet # 2004/06/18 17:58:33+01:00 tony@com.rmk.(none) # [ARM PATCH] 1931/1: Allow device address translation in dma-mapping, version 3 # # Patch from Tony Lindgren # # Allows translation of shared memory addresses for devices using # dma-mapping. In some cases the device DMA address is different # from the ARM DMA address, for example with some USB OHCI # controllers. # # For more background information, please see the ARM Linux mailing # list thread "OHCI controller". # # include/asm-arm/memory.h # 2004/06/18 00:11:37+01:00 tony@com.rmk.(none) +10 -1 # [PATCH] 1931/1: Allow device address translation in dma-mapping, version 3 # # include/asm-arm/dma-mapping.h # 2004/06/18 00:11:37+01:00 tony@com.rmk.(none) +4 -4 # [PATCH] 1931/1: Allow device address translation in dma-mapping, version 3 # # include/asm-arm/arch-omap/memory.h # 2004/06/18 00:11:37+01:00 tony@com.rmk.(none) +20 -4 # [PATCH] 1931/1: Allow device address translation in dma-mapping, version 3 # # arch/arm/mm/consistent.c # 2004/06/18 00:11:02+01:00 tony@com.rmk.(none) +1 -1 # [PATCH] 1931/1: Allow device address translation in dma-mapping, version 3 # # arch/arm/common/dmabounce.c # 2004/06/18 00:11:01+01:00 tony@com.rmk.(none) +5 -5 # [PATCH] 1931/1: Allow device address translation in dma-mapping, version 3 # # ChangeSet # 2004/06/18 17:53:15+01:00 nico@org.rmk.(none) # [ARM PATCH] 1932/1: fix comment about cache handling syscall # # Patch from Nicolas Pitre # # Let's make it coherent with what the actual code is doing and has # always done, even in 2.4. Nobody complained about this so let's # just fix the comment. The most natural usage pattern for this is # a base address and a size so it's more efficient to have an exclusive # end address anyway. # # ChangeSet # 2004/06/18 09:52:38-07:00 stern@rowland.harvard.edu # [PATCH] USB: dummy_hcd shouldn't reject SET-ADDRESS requests # # This patch for the dummy_hcd driver prevents it from rejecting SET-ADDRESS # requests when the address is already set. The USB 2.0 spec states that if # a device is in the ADDRESS state, it should accept and start using the new # address. Behavior in the CONFIGURED state is undefined, but since # dummy_hcd doesn't keep track of the difference between the two states we # might as well accept the new address in any case. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/dummy_hcd.c # 2004/06/18 03:18:28-07:00 stern@rowland.harvard.edu +0 -5 # USB: dummy_hcd shouldn't reject SET-ADDRESS requests # # arch/arm/kernel/traps.c # 2004/06/18 02:01:40+01:00 nico@org.rmk.(none) +1 -1 # [PATCH] 1932/1: fix comment about cache handling syscall # # ChangeSet # 2004/06/18 09:50:41-07:00 axboe@suse.de # [PATCH] cfq direct io alias problem # # This is a fix for when we encounter an alias during insert. When that # happens we move the request to dispatch, but it may happen that this # request is also the ->last_merge hint. So we may attempt to merge with # this later, when it's either in progress or already freed. Rearrange the # logic a bit so we clear the merge hint there as well. It looks more # complex than it is, the only real code change is the addition of a # cfq_remove_merge_hints() in cfq_dispatch_sort(). # # Signed-off-by: Linus Torvalds # # drivers/block/cfq-iosched.c # 2004/06/17 10:37:34-07:00 axboe@suse.de +14 -8 # cfq direct io alias problem # # ChangeSet # 2004/06/18 09:50:31-07:00 axboe@suse.de # [PATCH] cfq allocation race # # It's possible under unlucky circumstances for this race to trigger. I # described it with a comment in the code. # # Signed-Off-By: Jens Axboe # Signed-off-by: Linus Torvalds # # drivers/block/cfq-iosched.c # 2004/05/24 06:35:01-07:00 axboe@suse.de +19 -0 # cfq allocation race # # ChangeSet # 2004/06/18 09:50:20-07:00 axboe@suse.de # [PATCH] cfq sysfs support # # This makes the CFQ tunables available in sysfs, like AS and deadline. # # Signed-off-by: Jens Axboe # Signed-off-by: Linus Torvalds # # drivers/block/cfq-iosched.c # 2004/05/24 06:06:17-07:00 axboe@suse.de +113 -2 # cfq sysfs support # # ChangeSet # 2004/06/18 17:49:27+01:00 icampbell@com.rmk.(none) # [ARM PATCH] 1934/2: Consolidate code to set CKEN on PXA # # Patch from Ian Campbell # # I've seen comments several times that various PXA drivers # update CKEN in an unsafe manner. This patch consolidates # this code into a single function pxa_set_cken() and updates # all the in tree drivers to use it. # # ChangeSet # 2004/06/18 09:48:38-07:00 torvalds@ppc970.osdl.org # Remove old stale header files that aren't referenced anywhere. # # Noted by Alexey Dobriyan. # # BitKeeper/deleted/.del-netfilter_x25.h~5e2c13d4592d8c13 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/netfilter_x25.h # # BitKeeper/deleted/.del-netfilter_ipx.h~7e5cd8fa9a3985ac # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/netfilter_ipx.h # # BitKeeper/deleted/.del-netfilter_ddp.h~2153f0da7220ca38 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/netfilter_ddp.h # # BitKeeper/deleted/.del-netbeui.h~1cf2e2f4793bcad1 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/netbeui.h # # BitKeeper/deleted/.del-mpp.h~8ebce3fa907ece97 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/mpp.h # # BitKeeper/deleted/.del-isdn_lzscomp.h~99cfe6e36b994a1 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/isdn_lzscomp.h # # BitKeeper/deleted/.del-in_systm.h~268bf1b1642e1ee5 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/in_systm.h # # BitKeeper/deleted/.del-fsfilter.h~5fc8d5fdaaa381a # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/fsfilter.h # # BitKeeper/deleted/.del-atapi.h~8a1b1aeca6c26a7 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/atapi.h # # BitKeeper/deleted/.del-adb_mouse.h~d5f39849c4abbd6e # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/adb_mouse.h # # BitKeeper/deleted/.del-acpi_serial.h~d839323d8907296b # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/acpi_serial.h # # BitKeeper/deleted/.del-802_11.h~9b6bd4cff8af7a90 # 2004/06/18 09:47:58-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/linux/802_11.h # # include/asm-arm/arch-pxa/hardware.h # 2004/06/18 01:00:00+01:00 icampbell@com.rmk.(none) +5 -0 # [PATCH] 1934/2: Consolidate code to set CKEN on PXA # # drivers/video/pxafb.c # 2004/06/18 01:00:00+01:00 icampbell@com.rmk.(none) +1 -4 # [PATCH] 1934/2: Consolidate code to set CKEN on PXA # # drivers/usb/gadget/pxa2xx_udc.c # 2004/06/18 01:00:00+01:00 icampbell@com.rmk.(none) +2 -2 # [PATCH] 1934/2: Consolidate code to set CKEN on PXA # # drivers/serial/pxa.c # 2004/06/18 01:00:00+01:00 icampbell@com.rmk.(none) +2 -7 # [PATCH] 1934/2: Consolidate code to set CKEN on PXA # # arch/arm/mach-pxa/generic.c # 2004/06/18 01:00:00+01:00 icampbell@com.rmk.(none) +18 -0 # [PATCH] 1934/2: Consolidate code to set CKEN on PXA # # ChangeSet # 2004/06/18 09:46:06-07:00 torvalds@ppc970.osdl.org # Merge # # drivers/net/at1700.c # 2004/06/18 09:46:04-07:00 torvalds@ppc970.osdl.org +0 -0 # SCCS merged # # ChangeSet # 2004/06/18 17:43:22+01:00 icampbell@com.rmk.(none) # [ARM PATCH] 1930/1: Allocate correct number of pseudo palette entries in pxafb # # Patch from Ian Campbell # # The pxafb driver incorrectly allocates 17 u32's for a 16 entry # pseudo palette. # # drivers/net/Makefile # 2004/06/18 09:43:07-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # BitKeeper/deleted/.del-ne2k_cbus.c~db2bde9191a8ce9a # 2004/06/18 09:43:06-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/06/18 09:43:06-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # drivers/net/82596.c # 2004/06/18 09:43:06-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # BitKeeper/deleted/.del-ne2k_cbus.c~db2bde9191a8ce9a # 2004/06/18 09:43:06-07:00 torvalds@ppc970.osdl.org +0 -0 # Merge rename: drivers/net/ne2k_cbus.c -> BitKeeper/deleted/.del-ne2k_cbus.c~db2bde9191a8ce9a # # drivers/video/pxafb.c # 2004/06/18 01:00:00+01:00 icampbell@com.rmk.(none) +1 -1 # [PATCH] 1930/1: Allocate correct number of pseudo palette entries in pxafb # # ChangeSet # 2004/06/18 09:36:50-07:00 davem@nuts.davemloft.net # Merge # # security/selinux/hooks.c # 2004/06/18 09:36:41-07:00 davem@nuts.davemloft.net +0 -101 # SCCS merged # # security/selinux/ss/services.c # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -12 # Auto merged # # security/selinux/ss/policydb.c # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -9 # Auto merged # # security/selinux/include/security.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -5 # Auto merged # # security/selinux/include/flask.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -21 # Auto merged # # security/selinux/include/class_to_string.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -21 # Auto merged # # security/selinux/include/av_permissions.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -573 # Auto merged # # security/selinux/include/av_perm_to_string.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -101 # Auto merged # # security/selinux/include/av_inherit.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -9 # Auto merged # # security/selinux/Makefile # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -1 # Auto merged # # security/dummy.c # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -1 # Auto merged # # net/netlink/af_netlink.c # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -4 # Auto merged # # include/linux/security.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -11 # Auto merged # # include/asm-ppc64/system.h # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # Documentation/filesystems/proc.txt # 2004/06/18 09:35:13-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/18 09:33:53-07:00 torvalds@ppc970.osdl.org # This removes the files orphaned by the earlier PC9800 removal # # BitKeeper/deleted/.del-smpboot_hooks.h~5940f4c36bed59b4 # 2004/06/18 09:32:54-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/smpboot_hooks.h # # BitKeeper/deleted/.del-setup_arch_pre.h~1aa05e47e2ae5d10 # 2004/06/18 09:32:54-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/setup_arch_pre.h # # BitKeeper/deleted/.del-setup_arch_post.h~c1ce95fa8d614f4d # 2004/06/18 09:32:54-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/setup_arch_post.h # # BitKeeper/deleted/.del-pci-functions.h~930f4ea96f69d14 # 2004/06/18 09:32:54-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/pci-functions.h # # BitKeeper/deleted/.del-mach_wakecpu.h~de206fda8667a7e7 # 2004/06/18 09:32:54-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/mach_wakecpu.h # # BitKeeper/deleted/.del-mach_traps.h~db7e527be9d0d95b # 2004/06/18 09:32:54-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/mach_traps.h # # BitKeeper/deleted/.del-mach_timer.h~6faf9e0362bc9cad # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/mach_timer.h # # BitKeeper/deleted/.del-mach_time.h~4ec98fea93568edd # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/mach_time.h # # BitKeeper/deleted/.del-mach_reboot.h~666bd1054bae0a25 # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/mach_reboot.h # # BitKeeper/deleted/.del-irq_vectors.h~5a325ee32bbed31 # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/irq_vectors.h # # BitKeeper/deleted/.del-io_ports.h~8f892217bfd99be4 # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/io_ports.h # # BitKeeper/deleted/.del-do_timer.h~e73335e43b11ea32 # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/do_timer.h # # BitKeeper/deleted/.del-bios_ebda.h~4a870d9833986305 # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/bios_ebda.h # # BitKeeper/deleted/.del-apm.h~324fabc1c2354803 # 2004/06/18 09:32:53-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/mach-pc9800/apm.h # # BitKeeper/deleted/.del-video.S~284da1c1c2e38aa8 # 2004/06/18 09:32:48-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/boot98/video.S # # BitKeeper/deleted/.del-setup.S~bd07a5b2361060c # 2004/06/18 09:32:48-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/boot98/setup.S # # BitKeeper/deleted/.del-mtools.conf.in~3346efde195fa35 # 2004/06/18 09:32:48-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/boot98/mtools.conf.in # # BitKeeper/deleted/.del-install.sh~6441f5459fde0cb0 # 2004/06/18 09:32:48-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/boot98/install.sh # # BitKeeper/deleted/.del-bootsect.S~aa4f19a632039843 # 2004/06/18 09:32:48-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/boot98/bootsect.S # # BitKeeper/deleted/.del-Makefile~2700a53f2e1fb469 # 2004/06/18 09:32:48-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/boot98/Makefile # # BitKeeper/deleted/.del-topology.c~607813b1b960974f # 2004/06/18 09:32:43-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/mach-pc9800/topology.c # # BitKeeper/deleted/.del-std_resources.c~54f4a08a759f2f5f # 2004/06/18 09:32:43-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/mach-pc9800/std_resources.c # # BitKeeper/deleted/.del-setup.c~161f6c99c14ddb5d # 2004/06/18 09:32:43-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/mach-pc9800/setup.c # # BitKeeper/deleted/.del-Makefile~c002abb789b0791f # 2004/06/18 09:32:43-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: arch/i386/mach-pc9800/Makefile # # BitKeeper/deleted/.del-sound_pc9800.h~d8dde13c75b5753b # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: sound/isa/cs423x/sound_pc9800.h # # BitKeeper/deleted/.del-pc9801_118_magic.h~479c5fdd78d01b7a # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: sound/isa/cs423x/pc9801_118_magic.h # # BitKeeper/deleted/.del-pc9800_sca.h~b52752436ddb82ea # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/pc9800_sca.h # # BitKeeper/deleted/.del-pc9800.h~e8f7c13f33846c88 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: include/asm-i386/pc9800.h # # BitKeeper/deleted/.del-pc9800.c~1af765dbb1c51b76 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/ide/legacy/pc9800.c # # BitKeeper/deleted/.del-pc98.c~e5a92ca5f2b01d36 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: sound/isa/cs423x/pc98.c # # BitKeeper/deleted/.del-nec98.h~a0b8de1e822fa884 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: fs/partitions/nec98.h # # BitKeeper/deleted/.del-nec98.c~2e65e92f56ce9a56 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: fs/partitions/nec98.c # # BitKeeper/deleted/.del-hd98.c~fc4a0b69729bf7c1 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/ide/legacy/hd98.c # # BitKeeper/deleted/.del-98spkr.c~a1a91856da60a088 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/input/misc/98spkr.c # # BitKeeper/deleted/.del-98busmouse.c~ca244def94322735 # 2004/06/18 09:32:33-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/input/mouse/98busmouse.c # # BitKeeper/deleted/.del-serial98.c~c69c28b9984f1cca # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/serial/serial98.c # # BitKeeper/deleted/.del-scsi_pc98.c~63183f0558d43fc2 # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/scsi/scsi_pc98.c # # BitKeeper/deleted/.del-pc980155.h~f12bd20496e02379 # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/scsi/pc980155.h # # BitKeeper/deleted/.del-pc980155.c~e29865f8a9a6ed50 # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/scsi/pc980155.c # # BitKeeper/deleted/.del-lp_old98.c~fc58ff5b2fa5c998 # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/char/lp_old98.c # # BitKeeper/deleted/.del-floppy98.c~12864e155d00fa0e # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/block/floppy98.c # # BitKeeper/deleted/.del-98kbd.c~fcb070eb5c330ed3 # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/input/keyboard/98kbd.c # # BitKeeper/deleted/.del-98kbd-io.c~37d03ba23bb15415 # 2004/06/18 09:32:32-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/input/serio/98kbd-io.c # # BitKeeper/deleted/.del-upd4990a.c~6da2f3423f9a74f # 2004/06/18 09:32:23-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/char/upd4990a.c # # BitKeeper/deleted/.del-ne2k_cbus.h~b1e2c6c8f1caf542 # 2004/06/18 09:32:23-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/net/ne2k_cbus.h # # BitKeeper/deleted/.del-ne2k_cbus.c~db2bde9191a8ce9a # 2004/06/18 09:32:23-07:00 torvalds@ppc970.osdl.org +0 -0 # Delete: drivers/net/ne2k_cbus.c # # ChangeSet # 2004/06/18 09:31:40-07:00 torvalds@ppc970.osdl.org # Merge # # arch/i386/kernel/acpi/boot.c # 2004/06/18 09:31:38-07:00 torvalds@ppc970.osdl.org +0 -0 # SCCS merged # # arch/i386/kernel/mpparse.c # 2004/06/18 09:29:48-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/18 09:24:59-07:00 torvalds@ppc970.osdl.org # Merge duplicate selinux network hooks # # security/selinux/hooks.c # 2004/06/18 09:24:54-07:00 torvalds@ppc970.osdl.org +0 -101 # Merge duplicate selinux hooks # # security/selinux/ss/services.c # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -12 # Auto merged # # security/selinux/ss/policydb.c # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -9 # Auto merged # # security/selinux/include/security.h # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -5 # Auto merged # # security/selinux/include/flask.h # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -21 # Auto merged # # security/selinux/include/class_to_string.h # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -21 # Auto merged # # security/selinux/include/av_permissions.h # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -573 # Auto merged # # security/selinux/include/av_perm_to_string.h # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -101 # Auto merged # # security/selinux/include/av_inherit.h # 2004/06/18 09:21:51-07:00 torvalds@ppc970.osdl.org +0 -9 # Auto merged # # security/selinux/Makefile # 2004/06/18 09:21:50-07:00 torvalds@ppc970.osdl.org +0 -1 # Auto merged # # security/dummy.c # 2004/06/18 09:21:50-07:00 torvalds@ppc970.osdl.org +0 -1 # Auto merged # # net/netlink/af_netlink.c # 2004/06/18 09:21:50-07:00 torvalds@ppc970.osdl.org +0 -4 # Auto merged # # include/linux/security.h # 2004/06/18 09:21:50-07:00 torvalds@ppc970.osdl.org +0 -11 # Auto merged # # include/asm-ppc64/system.h # 2004/06/18 09:21:50-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # Documentation/filesystems/proc.txt # 2004/06/18 09:21:50-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/06/18 08:25:41-07:00 chrisw@osdl.org # [PATCH] RLIM: remove unused queued_signals global accounting # # Remove unused queued_signals global accounting. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sysctl.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +0 -18 # RLIM: remove unused queued_signals global accounting # # kernel/signal.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +0 -3 # RLIM: remove unused queued_signals global accounting # # ChangeSet # 2004/06/18 08:25:30-07:00 chrisw@osdl.org # [PATCH] RLIM: enforce rlimits on queued signals # # Add a user_struct pointer to the sigqueue structure. Charge sigqueue # allocation and destruction to the user_struct rather than a global pool. This # per user rlimit accounting obsoletes the global queued_signals accouting. # # The patch as charges the sigqueue struct allocation to the queue that it's # pending on (the receiver of the signal). So the owner of the queue is charged # for whoever writes to it (much like quota for a 777 file). # # The patch started out charging the task which allocated the sigqueue struct. # In most cases, these are always the same user (permission for sending a # signal), so those cases are moot. In the cases where it isn't the same user, # it's a privileged user sending a signal to another user. # # It seems wrong to charge the allocation to the privleged user, when the other # user could block receipt as long as it feels. The flipside is, someone else # can fill your queue (expectation is that someone else is privileged). I think # it's right the way it is. The change to revert is very small. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/signal.c # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +11 -6 # RLIM: enforce rlimits on queued signals # # include/linux/signal.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: enforce rlimits on queued signals # # ChangeSet # 2004/06/18 08:25:20-07:00 chrisw@osdl.org # [PATCH] RLIM: pass task_struct in send_signal() # # Update send_signal() api to allow passing the task receiving the signal. This # is necessary to ensure signals generated out of process context can be charged # to the correct user. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/signal.c # 2004/06/18 00:32:25-07:00 chrisw@osdl.org +4 -3 # RLIM: pass task_struct in send_signal() # # ChangeSet # 2004/06/18 08:23:45-07:00 torvalds@ppc970.osdl.org # Fix kill_pg_info(): return success if _any_ signal succeeded. # # kernel/signal.c # 2004/06/18 08:23:40-07:00 torvalds@ppc970.osdl.org +7 -11 # Fix kill_pg_info(): return success if _any_ signal succeeded. # # ChangeSet # 2004/06/18 08:17:04-07:00 kszysiu@iceberg.elsat.net.pl # [PATCH] cmpci oops on rmmod + fix # # The cmpci driver included in Linux 2.6.7 causes an oops on rmmod, I believe # cm_remove should be marked __devexit rather than __devinit. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/oss/cmpci.c # 2004/06/18 00:06:08-07:00 kszysiu@iceberg.elsat.net.pl +2 -2 # cmpci oops on rmmod + fix # # ChangeSet # 2004/06/18 08:16:53-07:00 ysato@users.sourceforge.jp # [PATCH] H8/300: io.h cleanup # # - optimize byteswap # - add noswap io mode # - cleanup var type # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-h8300/io.h # 2004/06/18 00:06:08-07:00 ysato@users.sourceforge.jp +68 -24 # H8/300: io.h cleanup # # ChangeSet # 2004/06/18 08:16:42-07:00 ysato@users.sourceforge.jp # [PATCH] H8/300: ptrace fix # # - Kconfig typo fix # - PTRACE_PEEKUSER read process info support # - exr restore fix # - ptrace register offset fix # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/h8300/platform/h8s/ptrace_h8s.c # 2004/06/18 00:06:07-07:00 ysato@users.sourceforge.jp +1 -1 # H8/300: ptrace fix # # arch/h8300/platform/h8s/entry.S # 2004/06/18 00:06:07-07:00 ysato@users.sourceforge.jp +1 -1 # H8/300: ptrace fix # # arch/h8300/kernel/ptrace.c # 2004/06/18 00:06:07-07:00 ysato@users.sourceforge.jp +23 -5 # H8/300: ptrace fix # # arch/h8300/Kconfig # 2004/06/18 00:06:07-07:00 ysato@users.sourceforge.jp +1 -1 # H8/300: ptrace fix # # ChangeSet # 2004/06/18 08:16:33-07:00 kaos@ocs.com.au # [PATCH] contify some scheduler functions # # Several scheduler macros only read from the task struct, mark them const. # It may help the compiler generate better code. # # Signed-off-by: Keith Owens # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/sched.c # 2004/06/18 00:06:07-07:00 kaos@ocs.com.au +3 -3 # contify some scheduler functions # # kernel/exit.c # 2004/06/18 00:06:07-07:00 kaos@ocs.com.au +3 -3 # contify some scheduler functions # # include/linux/sched.h # 2004/06/18 00:06:07-07:00 kaos@ocs.com.au +6 -6 # contify some scheduler functions # # ChangeSet # 2004/06/18 08:16:21-07:00 greg@kroah.com # [PATCH] remove EXPORT_SYMBOL(kallsyms_lookup) # # Distros have started to ship kernels with this patch, as it seems that some # unnamed binary module authors are already abusing this function (as well as # some open source modules, like the openib code.) I could not find any valid # reason why this symbol should be exported, so here's a patch against 2.6.7 # that removes it. # # Signed-off-by: Greg Kroah-Hartman # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/kallsyms.c # 2004/06/18 00:06:07-07:00 greg@kroah.com +0 -1 # remove EXPORT_SYMBOL(kallsyms_lookup) # # ChangeSet # 2004/06/18 08:16:11-07:00 rddunlap@osdl.org # [PATCH] remove blank line in show_trace() # # Delete a blank line for more error reporting on-screen. # # Signed-off-by: Randy Dunlap # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/traps.c # 2004/06/18 00:06:07-07:00 rddunlap@osdl.org +0 -1 # remove blank line in show_trace() # # ChangeSet # 2004/06/18 08:16:00-07:00 kenneth.w.chen@intel.com # [PATCH] Hugetlb page bug fix for i386 in PAE mode # # Hit a bug check when unmap a hugetlb vma in PAE mode on i386 (and x86-64). # # Bad page state at free_hot_cold_page (in process 'a.out', page c165cc40) # flags:0x20000000 mapping:f75e1d00 mapped:0 count:0 # Backtrace: # Call Trace: # [] bad_page+0x79/0x9e # [] free_hot_cold_page+0x71/0xfa # [] unmap_hugepage_range+0xa3/0xbf # [] unmap_vmas+0xac/0x252 # [] default_wake_function+0x0/0xc # [] unmap_region+0xd8/0x145 # [] do_munmap+0xfc/0x14d # [] sys_shmdt+0xa5/0x126 # [] sys_ipc+0x23c/0x27f # [] sys_write+0x38/0x59 # [] syscall_call+0x7/0xb # # It turns out there is a bug in hugetlb_prefault(): with 3 level page table, # huge_pte_alloc() might return a pmd that points to a PTE page. It happens # if the virtual address for hugetlb mmap is recycled from previously used # normal page mmap. free_pgtables() might not scrub the pmd entry on munmap # and hugetlb_prefault skips on any pmd presence regardless what type it is. # Patch to fix the bug. # # Signed-off-by: Ken Chen # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/mm/hugetlbpage.c # 2004/06/18 00:06:07-07:00 kenneth.w.chen@intel.com +9 -2 # Hugetlb page bug fix for i386 in PAE mode # # ChangeSet # 2004/06/18 08:15:49-07:00 minyard@acm.org # [PATCH] IPMI base patch to fix channel handling and add polling # # This patch fixes some problems with handling of channel detection in the # driver. Some systems that are IPMI 1.5 do not implement the channel query # command. Also, the interface has to be fully up before the command is # ready. # # This patch also adds a polling interface; this is required for situations # where interrupts are not running, but the system must still issue IPMI # commands, like when taking a crash dump. # # It also updates the driver version to v32. # # Signed-off-by: Corey Minyard # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/ipmi_smi.h # 2004/06/18 00:06:07-07:00 minyard@acm.org +4 -0 # IPMI base patch to fix channel handling and add polling # # include/linux/ipmi_msgdefs.h # 2004/06/18 00:06:07-07:00 minyard@acm.org +1 -0 # IPMI base patch to fix channel handling and add polling # # include/linux/ipmi.h # 2004/06/18 00:06:07-07:00 minyard@acm.org +10 -0 # IPMI base patch to fix channel handling and add polling # # drivers/char/ipmi/ipmi_watchdog.c # 2004/06/18 00:06:07-07:00 minyard@acm.org +3 -5 # IPMI base patch to fix channel handling and add polling # # drivers/char/ipmi/ipmi_smic_sm.c # 2004/06/18 00:06:07-07:00 minyard@acm.org +1 -1 # IPMI base patch to fix channel handling and add polling # # drivers/char/ipmi/ipmi_si_intf.c # 2004/06/18 00:06:07-07:00 minyard@acm.org +45 -16 # IPMI base patch to fix channel handling and add polling # # drivers/char/ipmi/ipmi_msghandler.c # 2004/06/18 00:06:07-07:00 minyard@acm.org +29 -2 # IPMI base patch to fix channel handling and add polling # # drivers/char/ipmi/ipmi_kcs_sm.c # 2004/06/18 00:06:07-07:00 minyard@acm.org +1 -1 # IPMI base patch to fix channel handling and add polling # # drivers/char/ipmi/ipmi_devintf.c # 2004/06/18 00:06:07-07:00 minyard@acm.org +1 -1 # IPMI base patch to fix channel handling and add polling # # drivers/char/ipmi/ipmi_bt_sm.c # 2004/06/18 00:06:07-07:00 minyard@acm.org +1 -1 # IPMI base patch to fix channel handling and add polling # # ChangeSet # 2004/06/18 08:15:37-07:00 jmorris@redhat.com # [PATCH] SELinux: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Cc: David S. Miller # Signed-off-by: James Morris # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # security/selinux/nlmsgtab.c # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +153 -0 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/ss/services.c # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +12 -0 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/ss/policydb.c # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +9 -1 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/nlmsgtab.c # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/security/selinux/nlmsgtab.c # # security/selinux/include/security.h # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +5 -4 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/include/flask.h # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +9 -0 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/include/class_to_string.h # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +9 -0 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/include/av_permissions.h # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +223 -0 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/include/av_perm_to_string.h # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +12 -0 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/include/av_inherit.h # 2004/06/18 00:06:06-07:00 jmorris@redhat.com +9 -0 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/hooks.c # 2004/06/18 00:06:06-07:00 jmorris@redhat.com +80 -22 # SELinux: Fine-grained Netlink support - SELinux changes # # security/selinux/Makefile # 2004/06/18 00:06:07-07:00 jmorris@redhat.com +1 -1 # SELinux: Fine-grained Netlink support - SELinux changes # # ChangeSet # 2004/06/18 08:15:25-07:00 jmorris@redhat.com # [PATCH] SELinux: Fine-grained Netlink support - add sk to netlink_send hook # # Modifies the LSM netlink_send() hook so that it takes a struct sock parameter. # SELinux will use this parameter to lookup the class of socket, which was # assigned during socket security initialization. # # Cc: David S. Miller # Signed-off-by: James Morris # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # security/selinux/hooks.c # 2004/06/18 00:32:07-07:00 jmorris@redhat.com +1 -1 # SELinux: Fine-grained Netlink support - add sk to netlink_send hook # # security/dummy.c # 2004/06/18 00:06:06-07:00 jmorris@redhat.com +1 -1 # SELinux: Fine-grained Netlink support - add sk to netlink_send hook # # net/netlink/af_netlink.c # 2004/06/18 00:06:06-07:00 jmorris@redhat.com +1 -1 # SELinux: Fine-grained Netlink support - add sk to netlink_send hook # # include/linux/security.h # 2004/06/18 00:06:06-07:00 jmorris@redhat.com +11 -8 # SELinux: Fine-grained Netlink support - add sk to netlink_send hook # # ChangeSet # 2004/06/18 08:15:14-07:00 jmorris@redhat.com # [PATCH] SELinux: Fine-grained Netlink support - move security_netlink_send() hook # # This patch moves the security_netlink_send() LSM hook after the user copy, so # that LSM modules can safely examine skb payload content. For SELinux, we need # to look at the Netlink message type. # # Cc: David S. Miller # Signed-off-by: James Morris # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # net/netlink/af_netlink.c # 2004/06/18 00:32:07-07:00 jmorris@redhat.com +4 -4 # SELinux: Fine-grained Netlink support - move security_netlink_send() hook # # ChangeSet # 2004/06/18 08:15:04-07:00 jmorris@redhat.com # [PATCH] SELinux: Fine-grained Netlink support - SELinux headers update # # This patch regenerates the SELinux module headers to reflect new class and # access vectors definitions. The size of the diff is misleading; much of it is # simply a change in the ordering of the automatically generated definitions. # The corresponding generation script has been changed to ensure a stable order # in the future. Please apply. # # Author: Stephen Smalley # Cc: David S. Miller # Signed-off-by: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # security/selinux/include/flask.h # 2004/06/18 00:32:07-07:00 jmorris@redhat.com +12 -0 # SELinux: Fine-grained Netlink support - SELinux headers update # # security/selinux/include/class_to_string.h # 2004/06/18 00:32:07-07:00 jmorris@redhat.com +12 -0 # SELinux: Fine-grained Netlink support - SELinux headers update # # security/selinux/include/av_permissions.h # 2004/06/18 00:32:07-07:00 jmorris@redhat.com +350 -250 # SELinux: Fine-grained Netlink support - SELinux headers update # # security/selinux/include/av_perm_to_string.h # 2004/06/18 00:32:07-07:00 jmorris@redhat.com +89 -3 # SELinux: Fine-grained Netlink support - SELinux headers update # # ChangeSet # 2004/06/18 08:14:53-07:00 chrisw@osdl.org # [PATCH] fix simple_strtoul base 16 handling # # I know it's simple_strtoul, but is it meant to be that simple? Fix up for # both simple_strtoul and simple_strtoull. # # simple_strtoul(0x401b, NULL, 0) = 0x401b # simple_strtoul(0X401b, NULL, 0) = 0x0 # simple_strtoul(0x401b, NULL, 16) = 0x0 # simple_strtoul(0X401b, NULL, 16) = 0x0 # # simple_strtoull(0x401b, NULL, 0) = 0x401b # simple_strtoull(0X401b, NULL, 0) = 0x0 # simple_strtoull(0x401b, NULL, 16) = 0x0 # simple_strtoull(0X401b, NULL, 16) = 0x0 # # Signed-off-by: Chris Wright # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # lib/vsprintf.c # 2004/06/18 00:06:06-07:00 chrisw@osdl.org +8 -2 # fix simple_strtoul base 16 handling # # ChangeSet # 2004/06/18 08:14:42-07:00 eger@havoc.gtf.org # [PATCH] rivafb: fb accel capabilities # # Here's the fb accel capabilities patch for rivafb. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/riva/fbdev.c # 2004/06/18 00:06:06-07:00 eger@havoc.gtf.org +6 -1 # rivafb: fb accel capabilities # # ChangeSet # 2004/06/18 08:14:31-07:00 geert@linux-m68k.org # [PATCH] fix warning in fbmem.c # # Fix a const/non-const warning. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/fb.h # 2004/06/18 00:06:06-07:00 geert@linux-m68k.org +1 -1 # fix warning in fbmem.c # # drivers/video/fbmem.c # 2004/06/18 00:06:06-07:00 geert@linux-m68k.org +13 -9 # fix warning in fbmem.c # # ChangeSet # 2004/06/18 08:14:20-07:00 eger@havoc.gtf.org # [PATCH] fix radeonfb panning and make it play nice with copyarea() # # radeonfb: fix panning corruption on a large virtual screen, Make panning # and copyarea() play nicely with each other. # # Signed-off-by: David Eger # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/aty/radeon_base.c # 2004/06/18 00:06:05-07:00 eger@havoc.gtf.org +13 -0 # fix radeonfb panning and make it play nice with copyarea() # # drivers/video/aty/radeon_accel.c # 2004/06/18 00:06:05-07:00 eger@havoc.gtf.org +4 -4 # fix radeonfb panning and make it play nice with copyarea() # # ChangeSet # 2004/06/18 08:14:09-07:00 lethal@Linux-SH.ORG # [PATCH] asiliantfb init fix # # asiliantfb seems to have only been partially merged (the fbmem.c bits in # particular seem to have been missed entirely). This adds them back in, # though they do seem to be present in the fbdev tree, at least they were the # last time I looked. # # These are the last bit of outstanding changes I have in the LinuxSH # tree for asiliantfb, so it would be nice to get this out of the way. # # Signed-off-by: Paul Mundt # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/fbmem.c # 2004/06/18 00:32:08-07:00 lethal@Linux-SH.ORG +4 -0 # asiliantfb init fix # # ChangeSet # 2004/06/18 08:13:58-07:00 adaplas@hotpop.com # [PATCH] More updates to rivafb driver # # 1. pass info->monspecs.modedb and info->monspecs.modedb_len to # fb_find_mode() instead of NULL, 0 since its contents are specific to the # attached display. Anyway, if info->monspecs.modedb == NULL, # fb_find_mode() will use the default database. # # 2. Added best fit algo to fb_find_mode(). # # 3. Use snprintf instead of sprintf. # # Signed-off-by: Antonino Daplas # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/modedb.c # 2004/06/18 00:06:05-07:00 adaplas@hotpop.com +19 -2 # More updates to rivafb driver # # drivers/video/console/fbcon.c # 2004/06/18 00:06:05-07:00 adaplas@hotpop.com +4 -3 # More updates to rivafb driver # # ChangeSet # 2004/06/18 08:13:47-07:00 adaplas@hotpop.com # [PATCH] Updates to rivafb driver # # The patch updates rivafb to the following: # # 1. Fixed cursor corruption and simplified cursor code. # # 2. Maximized var->yres_virtual on initial mode setting. Scrolling, # therefore, defaults to y-panning which is significantly faster. # # 3. Restricted var->xres_virtual and var->yres_virtual to 0x7fff # (hardware limitation?). Otherwise, var->yres_virtual > 0x7fff + panning # will hang the GPU. # # 4. Added I2C/DDC support. This feature enables independent mode setup # to rivafb. 'stty rows n cols n' should now work correctly. This is a # configurable option. # # 5. Various/minor fixes to drawing code. # # Signed-off-by: Antonino Daplas # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/riva/rivafb-i2c.c # 2004/06/18 00:06:05-07:00 adaplas@hotpop.com +209 -0 # Updates to rivafb driver # # drivers/video/riva/rivafb.h # 2004/06/18 00:06:05-07:00 adaplas@hotpop.com +24 -9 # Updates to rivafb driver # # drivers/video/riva/rivafb-i2c.c # 2004/06/18 00:06:05-07:00 adaplas@hotpop.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/video/riva/rivafb-i2c.c # # drivers/video/riva/fbdev.c # 2004/06/18 00:32:08-07:00 adaplas@hotpop.com +188 -148 # Updates to rivafb driver # # drivers/video/riva/Makefile # 2004/06/18 00:06:05-07:00 adaplas@hotpop.com +6 -2 # Updates to rivafb driver # # drivers/video/Kconfig # 2004/06/18 00:06:05-07:00 adaplas@hotpop.com +5 -0 # Updates to rivafb driver # # ChangeSet # 2004/06/18 08:13:36-07:00 eger@havoc.gtf.org # [PATCH] fbcon: prefer pan when available # # Improve heuristics to favor panning over copyarea() thanks to pseudocode # from Antonino Daplas # # Signed-off-by: David Eger # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/console/fbcon.c # 2004/06/18 00:32:09-07:00 eger@havoc.gtf.org +19 -15 # fbcon: prefer pan when available # # ChangeSet # 2004/06/18 08:13:25-07:00 eger@havoc.gtf.org # [PATCH] fb accel capabilities # # Baseline patch to make framebuffer/fbcon interaction more sane by basing the # fbcon heuristics on capabilities advertized by underlying framebuffer via the # fb_info.flags field. # # This patch updates fbcon, fb.h, and skeletonfb.c. It does *not* yet update # the drivers themselves. They should compile and work, but their hinting is # not correct yet, meaning most fb drivers will be slow until I set the flags to # the right hinting driver-by-driver # # Signed-off-by: David Eger # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/fb.h # 2004/06/18 00:32:08-07:00 eger@havoc.gtf.org +46 -6 # fb accel capabilities # # drivers/video/skeletonfb.c # 2004/06/18 00:06:05-07:00 eger@havoc.gtf.org +7 -1 # fb accel capabilities # # drivers/video/console/fbcon.h # 2004/06/18 00:06:05-07:00 eger@havoc.gtf.org +19 -32 # fb accel capabilities # # drivers/video/console/fbcon.c # 2004/06/18 00:32:09-07:00 eger@havoc.gtf.org +50 -47 # fb accel capabilities # # ChangeSet # 2004/06/18 08:13:13-07:00 daniel@osdl.org # [PATCH] handle partial DIO write # # The fsx-linux hole fill failure problem was caused by # generic_file_aio_write_nolock() not handling the partial DIO write # correctly. Here's a patch lets DIO do the partial write, and the fallback # to buffered is done (correctly) for what is left. This fixes the hole # filling without retrying the entire i/o. This patch also applies to # 2.6.7-rc3 with some offset. # # I tested this (on ext3) with # fsx-linux -l 500000 -r 4096 -t 4096 -w 4096 -Z -N 10000 junk -R -W # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/filemap.c # 2004/06/18 00:06:05-07:00 daniel@osdl.org +1 -1 # handle partial DIO write # # fs/direct-io.c # 2004/06/18 00:06:05-07:00 daniel@osdl.org +7 -7 # handle partial DIO write # # ChangeSet # 2004/06/18 08:13:02-07:00 schwidefsky@de.ibm.com # [PATCH] s390: lost dirty bits # # The SetPageUptodate function is called for pages that are already up to # date. The arch_set_page_uptodate function of s390 may not clear the dirty # bit in that case otherwise a dirty bit which is set between the start of an # i/o for a writeback and a following call to SetPageUptodate is lost. # # Signed-off-by: Martin Schwidefsky # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/page-flags.h # 2004/06/18 00:06:04-07:00 schwidefsky@de.ibm.com +3 -9 # s390: lost dirty bits # # include/asm-s390/pgtable.h # 2004/06/18 00:06:04-07:00 schwidefsky@de.ibm.com +4 -2 # s390: lost dirty bits # # ChangeSet # 2004/06/18 08:12:51-07:00 hch@lst.de # [PATCH] fix standalone inclusion of asm-i386/dma-mapping.h # # Without this a usb-storage patch I sent fails on x86 because dma-mapping.h # uses struct device and various VM stuff without proper includes. It's fine # on ppc at least. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/dma-mapping.h # 2004/06/18 00:06:04-07:00 hch@lst.de +3 -0 # fix standalone inclusion of asm-i386/dma-mapping.h # # ChangeSet # 2004/06/18 08:12:41-07:00 jmorris@redhat.com # [PATCH] Fix sock_orphan race. # # The patch below fixes a race between sock_orphan() and # selinux_socket_sock_rcv_skb() which can lead to a null pointer deref oops # under heavy load. The sk_callback_lock is used in the patch to synchronize # access to the incoming socket's inode security state. # # This patch has been under test in the Fedora kernel for over a month # without incident. # # Author: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # security/selinux/hooks.c # 2004/06/18 00:32:07-07:00 jmorris@redhat.com +21 -16 # Fix sock_orphan race. # # ChangeSet # 2004/06/18 08:12:29-07:00 marcelo.tosatti@cyclades.com # [PATCH] update Marcelo CREDITS info # # Update my CREDITS information. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # CREDITS # 2004/06/18 00:06:04-07:00 marcelo.tosatti@cyclades.com +7 -6 # update Marcelo CREDITS info # # ChangeSet # 2004/06/18 08:12:18-07:00 jmorris@redhat.com # [PATCH] Add security_file_permission() to AIO paths. # # Currently, there are no LSM hooks in the AIO codepaths, which means that # LSM based access controls are not revalidated upon AIO read and write # operations. The patch below adds the security_file_permission() LSM hook # prior to the VFS aio_read()/aio_write() calls. # # Signed-off-by: James Morris # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/aio.c # 2004/06/18 00:06:04-07:00 jmorris@redhat.com +7 -0 # Add security_file_permission() to AIO paths. # # ChangeSet # 2004/06/18 08:12:08-07:00 linux@dominikbrodowski.de # [PATCH] add 1 in __const_udelay() # # The "mull" instruction in __const_udelay() cuts off the lower 32 bits -- # so, it is "rounding down". This is both an issue for small ndelay()s for # _all_ values for loops_per_jiffy and for certain {n,u}delay()s for many # loops_per_jiffy values. # # Assuming # # LPJ = 1501115 # # udelay(87) # # results in # # 130597 loops to be spent. # # However, 1000 * 130597 / 1501115 is 86.999997 us, so we're actually # _rounding down_. 1000 * 130598 / 1501115 is 87.000662841, which would be # the technically correct thing to do. Of course, for the TSC case this # won't matter as the maths take some time, so the actual delay is # # 1000 * __udelay(x) / lpj + __OVERHEAD(x) # # Anybody worried about both the additional overhead and the fact that the # overhead takes some time to run should add a check # # if (unlikely(xloops < OVERHEAD)) # return; # xloops -= OVERHEAD; # # to the delay() routines in arch/i386/kernel/timers/*.c and determine # what the OVERHEAD is. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/lib/delay.c # 2004/06/18 00:06:04-07:00 linux@dominikbrodowski.de +1 -1 # add 1 in __const_udelay() # # ChangeSet # 2004/06/18 08:11:56-07:00 linux@dominikbrodowski.de # [PATCH] round up in __udelay() # # Round up in __udelay(): 2**32 / 100000 is 4294.97, so it's more intuitive # to round up, and it causes more predictable results: # # n usec delay on a 1500000 BogoMIPS system: # # n before -mull after # 1 1000 ticks 1499 ticks 1500 ticks # 10 14000 ticks 14999 ticks 15000 ticks # # n usec delay on a 100000 BogoMIPS system: # # n before -mull after # 1 0 ticks 99 ticks 100 ticks # 10 0 ticks 999 ticks 1000 ticks # 100 9000 ticks 9999 ticks 10000 ticks # # While it can be argued that some time is also spent in the delay functions, # it's better to spend _at least_ the specified time sleeping, in my humble # opinion. And the overhead of a specific ->delay() implementation should be # substracted in the specific ->delay() implementation. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/delay.h # 2004/06/18 00:06:04-07:00 linux@dominikbrodowski.de +1 -1 # round up in __udelay() # # arch/i386/lib/delay.c # 2004/06/18 00:32:10-07:00 linux@dominikbrodowski.de +1 -1 # round up in __udelay() # # ChangeSet # 2004/06/18 08:11:46-07:00 linux@dominikbrodowski.de # [PATCH] mull'ify multiplication with HZ in __const_udelay() # # John Stultz mentioned on lkml ( http://lkml.org/lkml/2004/6/5/15 ) that # calls to udelay() don't delay long enough, causing trouble e.g. in the USB # subsystem. The following patches address this issue. # # Move the multiplication of (loops_per_jiffy * xloops) with HZ into the # "mull" asm operation. This increases the accuracy of the delay functions # largely: # # n usec delay on a system with loops_per_jiffy = 1500000 : # # n before after # 1 1000 ticks 1499 ticks # 10 14000 ticks 14999 ticks # # n usec delay on a system with loops_per_jiffy = 100000 : # # n before after # 1 0 ticks 99 ticks # 10 0 ticks 999 ticks # 100 9000 ticks 9999 ticks # # As noted by Kurt Garloff, it's necessary to adjust for large # loops_per_jiffies, as the multiplication of it with HZ fails for 4GHz or # larger. So, John Stultz suggested multiplying xloops with 4 first, and # multiplying with (HZ/4). # # Signed-off-by: Dominik Brodowski # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/lib/delay.c # 2004/06/18 00:32:10-07:00 linux@dominikbrodowski.de +3 -2 # mull'ify multiplication with HZ in __const_udelay() # # ChangeSet # 2004/06/18 08:11:35-07:00 neilb@cse.unsw.edu.au # [PATCH] Fix raid1 read_balancing code. # # The meaning of mddev->in_sync changed subtly a while ago, and raid1 wasn't # changed to match. This results in raid1 read_balancing not working # properly. This patch corrects the relevant test. # # Signed-off-by: Neil Brown # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/raid1.c # 2004/06/18 00:06:03-07:00 neilb@cse.unsw.edu.au +2 -1 # Fix raid1 read_balancing code. # # ChangeSet # 2004/06/18 08:11:24-07:00 alex@clusterfs.com # [PATCH] ext3: htree readdir fix # # I've observed that ext3_htree_fill_tree() doesn't ignore empty records # (de->inode == 0). test case is very simple: turn htree on, create several # hundreds of files, remove them and look at strace ls: # # [root@victim tests]# ls -a /test/1 # . .. # # [root@victim tests]# strace ls /test/1/ # .... # getdents64(3, /* 18 entries */, 4096) = 432 # getdents64(3, /* 0 entries */, 4096) = 0 # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/ext3/namei.c # 2004/06/18 00:06:03-07:00 alex@clusterfs.com +2 -0 # ext3: htree readdir fix # # ChangeSet # 2004/06/18 08:11:13-07:00 wli@holomorphy.com # [PATCH] fix isofs ignoring noexec and mode mount options # # * Removed period check for executables in fs/isofs/inode.c # This fixes Debian BTS #162190 # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=162190 # # From: Jan Gregor # To: Debian Bug Tracking System # Subject: kernel-source-2.4.18: kernel ignores noexec and mode option in cdrom case # Message-ID: <20020924162129.A328@pisidlo> # # In /etc/fstab i have following line: # /dev/cdrom /cdrom iso9660 gid=100,noauto,ro,noexec,mode=0444,user 0 0 # # I found on one CD that some files have exec bit set. From brief view # those files has no extension (filename.ext). # # My drive is asus-1610a (ATAPI writer) connected throught scsi-emulation. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/isofs/inode.c # 2004/06/18 00:06:03-07:00 wli@holomorphy.com +0 -8 # fix isofs ignoring noexec and mode mount options # # ChangeSet # 2004/06/18 08:11:04-07:00 wli@holomorphy.com # [PATCH] fix handling of '/' embedded in filenames in isofs # # * Fix slashes in broken Acorn ISO9660 images in fs/isofs/dir.c (Darren Salt) # This fixes Debian BTS #141660. # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=141660 # # From: Darren Salt # Message-ID: <4B238BA09A%linux@youmustbejoking.demon.co.uk> # To: submit@bugs.debian.org # Subject: Handle '/' in filenames in broken ISO9660 images # # [Also applicable to 2.2.x] # # There has been for some time a problem with certain CD-ROMs whose images # were generated using a particular tool on Acorn RISC OS. The problem is # that in certain catalogue entries, the extension separator character '/' # (RISC OS uses '.' and '/' the other way round) was not replaced with '.'; # thus Linux cannot properly parse this without this patch, thinking that it # is a directory separator. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/isofs/dir.c # 2004/06/18 00:06:03-07:00 wli@holomorphy.com +2 -1 # fix handling of '/' embedded in filenames in isofs # # ChangeSet # 2004/06/18 08:10:53-07:00 wli@holomorphy.com # [PATCH] fix duplicate environment variables passed to init # # * Fixed argument processing bug in init/main.c (Eric Delaunay) # This fixes Debian BTS #58566. # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=58566 # # From: Eric Delaunay # Message-Id: <200002201918.UAA02327@jazz.pontchartrain.fr> # Subject: pb in handling parameters on kernel command line # To: submit@bugs.debian.org (debian bug tracking system) # # Hello, I found some bugs in kernel command line parser. AFAIK, they are not # Debian nor sparc specific but I'm not subscribed to linux-kernel mailing list # and since I'm involved with boot-floppies (mainly for sparc), I think I'm right # to report it here. Feel free to forward it upstream (I checked the latest # 2.3.46 sources and it seems these bugs are still there). # # These bugs are not release critical. The latter just not gives the user a # chance to overwrite TERM env var at boot time. It could be just # inconvenient for serial console boot, and in this case, our busybox' init is # already enforcing TERM=vt102. # Nevertheless if it could not be fixed before the release, I could even write a # workaround in busybox' init (it's just a matter of rewriting getenv()). # # At last, it does not affect sysvinit package because serial console tty is # controlled by a getty process which is reading terminal settings on its command # line (take a look in inittab for T0 entries, if any). # # Ok, here is my modest contribution to kernel hacking. I don't know much about # kernel internals but it seems that argument parsing is a bit broken. # # One trivial patch for command line like "init=/bin/sh console=prom" where # console=prom is replaced by lot of spaces in previous call to setup_arch() on # sparc, therefore the line parsed by parse_options() is really # "init=/bin/sh " and a lot of null args are pushed into argv_init. # # The other patch is for command line like "TERM=vt100" where both default & user # TERM entries are pushed into the env array. # Taking a look into /proc/1/environ, it shows up: # HOME=/ # TERM=linux # TERM=vt100 # # It appears that ash (maybe other shells too) is giving the latter entry but # glibc getenv() is giving the former. It is therefore impossible to get entry # from the user in a C program like busybox' init (used in Debian boot-floppies). # # I guess getenv() is not written to support duplicate entries, therefore the # kernel should avoid such construct. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # init/main.c # 2004/06/18 00:06:03-07:00 wli@holomorphy.com +2 -0 # fix duplicate environment variables passed to init # # ChangeSet # 2004/06/18 08:10:43-07:00 wli@holomorphy.com # [PATCH] unregister driver if probing fails in sb_card.c # # * Unregister driver if probing fails in sound/oss/sb_card.c # This fixes Debian BTS #218845. # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=218845 # # From: Robin Gerard # To: submit@bugs.debian.org # Subject: no sound with kernel-image-2.6.0-test9-1-386 # Message-ID: <20031103004939.GA2071@mauritius> # # I downlaoded the kernel-image-2.6.0-test9-1-386_2.6.0-test9-1_i386.deb # and I installed it successfully. Everything works fine, except the sound. # (I run also the kernel-image-2.4.20 and the sound is ok with this kernel) # My sound card is a sb. # # First I launched modconf but no module was displayed. # # I did: modprobe sb # and I got: # # sb: Init: Done # sb: Init: Starting Probe... # kobject_register failed for OSS SndBlstr (-17) # Call Trace: # [] kobject_register+0x3a/0x40 # [] bus_add_driver+0x30/0x64 # [] driver_register+0x2d/0x34 # [] preempt_schedule+0x2a/0x48 # [] pnp_register_driver+0x28/0x58 # [] pnp_register_card_driver+0x5e/0x98 # [] sb_init+0x63/0xb5 [sb] # [] sys_init_module+0xe8/0x1f0 # [] syscall_call+0x7/0xb # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/oss/sb_card.c # 2004/06/18 00:06:03-07:00 wli@holomorphy.com +7 -1 # unregister driver if probing fails in sb_card.c # # ChangeSet # 2004/06/18 08:10:32-07:00 wli@holomorphy.com # [PATCH] lower priority of "too many keys" msg in atkbd.c # # From: "Jon Thackray" # # * Lowered priority of "too many keys" message in drivers/input/keyboard/atkbd.c # This fixes Debian BTS #239036. # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=239036 # # # The keyboard under 2.6.4 seems to be behaving strangely, reporting unknown # key codes and too many keys pressed, even when no keys have been pressed. # The keyboard is connected via an 8 way KVM switch, but was working quite # acceptably under 2.4.25 with no such messages. Trying 2.6.3 is not an # option as it doesn't support the hardware properly, as previously reported. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/input/keyboard/atkbd.c # 2004/06/18 00:48:49-07:00 wli@holomorphy.com +1 -1 # lower priority of "too many keys" msg in atkbd.c # # ChangeSet # 2004/06/18 08:10:21-07:00 rddunlap@osdl.org # [PATCH] istallion printk fix # # istallion: Remove duplicate "%d" in printk(); # # Signed-off-by: Randy Dunlap # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/char/istallion.c # 2004/06/18 00:06:03-07:00 rddunlap@osdl.org +1 -1 # istallion printk fix # # ChangeSet # 2004/06/18 08:10:10-07:00 egmont@uhulinux.hu # [PATCH] Shift+PgUp if nr of scrolled lines is < 4 # # Using the vga console driver, if the number of the lines scrolled out is # less than four, then Shift+PageUp doesn't work. # # The bug is closely related to the 'margin' feature of scrolling, which # means that if less than four lines should remain unvisible in the direction # we are scrolling to, then we scroll a little bit more just to see those few # lines. Kind of two small magnets at the borders of the buffer. # # This bug was also reported with maybe a less clear description by Stepan # Koltsov (cc'ed just for fun) back in 2001 and he got no answer. I found it # at http://seclists.org/lists/linux-kernel/2001/Nov/0080.html # # His patch simply disables margin support and hence everythings becomes # okay, but you lose a nice feature. # # Here's a patch that retains margin support and fixes the bug. Works for # me, tested for a week. No guarantee. As I don't fully understand the code # (see also my previous mail) I'm not 100% sure that I'm doing the right # thing, so I'd prefer if someone would take a closer look at it. # # At least 2.4 and 2.6 are affected, maybe older ones too. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/video/console/vgacon.c # 2004/06/18 00:06:02-07:00 egmont@uhulinux.hu +2 -0 # Shift+PgUp if nr of scrolled lines is < 4 # # ChangeSet # 2004/06/18 08:09:59-07:00 davidel@xmailserver.org # [PATCH] epoll: replace the file lookup hash with rbtrees # # The epoll allocation for the fd lookup hash used to allocate up to 1MB # (depending on the "hint" size passed to epoll_create()) with # __get_free_pages(0), and this might lead to a "malicious" user to do # something like: # # for (i = 0; i < 1024; i++) # epoll_create(BIG-NUM); # # You can replace "malicious user" with IBM-ltp test suite, and the meaning # does not change. The above code might exhaust memory badly, even before # the file creation limit is topped. Also, the allocation was independent # from the number of fds pushed into the epoll fd hash. Using an rb-tree # ther will be not pre-allocation of the hash, and the size of the memory # used will be proportional to the number of fds pushed into the epoll fd. # The patch also removes 100 lines of code, that is never a bad thing ;) # # Signed-off-by: Davide Libenzi # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/eventpoll.c # 2004/06/18 00:06:02-07:00 davidel@xmailserver.org +93 -187 # epoll: replace the file lookup hash with rbtrees # # ChangeSet # 2004/06/18 08:09:48-07:00 rtjohnso@eecs.berkeley.edu # [PATCH] drivers/char/ipmi/ipmi_devintf.c: user/kernel pointer typo # # Judging from context, I think there's a misplaced "&" in this code that can # cause stack overflows and other nasty problems. Perhaps it's left over # from when msgdata was an array instead of a pointer? # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/char/ipmi/ipmi_devintf.c # 2004/06/18 00:32:07-07:00 rtjohnso@eecs.berkeley.edu +1 -1 # drivers/char/ipmi/ipmi_devintf.c: user/kernel pointer typo # # ChangeSet # 2004/06/18 08:09:37-07:00 akpm@osdl.org # [PATCH] Make update_one_process() static # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/timer.c # 2004/06/17 23:59:01-07:00 akpm@osdl.org +1 -1 # Make update_one_process() static # # include/linux/sched.h # 2004/06/18 00:32:06-07:00 akpm@osdl.org +0 -2 # Make update_one_process() static # # ChangeSet # 2004/06/18 08:09:26-07:00 vandrove@vc.cvut.cz # [PATCH] Decrease stack usage in ncpfs's ioctl # # It decreases stack consumption in one of ncpfs's paths from 3000 to 2200 # bytes (and stack portion in ncpfs ioctl code from 1336 to 452 bytes). # # - some code used large structure (with embeded 256 bytes for filename) # while it never passed filename around. Use something smaller in # ncp_conn_logged_in. Decrease 616 => 300. # # - gcc-3.3 is very bad when it comes to parallel blocks in ioctl. Split # some branches from large switch to separate functions. ncp_ioctl now # uses 152 bytes of stack (instead of 720) and biggest child 64. # # Signed-off-by: Petr Vandrovec # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/ncpfs/ncplib_kernel.h # 2004/06/17 23:59:01-07:00 vandrove@vc.cvut.cz +5 -3 # Decrease stack usage in ncpfs's ioctl # # fs/ncpfs/ncplib_kernel.c # 2004/06/17 23:59:01-07:00 vandrove@vc.cvut.cz +27 -15 # Decrease stack usage in ncpfs's ioctl # # fs/ncpfs/ioctl.c # 2004/06/17 23:59:01-07:00 vandrove@vc.cvut.cz +160 -157 # Decrease stack usage in ncpfs's ioctl # # fs/ncpfs/dir.c # 2004/06/17 23:59:01-07:00 vandrove@vc.cvut.cz +5 -5 # Decrease stack usage in ncpfs's ioctl # # ChangeSet # 2004/06/18 08:09:16-07:00 herbert@gondor.apana.org.au # [PATCH] swsusp: remove copy_pagedir # # It can be replaced by a simple memcpy. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/power/swsusp.c # 2004/06/17 23:59:00-07:00 herbert@gondor.apana.org.au +3 -16 # swsusp: remove copy_pagedir # # kernel/power/pmdisk.c # 2004/06/17 23:59:00-07:00 herbert@gondor.apana.org.au +4 -16 # swsusp: remove copy_pagedir # # ChangeSet # 2004/06/18 08:09:05-07:00 herbert@gondor.apana.org.au # [PATCH] remove unnecessary memsets from swsusp and pmdisk # # Here's the patch that removes the memset calls from both pmdisk and swsusp. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/power/swsusp.c # 2004/06/18 00:32:12-07:00 herbert@gondor.apana.org.au +0 -1 # remove unnecessary memsets from swsusp and pmdisk # # kernel/power/pmdisk.c # 2004/06/18 00:32:12-07:00 herbert@gondor.apana.org.au +0 -1 # remove unnecessary memsets from swsusp and pmdisk # # ChangeSet # 2004/06/18 08:08:54-07:00 herbert@gondor.apana.org.au # [PATCH] omdisk memory leak fix # # Fix a couple of memory leaks in the pmdisk driver. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/power/pmdisk.c # 2004/06/18 00:32:13-07:00 herbert@gondor.apana.org.au +11 -11 # omdisk memory leak fix # # ChangeSet # 2004/06/18 08:08:43-07:00 pavel@ucw.cz # [PATCH] Fix memory leak in swsusp # # This fixes 2 memory leaks in swsusp: during relocating pagedir, eaten pages # were not properly freed in error path and even regular freeing path was # freeing one page too little. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/power/swsusp.c # 2004/06/18 00:32:13-07:00 pavel@ucw.cz +16 -11 # Fix memory leak in swsusp # # ChangeSet # 2004/06/18 08:08:32-07:00 axboe@suse.de # [PATCH] blk: move threshold unplugging # # The 'unplug on queued exceeding unplug threshold' logic only works for file # system requests currently, since it's in __make_request(). Move it where # it belongs, in elv_add_request(). This way it works for queued block sg # requests as well. # # Signed-Off-By: Jens Axboe # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/blkdev.h # 2004/06/18 08:08:26-07:00 axboe@suse.de +1 -0 # blk: move threshold unplugging # # drivers/block/ll_rw_blk.c # 2004/06/18 08:08:26-07:00 axboe@suse.de +4 -7 # blk: move threshold unplugging # # drivers/block/elevator.c # 2004/06/18 08:08:26-07:00 axboe@suse.de +8 -0 # blk: move threshold unplugging # # ChangeSet # 2004/06/18 08:08:21-07:00 axboe@suse.de # [PATCH] fix cdrom mt rainier probe # # Mt rainier probe must be deferred to media load time, since it requires a # valid media (the drive may present a different capability based on what # media is loaded). This fixes that for ide-cd and sr. # # Signed-Off-By: Jens Axboe # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/scsi/sr.c # 2004/06/18 08:08:15-07:00 axboe@suse.de +1 -15 # fix cdrom mt rainier probe # # drivers/ide/ide-cd.h # 2004/06/18 08:08:15-07:00 axboe@suse.de +0 -2 # fix cdrom mt rainier probe # # drivers/ide/ide-cd.c # 2004/06/18 08:08:15-07:00 axboe@suse.de +1 -22 # fix cdrom mt rainier probe # # drivers/cdrom/cdrom.c # 2004/06/18 08:08:15-07:00 axboe@suse.de +30 -2 # fix cdrom mt rainier probe # # ChangeSet # 2004/06/18 08:08:10-07:00 mikem@beardog.cca.cpqcorp.net # [PATCH] cciss ioctl32 update # # This patch provides a conversion routine for 32-bit user space apps that # call into a 64-bit kernel on x86_64 architectures. This is required for # the HP Array Configuration utility and the HP management agents. Without # this patch the apps will not function. # # The 2 ioctls affected are the cciss pass thru ioctls. Caveat: it spits out # 2 warnings during compilation. I've tried everything I can think of to # clean them up, but... If anyone has any helpful suggestions I'm all ears. # # Code by Stephen Cameron # Tested by Stephen Cameron & Mike Miller # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/cciss_ioctl.h # 2004/06/18 08:08:04-07:00 mikem@beardog.cca.cpqcorp.net +28 -0 # cciss ioctl32 update # # drivers/block/cciss.c # 2004/06/18 08:08:04-07:00 mikem@beardog.cca.cpqcorp.net +144 -0 # cciss ioctl32 update # # ChangeSet # 2004/06/18 08:07:59-07:00 andrea@suse.de # [PATCH] remap_file_pages() speedup # # Avoid taking down_write(mmap_sem) unless we really need it. # # Seems that the only reason we're taking it for writing is to protect # vma->vm_flags. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/fremap.c # 2004/06/17 23:58:59-07:00 andrea@suse.de +12 -5 # remap_file_pages() speedup # # ChangeSet # 2004/06/18 08:07:48-07:00 arun.sharma@intel.com # [PATCH] sys_getdents64 needs compat wrapper # # Due to different structure alignment rules in the ABI between ia32 and # ia64, certain members of the dirent structure are not guaranteed to be 8 # byte aligned on ia64. This requires a compat wrapper around these 32 bit # system calls. Other architectures may or may not have the problem, # depending on the alignment rules. # # This was observed by running /emul/ia32-linux/bin/ls on 2.6.6 which produces # kernel mode unaligned faults. # # Original patch by: Arnd Bergmann # Signed-off-by: Gordon Jin # Signed-off-by: Arun Sharma # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/compat.c # 2004/06/17 23:58:59-07:00 arun.sharma@intel.com +255 -0 # sys_getdents64 needs compat wrapper # # arch/ia64/ia32/ia32_entry.S # 2004/06/17 23:58:59-07:00 arun.sharma@intel.com +2 -2 # sys_getdents64 needs compat wrapper # # ChangeSet # 2004/06/18 08:07:37-07:00 tvignaud@mandrakesoft.com # [PATCH] checksatck.pl fixes # # - "\<" and "\>" can be safely replaced with "<" and ">" # # - "$var =~ /^string$/" is better written "$var eq 'string'" # # - $i is better written without the double quotes # # - it's not safe to use for without "my"ing the iteration variable # # - "print foreach @array" is better written "print @array" # # - declare variables # # - ".*" is useless at the end of a regexp # # - "$a[@a] = $foo" is a rather obfuscated syntax for "push @a, $foo"... # let's not opencoding language basic operators... # # - ignoring return value from a regexp is very bad: this can results in # working on previous value of $1, $2, ... # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # scripts/checkstack.pl # 2004/06/17 23:58:59-07:00 tvignaud@mandrakesoft.com +14 -15 # checksatck.pl fixes # # ChangeSet # 2004/06/18 08:07:26-07:00 ashok.raj@intel.com # [PATCH] don't create cpu/online sysfs file # # This file provides ability for caller of register_cpu() to either create a # control file, or not. This can be handy if a particular platform decides # that certain CPU's are not removable. Hence would like to not create a # control file. # # Signed-off-by: Dave Hansen # Signed-off-by: Ashok Raj # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/cpu.h # 2004/06/17 23:58:59-07:00 ashok.raj@intel.com +1 -0 # don't create cpu/online sysfs file # # drivers/base/cpu.c # 2004/06/17 23:58:59-07:00 ashok.raj@intel.com +3 -1 # don't create cpu/online sysfs file # # arch/ppc64/kernel/sysfs.c # 2004/06/17 23:58:59-07:00 ashok.raj@intel.com +10 -0 # don't create cpu/online sysfs file # # ChangeSet # 2004/06/18 08:07:15-07:00 umka@namesys.com # [PATCH] memory allocation checks in cs46xx_dsp_proc_register_scb_desc() # # Adds memory allocation checks in cs46xx_dsp_proc_register_scb_desc() # # Signed-off-by: Yury Umanets # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/pci/cs46xx/dsp_spos_scb_lib.c # 2004/06/17 23:57:06-07:00 umka@namesys.com +7 -1 # memory allocation checks in cs46xx_dsp_proc_register_scb_desc() # # ChangeSet # 2004/06/18 08:07:05-07:00 torque@ukrpost.net # [PATCH] memory allocation checks in mtdblock_open() # # Fixes memory allocation check in mtdblock_open() # # Signed-off-by: Yury Umanets # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/mtd/mtdblock.c # 2004/06/17 23:57:06-07:00 torque@ukrpost.net +1 -1 # memory allocation checks in mtdblock_open() # # ChangeSet # 2004/06/18 08:06:54-07:00 torque@ukrpost.net # [PATCH] memory allocation checks in eth1394_update() # # Adds memory allocation checks in eth1394_update(). # # Signed-off-by: Yury Umanets # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/ieee1394/eth1394.c # 2004/06/17 23:57:06-07:00 torque@ukrpost.net +4 -1 # memory allocation checks in eth1394_update() # # ChangeSet # 2004/06/18 08:06:43-07:00 ak@suse.de # [PATCH] Use numa policy API for boot time policy # # Suggested by Manfred Spraul. # # __get_free_pages had a hack to do node interleaving allocation at boot # time. This patch sets an interleave process policy using the NUMA API for # init and the idle threads instead. Before entering the user space init the # policy is reset to default again. Result is the same. # # Advantage is less code and removing of a check from a fast path. # # Removes more code than it adds. # # I verified that the memory distribution after boot is roughly the same. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/page_alloc.c # 2004/06/17 23:57:05-07:00 ak@suse.de +0 -41 # Use numa policy API for boot time policy # # mm/mempolicy.c # 2004/06/17 23:57:05-07:00 ak@suse.de +15 -3 # Use numa policy API for boot time policy # # init/main.c # 2004/06/18 00:32:11-07:00 ak@suse.de +4 -0 # Use numa policy API for boot time policy # # include/linux/mempolicy.h # 2004/06/17 23:57:05-07:00 ak@suse.de +11 -0 # Use numa policy API for boot time policy # # ChangeSet # 2004/06/18 08:06:32-07:00 wli@holomorphy.com # [PATCH] apic: make mach_default compile again # # While sweeping the APIC code two points were missed. The first is getting # the definition of BAD_APICID available to # include/asm-i386/mach-default/mach_apic.h by #including the right header, # and the second is UP local APIC without UP IO-APIC linking in # get_broadcast_physid(). # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/mach-default/mach_apic.h # 2004/06/17 23:56:25-07:00 wli@holomorphy.com +1 -0 # apic: make mach_default compile again # # arch/i386/kernel/io_apic.c # 2004/06/17 23:56:25-07:00 wli@holomorphy.com +0 -11 # apic: make mach_default compile again # # arch/i386/kernel/apic.c # 2004/06/17 23:56:25-07:00 wli@holomorphy.com +11 -0 # apic: make mach_default compile again # # ChangeSet # 2004/06/18 08:06:21-07:00 wli@holomorphy.com # [PATCH] apic: remove marking of non-present physids in phys_cpu_present_map # # Marking invalid APIC ID's in phys_cpu_present_map was intended to generate # "collisions" between APIC ID's in order to assist the ordinary bounds # checking against the broadcast physical APIC ID. However, this is bounds # checked everywhere it's necessary, and it's also not even possible to # properly bounds-check everywhere. So this patch removes that marking of # non-present physical APIC ID's. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/mach-visws/mpparse.c # 2004/06/17 23:56:23-07:00 wli@holomorphy.com +0 -8 # apic: remove marking of non-present physids in phys_cpu_present_map # # arch/i386/kernel/mpparse.c # 2004/06/17 23:56:23-07:00 wli@holomorphy.com +1 -13 # apic: remove marking of non-present physids in phys_cpu_present_map # # ChangeSet # 2004/06/18 08:06:09-07:00 wli@holomorphy.com # [PATCH] apic: fix kicking of non-present cpus # # The following patch repairs kicking of non-present cpus by making # cpu_present_to_apicid() bounds-check its argument. It also corrects the # same issue on NUMA-Q by correctly passing the generated artificial APIC ID # instead of the raw value discovered in the MP table. # # A miscellaneous compilefix for CONFIG_ACPI_BOOT is also included for # completeness. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/mach-visws/mach_apic.h # 2004/06/17 23:55:40-07:00 wli@holomorphy.com +4 -1 # apic: fix kicking of non-present cpus # # include/asm-i386/mach-default/mach_apic.h # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +4 -1 # apic: fix kicking of non-present cpus # # include/asm-i386/apic.h # 2004/06/17 23:55:40-07:00 wli@holomorphy.com +2 -0 # apic: fix kicking of non-present cpus # # arch/i386/kernel/mpparse.c # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +4 -4 # apic: fix kicking of non-present cpus # # arch/i386/kernel/io_apic.c # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +1 -1 # apic: fix kicking of non-present cpus # # ChangeSet # 2004/06/18 08:05:58-07:00 wli@holomorphy.com # [PATCH] APIC enumeration fixes # # The following patch appears sound according to an audit to ensure that all # of the codepaths where it was introduced were called after the APIC # fixmappings were set up. # # This patch introduces get_physical_broadcast(), which checks the version ID # of the local APIC to determine whether it's a serial APIC or xAPIC, and # returns the correct physical broadcast ID. It replaces all uses of # APIC_BROADCAST_ID and IO_APIC_MAX_ID with this in order to ensure. It also # changes the checks during MP table parsing so the APIC ID is checked in # tandem with the version number. # # I'm holding out for some kind of testing to get an idea of whether this # covers the cases or introduces regressions, or whatever. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/mpspec_def.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +1 -0 # APIC enumeration fixes # # include/asm-i386/mach-visws/mach_apic.h # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +0 -1 # APIC enumeration fixes # # include/asm-i386/mach-summit/mach_mpspec.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -5 # APIC enumeration fixes # # include/asm-i386/mach-summit/mach_apic.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -1 # APIC enumeration fixes # # include/asm-i386/mach-numaq/mach_mpspec.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -5 # APIC enumeration fixes # # include/asm-i386/mach-numaq/mach_apic.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -1 # APIC enumeration fixes # # include/asm-i386/mach-generic/mach_mpspec.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -5 # APIC enumeration fixes # # include/asm-i386/mach-generic/mach_apic.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -1 # APIC enumeration fixes # # include/asm-i386/mach-es7000/mach_mpspec.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -5 # APIC enumeration fixes # # include/asm-i386/mach-es7000/mach_apic.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -1 # APIC enumeration fixes # # include/asm-i386/mach-default/mach_mpspec.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -5 # APIC enumeration fixes # # include/asm-i386/mach-default/mach_apic.h # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +0 -6 # APIC enumeration fixes # # include/asm-i386/mach-bigsmp/mach_mpspec.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -5 # APIC enumeration fixes # # include/asm-i386/mach-bigsmp/mach_apic.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -1 # APIC enumeration fixes # # include/asm-i386/genapic.h # 2004/06/17 23:55:23-07:00 wli@holomorphy.com +0 -2 # APIC enumeration fixes # # arch/i386/mach-visws/mpparse.c # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +10 -2 # APIC enumeration fixes # # arch/i386/kernel/mpparse.c # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +30 -2 # APIC enumeration fixes # # arch/i386/kernel/io_apic.c # 2004/06/18 00:32:15-07:00 wli@holomorphy.com +18 -9 # APIC enumeration fixes # # ChangeSet # 2004/06/18 08:05:47-07:00 akpm@osdl.org # [PATCH] i386 uninline some bitops # # Uninline the non-leaf bit search functions. Saves 9 kbytes from my vmlinux. # # And gratuitously s/__inline__/inline/ # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/lib/bitops.c # 2004/06/17 23:55:22-07:00 akpm@osdl.org +70 -0 # i386 uninline some bitops # # include/asm-i386/bitops.h # 2004/06/17 23:55:22-07:00 akpm@osdl.org +27 -77 # i386 uninline some bitops # # arch/i386/lib/bitops.c # 2004/06/17 23:55:22-07:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/i386/lib/bitops.c # # arch/i386/lib/Makefile # 2004/06/17 23:55:22-07:00 akpm@osdl.org +2 -3 # i386 uninline some bitops # # ChangeSet # 2004/06/18 08:05:36-07:00 wli@holomorphy.com # [PATCH] x86_64 numa cpumask build fix # # arch/x86_64/mm/numa.c: In function `numa_initmem_init': # arch/x86_64/mm/numa.c:185: error: incompatible types in assignment # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/x86_64/mm/numa.c # 2004/06/17 23:53:45-07:00 wli@holomorphy.com +1 -1 # x86_64 numa cpumask build fix # # ChangeSet # 2004/06/18 08:05:25-07:00 tom.l.nguyen@intel.com # [PATCH] msi TARGET_CPUS fix # # Somehow the change in TARGET_CPUS generated this error in UP environment. # Patch below will fix it. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/msi.h # 2004/06/17 23:53:44-07:00 tom.l.nguyen@intel.com +1 -1 # msi TARGET_CPUS fix # # ChangeSet # 2004/06/18 08:05:14-07:00 kevcorry@us.ibm.com # [PATCH] dm: dm-raid1.c: Use list_for_each_entry_safe # # dm-raid1.c: In rh_exit(), use list_for_each_entry_safe instead of # list_for_each_safe. # # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-raid1.c # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +2 -4 # dm: dm-raid1.c: Use list_for_each_entry_safe # # ChangeSet # 2004/06/18 08:05:03-07:00 kevcorry@us.ibm.com # [PATCH] dm: dm-raid1.c: Make delayed_bios a bio_list # # dm-raid1.c: Make struct region::delayed_bios a bio_list instead of a bio*. # This will ensure the queued bios are kept in the proper order. # # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-raid1.c # 2004/06/18 00:32:16-07:00 kevcorry@us.ibm.com +7 -10 # dm: dm-raid1.c: Make delayed_bios a bio_list # # ChangeSet # 2004/06/18 08:04:52-07:00 kevcorry@us.ibm.com # [PATCH] dm: dm-io: Error handling # # dm-io: Proper error handling when someone is trying to read from multiple # regions. # # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-io.c # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +12 -2 # dm: dm-io: Error handling # # ChangeSet # 2004/06/18 08:04:41-07:00 kevcorry@us.ibm.com # [PATCH] dm: Use structure assignments instead of memcpy # # Use structure assignments instead of memcpy's. # [Suggested by akpm during kcopyd review.] # # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/kcopyd.c # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +2 -2 # dm: Use structure assignments instead of memcpy # # drivers/md/dm.c # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +1 -1 # dm: Use structure assignments instead of memcpy # # drivers/md/dm-table.c # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +2 -2 # dm: Use structure assignments instead of memcpy # # drivers/md/dm-snap.c # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +1 -1 # dm: Use structure assignments instead of memcpy # # drivers/md/dm-raid1.c # 2004/06/18 00:32:16-07:00 kevcorry@us.ibm.com +2 -2 # dm: Use structure assignments instead of memcpy # # ChangeSet # 2004/06/18 08:04:32-07:00 kevcorry@us.ibm.com # [PATCH] dm: Create/destroy kcopyd on demand. # # Create/destroy kcopyd on demand. # # This changes kcopyd to initialize its mempool and workqueue only when a # client specifically needs to use it. # # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/kcopyd.h # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +0 -3 # dm: Create/destroy kcopyd on demand. # # drivers/md/kcopyd.c # 2004/06/18 00:32:16-07:00 kevcorry@us.ibm.com +61 -27 # dm: Create/destroy kcopyd on demand. # # drivers/md/dm.h # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +0 -3 # dm: Create/destroy kcopyd on demand. # # drivers/md/dm.c # 2004/06/18 00:32:16-07:00 kevcorry@us.ibm.com +0 -1 # dm: Create/destroy kcopyd on demand. # # ChangeSet # 2004/06/18 08:04:21-07:00 kevcorry@us.ibm.com # [PATCH] dm: Documentation # # Device-Mapper documentation. # # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # Documentation/device-mapper/zero.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +37 -0 # dm: Documentation # # Documentation/device-mapper/striped.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +58 -0 # dm: Documentation # # Documentation/device-mapper/linear.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +61 -0 # dm: Documentation # # Documentation/device-mapper/kcopyd.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +47 -0 # dm: Documentation # # Documentation/device-mapper/dm-io.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +75 -0 # dm: Documentation # # Documentation/device-mapper/zero.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/device-mapper/zero.txt # # Documentation/device-mapper/striped.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/device-mapper/striped.txt # # Documentation/device-mapper/linear.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/device-mapper/linear.txt # # Documentation/device-mapper/kcopyd.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/device-mapper/kcopyd.txt # # Documentation/device-mapper/dm-io.txt # 2004/06/17 23:53:44-07:00 kevcorry@us.ibm.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/device-mapper/dm-io.txt # # ChangeSet # 2004/06/18 08:04:10-07:00 christophe@saout.de # [PATCH] Device-mapper: dm-zero flushing fix # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-zero.c # 2004/06/17 23:53:43-07:00 christophe@saout.de +2 -1 # Device-mapper: dm-zero flushing fix # # ChangeSet # 2004/06/18 08:03:59-07:00 kevcorry@us.ibm.com # [PATCH] dm: dm-zero version # # Add missing dm-zero version number. # # From: Alasdair Kergon # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-zero.c # 2004/06/18 00:32:17-07:00 kevcorry@us.ibm.com +1 -0 # dm: dm-zero version # # ChangeSet # 2004/06/18 08:03:48-07:00 agk@redhat.com # [PATCH] Device-mapper: dm-zero # # Add dm-zero target # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-zero.c # 2004/06/18 00:32:17-07:00 agk@redhat.com +96 -0 # Device-mapper: dm-zero # # drivers/md/dm-zero.c # 2004/06/18 00:32:17-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-zero.c # # drivers/md/Makefile # 2004/06/17 23:53:43-07:00 agk@redhat.com +1 -0 # Device-mapper: dm-zero # # drivers/md/Kconfig # 2004/06/17 23:53:43-07:00 agk@redhat.com +7 -0 # Device-mapper: dm-zero # # ChangeSet # 2004/06/18 08:03:37-07:00 agk@redhat.com # [PATCH] Device-mapper: mirroring # # Add mirror target. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-raid1.c # 2004/06/18 00:32:16-07:00 agk@redhat.com +1283 -0 # Device-mapper: mirroring # # drivers/md/dm-log.h # 2004/06/17 23:53:43-07:00 agk@redhat.com +124 -0 # Device-mapper: mirroring # # drivers/md/dm-log.c # 2004/06/17 23:53:43-07:00 agk@redhat.com +629 -0 # Device-mapper: mirroring # # drivers/md/dm-raid1.c # 2004/06/18 00:32:16-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-raid1.c # # drivers/md/dm-log.h # 2004/06/17 23:53:43-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-log.h # # drivers/md/dm-log.c # 2004/06/17 23:53:43-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-log.c # # drivers/md/Makefile # 2004/06/18 00:32:17-07:00 agk@redhat.com +2 -0 # Device-mapper: mirroring # # drivers/md/Kconfig # 2004/06/18 00:32:17-07:00 agk@redhat.com +7 -0 # Device-mapper: mirroring # # ChangeSet # 2004/06/18 08:03:25-07:00 kevcorry@us.ibm.com # [PATCH] dm: Fix error cleanup in dm_create_persistent() # # dm-exception-store.c: Fix error cleanup in dm_create_persistent(). # This was originally found by chrisw during code review. # # From: Dave Olien # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-exception-store.c # 2004/06/17 23:53:43-07:00 kevcorry@us.ibm.com +2 -2 # dm: Fix error cleanup in dm_create_persistent() # # ChangeSet # 2004/06/18 08:03:15-07:00 agk@redhat.com # [PATCH] Device-mapper: snapshots # # Add snapshot target # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-snap.h # 2004/06/17 23:53:43-07:00 agk@redhat.com +161 -0 # Device-mapper: snapshots # # drivers/md/dm-snap.c # 2004/06/18 00:32:16-07:00 agk@redhat.com +1213 -0 # Device-mapper: snapshots # # drivers/md/dm-snap.h # 2004/06/17 23:53:43-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-snap.h # # drivers/md/dm-snap.c # 2004/06/18 00:32:16-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-snap.c # # drivers/md/dm-exception-store.c # 2004/06/18 00:32:17-07:00 agk@redhat.com +648 -0 # Device-mapper: snapshots # # drivers/md/Makefile # 2004/06/18 00:32:17-07:00 agk@redhat.com +2 -0 # Device-mapper: snapshots # # drivers/md/Kconfig # 2004/06/18 00:32:17-07:00 agk@redhat.com +6 -0 # Device-mapper: snapshots # # drivers/md/dm-exception-store.c # 2004/06/18 00:32:17-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-exception-store.c # # ChangeSet # 2004/06/18 08:03:03-07:00 kevcorry@us.ibm.com # [PATCH] kcopyd commentary # # We're also working on some general documentation which will go in # Documentation/device-mapper and will include more detailed information # about the core driver and the other sub-modules. We'll try to submit those # patches in the near future. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/kcopyd.h # 2004/06/18 00:32:16-07:00 kevcorry@us.ibm.com +4 -0 # kcopyd commentary # # drivers/md/kcopyd.c # 2004/06/18 00:32:16-07:00 kevcorry@us.ibm.com +4 -0 # kcopyd commentary # # ChangeSet # 2004/06/18 08:02:55-07:00 kevcorry@us.ibm.com # [PATCH] dm: kcopyd: No need to lock pages # # No need to lock kcopyd pages. # # From: Alasdair Kergon # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/kcopyd.c # 2004/06/18 00:32:18-07:00 kevcorry@us.ibm.com +0 -2 # dm: kcopyd: No need to lock pages # # ChangeSet # 2004/06/18 08:02:44-07:00 kevcorry@us.ibm.com # [PATCH] dm: kcopyd: remove superfluous INIT_LIST_HEADs # # Remove superfluous kcopyd INIT_LIST_HEAD. # # From: Alasdair Kergon # Signed-off-by: Kevin Corry # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/kcopyd.c # 2004/06/18 00:32:18-07:00 kevcorry@us.ibm.com +0 -4 # dm: kcopyd: remove superfluous INIT_LIST_HEADs # # ChangeSet # 2004/06/18 08:02:33-07:00 agk@redhat.com # [PATCH] Device-mapper: kcopyd # # Add kcopyd - a daemon for copying regions of block devices around in an # efficient manner. Multiple destinations can be specified for a copy. # Designed to perform well both with many small chunks or few large chunks. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/kcopyd.h # 2004/06/18 00:32:18-07:00 agk@redhat.com +41 -0 # Device-mapper: kcopyd # # drivers/md/kcopyd.c # 2004/06/18 00:32:18-07:00 agk@redhat.com +667 -0 # Device-mapper: kcopyd # # drivers/md/kcopyd.h # 2004/06/18 00:32:18-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/kcopyd.h # # drivers/md/kcopyd.c # 2004/06/18 00:32:18-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/kcopyd.c # # drivers/md/dm.h # 2004/06/18 00:32:16-07:00 agk@redhat.com +3 -0 # Device-mapper: kcopyd # # drivers/md/dm.c # 2004/06/18 00:32:16-07:00 agk@redhat.com +1 -0 # Device-mapper: kcopyd # # drivers/md/Makefile # 2004/06/18 00:32:17-07:00 agk@redhat.com +1 -1 # Device-mapper: kcopyd # # ChangeSet # 2004/06/18 08:02:21-07:00 agk@redhat.com # [PATCH] dm-io: device-mapper i/o library for kcopyd # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/md/dm-io.h # 2004/06/17 23:53:42-07:00 agk@redhat.com +77 -0 # dm-io: device-mapper i/o library for kcopyd # # mm/mempool.c # 2004/06/17 23:53:42-07:00 agk@redhat.com +0 -6 # dm-io: device-mapper i/o library for kcopyd # # drivers/md/dm-io.h # 2004/06/17 23:53:42-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-io.h # # drivers/md/dm-io.c # 2004/06/18 00:32:16-07:00 agk@redhat.com +637 -0 # dm-io: device-mapper i/o library for kcopyd # # drivers/md/Makefile # 2004/06/18 00:32:18-07:00 agk@redhat.com +1 -1 # dm-io: device-mapper i/o library for kcopyd # # drivers/md/dm-io.c # 2004/06/18 00:32:16-07:00 agk@redhat.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/md/dm-io.c # # ChangeSet # 2004/06/18 08:02:10-07:00 bogdan.costescu@iwr.uni-heidelberg.de # [PATCH] 3c59x: support for ATI Radeon 9100 IGP # # The following patch adds support for the 3Com networking core found in the # ATI Radeon 9100 IGP southbridge used on boards like Asus P4R800-VM. # # The main point of this patch is using HAS_MII instead of HAS_NWAY for the # definition of the board. All the previous trials since the end of last # year used HAS_NWAY which disables the Tx part of the transceiver; using # HAS_NWAY was the way all 3Com Cyclone and Tornado chips worked, as they had # the transceiver integrated. The ATI solution has an external transceiver # and I had to physically see the different chip on the board (the board was # provided by ATI) to finally understand that it needs the HAS_MII # definition... I'm still waiting for some docs from ATI to clarify if this # is the correct way of handling this chip and if there are any differences # w.r.t EEPROM handling, but as it appears to work and was also confirmed by # other testers, I don't want to keep owners of such boards away from their # networks :-) # # The textual identification was a bit hard to decide; it's called # "3c920B-EMB-WNM" in the Windows .INF file that Asus provides for their # boards. As this name was already used for PCI ID 9210, I added the # paranthesis which specifies where this chip is found. # # The Scyld driver defines FEATURE_TORNADO to include HAS_NWAY. This board # would then probably need to not be defined with FEATURE_TORNADO, but the # same as in this patch. # # I would like to publicly thank Tyson Vickers for both ideas and patience # during the last few weeks. He managed to get the driver working by # randomly setting driver parameters :-) But then he contacted me and worked # with me towards the solution. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/net/3c59x.c # 2004/06/17 23:53:42-07:00 bogdan.costescu@iwr.uni-heidelberg.de +8 -4 # 3c59x: support for ATI Radeon 9100 IGP # # ChangeSet # 2004/06/18 08:01:58-07:00 thomas@winischhofer.net # [PATCH] sisfb update 1.7.10 # # attached is an update for the sisfb driver to version 1.7.10. # # This update includes # # - fixes for pure 64bit and 32/64bit mixed systems (add ioctl conversion; # fix variable sizes, etc; REQUIRED for current X.org/XFree86 on 64bit # systems, even if pure 64bit), # # - fixes for 301C video bridge, (scales TV output correctly now) # # - fixes for 1600x1200 and 1400x1050 LCD panels, # # - many fixes for 661/741/760 (amongst others, proper LFB support for the # 760 and corrections for SiS' new BIOS data layout; would lead to display # corruption with old driver) # # - add support for many modes for LCD which were unsupported previously, # # - add support for HiVision and YPbPr HDTV # # - "vga=" statement now honoured properly (sisfb will set the same mode as # the kernel did by default) # # - use LCD native resolution mode if no mode is given # # - a major clean up of main driver code, # # - radical removal of duplicate (or nearly duplicate) code, # # - switched to 2.6 module_param macros, # # - enhanced communication with the X driver, # # - added eventual POSTing of SiS300/305 card for non-x86 archs, # # - added ability to relocate the image on the TV screen using a userland # tool, # # - added Documentation/fb/sisfb.txt (why the heck was this missing?!) # # - small fix for SiS DRM driver (match 32/64bit fixes mentioned above) # (cast the data passed to sis_free as u32) # # - make driver re-entrant by avoiding static structures and variables. # # As usual, heavily tested. The mode switching code is even lab-tested by # SiS (although 100% written by me). Please apply asap (especially since # 64bit systems were not properly supported previously; as mentioned, current # X.org/XFree86 needs this update for proper communication with the # framebuffer driver on 64bit systems. X crashes on such systems with the # old driver). # # Signed-off-by: Thomas Winischhofer # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/video/sisfb.h # 2004/06/17 23:53:42-07:00 thomas@winischhofer.net +80 -171 # sisfb update 1.7.10 # # drivers/video/sis/vstruct.h # 2004/06/17 23:53:42-07:00 thomas@winischhofer.net +58 -100 # sisfb update 1.7.10 # # drivers/video/sis/vgatypes.h # 2004/06/17 23:53:42-07:00 thomas@winischhofer.net +62 -103 # sisfb update 1.7.10 # # drivers/video/sis/sis_main.h # 2004/06/17 23:53:42-07:00 thomas@winischhofer.net +365 -704 # sisfb update 1.7.10 # # drivers/video/sis/sis_main.c # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +3762 -3016 # sisfb update 1.7.10 # # drivers/video/sis/sis_accel.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +140 -264 # sisfb update 1.7.10 # # drivers/video/sis/sis_accel.c # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +188 -187 # sisfb update 1.7.10 # # drivers/video/sis/sis.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +497 -2 # sisfb update 1.7.10 # # drivers/video/sis/osdef.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +45 -65 # sisfb update 1.7.10 # # drivers/video/sis/oem310.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +32 -196 # sisfb update 1.7.10 # # drivers/video/sis/oem300.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +3 -5 # sisfb update 1.7.10 # # drivers/video/sis/initdef.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +85 -37 # sisfb update 1.7.10 # # drivers/video/sis/init301.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +132 -60 # sisfb update 1.7.10 # # drivers/video/sis/init.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +198 -607 # sisfb update 1.7.10 # # drivers/video/sis/init.c # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +961 -1060 # sisfb update 1.7.10 # # Documentation/fb/sisfb.txt # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +158 -0 # sisfb update 1.7.10 # # drivers/video/sis/init301.c # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +3425 -4113 # sisfb update 1.7.10 # # drivers/video/sis/310vtbl.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +507 -1122 # sisfb update 1.7.10 # # drivers/video/sis/300vtbl.h # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +346 -458 # sisfb update 1.7.10 # # drivers/char/drm/sis_mm.c # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +2 -2 # sisfb update 1.7.10 # # Documentation/ioctl-number.txt # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +2 -0 # sisfb update 1.7.10 # # Documentation/fb/sisfb.txt # 2004/06/17 23:53:41-07:00 thomas@winischhofer.net +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/fb/sisfb.txt # # ChangeSet # 2004/06/18 08:01:45-07:00 paul@serice.net # [PATCH] iso9660: NFS fix # # Make all inode numbers unique for images less than 128GB in size. Required # for knfsd. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/iso_fs.h # 2004/06/17 23:53:41-07:00 paul@serice.net +6 -12 # iso9660: NFS fix # # fs/isofs/inode.c # 2004/06/18 00:32:11-07:00 paul@serice.net +4 -2 # iso9660: NFS fix # # fs/isofs/dir.c # 2004/06/18 00:32:11-07:00 paul@serice.net +12 -3 # iso9660: NFS fix # # ChangeSet # 2004/06/18 08:01:34-07:00 paul@serice.net # [PATCH] iso9660: fix handling of inodes beyond 4GB # # This is my fourth attempt to patch the isofs code. It is similar to the last # posting except this one implements the NFS get_parent() method which has # always been missing. # # The original problem I set out to addresses is that the current iso9660 file # system cannot reach inodes located beyond the 4GB barrier. This is caused by # using the inode number as the byte offset of the inode data. Being 32-bits # wide, the inode number is unable to reach inode data that does not reside on # the first 4GB of the file system. # # This causes real problems with "growisofs" # # http://fy.chalmers.se/~appro/linux/DVD+RW/#isofs4gb # # and my pet project "shunt" # # http://www.serice.net/shunt/ # # This patch switches the isofs code from iget() to iget5_locked() which allows # extra data to be passed into isofs_read_inode() so that inode data anywhere on # the disk can be reached. # # The inode number scheme was also changed. Continuing to use the byte offset # would have resulted in non-unique inodes in many common situations, but # because the inode number no longer plays any role in reading the meta-data off # the disk, I was free to set the inode number to some unique characteristic of # the file. I have chosen to use the block offset which is also 32-bits wide. # # Lastly, the pre-patch code uses the default export_operations to handle # accessing the file system through NFS. The problem with this is that the # default NFS operations assume that iget() works which is no longer the case # because of the necessity of switching to iget5_locked(). So, I had to # implement the NFS operations too. As a bonus, I went ahead and implemented # the NFS get_parent() method which has always been missing. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/isofs/export.c # 2004/06/17 23:53:41-07:00 paul@serice.net +228 -0 # iso9660: fix handling of inodes beyond 4GB # # include/linux/iso_fs_i.h # 2004/06/17 23:53:41-07:00 paul@serice.net +4 -1 # iso9660: fix handling of inodes beyond 4GB # # include/linux/iso_fs.h # 2004/06/18 00:32:20-07:00 paul@serice.net +66 -0 # iso9660: fix handling of inodes beyond 4GB # # fs/isofs/rock.c # 2004/06/17 23:53:41-07:00 paul@serice.net +7 -8 # iso9660: fix handling of inodes beyond 4GB # # fs/isofs/namei.c # 2004/06/17 23:53:41-07:00 paul@serice.net +21 -9 # iso9660: fix handling of inodes beyond 4GB # # fs/isofs/inode.c # 2004/06/18 00:32:20-07:00 paul@serice.net +104 -53 # iso9660: fix handling of inodes beyond 4GB # # fs/isofs/export.c # 2004/06/17 23:53:41-07:00 paul@serice.net +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/fs/isofs/export.c # # fs/isofs/dir.c # 2004/06/18 00:32:20-07:00 paul@serice.net +3 -3 # iso9660: fix handling of inodes beyond 4GB # # fs/isofs/Makefile # 2004/06/17 23:53:41-07:00 paul@serice.net +1 -1 # iso9660: fix handling of inodes beyond 4GB # # ChangeSet # 2004/06/18 08:01:23-07:00 tim@physik3.uni-rostock.de # [PATCH] BSD accounting format rework # # BSD accounting format rework: # # Use all explicit and implicit padding in struct acct to # # - correctly report 32 bit uid/gid, # - correctly report jobs (e.g., daemons) running longer than 497 days, # - increase the precision of ac_etime from 2^-13 to 2^-20 # (i.e., from ~6 hours to ~1 min. after a year) # - store the current AHZ value. # - allow cross-platform processing of the accounting file # (limited for m68k which has a different size struct acct). # - introduce versioning for smooth transition to incompatible formats in # the future. Currently the following version numbers are defined: # 0: old format (until 2.6.7) with 16 bit uid/gid # 1: extended variant (binary compatible to v0 on M68K) # 2: extended variant (binary compatible to v0 on everything except M68K) # 3: a new binary incompatible format (64 bytes) # 4: new binary incompatible format (128 bytes). # layout of its first 64 bytes is the same as for v3. # 5: marks second half of new binary incompatible format (128 bytes) # (layout is not yet defined) # # All this is accomplished without breaking binary compatibility. 32 bit # uid/gid support is compatible with the patch previously floating around and # used e.g. by Red Hat. # # This patch also introduces a config option for a new, binary incompatible # "version 3" format that # # - is uniform across and properly aligned on all platforms # - stores pid and ppid # - uses AHZ==100 on all platforms (allows to report longer times) # # Much of the compatibility glue goes away when v1/v2 support is removed from # the kernel. Such a patch is at # # http://www.physik3.uni-rostock.de/tim/kernel/2.7/acct-cleanup-04.patch # # and might be applied in the 2.7 timeframe. # # The new v3 format is source compatible with current GNU acct tools (6.3.5). # However, current GNU acct tools can be compiled for only one format. As there # is no way to pass the kernel configuration to userspace, with my patch it will # still only support the old v2 format. Only if v1/v2 support is removed from # the kernel, recompiling GNU acct tools will yield v3 support. # # A preliminary take at the corresponding work on cross-platform userspace tools # (GNU acct package) is at # # http://www.physik3.uni-rostock.de/tim/kernel/utils/acct/ # # This version of the package is able to read any of the v0/v2/v3 formats, # regardless of byte-order (untested), even within the same file. # Cross-platform compatibility with m68k (v1 format) is not yet implemented, but # native use on m68k should work (untested). pid and ppid are currently only # shown by the dump-acct utility. # # Thanks to Arthur Corliss, Albert Cahalan and Ragnar Kjørstad for their # comments, and to Albert Cahalan for the u64->IEEE float conversion code. # # Signed-off-by: Tim Schmielau # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/acct.c # 2004/06/17 23:53:41-07:00 tim@physik3.uni-rostock.de +97 -8 # BSD accounting format rework # # init/Kconfig # 2004/06/17 23:53:41-07:00 tim@physik3.uni-rostock.de +12 -0 # BSD accounting format rework # # include/linux/acct.h # 2004/06/17 23:53:41-07:00 tim@physik3.uni-rostock.de +120 -25 # BSD accounting format rework # # ChangeSet # 2004/06/18 08:01:12-07:00 alan@redhat.com # [PATCH] make the 3c59x/3c90x driver somewhat more reliable # # The existing driver violates basic PCI rules in several places making it # unusable for basic things like DHCP in Fedora Core. This patch removes all # the situations I can find where it writes to the device while in D3 state # and breaks stuff. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/net/3c59x.c # 2004/06/18 00:32:18-07:00 alan@redhat.com +34 -9 # make the 3c59x/3c90x driver somewhat more reliable # # ChangeSet # 2004/06/18 08:01:01-07:00 bwindle@fint.org # [PATCH] fix 3c59x.c to allow 3c905c 100bT-FD # # Fix the 3c905C 10/100 transceiver initialisation woes. # # (This was reverted from 2.6.7-rcX, but the bug reporter said the failure # turned out to be unrepeatable). # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/net/3c59x.c # 2004/06/18 00:32:20-07:00 bwindle@fint.org +1 -1 # fix 3c59x.c to allow 3c905c 100bT-FD # # ChangeSet # 2004/06/18 08:00:52-07:00 joris@eljakim.nl # [PATCH] Validate PM-Timer rate at boot time # # Add a check to the PM-Timer initialization code. It validates the PM-Timer # rate against PIT channel 2 and rejects the PM-Timer if its rate is not # withing 5% of the expected number. # # Rationale: # # The PMTMR timers of certain (older) mainboards are running at invalid # rates, often much faster than the rate expected by the PM-Timer code. This # causes the system clock to run much too fast. See also # http://bugme.osdl.org/show_bug.cgi?id=2375 # # Possible workarounds are disabling the PM-Timer in the kernel config or # disabling the PM-Timer at boot time through the "clock=tsc" parameter. # However, we believe it is more user friendly to automatically validate the # PM-Timer rate at boot time before using it as the system time source. # # Tested by me (with broken timer) and John Stultz (with good timer) and # believed to be ok. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/timers/timer_pm.c # 2004/06/17 23:53:40-07:00 joris@eljakim.nl +38 -0 # Validate PM-Timer rate at boot time # # ChangeSet # 2004/06/18 08:00:41-07:00 willy@debian.org # [PATCH] ahc1542 !CONFIG_MCA build fix # # The old 1542 scsi driver is both ISA and MCA. The MCA portions are disabled # when !CONFIG_MCA through the typical wrapper scheme (a la pci.h and # !CONFIG_PCI). However... the driver unconditionally includes linux/mca.h # which in turn unconditionally includes asm/mca.h. # # This breaks drivers on platforms with ISA but not MCA, like alpha. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/mca.h # 2004/06/17 23:53:40-07:00 willy@debian.org +2 -0 # ahc1542 !CONFIG_MCA build fix # # ChangeSet # 2004/06/18 08:00:30-07:00 mingo@elte.hu # [PATCH] x86: remove io_apic_sync # # The patch below gets rid of io_apic_sync(). # # io_apic_sync() was introduced in 2.1.104 and it was originally done for # masking and unmasking as well. Later the unmasking use got removed but the # masking use lingered around. I dont think it was ever justified to do it # and clearly since the lack of io_apic_sync() didnt break some of the other # writes we do to the IO-APIC registers, it must be unnecessary in the # masking case too. # # Signed-off-by: Ingo Molnar # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-i386/io_apic.h # 2004/06/17 23:49:30-07:00 mingo@elte.hu +0 -9 # x86: remove io_apic_sync # # arch/i386/kernel/io_apic.c # 2004/06/18 00:32:15-07:00 mingo@elte.hu +0 -3 # x86: remove io_apic_sync # # ChangeSet # 2004/06/18 08:00:20-07:00 mingo@elte.hu # [PATCH] x86: remove APIC_LOCKUP_DEBUG # # the patch below gets rid of APIC_LOCKUP_DEBUG. It has been in the kernel # for more than 3 years and the message was only reported once during that # period of time - and even in that case it was a side-effect of a really bad # crash. The lockup workaround works, the debugging code can be moved out. # # Signed-off-by: Ingo Molnar # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/io_apic.c # 2004/06/18 00:32:21-07:00 mingo@elte.hu +0 -21 # x86: remove APIC_LOCKUP_DEBUG # # ChangeSet # 2004/06/18 08:00:09-07:00 pavel@ucw.cz # [PATCH] io_apic.c code consolidation # # This cleans up io_apic.c a bit -- I do not really like 4 copies of same # code. # # Ingo said: # # yeah, agreed - i checked & test it, it's ok. I made a small # modification (see the patch below) to uninline the __modify_IO_APIC_irq() # function - shaving 0.5K off the kernel's size. # # Signed-off-by: Ingo Molnar # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/io_apic.c # 2004/06/18 00:32:21-07:00 pavel@ucw.cz +16 -51 # io_apic.c code consolidation # # ChangeSet # 2004/06/18 07:59:58-07:00 nickpiggin@yahoo.com.au # [PATCH] Fix read() vs truncate race # # do_generic_mapping_read() # { # isize1 = i_size_read(); # ... # readpage # copy_to_user up to isize1; # } # # readpage() # { # isize2 = i_size_read(); # ... # read blocks # ... # zero-fill all blocks past isize2 # } # # If a second thread runs truncate and shrinks i_size, so isize1 and isize2 are # different, the read can return up to a page of zero-fill that shouldn't really # exist. # # The trick is to read isize1 after doing the readpage. I realised this is the # right way to do it without having to change the readpage API. # # The patch should not cost any cycles when reading from pagecache. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/filemap.c # 2004/06/18 00:32:09-07:00 nickpiggin@yahoo.com.au +50 -26 # Fix read() vs truncate race # # ChangeSet # 2004/06/18 07:59:47-07:00 akpm@osdl.org # [PATCH] invalidate_inodes2(): mark pages not uptodate # # Andrea Arcangeli points out that invalidate_inode_pages2() is # supposed to mark mapped-into-pagetable pages as not uptodate so that next time # someone faults the page in we will go get a new version from backing store. # # The callers are the direct-io code and the NFS "something changed on the # server" code. In both these cases we do need to go and re-read the page. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/truncate.c # 2004/06/17 23:49:30-07:00 akpm@osdl.org +8 -2 # invalidate_inodes2(): mark pages not uptodate # # ChangeSet # 2004/06/18 07:59:36-07:00 herbert@gondor.apana.org.au # [PATCH] Check return status of register calls in i82365 # # i82365 calls driver_register and platform_device_register without checking # their return values. This patch fixes that. # # It also runs platform_device_register() prior to isa_probe() so we don't have # to undo ise_probe()'s effects if platform_device_register() ends up failing. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/pcmcia/i82365.c # 2004/06/17 23:49:30-07:00 herbert@gondor.apana.org.au +10 -4 # Check return status of register calls in i82365 # # ChangeSet # 2004/06/18 07:59:25-07:00 tol@stacken.kth.se # [PATCH] getgroups16() fix # # sys_getgroups16 (or rather groups16_to_user()) returns large gids # truncated. Needs to be fixed, one way or another. Don't know why the # other similar casts are still there. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/uid16.c # 2004/06/17 23:49:29-07:00 tol@stacken.kth.se +6 -6 # getgroups16() fix # # include/linux/sched.h # 2004/06/18 00:32:12-07:00 tol@stacken.kth.se +9 -1 # getgroups16() fix # # ChangeSet # 2004/06/18 07:59:14-07:00 rene.herman@keyaccess.nl # [PATCH] same small resource tweaks, x86_64 version # # The same small tweaks for x86_64. Just to keep the two in sync. One # additional wrinkle: vram_resource was exported to e820.c, which didn't # actually use it. Undo that. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/x86_64/kernel/setup.c # 2004/06/17 23:49:29-07:00 rene.herman@keyaccess.nl +11 -9 # same small resource tweaks, x86_64 version # # arch/x86_64/kernel/e820.c # 2004/06/17 23:49:29-07:00 rene.herman@keyaccess.nl +1 -1 # same small resource tweaks, x86_64 version # # ChangeSet # 2004/06/18 07:59:03-07:00 rene.herman@keyaccess.nl # [PATCH] small tweaks to standard resource stuff # # Various small tweaks. Compiled and booted. # # 1. add IORESOURCE_BUSY | IORESOURCE_MEM also for the kernel code and # data resources. I don't believe this actually matters one bit, but # they're hooked into a BUSY/MEM parent ("System RAM") and marking # them busy seems to make sense. # # 2. delete the .start = 1M default for the kernel code resource. This # isn't actually a change; it's set to virt_to_phys(_text) in # setup_arch() overriding any default anyways. # # 3. s/vram_resource/video_ram_resource/. Lines up much nicer with # video_rom_resource... # # 4. s/checksum/romchecksum/. setup.c is a fairly large file, and # "checksum" pollutes the namespace. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/setup.c # 2004/06/17 23:49:29-07:00 rene.herman@keyaccess.nl +11 -9 # small tweaks to standard resource stuff # # ChangeSet # 2004/06/18 07:58:52-07:00 hpa@zytor.com # [PATCH] Use first-fit for pty allocation # # (With Andrew Morton). # # The current dynamic pty allocation scheme has a few problems: # # - pty numbers grow to be very large, causing wtmp file bloat. # # - Seems to break libc5 and some old applications # # So change it to do first-fit. An IDR tree is used to provide a # logarithmic-time search. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/char/tty_io.c # 2004/06/17 23:49:29-07:00 hpa@zytor.com +64 -19 # Use first-fit for pty allocation # # ChangeSet # 2004/06/18 07:58:40-07:00 tytso@mit.edu # [PATCH] Ext3: Retry allocation after transaction commit (v2) # # Here is a reworked version of my patch to ext3 to retry certain filesystem # operations after an ENOSPC error. The ext3_should_retry_alloc() function will # not wait on the currently running transaction if there is a currently active # handle; hence this should avoid deadlocks in the Lustre use case. The patch # is versus BK-recent. # # I've also included a simple, reliable test case which demonstrates the problem # this patch is intended to fix. (Note that BK-recent is not sufficient to # address this test case, and waiting on the commiting transaction in # ext3_new_block is also not sufficient. Been there, tried that, didn't work. # We need to do the full-bore retry from the top level. The # ext3_should_retry_alloc() will only wait on the committing transaction if # there is an active handle; hence Lustre will probably also need to use # ext3_should_retry_alloc() if it wants to reliably avoid this particular # problem.) # # #!/bin/sh # # # # # TEST_DIR=/tmp # IMAGE=$TEST_DIR/retry.img # MNTPT=$TEST_DIR/retry.mnt # TEST_SRC=/usr/projects/e2fsprogs/e2fsprogs/build # MKE2FS_OPTS="" # IMAGE_SIZE=8192 # # umount $MNTPT # dd if=/dev/zero of=$IMAGE bs=4k count=$IMAGE_SIZE # mke2fs -j -F $MKE2FS_OPTS $IMAGE # # function test_log () # { # echo $* # logger -p local4.notice $* # } # # mkdir -p $MNTPT # mount -o loop -t ext3 $IMAGE $MNTPT # test_log Retry test: BEGIN # for i in `seq 1 3` # do # test_log "Retry test: Loop $i" # echo 2 > /proc/sys/fs/jbd-debug # while ! mkdir -p $MNTPT/foo/bar # do # test_log "Retry test: mkdir failed" # sleep 1 # done # echo 0 > /proc/sys/fs/jbd-debug # cp -r $TEST_SRC $MNTPT/foo/bar 2> /dev/null # rm -rf $MNTPT/* # done # umount $MNTPT # test_log "Retry test: END" # # # akpm@osdl.org # # Rework the code to make it a formal JBD API entry point. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/jbd.h # 2004/06/17 23:47:53-07:00 tytso@mit.edu +1 -0 # Ext3: Retry allocation after transaction commit (v2) # # include/linux/ext3_fs.h # 2004/06/17 23:47:53-07:00 tytso@mit.edu +1 -0 # Ext3: Retry allocation after transaction commit (v2) # # fs/jbd/journal.c # 2004/06/17 23:47:53-07:00 tytso@mit.edu +34 -0 # Ext3: Retry allocation after transaction commit (v2) # # fs/ext3/xattr.c # 2004/06/17 23:47:53-07:00 tytso@mit.edu +5 -1 # Ext3: Retry allocation after transaction commit (v2) # # fs/ext3/namei.c # 2004/06/18 00:32:11-07:00 tytso@mit.edu +20 -5 # Ext3: Retry allocation after transaction commit (v2) # # fs/ext3/inode.c # 2004/06/17 23:47:53-07:00 tytso@mit.edu +5 -14 # Ext3: Retry allocation after transaction commit (v2) # # fs/ext3/balloc.c # 2004/06/17 23:49:23-07:00 tytso@mit.edu +32 -6 # Ext3: Retry allocation after transaction commit (v2) # # fs/ext3/acl.c # 2004/06/17 23:47:53-07:00 tytso@mit.edu +9 -1 # Ext3: Retry allocation after transaction commit (v2) # # ChangeSet # 2004/06/18 07:58:28-07:00 rene.herman@keyaccess.nl # [PATCH] pc9800: merge std_resources.c back into setup.c # # std_resources.{c,h} was only split off due to pc9800 wanting to override it. # With it gone, it might as well be merged back in. Doesn't change any code. # It was compiled and booted. # # This time this also actually doesn't break compilation of any of the # subarches. That's to say, any further. I guess it might have been my .config # (my regular PC config, with just the subarch switched through menuconfig) or # O=, but only ELAN actually compiled. Voyager and VISWS bombed out at the # final link and NUMAQ much sooner (with "physnode_map undeclared" during # compilation of numaq.c). # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/kernel/setup.c # 2004/06/18 00:32:22-07:00 rene.herman@keyaccess.nl +200 -5 # pc9800: merge std_resources.c back into setup.c # # arch/i386/kernel/Makefile # 2004/06/17 23:44:27-07:00 rene.herman@keyaccess.nl +0 -1 # pc9800: merge std_resources.c back into setup.c # # arch/i386/Kconfig # 2004/06/17 23:44:27-07:00 rene.herman@keyaccess.nl +0 -6 # pc9800: merge std_resources.c back into setup.c # # BitKeeper/deleted/.del-std_resources.h~45da2e05d849a20f # 2004/06/18 07:58:23-07:00 rene.herman@keyaccess.nl +0 -0 # Delete: include/asm-i386/std_resources.h # # BitKeeper/deleted/.del-std_resources.c~3be5b97880eb064e # 2004/06/18 07:58:22-07:00 rene.herman@keyaccess.nl +0 -0 # Delete: arch/i386/kernel/std_resources.c # # ChangeSet # 2004/06/18 07:58:17-07:00 bunk@fs.tum.de # [PATCH] more PC9800 removal # # Removes more PC9800 code. # # Requires: # # bk rm drivers/char/upd4990a.c # bk rm drivers/net/ne2k_cbus.c # bk rm drivers/net/ne2k_cbus.h # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/drivers/opl3/opl3_lib.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -20 # more PC9800 removal # # sound/drivers/mpu401/mpu401.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -11 # more PC9800 removal # # sound/core/seq/instr/Makefile # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -1 # more PC9800 removal # # sound/core/seq/Makefile # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -1 # more PC9800 removal # # include/linux/serio.h # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -1 # more PC9800 removal # # include/linux/serial_core.h # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -8 # more PC9800 removal # # include/linux/ide.h # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +1 -1 # more PC9800 removal # # include/asm-i386/timex.h # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -4 # more PC9800 removal # # include/asm-i386/serial.h # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -7 # more PC9800 removal # # include/asm-i386/processor.h # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -6 # more PC9800 removal # # include/asm-i386/ide.h # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -34 # more PC9800 removal # # drivers/serial/8250_pnp.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -3 # more PC9800 removal # # drivers/pnp/isapnp/core.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -5 # more PC9800 removal # # drivers/net/at1700.c # 2004/06/17 23:44:24-07:00 bunk@fs.tum.de +0 -88 # more PC9800 removal # # drivers/net/Space.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +2 -2 # more PC9800 removal # # drivers/net/3c509.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +9 -36 # more PC9800 removal # # drivers/ide/ide-proc.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -1 # more PC9800 removal # # drivers/char/keyboard.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +2 -3 # more PC9800 removal # # arch/i386/kernel/i8259.c # 2004/06/17 23:43:58-07:00 bunk@fs.tum.de +0 -5 # more PC9800 removal # # ChangeSet # 2004/06/18 07:58:05-07:00 rddunlap@osdl.org # [PATCH] Remove PC9800 support # # PC9800 sub-arch is incomplete, hackish (at least in IDE), maintainers don't # reply to emails and haven't touched it in awhile. Can't even config it to # try to build it without other patches to the kernel tree. # # bk-rm-script: # # #! /bin/sh # bk rm -r ./arch/i386/mach-pc9800 # bk rm -r ./arch/i386/boot98 # bk rm ./drivers/char/lp_old98.c # bk rm ./drivers/serial/serial98.c # bk rm ./drivers/scsi/scsi_pc98.c # bk rm ./drivers/scsi/pc980155.c # bk rm ./drivers/scsi/pc980155.h # bk rm ./drivers/block/floppy98.c # bk rm ./drivers/input/keyboard/98kbd.c # bk rm ./drivers/input/serio/98kbd-io.c # bk rm ./drivers/input/misc/98spkr.c # bk rm ./drivers/input/mouse/98busmouse.c # bk rm ./drivers/ide/legacy/pc9800.c # bk rm ./drivers/ide/legacy/hd98.c # bk rm -r ./include/asm-i386/mach-pc9800 # bk rm ./include/asm-i386/pc9800_sca.h # bk rm ./include/asm-i386/pc9800.h # bk rm ./fs/partitions/nec98.c # bk rm ./fs/partitions/nec98.h # bk rm ./sound/isa/cs423x/pc98.c # bk rm ./sound/isa/cs423x/pc9801_118_magic.h # bk rm ./sound/isa/cs423x/sound_pc9800.h # # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/isa/cs423x/Makefile # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -2 # Remove PC9800 support # # sound/isa/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -10 # Remove PC9800 support # # fs/partitions/check.c # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -1 # Remove PC9800 support # # fs/partitions/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -7 # Remove PC9800 support # # drivers/serial/Makefile # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -1 # Remove PC9800 support # # drivers/serial/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -13 # Remove PC9800 support # # drivers/scsi/Makefile # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -2 # Remove PC9800 support # # drivers/scsi/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -12 # Remove PC9800 support # # drivers/net/Makefile # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -1 # Remove PC9800 support # # drivers/net/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +1 -51 # Remove PC9800 support # # drivers/input/serio/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -10 # Remove PC9800 support # # drivers/input/mouse/Makefile # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -1 # Remove PC9800 support # # drivers/input/mouse/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -11 # Remove PC9800 support # # drivers/input/misc/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -4 # Remove PC9800 support # # drivers/input/keyboard/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -12 # Remove PC9800 support # # drivers/ide/Makefile # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -1 # Remove PC9800 support # # drivers/ide/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +1 -19 # Remove PC9800 support # # drivers/char/Makefile # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +0 -1 # Remove PC9800 support # # drivers/char/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +1 -21 # Remove PC9800 support # # drivers/block/Kconfig # 2004/06/17 23:43:53-07:00 rddunlap@osdl.org +1 -8 # Remove PC9800 support # # ChangeSet # 2004/06/18 07:57:53-07:00 Robert.Picco@hp.com # [PATCH] HPET driver # # The driver supports the High Precision Event Timer. The driver has adopted # a similar API to the Real Time Clock driver. It can support any number of # HPET devices and the maximum number of timers per HPET device. For further # information look at the documentation in the patch. # # Thanks to Venki at Intel for testing the driver on X86 hardware with HPET. # # HPET documentation is available at http://www.intel.com/design/chipsets/datashts/252516.htm # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/hpet.h # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +133 -0 # HPET driver # # drivers/char/hpet.c # 2004/06/17 23:43:14-07:00 Robert.Picco@hp.com +1076 -0 # HPET driver # # include/linux/miscdevice.h # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +1 -0 # HPET driver # # include/linux/hpet.h # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/linux/hpet.h # # include/asm-i386/hpet.h # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +3 -0 # HPET driver # # drivers/char/rtc.c # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +5 -0 # HPET driver # # drivers/char/hpet.c # 2004/06/17 23:43:14-07:00 Robert.Picco@hp.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/drivers/char/hpet.c # # drivers/char/Makefile # 2004/06/18 00:32:23-07:00 Robert.Picco@hp.com +1 -0 # HPET driver # # drivers/char/Kconfig # 2004/06/18 00:32:23-07:00 Robert.Picco@hp.com +27 -0 # HPET driver # # arch/i386/kernel/time_hpet.c # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +46 -0 # HPET driver # # arch/i386/Kconfig # 2004/06/18 00:32:22-07:00 Robert.Picco@hp.com +2 -1 # HPET driver # # Documentation/hpet.txt # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +298 -0 # HPET driver # # Documentation/filesystems/proc.txt # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +1 -1 # HPET driver # # Documentation/hpet.txt # 2004/06/17 23:41:40-07:00 Robert.Picco@hp.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/Documentation/hpet.txt # # ChangeSet # 2004/06/18 07:57:41-07:00 chrisw@osdl.org # [PATCH] RLIM: adjust default mqueue sizes # # Lower default sizes for POSIX mqueue allocation now that rlimits are in place. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # ipc/mqueue.c # 2004/06/17 23:41:40-07:00 chrisw@osdl.org +3 -3 # RLIM: adjust default mqueue sizes # # ChangeSet # 2004/06/18 07:57:29-07:00 chrisw@osdl.org # [PATCH] RLIM: enforce rlimits for POSIX mqueue allocation # # Add a user_struct to the mq_inode_info structure. Charge the maximum number # of bytes that could be allocated to a mqueue to the user who creates the # mqueue. This is checked against the per user rlimit. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # ipc/mqueue.c # 2004/06/18 00:32:23-07:00 chrisw@osdl.org +39 -5 # RLIM: enforce rlimits for POSIX mqueue allocation # # ChangeSet # 2004/06/18 07:57:18-07:00 chrisw@osdl.org # [PATCH] RLIM: add mq_attr_ok() helper # # Add helper function mq_attr_ok() to do mq_attr sanity checking, and do some # extra overlow checking. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # ipc/mqueue.c # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +23 -10 # RLIM: add mq_attr_ok() helper # # ChangeSet # 2004/06/18 07:57:07-07:00 chrisw@osdl.org # [PATCH] RLIM: add mq_bytes to user_struct # # Add mq_bytes field to user_struct, and make sure it's properly initialized. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/user.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -0 # RLIM: add mq_bytes to user_struct # # include/linux/sched.h # 2004/06/18 00:32:22-07:00 chrisw@osdl.org +2 -0 # RLIM: add mq_bytes to user_struct # # ChangeSet # 2004/06/18 07:56:56-07:00 chrisw@osdl.org # [PATCH] RLIM: add rlimit entry for POSIX mqueue allocation # # Add an rlimit entry to control the maximum number of bytes a user can allocate # to a POSIX mqueue. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/mqueue.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +2 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-x86_64/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-v850/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-sparc64/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-sparc/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-sh/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-s390/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-ppc64/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-ppc/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-parisc/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-mips/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-m68k/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-ia64/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-i386/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-h8300/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-cris/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-arm26/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-arm/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # include/asm-alpha/resource.h # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/x86_64/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/v850/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/um/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/sparc64/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/sparc/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/sh/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/s390/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/ppc64/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/ppc/kernel/process.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/parisc/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/mips/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/m68knommu/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/m68k/kernel/process.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/ia64/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/i386/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/h8300/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/cris/kernel/process.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/arm26/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/arm/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # arch/alpha/kernel/init_task.c # 2004/06/17 23:41:39-07:00 chrisw@osdl.org +1 -0 # RLIM: add rlimit entry for POSIX mqueue allocation # # ChangeSet # 2004/06/18 07:56:43-07:00 chrisw@osdl.org # [PATCH] RLIM: add simple get_uid() helper # # Add simple helper function to grab a reference to a user_struct. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/sched.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +5 -0 # RLIM: add simple get_uid() helper # # ChangeSet # 2004/06/18 07:56:32-07:00 chrisw@osdl.org # [PATCH] RLIM: add sigpending field to user_struct # # Add sigpending field to user_struct, and make sure it's properly initialized. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # kernel/user.c # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add sigpending field to user_struct # # include/linux/sched.h # 2004/06/18 00:32:25-07:00 chrisw@osdl.org +1 -0 # RLIM: add sigpending field to user_struct # # ChangeSet # 2004/06/18 07:56:20-07:00 chrisw@osdl.org # [PATCH] RLIM: add rlimit entry for controlling queued signals # # The following patches introduce per user rlimits for both queued signals and # POSIX message queues. The changes touch all the arches resource.h files as # well as init_task.c to get the rlimit defaults setup. # # Both require caching the user_struct to avoid problems with setuid(). # # The signal changes makes some small changes to send_signal() to pass along the # task being signalled to get proper accounting for signals initiated in # interrupt. Thanks to Marcelo for getting this one going. # # # This patch: # # Add an rlimit entry to control the maximum number of pending signals a user # may have. This is essentially just the resource.h changes. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/signal.h # 2004/06/18 00:32:25-07:00 chrisw@osdl.org +3 -0 # RLIM: add rlimit entry for controlling queued signals # # include/asm-x86_64/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +4 -2 # RLIM: add rlimit entry for controlling queued signals # # include/asm-v850/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +4 -2 # RLIM: add rlimit entry for controlling queued signals # # include/asm-sparc64/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +6 -4 # RLIM: add rlimit entry for controlling queued signals # # include/asm-sparc/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +6 -4 # RLIM: add rlimit entry for controlling queued signals # # include/asm-sh/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-s390/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +4 -2 # RLIM: add rlimit entry for controlling queued signals # # include/asm-ppc64/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-ppc/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-parisc/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-mips/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-m68k/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +4 -2 # RLIM: add rlimit entry for controlling queued signals # # include/asm-ia64/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-i386/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +5 -2 # RLIM: add rlimit entry for controlling queued signals # # include/asm-h8300/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +4 -2 # RLIM: add rlimit entry for controlling queued signals # # include/asm-cris/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +5 -3 # RLIM: add rlimit entry for controlling queued signals # # include/asm-arm26/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-arm/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +3 -1 # RLIM: add rlimit entry for controlling queued signals # # include/asm-alpha/resource.h # 2004/06/18 00:32:24-07:00 chrisw@osdl.org +5 -3 # RLIM: add rlimit entry for controlling queued signals # # ChangeSet # 2004/06/18 07:56:09-07:00 akpm@osdl.org # [PATCH] i2c fixups for idr API change # # Fix up the i2c code which uses the IDR library. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # drivers/i2c/i2c-core.c # 2004/06/17 23:41:38-07:00 akpm@osdl.org +8 -2 # i2c fixups for idr API change # # ChangeSet # 2004/06/18 07:55:58-07:00 minyard@acm.org # [PATCH] IDR fixups # # There were definately some problems in there. I've made some changes and # tested with a lot of bounds. I don't have a machine with enough memory to # fill it up (it would take ~16GB on a 64-bit machine), but I use the "above" # code to simulate a lot of situations. # # The problems were: # # * IDR_FULL was not the right value # * idr_get_new_above() was not defined in the headers or documented. # * idr_alloc() bug-ed if there was a race and not enough memory was # allocated. It should have returned NULL. # * id will overflow when you go past the end. # * There was a "(id >= (1 << (layers*IDR_BITS)))" comparison, but at # the top layer it would overflow the id and be zero. # * The allocation should return ENOSPC for an "above" value with # nothing above it, but it returned EAGAIN. # # I have not tested on 64-bits (as I don't have a 64-bit machine). # # I've included the files, a diff from the previous version, and my test # programs. # # For the test programs, idr_test will just attempt to allocate # elements, check them, free them, and check them again. # # idr_test2 will allocate element with between # them. # # idr_test3 just tests some bounds and tries all values with just a few in # the idr. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # lib/idr.c # 2004/06/17 23:41:38-07:00 minyard@acm.org +31 -14 # IDR fixups # # include/linux/idr.h # 2004/06/17 23:41:38-07:00 minyard@acm.org +9 -6 # IDR fixups # # ChangeSet # 2004/06/18 07:55:47-07:00 akpm@osdl.org # [PATCH] idr: remove counter bits from id's # # idr_get_new() currently returns an incrementing counter in the top 8 bits of # the counter. Which means that most users have to mask it off again, and we # only have a 24-bit range. # # So remove that counter. Also: # # - Remove the BITS_PER_INT define due to namespace collision risk. # # - Make MAX_ID_SHIFT 31, so counters have a 0 to 2G-1 range. # # - Why is MAX_ID_SHIFT using sizeof(int) and not sizeof(long)? If it's for # consistency across 32- and 64-bit machines, why not just make it "31"? # # - Does this still hold true with the counter removed? # # /* We can only use half the bits in the top level because there are # only four possible bits in the top level (5 bits * 4 levels = 25 # bits, but you only use 24 bits in the id). */ # # If not, what needs to change? # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # lib/idr.c # 2004/06/18 00:32:26-07:00 akpm@osdl.org +3 -16 # idr: remove counter bits from id's # # include/linux/idr.h # 2004/06/18 00:32:26-07:00 akpm@osdl.org +5 -13 # idr: remove counter bits from id's # # ChangeSet # 2004/06/18 07:55:36-07:00 minyard@acm.org # [PATCH] Fixes for idr code # # * On a 32-bit architecture, the idr code will cease to work if you add # more than 2^20 entries. You will not be able to find many of the # entries. The problem is that the IDR code uses 5-bit chunks of the # number and the lower portion used by IDR is 24 bits, so you have one bit # that leaks over into the comparisons that should not be there. The # solution is to mask off that bit before doing IDR processing. This # actually causes the POSIX timer code to crash if you create that many # timers. I have included an idr_test.tar.gz file that demonstrates this # with and without the fix, in case you need more evidence :). # # * When the IDR fills up, it returns -1. However, there was no way to # check for this condition. This patch adds the ability to check for the # idr being full and fixes all the users. It also fixes a problem in # fs/super.c where the idr code wasn't checking for -1. # # * There was a race condition creating POSIX timers. The timer was added # to a task struct for another process then the data for the timer was # filled out. The other task could use/destroy time timer as soon as it is # in the task's queue and the lock is released. This moves settup up the # timer data to before the timer is enqueued or (for some data) into the # lock. # # * Change things so that the caller doesn't need to run idr_full() to find # out the reason for an idr_get_new() failure. # # Just return -ENOSPC if the tree was full, or -EAGAIN if the caller needs # to re-run idr_pre_get() and try again. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # net/sctp/sm_make_chunk.c # 2004/06/17 23:41:37-07:00 minyard@acm.org +15 -10 # Fixes for idr code # # lib/idr.c # 2004/06/18 00:32:26-07:00 minyard@acm.org +37 -8 # Fixes for idr code # # kernel/posix-timers.c # 2004/06/17 23:41:37-07:00 minyard@acm.org +52 -34 # Fixes for idr code # # include/linux/idr.h # 2004/06/18 00:32:26-07:00 minyard@acm.org +7 -1 # Fixes for idr code # # fs/super.c # 2004/06/17 23:41:37-07:00 minyard@acm.org +10 -5 # Fixes for idr code # # fs/proc/generic.c # 2004/06/17 23:41:37-07:00 minyard@acm.org +6 -4 # Fixes for idr code # # ChangeSet # 2004/06/18 07:55:25-07:00 mason@suse.com # [PATCH] reiserfs data logging support # # Add data=journal support for reiserfs # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/reiserfs_fs_i.h # 2004/06/17 23:41:37-07:00 mason@suse.com +1 -0 # reiserfs data logging support # # include/linux/reiserfs_fs.h # 2004/06/17 23:41:37-07:00 mason@suse.com +8 -0 # reiserfs data logging support # # fs/reiserfs/tail_conversion.c # 2004/06/17 23:41:37-07:00 mason@suse.com +0 -41 # reiserfs data logging support # # fs/reiserfs/stree.c # 2004/06/17 23:41:37-07:00 mason@suse.com +40 -3 # reiserfs data logging support # # fs/reiserfs/journal.c # 2004/06/17 23:41:37-07:00 mason@suse.com +13 -4 # reiserfs data logging support # # fs/reiserfs/inode.c # 2004/06/17 23:41:37-07:00 mason@suse.com +49 -10 # reiserfs data logging support # # fs/reiserfs/file.c # 2004/06/17 23:41:37-07:00 mason@suse.com +18 -2 # reiserfs data logging support # # ChangeSet # 2004/06/18 07:55:13-07:00 mason@suse.com # [PATCH] reiserfs: btree readahead # # Walking the btree can trigger a number of single block synchronous reads. # This patch does btree readahead during operations that are likely to be long # and sequential. So far, that only includes directory reads and truncates, but # it can make both much faster. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/reiserfs_fs.h # 2004/06/18 00:32:26-07:00 mason@suse.com +5 -1 # reiserfs: btree readahead # # fs/reiserfs/stree.c # 2004/06/18 00:32:26-07:00 mason@suse.com +68 -25 # reiserfs: btree readahead # # fs/reiserfs/dir.c # 2004/06/17 23:41:37-07:00 mason@suse.com +1 -0 # reiserfs: btree readahead # # ChangeSet # 2004/06/18 07:55:03-07:00 mason@suse.com # [PATCH] reiserfs: remove debugging warning from block allocator # # Remove debugging warning from the reiserfs block allocator code # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/reiserfs/bitmap.c # 2004/06/17 23:41:37-07:00 mason@suse.com +0 -1 # reiserfs: remove debugging warning from block allocator # # ChangeSet # 2004/06/18 07:54:52-07:00 mason@suse.com # [PATCH] reiserfs: block allocator should not inherit "packing locality 1" # # reiserfsck --rebuild-tree expects the only key with a packing locality of 1 to # be for the root directory (key [1 2]). The new block allocator inherited that # packing locality down to subdirectories, which triggers failures in reiserfsck # --rebuild-tree # # reiserfsck in readonly check mode doesn't complain about this, thanks to Jeff # Mahoney for finding it. # # The fix is to never inherit packing locality #1 # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/reiserfs/bitmap.c # 2004/06/18 00:32:26-07:00 mason@suse.com +6 -1 # reiserfs: block allocator should not inherit "packing locality 1" # # ChangeSet # 2004/06/18 07:54:43-07:00 mason@suse.com # [PATCH] reiserfs: block allocator optimizations # # From: # From: # # The current reiserfs allocator pretty much allocates things sequentially # from the start of the disk, it works very nicely for desktop loads but # once you've got more then one proc doing io data files can fragment badly. # # One obvious solution is something like ext2's bitmap groups, which puts # file data into different areas of the disk based on which subdirectory # they are in. The problem with bitmap groups is that if you've got a # group of subdirectories their contents will be spread out all over the # disk, leading to lots of seeks during a sequential read. # # This allocator patch uses the packing locality to determine which bitmap # group to allocate from, but when you create a file it looks in the bitmaps # to see how 'full' that packing locality already is. If it hasn't been # heavily used yet, the packing locality is inherited from the parent # directory putting files in new subdirs close to the parent subdir, # otherwise it is the inode number of the parent directory putting new # files far away from the parent subdir. # # The end result is fewer bitmap groups for the same working set. For # example, one test data set created by 20 procs running in parallel has # 6822 subdirs. And with vanilla reiserfs that would mean 6822 # packing localities. This patch turns that into 26 packing localities. # # This makes sequential reads of big directory trees more efficient, but # it also makes the btree more efficient in general. Things end up sorted # better because groups of subdirs end up with similar keys in the btree, # instead of being spread out all over. # # The bitmap grouping code tries to use the start of each bitmap group # for metadata, and offsets the data slightly. The data and metadata # are still close together, but not completely intermixed like they are # in the default allocator. The end result is that leaf nodes tend to be # close to each other, making metadata readahead more effective. # # The old block allocator had the ability to enforce a minimum # allocation size, but did not use it. It now tries to do a pass looking # for larger allocation chunks before falling back to the old behaviour # of taking any blocks it can find. # # The patch changes the defaults to: # # mount -o alloc=skip_busy:dirid_groups:packing_groups # # You can get back the old behaviour with mount -o alloc=skip_busy # # mount -o alloc=dirid_groups will turn on the bitmap groups # mount -o alloc=packing_groups turns on the packing locality reduction code # mount -o alloc=skip_busy:dirid_groups turns on both dirid_groups and # skip_busy # # Finally the patch adds a mount -o alloc=oid_groups, which puts files into # bitmap groups based on a hash of their objectid. This would be used for # databases or other situations where you have a limited number of very # large files. # # This command will tell you how many packing localities are actually in # use: # # debugreiserfs -d /dev/xxx | grep '^|.*SD' | sed 's/^.....//' | awk '{print $1}' | sort -u | wc -l # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/reiserfs_fs.h # 2004/06/18 00:32:26-07:00 mason@suse.com +10 -1 # reiserfs: block allocator optimizations # # fs/reiserfs/super.c # 2004/06/17 23:41:36-07:00 mason@suse.com +7 -6 # reiserfs: block allocator optimizations # # fs/reiserfs/inode.c # 2004/06/18 00:32:26-07:00 mason@suse.com +1 -2 # reiserfs: block allocator optimizations # # fs/reiserfs/file.c # 2004/06/18 00:32:26-07:00 mason@suse.com +11 -3 # reiserfs: block allocator optimizations # # fs/reiserfs/bitmap.c # 2004/06/18 00:32:27-07:00 mason@suse.com +234 -55 # reiserfs: block allocator optimizations # # ChangeSet # 2004/06/18 07:54:32-07:00 akpm@osdl.org # [PATCH] ppc64: uninline __pte_free_tlb() # # The pgalloc.h changes broke ppc64: # # In file included from include/asm-generic/tlb.h:18, # from include/asm/tlb.h:24, # from arch/ppc64/mm/hash_utils.c:48: # include/asm/pgalloc.h: In function `__pte_free_tlb': # include/asm/pgalloc.h:110: dereferencing pointer to incomplete type # include/asm/pgalloc.h:111: dereferencing pointer to incomplete type # # Uninlining __pte_free_tlb() fixes that. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-ppc64/pgalloc.h # 2004/06/17 23:41:36-07:00 akpm@osdl.org +1 -27 # ppc64: uninline __pte_free_tlb() # # arch/ppc64/mm/tlb.c # 2004/06/17 23:41:36-07:00 akpm@osdl.org +27 -0 # ppc64: uninline __pte_free_tlb() # # ChangeSet # 2004/06/18 07:54:20-07:00 rmk@arm.linux.org.uk # [PATCH] Clean up asm/pgalloc.h include 3 # # This patch cleans up needless includes of asm/pgalloc.h from the arch/i386/ # subtree. Compile tested on x86_pc SMP. # # [I also tried VISWS + SMP without PM doesn't build in smpboot.c, # though I don't believe its caused by this patch. With PM, fails # to link complaining maxcpus is undefined. Therefore, I presume # VISWS + SMP is an invalid configuration.] # # This patch is part of a larger patch aiming towards getting the include of # asm/pgtable.h out of linux/mm.h, so that asm/pgtable.h can sanely get at # things like mm_struct and friends. # # I suggest testing in -mm for a while to ensure there aren't any hidden arch # issues. # # The outstanding list of files for other architectures can be found # at http://www.arm.linux.org.uk/misc/pgalloc.txt # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/i386/mm/ioremap.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/mm/init.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/mm/hugetlbpage.c # 2004/06/18 00:32:07-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/mm/fault.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/mach-voyager/voyager_thread.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/mach-voyager/voyager_smp.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/mach-voyager/voyager_basic.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/mach-visws/traps.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/vm86.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/traps.c # 2004/06/18 00:32:07-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/smpboot.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/smp.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/mpparse.c # 2004/06/18 00:32:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/irq.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/i386_ksyms.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/efi.c # 2004/06/17 23:41:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/apic.c # 2004/06/18 00:32:15-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include 3 # # arch/i386/kernel/acpi/boot.c # 2004/06/17 23:41:33-07:00 rmk@arm.linux.org.uk +2 -1 # Clean up asm/pgalloc.h include 3 # # ChangeSet # 2004/06/18 07:54:08-07:00 rmk@arm.linux.org.uk # [PATCH] Clean up asm/pgalloc.h include # # This patch cleans up needless includes of asm/pgalloc.h from the drivers/ # subtree. drivers/char/mem.c has been compile tested; the others have not, # since they are for non-x86 and non-ARM architectures. # # This patch is part of a larger patch aiming towards getting the include of # asm/pgtable.h out of linux/mm.h, so that asm/pgtable.h can sanely get at # things like mm_struct and friends. # # I suggest testing in -mm for a while to ensure there aren't any hidden arch # issues. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # sound/oss/dmasound/dmasound_atari.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/video/console/sticore.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/parisc/ccio-rm-dma.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/parisc/ccio-dma.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/net/sun3lance.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/net/macsonic.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/net/lasi_82596.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/net/82596.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # drivers/char/mem.c # 2004/06/17 23:41:10-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # ChangeSet # 2004/06/18 07:53:57-07:00 rmk@arm.linux.org.uk # [PATCH] Clean up asm/pgalloc.h include # # This patch cleans up needless includes of asm/pgalloc.h from the fs/ # kernel/ and mm/ subtrees. Compile tested on multiple ARM platforms, and # x86, this patch appears safe. # # This patch is part of a larger patch aiming towards getting the include of # asm/pgtable.h out of linux/mm.h, so that asm/pgtable.h can sanely get at # things like mm_struct and friends. # # I suggest testing in -mm for a while to ensure there aren't any hidden arch # issues. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/vmscan.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/vmalloc.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/nommu.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/msync.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/mremap.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/mprotect.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/mmap.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/mincore.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # mm/highmem.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # kernel/module.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # include/asm-generic/tlb.h # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +1 -0 # Clean up asm/pgalloc.h include # # include/asm-arm26/tlb.h # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +1 -0 # Clean up asm/pgalloc.h include # # fs/proc/proc_misc.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # fs/exec.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # fs/binfmt_flat.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # fs/binfmt_elf.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # fs/binfmt_aout.c # 2004/06/17 23:41:09-07:00 rmk@arm.linux.org.uk +0 -1 # Clean up asm/pgalloc.h include # # ChangeSet # 2004/06/18 07:53:45-07:00 yoav.zach@intel.com # [PATCH] binfmt_misc: improve calculation of interpreter's credentials # # This patch allows for misc binaries to run with credentials and security # token that are calculated according to the binaries, and not according to the # interpreter, which is the legacy behavior of binfmt_misc. # # The way it is done is by calling prepare_binprm, which is where these # attributes are calculated, before switching the 'file' field in the bprm from # the binary to the interpreter. # # This feature should be used with care, since the interpreter will have root # permissions when running a setuid binary owned by root. # # Please note - # # - Only root can register an interpreter with binfmt_misc. The feature is # documented and the administrator is advised to handle it with care # # - The new feature is enabled only with a special flag in the registration # string. When this flag is not specified the current behavior of # binfmt_misc is kept # # - This is the only 'right' way for an interpreter to know the correct # AT_SECURE value for the interpreted binary # # # From: Chris Wright # # This patchset looks OK, except for one problem. It installs the fd (which # could've been unreadable) without unsharing the ->files. So someone can use # this to read unreadable yet executable files. Here's a patch which fixes # that up. I added one bit that's commented out because I'm not positive if a # final steal_locks() is needed. # # I did a fair amount of rearranging to simplify the error conditions # relative to the fd_install(), and unshare_files(). # # From: Chris Wright # # I found that the intel patchset (and mine as well) leaked i_writecount on # the original executed file. In addition, I verified that the steal_locks() # bit is indeed needed. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # fs/binfmt_misc.c # 2004/06/17 23:41:09-07:00 yoav.zach@intel.com +71 -51 # binfmt_misc: improve calculation of interpreter's credentials # # Documentation/binfmt_misc.txt # 2004/06/17 23:41:09-07:00 yoav.zach@intel.com +7 -0 # binfmt_misc: improve calculation of interpreter's credentials # # ChangeSet # 2004/06/18 07:53:34-07:00 yoav.zach@intel.com # [PATCH] Handle non-readable binfmt_misc executables # # # # I work in a group that works on enabling the IA-32 Execution Layer # (http://www.intel.com/pressroom/archive/releases/20040113comp.htm) on Linux. # In a few words - this is a dynamic translator for IA-32 binaries on IPF # platform. Following David Mosberger's advice - we use the binfmt_misc # mechanism for the invocation of the translator whenever the user tries to # exec an IA-32 binary. # # The EL is meant to help in the migration path from IA-32 to IPF. From our # beta customers we learnt that at first stage - they tend to keep their # environment mostly intact, using the legacy IA-32 binaries. # # Such an environment has, naturally, setuid and non-readable binaries. It # will be useless to ask the administrator to change the settings of such an # environment - some of them are very complex, and the administrators are # reluctant to make any changes in a system that already proved itself to be # robust and secure. So, our target with these patches is not to enhance the # support for scripts but rather to allow a translator to be integrated into a # working environment that is not (and should not be) aware to the fact it's # being emulated. # # As I said before - it is practically hopeless to expect an administrator of # such a system to change it so that it will suit the current behavior of # binfmt_misc. But, even if we could do that, # # I'm not sure it would be a good idea - these changes are likely to be less # secure than the suggested patches - # # - In order to execute non-readable binaries the binary will have to be made # readable, which is obviously less secure than allowing only a trusted # translator to read it # # - There will be no way for the translator to calculate the accurate # AT_SECURE value for the translated process. This might end up with the # translated process running in a non-secured mode when it actually needs to # be secured. # # # # # I prepared a patch that solves a couple of problems that interpreters have # when invoked via binfmt_misc. currently - # # 1) such interpreters cannot open non-readable binaries # # 2) the processes will have their credentials and security attributes # calculated according to interpreter permissions and not those of the # original binary # # the proposed patch solves these problems by - # # 1) opening the binary on behalf of the interpreter and passing its fd # instead of the path as argv[1] to the interpreter # # 2) calling prepare_binprm with the file struct of the binary and not the # one of the interpreter # # The new functionality is enabled by adding a special flag to the registration # string. If this flag is not added then old behavior is not changed. # # A preliminary version of this patch was sent to the list on 9/1/2003 with the # title "[PATCH]: non-readable binaries - binfmt_misc 2.6.0-test4". This new # version fixes the concerns that were raised by the patch, except of calling # unshare_files() before allocating a new fd. this is because this feature did # not enter 2.6 yet. # # # Arun Sharma says: # # We were going through an internal review of this patch: # # http://marc.theaimsgroup.com/?l=linux-kernel&m=107424598901720&w=2 # # which is in your tree already. I'm not sure if this line of code got # sufficient review. # # + /* call prepare_binprm before switching to interpreter's file # + * so that all security calculation will be done according to # + * binary and not interpreter */ # + retval = prepare_binprm(bprm); # # The case that concerns me is: unprivileged interpreter and a privileged # binary. One can use binfmt_misc to execute untrusted code (interpreter) with # elevated privileges. One could argue that all binfmt_misc interpreters are # trusted, because only root can register them. But that's a change from the # traditional behavior of binfmt_misc (and binfmt_script). # # # (Update): # # Arun pointed out that calculating the process credentials according to the # binary that needs to be translated is a bit risky, since it requires the # administrator to pay extra attention not to register an interpreter which is # not intended to run with root credentials. # # After discussing this issue with him, I would like to propose a modified # patch: The old patch did 2 things - 1) open the binary for reading and 2) # calculate the credentials according to the binary. # # I removed the riskier part of changing the credentials calculation, so the # revised patch only opens the binary for reading. It also includes few words # of warning in the description of the 'open-binary' feature in # binfmt_misc.txt, and makes the function entry_status print the flags in use. # # As for the 'credentials' part of the patch, I will prepare a separate patch # for it and send it again to the LKML, describe the problem and ask for people # comments. # # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/linux/binfmts.h # 2004/06/17 23:41:09-07:00 yoav.zach@intel.com +4 -0 # Handle non-readable binfmt_misc executables # # fs/exec.c # 2004/06/18 00:32:28-07:00 yoav.zach@intel.com +3 -1 # Handle non-readable binfmt_misc executables # # fs/binfmt_misc.c # 2004/06/18 00:32:28-07:00 yoav.zach@intel.com +120 -21 # Handle non-readable binfmt_misc executables # # Documentation/binfmt_misc.txt # 2004/06/18 00:32:28-07:00 yoav.zach@intel.com +19 -4 # Handle non-readable binfmt_misc executables # # ChangeSet # 2004/06/18 07:53:23-07:00 mporter@kernel.crashing.org # [PATCH] Add PPC4xx MAINTAINERS entry, merge CREDITS from 2.4 # # Add myself as the PPC4xx maintainer. Merge CREDITS entry from 2.4 # # Signed-off-by: Matt Porter # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # MAINTAINERS # 2004/06/17 23:41:09-07:00 mporter@kernel.crashing.org +7 -0 # Add PPC4xx MAINTAINERS entry, merge CREDITS from 2.4 # # CREDITS # 2004/06/18 00:32:10-07:00 mporter@kernel.crashing.org +8 -0 # Add PPC4xx MAINTAINERS entry, merge CREDITS from 2.4 # # ChangeSet # 2004/06/18 07:53:12-07:00 olh@suse.de # [PATCH] ppc64: avoid multiline /proc/cmdline content on iSeries # # /proc/cmdline is filled via an OS400 call iSeries_init(). It scans the # returned data from the end, instead of the beginning. This leads to # multiple lines in /proc/cmdline # # Just scan from the beginning and stop at the first newline. This patch # changes also the /proc/iSeries/mf/*/cmdline interface to do the same as the # initial setup. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/ppc64/kernel/mf_proc.c # 2004/06/17 23:41:08-07:00 olh@suse.de +15 -22 # ppc64: avoid multiline /proc/cmdline content on iSeries # # arch/ppc64/kernel/iSeries_setup.c # 2004/06/17 23:41:08-07:00 olh@suse.de +6 -7 # ppc64: avoid multiline /proc/cmdline content on iSeries # # ChangeSet # 2004/06/18 07:53:00-07:00 mikpe@csd.uu.se # [PATCH] ppc32 irq.c cpumask fix # # 2.6.7-rc3-mm1 changed cpumask_t from ulong to a struct, causing # compile-time errors in arch/ppc/kernel/irq.c. # # Proposed fix below. Tested on a G3. # # Signed-off-by: Mikael Pettersson # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # arch/ppc/kernel/irq.c # 2004/06/17 23:41:08-07:00 mikpe@csd.uu.se +3 -1 # ppc32 irq.c cpumask fix # # ChangeSet # 2004/06/18 07:52:49-07:00 kumar.gala@freescale.com # [PATCH] ppc32: support for e500 and 85xx # # Here is both a GNU style and BK patch for adding support for the e500 core and # 85xx platform to 2.6. This is pretty much a direct port from 2.4 with a bit # of cleanup around the edges. # # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-ppc/mpc85xx.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +128 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/immap_85xx.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +126 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/fsl_ocp.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +54 -0 # ppc32: support for e500 and 85xx # # arch/ppc/syslib/ppc85xx_setup.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +67 -0 # ppc32: support for e500 and 85xx # # arch/ppc/syslib/ppc85xx_setup.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +341 -0 # ppc32: support for e500 and 85xx # # arch/ppc/syslib/ppc85xx_common.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +29 -0 # ppc32: support for e500 and 85xx # # arch/ppc/syslib/ppc85xx_common.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +46 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/mpc85xx_ads_common.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +50 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/mpc85xx_ads_common.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +237 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/mpc8540_ads.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +30 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/mpc8540_ads.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +238 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/mpc8540.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +97 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/Makefile # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +7 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/Kconfig # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +44 -0 # ppc32: support for e500 and 85xx # # arch/ppc/mm/fsl_booke_mmu.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +236 -0 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/head_e500.S # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +1329 -0 # ppc32: support for e500 and 85xx # # include/linux/prctl.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +6 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/tlbflush.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +22 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/system.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +2 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/serial.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +2 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/reg_booke.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +119 -11 # ppc32: support for e500 and 85xx # # include/asm-ppc/reg.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +12 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/ptrace.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +5 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/processor.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +16 -9 # ppc32: support for e500 and 85xx # # include/asm-ppc/ppcboot.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +2 -2 # ppc32: support for e500 and 85xx # # include/asm-ppc/ppc_asm.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +56 -10 # ppc32: support for e500 and 85xx # # include/asm-ppc/pgtable.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +37 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/ocp_ids.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +2 -1 # ppc32: support for e500 and 85xx # # include/asm-ppc/ocp.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +4 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/mpc85xx.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-ppc/mpc85xx.h # # include/asm-ppc/mmu_context.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +5 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/mmu.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +68 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/io.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +2 -0 # ppc32: support for e500 and 85xx # # include/asm-ppc/immap_85xx.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-ppc/immap_85xx.h # # include/asm-ppc/fsl_ocp.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/include/asm-ppc/fsl_ocp.h # # include/asm-ppc/elf.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +1 -0 # ppc32: support for e500 and 85xx # # arch/ppc/syslib/ppc85xx_setup.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/syslib/ppc85xx_setup.h # # arch/ppc/syslib/ppc85xx_setup.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/syslib/ppc85xx_setup.c # # arch/ppc/syslib/ppc85xx_common.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/syslib/ppc85xx_common.h # # arch/ppc/syslib/ppc85xx_common.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/syslib/ppc85xx_common.c # # arch/ppc/syslib/open_pic.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +1 -1 # ppc32: support for e500 and 85xx # # arch/ppc/syslib/Makefile # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +7 -0 # ppc32: support for e500 and 85xx # # arch/ppc/platforms/85xx/mpc85xx_ads_common.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/platforms/85xx/mpc85xx_ads_common.h # # arch/ppc/platforms/85xx/mpc85xx_ads_common.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/platforms/85xx/mpc85xx_ads_common.c # # arch/ppc/platforms/85xx/mpc8540_ads.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/platforms/85xx/mpc8540_ads.h # # arch/ppc/platforms/85xx/mpc8540_ads.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/platforms/85xx/mpc8540_ads.c # # arch/ppc/platforms/85xx/mpc8540.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/platforms/85xx/mpc8540.c # # arch/ppc/platforms/85xx/Makefile # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/platforms/85xx/Makefile # # arch/ppc/platforms/85xx/Kconfig # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/platforms/85xx/Kconfig # # arch/ppc/mm/pgtable.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +32 -0 # ppc32: support for e500 and 85xx # # arch/ppc/mm/mmu_decl.h # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +9 -0 # ppc32: support for e500 and 85xx # # arch/ppc/mm/init.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +6 -0 # ppc32: support for e500 and 85xx # # arch/ppc/mm/fsl_booke_mmu.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/mm/fsl_booke_mmu.c # # arch/ppc/mm/fault.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +7 -7 # ppc32: support for e500 and 85xx # # arch/ppc/mm/Makefile # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +1 -0 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/traps.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +89 -2 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/signal.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +42 -3 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/ptrace.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +84 -3 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/process.c # 2004/06/18 00:32:24-07:00 kumar.gala@freescale.com +95 -6 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/ppc_ksyms.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +5 -1 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/misc.S # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +37 -3 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/head_e500.S # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +0 -0 # BitKeeper file /home/torvalds/v2.6/linux/arch/ppc/kernel/head_e500.S # # arch/ppc/kernel/entry.S # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +24 -12 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/cputable.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +12 -1 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/asm-offsets.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +7 -1 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/align.c # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +5 -5 # ppc32: support for e500 and 85xx # # arch/ppc/kernel/Makefile # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +4 -0 # ppc32: support for e500 and 85xx # # arch/ppc/Makefile # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +8 -2 # ppc32: support for e500 and 85xx # # arch/ppc/Kconfig # 2004/06/17 23:41:08-07:00 kumar.gala@freescale.com +33 -4 # ppc32: support for e500 and 85xx # # ChangeSet # 2004/06/18 07:52:38-07:00 hugh@veritas.com # [PATCH] mm: pretest pte_young and pte_dirty # # Test for pte_young before going to the costlier atomic test_and_clear, as # asm-generic does. Test for pte_dirty before going to the costlier atomic # test_and_clear, as asm-generic does (I said before that I would not do so for # pte_dirty, but was missing the point: there is nothing atomic about deciding # to do nothing). But I've not touched the rather different ppc and ppc64. # # Signed-off-by: Hugh Dickins # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # include/asm-x86_64/pgtable.h # 2004/06/17 23:41:07-07:00 hugh@veritas.com +15 -2 # mm: pretest pte_young and pte_dirty # # include/asm-parisc/pgtable.h # 2004/06/17 23:41:07-07:00 hugh@veritas.com +4 -0 # mm: pretest pte_young and pte_dirty # # include/asm-ia64/pgtable.h # 2004/06/17 23:41:07-07:00 hugh@veritas.com +4 -0 # mm: pretest pte_young and pte_dirty # # include/asm-i386/pgtable.h # 2004/06/17 23:41:07-07:00 hugh@veritas.com +14 -2 # mm: pretest pte_young and pte_dirty # # ChangeSet # 2004/06/18 07:52:27-07:00 hugh@veritas.com # [PATCH] mm: flush TLB when clearing young # # Traditionally we've not flushed TLB after clearing the young/referenced bit, # it has seemed just a waste of time. Russell King points out that on some # architectures, with the move from 2.4 mm sweeping to 2.6 rmap, this may be a # serious omission: very frequently referenced pages never re-marked young, and # the worst choices made for unmapping. # # So, replace ptep_test_and_clear_young by ptep_clear_flush_young throughout # rmap.c. Originally I'd imagined making some kind of TLB gather optimization, # but don't see what now: whether worth it rather depends on how common # cross-cpu flushes are, and whether global or not. # # ppc and ppc64 have already found this issue, and worked around it by arranging # TLB flush from their ptep_test_and_clear_young: with the aid of pgtable rmap # pointers. I'm hoping ptep_clear_flush_young will allow ppc and ppc64 to # remove that special code, but won't change them myself. # # It's worth noting that it is Andrea's anon_vma rmap which makes the vma # available for ptep_clear_flush_young in page_referenced_one: anonmm and # pte_chains would both need an additional find_vma for that. # # Signed-off-by: Hugh Dickins # Signed-off-by: Andrew Morton # Signed-off-by: Linus Torvalds # # mm/rmap.c # 2004/06/17 23:41:07-07:00 hugh@veritas.com +3 -3 # mm: flush TLB when clearing young # # ChangeSet # 2004/06/18 13:33:48+01:00 rmk@flint.arm.linux.org.uk # [ARM] Add support code for ARM hardware vector floating point # # This cset adds the code to handle the hardware vector floating point # unit found on some ARM926 and later CPUs. The hardware provides # an implementation for the common cases, and bounces exceptions for # other cases, which have to be handled in software, and signalling # SIGFPE as appropriate. # # include/asm-arm/vfpmacros.h # 2004/06/18 13:31:34+01:00 rmk@flint.arm.linux.org.uk +25 -0 # # include/asm-arm/vfpmacros.h # 2004/06/18 13:31:33+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/include/asm-arm/vfpmacros.h # # include/asm-arm/vfp.h # 2004/06/18 13:31:26+01:00 rmk@flint.arm.linux.org.uk +78 -0 # # include/asm-arm/vfp.h # 2004/06/18 13:31:26+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/include/asm-arm/vfp.h # # arch/arm/vfp/vfpsingle.c # 2004/06/18 13:31:18+01:00 rmk@flint.arm.linux.org.uk +1224 -0 # # arch/arm/vfp/vfpsingle.c # 2004/06/18 13:31:18+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/vfpsingle.c # # arch/arm/vfp/vfpmodule.c # 2004/06/18 13:31:11+01:00 rmk@flint.arm.linux.org.uk +288 -0 # # arch/arm/vfp/vfpmodule.c # 2004/06/18 13:31:11+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/vfpmodule.c # # arch/arm/vfp/vfpinstr.h # 2004/06/18 13:31:03+01:00 rmk@flint.arm.linux.org.uk +88 -0 # # arch/arm/vfp/vfpinstr.h # 2004/06/18 13:31:03+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/vfpinstr.h # # arch/arm/vfp/vfphw.S # 2004/06/18 13:30:55+01:00 rmk@flint.arm.linux.org.uk +210 -0 # # arch/arm/vfp/vfphw.S # 2004/06/18 13:30:55+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/vfphw.S # # arch/arm/vfp/vfpdouble.c # 2004/06/18 13:30:41+01:00 rmk@flint.arm.linux.org.uk +1186 -0 # # arch/arm/vfp/vfpdouble.c # 2004/06/18 13:30:41+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/vfpdouble.c # # arch/arm/vfp/vfp.h # 2004/06/18 13:30:32+01:00 rmk@flint.arm.linux.org.uk +333 -0 # # arch/arm/vfp/vfp.h # 2004/06/18 13:30:32+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/vfp.h # # arch/arm/vfp/entry.S # 2004/06/18 13:30:14+01:00 rmk@flint.arm.linux.org.uk +45 -0 # # arch/arm/vfp/entry.S # 2004/06/18 13:30:14+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/entry.S # # arch/arm/vfp/Makefile # 2004/06/18 13:29:58+01:00 rmk@flint.arm.linux.org.uk +12 -0 # # arch/arm/vfp/Makefile # 2004/06/18 13:29:58+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/vfp/Makefile # # Documentation/arm/VFP/release-notes.txt # 2004/06/18 13:29:51+01:00 rmk@flint.arm.linux.org.uk +55 -0 # # include/asm-arm/thread_info.h # 2004/06/18 13:29:51+01:00 rmk@flint.arm.linux.org.uk +5 -2 # Add VFP state to thread information structure. # # include/asm-arm/fpstate.h # 2004/06/18 13:29:51+01:00 rmk@flint.arm.linux.org.uk +32 -0 # Add VFP hardware structures. # # Documentation/arm/VFP/release-notes.txt # 2004/06/18 13:29:51+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/Documentation/arm/VFP/release-notes.txt # # arch/arm/kernel/process.c # 2004/06/18 13:29:50+01:00 rmk@flint.arm.linux.org.uk +6 -0 # Add VFP calls for releasing VFP state held by a thread and # initialising VFP State. # # arch/arm/kernel/entry-armv.S # 2004/06/18 13:29:50+01:00 rmk@flint.arm.linux.org.uk +13 -0 # Add VFP calls and additional context switch support. # # arch/arm/Makefile # 2004/06/18 13:29:50+01:00 rmk@flint.arm.linux.org.uk +1 -0 # Add VFP directory to build # # arch/arm/Kconfig # 2004/06/18 13:29:49+01:00 rmk@flint.arm.linux.org.uk +11 -0 # Add VFP configuration option. # # ChangeSet # 2004/06/18 15:21:08+09:00 yoshfuji@linux-ipv6.org # [XFRM] fix dependency issues for CONFIG_IPV6=m. # # net/xfrm/xfrm_state.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +10 -0 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/xfrm/xfrm_export.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +1 -1 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/xfrm/Makefile # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +1 -1 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/ipv6/ipcomp6.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +5 -1 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/ipv6/esp6.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +8 -5 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/ipv6/ah6.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +5 -1 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/ipv4/ipcomp.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +7 -3 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/ipv4/esp4.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +9 -4 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # net/ipv4/ah4.c # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +4 -1 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # include/net/xfrm.h # 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +1 -1 # [XFRM] split up xfrm_check_output() into two functions to solve dependency issues. # # BitKeeper/deleted/.del-xfrm_output.c~af23cc5516e28602 # 2004/06/18 15:10:51+09:00 yoshfuji@linux-ipv6.org +0 -0 # Delete: net/xfrm/xfrm_output.c # # ChangeSet # 2004/06/18 01:56:40-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/bk/linux-acpi-test-2.6.7 # # drivers/acpi/pci_link.c # 2004/06/18 01:54:24-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/mpparse.c # 2004/06/18 01:54:24-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/mpparse.c # 2004/06/18 01:54:23-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/18 01:40:30-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.6 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # # arch/x86_64/kernel/mpparse.c # 2004/06/18 01:40:27-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/18 14:25:15+09:00 yoshfuji@linux-ipv6.org # [IPV6] XFRM: support (uncompressed) tunnel mode ipcomp6 using xfrm6_tunnel infrastructure. # # net/ipv6/xfrm6_tunnel.c # 2004/06/18 14:25:06+09:00 yoshfuji@linux-ipv6.org +623 -0 # # net/ipv6/xfrm6_tunnel.c # 2004/06/18 14:25:06+09:00 yoshfuji@linux-ipv6.org +0 -0 # BitKeeper file /home2/yoshfuji/BitKeeper/linux-2.6-export-2.6.8/linux-2.6-xfrm6tunnel/net/ipv6/xfrm6_tunnel.c # # net/ipv6/xfrm6_policy.c # 2004/06/18 14:25:06+09:00 yoshfuji@linux-ipv6.org +2 -0 # [IPV6] XFRM: add missing xfrm6_tunnel.c. # # net/ipv6/ipcomp6.c # 2004/06/18 14:25:06+09:00 yoshfuji@linux-ipv6.org +69 -0 # [IPV6] XFRM: support (uncompressed) tunnel mode ipcomp6 using xfrm6_tunnel infrastructure. # # net/ipv6/ip6_tunnel.c # 2004/06/18 14:25:06+09:00 yoshfuji@linux-ipv6.org +9 -9 # [IPV6] XFRM: use xfrm6_tunnel infrastructure to register/unregister protocol handers. # # net/ipv6/Makefile # 2004/06/18 14:25:06+09:00 yoshfuji@linux-ipv6.org +2 -1 # [IPV6] XFRM: add missing xfrm6_tunnel.c. # # include/net/xfrm.h # 2004/06/18 14:25:06+09:00 yoshfuji@linux-ipv6.org +14 -4 # [IPV6] XFRM: add missing xfrm6_tunnel.c. # # ChangeSet # 2004/06/18 13:56:36+09:00 yoshfuji@linux-ipv6.org # [IPV6] XFRM: add missing xfrm6_policy_check(). # # net/ipv6/ip6_tunnel.c # 2004/06/18 13:56:27+09:00 yoshfuji@linux-ipv6.org +5 -0 # [IPV6] XFRM: add missing xfrm6_policy_check(). # # ChangeSet # 2004/06/18 13:54:05+09:00 yoshfuji@linux-ipv6.org # [IPV6] make several functions static in ip6_tunnel that should be. # # net/ipv6/ip6_tunnel.c # 2004/06/18 13:53:56+09:00 yoshfuji@linux-ipv6.org +10 -6 # [IPV6] make several functions static in ip6_tunnel that should be. # # ChangeSet # 2004/06/18 00:18:19-04:00 len.brown@intel.com # [ACPI] handle SCI override to nth IOAPIC # http://bugzilla.kernel.org/show_bug.cgi?id=2835 # # arch/x86_64/kernel/mpparse.c # 2004/06/17 20:18:02-04:00 len.brown@intel.com +1 -0 # handle SCI override to nth IOAPIC # # arch/i386/kernel/mpparse.c # 2004/06/17 20:18:02-04:00 len.brown@intel.com +1 -0 # handle SCI override to nth IOAPIC # # ChangeSet # 2004/06/17 21:16:48-07:00 rth@twiddle.net # [PATCH] alpha: fix discontigmem+initrd build # # From: Ivan Kokshaysky # # Compilation fails due to incorrect usage of NODE_DATA(). # # Reported by hpa. # # arch/alpha/mm/numa.c # 2004/06/14 08:25:24-07:00 rth@twiddle.net +2 -2 # alpha: fix discontigmem+initrd build # # ChangeSet # 2004/06/18 14:09:35+10:00 nathans@sgi.com # [XFS] Fix up highmem build and error handling on inode shrink register. # # SGI Modid: xfs-linux:xfs-kern:173764a # Signed-off-by: nathans@sgi.com # # fs/xfs/linux-2.6/xfs_super.c # 2004/06/18 14:09:11+10:00 nathans@sgi.com +7 -0 # [XFS] Fix up highmem build and error handling on inode shrink register. # # fs/xfs/linux-2.6/kmem.c # 2004/06/18 14:09:11+10:00 nathans@sgi.com +1 -0 # [XFS] Fix up highmem build and error handling on inode shrink register. # # ChangeSet # 2004/06/17 21:04:44-07:00 paulus@samba.org # [PATCH] ppc64: Optimize exception/syscall entry/exit # # This rewrites the PPC64 exception entry/exit routines to make them # smaller and faster. # # In particular we no longer save all of the registers for the common # exceptions - system calls, hardware interrupts and decrementer (timer) # interrupts - only the volatile registers. The other registers are saved # and restored (if used) by the C functions we call. This involved # changing the registers we use in early exception processing from r20-r23 # to r9-r12, which ended up changing quite a lot of code in head.S. # Overall this gives us about a 20% reduction in null syscall time. # # Some system calls need all the registers (e.g. fork/clone/vfork and # [rt_]sigsuspend). For these the syscall dispatch code calls a stub that # saves the nonvolatile registers before calling the real handler. # # This also implements the force_successful_syscall_return() thing for # ppc64. # # Signed-off-by: Paul Mackerras # Signed-off-by: Linus Torvalds # # include/asm-ppc64/thread_info.h # 2004/06/16 22:46:06-07:00 paulus@samba.org +2 -2 # ppc64: Optimize exception/syscall entry/exit # # include/asm-ppc64/ptrace.h # 2004/06/16 22:46:06-07:00 paulus@samba.org +12 -0 # ppc64: Optimize exception/syscall entry/exit # # include/asm-ppc64/processor.h # 2004/06/16 22:46:06-07:00 paulus@samba.org +1 -2 # ppc64: Optimize exception/syscall entry/exit # # include/asm-ppc64/ppc_asm.h # 2004/06/16 22:46:06-07:00 paulus@samba.org +3 -5 # ppc64: Optimize exception/syscall entry/exit # # include/asm-ppc64/paca.h # 2004/06/16 22:46:06-07:00 paulus@samba.org +9 -11 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/xmon/xmon.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +0 -3 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/mm/fault.c # 2004/06/16 23:23:50-07:00 paulus@samba.org +33 -24 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/traps.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +15 -1 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/syscalls.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +14 -0 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/signal32.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +1 -1 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/signal.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +2 -2 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/process.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +5 -1 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/pacaData.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +0 -2 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/misc.S # 2004/06/16 22:46:06-07:00 paulus@samba.org +13 -12 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/head.S # 2004/06/16 22:46:06-07:00 paulus@samba.org +707 -760 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/entry.S # 2004/06/16 22:48:02-07:00 paulus@samba.org +277 -193 # ppc64: Optimize exception/syscall entry/exit # # arch/ppc64/kernel/asm-offsets.c # 2004/06/16 22:46:06-07:00 paulus@samba.org +10 -2 # ppc64: Optimize exception/syscall entry/exit # # ChangeSet # 2004/06/17 21:04:32-07:00 paulus@samba.org # [PATCH] ppc64: Implement CONFIG_PREEMPT # # This implements CONFIG_PREEMPT for ppc64. Aside from the entry.S # changes to check the _TIF_NEED_RESCHED bit when returning from an # exception, there are various changes to make the ppc64-specific code # preempt-safe, mostly adding preempt_enable/disable or get_cpu/put_cpu # calls where needed. I have been using this on my desktop G5 for the # last week without problems. # # Signed-off-by: Paul Mackerras # Signed-off-by: Linus Torvalds # # include/asm-ppc64/thread_info.h # 2004/06/09 23:21:41-07:00 paulus@samba.org +5 -2 # ppc64: Implement CONFIG_PREEMPT # # include/asm-ppc64/system.h # 2004/06/09 23:21:41-07:00 paulus@samba.org +2 -0 # ppc64: Implement CONFIG_PREEMPT # # include/asm-ppc64/hardirq.h # 2004/06/09 23:21:41-07:00 paulus@samba.org +2 -0 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/mm/tlb.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +5 -1 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/mm/init.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +4 -1 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/mm/hugetlbpage.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +4 -1 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/mm/hash_utils.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +7 -3 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/traps.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +2 -4 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/sys_ppc32.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +2 -6 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/signal32.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +5 -7 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/signal.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +3 -5 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/rtas.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +4 -2 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/ptrace32.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +6 -12 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/ptrace.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +4 -8 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/process.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +64 -23 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/entry.S # 2004/06/09 23:21:41-07:00 paulus@samba.org +50 -9 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/asm-offsets.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +1 -0 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/kernel/align.c # 2004/06/09 23:21:41-07:00 paulus@samba.org +9 -4 # ppc64: Implement CONFIG_PREEMPT # # arch/ppc64/Kconfig # 2004/06/09 23:21:41-07:00 paulus@samba.org +0 -1 # ppc64: Implement CONFIG_PREEMPT # # ChangeSet # 2004/06/17 22:54:26-05:00 stevef@smfhome1.smfdom # Fix typo in name of CIFS Kconfig option and add rename stats # # fs/cifs/cifssmb.c # 2004/06/17 22:54:19-05:00 stevef@smfhome1.smfdom +12 -1 # add rename stats # # fs/cifs/cifsglob.h # 2004/06/17 22:54:19-05:00 stevef@smfhome1.smfdom +2 -0 # add rename stats # # fs/cifs/cifs_debug.c # 2004/06/17 22:54:19-05:00 stevef@smfhome1.smfdom +7 -1 # Add rename stats # # fs/Kconfig # 2004/06/17 22:54:19-05:00 stevef@smfhome1.smfdom +1 -1 # Fix typo in name of CIFS Kconfig option # # ChangeSet # 2004/06/18 13:38:36+10:00 cattelan@sgi.com # [XFS] Fix for NFS+XFS data corruption problem. # See http://oss.sgi.com/bugzilla/show_bug.cgi?id=198 for full details. # # SGI Modid: xfs-linux:xfs-kern:173598a # Signed-off-by: nathans@sgi.com # # fs/xfs/linux-2.6/xfs_aops.c # 2004/06/18 13:38:08+10:00 cattelan@sgi.com +16 -9 # [XFS] Fix for NFS+XFS data corruption problem. # See http://oss.sgi.com/bugzilla/show_bug.cgi?id=198 for full details. # # ChangeSet # 2004/06/17 23:21:03-04:00 len.brown@intel.com # [ACPI] avoid spurious interrupts on VIA # http://bugzilla.kernel.org/show_bug.cgi?id=2243 # # drivers/acpi/pci_link.c # 2004/06/11 10:38:46-04:00 len.brown@intel.com +3 -19 # disable all PCI Interrupt Links to be enabled by _SRS # # ChangeSet # 2004/06/17 20:05:11-07:00 dsaxena@plexity.net # Merge plexity.net:/home/dsaxena/src/linux-2.6-arm-timer # into plexity.net:/home/dsaxena/src/linux-2.6-for-rmk # # arch/arm/mach-integrator/integrator_cp.c # 2004/06/17 20:05:06-07:00 dsaxena@plexity.net +0 -0 # Auto merged # # arch/arm/kernel/debug.S # 2004/06/17 20:05:06-07:00 dsaxena@plexity.net +0 -0 # Auto merged # # arch/arm/Kconfig # 2004/06/17 20:05:06-07:00 dsaxena@plexity.net +0 -0 # Auto merged # # ChangeSet # 2004/06/17 23:00:08-04:00 len.brown@intel.com # [ACPI] fix passive cooling mode indicator (Luming Yu) # http://bugzilla.kernel.org/show_bug.cgi?id=1770 # # drivers/acpi/thermal.c # 2004/01/02 00:06:13-05:00 len.brown@intel.com +7 -0 # fix passive cooling mode indicator (Luming Yu) # # ChangeSet # 2004/06/18 12:05:32+10:00 nathans@sgi.com # [XFS] Fix up memory allocators to be more resilient. # # SGI Modid: xfs-linux:xfs-kern:173571a # Signed-off-by: nathans@sgi.com # # fs/xfs/linux-2.6/kmem.c # 2004/06/18 12:05:01+10:00 nathans@sgi.com +126 -0 # # fs/xfs/linux-2.6/xfs_super.c # 2004/06/18 12:05:01+10:00 nathans@sgi.com +23 -6 # [XFS] Fix up memory allocators to be more resilient. # # fs/xfs/linux-2.6/xfs_buf.c # 2004/06/18 12:05:01+10:00 nathans@sgi.com +28 -15 # [XFS] Fix up memory allocators to be more resilient. # # fs/xfs/linux-2.6/kmem.h # 2004/06/18 12:05:01+10:00 nathans@sgi.com +38 -76 # [XFS] Fix up memory allocators to be more resilient. # # fs/xfs/linux-2.6/kmem.c # 2004/06/18 12:05:01+10:00 nathans@sgi.com +0 -0 # BitKeeper file /source2/xfs-linux-2.6/fs/xfs/linux-2.6/kmem.c # # fs/xfs/Makefile # 2004/06/18 12:05:01+10:00 nathans@sgi.com +1 -0 # [XFS] Fix up memory allocators to be more resilient. # # ChangeSet # 2004/06/18 11:53:10+10:00 nathans@sgi.com # [XFS] Fix a race condition in the undo-delayed-write buffer routine. # # SGI Modid: xfs-linux:xfs-kern:173564a # Signed-off-by: nathans@sgi.com # # fs/xfs/linux-2.6/xfs_buf.h # 2004/06/18 11:52:41+10:00 nathans@sgi.com +4 -16 # [XFS] Fix a race condition in the undo-delayed-write buffer routine. # # fs/xfs/linux-2.6/xfs_buf.c # 2004/06/18 11:52:41+10:00 nathans@sgi.com +11 -2 # [XFS] Fix a race condition in the undo-delayed-write buffer routine. # # ChangeSet # 2004/06/18 11:47:58+10:00 nathans@sgi.com # [XFS] Fix flags argument to xfs_incore call on attr removal. # # SGI Modid: xfs-linux:xfs-kern:173563a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_attr.c # 2004/06/18 11:47:36+10:00 nathans@sgi.com +3 -3 # [XFS] Fix flags argument to xfs_incore call on attr removal. # # ChangeSet # 2004/06/18 11:44:24+10:00 nathans@sgi.com # [XFS] Remove the one remaining, broken use of XFS_WRITEIO_LOG and # sanitize direct IO map blocks call. # # SGI Modid: xfs-linux:xfs-kern:173562a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_mount.h # 2004/06/18 11:44:01+10:00 nathans@sgi.com +1 -5 # [XFS] Remove the one remaining, broken use of XFS_WRITEIO_LOG and # sanitize direct IO map blocks call. # # fs/xfs/linux-2.6/xfs_aops.c # 2004/06/18 11:44:01+10:00 nathans@sgi.com +4 -17 # [XFS] Remove the one remaining, broken use of XFS_WRITEIO_LOG and # sanitize direct IO map blocks call. # # ChangeSet # 2004/06/18 10:59:11+10:00 nathans@sgi.com # [XFS] Remove unused MAC macros, never needed on Linux. # # SGI Modid: xfs-linux:xfs-kern:173561a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_vnodeops.c # 2004/06/18 10:58:48+10:00 nathans@sgi.com +0 -16 # [XFS] Remove unused MAC macros, never needed on Linux. # # fs/xfs/xfs_inode.c # 2004/06/18 10:58:48+10:00 nathans@sgi.com +0 -6 # [XFS] Remove unused MAC macros, never needed on Linux. # # fs/xfs/xfs_acl.c # 2004/06/18 10:58:48+10:00 nathans@sgi.com +0 -4 # [XFS] Remove unused MAC macros, never needed on Linux. # # ChangeSet # 2004/06/18 10:52:51+10:00 nathans@sgi.com # [XFS] Sanitise the ACL initialisation macros. # # SGI Modid: xfs-linux:xfs-kern:173559a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_vfsops.c # 2004/06/18 10:52:27+10:00 nathans@sgi.com +2 -2 # [XFS] Sanitise the ACL initialisation macros. # # fs/xfs/xfs_acl.h # 2004/06/18 10:52:27+10:00 nathans@sgi.com +11 -15 # [XFS] Sanitise the ACL initialisation macros. # # ChangeSet # 2004/06/18 10:49:46+10:00 nathans@sgi.com # [XFS] Ensure buffers that map to unwritten extents are only submitted # when properly setup. # # SGI Modid: xfs-linux:xfs-kern:173555a # Signed-off-by: nathans@sgi.com # # fs/xfs/linux-2.6/xfs_aops.c # 2004/06/18 10:49:23+10:00 nathans@sgi.com +7 -2 # [XFS] Ensure buffers that map to unwritten extents are only submitted # when properly setup. # # ChangeSet # 2004/06/18 10:43:35+10:00 roehrich@sgi.com # [XFS] Fix non-dmapi build # # SGI Modid: xfs-linux:xfs-kern:173222a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_dmapi.h # 2004/06/18 10:43:11+10:00 roehrich@sgi.com +2 -2 # [XFS] Fix non-dmapi build # # ChangeSet # 2004/06/18 10:38:53+10:00 roehrich@sgi.com # [XFS] Change things to use new version of xfs_dm_init/xfs_dm_exit # # SGI Modid: xfs-linux:xfs-kern:173206a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_dmapi.h # 2004/06/18 10:38:30+10:00 roehrich@sgi.com +10 -3 # [XFS] Change things to use new version of xfs_dm_init/xfs_dm_exit # # fs/xfs/linux-2.6/xfs_super.h # 2004/06/18 10:38:30+10:00 roehrich@sgi.com +8 -1 # [XFS] Change things to use new version of xfs_dm_init/xfs_dm_exit # # fs/xfs/linux-2.6/xfs_super.c # 2004/06/18 10:38:30+10:00 roehrich@sgi.com +2 -2 # [XFS] Change things to use new version of xfs_dm_init/xfs_dm_exit # # ChangeSet # 2004/06/18 10:17:44+10:00 nathans@sgi.com # [XFS] sparse: fix uses of macros before their definitions, etc. # # SGI Modid: xfs-linux:xfs-kern:173194a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_arch.h # 2004/06/18 10:17:21+10:00 nathans@sgi.com +5 -5 # [XFS] sparse: fix uses of macros before their definitions, etc. # # fs/xfs/xfs.h # 2004/06/18 10:17:21+10:00 nathans@sgi.com +1 -0 # [XFS] sparse: fix uses of macros before their definitions, etc. # # fs/xfs/linux-2.6/xfs_fs_subr.c # 2004/06/18 10:17:21+10:00 nathans@sgi.com +3 -3 # [XFS] sparse: fix uses of macros before their definitions, etc. # # fs/xfs/linux-2.6/kmem.h # 2004/06/18 10:17:21+10:00 nathans@sgi.com +1 -1 # [XFS] sparse: fix uses of macros before their definitions, etc. # # ChangeSet # 2004/06/18 10:09:06+10:00 nathans@sgi.com # [XFS] Fix xfs_lowbit64, it mishandled zero in the high bits. # Cleanup a couple of other ffs users, since ffs(0) is apparently # undefined on some architectures. # # SGI Modid: xfs-linux:xfs-kern:173034a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_rtalloc.c # 2004/06/18 10:08:43+10:00 nathans@sgi.com +4 -2 # [XFS] Fix xfs_lowbit64, it mishandled zero in the high bits. # Cleanup a couple of other ffs users, since ffs(0) is apparently # undefined on some architectures. # # fs/xfs/xfs_bit.c # 2004/06/18 10:08:43+10:00 nathans@sgi.com +14 -10 # [XFS] Fix xfs_lowbit64, it mishandled zero in the high bits. # Cleanup a couple of other ffs users, since ffs(0) is apparently # undefined on some architectures. # # ChangeSet # 2004/06/18 10:04:34+10:00 nathans@sgi.com # [XFS] Remove a couple of redundant NULL parent inode pointer checks. # # SGI Modid: xfs-linux:xfs-kern:173033a # Signed-off-by: nathans@sgi.com # # fs/xfs/xfs_inode.h # 2004/06/18 10:04:10+10:00 nathans@sgi.com +2 -2 # [XFS] Remove a couple of redundant NULL parent inode pointer checks. # # fs/xfs/xfs_inode.c # 2004/06/18 10:04:10+10:00 nathans@sgi.com +1 -2 # [XFS] Remove a couple of redundant NULL parent inode pointer checks. # # ChangeSet # 2004/06/18 10:00:58+10:00 nathans@sgi.com # [XFS] No longer hold the BKL for the entire ioctl operation, # its not needed here. # # SGI Modid: xfs-linux:xfs-kern:173032a # Signed-off-by: nathans@sgi.com # # fs/xfs/linux-2.6/xfs_file.c # 2004/06/18 10:00:35+10:00 nathans@sgi.com +6 -2 # [XFS] No longer hold the BKL for the entire ioctl operation, # its not needed here. # # ChangeSet # 2004/06/17 16:25:47-07:00 tony.luck@intel.com # [PATCH] ia64: switching between CPEI & CPEP # # A couple of months ago Hidetoshi Seto from Fujitsu proposed # a patch to provide similar switching between interrupt mode # and polling mode for corrected platform events (CPE) as we # have for processor events (CMC) [with the obvious difference # that not all platforms support an interrupt for CPE]. # # I dusted it off and made a couple of very minor cleanups (which # Seto-san checked out last night on his test setup and confirmed # still passes). # # Signed-off-by: Tony Luck # Signed-off-by: David Mosberger # # arch/ia64/kernel/mca.c # 2004/06/16 13:24:00-07:00 tony.luck@intel.com +71 -16 # ia64: switching between CPEI & CPEP # # ChangeSet # 2004/06/17 16:22:26-07:00 pfg@sgi.com # [PATCH] ia64: fix SN2 interrupt rerouting # # Signed-off-by: Patrick Gefre # Signed-off-by: David Mosberger # # arch/ia64/sn/kernel/irq.c # 2004/06/17 08:42:20-07:00 pfg@sgi.com +17 -0 # ia64: fix SN2 interrupt rerouting # # arch/ia64/sn/io/sn2/ml_iograph.c # 2004/06/17 08:42:20-07:00 pfg@sgi.com +8 -8 # ia64: fix SN2 interrupt rerouting # # ChangeSet # 2004/06/17 15:47:19-07:00 davidm@tiger.hpl.hp.com # ia64: Fix build-problem when CONFIG_IA32 is not enabled. # # Without this fix, you'll get unresolved references to # sys_rt_sigaction(). # # include/asm-ia64/unistd.h # 2004/06/17 15:47:11-07:00 davidm@tiger.hpl.hp.com +2 -1 # (__ARCH_WANT_SYS_RT_SIGACTION): Move outside of # #ifdef CONFIG_IA32_SUPPORT bracket---we need # sys_rt_sigaction() whether we have ia32 emulation or not. # # ChangeSet # 2004/06/17 15:45:25-07:00 davidm@tiger.hpl.hp.com # ia64: Squish some more hazards & warnings for UP compile. # # include/asm-ia64/system.h # 2004/06/17 15:45:17-07:00 davidm@tiger.hpl.hp.com +1 -1 # (local_irq_enable): Precede ia64_ssm() with ia64_stop() to avoid # WAW hazard when local_irq_disable() is followed in the # same instruction-group by local_irq_enable(). # # include/asm-ia64/gcc_intrin.h # 2004/06/17 15:45:17-07:00 davidm@tiger.hpl.hp.com +11 -5 # (ia64_ptcga): Follow with ia64_dv_serialize_data() to shut up some # compiler/assembler-warnings which showed when compiling for UP. # (ia64_ptcl): Likewise. # (ia64_intrin_local_irq_restore): Put a stop-bit before the cmp.ne to # work around an apparent GCC v3.4 bug/limitation (it doesn't # seem to heed the clobber of p6/p7 and merrily generates code # that writes to p6/p7 right before the cmp.ne. # # ChangeSet # 2004/06/17 15:41:52-07:00 dsaxena@plexity.net # [ARM] Remove ADIFCC machine type # # The code is completely out of date, I am no longer maintaining it, # and nobdy has volunteered to do so; therefore, I am killing it. # # Signed-off-by: Deepak Saxena # # arch/arm/mm/Kconfig # 2004/06/17 15:41:42-07:00 dsaxena@plexity.net +1 -1 # Remove ADIFCC machine type # # arch/arm/kernel/entry-armv.S # 2004/06/17 15:41:42-07:00 dsaxena@plexity.net +1 -1 # Remove ADIFCC machine type # # arch/arm/kernel/debug.S # 2004/06/17 15:41:42-07:00 dsaxena@plexity.net +0 -26 # Remove ADIFCC machine type # # arch/arm/boot/compressed/head-xscale.S # 2004/06/17 15:41:42-07:00 dsaxena@plexity.net +0 -3 # Remove ADIFCC machine type # # arch/arm/boot/Makefile # 2004/06/17 15:41:42-07:00 dsaxena@plexity.net +0 -2 # Remove ADIFCC machine type # # arch/arm/Makefile # 2004/06/17 15:41:42-07:00 dsaxena@plexity.net +0 -1 # Remove ADIFCC machine type # # arch/arm/Kconfig # 2004/06/17 15:41:42-07:00 dsaxena@plexity.net +0 -3 # Remove ADIFCC machine type # # ChangeSet # 2004/06/17 15:41:25-07:00 davidm@tiger.hpl.hp.com # ia64: Squish compiler-warning in perfmon.c when compiling for UP. # # arch/ia64/kernel/perfmon.c # 2004/06/17 15:41:17-07:00 davidm@tiger.hpl.hp.com +26 -25 # (pfm_force_cleanup): Move nside "#ifdef CONFIG_SMP" bracket to # avoid compiler-warning. # # BitKeeper/deleted/.del-adi_evb_defconfig~5ab95444ffcea5c9 # 2004/06/17 15:27:16-07:00 dsaxena@plexity.net +0 -0 # Delete: arch/arm/configs/adi_evb_defconfig # # BitKeeper/deleted/.del-vmalloc.h~15c97e3acb543bb0 # 2004/06/17 15:25:00-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/vmalloc.h # # BitKeeper/deleted/.del-uncompress.h~62baa5a4fcf5eb3b # 2004/06/17 15:25:00-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/uncompress.h # # BitKeeper/deleted/.del-timex.h~a141f6df7754bb0a # 2004/06/17 15:25:00-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/timex.h # # BitKeeper/deleted/.del-system.h~198f47232b9136f1 # 2004/06/17 15:25:00-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/system.h # # BitKeeper/deleted/.del-serial.h~bc766ee26826eae8 # 2004/06/17 15:24:59-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/serial.h # # BitKeeper/deleted/.del-param.h~80c7330f7482c3c7 # 2004/06/17 15:24:59-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/param.h # # BitKeeper/deleted/.del-memory.h~2d1748648a3d612 # 2004/06/17 15:24:59-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/memory.h # # BitKeeper/deleted/.del-irqs.h~f0180913d4bf323c # 2004/06/17 15:24:59-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/irqs.h # # BitKeeper/deleted/.del-io.h~e0d8c315f73a9e29 # 2004/06/17 15:24:59-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/io.h # # BitKeeper/deleted/.del-hardware.h~b995a53087c6aa07 # 2004/06/17 15:24:59-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/hardware.h # # BitKeeper/deleted/.del-dma.h~1aab232a2312a68e # 2004/06/17 15:24:58-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/dma.h # # BitKeeper/deleted/.del-adi_evb.h~cd33495e40db9649 # 2004/06/17 15:24:56-07:00 dsaxena@plexity.net +0 -0 # Delete: include/asm-arm/arch-adifcc/adi_evb.h # # ChangeSet # 2004/06/17 15:23:14-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix endian bug in g_file_storage # # This patch fixes a couple of places in g_file_storage where I forgot to # use proper byte-swapping. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/file_storage.c # 2004/06/17 09:15:53-07:00 stern@rowland.harvard.edu +2 -2 # USB: Fix endian bug in g_file_storage # # ChangeSet # 2004/06/17 15:22:55-07:00 stern@rowland.harvard.edu # [PATCH] USB Storage: unusual_devs.h update # # On Thu, 17 Jun 2004, Daniel Nouri wrote: # > I get this message when inserting my USB MMC card reader: # > # > usb 3-1: new full speed USB device using address 4 # > usb.agent[5388]: usb-storage: already loaded # > usb-storage: This device (04e6,0006,0205 S 01 P 01) has an unneeded Protocol entry in unusual_devs.h # > Please send a copy of this message to # # Thanks for letting us know. This patch will eliminate that log message. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # BitKeeper/deleted/.del-mm.c~5479359d6124d62c # 2004/06/17 15:22:54-07:00 dsaxena@plexity.net +0 -0 # Delete: arch/arm/mach-adifcc/mm.c # # BitKeeper/deleted/.del-irq.c~df46d54c803ac527 # 2004/06/17 15:22:54-07:00 dsaxena@plexity.net +0 -0 # Delete: arch/arm/mach-adifcc/irq.c # # BitKeeper/deleted/.del-arch.c~e5363b35d51cf728 # 2004/06/17 15:22:54-07:00 dsaxena@plexity.net +0 -0 # Delete: arch/arm/mach-adifcc/arch.c # # BitKeeper/deleted/.del-Makefile~bb9d2878ad23132d # 2004/06/17 15:22:53-07:00 dsaxena@plexity.net +0 -0 # Delete: arch/arm/mach-adifcc/Makefile # # drivers/usb/storage/unusual_devs.h # 2004/06/17 09:06:45-07:00 stern@rowland.harvard.edu +1 -1 # USB Storage: unusual_devs.h update # # ChangeSet # 2004/06/17 15:22:34-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: Lexar Jumpshot CF reader # # This patch is required to fix up the jumpshot driver, and to supress # the 'unneeded entry' message for another device which uses the same # VID/PID/rev for multiple different versions of the device. # # Alan Stern cooked this patch up, originally. # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/06/17 08:57:07-07:00 mdharm-usb@one-eyed-alien.net +2 -2 # USB Storage: Lexar Jumpshot CF reader # # drivers/usb/storage/jumpshot.c # 2004/06/17 08:51:10-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: Lexar Jumpshot CF reader # # ChangeSet # 2004/06/17 15:22:14-07:00 david-b@pacbell.net # [PATCH] USB: add support for Buffalo LUA-U2-KTX # # Add support for Buffalo's LUA-U2-KTX, which is a AX8817X based usb # ethernet adapter. I just added the USB id and it worked like a dream. # # From: Neil Bortnak # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/usbnet.c # 2004/06/14 05:52:53-07:00 david-b@pacbell.net +6 -0 # USB: add support for Buffalo LUA-U2-KTX # # ChangeSet # 2004/06/17 15:21:44-07:00 david-b@pacbell.net # [PATCH] proper bios handoff in ehci-hcd # # Stuart Hayes here at Dell has identified this or/and mix-up in the # ehci-hcd driver. Because of this, ehci-hcd is not properly released by # BIOSes supporting full 2.0 and port behavior can then become erratic. # # (Code predates general availability of such BIOS firmware. This version # of the patch also fixes minor linewrap issues.) # # From: Gary Lerhaupt # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ehci-hcd.c # 2004/06/16 01:29:01-07:00 david-b@pacbell.net +4 -3 # proper bios handoff in ehci-hcd # # ChangeSet # 2004/06/17 15:21:14-07:00 sean@mess.org # [PATCH] USB: PhidgetServo driver fixes # # Here is a patch for the phidgetservo driver -- it was using memory after # kfree(), and using driver_info is much nicer. :) # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/phidgetservo.c # 2004/06/16 08:28:42-07:00 sean@mess.org +63 -54 # USB: PhidgetServo driver fixes # # ChangeSet # 2004/06/17 15:20:50-07:00 stern@rowland.harvard.edu # [PATCH] USB: Only process ports with change events pending # # This patch adds a bit-array to the hub driver's private data structure, # used for storing the contents of the hub's interrupt status message. That # message indicates which ports have events pending (and whether the hub # itself has events pending). By only polling the status of the ports # listed in the bit-array we can save a fair amount of overhead in hub # communication. # # (The #error test added to hub.h is a little awkward, but it's purely # precautionary -- it won't matter until someone decides to support hubs # with more than 31 ports!) # # Also included in the patch, since this seemed the perfect opportunity for # it, is Byron's suggestion for handling hub events in the order in which # they were received. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.h # 2004/06/15 09:10:57-07:00 stern@rowland.harvard.edu +4 -0 # USB: Only process ports with change events pending # # drivers/usb/core/hub.c # 2004/06/15 09:11:37-07:00 stern@rowland.harvard.edu +14 -2 # USB: Only process ports with change events pending # # ChangeSet # 2004/06/17 14:21:35-07:00 dsaxena@plexity.net # [ARM] Consolidate various ARM timer fns. into single timer_tick() call. # # Signed-off-by: Deepak Saxena # # include/asm-arm/mach/time.h # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +2 -6 # Consolidate various ARM timer functions into a single timer_tick() call. # # arch/arm/mach-versatile/core.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/mach-shark/core.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/mach-sa1100/time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -5 # Call timer_tick() # # arch/arm/mach-s3c2410/time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -6 # Call timer_tick() # # arch/arm/mach-rpc/riscpc.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/mach-pxa/time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -5 # Call timer_tick() # # arch/arm/mach-omap/time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/mach-lh7a40x/time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -4 # Call timer_tick() # # arch/arm/mach-ixp4xx/common.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -1 # Call timer_tick() # # arch/arm/mach-iop3xx/iop321-time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -1 # Call timer_tick() # # arch/arm/mach-integrator/time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/mach-footbridge/time.c # 2004/06/17 14:21:26-07:00 dsaxena@plexity.net +2 -11 # Call timer_tick() # # arch/arm/mach-epxa10db/time.c # 2004/06/17 14:21:25-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/mach-ebsa110/core.c # 2004/06/17 14:21:25-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/mach-clps7500/core.c # 2004/06/17 14:21:25-07:00 dsaxena@plexity.net +2 -3 # Call timer_tick() # # arch/arm/mach-clps711x/time.c # 2004/06/17 14:21:25-07:00 dsaxena@plexity.net +1 -3 # Call timer_tick() # # arch/arm/kernel/time.c # 2004/06/17 14:21:25-07:00 dsaxena@plexity.net +16 -8 # Consolidate various ARM timer functions into a single timer_tick() call. # # ChangeSet # 2004/06/17 13:40:02-07:00 jmorris@redhat.com # [IPV6]: Fix OOPS in fragmentation. # # Incorrect SKB pointer is passed to output() callback # in ip6_fragment(). # # Work done by James Morris and Yoshifuji Hideaki. # # Signed-off-by: James Morris # Signed-off-by: Yoshifuji Hideaki # Signed-off-by: David S. Miller # # net/ipv6/ip6_output.c # 2004/06/17 13:39:47-07:00 jmorris@redhat.com +4 -6 # [IPV6]: Fix OOPS in fragmentation. # # Incorrect SKB pointer is passed to output() callback # in ip6_fragment(). # # Work done by James Morris and Yoshifuji Hideaki. # # Signed-off-by: James Morris # Signed-off-by: Yoshifuji Hideaki # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/17 16:31:52-04:00 len.brown@intel.com # [ACPI] PCI bus numbering workaround for ServerWorks # from David Shaohua Li # http://bugzilla.kernel.org/show_bug.cgi?id=1662 # # drivers/acpi/pci_root.c # 2004/06/17 12:31:13-04:00 len.brown@intel.com +48 -1 # if _BBN is bogus, evaluate _CRS on PCI bus # to get the bus number (David Shaohua Li) # # ChangeSet # 2004/06/17 12:11:42-07:00 davem@nuts.davemloft.net # [NET]: In unregister_netdevice(), do synchronize_net() before final dev_put(). # # This way we make sure that all destination cache updates # to remove references to this device are seen by entire # system before final destruction of the device. # # ChangeSet # 2004/06/17 12:09:59-07:00 davem@nuts.davemloft.net # Cset exclude: kuznet@ms2.inr.ac.ru|ChangeSet|20040616204246|05149 # # net/core/dst.c # 2004/06/17 12:09:54-07:00 davem@nuts.davemloft.net +0 -0 # Exclude # # ChangeSet # 2004/06/17 11:52:18-07:00 shemminger@osdl.org # [SPARSE]: Fix another net warning. # # Get rid of warning from assignment in conditional. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/core/net-sysfs.c # 2004/06/17 11:52:04-07:00 shemminger@osdl.org +1 -1 # [SPARSE]: Fix another net warning. # # Get rid of warning from assignment in conditional. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/17 11:40:00-07:00 shemminger@osdl.org # [SPARSE]: Get rid of warning in bridge ethtool ioctl. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # net/bridge/br_if.c # 2004/06/17 11:39:35-07:00 shemminger@osdl.org +1 -1 # [SPARSE]: Get rid of warning in bridge ethtool ioctl. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/17 11:16:48-07:00 shemminger@osdl.org # [SPARSE]: Annotate csum_and_copy_to_user(). # # include/asm-sparc64/checksum.h # 2004/06/17 11:16:34-07:00 shemminger@osdl.org +2 -1 # [SPARSE]: Annotate csum_and_copy_to_user(). # # include/asm-sparc/checksum.h # 2004/06/17 11:16:34-07:00 shemminger@osdl.org +1 -1 # [SPARSE]: Annotate csum_and_copy_to_user(). # # include/asm-sh/checksum.h # 2004/06/17 11:16:34-07:00 shemminger@osdl.org +4 -2 # [SPARSE]: Annotate csum_and_copy_to_user(). # # include/asm-parisc/checksum.h # 2004/06/17 11:16:34-07:00 shemminger@osdl.org +4 -2 # [SPARSE]: Annotate csum_and_copy_to_user(). # # include/asm-mips/checksum.h # 2004/06/17 11:16:34-07:00 shemminger@osdl.org +2 -1 # [SPARSE]: Annotate csum_and_copy_to_user(). # # include/asm-i386/checksum.h # 2004/06/17 11:16:34-07:00 shemminger@osdl.org +4 -2 # [SPARSE]: Annotate csum_and_copy_to_user(). # # ChangeSet # 2004/06/17 11:15:13-07:00 akpm@osdl.org # [BRIDGE]: Fix bridge sysfs improprely initialized kobject. # # The bridge sysfs interface introduced around 2.6.7-rc1 created a bad # entry in /sys because it didn't initialise the name member of the kobject. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # net/bridge/br_sysfs_br.c # 2004/06/17 11:14:46-07:00 akpm@osdl.org +1 -3 # [BRIDGE]: Fix bridge sysfs improprely initialized kobject. # # The bridge sysfs interface introduced around 2.6.7-rc1 created a bad # entry in /sys because it didn't initialise the name member of the kobject. # # Signed-off-by: Andrew Morton # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/17 10:56:25-07:00 shemminger@osdl.org # [SPARSE]: Add annotations to sock_filter.h # # Since sock_fprog is argument in ioctl, the filter pointer needs # to be annotated. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # include/linux/filter.h # 2004/06/17 10:56:10-07:00 shemminger@osdl.org +3 -1 # [SPARSE]: Add annotations to sock_filter.h # # Since sock_fprog is argument in ioctl, the filter pointer needs # to be annotated. # # Signed-off-by: Stephen Hemminger # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/17 10:51:14-07:00 shemminger@osdl.org # [SPARSE]: Get rid of warning in irtty_ioctl(). # # Don't really need verify_area because result of copy_to_user is checked. # Add annotation to get rid of sparse warnings. # # Signed-off-by: Stephen Hemminger # Signed-off-by: Jean Tourrilhes # Signed-off-by: David S. Miller # # drivers/net/irda/irtty-sir.c # 2004/06/17 10:50:59-07:00 shemminger@osdl.org +1 -9 # [SPARSE]: Get rid of warning in irtty_ioctl(). # # Don't really need verify_area because result of copy_to_user is checked. # Add annotation to get rid of sparse warnings. # # Signed-off-by: Stephen Hemminger # Signed-off-by: Jean Tourrilhes # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/17 11:09:05-05:00 stevef@stevef95.austin.ibm.com # fix typo in cifs kernel config option title # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/Kconfig # 2004/06/17 11:08:47-05:00 stevef@stevef95.austin.ibm.com +1 -1 # fix typo in cifs kernel config option title # # ChangeSet # 2004/06/17 13:57:37+01:00 dwmw2@shinybook.infradead.org # Workaround for MPC826x PCI erratum #9. # # include/asm-ppc/mpc8260_pci9.h # 2004/06/17 13:57:17+01:00 dwmw2@shinybook.infradead.org +51 -0 # # include/asm-ppc/mpc8260_pci9.h # 2004/06/17 13:57:17+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/include/asm-ppc/mpc8260_pci9.h # # arch/ppc/syslib/m8260_pci_erratum9.c # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +474 -0 # # include/asm-ppc/io.h # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +15 -1 # Accomodate out-of-line read[bwl] functions for 8260 PCI erratum workaround # # arch/ppc/syslib/m8260_setup.c # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +5 -0 # Initialise IDMA controller for PCI erratum workaround # # arch/ppc/syslib/m8260_pci_erratum9.c # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/arch/ppc/syslib/m8260_pci_erratum9.c # # arch/ppc/syslib/m8260_pci.h # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +7 -0 # Add setup_m8260_indirect_pci() prototype or #define # # arch/ppc/syslib/m8260_pci.c # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +3 -3 # Use m8260-specific PCI setup function to allow for erratum workaround # # arch/ppc/syslib/Makefile # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +1 -0 # Make rule for 8260 PCI erratum #9 workaround # # arch/ppc/Kconfig # 2004/06/17 13:57:15+01:00 dwmw2@shinybook.infradead.org +23 -0 # Config options for 8260 PCI erratum #9 workaround # # ChangeSet # 2004/06/17 08:32:23+01:00 dwmw2@shinybook.infradead.org # Change new Motorola copyright notices and email addresses to Freescale. # # Requested by Kumar Gala # # drivers/serial/cpm_uart/cpm_uart_cpm2.c # 2004/06/17 08:32:04+01:00 dwmw2@shinybook.infradead.org +2 -2 # s/Motorola/Freescale/ # # drivers/serial/cpm_uart/cpm_uart_cpm1.c # 2004/06/17 08:32:04+01:00 dwmw2@shinybook.infradead.org +2 -2 # s/Motorola/Freescale/ # # drivers/serial/cpm_uart/cpm_uart_core.c # 2004/06/17 08:32:04+01:00 dwmw2@shinybook.infradead.org +2 -2 # s/Motorola/Freescale/ # # drivers/serial/cpm_uart/cpm_uart.h # 2004/06/17 08:32:04+01:00 dwmw2@shinybook.infradead.org +1 -1 # s/Motorola/Freescale/ # # arch/ppc/platforms/pq2ads_setup.c # 2004/06/17 08:32:04+01:00 dwmw2@shinybook.infradead.org +2 -2 # s/Motorola/Freescale/ # # ChangeSet # 2004/06/17 02:15:36-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7-mpparse # into intel.com:/home/lenb/bk/linux-acpi-test-2.6.7 # # arch/x86_64/kernel/mpparse.c # 2004/06/17 02:15:31-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/17 01:42:44-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # into intel.com:/home/lenb/bk/linux-acpi-test-2.6.7 # # arch/x86_64/kernel/mpparse.c # 2004/06/17 01:42:37-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/ia64/pci/pci.c # 2004/06/17 01:42:37-04:00 len.brown@intel.com +0 -0 # Auto merged # # arch/ia64/kernel/iosapic.c # 2004/06/17 01:42:36-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/17 01:30:00-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.6 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.7 # # arch/i386/kernel/dmi_scan.c # 2004/06/17 01:29:57-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/06/17 01:26:33-04:00 len.brown@intel.com # [ACPI] Fix a lockup which Sid Boyce # discovered with IOAPIC disabled. # # The problem was that drivers/serial/8250_acpi.c found COM1 in the ACPI # namespace and called acpi_register_gsi() to set up its IRQ. ACPI tells us # that the COM1 IRQ is edge triggered, active high, but acpi_register_gsi() # was ignoring the edge_level argument, so it blindly set the COM1 IRQ to be # level-triggered. # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Andrew Morton # Signed-off-by: Andrew Morton # With the 2.6.7-rc3-mm1 acpi changes to arch/x86_64/kernel/mpparse.c, # mp_find_ioapic is called from a non-__init function. The fatal code # path is reached when loading device drivers for PCI devices. # # ChangeSet # 2004/06/17 01:19:49-04:00 len.brown@intel.com # [ACPI] mp_find_ioapic() oops from mp_register_gsi() on device resume # Signed-off-by: Andrew Morton # # arch/i386/kernel/mpparse.c # 2004/05/31 06:03:27-04:00 len.brown@intel.com +1 -1 # It is called from mp_register_gsi(), which is called on the device resume # path. Kernel oopses. # # Program received signal SIGEMT, Emulation trap. # mp_find_ioapic (gsi=1) at arch/i386/kernel/mpparse.c:862 # 862 { # (gdb) bt # #0 mp_find_ioapic (gsi=1) at arch/i386/kernel/mpparse.c:862 # #1 0xc0111de1 in mp_register_gsi (gsi=17, edge_level=1, active_high_low=1) # at arch/i386/kernel/mpparse.c:1042 # #2 0xc010e164 in acpi_register_gsi (gsi=17, edge_level=9, active_high_low=9) # at arch/i386/kernel/acpi/boot.c:460 # #3 0xc01ef27e in acpi_pci_irq_enable (dev=0xc16da800) at drivers/acpi/pci_irq.c:382 # # ChangeSet # 2004/06/17 01:15:58-04:00 len.brown@intel.com # [ACPI] *** Warning: "acpi_register_gsi" [drivers/serial/8250_acpi.ko] undefined! # # Signed-off-by: Andrew Morton # # arch/i386/kernel/acpi/boot.c # 2004/06/17 01:15:53-04:00 len.brown@intel.com +2 -0 # *** Warning: "acpi_register_gsi" [drivers/serial/8250_acpi.ko] undefined! # # Signed-off-by: Andrew Morton # # ChangeSet # 2004/06/17 00:24:34-04:00 jgarzik@pobox.com # [libata/IDE nvidia] shuffle pci ids # # * Mark conflicting PCI ids with CONFIG_BLK_DEV_IDE_SATA # * Move not-yet-released PCI ids to libata sata_nv driver # # drivers/scsi/sata_nv.c # 2004/06/17 00:24:28-04:00 jgarzik@pobox.com +11 -3 # [libata/IDE nvidia] shuffle pci ids # # * Mark conflicting PCI ids with CONFIG_BLK_DEV_IDE_SATA # * Move not-yet-released PCI ids to libata sata_nv driver # # drivers/ide/pci/amd74xx.c # 2004/06/17 00:24:28-04:00 jgarzik@pobox.com +6 -14 # [libata/IDE nvidia] shuffle pci ids # # * Mark conflicting PCI ids with CONFIG_BLK_DEV_IDE_SATA # * Move not-yet-released PCI ids to libata sata_nv driver # # ChangeSet # 2004/06/16 23:10:50-05:00 stevef@smfhome1.smfdom # Fix /proc/fs/cifs/Stats to handle larger return data, and correct Kconfig reference to /proc/fs/cifs/Stats # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifsfs.h # 2004/06/16 23:10:44-05:00 stevef@smfhome1.smfdom +1 -1 # update cifs version to 1.19 # # fs/cifs/cifs_debug.c # 2004/06/16 23:10:44-05:00 stevef@smfhome1.smfdom +42 -17 # fix /proc/fs/cifs/Stats to handle larger return data # # fs/cifs/CHANGES # 2004/06/16 23:10:44-05:00 stevef@smfhome1.smfdom +9 -1 # Update cifs change log for 1.19 # # fs/Kconfig # 2004/06/16 23:10:44-05:00 stevef@smfhome1.smfdom +11 -2 # Correct name of /proc/fs/cifs/Stats file. Add cifs posix extensions configure option. # # ChangeSet # 2004/06/16 21:05:55-07:00 davidm@tiger.hpl.hp.com # Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5 # into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # # arch/ia64/kernel/gate.S # 2004/06/16 21:05:50-07:00 davidm@tiger.hpl.hp.com +0 -4 # Auto merged # # arch/ia64/kernel/fsys.S # 2004/06/16 21:05:50-07:00 davidm@tiger.hpl.hp.com +0 -2 # Auto merged # # ChangeSet # 2004/06/16 20:53:53-07:00 davidm@tiger.hpl.hp.com # ia64: Nuke two warnings in mca.c that showed in the simulator configuration. # # arch/ia64/kernel/mca.c # 2004/06/16 20:53:46-07:00 davidm@tiger.hpl.hp.com +8 -0 # (ia64_mca_cpe_int_handler): Define only if CONFIG_ACPI is defined. # (ia64_mca_cpe_int_caller): Likewise. # # ChangeSet # 2004/06/16 20:51:30-07:00 davidm@tiger.hpl.hp.com # ia64: Fix ia32 partial-page-list code to compile cleanly in more configs. # # # include/asm-ia64/ia32.h # 2004/06/16 20:51:21-07:00 davidm@tiger.hpl.hp.com +9 -3 # (IA32_PAGE_SHIFT): Move to here from ia32priv.h. # (ia32_copy_partial_page_list): Declare unconditionally. If # PAGE_SHIFT == IA32_PAGE_SHIFT< define it as a no-op. # (ia32_drop_partial_page_list): Likewise. # # arch/ia64/kernel/process.c # 2004/06/16 20:51:21-07:00 davidm@tiger.hpl.hp.com +2 -6 # (flush_thread): Remove #ifdef CONFIG_IA32_SUPPORT bracket (no longer needed). # Pass task-pointer to ia32_drop_partial_page_list() instead of # partial-page list (the thread.ppl member may not exist in all # configurations). # (exit_thread): Likewise. # # arch/ia64/ia32/sys_ia32.c # 2004/06/16 20:51:21-07:00 davidm@tiger.hpl.hp.com +8 -5 # (ia32_drop_partial_page_list): Take task-pointer instead of partial_page_list- # pointer. # (sys32_munmap): Declare pstart and pend only when really needed. # (sys32_mremap): Likewise. # # arch/ia64/ia32/ia32priv.h # 2004/06/16 20:51:21-07:00 davidm@tiger.hpl.hp.com +7 -4 # (_ASM_IA64_IA32_PRIV_H): Rename from _ASM_IA64_IA32_H to avoid name-clash. # (IA32_PAGE_SHIFT): Move to include/asm-ia64/ia32.h. # (ia32_init_pp_list): Define as 0 for case swhere PAGE_SHIFT==IA32_PAGE_SHIFT. # # ChangeSet # 2004/06/16 23:44:40-04:00 jgarzik@pobox.com # [libata] put nvidia in Kconfig, in alphabetical order # # drivers/scsi/Kconfig # 2004/06/16 23:44:34-04:00 jgarzik@pobox.com +8 -8 # [libata] put nvidia in Kconfig, in alphabetical order # # ChangeSet # 2004/06/16 23:42:01-04:00 achew@nvidia.com # [libata] Add NVIDIA SATA driver # # drivers/scsi/sata_nv.c # 2004/06/16 23:41:55-04:00 achew@nvidia.com +1 -1 # [libata] Add NVIDIA SATA driver # # drivers/scsi/Makefile # 2004/06/16 23:41:55-04:00 achew@nvidia.com +1 -0 # [libata] Add NVIDIA SATA driver # # drivers/scsi/Kconfig # 2004/06/16 23:41:55-04:00 achew@nvidia.com +8 -0 # [libata] Add NVIDIA SATA driver # # drivers/scsi/sata_nv.c # 2004/06/16 23:40:44-04:00 jgarzik@pobox.com +345 -0 # # drivers/scsi/sata_nv.c # 2004/06/16 23:40:44-04:00 jgarzik@pobox.com +0 -0 # BitKeeper file /spare/repo/libata-2.6/drivers/scsi/sata_nv.c # # ChangeSet # 2004/06/16 23:29:08-04:00 jgarzik@pobox.com # [IDE] Introduce SATA enable/disable config option # # This config option is introduced to help reduce user confusion, # and eliminate conflicts between the IDE driver (which is often # built into user kernels) and the new libata SATA driver. # # drivers/ide/pci/siimage.c # 2004/06/16 23:29:02-04:00 jgarzik@pobox.com +3 -0 # [IDE] Introduce SATA enable/disable config option # # This config option is introduced to help reduce user confusion, # and eliminate conflicts between the IDE driver (which is often # built into user kernels) and the new libata SATA driver. # # drivers/ide/pci/piix.c # 2004/06/16 23:29:02-04:00 jgarzik@pobox.com +2 -2 # [IDE] Introduce SATA enable/disable config option # # This config option is introduced to help reduce user confusion, # and eliminate conflicts between the IDE driver (which is often # built into user kernels) and the new libata SATA driver. # # drivers/ide/pci/generic.c # 2004/06/16 23:29:02-04:00 jgarzik@pobox.com +2 -0 # [IDE] Introduce SATA enable/disable config option # # This config option is introduced to help reduce user confusion, # and eliminate conflicts between the IDE driver (which is often # built into user kernels) and the new libata SATA driver. # # drivers/ide/Kconfig # 2004/06/16 23:29:02-04:00 jgarzik@pobox.com +20 -0 # [IDE] Introduce SATA enable/disable config option # # This config option is introduced to help reduce user confusion, # and eliminate conflicts between the IDE driver (which is often # built into user kernels) and the new libata SATA driver. # # arch/ia64/kernel/head.S # 2004/06/16 18:09:33-07:00 davidm@tiger.hpl.hp.com +5 -1 # (_start): Initialize "current" pointer for init-task to be in # region 5, not 7. # # arch/ia64/kernel/entry.S # 2004/06/16 18:09:33-07:00 davidm@tiger.hpl.hp.com +4 -2 # (ia64_switch_to): Don't try to map "current"-pointers which are # inside region 5. # # arch/ia64/ia32/ia32_support.c # 2004/06/16 18:09:33-07:00 davidm@tiger.hpl.hp.com +10 -6 # ia64: Move "current" pointer for init-task from region 7 to region 5. # # This patch initializes "current" for the init-task such that it will # be an address in region 5 rather than region 7. Also, it updates the # context-switch code such that it won't attempt to install a pinned TLB # entry when the current task points inside region 5 (as will happen now # with the init-task). # # This fixes a problem which was triggered by SELinux. The problem was # due to the fact that the init_task is initialized statically (in # init_tasks.c) and hence resides in region 5, but the "current" pointer # was using the region 7-alias of that data-structure, which causes # inconsistencies and failers with the list-maniplulation code. # # Signed-off-by: Kazuto MIYOSHI # Signed-off-by: Takayoshi Kochi # Signed-off-by: Kaigai Kohei # Signed-off-by: David Mosberger # # ChangeSet # 2004/06/16 19:57:30-04:00 jgarzik@pobox.com # Merge pobox.com:/spare/repo/netdev-2.6/via-rhine # into pobox.com:/spare/repo/net-drivers-2.6 # # drivers/net/via-rhine.c # 2004/06/16 19:57:26-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # ChangeSet # 2004/06/16 19:56:25-04:00 jgarzik@pobox.com # Merge pobox.com:/spare/repo/netdev-2.6/via-gbit # into pobox.com:/spare/repo/net-drivers-2.6 # # drivers/net/Kconfig # 2004/06/16 19:56:21-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # ChangeSet # 2004/06/16 19:54:04-04:00 jgarzik@pobox.com # Merge pobox.com:/spare/repo/netdev-2.6/misc-herbert # into pobox.com:/spare/repo/net-drivers-2.6 # # drivers/net/yellowfin.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/sungem.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/starfire.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/ns83820.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/natsemi.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/ibmlana.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/forcedeth.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/ewrk3.c # 2004/06/16 19:54:01-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/at1700.c # 2004/06/16 19:54:00-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/acenic.c # 2004/06/16 19:54:00-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/3c527.c # 2004/06/16 19:54:00-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # ChangeSet # 2004/06/16 19:51:21-04:00 jgarzik@pobox.com # Merge pobox.com:/spare/repo/netdev-2.6/ip-copysum # into pobox.com:/spare/repo/net-drivers-2.6 # # drivers/net/yellowfin.c # 2004/06/16 19:51:17-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/tulip/winbond-840.c # 2004/06/16 19:51:17-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/natsemi.c # 2004/06/16 19:51:17-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # drivers/net/epic100.c # 2004/06/16 19:51:17-04:00 jgarzik@pobox.com +0 -0 # Auto merged # # ChangeSet # 2004/06/16 16:51:07-07:00 jbarnes@engr.sgi.com # [PATCH] ia64: update sn2_defconfig # # Small patch to update the sn2_defconfig file. I just did a 'make oldconfig' # with the current sn2_defconfig and removed 8250 support. # Signed-off-by: David Mosberger # # arch/ia64/configs/sn2_defconfig # 2004/06/16 09:03:12-07:00 jbarnes@engr.sgi.com +51 -55 # ia64: update sn2_defconfig # # ChangeSet # 2004/06/16 16:04:19-07:00 kaos@sgi.com # [PATCH] ia64: Support SN platform specific error features # # The SN prom supports fine grained error handling features, the OS needs # to tell the prom if the OS expects to use these platform specific # features. # # Signed-off-by: Keith Owens # Signed-off-by: David Mosberger # # include/asm-ia64/sn/sn_sal.h # 2004/06/16 06:14:42-07:00 kaos@sgi.com +34 -0 # ia64: Support SN platform specific error features # # arch/ia64/sn/kernel/setup.c # 2004/06/16 06:14:42-07:00 kaos@sgi.com +22 -1 # ia64: Support SN platform specific error features # # ChangeSet # 2004/06/17 00:01:45+01:00 dwmw2@shinybook.infradead.org # Add support for i8259 IRQ controller on WindRiver PowerQUICC II # # arch/ppc/platforms/sbc82xx.h # 2004/06/17 00:01:26+01:00 dwmw2@shinybook.infradead.org +9 -0 # Define i8259 IRQ numbers. # # arch/ppc/platforms/sbc82xx.c # 2004/06/17 00:01:26+01:00 dwmw2@shinybook.infradead.org +154 -0 # Add support for i8259 interrupt controller. # # ChangeSet # 2004/06/16 23:56:26+01:00 dwmw2@shinybook.infradead.org # PCI host bridge support for Motorola MPC826x # # include/asm-ppc/m8260_pci.h # 2004/06/16 23:56:05+01:00 dwmw2@shinybook.infradead.org +186 -0 # # include/asm-ppc/m8260_pci.h # 2004/06/16 23:56:05+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/include/asm-ppc/m8260_pci.h # # arch/ppc/syslib/m8260_pci.h # 2004/06/16 23:56:03+01:00 dwmw2@shinybook.infradead.org +68 -0 # # arch/ppc/syslib/m8260_pci.h # 2004/06/16 23:56:03+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/arch/ppc/syslib/m8260_pci.h # # arch/ppc/syslib/m8260_pci.c # 2004/06/16 23:56:02+01:00 dwmw2@shinybook.infradead.org +194 -0 # # arch/ppc/syslib/m8260_setup.c # 2004/06/16 23:56:02+01:00 dwmw2@shinybook.infradead.org +4 -0 # Initialise 8260 PCI if present. # # arch/ppc/syslib/m8260_pci.c # 2004/06/16 23:56:02+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/arch/ppc/syslib/m8260_pci.c # # arch/ppc/syslib/Makefile # 2004/06/16 23:56:02+01:00 dwmw2@shinybook.infradead.org +1 -0 # Add rules for 8260 PCI # # arch/ppc/Kconfig # 2004/06/16 23:56:02+01:00 dwmw2@shinybook.infradead.org +5 -0 # Add PCI_8260 option. # # ChangeSet # 2004/06/16 23:37:43+01:00 dwmw2@shinybook.infradead.org # PPC SBC82xx: Move RTC to 0xd0000000 to make room for PCI I/O stuff. # # arch/ppc/platforms/sbc82xx.h # 2004/06/16 23:37:12+01:00 dwmw2@shinybook.infradead.org +1 -1 # Move RTC to 0xd0000000 to avoid conflicting with where we want PCI. # # arch/ppc/platforms/sbc82xx.c # 2004/06/16 23:37:12+01:00 dwmw2@shinybook.infradead.org +5 -3 # Honour SBC82xx_TODC_NVRAM_ADDR when setting up BR11 for RTC. # # ChangeSet # 2004/06/16 23:31:12+01:00 dwmw2@shinybook.infradead.org # Remove old MPC82xx (CPM2) uart driver # # arch/ppc/Kconfig # 2004/06/16 23:30:54+01:00 dwmw2@shinybook.infradead.org +1 -1 # SERIAL_CONSOLE only relevant for 8xx now. # # arch/ppc/8260_io/Makefile # 2004/06/16 23:30:54+01:00 dwmw2@shinybook.infradead.org +0 -2 # Remove old uart driver # # arch/ppc/8260_io/Kconfig # 2004/06/16 23:30:54+01:00 dwmw2@shinybook.infradead.org +0 -3 # Remove SCC_CONSOLE option # # BitKeeper/deleted/.del-uart.c~c6dfa4adcc8b2a32 # 2004/06/16 23:29:28+01:00 dwmw2@shinybook.infradead.org +0 -0 # Delete: arch/ppc/8260_io/uart.c # # ChangeSet # 2004/06/16 23:29:15+01:00 dwmw2@shinybook.infradead.org # UART driver for Motorola CPM/CPM2 I/O core on 8xx/8xxx chips. # # drivers/serial/cpm_uart/cpm_uart_cpm2.h # 2004/06/16 23:28:56+01:00 dwmw2@shinybook.infradead.org +45 -0 # # drivers/serial/cpm_uart/cpm_uart_cpm2.h # 2004/06/16 23:28:56+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/drivers/serial/cpm_uart/cpm_uart_cpm2.h # # drivers/serial/cpm_uart/cpm_uart_cpm2.c # 2004/06/16 23:28:54+01:00 dwmw2@shinybook.infradead.org +327 -0 # # drivers/serial/cpm_uart/cpm_uart_cpm2.c # 2004/06/16 23:28:54+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/drivers/serial/cpm_uart/cpm_uart_cpm2.c # # drivers/serial/cpm_uart/cpm_uart_cpm1.h # 2004/06/16 23:28:53+01:00 dwmw2@shinybook.infradead.org +45 -0 # # drivers/serial/cpm_uart/cpm_uart_cpm1.h # 2004/06/16 23:28:53+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/drivers/serial/cpm_uart/cpm_uart_cpm1.h # # drivers/serial/cpm_uart/cpm_uart_cpm1.c # 2004/06/16 23:28:51+01:00 dwmw2@shinybook.infradead.org +275 -0 # # drivers/serial/cpm_uart/cpm_uart_cpm1.c # 2004/06/16 23:28:51+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/drivers/serial/cpm_uart/cpm_uart_cpm1.c # # drivers/serial/cpm_uart/cpm_uart_core.c # 2004/06/16 23:28:50+01:00 dwmw2@shinybook.infradead.org +1177 -0 # # drivers/serial/cpm_uart/cpm_uart_core.c # 2004/06/16 23:28:50+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/drivers/serial/cpm_uart/cpm_uart_core.c # # drivers/serial/cpm_uart/cpm_uart.h # 2004/06/16 23:28:48+01:00 dwmw2@shinybook.infradead.org +89 -0 # # drivers/serial/cpm_uart/cpm_uart.h # 2004/06/16 23:28:48+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/drivers/serial/cpm_uart/cpm_uart.h # # drivers/serial/cpm_uart/Makefile # 2004/06/16 23:28:47+01:00 dwmw2@shinybook.infradead.org +11 -0 # # include/linux/serial_core.h # 2004/06/16 23:28:47+01:00 dwmw2@shinybook.infradead.org +3 -0 # Add PORT_CPM definition # # drivers/serial/cpm_uart/Makefile # 2004/06/16 23:28:47+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/drivers/serial/cpm_uart/Makefile # # drivers/serial/Makefile # 2004/06/16 23:28:47+01:00 dwmw2@shinybook.infradead.org +1 -0 # Add CPM/CPM2 UART directory # # drivers/serial/Kconfig # 2004/06/16 23:28:47+01:00 dwmw2@shinybook.infradead.org +60 -0 # Add CPM/CPM2 UART options # # ChangeSet # 2004/06/16 18:25:29-04:00 alan@redhat.com # [PATCH] add new via-velocity gigabit ethernet driver # # Contributed by VIA, cleaned up by Alan. # # drivers/net/via-velocity.h # 2004/06/02 15:49:48-04:00 alan@redhat.com +1885 -0 # PATCH: via-velocity with new ethtool used # # drivers/net/via-velocity.h # 2004/06/02 15:49:48-04:00 alan@redhat.com +0 -0 # BitKeeper file /spare/repo/netdev-2.6/via-gbit/drivers/net/via-velocity.h # # drivers/net/via-velocity.c # 2004/06/16 17:29:42-04:00 alan@redhat.com +3277 -0 # PATCH: via-velocity with new ethtool used # # drivers/net/Makefile # 2004/06/16 16:22:14-04:00 alan@redhat.com +1 -0 # PATCH: via-velocity with new ethtool used # # drivers/net/Kconfig # 2004/06/16 16:22:14-04:00 alan@redhat.com +11 -0 # PATCH: via-velocity with new ethtool used # # drivers/net/via-velocity.c # 2004/06/16 17:29:42-04:00 alan@redhat.com +0 -0 # BitKeeper file /spare/repo/netdev-2.6/via-gbit/drivers/net/via-velocity.c # # ChangeSet # 2004/06/16 15:52:13-05:00 stevef@stevef95.austin.ibm.com # fix throttle to limit number of requests to 50 on wire to server at one time. # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/transport.c # 2004/06/16 15:52:04-05:00 stevef@stevef95.austin.ibm.com +20 -13 # fix throttle to limit number of requests to 50 on wire to server at one time. # # ChangeSet # 2004/06/16 13:48:12-07:00 davem@nuts.davemloft.net # [TCP]: No vegas by default just yet. # # net/ipv4/tcp_input.c # 2004/06/16 13:47:53-07:00 davem@nuts.davemloft.net +1 -1 # [TCP]: No vegas by default just yet. # # ChangeSet # 2004/06/16 19:22:55+01:00 dwmw2@shinybook.infradead.org # PPC: Add support for ADS8272 board. # # From Kumar Gala # # arch/ppc/platforms/pq2ads_setup.c # 2004/06/16 19:22:38+01:00 dwmw2@shinybook.infradead.org +66 -0 # # arch/ppc/platforms/pq2ads_setup.c # 2004/06/16 19:22:38+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/arch/ppc/platforms/pq2ads_setup.c # # arch/ppc/platforms/pq2ads.h # 2004/06/16 19:22:36+01:00 dwmw2@shinybook.infradead.org +90 -0 # # arch/ppc/platforms/pq2ads.h # 2004/06/16 19:22:36+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/arch/ppc/platforms/pq2ads.h # # arch/ppc/configs/ads8272_defconfig # 2004/06/16 19:22:35+01:00 dwmw2@shinybook.infradead.org +583 -0 # # include/asm-ppc/mpc8260.h # 2004/06/16 19:22:35+01:00 dwmw2@shinybook.infradead.org +4 -0 # Add PQ2ADS boards support. # # arch/ppc/platforms/Makefile # 2004/06/16 19:22:35+01:00 dwmw2@shinybook.infradead.org +1 -0 # Add PQ2ADS boards support # # arch/ppc/configs/ads8272_defconfig # 2004/06/16 19:22:35+01:00 dwmw2@shinybook.infradead.org +0 -0 # BitKeeper file /home/dwmw2/bk/new82xx-2.6/arch/ppc/configs/ads8272_defconfig # # arch/ppc/Kconfig # 2004/06/16 19:22:35+01:00 dwmw2@shinybook.infradead.org +17 -0 # Add ADS8272, PQ2ADS and generic 8272 config options # # arch/ppc/8260_io/fcc_enet.c # 2004/06/16 19:22:35+01:00 dwmw2@shinybook.infradead.org +99 -13 # Add support for ADS8272 board and Davicom DM9131 PHY # # ChangeSet # 2004/06/16 11:18:42-07:00 dada1@cosmosbay.com # [NET]: Tidy somaxconn sysctl doc. # # Documentation/networking/ip-sysctl.txt # 2004/06/16 11:18:23-07:00 dada1@cosmosbay.com +3 -2 # [NET]: Tidy somaxconn sysctl doc. # # ChangeSet # 2004/06/16 19:08:12+01:00 dwmw2@shinybook.infradead.org # PPC: Move CPM2 common core routines to arch/ppc/syslib/ # # arch/ppc/syslib/Makefile # 2004/06/16 19:07:54+01:00 dwmw2@shinybook.infradead.org +1 -0 # Move cpm2_common.c from 8260_io/commproc.c # # arch/ppc/8260_io/Makefile # 2004/06/16 19:07:54+01:00 dwmw2@shinybook.infradead.org +1 -1 # Move commproc.c to syslib/cpm2_common.c # # arch/ppc/syslib/cpm2_common.c # 2004/06/16 19:02:28+01:00 dwmw2@shinybook.infradead.org +0 -0 # Rename: arch/ppc/8260_io/commproc.c -> arch/ppc/syslib/cpm2_common.c # # ChangeSet # 2004/06/16 10:57:05-07:00 dlstevens@us.ibm.com # [IPV4]: Fix interface selection in multicast sockops. # # net/ipv4/ip_sockglue.c # 2004/06/16 10:56:46-07:00 dlstevens@us.ibm.com +1 -0 # [IPV4]: Fix interface selection in multicast sockops. # # ChangeSet # 2004/06/16 18:56:31+01:00 dwmw2@shinybook.infradead.org # PPC: Make Motorola CPM2 I/O core support more generic. # It's used on more than one CPU. # # include/asm-ppc/ppcboot.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +2 -2 # Make Motorola CPM2 I/O core support more generic # # include/asm-ppc/irq.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +40 -2 # Add the rest of the SIU interrupts # # include/asm-ppc/immap_cpm2.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +544 -329 # Make Motorola CPM2 I/O core support more generic # # include/asm-ppc/cpm2.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +364 -29 # Make Motorola CPM2 I/O core support more generic # # drivers/mtd/maps/wr_sbc82xx_flash.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +2 -2 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/syslib/m8260_setup.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +14 -14 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/syslib/cpm2_pic.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +7 -7 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/syslib/cpm2_pic.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +21 -21 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/syslib/Makefile # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +1 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/platforms/tqm8260_setup.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +4 -4 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/platforms/tqm8260.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +1 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/platforms/sbs8260.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +1 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/platforms/sbc82xx.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +0 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/platforms/sbc82xx.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +2 -2 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/platforms/rpxsuper.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +1 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/platforms/est8260.h # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +1 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/boot/simple/m8260_tty.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +12 -11 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/boot/simple/embed_config.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +5 -5 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/Makefile # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +1 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/Kconfig # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +23 -14 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/8260_io/uart.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +58 -58 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/8260_io/fcc_enet.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +22 -22 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/8260_io/enet.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +12 -12 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/8260_io/commproc.c # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +16 -19 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/8260_io/Makefile # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +1 -1 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/8260_io/Kconfig # 2004/06/16 18:56:13+01:00 dwmw2@shinybook.infradead.org +6 -6 # Make Motorola CPM2 I/O core support more generic # # arch/ppc/syslib/cpm2_pic.h # 2004/06/16 18:53:02+01:00 dwmw2@shinybook.infradead.org +0 -0 # Rename: arch/ppc/syslib/ppc8260_pic.h -> arch/ppc/syslib/cpm2_pic.h # # arch/ppc/syslib/cpm2_pic.c # 2004/06/16 18:52:55+01:00 dwmw2@shinybook.infradead.org +0 -0 # Rename: arch/ppc/syslib/ppc8260_pic.c -> arch/ppc/syslib/cpm2_pic.c # # include/asm-ppc/cpm2.h # 2004/06/16 18:31:46+01:00 dwmw2@shinybook.infradead.org +0 -0 # Rename: include/asm-ppc/cpm_8260.h -> include/asm-ppc/cpm2.h # # include/asm-ppc/immap_cpm2.h # 2004/06/16 18:31:24+01:00 dwmw2@shinybook.infradead.org +0 -0 # Rename: include/asm-ppc/immap_8260.h -> include/asm-ppc/immap_cpm2.h # # ChangeSet # 2004/06/16 10:27:13-07:00 herbert@gondor.apana.org.au # [NET]: Clear dev refs in dst->child. # # This is a resend of an earlier patch to dst_dev_event. I've changed # it slightly by moving the input/output assignment into dst_ifdown. # # To recap, this patch drops lingering IPsec references to a device that # is being unregistered. The child processing in the GC is too late # since it never runs until the reference on the dst hits zero which # could take a long time for things like TCP connections. # # The reason I've left the input/output assignment outside the loop is # because they aren't really necessary for the IPsec dst's, and if # it were in the loop then we'll have to do the same child processing # in ___dst_free as well. # # I've tested this with an ESP/IPCOMP tunnel and I can confirm that it # does fix the problem. # # Signed-off-by: Herbert Xu # Signed-off-by: David S. Miller # # net/core/dst.c # 2004/06/16 10:26:56-07:00 herbert@gondor.apana.org.au +37 -25 # [NET]: Clear dev refs in dst->child. # # This is a resend of an earlier patch to dst_dev_event. I've changed # it slightly by moving the input/output assignment into dst_ifdown. # # To recap, this patch drops lingering IPsec references to a device that # is being unregistered. The child processing in the GC is too late # since it never runs until the reference on the dst hits zero which # could take a long time for things like TCP connections. # # The reason I've left the input/output assignment outside the loop is # because they aren't really necessary for the IPsec dst's, and if # it were in the loop then we'll have to do the same child processing # in ___dst_free as well. # # I've tested this with an ESP/IPCOMP tunnel and I can confirm that it # does fix the problem. # # Signed-off-by: Herbert Xu # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/16 10:23:42-07:00 davem@nuts.davemloft.net # Merge nuts.davemloft.net:/disk1/BK/net-2.6.8 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/ipv4/tcp.c # 2004/06/16 10:23:34-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/16 11:36:45-05:00 jejb@mulgrave.(none) # scsi_debug: num_parts, ptype and (re-)scans # # From: Douglas Gilbert # # Changes in version 1.73: # - 'num_parts' parameter to specify 0 to 4 partitions # - 'ptype' to specify (or change via sysfs) SCSI # peripheral device type # - support ability to increase the number of targets # and/or luns then re-scan a scsi_debug host # - remove redundant trailing spaces # # The new facilties are described at: # http://www.torque.net/sg/sdebug26.html # A tarball of driver (version 1.73) is also there. # # Signed-off-by: James Bottomley # (conflict resolution) # # drivers/scsi/scsi_debug.h # 2004/06/16 11:36:19-05:00 jejb@mulgrave.(none) +1 -4 # scsi_debug: num_parts, ptype and (re-)scans # # drivers/scsi/scsi_debug.c # 2004/06/16 11:36:19-05:00 jejb@mulgrave.(none) +253 -124 # scsi_debug: num_parts, ptype and (re-)scans # # ChangeSet # 2004/06/16 09:32:58-05:00 jejb@mulgrave.(none) # SCSI: fix uninitialised variable warning # # Spotted By: Andrew Morton # # drivers/scsi/scsi_transport_spi.c: In function `spi_dv_retrain': # drivers/scsi/scsi_transport_spi.c:393: warning: `period' might be used uninitialized in this function # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_transport_spi.c # 2004/06/16 09:32:42-05:00 jejb@mulgrave.(none) +1 -1 # SCSI: fix uninitialised variable warning # # ChangeSet # 2004/06/15 21:46:23-07:00 jmorris@redhat.com # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/ss/services.c # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +12 -0 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/ss/policydb.c # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +9 -1 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/security.h # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +5 -4 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/flask.h # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +9 -0 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/class_to_string.h # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +9 -0 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/av_permissions.h # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +223 -0 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/av_perm_to_string.h # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +12 -0 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/av_inherit.h # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +9 -0 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/hooks.c # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +80 -22 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/Makefile # 2004/06/15 21:46:08-07:00 jmorris@redhat.com +1 -1 # [SELINUX]: Fine-grained Netlink support - SELinux changes # # This patch contains SELinux changes which add support for extended Netlink # socket classes and the associated permissions nlmsg_read and nlmsg_write. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 21:45:30-07:00 jmorris@redhat.com # [SELINUX]: Fine-grained Netlink support - add sk to netlink_send hook # # Modifies the LSM netlink_send() hook so that it takes a struct sock # parameter. SELinux will use this parameter to lookup the class of socket, # which was assigned during socket security initialization. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/hooks.c # 2004/06/15 21:45:15-07:00 jmorris@redhat.com +1 -1 # [SELINUX]: Fine-grained Netlink support - add sk to netlink_send hook # # Modifies the LSM netlink_send() hook so that it takes a struct sock # parameter. SELinux will use this parameter to lookup the class of socket, # which was assigned during socket security initialization. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/dummy.c # 2004/06/15 21:45:15-07:00 jmorris@redhat.com +1 -1 # [SELINUX]: Fine-grained Netlink support - add sk to netlink_send hook # # Modifies the LSM netlink_send() hook so that it takes a struct sock # parameter. SELinux will use this parameter to lookup the class of socket, # which was assigned during socket security initialization. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # net/netlink/af_netlink.c # 2004/06/15 21:45:15-07:00 jmorris@redhat.com +1 -1 # [SELINUX]: Fine-grained Netlink support - add sk to netlink_send hook # # Modifies the LSM netlink_send() hook so that it takes a struct sock # parameter. SELinux will use this parameter to lookup the class of socket, # which was assigned during socket security initialization. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # include/linux/security.h # 2004/06/15 21:45:15-07:00 jmorris@redhat.com +11 -8 # [SELINUX]: Fine-grained Netlink support - add sk to netlink_send hook # # Modifies the LSM netlink_send() hook so that it takes a struct sock # parameter. SELinux will use this parameter to lookup the class of socket, # which was assigned during socket security initialization. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 21:44:40-07:00 jmorris@redhat.com # [SELINUX]: Fine-grained Netlink support - move security_netlink_send() hook. # # This patch moves the security_netlink_send() LSM hook after the user copy, # so that LSM modules can safely examine skb payload content. For SELinux, # we need to look at the Netlink message type. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # net/netlink/af_netlink.c # 2004/06/15 21:44:26-07:00 jmorris@redhat.com +4 -4 # [SELINUX]: Fine-grained Netlink support - move security_netlink_send() hook. # # This patch moves the security_netlink_send() LSM hook after the user copy, # so that LSM modules can safely examine skb payload content. For SELinux, # we need to look at the Netlink message type. # # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 21:42:03-07:00 jmorris@redhat.com # [SELINUX]: Fine-grained Netlink support - SELinux headers # # This patch regenerates the SELinux module headers to reflect new class # and access vectors definitions. The size of the diff is misleading; # much of it is simply a change in the ordering of the automatically # generated definitions. The corresponding generation script has been # changed to ensure a stable order in the future. # # Author: Stephen Smalley # Signed-off-by: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/flask.h # 2004/06/15 21:41:48-07:00 jmorris@redhat.com +12 -0 # [SELINUX]: Fine-grained Netlink support - SELinux headers # # This patch regenerates the SELinux module headers to reflect new class # and access vectors definitions. The size of the diff is misleading; # much of it is simply a change in the ordering of the automatically # generated definitions. The corresponding generation script has been # changed to ensure a stable order in the future. # # Author: Stephen Smalley # Signed-off-by: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/class_to_string.h # 2004/06/15 21:41:48-07:00 jmorris@redhat.com +12 -0 # [SELINUX]: Fine-grained Netlink support - SELinux headers # # This patch regenerates the SELinux module headers to reflect new class # and access vectors definitions. The size of the diff is misleading; # much of it is simply a change in the ordering of the automatically # generated definitions. The corresponding generation script has been # changed to ensure a stable order in the future. # # Author: Stephen Smalley # Signed-off-by: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/av_permissions.h # 2004/06/15 21:41:48-07:00 jmorris@redhat.com +350 -250 # [SELINUX]: Fine-grained Netlink support - SELinux headers # # This patch regenerates the SELinux module headers to reflect new class # and access vectors definitions. The size of the diff is misleading; # much of it is simply a change in the ordering of the automatically # generated definitions. The corresponding generation script has been # changed to ensure a stable order in the future. # # Author: Stephen Smalley # Signed-off-by: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/include/av_perm_to_string.h # 2004/06/15 21:41:48-07:00 jmorris@redhat.com +89 -3 # [SELINUX]: Fine-grained Netlink support - SELinux headers # # This patch regenerates the SELinux module headers to reflect new class # and access vectors definitions. The size of the diff is misleading; # much of it is simply a change in the ordering of the automatically # generated definitions. The corresponding generation script has been # changed to ensure a stable order in the future. # # Author: Stephen Smalley # Signed-off-by: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 21:39:10-07:00 anton@samba.org # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # include/linux/skbuff.h # 2004/06/15 21:38:55-07:00 anton@samba.org +24 -0 # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # include/asm-ppc64/system.h # 2004/06/15 21:38:55-07:00 anton@samba.org +9 -0 # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # drivers/net/s2io.h # 2004/06/15 21:38:55-07:00 anton@samba.org +0 -1 # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # drivers/net/s2io.c # 2004/06/15 21:38:55-07:00 anton@samba.org +2 -2 # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # drivers/net/ixgb/ixgb_main.c # 2004/06/15 21:38:55-07:00 anton@samba.org +2 -3 # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # drivers/net/e1000/e1000_main.c # 2004/06/15 21:38:55-07:00 anton@samba.org +2 -3 # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # drivers/net/e1000/e1000_ethtool.c # 2004/06/15 21:38:55-07:00 anton@samba.org +3 -2 # [NET]: Allow IP header alignment to be overriden. # # Author: Anton Blanchard # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 21:37:06-07:00 shemminger@osdl.org # [ATM]: Include compiler.h in atm.h # # include/linux/atm.h # 2004/06/15 21:36:52-07:00 shemminger@osdl.org +1 -0 # [ATM]: Include compiler.h in atm.h # # ChangeSet # 2004/06/15 21:35:21-07:00 davem@nuts.davemloft.net # [TCP]: Tweak some default sysctl values. # # tcp_default_win_scale: 7 # tcp_vegas_cong_avoid: 1 # tcp_moderate_rcvbuf: 1 # tcp_bic: 1 # # net/ipv4/tcp_input.c # 2004/06/15 21:18:53-07:00 davem@nuts.davemloft.net +3 -3 # [TCP]: Tweak some default sysctl values. # # tcp_default_win_scale: 7 # tcp_vegas_cong_avoid: 1 # tcp_moderate_rcvbuf: 1 # tcp_bic: 1 # # net/ipv4/tcp.c # 2004/06/15 21:18:53-07:00 davem@nuts.davemloft.net +1 -1 # [TCP]: Tweak some default sysctl values. # # tcp_default_win_scale: 7 # tcp_vegas_cong_avoid: 1 # tcp_moderate_rcvbuf: 1 # tcp_bic: 1 # # ChangeSet # 2004/06/15 21:09:47-07:00 yoshfuji@linux-ipv6.org # [IPV6]: UDPv6 checksum. # # We always need to check UDPv6 checksum because it is mandatory. # # Author: Yoshifuji Hideaki # Signed-off-by: David S. Miller # # net/ipv6/udp.c # 2004/06/15 21:09:31-07:00 yoshfuji@linux-ipv6.org +1 -1 # [IPV6]: UDPv6 checksum. # # We always need to check UDPv6 checksum because it is mandatory. # # Author: Yoshifuji Hideaki # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 21:07:24-07:00 jmorris@redhat.com # [SELINUX]: Fix sock_orphan race. # # The patch below fixes a race between sock_orphan() and # selinux_socket_sock_rcv_skb() which can lead to a null pointer deref oops # under heavy load. The sk_callback_lock is used in the patch to # synchronize access to the incoming socket's inode security state. # # This patch has been under test in the Fedora kernel for over a month # without incident. # # Author: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # security/selinux/hooks.c # 2004/06/15 21:07:09-07:00 jmorris@redhat.com +21 -16 # [SELINUX]: Fix sock_orphan race. # # The patch below fixes a race between sock_orphan() and # selinux_socket_sock_rcv_skb() which can lead to a null pointer deref oops # under heavy load. The sk_callback_lock is used in the patch to # synchronize access to the incoming socket's inode security state. # # This patch has been under test in the Fedora kernel for over a month # without incident. # # Author: Stephen Smalley # Signed-off-by: James Morris # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 20:37:41-07:00 hadi@znyx.com # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/sch_prio.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +58 -14 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/sch_ingress.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +64 -8 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/police.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +329 -1 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/cls_u32.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +179 -8 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/cls_tcindex.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +2 -2 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/cls_rsvp.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +3 -3 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/cls_route.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +3 -3 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/cls_fw.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +174 -3 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/cls_api.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +18 -5 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/Makefile # 2004/06/15 20:37:18-07:00 hadi@znyx.com +3 -1 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/Kconfig # 2004/06/15 20:37:18-07:00 hadi@znyx.com +33 -2 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/ethernet/eth.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +3 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/core/skbuff.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +23 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/core/rtnetlink.c # 2004/06/15 20:37:18-07:00 hadi@znyx.com +4 -2 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/net/pkt_sched.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +76 -4 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/net/pkt_cls.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +30 -2 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/linux/skbuff.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +9 -1 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/linux/rtnetlink.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +17 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/linux/pkt_sched.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +1 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/linux/pkt_cls.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +163 -8 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/linux/netdevice.h # 2004/06/15 20:37:18-07:00 hadi@znyx.com +2 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/act_api.c # 2004/06/15 20:37:06-07:00 hadi@znyx.com +978 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # net/sched/act_api.c # 2004/06/15 20:37:06-07:00 hadi@znyx.com +0 -0 # BitKeeper file /disk1/BK/tc-2.6/net/sched/act_api.c # # include/net/pkt_act.h # 2004/06/15 20:37:05-07:00 hadi@znyx.com +286 -0 # [NET]: Add tc extensions infrastructure. # # Signed-off-by: Jamal Hadi Salim # Signed-off-by: David S. Miller # # include/net/pkt_act.h # 2004/06/15 20:37:05-07:00 hadi@znyx.com +0 -0 # BitKeeper file /disk1/BK/tc-2.6/include/net/pkt_act.h # # ChangeSet # 2004/06/16 00:33:13-03:00 acme@toy.kerneljanitors.org # [ECONET] kill some trivial warnings # # Signed-off-by: Arnaldo Carvalho de Melo # # net/econet/af_econet.c # 2004/06/16 00:33:01-03:00 acme@toy.kerneljanitors.org +6 -8 # [ECONET] kill some trivial warnings # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/15 20:24:51-07:00 davem@nuts.davemloft.net # Merge bk://kernel.bkbits.net/acme/net-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/ipv6/tcp_ipv6.c # 2004/06/15 20:24:38-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/06/15 20:20:25-07:00 ahu@ds9a.nl # [NET]: Update some sysctl documentation. # # I ran the following (crappy) script: # ... # In /proc/sys/ and found a host of undocumented sysctls. This patch documents # a number of them, and at least mentions the rest as 'TODO'. Please verify my # code-inspired documentation before applying! # # Signed-off-by: Bert Hubert # Signed-off-by: David S. Miller # # Documentation/networking/ip-sysctl.txt # 2004/06/15 20:19:32-07:00 ahu@ds9a.nl +57 -0 # [NET]: Update some sysctl documentation. # # I ran the following (crappy) script: # ... # In /proc/sys/ and found a host of undocumented sysctls. This patch documents # a number of them, and at least mentions the rest as 'TODO'. Please verify my # code-inspired documentation before applying! # # Signed-off-by: Bert Hubert # Signed-off-by: David S. Miller # # Documentation/filesystems/proc.txt # 2004/06/15 20:19:32-07:00 ahu@ds9a.nl +2 -1 # [NET]: Update some sysctl documentation. # # I ran the following (crappy) script: # ... # In /proc/sys/ and found a host of undocumented sysctls. This patch documents # a number of them, and at least mentions the rest as 'TODO'. Please verify my # code-inspired documentation before applying! # # Signed-off-by: Bert Hubert # Signed-off-by: David S. Miller # # ChangeSet # 2004/06/15 19:32:48-07:00 dsaxena@omelas.(none) # [ARM] Add include/asm-arm/mach/time.h for shared timer definitions # # Signed-off-by: Deepak Saxena # # include/asm-arm/mach/time.h # 2004/06/15 19:31:40-07:00 dsaxena@omelas.(none) +24 -0 # # include/asm-arm/mach/time.h # 2004/06/15 19:31:40-07:00 dsaxena@omelas.(none) +0 -0 # BitKeeper file /home/dsaxena/src/linux-2.6-arm-timer/include/asm-arm/mach/time.h # # ChangeSet # 2004/06/15 19:00:23-07:00 dsaxena@omelas.(none) # [ARM] Delete include/asm-arm/arch-versatile/time.h # # Signed-off-by: Deepak Saxena # # BitKeeper/deleted/.del-time.h~c344b24f8045f7dc # 2004/06/15 18:59:09-07:00 dsaxena@omelas.(none) +0 -0 # Delete: include/asm-arm/arch-versatile/time.h # # ChangeSet # 2004/06/15 18:45:01-07:00 dsaxena@omelas.(none) # [ARM] Delete include/asm-arm/arch-ixp4xx/time.h # # Signed-off-by: Deepak Saxena # # BitKeeper/deleted/.del-time.h~cc23e4568356fd42 # 2004/06/15 18:44:35-07:00 dsaxena@omelas.(none) +0 -0 # Delete: include/asm-arm/arch-ixp4xx/time.h # # ChangeSet # 2004/06/15 18:42:18-07:00 dsaxena@omelas.(none) # [ARM] Delete include/asm-arm/arch-iop3xx/time.h # # Signed-off-by: Deepak Saxena # # BitKeeper/deleted/.del-time.h~66507b95d41b2fa3 # 2004/06/15 18:41:53-07:00 dsaxena@omelas.(none) +0 -0 # Delete: include/asm-arm/arch-iop3xx/time.h # # ChangeSet # 2004/06/15 18:38:14-07:00 dsaxena@omelas.(none) # [ARM] Delete include/asm-arm/arch-nexuspci/time.h # # Signed-off-by: Deepak Saxena # # BitKeeper/deleted/.del-time.h~730e38fa47912a2c # 2004/06/15 18:37:53-07:00 dsaxena@omelas.(none) +0 -0 # Delete: include/asm-arm/arch-nexuspci/time.h # # ChangeSet # 2004/06/15 18:16:01-07:00 dsaxena@omelas.(none) # [ARM] Remove bogus gettimeoffset ptr from machine_desc struct. # # This was accidently added during the timer code cleanup. # # Signed-off-by: Deepak Saxena # # include/asm-arm/mach/arch.h # 2004/06/15 18:14:13-07:00 dsaxena@omelas.(none) +0 -1 # Remove bogus gettimeoffset() from machine_desc struct # # ChangeSet # 2004/06/15 17:57:04-07:00 dsaxena@omelas.(none) # Merge # # arch/arm/mach-omap/board-generic.c # 2004/06/15 17:57:02-07:00 dsaxena@omelas.(none) +0 -0 # SCCS merged # # arch/arm/mach-omap/time.c # 2004/06/15 17:50:10-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/mach-omap/time.c # 2004/06/15 17:50:10-07:00 dsaxena@omelas.(none) +0 -0 # Merge rename: include/asm-arm/arch-omap/time.h -> arch/arm/mach-omap/time.c # # arch/arm/mach-omap/board-perseus2.c # 2004/06/15 17:50:10-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/mach-omap/board-osk.c # 2004/06/15 17:50:10-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/mach-omap/board-innovator.c # 2004/06/15 17:50:10-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # arch/arm/Kconfig # 2004/06/15 17:50:10-07:00 dsaxena@omelas.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/15 17:48:14-07:00 dsaxena@omelas.(none) # [ARM] Timer cleanup # # Signed-off-by: Deepak Saxena # # include/asm-arm/mach/arch.h # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +5 -0 # ARM timer cleanup # # include/asm-arm/arch-ixp4xx/platform.h # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # include/asm-arm/arch-integrator/platform.h # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +4 -0 # ARM timer cleanup # # arch/arm/mach-versatile/core.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +147 -0 # ARM timer cleanup # # arch/arm/mach-tbox/core.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +27 -0 # ARM timer cleanup # # arch/arm/mach-shark/core.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +40 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/yopy.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/xp860.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/trizeps.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +8 -3 # ARM timer cleanup # # arch/arm/mach-sa1100/system3.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/stork.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/simpad.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/sherman.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/shannon.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/pleb.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/pfs168.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/pangolin.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/omnimeter.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/nanoengine.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/lart.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/jornada720.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/itsy.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/huw_webpanel.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/hackkit.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/h3600.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +3 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/graphicsmaster.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/graphicsclient.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/generic.h # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/freebird.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/flexanet.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/empeg.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/cerf.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/brutus.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/badge4.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/assabet.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-sa1100/adsbitsy.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-s3c2410/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +18 -10 # ARM timer cleanup # # arch/arm/mach-s3c2410/s3c2410.h # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-s3c2410/mach-vr1000.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +6 -0 # ARM timer cleanup # # arch/arm/mach-s3c2410/mach-smdk2410.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +6 -0 # ARM timer cleanup # # arch/arm/mach-s3c2410/mach-h1940.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +6 -0 # ARM timer cleanup # # arch/arm/mach-s3c2410/mach-bast.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +6 -0 # ARM timer cleanup # # arch/arm/mach-s3c2410/Makefile # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -1 # ARM timer cleanup # # arch/arm/mach-rpc/riscpc.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +31 -0 # ARM timer cleanup # # arch/arm/mach-pxa/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +27 -4 # ARM timer cleanup # # arch/arm/mach-pxa/mainstone.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-pxa/lubbock.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-pxa/idp.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-pxa/generic.h # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-pxa/Makefile # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -1 # ARM timer cleanup # # arch/arm/mach-omap/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +15 -13 # ARM timer cleanup # # arch/arm/mach-omap/common.h # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-omap/board-perseus2.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-omap/board-osk.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-omap/board-innovator.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-omap/board-generic.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +7 -0 # ARM timer cleanup # # arch/arm/mach-omap/Makefile # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -1 # ARM timer cleanup # # arch/arm/mach-lh7a40x/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +22 -5 # ARM timer cleanup # # arch/arm/mach-lh7a40x/arch-lpd7a40x.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-lh7a40x/arch-kev7a400.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-lh7a40x/Makefile # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -1 # ARM timer cleanup # # arch/arm/mach-ixp4xx/prpmc1100-setup.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-ixp4xx/ixdp425-setup.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +3 -0 # ARM timer cleanup # # arch/arm/mach-ixp4xx/coyote-setup.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/mach-ixp4xx/common.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +7 -8 # ARM timer cleanup # # arch/arm/mach-iop3xx/iop321-time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +7 -6 # ARM timer cleanup # # arch/arm/mach-iop3xx/arch.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-integrator/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +146 -0 # ARM timer cleanup # # arch/arm/mach-integrator/integrator_cp.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +6 -0 # ARM timer cleanup # # arch/arm/mach-integrator/integrator_ap.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +6 -0 # ARM timer cleanup # # arch/arm/mach-ftvpci/core.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +47 -0 # ARM timer cleanup # # arch/arm/mach-footbridge/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +26 -8 # ARM timer cleanup # # arch/arm/mach-footbridge/arch.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +6 -0 # ARM timer cleanup # # arch/arm/mach-footbridge/Makefile # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +1 -1 # ARM timer cleanup # # arch/arm/mach-epxa10db/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +45 -1 # ARM timer cleanup # # arch/arm/mach-epxa10db/arch.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +3 -0 # ARM timer cleanup # # arch/arm/mach-ebsa110/core.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +102 -0 # ARM timer cleanup # # arch/arm/mach-clps7500/core.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +40 -1 # ARM timer cleanup # # arch/arm/mach-clps711x/time.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +28 -4 # ARM timer cleanup # # arch/arm/mach-clps711x/p720t.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-clps711x/fortunet.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-clps711x/edb7211-arch.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-clps711x/clep7312.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-clps711x/ceiva.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/mach-clps711x/cdb89712.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/common/time-acorn.c # 2004/06/15 17:42:35-07:00 dsaxena@omelas.(none) +3 -2 # ARM timer cleanup # # arch/arm/mach-clps711x/autcpu12.c # 2004/06/15 17:42:34-07:00 dsaxena@omelas.(none) +2 -0 # ARM timer cleanup # # arch/arm/kernel/time.c # 2004/06/15 17:42:34-07:00 dsaxena@omelas.(none) +12 -15 # ARM timer cleanup # # arch/arm/kernel/setup.c # 2004/06/15 17:42:34-07:00 dsaxena@omelas.(none) +3 -0 # ARM timer cleanup # # arch/arm/kernel/Makefile # 2004/06/15 17:42:34-07:00 dsaxena@omelas.(none) +1 -2 # ARM timer cleanup # # arch/arm/common/Makefile # 2004/06/15 17:42:34-07:00 dsaxena@omelas.(none) +1 -0 # ARM timer cleanup # # arch/arm/Kconfig # 2004/06/15 17:42:34-07:00 dsaxena@omelas.(none) +5 -0 # ARM timer cleanup # # BitKeeper/deleted/.del-time.h~e839fe4bcd9e4cf9 # 2004/06/15 16:48:56-07:00 dsaxena@omelas.(none) +0 -0 # Delete: include/asm-arm/arch-tbox/time.h # # ChangeSet # 2004/06/15 16:29:30-07:00 eranian@hpl.hp.com # [PATCH] ia64: fix info in /proc/pal/*/bus_info # # This patch fixes to minor bugs: # - corrected descriptions for bit 52 and 53 of the /proc/pal/CPU*/bus_info # entry; they were swapped # - corrected a typo for bit 55 of the /proc/pal/CPU*/bus_info entry # # Signed-off-by: Stephane Eranian # Signed-off-by: David Mosberger # # arch/ia64/kernel/palinfo.c # 2004/06/15 10:28:07-07:00 eranian@hpl.hp.com +2 -2 # ia64: fix info in /proc/pal/*/bus_info # # BitKeeper/deleted/.del-time.c~e41898daed8bea09 # 2004/06/15 16:08:17-07:00 dsaxena@omelas.(none) +0 -0 # Delete: arch/arm/mach-shark/time.c # # arch/arm/mach-shark/time.c # 2004/06/15 15:58:38-07:00 dsaxena@omelas.(none) +0 -0 # Rename: arch/arm/mach-shark/time.ch -> arch/arm/mach-shark/time.c # # arch/arm/mach-shark/time.ch # 2004/06/15 15:46:57-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-shark/time.h -> arch/arm/mach-shark/time.ch # # arch/arm/mach-sa1100/time.c # 2004/06/15 15:02:29-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-sa1100/time.h -> arch/arm/mach-sa1100/time.c # # arch/arm/mach-s3c2410/time.c # 2004/06/15 13:52:07-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-s3c2410/time.h -> arch/arm/mach-s3c2410/time.c # # BitKeeper/deleted/.del-time.c~16d0f1fb7b29ea89 # 2004/06/15 13:09:43-07:00 dsaxena@omelas.(none) +0 -23 # Delete: arch/arm/mach-rpc/time.c # # arch/arm/mach-rpc/time.c # 2004/06/15 13:02:38-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-rpc/time.h -> arch/arm/mach-rpc/time.c # # arch/arm/mach-pxa/time.c # 2004/06/15 12:36:09-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-pxa/time.h -> arch/arm/mach-pxa/time.c # # arch/arm/mach-omap/time.c # 2004/06/15 12:06:48-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-omap/time.h -> arch/arm/mach-omap/time.c # # arch/arm/mach-lh7a40x/time.c # 2004/06/15 11:01:21-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-lh7a40x/time.h -> arch/arm/mach-lh7a40x/time.c # # ChangeSet # 2004/06/15 12:48:08-05:00 jejb@mulgrave.(none) # Fix endless loop in SCSI SPI transport class # # If the driver doesn't update the peroid, we go # around forever. The fix is to keep our old period # unless the driver returns a greater one. # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_transport_spi.c # 2004/06/15 12:47:53-05:00 jejb@mulgrave.(none) +3 -1 # Fix endless loop in SCSI SPI transport class # # ChangeSet # 2004/06/15 12:32:52-05:00 jejb@mulgrave.(none) # Merge # # drivers/scsi/qlogicpti.c # 2004/06/15 12:32:34-05:00 jejb@mulgrave.(none) +0 -1 # SCCS merged # # drivers/scsi/esp.c # 2004/06/15 12:32:09-05:00 jejb@mulgrave.(none) +0 -1 # SCCS merged # # include/linux/pci_ids.h # 2004/06/15 12:28:06-05:00 jejb@mulgrave.(none) +0 -0 # Auto merged # # drivers/scsi/st.c # 2004/06/15 12:28:06-05:00 jejb@mulgrave.(none) +0 -0 # Auto merged # # drivers/scsi/scsi_debug.c # 2004/06/15 12:28:06-05:00 jejb@mulgrave.(none) +0 -0 # Auto merged # # drivers/scsi/osst.c # 2004/06/15 12:28:05-05:00 jejb@mulgrave.(none) +0 -0 # Auto merged # # drivers/scsi/cpqfcTScontrol.c # 2004/06/15 12:28:05-05:00 jejb@mulgrave.(none) +0 -0 # Auto merged # # drivers/scsi/Kconfig # 2004/06/15 12:28:05-05:00 jejb@mulgrave.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/06/15 12:28:05-05:00 jejb@mulgrave.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/15 12:09:19-05:00 rddunlap@osdl.org # [PATCH] Comment out an unused function in drivers/scsi/wd7000.c # # Eliminate unused function wd7000_abort() in wd7000 driver. # # CC [M] drivers/scsi/wd7000.o # drivers/scsi/wd7000.c:1612: warning: `wd7000_abort' defined but not used # # As the author states in his comment, this is "unfinished business" ;-) # # # From: Mika Kukkonen # Signed-off-by: Randy Dunlap # Signed-off-by: James Bottomley # # drivers/scsi/wd7000.c # 2004/06/15 10:49:13-05:00 rddunlap@osdl.org +2 -1 # Comment out an unused function in drivers/scsi/wd7000.c # # ChangeSet # 2004/06/15 12:07:20-05:00 bunk@fs.tum.de # [PATCH] modular scsi/mca_53c9x doesn't work # # On Mon, Jun 14, 2004 at 08:22:15PM +0100, Christoph Hellwig wrote: # > On Mon, Jun 14, 2004 at 08:52:56PM +0200, Adrian Bunk wrote: # > > The issue described in the mail forwarded below is still present in # > > 2.6.7-rc3-mm2 (but not specific to -mm). # > > # > > I'd suggest the following workaround: # > # > Please add the exports instead. It'll affect all the other 53C9X-based # > drivers aswell. # # This sounds like a better solution. # # Signed-off-by: James Bottomley # # drivers/scsi/NCR53C9x.c # 2004/06/14 17:47:23-05:00 bunk@fs.tum.de +11 -0 # modular scsi/mca_53c9x doesn't work # # ChangeSet # 2004/06/15 12:06:00-05:00 akpm@osdl.org # [PATCH] drivers/scsi/megaraid.c: user/kernel pointer bugs # # From: "Robert T. Johnson" # # Since arg is a user pointer, so are uioc_mimd and uiocp, and hence umc is a # user pointer. Thus reading umc->xferaddr requires dereferencing a user # pointer, which isn't safe. # # Signed-off-by: Andrew Morton # Signed-off-by: James Bottomley # # drivers/scsi/megaraid.c # 2004/06/10 08:19:19-05:00 akpm@osdl.org +4 -2 # drivers/scsi/megaraid.c: user/kernel pointer bugs # # ChangeSet # 2004/06/15 12:04:04-05:00 g.liakhovetski@gmx.de # [PATCH] tmscsim: 64-bit cleanup # # > Although, I think, there's still a glitch there (modified if's order). # > I'll send a new version, if the approach is approved in principle. # # Ok, attached is version 3:-) It also fixes a definite (although, perhaps, # harmless) bug in scsiiom.c. And removes a redundant assignment in # tmscsim.c. # # Signed-off-by: Guennadi Liakhovetski # Signed-off-by: James Bottomley # # drivers/scsi/tmscsim.c # 2004/06/14 17:28:50-05:00 g.liakhovetski@gmx.de +40 -34 # tmscsim: 64-bit cleanup # # ChangeSet # 2004/06/15 12:01:55-05:00 hch@lst.de # [PATCH] avoid obsolete scsi APIs in eata_pio # # Signed-off-by: James Bottomley # # drivers/scsi/eata_pio.c # 2004/06/07 05:22:42-05:00 hch@lst.de +66 -65 # avoid obsolete scsi APIs in eata_pio # # drivers/scsi/eata_generic.h # 2004/06/07 05:19:05-05:00 hch@lst.de +1 -1 # avoid obsolete scsi APIs in eata_pio # # ChangeSet # 2004/06/15 11:59:06-05:00 hch@lst.de # [PATCH] clean up SCSI_TIMEOUT usage # # - qlogicfc.c abuses SCSI_TIEMOUT although it's not part of the scsi # core, give it it's own ISP_TIMEOUT define # - avoid redefining timeouts #ifdef DEBUG, that's a cause for heisenbugs # just waiting to happen # - now SCSI_TIMEOUT is private to scsi_scan.c, move it there # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_scan.c # 2004/06/06 06:20:50-05:00 hch@lst.de +5 -0 # clean up SCSI_TIMEOUT usage # # drivers/scsi/scsi_error.c # 2004/06/06 06:19:15-05:00 hch@lst.de +4 -9 # clean up SCSI_TIMEOUT usage # # drivers/scsi/scsi.h # 2004/06/06 06:17:31-05:00 hch@lst.de +0 -6 # clean up SCSI_TIMEOUT usage # # drivers/scsi/qlogicfc.c # 2004/06/06 06:17:21-05:00 hch@lst.de +2 -1 # clean up SCSI_TIMEOUT usage # # ChangeSet # 2004/06/15 16:33:27+01:00 rmk@flint.arm.linux.org.uk # [ARM] pxafb doesn't need to include asm/mach-types.h # # drivers/video/pxafb.c # 2004/06/15 16:31:17+01:00 rmk@flint.arm.linux.org.uk +0 -1 # pxafb doesn't need to include asm/mach-types.h # # ChangeSet # 2004/06/15 15:50:19+01:00 elf@com.rmk.(none) # [ARM PATCH] 1928/1: lh7a40x #7 Changes to memory model to support contiguous SDRAM # # Patch from Marc Singer # # [if's replaced by ifdef's.] # # While the BLOB boot loader doesn't support it, there are two others, # UBOOT and Logic's LOLO, that will initialize the SDRAM controller such # that the memory appears as a contiguous region. This layout to be # required for WinCE and, thus, is the default for these loaders. The # memory organization had been optimized for discontiguous blocks. Now, # it supports a default mode that is compatible with all of the # bootloaders as well as options to optimize for either contiguous or # discontiguous models. # # Withing, there is also a slight change to the way that the DEBUG_LL # macros select the UART address. Now it uses immediate constants # exclusively. # # # include/asm-arm/arch-lh7a40x/memory.h # 2004/06/12 22:57:20+01:00 elf@com.rmk.(none) +21 -48 # [PATCH] 1928/1: lh7a40x #7 Changes to memory model to support contiguous SDRAM # # arch/arm/mach-lh7a40x/Kconfig # 2004/06/12 22:57:20+01:00 elf@com.rmk.(none) +31 -0 # [PATCH] 1928/1: lh7a40x #7 Changes to memory model to support contiguous SDRAM # # arch/arm/kernel/debug.S # 2004/06/12 22:57:20+01:00 elf@com.rmk.(none) +2 -1 # [PATCH] 1928/1: lh7a40x #7 Changes to memory model to support contiguous SDRAM # # arch/arm/Kconfig # 2004/06/12 22:57:20+01:00 elf@com.rmk.(none) +2 -2 # [PATCH] 1928/1: lh7a40x #7 Changes to memory model to support contiguous SDRAM # # Documentation/arm/Sharp-LH/SDRAM # 2004/06/12 22:57:20+01:00 elf@com.rmk.(none) +51 -0 # [PATCH] 1928/1: lh7a40x #7 Changes to memory model to support contiguous SDRAM # # Documentation/arm/Sharp-LH/SDRAM # 2004/06/12 22:57:20+01:00 elf@com.rmk.(none) +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/Documentation/arm/Sharp-LH/SDRAM # # ChangeSet # 2004/06/15 15:46:21+01:00 icampbell@com.rmk.(none) # [ARM PATCH] 1926/3: PXAFB cleanups and fixes # # Patch from Ian Campbell # # Sorry, 1926/2 was missing a brace. Fixed here. # # Previous commentry: # I have corrected the grayscale conversion to correctly use the upper # byte rather than the lower one. As requested I have also left the # actual grayscale conversion where it was this time and just dealt with # the palette differences in pxafb_setpalettereg. # # fb_alloc_cmap is only called when bits_per_pixel is < 16, otherwise # any existing cmap is freed. # # I also fixed up all the spaces and brackets issues (not just the one # you raised previously) this introduces some noise in the patch, if # you'd like the two patches separately please ask. # # drivers/video/pxafb.c # 2004/06/15 13:42:45+01:00 icampbell@com.rmk.(none) +50 -43 # [PATCH] 1926/3: PXAFB cleanups and fixes # # ChangeSet # 2004/06/15 14:52:36+01:00 rmk@flint.arm.linux.org.uk # [ARM] Add clock API # # Since peripheral clocks are be derived in SoC or even platform # specific ways, we need a way to keep this information out of the # drivers. AMBA Primecells are defined in terms of functional units # where clocks are derived from external sources, and it is up to the # SoC designer to determine where to derive those clocks from. # # Therefore, we provide a very basic API which allows platforms to # provide this information in a generic manner to their peripherals. # This framework also allows peripherals to shut down unused clock # sources when they're not in use. # # include/asm-arm/hardware/clock.h # 2004/06/15 14:49:41+01:00 rmk@flint.arm.linux.org.uk +121 -0 # # include/asm-arm/hardware/clock.h # 2004/06/15 14:49:41+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/include/asm-arm/hardware/clock.h # # arch/arm/mach-versatile/clock.h # 2004/06/15 14:49:33+01:00 rmk@flint.arm.linux.org.uk +25 -0 # # arch/arm/mach-versatile/clock.h # 2004/06/15 14:49:33+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/mach-versatile/clock.h # # arch/arm/mach-versatile/clock.c # 2004/06/15 14:49:25+01:00 rmk@flint.arm.linux.org.uk +146 -0 # # arch/arm/mach-versatile/clock.c # 2004/06/15 14:49:25+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/mach-versatile/clock.c # # arch/arm/mach-integrator/clock.h # 2004/06/15 14:49:18+01:00 rmk@flint.arm.linux.org.uk +25 -0 # # arch/arm/mach-integrator/clock.h # 2004/06/15 14:49:18+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/mach-integrator/clock.h # # arch/arm/mach-integrator/clock.c # 2004/06/15 14:49:09+01:00 rmk@flint.arm.linux.org.uk +138 -0 # # include/asm-arm/arch-integrator/impd1.h # 2004/06/15 14:49:09+01:00 rmk@flint.arm.linux.org.uk +0 -1 # IM-PD/1 VCO is now controlled via the clock subsystem. # # arch/arm/mach-integrator/clock.c # 2004/06/15 14:49:09+01:00 rmk@flint.arm.linux.org.uk +0 -0 # BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/mach-integrator/clock.c # # drivers/serial/amba-pl011.c # 2004/06/15 14:49:08+01:00 rmk@flint.arm.linux.org.uk +58 -23 # Make PL011 UART use clock layer to obtain clock source information. # # drivers/input/serio/ambakmi.c # 2004/06/15 14:49:08+01:00 rmk@flint.arm.linux.org.uk +33 -5 # Make keyboard/mouse interface use clock layer to obtain KMI clock # source information. # # arch/arm/mach-versatile/Makefile # 2004/06/15 14:49:08+01:00 rmk@flint.arm.linux.org.uk +1 -1 # Add clock.o object. # # arch/arm/mach-integrator/integrator_cp.c # 2004/06/15 14:49:08+01:00 rmk@flint.arm.linux.org.uk +62 -0 # Add Integrator/CP specific clocks. # # arch/arm/mach-integrator/impd1.c # 2004/06/15 14:49:08+01:00 rmk@flint.arm.linux.org.uk +28 -13 # Add clock structures for IM-PD/1 on-board clocks. # # arch/arm/mach-integrator/Makefile # 2004/06/15 14:49:08+01:00 rmk@flint.arm.linux.org.uk +1 -1 # Add clock.o to build objects. # # ChangeSet # 2004/06/15 00:29:37-04:00 jgarzik@pobox.com # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # include/linux/libata.h # 2004/06/15 00:29:32-04:00 jgarzik@pobox.com +2 -2 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/sata_vsc.c # 2004/06/15 00:29:32-04:00 jgarzik@pobox.com +1 -1 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/sata_via.c # 2004/06/15 00:29:32-04:00 jgarzik@pobox.com +1 -1 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/sata_sx4.c # 2004/06/15 00:29:32-04:00 jgarzik@pobox.com +6 -3 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/sata_svw.c # 2004/06/15 00:29:32-04:00 jgarzik@pobox.com +1 -1 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/sata_sis.c # 2004/06/15 00:29:32-04:00 jgarzik@pobox.com +1 -1 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/sata_sil.c # 2004/06/15 00:29:32-04:00 jgarzik@pobox.com +1 -1 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/sata_promise.c # 2004/06/15 00:29:31-04:00 jgarzik@pobox.com +4 -4 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/libata-core.c # 2004/06/15 00:29:31-04:00 jgarzik@pobox.com +29 -21 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # drivers/scsi/ata_piix.c # 2004/06/15 00:29:31-04:00 jgarzik@pobox.com +2 -2 # [libata] ->qc_prep hook # # Rename ->fill_sg hook to ->qc_prep, and call it unconditionally # (as opposed to ->fill_sg, which was called only when the # flag ATA_QCFLAG_SG was set). # # ChangeSet # 2004/06/14 23:54:02-04:00 jgarzik@pobox.com # [libata] PCI IDE command-end/irq-acknowledge cleanup # # Restruct default irq handler (used for many PCI IDE-like SATA # controllers) to obtain device status and acknowledge interrupts # a bit differently. # # In an attempt to better attack the "ich5 screaming interrupt" problem, # acknowledge and clear the device's INTRQ by reading the Status register # _before_ ack'ing the controller's irq status. This is a deviation # from how the Linux IDE driver acknowledges interrupts, but it may # be the best method, since the ICH5 appears to continue to assert # the interrupt bit in the BMDMA until the device INTRQ line is cleared. # # Of course, SATA has no INTRQ line per se, so ICH5 essentially has # new interrupt behavior not seen before in the PCI IDE world, while # pretending that it's compatible with PCI IDE. Sigh. # # This change affects all SATA controllers (for which there are libata # drivers) except for sata_promise and sata_sx4. # # drivers/scsi/libata-core.c # 2004/06/14 23:53:57-04:00 jgarzik@pobox.com +57 -83 # [libata] PCI IDE command-end/irq-acknowledge cleanup # # Restruct default irq handler (used for many PCI IDE-like SATA # controllers) to obtain device status and acknowledge interrupts # a bit differently. # # In an attempt to better attack the "ich5 screaming interrupt" problem, # acknowledge and clear the device's INTRQ by reading the Status register # _before_ ack'ing the controller's irq status. This is a deviation # from how the Linux IDE driver acknowledges interrupts, but it may # be the best method, since the ICH5 appears to continue to assert # the interrupt bit in the BMDMA until the device INTRQ line is cleared. # # Of course, SATA has no INTRQ line per se, so ICH5 essentially has # new interrupt behavior not seen before in the PCI IDE world, while # pretending that it's compatible with PCI IDE. Sigh. # # This change affects all SATA controllers (for which there are libata # drivers) except for sata_promise and sata_sx4. # # ChangeSet # 2004/06/14 22:40:59-04:00 jgarzik@pobox.com # [libata] PCI IDE DMA code shuffling # # PCI IDE DMA standard (or "bmdma") helper routines ata_bmdma_stop, # ata_bmdma_ack_irq, and ata_bmdma_status are added to linux/libata.h, # and used in libata-core. # # There is a minor behavior change, such that, the Alt Status register # is read before acknowledging the bmdma interrupt. This should be ok, # and furthermore there will be more significant behavior changes # in this area coming soon. # # include/linux/libata.h # 2004/06/14 22:40:53-04:00 jgarzik@pobox.com +40 -0 # [libata] PCI IDE DMA code shuffling # # PCI IDE DMA standard (or "bmdma") helper routines ata_bmdma_stop, # ata_bmdma_ack_irq, and ata_bmdma_status are added to linux/libata.h, # and used in libata-core. # # There is a minor behavior change, such that, the Alt Status register # is read before acknowledging the bmdma interrupt. This should be ok, # and furthermore there will be more significant behavior changes # in this area coming soon. # # drivers/scsi/libata-core.c # 2004/06/14 22:40:53-04:00 jgarzik@pobox.com +4 -41 # [libata] PCI IDE DMA code shuffling # # PCI IDE DMA standard (or "bmdma") helper routines ata_bmdma_stop, # ata_bmdma_ack_irq, and ata_bmdma_status are added to linux/libata.h, # and used in libata-core. # # There is a minor behavior change, such that, the Alt Status register # is read before acknowledging the bmdma interrupt. This should be ok, # and furthermore there will be more significant behavior changes # in this area coming soon. # # drivers/net/acenic.c # 2004/06/14 18:49:59-04:00 johnpol@2ka.mipt.ru +2 -2 # Typo in ethtool code in acenic driver # # ChangeSet # 2004/06/14 18:34:29-04:00 akpm@osdl.org # [PATCH] prism94 build fix # # init_wds is being instantiated in both isl_ioctl.c and islpci_eth.c, causing # linkage errors. # # drivers/net/wireless/prism54/islpci_mgt.o(.rodata+0x198): In function `islpci_mgmt_rx_fill': # /usr/src/25/drivers/net/wireless/prism54/islpci_mgt.c:154: multiple definition of `init_wds' # drivers/net/wireless/prism54/islpci_eth.o(.rodata+0x1c8):/usr/src/25/include/linux/skbuff.h:815: first defined here # # Signed-off-by: Andrew Morton # # drivers/net/wireless/prism54/islpci_mgt.h # 2004/06/13 22:29:45-04:00 akpm@osdl.org +1 -1 # prism94 build fix # # ChangeSet # 2004/06/14 18:33:35-04:00 a.othieno@bluewin.ch # [PATCH] Kill stale references to Documentation/networking/8139too.txt # # Documentation/networking/8139too.txt was removed with this ChangeSet: # # ChangeSet@1.1371.153.2 2004-01-10 15:34:47-05:00 jgarzik@redhat.com # [netdrvr] remove Documentation/networking/8139too.txt # # All sections of the document are woefully outdated. # # # However, `grep' still reveals these references to it: # # drivers/net/8139too.c:90: See 8139too.txt for more details. # drivers/net/Kconfig:1539: as well as the # Documentation/networking/00-INDEX:7:8139too.txt # # Signed-off-by: Arthur Othieno # # drivers/net/Kconfig # 2004/06/14 14:50:09-04:00 a.othieno@bluewin.ch +1 -3 # Kill stale references to Documentation/networking/8139too.txt # # drivers/net/8139too.c # 2004/06/14 14:50:09-04:00 a.othieno@bluewin.ch +0 -2 # Kill stale references to Documentation/networking/8139too.txt # # Documentation/networking/00-INDEX # 2004/06/14 14:50:09-04:00 a.othieno@bluewin.ch +0 -2 # Kill stale references to Documentation/networking/8139too.txt # # ChangeSet # 2004/06/14 18:32:42-04:00 johnpol@2ka.mipt.ru # [PATCH] Typo in ethtool code in acenic driver # # In 10mbps detection code. # # ChangeSet # 2004/06/14 14:38:31-07:00 stern@rowland.harvard.edu # [PATCH] USB: Remove private khubd semaphore # # This patch removes the private semaphore used by the hub driver, and uses # the regular "serialize" semaphore instead. This will satisfy the general # locking requirements for adding and removing devices attached to the hub. # The only tricky aspect is that now the hub event handler must take a # reference to the hub device while waiting to acquire the semaphore, in # case the hub is disconnected during the wait. # # The patch also replaces a few occurrences of spin_lock_irqsave() in # regions where interrupts are known to be enabled with spin_lock_irq(). # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.h # 2004/06/14 03:33:06-07:00 stern@rowland.harvard.edu +0 -1 # USB: Remove private khubd semaphore # # drivers/usb/core/hub.c # 2004/06/14 03:59:02-07:00 stern@rowland.harvard.edu +24 -21 # USB: Remove private khubd semaphore # # ChangeSet # 2004/06/14 16:27:27-04:00 jgarzik@pobox.com # [libata] don't probe from workqueue # # Since we want the probe phase to call other workqueues, this is # required to eliminate future deadlocks. # # Other methods would include starting a single-shot thread just for # probing, but overall, using a separate thread for probing is pointless # since we are already in process context when we probe. # # So, we simply call ata_bus_probe directly. # # include/linux/libata.h # 2004/06/14 16:27:21-04:00 jgarzik@pobox.com +0 -15 # [libata] don't probe from workqueue # # Since we want the probe phase to call other workqueues, this is # required to eliminate future deadlocks. # # Other methods would include starting a single-shot thread just for # probing, but overall, using a separate thread for probing is pointless # since we are already in process context when we probe. # # So, we simply call ata_bus_probe directly. # # drivers/scsi/libata-core.c # 2004/06/14 16:27:21-04:00 jgarzik@pobox.com +18 -118 # [libata] don't probe from workqueue # # Since we want the probe phase to call other workqueues, this is # required to eliminate future deadlocks. # # Other methods would include starting a single-shot thread just for # probing, but overall, using a separate thread for probing is pointless # since we are already in process context when we probe. # # So, we simply call ata_bus_probe directly. # # BitKeeper/deleted/.del-time.h~d87f27565ed1c644 # 2004/06/14 11:55:15-07:00 dsaxena@omelas.(none) +0 -0 # Delete: include/asm-arm/arch-epxa10db/time.h # # ChangeSet # 2004/06/14 11:11:45-07:00 rl@hellgate.ch # [PATCH] PCI: Fix off-by-one in pci_enable_wake # # Fix off-by-one in pci_enable_wake. # Bit field location determined by mask, not value. # # Signed-off-by: Roger Luethi # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/pci.c # 2004/06/14 09:43:15-07:00 rl@hellgate.ch +1 -1 # PCI: Fix off-by-one in pci_enable_wake # # ChangeSet # 2004/06/14 11:08:54-07:00 rl@hellgate.ch # [PATCH] PCI: Fix PME bits in pci.txt # # Signed-off-by: Roger Luethi # Signed-off-by: Greg Kroah-Hartman # # Documentation/power/pci.txt # 2004/06/14 09:54:41-07:00 rl@hellgate.ch +4 -4 # PCI: Fix PME bits in pci.txt # # ChangeSet # 2004/06/14 10:50:59-07:00 mhoffman@lightlink.com # [PATCH] I2C: add alternate VCORE calculations for w83627thf and w83637hf # # Pick a VRM (for VID interpretation) based on the VRM & OVT config, # if available. Props to Jean Delvare for the # idea & code fragment. # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83627hf.c # 2004/06/08 19:06:02-07:00 mhoffman@lightlink.com +6 -3 # I2C: add alternate VCORE calculations for w83627thf and w83637hf # # ChangeSet # 2004/06/14 10:35:58-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix bug in TT initialization introduced by earlier # # This patch repairs a bug introduced by an earlier patch: The TT # initialization code was moved to _after_ the TT's first use. The patch # simply puts the code back the way it used to be. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/13 07:11:31-07:00 stern@rowland.harvard.edu +13 -10 # USB: Fix bug in TT initialization introduced by earlier # # ChangeSet # 2004/06/14 10:35:15-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: Fix race when removing the SCSI host # # This patch fixes a race is disconnecting a usb-storage device that occurs # with the SCSI layer. It's primarily reproducable via adding delays into # various disconnect and reset processing paths, but has also been # encountered in the field. # # This patch started life as as281b, and was modified by me only to patch # properly against current kernels. # # The main features of the patch are: # # Store the host pointer at the start of the control thread # rather than trying to get it from srb->device; after the host # is removed the SCSI device structure may no longer exist. # # Keep dev_semaphore locked during the entire time the control # thread or reset handlers are using the us_data structure. # # Reorder the items in dissociate_dev() and release_resources() # so that things are released in the opposite order from the way # they were acquired originally. Don't bother to increment and # decrement the usb_device's reference count; it's unnecessary. # # In disconnect(), first set the DISCONNECTING flag so that no # more I/O will take place and no more requests will be accepted. # Next, cut short the current command and wait for it to finish. # Then call scsi_remove_host(). The SCSI core guarantees that # when scsi_remove_host() returns, the host will not be in error # recovery and all outstanding commands will have been cancelled. # # Remove some old useless left-over code that was #if'ed out. # # Use a wait_queue for the 6-second delay during device resets # so that we can be woken up in the middle if a disconnect occurs. # # The key point here is that after scsi_remove_host(), everything is idle as # far as the SCSI midlayer is concerned. But if there was a command in # progress at the time, the midlayer will abort it without telling us or # waiting for it to complete. Hence we have to wait for the control thread # to be idle before we can try to kill it. This should happen quickly, # since all I/O attempted by the thread will fail immediately. # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/usb.h # 2004/06/13 13:09:07-07:00 mdharm-usb@one-eyed-alien.net +3 -2 # USB Storage: Fix race when removing the SCSI host # # drivers/usb/storage/usb.c # 2004/06/13 13:09:07-07:00 mdharm-usb@one-eyed-alien.net +85 -126 # USB Storage: Fix race when removing the SCSI host # # drivers/usb/storage/transport.c # 2004/06/13 13:09:07-07:00 mdharm-usb@one-eyed-alien.net +5 -4 # USB Storage: Fix race when removing the SCSI host # # ChangeSet # 2004/06/14 10:33:05-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: INQUIRY fixup, mode-sense options, Genesys devices # # This patch does a few things (all in the same section of code). It started # life as patches as226b, as280, and as275. Later it was merged into as226e # and I added significantly to it. # # # First, this patch introduces a new config option to allow people to enable # write-protect detection for their USB devices. With some luck, we've # finally got it right and can eventually remove this option in favor of # enabling this behavior all the time. # # Next, we change how we force some flags on -- it turns out that there are # some 'generic' entries in the SCSI devinfo which was overriding us when we # didn't want it. # # Finally, we add a safety check to the workaround for GeneSys Logic devices # -- if the max_sectors parameter has already been turned down, we won't turn # it up. # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/scsiglue.c # 2004/06/13 08:24:10-07:00 mdharm-usb@one-eyed-alien.net +46 -6 # USB Storage: INQUIRY fixup, mode-sense options, Genesys devices # # drivers/usb/storage/Kconfig # 2004/06/13 08:24:10-07:00 mdharm-usb@one-eyed-alien.net +22 -0 # USB Storage: INQUIRY fixup, mode-sense options, Genesys devices # # arch/arm/mach-footbridge/time.c # 2004/06/14 10:27:44-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-ebsa285/time.h -> arch/arm/mach-footbridge/time.c # # arch/arm/mach-ebsa110/time.c # 2004/06/14 10:03:25-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-ebsa110/time.h -> arch/arm/mach-ebsa110/time.c # # ChangeSet # 2004/06/14 09:45:55-07:00 greg@kroah.com # I2C: sparse cleanups again, based on comments from lkml # # This is more like the original code. # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/it87.c # 2004/06/14 02:45:18-07:00 greg@kroah.com +1 -4 # I2C: sparse cleanups again, based on comments from lkml # # This is more like the original code. # # Signed-off-by: Greg Kroah-Hartman # # BitKeeper/deleted/.del-time.c~8f84839a52a43e18 # 2004/06/13 20:40:08-07:00 dsaxena@omelas.(none) +0 -31 # Delete: arch/arm/mach-clps7500/time.c # # arch/arm/common/time-acorn.c # 2004/06/13 20:24:17-07:00 dsaxena@omelas.(none) +0 -0 # Rename: arch/arm/kernel/time-acorn.c -> arch/arm/common/time-acorn.c # # ChangeSet # 2004/06/12 22:23:05-03:00 acme@toy.kerneljanitors.org # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +41 -0 # # net/sunrpc/xprt.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +2 -2 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/sunrpc/svcsock.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv6/tcp_ipv6.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_output.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +4 -4 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_minisocks.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp_ipv4.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/ipv4/tcp.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +3 -22 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # net/core/stream.c # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +0 -0 # BitKeeper file /home/acme/bk/net-2.6/net/core/stream.c # # net/core/Makefile # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +1 -1 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/tcp.h # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +0 -22 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # include/net/sock.h # 2004/06/12 22:22:55-03:00 acme@toy.kerneljanitors.org +20 -0 # [NET] first bits of net/core/stream.c # # Move tcp sk_wmem_queued related functions to net/core/stream.c, will be # used by other SOCK_STREAM protocols, starting with LLC. # # Also move the tcp_charge_skb to sock.h, for the same reasons. # # Signed-off-by: Arnaldo Carvalho de Melo # # ChangeSet # 2004/06/11 17:22:53-07:00 linux@kodeaffe.de # [PATCH] sysfs: fs/sysfs/inode.c: modify parents ctime and mtime on creation # # When a node is added to sysfs (e.g. a device plugged in via USB), the # filesystem fails to make this change visible in the parent directory's # ctime/mtime. This is in contrast to removing a device, because in that # case, sysfs makes use of the function simple_unlink from fs/libfs.c which # takes care of that. Instead of using simple_link from fs/libfs.c on # creation, sysfs implements its own mechanism. This patch hooks into the # function sysfs_create and sets the ctime and the mtime of the parent to # CURRENT_TIME. # # Signed-off-by: Sebastian Henschel # Signed-off-by: Greg Kroah-Hartman # # fs/sysfs/inode.c # 2004/06/10 14:47:54-07:00 linux@kodeaffe.de +6 -1 # sysfs: fs/sysfs/inode.c: modify parents ctime and mtime on creation # # ChangeSet # 2004/06/11 17:22:14-07:00 hannal@us.ibm.com # [PATCH] Driver Model: Add class support to msr.c # # This patch enables class support in arch/i386/kernel/msr.c. Very simliar # to cpuid (with the fixes Zwane/Greg made, thanks). # # [root@w-hlinder2 root]# tree /sys/class/msr # /sys/class/msr # | -- msr0 # | `-- dev # `-- msr1 # `-- dev # # 2 directories, 2 files # # Thanks to Randy Dunlap for pointing out the unnecessary tabs. Fixed. # # Signed-off-by Hanna Linder # Signed-off-by: Greg Kroah-Hartman # # arch/i386/kernel/msr.c # 2004/06/09 16:33:29-07:00 hannal@us.ibm.com +69 -2 # Driver Model: Add class support to msr.c # # ChangeSet # 2004/06/11 17:15:38-07:00 lxiep@us.ibm.com # [PATCH] PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly # # I made changes to rpaphp code, so it can handle multi-fuction # devices correctly. The problem is that the pci_dev field of slot struct # can only record one pci_dev of the devices of a multi-fuction card. I # changed pci_dev (a single pci_dev type pointer) to pci_funcs( a list of # pci_dev type pointers). I rewrote some of the config/unconfig code to # support the slot struct change. # # Along with above changes, I added LDRSLOT(logical I/O slot) support. # We need LDRSLOT support for DLPAR I/O. A card in a LDRSLOT can't be # physically removed, but can be logically removed from one partiton and # reassinged to another partition. # # I also merged rpaphp changes from ames tree. # # # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/hotplug/rpaphp_core.c # 2004/06/08 15:53:59-07:00 lxiep@us.ibm.com +137 -62 # PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly # # drivers/pci/hotplug/rpaphp.h # 2004/06/08 15:53:59-07:00 lxiep@us.ibm.com +22 -6 # PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly # # drivers/pci/hotplug/rpadlpar_core.c # 2004/06/08 15:53:59-07:00 lxiep@us.ibm.com +5 -23 # PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly # # ChangeSet # 2004/06/11 17:15:00-07:00 bjorn.helgaas@hp.com # [PATCH] PCI: clarify pci.txt wrt IRQ allocation # # I think we should make it explicit that PCI IRQs shouldn't be relied # upon until after pci_enable_device(). This patch: # # ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.7-rc3/2.6.7-rc3-mm1/broken-out/bk-acpi.patch # # does PCI interrupt routing (based on ACPI _PRT) and IRQ allocation # at pci_enable_device()-time. # # (To avoid breaking things in 2.6, the above patch still allocates # all PCI IRQs in pci_acpi_init(), before any drivers are initialized. # But that shouldn't be needed by correct drivers, and I'd like to # remove it in 2.7.) # # # Signed-off-by: Greg Kroah-Hartman # # Documentation/pci.txt # 2004/06/11 14:09:58-07:00 bjorn.helgaas@hp.com +3 -2 # PCI: clarify pci.txt wrt IRQ allocation # # arch/ia64/kernel/unwind.c # 2004/06/11 17:13:56-07:00 kaos@sgi.com +20 -15 # ia64: Remove warnings when unwind debug is turned on # # ChangeSet # 2004/06/11 17:06:39-07:00 david-b@pacbell.net # [PATCH] USB: usb on big endian, ehci needs a byteswap # # Adds a missing byteswap that would affect interrupt transfers # with EHCI on big-endian platforms, like Rick's MIPS-4km uClinux. # Needed for external hubs, and then likely for mice, keyboards, # and so on. # # From: Rick Sewill # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ehci-sched.c # 2004/06/11 06:09:39-07:00 david-b@pacbell.net +1 -1 # USB: usb on big endian, ehci needs a byteswap # # ChangeSet # 2004/06/11 17:06:09-07:00 david-b@pacbell.net # [PATCH] USB: retry string fetches on ZLPs not just STALLs # # This matches the behavior for other descriptor fetches. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/06/11 04:49:33-07:00 david-b@pacbell.net +2 -2 # USB: retry string fetches on ZLPs not just STALLs # # ChangeSet # 2004/06/11 17:05:38-07:00 david-b@pacbell.net # [PATCH] USB: usbnet shouldn't oops on cdc error path # # If the string descriptor fetch works, no problem. Else # make the disconnect() logic -- newly called because of # "recent" changes to interface claiming logic -- use its # fast cleanup path, since we're still not fully set up yet. # # Should resolve OSDL bugid 2714; please merge. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/usbnet.c # 2004/06/10 23:55:54-07:00 david-b@pacbell.net +1 -0 # USB: usbnet shouldn't oops on cdc error path # # ChangeSet # 2004/06/11 17:05:08-07:00 david-b@pacbell.net # [PATCH] USB: usbtest just uses module_param() # # This prevents some warnings during modprobe. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/usbtest.c # 2004/06/11 00:06:34-07:00 david-b@pacbell.net +8 -8 # USB: usbtest just uses module_param() # # ChangeSet # 2004/06/11 16:52:33-07:00 thoffman@arnor.net # [PATCH] USB: ATI Remote driver update # # Here are some contributed improvements for the ATI remote driver. # # I submitted the driver and it was accepted several months ago. # Since then a few people have sent me patches and suggestions. # # This patch adds two things: # # (1) support for the "Lola" X10 remote, sent to me by # Seth Cohn # # (2) key autorepeat support, sent to me by # Vincent Vanackere # # The key autorepeat support has been tested by me, but the Lola support # has not, as I don't have the hardware. # # Thanks to Seth and Vincent, with my apologies for taking so long to # forward their improvements along. # # # Signed-off-by: Torrey Hoffman # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/ati_remote.c # 2004/06/08 17:12:09-07:00 thoffman@arnor.net +42 -12 # USB: ATI Remote driver update # # drivers/usb/input/Kconfig # 2004/06/09 15:24:29-07:00 thoffman@arnor.net +8 -6 # USB: ATI Remote driver update # # ChangeSet # 2004/06/11 16:51:56-07:00 stern@rowland.harvard.edu # [PATCH] USB: Mark devices as NOTATTACHED as soon as possible # # This patch implements something we've been lacking for a long time: a way # to mark devices as USB_STATE_NOTATTACHED as soon as we know that they're # gone. The usb_device->state member is no longer protected by the # ->serialize semaphore; instead there's a new private spinlock. Usbcore # routines should no longer set ->state directly; instead they should use # the new utility routine usb_set_device_state(). There are protections # against changing states while devices are being added or removed. # # Change assignments to udev->state into calls of # usb_set_device_state(). # # Add new private device_state_lock to the hub driver, along # with usb_set_device_state() and recursively_mark_NOTATTACHED(). # # Acquire the new spinlock while adding or removing children[] # pointers. # # When disabling a port that has a child device, mark the child # as NOTATTACHED. # # You mentioned once having tried to do something like this and running into # trouble. Take a good look and let me know if you see any difficulties # here. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/usb.h # 2004/06/09 06:52:00-07:00 stern@rowland.harvard.edu +3 -0 # USB: Mark devices as NOTATTACHED as soon as possible # # drivers/usb/core/message.c # 2004/06/09 06:50:10-07:00 stern@rowland.harvard.edu +4 -4 # USB: Mark devices as NOTATTACHED as soon as possible # # drivers/usb/core/hub.c # 2004/06/09 07:16:54-07:00 stern@rowland.harvard.edu +85 -12 # USB: Mark devices as NOTATTACHED as soon as possible # # drivers/usb/core/hcd.c # 2004/06/09 06:46:56-07:00 stern@rowland.harvard.edu +2 -2 # USB: Mark devices as NOTATTACHED as soon as possible # # ChangeSet # 2004/06/11 16:24:02-07:00 davidm@tiger.hpl.hp.com # ia64: Update defconfig # # arch/ia64/defconfig # 2004/06/11 16:23:55-07:00 davidm@tiger.hpl.hp.com +17 -6 # Update # # arch/arm/mach-clps7500/time.c # 2004/06/11 14:14:12-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-cl7500/time.h -> arch/arm/mach-clps7500/time.c # # BitKeeper/deleted/.del-time.c~531bda1d3ed195a5 # 2004/06/11 14:12:46-07:00 dsaxena@omelas.(none) +0 -0 # Delete: arch/arm/mach-adifcc/time.c # # arch/arm/mach-adifcc/time.c # 2004/06/11 14:10:55-07:00 dsaxena@omelas.(none) +0 -0 # Rename: include/asm-arm/arch-adifcc/time.h -> arch/arm/mach-adifcc/time.c # # ChangeSet # 2004/06/11 11:32:29-07:00 kaos@sgi.com # [PATCH] ia64: Remove warnings when unwind debug is turned on # # Turning on UNW_DEBUG generates warnings for incorrect number of # parameters for formats and several cases of "suggest explicit braces to # avoid ambiguous `else'", because UNW_DPRINT contains an if statement. # # Signed-off-by: Keith Owens # Signed-off-by: David Mosberger # # ChangeSet # 2004/06/10 20:00:01-04:00 margitsw@t-online.de # [PATCH] prism54: White space and indentation # # 2004-05-29 Margit Schubert-While # # * White space and indentation patch # # ChangeSet # 2004/06/10 19:59:53-04:00 margitsw@t-online.de # [PATCH] prism54: Fix typo # # 2004-05-29 Margit Schubert-While # # * isl_ioctl.c : Fix typo # # ChangeSet # 2004/06/10 19:59:45-04:00 margitsw@t-online.de # [PATCH] prism54: Fix channel stats, bump version to 1.2 # # 2004-05-20 Aurelien Alleaume # # * islpci_eth.c : use dev_kfree_skb_irq instead of dev_kfree_skb where needed. # # * isl_ioctl.c : report channel instead of frequency in scan. # # * islpci_hotplug.c : bump version to 1.2 # # ChangeSet # 2004/06/10 19:59:36-04:00 margitsw@t-online.de # [PATCH] prism54: Reduce module verbosity # # 2004-05-01 Margit Schubert-While # # * Reduce module verbosity # # ChangeSet # 2004/06/10 19:59:28-04:00 margitsw@t-online.de # [PATCH] prism54: Align skb patch # # * islpci_eth.c, islpci_dev.c : Align skb->data unconditonally after # allocation. This would appear to improve RX rate # # ChangeSet # 2004/06/10 19:59:20-04:00 margitsw@t-online.de # [PATCH] prism54: Add likely/unlikely, KO wds completely # # * islpci_mgt.h : Change init_wds definition # # * islpci_eth.c : Do some likely/unlikely # # ChangeSet # 2004/06/10 19:59:11-04:00 margitsw@t-online.de # [PATCH] prism54: Don't allow mib reads while unconfigured # # 004-04-17 Aurelien Alleaume # # * oid_mgt.c, isl_ioctl.c : Cleanup. Prevented real oid reading # before the card is configured with mib values (might be # related to # bug #53). # # ChangeSet # 2004/06/10 19:59:03-04:00 margitsw@t-online.de # [PATCH] prism54: Fix bug 77, strengthened oid txn # # 2004-04-09 Aurelien Alleaume # # * oid_mgt.c, isl_ioctl.c : Cleanups. Bug #77. Minor stuffs. # # * islpci_mgt.c (islpci_mgt_transaction) : enforce serialization # in oid transaction. lindent.sh. # # * islpci_mgt.c (islpci_mgt_transaction) : Strengthened oid transaction. # # ChangeSet # 2004/06/10 19:58:55-04:00 margitsw@t-online.de # [PATCH] prism54: Fix bugs 39/73 # # 2004-04-07 Margit Schubert-While # # * Bugs 39 and 73 # # ChangeSet # 2004/06/10 19:58:46-04:00 margitsw@t-online.de # [PATCH] prism54: Fix bugs 74/75 # # 2004-03-22 Aurelien Alleaume # # * oid_mgt.c, isl_ioctl.c : Minor bugfixes : #74 and #75. # # ChangeSet # 2004/06/10 19:38:59-04:00 bunk@fs.tum.de # [PATCH] add NAPI help texts # # NAPI seems to be so self-explaining that no help texts are needed. ;-) # # I combined the two help texts that were at NAPI options, and added them # to all NAPI options. # # ChangeSet # 2004/06/10 19:37:53-04:00 rmk@arm.linux.org.uk # [PATCH] add ARM smc91x driver # # ChangeSet # 2004/06/10 19:58:38-04:00 margitsw@t-online.de # [PATCH] prism54: Fix endian patch # # * Split out patch islpci_eth.c : # * Fix endian problem (bug 74/75 related) # # ChangeSet # 2004/06/10 20:52:50-04:00 jgarzik@pobox.com # [netdrvr acenic] remove unneeded ifdefs # # ChangeSet # 2004/06/10 20:19:03-04:00 shemminger@osdl.org # [PATCH] fix oops from acenic ethtool # # Fix the following OOPS that happens when doing ifup on FC-2 # with 2.6.7 in acenic and a security hole due to missing capable(NET_ADMIN), # by replacing private ethtool handling with ethtool_ops. # # (Yes, Jes because of DEV_ETHTOOL_OPS define it will still work # on ancient kernels.) # # ChangeSet # 2004/06/10 19:58:30-04:00 margitsw@t-online.de # [PATCH] prism54: Kernel compatibility # # 2004-03-20 Margit Schubert-While # # * isl_38xx.[ch], isl_ioctl.c, islpci_dev.[ch], islpci_eth.c # islpci_hotplug.c, islpci_mgt.[ch], oid_mgt.c, prismcompat.h: # Adopt new prism54 kernel compatibility. # Remove remaining kernel version ifdefs. # # ChangeSet # 2004/06/10 19:37:01-04:00 akpm@osdl.org # [PATCH] fealnx-mac-address-and-other-issues.patch # # (resend - I need to get this out of my tree my one means or another..) # # # From: "SuD (Alex)" # # I recently was given a surecom 10/100 ethernet card and found that i could # not change Mac address for it as other driver/devices allow. I tried to # implement the missing feature and noticed that the device is quite peculiar # (or either my system is broken), when trying to fill mac address registers # (no matter whether io_ops is set): - If I write a byte (writeb) to an even # i/o address it seems like actually a word was written (the next byte is set # to 0). - If I write a byte to an odd i/o address my pc gets bad freezed. # # That made think of writing 16bit words (writew) for the memory address, as # opposed to what most driver examples do. It works for me (I hope i set the # lines at the right place in device_open function after the device is # reset). I hope the code is clean enough and does not mess with byte # ordering. This is the patch (this time against 2.6.5): # # (akpm: Is this right on big-endian?) # # drivers/net/acenic.c # 2004/06/10 20:52:44-04:00 jgarzik@pobox.com +0 -6 # [netdrvr acenic] remove unneeded ifdefs # # drivers/net/acenic.h # 2004/06/04 17:31:46-04:00 shemminger@osdl.org +0 -1 # fix oops from acenic ethtool # # drivers/net/acenic.c # 2004/06/04 17:31:46-04:00 shemminger@osdl.org +127 -121 # fix oops from acenic ethtool # # drivers/net/wireless/prism54/oid_mgt.h # 2004/05/28 08:06:38-04:00 margitsw@t-online.de +1 -1 # prism54: White space and indentation (resend) # # drivers/net/wireless/prism54/oid_mgt.c # 2004/05/28 09:12:49-04:00 margitsw@t-online.de +7 -7 # prism54: White space and indentation (resend) # # drivers/net/wireless/prism54/islpci_mgt.c # 2004/05/28 09:12:49-04:00 margitsw@t-online.de +42 -42 # prism54: White space and indentation (resend) # # drivers/net/wireless/prism54/islpci_eth.c # 2004/05/28 09:49:41-04:00 margitsw@t-online.de +8 -8 # prism54: White space and indentation (resend) # # drivers/net/wireless/prism54/islpci_dev.h # 2004/05/28 08:25:30-04:00 margitsw@t-online.de +1 -1 # prism54: White space and indentation (resend) # # drivers/net/wireless/prism54/isl_ioctl.c # 2004/05/28 09:49:41-04:00 margitsw@t-online.de +28 -34 # prism54: White space and indentation (resend) # # drivers/net/wireless/prism54/isl_ioctl.c # 2004/05/28 09:33:42-04:00 margitsw@t-online.de +1 -1 # prism54: Fix typo # # drivers/net/wireless/prism54/islpci_hotplug.c # 2004/05/28 09:49:41-04:00 margitsw@t-online.de +1 -1 # prism54: Fix channel stats, bump version to 1.2 (resend) # # drivers/net/wireless/prism54/islpci_eth.c # 2004/05/28 09:49:41-04:00 margitsw@t-online.de +3 -3 # prism54: Fix channel stats, bump version to 1.2 (resend) # # drivers/net/wireless/prism54/isl_ioctl.c # 2004/05/28 09:49:41-04:00 margitsw@t-online.de +2 -2 # prism54: Fix channel stats, bump version to 1.2 (resend) # # drivers/net/wireless/prism54/islpci_dev.c # 2004/06/05 08:11:34-04:00 margitsw@t-online.de +3 -1 # prism54: Reduce module verbosity (resend) # # drivers/net/wireless/prism54/islpci_eth.c # 2004/06/05 08:09:41-04:00 margitsw@t-online.de +1 -0 # prism54: Align skb patch (resend) # # drivers/net/wireless/prism54/islpci_dev.c # 2004/06/05 08:09:41-04:00 margitsw@t-online.de +1 -0 # prism54: Align skb patch (resend) # # drivers/net/wireless/prism54/islpci_mgt.h # 2004/05/28 09:33:42-04:00 margitsw@t-online.de +1 -1 # prism54: Add likely/unlikely, KO wds completely (resend) # # drivers/net/wireless/prism54/islpci_eth.c # 2004/05/28 09:33:42-04:00 margitsw@t-online.de +9 -8 # prism54: Add likely/unlikely, KO wds completely (resend) # # drivers/net/wireless/prism54/oid_mgt.c # 2004/06/05 08:03:15-04:00 margitsw@t-online.de +40 -21 # prism54: Don't allow mib reads while unconfigured (resend) # # drivers/net/wireless/prism54/islpci_mgt.c # 2004/06/05 08:03:15-04:00 margitsw@t-online.de +5 -3 # prism54: Don't allow mib reads while unconfigured (resend) # # drivers/net/wireless/prism54/islpci_dev.c # 2004/06/05 08:03:15-04:00 margitsw@t-online.de +3 -1 # prism54: Don't allow mib reads while unconfigured (resend) # # drivers/net/wireless/prism54/isl_ioctl.h # 2004/06/05 08:03:15-04:00 margitsw@t-online.de +0 -1 # prism54: Don't allow mib reads while unconfigured (resend) # # drivers/net/wireless/prism54/isl_ioctl.c # 2004/06/05 08:03:15-04:00 margitsw@t-online.de +5 -31 # prism54: Don't allow mib reads while unconfigured (resend) # # drivers/net/wireless/prism54/oid_mgt.c # 2004/05/28 09:08:01-04:00 margitsw@t-online.de +2 -6 # prism54: Fix bug 77, strengthened oid txn (resend) # # drivers/net/wireless/prism54/islpci_mgt.c # 2004/05/28 09:08:01-04:00 margitsw@t-online.de +35 -26 # prism54: Fix bug 77, strengthened oid txn (resend) # # drivers/net/wireless/prism54/isl_ioctl.c # 2004/05/28 09:08:01-04:00 margitsw@t-online.de +13 -76 # prism54: Fix bug 77, strengthened oid txn (resend) # # drivers/net/wireless/prism54/islpci_dev.c # 2004/06/05 07:57:11-04:00 margitsw@t-online.de +2 -2 # prism54: Fix bugs 39/73 (resend) # # drivers/net/wireless/prism54/oid_mgt.c # 2004/05/28 08:43:01-04:00 margitsw@t-online.de +2 -2 # prism54: Fix bugs 74/75 (resend) # # drivers/net/wireless/prism54/isl_ioctl.c # 2004/05/28 08:43:01-04:00 margitsw@t-online.de +1 -0 # prism54: Fix bugs 74/75 (resend) # # drivers/net/wireless/prism54/islpci_eth.c # 2004/05/28 08:25:30-04:00 margitsw@t-online.de +16 -16 # prism54: Fix endian patch (resend) # # drivers/net/wireless/prism54/prismcompat.h # 2004/06/05 07:45:32-04:00 margitsw@t-online.de +46 -0 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/prismcompat.h # 2004/06/05 07:45:32-04:00 margitsw@t-online.de +0 -0 # BitKeeper file /spare/repo/netdev-2.6/prism54/drivers/net/wireless/prism54/prismcompat.h # # drivers/net/wireless/prism54/oid_mgt.c # 2004/06/05 07:44:14-04:00 margitsw@t-online.de +1 -0 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/islpci_mgt.h # 2004/06/05 07:44:14-04:00 margitsw@t-online.de +0 -9 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/islpci_mgt.c # 2004/06/05 07:44:14-04:00 margitsw@t-online.de +1 -15 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/islpci_hotplug.c # 2004/06/05 07:44:14-04:00 margitsw@t-online.de +1 -0 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/islpci_eth.c # 2004/06/05 07:44:14-04:00 margitsw@t-online.de +1 -0 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/islpci_dev.h # 2004/06/05 07:44:14-04:00 margitsw@t-online.de +0 -20 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/islpci_dev.c # 2004/06/05 07:45:32-04:00 margitsw@t-online.de +121 -27 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/isl_ioctl.c # 2004/06/05 07:44:14-04:00 margitsw@t-online.de +1 -1 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/isl_38xx.h # 2004/06/05 07:45:32-04:00 margitsw@t-online.de +0 -10 # prism54: Kernel compatibility (resend) # # drivers/net/wireless/prism54/isl_38xx.c # 2004/06/05 07:45:32-04:00 margitsw@t-online.de +2 -132 # prism54: Kernel compatibility (resend) # # drivers/net/tulip/Kconfig # 2004/06/04 11:16:07-04:00 bunk@fs.tum.de +11 -4 # add NAPI help texts # # drivers/net/Kconfig # 2004/06/04 11:18:14-04:00 bunk@fs.tum.de +70 -0 # add NAPI help texts # # drivers/net/arm/smc91x.h # 2004/05/29 08:04:43-04:00 rmk@arm.linux.org.uk +829 -0 # Re: smc91x driver # # drivers/net/arm/smc91x.c # 2004/05/29 07:57:20-04:00 rmk@arm.linux.org.uk +2171 -0 # Re: smc91x driver # # drivers/net/arm/smc91x.h # 2004/05/29 08:04:43-04:00 rmk@arm.linux.org.uk +0 -0 # BitKeeper file /spare/repo/netdev-2.6/misc/drivers/net/arm/smc91x.h # # drivers/net/arm/smc91x.c # 2004/05/29 07:57:20-04:00 rmk@arm.linux.org.uk +0 -0 # BitKeeper file /spare/repo/netdev-2.6/misc/drivers/net/arm/smc91x.c # # drivers/net/arm/Makefile # 2003/07/06 11:12:19-04:00 rmk@arm.linux.org.uk +1 -0 # Re: smc91x driver # # drivers/net/arm/Kconfig # 2003/09/28 11:03:12-04:00 rmk@arm.linux.org.uk +17 -0 # Re: smc91x driver # # drivers/net/fealnx.c # 2004/04/23 01:29:23-04:00 akpm@osdl.org +5 -0 # fealnx-mac-address-and-other-issues.patch # # ChangeSet # 2004/06/10 16:34:14-07:00 kenneth.w.chen@intel.com # [PATCH] ia64: fix race in fsys_bubble_down to avoid fp-register corruption # # The fast system-call fall-back-path has a race: it reads PSR, modifies # some bits, then writes back the new PSR. Unfortunately, the contents # of PSR may change between reading and writing it. For example, an # interrupt could occur which could trigger a context-switch. The # context-switch might in turn flush the floating-point-high (FPH) # partition to memory, clear PSR.MFH, and set PSR.DFH. To prevent this # race, the patch below turns off PSR.I before reading PSR. # # This fixes a floating-point corruption problem that was observed on a # system with a libc which has the fast system-call support enabled. # # The performance impact is minimal (on the order of a handful of cycles). # # Signed-off-by: Kevin Tian # Signed-off-by: Ken Chen # Signed-off-by: Asit Mallick # Signed-off-by: David Mosberger # # arch/ia64/kernel/gate.S # 2004/06/09 05:36:21-07:00 kenneth.w.chen@intel.com +4 -2 # ia64: fix race in fsys_bubble_down # # arch/ia64/kernel/fsys.S # 2004/06/09 05:11:54-07:00 kenneth.w.chen@intel.com +2 -1 # ia64: fix race in fsys_bubble_down # # ChangeSet # 2004/06/10 13:25:26-07:00 Robert.Picco@hp.com # [PATCH] ia64: mark non-existent NUMA-nodes as offline # # I found a problem with HP NUMA configuration in 2.6.7-rc3-mm1. The # node_online_map is incorrect because of actions taken by # reassign_cpu_only_nodes in arch/ia64/mm/discontig.c. The mm1 patch # which changes the mempolicy for the init_task uses this invalid # node_online_map and eventually uses a non-existent node's zonelist # when calling __alloc_pages. # # The patch below takes care of this issue. It puts the non-existent # nodes offline. # # Signed-off-by: David Mosberger # # arch/ia64/mm/discontig.c # 2004/06/09 15:44:02-07:00 Robert.Picco@hp.com +3 -0 # ia64: mark non-existent NUMA-nodes as offline # # ChangeSet # 2004/06/10 12:52:02-07:00 greg@kroah.com # I2C: sparse cleanups for drivers/i2c/* # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/i2c-dev.c # 2004/06/10 05:51:18-07:00 greg@kroah.com +3 -4 # I2C: sparse cleanups for drivers/i2c/* # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/it87.c # 2004/06/10 05:51:18-07:00 greg@kroah.com +4 -1 # I2C: sparse cleanups for drivers/i2c/* # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/10 12:09:46-07:00 greg@kroah.com # USB: fix up dumb int_user_arg variable name as pointed out by Al Viro. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/auerswald.c # 2004/06/10 05:08:46-07:00 greg@kroah.com +7 -7 # USB: fix up dumb int_user_arg variable name as pointed out by Al Viro. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/hiddev.c # 2004/06/10 05:08:46-07:00 greg@kroah.com +4 -5 # USB: fix up dumb int_user_arg variable name as pointed out by Al Viro. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/audio.c # 2004/06/10 05:08:46-07:00 greg@kroah.com +32 -32 # USB: fix up dumb int_user_arg variable name as pointed out by Al Viro. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/10 11:40:08-07:00 greg@kroah.com # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/whiteheat.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +3 -2 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/kobil_sct.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +5 -4 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/kl5kusb105.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +7 -8 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/io_ti.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +3 -3 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/io_edgeport.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +7 -8 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ftdi_sio.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +6 -6 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/rtl8150.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +15 -15 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/legousbtower.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +4 -4 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/auerswald.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +8 -6 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/w9968cf.h # 2004/06/10 04:39:09-07:00 greg@kroah.com +1 -1 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/w9968cf.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +24 -23 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/vicam.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +14 -18 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/usbvideo.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +2 -2 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/stv680.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +1 -1 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/se401.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +1 -1 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/pwc-if.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +2 -2 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/ov511.h # 2004/06/10 04:39:09-07:00 greg@kroah.com +1 -1 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/ov511.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +1 -1 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/dabusb.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +5 -5 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/hiddev.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +26 -24 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/hid-core.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +3 -1 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/image/mdc800.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +3 -3 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/audio.c # 2004/06/10 04:39:09-07:00 greg@kroah.com +36 -30 # USB: sparse cleanups for the whole driver/usb/* tree. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/10 09:48:09-07:00 rtjohnso@eecs.berkeley.edu # [PATCH] PATCH: 2.6.7-rc3 drivers/usb/core/devio.c: user/kernel pointer bugs # # Since ctrl is copied in from userspace, ctrl.data cannot safely be # dereferenced. Let me know if you have any questions or if I've made # a mistake. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/devio.c # 2004/06/09 05:49:50-07:00 rtjohnso@eecs.berkeley.edu +2 -2 # PATCH: 2.6.7-rc3 drivers/usb/core/devio.c: user/kernel pointer bugs # # ChangeSet # 2004/06/10 09:36:26-07:00 greg@kroah.com # Driver Core: more whitespace fixups # # This catches the files I had to do by hand as Dmitry's patch differed from my tree. # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # drivers/base/bus.c # 2004/06/10 02:35:56-07:00 greg@kroah.com +64 -65 # Driver Core: more whitespace fixups # # This catches the files I had to do by hand as Dmitry's patch differed from my tree. # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/10 09:34:27-07:00 dtor_core@ameritech.net # [PATCH] Driver Core: Whitespace fixes # # Whitespace and formatting changes (a,b,c -> a, b, c) in drivers/base # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # drivers/base/sys.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +51 -51 # Driver Core: Whitespace fixes # # drivers/base/power/sysfs.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +9 -9 # Driver Core: Whitespace fixes # # drivers/base/power/suspend.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +21 -21 # Driver Core: Whitespace fixes # # drivers/base/power/shutdown.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +9 -9 # Driver Core: Whitespace fixes # # drivers/base/power/runtime.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +4 -4 # Driver Core: Whitespace fixes # # drivers/base/power/resume.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +6 -6 # Driver Core: Whitespace fixes # # drivers/base/power/power.h # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +4 -4 # Driver Core: Whitespace fixes # # drivers/base/power/main.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +7 -7 # Driver Core: Whitespace fixes # # drivers/base/platform.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +9 -9 # Driver Core: Whitespace fixes # # drivers/base/node.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +7 -7 # Driver Core: Whitespace fixes # # drivers/base/interface.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +9 -9 # Driver Core: Whitespace fixes # # drivers/base/init.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +2 -2 # Driver Core: Whitespace fixes # # drivers/base/firmware_class.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +5 -5 # Driver Core: Whitespace fixes # # drivers/base/firmware.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +3 -3 # Driver Core: Whitespace fixes # # drivers/base/driver.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +8 -8 # Driver Core: Whitespace fixes # # drivers/base/core.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +23 -23 # Driver Core: Whitespace fixes # # drivers/base/class_simple.c # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +6 -6 # Driver Core: Whitespace fixes # # drivers/base/base.h # 2004/06/09 23:34:24-07:00 dtor_core@ameritech.net +3 -2 # Driver Core: Whitespace fixes # # ChangeSet # 2004/06/10 09:25:58-07:00 dtor_core@ameritech.net # [PATCH] Driver Core: Suppress platform device suffixes # # Do not add numeric suffix to platform device name if device id is set to # -1. This can be used when there can be only one instance of a device # (like i8042). # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # drivers/base/platform.c # 2004/06/09 23:33:27-07:00 dtor_core@ameritech.net +4 -1 # Driver Core: Suppress platform device suffixes # # ChangeSet # 2004/06/09 11:14:30-07:00 greg@kroah.com # USB: crap, I misapplied a patch with the wrong level # # This gets rid of usb/host and puts the file in the proper drivers/usb/host # directory. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ohci-lh7a404.c # 2004/06/09 04:12:00-07:00 greg@kroah.com +0 -0 # USB: crap, I misapplied a patch with the wrong level # # This gets rid of usb/host and puts the file in the proper drivers/usb/host # directory. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/09 11:10:52-07:00 stern@rowland.harvard.edu # [PATCH] USB: Update root-hub code for the ohci-lh7a404 driver # # On Wed, 9 Jun 2004, David Brownell wrote: # # > Needs an update for ohci-lh7a404.c too ... # # I didn't even know this driver existed! Where did usb/host/* come from? # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # usb/host/ohci-lh7a404.c # 2004/06/09 06:09:47-07:00 stern@rowland.harvard.edu +1 -3 # USB: Update root-hub code for the ohci-lh7a404 driver # # ChangeSet # 2004/06/09 11:10:09-07:00 stern@rowland.harvard.edu # [PATCH] USB: Minor tidying up of hub driver # # After my last few changesets there were a few small items that needed to # be tidied up. # # Update kerneldoc to reflect the actual operation of # usb_disconnect() and usb_new_device(). The new locking # requirements are listed too, though they aren't all # implemented yet. # # Fulfill the new locking requirement in hcd_panic(). # # Remove unneeded local variables to conserve stack space in # usb_disconnect(), which calls itself recursively. # # In hub_port_connect_change(), store the parent's children[] # pointer as late as possible and don't lock the new device until # then (that's when it becomes globally accessible). This will # minimize the time that the not-fully-configured device structure # is visible to other parts of the kernel. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/09 05:20:00-07:00 stern@rowland.harvard.edu +25 -23 # USB: Minor tidying up of hub driver # # drivers/usb/core/hcd.c # 2004/06/09 05:03:06-07:00 stern@rowland.harvard.edu +2 -0 # USB: Minor tidying up of hub driver # # ChangeSet # 2004/06/09 11:09:31-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix bus-list root-hub race # # There are a few places where the code enumerates through all the USB # devices on all the buses, starting with each bus's root hub and working # down. However a bus does not always have a root hub, and the code does # not check that the root_hub pointer is non-NULL. This patch fixes the # problem, using the usb_bus_list_lock semaphore to synchronize access when # root hubs are added or removed. # # In addition it seemed like a good idea to minimize the time that a # non-fully-configured root hub is accessible through the bus's pointer. So # this patch delays setting the pointer and holds usb_bus_list_lock while # configuring a root hub. # # It turned out that a bunch of things needed to be changed for all this to # work: # # Check for NULL root_hub pointer in usb_device_read() and # usb_find_device(). # # Pass the root-hub device as a separate argument to # hcd_register_root(). # # Make usb_register_root_hub() acquire the usb_bus_list_lock and # set the bus->root_hub pointer. # # For consistency's sake, move the place where the children[] # pointer to a non-root-hub device gets stored as close as possible # to where usb_new_device() is called. # # Make usb_disconnect() acquire the usb_bus_list_lock when removing # a root hub. # # Change usb_hcd_pci_remove() and the non-PCI host drivers so that # they call usb_disconnect() with a pointer to the bus's root_hub # pointer, not a pointer to a temporary variable. # # Change all the host controller drivers not to store the root_hub # pointer in the bus structure but instead to pass it as a new # argument to hcd_register_root(). # # I made some attempt to update the hc_sl811 driver along with the rest, but # it's pretty clear that driver won't work in the current framework. Among # other things, it never reads the root hub's device descriptor. To what # extent is the driver really supported? # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/uhci-hcd.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +2 -3 # USB: Fix bus-list root-hub race # # drivers/usb/host/ohci-sa1111.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +1 -3 # USB: Fix bus-list root-hub race # # drivers/usb/host/ohci-omap.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +1 -3 # USB: Fix bus-list root-hub race # # drivers/usb/host/ohci-hcd.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +2 -3 # USB: Fix bus-list root-hub race # # drivers/usb/host/hc_sl811_rh.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +8 -2 # USB: Fix bus-list root-hub race # # drivers/usb/host/ehci-hcd.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +2 -3 # USB: Fix bus-list root-hub race # # drivers/usb/gadget/dummy_hcd.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +2 -3 # USB: Fix bus-list root-hub race # # drivers/usb/core/usb.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +2 -0 # USB: Fix bus-list root-hub race # # drivers/usb/core/hub.c # 2004/06/09 04:45:43-07:00 stern@rowland.harvard.edu +16 -7 # USB: Fix bus-list root-hub race # # drivers/usb/core/hcd.h # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +3 -3 # USB: Fix bus-list root-hub race # # drivers/usb/core/hcd.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +10 -3 # USB: Fix bus-list root-hub race # # drivers/usb/core/hcd-pci.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +1 -3 # USB: Fix bus-list root-hub race # # drivers/usb/core/devices.c # 2004/06/09 04:40:49-07:00 stern@rowland.harvard.edu +2 -0 # USB: Fix bus-list root-hub race # # ChangeSet # 2004/06/09 11:08:58-07:00 oliver@neukum.org # [PATCH] USB: add printer reset ioctl # # - add soft reset ioctl # # Signed-off-by: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usblp.c # 2004/06/09 10:05:10-07:00 oliver@neukum.org +10 -0 # USB: add printer reset ioctl # # ChangeSet # 2004/06/09 10:34:09-07:00 akpm@osdl.org # [PATCH] I2C: w83627hf.c build fix # # with gcc-2.95: # # drivers/i2c/chips/w83627hf.c:482: parse error before `static' # drivers/i2c/chips/w83627hf.c:502: parse error before `static' # drivers/i2c/chips/w83627hf.c: In function `show_regs_fan_1': # drivers/i2c/chips/w83627hf.c:541: warning: implicit declaration of function `show_fan' # drivers/i2c/chips/w83627hf.c: In function `w83627hf_detect': # drivers/i2c/chips/w83627hf.c:1074: `dev_attr_in0_min' undeclared (first use in this function) # drivers/i2c/chips/w83627hf.c:1074: (Each undeclared identifier is reported only once # drivers/i2c/chips/w83627hf.c:1074: for each function it appears in.) # drivers/i2c/chips/w83627hf.c: At top level: # drivers/i2c/chips/w83627hf.c:428: warning: `show_regs_in_min0' defined but not used # drivers/i2c/chips/w83627hf.c:441: warning: `store_regs_in_min0' defined but not used # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83627hf.c # 2004/06/08 23:10:38-07:00 akpm@osdl.org +3 -3 # I2C: w83627hf.c build fix # # ChangeSet # 2004/06/09 10:19:23-07:00 greg@kroah.com # merge i2c-2.6 into driver-2.6 trees due to problems people reported. # # drivers/i2c/chips/w83627hf.c # 2004/06/09 10:19:12-07:00 greg@kroah.com +0 -1 # merge i2c-2.6 into driver-2.6 trees due to problems people reported. # # drivers/scsi/scsi_debug.c # 2004/06/09 10:11:48-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/i2c/chips/it87.c # 2004/06/09 10:11:48-07:00 greg@kroah.com +0 -0 # Auto merged # # MAINTAINERS # 2004/06/09 10:11:47-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/06/08 22:45:12-07:00 greg@kroah.com # cpuid: fix hotplug cpu remove bug for class device. # # Signed-off-by: Greg Kroah-Hartman # # arch/i386/kernel/cpuid.c # 2004/06/08 22:44:49-07:00 greg@kroah.com +12 -14 # cpuid: fix hotplug cpu remove bug for class device. # # Signed-off-by: Greg Kroah-Hartman # # drivers/base/platform.c # 2004/06/08 16:46:21-07:00 rmk@arm.linux.org.uk +86 -0 # Add platform_get_resource() # # ChangeSet # 2004/06/08 16:28:02-07:00 rmk@arm.linux.org.uk # [PATCH] Add platform_get_resource() # # This patch adds management of platform device resources to the # device model, allowing drivers to lookup resources, IRQs and DMA # numbers in the platform device resource array. We also add a # couple of functions which allow platform devices and their resources # to be registered. # # Signed-off-by: Russell King # Signed-off-by: Greg Kroah-Hartman # # include/linux/device.h # 2004/05/28 12:29:34-07:00 rmk@arm.linux.org.uk +5 -0 # Add platform_get_resource() # # ChangeSet # 2004/06/08 16:26:12-07:00 hannal@us.ibm.com # [PATCH] Add cpu hotplug support to cpuid.c # # Here is the patch that uses a cpu hotplug callback, to allow dynamic support # of cpu id for classes in sysfs. # # This patch applies on top of the one I sent out earlier that Greg included. # I do not have access to hardware that supports cpu hotswapping (virtually or not) # so have not been able to test that aspect of the patch. However, the original # functionality of listing static cpu's still works. # # Please consider for testing or inclusion. # # Signed-off-by: Hanna Linder # Signed-off-by: Greg Kroah-Hartman # # arch/i386/kernel/cpuid.c # 2004/06/08 14:31:22-07:00 hannal@us.ibm.com +48 -11 # Add cpu hotplug support to cpuid.c # # ChangeSet # 2004/06/08 16:10:24-07:00 stern@rowland.harvard.edu # [PATCH] USB: Initialize endpoint autoconfig in g_file_storage # # This one-line patch corrects a simple problem in the g_file_storage # driver. It neglected to initialize the endpoint-autoconfiguration library # before using it. Please apply. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/file_storage.c # 2004/06/08 04:03:07-07:00 stern@rowland.harvard.edu +1 -0 # USB: Initialize endpoint autoconfig in g_file_storage # # ChangeSet # 2004/06/08 16:09:55-07:00 david-b@pacbell.net # [PATCH] lh7a404 USB host against 2.6.7-rc2 # # Support for the Sharp LH7A404 OHCI, another non-PCI implementation. # This uses a platform_device and a workaround for a register read # problem. # # Signed-off-by: Marc Singer # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # usb/host/ohci-lh7a404.c # 2004/06/07 16:24:04-07:00 david-b@pacbell.net +387 -0 # lh7a404 USB host against 2.6.7-rc2 # # drivers/usb/Kconfig # 2004/06/07 09:24:04-07:00 david-b@pacbell.net +1 -1 # lh7a404 USB host against 2.6.7-rc2 # # usb/host/ohci-lh7a404.c # 2004/06/07 16:24:04-07:00 david-b@pacbell.net +0 -0 # BitKeeper file /home/greg/linux/BK/usb-2.6/usb/host/ohci-lh7a404.c # # drivers/usb/host/ohci.h # 2004/06/07 09:24:04-07:00 david-b@pacbell.net +19 -0 # lh7a404 USB host against 2.6.7-rc2 # # drivers/usb/host/ohci-q.c # 2004/06/07 09:24:04-07:00 david-b@pacbell.net +3 -3 # lh7a404 USB host against 2.6.7-rc2 # # drivers/usb/host/ohci-hub.c # 2004/06/07 09:33:47-07:00 david-b@pacbell.net +21 -21 # lh7a404 USB host against 2.6.7-rc2 # # drivers/usb/host/ohci-hcd.c # 2004/06/07 09:24:04-07:00 david-b@pacbell.net +26 -16 # lh7a404 USB host against 2.6.7-rc2 # # drivers/usb/host/ohci-dbg.c # 2004/06/07 09:24:04-07:00 david-b@pacbell.net +15 -15 # lh7a404 USB host against 2.6.7-rc2 # # ChangeSet # 2004/06/08 16:09:24-07:00 david-b@pacbell.net # [PATCH] USB: rndis (3/4) Big Endian support for gadget RNDIS # # Add byteswapping. Original version partially worked on PPC with Net2280, # this version applies to the latest RNDIS code but hasn't been retested on # big-endian. Ping should be working in at least one one direction. # # Also added a handful of other things from my BK: track suspend/resume # (to eventually implement wake-on-lan), give a better rndis error # message, and add missing declarations for PM-related OIDs (usage is # #ifdeffed out by previous patch). # # From: Jon Neal # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/rndis.c # 2004/06/07 11:30:16-07:00 david-b@pacbell.net +199 -163 # USB: rndis (3/4) Big Endian support for gadget RNDIS # # drivers/usb/gadget/ndis.h # 2004/06/07 11:30:16-07:00 david-b@pacbell.net +30 -0 # USB: rndis (3/4) Big Endian support for gadget RNDIS # # drivers/usb/gadget/ether.c # 2004/06/07 11:32:18-07:00 david-b@pacbell.net +28 -2 # USB: rndis (3/4) Big Endian support for gadget RNDIS # # ChangeSet # 2004/06/08 16:08:52-07:00 david-b@pacbell.net # [PATCH] USB: usb suspend/resume work better on net2280 # # This makes net2280 behave more correctly with respect to # usb suspend and resume processing. # # So for example gadget zero autoresume testing works. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/net2280.c # 2004/06/07 07:31:53-07:00 david-b@pacbell.net +17 -8 # USB: usb suspend/resume work better on net2280 # # ChangeSet # 2004/06/08 16:08:19-07:00 david-b@pacbell.net # [PATCH] USB: usb root hubs can set power budgets # # This adds hub_set_power_budget(), mostly so that HCDs for low # powered ports (cell phone, PDA, etc) can more easily report their # true power budgets. It's not always 500mA per root hub port; this # makes dummy_hcd report the minimum, 8mA. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/dummy_hcd.c # 2004/06/07 07:31:53-07:00 david-b@pacbell.net +3 -0 # USB: usb root hubs can set power budgets # # drivers/usb/core/hub.h # 2004/06/07 07:31:53-07:00 david-b@pacbell.net +11 -0 # USB: usb root hubs can set power budgets # # ChangeSet # 2004/06/08 14:36:23-07:00 jmunsin@iki.fi # [PATCH] I2C: drivers/i2c/chips/it87.c cleanup patch # # Attached is a cleanup patch for the it87 sensor driver, against # 2.6.7-rc2. Jean Delvare has reviewed it. # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/it87.c # 2004/06/08 13:33:09-07:00 jmunsin@iki.fi +22 -26 # I2C: drivers/i2c/chips/it87.c cleanup patch # # ChangeSet # 2004/06/08 14:31:15-07:00 mhoffman@lightlink.com # [PATCH] I2C: add alternate VCORE calculations for w83627thf and w83637hf # # This patch adds support for the alternate in0/VCORE calculation which is # available for 2 of 4 chips this driver supports. It also fixes a minor # bug in the standard voltage input calculation. # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83627hf.c # 2004/06/05 19:02:59-07:00 mhoffman@lightlink.com +91 -3 # I2C: add alternate VCORE calculations for w83627thf and w83637hf # # ChangeSet # 2004/06/08 14:28:46-07:00 daniel.ritz@gmx.ch # [PATCH] PCI: fix irq routing on acer travelmate 360 laptop # # Fixes interrupt routing on acer travelmate 360 notebooks. it looks like # the bios assigned the wrong pirq value for the cardbus bridge. just # assigning irq 10 to all devices with pirq 0x63 would break second usb port. # pirq 0x68 seems to be right one for cardbus. # # Signed-off-by: Daniel Ritz # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # arch/i386/pci/irq.c # 2004/06/05 00:16:53-07:00 daniel.ritz@gmx.ch +9 -0 # PCI: fix irq routing on acer travelmate 360 laptop # # arch/i386/kernel/dmi_scan.c # 2004/06/05 00:16:53-07:00 daniel.ritz@gmx.ch +29 -0 # PCI: fix irq routing on acer travelmate 360 laptop # # ChangeSet # 2004/06/08 14:12:40-07:00 greg@kroah.com # Merge kroah.com:/home/greg/linux/BK/bleed-2.6 # into kroah.com:/home/greg/linux/BK/usb-2.6 # # include/linux/usb.h # 2004/06/08 14:12:36-07:00 greg@kroah.com +0 -1 # Auto merged # # drivers/usb/serial/cyberjack.c # 2004/06/08 14:12:36-07:00 greg@kroah.com +0 -6 # Auto merged # # drivers/usb/media/pwc-if.c # 2004/06/08 14:12:36-07:00 greg@kroah.com +0 -1 # Auto merged # # drivers/usb/media/Kconfig # 2004/06/08 14:12:35-07:00 greg@kroah.com +0 -1 # Auto merged # # drivers/usb/core/devio.c # 2004/06/08 14:12:35-07:00 greg@kroah.com +0 -1 # Auto merged # # ChangeSet # 2004/06/07 21:38:30-07:00 kaos@sgi.com # [PATCH] ia64: Rename SN "modules" variable to "sn_modules". # # SN code has a "modules" variable that conflicts with a variable of the # same name in kernel/module.c. This conflict breaks lcrash for ia64. # Rename "modules" to "sn_modules". # # Signed-off-by: Keith Owens # Signed-off-by: David Mosberger # # include/asm-ia64/sn/module.h # 2004/06/07 08:45:42-07:00 kaos@sgi.com +1 -1 # ia64: Rename modules to sn_modules # # arch/ia64/sn/io/sn2/module.c # 2004/06/07 08:45:32-07:00 kaos@sgi.com +7 -7 # ia64: Rename modules to sn_modules # # arch/ia64/sn/io/sn2/klgraph.c # 2004/06/07 08:49:25-07:00 kaos@sgi.com +2 -2 # ia64: Rename modules to sn_modules # # arch/ia64/sn/io/machvec/pci_bus_cvlink.c # 2004/06/07 08:45:20-07:00 kaos@sgi.com +2 -2 # ia64: Rename modules to sn_modules # # ChangeSet # 2004/06/07 17:01:22-07:00 david-b@pacbell.net # [PATCH] USB: rndis (4/4) start documenting spec variances # # This partially reverts one of the changes in an earlier patch, # starting to document where Microsoft's spec is lying. Needed # to interop with Windows ME. # # # The Windows ME implementation of RNDIS relies on a message that # Microsoft's specification says isn't used. Restore this (removed # in earlier cleanup), and start collecting comments specifically # on where MSFT violates its own specifications. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/rndis.c # 2004/06/07 07:04:50-07:00 david-b@pacbell.net +17 -0 # USB: rndis (4/4) start documenting spec variances # # ChangeSet # 2004/06/07 16:58:23-07:00 david-b@pacbell.net # [PATCH] USB: rndis (2/4) fix memory leaks # # Tao Huang wrote: # > I'm writing udc driver for S3C2410. I found RNDIS almost not call my # > driver's free_request and free_buffer. So after run my driver about 3 # > hours the system will out of memory. # > # > This patch will fix the memory leak. # > # > There will still have memory leak when driver unload, but I don't known # > where is the proper place to fix it. # > 1) rndis.c should free resp_queue when it unload # > 2) ether.c should free tx_reqs and rx_reqs when it unload (as # > eth_reset_config) # # Thanks ... this is a nice patch to have. # # # From: Tao Huang # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/ether.c # 2004/06/06 06:34:51-07:00 david-b@pacbell.net +13 -5 # USB: rndis (2/4) fix memory leaks # # ChangeSet # 2004/06/07 16:57:06-07:00 david-b@pacbell.net # [PATCH] USB: rndis (1/4) update OID support # # NDIS devices have a generic attribute get/set API where the attributes # are identified by 32 bit "OIDs". This fixes some problems with the OIDs # supported by the original RNDIS patch: # # - It included OIDs not found in the RNDIS spec. These have been # removed. As a rule, these weren't exported in the "OIDs I support" # list, and only a couple wouldn't fail those accesses, so this mostly # changes what debug printk appears. # # - OIDs used for optional 802.3 statistics were partially supported. # They're all in the OID list now, but the support is #ifdeffed out. # (Those statistics were mostly just made up, anyway!) # # - "Required" OIDs for suspend, resume, and wakeup support weren't # listed. Their messages are now defined, but support is #ifdeffed # out. Seems the docs aren't entirely accurate, and Windows can # behave reasonably without them. (This area needs help from someone # who knows MS-Windows power management.) # # There are also a few minor cleanups, more reasonable default volume level # for debug messages (never at KERN_INFO, keepalives only if VERBOSE), and # dumping of all bytes of some undocumented messages Windows XP has been # seen emitting shortly before the host suspended itself. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/rndis.h # 2004/06/06 06:06:42-07:00 david-b@pacbell.net +37 -4 # USB: rndis (1/4) update OID support # # drivers/usb/gadget/rndis.c # 2004/06/06 06:06:42-07:00 david-b@pacbell.net +162 -166 # USB: rndis (1/4) update OID support # # ChangeSet # 2004/06/07 16:55:44-07:00 stern@rowland.harvard.edu # [PATCH] USB: unusual_devs.h update # # Given the problems that Dan Scholnik has reported, we should combine the # unusual_devs.h entries for the Casio QV cameras into one. The new # NEED_OVERRIDE flag will prevent complaints about unnecessary overrides, # and Dan says the same subclass and protocol values should work for all the # cameras. If they don't we'll hear about it soon enough! # # # On Tue, 1 Jun 2004, Dan Scholnik wrote: # > On Tue, 2004-06-01 at 14:14, Alan Stern wrote: # > > On Tue, 1 Jun 2004, Dan Scholnik wrote: # > > # > > > Up until the 2.6 kernels, there was one entry for all the QV cameras # > > > with both US_SC_8070 and US_PR_CB that I think seemed to work fine for # > > > everyone. As far as I know the only problem was all the folks emailing # > > > the log entry stating that the Casio entry wasn't needed. So, you could # > > > revert back to that, or revert back to the 2.6.3ish version (pre-as190) # > > > that had the overrides just for product IDs 1001-9009. I'm not really # > > > an expert on Casio's cameras, I'm afraid, just the one model I own which # > > > is 4-5 years old now. # > > > # > > > I'll be happy to prepare a patch any way you choose to go. # > > # > > How does this work for you? # > > # > > Alan Stern # > # > Works fine for me; that's I think exactly how it was from the beginning # > until 2.6 and the later 2.4 kernels when all the changes were made. # > Just cross your fingers that it doesn't somehow break newer Casios, as # > it would seem every camera they ever made falls under that entry. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/06/01 05:46:58-07:00 stern@rowland.harvard.edu +3 -9 # USB: unusual_devs.h update # # ChangeSet # 2004/06/07 16:55:17-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix resource leakage in the hub driver # # The hub driver is very careless about returning resources when an error # occurs while installing a new device. This patch attempts to put some # order back into the situation. Details: # # Since usb_new_device() allocates neither the device structure # nor the device address, it shouldn't release either one. # # Because usb_new_device() no longer releases the device structure, # usb_register_root_hub() doesn't need to take an extra reference # to it. # # Since the device address selection and TT setup code is used # only for new devices, not ones being reset, move that code from # hub_port_init() to hub_port_connect_change(). By the same token, # hub_port_init() doesn't have to release the device address or # the device structure. # # Just to make things look better, move the failure code in # hub_port_init() to the end of the routine. And when disabling # endpoint 0, disable both the IN and OUT parts of the endpoint. # # In hub_port_connect_change(), make all the failure paths # execute the same code so that resources are always released. # These resources comprise: the pointer from the parent to the # new child device, the HCD state for ep0, the device's address, # and the device structure itself -- in short, everything that's # set up before calling usb_new_device(). # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/07 10:08:06-07:00 stern@rowland.harvard.edu +45 -50 # USB: Fix resource leakage in the hub driver # # drivers/usb/core/hcd.c # 2004/06/07 09:55:49-07:00 stern@rowland.harvard.edu +1 -3 # USB: Fix resource leakage in the hub driver # # ChangeSet # 2004/06/07 16:54:49-07:00 stern@rowland.harvard.edu # [PATCH] USB: Check port reset return code # # This patch adds checking for the SET-FEATURE request that actually does a # port reset. Without the check, the hub driver just assumes that the port # reset command actually was transferred okay. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/07 08:20:11-07:00 stern@rowland.harvard.edu +6 -2 # USB: Check port reset return code # # ChangeSet # 2004/06/07 16:34:04-07:00 baldrick@free.fr # [PATCH] USB devio.c: deadlock fix # # proc_resetdevice is called with dev->serialize held. # usb_reset_device takes dev->serialize and then calls # __usb_reset_device. To avoid deadlock, proc_resetdevice # should call __usb_reset_device directly. # # Signed-off-by: Duncan Sands # Signed-off-by: Greg Kroah-Hartman # # include/linux/usb.h # 2004/06/07 01:39:20-07:00 baldrick@free.fr +1 -0 # USB devio.c: deadlock fix # # drivers/usb/core/devio.c # 2004/06/07 01:39:20-07:00 baldrick@free.fr +1 -1 # USB devio.c: deadlock fix # # ChangeSet # 2004/06/07 14:39:16-07:00 arun.sharma@intel.com # [PATCH] ia64: fix ia32 virtual memory leaks due to partial-page mappings # # Certain IA-32 applications which do mmap/munmaps which are not # PAGE_SIZE aligned could see temporary (recovered at process exit time) # memory leaks, because the kernel didn't have enough data to decide if # the complete page could be unmapped. This patch adds a new data # structure called the "partial page list" which helps the kernel keep # track of precisely which 4k pages are in use by the IA-32 application. # # Armed with this data, the kernel can make better decisions at munmap # and mprotect time. No significant performance degradation was observed # in the workloads we tested and in some cases, the performance actually # improved! This is possibly due to the reduced length of the vma list. # # Signed-off-by: Arun Sharma # Signed-off-by: Gordon Jin # Signed-off-by: David Mosberger # # include/asm-ia64/processor.h # 2004/06/04 18:14:13-07:00 arun.sharma@intel.com +4 -1 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # include/asm-ia64/ia32.h # 2004/06/04 18:15:32-07:00 arun.sharma@intel.com +2 -0 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # arch/ia64/kernel/process.c # 2004/06/04 04:59:05-07:00 arun.sharma@intel.com +12 -0 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # arch/ia64/ia32/sys_ia32.c # 2004/06/04 06:31:39-07:00 arun.sharma@intel.com +524 -5 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # arch/ia64/ia32/ia32priv.h # 2004/06/04 03:42:27-07:00 arun.sharma@intel.com +25 -0 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # arch/ia64/ia32/ia32_support.c # 2004/06/04 02:57:01-07:00 arun.sharma@intel.com +8 -0 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # arch/ia64/ia32/ia32_entry.S # 2004/06/04 02:57:01-07:00 arun.sharma@intel.com +1 -1 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # arch/ia64/ia32/binfmt_elf32.c # 2004/06/04 02:57:01-07:00 arun.sharma@intel.com +4 -0 # ia64: fix virtual memory leaks in ia32 emulator due to partial-page mappings # # ChangeSet # 2004/06/07 13:00:07-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix logic in usb_get_descriptor() # # This patch fixes a simple logic error in usb_get_descriptor(). It also # takes the opportunity to make the subroutine a little easier to read. # Please apply. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/06/06 09:43:22-07:00 stern@rowland.harvard.edu +7 -7 # USB: Fix logic in usb_get_descriptor() # # ChangeSet # 2004/06/07 12:59:41-07:00 kaie@kuix.de # [PATCH] USB: enable pwc usb camera driver # # The attached patch enables the pwc driver included with kernel 2.6.7-rc2 # # It also removes the warnings during compilation. # However, note that I blindly duplicated the release approach used by # other usb camera drivers, replacing the current no-op. # # The driver works for me with a Logitech QuickCam Notebook Pro and # GnomeMeeting. # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/pwc-if.c # 2004/06/07 02:42:50-07:00 kaie@kuix.de +1 -8 # USB: enable pwc usb camera driver # # drivers/usb/media/Kconfig # 2004/06/07 02:27:03-07:00 kaie@kuix.de +1 -1 # USB: enable pwc usb camera driver # # ChangeSet # 2004/06/07 12:59:12-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: GetMaxLUN tightening # # This patch started life from Alan Stern as as274, and has been heavily # modified. It narrows the case where a clear_halt() is issued after a # failed GetMaxLUN command to only a STALL case. # # Since the only legimate responses to a GetMaxLUN are STALL or data, # anything else is now considered a fatal error and we give up on the device. # # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/usb.c # 2004/06/06 15:22:29-07:00 mdharm-usb@one-eyed-alien.net +8 -2 # USB Storage: GetMaxLUN tightening # # drivers/usb/storage/transport.c # 2004/06/06 15:22:29-07:00 mdharm-usb@one-eyed-alien.net +13 -10 # USB Storage: GetMaxLUN tightening # # ChangeSet # 2004/06/07 12:58:42-07:00 Siegfried.Hildebrand@FernUni-Hagen.de # [PATCH] Re: Problems with cyberjack usb-serial-module since kernel 2.6.2 # # > Send me a patch to back those changes out to fix your device and I'll # > apply it. If the author is around to realize this, that should wake # > them up :) # # Ok, here you are! :) # Attached is a patch for linux-2.6.7-rc2. (though the patch hasn't changed # since -rc1) # # Again a short description: # (the patch removes most of the changes done in linux-2.6.2) # 1. Removed the local buffer of cyberjack_write, because something goes wrong # upon a write-request bigger than the buffer. Without this, a write-request # stalls with error -3. # 2. Removed some usb_clear_halt() lines. Without this, the device doesn't even # open and returns -7. # # It works for my cyberjack pinpad USB card reader on # - nforce2 chipset # - VIA KM266 chipset # - AMD Irongate chipset # # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/cyberjack.c # 2004/06/06 09:25:11-07:00 Siegfried.Hildebrand@FernUni-Hagen.de +6 -15 # Re: Problems with cyberjack usb-serial-module since kernel 2.6.2 # # ChangeSet # 2004/06/07 11:44:48-07:00 alex.williamson@hp.com # [PATCH] ia64: delete McKinley A-stepping code # # The patch below removes the config option and one bit of code for # McKinley A0/A1 CPU workarounds. These CPUs were never used in # production, and IIRC this workaround really only affected X11. # # Signed-off-by: David Mosberger # # include/asm-ia64/pgtable.h # 2004/06/07 03:07:59-07:00 alex.williamson@hp.com +1 -5 # ia64: delete McKinley A-stepping code # # arch/ia64/Kconfig # 2004/06/07 03:03:19-07:00 alex.williamson@hp.com +0 -14 # ia64: delete McKinley A-stepping code # # ChangeSet # 2004/06/07 11:27:28-07:00 greg@kroah.com # USB: make usb devices remove their sysfs files when disconnected. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/usb.h # 2004/06/07 04:26:43-07:00 greg@kroah.com +2 -0 # USB: make usb devices remove their sysfs files when disconnected. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/sysfs.c # 2004/06/07 04:26:43-07:00 greg@kroah.com +59 -30 # USB: make usb devices remove their sysfs files when disconnected. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/06/07 04:26:43-07:00 greg@kroah.com +1 -0 # USB: make usb devices remove their sysfs files when disconnected. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/07 04:26:43-07:00 greg@kroah.com +1 -0 # USB: make usb devices remove their sysfs files when disconnected. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/07 10:30:35-07:00 greg@kroah.com # Merge kroah.com:/home/greg/linux/BK/bleed-2.6 # into kroah.com:/home/greg/linux/BK/usb-2.6 # # drivers/usb/gadget/ether.c # 2004/06/07 10:30:30-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/06/04 16:48:04-07:00 greg@kroah.com # Driver core: finally add a MAINTAINERS entry for it. # # Signed-off-by: Greg Kroah-Hartman # # MAINTAINERS # 2004/06/04 09:47:20-07:00 greg@kroah.com +6 -0 # Driver core: finally add a MAINTAINERS entry for it. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/04 15:54:01-07:00 corbet@lwn.net # [PATCH] Module section offsets in /sys/module # # So here I am trying to write about how one can apply gdb to a running # kernel, and I'd like to tell people how to debug loadable modules. Only # with the 2.6 module loader, there's no way to find out where the various # sections in the module image ended up, so you can't do much. This patch # attempts to fix that by adding a "sections" subdirectory to every module's # entry in /sys/module; each attribute in that directory associates a # beginning address with the section name. Those attributes can be used by a # a simple script to generate an add-symbol-file command for gdb, something # like: # # #!/bin/bash # # # # gdbline module image # # # # Outputs an add-symbol-file line suitable for pasting into gdb to examine # # a loaded module. # # # cd /sys/module/$1/sections # echo -n add-symbol-file $2 `/bin/cat .text` # # for section in .[a-z]* *; do # if [ $section != ".text" ]; then # echo " \\" # echo -n " -s" $section `/bin/cat $section` # fi # done # echo # # Currently, this feature is absent if CONFIG_KALLSYMS is not set. I do # wonder if CONFIG_DEBUG_INFO might not be a better choice, now that I think # about it. Section names are unmunged, so "ls -a" is needed to see most of # them. # # Signed-off-by: Greg Kroah-Hartman # # kernel/module.c # 2004/06/03 14:37:17-07:00 corbet@lwn.net +100 -0 # Module section offsets in /sys/module # # include/linux/module.h # 2004/06/03 14:01:29-07:00 corbet@lwn.net +19 -0 # Module section offsets in /sys/module # # ChangeSet # 2004/06/04 17:17:42-05:00 stern@rowland.harvard.edu # [PATCH] Make the scsi error handler bus settle delay a per template option # # On 1 Jun 2004, James Bottomley wrote: # > On Tue, 2004-06-01 at 15:29, Alan Stern wrote: # > > In addition, the settle-time delays would have to be removed from the # > > error handler -- which means adding it to all the low-level drivers. Is # > > that doable? # > # > Well, for 2.6, I think that a simple flag indicating that the driver # > will implement it's own timeout should suffice rather than altering # > every LLD... # # Signed-off-by: Alan Stern # Signed-off-by: James Bottomley # # include/scsi/scsi_host.h # 2004/06/04 11:51:31-05:00 stern@rowland.harvard.edu +5 -0 # Make the scsi error handler bus settle delay a per template option # # drivers/usb/storage/scsiglue.c # 2004/06/04 11:52:56-05:00 stern@rowland.harvard.edu +3 -0 # Make the scsi error handler bus settle delay a per template option # # drivers/scsi/scsi_error.c # 2004/06/04 11:54:06-05:00 stern@rowland.harvard.edu +4 -2 # Make the scsi error handler bus settle delay a per template option # # ChangeSet # 2004/06/04 15:15:08-07:00 stern@rowland.harvard.edu # [PATCH] USB: Genuine changes to hub_port_debounce() # # This patch includes the algorithmic changes I would like to see in # hub_port_debounce(). They are: # # Increase the total timeout period from 400 ms to 1500 ms. # # Check the port's connect-changed status during the polling # loop. # # Return as soon as the connection has been stable for the # required time, even if it has been stably _dis_-connected. # (The current code waits for the full timeout period if there # isn't a connection.) # # In previous emails I have responded to all the concerns raised by others # about these changes, and I can't imagine how they could cause any trouble. # # Increasing the total timeout won't affect people with properly # functioning hardware. Their connections will quickly stabilize # and the routine will return just as before. People with flaky # hardware that takes a long time to settle down will now be able # to use their devices. # # Checking the connect-changed status during the polling loop will # make the test more conservative. The code will be able to # detect transient disconnections that it would have missed # before, and it won't return until the connection really _is_ # stable. Furthermore, this makes the test compliant with the # USB specification, which requires the stability timer to be # restarted whenever a connection change occurs. # # Returning early for disconnections is a simple optimization. # It's more important now that the total timeout length is 1.5 # seconds rather than 0.4 seconds. # # I urge you to apply this patch and for people to try it out. If there do # turn out to be problems... the patch is very small, well-contained, and # easy to revert. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/04 07:28:00-07:00 stern@rowland.harvard.edu +4 -4 # USB: Genuine changes to hub_port_debounce() # # ChangeSet # 2004/06/04 15:14:42-07:00 stern@rowland.harvard.edu # [PATCH] USB: Superficial improvements to hub_port_debounce() # # Since my previous suggestions for changes to hub_port_debounce() # encountered so much resistance, this patch makes some fairly superficial # improvements to the code while leaving the logic of the algorithm almost # completely intact. The only behavioral change is that it actually # requests the port status at the start, rather than assuming the status is # not CONNECTED. Changes include: # # Vastly improved comments that are now unambiguous and accurately # descriptive of the code. # # Local variables changed to more sensible names. The stability # period is now reported in milliseconds rather than a meaningless # poll count. # # The sleep interval is moved from the start of the loop to the # end, so that the first time through we read the port status # immediately. # # If the connection has not stabilized after the total timeout # expires, -ETIMEDOUT is returned rather than whatever the # current connect status happens to be. # # If the connection does stabilize then the port status is returned # so that hub_port_connect_change() will have an up-to-date value # for the status rather than relying on the pre-debounce value. # # The changes I wanted to make but other people were worried about are # included as comments. A later (small) patch will uncomment them for # testing. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/04 07:15:37-07:00 stern@rowland.harvard.edu +34 -30 # USB: Superficial improvements to hub_port_debounce() # # ChangeSet # 2004/06/04 15:14:11-07:00 stern@rowland.harvard.edu # [PATCH] USB: Debounce all connect change events # # This patch makes the hub driver debounce all connection changes. Right # now the driver only does so if the status happens to be CONNECTED at one # particular instant. However, the whole point of debouncing is that the # connection is subject to transient interruptions until it has stabilized; # hence deciding whether to debounce based on a single initial test defeats # the entire purpose. # # There are some additional smaller changes that go along with the major # one: # # Comments added to hub_port_connect_change() detailing the # conditions under which it will be called. # # Don't clear the port's connect-changed feature if it wasn't # set. # # Skip debouncing if there wasn't a physical connection change # but only a logical port-enable change (or a firmware-download- # induced device morph -- not yet implemented). # # Clear all the hub status change indicators in hub_events() # before handling a connect change. This will reduce syslog # clutter from status change bits that remain set while khubd # is busy taking care of a new device. # # The patch includes no changes to the debounce routine itself. Please # apply. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/06/04 07:10:33-07:00 stern@rowland.harvard.edu +41 -22 # USB: Debounce all connect change events # # ChangeSet # 2004/06/04 15:13:47-07:00 stern@rowland.harvard.edu # [PATCH] USB: Code cleanup for the UHCI driver # # This patch makes some simple cleanups in the UHCI driver: # # It introduces msecs_to_jiffies() conversions and uses msleep(). # # It wakes up threads waiting for an endpoint to be disabled # in the oddball case where interrupts aren't working. (This # should have been in a previous patch but I missed it.) # # It disables PCI interrupt generation whenever the controller # is reset and enables it when the controller is started. This # may possibly solve some people's problems with suspend/resume. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/uhci-hcd.c # 2004/06/04 08:14:49-07:00 stern@rowland.harvard.edu +28 -17 # USB: Code cleanup for the UHCI driver # # ChangeSet # 2004/06/04 15:13:16-07:00 jnardelli@infosciences.com # [PATCH] USB: fix Memory leak in visor.c and ftdi_sio.c # # Signed-off-by: Joe Nardelli # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/visor.c # 2004/06/04 07:13:10-07:00 jnardelli@infosciences.com +1 -0 # USB: fix Memory leak in visor.c and ftdi_sio.c # # drivers/usb/serial/ftdi_sio.c # 2004/06/04 06:53:27-07:00 jnardelli@infosciences.com +1 -0 # USB: fix Memory leak in visor.c and ftdi_sio.c # # ChangeSet # 2004/06/04 15:12:44-07:00 spitalnik@penguin.cz # [PATCH] USB: pegasus driver and ATEN device support # # I have created a patch to add support for ATEN device in pegasus usb driver. # I've sent the patch to the maintainer stated in pegasus.h but after several # weeks I didn't recieve a response, so I'm sending it to you now. The patch # should apply cleanly on 2.6.6, but it doesn't apply cleanly on todays -bk as # there was some patch adding some other device. One thing I'm not 100% sure # are the flags specified to PEGASUS_DEV, what means HAS_HOME_PNA? # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/pegasus.h # 2004/04/15 14:37:12-07:00 spitalnik@penguin.cz +3 -0 # USB: pegasus driver and ATEN device support # # ChangeSet # 2004/06/04 15:01:07-07:00 dlsy@snoqualmie.dp.intel.com # [PATCH] Fixes for hot-plug drivers (updated) # # Here is the updated patch (against 2.6.7-rc1) for the shpchp and pciehp # drivers that fixes the following issues: # - proper LED status when latch is open or card is not present while the # user tries to power up the slot; (reported by D. Keck) # - check if kmalloc() return NULL before proceeding in acpi_get__hpp(); # (provided by L. Capitulino) # - add up(&ctrl->crit_sect) before return in error cases in several # places; # - proper handling of resources when there are other onboard devices # behind the p2p bridge that has the hot-plug capabaility; # - need to check negotiated link width in check_lnk_status(); # - cleanup board_added() in pciehp # # # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/hotplug/shpchprm_nonacpi.c # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +13 -5 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/shpchprm_acpi.c # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +17 -5 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/shpchp_pci.c # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +1 -0 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/shpchp_ctrl.c # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +23 -37 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/shpchp.h # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +1 -0 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/pciehprm_nonacpi.c # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +13 -5 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/pciehprm_acpi.c # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +17 -5 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/pciehp_hpc.c # 2004/06/02 11:59:48-07:00 dlsy@snoqualmie.dp.intel.com +3 -1 # Fixes for hot-plug drivers (updated) # # drivers/pci/hotplug/pciehp_ctrl.c # 2004/06/02 17:04:06-07:00 dlsy@snoqualmie.dp.intel.com +49 -98 # Fixes for hot-plug drivers (updated) # # ChangeSet # 2004/06/04 14:53:48-07:00 Frank.A.Uepping@t-online.de # [PATCH] Driver Core: fix struct device::release issue # # Signed-off-by: Greg Kroah-Hartman # # # On Saturday 27 March 2004 02:14, Greg KH wrote: # > On Sat, Mar 06, 2004 at 12:47:24PM +0100, Frank A. Uepping wrote: # > > Hi, # > > if device_add fails (e.g. bus_add_device returns an error) then the release # > > method will be called for the device. Is this a bug or a feature? # > # > Are you sure this will happen? device_initialize() gets a reference # > that is still present after device_add() fails, right? So release() # > will not get called. # At the label PMError, kobject_unregister is called, which decrements the # recount by 2, which will result in calling release at label Done (put_device). # # kobject_unregister should be superseded by kobject_del. # Here is a patch: # # drivers/base/core.c # 2004/03/27 07:04:27-08:00 Frank.A.Uepping@t-online.de +1 -1 # Driver Core: fix struct device::release issue # # ChangeSet # 2004/06/04 14:46:39-07:00 khali@linux-fr.org # [PATCH] I2C: update I2C IDs # # > > Greg, should I send a patch to you with these? # > # > Sure, if it's needed. # # Just noticed that I never sent the promised patch. Here it is. I also # added a few other IDs, since we have them in our (2.4) i2c CVS # repository. Having them in 2.6 as well will at least prevent collisions. # # Signed-off-by: Greg Kroah-Hartman # # include/linux/i2c-id.h # 2004/05/31 14:26:48-07:00 khali@linux-fr.org +12 -0 # I2C: update I2C IDs # # ChangeSet # 2004/06/04 14:45:53-07:00 vojtech@suse.cz # [PATCH] I2C i2c-piix: Don't treat ServerWorks servers as Laptops # # I'm sending you this little obvious patch which should enable i2c-piix # to work on IBM servers with ServerWorks chipsets. It still will treat # any IBM/Intel machine as a laptop and refuse to work, but it's better # than before. # # # i2c: Treat only IBM machines with Intel chipsets as IBM laptops. # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/busses/i2c-piix4.c # 2004/03/19 08:01:34-08:00 vojtech@suse.cz +1 -1 # I2C i2c-piix: Don't treat ServerWorks servers as Laptops # # ChangeSet # 2004/06/04 13:24:29-07:00 greg@kroah.com # PCI: convert to using dev_attrs for all PCI devices. # # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/pci.h # 2004/06/04 06:23:04-07:00 greg@kroah.com +1 -0 # PCI: convert to using dev_attrs for all PCI devices. # # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/pci-sysfs.c # 2004/06/04 06:23:04-07:00 greg@kroah.com +15 -18 # PCI: convert to using dev_attrs for all PCI devices. # # Signed-off-by: Greg Kroah-Hartman # # drivers/pci/pci-driver.c # 2004/06/04 06:23:04-07:00 greg@kroah.com +1 -0 # PCI: convert to using dev_attrs for all PCI devices. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/04 11:09:29-07:00 greg@kroah.com # Driver Model: And even more cleanup of silly scsi use of the *ATTR macros... # # Signed-off-by: Greg Kroah-Hartman # # drivers/scsi/scsi_transport_spi.c # 2004/06/04 04:08:48-07:00 greg@kroah.com +2 -2 # Driver Model: And even more cleanup of silly scsi use of the *ATTR macros... # # Signed-off-by: Greg Kroah-Hartman # # drivers/scsi/scsi_sysfs.c # 2004/06/04 04:08:48-07:00 greg@kroah.com +5 -5 # Driver Model: And even more cleanup of silly scsi use of the *ATTR macros... # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/04 11:55:11-05:00 jejb@mulgrave.(none) # sg update to 20040516 # # From: Douglas Gilbert # # Here are some further refinements to this patch with help # from Pat Mansfield: # - replace vmalloc() with kmalloc(,GFP_KERNEL) # - bump max sg devices from 8192 to 32768 # # Tested to 16k devices (and 8k devices on a box with 512MB # ram), Patch is against lk 2.6.6 (or 2.6.6-bk1). # # Signed-off-by: James Bottomley # # drivers/scsi/sg.c # 2004/06/04 11:54:42-05:00 jejb@mulgrave.(none) +22 -15 # sg update to 20040516 # # ChangeSet # 2004/06/04 09:13:16-05:00 hch@lst.de # [PATCH] kill dead compat code in advansys # # I actually wanted to fix up the check_region usage there but got lost # in the mess. Let's start by kicking out the 2.2 compat and using scsi # layer constants instead of their own redefinitions first. # # Signed-off-by: James Bottomley # # drivers/scsi/advansys.c # 2004/06/04 06:19:50-05:00 hch@lst.de +119 -508 # kill dead compat code in advansys # # ChangeSet # 2004/06/04 09:09:27-05:00 hch@lst.de # [PATCH] update 53c700 to avoid obsolete headers # # Signed-off-by: James Bottomley # # drivers/scsi/sim710.c # 2004/06/04 05:53:02-05:00 hch@lst.de +2 -3 # update 53c700 to avoid obsolete headers # # drivers/scsi/lasi700.c # 2004/06/04 05:53:02-05:00 hch@lst.de +1 -2 # update 53c700 to avoid obsolete headers # # drivers/scsi/NCR_D700.c # 2004/06/04 06:45:28-05:00 hch@lst.de +1 -3 # update 53c700 to avoid obsolete headers # # drivers/scsi/53c700.h # 2004/06/04 06:43:36-05:00 hch@lst.de +13 -10 # update 53c700 to avoid obsolete headers # # drivers/scsi/53c700.c # 2004/06/04 06:43:46-05:00 hch@lst.de +65 -64 # update 53c700 to avoid obsolete headers # # ChangeSet # 2004/06/04 08:59:37-05:00 hch@lst.de # [PATCH] missing forward declarations in scsi_eh.h # # Signed-off-by: James Bottomley # # include/scsi/scsi_eh.h # 2004/06/04 06:45:01-05:00 hch@lst.de +4 -0 # missing forward declarations in scsi_eh.h # # ChangeSet # 2004/06/03 21:54:17-05:00 akpm@osdl.org # [PATCH] 3ware 9000 schedule_timeout fix # # From: "Adam Radford" # # This small patch fixes the broken schedule_timeout() usage in the 3w-9xxx # driver, and replaces the calls with msleep(). # # Signed-off-by: Andrew Morton # Signed-off-by: James Bottomley # # drivers/scsi/3w-9xxx.c # 2004/06/03 19:43:06-05:00 akpm@osdl.org +4 -3 # 3ware 9000 schedule_timeout fix # # ChangeSet # 2004/06/03 21:51:02-05:00 akpm@osdl.org # [PATCH] 3ware 9000 driver update # # From: "Adam Radford" # # This patch updates the 3w-9xxx driver in 2.6.7-rc2-mm1 to v2.26.02.000 to # cleanup several things pointed out by Chris Hellwig / Jeff Garzik. # # Changes in this release: # - Use descriptive defines for phase numbers. # - Remove un-needed casts for TW_Command_Full # - Rework eh_reset(), eh_abort() spinlocks. # - Remove all mdelays, replace w/ schedule_timeout(). # - Remove MODULE_PARAM cmds_per_lun, add sysfs device attribute 'queue_depth'. # - Remove twa_slave_configure(). # - Remove twa_info(). # - Remove all bitfields from structures, add bitmask macros. # - Remove twa_setup_irq() wrapper, call directly. # - Remove un-needed prototypes. # - Propogate return value of pci_enable_device(), pci_set_dma_mask(), ioremap(). # - Use pci_request/free_regions(). # - Add missing call to pci_disable_device() on probe failure. # - Unregister character ioctl interface in twa_remove(). # - Make some excessively lengthy lines < 80 columns. # - Use pci_module_init() instead of pci_register_driver(). # - Remove bogus TW_IN_INTR check, fix twa_interrupt() spinlock. # - Rev driver branch to .02 to denote kernel version. # # Signed-off-by: Andrew Morton # Signed-off-by: James Bottomley # # drivers/scsi/3w-9xxx.h # 2004/06/03 21:44:23-05:00 akpm@osdl.org +31 -53 # 3ware 9000 driver update # # drivers/scsi/3w-9xxx.c # 2004/06/03 21:44:23-05:00 akpm@osdl.org +167 -159 # 3ware 9000 driver update # # ChangeSet # 2004/06/03 20:12:20-05:00 arjanv@redhat.com # [PATCH] SCSI: replace deprecated hosts.h file # # Signed-off-by: James Bottomley # # drivers/scsi/zalon.c # 2004/05/12 10:46:24-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/wd7000.c # 2004/05/12 10:46:24-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/wd33c93.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/ultrastor.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/u14-34f.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/tmscsim.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/t128.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sym53c416.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sun3x_esp.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sun3_scsi_vme.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sun3_scsi.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/st.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sr_vendor.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sr_ioctl.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sr.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sim710.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sgiwd93.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sg.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/seagate.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/sd.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/scsicam.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/scsi_pc98.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/scsi_module.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/scsi_ioctl.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/scsi_error.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/scsi_devinfo.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/scsi_debug.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/qlogicpti.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/qlogicisp.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/qlogicfc.c # 2004/05/12 10:46:23-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/qlogicfas408.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/qlogicfas.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/qla2xxx/qla_os.h # 2004/05/12 10:46:27-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/qla1280.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/psi240i.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/ppa.h # 2004/05/12 10:46:24-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pluto.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pcmcia/qlogic_stub.c # 2004/05/12 10:46:25-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pcmcia/fdomain_stub.c # 2004/05/12 10:46:25-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pcmcia/aha152x_stub.c # 2004/05/12 10:46:25-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pci2220i.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pci2000.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pc980155.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/pas16.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/osst.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/oktagon_esp.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/nsp32.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/ncr53c8xx.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/mvme16x.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/mvme147.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/megaraid.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/mca_53c9x.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/mac_scsi.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/mac_esp.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/lasi700.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/jazz_esp.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/ips.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/ini9100u.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/in2000.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/imm.h # 2004/05/12 10:46:24-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/ide-scsi.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/ibmmca.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/i60uscsi.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/gvp11.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/g_NCR5380.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/fdomain.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/fd_mcs.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/fcal.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/fastlane.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/esp.c # 2004/05/12 10:46:21-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/eata_pio.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/eata.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/dtc.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/dmx3191d.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/dec_esp.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/dc395x.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/cyberstormII.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/cyberstorm.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/cpqfcTSworker.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/cpqfcTSinit.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +2 -2 # SCSI: replace deprecated hosts.h file # # drivers/scsi/cpqfcTScontrol.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/constants.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/bvme6000.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/blz2060.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/blz1230.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/atp870u.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/atari_scsi.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/amiga7xx.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/aic7xxx_old.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/aic7xxx/aiclib.c # 2004/05/12 10:46:25-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/aic7xxx/aic7xxx_osm.h # 2004/05/12 10:46:27-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/aic7xxx/aic79xx_osm.h # 2004/05/12 10:46:27-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/aha1740.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/aha1542.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/advansys.c # 2004/05/12 10:46:19-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/a3000.c # 2004/05/12 10:46:19-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/a2091.c # 2004/05/12 10:46:19-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/NCR_Q720.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/NCR_D700.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/NCR53c406a.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/NCR53C9x.c # 2004/05/12 10:46:22-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/BusLogic.c # 2004/05/12 10:46:20-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/53c7xx.c # 2004/05/12 10:46:19-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/53c700.c # 2004/05/12 10:46:19-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # drivers/scsi/3w-xxxx.c # 2004/05/12 10:46:19-05:00 arjanv@redhat.com +1 -1 # SCSI: replace deprecated hosts.h file # # ChangeSet # 2004/06/03 20:07:56-05:00 akpm@osdl.org # [PATCH] scsi_transport_spi.c build fix # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_transport_spi.c # 2004/06/03 11:23:05-05:00 akpm@osdl.org +1 -1 # scsi_transport_spi.c build fix # # ChangeSet # 2004/06/03 20:06:32-05:00 akpm@osdl.org # [PATCH] Lost 2.4 change for BusLogic info # # From: Alan Cox # # I think it might be a good thing if this was fixed to match 2.4 # # Signed-off-by: Andrew Morton # Signed-off-by: James Bottomley # # drivers/scsi/Kconfig # 2004/06/03 01:56:10-05:00 akpm@osdl.org +1 -3 # Lost 2.4 change for BusLogic info # # ChangeSet # 2004/06/03 20:05:10-05:00 hch@lst.de # [PATCH] scsi_dev_flags must be __initdata, not __init # # __init is only for functions # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_devinfo.c # 2004/05/31 16:05:51-05:00 hch@lst.de +1 -1 # scsi_dev_flags must be __initdata, not __init # # ChangeSet # 2004/06/03 20:03:33-05:00 rddunlap@osdl.org # [PATCH] fix check_region usage in eata_pio # # Based on "eata_generic.h", this SCSI controller has 9 bytes of IO # space, not 8, so update request_region(), release_region(), and # n_io_port to use 9 instead of 8. # # diffstat:= # drivers/scsi/eata_pio.c | 16 ++++++++-------- # 1 files changed, 8 insertions(+), 8 deletions(-) # # Signed-off-by: James Bottomley # # drivers/scsi/eata_pio.c # 2004/06/01 17:29:30-05:00 rddunlap@osdl.org +8 -8 # fix check_region usage in eata_pio # # ChangeSet # 2004/06/03 20:01:03-05:00 James.Bottomley@steeleye.com # [PATCH] Advansys: Add basic highmem/DMA support # # On Wed, 2004-05-19 at 05:38, Herbert Xu wrote: # > This is a resend of my patch that adds basic support for highmem # > on i386 to the advansys driver. It has been tested in # > http://bugs.debian.org/245238. # > # > The maintainer email address listed in the MAINTAINERS file bounced # > so someone else will need to look at this. # # I converted your patch to use the DMA-API. This will be necessary to # use the EISA advansys boards---Of course, EISA won't work properly until # the entire driver is converted to the driverfs probing API, sigh, but # I'll get around to that eventually. # # OK, and I couldn't resist getting rid of the stupid in_isr locking on # the done function. # # Converted from original patch by Herbert Xu # Signed-off-by: James Bottomley # # drivers/scsi/advansys.c # 2004/05/31 12:14:32-05:00 James.Bottomley@steeleye.com +95 -50 # Add basic highmem/DMA support # # ChangeSet # 2004/06/03 19:59:37-05:00 hch@lst.de # [PATCH] remove obsolete API usage from dpt_i2o # # Signed-off-by: James Bottomley # # drivers/scsi/dpti.h # 2004/05/31 08:34:32-05:00 hch@lst.de +12 -12 # remove obsolete API usage from dpt_i2o # # drivers/scsi/dpt_i2o.c # 2004/05/31 08:35:50-05:00 hch@lst.de +28 -25 # remove obsolete API usage from dpt_i2o # # ChangeSet # 2004/06/03 19:58:15-05:00 hch@lst.de # [PATCH] fix sym53c416 check_region usage # # again, the init code could use some bigger rework, but let's stick to # the minimal fix until we have some testers. # # Signed-off-by: James Bottomley # # drivers/scsi/sym53c416.c # 2004/05/31 07:18:12-05:00 hch@lst.de +41 -42 # fix sym53c416 check_region usage # # ChangeSet # 2004/06/03 19:56:47-05:00 hch@lst.de # [PATCH] fix check_region usage in eata_pio # # I'd love to rework the init sequence a bit more, but without beeing able # to actually test the driver I'd rather stick to the bulletproof fix. # # Signed-off-by: James Bottomley # # drivers/scsi/eata_pio.c # 2004/05/31 06:30:48-05:00 hch@lst.de +58 -44 # fix check_region usage in eata_pio # # ChangeSet # 2004/06/03 19:55:15-05:00 hch@lst.de # [PATCH] handle NO_SENSE in sd # # Original patch from # http://marc.theaimsgroup.com/?l=linux-scsi&m=107428662718579&w=2 # reworked to according to James' suggestion to handle NO_SENSE the same # as RECOVERED_ERROR. # # Signed-off-by: James Bottomley # # drivers/scsi/sd.c # 2004/05/31 05:53:01-05:00 hch@lst.de +4 -4 # handle NO_SENSE in sd # # ChangeSet # 2004/06/03 19:53:41-05:00 hch@lst.de # [PATCH] remove sleep_on_timeout usage in megaraid # # megaraid does sleep_on_timeout on a stack waitq - use msleep instead. # # Signed-off-by: James Bottomley # # drivers/scsi/megaraid.c # 2004/05/30 08:04:14-05:00 hch@lst.de +3 -6 # remove sleep_on_timeout usage in megaraid # # ChangeSet # 2004/06/03 19:52:05-05:00 g.liakhovetski@gmx.de # [PATCH] tmscsim: Store pDCB in device->hostdata # # On Sun, 23 May 2004, Christoph Hellwig wrote: # > The other thing is that most calls to dc390_findDCB could probably be # > replaced with stroing the pDCB in scsi_device->hostdata on slave_alloc, # > but that could aswell be done in an incremental patch. # # Done in the attached patch. Tested as usual and a bit harder. # # Signed-off-by: James Bottomley # # drivers/scsi/tmscsim.c # 2004/05/28 18:17:17-05:00 g.liakhovetski@gmx.de +8 -10 # tmscsim: Store pDCB in device->hostdata # # ChangeSet # 2004/06/03 19:50:16-05:00 hch@lst.de # [PATCH] fix dpt_i2o compilation for alpha and sparc # # This patch has been floating around for ages, got reminded of it again # when looking at the debian kernel package. # # Signed-off-by: James Bottomley # # drivers/scsi/dpt_i2o.c # 2004/05/10 07:21:38-05:00 hch@lst.de +2 -2 # fix dpt_i2o compilation for alpha and sparc # # ChangeSet # 2004/06/03 20:43:58-04:00 len.brown@intel.com # [ACPI] acpi=force overrides blacklist pci=noacpi or acpi=noirq (Andi Kleen) # # arch/i386/kernel/dmi_scan.c # 2004/06/03 20:43:48-04:00 len.brown@intel.com +12 -6 # acpi=force overrides blacklist pci=noacpi or acpi=noirq (Andi Kleen) # # ChangeSet # 2004/06/03 19:41:12-05:00 aradford@amcc.com # [PATCH] 2/2 3ware 9000 SATA-RAID driver v2.26.00.009 # # Signed-off-by: James Bottomley # # include/linux/pci_ids.h # 2004/05/21 17:33:51-05:00 aradford@amcc.com +2 -0 # 3ware 9000 SATA-RAID driver v2.26.00.009 # # drivers/scsi/Makefile # 2004/05/21 17:24:55-05:00 aradford@amcc.com +1 -0 # 3ware 9000 SATA-RAID driver v2.26.00.009 # # drivers/scsi/Kconfig # 2004/05/21 18:29:59-05:00 aradford@amcc.com +12 -1 # 3ware 9000 SATA-RAID driver v2.26.00.009 # # drivers/scsi/3w-9xxx.h # 2004/05/26 15:17:26-05:00 aradford@amcc.com +726 -0 # 3ware 9000 SATA-RAID driver v2.26.00.009 # # MAINTAINERS # 2004/05/21 17:56:25-05:00 aradford@amcc.com +14 -0 # 3ware 9000 SATA-RAID driver v2.26.00.009 # # drivers/scsi/3w-9xxx.h # 2004/05/26 15:17:26-05:00 aradford@amcc.com +0 -0 # BitKeeper file /home/jejb/BK/scsi-misc-2.6/drivers/scsi/3w-9xxx.h # # ChangeSet # 2004/06/03 19:39:01-05:00 aradford@amcc.com # [PATCH] 1/2 3ware 9000 SATA-RAID driver v2.26.00.009 # # Here is an updated version v2.26.00.009 of the 3ware 9000 SATA-RAID driver. # # Changes in this release: # - Convert driver to pci_driver format. # - Remove proc interface, add sysfs attributes. # - Return SCSI_MLQUEUE_HOST_BUSY when card status is busy. # # Future versions may include: # - PAE fix # - 80 column wrap fixes # - Remove more prototypes by re-ordering functions. # - sysfs queue depth adjustment instead of module_param # # Signed-off-by: James Bottomley # # drivers/scsi/3w-9xxx.c # 2004/05/26 15:17:24-05:00 aradford@amcc.com +2144 -0 # 3ware 9000 SATA-RAID driver v2.26.00.009 # # drivers/scsi/3w-9xxx.c # 2004/05/26 15:17:24-05:00 aradford@amcc.com +0 -0 # BitKeeper file /home/jejb/BK/scsi-misc-2.6/drivers/scsi/3w-9xxx.c # # ChangeSet # 2004/06/03 17:37:14-07:00 mochel@digitalimplant.org # [Driver Model] Add default device attributes to struct bus_type. # # - Add struct bus_type::dev_attrs, which is an array of device # attributes that are added to each device as they are registered. # # - Also make sure that we don't hang when removing bus attributes # if adding one failed.. # # include/linux/device.h # 2004/06/03 17:37:08-07:00 mochel@digitalimplant.org +1 -0 # [Driver Model] Add default device attributes to struct bus_type. # # drivers/base/bus.c # 2004/06/03 17:37:08-07:00 mochel@digitalimplant.org +35 -1 # [Driver Model] Add default device attributes to struct bus_type. # # ChangeSet # 2004/06/03 17:14:32-07:00 greg@kroah.com # USB: remove "devfs" message from kernel log for usb-serial driver # # No one uses devfs on 2.6 :) # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/bus.c # 2004/06/03 17:14:00-07:00 greg@kroah.com +2 -2 # USB: remove "devfs" message from kernel log for usb-serial driver # # No one uses devfs on 2.6 :) # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/03 17:05:41-07:00 mochel@digitalimplant.org # [Driver Model] Add default attributes for struct bus_type. # # - Similar to default attributes for struct class, this is an array # of attributes, terminated with an attribute with a NULL name, that # are added when the bus is registered, and removed when the bus is # unregistered. # # include/linux/device.h # 2004/06/03 17:05:35-07:00 mochel@digitalimplant.org +2 -0 # [Driver Model] Add default attributes for struct bus_type. # # drivers/base/bus.c # 2004/06/03 17:05:35-07:00 mochel@digitalimplant.org +37 -0 # [Driver Model] Add default attributes for struct bus_type. # # ChangeSet # 2004/06/03 16:50:29-07:00 scott@concord.org # [PATCH] USB: kyocera 7135 patch # # Here is a patch based on 2.6.7-rc2 that makes the Kyocera 7135 work. # The Kyocera appears to have the same setup as the Trio. Its endpoints # are laid out like this: # # > >>>type address # > >>>usb bulk out: 0x01 # > >>>usb interrupt in: 0x82 # > >>>usb bulk out: 0x03 # > >>>usb bulk in: 0x84 # The last two are the ones used for the syncing communication. # # So the patch adds the ids for the kyocera and makes the treo_attach # function handle the kyocera too. I also changed the comment; it appears # there was an error in the original comment about the treo: # # Joe Nardelli wrote: # > Actually, the comment isn't quite right for Treos either (oops). It # > should read: # > # > ... # > 1st bulk in endpoint to communicate with the 2nd bulk out endpoint # > ... # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/visor.h # 2004/06/02 07:09:27-07:00 scott@concord.org +3 -0 # USB: kyocera 7135 patch # # drivers/usb/serial/visor.c # 2004/06/02 10:03:04-07:00 scott@concord.org +11 -7 # USB: kyocera 7135 patch # # ChangeSet # 2004/06/03 16:49:51-07:00 stern@rowland.harvard.edu # [PATCH] USB: 2.6-BK usb (printing) broken # # On Sat, 29 May 2004, Jens Axboe wrote: # # > > > Both 2.6.7-rc1 and BK current spit out a bunch of: # > > > # > > > drivers/usb/class/usblp.c: usblp1: nonzero read/write bulk status received: -2 # > > > drivers/usb/class/usblp.c: usblp1: error -2 reading from printer # > > > drivers/usb/class/usblp.c: usblp1: error -115 reading from printer # > > > drivers/usb/class/usblp.c: usblp1: error -115 reading from printer # > > > ... # > > > # > > > (about ~80 of that last line) but work for me. # # > Sorry wasn't quite clear - the above messages are with 2.6.7-rc1 and # > current bk with your patch backed out. Current bk with the patch reports # > only the timeouts I originally listed. # # Okay, I feel better. # # It looks like those errors you see are caused by a bug in the usblp # driver. The patch below ought to help. # # drivers/usb/class/usblp.c # 2004/05/29 07:25:51-07:00 stern@rowland.harvard.edu +1 -0 # USB: 2.6-BK usb (printing) broken # # ChangeSet # 2004/06/03 12:38:31-07:00 hannal@us.ibm.com # [PATCH] Add class support to cpuid.c # # This patch adds class support to arch/i386/kernel/cpuid.c. This enables udev # support. I have tested on a 2-way SMP system and on a 2-way built as UP. # Here are the results for the SMP: # # [hlinder@w-hlinder2 hlinder]$ tree /sys/class/cpuid # /sys/class/cpuid # |-- cpu0 # | `-- dev # `-- cpu1 # `-- dev # # 2 directories, 2 files # [hlinder@w-hlinder2 hlinder]$ more /sys/class/cpuid/cpu0/dev # 203:0 # [hlinder@w-hlinder2 hlinder]$ more /sys/class/cpuid/cpu1/dev # 203:1 # [hlinder@w-hlinder2 hlinder]$ # # And for the UP: # # [root@w-hlinder2 root]# tree /sys/class/cpuid # /sys/class/cpuid # `-- cpu0 # `-- dev # # 1 directory, 1 file # # # Signed-off-by: Greg Kroah-Hartman # # arch/i386/kernel/cpuid.c # 2004/06/02 14:22:27-07:00 hannal@us.ibm.com +36 -2 # Add class support to cpuid.c # # ChangeSet # 2004/06/03 12:06:36-07:00 greg@kroah.com # Cset exclude: vojtech@suse.cz|ChangeSet|20040602201956|45549 # # Oops, this broke device removal pretty badly :( # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/transport.c # 2004/06/03 12:06:28-07:00 greg@kroah.com +0 -0 # Exclude # # drivers/usb/storage/isd200.c # 2004/06/03 12:06:28-07:00 greg@kroah.com +0 -0 # Exclude # # ChangeSet # 2004/06/03 11:42:20-07:00 greg@kroah.com # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83l785ts.c # 2004/06/03 11:41:43-07:00 greg@kroah.com +2 -2 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83781d.c # 2004/06/03 11:41:44-07:00 greg@kroah.com +15 -15 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83627hf.c # 2004/06/03 11:41:43-07:00 greg@kroah.com +49 -49 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/via686a.c # 2004/06/03 11:41:44-07:00 greg@kroah.com +9 -9 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/lm85.c # 2004/06/03 11:41:43-07:00 greg@kroah.com +13 -13 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/lm78.c # 2004/06/03 11:41:43-07:00 greg@kroah.com +11 -11 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/it87.c # 2004/06/03 11:41:44-07:00 greg@kroah.com +11 -11 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/asb100.c # 2004/06/03 11:41:43-07:00 greg@kroah.com +33 -33 # Driver Model: Cleanup the i2c driver silly use of the *ATTR macros which just broke # # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/03 11:40:44-07:00 greg@kroah.com # Driver Model: More cleanup of silly scsi use of the *ATTR macros... # # Signed-off-by: Greg Kroah-Hartman # # drivers/scsi/scsi_debug.c # 2004/06/03 11:40:14-07:00 greg@kroah.com +8 -8 # Driver Model: More cleanup of silly scsi use of the *ATTR macros... # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/03 10:41:29-07:00 mochel@digitalimplant.org # [Driver Model] Add default attributes for classes class devices. # # - add struct class::class_attrs, which is designed to point to an # array of class_attributes that are added when the class is registered # and removed when the class is unregistered. # This allows for more consolidated and cleaner definition of and # management of attributes. # # - Add struct class::class_dev_attrs to do something similarly for # class devices. Each class device that is registered with the class # gets that set of attributes added for them, and subsequently removed # when the device is unregistered. # # Each array depends on a terminating attribute with a NULL name. Hint: # use the new __ATTR_NULL macro to terminate it. # # include/linux/device.h # 2004/06/03 10:41:22-07:00 mochel@digitalimplant.org +3 -0 # [Driver Model] Add default attributes for classes class devices. # # ChangeSet # 2004/06/03 10:27:16-07:00 mochel@digitalimplant.org # [sysfs] Add attr_name() macro # # - Returns the name of an embedded attribute in a higher-level # attribute. # # ChangeSet # 2004/06/03 09:48:45-07:00 greg@kroah.com # Add basic sysfs support for raw devices # # This is needed by people who use udev and want raw devices. # SuSE is shipping with this patch. # # Signed-off-by: Greg Kroah-Hartman # # drivers/char/raw.c # 2004/06/03 09:48:22-07:00 greg@kroah.com +24 -1 # Add basic sysfs support for raw devices # # This is needed by people who use udev and want raw devices. # SuSE is shipping with this patch. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/03 08:44:34-07:00 mochel@digitalimplant.org # [Driver Model] Fix up silly scsi usage of DEVICE_ATTR() macros. # # - Hey, just because the macro incorrectly included a ';' doesn't mean # one shouldn't add one on their own.. (Or at least be consistent.) # # Signed-off-by: Greg Kroah-Hartman # # drivers/scsi/scsi_sysfs.c # 2004/06/03 08:44:27-07:00 mochel@digitalimplant.org +2 -2 # [Driver Model] Fix up silly scsi usage of DEVICE_ATTR() macros. # # ChangeSet # 2004/06/03 00:45:08-04:00 len.brown@intel.com # [ACPI] fix !CONFIG_PCI build (Bjorn Helgaas) # # include/linux/acpi.h # 2004/06/02 11:02:20-04:00 len.brown@intel.com +2 -2 # fix !CONFIG_PCI build (Bjorn Helgaas) # # arch/i386/kernel/acpi/boot.c # 2004/06/02 11:02:20-04:00 len.brown@intel.com +5 -4 # fix !CONFIG_PCI build (Bjorn Helgaas) # # ChangeSet # 2004/06/02 21:08:30-04:00 p.lavarre@ieee.org # [PATCH] ata_check_bmdma # # Move hand-coded BMDMA status check into separate function. # # drivers/scsi/libata-core.c # 2004/05/27 19:56:57-04:00 p.lavarre@ieee.org +18 -10 # ata_check_bmdma # # ChangeSet # 2004/06/02 17:10:52-07:00 mochel@digitalimplant.org # [Driver Model] Consolidate attribute definition macros # # - Create __ATTR(), __ATTR_RO(), and __ATTR_NULL macros to help define # attributes in a neat, short-hand form. # # - Apply these macros to the attribute definition in include/linux/device.h # # - Note: These can be used to more cleanly define attributes in your own # code. e.g: # # static struct device_attribute attrs[] = { # __ATTR_RO(foo), # __ATTR_RO(bar), # __ATTR(baz,0666,baz_show,baz_store), # __ATTR_NULL, # }; # # ...etc. # # Signed-off-by: Greg Kroah-Hartman # # include/linux/device.h # 2004/06/02 17:01:55-07:00 mochel@digitalimplant.org +6 -25 # [Driver Model] Consolidate object attribute definition. # # ChangeSet # 2004/06/02 14:07:26-07:00 stern@rowland.harvard.edu # [PATCH] USB: Move usb_new_device() et al. into hub.c # # This patch moves usb_new_device(), usb_disconnect(), usb_choose_address(), # and usb_release_address() from usb.c to hub.c. As a side benefit, # choose_address() and release_address() can now become static. The other # two can't, because they have to be exported for use by HCD's when # registering/unregistering root hubs. # # Some other features of the patch: # # The usb_snddefctrl() and usb_rcvdefctrl() macros have been # removed, since only one of them was used and only in one spot. # # The comment about configuration choice needing to interact with # hub power budgeting has been moved in accordance with David's # wish. usb_new_device() checks to make sure a configuration # could be chosen and logs a warning if no choice was made. # # Following Linus's preference, the #ifdef preprocessor stuff has # been removed from around the calls the show_string routine. It # is now defined as a non-inline routine when debugging is enabled # and as an inline no-op otherwise (the compiler will optimize # away the useless tests). # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/usb.c # 2004/06/01 09:54:17-07:00 stern@rowland.harvard.edu +0 -229 # USB: Move usb_new_device() et al. into hub.c # # drivers/usb/core/hub.c # 2004/06/01 09:54:17-07:00 stern@rowland.harvard.edu +231 -3 # USB: Move usb_new_device() et al. into hub.c # # drivers/usb/core/hcd.h # 2004/06/01 09:54:17-07:00 stern@rowland.harvard.edu +0 -7 # USB: Move usb_new_device() et al. into hub.c # # ChangeSet # 2004/06/02 14:06:55-07:00 stern@rowland.harvard.edu # [PATCH] USB: Minor cleanups for hub driver # # Greg: # # This patch takes care of some small miscellaneous items in hub.c: # # Move the definition of CONFIG to the right place; # # Print the proper value for submission status in the error log; # # Remove an unused list of all hubs; # # Remove some unneeded braces; # # Kill an accidentally-resurrected comment. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.h # 2004/06/01 09:31:11-07:00 stern@rowland.harvard.edu +0 -1 # USB: Minor cleanups for hub driver # # drivers/usb/core/hub.c # 2004/06/01 09:39:04-07:00 stern@rowland.harvard.edu +9 -25 # USB: Minor cleanups for hub driver # # ChangeSet # 2004/06/02 13:55:44-07:00 oliver@neukum.org # [PATCH] USB: fix race between disconnect and write of acm driver # # acm uses a workqueue to defer part of a write operation. # In case of disconnect this work must be waited for. # - fix race between write and disconnect # # Signed-off-by: Oliver Neukum # Signed-off-by: Vojtech Pavlik # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.c # 2004/05/31 08:13:14-07:00 oliver@neukum.org +2 -0 # USB: fix race between disconnect and write of acm driver # # ChangeSet # 2004/06/02 13:49:28-07:00 oliver@neukum.org # [PATCH] USB: fix racy access to urb->status in cdc acm driver # # Hi, # # fix access to urb->status by introduction of an explicit flag # for finished data transfer. # - fix racy access to urb->status # # Signed-off-by: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.h # 2004/05/31 08:02:12-07:00 oliver@neukum.org +1 -0 # USB: fix racy access to urb->status in cdc acm driver # # drivers/usb/class/cdc-acm.c # 2004/05/31 08:02:12-07:00 oliver@neukum.org +10 -6 # USB: fix racy access to urb->status in cdc acm driver # # ChangeSet # 2004/06/02 13:36:24-07:00 oliver@neukum.org # [PATCH] USB: error handling of open of acm driver # # this adds error handling to the open method of the cdc acm driver. # The change set is relative to my last patch rewriting probe. # - add error handling to open method # # # Signed-off-by: Oliver Neukum # Signed-off-by: Vojtech Pavlik # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.c # 2004/05/31 06:54:36-07:00 oliver@neukum.org +23 -8 # USB: error handling of open of acm driver # # ChangeSet # 2004/06/02 13:31:54-07:00 oliver@neukum.org # [PATCH] USB: proper evaluation of the union descriptor for CDC ACM # # this changes acm_probe() to using the proper union descriptor. # It contains the workaround David suggested. Please apply. # # - fix probing to use cdc union descriptor # # Signed-off-by: Oliver Neukum # Signed-off-by: Vojtech Pavlik # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.c # 2004/05/30 03:56:45-07:00 oliver@neukum.org +100 -174 # USB: proper evaluation of the union descriptor for CDC ACM # # drivers/usb/class/cdc-acm.h # 2004/05/30 03:56:45-07:00 oliver@neukum.org +114 -0 # USB: proper evaluation of the union descriptor for CDC ACM # # drivers/usb/class/cdc-acm.h # 2004/05/30 03:56:45-07:00 oliver@neukum.org +0 -0 # BitKeeper file /home/greg/linux/BK/usb-2.6/drivers/usb/class/cdc-acm.h # # ChangeSet # 2004/06/02 13:25:59-07:00 david-b@pacbell.net # [PATCH] USB: usb retry cleanups # # This patch stops changing the reported fault mode in cases where retries of # GET_DESCRIPTOR fail because the device just doesn't have such a descriptor. # Plus, it stops printing messages when retrying. # # It also reduces the number of retries; the first retry seems to resolve most # of these firmware problems. # # Signed-Off-By: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/06/01 08:10:37-07:00 david-b@pacbell.net +1 -4 # USB: usb retry cleanups # # ChangeSet # 2004/06/02 13:25:08-07:00 david-b@pacbell.net # [PATCH] USB: pxa/rndis device descriptor # # This fixes a problem that all pxa2xx_udc g_ether devices # would run into. They'd give the wrong descriptors, like: # # > --------msg1- usbview ---------- # > Device Descriptor: bcdUSB: 0x0200 # > bDeviceClass: 0xFF # > bDeviceSubClass: 0x00 # > bDeviceProtocol: 0x00 # > bMaxPacketSize0: 0x10 (16) # # Windows doesn't like RNDIS-supporting devices to point # out that they're really vendor-specific. So this patch # makes sure they don't. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/ether.c # 2004/05/29 04:01:44-07:00 david-b@pacbell.net +10 -11 # USB: pxa/rndis device descriptor # # ChangeSet # 2004/06/02 13:19:23-07:00 numlock@freesurf.ch # [PATCH] Add support for ISD-300 controller # # This patch adds support in unusual_devs.h for the ISD-300 USB controller # used in CD-ROM enclosures. # # With it, since 2.6.0 it allowed me to move gigabytes of data and worked # without a hitch. # # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/05/25 20:32:24-07:00 numlock@freesurf.ch +6 -0 # Add support for ISD-300 controller # # ChangeSet # 2004/06/02 13:18:53-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix disconnect bug in dummy_hcd # # Greg: # # This patch fixes a bug in disconnect handling for the dummy_hcd driver. # After a disconnect the driver would still accept URBs for endpoint 0, # leading to an oops. It also improves the ad-hoc technique used by the # driver to track its gadget's struct usb_device and fixes the way # port-power changes are handled. Please apply. # # Alan Stern # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/dummy_hcd.c # 2004/05/17 10:12:20-07:00 stern@rowland.harvard.edu +11 -4 # USB: Fix disconnect bug in dummy_hcd # # ChangeSet # 2004/06/02 13:18:15-07:00 stern@rowland.harvard.edu # [PATCH] USB: unusual_devs.h update # # On Mon, 3 May 2004, zcat wrote: # # > I am trying to get my camera going as a webcam (concord EyeQ Duo in PC # > mode, not HDD mode) with the 2.6.4 kernel using the se401 driver # > (compiled in).. It logged the following message, which doesn't mean much # > to me so I have no idea if it's useful information or not; # > # > May 3 21:08:11 mrsnorris kernel: usb 1-1: new full speed USB device # > using address 2 # > May 3 21:08:16 mrsnorris kernel: usb 1-1: control timeout on ep0out # > May 3 21:08:16 mrsnorris kernel: usb-storage: This device # > (0595,4343,0100 S 00 P 00) has an unneeded Protocol entry in unusual_devs.h # > May 3 21:08:16 mrsnorris kernel: Please send a copy of this message # > to # # This fixes the "unneeded Protocol entry" message. We never solved the # control timeout problem. # # Alan Stern # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/05/03 04:15:35-07:00 stern@rowland.harvard.edu +1 -1 # USB: unusual_devs.h update # # ChangeSet # 2004/06/02 15:37:59-04:00 rl@hellgate.ch # [PATCH] Add rhine_power_init(): get power regs into sane state # # Add rhine_power_init(): get power regs into sane state. # Move the respective code out of rhine_init_one. Add code for # two additional patterns (Rhine III). # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +35 -20 # Add rhine_power_init(): get power regs into sane state # # ChangeSet # 2004/06/02 15:37:51-04:00 rl@hellgate.ch # [PATCH] Rewrite special-casing # # Use PCI revision to determine special cases. One bit field replaces a # bunch of data structures holding special case information. # # Replace chip_id, drv_flags in rhine_private with quirks # # Remove enum rhine_chips, struct rhine_chip_info (and array), # enum chip_capability_flags # # Add enum rhine_revs, enum rhine_quirks (some values in preparation for # subsequent changes) # # wait_for_reset() and enable_mmio() now use quirks instead of chip_id # # Remove model names from ident strings for now. # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +76 -58 # Rewrite special-casing # # ChangeSet # 2004/06/02 15:37:42-04:00 rl@hellgate.ch # [PATCH] Return codes for rhine_init_one # # Use return codes in rhine_init_one instead of -ENODEV for all errors. # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +15 -7 # Return codes for rhine_init_one # # ChangeSet # 2004/06/02 15:37:34-04:00 rl@hellgate.ch # [PATCH] Nuke all pci_flags # # All this code together can be replaced with a single #ifdef USE_MMIO. # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +11 -20 # Nuke all pci_flags # # ChangeSet # 2004/06/02 15:37:26-04:00 rl@hellgate.ch # [PATCH] Nuke default_port, references to if_port, medialock # # As is, code doesn't do anything useful. # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +0 -10 # Nuke default_port, references to if_port, medialock # # ChangeSet # 2004/06/02 15:37:18-04:00 rl@hellgate.ch # [PATCH] Nuke HasESIPhy and related code # # This has been dead code forever. # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +2 -3 # Nuke HasESIPhy and related code # # ChangeSet # 2004/06/02 15:37:09-04:00 rl@hellgate.ch # [PATCH] Nuke CanHaveMII and related code # # All Rhines can have a MII. # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +26 -40 # Nuke CanHaveMII and related code # # ChangeSet # 2004/06/02 15:37:01-04:00 rl@hellgate.ch # [PATCH] Nuke HAS_IP_COPYSUM # # HAS_IP_COPYSUM has been utterly meaningless for a long time. # # Signed-off-by: Roger Luethi # # drivers/net/via-rhine.c # 2004/06/01 20:00:00-04:00 rl@hellgate.ch +0 -5 # Nuke HAS_IP_COPYSUM # # ChangeSet # 2004/06/01 12:39:07-05:00 jejb@raven.il.steeleye.com # Merge # # drivers/scsi/sr_ioctl.c # 2004/06/01 12:38:49-05:00 jejb@raven.il.steeleye.com +0 -0 # SCCS merged # # drivers/scsi/sg.c # 2004/06/01 12:36:37-05:00 jejb@raven.il.steeleye.com +0 -0 # Auto merged # # drivers/scsi/scsi_devinfo.c # 2004/06/01 12:36:37-05:00 jejb@raven.il.steeleye.com +0 -0 # Auto merged # # drivers/scsi/constants.c # 2004/06/01 12:36:36-05:00 jejb@raven.il.steeleye.com +0 -0 # Auto merged # # ChangeSet # 2004/05/29 10:47:12-05:00 akpm@osdl.org # [PATCH] remove calls of obsolete scsi APIs in i2o_scsi # # From: Markus Lidel # # Here is a patch from Christoph Hellwig, which removes calls of the obsolete # scsi API in i2o_scsi. # # Signed-off-by: Andrew Morton # Signed-off-by: James Bottomley # # drivers/message/i2o/i2o_scsi.c # 2004/05/28 11:21:05-05:00 akpm@osdl.org +34 -57 # remove calls of obsolete scsi APIs in i2o_scsi # # ChangeSet # 2004/05/29 10:44:40-05:00 Markus.Lidel@shadowconnect.com # [PATCH] get I2O working with Adaptec's zero channel # # this patch now gets the mentioned controllers working with the I2O # subsystem. It tested on two different system with ASR-2005S and # ASR-2010S and reported as working. # # It's also tested on i686 and x86_64 with already working I2O controllers # without a problem. # # Signed-off-by: James Bottomley # # include/linux/i2o.h # 2004/05/24 18:53:22-05:00 Markus.Lidel@shadowconnect.com +9 -5 # get I2O working with Adaptec's zero channel # # drivers/message/i2o/i2o_scsi.c # 2004/05/24 18:56:46-05:00 Markus.Lidel@shadowconnect.com +3 -3 # get I2O working with Adaptec's zero channel # # drivers/message/i2o/i2o_core.c # 2004/05/24 19:07:35-05:00 Markus.Lidel@shadowconnect.com +104 -55 # get I2O working with Adaptec's zero channel # # drivers/message/i2o/i2o_config.c # 2004/05/24 16:57:44-05:00 Markus.Lidel@shadowconnect.com +1 -1 # get I2O working with Adaptec's zero channel # # drivers/message/i2o/i2o_block.c # 2004/05/24 18:56:06-05:00 Markus.Lidel@shadowconnect.com +4 -4 # get I2O working with Adaptec's zero channel # # ChangeSet # 2004/05/29 10:40:12-05:00 brking@us.ibm.com # [PATCH] ipr operational timeout oops # # This patch fixes an oops that can occur if an adapter times # out coming operational. # # Signed-off-by: James Bottomley # # drivers/scsi/ipr.h # 2004/05/26 22:30:13-05:00 brking@us.ibm.com +2 -2 # ipr operational timeout oops # # drivers/scsi/ipr.c # 2004/05/26 17:22:36-05:00 brking@us.ibm.com +1 -0 # ipr operational timeout oops # # ChangeSet # 2004/05/29 10:37:41-05:00 g.liakhovetski@gmx.de # [PATCH] tmscsim: convert to slave_... # # On Wed, 26 May 2004, Christoph Hellwig wrote: # > Looks like a way to go. I'm not sure what scan_device is supposed to # > do as I already wrote, but from looking at when it's set/cleared I'm # > pretty sure it tries to indicate whethere we're currently scanning for # > devices. And useing slave_alloc/slave_configure is a much safer way to # > find that out then guessing from the commands sent. # # Attached is a patch, that moves scan_device to # slave_alloc/_configure/_destroy, as you suggested (to be precise, as I # understood your suggestion:-)) # # Signed-off-by: James Bottomley # # drivers/scsi/tmscsim.h # 2004/05/27 17:52:39-05:00 g.liakhovetski@gmx.de +0 -2 # tmscsim: convert to slave_... # # drivers/scsi/tmscsim.c # 2004/05/27 17:57:12-05:00 g.liakhovetski@gmx.de +19 -14 # tmscsim: convert to slave_... # # drivers/scsi/scsiiom.c # 2004/05/27 17:32:23-05:00 g.liakhovetski@gmx.de +21 -41 # tmscsim: convert to slave_... # # drivers/scsi/dc390.h # 2004/05/27 17:57:23-05:00 g.liakhovetski@gmx.de +1 -13 # tmscsim: convert to slave_... # # ChangeSet # 2004/05/29 10:33:13-05:00 akpm@osdl.org # [PATCH] unchecked kmalloc in sr_audio_ioctl() # # From: "Luiz Fernando N. Capitulino" # # # Signed-off-by: Andrew Morton # Signed-off-by: James Bottomley # # drivers/scsi/sr_ioctl.c # 2004/05/26 11:03:15-05:00 akpm@osdl.org +3 -0 # unchecked kmalloc in sr_audio_ioctl() # # ChangeSet # 2004/05/29 10:31:04-05:00 g.liakhovetski@gmx.de # [PATCH] tmscsim: remove DeviceCnt # # On Wed, 26 May 2004, Christoph Hellwig wrote: # > On Sun, May 23, 2004 at 11:19:58PM +0200, Guennadi Liakhovetski wrote: # > > # > > Whereas, DCBCnt is incremented on slave_alloc, decremented on # > > slave_destroy and used in a couple more places. So, is it safe to assume # > > that DeviceCnt is redundant and remove it in a next patch?... Then it # > > might be already safe to move scan_devices as you suggest? # > # > Looks like a way to go. I'm not sure what scan_device is supposed to # > do as I already wrote, but from looking at when it's set/cleared I'm # > pretty sure it tries to indicate whethere we're currently scanning for # > devices. And useing slave_alloc/slave_configure is a much safer way to # > find that out then guessing from the commands sent. # # So, here's the first one - remove DeviceCnt. # # Signed-off-by: James Bottomley # # drivers/scsi/tmscsim.h # 2004/05/26 15:23:14-05:00 g.liakhovetski@gmx.de +2 -9 # tmscsim: remove DeviceCnt # # drivers/scsi/tmscsim.c # 2004/05/26 15:24:01-05:00 g.liakhovetski@gmx.de +1 -2 # tmscsim: remove DeviceCnt # # drivers/scsi/scsiiom.c # 2004/05/26 15:23:32-05:00 g.liakhovetski@gmx.de +0 -2 # tmscsim: remove DeviceCnt # # ChangeSet # 2004/05/29 10:28:07-05:00 g.liakhovetski@gmx.de # [PATCH] tmscsim: Update version after "new API" # # The "API-update" patch, just approved by Christoph deserves a new version. # # Signed-off-by: James Bottomley # # drivers/scsi/tmscsim.c # 2004/05/26 15:16:10-05:00 g.liakhovetski@gmx.de +2 -0 # tmscsim: Update version after "new API" # # drivers/scsi/dc390.h # 2004/05/26 15:16:08-05:00 g.liakhovetski@gmx.de +1 -1 # tmscsim: Update version after "new API" # # ChangeSet # 2004/05/29 10:24:44-05:00 davej@redhat.com # [PATCH] SCSI: Correct BELKIN card reader whitelist entry. # # Should be FORCELUN not SPARSELUN ? # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_devinfo.c # 2004/05/26 08:13:42-05:00 davej@redhat.com +1 -1 # SCSI: Correct BELKIN card reader whitelist entry. # # ChangeSet # 2004/05/29 10:22:47-05:00 davej@redhat.com # [PATCH] SCSI: more whitelist updates for usb card readers # # ATech 9-in-1 card reader. # Cbox 3 5 1/2 bay with 6in1 card reader # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_devinfo.c # 2004/05/26 07:44:43-05:00 davej@redhat.com +3 -0 # SCSI: more whitelist updates for usb card readers # # ChangeSet # 2004/05/29 10:20:15-05:00 akpm@osdl.org # [PATCH] Stop megaraid trashing other i960 based devices # # From: Alan Cox # # In 2.4 the megaraid driver was careful to avoid stepping on wrong devices. # Specifically the megaraid3 series devices used an intel pci ID (8086:1960) # which is the generic i960 identifier not their own. # # The code to do this in 2.4 worked for almost all cases, but even that code has # mysteriously vanished in 2.6 meaning the megaraid driver trashes stuff like # promise i2o cards and compaq management cards. # # The following patch puts back the 2.4 stuff + one additional check so that the # driver isn't quite as rude as it was before. # # Signed-off-by: James Bottomley # # drivers/scsi/megaraid.c # 2004/05/22 20:59:10-05:00 akpm@osdl.org +20 -0 # Stop megaraid trashing other i960 based devices # # ChangeSet # 2004/05/29 10:17:42-05:00 lcapitulino@prefeitura.sp.gov.br # [PATCH] qla1280.c warning fix. # # drivers/scsi/qla1280.c:3124: warning: `qla1280_64bit_start_scsi' defined but not used # # Signed-off-by: James Bottomley # # drivers/scsi/qla1280.c # 2004/04/13 12:56:24-05:00 lcapitulino@prefeitura.sp.gov.br +2 -2 # qla1280.c warning fix. # # ChangeSet # 2004/05/29 10:13:11-05:00 michaelc@cs.wisc.edu # [PATCH] SCSI: remove extra queue unplug calls # # blk_insert_request will do the right thing and either unplug the queue or # call the request_fn, so users of scsi_do_req do not need to call # generic_unplug_device themselves. The attached patch just removes that # call from scsi_lib.c and the sg driver after they do a scsi_do_req. # # Signed-off-by: James Bottomley # # drivers/scsi/sg.c # 2004/05/24 20:59:40-05:00 michaelc@cs.wisc.edu +0 -1 # SCSI: remove extra queue unplug calls # # drivers/scsi/scsi_lib.c # 2004/05/24 20:59:39-05:00 michaelc@cs.wisc.edu +0 -1 # SCSI: remove extra queue unplug calls # # ChangeSet # 2004/05/29 10:11:11-05:00 jejb@mulgrave.(none) # MPT Fusion driver 3.01.07 update # # From: "Moore, Eric Dean" # # Clean up backword compatibility with 2.4 kernel and older. Patch # provided by Christoph Hellwig # # Signed-off-by: James Bottomley # # drivers/message/fusion/mptscsih.h # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +0 -71 # MPT Fusion driver 3.01.07 update # # drivers/message/fusion/mptscsih.c # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +36 -37 # MPT Fusion driver 3.01.07 update # # drivers/message/fusion/mptlan.c # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +3 -16 # MPT Fusion driver 3.01.07 update # # drivers/message/fusion/mptctl.c # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +2 -66 # MPT Fusion driver 3.01.07 update # # drivers/message/fusion/mptbase.h # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +7 -3 # MPT Fusion driver 3.01.07 update # # drivers/message/fusion/mptbase.c # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +10 -8 # MPT Fusion driver 3.01.07 update # # drivers/message/fusion/linux_compat.h # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +0 -189 # MPT Fusion driver 3.01.07 update # # drivers/message/fusion/isense.c # 2004/05/29 10:10:51-05:00 jejb@mulgrave.(none) +0 -8 # MPT Fusion driver 3.01.07 update # # ChangeSet # 2004/05/29 10:06:35-05:00 davej@redhat.com # [PATCH] USB / SCSI multi-card reader whitelist updates. # # For more info see Red Hat bugzilla entries #85851 and #124048 # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_devinfo.c # 2004/05/04 11:44:37-05:00 davej@redhat.com +2 -0 # USB / SCSI multi-card reader whitelist updates. # # ChangeSet # 2004/05/29 10:04:10-05:00 brking@us.ibm.com # [PATCH] ipr driver version 2.0.8 # # Bump driver version # # Signed-off-by: James Bottomley # # drivers/scsi/ipr.h # 2004/05/23 21:48:22-05:00 brking@us.ibm.com +2 -2 # ipr driver version 2.0.8 # # ChangeSet # 2004/05/29 10:01:45-05:00 brking@us.ibm.com # [PATCH] ipr duplicate ioa reset fix # # This patch closes a window where if a device had a cancel all # outstanding as a result of a check condition and the adapter # was reset for some reason, a request sense would still be issued, # which would end up timing out and issuing an additional adapter # reset. It could also result in a leak of command blocks, depending # on when it timed out. # # Signed-off-by: James Bottomley # # drivers/scsi/ipr.c # 2004/05/23 21:43:47-05:00 brking@us.ibm.com +6 -0 # ipr duplicate ioa reset fix # # ChangeSet # 2004/05/29 09:59:59-05:00 brking@us.ibm.com # [PATCH] ipr scsi busy io hang # # Signed-off-by: James Bottomley # # drivers/scsi/ipr.c # 2004/05/23 21:40:15-05:00 brking@us.ibm.com +5 -1 # ipr scsi busy io hang # # ChangeSet # 2004/05/29 09:59:10-05:00 jejb@mulgrave.(none) # Convert tmcscsim to new probing interfaces # # From: Guennadi Liakhovetski # # Update the driver to use the new pci, scsi and # module interfaces. # # Modified with feedback from hch # # Signed-off-by: James Bottomley # # drivers/scsi/tmscsim.c # 2004/05/29 09:58:54-05:00 jejb@mulgrave.(none) +151 -98 # Convert tmcscsim to new probing interfaces # # drivers/scsi/scsiiom.c # 2004/05/29 09:58:54-05:00 jejb@mulgrave.(none) +12 -26 # Convert tmcscsim to new probing interfaces # # drivers/scsi/dc390.h # 2004/05/29 09:58:54-05:00 jejb@mulgrave.(none) +0 -1 # Convert tmcscsim to new probing interfaces # # ChangeSet # 2004/05/29 09:55:10-05:00 jejb@mulgrave.(none) # SCSI: slave_detach -> slave_destory comment fix # # From: Guennadi Liakhovetski # # Signed-off-by: James Bottomley # # include/scsi/scsi_host.h # 2004/05/29 09:54:55-05:00 jejb@mulgrave.(none) +2 -2 # SCSI: slave_detach -> slave_destory comment fix # # ChangeSet # 2004/05/29 09:48:47-05:00 hch@lst.de # [PATCH] move scsi debugging helpers and give them sane names # # - give the constants.c prettyprinting helpers proper scsi_ prefixed # names (and keep compat versions for 2.6.x) # - move them to include/scsi/scsi_dbg.h so now really only legacy stuff # is left in drivers/scsi/scsi.h # # Signed-off-by: James Bottomley # # drivers/scsi/scsi_syms.c # 2004/05/19 12:46:14-05:00 hch@lst.de +6 -6 # move scsi debugging helpers and give them sane names # # drivers/scsi/scsi.h # 2004/05/19 12:46:14-05:00 hch@lst.de +42 -15 # move scsi debugging helpers and give them sane names # # drivers/scsi/constants.c # 2004/05/19 12:46:14-05:00 hch@lst.de +11 -11 # move scsi debugging helpers and give them sane names # # include/scsi/scsi_dbg.h # 2004/05/13 03:45:25-05:00 hch@lst.de +18 -0 # move scsi debugging helpers and give them sane names # # include/scsi/scsi_dbg.h # 2004/05/13 03:45:25-05:00 hch@lst.de +0 -0 # BitKeeper file /home/jejb/BK/scsi-misc-2.6/include/scsi/scsi_dbg.h # # ChangeSet # 2004/05/27 15:21:03-04:00 herbert@gondor.apana.org.au # [NETDRV #2] Use driver-specific name for resources # # Here is the next part which uses a driver-specific name instead of # dev->name for resource allocations prior to netdev registration. # It also changes printks that are in direct response to errors in # resource allocations. # # drivers/net/zorro8390.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/yellowfin.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/wd.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/sunhme.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/sungem.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/sun3_82586.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/stnic.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/starfire.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/smc9194.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +5 -3 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/smc-ultra32.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/smc-ultra.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/smc-mca.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/r8169.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/oaknet.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ns83820.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ni52.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ne3210.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +6 -4 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ne2k_cbus.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ne2.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ne.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ne-h8300.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/natsemi.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/lp486e.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/lne390.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +5 -3 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/jazzsonic.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ibmlana.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/hp.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +5 -3 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/hp-plus.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/forcedeth.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +2 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/fmv18x.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ewrk3.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +2 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/eth16i.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -4 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/eepro.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/e2100.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/defxx.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/cs89x0.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/at1700.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +5 -3 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/apne.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/acenic.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/ac3200.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +4 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/82596.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +3 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/3c527.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +2 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/3c523.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/3c507.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +2 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/3c503.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +2 -2 # 2/x: [NETDRV] Use driver-specific name for resources # # drivers/net/3c501.c # 2004/05/22 13:40:55-04:00 herbert@gondor.apana.org.au +1 -1 # 2/x: [NETDRV] Use driver-specific name for resources # # ChangeSet # 2004/05/27 15:20:53-04:00 herbert@gondor.apana.org.au # [NETDRV #1] Ifdef builtin-only probe in ISA/MCA drivers # # Here is the bit which conditionalises the # builtin-only probe functions. # # drivers/net/wd.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/smc-ultra.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/ne2k_cbus.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/ne2.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/ne.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/ne-h8300.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/lne390.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/lance.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/isa-skeleton.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/hp100.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/hp.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/hp-plus.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/ewrk3.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/eth16i.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/es3210.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/eexpress.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/eepro.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/e2100.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/cs89x0.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +1 -1 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/ac3200.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/3c523.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/3c505.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -1 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # drivers/net/3c503.c # 2004/05/20 17:16:23-04:00 herbert@gondor.apana.org.au +2 -0 # 1/x: [NETDRV] Ifdef builtin-only probe in ISA/MCA drivers # # ChangeSet # 2004/05/27 13:38:57-04:00 rl@hellgate.ch # [PATCH] Nuke HAS_IP_COPYSUM for net drivers # # Entirely untested, but Obviously Correct(TM). HAS_IP_COPYSUM has been # utterly meaningless for a long time. # # drivers/net/yellowfin.c # 2004/05/25 14:46:47-04:00 rl@hellgate.ch +0 -5 # Nuke HAS_IP_COPYSUM for net drivers # # drivers/net/tulip/winbond-840.c # 2004/05/25 14:46:26-04:00 rl@hellgate.ch +0 -6 # Nuke HAS_IP_COPYSUM for net drivers # # drivers/net/natsemi.c # 2004/05/25 14:51:58-04:00 rl@hellgate.ch +0 -5 # Nuke HAS_IP_COPYSUM for net drivers # # drivers/net/epic100.c # 2004/05/25 14:45:55-04:00 rl@hellgate.ch +0 -5 # Nuke HAS_IP_COPYSUM for net drivers # # ChangeSet # 2004/05/25 01:32:47-04:00 len.brown@intel.com # [ACPI] PCI IRQ update (Bjorn Helgaas) # http://bugme.osdl.org/show_bug.cgi?id=2574 # # mp_parse_prt() and iosapic_parse_prt() used to allocate all # IRQs, whether devices needed them or not. Some devices # failed because the this method enabled unused PCI Interrupt # Link Devices, which disrupted active link devices. # # Now the PRT knowledge is pulled out of the arch # code and the IRQ allocation and IO-APIC programming # is done by pci_enable_device(). # This is also a step toward allowing the addition # of new root bridges and PRTs at run-time. # # The architecture supplies # # unsigned int # acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) # # which is called by acpi_pci_irq_enable(). ACPI supplies # all the information from the PRT, and the arch sets up # the routing and returns the IRQ it allocated. # # include/linux/acpi.h # 2004/05/25 01:32:34-04:00 len.brown@intel.com +1 -1 # PCI IRQ update (Bjorn Helgaas) # # include/asm-x86_64/mpspec.h # 2004/05/25 01:32:34-04:00 len.brown@intel.com +1 -1 # PCI IRQ update (Bjorn Helgaas) # # include/asm-ia64/iosapic.h # 2004/05/25 01:32:34-04:00 len.brown@intel.com +0 -1 # PCI IRQ update (Bjorn Helgaas) # # include/asm-i386/mpspec.h # 2004/05/25 01:32:34-04:00 len.brown@intel.com +1 -1 # PCI IRQ update (Bjorn Helgaas) # # include/acpi/acpi_drivers.h # 2004/05/25 01:32:34-04:00 len.brown@intel.com +1 -1 # PCI IRQ update (Bjorn Helgaas) # # drivers/serial/8250_hcdp.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +4 -8 # PCI IRQ update (Bjorn Helgaas) # # drivers/serial/8250_acpi.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +6 -16 # PCI IRQ update (Bjorn Helgaas) # # drivers/acpi/tables.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +3 -3 # PCI IRQ update (Bjorn Helgaas) # # drivers/acpi/pci_link.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +2 -2 # PCI IRQ update (Bjorn Helgaas) # # drivers/acpi/pci_irq.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +36 -83 # PCI IRQ update (Bjorn Helgaas) # # arch/x86_64/kernel/mpparse.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +39 -76 # PCI IRQ update (Bjorn Helgaas) # # arch/ia64/pci/pci.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +12 -4 # PCI IRQ update (Bjorn Helgaas) # # arch/ia64/kernel/iosapic.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +80 -129 # PCI IRQ update (Bjorn Helgaas) # # arch/ia64/kernel/acpi.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +8 -15 # PCI IRQ update (Bjorn Helgaas) # # arch/i386/pci/acpi.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +23 -8 # PCI IRQ update (Bjorn Helgaas) # # arch/i386/kernel/mpparse.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +38 -78 # PCI IRQ update (Bjorn Helgaas) # # arch/i386/kernel/acpi/boot.c # 2004/05/25 01:32:34-04:00 len.brown@intel.com +28 -0 # PCI IRQ update (Bjorn Helgaas) # # ChangeSet # 2004/05/22 23:32:21-04:00 len.brown@intel.com # Kconfig typo fix from Jochen Voss # # drivers/acpi/Kconfig # 2004/04/05 06:54:30-04:00 len.brown@intel.com +1 -1 # Kconfig typo fix from Jochen Voss # diff -Nru a/CREDITS b/CREDITS --- a/CREDITS 2004-06-26 17:09:19 -07:00 +++ b/CREDITS 2004-06-26 17:09:19 -07:00 @@ -1060,6 +1060,12 @@ N: Jeff Garzik E: jgarzik@pobox.com +N: Kumar Gala +E: kumar.gala@freescale.com +D: Embedded PowerPC 6xx/7xx/74xx/82xx/85xx support +S: Austin, Texas 78729 +S: USA + N: Jacques Gelinas E: jacques@solucorp.qc.ca D: Author of the Umsdos file system @@ -2267,8 +2273,8 @@ N: Eberhard Moenkeberg E: emoenke@gwdg.de D: CDROM driver "sbpcd" (Matsushita/Panasonic/Soundblaster) -S: Reinholdstrasse 14 -S: D-37083 Goettingen +S: Ruhstrathoehe 2 b. +S: D-37085 Goettingen S: Germany N: Thomas Molina @@ -2571,6 +2577,14 @@ D: sonypi, meye drivers, mct_u232 usb serial hacks S: Paris, France +N: Matt Porter +E: mporter@kernel.crashing.org +D: Motorola PowerPC PReP support +D: cPCI PowerPC support +D: Embedded PowerPC 4xx/6xx/7xx/74xx support +S: Chandler, Arizona 85249 +S: USA + N: Frederic Potter E: fpotter@cirpack.com D: Some PCI kernel support @@ -3109,12 +3123,13 @@ S: USA N: Marcelo W. Tosatti -E: marcelo@conectiva.com.br -W: http://bazar.conectiva.com.br/~marcelo/ -D: Miscellaneous kernel hacker (mostly VM/MM work) -S: Conectiva S.A. -S: R. Tocantins, 89 - Cristo Rei -S: 80050-430 - Curitiba - Paraná +E: marcelo.tosatti@cyclades.com +D: Miscellaneous kernel hacker +D: v2.4 kernel maintainer +D: Current pc300/cyclades maintainer +S: Cyclades Corporation +S: Av Cristovao Colombo, 462. Floresta. +S: Porto Alegre S: Brazil N: Stefan Traby diff -Nru a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers --- a/Documentation/SubmittingDrivers 2004-06-26 17:09:19 -07:00 +++ b/Documentation/SubmittingDrivers 2004-06-26 17:09:19 -07:00 @@ -3,7 +3,8 @@ This document is intended to explain how to submit device drivers to the various kernel trees. Note that if you are interested in video card drivers -you should probably talk to XFree86 (http://www.xfree86.org) instead. +you should probably talk to XFree86 (http://www.xfree86.org/) and/or X.Org +(http://x.org/) instead. Also read the Documentation/SubmittingPatches document. diff -Nru a/Documentation/arm/Sharp-LH/SDRAM b/Documentation/arm/Sharp-LH/SDRAM --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/arm/Sharp-LH/SDRAM 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,51 @@ +README on the SDRAM Controller for the LH7a40X +============================================== + +The standard configuration for the SDRAM controller generates a sparse +memory array. The precise layout is determined by the SDRAM chips. A +default kernel configuration assembles the discontiguous memory +regions into separate memory nodes via the NUMA (Non-Uniform Memory +Architecture) facilities. In this default configuration, the kernel +is forgiving about the precise layout. As long as it is given an +accurate picture of available memory by the bootloader the kernel will +execute correctly. + +The SDRC supports a mode where some of the chip select lines are +swapped in order to make SDRAM look like a synchronous ROM. Setting +this bit means that the RAM will present as a contiguous array. Some +programmers prefer this to the discontiguous layout. Be aware that +may be a penalty for this feature where some some configurations of +memory are significantly reduced; i.e. 64MiB of RAM appears as only 32 +MiB. + +There are a couple of configuration options to override the default +behavior. When the SROMLL bit is set and memory appears as a +contiguous array, there is no reason to support NUMA. +CONFIG_LH7A40X_CONTIGMEM disables NUMA support. When physical memory +is discontiguous, the memory tables are organized such that there are +two banks per nodes with a small gap between them. This layout wastes +some kernel memory for page tables representing non-existent memory. +CONFIG_LH7A40X_ONE_BANK_PER_NODE optimizes the node tables such that +there are no gaps. These options control the low level organization +of the memory management tables in ways that may prevent the kernel +from booting or may cause the kernel to allocated excessively large +page tables. Be warned. Only change these options if you know what +you are doing. The default behavior is a reasonable compromise that +will suit all users. + +-- + +A typical 32MiB system with the default configuration options will +find physical memory managed as follows. + + node 0: 0xc0000000 4MiB + 0xc1000000 4MiB + node 1: 0xc4000000 4MiB + 0xc5000000 4MiB + node 2: 0xc8000000 4MiB + 0xc9000000 4MiB + node 3: 0xcc000000 4MiB + 0xcd000000 4MiB + +Setting CONFIG_LH7A40X_ONE_BANK_PER_NODE will put each bank into a +separate node. diff -Nru a/Documentation/arm/VFP/release-notes.txt b/Documentation/arm/VFP/release-notes.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/arm/VFP/release-notes.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,55 @@ +Release notes for Linux Kernel VFP support code +----------------------------------------------- + +Date: 20 May 2004 +Author: Russell King + +This is the first release of the Linux Kernel VFP support code. It +provides support for the exceptions bounced from VFP hardware found +on ARM926EJ-S. + +This release has been validated against the SoftFloat-2b library by +John R. Hauser using the TestFloat-2a test suite. Details of this +library and test suite can be found at: + + http://www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html + +The operations which have been tested with this package are: + + - fdiv + - fsub + - fadd + - fmul + - fcmp + - fcmpe + - fcvtd + - fcvts + - fsito + - ftosi + - fsqrt + +All the above pass softfloat tests with the following exceptions: + +- fadd/fsub shows some differences in the handling of +0 / -0 results + when input operands differ in signs. +- the handling of underflow exceptions is slightly different. If a + result underflows before rounding, but becomes a normalised number + after rounding, we do not signal an underflow exception. + +Other operations which have been tested by basic assembly-only tests +are: + + - fcpy + - fabs + - fneg + - ftoui + - ftosiz + - ftouiz + +The combination operations have not been tested: + + - fmac + - fnmac + - fmsc + - fnmsc + - fnmul diff -Nru a/Documentation/as-iosched.txt b/Documentation/as-iosched.txt --- a/Documentation/as-iosched.txt 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,165 +0,0 @@ -Anticipatory IO scheduler -------------------------- -Nick Piggin 13 Sep 2003 - -Attention! Database servers, especially those using "TCQ" disks should -investigate performance with the 'deadline' IO scheduler. Any system with high -disk performance requirements should do so, in fact. - -If you see unusual performance characteristics of your disk systems, or you -see big performance regressions versus the deadline scheduler, please email -me. Database users don't bother unless you're willing to test a lot of patches -from me ;) its a known issue. - -Also, users with hardware RAID controllers, doing striping, may find -highly variable performance results with using the as-iosched. The -as-iosched anticipatory implementation is based on the notion that a disk -device has only one physical seeking head. A striped RAID controller -actually has a head for each physical device in the logical RAID device. - -However, setting the antic_expire (see tunable parameters below) produces -very similar behavior to the deadline IO scheduler. - - -Selecting IO schedulers ------------------------ -To choose IO schedulers at boot time, use the argument 'elevator=deadline'. -'noop' and 'as' (the default) are also available. IO schedulers are assigned -globally at boot time only presently. - - -Anticipatory IO scheduler Policies ----------------------------------- -The as-iosched implementation implements several layers of policies -to determine when an IO request is dispatched to the disk controller. -Here are the policies outlined, in order of application. - -1. one-way Elevator algorithm. - -The elevator algorithm is similar to that used in deadline scheduler, with -the addition that it allows limited backward movement of the elevator -(i.e. seeks backwards). A seek backwards can occur when choosing between -two IO requests where one is behind the elevator's current position, and -the other is in front of the elevator's position. If the seek distance to -the request in back of the elevator is less than half the seek distance to -the request in front of the elevator, then the request in back can be chosen. -Backward seeks are also limited to a maximum of MAXBACK (1024*1024) sectors. -This favors forward movement of the elevator, while allowing opportunistic -"short" backward seeks. - -2. FIFO expiration times for reads and for writes. - -This is again very similar to the deadline IO scheduler. The expiration -times for requests on these lists is tunable using the parameters read_expire -and write_expire discussed below. When a read or a write expires in this way, -the IO scheduler will interrupt its current elevator sweep or read anticipation -to service the expired request. - -3. Read and write request batching - -A batch is a collection of read requests or a collection of write -requests. The as scheduler alternates dispatching read and write batches -to the driver. In the case a read batch, the scheduler submits read -requests to the driver as long as there are read requests to submit, and -the read batch time limit has not been exceeded (read_batch_expire). -The read batch time limit begins counting down only when there are -competing write requests pending. - -In the case of a write batch, the scheduler submits write requests to -the driver as long as there are write requests available, and the -write batch time limit has not been exceeded (write_batch_expire). -However, the length of write batches will be gradually shortened -when read batches frequently exceed their time limit. - -When changing between batch types, the scheduler waits for all requests -from the previous batch to complete before scheduling requests for the -next batch. - -The read and write fifo expiration times described in policy 2 above -are checked only when in scheduling IO of a batch for the corresponding -(read/write) type. So for example, the read FIFO timeout values are -tested only during read batches. Likewise, the write FIFO timeout -values are tested only during write batches. For this reason, -it is generally not recommended for the read batch time -to be longer than the write expiration time, nor for the write batch -time to exceed the read expiration time (see tunable parameters below). - -When the IO scheduler changes from a read to a write batch, -it begins the elevator from the request that is on the head of the -write expiration FIFO. Likewise, when changing from a write batch to -a read batch, scheduler begins the elevator from the first entry -on the read expiration FIFO. - -4. Read anticipation. - -Read anticipation occurs only when scheduling a read batch. -This implementation of read anticipation allows only one read request -to be dispatched to the disk controller at a time. In -contrast, many write requests may be dispatched to the disk controller -at a time during a write batch. It is this characteristic that can make -the anticipatory scheduler perform anomalously with controllers supporting -TCQ, or with hardware striped RAID devices. Setting the antic_expire -queue paramter (see below) to zero disables this behavior, and the anticipatory -scheduler behaves essentially like the deadline scheduler. - -When read anticipation is enabled (antic_expire is not zero), reads -are dispatched to the disk controller one at a time. -At the end of each read request, the IO scheduler examines its next -candidate read request from its sorted read list. If that next request -is from the same process as the request that just completed, -or if the next request in the queue is "very close" to the -just completed request, it is dispatched immediately. Otherwise, -statistics (average think time, average seek distance) on the process -that submitted the just completed request are examined. If it seems -likely that that process will submit another request soon, and that -request is likely to be near the just completed request, then the IO -scheduler will stop dispatching more read requests for up time (antic_expire) -milliseconds, hoping that process will submit a new request near the one -that just completed. If such a request is made, then it is dispatched -immediately. If the antic_expire wait time expires, then the IO scheduler -will dispatch the next read request from the sorted read queue. - -To decide whether an anticipatory wait is worthwhile, the scheduler -maintains statistics for each process that can be used to compute -mean "think time" (the time between read requests), and mean seek -distance for that process. One observation is that these statistics -are associated with each process, but those statistics are not associated -with a specific IO device. So for example, if a process is doing IO -on several file systems on separate devices, the statistics will be -a combination of IO behavior from all those devices. - - -Tuning the anticipatory IO scheduler ------------------------------------- -When using 'as', the anticipatory IO scheduler there are 5 parameters under -/sys/block/*/iosched/. All are units of milliseconds. - -The parameters are: -* read_expire - Controls how long until a read request becomes "expired". It also controls the - interval between which expired requests are served, so set to 50, a request - might take anywhere < 100ms to be serviced _if_ it is the next on the - expired list. Obviously request expiration strategies won't make the disk - go faster. The result basically equates to the timeslice a single reader - gets in the presence of other IO. 100*((seek time / read_expire) + 1) is - very roughly the % streaming read efficiency your disk should get with - multiple readers. - -* read_batch_expire - Controls how much time a batch of reads is given before pending writes are - served. A higher value is more efficient. This might be set below read_expire - if writes are to be given higher priority than reads, but reads are to be - as efficient as possible when there are no writes. Generally though, it - should be some multiple of read_expire. - -* write_expire, and -* write_batch_expire are equivalent to the above, for writes. - -* antic_expire - Controls the maximum amount of time we can anticipate a good read (one - with a short seek distance from the most recently completed request) before - giving up. Many other factors may cause anticipation to be stopped early, - or some processes will not be "anticipated" at all. Should be a bit higher - for big seek time devices though not a linear correspondence - most - processes have only a few ms thinktime. - diff -Nru a/Documentation/basic_profiling.txt b/Documentation/basic_profiling.txt --- a/Documentation/basic_profiling.txt 2004-06-26 17:09:17 -07:00 +++ b/Documentation/basic_profiling.txt 2004-06-26 17:09:17 -07:00 @@ -5,16 +5,19 @@ is the thing you're trying to measure. Make sure you have the correct System.map / vmlinux referenced! -IMHO it's easier to use "make install" for linux and hack /sbin/installkernel -to copy config files, system.map, vmlinux to /boot. + +It is probably easiest to use "make install" for linux and hack +/sbin/installkernel to copy vmlinux to /boot, in addition to vmlinuz, +config, System.map, which are usually installed by default. Readprofile ----------- -You need a fixed readprofile command for 2.5 ... either get hold of -a current version from: +A recent readprofile command is needed for 2.6, such as found in util-linux +2.12a, which can be downloaded from: + http://www.kernel.org/pub/linux/utils/util-linux/ -or get readprofile binary fixed for 2.5 / akpm's 2.5 patch from -ftp://ftp.kernel.org/pub/linux/kernel/people/mbligh/tools/readprofile/ + +Most distributions will ship it already. Add "profile=2" to the kernel command line. @@ -24,25 +27,26 @@ Oprofile -------- -get source (I use 0.5) from http://oprofile.sourceforge.net/ -add "idle=poll" to the kernel command line +Get the source (I use 0.8) from http://oprofile.sourceforge.net/ +and add "idle=poll" to the kernel command line Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel ./configure --with-kernel-support make install -One time setup (pick appropriate one for your CPU): -P3 opcontrol --setup --vmlinux=/boot/vmlinux \ - --ctr0-event=CPU_CLK_UNHALTED --ctr0-count=100000 -Athlon/x86-64 opcontrol --setup --vmlinux=/boot/vmlinux \ - --ctr0-event=RETIRED_INSNS --ctr0-count=100000 -P4 opcontrol --setup --vmlinux=/boot/vmlinux \ - --ctr0-event=GLOBAL_POWER_EVENTS \ - --ctr0-unit-mask=1 --ctr0-count=100000 +For superior results, be sure to enable the local APIC. If opreport sees +a 0Hz CPU, APIC was not on. Be aware that idle=poll may mean a performance +penalty. + +One time setup: + opcontrol --setup --vmlinux=/boot/vmlinux -start daemon opcontrol --start-daemon clear opcontrol --reset start opcontrol --start stop opcontrol --stop -dump output oprofpp -dl -i /boot/vmlinux > output_file +dump output opreport > output_file + +To only report on the kernel, run opreport /boot/vmlinux > output_file + +A reset is needed to clear old statistics, which survive a reboot. diff -Nru a/Documentation/binfmt_misc.txt b/Documentation/binfmt_misc.txt --- a/Documentation/binfmt_misc.txt 2004-06-26 17:09:21 -07:00 +++ b/Documentation/binfmt_misc.txt 2004-06-26 17:09:21 -07:00 @@ -15,7 +15,7 @@ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc To actually register a new binary type, you have to set up a string looking like -:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon +:name:type:offset:magic:mask:interpreter:flags (where you can choose the ':' upon your needs) and echo it to /proc/sys/fs/binfmt_misc/register. Here is what the fields mean: - 'name' is an identifier string. A new /proc file will be created with this @@ -34,6 +34,28 @@ The mask is anded with the byte sequence of the file. - 'interpreter' is the program that should be invoked with the binary as first argument (specify the full path) + - 'flags' is an optional field that controls several aspects of the invocation + of the interpreter. It is a string of capital letters, each controls a certain + aspect. The following flags are supported - + 'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite the + original argv[0] with the full path to the binary. When this flag is + included, binfmt_misc will add an argument to the argument vector for + this purpose, thus preserving the original argv[0]. + 'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path + of the binary to the interpreter as an argument. When this flag is + included, binfmt_misc will open the file for reading and pass its + descriptor as an argument, instead of the full path, thus allowing + the interpreter to execute non-readable binaries. This feature should + be used with care - the interpreter has to be trusted not to emit + the contents of the non-readable binary. + 'C' - credentials. Currently, the behavior of binfmt_misc is to calculate + the credentials and security token of the new process according to + the interpreter. When this flag is included, these attributes are + calculated according to the binary. It also implies the 'O' flag. + This feature should be used with care as the interpreter + will run with root permissions when a setuid binary owned by root + is run with binfmt_misc. + There are some restrictions: - the whole register string may not exceed 255 characters @@ -83,9 +105,9 @@ write a wrapper script for it. See Documentation/java.txt for an example. -Your interpreter should NOT look in the PATH for the filename; the -kernel passes it the full filename to use. Using the PATH can cause -unexpected behaviour and be a security hazard. +Your interpreter should NOT look in the PATH for the filename; the kernel +passes it the full filename (or the file descriptor) to use. Using $PATH can +cause unexpected behaviour and can be a security hazard. There is a web page about binfmt_misc at diff -Nru a/Documentation/block/as-iosched.txt b/Documentation/block/as-iosched.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/block/as-iosched.txt 2004-06-26 17:09:16 -07:00 @@ -0,0 +1,165 @@ +Anticipatory IO scheduler +------------------------- +Nick Piggin 13 Sep 2003 + +Attention! Database servers, especially those using "TCQ" disks should +investigate performance with the 'deadline' IO scheduler. Any system with high +disk performance requirements should do so, in fact. + +If you see unusual performance characteristics of your disk systems, or you +see big performance regressions versus the deadline scheduler, please email +me. Database users don't bother unless you're willing to test a lot of patches +from me ;) its a known issue. + +Also, users with hardware RAID controllers, doing striping, may find +highly variable performance results with using the as-iosched. The +as-iosched anticipatory implementation is based on the notion that a disk +device has only one physical seeking head. A striped RAID controller +actually has a head for each physical device in the logical RAID device. + +However, setting the antic_expire (see tunable parameters below) produces +very similar behavior to the deadline IO scheduler. + + +Selecting IO schedulers +----------------------- +To choose IO schedulers at boot time, use the argument 'elevator=deadline'. +'noop' and 'as' (the default) are also available. IO schedulers are assigned +globally at boot time only presently. + + +Anticipatory IO scheduler Policies +---------------------------------- +The as-iosched implementation implements several layers of policies +to determine when an IO request is dispatched to the disk controller. +Here are the policies outlined, in order of application. + +1. one-way Elevator algorithm. + +The elevator algorithm is similar to that used in deadline scheduler, with +the addition that it allows limited backward movement of the elevator +(i.e. seeks backwards). A seek backwards can occur when choosing between +two IO requests where one is behind the elevator's current position, and +the other is in front of the elevator's position. If the seek distance to +the request in back of the elevator is less than half the seek distance to +the request in front of the elevator, then the request in back can be chosen. +Backward seeks are also limited to a maximum of MAXBACK (1024*1024) sectors. +This favors forward movement of the elevator, while allowing opportunistic +"short" backward seeks. + +2. FIFO expiration times for reads and for writes. + +This is again very similar to the deadline IO scheduler. The expiration +times for requests on these lists is tunable using the parameters read_expire +and write_expire discussed below. When a read or a write expires in this way, +the IO scheduler will interrupt its current elevator sweep or read anticipation +to service the expired request. + +3. Read and write request batching + +A batch is a collection of read requests or a collection of write +requests. The as scheduler alternates dispatching read and write batches +to the driver. In the case a read batch, the scheduler submits read +requests to the driver as long as there are read requests to submit, and +the read batch time limit has not been exceeded (read_batch_expire). +The read batch time limit begins counting down only when there are +competing write requests pending. + +In the case of a write batch, the scheduler submits write requests to +the driver as long as there are write requests available, and the +write batch time limit has not been exceeded (write_batch_expire). +However, the length of write batches will be gradually shortened +when read batches frequently exceed their time limit. + +When changing between batch types, the scheduler waits for all requests +from the previous batch to complete before scheduling requests for the +next batch. + +The read and write fifo expiration times described in policy 2 above +are checked only when in scheduling IO of a batch for the corresponding +(read/write) type. So for example, the read FIFO timeout values are +tested only during read batches. Likewise, the write FIFO timeout +values are tested only during write batches. For this reason, +it is generally not recommended for the read batch time +to be longer than the write expiration time, nor for the write batch +time to exceed the read expiration time (see tunable parameters below). + +When the IO scheduler changes from a read to a write batch, +it begins the elevator from the request that is on the head of the +write expiration FIFO. Likewise, when changing from a write batch to +a read batch, scheduler begins the elevator from the first entry +on the read expiration FIFO. + +4. Read anticipation. + +Read anticipation occurs only when scheduling a read batch. +This implementation of read anticipation allows only one read request +to be dispatched to the disk controller at a time. In +contrast, many write requests may be dispatched to the disk controller +at a time during a write batch. It is this characteristic that can make +the anticipatory scheduler perform anomalously with controllers supporting +TCQ, or with hardware striped RAID devices. Setting the antic_expire +queue paramter (see below) to zero disables this behavior, and the anticipatory +scheduler behaves essentially like the deadline scheduler. + +When read anticipation is enabled (antic_expire is not zero), reads +are dispatched to the disk controller one at a time. +At the end of each read request, the IO scheduler examines its next +candidate read request from its sorted read list. If that next request +is from the same process as the request that just completed, +or if the next request in the queue is "very close" to the +just completed request, it is dispatched immediately. Otherwise, +statistics (average think time, average seek distance) on the process +that submitted the just completed request are examined. If it seems +likely that that process will submit another request soon, and that +request is likely to be near the just completed request, then the IO +scheduler will stop dispatching more read requests for up time (antic_expire) +milliseconds, hoping that process will submit a new request near the one +that just completed. If such a request is made, then it is dispatched +immediately. If the antic_expire wait time expires, then the IO scheduler +will dispatch the next read request from the sorted read queue. + +To decide whether an anticipatory wait is worthwhile, the scheduler +maintains statistics for each process that can be used to compute +mean "think time" (the time between read requests), and mean seek +distance for that process. One observation is that these statistics +are associated with each process, but those statistics are not associated +with a specific IO device. So for example, if a process is doing IO +on several file systems on separate devices, the statistics will be +a combination of IO behavior from all those devices. + + +Tuning the anticipatory IO scheduler +------------------------------------ +When using 'as', the anticipatory IO scheduler there are 5 parameters under +/sys/block/*/iosched/. All are units of milliseconds. + +The parameters are: +* read_expire + Controls how long until a read request becomes "expired". It also controls the + interval between which expired requests are served, so set to 50, a request + might take anywhere < 100ms to be serviced _if_ it is the next on the + expired list. Obviously request expiration strategies won't make the disk + go faster. The result basically equates to the timeslice a single reader + gets in the presence of other IO. 100*((seek time / read_expire) + 1) is + very roughly the % streaming read efficiency your disk should get with + multiple readers. + +* read_batch_expire + Controls how much time a batch of reads is given before pending writes are + served. A higher value is more efficient. This might be set below read_expire + if writes are to be given higher priority than reads, but reads are to be + as efficient as possible when there are no writes. Generally though, it + should be some multiple of read_expire. + +* write_expire, and +* write_batch_expire are equivalent to the above, for writes. + +* antic_expire + Controls the maximum amount of time we can anticipate a good read (one + with a short seek distance from the most recently completed request) before + giving up. Many other factors may cause anticipation to be stopped early, + or some processes will not be "anticipated" at all. Should be a bit higher + for big seek time devices though not a linear correspondence - most + processes have only a few ms thinktime. + diff -Nru a/Documentation/block/deadline-iosched.txt b/Documentation/block/deadline-iosched.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/block/deadline-iosched.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,78 @@ +Deadline IO scheduler tunables +============================== + +This little file attempts to document how the deadline io scheduler works. +In particular, it will clarify the meaning of the exposed tunables that may be +of interest to power users. + +Each io queue has a set of io scheduler tunables associated with it. These +tunables control how the io scheduler works. You can find these entries +in: + +/sys/block//iosched + +assuming that you have sysfs mounted on /sys. If you don't have sysfs mounted, +you can do so by typing: + +# mount none /sys -t sysfs + + +******************************************************************************** + + +read_expire (in ms) +----------- + +The goal of the deadline io scheduler is to attempt to guarentee a start +service time for a request. As we focus mainly on read latencies, this is +tunable. When a read request first enters the io scheduler, it is assigned +a deadline that is the current time + the read_expire value in units of +miliseconds. + + +write_expire (in ms) +----------- + +Similar to read_expire mentioned above, but for writes. + + +fifo_batch +---------- + +When a read request expires its deadline, we must move some requests from +the sorted io scheduler list to the block device dispatch queue. fifo_batch +controls how many requests we move, based on the cost of each request. A +request is either qualified as a seek or a stream. The io scheduler knows +the last request that was serviced by the drive (or will be serviced right +before this one). See seek_cost and stream_unit. + + +write_starved (number of dispatches) +------------- + +When we have to move requests from the io scheduler queue to the block +device dispatch queue, we always give a preference to reads. However, we +don't want to starve writes indefinitely either. So writes_starved controls +how many times we give preference to reads over writes. When that has been +done writes_starved number of times, we dispatch some writes based on the +same criteria as reads. + + +front_merges (bool) +------------ + +Sometimes it happens that a request enters the io scheduler that is contigious +with a request that is already on the queue. Either it fits in the back of that +request, or it fits at the front. That is called either a back merge candidate +or a front merge candidate. Due to the way files are typically laid out, +back merges are much more common than front merges. For some work loads, you +may even know that it is a waste of time to spend any time attempting to +front merge requests. Setting front_merges to 0 disables this functionality. +Front merges may still occur due to the cached last_merge hint, but since +that comes at basically 0 cost we leave that on. We simply disable the +rbtree front sector lookup when the io scheduler merge function is called. + + +Nov 11 2002, Jens Axboe + + diff -Nru a/Documentation/device-mapper/dm-io.txt b/Documentation/device-mapper/dm-io.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/device-mapper/dm-io.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,75 @@ +dm-io +===== + +Dm-io provides synchronous and asynchronous I/O services. There are three +types of I/O services available, and each type has a sync and an async +version. + +The user must set up an io_region structure to describe the desired location +of the I/O. Each io_region indicates a block-device along with the starting +sector and size of the region. + + struct io_region { + struct block_device *bdev; + sector_t sector; + sector_t count; + }; + +Dm-io can read from one io_region or write to one or more io_regions. Writes +to multiple regions are specified by an array of io_region structures. + +The first I/O service type takes a list of memory pages as the data buffer for +the I/O, along with an offset into the first page. + + struct page_list { + struct page_list *next; + struct page *page; + }; + + int dm_io_sync(unsigned int num_regions, struct io_region *where, int rw, + struct page_list *pl, unsigned int offset, + unsigned long *error_bits); + int dm_io_async(unsigned int num_regions, struct io_region *where, int rw, + struct page_list *pl, unsigned int offset, + io_notify_fn fn, void *context); + +The second I/O service type takes an array of bio vectors as the data buffer +for the I/O. This service can be handy if the caller has a pre-assembled bio, +but wants to direct different portions of the bio to different devices. + + int dm_io_sync_bvec(unsigned int num_regions, struct io_region *where, + int rw, struct bio_vec *bvec, + unsigned long *error_bits); + int dm_io_async_bvec(unsigned int num_regions, struct io_region *where, + int rw, struct bio_vec *bvec, + io_notify_fn fn, void *context); + +The third I/O service type takes a pointer to a vmalloc'd memory buffer as the +data buffer for the I/O. This service can be handy if the caller needs to do +I/O to a large region but doesn't want to allocate a large number of individual +memory pages. + + int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw, + void *data, unsigned long *error_bits); + int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw, + void *data, io_notify_fn fn, void *context); + +Callers of the asynchronous I/O services must include the name of a completion +callback routine and a pointer to some context data for the I/O. + + typedef void (*io_notify_fn)(unsigned long error, void *context); + +The "error" parameter in this callback, as well as the "*error" parameter in +all of the synchronous versions, is a bitset (instead of a simple error value). +In the case of an write-I/O to multiple regions, this bitset allows dm-io to +indicate success or failure on each individual region. + +Before using any of the dm-io services, the user should call dm_io_get() +and specify the number of pages they expect to perform I/O on concurrently. +Dm-io will attempt to resize its mempool to make sure enough pages are +always available in order to avoid unnecessary waiting while performing I/O. + +When the user is finished using the dm-io services, they should call +dm_io_put() and specify the same number of pages that were given on the +dm_io_get() call. + diff -Nru a/Documentation/device-mapper/kcopyd.txt b/Documentation/device-mapper/kcopyd.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/device-mapper/kcopyd.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,47 @@ +kcopyd +====== + +Kcopyd provides the ability to copy a range of sectors from one block-device +to one or more other block-devices, with an asynchronous completion +notification. It is used by dm-snapshot and dm-mirror. + +Users of kcopyd must first create a client and indicate how many memory pages +to set aside for their copy jobs. This is done with a call to +kcopyd_client_create(). + + int kcopyd_client_create(unsigned int num_pages, + struct kcopyd_client **result); + +To start a copy job, the user must set up io_region structures to describe +the source and destinations of the copy. Each io_region indicates a +block-device along with the starting sector and size of the region. The source +of the copy is given as one io_region structure, and the destinations of the +copy are given as an array of io_region structures. + + struct io_region { + struct block_device *bdev; + sector_t sector; + sector_t count; + }; + +To start the copy, the user calls kcopyd_copy(), passing in the client +pointer, pointers to the source and destination io_regions, the name of a +completion callback routine, and a pointer to some context data for the copy. + + int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, + unsigned int num_dests, struct io_region *dests, + unsigned int flags, kcopyd_notify_fn fn, void *context); + + typedef void (*kcopyd_notify_fn)(int read_err, unsigned int write_err, + void *context); + +When the copy completes, kcopyd will call the user's completion routine, +passing back the user's context pointer. It will also indicate if a read or +write error occurred during the copy. + +When a user is done with all their copy jobs, they should call +kcopyd_client_destroy() to delete the kcopyd client, which will release the +associated memory pages. + + void kcopyd_client_destroy(struct kcopyd_client *kc); + diff -Nru a/Documentation/device-mapper/linear.txt b/Documentation/device-mapper/linear.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/device-mapper/linear.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,61 @@ +dm-linear +========= + +Device-Mapper's "linear" target maps a linear range of the Device-Mapper +device onto a linear range of another device. This is the basic building +block of logical volume managers. + +Parameters: + : Full pathname to the underlying block-device, or a + "major:minor" device-number. + : Starting sector within the device. + + +Example scripts +=============== +[[ +#!/bin/sh +# Create an identity mapping for a device +echo "0 `blockdev --getsize $1` linear $1 0" | dmsetup create identity +]] + + +[[ +#!/bin/sh +# Join 2 devices together +size1=`blockdev --getsize $1` +size2=`blockdev --getsize $2` +echo "0 $size1 linear $1 0 +$size1 $size2 linear $2 0" | dmsetup create joined +]] + + +[[ +#!/usr/bin/perl -w +# Split a device into 4M chunks and then join them together in reverse order. + +my $name = "reverse"; +my $extent_size = 4 * 1024 * 2; +my $dev = $ARGV[0]; +my $table = ""; +my $count = 0; + +if (!defined($dev)) { + die("Please specify a device.\n"); +} + +my $dev_size = `blockdev --getsize $dev`; +my $extents = int($dev_size / $extent_size) - + (($dev_size % $extent_size) ? 1 : 0); + +while ($extents > 0) { + my $this_start = $count * $extent_size; + $extents--; + $count++; + my $this_offset = $extents * $extent_size; + + $table .= "$this_start $extent_size linear $dev $this_offset\n"; +} + +`echo \"$table\" | dmsetup create $name`; +]] diff -Nru a/Documentation/device-mapper/striped.txt b/Documentation/device-mapper/striped.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/device-mapper/striped.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,58 @@ +dm-stripe +========= + +Device-Mapper's "striped" target is used to create a striped (i.e. RAID-0) +device across one or more underlying devices. Data is written in "chunks", +with consecutive chunks rotating among the underlying devices. This can +potentially provide improved I/O throughput by utilizing several physical +devices in parallel. + +Parameters: [ ]+ + : Number of underlying devices. + : Size of each chunk of data. Must be a power-of-2 and at + least as large as the system's PAGE_SIZE. + : Full pathname to the underlying block-device, or a + "major:minor" device-number. + : Starting sector within the device. + +One or more underlying devices can be specified. The striped device size must +be a multiple of the chunk size and a multiple of the number of underlying +devices. + + +Example scripts +=============== + +[[ +#!/usr/bin/perl -w +# Create a striped device across any number of underlying devices. The device +# will be called "stripe_dev" and have a chunk-size of 128k. + +my $chunk_size = 128 * 2; +my $dev_name = "stripe_dev"; +my $num_devs = @ARGV; +my @devs = @ARGV; +my ($min_dev_size, $stripe_dev_size, $i); + +if (!$num_devs) { + die("Specify at least one device\n"); +} + +$min_dev_size = `blockdev --getsize $devs[0]`; +for ($i = 1; $i < $num_devs; $i++) { + my $this_size = `blockdev --getsize $devs[$i]`; + $min_dev_size = ($min_dev_size < $this_size) ? + $min_dev_size : $this_size; +} + +$stripe_dev_size = $min_dev_size * $num_devs; +$stripe_dev_size -= $stripe_dev_size % ($chunk_size * $num_devs); + +$table = "0 $stripe_dev_size striped $num_devs $chunk_size"; +for ($i = 0; $i < $num_devs; $i++) { + $table .= " $devs[$i] 0"; +} + +`echo $table | dmsetup create $dev_name`; +]] + diff -Nru a/Documentation/device-mapper/zero.txt b/Documentation/device-mapper/zero.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/device-mapper/zero.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,37 @@ +dm-zero +======= + +Device-Mapper's "zero" target provides a block-device that always returns +zero'd data on reads and silently drops writes. This is similar behavior to +/dev/zero, but as a block-device instead of a character-device. + +Dm-zero has no target-specific parameters. + +One very interesting use of dm-zero is for creating "sparse" devices in +conjunction with dm-snapshot. A sparse device reports a device-size larger +than the amount of actual storage space available for that device. A user can +write data anywhere within the sparse device and read it back like a normal +device. Reads to previously unwritten areas will return a zero'd buffer. When +enough data has been written to fill up the actual storage space, the sparse +device is deactivated. This can be very useful for testing device and +filesystem limitations. + +To create a sparse device, start by creating a dm-zero device that's the +desired size of the sparse device. For this example, we'll assume a 10TB +sparse device. + +TEN_TERABYTES=`expr 10 \* 1024 \* 1024 \* 1024 \* 2` # 10 TB in sectors +echo "0 $TEN_TERABYTES zero" | dmsetup create zero1 + +Then create a snapshot of the zero device, using any available block-device as +the COW device. The size of the COW device will determine the amount of real +space available to the sparse device. For this example, we'll assume /dev/sdb1 +is an available 10GB partition. + +echo "0 $TEN_TERABYTES snapshot /dev/mapper/zero1 /dev/sdb1 p 128" | \ + dmsetup create sparse1 + +This will create a 10TB sparse device called /dev/mapper/sparse1 that has +10GB of actual storage space available. If more than 10GB of data is written +to this device, it will start returning I/O errors. + diff -Nru a/Documentation/devices.txt b/Documentation/devices.txt --- a/Documentation/devices.txt 2004-06-26 17:09:17 -07:00 +++ b/Documentation/devices.txt 2004-06-26 17:09:17 -07:00 @@ -2377,16 +2377,16 @@ 1 = /dev/gpib1 Second GPIB bus ... -160 block Carmel 8-port SATA Disks on First Controller - 0 = /dev/carmel/0 SATA disk 0 whole disk - 1 = /dev/carmel/0p1 SATA disk 0 partition 1 +160 block Promise SX8 8-port SATA Disks on First Controller + 0 = /dev/sx8/0 SATA disk 0 whole disk + 1 = /dev/sx8/0p1 SATA disk 0 partition 1 ... - 31 = /dev/carmel/0p31 SATA disk 0 partition 31 + 31 = /dev/sx8/0p31 SATA disk 0 partition 31 - 32 = /dev/carmel/1 SATA disk 1 whole disk - 64 = /dev/carmel/2 SATA disk 2 whole disk + 32 = /dev/sx8/1 SATA disk 1 whole disk + 64 = /dev/sx8/2 SATA disk 2 whole disk ... - 224 = /dev/carmel/7 SATA disk 7 whole disk + 224 = /dev/sx8/7 SATA disk 7 whole disk Partitions are handled in the same way as for IDE disks (see major number 3) except that the limit on @@ -2400,16 +2400,16 @@ 17 = /dev/irlpt1 Second IrLPT device ... -161 block Carmel 8-port SATA Disks on Second Controller - 0 = /dev/carmel/8 SATA disk 8 whole disk - 1 = /dev/carmel/8p1 SATA disk 8 partition 1 +161 block Promise SX8 8-port SATA Disks on Second Controller + 0 = /dev/sx8/8 SATA disk 8 whole disk + 1 = /dev/sx8/8p1 SATA disk 8 partition 1 ... - 31 = /dev/carmel/8p31 SATA disk 8 partition 31 + 31 = /dev/sx8/8p31 SATA disk 8 partition 31 - 32 = /dev/carmel/9 SATA disk 9 whole disk - 64 = /dev/carmel/10 SATA disk 10 whole disk + 32 = /dev/sx8/9 SATA disk 9 whole disk + 64 = /dev/sx8/10 SATA disk 10 whole disk ... - 224 = /dev/carmel/15 SATA disk 15 whole disk + 224 = /dev/sx8/15 SATA disk 15 whole disk Partitions are handled in the same way as for IDE disks (see major number 3) except that the limit on diff -Nru a/Documentation/fb/sisfb.txt b/Documentation/fb/sisfb.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/fb/sisfb.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,158 @@ + +What is sisfb? +============== + +sisfb is a framebuffer device driver for SiS (Silicon Integrated Systems) +graphics chips. Supported are: + +- SiS 300 series: SiS 300/305, 540, 630(S), 730(S) +- SiS 315 series: SiS 315/H/PRO, 55x, (M)65x, 740, (M)661(F/M)X, (M)741(GX) +- SiS 330 series: SiS 330 ("Xabre"), (M)760 + + +Why do I need a framebuffer driver? +=================================== + +sisfb is eg. useful if you want a high-resolution text console. Besides that, +sisfb is required to run DirectFB (which comes with an additional, dedicated +driver for the 315 series). + +On the 300 series, sisfb on kernels older than 2.6.3 furthermore plays an +important role in connection with DRM/DRI: Sisfb manages the memory heap +used by DRM/DRI for 3D texture and other data. This memory management is +required for using DRI/DRM. + +Kernels >= around 2.6.3 do not need sisfb any longer for DRI/DRM memory +management. The SiS DRM driver has been updated and features a memory manager +of its own (which will be used if sisfb is not compiled). So unless you want +a graphical console, you don't need sisfb on kernels >=2.6.3. + +Sidenote: Since this seems to be a commonly made mistake: sisfb and vesafb +cannot be active at the same time! Do only select one of them in your kernel +configuration. + + +How are parameters passed to sisfb? +=================================== + +Well, it depends: If compiled statically into the kernel, use lilo's append +statement to add the parameters to the kernel command line. Please see lilo's +(or GRUB's) documentation for more information. If sisfb is a kernel module, +parameters are given with the modprobe (or insmod) command. + +Example for sisfb as part of the static kernel: Add the following line to your +lilo.conf: + + append="video=sisfb:mode:1024x768x16,mem:12288,rate:75" + +Example for sisfb as a module: Start sisfb by typing + + modprobe sisfb mode=1024x768x16 rate=75 mem=12288 + +A common mistake is that folks use a wrong parameter format when using the +driver compiled into the kernel. Please note: If compiled into the kernel, +the parameter format is video=sisfb:mode:none or video=sisfb:mode:1024x768x16 +(or whatever mode you want to use, alternatively using any other format +described above or the vesa keyword instead of mode). If compiled as a module, +the parameter format reads mode=none or mode=1024x768x16 (or whatever mode you +want to use). Using a "=" for a ":" (and vice versa) is a huge difference! +Additionally: If you give more than one argument to the in-kernel sisfb, the +arguments are separated with ",". For example: + + video=sisfb:mode:1024x768x16,rate:75,mem:12288 + + +How do I use it? +================ + +Preface statement: This file only covers very little of the driver's +capabilities and features. Please refer to the author's and maintainer's +website at http://www.winischhofer.net/linuxsisvga.shtml for more +information. Additionally, "modinfo sisfb" gives an overview over all +supported options including some explanation. + +The desired display mode can be specified using the keyword "mode" with +a parameter in one of the follwing formats: + - XxYxDepth or + - XxY-Depth or + - XxY-Depth@Rate or + - XxY + - or simply use the VESA mode number in hexadecimal or decimal. + +For example: 1024x768x16, 1024x768-16@75, 1280x1024-16. If no depth is +specified, it defaults to 8. If no rate is given, it defaults to 60Hz. Depth 32 +means 24bit color depth (but 32 bit framebuffer depth, which is not relevant +to the user). + +Additionally, sisfb understands the keyword "vesa" followed by a VESA mode +number in decimal or hexadecimal. For example: vesa=791 or vesa=0x117. Please +use either "mode" or "vesa" but not both. + +Linux 2.4 only: If no mode is given, sisfb defaults to "no mode" (mode=none) if +compiled as a module; if sisfb is statically compiled into the kernel, it +defaults to 800x600x8 unless CRT2 type is LCD, in which case the LCD's native +resolution is used. If you want to switch to a different mode, use the fbset +shell command. + +Linux 2.6 only: If no mode is given, sisfb defaults to 800x600x8 unless CRT2 +type is LCD, in which case it defaults to the LCD's native resolution. If +you want to switch to another mode, use the stty shell command. + +You should compile in both vgacon (to boot if you remove you SiS card from +your system) and sisfb (for graphics mode). Under Linux 2.6, also "Framebuffer +console support" (fbcon) is needed for a graphical console. + +You should *not* compile-in vesafb. And please do not use the "vga=" keyword +in lilo's or grub's configuration file; mode selection is done using the +"mode" or "vesa" keywords as a parameter. See above and below. + + +X11 +=== + +If using XFree86 or X.org, it is recommended that you don't use the "fbdev" +driver but the dedicated "sis" X driver. The "sis" X driver and sisfb are +developed by the same person (Thomas Winischhofer) and cooperate well with +each other. + + +SVGALib +======= + +SVGALib, if directly accessing the hardware, never restores the screen +correctly, especially on laptops or if the output devices are LCD or TV. +Therefore, use the chipset "FBDEV" in SVGALib configuration. This will make +SVGALib use the framebuffer device for mode switches and restoration. + + +Configuration +============= + +(Some) accepted options: + +off - Disable sisfb. This option is only understood if sisfb is + in-kernel, not a module. +mem:X - size of memory for the console, rest will be used for DRI/DRM. X + is in kilobytes. On 300 series, the default is 4096, 8192 or + 16384 (each in kilobyte) depending on how much video ram the card + has. On 315/330 series, the default is the maximum available ram + (since DRI/DRM is not supported for these chipsets). +noaccel - do not use 2D acceleration engine. (Default: use acceleration) +noypan - disable y-panning and scroll by redrawing the entire screen. + This is much slower than y-panning. (Default: use y-panning) +vesa:X - selects startup videomode. X is number from 0 to 0x1FF and + represents the VESA mode number (can be given in decimal or + hexadecimal form, the latter prefixed with "0x"). +mode:X - selects startup videomode. Please see above for the format of + "X". + +Boolean options such as "noaccel" or "noypan" are to be given without a +parameter if sisfb is in-kernel (for example "video=sisfb:noypan). If +sisfb is a module, these are to be set to 1 (for example "modprobe sisfb +noypan=1"). + +-- +Thomas Winischhofer +May 27, 2004 + + diff -Nru a/Documentation/filesystems/hpfs.txt b/Documentation/filesystems/hpfs.txt --- a/Documentation/filesystems/hpfs.txt 2004-06-26 17:09:17 -07:00 +++ b/Documentation/filesystems/hpfs.txt 2004-06-26 17:09:17 -07:00 @@ -1,5 +1,5 @@ -Read/Write HPFS 2.05 -1998-2001, Mikulas Patocka +Read/Write HPFS 2.09 +1998-2004, Mikulas Patocka email: mikulas@artax.karlin.mff.cuni.cz homepage: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi @@ -283,6 +283,14 @@ 2.05 Fixed crash when got mount parameters without = Fixed crash when allocation of anode failed due to full disk Fixed some crashes when block io or inode allocation failed +2.06 Fixed some crash on corrupted disk structures + Better allocation strategy + Reschedule points added so that it doesn't lock CPU long time + It should work in read-only mode on Warp Server +2.07 More fixes for Warp Server. Now it really works +2.08 Creating new files is not so slow on large disks + An attempt to sync deleted file does not generate filesystem error +2.09 Fixed error on extremly fragmented files vim: set textwidth=80: diff -Nru a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt --- a/Documentation/filesystems/proc.txt 2004-06-26 17:09:16 -07:00 +++ b/Documentation/filesystems/proc.txt 2004-06-26 17:09:16 -07:00 @@ -201,7 +201,7 @@ devices Available devices (block and character) dma Used DMS channels filesystems Supported filesystems - driver Various drivers grouped here, currently rtc (2.4) + driver Various drivers grouped here, currently rtc (2.4) and hpet (2.6) execdomains Execdomains, related to security (2.4) fb Frame Buffer devices (2.4) fs File system parameters, currently nfs/exports (2.4) @@ -1115,6 +1115,18 @@ The files in this directory can be used to tune the operation of the virtual memory (VM) subsystem of the Linux kernel. +vfs_cache_pressure +------------------ + +Controls the tendency of the kernel to reclaim the memory which is used for +caching of directory and inode objects. + +At the default value of vfs_cache_pressure=100 the kernel will attempt to +reclaim dentries and inodes at a "fair" rate with respect to pagecache and +swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer +to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 +causes the kernel to prefer to reclaim dentries and inodes. + dirty_background_ratio ---------------------- @@ -1640,7 +1652,8 @@ Writing to this file results in a flush of the routing cache. -gc_elastic, gc_interval, gc_min_interval, gc_tresh, gc_timeout +gc_elasticity, gc_interval, gc_min_interval, gc_tresh, gc_timeout, +gc_thresh, gc_thresh1, gc_thresh2, gc_thresh3 -------------------------------------------------------------- Values to control the frequency and behavior of the garbage collection diff -Nru a/Documentation/hpet.txt b/Documentation/hpet.txt --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/Documentation/hpet.txt 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,298 @@ + High Precision Event Timer Driver for Linux + +The High Precision Event Timer (HPET) hardware is the future replacement for the 8254 and Real +Time Clock (RTC) periodic timer functionality. Each HPET can have up two 32 timers. It is possible +to configure the first two timers as legacy replacements for 8254 and RTC periodic. A specification +done by INTEL and Microsoft can be found at http://www.intel.com/labs/platcomp/hpet/hpetspec.htm. + +The driver supports detection of HPET driver allocation and initialization of the HPET before the +driver module_init routine is called. This enables platform code which uses timer 0 or 1 as the +main timer to intercept HPET initialization. An example of this initialization can be found in +arch/i386/kernel/time_hpet.c. + +The driver provides two APIs which are very similar to the API found in the rtc.c driver. +There is a user space API and a kernel space API. An example user space program is provided +below. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +extern void hpet_open_close(int, const char **); +extern void hpet_info(int, const char **); +extern void hpet_poll(int, const char **); +extern void hpet_fasync(int, const char **); +extern void hpet_read(int, const char **); + +#include +#include +#include + +struct hpet_command { + char *command; + void (*func)(int argc, const char ** argv); +} hpet_command[] = { + { + "open-close", + hpet_open_close + }, + { + "info", + hpet_info + }, + { + "poll", + hpet_poll + }, + { + "fasync", + hpet_fasync + }, +}; + +int +main(int argc, const char ** argv) +{ + int i; + + argc--; + argv++; + + if (!argc) { + fprintf(stderr, "-hpet: requires command\n"); + return -1; + } + + + for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++) + if (!strcmp(argv[0], hpet_command[i].command)) { + argc--; + argv++; + fprintf(stderr, "-hpet: executing %s\n", + hpet_command[i].command); + hpet_command[i].func(argc, argv); + return 0; + } + + fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]); + + return -1; +} + +void +hpet_open_close(int argc, const char **argv) +{ + int fd; + + if (argc != 1) { + fprintf(stderr, "hpet_open_close: device-name\n"); + return; + } + + fd = open(argv[0], O_RDWR); + if (fd < 0) + fprintf(stderr, "hpet_open_close: open failed\n"); + else + close(fd); + + return; +} + +void +hpet_info(int argc, const char **argv) +{ +} + +void +hpet_poll(int argc, const char **argv) +{ + unsigned long freq; + int iterations, i, fd; + struct pollfd pfd; + struct hpet_info info; + struct timeval stv, etv; + struct timezone tz; + long usec; + + if (argc != 3) { + fprintf(stderr, "hpet_poll: device-name freq iterations\n"); + return; + } + + freq = atoi(argv[1]); + iterations = atoi(argv[2]); + + fd = open(argv[0], O_RDWR); + + if (fd < 0) { + fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]); + return; + } + + if (ioctl(fd, HPET_IRQFREQ, freq) < 0) { + fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n"); + goto out; + } + + if (ioctl(fd, HPET_INFO, &info) < 0) { + fprintf(stderr, "hpet_poll: failed to get info\n"); + goto out; + } + + fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags); + + if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) { + fprintf(stderr, "hpet_poll: HPET_EPI failed\n"); + goto out; + } + + if (ioctl(fd, HPET_IE_ON, 0) < 0) { + fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n"); + goto out; + } + + pfd.fd = fd; + pfd.events = POLLIN; + + for (i = 0; i < iterations; i++) { + pfd.revents = 0; + gettimeofday(&stv, &tz); + if (poll(&pfd, 1, -1) < 0) + fprintf(stderr, "hpet_poll: poll failed\n"); + else { + long data; + + gettimeofday(&etv, &tz); + usec = stv.tv_sec * 1000000 + stv.tv_usec; + usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec; + + fprintf(stderr, + "hpet_poll: expired time = 0x%lx\n", usec); + + fprintf(stderr, "hpet_poll: revents = 0x%x\n", + pfd.revents); + + if (read(fd, &data, sizeof(data)) != sizeof(data)) { + fprintf(stderr, "hpet_poll: read failed\n"); + } + else + fprintf(stderr, "hpet_poll: data 0x%lx\n", + data); + } + } + +out: + close(fd); + return; +} + +static int hpet_sigio_count; + +static void +hpet_sigio(int val) +{ + fprintf(stderr, "hpet_sigio: called\n"); + hpet_sigio_count++; +} + +void +hpet_fasync(int argc, const char **argv) +{ + unsigned long freq; + int iterations, i, fd, value; + sig_t oldsig; + struct hpet_info info; + + hpet_sigio_count = 0; + fd = -1; + + if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) { + fprintf(stderr, "hpet_fasync: failed to set signal handler\n"); + return; + } + + if (argc != 3) { + fprintf(stderr, "hpet_fasync: device-name freq iterations\n"); + goto out; + } + + fd = open(argv[0], O_RDWR); + + if (fd < 0) { + fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]); + return; + } + + + if ((fcntl(fd, F_SETOWN, getpid()) == 1) || + ((value = fcntl(fd, F_GETFL)) == 1) || + (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) { + fprintf(stderr, "hpet_fasync: fcntl failed\n"); + goto out; + } + + freq = atoi(argv[1]); + iterations = atoi(argv[2]); + + if (ioctl(fd, HPET_IRQFREQ, freq) < 0) { + fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n"); + goto out; + } + + if (ioctl(fd, HPET_INFO, &info) < 0) { + fprintf(stderr, "hpet_fasync: failed to get info\n"); + goto out; + } + + fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags); + + if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) { + fprintf(stderr, "hpet_fasync: HPET_EPI failed\n"); + goto out; + } + + if (ioctl(fd, HPET_IE_ON, 0) < 0) { + fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n"); + goto out; + } + + for (i = 0; i < iterations; i++) { + (void) pause(); + fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count); + } + +out: + signal(SIGIO, oldsig); + + if (fd >= 0) + close(fd); + + return; +} + +The kernel API has three interfaces exported from the driver: + + hpet_register(struct hpet_task *tp, int periodic) + hpet_unregister(struct hpet_task *tp) + hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg) + +The kernel module using this interface fills in the ht_func and ht_data members of the +hpet_task structure before calling hpet_register. hpet_control simply vectors to the hpet_ioctl +routine and has the same commands and respective arguments as the user API. hpet_unregister +is used to terminate usage of the HPET timer reserved by hpet_register. + + diff -Nru a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt --- a/Documentation/ioctl-number.txt 2004-06-26 17:09:20 -07:00 +++ b/Documentation/ioctl-number.txt 2004-06-26 17:09:20 -07:00 @@ -189,3 +189,5 @@ 0xDD 00-3F ZFCP device driver see drivers/s390/scsi/ +0xF3 00-3F video/sisfb.h sisfb (in development) + diff -Nru a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX --- a/Documentation/networking/00-INDEX 2004-06-26 17:09:19 -07:00 +++ b/Documentation/networking/00-INDEX 2004-06-26 17:09:19 -07:00 @@ -4,8 +4,6 @@ - information on the 3Com EtherLink Plus (3c505) driver. 6pack.txt - info on the 6pack protocol, an alternative to KISS for AX.25 -8139too.txt - - info on the 8139too driver for RTL-8139 based network cards. Configurable - info on some of the configurable network parameters DLINK.txt diff -Nru a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt --- a/Documentation/networking/ip-sysctl.txt 2004-06-26 17:09:17 -07:00 +++ b/Documentation/networking/ip-sysctl.txt 2004-06-26 17:09:17 -07:00 @@ -17,6 +17,16 @@ Disable Path MTU Discovery. default FALSE +min_pmtu - INTEGER + default 562 - minimum discovered Path MTU + +mtu_expires - INTEGER + Time, in seconds, that cached PMTU information is kept. + +min_adv_mss - INTEGER + The advertised MSS depends on the first hop route MTU, but will + never be lower than this setting. + IP Fragmentation: ipfrag_high_thresh - INTEGER @@ -345,6 +355,20 @@ conections. Default: 7 + +tcp_frto - BOOLEAN + Enables F-RTO, an enhanced recovery algorithm for TCP retransmission + timeouts. It is particularly beneficial in wireless environments + where packet loss is typically due to random radio interference + rather than intermediate router congestion. + +somaxconn - INTEGER + Limit of socket listen() backlog, known in userspace as SOMAXCONN. + Defaults to 128. See also tcp_max_syn_backlog for additional tuning + for TCP sockets. + +IP Variables: + ip_local_port_range - 2 INTEGERS Defines the local port range that is used by TCP and UDP to choose the local port. The first number is the first, the @@ -586,6 +610,19 @@ The max value from conf/{all,interface}/arp_ignore is used when ARP request is received on the {interface} +app_solicit - INTEGER + The maximum number of probes to send to the user space ARP daemon + via netlink before dropping back to multicast probes (see + mcast_solicit). Defaults to 0. + +disable_policy - BOOLEAN + Disable IPSEC policy (SPD) for this interface + +disable_xfrm - BOOLEAN + Disable IPSEC encryption on this interface, whatever the policy + + + tag - INTEGER Allows you to write a number, which can be used as required. Default value is 0. @@ -678,9 +715,11 @@ disabled if local forwarding is enabled. autoconf - BOOLEAN - Configure link-local addresses using L2 hardware addresses. + Autoconfigure addresses using Prefix Information in Router + Advertisements. - Default: TRUE + Functional default: enabled if accept_ra is enabled. + disabled if accept_ra is disabled. dad_transmits - INTEGER The amount of Duplicate Address Detection probes to send. @@ -803,5 +842,26 @@ 0 : disable this. Default: 1 + +UNDOCUMENTED: + +dev_weight FIXME +discovery_slots FIXME +discovery_timeout FIXME +fast_poll_increase FIXME +ip6_queue_maxlen FIXME +lap_keepalive_time FIXME +lo_cong FIXME +max_baud_rate FIXME +max_dgram_qlen FIXME +max_noreply_time FIXME +max_tx_data_size FIXME +max_tx_window FIXME +min_tx_turn_time FIXME +mod_cong FIXME +no_cong FIXME +no_cong_thresh FIXME +slot_timeout FIXME +warn_noreply_time FIXME $Id: ip-sysctl.txt,v 1.20 2001/12/13 09:00:18 davem Exp $ diff -Nru a/Documentation/pci.txt b/Documentation/pci.txt --- a/Documentation/pci.txt 2004-06-26 17:09:18 -07:00 +++ b/Documentation/pci.txt 2004-06-26 17:09:18 -07:00 @@ -166,8 +166,9 @@ ~~~~~~~~~~~~~~~~~~~ Before you do anything with the device you've found, you need to enable it by calling pci_enable_device() which enables I/O and memory regions of -the device, assigns missing resources if needed and wakes up the device -if it was in suspended state. Please note that this function can fail. +the device, allocates an IRQ if necessary, assigns missing resources if +needed and wakes up the device if it was in suspended state. Please note +that this function can fail. If you want to use the device in bus mastering mode, call pci_set_master() which enables the bus master bit in PCI_COMMAND register and also fixes diff -Nru a/Documentation/power/pci.txt b/Documentation/power/pci.txt --- a/Documentation/power/pci.txt 2004-06-26 17:09:20 -07:00 +++ b/Documentation/power/pci.txt 2004-06-26 17:09:20 -07:00 @@ -286,11 +286,11 @@ +------------------+ | Bit | State | +------------------+ -| 15 | D0 | -| 14 | D1 | +| 11 | D0 | +| 12 | D1 | | 13 | D2 | -| 12 | D3hot | -| 11 | D3cold | +| 14 | D3hot | +| 15 | D3cold | +------------------+ A device can use this to enable wake events: diff -Nru a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt --- a/Documentation/power/swsusp.txt 2004-06-26 17:09:15 -07:00 +++ b/Documentation/power/swsusp.txt 2004-06-26 17:09:15 -07:00 @@ -12,6 +12,9 @@ * ...you'd better find out how to get along * without your data. * + * If you change kernel command line between suspend and resume... + * ...prepare for nasty fsck or worse. + * * (*) pm interface support is needed to make it safe. You need to append resume=/dev/your_swap_partition to kernel command diff -Nru a/Documentation/power/video.txt b/Documentation/power/video.txt --- a/Documentation/power/video.txt 2004-06-26 17:09:18 -07:00 +++ b/Documentation/power/video.txt 2004-06-26 17:09:18 -07:00 @@ -30,10 +30,6 @@ patched X, and plain text console (no vesafb or radeonfb), see http://www.doesi.gmxhome.de/linux/tm800s3/s3.html. (Acer TM 800) -* radeon systems, where X can soft-boot your video card. You'll need - patched X, and plain text console (no vesafb or radeonfb), see - http://www.doesi.gmxhome.de/linux/tm800s3/s3.html. (Acer TM 800) - Now, if you pass acpi_sleep=something, and it does not work with your bios, you'll get hard crash during resume. Be carefull. diff -Nru a/Documentation/sh/new-machine.txt b/Documentation/sh/new-machine.txt --- a/Documentation/sh/new-machine.txt 2004-06-26 17:09:19 -07:00 +++ b/Documentation/sh/new-machine.txt 2004-06-26 17:09:19 -07:00 @@ -188,13 +188,7 @@ - add a new file include/asm-sh/vapor/io.h which contains prototypes for any machine specific IO functions prefixed with the machine name, for example vapor_inb. These will be needed when filling out the machine - vector. In addition, a section is required which defines what to do when - building a machine specific version. For example: - - #ifdef __WANT_IO_DEF - #define inb vapor_inb - ... - #endif + vector. This is the minimum that is required, however there are ample opportunities to optimise this. In particular, by making the prototypes diff -Nru a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt --- a/Documentation/sysctl/vm.txt 2004-06-26 17:09:19 -07:00 +++ b/Documentation/sysctl/vm.txt 2004-06-26 17:09:19 -07:00 @@ -28,7 +28,7 @@ ============================================================== dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, -dirty_writeback_centisecs: +dirty_writeback_centisecs, vfs_cache_pressure: See Documentation/filesystems/proc.txt diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS 2004-06-26 17:09:18 -07:00 +++ b/MAINTAINERS 2004-06-26 17:09:18 -07:00 @@ -90,6 +90,20 @@ L: linux-net@vger.kernel.org S: Maintained +3W-XXXX ATA-RAID CONTROLLER DRIVER +P: Adam Radford +M: linuxraid@amcc.com +L: linux-scsi@vger.kernel.org +W: http://www.amcc.com +S: Supported + +3W-9XXX SATA-RAID CONTROLLER DRIVER +P: Adam Radford +M: linuxraid@amcc.com +L: linux-scsi@vger.kernel.org +W: http://www.amcc.com +S: Supported + 53C700 AND 53C700-66 SCSI DRIVER P: James E.J. Bottomley M: James.Bottomley@HansenPartnership.com @@ -689,6 +703,12 @@ L: blinux-list@redhat.com S: Maintained +DRIVER CORE, KOBJECTS, AND SYSFS +P: Greg Kroah-Hartman +M: greg@kroah.com +L: linux-kernel@vger.kernel.org +S: Supported + DRM DRIVERS L: dri-devel@lists.sourceforge.net S: Supported @@ -1250,6 +1270,20 @@ W: http://www.linuxppc.org/ L: linuxppc-dev@lists.linuxppc.org S: Maintained + +LINUX FOR POWERPC EMBEDDED PPC4XX +P: Matt Porter +M: mporter@kernel.crashing.org +W: http://www.penguinppc.org/ +L: linuxppc-embedded@lists.linuxppc.org +S: Maintained + +LINUX FOR POWERPC EMBEDDED PPC85XX +P: Kumar Gala +M: kumar.gala@freescale.com +W: http://www.penguinppc.org/ +L: linuxppc-embedded@lists.linuxppc.org +S: Maintained LLC (802.2) P: Arnaldo Carvalho de Melo diff -Nru a/Makefile b/Makefile --- a/Makefile 2004-06-26 17:09:19 -07:00 +++ b/Makefile 2004-06-26 17:09:19 -07:00 @@ -290,8 +290,6 @@ OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump AWK = awk -RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \ - else echo rpm; fi) GENKSYMS = scripts/genksyms/genksyms DEPMOD = /sbin/depmod KALLSYMS = scripts/kallsyms @@ -409,13 +407,6 @@ scripts_basic: include/linux/autoconf.h - -# That's our default target when none is given on the command line -# Note that 'modules' will be added as a prerequisite as well, -# in the CONFIG_MODULES part below - -all: vmlinux - # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ drivers-y := drivers/ sound/ @@ -449,6 +440,19 @@ include $(srctree)/arch/$(ARCH)/Makefile +# Default kernel image to build when no specific target is given. +# KBUILD_IMAGE may be overruled on the commandline or +# set in the environment +# Also any assingments in arch/$(ARCH)/Makefiel take precedence over +# this default value +export KBUILD_IMAGE ?= vmlinux + +# The all: target is the default when no target is given on the +# command line. +# This allow a user to issue only 'make' to build a kernel including modules +# Defaults vmlinux but it is usually overriden in the arch makefile +all: vmlinux + ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE CFLAGS += -Os else @@ -795,7 +799,7 @@ # Directories & files removed with 'make clean' CLEAN_DIRS += $(MODVERDIR) -CLEAN_FILES += vmlinux System.map kernel.spec \ +CLEAN_FILES += vmlinux System.map \ .tmp_kallsyms* .tmp_version .tmp_vmlinux* # Directories & files removed with 'make mrproper' @@ -848,37 +852,19 @@ -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \ -type f -print | xargs rm -f -# RPM target -# --------------------------------------------------------------------------- - -.PHONY: rpm -# Remove hyphens since they have special meaning in RPM filenames -KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE)) +# Packaging of the kernel to various formats +# --------------------------------------------------------------------------- +# rpm target kept for backward compatibility +package-dir := $(srctree)/scripts/package -# If you do a make spec before packing the tarball you can rpm -ta it +.PHONY: %-pkg rpm -spec: - $(CONFIG_SHELL) $(srctree)/scripts/mkspec > $(objtree)/kernel.spec - -# a) Build a tar ball -# b) generate an rpm from it -# c) and pack the result -# - Use /. to avoid tar packing just the symlink - -rpm: clean spec - set -e; \ - cd .. ; \ - ln -sf $(srctree) $(KERNELPATH) ; \ - tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \ - rm $(KERNELPATH) - - set -e; \ - $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version;\ - mv -f $(objtree)/.tmp_version $(objtree)/.version; +%pkg: FORCE + $(Q)$(MAKE) -f $(package-dir)/Makefile $@ +rpm: FORCE + $(Q)$(MAKE) -f $(package-dir)/Makefile $@ - $(RPM) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz - rm ../$(KERNELPATH).tar.gz # Brief documentation of the typical targets used # --------------------------------------------------------------------------- @@ -905,6 +891,8 @@ @echo ' tags/TAGS - Generate tags file for editors' @echo ' cscope - Generate cscope index' @echo ' checkstack - Generate a list of stack hogs' + @echo 'Kernel packaging:' + @$(MAKE) -f $(package-dir)/Makefile help @echo '' @echo 'Documentation targets:' @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp diff -Nru a/arch/alpha/kernel/init_task.c b/arch/alpha/kernel/init_task.c --- a/arch/alpha/kernel/init_task.c 2004-06-26 17:09:16 -07:00 +++ b/arch/alpha/kernel/init_task.c 2004-06-26 17:09:16 -07:00 @@ -4,6 +4,7 @@ #include #include #include +#include #include diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c --- a/arch/alpha/kernel/irq.c 2004-06-26 17:09:19 -07:00 +++ b/arch/alpha/kernel/irq.c 2004-06-26 17:09:19 -07:00 @@ -227,7 +227,7 @@ #ifdef CONFIG_SMP static struct proc_dir_entry * smp_affinity_entry[NR_IRQS]; static char irq_user_affinity[NR_IRQS]; -static unsigned long irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; static void select_smp_affinity(int irq) @@ -238,16 +238,14 @@ if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) return; - while (((cpu_present_mask >> cpu) & 1) == 0) + while (!cpu_possible(cpu)) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - irq_affinity[irq] = 1UL << cpu; - irq_desc[irq].handler->set_affinity(irq, 1UL << cpu); + irq_affinity[irq] = cpumask_of_cpu(cpu); + irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); } -#define HEX_DIGITS 16 - static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) @@ -259,67 +257,28 @@ return len; } -static unsigned int -parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) -{ - unsigned char hexnum [HEX_DIGITS]; - unsigned long value; - unsigned long i; - - if (!count) - return -EINVAL; - if (count > HEX_DIGITS) - count = HEX_DIGITS; - if (copy_from_user(hexnum, buffer, count)) - return -EFAULT; - - /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. - */ - value = 0; - - for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; - - switch (c) { - case '0' ... '9': c -= '0'; break; - case 'a' ... 'f': c -= 'a'-10; break; - case 'A' ... 'F': c -= 'A'-10; break; - default: - goto out; - } - value = (value << 4) | c; - } -out: - *ret = value; - return 0; -} - static int irq_affinity_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value; + cpumask_t new_value; if (!irq_desc[irq].handler->set_affinity) return -EIO; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); /* The special value 0 means release control of the affinity to kernel. */ - if (new_value == 0) { + cpus_and(new_value, new_value, cpu_online_map); + if (cpus_empty(new_value)) { irq_user_affinity[irq] = 0; select_smp_affinity(irq); } /* Do not allow disabling IRQs completely - it's a too easy way to make the system unusable accidentally :-) At least one online CPU still has to be targeted. */ - else if (!(new_value & cpu_present_mask)) - return -EINVAL; else { irq_affinity[irq] = new_value; irq_user_affinity[irq] = 1; @@ -344,10 +303,10 @@ prof_cpu_mask_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + unsigned long full_count = count, err; + cpumask_t new_value, *mask = (cpumask_t *)data; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); if (err) return err; @@ -457,7 +416,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c --- a/arch/alpha/kernel/process.c 2004-06-26 17:09:20 -07:00 +++ b/arch/alpha/kernel/process.c 2004-06-26 17:09:20 -07:00 @@ -119,8 +119,8 @@ #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - clear_bit(boot_cpuid, &cpu_present_mask); - while (cpu_present_mask) + cpu_clear(boot_cpuid, cpu_possible_map); + while (cpus_weight(cpu_possible_map)) barrier(); #endif diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c --- a/arch/alpha/kernel/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/alpha/kernel/setup.c 2004-06-26 17:09:16 -07:00 @@ -122,7 +122,6 @@ static void determine_cpu_caches (unsigned int); static char command_line[COMMAND_LINE_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; /* * The format of "screen_info" is strange, and due to early @@ -1246,9 +1245,9 @@ platform_string(), nr_processors); #ifdef CONFIG_SMP - seq_printf(f, "cpus active\t\t: %ld\n" + seq_printf(f, "cpus active\t\t: %d\n" "cpu active mask\t\t: %016lx\n", - num_online_cpus(), cpu_present_mask); + num_online_cpus(), cpus_addr(cpu_possible_map)[0]); #endif show_cache_size (f, "L1 Icache", alpha_l1i_cacheshape); diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c --- a/arch/alpha/kernel/smp.c 2004-06-26 17:09:16 -07:00 +++ b/arch/alpha/kernel/smp.c 2004-06-26 17:09:16 -07:00 @@ -68,7 +68,7 @@ static int smp_secondary_alive __initdata = 0; /* Which cpus ids came online. */ -unsigned long cpu_present_mask; +cpumask_t cpu_present_mask; cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); @@ -522,7 +522,7 @@ smp_num_probed = 1; hwrpb_cpu_present_mask = (1UL << boot_cpuid); } - cpu_present_mask = 1UL << boot_cpuid; + cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", smp_num_probed, hwrpb_cpu_present_mask); @@ -547,7 +547,7 @@ /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - cpu_present_mask = 1UL << boot_cpuid; + cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } @@ -562,7 +562,7 @@ if (((hwrpb_cpu_present_mask >> i) & 1) == 0) continue; - cpu_present_mask |= 1UL << i; + cpu_set(i, cpu_possible_map); cpu_count++; } @@ -597,7 +597,7 @@ if (cpu_online(cpu)) bogosum += cpu_data[cpu].loops_per_jiffy; - printk(KERN_INFO "SMP: Total of %ld processors activated " + printk(KERN_INFO "SMP: Total of %d processors activated " "(%lu.%02lu BogoMIPS).\n", num_online_cpus(), (bogosum + 2500) / (500000/HZ), @@ -638,23 +638,17 @@ static void -send_ipi_message(unsigned long to_whom, enum ipi_message_type operation) +send_ipi_message(cpumask_t to_whom, enum ipi_message_type operation) { - unsigned long i, set, n; + int i; mb(); - for (i = to_whom; i ; i &= ~set) { - set = i & -i; - n = __ffs(set); - set_bit(operation, &ipi_data[n].bits); - } + for_each_cpu_mask(i, to_whom) + set_bit(operation, &ipi_data[i].bits); mb(); - for (i = to_whom; i ; i &= ~set) { - set = i & -i; - n = __ffs(set); - wripir(n); - } + for_each_cpu_mask(i, to_whom) + wripir(i); } /* Structure and data for smp_call_function. This is designed to @@ -784,13 +778,14 @@ printk(KERN_WARNING "smp_send_reschedule: Sending IPI to self.\n"); #endif - send_ipi_message(1UL << cpu, IPI_RESCHEDULE); + send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); } void smp_send_stop(void) { - unsigned long to_whom = cpu_present_mask & ~(1UL << smp_processor_id()); + cpumask_t to_whom = cpu_possible_map; + cpu_clear(smp_processor_id(), to_whom); #ifdef DEBUG_IPI_MSG if (hard_smp_processor_id() != boot_cpu_id) printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n"); @@ -814,7 +809,7 @@ int smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, - int wait, unsigned long to_whom) + int wait, cpumask_t to_whom) { struct smp_call_struct data; unsigned long timeout; @@ -827,8 +822,8 @@ data.info = info; data.wait = wait; - to_whom &= ~(1L << smp_processor_id()); - num_cpus_to_call = hweight64(to_whom); + cpu_clear(smp_processor_id(), to_whom); + num_cpus_to_call = cpus_weight(to_whom); atomic_set(&data.unstarted_count, num_cpus_to_call); atomic_set(&data.unfinished_count, num_cpus_to_call); diff -Nru a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c --- a/arch/alpha/kernel/sys_dp264.c 2004-06-26 17:09:16 -07:00 +++ b/arch/alpha/kernel/sys_dp264.c 2004-06-26 17:09:16 -07:00 @@ -53,7 +53,6 @@ register int bcpu = boot_cpuid; #ifdef CONFIG_SMP - register unsigned long cpm = cpu_present_mask; volatile unsigned long *dim0, *dim1, *dim2, *dim3; unsigned long mask0, mask1, mask2, mask3, dummy; @@ -72,10 +71,10 @@ dim1 = &cchip->dim1.csr; dim2 = &cchip->dim2.csr; dim3 = &cchip->dim3.csr; - if ((cpm & 1) == 0) dim0 = &dummy; - if ((cpm & 2) == 0) dim1 = &dummy; - if ((cpm & 4) == 0) dim2 = &dummy; - if ((cpm & 8) == 0) dim3 = &dummy; + if (cpu_possible(0)) dim0 = &dummy; + if (cpu_possible(1)) dim1 = &dummy; + if (cpu_possible(2)) dim2 = &dummy; + if (cpu_possible(3)) dim3 = &dummy; *dim0 = mask0; *dim1 = mask1; @@ -164,13 +163,13 @@ } static void -cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) +cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) { int cpu; for (cpu = 0; cpu < 4; cpu++) { unsigned long aff = cpu_irq_affinity[cpu]; - if (affinity & (1UL << cpu)) + if (cpu_isset(cpu, affinity)) aff |= 1UL << irq; else aff &= ~(1UL << irq); @@ -179,7 +178,7 @@ } static void -dp264_set_affinity(unsigned int irq, unsigned long affinity) +dp264_set_affinity(unsigned int irq, cpumask_t affinity) { spin_lock(&dp264_irq_lock); cpu_set_irq_affinity(irq, affinity); @@ -188,7 +187,7 @@ } static void -clipper_set_affinity(unsigned int irq, unsigned long affinity) +clipper_set_affinity(unsigned int irq, cpumask_t affinity) { spin_lock(&dp264_irq_lock); cpu_set_irq_affinity(irq - 16, affinity); diff -Nru a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c --- a/arch/alpha/mm/init.c 2004-06-26 17:09:20 -07:00 +++ b/arch/alpha/mm/init.c 2004-06-26 17:09:20 -07:00 @@ -106,7 +106,7 @@ printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff -Nru a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c --- a/arch/alpha/mm/numa.c 2004-06-26 17:09:15 -07:00 +++ b/arch/alpha/mm/numa.c 2004-06-26 17:09:15 -07:00 @@ -279,8 +279,8 @@ initrd_end, phys_to_virt(PFN_PHYS(max_low_pfn))); } else { - nid = NODE_DATA(kvaddr_to_nid(initrd_start)); - reserve_bootmem_node(nid, + nid = kvaddr_to_nid(initrd_start); + reserve_bootmem_node(NODE_DATA(nid), virt_to_phys((void *)initrd_start), INITRD_SIZE); } @@ -371,7 +371,7 @@ printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for (nid = 0; nid < numnodes; nid++) { struct page * lmem_map = node_mem_map(nid); i = node_spanned_pages(nid); diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig --- a/arch/arm/Kconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/Kconfig 2004-06-26 17:09:18 -07:00 @@ -72,9 +72,6 @@ prompt "ARM system type" default ARCH_RPC -config ARCH_ADIFCC - bool "ADIFCC-based" - config ARCH_CLPS7500 bool "Cirrus-CL-PS7500FE" @@ -191,6 +188,11 @@ depends on ARCH_RPC default y +config TIMER_ACORN + bool + depends on ARCH_ACORN || ARCH_CLPS7500 + default y + ##################################################################### # Footbridge support config FOOTBRIDGE @@ -246,10 +248,10 @@ # Select various configuration options depending on the machine type config DISCONTIGMEM bool - depends on ARCH_EDB7211 || ARCH_SA1100 || ARCH_LH7A40X + depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_SROMLL) default y help - Say Y to upport efficient handling of discontiguous physical memory, + Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access) or have huge holes in the physical address space for other reasons. See for more. @@ -257,7 +259,7 @@ # Now handle the bus types config PCI bool "PCI support" if ARCH_INTEGRATOR_AP - default y if ARCH_FTVPCI || ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX + default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside @@ -270,11 +272,6 @@ doesn't. # Select the host bridge type -config PCI_HOST_PLX90X0 - bool - depends on PCI && ARCH_FTVPCI - default y - config PCI_HOST_VIA82C505 bool depends on PCI && ARCH_SHARK @@ -421,6 +418,17 @@ If you do not feel you need a faster FP emulation you should better choose NWFPE. +config VFP + bool "VFP-format floating point maths" + help + Say Y to include VFP support code in the kernel. This is needed + if your hardware includes a VFP unit. + + Please see for + release notes and additional status information. + + Say N if your target does not have VFP hardware. + source "fs/Kconfig.binfmt" source "drivers/base/Kconfig" @@ -539,7 +547,7 @@ config LEDS bool "Timer and CPU usage LEDs" - depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_FTVPCI || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB + depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB help If you say Y here, the LEDs on your machine will be used to provide useful information about your current system status. @@ -553,7 +561,7 @@ config LEDS_TIMER bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB) - depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_FTVPCI || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB + depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB default y if ARCH_EBSA110 help If you say Y here, one of the system LEDs (the green one on the @@ -609,7 +617,7 @@ source "net/Kconfig" -if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_FTVPCI || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE +if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE source "drivers/ide/Kconfig" endif diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile --- a/arch/arm/Makefile 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/Makefile 2004-06-26 17:09:17 -07:00 @@ -74,9 +74,6 @@ textaddr-$(CONFIG_ARCH_CO285) := 0x60008000 machine-$(CONFIG_ARCH_CO285) := footbridge incdir-$(CONFIG_ARCH_CO285) := ebsa285 - machine-$(CONFIG_ARCH_FTVPCI) := ftvpci - incdir-$(CONFIG_ARCH_FTVPCI) := nexuspci - machine-$(CONFIG_ARCH_TBOX) := tbox machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SA1100) := sa1100 ifeq ($(CONFIG_ARCH_SA1100),y) @@ -91,7 +88,6 @@ machine-$(CONFIG_ARCH_CLPS711X) := clps711x textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 machine-$(CONFIG_ARCH_IOP3XX) := iop3xx - machine-$(CONFIG_ARCH_ADIFCC) := adifcc machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_OMAP) := omap machine-$(CONFIG_ARCH_S3C2410) := s3c2410 @@ -119,6 +115,7 @@ endif core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) +core-$(CONFIG_VFP) += arch/arm/vfp/ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/ diff -Nru a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile --- a/arch/arm/boot/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/boot/Makefile 2004-06-26 17:09:15 -07:00 @@ -49,8 +49,6 @@ zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000 zreladdr-$(CONFIG_ARCH_IOP3XX) := 0xa0008000 params_phys-$(CONFIG_ARCH_IOP3XX) := 0xa0000100 - zreladdr-$(CONFIG_ARCH_ADIFCC) := 0xc0008000 -params_phys-$(CONFIG_ARCH_ADIFCC) := 0xc0000100 zreladdr-$(CONFIG_ARCH_IXP4XX) := 0x00008000 params-phys-$(CONFIG_ARCH_IXP4XX) := 0x00000100 zreladdr-$(CONFIG_ARCH_OMAP) := 0x10008000 diff -Nru a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S --- a/arch/arm/boot/compressed/head-xscale.S 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/boot/compressed/head-xscale.S 2004-06-26 17:09:16 -07:00 @@ -66,7 +66,4 @@ mov r7, #MACH_TYPE_IQ80310 #endif -#ifdef CONFIG_ARCH_ADI_EVB - mov r7, #MACH_TYPE_ADI_EVB -#endif diff -Nru a/arch/arm/common/Makefile b/arch/arm/common/Makefile --- a/arch/arm/common/Makefile 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/common/Makefile 2004-06-26 17:09:17 -07:00 @@ -2,10 +2,9 @@ # Makefile for the linux kernel. # -obj-y += platform.o obj-$(CONFIG_ARM_AMBA) += amba.o obj-$(CONFIG_ICST525) += icst525.o obj-$(CONFIG_SA1111) += sa1111.o -obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o +obj-$(CONFIG_TIMER_ACORN) += time-acorn.o diff -Nru a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c --- a/arch/arm/common/dmabounce.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/common/dmabounce.c 2004-06-26 17:09:15 -07:00 @@ -234,7 +234,7 @@ } } - dma_addr = virt_to_bus(ptr); + dma_addr = virt_to_dma(dev, ptr); if (device_info && dma_needs_bounce(dev, dma_addr, size)) { struct safe_buffer *buf; @@ -248,7 +248,7 @@ dev_dbg(dev, "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", - __func__, buf->ptr, (void *) virt_to_bus(buf->ptr), + __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr), buf->safe, (void *) buf->safe_dma_addr); if ((dir == DMA_TO_DEVICE) || @@ -290,7 +290,7 @@ dev_dbg(dev, "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", - __func__, buf->ptr, (void *) virt_to_bus(buf->ptr), + __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr), buf->safe, (void *) buf->safe_dma_addr); @@ -342,7 +342,7 @@ dev_dbg(dev, "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", - __func__, buf->ptr, (void *) virt_to_bus(buf->ptr), + __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr), buf->safe, (void *) buf->safe_dma_addr); DO_STATS ( device_info->bounce_count++ ); @@ -367,7 +367,7 @@ } consistent_sync(buf->safe, size, dir); } else { - consistent_sync(bus_to_virt(dma_addr), size, dir); + consistent_sync(dma_to_virt(dev, dma_addr), size, dir); } } diff -Nru a/arch/arm/common/platform.c b/arch/arm/common/platform.c --- a/arch/arm/common/platform.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,35 +0,0 @@ -#include -#include -#include - -int __init platform_add_device(struct platform_device *dev) -{ - int i; - - for (i = 0; i < dev->num_resources; i++) { - struct resource *r = &dev->resource[i]; - - r->name = dev->dev.bus_id; - - if (r->flags & IORESOURCE_MEM && - request_resource(&iomem_resource, r)) { - printk(KERN_ERR - "%s%d: failed to claim resource %d\n", - dev->name, dev->id, i); - break; - } - } - if (i == dev->num_resources) - platform_device_register(dev); - return 0; -} - -int __init platform_add_devices(struct platform_device **devs, int num) -{ - int i; - - for (i = 0; i < num; i++) - platform_add_device(devs[i]); - - return 0; -} diff -Nru a/arch/arm/common/plx90x0.c b/arch/arm/common/plx90x0.c --- a/arch/arm/common/plx90x0.c 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,178 +0,0 @@ -/* - * Driver for PLX Technology PCI9000-series host bridge. - * - * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs Ltd - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * Since the following functions are all very similar, the common parts - * are pulled out into these macros. - */ - -#define PLX_CLEAR_CONFIG \ - __raw_writel(0, PLX_BASE + 0xac); \ - local_irq_restore(flags); } - -#define PLX_SET_CONFIG \ - { unsigned long flags; \ - local_irq_save(flags); \ - __raw_writel((1<<31 | (bus->number << 16) \ - | (devfn << 8) | (where & ~3) \ - | ((bus->number == 0)?0:1)), PLX_BASE + 0xac); \ - -#define PLX_CONFIG_WRITE(size) \ - PLX_SET_CONFIG \ - __raw_write##size(value, PCIO_BASE + (where & 3)); \ - if (__raw_readw(PLX_BASE + 0x6) & 0x2000) \ - __raw_writew(0x2000, PLX_BASE + 0x6); \ - PLX_CLEAR_CONFIG \ - return PCIBIOS_SUCCESSFUL; - -#define PLX_CONFIG_READ(size) \ - PLX_SET_CONFIG \ - *value = __raw_read##size(PCIO_BASE + (where & 3)); \ - if (__raw_readw(PLX_BASE + 0x6) & 0x2000) { \ - __raw_writew(0x2000, PLX_BASE + 0x6); \ - *value = 0xffffffffUL; \ - } \ - PLX_CLEAR_CONFIG \ - return PCIBIOS_SUCCESSFUL; - -/* Configuration space access routines */ - -static int -plx90x0_read_config (struct pci_bus *bus, unsigned int devfn, int where, - int where, int size, u32 *value) -{ - switch (size) { - case 1: - PLX_CONFIG_READ(b) - break; - case 2: - PLX_CONFIG_READ(w) - break; - case 4: - PLX_CONFIG_READ(l) - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int -plx90x0_write_config (struct pci_bus *bus, unsigned int devfn, int where, - int where, int size, u32 value) -{ - switch (size) { - case 1: - PLX_CONFIG_WRITE(b) - break; - case 2: - PLX_CONFIG_WRITE(w) - break; - case 4: - PLX_CONFIG_WRITE(l) - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops plx90x0_ops = -{ - .read = plx90x0_read_config, - .write = plx90x0_write_config, -}; - -static void -plx_syserr_handler(int irq, void *handle, struct pt_regs *regs) -{ - printk("PLX90x0: machine check %04x (pc=%08lx)\n", - readw(PLX_BASE + 6), regs->ARM_pc); - __raw_writew(0xf000, PLX_BASE + 6); -} - -/* - * Initialise the PCI system. - */ - -void __init -plx90x0_init(struct arm_sysdata *sysdata) -{ - static const unsigned long int base = PLX_BASE; - char *what; - unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET); - - /* Have a sniff around and see which PLX device is present. */ - unsigned long id = __raw_readl(base + 0xf0); - -#if 0 - /* This check was a good idea, but can fail. The PLX9060 puts no - default value in these registers unless NB# is asserted (which it - isn't on these cards). */ - if ((id & 0xffff) != PCI_VENDOR_ID_PLX) - return; /* Nothing found */ -#endif - - /* Found one - now work out what it is. */ - switch (id >> 16) { - case 0: /* PCI_DEVICE_ID_PLX_9060 */ - what = "PCI9060"; - break; - case PCI_DEVICE_ID_PLX_9060ES: - what = "PCI9060ES"; - break; - case PCI_DEVICE_ID_PLX_9060SD: - what = "PCI9060SD"; /* uhuhh.. */ - break; - case PCI_DEVICE_ID_PLX_9080: - what = "PCI9080"; - break; - default: - printk("PCI: Unknown PLX device %04lx found -- ignored.\n", - id >> 16); - return; - } - - printk("PCI: PLX Technology %s host bridge found.\n", what); - - /* Now set it up for both master and slave accesses. */ - __raw_writel(0xffff0147, base + 0x4); - __raw_writeb(32, base + 0xd); - __raw_writel(0x8 | bar, base + 0x18); - __raw_writel(0xf8000008, base + 0x80); - __raw_writel(0x40000001, base + 0x84); - __raw_writel(0, base + 0x88); - __raw_writel(0, base + 0x8c); - __raw_writel(0x11, base + 0x94); - __raw_writel(0xC3 + (4 << 28) - + (8 << 11) + (1 << 10) - + (1 << 24), base + 0x98); - __raw_writel(0xC0000000, base + 0x9c); - __raw_writel(PLX_MEM_START, base + 0xa0); - __raw_writel(PLX_IO_START, base + 0xa4); - __raw_writel(0x3, base + 0xa8); - __raw_writel(0, base + 0xac); - __raw_writel(0x10001, base + 0xe8); - __raw_writel(0x8000767e, base + 0xec); - - request_irq(IRQ_SYSERR, plx_syserr_handler, 0, - "system error", NULL); - - pci_scan_bus(0, &plx90x0_ops, sysdata); -} diff -Nru a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c --- a/arch/arm/common/sa1111.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/common/sa1111.c 2004-06-26 17:09:20 -07:00 @@ -610,7 +610,7 @@ * %-EBUSY physical address already marked in-use. * %0 successful. */ -static int __init +static int __sa1111_probe(struct device *me, struct resource *mem, int irq) { struct sa1111 *sachip; diff -Nru a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/common/time-acorn.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,67 @@ +/* + * linux/arch/arm/common/time-acorn.c + * + * Copyright (c) 1996-2000 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 24-Sep-1996 RMK Created + * 10-Oct-1996 RMK Brought up to date with arch-sa110eval + * 04-Dec-1997 RMK Updated for new arch/arm/time.c + * 13=Jun-2004 DS Moved to arch/arm/common b/c shared w/CLPS7500 + */ +#include +#include + +#include +#include +#include + +#include + +static unsigned long ioctime_gettimeoffset(void) +{ + unsigned int count1, count2, status; + long offset; + + ioc_writeb (0, IOC_T0LATCH); + barrier (); + count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); + barrier (); + status = ioc_readb(IOC_IRQREQA); + barrier (); + ioc_writeb (0, IOC_T0LATCH); + barrier (); + count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); + + offset = count2; + if (count2 < count1) { + /* + * We have not had an interrupt between reading count1 + * and count2. + */ + if (status & (1 << 5)) + offset -= LATCH; + } else if (count2 > count1) { + /* + * We have just had another interrupt between reading + * count1 and count2. + */ + offset -= LATCH; + } + + offset = (LATCH - offset) * (tick_nsec / 1000); + return (offset + LATCH/2) / LATCH; +} + +void __init ioctime_init(void) +{ + ioc_writeb(LATCH & 255, IOC_T0LTCHL); + ioc_writeb(LATCH >> 8, IOC_T0LTCHH); + ioc_writeb(0, IOC_T0GO); + + gettimeoffset = ioctime_gettimeoffset; +} diff -Nru a/arch/arm/configs/adi_evb_defconfig b/arch/arm/configs/adi_evb_defconfig --- a/arch/arm/configs/adi_evb_defconfig 2004-06-26 17:09:18 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,678 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_ARM=y -# CONFIG_EISA is not set -# CONFIG_SBUS is not set -# CONFIG_MCA is not set -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_GENERIC_BUST_SPINLOCK is not set -# CONFIG_GENERIC_ISA_DMA is not set - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -# CONFIG_OBSOLETE is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set - -# -# System Type -# -CONFIG_ARCH_ADIFCC=y -# CONFIG_ARCH_ARCA5K is not set -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP310 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_SHARK is not set - -# -# Archimedes/A5000 Implementations -# -# CONFIG_ARCH_ARC is not set -# CONFIG_ARCH_A5K is not set - -# -# Footbridge Implementations -# -# CONFIG_ARCH_CATS is not set -# CONFIG_ARCH_PERSONAL_SERVER is not set -# CONFIG_ARCH_EBSA285_ADDIN is not set -# CONFIG_ARCH_EBSA285_HOST is not set -# CONFIG_ARCH_NETWINDER is not set - -# -# SA11x0 Implementations -# -# CONFIG_SA1100_ASSABET is not set -# CONFIG_ASSABET_NEPONSET is not set -# CONFIG_SA1100_ADSBITSY is not set -# CONFIG_SA1100_BRUTUS is not set -# CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_H3600 is not set -# CONFIG_SA1100_EXTENEX1 is not set -# CONFIG_SA1100_FLEXANET is not set -# CONFIG_SA1100_FREEBIRD is not set -# CONFIG_SA1100_GRAPHICSCLIENT is not set -# CONFIG_SA1100_GRAPHICSMASTER is not set -# CONFIG_SA1100_JORNADA720 is not set -# CONFIG_SA1100_HUW_WEBPANEL is not set -# CONFIG_SA1100_ITSY is not set -# CONFIG_SA1100_LART is not set -# CONFIG_SA1100_NANOENGINE is not set -# CONFIG_SA1100_OMNIMETER is not set -# CONFIG_SA1100_PANGOLIN is not set -# CONFIG_SA1100_PLEB is not set -# CONFIG_SA1100_SHERMAN is not set -# CONFIG_SA1100_SIMPAD is not set -# CONFIG_SA1100_PFS168 is not set -# CONFIG_SA1100_VICTOR is not set -# CONFIG_SA1100_XP860 is not set -# CONFIG_SA1100_YOPY is not set -# CONFIG_SA1100_USB is not set -# CONFIG_SA1100_USB_NETLINK is not set -# CONFIG_SA1100_USB_CHAR is not set - -# -# CLPS711X/EP721X Implementations -# -# CONFIG_ARCH_CDB89712 is not set -# CONFIG_ARCH_CLEP7312 is not set -# CONFIG_ARCH_EDB7211 is not set -# CONFIG_ARCH_P720T is not set -# CONFIG_ARCH_EP7211 is not set -# CONFIG_ARCH_EP7212 is not set -CONFIG_ARCH_ADI_EVB=y -CONFIG_XSCALE_PMU_TIMER=y -# CONFIG_ARCH_ACORN is not set -# CONFIG_FOOTBRIDGE is not set -# CONFIG_FOOTBRIDGE_HOST is not set -# CONFIG_FOOTBRIDGE_ADDIN is not set -CONFIG_CPU_32=y -# CONFIG_CPU_26 is not set -# CONFIG_CPU_32v3 is not set -# CONFIG_CPU_32v4 is not set -# CONFIG_CPU_ARM610 is not set -# CONFIG_CPU_ARM710 is not set -# CONFIG_CPU_ARM720T is not set -# CONFIG_CPU_ARM920T is not set -# CONFIG_CPU_ARM926T is not set -# CONFIG_CPU_ARM1020 is not set -# CONFIG_CPU_SA110 is not set -# CONFIG_CPU_SA1100 is not set -CONFIG_CPU_32v4=y -CONFIG_CPU_XSCALE=y -CONFIG_ARM_THUMB=y -# CONFIG_XSCALE_TOOLS is not set -CONFIG_XSCALE_WRITE_ALLOC=y -CONFIG_XSCALE_PMU=y -CONFIG_ARM_THUMB=y -# CONFIG_DISCONTIGMEM is not set - -# -# General setup -# -# CONFIG_PCI is not set -# CONFIG_ISA is not set -# CONFIG_ISA_DMA is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_NET=y -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_FASTFPE is not set -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set -# CONFIG_ARTHUR is not set -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/mtdblock1 mem=32M initrd=0xc0800000,3M" -CONFIG_ALIGNMENT_TRAP=y - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_BOOTLDR_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set -# CONFIG_MTD_JEDEC is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_NORA is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_CDB89712 is not set -# CONFIG_MTD_SA1100 is not set -# CONFIG_MTD_DC21285 is not set -# CONFIG_MTD_IQ80310 is not set -CONFIG_MTD_ADI_EVB=y -# CONFIG_MTD_PCI is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_DOC1000 is not set -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_INITRD=y - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -# CONFIG_PACKET is not set -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_ARM_AM79C961A is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_AMBA is not set -# CONFIG_SERIAL_AMBA_CONSOLE is not set -# CONFIG_SERIAL_CLPS711X is not set -# CONFIG_SERIAL_CLPS711X_CONSOLE is not set -# CONFIG_SERIAL_21285 is not set -# CONFIG_SERIAL_21285_OLD is not set -# CONFIG_SERIAL_21285_CONSOLE is not set -# CONFIG_SERIAL_UART00 is not set -# CONFIG_SERIAL_UART00_CONSOLE is not set -# CONFIG_SERIAL_SA1100 is not set -# CONFIG_SERIAL_SA1100_CONSOLE is not set -# CONFIG_SERIAL_8250 is not set -# CONFIG_SERIAL_8250_CONSOLE is not set -# CONFIG_SERIAL_8250_EXTENDED is not set -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_SHARE_IRQ is not set -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set -# CONFIG_SERIAL_8250_HUB6 is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# L3 serial bus support -# -# CONFIG_L3 is not set -# CONFIG_L3_ALGOBIT is not set -# CONFIG_L3_BIT_SA1100_GPIO is not set -# CONFIG_L3_SA1111 is not set -# CONFIG_BIT_SA1100_GPIO is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Multimedia Capabilities Port drivers -# -# CONFIG_MCP is not set -# CONFIG_MCP_SA1100 is not set -# CONFIG_MCP_UCB1200 is not set -# CONFIG_MCP_UCB1200_AUDIO is not set -# CONFIG_MCP_UCB1200_TS is not set - -# -# USB support -# -# CONFIG_USB is not set -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set -# CONFIG_USB_OHCI_SA1111 is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set - -# -# Kernel hacking -# -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_INFO is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_NO_PGT_CACHE is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_DC21285_PORT is not set -# CONFIG_DEBUG_CLPS711X_UART2 is not set diff -Nru a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig --- a/arch/arm/configs/mainstone_defconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/configs/mainstone_defconfig 2004-06-26 17:09:18 -07:00 @@ -28,6 +28,7 @@ # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_IOSCHED_NOOP=y @@ -52,44 +53,23 @@ # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set -CONFIG_ARCH_PXA=y # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_CAMELOT is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_PXA=y # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_VERSATILE_PB is not set # -# CLPS711X/EP721X Implementations -# - -# -# Epxa10db -# - -# -# Footbridge Implementations -# - -# -# IOP3xx Implementation Options -# -# CONFIG_ARCH_IOP310 is not set -# CONFIG_ARCH_IOP321 is not set - -# -# IOP3xx Chipset Features -# - -# # Intel PXA2xx Implementations # # CONFIG_ARCH_LUBBOCK is not set @@ -99,34 +79,6 @@ CONFIG_IWMMXT=y # -# SA11x0 Implementations -# - -# -# TI OMAP Implementations -# - -# -# OMAP Core Type -# - -# -# OMAP Board Type -# - -# -# OMAP Feature Selections -# - -# -# S3C2410 Implementations -# - -# -# LH7A40X Implementations -# - -# # Processor Type # CONFIG_CPU_32=y @@ -163,6 +115,7 @@ CONFIG_FPE_NWFPE=y # CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set @@ -170,6 +123,7 @@ # # Generic Driver Options # +CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set # CONFIG_PM is not set @@ -394,7 +348,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=y # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -406,6 +359,7 @@ # IDE chipset support/bugfixes # # CONFIG_IDE_GENERIC is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -571,6 +525,7 @@ CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_VFAT_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 # CONFIG_NTFS_FS is not set # @@ -622,7 +577,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -658,6 +612,7 @@ # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -681,7 +636,10 @@ # # Graphics support # -# CONFIG_FB is not set +CONFIG_FB=y +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_PARAMETERS is not set +# CONFIG_FB_VIRTUAL is not set # # Console display driver support @@ -689,6 +647,19 @@ # CONFIG_VGA_CONSOLE is not set # CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y # # Sound diff -Nru a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile --- a/arch/arm/kernel/Makefile 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/kernel/Makefile 2004-06-26 17:09:20 -07:00 @@ -11,8 +11,7 @@ time.o traps.o obj-$(CONFIG_APM) += apm.o -obj-$(CONFIG_ARCH_ACORN) += ecard.o time-acorn.o -obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o +obj-$(CONFIG_ARCH_ACORN) += ecard.o obj-$(CONFIG_FOOTBRIDGE) += isa.o obj-$(CONFIG_FIQ) += fiq.o obj-$(CONFIG_MODULES) += armksyms.o module.o diff -Nru a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S --- a/arch/arm/kernel/debug.S 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/kernel/debug.S 2004-06-26 17:09:17 -07:00 @@ -439,32 +439,6 @@ #endif .endm -#elif defined(CONFIG_ARCH_ADI_EVB) - - .macro addruart,rx - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 @ MMU enabled? - mov \rx, #0x00400000 @ physical base address - orrne \rx, \rx, #0xff000000 @ virtual base - .endm - - .macro senduart,rd,rx - strb \rd, [\rx] - .endm - - .macro busyuart,rd,rx -1002: ldrb \rd, [\rx, #0x5] - and \rd, \rd, #0x60 - teq \rd, #0x60 - bne 1002b - .endm - - .macro waituart,rd,rx -1001: ldrb \rd, [\rx, #0x6] - tst \rd, #0x10 - beq 1001b - .endm - #elif defined(CONFIG_ARCH_IXP4XX) .macro addruart,rx @@ -591,7 +565,8 @@ .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? - ldr \rx, =0x80000700 @ physical base address + mov \rx, #0x00000700 @ offset from base + orreq \rx, \rx, #0x80000000 @ physical base orrne \rx, \rx, #0xf8000000 @ virtual base .endm diff -Nru a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S --- a/arch/arm/kernel/entry-armv.S 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/kernel/entry-armv.S 2004-06-26 17:09:17 -07:00 @@ -19,6 +19,7 @@ #include #include #include +#include #include "entry-header.S" @@ -561,7 +562,7 @@ .macro irq_prio_table .endm -#elif defined(CONFIG_ARCH_IOP310) || defined(CONFIG_ARCH_ADIFCC) +#elif defined(CONFIG_ARCH_IOP310) .macro disable_fiq .endm @@ -1198,8 +1199,13 @@ mov pc, lr @ CP#7 mov pc, lr @ CP#8 mov pc, lr @ CP#9 +#ifdef CONFIG_VFP + b do_vfp @ CP#10 (VFP) + b do_vfp @ CP#11 (VFP) +#else mov pc, lr @ CP#10 (VFP) mov pc, lr @ CP#11 (VFP) +#endif mov pc, lr @ CP#12 mov pc, lr @ CP#13 mov pc, lr @ CP#14 (Debug) @@ -1260,6 +1266,13 @@ ldr r3, [r2, #TI_CPU_DOMAIN]! stmia ip, {r4 - sl, fp, sp, lr} @ Store most regs on stack mcr p15, 0, r3, c3, c0, 0 @ Set domain register +#ifdef CONFIG_VFP + @ Always disable VFP so we can lazily save/restore the old + @ state. This occurs in the context of the previous thread. + VFPFMRX r4, FPEXC + bic r4, r4, #FPEXC_ENABLE + VFPFMXR FPEXC, r4 +#endif ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously __INIT diff -Nru a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c --- a/arch/arm/kernel/init_task.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/kernel/init_task.c 2004-06-26 17:09:20 -07:00 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c --- a/arch/arm/kernel/irq.c 2004-06-26 17:09:14 -07:00 +++ b/arch/arm/kernel/irq.c 2004-06-26 17:09:14 -07:00 @@ -674,7 +674,7 @@ action->handler = handler; action->flags = irq_flags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c --- a/arch/arm/kernel/process.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/kernel/process.c 2004-06-26 17:09:20 -07:00 @@ -314,10 +314,16 @@ memset(thread->used_cp, 0, sizeof(thread->used_cp)); memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); fp_init(&thread->fpstate); +#if defined(CONFIG_VFP) + vfp_flush_thread(&thread->vfpstate); +#endif } void release_thread(struct task_struct *dead_task) { +#if defined(CONFIG_VFP) + vfp_release_thread(&dead_task->thread_info->vfpstate); +#endif } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c --- a/arch/arm/kernel/setup.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/kernel/setup.c 2004-06-26 17:09:18 -07:00 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ #include #include +#include #ifndef MEM_SIZE #define MEM_SIZE (16*1024*1024) @@ -95,7 +97,6 @@ char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); -char saved_command_line[COMMAND_LINE_SIZE]; unsigned long phys_initrd_start __initdata = 0; unsigned long phys_initrd_size __initdata = 0; @@ -727,6 +728,7 @@ * Set up various architecture-specific pointers */ init_arch_irq = mdesc->init_irq; + init_arch_time = mdesc->init_time; init_machine = mdesc->init_machine; #ifdef CONFIG_VT diff -Nru a/arch/arm/kernel/time-acorn.c b/arch/arm/kernel/time-acorn.c --- a/arch/arm/kernel/time-acorn.c 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,66 +0,0 @@ -/* - * linux/arch/arm/kernel/time-acorn.c - * - * Copyright (c) 1996-2000 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Changelog: - * 24-Sep-1996 RMK Created - * 10-Oct-1996 RMK Brought up to date with arch-sa110eval - * 04-Dec-1997 RMK Updated for new arch/arm/time.c - */ -#include -#include - -#include -#include -#include - -extern unsigned long (*gettimeoffset)(void); - -static unsigned long ioctime_gettimeoffset(void) -{ - unsigned int count1, count2, status; - long offset; - - ioc_writeb (0, IOC_T0LATCH); - barrier (); - count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); - barrier (); - status = ioc_readb(IOC_IRQREQA); - barrier (); - ioc_writeb (0, IOC_T0LATCH); - barrier (); - count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); - - offset = count2; - if (count2 < count1) { - /* - * We have not had an interrupt between reading count1 - * and count2. - */ - if (status & (1 << 5)) - offset -= LATCH; - } else if (count2 > count1) { - /* - * We have just had another interrupt between reading - * count1 and count2. - */ - offset -= LATCH; - } - - offset = (LATCH - offset) * (tick_nsec / 1000); - return (offset + LATCH/2) / LATCH; -} - -void __init ioctime_init(void) -{ - ioc_writeb(LATCH & 255, IOC_T0LTCHL); - ioc_writeb(LATCH >> 8, IOC_T0LTCHH); - ioc_writeb(0, IOC_T0GO); - - gettimeoffset = ioctime_gettimeoffset; -} diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c --- a/arch/arm/kernel/time.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/kernel/time.c 2004-06-26 17:09:19 -07:00 @@ -27,12 +27,15 @@ #include #include #include +#include #include #include #include #include +#include + u64 jiffies_64 = INITIAL_JIFFIES; EXPORT_SYMBOL(jiffies_64); @@ -49,15 +52,11 @@ /* change this if you have some constant time drift */ #define USECS_PER_JIFFY (1000000/HZ) -static int dummy_set_rtc(void) -{ - return 0; -} /* * hook for setting the RTC's idea of the current time. */ -int (*set_rtc)(void) = dummy_set_rtc; +int (*set_rtc)(void); static unsigned long dummy_gettimeoffset(void) { @@ -238,7 +237,7 @@ #endif #ifdef CONFIG_LEDS_TIMER -static void do_leds(void) +static inline void do_leds(void) { static unsigned int count = 50; @@ -248,7 +247,7 @@ } } #else -#define do_leds() +#define do_leds() #endif void do_gettimeofday(struct timeval *tv) @@ -316,12 +315,18 @@ EXPORT_SYMBOL(do_settimeofday); -static struct irqaction timer_irq = { - .name = "timer", - .flags = SA_INTERRUPT, -}; +void timer_tick(struct pt_regs *regs) +{ + do_profile(regs); + do_leds(); + do_set_rtc(); + do_timer(regs); +} + +void (*init_arch_time)(void); + +void __init time_init(void) +{ + init_arch_time(); +} -/* - * Include architecture specific code - */ -#include diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c --- a/arch/arm/kernel/traps.c 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/kernel/traps.c 2004-06-26 17:09:17 -07:00 @@ -426,7 +426,7 @@ /* * Flush a region from virtual address 'r0' to virtual address 'r1' - * _inclusive_. There is no alignment requirement on either address; + * _exclusive_. There is no alignment requirement on either address; * user space does not need to know the hardware cache layout. * * r2 contains flags. It should ALWAYS be passed as ZERO until it diff -Nru a/arch/arm/mach-adifcc/Makefile b/arch/arm/mach-adifcc/Makefile --- a/arch/arm/mach-adifcc/Makefile 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,11 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := arch.o irq.o mm.o -obj-m := -obj-n := -obj- := - diff -Nru a/arch/arm/mach-adifcc/arch.c b/arch/arm/mach-adifcc/arch.c --- a/arch/arm/mach-adifcc/arch.c 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,32 +0,0 @@ -/* - * linux/arch/arm/mach-adifcc/arch.c - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -extern void adifcc_map_io(void); -extern void adifcc_init_irq(void); - -#ifdef CONFIG_ARCH_ADI_EVB -MACHINE_START(ADI_EVB, "ADI 80200FCC Evaluation Board") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xc0000000, 0x00400000, 0xff400000) - MAPIO(adifcc_map_io) - INITIRQ(adifcc_init_irq) -MACHINE_END -#endif - diff -Nru a/arch/arm/mach-adifcc/irq.c b/arch/arm/mach-adifcc/irq.c --- a/arch/arm/mach-adifcc/irq.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,61 +0,0 @@ -/* - * linux/arch/arm/mach-xscale/irq.c - * - * Author: Deepak Saxena - * Copyright: (C) 2001 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Based on IOP80310 code. Currently there's nothing more than the - * 80200 on chip interrupts. That'll change once the hardware adds - * support for PCI though. - */ -#include -#include - -#include -#include -#include - -static void xs80200_irq_mask (unsigned int irq) -{ - long INTCTL; - asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL)); - switch (irq) { - case IRQ_XS80200_BCU: INTCTL &= ~(1<<3); break; - case IRQ_XS80200_PMU: INTCTL &= ~(1<<2); break; - case IRQ_XS80200_EXTIRQ: INTCTL &= ~(1<<1); break; - case IRQ_XS80200_EXTFIQ: INTCTL &= ~(1<<0); break; - } - asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL)); -} - -static void xs80200_irq_unmask (unsigned int irq) -{ - long INTCTL; - asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL)); - switch (irq) { - case IRQ_XS80200_BCU: INTCTL |= (1<<3); break; - case IRQ_XS80200_PMU: INTCTL |= (1<<2); break; - case IRQ_XS80200_EXTIRQ: INTCTL |= (1<<1); break; - case IRQ_XS80200_EXTFIQ: INTCTL |= (1<<0); break; - } - asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL)); -} - -void __init adifcc_init_irq(void) -{ - int i; - - for (i = 0; i < NR_XS80200_IRQS; i++) { - irq_desc[i].valid = 1; - irq_desc[i].probe_ok = 0; - irq_desc[i].mask_ack = xs80200_irq_mask; - irq_desc[i].mask = xs80200_irq_mask; - irq_desc[i].unmask = xs80200_irq_unmask; - } -} - - diff -Nru a/arch/arm/mach-adifcc/mm.c b/arch/arm/mach-adifcc/mm.c --- a/arch/arm/mach-adifcc/mm.c 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,23 +0,0 @@ -/* - * linux/arch/arm/mach-xscale/mm.c - */ -#include -#include -#include - -#include -#include -#include - -#include - - -static struct map_desc adifcc_io_desc[] __initdata = { - /* on-board devices */ - { 0xff400000, 0x00400000, 0x00300000, MT_DEVICE } -}; - -void __init adifcc_map_io(void) -{ - iotable_init(adifcc_io_desc, ARRAY_SIZE(adifcc_io_desc)); -} diff -Nru a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c --- a/arch/arm/mach-clps711x/autcpu12.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-clps711x/autcpu12.c 2004-06-26 17:09:16 -07:00 @@ -37,6 +37,7 @@ extern void clps711x_map_io(void); extern void clps711x_init_irq(void); +extern void clps711x_init_time(void); /* * The on-chip registers are given a size of 1MB so that a section can @@ -65,5 +66,6 @@ BOOT_PARAMS(0xc0020000) MAPIO(autcpu12_map_io) INITIRQ(clps711x_init_irq) + INITTIME(clp711x_init_time) MACHINE_END diff -Nru a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c --- a/arch/arm/mach-clps711x/cdb89712.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-clps711x/cdb89712.c 2004-06-26 17:09:15 -07:00 @@ -34,6 +34,7 @@ extern void clps711x_init_irq(void); extern void clps711x_map_io(void); +extern void clps711x-init_time(void); /* * Map the CS89712 Ethernet port. That should be moved to the @@ -55,6 +56,7 @@ BOOT_PARAMS(0xc0000100) MAPIO(cdb89712_map_io) INITIRQ(clps711x_init_irq) + INITTIME(clps711x_init_time) MACHINE_END static int cdb89712_hw_init(void) diff -Nru a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c --- a/arch/arm/mach-clps711x/ceiva.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-clps711x/ceiva.c 2004-06-26 17:09:16 -07:00 @@ -35,6 +35,7 @@ #include extern void clps711x_init_irq(void); +extern void clps711x_init_time(void); static struct map_desc ceiva_io_desc[] __initdata = { /* virtual, physical, length, type */ @@ -58,4 +59,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(ceiva_map_io) INITIRQ(clps711x_init_irq) + INITTIME(clps711x_init_time) MACHINE_END diff -Nru a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c --- a/arch/arm/mach-clps711x/clep7312.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-clps711x/clep7312.c 2004-06-26 17:09:18 -07:00 @@ -25,6 +25,7 @@ extern void clps711x_init_irq(void); extern void clps711x_map_io(void); +extern void clps711x_init_time(void); static void __init fixup_clep7312(struct machine_desc *desc, struct tag *tags, @@ -44,5 +45,6 @@ FIXUP(fixup_clep7312) MAPIO(clps711x_map_io) INITIRQ(clps711x_init_irq) + INITTIME(clps711x_init_time) MACHINE_END diff -Nru a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c --- a/arch/arm/mach-clps711x/edb7211-arch.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-clps711x/edb7211-arch.c 2004-06-26 17:09:19 -07:00 @@ -27,6 +27,7 @@ extern void clps711x_init_irq(void); extern void edb7211_map_io(void); +extern void clps711x_init_time(void); static void __init fixup_edb7211(struct machine_desc *desc, struct tag *tags, @@ -56,4 +57,5 @@ FIXUP(fixup_edb7211) MAPIO(edb7211_map_io) INITIRQ(clps711x_init_irq) + INITTIME(clps711x_init_time) MACHINE_END diff -Nru a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c --- a/arch/arm/mach-clps711x/fortunet.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-clps711x/fortunet.c 2004-06-26 17:09:19 -07:00 @@ -33,6 +33,7 @@ extern void clps711x_map_io(void); extern void clps711x_init_irq(void); +extern void clps711x_init_time(void); struct meminfo memmap = { .nr_banks = 1, @@ -82,4 +83,5 @@ FIXUP(fortunet_fixup) MAPIO(clps711x_map_io) INITIRQ(clps711x_init_irq) + INITTIME(clps711x_init_time) MACHINE_END diff -Nru a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c --- a/arch/arm/mach-clps711x/p720t.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-clps711x/p720t.c 2004-06-26 17:09:18 -07:00 @@ -36,6 +36,7 @@ extern void clps711x_init_irq(void); extern void clps711x_map_io(void); +extern void clps711x_init_time(void); /* * Map the P720T system PLD. It occupies two address spaces: @@ -86,6 +87,7 @@ FIXUP(fixup_p720t) MAPIO(p720t_map_io) INITIRQ(clps711x_init_irq) + INITTIME(clps711x_init_time) MACHINE_END static int p720t_hw_init(void) diff -Nru a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c --- a/arch/arm/mach-clps711x/time.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-clps711x/time.c 2004-06-26 17:09:15 -07:00 @@ -18,12 +18,17 @@ */ #include #include +#include +#include #include +#include +#include #include #include -extern unsigned long (*gettimeoffset)(void); +#include + /* * gettimeoffset() returns time since last timer tick, in usecs. @@ -38,18 +43,35 @@ return (hwticks * (tick_nsec / 1000)) / LATCH; } -void __init clps711x_setup_timer(void) +/* + * IRQ handler for the timer + */ +static irqreturn_t +p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + timer_tick(regs); + return IRQ_HANDLED; +} + +static struct irqaction clps711x_timer_irq = { + .name = "CLPS711x Timer Tick", + .flags = SA_INTERRUPT, + .handler = p720t_timer_interrupt +}; + +void __init clps711x_init_time(void) { struct timespec tv; unsigned int syscon; - gettimeoffset = clps711x_gettimeoffset; - syscon = clps_readl(SYSCON1); syscon |= SYSCON1_TC2S | SYSCON1_TC2M; clps_writel(syscon, SYSCON1); clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */ + + setup_irq(IRQ_TC2OI, &clps711x_timer_irq); + gettimeoffset = clps711x_gettimeoffset; tv.tv_nsec = 0; tv.tv_sec = clps_readl(RTCDR); diff -Nru a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c --- a/arch/arm/mach-clps7500/core.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-clps7500/core.c 2004-06-26 17:09:18 -07:00 @@ -10,12 +10,13 @@ #include #include #include -#include +#include #include #include #include #include +#include #include #include @@ -187,7 +188,7 @@ .unmask = cl7500_no_action, }; -static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL }; +static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL }; static void __init clps7500_init_irq(void) { @@ -265,10 +266,47 @@ iotable_init(cl7500_io_desc, ARRAY_SIZE(cl7500_io_desc)); } +extern void ioctime_init(void); + +static irqreturn_t +clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + timer_tick(regs); + + /* Why not using do_leds interface?? */ + { + /* Twinkle the lights. */ + static int count, state = 0xff00; + if (count-- == 0) { + state ^= 0x100; + count = 25; + *((volatile unsigned int *)LED_ADDRESS) = state; + } + } + return IRQ_HANDLED; +} + +static struct irqaction clps7500_timer_irq = { + .name = "CLPS7500 Timer Tick", + .flags = SA_INTERRUPT, + .handler = clps7500_timer_interrupt +}; + +/* + * Set up timer interrupt. + */ +void __init clps7500_init_time(void) +{ + ioctime_init(); + + setup_irq(IRQ_TIMER, &clps7500_timer_irq); +} + MACHINE_START(CLPS7500, "CL-PS7500") MAINTAINER("Philip Blundell") BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) MAPIO(clps7500_map_io) INITIRQ(clps7500_init_irq) + INITTIME(clps7500_init_time) MACHINE_END diff -Nru a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c --- a/arch/arm/mach-ebsa110/core.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-ebsa110/core.c 2004-06-26 17:09:16 -07:00 @@ -11,6 +11,7 @@ */ #include #include +#include #include #include @@ -26,6 +27,8 @@ #include #include +#include + #define IRQ_MASK 0xfe000000 /* read */ #define IRQ_MSET 0xfe000000 /* write */ #define IRQ_STAT 0xff000000 /* read */ @@ -89,6 +92,103 @@ iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc)); } + +#define PIT_CTRL (PIT_BASE + 0x0d) +#define PIT_T2 (PIT_BASE + 0x09) +#define PIT_T1 (PIT_BASE + 0x05) +#define PIT_T0 (PIT_BASE + 0x01) + +/* + * This is the rate at which your MCLK signal toggles (in Hz) + * This was measured on a 10 digit frequency counter sampling + * over 1 second. + */ +#define MCLK 47894000 + +/* + * This is the rate at which the PIT timers get clocked + */ +#define CLKBY7 (MCLK / 7) + +/* + * This is the counter value. We tick at 200Hz on this platform. + */ +#define COUNT ((CLKBY7 + (HZ / 2)) / HZ) + +/* + * Get the time offset from the system PIT. Note that if we have missed an + * interrupt, then the PIT counter will roll over (ie, be negative). + * This actually works out to be convenient. + */ +static unsigned long ebsa110_gettimeoffset(void) +{ + unsigned long offset, count; + + __raw_writeb(0x40, PIT_CTRL); + count = __raw_readb(PIT_T1); + count |= __raw_readb(PIT_T1) << 8; + + /* + * If count > COUNT, make the number negative. + */ + if (count > COUNT) + count |= 0xffff0000; + + offset = COUNT; + offset -= count; + + /* + * `offset' is in units of timer counts. Convert + * offset to units of microseconds. + */ + offset = offset * (1000000 / HZ) / COUNT; + + return offset; +} + +static irqreturn_t +ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 count; + + /* latch and read timer 1 */ + __raw_writeb(0x40, PIT_CTRL); + count = __raw_readb(PIT_T1); + count |= __raw_readb(PIT_T1) << 8; + + count += COUNT; + + __raw_writeb(count & 0xff, PIT_T1); + __raw_writeb(count >> 8, PIT_T1); + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction ebsa110_timer_irq = { + .name = "EBSA110 Timer Tick", + .flags = SA_INTERRUPT, + .handler = ebsa110_timer_interrupt +}; + +/* + * Set up timer interrupt. + */ +static void __init ebsa110_init_time(void) +{ + /* + * Timer 1, mode 2, LSB/MSB + */ + __raw_writeb(0x70, PIT_CTRL); + __raw_writeb(COUNT & 0xff, PIT_T1); + __raw_writeb(COUNT >> 8, PIT_T1); + + gettimeoffset = ebsa110_gettimeoffset; + + setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq); +} + MACHINE_START(EBSA110, "EBSA110") MAINTAINER("Russell King") BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) @@ -98,4 +198,5 @@ SOFT_REBOOT MAPIO(ebsa110_map_io) INITIRQ(ebsa110_init_irq) + INITTIME(ebsa110_init_time) MACHINE_END diff -Nru a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c --- a/arch/arm/mach-epxa10db/arch.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-epxa10db/arch.c 2004-06-26 17:09:18 -07:00 @@ -29,10 +29,13 @@ extern void epxa10db_map_io(void); extern void epxa10db_init_irq(void); +extern void epxa10db_init_time(void); MACHINE_START(CAMELOT, "Altera Epxa10db") MAINTAINER("Altera Corporation") BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) MAPIO(epxa10db_map_io) INITIRQ(epxa10db_init_irq) + INITTIME(epxa10db_init_time) MACHINE_END + diff -Nru a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c --- a/arch/arm/mach-epxa10db/time.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-epxa10db/time.c 2004-06-26 17:09:16 -07:00 @@ -10,11 +10,17 @@ */ #include #include +#include +#include #include +#include +#include +#include -extern int (*set_rtc)(void); +#define TIMER00_TYPE (volatile unsigned int*) +#include static int epxa10db_set_rtc(void) { @@ -29,3 +35,39 @@ } __initcall(epxa10db_rtc_init); + + +/* + * IRQ handler for the timer + */ +static irqreturn_t +epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + + // ...clear the interrupt + *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK; + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction epxa10db_timer_irq = { + .name = "Excalibur Timer Tick", + .flags = SA_INTERRUPT, + .handler = epxa10db_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init epxa10db_init_time(void) +{ + /* Start the timer */ + *TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200); + *TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1; + *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK; + + setup_irq(IRQ_TIMER0, &epxa10db_timer_irq); +} + diff -Nru a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile --- a/arch/arm/mach-footbridge/Makefile 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-footbridge/Makefile 2004-06-26 17:09:18 -07:00 @@ -4,7 +4,7 @@ # Object file lists. -obj-y := arch.o dc21285.o dma.o irq.o isa-irq.o mm.o +obj-y := arch.o dc21285.o dma.o irq.o isa-irq.o mm.o time.o obj-m := obj-n := obj- := diff -Nru a/arch/arm/mach-footbridge/arch.c b/arch/arm/mach-footbridge/arch.c --- a/arch/arm/mach-footbridge/arch.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-footbridge/arch.c 2004-06-26 17:09:16 -07:00 @@ -22,6 +22,7 @@ extern void footbridge_map_io(void); extern void footbridge_init_irq(void); +extern void footbridge_init_time(void); unsigned int mem_fclk_21285 = 50000000; @@ -43,6 +44,7 @@ VIDEO(0x000a0000, 0x000bffff) MAPIO(footbridge_map_io) INITIRQ(footbridge_init_irq) + INITTIME(footbridge_init_time) MACHINE_END #endif @@ -78,6 +80,7 @@ FIXUP(fixup_netwinder) MAPIO(footbridge_map_io) INITIRQ(footbridge_init_irq) + INITTIME(footbridge_init_time) MACHINE_END #endif @@ -103,6 +106,7 @@ FIXUP(fixup_cats) MAPIO(footbridge_map_io) INITIRQ(footbridge_init_irq) + INITTIME(footbridge_init_time) MACHINE_END #endif @@ -129,6 +133,7 @@ FIXUP(fixup_coebsa285) MAPIO(footbridge_map_io) INITIRQ(footbridge_init_irq) + INITTIME(footbridge_init_time) MACHINE_END #endif @@ -139,5 +144,6 @@ BOOT_PARAMS(0x00000100) MAPIO(footbridge_map_io) INITIRQ(footbridge_init_irq) + INITTIME(footbridge_init_time) MACHINE_END #endif diff -Nru a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-footbridge/time.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,296 @@ +/* + * linux/include/asm-arm/arch-ebsa285/time.h + * + * Copyright (C) 1998 Russell King. + * Copyright (C) 1998 Phil Blundell + * + * CATS has a real-time clock, though the evaluation board doesn't. + * + * Changelog: + * 21-Mar-1998 RMK Created + * 27-Aug-1998 PJB CATS support + * 28-Dec-1998 APH Made leds optional + * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder + * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in + */ + +#define RTC_PORT(x) (rtc_base+(x)) +#define RTC_ALWAYS_BCD 0 + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +static int rtc_base; + +#define mSEC_10_from_14 ((14318180 + 100) / 200) + +static unsigned long isa_gettimeoffset(void) +{ + int count; + + static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */ + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have IRQs turned off. + */ + unsigned long jiffies_t; + + /* timer count may underflow right here */ + outb_p(0x00, 0x43); /* latch the count ASAP */ + + count = inb_p(0x40); /* read the latched count */ + + /* + * We do this guaranteed double memory access instead of a _p + * postfix in the previous port access. Wheee, hackady hack + */ + jiffies_t = jiffies; + + count |= inb_p(0x40) << 8; + + /* Detect timer underflows. If we haven't had a timer tick since + the last time we were called, and time is apparently going + backwards, the counter must have wrapped during this routine. */ + if ((jiffies_t == jiffies_p) && (count > count_p)) + count -= (mSEC_10_from_14/6); + else + jiffies_p = jiffies_t; + + count_p = count; + + count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000); + count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6); + + return count; +} + +static irqreturn_t +isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + timer_tick(regs); + + return IRQ_HANDLED; +} + +static unsigned long __init get_isa_cmos_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + int i; + + // check to see if the RTC makes sense..... + if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) + return mktime(1970, 1, 1, 0, 0, 0); + + /* The Linux interpretation of the CMOS clock register contents: + * When the Update-In-Progress (UIP) flag goes from 1 to 0, the + * RTC registers show the second which has precisely just started. + * Let's hope other operating systems interpret the RTC the same way. + */ + /* read RTC exactly on falling edge of update flag */ + for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ + if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) + break; + + for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ + if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + break; + + do { /* Isn't this overkill ? UIP above should guarantee consistency */ + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + } while (sec != CMOS_READ(RTC_SECONDS)); + + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + if ((year += 1900) < 1970) + year += 100; + return mktime(year, mon, day, hour, min, sec); +} + +static int +set_isa_cmos_time(void) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned char save_control, save_freq_select; + unsigned long nowtime = xtime.tv_sec; + + save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + cmos_minutes = CMOS_READ(RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + } + CMOS_WRITE(real_seconds,RTC_SECONDS); + CMOS_WRITE(real_minutes,RTC_MINUTES); + } else + retval = -1; + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + + return retval; +} + + +static unsigned long timer1_latch; + +static unsigned long timer1_gettimeoffset (void) +{ + unsigned long value = timer1_latch - *CSR_TIMER1_VALUE; + + return ((tick_nsec / 1000) * value) / timer1_latch; +} + +static irqreturn_t +timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + *CSR_TIMER1_CLR = 0; + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction footbridge_timer_irq = { + .flags = SA_INTERRUPT +}; + +/* + * Set up timer interrupt. + */ +void __init footbridge_init_time(void) +{ + if (machine_is_co285() || + machine_is_personal_server()) + /* + * Add-in 21285s shouldn't access the RTC + */ + rtc_base = 0; + else + rtc_base = 0x70; + + if (rtc_base) { + int reg_d, reg_b; + + /* + * Probe for the RTC. + */ + reg_d = CMOS_READ(RTC_REG_D); + + /* + * make sure the divider is set + */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); + + /* + * Set control reg B + * (24 hour mode, update enabled) + */ + reg_b = CMOS_READ(RTC_REG_B) & 0x7f; + reg_b |= 2; + CMOS_WRITE(reg_b, RTC_REG_B); + + if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && + CMOS_READ(RTC_REG_B) == reg_b) { + struct timespec tv; + + /* + * We have a RTC. Check the battery + */ + if ((reg_d & 0x80) == 0) + printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); + + tv.tv_nsec = 0; + tv.tv_sec = get_isa_cmos_time(); + do_settimeofday(&tv); + set_rtc = set_isa_cmos_time; + } else + rtc_base = 0; + } + + if (machine_is_ebsa285() || + machine_is_co285() || + machine_is_personal_server()) { + gettimeoffset = timer1_gettimeoffset; + + timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ); + + *CSR_TIMER1_CLR = 0; + *CSR_TIMER1_LOAD = timer1_latch; + *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; + + footbridge_timer_irq.name = "Timer1 Timer Tick"; + footbridge_timer_irq.handler = timer1_interrupt; + + setup_irq(IRQ_TIMER1, &footbridge_timer_irq); + + } else { + /* enable PIT timer */ + /* set for periodic (4) and LSB/MSB write (0x30) */ + outb(0x34, 0x43); + outb((mSEC_10_from_14/6) & 0xFF, 0x40); + outb((mSEC_10_from_14/6) >> 8, 0x40); + + gettimeoffset = isa_gettimeoffset; + + footbridge_timer_irq.name = "ISA Timer Tick"; + footbridge_timer_irq.handler = isa_timer_interrupt; + + setup_irq(IRQ_ISA_TIMER, &footbridge_timer_irq); + } +} diff -Nru a/arch/arm/mach-ftvpci/Makefile b/arch/arm/mach-ftvpci/Makefile --- a/arch/arm/mach-ftvpci/Makefile 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,13 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := core.o -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_LEDS) += leds.o diff -Nru a/arch/arm/mach-ftvpci/core.c b/arch/arm/mach-ftvpci/core.c --- a/arch/arm/mach-ftvpci/core.c 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,96 +0,0 @@ -/* - * linux/arch/arm/mach-ftvpci/core.c - * - * Architecture specific fixups. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -extern unsigned long soft_irq_mask; - -static const unsigned char irq_cmd[] = -{ - INTCONT_IRQ_DUART, - INTCONT_IRQ_PLX, - INTCONT_IRQ_D, - INTCONT_IRQ_C, - INTCONT_IRQ_B, - INTCONT_IRQ_A, - INTCONT_IRQ_SYSERR -}; - -static void ftvpci_mask_irq(unsigned int irq) -{ - __raw_writel(irq_cmd[irq], INTCONT_BASE); - soft_irq_mask &= ~(1<= FIRST_IRQ && i <= LAST_IRQ) { - irq_desc[i].valid = 1; - irq_desc[i].probe_ok = 1; - irq_desc[i].mask_ack = ftvpci_mask_irq; - irq_desc[i].mask = ftvpci_mask_irq; - irq_desc[i].unmask = ftvpci_unmask_irq; - ftvpci_mask_irq(i); - } else { - irq_desc[i].valid = 0; - irq_desc[i].probe_ok = 0; - } - } -} - -static struct map_desc ftvpci_io_desc[] __initdata = { - { INTCONT_BASE, INTCONT_START, 0x00001000, MT_DEVICE }, - { PLX_BASE, PLX_START, 0x00001000, MT_DEVICE }, - { PCIO_BASE, PLX_IO_START, 0x00100000, MT_DEVICE }, - { DUART_BASE, DUART_START, 0x00001000, MT_DEVICE }, - { STATUS_BASE, STATUS_START, 0x00001000, MT_DEVICE } -}; - -static void __init ftvpci_map_io(void) -{ - iotable_init(ftvpci_io_desc, ARRAY_SIZE(ftvpci_io_desc)); -} - -MACHINE_START(NEXUSPCI, "FTV/PCI") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x40000000, 0x10000000, 0xe0000000) - MAPIO(ftvpci_map_io) - INITIRQ(ftvpci_init_irq) -MACHINE_END diff -Nru a/arch/arm/mach-ftvpci/leds.c b/arch/arm/mach-ftvpci/leds.c --- a/arch/arm/mach-ftvpci/leds.c 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,36 +0,0 @@ -/* - * linux/arch/arm/kernel/leds-ftvpci.c - * - * Copyright (C) 1999 FutureTV Labs Ltd - */ - -#include -#include - -#include -#include -#include -#include - -static void ftvpci_leds_event(led_event_t ledevt) -{ - static int led_state = 0; - - switch(ledevt) { - case led_timer: - led_state ^= 1; - raw_writeb(0x1a | led_state, INTCONT_BASE); - break; - - default: - break; - } -} - -static int __init ftvpci_leds_init(void) -{ - leds_event = ftvpci_leds_event; - return 0; -} - -arch_initcall(ftvpci_leds_init); diff -Nru a/arch/arm/mach-ftvpci/pci.c b/arch/arm/mach-ftvpci/pci.c --- a/arch/arm/mach-ftvpci/pci.c 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,60 +0,0 @@ -/* - * linux/arch/arm/kernel/ftv-pci.c - * - * PCI bios-type initialisation for PCI machines - * - * Bits taken from various places. - */ -#include -#include -#include - -#include -#include -#include - -/* - * Owing to a PCB cockup, issue A backplanes are wired thus: - * - * Slot 1 2 3 4 5 Bridge S1 S2 S3 S4 - * IRQ D C B A A C B A D - * A D C B B D C B A - * B A D C C A D C B - * C B A D D B A D C - * - * ID A31 A30 A29 A28 A27 A26 DEV4 DEV5 DEV6 DEV7 - * - * Actually, this isn't too bad, because with the processor card - * in slot 5 on the primary bus, the IRQs rotate on both sides - * as you'd expect. - */ - -static int irqmap_ftv[] __initdata = { IRQ_PCI_D, IRQ_PCI_C, IRQ_PCI_B, IRQ_PCI_A }; - -static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (slot > 0x10) - slot--; - return irqmap_ftv[(slot - pin) & 3]; -} - -static u8 __init ftv_swizzle(struct pci_dev *dev, u8 *pin) -{ - return PCI_SLOT(dev->devfn); -} - -/* ftv host-specific stuff */ -static struct hw_pci ftv_pci __initdata = { - .init = plx90x0_init, - .swizzle = ftv_swizzle, - .map_irq = ftv_map_irq, -}; - -static int __init ftv_pci_init(void) -{ - if (machine_is_ftvpci()) - pci_common_init(&ftv_pci); - return 0; -} - -subsys_initcall(ftv_pci_init); diff -Nru a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile --- a/arch/arm/mach-integrator/Makefile 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-integrator/Makefile 2004-06-26 17:09:20 -07:00 @@ -4,7 +4,7 @@ # Object file lists. -obj-y := core.o lm.o time.o +obj-y := clock.o core.o lm.o time.o obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o diff -Nru a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-integrator/clock.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,138 @@ +/* + * linux/arch/arm/mach-integrator/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clock.h" + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + down(&clocks_sem); + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + up(&clocks_sem); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +int clk_use(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_use); + +void clk_unuse(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_unuse); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return rate; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EIO; + if (clk->setvco) { + struct icst525_vco vco; + + vco = icst525_khz_to_vco(clk->params, rate); + clk->rate = icst525_khz(clk->params, vco); + + printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n", + clk->name, vco.s, vco.r, vco.v); + + clk->setvco(clk, vco); + ret = 0; + } + return 0; +} +EXPORT_SYMBOL(clk_set_rate); + +/* + * These are fixed clocks. + */ +static struct clk kmi_clk = { + .name = "KMIREFCLK", + .rate = 24000000, +}; + +static struct clk uart_clk = { + .name = "UARTCLK", + .rate = 14745600, +}; + +int clk_register(struct clk *clk) +{ + down(&clocks_sem); + list_add(&clk->node, &clocks); + up(&clocks_sem); + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + down(&clocks_sem); + list_del(&clk->node); + up(&clocks_sem); +} +EXPORT_SYMBOL(clk_unregister); + +static int __init clk_init(void) +{ + clk_register(&kmi_clk); + clk_register(&uart_clk); + return 0; +} +arch_initcall(clk_init); diff -Nru a/arch/arm/mach-integrator/clock.h b/arch/arm/mach-integrator/clock.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-integrator/clock.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/mach-integrator/clock.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +struct module; +struct icst525_params; + +struct clk { + struct list_head node; + unsigned long rate; + struct module *owner; + const char *name; + const struct icst525_params *params; + void *data; + void (*setvco)(struct clk *, struct icst525_vco vco); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); diff -Nru a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c --- a/arch/arm/mach-integrator/core.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-integrator/core.c 2004-06-26 17:09:19 -07:00 @@ -12,12 +12,17 @@ #include #include #include +#include +#include #include #include #include #include #include +#include +#include +#include static struct amba_device rtc_device = { .dev = { @@ -127,3 +132,137 @@ } EXPORT_SYMBOL(cm_control); + +/* + * Where is the timer (VA)? + */ +#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000) +#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100) +#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200) +#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) +#elif TIMER_INTERVAL >= 0x10000 +#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) +#else +#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) +#endif + +/* + * What does it look like? + */ +typedef struct TimerStruct { + unsigned long TimerLoad; + unsigned long TimerValue; + unsigned long TimerControl; + unsigned long TimerClear; +} TimerStruct_t; + +extern unsigned long (*gettimeoffset)(void); + +static unsigned long timer_reload; + +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +static unsigned long integrator_gettimeoffset(void) +{ + volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; + unsigned long ticks1, ticks2, status; + + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks2 = timer1->TimerValue & 0xffff; + do { + ticks1 = ticks2; + status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); + ticks2 = timer1->TimerValue & 0xffff; + } while (ticks2 > ticks1); + + /* + * Number of ticks since last interrupt. + */ + ticks1 = timer_reload - ticks2; + + /* + * Interrupt pending? If so, we've reloaded once already. + */ + if (status & (1 << IRQ_TIMERINT1)) + ticks1 += timer_reload; + + /* + * Convert the ticks to usecs + */ + return TICKS2USECS(ticks1); +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t +integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + + // ...clear the interrupt + timer1->TimerClear = 1; + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction integrator_timer_irq = { + .name = "Integrator Timer Tick", + .flags = SA_INTERRUPT, + .handler = integrator_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +{ + volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; + unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ + + timer_reload = reload; + timer_ctrl |= ctrl; + + if (timer_reload > 0x100000) { + timer_reload >>= 8; + timer_ctrl |= 0x08; /* /256 */ + } else if (timer_reload > 0x010000) { + timer_reload >>= 4; + timer_ctrl |= 0x04; /* /16 */ + } + + /* + * Initialise to a known state (all timers off) + */ + timer0->TimerControl = 0; + timer1->TimerControl = 0; + timer2->TimerControl = 0; + + timer1->TimerLoad = timer_reload; + timer1->TimerValue = timer_reload; + timer1->TimerControl = timer_ctrl; + + /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); + gettimeoffset = integrator_gettimeoffset; +} diff -Nru a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c --- a/arch/arm/mach-integrator/impd1.c 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/mach-integrator/impd1.c 2004-06-26 17:09:17 -07:00 @@ -25,13 +25,16 @@ #include #include +#include "clock.h" + static int module_id; module_param_named(lmid, module_id, int, 0444); MODULE_PARM_DESC(lmid, "logic module stack position"); struct impd1_module { - void *base; + void *base; + struct clk vcos[2]; }; static const struct icst525_params impd1_vco_params = { @@ -43,25 +46,20 @@ .rd_max = 120, }; -void impd1_set_vco(struct device *dev, int vconr, unsigned long period) +static void impd1_setvco(struct clk *clk, struct icst525_vco vco) { - struct impd1_module *impd1 = dev_get_drvdata(dev); - struct icst525_vco vco; + struct impd1_module *impd1 = clk->data; + int vconr = clk - impd1->vcos; u32 val; - vco = icst525_ps_to_vco(&impd1_vco_params, period); - - pr_debug("Guessed VCO reg params: S=%d R=%d V=%d\n", - vco.s, vco.r, vco.v); - val = vco.v | (vco.r << 9) | (vco.s << 16); writel(0xa05f, impd1->base + IMPD1_LOCK); switch (vconr) { - case 1: + case 0: writel(val, impd1->base + IMPD1_OSC1); break; - case 2: + case 1: writel(val, impd1->base + IMPD1_OSC2); break; } @@ -77,8 +75,6 @@ #endif } -EXPORT_SYMBOL(impd1_set_vco); - void impd1_tweak_control(struct device *dev, u32 mask, u32 val) { struct impd1_module *impd1 = dev_get_drvdata(dev); @@ -140,6 +136,11 @@ } }; +static const char *impd1_vconames[2] = { + "CLCDCLK", + "AUXVCO2", +}; + static int impd1_probe(struct lm_device *dev) { struct impd1_module *impd1; @@ -168,6 +169,16 @@ printk("IM-PD1 found at 0x%08lx\n", dev->resource.start); + for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { + impd1->vcos[i].owner = THIS_MODULE, + impd1->vcos[i].name = impd1_vconames[i], + impd1->vcos[i].params = &impd1_vco_params, + impd1->vcos[i].data = impd1, + impd1->vcos[i].setvco = impd1_setvco; + + clk_register(&impd1->vcos[i]); + } + for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { struct impd1_device *idev = impd1_devs + i; struct amba_device *d; @@ -216,12 +227,16 @@ { struct impd1_module *impd1 = lm_get_drvdata(dev); struct list_head *l, *n; + int i; list_for_each_safe(l, n, &dev->dev.children) { struct device *d = list_to_dev(l); device_unregister(d); } + + for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) + clk_unregister(&impd1->vcos[i]); lm_set_drvdata(dev, NULL); diff -Nru a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c --- a/arch/arm/mach-integrator/integrator_ap.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-integrator/integrator_ap.c 2004-06-26 17:09:20 -07:00 @@ -256,7 +256,7 @@ unsigned long sc_dec; int i; - platform_add_device(&cfi_flash_device); + platform_device_register(&cfi_flash_device); sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); for (i = 0; i < 4; i++) { @@ -281,11 +281,17 @@ } } +static void ap_time_init(void) +{ + integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0); +} + MACHINE_START(INTEGRATOR, "ARM-Integrator") MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) BOOT_PARAMS(0x00000100) MAPIO(ap_map_io) INITIRQ(ap_init_irq) + INITTIME(ap_time_init) INIT_MACHINE(ap_init) MACHINE_END diff -Nru a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c --- a/arch/arm/mach-integrator/integrator_cp.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-integrator/integrator_cp.c 2004-06-26 17:09:20 -07:00 @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -32,12 +33,16 @@ #include #include +#include "clock.h" + #define INTCP_PA_MMC_BASE 0x1c000000 #define INTCP_PA_AACI_BASE 0x1d000000 #define INTCP_PA_FLASH_BASE 0x24000000 #define INTCP_FLASH_SIZE SZ_32M +#define INTCP_PA_CLCD_BASE 0xc0000000 + #define INTCP_VA_CIC_BASE 0xf1000040 #define INTCP_VA_PIC_BASE 0xf1400000 #define INTCP_VA_SIC_BASE 0xfca00000 @@ -210,6 +215,44 @@ } /* + * Clock handling + */ +#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) +#define CM_AUXOSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+0x1c) + +static const struct icst525_params cp_auxvco_params = { + .ref = 24000, + .vco_max = 320000, + .vd_min = 8, + .vd_max = 263, + .rd_min = 3, + .rd_max = 65, +}; + +static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco) +{ + u32 val; + + val = readl(CM_AUXOSC) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + writel(0xa05f, CM_LOCK); + writel(val, CM_AUXOSC); + writel(0, CM_LOCK); +} + +static struct clk cp_clcd_clk = { + .name = "CLCDCLK", + .params = &cp_auxvco_params, + .setvco = cp_auxvco_set, +}; + +static struct clk cp_mmci_clk = { + .name = "MCLK", + .rate = 14745600, +}; + +/* * Flash handling. */ static int intcp_flash_init(void) @@ -308,7 +351,7 @@ } static struct mmc_platform_data mmc_data = { - .mclk = 33000000, + .mclk = 14745600, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .status = mmc_status, }; @@ -340,15 +383,34 @@ .periphid = 0, }; +static struct amba_device clcd_device = { + .dev = { + .bus_id = "mb:c0", + .coherent_dma_mask = ~0, + }, + .res = { + .start = INTCP_PA_CLCD_BASE, + .end = INTCP_PA_CLCD_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = { IRQ_CP_CLCDCINT, NO_IRQ }, + .periphid = 0, +}; + static struct amba_device *amba_devs[] __initdata = { &mmc_device, &aaci_device, + &clcd_device, }; static void __init intcp_init(void) { int i; + clk_register(&cp_clcd_clk); + clk_register(&cp_mmci_clk); + platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { @@ -357,11 +419,19 @@ } } +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ + +static void __init intcp_init_time(void) +{ + integrator_time_init(1000000 / HZ, TIMER_CTRL_IE); +} + MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) BOOT_PARAMS(0x00000100) MAPIO(intcp_map_io) INITIRQ(intcp_init_irq) + INITTIME(intcp_init_time) INIT_MACHINE(intcp_init) MACHINE_END diff -Nru a/arch/arm/mach-iop3xx/arch.c b/arch/arm/mach-iop3xx/arch.c --- a/arch/arm/mach-iop3xx/arch.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-iop3xx/arch.c 2004-06-26 17:09:18 -07:00 @@ -29,6 +29,7 @@ #ifdef CONFIG_ARCH_IQ80321 extern void iq80321_map_io(void); extern void iop321_init_irq(void); +extern void iop321_init_time(void); #endif #ifdef CONFIG_ARCH_IQ80310 @@ -67,6 +68,7 @@ FIXUP(fixup_iop321) MAPIO(iq80321_map_io) INITIRQ(iop321_init_irq) + INITTIME(iop321_init_time) MACHINE_END #else diff -Nru a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c --- a/arch/arm/mach-iop3xx/iop321-time.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-iop3xx/iop321-time.c 2004-06-26 17:09:20 -07:00 @@ -23,7 +23,9 @@ #include #include #include + #include +#include static unsigned long iop321_gettimeoffset(void) { @@ -61,27 +63,26 @@ asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); - do_timer(regs); + timer_tick(regs); return IRQ_HANDLED; } -extern unsigned long (*gettimeoffset)(void); - -static struct irqaction timer_irq = { - .name = "timer", +static struct irqaction iop321_timer_irq = { + .name = "IOP321 Timer Tick", .handler = iop321_timer_interrupt, + .flags = SA_INTERRUPT }; extern int setup_arm_irq(int, struct irqaction*); -void __init time_init(void) +void __init iop321_init_time(void) { u32 timer_ctl; u32 latch = LATCH; gettimeoffset = iop321_gettimeoffset; - setup_irq(IRQ_IOP321_TIMER0, &timer_irq); + setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq); timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD | IOP321_TMR_RATIO_1_1; diff -Nru a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c --- a/arch/arm/mach-ixp4xx/common.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-ixp4xx/common.c 2004-06-26 17:09:18 -07:00 @@ -36,6 +36,7 @@ #include #include +#include /************************************************************************* @@ -227,24 +228,22 @@ * Catch up with the real idea of time */ do { - do_timer(regs); + timer_tick(regs); last_jiffy_time += LATCH; } while((*IXP4XX_OSTS - last_jiffy_time) > LATCH); return IRQ_HANDLED; } -extern unsigned long (*gettimeoffset)(void); - -static struct irqaction timer_irq = { - .name = "IXP4xx Timer Tick", - .flags = SA_INTERRUPT +static struct irqaction ixp4xx_timer_irq = { + .name = "IXP4xx Timer Tick", + .flags = SA_INTERRUPT, + .handler = ixp4xx_timer_interrupt }; -void __init time_init(void) +void __init ixp4xx_init_time(void) { gettimeoffset = ixp4xx_gettimeoffset; - timer_irq.handler = ixp4xx_timer_interrupt; /* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; @@ -257,7 +256,7 @@ last_jiffy_time = 0; /* Connect the interrupt handler and enable the interrupt */ - setup_irq(IRQ_IXP4XX_TIMER1, &timer_irq); + setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); } diff -Nru a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c --- a/arch/arm/mach-ixp4xx/coyote-setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-ixp4xx/coyote-setup.c 2004-06-26 17:09:16 -07:00 @@ -84,6 +84,7 @@ IXP4XX_PERIPHERAL_BASE_VIRT) MAPIO(coyote_map_io) INITIRQ(ixp4xx_init_irq) + INITTIME(ixp4xx_init_time) BOOT_PARAMS(0x0100) INIT_MACHINE(coyote_init) MACHINE_END diff -Nru a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c 2004-06-26 17:09:18 -07:00 @@ -113,6 +113,7 @@ IXP4XX_PERIPHERAL_BASE_VIRT) MAPIO(ixdp425_map_io) INITIRQ(ixp4xx_init_irq) + INITTIME(ixp4xx_init_time) BOOT_PARAMS(0x0100) INIT_MACHINE(ixdp425_init) MACHINE_END @@ -123,6 +124,7 @@ IXP4XX_PERIPHERAL_BASE_VIRT) MAPIO(ixdp425_map_io) INITIRQ(ixp4xx_init_irq) + INITTIME(ixp4xx_init_time) BOOT_PARAMS(0x0100) INIT_MACHINE(ixdp425_init) MACHINE_END @@ -140,6 +142,7 @@ IXP4XX_PERIPHERAL_BASE_VIRT) MAPIO(ixdp425_map_io) INITIRQ(ixp4xx_init_irq) + INITTIME(ixp4xx_init_time) BOOT_PARAMS(0x0100) INIT_MACHINE(ixdp425_init) MACHINE_END diff -Nru a/arch/arm/mach-ixp4xx/prpmc1100-setup.c b/arch/arm/mach-ixp4xx/prpmc1100-setup.c --- a/arch/arm/mach-ixp4xx/prpmc1100-setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-ixp4xx/prpmc1100-setup.c 2004-06-26 17:09:16 -07:00 @@ -84,6 +84,7 @@ IXP4XX_PERIPHERAL_BASE_VIRT) MAPIO(prpmc1100_map_io) INITIRQ(ixp4xx_init_irq) + INITTIME(ixp4xx_init_time) BOOT_PARAMS(0x0100) INIT_MACHINE(prpmc1100_init) MACHINE_END diff -Nru a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig --- a/arch/arm/mach-lh7a40x/Kconfig 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-lh7a40x/Kconfig 2004-06-26 17:09:19 -07:00 @@ -34,6 +34,37 @@ config ARCH_LH7A404 bool +config LH7A40X_CONTIGMEM + bool "Disable NUMA Support" + depends on ARCH_LH7A40X + help + Say Y here if your bootloader sets the SROMLL bit(s) in + the SDRAM controller, organizing memory as a contiguous + array. This option will disable CONFIG_DISCONTIGMEM and + force the kernel to manage all memory in one node. + + Setting this option incorrectly may prevent the kernel from + booting. It is OK to leave it N. + + For more information, consult + . + +config LH7A40X_ONE_BANK_PER_NODE + bool "Optimize NUMA Node Tables for Size" + depends on ARCH_LH7A40X && !LH7A40X_CONTIGMEM + help + Say Y here to produce compact memory node tables. By + default pairs of adjacent physical RAM banks are managed + together in a single node, incurring some wasted overhead + in the node tables, however also maintaining compatibility + with systems where physical memory is truly contiguous. + + Setting this option incorrectly may prevent the kernel from + booting. It is OK to leave it N. + + For more information, consult + . + endmenu endif diff -Nru a/arch/arm/mach-lh7a40x/Makefile b/arch/arm/mach-lh7a40x/Makefile --- a/arch/arm/mach-lh7a40x/Makefile 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-lh7a40x/Makefile 2004-06-26 17:09:18 -07:00 @@ -4,7 +4,7 @@ # Object file lists. -obj-y := fiq.o +obj-y := fiq.o time.o # generic.o obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o ide-lpd7a40x.o irq-lh7a400.o diff -Nru a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c 2004-06-26 17:09:15 -07:00 @@ -25,6 +25,7 @@ /* This function calls the board specific IRQ initialization function. */ extern void lh7a400_init_irq (void); +extern void lh7a40x_init_time (void); static struct map_desc kev7a400_io_desc[] __initdata = { { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, @@ -108,4 +109,5 @@ BOOT_PARAMS (0xc0000100) MAPIO (kev7a400_map_io) INITIRQ (lh7a400_init_irq) + INITTIME (lh7a40x_init_time) MACHINE_END diff -Nru a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c 2004-06-26 17:09:15 -07:00 @@ -280,6 +280,7 @@ #ifdef CONFIG_MACH_LPD7A404 extern void lh7a404_init_irq (void); +extern void lh7a40x_init_time (void); MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") MAINTAINER ("Marc Singer") @@ -287,6 +288,7 @@ BOOT_PARAMS (0xc0000100) MAPIO (lpd7a400_map_io) INITIRQ (lh7a404_init_irq) + INITTIME (lh7a40x_init_time) INIT_MACHINE (lpd7a40x_init) MACHINE_END diff -Nru a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-lh7a40x/time.c 2004-06-26 17:09:18 -07:00 @@ -0,0 +1,67 @@ +/* + * arch/arm/mach-lh7a40x/time.c + * + * Copyright (C) 2004 Logic Product Development + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#if HZ < 100 +# define TIMER_CONTROL TIMER_CONTROL1 +# define TIMER_LOAD TIMER_LOAD1 +# define TIMER_CONSTANT (508469/HZ) +# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC | TIMER_C_508KHZ) +# define TIMER_EOI TIMER_EOI1 +# define TIMER_IRQ IRQ_T1UI +#else +# define TIMER_CONTROL TIMER_CONTROL3 +# define TIMER_LOAD TIMER_LOAD3 +# define TIMER_CONSTANT (3686400/HZ) +# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC) +# define TIMER_EOI TIMER_EOI3 +# define TIMER_IRQ IRQ_T3UI +#endif + +static irqreturn_t +lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + TIMER_EOI = 0; + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction lh7a40x_timer_irq = { + .name = "LHA740x Timer Tick", + .flags = SA_INTERRUPT, + .handler = lh7a40x_timer_interrupt +}; + +void __init lh7a40x_init_time(void) +{ + /* Stop/disable all timers */ + TIMER_CONTROL1 = 0; + TIMER_CONTROL2 = 0; + TIMER_CONTROL3 = 0; + + setup_irq (TIMER_IRQ, &lh7a40x_timer_irq); + + TIMER_LOAD = TIMER_CONSTANT; + TIMER_CONTROL = TIMER_MODE; +} + diff -Nru a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile --- a/arch/arm/mach-omap/Makefile 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-omap/Makefile 2004-06-26 17:09:16 -07:00 @@ -3,7 +3,7 @@ # # Common support -obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o +obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o time.o obj-m := obj-n := obj- := diff -Nru a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c --- a/arch/arm/mach-omap/board-generic.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-omap/board-generic.c 2004-06-26 17:09:19 -07:00 @@ -65,6 +65,11 @@ omap_map_io(); } +static void __init omap_generic_init_time(void) +{ + omap_init_time(); +} + MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710") MAINTAINER("Tony Lindgren ") BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) @@ -72,4 +77,6 @@ MAPIO(omap_generic_map_io) INITIRQ(omap_generic_init_irq) INIT_MACHINE(omap_generic_init) + INITTIME(omap_generic_init_time) MACHINE_END + diff -Nru a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c --- a/arch/arm/mach-omap/board-innovator.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-omap/board-innovator.c 2004-06-26 17:09:15 -07:00 @@ -156,5 +156,6 @@ BOOT_PARAMS(0x10000100) MAPIO(innovator_map_io) INITIRQ(innovator_init_irq) + INITTIME(omap_init_time) INIT_MACHINE(innovator_init) MACHINE_END diff -Nru a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c --- a/arch/arm/mach-omap/board-osk.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-omap/board-osk.c 2004-06-26 17:09:20 -07:00 @@ -94,5 +94,6 @@ BOOT_PARAMS(0x10000100) MAPIO(osk_map_io) INITIRQ(osk_init_irq) + INITTIME(omap_init_time) INIT_MACHINE(osk_init) MACHINE_END diff -Nru a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c --- a/arch/arm/mach-omap/board-perseus2.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-omap/board-perseus2.c 2004-06-26 17:09:19 -07:00 @@ -111,5 +111,6 @@ BOOT_PARAMS(0x10000100) MAPIO(omap_perseus2_map_io) INITIRQ(omap_perseus2_init_irq) + INITTIME(omap_init_time) INIT_MACHINE(omap_perseus2_init) MACHINE_END diff -Nru a/arch/arm/mach-omap/bus.c b/arch/arm/mach-omap/bus.c --- a/arch/arm/mach-omap/bus.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-omap/bus.c 2004-06-26 17:09:21 -07:00 @@ -81,40 +81,6 @@ }, }; -#ifdef CONFIG_ARCH_OMAP1510 -/* - * NOTE: This code _should_ go somewhere else. But let's wait for the - * dma-mapping code to settle down first. - */ - -/* - * Test for Local Bus device in order to do address translation between - * dma_handle and Local Bus address. - */ -inline int dmadev_uses_omap_lbus(struct device * dev) -{ - if (dev == NULL || !cpu_is_omap1510()) - return 0; - return dev->bus == &omap_bus_types[OMAP_BUS_LBUS] ? 1 : 0; -} - -/* - * Translate bus address to Local Bus address for dma-mapping - */ -inline int dmadev_to_lbus(dma_addr_t addr) -{ - return bus_to_lbus(addr); -} - -/* - * Translate Local Bus address to bus address for dma-mapping - */ -inline int lbus_to_dmadev(dma_addr_t addr) -{ - return lbus_to_bus(addr); -} -#endif - static int omap_bus_match(struct device *dev, struct device_driver *drv) { struct omap_dev *omapdev = OMAP_DEV(dev); @@ -278,8 +244,3 @@ EXPORT_SYMBOL(omap_device_register); EXPORT_SYMBOL(omap_device_unregister); -#ifdef CONFIG_ARCH_OMAP1510 -EXPORT_SYMBOL(dmadev_uses_omap_lbus); -EXPORT_SYMBOL(dmadev_to_lbus); -EXPORT_SYMBOL(lbus_to_dmadev); -#endif diff -Nru a/arch/arm/mach-omap/common.h b/arch/arm/mach-omap/common.h --- a/arch/arm/mach-omap/common.h 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-omap/common.h 2004-06-26 17:09:18 -07:00 @@ -28,6 +28,7 @@ #define __ARCH_ARM_MACH_OMAP_COMMON_H extern void omap_map_io(void); +extern void omap_init_time(void); #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff -Nru a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-omap/time.c 2004-06-26 17:09:18 -07:00 @@ -0,0 +1,217 @@ +/* + * arch/arm/mach-omap/time.c + * + * OMAP Timer Tick + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: Greg Lonnon + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __instrument +#define __instrument +#define __noinstrument __attribute__ ((no_instrument_function)) +#endif + +typedef struct { + u32 cntl; /* CNTL_TIMER, R/W */ + u32 load_tim; /* LOAD_TIM, W */ + u32 read_tim; /* READ_TIM, R */ +} mputimer_regs_t; + +#define mputimer_base(n) \ + ((volatile mputimer_regs_t*)IO_ADDRESS(OMAP_MPUTIMER_BASE + \ + (n)*OMAP_MPUTIMER_OFFSET)) + +static inline unsigned long timer32k_read(int reg) { + unsigned long val; + val = omap_readw(reg + OMAP_32kHz_TIMER_BASE); + return val; +} +static inline void timer32k_write(int reg,int val) { + omap_writew(val, reg + OMAP_32kHz_TIMER_BASE); +} + +/* + * How long is the timer interval? 100 HZ, right... + * IRQ rate = (TVR + 1) / 32768 seconds + * TVR = 32768 * IRQ_RATE -1 + * IRQ_RATE = 1/100 + * TVR = 326 + */ +#define TIMER32k_PERIOD 326 +//#define TIMER32k_PERIOD 0x7ff + +static inline void start_timer32k(void) { + timer32k_write(TIMER32k_CR, + TIMER32k_TSS | TIMER32k_TRB | + TIMER32k_INT | TIMER32k_ARL); +} + +#ifdef CONFIG_MACH_OMAP_PERSEUS2 +/* + * After programming PTV with 0 and setting the MPUTIM_CLOCK_ENABLE + * (external clock enable) bit, the timer count rate is 6.5 MHz (13 + * MHZ input/2). !! The divider by 2 is undocumented !! + */ +#define MPUTICKS_PER_SEC (13000000/2) +#else +/* + * After programming PTV with 0, the timer count rate is 6 MHz. + * WARNING! this must be an even number, or machinecycles_to_usecs + * below will break. + */ +#define MPUTICKS_PER_SEC (12000000/2) +#endif + +static int mputimer_started[3] = {0,0,0}; + +static inline void __noinstrument start_mputimer(int n, + unsigned long load_val) +{ + volatile mputimer_regs_t* timer = mputimer_base(n); + + mputimer_started[n] = 0; + timer->cntl = MPUTIM_CLOCK_ENABLE; + udelay(1); + + timer->load_tim = load_val; + udelay(1); + timer->cntl = (MPUTIM_CLOCK_ENABLE | MPUTIM_AR | MPUTIM_ST); + mputimer_started[n] = 1; +} + +static inline unsigned long __noinstrument +read_mputimer(int n) +{ + volatile mputimer_regs_t* timer = mputimer_base(n); + return (mputimer_started[n] ? timer->read_tim : 0); +} + +void __noinstrument start_mputimer1(unsigned long load_val) +{ + start_mputimer(0, load_val); +} +void __noinstrument start_mputimer2(unsigned long load_val) +{ + start_mputimer(1, load_val); +} +void __noinstrument start_mputimer3(unsigned long load_val) +{ + start_mputimer(2, load_val); +} + +unsigned long __noinstrument read_mputimer1(void) +{ + return read_mputimer(0); +} +unsigned long __noinstrument read_mputimer2(void) +{ + return read_mputimer(1); +} +unsigned long __noinstrument read_mputimer3(void) +{ + return read_mputimer(2); +} + +unsigned long __noinstrument do_getmachinecycles(void) +{ + return 0 - read_mputimer(0); +} + +unsigned long __noinstrument machinecycles_to_usecs(unsigned long mputicks) +{ + /* Round up to nearest usec */ + return ((mputicks * 1000) / (MPUTICKS_PER_SEC / 2 / 1000) + 1) >> 1; +} + +/* + * This marks the time of the last system timer interrupt + * that was *processed by the ISR* (timer 2). + */ +static unsigned long systimer_mark; + +static unsigned long omap_gettimeoffset(void) +{ + /* Return elapsed usecs since last system timer ISR */ + return machinecycles_to_usecs(do_getmachinecycles() - systimer_mark); +} + +static irqreturn_t +omap_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long now, ilatency; + + /* + * Mark the time at which the timer interrupt ocurred using + * timer1. We need to remove interrupt latency, which we can + * retrieve from the current system timer2 counter. Both the + * offset timer1 and the system timer2 are counting at 6MHz, + * so we're ok. + */ + now = 0 - read_mputimer1(); + ilatency = MPUTICKS_PER_SEC / 100 - read_mputimer2(); + systimer_mark = now - ilatency; + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction omap_timer_irq = { + .name = "OMAP Timer Tick", + .flags = SA_INTERRUPT, + .handler = omap_timer_interrupt +}; + +void __init omap_init_time(void) +{ + /* Since we don't call request_irq, we must init the structure */ + gettimeoffset = omap_gettimeoffset; + +#ifdef OMAP1510_USE_32KHZ_TIMER + timer32k_write(TIMER32k_CR, 0x0); + timer32k_write(TIMER32k_TVR,TIMER32k_PERIOD); + setup_irq(INT_OS_32kHz_TIMER, &omap_timer_irq); + start_timer32k(); +#else + setup_irq(INT_TIMER2, &omap_timer_irq); + start_mputimer2(MPUTICKS_PER_SEC / 100 - 1); +#endif +} + diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile --- a/arch/arm/mach-pxa/Makefile 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-pxa/Makefile 2004-06-26 17:09:18 -07:00 @@ -3,7 +3,7 @@ # # Common support (must be linked before board specific support) -obj-y += generic.o irq.o dma.o +obj-y += generic.o irq.o dma.o time.o obj-$(CONFIG_PXA25x) += pxa25x.o obj-$(CONFIG_PXA27x) += pxa27x.o diff -Nru a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c --- a/arch/arm/mach-pxa/generic.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-pxa/generic.c 2004-06-26 17:09:16 -07:00 @@ -59,6 +59,24 @@ EXPORT_SYMBOL(pxa_gpio_mode); /* + * Routine to safely enable or disable a clock in the CKEN + */ +void pxa_set_cken(int clock, int enable) +{ + unsigned long flags; + local_irq_save(flags); + + if (enable) + CKEN |= clock; + else + CKEN &= ~clock; + + local_irq_restore(flags); +} + +EXPORT_SYMBOL(pxa_set_cken); + +/* * Intel PXA2xx internal register mapping. * * Note 1: not all PXA2xx variants implement all those addresses. @@ -180,10 +198,26 @@ .resource = pxafb_resources, }; +static struct platform_device ffuart_device = { + .name = "pxa2xx-uart", + .id = 0, +}; +static struct platform_device btuart_device = { + .name = "pxa2xx-uart", + .id = 1, +}; +static struct platform_device stuart_device = { + .name = "pxa2xx-uart", + .id = 2, +}; + static struct platform_device *devices[] __initdata = { &pxamci_device, &udc_device, &pxafb_device, + &ffuart_device, + &btuart_device, + &stuart_device, }; static int __init pxa_init(void) diff -Nru a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h --- a/arch/arm/mach-pxa/generic.h 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-pxa/generic.h 2004-06-26 17:09:20 -07:00 @@ -11,6 +11,7 @@ extern void __init pxa_map_io(void); extern void __init pxa_init_irq(void); +extern void __init pxa_init_time(void); #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ diff -Nru a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c --- a/arch/arm/mach-pxa/idp.c 2004-06-26 17:09:14 -07:00 +++ b/arch/arm/mach-pxa/idp.c 2004-06-26 17:09:14 -07:00 @@ -118,5 +118,6 @@ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) MAPIO(idp_map_io) INITIRQ(idp_init_irq) + INITTIME(pxa_init_time) INIT_MACHINE(idp_init) MACHINE_END diff -Nru a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c --- a/arch/arm/mach-pxa/lubbock.c 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/mach-pxa/lubbock.c 2004-06-26 17:09:17 -07:00 @@ -220,5 +220,6 @@ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) MAPIO(lubbock_map_io) INITIRQ(lubbock_init_irq) + INITTIME(pxa_init_time) INIT_MACHINE(lubbock_init) MACHINE_END diff -Nru a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c --- a/arch/arm/mach-pxa/mainstone.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-pxa/mainstone.c 2004-06-26 17:09:21 -07:00 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ #include #include +#include #include "generic.h" @@ -116,9 +118,66 @@ .resource = smc91x_resources, }; + +static void mainstone_backlight_power(int on) +{ + if (on) { + pxa_gpio_mode(GPIO16_PWM0_MD); + pxa_set_cken(CKEN0_PWM0, 1); + PWM_CTRL0 = 0; + PWM_PWDUTY0 = 0x3ff; + PWM_PERVAL0 = 0x3ff; + } else { + PWM_CTRL0 = 0; + PWM_PWDUTY0 = 0x0; + PWM_PERVAL0 = 0x3FF; + pxa_set_cken(CKEN0_PWM0, 0); + } +} + +static struct pxafb_mach_info toshiba_ltm04c380k __initdata = { + .pixclock = 50000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 1, + .left_margin = 0x9f, + .right_margin = 1, + .vsync_len = 44, + .upper_margin = 0, + .lower_margin = 0, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PCP, + .pxafb_backlight_power = mainstone_backlight_power, +}; + +static struct pxafb_mach_info toshiba_ltm035a776c __initdata = { + .pixclock = 110000, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 4, + .left_margin = 8, + .right_margin = 20, + .vsync_len = 3, + .upper_margin = 1, + .lower_margin = 10, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PCP, + .pxafb_backlight_power = mainstone_backlight_power, +}; + static void __init mainstone_init(void) { platform_add_device(&smc91x_device); + + /* reading the BSR might be handy to select LCD type here */ + if (0) + set_pxa_fb_info(&toshiba_ltm04c380k); + else + set_pxa_fb_info(&toshiba_ltm035a776c); } @@ -137,5 +196,6 @@ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) MAPIO(mainstone_map_io) INITIRQ(mainstone_init_irq) + INITTIME(pxa_init_time) INIT_MACHINE(mainstone_init) MACHINE_END diff -Nru a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-pxa/time.c 2004-06-26 17:09:17 -07:00 @@ -0,0 +1,124 @@ +/* + * arch/arm/mach-pxa/time.c + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +static inline unsigned long pxa_get_rtc_time(void) +{ + return RCNR; +} + +static int pxa_set_rtc(void) +{ + unsigned long current_time = xtime.tv_sec; + + if (RTSR & RTSR_ALE) { + /* make sure not to forward the clock over an alarm */ + unsigned long alarm = RTAR; + if (current_time >= alarm && alarm >= RCNR) + return -ERESTARTSYS; + } + RCNR = current_time; + return 0; +} + +/* IRQs are disabled before entering here from do_gettimeofday() */ +static unsigned long pxa_gettimeoffset (void) +{ + long ticks_to_match, elapsed, usec; + + /* Get ticks before next timer match */ + ticks_to_match = OSMR0 - OSCR; + + /* We need elapsed ticks since last match */ + elapsed = LATCH - ticks_to_match; + + /* don't get fooled by the workaround in pxa_timer_interrupt() */ + if (elapsed <= 0) + return 0; + + /* Now convert them to usec */ + usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; + + return usec; +} + +static irqreturn_t +pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int next_match; + + /* Loop until we get ahead of the free running timer. + * This ensures an exact clock tick count and time accuracy. + * IRQs are disabled inside the loop to ensure coherence between + * lost_ticks (updated in do_timer()) and the match reg value, so we + * can use do_gettimeofday() from interrupt handlers. + * + * HACK ALERT: it seems that the PXA timer regs aren't updated right + * away in all cases when a write occurs. We therefore compare with + * 8 instead of 0 in the while() condition below to avoid missing a + * match if OSCR has already reached the next OSMR value. + * Experience has shown that up to 6 ticks are needed to work around + * this problem, but let's use 8 to be conservative. Note that this + * affect things only when the timer IRQ has been delayed by nearly + * exactly one tick period which should be a pretty rare event. + */ + do { + timer_tick(regs); + OSSR = OSSR_M0; /* Clear match on timer 0 */ + next_match = (OSMR0 += LATCH); + } while( (signed long)(next_match - OSCR) <= 8 ); + + return IRQ_HANDLED; +} + +static struct irqaction pxa_timer_irq = { + .name = "PXA Timer Tick", + .flags = SA_INTERRUPT, + .handler = pxa_timer_interrupt +}; + +void __init pxa_init_time(void) +{ + struct timespec tv; + + gettimeoffset = pxa_gettimeoffset; + set_rtc = pxa_set_rtc; + + tv.tv_nsec = 0; + tv.tv_sec = pxa_get_rtc_time(); + do_settimeofday(&tv); + + OSMR0 = 0; /* set initial match at 0 */ + OSSR = 0xf; /* clear status on all timers */ + setup_irq(IRQ_OST0, &pxa_timer_irq); + OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ + OSCR = 0; /* initialize free-running timer, force first match */ +} + diff -Nru a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c --- a/arch/arm/mach-rpc/riscpc.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-rpc/riscpc.c 2004-06-26 17:09:19 -07:00 @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -25,6 +27,7 @@ #include #include +#include extern void rpc_init_irq(void); @@ -82,6 +85,31 @@ elf_hwcap &= ~HWCAP_HALF; } +static irqreturn_t +rpc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction rpc_timer_irq = { + .name = "RiscPC Timer Tick", + .flags = SA_INTERRUPT, + .handler = rpc_timer_interrupt +}; + +/* + * Set up timer interrupt. + */ +void __init rpc_init_time(void) +{ + extern void ioctime_init(void); + ioctime_init(); + + setup_irq(IRQ_TIMER, &rpc_timer_irq); +} + MACHINE_START(RISCPC, "Acorn-RiscPC") MAINTAINER("Russell King") BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) @@ -90,4 +118,5 @@ DISABLE_PARPORT(1) MAPIO(rpc_map_io) INITIRQ(rpc_init_irq) + INITTIME(rpc_init_time) MACHINE_END diff -Nru a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile --- a/arch/arm/mach-s3c2410/Makefile 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-s3c2410/Makefile 2004-06-26 17:09:16 -07:00 @@ -4,7 +4,7 @@ # Object file lists. -obj-y := s3c2410.o irq.o +obj-y := s3c2410.o irq.o time.o obj-m := obj-n := obj- := diff -Nru a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c --- a/arch/arm/mach-s3c2410/mach-bast.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-s3c2410/mach-bast.c 2004-06-26 17:09:18 -07:00 @@ -185,10 +185,16 @@ } +void __init bast_init_time(void) +{ + s3c2410_init_time(); +} + MACHINE_START(BAST, "Simtec-BAST") MAINTAINER("Ben Dooks ") BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART) BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) MAPIO(bast_map_io) INITIRQ(bast_init_irq) + INITTIME(bast_init_time) MACHINE_END diff -Nru a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c --- a/arch/arm/mach-s3c2410/mach-h1940.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-s3c2410/mach-h1940.c 2004-06-26 17:09:19 -07:00 @@ -91,10 +91,16 @@ } +void __init ipaq_init_time(void) +{ + s3c2410_init_time(); +} + MACHINE_START(H1940, "IPAQ-H1940") MAINTAINER("Ben Dooks ") BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART) BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) MAPIO(ipaq_map_io) INITIRQ(ipaq_init_irq) + INITTIME(ipaq_init_time) MACHINE_END diff -Nru a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c --- a/arch/arm/mach-s3c2410/mach-smdk2410.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c 2004-06-26 17:09:18 -07:00 @@ -99,6 +99,11 @@ s3c2410_init_irq(); } +void __init smdk2410_init_time(void) +{ + s3c2401_init_time(); +} + MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch * to SMDK2410 */ MAINTAINER("Jonas Dietsche") @@ -106,4 +111,5 @@ BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) MAPIO(smdk2410_map_io) INITIRQ(smdk2410_init_irq) + INITTIME(smdk2410_init_time) MACHINE_END diff -Nru a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c --- a/arch/arm/mach-s3c2410/mach-vr1000.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-s3c2410/mach-vr1000.c 2004-06-26 17:09:20 -07:00 @@ -155,10 +155,16 @@ } +void __init vr1000_init_time(void) +{ + s3c2401_init_time(); +} + MACHINE_START(VR1000, "Simtec-VR1000") MAINTAINER("Ben Dooks ") BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART) BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) MAPIO(vr1000_map_io) INITIRQ(vr1000_init_irq) + INITTIME(vr1000_init_time) MACHINE_END diff -Nru a/arch/arm/mach-s3c2410/s3c2410.h b/arch/arm/mach-s3c2410/s3c2410.h --- a/arch/arm/mach-s3c2410/s3c2410.h 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/mach-s3c2410/s3c2410.h 2004-06-26 17:09:17 -07:00 @@ -4,3 +4,5 @@ extern void s3c2410_init_irq(void); +extern s3c2410_init_time(void); + diff -Nru a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-s3c2410/time.c 2004-06-26 17:09:17 -07:00 @@ -0,0 +1,176 @@ +/* linux/include/asm-arm/arch-s3c2410/time.h + * + * Copyright (C) 2003 Simtec Electronics + * Ben Dooks, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static unsigned long timer_startval; +static unsigned long timer_ticks_usec; + +#ifdef CONFIG_S3C2410_RTC +extern void s3c2410_rtc_check(); +#endif + +/* with an 12MHz clock, we get 12 ticks per-usec + */ + + +/*** + * Returns microsecond since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + * IRQs are disabled before entering here from do_gettimeofday() + */ +static unsigned long s3c2410_gettimeoffset (void) +{ + unsigned long tdone; + unsigned long usec; + + /* work out how many ticks have gone since last timer interrupt */ + + tdone = timer_startval - __raw_readl(S3C2410_TCNTO(4)); + + /* currently, tcnt is in 12MHz units, but this may change + * for non-bast machines... + */ + + usec = tdone / timer_ticks_usec; + + return usec; +} + + +/* + * IRQ handler for the timer + */ +static irqreturn_t +s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction s3c2410_timer_irq = { + .name = "S32410 Timer Tick", + .flags = SA_INTERRUPT, + .handler = s3c2410_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + * + * Currently we only use timer4, as it is the only timer which has no + * other function that can be exploited externally + */ +void __init s3c2410_init_time (void) +{ + unsigned long tcon; + unsigned long tcnt; + unsigned long tcfg1; + unsigned long tcfg0; + + gettimeoffset = s3c2410_gettimeoffset; + + tcnt = 0xffff; /* default value for tcnt */ + + /* read the current timer configuration bits */ + + tcon = __raw_readl(S3C2410_TCON); + tcfg1 = __raw_readl(S3C2410_TCFG1); + tcfg0 = __raw_readl(S3C2410_TCFG0); + + /* configure the system for whichever machine is in use */ + + if (machine_is_bast() || machine_is_vr1000()) { + timer_ticks_usec = 12; /* timer is at 12MHz */ + tcnt = (timer_ticks_usec * (1000*1000)) / HZ; + } + + /* for the h1940, we use the pclk from the core to generate + * the timer values. since 67.5MHz is not a value we can directly + * generate the timer value from, we need to pre-scale and + * divied before using it. + * + * overall divsior to get 200Hz is 337500 + * we can fit tcnt if we pre-scale by 6, producing a tick rate + * of 11.25MHz, and a tcnt of 56250. + */ + + if (machine_is_h1940() || machine_is_smdk2410() ) { + timer_ticks_usec = s3c2410_pclk / (1000*1000); + timer_ticks_usec /= 6; + + tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; + tcfg1 |= S3C2410_TCFG1_MUX4_DIV2; + + tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; + tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT; + + tcnt = (s3c2410_pclk / 6) / HZ; + } + + + printk("setup_timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx\n", + tcon, tcnt, tcfg0, tcfg1); + + /* check to see if timer is within 16bit range... */ + if (tcnt > 0xffff) { + panic("setup_timer: HZ is too small, cannot configure timer!"); + return; + } + + __raw_writel(tcfg1, S3C2410_TCFG1); + __raw_writel(tcfg0, S3C2410_TCFG0); + + timer_startval = tcnt; + __raw_writel(tcnt, S3C2410_TCNTB(4)); + + /* ensure timer is stopped... */ + + tcon &= ~(7<<20); + tcon |= S3C2410_TCON_T4RELOAD; + tcon |= S3C2410_TCON_T4MANUALUPD; + + __raw_writel(tcon, S3C2410_TCON); + __raw_writel(tcnt, S3C2410_TCNTB(4)); + __raw_writel(tcnt, S3C2410_TCMPB(4)); + + setup_irq(IRQ_TIMER4, &s3c2410_timer_irq); + + /* start the timer running */ + tcon |= S3C2410_TCON_T4START; + tcon &= ~S3C2410_TCON_T4MANUALUPD; + __raw_writel(tcon, S3C2410_TCON); +} + + + diff -Nru a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile --- a/arch/arm/mach-sa1100/Makefile 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/Makefile 2004-06-26 17:09:21 -07:00 @@ -3,7 +3,7 @@ # # Common support -obj-y := generic.o irq.o dma.o +obj-y := generic.o irq.o dma.o time.o obj-m := obj-n := obj- := diff -Nru a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c --- a/arch/arm/mach-sa1100/adsbitsy.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/adsbitsy.c 2004-06-26 17:09:15 -07:00 @@ -147,4 +147,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(adsbitsy_map_io) INITIRQ(adsbitsy_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c --- a/arch/arm/mach-sa1100/assabet.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/assabet.c 2004-06-26 17:09:15 -07:00 @@ -324,5 +324,6 @@ FIXUP(fixup_assabet) MAPIO(assabet_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) INIT_MACHINE(assabet_init) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c --- a/arch/arm/mach-sa1100/badge4.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/badge4.c 2004-06-26 17:09:15 -07:00 @@ -245,4 +245,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(badge4_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/brutus.c b/arch/arm/mach-sa1100/brutus.c --- a/arch/arm/mach-sa1100/brutus.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-sa1100/brutus.c 2004-06-26 17:09:20 -07:00 @@ -37,4 +37,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(brutus_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c --- a/arch/arm/mach-sa1100/cerf.c 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/mach-sa1100/cerf.c 2004-06-26 17:09:17 -07:00 @@ -92,4 +92,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(cerf_map_io) INITIRQ(cerf_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/empeg.c b/arch/arm/mach-sa1100/empeg.c --- a/arch/arm/mach-sa1100/empeg.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-sa1100/empeg.c 2004-06-26 17:09:19 -07:00 @@ -35,4 +35,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(empeg_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/flexanet.c b/arch/arm/mach-sa1100/flexanet.c --- a/arch/arm/mach-sa1100/flexanet.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/flexanet.c 2004-06-26 17:09:21 -07:00 @@ -183,5 +183,6 @@ BOOT_PARAMS(0xc0000100) MAPIO(flexanet_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/freebird.c b/arch/arm/mach-sa1100/freebird.c --- a/arch/arm/mach-sa1100/freebird.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-sa1100/freebird.c 2004-06-26 17:09:16 -07:00 @@ -77,4 +77,5 @@ #endif MAPIO(freebird_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h --- a/arch/arm/mach-sa1100/generic.h 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-sa1100/generic.h 2004-06-26 17:09:19 -07:00 @@ -6,6 +6,7 @@ extern void __init sa1100_map_io(void); extern void __init sa1100_init_irq(void); +extern void __init sa1100_init_time(void); #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ diff -Nru a/arch/arm/mach-sa1100/graphicsclient.c b/arch/arm/mach-sa1100/graphicsclient.c --- a/arch/arm/mach-sa1100/graphicsclient.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-sa1100/graphicsclient.c 2004-06-26 17:09:20 -07:00 @@ -198,4 +198,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(graphicsclient_map_io) INITIRQ(graphicsclient_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c --- a/arch/arm/mach-sa1100/graphicsmaster.c 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/mach-sa1100/graphicsmaster.c 2004-06-26 17:09:17 -07:00 @@ -287,4 +287,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(graphicsmaster_map_io) INITIRQ(graphicsmaster_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c --- a/arch/arm/mach-sa1100/h3600.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-sa1100/h3600.c 2004-06-26 17:09:16 -07:00 @@ -286,6 +286,7 @@ BOOT_PARAMS(0xc0000100) MAPIO(h3100_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END #endif /* CONFIG_SA1100_H3100 */ @@ -400,6 +401,7 @@ BOOT_PARAMS(0xc0000100) MAPIO(h3600_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END #endif /* CONFIG_SA1100_H3600 */ @@ -783,6 +785,7 @@ BOOT_PARAMS(0xc0000100) MAPIO(h3800_map_io) INITIRQ(h3800_init_irq) + INITTIME(sa1100_init_time) MACHINE_END #endif /* CONFIG_SA1100_H3800 */ diff -Nru a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c --- a/arch/arm/mach-sa1100/hackkit.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/hackkit.c 2004-06-26 17:09:21 -07:00 @@ -174,4 +174,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(hackkit_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/huw_webpanel.c b/arch/arm/mach-sa1100/huw_webpanel.c --- a/arch/arm/mach-sa1100/huw_webpanel.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/huw_webpanel.c 2004-06-26 17:09:21 -07:00 @@ -81,4 +81,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(huw_webpanel_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/itsy.c b/arch/arm/mach-sa1100/itsy.c --- a/arch/arm/mach-sa1100/itsy.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-sa1100/itsy.c 2004-06-26 17:09:20 -07:00 @@ -37,4 +37,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(itsy_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c --- a/arch/arm/mach-sa1100/jornada720.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/jornada720.c 2004-06-26 17:09:21 -07:00 @@ -101,4 +101,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(jornada720_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c --- a/arch/arm/mach-sa1100/lart.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/lart.c 2004-06-26 17:09:21 -07:00 @@ -43,4 +43,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(lart_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c --- a/arch/arm/mach-sa1100/nanoengine.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/nanoengine.c 2004-06-26 17:09:15 -07:00 @@ -49,4 +49,5 @@ FIXUP(fixup_nanoengine) MAPIO(nanoengine_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/omnimeter.c b/arch/arm/mach-sa1100/omnimeter.c --- a/arch/arm/mach-sa1100/omnimeter.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/omnimeter.c 2004-06-26 17:09:15 -07:00 @@ -59,4 +59,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(omnimeter_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/pangolin.c b/arch/arm/mach-sa1100/pangolin.c --- a/arch/arm/mach-sa1100/pangolin.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-sa1100/pangolin.c 2004-06-26 17:09:20 -07:00 @@ -40,4 +40,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(pangolin_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/pfs168.c b/arch/arm/mach-sa1100/pfs168.c --- a/arch/arm/mach-sa1100/pfs168.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/pfs168.c 2004-06-26 17:09:15 -07:00 @@ -112,4 +112,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(pfs168_map_io) INITIRQ(pfs168_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c --- a/arch/arm/mach-sa1100/pleb.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm/mach-sa1100/pleb.c 2004-06-26 17:09:16 -07:00 @@ -31,4 +31,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(pleb_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c --- a/arch/arm/mach-sa1100/shannon.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/shannon.c 2004-06-26 17:09:21 -07:00 @@ -41,4 +41,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(shannon_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/sherman.c b/arch/arm/mach-sa1100/sherman.c --- a/arch/arm/mach-sa1100/sherman.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-sa1100/sherman.c 2004-06-26 17:09:18 -07:00 @@ -27,4 +27,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(sherman_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c --- a/arch/arm/mach-sa1100/simpad.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/simpad.c 2004-06-26 17:09:15 -07:00 @@ -231,4 +231,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(simpad_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/stork.c b/arch/arm/mach-sa1100/stork.c --- a/arch/arm/mach-sa1100/stork.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-sa1100/stork.c 2004-06-26 17:09:19 -07:00 @@ -331,6 +331,7 @@ BOOT_PARAMS(0xc0000100) MAPIO(stork_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/system3.c b/arch/arm/mach-sa1100/system3.c --- a/arch/arm/mach-sa1100/system3.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mach-sa1100/system3.c 2004-06-26 17:09:20 -07:00 @@ -470,4 +470,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(system3_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-sa1100/time.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,119 @@ +/* + * linux/arch/arm/mach-sa1100/time.c + * + * Copyright (C) 1998 Deborah Wallach. + * Twiddles (C) 1999 Hugo Fiennes + * + * 2000/03/29 (C) Nicolas Pitre + * Rewritten: big cleanup, much simpler, better HZ accuracy. + * + */ +#include +#include +#include +#include +#include + +#include +#include + +#define RTC_DEF_DIVIDER (32768 - 1) +#define RTC_DEF_TRIM 0 + +static unsigned long __init sa1100_get_rtc_time(void) +{ + /* + * According to the manual we should be able to let RTTR be zero + * and then a default diviser for a 32.768KHz clock is used. + * Apparently this doesn't work, at least for my SA1110 rev 5. + * If the clock divider is uninitialized then reset it to the + * default value to get the 1Hz clock. + */ + if (RTTR == 0) { + RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); + printk(KERN_WARNING "Warning: uninitialized Real Time Clock\n"); + /* The current RTC value probably doesn't make sense either */ + RCNR = 0; + return 0; + } + return RCNR; +} + +static int sa1100_set_rtc(void) +{ + unsigned long current_time = xtime.tv_sec; + + if (RTSR & RTSR_ALE) { + /* make sure not to forward the clock over an alarm */ + unsigned long alarm = RTAR; + if (current_time >= alarm && alarm >= RCNR) + return -ERESTARTSYS; + } + RCNR = current_time; + return 0; +} + +/* IRQs are disabled before entering here from do_gettimeofday() */ +static unsigned long sa1100_gettimeoffset (void) +{ + unsigned long ticks_to_match, elapsed, usec; + + /* Get ticks before next timer match */ + ticks_to_match = OSMR0 - OSCR; + + /* We need elapsed ticks since last match */ + elapsed = LATCH - ticks_to_match; + + /* Now convert them to usec */ + usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; + + return usec; +} + +/* + * We will be entered with IRQs enabled. + * + * Loop until we get ahead of the free running timer. + * This ensures an exact clock tick count and time accuracy. + * IRQs are disabled inside the loop to ensure coherence between + * lost_ticks (updated in do_timer()) and the match reg value, so we + * can use do_gettimeofday() from interrupt handlers. + */ +static irqreturn_t +sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int next_match; + + do { + timer_tick(regs); + OSSR = OSSR_M0; /* Clear match on timer 0 */ + next_match = (OSMR0 += LATCH); + } while ((signed long)(next_match - OSCR) <= 0); + + return IRQ_HANDLED; +} + +static struct irqaction sa1100_timer_irq = { + .name = "SA11xx Timer Tick", + .flags = SA_INTERRUPT, + .handler = sa1100_timer_interrupt +}; + +void __init sa1100_init_time(void) +{ + struct timespec tv; + + gettimeoffset = sa1100_gettimeoffset; + set_rtc = sa1100_set_rtc; + + tv.tv_nsec = 0; + tv.tv_sec = sa1100_get_rtc_time(); + do_settimeofday(&tv); + + OSMR0 = 0; /* set initial match at 0 */ + OSSR = 0xf; /* clear status on all timers */ + setup_irq(IRQ_OST0, &sa1100_timer_irq); + OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ + OSCR = 0; /* initialize free-running timer, force first match */ +} + diff -Nru a/arch/arm/mach-sa1100/trizeps.c b/arch/arm/mach-sa1100/trizeps.c --- a/arch/arm/mach-sa1100/trizeps.c 2004-06-26 17:09:21 -07:00 +++ b/arch/arm/mach-sa1100/trizeps.c 2004-06-26 17:09:21 -07:00 @@ -228,4 +228,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(trizeps_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/xp860.c b/arch/arm/mach-sa1100/xp860.c --- a/arch/arm/mach-sa1100/xp860.c 2004-06-26 17:09:18 -07:00 +++ b/arch/arm/mach-sa1100/xp860.c 2004-06-26 17:09:18 -07:00 @@ -89,4 +89,5 @@ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) MAPIO(xp860_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-sa1100/yopy.c b/arch/arm/mach-sa1100/yopy.c --- a/arch/arm/mach-sa1100/yopy.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-sa1100/yopy.c 2004-06-26 17:09:15 -07:00 @@ -91,4 +91,5 @@ BOOT_PARAMS(0xc0000100) MAPIO(yopy_map_io) INITIRQ(sa1100_init_irq) + INITTIME(sa1100_init_time) MACHINE_END diff -Nru a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c --- a/arch/arm/mach-shark/core.c 2004-06-26 17:09:19 -07:00 +++ b/arch/arm/mach-shark/core.c 2004-06-26 17:09:19 -07:00 @@ -5,13 +5,18 @@ */ #include #include +#include +#include #include #include #include +#include +#include #include #include +#include extern void shark_init_irq(void); @@ -24,10 +29,43 @@ iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc)); } +#define IRQ_TIMER 0 +#define HZ_TIME ((1193180 + HZ/2) / HZ) + +static irqreturn_t +shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction shark_timer_irq = { + .name = "Shark Timer Tick", + .flags = SA_INTERRUPT, + .handler = shark_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init shark_init_time(void) +{ + unsigned long flags; + + outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */ + outb(HZ_TIME & 0xff, 0x40); /* LSB of count */ + outb(HZ_TIME >> 8, 0x40); + + setup_irq(IRQ_TIMER, &shark_timer_irq); +} + + MACHINE_START(SHARK, "Shark") MAINTAINER("Alexander Schulz") BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) BOOT_PARAMS(0x08003000) MAPIO(shark_map_io) INITIRQ(shark_init_irq) + INITTIME(shark_init_time) MACHINE_END diff -Nru a/arch/arm/mach-tbox/Makefile b/arch/arm/mach-tbox/Makefile --- a/arch/arm/mach-tbox/Makefile 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,11 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := core.o -obj-m := -obj-n := -obj- := - diff -Nru a/arch/arm/mach-tbox/core.c b/arch/arm/mach-tbox/core.c --- a/arch/arm/mach-tbox/core.c 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,73 +0,0 @@ -/* - * linux/arch/arm/mm/mm-tbox.c - * - * Copyright (C) 1998, 1999, 2000 Phil Blundell - * Copyright (C) 1998-1999 Russell King - * - * Extra MM routines for the Tbox architecture - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -extern unsigned long soft_irq_mask; - -static void tbox_mask_irq(unsigned int irq) -{ - __raw_writel(0, INTCONT + (irq << 2)); - soft_irq_mask &= ~(1<= 12 && i <= 13)) { - irq_desc[i].valid = 1; - irq_desc[i].probe_ok = 0; - irq_desc[i].mask_ack = tbox_mask_irq; - irq_desc[i].mask = tbox_mask_irq; - irq_desc[i].unmask = tbox_unmask_irq; - tbox_mask_irq(i); - } else { - irq_desc[i].valid = 0; - irq_desc[i].probe_ok = 0; - } - } -} - -static struct map_desc tbox_io_desc[] __initdata = { - /* See hardware.h for details */ - { IO_BASE, IO_START, 0x00100000, MT_DEVICE } -}; - -static void __init tbox_map_io(void) -{ - iotable_init(tbox_io_desc, ARRAY_SIZE(tbox_io_desc)); -} - -MACHINE_START(TBOX, "unknown-TBOX") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x80000000, 0x00400000, 0xe0000000) - MAPIO(tbox_map_io) - INITIRQ(tbox_init_irq) -MACHINE_END - diff -Nru a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile --- a/arch/arm/mach-versatile/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mach-versatile/Makefile 2004-06-26 17:09:15 -07:00 @@ -2,4 +2,4 @@ # Makefile for the linux kernel. # -obj-y := core.o +obj-y := core.o clock.o diff -Nru a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-versatile/clock.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,146 @@ +/* + * linux/arch/arm/mach-versatile/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clock.h" + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + down(&clocks_sem); + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + up(&clocks_sem); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +int clk_use(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_use); + +void clk_unuse(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_unuse); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return rate; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EIO; +#if 0 // Not yet + if (clk->setvco) { + struct icst525_vco vco; + + vco = icst525_khz_to_vco(clk->params, rate); + clk->rate = icst525_khz(clk->params, vco); + + printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n", + clk->name, vco.s, vco.r, vco.v); + + clk->setvco(clk, vco); + ret = 0; + } +#endif + return 0; +} +EXPORT_SYMBOL(clk_set_rate); + +/* + * These are fixed clocks. + */ +static struct clk kmi_clk = { + .name = "KMIREFCLK", + .rate = 24000000, +}; + +static struct clk uart_clk = { + .name = "UARTCLK", + .rate = 24000000, +}; + +static struct clk mmci_clk = { + .name = "MCLK", + .rate = 33000000, +}; + +int clk_register(struct clk *clk) +{ + down(&clocks_sem); + list_add(&clk->node, &clocks); + up(&clocks_sem); + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + down(&clocks_sem); + list_del(&clk->node); + up(&clocks_sem); +} +EXPORT_SYMBOL(clk_unregister); + +static int __init clk_init(void) +{ + clk_register(&kmi_clk); + clk_register(&uart_clk); + clk_register(&mmci_clk); + return 0; +} +arch_initcall(clk_init); diff -Nru a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/mach-versatile/clock.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/mach-versatile/clock.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +struct module; +struct icst525_params; + +struct clk { + struct list_head node; + unsigned long rate; + struct module *owner; + const char *name; + const struct icst525_params *params; + void *data; + void (*setvco)(struct clk *, struct icst525_vco vco); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); diff -Nru a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c --- a/arch/arm/mach-versatile/core.c 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/mach-versatile/core.c 2004-06-26 17:09:17 -07:00 @@ -22,7 +22,9 @@ #include #include #include +#include +#include #include #include #include @@ -33,6 +35,7 @@ #include #include #include +#include #include #ifdef CONFIG_MMC #include @@ -500,8 +503,8 @@ { int i; - platform_add_device(&versatile_flash_device); - platform_add_device(&smc91x_device); + platform_device_register(&versatile_flash_device); + platform_device_register(&smc91x_device); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; @@ -511,11 +514,153 @@ leds_event = versatile_leds_event; } +/* + * Where is the timer (VA)? + */ +#define TIMER0_VA_BASE IO_ADDRESS(VERSATILE_TIMER0_1_BASE) +#define TIMER1_VA_BASE (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20) +#define TIMER2_VA_BASE IO_ADDRESS(VERSATILE_TIMER2_3_BASE) +#define TIMER3_VA_BASE (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20) +#define VA_IC_BASE IO_ADDRESS(VERSATILE_VIC_BASE) + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ +#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ +#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) +#elif TIMER_INTERVAL >= 0x10000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ +#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ +#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) +#else +#define TIMER_RELOAD (TIMER_INTERVAL) +#define TIMER_CTRL 0x80 /* Enable */ +#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) +#endif + +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ + +/* + * What does it look like? + */ +typedef struct TimerStruct { + unsigned long TimerLoad; + unsigned long TimerValue; + unsigned long TimerControl; + unsigned long TimerClear; +} TimerStruct_t; + +extern unsigned long (*gettimeoffset)(void); + +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +static unsigned long versatile_gettimeoffset(void) +{ + volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; + unsigned long ticks1, ticks2, status; + + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks2 = timer0->TimerValue & 0xffff; + do { + ticks1 = ticks2; + status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); + ticks2 = timer0->TimerValue & 0xffff; + } while (ticks2 > ticks1); + + /* + * Number of ticks since last interrupt. + */ + ticks1 = TIMER_RELOAD - ticks2; + + /* + * Interrupt pending? If so, we've reloaded once already. + * + * FIXME: Need to check this is effectively timer 0 that expires + */ + if (status & IRQMASK_TIMERINT0_1) + ticks1 += TIMER_RELOAD; + + /* + * Convert the ticks to usecs + */ + return TICKS2USECS(ticks1); +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; + + // ...clear the interrupt + timer0->TimerClear = 1; + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction versatile_timer_irq = { + .name = "Versatile Timer Tick", + .flags = SA_INTERRUPT, + .handler = versatile_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init versatile_init_time(void) +{ + volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; + volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; + + /* + * set clock frequency: + * VERSATILE_REFCLK is 32KHz + * VERSATILE_TIMCLK is 1MHz + */ + *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= + ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); + + /* + * Initialise to a known state (all timers off) + */ + timer0->TimerControl = 0; + timer1->TimerControl = 0; + timer2->TimerControl = 0; + timer3->TimerControl = 0; + + timer0->TimerLoad = TIMER_RELOAD; + timer0->TimerValue = TIMER_RELOAD; + timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ + + /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); + gettimeoffset = versatile_gettimeoffset; +} + MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) BOOT_PARAMS(0x00000100) MAPIO(versatile_map_io) INITIRQ(versatile_init_irq) + INITTIME(versatile_init_time) INIT_MACHINE(versatile_init) MACHINE_END diff -Nru a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig --- a/arch/arm/mm/Kconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/arm/mm/Kconfig 2004-06-26 17:09:17 -07:00 @@ -220,7 +220,7 @@ # XScale config CPU_XSCALE bool - depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA || ARCH_IXP4XX + depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX default y select CPU_32v5 select CPU_ABRT_EV5T diff -Nru a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c --- a/arch/arm/mm/consistent.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm/mm/consistent.c 2004-06-26 17:09:20 -07:00 @@ -194,7 +194,7 @@ /* * Set the "dma handle" */ - *handle = page_to_bus(page); + *handle = page_to_dma(dev, page); do { BUG_ON(!pte_none(*pte)); diff -Nru a/arch/arm/mm/init.c b/arch/arm/mm/init.c --- a/arch/arm/mm/init.c 2004-06-26 17:09:15 -07:00 +++ b/arch/arm/mm/init.c 2004-06-26 17:09:15 -07:00 @@ -58,7 +58,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for (node = 0; node < numnodes; node++) { struct page *page, *end; diff -Nru a/arch/arm/vfp/Makefile b/arch/arm/vfp/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,12 @@ +# +# linux/arch/arm/vfp/Makefile +# +# Copyright (C) 2001 ARM Limited +# + +# EXTRA_CFLAGS := -DDEBUG +# EXTRA_AFLAGS := -DDEBUG + +obj-y += vfp.o + +vfp-$(CONFIG_VFP) += entry.o vfpmodule.o vfphw.o vfpsingle.o vfpdouble.o diff -Nru a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/entry.S 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/vfp/entry.S + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Basic entry code, called from the kernel's undefined instruction trap. + * r0 = faulted instruction + * r5 = faulted PC+4 + * r9 = successful return + * r10 = thread_info structure + * lr = failure return + */ +#include +#include +#include +#include + + .globl do_vfp +do_vfp: + ldr r4, .LCvfp + add r10, r10, #TI_VFPSTATE @ r10 = workspace + ldr pc, [r4] @ call VFP entry point + +.LCvfp: + .word vfp_vector + +@ This code is called if the VFP does not exist. It needs to flag the +@ failure to the VFP initialisation code. + + __INIT + .globl vfp_testing_entry +vfp_testing_entry: + ldr r0, VFP_arch_address + str r5, [r0] @ known non-zero value + mov pc, r9 @ we have handled the fault + +VFP_arch_address: + .word VFP_arch + + __FINIT diff -Nru a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/vfp.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,333 @@ +/* + * linux/arch/arm/vfp/vfp.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) +{ + if (shift) { + if (shift < 32) + val = val >> shift | ((val << (32 - shift)) != 0); + else + val = val != 0; + } + return val; +} + +static inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift) +{ + if (shift) { + if (shift < 64) + val = val >> shift | ((val << (64 - shift)) != 0); + else + val = val != 0; + } + return val; +} + +static inline u32 vfp_hi64to32jamming(u64 val) +{ + u32 v; + + asm( + "cmp %Q1, #1 @ vfp_hi64to32jamming\n\t" + "movcc %0, %R1\n\t" + "orrcs %0, %R1, #1" + : "=r" (v) : "r" (val) : "cc"); + + return v; +} + +static inline void add128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml) +{ + asm( "adds %Q0, %Q2, %Q4\n\t" + "adcs %R0, %R2, %R4\n\t" + "adcs %Q1, %Q3, %Q5\n\t" + "adc %R1, %R3, %R5" + : "=r" (nl), "=r" (nh) + : "0" (nl), "1" (nh), "r" (ml), "r" (mh) + : "cc"); + *resh = nh; + *resl = nl; +} + +static inline void sub128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml) +{ + asm( "subs %Q0, %Q2, %Q4\n\t" + "sbcs %R0, %R2, %R4\n\t" + "sbcs %Q1, %Q3, %Q5\n\t" + "sbc %R1, %R3, %R5\n\t" + : "=r" (nl), "=r" (nh) + : "0" (nl), "1" (nh), "r" (ml), "r" (mh) + : "cc"); + *resh = nh; + *resl = nl; +} + +static inline void mul64to128(u64 *resh, u64 *resl, u64 n, u64 m) +{ + u32 nh, nl, mh, ml; + u64 rh, rma, rmb, rl; + + nl = n; + ml = m; + rl = (u64)nl * ml; + + nh = n >> 32; + rma = (u64)nh * ml; + + mh = m >> 32; + rmb = (u64)nl * mh; + rma += rmb; + + rh = (u64)nh * mh; + rh += ((u64)(rma < rmb) << 32) + (rma >> 32); + + rma <<= 32; + rl += rma; + rh += (rl < rma); + + *resl = rl; + *resh = rh; +} + +static inline void shift64left(u64 *resh, u64 *resl, u64 n) +{ + *resh = n >> 63; + *resl = n << 1; +} + +static inline u64 vfp_hi64multiply64(u64 n, u64 m) +{ + u64 rh, rl; + mul64to128(&rh, &rl, n, m); + return rh | (rl != 0); +} + +static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) +{ + u64 mh, ml, remh, reml, termh, terml, z; + + if (nh >= m) + return ~0ULL; + mh = m >> 32; + z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32; + mul64to128(&termh, &terml, m, z); + sub128(&remh, &reml, nh, nl, termh, terml); + ml = m << 32; + while ((s64)remh < 0) { + z -= 0x100000000ULL; + add128(&remh, &reml, remh, reml, mh, ml); + } + remh = (remh << 32) | (reml >> 32); + z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh; + return z; +} + +/* + * Operations on unpacked elements + */ +#define vfp_sign_negate(sign) (sign ^ 0x8000) + +/* + * Single-precision + */ +struct vfp_single { + s16 exponent; + u16 sign; + u32 significand; +}; + +extern s32 vfp_get_float(unsigned int reg); +extern void vfp_put_float(unsigned int reg, s32 val); + +/* + * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa + * VFP_SINGLE_EXPONENT_BITS - number of bits in the exponent + * VFP_SINGLE_LOW_BITS - number of low bits in the unpacked significand + * which are not propagated to the float upon packing. + */ +#define VFP_SINGLE_MANTISSA_BITS (23) +#define VFP_SINGLE_EXPONENT_BITS (8) +#define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2) +#define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1) + +/* + * The bit in an unpacked float which indicates that it is a quiet NaN + */ +#define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS)) + +/* + * Operations on packed single-precision numbers + */ +#define vfp_single_packed_sign(v) ((v) & 0x80000000) +#define vfp_single_packed_negate(v) ((v) ^ 0x80000000) +#define vfp_single_packed_abs(v) ((v) & ~0x80000000) +#define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1)) +#define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1)) + +/* + * Unpack a single-precision float. Note that this returns the magnitude + * of the single-precision float mantissa with the 1. if necessary, + * aligned to bit 30. + */ +static inline void vfp_single_unpack(struct vfp_single *s, s32 val) +{ + u32 significand; + + s->sign = vfp_single_packed_sign(val) >> 16, + s->exponent = vfp_single_packed_exponent(val); + + significand = (u32) val; + significand = (significand << (32 - VFP_SINGLE_MANTISSA_BITS)) >> 2; + if (s->exponent && s->exponent != 255) + significand |= 0x40000000; + s->significand = significand; +} + +/* + * Re-pack a single-precision float. This assumes that the float is + * already normalised such that the MSB is bit 30, _not_ bit 31. + */ +static inline s32 vfp_single_pack(struct vfp_single *s) +{ + u32 val; + val = (s->sign << 16) + + (s->exponent << VFP_SINGLE_MANTISSA_BITS) + + (s->significand >> VFP_SINGLE_LOW_BITS); + return (s32)val; +} + +#define VFP_NUMBER (1<<0) +#define VFP_ZERO (1<<1) +#define VFP_DENORMAL (1<<2) +#define VFP_INFINITY (1<<3) +#define VFP_NAN (1<<4) +#define VFP_NAN_SIGNAL (1<<5) + +#define VFP_QNAN (VFP_NAN) +#define VFP_SNAN (VFP_NAN|VFP_NAN_SIGNAL) + +static inline int vfp_single_type(struct vfp_single *s) +{ + int type = VFP_NUMBER; + if (s->exponent == 255) { + if (s->significand == 0) + type = VFP_INFINITY; + else if (s->significand & VFP_SINGLE_SIGNIFICAND_QNAN) + type = VFP_QNAN; + else + type = VFP_SNAN; + } else if (s->exponent == 0) { + if (s->significand == 0) + type |= VFP_ZERO; + else + type |= VFP_DENORMAL; + } + return type; +} + +#ifndef DEBUG +#define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except) +u32 __vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions); +#else +u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func); +#endif + +/* + * Double-precision + */ +struct vfp_double { + s16 exponent; + u16 sign; + u64 significand; +}; + +extern u64 vfp_get_double(unsigned int reg); +extern void vfp_put_double(unsigned int reg, u64 val); + +#define VFP_DOUBLE_MANTISSA_BITS (52) +#define VFP_DOUBLE_EXPONENT_BITS (11) +#define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2) +#define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1) + +/* + * The bit in an unpacked double which indicates that it is a quiet NaN + */ +#define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS)) + +/* + * Operations on packed single-precision numbers + */ +#define vfp_double_packed_sign(v) ((v) & (1ULL << 63)) +#define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63)) +#define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63)) +#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1)) +#define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1)) + +/* + * Unpack a double-precision float. Note that this returns the magnitude + * of the double-precision float mantissa with the 1. if necessary, + * aligned to bit 62. + */ +static inline void vfp_double_unpack(struct vfp_double *s, s64 val) +{ + u64 significand; + + s->sign = vfp_double_packed_sign(val) >> 48; + s->exponent = vfp_double_packed_exponent(val); + + significand = (u64) val; + significand = (significand << (64 - VFP_DOUBLE_MANTISSA_BITS)) >> 2; + if (s->exponent && s->exponent != 2047) + significand |= (1ULL << 62); + s->significand = significand; +} + +/* + * Re-pack a double-precision float. This assumes that the float is + * already normalised such that the MSB is bit 30, _not_ bit 31. + */ +static inline s64 vfp_double_pack(struct vfp_double *s) +{ + u64 val; + val = ((u64)s->sign << 48) + + ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) + + (s->significand >> VFP_DOUBLE_LOW_BITS); + return (s64)val; +} + +static inline int vfp_double_type(struct vfp_double *s) +{ + int type = VFP_NUMBER; + if (s->exponent == 2047) { + if (s->significand == 0) + type = VFP_INFINITY; + else if (s->significand & VFP_DOUBLE_SIGNIFICAND_QNAN) + type = VFP_QNAN; + else + type = VFP_SNAN; + } else if (s->exponent == 0) { + if (s->significand == 0) + type |= VFP_ZERO; + else + type |= VFP_DENORMAL; + } + return type; +} + +u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); + +/* + * System registers + */ +extern u32 vfp_get_sys(unsigned int reg); +extern void vfp_put_sys(unsigned int reg, u32 val); + +u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); diff -Nru a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/vfpdouble.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1186 @@ +/* + * linux/arch/arm/vfp/vfpdouble.c + * + * This code is derived in part from John R. Housers softfloat library, which + * carries the following notice: + * + * =========================================================================== + * This C source file is part of the SoftFloat IEC/IEEE Floating-point + * Arithmetic Package, Release 2. + * + * Written by John R. Hauser. This work was made possible in part by the + * International Computer Science Institute, located at Suite 600, 1947 Center + * Street, Berkeley, California 94704. Funding was partially provided by the + * National Science Foundation under grant MIP-9311980. The original version + * of this code was written as part of a project to build a fixed-point vector + * processor in collaboration with the University of California at Berkeley, + * overseen by Profs. Nelson Morgan and John Wawrzynek. More information + * is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ + * arithmetic/softfloat.html'. + * + * THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort + * has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT + * TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO + * PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY + * AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + * + * Derivative works are acceptable, even for commercial purposes, so long as + * (1) they include prominent notice that the work is derivative, and (2) they + * include prominent notice akin to these three paragraphs for those parts of + * this code that are retained. + * =========================================================================== + */ +#include +#include +#include +#include + +#include "vfpinstr.h" +#include "vfp.h" + +static struct vfp_double vfp_double_default_qnan = { + .exponent = 2047, + .sign = 0, + .significand = VFP_DOUBLE_SIGNIFICAND_QNAN, +}; + +static void vfp_double_dump(const char *str, struct vfp_double *d) +{ + pr_debug("VFP: %s: sign=%d exponent=%d significand=%016llx\n", + str, d->sign != 0, d->exponent, d->significand); +} + +static void vfp_double_normalise_denormal(struct vfp_double *vd) +{ + int bits = 31 - fls(vd->significand >> 32); + if (bits == 31) + bits = 62 - fls(vd->significand); + + vfp_double_dump("normalise_denormal: in", vd); + + if (bits) { + vd->exponent -= bits - 1; + vd->significand <<= bits; + } + + vfp_double_dump("normalise_denormal: out", vd); +} + +u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func) +{ + u64 significand, incr; + int exponent, shift, underflow; + u32 rmode; + + vfp_double_dump("pack: in", vd); + + /* + * Infinities and NaNs are a special case. + */ + if (vd->exponent == 2047 && (vd->significand == 0 || exceptions)) + goto pack; + + /* + * Special-case zero. + */ + if (vd->significand == 0) { + vd->exponent = 0; + goto pack; + } + + exponent = vd->exponent; + significand = vd->significand; + + shift = 32 - fls(significand >> 32); + if (shift == 32) + shift = 64 - fls(significand); + if (shift) { + exponent -= shift; + significand <<= shift; + } + +#ifdef DEBUG + vd->exponent = exponent; + vd->significand = significand; + vfp_double_dump("pack: normalised", vd); +#endif + + /* + * Tiny number? + */ + underflow = exponent < 0; + if (underflow) { + significand = vfp_shiftright64jamming(significand, -exponent); + exponent = 0; +#ifdef DEBUG + vd->exponent = exponent; + vd->significand = significand; + vfp_double_dump("pack: tiny number", vd); +#endif + if (!(significand & ((1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1))) + underflow = 0; + } + + /* + * Select rounding increment. + */ + incr = 0; + rmode = fpscr & FPSCR_RMODE_MASK; + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 1ULL << VFP_DOUBLE_LOW_BITS; + if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0)) + incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1; + + pr_debug("VFP: rounding increment = 0x%08llx\n", incr); + + /* + * Is our rounding going to overflow? + */ + if ((significand + incr) < significand) { + exponent += 1; + significand = (significand >> 1) | (significand & 1); + incr >>= 1; +#ifdef DEBUG + vd->exponent = exponent; + vd->significand = significand; + vfp_double_dump("pack: overflow", vd); +#endif + } + + /* + * If any of the low bits (which will be shifted out of the + * number) are non-zero, the result is inexact. + */ + if (significand & ((1 << (VFP_DOUBLE_LOW_BITS + 1)) - 1)) + exceptions |= FPSCR_IXC; + + /* + * Do our rounding. + */ + significand += incr; + + /* + * Infinity? + */ + if (exponent >= 2046) { + exceptions |= FPSCR_OFC | FPSCR_IXC; + if (incr == 0) { + vd->exponent = 2045; + vd->significand = 0x7fffffffffffffffULL; + } else { + vd->exponent = 2047; /* infinity */ + vd->significand = 0; + } + } else { + if (significand >> (VFP_DOUBLE_LOW_BITS + 1) == 0) + exponent = 0; + if (exponent || significand > 0x8000000000000000ULL) + underflow = 0; + if (underflow) + exceptions |= FPSCR_UFC; + vd->exponent = exponent; + vd->significand = significand >> 1; + } + + pack: + vfp_double_dump("pack: final", vd); + { + s64 d = vfp_double_pack(vd); + pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, + dd, d, exceptions); + vfp_put_double(dd, d); + } + return exceptions; +} + +/* + * Propagate the NaN, setting exceptions if it is signalling. + * 'n' is always a NaN. 'm' may be a number, NaN or infinity. + */ +static u32 +vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + struct vfp_double *nan; + int tn, tm = 0; + + tn = vfp_double_type(vdn); + + if (vdm) + tm = vfp_double_type(vdm); + + if (fpscr & FPSCR_DEFAULT_NAN) + /* + * Default NaN mode - always returns a quiet NaN + */ + nan = &vfp_double_default_qnan; + else { + /* + * Contemporary mode - select the first signalling + * NAN, or if neither are signalling, the first + * quiet NAN. + */ + if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN)) + nan = vdn; + else + nan = vdm; + /* + * Make the NaN quiet. + */ + nan->significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; + } + + *vdd = *nan; + + /* + * If one was a signalling NAN, raise invalid operation. + */ + return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : 0x100; +} + +/* + * Extended operations + */ +static u32 vfp_double_fabs(int dd, int unused, int dm, u32 fpscr) +{ + vfp_put_double(dd, vfp_double_packed_abs(vfp_get_double(dm))); + return 0; +} + +static u32 vfp_double_fcpy(int dd, int unused, int dm, u32 fpscr) +{ + vfp_put_double(dd, vfp_get_double(dm)); + return 0; +} + +static u32 vfp_double_fneg(int dd, int unused, int dm, u32 fpscr) +{ + vfp_put_double(dd, vfp_double_packed_negate(vfp_get_double(dm))); + return 0; +} + +static u32 vfp_double_fsqrt(int dd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm, vdd; + int ret, tm; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + tm = vfp_double_type(&vdm); + if (tm & (VFP_NAN|VFP_INFINITY)) { + struct vfp_double *vdp = &vdd; + + if (tm & VFP_NAN) + ret = vfp_propagate_nan(vdp, &vdm, NULL, fpscr); + else if (vdm.sign == 0) { + sqrt_copy: + vdp = &vdm; + ret = 0; + } else { + sqrt_invalid: + vdp = &vfp_double_default_qnan; + ret = FPSCR_IOC; + } + vfp_put_double(dd, vfp_double_pack(vdp)); + return ret; + } + + /* + * sqrt(+/- 0) == +/- 0 + */ + if (tm & VFP_ZERO) + goto sqrt_copy; + + /* + * Normalise a denormalised number + */ + if (tm & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdm); + + /* + * sqrt(<0) = invalid + */ + if (vdm.sign) + goto sqrt_invalid; + + vfp_double_dump("sqrt", &vdm); + + /* + * Estimate the square root. + */ + vdd.sign = 0; + vdd.exponent = ((vdm.exponent - 1023) >> 1) + 1023; + vdd.significand = (u64)vfp_estimate_sqrt_significand(vdm.exponent, vdm.significand >> 32) << 31; + + vfp_double_dump("sqrt estimate1", &vdd); + + vdm.significand >>= 1 + (vdm.exponent & 1); + vdd.significand += 2 + vfp_estimate_div128to64(vdm.significand, 0, vdd.significand); + + vfp_double_dump("sqrt estimate2", &vdd); + + /* + * And now adjust. + */ + if ((vdd.significand & VFP_DOUBLE_LOW_BITS_MASK) <= 5) { + if (vdd.significand < 2) { + vdd.significand = ~0ULL; + } else { + u64 termh, terml, remh, reml; + vdm.significand <<= 2; + mul64to128(&termh, &terml, vdd.significand, vdd.significand); + sub128(&remh, &reml, vdm.significand, 0, termh, terml); + while ((s64)remh < 0) { + vdd.significand -= 1; + shift64left(&termh, &terml, vdd.significand); + terml |= 1; + add128(&remh, &reml, remh, reml, termh, terml); + } + vdd.significand |= (remh | reml) != 0; + } + } + vdd.significand = vfp_shiftright64jamming(vdd.significand, 1); + + return vfp_double_normaliseround(dd, &vdd, fpscr, 0, "fsqrt"); +} + +/* + * Equal := ZC + * Less than := N + * Greater than := C + * Unordered := CV + */ +static u32 vfp_compare(int dd, int signal_on_qnan, int dm, u32 fpscr) +{ + s64 d, m; + u32 ret = 0; + + m = vfp_get_double(dm); + if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + d = vfp_get_double(dd); + if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + if (ret == 0) { + if (d == m || vfp_double_packed_abs(d | m) == 0) { + /* + * equal + */ + ret |= FPSCR_Z | FPSCR_C; + } else if (vfp_double_packed_sign(d ^ m)) { + /* + * different signs + */ + if (vfp_double_packed_sign(d)) + /* + * d is negative, so d < m + */ + ret |= FPSCR_N; + else + /* + * d is positive, so d > m + */ + ret |= FPSCR_C; + } else if ((vfp_double_packed_sign(d) != 0) ^ (d < m)) { + /* + * d < m + */ + ret |= FPSCR_N; + } else if ((vfp_double_packed_sign(d) != 0) ^ (d > m)) { + /* + * d > m + */ + ret |= FPSCR_C; + } + } + + return ret; +} + +static u32 vfp_double_fcmp(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 0, dm, fpscr); +} + +static u32 vfp_double_fcmpe(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 1, dm, fpscr); +} + +static u32 vfp_double_fcmpz(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 0, -1, fpscr); +} + +static u32 vfp_double_fcmpez(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 1, -1, fpscr); +} + +static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + struct vfp_single vsd; + int tm; + u32 exceptions = 0; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + + tm = vfp_double_type(&vdm); + + /* + * If we have a signalling NaN, signal invalid operation. + */ + if (tm == VFP_SNAN) + exceptions = FPSCR_IOC; + + if (tm & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdm); + + vsd.sign = vdm.sign; + vsd.significand = vfp_hi64to32jamming(vdm.significand); + + /* + * If we have an infinity or a NaN, the exponent must be 255 + */ + if (tm & (VFP_INFINITY|VFP_NAN)) { + vsd.exponent = 255; + if (tm & VFP_NAN) + vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN; + goto pack_nan; + } else if (tm & VFP_ZERO) + vsd.exponent = 0; + else + vsd.exponent = vdm.exponent - (1023 - 127); + + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fcvts"); + + pack_nan: + vfp_put_float(sd, vfp_single_pack(&vsd)); + return exceptions; +} + +static u32 vfp_double_fuito(int dd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 m = vfp_get_float(dm); + + vdm.sign = 0; + vdm.exponent = 1023 + 63 - 1; + vdm.significand = (u64)m; + + return vfp_double_normaliseround(dd, &vdm, fpscr, 0, "fuito"); +} + +static u32 vfp_double_fsito(int dd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 m = vfp_get_float(dm); + + vdm.sign = (m & 0x80000000) >> 16; + vdm.exponent = 1023 + 63 - 1; + vdm.significand = vdm.sign ? -m : m; + + return vfp_double_normaliseround(dd, &vdm, fpscr, 0, "fsito"); +} + +static u32 vfp_double_ftoui(int sd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + int tm; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + + /* + * Do we have a denormalised number? + */ + tm = vfp_double_type(&vdm); + if (tm & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (tm & VFP_NAN) + vdm.sign = 0; + + if (vdm.exponent >= 1023 + 32) { + d = vdm.sign ? 0 : 0xffffffff; + exceptions = FPSCR_IOC; + } else if (vdm.exponent >= 1023 - 1) { + int shift = 1023 + 63 - vdm.exponent; + u64 rem, incr = 0; + + /* + * 2^0 <= m < 2^32-2^8 + */ + d = (vdm.significand << 1) >> shift; + rem = vdm.significand << (65 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x8000000000000000ULL; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) { + incr = ~0ULL; + } + + if ((rem + incr) < rem) { + if (d < 0xffffffff) + d += 1; + else + exceptions |= FPSCR_IOC; + } + + if (d && vdm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + } else { + d = 0; + if (vdm.exponent | vdm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } + } + } + + pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, d); + + return exceptions; +} + +static u32 vfp_double_ftouiz(int sd, int unused, int dm, u32 fpscr) +{ + return vfp_double_ftoui(sd, unused, dm, FPSCR_ROUND_TOZERO); +} + +static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + vfp_double_dump("VDM", &vdm); + + /* + * Do we have denormalised number? + */ + if (vfp_double_type(&vdm) & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (vdm.exponent >= 1023 + 32) { + d = 0x7fffffff; + if (vdm.sign) + d = ~d; + exceptions |= FPSCR_IOC; + } else if (vdm.exponent >= 1023 - 1) { + int shift = 1023 + 63 - vdm.exponent; /* 58 */ + u64 rem, incr = 0; + + d = (vdm.significand << 1) >> shift; + rem = vdm.significand << (65 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x8000000000000000ULL; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) { + incr = ~0ULL; + } + + if ((rem + incr) < rem && d < 0xffffffff) + d += 1; + if (d > 0x7fffffff + (vdm.sign != 0)) { + d = 0x7fffffff + (vdm.sign != 0); + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + + if (vdm.sign) + d = -d; + } else { + d = 0; + if (vdm.exponent | vdm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) + d = -1; + } + } + + pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, (s32)d); + + return exceptions; +} + +static u32 vfp_double_ftosiz(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_double_ftosi(dd, unused, dm, FPSCR_ROUND_TOZERO); +} + + +static u32 (* const fop_extfns[32])(int dd, int unused, int dm, u32 fpscr) = { + [FEXT_TO_IDX(FEXT_FCPY)] = vfp_double_fcpy, + [FEXT_TO_IDX(FEXT_FABS)] = vfp_double_fabs, + [FEXT_TO_IDX(FEXT_FNEG)] = vfp_double_fneg, + [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_double_fsqrt, + [FEXT_TO_IDX(FEXT_FCMP)] = vfp_double_fcmp, + [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_double_fcmpe, + [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_double_fcmpz, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_double_fcmpez, + [FEXT_TO_IDX(FEXT_FCVT)] = vfp_double_fcvts, + [FEXT_TO_IDX(FEXT_FUITO)] = vfp_double_fuito, + [FEXT_TO_IDX(FEXT_FSITO)] = vfp_double_fsito, + [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_double_ftoui, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_double_ftouiz, + [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_double_ftosi, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_double_ftosiz, +}; + + + + +static u32 +vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + struct vfp_double *vdp; + u32 exceptions = 0; + int tn, tm; + + tn = vfp_double_type(vdn); + tm = vfp_double_type(vdm); + + if (tn & tm & VFP_INFINITY) { + /* + * Two infinities. Are they different signs? + */ + if (vdn->sign ^ vdm->sign) { + /* + * different signs -> invalid + */ + exceptions = FPSCR_IOC; + vdp = &vfp_double_default_qnan; + } else { + /* + * same signs -> valid + */ + vdp = vdn; + } + } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) { + /* + * One infinity and one number -> infinity + */ + vdp = vdn; + } else { + /* + * 'n' is a NaN of some type + */ + return vfp_propagate_nan(vdd, vdn, vdm, fpscr); + } + *vdd = *vdp; + return exceptions; +} + +static u32 +vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + u32 exp_diff; + u64 m_sig; + + if (vdn->significand & (1ULL << 63) || + vdm->significand & (1ULL << 63)) { + pr_info("VFP: bad FP values in %s\n", __func__); + vfp_double_dump("VDN", vdn); + vfp_double_dump("VDM", vdm); + } + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vdn->exponent < vdm->exponent) { + struct vfp_double *t = vdn; + vdn = vdm; + vdm = t; + } + + /* + * Is 'n' an infinity or a NaN? Note that 'm' may be a number, + * infinity or a NaN here. + */ + if (vdn->exponent == 2047) + return vfp_double_fadd_nonnumber(vdd, vdn, vdm, fpscr); + + /* + * We have two proper numbers, where 'vdn' is the larger magnitude. + * + * Copy 'n' to 'd' before doing the arithmetic. + */ + *vdd = *vdn; + + /* + * Align 'm' with the result. + */ + exp_diff = vdn->exponent - vdm->exponent; + m_sig = vfp_shiftright64jamming(vdm->significand, exp_diff); + + /* + * If the signs are different, we are really subtracting. + */ + if (vdn->sign ^ vdm->sign) { + m_sig = vdn->significand - m_sig; + if ((s64)m_sig < 0) { + vdd->sign = vfp_sign_negate(vdd->sign); + m_sig = -m_sig; + } + } else { + m_sig += vdn->significand; + } + vdd->significand = m_sig; + + return 0; +} + +static u32 +vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + vfp_double_dump("VDN", vdn); + vfp_double_dump("VDM", vdm); + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vdn->exponent < vdm->exponent) { + struct vfp_double *t = vdn; + vdn = vdm; + vdm = t; + pr_debug("VFP: swapping M <-> N\n"); + } + + vdd->sign = vdn->sign ^ vdm->sign; + + /* + * If 'n' is an infinity or NaN, handle it. 'm' may be anything. + */ + if (vdn->exponent == 2047) { + if (vdn->significand || (vdm->exponent == 2047 && vdm->significand)) + return vfp_propagate_nan(vdd, vdn, vdm, fpscr); + if ((vdm->exponent | vdm->significand) == 0) { + *vdd = vfp_double_default_qnan; + return FPSCR_IOC; + } + vdd->exponent = vdn->exponent; + vdd->significand = 0; + return 0; + } + + /* + * If 'm' is zero, the result is always zero. In this case, + * 'n' may be zero or a number, but it doesn't matter which. + */ + if ((vdm->exponent | vdm->significand) == 0) { + vdd->exponent = 0; + vdd->significand = 0; + return 0; + } + + /* + * We add 2 to the destination exponent for the same reason + * as the addition case - though this time we have +1 from + * each input operand. + */ + vdd->exponent = vdn->exponent + vdm->exponent - 1023 + 2; + vdd->significand = vfp_hi64multiply64(vdn->significand, vdm->significand); + + vfp_double_dump("VDD", vdd); + return 0; +} + +#define NEG_MULTIPLY (1 << 0) +#define NEG_SUBTRACT (1 << 1) + +static u32 +vfp_double_multiply_accumulate(int dd, int dn, int dm, u32 fpscr, u32 negate, char *func) +{ + struct vfp_double vdd, vdp, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_multiply(&vdp, &vdn, &vdm, fpscr); + if (negate & NEG_MULTIPLY) + vdp.sign = vfp_sign_negate(vdp.sign); + + vfp_double_unpack(&vdn, vfp_get_double(dd)); + if (negate & NEG_SUBTRACT) + vdn.sign = vfp_sign_negate(vdn.sign); + + exceptions |= vfp_double_add(&vdd, &vdn, &vdp, fpscr); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, func); +} + +/* + * Standard operations + */ + +/* + * sd = sd + (sn * sm) + */ +static u32 vfp_double_fmac(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, 0, "fmac"); +} + +/* + * sd = sd - (sn * sm) + */ +static u32 vfp_double_fnmac(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_MULTIPLY, "fnmac"); +} + +/* + * sd = -sd + (sn * sm) + */ +static u32 vfp_double_fmsc(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_SUBTRACT, "fmsc"); +} + +/* + * sd = -sd - (sn * sm) + */ +static u32 vfp_double_fnmsc(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); +} + +/* + * sd = sn * sm + */ +static u32 vfp_double_fmul(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr); + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fmul"); +} + +/* + * sd = -(sn * sm) + */ +static u32 vfp_double_fnmul(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr); + vdd.sign = vfp_sign_negate(vdd.sign); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fnmul"); +} + +/* + * sd = sn + sm + */ +static u32 vfp_double_fadd(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fadd"); +} + +/* + * sd = sn - sm + */ +static u32 vfp_double_fsub(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + /* + * Subtraction is like addition, but with a negated operand. + */ + vdm.sign = vfp_sign_negate(vdm.sign); + + exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fsub"); +} + +/* + * sd = sn / sm + */ +static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions = 0; + int tm, tn; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + vfp_double_unpack(&vdm, vfp_get_double(dm)); + + vdd.sign = vdn.sign ^ vdm.sign; + + tn = vfp_double_type(&vdn); + tm = vfp_double_type(&vdm); + + /* + * Is n a NAN? + */ + if (tn & VFP_NAN) + goto vdn_nan; + + /* + * Is m a NAN? + */ + if (tm & VFP_NAN) + goto vdm_nan; + + /* + * If n and m are infinity, the result is invalid + * If n and m are zero, the result is invalid + */ + if (tm & tn & (VFP_INFINITY|VFP_ZERO)) + goto invalid; + + /* + * If n is infinity, the result is infinity + */ + if (tn & VFP_INFINITY) + goto infinity; + + /* + * If m is zero, raise div0 exceptions + */ + if (tm & VFP_ZERO) + goto divzero; + + /* + * If m is infinity, or n is zero, the result is zero + */ + if (tm & VFP_INFINITY || tn & VFP_ZERO) + goto zero; + + if (tn & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdn); + if (tm & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdm); + + /* + * Ok, we have two numbers, we can perform division. + */ + vdd.exponent = vdn.exponent - vdm.exponent + 1023 - 1; + vdm.significand <<= 1; + if (vdm.significand <= (2 * vdn.significand)) { + vdn.significand >>= 1; + vdd.exponent++; + } + vdd.significand = vfp_estimate_div128to64(vdn.significand, 0, vdm.significand); + if ((vdd.significand & 0x1ff) <= 2) { + u64 termh, terml, remh, reml; + mul64to128(&termh, &terml, vdm.significand, vdd.significand); + sub128(&remh, &reml, vdn.significand, 0, termh, terml); + while ((s64)remh < 0) { + vdd.significand -= 1; + add128(&remh, &reml, remh, reml, 0, vdm.significand); + } + vdd.significand |= (reml != 0); + } + return vfp_double_normaliseround(dd, &vdd, fpscr, 0, "fdiv"); + + vdn_nan: + exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr); + pack: + vfp_put_double(dd, vfp_double_pack(&vdd)); + return exceptions; + + vdm_nan: + exceptions = vfp_propagate_nan(&vdd, &vdm, &vdn, fpscr); + goto pack; + + zero: + vdd.exponent = 0; + vdd.significand = 0; + goto pack; + + divzero: + exceptions = FPSCR_DZC; + infinity: + vdd.exponent = 2047; + vdd.significand = 0; + goto pack; + + invalid: + vfp_put_double(dd, vfp_double_pack(&vfp_double_default_qnan)); + return FPSCR_IOC; +} + +static u32 (* const fop_fns[16])(int dd, int dn, int dm, u32 fpscr) = { + [FOP_TO_IDX(FOP_FMAC)] = vfp_double_fmac, + [FOP_TO_IDX(FOP_FNMAC)] = vfp_double_fnmac, + [FOP_TO_IDX(FOP_FMSC)] = vfp_double_fmsc, + [FOP_TO_IDX(FOP_FNMSC)] = vfp_double_fnmsc, + [FOP_TO_IDX(FOP_FMUL)] = vfp_double_fmul, + [FOP_TO_IDX(FOP_FNMUL)] = vfp_double_fnmul, + [FOP_TO_IDX(FOP_FADD)] = vfp_double_fadd, + [FOP_TO_IDX(FOP_FSUB)] = vfp_double_fsub, + [FOP_TO_IDX(FOP_FDIV)] = vfp_double_fdiv, +}; + +#define FREG_BANK(x) ((x) & 0x0c) +#define FREG_IDX(x) ((x) & 3) + +u32 vfp_double_cpdo(u32 inst, u32 fpscr) +{ + u32 op = inst & FOP_MASK; + u32 exceptions = 0; + unsigned int dd = vfp_get_sd(inst); + unsigned int dn = vfp_get_sn(inst); + unsigned int dm = vfp_get_sm(inst); + unsigned int vecitr, veclen, vecstride; + u32 (*fop)(int, int, s32, u32); + + veclen = fpscr & FPSCR_LENGTH_MASK; + vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2; + + /* + * If destination bank is zero, vector length is always '1'. + * ARM DDI0100F C5.1.3, C5.3.2. + */ + if (FREG_BANK(dd) == 0) + veclen = 0; + + pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, + (veclen >> FPSCR_LENGTH_BIT) + 1); + + fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)]; + if (!fop) + goto invalid; + + for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { + u32 except; + + if (op == FOP_EXT) + pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n", + vecitr >> FPSCR_LENGTH_BIT, + dd >> 1, dd & 1, dn, + dm >> 1, dm & 1); + else + pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n", + vecitr >> FPSCR_LENGTH_BIT, + dd >> 1, dd & 1, + dn >> 1, dn & 1, + FOP_TO_IDX(op), + dm >> 1, dm & 1); + + except = fop(dd, dn, dm, fpscr); + pr_debug("VFP: itr%d: exceptions=%08x\n", + vecitr >> FPSCR_LENGTH_BIT, except); + + exceptions |= except; + + /* + * This ensures that comparisons only operate on scalars; + * comparisons always return with one FPSCR status bit set. + */ + if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + break; + + /* + * CHECK: It appears to be undefined whether we stop when + * we encounter an exception. We continue. + */ + + dd = FREG_BANK(dd) + ((FREG_IDX(dd) + vecstride) & 6); + dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6); + if (FREG_BANK(dm) != 0) + dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6); + } + return exceptions; + + invalid: + return ~0; +} diff -Nru a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/vfphw.S 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,210 @@ +/* + * linux/arch/arm/vfp/vfphw.S + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This code is called from the kernel's undefined instruction trap. + * r9 holds the return address for successful handling. + * lr holds the return address for unrecognised instructions. + * r10 points at the start of the private FP workspace in the thread structure + * sp points to a struct pt_regs (as defined in include/asm/proc/ptrace.h) + */ +#include +#include +#include "../kernel/entry-header.S" + + .macro DBGSTR, str +#ifdef DEBUG + stmfd sp!, {r0-r3, ip, lr} + add r0, pc, #4 + bl printk + b 1f + .asciz "<7>VFP: \str\n" + .balign 4 +1: ldmfd sp!, {r0-r3, ip, lr} +#endif + .endm + + .macro DBGSTR1, str, arg +#ifdef DEBUG + stmfd sp!, {r0-r3, ip, lr} + mov r1, \arg + add r0, pc, #4 + bl printk + b 1f + .asciz "<7>VFP: \str\n" + .balign 4 +1: ldmfd sp!, {r0-r3, ip, lr} +#endif + .endm + + .macro DBGSTR3, str, arg1, arg2, arg3 +#ifdef DEBUG + stmfd sp!, {r0-r3, ip, lr} + mov r3, \arg3 + mov r2, \arg2 + mov r1, \arg1 + add r0, pc, #4 + bl printk + b 1f + .asciz "<7>VFP: \str\n" + .balign 4 +1: ldmfd sp!, {r0-r3, ip, lr} +#endif + .endm + + +@ VFP hardware support entry point. +@ +@ r0 = faulted instruction +@ r5 = faulted PC+4 +@ r9 = successful return +@ r10 = vfp_state union +@ lr = failure return + + .globl vfp_support_entry +vfp_support_entry: + DBGSTR3 "instr %08x pc %08x state %p", r0, r5, r10 + + VFPFMRX r1, FPEXC @ Is the VFP enabled? + DBGSTR1 "fpexc %08x", r1 + tst r1, #FPEXC_ENABLE + bne look_for_VFP_exceptions @ VFP is already enabled + + DBGSTR1 "enable %x", r10 + ldr r3, last_VFP_context_address + orr r1, r1, #FPEXC_ENABLE @ user FPEXC has the enable bit set + ldr r4, [r3] @ last_VFP_context pointer + bic r2, r1, #FPEXC_EXCEPTION @ make sure exceptions are disabled + cmp r4, r10 + beq check_for_exception @ we are returning to the same + @ process, so the registers are + @ still there. In this case, we do + @ not want to drop a pending exception. + + VFPFMXR FPEXC, r2 @ enable VFP, disable any pending + @ exceptions, so we can get at the + @ rest of it + + @ Save out the current registers to the old thread state + + DBGSTR1 "save old state %p", r4 + cmp r4, #0 + beq no_old_VFP_process + VFPFMRX r2, FPSCR @ current status + VFPFMRX r6, FPINST @ FPINST (always there, rev0 onwards) + tst r1, #FPEXC_FPV2 @ is there an FPINST2 to read? + VFPFMRX r8, FPINST2, NE @ FPINST2 if needed - avoids reading + @ nonexistant reg on rev0 + VFPFSTMIA r4 @ save the working registers + add r4, r4, #8*16+4 + stmia r4, {r1, r2, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 + @ and point r4 at the word at the + @ start of the register dump + +no_old_VFP_process: + DBGSTR1 "load state %p", r10 + str r10, [r3] @ update the last_VFP_context pointer + @ Load the saved state back into the VFP + add r4, r10, #8*16+4 + ldmia r4, {r1, r2, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2 + VFPFLDMIA r10 @ reload the working registers while + @ FPEXC is in a safe state + tst r1, #FPEXC_FPV2 @ is there an FPINST2 to write? + VFPFMXR FPINST2, r8, NE @ FPINST2 if needed - avoids writing + @ nonexistant reg on rev0 + VFPFMXR FPINST, r6 + VFPFMXR FPSCR, r2 @ restore status + +check_for_exception: + tst r1, #FPEXC_EXCEPTION + bne process_exception @ might as well handle the pending + @ exception before retrying branch + @ out before setting an FPEXC that + @ stops us reading stuff + VFPFMXR FPEXC, r1 @ restore FPEXC last + sub r5, r5, #4 + str r5, [sp, #S_PC] @ retry the instruction + mov pc, r9 @ we think we have handled things + + +look_for_VFP_exceptions: + tst r1, #FPEXC_EXCEPTION + bne process_exception + VFPFMRX r2, FPSCR + tst r2, #FPSCR_IXE @ IXE doesn't set FPEXC_EXCEPTION ! + bne process_exception + + @ Fall into hand on to next handler - appropriate coproc instr + @ not recognised by VFP + + DBGSTR "not VFP" + mov pc, lr + +process_exception: + DBGSTR "bounce" + sub r5, r5, #4 + str r5, [sp, #S_PC] @ retry the instruction on exit from + @ the imprecise exception handling in + @ the support code + mov r2, sp @ nothing stacked - regdump is at TOS + mov lr, r9 @ setup for a return to the user code. + + @ Now call the C code to package up the bounce to the support code + @ r0 holds the trigger instruction + @ r1 holds the FPEXC value + @ r2 pointer to register dump + b VFP9_bounce @ we have handled this - the support + @ code will raise an exception if + @ required. If not, the user code will + @ retry the faulted instruction + +last_VFP_context_address: + .word last_VFP_context + + .globl vfp_get_float +vfp_get_float: + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0 + mov pc, lr + mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1 + mov pc, lr + .endr + + .globl vfp_put_float +vfp_put_float: + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mcr p10, 0, r1, c\dr, c0, 0 @ fmsr r0, s0 + mov pc, lr + mcr p10, 0, r1, c\dr, c0, 4 @ fmsr r0, s1 + mov pc, lr + .endr + + .globl vfp_get_double +vfp_get_double: + mov r0, r0, lsr #1 + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mrrc p10, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr + mov pc, lr + .endr + + .globl vfp_put_double +vfp_put_double: + mov r0, r0, lsr #1 + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mcrr p10, 1, r1, r2, c\dr @ fmrrd r1, r2, d\dr + mov pc, lr + .endr diff -Nru a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/vfpinstr.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,88 @@ +/* + * linux/arch/arm/vfp/vfpinstr.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * VFP instruction masks. + */ +#define INST_CPRTDO(inst) (((inst) & 0x0f000000) == 0x0e000000) +#define INST_CPRT(inst) ((inst) & (1 << 4)) +#define INST_CPRT_L(inst) ((inst) & (1 << 20)) +#define INST_CPRT_Rd(inst) (((inst) & (15 << 12)) >> 12) +#define INST_CPRT_OP(inst) (((inst) >> 21) & 7) +#define INST_CPNUM(inst) ((inst) & 0xf00) +#define CPNUM(cp) ((cp) << 8) + +#define FOP_MASK (0x00b00040) +#define FOP_FMAC (0x00000000) +#define FOP_FNMAC (0x00000040) +#define FOP_FMSC (0x00100000) +#define FOP_FNMSC (0x00100040) +#define FOP_FMUL (0x00200000) +#define FOP_FNMUL (0x00200040) +#define FOP_FADD (0x00300000) +#define FOP_FSUB (0x00300040) +#define FOP_FDIV (0x00800000) +#define FOP_EXT (0x00b00040) + +#define FOP_TO_IDX(inst) ((inst & 0x00b00000) >> 20 | (inst & (1 << 6)) >> 4) + +#define FEXT_MASK (0x000f0080) +#define FEXT_FCPY (0x00000000) +#define FEXT_FABS (0x00000080) +#define FEXT_FNEG (0x00010000) +#define FEXT_FSQRT (0x00010080) +#define FEXT_FCMP (0x00040000) +#define FEXT_FCMPE (0x00040080) +#define FEXT_FCMPZ (0x00050000) +#define FEXT_FCMPEZ (0x00050080) +#define FEXT_FCVT (0x00070080) +#define FEXT_FUITO (0x00080000) +#define FEXT_FSITO (0x00080080) +#define FEXT_FTOUI (0x000c0000) +#define FEXT_FTOUIZ (0x000c0080) +#define FEXT_FTOSI (0x000d0000) +#define FEXT_FTOSIZ (0x000d0080) + +#define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) + +#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) +#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12) +#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) +#define vfp_get_dm(inst) ((inst & 0x0000000f)) +#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) +#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16) + +#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) + +#define FPSCR_N (1 << 31) +#define FPSCR_Z (1 << 30) +#define FPSCR_C (1 << 29) +#define FPSCR_V (1 << 28) + +/* + * Since we aren't building with -mfpu=vfp, we need to code + * these instructions using their MRC/MCR equivalents. + */ +#define vfpreg(_vfp_) #_vfp_ + +#define fmrx(_vfp_) ({ \ + u32 __v; \ + asm("mrc%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ + : "=r" (__v)); \ + __v; \ + }) + +#define fmxr(_vfp_,_var_) \ + asm("mcr%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ + : : "r" (_var_)) + +u32 vfp_single_cpdo(u32 inst, u32 fpscr); +u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs); + +u32 vfp_double_cpdo(u32 inst, u32 fpscr); diff -Nru a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/vfpmodule.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,288 @@ +/* + * linux/arch/arm/vfp/vfpmodule.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vfpinstr.h" +#include "vfp.h" + +/* + * Our undef handlers (in entry.S) + */ +void vfp_testing_entry(void); +void vfp_support_entry(void); + +void (*vfp_vector)(void) = vfp_testing_entry; +union vfp_state *last_VFP_context; + +/* + * Dual-use variable. + * Used in startup: set to non-zero if VFP checks fail + * After startup, holds VFP architecture + */ +unsigned int VFP_arch; + +/* + * Per-thread VFP initialisation. + */ +void vfp_flush_thread(union vfp_state *vfp) +{ + memset(vfp, 0, sizeof(union vfp_state)); + + vfp->hard.fpexc = FPEXC_ENABLE; + vfp->hard.fpscr = FPSCR_ROUND_NEAREST; + + /* + * Disable VFP to ensure we initialise it first. + */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); + + /* + * Ensure we don't try to overwrite our newly initialised + * state information on the first fault. + */ + if (last_VFP_context == vfp) + last_VFP_context = NULL; +} + +/* + * Per-thread VFP cleanup. + */ +void vfp_release_thread(union vfp_state *vfp) +{ + if (last_VFP_context == vfp) + last_VFP_context = NULL; +} + +/* + * Raise a SIGFPE for the current process. + * sicode describes the signal being raised. + */ +void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) +{ + siginfo_t info; + + memset(&info, 0, sizeof(info)); + + info.si_signo = SIGFPE; + info.si_code = sicode; + info.si_addr = (void *)(instruction_pointer(regs) - 4); + + /* + * This is the same as NWFPE, because it's not clear what + * this is used for + */ + current->thread.error_code = 0; + current->thread.trap_no = 6; + + force_sig_info(SIGFPE, &info, current); +} + +static void vfp_panic(char *reason) +{ + int i; + + printk(KERN_ERR "VFP: Error: %s\n", reason); + printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n", + fmrx(FPEXC), fmrx(FPSCR), fmrx(FPINST)); + for (i = 0; i < 32; i += 2) + printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n", + i, vfp_get_float(i), i+1, vfp_get_float(i+1)); +} + +/* + * Process bitmask of exception conditions. + */ +static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_regs *regs) +{ + int si_code = 0; + + pr_debug("VFP: raising exceptions %08x\n", exceptions); + + if (exceptions == (u32)-1) { + vfp_panic("unhandled bounce"); + vfp_raise_sigfpe(0, regs); + return; + } + + /* + * If any of the status flags are set, update the FPSCR. + * Comparison instructions always return at least one of + * these flags set. + */ + if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V); + + fpscr |= exceptions; + + fmxr(FPSCR, fpscr); + +#define RAISE(stat,en,sig) \ + if (exceptions & stat && fpscr & en) \ + si_code = sig; + + /* + * These are arranged in priority order, least to highest. + */ + RAISE(FPSCR_IXC, FPSCR_IXE, FPE_FLTRES); + RAISE(FPSCR_UFC, FPSCR_UFE, FPE_FLTUND); + RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF); + RAISE(FPSCR_IOC, FPSCR_IOE, FPE_FLTINV); + + if (si_code) + vfp_raise_sigfpe(si_code, regs); +} + +/* + * Emulate a VFP instruction. + */ +static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) +{ + u32 exceptions = (u32)-1; + + pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr); + + if (INST_CPRTDO(inst)) { + if (!INST_CPRT(inst)) { + /* + * CPDO + */ + if (vfp_single(inst)) { + exceptions = vfp_single_cpdo(inst, fpscr); + } else { + exceptions = vfp_double_cpdo(inst, fpscr); + } + } else { + /* + * A CPRT instruction can not appear in FPINST2, nor + * can it cause an exception. Therefore, we do not + * have to emulate it. + */ + } + } else { + /* + * A CPDT instruction can not appear in FPINST2, nor can + * it cause an exception. Therefore, we do not have to + * emulate it. + */ + } + return exceptions; +} + +/* + * Package up a bounce condition. + */ +void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) +{ + u32 fpscr, orig_fpscr, exceptions, inst; + + pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); + + /* + * Enable access to the VFP so we can handle the bounce. + */ + fmxr(FPEXC, fpexc & ~(FPEXC_EXCEPTION|FPEXC_INV|FPEXC_UFC|FPEXC_IOC)); + + orig_fpscr = fpscr = fmrx(FPSCR); + + /* + * If we are running with inexact exceptions enabled, we need to + * emulate the trigger instruction. Note that as we're emulating + * the trigger instruction, we need to increment PC. + */ + if (fpscr & FPSCR_IXE) { + regs->ARM_pc += 4; + goto emulate; + } + + barrier(); + + /* + * Modify fpscr to indicate the number of iterations remaining + */ + if (fpexc & FPEXC_EXCEPTION) { + u32 len; + + len = fpexc + (1 << FPEXC_LENGTH_BIT); + + fpscr &= ~FPSCR_LENGTH_MASK; + fpscr |= (len & FPEXC_LENGTH_MASK) << (FPSCR_LENGTH_BIT - FPEXC_LENGTH_BIT); + } + + /* + * Handle the first FP instruction. We used to take note of the + * FPEXC bounce reason, but this appears to be unreliable. + * Emulate the bounced instruction instead. + */ + inst = fmrx(FPINST); + exceptions = vfp_emulate_instruction(inst, fpscr, regs); + if (exceptions) + vfp_raise_exceptions(exceptions, inst, orig_fpscr, regs); + + /* + * If there isn't a second FP instruction, exit now. + */ + if (!(fpexc & FPEXC_FPV2)) + return; + + /* + * The barrier() here prevents fpinst2 being read + * before the condition above. + */ + barrier(); + trigger = fmrx(FPINST2); + fpscr = fmrx(FPSCR); + + emulate: + exceptions = vfp_emulate_instruction(trigger, fpscr, regs); + if (exceptions) + vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); +} + +/* + * VFP support code initialisation. + */ +static int __init vfp_init(void) +{ + unsigned int vfpsid; + + /* + * First check that there is a VFP that we can use. + * The handler is already setup to just log calls, so + * we just need to read the VFPSID register. + */ + vfpsid = fmrx(FPSID); + + printk(KERN_INFO "VFP support v0.3: "); + if (VFP_arch) { + printk("not present\n"); + } else if (vfpsid & FPSID_NODOUBLE) { + printk("no double precision support\n"); + } else { + VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ + printk("implementor %02x architecture %d part %02x variant %x rev %x\n", + (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, + (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT, + (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, + (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, + (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); + vfp_vector = vfp_support_entry; + } + return 0; +} + +late_initcall(vfp_init); diff -Nru a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/arm/vfp/vfpsingle.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1224 @@ +/* + * linux/arch/arm/vfp/vfpsingle.c + * + * This code is derived in part from John R. Housers softfloat library, which + * carries the following notice: + * + * =========================================================================== + * This C source file is part of the SoftFloat IEC/IEEE Floating-point + * Arithmetic Package, Release 2. + * + * Written by John R. Hauser. This work was made possible in part by the + * International Computer Science Institute, located at Suite 600, 1947 Center + * Street, Berkeley, California 94704. Funding was partially provided by the + * National Science Foundation under grant MIP-9311980. The original version + * of this code was written as part of a project to build a fixed-point vector + * processor in collaboration with the University of California at Berkeley, + * overseen by Profs. Nelson Morgan and John Wawrzynek. More information + * is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ + * arithmetic/softfloat.html'. + * + * THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort + * has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT + * TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO + * PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY + * AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + * + * Derivative works are acceptable, even for commercial purposes, so long as + * (1) they include prominent notice that the work is derivative, and (2) they + * include prominent notice akin to these three paragraphs for those parts of + * this code that are retained. + * =========================================================================== + */ +#include +#include +#include +#include + +#include "vfpinstr.h" +#include "vfp.h" + +static struct vfp_single vfp_single_default_qnan = { + .exponent = 255, + .sign = 0, + .significand = VFP_SINGLE_SIGNIFICAND_QNAN, +}; + +static void vfp_single_dump(const char *str, struct vfp_single *s) +{ + pr_debug("VFP: %s: sign=%d exponent=%d significand=%08x\n", + str, s->sign != 0, s->exponent, s->significand); +} + +static void vfp_single_normalise_denormal(struct vfp_single *vs) +{ + int bits = 31 - fls(vs->significand); + + vfp_single_dump("normalise_denormal: in", vs); + + if (bits) { + vs->exponent -= bits - 1; + vs->significand <<= bits; + } + + vfp_single_dump("normalise_denormal: out", vs); +} + +#ifndef DEBUG +#define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except) +u32 __vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions) +#else +u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func) +#endif +{ + u32 significand, incr, rmode; + int exponent, shift, underflow; + + vfp_single_dump("pack: in", vs); + + /* + * Infinities and NaNs are a special case. + */ + if (vs->exponent == 255 && (vs->significand == 0 || exceptions)) + goto pack; + + /* + * Special-case zero. + */ + if (vs->significand == 0) { + vs->exponent = 0; + goto pack; + } + + exponent = vs->exponent; + significand = vs->significand; + + /* + * Normalise first. Note that we shift the significand up to + * bit 31, so we have VFP_SINGLE_LOW_BITS + 1 below the least + * significant bit. + */ + shift = 32 - fls(significand); + if (shift < 32 && shift) { + exponent -= shift; + significand <<= shift; + } + +#ifdef DEBUG + vs->exponent = exponent; + vs->significand = significand; + vfp_single_dump("pack: normalised", vs); +#endif + + /* + * Tiny number? + */ + underflow = exponent < 0; + if (underflow) { + significand = vfp_shiftright32jamming(significand, -exponent); + exponent = 0; +#ifdef DEBUG + vs->exponent = exponent; + vs->significand = significand; + vfp_single_dump("pack: tiny number", vs); +#endif + if (!(significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1))) + underflow = 0; + } + + /* + * Select rounding increment. + */ + incr = 0; + rmode = fpscr & FPSCR_RMODE_MASK; + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 1 << VFP_SINGLE_LOW_BITS; + if ((significand & (1 << (VFP_SINGLE_LOW_BITS + 1))) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vs->sign != 0)) + incr = (1 << (VFP_SINGLE_LOW_BITS + 1)) - 1; + + pr_debug("VFP: rounding increment = 0x%08x\n", incr); + + /* + * Is our rounding going to overflow? + */ + if ((significand + incr) < significand) { + exponent += 1; + significand = (significand >> 1) | (significand & 1); + incr >>= 1; +#ifdef DEBUG + vs->exponent = exponent; + vs->significand = significand; + vfp_single_dump("pack: overflow", vs); +#endif + } + + /* + * If any of the low bits (which will be shifted out of the + * number) are non-zero, the result is inexact. + */ + if (significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1)) + exceptions |= FPSCR_IXC; + + /* + * Do our rounding. + */ + significand += incr; + + /* + * Infinity? + */ + if (exponent >= 254) { + exceptions |= FPSCR_OFC | FPSCR_IXC; + if (incr == 0) { + vs->exponent = 253; + vs->significand = 0x7fffffff; + } else { + vs->exponent = 255; /* infinity */ + vs->significand = 0; + } + } else { + if (significand >> (VFP_SINGLE_LOW_BITS + 1) == 0) + exponent = 0; + if (exponent || significand > 0x80000000) + underflow = 0; + if (underflow) + exceptions |= FPSCR_UFC; + vs->exponent = exponent; + vs->significand = significand >> 1; + } + + pack: + vfp_single_dump("pack: final", vs); + { + s32 d = vfp_single_pack(vs); + pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, + sd, d, exceptions); + vfp_put_float(sd, d); + } + + return exceptions; +} + +/* + * Propagate the NaN, setting exceptions if it is signalling. + * 'n' is always a NaN. 'm' may be a number, NaN or infinity. + */ +static u32 +vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn, + struct vfp_single *vsm, u32 fpscr) +{ + struct vfp_single *nan; + int tn, tm = 0; + + tn = vfp_single_type(vsn); + + if (vsm) + tm = vfp_single_type(vsm); + + if (fpscr & FPSCR_DEFAULT_NAN) + /* + * Default NaN mode - always returns a quiet NaN + */ + nan = &vfp_single_default_qnan; + else { + /* + * Contemporary mode - select the first signalling + * NAN, or if neither are signalling, the first + * quiet NAN. + */ + if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN)) + nan = vsn; + else + nan = vsm; + /* + * Make the NaN quiet. + */ + nan->significand |= VFP_SINGLE_SIGNIFICAND_QNAN; + } + + *vsd = *nan; + + /* + * If one was a signalling NAN, raise invalid operation. + */ + return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : 0x100; +} + + +/* + * Extended operations + */ +static u32 vfp_single_fabs(int sd, int unused, s32 m, u32 fpscr) +{ + vfp_put_float(sd, vfp_single_packed_abs(m)); + return 0; +} + +static u32 vfp_single_fcpy(int sd, int unused, s32 m, u32 fpscr) +{ + vfp_put_float(sd, m); + return 0; +} + +static u32 vfp_single_fneg(int sd, int unused, s32 m, u32 fpscr) +{ + vfp_put_float(sd, vfp_single_packed_negate(m)); + return 0; +} + +static const u16 sqrt_oddadjust[] = { + 0x0004, 0x0022, 0x005d, 0x00b1, 0x011d, 0x019f, 0x0236, 0x02e0, + 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67 +}; + +static const u16 sqrt_evenadjust[] = { + 0x0a2d, 0x08af, 0x075a, 0x0629, 0x051a, 0x0429, 0x0356, 0x029e, + 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002 +}; + +u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) +{ + int index; + u32 z, a; + + if ((significand & 0xc0000000) != 0x40000000) { + printk(KERN_WARNING "VFP: estimate_sqrt: invalid significand\n"); + } + + a = significand << 1; + index = (a >> 27) & 15; + if (exponent & 1) { + z = 0x4000 + (a >> 17) - sqrt_oddadjust[index]; + z = ((a / z) << 14) + (z << 15); + a >>= 1; + } else { + z = 0x8000 + (a >> 17) - sqrt_evenadjust[index]; + z = a / z + z; + z = (z >= 0x20000) ? 0xffff8000 : (z << 15); + if (z <= a) + return (s32)a >> 1; + } + return (u32)(((u64)a << 31) / z) + (z >> 1); +} + +static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm, vsd; + int ret, tm; + + vfp_single_unpack(&vsm, m); + tm = vfp_single_type(&vsm); + if (tm & (VFP_NAN|VFP_INFINITY)) { + struct vfp_single *vsp = &vsd; + + if (tm & VFP_NAN) + ret = vfp_propagate_nan(vsp, &vsm, NULL, fpscr); + else if (vsm.sign == 0) { + sqrt_copy: + vsp = &vsm; + ret = 0; + } else { + sqrt_invalid: + vsp = &vfp_single_default_qnan; + ret = FPSCR_IOC; + } + vfp_put_float(sd, vfp_single_pack(vsp)); + return ret; + } + + /* + * sqrt(+/- 0) == +/- 0 + */ + if (tm & VFP_ZERO) + goto sqrt_copy; + + /* + * Normalise a denormalised number + */ + if (tm & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsm); + + /* + * sqrt(<0) = invalid + */ + if (vsm.sign) + goto sqrt_invalid; + + vfp_single_dump("sqrt", &vsm); + + /* + * Estimate the square root. + */ + vsd.sign = 0; + vsd.exponent = ((vsm.exponent - 127) >> 1) + 127; + vsd.significand = vfp_estimate_sqrt_significand(vsm.exponent, vsm.significand) + 2; + + vfp_single_dump("sqrt estimate", &vsd); + + /* + * And now adjust. + */ + if ((vsd.significand & VFP_SINGLE_LOW_BITS_MASK) <= 5) { + if (vsd.significand < 2) { + vsd.significand = 0xffffffff; + } else { + u64 term; + s64 rem; + vsm.significand <<= !(vsm.exponent & 1); + term = (u64)vsd.significand * vsd.significand; + rem = ((u64)vsm.significand << 32) - term; + + pr_debug("VFP: term=%016llx rem=%016llx\n", term, rem); + + while (rem < 0) { + vsd.significand -= 1; + rem += ((u64)vsd.significand << 1) | 1; + } + vsd.significand |= rem != 0; + } + } + vsd.significand = vfp_shiftright32jamming(vsd.significand, 1); + + return vfp_single_normaliseround(sd, &vsd, fpscr, 0, "fsqrt"); +} + +/* + * Equal := ZC + * Less than := N + * Greater than := C + * Unordered := CV + */ +static u32 vfp_compare(int sd, int signal_on_qnan, s32 m, u32 fpscr) +{ + s32 d; + u32 ret = 0; + + d = vfp_get_float(sd); + if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + if (ret == 0) { + if (d == m || vfp_single_packed_abs(d | m) == 0) { + /* + * equal + */ + ret |= FPSCR_Z | FPSCR_C; + } else if (vfp_single_packed_sign(d ^ m)) { + /* + * different signs + */ + if (vfp_single_packed_sign(d)) + /* + * d is negative, so d < m + */ + ret |= FPSCR_N; + else + /* + * d is positive, so d > m + */ + ret |= FPSCR_C; + } else if ((vfp_single_packed_sign(d) != 0) ^ (d < m)) { + /* + * d < m + */ + ret |= FPSCR_N; + } else if ((vfp_single_packed_sign(d) != 0) ^ (d > m)) { + /* + * d > m + */ + ret |= FPSCR_C; + } + } + return ret; +} + +static u32 vfp_single_fcmp(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 0, m, fpscr); +} + +static u32 vfp_single_fcmpe(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 1, m, fpscr); +} + +static u32 vfp_single_fcmpz(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 0, 0, fpscr); +} + +static u32 vfp_single_fcmpez(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 1, 0, fpscr); +} + +static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm; + struct vfp_double vdd; + int tm; + u32 exceptions = 0; + + vfp_single_unpack(&vsm, m); + + tm = vfp_single_type(&vsm); + + /* + * If we have a signalling NaN, signal invalid operation. + */ + if (tm == VFP_SNAN) + exceptions = FPSCR_IOC; + + if (tm & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsm); + + vdd.sign = vsm.sign; + vdd.significand = (u64)vsm.significand << 32; + + /* + * If we have an infinity or NaN, the exponent must be 2047. + */ + if (tm & (VFP_INFINITY|VFP_NAN)) { + vdd.exponent = 2047; + if (tm & VFP_NAN) + vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; + goto pack_nan; + } else if (tm & VFP_ZERO) + vdd.exponent = 0; + else + vdd.exponent = vsm.exponent + (1023 - 127); + + /* + * Technically, if bit 0 of dd is set, this is an invalid + * instruction. However, we ignore this for efficiency. + */ + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd"); + + pack_nan: + vfp_put_double(dd, vfp_double_pack(&vdd)); + return exceptions; +} + +static u32 vfp_single_fuito(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vs; + + vs.sign = 0; + vs.exponent = 127 + 31 - 1; + vs.significand = (u32)m; + + return vfp_single_normaliseround(sd, &vs, fpscr, 0, "fuito"); +} + +static u32 vfp_single_fsito(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vs; + + vs.sign = (m & 0x80000000) >> 16; + vs.exponent = 127 + 31 - 1; + vs.significand = vs.sign ? -m : m; + + return vfp_single_normaliseround(sd, &vs, fpscr, 0, "fsito"); +} + +static u32 vfp_single_ftoui(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + int tm; + + vfp_single_unpack(&vsm, m); + vfp_single_dump("VSM", &vsm); + + /* + * Do we have a denormalised number? + */ + tm = vfp_single_type(&vsm); + if (tm & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (tm & VFP_NAN) + vsm.sign = 0; + + if (vsm.exponent >= 127 + 32) { + d = vsm.sign ? 0 : 0xffffffff; + exceptions = FPSCR_IOC; + } else if (vsm.exponent >= 127 - 1) { + int shift = 127 + 31 - vsm.exponent; + u32 rem, incr = 0; + + /* + * 2^0 <= m < 2^32-2^8 + */ + d = (vsm.significand << 1) >> shift; + rem = vsm.significand << (33 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x80000000; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) { + incr = ~0; + } + + if ((rem + incr) < rem) { + if (d < 0xffffffff) + d += 1; + else + exceptions |= FPSCR_IOC; + } + + if (d && vsm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + } else { + d = 0; + if (vsm.exponent | vsm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } + } + } + + pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, d); + + return exceptions; +} + +static u32 vfp_single_ftouiz(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_single_ftoui(sd, unused, m, FPSCR_ROUND_TOZERO); +} + +static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + + vfp_single_unpack(&vsm, m); + vfp_single_dump("VSM", &vsm); + + /* + * Do we have a denormalised number? + */ + if (vfp_single_type(&vsm) & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (vsm.exponent >= 127 + 32) { + /* + * m >= 2^31-2^7: invalid + */ + d = 0x7fffffff; + if (vsm.sign) + d = ~d; + exceptions |= FPSCR_IOC; + } else if (vsm.exponent >= 127 - 1) { + int shift = 127 + 31 - vsm.exponent; + u32 rem, incr = 0; + + /* 2^0 <= m <= 2^31-2^7 */ + d = (vsm.significand << 1) >> shift; + rem = vsm.significand << (33 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x80000000; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) { + incr = ~0; + } + + if ((rem + incr) < rem && d < 0xffffffff) + d += 1; + if (d > 0x7fffffff + (vsm.sign != 0)) { + d = 0x7fffffff + (vsm.sign != 0); + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + + if (vsm.sign) + d = -d; + } else { + d = 0; + if (vsm.exponent | vsm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) + d = -1; + } + } + + pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, (s32)d); + + return exceptions; +} + +static u32 vfp_single_ftosiz(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_single_ftosi(sd, unused, m, FPSCR_ROUND_TOZERO); +} + +static u32 (* const fop_extfns[32])(int sd, int unused, s32 m, u32 fpscr) = { + [FEXT_TO_IDX(FEXT_FCPY)] = vfp_single_fcpy, + [FEXT_TO_IDX(FEXT_FABS)] = vfp_single_fabs, + [FEXT_TO_IDX(FEXT_FNEG)] = vfp_single_fneg, + [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_single_fsqrt, + [FEXT_TO_IDX(FEXT_FCMP)] = vfp_single_fcmp, + [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_single_fcmpe, + [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_single_fcmpz, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_single_fcmpez, + [FEXT_TO_IDX(FEXT_FCVT)] = vfp_single_fcvtd, + [FEXT_TO_IDX(FEXT_FUITO)] = vfp_single_fuito, + [FEXT_TO_IDX(FEXT_FSITO)] = vfp_single_fsito, + [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_single_ftoui, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_single_ftouiz, + [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_single_ftosi, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_single_ftosiz, +}; + + + + + +static u32 +vfp_single_fadd_nonnumber(struct vfp_single *vsd, struct vfp_single *vsn, + struct vfp_single *vsm, u32 fpscr) +{ + struct vfp_single *vsp; + u32 exceptions = 0; + int tn, tm; + + tn = vfp_single_type(vsn); + tm = vfp_single_type(vsm); + + if (tn & tm & VFP_INFINITY) { + /* + * Two infinities. Are they different signs? + */ + if (vsn->sign ^ vsm->sign) { + /* + * different signs -> invalid + */ + exceptions = FPSCR_IOC; + vsp = &vfp_single_default_qnan; + } else { + /* + * same signs -> valid + */ + vsp = vsn; + } + } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) { + /* + * One infinity and one number -> infinity + */ + vsp = vsn; + } else { + /* + * 'n' is a NaN of some type + */ + return vfp_propagate_nan(vsd, vsn, vsm, fpscr); + } + *vsd = *vsp; + return exceptions; +} + +static u32 +vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn, + struct vfp_single *vsm, u32 fpscr) +{ + u32 exp_diff, m_sig; + + if (vsn->significand & 0x80000000 || + vsm->significand & 0x80000000) { + pr_info("VFP: bad FP values in %s\n", __func__); + vfp_single_dump("VSN", vsn); + vfp_single_dump("VSM", vsm); + } + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vsn->exponent < vsm->exponent) { + struct vfp_single *t = vsn; + vsn = vsm; + vsm = t; + } + + /* + * Is 'n' an infinity or a NaN? Note that 'm' may be a number, + * infinity or a NaN here. + */ + if (vsn->exponent == 255) + return vfp_single_fadd_nonnumber(vsd, vsn, vsm, fpscr); + + /* + * We have two proper numbers, where 'vsn' is the larger magnitude. + * + * Copy 'n' to 'd' before doing the arithmetic. + */ + *vsd = *vsn; + + /* + * Align both numbers. + */ + exp_diff = vsn->exponent - vsm->exponent; + m_sig = vfp_shiftright32jamming(vsm->significand, exp_diff); + + /* + * If the signs are different, we are really subtracting. + */ + if (vsn->sign ^ vsm->sign) { + m_sig = vsn->significand - m_sig; + if ((s32)m_sig < 0) { + vsd->sign = vfp_sign_negate(vsd->sign); + m_sig = -m_sig; + } else if (m_sig == 0) { + vsd->sign = (fpscr & FPSCR_RMODE_MASK) == + FPSCR_ROUND_MINUSINF ? 0x8000 : 0; + } + } else { + m_sig = vsn->significand + m_sig; + } + vsd->significand = m_sig; + + return 0; +} + +static u32 +vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_single *vsm, u32 fpscr) +{ + vfp_single_dump("VSN", vsn); + vfp_single_dump("VSM", vsm); + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vsn->exponent < vsm->exponent) { + struct vfp_single *t = vsn; + vsn = vsm; + vsm = t; + pr_debug("VFP: swapping M <-> N\n"); + } + + vsd->sign = vsn->sign ^ vsm->sign; + + /* + * If 'n' is an infinity or NaN, handle it. 'm' may be anything. + */ + if (vsn->exponent == 255) { + if (vsn->significand || (vsm->exponent == 255 && vsm->significand)) + return vfp_propagate_nan(vsd, vsn, vsm, fpscr); + if ((vsm->exponent | vsm->significand) == 0) { + *vsd = vfp_single_default_qnan; + return FPSCR_IOC; + } + vsd->exponent = vsn->exponent; + vsd->significand = 0; + return 0; + } + + /* + * If 'm' is zero, the result is always zero. In this case, + * 'n' may be zero or a number, but it doesn't matter which. + */ + if ((vsm->exponent | vsm->significand) == 0) { + vsd->exponent = 0; + vsd->significand = 0; + return 0; + } + + /* + * We add 2 to the destination exponent for the same reason as + * the addition case - though this time we have +1 from each + * input operand. + */ + vsd->exponent = vsn->exponent + vsm->exponent - 127 + 2; + vsd->significand = vfp_hi64to32jamming((u64)vsn->significand * vsm->significand); + + vfp_single_dump("VSD", vsd); + return 0; +} + +#define NEG_MULTIPLY (1 << 0) +#define NEG_SUBTRACT (1 << 1) + +static u32 +vfp_single_multiply_accumulate(int sd, int sn, s32 m, u32 fpscr, u32 negate, char *func) +{ + struct vfp_single vsd, vsp, vsn, vsm; + u32 exceptions; + s32 v; + + v = vfp_get_float(sn); + pr_debug("VFP: s%u = %08x\n", sn, v); + vfp_single_unpack(&vsn, v); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr); + if (negate & NEG_MULTIPLY) + vsp.sign = vfp_sign_negate(vsp.sign); + + v = vfp_get_float(sd); + pr_debug("VFP: s%u = %08x\n", sd, v); + vfp_single_unpack(&vsn, v); + if (negate & NEG_SUBTRACT) + vsn.sign = vfp_sign_negate(vsn.sign); + + exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr); + + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, func); +} + +/* + * Standard operations + */ + +/* + * sd = sd + (sn * sm) + */ +static u32 vfp_single_fmac(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, 0, "fmac"); +} + +/* + * sd = sd - (sn * sm) + */ +static u32 vfp_single_fnmac(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac"); +} + +/* + * sd = -sd + (sn * sm) + */ +static u32 vfp_single_fmsc(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc"); +} + +/* + * sd = -sd - (sn * sm) + */ +static u32 vfp_single_fnmsc(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); +} + +/* + * sd = sn * sm + */ +static u32 vfp_single_fmul(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions; + s32 n = vfp_get_float(sn); + + pr_debug("VFP: s%u = %08x\n", sn, n); + + vfp_single_unpack(&vsn, n); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr); + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fmul"); +} + +/* + * sd = -(sn * sm) + */ +static u32 vfp_single_fnmul(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions; + s32 n = vfp_get_float(sn); + + pr_debug("VFP: s%u = %08x\n", sn, n); + + vfp_single_unpack(&vsn, n); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr); + vsd.sign = vfp_sign_negate(vsd.sign); + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fnmul"); +} + +/* + * sd = sn + sm + */ +static u32 vfp_single_fadd(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions; + s32 n = vfp_get_float(sn); + + pr_debug("VFP: s%u = %08x\n", sn, n); + + /* + * Unpack and normalise denormals. + */ + vfp_single_unpack(&vsn, n); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_add(&vsd, &vsn, &vsm, fpscr); + + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fadd"); +} + +/* + * sd = sn - sm + */ +static u32 vfp_single_fsub(int sd, int sn, s32 m, u32 fpscr) +{ + /* + * Subtraction is addition with one sign inverted. + */ + return vfp_single_fadd(sd, sn, vfp_single_packed_negate(m), fpscr); +} + +/* + * sd = sn / sm + */ +static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions = 0; + s32 n = vfp_get_float(sn); + int tm, tn; + + pr_debug("VFP: s%u = %08x\n", sn, n); + + vfp_single_unpack(&vsn, n); + vfp_single_unpack(&vsm, m); + + vsd.sign = vsn.sign ^ vsm.sign; + + tn = vfp_single_type(&vsn); + tm = vfp_single_type(&vsm); + + /* + * Is n a NAN? + */ + if (tn & VFP_NAN) + goto vsn_nan; + + /* + * Is m a NAN? + */ + if (tm & VFP_NAN) + goto vsm_nan; + + /* + * If n and m are infinity, the result is invalid + * If n and m are zero, the result is invalid + */ + if (tm & tn & (VFP_INFINITY|VFP_ZERO)) + goto invalid; + + /* + * If n is infinity, the result is infinity + */ + if (tn & VFP_INFINITY) + goto infinity; + + /* + * If m is zero, raise div0 exception + */ + if (tm & VFP_ZERO) + goto divzero; + + /* + * If m is infinity, or n is zero, the result is zero + */ + if (tm & VFP_INFINITY || tn & VFP_ZERO) + goto zero; + + if (tn & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsn); + if (tm & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsm); + + /* + * Ok, we have two numbers, we can perform division. + */ + vsd.exponent = vsn.exponent - vsm.exponent + 127 - 1; + vsm.significand <<= 1; + if (vsm.significand <= (2 * vsn.significand)) { + vsn.significand >>= 1; + vsd.exponent++; + } + vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; + if ((vsd.significand & 0x3f) == 0) + vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); + + return vfp_single_normaliseround(sd, &vsd, fpscr, 0, "fdiv"); + + vsn_nan: + exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr); + pack: + vfp_put_float(sd, vfp_single_pack(&vsd)); + return exceptions; + + vsm_nan: + exceptions = vfp_propagate_nan(&vsd, &vsm, &vsn, fpscr); + goto pack; + + zero: + vsd.exponent = 0; + vsd.significand = 0; + goto pack; + + divzero: + exceptions = FPSCR_DZC; + infinity: + vsd.exponent = 255; + vsd.significand = 0; + goto pack; + + invalid: + vfp_put_float(sd, vfp_single_pack(&vfp_single_default_qnan)); + return FPSCR_IOC; +} + +static u32 (* const fop_fns[16])(int sd, int sn, s32 m, u32 fpscr) = { + [FOP_TO_IDX(FOP_FMAC)] = vfp_single_fmac, + [FOP_TO_IDX(FOP_FNMAC)] = vfp_single_fnmac, + [FOP_TO_IDX(FOP_FMSC)] = vfp_single_fmsc, + [FOP_TO_IDX(FOP_FNMSC)] = vfp_single_fnmsc, + [FOP_TO_IDX(FOP_FMUL)] = vfp_single_fmul, + [FOP_TO_IDX(FOP_FNMUL)] = vfp_single_fnmul, + [FOP_TO_IDX(FOP_FADD)] = vfp_single_fadd, + [FOP_TO_IDX(FOP_FSUB)] = vfp_single_fsub, + [FOP_TO_IDX(FOP_FDIV)] = vfp_single_fdiv, +}; + +#define FREG_BANK(x) ((x) & 0x18) +#define FREG_IDX(x) ((x) & 7) + +u32 vfp_single_cpdo(u32 inst, u32 fpscr) +{ + u32 op = inst & FOP_MASK; + u32 exceptions = 0; + unsigned int sd = vfp_get_sd(inst); + unsigned int sn = vfp_get_sn(inst); + unsigned int sm = vfp_get_sm(inst); + unsigned int vecitr, veclen, vecstride; + u32 (*fop)(int, int, s32, u32); + + veclen = fpscr & FPSCR_LENGTH_MASK; + vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); + + /* + * If destination bank is zero, vector length is always '1'. + * ARM DDI0100F C5.1.3, C5.3.2. + */ + if (FREG_BANK(sd) == 0) + veclen = 0; + + pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, + (veclen >> FPSCR_LENGTH_BIT) + 1); + + fop = (op == FOP_EXT) ? fop_extfns[sn] : fop_fns[FOP_TO_IDX(op)]; + if (!fop) + goto invalid; + + for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { + s32 m = vfp_get_float(sm); + u32 except; + + if (op == FOP_EXT) + pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, sd, sn, sm, m); + else + pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, sd, sn, + FOP_TO_IDX(op), sm, m); + + except = fop(sd, sn, m, fpscr); + pr_debug("VFP: itr%d: exceptions=%08x\n", + vecitr >> FPSCR_LENGTH_BIT, except); + + exceptions |= except; + + /* + * This ensures that comparisons only operate on scalars; + * comparisons always return with one FPSCR status bit set. + */ + if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + break; + + /* + * CHECK: It appears to be undefined whether we stop when + * we encounter an exception. We continue. + */ + + sd = FREG_BANK(sd) + ((FREG_IDX(sd) + vecstride) & 7); + sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7); + if (FREG_BANK(sm) != 0) + sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7); + } + return exceptions; + + invalid: + return (u32)-1; +} diff -Nru a/arch/arm26/kernel/init_task.c b/arch/arm26/kernel/init_task.c --- a/arch/arm26/kernel/init_task.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm26/kernel/init_task.c 2004-06-26 17:09:16 -07:00 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c --- a/arch/arm26/kernel/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm26/kernel/irq.c 2004-06-26 17:09:20 -07:00 @@ -549,7 +549,7 @@ action->handler = handler; action->flags = irq_flags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c --- a/arch/arm26/kernel/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/arm26/kernel/setup.c 2004-06-26 17:09:16 -07:00 @@ -76,7 +76,6 @@ unsigned char aux_device_present; char elf_platform[ELF_PLATFORM_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned long phys_initrd_start __initdata = 0; unsigned long phys_initrd_size __initdata = 0; diff -Nru a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c --- a/arch/arm26/mm/init.c 2004-06-26 17:09:20 -07:00 +++ b/arch/arm26/mm/init.c 2004-06-26 17:09:20 -07:00 @@ -67,7 +67,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); page = NODE_MEM_MAP(0); diff -Nru a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c --- a/arch/cris/arch-v10/kernel/time.c 2004-06-26 17:09:19 -07:00 +++ b/arch/cris/arch-v10/kernel/time.c 2004-06-26 17:09:19 -07:00 @@ -253,7 +253,7 @@ */ static struct irqaction irq2 = { timer_interrupt, SA_SHIRQ | SA_INTERRUPT, - 0, "timer", NULL, NULL}; + CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init(void) diff -Nru a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c --- a/arch/cris/kernel/irq.c 2004-06-26 17:09:21 -07:00 +++ b/arch/cris/kernel/irq.c 2004-06-26 17:09:21 -07:00 @@ -240,7 +240,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c --- a/arch/cris/kernel/process.c 2004-06-26 17:09:18 -07:00 +++ b/arch/cris/kernel/process.c 2004-06-26 17:09:19 -07:00 @@ -112,6 +112,7 @@ #include #include #include +#include //#define DEBUG diff -Nru a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c --- a/arch/cris/kernel/setup.c 2004-06-26 17:09:20 -07:00 +++ b/arch/cris/kernel/setup.c 2004-06-26 17:09:20 -07:00 @@ -29,10 +29,7 @@ extern int root_mountflags; extern char _etext, _edata, _end; -#define COMMAND_LINE_SIZE 256 - static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; extern const unsigned long text_start, edata; /* set by the linker script */ extern unsigned long dram_start, dram_end; diff -Nru a/arch/cris/mm/init.c b/arch/cris/mm/init.c --- a/arch/cris/mm/init.c 2004-06-26 17:09:17 -07:00 +++ b/arch/cris/mm/init.c 2004-06-26 17:09:17 -07:00 @@ -138,7 +138,7 @@ printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff -Nru a/arch/h8300/Kconfig b/arch/h8300/Kconfig --- a/arch/h8300/Kconfig 2004-06-26 17:09:19 -07:00 +++ b/arch/h8300/Kconfig 2004-06-26 17:09:19 -07:00 @@ -223,7 +223,7 @@ config CONFIG_SH_STANDARD_BIOS bool "Use gdb protocol serial console" - depends on (!H8300H_SIM && H8S_SIM) + depends on (!H8300H_SIM && !H8S_SIM) help serial console output using GDB protocol. Require eCos/RedBoot diff -Nru a/arch/h8300/kernel/init_task.c b/arch/h8300/kernel/init_task.c --- a/arch/h8300/kernel/init_task.c 2004-06-26 17:09:16 -07:00 +++ b/arch/h8300/kernel/init_task.c 2004-06-26 17:09:16 -07:00 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c --- a/arch/h8300/kernel/ptrace.c 2004-06-26 17:09:17 -07:00 +++ b/arch/h8300/kernel/ptrace.c 2004-06-26 17:09:17 -07:00 @@ -116,18 +116,36 @@ case PTRACE_PEEKUSR: { unsigned long tmp; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) { ret = -EIO; + break ; + } - tmp = 0; /* Default return condition */ + ret = 0; /* Default return condition */ addr = addr >> 2; /* temporary hack. */ + if (addr < H8300_REGS_NO) tmp = h8300_get_reg(child, addr); else { - ret = -EIO; - break ; + switch(addr) { + case 49: + tmp = child->mm->start_code; + break ; + case 50: + tmp = child->mm->start_data; + break ; + case 51: + tmp = child->mm->end_code; + break ; + case 52: + tmp = child->mm->end_data; + break ; + default: + ret = -EIO; + } } - ret = put_user(tmp,(unsigned long *) data); + if (!ret) + ret = put_user(tmp,(unsigned long *) data); break ; } diff -Nru a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c --- a/arch/h8300/kernel/setup.c 2004-06-26 17:09:15 -07:00 +++ b/arch/h8300/kernel/setup.c 2004-06-26 17:09:15 -07:00 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -54,8 +55,7 @@ unsigned long memory_start; unsigned long memory_end; -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; extern int _ramstart, _ramend; diff -Nru a/arch/h8300/platform/h8s/entry.S b/arch/h8300/platform/h8s/entry.S --- a/arch/h8300/platform/h8s/entry.S 2004-06-26 17:09:20 -07:00 +++ b/arch/h8300/platform/h8s/entry.S 2004-06-26 17:09:20 -07:00 @@ -83,6 +83,7 @@ mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */ mov.l er1,@er0 mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */ + mov.b r1l,r1h mov.w r1,@(8:16,er0) mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */ mov.b r1l,r1h @@ -213,7 +214,6 @@ mov.l er0,@(LER0:16,sp) /* save the return value */ jsr @SYMBOL_NAME(syscall_trace) bra SYMBOL_NAME(ret_from_exception):8 - SYMBOL_NAME_LABEL(ret_from_fork) mov.l er2,er0 diff -Nru a/arch/h8300/platform/h8s/ptrace_h8s.c b/arch/h8300/platform/h8s/ptrace_h8s.c --- a/arch/h8300/platform/h8s/ptrace_h8s.c 2004-06-26 17:09:16 -07:00 +++ b/arch/h8300/platform/h8s/ptrace_h8s.c 2004-06-26 17:09:16 -07:00 @@ -23,7 +23,7 @@ static const int h8300_register_offset[] = { PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4), PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0), - PT_REG(ccr), PT_REG(pc), PT_REG(exr) + PT_REG(ccr), PT_REG(pc), 0, PT_REG(exr) }; /* read register */ diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/i386/Kconfig 2004-06-26 17:09:16 -07:00 @@ -436,7 +436,8 @@ Choose N to continue using the legacy 8254 timer. config HPET_EMULATE_RTC - def_bool HPET_TIMER && RTC=y + bool "Provide RTC interrupt" + depends on HPET_TIMER && RTC=y config SMP bool "Symmetric multi-processing support" @@ -1333,12 +1334,6 @@ config X86_TRAMPOLINE bool depends on X86_SMP || (X86_VOYAGER && SMP) - default y - -# std_resources is overridden for pc9800, but that's not -# a currently selectable arch choice -config X86_STD_RESOURCES - bool default y config PC diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile --- a/arch/i386/Makefile 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/Makefile 2004-06-26 17:09:17 -07:00 @@ -121,22 +121,23 @@ all: bzImage -BOOTIMAGE=arch/i386/boot/bzImage -zImage zlilo zdisk: BOOTIMAGE=arch/i386/boot/zImage +# KBUILD_IMAGE specify target image being built + KBUILD_IMAGE := $(boot)/bzImage +zImage zlilo zdisk: KBUILD_IMAGE := arch/i386/boot/zImage zImage bzImage: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE) + $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE) compressed: zImage zlilo bzlilo: vmlinux - $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo + $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo zdisk bzdisk: vmlinux - $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zdisk + $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk install fdimage fdimage144 fdimage288: vmlinux - $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ + $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ prepare: include/asm-$(ARCH)/asm_offsets.h CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h diff -Nru a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c --- a/arch/i386/boot/compressed/misc.c 2004-06-26 17:09:18 -07:00 +++ b/arch/i386/boot/compressed/misc.c 2004-06-26 17:09:18 -07:00 @@ -87,12 +87,11 @@ */ static unsigned char *real_mode; /* Pointer to real-mode data */ -#define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) +#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) #ifndef STANDARD_MEMORY_BIOS_CALL -#define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) +#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) #endif -#define SCREEN_INFO (*(struct screen_info *)(real_mode+0)) -#define EDID_INFO (*(struct edid_info *)(real_mode+0x440)) +#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) extern char input_data[]; extern int input_len; @@ -174,8 +173,8 @@ int x,y,pos; char c; - x = SCREEN_INFO.orig_x; - y = SCREEN_INFO.orig_y; + x = RM_SCREEN_INFO.orig_x; + y = RM_SCREEN_INFO.orig_y; while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { @@ -196,8 +195,8 @@ } } - SCREEN_INFO.orig_x = x; - SCREEN_INFO.orig_y = y; + RM_SCREEN_INFO.orig_x = x; + RM_SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; /* Update cursor position */ outb_p(14, vidport); @@ -306,9 +305,9 @@ static void setup_normal_output_buffer(void) { #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < 1024) error("Less than 2MB of memory"); + if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif output_data = (char *)0x100000; /* Points to 1M */ free_mem_end_ptr = (long)real_mode; @@ -323,9 +322,11 @@ { high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); + if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < + (3*1024)) + error("Less than 4MB of memory"); #endif mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX @@ -358,7 +359,7 @@ { real_mode = rmode; - if (SCREEN_INFO.orig_video_mode == 7) { + if (RM_SCREEN_INFO.orig_video_mode == 7) { vidmem = (char *) 0xb0000; vidport = 0x3b4; } else { @@ -366,8 +367,8 @@ vidport = 0x3d4; } - lines = SCREEN_INFO.orig_video_lines; - cols = SCREEN_INFO.orig_video_cols; + lines = RM_SCREEN_INFO.orig_video_lines; + cols = RM_SCREEN_INFO.orig_video_cols; if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); else setup_output_buffer_if_we_run_high(mv); diff -Nru a/arch/i386/boot98/Makefile b/arch/i386/boot98/Makefile --- a/arch/i386/boot98/Makefile 2004-06-26 17:09:18 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,102 +0,0 @@ -# -# arch/i386/boot/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1994 by Linus Torvalds -# - -# ROOT_DEV specifies the default root-device when making the image. -# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case -# the default of FLOPPY is used by 'build'. - -ROOT_DEV := CURRENT - -# If you want to preset the SVGA mode, uncomment the next line and -# set SVGA_MODE to whatever number you want. -# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode. -# The number is the same as you would ordinarily press at bootup. - -SVGA_MODE := -DSVGA_MODE=NORMAL_VGA - -# If you want the RAM disk device, define this to be the size in blocks. - -#RAMDISK := -DRAMDISK=512 - -targets := vmlinux.bin bootsect bootsect.o setup setup.o \ - zImage bzImage -subdir- := compressed - -host-progs := tools/build - -# --------------------------------------------------------------------------- - -$(obj)/zImage: IMAGE_OFFSET := 0x1000 -$(obj)/zImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -$(obj)/bzImage: IMAGE_OFFSET := 0x100000 -$(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ -$(obj)/bzImage: BUILDFLAGS := -b - -quiet_cmd_image = BUILD $@ -cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \ - $(obj)/vmlinux.bin $(ROOT_DEV) > $@ - -$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ - $(obj)/vmlinux.bin $(obj)/tools/build FORCE - $(call if_changed,image) - @echo 'Kernel: $@ is ready' - -$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE - $(call if_changed,objcopy) - -LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary -LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext - -$(obj)/setup $(obj)/bootsect: %: %.o FORCE - $(call if_changed,ld) - -$(obj)/compressed/vmlinux: FORCE - $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ - -# Set this if you want to pass append arguments to the zdisk/fdimage kernel -FDARGS = - -$(obj)/mtools.conf: $(src)/mtools.conf.in - sed -e 's|@OBJ@|$(obj)|g' < $< > $@ - -# This requires write access to /dev/fd0 -zdisk: $(BOOTIMAGE) $(obj)/mtools.conf - MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync - syslinux /dev/fd0 ; sync - echo 'default linux $(FDARGS)' | \ - MTOOLSRC=$(src)/mtools.conf mcopy - a:syslinux.cfg - MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync - -# These require being root or having syslinux 2.02 or higher installed -fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf - dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440 - MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync - syslinux $(obj)/fdimage ; sync - echo 'default linux $(FDARGS)' | \ - MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg - MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync - -fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf - dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880 - MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync - syslinux $(obj)/fdimage ; sync - echo 'default linux $(FDARGS)' | \ - MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg - MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync - -zlilo: $(BOOTIMAGE) - if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi - if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi - cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz - cp System.map $(INSTALL_PATH)/ - if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi - -install: $(BOOTIMAGE) - sh $(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" diff -Nru a/arch/i386/boot98/bootsect.S b/arch/i386/boot98/bootsect.S --- a/arch/i386/boot98/bootsect.S 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,397 +0,0 @@ -/* - * bootsect.S - boot sector for NEC PC-9800 series - * - * Linux/98 project at Kyoto University Microcomputer Club (KMC) - * FUJITA Norimasa, TAKAI Kousuke 1997-1998 - * rewritten by TAKAI Kousuke (as86 -> gas), Nov 1999 - * - * Based on: - * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds - * modified by Drew Eckhardt - * modified by Bruce Evans (bde) - * - * bootsect.S is loaded at 0x1FC00 or 0x1FE00 by the bios-startup routines, - * and moves itself out of the way to address 0x90000, and jumps there. - * - * It then loads 'setup' directly after itself (0x90200), and the system - * at 0x10000, using BIOS interrupts. - * - * NOTE! currently system is at most (8*65536-4096) bytes long. This should - * be no problem, even in the future. I want to keep it simple. This 508 kB - * kernel size should be enough, especially as this doesn't contain the - * buffer cache as in minix (and especially now that the kernel is - * compressed :-) - * - * The loader has been made as simple as possible, and continuous - * read errors will result in a unbreakable loop. Reboot by hand. It - * loads pretty fast by getting whole tracks at a time whenever possible. - */ - -#include /* for CONFIG_ROOT_RDONLY */ -#include - -SETUPSECTS = 4 /* default nr of setup-sectors */ -BOOTSEG = 0x1FC0 /* original address of boot-sector */ -INITSEG = DEF_INITSEG /* we move boot here - out of the way */ -SETUPSEG = DEF_SETUPSEG /* setup starts here */ -SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */ -SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */ - /* to be loaded */ -ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */ -SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */ - -#ifndef SVGA_MODE -#define SVGA_MODE ASK_VGA -#endif - -#ifndef RAMDISK -#define RAMDISK 0 -#endif - -#ifndef ROOT_RDONLY -#define ROOT_RDONLY 1 -#endif - -/* normal/hireso text VRAM segments */ -#define NORMAL_TEXT 0xa000 -#define HIRESO_TEXT 0xe000 - -/* bios work area addresses */ -#define EXPMMSZ 0x0401 -#define BIOS_FLAG 0x0501 -#define DISK_BOOT 0x0584 - -.code16 -.text - -.global _start -_start: - -#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */ - int $0x3 -#endif - jmp real_start - .ascii "Linux 98" - .word 0 -real_start: - xorw %di, %di /* %di = 0 */ - movw %di, %ss /* %ss = 0 */ - movw $0x03F0, %sp - pushw %cx /* for hint */ - - movw $0x0A00, %ax /* normal mode defaults (80x25) */ - - testb $0x08, %ss:BIOS_FLAG /* check hi-reso bit */ - jnz set_crt_mode -/* - * Hi-Reso (high-resolution) machine. - * - * Some hi-reso machines have no RAMs on bank 8/A (0x080000 - 0x0BFFFF). - * On such machines we get two RAM banks from top of protect menory and - * map them on bank 8/A. - * These work-around must be done before moving myself on INITSEG (0x090000-). - */ - movw $(HIRESO_TEXT >> 8), %cs:(vram + 1) /* text VRAM segment */ - - /* set memory window */ - movb $0x08, %al - outb %al, $0x91 /* map native RAM (if any) */ - movb $0x0A, %al - outb %al, $0x93 - - /* check bank ram A */ - pushw $0xA500 - popw %ds - movw (%di), %cx /* %si == 0 from entry */ - notw %cx - movw %cx, (%di) - - movw $0x43F, %dx /* cache flush for 486 and up. */ - movb $0xA0, %al - outb %al, %dx - - cmpw %cx, (%di) - je hireso_done - - /* - * Write test failed; we have no native RAM on 080000h - 0BFFFFh. - * Take 256KB of RAM from top of protected memory. - */ - movb %ss:EXPMMSZ, %al - subb $2, %al /* reduce 2 x 128KB */ - movb %al, %ss:EXPMMSZ - addb %al, %al - addb $0x10, %al - outb %al, $0x91 - addb $2, %al - outb %al, $0x93 - -hireso_done: - movb $0x10, %al /* CRT mode 80x31, %ah still 0Ah */ - -set_crt_mode: - int $0x18 /* set CRT mode */ - - movb $0x0C, %ah /* turn on text displaying */ - int $0x18 - - xorw %dx, %dx /* position cursor to home */ - movb $0x13, %ah - int $0x18 - - movb $0x11, %ah /* turn cursor displaying on */ - int $0x18 - - /* move 1 kilobytes from [BOOTSEG:0000h] to [INITSEG:0000h] */ - cld - xorw %si, %si - pushw $INITSEG - popw %es - movw $512, %cx /* %di == 0 from entry */ - rep - cs - movsw - - ljmp $INITSEG, $go - -go: - pushw %cs - popw %ds /* %ds = %cs */ - - popw %dx /* %dh = saved %ch passed from BIOS */ - movb %ss:DISK_BOOT, %al - andb $0xf0, %al /* %al = Device Address */ - movb $18, %ch /* 18 secs/track, 512 b/sec (1440 KB) */ - cmpb $0x30, %al - je try512 - cmpb $0x90, %al /* 1 MB I/F, 1 MB floppy */ - je try1.2M - cmpb $0xf0, %al /* 640 KB I/F, 1 MB floppy */ - je try1.2M - movb $9, %ch /* 9 secs/track, 512 b/sec ( 720 KB) */ - cmpb $0x10, %al /* 1 MB I/F, 640 KB floppy */ - je try512 - cmpb $0x70, %al /* 640 KB I/F, 640 KB floppy */ - jne error /* unknown device? */ - - /* XXX: Does it make sense to support 8 secs/track, 512 b/sec - (640 KB) floppy? */ - -try512: movb $2, %cl /* 512 b/sec */ -lasttry:call tryload -/* - * Display error message and halt - */ -error: movw $error_msg, %si - call print -wait_reboot: - movb $0x0, %ah - int $0x18 /* wait keyboard input */ -1: movb $0, %al - outb %al, $0xF0 /* reset CPU */ - jmp 1b /* just in case... */ - -try1.2M:cmpb $2, %dh - je try2HC - movw $0x0803, %cx /* 8 secs/track, 1024 b/sec (1232 KB) */ - call tryload - movb $15, %ch /* 15 secs/track, 512 b/sec (1200 KB) */ - jmp try512 -try2HC: movw $0x0F02, %cx /* 15 secs/track, 512 b/sec (1200 KB) */ - call tryload - movw $0x0803, %cx /* 8 secs/track, 1024 b/sec (1232 KB) */ - jmp lasttry - -/* - * Try to load SETUP and SYSTEM provided geometry information in %cx. - * This routine *will not* return on successful load... - */ -tryload: - movw %cx, sectlen - movb %ss:DISK_BOOT, %al - movb $0x7, %ah /* recalibrate the drive */ - int $0x1b - jc error /* recalibration should succeed */ - - /* - * Load SETUP into memory. It is assumed that SETUP fits into - * first cylinder (2 tracks, 9KB on 2DD, 15-18KB on 2HD). - */ - movb $0, %bl - movb setup_sects, %bh - incb %bh - shlw %bx /* %bx = (setup_sects + 1) * 512 */ - movw $128, %bp - shlw %cl, %bp /* %bp = */ - subw %bp, %bx /* length to load */ - movw $0x0002, %dx /* head 0, sector 2 */ - movb %cl, %ch /* `N' for sector address */ - movb $0, %cl /* cylinder 0 */ - pushw %cs - popw %es /* %es = %cs (= INITSEG) */ - movb $0xd6, %ah /* read, multi-track, MFM */ - int $0x1b /* load it! */ - jc read_error - - movw $loading_msg, %si - call print - - movw $SYSSEG, %ax - movw %ax, %es /* %es = SYSSEG */ - -/* - * This routine loads the system at address 0x10000, making sure - * no 64kB boundaries are crossed. We try to load it as fast as - * possible, loading whole tracks whenever we can. - * - * in: es - starting address segment (normally 0x1000) - */ - movb %ch, %cl - addb $7, %cl /* %cl = log2 */ - shrw %cl, %bx /* %bx = # of phys. sectors in SETUP */ - addb %bl, %dl /* %dl = start sector # of SYSTEM */ - decb %dl /* %dl is 0-based in below loop */ - -rp_read_newseg: - xorw %bp, %bp /* = starting address within segment */ -#ifdef __BIG_KERNEL__ - bootsect_kludge = 0x220 /* 0x200 (size of bootsector) + 0x20 (offset */ - lcall *bootsect_kludge /* of bootsect_kludge in setup.S */ -#else - movw %es, %ax - subw $SYSSEG, %ax -#endif - cmpw syssize, %ax - ja boot /* done! */ - -rp_read: - movb sectors, %al - addb %al, %al - movb %al, %ch /* # of sectors on both surface */ - subb %dl, %al /* # of sectors left on this track */ - movb $0, %ah - shlw %cl, %ax /* # of bytes left on this track */ - movw %ax, %bx /* transfer length */ - addw %bp, %ax /* cross 64K boundary? */ - jnc 1f /* ok. */ - jz 1f /* also ok. */ - /* - * Oops, we are crossing 64K boundary... - * Adjust transfer length to make transfer fit in the boundary. - * - * Note: sector size is assumed to be a measure of 65536. - */ - xorw %bx, %bx - subw %bp, %bx -1: pushw %dx - movw $dot_msg, %si /* give progress message */ - call print - xchgw %ax, %dx - movb $0, %ah - divb sectors - xchgb %al, %ah - xchgw %ax, %dx /* %dh = head # / %dl = sector # */ - incb %dl /* fix %dl to 1-based */ - pushw %cx - movw cylinder, %cx - movb $0xd6, %ah /* read, multi-track, seek, MFM */ - movb %ss:DISK_BOOT, %al - int $0x1b - popw %cx - popw %dx - jc read_error - movw %bx, %ax /* # of bytes just read */ - shrw %cl, %ax /* %ax = # of sectors just read */ - addb %al, %dl /* advance sector # */ - cmpb %ch, %dl /* %ch = # of sectors/cylinder */ - jb 2f - incb cylinder /* next cylinder */ - xorb %dl, %dl /* sector 0 */ -2: addw %bx, %bp /* advance offset pointer */ - jnc rp_read - /* offset pointer wrapped; advance segment pointer. */ - movw %es, %ax - addw $0x1000, %ax - movw %ax, %es - jmp rp_read_newseg - -read_error: - ret - -boot: movw %cs, %ax /* = INITSEG */ - /* movw %ax, %ds */ - movw %ax, %ss - movw $0x4000, %sp /* 0x4000 is arbitrary value >= - * length of bootsect + length of - * setup + room for stack; - * PC-9800 never have BIOS workareas - * on high memory. - */ -/* - * After that we check which root-device to use. If the device is - * not defined, /dev/fd0 (2, 0) will be used. - */ - cmpw $0, root_dev - jne 3f - movb $2, root_dev+1 -3: - -/* - * After that (everything loaded), we jump to the setup-routine - * loaded directly after the bootblock: - */ - ljmp $SETUPSEG, $0 - -/* - * Subroutine for print string on console. - * %cs:%si - pointer to message - */ -print: - pushaw - pushw %ds - pushw %es - pushw %cs - popw %ds - lesw curpos, %di /* %es:%di = current text VRAM addr. */ -1: xorw %ax, %ax - lodsb - testb %al, %al - jz 2f /* end of string */ - stosw /* character code */ - movb $0xE1, %es:0x2000-2(%di) /* character attribute */ - jmp 1b -2: movw %di, %dx - movb $0x13, %ah - int $0x18 /* move cursor to current point */ - popw %es - popw %ds - popaw - ret - -loading_msg: - .string "Loading" -dot_msg: - .string "." -error_msg: - .string "Read Error!" - - .org 490 - -curpos: .word 160 /* current cursor position */ -vram: .word NORMAL_TEXT /* text VRAM segment */ - -cylinder: .byte 0 /* current cylinder (lower byte) */ -sectlen: .byte 0 /* (log2 of ) - 7 */ -sectors: .byte 0x0F /* default is 2HD (15 sector/track) */ - -# XXX: This is a fairly snug fit. - -.org 497 -setup_sects: .byte SETUPSECTS -root_flags: .word ROOT_RDONLY -syssize: .word SYSSIZE -swap_dev: .word SWAP_DEV -ram_size: .word RAMDISK -vid_mode: .word SVGA_MODE -root_dev: .word ROOT_DEV -boot_flag: .word 0xAA55 diff -Nru a/arch/i386/boot98/install.sh b/arch/i386/boot98/install.sh --- a/arch/i386/boot98/install.sh 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,40 +0,0 @@ -#!/bin/sh -# -# arch/i386/boot/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for i386 architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -# User may have a custom install script - -if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi -if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi - -# Default install - same as make zlilo - -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old -fi - -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old -fi - -cat $2 > $4/vmlinuz -cp $3 $4/System.map - -if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi diff -Nru a/arch/i386/boot98/mtools.conf.in b/arch/i386/boot98/mtools.conf.in --- a/arch/i386/boot98/mtools.conf.in 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,17 +0,0 @@ -# -# mtools configuration file for "make (b)zdisk" -# - -# Actual floppy drive -drive a: - file="/dev/fd0" - -# 1.44 MB floppy disk image -drive v: - file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter - -# 2.88 MB floppy disk image (mostly for virtual uses) -drive w: - file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter - - diff -Nru a/arch/i386/boot98/setup.S b/arch/i386/boot98/setup.S --- a/arch/i386/boot98/setup.S 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,876 +0,0 @@ -/* - * setup.S Copyright (C) 1991, 1992 Linus Torvalds - * - * setup.s is responsible for getting the system data from the BIOS, - * and putting them into the appropriate places in system memory. - * both setup.s and system has been loaded by the bootblock. - * - * This code asks the bios for memory/disk/other parameters, and - * puts them in a "safe" place: 0x90000-0x901FF, ie where the - * boot-block used to be. It is then up to the protected mode - * system to read them from there before the area is overwritten - * for buffer-blocks. - * - * Move PS/2 aux init code to psaux.c - * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92 - * - * some changes and additional features by Christoph Niemann, - * March 1993/June 1994 (Christoph.Niemann@linux.org) - * - * add APM BIOS checking by Stephen Rothwell, May 1994 - * (sfr@canb.auug.org.au) - * - * High load stuff, initrd support and position independency - * by Hans Lermen & Werner Almesberger, February 1996 - * , - * - * Video handling moved to video.S by Martin Mares, March 1996 - * - * - * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david - * parsons) to avoid loadlin confusion, July 1997 - * - * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. - * - * - * Fix to work around buggy BIOSes which dont use carry bit correctly - * and/or report extended memory in CX/DX for e801h memory size detection - * call. As a result the kernel got wrong figures. The int15/e801h docs - * from Ralf Brown interrupt list seem to indicate AX/BX should be used - * anyway. So to avoid breaking many machines (presumably there was a reason - * to orginally use CX/DX instead of AX/BX), we do a kludge to see - * if CX/DX have been changed in the e801 call and if so use AX/BX . - * Michael Miller, April 2001 - * - * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes - * by Robert Schwebel, December 2001 - * - * Heavily modified for NEC PC-9800 series by Kyoto University Microcomputer - * Club (KMC) Linux/98 project , 1997-1999 - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Signature words to ensure LILO loaded us right */ -#define SIG1 0xAA55 -#define SIG2 0x5A5A - -#define HIRESO_TEXT 0xe000 -#define NORMAL_TEXT 0xa000 - -#define BIOS_FLAG2 0x0400 -#define BIOS_FLAG5 0x0458 -#define RDISK_EQUIP 0x0488 -#define BIOS_FLAG 0x0501 -#define KB_SHFT_STS 0x053a -#define DISK_EQUIP 0x055c - -INITSEG = DEF_INITSEG # 0x9000, we move boot here, out of the way -SYSSEG = DEF_SYSSEG # 0x1000, system loaded at 0x10000 (65536). -SETUPSEG = DEF_SETUPSEG # 0x9020, this is the current segment - # ... and the former contents of CS - -DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020 - -.code16 -.globl begtext, begdata, begbss, endtext, enddata, endbss - -.text -begtext: -.data -begdata: -.bss -begbss: -.text - -start: - jmp trampoline - -# This is the setup header, and it must start at %cs:2 (old 0x9020:2) - - .ascii "HdrS" # header signature - .word 0x0203 # header version number (>= 0x0105) - # or else old loadlin-1.5 will fail) -realmode_swtch: .word 0, 0 # default_switch, SETUPSEG -start_sys_seg: .word SYSSEG - .word kernel_version # pointing to kernel version string - # above section of header is compatible - # with loadlin-1.5 (header v1.5). Don't - # change it. - -type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin, - # Bootlin, SYSLX, bootsect...) - # See Documentation/i386/boot.txt for - # assigned ids - -# flags, unused bits must be zero (RFU) bit within loadflags -loadflags: -LOADED_HIGH = 1 # If set, the kernel is loaded high -CAN_USE_HEAP = 0x80 # If set, the loader also has set - # heap_end_ptr to tell how much - # space behind setup.S can be used for - # heap purposes. - # Only the loader knows what is free -#ifndef __BIG_KERNEL__ - .byte 0 -#else - .byte LOADED_HIGH -#endif - -setup_move_size: .word 0x8000 # size to move, when setup is not - # loaded at 0x90000. We will move setup - # to 0x90000 then just before jumping - # into the kernel. However, only the - # loader knows how much data behind - # us also needs to be loaded. - -code32_start: # here loaders can put a different - # start address for 32-bit code. -#ifndef __BIG_KERNEL__ - .long 0x1000 # 0x1000 = default for zImage -#else - .long 0x100000 # 0x100000 = default for big kernel -#endif - -ramdisk_image: .long 0 # address of loaded ramdisk image - # Here the loader puts the 32-bit - # address where it loaded the image. - # This only will be read by the kernel. - -ramdisk_size: .long 0 # its size in bytes - -bootsect_kludge: - .long 0 # obsolete - -heap_end_ptr: .word modelist+1024 # (Header version 0x0201 or later) - # space from here (exclusive) down to - # end of setup code can be used by setup - # for local heap purposes. - -pad1: .word 0 -cmd_line_ptr: .long 0 # (Header version 0x0202 or later) - # If nonzero, a 32-bit pointer - # to the kernel command line. - # The command line should be - # located between the start of - # setup and the end of low - # memory (0xa0000), or it may - # get overwritten before it - # gets read. If this field is - # used, there is no longer - # anything magical about the - # 0x90000 segment; the setup - # can be located anywhere in - # low memory 0x10000 or higher. - -ramdisk_max: .long MAXMEM-1 # (Header version 0x0203 or later) - # The highest safe address for - # the contents of an initrd - -trampoline: call start_of_setup - .space 1024 -# End of setup header ##################################################### - -start_of_setup: -# Set %ds = %cs, we know that SETUPSEG = %cs at this point - movw %cs, %ax # aka SETUPSEG - movw %ax, %ds -# Check signature at end of setup - cmpw $SIG1, setup_sig1 - jne bad_sig - - cmpw $SIG2, setup_sig2 - jne bad_sig - - jmp good_sig1 - -# Routine to print asciiz string at ds:si -prtstr: - lodsb - andb %al, %al - jz fin - - call prtchr - jmp prtstr - -fin: ret - -no_sig_mess: .string "No setup signature found ..." - -good_sig1: - jmp good_sig - -# We now have to find the rest of the setup code/data -bad_sig: - movw %cs, %ax # SETUPSEG - subw $DELTA_INITSEG, %ax # INITSEG - movw %ax, %ds - xorb %bh, %bh - movb (497), %bl # get setup sect from bootsect - subw $4, %bx # LILO loads 4 sectors of setup - shlw $8, %bx # convert to words (1sect=2^8 words) - movw %bx, %cx - shrw $3, %bx # convert to segment - addw $SYSSEG, %bx - movw %bx, %cs:start_sys_seg -# Move rest of setup code/data to here - movw $2048, %di # four sectors loaded by LILO - subw %si, %si - pushw %cs - popw %es - movw $SYSSEG, %ax - movw %ax, %ds - rep - movsw - movw %cs, %ax # aka SETUPSEG - movw %ax, %ds - cmpw $SIG1, setup_sig1 - jne no_sig - - cmpw $SIG2, setup_sig2 - jne no_sig - - jmp good_sig - -no_sig: - lea no_sig_mess, %si - call prtstr - -no_sig_loop: - hlt - jmp no_sig_loop - -good_sig: - movw %cs, %ax # aka SETUPSEG - subw $DELTA_INITSEG, %ax # aka INITSEG - movw %ax, %ds -# Check if an old loader tries to load a big-kernel - testb $LOADED_HIGH, %cs:loadflags # Do we have a big kernel? - jz loader_ok # No, no danger for old loaders. - - cmpb $0, %cs:type_of_loader # Do we have a loader that - # can deal with us? - jnz loader_ok # Yes, continue. - - pushw %cs # No, we have an old loader, - popw %ds # die. - lea loader_panic_mess, %si - call prtstr - - jmp no_sig_loop - -loader_panic_mess: .string "Wrong loader, giving up..." - -loader_ok: -# Get memory size (extended mem, kB) - -# On PC-9800, memory size detection is done completely in 32-bit -# kernel initialize code (kernel/setup.c). - pushw %es - xorl %eax, %eax - movw %ax, %es - movb %al, (E820NR) # PC-9800 has no E820 - movb %es:(0x401), %al - shll $7, %eax - addw $1024, %ax - movw %ax, (2) - movl %eax, (0x1e0) - movw %es:(0x594), %ax - shll $10, %eax - addl %eax, (0x1e0) - popw %es - -# Check for video adapter and its parameters and allow the -# user to browse video modes. - call video # NOTE: we need %ds pointing - # to bootsector - -# Get text video mode - movb $0x0B, %ah - int $0x18 # CRT mode sense - movw $(20 << 8) + 40, %cx - testb $0x10, %al - jnz 3f - movb $20, %ch - testb $0x01, %al - jnz 1f - movb $25, %ch - jmp 1f -3: # If bit 4 was 1, it means either 1) 31 lines for hi-reso mode, - # or 2) 30 lines for PC-9821. - movb $31, %ch # hireso mode value - pushw $0 - popw %es - testb $0x08, %es:BIOS_FLAG - jnz 1f - movb $30, %ch -1: # Now we got # of rows in %ch - movb %ch, (14) - - testb $0x02, %al - jnz 2f - movb $80, %cl -2: # Now we got # of columns in %cl - movb %cl, (7) - - # Next, get horizontal frequency if supported - movw $0x3100, %ax - int $0x18 # Call CRT bios - movb %al, (6) # If 31h is unsupported, %al remains 0 - -# Get hd0-3 data... - pushw %ds # aka INITSEG - popw %es - xorw %ax, %ax - movw %ax, %ds - cld - movw $0x0080, %di - movb DISK_EQUIP+1, %ah - movb $0x80, %al - -get_hd_info: - shrb %ah - pushw %ax - jnc 1f - movb $0x84, %ah - int $0x1b - jnc 2f # Success -1: xorw %cx, %cx # `0 cylinders' means no drive -2: # Attention! Work area (drive_info) is arranged for PC-9800. - movw %cx, %ax # # of cylinders - stosw - movw %dx, %ax # # of sectors / # of heads - stosw - movw %bx, %ax # sector size in bytes - stosw - popw %ax - incb %al - cmpb $0x84, %al - jb get_hd_info - -# Get fd data... - movw DISK_EQUIP, %ax - andw $0xf00f, %ax - orb %al, %ah - movb RDISK_EQUIP, %al - notb %al - andb %al, %ah # ignore all `RAM drive' - - movb $0x30, %al - -get_fd_info: - shrb %ah - pushw %ax - jnc 1f - movb $0xc4, %ah - int $0x1b - movb %ah, %al - andb $4, %al # 1.44MB support flag - shrb %al - addb $2, %al # %al = 2 (1.2MB) or 4 (1.44MB) - jmp 2f -1: movb $0, %al # no drive -2: stosb - popw %ax - incb %al - testb $0x04, %al - jz get_fd_info - - addb $(0xb0 - 0x34), %al - jnc get_fd_info # check FDs on 640KB I/F - - pushw %es - popw %ds # %ds got bootsector again -#if 0 - mov $0, (0x1ff) # default is no pointing device -#endif - -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) -# Then check for an APM BIOS... - # %ds points to the bootsector - movw $0, 0x40 # version = 0 means no APM BIOS - movw $0x09a00, %ax # APM BIOS installation check - xorw %bx, %bx - int $0x1f - jc done_apm_bios # Nope, no APM BIOS - - cmpw $0x0504d, %bx # Check for "PM" signature - jne done_apm_bios # No signature, no APM BIOS - - testb $0x02, %cl # Is 32 bit supported? - je done_apm_bios # No 32-bit, no (good) APM BIOS - - movw $0x09a04, %ax # Disconnect first just in case - xorw %bx, %bx - int $0x1f # ignore return code - movw $0x09a03, %ax # 32 bit connect - xorl %ebx, %ebx - int $0x1f - jc no_32_apm_bios # Ack, error. - - movw %ax, (66) # BIOS code segment - movl %ebx, (68) # BIOS entry point offset - movw %cx, (72) # BIOS 16 bit code segment - movw %dx, (74) # BIOS data segment - movl %esi, (78) # BIOS code segment length - movw %di, (82) # BIOS data segment length -# Redo the installation check as the 32 bit connect -# modifies the flags returned on some BIOSs - movw $0x09a00, %ax # APM BIOS installation check - xorw %bx, %bx - int $0x1f - jc apm_disconnect # error -> shouldn't happen - - cmpw $0x0504d, %bx # check for "PM" signature - jne apm_disconnect # no sig -> shouldn't happen - - movw %ax, (64) # record the APM BIOS version - movw %cx, (76) # and flags - jmp done_apm_bios - -apm_disconnect: # Tidy up - movw $0x09a04, %ax # Disconnect - xorw %bx, %bx - int $0x1f # ignore return code - - jmp done_apm_bios - -no_32_apm_bios: - andw $0xfffd, (76) # remove 32 bit support bit -done_apm_bios: -#endif - -# Pass cursor position to kernel... - movw %cs:cursor_address, %ax - shrw %ax # cursor_address is 2 bytes unit - movb $80, %cl - divb %cl - xchgb %al, %ah # (0) = %al = X, (1) = %ah = Y - movw %ax, (0) - -#if 0 - movw $msg_cpos, %si - call prtstr_cs - call prthex - call prtstr_cs - movw %ds, %ax - call prthex - call prtstr_cs - movb $0x11, %ah - int $0x18 - movb $0, %ah - int $0x18 - .section .rodata, "a" -msg_cpos: .string "Cursor position: 0x" - .string ", %ds:0x" - .string "\r\n" - .previous -#endif - -# Now we want to move to protected mode ... - cmpw $0, %cs:realmode_swtch - jz rmodeswtch_normal - - lcall *%cs:realmode_swtch - - jmp rmodeswtch_end - -rmodeswtch_normal: - pushw %cs - call default_switch - -rmodeswtch_end: -# we get the code32 start address and modify the below 'jmpi' -# (loader may have changed it) - movl %cs:code32_start, %eax - movl %eax, %cs:code32 - -# Now we move the system to its rightful place ... but we check if we have a -# big-kernel. In that case we *must* not move it ... - testb $LOADED_HIGH, %cs:loadflags - jz do_move0 # .. then we have a normal low - # loaded zImage - # .. or else we have a high - # loaded bzImage - jmp end_move # ... and we skip moving - -do_move0: - movw $0x100, %ax # start of destination segment - movw %cs, %bp # aka SETUPSEG - subw $DELTA_INITSEG, %bp # aka INITSEG - movw %cs:start_sys_seg, %bx # start of source segment - cld -do_move: - movw %ax, %es # destination segment - incb %ah # instead of add ax,#0x100 - movw %bx, %ds # source segment - addw $0x100, %bx - subw %di, %di - subw %si, %si - movw $0x800, %cx - rep - movsw - cmpw %bp, %bx # assume start_sys_seg > 0x200, - # so we will perhaps read one - # page more than needed, but - # never overwrite INITSEG - # because destination is a - # minimum one page below source - jb do_move - -end_move: -# then we load the segment descriptors - movw %cs, %ax # aka SETUPSEG - movw %ax, %ds - -# Check whether we need to be downward compatible with version <=201 - cmpl $0, cmd_line_ptr - jne end_move_self # loader uses version >=202 features - cmpb $0x20, type_of_loader - je end_move_self # bootsect loader, we know of it - -# Boot loader does not support boot protocol version 2.02. -# If we have our code not at 0x90000, we need to move it there now. -# We also then need to move the params behind it (commandline) -# Because we would overwrite the code on the current IP, we move -# it in two steps, jumping high after the first one. - movw %cs, %ax - cmpw $SETUPSEG, %ax - je end_move_self - - cli # make sure we really have - # interrupts disabled ! - # because after this the stack - # should not be used - subw $DELTA_INITSEG, %ax # aka INITSEG - movw %ss, %dx - cmpw %ax, %dx - jb move_self_1 - - addw $INITSEG, %dx - subw %ax, %dx # this will go into %ss after - # the move -move_self_1: - movw %ax, %ds - movw $INITSEG, %ax # real INITSEG - movw %ax, %es - movw %cs:setup_move_size, %cx - std # we have to move up, so we use - # direction down because the - # areas may overlap - movw %cx, %di - decw %di - movw %di, %si - subw $move_self_here+0x200, %cx - rep - movsb - ljmp $SETUPSEG, $move_self_here - -move_self_here: - movw $move_self_here+0x200, %cx - rep - movsb - movw $SETUPSEG, %ax - movw %ax, %ds - movw %dx, %ss - -end_move_self: # now we are at the right place - lidt idt_48 # load idt with 0,0 - xorl %eax, %eax # Compute gdt_base - movw %ds, %ax # (Convert %ds:gdt to a linear ptr) - shll $4, %eax - addl $gdt, %eax - movl %eax, (gdt_48+2) - lgdt gdt_48 # load gdt with whatever is - # appropriate - -# that was painless, now we enable A20 - - outb %al, $0xf2 # A20 on - movb $0x02, %al - outb %al, $0xf6 # also A20 on; making ITF's - # way our model - - # PC-9800 seems to enable A20 at the moment of `outb'; - # so we don't wait unlike IBM PCs (see ../setup.S). - -# enable DMA to access memory over 0x100000 (1MB). - - movw $0x439, %dx - inb %dx, %al - andb $(~4), %al - outb %al, %dx - -# Set DMA to increment its bank address automatically at 16MB boundary. -# Initial setting is 64KB boundary mode so that we can't run DMA crossing -# physical address 0xXXXXFFFF. - - movb $0x0c, %al - outb %al, $0x29 # ch. 0 - movb $0x0d, %al - outb %al, $0x29 # ch. 1 - movb $0x0e, %al - outb %al, $0x29 # ch. 2 - movb $0x0f, %al - outb %al, $0x29 # ch. 3 - movb $0x50, %al - outb %al, $0x11 # reinitialize DMAC - -# make sure any possible coprocessor is properly reset.. - movb $0, %al - outb %al, $0xf8 - outb %al, $0x5f # delay - -# well, that went ok, I hope. Now we mask all interrupts - the rest -# is done in init_IRQ(). - movb $0xFF, %al # mask all interrupts for now - outb %al, $0x0A - outb %al, $0x5f # delay - - movb $0x7F, %al # mask all irq's but irq7 which - outb %al, $0x02 # is cascaded - -# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't -# need no steenking BIOS anyway (except for the initial loading :-). -# The BIOS-routine wants lots of unnecessary data, and it's less -# "interesting" anyway. This is how REAL programmers do it. -# -# Well, now's the time to actually move into protected mode. To make -# things as simple as possible, we do no register set-up or anything, -# we let the gnu-compiled 32-bit programs do that. We just jump to -# absolute address 0x1000 (or the loader supplied one), -# in 32-bit protected mode. -# -# Note that the short jump isn't strictly needed, although there are -# reasons why it might be a good idea. It won't hurt in any case. - movw $1, %ax # protected mode (PE) bit - lmsw %ax # This is it! - jmp flush_instr - -flush_instr: - xorw %bx, %bx # Flag to indicate a boot - xorl %esi, %esi # Pointer to real-mode code - movw %cs, %si - subw $DELTA_INITSEG, %si - shll $4, %esi # Convert to 32-bit pointer -# NOTE: For high loaded big kernels we need a -# jmpi 0x100000,__BOOT_CS -# -# but we yet haven't reloaded the CS register, so the default size -# of the target offset still is 16 bit. -# However, using an operand prefix (0x66), the CPU will properly -# take our 48 bit far pointer. (INTeL 80386 Programmer's Reference -# Manual, Mixing 16-bit and 32-bit code, page 16-6) - - .byte 0x66, 0xea # prefix + jmpi-opcode -code32: .long 0x1000 # will be set to 0x100000 - # for big kernels - .word __BOOT_CS - -# Here's a bunch of information about your current kernel.. -kernel_version: .ascii UTS_RELEASE - .ascii " (" - .ascii LINUX_COMPILE_BY - .ascii "@" - .ascii LINUX_COMPILE_HOST - .ascii ") " - .ascii UTS_VERSION - .byte 0 - -# This is the default real mode switch routine. -# to be called just before protected mode transition -default_switch: - cli # no interrupts allowed ! - outb %al, $0x50 # disable NMI for bootup - # sequence - lret - - -# This routine prints one character (in %al) on console. -# PC-9800 doesn't have BIOS-function to do it like IBM PC's INT 10h - 0Eh, -# so we hardcode `prtchr' subroutine here. -prtchr: - pushaw - pushw %es - cmpb $0, %cs:prtchr_initialized - jnz prtchr_ok - xorw %cx, %cx - movw %cx, %es - testb $0x8, %es:BIOS_FLAG - jz 1f - movb $(HIRESO_TEXT >> 8), %cs:cursor_address+3 - movw $(80 * 31 * 2), %cs:max_cursor_offset -1: pushw %ax - call get_cursor_position - movw %ax, %cs:cursor_address - popw %ax - movb $1, %cs:prtchr_initialized -prtchr_ok: - lesw %cs:cursor_address, %di - movw $160, %bx - movb $0, %ah - cmpb $13, %al - je do_cr - cmpb $10, %al - je do_lf - - # normal (printable) character - stosw - movb $0xe1, %es:0x2000-2(%di) - jmp 1f - -do_cr: movw %di, %ax - divb %bl # %al = Y, %ah = X * 2 - mulb %bl - movw %ax, %dx - jmp 2f - -do_lf: addw %bx, %di -1: movw %cs:max_cursor_offset, %cx - cmpw %cx, %di - movw %di, %dx - jb 2f - # cursor reaches bottom of screen; scroll it - subw %bx, %dx - xorw %di, %di - movw %bx, %si - cld - subw %bx, %cx - shrw %cx - pushw %cx - rep; es; movsw - movb $32, %al # clear bottom line characters - movb $80, %cl - rep; stosw - movw $0x2000, %di - popw %cx - leaw (%bx,%di), %si - rep; es; movsw - movb $0xe1, %al # clear bottom line attributes - movb $80, %cl - rep; stosw -2: movw %dx, %cs:cursor_address - movb $0x13, %ah # move cursor to right position - int $0x18 - popw %es - popaw - ret - -cursor_address: - .word 0 - .word NORMAL_TEXT -max_cursor_offset: - .word 80 * 25 * 2 # for normal 80x25 mode - -# putstr may called without running through start_of_setup (via bootsect_panic) -# so we should initialize ourselves on demand. -prtchr_initialized: - .byte 0 - -# This routine queries GDC (graphic display controller) for current cursor -# position. Cursor position is returned in %ax (CPU offset address). -get_cursor_position: -1: inb $0x60, %al - outb %al, $0x5f # delay - outb %al, $0x5f # delay - testb $0x04, %al # Is FIFO empty? - jz 1b # no -> wait until empty - - movb $0xe0, %al # CSRR command - outb %al, $0x62 # command write - outb %al, $0x5f # delay - outb %al, $0x5f # delay - -2: inb $0x60, %al - outb %al, $0x5f # delay - outb %al, $0x5f # delay - testb $0x01, %al # Is DATA READY? - jz 2b # no -> wait until ready - - inb $0x62, %al # read xAD (L) - outb %al, $0x5f # delay - outb %al, $0x5f # delay - movb %al, %ah - inb $0x62, %al # read xAD (H) - outb %al, $0x5f # delay - outb %al, $0x5f # delay - xchgb %al, %ah # correct byte order - pushw %ax - inb $0x62, %al # read yAD (L) - outb %al, $0x5f # delay - outb %al, $0x5f # delay - inb $0x62, %al # read yAD (M) - outb %al, $0x5f # delay - outb %al, $0x5f # delay - inb $0x62, %al # read yAD (H) - # yAD is not our interest, - # so discard it. - popw %ax - addw %ax, %ax # convert to CPU address - ret - -# Descriptor tables -# -# NOTE: The intel manual says gdt should be sixteen bytes aligned for -# efficiency reasons. However, there are machines which are known not -# to boot with misaligned GDTs, so alter this at your peril! If you alter -# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two -# empty GDT entries (one for NULL and one reserved). -# -# NOTE: On some CPUs, the GDT must be 8 byte aligned. This is -# true for the Voyager Quad CPU card which will not boot without -# This directive. 16 byte aligment is recommended by intel. -# - .align 16 -gdt: - .fill GDT_ENTRY_BOOT_CS,8,0 - - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9A00 # code read/exec - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) - - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9200 # data read/write - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) -gdt_end: - .align 4 - - .word 0 # alignment byte -idt_48: - .word 0 # idt limit = 0 - .word 0, 0 # idt base = 0L - - .word 0 # alignment byte -gdt_48: - .word gdt_end - gdt - 1 # gdt limit - .word 0, 0 # gdt base (filled in later) - -# Include video setup & detection code - -#include "video.S" - -# Setup signature -- must be last -setup_sig1: .word SIG1 -setup_sig2: .word SIG2 - -# After this point, there is some free space which is used by the video mode -# handling code to store the temporary mode table (not used by the kernel). - -modelist: - -.text -endtext: -.data -enddata: -.bss -endbss: diff -Nru a/arch/i386/boot98/video.S b/arch/i386/boot98/video.S --- a/arch/i386/boot98/video.S 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,262 +0,0 @@ -/* video.S - * - * Video mode setup, etc. for NEC PC-9800 series. - * - * Copyright (C) 1997,98,99 Linux/98 project - * - * Based on the video.S for IBM PC: - * copyright (C) Martin Mares - */ - -/* Positions of various video parameters passed to the kernel */ -/* (see also include/linux/tty.h) */ -#define PARAM_CURSOR_POS 0x00 -#define PARAM_VIDEO_PAGE 0x04 -#define PARAM_VIDEO_MODE 0x06 -#define PARAM_VIDEO_COLS 0x07 -#define PARAM_VIDEO_EGA_BX 0x0a -#define PARAM_VIDEO_LINES 0x0e -#define PARAM_HAVE_VGA 0x0f -#define PARAM_FONT_POINTS 0x10 - -#define PARAM_VIDEO98_COMPAT 0x0a -#define PARAM_VIDEO98_HIRESO 0x0b -#define PARAM_VIDEO98_MACHTYPE 0x0c -#define PARAM_VIDEO98_LINES 0x0e -#define PARAM_VIDEO98_COLS 0x0f - -# PARAM_LFB_* and PARAM_VESAPM_* are unused on PC-9800. - -# This is the main entry point called by setup.S -# %ds *must* be pointing to the bootsector -video: xorw %ax, %ax - movw %ax, %es # %es = 0 - - movb %es:BIOS_FLAG, %al - movb %al, PARAM_VIDEO_MODE - - movb $0, PARAM_VIDEO98_HIRESO # 0 = normal - movw $NORMAL_TEXT, PARAM_VIDEO_PAGE - testb $0x8, %al - movw $(80 * 256 + 25), %ax - jz 1f - # hireso machine. - movb $1, PARAM_VIDEO98_HIRESO # !0 = hi-reso - movb $(HIRESO_TEXT >> 8), PARAM_VIDEO_PAGE + 1 - movw $(80 * 256 + 31), %ax -1: movw %ax, PARAM_VIDEO98_LINES # also sets VIDEO98_COLS - - movb $0xc0, %ch # 400-line graphic mode - movb $0x42, %ah - int $0x18 - - movw $80, PARAM_VIDEO_COLS - - movw $msg_probing, %si - call prtstr_cs - -# Check vendor from font pattern of `A'... - -1: inb $0x60, %al # wait V-sync - testb $0x20, %al - jnz 1b -2: inb $0x60, %al - testb $0x20, %al - jz 2b - - movb $0x00, %al # select font of `A' - outb %al, $0xa1 - movb $0x41, %al - outb %al, $0xa3 - - movw $8, %cx - movw PARAM_VIDEO_PAGE, %ax - cmpw $NORMAL_TEXT, %ax - je 3f - movb $24, %cl # for hi-reso machine -3: addw $0x400, %ax # %ax = CG window segment - pushw %ds - movw %ax, %ds - xorw %dx, %dx # get sum of `A' pattern... - xorw %si, %si -4: lodsw - addw %ax, %dx - loop 4b - popw %ds - - movw %dx, %ax - movw $msg_nec, %si - xorw %bx, %bx # vendor info will go into %bx - testb $8, %es:BIOS_FLAG - jnz check_hireso_vendor - cmpw $0xc7f8, %ax - je 5f - jmp 6f -check_hireso_vendor: - cmpw $0x9639, %ax # XXX: NOT VERIFIED!!! - je 5f -6: incw %bx # compatible machine - movw $msg_compat, %si -5: movb %bl, PARAM_VIDEO98_COMPAT - call prtstr_cs - - movw $msg_fontdata, %si - call prtstr_cs # " (CG sum of A = 0x" - movw %dx, %ax - call prthex - call prtstr_cs # ") PC-98" - - movb $'0', %al - pushw %ds - pushw $0xf8e8 - popw %ds - cmpw $0x2198, (0) - popw %ds - jne 7f - movb $'2', %al -7: call prtchr - call prtstr_cs # "1 " - - movb $0, PARAM_VIDEO98_MACHTYPE -#if 0 /* XXX - This check is bogus? [0000:BIOS_FLAG2]-bit7 does NOT - indicate whether it is a note machine, but merely indicates - whether it has ``RAM drive''. */ -# check note machine - testb $0x80, %es:BIOS_FLAG2 - jnz is_note - pushw %ds - pushw $0xfd80 - popw %ds - movb (4), %al - popw %ds - cmpb $0x20, %al # EPSON note A - je epson_note - cmpb $0x22, %al # EPSON note W - je epson_note - cmpb $0x27, %al # EPSON note AE - je epson_note - cmpb $0x2a, %al # EPSON note WR - jne note_done -epson_note: - movb $1, PARAM_VIDEO98_MACHTYPE - movw $msg_note, %si - call prtstr_cs -note_done: -#endif - -# print h98 ? (only NEC) - cmpb $0, PARAM_VIDEO98_COMPAT - jnz 8f # not NEC -> not H98 - - testb $0x80, %es:BIOS_FLAG5 - jz 8f # have NESA bus -> H98 - movw $msg_h98, %si - call prtstr_cs - orb $2, PARAM_VIDEO98_MACHTYPE -8: testb $0x40, %es:BIOS_FLAG5 - jz 9f - movw $msg_gs, %si - call prtstr_cs # only prints it :-) -9: - movw $msg_normal, %si # "normal" - testb $0x8, %es:BIOS_FLAG - jz 1f - movw $msg_hireso, %si -1: call prtstr_cs - - movw $msg_sysclk, %si - call prtstr_cs - movb $'5', %al - testb $0x80, %es:BIOS_FLAG - jz 2f - movb $'8', %al -2: call prtchr - call prtstr_cs - -#if 0 - testb $0x40, %es:(0x45c) - jz no_30line # no 30-line support - - movb %es:KB_SHFT_STS, %al - testb $0x01, %al # is SHIFT key pressed? - jz no_30line - - testb $0x10, %al # is CTRL key pressed? - jnz line40 - - # switch to 30-line mode - movb $30, PARAM_VIDEO98_LINES - movw $msg_30line, %si - jmp 3f - -line40: - movb $37, PARAM_VIDEO98_LINES - movw $40, PARAM_VIDEO_LINES - movw $msg_40line, %si -3: call prtstr_cs - - movb $0x32, %bh - movw $0x300c, %ax - int $0x18 # switch video mode - movb $0x0c, %ah - int $0x18 # turn on text plane - movw %cs:cursor_address, %dx - movb $0x13, %ah - int $0x18 # move cursor to correct place - mov $0x11, %ah - int $0x18 # turn on text plane - - call prtstr_cs # "Ok.\r\n" -no_30line: -#endif - ret - -prtstr_cs: - pushw %ds - pushw %cs - popw %ds - call prtstr - popw %ds - ret - -# prthex is for debugging purposes, and prints %ax in hexadecimal. -prthex: pushw %cx - movw $4, %cx -1: rolw $4, %ax - pushw %ax - andb $0xf, %al - cmpb $10, %al - sbbb $0x69, %al - das - call prtchr - popw %ax - loop 1b - popw %cx - ret - -msg_probing: .string "Probing machine: " - -msg_nec: .string "NEC" -msg_compat: .string "compatible" - -msg_fontdata: .string " (CG sum of A = 0x" - .string ") PC-98" - .string "1 " - -msg_gs: .string "(GS) " -msg_h98: .string "(H98) " - -msg_normal: .string "normal" -msg_hireso: .string "Hi-reso" - -msg_sysclk: .string " mode, system clock " - .string "MHz\r\n" - -#if 0 -msg_40line: # cpp will concat following lines, so the assembler can deal. - .ascii "\ -Video mode will be adjusted to 37-line (so-called ``40-line'') mode later.\r\n\ -THIS MODE MAY DAMAGE YOUR MONITOR PHYSICALLY. USE AT YOUR OWN RISK.\r\n" -msg_30line: .string "Switching video mode to 30-line (640x480) mode... " - .string "Ok.\r\n" -#endif diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile 2004-06-26 17:09:16 -07:00 +++ b/arch/i386/kernel/Makefile 2004-06-26 17:09:16 -07:00 @@ -31,7 +31,6 @@ obj-$(CONFIG_HPET_TIMER) += time_hpet.o obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_X86_STD_RESOURCES) += std_resources.o EXTRA_AFLAGS := -traditional diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/kernel/acpi/boot.c 2004-06-26 17:09:20 -07:00 @@ -28,7 +28,9 @@ #include #include #include -#include +#include + +#include #include #include #include @@ -436,6 +438,38 @@ *irq = gsi; return 0; } + +unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) +{ + unsigned int irq; + +#ifdef CONFIG_PCI + /* + * Make sure all (legacy) PCI IRQs are set as level-triggered. + */ + if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { + static u16 irq_mask; + extern void eisa_set_level_irq(unsigned int irq); + + if (edge_level == ACPI_LEVEL_SENSITIVE) { + if ((gsi < 16) && !((1 << gsi) & irq_mask)) { + Dprintk(KERN_DEBUG PREFIX "Setting GSI %u as level-triggered\n", gsi); + irq_mask |= (1 << gsi); + eisa_set_level_irq(gsi); + } + } + } +#endif + +#ifdef CONFIG_X86_IO_APIC + if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { + mp_register_gsi(gsi, edge_level, active_high_low); + } +#endif + acpi_gsi_to_irq(gsi, &irq); + return irq; +} +EXPORT_SYMBOL(acpi_register_gsi); static unsigned long __init acpi_scan_rsdp ( diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c --- a/arch/i386/kernel/apic.c 2004-06-26 17:09:21 -07:00 +++ b/arch/i386/kernel/apic.c 2004-06-26 17:09:21 -07:00 @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -79,6 +78,17 @@ if (!APIC_INTEGRATED(ver)) /* 82489DX */ v |= APIC_LVT_LEVEL_TRIGGER; apic_write_around(APIC_LVT0, v); +} + +int get_physical_broadcast(void) +{ + unsigned int lvr, version; + lvr = apic_read(APIC_LVR); + version = GET_APIC_VERSION(lvr); + if (version >= 0x14) + return 0xff; + else + return 0xf; } int get_maxlvt(void) diff -Nru a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c --- a/arch/i386/kernel/cpu/common.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/kernel/cpu/common.c 2004-06-26 17:09:15 -07:00 @@ -473,7 +473,6 @@ void __init early_cpu_init(void) { - early_cpu_detect(); intel_cpu_init(); cyrix_init_cpu(); nsc_init_cpu(); @@ -483,6 +482,7 @@ rise_init_cpu(); nexgen_init_cpu(); umc_init_cpu(); + early_cpu_detect(); #ifdef CONFIG_DEBUG_PAGEALLOC /* pse is not compatible with on-the-fly unmapping, diff -Nru a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c --- a/arch/i386/kernel/cpuid.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/kernel/cpuid.c 2004-06-26 17:09:15 -07:00 @@ -36,12 +36,17 @@ #include #include #include +#include +#include +#include #include #include #include #include +static struct class_simple *cpuid_class; + #ifdef CONFIG_SMP struct cpuid_command { @@ -153,20 +158,84 @@ .open = cpuid_open, }; +static int cpuid_class_simple_device_add(int i) +{ + int err = 0; + struct class_device *class_err; + + class_err = class_simple_device_add(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i); + if (IS_ERR(class_err)) + err = PTR_ERR(class_err); + return err; +} + +static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + + switch (action) { + case CPU_ONLINE: + cpuid_class_simple_device_add(cpu); + break; + case CPU_DEAD: + class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu)); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block cpuid_class_cpu_notifier = +{ + .notifier_call = cpuid_class_cpu_callback, +}; + int __init cpuid_init(void) { + int i, err = 0; + i = 0; + if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) { printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n", CPUID_MAJOR); - return -EBUSY; + err = -EBUSY; + goto out; + } + cpuid_class = class_simple_create(THIS_MODULE, "cpuid"); + if (IS_ERR(cpuid_class)) { + err = PTR_ERR(cpuid_class); + goto out_chrdev; } + for_each_online_cpu(i) { + err = cpuid_class_simple_device_add(i); + if (err != 0) + goto out_class; + } + register_cpu_notifier(&cpuid_class_cpu_notifier); - return 0; + err = 0; + goto out; + +out_class: + i = 0; + for_each_online_cpu(i) { + class_simple_device_remove(MKDEV(CPUID_MAJOR, i)); + } + class_simple_destroy(cpuid_class); +out_chrdev: + unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); +out: + return err; } void __exit cpuid_exit(void) { + int cpu = 0; + + for_each_online_cpu(cpu) + class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu)); + class_simple_destroy(cpuid_class); unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); + unregister_cpu_notifier(&cpuid_class_cpu_notifier); } module_init(cpuid_init); diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c --- a/arch/i386/kernel/dmi_scan.c 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/kernel/dmi_scan.c 2004-06-26 17:09:17 -07:00 @@ -10,6 +10,7 @@ #include #include #include +#include #include unsigned long dmi_broken; @@ -139,21 +140,6 @@ return -1; } - -enum -{ - DMI_BIOS_VENDOR, - DMI_BIOS_VERSION, - DMI_BIOS_DATE, - DMI_SYS_VENDOR, - DMI_PRODUCT_NAME, - DMI_PRODUCT_VERSION, - DMI_BOARD_VENDOR, - DMI_BOARD_NAME, - DMI_BOARD_VERSION, - DMI_STRING_MAX -}; - static char *dmi_ident[DMI_STRING_MAX]; /* @@ -176,26 +162,11 @@ } /* - * DMI callbacks for problem boards + * Ugly compatibility crap. */ - -struct dmi_strmatch -{ - u8 slot; - char *substr; -}; - -#define NONE 255 - -struct dmi_blacklist -{ - int (*callback)(struct dmi_blacklist *); - char *ident; - struct dmi_strmatch matches[4]; -}; - -#define NO_MATCH { NONE, NULL} -#define MATCH(a,b) { a, b } +#define dmi_blacklist dmi_system_id +#define NO_MATCH { DMI_NONE, NULL} +#define MATCH DMI_MATCH /* * Reboot options and system auto-detection code provided by @@ -343,16 +314,15 @@ } /* - * Work around broken HP Pavilion Notebooks which assign USB to - * IRQ 9 even though it is actually wired to IRQ 11 + * Work around broken Acer TravelMate 360 Notebooks which assign Cardbus to + * IRQ 11 even though it is actually wired to IRQ 10 */ -static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d) +static __init int fix_acer_tm360_irqrouting(struct dmi_blacklist *d) { #ifdef CONFIG_PCI - extern int broken_hp_bios_irq9; - if (broken_hp_bios_irq9 == 0) - { - broken_hp_bios_irq9 = 1; + extern int acer_tm360_irqrouting; + if (acer_tm360_irqrouting == 0) { + acer_tm360_irqrouting = 1; printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident); } #endif @@ -546,15 +516,21 @@ #ifdef CONFIG_ACPI_PCI static __init int disable_acpi_irq(struct dmi_blacklist *d) -{ - printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", d->ident); - acpi_noirq_set(); +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", + d->ident); + acpi_noirq_set(); + } return 0; } static __init int disable_acpi_pci(struct dmi_blacklist *d) -{ - printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident); - acpi_disable_pci(); +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", + d->ident); + acpi_disable_pci(); + } return 0; } #endif @@ -839,13 +815,12 @@ NO_MATCH, NO_MATCH } }, - { fix_broken_hp_bios_irq9, "HP Pavilion N5400 Series Laptop", { - MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - MATCH(DMI_BIOS_VERSION, "GE.M1.03"), - MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"), - MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736") + + { fix_acer_tm360_irqrouting, "Acer TravelMate 36x Laptop", { + MATCH(DMI_SYS_VENDOR, "Acer"), + MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), + NO_MATCH, NO_MATCH } }, - /* * Generic per vendor APM settings @@ -1034,6 +1009,13 @@ MATCH(DMI_BOARD_NAME, "PR-DLS"), MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"), MATCH(DMI_BIOS_DATE, "03/21/2003") }}, + + { disable_acpi_pci, "Acer TravelMate 36x Laptop", { + MATCH(DMI_SYS_VENDOR, "Acer"), + MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), + NO_MATCH, NO_MATCH + } }, + #endif { NULL, } @@ -1048,9 +1030,6 @@ static __init void dmi_check_blacklist(void) { - struct dmi_blacklist *d; - int i; - #ifdef CONFIG_ACPI_BOOT #define ACPI_BLACKLIST_CUTOFF_YEAR 2001 @@ -1072,25 +1051,7 @@ } } #endif - - d=&dmi_blacklist[0]; - while(d->callback) - { - for(i=0;i<4;i++) - { - int s = d->matches[i].slot; - if(s==NONE) - continue; - if(dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) - continue; - /* No match */ - goto fail; - } - if(d->callback(d)) - return; -fail: - d++; - } + dmi_check_system(dmi_blacklist); } @@ -1157,3 +1118,52 @@ } EXPORT_SYMBOL(is_unsafe_smbus); + + +/** + * dmi_check_system - check system DMI data + * @list: array of dmi_system_id structures to match against + * + * Walk the blacklist table running matching functions until someone + * returns non zero or we hit the end. Callback function is called for + * each successfull match. Returns the number of matches. + */ +int dmi_check_system(struct dmi_system_id *list) +{ + int i, count = 0; + struct dmi_system_id *d = list; + + while (d->ident) { + for (i = 0; i < ARRAY_SIZE(d->matches); i++) { + int s = d->matches[i].slot; + if (s == DMI_NONE) + continue; + if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) + continue; + /* No match */ + goto fail; + } + if (d->callback && d->callback(d)) + break; + count++; +fail: d++; + } + + return count; +} + +EXPORT_SYMBOL(dmi_check_system); + +/** + * dmi_get_system_info - return DMI data value + * @field: data index (see enum dmi_filed) + * + * Returns one DMI data value, can be used to perform + * complex DMI data checks. + */ +char * dmi_get_system_info(int field) +{ + return dmi_ident[field]; +} + +EXPORT_SYMBOL(dmi_get_system_info); diff -Nru a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c --- a/arch/i386/kernel/efi.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/kernel/efi.c 2004-06-26 17:09:19 -07:00 @@ -37,7 +37,6 @@ #include #include #include -#include #include #define EFI_DEBUG 0 diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c --- a/arch/i386/kernel/i386_ksyms.c 2004-06-26 17:09:21 -07:00 +++ b/arch/i386/kernel/i386_ksyms.c 2004-06-26 17:09:21 -07:00 @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c --- a/arch/i386/kernel/i8259.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/kernel/i8259.c 2004-06-26 17:09:20 -07:00 @@ -317,16 +317,11 @@ * be shot. */ -/* - * =PC9800NOTE= In NEC PC-9800, we use irq8 instead of irq13! - */ static irqreturn_t math_error_irq(int cpl, void *dev_id, struct pt_regs *regs) { extern void math_error(void *); -#ifndef CONFIG_X86_PC9800 outb(0,0xF0); -#endif if (ignore_fpu_irq || !boot_cpu_data.hard_math) return IRQ_NONE; math_error((void *)regs->eip); @@ -337,7 +332,7 @@ * New motherboards sometimes make IRQ 13 be a PCI interrupt, * so allow interrupt sharing. */ -static struct irqaction fpu_irq = { math_error_irq, 0, 0, "fpu", NULL, NULL }; +static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL }; void __init init_ISA_irqs (void) { diff -Nru a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c --- a/arch/i386/kernel/init_task.c 2004-06-26 17:09:21 -07:00 +++ b/arch/i386/kernel/init_task.c 2004-06-26 17:09:21 -07:00 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/kernel/io_apic.c 2004-06-26 17:09:17 -07:00 @@ -41,10 +41,6 @@ #include "io_ports.h" -#undef APIC_LOCKUP_DEBUG - -#define APIC_LOCKUP_DEBUG - static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED; /* @@ -127,83 +123,47 @@ } } -/* mask = 1 */ -static void __mask_IO_APIC_irq (unsigned int irq) +static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable) { - int pin; struct irq_pin_list *entry = irq_2_pin + irq; + unsigned int pin, reg; for (;;) { - unsigned int reg; pin = entry->pin; if (pin == -1) break; reg = io_apic_read(entry->apic, 0x10 + pin*2); - io_apic_modify(entry->apic, 0x10 + pin*2, reg |= 0x00010000); + reg &= ~disable; + reg |= enable; + io_apic_modify(entry->apic, 0x10 + pin*2, reg); if (!entry->next) break; entry = irq_2_pin + entry->next; } - io_apic_sync(entry->apic); +} + +/* mask = 1 */ +static void __mask_IO_APIC_irq (unsigned int irq) +{ + __modify_IO_APIC_irq(irq, 0x00010000, 0); } /* mask = 0 */ static void __unmask_IO_APIC_irq (unsigned int irq) { - int pin; - struct irq_pin_list *entry = irq_2_pin + irq; - - for (;;) { - unsigned int reg; - pin = entry->pin; - if (pin == -1) - break; - reg = io_apic_read(entry->apic, 0x10 + pin*2); - io_apic_modify(entry->apic, 0x10 + pin*2, reg &= 0xfffeffff); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } + __modify_IO_APIC_irq(irq, 0, 0x00010000); } /* mask = 1, trigger = 0 */ static void __mask_and_edge_IO_APIC_irq (unsigned int irq) { - int pin; - struct irq_pin_list *entry = irq_2_pin + irq; - - for (;;) { - unsigned int reg; - pin = entry->pin; - if (pin == -1) - break; - reg = io_apic_read(entry->apic, 0x10 + pin*2); - reg = (reg & 0xffff7fff) | 0x00010000; - io_apic_modify(entry->apic, 0x10 + pin*2, reg); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } + __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); } /* mask = 0, trigger = 1 */ static void __unmask_and_level_IO_APIC_irq (unsigned int irq) { - int pin; - struct irq_pin_list *entry = irq_2_pin + irq; - - for (;;) { - unsigned int reg; - pin = entry->pin; - if (pin == -1) - break; - reg = io_apic_read(entry->apic, 0x10 + pin*2); - reg = (reg & 0xfffeffff) | 0x00008000; - io_apic_modify(entry->apic, 0x10 + pin*2, reg); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } + __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); } static void mask_IO_APIC_irq (unsigned int irq) @@ -264,7 +224,7 @@ struct irq_pin_list *entry = irq_2_pin + irq; unsigned int apicid_value; - apicid_value = cpu_mask_to_apicid(mk_cpumask_const(cpumask)); + apicid_value = cpu_mask_to_apicid(cpumask); /* Prepare to do the io_apic_write */ apicid_value = apicid_value << 24; spin_lock_irqsave(&ioapic_lock, flags); @@ -595,7 +555,7 @@ return; } -int balanced_irq(void *unused) +static int balanced_irq(void *unused) { int i; unsigned long prev_balance_time = jiffies; @@ -608,17 +568,17 @@ pending_irq_balance_cpumask[i] = cpumask_of_cpu(0); } -repeat: - set_current_state(TASK_INTERRUPTIBLE); - time_remaining = schedule_timeout(time_remaining); - if (time_after(jiffies, prev_balance_time+balanced_irq_interval)) { - Dprintk("balanced_irq: calling do_irq_balance() %lu\n", - jiffies); - do_irq_balance(); - prev_balance_time = jiffies; - time_remaining = balanced_irq_interval; + for ( ; ; ) { + set_current_state(TASK_INTERRUPTIBLE); + time_remaining = schedule_timeout(time_remaining); + if (time_after(jiffies, + prev_balance_time+balanced_irq_interval)) { + do_irq_balance(); + prev_balance_time = jiffies; + time_remaining = balanced_irq_interval; + } } - goto repeat; + return 0; } static int __init balanced_irq_init(void) @@ -1366,7 +1326,7 @@ printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); - if (reg_00.bits.ID >= APIC_BROADCAST_ID) + if (reg_00.bits.ID >= get_physical_broadcast()) UNEXPECTED_IO_APIC(); if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) UNEXPECTED_IO_APIC(); @@ -1451,12 +1411,17 @@ ); } } + if (use_pci_vector()) + printk(KERN_INFO "Using vector-based indexing\n"); printk(KERN_DEBUG "IRQ to pin mappings:\n"); for (i = 0; i < NR_IRQS; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; - printk(KERN_DEBUG "IRQ%d ", i); + if (use_pci_vector() && !platform_legacy_irq(i)) + printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); + else + printk(KERN_DEBUG "IRQ%d ", i); for (;;) { printk("-> %d:%d", entry->apic, entry->pin); if (!entry->next) @@ -1682,7 +1647,7 @@ old_id = mp_ioapics[apic].mpc_apicid; - if (mp_ioapics[apic].mpc_apicid >= APIC_BROADCAST_ID) { + if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", apic, mp_ioapics[apic].mpc_apicid); printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", @@ -1703,10 +1668,10 @@ mp_ioapics[apic].mpc_apicid)) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", apic, mp_ioapics[apic].mpc_apicid); - for (i = 0; i < APIC_BROADCAST_ID; i++) + for (i = 0; i < get_physical_broadcast(); i++) if (!physid_isset(i, phys_id_present_map)) break; - if (i >= APIC_BROADCAST_ID) + if (i >= get_physical_broadcast()) panic("Max APIC ID exceeded!\n"); printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", i); @@ -1893,30 +1858,11 @@ ack_APIC_irq(); if (!(v & (1 << (i & 0x1f)))) { -#ifdef APIC_LOCKUP_DEBUG - struct irq_pin_list *entry; -#endif - #ifdef APIC_MISMATCH_DEBUG atomic_inc(&irq_mis_count); #endif spin_lock(&ioapic_lock); __mask_and_edge_IO_APIC_irq(irq); -#ifdef APIC_LOCKUP_DEBUG - for (entry = irq_2_pin + irq;;) { - unsigned int reg; - - if (entry->pin == -1) - break; - reg = io_apic_read(entry->apic, 0x10 + entry->pin * 2); - if (reg & 0x00004000) - printk(KERN_CRIT "Aieee!!! Remote IRR" - " still set after unlock!\n"); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } -#endif __unmask_and_level_IO_APIC_irq(irq); spin_unlock(&ioapic_lock); } @@ -2322,8 +2268,6 @@ #ifdef CONFIG_ACPI_BOOT -#define IO_APIC_MAX_ID APIC_BROADCAST_ID - int __init io_apic_get_unique_id (int ioapic, int apic_id) { union IO_APIC_reg_00 reg_00; @@ -2348,7 +2292,7 @@ reg_00.raw = io_apic_read(ioapic, 0); spin_unlock_irqrestore(&ioapic_lock, flags); - if (apic_id >= IO_APIC_MAX_ID) { + if (apic_id >= get_physical_broadcast()) { printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " "%d\n", ioapic, apic_id, reg_00.bits.ID); apic_id = reg_00.bits.ID; @@ -2360,12 +2304,12 @@ */ if (check_apicid_used(apic_id_map, apic_id)) { - for (i = 0; i < IO_APIC_MAX_ID; i++) { + for (i = 0; i < get_physical_broadcast(); i++) { if (!check_apicid_used(apic_id_map, i)) break; } - if (i == IO_APIC_MAX_ID) + if (i == get_physical_broadcast()) panic("Max apic_id exceeded!\n"); printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c --- a/arch/i386/kernel/irq.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/kernel/irq.c 2004-06-26 17:09:15 -07:00 @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -653,7 +652,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c --- a/arch/i386/kernel/mpparse.c 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/kernel/mpparse.c 2004-06-26 17:09:17 -07:00 @@ -23,12 +23,12 @@ #include #include #include +#include #include #include #include #include -#include #include #include @@ -104,6 +104,21 @@ static int mpc_record; static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; +#ifdef CONFIG_X86_NUMAQ +static int MP_valid_apicid(int apicid, int version) +{ + return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; +} +#else +static int MP_valid_apicid(int apicid, int version) +{ + if (version >= 0x14) + return apicid < 0xff; + else + return apicid < 0xf; +} +#endif + void __init MP_processor_info (struct mpc_config_processor *m) { int ver, apicid; @@ -180,14 +195,14 @@ return; } num_processors++; + ver = m->mpc_apicver; - if (MAX_APICS - m->mpc_apicid <= 0) { + if (!MP_valid_apicid(apicid, ver)) { printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", m->mpc_apicid, MAX_APICS); --num_processors; return; } - ver = m->mpc_apicver; tmp = apicid_to_cpu_present(apicid); physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp); @@ -844,7 +859,7 @@ MP_processor_info(&processor); } -#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) +#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT)) #define MP_ISA_BUS 0 #define MP_MAX_IOAPIC_PIN 127 @@ -857,7 +872,7 @@ } mp_ioapic_routing[MAX_IO_APICS]; -static int __init mp_find_ioapic ( +static int mp_find_ioapic ( int gsi) { int i = 0; @@ -1000,14 +1015,23 @@ for (i = 0; i < 16; i++) { int idx; - for (idx = 0; idx < mp_irq_entries; idx++) - if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS && - (mp_irqs[idx].mpc_srcbusirq == i || - mp_irqs[idx].mpc_dstirq == i)) - break; + for (idx = 0; idx < mp_irq_entries; idx++) { + struct mpc_config_intsrc *irq = mp_irqs + idx; - if (idx != mp_irq_entries) - continue; /* IRQ already used */ + /* Do we already have a mapping for this ISA IRQ? */ + if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i) + break; + + /* Do we already have a mapping for this IOAPIC pin */ + if ((irq->mpc_dstapic == intsrc.mpc_dstapic) && + (irq->mpc_dstirq == i)) + break; + } + + if (idx != mp_irq_entries) { + printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i); + continue; /* IRQ already used */ + } intsrc.mpc_irqtype = mp_INT; intsrc.mpc_srcbusirq = i; /* Identity mapped */ @@ -1025,96 +1049,56 @@ } } -extern FADT_DESCRIPTOR acpi_fadt; - -#ifdef CONFIG_ACPI_PCI - int (*platform_rename_gsi)(int ioapic, int gsi); -void __init mp_parse_prt (void) +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) { - struct list_head *node = NULL; - struct acpi_prt_entry *entry = NULL; int ioapic = -1; int ioapic_pin = 0; - int gsi = 0; int idx, bit = 0; - int edge_level = 0; - int active_high_low = 0; - /* - * Parsing through the PCI Interrupt Routing Table (PRT) and program - * routing for all entries. - */ - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); +#ifdef CONFIG_ACPI_BUS + /* Don't set up the ACPI SCI because it's already set up */ + if (acpi_fadt.sci_int == gsi) + return; +#endif - /* Need to get gsi for dynamic entry */ - if (entry->link.handle) { - gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); - if (!gsi) - continue; - } - else { - /* Hardwired GSI. Assume PCI standard settings */ - gsi = entry->link.index; - edge_level = 1; - active_high_low = 1; - } + ioapic = mp_find_ioapic(gsi); + if (ioapic < 0) { + printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); + return; + } - /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_fadt.sci_int == gsi) { - /* we still need to set entry's irq */ - acpi_gsi_to_irq(gsi, &entry->irq); - continue; - } - - ioapic = mp_find_ioapic(gsi); - if (ioapic < 0) - continue; - ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; - - if (platform_rename_gsi) - gsi = platform_rename_gsi(ioapic, gsi); - - /* - * Avoid pin reprogramming. PRTs typically include entries - * with redundant pin->gsi mappings (but unique PCI devices); - * we only only program the IOAPIC on the first. - */ - bit = ioapic_pin % 32; - idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); - if (idx > 3) { - printk(KERN_ERR "Invalid reference to IOAPIC pin " - "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, - ioapic_pin); - continue; - } - if ((1<irq); - continue; - } + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; - mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq); - } - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d %s %s\n", - entry->id.segment, entry->id.bus, - entry->id.device, ('A' + entry->pin), - mp_ioapic_routing[ioapic].apic_id, ioapic_pin, - entry->irq, edge_level ? "level" : "edge", - active_high_low ? "low" : "high"); + /* + * Avoid pin reprogramming. PRTs typically include entries + * with redundant pin->gsi mappings (but unique PCI devices); + * we only program the IOAPIC on the first. + */ + bit = ioapic_pin % 32; + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); + if (idx > 3) { + printk(KERN_ERR "Invalid reference to IOAPIC pin " + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, + ioapic_pin); + return; + } + if ((1< #include #include +#include +#include +#include #include #include #include #include +static struct class_simple *msr_class; + /* Note: "err" is handled in a funny way below. Otherwise one version of gcc or another breaks. */ @@ -255,20 +260,82 @@ .open = msr_open, }; +static int msr_class_simple_device_add(int i) +{ + int err = 0; + struct class_device *class_err; + + class_err = class_simple_device_add(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i); + if (IS_ERR(class_err)) + err = PTR_ERR(class_err); + return err; +} + +static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + + switch (action) { + case CPU_ONLINE: + msr_class_simple_device_add(cpu); + break; + case CPU_DEAD: + class_simple_device_remove(MKDEV(MSR_MAJOR, cpu)); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block msr_class_cpu_notifier = +{ + .notifier_call = msr_class_cpu_callback, +}; + int __init msr_init(void) { + int i, err = 0; + i = 0; + if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) { printk(KERN_ERR "msr: unable to get major %d for msr\n", MSR_MAJOR); - return -EBUSY; + err = -EBUSY; + goto out; + } + msr_class = class_simple_create(THIS_MODULE, "msr"); + if (IS_ERR(msr_class)) { + err = PTR_ERR(msr_class); + goto out_chrdev; } + for_each_online_cpu(i) { + err = msr_class_simple_device_add(i); + if (err != 0) + goto out_class; + } + register_cpu_notifier(&msr_class_cpu_notifier); - return 0; + err = 0; + goto out; + +out_class: + i = 0; + for_each_online_cpu(i) + class_simple_device_remove(MKDEV(MSR_MAJOR, i)); + class_simple_destroy(msr_class); +out_chrdev: + unregister_chrdev(MSR_MAJOR, "cpu/msr"); +out: + return err; } void __exit msr_exit(void) { + int cpu = 0; + for_each_online_cpu(cpu) + class_simple_device_remove(MKDEV(MSR_MAJOR, cpu)); + class_simple_destroy(msr_class); unregister_chrdev(MSR_MAJOR, "cpu/msr"); + unregister_cpu_notifier(&msr_class_cpu_notifier); } module_init(msr_init); diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c 2004-06-26 17:09:18 -07:00 +++ b/arch/i386/kernel/setup.c 2004-06-26 17:09:18 -07:00 @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include "setup_arch_pre.h" /* This value is set up by the early boot code to point to the value @@ -57,8 +57,6 @@ int disable_pse __initdata = 0; -static inline char * __init machine_specific_memory_setup(void); - /* * Machine setup.. */ @@ -129,12 +127,206 @@ #define RAMDISK_LOAD_FLAG 0x4000 static char command_line[COMMAND_LINE_SIZE]; - char saved_command_line[COMMAND_LINE_SIZE]; unsigned char __initdata boot_params[PARAM_SIZE]; -static struct resource code_resource = { "Kernel code", 0x100000, 0 }; -static struct resource data_resource = { "Kernel data", 0, 0 }; +static struct resource data_resource = { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource code_resource = { + .name = "Kernel code", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource system_rom_resource = { + .name = "System ROM", + .start = 0xf0000, + .end = 0xfffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource extension_rom_resource = { + .name = "Extension ROM", + .start = 0xe0000, + .end = 0xeffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource adapter_rom_resources[] = { { + .name = "Adapter ROM", + .start = 0xc8000, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +} }; + +#define ADAPTER_ROM_RESOURCES \ + (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) + +static struct resource video_rom_resource = { + .name = "Video ROM", + .start = 0xc0000, + .end = 0xc7fff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource video_ram_resource = { + .name = "Video RAM area", + .start = 0xa0000, + .end = 0xbffff, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource standard_io_resources[] = { { + .name = "dma1", + .start = 0x0000, + .end = 0x001f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic1", + .start = 0x0020, + .end = 0x0021, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "timer", + .start = 0x0040, + .end = 0x005f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "keyboard", + .start = 0x0060, + .end = 0x006f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma page reg", + .start = 0x0080, + .end = 0x008f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic2", + .start = 0x00a0, + .end = 0x00a1, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma2", + .start = 0x00c0, + .end = 0x00df, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "fpu", + .start = 0x00f0, + .end = 0x00ff, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +} }; + +#define STANDARD_IO_RESOURCES \ + (sizeof standard_io_resources / sizeof standard_io_resources[0]) + +#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) + +static int __init romchecksum(unsigned char *rom, unsigned long length) +{ + unsigned char *p, sum = 0; + + for (p = rom; p < rom + length; p++) + sum += *p; + return sum == 0; +} + +static void __init probe_roms(void) +{ + unsigned long start, length, upper; + unsigned char *rom; + int i; + + /* video rom */ + upper = adapter_rom_resources[0].start; + for (start = video_rom_resource.start; start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + video_rom_resource.start = start; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* if checksum okay, trust length byte */ + if (length && romchecksum(rom, length)) + video_rom_resource.end = start + length - 1; + + request_resource(&iomem_resource, &video_rom_resource); + break; + } + + start = (video_rom_resource.end + 1 + 2047) & ~2047UL; + if (start < upper) + start = upper; + + /* system rom */ + request_resource(&iomem_resource, &system_rom_resource); + upper = system_rom_resource.start; + + /* check for extension rom (ignore length byte!) */ + rom = isa_bus_to_virt(extension_rom_resource.start); + if (romsignature(rom)) { + length = extension_rom_resource.end - extension_rom_resource.start + 1; + if (romchecksum(rom, length)) { + request_resource(&iomem_resource, &extension_rom_resource); + upper = extension_rom_resource.start; + } + } + + /* check for adapter roms on 2k boundaries */ + for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* but accept any length that fits if checksum okay */ + if (!length || start + length > upper || !romchecksum(rom, length)) + continue; + + adapter_rom_resources[i].start = start; + adapter_rom_resources[i].end = start + length - 1; + request_resource(&iomem_resource, &adapter_rom_resources[i]); + + start = adapter_rom_resources[i++].end & ~2047UL; + } +} static void __init limit_regions(unsigned long long size) { @@ -465,14 +657,6 @@ */ #define LOWMEMSIZE() (0x9f000) -static void __init setup_memory_region(void) -{ - char *who = machine_specific_memory_setup(); - printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - print_memory_map(who); -} /* setup_memory_region */ - - static void __init parse_cmdline_early (char ** cmdline_p) { char c = ' ', *to = command_line, *from = saved_command_line; @@ -948,6 +1132,7 @@ static void __init register_memory(unsigned long max_low_pfn) { unsigned long low_mem_size; + int i; if (efi_enabled) efi_initialize_iomem_resources(&code_resource, &data_resource); @@ -955,10 +1140,11 @@ legacy_init_iomem_resources(&code_resource, &data_resource); /* EFI systems may still have VGA */ - request_graphics_resource(); + request_resource(&iomem_resource, &video_ram_resource); /* request I/O space for devices used on all i[345]86 PCs */ - request_standard_io_resources(); + for (i = 0; i < STANDARD_IO_RESOURCES; i++) + request_resource(&ioport_resource, &standard_io_resources[i]); /* Tell the PCI layer not to allocate too close to the RAM area.. */ low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff; @@ -1073,6 +1259,8 @@ __setup("noreplacement", noreplacement_setup); +static char * __init machine_specific_memory_setup(void); + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -1123,8 +1311,10 @@ ARCH_SETUP if (efi_enabled) efi_init(); - else - setup_memory_region(); + else { + printk(KERN_INFO "BIOS-provided physical RAM map:\n"); + print_memory_map(machine_specific_memory_setup()); + } copy_edd(); diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c --- a/arch/i386/kernel/signal.c 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/kernel/signal.c 2004-06-26 17:09:17 -07:00 @@ -56,16 +56,15 @@ } asmlinkage int -sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize) +sys_rt_sigsuspend(struct pt_regs regs) { - struct pt_regs * regs = (struct pt_regs *) &unewset; sigset_t saveset, newset; /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) + if (regs.ecx != sizeof(sigset_t)) return -EINVAL; - if (copy_from_user(&newset, unewset, sizeof(newset))) + if (copy_from_user(&newset, (sigset_t __user *)regs.ebx, sizeof(newset))) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); @@ -75,11 +74,11 @@ recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - regs->eax = -EINTR; + regs.eax = -EINTR; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(regs, &saveset)) + if (do_signal(®s, &saveset)) return -EINTR; } } @@ -117,10 +116,11 @@ } asmlinkage int -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) +sys_sigaltstack(struct pt_regs regs) { - struct pt_regs *regs = (struct pt_regs *) &uss; - return do_sigaltstack(uss, uoss, regs->esp); + const stack_t __user *uss = (const stack_t __user *)regs.ebx; + stack_t __user *uoss = (stack_t __user *)regs.ecx; + return do_sigaltstack(uss, uoss, regs.esp); } diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c --- a/arch/i386/kernel/smp.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/kernel/smp.c 2004-06-26 17:09:15 -07:00 @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -160,7 +159,7 @@ */ inline void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) { - unsigned long mask = cpus_coerce(cpumask); + unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; unsigned long flags; diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c --- a/arch/i386/kernel/smpboot.c 2004-06-26 17:09:18 -07:00 +++ b/arch/i386/kernel/smpboot.c 2004-06-26 17:09:18 -07:00 @@ -47,7 +47,6 @@ #include #include -#include #include #include #include @@ -1193,7 +1192,9 @@ int j; cpumask_t nodemask; struct sched_group *node = &sched_group_nodes[i]; - cpus_and(nodemask, node_to_cpumask(i), cpu_possible_map); + cpumask_t node_cpumask = node_to_cpumask(i); + + cpus_and(nodemask, node_cpumask, cpu_possible_map); if (cpus_empty(nodemask)) continue; @@ -1229,7 +1230,9 @@ for (i = 0; i < MAX_NUMNODES; i++) { struct sched_group *cpu = &sched_group_nodes[i]; cpumask_t nodemask; - cpus_and(nodemask, node_to_cpumask(i), cpu_possible_map); + cpumask_t node_cpumask = node_to_cpumask(i); + + cpus_and(nodemask, node_cpumask, cpu_possible_map); if (cpus_empty(nodemask)) continue; diff -Nru a/arch/i386/kernel/std_resources.c b/arch/i386/kernel/std_resources.c --- a/arch/i386/kernel/std_resources.c 2004-06-26 17:09:18 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,204 +0,0 @@ -/* - * Machine specific resource allocation for generic. - */ - -#include -#include -#include - -#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) - -static struct resource system_rom_resource = { - .name = "System ROM", - .start = 0xf0000, - .end = 0xfffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource extension_rom_resource = { - .name = "Extension ROM", - .start = 0xe0000, - .end = 0xeffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource adapter_rom_resources[] = { { - .name = "Adapter ROM", - .start = 0xc8000, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -} }; - -#define ADAPTER_ROM_RESOURCES \ - (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) - -static struct resource video_rom_resource = { - .name = "Video ROM", - .start = 0xc0000, - .end = 0xc7fff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource vram_resource = { - .name = "Video RAM area", - .start = 0xa0000, - .end = 0xbffff, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource standard_io_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x001f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic1", - .start = 0x0020, - .end = 0x0021, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer", - .start = 0x0040, - .end = 0x005f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0060, - .end = 0x006f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma page reg", - .start = 0x0080, - .end = 0x008f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic2", - .start = 0x00a0, - .end = 0x00a1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "fpu", - .start = 0x00f0, - .end = 0x00ff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -} }; - -#define STANDARD_IO_RESOURCES \ - (sizeof standard_io_resources / sizeof standard_io_resources[0]) - -static int __init checksum(unsigned char *rom, unsigned long length) -{ - unsigned char *p, sum = 0; - - for (p = rom; p < rom + length; p++) - sum += *p; - return sum == 0; -} - -void __init probe_roms(void) -{ - unsigned long start, length, upper; - unsigned char *rom; - int i; - - /* video rom */ - upper = adapter_rom_resources[0].start; - for (start = video_rom_resource.start; start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - video_rom_resource.start = start; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* if checksum okay, trust length byte */ - if (length && checksum(rom, length)) - video_rom_resource.end = start + length - 1; - - request_resource(&iomem_resource, &video_rom_resource); - break; - } - - start = (video_rom_resource.end + 1 + 2047) & ~2047UL; - if (start < upper) - start = upper; - - /* system rom */ - request_resource(&iomem_resource, &system_rom_resource); - upper = system_rom_resource.start; - - /* check for extension rom (ignore length byte!) */ - rom = isa_bus_to_virt(extension_rom_resource.start); - if (romsignature(rom)) { - length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (checksum(rom, length)) { - request_resource(&iomem_resource, &extension_rom_resource); - upper = extension_rom_resource.start; - } - } - - /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !checksum(rom, length)) - continue; - - adapter_rom_resources[i].start = start; - adapter_rom_resources[i].end = start + length - 1; - request_resource(&iomem_resource, &adapter_rom_resources[i]); - - start = adapter_rom_resources[i++].end & ~2047UL; - } -} - -void __init request_graphics_resource(void) -{ - request_resource(&iomem_resource, &vram_resource); -} - -void __init request_standard_io_resources(void) -{ - int i; - - for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, &standard_io_resources[i]); -} diff -Nru a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c --- a/arch/i386/kernel/time_hpet.c 2004-06-26 17:09:16 -07:00 +++ b/arch/i386/kernel/time_hpet.c 2004-06-26 17:09:16 -07:00 @@ -21,6 +21,7 @@ #include #include +#include unsigned long hpet_period; /* fsecs / HPET clock */ unsigned long hpet_tick; /* hpet clks count per tick */ @@ -135,6 +136,51 @@ hpet_writel(cfg, HPET_CFG); use_hpet = 1; + +#ifdef CONFIG_HPET + { + struct hpet_data hd; + unsigned int ntimer; + + memset(&hd, 0, sizeof (hd)); + + ntimer = hpet_readl(HPET_ID); + ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT; + ntimer++; + + /* + * Register with driver. + * Timer0 and Timer1 is used by platform. + */ + hd.hd_address = hpet_virt_address; + hd.hd_nirqs = ntimer; + hd.hd_flags = HPET_DATA_PLATFORM; +#ifndef CONFIG_HPET_EMULATE_RTC + hd.hd_state = 0x1; +#else + hd.hd_state = 0x3; +#endif + hd.hd_irq[0] = HPET_LEGACY_8254; + hd.hd_irq[1] = HPET_LEGACY_RTC; + if (ntimer > 2) { + struct hpet *hpet; + struct hpet_timer *timer; + int i; + + hpet = (struct hpet *) hpet_virt_address; + + for (i = 2, timer = &hpet->hpet_timers[2]; i < ntimer; + timer++, i++) + hd.hd_irq[i] = (timer->hpet_config & + Tn_INT_ROUTE_CNF_MASK) >> + Tn_INT_ROUTE_CNF_SHIFT; + + } + + hpet_alloc(&hd); + } +#endif + #ifdef CONFIG_X86_LOCAL_APIC wait_timer_tick = wait_hpet_tick; #endif diff -Nru a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c --- a/arch/i386/kernel/timers/timer_pm.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/kernel/timers/timer_pm.c 2004-06-26 17:09:15 -07:00 @@ -21,6 +21,14 @@ #include #include +#include +#include "mach_timer.h" + +/* Number of PMTMR ticks expected during calibration run */ +#define PMTMR_TICKS_PER_SEC 3579545 +#define PMTMR_EXPECTED_RATE \ + ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10)) + /* The I/O port the PMTMR resides at. * The location is detected during setup_arch(), @@ -57,6 +65,33 @@ return v2 & ACPI_PM_MASK; } + +/* + * Some boards have the PMTMR running way too fast. We check + * the PMTMR rate against PIT channel 2 to catch these cases. + */ +static int verify_pmtmr_rate(void) +{ + u32 value1, value2; + unsigned long count, delta; + + mach_prepare_counter(); + value1 = read_pmtmr(); + mach_countup(&count); + value2 = read_pmtmr(); + delta = (value2 - value1) & ACPI_PM_MASK; + + /* Check that the PMTMR delta is within 5% of what we expect */ + if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 || + delta > (PMTMR_EXPECTED_RATE * 21) / 20) { + printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE); + return -1; + } + + return 0; +} + + static int init_pmtmr(char* override) { u32 value1, value2; @@ -89,6 +124,9 @@ return -ENODEV; pm_good: + if (verify_pmtmr_rate() != 0) + return -ENODEV; + init_cpu_khz(); return 0; } diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c 2004-06-26 17:09:16 -07:00 +++ b/arch/i386/kernel/traps.c 2004-06-26 17:09:16 -07:00 @@ -47,7 +47,6 @@ #include #include -#include #include #include @@ -163,7 +162,6 @@ break; printk(" =======================\n"); } - printk("\n"); } void show_stack(struct task_struct *task, unsigned long *esp) diff -Nru a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c --- a/arch/i386/kernel/vm86.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/kernel/vm86.c 2004-06-26 17:09:15 -07:00 @@ -44,7 +44,6 @@ #include #include -#include #include #include #include @@ -178,8 +177,9 @@ static int do_vm86_irq_handling(int subfunction, int irqnumber); static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk); -asmlinkage int sys_vm86old(struct vm86_struct __user * v86) +asmlinkage int sys_vm86old(struct pt_regs regs) { + struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.ebx; struct kernel_vm86_struct info; /* declare this _on top_, * this avoids wasting of stack space. * This remains on the stack until we @@ -198,7 +198,7 @@ if (tmp) goto out; memset(&info.vm86plus, 0, (int)&info.regs32 - (int)&info.vm86plus); - info.regs32 = (struct pt_regs *) &v86; + info.regs32 = ®s; tsk->thread.vm86_info = v86; do_sys_vm86(&info, tsk); ret = 0; /* we never return here */ @@ -207,7 +207,7 @@ } -asmlinkage int sys_vm86(unsigned long subfunction, struct vm86plus_struct __user * v86) +asmlinkage int sys_vm86(struct pt_regs regs) { struct kernel_vm86_struct info; /* declare this _on top_, * this avoids wasting of stack space. @@ -216,14 +216,15 @@ */ struct task_struct *tsk; int tmp, ret; + struct vm86plus_struct __user *v86; tsk = current; - switch (subfunction) { + switch (regs.ebx) { case VM86_REQUEST_IRQ: case VM86_FREE_IRQ: case VM86_GET_IRQ_BITS: case VM86_GET_AND_RESET_IRQ: - ret = do_vm86_irq_handling(subfunction,(int)v86); + ret = do_vm86_irq_handling(regs.ebx, (int)regs.ecx); goto out; case VM86_PLUS_INSTALL_CHECK: /* NOTE: on old vm86 stuff this will return the error @@ -239,13 +240,14 @@ ret = -EPERM; if (tsk->thread.saved_esp0) goto out; + v86 = (struct vm86plus_struct __user *)regs.ecx; tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, (long)&info.regs32 - (long)&info.regs.VM86_REGS_PART2); ret = -EFAULT; if (tmp) goto out; - info.regs32 = (struct pt_regs *) &subfunction; + info.regs32 = ®s; info.vm86plus.is_vm86pus = 1; tsk->thread.vm86_info = (struct vm86_struct __user *)v86; do_sys_vm86(&info, tsk); @@ -486,9 +488,10 @@ * in userspace is always better than an Oops anyway.) [KD] */ static void do_int(struct kernel_vm86_regs *regs, int i, - unsigned char * ssp, unsigned short sp) + unsigned char __user * ssp, unsigned short sp) { - unsigned long *intr_ptr, segoffs; + unsigned long __user *intr_ptr; + unsigned long segoffs; if (regs->cs == BIOSSEG) goto cannot_handle; @@ -496,7 +499,7 @@ goto cannot_handle; if (i==0x21 && is_revectored(AH(regs),&KVM86->int21_revectored)) goto cannot_handle; - intr_ptr = (unsigned long *) (i << 2); + intr_ptr = (unsigned long __user *) (i << 2); if (get_user(segoffs, intr_ptr)) goto cannot_handle; if ((segoffs >> 16) == BIOSSEG) @@ -521,7 +524,7 @@ if (VMPI.is_vm86pus) { if ( (trapno==3) || (trapno==1) ) return_to_32bit(regs, VM86_TRAP + (trapno << 8)); - do_int(regs, trapno, (unsigned char *) (regs->ss << 4), SP(regs)); + do_int(regs, trapno, (unsigned char __user *) (regs->ss << 4), SP(regs)); return 0; } if (trapno !=1) @@ -541,7 +544,9 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) { - unsigned char *csp, *ssp, opcode; + unsigned char opcode; + unsigned char __user *csp; + unsigned char __user *ssp; unsigned short ip, sp; int data32, pref_done; @@ -553,8 +558,8 @@ return_to_32bit(regs, VM86_PICRETURN); \ return; } while (0) - csp = (unsigned char *) (regs->cs << 4); - ssp = (unsigned char *) (regs->ss << 4); + csp = (unsigned char __user *) (regs->cs << 4); + ssp = (unsigned char __user *) (regs->ss << 4); sp = SP(regs); ip = IP(regs); diff -Nru a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile --- a/arch/i386/lib/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/lib/Makefile 2004-06-26 17:09:15 -07:00 @@ -3,9 +3,8 @@ # -lib-y = checksum.o delay.o \ - usercopy.o getuser.o \ - memcpy.o strstr.o +lib-y = checksum.o delay.o usercopy.o getuser.o memcpy.o strstr.o \ + bitops.o lib-$(CONFIG_X86_USE_3DNOW) += mmx.o lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff -Nru a/arch/i386/lib/bitops.c b/arch/i386/lib/bitops.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/i386/lib/bitops.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,70 @@ +#include +#include + +/** + * find_next_bit - find the first set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +int find_next_bit(const unsigned long *addr, int size, int offset) +{ + const unsigned long *p = addr + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for nonzero in the first 32 bits: + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (*p >> bit)); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No set bit yet, search remaining full words for a bit + */ + res = find_first_bit (p, size - 32 * (p - addr)); + return (offset + set + res); +} +EXPORT_SYMBOL(find_next_bit); + +/** + * find_next_zero_bit - find the first zero bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +int find_next_zero_bit(const unsigned long *addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in the first 32 bits. + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} +EXPORT_SYMBOL(find_next_zero_bit); diff -Nru a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c --- a/arch/i386/lib/delay.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/lib/delay.c 2004-06-26 17:09:20 -07:00 @@ -31,15 +31,16 @@ inline void __const_udelay(unsigned long xloops) { int d0; + xloops *= 4; __asm__("mull %0" :"=d" (xloops), "=&a" (d0) - :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy)); - __delay(xloops * HZ); + :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy * (HZ/4))); + __delay(++xloops); } void __udelay(unsigned long usecs) { - __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ } void __ndelay(unsigned long nsecs) diff -Nru a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c --- a/arch/i386/mach-default/setup.c 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/mach-default/setup.c 2004-06-26 17:09:17 -07:00 @@ -27,7 +27,7 @@ /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; /** * intr_init_hook - post gate setup interrupt initialisation @@ -71,7 +71,7 @@ { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; /** * time_init_hook - do any specific initialisations for the system timer. diff -Nru a/arch/i386/mach-pc9800/Makefile b/arch/i386/mach-pc9800/Makefile --- a/arch/i386/mach-pc9800/Makefile 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,5 +0,0 @@ -# -# Makefile for the linux kernel. -# - -obj-y := setup.o topology.o std_resources.o diff -Nru a/arch/i386/mach-pc9800/setup.c b/arch/i386/mach-pc9800/setup.c --- a/arch/i386/mach-pc9800/setup.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,117 +0,0 @@ -/* - * Machine specific setup for pc9800 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct sys_desc_table_struct { - unsigned short length; - unsigned char table[0]; -}; - -/** - * pre_intr_init_hook - initialisation prior to setting up interrupt vectors - * - * Description: - * Perform any necessary interrupt initialisation prior to setting up - * the "ordinary" interrupt call gates. For legacy reasons, the ISA - * interrupts should be initialised here if the machine emulates a PC - * in any way. - **/ -void __init pre_intr_init_hook(void) -{ - init_ISA_irqs(); -} - -/* - * IRQ7 is cascade interrupt to second interrupt controller - */ -static struct irqaction irq7 = { no_action, 0, 0, "cascade", NULL, NULL}; - -/** - * intr_init_hook - post gate setup interrupt initialisation - * - * Description: - * Fill in any interrupts that may have been left out by the general - * init_IRQ() routine. interrupts having to do with the machine rather - * than the devices on the I/O bus (like APIC interrupts in intel MP - * systems) are started here. - **/ -void __init intr_init_hook(void) -{ -#ifdef CONFIG_X86_LOCAL_APIC - apic_intr_init(); -#endif - - setup_irq(7, &irq7); -} - -/** - * pre_setup_arch_hook - hook called prior to any setup_arch() execution - * - * Description: - * generally used to activate any machine specific identification - * routines that may be needed before setup_arch() runs. On VISWS - * this is used to get the board revision and type. - **/ -void __init pre_setup_arch_hook(void) -{ - SYS_DESC_TABLE.length = 0; - MCA_bus = 0; - /* In PC-9800, APM BIOS version is written in BCD...?? */ - APM_BIOS_INFO.version = (APM_BIOS_INFO.version & 0xff00) - | ((APM_BIOS_INFO.version & 0x00f0) >> 4); -} - -/** - * trap_init_hook - initialise system specific traps - * - * Description: - * Called as the final act of trap_init(). Used in VISWS to initialise - * the various board specific APIC traps. - **/ -void __init trap_init_hook(void) -{ -} - -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; - -/** - * time_init_hook - do any specific initialisations for the system timer. - * - * Description: - * Must plug the system timer interrupt source at HZ into the IRQ listed - * in irq_vectors.h:TIMER_IRQ - **/ -void __init time_init_hook(void) -{ - setup_irq(0, &irq0); -} - -#ifdef CONFIG_MCA -/** - * mca_nmi_hook - hook into MCA specific NMI chain - * - * Description: - * The MCA (Microchannel Architecture) has an NMI chain for NMI sources - * along the MCA bus. Use this to hook into that chain if you will need - * it. - **/ -void __init mca_nmi_hook(void) -{ - /* If I recall correctly, there's a whole bunch of other things that - * we can do to check for NMI problems, but that's all I know about - * at the moment. - */ - - printk("NMI generated from unknown source!\n"); -} -#endif diff -Nru a/arch/i386/mach-pc9800/std_resources.c b/arch/i386/mach-pc9800/std_resources.c --- a/arch/i386/mach-pc9800/std_resources.c 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,195 +0,0 @@ -/* - * Machine specific resource allocation for PC-9800. - * Written by Osamu Tomita - */ - -#include -#include -#include - -static char str_pic1[] = "pic1"; -static char str_dma[] = "dma"; -static char str_pic2[] = "pic2"; -static char str_calender_clock[] = "calender clock"; -static char str_system[] = "system"; -static char str_nmi_control[] = "nmi control"; -static char str_kanji_rom[] = "kanji rom"; -static char str_keyboard[] = "keyboard"; -static char str_text_gdc[] = "text gdc"; -static char str_crtc[] = "crtc"; -static char str_timer[] = "timer"; -static char str_graphic_gdc[] = "graphic gdc"; -static char str_dma_ex_bank[] = "dma ex. bank"; -static char str_beep_freq[] = "beep freq."; -static char str_mouse_pio[] = "mouse pio"; -struct resource standard_io_resources[] = { - { str_pic1, 0x00, 0x00, IORESOURCE_BUSY }, - { str_dma, 0x01, 0x01, IORESOURCE_BUSY }, - { str_pic1, 0x02, 0x02, IORESOURCE_BUSY }, - { str_dma, 0x03, 0x03, IORESOURCE_BUSY }, - { str_dma, 0x05, 0x05, IORESOURCE_BUSY }, - { str_dma, 0x07, 0x07, IORESOURCE_BUSY }, - { str_pic2, 0x08, 0x08, IORESOURCE_BUSY }, - { str_dma, 0x09, 0x09, IORESOURCE_BUSY }, - { str_pic2, 0x0a, 0x0a, IORESOURCE_BUSY }, - { str_dma, 0x0b, 0x0b, IORESOURCE_BUSY }, - { str_dma, 0x0d, 0x0d, IORESOURCE_BUSY }, - { str_dma, 0x0f, 0x0f, IORESOURCE_BUSY }, - { str_dma, 0x11, 0x11, IORESOURCE_BUSY }, - { str_dma, 0x13, 0x13, IORESOURCE_BUSY }, - { str_dma, 0x15, 0x15, IORESOURCE_BUSY }, - { str_dma, 0x17, 0x17, IORESOURCE_BUSY }, - { str_dma, 0x19, 0x19, IORESOURCE_BUSY }, - { str_dma, 0x1b, 0x1b, IORESOURCE_BUSY }, - { str_dma, 0x1d, 0x1d, IORESOURCE_BUSY }, - { str_dma, 0x1f, 0x1f, IORESOURCE_BUSY }, - { str_calender_clock, 0x20, 0x20, 0 }, - { str_dma, 0x21, 0x21, IORESOURCE_BUSY }, - { str_calender_clock, 0x22, 0x22, 0 }, - { str_dma, 0x23, 0x23, IORESOURCE_BUSY }, - { str_dma, 0x25, 0x25, IORESOURCE_BUSY }, - { str_dma, 0x27, 0x27, IORESOURCE_BUSY }, - { str_dma, 0x29, 0x29, IORESOURCE_BUSY }, - { str_dma, 0x2b, 0x2b, IORESOURCE_BUSY }, - { str_dma, 0x2d, 0x2d, IORESOURCE_BUSY }, - { str_system, 0x31, 0x31, IORESOURCE_BUSY }, - { str_system, 0x33, 0x33, IORESOURCE_BUSY }, - { str_system, 0x35, 0x35, IORESOURCE_BUSY }, - { str_system, 0x37, 0x37, IORESOURCE_BUSY }, - { str_nmi_control, 0x50, 0x50, IORESOURCE_BUSY }, - { str_nmi_control, 0x52, 0x52, IORESOURCE_BUSY }, - { "time stamp", 0x5c, 0x5f, IORESOURCE_BUSY }, - { str_kanji_rom, 0xa1, 0xa1, IORESOURCE_BUSY }, - { str_kanji_rom, 0xa3, 0xa3, IORESOURCE_BUSY }, - { str_kanji_rom, 0xa5, 0xa5, IORESOURCE_BUSY }, - { str_kanji_rom, 0xa7, 0xa7, IORESOURCE_BUSY }, - { str_kanji_rom, 0xa9, 0xa9, IORESOURCE_BUSY }, - { str_keyboard, 0x41, 0x41, IORESOURCE_BUSY }, - { str_keyboard, 0x43, 0x43, IORESOURCE_BUSY }, - { str_text_gdc, 0x60, 0x60, IORESOURCE_BUSY }, - { str_text_gdc, 0x62, 0x62, IORESOURCE_BUSY }, - { str_text_gdc, 0x64, 0x64, IORESOURCE_BUSY }, - { str_text_gdc, 0x66, 0x66, IORESOURCE_BUSY }, - { str_text_gdc, 0x68, 0x68, IORESOURCE_BUSY }, - { str_text_gdc, 0x6a, 0x6a, IORESOURCE_BUSY }, - { str_text_gdc, 0x6c, 0x6c, IORESOURCE_BUSY }, - { str_text_gdc, 0x6e, 0x6e, IORESOURCE_BUSY }, - { str_crtc, 0x70, 0x70, IORESOURCE_BUSY }, - { str_crtc, 0x72, 0x72, IORESOURCE_BUSY }, - { str_crtc, 0x74, 0x74, IORESOURCE_BUSY }, - { str_crtc, 0x74, 0x74, IORESOURCE_BUSY }, - { str_crtc, 0x76, 0x76, IORESOURCE_BUSY }, - { str_crtc, 0x78, 0x78, IORESOURCE_BUSY }, - { str_crtc, 0x7a, 0x7a, IORESOURCE_BUSY }, - { str_timer, 0x71, 0x71, IORESOURCE_BUSY }, - { str_timer, 0x73, 0x73, IORESOURCE_BUSY }, - { str_timer, 0x75, 0x75, IORESOURCE_BUSY }, - { str_timer, 0x77, 0x77, IORESOURCE_BUSY }, - { str_graphic_gdc, 0xa0, 0xa0, IORESOURCE_BUSY }, - { str_graphic_gdc, 0xa2, 0xa2, IORESOURCE_BUSY }, - { str_graphic_gdc, 0xa4, 0xa4, IORESOURCE_BUSY }, - { str_graphic_gdc, 0xa6, 0xa6, IORESOURCE_BUSY }, - { "cpu", 0xf0, 0xf7, IORESOURCE_BUSY }, - { "fpu", 0xf8, 0xff, IORESOURCE_BUSY }, - { str_dma_ex_bank, 0x0e05, 0x0e05, 0 }, - { str_dma_ex_bank, 0x0e07, 0x0e07, 0 }, - { str_dma_ex_bank, 0x0e09, 0x0e09, 0 }, - { str_dma_ex_bank, 0x0e0b, 0x0e0b, 0 }, - { str_beep_freq, 0x3fd9, 0x3fd9, IORESOURCE_BUSY }, - { str_beep_freq, 0x3fdb, 0x3fdb, IORESOURCE_BUSY }, - { str_beep_freq, 0x3fdd, 0x3fdd, IORESOURCE_BUSY }, - { str_beep_freq, 0x3fdf, 0x3fdf, IORESOURCE_BUSY }, - /* All PC-9800 have (exactly) one mouse interface. */ - { str_mouse_pio, 0x7fd9, 0x7fd9, 0 }, - { str_mouse_pio, 0x7fdb, 0x7fdb, 0 }, - { str_mouse_pio, 0x7fdd, 0x7fdd, 0 }, - { str_mouse_pio, 0x7fdf, 0x7fdf, 0 }, - { "mouse timer", 0xbfdb, 0xbfdb, 0 }, - { "mouse irq", 0x98d7, 0x98d7, 0 }, -}; - -#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) - -static struct resource tvram_resource = { "Text VRAM/CG window", 0xa0000, 0xa4fff, IORESOURCE_BUSY }; -static struct resource gvram_brg_resource = { "Graphic VRAM (B/R/G)", 0xa8000, 0xbffff, IORESOURCE_BUSY }; -static struct resource gvram_e_resource = { "Graphic VRAM (E)", 0xe0000, 0xe7fff, IORESOURCE_BUSY }; - -/* System ROM resources */ -#define MAXROMS 6 -static struct resource rom_resources[MAXROMS] = { - { "System ROM", 0xe8000, 0xfffff, IORESOURCE_BUSY } -}; - -void __init probe_roms(void) -{ - int i; - __u8 *xrom_id; - int roms = 1; - - request_resource(&iomem_resource, rom_resources+0); - - xrom_id = (__u8 *) isa_bus_to_virt(PC9800SCA_XROM_ID + 0x10); - - for (i = 0; i < 16; i++) { - if (xrom_id[i] & 0x80) { - int j; - - for (j = i + 1; j < 16 && (xrom_id[j] & 0x80); j++) - ; - rom_resources[roms].start = 0x0d0000 + i * 0x001000; - rom_resources[roms].end = 0x0d0000 + j * 0x001000 - 1; - rom_resources[roms].name = "Extension ROM"; - rom_resources[roms].flags = IORESOURCE_BUSY; - - request_resource(&iomem_resource, - rom_resources + roms); - if (++roms >= MAXROMS) - return; - } - } -} - -void __init request_graphics_resource(void) -{ - int i; - - if (PC9800_HIGHRESO_P()) { - tvram_resource.start = 0xe0000; - tvram_resource.end = 0xe4fff; - gvram_brg_resource.name = "Graphic VRAM"; - gvram_brg_resource.start = 0xc0000; - gvram_brg_resource.end = 0xdffff; - } - - request_resource(&iomem_resource, &tvram_resource); - request_resource(&iomem_resource, &gvram_brg_resource); - if (!PC9800_HIGHRESO_P()) - request_resource(&iomem_resource, &gvram_e_resource); - - if (PC9800_HIGHRESO_P() || PC9800_9821_P()) { - static char graphics[] = "graphics"; - static struct resource graphics_resources[] = { - { graphics, 0x9a0, 0x9a0, 0 }, - { graphics, 0x9a2, 0x9a2, 0 }, - { graphics, 0x9a4, 0x9a4, 0 }, - { graphics, 0x9a6, 0x9a6, 0 }, - { graphics, 0x9a8, 0x9a8, 0 }, - { graphics, 0x9aa, 0x9aa, 0 }, - { graphics, 0x9ac, 0x9ac, 0 }, - { graphics, 0x9ae, 0x9ae, 0 }, - }; - -#define GRAPHICS_RESOURCES (sizeof(graphics_resources)/sizeof(struct resource)) - - for (i = 0; i < GRAPHICS_RESOURCES; i++) - request_resource(&ioport_resource, graphics_resources + i); - } -} - -void __init request_standard_io_resources(void) -{ - int i; - - for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, standard_io_resources+i); -} diff -Nru a/arch/i386/mach-pc9800/topology.c b/arch/i386/mach-pc9800/topology.c --- a/arch/i386/mach-pc9800/topology.c 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,44 +0,0 @@ -/* - * arch/i386/mach-pc9800/topology.c - Populate driverfs with topology information - * - * Written by: Matthew Dobson, IBM Corporation - * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL - * - * Copyright (C) 2002, IBM Corp. - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Modify for PC-9800 by Osamu Tomita - * - */ -#include -#include -#include - -struct i386_cpu cpu_devices[NR_CPUS]; - -static int __init topology_init(void) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) - if (cpu_possible(i)) arch_register_cpu(i); - return 0; -} - -subsys_initcall(topology_init); diff -Nru a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c --- a/arch/i386/mach-visws/mpparse.c 2004-06-26 17:09:16 -07:00 +++ b/arch/i386/mach-visws/mpparse.c 2004-06-26 17:09:16 -07:00 @@ -57,12 +57,12 @@ boot_cpu_logical_apicid = logical_apicid; } - if (m->mpc_apicid > MAX_APICS) { + ver = m->mpc_apicver; + if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", m->mpc_apicid, MAX_APICS); return; } - ver = m->mpc_apicver; apic_cpus = apicid_to_cpu_present(m->mpc_apicid); physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); diff -Nru a/arch/i386/mach-visws/traps.c b/arch/i386/mach-visws/traps.c --- a/arch/i386/mach-visws/traps.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/mach-visws/traps.c 2004-06-26 17:09:19 -07:00 @@ -8,7 +8,6 @@ #include #include -#include #include #include #include "cobalt.h" diff -Nru a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c --- a/arch/i386/mach-voyager/setup.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/mach-voyager/setup.c 2004-06-26 17:09:19 -07:00 @@ -17,7 +17,7 @@ /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init intr_init_hook(void) { @@ -40,7 +40,7 @@ { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init_hook(void) { diff -Nru a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c --- a/arch/i386/mach-voyager/voyager_basic.c 2004-06-26 17:09:16 -07:00 +++ b/arch/i386/mach-voyager/voyager_basic.c 2004-06-26 17:09:16 -07:00 @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c --- a/arch/i386/mach-voyager/voyager_smp.c 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/mach-voyager/voyager_smp.c 2004-06-26 17:09:17 -07:00 @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -154,7 +153,7 @@ send_CPI_allbutself(__u8 cpi) { __u8 cpu = smp_processor_id(); - __u32 mask = cpus_coerce(cpu_online_map) & ~(1 << cpu); + __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu); send_CPI(mask, cpi); } @@ -403,11 +402,11 @@ /* set up everything for just this CPU, we can alter * this as we start the other CPUs later */ /* now get the CPU disposition from the extended CMOS */ - phys_cpu_present_map = cpus_promote(voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK)); - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; - printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_coerce(phys_cpu_present_map)); + cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; + printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]); /* Here we set up the VIC to enable SMP */ /* enable the CPIs by writing the base vector to their register */ outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); @@ -707,12 +706,12 @@ /* now that the cat has probed the Voyager System Bus, sanity * check the cpu map */ if( ((voyager_quad_processors | voyager_extended_vic_processors) - & cpus_coerce(phys_cpu_present_map)) != cpus_coerce(phys_cpu_present_map)) { + & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) { /* should panic */ printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n"); } } else if(voyager_level == 4) - voyager_extended_vic_processors = cpus_coerce(phys_cpu_present_map); + voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0]; /* this sets up the idle task to run on the current cpu */ voyager_extended_cpus = 1; @@ -910,7 +909,7 @@ if (!cpumask) BUG(); - if ((cpumask & cpus_coerce(cpu_online_map)) != cpumask) + if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask) BUG(); if (cpumask & (1 << smp_processor_id())) BUG(); @@ -953,7 +952,7 @@ preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); local_flush_tlb(); if (cpu_mask) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); @@ -969,7 +968,7 @@ preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if (current->mm) @@ -990,7 +989,7 @@ preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if(current->mm) __flush_tlb_one(va); @@ -1099,7 +1098,7 @@ int wait) { struct call_data_struct data; - __u32 mask = cpus_coerce(cpu_online_map); + __u32 mask = cpus_addr(cpu_online_map)[0]; mask &= ~(1< #include #include -#include #include #include diff -Nru a/arch/i386/math-emu/errors.c b/arch/i386/math-emu/errors.c --- a/arch/i386/math-emu/errors.c 2004-06-26 17:09:18 -07:00 +++ b/arch/i386/math-emu/errors.c 2004-06-26 17:09:18 -07:00 @@ -41,18 +41,18 @@ RE_ENTRANT_CHECK_OFF; /* No need to verify_area(), we have previously fetched these bytes. */ - printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address); + printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *) address); if ( FPU_CS == __USER_CS ) { while ( 1 ) { - FPU_get_user(byte1, (u_char *) address); + FPU_get_user(byte1, (u_char __user *) address); if ( (byte1 & 0xf8) == 0xd8 ) break; printk("[%02x]", byte1); address++; } printk("%02x ", byte1); - FPU_get_user(FPU_modrm, 1 + (u_char *) address); + FPU_get_user(FPU_modrm, 1 + (u_char __user *) address); if (FPU_modrm >= 0300) printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7); @@ -98,7 +98,7 @@ #define MAX_PRINTED_BYTES 20 for ( i = 0; i < MAX_PRINTED_BYTES; i++ ) { - FPU_get_user(byte1, (u_char *) address); + FPU_get_user(byte1, (u_char __user *) address); if ( (byte1 & 0xf8) == 0xd8 ) { printk(" %02x", byte1); @@ -111,7 +111,7 @@ printk(" [more..]\n"); else { - FPU_get_user(FPU_modrm, 1 + (u_char *) address); + FPU_get_user(FPU_modrm, 1 + (u_char __user *) address); if (FPU_modrm >= 0300) printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7); diff -Nru a/arch/i386/math-emu/fpu_arith.c b/arch/i386/math-emu/fpu_arith.c --- a/arch/i386/math-emu/fpu_arith.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/math-emu/fpu_arith.c 2004-06-26 17:09:20 -07:00 @@ -16,7 +16,7 @@ #include "status_w.h" -void fadd__() +void fadd__(void) { /* fadd st,st(i) */ int i = FPU_rm; @@ -25,7 +25,7 @@ } -void fmul__() +void fmul__(void) { /* fmul st,st(i) */ int i = FPU_rm; @@ -35,7 +35,7 @@ -void fsub__() +void fsub__(void) { /* fsub st,st(i) */ clear_C1(); @@ -43,7 +43,7 @@ } -void fsubr_() +void fsubr_(void) { /* fsubr st,st(i) */ clear_C1(); @@ -51,7 +51,7 @@ } -void fdiv__() +void fdiv__(void) { /* fdiv st,st(i) */ clear_C1(); @@ -59,7 +59,7 @@ } -void fdivr_() +void fdivr_(void) { /* fdivr st,st(i) */ clear_C1(); @@ -68,7 +68,7 @@ -void fadd_i() +void fadd_i(void) { /* fadd st(i),st */ int i = FPU_rm; @@ -77,7 +77,7 @@ } -void fmul_i() +void fmul_i(void) { /* fmul st(i),st */ clear_C1(); @@ -85,7 +85,7 @@ } -void fsubri() +void fsubri(void) { /* fsubr st(i),st */ clear_C1(); @@ -93,7 +93,7 @@ } -void fsub_i() +void fsub_i(void) { /* fsub st(i),st */ clear_C1(); @@ -101,7 +101,7 @@ } -void fdivri() +void fdivri(void) { /* fdivr st(i),st */ clear_C1(); @@ -109,7 +109,7 @@ } -void fdiv_i() +void fdiv_i(void) { /* fdiv st(i),st */ clear_C1(); @@ -118,7 +118,7 @@ -void faddp_() +void faddp_(void) { /* faddp st(i),st */ int i = FPU_rm; @@ -128,7 +128,7 @@ } -void fmulp_() +void fmulp_(void) { /* fmulp st(i),st */ clear_C1(); @@ -138,7 +138,7 @@ -void fsubrp() +void fsubrp(void) { /* fsubrp st(i),st */ clear_C1(); @@ -147,7 +147,7 @@ } -void fsubp_() +void fsubp_(void) { /* fsubp st(i),st */ clear_C1(); @@ -156,7 +156,7 @@ } -void fdivrp() +void fdivrp(void) { /* fdivrp st(i),st */ clear_C1(); @@ -165,7 +165,7 @@ } -void fdivp_() +void fdivp_(void) { /* fdivp st(i),st */ clear_C1(); diff -Nru a/arch/i386/math-emu/fpu_aux.c b/arch/i386/math-emu/fpu_aux.c --- a/arch/i386/math-emu/fpu_aux.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/math-emu/fpu_aux.c 2004-06-26 17:09:15 -07:00 @@ -30,7 +30,7 @@ } /* Needs to be externally visible */ -void finit() +void finit(void) { control_word = 0x037f; partial_status = 0; @@ -58,7 +58,7 @@ fsetpm, FPU_illegal, FPU_illegal, FPU_illegal }; -void finit_() +void finit_(void) { (finit_table[FPU_rm])(); } @@ -75,7 +75,7 @@ FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal }; -void fstsw_() +void fstsw_(void) { (fstsw_table[FPU_rm])(); } @@ -86,13 +86,13 @@ FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal }; -void fp_nop() +void fp_nop(void) { (fp_nop_table[FPU_rm])(); } -void fld_i_() +void fld_i_(void) { FPU_REG *st_new_ptr; int i; @@ -124,7 +124,7 @@ } -void fxch_i() +void fxch_i(void) { /* fxch st(i) */ FPU_REG t; @@ -173,14 +173,14 @@ } -void ffree_() +void ffree_(void) { /* ffree st(i) */ FPU_settagi(FPU_rm, TAG_Empty); } -void ffreep() +void ffreep(void) { /* ffree st(i) + pop - unofficial code */ FPU_settagi(FPU_rm, TAG_Empty); @@ -188,14 +188,14 @@ } -void fst_i_() +void fst_i_(void) { /* fst st(i) */ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm); } -void fstp_i() +void fstp_i(void) { /* fstp st(i) */ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm); diff -Nru a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c --- a/arch/i386/math-emu/fpu_entry.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/math-emu/fpu_entry.c 2004-06-26 17:09:20 -07:00 @@ -128,7 +128,7 @@ u_char emulating=0; #endif /* RE_ENTRANT_CHECKING */ -static int valid_prefix(u_char *Byte, u_char **fpu_eip, +static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, overrides *override); asmlinkage void math_emulate(long arg) @@ -140,7 +140,7 @@ FPU_REG loaded_data; FPU_REG *st0_ptr; u_char loaded_tag, st0_tag; - void *data_address; + void __user *data_address; struct address data_sel_off; struct address entry_sel_off; unsigned long code_base = 0; @@ -192,7 +192,8 @@ math_abort(FPU_info, SIGILL); } - if ( SEG_D_SIZE(code_descriptor = LDT_DESCRIPTOR(FPU_CS)) ) + code_descriptor = LDT_DESCRIPTOR(FPU_CS); + if ( SEG_D_SIZE(code_descriptor) ) { /* The above test may be wrong, the book is not clear */ /* Segmented 32 bit protected mode */ @@ -214,7 +215,7 @@ if (current->ptrace & PT_PTRACED) FPU_lookahead = 0; - if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP, + if ( !valid_prefix(&byte1, (u_char __user **)&FPU_EIP, &addr_modes.override) ) { RE_ENTRANT_CHECK_OFF; @@ -257,7 +258,7 @@ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(1); - FPU_get_user(FPU_modrm, (u_char *) FPU_EIP); + FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP); RE_ENTRANT_CHECK_ON; FPU_EIP++; @@ -336,23 +337,23 @@ switch ( (byte1 >> 1) & 3 ) { case 0: - unmasked = FPU_load_single((float *)data_address, + unmasked = FPU_load_single((float __user *)data_address, &loaded_data); loaded_tag = unmasked & 0xff; unmasked &= ~0xff; break; case 1: - loaded_tag = FPU_load_int32((long *)data_address, &loaded_data); + loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data); break; case 2: - unmasked = FPU_load_double((double *)data_address, + unmasked = FPU_load_double((double __user *)data_address, &loaded_data); loaded_tag = unmasked & 0xff; unmasked &= ~0xff; break; case 3: default: /* Used here to suppress gcc warnings. */ - loaded_tag = FPU_load_int16((short *)data_address, &loaded_data); + loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data); break; } @@ -563,7 +564,7 @@ if (FPU_lookahead && !need_resched()) { FPU_ORIG_EIP = FPU_EIP - code_base; - if ( valid_prefix(&byte1, (u_char **)&FPU_EIP, + if ( valid_prefix(&byte1, (u_char __user **)&FPU_EIP, &addr_modes.override) ) goto do_another_FPU_instruction; } @@ -579,11 +580,11 @@ all prefix bytes, further changes are needed in the emulator code which accesses user address space. Access to separate segments is important for msdos emulation. */ -static int valid_prefix(u_char *Byte, u_char **fpu_eip, +static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, overrides *override) { u_char byte; - u_char *ip = *fpu_eip; + u_char __user *ip = *fpu_eip; *override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */ @@ -679,9 +680,9 @@ #define sstatus_word() \ ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top)) -int restore_i387_soft(void *s387, struct _fpstate *buf) +int restore_i387_soft(void *s387, struct _fpstate __user *buf) { - u_char *d = (u_char *)buf; + u_char __user *d = (u_char __user *)buf; int offset, other, i, tags, regnr, tag, newtop; RE_ENTRANT_CHECK_OFF; @@ -725,9 +726,9 @@ } -int save_i387_soft(void *s387, struct _fpstate * buf) +int save_i387_soft(void *s387, struct _fpstate __user * buf) { - u_char *d = (u_char *)buf; + u_char __user *d = (u_char __user *)buf; int offset = (S387->ftop & 7) * 10, other = 80 - offset; RE_ENTRANT_CHECK_OFF; diff -Nru a/arch/i386/math-emu/fpu_etc.c b/arch/i386/math-emu/fpu_etc.c --- a/arch/i386/math-emu/fpu_etc.c 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/math-emu/fpu_etc.c 2004-06-26 17:09:17 -07:00 @@ -137,7 +137,7 @@ ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal }; -void FPU_etc() +void FPU_etc(void) { (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0()); } diff -Nru a/arch/i386/math-emu/fpu_proto.h b/arch/i386/math-emu/fpu_proto.h --- a/arch/i386/math-emu/fpu_proto.h 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/math-emu/fpu_proto.h 2004-06-26 17:09:20 -07:00 @@ -77,13 +77,13 @@ extern void FPU_triga(void); extern void FPU_trigb(void); /* get_address.c */ -extern void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip, +extern void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip, struct address *addr, fpu_addr_modes addr_modes); -extern void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip, +extern void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip, struct address *addr, fpu_addr_modes addr_modes); /* load_store.c */ extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes, - void *data_address); + void __user *data_address); /* poly_2xm1.c */ extern int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result); /* poly_atan.c */ @@ -112,26 +112,26 @@ /* reg_constant.c */ extern void fconst(void); /* reg_ld_str.c */ -extern int FPU_load_extended(long double *s, int stnr); -extern int FPU_load_double(double *dfloat, FPU_REG *loaded_data); -extern int FPU_load_single(float *single, FPU_REG *loaded_data); -extern int FPU_load_int64(long long *_s); -extern int FPU_load_int32(long *_s, FPU_REG *loaded_data); -extern int FPU_load_int16(short *_s, FPU_REG *loaded_data); -extern int FPU_load_bcd(u_char *s); +extern int FPU_load_extended(long double __user *s, int stnr); +extern int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data); +extern int FPU_load_single(float __user *single, FPU_REG *loaded_data); +extern int FPU_load_int64(long long __user *_s); +extern int FPU_load_int32(long __user *_s, FPU_REG *loaded_data); +extern int FPU_load_int16(short __user *_s, FPU_REG *loaded_data); +extern int FPU_load_bcd(u_char __user *s); extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, - long double *d); -extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat); -extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single); -extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d); -extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d); -extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d); -extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d); + long double __user *d); +extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat); +extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single); +extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d); +extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d); +extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d); +extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d); extern int FPU_round_to_int(FPU_REG *r, u_char tag); -extern u_char *fldenv(fpu_addr_modes addr_modes, u_char *s); -extern void frstor(fpu_addr_modes addr_modes, u_char *data_address); -extern u_char *fstenv(fpu_addr_modes addr_modes, u_char *d); -extern void fsave(fpu_addr_modes addr_modes, u_char *data_address); +extern u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s); +extern void frstor(fpu_addr_modes addr_modes, u_char __user *data_address); +extern u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d); +extern void fsave(fpu_addr_modes addr_modes, u_char __user *data_address); extern int FPU_tagof(FPU_REG *ptr); /* reg_mul.c */ extern int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w); diff -Nru a/arch/i386/math-emu/fpu_system.h b/arch/i386/math-emu/fpu_system.h --- a/arch/i386/math-emu/fpu_system.h 2004-06-26 17:09:17 -07:00 +++ b/arch/i386/math-emu/fpu_system.h 2004-06-26 17:09:17 -07:00 @@ -80,7 +80,7 @@ /* A simpler test than verify_area() can probably be done for FPU_code_verify_area() because the only possible error is to step past the upper boundary of a legal code area. */ -#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z) +#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void __user *)FPU_EIP,z) #endif #define FPU_get_user(x,y) get_user((x),(y)) diff -Nru a/arch/i386/math-emu/get_address.c b/arch/i386/math-emu/get_address.c --- a/arch/i386/math-emu/get_address.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/math-emu/get_address.c 2004-06-26 17:09:20 -07:00 @@ -82,7 +82,7 @@ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(1); - FPU_get_user(base, (u_char *) (*fpu_eip)); /* The SIB byte */ + FPU_get_user(base, (u_char __user *) (*fpu_eip)); /* The SIB byte */ RE_ENTRANT_CHECK_ON; (*fpu_eip)++; ss = base >> 6; @@ -112,7 +112,7 @@ long displacement; RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(1); - FPU_get_user(displacement, (signed char *) (*fpu_eip)); + FPU_get_user(displacement, (signed char __user *) (*fpu_eip)); offset += displacement; RE_ENTRANT_CHECK_ON; (*fpu_eip)++; @@ -123,7 +123,7 @@ long displacement; RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(4); - FPU_get_user(displacement, (long *) (*fpu_eip)); + FPU_get_user(displacement, (long __user *) (*fpu_eip)); offset += displacement; RE_ENTRANT_CHECK_ON; (*fpu_eip) += 4; @@ -241,7 +241,7 @@ */ -void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip, +void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip, struct address *addr, fpu_addr_modes addr_modes) { @@ -277,24 +277,24 @@ /* Special case: disp32 */ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(4); - FPU_get_user(address, (unsigned long *) (*fpu_eip)); + FPU_get_user(address, (unsigned long __user *) (*fpu_eip)); (*fpu_eip) += 4; RE_ENTRANT_CHECK_ON; addr->offset = address; - return (void *) address; + return (void __user *) address; } else { address = *cpu_reg_ptr; /* Just return the contents of the cpu register */ addr->offset = address; - return (void *) address; + return (void __user *) address; } case 1: /* 8 bit signed displacement */ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(1); - FPU_get_user(address, (signed char *) (*fpu_eip)); + FPU_get_user(address, (signed char __user *) (*fpu_eip)); RE_ENTRANT_CHECK_ON; (*fpu_eip)++; break; @@ -302,7 +302,7 @@ /* 32 bit displacement */ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(4); - FPU_get_user(address, (long *) (*fpu_eip)); + FPU_get_user(address, (long __user *) (*fpu_eip)); (*fpu_eip) += 4; RE_ENTRANT_CHECK_ON; break; @@ -331,11 +331,11 @@ EXCEPTION(EX_INTERNAL|0x133); } - return (void *)address; + return (void __user *)address; } -void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip, +void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip, struct address *addr, fpu_addr_modes addr_modes) { @@ -363,7 +363,7 @@ /* Special case: disp16 */ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(2); - FPU_get_user(address, (unsigned short *) (*fpu_eip)); + FPU_get_user(address, (unsigned short __user *) (*fpu_eip)); (*fpu_eip) += 2; RE_ENTRANT_CHECK_ON; goto add_segment; @@ -373,7 +373,7 @@ /* 8 bit signed displacement */ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(1); - FPU_get_user(address, (signed char *) (*fpu_eip)); + FPU_get_user(address, (signed char __user *) (*fpu_eip)); RE_ENTRANT_CHECK_ON; (*fpu_eip)++; break; @@ -381,7 +381,7 @@ /* 16 bit displacement */ RE_ENTRANT_CHECK_OFF; FPU_code_verify_area(2); - FPU_get_user(address, (unsigned short *) (*fpu_eip)); + FPU_get_user(address, (unsigned short __user *) (*fpu_eip)); (*fpu_eip) += 2; RE_ENTRANT_CHECK_ON; break; @@ -445,5 +445,5 @@ EXCEPTION(EX_INTERNAL|0x131); } - return (void *)address ; + return (void __user *)address ; } diff -Nru a/arch/i386/math-emu/load_store.c b/arch/i386/math-emu/load_store.c --- a/arch/i386/math-emu/load_store.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/math-emu/load_store.c 2004-06-26 17:09:15 -07:00 @@ -61,7 +61,7 @@ }; int FPU_load_store(u_char type, fpu_addr_modes addr_modes, - void *data_address) + void __user *data_address) { FPU_REG loaded_data; FPU_REG *st0_ptr; @@ -119,7 +119,7 @@ { case 000: /* fld m32real */ clear_C1(); - loaded_tag = FPU_load_single((float *)data_address, &loaded_data); + loaded_tag = FPU_load_single((float __user *)data_address, &loaded_data); if ( (loaded_tag == TAG_Special) && isNaN(&loaded_data) && (real_1op_NaN(&loaded_data) < 0) ) @@ -131,12 +131,12 @@ break; case 001: /* fild m32int */ clear_C1(); - loaded_tag = FPU_load_int32((long *)data_address, &loaded_data); + loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data); FPU_copy_to_reg0(&loaded_data, loaded_tag); break; case 002: /* fld m64real */ clear_C1(); - loaded_tag = FPU_load_double((double *)data_address, &loaded_data); + loaded_tag = FPU_load_double((double __user *)data_address, &loaded_data); if ( (loaded_tag == TAG_Special) && isNaN(&loaded_data) && (real_1op_NaN(&loaded_data) < 0) ) @@ -148,68 +148,68 @@ break; case 003: /* fild m16int */ clear_C1(); - loaded_tag = FPU_load_int16((short *)data_address, &loaded_data); + loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data); FPU_copy_to_reg0(&loaded_data, loaded_tag); break; case 010: /* fst m32real */ clear_C1(); - FPU_store_single(st0_ptr, st0_tag, (float *)data_address); + FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address); break; case 011: /* fist m32int */ clear_C1(); - FPU_store_int32(st0_ptr, st0_tag, (long *)data_address); + FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address); break; case 012: /* fst m64real */ clear_C1(); - FPU_store_double(st0_ptr, st0_tag, (double *)data_address); + FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address); break; case 013: /* fist m16int */ clear_C1(); - FPU_store_int16(st0_ptr, st0_tag, (short *)data_address); + FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address); break; case 014: /* fstp m32real */ clear_C1(); - if ( FPU_store_single(st0_ptr, st0_tag, (float *)data_address) ) + if ( FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address) ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 015: /* fistp m32int */ clear_C1(); - if ( FPU_store_int32(st0_ptr, st0_tag, (long *)data_address) ) + if ( FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address) ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 016: /* fstp m64real */ clear_C1(); - if ( FPU_store_double(st0_ptr, st0_tag, (double *)data_address) ) + if ( FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address) ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 017: /* fistp m16int */ clear_C1(); - if ( FPU_store_int16(st0_ptr, st0_tag, (short *)data_address) ) + if ( FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address) ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 020: /* fldenv m14/28byte */ - fldenv(addr_modes, (u_char *)data_address); + fldenv(addr_modes, (u_char __user *)data_address); /* Ensure that the values just loaded are not changed by fix-up operations. */ return 1; case 022: /* frstor m94/108byte */ - frstor(addr_modes, (u_char *)data_address); + frstor(addr_modes, (u_char __user *)data_address); /* Ensure that the values just loaded are not changed by fix-up operations. */ return 1; case 023: /* fbld m80dec */ clear_C1(); - loaded_tag = FPU_load_bcd((u_char *)data_address); + loaded_tag = FPU_load_bcd((u_char __user *)data_address); FPU_settag0(loaded_tag); break; case 024: /* fldcw */ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_READ, data_address, 2); - FPU_get_user(control_word, (unsigned short *) data_address); + FPU_get_user(control_word, (unsigned short __user *) data_address); RE_ENTRANT_CHECK_ON; if ( partial_status & ~control_word & CW_Exceptions ) partial_status |= (SW_Summary | SW_Backward); @@ -221,47 +221,47 @@ return 1; case 025: /* fld m80real */ clear_C1(); - loaded_tag = FPU_load_extended((long double *)data_address, 0); + loaded_tag = FPU_load_extended((long double __user *)data_address, 0); FPU_settag0(loaded_tag); break; case 027: /* fild m64int */ clear_C1(); - loaded_tag = FPU_load_int64((long long *)data_address); + loaded_tag = FPU_load_int64((long long __user *)data_address); FPU_settag0(loaded_tag); break; case 030: /* fstenv m14/28byte */ - fstenv(addr_modes, (u_char *)data_address); + fstenv(addr_modes, (u_char __user *)data_address); return 1; case 032: /* fsave */ - fsave(addr_modes, (u_char *)data_address); + fsave(addr_modes, (u_char __user *)data_address); return 1; case 033: /* fbstp m80dec */ clear_C1(); - if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char *)data_address) ) + if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char __user *)data_address) ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 034: /* fstcw m16int */ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE,data_address,2); - FPU_put_user(control_word, (unsigned short *) data_address); + FPU_put_user(control_word, (unsigned short __user *) data_address); RE_ENTRANT_CHECK_ON; return 1; case 035: /* fstp m80real */ clear_C1(); - if ( FPU_store_extended(st0_ptr, st0_tag, (long double *)data_address) ) + if ( FPU_store_extended(st0_ptr, st0_tag, (long double __user *)data_address) ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 036: /* fstsw m2byte */ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE,data_address,2); - FPU_put_user(status_word(),(unsigned short *) data_address); + FPU_put_user(status_word(),(unsigned short __user *) data_address); RE_ENTRANT_CHECK_ON; return 1; case 037: /* fistp m64int */ clear_C1(); - if ( FPU_store_int64(st0_ptr, st0_tag, (long long *)data_address) ) + if ( FPU_store_int64(st0_ptr, st0_tag, (long long __user *)data_address) ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; diff -Nru a/arch/i386/math-emu/reg_compare.c b/arch/i386/math-emu/reg_compare.c --- a/arch/i386/math-emu/reg_compare.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/math-emu/reg_compare.c 2004-06-26 17:09:20 -07:00 @@ -324,14 +324,14 @@ /*---------------------------------------------------------------------------*/ -void fcom_st() +void fcom_st(void) { /* fcom st(i) */ compare_st_st(FPU_rm); } -void fcompst() +void fcompst(void) { /* fcomp st(i) */ if ( !compare_st_st(FPU_rm) ) @@ -339,7 +339,7 @@ } -void fcompp() +void fcompp(void) { /* fcompp */ if (FPU_rm != 1) @@ -352,7 +352,7 @@ } -void fucom_() +void fucom_(void) { /* fucom st(i) */ compare_u_st_st(FPU_rm); @@ -360,7 +360,7 @@ } -void fucomp() +void fucomp(void) { /* fucomp st(i) */ if ( !compare_u_st_st(FPU_rm) ) @@ -368,7 +368,7 @@ } -void fucompp() +void fucompp(void) { /* fucompp */ if (FPU_rm == 1) diff -Nru a/arch/i386/math-emu/reg_ld_str.c b/arch/i386/math-emu/reg_ld_str.c --- a/arch/i386/math-emu/reg_ld_str.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/math-emu/reg_ld_str.c 2004-06-26 17:09:19 -07:00 @@ -86,7 +86,7 @@ /* Get a long double from user memory */ -int FPU_load_extended(long double *s, int stnr) +int FPU_load_extended(long double __user *s, int stnr) { FPU_REG *sti_ptr = &st(stnr); @@ -100,15 +100,15 @@ /* Get a double from user memory */ -int FPU_load_double(double *dfloat, FPU_REG *loaded_data) +int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data) { int exp, tag, negative; unsigned m64, l64; RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_READ, dfloat, 8); - FPU_get_user(m64, 1 + (unsigned long *) dfloat); - FPU_get_user(l64, (unsigned long *) dfloat); + FPU_get_user(m64, 1 + (unsigned long __user *) dfloat); + FPU_get_user(l64, (unsigned long __user *) dfloat); RE_ENTRANT_CHECK_ON; negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive; @@ -172,14 +172,14 @@ /* Get a float from user memory */ -int FPU_load_single(float *single, FPU_REG *loaded_data) +int FPU_load_single(float __user *single, FPU_REG *loaded_data) { unsigned m32; int exp, tag, negative; RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_READ, single, 4); - FPU_get_user(m32, (unsigned long *) single); + FPU_get_user(m32, (unsigned long __user *) single); RE_ENTRANT_CHECK_ON; negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive; @@ -236,7 +236,7 @@ /* Get a long long from user memory */ -int FPU_load_int64(long long *_s) +int FPU_load_int64(long long __user *_s) { long long s; int sign; @@ -268,7 +268,7 @@ /* Get a long from user memory */ -int FPU_load_int32(long *_s, FPU_REG *loaded_data) +int FPU_load_int32(long __user *_s, FPU_REG *loaded_data) { long s; int negative; @@ -297,7 +297,7 @@ /* Get a short from user memory */ -int FPU_load_int16(short *_s, FPU_REG *loaded_data) +int FPU_load_int16(short __user *_s, FPU_REG *loaded_data) { int s, negative; @@ -326,7 +326,7 @@ /* Get a packed bcd array from user memory */ -int FPU_load_bcd(u_char *s) +int FPU_load_bcd(u_char __user *s) { FPU_REG *st0_ptr = &st(0); int pos; @@ -341,7 +341,7 @@ { l *= 10; RE_ENTRANT_CHECK_OFF; - FPU_get_user(bcd, (u_char *) s+pos); + FPU_get_user(bcd, s+pos); RE_ENTRANT_CHECK_ON; l += bcd >> 4; l *= 10; @@ -349,7 +349,7 @@ } RE_ENTRANT_CHECK_OFF; - FPU_get_user(sign, (u_char *) s+9); + FPU_get_user(sign, s+9); sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive; RE_ENTRANT_CHECK_ON; @@ -369,7 +369,7 @@ /*===========================================================================*/ /* Put a long double into user memory */ -int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d) +int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double __user *d) { /* The only exception raised by an attempt to store to an @@ -382,9 +382,9 @@ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE, d, 10); - FPU_put_user(st0_ptr->sigl, (unsigned long *) d); - FPU_put_user(st0_ptr->sigh, (unsigned long *) ((u_char *)d + 4)); - FPU_put_user(exponent16(st0_ptr), (unsigned short *) ((u_char *)d + 8)); + FPU_put_user(st0_ptr->sigl, (unsigned long __user *) d); + FPU_put_user(st0_ptr->sigh, (unsigned long __user *) ((u_char __user *)d + 4)); + FPU_put_user(exponent16(st0_ptr), (unsigned short __user *) ((u_char __user *)d + 8)); RE_ENTRANT_CHECK_ON; return 1; @@ -398,9 +398,9 @@ /* Put out the QNaN indefinite */ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE,d,10); - FPU_put_user(0, (unsigned long *) d); - FPU_put_user(0xc0000000, 1 + (unsigned long *) d); - FPU_put_user(0xffff, 4 + (short *) d); + FPU_put_user(0, (unsigned long __user *) d); + FPU_put_user(0xc0000000, 1 + (unsigned long __user *) d); + FPU_put_user(0xffff, 4 + (short __user *) d); RE_ENTRANT_CHECK_ON; return 1; } @@ -411,7 +411,7 @@ /* Put a double into user memory */ -int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat) +int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat) { unsigned long l[2]; unsigned long increment = 0; /* avoid gcc warnings */ @@ -607,9 +607,9 @@ /* The masked response */ /* Put out the QNaN indefinite */ RE_ENTRANT_CHECK_OFF; - FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8); - FPU_put_user(0, (unsigned long *) dfloat); - FPU_put_user(0xfff80000, 1 + (unsigned long *) dfloat); + FPU_verify_area(VERIFY_WRITE,dfloat,8); + FPU_put_user(0, (unsigned long __user *) dfloat); + FPU_put_user(0xfff80000, 1 + (unsigned long __user *) dfloat); RE_ENTRANT_CHECK_ON; return 1; } @@ -620,9 +620,9 @@ l[1] |= 0x80000000; RE_ENTRANT_CHECK_OFF; - FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8); - FPU_put_user(l[0], (unsigned long *)dfloat); - FPU_put_user(l[1], 1 + (unsigned long *)dfloat); + FPU_verify_area(VERIFY_WRITE,dfloat,8); + FPU_put_user(l[0], (unsigned long __user *)dfloat); + FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat); RE_ENTRANT_CHECK_ON; return 1; @@ -630,7 +630,7 @@ /* Put a float into user memory */ -int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single) +int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single) { long templ = 0; unsigned long increment = 0; /* avoid gcc warnings */ @@ -826,8 +826,8 @@ /* The masked response */ /* Put out the QNaN indefinite */ RE_ENTRANT_CHECK_OFF; - FPU_verify_area(VERIFY_WRITE,(void *)single,4); - FPU_put_user(0xffc00000, (unsigned long *) single); + FPU_verify_area(VERIFY_WRITE,single,4); + FPU_put_user(0xffc00000, (unsigned long __user *) single); RE_ENTRANT_CHECK_ON; return 1; } @@ -845,8 +845,8 @@ templ |= 0x80000000; RE_ENTRANT_CHECK_OFF; - FPU_verify_area(VERIFY_WRITE,(void *)single,4); - FPU_put_user(templ,(unsigned long *) single); + FPU_verify_area(VERIFY_WRITE,single,4); + FPU_put_user(templ,(unsigned long __user *) single); RE_ENTRANT_CHECK_ON; return 1; @@ -854,7 +854,7 @@ /* Put a long long into user memory */ -int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d) +int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d) { FPU_REG t; long long tll; @@ -906,7 +906,7 @@ } RE_ENTRANT_CHECK_OFF; - FPU_verify_area(VERIFY_WRITE,(void *)d,8); + FPU_verify_area(VERIFY_WRITE,d,8); copy_to_user(d, &tll, 8); RE_ENTRANT_CHECK_ON; @@ -915,7 +915,7 @@ /* Put a long into user memory */ -int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d) +int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d) { FPU_REG t; int precision_loss; @@ -964,7 +964,7 @@ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE,d,4); - FPU_put_user(t.sigl, (unsigned long *) d); + FPU_put_user(t.sigl, (unsigned long __user *) d); RE_ENTRANT_CHECK_ON; return 1; @@ -972,7 +972,7 @@ /* Put a short into user memory */ -int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d) +int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d) { FPU_REG t; int precision_loss; @@ -1021,7 +1021,7 @@ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE,d,2); - FPU_put_user((short)t.sigl,(short *) d); + FPU_put_user((short)t.sigl, d); RE_ENTRANT_CHECK_ON; return 1; @@ -1029,7 +1029,7 @@ /* Put a packed bcd array into user memory */ -int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d) +int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d) { FPU_REG t; unsigned long long ll; @@ -1071,10 +1071,10 @@ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE,d,10); for ( i = 0; i < 7; i++) - FPU_put_user(0, (u_char *) d+i); /* These bytes "undefined" */ - FPU_put_user(0xc0, (u_char *) d+7); /* This byte "undefined" */ - FPU_put_user(0xff, (u_char *) d+8); - FPU_put_user(0xff, (u_char *) d+9); + FPU_put_user(0, d+i); /* These bytes "undefined" */ + FPU_put_user(0xc0, d+7); /* This byte "undefined" */ + FPU_put_user(0xff, d+8); + FPU_put_user(0xff, d+9); RE_ENTRANT_CHECK_ON; return 1; } @@ -1095,11 +1095,11 @@ b = FPU_div_small(&ll, 10); b |= (FPU_div_small(&ll, 10)) << 4; RE_ENTRANT_CHECK_OFF; - FPU_put_user(b,(u_char *) d+i); + FPU_put_user(b, d+i); RE_ENTRANT_CHECK_ON; } RE_ENTRANT_CHECK_OFF; - FPU_put_user(sign,(u_char *) d+9); + FPU_put_user(sign, d+9); RE_ENTRANT_CHECK_ON; return 1; @@ -1175,7 +1175,7 @@ /*===========================================================================*/ -u_char *fldenv(fpu_addr_modes addr_modes, u_char *s) +u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s) { unsigned short tag_word = 0; u_char tag; @@ -1187,13 +1187,13 @@ { RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_READ, s, 0x0e); - FPU_get_user(control_word, (unsigned short *) s); - FPU_get_user(partial_status, (unsigned short *) (s+2)); - FPU_get_user(tag_word, (unsigned short *) (s+4)); - FPU_get_user(instruction_address.offset, (unsigned short *) (s+6)); - FPU_get_user(instruction_address.selector, (unsigned short *) (s+8)); - FPU_get_user(operand_address.offset, (unsigned short *) (s+0x0a)); - FPU_get_user(operand_address.selector, (unsigned short *) (s+0x0c)); + FPU_get_user(control_word, (unsigned short __user *) s); + FPU_get_user(partial_status, (unsigned short __user *) (s+2)); + FPU_get_user(tag_word, (unsigned short __user *) (s+4)); + FPU_get_user(instruction_address.offset, (unsigned short __user *) (s+6)); + FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+8)); + FPU_get_user(operand_address.offset, (unsigned short __user *) (s+0x0a)); + FPU_get_user(operand_address.selector, (unsigned short __user *) (s+0x0c)); RE_ENTRANT_CHECK_ON; s += 0x0e; if ( addr_modes.default_mode == VM86 ) @@ -1207,14 +1207,14 @@ { RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_READ, s, 0x1c); - FPU_get_user(control_word, (unsigned short *) s); - FPU_get_user(partial_status, (unsigned short *) (s+4)); - FPU_get_user(tag_word, (unsigned short *) (s+8)); - FPU_get_user(instruction_address.offset, (unsigned long *) (s+0x0c)); - FPU_get_user(instruction_address.selector, (unsigned short *) (s+0x10)); - FPU_get_user(instruction_address.opcode, (unsigned short *) (s+0x12)); - FPU_get_user(operand_address.offset, (unsigned long *) (s+0x14)); - FPU_get_user(operand_address.selector, (unsigned long *) (s+0x18)); + FPU_get_user(control_word, (unsigned short __user *) s); + FPU_get_user(partial_status, (unsigned short __user *) (s+4)); + FPU_get_user(tag_word, (unsigned short __user *) (s+8)); + FPU_get_user(instruction_address.offset, (unsigned long __user *) (s+0x0c)); + FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+0x10)); + FPU_get_user(instruction_address.opcode, (unsigned short __user *) (s+0x12)); + FPU_get_user(operand_address.offset, (unsigned long __user *) (s+0x14)); + FPU_get_user(operand_address.selector, (unsigned long __user *) (s+0x18)); RE_ENTRANT_CHECK_ON; s += 0x1c; } @@ -1266,10 +1266,10 @@ } -void frstor(fpu_addr_modes addr_modes, u_char *data_address) +void frstor(fpu_addr_modes addr_modes, u_char __user *data_address) { int i, regnr; - u_char *s = fldenv(addr_modes, data_address); + u_char __user *s = fldenv(addr_modes, data_address); int offset = (top & 7) * 10, other = 80 - offset; /* Copy all registers in stack order. */ @@ -1291,7 +1291,7 @@ } -u_char *fstenv(fpu_addr_modes addr_modes, u_char *d) +u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d) { if ( (addr_modes.default_mode == VM86) || ((addr_modes.default_mode == PM16) @@ -1300,25 +1300,25 @@ RE_ENTRANT_CHECK_OFF; FPU_verify_area(VERIFY_WRITE,d,14); #ifdef PECULIAR_486 - FPU_put_user(control_word & ~0xe080, (unsigned long *) d); + FPU_put_user(control_word & ~0xe080, (unsigned long __user *) d); #else - FPU_put_user(control_word, (unsigned short *) d); + FPU_put_user(control_word, (unsigned short __user *) d); #endif /* PECULIAR_486 */ - FPU_put_user(status_word(), (unsigned short *) (d+2)); - FPU_put_user(fpu_tag_word, (unsigned short *) (d+4)); - FPU_put_user(instruction_address.offset, (unsigned short *) (d+6)); - FPU_put_user(operand_address.offset, (unsigned short *) (d+0x0a)); + FPU_put_user(status_word(), (unsigned short __user *) (d+2)); + FPU_put_user(fpu_tag_word, (unsigned short __user *) (d+4)); + FPU_put_user(instruction_address.offset, (unsigned short __user *) (d+6)); + FPU_put_user(operand_address.offset, (unsigned short __user *) (d+0x0a)); if ( addr_modes.default_mode == VM86 ) { FPU_put_user((instruction_address.offset & 0xf0000) >> 4, - (unsigned short *) (d+8)); + (unsigned short __user *) (d+8)); FPU_put_user((operand_address.offset & 0xf0000) >> 4, - (unsigned short *) (d+0x0c)); + (unsigned short __user *) (d+0x0c)); } else { - FPU_put_user(instruction_address.selector, (unsigned short *) (d+8)); - FPU_put_user(operand_address.selector, (unsigned short *) (d+0x0c)); + FPU_put_user(instruction_address.selector, (unsigned short __user *) (d+8)); + FPU_put_user(operand_address.selector, (unsigned short __user *) (d+0x0c)); } RE_ENTRANT_CHECK_ON; d += 0x0e; @@ -1348,9 +1348,9 @@ } -void fsave(fpu_addr_modes addr_modes, u_char *data_address) +void fsave(fpu_addr_modes addr_modes, u_char __user *data_address) { - u_char *d; + u_char __user *d; int offset = (top & 7) * 10, other = 80 - offset; d = fstenv(addr_modes, data_address); diff -Nru a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c --- a/arch/i386/mm/discontig.c 2004-06-26 17:09:18 -07:00 +++ b/arch/i386/mm/discontig.c 2004-06-26 17:09:18 -07:00 @@ -129,8 +129,11 @@ } /* - * Allocate memory for the pg_data_t via a crude pre-bootmem method - * We ought to relocate these onto their own node later on during boot. + * Allocate memory for the pg_data_t for this node via a crude pre-bootmem + * method. For node zero take this from the bottom of memory, for + * subsequent nodes place them at node_remap_start_vaddr which contains + * node local data in physically node local memory. See setup_memory() + * for details. */ static void __init allocate_pgdat(int nid) { diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c --- a/arch/i386/mm/fault.c 2004-06-26 17:09:15 -07:00 +++ b/arch/i386/mm/fault.c 2004-06-26 17:09:15 -07:00 @@ -24,7 +24,6 @@ #include #include -#include #include #include diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c --- a/arch/i386/mm/hugetlbpage.c 2004-06-26 17:09:20 -07:00 +++ b/arch/i386/mm/hugetlbpage.c 2004-06-26 17:09:20 -07:00 @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -245,8 +244,15 @@ ret = -ENOMEM; goto out; } - if (!pte_none(*pte)) - continue; + + if (!pte_none(*pte)) { + pmd_t *pmd = (pmd_t *) pte; + + page = pmd_page(*pmd); + pmd_clear(pmd); + dec_page_state(nr_page_table_pages); + page_cache_release(page); + } idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); diff -Nru a/arch/i386/mm/init.c b/arch/i386/mm/init.c --- a/arch/i386/mm/init.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/mm/init.c 2004-06-26 17:09:19 -07:00 @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff -Nru a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c --- a/arch/i386/mm/ioremap.c 2004-06-26 17:09:16 -07:00 +++ b/arch/i386/mm/ioremap.c 2004-06-26 17:09:16 -07:00 @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff -Nru a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c --- a/arch/i386/mm/pgtable.c 2004-06-26 17:09:21 -07:00 +++ b/arch/i386/mm/pgtable.c 2004-06-26 17:09:21 -07:00 @@ -33,7 +33,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { page = pgdat->node_mem_map + i; diff -Nru a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c --- a/arch/i386/pci/acpi.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/pci/acpi.c 2004-06-26 17:09:19 -07:00 @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "pci.h" struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) @@ -15,18 +17,31 @@ static int __init pci_acpi_init(void) { + struct pci_dev *dev = NULL; + if (pcibios_scanned) return 0; - if (!acpi_noirq) { - if (!acpi_pci_irq_init()) { - printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); - pcibios_scanned++; - pcibios_enable_irq = acpi_pci_irq_enable; - } else - printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n"); + if (acpi_noirq) + return 0; - } + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); + acpi_irq_penalty_init(); + pcibios_scanned++; + pcibios_enable_irq = acpi_pci_irq_enable; + + /* + * PCI IRQ routing is set up by pci_enable_device(), but we + * also do it here in case there are still broken drivers that + * don't use pci_enable_device(). + */ + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) + acpi_pci_irq_enable(dev); + +#ifdef CONFIG_X86_IO_APIC + if (acpi_ioapic) + print_IO_APIC(); +#endif return 0; } diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c --- a/arch/i386/pci/irq.c 2004-06-26 17:09:21 -07:00 +++ b/arch/i386/pci/irq.c 2004-06-26 17:09:21 -07:00 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,8 @@ #define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) #define PIRQ_VERSION 0x0100 -int broken_hp_bios_irq9; +static int broken_hp_bios_irq9; +int acer_tm360_irqrouting; static struct irq_routing_table *pirq_table; @@ -745,6 +747,14 @@ r->set(pirq_router_dev, dev, pirq, 11); } + /* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */ + if (acer_tm360_irqrouting && dev->irq == 11 && dev->vendor == PCI_VENDOR_ID_O2) { + pirq = 0x68; + mask = 0x400; + dev->irq = r->get(pirq_router_dev, dev, pirq); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } + /* * Find the best IRQ to assign: use the one * reported by the device if possible. @@ -893,6 +903,33 @@ } } +/* + * Work around broken HP Pavilion Notebooks which assign USB to + * IRQ 9 even though it is actually wired to IRQ 11 + */ +static int __init fix_broken_hp_bios_irq9(struct dmi_system_id *d) +{ + if (!broken_hp_bios_irq9) { + broken_hp_bios_irq9 = 1; + printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident); + } + return 0; +} + +static struct dmi_system_id __initdata pciirq_dmi_table[] = { + { + .callback = fix_broken_hp_bios_irq9, + .ident = "HP Pavilion N5400 Series Laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_BIOS_VERSION, "GE.M1.03"), + DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"), + DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"), + }, + }, + { } +}; + static int __init pcibios_irq_init(void) { DBG("PCI: IRQ init\n"); @@ -900,6 +937,8 @@ if (pcibios_enable_irq || raw_pci_ops == NULL) return 0; + dmi_check_system(pciirq_dmi_table); + pirq_table = pirq_find_routing_table(); #ifdef CONFIG_PCI_BIOS @@ -1000,7 +1039,7 @@ /* VIA bridges use interrupt line for apic/pci steering across the V-Link */ else if (interrupt_line_quirk) - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15); return 0; } diff -Nru a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c --- a/arch/i386/pci/visws.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/pci/visws.c 2004-06-26 17:09:19 -07:00 @@ -15,8 +15,6 @@ #include "pci.h" -int broken_hp_bios_irq9; - extern struct pci_raw_ops pci_direct_conf1; static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } diff -Nru a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c --- a/arch/i386/power/cpu.c 2004-06-26 17:09:19 -07:00 +++ b/arch/i386/power/cpu.c 2004-06-26 17:09:19 -07:00 @@ -27,7 +27,6 @@ #include static struct saved_context saved_context; -static void fix_processor_context(void); unsigned long saved_context_eax, saved_context_ebx; unsigned long saved_context_ecx, saved_context_edx; @@ -37,33 +36,38 @@ extern void enable_sep_cpu(void *); -void save_processor_state(void) +void __save_processor_state(struct saved_context *ctxt) { kernel_fpu_begin(); /* * descriptor tables */ - asm volatile ("sgdt %0" : "=m" (saved_context.gdt_limit)); - asm volatile ("sidt %0" : "=m" (saved_context.idt_limit)); - asm volatile ("sldt %0" : "=m" (saved_context.ldt)); - asm volatile ("str %0" : "=m" (saved_context.tr)); + asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); + asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); + asm volatile ("sldt %0" : "=m" (ctxt->ldt)); + asm volatile ("str %0" : "=m" (ctxt->tr)); /* * segment registers */ - asm volatile ("movw %%es, %0" : "=m" (saved_context.es)); - asm volatile ("movw %%fs, %0" : "=m" (saved_context.fs)); - asm volatile ("movw %%gs, %0" : "=m" (saved_context.gs)); - asm volatile ("movw %%ss, %0" : "=m" (saved_context.ss)); + asm volatile ("movw %%es, %0" : "=m" (ctxt->es)); + asm volatile ("movw %%fs, %0" : "=m" (ctxt->fs)); + asm volatile ("movw %%gs, %0" : "=m" (ctxt->gs)); + asm volatile ("movw %%ss, %0" : "=m" (ctxt->ss)); /* * control registers */ - asm volatile ("movl %%cr0, %0" : "=r" (saved_context.cr0)); - asm volatile ("movl %%cr2, %0" : "=r" (saved_context.cr2)); - asm volatile ("movl %%cr3, %0" : "=r" (saved_context.cr3)); - asm volatile ("movl %%cr4, %0" : "=r" (saved_context.cr4)); + asm volatile ("movl %%cr0, %0" : "=r" (ctxt->cr0)); + asm volatile ("movl %%cr2, %0" : "=r" (ctxt->cr2)); + asm volatile ("movl %%cr3, %0" : "=r" (ctxt->cr3)); + asm volatile ("movl %%cr4, %0" : "=r" (ctxt->cr4)); +} + +void save_processor_state(void) +{ + __save_processor_state(&saved_context); } static void @@ -75,32 +79,59 @@ mxcsr_feature_mask_init(); } -void restore_processor_state(void) + +static void fix_processor_context(void) +{ + int cpu = smp_processor_id(); + struct tss_struct * t = init_tss + cpu; + + set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ + cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff; + + load_TR_desc(); /* This does ltr */ + load_LDT(¤t->active_mm->context); /* This does lldt */ + + /* + * Now maybe reload the debug registers + */ + if (current->thread.debugreg[7]){ + loaddebug(¤t->thread, 0); + loaddebug(¤t->thread, 1); + loaddebug(¤t->thread, 2); + loaddebug(¤t->thread, 3); + /* no 4 and 5 */ + loaddebug(¤t->thread, 6); + loaddebug(¤t->thread, 7); + } + +} + +void __restore_processor_state(struct saved_context *ctxt) { /* * control registers */ - asm volatile ("movl %0, %%cr4" :: "r" (saved_context.cr4)); - asm volatile ("movl %0, %%cr3" :: "r" (saved_context.cr3)); - asm volatile ("movl %0, %%cr2" :: "r" (saved_context.cr2)); - asm volatile ("movl %0, %%cr0" :: "r" (saved_context.cr0)); + asm volatile ("movl %0, %%cr4" :: "r" (ctxt->cr4)); + asm volatile ("movl %0, %%cr3" :: "r" (ctxt->cr3)); + asm volatile ("movl %0, %%cr2" :: "r" (ctxt->cr2)); + asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0)); /* * segment registers */ - asm volatile ("movw %0, %%es" :: "r" (saved_context.es)); - asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs)); - asm volatile ("movw %0, %%gs" :: "r" (saved_context.gs)); - asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss)); + asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); + asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs)); + asm volatile ("movw %0, %%gs" :: "r" (ctxt->gs)); + asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); /* * now restore the descriptor tables to their proper values * ltr is done i fix_processor_context(). */ - asm volatile ("lgdt %0" :: "m" (saved_context.gdt_limit)); - asm volatile ("lidt %0" :: "m" (saved_context.idt_limit)); - asm volatile ("lldt %0" :: "m" (saved_context.ldt)); + asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); + asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); + asm volatile ("lldt %0" :: "m" (ctxt->ldt)); /* * sysenter MSRs @@ -112,31 +143,11 @@ do_fpu_end(); } -static void fix_processor_context(void) +void restore_processor_state(void) { - int cpu = smp_processor_id(); - struct tss_struct * t = init_tss + cpu; - - set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ - cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff; - - load_TR_desc(); /* This does ltr */ - load_LDT(¤t->active_mm->context); /* This does lldt */ - - /* - * Now maybe reload the debug registers - */ - if (current->thread.debugreg[7]){ - loaddebug(¤t->thread, 0); - loaddebug(¤t->thread, 1); - loaddebug(¤t->thread, 2); - loaddebug(¤t->thread, 3); - /* no 4 and 5 */ - loaddebug(¤t->thread, 6); - loaddebug(¤t->thread, 7); - } - + __restore_processor_state(&saved_context); } + EXPORT_SYMBOL(save_processor_state); EXPORT_SYMBOL(restore_processor_state); diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/ia64/Kconfig 2004-06-26 17:09:20 -07:00 @@ -149,20 +149,6 @@ default "6" if ITANIUM # align cache-sensitive data to 64 bytes -config MCKINLEY_ASTEP_SPECIFIC - bool "McKinley A-step specific code" - depends on MCKINLEY - help - Select this option to build a kernel for an IA-64 McKinley prototype - system with any A-stepping CPU. - -config MCKINLEY_A0_SPECIFIC - bool "McKinley A0/A1-step specific code" - depends on MCKINLEY_ASTEP_SPECIFIC - help - Select this option to build a kernel for an IA-64 McKinley prototype - system with an A0 or A1 stepping CPU. - config NUMA bool "NUMA support" depends on !IA64_HP_SIM diff -Nru a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig --- a/arch/ia64/configs/sn2_defconfig 2004-06-26 17:09:15 -07:00 +++ b/arch/ia64/configs/sn2_defconfig 2004-06-26 17:09:15 -07:00 @@ -14,18 +14,22 @@ # CONFIG_SWAP=y CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set CONFIG_LOG_BUF_SHIFT=20 CONFIG_HOTPLUG=y # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # @@ -60,7 +64,6 @@ CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set CONFIG_IA64_L1_CACHE_SHIFT=7 -# CONFIG_MCKINLEY_ASTEP_SPECIFIC is not set CONFIG_NUMA=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_DISCONTIGMEM=y @@ -70,12 +73,17 @@ CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=512 +# CONFIG_HOTPLUG_CPU is not set # CONFIG_PREEMPT is not set CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y + +# +# Firmware Drivers +# CONFIG_EFI_VARS=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set @@ -105,6 +113,7 @@ # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_USE_VECTOR is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -174,7 +183,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=m CONFIG_BLK_DEV_IDETAPE=m CONFIG_BLK_DEV_IDEFLOPPY=y @@ -218,6 +226,7 @@ # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -243,7 +252,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_REPORT_LUNS=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -281,7 +289,9 @@ CONFIG_SCSI_SATA_SVW=m CONFIG_SCSI_ATA_PIIX=m CONFIG_SCSI_SATA_PROMISE=m +# CONFIG_SCSI_SATA_SX4 is not set # CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIS is not set CONFIG_SCSI_SATA_VIA=m CONFIG_SCSI_SATA_VITESSE=y # CONFIG_SCSI_BUSLOGIC is not set @@ -298,6 +308,7 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y @@ -343,6 +354,7 @@ # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -389,8 +401,6 @@ CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m CONFIG_IPV6_TUNNEL=m -# CONFIG_DECNET is not set -CONFIG_BRIDGE=m CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_BRIDGE_NETFILTER=y @@ -452,6 +462,7 @@ CONFIG_IP_NF_ARP_MANGLE=m # CONFIG_IP_NF_COMPAT_IPCHAINS is not set # CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IP_NF_RAW is not set # # IPv6: Netfilter Configuration @@ -471,7 +482,9 @@ # # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set +CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -516,12 +529,14 @@ # Network testing # # CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set CONFIG_DUMMY=m CONFIG_BONDING=m CONFIG_EQUALIZER=m @@ -529,6 +544,11 @@ # CONFIG_ETHERTAP is not set # +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y @@ -582,7 +602,6 @@ CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m CONFIG_R8169=m -CONFIG_SIS190=m CONFIG_SK98LIN=m CONFIG_TIGON3=y @@ -591,6 +610,22 @@ # CONFIG_IXGB=m # CONFIG_IXGB_NAPI is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=m @@ -602,45 +637,11 @@ # CONFIG_PPP_BSDCOMP is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set CONFIG_NET_FC=y # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y # -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y - -# # ISDN subsystem # # CONFIG_ISDN is not set @@ -703,6 +704,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_NONSTANDARD=y # CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set # CONFIG_SYNCLINK is not set # CONFIG_SYNCLINKMP is not set # CONFIG_N_HDLC is not set @@ -713,18 +715,11 @@ # # Serial drivers # -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_HCDP=y -CONFIG_SERIAL_8250_ACPI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support # -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -740,7 +735,6 @@ # # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set CONFIG_EFI_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -852,6 +846,7 @@ # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y @@ -897,7 +892,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -968,6 +962,7 @@ # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m @@ -1019,4 +1014,5 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set diff -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig --- a/arch/ia64/defconfig 2004-06-26 17:09:15 -07:00 +++ b/arch/ia64/defconfig 2004-06-26 17:09:15 -07:00 @@ -26,6 +26,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_IOSCHED_NOOP=y @@ -66,7 +67,6 @@ CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set CONFIG_IA64_L1_CACHE_SHIFT=7 -# CONFIG_MCKINLEY_ASTEP_SPECIFIC is not set # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y # CONFIG_IA64_CYCLONE is not set @@ -74,6 +74,7 @@ CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=16 +# CONFIG_HOTPLUG_CPU is not set # CONFIG_PREEMPT is not set CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y @@ -178,7 +179,6 @@ # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set CONFIG_BLK_DEV_IDEFLOPPY=m @@ -220,6 +220,7 @@ # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -245,7 +246,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_REPORT_LUNS=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -282,6 +282,7 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set @@ -328,6 +329,7 @@ # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -573,7 +575,12 @@ # # IPMI # -# CONFIG_IPMI_HANDLER is not set +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_PANIC_EVENT=y +CONFIG_IPMI_PANIC_STRING=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m # # Watchdog Cards @@ -651,6 +658,7 @@ # CONFIG_SENSORS_LM83 is not set # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83L785TS is not set @@ -662,6 +670,7 @@ # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -688,6 +697,7 @@ # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_RIVA=m # CONFIG_FB_MATROX is not set @@ -852,6 +862,7 @@ # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -901,6 +912,7 @@ # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_TEST is not set # @@ -998,7 +1010,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -1083,7 +1094,7 @@ # CONFIG_IA64_GRANULE_64MB is not set CONFIG_DEBUG_KERNEL=y CONFIG_IA64_PRINT_HAZARDS=y -CONFIG_DISABLE_VHPT=y +# CONFIG_DISABLE_VHPT is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_IA64_EARLY_PRINTK_VGA is not set # CONFIG_DEBUG_SLAB is not set diff -Nru a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c --- a/arch/ia64/ia32/binfmt_elf32.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ia64/ia32/binfmt_elf32.c 2004-06-26 17:09:20 -07:00 @@ -197,6 +197,10 @@ } up_write(¤t->mm->mmap_sem); + /* Can't do it in ia64_elf32_init(). Needs to be done before calls to + elf32_map() */ + current->thread.ppl = ia32_init_pp_list(); + return 0; } diff -Nru a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S --- a/arch/ia64/ia32/ia32_entry.S 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/ia32/ia32_entry.S 2004-06-26 17:09:18 -07:00 @@ -349,7 +349,7 @@ data8 sys_setfsuid /* 16-bit version */ data8 sys_setfsgid /* 16-bit version */ data8 sys_llseek /* 140 */ - data8 sys32_getdents + data8 compat_sys_getdents data8 compat_sys_select data8 sys_flock data8 sys32_msync @@ -371,7 +371,7 @@ data8 sys_sched_get_priority_min /* 160 */ data8 sys32_sched_rr_get_interval data8 compat_sys_nanosleep - data8 sys_mremap + data8 sys32_mremap data8 sys_setresuid /* 16-bit version */ data8 sys32_getresuid16 /* 16-bit version */ /* 165 */ data8 sys_ni_syscall /* vm86 */ @@ -428,7 +428,7 @@ data8 sys_pivot_root data8 sys_mincore data8 sys_madvise - data8 sys_getdents64 /* 220 */ + data8 compat_sys_getdents64 /* 220 */ data8 compat_sys_fcntl64 data8 sys_ni_syscall /* reserved for TUX */ data8 sys_ni_syscall /* reserved for Security */ diff -Nru a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c --- a/arch/ia64/ia32/ia32_support.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ia64/ia32/ia32_support.c 2004-06-26 17:09:15 -07:00 @@ -218,6 +218,18 @@ ia32_exec_domain.signal_map = default_exec_domain.signal_map; ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; register_exec_domain(&ia32_exec_domain); + +#if PAGE_SHIFT > IA32_PAGE_SHIFT + { + extern kmem_cache_t *partial_page_cachep; + + partial_page_cachep = kmem_cache_create("partial_page_cache", + sizeof(struct partial_page), 0, 0, + NULL, NULL); + if (!partial_page_cachep) + panic("Cannot create partial page SLAB cache"); + } +#endif return 0; } diff -Nru a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h --- a/arch/ia64/ia32/ia32priv.h 2004-06-26 17:09:21 -07:00 +++ b/arch/ia64/ia32/ia32priv.h 2004-06-26 17:09:21 -07:00 @@ -1,5 +1,5 @@ -#ifndef _ASM_IA64_IA32_H -#define _ASM_IA64_IA32_H +#ifndef _ASM_IA64_IA32_PRIV_H +#define _ASM_IA64_IA32_PRIV_H #include @@ -9,6 +9,7 @@ #include #include +#include #include @@ -16,12 +17,39 @@ * 32 bit structures for IA32 support. */ -#define IA32_PAGE_SHIFT 12 /* 4KB pages */ #define IA32_PAGE_SIZE (1UL << IA32_PAGE_SHIFT) #define IA32_PAGE_MASK (~(IA32_PAGE_SIZE - 1)) #define IA32_PAGE_ALIGN(addr) (((addr) + IA32_PAGE_SIZE - 1) & IA32_PAGE_MASK) #define IA32_CLOCKS_PER_SEC 100 /* Cast in stone for IA32 Linux */ +/* + * partially mapped pages provide precise accounting of which 4k sub pages + * are mapped and which ones are not, thereby improving IA-32 compatibility. + */ +struct partial_page { + struct partial_page *next; /* linked list, sorted by address */ + struct rb_node pp_rb; + /* 64K is the largest "normal" page supported by ia64 ABI. So 4K*32 + * should suffice.*/ + unsigned int bitmap; + unsigned int base; +}; + +struct partial_page_list { + struct partial_page *pp_head; /* list head, points to the lowest + * addressed partial page */ + struct rb_root ppl_rb; + struct partial_page *pp_hint; /* pp_hint->next is the last + * accessed partial page */ + atomic_t pp_count; /* reference count */ +}; + +#if PAGE_SHIFT > IA32_PAGE_SHIFT +struct partial_page_list* ia32_init_pp_list (void); +#else +# define ia32_init_pp_list() 0 +#endif + /* sigcontext.h */ /* * As documented in the iBCS2 standard.. @@ -528,4 +556,4 @@ #endif /* !CONFIG_IA32_SUPPORT */ -#endif /* _ASM_IA64_IA32_H */ +#endif /* _ASM_IA64_IA32_PRIV_H */ diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c --- a/arch/ia64/ia32/sys_ia32.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/ia32/sys_ia32.c 2004-06-26 17:09:18 -07:00 @@ -8,6 +8,7 @@ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 2000-2003 Hewlett-Packard Co * David Mosberger-Tang + * Copyright (C) 2004 Gordon Jin * * These routines maintain argument size conversion between 32bit and 64bit * environment. @@ -48,6 +49,7 @@ #include #include #include +#include #include #include @@ -250,6 +252,508 @@ return ret; } +/* SLAB cache for partial_page structures */ +kmem_cache_t *partial_page_cachep; + +/* + * init partial_page_list. + * return 0 means kmalloc fail. + */ +struct partial_page_list* +ia32_init_pp_list(void) +{ + struct partial_page_list *p; + + if ((p = kmalloc(sizeof(*p), GFP_KERNEL)) == NULL) + return p; + p->pp_head = 0; + p->ppl_rb = RB_ROOT; + p->pp_hint = 0; + atomic_set(&p->pp_count, 1); + return p; +} + +/* + * Search for the partial page with @start in partial page list @ppl. + * If finds the partial page, return the found partial page. + * Else, return 0 and provide @pprev, @rb_link, @rb_parent to + * be used by later __ia32_insert_pp(). + */ +static struct partial_page * +__ia32_find_pp(struct partial_page_list *ppl, unsigned int start, + struct partial_page **pprev, struct rb_node ***rb_link, + struct rb_node **rb_parent) +{ + struct partial_page *pp; + struct rb_node **__rb_link, *__rb_parent, *rb_prev; + + pp = ppl->pp_hint; + if (pp && pp->base == start) + return pp; + + __rb_link = &ppl->ppl_rb.rb_node; + rb_prev = __rb_parent = NULL; + + while (*__rb_link) { + __rb_parent = *__rb_link; + pp = rb_entry(__rb_parent, struct partial_page, pp_rb); + + if (pp->base == start) { + ppl->pp_hint = pp; + return pp; + } else if (pp->base < start) { + rb_prev = __rb_parent; + __rb_link = &__rb_parent->rb_right; + } else { + __rb_link = &__rb_parent->rb_left; + } + } + + *rb_link = __rb_link; + *rb_parent = __rb_parent; + *pprev = NULL; + if (rb_prev) + *pprev = rb_entry(rb_prev, struct partial_page, pp_rb); + return NULL; +} + +/* + * insert @pp into @ppl. + */ +static void +__ia32_insert_pp(struct partial_page_list *ppl, struct partial_page *pp, + struct partial_page *prev, struct rb_node **rb_link, + struct rb_node *rb_parent) +{ + /* link list */ + if (prev) { + pp->next = prev->next; + prev->next = pp; + } else { + ppl->pp_head = pp; + if (rb_parent) + pp->next = rb_entry(rb_parent, + struct partial_page, pp_rb); + else + pp->next = NULL; + } + + /* link rb */ + rb_link_node(&pp->pp_rb, rb_parent, rb_link); + rb_insert_color(&pp->pp_rb, &ppl->ppl_rb); + + ppl->pp_hint = pp; +} + +/* + * delete @pp from partial page list @ppl. + */ +static void +__ia32_delete_pp(struct partial_page_list *ppl, struct partial_page *pp, + struct partial_page *prev) +{ + if (prev) { + prev->next = pp->next; + if (ppl->pp_hint == pp) + ppl->pp_hint = prev; + } else { + ppl->pp_head = pp->next; + if (ppl->pp_hint == pp) + ppl->pp_hint = pp->next; + } + rb_erase(&pp->pp_rb, &ppl->ppl_rb); + kmem_cache_free(partial_page_cachep, pp); +} + +static struct partial_page * +__pp_prev(struct partial_page *pp) +{ + struct rb_node *prev = rb_prev(&pp->pp_rb); + if (prev) + return rb_entry(prev, struct partial_page, pp_rb); + else + return NULL; +} + +/* + * Delete partial pages with address between @start and @end. + * @start and @end are page aligned. + */ +static void +__ia32_delete_pp_range(unsigned int start, unsigned int end) +{ + struct partial_page *pp, *prev; + struct rb_node **rb_link, *rb_parent; + + if (start >= end) + return; + + pp = __ia32_find_pp(current->thread.ppl, start, &prev, + &rb_link, &rb_parent); + if (pp) + prev = __pp_prev(pp); + else { + if (prev) + pp = prev->next; + else + pp = current->thread.ppl->pp_head; + } + + while (pp && pp->base < end) { + struct partial_page *tmp = pp->next; + __ia32_delete_pp(current->thread.ppl, pp, prev); + pp = tmp; + } +} + +/* + * Set the range between @start and @end in bitmap. + * @start and @end should be IA32 page aligned and in the same IA64 page. + */ +static int +__ia32_set_pp(unsigned int start, unsigned int end, int flags) +{ + struct partial_page *pp, *prev; + struct rb_node ** rb_link, *rb_parent; + unsigned int pstart, start_bit, end_bit, i; + + pstart = PAGE_START(start); + start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE; + end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE; + if (end_bit == 0) + end_bit = PAGE_SIZE / IA32_PAGE_SIZE; + pp = __ia32_find_pp(current->thread.ppl, pstart, &prev, + &rb_link, &rb_parent); + if (pp) { + for (i = start_bit; i < end_bit; i++) + set_bit(i, &pp->bitmap); + /* + * Check: if this partial page has been set to a full page, + * then delete it. + */ + if (find_first_zero_bit(&pp->bitmap, sizeof(pp->bitmap)*8) >= + PAGE_SIZE/IA32_PAGE_SIZE) { + __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp)); + } + return 0; + } + + /* + * MAP_FIXED may lead to overlapping mmap. + * In this case, the requested mmap area may already mmaped as a full + * page. So check vma before adding a new partial page. + */ + if (flags & MAP_FIXED) { + struct vm_area_struct *vma = find_vma(current->mm, pstart); + if (vma && vma->vm_start <= pstart) + return 0; + } + + /* new a partial_page */ + pp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL); + if (!pp) + return -ENOMEM; + pp->base = pstart; + pp->bitmap = 0; + for (i=start_bit; ibitmap)); + pp->next = NULL; + __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent); + return 0; +} + +/* + * @start and @end should be IA32 page aligned, but don't need to be in the + * same IA64 page. Split @start and @end to make sure they're in the same IA64 + * page, then call __ia32_set_pp(). + */ +static void +ia32_set_pp(unsigned int start, unsigned int end, int flags) +{ + down_write(¤t->mm->mmap_sem); + if (flags & MAP_FIXED) { + /* + * MAP_FIXED may lead to overlapping mmap. When this happens, + * a series of complete IA64 pages results in deletion of + * old partial pages in that range. + */ + __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end)); + } + + if (end < PAGE_ALIGN(start)) { + __ia32_set_pp(start, end, flags); + } else { + if (offset_in_page(start)) + __ia32_set_pp(start, PAGE_ALIGN(start), flags); + if (offset_in_page(end)) + __ia32_set_pp(PAGE_START(end), end, flags); + } + up_write(¤t->mm->mmap_sem); +} + +/* + * Unset the range between @start and @end in bitmap. + * @start and @end should be IA32 page aligned and in the same IA64 page. + * After doing that, if the bitmap is 0, then free the page and return 1, + * else return 0; + * If not find the partial page in the list, then + * If the vma exists, then the full page is set to a partial page; + * Else return -ENOMEM. + */ +static int +__ia32_unset_pp(unsigned int start, unsigned int end) +{ + struct partial_page *pp, *prev; + struct rb_node ** rb_link, *rb_parent; + unsigned int pstart, start_bit, end_bit, i; + struct vm_area_struct *vma; + + pstart = PAGE_START(start); + start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE; + end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE; + if (end_bit == 0) + end_bit = PAGE_SIZE / IA32_PAGE_SIZE; + + pp = __ia32_find_pp(current->thread.ppl, pstart, &prev, + &rb_link, &rb_parent); + if (pp) { + for (i = start_bit; i < end_bit; i++) + clear_bit(i, &pp->bitmap); + if (pp->bitmap == 0) { + __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp)); + return 1; + } + return 0; + } + + vma = find_vma(current->mm, pstart); + if (!vma || vma->vm_start > pstart) { + return -ENOMEM; + } + + /* new a partial_page */ + pp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL); + if (!pp) + return -ENOMEM; + pp->base = pstart; + pp->bitmap = 0; + for (i = 0; i < start_bit; i++) + set_bit(i, &(pp->bitmap)); + for (i = end_bit; i < PAGE_SIZE / IA32_PAGE_SIZE; i++) + set_bit(i, &(pp->bitmap)); + pp->next = NULL; + __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent); + return 0; +} + +/* + * Delete pp between PAGE_ALIGN(start) and PAGE_START(end) by calling + * __ia32_delete_pp_range(). Unset possible partial pages by calling + * __ia32_unset_pp(). + * The returned value see __ia32_unset_pp(). + */ +static int +ia32_unset_pp(unsigned int *startp, unsigned int *endp) +{ + unsigned int start = *startp, end = *endp; + int ret = 0; + + down_write(¤t->mm->mmap_sem); + + __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end)); + + if (end < PAGE_ALIGN(start)) { + ret = __ia32_unset_pp(start, end); + if (ret == 1) { + *startp = PAGE_START(start); + *endp = PAGE_ALIGN(end); + } + if (ret == 0) { + /* to shortcut sys_munmap() in sys32_munmap() */ + *startp = PAGE_START(start); + *endp = PAGE_START(end); + } + } else { + if (offset_in_page(start)) { + ret = __ia32_unset_pp(start, PAGE_ALIGN(start)); + if (ret == 1) + *startp = PAGE_START(start); + if (ret == 0) + *startp = PAGE_ALIGN(start); + if (ret < 0) + goto out; + } + if (offset_in_page(end)) { + ret = __ia32_unset_pp(PAGE_START(end), end); + if (ret == 1) + *endp = PAGE_ALIGN(end); + if (ret == 0) + *endp = PAGE_START(end); + } + } + + out: + up_write(¤t->mm->mmap_sem); + return ret; +} + +/* + * Compare the range between @start and @end with bitmap in partial page. + * @start and @end should be IA32 page aligned and in the same IA64 page. + */ +static int +__ia32_compare_pp(unsigned int start, unsigned int end) +{ + struct partial_page *pp, *prev; + struct rb_node ** rb_link, *rb_parent; + unsigned int pstart, start_bit, end_bit, size; + unsigned int first_bit, next_zero_bit; /* the first range in bitmap */ + + pstart = PAGE_START(start); + + pp = __ia32_find_pp(current->thread.ppl, pstart, &prev, + &rb_link, &rb_parent); + if (!pp) + return 1; + + start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE; + end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE; + size = sizeof(pp->bitmap) * 8; + first_bit = find_first_bit(&pp->bitmap, size); + next_zero_bit = find_next_zero_bit(&pp->bitmap, size, first_bit); + if ((start_bit < first_bit) || (end_bit > next_zero_bit)) { + /* exceeds the first range in bitmap */ + return -ENOMEM; + } else if ((start_bit == first_bit) && (end_bit == next_zero_bit)) { + first_bit = find_next_bit(&pp->bitmap, size, next_zero_bit); + if ((next_zero_bit < first_bit) && (first_bit < size)) + return 1; /* has next range */ + else + return 0; /* no next range */ + } else + return 1; +} + +/* + * @start and @end should be IA32 page aligned, but don't need to be in the + * same IA64 page. Split @start and @end to make sure they're in the same IA64 + * page, then call __ia32_compare_pp(). + * + * Take this as example: the range is the 1st and 2nd 4K page. + * Return 0 if they fit bitmap exactly, i.e. bitmap = 00000011; + * Return 1 if the range doesn't cover whole bitmap, e.g. bitmap = 00001111; + * Return -ENOMEM if the range exceeds the bitmap, e.g. bitmap = 00000001 or + * bitmap = 00000101. + */ +static int +ia32_compare_pp(unsigned int *startp, unsigned int *endp) +{ + unsigned int start = *startp, end = *endp; + int retval = 0; + + down_write(¤t->mm->mmap_sem); + + if (end < PAGE_ALIGN(start)) { + retval = __ia32_compare_pp(start, end); + if (retval == 0) { + *startp = PAGE_START(start); + *endp = PAGE_ALIGN(end); + } + } else { + if (offset_in_page(start)) { + retval = __ia32_compare_pp(start, + PAGE_ALIGN(start)); + if (retval == 0) + *startp = PAGE_START(start); + if (retval < 0) + goto out; + } + if (offset_in_page(end)) { + retval = __ia32_compare_pp(PAGE_START(end), end); + if (retval == 0) + *endp = PAGE_ALIGN(end); + } + } + + out: + up_write(¤t->mm->mmap_sem); + return retval; +} + +static void +__ia32_drop_pp_list(struct partial_page_list *ppl) +{ + struct partial_page *pp = ppl->pp_head; + + while (pp) { + struct partial_page *next = pp->next; + kmem_cache_free(partial_page_cachep, pp); + pp = next; + } + + kfree(ppl); +} + +void +ia32_drop_partial_page_list(struct task_struct *task) +{ + struct partial_page_list* ppl = task->thread.ppl; + + if (ppl && atomic_dec_and_test(&ppl->pp_count)) + __ia32_drop_pp_list(ppl); +} + +/* + * Copy current->thread.ppl to ppl (already initialized). + */ +static int +__ia32_copy_pp_list(struct partial_page_list *ppl) +{ + struct partial_page *pp, *tmp, *prev; + struct rb_node **rb_link, *rb_parent; + + ppl->pp_head = NULL; + ppl->pp_hint = NULL; + ppl->ppl_rb = RB_ROOT; + rb_link = &ppl->ppl_rb.rb_node; + rb_parent = NULL; + prev = NULL; + + for (pp = current->thread.ppl->pp_head; pp; pp = pp->next) { + tmp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + *tmp = *pp; + __ia32_insert_pp(ppl, tmp, prev, rb_link, rb_parent); + prev = tmp; + rb_link = &tmp->pp_rb.rb_right; + rb_parent = &tmp->pp_rb; + } + return 0; +} + +int +ia32_copy_partial_page_list(struct task_struct *p, unsigned long clone_flags) +{ + int retval = 0; + + if (clone_flags & CLONE_VM) { + atomic_inc(¤t->thread.ppl->pp_count); + p->thread.ppl = current->thread.ppl; + } else { + p->thread.ppl = ia32_init_pp_list(); + if (!p->thread.ppl) + return -ENOMEM; + down_write(¤t->mm->mmap_sem); + { + retval = __ia32_copy_pp_list(p->thread.ppl); + } + up_write(¤t->mm->mmap_sem); + } + + return retval; +} + static unsigned long emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags, loff_t off) @@ -263,6 +767,7 @@ pend = PAGE_ALIGN(end); if (flags & MAP_FIXED) { + ia32_set_pp((unsigned int)start, (unsigned int)end, flags); if (start > pstart) { if (flags & MAP_SHARED) printk(KERN_INFO @@ -274,7 +779,7 @@ return ret; pstart += PAGE_SIZE; if (pstart >= pend) - return start; /* done */ + goto out; /* done */ } if (end < pend) { if (flags & MAP_SHARED) @@ -287,7 +792,7 @@ return ret; pend -= PAGE_SIZE; if (pstart >= pend) - return start; /* done */ + goto out; /* done */ } } else { /* @@ -341,6 +846,10 @@ if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0) return -EINVAL; } + + if (!(flags & MAP_FIXED)) + ia32_set_pp((unsigned int)start, (unsigned int)end, flags); +out: return start; } @@ -478,11 +987,16 @@ #if PAGE_SHIFT <= IA32_PAGE_SHIFT ret = sys_munmap(start, end - start); #else + if (OFFSET4K(start)) + return -EINVAL; + + end = IA32_PAGE_ALIGN(end); if (start >= end) return -EINVAL; - start = PAGE_ALIGN(start); - end = PAGE_START(end); + ret = ia32_unset_pp(&start, &end); + if (ret < 0) + return ret; if (start >= end) return 0; @@ -521,7 +1035,7 @@ asmlinkage long sys32_mprotect (unsigned int start, unsigned int len, int prot) { - unsigned long end = start + len; + unsigned int end = start + len; #if PAGE_SHIFT > IA32_PAGE_SHIFT long retval = 0; #endif @@ -538,6 +1052,11 @@ if (end < start) return -EINVAL; + retval = ia32_compare_pp(&start, &end); + + if (retval < 0) + return retval; + down(&ia32_mmap_sem); { if (offset_in_page(start)) { @@ -565,6 +1084,59 @@ up(&ia32_mmap_sem); return retval; #endif +} + +asmlinkage long +sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len, + unsigned int flags, unsigned int new_addr) +{ + long ret; + +#if PAGE_SHIFT <= IA32_PAGE_SHIFT + ret = sys_mremap(addr, old_len, new_len, flags, new_addr); +#else + unsigned int old_end, new_end; + + if (OFFSET4K(addr)) + return -EINVAL; + + old_len = IA32_PAGE_ALIGN(old_len); + new_len = IA32_PAGE_ALIGN(new_len); + old_end = addr + old_len; + new_end = addr + new_len; + + if (!new_len) + return -EINVAL; + + if ((flags & MREMAP_FIXED) && (OFFSET4K(new_addr))) + return -EINVAL; + + if (old_len >= new_len) { + ret = sys32_munmap(addr + new_len, old_len - new_len); + if (ret && old_len != new_len) + return ret; + ret = addr; + if (!(flags & MREMAP_FIXED) || (new_addr == addr)) + return ret; + old_len = new_len; + } + + addr = PAGE_START(addr); + old_len = PAGE_ALIGN(old_end) - addr; + new_len = PAGE_ALIGN(new_end) - addr; + + down(&ia32_mmap_sem); + { + ret = sys_mremap(addr, old_len, new_len, flags, new_addr); + } + up(&ia32_mmap_sem); + + if ((ret >= 0) && (old_len < new_len)) { + /* mremap expanded successfully */ + ia32_set_pp(old_end, new_end, flags); + } +#endif + return ret; } asmlinkage long diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/kernel/acpi.c 2004-06-26 17:09:18 -07:00 @@ -521,9 +521,14 @@ #endif /* CONFIG_ACPI_NUMA */ unsigned int -acpi_register_gsi (u32 gsi, int polarity, int trigger) +acpi_register_gsi (u32 gsi, int edge_level, int active_high_low) { - return acpi_register_irq(gsi, polarity, trigger); + if (has_8259 && gsi < 16) + return isa_irq_to_vector(gsi); + + return iosapic_register_intr(gsi, + (active_high_low == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (edge_level == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); } EXPORT_SYMBOL(acpi_register_gsi); @@ -548,7 +553,7 @@ if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) acpi_legacy_devices = 1; - acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE); + acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return 0; } @@ -661,17 +666,5 @@ } return 0; } - -int -acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) -{ - if (has_8259 && gsi < 16) - return isa_irq_to_vector(gsi); - - return iosapic_register_intr(gsi, - (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); -} -EXPORT_SYMBOL(acpi_register_irq); #endif /* CONFIG_ACPI_BOOT */ diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S --- a/arch/ia64/kernel/entry.S 2004-06-26 17:09:16 -07:00 +++ b/arch/ia64/kernel/entry.S 2004-06-26 17:09:16 -07:00 @@ -179,17 +179,19 @@ .body adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13 + movl r25=init_task mov r27=IA64_KR(CURRENT_STACK) + adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0 dep r20=0,in0,61,3 // physical address of "current" ;; st8 [r22]=sp // save kernel stack pointer of old task shr.u r26=r20,IA64_GRANULE_SHIFT - adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0 + cmp.eq p7,p6=r25,in0 ;; /* * If we've already mapped this task's page, we can skip doing it again. */ - cmp.eq p7,p6=r26,r27 +(p6) cmp.eq p7,p6=r26,r27 (p6) br.cond.dpnt .map ;; .done: diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S --- a/arch/ia64/kernel/head.S 2004-06-26 17:09:19 -07:00 +++ b/arch/ia64/kernel/head.S 2004-06-26 17:09:19 -07:00 @@ -154,6 +154,10 @@ #endif ;; tpa r3=r2 // r3 == phys addr of task struct + ;; + shr.u r16=r3,IA64_GRANULE_SHIFT +(isBP) br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it + // load mapping for stack (virtaddr in r2, physaddr in r3) rsm psr.ic movl r17=PAGE_KERNEL @@ -165,7 +169,6 @@ dep r2=-1,r3,61,3 // IMVA of task ;; mov r17=rr[r2] - shr.u r16=r3,IA64_GRANULE_SHIFT ;; dep r17=0,r17,8,24 ;; @@ -180,6 +183,7 @@ srlz.d ;; +.load_current: // load the "current" pointer (r13) and ar.k6 with the current task mov IA64_KR(CURRENT)=r2 // virtual address mov IA64_KR(CURRENT_STACK)=r16 diff -Nru a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c --- a/arch/ia64/kernel/init_task.c 2004-06-26 17:09:21 -07:00 +++ b/arch/ia64/kernel/init_task.c 2004-06-26 17:09:21 -07:00 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c --- a/arch/ia64/kernel/iosapic.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/kernel/iosapic.c 2004-06-26 17:09:18 -07:00 @@ -100,7 +100,6 @@ #endif static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; -extern cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS]; /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */ @@ -335,21 +334,6 @@ #endif } -static inline void move_irq(int irq) -{ - /* note - we hold desc->lock */ - cpumask_t tmp; - irq_desc_t *desc = irq_descp(irq); - - if (!cpus_empty(pending_irq_cpumask[irq])) { - cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); - if (unlikely(!cpus_empty(tmp))) { - desc->handler->set_affinity(irq, pending_irq_cpumask[irq]); - } - cpus_clear(pending_irq_cpumask[irq]); - } -} - /* * Handlers for level-triggered interrupts. */ @@ -483,7 +467,7 @@ index = find_iosapic(gsi); if (index < 0) { - printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi); + printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi); return; } @@ -512,6 +496,42 @@ } } +static unsigned int +get_target_cpu (void) +{ +#ifdef CONFIG_SMP + static int cpu = -1; + + /* + * If the platform supports redirection via XTP, let it + * distribute interrupts. + */ + if (smp_int_redirect & SMP_IRQ_REDIRECTION) + return hard_smp_processor_id(); + + /* + * Some interrupts (ACPI SCI, for instance) are registered + * before the BSP is marked as online. + */ + if (!cpu_online(smp_processor_id())) + return hard_smp_processor_id(); + + /* + * Otherwise, round-robin interrupt vectors across all the + * processors. (It'd be nice if we could be smarter in the + * case of NUMA.) + */ + do { + if (++cpu >= NR_CPUS) + cpu = 0; + } while (!cpu_online(cpu)); + + return cpu_physical_id(cpu); +#else + return hard_smp_processor_id(); +#endif +} + /* * ACPI can describe IOSAPIC interrupts via static tables and namespace * methods. This provides an interface to register those interrupts and @@ -522,21 +542,35 @@ unsigned long polarity, unsigned long trigger) { int vector; - unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; + unsigned int dest; + unsigned long flags; - vector = gsi_to_vector(gsi); - if (vector < 0) - vector = assign_irq_vector(AUTO_ASSIGN); + /* + * If this GSI has already been registered (i.e., it's a + * shared interrupt, or we lost a race to register it), + * don't touch the RTE. + */ + spin_lock_irqsave(&iosapic_lock, flags); + { + vector = gsi_to_vector(gsi); + if (vector > 0) { + spin_unlock_irqrestore(&iosapic_lock, flags); + return vector; + } - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, - polarity, trigger); + vector = assign_irq_vector(AUTO_ASSIGN); + dest = get_target_cpu(); + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, + polarity, trigger); + } + spin_unlock_irqrestore(&iosapic_lock, flags); - printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", - gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), - (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector); + printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", + gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), + (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), + cpu_logical_id(dest), dest, vector); - /* program the IOSAPIC routing table */ - set_rte(vector, dest, 0); + set_rte(vector, dest, 1); return vector; } @@ -549,8 +583,9 @@ int iosapic_vector, u16 eid, u16 id, unsigned long polarity, unsigned long trigger) { + static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"}; unsigned char delivery; - int vector; + int vector, mask = 0; unsigned int dest = ((id << 8) | eid) & 0xffff; switch (int_type) { @@ -570,21 +605,22 @@ case ACPI_INTERRUPT_CPEI: vector = IA64_CPE_VECTOR; delivery = IOSAPIC_LOWEST_PRIORITY; + mask = 1; break; default: - printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type\n"); + printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type); return -1; } - register_intr(gsi, vector, delivery, polarity, - trigger); + register_intr(gsi, vector, delivery, polarity, trigger); - printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", - int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), - (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector); + printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", + int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", + int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), + (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), + cpu_logical_id(dest), dest, vector); - /* program the IOSAPIC routing table */ - set_rte(vector, dest, 0); + set_rte(vector, dest, mask); return vector; } @@ -599,18 +635,18 @@ unsigned long trigger) { int vector; - unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; + unsigned int dest = hard_smp_processor_id(); vector = isa_irq_to_vector(isa_irq); register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); - DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n", - isa_irq, gsi, polarity == IOSAPIC_POL_HIGH ? "high" : "low", - trigger == IOSAPIC_EDGE ? "edge" : "level", dest, vector); + DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n", + isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level", + polarity == IOSAPIC_POL_HIGH ? "high" : "low", + cpu_logical_id(dest), dest, vector); - /* program the IOSAPIC routing table */ - set_rte(vector, dest, 0); + set_rte(vector, dest, 1); } void __init @@ -665,104 +701,3 @@ iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } } - -void -iosapic_enable_intr (unsigned int vector) -{ - unsigned int dest; - irq_desc_t *desc; - - /* - * In the case of a shared interrupt, do not re-route the vector, and - * especially do not mask a running interrupt (startup will not get - * called for a shared interrupt). - */ - desc = irq_descp(vector); - if (desc->action) - return; - -#ifdef CONFIG_SMP - /* - * For platforms that do not support interrupt redirect via the XTP interface, we - * can round-robin the PCI device interrupts to the processors - */ - if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) { - static int cpu_index = -1; - - do - if (++cpu_index >= NR_CPUS) - cpu_index = 0; - while (!cpu_online(cpu_index)); - - dest = cpu_physical_id(cpu_index) & 0xffff; - } else { - /* - * Direct the interrupt vector to the current cpu, platform redirection - * will distribute them. - */ - dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; - } -#else - /* direct the interrupt vector to the running cpu id */ - dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; -#endif - set_rte(vector, dest, 1); - - printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n", - vector, dest); -} - -#ifdef CONFIG_ACPI_PCI - -void __init -iosapic_parse_prt (void) -{ - struct acpi_prt_entry *entry; - struct list_head *node; - unsigned int gsi; - int vector; - char pci_id[16]; - struct hw_interrupt_type *irq_type = &irq_type_iosapic_level; - irq_desc_t *idesc; - - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); - - /* We're only interested in static (non-link) entries. */ - if (entry->link.handle) - continue; - - gsi = entry->link.index; - - vector = gsi_to_vector(gsi); - if (vector < 0) { - if (find_iosapic(gsi) < 0) - continue; - - /* allocate a vector for this interrupt line */ - if (pcat_compat && (gsi < 16)) - vector = isa_irq_to_vector(gsi); - else - /* new GSI; allocate a vector for it */ - vector = assign_irq_vector(AUTO_ASSIGN); - - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, - IOSAPIC_LEVEL); - } - entry->irq = vector; - snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]", - entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin); - - /* - * If vector was previously initialized to a different - * handler, re-initialize. - */ - idesc = irq_descp(vector); - if (idesc->handler != irq_type) - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, - IOSAPIC_LEVEL); - - } -} - -#endif /* CONFIG_ACPI */ diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c --- a/arch/ia64/kernel/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ia64/kernel/irq.c 2004-06-26 17:09:20 -07:00 @@ -607,7 +607,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; @@ -1017,6 +1017,22 @@ return full_count; } + +void move_irq(int irq) +{ + /* note - we hold desc->lock */ + cpumask_t tmp; + irq_desc_t *desc = irq_descp(irq); + + if (!cpus_empty(pending_irq_cpumask[irq])) { + cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); + if (unlikely(!cpus_empty(tmp))) { + desc->handler->set_affinity(irq, pending_irq_cpumask[irq]); + } + cpus_clear(pending_irq_cpumask[irq]); + } +} + #endif /* CONFIG_SMP */ diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c --- a/arch/ia64/kernel/mca.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/kernel/mca.c 2004-06-26 17:09:18 -07:00 @@ -108,6 +108,7 @@ #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */ #define MIN_CPE_POLL_INTERVAL (2*60*HZ) /* 2 minutes */ #define CMC_POLL_INTERVAL (1*60*HZ) /* 1 minute */ +#define CPE_HISTORY_LENGTH 5 #define CMC_HISTORY_LENGTH 5 static struct timer_list cpe_poll_timer; @@ -127,6 +128,8 @@ */ static int cpe_poll_enabled = 1; +static int cpe_vector = -1; + extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); /* @@ -267,20 +270,65 @@ */ #ifndef PLATFORM_MCA_HANDLERS +#ifdef CONFIG_ACPI + static irqreturn_t ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) { - IA64_MCA_DEBUG("%s: received interrupt. CPU:%d vector = %#x\n", - __FUNCTION__, smp_processor_id(), cpe_irq); + static unsigned long cpe_history[CPE_HISTORY_LENGTH]; + static int index; + static spinlock_t cpe_history_lock = SPIN_LOCK_UNLOCKED; + + IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n", + __FUNCTION__, cpe_irq, smp_processor_id()); /* SAL spec states this should run w/ interrupts enabled */ local_irq_enable(); - /* Get the CMC error record and log it */ + /* Get the CPE error record and log it */ ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE); + + spin_lock(&cpe_history_lock); + if (!cpe_poll_enabled && cpe_vector >= 0) { + + int i, count = 1; /* we know 1 happened now */ + unsigned long now = jiffies; + + for (i = 0; i < CPE_HISTORY_LENGTH; i++) { + if (now - cpe_history[i] <= HZ) + count++; + } + + IA64_MCA_DEBUG(KERN_INFO "CPE threshold %d/%d\n", count, CPE_HISTORY_LENGTH); + if (count >= CPE_HISTORY_LENGTH) { + + cpe_poll_enabled = 1; + spin_unlock(&cpe_history_lock); + disable_irq_nosync(local_vector_to_irq(IA64_CPE_VECTOR)); + + /* + * Corrected errors will still be corrected, but + * make sure there's a log somewhere that indicates + * something is generating more than we can handle. + */ + printk(KERN_WARNING "WARNING: Switching to polling CPE handler; error records may be lost\n"); + + mod_timer(&cpe_poll_timer, jiffies + MIN_CPE_POLL_INTERVAL); + + /* lock already released, get out now */ + return IRQ_HANDLED; + } else { + cpe_history[index++] = now; + if (index == CPE_HISTORY_LENGTH) + index = 0; + } + } + spin_unlock(&cpe_history_lock); return IRQ_HANDLED; } +#endif /* CONFIG_ACPI */ + static void show_min_state (pal_min_state_area_t *minstate) { @@ -901,7 +949,7 @@ * handled */ static irqreturn_t -ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) +ia64_mca_cmc_int_caller(int cmc_irq, void *arg, struct pt_regs *ptregs) { static int start_count = -1; unsigned int cpuid; @@ -912,7 +960,7 @@ if (start_count == -1) start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC); - ia64_mca_cmc_int_handler(cpe_irq, arg, ptregs); + ia64_mca_cmc_int_handler(cmc_irq, arg, ptregs); for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); @@ -967,11 +1015,13 @@ * Outputs * handled */ +#ifdef CONFIG_ACPI + static irqreturn_t ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) { static int start_count = -1; - static int poll_time = MAX_CPE_POLL_INTERVAL; + static int poll_time = MIN_CPE_POLL_INTERVAL; unsigned int cpuid; cpuid = smp_processor_id(); @@ -989,20 +1039,30 @@ } else { /* * If a log was recorded, increase our polling frequency, - * otherwise, backoff. + * otherwise, backoff or return to interrupt mode. */ if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) { poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time / 2); - } else { + } else if (cpe_vector < 0) { poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2); + } else { + poll_time = MIN_CPE_POLL_INTERVAL; + + printk(KERN_WARNING "Returning to interrupt driven CPE handler\n"); + enable_irq(local_vector_to_irq(IA64_CPE_VECTOR)); + cpe_poll_enabled = 0; } + + if (cpe_poll_enabled) + mod_timer(&cpe_poll_timer, jiffies + poll_time); start_count = -1; - mod_timer(&cpe_poll_timer, jiffies + poll_time); } return IRQ_HANDLED; } +#endif /* CONFIG_ACPI */ + /* * ia64_mca_cpe_poll * @@ -1240,21 +1300,23 @@ register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); #ifdef CONFIG_ACPI - /* Setup the CPE interrupt vector */ + /* Setup the CPEI/P vector and handler */ { irq_desc_t *desc; unsigned int irq; - int cpev = acpi_request_vector(ACPI_INTERRUPT_CPEI); - if (cpev >= 0) { + cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI); + + if (cpe_vector >= 0) { for (irq = 0; irq < NR_IRQS; ++irq) - if (irq_to_vector(irq) == cpev) { + if (irq_to_vector(irq) == cpe_vector) { desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; setup_irq(irq, &mca_cpe_irqaction); } - ia64_mca_register_cpev(cpev); + ia64_mca_register_cpev(cpe_vector); } + register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); } #endif @@ -1294,9 +1356,10 @@ #ifdef CONFIG_ACPI /* If platform doesn't support CPEI, get the timer going. */ - if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0 && cpe_poll_enabled) { - register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); + if (cpe_vector < 0 && cpe_poll_enabled) { ia64_mca_cpe_poll(0UL); + } else { + cpe_poll_enabled = 0; } #endif diff -Nru a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c --- a/arch/ia64/kernel/palinfo.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ia64/kernel/palinfo.c 2004-06-26 17:09:15 -07:00 @@ -515,10 +515,10 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "Enable Cache Line Repl. Exclusive", "Enable Cache Line Repl. Shared", + "Enable Cache Line Repl. Exclusive", "Disable Transaction Queuing", - "Disable Reponse Error Checking", + "Disable Response Error Checking", "Disable Bus Error Checking", "Disable Bus Requester Internal Error Signalling", "Disable Bus Requester Error Signalling", diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ia64/kernel/perfmon.c 2004-06-26 17:09:20 -07:00 @@ -311,6 +311,7 @@ unsigned int ctx_cpu; /* cpu to which perfmon is applied (system wide) */ int ctx_fd; /* file descriptor used my this context */ + pfm_ovfl_arg_t ctx_ovfl_arg; /* argument to custom buffer format handler */ pfm_buffer_fmt_t *ctx_buf_fmt; /* buffer format callbacks */ void *ctx_smpl_hdr; /* points to sampling buffer header kernel vaddr */ @@ -4584,31 +4585,6 @@ return 0; } -static void -pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs) -{ - struct task_struct *task = ctx->ctx_task; - - ia64_psr(regs)->up = 0; - ia64_psr(regs)->sp = 1; - - if (GET_PMU_OWNER() == task) { - DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid)); - SET_PMU_OWNER(NULL, NULL); - } - - /* - * disconnect the task from the context and vice-versa - */ - PFM_SET_WORK_PENDING(task, 0); - - task->thread.pfm_context = NULL; - task->thread.flags &= ~IA64_THREAD_PM_VALID; - - DPRINT(("force cleanupf for [%d]\n", task->pid)); -} - - /* * called only from exit_thread(): task == current @@ -5185,7 +5161,7 @@ static void pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs) { - pfm_ovfl_arg_t ovfl_arg; + pfm_ovfl_arg_t *ovfl_arg; unsigned long mask; unsigned long old_val, ovfl_val, new_val; unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL, reset_pmds; @@ -5272,7 +5248,8 @@ int j, k, ret = 0; int this_cpu = smp_processor_id(); - pmd_mask = ovfl_pmds >> PMU_FIRST_COUNTER; + pmd_mask = ovfl_pmds >> PMU_FIRST_COUNTER; + ovfl_arg = &ctx->ctx_ovfl_arg; prefetch(ctx->ctx_smpl_hdr); @@ -5282,15 +5259,15 @@ if ((pmd_mask & 0x1) == 0) continue; - ovfl_arg.ovfl_pmd = (unsigned char )i; - ovfl_arg.ovfl_notify = ovfl_notify & mask ? 1 : 0; - ovfl_arg.active_set = 0; - ovfl_arg.ovfl_ctrl.val = 0; /* module must fill in all fields */ - ovfl_arg.smpl_pmds[0] = smpl_pmds = ctx->ctx_pmds[i].smpl_pmds[0]; - - ovfl_arg.pmd_value = ctx->ctx_pmds[i].val; - ovfl_arg.pmd_last_reset = ctx->ctx_pmds[i].lval; - ovfl_arg.pmd_eventid = ctx->ctx_pmds[i].eventid; + ovfl_arg->ovfl_pmd = (unsigned char )i; + ovfl_arg->ovfl_notify = ovfl_notify & mask ? 1 : 0; + ovfl_arg->active_set = 0; + ovfl_arg->ovfl_ctrl.val = 0; /* module must fill in all fields */ + ovfl_arg->smpl_pmds[0] = smpl_pmds = ctx->ctx_pmds[i].smpl_pmds[0]; + + ovfl_arg->pmd_value = ctx->ctx_pmds[i].val; + ovfl_arg->pmd_last_reset = ctx->ctx_pmds[i].lval; + ovfl_arg->pmd_eventid = ctx->ctx_pmds[i].eventid; /* * copy values of pmds of interest. Sampling format may copy them @@ -5299,8 +5276,8 @@ if (smpl_pmds) { for(j=0, k=0; smpl_pmds; j++, smpl_pmds >>=1) { if ((smpl_pmds & 0x1) == 0) continue; - ovfl_arg.smpl_pmds_values[k++] = PMD_IS_COUNTING(j) ? pfm_read_soft_counter(ctx, j) : ia64_get_pmd(j); - DPRINT_ovfl(("smpl_pmd[%d]=pmd%u=0x%lx\n", k-1, j, ovfl_arg.smpl_pmds_values[k-1])); + ovfl_arg->smpl_pmds_values[k++] = PMD_IS_COUNTING(j) ? pfm_read_soft_counter(ctx, j) : ia64_get_pmd(j); + DPRINT_ovfl(("smpl_pmd[%d]=pmd%u=0x%lx\n", k-1, j, ovfl_arg->smpl_pmds_values[k-1])); } } @@ -5311,7 +5288,7 @@ /* * call custom buffer format record (handler) routine */ - ret = (*ctx->ctx_buf_fmt->fmt_handler)(task, ctx->ctx_smpl_hdr, &ovfl_arg, regs, tstamp); + ret = (*ctx->ctx_buf_fmt->fmt_handler)(task, ctx->ctx_smpl_hdr, ovfl_arg, regs, tstamp); end_cycles = ia64_get_itc(); @@ -5319,13 +5296,13 @@ * For those controls, we take the union because they have * an all or nothing behavior. */ - ovfl_ctrl.bits.notify_user |= ovfl_arg.ovfl_ctrl.bits.notify_user; - ovfl_ctrl.bits.block_task |= ovfl_arg.ovfl_ctrl.bits.block_task; - ovfl_ctrl.bits.mask_monitoring |= ovfl_arg.ovfl_ctrl.bits.mask_monitoring; + ovfl_ctrl.bits.notify_user |= ovfl_arg->ovfl_ctrl.bits.notify_user; + ovfl_ctrl.bits.block_task |= ovfl_arg->ovfl_ctrl.bits.block_task; + ovfl_ctrl.bits.mask_monitoring |= ovfl_arg->ovfl_ctrl.bits.mask_monitoring; /* * build the bitmask of pmds to reset now */ - if (ovfl_arg.ovfl_ctrl.bits.reset_ovfl_pmds) reset_pmds |= mask; + if (ovfl_arg->ovfl_ctrl.bits.reset_ovfl_pmds) reset_pmds |= mask; pfm_stats[this_cpu].pfm_smpl_handler_cycles += end_cycles - start_cycles; } @@ -5793,6 +5770,32 @@ } #ifdef CONFIG_SMP + +static void +pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs) +{ + struct task_struct *task = ctx->ctx_task; + + ia64_psr(regs)->up = 0; + ia64_psr(regs)->sp = 1; + + if (GET_PMU_OWNER() == task) { + DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid)); + SET_PMU_OWNER(NULL, NULL); + } + + /* + * disconnect the task from the context and vice-versa + */ + PFM_SET_WORK_PENDING(task, 0); + + task->thread.pfm_context = NULL; + task->thread.flags &= ~IA64_THREAD_PM_VALID; + + DPRINT(("force cleanup for [%d]\n", task->pid)); +} + + /* * in 2.6, interrupts are masked when we come here and the runqueue lock is held */ diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c --- a/arch/ia64/kernel/process.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/kernel/process.c 2004-06-26 17:09:18 -07:00 @@ -439,6 +439,10 @@ ia32_save_state(p); if (clone_flags & CLONE_SETTLS) retval = ia32_clone_tls(p, child_ptregs); + + /* Copy partially mapped page list */ + if (!retval) + retval = ia32_copy_partial_page_list(p, clone_flags); } #endif @@ -672,6 +676,8 @@ /* drop floating-point and debug-register state if it exists: */ current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); ia64_drop_fpu(current); + if (IS_IA32_PROCESS(ia64_task_regs(current))) + ia32_drop_partial_page_list(current); } /* @@ -691,6 +697,8 @@ if (current->thread.flags & IA64_THREAD_DBG_VALID) pfm_release_debug_registers(current); #endif + if (IS_IA32_PROCESS(ia64_task_regs(current))) + ia32_drop_partial_page_list(current); } unsigned long diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ia64/kernel/setup.c 2004-06-26 17:09:16 -07:00 @@ -88,10 +88,6 @@ unsigned long ia64_max_iommu_merge_mask = ~0UL; EXPORT_SYMBOL(ia64_max_iommu_merge_mask); -#define COMMAND_LINE_SIZE 512 - -char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */ - /* * We use a special marker for the end of memory and it uses the extra (+1) slot */ diff -Nru a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c --- a/arch/ia64/kernel/unwind.c 2004-06-26 17:09:21 -07:00 +++ b/arch/ia64/kernel/unwind.c 2004-06-26 17:09:21 -07:00 @@ -385,9 +385,10 @@ } if (write) { - if (read_only(addr)) - UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); - else { + if (read_only(addr)) { + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", + __FUNCTION__); + } else { *addr = *val; if (*nat) *nat_addr |= nat_mask; @@ -432,9 +433,10 @@ return -1; } if (write) - if (read_only(addr)) - UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); - else + if (read_only(addr)) { + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", + __FUNCTION__); + } else *addr = *val; else *val = *addr; @@ -480,9 +482,10 @@ } if (write) - if (read_only(addr)) - UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); - else + if (read_only(addr)) { + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", + __FUNCTION__); + } else *addr = *val; else *val = *addr; @@ -576,9 +579,10 @@ } if (write) { - if (read_only(addr)) - UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); - else + if (read_only(addr)) { + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", + __FUNCTION__); + } else *addr = *val; } else *val = *addr; @@ -596,9 +600,10 @@ addr = &info->sw->pr; if (write) { - if (read_only(addr)) - UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); - else + if (read_only(addr)) { + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", + __FUNCTION__); + } else *addr = *val; } else *val = *addr; diff -Nru a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c --- a/arch/ia64/mm/contig.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ia64/mm/contig.c 2004-06-26 17:09:17 -07:00 @@ -43,7 +43,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { if (!pfn_valid(i)) diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c --- a/arch/ia64/mm/discontig.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ia64/mm/discontig.c 2004-06-26 17:09:20 -07:00 @@ -154,6 +154,9 @@ memcpy(numa_slit, numa_slit_fix, sizeof (numa_slit)); + for (i = nnode; i < numnodes; i++) + node_set_offline(i); + numnodes = nnode; return; @@ -495,7 +498,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { printk("Node ID: %d\n", pgdat->node_id); for(i = 0; i < pgdat->node_spanned_pages; i++) { diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c --- a/arch/ia64/mm/hugetlbpage.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/mm/hugetlbpage.c 2004-06-26 17:09:18 -07:00 @@ -297,7 +297,7 @@ unlock_page(page); } else { hugetlb_put_quota(mapping); - free_huge_page(page); + page_cache_release(page); goto out; } } diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c --- a/arch/ia64/pci/pci.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ia64/pci/pci.c 2004-06-26 17:09:17 -07:00 @@ -134,10 +134,18 @@ static int __init pci_acpi_init (void) { - if (!acpi_pci_irq_init()) - printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); - else - printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n"); + struct pci_dev *dev = NULL; + + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); + + /* + * PCI IRQ routing is set up by pci_enable_device(), but we + * also do it here in case there are still broken drivers that + * don't use pci_enable_device(). + */ + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) + acpi_pci_irq_enable(dev); + return 0; } diff -Nru a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c --- a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2004-06-26 17:09:19 -07:00 @@ -741,7 +741,7 @@ /* Is this PCI bus associated with this moduleid? */ moduleid = NODE_MODULEID( nasid_to_cnodeid(pcibr_soft->bs_nasid)); - if (modules[i]->id == moduleid) { + if (sn_modules[i]->id == moduleid) { struct pcibr_list_s *new_element; new_element = kmalloc(sizeof (struct pcibr_soft_s), GFP_KERNEL); @@ -781,7 +781,7 @@ /* * We now have a list of all the pci bridges associated with - * the module_id, modules[i]. Call pci_bus_map_create() for + * the module_id, sn_modules[i]. Call pci_bus_map_create() for * each pci bridge */ softlistp = first_in_list; diff -Nru a/arch/ia64/sn/io/sn2/klgraph.c b/arch/ia64/sn/io/sn2/klgraph.c --- a/arch/ia64/sn/io/sn2/klgraph.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ia64/sn/io/sn2/klgraph.c 2004-06-26 17:09:18 -07:00 @@ -527,7 +527,7 @@ /* Use module as module vertex fastinfo */ memset(buffer, 0, 16); - format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF); + format_module_id(buffer, sn_modules[cm]->id, MODULE_FORMAT_BRIEF); sprintf(name, EDGE_LBL_MODULE "/%s", buffer); rc = hwgraph_path_add(hwgraph_root, name, &module_vhdl); @@ -535,7 +535,7 @@ rc = rc; HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, module_vhdl, NULL, "Created module path.\n"); - hwgraph_fastinfo_set(module_vhdl, (arbitrary_info_t) modules[cm]); + hwgraph_fastinfo_set(module_vhdl, (arbitrary_info_t) sn_modules[cm]); /* Add system controller */ sprintf(name, diff -Nru a/arch/ia64/sn/io/sn2/ml_iograph.c b/arch/ia64/sn/io/sn2/ml_iograph.c --- a/arch/ia64/sn/io/sn2/ml_iograph.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ia64/sn/io/sn2/ml_iograph.c 2004-06-26 17:09:15 -07:00 @@ -518,6 +518,14 @@ ASSERT(hubv != GRAPH_VERTEX_NONE); /* + * attach our hub_provider information to hubv, + * so we can use it as a crosstalk provider "master" + * vertex. + */ + xtalk_provider_register(hubv, &hub_provider); + xtalk_provider_startup(hubv); + + /* * If nothing connected to this hub's xtalk port, we're done. */ early_probe_for_widget(hubv, &hwid); @@ -526,14 +534,6 @@ return; /* NOTREACHED */ } - - /* - * attach our hub_provider information to hubv, - * so we can use it as a crosstalk provider "master" - * vertex. - */ - xtalk_provider_register(hubv, &hub_provider); - xtalk_provider_startup(hubv); /* * Create a vertex to represent the crosstalk bus diff -Nru a/arch/ia64/sn/io/sn2/module.c b/arch/ia64/sn/io/sn2/module.c --- a/arch/ia64/sn/io/sn2/module.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ia64/sn/io/sn2/module.c 2004-06-26 17:09:15 -07:00 @@ -33,7 +33,7 @@ #define DPRINTF(x...) #endif -module_t *modules[MODULE_MAX]; +module_t *sn_modules[MODULE_MAX]; int nummodules; #define SN00_SERIAL_FUDGE 0x3b1af409d513c2 @@ -59,9 +59,9 @@ int i; for (i = 0; i < nummodules; i++) - if (modules[i]->id == id) { - DPRINTF("module_lookup: found m=0x%p\n", modules[i]); - return modules[i]; + if (sn_modules[i]->id == id) { + DPRINTF("module_lookup: found m=0x%p\n", sn_modules[i]); + return sn_modules[i]; } return NULL; @@ -104,10 +104,10 @@ /* Insert in sorted order by module number */ - for (i = nummodules; i > 0 && modules[i - 1]->id > moduleid; i--) - modules[i] = modules[i - 1]; + for (i = nummodules; i > 0 && sn_modules[i - 1]->id > moduleid; i--) + sn_modules[i] = sn_modules[i - 1]; - modules[i] = m; + sn_modules[i] = m; nummodules++; } diff -Nru a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c --- a/arch/ia64/sn/kernel/irq.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ia64/sn/kernel/irq.c 2004-06-26 17:09:16 -07:00 @@ -41,6 +41,7 @@ extern void pcibr_force_interrupt(pcibr_intr_t intr); extern int sn_force_interrupt_flag; struct irq_desc * sn_irq_desc(unsigned int irq); +extern cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS]; struct sn_intr_list_t { struct sn_intr_list_t *next; @@ -71,6 +72,21 @@ { } +static inline void move_irq(int irq) +{ + /* note - we hold desc->lock */ + cpumask_t tmp; + irq_desc_t *desc = irq_descp(irq); + + if (!cpus_empty(pending_irq_cpumask[irq])) { + cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); + if (unlikely(!cpus_empty(tmp))) { + desc->handler->set_affinity(irq, pending_irq_cpumask[irq]); + } + cpus_clear(pending_irq_cpumask[irq]); + } +} + static void sn_ack_irq(unsigned int irq) { @@ -94,6 +110,7 @@ } HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask ); __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); + move_irq(irq); } static void diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c --- a/arch/ia64/sn/kernel/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ia64/sn/kernel/setup.c 2004-06-26 17:09:16 -07:00 @@ -226,7 +226,25 @@ shub_1_1_found = 1; } - +/** + * sn_set_error_handling_features - Tell the SN prom how to handle certain + * error types. + */ +static void __init +sn_set_error_handling_features(void) +{ + u64 ret; + u64 sn_ehf_bits[7]; /* see ia64_sn_set_error_handling_features */ + memset(sn_ehf_bits, 0, sizeof(sn_ehf_bits)); +#define EHF(x) __set_bit(SN_SAL_EHF_ ## x, sn_ehf_bits) + EHF(MCA_SLV_TO_OS_INIT_SLV); + EHF(NO_RZ_TLBC); + // Uncomment once Jesse's code goes in - EHF(NO_RZ_IO_READ); +#undef EHF + ret = ia64_sn_set_error_handling_features(sn_ehf_bits); + if (ret) + printk(KERN_ERR "%s: failed, return code %ld\n", __FUNCTION__, ret); +} /** * sn_setup - SN platform setup routine @@ -317,6 +335,9 @@ printk(KERN_DEBUG "sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address); } + + /* Tell the prom how to handle certain error types */ + sn_set_error_handling_features(); /* * we set the default root device to /dev/hda diff -Nru a/arch/m68k/Makefile b/arch/m68k/Makefile --- a/arch/m68k/Makefile 2004-06-26 17:09:20 -07:00 +++ b/arch/m68k/Makefile 2004-06-26 17:09:20 -07:00 @@ -28,6 +28,8 @@ LDFLAGS_vmlinux = -N endif +CHECK := $(CHECK) -D__mc68000__=1 -I$(shell $(CC) -print-file-name=include) + # without -fno-strength-reduce the 53c7xx.c driver fails ;-( CFLAGS += -pipe -fno-strength-reduce -ffixed-a2 diff -Nru a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c --- a/arch/m68k/atari/stram.c 2004-06-26 17:09:19 -07:00 +++ b/arch/m68k/atari/stram.c 2004-06-26 17:09:19 -07:00 @@ -743,7 +743,7 @@ if (map[i]) { entry = swp_entry(stram_swap_type, i); - DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n", + DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n", i, map[i], nr_swap_pages); swap_device_lock(stram_swap_info); @@ -772,7 +772,7 @@ #endif } - DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n", + DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n", i, map[i], nr_swap_pages ); swap_list_lock(); swap_device_lock(stram_swap_info); diff -Nru a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S --- a/arch/m68k/ifpsp060/iskeleton.S 2004-06-26 17:09:15 -07:00 +++ b/arch/m68k/ifpsp060/iskeleton.S 2004-06-26 17:09:15 -07:00 @@ -196,14 +196,57 @@ | Expected outputs: | d0 = 0 -> success; non-zero -> failure | -| Linux/68k: As long as ints are disabled, no swapping out should -| occur (hopefully...) +| Linux/m68k: Make sure the page is properly paged in, so we use +| plpaw and handle any exception here. The kernel must not be +| preempted until _060_unlock_page(), so that the page stays mapped. | .global _060_real_lock_page _060_real_lock_page: - clr.l %d0 + move.l %d2,-(%sp) + | load sfc/dfc + moveq #5,%d0 + tst.b %d0 + jne 1f + moveq #1,%d0 +1: movec.l %dfc,%d2 + movec.l %d0,%dfc + movec.l %d0,%sfc + + clr.l %d0 + | prefetch address + .chip 68060 + move.l %a0,%a1 +1: plpaw (%a1) + addq.w #1,%a0 + tst.b %d1 + jeq 2f + addq.w #2,%a0 +2: plpaw (%a0) +3: .chip 68k + + | restore sfc/dfc + movec.l %d2,%dfc + movec.l %d2,%sfc + move.l (%sp)+,%d2 rts +.section __ex_table,"a" + .align 4 + .long 1b,11f + .long 2b,21f +.previous +.section .fixup,"ax" + .even +11: move.l #0x020003c0,%d0 + or.l %d2,%d0 + swap %d0 + jra 3b +21: move.l #0x02000bc0,%d0 + or.l %d2,%d0 + swap %d0 + jra 3b +.previous + | | _060_unlock_page(): | @@ -216,8 +259,7 @@ | d0 = `xxxxxxff -> supervisor; `xxxxxx00 -> user | d1 = `xxxxxxff -> longword; `xxxxxx00 -> word | -| Linux/68k: As we do no special locking operation, also no unlocking -| is needed... +| Linux/m68k: perhaps reenable preemption here... .global _060_real_unlock_page _060_real_unlock_page: diff -Nru a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c --- a/arch/m68k/kernel/process.c 2004-06-26 17:09:21 -07:00 +++ b/arch/m68k/kernel/process.c 2004-06-26 17:09:21 -07:00 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c --- a/arch/m68k/kernel/setup.c 2004-06-26 17:09:20 -07:00 +++ b/arch/m68k/kernel/setup.c 2004-06-26 17:09:20 -07:00 @@ -62,7 +62,6 @@ static struct mem_info m68k_ramdisk; static char m68k_command_line[CL_SIZE]; -char saved_command_line[CL_SIZE]; char m68k_debug_device[6] = ""; diff -Nru a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c --- a/arch/m68k/kernel/signal.c 2004-06-26 17:09:19 -07:00 +++ b/arch/m68k/kernel/signal.c 2004-06-26 17:09:19 -07:00 @@ -228,8 +228,8 @@ goto out; __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %0,%/fp0-%/fp1\n\t" - "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" + "fmovemx %0,%%fp0-%%fp1\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" ".chip 68k" : /* no outputs */ : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); @@ -258,7 +258,7 @@ if (FPU_IS_EMU) { /* restore fpu control register */ if (__copy_from_user(current->thread.fpcntl, - &uc->uc_mcontext.fpregs.f_pcr, 12)) + uc->uc_mcontext.fpregs.f_fpcntl, 12)) goto out; /* restore all other fpu register */ if (__copy_from_user(current->thread.fp, @@ -298,12 +298,12 @@ sizeof(fpregs))) goto out; __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %0,%/fp0-%/fp7\n\t" - "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" + "fmovemx %0,%%fp0-%%fp7\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" ".chip 68k" : /* no outputs */ : "m" (*fpregs.f_fpregs), - "m" (fpregs.f_pcr)); + "m" (*fpregs.f_fpcntl)); } if (context_size && __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1, @@ -586,12 +586,12 @@ sc->sc_fpstate[0x38] |= 1 << 3; } __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %/fp0-%/fp1,%0\n\t" - "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" + "fmovemx %%fp0-%%fp1,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" ".chip 68k" - : /* no outputs */ - : "m" (*sc->sc_fpregs), - "m" (*sc->sc_fpcntl) + : "=m" (*sc->sc_fpregs), + "=m" (*sc->sc_fpcntl) + : /* no inputs */ : "memory"); } } @@ -604,7 +604,7 @@ if (FPU_IS_EMU) { /* save fpu control register */ - err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr, + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, current->thread.fpcntl, 12); /* save all other fpu register */ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, @@ -631,12 +631,12 @@ fpstate[0x38] |= 1 << 3; } __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %/fp0-%/fp7,%0\n\t" - "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" + "fmovemx %%fp0-%%fp7,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" ".chip 68k" - : /* no outputs */ - : "m" (*fpregs.f_fpregs), - "m" (fpregs.f_pcr) + : "=m" (*fpregs.f_fpregs), + "=m" (*fpregs.f_fpcntl) + : /* no inputs */ : "memory"); err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, sizeof(fpregs)); diff -Nru a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c --- a/arch/m68k/kernel/traps.c 2004-06-26 17:09:21 -07:00 +++ b/arch/m68k/kernel/traps.c 2004-06-26 17:09:21 -07:00 @@ -329,7 +329,8 @@ * fault during mem_read/mem_write in ifpsp060/os.S */ send_fault_sig(&fp->ptregs); - } else { + } else if (!(fslw & (MMU060_RE|MMU060_WE)) || + send_fault_sig(&fp->ptregs) > 0) { printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr); printk( "68060 access error, fslw=%lx\n", fslw ); trap_c( fp ); @@ -517,7 +518,7 @@ if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr) fp->un.fmt7.wb2s &= ~WBV_040; } - } else { + } else if (send_fault_sig(&fp->ptregs) > 0) { printk("68040 access error, ssw=%x\n", ssw); trap_c(fp); } @@ -732,7 +733,7 @@ return; } else if (!(mmusr & MMU_I)) { /* probably a 020 cas fault */ - if (!(ssw & RM)) + if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0) printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr); } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { printk("invalid %s access at %#lx from pc %#lx\n", diff -Nru a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c --- a/arch/m68k/mac/iop.c 2004-06-26 17:09:20 -07:00 +++ b/arch/m68k/mac/iop.c 2004-06-26 17:09:20 -07:00 @@ -261,7 +261,7 @@ } else { iop_base[IOP_NUM_ISM] = (struct mac_iop *) ISM_IOP_BASE_QUADRA; } - iop_base[IOP_NUM_SCC]->status_ctrl = 0; + iop_base[IOP_NUM_ISM]->status_ctrl = 0; iop_ism_present = 1; } else { iop_base[IOP_NUM_ISM] = NULL; diff -Nru a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c --- a/arch/m68k/mm/init.c 2004-06-26 17:09:20 -07:00 +++ b/arch/m68k/mm/init.c 2004-06-26 17:09:20 -07:00 @@ -47,7 +47,7 @@ printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff -Nru a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c --- a/arch/m68k/mm/memory.c 2004-06-26 17:09:19 -07:00 +++ b/arch/m68k/mm/memory.c 2004-06-26 17:09:19 -07:00 @@ -54,7 +54,7 @@ /* unreserve the page so it's possible to free that page */ PD_PAGE(dp)->flags &= ~(1 << PG_reserved); - atomic_set(&PD_PAGE(dp)->count, 1); + set_page_count(PD_PAGE(dp), 1); return; } diff -Nru a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c --- a/arch/m68k/q40/config.c 2004-06-26 17:09:18 -07:00 +++ b/arch/m68k/q40/config.c 2004-06-26 17:09:18 -07:00 @@ -64,7 +64,6 @@ extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ ); -extern char *saved_command_line; extern char m68k_debug_device[]; static void q40_mem_console_write(struct console *co, const char *b, unsigned int count); diff -Nru a/arch/m68knommu/kernel/init_task.c b/arch/m68knommu/kernel/init_task.c --- a/arch/m68knommu/kernel/init_task.c 2004-06-26 17:09:17 -07:00 +++ b/arch/m68knommu/kernel/init_task.c 2004-06-26 17:09:17 -07:00 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c --- a/arch/m68knommu/kernel/setup.c 2004-06-26 17:09:19 -07:00 +++ b/arch/m68knommu/kernel/setup.c 2004-06-26 17:09:19 -07:00 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -44,8 +45,7 @@ unsigned long memory_start; unsigned long memory_end; -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; /* setup some dummy routines */ static void dummy_waitbut(void) diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig --- a/arch/mips/Kconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/Kconfig 2004-06-26 17:09:18 -07:00 @@ -96,11 +96,13 @@ select DMA_NONCOHERENT select IRQ_CPU depends on MACH_VR41XX + select HW_HAS_PCI config TANBAC_TB0226 bool "Support for TANBAC TB0226 (Mbase)" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help The TANBAC TB0226 (Mbase) is a MIPS-based platform manufactured by TANBAC. @@ -110,6 +112,7 @@ bool "Support for TANBAC TB0229 (VR4131DIMM)" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help The TANBAC TB0229 (VR4131DIMM) is a MIPS-based platform manufactured by TANBAC. @@ -118,6 +121,7 @@ config VICTOR_MPC30X bool "Support for Victor MP-C303/304" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU depends on MACH_VR41XX @@ -125,17 +129,22 @@ bool "Support for ZAO Networks Capcella" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU +config PCI_VR41XX + bool "Add PCI control unit support of NEC VR4100 series" + depends on MACH_VR41XX && PCI + config VRC4171 - tristate "add NEC VRC4171 companion chip support" + tristate "Add NEC VRC4171 companion chip support" depends on MACH_VR41XX && ISA ---help--- The NEC VRC4171/4171A is a companion chip for NEC VR4111/VR4121. config VRC4173 - tristate "add NEC VRC4173 companion chip support" - depends on MACH_VR41XX && PCI + tristate "Add NEC VRC4173 companion chip support" + depends on MACH_VR41XX && PCI_VR41XX ---help--- The NEC VRC4173 is a companion chip for NEC VR4122/VR4131. @@ -143,11 +152,13 @@ bool "Support for Toshiba JMR-TX3927 board" depends on MIPS32 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_COBALT bool "Support for Cobalt Server (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU config MACH_DECSTATION @@ -174,6 +185,7 @@ bool "Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI help This is an evaluation board based on the Galileo GT-64120 single-chip system controller that contains a MIPS R5000 compatible @@ -189,6 +201,7 @@ bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select MIPS_GT96100 select RM7000_CPU_SCACHE @@ -201,6 +214,7 @@ config MIPS_IVR bool "Support for Globespan IVR board" select DMA_NONCOHERENT + select HW_HAS_PCI help This is an evaluation board built by Globespan to showcase thir iVR (Internet Video Recorder) design. It utilizes a QED RM5231 @@ -211,6 +225,7 @@ config LASAT bool "Support for LASAT Networks platforms" select DMA_NONCOHERENT + select HW_HAS_PCI select R5000_CPU_SCACHE config PICVUE @@ -233,11 +248,13 @@ bool "Support for Hewlett Packard LaserJet board" depends on BROKEN select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU config MIPS_ITE8172 bool "Support for ITE 8172G board" select DMA_NONCOHERENT + select HW_HAS_PCI help Ths is an evaluation board made by ITE with ATX form factor that utilizes a MIPS R5000 to work with its @@ -257,6 +274,7 @@ config MIPS_ATLAS bool "Support for MIPS Atlas board" select DMA_NONCOHERENT + select HW_HAS_PCI help This enables support for the QED R5231-based MIPS Atlas evaluation board. @@ -265,6 +283,7 @@ bool "Support for MIPS Malta board" select HAVE_STD_PC_SERIAL_PORT select DMA_NONCOHERENT + select HW_HAS_PCI help This enables support for the VR5000-based MIPS Malta evaluation board. @@ -278,6 +297,7 @@ config MOMENCO_OCELOT bool "Support for Momentum Ocelot board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select RM7000_CPU_SCACHE @@ -288,6 +308,7 @@ config MOMENCO_OCELOT_G bool "Support for Momentum Ocelot-G board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select RM7000_CPU_SCACHE @@ -298,6 +319,7 @@ config MOMENCO_OCELOT_C bool "Support for Momentum Ocelot-C board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select RM7000_CPU_SCACHE help @@ -307,6 +329,7 @@ config MOMENCO_JAGUAR_ATX bool "Support for Momentum Jaguar board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select LIMITED_DMA @@ -324,7 +347,10 @@ config PMC_YOSEMITE bool "Support for PMC-Sierra Yosemite eval board" - select DMA_NONCOHERENT + select DMA_COHERENT + select HW_HAS_PCI + select IRQ_CPU + select IRQ_CPU_RM7K help Yosemite is an evaluation board for the RM9000x2 processor manufactured by PMC-Sierra @@ -338,6 +364,7 @@ depends on EXPERIMENTAL select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select IRQ_CPU select ISA help @@ -348,6 +375,7 @@ bool "Support for NEC DDB Vrc-5476" select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select IRQ_CPU select ISA help @@ -361,6 +389,7 @@ config DDB5477 bool "Support for NEC DDB Vrc-5477" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help This enables support for the R5432-based NEC DDB Vrc-5477, @@ -393,6 +422,7 @@ bool "Support for SGI IP27 (Origin200/2000)" depends on MIPS64 select DMA_IP27 + select HW_HAS_PCI help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y @@ -457,6 +487,7 @@ bool "Support for SGI IP32 (O2) (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select R5000_CPU_SCACHE select RM7000_CPU_SCACHE help @@ -499,26 +530,31 @@ bool "PB1000 board" depends on SOC_AU1000 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1100 bool "PB1100 board" depends on SOC_AU1100 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1500 bool "PB1500 board" depends on SOC_AU1500 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1550 bool "PB1550 board" depends on SOC_AU1550 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1000 bool "DB1000 board" depends on SOC_AU1000 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1100 bool "DB1100 board" @@ -529,10 +565,12 @@ bool "DB1500 board" depends on SOC_AU1500 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1550 bool "DB1550 board" depends on SOC_AU1550 + select HW_HAS_PCI config MIPS_BOSPORUS bool "Bosporus board" @@ -642,6 +680,7 @@ config SIBYTE_SB1250 bool + select HW_HAS_PCI config SIBYTE_BCM1120 bool @@ -649,10 +688,12 @@ config SIBYTE_BCM1125 bool + select HW_HAS_PCI select SIBYTE_BCM112X config SIBYTE_BCM1125H bool + select HW_HAS_PCI select SIBYTE_BCM112X config SIBYTE_BCM112X @@ -699,11 +740,6 @@ config CPU_SB1_PASS_2 bool -config SIBYTE_HAS_PCI - bool - depends on SIBYTE_SB1250 || SIBYTE_BCM1125 || SIBYTE_BCM1125H - default y - config SIBYTE_HAS_LDT bool depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H) @@ -770,6 +806,7 @@ bool "Support for SNI RM200 PCI" select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select ISA help The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens @@ -781,6 +818,7 @@ bool "Support for Toshiba TBTX49[23]7 board" depends on MIPS32 select DMA_NONCOHERENT + select HW_HAS_PCI select ISA config RWSEM_GENERIC_SPINLOCK @@ -860,11 +898,6 @@ config IRQ_CPU_RM7K bool -config DUMMY_KEYB - bool - depends on ZAO_CAPCELLA || VICTOR_MPC30X || SIBYTE_SB1xxx_SOC || NEC_EAGLE || NEC_OSPREY || DDB5477 || CASIO_E55 || TANBAC_TB0226 || TANBAC_TB0229 - default y - config DDB5XXX_COMMON bool depends on DDB5074 || DDB5476 || DDB5477 @@ -932,11 +965,6 @@ depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 default n -config COBALT_LCD - bool - depends on MIPS_COBALT - default y - config MIPS_GT96100 bool depends on MIPS_EV96100 @@ -1169,6 +1197,16 @@ 4kB page size will minimize memory consumption and is therefore recommended for low memory systems. +config PAGE_SIZE_8KB + bool "8kB" + depends on EXPERIMENTAL && CPU_R8000 + help + Using 8kB page size will result in higher performance kernel at + the price of higher memory consumption. This option is available + only on the R8000 processor. Not that at the time of this writing + this option is still high experimental; there are also issues with + compatibility of user applications. + config PAGE_SIZE_16KB bool "16kB" depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX @@ -1382,9 +1420,12 @@ menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" +config HW_HAS_PCI + bool + config PCI bool "Support for PCI controller" - depends on MIPS_DB1000 || DDB5074 || DDB5476 || DDB5477 || HP_LASERJET || LASAT || MIPS_IVR || MIPS_ATLAS || MIPS_COBALT || MIPS_EV64120 || MIPS_EV96100 || MIPS_ITE8172 || MIPS_MALTA || MOMENCO_OCELOT || MOMENCO_OCELOT_C || MOMENCO_OCELOT_G || MOMENCO_JAGUAR_ATX || MIPS_PB1000 || MIPS_PB1100 || SOC_AU1500 || SOC_AU1550 || NEC_EAGLE || SGI_IP27 || SGI_IP32 || SIBYTE_HAS_PCI || SNI_RM200_PCI || TANBAC_TB0226 || TANBAC_TB0229 || TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || VICTOR_MPC30X || ZAO_CAPCELLA + depends on HW_HAS_PCI help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside @@ -1564,7 +1605,7 @@ config DEBUG_SLAB bool "Debug memory allocations" - depends on DEBUG_KERNEL && !CPU_HAS_LLDSCD + 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 diff -Nru a/arch/mips/Makefile b/arch/mips/Makefile --- a/arch/mips/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/Makefile 2004-06-26 17:09:15 -07:00 @@ -406,6 +406,13 @@ load-$(CONFIG_MOMENCO_OCELOT_C) += 0x80100000 # +# PMC-Sierra Yosemite +# +core-$(CONFIG_PMC_YOSEMITE) += arch/mips/pmc-sierra/yosemite/ +cflags-$(CONFIG_PMC_YOSEMITE) += -Iinclude/asm-mips/mach-yosemite +load-$(CONFIG_PMC_YOSEMITE) += 0x80100000 + +# # Momentum Jaguar ATX # core-$(CONFIG_MOMENCO_JAGUAR_ATX) += arch/mips/momentum/jaguar_atx/ @@ -659,8 +666,6 @@ libs-$(CONFIG_MIPS64) += arch/mips/lib-64/ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ -core-$(CONFIG_MIPS32) += arch/mips/mm-32/ -core-$(CONFIG_MIPS64) += arch/mips/mm-64/ ifdef CONFIG_BAGET_MIPS diff -Nru a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c --- a/arch/mips/baget/irq.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/baget/irq.c 2004-06-26 17:09:19 -07:00 @@ -325,7 +325,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; @@ -389,7 +389,7 @@ } static struct irqaction irq0 = -{ write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL}; +{ write_err_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "bus write error", NULL, NULL}; void __init init_IRQ(void) { diff -Nru a/arch/mips/baget/time.c b/arch/mips/baget/time.c --- a/arch/mips/baget/time.c 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/baget/time.c 2004-06-26 17:09:15 -07:00 @@ -67,7 +67,7 @@ } static struct irqaction timer_irq = -{ timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +{ timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init(void) { diff -Nru a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile --- a/arch/mips/boot/Makefile 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/boot/Makefile 2004-06-26 17:09:19 -07:00 @@ -39,7 +39,7 @@ archhelp: @echo '* vmlinux.ecoff - ECOFF boot image' -CLEAN_FILES += addinitrd \ +clean-files += addinitrd \ elf2ecoff \ vmlinux.ecoff \ vmlinux.srec \ diff -Nru a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig --- a/arch/mips/configs/atlas_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/atlas_defconfig 2004-06-26 17:09:20 -07:00 @@ -107,6 +107,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -121,6 +122,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -197,7 +199,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -216,11 +217,11 @@ # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -229,6 +230,7 @@ # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -395,7 +397,6 @@ # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -616,7 +617,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -651,3 +651,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/bosporus_defconfig b/arch/mips/configs/bosporus_defconfig --- a/arch/mips/configs/bosporus_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/bosporus_defconfig 2004-06-26 17:09:20 -07:00 @@ -105,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig --- a/arch/mips/configs/capcella_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/capcella_defconfig 2004-06-26 17:09:16 -07:00 @@ -59,7 +59,8 @@ # CONFIG_TANBAC_TB0229 is not set # CONFIG_VICTOR_MPC30X is not set CONFIG_ZAO_CAPCELLA=y -# CONFIG_VRC4173 is not set +CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set @@ -91,7 +92,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -185,7 +187,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -197,6 +198,7 @@ # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -214,7 +216,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -357,7 +358,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -591,7 +591,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -626,3 +625,4 @@ # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig --- a/arch/mips/configs/cobalt_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/cobalt_defconfig 2004-06-26 17:09:17 -07:00 @@ -80,7 +80,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y CONFIG_MIPS_GT64111=y -CONFIG_COBALT_LCD=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -105,6 +104,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -117,6 +117,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -177,7 +178,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -189,6 +189,7 @@ # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -206,7 +207,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -345,7 +345,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -432,6 +431,7 @@ # # CONFIG_WATCHDOG is not set CONFIG_RTC=y +CONFIG_COBALT_LCD=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -567,7 +567,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,3 +601,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig --- a/arch/mips/configs/db1000_defconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/configs/db1000_defconfig 2004-06-26 17:09:18 -07:00 @@ -122,6 +122,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -522,6 +524,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -593,7 +598,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -678,11 +682,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig --- a/arch/mips/configs/db1100_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/db1100_defconfig 2004-06-26 17:09:17 -07:00 @@ -122,6 +122,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -518,6 +519,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -589,7 +593,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -674,11 +677,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig --- a/arch/mips/configs/db1500_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/db1500_defconfig 2004-06-26 17:09:17 -07:00 @@ -122,6 +122,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -259,7 +261,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=m # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -271,6 +272,7 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -592,6 +594,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -665,7 +670,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -750,11 +754,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig --- a/arch/mips/configs/ddb5476_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/ddb5476_defconfig 2004-06-26 17:09:17 -07:00 @@ -105,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -117,6 +118,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -179,7 +181,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +192,7 @@ # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -214,7 +216,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -363,7 +364,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -487,6 +487,7 @@ # # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -606,7 +607,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -641,3 +641,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig --- a/arch/mips/configs/ddb5477_defconfig 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/configs/ddb5477_defconfig 2004-06-26 17:09:19 -07:00 @@ -80,7 +80,6 @@ CONFIG_I8259=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_DDB5XXX_COMMON=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -106,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -118,6 +118,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -184,7 +185,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -345,7 +345,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -567,7 +566,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,3 +600,4 @@ # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig --- a/arch/mips/configs/decstation_defconfig 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/configs/decstation_defconfig 2004-06-26 17:09:19 -07:00 @@ -109,6 +109,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -184,7 +185,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -537,7 +537,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -587,3 +586,4 @@ # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig --- a/arch/mips/configs/e55_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/e55_defconfig 2004-06-26 17:09:16 -07:00 @@ -91,7 +91,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +115,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -180,7 +180,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +190,7 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -570,7 +570,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -605,3 +604,4 @@ # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/eagle_defconfig b/arch/mips/configs/eagle_defconfig --- a/arch/mips/configs/eagle_defconfig 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/configs/eagle_defconfig 2004-06-26 17:09:15 -07:00 @@ -59,6 +59,7 @@ # CONFIG_TANBAC_TB0229 is not set # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set +CONFIG_PCI_VR41XX=y CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set @@ -91,7 +92,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -261,7 +263,6 @@ # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=y # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -274,6 +275,7 @@ # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -291,7 +293,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -447,7 +448,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -692,7 +692,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -739,11 +738,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig --- a/arch/mips/configs/ev64120_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/ev64120_defconfig 2004-06-26 17:09:17 -07:00 @@ -111,6 +111,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -124,6 +125,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -191,7 +193,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -339,7 +340,6 @@ # CONFIG_PPP_BSDCOMP is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -559,7 +559,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -594,3 +593,4 @@ # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig --- a/arch/mips/configs/ev96100_defconfig 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/configs/ev96100_defconfig 2004-06-26 17:09:19 -07:00 @@ -110,6 +110,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -126,6 +127,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -514,7 +516,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -549,3 +550,4 @@ # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig --- a/arch/mips/configs/ip22_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/ip22_defconfig 2004-06-26 17:09:17 -07:00 @@ -114,6 +114,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -196,7 +197,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -583,7 +583,7 @@ CONFIG_INDYDOG=m # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set -CONFIG_SGI_DS1286=y +CONFIG_SGI_DS1286=m # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -750,7 +750,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -850,11 +849,13 @@ CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig --- a/arch/mips/configs/ip27_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/ip27_defconfig 2004-06-26 17:09:17 -07:00 @@ -113,6 +113,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -128,6 +129,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -203,7 +205,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -226,7 +227,6 @@ # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -235,6 +235,7 @@ # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set CONFIG_SCSI_QLOGIC_ISP=y # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -267,6 +268,7 @@ # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -638,7 +640,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -700,11 +701,13 @@ CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig --- a/arch/mips/configs/ip32_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/ip32_defconfig 2004-06-26 17:09:16 -07:00 @@ -102,6 +102,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -116,6 +117,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -193,7 +195,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -222,7 +223,6 @@ # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -231,6 +231,7 @@ # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -263,6 +264,7 @@ # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -617,7 +619,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -663,3 +664,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig --- a/arch/mips/configs/it8172_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/it8172_defconfig 2004-06-26 17:09:16 -07:00 @@ -110,6 +110,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -122,6 +123,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -231,7 +233,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -242,6 +243,7 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -615,7 +617,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -650,3 +651,4 @@ # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig --- a/arch/mips/configs/ivr_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/ivr_defconfig 2004-06-26 17:09:16 -07:00 @@ -108,6 +108,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -120,6 +121,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -179,7 +181,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +192,7 @@ # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -208,7 +210,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -350,7 +351,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -571,7 +571,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -606,3 +605,4 @@ # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig --- a/arch/mips/configs/jaguar-atx_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/jaguar-atx_defconfig 2004-06-26 17:09:20 -07:00 @@ -100,6 +100,7 @@ CONFIG_CPU_RM9000=y # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -118,6 +119,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -184,7 +186,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -538,3 +539,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig --- a/arch/mips/configs/jmr3927_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/jmr3927_defconfig 2004-06-26 17:09:16 -07:00 @@ -104,6 +104,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -115,6 +116,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -182,7 +184,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -324,7 +325,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -462,6 +462,7 @@ # # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -578,7 +579,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -613,3 +613,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig --- a/arch/mips/configs/lasat200_defconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/configs/lasat200_defconfig 2004-06-26 17:09:18 -07:00 @@ -112,6 +112,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -127,6 +128,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set @@ -242,7 +244,6 @@ # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -283,6 +284,7 @@ # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -301,7 +303,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -438,7 +439,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -665,7 +665,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -700,3 +699,4 @@ # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig --- a/arch/mips/configs/malta_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/malta_defconfig 2004-06-26 17:09:20 -07:00 @@ -115,6 +115,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -129,6 +130,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -197,7 +199,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -357,7 +358,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -580,7 +580,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -615,3 +614,4 @@ # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/mirage_defconfig b/arch/mips/configs/mirage_defconfig --- a/arch/mips/configs/mirage_defconfig 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/configs/mirage_defconfig 2004-06-26 17:09:19 -07:00 @@ -105,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig --- a/arch/mips/configs/mpc30x_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/mpc30x_defconfig 2004-06-26 17:09:20 -07:00 @@ -59,6 +59,7 @@ # CONFIG_TANBAC_TB0229 is not set CONFIG_VICTOR_MPC30X=y # CONFIG_ZAO_CAPCELLA is not set +CONFIG_PCI_VR41XX=y CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set @@ -91,7 +92,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -192,7 +194,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -335,7 +336,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -555,7 +555,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,11 +601,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig --- a/arch/mips/configs/mtx1_defconfig 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/configs/mtx1_defconfig 2004-06-26 17:09:19 -07:00 @@ -105,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig --- a/arch/mips/configs/ocelot_c_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/ocelot_c_defconfig 2004-06-26 17:09:16 -07:00 @@ -100,6 +100,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -114,7 +115,10 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_PCI is not set +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y CONFIG_MMU=y # @@ -154,8 +158,13 @@ # Block devices # # CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set # CONFIG_BLK_DEV_RAM is not set # @@ -185,6 +194,7 @@ # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -258,26 +268,50 @@ # CONFIG_ETHERTAP is not set # +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # -CONFIG_MV64340_ETH=y -CONFIG_MV64340_ETH_0=y -# CONFIG_MV64340_ETH_1 is not set -# CONFIG_MV64340_ETH_2 is not set +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_MV64340_ETH is not set # # Ethernet (10000 Mbit) # +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -288,6 +322,8 @@ # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -329,6 +365,7 @@ # CONFIG_SERIO_I8042 is not set CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set # # Input Device Drivers @@ -426,6 +463,7 @@ # # USB support # +# CONFIG_USB is not set # # USB Gadget Support @@ -509,7 +547,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -544,3 +581,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig --- a/arch/mips/configs/ocelot_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/ocelot_defconfig 2004-06-26 17:09:17 -07:00 @@ -108,6 +108,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -124,6 +125,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -513,7 +515,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -548,3 +549,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/configs/ocelot_g_defconfig 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,587 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS64=y +CONFIG_64BIT=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_MACH_JAZZ is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +CONFIG_MOMENCO_OCELOT_G=y +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_IRQ_CPU_RM7K=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_SYSCLK_75 is not set +# CONFIG_SYSCLK_83 is not set +CONFIG_SYSCLK_100=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_RM7000_CPU_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +# CONFIG_BLK_DEV_RAM is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_GALILEO_64240_ETH=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/osprey_defconfig b/arch/mips/configs/osprey_defconfig --- a/arch/mips/configs/osprey_defconfig 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/configs/osprey_defconfig 2004-06-26 17:09:15 -07:00 @@ -83,7 +83,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set CONFIG_VR4181=y @@ -109,6 +108,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -507,7 +507,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -542,3 +541,4 @@ # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff -Nru a/arch/mips/configs/pb1000_defconfig b/arch/mips/configs/pb1000_defconfig --- a/arch/mips/configs/pb1000_defconfig 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/configs/pb1000_defconfig 2004-06-26 17:09:15 -07:00 @@ -105,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig --- a/arch/mips/configs/pb1100_defconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/configs/pb1100_defconfig 2004-06-26 17:09:18 -07:00 @@ -105,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig --- a/arch/mips/configs/pb1500_defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/configs/pb1500_defconfig 2004-06-26 17:09:17 -07:00 @@ -123,6 +123,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -137,6 +138,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -213,7 +215,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -254,6 +255,7 @@ # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set @@ -272,7 +274,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -452,7 +453,6 @@ # CONFIG_PPP_BSDCOMP is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -611,6 +611,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -682,7 +685,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -767,11 +769,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig --- a/arch/mips/configs/pb1550_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/pb1550_defconfig 2004-06-26 17:09:16 -07:00 @@ -122,6 +122,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -212,7 +214,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -253,6 +254,7 @@ # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set @@ -271,7 +273,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -451,7 +452,6 @@ # CONFIG_PPP_BSDCOMP is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -610,6 +610,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -681,7 +684,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -766,11 +768,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig --- a/arch/mips/configs/rm200_defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/configs/rm200_defconfig 2004-06-26 17:09:16 -07:00 @@ -116,6 +116,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -129,6 +130,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set @@ -246,7 +248,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -268,12 +269,12 @@ # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -294,6 +295,7 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set @@ -695,7 +697,6 @@ # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -908,6 +909,7 @@ CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m # CONFIG_USB_MTOUCH is not set +CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m # CONFIG_USB_ATI_REMOTE is not set @@ -1016,6 +1018,7 @@ CONFIG_USB_LCD=m CONFIG_USB_LED=m CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGETSERVO=m CONFIG_USB_TEST=m # @@ -1051,10 +1054,14 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y CONFIG_JFS_FS=m # CONFIG_JFS_POSIX_ACL is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m # CONFIG_XFS_RT is not set CONFIG_XFS_QUOTA=y @@ -1140,6 +1147,7 @@ CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y @@ -1151,7 +1159,6 @@ CONFIG_NCPFS_EXTRAS=y CONFIG_CODA_FS=m CONFIG_CODA_FS_OLD_API=y -CONFIG_INTERMEZZO_FS=m CONFIG_AFS_FS=m CONFIG_RXRPC=m @@ -1252,11 +1259,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set CONFIG_CRYPTO_TEST=m # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig --- a/arch/mips/configs/sb1250-swarm_defconfig 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/configs/sb1250-swarm_defconfig 2004-06-26 17:09:21 -07:00 @@ -93,7 +93,6 @@ # CONFIG_CPU_SB1_PASS_4 is not set # CONFIG_CPU_SB1_PASS_2_112x is not set # CONFIG_CPU_SB1_PASS_3 is not set -CONFIG_SIBYTE_HAS_PCI=y CONFIG_SIBYTE_HAS_LDT=y # CONFIG_SIMULATION is not set CONFIG_SIBYTE_CFE=y @@ -107,7 +106,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_COHERENT=y # CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_DUMMY_KEYB=y CONFIG_SWAP_IO_SPACE=y CONFIG_BOOT_ELF32=y CONFIG_MIPS_L1_CACHE_SHIFT=5 @@ -134,6 +132,7 @@ # CONFIG_CPU_RM9000 is not set CONFIG_CPU_SB1=y CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_SIBYTE_DMA_PAGEOPS is not set @@ -154,6 +153,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -213,7 +213,30 @@ # # ATA/ATAPI/MFM/RLL support # -# CONFIG_IDE is not set +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDETAPE=y +CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPCI is not set +CONFIG_BLK_DEV_IDE_SWARM=y +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI device support @@ -228,7 +251,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -371,7 +393,6 @@ # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -575,7 +596,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -623,11 +643,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig --- a/arch/mips/configs/sead_defconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/configs/sead_defconfig 2004-06-26 17:09:18 -07:00 @@ -19,7 +19,6 @@ # CONFIG_SWAP=y # CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set @@ -103,6 +102,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -429,3 +429,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig --- a/arch/mips/configs/tb0226_defconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/configs/tb0226_defconfig 2004-06-26 17:09:18 -07:00 @@ -90,7 +90,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_FB=y @@ -115,6 +114,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -125,6 +125,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -179,7 +180,6 @@ # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +191,7 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -215,7 +216,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -608,7 +608,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -681,5 +680,6 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig --- a/arch/mips/configs/tb0229_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/tb0229_defconfig 2004-06-26 17:09:20 -07:00 @@ -59,7 +59,8 @@ CONFIG_TANBAC_TB0229=y # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set -# CONFIG_VRC4173 is not set +CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set @@ -91,7 +92,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set CONFIG_TANBAC_TB0219=y @@ -117,6 +117,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -127,6 +128,7 @@ # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -196,7 +198,6 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -355,7 +356,6 @@ CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -599,7 +599,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -672,5 +671,6 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig --- a/arch/mips/configs/workpad_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/workpad_defconfig 2004-06-26 17:09:20 -07:00 @@ -115,6 +115,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -179,7 +180,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -190,6 +190,7 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -573,7 +574,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -608,3 +608,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/configs/xxs1500_defconfig b/arch/mips/configs/xxs1500_defconfig --- a/arch/mips/configs/xxs1500_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/xxs1500_defconfig 2004-06-26 17:09:20 -07:00 @@ -105,6 +105,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig --- a/arch/mips/configs/yosemite_defconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/configs/yosemite_defconfig 2004-06-26 17:09:20 -07:00 @@ -9,20 +9,20 @@ # # Code maturity level options # -CONFIG_EXPERIMENTAL=y +# CONFIG_EXPERIMENTAL is not set CONFIG_CLEAN_COMPILE=y CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y # # General setup # CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=15 +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -41,47 +41,40 @@ # CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y -CONFIG_MODVERSIONS=y CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y # # Machine selection # # CONFIG_MACH_JAZZ is not set -# CONFIG_BAGET_MIPS is not set # CONFIG_MACH_VR41XX is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_DDB5074 is not set +CONFIG_PMC_YOSEMITE=y +# CONFIG_HYPERTRANSPORT is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SOC_AU1X00 is not set -# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set # CONFIG_TOSHIBA_RBTX4927 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_HAVE_DEC_LOCK=y +CONFIG_DMA_COHERENT=y # CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_IRQ_CPU_RM7K=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -106,6 +99,7 @@ CONFIG_CPU_RM9000=y # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -114,15 +108,18 @@ CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y CONFIG_CPU_HAS_SYNC=y -# CONFIG_HIGHMEM is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 +CONFIG_HIGHMEM=y +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y CONFIG_MMU=y # @@ -159,11 +156,14 @@ # Block devices # # CONFIG_BLK_DEV_FD is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set # CONFIG_BLK_DEV_RAM is not set -CONFIG_LBD=y +# CONFIG_LBD is not set # # ATA/ATAPI/MFM/RLL support @@ -173,40 +173,7 @@ # # SCSI device support # -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_REPORT_LUNS=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI is not set # # Multi-device support (RAID and LVM) @@ -225,6 +192,7 @@ # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -234,46 +202,31 @@ # # Networking options # -CONFIG_PACKET=y +CONFIG_PACKET=m CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set +CONFIG_NETLINK_DEV=m CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set # # QoS and/or fair queueing @@ -296,22 +249,49 @@ # CONFIG_TUN is not set # +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +CONFIG_TITAN_GE=y # # Ethernet (10000 Mbit) # +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -322,10 +302,9 @@ # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set # # ISDN subsystem @@ -351,10 +330,8 @@ # # CONFIG_GAMEPORT is not set CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set # # Input Device Drivers @@ -364,22 +341,21 @@ # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_SYNCLINK is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_N_HDLC is not set -# CONFIG_STALDRV is not set +# CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # -# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set # # Non-8250 serial port support # +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -403,6 +379,7 @@ # # Ftape, the floppy tape device driver # +# CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -438,6 +415,7 @@ # # USB support # +# CONFIG_USB is not set # # USB Gadget Support @@ -448,13 +426,8 @@ # File systems # # CONFIG_EXT2_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_XFS_FS is not set @@ -482,7 +455,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set @@ -491,13 +463,7 @@ # # Miscellaneous filesystems # -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -509,22 +475,16 @@ # Network File Systems # CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFS_V3 is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y # CONFIG_EXPORTFS is not set CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_AFS_FS is not set # # Partition Types @@ -558,3 +518,4 @@ # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c --- a/arch/mips/ddb5xxx/ddb5074/irq.c 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/ddb5xxx/ddb5074/irq.c 2004-06-26 17:09:21 -07:00 @@ -24,7 +24,7 @@ extern asmlinkage void ddbIRQ(void); -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ #define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ diff -Nru a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c --- a/arch/mips/ddb5xxx/ddb5476/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/ddb5xxx/ddb5476/irq.c 2004-06-26 17:09:20 -07:00 @@ -107,8 +107,8 @@ /* memory resource acquire in ddb_setup */ } -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; -static struct irqaction irq_error = { no_action, 0, 0, "error", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; +static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; extern asmlinkage void ddb5476_handle_int(void); extern int setup_irq(unsigned int irq, struct irqaction *irqaction); diff -Nru a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c --- a/arch/mips/ddb5xxx/ddb5477/irq.c 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/ddb5xxx/ddb5477/irq.c 2004-06-26 17:09:15 -07:00 @@ -77,7 +77,7 @@ extern void mips_cpu_irq_init(u32 base); extern asmlinkage void ddb5477_handle_int(void); extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; void ddb5477_irq_setup(void) diff -Nru a/arch/mips/defconfig b/arch/mips/defconfig --- a/arch/mips/defconfig 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/defconfig 2004-06-26 17:09:16 -07:00 @@ -114,6 +114,7 @@ # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -196,7 +197,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -583,7 +583,7 @@ CONFIG_INDYDOG=m # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set -CONFIG_SGI_DS1286=y +CONFIG_SGI_DS1286=m # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -750,7 +750,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -850,11 +849,13 @@ CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c --- a/arch/mips/gt64120/common/time.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/gt64120/common/time.c 2004-06-26 17:09:20 -07:00 @@ -80,7 +80,7 @@ timer.name = "timer"; timer.dev_id = NULL; timer.next = NULL; - timer.mask = 0; + timer.mask = CPU_MASK_NONE; irq_desc[GT_TIMER].action = &timer; enable_irq(GT_TIMER); diff -Nru a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c --- a/arch/mips/jmr3927/rbhma3100/irq.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/jmr3927/rbhma3100/irq.c 2004-06-26 17:09:17 -07:00 @@ -301,7 +301,7 @@ } static struct irqaction ioc_action = { - jmr3927_ioc_interrupt, 0, 0, "IOC", NULL, NULL, + jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL, }; static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -318,7 +318,7 @@ } static struct irqaction isac_action = { - jmr3927_isac_interrupt, 0, 0, "ISAC", NULL, NULL, + jmr3927_isac_interrupt, 0, CPU_MASK_NONE, "ISAC", NULL, NULL, }; @@ -327,7 +327,7 @@ printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); } static struct irqaction isaerr_action = { - jmr3927_isaerr_interrupt, 0, 0, "ISA error", NULL, NULL, + jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL, }; static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) @@ -337,7 +337,7 @@ tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); } static struct irqaction pcierr_action = { - jmr3927_pcierr_interrupt, 0, 0, "PCI error", NULL, NULL, + jmr3927_pcierr_interrupt, 0, CPU_MASK_NONE, "PCI error", NULL, NULL, }; int jmr3927_ether1_irq = 0; diff -Nru a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile --- a/arch/mips/kernel/Makefile 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/kernel/Makefile 2004-06-26 17:09:17 -07:00 @@ -9,7 +9,7 @@ time.o traps.o unaligned.o ifdef CONFIG_MODULES -obj-y += mips_ksyms.o +obj-y += mips_ksyms.o module.o obj-$(CONFIG_MIPS32) += module-elf32.o obj-$(CONFIG_MIPS64) += module-elf64.o endif @@ -23,6 +23,7 @@ obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o diff -Nru a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c --- a/arch/mips/kernel/cpu-bugs64.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/kernel/cpu-bugs64.c 2004-06-26 17:09:19 -07:00 @@ -177,7 +177,7 @@ extern asmlinkage void handle_daddi_ov(void); unsigned long flags; void *handler; - long v; + long v, tmp; printk("Checking for the daddi bug... "); @@ -197,13 +197,15 @@ ".set noat\n\t" ".set noreorder\n\t" ".set nomacro\n\t" + "addiu %1, $0, %2\n\t" + "dsrl %1, %1, 1\n\t" #ifdef HAVE_AS_SET_DADDI ".set daddi\n\t" #endif - "daddi %0, %1, %2\n\t" + "daddi %0, %1, %3\n\t" ".set pop" - : "=r" (v) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=r" (v), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -217,9 +219,11 @@ local_irq_save(flags); handler = set_except_vector(12, handle_daddi_ov); asm volatile( - "daddi %0, %1, %2" - : "=r" (v) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + "addiu %1, $0, %2\n\t" + "dsrl %1, %1, 1\n\t" + "daddi %0, %1, %3" + : "=r" (v), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -240,7 +244,7 @@ static inline void check_daddiu(void) { - long v, w; + long v, w, tmp; printk("Checking for the daddiu bug... "); @@ -265,15 +269,17 @@ ".set noat\n\t" ".set noreorder\n\t" ".set nomacro\n\t" + "addiu %2, $0, %3\n\t" + "dsrl %2, %2, 1\n\t" #ifdef HAVE_AS_SET_DADDI ".set daddi\n\t" #endif - "daddiu %0, %2, %3\n\t" - "addiu %1, $0, %3\n\t" + "daddiu %0, %2, %4\n\t" + "addiu %1, $0, %4\n\t" "daddu %1, %2\n\t" ".set pop" - : "=&r" (v), "=&r" (w) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=&r" (v), "=&r" (w), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); if (v == w) { printk("no.\n"); @@ -283,11 +289,13 @@ printk("yes, workaround... "); asm volatile( - "daddiu %0, %2, %3\n\t" - "addiu %1, $0, %3\n\t" + "addiu %2, $0, %3\n\t" + "dsrl %2, %2, 1\n\t" + "daddiu %0, %2, %4\n\t" + "addiu %1, $0, %4\n\t" "daddu %1, %2" - : "=&r" (v), "=&r" (w) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=&r" (v), "=&r" (w), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); if (v == w) { printk("yes.\n"); diff -Nru a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c --- a/arch/mips/kernel/cpu-probe.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/kernel/cpu-probe.c 2004-06-26 17:09:17 -07:00 @@ -1,6 +1,8 @@ /* * Processor capabilities determination functions. * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 2003 Maciej W. Rozycki * Copyright (C) 1994 - 2003 Ralf Baechle * Copyright (C) 2001 MIPS Inc. * @@ -49,6 +51,14 @@ ".set\tmips0"); } +/* + * The Au1xxx wait is available only if we run CONFIG_PM and + * the timer setup found we had a 32KHz counter available. + * There are still problems with functions that may call au1k_wait + * directly, but that will be discovered pretty quickly. + */ +extern void (*au1k_wait_ptr)(void); + void au1k_wait(void) { #ifdef CONFIG_PM @@ -90,7 +100,6 @@ case CPU_R5000: case CPU_NEVADA: case CPU_RM7000: -/* case CPU_RM9000: */ case CPU_TX49XX: case CPU_4KC: case CPU_4KEC: @@ -102,12 +111,19 @@ cpu_wait = r4k_wait; printk(" available.\n"); break; +#ifdef CONFIG_PM case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: - cpu_wait = au1k_wait; - printk(" available.\n"); + if (au1k_wait_ptr != NULL) { + cpu_wait = au1k_wait_ptr; + printk(" available.\n"); + } + else { + printk(" unavailable.\n"); + } break; +#endif default: printk(" unavailable.\n"); break; @@ -238,8 +254,8 @@ break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - c->cputype = CPU_VR41XX; - break; + c->cputype = CPU_VR41XX; + break; } c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS; @@ -371,7 +387,7 @@ c->cputype = CPU_RM9000; c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; + MIPS_CPU_LLSC; /* * Bit 29 in the info register of the RM9000 * indicates if the TLB has 48 or 64 entries. @@ -407,9 +423,6 @@ MIPS_CPU_LLSC; c->tlbsize = 64; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -475,9 +488,6 @@ /* Probe for L2 cache */ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -505,9 +515,6 @@ break; } c->isa_level = MIPS_CPU_ISA_M32; - break; - default: - c->cputype = CPU_UNKNOWN; break; } } @@ -528,9 +535,6 @@ c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; #endif break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -542,14 +546,11 @@ c->cputype = CPU_SR71000; c->isa_level = MIPS_CPU_ISA_M64; c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; c->scache.ways = 8; c->tlbsize = 64; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -563,7 +564,6 @@ c->processor_id = read_c0_prid(); switch (c->processor_id & 0xff0000) { - case PRID_COMP_LEGACY: cpu_probe_legacy(c); break; diff -Nru a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c --- a/arch/mips/kernel/init_task.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/kernel/init_task.c 2004-06-26 17:09:16 -07:00 @@ -3,6 +3,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c --- a/arch/mips/kernel/irq.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/kernel/irq.c 2004-06-26 17:09:16 -07:00 @@ -487,7 +487,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/mips/kernel/module-elf32.c b/arch/mips/kernel/module-elf32.c --- a/arch/mips/kernel/module-elf32.c 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/kernel/module-elf32.c 2004-06-26 17:09:15 -07:00 @@ -248,14 +248,3 @@ me->name); return -ENOEXEC; } - -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff -Nru a/arch/mips/kernel/module-elf64.c b/arch/mips/kernel/module-elf64.c --- a/arch/mips/kernel/module-elf64.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/kernel/module-elf64.c 2004-06-26 17:09:19 -07:00 @@ -272,14 +272,3 @@ return 0; } - -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff -Nru a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/kernel/module.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,53 @@ +#include +#include + +static LIST_HEAD(dbe_list); +static spinlock_t dbe_lock = SPIN_LOCK_UNLOCKED; + +/* Given an address, look for it in the module exception tables. */ +const struct exception_table_entry *search_module_dbetables(unsigned long addr) +{ + unsigned long flags; + const struct exception_table_entry *e = NULL; + struct mod_arch_specific *dbe; + + spin_lock_irqsave(&dbe_lock, flags); + list_for_each_entry(dbe, &dbe_list, dbe_list) { + e = search_extable(dbe->dbe_start, dbe->dbe_end - 1, addr); + if (e) + break; + } + spin_unlock_irqrestore(&dbe_lock, flags); + + /* Now, if we found one, we are running inside it now, hence + we cannot unload the module, hence no refcnt needed. */ + return e; +} + +/* Put in dbe list if neccessary. */ +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *me) +{ + const Elf_Shdr *s; + char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + + INIT_LIST_HEAD(&me->arch.dbe_list); + for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { + if (strcmp("__dbe_table", secstrings + s->sh_name) != 0) + continue; + me->arch.dbe_start = (void *)s->sh_addr; + me->arch.dbe_end = (void *)s->sh_addr + s->sh_size; + spin_lock_irq(&dbe_lock); + list_add(&me->arch.dbe_list, &dbe_list); + spin_unlock_irq(&dbe_lock); + } + return 0; +} + +void module_arch_cleanup(struct module *mod) +{ + spin_lock_irq(&dbe_lock); + list_del(&mod->arch.dbe_list); + spin_unlock_irq(&dbe_lock); +} diff -Nru a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S --- a/arch/mips/kernel/scall32-o32.S 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/kernel/scall32-o32.S 2004-06-26 17:09:15 -07:00 @@ -627,6 +627,7 @@ sys sys_mq_timedreceive 5 sys sys_mq_notify 2 /* 4275 */ sys sys_mq_getsetattr 3 + sys sys_ni_syscall 0 /* sys_vserver */ .endm diff -Nru a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S --- a/arch/mips/kernel/scall64-64.S 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/kernel/scall64-64.S 2004-06-26 17:09:19 -07:00 @@ -447,3 +447,4 @@ PTR sys_mq_timedreceive PTR sys_mq_notify PTR sys_mq_getsetattr /* 5235 */ + PTR sys_ni_syscall /* sys_vserver */ diff -Nru a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S --- a/arch/mips/kernel/scall64-n32.S 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/kernel/scall64-n32.S 2004-06-26 17:09:20 -07:00 @@ -357,3 +357,4 @@ PTR compat_sys_mq_timedreceive PTR compat_sys_mq_notify PTR compat_sys_mq_getsetattr /* 6239 */ + PTR sys_ni_syscall /* sys_vserver */ diff -Nru a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S --- a/arch/mips/kernel/scall64-o32.S 2004-06-26 17:09:14 -07:00 +++ b/arch/mips/kernel/scall64-o32.S 2004-06-26 17:09:14 -07:00 @@ -535,6 +535,7 @@ sys compat_sys_mq_timedreceive 5 sys compat_sys_mq_notify 2 /* 4275 */ sys compat_sys_mq_getsetattr 3 + sys sys_ni_syscall 0 /* sys_vserver */ .endm diff -Nru a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c --- a/arch/mips/kernel/semaphore.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/kernel/semaphore.c 2004-06-26 17:09:19 -07:00 @@ -1,273 +1,165 @@ /* - * Copyright (C) 1999, 2001, 02, 03 Ralf Baechle + * MIPS-specific semaphore code. * - * Heavily inspired by the Alpha implementation + * Copyright (C) 1999 Cort Dougan + * Copyright (C) 2004 Ralf Baechle + * + * 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. + * + * April 2001 - Reworked by Paul Mackerras + * to eliminate the SMP races in the old version between the updates + * of `count' and `waking'. Now we use negative `count' values to + * indicate that some process(es) are waiting for the semaphore. */ + #include -#include #include -#include #include +#include +#include +#include +#include -#ifdef CONFIG_CPU_HAS_LLDSCD -/* - * On machines without lld/scd we need a spinlock to make the manipulation of - * sem->count and sem->waking atomic. Scalability isn't an issue because - * this lock is used on UP only so it's just an empty variable. - */ -spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; - -EXPORT_SYMBOL(semaphore_lock); -#endif +#ifdef CONFIG_CPU_HAS_LLSC /* - * Semaphores are implemented using a two-way counter: The "count" variable is - * decremented for each process that tries to sleep, while the "waking" variable - * is incremented when the "up()" code goes to wake up waiting processes. - * - * Notably, the inline "up()" and "down()" functions can efficiently test if - * they need to do any extra work (up needs to do something only if count was - * negative before the increment operation. - * - * waking_non_zero() must execute atomically. - * - * When __up() is called, the count was negative before incrementing it, and we - * need to wake up somebody. + * Atomically update sem->count. + * This does the equivalent of the following: * - * This routine adds one to the count of processes that need to wake up and - * exit. ALL waiting processes actually wake up but only the one that gets to - * the "waking" field first will gate through and acquire the semaphore. The - * others will go back to sleep. - * - * Note that these functions are only called when there is contention on the - * lock, and as such all this is the "non-critical" part of the whole semaphore - * business. The critical part is the inline stuff in where - * we want to avoid any extra jumps and calls. + * old_count = sem->count; + * tmp = MAX(old_count, 0) + incr; + * sem->count = tmp; + * return old_count; */ -void __up_wakeup(struct semaphore *sem) -{ - wake_up(&sem->wait); -} - -EXPORT_SYMBOL(__up_wakeup); - -#ifdef CONFIG_CPU_HAS_LLSC - -static inline int waking_non_zero(struct semaphore *sem) +static inline int __sem_update_count(struct semaphore *sem, int incr) { - int ret, tmp; + int old_count, tmp; __asm__ __volatile__( - "1: ll %1, %2 # waking_non_zero \n" - " blez %1, 2f \n" - " subu %0, %1, 1 \n" - " sc %0, %2 \n" - " beqz %0, 1b \n" - "2: \n" - : "=r" (ret), "=r" (tmp), "+m" (sem->waking) - : "0" (0)); + "1: ll %0, %2 \n" + " sra %1, %0, 31 \n" + " not %1 \n" + " and %1, %0, %1 \n" + " add %1, %1, %3 \n" + " sc %1, %2 \n" + " beqz %1, 1b \n" + : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) + : "r" (incr), "m" (sem->count)); - return ret; + return old_count; } -#else /* !CONFIG_CPU_HAS_LLSC */ +#else + +/* + * On machines without lld/scd we need a spinlock to make the manipulation of + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; -static inline int waking_non_zero(struct semaphore *sem) +static inline int __sem_update_count(struct semaphore *sem, int incr) { unsigned long flags; - int waking, ret = 0; + int old_count, tmp; spin_lock_irqsave(&semaphore_lock, flags); - waking = atomic_read(&sem->waking); - if (waking > 0) { - atomic_set(&sem->waking, waking - 1); - ret = 1; - } + old_count = atomic_read(&sem->count); + tmp = max_t(int, old_count, 0) + incr; + atomic_set(&sem->count, tmp); spin_unlock_irqrestore(&semaphore_lock, flags); - return ret; + return old_count; } -#endif /* !CONFIG_CPU_HAS_LLSC */ - -/* - * Perform the "down" function. Return zero for semaphore acquired, return - * negative for signalled out of the function. - * - * If called from down, the return is ignored and the wait loop is not - * interruptible. This means that a task waiting on a semaphore using "down()" - * cannot be killed until someone does an "up()" on the semaphore. - * - * If called from down_interruptible, the return value gets checked upon return. - * If the return value is negative then the task continues with the negative - * value in the return register (it can be tested by the caller). - * - * Either form may be used in conjunction with "up()". - */ +#endif -void __sched __down_failed(struct semaphore * sem) +void __up(struct semaphore *sem) { - struct task_struct *tsk = current; - wait_queue_t wait; - - init_waitqueue_entry(&wait, tsk); - __set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue_exclusive(&sem->wait, &wait); - /* - * Ok, we're set up. sem->count is known to be less than zero - * so we must wait. - * - * We can let go the lock for purposes of waiting. - * We re-acquire it after awaking so as to protect - * all semaphore operations. - * - * If "up()" is called before we call waking_non_zero() then - * we will catch it right away. If it is called later then - * we will have to go through a wakeup cycle to catch it. - * - * Multiple waiters contend for the semaphore lock to see - * who gets to gate through and who has to wait some more. + * Note that we incremented count in up() before we came here, + * but that was ineffective since the result was <= 0, and + * any negative value of count is equivalent to 0. + * This ends up setting count to 1, unless count is now > 0 + * (i.e. because some other cpu has called up() in the meantime), + * in which case we just increment count. */ - for (;;) { - if (waking_non_zero(sem)) - break; - schedule(); - __set_current_state(TASK_UNINTERRUPTIBLE); - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&sem->wait, &wait); + __sem_update_count(sem, 1); + wake_up(&sem->wait); } -EXPORT_SYMBOL(__down_failed); - -#ifdef CONFIG_CPU_HAS_LLDSCD +EXPORT_SYMBOL(__up); /* - * waking_non_zero_interruptible: - * 1 got the lock - * 0 go to sleep - * -EINTR interrupted - * - * We must undo the sem->count down_interruptible decrement - * simultaneously and atomically with the sem->waking adjustment, - * otherwise we can race with wake_one_more. - * - * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. - * - * This is crazy. Normally it's strictly forbidden to use 64-bit operations - * in the 32-bit MIPS kernel. In this case it's however ok because if an - * interrupt has destroyed the upper half of registers sc will fail. - * Note also that this will not work for MIPS32 CPUs! - * - * Pseudocode: - * - * If(sem->waking > 0) { - * Decrement(sem->waking) - * Return(SUCCESS) - * } else If(signal_pending(tsk)) { - * Increment(sem->count) - * Return(-EINTR) - * } else { - * Return(SLEEP) - * } + * Note that when we come in to __down or __down_interruptible, + * we have already decremented count, but that decrement was + * ineffective since the result was < 0, and any negative value + * of count is equivalent to 0. + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. */ - -static inline int -waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) +void __sched __down(struct semaphore *sem) { - long ret, tmp; - - __asm__ __volatile__( - " .set push # waking_non_zero_interruptible \n" - " .set mips3 \n" - " .set noat \n" - "0: lld %1, %2 \n" - " li %0, 0 \n" - " sll $1, %1, 0 \n" - " blez $1, 1f \n" - " daddiu %1, %1, -1 \n" - " li %0, 1 \n" - " b 2f \n" - "1: beqz %3, 2f \n" - " li %0, %4 \n" - " dli $1, 0x0000000100000000 \n" - " daddu %1, %1, $1 \n" - "2: scd %1, %2 \n" - " beqz %1, 0b \n" - " .set pop \n" - : "=&r" (ret), "=&r" (tmp), "=m" (*sem) - : "r" (signal_pending(tsk)), "i" (-EINTR)); - - return ret; -} - -#else /* !CONFIG_CPU_HAS_LLDSCD */ - -static inline int waking_non_zero_interruptible(struct semaphore *sem, - struct task_struct *tsk) -{ - int waking, pending, ret = 0; - unsigned long flags; + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); - pending = signal_pending(tsk); + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); - spin_lock_irqsave(&semaphore_lock, flags); - waking = atomic_read(&sem->waking); - if (waking > 0) { - atomic_set(&sem->waking, waking - 1); - ret = 1; - } else if (pending) { - atomic_set(&sem->count, atomic_read(&sem->count) + 1); - ret = -EINTR; + /* + * Try to get the semaphore. If the count is > 0, then we've + * got the semaphore; we decrement count and exit the loop. + * If the count is 0 or negative, we set it to -1, indicating + * that we are asleep, and then sleep. + */ + while (__sem_update_count(sem, -1) <= 0) { + schedule(); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); } - spin_unlock_irqrestore(&semaphore_lock, flags); + remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); - return ret; + /* + * If there are any more sleepers, wake one of them up so + * that it can either get the semaphore, or set count to -1 + * indicating that there are still processes sleeping. + */ + wake_up(&sem->wait); } -#endif /* !CONFIG_CPU_HAS_LLDSCD */ +EXPORT_SYMBOL(__down); -int __sched __down_failed_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { + int retval = 0; struct task_struct *tsk = current; - wait_queue_t wait; - int ret = 0; + DECLARE_WAITQUEUE(wait, tsk); - init_waitqueue_entry(&wait, tsk); - __set_current_state(TASK_INTERRUPTIBLE); + __set_task_state(tsk, TASK_INTERRUPTIBLE); add_wait_queue_exclusive(&sem->wait, &wait); - /* - * Ok, we're set up. sem->count is known to be less than zero - * so we must wait. - * - * We can let go the lock for purposes of waiting. - * We re-acquire it after awaking so as to protect - * all semaphore operations. - * - * If "up()" is called before we call waking_non_zero() then - * we will catch it right away. If it is called later then - * we will have to go through a wakeup cycle to catch it. - * - * Multiple waiters contend for the semaphore lock to see - * who gets to gate through and who has to wait some more. - */ - for (;;) { - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; + while (__sem_update_count(sem, -1) <= 0) { + if (signal_pending(current)) { + /* + * A signal is pending - give up trying. + * Set sem->count to 0 if it is negative, + * since we are no longer sleeping. + */ + __sem_update_count(sem, 0); + retval = -EINTR; break; } schedule(); - __set_current_state(TASK_INTERRUPTIBLE); + set_task_state(tsk, TASK_INTERRUPTIBLE); } - __set_current_state(TASK_RUNNING); remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); - return ret; + wake_up(&sem->wait); + return retval; } -EXPORT_SYMBOL(__down_failed_interruptible); +EXPORT_SYMBOL(__down_interruptible); diff -Nru a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c --- a/arch/mips/kernel/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/kernel/setup.c 2004-06-26 17:09:16 -07:00 @@ -71,7 +71,6 @@ struct boot_mem_map boot_mem_map; static char command_line[CL_SIZE]; - char saved_command_line[CL_SIZE]; char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE; /* @@ -453,14 +452,18 @@ void __init setup_arch(char **cmdline_p) { + unsigned int status; + cpu_probe(); prom_init(); cpu_report(); #ifdef CONFIG_MIPS32 /* Disable coprocessors and set FPU for 16/32 FPR register model */ - clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); - set_c0_status(ST0_CU0); + status = read_c0_status(); + status &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); + status |= ST0_CU0; + write_c0_status(status); #endif #ifdef CONFIG_MIPS64 /* @@ -468,8 +471,10 @@ * Maybe because the kernel is in ckseg0 and not xkphys? Clear it * anyway ... */ - clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); - set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + status = read_c0_status(); + status &= ~(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); + status |= (ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + write_c0_status(status); #endif #if defined(CONFIG_VT) diff -Nru a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c --- a/arch/mips/kernel/syscall.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/kernel/syscall.c 2004-06-26 17:09:20 -07:00 @@ -36,7 +36,7 @@ #include #include -asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs) +asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs) { int fd[2]; int error, res; diff -Nru a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c --- a/arch/mips/kernel/sysirix.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/kernel/sysirix.c 2004-06-26 17:09:20 -07:00 @@ -1639,7 +1639,7 @@ printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n", current->comm, current->pid, fname, buf); - error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)); + error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64)); if(error) goto out; error = user_path_walk(fname, &nd); diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c --- a/arch/mips/kernel/time.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/kernel/time.c 2004-06-26 17:09:17 -07:00 @@ -789,3 +789,8 @@ EXPORT_SYMBOL(to_tm); EXPORT_SYMBOL(rtc_set_time); EXPORT_SYMBOL(rtc_get_time); + +unsigned long long sched_clock(void) +{ + return (unsigned long long)jiffies*(1000000000/HZ); +} diff -Nru a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c --- a/arch/mips/kernel/traps.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/kernel/traps.c 2004-06-26 17:09:17 -07:00 @@ -234,6 +234,7 @@ void show_registers(struct pt_regs *regs) { show_regs(regs); + print_modules(); printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", current->comm, current->pid, current_thread_info(), current); show_stack(current, (long *) regs->regs[29]); @@ -278,47 +279,8 @@ ); } -#ifdef CONFIG_MDULES - -/* Given an address, look for it in the module exception tables. */ -const struct exception_table_entry *search_module_dbetables(unsigned long addr) -{ - unsigned long flags; - const struct exception_table_entry *e = NULL; - struct module *mod; - - spin_lock_irqsave(&modlist_lock, flags); - list_for_each_entry(mod, &modules, list) { - if (mod->arch.num_dbeentries == 0) - continue; - - e = search_extable(mod->arch.dbe_table_start, - mod->arch.dbe_table_end + - mod->arch.num_dbeentries - 1, - addr); - if (e) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - - /* Now, if we found one, we are running inside it now, hence - we cannot unload the module, hence no refcnt needed. */ - return e; -} - -#else - -/* Given an address, look for it in the exception tables. */ -static inline const struct exception_table_entry * -search_module_dbetables(unsigned long addr) -{ - return NULL; -} - -#endif - /* Given an address, look for it in the exception tables. */ -const struct exception_table_entry *search_dbe_tables(unsigned long addr) +static const struct exception_table_entry *search_dbe_tables(unsigned long addr) { const struct exception_table_entry *e; @@ -745,11 +707,24 @@ static inline void parity_protection_init(void) { switch (current_cpu_data.cputype) { + case CPU_24K: + /* 24K cache parity not currently implemented in FPGA */ + printk(KERN_INFO "Disable cache parity protection for " + "MIPS 24K CPU.\n"); + write_c0_ecc(read_c0_ecc() & ~0x80000000); + break; case CPU_5KC: /* Set the PE bit (bit 31) in the c0_ecc register. */ - printk(KERN_INFO "Enable the cache parity protection for " - "MIPS 5KC CPUs.\n"); + printk(KERN_INFO "Enable cache parity protection for " + "MIPS 5KC/24K CPUs.\n"); write_c0_ecc(read_c0_ecc() | 0x80000000); + break; + case CPU_20KC: + case CPU_25KF: + /* Clear the DE bit (bit 16) in the c0_status register. */ + printk(KERN_INFO "Enable cache parity protection for " + "MIPS 20KC/25KF CPUs.\n"); + clear_c0_status(ST0_DE); break; default: break; diff -Nru a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile --- a/arch/mips/lib-32/Makefile 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/lib-32/Makefile 2004-06-26 17:09:16 -07:00 @@ -4,10 +4,22 @@ lib-y += csum_partial.o memset.o watch.o -ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) - lib-y += r3k_dump_tlb.o -else - lib-y += dump_tlb.o -endif +obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o +obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o +obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o +obj-$(CONFIG_CPU_R10000) += dump_tlb.o +obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_R4300) += dump_tlb.o +obj-$(CONFIG_CPU_R4X00) += dump_tlb.o +obj-$(CONFIG_CPU_R5000) += dump_tlb.o +obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R6000) += +obj-$(CONFIG_CPU_R8000) += +obj-$(CONFIG_CPU_RM7000) += dump_tlb.o +obj-$(CONFIG_CPU_RM9000) += dump_tlb.o +obj-$(CONFIG_CPU_SB1) += dump_tlb.o +obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o +obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile --- a/arch/mips/lib-64/Makefile 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/lib-64/Makefile 2004-06-26 17:09:17 -07:00 @@ -4,10 +4,22 @@ lib-y += csum_partial.o memset.o watch.o -ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) - lib-y += r3k_dump_tlb.o -else - lib-y += dump_tlb.o -endif +obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o +obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o +obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o +obj-$(CONFIG_CPU_R10000) += dump_tlb.o +obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_R4300) += dump_tlb.o +obj-$(CONFIG_CPU_R4X00) += dump_tlb.o +obj-$(CONFIG_CPU_R5000) += dump_tlb.o +obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R6000) += +obj-$(CONFIG_CPU_R8000) += +obj-$(CONFIG_CPU_RM7000) += dump_tlb.o +obj-$(CONFIG_CPU_RM9000) += dump_tlb.o +obj-$(CONFIG_CPU_SB1) += dump_tlb.o +obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o +obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c --- a/arch/mips/mips-boards/generic/cmdline.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/mips-boards/generic/cmdline.c 2004-06-26 17:09:19 -07:00 @@ -51,7 +51,9 @@ *cp++ = ' '; actr++; } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + if (cp != &(arcs_cmdline[0])) { + /* get rid of trailing space */ --cp; - *cp = '\0'; + *cp = '\0'; + } } diff -Nru a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c --- a/arch/mips/mips-boards/generic/printf.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/mips-boards/generic/printf.c 2004-06-26 17:09:19 -07:00 @@ -59,7 +59,7 @@ outb(value, PORT(offset)); } -int putPromChar(char c) +int prom_putchar(char c) { while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; @@ -69,7 +69,7 @@ return 1; } -char getPromChar(void) +char prom_getchar(void) { while (!(serial_in(UART_LSR) & UART_LSR_DR)) ; @@ -77,33 +77,3 @@ return serial_in(UART_RX); } -static spinlock_t con_lock = SPIN_LOCK_UNLOCKED; - -static char buf[1024]; - -void __init prom_printf(char *fmt, ...) -{ - va_list args; - int l; - char *p, *buf_end; - long flags; - - spin_lock_irqsave(con_lock, flags); - - va_start(args, fmt); - l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ - va_end(args); - - buf_end = buf + l; - - for (p = buf; p < buf_end; p++) { - /* Crude cr/nl handling is better than none */ - if (*p == '\n') - putPromChar('\r'); - putPromChar(*p); - } - /* wait for output to drain */ - while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0) - ; - spin_unlock_irqrestore(con_lock, flags); -} diff -Nru a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile --- a/arch/mips/mm/Makefile 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/mm/Makefile 2004-06-26 17:09:18 -07:00 @@ -12,18 +12,53 @@ obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o pg-r4k.o tlb-andes.o -obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o tlbex-r3k.o +obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o +obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_SB1) += c-sb1.o cerr-sb1.o cex-sb1.o pg-sb1.o \ tlb-sb1.o -obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o + +# +# TLB exception handling code differs between 32-bit and 64-bit kernels. +# +ifdef CONFIG_MIPS32 +obj-$(CONFIG_CPU_R3000) += tlbex32-r3k.o +obj-$(CONFIG_CPU_TX49XX) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R4300) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R4X00) += tlbex32-r4k.o +obj-$(CONFIG_CPU_VR41XX) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R5000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_NEVADA) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R5432) += tlbex32-r4k.o +obj-$(CONFIG_CPU_RM7000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_RM9000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R10000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_MIPS32) += tlbex32-r4k.o +obj-$(CONFIG_CPU_MIPS64) += tlbex32-r4k.o +obj-$(CONFIG_CPU_SB1) += tlbex32-r4k.o +obj-$(CONFIG_CPU_TX39XX) += tlbex32-r3k.o +endif +ifdef CONFIG_MIPS64 +obj-$(CONFIG_CPU_R4300) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R4X00) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R5000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_NEVADA) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R5432) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_RM7000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_RM9000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R10000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_SB1) += tlb64-glue-sb1.o tlbex64-r4k.o +obj-$(CONFIG_CPU_MIPS64) += tlb64-glue-r4k.o tlbex64-r4k.o +endif + obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o diff -Nru a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c --- a/arch/mips/mm/pgtable.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/mm/pgtable.c 2004-06-26 17:09:17 -07:00 @@ -12,7 +12,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); pfn = max_mapnr; while (pfn-- > 0) { page = pfn_to_page(pfn); diff -Nru a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/mm/tlb-r8k.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,253 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern void except_vec0_generic(void); +extern void except_vec1_r8k(void); + +#define TFP_TLB_SIZE 384 +#define TFP_TLB_SET_SHIFT 7 + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi(); + write_c0_entrylo(0); + + for (entry = 0; entry < TFP_TLB_SIZE; entry++) { + write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT); + write_c0_vaddr(entry << PAGE_SHIFT); + write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); + mtc0_tlbw_hazard(); + tlb_write(); + } + tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) + drop_mmu_context(mm,cpu); +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int cpu = smp_processor_id(); + unsigned long flags; + int oldpid, newpid, size; + + if (!cpu_context(cpu, mm)) + return; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + local_irq_save(flags); + + if (size > TFP_TLB_SIZE / 2) { + drop_mmu_context(mm, cpu); + goto out_restore; + } + + oldpid = read_c0_entryhi(); + newpid = cpu_asid(cpu, mm); + + write_c0_entrylo(0); + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + while (start < end) { + signed long idx; + + write_c0_vaddr(start); + write_c0_entryhi(start); + start += PAGE_SIZE; + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + continue; + + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + } + write_c0_entryhi(oldpid); + +out_restore: + local_irq_restore(flags); +} + +/* Usable for KV1 addresses only! */ +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + if (size > TFP_TLB_SIZE / 2) { + local_flush_tlb_all(); + return; + } + + local_irq_save(flags); + + write_c0_entrylo(0); + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + while (start < end) { + signed long idx; + + write_c0_vaddr(start); + write_c0_entryhi(start); + start += PAGE_SIZE; + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + continue; + + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + } + + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + int cpu = smp_processor_id(); + unsigned long flags; + int oldpid, newpid; + signed long idx; + + if (!cpu_context(cpu, vma->vm_mm)) + return; + + newpid = cpu_asid(cpu, vma->vm_mm); + page &= PAGE_MASK; + local_irq_save(flags); + oldpid = read_c0_entryhi(); + write_c0_vaddr(page); + write_c0_entryhi(newpid); + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + goto finish; + + write_c0_entrylo(0); + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + +finish: + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} + +/* + * We will need multiple versions of update_mmu_cache(), one that just + * updates the TLB with the new pte(s), and another which also checks + * for the R4k "end of page" hardware bug and does the needy. + */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + address &= PAGE_MASK; + write_c0_vaddr(address); + write_c0_entryhi(pid); + pgdp = pgd_offset(vma->vm_mm, address); + pmdp = pmd_offset(pgdp, address); + ptep = pte_offset_map(pmdp, address); + tlb_probe(); + + write_c0_entrylo(pte_val(*ptep++) >> 6); + tlb_write(); + + write_c0_entryhi(pid); + local_irq_restore(flags); +} + +static void __init probe_tlb(unsigned long config) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + c->tlbsize = 3 * 128; /* 3 sets each 128 entries */ +} + +void __init tlb_init(void) +{ + unsigned int config = read_c0_config(); + unsigned long status; + + probe_tlb(config); + + status = read_c0_status(); + status &= ~(ST0_UPS | ST0_KPS); +#ifdef CONFIG_PAGE_SIZE_4KB + status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36); +#elif defined(CONFIG_PAGE_SIZE_8KB) + status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36); +#elif defined(CONFIG_PAGE_SIZE_16KB) + status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36); +#elif defined(CONFIG_PAGE_SIZE_64KB) + status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36); +#endif + write_c0_status(status); + + write_c0_wired(0); + + local_flush_tlb_all(); + + memcpy((void *)(CKSEG0 + 0x00), &except_vec0_generic, 0x80); + memcpy((void *)(CKSEG0 + 0x80), except_vec1_r8k, 0x80); + flush_icache_range(CKSEG0 + 0x80, CKSEG0 + 0x100); +} diff -Nru a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c --- a/arch/mips/mm/tlb-sb1.c 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/mm/tlb-sb1.c 2004-06-26 17:09:21 -07:00 @@ -125,7 +125,7 @@ * with the firmware, go back and give all the entries invalid addresses with * the normal flush routine. Wired entries will be killed as well! */ -void sb1_sanitize_tlb(void) +static void __init sb1_sanitize_tlb(void) { int entry; long addr = 0; diff -Nru a/arch/mips/mm/tlb64-glue-r4k.S b/arch/mips/mm/tlb64-glue-r4k.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/mm/tlb64-glue-r4k.S 2004-06-26 17:09:20 -07:00 @@ -0,0 +1,41 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 + tlb_handler xtlb_tlbl kmode 0 + tlb_handler xtlb_tlbs kmode 1 diff -Nru a/arch/mips/mm/tlb64-glue-sb1.S b/arch/mips/mm/tlb64-glue-sb1.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/mm/tlb64-glue-sb1.S 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,66 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + .macro tlb_handler_m3 name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT + 1 + bnez k0, 1f + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault +1: + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 +#if BCM1250_M3_WAR + tlb_handler_m3 xtlb_tlbl kmode 0 +#else + tlb_handler xtlb_tlbl kmode 0 +#endif + tlb_handler xtlb_tlbs kmode 1 diff -Nru a/arch/mips/mm/tlbex-r3k.S b/arch/mips/mm/tlbex-r3k.S --- a/arch/mips/mm/tlbex-r3k.S 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,224 +0,0 @@ -/* - * TLB exception handling code for R2000/R3000. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-CPU abstraction reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Further modifications to make this work: - * Copyright (c) 1998 Harald Koerfgen - * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov - * Copyright (c) 2001 Ralf Baechle - * Copyright (c) 2001 MIPS Technologies, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - - .text - .set mips1 - .set noreorder - - __INIT - - /* TLB refill, R[23]00 version */ - LEAF(except_vec0_r2300) - .set noat - .set mips1 - mfc0 k0, CP0_BADVADDR - lw k1, pgd_current # get pgd pointer - srl k0, k0, 22 - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - and k0, k0, 0xffc - addu k1, k1, k0 - lw k0, (k1) - nop - mtc0 k0, CP0_ENTRYLO0 - mfc0 k1, CP0_EPC - tlbwr - jr k1 - rfe - END(except_vec0_r2300) - - __FINIT - - /* ABUSE of CPP macros 101. */ - - /* After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ -#define LOAD_PTE(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, pgd_current; \ - srl pte, pte, 22; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_CONTEXT; \ - lw ptr, (ptr); \ - andi pte, pte, 0xffc; \ - addu ptr, ptr, pte; \ - lw pte, (ptr); \ - nop; - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr) \ - lw ptr, (ptr) ; \ - nop ; \ - mtc0 ptr, CP0_ENTRYLO0; \ - nop; - -#define DO_FAULT(write) \ - .set noat; \ - .set macro; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; \ - .set nomacro; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - sw pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - sw pte, (ptr); - -/* - * The index register may have the probe fail bit set, - * because we would trap on access kseg2, i.e. without refill. - */ -#define TLB_WRITE(reg) \ - mfc0 reg, CP0_INDEX; \ - nop; \ - bltz reg, 1f; \ - nop; \ - tlbwi; \ - j 2f; \ - nop; \ -1: tlbwr; \ -2: - -#define RET(reg) \ - mfc0 reg, CP0_EPC; \ - nop; \ - jr reg; \ - rfe - - .set noreorder - - .align 5 -NESTED(handle_tlbl, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbl: -#endif - - DO_FAULT(0) -END(handle_tlbl) - -NESTED(handle_tlbs, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbs: -#endif - - DO_FAULT(1) -END(handle_tlbs) - - .align 5 -NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - .set push - .set reorder - lw k0, (k1) - .set pop - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1) - tlbwi - RET(k0) -#endif - -nowrite_mod: - DO_FAULT(1) -END(handle_mod) diff -Nru a/arch/mips/mm/tlbex32-r3k.S b/arch/mips/mm/tlbex32-r3k.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/mm/tlbex32-r3k.S 2004-06-26 17:09:19 -07:00 @@ -0,0 +1,224 @@ +/* + * TLB exception handling code for R2000/R3000. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-CPU abstraction reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Further modifications to make this work: + * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov + * Copyright (c) 2001 Ralf Baechle + * Copyright (c) 2001 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + + .text + .set mips1 + .set noreorder + + __INIT + + /* TLB refill, R[23]00 version */ + LEAF(except_vec0_r2300) + .set noat + .set mips1 + mfc0 k0, CP0_BADVADDR + lw k1, pgd_current # get pgd pointer + srl k0, k0, 22 + sll k0, k0, 2 + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + and k0, k0, 0xffc + addu k1, k1, k0 + lw k0, (k1) + nop + mtc0 k0, CP0_ENTRYLO0 + mfc0 k1, CP0_EPC + tlbwr + jr k1 + rfe + END(except_vec0_r2300) + + __FINIT + + /* ABUSE of CPP macros 101. */ + + /* After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ +#define LOAD_PTE(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, pgd_current; \ + srl pte, pte, 22; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_CONTEXT; \ + lw ptr, (ptr); \ + andi pte, pte, 0xffc; \ + addu ptr, ptr, pte; \ + lw pte, (ptr); \ + nop; + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr) \ + lw ptr, (ptr) ; \ + nop ; \ + mtc0 ptr, CP0_ENTRYLO0; \ + nop; + +#define DO_FAULT(write) \ + .set noat; \ + .set macro; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; \ + .set nomacro; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + sw pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + sw pte, (ptr); + +/* + * The index register may have the probe fail bit set, + * because we would trap on access kseg2, i.e. without refill. + */ +#define TLB_WRITE(reg) \ + mfc0 reg, CP0_INDEX; \ + nop; \ + bltz reg, 1f; \ + nop; \ + tlbwi; \ + j 2f; \ + nop; \ +1: tlbwr; \ +2: + +#define RET(reg) \ + mfc0 reg, CP0_EPC; \ + nop; \ + jr reg; \ + rfe + + .set noreorder + + .align 5 +NESTED(handle_tlbl, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbl: +#endif + + DO_FAULT(0) +END(handle_tlbl) + +NESTED(handle_tlbs, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbs: +#endif + + DO_FAULT(1) +END(handle_tlbs) + + .align 5 +NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + .set push + .set reorder + lw k0, (k1) + .set pop + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1) + tlbwi + RET(k0) +#endif + +nowrite_mod: + DO_FAULT(1) +END(handle_mod) diff -Nru a/arch/mips/mm/tlbex32-r4k.S b/arch/mips/mm/tlbex32-r4k.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/mm/tlbex32-r4k.S 2004-06-26 17:09:20 -07:00 @@ -0,0 +1,524 @@ +/* + * TLB exception handling code for r4k. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-cpu abstraction and reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PTE_L ld +#define PTE_S sd +#define PTE_SRL dsrl +#define P_MTC0 dmtc0 +#define PTE_SIZE 8 +#define PTEP_INDX_MSK 0xff0 +#define PTE_INDX_MSK 0xff8 +#define PTE_INDX_SHIFT 9 +#else +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_SIZE 4 +#define PTEP_INDX_MSK 0xff8 +#define PTE_INDX_MSK 0xffc +#define PTE_INDX_SHIFT 10 +#endif + +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, _PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, PTE_SIZE(ptr); \ + PTE_L ptr, 0(ptr); \ + PTE_SRL tmp, tmp, 6; \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_SRL ptr, ptr, 6; \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + + __INIT + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define GET_PTE_OFF(reg) +#elif CONFIG_CPU_VR41XX +#define GET_PTE_OFF(reg) srl reg, reg, 3 +#else +#define GET_PTE_OFF(reg) srl reg, reg, 1 +#endif + +/* + * These handlers much be written in a relocatable manner + * because based upon the cpu type an arbitrary one of the + * following pieces of code will be copied to the KSEG0 + * vector location. + */ + /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ + .set noreorder + .set noat + LEAF(except_vec0_r4000) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + mtc0_tlbw_hazard + tlbwr # write random tlb entry + tlbw_eret_hazard + eret # return from trap + END(except_vec0_r4000) + + /* TLB refill, EXL == 0, R4600 version */ + LEAF(except_vec0_r4600) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 k1, CP0_ENTRYLO1 + nop + tlbwr + nop + eret + END(except_vec0_r4600) + + /* TLB refill, EXL == 0, R52x0 "Nevada" version */ + /* + * This version has a bug workaround for the Nevada. It seems + * as if under certain circumstances the move from cp0_context + * might produce a bogus result when the mfc0 instruction and + * it's consumer are in a different cacheline or a load instruction, + * probably any memory reference, is between them. This is + * potencially slower than the R4000 version, so we use this + * special version. + */ + .set noreorder + .set noat + LEAF(except_vec0_nevada) + .set mips3 + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + lw k1, pgd_current # get pgd pointer + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 # add in pgd offset + lw k1, (k1) + mfc0 k0, CP0_CONTEXT # get context reg + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + nop # QED specified nops + nop + tlbwr # write random tlb entry + nop # traditional nop + eret # return from trap + END(except_vec0_nevada) + + /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ + LEAF(except_vec0_sb1) +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + tlbwr # write random tlb entry +1: eret # return from trap + END(except_vec0_sb1) + + /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ + LEAF(except_vec0_r45k_bvahwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r45k_bvahwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ + LEAF(except_vec0_r4k_mphwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_mphwbug) +#endif + + /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ + LEAF(except_vec0_r4k_250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + b 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_250MHZhwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ + LEAF(except_vec0_r4k_MP250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + mfc0 k0, CP0_INDEX + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_MP250MHZhwbug) +#endif + + __FINIT + + .set noreorder + +/* + * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: + * 2. A timing hazard exists for the TLBP instruction. + * + * stalling_instruction + * TLBP + * + * The JTLB is being read for the TLBP throughout the stall generated by the + * previous instruction. This is not really correct as the stalling instruction + * can modify the address used to access the JTLB. The failure symptom is that + * the TLBP instruction will use an address created for the stalling instruction + * and not the address held in C0_ENHI and thus report the wrong results. + * + * The software work-around is to not allow the instruction preceding the TLBP + * to stall - make it an NOP or some other instruction guaranteed not to stall. + * + * Errata 2 will not be fixed. This errata is also on the R5000. + * + * As if we MIPS hackers wouldn't know how to nop pipelines happy ... + */ +#define R5K_HAZARD nop + + /* + * Note for many R4k variants tlb probes cannot be executed out + * of the instruction cache else you get bogus results. + */ + .align 5 + NESTED(handle_tlbl, PT_SIZE, sp) + .set noat +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + beqz k0, 1f + nop + .set mips3 + eret + .set mips0 +1: +#endif +invalid_tlbl: +#ifdef TLB_OPTIMIZE + .set mips3 + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbl: + DO_FAULT(0) + END(handle_tlbl) + + .align 5 + NESTED(handle_tlbs, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + li k0,0 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbs: + DO_FAULT(1) + END(handle_tlbs) + + .align 5 + NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + PTE_L k0, (k1) + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nowrite_mod: + DO_FAULT(1) + END(handle_mod) diff -Nru a/arch/mips/mm/tlbex64-r4k.S b/arch/mips/mm/tlbex64-r4k.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/mm/tlbex64-r4k.S 2004-06-26 17:09:16 -07:00 @@ -0,0 +1,203 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * Copyright (C) 2002 Maciej W. Rozycki + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define _VMALLOC_START 0xc000000000000000 + + /* + * After this macro runs we have a pointer to the pte of the address + * that caused the fault in PTR. + */ + .macro LOAD_PTE2, ptr, tmp, kaddr +#ifdef CONFIG_SMP + dmfc0 \ptr, CP0_CONTEXT + dmfc0 \tmp, CP0_BADVADDR + dsra \ptr, 23 # get pgd_current[cpu] +#else + dmfc0 \tmp, CP0_BADVADDR + dla \ptr, pgd_current +#endif + bltz \tmp, \kaddr + ld \ptr, (\ptr) + dsrl \tmp, (_PGDIR_SHIFT-3) # get pgd offset in bytes + andi \tmp, ((_PTRS_PER_PGD - 1)<<3) + daddu \ptr, \tmp # add in pgd offset + dmfc0 \tmp, CP0_BADVADDR + ld \ptr, (\ptr) # get pmd pointer + dsrl \tmp, (_PMD_SHIFT-3) # get pmd offset in bytes + andi \tmp, ((_PTRS_PER_PMD - 1)<<3) + daddu \ptr, \tmp # add in pmd offset + dmfc0 \tmp, CP0_XCONTEXT + ld \ptr, (\ptr) # get pte pointer + andi \tmp, 0xff0 # get pte offset + daddu \ptr, \tmp + .endm + + + /* + * Ditto for the kernel table. + */ + .macro LOAD_KPTE2, ptr, tmp, not_vmalloc + /* + * First, determine that the address is in/above vmalloc range. + */ + dmfc0 \tmp, CP0_BADVADDR + dli \ptr, _VMALLOC_START + + /* + * Now find offset into kptbl. + */ + dsubu \tmp, \tmp, \ptr + dla \ptr, kptbl + dsrl \tmp, (_PAGE_SHIFT+1) # get vpn2 + dsll \tmp, 4 # byte offset of pte + daddu \ptr, \ptr, \tmp + + /* + * Determine that fault address is within vmalloc range. + */ + dla \tmp, ekptbl + slt \tmp, \ptr, \tmp + beqz \tmp, \not_vmalloc # not vmalloc + nop + .endm + + + /* + * This places the even/odd pte pair in the page table at the pte + * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. + */ + .macro PTE_RELOAD, pte0, pte1 + dsrl \pte0, 6 # convert to entrylo0 + dmtc0 \pte0, CP0_ENTRYLO0 # load it + dsrl \pte1, 6 # convert to entrylo1 + dmtc0 \pte1, CP0_ENTRYLO1 # load it + .endm + + + .text + .set noreorder + .set mips3 + + __INIT + + /* + * TLB refill handlers for the R4000 and SB1. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r4k) + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop +END(except_vec1_r4k) + +LEAF(except_vec1_sb1) +#if BCM1250_M3_WAR + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, _PAGE_SHIFT+1 + bnez k0, 1f +#endif + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop + +1: eret + nop +END(except_vec1_sb1) + + __FINIT + + .align 5 +LEAF(handle_vec1_r4k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + mtc0_tlbw_hazard + tlbwr + tlbw_eret_hazard + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + mtc0_tlbw_hazard + tlbwr + tlbw_eret_hazard + eret +END(handle_vec1_r4k) + + + __INIT + + /* + * TLB refill handler for the R10000. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r10k) + .set noat + dla k0, handle_vec1_r10k + jr k0 + nop +END(except_vec1_r10k) + + __FINIT + + .align 5 +LEAF(handle_vec1_r10k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret +END(handle_vec1_r10k) + + + .align 5 +LEAF(invalid_vmalloc_address) + .set noat + SAVE_ALL + CLI + dmfc0 t0, CP0_BADVADDR + sd t0, PT_BVADDR(sp) + move a0, sp + jal show_regs + PANIC("Invalid kernel address") +END(invalid_vmalloc_address) diff -Nru a/arch/mips/mm-32/Makefile b/arch/mips/mm-32/Makefile --- a/arch/mips/mm-32/Makefile 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,19 +0,0 @@ -# -# Makefile for the Linux/MIPS-specific parts of the memory manager. -# - -obj-$(CONFIG_CPU_TX49XX) += tlbex-r4k.o -obj-$(CONFIG_CPU_R4300) += tlbex-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlbex-r4k.o -obj-$(CONFIG_CPU_VR41XX) += tlbex-r4k.o -obj-$(CONFIG_CPU_R5000) += tlbex-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlbex-r4k.o -obj-$(CONFIG_CPU_R5432) += tlbex-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlbex-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlbex-r4k.o -obj-$(CONFIG_CPU_R10000) += tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS32) += tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS64) += tlbex-r4k.o -obj-$(CONFIG_CPU_SB1) += tlbex-r4k.o - -EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/mm-32/tlbex-r4k.S b/arch/mips/mm-32/tlbex-r4k.S --- a/arch/mips/mm-32/tlbex-r4k.S 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,524 +0,0 @@ -/* - * TLB exception handling code for r4k. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-cpu abstraction and reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define PTE_L ld -#define PTE_S sd -#define PTE_SRL dsrl -#define P_MTC0 dmtc0 -#define PTE_SIZE 8 -#define PTEP_INDX_MSK 0xff0 -#define PTE_INDX_MSK 0xff8 -#define PTE_INDX_SHIFT 9 -#else -#define PTE_L lw -#define PTE_S sw -#define PTE_SRL srl -#define P_MTC0 mtc0 -#define PTE_SIZE 4 -#define PTEP_INDX_MSK 0xff8 -#define PTE_INDX_MSK 0xffc -#define PTE_INDX_SHIFT 10 -#endif - -/* - * ABUSE of CPP macros 101. - * - * After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, pgd_current;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, pgd_current; -#endif - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, PTE_INDX_SHIFT; \ - and pte, pte, PTE_INDX_MSK; \ - addu ptr, ptr, pte; \ - PTE_L pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, PTE_SIZE(ptr); \ - PTE_L ptr, 0(ptr); \ - PTE_SRL tmp, tmp, 6; \ - P_MTC0 tmp, CP0_ENTRYLO1; \ - PTE_SRL ptr, ptr, 6; \ - P_MTC0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - PTE_S pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - PTE_S pte, (ptr); - - __INIT - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define GET_PTE_OFF(reg) -#elif CONFIG_CPU_VR41XX -#define GET_PTE_OFF(reg) srl reg, reg, 3 -#else -#define GET_PTE_OFF(reg) srl reg, reg, 1 -#endif - -/* - * These handlers much be written in a relocatable manner - * because based upon the cpu type an arbitrary one of the - * following pieces of code will be copied to the KSEG0 - * vector location. - */ - /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ - .set noreorder - .set noat - LEAF(except_vec0_r4000) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - mfc0 k0, CP0_CONTEXT # get context reg - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - mtc0_tlbw_hazard - tlbwr # write random tlb entry - tlbw_eret_hazard - eret # return from trap - END(except_vec0_r4000) - - /* TLB refill, EXL == 0, R4600 version */ - LEAF(except_vec0_r4600) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - P_MTC0 k1, CP0_ENTRYLO1 - nop - tlbwr - nop - eret - END(except_vec0_r4600) - - /* TLB refill, EXL == 0, R52x0 "Nevada" version */ - /* - * This version has a bug workaround for the Nevada. It seems - * as if under certain circumstances the move from cp0_context - * might produce a bogus result when the mfc0 instruction and - * it's consumer are in a different cacheline or a load instruction, - * probably any memory reference, is between them. This is - * potencially slower than the R4000 version, so we use this - * special version. - */ - .set noreorder - .set noat - LEAF(except_vec0_nevada) - .set mips3 - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - lw k1, pgd_current # get pgd pointer - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 # add in pgd offset - lw k1, (k1) - mfc0 k0, CP0_CONTEXT # get context reg - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - nop # QED specified nops - nop - tlbwr # write random tlb entry - nop # traditional nop - eret # return from trap - END(except_vec0_nevada) - - /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ - LEAF(except_vec0_sb1) -#if BCM1250_M3_WAR - mfc0 k0, CP0_BADVADDR - mfc0 k1, CP0_ENTRYHI - xor k0, k1 - srl k0, k0, PAGE_SHIFT+1 - bnez k0, 1f -#endif - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - mfc0 k0, CP0_CONTEXT # get context reg - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - tlbwr # write random tlb entry -1: eret # return from trap - END(except_vec0_sb1) - - /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ - LEAF(except_vec0_r45k_bvahwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - mfc0 k0, CP0_INDEX - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r45k_bvahwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ - LEAF(except_vec0_r4k_mphwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - mfc0 k0, CP0_INDEX - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_mphwbug) -#endif - - /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ - LEAF(except_vec0_r4k_250MHZhwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - PTE_SRL k0, k0, 6 - P_MTC0 zero, CP0_ENTRYLO0 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - P_MTC0 zero, CP0_ENTRYLO1 - P_MTC0 k1, CP0_ENTRYLO1 - b 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_250MHZhwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ - LEAF(except_vec0_r4k_MP250MHZhwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 zero, CP0_ENTRYLO0 - P_MTC0 k0, CP0_ENTRYLO0 - mfc0 k0, CP0_INDEX - PTE_SRL k1, k1, 6 - P_MTC0 zero, CP0_ENTRYLO1 - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_MP250MHZhwbug) -#endif - - __FINIT - - .set noreorder - -/* - * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: - * 2. A timing hazard exists for the TLBP instruction. - * - * stalling_instruction - * TLBP - * - * The JTLB is being read for the TLBP throughout the stall generated by the - * previous instruction. This is not really correct as the stalling instruction - * can modify the address used to access the JTLB. The failure symptom is that - * the TLBP instruction will use an address created for the stalling instruction - * and not the address held in C0_ENHI and thus report the wrong results. - * - * The software work-around is to not allow the instruction preceding the TLBP - * to stall - make it an NOP or some other instruction guaranteed not to stall. - * - * Errata 2 will not be fixed. This errata is also on the R5000. - * - * As if we MIPS hackers wouldn't know how to nop pipelines happy ... - */ -#define R5K_HAZARD nop - - /* - * Note for many R4k variants tlb probes cannot be executed out - * of the instruction cache else you get bogus results. - */ - .align 5 - NESTED(handle_tlbl, PT_SIZE, sp) - .set noat -#if BCM1250_M3_WAR - mfc0 k0, CP0_BADVADDR - mfc0 k1, CP0_ENTRYHI - xor k0, k1 - srl k0, k0, PAGE_SHIFT+1 - beqz k0, 1f - nop - .set mips3 - eret - .set mips0 -1: -#endif -invalid_tlbl: -#ifdef TLB_OPTIMIZE - .set mips3 - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbl: - DO_FAULT(0) - END(handle_tlbl) - - .align 5 - NESTED(handle_tlbs, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - li k0,0 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbs: - DO_FAULT(1) - END(handle_tlbs) - - .align 5 - NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - PTE_L k0, (k1) - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nowrite_mod: - DO_FAULT(1) - END(handle_mod) diff -Nru a/arch/mips/mm-64/Makefile b/arch/mips/mm-64/Makefile --- a/arch/mips/mm-64/Makefile 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,25 +0,0 @@ -# -# Makefile for the Linux/MIPS-specific parts of the memory manager. -# - -obj-y := tlbex-r4k.o - -obj-$(CONFIG_CPU_R4300) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5432) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R10000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_SB1) += tlb-glue-sb1.o -obj-$(CONFIG_CPU_MIPS64) += tlb-glue-r4k.o - -# -# Debug TLB exception handler, currently unused -# -#obj-y += tlb-dbg-r4k.o - -AFLAGS_tlb-glue-r4k.o := -P - -EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/mm-64/tlb-dbg-r4k.c b/arch/mips/mm-64/tlb-dbg-r4k.c --- a/arch/mips/mm-64/tlb-dbg-r4k.c 2004-06-26 17:09:18 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,71 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - * - * TLB debugging routines. These perform horribly slow but can easily be - * modified for debugging purposes. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, - unsigned long address); - -asmlinkage void tlb_refill_debug(struct pt_regs regs) -{ - show_regs(®s); - panic("%s called. This Does Not Happen (TM).", __FUNCTION__); -} - -asmlinkage void xtlb_refill_debug(struct pt_regs *regs) -{ - unsigned long addr; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1); - pgd = pgd_offset(current->active_mm, addr); - pmd = pmd_offset(pgd, addr); - pte = pte_offset(pmd, addr); - - write_c0_entrylo0(pte_val(pte[0]) >> 6); - write_c0_entrylo1(pte_val(pte[1]) >> 6); - __asm__ __volatile__("nop;nop;nop"); - - tlb_write_random(); -} - -asmlinkage void xtlb_mod_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} - -asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 0, addr); -} - -asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} diff -Nru a/arch/mips/mm-64/tlb-glue-r4k.S b/arch/mips/mm-64/tlb-glue-r4k.S --- a/arch/mips/mm-64/tlb-glue-r4k.S 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,41 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 - tlb_handler xtlb_tlbl kmode 0 - tlb_handler xtlb_tlbs kmode 1 diff -Nru a/arch/mips/mm-64/tlb-glue-sb1.S b/arch/mips/mm-64/tlb-glue-sb1.S --- a/arch/mips/mm-64/tlb-glue-sb1.S 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,66 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - .macro tlb_handler_m3 name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - dmfc0 k0, CP0_BADVADDR - dmfc0 k1, CP0_ENTRYHI - xor k0, k1 - dsrl k0, k0, PAGE_SHIFT + 1 - bnez k0, 1f - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault -1: - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 -#if BCM1250_M3_WAR - tlb_handler_m3 xtlb_tlbl kmode 0 -#else - tlb_handler xtlb_tlbl kmode 0 -#endif - tlb_handler xtlb_tlbs kmode 1 diff -Nru a/arch/mips/mm-64/tlbex-r4k.S b/arch/mips/mm-64/tlbex-r4k.S --- a/arch/mips/mm-64/tlbex-r4k.S 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,203 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * Copyright (C) 2002 Maciej W. Rozycki - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define _VMALLOC_START 0xc000000000000000 - - /* - * After this macro runs we have a pointer to the pte of the address - * that caused the fault in PTR. - */ - .macro LOAD_PTE2, ptr, tmp, kaddr -#ifdef CONFIG_SMP - dmfc0 \ptr, CP0_CONTEXT - dmfc0 \tmp, CP0_BADVADDR - dsra \ptr, 23 # get pgd_current[cpu] -#else - dmfc0 \tmp, CP0_BADVADDR - dla \ptr, pgd_current -#endif - bltz \tmp, \kaddr - ld \ptr, (\ptr) - dsrl \tmp, (_PGDIR_SHIFT-3) # get pgd offset in bytes - andi \tmp, ((_PTRS_PER_PGD - 1)<<3) - daddu \ptr, \tmp # add in pgd offset - dmfc0 \tmp, CP0_BADVADDR - ld \ptr, (\ptr) # get pmd pointer - dsrl \tmp, (_PMD_SHIFT-3) # get pmd offset in bytes - andi \tmp, ((_PTRS_PER_PMD - 1)<<3) - daddu \ptr, \tmp # add in pmd offset - dmfc0 \tmp, CP0_XCONTEXT - ld \ptr, (\ptr) # get pte pointer - andi \tmp, 0xff0 # get pte offset - daddu \ptr, \tmp - .endm - - - /* - * Ditto for the kernel table. - */ - .macro LOAD_KPTE2, ptr, tmp, not_vmalloc - /* - * First, determine that the address is in/above vmalloc range. - */ - dmfc0 \tmp, CP0_BADVADDR - dli \ptr, _VMALLOC_START - - /* - * Now find offset into kptbl. - */ - dsubu \tmp, \tmp, \ptr - dla \ptr, kptbl - dsrl \tmp, (_PAGE_SHIFT+1) # get vpn2 - dsll \tmp, 4 # byte offset of pte - daddu \ptr, \ptr, \tmp - - /* - * Determine that fault address is within vmalloc range. - */ - dla \tmp, ekptbl - slt \tmp, \ptr, \tmp - beqz \tmp, \not_vmalloc # not vmalloc - nop - .endm - - - /* - * This places the even/odd pte pair in the page table at the pte - * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. - */ - .macro PTE_RELOAD, pte0, pte1 - dsrl \pte0, 6 # convert to entrylo0 - dmtc0 \pte0, CP0_ENTRYLO0 # load it - dsrl \pte1, 6 # convert to entrylo1 - dmtc0 \pte1, CP0_ENTRYLO1 # load it - .endm - - - .text - .set noreorder - .set mips3 - - __INIT - - /* - * TLB refill handlers for the R4000 and SB1. - * Attention: We may only use 32 instructions / 128 bytes. - */ - .align 5 -LEAF(except_vec1_r4k) - .set noat - dla k0, handle_vec1_r4k - jr k0 - nop -END(except_vec1_r4k) - -LEAF(except_vec1_sb1) -#if BCM1250_M3_WAR - dmfc0 k0, CP0_BADVADDR - dmfc0 k1, CP0_ENTRYHI - xor k0, k1 - dsrl k0, k0, _PAGE_SHIFT+1 - bnez k0, 1f -#endif - .set noat - dla k0, handle_vec1_r4k - jr k0 - nop - -1: eret - nop -END(except_vec1_sb1) - - __FINIT - - .align 5 -LEAF(handle_vec1_r4k) - .set noat - LOAD_PTE2 k1 k0 9f - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - mtc0_tlbw_hazard - tlbwr - tlbw_eret_hazard - eret - -9: # handle the vmalloc range - LOAD_KPTE2 k1 k0 invalid_vmalloc_address - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - mtc0_tlbw_hazard - tlbwr - tlbw_eret_hazard - eret -END(handle_vec1_r4k) - - - __INIT - - /* - * TLB refill handler for the R10000. - * Attention: We may only use 32 instructions / 128 bytes. - */ - .align 5 -LEAF(except_vec1_r10k) - .set noat - dla k0, handle_vec1_r10k - jr k0 - nop -END(except_vec1_r10k) - - __FINIT - - .align 5 -LEAF(handle_vec1_r10k) - .set noat - LOAD_PTE2 k1 k0 9f - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - nop - tlbwr - eret - -9: # handle the vmalloc range - LOAD_KPTE2 k1 k0 invalid_vmalloc_address - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - nop - tlbwr - eret -END(handle_vec1_r10k) - - - .align 5 -LEAF(invalid_vmalloc_address) - .set noat - SAVE_ALL - CLI - dmfc0 t0, CP0_BADVADDR - sd t0, PT_BVADDR(sp) - move a0, sp - jal show_regs - PANIC("Invalid kernel address") -END(invalid_vmalloc_address) diff -Nru a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c --- a/arch/mips/momentum/jaguar_atx/irq.c 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/momentum/jaguar_atx/irq.c 2004-06-26 17:09:18 -07:00 @@ -42,7 +42,7 @@ extern asmlinkage void jaguar_handle_int(void); static struct irqaction cascade_mv64340 = { - no_action, SA_INTERRUPT, 0, "MV64340-Cascade", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL }; void __init init_IRQ(void) diff -Nru a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c --- a/arch/mips/momentum/jaguar_atx/prom.c 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/momentum/jaguar_atx/prom.c 2004-06-26 17:09:21 -07:00 @@ -245,20 +245,6 @@ { } -/* - * SMP support - */ -int prom_setup_smp(void) -{ - int num_cpus = 2; - - /* - * We know that the RM9000 on the Jaguar ATX board has 2 cores. - * Hence, this can be hardcoded for now. - */ - return num_cpus; -} - int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) { /* Clear the semaphore */ diff -Nru a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c --- a/arch/mips/momentum/jaguar_atx/setup.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/momentum/jaguar_atx/setup.c 2004-06-26 17:09:20 -07:00 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,6 @@ #include #include #include -#include #include #include #include diff -Nru a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile --- a/arch/mips/momentum/ocelot_c/Makefile 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/momentum/ocelot_c/Makefile 2004-06-26 17:09:20 -07:00 @@ -2,7 +2,7 @@ # Makefile for Momentum Computer's Ocelot-C and -CS boards. # -obj-y += cpci-irq.o uart-irq.o int-handler.o irq.o pci-irq.o \ - prom.o reset.o setup.o +obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \ + setup.o uart-irq.o obj-$(CONFIG_KGDB) += dbg_io.o diff -Nru a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c --- a/arch/mips/momentum/ocelot_c/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/momentum/ocelot_c/irq.c 2004-06-26 17:09:20 -07:00 @@ -44,8 +44,9 @@ #include #include #include -#include +#include #include +#include #include extern asmlinkage void ocelot_handle_int(void); @@ -53,11 +54,11 @@ extern void cpci_irq_init(void); static struct irqaction cascade_fpga = { - no_action, SA_INTERRUPT, 0, "cascade via FPGA", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via FPGA", NULL, NULL }; static struct irqaction cascade_mv64340 = { - no_action, SA_INTERRUPT, 0, "cascade via MV64340", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL }; void __init init_IRQ(void) diff -Nru a/arch/mips/momentum/ocelot_c/pci-irq.c b/arch/mips/momentum/ocelot_c/pci-irq.c --- a/arch/mips/momentum/ocelot_c/pci-irq.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,72 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Based on work for the Linux port to the Ocelot board, which is - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/momentum/ocelot_g/pci.c - * Board-specific PCI routines for mv64340 controller. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include - - -void __init mv64340_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - /* loop over all known devices on this bus */ - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if ((current_bus->number == 0) && - (PCI_SLOT(devices->devfn) == 1) && - (PCI_FUNC(devices->devfn) == 0)) { - /* LSI 53C10101R SCSI (A) */ - devices->irq = 2; - } else if ((current_bus->number == 0) && - (PCI_SLOT(devices->devfn) == 1) && - (PCI_FUNC(devices->devfn) == 1)) { - /* LSI 53C10101R SCSI (B) */ - devices->irq = 2; - } else if ((current_bus->number == 1) && - (PCI_SLOT(devices->devfn) == 1)) { - /* Intel 21555 bridge */ - devices->irq = 12; - } else if ((current_bus->number == 1) && - (PCI_SLOT(devices->devfn) == 2)) { - /* PMC Slot */ - devices->irq = 4; - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); - - /* enable master for everything but the MV-64340 */ - if (((current_bus->number != 0) && (current_bus->number != 1)) - || (PCI_SLOT(devices->devfn) != 0)) { - bus->ops->read_word(devices, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write_word(devices, PCI_COMMAND, cmd); - } - } -} diff -Nru a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c --- a/arch/mips/momentum/ocelot_c/prom.c 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/momentum/ocelot_c/prom.c 2004-06-26 17:09:18 -07:00 @@ -147,13 +147,14 @@ #endif /* CONFIG_MIPS64 */ -/* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(void) { int argc = fw_arg0; char **arg = (char **) fw_arg1; char **env = (char **) fw_arg2; + struct callvectors *cv = (struct callvectors *) fw_arg3; int i; + #ifdef CONFIG_MIPS64 char *ptr; diff -Nru a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c --- a/arch/mips/momentum/ocelot_c/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/momentum/ocelot_c/setup.c 2004-06-26 17:09:16 -07:00 @@ -193,7 +193,7 @@ rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = CONV_BIN2BCD(tm.tm_wday + 1); + rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); /* disable writing */ rtc_base[0x7ff8] = 0x00; diff -Nru a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile --- a/arch/mips/momentum/ocelot_g/Makefile 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/momentum/ocelot_g/Makefile 2004-06-26 17:09:16 -07:00 @@ -2,8 +2,7 @@ # Makefile for Momentum Computer's Ocelot-G board. # -obj-y += gt-irq.o pci-irq.o int-handler.o irq.o prom.o \ - reset.o setup.o +obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o obj-$(CONFIG_KGDB) += dbg_io.o EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c --- a/arch/mips/momentum/ocelot_g/gt-irq.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/momentum/ocelot_g/gt-irq.c 2004-06-26 17:09:16 -07:00 @@ -17,8 +17,8 @@ #include #include #include +#include #include -#include "gt64240.h" unsigned long bus_clock; @@ -108,25 +108,25 @@ * we keep this particular structure in the function. */ -static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs) { uint32_t irq_src, irq_src_mask; int handled; /* get the low interrupt cause register */ - GT_READ(LOW_INTERRUPT_CAUSE_REGISTER, &irq_src); + irq_src = GT_READ(LOW_INTERRUPT_CAUSE_REGISTER); /* get the mask register for this pin */ - GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, &irq_src_mask); + irq_src_mask = GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW); /* mask off only the interrupts we're interested in */ irq_src = irq_src & irq_src_mask; - handled = 0; + handled = IRQ_NONE; /* Check for timer interrupt */ if (irq_src & 0x00000100) { - handled = 1; + handled = IRQ_HANDLED; irq_src &= ~0x00000100; /* Clear any pending cause bits */ @@ -141,90 +141,8 @@ "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n", irq_src); } -} - -/* - * Interrupt handler for interrupts coming from the Galileo chip. - * It could be built in ethernet ports etc... - */ -static void gt64240_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int irq_src, int_high_src, irq_src_mask, - int_high_src_mask; - int handled; - -#if 0 - GT_READ(GT_INTRCAUSE_OFS, &irq_src); - GT_READ(GT_INTRMASK_OFS, &irq_src_mask); - GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); - GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); -#endif - irq_src = irq_src & irq_src_mask; - int_high_src = int_high_src & int_high_src_mask; - - handled = 0; - - /* Execute all interrupt handlers */ - /* Check for timer interrupt */ - if (irq_src & 0x00000800) { - handled = 1; - irq_src &= ~0x00000800; - // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); - do_timer(regs); - } - - if (irq_src) { - printk(KERN_INFO - "Other Galileo interrupt received irq_src %x\n", - irq_src); -#if CURRENTLY_UNUSED - for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { - if (irq_src & (1 << count)) { - if (irq_handlers[INT_CAUSE_MAIN][count]. - routine) { - queue_task(&irq_handlers - [INT_CAUSE_MAIN][count], - &tq_immediate); - mark_bh(IMMEDIATE_BH); - handled = 1; - } - } - } -#endif /* UNUSED */ - } -#if 0 - GT_WRITE(GT_INTRCAUSE_OFS, 0); - GT_WRITE(GT_HINTRCAUSE_OFS, 0); -#endif - -#undef GALILEO_I2O -#ifdef GALILEO_I2O - /* - * Future I2O support. We currently attach I2O interrupt handlers to - * the Galileo interrupt (int 4) and handle them in do_IRQ. - */ - if (isInBoundDoorBellInterruptSet()) { - printk(KERN_INFO "I2O doorbell interrupt received.\n"); - handled = 1; - } - if (isInBoundPostQueueInterruptSet()) { - printk(KERN_INFO "I2O Queue interrupt received.\n"); - handled = 1; - } - - /* - * This normally would be outside of the ifdef, but since we're - * handling I2O outside of this handler, this printk shows up every - * time we get a valid I2O interrupt. So turn this off for now. - */ - if (handled == 0) { - if (counter < 50) { - printk("Spurious Galileo interrupt...\n"); - counter++; - } - } -#endif + return handled; } /* diff -Nru a/arch/mips/momentum/ocelot_g/gt64240.h b/arch/mips/momentum/ocelot_g/gt64240.h --- a/arch/mips/momentum/ocelot_g/gt64240.h 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,1238 +0,0 @@ -/* gt64240r.h - GT-64240 Internal registers definition file */ - -/* Copyright - Galileo technology. */ - -#ifndef __INCgt64240rh -#define __INCgt64240rh - -#define GTREG(v) (((v) & 0xff) << 24) | (((v) & 0xff00) << 8) | \ - (((v) >> 24) & 0xff) | (((v) >> 8) & 0xff00) - -#if 0 -#define GTREG_SHORT(X) (((X) << 8) | ((X) >> 8)) - -#define LONG_GTREG(X) ((l64) \ - (((X)&0x00000000000000ffULL) << 56) | \ - (((X)&0x000000000000ff00ULL) << 40) | \ - (((X)&0x0000000000ff0000ULL) << 24) | \ - (((X)&0x00000000ff000000ULL) << 8) | \ - (((X)&0x000000ff00000000ULL) >> 8) | \ - (((X)&0x0000ff0000000000ULL) >> 24) | \ - (((X)&0x00ff000000000000ULL) >> 40) | \ - (((X)&0xff00000000000000ULL) >> 56)) -#endif - -#include "gt64240_dep.h" - -/****************************************/ -/* CPU Control Registers */ -/****************************************/ - -#define CPU_CONFIGURATION 0x000 -#define CPU_MODE 0x120 -#define CPU_READ_RESPONSE_CROSSBAR_LOW 0x170 -#define CPU_READ_RESPONSE_CROSSBAR_HIGH 0x178 - -/****************************************/ -/* Processor Address Space */ -/****************************************/ - -/* Sdram's BAR'S */ -#define SCS_0_LOW_DECODE_ADDRESS 0x008 -#define SCS_0_HIGH_DECODE_ADDRESS 0x010 -#define SCS_1_LOW_DECODE_ADDRESS 0x208 -#define SCS_1_HIGH_DECODE_ADDRESS 0x210 -#define SCS_2_LOW_DECODE_ADDRESS 0x018 -#define SCS_2_HIGH_DECODE_ADDRESS 0x020 -#define SCS_3_LOW_DECODE_ADDRESS 0x218 -#define SCS_3_HIGH_DECODE_ADDRESS 0x220 -/* Devices BAR'S */ -#define CS_0_LOW_DECODE_ADDRESS 0x028 -#define CS_0_HIGH_DECODE_ADDRESS 0x030 -#define CS_1_LOW_DECODE_ADDRESS 0x228 -#define CS_1_HIGH_DECODE_ADDRESS 0x230 -#define CS_2_LOW_DECODE_ADDRESS 0x248 -#define CS_2_HIGH_DECODE_ADDRESS 0x250 -#define CS_3_LOW_DECODE_ADDRESS 0x038 -#define CS_3_HIGH_DECODE_ADDRESS 0x040 -#define BOOTCS_LOW_DECODE_ADDRESS 0x238 -#define BOOTCS_HIGH_DECODE_ADDRESS 0x240 - -#define PCI_0I_O_LOW_DECODE_ADDRESS 0x048 -#define PCI_0I_O_HIGH_DECODE_ADDRESS 0x050 -#define PCI_0MEMORY0_LOW_DECODE_ADDRESS 0x058 -#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS 0x060 -#define PCI_0MEMORY1_LOW_DECODE_ADDRESS 0x080 -#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS 0x088 -#define PCI_0MEMORY2_LOW_DECODE_ADDRESS 0x258 -#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS 0x260 -#define PCI_0MEMORY3_LOW_DECODE_ADDRESS 0x280 -#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS 0x288 - -#define PCI_1I_O_LOW_DECODE_ADDRESS 0x090 -#define PCI_1I_O_HIGH_DECODE_ADDRESS 0x098 -#define PCI_1MEMORY0_LOW_DECODE_ADDRESS 0x0a0 -#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS 0x0a8 -#define PCI_1MEMORY1_LOW_DECODE_ADDRESS 0x0b0 -#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS 0x0b8 -#define PCI_1MEMORY2_LOW_DECODE_ADDRESS 0x2a0 -#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS 0x2a8 -#define PCI_1MEMORY3_LOW_DECODE_ADDRESS 0x2b0 -#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS 0x2b8 - -#define INTERNAL_SPACE_DECODE 0x068 - -#define CPU_0_LOW_DECODE_ADDRESS 0x290 -#define CPU_0_HIGH_DECODE_ADDRESS 0x298 -#define CPU_1_LOW_DECODE_ADDRESS 0x2c0 -#define CPU_1_HIGH_DECODE_ADDRESS 0x2c8 - -#define PCI_0I_O_ADDRESS_REMAP 0x0f0 -#define PCI_0MEMORY0_ADDRESS_REMAP 0x0f8 -#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP 0x320 -#define PCI_0MEMORY1_ADDRESS_REMAP 0x100 -#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP 0x328 -#define PCI_0MEMORY2_ADDRESS_REMAP 0x2f8 -#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP 0x330 -#define PCI_0MEMORY3_ADDRESS_REMAP 0x300 -#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP 0x338 - -#define PCI_1I_O_ADDRESS_REMAP 0x108 -#define PCI_1MEMORY0_ADDRESS_REMAP 0x110 -#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP 0x340 -#define PCI_1MEMORY1_ADDRESS_REMAP 0x118 -#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP 0x348 -#define PCI_1MEMORY2_ADDRESS_REMAP 0x310 -#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP 0x350 -#define PCI_1MEMORY3_ADDRESS_REMAP 0x318 -#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP 0x358 - -/****************************************/ -/* CPU Sync Barrier */ -/****************************************/ - -#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER 0x0c0 -#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER 0x0c8 - - -/****************************************/ -/* CPU Access Protect */ -/****************************************/ - -#define CPU_LOW_PROTECT_ADDRESS_0 0X180 -#define CPU_HIGH_PROTECT_ADDRESS_0 0X188 -#define CPU_LOW_PROTECT_ADDRESS_1 0X190 -#define CPU_HIGH_PROTECT_ADDRESS_1 0X198 -#define CPU_LOW_PROTECT_ADDRESS_2 0X1a0 -#define CPU_HIGH_PROTECT_ADDRESS_2 0X1a8 -#define CPU_LOW_PROTECT_ADDRESS_3 0X1b0 -#define CPU_HIGH_PROTECT_ADDRESS_3 0X1b8 -#define CPU_LOW_PROTECT_ADDRESS_4 0X1c0 -#define CPU_HIGH_PROTECT_ADDRESS_4 0X1c8 -#define CPU_LOW_PROTECT_ADDRESS_5 0X1d0 -#define CPU_HIGH_PROTECT_ADDRESS_5 0X1d8 -#define CPU_LOW_PROTECT_ADDRESS_6 0X1e0 -#define CPU_HIGH_PROTECT_ADDRESS_6 0X1e8 -#define CPU_LOW_PROTECT_ADDRESS_7 0X1f0 -#define CPU_HIGH_PROTECT_ADDRESS_7 0X1f8 - - -/****************************************/ -/* Snoop Control */ -/****************************************/ - -#define SNOOP_BASE_ADDRESS_0 0x380 -#define SNOOP_TOP_ADDRESS_0 0x388 -#define SNOOP_BASE_ADDRESS_1 0x390 -#define SNOOP_TOP_ADDRESS_1 0x398 -#define SNOOP_BASE_ADDRESS_2 0x3a0 -#define SNOOP_TOP_ADDRESS_2 0x3a8 -#define SNOOP_BASE_ADDRESS_3 0x3b0 -#define SNOOP_TOP_ADDRESS_3 0x3b8 - -/****************************************/ -/* CPU Error Report */ -/****************************************/ - -#define CPU_ERROR_ADDRESS_LOW 0x070 -#define CPU_ERROR_ADDRESS_HIGH 0x078 -#define CPU_ERROR_DATA_LOW 0x128 -#define CPU_ERROR_DATA_HIGH 0x130 -#define CPU_ERROR_PARITY 0x138 -#define CPU_ERROR_CAUSE 0x140 -#define CPU_ERROR_MASK 0x148 - -/****************************************/ -/* Pslave Debug */ -/****************************************/ - -#define X_0_ADDRESS 0x360 -#define X_0_COMMAND_ID 0x368 -#define X_1_ADDRESS 0x370 -#define X_1_COMMAND_ID 0x378 -#define WRITE_DATA_LOW 0x3c0 -#define WRITE_DATA_HIGH 0x3c8 -#define WRITE_BYTE_ENABLE 0X3e0 -#define READ_DATA_LOW 0x3d0 -#define READ_DATA_HIGH 0x3d8 -#define READ_ID 0x3e8 - - -/****************************************/ -/* SDRAM and Device Address Space */ -/****************************************/ - - -/****************************************/ -/* SDRAM Configuration */ -/****************************************/ - -#define SDRAM_CONFIGURATION 0x448 -#define SDRAM_OPERATION_MODE 0x474 -#define SDRAM_ADDRESS_DECODE 0x47C -#define SDRAM_TIMING_PARAMETERS 0x4b4 -#define SDRAM_UMA_CONTROL 0x4a4 -#define SDRAM_CROSS_BAR_CONTROL_LOW 0x4a8 -#define SDRAM_CROSS_BAR_CONTROL_HIGH 0x4ac -#define SDRAM_CROSS_BAR_TIMEOUT 0x4b0 - - -/****************************************/ -/* SDRAM Parameters */ -/****************************************/ - -#define SDRAM_BANK0PARAMETERS 0x44C -#define SDRAM_BANK1PARAMETERS 0x450 -#define SDRAM_BANK2PARAMETERS 0x454 -#define SDRAM_BANK3PARAMETERS 0x458 - - -/****************************************/ -/* SDRAM Error Report */ -/****************************************/ - -#define SDRAM_ERROR_DATA_LOW 0x484 -#define SDRAM_ERROR_DATA_HIGH 0x480 -#define SDRAM_AND_DEVICE_ERROR_ADDRESS 0x490 -#define SDRAM_RECEIVED_ECC 0x488 -#define SDRAM_CALCULATED_ECC 0x48c -#define SDRAM_ECC_CONTROL 0x494 -#define SDRAM_ECC_ERROR_COUNTER 0x498 - - -/****************************************/ -/* SDunit Debug (for internal use) */ -/****************************************/ - -#define X0_ADDRESS 0x500 -#define X0_COMMAND_AND_ID 0x504 -#define X0_WRITE_DATA_LOW 0x508 -#define X0_WRITE_DATA_HIGH 0x50c -#define X0_WRITE_BYTE_ENABLE 0x518 -#define X0_READ_DATA_LOW 0x510 -#define X0_READ_DATA_HIGH 0x514 -#define X0_READ_ID 0x51c -#define X1_ADDRESS 0x520 -#define X1_COMMAND_AND_ID 0x524 -#define X1_WRITE_DATA_LOW 0x528 -#define X1_WRITE_DATA_HIGH 0x52c -#define X1_WRITE_BYTE_ENABLE 0x538 -#define X1_READ_DATA_LOW 0x530 -#define X1_READ_DATA_HIGH 0x534 -#define X1_READ_ID 0x53c -#define X0_SNOOP_ADDRESS 0x540 -#define X0_SNOOP_COMMAND 0x544 -#define X1_SNOOP_ADDRESS 0x548 -#define X1_SNOOP_COMMAND 0x54c - - -/****************************************/ -/* Device Parameters */ -/****************************************/ - -#define DEVICE_BANK0PARAMETERS 0x45c -#define DEVICE_BANK1PARAMETERS 0x460 -#define DEVICE_BANK2PARAMETERS 0x464 -#define DEVICE_BANK3PARAMETERS 0x468 -#define DEVICE_BOOT_BANK_PARAMETERS 0x46c -#define DEVICE_CONTROL 0x4c0 -#define DEVICE_CROSS_BAR_CONTROL_LOW 0x4c8 -#define DEVICE_CROSS_BAR_CONTROL_HIGH 0x4cc -#define DEVICE_CROSS_BAR_TIMEOUT 0x4c4 - - -/****************************************/ -/* Device Interrupt */ -/****************************************/ - -#define DEVICE_INTERRUPT_CAUSE 0x4d0 -#define DEVICE_INTERRUPT_MASK 0x4d4 -#define DEVICE_ERROR_ADDRESS 0x4d8 - -/****************************************/ -/* DMA Record */ -/****************************************/ - -#define CHANNEL0_DMA_BYTE_COUNT 0x800 -#define CHANNEL1_DMA_BYTE_COUNT 0x804 -#define CHANNEL2_DMA_BYTE_COUNT 0x808 -#define CHANNEL3_DMA_BYTE_COUNT 0x80C -#define CHANNEL4_DMA_BYTE_COUNT 0x900 -#define CHANNEL5_DMA_BYTE_COUNT 0x904 -#define CHANNEL6_DMA_BYTE_COUNT 0x908 -#define CHANNEL7_DMA_BYTE_COUNT 0x90C -#define CHANNEL0_DMA_SOURCE_ADDRESS 0x810 -#define CHANNEL1_DMA_SOURCE_ADDRESS 0x814 -#define CHANNEL2_DMA_SOURCE_ADDRESS 0x818 -#define CHANNEL3_DMA_SOURCE_ADDRESS 0x81C -#define CHANNEL4_DMA_SOURCE_ADDRESS 0x910 -#define CHANNEL5_DMA_SOURCE_ADDRESS 0x914 -#define CHANNEL6_DMA_SOURCE_ADDRESS 0x918 -#define CHANNEL7_DMA_SOURCE_ADDRESS 0x91C -#define CHANNEL0_DMA_DESTINATION_ADDRESS 0x820 -#define CHANNEL1_DMA_DESTINATION_ADDRESS 0x824 -#define CHANNEL2_DMA_DESTINATION_ADDRESS 0x828 -#define CHANNEL3_DMA_DESTINATION_ADDRESS 0x82C -#define CHANNEL4_DMA_DESTINATION_ADDRESS 0x920 -#define CHANNEL5_DMA_DESTINATION_ADDRESS 0x924 -#define CHANNEL6_DMA_DESTINATION_ADDRESS 0x928 -#define CHANNEL7_DMA_DESTINATION_ADDRESS 0x92C -#define CHANNEL0NEXT_RECORD_POINTER 0x830 -#define CHANNEL1NEXT_RECORD_POINTER 0x834 -#define CHANNEL2NEXT_RECORD_POINTER 0x838 -#define CHANNEL3NEXT_RECORD_POINTER 0x83C -#define CHANNEL4NEXT_RECORD_POINTER 0x930 -#define CHANNEL5NEXT_RECORD_POINTER 0x934 -#define CHANNEL6NEXT_RECORD_POINTER 0x938 -#define CHANNEL7NEXT_RECORD_POINTER 0x93C -#define CHANNEL0CURRENT_DESCRIPTOR_POINTER 0x870 -#define CHANNEL1CURRENT_DESCRIPTOR_POINTER 0x874 -#define CHANNEL2CURRENT_DESCRIPTOR_POINTER 0x878 -#define CHANNEL3CURRENT_DESCRIPTOR_POINTER 0x87C -#define CHANNEL4CURRENT_DESCRIPTOR_POINTER 0x970 -#define CHANNEL5CURRENT_DESCRIPTOR_POINTER 0x974 -#define CHANNEL6CURRENT_DESCRIPTOR_POINTER 0x978 -#define CHANNEL7CURRENT_DESCRIPTOR_POINTER 0x97C -#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS 0x890 -#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS 0x894 -#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS 0x898 -#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS 0x89c -#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS 0x990 -#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS 0x994 -#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS 0x998 -#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS 0x99c -#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a0 -#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a4 -#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a8 -#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8ac -#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a0 -#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a4 -#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a8 -#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9ac -#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b0 -#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b4 -#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b8 -#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8bc -#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b0 -#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b4 -#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b8 -#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9bc - -/****************************************/ -/* DMA Channel Control */ -/****************************************/ - -#define CHANNEL0CONTROL 0x840 -#define CHANNEL0CONTROL_HIGH 0x880 - -#define CHANNEL1CONTROL 0x844 -#define CHANNEL1CONTROL_HIGH 0x884 - -#define CHANNEL2CONTROL 0x848 -#define CHANNEL2CONTROL_HIGH 0x888 - -#define CHANNEL3CONTROL 0x84C -#define CHANNEL3CONTROL_HIGH 0x88C - -#define CHANNEL4CONTROL 0x940 -#define CHANNEL4CONTROL_HIGH 0x980 - -#define CHANNEL5CONTROL 0x944 -#define CHANNEL5CONTROL_HIGH 0x984 - -#define CHANNEL6CONTROL 0x948 -#define CHANNEL6CONTROL_HIGH 0x988 - -#define CHANNEL7CONTROL 0x94C -#define CHANNEL7CONTROL_HIGH 0x98C - - -/****************************************/ -/* DMA Arbiter */ -/****************************************/ - -#define ARBITER_CONTROL_0_3 0x860 -#define ARBITER_CONTROL_4_7 0x960 - - -/****************************************/ -/* DMA Interrupt */ -/****************************************/ - -#define CHANELS0_3_INTERRUPT_CAUSE 0x8c0 -#define CHANELS0_3_INTERRUPT_MASK 0x8c4 -#define CHANELS0_3_ERROR_ADDRESS 0x8c8 -#define CHANELS0_3_ERROR_SELECT 0x8cc -#define CHANELS4_7_INTERRUPT_CAUSE 0x9c0 -#define CHANELS4_7_INTERRUPT_MASK 0x9c4 -#define CHANELS4_7_ERROR_ADDRESS 0x9c8 -#define CHANELS4_7_ERROR_SELECT 0x9cc - - -/****************************************/ -/* DMA Debug (for internal use) */ -/****************************************/ - -#define DMA_X0_ADDRESS 0x8e0 -#define DMA_X0_COMMAND_AND_ID 0x8e4 -#define DMA_X0_WRITE_DATA_LOW 0x8e8 -#define DMA_X0_WRITE_DATA_HIGH 0x8ec -#define DMA_X0_WRITE_BYTE_ENABLE 0x8f8 -#define DMA_X0_READ_DATA_LOW 0x8f0 -#define DMA_X0_READ_DATA_HIGH 0x8f4 -#define DMA_X0_READ_ID 0x8fc -#define DMA_X1_ADDRESS 0x9e0 -#define DMA_X1_COMMAND_AND_ID 0x9e4 -#define DMA_X1_WRITE_DATA_LOW 0x9e8 -#define DMA_X1_WRITE_DATA_HIGH 0x9ec -#define DMA_X1_WRITE_BYTE_ENABLE 0x9f8 -#define DMA_X1_READ_DATA_LOW 0x9f0 -#define DMA_X1_READ_DATA_HIGH 0x9f4 -#define DMA_X1_READ_ID 0x9fc - -/****************************************/ -/* Timer_Counter */ -/****************************************/ - -#define TIMER_COUNTER0 0x850 -#define TIMER_COUNTER1 0x854 -#define TIMER_COUNTER2 0x858 -#define TIMER_COUNTER3 0x85C -#define TIMER_COUNTER_0_3_CONTROL 0x864 -#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 -#define TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c -#define TIMER_COUNTER4 0x950 -#define TIMER_COUNTER5 0x954 -#define TIMER_COUNTER6 0x958 -#define TIMER_COUNTER7 0x95C -#define TIMER_COUNTER_4_7_CONTROL 0x964 -#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE 0x968 -#define TIMER_COUNTER_4_7_INTERRUPT_MASK 0x96c - -/****************************************/ -/* PCI Slave Address Decoding */ -/****************************************/ - -#define PCI_0SCS_0_BANK_SIZE 0xc08 -#define PCI_1SCS_0_BANK_SIZE 0xc88 -#define PCI_0SCS_1_BANK_SIZE 0xd08 -#define PCI_1SCS_1_BANK_SIZE 0xd88 -#define PCI_0SCS_2_BANK_SIZE 0xc0c -#define PCI_1SCS_2_BANK_SIZE 0xc8c -#define PCI_0SCS_3_BANK_SIZE 0xd0c -#define PCI_1SCS_3_BANK_SIZE 0xd8c -#define PCI_0CS_0_BANK_SIZE 0xc10 -#define PCI_1CS_0_BANK_SIZE 0xc90 -#define PCI_0CS_1_BANK_SIZE 0xd10 -#define PCI_1CS_1_BANK_SIZE 0xd90 -#define PCI_0CS_2_BANK_SIZE 0xd18 -#define PCI_1CS_2_BANK_SIZE 0xd98 -#define PCI_0CS_3_BANK_SIZE 0xc14 -#define PCI_1CS_3_BANK_SIZE 0xc94 -#define PCI_0CS_BOOT_BANK_SIZE 0xd14 -#define PCI_1CS_BOOT_BANK_SIZE 0xd94 -#define PCI_0P2P_MEM0_BAR_SIZE 0xd1c -#define PCI_1P2P_MEM0_BAR_SIZE 0xd9c -#define PCI_0P2P_MEM1_BAR_SIZE 0xd20 -#define PCI_1P2P_MEM1_BAR_SIZE 0xda0 -#define PCI_0P2P_I_O_BAR_SIZE 0xd24 -#define PCI_1P2P_I_O_BAR_SIZE 0xda4 -#define PCI_0CPU_BAR_SIZE 0xd28 -#define PCI_1CPU_BAR_SIZE 0xda8 -#define PCI_0DAC_SCS_0_BANK_SIZE 0xe00 -#define PCI_1DAC_SCS_0_BANK_SIZE 0xe80 -#define PCI_0DAC_SCS_1_BANK_SIZE 0xe04 -#define PCI_1DAC_SCS_1_BANK_SIZE 0xe84 -#define PCI_0DAC_SCS_2_BANK_SIZE 0xe08 -#define PCI_1DAC_SCS_2_BANK_SIZE 0xe88 -#define PCI_0DAC_SCS_3_BANK_SIZE 0xe0c -#define PCI_1DAC_SCS_3_BANK_SIZE 0xe8c -#define PCI_0DAC_CS_0_BANK_SIZE 0xe10 -#define PCI_1DAC_CS_0_BANK_SIZE 0xe90 -#define PCI_0DAC_CS_1_BANK_SIZE 0xe14 -#define PCI_1DAC_CS_1_BANK_SIZE 0xe94 -#define PCI_0DAC_CS_2_BANK_SIZE 0xe18 -#define PCI_1DAC_CS_2_BANK_SIZE 0xe98 -#define PCI_0DAC_CS_3_BANK_SIZE 0xe1c -#define PCI_1DAC_CS_3_BANK_SIZE 0xe9c -#define PCI_0DAC_BOOTCS_BANK_SIZE 0xe20 -#define PCI_1DAC_BOOTCS_BANK_SIZE 0xea0 -#define PCI_0DAC_P2P_MEM0_BAR_SIZE 0xe24 -#define PCI_1DAC_P2P_MEM0_BAR_SIZE 0xea4 -#define PCI_0DAC_P2P_MEM1_BAR_SIZE 0xe28 -#define PCI_1DAC_P2P_MEM1_BAR_SIZE 0xea8 -#define PCI_0DAC_CPU_BAR_SIZE 0xe2c -#define PCI_1DAC_CPU_BAR_SIZE 0xeac -#define PCI_0EXPANSION_ROM_BAR_SIZE 0xd2c -#define PCI_1EXPANSION_ROM_BAR_SIZE 0xdac -#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 0xc3c -#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 0xcbc -#define PCI_0SCS_0_BASE_ADDRESS_REMAP 0xc48 -#define PCI_1SCS_0_BASE_ADDRESS_REMAP 0xcc8 -#define PCI_0SCS_1_BASE_ADDRESS_REMAP 0xd48 -#define PCI_1SCS_1_BASE_ADDRESS_REMAP 0xdc8 -#define PCI_0SCS_2_BASE_ADDRESS_REMAP 0xc4c -#define PCI_1SCS_2_BASE_ADDRESS_REMAP 0xccc -#define PCI_0SCS_3_BASE_ADDRESS_REMAP 0xd4c -#define PCI_1SCS_3_BASE_ADDRESS_REMAP 0xdcc -#define PCI_0CS_0_BASE_ADDRESS_REMAP 0xc50 -#define PCI_1CS_0_BASE_ADDRESS_REMAP 0xcd0 -#define PCI_0CS_1_BASE_ADDRESS_REMAP 0xd50 -#define PCI_1CS_1_BASE_ADDRESS_REMAP 0xdd0 -#define PCI_0CS_2_BASE_ADDRESS_REMAP 0xd58 -#define PCI_1CS_2_BASE_ADDRESS_REMAP 0xdd8 -#define PCI_0CS_3_BASE_ADDRESS_REMAP 0xc54 -#define PCI_1CS_3_BASE_ADDRESS_REMAP 0xcd4 -#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP 0xd54 -#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP 0xdd4 -#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xd5c -#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xddc -#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xd60 -#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xde0 -#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xd64 -#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xde4 -#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xd68 -#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xde8 -#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP 0xd6c -#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP 0xdec -#define PCI_0CPU_BASE_ADDRESS_REMAP 0xd70 -#define PCI_1CPU_BASE_ADDRESS_REMAP 0xdf0 -#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP 0xf00 -#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP 0xff0 -#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP 0xf04 -#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP 0xf84 -#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP 0xf08 -#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP 0xf88 -#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP 0xf0c -#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP 0xf8c -#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP 0xf10 -#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP 0xf90 -#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP 0xf14 -#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP 0xf94 -#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP 0xf18 -#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP 0xf98 -#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP 0xf1c -#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP 0xf9c -#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP 0xf20 -#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP 0xfa0 -#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xf24 -#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xfa4 -#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xf28 -#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xfa8 -#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xf2c -#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xfac -#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xf30 -#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xfb0 -#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP 0xf34 -#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP 0xfb4 -#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP 0xf38 -#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP 0xfb8 -#define PCI_0ADDRESS_DECODE_CONTROL 0xd3c -#define PCI_1ADDRESS_DECODE_CONTROL 0xdbc - -/****************************************/ -/* PCI Control */ -/****************************************/ - -#define PCI_0COMMAND 0xc00 -#define PCI_1COMMAND 0xc80 -#define PCI_0MODE 0xd00 -#define PCI_1MODE 0xd80 -#define PCI_0TIMEOUT_RETRY 0xc04 -#define PCI_1TIMEOUT_RETRY 0xc84 -#define PCI_0READ_BUFFER_DISCARD_TIMER 0xd04 -#define PCI_1READ_BUFFER_DISCARD_TIMER 0xd84 -#define MSI_0TRIGGER_TIMER 0xc38 -#define MSI_1TRIGGER_TIMER 0xcb8 -#define PCI_0ARBITER_CONTROL 0x1d00 -#define PCI_1ARBITER_CONTROL 0x1d80 -/* changing untill here */ -#define PCI_0CROSS_BAR_CONTROL_LOW 0x1d08 -#define PCI_0CROSS_BAR_CONTROL_HIGH 0x1d0c -#define PCI_0CROSS_BAR_TIMEOUT 0x1d04 -#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d18 -#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d1c -#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER 0x1d10 -#define PCI_0P2P_CONFIGURATION 0x1d14 -#define PCI_0ACCESS_CONTROL_BASE_0_LOW 0x1e00 -#define PCI_0ACCESS_CONTROL_BASE_0_HIGH 0x1e04 -#define PCI_0ACCESS_CONTROL_TOP_0 0x1e08 -#define PCI_0ACCESS_CONTROL_BASE_1_LOW 0c1e10 -#define PCI_0ACCESS_CONTROL_BASE_1_HIGH 0x1e14 -#define PCI_0ACCESS_CONTROL_TOP_1 0x1e18 -#define PCI_0ACCESS_CONTROL_BASE_2_LOW 0c1e20 -#define PCI_0ACCESS_CONTROL_BASE_2_HIGH 0x1e24 -#define PCI_0ACCESS_CONTROL_TOP_2 0x1e28 -#define PCI_0ACCESS_CONTROL_BASE_3_LOW 0c1e30 -#define PCI_0ACCESS_CONTROL_BASE_3_HIGH 0x1e34 -#define PCI_0ACCESS_CONTROL_TOP_3 0x1e38 -#define PCI_0ACCESS_CONTROL_BASE_4_LOW 0c1e40 -#define PCI_0ACCESS_CONTROL_BASE_4_HIGH 0x1e44 -#define PCI_0ACCESS_CONTROL_TOP_4 0x1e48 -#define PCI_0ACCESS_CONTROL_BASE_5_LOW 0c1e50 -#define PCI_0ACCESS_CONTROL_BASE_5_HIGH 0x1e54 -#define PCI_0ACCESS_CONTROL_TOP_5 0x1e58 -#define PCI_0ACCESS_CONTROL_BASE_6_LOW 0c1e60 -#define PCI_0ACCESS_CONTROL_BASE_6_HIGH 0x1e64 -#define PCI_0ACCESS_CONTROL_TOP_6 0x1e68 -#define PCI_0ACCESS_CONTROL_BASE_7_LOW 0c1e70 -#define PCI_0ACCESS_CONTROL_BASE_7_HIGH 0x1e74 -#define PCI_0ACCESS_CONTROL_TOP_7 0x1e78 -#define PCI_1CROSS_BAR_CONTROL_LOW 0x1d88 -#define PCI_1CROSS_BAR_CONTROL_HIGH 0x1d8c -#define PCI_1CROSS_BAR_TIMEOUT 0x1d84 -#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d98 -#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d9c -#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER 0x1d90 -#define PCI_1P2P_CONFIGURATION 0x1d94 -#define PCI_1ACCESS_CONTROL_BASE_0_LOW 0x1e80 -#define PCI_1ACCESS_CONTROL_BASE_0_HIGH 0x1e84 -#define PCI_1ACCESS_CONTROL_TOP_0 0x1e88 -#define PCI_1ACCESS_CONTROL_BASE_1_LOW 0c1e90 -#define PCI_1ACCESS_CONTROL_BASE_1_HIGH 0x1e94 -#define PCI_1ACCESS_CONTROL_TOP_1 0x1e98 -#define PCI_1ACCESS_CONTROL_BASE_2_LOW 0c1ea0 -#define PCI_1ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 -#define PCI_1ACCESS_CONTROL_TOP_2 0x1ea8 -#define PCI_1ACCESS_CONTROL_BASE_3_LOW 0c1eb0 -#define PCI_1ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 -#define PCI_1ACCESS_CONTROL_TOP_3 0x1eb8 -#define PCI_1ACCESS_CONTROL_BASE_4_LOW 0c1ec0 -#define PCI_1ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 -#define PCI_1ACCESS_CONTROL_TOP_4 0x1ec8 -#define PCI_1ACCESS_CONTROL_BASE_5_LOW 0c1ed0 -#define PCI_1ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 -#define PCI_1ACCESS_CONTROL_TOP_5 0x1ed8 -#define PCI_1ACCESS_CONTROL_BASE_6_LOW 0c1ee0 -#define PCI_1ACCESS_CONTROL_BASE_6_HIGH 0x1ee4 -#define PCI_1ACCESS_CONTROL_TOP_6 0x1ee8 -#define PCI_1ACCESS_CONTROL_BASE_7_LOW 0c1ef0 -#define PCI_1ACCESS_CONTROL_BASE_7_HIGH 0x1ef4 -#define PCI_1ACCESS_CONTROL_TOP_7 0x1ef8 - -/****************************************/ -/* PCI Snoop Control */ -/****************************************/ - -#define PCI_0SNOOP_CONTROL_BASE_0_LOW 0x1f00 -#define PCI_0SNOOP_CONTROL_BASE_0_HIGH 0x1f04 -#define PCI_0SNOOP_CONTROL_TOP_0 0x1f08 -#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW 0x1f10 -#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH 0x1f14 -#define PCI_0SNOOP_CONTROL_TOP_1 0x1f18 -#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW 0x1f20 -#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH 0x1f24 -#define PCI_0SNOOP_CONTROL_TOP_2 0x1f28 -#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW 0x1f30 -#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH 0x1f34 -#define PCI_0SNOOP_CONTROL_TOP_3 0x1f38 -#define PCI_1SNOOP_CONTROL_BASE_0_LOW 0x1f80 -#define PCI_1SNOOP_CONTROL_BASE_0_HIGH 0x1f84 -#define PCI_1SNOOP_CONTROL_TOP_0 0x1f88 -#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW 0x1f90 -#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH 0x1f94 -#define PCI_1SNOOP_CONTROL_TOP_1 0x1f98 -#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW 0x1fa0 -#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH 0x1fa4 -#define PCI_1SNOOP_CONTROL_TOP_2 0x1fa8 -#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW 0x1fb0 -#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH 0x1fb4 -#define PCI_1SNOOP_CONTROL_TOP_3 0x1fb8 - -/****************************************/ -/* PCI Configuration Address */ -/****************************************/ - -#define PCI_0CONFIGURATION_ADDRESS 0xcf8 -#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER 0xcfc -#define PCI_1CONFIGURATION_ADDRESS 0xc78 -#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER 0xc7c -#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xc34 -#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xcb4 - -/****************************************/ -/* PCI Error Report */ -/****************************************/ - -#define PCI_0SERR_MASK 0xc28 -#define PCI_0ERROR_ADDRESS_LOW 0x1d40 -#define PCI_0ERROR_ADDRESS_HIGH 0x1d44 -#define PCI_0ERROR_DATA_LOW 0x1d48 -#define PCI_0ERROR_DATA_HIGH 0x1d4c -#define PCI_0ERROR_COMMAND 0x1d50 -#define PCI_0ERROR_CAUSE 0x1d58 -#define PCI_0ERROR_MASK 0x1d5c - -#define PCI_1SERR_MASK 0xca8 -#define PCI_1ERROR_ADDRESS_LOW 0x1dc0 -#define PCI_1ERROR_ADDRESS_HIGH 0x1dc4 -#define PCI_1ERROR_DATA_LOW 0x1dc8 -#define PCI_1ERROR_DATA_HIGH 0x1dcc -#define PCI_1ERROR_COMMAND 0x1dd0 -#define PCI_1ERROR_CAUSE 0x1dd8 -#define PCI_1ERROR_MASK 0x1ddc - - -/****************************************/ -/* Lslave Debug (for internal use) */ -/****************************************/ - -#define L_SLAVE_X0_ADDRESS 0x1d20 -#define L_SLAVE_X0_COMMAND_AND_ID 0x1d24 -#define L_SLAVE_X1_ADDRESS 0x1d28 -#define L_SLAVE_X1_COMMAND_AND_ID 0x1d2c -#define L_SLAVE_WRITE_DATA_LOW 0x1d30 -#define L_SLAVE_WRITE_DATA_HIGH 0x1d34 -#define L_SLAVE_WRITE_BYTE_ENABLE 0x1d60 -#define L_SLAVE_READ_DATA_LOW 0x1d38 -#define L_SLAVE_READ_DATA_HIGH 0x1d3c -#define L_SLAVE_READ_ID 0x1d64 - -/****************************************/ -/* PCI Configuration Function 0 */ -/****************************************/ - -#define PCI_DEVICE_AND_VENDOR_ID 0x000 -#define PCI_STATUS_AND_COMMAND 0x004 -#define PCI_CLASS_CODE_AND_REVISION_ID 0x008 -#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C -#define PCI_SCS_0_BASE_ADDRESS 0x010 -#define PCI_SCS_1_BASE_ADDRESS 0x014 -#define PCI_SCS_2_BASE_ADDRESS 0x018 -#define PCI_SCS_3_BASE_ADDRESS 0x01C -#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS 0x020 -#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS 0x024 -#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02C -#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER 0x030 -#define PCI_CAPABILTY_LIST_POINTER 0x034 -#define PCI_INTERRUPT_PIN_AND_LINE 0x03C -#define PCI_POWER_MANAGEMENT_CAPABILITY 0x040 -#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 -#define PCI_VPD_ADDRESS 0x048 -#define PCI_VPD_DATA 0X04c -#define PCI_MSI_MESSAGE_CONTROL 0x050 -#define PCI_MSI_MESSAGE_ADDRESS 0x054 -#define PCI_MSI_MESSAGE_UPPER_ADDRESS 0x058 -#define PCI_MSI_MESSAGE_DATA 0x05c -#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY 0x058 - -/****************************************/ -/* PCI Configuration Function 1 */ -/****************************************/ - -#define PCI_CS_0_BASE_ADDRESS 0x110 -#define PCI_CS_1_BASE_ADDRESS 0x114 -#define PCI_CS_2_BASE_ADDRESS 0x118 -#define PCI_CS_3_BASE_ADDRESS 0x11c -#define PCI_BOOTCS_BASE_ADDRESS 0x120 - -/****************************************/ -/* PCI Configuration Function 2 */ -/****************************************/ - -#define PCI_P2P_MEM0_BASE_ADDRESS 0x210 -#define PCI_P2P_MEM1_BASE_ADDRESS 0x214 -#define PCI_P2P_I_O_BASE_ADDRESS 0x218 -#define PCI_CPU_BASE_ADDRESS 0x21c - -/****************************************/ -/* PCI Configuration Function 4 */ -/****************************************/ - -#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 0x410 -#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH 0x414 -#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW 0x418 -#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH 0x41c -#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW 0x420 -#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH 0x424 - - -/****************************************/ -/* PCI Configuration Function 5 */ -/****************************************/ - -#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 0x510 -#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH 0x514 -#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW 0x518 -#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH 0x51c -#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW 0x520 -#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH 0x524 - - -/****************************************/ -/* PCI Configuration Function 6 */ -/****************************************/ - -#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 0x610 -#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH 0x614 -#define PCI_DAC_CS_1_BASE_ADDRESS_LOW 0x618 -#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH 0x61c -#define PCI_DAC_CS_2_BASE_ADDRESS_LOW 0x620 -#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH 0x624 - -/****************************************/ -/* PCI Configuration Function 7 */ -/****************************************/ - -#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 0x710 -#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH 0x714 -#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW 0x718 -#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH 0x71c -#define PCI_DAC_CPU_BASE_ADDRESS_LOW 0x720 -#define PCI_DAC_CPU_BASE_ADDRESS_HIGH 0x724 - -/****************************************/ -/* Interrupts */ -/****************************************/ - -#define LOW_INTERRUPT_CAUSE_REGISTER 0xc18 -#define HIGH_INTERRUPT_CAUSE_REGISTER 0xc68 -#define CPU_INTERRUPT_MASK_REGISTER_LOW 0xc1c -#define CPU_INTERRUPT_MASK_REGISTER_HIGH 0xc6c -#define CPU_SELECT_CAUSE_REGISTER 0xc70 -#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xc24 -#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xc64 -#define PCI_0SELECT_CAUSE 0xc74 -#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xca4 -#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xce4 -#define PCI_1SELECT_CAUSE 0xcf4 -#define CPU_INT_0_MASK 0xe60 -#define CPU_INT_1_MASK 0xe64 -#define CPU_INT_2_MASK 0xe68 -#define CPU_INT_3_MASK 0xe6c - -/****************************************/ -/* I20 Support registers */ -/****************************************/ - -#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x010 -#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x014 -#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x018 -#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x01C -#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x020 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x024 -#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x028 -#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x02C -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x030 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x034 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x040 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x044 -#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 0x050 -#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 0x054 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x060 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x064 -#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x068 -#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x06C -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x070 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x074 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x0F8 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x0FC - -#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x090 -#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x094 -#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x098 -#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x09C -#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0A0 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0A4 -#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0A8 -#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0AC -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0B0 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0B4 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C0 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C4 -#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 0x0D0 -#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 0x0D4 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E0 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0E4 -#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E8 -#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0EC -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0F0 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0F4 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x078 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x07C - -#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C10 -#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C14 -#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C18 -#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C1C -#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C20 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C24 -#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C28 -#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C2C -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C30 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C34 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C40 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C44 -#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 0X1C50 -#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 0X1C54 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C60 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C64 -#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C68 -#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C6C -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C70 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C74 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1CF8 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1CFC - -#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C90 -#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C94 -#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C98 -#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C9C -#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CA0 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CA4 -#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CA8 -#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CAC -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CB0 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CB4 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC0 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC4 -#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 0X1CD0 -#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 0X1CD4 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE0 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CE4 -#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE8 -#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CEC -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CF0 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CF4 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1C78 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1C7C - -/****************************************/ -/* Communication Unit Registers */ -/****************************************/ - -#define ETHERNET_0_ADDRESS_CONTROL_LOW -#define ETHERNET_0_ADDRESS_CONTROL_HIGH 0xf204 -#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf208 -#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf20c -#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf210 -#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf214 -#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS 0xf218 -#define ETHERNET_1_ADDRESS_CONTROL_LOW 0xf220 -#define ETHERNET_1_ADDRESS_CONTROL_HIGH 0xf224 -#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf228 -#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf22c -#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf230 -#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf234 -#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS 0xf238 -#define ETHERNET_2_ADDRESS_CONTROL_LOW 0xf240 -#define ETHERNET_2_ADDRESS_CONTROL_HIGH 0xf244 -#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf248 -#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf24c -#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf250 -#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf254 -#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS 0xf258 -#define MPSC_0_ADDRESS_CONTROL_LOW 0xf280 -#define MPSC_0_ADDRESS_CONTROL_HIGH 0xf284 -#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf288 -#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf28c -#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf290 -#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf294 -#define MPSC_1_ADDRESS_CONTROL_LOW 0xf2a0 -#define MPSC_1_ADDRESS_CONTROL_HIGH 0xf2a4 -#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2a8 -#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2ac -#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b0 -#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b4 -#define MPSC_2_ADDRESS_CONTROL_LOW 0xf2c0 -#define MPSC_2_ADDRESS_CONTROL_HIGH 0xf2c4 -#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2c8 -#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2cc -#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d0 -#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d4 -#define SERIAL_INIT_PCI_HIGH_ADDRESS 0xf320 -#define SERIAL_INIT_LAST_DATA 0xf324 -#define SERIAL_INIT_STATUS_AND_CONTROL 0xf328 -#define COMM_UNIT_ARBITER_CONTROL 0xf300 -#define COMM_UNIT_CROSS_BAR_TIMEOUT 0xf304 -#define COMM_UNIT_INTERRUPT_CAUSE 0xf310 -#define COMM_UNIT_INTERRUPT_MASK 0xf314 -#define COMM_UNIT_ERROR_ADDRESS 0xf314 - -/****************************************/ -/* Cunit Debug (for internal use) */ -/****************************************/ - -#define CUNIT_ADDRESS 0xf340 -#define CUNIT_COMMAND_AND_ID 0xf344 -#define CUNIT_WRITE_DATA_LOW 0xf348 -#define CUNIT_WRITE_DATA_HIGH 0xf34c -#define CUNIT_WRITE_BYTE_ENABLE 0xf358 -#define CUNIT_READ_DATA_LOW 0xf350 -#define CUNIT_READ_DATA_HIGH 0xf354 -#define CUNIT_READ_ID 0xf35c - -/****************************************/ -/* Fast Ethernet Unit Registers */ -/****************************************/ - -/* Ethernet */ - -#define ETHERNET_PHY_ADDRESS_REGISTER 0x2000 -#define ETHERNET_SMI_REGISTER 0x2010 - -/* Ethernet 0 */ - -#define ETHERNET0_PORT_CONFIGURATION_REGISTER 0x2400 -#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER 0x2408 -#define ETHERNET0_PORT_COMMAND_REGISTER 0x2410 -#define ETHERNET0_PORT_STATUS_REGISTER 0x2418 -#define ETHERNET0_SERIAL_PARAMETRS_REGISTER 0x2420 -#define ETHERNET0_HASH_TABLE_POINTER_REGISTER 0x2428 -#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2430 -#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2438 -#define ETHERNET0_SDMA_CONFIGURATION_REGISTER 0x2440 -#define ETHERNET0_SDMA_COMMAND_REGISTER 0x2448 -#define ETHERNET0_INTERRUPT_CAUSE_REGISTER 0x2450 -#define ETHERNET0_INTERRUPT_MASK_REGISTER 0x2458 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 0x2480 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1 0x2484 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2 0x2488 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3 0x248c -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 0x24a0 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1 0x24a4 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2 0x24a8 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3 0x24ac -#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 0x24e0 -#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 0x24e4 -#define ETHERNET0_MIB_COUNTER_BASE 0x2500 - -/* Ethernet 1 */ - -#define ETHERNET1_PORT_CONFIGURATION_REGISTER 0x2800 -#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER 0x2808 -#define ETHERNET1_PORT_COMMAND_REGISTER 0x2810 -#define ETHERNET1_PORT_STATUS_REGISTER 0x2818 -#define ETHERNET1_SERIAL_PARAMETRS_REGISTER 0x2820 -#define ETHERNET1_HASH_TABLE_POINTER_REGISTER 0x2828 -#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2830 -#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2838 -#define ETHERNET1_SDMA_CONFIGURATION_REGISTER 0x2840 -#define ETHERNET1_SDMA_COMMAND_REGISTER 0x2848 -#define ETHERNET1_INTERRUPT_CAUSE_REGISTER 0x2850 -#define ETHERNET1_INTERRUPT_MASK_REGISTER 0x2858 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0 0x2880 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1 0x2884 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2 0x2888 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3 0x288c -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0 0x28a0 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1 0x28a4 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2 0x28a8 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3 0x28ac -#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0 0x28e0 -#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1 0x28e4 -#define ETHERNET1_MIB_COUNTER_BASE 0x2900 - -/* Ethernet 2 */ - -#define ETHERNET2_PORT_CONFIGURATION_REGISTER 0x2c00 -#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER 0x2c08 -#define ETHERNET2_PORT_COMMAND_REGISTER 0x2c10 -#define ETHERNET2_PORT_STATUS_REGISTER 0x2c18 -#define ETHERNET2_SERIAL_PARAMETRS_REGISTER 0x2c20 -#define ETHERNET2_HASH_TABLE_POINTER_REGISTER 0x2c28 -#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2c30 -#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2c38 -#define ETHERNET2_SDMA_CONFIGURATION_REGISTER 0x2c40 -#define ETHERNET2_SDMA_COMMAND_REGISTER 0x2c48 -#define ETHERNET2_INTERRUPT_CAUSE_REGISTER 0x2c50 -#define ETHERNET2_INTERRUPT_MASK_REGISTER 0x2c58 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0 0x2c80 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1 0x2c84 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2 0x2c88 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3 0x2c8c -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0 0x2ca0 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1 0x2ca4 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2 0x2ca8 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3 0x2cac -#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0 0x2ce0 -#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1 0x2ce4 -#define ETHERNET2_MIB_COUNTER_BASE 0x2d00 - -/****************************************/ -/* SDMA Registers */ -/****************************************/ - -#define SDMA_GROUP_CONFIGURATION_REGISTER 0xb1f0 -#define CHANNEL0_CONFIGURATION_REGISTER 0x4000 -#define CHANNEL0_COMMAND_REGISTER 0x4008 -#define CHANNEL0_RX_CMD_STATUS 0x4800 -#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES 0x4804 -#define CHANNEL0_RX_BUFFER_POINTER 0x4808 -#define CHANNEL0_RX_NEXT_POINTER 0x480c -#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER 0x4810 -#define CHANNEL0_TX_CMD_STATUS 0x4C00 -#define CHANNEL0_TX_PACKET_SIZE 0x4C04 -#define CHANNEL0_TX_BUFFER_POINTER 0x4C08 -#define CHANNEL0_TX_NEXT_POINTER 0x4C0c -#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER 0x4c10 -#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER 0x4c14 -#define CHANNEL1_CONFIGURATION_REGISTER 0x6000 -#define CHANNEL1_COMMAND_REGISTER 0x6008 -#define CHANNEL1_RX_CMD_STATUS 0x6800 -#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES 0x6804 -#define CHANNEL1_RX_BUFFER_POINTER 0x6808 -#define CHANNEL1_RX_NEXT_POINTER 0x680c -#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 -#define CHANNEL1_TX_CMD_STATUS 0x6C00 -#define CHANNEL1_TX_PACKET_SIZE 0x6C04 -#define CHANNEL1_TX_BUFFER_POINTER 0x6C08 -#define CHANNEL1_TX_NEXT_POINTER 0x6C0c -#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 -#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER 0x6c10 -#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER 0x6c14 - -/* SDMA Interrupt */ - -#define SDMA_CAUSE 0xb820 -#define SDMA_MASK 0xb8a0 - - -/****************************************/ -/* Baude Rate Generators Registers */ -/****************************************/ - -/* BRG 0 */ - -#define BRG0_CONFIGURATION_REGISTER 0xb200 -#define BRG0_BAUDE_TUNING_REGISTER 0xb204 - -/* BRG 1 */ - -#define BRG1_CONFIGURATION_REGISTER 0xb208 -#define BRG1_BAUDE_TUNING_REGISTER 0xb20c - -/* BRG 2 */ - -#define BRG2_CONFIGURATION_REGISTER 0xb210 -#define BRG2_BAUDE_TUNING_REGISTER 0xb214 - -/* BRG Interrupts */ - -#define BRG_CAUSE_REGISTER 0xb834 -#define BRG_MASK_REGISTER 0xb8b4 - -/* MISC */ - -#define MAIN_ROUTING_REGISTER 0xb400 -#define RECEIVE_CLOCK_ROUTING_REGISTER 0xb404 -#define TRANSMIT_CLOCK_ROUTING_REGISTER 0xb408 -#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER 0xb40c -#define WATCHDOG_CONFIGURATION_REGISTER 0xb410 -#define WATCHDOG_VALUE_REGISTER 0xb414 - - -/****************************************/ -/* Flex TDM Registers */ -/****************************************/ - -/* FTDM Port */ - -#define FLEXTDM_TRANSMIT_READ_POINTER 0xa800 -#define FLEXTDM_RECEIVE_READ_POINTER 0xa804 -#define FLEXTDM_CONFIGURATION_REGISTER 0xa808 -#define FLEXTDM_AUX_CHANNELA_TX_REGISTER 0xa80c -#define FLEXTDM_AUX_CHANNELA_RX_REGISTER 0xa810 -#define FLEXTDM_AUX_CHANNELB_TX_REGISTER 0xa814 -#define FLEXTDM_AUX_CHANNELB_RX_REGISTER 0xa818 - -/* FTDM Interrupts */ - -#define FTDM_CAUSE_REGISTER 0xb830 -#define FTDM_MASK_REGISTER 0xb8b0 - - -/****************************************/ -/* GPP Interface Registers */ -/****************************************/ - -#define GPP_IO_CONTROL 0xf100 -#define GPP_LEVEL_CONTROL 0xf110 -#define GPP_VALUE 0xf104 -#define GPP_INTERRUPT_CAUSE 0xf108 -#define GPP_INTERRUPT_MASK 0xf10c - -#define MPP_CONTROL0 0xf000 -#define MPP_CONTROL1 0xf004 -#define MPP_CONTROL2 0xf008 -#define MPP_CONTROL3 0xf00c -#define DEBUG_PORT_MULTIPLEX 0xf014 -#define SERIAL_PORT_MULTIPLEX 0xf010 - -/****************************************/ -/* I2C Registers */ -/****************************************/ - -#define I2C_SLAVE_ADDRESS 0xc000 -#define I2C_EXTENDED_SLAVE_ADDRESS 0xc040 -#define I2C_DATA 0xc004 -#define I2C_CONTROL 0xc008 -#define I2C_STATUS_BAUDE_RATE 0xc00C -#define I2C_SOFT_RESET 0xc01c - -/****************************************/ -/* MPSC Registers */ -/****************************************/ - -/* MPSC0 */ - -#define MPSC0_MAIN_CONFIGURATION_LOW 0x8000 -#define MPSC0_MAIN_CONFIGURATION_HIGH 0x8004 -#define MPSC0_PROTOCOL_CONFIGURATION 0x8008 -#define CHANNEL0_REGISTER1 0x800c -#define CHANNEL0_REGISTER2 0x8010 -#define CHANNEL0_REGISTER3 0x8014 -#define CHANNEL0_REGISTER4 0x8018 -#define CHANNEL0_REGISTER5 0x801c -#define CHANNEL0_REGISTER6 0x8020 -#define CHANNEL0_REGISTER7 0x8024 -#define CHANNEL0_REGISTER8 0x8028 -#define CHANNEL0_REGISTER9 0x802c -#define CHANNEL0_REGISTER10 0x8030 -#define CHANNEL0_REGISTER11 0x8034 - -/* MPSC1 */ - -#define MPSC1_MAIN_CONFIGURATION_LOW 0x9000 -#define MPSC1_MAIN_CONFIGURATION_HIGH 0x9004 -#define MPSC1_PROTOCOL_CONFIGURATION 0x9008 -#define CHANNEL1_REGISTER1 0x900c -#define CHANNEL1_REGISTER2 0x9010 -#define CHANNEL1_REGISTER3 0x9014 -#define CHANNEL1_REGISTER4 0x9018 -#define CHANNEL1_REGISTER5 0x901c -#define CHANNEL1_REGISTER6 0x9020 -#define CHANNEL1_REGISTER7 0x9024 -#define CHANNEL1_REGISTER8 0x9028 -#define CHANNEL1_REGISTER9 0x902c -#define CHANNEL1_REGISTER10 0x9030 -#define CHANNEL1_REGISTER11 0x9034 - -/* MPSCs Interupts */ - -#define MPSC0_CAUSE 0xb804 -#define MPSC0_MASK 0xb884 -#define MPSC1_CAUSE 0xb80c -#define MPSC1_MASK 0xb88c - -#endif /* __INCgt64240rh */ diff -Nru a/arch/mips/momentum/ocelot_g/gt64240_dep.h b/arch/mips/momentum/ocelot_g/gt64240_dep.h --- a/arch/mips/momentum/ocelot_g/gt64240_dep.h 2004-06-26 17:09:18 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,57 +0,0 @@ -/*********************************************************************** - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/gt64240/gt64240-dep.h - * Board-dependent definitions for GT-64120 chip. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - *********************************************************************** - */ - -#ifndef _ASM_GT64240_DEP_H -#define _ASM_GT64240_DEP_H - -#include /* for KSEG1ADDR() */ -#include /* for cpu_to_le32() */ - -/* - * PCI address allocation - */ -#if 0 -#define GT_PCI_MEM_BASE (0x22000000) -#define GT_PCI_MEM_SIZE GT_DEF_PCI0_MEM0_SIZE -#define GT_PCI_IO_BASE (0x20000000) -#define GT_PCI_IO_SIZE GT_DEF_PCI0_IO_SIZE -#endif - -extern unsigned long gt64240_base; - -#define GT64240_BASE (gt64240_base) - -/* - * Because of an error/peculiarity in the Galileo chip, we need to swap the - * bytes when running bigendian. - */ - -#define GT_WRITE(ofs, data) \ - *(volatile u32 *)(GT64240_BASE+(ofs)) = cpu_to_le32(data) -#define GT_READ(ofs, data) \ - *(data) = le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) -#define GT_READ_DATA(ofs) \ - le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) - -#define GT_WRITE_16(ofs, data) \ - *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data) -#define GT_READ_16(ofs, data) \ - *(data) = le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs))) - -#define GT_WRITE_8(ofs, data) \ - *(volatile u8 *)(GT64240_BASE+(ofs)) = data -#define GT_READ_8(ofs, data) \ - *(data) = *(volatile u8 *)(GT64240_BASE+(ofs)) - -#endif /* _ASM_GT64120_MOMENCO_OCELOT_GT64120_DEP_H */ diff -Nru a/arch/mips/momentum/ocelot_g/pci-irq.c b/arch/mips/momentum/ocelot_g/pci-irq.c --- a/arch/mips/momentum/ocelot_g/pci-irq.c 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,73 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Based on work for the Linux port to the Ocelot board, which is - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/momentum/ocelot_g/pci.c - * Board-specific PCI routines for gt64240 controller. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include - - -void __devinit gt64240_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - /* loop over all known devices on this bus */ - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if ((current_bus->number == 0) && - PCI_SLOT(devices->devfn) == 1) { - /* Intel 82543 Gigabit MAC */ - devices->irq = 2; /* irq_nr is 2 for INT0 */ - } else if ((current_bus->number == 0) && - PCI_SLOT(devices->devfn) == 2) { - /* Intel 82543 Gigabit MAC */ - devices->irq = 3; /* irq_nr is 3 for INT1 */ - } else if ((current_bus->number == 1) && - PCI_SLOT(devices->devfn) == 3) { - /* Intel 21555 bridge */ - devices->irq = 5; /* irq_nr is 8 for INT6 */ - } else if ((current_bus->number == 1) && - PCI_SLOT(devices->devfn) == 4) { - /* PMC Slot */ - devices->irq = 9; /* irq_nr is 9 for INT7 */ - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write(current_bus, devices, - PCI_INTERRUPT_LINE, 1, devices->irq); - - /* enable master for everything but the GT-64240 */ - if (((current_bus->number != 0) && (current_bus->number != 1)) - || (PCI_SLOT(devices->devfn) != 0)) { - bus->ops->read(current_bus, devices, - PCI_COMMAND, 2, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write(current_bus, devices, - PCI_COMMAND, 2, cmd); - } - } -} diff -Nru a/arch/mips/momentum/ocelot_g/prom.c b/arch/mips/momentum/ocelot_g/prom.c --- a/arch/mips/momentum/ocelot_g/prom.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/momentum/ocelot_g/prom.c 2004-06-26 17:09:16 -07:00 @@ -20,8 +20,8 @@ #include #include #include +#include -#include "gt64240.h" #include "ocelot_pld.h" struct callvectors* debug_vectors; @@ -38,10 +38,8 @@ return "Momentum Ocelot"; } -/* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(void) { - uint32_t tmp; int argc = fw_arg0; char **arg = (char **) fw_arg1; char **env = (char **) fw_arg2; @@ -78,10 +76,8 @@ bus_clock = simple_strtol(*env + strlen("busclock="), NULL, 10); } - *env++; + env++; } - - debug_vectors->printf("Booting Linux kernel...\n"); } unsigned long __init prom_free_prom_memory(void) diff -Nru a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c --- a/arch/mips/momentum/ocelot_g/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/momentum/ocelot_g/setup.c 2004-06-26 17:09:16 -07:00 @@ -1,6 +1,4 @@ /* - * setup.c - * * BRIEF MODULE DESCRIPTION * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines * @@ -55,14 +53,14 @@ #include #include #include +#include #include #include #include #include #include #include -#include -#include "gt64240.h" + #include "ocelot_pld.h" #ifdef CONFIG_GALILLEO_GT64240_ETH @@ -88,8 +86,6 @@ _CACHE_UNCACHED)) >> 6; } -static void __init setup_l3cache(unsigned long size); - /* setup code for a handoff from a version 2 PMON 2000 PROM */ void PMON_v2_setup(void) { @@ -104,8 +100,10 @@ GT64240 Internal Regs 0xf4000000 0xe0000000 UARTs (CS2) 0xfd000000 0xe0001000 */ - add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); - add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), 0xfd000000, PM_4K); + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), + 0xf4000000, PM_64K); + add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), + 0xfd000000, PM_4K); /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM in the CS[012] region. We can't use ioremap() yet. The NVRAM @@ -114,15 +112,57 @@ Ocelot PLD (CS0) 0xfc000000 0xe0020000 NVRAM (CS1) 0xfc800000 0xe0030000 */ - add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), 0xfc000000, PM_64K); - add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), 0xfc800000, PM_64K); + add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), + 0xfc000000, PM_64K); + add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), + 0xfc800000, PM_64K); gt64240_base = 0xf4000000; } -static void __init momenco_ocelot_g_setup(void) +extern int rm7k_tcache_enabled; + +/* + * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() + */ +#define Page_Invalidate_T 0x16 +static void __init setup_l3cache(unsigned long size) +{ + int register i; + + printk("Enabling L3 cache..."); + + /* Enable the L3 cache in the GT64120A's CPU Configuration register */ + GT_WRITE(0, GT_READ(0) | (1<<14)); + + /* Enable the L3 cache in the CPU */ + set_c0_config(1<<12 /* CONF_TE */); + + /* Clear the cache */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i < size; i+= 4096) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (KSEG0ADDR(i)), + "i" (Page_Invalidate_T)); + } + + /* Let the RM7000 MM code know that the tertiary cache is enabled */ + rm7k_tcache_enabled = 1; + + printk("Done\n"); +} + +static int __init momenco_ocelot_g_setup(void) { - void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); + void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache); unsigned int tmpword; board_time_init = gt64240_time_init; @@ -200,51 +240,11 @@ /* FIXME: Fix up the DiskOnChip mapping */ GT_WRITE(0x468, 0xfef73); -} - -early_initcall(momenco_ocelot_g_setup); - -extern int rm7k_tcache_enabled; -/* - * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() - */ -#define Page_Invalidate_T 0x16 -static void __init setup_l3cache(unsigned long size) -{ - int register i; - unsigned long tmp; - - printk("Enabling L3 cache..."); - - /* Enable the L3 cache in the GT64120A's CPU Configuration register */ - GT_READ(0, &tmp); - GT_WRITE(0, tmp | (1<<14)); - - /* Enable the L3 cache in the CPU */ - set_c0_config(1<<12 /* CONF_TE */); - - /* Clear the cache */ - write_c0_taglo(0); - write_c0_taghi(0); - for (i=0; i < size; i+= 4096) { - __asm__ __volatile__ ( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (KSEG0ADDR(i)), - "i" (Page_Invalidate_T)); - } - - /* Let the RM7000 MM code know that the tertiary cache is enabled */ - rm7k_tcache_enabled = 1; - - printk("Done\n"); + return 0; } +early_initcall(momenco_ocelot_g_setup); /* This needs to be one of the first initcalls, because no I/O port access can work before this */ @@ -252,12 +252,12 @@ static int io_base_ioremap(void) { /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ - void *io_remap_range = ioremap(0xc0000000, 0x30000000); + unsigned long io_remap_range; - if (!io_remap_range) { + io_remap_range = (unsigned long) ioremap(0xc0000000, 0x30000000); + if (!io_remap_range) panic("Could not ioremap I/O port range"); - } - printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); return 0; diff -Nru a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile --- a/arch/mips/pci/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/pci/Makefile 2004-06-26 17:09:15 -07:00 @@ -16,6 +16,7 @@ obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o obj-$(CONFIG_MIPS_TX3927) += ops-jmr3927.o +obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o # # These are still pretty much in the old state, watch, go blind. @@ -34,20 +35,20 @@ obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o -obj-$(CONFIG_MIPS_MV64340) += fixup-mv64340.o +obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o -obj-$(CONFIG_MOMENCO_OCELOT_C) += pci-ocelot-c.o -obj-$(CONFIG_MOMENCO_OCELOT_G) += pci-ocelot-g.o +obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o +obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o ops-gt64240.o pci-ocelot-g.o obj-$(CONFIG_NEC_EAGLE) += fixup-eagle.o ops-vrc4173.o -obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o +obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ + pci-yosemite.o obj-$(CONFIG_SGI_IP27) += pci-ip27.o obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o obj-$(CONFIG_SIBYTE_SB1250) += pci-sb1250.o obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o +obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o -obj-$(CONFIG_TANBAC_TB0229) += fixup-tb0229.o obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o -obj-$(CONFIG_VICTOR_MPC30X) += fixup-capcella.o -obj-$(CONFIG_MACH_VR41XX) += pci-vr41xx.o -obj-$(CONFIG_ZAO_CAPCELLA) += fixup-victor-mpc30x.o +obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o +obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o diff -Nru a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c --- a/arch/mips/pci/fixup-capcella.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/pci/fixup-capcella.c 2004-06-26 17:09:17 -07:00 @@ -1,17 +1,21 @@ /* - * FILE NAME - * arch/mips/vr41xx/zao-capcella/pci_fixup.c + * fixup-cappcela.c, The ZAO Networks Capcella specific PCI fixups. * - * BRIEF MODULE DESCRIPTION - * The ZAO Networks Capcella specific PCI fixups. + * Copyright (C) 2002,2004 Yoichi Yuasa * - * Copyright 2002 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include @@ -38,3 +42,7 @@ { return irq_tab_capcella[slot][pin]; } + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff -Nru a/arch/mips/pci/fixup-jaguar.c b/arch/mips/pci/fixup-jaguar.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/fixup-jaguar.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,42 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Marvell MV64340 interrupt fixup code. + * + * Marvell wants an NDA for their docs so this was written without + * documentation. You've been warned. + * + * Copyright (C) 2004 Ralf Baechle + */ +#include +#include +#include + +#include +#include + +/* + * WARNING: Example of how _NOT_ to do it. + */ +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) + return 3; /* PCI-X A */ + if (bus == 0 && slot == 2) + return 4; /* PCI-X B */ + if (bus == 1 && slot == 1) + return 5; /* PCI A */ + if (bus == 1 && slot == 2) + return 6; /* PCI B */ + +return 0; + panic("Whooops in pcibios_map_irq"); +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff -Nru a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/fixup-mpc30x.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,48 @@ +/* + * fixup-mpc30x.c, The Victor MP-C303/304 specific PCI fixups. + * + * Copyright (C) 2002,2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include +#include + +static const int internal_func_irqs[] __initdata = { + VRC4173_CASCADE_IRQ, + VRC4173_AC97_IRQ, + VRC4173_USB_IRQ, +}; + +static char irq_tab_mpc30x[] __initdata = { + [12] = VRC4173_PCMCIA1_IRQ, + [13] = VRC4173_PCMCIA2_IRQ, + [29] = MQ200_IRQ, +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (slot == 30) + return internal_func_irqs[PCI_FUNC(dev->devfn)]; + + return irq_tab_mpc30x[slot]; +} + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff -Nru a/arch/mips/pci/fixup-mv64340.c b/arch/mips/pci/fixup-mv64340.c --- a/arch/mips/pci/fixup-mv64340.c 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,42 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Marvell MV64340 interrupt fixup code. - * - * Marvell wants an NDA for their docs so this was written without - * documentation. You've been warned. - * - * Copyright (C) 2004 Ralf Baechle - */ -#include -#include -#include - -#include -#include - -/* - * WARNING: Example of how _NOT_ to do it. - */ -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int bus = dev->bus->number; - - if (bus == 0 && slot == 1) - return 3; /* PCI-X A */ - if (bus == 0 && slot == 2) - return 4; /* PCI-X B */ - if (bus == 1 && slot == 1) - return 5; /* PCI A */ - if (bus == 1 && slot == 2) - return 6; /* PCI B */ - -return 0; - panic("Whooops in pcibios_map_irq"); -} - -struct pci_fixup pcibios_fixups[] = { - {0} -}; diff -Nru a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/fixup-ocelot-c.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,39 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/ocelot_g/pci.c + * Board-specific PCI routines for mv64340 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) + return 2; /* PCI-X A */ + if (bus == 1 && slot == 1) + return 12; /* PCI-X B */ + if (bus == 1 && slot == 2) + return 4; /* PCI B */ + +return 0; + panic("Whooops in pcibios_map_irq"); +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff -Nru a/arch/mips/pci/fixup-ocelot-g.c b/arch/mips/pci/fixup-ocelot-g.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/fixup-ocelot-g.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,35 @@ +/* + * 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. + * + * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) /* Intel 82543 Gigabit MAC */ + return 2; /* irq_nr is 2 for INT0 */ + + if (bus == 0 && slot == 2) /* Intel 82543 Gigabit MAC */ + return 3; /* irq_nr is 3 for INT1 */ + + if (bus == 1 && slot == 3) /* Intel 21555 bridge */ + return 5; /* irq_nr is 8 for INT6 */ + + if (bus == 1 && slot == 4) /* PMC Slot */ + return 9; /* irq_nr is 9 for INT7 */ + + return -1; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff -Nru a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/fixup-tb0219.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,64 @@ +/* + * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. + * + * Copyright (C) 2003 Megasolution Inc. + * Copyright (C) 2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = -1; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT2_IRQ; + break; + case 14: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT3_IRQ; + break; + default: + break; + } + + return irq; +} + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff -Nru a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c --- a/arch/mips/pci/fixup-tb0226.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/pci/fixup-tb0226.c 2004-06-26 17:09:19 -07:00 @@ -1,78 +1,83 @@ /* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c + * fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups. * - * BRIEF MODULE DESCRIPTION - * The TANBAC TB0226 specific PCI fixups. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include -void __init pcibios_fixup_irqs(void) +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - struct pci_dev *dev = NULL; - u8 slot, pin; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot = PCI_SLOT(dev->devfn); - dev->irq = 0; + int irq = -1; - switch (slot) { - case 12: - vr41xx_set_irq_trigger(GD82559_1_PIN, + switch (slot) { + case 12: + vr41xx_set_irq_trigger(GD82559_1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); + irq = GD82559_1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(GD82559_2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); + irq = GD82559_2_IRQ; + break; + case 14: + switch (pin) { + case 1: + vr41xx_set_irq_trigger(UPD720100_INTA_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTA_PIN, + LEVEL_LOW); + irq = UPD720100_INTA_IRQ; + break; + case 2: + vr41xx_set_irq_trigger(UPD720100_INTB_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); - dev->irq = GD82559_1_IRQ; + vr41xx_set_irq_level(UPD720100_INTB_PIN, + LEVEL_LOW); + irq = UPD720100_INTB_IRQ; break; - case 13: - vr41xx_set_irq_trigger(GD82559_2_PIN, + case 3: + vr41xx_set_irq_trigger(UPD720100_INTC_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); - dev->irq = GD82559_2_IRQ; + vr41xx_set_irq_level(UPD720100_INTC_PIN, + LEVEL_LOW); + irq = UPD720100_INTC_IRQ; break; - case 14: - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - switch (pin) { - case 1: - vr41xx_set_irq_trigger(UPD720100_INTA_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTA_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTA_IRQ; - break; - case 2: - vr41xx_set_irq_trigger(UPD720100_INTB_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTB_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTB_IRQ; - break; - case 3: - vr41xx_set_irq_trigger(UPD720100_INTC_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTC_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTC_IRQ; - break; - } + default: break; } - - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + break; + default: + break; } + + return irq; } + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff -Nru a/arch/mips/pci/fixup-tb0229.c b/arch/mips/pci/fixup-tb0229.c --- a/arch/mips/pci/fixup-tb0229.c 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,64 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c - * - * BRIEF MODULE DESCRIPTION - * The TANBAC TB0229(VR4131DIMM) specific PCI fixups. - * - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -#include - -void __init pcibios_fixup_irqs(void) -{ -#ifdef CONFIG_TANBAC_TB0219 - struct pci_dev *dev = NULL; - u8 slot; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot = PCI_SLOT(dev->devfn); - dev->irq = 0; - - switch (slot) { - case 12: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT1_IRQ; - break; - case 13: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT2_IRQ; - break; - case 14: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT3_IRQ; - break; - default: - break; - } - - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } -#endif -} diff -Nru a/arch/mips/pci/fixup-victor-mpc30x.c b/arch/mips/pci/fixup-victor-mpc30x.c --- a/arch/mips/pci/fixup-victor-mpc30x.c 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,48 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/victor-mpc30x/pci_fixup.c - * - * BRIEF MODULE DESCRIPTION - * The Victor MP-C303/304 specific PCI fixups. - * - * Copyright 2002 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include -#include - -/* - * Shortcuts - */ -#define PCMCIA1 VRC4173_PCMCIA1_IRQ -#define PCMCIA2 VRC4173_PCMCIA2_IRQ -#define MQ MQ200_IRQ - -static const int internal_func_irqs[8] __initdata = { - VRC4173_CASCADE_IRQ, - VRC4173_AC97_IRQ, - VRC4173_USB_IRQ, - -}; - -static char irq_tab_mpc30x[][5] __initdata = { - [12] = { PCMCIA1, PCMCIA1, 0, 0 }, - [13] = { PCMCIA2, PCMCIA2, 0, 0 }, - [29] = { MQ, MQ, 0, 0 }, /* mediaQ MQ-200 */ -}; - -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (slot == 30) - return internal_func_irqs[PCI_FUNC(dev->devfn)]; - - return irq_tab_mpc30x[slot][pin]; -} diff -Nru a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c --- a/arch/mips/pci/fixup-yosemite.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/pci/fixup-yosemite.c 2004-06-26 17:09:17 -07:00 @@ -26,21 +26,12 @@ #include #include -static char irq_tab_yosemite[8][5] __initdata = { - /* INTA INTB INTC INTD */ - { -1, -1, -1, -1, -1 }, - { -1, 3, 3, 3, 3 }, - { -1, 4, 4, 4, 4 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, -}; - int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - return irq_tab_yosemite[slot][pin]; + if (pin == 0) + return -1; + + return 3; /* Everything goes to one irq bit */ } struct pci_fixup pcibios_fixups[] = { diff -Nru a/arch/mips/pci/ops-gt64240.c b/arch/mips/pci/ops-gt64240.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/ops-gt64240.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,149 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm + * Copyright (C) 2004 Ralf Baechle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + + +#define MASTER_ABORT_BIT 0x100 + +/* + * galileo_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + + +static int gt_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int size, u32 *val, u32 address_reg, u32 data_reg) +{ + uint32_t address; + int dev, busno; + + busno = bus->number; + dev = PCI_SLOT(devfn); + + /* verify the range */ + if (dev == 31) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + switch (size) { + case 1: + GT_READ_8(data_reg + (offset & 0x3), val); + break; + case 2: + GT_READ_16(data_reg + (offset & 0x3), val); + break; + case 4: + *val = GT_READ(data_reg); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int gt_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int size, u32 val, u32 address_reg, u32 data_reg) +{ + unsigned int address; + int dev, busno; + + busno = bus->number; + dev = PCI_SLOT(devfn); + + /* verify the range */ + if (dev == 31) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + switch (size) { + case 1: + GT_WRITE_8(data_reg + (offset & 0x3), val); + break; + case 2: + GT_WRITE_16(data_reg + (offset & 0x3), val); + break; + case 4: + GT_WRITE(data_reg, val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +#define BUILD_PCI_OPS(host) \ + \ +static int gt_bus ## host ## _read_config(struct pci_bus *bus, \ + unsigned int devfn, int reg, int size, u32 * val) \ +{ \ + return gt_read_config(bus, devfn, reg, size, val, \ + PCI_ ## host ## CONFIGURATION_ADDRESS, \ + PCI_ ## host ## CONFIGURATION_DATA_VIRTUAL_REGISTER); \ +} \ + \ +static int gt_bus ## host ## _write_config(struct pci_bus *bus, \ + unsigned int devfn, int reg, int size, u32 val) \ +{ \ + return gt_write_config(bus, devfn, reg, size, val, \ + PCI_ ## host ## CONFIGURATION_ADDRESS, \ + PCI_ ## host ## CONFIGURATION_DATA_VIRTUAL_REGISTER); \ +} \ + \ +struct pci_ops gt_bus ## host ## _pci_ops = { \ + .read = gt_bus ## host ## _read_config, \ + .write = gt_bus ## host ## _write_config \ +}; + +BUILD_PCI_OPS(0) +BUILD_PCI_OPS(1) diff -Nru a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c --- a/arch/mips/pci/ops-msc.c 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/pci/ops-msc.c 2004-06-26 17:09:21 -07:00 @@ -48,8 +48,12 @@ unsigned char type; u32 intr; - if ((busnum == 0) && (PCI_SLOT(devfn) == 0)) +#ifdef CONFIG_MIPS_BOARDS_GEN + if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) { + /* MIPS Core boards have SOCit connected as device 17 */ return -1; + } +#endif /* Clear status register bits. */ MSC_WRITE(MSC01_PCI_INTSTAT, diff -Nru a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/ops-titan-ht.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,125 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn, + int offset, u32 * val) +{ + volatile uint32_t address; + int busno; + + busno = bus->number; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + if (busno != 0) + address |= 1; + + /* + * RM9000 HT Errata: Issue back to back HT config + * transcations. Issue a BIU sync before and + * after the HT cycle + */ + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + udelay(30); + + *(volatile int32_t *) 0xfb0006f8 = address; + *(val) = *(volatile int32_t *) 0xfb0006fc; + + udelay(30); + + * (volatile int32_t *) 0xfb0000f0 |= 0x2; + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 * val) +{ + uint32_t dword; + + titan_ht_config_read_dword(bus, devfn, offset, &dword); + + dword >>= ((offset & 3) << 3); + dword &= (0xffffffffU >> ((4 - size) << 8)); + + return PCIBIOS_SUCCESSFUL; +} + +static inline int titan_ht_config_write_dword(struct pci_bus *bus, + unsigned int devfn, int offset, u32 val) +{ + volatile uint32_t address; + int busno; + + busno = bus->number; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + if (busno != 0) + address |= 1; + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + udelay(30); + + *(volatile int32_t *) 0xfb0006f8 = address; + *(volatile int32_t *) 0xfb0006fc = val; + + udelay(30); + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 val) +{ + uint32_t val1, val2, mask; + + titan_ht_config_read_dword(bus, devfn, offset, &val2); + + val1 = val << ((offset & 3) << 3); + mask = ~(0xffffffffU >> ((4 - size) << 8)); + val2 &= ~(mask << ((offset & 3) << 8)); + + titan_ht_config_write_dword(bus, devfn, offset, val1 | val2); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops titan_ht_pci_ops = { + .read = titan_ht_config_read, + .write = titan_ht_config_write, +}; diff -Nru a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c --- a/arch/mips/pci/ops-titan.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/pci/ops-titan.c 2004-06-26 17:09:16 -07:00 @@ -39,30 +39,30 @@ static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 * val) { - int dev, bus, func; + int dev, busno, func; uint32_t address_reg, data_reg; uint32_t address; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); address_reg = TITAN_PCI_0_CONFIG_ADDRESS; data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; + address = (busno << 16) | (dev << 11) | (func << 8) | + (reg & 0xfc) | 0x80000000; /* start the configuration cycle */ TITAN_WRITE(address_reg, address); switch (size) { case 1: - TITAN_READ_8(data_reg + (offset & 0x3), val); + TITAN_READ_8(data_reg + (reg & 0x3), val); break; case 2: - TITAN_READ_16(data_reg + (offset & 0x2), val); + TITAN_READ_16(data_reg + (reg & 0x2), val); break; case 4: @@ -80,17 +80,17 @@ int size, u32 val) { uint32_t address_reg, data_reg, address; - int dev, bus, func; + int dev, busno, func; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); address_reg = TITAN_PCI_0_CONFIG_ADDRESS; data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; + address = (busno << 16) | (dev << 11) | (func << 8) | + (reg & 0xfc) | 0x80000000; /* start the configuration cycle */ TITAN_WRITE(address_reg, address); @@ -98,11 +98,11 @@ /* write the data */ switch (size) { case 1: - TITAN_WRITE_8(data_reg + (offset & 0x3), val); + TITAN_WRITE_8(data_reg + (reg & 0x3), val); break; case 2: - TITAN_WRITE_16(data_reg + (offset & 0x2), val); + TITAN_WRITE_16(data_reg + (reg & 0x2), val); break; case 4: diff -Nru a/arch/mips/pci/ops-vr41xx.c b/arch/mips/pci/ops-vr41xx.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/ops-vr41xx.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,126 @@ +/* + * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series. + * + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * Changes: + * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include +#include + +#include + +#define PCICONFDREG KSEG1ADDR(0x0f000c14) +#define PCICONFAREG KSEG1ADDR(0x0f000c18) + +static inline int set_pci_configuration_address(unsigned char number, + unsigned int devfn, int where) +{ + if (number == 0) { + /* + * Type 0 configuration + */ + if (PCI_SLOT(devfn) < 11 || where > 0xff) + return -EINVAL; + + writel((1U << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) | + (where & 0xfc), PCICONFAREG); + } else { + /* + * Type 1 configuration + */ + if (where > 0xff) + return -EINVAL; + + writel(((uint32_t)number << 16) | ((devfn & 0xff) << 8) | + (where & 0xfc) | 1U, PCICONFAREG); + } + + return 0; +} + +static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *val) +{ + uint32_t data; + + *val = 0xffffffffU; + if (set_pci_configuration_address(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xffU; + break; + case 2: + *val = (data >> ((where & 2) << 3)) & 0xffffU; + break; + case 4: + *val = data; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t val) +{ + uint32_t data; + int shift; + + if (set_pci_configuration_address(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + shift = (where & 3) << 3; + data &= ~(0xffU << shift); + data |= ((val & 0xffU) << shift); + break; + case 2: + shift = (where & 2) << 3; + data &= ~(0xffffU << shift); + data |= ((val & 0xffffU) << shift); + break; + case 4: + data = val; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + writel(data, PCICONFDREG); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops vr41xx_pci_ops = { + .read = pci_config_read, + .write = pci_config_write, +}; diff -Nru a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c --- a/arch/mips/pci/pci-ocelot-c.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/pci/pci-ocelot-c.c 2004-06-26 17:09:19 -07:00 @@ -1,61 +1,140 @@ /* - * Copyright 2002 Momentum Computer - * Author: Matthew Dharm + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * Copyright (C) 2004 by Ralf Baechle */ + #include #include -#include -#include -#include -#include #include +#include #include /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. + * We assume the address ranges have already been setup appropriately by + * the firmware. PMON in case of the Ocelot C does that. */ +static struct resource mv_pci_io_mem0_resource = { + .name = "MV64340 PCI0 IO MEM", + .flags = IORESOURCE_IO +}; -void mv64340_board_pcibios_fixup_bus(struct pci_bus *c); +static struct resource mv_pci_mem0_resource = { + .name = "MV64340 PCI0 MEM", + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops mv64340_bus0_pci_ops; -struct pci_fixup pcibios_fixups[] = { - {0} +static struct pci_controller mv_bus0_controller = { + .pci_ops = &mv64340_bus0_pci_ops, + .mem_resource = &mv_pci_mem0_resource, + .io_resource = &mv_pci_io_mem0_resource, }; -void __init pcibios_fixup_bus(struct pci_bus *c) +static uint32_t mv_io_base, mv_io_size; + +static void mv64340_pci0_init(void) { - mv64340_board_pcibios_fixup_bus(c); + uint32_t mem0_base, mem0_size; + uint32_t io_base, io_size; + + io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16; + io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16; + mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16; + mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16; + + mv_pci_io_mem0_resource.start = 0; + mv_pci_io_mem0_resource.end = io_size - 1; + mv_pci_mem0_resource.start = mem0_base; + mv_pci_mem0_resource.end = mem0_base + mem0_size - 1; + mv_bus0_controller.mem_offset = mem0_base; + mv_bus0_controller.io_offset = 0; + + ioport_resource.end = io_size - 1; + + register_pci_controller(&mv_bus0_controller); + + mv_io_base = io_base; + mv_io_size = io_size; } -void __init pcibios_init(void) +static struct resource mv_pci_io_mem1_resource = { + .name = "MV64340 PCI1 IO MEM", + .flags = IORESOURCE_IO +}; + +static struct resource mv_pci_mem1_resource = { + .name = "MV64340 PCI1 MEM", + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops mv64340_bus1_pci_ops; + +static struct pci_controller mv_bus1_controller = { + .pci_ops = &mv64340_bus1_pci_ops, + .mem_resource = &mv_pci_mem1_resource, + .io_resource = &mv_pci_io_mem1_resource, +}; + +static __init void mv64340_pci1_init(void) +{ + uint32_t mem0_base, mem0_size; + uint32_t io_base, io_size; + + io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16; + io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16; + mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16; + mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16; + + /* + * Here we assume the I/O window of second bus to be contiguous with + * the first. A gap is no problem but would waste address space for + * remapping the port space. + */ + mv_pci_io_mem1_resource.start = mv_io_size; + mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1; + mv_pci_mem1_resource.start = mem0_base; + mv_pci_mem1_resource.end = mem0_base + mem0_size - 1; + mv_bus1_controller.mem_offset = mem0_base; + mv_bus1_controller.io_offset = 0; + + ioport_resource.end = io_base + io_size -mv_io_base - 1; + + register_pci_controller(&mv_bus1_controller); + + mv_io_size = io_base + io_size - mv_io_base; +} + +static __init int __init ocelot_c_pci_init(void) { - /* Reset PCI I/O and PCI MEM values */ - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + unsigned long io_v_base; + uint32_t enable; + + enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE); - pci_scan_bus(0, &mv64340_bus0_pci_ops, NULL); - pci_scan_bus(1, &mv64340_bus1_pci_ops, NULL); + /* + * We require at least one enabled I/O or PCI memory window or we + * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3. + */ + if (enable & (0x01 << 9) || enable & (0x01 << 10)) + mv64340_pci0_init(); + + if (enable & (0x01 << 14) || enable & (0x01 << 15)) + mv64340_pci1_init(); + + if (mv_io_size) { + io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size); + if (!io_v_base) + panic("Could not ioremap I/O port range"); + + set_io_port_base(io_v_base); + } + + return 0; } + +arch_initcall(ocelot_c_pci_init); diff -Nru a/arch/mips/pci/pci-ocelot-g.c b/arch/mips/pci/pci-ocelot-g.c --- a/arch/mips/pci/pci-ocelot-g.c 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/pci/pci-ocelot-g.c 2004-06-26 17:09:18 -07:00 @@ -1,460 +1,90 @@ /* - * Copyright 2002 Momentum Computer - * Author: Matthew Dharm + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * 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. + * Copyright (C) 2004 by Ralf Baechle * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * This doesn't really fly - but I don't have a GT64240 system for testing. */ +#include +#include #include #include -#include -#include -#include -#include -#include "gt64240.h" - -#include - -#define SELF 0 -#define MASTER_ABORT_BIT 0x100 +#include +#include /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. + * We assume these address ranges have been programmed into the GT-64240 by + * the firmware. PMON in case of the Ocelot G does that. Note the size of + * the I/O range is completly stupid; I/O mappings are limited to at most + * 256 bytes by the PCI spec and deprecated; and just to make things worse + * apparently many devices don't decode more than 64k of I/O space. */ -void gt64240_board_pcibios_fixup_bus(struct pci_bus *c); - -/* Functions to implement "pci ops" */ -static int galileo_pcibios_read_config_word(int bus, int devfn, - int offset, u16 * val); -static int galileo_pcibios_read_config_byte(int bus, int devfn, - int offset, u8 * val); -static int galileo_pcibios_read_config_dword(int bus, int devfn, - int offset, u32 * val); -static int galileo_pcibios_write_config_byte(int bus, int devfn, - int offset, u8 val); -static int galileo_pcibios_write_config_word(int bus, int devfn, - int offset, u16 val); -static int galileo_pcibios_write_config_dword(int bus, int devfn, - int offset, u32 val); - -static int pci_read(struct pci_bus *bus, unsigned int devfs, int where, - int size, u32 * val); -static int pci_write(struct pci_bus *bus, unsigned int devfs, int where, - int size, u32 val); - -/* - * General-purpose PCI functions. - */ - - -/* - * pci_range_ck - - * - * Check if the pci device that are trying to access does really exists - * on the evaluation board. - * - * Inputs : - * bus - bus number (0 for PCI 0 ; 1 for PCI 1) - * dev - number of device on the specific pci bus - * - * Outpus : - * 0 - if OK , 1 - if failure - */ -static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) -{ - /* Accessing device 31 crashes the GT-64240. */ - if (dev < 5) - return 0; - return -1; -} - -/* - * galileo_pcibios_(read/write)_config_(dword/word/byte) - - * - * reads/write a dword/word/byte register from the configuration space - * of a device. - * - * Note that bus 0 and bus 1 are local, and we assume all other busses are - * bridged from bus 1. This is a safe assumption, since any other - * configuration will require major modifications to the CP7000G - * - * Inputs : - * bus - bus number - * dev - device number - * offset - register offset in the configuration space - * val - value to be written / read - * - * Outputs : - * PCIBIOS_SUCCESSFUL when operation was succesfull - * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous - * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned - */ - -static int galileo_pcibios_read_config_dword(int bus, int devfn, - int offset, u32 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* read the data */ - GT_READ(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_read_config_word(int bus, int devfn, - int offset, u16 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* read the data */ - GT_READ_16(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_byte(int bus, int devfn, - int offset, u8 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); +#define gt_io_size 0x20000000UL +#define gt_io_base 0xe0000000UL - /* write the data */ - GT_READ_8(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_dword(int bus, int devfn, - int offset, u32 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_write_config_word(int bus, int devfn, - int offset, u16 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE_16(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_byte(int bus, int devfn, - int offset, u8 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE_8(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops galileo_pci_ops = { - .read = pci_read, - .write = pci_write +static struct resource gt_pci_mem0_resource = { + .name = "MV64240 PCI0 MEM", + .start = 0xc0000000UL, + .end = 0xcfffffffUL, + .flags = IORESOURCE_MEM }; -static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 * val) -{ - switch (size) { - case 1: - return galileo_pcibios_read_config_byte(bus->number, - devfn, where, - (u8 *) val); - case 2: - return galileo_pcibios_read_config_word(bus->number, - devfn, where, - (u16 *) val); - case 4: - return galileo_pcibios_read_config_dword(bus->number, - devfn, where, - (u32 *) val); - } - return PCIBIOS_FUNC_NOT_SUPPORTED; -} - -static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - switch (size) { - case 1: - return galileo_pcibios_write_config_byte(bus->number, - devfn, where, - val); - case 2: - return galileo_pcibios_write_config_word(bus->number, - devfn, where, - val); - case 4: - return galileo_pcibios_write_config_dword(bus->number, - devfn, where, - val); - } - return PCIBIOS_FUNC_NOT_SUPPORTED; -} - -struct pci_fixup pcibios_fixups[] = { - {0} +static struct resource gt_pci_io_mem0_resource = { + .name = "MV64240 PCI0 IO MEM", + .start = 0xe0000000UL, + .end = 0xefffffffUL, + .flags = IORESOURCE_IO }; -void __devinit pcibios_fixup_bus(struct pci_bus *c) -{ - gt64240_board_pcibios_fixup_bus(c); -} +static struct pci_controller gt_bus0_controller = { + .pci_ops = >_bus0_pci_ops, + .mem_resource = >_pci_mem0_resource, + .mem_offset = 0xc0000000UL, + .io_resource = >_pci_io_mem0_resource, + .io_offset = 0x00000000UL +}; +static struct resource gt_pci_mem1_resource = { + .name = "MV64240 PCI1 MEM", + .start = 0xd0000000UL, + .end = 0xdfffffffUL, + .flags = IORESOURCE_MEM +}; -/******************************************************************** -* pci0P2PConfig - This function set the PCI_0 P2P configurate. -* For more information on the P2P read PCI spec. -* -* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower -* Boundry. -* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper -* Boundry. -* unsigned int busNum - The CPI bus number to which the PCI interface -* is connected. -* unsigned int devNum - The PCI interface's device number. -* -* Returns: true. -*/ -void pci0P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, - unsigned int busNum, unsigned int devNum) -{ - uint32_t regData; +static struct resource gt_pci_io_mem1_resource = { + .name = "MV64240 PCI1 IO MEM", + .start = 0xf0000000UL, + .end = 0xffffffffUL, + .flags = IORESOURCE_IO +}; - regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | - ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); - GT_WRITE(PCI_0P2P_CONFIGURATION, regData); -} +static struct pci_controller gt_bus1_controller = { + .pci_ops = >_bus1_pci_ops, + .mem_resource = >_pci_mem1_resource, + .mem_offset = 0xd0000000UL, + .io_resource = >_pci_io_mem1_resource, + .io_offset = 0x10000000UL +}; -/******************************************************************** -* pci1P2PConfig - This function set the PCI_1 P2P configurate. -* For more information on the P2P read PCI spec. -* -* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower -* Boundry. -* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper -* Boundry. -* unsigned int busNum - The CPI bus number to which the PCI interface -* is connected. -* unsigned int devNum - The PCI interface's device number. -* -* Returns: true. -*/ -void pci1P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, - unsigned int busNum, unsigned int devNum) +static __init int __init ocelot_g_pci_init(void) { - uint32_t regData; - - regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | - ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); - GT_WRITE(PCI_1P2P_CONFIGURATION, regData); -} + unsigned long io_v_base; -#define PCI0_STATUS_COMMAND_REG 0x4 -#define PCI1_STATUS_COMMAND_REG 0x84 + if (gt_io_size) { + io_v_base = (unsigned long) ioremap(gt_io_base, gt_io_size); + if (!io_v_base) + panic("Could not ioremap I/O port range"); -static int __init pcibios_init(void) -{ - /* Reset PCI I/O and PCI MEM values */ - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + set_io_port_base(io_v_base); + } - pci_scan_bus(0, &galileo_pci_ops, NULL); - pci_scan_bus(1, &galileo_pci_ops, NULL); + register_pci_controller(>_bus0_controller); + register_pci_controller(>_bus1_controller); return 0; } -subsys_initcall(pcibios_init); +arch_initcall(ocelot_g_pci_init); diff -Nru a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c --- a/arch/mips/pci/pci-vr41xx.c 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/pci/pci-vr41xx.c 2004-06-26 17:09:21 -07:00 @@ -1,48 +1,32 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/pciu.c + * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * PCI Control Unit routines for the NEC VR4100 series. + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Copyright 2001-2003 MontaVista Software Inc. + * 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. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * 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 */ /* * Changes: - * Paul Mundt - * - Fix deadlock-causing PCIU access race for VR4131. - * * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. */ -#include #include #include #include -#include #include #include @@ -51,183 +35,257 @@ #include "pci-vr41xx.h" -static inline int vr41xx_pci_config_access(unsigned char bus, - unsigned int devfn, int where) -{ - if (bus == 0) { - /* - * Type 0 configuration - */ - if (PCI_SLOT(devfn) < 11 || where > 255) - return -1; - - writel((1UL << PCI_SLOT(devfn)) | - (PCI_FUNC(devfn) << 8) | - (where & 0xfc), PCICONFAREG); - } else { - /* - * Type 1 configuration - */ - if (where > 255) - return -1; - - writel((bus << 16) | - (devfn << 8) | (where & 0xfc) | 1UL, PCICONFAREG); - } - - return 0; -} - -static int vr41xx_pci_config_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - u32 data; +extern struct pci_ops vr41xx_pci_ops; - *val = 0xffffffffUL; - if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; +static struct pci_master_address_conversion pci_master_memory1 = { + .bus_base_address = PCI_MASTER_MEM1_BUS_BASE_ADDRESS, + .address_mask = PCI_MASTER_MEM1_ADDRESS_MASK, + .pci_base_address = PCI_MASTER_MEM1_PCI_BASE_ADDRESS, +}; - data = readl(PCICONFDREG); +static struct pci_target_address_conversion pci_target_memory1 = { + .address_mask = PCI_TARGET_MEM1_ADDRESS_MASK, + .bus_base_address = PCI_TARGET_MEM1_BUS_BASE_ADDRESS, +}; - switch (size) { - case 1: - *val = (data >> ((where & 3) << 3)) & 0xffUL; - break; - case 2: - *val = (data >> ((where & 2) << 3)) & 0xffffUL; - break; - case 4: - *val = data; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } +static struct pci_master_address_conversion pci_master_io = { + .bus_base_address = PCI_MASTER_IO_BUS_BASE_ADDRESS, + .address_mask = PCI_MASTER_IO_ADDRESS_MASK, + .pci_base_address = PCI_MASTER_IO_PCI_BASE_ADDRESS, +}; - return PCIBIOS_SUCCESSFUL; -} +static struct pci_mailbox_address pci_mailbox = { + .base_address = PCI_MAILBOX_BASE_ADDRESS, +}; -static int vr41xx_pci_config_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 data; - int shift; +static struct pci_target_address_window pci_target_window1 = { + .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS, +}; - if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; +static struct resource pci_mem_resource = { + .name = "PCI Memory resources", + .start = PCI_MEM_RESOURCE_START, + .end = PCI_MEM_RESOURCE_END, + .flags = IORESOURCE_MEM, +}; - data = readl(PCICONFDREG); +static struct resource pci_io_resource = { + .name = "PCI I/O resources", + .start = PCI_IO_RESOURCE_START, + .end = PCI_IO_RESOURCE_END, + .flags = IORESOURCE_IO, +}; - switch (size) { - case 1: - shift = (where & 3) << 3; - data &= ~(0xff << shift); - data |= ((val & 0xff) << shift); - break; - case 2: - shift = (where & 2) << 3; - data &= ~(0xffff << shift); - data |= ((val & 0xffff) << shift); - break; - case 4: - data = val; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } +static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = { + .master_memory1 = &pci_master_memory1, + .target_memory1 = &pci_target_memory1, + .master_io = &pci_master_io, + .exclusive_access = CANNOT_LOCK_FROM_DEVICE, + .wait_time_limit_from_irdy_to_trdy = 0, + .mailbox = &pci_mailbox, + .target_window1 = &pci_target_window1, + .master_latency_timer = 0x80, + .retry_limit = 0, + .arbiter_priority_control = PCI_ARBITRATION_MODE_FAIR, + .take_away_gnt_mode = PCI_TAKE_AWAY_GNT_DISABLE, +}; - writel(data, PCICONFDREG); +static struct pci_controller vr41xx_pci_controller = { + .pci_ops = &vr41xx_pci_ops, + .mem_resource = &pci_mem_resource, + .io_resource = &pci_io_resource, +}; - return PCIBIOS_SUCCESSFUL; +void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup) +{ + vr41xx_pci_controller_unit_setup = *setup; } -struct pci_ops vr41xx_pci_ops = { - .read = vr41xx_pci_config_read, - .write = vr41xx_pci_config_write, -}; - -void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map) +static int __init vr41xx_pciu_init(void) { - struct vr41xx_pci_address_space *s; - unsigned long vtclock; - u32 config; - int n; + struct pci_controller_unit_setup *setup; + struct pci_master_address_conversion *master; + struct pci_target_address_conversion *target; + struct pci_mailbox_address *mailbox; + struct pci_target_address_window *window; + unsigned long vtclock, pci_clock_max; + uint32_t val; - if (!map) - return; + setup = &vr41xx_pci_controller_unit_setup; /* Disable PCI interrupt */ - writew(0, MPCIINTREG); + vr41xx_disable_pciint(); /* Supply VTClock to PCIU */ vr41xx_supply_clock(PCIU_CLOCK); - /* - * Sleep for 1us after setting MSKPPCIU bit in CMUCLKMSK - * before doing any PCIU access to avoid deadlock on VR4131. - */ - udelay(1); + /* Dummy write, waiting for supply of VTClock. */ + vr41xx_disable_pciint(); /* Select PCI clock */ + if (setup->pci_clock_max != 0) + pci_clock_max = setup->pci_clock_max; + else + pci_clock_max = PCI_CLOCK_MAX; vtclock = vr41xx_get_vtclock_frequency(); - if (vtclock < MAX_PCI_CLOCK) + if (vtclock < pci_clock_max) writel(EQUAL_VTCLOCK, PCICLKSELREG); - else if ((vtclock / 2) < MAX_PCI_CLOCK) + else if ((vtclock / 2) < pci_clock_max) writel(HALF_VTCLOCK, PCICLKSELREG); - else if ((vtclock / 4) < MAX_PCI_CLOCK) + else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 && + (vtclock / 3) < pci_clock_max) + writel(ONE_THIRD_VTCLOCK, PCICLKSELREG); + else if ((vtclock / 4) < pci_clock_max) writel(QUARTER_VTCLOCK, PCICLKSELREG); - else - printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n"); + else { + printk(KERN_ERR "PCI Clock is over 33MHz.\n"); + return -EINVAL; + } /* Supply PCI clock by PCI bus */ vr41xx_supply_clock(PCI_CLOCK); - /* - * Set PCI memory & I/O space address conversion registers - * for master transaction. - */ - if (map->mem1 != NULL) { - s = map->mem1; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMMAW1REG); - } - if (map->mem2 != NULL) { - s = map->mem2; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMMAW2REG); - } - if (map->io != NULL) { - s = map->io; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMIOAWREG); - } - - /* Set target memory windows */ - writel(0x00081000, PCITAW1REG); - writel(0UL, PCITAW2REG); - pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0UL); - pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0UL); + if (setup->master_memory1 != NULL) { + master = setup->master_memory1; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIA(master->pci_base_address); + writel(val, PCIMMAW1REG); + } else { + val = readl(PCIMMAW1REG); + val &= ~WINEN; + writel(val, PCIMMAW1REG); + } + + if (setup->master_memory2 != NULL) { + master = setup->master_memory2; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIA(master->pci_base_address); + writel(val, PCIMMAW2REG); + } else { + val = readl(PCIMMAW2REG); + val &= ~WINEN; + writel(val, PCIMMAW2REG); + } - /* Clear bus error */ - n = readl(BUSERRADREG); + if (setup->target_memory1 != NULL) { + target = setup->target_memory1; + val = TARGET_MSK(target->address_mask) | + WINEN | + ITA(target->bus_base_address); + writel(val, PCITAW1REG); + } else { + val = readl(PCITAW1REG); + val &= ~WINEN; + writel(val, PCITAW1REG); + } + + if (setup->target_memory2 != NULL) { + target = setup->target_memory2; + val = TARGET_MSK(target->address_mask) | + WINEN | + ITA(target->bus_base_address); + writel(val, PCITAW2REG); + } else { + val = readl(PCITAW2REG); + val &= ~WINEN; + writel(val, PCITAW2REG); + } - if (current_cpu_data.cputype == CPU_VR4122) { - writel(0UL, PCITRDYVREG); - pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804); + if (setup->master_io != NULL) { + master = setup->master_io; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIIA(master->pci_base_address); + writel(val, PCIMIOAWREG); } else { - writel(100UL, PCITRDYVREG); - pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x00008004); + val = readl(PCIMIOAWREG); + val &= ~WINEN; + writel(val, PCIMIOAWREG); + } + + if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE) + writel(UNLOCK, PCIEXACCREG); + else + writel(0, PCIEXACCREG); + + if (current_cpu_data.cputype == CPU_VR4122) + writel(TRDYV(setup->wait_time_limit_from_irdy_to_trdy), PCITRDYVREG); + + writel(MLTIM(setup->master_latency_timer), LATTIMEREG); + + if (setup->mailbox != NULL) { + mailbox = setup->mailbox; + val = MBADD(mailbox->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, MAILBAREG); + } + + if (setup->target_window1) { + window = setup->target_window1; + val = PMBA(window->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, PCIMBA1REG); + } + + if (setup->target_window2) { + window = setup->target_window2; + val = PMBA(window->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, PCIMBA2REG); } + val = readl(RETVALREG); + val &= ~RTYVAL_MASK; + val |= RTYVAL(setup->retry_limit); + writel(val, RETVALREG); + + val = readl(PCIAPCNTREG); + val &= ~(TKYGNT | PAPC); + + switch (setup->arbiter_priority_control) { + case PCI_ARBITRATION_MODE_ALTERNATE_0: + val |= PAPC_ALTERNATE_0; + break; + case PCI_ARBITRATION_MODE_ALTERNATE_B: + val |= PAPC_ALTERNATE_B; + break; + default: + val |= PAPC_FAIR; + break; + } + + if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE) + val |= TKYGNT_ENABLE; + + writel(val, PCIAPCNTREG); + + writel(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR, COMMANDREG); + + /* Clear bus error */ + readl(BUSERRADREG); + writel(CONFIG_DONE, PCIENREG); - pciu_write_config_dword(PCI_COMMAND, - PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + + if (setup->mem_resource != NULL) + vr41xx_pci_controller.mem_resource = setup->mem_resource; + + if (setup->io_resource != NULL) { + vr41xx_pci_controller.io_resource = setup->io_resource; + } else { + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + } + + register_pci_controller(&vr41xx_pci_controller); + + return 0; } + +early_initcall(vr41xx_pciu_init); diff -Nru a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h --- a/arch/mips/pci/pci-vr41xx.h 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/pci/pci-vr41xx.h 2004-06-26 17:09:18 -07:00 @@ -1,164 +1,151 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/pciu.h + * pci-vr41xx.h, Include file for PCI Control Unit of the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * Include file for PCI Control Unit of the NEC VR4100 series. - * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com - * - * Copyright 2002 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* - * Changes: - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __VR41XX_PCIU_H -#define __VR41XX_PCIU_H - -#include -#include - -#define BIT(x) (1 << (x)) - -#define PCIMMAW1REG KSEG1ADDR(0x0f000c00) -#define PCIMMAW2REG KSEG1ADDR(0x0f000c04) -#define PCITAW1REG KSEG1ADDR(0x0f000c08) -#define PCITAW2REG KSEG1ADDR(0x0f000c0c) -#define PCIMIOAWREG KSEG1ADDR(0x0f000c10) -#define INTERNAL_BUS_BASE_ADDRESS 0xff000000 -#define ADDRESS_MASK 0x000fe000 -#define PCI_ACCESS_ENABLE BIT(12) -#define PCI_ADDRESS_SETTING 0x000000ff - -#define PCICONFDREG KSEG1ADDR(0x0f000c14) -#define PCICONFAREG KSEG1ADDR(0x0f000c18) -#define PCIMAILREG KSEG1ADDR(0x0f000c1c) - -#define BUSERRADREG KSEG1ADDR(0x0f000c24) -#define ERROR_ADDRESS 0xfffffffc - -#define INTCNTSTAREG KSEG1ADDR(0x0f000c28) -#define MABTCLR BIT(31) -#define TRDYCLR BIT(30) -#define PARCLR BIT(29) -#define MBCLR BIT(28) -#define SERRCLR BIT(27) - -#define PCIEXACCREG KSEG1ADDR(0x0f000c2c) -#define UNLOCK BIT(1) -#define EAREQ BIT(0) - -#define PCIRECONTREG KSEG1ADDR(0x0f000c30) -#define RTRYCNT 0x000000ff +#ifndef __PCI_VR41XX_H +#define __PCI_VR41XX_H -#define PCIENREG KSEG1ADDR(0x0f000c34) -#define CONFIG_DONE BIT(2) +#define PCIMMAW1REG KSEG1ADDR(0x0f000c00) +#define PCIMMAW2REG KSEG1ADDR(0x0f000c04) +#define PCITAW1REG KSEG1ADDR(0x0f000c08) +#define PCITAW2REG KSEG1ADDR(0x0f000c0c) +#define PCIMIOAWREG KSEG1ADDR(0x0f000c10) + #define IBA(addr) ((addr) & 0xff000000U) + #define MASTER_MSK(mask) (((mask) >> 11) & 0x000fe000U) + #define PCIA(addr) (((addr) >> 24) & 0x000000ffU) + #define TARGET_MSK(mask) (((mask) >> 8) & 0x000fe000U) + #define ITA(addr) (((addr) >> 24) & 0x000000ffU) + #define PCIIA(addr) (((addr) >> 24) & 0x000000ffU) + #define WINEN 0x1000U +#define PCICONFDREG KSEG1ADDR(0x0f000c14) +#define PCICONFAREG KSEG1ADDR(0x0f000c18) +#define PCIMAILREG KSEG1ADDR(0x0f000c1c) +#define BUSERRADREG KSEG1ADDR(0x0f000c24) + #define EA(reg) ((reg) &0xfffffffc) + +#define INTCNTSTAREG KSEG1ADDR(0x0f000c28) + #define MABTCLR 0x80000000U + #define TRDYCLR 0x40000000U + #define PARCLR 0x20000000U + #define MBCLR 0x10000000U + #define SERRCLR 0x08000000U + #define RTYCLR 0x04000000U + #define MABCLR 0x02000000U + #define TABCLR 0x01000000U + /* RFU */ + #define MABTMSK 0x00008000U + #define TRDYMSK 0x00004000U + #define PARMSK 0x00002000U + #define MBMSK 0x00001000U + #define SERRMSK 0x00000800U + #define RTYMSK 0x00000400U + #define MABMSK 0x00000200U + #define TABMSK 0x00000100U + #define IBAMABT 0x00000080U + #define TRDYRCH 0x00000040U + #define PAR 0x00000020U + #define MB 0x00000010U + #define PCISERR 0x00000008U + #define RTYRCH 0x00000004U + #define MABORT 0x00000002U + #define TABORT 0x00000001U + +#define PCIEXACCREG KSEG1ADDR(0x0f000c2c) + #define UNLOCK 0x2U + #define EAREQ 0x1U +#define PCIRECONTREG KSEG1ADDR(0x0f000c30) + #define RTRYCNT(reg) ((reg) & 0x000000ffU) +#define PCIENREG KSEG1ADDR(0x0f000c34) + #define CONFIG_DONE 0x4U +#define PCICLKSELREG KSEG1ADDR(0x0f000c38) + #define EQUAL_VTCLOCK 0x2U + #define HALF_VTCLOCK 0x0U + #define ONE_THIRD_VTCLOCK 0x3U + #define QUARTER_VTCLOCK 0x1U +#define PCITRDYVREG KSEG1ADDR(0x0f000c3c) + #define TRDYV(val) ((uint32_t)(val) & 0xffU) +#define PCICLKRUNREG KSEG1ADDR(0x0f000c60) + +#define VENDORIDREG KSEG1ADDR(0x0f000d00) +#define DEVICEIDREG KSEG1ADDR(0x0f000d00) +#define COMMANDREG KSEG1ADDR(0x0f000d04) +#define STATUSREG KSEG1ADDR(0x0f000d04) +#define REVIDREG KSEG1ADDR(0x0f000d08) +#define CLASSREG KSEG1ADDR(0x0f000d08) +#define CACHELSREG KSEG1ADDR(0x0f000d0c) +#define LATTIMEREG KSEG1ADDR(0x0f000d0c) + #define MLTIM(val) (((uint32_t)(val) << 7) & 0xff00U) +#define MAILBAREG KSEG1ADDR(0x0f000d10) +#define PCIMBA1REG KSEG1ADDR(0x0f000d14) +#define PCIMBA2REG KSEG1ADDR(0x0f000d18) + #define MBADD(base) ((base) & 0xfffff800U) + #define PMBA(base) ((base) & 0xffe00000U) + #define PREF 0x8U + #define PREF_APPROVAL 0x8U + #define PREF_DISAPPROVAL 0x0U + #define TYPE 0x6U + #define TYPE_32BITSPACE 0x0U + #define MSI 0x1U + #define MSI_MEMORY 0x0U +#define INTLINEREG KSEG1ADDR(0x0f000d3c) +#define INTPINREG KSEG1ADDR(0x0f000d3c) +#define RETVALREG KSEG1ADDR(0x0f000d40) +#define PCIAPCNTREG KSEG1ADDR(0x0f000d40) + #define TKYGNT 0x04000000U + #define TKYGNT_ENABLE 0x04000000U + #define TKYGNT_DISABLE 0x00000000U + #define PAPC 0x03000000U + #define PAPC_ALTERNATE_B 0x02000000U + #define PAPC_ALTERNATE_0 0x01000000U + #define PAPC_FAIR 0x00000000U + #define RTYVAL(val) (((uint32_t)(val) << 7) & 0xff00U) + #define RTYVAL_MASK 0xff00U -#define PCICLKSELREG KSEG1ADDR(0x0f000c38) -#define EQUAL_VTCLOCK 0x00000002 -#define HALF_VTCLOCK 0x00000000 -#define QUARTER_VTCLOCK 0x00000001 +#define PCI_CLOCK_MAX 33333333U -#define PCITRDYVREG KSEG1ADDR(0x0f000c3c) - -#define PCICLKRUNREG KSEG1ADDR(0x0f000c60) - -#define PCIU_CONFIGREGS_BASE KSEG1ADDR(0x0f000d00) -#define VENDORIDREG KSEG1ADDR(0x0f000d00) -#define DEVICEIDREG KSEG1ADDR(0x0f000d00) -#define COMMANDREG KSEG1ADDR(0x0f000d04) -#define STATUSREG KSEG1ADDR(0x0f000d04) -#define REVIDREG KSEG1ADDR(0x0f000d08) -#define CLASSREG KSEG1ADDR(0x0f000d08) -#define CACHELSREG KSEG1ADDR(0x0f000d0c) -#define LATTIMEREG KSEG1ADDR(0x0f000d0c) -#define MAILBAREG KSEG1ADDR(0x0f000d10) -#define PCIMBA1REG KSEG1ADDR(0x0f000d14) -#define PCIMBA2REG KSEG1ADDR(0x0f000d18) -#define INTLINEREG KSEG1ADDR(0x0f000d3c) -#define INTPINREG KSEG1ADDR(0x0f000d3c) -#define RETVALREG KSEG1ADDR(0x0f000d40) -#define PCIAPCNTREG KSEG1ADDR(0x0f000d40) - -#define MPCIINTREG KSEG1ADDR(0x0f0000b2) - -#define MAX_PCI_CLOCK 33333333 - -static inline int pciu_read_config_byte(int where, u8 * val) -{ - u32 data; - - data = readl(PCIU_CONFIGREGS_BASE + where); - *val = (u8) (data >> ((where & 3) << 3)); - - return PCIBIOS_SUCCESSFUL; -} - -static inline int pciu_read_config_word(int where, u16 * val) -{ - u32 data; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - data = readl(PCIU_CONFIGREGS_BASE + where); - *val = (u16) (data >> ((where & 2) << 3)); - - return PCIBIOS_SUCCESSFUL; -} - -static inline int pciu_read_config_dword(int where, u32 * val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - *val = readl(PCIU_CONFIGREGS_BASE + where); +/* + * Default setup + */ +#define PCI_MASTER_MEM1_BUS_BASE_ADDRESS 0x10000000U +#define PCI_MASTER_MEM1_ADDRESS_MASK 0x7c000000U +#define PCI_MASTER_MEM1_PCI_BASE_ADDRESS 0x10000000U - return PCIBIOS_SUCCESSFUL; -} +#define PCI_TARGET_MEM1_ADDRESS_MASK 0x08000000U +#define PCI_TARGET_MEM1_BUS_BASE_ADDRESS 0x00000000U -static inline int pciu_write_config_byte(int where, u8 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_MASTER_IO_BUS_BASE_ADDRESS 0x16000000U +#define PCI_MASTER_IO_ADDRESS_MASK 0x7e000000U +#define PCI_MASTER_IO_PCI_BASE_ADDRESS 0x00000000U - return 0; -} +#define PCI_MAILBOX_BASE_ADDRESS 0x00000000U -static inline int pciu_write_config_word(int where, u16 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_TARGET_WINDOW1_BASE_ADDRESS 0x00000000U - return 0; -} +#define IO_PORT_BASE KSEG1ADDR(PCI_MASTER_IO_BUS_BASE_ADDRESS) +#define IO_PORT_RESOURCE_START PCI_MASTER_IO_PCI_BASE_ADDRESS +#define IO_PORT_RESOURCE_END (~PCI_MASTER_IO_ADDRESS_MASK & PCI_MASTER_ADDRESS_MASK) -static inline int pciu_write_config_dword(int where, u32 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_IO_RESOURCE_START 0x01000000UL +#define PCI_IO_RESOURCE_END 0x01ffffffUL - return 0; -} +#define PCI_MEM_RESOURCE_START 0x11000000UL +#define PCI_MEM_RESOURCE_END 0x13ffffffUL -#endif /* __VR41XX_PCIU_H */ +#endif /* __PCI_VR41XX_H */ diff -Nru a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pci/pci-yosemite.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,37 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2004 by Ralf Baechle + * + */ +#include +#include +#include +#include +#include +#include + +extern struct pci_ops titan_pci_ops; + +static struct resource py_mem_resource = { + "Titan PCI MEM", 0xe0000000UL, 0xe3ffffffUL, IORESOURCE_MEM +}; + +static struct resource py_io_resource = { + "Titan IO MEM", 0x00000000UL, 0x00ffffffUL, IORESOURCE_IO, +}; + +static struct pci_controller py_controller = { + .pci_ops = &titan_pci_ops, + .mem_resource = &py_mem_resource, + .mem_offset = 0x10000000UL, + .io_resource = &py_io_resource, + .io_offset = 0x00000000UL +}; + +static int __init pmc_yosemite_setup(void) +{ + register_pci_controller(&py_controller); +} diff -Nru a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c --- a/arch/mips/pci/pci.c 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/pci/pci.c 2004-06-26 17:09:18 -07:00 @@ -231,7 +231,7 @@ { /* Update device resources. */ struct pci_controller *hose = (struct pci_controller *)bus->sysdata; - unsigned long offset; + unsigned long offset = 0; int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { diff -Nru a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile --- a/arch/mips/pmc-sierra/yosemite/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/pmc-sierra/yosemite/Makefile 2004-06-26 17:09:15 -07:00 @@ -1,8 +1,7 @@ # -# Makefile for the PMC-Sierra Titan +# Makefile for the PMC-Sierra Titan # -obj-y += irq-handler.o irq.o prom.o setup.o +obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_HYPERTRANSPORT) += ht-irq.o ht.o +obj-$(CONFIG_KGDB) += dbg_io.o diff -Nru a/arch/mips/pmc-sierra/yosemite/dbg_io.c b/arch/mips/pmc-sierra/yosemite/dbg_io.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pmc-sierra/yosemite/dbg_io.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,184 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Support for KGDB for the Yosemite board. We make use of single serial + * port to be used for KGDB as well as console. The second serial port + * seems to be having a problem. Single IRQ is allocated for both the + * ports. Hence, the interrupt routing code needs to figure out whether + * the interrupt came from channel A or B. + */ + +#include + +#if defined(CONFIG_KGDB) +#include + +/* + * Baud rate, Parity, Data and Stop bit settings for the + * serial port on the Yosemite. Note that the Early printk + * patch has been added. So, we should be all set to go + */ +#define YOSEMITE_BAUD_2400 2400 +#define YOSEMITE_BAUD_4800 4800 +#define YOSEMITE_BAUD_9600 9600 +#define YOSEMITE_BAUD_19200 19200 +#define YOSEMITE_BAUD_38400 38400 +#define YOSEMITE_BAUD_57600 57600 +#define YOSEMITE_BAUD_115200 115200 + +#define YOSEMITE_PARITY_NONE 0 +#define YOSEMITE_PARITY_ODD 0x08 +#define YOSEMITE_PARITY_EVEN 0x18 +#define YOSEMITE_PARITY_MARK 0x28 +#define YOSEMITE_PARITY_SPACE 0x38 + +#define YOSEMITE_DATA_5BIT 0x0 +#define YOSEMITE_DATA_6BIT 0x1 +#define YOSEMITE_DATA_7BIT 0x2 +#define YOSEMITE_DATA_8BIT 0x3 + +#define YOSEMITE_STOP_1BIT 0x0 +#define YOSEMITE_STOP_2BIT 0x4 + +/* This is crucial */ +#define SERIAL_REG_OFS 0x1 + +#define SERIAL_RCV_BUFFER 0x0 +#define SERIAL_TRANS_HOLD 0x0 +#define SERIAL_SEND_BUFFER 0x0 +#define SERIAL_INTR_ENABLE (1 * SERIAL_REG_OFS) +#define SERIAL_INTR_ID (2 * SERIAL_REG_OFS) +#define SERIAL_DATA_FORMAT (3 * SERIAL_REG_OFS) +#define SERIAL_LINE_CONTROL (3 * SERIAL_REG_OFS) +#define SERIAL_MODEM_CONTROL (4 * SERIAL_REG_OFS) +#define SERIAL_RS232_OUTPUT (4 * SERIAL_REG_OFS) +#define SERIAL_LINE_STATUS (5 * SERIAL_REG_OFS) +#define SERIAL_MODEM_STATUS (6 * SERIAL_REG_OFS) +#define SERIAL_RS232_INPUT (6 * SERIAL_REG_OFS) +#define SERIAL_SCRATCH_PAD (7 * SERIAL_REG_OFS) + +#define SERIAL_DIVISOR_LSB (0 * SERIAL_REG_OFS) +#define SERIAL_DIVISOR_MSB (1 * SERIAL_REG_OFS) + +/* + * Functions to READ and WRITE to serial port 0 + */ +#define SERIAL_READ(ofs) (*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE + ofs))) + +#define SERIAL_WRITE(ofs, val) ((*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE + ofs))) = val) + +/* + * Functions to READ and WRITE to serial port 1 + */ +#define SERIAL_READ_1(ofs) (*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE_1 + ofs) + +#define SERIAL_WRITE_1(ofs, val) ((*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE_1 + ofs))) = val) + +/* + * Second serial port initialization + */ +void init_second_port(void) +{ + /* Disable Interrupts */ + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0); + SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0); + + { + unsigned int divisor; + + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80); + divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200; + SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff); + + SERIAL_WRITE_1(SERIAL_DIVISOR_MSB, + (divisor & 0xff00) >> 8); + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0); + } + + SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT | + YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT); + + /* Enable Interrupts */ + SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf); +} + +/* Initialize the serial port for KGDB debugging */ +void debugInit(unsigned int baud, unsigned char data, unsigned char parity, + unsigned char stop) +{ + /* Disable Interrupts */ + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0); + SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0); + + { + unsigned int divisor; + + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80); + + divisor = TITAN_SERIAL_BASE_BAUD / baud; + SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff); + + SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8); + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0); + } + + SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +unsigned char getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(YOSEMITE_BAUD_115200, + YOSEMITE_DATA_8BIT, + YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT); + } + + while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0); + return SERIAL_READ(SERIAL_RCV_BUFFER); +} + +int putDebugChar(unsigned char byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(YOSEMITE_BAUD_115200, + YOSEMITE_DATA_8BIT, + YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT); + } + + while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0); + SERIAL_WRITE(SERIAL_SEND_BUFFER, byte); + + return 1; +} +#endif diff -Nru a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Detailed Description: + * + * This block implements the I2C interface to the slave devices like the + * Atmel 24C32 EEPROM and the MAX 1619 Sensors device. The I2C Master interface + * can be controlled by the SCMB block. And the SCMB block kicks in only when + * using the Ethernet Mode of operation and __not__ the SysAD mode + * + * The SCMB controls the two modes: MDIO and the I2C. The MDIO mode is used to + * communicate with the Quad-PHY from Marvel. The I2C is used to communicate + * with the I2C slave devices. It seems that the driver does not explicitly + * deal with the control of SDA and SCL serial lines. So, the driver will set + * the slave address, drive the command and then the data. The SCMB will then + * control the two serial lines as required. + * + * It seems the documents are very unclear abt this. Hence, I took some time + * out to write the desciption to have an idea of how the I2C can actually + * work. Currently, this Linux driver wont be integrated into the generic Linux + * I2C framework. And finally, the I2C interface is also known as the 2BI + * interface. 2BI means 2-bit interface referring to SDA and SCL serial lines + * respectively. + * + * - Manish Lachwani (12/09/2003) + */ + +#include "i2c-yosemite.h" + +/* + * Poll the I2C interface for the BUSY bit. + */ +static int titan_i2c_poll(void) +{ + int i = 0; + unsigned long val = 0; + + for (i = 0; i < TITAN_I2C_MAX_POLL; i++) { + val = TITAN_I2C_READ(TITAN_I2C_COMMAND); + + if (!(val & 0x8000)) + return 0; + } + + return TITAN_I2C_ERR_TIMEOUT; +} + +/* + * Execute the I2C command + */ +int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd, + int size, unsigned int *addr) +{ + int loop = 0, bytes, i; + unsigned int *write_data, data, *read_data; + unsigned long reg_val, val; + + write_data = cmd->data; + read_data = addr; + + TITAN_I2C_WRITE(TITAN_I2C_SLAVE_ADDRESS, slave_addr); + + if (cmd->type == TITAN_I2C_CMD_WRITE) + loop = cmd->write_size; + else + loop = size; + + while (loop > 0) { + if ((cmd->type == TITAN_I2C_CMD_WRITE) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE)) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; + ++i, write_data += 2, reg_val += 4) { + if (bytes < cmd->write_size) { + data = write_data[0]; + ++data; + } + + if (bytes < cmd->write_size) { + data = write_data[1]; + ++data; + } + + TITAN_I2C_WRITE(reg_val, data); + } + } + + TITAN_I2C_WRITE(TITAN_I2C_COMMAND, + (unsigned int) (cmd->type << 13)); + if (titan_i2c_poll() != TITAN_I2C_ERR_OK) + return TITAN_I2C_ERR_TIMEOUT; + + if ((cmd->type == TITAN_I2C_CMD_READ) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE)) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; + ++i, read_data += 2, reg_val += 4) { + data = TITAN_I2C_READ(reg_val); + + if (bytes < size) { + read_data[0] = data & 0xff; + ++bytes; + } + + if (bytes < size) { + read_data[1] = + ((data >> 8) & 0xff); + ++bytes; + } + } + } + + loop -= (TITAN_I2C_MAX_WORDS_PER_RW * 2); + } + + /* + * Read the Interrupt status and then return the appropriate error code + */ + + val = TITAN_I2C_READ(TITAN_I2C_INTERRUPTS); + if (val & 0x0020) + return TITAN_I2C_ERR_ARB_LOST; + + if (val & 0x0040) + return TITAN_I2C_ERR_NO_RESP; + + if (val & 0x0080) + return TITAN_I2C_ERR_DATA_COLLISION; + + return TITAN_I2C_ERR_OK; +} + +/* + * Init the I2C subsystem of the PMC-Sierra Yosemite board + */ +int titan_i2c_init(titan_i2c_config * config) +{ + unsigned int val; + + /* + * Reset the SCMB and program into the I2C mode + */ + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0xA000); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0x2000); + + /* + * Configure the filtera and clka values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_A); + val |= ((val & ~(0xF000)) | ((config->filtera << 12) & 0xF000)); + val |= ((val & ~(0x03FF)) | (config->clka & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_A, val); + + /* + * Configure the filterb and clkb values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_B); + val |= ((val & ~(0xF000)) | ((config->filterb << 12) & 0xF000)); + val |= ((val & ~(0x03FF)) | (config->clkb & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_B, val); + + return TITAN_I2C_ERR_OK; +} diff -Nru a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h --- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h 2004-06-26 17:09:15 -07:00 @@ -31,7 +31,7 @@ /* Read and Write operations to the chip */ #define TITAN_I2C_BASE 0xbb000000 /* XXX Needs to change */ - + #define TITAN_I2C_WRITE(offset, data) \ *(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data @@ -48,14 +48,14 @@ #define TITAN_I2C_MAX_POLL 100 /* Registers used for I2C work */ -#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */ -#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */ -#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */ -#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */ -#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */ +#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */ +#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */ +#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */ +#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */ +#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */ #define TITAN_I2C_SLAVE_ADDRESS 0x01A8 /* I2C Slave Address */ -#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */ -#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */ +#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */ +#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */ /* Error */ #define TITAN_I2C_ERR_ARB_LOST (-9220) @@ -66,31 +66,31 @@ /* I2C Command Type */ typedef enum { - TITAN_I2C_CMD_WRITE = 0, - TITAN_I2C_CMD_READ = 1, - TITAN_I2C_CMD_READ_WRITE = 2 + TITAN_I2C_CMD_WRITE = 0, + TITAN_I2C_CMD_READ = 1, + TITAN_I2C_CMD_READ_WRITE = 2 } titan_i2c_cmd_type; /* I2C structures */ typedef struct { - int filtera; /* Register 0x0184, bits 15 - 12*/ - int clka; /* Register 0x0184, bits 9 - 0 */ - int filterb; /* Register 0x0188, bits 15 - 12 */ - int clkb; /* Register 0x0188, bits 9 - 0 */ + int filtera; /* Register 0x0184, bits 15 - 12 */ + int clka; /* Register 0x0184, bits 9 - 0 */ + int filterb; /* Register 0x0188, bits 15 - 12 */ + int clkb; /* Register 0x0188, bits 9 - 0 */ } titan_i2c_config; /* I2C command type */ typedef struct { - titan_i2c_cmd_type type; /* Type of command */ - int num_arb; /* Register 0x01a0, bits 15 - 12 */ - int num_nak; /* Register 0x01a0, bits 11 - 8 */ - int addr_size; /* Register 0x01a0, bit 7 */ - int mst_code; /* Register 0x01a0, bits 6 - 4 */ - int arb_en; /* Register 0x01a0, bit 1 */ - int speed; /* Register 0x01a0, bit 0 */ - int slave_addr; /* Register 0x01a8 */ - int write_size; /* Register 0x01a4, bits 10 - 8 */ - unsigned int *data; /* Register 0x01ac */ + titan_i2c_cmd_type type; /* Type of command */ + int num_arb; /* Register 0x01a0, bits 15 - 12 */ + int num_nak; /* Register 0x01a0, bits 11 - 8 */ + int addr_size; /* Register 0x01a0, bit 7 */ + int mst_code; /* Register 0x01a0, bits 6 - 4 */ + int arb_en; /* Register 0x01a0, bit 1 */ + int speed; /* Register 0x01a0, bit 0 */ + int slave_addr; /* Register 0x01a8 */ + int write_size; /* Register 0x01a4, bits 10 - 8 */ + unsigned int *data; /* Register 0x01ac */ } titan_i2c_command; -#endif /* __I2C_YOSEMITE_H */ +#endif /* __I2C_YOSEMITE_H */ diff -Nru a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S --- a/arch/mips/pmc-sierra/yosemite/irq-handler.S 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/pmc-sierra/yosemite/irq-handler.S 2004-06-26 17:09:20 -07:00 @@ -8,6 +8,10 @@ * 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. + * + * Titan supports Hypertransport or PCI but not both. Hence, one interrupt + * line is shared between the PCI slot A and Hypertransport. This is the + * Processor INTB #0. */ #include @@ -17,109 +21,90 @@ #include #include -/* - * IRQ router for the Titan board - */ - .align 5 NESTED(titan_handle_int, PT_SIZE, sp) SAVE_ALL CLI .set at + .set noreorder mfc0 t0, CP0_CAUSE mfc0 t2, CP0_STATUS and t0, t2 - - andi t1, t0, STATUSF_IP0 /* INTB0 hardware line */ + + andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */ bnez t1, ll_pcia_irq /* 64-bit PCI */ - andi t1, t0, STATUSF_IP1 /* INTB1 hardware line */ + andi t1, t0, STATUSF_IP3 /* INTB1 hardware line */ bnez t1, ll_pcib_irq /* second 64-bit PCI slot */ - andi t1, t0, STATUSF_IP2 /* INTB2 hardware line */ + andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */ bnez t1, ll_duart_irq /* UART */ - andi t1, t0, STATUSF_IP3 /* INTB3 hardware line*/ - bnez t1, ll_ht_smp_irq /* Hypertransport */ - andi t1, t0, STATUSF_IP5 /* INTB5 hardware line */ + andi t1, t0, STATUSF_IP5 /* SMP inter-core interrupts */ + bnez t1, ll_smp_irq + andi t1, t0, STATUSF_IP6 + bnez t1, ll_ht_irq /* Hypertransport */ + andi t1, t0, STATUSF_IP7 /* INTB5 hardware line */ bnez t1, ll_timer_irq /* Timer */ nop nop /* Extended interrupts */ - mfc0 t0, CPU_CAUSE - cfc0 t1, CP0_S1_INTCONTROL + mfc0 t0, CP0_CAUSE + cfc0 t1, CP0_S1_INTCONTROL - sll t2, t1, 8 - - and t0, t2 - srl t0, t0, 16 - - - andi t1, t0, STATUSF_IP6 /* INTB6 hardware line */ - bnez t1, ll_phy0_irq /* Ethernet port 0 */ - andi t1, t0, STATUSF_IP7 /* INTB7 hardware line */ - bnez t1, ll_phy1_irq /* Ethernet port 1 */ - andi t1, t0, STATUSF_IP8 /* INTB8 hardware line */ - bnez t1, ll_phy2_irq /* Ethernet Port 2 */ + sll t2, t1, 8 - nop - nop + and t0, t2 + srl t0, t0, 16 .set reorder - /* No handler */ j spurious_interrupt nop END(titan_handle_int) .align 5 -/* Individual Handlers */ - ll_pcia_irq: - li a0, 1 - move a2, sp + li a0, 2 + move a1, sp +#ifdef CONFIG_HYPERTRANSPORT + jal ll_ht_smp_irq_handler +#else jal do_IRQ +#endif j ret_from_irq ll_pcib_irq: - li a0, 2 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_duart_irq: li a0, 3 move a1, sp jal do_IRQ j ret_from_irq -ll_ht_irq: +ll_duart_irq: li a0, 4 move a1, sp - jal ll_ht_smp_irq_handler /* Detailed HT & SMP IRQ handling */ + jal do_IRQ j ret_from_irq -ll_timer_irq: +ll_smp_irq: li a0, 5 move a1, sp +#ifdef CONFIG_SMP + jal jaguar_mailbox_irq +#else jal do_IRQ +#endif j ret_from_irq -ll_phy0_irq: +ll_ht_irq: li a0, 6 move a1, sp - jal do_IRQ - j ret_from_irq - -ll_phy1_irq: - li a0, 7 - move a1, sp - jal do_IRQ + jal ll_ht_smp_irq_handler j ret_from_irq -ll_phy2_irq: - li a0, 8 +ll_timer_irq: + li a0, 7 move a1, sp jal do_IRQ j ret_from_irq diff -Nru a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c --- a/arch/mips/pmc-sierra/yosemite/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/pmc-sierra/yosemite/irq.c 2004-06-26 17:09:20 -07:00 @@ -41,207 +41,116 @@ #include #include #include +#include #include #include +#include /* Hypertransport specific */ -#define IRQ_STATUS_REG_CPU0 0xbb001b30 /* INT# 3 status register on CPU 0*/ -#define IRQ_STATUS_REG_CPU1 0xbb002b30 /* INT# 3 status register on CPU 1*/ -#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ -#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 0*/ -#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 1*/ - -#define HYPERTRANSPORT_EOI 0xbb0006E0 /* End of Interrupt */ -#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ -#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ -#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ -#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ - -#define read_32bit_cp0_set1_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "cfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) - -#define write_32bit_cp0_set1_register(register,value) \ - __asm__ __volatile__( \ - "ctc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); +#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ -static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; - -/* Function for careful CP0 interrupt mask access */ -static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) -{ - unsigned long status; - unsigned clr_mask; - unsigned set_mask; - - /* do the low 8 bits first */ - clr_mask = 0xff & clr_mask_in; - set_mask = 0xff & set_mask_in; - status = read_c0_status(); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8 | 0x0000FF00; - write_c0_status(status); - - /* do the high 8 bits */ - clr_mask = 0xff & (clr_mask_in >> 8); - set_mask = 0xff & (set_mask_in >> 8); - status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); -} - -static inline void mask_irq(unsigned int irq) -{ - modify_cp0_intmask(irq, 0); -} - -static inline void unmask_irq(unsigned int irq) -{ - modify_cp0_intmask(0, irq); -} - -static void enable_rm9000_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - unmask_irq(1 << (irq-1)); - spin_unlock_irqrestore(&irq_lock, flags); -} - -static unsigned int startup_rm9000_irq(unsigned int irq) -{ - enable_rm9000_irq(irq); - - return 0; /* never anything pending */ -} - -static void disable_rm9000_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - mask_irq(1 << (irq-1)); - spin_unlock_irqrestore(&irq_lock, flags); -} - -#define shutdown_rm9000_irq disable_rm9000_irq - -static void mask_and_ack_rm9000_irq(unsigned int irq) -{ - mask_irq(1 << (irq-1)); -} - -static void end_rm9000_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_irq(1 << (irq-1)); -} - -static struct hw_interrupt_type rm9000_hpcdma_irq_type = { - "RM9000", - startup_rm9000_irq, - shutdown_rm9000_irq, - enable_rm9000_irq, - disable_rm9000_irq, - mask_and_ack_rm9000_irq, - end_rm9000_irq, - NULL -}; +#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ +#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ +#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ +#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ extern asmlinkage void titan_handle_int(void); extern void jaguar_mailbox_irq(struct pt_regs *); /* - * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. For interprocessor - * interrupts, the best thing to do is to use the INTMSG register. We use the same external - * interrupt line, i.e. INTB3 and monitor another status bit + * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. + * For interprocessor interrupts, the best thing to do is to use the INTMSG + * register. We use the same external interrupt line, i.e. INTB3 and monitor + * another status bit */ asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs) { - u32 status; - status = *(volatile uint32_t *)(IRQ_STATUS_REG_CPU0); + u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4); /* Ack all the bits that correspond to the interrupt sources */ if (status != 0) - *(volatile uint32_t *)(IRQ_STATUS_REG_CPU0) = IRQ_ACK_BITS; + OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS); - status = *(volatile uint32_t *)(IRQ_STATUS_REG_CPU1); + status = OCD_READ(RM9000x2_OCD_INTP1STATUS4); if (status != 0) - *(volatile uint32_t *)(IRQ_STATUS_REG_CPU1) = IRQ_ACK_BITS; + OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS); -#ifdef CONFIG_SMP - if (status == 0x2) { - /* This is an SMP IPI sent from one core to another */ - jaguar_mailbox_irq(regs); - goto done; - } -#endif - #ifdef CONFIG_HT_LEVEL_TRIGGER - /* - * Level Trigger Mode only. Send the HT EOI message back to the source. - */ - switch (status) { - case 0x1000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; - break; - case 0x2000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; - break; - case 0x4000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; - break; - case 0x8000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; - break; - case 0x0000001: - /* PLX */ - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = 0x20; - *(volatile uint32_t *)(IRQ_CLEAR_REG) = IRQ_ACK_BITS; - break; - case 0xf000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; - break; - } + /* + * Level Trigger Mode only. Send the HT EOI message back to the source. + */ + switch (status) { + case 0x1000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); + break; + case 0x2000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); + break; + case 0x4000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); + break; + case 0x8000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); + break; + case 0x0000001: + /* PLX */ + OCD_WRITE(RM9000x2_OCD_HTEOI, 0x20); + OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS); + break; + case 0xf000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); + break; + } #endif /* CONFIG_HT_LEVEL_TRIGGER */ -done: - if (status != 0x2) - /* Not for SMP */ - do_IRQ(irq, regs); + do_IRQ(irq, regs); } +#ifdef CONFIG_KGDB +extern void init_second_port(void); +extern void breakpoint(void); +extern void set_debug_traps(void); +#endif + /* * Initialize the next level interrupt handler */ void __init init_IRQ(void) { - int i; - - clear_c0_status(ST0_IM | ST0_BEV); - __cli(); + clear_c0_status(ST0_IM); set_except_vector(0, titan_handle_int); init_generic_irq(); + mips_cpu_irq_init(0); + rm7k_cpu_irq_init(8); - for (i = 0; i < 13; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].handler = &rm9000_hpcdma_irq_type; - } +#ifdef CONFIG_KGDB + /* At this point, initialize the second serial port */ + init_second_port(); + printk("Start kgdb ... \n"); + set_debug_traps(); + breakpoint(); +#endif + +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif } +#ifdef CONFIG_KGDB +/* + * The 16550 DUART has two ports, but is allocated one IRQ + * for the serial console. Hence, a generic framework for + * serial IRQ routing in place. Currently, just calls the + * do_IRQ fuction. But, going in the future, need to check + * DUART registers for channel A and B, then decide the + * appropriate action + */ +asmlinkage void yosemite_kgdb_irq(int irq, struct pt_regs *regs) +{ + do_IRQ(irq, regs); +} +#endif diff -Nru a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c --- a/arch/mips/pmc-sierra/yosemite/prom.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/pmc-sierra/yosemite/prom.c 2004-06-26 17:09:20 -07:00 @@ -7,55 +7,44 @@ * Copyright (C) 2003 PMC-Sierra Inc. * Author: Manish Lachwani (lachwani@pmc-sierra.com) */ - +#include #include #include +#include +#include + #include #include #include #include #include -#include -#include #include +#include #include "setup.h" -/* Call Vectors */ -struct callvectors { - int (*open) (char*, int, int); - int (*close) (int); - int (*read) (int, void*, int); - int (*write) (int, void*, int); - off_t (*lseek) (int, off_t, int); - int (*printf) (const char*, ...); - void (*cacheflush) (void); - char* (*gets) (char*); -}; - -struct callvectors* debug_vectors; +struct callvectors *debug_vectors; extern unsigned long yosemite_base; extern unsigned long cpu_clock; -unsigned char titan_ge_mac_addr_base[6]; const char *get_system_type(void) { - return "PMC-Sierra Yosemite"; + return "PMC-Sierra Yosemite"; } -static void prom_cpu0_exit(void) +static void prom_cpu0_exit(void *arg) { - void *nvram = YOSEMITE_NVRAM_BASE_ADDR; - + void *nvram = (void *) YOSEMITE_NVRAM_BASE_ADDR; + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ - writeb(0x84, nvram + 0xff7); + writeb(0x84, nvram + 0xff7); - /* wait for the watchdog to go off */ - mdelay(100+(1000/16)); + /* wait for the watchdog to go off */ + mdelay(100 + (1000 / 16)); - /* if the watchdog fails for some reason, let people know */ - printk(KERN_NOTICE "Watchdog reset failed\n"); + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); } /* @@ -68,78 +57,73 @@ /* CPU 1 */ smp_call_function(prom_cpu0_exit, NULL, 1, 1); #endif - prom_cpu0_exit; -} - -/* - * Get the MAC address from the EEPROM using the I2C protocol - */ -void get_mac_address(char dest[6]) -{ - /* Use the I2C command code in the i2c-yosemite */ + prom_cpu0_exit(NULL); } /* - * Halt the system + * Halt the system */ static void prom_halt(void) { printk(KERN_NOTICE "\n** You can safely turn off the power\n"); while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); + __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); } /* * Init routine which accepts the variables from PMON */ -__init prom_init(int argc, char **arg, char **env, struct callvectors *cv) +void __init prom_init(void) { - int i = 0; + int argc = fw_arg0; + char **arg = (char **) fw_arg1; + char **env = (char **) fw_arg2; + struct callvectors *cv = (struct callvectors *) fw_arg3; + int i = 0; /* Callbacks for halt, restart */ - _machine_restart = (void (*)(char *))prom_exit; + _machine_restart = (void (*)(char *)) prom_exit; _machine_halt = prom_halt; _machine_power_off = prom_halt; -#ifdef CONFIG_MIPS64 - - /* Do nothing for the 64-bit for now. Just implement for the 32-bit */ - -#else /* CONFIG_MIPS64 */ +#ifdef CONFIG_MIPS32 debug_vectors = cv; arcs_cmdline[0] = '\0'; /* Get the boot parameters */ for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline)) - break; + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= + sizeof(arcs_cmdline)) + break; strcat(arcs_cmdline, arg[i]); strcat(arcs_cmdline, " "); } while (*env) { - if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) - yosemite_base = simple_strtol(*env + strlen("ocd_base="), - NULL, 16); - - if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) - cpu_clock = simple_strtol(*env + strlen("cpuclock="), - NULL, 10); - + if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) + yosemite_base = + simple_strtol(*env + strlen("ocd_base="), NULL, + 16); + + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) + cpu_clock = + simple_strtol(*env + strlen("cpuclock="), NULL, + 10); + env++; } +#endif /* CONFIG_MIPS32 */ + +#ifdef CONFIG_MIPS64 + + /* Do nothing for the 64-bit for now. Just implement for the 32-bit */ + #endif /* CONFIG_MIPS64 */ mips_machgroup = MACH_GROUP_TITAN; mips_machtype = MACH_TITAN_YOSEMITE; - - get_mac_address(titan_ge_mac_addr_base); - - debug_vectors->printf("Booting Linux kernel...\n"); } void __init prom_free_prom_memory(void) @@ -149,41 +133,3 @@ void __init prom_fixup_mem_map(unsigned long start, unsigned long end) { } - -extern void asmlinkage smp_bootstrap(void); - -/* - * SMP support - */ -int prom_setup_smp(void) -{ - int num_cpus = 2; - - /* - * We know that the RM9000 on the Jaguar ATX board has 2 cores. Hence, this - * can be hardcoded for now. - */ - return num_cpus; -} - -int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) -{ - /* Clear the semaphore */ - *(volatile uint32_t *)(0xbb000a68) = 0x80000000; - - return 1; -} - -void prom_init_secondary(void) -{ - clear_c0_config(CONF_CM_CMASK); - set_c0_config(0x2); - - clear_c0_status(ST0_IM); - set_c0_status(0x1ffff); -} - -void prom_smp_finish(void) -{ -} - diff -Nru a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/pmc-sierra/yosemite/py-console.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,130 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001, 2002, 2004 Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* SUPERIO uart register map */ +struct yo_uartregs { + union { + volatile u8 rbr; /* read only, DLAB == 0 */ + volatile u8 thr; /* write only, DLAB == 0 */ + volatile u8 dll; /* DLAB == 1 */ + } u1; + union { + volatile u8 ier; /* DLAB == 0 */ + volatile u8 dlm; /* DLAB == 1 */ + } u2; + union { + volatile u8 iir; /* read only */ + volatile u8 fcr; /* write only */ + } u3; + volatile u8 iu_lcr; + volatile u8 iu_mcr; + volatile u8 iu_lsr; + volatile u8 iu_msr; + volatile u8 iu_scr; +} yo_uregs_t; + +#define iu_rbr u1.rbr +#define iu_thr u1.thr +#define iu_dll u1.dll +#define iu_ier u2.ier +#define iu_dlm u2.dlm +#define iu_iir u3.iir +#define iu_fcr u3.fcr + +extern unsigned long uart_base; + +#define IO_BASE_64 0x9000000000000000ULL + +static unsigned char readb_outer_space(unsigned long phys) +{ + unsigned long long vaddr = IO_BASE_64 | phys; + unsigned char res; + unsigned int sr; + + sr = read_c0_status(); + write_c0_status((sr | ST0_KX) & ~ ST0_IE); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + __asm__ __volatile__ ( + " .set mips3 \n" + " ld %0, (%0) \n" + " lbu %0, (%0) \n" + " .set mips0 \n" + : "=r" (res) + : "0" (&vaddr)); + + write_c0_status(sr); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + return res; +} + +static void writeb_outer_space(unsigned long phys, unsigned char c) +{ + unsigned long long vaddr = IO_BASE_64 | phys; + unsigned long tmp; + unsigned int sr; + + sr = read_c0_status(); + write_c0_status((sr | ST0_KX) & ~ ST0_IE); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + __asm__ __volatile__ ( + " .set mips3 \n" + " ld %0, (%1) \n" + " sb %2, (%0) \n" + " .set mips0 \n" + : "=r" (tmp) + : "r" (&vaddr), "r" (c)); + + write_c0_status(sr); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); +} + +static inline struct yo_uartregs *console_uart(void) +{ + return (struct yo_uartregs *) (uart_base + 8); +} + +void prom_putchar(char c) +{ + unsigned long lsr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_lsr); + unsigned long thr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_thr); + + while ((readb_outer_space(lsr) & 0x20) == 0); + writeb_outer_space(thr, c); +} + +char __init prom_getchar(void) +{ + return 0; +} diff -Nru a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c --- a/arch/mips/pmc-sierra/yosemite/setup.c 2004-06-26 17:09:14 -07:00 +++ b/arch/mips/pmc-sierra/yosemite/setup.c 2004-06-26 17:09:14 -07:00 @@ -1,6 +1,4 @@ /* - * arch/mips/pmc-sierra/yosemite/setup.c - * * Copyright (C) 2003 PMC-Sierra Inc. * Author: Manish Lachwani (lachwani@pmc-sierra.com) * @@ -24,19 +22,18 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include #include #include #include -#include #include +#include #include #include #include #include -#include #include -#include + #include #include #include @@ -46,36 +43,46 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include "setup.h" +unsigned char titan_ge_mac_addr_base[6] = { + 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 +}; + unsigned long cpu_clock; unsigned long yosemite_base; -void __init bus_error_init(void) -{ - /* Do nothing */ +void __init bus_error_init(void) +{ + /* Do nothing */ } unsigned long m48t37y_get_time(void) { - unsigned char *rtc_base = YOSEMITE_RTC_BASE; - unsigned int year, month, day, hour, min, sec; + //unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; + unsigned char *rtc_base = (unsigned char *) 0xfc000000UL; + unsigned int year, month, day, hour, min, sec; +return; /* Stop the update to the time */ rtc_base[0x7ff8] = 0x40; - year = CONV_BCD_TO_BIN(rtc_base[0x7fff]); - year += CONV_BCD_TO_BIN(rtc_base[0x7fff1]) * 100; + year = BCD2BIN(rtc_base[0x7fff]); + year += BCD2BIN(rtc_base[0x7fff1]) * 100; - month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]); - day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]); - hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]); - min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]); - sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]); + month = BCD2BIN(rtc_base[0x7ffe]); + day = BCD2BIN(rtc_base[0x7ffd]); + hour = BCD2BIN(rtc_base[0x7ffb]); + min = BCD2BIN(rtc_base[0x7ffa]); + sec = BCD2BIN(rtc_base[0x7ff9]); /* Start the update to the time again */ rtc_base[0x7ff8] = 0x00; @@ -85,83 +92,119 @@ int m48t37y_set_time(unsigned long sec) { - unsigned char *rtc_base = YOSEMITE_RTC_BASE; - unsigned int year, month, day, hour, min, sec; - - struct rtc_time tm; + unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; + struct rtc_time tm; +return; - /* convert to a more useful format -- note months count from 0 */ - to_tm(sec, &tm); - tm.tm_mon += 1; + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; - /* enable writing */ - rtc_base[0x7ff8] = 0x80; + /* enable writing */ + rtc_base[0x7ff8] = 0x80; - /* year */ - rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100); - rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100); + /* year */ + rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); - /* month */ - rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon); + /* month */ + rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); - /* day */ - rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday); + /* day */ + rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); - /* hour/min/sec */ - rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour); - rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min); - rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec); + /* hour/min/sec */ + rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); + rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); + rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); - /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1); + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); - /* disable writing */ - rtc_base[0x7ff8] = 0x00; + /* disable writing */ + rtc_base[0x7ff8] = 0x00; - return 0; + return 0; } void yosemite_timer_setup(struct irqaction *irq) { - setup_irq(6, irq); + setup_irq(7, irq); } void yosemite_time_init(void) { - mips_counter_frequency = cpu_clock / 2; board_timer_setup = yosemite_timer_setup; + mips_hpt_frequency = cpu_clock / 2; rtc_get_time = m48t37y_get_time; rtc_set_time = m48t37y_set_time; } +unsigned long uart_base = 0xfd000000L; + +/* No other usable initialization hook than this ... */ +extern void (*late_time_init)(void); + +unsigned long ocd_base; + +EXPORT_SYMBOL(ocd_base); + +/* + * Common setup before any secondaries are started + */ + +#define TITAN_UART_CLK 3686400 +#define TITAN_SERIAL_BASE_BAUD (TITAN_UART_CLK / 16) +#define TITAN_SERIAL_IRQ 4 +#define TITAN_SERIAL_BASE 0xfd000008UL + +static void __init py_map_ocd(void) +{ + struct uart_port up; + + /* + * Not specifically interrupt stuff but in case of SMP core_send_ipi + * needs this first so I'm mapping it here ... + */ + ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE); + if (!ocd_base) + panic("Mapping OCD failed - game over. Your score is 0."); + + /* + * Register to interrupt zero because we share the interrupt with + * the serial driver which we don't properly support yet. + */ + memset(&up, 0, sizeof(up)); + up.membase = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8); + up.irq = TITAN_SERIAL_IRQ; + up.uartclk = TITAN_UART_CLK; + up.regshift = 0; + up.iotype = UPIO_MEM; + up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + up.line = 0; + + if (early_serial_setup(&up)) + printk(KERN_ERR "Early serial init of port 0 failed\n"); +} + static int __init pmc_yosemite_setup(void) { - unsigned long val = 0; + extern void pmon_smp_bootstrap(void); - printk("PMC-Sierra Yosemite Board Setup \n"); board_time_init = yosemite_time_init; + late_time_init = py_map_ocd; /* Add memory regions */ add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); - add_memory_region(0x10000000, 0x10000000, BOOT_MEM_RAM); - - /* Setup the HT controller */ - val = *(volatile uint32_t *)(HYPERTRANSPORT_CONFIG_REG); - val |= HYPERTRANSPORT_ENABLE; - *(volatile uint32_t *)(HYPERTRANSPORT_CONFIG_REG) = val; - - /* Set the BAR. Shifted mode */ - *(volatile uint32_t *)(HYPERTRANSPORT_BAR0_REG) = HYPERTRANSPORT_BAR0_ADDR; - *(volatile uint32_t *)(HYPERTRANSPORT_SIZE0_REG) = HYPERTRANSPORT_SIZE0; - -#ifdef CONFIG_PCI - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; - pci_scan_bus(0, &titan_pci_ops, NULL); +#if 0 /* XXX Crash ... */ + OCD_WRITE(RM9000x2_OCD_HTSC, + OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE); + + /* Set the BAR. Shifted mode */ + OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR); + OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0); #endif return 0; diff -Nru a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h --- a/arch/mips/pmc-sierra/yosemite/setup.h 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/pmc-sierra/yosemite/setup.h 2004-06-26 17:09:17 -07:00 @@ -9,27 +9,13 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ - #ifndef __SETUP_H__ #define __SETUP_H__ -/* Real Time Clock base */ -#define YOSEMITE_RTC_BASE -#define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) -#define CONV_BIN_TO_BCD(val) (((val) % 10) + (((val) / 10) << 4)) - /* NVRAM Base */ #define YOSEMITE_NVRAM_BASE_ADDR 0xbb000678 /* XXX Need change */ #define YOSEMITE_RTC_BASE 0xbb000679 /* XXX Need change */ -/* - * Hypertransport Specific - */ -#define HYPERTRANSPORT_CONFIG_REG 0xbb000604 -#define HYPERTRANSPORT_BAR0_REG 0xbb000610 -#define HYPERTRANSPORT_SIZE0_REG 0xbb000688 -#define HYPERTRANSPORT_BAR0_ATTR_REG 0xbb000680 - #define HYPERTRANSPORT_BAR0_ADDR 0x00000006 #define HYPERTRANSPORT_SIZE0 0x0fffffff #define HYPERTRANSPORT_BAR0_ATTR 0x00002000 @@ -37,11 +23,9 @@ #define HYPERTRANSPORT_ENABLE 0x6 /* - * EEPROM Size + * EEPROM Size */ #define TITAN_ATMEL_24C32_SIZE 32768 #define TITAN_ATMEL_24C64_SIZE 65536 - #endif /* __SETUP_H__ */ - diff -Nru a/arch/mips/ramdisk/Makefile b/arch/mips/ramdisk/Makefile --- a/arch/mips/ramdisk/Makefile 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/ramdisk/Makefile 2004-06-26 17:09:19 -07:00 @@ -12,7 +12,7 @@ quiet_cmd_ramdisk = LD $@ define cmd_ramdisk - $(LD) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) + $(LD) $(LDFLAGS) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) endef $(obj)/ramdisk.o: $(img) $(src)/ld.script diff -Nru a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c --- a/arch/mips/sgi-ip22/ip22-setup.c 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/sgi-ip22/ip22-setup.c 2004-06-26 17:09:15 -07:00 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,8 @@ printk("\n"); ArcEnterInteractiveMode(); } + +EXPORT_SYMBOL(ip22_do_break); extern void ip22_be_init(void) __init; extern void ip22_time_init(void) __init; diff -Nru a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c --- a/arch/mips/sgi-ip32/ip32-irq.c 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/sgi-ip32/ip32-irq.c 2004-06-26 17:09:18 -07:00 @@ -123,9 +123,9 @@ struct pt_regs *regs); struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, - 0, "CRIME memory error", NULL, NULL }; + CPU_MASK_NONE, "CRIME memory error", NULL, NULL }; struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, - 0, "CRIME CPU error", NULL, NULL }; + CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; extern void ip32_handle_int(void); diff -Nru a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c --- a/arch/mips/sibyte/sb1250/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/sibyte/sb1250/irq.c 2004-06-26 17:09:20 -07:00 @@ -279,7 +279,7 @@ static struct irqaction sb1250_dummy_action = { .handler = sb1250_dummy_handler, .flags = 0, - .mask = 0, + .mask = CPU_MASK_NONE, .name = "sb1250-private", .next = NULL, .dev_id = 0 diff -Nru a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c --- a/arch/mips/tx4927/common/tx4927_irq.c 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/tx4927/common/tx4927_irq.c 2004-06-26 17:09:21 -07:00 @@ -172,7 +172,7 @@ .set_affinity = NULL }; -#define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +#define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } static struct irqaction tx4927_irq_pic_action = TX4927_PIC_ACTION(TX4927_PIC_NAME); diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 2004-06-26 17:09:17 -07:00 @@ -337,8 +337,8 @@ return (sw_irq); } -//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } -#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, 0, s, NULL, NULL } +//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } +#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, CPU_MASK_NONE, s, NULL, NULL } static struct irqaction toshiba_rbtx4927_irq_ioc_action = TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME); #ifdef CONFIG_TOSHIBA_FPCIB0 diff -Nru a/arch/mips/vr4181/common/irq.c b/arch/mips/vr4181/common/irq.c --- a/arch/mips/vr4181/common/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/vr4181/common/irq.c 2004-06-26 17:09:20 -07:00 @@ -180,9 +180,9 @@ extern void mips_cpu_irq_init(u32 irq_base); static struct irqaction cascade = - { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; + { no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL }; static struct irqaction reserved = - { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; + { no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL }; void __init init_IRQ(void) { diff -Nru a/arch/mips/vr41xx/common/bcu.c b/arch/mips/vr41xx/common/bcu.c --- a/arch/mips/vr41xx/common/bcu.c 2004-06-26 17:09:20 -07:00 +++ b/arch/mips/vr41xx/common/bcu.c 2004-06-26 17:09:20 -07:00 @@ -1,34 +1,23 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/bcu.c + * bcu.c, Bus Control Unit routines for the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * Bus Control Unit routines for the NEC VR4100 series. - * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com - * - * Copyright 2002 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Changes: @@ -40,12 +29,16 @@ * - Added support for NEC VR4133. */ #include +#include #include #include #include #include +#define IO_MEM_RESOURCE_START 0UL +#define IO_MEM_RESOURCE_END 0x1fffffffUL + #define CLKSPEEDREG_TYPE1 KSEG1ADDR(0x0b000014) #define CLKSPEEDREG_TYPE2 KSEG1ADDR(0x0f000014) #define CLKSP(x) ((x) & 0x001f) @@ -213,7 +206,7 @@ return tclock; } -void __init vr41xx_bcu_init(void) +static int __init vr41xx_bcu_init(void) { unsigned long pclock; uint16_t clkspeed; @@ -223,4 +216,11 @@ pclock = calculate_pclock(clkspeed); vr41xx_vtclock = calculate_vtclock(clkspeed, pclock); vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock); + + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + + return 0; } + +early_initcall(vr41xx_bcu_init); diff -Nru a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c --- a/arch/mips/vr41xx/common/cmu.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/vr41xx/common/cmu.c 2004-06-26 17:09:17 -07:00 @@ -200,7 +200,7 @@ spin_unlock_irq(&cmu_lock); } -void __init vr41xx_cmu_init(void) +static int __init vr41xx_cmu_init(void) { switch (current_cpu_data.cputype) { case CPU_VR4111: @@ -223,4 +223,8 @@ cmuclkmsk = read_cmuclkmsk(); spin_lock_init(&cmu_lock); + + return 0; } + +early_initcall(vr41xx_cmu_init); diff -Nru a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c --- a/arch/mips/vr41xx/common/giu.c 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/vr41xx/common/giu.c 2004-06-26 17:09:15 -07:00 @@ -28,10 +28,12 @@ * - Added support for NEC VR4133. * - Removed board_irq_init. */ +#include #include #include #include #include +#include #include #include @@ -64,6 +66,8 @@ #define read_giuint(offset) readw(giu_base + (offset)) #define write_giuint(val, offset) writew((val), giu_base + (offset)) +#define GIUINT_HIGH_OFFSET 16 + static inline uint16_t set_giuint(uint8_t offset, uint16_t set) { uint16_t res; @@ -86,35 +90,121 @@ return res; } -void vr41xx_enable_giuint(int pin) +static unsigned int startup_giuint_low_irq(unsigned int irq) { - if (pin < 16) - set_giuint(GIUINTENL, (uint16_t)1 << pin); - else - set_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); + set_giuint(GIUINTENL, (uint16_t)1 << pin); + + return 0; } -void vr41xx_disable_giuint(int pin) +static void shutdown_giuint_low_irq(unsigned int irq) { - if (pin < 16) - clear_giuint(GIUINTENL, (uint16_t)1 << pin); - else - clear_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); + clear_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); } -void vr41xx_clear_giuint(int pin) +static void enable_giuint_low_irq(unsigned int irq) { - if (pin < 16) - write_giuint((uint16_t)1 << pin, GIUINTSTATL); - else - write_giuint((uint16_t)1 << (pin - 16), GIUINTSTATH); + set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); +} + +#define disable_giuint_low_irq shutdown_giuint_low_irq + +static void ack_giuint_low_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq); + clear_giuint(GIUINTENL, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); +} + +static void end_giuint_low_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); +} + +static struct hw_interrupt_type giuint_low_irq_type = { + .typename = "GIUINTL", + .startup = startup_giuint_low_irq, + .shutdown = shutdown_giuint_low_irq, + .enable = enable_giuint_low_irq, + .disable = disable_giuint_low_irq, + .ack = ack_giuint_low_irq, + .end = end_giuint_low_irq, +}; + +static unsigned int startup_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); + set_giuint(GIUINTENH, (uint16_t)1 << pin); + + return 0; +} + +static void shutdown_giuint_high_irq(unsigned int irq) +{ + clear_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +static void enable_giuint_high_irq(unsigned int irq) +{ + set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +#define disable_giuint_high_irq shutdown_giuint_high_irq + +static void ack_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); + clear_giuint(GIUINTENH, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); +} + +static void end_giuint_high_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +static struct hw_interrupt_type giuint_high_irq_type = { + .typename = "GIUINTH", + .startup = startup_giuint_high_irq, + .shutdown = shutdown_giuint_high_irq, + .enable = enable_giuint_high_irq, + .disable = disable_giuint_high_irq, + .ack = ack_giuint_high_irq, + .end = end_giuint_high_irq, +}; + +void __init init_vr41xx_giuint_irq(void) +{ + int i; + + for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { + if (i < (GIU_IRQ_BASE + GIUINT_HIGH_OFFSET)) + irq_desc[i].handler = &giuint_low_irq_type; + else + irq_desc[i].handler = &giuint_high_irq_type; + } + + setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade); } void vr41xx_set_irq_trigger(int pin, int trigger, int hold) { uint16_t mask; - if (pin < 16) { + if (pin < GIUINT_HIGH_OFFSET) { mask = (uint16_t)1 << pin; if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPL, mask); @@ -142,8 +232,9 @@ clear_giuint(GIUINTTYPL, mask); clear_giuint(GIUINTHTSELL, mask); } + write_giuint(mask, GIUINTSTATL); } else { - mask = (uint16_t)1 << (pin - 16); + mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPH, mask); if (hold == SIGNAL_HOLD) @@ -170,32 +261,35 @@ clear_giuint(GIUINTTYPH, mask); clear_giuint(GIUINTHTSELH, mask); } + write_giuint(mask, GIUINTSTATH); } - - vr41xx_clear_giuint(pin); } +EXPORT_SYMBOL(vr41xx_set_irq_trigger); + void vr41xx_set_irq_level(int pin, int level) { uint16_t mask; - if (pin < 16) { + if (pin < GIUINT_HIGH_OFFSET) { mask = (uint16_t)1 << pin; if (level == LEVEL_HIGH) set_giuint(GIUINTALSELL, mask); else clear_giuint(GIUINTALSELL, mask); + write_giuint(mask, GIUINTSTATL); } else { - mask = (uint16_t)1 << (pin - 16); + mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); if (level == LEVEL_HIGH) set_giuint(GIUINTALSELH, mask); else clear_giuint(GIUINTALSELH, mask); + write_giuint(mask, GIUINTSTATH); } - - vr41xx_clear_giuint(pin); } +EXPORT_SYMBOL(vr41xx_set_irq_level); + #define GIUINT_NR_IRQS 32 enum { @@ -209,7 +303,7 @@ }; static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS]; -static struct irqaction giu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction giu_cascade = {no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; static int no_irq_number(int irq) { @@ -232,7 +326,7 @@ giuint_cascade[pin].get_irq_number = get_irq_number; retval = setup_irq(irq, &giu_cascade); - if (retval) { + if (retval != 0) { giuint_cascade[pin].flag = GIUINT_NO_CASCADE; giuint_cascade[pin].get_irq_number = no_irq_number; } @@ -240,29 +334,89 @@ return retval; } -unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs) +EXPORT_SYMBOL(vr41xx_cascade_irq); + +static inline int get_irq_pin_number(void) +{ + uint16_t pendl, pendh, maskl, maskh; + int i; + + pendl = read_giuint(GIUINTSTATL); + pendh = read_giuint(GIUINTSTATH); + maskl = read_giuint(GIUINTENL); + maskh = read_giuint(GIUINTENH); + + maskl &= pendl; + maskh &= pendh; + + if (maskl) { + for (i = 0; i < 16; i++) { + if (maskl & ((uint16_t)1 << i)) + return i; + } + } else if (maskh) { + for (i = 0; i < 16; i++) { + if (maskh & ((uint16_t)1 << i)) + return i + GIUINT_HIGH_OFFSET; + } + } + + printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", + maskl, pendl, maskh, pendh); + + atomic_inc(&irq_err_count); + + return -1; +} + +static inline void ack_giuint_irq(int pin) +{ + if (pin < GIUINT_HIGH_OFFSET) { + clear_giuint(GIUINTENL, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); + } else { + pin -= GIUINT_HIGH_OFFSET; + clear_giuint(GIUINTENH, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); + } +} + +static inline void end_giuint_irq(int pin) +{ + if (pin < GIUINT_HIGH_OFFSET) + set_giuint(GIUINTENL, (uint16_t)1 << pin); + else + set_giuint(GIUINTENH, (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET)); +} + +void giuint_irq_dispatch(struct pt_regs *regs) { struct vr41xx_giuint_cascade *cascade; - unsigned int retval = 0; - int giuint_irq, cascade_irq; + unsigned int giuint_irq; + int pin; + + pin = get_irq_pin_number(); + if (pin < 0) + return; disable_irq(GIUINT_CASCADE_IRQ); + cascade = &giuint_cascade[pin]; giuint_irq = GIU_IRQ(pin); if (cascade->flag == GIUINT_CASCADE) { - cascade_irq = cascade->get_irq_number(giuint_irq); - disable_irq(giuint_irq); - if (cascade_irq > 0) - retval = do_IRQ(cascade_irq, regs); - enable_irq(giuint_irq); - } else - retval = do_IRQ(giuint_irq, regs); - enable_irq(GIUINT_CASCADE_IRQ); + int irq = cascade->get_irq_number(giuint_irq); + ack_giuint_irq(pin); + if (irq >= 0) + do_IRQ(irq, regs); + end_giuint_irq(pin); + } else { + do_IRQ(giuint_irq, regs); + } - return retval; + enable_irq(GIUINT_CASCADE_IRQ); } -void __init vr41xx_giuint_init(void) +static int __init vr41xx_giu_init(void) { int i; @@ -277,16 +431,20 @@ giu_base = GIUIOSELL_TYPE2; break; default: - panic("GIU: Unexpected CPU of NEC VR4100 series"); - break; + printk(KERN_ERR "GIU: Unexpected CPU of NEC VR4100 series\n"); + return -EINVAL; } for (i = 0; i < GIUINT_NR_IRQS; i++) { - vr41xx_disable_giuint(i); + if (i < GIUINT_HIGH_OFFSET) + clear_giuint(GIUINTENL, (uint16_t)1 << i); + else + clear_giuint(GIUINTENH, (uint16_t)1 << (i - GIUINT_HIGH_OFFSET)); giuint_cascade[i].flag = GIUINT_NO_CASCADE; giuint_cascade[i].get_irq_number = no_irq_number; } - if (setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade)) - printk("GIUINT: Can not cascade IRQ %d.\n", GIUINT_CASCADE_IRQ); + return 0; } + +early_initcall(vr41xx_giu_init); diff -Nru a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c --- a/arch/mips/vr41xx/common/icu.c 2004-06-26 17:09:15 -07:00 +++ b/arch/mips/vr41xx/common/icu.c 2004-06-26 17:09:15 -07:00 @@ -28,10 +28,12 @@ * Yoichi Yuasa * - Coped with INTASSIGN of NEC VR4133. */ +#include #include #include #include #include +#include #include #include @@ -43,11 +45,8 @@ extern asmlinkage void vr41xx_handle_interrupt(void); -extern void vr41xx_giuint_init(void); -extern void vr41xx_enable_giuint(int pin); -extern void vr41xx_disable_giuint(int pin); -extern void vr41xx_clear_giuint(int pin); -extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); +extern void init_vr41xx_giuint_irq(void); +extern void giuint_irq_dispatch(struct pt_regs *regs); static uint32_t icu1_base; static uint32_t icu2_base; @@ -64,11 +63,17 @@ #define SYSINT2REG_TYPE2 KSEG1ADDR(0x0f0000a0) #define SYSINT1REG 0x00 +#define PIUINTREG 0x02 #define INTASSIGN0 0x04 #define INTASSIGN1 0x06 #define GIUINTLREG 0x08 +#define DSIUINTREG 0x0a #define MSYSINT1REG 0x0c +#define MPIUINTREG 0x0e +#define MAIUINTREG 0x10 +#define MKIUINTREG 0x12 #define MGIUINTLREG 0x14 +#define MDSIUINTREG 0x16 #define NMIREG 0x18 #define SOFTREG 0x1a #define INTASSIGN2 0x1c @@ -76,11 +81,21 @@ #define SYSINT2REG 0x00 #define GIUINTHREG 0x02 +#define FIRINTREG 0x04 #define MSYSINT2REG 0x06 #define MGIUINTHREG 0x08 - -#define MDSIUINTREG KSEG1ADDR(0x0f000096) - #define INTDSIU 0x0800 +#define MFIRINTREG 0x0a +#define PCIINTREG 0x0c + #define PCIINT0 0x0001 +#define SCUINTREG 0x0e + #define SCUINT0 0x0001 +#define CSIINTREG 0x10 +#define MPCIINTREG 0x12 +#define MSCUINTREG 0x14 +#define MCSIINTREG 0x16 +#define BCUINTREG 0x18 + #define BCUINTR 0x0001 +#define MBCUINTREG 0x1a #define SYSINT1_IRQ_TO_PIN(x) ((x) - SYSINT1_IRQ_BASE) /* Pin 0-15 */ #define SYSINT2_IRQ_TO_PIN(x) ((x) - SYSINT2_IRQ_BASE) /* Pin 0-15 */ @@ -140,212 +155,298 @@ /*=======================================================================*/ -void vr41xx_enable_dsiuint(void) +void vr41xx_enable_piuint(uint16_t mask) { - writew(INTDSIU, MDSIUINTREG); + irq_desc_t *desc = irq_desc + PIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MPIUINTREG); + val |= mask; + write_icu1(val, MPIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -void vr41xx_disable_dsiuint(void) +void vr41xx_disable_piuint(uint16_t mask) { - writew(0, MDSIUINTREG); + irq_desc_t *desc = irq_desc + PIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MPIUINTREG); + val &= ~mask; + write_icu1(val, MPIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -/*=======================================================================*/ +void vr41xx_enable_aiuint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + AIU_IRQ; + unsigned long flags; + uint16_t val; -static void enable_sysint1_irq(unsigned int irq) + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MAIUINTREG); + val |= mask; + write_icu1(val, MAIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +void vr41xx_disable_aiuint(uint16_t mask) { - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + AIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MAIUINTREG); + val &= ~mask; + write_icu1(val, MAIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_sysint1_irq(unsigned int irq) +void vr41xx_enable_kiuint(uint16_t mask) { - clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + KIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MKIUINTREG); + val |= mask; + write_icu1(val, MKIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_sysint1_irq(unsigned int irq) +void vr41xx_disable_kiuint(uint16_t mask) { - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + KIU_IRQ; + unsigned long flags; + uint16_t val; - return 0; /* never anything pending */ + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MKIUINTREG); + val &= ~mask; + write_icu1(val, MKIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -#define shutdown_sysint1_irq disable_sysint1_irq -#define ack_sysint1_irq disable_sysint1_irq +void vr41xx_enable_dsiuint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + DSIU_IRQ; + unsigned long flags; + uint16_t val; -static void end_sysint1_irq(unsigned int irq) + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MDSIUINTREG); + val |= mask; + write_icu1(val, MDSIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +void vr41xx_disable_dsiuint(uint16_t mask) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + DSIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MDSIUINTREG); + val &= ~mask; + write_icu1(val, MDSIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static struct hw_interrupt_type sysint1_irq_type = { - .typename = "SYSINT1", - .startup = startup_sysint1_irq, - .shutdown = shutdown_sysint1_irq, - .enable = enable_sysint1_irq, - .disable = disable_sysint1_irq, - .ack = ack_sysint1_irq, - .end = end_sysint1_irq, -}; +void vr41xx_enable_firint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + FIR_IRQ; + unsigned long flags; + uint16_t val; -/*=======================================================================*/ + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MFIRINTREG); + val |= mask; + write_icu2(val, MFIRINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -static void enable_sysint2_irq(unsigned int irq) +void vr41xx_disable_firint(uint16_t mask) { - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + FIR_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MFIRINTREG); + val &= ~mask; + write_icu2(val, MFIRINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_sysint2_irq(unsigned int irq) +void vr41xx_enable_pciint(void) { - clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + PCI_IRQ; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + write_icu2(PCIINT0, MPCIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_sysint2_irq(unsigned int irq) +void vr41xx_disable_pciint(void) { - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + PCI_IRQ; + unsigned long flags; - return 0; /* never anything pending */ + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MPCIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -#define shutdown_sysint2_irq disable_sysint2_irq -#define ack_sysint2_irq disable_sysint2_irq +void vr41xx_enable_scuint(void) +{ + irq_desc_t *desc = irq_desc + SCU_IRQ; + unsigned long flags; -static void end_sysint2_irq(unsigned int irq) + spin_lock_irqsave(&desc->lock, flags); + write_icu2(SCUINT0, MSCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +void vr41xx_disable_scuint(void) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + SCU_IRQ; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MSCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static struct hw_interrupt_type sysint2_irq_type = { - .typename = "SYSINT2", - .startup = startup_sysint2_irq, - .shutdown = shutdown_sysint2_irq, - .enable = enable_sysint2_irq, - .disable = disable_sysint2_irq, - .ack = ack_sysint2_irq, - .end = end_sysint2_irq, -}; +void vr41xx_enable_csiint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + CSI_IRQ; + unsigned long flags; + uint16_t val; -/*=======================================================================*/ + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MCSIINTREG); + val |= mask; + write_icu2(val, MCSIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -static void enable_giuint_irq(unsigned int irq) +void vr41xx_disable_csiint(uint16_t mask) { - int pin; + irq_desc_t *desc = irq_desc + CSI_IRQ; + unsigned long flags; + uint16_t val; - pin = GIU_IRQ_TO_PIN(irq); - if (pin < 16) - set_icu1(MGIUINTLREG, (uint16_t)1 << pin); - else - set_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); - vr41xx_enable_giuint(pin); + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MCSIINTREG); + val &= ~mask; + write_icu2(val, MCSIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_giuint_irq(unsigned int irq) +void vr41xx_enable_bcuint(void) { - int pin; + irq_desc_t *desc = irq_desc + BCU_IRQ; + unsigned long flags; - pin = GIU_IRQ_TO_PIN(irq); - vr41xx_disable_giuint(pin); - if (pin < 16) - clear_icu1(MGIUINTLREG, (uint16_t)1 << pin); - else - clear_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); + spin_lock_irqsave(&desc->lock, flags); + write_icu2(BCUINTR, MBCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_giuint_irq(unsigned int irq) +void vr41xx_disable_bcuint(void) { - vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + BCU_IRQ; + unsigned long flags; - enable_giuint_irq(irq); + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MBCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +/*=======================================================================*/ + +static unsigned int startup_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); return 0; /* never anything pending */ } -#define shutdown_giuint_irq disable_giuint_irq - -static void ack_giuint_irq(unsigned int irq) +static void shutdown_sysint1_irq(unsigned int irq) { - disable_giuint_irq(irq); + clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); +} - vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); +static void enable_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } -static void end_giuint_irq(unsigned int irq) +#define disable_sysint1_irq shutdown_sysint1_irq +#define ack_sysint1_irq shutdown_sysint1_irq + +static void end_sysint1_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_giuint_irq(irq); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } -static struct hw_interrupt_type giuint_irq_type = { - .typename = "GIUINT", - .startup = startup_giuint_irq, - .shutdown = shutdown_giuint_irq, - .enable = enable_giuint_irq, - .disable = disable_giuint_irq, - .ack = ack_giuint_irq, - .end = end_giuint_irq, +static struct hw_interrupt_type sysint1_irq_type = { + .typename = "SYSINT1", + .startup = startup_sysint1_irq, + .shutdown = shutdown_sysint1_irq, + .enable = enable_sysint1_irq, + .disable = disable_sysint1_irq, + .ack = ack_sysint1_irq, + .end = end_sysint1_irq, }; /*=======================================================================*/ -static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; - -static void __init vr41xx_icu_init(void) +static unsigned int startup_sysint2_irq(unsigned int irq) { - int i; - - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - icu1_base = SYSINT1REG_TYPE1; - icu2_base = SYSINT2REG_TYPE1; - break; - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4133: - icu1_base = SYSINT1REG_TYPE2; - icu2_base = SYSINT2REG_TYPE2; - break; - default: - panic("Unexpected CPU of NEC VR4100 series"); - break; - } - - write_icu1(0, MSYSINT1REG); - write_icu1(0, MGIUINTLREG); - - write_icu2(0, MSYSINT2REG); - write_icu2(0, MGIUINTHREG); - - for (i = SYSINT1_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { - if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST) - irq_desc[i].handler = &sysint1_irq_type; - else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST) - irq_desc[i].handler = &sysint2_irq_type; - else if (i >= GIU_IRQ_BASE && i <= GIU_IRQ_LAST) - irq_desc[i].handler = &giuint_irq_type; - } + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); - setup_irq(INT0_CASCADE_IRQ, &icu_cascade); - setup_irq(INT1_CASCADE_IRQ, &icu_cascade); - setup_irq(INT2_CASCADE_IRQ, &icu_cascade); - setup_irq(INT3_CASCADE_IRQ, &icu_cascade); - setup_irq(INT4_CASCADE_IRQ, &icu_cascade); + return 0; /* never anything pending */ } -void __init init_IRQ(void) +static void shutdown_sysint2_irq(unsigned int irq) { - memset(irq_desc, 0, sizeof(irq_desc)); + clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); +} - init_generic_irq(); - mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); - vr41xx_icu_init(); +static void enable_sysint2_irq(unsigned int irq) +{ + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); +} - vr41xx_giuint_init(); +#define disable_sysint2_irq shutdown_sysint2_irq +#define ack_sysint2_irq shutdown_sysint2_irq - set_except_vector(0, vr41xx_handle_interrupt); +static void end_sysint2_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } +static struct hw_interrupt_type sysint2_irq_type = { + .typename = "SYSINT2", + .startup = startup_sysint2_irq, + .shutdown = shutdown_sysint2_irq, + .enable = enable_sysint2_irq, + .disable = disable_sysint2_irq, + .ack = ack_sysint2_irq, + .end = end_sysint2_irq, +}; + /*=======================================================================*/ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) @@ -492,34 +593,14 @@ return retval; } -/*=======================================================================*/ +EXPORT_SYMBOL(vr41xx_set_intassign); -static inline void giuint_irq_dispatch(uint16_t pendl, uint16_t pendh, - struct pt_regs *regs) -{ - int i; - - if (pendl) { - for (i = 0; i < 16; i++) { - if (pendl & ((uint16_t)1 << i)) { - giuint_do_IRQ(i, regs); - return; - } - } - } else { - for (i = 0; i < 16; i++) { - if (pendh & ((uint16_t)1 << i)) { - giuint_do_IRQ(i + 16, regs); - return; - } - } - } -} +/*=======================================================================*/ asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) { - uint16_t pend1, pend2, pendl, pendh; - uint16_t mask1, mask2, maskl, maskh; + uint16_t pend1, pend2; + uint16_t mask1, mask2; int i; pend1 = read_icu1(SYSINT1REG); @@ -528,28 +609,18 @@ pend2 = read_icu2(SYSINT2REG); mask2 = read_icu2(MSYSINT2REG); - pendl = read_icu1(GIUINTLREG); - maskl = read_icu1(MGIUINTLREG); - - pendh = read_icu2(GIUINTHREG); - maskh = read_icu2(MGIUINTHREG); - mask1 &= pend1; mask2 &= pend2; - maskl &= pendl; - maskh &= pendh; if (mask1) { for (i = 0; i < 16; i++) { if (intnum == sysint1_assign[i] && (mask1 & ((uint16_t)1 << i))) { - if (i == 8 && (maskl | maskh)) { - giuint_irq_dispatch(maskl, maskh, regs); - return; - } else { + if (i == 8) + giuint_irq_dispatch(regs); + else do_IRQ(SYSINT1_IRQ(i), regs); - return; - } + return; } } } @@ -564,6 +635,72 @@ } } - printk(KERN_ERR "spurious interrupt: %04x,%04x,%04x,%04x\n", pend1, pend2, pendl, pendh); + printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2); + atomic_inc(&irq_err_count); +} + +/*=======================================================================*/ + +static int __init vr41xx_icu_init(void) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + icu1_base = SYSINT1REG_TYPE1; + icu2_base = SYSINT2REG_TYPE1; + break; + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: + icu1_base = SYSINT1REG_TYPE2; + icu2_base = SYSINT2REG_TYPE2; + break; + default: + printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n"); + return -EINVAL; + } + + write_icu1(0, MSYSINT1REG); + write_icu1(0xffff, MGIUINTLREG); + + write_icu2(0, MSYSINT2REG); + write_icu2(0xffff, MGIUINTHREG); + + return 0; +} + +early_initcall(vr41xx_icu_init); + +/*=======================================================================*/ + +static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; + +static inline void init_vr41xx_icu_irq(void) +{ + int i; + + for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) + irq_desc[i].handler = &sysint1_irq_type; + + for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) + irq_desc[i].handler = &sysint2_irq_type; + + setup_irq(INT0_CASCADE_IRQ, &icu_cascade); + setup_irq(INT1_CASCADE_IRQ, &icu_cascade); + setup_irq(INT2_CASCADE_IRQ, &icu_cascade); + setup_irq(INT3_CASCADE_IRQ, &icu_cascade); + setup_irq(INT4_CASCADE_IRQ, &icu_cascade); +} + +void __init init_IRQ(void) +{ + memset(irq_desc, 0, sizeof(irq_desc)); + + init_generic_irq(); + mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); + init_vr41xx_icu_irq(); + init_vr41xx_giuint_irq(); + + set_except_vector(0, vr41xx_handle_interrupt); } diff -Nru a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c --- a/arch/mips/vr41xx/common/init.c 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/vr41xx/common/init.c 2004-06-26 17:09:18 -07:00 @@ -18,16 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include #include -#include - -extern void vr41xx_bcu_init(void); -extern void vr41xx_cmu_init(void); -extern void vr41xx_pmu_init(void); -extern void vr41xx_rtc_init(void); void __init prom_init(void) { @@ -42,14 +35,6 @@ if (i < (argc - 1)) strcat(arcs_cmdline, " "); } - - iomem_resource.start = IO_MEM_RESOURCE_START; - iomem_resource.end = IO_MEM_RESOURCE_END; - - vr41xx_bcu_init(); - vr41xx_cmu_init(); - vr41xx_pmu_init(); - vr41xx_rtc_init(); } unsigned long __init prom_free_prom_memory (void) diff -Nru a/arch/mips/vr41xx/common/ksyms.c b/arch/mips/vr41xx/common/ksyms.c --- a/arch/mips/vr41xx/common/ksyms.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/vr41xx/common/ksyms.c 2004-06-26 17:09:16 -07:00 @@ -25,8 +25,6 @@ EXPORT_SYMBOL(vr41xx_get_vtclock_frequency); EXPORT_SYMBOL(vr41xx_get_tclock_frequency); -EXPORT_SYMBOL(vr41xx_set_intassign); - EXPORT_SYMBOL(vr41xx_set_rtclong1_cycle); EXPORT_SYMBOL(vr41xx_read_rtclong1_counter); EXPORT_SYMBOL(vr41xx_set_rtclong2_cycle); diff -Nru a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c --- a/arch/mips/vr41xx/common/pmu.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/vr41xx/common/pmu.c 2004-06-26 17:09:19 -07:00 @@ -1,7 +1,7 @@ /* * pmu.c, Power Management Unit routines for NEC VR4100 series. * - * Copyright (C) 2003 Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * * 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 @@ -68,9 +68,13 @@ while (1) ; } -void __init vr41xx_pmu_init(void) +static int __init vr41xx_pmu_init(void) { _machine_restart = vr41xx_restart; _machine_halt = vr41xx_halt; _machine_power_off = vr41xx_power_off; + + return 0; } + +early_initcall(vr41xx_pmu_init); diff -Nru a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c --- a/arch/mips/vr41xx/common/rtc.c 2004-06-26 17:09:21 -07:00 +++ b/arch/mips/vr41xx/common/rtc.c 2004-06-26 17:09:21 -07:00 @@ -1,7 +1,7 @@ /* * rtc.c, RTC(has only timer function) routines for NEC VR4100 series. * - * Copyright (C) 2003 Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * * 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 @@ -310,8 +310,12 @@ setup_irq(ELAPSEDTIME_IRQ, irq); } -void __init vr41xx_rtc_init(void) +static int __init vr41xx_rtc_init(void) { board_time_init = vr41xx_time_init; board_timer_setup = vr41xx_timer_setup; + + return 0; } + +early_initcall(vr41xx_rtc_init); diff -Nru a/arch/mips/vr41xx/common/serial.c b/arch/mips/vr41xx/common/serial.c --- a/arch/mips/vr41xx/common/serial.c 2004-06-26 17:09:17 -07:00 +++ b/arch/mips/vr41xx/common/serial.c 2004-06-26 17:09:17 -07:00 @@ -168,7 +168,7 @@ if (port.membase != NULL) { if (early_serial_setup(&port) == 0) { vr41xx_supply_clock(DSIU_CLOCK); - vr41xx_enable_dsiuint(); + vr41xx_enable_dsiuint(DSIUINT_ALL); vr41xx_serial_ports++; return; } diff -Nru a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c --- a/arch/mips/vr41xx/common/vrc4173.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/vr41xx/common/vrc4173.c 2004-06-26 17:09:19 -07:00 @@ -1,143 +1,336 @@ /* - * FILE NAME - * drivers/char/vrc4173.c - * - * BRIEF MODULE DESCRIPTION - * NEC VRC4173 driver for NEC VR4122/VR4131. + * vrc4173.c, NEC VRC4173 base driver for NEC VR4122/VR4131. * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Copyright 2001,2002 MontaVista Software Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include #include #include +#include #include #include #include -MODULE_DESCRIPTION("NEC VRC4173 driver for NEC VR4122/4131"); +MODULE_DESCRIPTION("NEC VRC4173 base driver for NEC VR4122/4131"); MODULE_AUTHOR("Yoichi Yuasa "); MODULE_LICENSE("GPL"); #define VRC4173_CMUCLKMSK 0x040 + #define MSKPIU 0x0001 + #define MSKKIU 0x0002 + #define MSKAIU 0x0004 + #define MSKPS2CH1 0x0008 + #define MSKPS2CH2 0x0010 + #define MSKUSB 0x0020 + #define MSKCARD1 0x0040 + #define MSKCARD2 0x0080 + #define MSKAC97 0x0100 + #define MSK48MUSB 0x0400 + #define MSK48MPIN 0x0800 + #define MSK48MOSC 0x1000 #define VRC4173_CMUSRST 0x042 - -#define VRC4173_SELECTREG 0x09e + #define USBRST 0x0001 + #define CARD1RST 0x0002 + #define CARD2RST 0x0004 + #define AC97RST 0x0008 #define VRC4173_SYSINT1REG 0x060 #define VRC4173_MSYSINT1REG 0x06c -static struct pci_device_id vrc4173_table[] = { - {PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC4173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0, } +#define VRC4173_SELECTREG 0x09e + #define SEL3 0x0008 + #define SEL2 0x0004 + #define SEL1 0x0002 + #define SEL0 0x0001 + +static struct pci_device_id vrc4173_id_table[] __devinitdata = { + { .vendor = PCI_VENDOR_ID_NEC, + .device = PCI_DEVICE_ID_NEC_VRC4173, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, + { .vendor = 0, }, }; unsigned long vrc4173_io_offset = 0; EXPORT_SYMBOL(vrc4173_io_offset); -static u16 vrc4173_cmuclkmsk; static int vrc4173_initialized; +static uint16_t vrc4173_cmuclkmsk; +static uint16_t vrc4173_selectreg; +static spinlock_t vrc4173_cmu_lock; +static spinlock_t vrc4173_giu_lock; -void vrc4173_clock_supply(u16 mask) +static inline void set_cmusrst(uint16_t val) +{ + uint16_t cmusrst; + + cmusrst = vrc4173_inw(VRC4173_CMUSRST); + cmusrst |= val; + vrc4173_outw(cmusrst, VRC4173_CMUSRST); +} + +static inline void clear_cmusrst(uint16_t val) +{ + uint16_t cmusrst; + + cmusrst = vrc4173_inw(VRC4173_CMUSRST); + cmusrst &= ~val; + vrc4173_outw(cmusrst, VRC4173_CMUSRST); +} + +void vrc4173_supply_clock(vrc4173_clock_t clock) { if (vrc4173_initialized) { - vrc4173_cmuclkmsk |= mask; + spin_lock_irq(&vrc4173_cmu_lock); + + switch (clock) { + case VRC4173_PIU_CLOCK: + vrc4173_cmuclkmsk |= MSKPIU; + break; + case VRC4173_KIU_CLOCK: + vrc4173_cmuclkmsk |= MSKKIU; + break; + case VRC4173_AIU_CLOCK: + vrc4173_cmuclkmsk |= MSKAIU; + break; + case VRC4173_PS2_CH1_CLOCK: + vrc4173_cmuclkmsk |= MSKPS2CH1; + break; + case VRC4173_PS2_CH2_CLOCK: + vrc4173_cmuclkmsk |= MSKPS2CH2; + break; + case VRC4173_USBU_PCI_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk |= MSKUSB; + break; + case VRC4173_CARDU1_PCI_CLOCK: + set_cmusrst(CARD1RST); + vrc4173_cmuclkmsk |= MSKCARD1; + break; + case VRC4173_CARDU2_PCI_CLOCK: + set_cmusrst(CARD2RST); + vrc4173_cmuclkmsk |= MSKCARD2; + break; + case VRC4173_AC97U_PCI_CLOCK: + set_cmusrst(AC97RST); + vrc4173_cmuclkmsk |= MSKAC97; + break; + case VRC4173_USBU_48MHz_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk |= MSK48MUSB; + break; + case VRC4173_EXT_48MHz_CLOCK: + if (vrc4173_cmuclkmsk & MSK48MOSC) + vrc4173_cmuclkmsk |= MSK48MPIN; + else + printk(KERN_WARNING + "vrc4173_supply_clock: " + "Please supply VRC4173_48MHz_CLOCK first " + "rather than VRC4173_EXT_48MHz_CLOCK.\n"); + break; + case VRC4173_48MHz_CLOCK: + vrc4173_cmuclkmsk |= MSK48MOSC; + break; + default: + printk(KERN_WARNING + "vrc4173_supply_clock: Invalid CLOCK value %u\n", clock); + break; + } + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + + switch (clock) { + case VRC4173_USBU_PCI_CLOCK: + case VRC4173_USBU_48MHz_CLOCK: + clear_cmusrst(USBRST); + break; + case VRC4173_CARDU1_PCI_CLOCK: + clear_cmusrst(CARD1RST); + break; + case VRC4173_CARDU2_PCI_CLOCK: + clear_cmusrst(CARD2RST); + break; + case VRC4173_AC97U_PCI_CLOCK: + clear_cmusrst(AC97RST); + break; + default: + break; + } + + spin_unlock_irq(&vrc4173_cmu_lock); } } -void vrc4173_clock_mask(u16 mask) +EXPORT_SYMBOL(vrc4173_supply_clock); + +void vrc4173_mask_clock(vrc4173_clock_t clock) { if (vrc4173_initialized) { - vrc4173_cmuclkmsk &= ~mask; + spin_lock_irq(&vrc4173_cmu_lock); + + switch (clock) { + case VRC4173_PIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPIU; + break; + case VRC4173_KIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKKIU; + break; + case VRC4173_AIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKAIU; + break; + case VRC4173_PS2_CH1_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPS2CH1; + break; + case VRC4173_PS2_CH2_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPS2CH2; + break; + case VRC4173_USBU_PCI_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk &= ~MSKUSB; + break; + case VRC4173_CARDU1_PCI_CLOCK: + set_cmusrst(CARD1RST); + vrc4173_cmuclkmsk &= ~MSKCARD1; + break; + case VRC4173_CARDU2_PCI_CLOCK: + set_cmusrst(CARD2RST); + vrc4173_cmuclkmsk &= ~MSKCARD2; + break; + case VRC4173_AC97U_PCI_CLOCK: + set_cmusrst(AC97RST); + vrc4173_cmuclkmsk &= ~MSKAC97; + break; + case VRC4173_USBU_48MHz_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk &= ~MSK48MUSB; + break; + case VRC4173_EXT_48MHz_CLOCK: + vrc4173_cmuclkmsk &= ~MSK48MPIN; + break; + case VRC4173_48MHz_CLOCK: + vrc4173_cmuclkmsk &= ~MSK48MOSC; + break; + default: + printk(KERN_WARNING "vrc4173_mask_clock: Invalid CLOCK value %u\n", clock); + break; + } + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + + switch (clock) { + case VRC4173_USBU_PCI_CLOCK: + case VRC4173_USBU_48MHz_CLOCK: + clear_cmusrst(USBRST); + break; + case VRC4173_CARDU1_PCI_CLOCK: + clear_cmusrst(CARD1RST); + break; + case VRC4173_CARDU2_PCI_CLOCK: + clear_cmusrst(CARD2RST); + break; + case VRC4173_AC97U_PCI_CLOCK: + clear_cmusrst(AC97RST); + break; + default: + break; + } + + spin_unlock_irq(&vrc4173_cmu_lock); } } +EXPORT_SYMBOL(vrc4173_mask_clock); + static inline void vrc4173_cmu_init(void) { vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK); -} -EXPORT_SYMBOL(vrc4173_clock_supply); -EXPORT_SYMBOL(vrc4173_clock_mask); + spin_lock_init(&vrc4173_cmu_lock); +} -void vrc4173_select_function(int func) +void vrc4173_select_function(vrc4173_function_t function) { - u16 val; - if (vrc4173_initialized) { - val = vrc4173_inw(VRC4173_SELECTREG); - switch(func) { - case PS2CH1_SELECT: - val |= 0x0004; + spin_lock_irq(&vrc4173_giu_lock); + + switch(function) { + case PS2_CHANNEL1: + vrc4173_selectreg |= SEL2; break; - case PS2CH2_SELECT: - val |= 0x0002; + case PS2_CHANNEL2: + vrc4173_selectreg |= SEL1; break; - case TOUCHPANEL_SELECT: - val &= 0x0007; + case TOUCHPANEL: + vrc4173_selectreg &= SEL2 | SEL1 | SEL0; break; - case KIU8_SELECT: - val &= 0x000e; + case KEYBOARD_8SCANLINES: + vrc4173_selectreg &= SEL3 | SEL2 | SEL1; break; - case KIU10_SELECT: - val &= 0x000c; + case KEYBOARD_10SCANLINES: + vrc4173_selectreg &= SEL3 | SEL2; break; - case KIU12_SELECT: - val &= 0x0008; + case KEYBOARD_12SCANLINES: + vrc4173_selectreg &= SEL3; break; - case GPIO_SELECT: - val |= 0x0008; + case GPIO_0_15PINS: + vrc4173_selectreg |= SEL0; + break; + case GPIO_16_20PINS: + vrc4173_selectreg |= SEL3; break; } - vrc4173_outw(val, VRC4173_SELECTREG); + + vrc4173_outw(vrc4173_selectreg, VRC4173_SELECTREG); + + spin_unlock_irq(&vrc4173_giu_lock); } } EXPORT_SYMBOL(vrc4173_select_function); +static inline void vrc4173_giu_init(void) +{ + vrc4173_selectreg = vrc4173_inw(VRC4173_SELECTREG); + + spin_lock_init(&vrc4173_giu_lock); +} + static void enable_vrc4173_irq(unsigned int irq) { - u16 val; + uint16_t val; val = vrc4173_inw(VRC4173_MSYSINT1REG); - val |= (u16)1 << (irq - VRC4173_IRQ_BASE); + val |= (uint16_t)1 << (irq - VRC4173_IRQ_BASE); vrc4173_outw(val, VRC4173_MSYSINT1REG); } static void disable_vrc4173_irq(unsigned int irq) { - u16 val; + uint16_t val; val = vrc4173_inw(VRC4173_MSYSINT1REG); - val &= ~((u16)1 << (irq - VRC4173_IRQ_BASE)); + val &= ~((uint16_t)1 << (irq - VRC4173_IRQ_BASE)); vrc4173_outw(val, VRC4173_MSYSINT1REG); } @@ -157,19 +350,18 @@ } static struct hw_interrupt_type vrc4173_irq_type = { - "VRC4173", - startup_vrc4173_irq, - shutdown_vrc4173_irq, - enable_vrc4173_irq, - disable_vrc4173_irq, - ack_vrc4173_irq, - end_vrc4173_irq, - NULL + .typename = "VRC4173", + .startup = startup_vrc4173_irq, + .shutdown = shutdown_vrc4173_irq, + .enable = enable_vrc4173_irq, + .disable = disable_vrc4173_irq, + .ack = ack_vrc4173_irq, + .end = end_vrc4173_irq, }; static int vrc4173_get_irq_number(int irq) { - u16 status, mask; + uint16_t status, mask; int i; status = vrc4173_inw(VRC4173_SYSINT1REG); @@ -179,18 +371,18 @@ if (status) { for (i = 0; i < 16; i++) if (status & (0x0001 << i)) - return VRC4173_IRQ_BASE + i; + return VRC4173_IRQ(i); } return -EINVAL; } -static inline void vrc4173_icu_init(int cascade_irq) +static inline int vrc4173_icu_init(int cascade_irq) { int i; if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15)) - return; + return -EINVAL; vrc4173_outw(0, VRC4173_MSYSINT1REG); @@ -199,33 +391,38 @@ for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) irq_desc[i].handler = &vrc4173_irq_type; + + return 0; } -static int __devinit vrc4173_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit vrc4173_probe(struct pci_dev *dev, + const struct pci_device_id *id) { unsigned long start, flags; int err; - if ((err = pci_enable_device(pdev)) < 0) { - printk(KERN_ERR "vrc4173: failed to enable device -- err=%d\n", err); + err = pci_enable_device(dev); + if (err < 0) { + printk(KERN_ERR "vrc4173: Failed to enable PCI device, aborting\n"); return err; } - pci_set_master(pdev); + pci_set_master(dev); - start = pci_resource_start(pdev, 0); - if (!start) { - printk(KERN_ERR "vrc4173:No PCI I/O resources, aborting\n"); - return -ENODEV; + start = pci_resource_start(dev, 0); + if (start == 0) { + printk(KERN_ERR "vrc4173:No such PCI I/O resource, aborting\n"); + return -ENXIO; } - if (!start || (((flags = pci_resource_flags(pdev, 0)) & IORESOURCE_IO) == 0)) { - printk(KERN_ERR "vrc4173: No PCI I/O resources, aborting\n"); - return -ENODEV; + flags = pci_resource_flags(dev, 0); + if ((flags & IORESOURCE_IO) == 0) { + printk(KERN_ERR "vrc4173: No such PCI I/O resource, aborting\n"); + return -ENXIO; } - if ((err = pci_request_regions(pdev, "NEC VRC4173")) < 0) { + err = pci_request_regions(dev, "NEC VRC4173"); + if (err < 0) { printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n"); return err; } @@ -233,33 +430,46 @@ set_vrc4173_io_offset(start); vrc4173_cmu_init(); + vrc4173_giu_init(); - vrc4173_icu_init(pdev->irq); + err = vrc4173_icu_init(dev->irq); + if (err < 0) { + printk(KERN_ERR "vrc4173: Invalid IRQ %d, aborting\n", dev->irq); + return err; + } - if ((err = vr41xx_cascade_irq(pdev->irq, vrc4173_get_irq_number)) < 0) { - printk(KERN_ERR - "vrc4173: IRQ resource %d is busy, aborting\n", pdev->irq); + err = vr41xx_cascade_irq(dev->irq, vrc4173_get_irq_number); + if (err < 0) { + printk(KERN_ERR "vrc4173: IRQ resource %d is busy, aborting\n", dev->irq); return err; } printk(KERN_INFO - "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, pdev->irq); + "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, dev->irq); return 0; } +static void vrc4173_remove(struct pci_dev *dev) +{ + free_irq(dev->irq, NULL); + + pci_release_regions(dev); +} + static struct pci_driver vrc4173_driver = { .name = "NEC VRC4173", .probe = vrc4173_probe, - .remove = NULL, - .id_table = vrc4173_table, + .remove = vrc4173_remove, + .id_table = vrc4173_id_table, }; static int __devinit vrc4173_init(void) { int err; - if ((err = pci_module_init(&vrc4173_driver)) < 0) + err = pci_module_init(&vrc4173_driver); + if (err < 0) return err; vrc4173_initialized = 1; diff -Nru a/arch/mips/vr41xx/tanbac-tb0226/setup.c b/arch/mips/vr41xx/tanbac-tb0226/setup.c --- a/arch/mips/vr41xx/tanbac-tb0226/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/vr41xx/tanbac-tb0226/setup.c 2004-06-26 17:09:16 -07:00 @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - .name = "PCI I/O space", - .start = VR41XX_PCI_IO_START, - .end = VR41XX_PCI_IO_END, - .flags = IORESOURCE_IO, -}; - -static struct resource vr41xx_pci_mem_resource = { - .name = "PCI memory space", - .start = VR41XX_PCI_MEM_START, - .end = VR41XX_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller[] = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - .internal_base = VR41XX_PCI_MEM1_BASE, - .address_mask = VR41XX_PCI_MEM1_MASK, - .pci_base = IO_MEM1_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - .internal_base = VR41XX_PCI_MEM2_BASE, - .address_mask = VR41XX_PCI_MEM2_MASK, - .pci_base = IO_MEM2_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - .internal_base = VR41XX_PCI_IO_BASE, - .address_mask = VR41XX_PCI_IO_MASK, - .pci_base = IO_PORT_RESOURCE_START, -}; - -static struct vr41xx_pci_address_map pci_address_map = { - .mem1 = &vr41xx_pci_mem1, - .mem2 = &vr41xx_pci_mem2, - .io = &vr41xx_pci_io, -}; -#endif +#include const char *get_system_type(void) { @@ -79,17 +28,9 @@ static int tanbac_tb0226_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); -#endif - -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); #endif return 0; diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/Makefile b/arch/mips/vr41xx/tanbac-tb0229/Makefile --- a/arch/mips/vr41xx/tanbac-tb0229/Makefile 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/vr41xx/tanbac-tb0229/Makefile 2004-06-26 17:09:19 -07:00 @@ -4,4 +4,4 @@ obj-y := setup.o -obj-$(CONFIG_TANBAC_TB0219) += reboot.o +obj-$(CONFIG_TANBAC_TB0219) += tb0219.o diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/reboot.c b/arch/mips/vr41xx/tanbac-tb0229/reboot.c --- a/arch/mips/vr41xx/tanbac-tb0229/reboot.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,27 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0229/reboot.c - * - * BRIEF MODULE DESCRIPTION - * Depending on TANBAC TB0229(VR4131DIMM) of reboot system call. - * - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * 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 tb0229_hard_reset() writew(0, TB0219_RESET_REGS) - -void tanbac_tb0229_restart(char *command) -{ - local_irq_disable(); - tb0229_hard_reset(); - while (1); -} diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/setup.c b/arch/mips/vr41xx/tanbac-tb0229/setup.c --- a/arch/mips/vr41xx/tanbac-tb0229/setup.c 2004-06-26 17:09:18 -07:00 +++ b/arch/mips/vr41xx/tanbac-tb0229/setup.c 2004-06-26 17:09:18 -07:00 @@ -21,60 +21,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - .name = "PCI I/O space", - .start = VR41XX_PCI_IO_START, - .end = VR41XX_PCI_IO_END, - .flags = IORESOURCE_IO, -}; - -static struct resource vr41xx_pci_mem_resource = { - .name = "PCI memory space", - .start = VR41XX_PCI_MEM_START, - .end = VR41XX_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - .internal_base = VR41XX_PCI_MEM1_BASE, - .address_mask = VR41XX_PCI_MEM1_MASK, - .pci_base = IO_MEM1_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - .internal_base = VR41XX_PCI_MEM2_BASE, - .address_mask = VR41XX_PCI_MEM2_MASK, - .pci_base = IO_MEM2_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - .internal_base = VR41XX_PCI_IO_BASE, - .address_mask = VR41XX_PCI_IO_MASK, - .pci_base = IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - .mem1 = &vr41xx_pci_mem1, - .mem2 = &vr41xx_pci_mem2, - .io = &vr41xx_pci_io, -}; -#endif +#include const char *get_system_type(void) { @@ -83,22 +31,10 @@ static int tanbac_tb0229_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); vr41xx_dsiu_init(); -#endif - -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - -#ifdef CONFIG_TANBAC_TB0219 - _machine_restart = tanbac_tb0229_restart; #endif return 0; diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/tb0219.c b/arch/mips/vr41xx/tanbac-tb0229/tb0219.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/mips/vr41xx/tanbac-tb0229/tb0219.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,44 @@ +/* + * tb0219.c, Setup for the TANBAC TB0219 + * + * Copyright (C) 2003 Megasolution Inc. + * Copyright (C) 2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include + +#include +#include + +#define TB0219_RESET_REGS KSEG1ADDR(0x0a00000e) + +#define tb0219_hard_reset() writew(0, TB0219_RESET_REGS) + +static void tanbac_tb0219_restart(char *command) +{ + local_irq_disable(); + tb0219_hard_reset(); + while (1); +} + +static int __init tanbac_tb0219_setup(void) +{ + _machine_restart = tanbac_tb0219_restart; + + return 0; +} + +early_initcall(tanbac_tb0219_setup); diff -Nru a/arch/mips/vr41xx/victor-mpc30x/setup.c b/arch/mips/vr41xx/victor-mpc30x/setup.c --- a/arch/mips/vr41xx/victor-mpc30x/setup.c 2004-06-26 17:09:19 -07:00 +++ b/arch/mips/vr41xx/victor-mpc30x/setup.c 2004-06-26 17:09:19 -07:00 @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - "PCI I/O space", - VR41XX_PCI_IO_START, - VR41XX_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource vr41xx_pci_mem_resource = { - "PCI memory space", - VR41XX_PCI_MEM_START, - VR41XX_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller[] = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - VR41XX_PCI_MEM1_BASE, - VR41XX_PCI_MEM1_MASK, - IO_MEM1_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - VR41XX_PCI_MEM2_BASE, - VR41XX_PCI_MEM2_MASK, - IO_MEM2_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - VR41XX_PCI_IO_BASE, - VR41XX_PCI_IO_MASK, - IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - &vr41xx_pci_mem1, - &vr41xx_pci_mem2, - &vr41xx_pci_io -}; -#endif +#include const char *get_system_type(void) { @@ -79,17 +28,9 @@ static int victor_mpc30x_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); -#endif - -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); #endif return 0; diff -Nru a/arch/mips/vr41xx/zao-capcella/setup.c b/arch/mips/vr41xx/zao-capcella/setup.c --- a/arch/mips/vr41xx/zao-capcella/setup.c 2004-06-26 17:09:16 -07:00 +++ b/arch/mips/vr41xx/zao-capcella/setup.c 2004-06-26 17:09:16 -07:00 @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - "PCI I/O space", - VR41XX_PCI_IO_START, - VR41XX_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource vr41xx_pci_mem_resource = { - "PCI memory space", - VR41XX_PCI_MEM_START, - VR41XX_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - VR41XX_PCI_MEM1_BASE, - VR41XX_PCI_MEM1_MASK, - IO_MEM1_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - VR41XX_PCI_MEM2_BASE, - VR41XX_PCI_MEM2_MASK, - IO_MEM2_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - VR41XX_PCI_IO_BASE, - VR41XX_PCI_IO_MASK, - IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - &vr41xx_pci_mem1, - &vr41xx_pci_mem2, - &vr41xx_pci_io -}; -#endif +#include const char *get_system_type(void) { @@ -79,18 +28,10 @@ static int zao_capcella_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); vr41xx_dsiu_init(); -#endif - -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); #endif return 0; diff -Nru a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c --- a/arch/parisc/kernel/init_task.c 2004-06-26 17:09:18 -07:00 +++ b/arch/parisc/kernel/init_task.c 2004-06-26 17:09:18 -07:00 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c --- a/arch/parisc/kernel/irq.c 2004-06-26 17:09:17 -07:00 +++ b/arch/parisc/kernel/irq.c 2004-06-26 17:09:17 -07:00 @@ -644,7 +644,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c --- a/arch/parisc/kernel/setup.c 2004-06-26 17:09:20 -07:00 +++ b/arch/parisc/kernel/setup.c 2004-06-26 17:09:20 -07:00 @@ -45,8 +45,6 @@ #include #include -#define COMMAND_LINE_SIZE 1024 -char saved_command_line[COMMAND_LINE_SIZE]; char command_line[COMMAND_LINE_SIZE]; /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */ diff -Nru a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c --- a/arch/parisc/mm/init.c 2004-06-26 17:09:18 -07:00 +++ b/arch/parisc/mm/init.c 2004-06-26 17:09:18 -07:00 @@ -484,7 +484,8 @@ printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk(KERN_INFO "Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk(KERN_INFO "Free swap: %6ldkB\n", + nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff -Nru a/arch/ppc/8260_io/Kconfig b/arch/ppc/8260_io/Kconfig --- a/arch/ppc/8260_io/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/8260_io/Kconfig 2004-06-26 17:09:20 -07:00 @@ -1,12 +1,9 @@ # -# MPC8260 Communication options +# CPM2 Communication options # -menu "MPC8260 CPM Options" - depends on 8260 - -config SCC_CONSOLE - bool "Enable SCC Console" +menu "CPM2 Options" + depends on CPM2 config SCC_ENET bool "CPM SCC Ethernet" @@ -24,19 +21,19 @@ bool "Ethernet on FCC1" depends on FEC_ENET help - Use MPC8260 fast Ethernet controller 1 to drive Ethernet (default). + Use CPM2 fast Ethernet controller 1 to drive Ethernet (default). config FCC2_ENET bool "Ethernet on FCC2" depends on FEC_ENET help - Use MPC8260 fast Ethernet controller 2 to drive Ethernet. + Use CPM2 fast Ethernet controller 2 to drive Ethernet. config FCC3_ENET bool "Ethernet on FCC3" depends on FEC_ENET help - Use MPC8260 fast Ethernet controller 3 to drive Ethernet. + Use CPM2 fast Ethernet controller 3 to drive Ethernet. config USE_MDIO bool "Use MDIO for PHY configuration" diff -Nru a/arch/ppc/8260_io/Makefile b/arch/ppc/8260_io/Makefile --- a/arch/ppc/8260_io/Makefile 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc/8260_io/Makefile 2004-06-26 17:09:19 -07:00 @@ -1,8 +1,6 @@ # -# Makefile for the linux MPC8xx ppc-specific parts of comm processor +# Makefile for the linux ppc-specific parts of comm processor (v2) # - -obj-y := commproc.o uart.o obj-$(CONFIG_FEC_ENET) += fcc_enet.o obj-$(CONFIG_SCC_ENET) += enet.o diff -Nru a/arch/ppc/8260_io/commproc.c b/arch/ppc/8260_io/commproc.c --- a/arch/ppc/8260_io/commproc.c 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,179 +0,0 @@ -/* - * General Purpose functions for the global management of the - * 8260 Communication Processor Module. - * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) - * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) - * 2.3.99 Updates - * - * In addition to the individual control of the communication - * channels, there are a few functions that globally affect the - * communication processor. - * - * Buffer descriptors must be allocated from the dual ported memory - * space. The allocator for that is here. When the communication - * process is reset, we reclaim the memory available. There is - * currently no deallocator for this memory. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static uint dp_alloc_base; /* Starting offset in DP ram */ -static uint dp_alloc_top; /* Max offset + 1 */ -static uint host_buffer; /* One page of host buffer */ -static uint host_end; /* end + 1 */ -cpm8260_t *cpmp; /* Pointer to comm processor space */ - -/* We allocate this here because it is used almost exclusively for - * the communication processor devices. - */ -immap_t *immr; - -void -m8260_cpm_reset(void) -{ - volatile immap_t *imp; - volatile cpm8260_t *commproc; - uint vpgaddr; - - immr = imp = (volatile immap_t *)IMAP_ADDR; - commproc = &imp->im_cpm; - - /* Reclaim the DP memory for our use. - */ - dp_alloc_base = CPM_DATAONLY_BASE; - dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE; - - /* Set the host page for allocation. - */ - host_buffer = - (uint) alloc_bootmem_pages(PAGE_SIZE * NUM_CPM_HOST_PAGES); - host_end = host_buffer + (PAGE_SIZE * NUM_CPM_HOST_PAGES); - - vpgaddr = host_buffer; - - /* Tell everyone where the comm processor resides. - */ - cpmp = (cpm8260_t *)commproc; -} - -/* Allocate some memory from the dual ported ram. - * To help protocols with object alignment restrictions, we do that - * if they ask. - */ -uint -m8260_cpm_dpalloc(uint size, uint align) -{ - uint retloc; - uint align_mask, off; - uint savebase; - - align_mask = align - 1; - savebase = dp_alloc_base; - - if ((off = (dp_alloc_base & align_mask)) != 0) - dp_alloc_base += (align - off); - - if ((dp_alloc_base + size) >= dp_alloc_top) { - dp_alloc_base = savebase; - return(CPM_DP_NOSPACE); - } - - retloc = dp_alloc_base; - dp_alloc_base += size; - - return(retloc); -} - -/* We also own one page of host buffer space for the allocation of - * UART "fifos" and the like. - */ -uint -m8260_cpm_hostalloc(uint size, uint align) -{ - uint retloc; - uint align_mask, off; - uint savebase; - - align_mask = align - 1; - savebase = host_buffer; - - if ((off = (host_buffer & align_mask)) != 0) - host_buffer += (align - off); - - if ((host_buffer + size) >= host_end) { - host_buffer = savebase; - return(0); - } - - retloc = host_buffer; - host_buffer += size; - - return(retloc); -} - -/* Set a baud rate generator. This needs lots of work. There are - * eight BRGs, which can be connected to the CPM channels or output - * as clocks. The BRGs are in two different block of internal - * memory mapped space. - * The baud rate clock is the system clock divided by something. - * It was set up long ago during the initial boot phase and is - * is given to us. - * Baud rate clocks are zero-based in the driver code (as that maps - * to port numbers). Documentation uses 1-based numbering. - */ -#define BRG_INT_CLK (((bd_t *)__res)->bi_brgfreq) -#define BRG_UART_CLK (BRG_INT_CLK/16) - -/* This function is used by UARTS, or anything else that uses a 16x - * oversampled clock. - */ -void -m8260_cpm_setbrg(uint brg, uint rate) -{ - volatile uint *bp; - - /* This is good enough to get SMCs running..... - */ - if (brg < 4) { - bp = (uint *)&immr->im_brgc1; - } - else { - bp = (uint *)&immr->im_brgc5; - brg -= 4; - } - bp += brg; - *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN; -} - -/* This function is used to set high speed synchronous baud rate - * clocks. - */ -void -m8260_cpm_fastbrg(uint brg, uint rate, int div16) -{ - volatile uint *bp; - - if (brg < 4) { - bp = (uint *)&immr->im_brgc1; - } - else { - bp = (uint *)&immr->im_brgc5; - brg -= 4; - } - bp += brg; - *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN; - if (div16) - *bp |= CPM_BRG_DIV16; -} diff -Nru a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c --- a/arch/ppc/8260_io/enet.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/8260_io/enet.c 2004-06-26 17:09:15 -07:00 @@ -40,12 +40,12 @@ #include #include -#include +#include #include #include #include #include -#include +#include #include /* @@ -376,7 +376,7 @@ } if (must_restart) { - volatile cpm8260_t *cp; + volatile cpm_cpm2_t *cp; /* Some transmit errors cause the transmitter to shut * down. We now issue a restart transmit. Since the @@ -552,10 +552,10 @@ /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); - cep->sccp->scc_pmsr |= SCC_PSMR_PRO; + cep->sccp->scc_psmr |= SCC_PSMR_PRO; } else { - cep->sccp->scc_pmsr &= ~SCC_PSMR_PRO; + cep->sccp->scc_psmr &= ~SCC_PSMR_PRO; if (dev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the @@ -613,19 +613,20 @@ struct net_device *dev; struct scc_enet_private *cep; int i, j, err; + void * dpaddr; unsigned char *eap; unsigned long mem_addr; bd_t *bd; volatile cbd_t *bdp; - volatile cpm8260_t *cp; + volatile cpm_cpm2_t *cp; volatile scc_t *sccp; volatile scc_enet_t *ep; - volatile immap_t *immap; - volatile iop8260_t *io; + volatile cpm2_map_t *immap; + volatile iop_cpm2_t *io; cp = cpmp; /* Get pointer to Communication Processor */ - immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ + immap = (cpm2_map_t *)CPM_MAP_ADDR; /* and to internal registers */ io = &immap->im_ioport; bd = (bd_t *)__res; @@ -680,13 +681,13 @@ * These are relative offsets in the DP ram address space. * Initialize base addresses for the buffer descriptors. */ - i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); - ep->sen_genscc.scc_rbase = i; - cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i]; - - i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); - ep->sen_genscc.scc_tbase = i; - cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i]; + dpaddr = cpm2_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); + ep->sen_genscc.scc_rbase = cpm2_dpram_offset(dpaddr); + cep->rx_bd_base = (cbd_t *)dpaddr; + + dpaddr = cpm2_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); + ep->sen_genscc.scc_tbase = cpm2_dpram_offset(dpaddr); + cep->tx_bd_base = (cbd_t *)dpaddr; cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; cep->cur_rx = cep->rx_bd_base; @@ -820,7 +821,7 @@ /* Set processing mode. Use Ethernet CRC, catch broadcast, and * start frame search 22 bit times after RENA. */ - sccp->scc_pmsr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22); + sccp->scc_psmr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22); /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. diff -Nru a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c --- a/arch/ppc/8260_io/fcc_enet.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ppc/8260_io/fcc_enet.c 2004-06-26 17:09:17 -07:00 @@ -35,13 +35,13 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include /* The transmitter timeout */ @@ -159,20 +159,23 @@ #define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER) #ifdef CONFIG_SBC82xx -/* rx is clk9, tx is clk10 - */ +/* rx is clk9, tx is clk10 */ #define PC_F1RXCLK ((uint)0x00000100) #define PC_F1TXCLK ((uint)0x00000200) #define CMX1_CLK_ROUTE ((uint)0x25000000) #define CMX1_CLK_MASK ((uint)0xff000000) -#else -/* CLK12 is receive, CLK11 is transmit. These are board specific. -*/ +#elif defined(CONFIG_ADS8272) +#define PC_F1RXCLK ((uint)0x00000400) +#define PC_F1TXCLK ((uint)0x00000200) +#define CMX1_CLK_ROUTE ((uint)0x36000000) +#define CMX1_CLK_MASK ((uint)0xff000000) +#else /* other boards */ +/* CLK12 is receive, CLK11 is transmit. These are board specific. */ #define PC_F1RXCLK ((uint)0x00000800) #define PC_F1TXCLK ((uint)0x00000400) #define CMX1_CLK_ROUTE ((uint)0x3e000000) #define CMX1_CLK_MASK ((uint)0xff000000) -#endif /* !CONFIG_SBC82xx */ +#endif /* I/O Pin assignment for FCC2. I don't yet know the best way to do this, * but there is little variation among the choices. @@ -193,10 +196,17 @@ /* CLK13 is receive, CLK14 is transmit. These are board dependent. */ +#ifdef CONFIG_ADS8272 +#define PC_F2RXCLK ((uint)0x00004000) +#define PC_F2TXCLK ((uint)0x00008000) +#define CMX2_CLK_ROUTE ((uint)0x00370000) +#define CMX2_CLK_MASK ((uint)0x00ff0000) +#else #define PC_F2RXCLK ((uint)0x00001000) #define PC_F2TXCLK ((uint)0x00002000) #define CMX2_CLK_ROUTE ((uint)0x00250000) #define CMX2_CLK_MASK ((uint)0x00ff0000) +#endif /* I/O Pin assignment for FCC3. I don't yet know the best way to do this, * but there is little variation among the choices. @@ -228,6 +238,9 @@ /* TQM8260 has MDIO and MDCK on PC30 and PC31 respectively */ #define PC_MDIO ((uint)0x00000002) #define PC_MDCK ((uint)0x00000001) +#elif defined(CONFIG_ADS8272) +#define PC_MDIO ((uint)0x00002000) +#define PC_MDCK ((uint)0x00001000) #else #define PC_MDIO ((uint)0x00000004) #define PC_MDCK ((uint)0x00000020) @@ -255,7 +268,7 @@ #ifdef CONFIG_FCC1_ENET { 0, CPM_CR_FCC1_SBLOCK, CPM_CR_FCC1_PAGE, PROFF_FCC1, SIU_INT_FCC1, (PC_F1RXCLK | PC_F1TXCLK), CMX1_CLK_ROUTE, CMX1_CLK_MASK, -# if defined(CONFIG_TQM8260) +# if defined(CONFIG_TQM8260) || defined(CONFIG_ADS8272) PC_MDIO, PC_MDCK }, # else 0x00000004, 0x00000100 }, @@ -264,7 +277,7 @@ #ifdef CONFIG_FCC2_ENET { 1, CPM_CR_FCC2_SBLOCK, CPM_CR_FCC2_PAGE, PROFF_FCC2, SIU_INT_FCC2, (PC_F2RXCLK | PC_F2TXCLK), CMX2_CLK_ROUTE, CMX2_CLK_MASK, -# if defined(CONFIG_TQM8260) +# if defined(CONFIG_TQM8260) || defined(CONFIG_ADS8272) PC_MDIO, PC_MDCK }, # elif defined(CONFIG_EST8260) || defined(CONFIG_ADS8260) 0x00400000, 0x00200000 }, @@ -275,7 +288,7 @@ #ifdef CONFIG_FCC3_ENET { 2, CPM_CR_FCC3_SBLOCK, CPM_CR_FCC3_PAGE, PROFF_FCC3, SIU_INT_FCC3, (PC_F3RXCLK | PC_F3TXCLK), CMX3_CLK_ROUTE, CMX3_CLK_MASK, -# if defined(CONFIG_TQM8260) +# if defined(CONFIG_TQM8260) || defined(CONFIG_ADS8272) PC_MDIO, PC_MDCK }, # else 0x00000001, 0x00000040 }, @@ -331,12 +344,12 @@ }; static void init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep, - volatile immap_t *immap); + volatile cpm2_map_t *immap); static void init_fcc_startup(fcc_info_t *fip, struct net_device *dev); -static void init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, - volatile immap_t *immap); +static void init_fcc_ioports(fcc_info_t *fip, volatile iop_cpm2_t *io, + volatile cpm2_map_t *immap); static void init_fcc_param(fcc_info_t *fip, struct net_device *dev, - volatile immap_t *immap); + volatile cpm2_map_t *immap); #ifdef CONFIG_USE_MDIO static int mii_queue(struct net_device *dev, int request, void (*func)(uint, struct net_device *)); @@ -586,7 +599,7 @@ } if (must_restart) { - volatile cpm8260_t *cp; + volatile cpm_cpm2_t *cp; /* Some transmit errors cause the transmitter to shut * down. We now issue a restart transmit. Since the @@ -1052,6 +1065,75 @@ #endif /* CONFIG_FEC_QS6612 */ +/* ------------------------------------------------------------------------- */ +/* The Davicom DM9131 is used on the HYMOD board */ + +#ifdef CONFIG_FCC_DM9131 + +/* register definitions */ + +#define MII_DM9131_ACR 16 /* Aux. Config Register */ +#define MII_DM9131_ACSR 17 /* Aux. Config/Status Register */ +#define MII_DM9131_10TCSR 18 /* 10BaseT Config/Status Reg. */ +#define MII_DM9131_INTR 21 /* Interrupt Register */ +#define MII_DM9131_RECR 22 /* Receive Error Counter Reg. */ +#define MII_DM9131_DISCR 23 /* Disconnect Counter Register */ + +static void mii_parse_dm9131_acsr(uint mii_reg, struct net_device *dev) +{ + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; + + s &= ~(PHY_STAT_SPMASK); + + switch ((mii_reg >> 12) & 0xf) { + case 1: s |= PHY_STAT_10HDX; break; + case 2: s |= PHY_STAT_10FDX; break; + case 4: s |= PHY_STAT_100HDX; break; + case 8: s |= PHY_STAT_100FDX; break; + } + + fep->phy_status = s; +} + +static phy_info_t phy_info_dm9131 = { + 0x00181b80, + "DM9131", + + (const phy_cmd_t []) { /* config */ + /* parse cr and anar to get some info */ + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup - enable interrupts */ + { mk_mii_write(MII_DM9131_INTR, 0x0002), NULL }, + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + + /* we need to read INTR, SR and ANER to acknowledge */ + + { mk_mii_read(MII_DM9131_INTR), NULL }, + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_REG_ANER), NULL }, + + /* read acsr to get info */ + + { mk_mii_read(MII_DM9131_ACSR), mii_parse_dm9131_acsr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_write(MII_DM9131_INTR, 0x0f00), NULL }, + { mk_mii_end, } + }, +}; + + +#endif /* CONFIG_FEC_DM9131 */ + + static phy_info_t *phy_info[] = { #ifdef CONFIG_FCC_LXT970 @@ -1064,7 +1146,11 @@ #ifdef CONFIG_FCC_QS6612 &phy_info_qs6612, -#endif /* CONFIG_FEC_LXT971 */ +#endif /* CONFIG_FEC_QS6612 */ + +#ifdef CONFIG_FCC_DM9131 + &phy_info_dm9131, +#endif /* CONFIG_FEC_DM9131 */ NULL }; @@ -1361,10 +1447,10 @@ struct fcc_enet_private *cep; fcc_info_t *fip; int i, np, err; - volatile immap_t *immap; - volatile iop8260_t *io; + volatile cpm2_map_t *immap; + volatile iop_cpm2_t *io; - immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ + immap = (cpm2_map_t *)CPM_MAP_ADDR; /* and to internal registers */ io = &immap->im_ioport; np = sizeof(fcc_ports) / sizeof(fcc_info_t); @@ -1431,7 +1517,7 @@ */ static void __init init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep, - volatile immap_t *immap) + volatile cpm2_map_t *immap) { volatile fcc_enet_t *ep; volatile fcc_t *fccp; @@ -1454,8 +1540,8 @@ /* Initialize the I/O pins for the FCC Ethernet. */ static void __init -init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, - volatile immap_t *immap) +init_fcc_ioports(fcc_info_t *fip, volatile iop_cpm2_t *io, + volatile cpm2_map_t *immap) { /* FCC1 pins are on port A/C. FCC2/3 are port B/C. @@ -1513,7 +1599,7 @@ static void __init init_fcc_param(fcc_info_t *fip, struct net_device *dev, - volatile immap_t *immap) + volatile cpm2_map_t *immap) { unsigned char *eap; unsigned long mem_addr; @@ -1522,7 +1608,7 @@ struct fcc_enet_private *cep; volatile fcc_enet_t *ep; volatile cbd_t *bdp; - volatile cpm8260_t *cp; + volatile cpm_cpm2_t *cp; cep = (struct fcc_enet_private *)(dev->priv); ep = cep->ep; @@ -1535,28 +1621,15 @@ */ memset((char *)ep, 0, sizeof(fcc_enet_t)); - /* Allocate space for the buffer descriptors in the DP ram. - * These are relative offsets in the DP ram address space. + /* Allocate space for the buffer descriptors from regular memory. * Initialize base addresses for the buffer descriptors. */ -#if 0 - /* I really want to do this, but for some reason it doesn't - * work with the data cache enabled, so I allocate from the - * main memory instead. - */ - i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); - ep->fen_genfcc.fcc_rbase = (uint)&immap->im_dprambase[i]; - cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i]; - - i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); - ep->fen_genfcc.fcc_tbase = (uint)&immap->im_dprambase[i]; - cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i]; -#else - cep->rx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); + cep->rx_bd_base = (cbd_t *)kmalloc(sizeof(cbd_t) * RX_RING_SIZE, + GFP_KERNEL | GFP_DMA); ep->fen_genfcc.fcc_rbase = __pa(cep->rx_bd_base); - cep->tx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); + cep->tx_bd_base = (cbd_t *)kmalloc(sizeof(cbd_t) * TX_RING_SIZE, + GFP_KERNEL | GFP_DMA); ep->fen_genfcc.fcc_tbase = __pa(cep->tx_bd_base); -#endif cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; cep->cur_rx = cep->rx_bd_base; @@ -1773,11 +1846,11 @@ */ fccp->fcc_fpsmr = FCC_PSMR_ENCRC; -#ifdef CONFIG_ADS8260 +#ifdef CONFIG_PQ2ADS /* Enable the PHY. */ - ads_csr_addr[1] |= BCSR1_FETH_RST; /* Remove reset */ - ads_csr_addr[1] &= ~BCSR1_FETHIEN; /* Enable */ + *(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_FETHIEN; + *(volatile uint *)(BCSR_ADDR + 4) |= BCSR1_FETH_RST; #endif #if defined(CONFIG_USE_MDIO) || defined(CONFIG_TQM8260) @@ -1817,10 +1890,10 @@ { uint retval; int read_op, i, off; - volatile immap_t *immap; - volatile iop8260_t *io; + volatile cpm2_map_t *immap; + volatile iop_cpm2_t *io; - immap = (immap_t *)IMAP_ADDR; + immap = (cpm2_map_t *)CPM_MAP_ADDR; io = &immap->im_ioport; io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck); diff -Nru a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c --- a/arch/ppc/8260_io/uart.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,3061 +0,0 @@ -/* - * UART driver for MPC8260 CPM SCC or SMC - * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) - * Copyright (c) 2000 MontaVista Software, Inc. (source@mvista.com) - * 2.3.99 updates - * Copyright (c) 2002 Allen Curtis, Ones and Zeros, Inc. (acurtis@onz.com) - * 2.5.50 updates - * Fix the console driver to be registered with initcalls and some minor fixup - * for 2.6.2, by Petter Larsen, moreCom as (petter.larsen@morecom.no) and - * Miguel Valero, AxxessIT ASA (miguel.valero@axxessit.no) - * - * I used the 8xx uart.c driver as the framework for this driver. - * The original code was written for the EST8260 board. I tried to make - * it generic, but there may be some assumptions in the structures that - * have to be fixed later. - * - * The 8xx and 8260 are similar, but not identical. Over time we - * could probably merge these two drivers. - * To save porting time, I did not bother to change any object names - * that are not accessed outside of this file. - * It still needs lots of work........When it was easy, I included code - * to support the SCCs. - * Only the SCCs support modem control, so that is not complete either. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_MAGIC_SYSRQ -#include -#endif - -#ifdef CONFIG_SERIAL_CONSOLE -#include - -/* SCC Console configuration. Not quite finished. The SCC_CONSOLE - * should be the number of the SCC to use, but only SCC1 will - * work at this time. - */ -#ifdef CONFIG_SCC_CONSOLE -#define SCC_CONSOLE 1 -#endif - -/* this defines the index into rs_table for the port to use -*/ -#ifndef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 0 -#endif -#endif -#define CONFIG_SERIAL_CONSOLE_PORT 0 - -#define TX_WAKEUP ASYNC_SHARE_IRQ - -static char *serial_name = "CPM UART driver"; -static char *serial_version = "0.02"; - -static struct tty_driver *serial_driver; -static int __init serial_console_setup( struct console *co, char *options); -static void serial_console_write(struct console *c, const char *s, - unsigned count); - -static struct tty_driver *serial_console_device(struct console *c, int *index); - -#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -static unsigned long break_pressed; /* break, really ... */ -#endif - -/* - * Serial driver configuration section. Here are the various options: - */ -#define SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - -#define _INLINE_ inline - -#define DBG_CNT(s) - -/* We overload some of the items in the data structure to meet our - * needs. For example, the port address is the CPM parameter ram - * offset for the SCC or SMC. The maximum number of ports is 4 SCCs and - * 2 SMCs. The "hub6" field is used to indicate the channel number, with - * 0 and 1 indicating the SMCs and 2, 3, 4, and 5 are the SCCs. - * Since these ports are so versatile, I don't yet have a strategy for - * their management. For example, SCC1 is used for Ethernet. Right - * now, just don't put them in the table. Of course, right now I just - * want the SMC to work as a uart :-).. - * The "type" field is currently set to 0, for PORT_UNKNOWN. It is - * not currently used. I should probably use it to indicate the port - * type of CMS or SCC. - * The SMCs do not support any modem control signals. - */ -#define smc_scc_num hub6 - -/* The choice of serial port to use for KGDB. If the system has - * two ports, you can use one for console and one for KGDB (which - * doesn't make sense to me, but people asked for it). - */ -#ifdef CONFIG_KGDB_TTYS1 -#define KGDB_SER_IDX 1 /* SCC2/SMC2 */ -#else -#define KGDB_SER_IDX 0 /* SCC1/SMC1 */ -#endif - -#ifndef SCC_CONSOLE - -/* SMC2 is sometimes used for low performance TDM interfaces. Define - * this as 1 if you want SMC2 as a serial port UART managed by this driver. - * Define this as 0 if you wish to use SMC2 for something else. - */ -#define USE_SMC2 1 - -/* Define SCC to ttySx mapping. -*/ -#define SCC_NUM_BASE (USE_SMC2 + 1) /* SCC base tty "number" */ - -/* Define which SCC is the first one to use for a serial port. These - * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used - * for Ethernet, and the first available SCC for serial UART is SCC2. - * NOTE: IF YOU CHANGE THIS, you have to change the PROFF_xxx and - * interrupt vectors in the table below to match. - */ -#define SCC_IDX_BASE 1 /* table index */ - -static struct serial_state rs_table[] = { - /* UART CLK PORT IRQ FLAGS NUM */ - { 0, 0, PROFF_SMC1, SIU_INT_SMC1, 0, 0 }, /* SMC1 ttyS0 */ -#ifdef USE_SMC2 - { 0, 0, PROFF_SMC2, SIU_INT_SMC2, 0, 1 }, /* SMC2 ttyS1 */ -#endif -#ifndef CONFIG_SCC1_ENET - { 0, 0, PROFF_SCC1, SIU_INT_SCC1, 0, SCC_NUM_BASE}, /* SCC1 ttyS2 */ -#endif -#if !defined(CONFIG_SBC82xx) && !defined(CONFIG_SCC2_ENET) - { 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE + 1}, /* SCC2 ttyS3 */ -#endif -}; - -#else /* SCC_CONSOLE */ -#define SCC_NUM_BASE 0 /* SCC base tty "number" */ -#define SCC_IDX_BASE 0 /* table index */ -static struct serial_state rs_table[] = { - /* UART CLK PORT IRQ FLAGS NUM */ - { 0, 0, PROFF_SCC1, SIU_INT_SCC1, 0, SCC_NUM_BASE}, /* SCC1 ttyS2 */ - { 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE + 1}, /* SCC2 ttyS3 */ -}; -#endif /* SCC_CONSOLE */ - -#define PORT_NUM(P) (((P) < (SCC_NUM_BASE)) ? (P) : (P)-(SCC_NUM_BASE)) - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -/* The number of buffer descriptors and their sizes. -*/ -#define RX_NUM_FIFO 4 -#define RX_BUF_SIZE 32 -#define TX_NUM_FIFO 4 -#define TX_BUF_SIZE 32 - -/* The async_struct in serial.h does not really give us what we - * need, so define our own here. - */ -typedef struct serial_info { - int magic; - int flags; - struct serial_state *state; - struct tty_struct *tty; - int read_status_mask; - int ignore_status_mask; - int timeout; - int line; - int x_char; /* xon/xoff character */ - int close_delay; - unsigned short closing_wait; - unsigned short closing_wait2; - unsigned long event; - unsigned long last_active; - int blocked_open; /* # of blocked opens */ - struct work_struct tqueue; - struct work_struct tqueue_hangup; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - - /* CPM Buffer Descriptor pointers. - */ - cbd_t *rx_bd_base; - cbd_t *rx_cur; - cbd_t *tx_bd_base; - cbd_t *tx_cur; -} ser_info_t; - -static struct console sercons = { - .name = "ttyS", - .write = serial_console_write, - .device = serial_console_device, - .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = CONFIG_SERIAL_CONSOLE_PORT, -}; - -static void change_speed(ser_info_t *info); -static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout); - -static inline int serial_paranoia_check(ser_info_t *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* - * This is used to figure out the divisor speeds and the timeouts, - * indexed by the termio value. The generic CPM functions are responsible - * for setting and assigning baud rate generators for us. - */ -static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 }; - - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_8xx_stop(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile scc_t *sccp; - volatile smc_t *smcp; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - save_flags(flags); cli(); - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - smcp->smc_smcm &= ~SMCM_TX; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~UART_SCCM_TX; - } - restore_flags(flags); -} - -static void rs_8xx_start(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile scc_t *sccp; - volatile smc_t *smcp; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - save_flags(flags); cli(); - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - smcp->smc_smcm |= SMCM_TX; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm |= UART_SCCM_TX; - } - restore_flags(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(ser_info_t *info, - int event) -{ - info->event |= 1 << event; - schedule_work(&info->tqueue); -} - -static _INLINE_ void receive_chars(ser_info_t *info, struct pt_regs *regs) -{ - struct tty_struct *tty = info->tty; - unsigned char ch, *cp; - /*int ignored = 0;*/ - int i; - ushort status; - struct async_icount *icount; - volatile cbd_t *bdp; - - icount = &info->state->icount; - - /* Just loop through the closed BDs and copy the characters into - * the buffer. - */ - bdp = info->rx_cur; - for (;;) { - if (bdp->cbd_sc & BD_SC_EMPTY) /* If this one is empty */ - break; /* we are all done */ - - /* The read status mask tell us what we should do with - * incoming characters, especially if errors occur. - * One special case is the use of BD_SC_EMPTY. If - * this is not set, we are supposed to be ignoring - * inputs. In this case, just mark the buffer empty and - * continue. - if (!(info->read_status_mask & BD_SC_EMPTY)) { - bdp->cbd_sc |= BD_SC_EMPTY; - bdp->cbd_sc &= - ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - continue; - } - */ - - /* Get the number of characters and the buffer pointer. - */ - i = bdp->cbd_datlen; - cp = (unsigned char *)__va(bdp->cbd_bufaddr); - status = bdp->cbd_sc; -#ifdef CONFIG_KGDB - if (info->state->smc_scc_num == KGDB_SER_IDX) { - if (*cp == 0x03 || *cp == '$') - breakpoint(); - return; - } -#endif - - /* Check to see if there is room in the tty buffer for - * the characters in our BD buffer. If not, we exit - * now, leaving the BD with the characters. We'll pick - * them up again on the next receive interrupt (which could - * be a timeout). - */ - if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) - break; - - while (i-- > 0) { - ch = *cp++; - *tty->flip.char_buf_ptr = ch; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, *status); -#endif - *tty->flip.flag_buf_ptr = 0; - if (status & (BD_SC_BR | BD_SC_FR | - BD_SC_PR | BD_SC_OV)) { - /* - * For statistics only - */ - if (status & BD_SC_BR) - icount->brk++; - else if (status & BD_SC_PR) - icount->parity++; - else if (status & BD_SC_FR) - icount->frame++; - if (status & BD_SC_OV) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - if (status & info->ignore_status_mask) { - if (++ignored > 100) - break; - continue; - } - */ - status &= info->read_status_mask; - - if (status & (BD_SC_BR)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (status & BD_SC_PR) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (status & BD_SC_FR) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (status & BD_SC_OV) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - if (tty->flip.count < TTY_FLIPBUF_SIZE) { - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = - TTY_OVERRUN; - } - } - } - -#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (break_pressed && info->line == sercons.index) { - if (ch != 0 && time_before(jiffies, - break_pressed + HZ*5)) { - handle_sysrq(ch, regs, NULL); - break_pressed = 0; - goto ignore_char; - } else - break_pressed = 0; - } -#endif - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - } - -#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - ignore_char: -#endif - - /* This BD is ready to be used again. Clear status. - * Get next BD. - */ - bdp->cbd_sc |= BD_SC_EMPTY; - bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - } - - info->rx_cur = (cbd_t *)bdp; - - schedule_delayed_work(&tty->flip.work, 1); -} - -static _INLINE_ void receive_break(ser_info_t *info, struct pt_regs *regs) -{ - struct tty_struct *tty = info->tty; - - info->state->icount.brk++; - -#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (info->line == sercons.index) { - if (!break_pressed) { - break_pressed = jiffies; - return; - } else - break_pressed = 0; - } -#endif - - /* Check to see if there is room in the tty buffer for - * the break. If not, we exit now, losing the break. FIXME - */ - if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE) - return; - *(tty->flip.flag_buf_ptr++) = TTY_BREAK; - *(tty->flip.char_buf_ptr++) = 0; - tty->flip.count++; -} - - -static _INLINE_ void transmit_chars(ser_info_t *info, struct pt_regs *regs) -{ - - if (info->flags & TX_WAKEUP) { - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - } - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif -} - -#ifdef notdef - /* I need to do this for the SCCs, so it is left as a reminder. - */ -static _INLINE_ void check_modem_status(struct async_struct *info) -{ - int status; - struct async_icount *icount; - - status = serial_in(info, UART_MSR); - - if (status & UART_MSR_ANY_DELTA) { - icount = &info->state->icount; - /* update input line counters */ - if (status & UART_MSR_TERI) - icount->rng++; - if (status & UART_MSR_DDSR) - icount->dsr++; - if (status & UART_MSR_DDCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - (status & UART_MSR_DCD)) - hardpps(); -#endif - } - if (status & UART_MSR_DCTS) - icount->cts++; - wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) - wake_up_interruptible(&info->open_wait); - else { -#ifdef SERIAL_DEBUG_OPEN - printk("scheduling hangup..."); -#endif - schedule_work(&info->tqueue_hangup); - } - } - if (info->flags & ASYNC_CTS_FLOW) { - if (info->tty->hw_stopped) { - if (status & UART_MSR_CTS) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if (!(status & UART_MSR_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - } - } -} -#endif - -/* - * This is the serial driver's interrupt routine for a single port - */ -static irqreturn_t rs_8xx_interrupt(int irq, void * dev_id, struct pt_regs * regs) -{ - u_char events; - int idx; - ser_info_t *info; - volatile smc_t *smcp; - volatile scc_t *sccp; - - info = (ser_info_t *)dev_id; - - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - events = smcp->smc_smce; - if (events & SMCM_BRKE) - receive_break(info, regs); - if (events & SMCM_RX) - receive_chars(info, regs); - if (events & SMCM_TX) - transmit_chars(info, regs); - smcp->smc_smce = events; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - events = sccp->scc_scce; - if (events & SMCM_BRKE) - receive_break(info, regs); - if (events & SCCM_RX) - receive_chars(info, regs); - if (events & SCCM_TX) - transmit_chars(info, regs); - sccp->scc_scce = events; - } - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d, %x)...", - info->state->smc_scc_num, events); -#endif -#ifdef modem_control - check_modem_status(info); -#endif - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif - return IRQ_HANDLED; -} - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_softint(void *private_) -{ - ser_info_t *info = (ser_info_t *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); - } -} - -/* - * This routine is called from the scheduler work queue when the interrupt - * routine has signalled that a hangup has occurred. The path of - * hangup processing is: - * - * serial interrupt routine -> (scheduler tqueue) -> - * do_serial_hangup() -> tty->hangup() -> rs_hangup() - * - */ -static void do_serial_hangup(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (tty) - tty_hangup(tty); -} - -/*static void rs_8xx_timer(void) -{ - printk("rs_8xx_timer\n"); -}*/ - - -static int startup(ser_info_t *info) -{ - unsigned long flags; - int retval=0; - int idx; - struct serial_state *state= info->state; - volatile smc_t *smcp; - volatile scc_t *sccp; - volatile smc_uart_t *up; - volatile scc_uart_t *scup; - - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - goto errout; - } - -#ifdef maybe - if (!state->port || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - goto errout; - } -#endif - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - -#ifdef modem_control - info->MCR = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; -#endif - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - - /* - * and set the speed of the serial port - */ - change_speed(info); - - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - - /* Enable interrupts and I/O. - */ - smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); - - /* We can tune the buffer length and idle characters - * to take advantage of the entire incoming buffer size. - * If mrblr is something other than 1, maxidl has to be - * non-zero or we never get an interrupt. The maxidl - * is the number of character times we wait after reception - * of the last character before we decide no more characters - * are coming. - */ - up = (smc_uart_t *)&immr->im_dprambase[state->port]; -#if 0 - up->smc_mrblr = 1; /* receive buffer length */ - up->smc_maxidl = 0; /* wait forever for next char */ -#else - up->smc_mrblr = RX_BUF_SIZE; - up->smc_maxidl = RX_BUF_SIZE; -#endif - up->smc_brkcr = 1; /* number of break chars */ - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - scup = (scc_uart_t *)&immr->im_dprambase[state->port]; -#if 0 - scup->scc_genscc.scc_mrblr = 1; /* receive buffer length */ - scup->scc_maxidl = 0; /* wait forever for next char */ -#else - scup->scc_genscc.scc_mrblr = RX_BUF_SIZE; - scup->scc_maxidl = RX_BUF_SIZE; -#endif - - sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX); - sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - } - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(ser_info_t * info) -{ - unsigned long flags; - struct serial_state *state; - int idx; - volatile smc_t *smcp; - volatile scc_t *sccp; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - - /* Disable interrupts and I/O. - */ - smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); -#ifdef CONFIG_SERIAL_CONSOLE - /* We can't disable the transmitter if this is the - * system console. - */ - if (idx != CONFIG_SERIAL_CONSOLE_PORT) -#endif - smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); -#ifdef CONFIG_SERIAL_CONSOLE - if (idx != CONFIG_SERIAL_CONSOLE_PORT) - sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); -#endif - } - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(ser_info_t *info) -{ - int baud_rate; - unsigned cflag, cval, scval, prev_mode; - int i, bits, sbits, idx; - unsigned long flags; - volatile smc_t *smcp; - volatile scc_t *sccp; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - - /* Character length programmed into the mode register is the - * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, - * 1 or 2 stop bits, minus 1. - * The value 'bits' counts this for us. - */ - cval = 0; - scval = 0; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: bits = 5; break; - case CS6: bits = 6; break; - case CS7: bits = 7; break; - case CS8: bits = 8; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: bits = 8; break; - } - sbits = bits - 5; - - if (cflag & CSTOPB) { - cval |= SMCMR_SL; /* Two stops */ - scval |= SCU_PMSR_SL; - bits++; - } - if (cflag & PARENB) { - cval |= SMCMR_PEN; - scval |= SCU_PMSR_PEN; - bits++; - } - if (!(cflag & PARODD)) { - cval |= SMCMR_PM_EVEN; - scval |= (SCU_PMSR_REVP | SCU_PMSR_TEVP); - } - - /* Determine divisor based on baud rate */ - i = cflag & CBAUD; - if (i >= (sizeof(baud_table)/sizeof(int))) - baud_rate = 9600; - else - baud_rate = baud_table[i]; - - info->timeout = (TX_BUF_SIZE*HZ*bits); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - -#ifdef modem_control - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - if (info->flags & ASYNC_HARDPPS_CD) - info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - } else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else { - info->flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - serial_out(info, UART_IER, info->IER); -#endif - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); - if (I_INPCK(info->tty)) - info->read_status_mask |= BD_SC_FR | BD_SC_PR; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= BD_SC_BR; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= BD_SC_PR | BD_SC_FR; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= BD_SC_BR; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= BD_SC_OV; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->read_status_mask &= ~BD_SC_EMPTY; - save_flags(flags); cli(); - - /* Start bit has not been added (so don't, because we would just - * subtract it later), and we need to add one for the number of - * stops bits (there is always at least one). - */ - bits++; - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - - /* Set the mode register. We want to keep a copy of the - * enables, because we want to put them back if they were - * present. - */ - prev_mode = smcp->smc_smcmr; - smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; - smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_pmsr = (sbits << 12) | scval; - } - - m8260_cpm_setbrg(info->state->smc_scc_num, baud_rate); - - restore_flags(flags); -} - -static void rs_8xx_put_char(struct tty_struct *tty, unsigned char ch) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile cbd_t *bdp; - - if (serial_paranoia_check(info, tty->name, "rs_put_char")) - return; - - if (!tty) - return; - - bdp = info->tx_cur; - while (bdp->cbd_sc & BD_SC_READY); - - *((char *)__va(bdp->cbd_bufaddr)) = ch; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (cbd_t *)bdp; - -} - -static int rs_8xx_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile cbd_t *bdp; - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!tty) - return 0; - - bdp = info->tx_cur; - - while (1) { - c = min(count, TX_BUF_SIZE); - - if (c <= 0) - break; - - if (bdp->cbd_sc & BD_SC_READY) { - info->flags |= TX_WAKEUP; - break; - } - - if (from_user) { - if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) { - if (!ret) - ret = -EFAULT; - break; - } - } else { - memcpy(__va(bdp->cbd_bufaddr), buf, c); - } - - bdp->cbd_datlen = c; - bdp->cbd_sc |= BD_SC_READY; - - buf += c; - count -= c; - ret += c; - - /* Get next BD. - */ - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - info->tx_cur = (cbd_t *)bdp; - } - return ret; -} - -static int rs_8xx_write_room(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - - if ((info->tx_cur->cbd_sc & BD_SC_READY) == 0) { - info->flags &= ~TX_WAKEUP; - ret = TX_BUF_SIZE; - } - else { - info->flags |= TX_WAKEUP; - ret = 0; - } - return ret; -} - -/* I could track this with transmit counters....maybe later. -*/ -static int rs_8xx_chars_in_buffer(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return 0; -} - -static void rs_8xx_flush_buffer(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - - /* There is nothing to "flush", whatever we gave the CPM - * is on its way out. - */ - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - info->flags &= ~TX_WAKEUP; -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_8xx_send_xchar(struct tty_struct *tty, char ch) -{ - volatile cbd_t *bdp; - - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_send_char")) - return; - - bdp = info->tx_cur; - while (bdp->cbd_sc & BD_SC_READY); - - *((char *)__va(bdp->cbd_bufaddr)) = ch; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (cbd_t *)bdp; -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_8xx_throttle(struct tty_struct * tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_8xx_send_xchar(tty, STOP_CHAR(tty)); - -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; - - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); -#endif -} - -static void rs_8xx_unthrottle(struct tty_struct * tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_8xx_send_xchar(tty, START_CHAR(tty)); - } -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -#ifdef maybe -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned char status; - unsigned int result; - - cli(); - status = serial_in(info, UART_LSR); - sti(); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - return put_user(result,value); -} -#endif - -static int get_modem_info(ser_info_t *info, unsigned int *value) -{ - unsigned int result = 0; -#ifdef modem_control - unsigned char control, status; - - control = info->MCR; - cli(); - status = serial_in(info, UART_MSR); - sti(); - result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) - | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) -#ifdef TIOCM_OUT1 - | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) - | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) -#endif - | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) - | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) - | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) - | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); -#endif - return put_user(result,value); -} - -static int set_modem_info(ser_info_t *info, unsigned int cmd, - unsigned int *value) -{ - int error; - unsigned int arg; - - error = get_user(arg, value); - if (error) - return error; -#ifdef modem_control - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - info->MCR |= UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR |= UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR |= UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR |= UART_MCR_OUT2; -#endif - break; - case TIOCMBIC: - if (arg & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR &= ~UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR &= ~UART_MCR_OUT2; -#endif - break; - case TIOCMSET: - info->MCR = ((info->MCR & ~(UART_MCR_RTS | -#ifdef TIOCM_OUT1 - UART_MCR_OUT1 | - UART_MCR_OUT2 | -#endif - UART_MCR_DTR)) - | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) -#ifdef TIOCM_OUT1 - | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) - | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) -#endif - | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); - break; - default: - return -EINVAL; - } - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); -#endif - return 0; -} - -/* Sending a break is a two step process on the SMC/SCC. It is accomplished - * by sending a STOP TRANSMIT command followed by a RESTART TRANSMIT - * command. We take advantage of the begin/end functions to make this - * happen. - */ -static void begin_break(ser_info_t *info) -{ - volatile cpm8260_t *cp; - uint page, sblock; - int num; - - cp = cpmp; - - if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) { - if (num == 0) { - page = CPM_CR_SMC1_PAGE; - sblock = CPM_CR_SMC1_SBLOCK; - } - else { - page = CPM_CR_SMC2_PAGE; - sblock = CPM_CR_SMC2_SBLOCK; - } - } - else { - num -= SCC_NUM_BASE; - switch (num) { - case 0: - page = CPM_CR_SCC1_PAGE; - sblock = CPM_CR_SCC1_SBLOCK; - break; - case 1: - page = CPM_CR_SCC2_PAGE; - sblock = CPM_CR_SCC2_SBLOCK; - break; - case 2: - page = CPM_CR_SCC3_PAGE; - sblock = CPM_CR_SCC3_SBLOCK; - break; - case 3: - page = CPM_CR_SCC4_PAGE; - sblock = CPM_CR_SCC4_SBLOCK; - break; - default: return; - } - } - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, CPM_CR_STOP_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); -} - -static void end_break(ser_info_t *info) -{ - volatile cpm8260_t *cp; - uint page, sblock; - int num; - - cp = cpmp; - - if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) { - if (num == 0) { - page = CPM_CR_SMC1_PAGE; - sblock = CPM_CR_SMC1_SBLOCK; - } - else { - page = CPM_CR_SMC2_PAGE; - sblock = CPM_CR_SMC2_SBLOCK; - } - } - else { - num -= SCC_NUM_BASE; - switch (num) { - case 0: - page = CPM_CR_SCC1_PAGE; - sblock = CPM_CR_SCC1_SBLOCK; - break; - case 1: - page = CPM_CR_SCC2_PAGE; - sblock = CPM_CR_SCC2_SBLOCK; - break; - case 2: - page = CPM_CR_SCC3_PAGE; - sblock = CPM_CR_SCC3_SBLOCK; - break; - case 3: - page = CPM_CR_SCC4_PAGE; - sblock = CPM_CR_SCC4_SBLOCK; - break; - default: return; - } - } - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, CPM_CR_RESTART_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); -} - -/* - * This routine sends a break character out the serial port. - */ -static void send_break(ser_info_t *info, int duration) -{ - current->state = TASK_INTERRUPTIBLE; -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("rs_send_break(%d) jiff=%lu...", duration, jiffies); -#endif - begin_break(info); - schedule_timeout(duration); - end_break(info); -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("done jiffies=%lu\n", jiffies); -#endif -} - - -static int rs_8xx_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - int error; - ser_info_t *info = (ser_info_t *)tty->driver_data; - int retval; - struct async_icount cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TCSBRK: /* SVID version: non-zero arg --> no break */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; - if (!arg) { - send_break(info, HZ/4); /* 1/4 second */ - if (signal_pending(current)) - return -EINTR; - } - return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; - send_break(info, arg ? arg*(HZ/10) : HZ/4); - if (signal_pending(current)) - return -EINTR; - return 0; - case TIOCSBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - begin_break(info); - return 0; - case TIOCCBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - end_break(info); - return 0; - case TIOCGSOFTCAR: - return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); - case TIOCSSOFTCAR: - error = get_user(arg, (unsigned int *) arg); - if (error) - return error; - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); - return 0; - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); -#ifdef maybe - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); -#endif - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: -#ifdef modem_control - cli(); - /* note the counters on entry */ - cprev = info->state->icount; - sti(); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - cli(); - cnow = info->state->icount; /* atomic copy */ - sti(); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ -#else - return 0; -#endif - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - cli(); - cnow = info->state->icount; - sti(); - p_cuser = (struct serial_icounter_struct *) arg; - error = put_user(cnow.cts, &p_cuser->cts); - if (error) return error; - error = put_user(cnow.dsr, &p_cuser->dsr); - if (error) return error; - error = put_user(cnow.rng, &p_cuser->rng); - if (error) return error; - error = put_user(cnow.dcd, &p_cuser->dcd); - if (error) return error; - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -/* FIX UP modem control here someday...... -*/ -static void rs_8xx_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if ( (tty->termios->c_cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_speed(info); - -#ifdef modem_control - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(tty->termios->c_cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (tty->termios->c_cflag & CBAUD)) { - info->MCR |= UART_MCR_DTR; - if (!tty->hw_stopped || - !(tty->termios->c_cflag & CRTSCTS)) { - info->MCR |= UART_MCR_RTS; - } - cli(); - serial_out(info, UART_MCR, info->MCR); - sti(); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_8xx_start(tty); - } -#endif - -#if 0 - /* - * No need to wake up processes in open wait, since they - * sample the CLOCAL flag once, and don't recheck it. - * XXX It's not clear whether the current behavior is correct - * or not. Hence, this may change..... - */ - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_8xx_close(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - int idx; - volatile smc_t *smcp; - volatile scc_t *sccp; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - state = info->state; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->read_status_mask &= ~BD_SC_EMPTY; - if (info->flags & ASYNC_INITIALIZED) { - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &immr->im_smc[idx]; - smcp->smc_smcm &= ~SMCM_RX; - smcp->smc_smcmr &= ~SMCMR_REN; - } - else { - sccp = &immr->im_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~UART_SCCM_RX; - sccp->scc_gsmrl &= ~SCC_GSMRL_ENR; - } - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_8xx_wait_until_sent(tty, info->timeout); - } - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - restore_flags(flags); -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned long orig_jiffies, char_time; - /*int lsr;*/ - volatile cbd_t *bdp; - - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) - return; - -#ifdef maybe - if (info->state->type == PORT_UNKNOWN) - return; -#endif - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = 1; - if (timeout) - char_time = min(char_time, (unsigned long)timeout); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - - /* We go through the loop at least once because we can't tell - * exactly when the last character exits the shifter. There can - * be at least two characters waiting to be sent after the buffers - * are empty. - */ - do { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - current->state = TASK_INTERRUPTIBLE; -/* current->dyn_prio = 0; make us low-priority */ - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - bdp = info->tx_cur; - } while (bdp->cbd_sc & BD_SC_READY); - current->state = TASK_RUNNING; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_8xx_hangup(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->name, "rs_hangup")) - return; - - state = info->state; - - rs_8xx_flush_buffer(tty); - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - ser_info_t *info) -{ -#ifdef DO_THIS_LATER - DECLARE_WAITQUEUE(wait, current); - struct serial_state *state = info->state; -#endif - int retval; - int do_clocal = 0; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - * If this is an SMC port, we don't have modem control to wait - * for, so just get out here. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR)) || - (info->state->smc_scc_num < SCC_NUM_BASE)) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; -#ifdef DO_THIS_LATER - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - cli(); - if (!tty_hung_up_p(filp)) - state->count--; - sti(); - info->blocked_open++; - while (1) { - cli(); - if (tty->termios->c_cflag & CBAUD) - serial_out(info, UART_MCR, - serial_inp(info, UART_MCR) | - (UART_MCR_DTR | UART_MCR_RTS)); - sti(); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CLOSING) && - (do_clocal || (serial_in(info, UART_MSR) & - UART_MSR_DCD))) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif -#endif /* DO_THIS_LATER */ - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, ser_info_t **ret_info) -{ - struct serial_state *sstate; - - sstate = rs_table + line; - if (sstate->info) { - sstate->count++; - *ret_info = (ser_info_t *)sstate->info; - return 0; - } - else { - return -ENOMEM; - } -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_8xx_open(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info; - int retval, line; - - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) - return -ENODEV; - retval = get_async_struct(line, &info); - if (retval) - return retval; - if (serial_paranoia_check(info, tty->name, "rs_open")) - return -ENODEV; - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s, count = %d\n", tty->name, info->state->count); -#endif - tty->driver_data = info; - info->tty = tty; - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) - return retval; - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s successful...", line); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ -#ifdef notdef - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; -#endif - int ret; - - ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", - state->line, - (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC", - (unsigned int)(state->port), state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - -#ifdef notdef - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->tty = 0; - } - cli(); - status = serial_in(info, UART_MSR); - control = info ? info->MCR : serial_in(info, UART_MCR); - sti(); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (control & UART_MCR_RTS) - strcat(stat_buf, "|RTS"); - if (status & UART_MSR_CTS) - strcat(stat_buf, "|CTS"); - if (control & UART_MCR_DTR) - strcat(stat_buf, "|DTR"); - if (status & UART_MSR_DSR) - strcat(stat_buf, "|DSR"); - if (status & UART_MSR_DCD) - strcat(stat_buf, "|CD"); - if (status & UART_MSR_RI) - strcat(stat_buf, "|RI"); - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - /* - * Last thing is the RS-232 status lines - */ - ret += sprintf(buf+ret, " %s\n", stat_buf+1); -#endif - return ret; -} - -int rs_8xx_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - len += line_info(page + len, &rs_table[i]); - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (begin-off); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s\n", serial_name, serial_version); -} - - -/* - * The serial console driver used during boot. Note that these names - * clash with those found in "serial.c", so we currently can't support - * the 16xxx uarts and these at the same time. I will fix this to become - * an indirect function call from tty_io.c (or something). - */ - -#ifdef CONFIG_SERIAL_CONSOLE - -/* - * Print a string to the serial port trying not to disturb any possible - * real use of the port... - * These funcitons work equally well for SCC, even though they are - * designed for SMC. Our only interests are the transmit/receive - * buffers, which are identically mapped for either the SCC or SMC. - */ -static void my_console_write(int idx, const char *s, - unsigned count) -{ - struct serial_state *ser; - ser_info_t *info; - unsigned i; - volatile cbd_t *bdp, *bdbase; - volatile smc_uart_t *up; - volatile u_char *cp; - - ser = rs_table + idx; - - /* If the port has been initialized for general use, we have - * to use the buffer descriptors allocated there. Otherwise, - * we simply use the single buffer allocated. - */ - if ((info = (ser_info_t *)ser->info) != NULL) { - bdp = info->tx_cur; - bdbase = info->tx_bd_base; - } - else { - /* Pointer to UART in parameter ram. - */ - up = (smc_uart_t *)&immr->im_dprambase[ser->port]; - - /* Get the address of the host memory buffer. - */ - bdp = bdbase = (cbd_t *)&immr->im_dprambase[up->smc_tbase]; - } - - /* - * We need to gracefully shut down the transmitter, disable - * interrupts, then send our bytes out. - */ - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, s++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while (bdp->cbd_sc & BD_SC_READY); - - /* Send the character out. - * If the buffer address is in the CPM DPRAM, don't - * convert it. - */ - if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) - cp = (u_char *)(bdp->cbd_bufaddr); - else - cp = __va(bdp->cbd_bufaddr); - *cp = *s; - - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*s == 10) { - while (bdp->cbd_sc & BD_SC_READY); - cp = __va(bdp->cbd_bufaddr); - *cp = 13; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - - if (bdp->cbd_sc & BD_SC_WRAP) { - bdp = bdbase; - } - else { - bdp++; - } - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while (bdp->cbd_sc & BD_SC_READY); - - if (info) - info->tx_cur = (cbd_t *)bdp; -} - -static void serial_console_write(struct console *c, const char *s, - unsigned count) -{ -#if defined(CONFIG_KGDB_CONSOLE) && !defined(CONFIG_USE_SERIAL2_KGDB) - /* Try to let stub handle output. Returns true if it did. */ - if (kgdb_output_string(s, count)) - return; -#endif - my_console_write(c->index, s, count); -} - -#ifdef CONFIG_XMON -int -xmon_8xx_write(const char *s, unsigned count) -{ - my_console_write(KGDB_SER_IDX, s, count); - return(count); -} -#endif - -#ifdef CONFIG_KGDB -void -putDebugChar(char ch) -{ - my_console_write(KGDB_SER_IDX, &ch, 1); -} -#endif - -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) -/* - * Receive character from the serial port. This only works well - * before the port is initialize for real use. - */ -static int my_console_wait_key(int idx, int xmon, char *obuf) -{ - struct serial_state *ser; - u_char c, *cp; - ser_info_t *info; - volatile cbd_t *bdp; - volatile smc_uart_t *up; - int i; - - ser = rs_table + idx; - - /* Pointer to UART in parameter ram. - */ - up = (smc_uart_t *)&immr->im_dprambase[ser->port]; - - /* Get the address of the host memory buffer. - * If the port has been initialized for general use, we must - * use information from the port structure. - */ - if ((info = (ser_info_t *)ser->info)) - bdp = info->rx_cur; - else - bdp = (cbd_t *)&immr->im_dprambase[up->smc_rbase]; - - /* - * We need to gracefully shut down the receiver, disable - * interrupts, then read the input. - * XMON just wants a poll. If no character, return -1, else - * return the character. - */ - if (!xmon) { - while (bdp->cbd_sc & BD_SC_EMPTY); - } - else { - if (bdp->cbd_sc & BD_SC_EMPTY) - return -1; - } - - /* If the buffer address is in the CPM DPRAM, don't - * convert it. - */ - if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) - cp = (u_char *)(bdp->cbd_bufaddr); - else - cp = __va(bdp->cbd_bufaddr); - - if (obuf) { - i = c = bdp->cbd_datlen; - while (i-- > 0) - *obuf++ = *cp++; - } - else { - c = *cp; - } - bdp->cbd_sc |= BD_SC_EMPTY; - - if (info) { - if (bdp->cbd_sc & BD_SC_WRAP) { - bdp = info->rx_bd_base; - } - else { - bdp++; - } - info->rx_cur = (cbd_t *)bdp; - } - - return((int)c); -} -#endif /* CONFIG_XMON || CONFIG_KGDB */ - -#ifdef CONFIG_XMON -int -xmon_8xx_read_poll(void) -{ - return(my_console_wait_key(KGDB_SER_IDX, 1, NULL)); -} - -int -xmon_8xx_read_char(void) -{ - return(my_console_wait_key(KGDB_SER_IDX, 0, NULL)); -} -#endif - -#ifdef CONFIG_KGDB -static char kgdb_buf[RX_BUF_SIZE], *kgdp; -static int kgdb_chars; - -char -getDebugChar(void) -{ - if (kgdb_chars <= 0) { - kgdb_chars = my_console_wait_key(KGDB_SER_IDX, 0, kgdb_buf); - kgdp = kgdb_buf; - } - kgdb_chars--; - - return(*kgdp++); -} - -void kgdb_interruptible(int yes) -{ - volatile smc_t *smcp; - - smcp = &immr->im_smc[KGDB_SER_IDX]; - - if (yes == 1) - smcp->smc_smcm |= SMCM_RX; - else - smcp->smc_smcm &= ~SMCM_RX; -} - -void kgdb_map_scc(void) -{ - ushort serbase; - uint mem_addr; - volatile cbd_t *bdp; - volatile smc_uart_t *up; - - /* The serial port has already been initialized before - * we get here. We have to assign some pointers needed by - * the kernel, and grab a memory location in the CPM that will - * work until the driver is really initialized. - */ - immr = (immap_t *)IMAP_ADDR; - - /* Right now, assume we are using SMCs. - */ -#ifdef USE_KGDB_SMC2 - *(ushort *)(&immr->im_dprambase[PROFF_SMC2_BASE]) = serbase = PROFF_SMC2; -#else - *(ushort *)(&immr->im_dprambase[PROFF_SMC1_BASE]) = serbase = PROFF_SMC1; -#endif - up = (smc_uart_t *)&immr->im_dprambase[serbase]; - - /* Allocate space for an input FIFO, plus a few bytes for output. - * Allocate bytes to maintain word alignment. - */ - mem_addr = (uint)(&immr->im_dprambase[0x1000]); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - bdp = (cbd_t *)&immr->im_dprambase[up->smc_rbase]; - bdp->cbd_bufaddr = mem_addr; - - bdp = (cbd_t *)&immr->im_dprambase[up->smc_tbase]; - bdp->cbd_bufaddr = mem_addr+RX_BUF_SIZE; - - up->smc_mrblr = RX_BUF_SIZE; /* receive buffer length */ - up->smc_maxidl = RX_BUF_SIZE; -} -#endif - -static struct tty_driver *serial_console_device(struct console *c, int *index) -{ - *index = c->index; - return serial_driver; -} - -/* - * Register console. - */ -static int __init console_8xx_init(void) -{ - register_console(&sercons); - return 0; -} - -console_initcall(console_8xx_init); - -#endif - -/* Default console baud rate as determined by the board information - * structure. - */ -static int baud_idx; - -static struct tty_operations rs_8xx_ops = { - .open = rs_8xx_open, - .close = rs_8xx_close, - .write = rs_8xx_write, - .put_char = rs_8xx_put_char, - .write_room = rs_8xx_write_room, - .chars_in_buffer = rs_8xx_chars_in_buffer, - .flush_buffer = rs_8xx_flush_buffer, - .ioctl = rs_8xx_ioctl, - .throttle = rs_8xx_throttle, - .unthrottle = rs_8xx_unthrottle, - .send_xchar = rs_8xx_send_xchar, - .set_termios = rs_8xx_set_termios, - .stop = rs_8xx_stop, - .start = rs_8xx_start, - .hangup = rs_8xx_hangup, - .wait_until_sent = rs_8xx_wait_until_sent, - .read_proc = rs_8xx_read_proc, -}; - -/* - * The serial driver boot-time initialization code! - */ -static int __init rs_8xx_init(void) -{ - struct serial_state * state; - ser_info_t *info; - uint mem_addr, dp_addr; - int i, j, idx; - uint page, sblock; - volatile cbd_t *bdp; - volatile cpm8260_t *cp; - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile scc_t *scp; - volatile scc_uart_t *sup; - volatile immap_t *immap; - volatile iop8260_t *io; - - serial_driver = alloc_tty_driver(NR_PORTS); - if (!serial_driver) - return -ENOMEM; - - show_serial_version(); - - /* Initialize the tty_driver structure */ - - serial_driver->owner = THIS_MODULE; - serial_driver->driver_name = "serial"; - serial_driver->devfs_name = "tts/"; - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - baud_idx | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &rs_8xx_ops); - if (tty_register_driver(serial_driver)) - panic("Couldn't register serial driver\n"); - - immap = immr; - cp = &immap->im_cpm; - io = &immap->im_ioport; - - /* This should have been done long ago by the early boot code, - * but do it again to make sure. - */ - *(ushort *)(&immap->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; - *(ushort *)(&immap->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2; - - /* Geeze, here we go....Picking I/O port bits....Lots of - * choices. If you don't like mine, pick your own. - * Configure SMCs Tx/Rx. SMC1 is only on Port D, SMC2 is - * only on Port A. You either pick 'em, or not. - */ -#ifndef SCC_CONSOLE - io->iop_ppard |= 0x00c00000; - io->iop_pdird |= 0x00400000; - io->iop_pdird &= ~0x00800000; - io->iop_psord &= ~0x00c00000; -#ifdef USE_SMC2 - io->iop_ppara |= 0x00c00000; - io->iop_pdira |= 0x00400000; - io->iop_pdira &= ~0x00800000; - io->iop_psora &= ~0x00c00000; -#endif - - /* Configure SCC2 and SCC3. Be careful about the fine print. - * Secondary options are only available when you take away - * the primary option. Unless the pins are used for something - * else, SCC2 and SCC3 are on Port B. - * Port B, 8 - SCC3 TxD - * Port B, 12 - SCC2 TxD - * Port B, 14 - SCC3 RxD - * Port B, 15 - SCC2 RxD - */ - io->iop_pparb |= 0x008b0000; - io->iop_pdirb |= 0x00880000; - io->iop_psorb |= 0x00880000; - io->iop_pdirb &= ~0x00030000; - io->iop_psorb &= ~0x00030000; - - /* Wire BRG1 to SMC1 and BRG2 to SMC2. - */ - immap->im_cpmux.cmx_smr = 0; - - /* Connect SCC2 and SCC3 to NMSI. Connect BRG3 to SCC2 and - * BRG4 to SCC3. - */ - immap->im_cpmux.cmx_scr &= ~0x00ffff00; - immap->im_cpmux.cmx_scr |= 0x00121b00; -#else - io->iop_pparb |= 0x008b0000; - io->iop_pdirb |= 0x00880000; - io->iop_psorb |= 0x00880000; - io->iop_pdirb &= ~0x00030000; - io->iop_psorb &= ~0x00030000; - - /* Use Port D for SCC1 instead of other functions. - */ - io->iop_ppard |= 0x00000003; - io->iop_psord &= ~0x00000001; /* Rx */ - io->iop_psord |= 0x00000002; /* Tx */ - io->iop_pdird &= ~0x00000001; /* Rx */ - io->iop_pdird |= 0x00000002; /* Tx */ - - /* Connect SCC1, SCC2, SCC3 to NMSI. Connect BRG1 to SCC1, - * BRG2 to SCC2, BRG3 to SCC3. - */ - immap->im_cpmux.cmx_scr &= ~0xffffff00; - immap->im_cpmux.cmx_scr |= 0x00091200; -#endif - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - printk (KERN_INFO "ttyS%d on %s%d at 0x%04x, BRG%d\n", - i, - (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC", - PORT_NUM(state->smc_scc_num) + 1, - (unsigned int)(state->port), - state->smc_scc_num + 1); -#ifdef CONFIG_SERIAL_CONSOLE - /* If we just printed the message on the console port, and - * we are about to initialize it for general use, we have - * to wait a couple of character times for the CR/NL to - * make it out of the transmit buffer. - */ - if (i == CONFIG_SERIAL_CONSOLE_PORT) - mdelay(300); -#endif - info = kmalloc(sizeof(ser_info_t), GFP_KERNEL); - if (info) { - /*memset(info, 0, sizeof(ser_info_t));*/ - __clear_user(info,sizeof(ser_info_t)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - info->magic = SERIAL_MAGIC; - info->flags = state->flags; - INIT_WORK(&info->tqueue, do_softint, info); - INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info); - info->line = i; - info->state = state; - state->info = (struct async_struct *)info; - - /* We need to allocate a transmit and receive buffer - * descriptors from dual port ram, and a character - * buffer area from host mem. - */ - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO, 8); - - /* Allocate space for FIFOs in the host memory. - */ - mem_addr = m8260_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE, 1); - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - bdp = (cbd_t *)&immap->im_dprambase[dp_addr]; - info->rx_cur = info->rx_bd_base = (cbd_t *)bdp; - - for (j=0; j<(RX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; - mem_addr += RX_BUF_SIZE; - bdp++; - } - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; - - if ((idx = state->smc_scc_num) < SCC_NUM_BASE) { - sp = &immap->im_smc[idx]; - up = (smc_uart_t *)&immap->im_dprambase[state->port]; - up->smc_rbase = dp_addr; - } - else { - scp = &immap->im_scc[idx - SCC_IDX_BASE]; - sup = (scc_uart_t *)&immap->im_dprambase[state->port]; - scp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - sup->scc_genscc.scc_rbase = dp_addr; - } - - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO, 8); - - /* Allocate space for FIFOs in the host memory. - */ - mem_addr = m8260_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE, 1); - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - bdp = (cbd_t *)&immap->im_dprambase[dp_addr]; - info->tx_cur = info->tx_bd_base = (cbd_t *)bdp; - - for (j=0; j<(TX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = BD_SC_INTRPT; - mem_addr += TX_BUF_SIZE; - bdp++; - } - bdp->cbd_bufaddr = __pa(mem_addr); - bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT); - - if (idx < SCC_NUM_BASE) { - up->smc_tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; - up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle charater - * time requires some additional tuning. - */ - up->smc_mrblr = 1; - up->smc_maxidl = 0; - up->smc_brkcr = 1; - - /* Send the CPM an initialize command. - */ - if (state->smc_scc_num == 0) { - page = CPM_CR_SMC1_PAGE; - sblock = CPM_CR_SMC1_SBLOCK; - } - else { - page = CPM_CR_SMC2_PAGE; - sblock = CPM_CR_SMC2_SBLOCK; - } - - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Disable all interrupts and clear all pending - * events. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - } - else { - sup->scc_genscc.scc_tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; - sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle charater - * time requires some additional tuning. - */ - sup->scc_genscc.scc_mrblr = 1; - sup->scc_maxidl = 0; - sup->scc_brkcr = 1; - sup->scc_parec = 0; - sup->scc_frmec = 0; - sup->scc_nosec = 0; - sup->scc_brkec = 0; - sup->scc_uaddr1 = 0; - sup->scc_uaddr2 = 0; - sup->scc_toseq = 0; - sup->scc_char1 = 0x8000; - sup->scc_char2 = 0x8000; - sup->scc_char3 = 0x8000; - sup->scc_char4 = 0x8000; - sup->scc_char5 = 0x8000; - sup->scc_char6 = 0x8000; - sup->scc_char7 = 0x8000; - sup->scc_char8 = 0x8000; - sup->scc_rccm = 0xc0ff; - - /* Send the CPM an initialize command. - */ -#ifdef SCC_CONSOLE - switch (state->smc_scc_num) { - case 0: - page = CPM_CR_SCC1_PAGE; - sblock = CPM_CR_SCC1_SBLOCK; - break; - case 1: - page = CPM_CR_SCC2_PAGE; - sblock = CPM_CR_SCC2_SBLOCK; - break; - case 2: - page = CPM_CR_SCC3_PAGE; - sblock = CPM_CR_SCC3_SBLOCK; - break; - } -#else - if (state->smc_scc_num == 2) { - page = CPM_CR_SCC2_PAGE; - sblock = CPM_CR_SCC2_SBLOCK; - } - else { - page = CPM_CR_SCC3_PAGE; - sblock = CPM_CR_SCC3_SBLOCK; - } -#endif - - cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - scp->scc_gsmrh = 0; - scp->scc_gsmrl = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Disable all interrupts and clear all pending - * events. - */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_pmsr = 0x3000; - } - - /* Install interrupt handler. - */ - request_irq(state->irq, rs_8xx_interrupt, 0, "uart", info); - - /* Set up the baud rate generator. - */ - m8260_cpm_setbrg(state->smc_scc_num, - baud_table[baud_idx]); - - /* If the port is the console, enable Rx and Tx. - */ -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) { - if (idx < SCC_NUM_BASE) - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; - else - scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - } -#endif - } - } - return 0; -} -module_init(rs_8xx_init); - -/* This must always be called before the rs_8xx_init() function, otherwise - * it blows away the port control information. -*/ -static int __init serial_console_setup(struct console *co, char *options) -{ - struct serial_state *ser; - uint mem_addr, dp_addr, bidx; - volatile cbd_t *bdp; - volatile cpm8260_t *cp; - volatile immap_t *immap; -#ifndef SCC_CONSOLE - volatile smc_t *sp; - volatile smc_uart_t *up; -#endif -#ifdef SCC_CONSOLE - volatile scc_t *scp; - volatile scc_uart_t *sup; -#endif - volatile iop8260_t *io; - bd_t *bd; - - bd = (bd_t *)__res; - - for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++) - if (bd->bi_baudrate == baud_table[bidx]) - break; - - co->cflag = CREAD|CLOCAL|bidx|CS8; - baud_idx = bidx; - - ser = rs_table + co->index; - - immap = immr; - cp = &immap->im_cpm; - io = &immap->im_ioport; - -#ifdef SCC_CONSOLE - scp = (scc_t *)&(immap->im_scc[SCC_CONSOLE-1]); - sup = (scc_uart_t *)&immap->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; - scp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); - scp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - /* Use Port D for SCC1 instead of other functions. - */ - io->iop_ppard |= 0x00000003; - io->iop_psord &= ~0x00000001; /* Rx */ - io->iop_psord |= 0x00000002; /* Tx */ - io->iop_pdird &= ~0x00000001; /* Rx */ - io->iop_pdird |= 0x00000002; /* Tx */ - -#else - /* This should have been done long ago by the early boot code, - * but do it again to make sure. - */ - *(ushort *)(&immap->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; - *(ushort *)(&immap->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2; - - /* Right now, assume we are using SMCs. - */ - sp = &immap->im_smc[ser->smc_scc_num]; - - /* When we get here, the CPM has been reset, so we need - * to configure the port. - * We need to allocate a transmit and receive buffer descriptor - * from dual port ram, and a character buffer area from host mem. - */ - up = (smc_uart_t *)&immap->im_dprambase[ser->port]; - - /* Disable transmitter/receiver. - */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - - /* Use Port D for SMC1 instead of other functions. - */ - io->iop_ppard |= 0x00c00000; - io->iop_pdird |= 0x00400000; - io->iop_pdird &= ~0x00800000; - io->iop_psord &= ~0x00c00000; -#endif - - /* Allocate space for two buffer descriptors in the DP ram. - */ - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * 2, 8); - - /* Allocate space for two 2 byte FIFOs in the host memory. - */ - mem_addr = m8260_cpm_hostalloc(4, 1); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - bdp = (cbd_t *)&immap->im_dprambase[dp_addr]; - bdp->cbd_bufaddr = __pa(mem_addr); - (bdp+1)->cbd_bufaddr = __pa(mem_addr+2); - - /* For the receive, set empty and wrap. - * For transmit, set wrap. - */ - bdp->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; - (bdp+1)->cbd_sc = BD_SC_WRAP; - - /* Set up the uart parameters in the parameter ram. - */ -#ifdef SCC_CONSOLE - sup->scc_genscc.scc_rbase = dp_addr; - sup->scc_genscc.scc_tbase = dp_addr + sizeof(cbd_t); - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; - sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - sup->scc_genscc.scc_mrblr = 1; - sup->scc_maxidl = 0; - sup->scc_brkcr = 1; - sup->scc_parec = 0; - sup->scc_frmec = 0; - sup->scc_nosec = 0; - sup->scc_brkec = 0; - sup->scc_uaddr1 = 0; - sup->scc_uaddr2 = 0; - sup->scc_toseq = 0; - sup->scc_char1 = 0x8000; - sup->scc_char2 = 0x8000; - sup->scc_char3 = 0x8000; - sup->scc_char4 = 0x8000; - sup->scc_char5 = 0x8000; - sup->scc_char6 = 0x8000; - sup->scc_char7 = 0x8000; - sup->scc_char8 = 0x8000; - sup->scc_rccm = 0xc0ff; - - /* Send the CPM an initialize command. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - scp->scc_gsmrh = 0; - scp->scc_gsmrl = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Disable all interrupts and clear all pending - * events. - */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_pmsr = 0x3000; - - /* Wire BRG1 to SCC1. The serial init will take care of - * others. - */ - immap->im_cpmux.cmx_scr = 0; - - /* Set up the baud rate generator. - */ - m8260_cpm_setbrg(ser->smc_scc_num, bd->bi_baudrate); - - scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); -#else - up->smc_rbase = dp_addr; /* Base of receive buffer desc. */ - up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */ - up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; - up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; - - /* Set this to 1 for now, so we get single character interrupts. - */ - up->smc_mrblr = 1; /* receive buffer length */ - up->smc_maxidl = 0; /* wait forever for next char */ - - /* Send the CPM an initialize command. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Set up the baud rate generator. - */ - m8260_cpm_setbrg(ser->smc_scc_num, bd->bi_baudrate); - - /* And finally, enable Rx and Tx. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -#endif - - return 0; -} diff -Nru a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c --- a/arch/ppc/8xx_io/commproc.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/8xx_io/commproc.c 2004-06-26 17:09:18 -07:00 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -34,11 +35,11 @@ #include #include #include +#include extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); -static uint dp_alloc_base; /* Starting offset in DP ram */ -static uint dp_alloc_top; /* Max offset + 1 */ +static void m8xx_cpm_dpinit(void); static uint host_buffer; /* One page of host buffer */ static uint host_end; /* end + 1 */ cpm8xx_t *cpmp; /* Pointer to comm processor space */ @@ -84,10 +85,8 @@ */ imp->im_siu_conf.sc_sdcr = 1; - /* Reclaim the DP memory for our use. - */ - dp_alloc_base = CPM_DATAONLY_BASE; - dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE; + /* Reclaim the DP memory for our use. */ + m8xx_cpm_dpinit(); /* Tell everyone where the comm processor resides. */ @@ -138,10 +137,8 @@ */ imp->im_siu_conf.sc_sdcr = 1; - /* Reclaim the DP memory for our use. - */ - dp_alloc_base = CPM_DATAONLY_BASE; - dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE; + /* Reclaim the DP memory for our use. */ + m8xx_cpm_dpinit(); /* Set the host page for allocation. */ @@ -257,30 +254,6 @@ ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec); } -/* Allocate some memory from the dual ported ram. We may want to - * enforce alignment restrictions, but right now everyone is a good - * citizen. - */ -uint -m8xx_cpm_dpalloc(uint size) -{ - uint retloc; - - if ((dp_alloc_base + size) >= dp_alloc_top) - return(CPM_DP_NOSPACE); - - retloc = dp_alloc_base; - dp_alloc_base += size; - - return(retloc); -} - -uint -m8xx_cpm_dpalloc_index(void) -{ - return dp_alloc_base; -} - /* We also own one page of host buffer space for the allocation of * UART "fifos" and the like. */ @@ -330,3 +303,102 @@ *bp = (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16; } + +/* + * dpalloc / dpfree bits. + */ +static spinlock_t cpm_dpmem_lock; +/* + * 16 blocks should be enough to satisfy all requests + * until the memory subsystem goes up... + */ +static rh_block_t cpm_boot_dpmem_rh_block[16]; +static rh_info_t cpm_dpmem_info; + +#define CPM_DPMEM_ALIGNMENT 8 + +void m8xx_cpm_dpinit(void) +{ + cpm8xx_t *cp = &((immap_t *)IMAP_ADDR)->im_cpm; + + spin_lock_init(&cpm_dpmem_lock); + + /* Initialize the info header */ + rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT, + sizeof(cpm_boot_dpmem_rh_block) / + sizeof(cpm_boot_dpmem_rh_block[0]), + cpm_boot_dpmem_rh_block); + + /* + * Attach the usable dpmem area. + * XXX: This is actually crap. CPM_DATAONLY_BASE and + * CPM_DATAONLY_SIZE are a subset of the available dparm. It varies + * with the processor and the microcode patches applied / activated. + * But the following should be at least safe. + */ + rh_attach_region(&cpm_dpmem_info, cp->cp_dpmem + CPM_DATAONLY_BASE, + CPM_DATAONLY_SIZE); +} + +/* + * Allocate the requested size worth of DP memory. + * This function used to return an index into the DPRAM area. + * Now it returns the actuall physical address of that area. + * use m8xx_cpm_dpram_offset() to get the index + */ +void *m8xx_cpm_dpalloc(int size) +{ + void *start; + unsigned long flags; + + spin_lock_irqsave(&cpm_dpmem_lock, flags); + start = rh_alloc(&cpm_dpmem_info, size, "commproc"); + spin_unlock_irqrestore(&cpm_dpmem_lock, flags); + + return start; +} +EXPORT_SYMBOL(m8xx_cpm_dpalloc); + +int m8xx_cpm_dpfree(void *addr) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&cpm_dpmem_lock, flags); + ret = rh_free(&cpm_dpmem_info, addr); + spin_unlock_irqrestore(&cpm_dpmem_lock, flags); + + return ret; +} +EXPORT_SYMBOL(m8xx_cpm_dpfree); + +void *m8xx_cpm_dpalloc_fixed(void *addr, int size) +{ + void *start; + unsigned long flags; + + spin_lock_irqsave(&cpm_dpmem_lock, flags); + start = rh_alloc_fixed(&cpm_dpmem_info, addr, size, "commproc"); + spin_unlock_irqrestore(&cpm_dpmem_lock, flags); + + return start; +} +EXPORT_SYMBOL(m8xx_cpm_dpalloc_fixed); + +void m8xx_cpm_dpdump(void) +{ + rh_dump(&cpm_dpmem_info); +} +EXPORT_SYMBOL(m8xx_cpm_dpdump); + +int m8xx_cpm_dpram_offset(void *addr) +{ + return (u_char *)addr - ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem; +} +EXPORT_SYMBOL(m8xx_cpm_dpram_offset); + +void *m8xx_cpm_dpram_addr(int offset) +{ + return ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem + offset; +} +EXPORT_SYMBOL(m8xx_cpm_dpram_addr); diff -Nru a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c --- a/arch/ppc/8xx_io/cs4218_tdm.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/8xx_io/cs4218_tdm.c 2004-06-26 17:09:15 -07:00 @@ -2463,7 +2463,7 @@ int __init tdm8xx_sound_init(void) { int i, has_sound; - uint dp_addr; + uint dp_addr, dp_mem; volatile uint *sirp; volatile cbd_t *bdp; volatile cpm8xx_t *cp; @@ -2525,14 +2525,15 @@ /* We need to allocate a transmit and receive buffer * descriptors from dual port ram. */ - dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numReadBufs); + dp_mem = m8xx_cpm_dpalloc(sizeof(cbd_t) * numReadBufs); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); /* Set the physical address of the host memory * buffers in the buffer descriptors, and the * virtual address for us to work with. */ bdp = (cbd_t *)&cp->cp_dpmem[dp_addr]; - up->smc_rbase = dp_addr; + up->smc_rbase = dp_mem; rx_cur = rx_base = (cbd_t *)bdp; for (i=0; i<(numReadBufs-1); i++) { @@ -2547,10 +2548,11 @@ /* Now, do the same for the transmit buffers. */ - dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numBufs); + dp_mem = m8xx_cpm_dpalloc(sizeof(cbd_t) * numBufs); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); bdp = (cbd_t *)&cp->cp_dpmem[dp_addr]; - up->smc_tbase = dp_addr; + up->smc_tbase = dp_mem; tx_cur = tx_base = (cbd_t *)bdp; for (i=0; i<(numBufs-1); i++) { diff -Nru a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c --- a/arch/ppc/8xx_io/enet.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc/8xx_io/enet.c 2004-06-26 17:09:16 -07:00 @@ -644,6 +644,8 @@ struct net_device *dev; struct scc_enet_private *cep; int i, j, k, err; + void *dp_mem; + unsigned int dp_addr; unsigned char *eap, *ba; dma_addr_t mem_addr; bd_t *bd; @@ -738,13 +740,15 @@ * These are relative offsets in the DP ram address space. * Initialize base addresses for the buffer descriptors. */ - i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE); - ep->sen_genscc.scc_rbase = i; - cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i]; - - i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE); - ep->sen_genscc.scc_tbase = i; - cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i]; + dp_mem = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); + ep->sen_genscc.scc_rbase = dp_mem; + cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[dp_addr]; + + dp_mem = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); + ep->sen_genscc.scc_tbase = dp_mem; + cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[dp_addr]; cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; cep->cur_rx = cep->rx_bd_base; diff -Nru a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c --- a/arch/ppc/8xx_io/uart.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc/8xx_io/uart.c 2004-06-26 17:09:19 -07:00 @@ -2491,7 +2491,7 @@ { struct serial_state * state; ser_info_t *info; - uint mem_addr, dp_addr, iobits; + uint mem_addr, dp_addr, dp_mem, iobits; int i, j, idx; ushort chan; volatile cbd_t *bdp; @@ -2623,7 +2623,8 @@ * descriptors from dual port ram, and a character * buffer area from host mem. */ - dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO); + dp_mem = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); /* Allocate space for FIFOs in the host memory. */ @@ -2650,15 +2651,16 @@ if (info->state->smc_scc_num & NUM_IS_SCC) { scp = &cp->cp_scc[idx]; sup = (scc_uart_t *)&cp->cp_dparam[state->port]; - sup->scc_genscc.scc_rbase = dp_addr; + sup->scc_genscc.scc_rbase = dp_mem; } else { sp = &cp->cp_smc[idx]; up = (smc_uart_t *)&cp->cp_dparam[state->port]; - up->smc_rbase = dp_addr; + up->smc_rbase = dp_mem; } - dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO); + dp_mem = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); /* Allocate space for FIFOs in the host memory. */ @@ -2682,7 +2684,7 @@ bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT); if (info->state->smc_scc_num & NUM_IS_SCC) { - sup->scc_genscc.scc_tbase = dp_addr; + sup->scc_genscc.scc_tbase = dp_mem; /* Set up the uart parameters in the * parameter ram. @@ -2779,7 +2781,7 @@ cp->cp_simode &= ~(0xffff << (idx * 16)); cp->cp_simode |= (i << ((idx * 16) + 12)); - up->smc_tbase = dp_addr; + up->smc_tbase = dp_mem; /* Set up the uart parameters in the * parameter ram. @@ -2843,7 +2845,7 @@ static int __init serial_console_setup(struct console *co, char *options) { struct serial_state *ser; - uint mem_addr, dp_addr, bidx, idx; + uint mem_addr, dp_addr, dp_mem, bidx, idx; ushort chan; volatile cbd_t *bdp; volatile cpm8xx_t *cp; @@ -2889,12 +2891,14 @@ * memory yet because vm allocator isn't initialized * during this early console init. */ - dp_addr = m8xx_cpm_dpalloc(8); + dp_mem = m8xx_cpm_dpalloc(8); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]); /* Allocate space for two buffer descriptors in the DP ram. */ - dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2); + dp_mem = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2); + dp_addr = m8xx_cpm_dpram_offset(dp_mem); /* Set the physical address of the host memory buffers in * the buffer descriptors. @@ -2918,8 +2922,8 @@ */ if (ser->smc_scc_num & NUM_IS_SCC) { - sup->scc_genscc.scc_rbase = dp_addr; - sup->scc_genscc.scc_tbase = dp_addr + sizeof(cbd_t); + sup->scc_genscc.scc_rbase = dp_mem; + sup->scc_genscc.scc_tbase = dp_mem + sizeof(cbd_t); /* Set up the uart parameters in the * parameter ram. @@ -2977,8 +2981,8 @@ } else { - up->smc_rbase = dp_addr; /* Base of receive buffer desc. */ - up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */ + up->smc_rbase = dp_mem; /* Base of receive buffer desc. */ + up->smc_tbase = dp_mem+sizeof(cbd_t); /* Base of xmt buffer desc. */ up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig --- a/arch/ppc/Kconfig 2004-06-26 17:09:21 -07:00 +++ b/arch/ppc/Kconfig 2004-06-26 17:09:21 -07:00 @@ -72,8 +72,21 @@ config 8xx bool "8xx" +config E500 + bool "e500" + endchoice +config BOOKE + bool + depends on E500 + default y + +config FSL_BOOKE + bool + depends on E500 + default y + config PTE_64BIT bool depends on 44x @@ -96,6 +109,21 @@ If in doubt, say Y here. +config SPE + bool "SPE Support" + depends on E500 + ---help--- + This option enables kernel support for the Signal Processing + Extensions (SPE) to the PowerPC processor. The kernel currently + supports saving and restoring SPE registers, and turning on the + 'spe enable' bit so user processes can execute SPE instructions. + + This option is only usefully if you have a processor that supports + SPE (e500, otherwise known as 85xx series), but does not have any + affect on a non-spe cpu (it does, however add code to the kernel). + + If in doubt, say Y here. + config TAU bool "Thermal Management Support" depends on 6xx && !8260 @@ -142,7 +170,7 @@ config MATH_EMULATION bool "Math emulation" - depends on 4xx || 8xx + depends on 4xx || 8xx || E500 ---help--- Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the @@ -198,6 +226,7 @@ If in doubt, say Y here. source arch/ppc/platforms/4xx/Kconfig +source arch/ppc/platforms/85xx/Kconfig config PPC64BRIDGE bool @@ -295,7 +324,7 @@ HERMES: Hermes-Pro ISDN/LAN router with integrated 8 x hub - Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik + Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik Date of Release: 2000 (?) End of life: - @@ -569,8 +598,16 @@ End of Life: not yet :-) URL: +config ADS8272 + bool "ADS8272" + endchoice +config PQ2ADS + bool + depends on ADS8272 + default y + config TQM8xxL bool depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L || SM850) @@ -582,14 +619,32 @@ default y config 8260 - bool "MPC8260 CPM Support" if WILLOW + bool "CPM2 Support" if WILLOW depends on 6xx default y if TQM8260 || RPXSUPER || EST8260 || SBS8260 || SBC82xx help - The MPC8260 CPM (Communications Processor Module) is a typical - embedded CPU made by Motorola. Selecting this option means that - you wish to build a kernel for a machine with specifically an 8260 - for a CPU. + The MPC8260 is a typical embedded CPU made by Motorola. Selecting + this option means that you wish to build a kernel for a machine with + an 8260 class CPU. + +config 8272 + bool + depends on 6xx + default y if ADS8272 + select 8260 + help + The MPC8272 CPM has a different internal dpram setup than other CPM2 + devices + +config CPM2 + bool + depends on 8260 + default y + help + The CPM2 (Communications Processor Module) is a coprocessor on + embedded CPUs made by Motorola. Selecting this option means that + you wish to build a kernel for a machine with a CPM2 coprocessor + on it (826x, 827x, 8560). config PPC_CHRP bool @@ -672,11 +727,11 @@ config PC_KEYBOARD bool "PC PS/2 style Keyboard" - depends on 4xx || 8260 + depends on 4xx || CPM2 config SERIAL_CONSOLE bool - depends on 8xx || 8260 + depends on 8xx default y config SERIAL_CONSOLE_BAUD @@ -957,7 +1012,7 @@ config GENERIC_ISA_DMA bool - depends on POWER3 || POWER4 || 6xx && !8260 + depends on POWER3 || POWER4 || 6xx && !CPM2 default y config EISA @@ -974,10 +1029,10 @@ bool config PCI - bool "PCI support" if 40x || 8260 - default y if !40x && !8260 && !8xx && !APUS - default PCI_PERMEDIA if !4xx && !8260 && !8xx && APUS - default PCI_QSPAN if !4xx && !8260 && 8xx + bool "PCI support" if 40x || CPM2 || 85xx + default y if !40x && !CPM2 && !8xx && !APUS && !85xx + default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS + default PCI_QSPAN if !4xx && !CPM2 && 8xx help Find out whether your system includes a PCI bus. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside @@ -990,11 +1045,39 @@ config PCI_QSPAN bool "QSpan PCI" - depends on !4xx && !8260 && 8xx + depends on !4xx && !CPM2 && 8xx help Say Y here if you have a system based on a Motorola 8xx-series embedded processor with a QSPAN PCI interface, otherwise say N. +config PCI_8260 + bool + depends on PCI && 8260 && !8272 + default y + +config 8260_PCI9 + bool " Enable workaround for MPC826x erratum PCI 9" + depends on PCI_8260 + default y + +choice + prompt " IDMA channel for PCI 9 workaround" + depends on 8260_PCI9 + +config 8260_PCI9_IDMA1 + bool "IDMA1" + +config 8260_PCI9_IDMA2 + bool "IDMA2" + +config 8260_PCI9_IDMA3 + bool "IDMA3" + +config 8260_PCI9_IDMA4 + bool "IDMA4" + +endchoice + config PCI_PERMEDIA bool "PCI for Permedia2" depends on !4xx && !8xx && APUS @@ -1154,6 +1237,7 @@ source "lib/Kconfig" +source "arch/ppc/oprofile/Kconfig" menu "Kernel hacking" @@ -1229,7 +1313,7 @@ config KGDB_CONSOLE bool "Enable serial console thru kgdb port" - depends on KGDB && 8xx || 8260 + depends on KGDB && 8xx || CPM2 help If you enable this, all serial console messages will be sent over the gdb stub. @@ -1273,7 +1357,7 @@ config PPC_OCP bool - depends on IBM_OCP + depends on IBM_OCP || FSL_OCP default y endmenu diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile --- a/arch/ppc/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/Makefile 2004-06-26 17:09:15 -07:00 @@ -17,19 +17,24 @@ CPPFLAGS += -Iarch/$(ARCH) AFLAGS += -Iarch/$(ARCH) cflags-y += -Iarch/$(ARCH) -msoft-float -pipe \ - -ffixed-r2 -Wno-uninitialized -mmultiple -mstring + -ffixed-r2 -Wno-uninitialized -mmultiple CPP = $(CC) -E $(CFLAGS) +ifndef CONFIG_E500 +cflags-y += -mstring +endif + cflags-$(CONFIG_4xx) += -Wa,-m405 +cflags-$(CONFIG_E500) += -Wa,-me500 cflags-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge CFLAGS += $(cflags-y) - head-y := arch/ppc/kernel/head.o head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o +head-$(CONFIG_E500) := arch/ppc/kernel/head_e500.o head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o @@ -37,12 +42,15 @@ core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ +core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/ core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/ppc/xmon/ core-$(CONFIG_APUS) += arch/ppc/amiga/ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ -drivers-$(CONFIG_8260) += arch/ppc/8260_io/ +drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ + +drivers-$(CONFIG_OPROFILE) += arch/ppc/oprofile/ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm diff -Nru a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c --- a/arch/ppc/boot/simple/embed_config.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/boot/simple/embed_config.c 2004-06-26 17:09:15 -07:00 @@ -16,7 +16,7 @@ #endif #ifdef CONFIG_8260 #include -#include +#include #endif #ifdef CONFIG_40x #include @@ -415,9 +415,9 @@ { uint scmr, vco_out, clkin; uint plldf, pllmf, corecnf; - volatile immap_t *ip; + volatile cpm2_map_t *ip; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; scmr = ip->im_clkrst.car_scmr; /* The clkin is always bus frequency. @@ -457,9 +457,9 @@ { uint scmr, main_clk, clkin; uint pllmf, corecnf; - volatile immap_t *ip; + volatile cpm2_map_t *ip; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; scmr = ip->im_clkrst.car_scmr; /* The clkin is always bus frequency. diff -Nru a/arch/ppc/boot/simple/m8260_tty.c b/arch/ppc/boot/simple/m8260_tty.c --- a/arch/ppc/boot/simple/m8260_tty.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ppc/boot/simple/m8260_tty.c 2004-06-26 17:09:17 -07:00 @@ -3,7 +3,8 @@ */ #include #include -#include +#include +#include uint no_print; extern char *params[]; @@ -29,12 +30,12 @@ volatile scc_uart_t *sup; #endif volatile cbd_t *tbdf, *rbdf; - volatile immap_t *ip; - volatile iop8260_t *io; - volatile cpm8260_t *cp; + volatile cpm2_map_t *ip; + volatile iop_cpm2_t *io; + volatile cpm_cpm2_t *cp; uint dpaddr, memaddr; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; cp = &ip->im_cpm; io = &ip->im_ioport; @@ -223,10 +224,10 @@ volatile char *buf; volatile smc_uart_t *up; volatile scc_uart_t *sup; - volatile immap_t *ip; + volatile cpm2_map_t *ip; int i, nc; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; @@ -255,10 +256,10 @@ volatile char *buf; volatile smc_uart_t *up; volatile scc_uart_t *sup; - volatile immap_t *ip; + volatile cpm2_map_t *ip; extern bd_t *board_info; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase]; @@ -298,9 +299,9 @@ volatile cbd_t *rbdf; volatile smc_uart_t *up; volatile scc_uart_t *sup; - volatile immap_t *ip; + volatile cpm2_map_t *ip; - ip = (immap_t *)IMAP_ADDR; + ip = (cpm2_map_t *)CPM_MAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; diff -Nru a/arch/ppc/configs/ads8272_defconfig b/arch/ppc/configs/ads8272_defconfig --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/configs/ads8272_defconfig 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,583 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Processor +# +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_CPU_FREQ is not set +CONFIG_EMBEDDEDBOOT=y +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +# CONFIG_PPC_MULTIPLATFORM is not set +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX6 is not set +# CONFIG_TQM8260 is not set +CONFIG_ADS8272=y +CONFIG_PQ2ADS=y +CONFIG_8260=y +CONFIG_8272=y +CONFIG_CPM2=y +# CONFIG_PC_KEYBOARD is not set +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCI_NAMES is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00400000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_LBD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_OAKNET is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set +# CONFIG_SCC_ENET is not set +CONFIG_FEC_ENET=y +# CONFIG_USE_MDIO is not set + +# +# CPM2 Options +# +CONFIG_SCC_CONSOLE=y +CONFIG_FCC1_ENET=y +# CONFIG_FCC2_ENET is not set +# CONFIG_FCC3_ENET is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_KGDB_CONSOLE is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile --- a/arch/ppc/kernel/Makefile 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/kernel/Makefile 2004-06-26 17:09:20 -07:00 @@ -8,10 +8,14 @@ ifdef CONFIG_4xx EXTRA_AFLAGS := -Wa,-m405 endif +ifdef CONFIG_E500 +EXTRA_AFLAGS := -Wa,-me500 +endif extra-$(CONFIG_PPC_STD_MMU) := head.o extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o +extra-$(CONFIG_E500) := head_e500.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o extra-$(CONFIG_POWER4) += idle_power4.o diff -Nru a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c --- a/arch/ppc/kernel/align.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/kernel/align.c 2004-06-26 17:09:15 -07:00 @@ -21,7 +21,7 @@ unsigned char flags; }; -#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) +#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE) #define OPCD(inst) (((inst) & 0xFC000000) >> 26) #define RS(inst) (((inst) & 0x03E00000) >> 21) #define RA(inst) (((inst) & 0x001F0000) >> 16) @@ -184,7 +184,7 @@ fix_alignment(struct pt_regs *regs) { int instr, nb, flags; -#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) +#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE) int opcode, f1, f2, f3; #endif int i, t; @@ -199,8 +199,8 @@ CHECK_FULL_REGS(regs); -#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) - /* The 4xx-family processors have no DSISR register, +#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE) + /* The 4xx-family & Book-E processors have no DSISR register, * so we emulate it. * The POWER4 has a DSISR register but doesn't set it on * an alignment fault. -- paulus @@ -250,7 +250,7 @@ flags = aligninfo[instr].flags; - /* For the 4xx-family processors, the 'dar' field of the + /* For the 4xx-family & Book-E processors, the 'dar' field of the * pt_regs structure is overloaded and is really from the DEAR. */ diff -Nru a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c --- a/arch/ppc/kernel/asm-offsets.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/kernel/asm-offsets.c 2004-06-26 17:09:18 -07:00 @@ -44,7 +44,7 @@ DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); DEFINE(PT_PTRACED, PT_PTRACED); #endif @@ -54,6 +54,12 @@ DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0])); + DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc)); + DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr)); + DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe)); +#endif /* CONFIG_SPE */ /* Interrupt register frame */ DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); diff -Nru a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c --- a/arch/ppc/kernel/cputable.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/kernel/cputable.c 2004-06-26 17:09:18 -07:00 @@ -34,7 +34,8 @@ extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec); #define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \ - !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4)) + !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \ + !defined(CONFIG_BOOKE)) /* This table only contains "desktop" CPUs, it need to be filled with embedded * ones as well... @@ -561,6 +562,16 @@ 0, /*__setup_cpu_440 */ }, #endif /* CONFIG_44x */ +#ifdef CONFIG_E500 + { /* e500 */ + 0xffff0000, 0x80200000, "e500", + /* xxx - galak: add CPU_FTR_CAN_DOZE */ + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + 32, 32, + 0, /*__setup_cpu_e500 */ + }, +#endif #if !CLASSIC_PPC { /* default match */ 0x00000000, 0x00000000, "(generic PPC)", diff -Nru a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S --- a/arch/ppc/kernel/entry.S 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/kernel/entry.S 2004-06-26 17:09:20 -07:00 @@ -36,7 +36,7 @@ #undef SHOW_SYSCALLS_TASK /* - * MSR_KERNEL is > 0x10000 on 4xx since it include MSR_CE. + * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE. */ #if MSR_KERNEL >= 0x10000 #define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l @@ -45,7 +45,7 @@ #endif #ifdef CONFIG_BOOKE -#define COR r8 +#define COR r8 /* Critical Offset Register (COR) */ #define BOOKE_LOAD_COR lis COR,crit_save@ha #define BOOKE_REST_COR mfspr COR,SPRG2 #define BOOKE_SAVE_COR mtspr SPRG2,COR @@ -241,11 +241,11 @@ andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne- syscall_exit_work syscall_exit_cont: -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) /* If the process has its own DBCR0 value, load it up */ lwz r0,PTRACE(r2) andi. r0,r0,PT_PTRACED - bnel- load_4xx_dbcr0 + bnel- load_dbcr0 #endif stwcx. r0,0,r1 /* to clear the reservation */ lwz r4,_LINK(r1) @@ -510,7 +510,12 @@ stw r12,THREAD+THREAD_VRSAVE(r2) END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ - and. r0,r0,r11 /* FP or altivec enabled? */ +#ifdef CONFIG_SPE + oris r0,r0,MSR_SPE@h /* Disable SPE */ + mfspr r12,SPRN_SPEFSCR /* save spefscr register value */ + stw r12,THREAD+THREAD_SPEFSCR(r2) +#endif /* CONFIG_SPE */ + and. r0,r0,r11 /* FP or altivec or SPE enabled? */ beq+ 1f andc r11,r11,r0 MTMSRD(r11) @@ -543,6 +548,10 @@ mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + lwz r0,THREAD+THREAD_SPEFSCR(r2) + mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */ +#endif /* CONFIG_SPE */ lwz r0,_CCR(r1) mtcrf 0xFF,r0 @@ -589,11 +598,11 @@ bne do_work restore_user: -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) /* Check whether this process has its own DBCR0 value */ lwz r0,PTRACE(r2) andi. r0,r0,PT_PTRACED - bnel- load_4xx_dbcr0 + bnel- load_dbcr0 #endif #ifdef CONFIG_PREEMPT @@ -645,7 +654,7 @@ PPC405_ERR77(0,r1) stwcx. r0,0,r1 /* to clear the reservation */ -#ifndef CONFIG_4xx +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) lwz r9,_MSR(r1) andi. r10,r9,MSR_RI /* check if this exception occurred */ beql nonrecoverable /* at a bad place (MSR:RI = 0) */ @@ -681,9 +690,9 @@ SYNC RFI -#else /* CONFIG_4xx */ +#else /* !(CONFIG_4xx || CONFIG_BOOKE) */ /* - * This is a bit different on 4xx because 4xx doesn't have + * This is a bit different on 4xx/Book-E because it doesn't have * the RI bit in the MSR. * The TLB miss handler checks if we have interrupted * the exception exit path and restarts it if so @@ -720,6 +729,9 @@ * give the wrong answer). * We have to restore various SPRs that may have been in use at the * time of the critical interrupt. + * + * Note that SPRG6 is used for machine check on CONFIG_BOOKE parts and + * thus not saved in the critical handler */ .globl ret_from_crit_exc ret_from_crit_exc: @@ -866,7 +878,7 @@ * Load the DBCR0 value for a task that is being ptraced, * having first saved away the global DBCR0. */ -load_4xx_dbcr0: +load_dbcr0: mfmsr r0 /* first disable debug exceptions */ rlwinm r0,r0,0,~MSR_DE mtmsr r0 @@ -885,7 +897,7 @@ blr .comm global_dbcr0,8 -#endif /* CONFIG_4xx */ +#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ do_work: /* r10 contains MSR_KERNEL here */ andi. r0,r9,_TIF_NEED_RESCHED diff -Nru a/arch/ppc/kernel/head_e500.S b/arch/ppc/kernel/head_e500.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/kernel/head_e500.S 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1329 @@ +/* + * arch/ppc/kernel/head_e500.S + * + * Kernel execution entry point code. + * + * Copyright (c) 1995-1996 Gary Thomas + * Initial PowerPC version. + * Copyright (c) 1996 Cort Dougan + * Rewritten for PReP + * Copyright (c) 1996 Paul Mackerras + * Low-level exception handers, MMU support, and rewrite. + * Copyright (c) 1997 Dan Malek + * PowerPC 8xx modifications. + * Copyright (c) 1998-1999 TiVo, Inc. + * PowerPC 403GCX modifications. + * Copyright (c) 1999 Grant Erickson + * PowerPC 403GCX/405GP modifications. + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * PowerPC 403GCX/405GP modifications. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * Copyright 2002-2004 MontaVista Software, Inc. + * PowerPC 44x support, Matt Porter + * Copyright 2004 Freescale Semiconductor, Inc + * PowerPC e500 modifications, Kumar Gala + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Macros + */ + +#define SET_IVOR(vector_number, vector_label) \ + li r26,vector_label@l; \ + mtspr SPRN_IVOR##vector_number,r26; \ + sync + +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=128") + * r7 - End of kernel command line string + * + */ + .text +_GLOBAL(_stext) +_GLOBAL(_start) + /* + * Reserve a word at a fixed location to store the address + * of abatron_pteptrs + */ + nop +/* + * Save parameters we are passed + */ + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + li r24,0 /* CPU number */ + +/* We try to not make any assumptions about how the boot loader + * setup or used the TLBs. We invalidate all mappings from the + * boot loader and load a single entry in TLB1[0] to map the + * first 16M of kernel memory. Any boot info passed from the + * bootloader needs to live in this first 16M. + * + * Requirement on bootloader: + * - The page we're executing in needs to reside in TLB1 and + * have IPROT=1. If not an invalidate broadcast could + * evict the entry we're currently executing in. + * + * r3 = Index of TLB1 were executing in + * r4 = Current MSR[IS] + * r5 = Index of TLB1 temp mapping + * + * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0] + * if needed + */ + +/* 1. Find the index of the entry we're executing in */ + bl invstr /* Find our address */ +invstr: mflr r6 /* Make it accessible */ + mfmsr r7 + rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ + mfspr r7, SPRN_PID0 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ + mfspr r7,SPRN_MAS1 + andis. r7,r7,MAS1_VALID@h + bne match_TLB + mfspr r7,SPRN_PID1 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ + mfspr r7,SPRN_MAS1 + andis. r7,r7,MAS1_VALID@h + bne match_TLB + mfspr r7, SPRN_PID2 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* Fall through, we had to match */ +match_TLB: + mfspr r7,SPRN_MAS0 + rlwinm r3,r7,16,28,31 /* Extract MAS0(Entry) */ + + mfspr r7,SPRN_MAS1 /* Insure IPROT set */ + oris r7,r7,MAS1_IPROT@h + mtspr SPRN_MAS1,r7 + tlbwe + +/* 2. Invalidate all entries except the entry we're executing in */ + mfspr r9,SPRN_TLB1CFG + andi. r9,r9,0xfff + li r6,0 /* Set Entry counter to 0 */ +1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r6,16,12,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ + mtspr SPRN_MAS0,r7 + tlbre + mfspr r7,SPRN_MAS1 + rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ + cmpw r3,r6 + beq skpinv /* Dont update the current execution TLB */ + mtspr SPRN_MAS1,r7 + tlbwe + isync +skpinv: addi r6,r6,1 /* Increment */ + cmpw r6,r9 /* Are we done? */ + bne 1b /* If not, repeat */ + + /* Invalidate TLB0 */ + li r6,0x04 + tlbivax 0,r6 +#ifdef CONFIG_SMP + tlbsync +#endif + /* Invalidate TLB1 */ + li r6,0x0c + tlbivax 0,r6 +#ifdef CONFIG_SMP + tlbsync +#endif + msync + +/* 3. Setup a temp mapping and jump to it */ + andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ + addi r5, r5, 0x1 + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r3,16,12,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ + mtspr SPRN_MAS0,r7 + tlbre + + /* Just modify the entry ID and EPN for the temp mapping */ + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r5,16,12,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ + mtspr SPRN_MAS0,r7 + xori r6,r4,1 /* Setup TMP mapping in the other Address space */ + slwi r6,r6,12 + oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h + ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l + mtspr SPRN_MAS1,r6 + mfspr r6,SPRN_MAS2 + li r7,0 /* temp EPN = 0 */ + rlwimi r7,r6,0,20,31 + mtspr SPRN_MAS2,r7 + tlbwe + + xori r6,r4,1 + slwi r6,r6,5 /* setup new context with other address space */ + bl 1f /* Find our address */ +1: mflr r9 + rlwimi r7,r9,0,20,31 + addi r7,r7,24 + mtspr SRR0,r7 + mtspr SRR1,r6 + rfi + +/* 4. Clear out PIDs & Search info */ + li r6,0 + mtspr SPRN_PID0,r6 + mtspr SPRN_PID1,r6 + mtspr SPRN_PID2,r6 + mtspr SPRN_MAS6,r6 + +/* 5. Invalidate mapping we started in */ + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r3,16,12,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ + mtspr SPRN_MAS0,r7 + tlbre + li r6,0 + mtspr SPRN_MAS1,r6 + tlbwe + /* Invalidate TLB1 */ + li r9,0x0c + tlbivax 0,r9 +#ifdef CONFIG_SMP + tlbsync +#endif + msync + +/* 6. Setup KERNELBASE mapping in TLB1[0] */ + lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ + mtspr SPRN_MAS0,r6 + lis r6,(MAS1_VALID|MAS1_IPROT)@h + ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l + mtspr SPRN_MAS1,r6 + li r7,0 + lis r6,KERNELBASE@h + ori r6,r6,KERNELBASE@l + rlwimi r6,r7,0,20,31 + mtspr SPRN_MAS2,r6 + li r7,(MAS3_SX|MAS3_SW|MAS3_SR) + mtspr SPRN_MAS3,r7 + tlbwe + +/* 7. Jump to KERNELBASE mapping */ + li r7,0 + bl 1f /* Find our address */ +1: mflr r9 + rlwimi r6,r9,0,20,31 + addi r6,r6,24 + mtspr SRR0,r6 + mtspr SRR1,r7 + rfi /* start execution out of TLB1[0] entry */ + +/* 8. Clear out the temp mapping */ + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r5,16,12,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ + mtspr SPRN_MAS0,r7 + tlbre + mtspr SPRN_MAS1,r8 + tlbwe + /* Invalidate TLB1 */ + li r9,0x0c + tlbivax 0,r9 +#ifdef CONFIG_SMP + tlbsync +#endif + msync + + /* Establish the interrupt vector offsets */ + SET_IVOR(0, CriticalInput); + SET_IVOR(1, MachineCheck); + SET_IVOR(2, DataStorage); + SET_IVOR(3, InstructionStorage); + SET_IVOR(4, ExternalInput); + SET_IVOR(5, Alignment); + SET_IVOR(6, Program); + SET_IVOR(7, FloatingPointUnavailable); + SET_IVOR(8, SystemCall); + SET_IVOR(9, AuxillaryProcessorUnavailable); + SET_IVOR(10, Decrementer); + SET_IVOR(11, FixedIntervalTimer); + SET_IVOR(12, WatchdogTimer); + SET_IVOR(13, DataTLBError); + SET_IVOR(14, InstructionTLBError); + SET_IVOR(15, Debug); + SET_IVOR(32, SPEUnavailable); + SET_IVOR(33, SPEFloatingPointData); + SET_IVOR(34, SPEFloatingPointRound); + SET_IVOR(35, PerformanceMonitor); + + /* Establish the interrupt vector base */ + lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ + mtspr SPRN_IVPR,r4 + + /* Setup the defaults for TLB entries */ + li r2,MAS4_TSIZED(BOOKE_PAGESZ_4K) + mtspr SPRN_MAS4, r2 + +#if 0 + /* Enable DOZE */ + mfspr r2,SPRN_HID0 + oris r2,r2,HID0_DOZE@h + mtspr SPRN_HID0, r2 +#endif + + /* + * This is where the main kernel code starts. + */ + + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + + /* ptr to current thread */ + addi r4,r2,THREAD /* init task's THREAD */ + mtspr SPRG3,r4 + + /* stack */ + lis r1,init_thread_union@h + ori r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + + bl early_init + + mfspr r3,SPRN_TLB1CFG + andi. r3,r3,0xfff + lis r4,num_tlbcam_entries@ha + stw r3,num_tlbcam_entries@l(r4) +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + + /* Setup PTE pointers for the Abatron bdiGDB */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + lis r4, KERNELBASE@h + ori r4, r4, KERNELBASE@l + stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ + stw r6, 0(r5) + + /* Let's move on */ + lis r4,start_kernel@h + ori r4,r4,start_kernel@l + lis r3,MSR_KERNEL@h + ori r3,r3,MSR_KERNEL@l + mtspr SRR0,r4 + mtspr SRR1,r3 + rfi /* change context and jump to start_kernel */ + +/* + * Interrupt vector entry code + * + * The Book E MMUs are always on so we don't need to handle + * interrupts in real mode as with previous PPC processors. In + * this case we handle interrupts in the kernel virtual address + * space. + * + * Interrupt vectors are dynamically placed relative to the + * interrupt prefix as determined by the address of interrupt_base. + * The interrupt vectors offsets are programmed using the labels + * for each interrupt vector entry. + * + * Interrupt vectors must be aligned on a 16 byte boundary. + * We align on a 32 byte cache line boundary for good measure. + */ + +#define NORMAL_EXCEPTION_PROLOG \ + mtspr SPRN_SPRG0,r10; /* save two registers to work with */\ + mtspr SPRN_SPRG1,r11; \ + mtspr SPRN_SPRG4W,r1; \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_SRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + beq 1f; \ + mfspr r1,SPRG3; /* if from user, start at top of */\ + lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\ + addi r1,r1,THREAD_SIZE; \ +1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\ + tophys(r11,r1); \ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mfspr r10,SPRG0; \ + stw r10,GPR10(r11); \ + mfspr r12,SPRG1; \ + stw r12,GPR11(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r10,SPRG4R; \ + mfspr r12,SRR0; \ + stw r10,GPR1(r11); \ + mfspr r9,SRR1; \ + stw r10,0(r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception prolog for critical exceptions. This is a little different + * from the normal exception prolog above since a critical exception + * can potentially occur at any point during normal exception processing. + * Thus we cannot use the same SPRG registers as the normal prolog above. + * Instead we use a couple of words of memory at low physical addresses. + * This is OK since we don't support SMP on these processors. For Book E + * processors, we also have a reserved register (SPRG2) that is only used + * in critical exceptions so we can free up a GPR to use as the base for + * indirect access to the critical exception save area. This is necessary + * since the MMU is always on and the save area is offset from KERNELBASE. + */ +#define CRITICAL_EXCEPTION_PROLOG \ + mtspr SPRG2,r8; /* SPRG2 only used in criticals */ \ + lis r8,crit_save@ha; \ + stw r10,crit_r10@l(r8); \ + stw r11,crit_r11@l(r8); \ + mfspr r10,SPRG0; \ + stw r10,crit_sprg0@l(r8); \ + mfspr r10,SPRG1; \ + stw r10,crit_sprg1@l(r8); \ + mfspr r10,SPRG4R; \ + stw r10,crit_sprg4@l(r8); \ + mfspr r10,SPRG5R; \ + stw r10,crit_sprg5@l(r8); \ + mfspr r10,SPRG7R; \ + stw r10,crit_sprg7@l(r8); \ + mfspr r10,SPRN_PID; \ + stw r10,crit_pid@l(r8); \ + mfspr r10,SRR0; \ + stw r10,crit_srr0@l(r8); \ + mfspr r10,SRR1; \ + stw r10,crit_srr1@l(r8); \ + mfspr r8,SPRG2; /* SPRG2 only used in criticals */ \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + lis r11,critical_stack_top@h; \ + ori r11,r11,critical_stack_top@l; \ + beq 1f; \ + /* COMING FROM USER MODE */ \ + mfspr r11,SPRG3; /* if from user, start at top of */\ + lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ + addi r11,r11,THREAD_SIZE; \ +1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ + stw r12,_DEAR(r11); /* since they may have had stuff */\ + mfspr r9,SPRN_ESR; /* in them at the point where the */\ + stw r9,_ESR(r11); /* exception was taken */\ + mfspr r12,CSRR0; \ + stw r1,GPR1(r11); \ + mfspr r9,CSRR1; \ + stw r1,0(r11); \ + tovirt(r1,r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception prolog for machine check exceptions. This is similar to + * the critical exception prolog, except that machine check exceptions + * have their own save area. For Book E processors, we also have a + * reserved register (SPRG6) that is only used in machine check exceptions + * so we can free up a GPR to use as the base for indirect access to the + * machine check exception save area. This is necessary since the MMU + * is always on and the save area is offset from KERNELBASE. + */ +#define MCHECK_EXCEPTION_PROLOG \ + mtspr SPRG6W,r8; /* SPRG6 used in machine checks */ \ + lis r8,mcheck_save@ha; \ + stw r10,mcheck_r10@l(r8); \ + stw r11,mcheck_r11@l(r8); \ + mfspr r10,SPRG0; \ + stw r10,mcheck_sprg0@l(r8); \ + mfspr r10,SPRG1; \ + stw r10,mcheck_sprg1@l(r8); \ + mfspr r10,SPRG4R; \ + stw r10,mcheck_sprg4@l(r8); \ + mfspr r10,SPRG5R; \ + stw r10,mcheck_sprg5@l(r8); \ + mfspr r10,SPRG7R; \ + stw r10,mcheck_sprg7@l(r8); \ + mfspr r10,SPRN_PID; \ + stw r10,mcheck_pid@l(r8); \ + mfspr r10,SRR0; \ + stw r10,mcheck_srr0@l(r8); \ + mfspr r10,SRR1; \ + stw r10,mcheck_srr1@l(r8); \ + mfspr r10,CSRR0; \ + stw r10,mcheck_csrr0@l(r8); \ + mfspr r10,CSRR1; \ + stw r10,mcheck_csrr1@l(r8); \ + mfspr r8,SPRG6R; /* SPRG6 used in machine checks */ \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_MCSRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + lis r11,mcheck_stack_top@h; \ + ori r11,r11,mcheck_stack_top@l; \ + beq 1f; \ + /* COMING FROM USER MODE */ \ + mfspr r11,SPRG3; /* if from user, start at top of */\ + lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ + addi r11,r11,THREAD_SIZE; \ +1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ + stw r12,_DEAR(r11); /* since they may have had stuff */\ + mfspr r9,SPRN_ESR; /* in them at the point where the */\ + stw r9,_ESR(r11); /* exception was taken */\ + mfspr r12,MCSRR0; \ + stw r1,GPR1(r11); \ + mfspr r9,MCSRR1; \ + stw r1,0(r11); \ + tovirt(r1,r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception vectors. + */ +#define START_EXCEPTION(label) \ + .align 5; \ +label: + +#define FINISH_EXCEPTION(func) \ + bl transfer_to_handler_full; \ + .long func; \ + .long ret_from_except_full + +#define EXCEPTION(n, label, hdlr, xfer) \ + START_EXCEPTION(label); \ + NORMAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + xfer(n, hdlr) + +#define CRITICAL_EXCEPTION(n, label, hdlr) \ + START_EXCEPTION(label); \ + CRITICAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ + NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define MCHECK_EXCEPTION(n, label, hdlr) \ + START_EXCEPTION(label); \ + MCHECK_EXCEPTION_PROLOG; \ + mfspr r5,SPRN_ESR; \ + stw r5,_ESR(r11); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ + NOCOPY, mcheck_transfer_to_handler, \ + ret_from_mcheck_exc) + +#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \ + li r10,trap; \ + stw r10,TRAP(r11); \ + lis r10,msr@h; \ + ori r10,r10,msr@l; \ + copyee(r10, r9); \ + bl tfer; \ + .long hdlr; \ + .long ret + +#define COPY_EE(d, s) rlwimi d,s,0,16,16 +#define NOCOPY(d, s) + +#define EXC_XFER_STD(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ + ret_from_except) + +#define EXC_XFER_EE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_EE_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ + ret_from_except) + +interrupt_base: + /* Critical Input Interrupt */ + CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + + /* Machine Check Interrupt */ + MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + + /* Data Storage Interrupt */ + START_EXCEPTION(DataStorage) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mfcr r11 + mtspr SPRG7W, r11 + + /* + * Check if it was a store fault, if not then bail + * because a user tried to access a kernel or + * read-protected page. Otherwise, get the + * offending address and handle it. + */ + mfspr r10, SPRN_ESR + andis. r10, r10, ESR_ST@h + beq 2f + + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + ori r11, r11, TASK_SIZE@l + cmplw 0, r10, r11 + bge 2f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) +4: + rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r11, 0(r11) /* Get L1 entry */ + rlwinm. r12, r11, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */ + lwz r11, 0(r12) /* Get Linux PTE */ + + /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */ + andi. r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE + cmpwi 0, r13, _PAGE_RW|_PAGE_USER + bne 2f /* Bail if not */ + + /* Update 'changed'. */ + ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r11, 0(r12) /* Update Linux page table */ + + /* MAS2 not updated as the entry does exist in the tlb, this + fault taken to detect state transition (eg: COW -> DIRTY) + */ + lis r12, MAS3_RPN@h + ori r12, r12, _PAGE_HWEXEC | MAS3_RPN@l + and r11, r11, r12 + rlwimi r11, r11, 31, 27, 27 /* SX <- _PAGE_HWEXEC */ + ori r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */ + + /* update search PID in MAS6, AS = 0 */ + mfspr r12, SPRN_PID0 + slwi r12, r12, 16 + mtspr SPRN_MAS6, r12 + + /* find the TLB index that caused the fault. It has to be here. */ + tlbsx 0, r10 + + mtspr SPRN_MAS3,r11 + tlbwe + + /* Done...restore registers and get out of here. */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + rfi /* Force context change */ + +2: + /* + * The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b data_access + + /* Instruction Storage Interrupt */ + START_EXCEPTION(InstructionStorage) + NORMAL_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR and save it */ + stw r5,_ESR(r11) + mr r4,r12 /* Pass SRR0 as arg2 */ + li r5,0 /* Pass zero as arg3 */ + EXC_XFER_EE_LITE(0x0400, handle_page_fault) + + /* External Input Interrupt */ + EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) + + /* Alignment Interrupt */ + START_EXCEPTION(Alignment) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ + stw r4,_DEAR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x0600, AlignmentException) + + /* Program Interrupt */ + START_EXCEPTION(Program) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_ESR /* Grab the ESR and save it */ + stw r4,_ESR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_STD(0x0700, ProgramCheckException) + + /* Floating Point Unavailable Interrupt */ + EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) + + /* System Call Interrupt */ + START_EXCEPTION(SystemCall) + NORMAL_EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0x0c00, DoSyscall) + + /* Auxillary Processor Unavailable Interrupt */ + EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + + /* Decrementer Interrupt */ + START_EXCEPTION(Decrementer) + NORMAL_EXCEPTION_PROLOG + lis r0,TSR_DIS@h /* Setup the DEC interrupt mask */ + mtspr SPRN_TSR,r0 /* Clear the DEC interrupt */ + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_LITE(0x0900, timer_interrupt) + + /* Fixed Internal Timer Interrupt */ + /* TODO: Add FIT support */ + EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + + /* Watchdog Timer Interrupt */ + /* TODO: Add watchdog support */ + CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException) + + /* Data TLB Error Interrupt */ + START_EXCEPTION(DataTLBError) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mfcr r11 + mtspr SPRG7W, r11 + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + ori r11, r11, TASK_SIZE@l + cmplw 5, r10, r11 + blt 5, 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MAS1 /* Set TID to 0 */ + li r13,MAS1_TID@l + andc r12,r12,r13 + mtspr SPRN_MAS1,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + +4: + rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r11, 0(r11) /* Get L1 entry */ + rlwinm. r12, r11, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */ + lwz r11, 0(r12) /* Get Linux PTE */ + andi. r13, r11, _PAGE_PRESENT + beq 2f + + ori r11, r11, _PAGE_ACCESSED + stw r11, 0(r12) + + /* Jump to common tlb load */ + b finish_tlb_load +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b data_access + + /* Instruction TLB Error Interrupt */ + /* + * Nearly the same as above, except we get our + * information from different registers and bailout + * to a different point. + */ + START_EXCEPTION(InstructionTLBError) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mfcr r11 + mtspr SPRG7W, r11 + mfspr r10, SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11, TASK_SIZE@h + ori r11, r11, TASK_SIZE@l + cmplw 5, r10, r11 + blt 5, 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MAS1 /* Set TID to 0 */ + li r13,MAS1_TID@l + andc r12,r12,r13 + mtspr SPRN_MAS1,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + +4: + rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r11, 0(r11) /* Get L1 entry */ + rlwinm. r12, r11, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */ + lwz r11, 0(r12) /* Get Linux PTE */ + andi. r13, r11, _PAGE_PRESENT + beq 2f + + ori r11, r11, _PAGE_ACCESSED + stw r11, 0(r12) + + /* Jump to common TLB load point */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b InstructionStorage + +#ifdef CONFIG_SPE + /* SPE Unavailable */ + START_EXCEPTION(SPEUnavailable) + NORMAL_EXCEPTION_PROLOG + bne load_up_spe + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x2010, KernelSPE) +#else + EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE) +#endif /* CONFIG_SPE */ + + /* SPE Floating Point Data */ +#ifdef CONFIG_SPE + EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); +#else + EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE) +#endif /* CONFIG_SPE */ + + /* SPE Floating Point Round */ + EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE) + + /* Performance Monitor */ + EXCEPTION(0x2060, PerformanceMonitor, UnknownException, EXC_XFER_EE) + +/* Check for a single step debug exception while in an exception + * handler before state has been saved. This is to catch the case + * where an instruction that we are trying to single step causes + * an exception (eg ITLB/DTLB miss) and thus the first instruction of + * the exception handler generates a single step debug exception. + * + * If we get a debug trap on the first instruction of an exception handler, + * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is + * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR). + * The exception handler was handling a non-critical interrupt, so it will + * save (and later restore) the MSR via SPRN_SRR1, which will still have + * the MSR_DE bit set. + */ + /* Debug Interrupt */ + START_EXCEPTION(Debug) + CRITICAL_EXCEPTION_PROLOG + + /* + * If this is a single step or branch-taken exception in an + * exception entry sequence, it was probably meant to apply to + * the code where the exception occurred (since exception entry + * doesn't turn off DE automatically). We simulate the effect + * of turning off DE on entry to an exception handler by turning + * off DE in the CSRR1 value and clearing the debug status. + */ + mfspr r10,SPRN_DBSR /* check single-step/branch taken */ + andis. r10,r10,(DBSR_IC|DBSR_BT)@h + beq+ 1f + andi. r0,r9,MSR_PR /* check supervisor */ + beq 2f /* branch if we need to fix it up... */ + + /* continue normal handling for a critical exception... */ +1: mfspr r4,SPRN_DBSR + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_TEMPLATE(DebugException, 0x2002, \ + (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ + NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) + + /* here it looks like we got an inappropriate debug exception. */ +2: rlwinm r9,r9,0,~MSR_DE /* clear DE in the CSRR1 value */ + mtspr SPRN_DBSR,r10 /* clear the IC/BT debug intr status */ + /* restore state and get out */ + lwz r10,_CCR(r11) + lwz r0,GPR0(r11) + lwz r1,GPR1(r11) + mtcrf 0x80,r10 + mtspr CSRR0,r12 + mtspr CSRR1,r9 + lwz r9,GPR9(r11) + + mtspr SPRG2,r8; /* SPRG2 only used in criticals */ + lis r8,crit_save@ha; + lwz r10,crit_r10@l(r8) + lwz r11,crit_r11@l(r8) + mfspr r8,SPRG2 + + rfci + b . + +/* + * Local functions + */ + /* + * Data TLB exceptions will bail out to this point + * if they can't resolve the lightweight TLB fault. + */ +data_access: + NORMAL_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r11) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + andis. r10,r5,(ESR_ILK|ESR_DLK)@h + bne 1f + EXC_XFER_EE_LITE(0x0300, handle_page_fault) +1: + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x0300, CacheLockingException) + +/* + + * Both the instruction and data TLB miss get to this + * point to load the TLB. + * r10 - EA of fault + * r11 - TLB (info from Linux PTE) + * r12, r13 - available to use + * CR5 - results of addr < TASK_SIZE + * MAS0, MAS1 - loaded with proper value when we get here + * MAS2, MAS3 - will need additional info from Linux PTE + * Upon exit, we reload everything and RFI. + */ +finish_tlb_load: + /* + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + + mfspr r12, SPRN_MAS2 + rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ + mtspr SPRN_MAS2, r12 + + bge 5, 1f + + /* addr > TASK_SIZE */ + li r10, (MAS3_UX | MAS3_UW | MAS3_UR) + andi. r13, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC) + andi. r12, r11, _PAGE_USER /* Test for _PAGE_USER */ + iseleq r12, 0, r10 + and r10, r12, r13 + srwi r12, r10, 1 + or r12, r12, r10 /* Copy user perms into supervisor */ + b 2f + + /* addr <= TASK_SIZE */ +1: rlwinm r12, r11, 31, 29, 29 /* Extract _PAGE_HWWRITE into SW */ + ori r12, r12, (MAS3_SX | MAS3_SR) + +2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ + mtspr SPRN_MAS3, r11 + tlbwe + + /* Done...restore registers and get out of here. */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + rfi /* Force context change */ + +#ifdef CONFIG_SPE +/* Note that the SPE support is closely modeled after the AltiVec + * support. Changes to one are likely to be applicable to the + * other! */ +load_up_spe: +/* + * Disable SPE for the task which had SPE previously, + * and save its SPE registers in its thread_struct. + * Enables SPE for use in the kernel on return. + * On SMP we know the SPE units are free, since we give it up every + * switch. -- Kumar + */ + mfmsr r5 + oris r5,r5,MSR_SPE@h + mtmsr r5 /* enable use of SPE now */ + isync +/* + * For SMP, we don't do lazy SPE switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_spe in switch_to. + */ +#ifndef CONFIG_SMP + lis r3,last_task_used_spe@ha + lwz r4,last_task_used_spe@l(r3) + cmpi 0,r4,0 + beq 1f + addi r4,r4,THREAD /* want THREAD of last_task_used_spe */ + SAVE_32EVR(0,r10,r4) + evxor evr10, evr10, evr10 /* clear out evr10 */ + evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */ + li r5,THREAD_ACC + evstddx evr10, r4, r5 /* save off accumulator */ + lwz r5,PT_REGS(r4) + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r10,MSR_SPE@h + andc r4,r4,r10 /* disable SPE for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of SPE after return */ + oris r9,r9,MSR_SPE@h + mfspr r5,SPRG3 /* current task's THREAD (phys) */ + li r4,1 + li r10,THREAD_ACC + stw r4,THREAD_USED_SPE(r5) + evlddx evr4,r10,r5 + evmra evr4,evr4 + REST_32EVR(0,r10,r5) +#ifndef CONFIG_SMP + subi r4,r5,THREAD + stw r4,last_task_used_spe@l(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ +2: REST_4GPRS(3, r11) + lwz r10,_CCR(r11) + REST_GPR(1, r11) + mtcr r10 + lwz r10,_LINK(r11) + mtlr r10 + REST_GPR(10, r11) + mtspr SRR1,r9 + mtspr SRR0,r12 + REST_GPR(9, r11) + REST_GPR(12, r11) + lwz r11,GPR11(r11) + SYNC + rfi + + + +/* + * SPE unavailable trap from kernel - print a message, but let + * the task use SPE in the kernel until it returns to user mode. + */ +KernelSPE: + lwz r3,_MSR(r1) + oris r3,r3,MSR_SPE@h + stw r3,_MSR(r1) /* enable use of SPE after return */ + lis r3,87f@h + ori r3,r3,87f@l + mr r4,r2 /* current */ + lwz r5,_NIP(r1) + bl printk + b ret_from_except +87: .string "SPE used in kernel (task=%p, pc=%x) \n" + .align 4,0 + +#endif /* CONFIG_SPE */ + +/* + * Global functions + */ + +/* + * extern void loadcam_entry(unsigned int index) + * + * Load TLBCAM[index] entry in to the L2 CAM MMU + */ +_GLOBAL(loadcam_entry) + lis r4,TLBCAM@ha + addi r4,r4,TLBCAM@l + mulli r5,r3,20 + add r3,r5,r4 + lwz r4,0(r3) + mtspr SPRN_MAS0,r4 + lwz r4,4(r3) + mtspr SPRN_MAS1,r4 + lwz r4,8(r3) + mtspr SPRN_MAS2,r4 + lwz r4,12(r3) + mtspr SPRN_MAS3,r4 + tlbwe + isync + blr + +/* + * extern void giveup_altivec(struct task_struct *prev) + * + * The e500 core does not have an AltiVec unit. + */ +_GLOBAL(giveup_altivec) + blr + +#ifdef CONFIG_SPE +/* + * extern void giveup_spe(struct task_struct *prev) + * + */ +_GLOBAL(giveup_spe) + mfmsr r5 + oris r5,r5,MSR_SPE@h + SYNC + mtmsr r5 /* enable use of SPE now */ + isync + cmpi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + lwz r5,PT_REGS(r3) + cmpi 0,r5,0 + SAVE_32EVR(0, r4, r3) + evxor evr6, evr6, evr6 /* clear out evr6 */ + evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */ + li r4,THREAD_ACC + evstddx evr6, r4, r3 /* save off accumulator */ + beq 1f + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_SPE@h + andc r4,r4,r3 /* disable SPE for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + lis r4,last_task_used_spe@ha + stw r5,last_task_used_spe@l(r4) +#endif /* CONFIG_SMP */ + blr +#endif /* CONFIG_SPE */ + +/* + * extern void giveup_fpu(struct task_struct *prev) + * + * The e500 core does not have an FPU. + */ +_GLOBAL(giveup_fpu) + blr + +/* + * extern void abort(void) + * + * At present, this routine just applies a system reset. + */ +_GLOBAL(abort) + li r13,0 + mtspr SPRN_DBCR0,r13 /* disable all debug events */ + mfmsr r13 + ori r13,r13,MSR_DE@l /* Enable Debug Events */ + mtmsr r13 + mfspr r13,SPRN_DBCR0 + lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h + mtspr SPRN_DBCR0,r13 + +_GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r4, 0x4(r5) +#endif + mtspr SPRN_PID,r3 + isync /* Force context change */ + blr + +/* + * We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ + .data +_GLOBAL(sdata) +_GLOBAL(empty_zero_page) + .space 4096 +_GLOBAL(swapper_pg_dir) + .space 4096 + + .section .bss +/* Stack for handling critical exceptions from kernel mode */ +critical_stack_bottom: + .space 4096 +critical_stack_top: + .previous + +/* Stack for handling machine check exceptions from kernel mode */ +mcheck_stack_bottom: + .space 4096 +mcheck_stack_top: + .previous + +/* + * This area is used for temporarily saving registers during the + * critical and machine check exception prologs. It must always + * follow the page aligned allocations, so it starts on a page + * boundary, ensuring that all crit_save areas are in a single + * page. + */ + +/* crit_save */ +_GLOBAL(crit_save) + .space 4 +_GLOBAL(crit_r10) + .space 4 +_GLOBAL(crit_r11) + .space 4 +_GLOBAL(crit_sprg0) + .space 4 +_GLOBAL(crit_sprg1) + .space 4 +_GLOBAL(crit_sprg4) + .space 4 +_GLOBAL(crit_sprg5) + .space 4 +_GLOBAL(crit_sprg7) + .space 4 +_GLOBAL(crit_pid) + .space 4 +_GLOBAL(crit_srr0) + .space 4 +_GLOBAL(crit_srr1) + .space 4 + +/* mcheck_save */ +_GLOBAL(mcheck_save) + .space 4 +_GLOBAL(mcheck_r10) + .space 4 +_GLOBAL(mcheck_r11) + .space 4 +_GLOBAL(mcheck_sprg0) + .space 4 +_GLOBAL(mcheck_sprg1) + .space 4 +_GLOBAL(mcheck_sprg4) + .space 4 +_GLOBAL(mcheck_sprg5) + .space 4 +_GLOBAL(mcheck_sprg7) + .space 4 +_GLOBAL(mcheck_pid) + .space 4 +_GLOBAL(mcheck_srr0) + .space 4 +_GLOBAL(mcheck_srr1) + .space 4 +_GLOBAL(mcheck_csrr0) + .space 4 +_GLOBAL(mcheck_csrr1) + .space 4 + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ +_GLOBAL(cmd_line) + .space 512 + +/* + * Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 + + diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c --- a/arch/ppc/kernel/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/kernel/irq.c 2004-06-26 17:09:20 -07:00 @@ -241,7 +241,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = dev_id; action->next = NULL; @@ -628,7 +628,9 @@ static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer, unsigned long count, void *data) { - cpumask_t *mask = (cpumask_t *)data, full_count = count, err; + int err; + int full_count = count; + cpumask_t *mask = (cpumask_t *)data; cpumask_t new_value; err = cpumask_parse(buffer, count, new_value); diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S --- a/arch/ppc/kernel/misc.S 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/kernel/misc.S 2004-06-26 17:09:20 -07:00 @@ -253,6 +253,24 @@ mtmsr r7 blr +_GLOBAL(low_choose_7447a_dfs) + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Calc new HID1 value */ + mfspr r4,SPRN_HID1 + insrwi r4,r3,1,9 /* insert parameter into bit 9 */ + sync + mtspr SPRN_HID1,r4 + sync + isync + + /* Return */ + mtmsr r7 + blr + #endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */ /* void local_save_flags_ptr(unsigned long *flags) */ @@ -419,7 +437,24 @@ ble 1b isync -#else /* !(CONFIG_40x || CONFIG_44x) */ +#elif defined(CONFIG_FSL_BOOKE) + /* Invalidate all entries in TLB0 */ + li r3, 0x04 + tlbivax 0,3 + /* Invalidate all entries in TLB1 */ + li r3, 0x0c + tlbivax 0,3 + /* Invalidate all entries in TLB2 */ + li r3, 0x14 + tlbivax 0,3 + /* Invalidate all entries in TLB3 */ + li r3, 0x1c + tlbivax 0,3 + msync +#ifdef CONFIG_SMP + tlbsync +#endif /* CONFIG_SMP */ +#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -487,7 +522,20 @@ tlbwe r3, r3, PPC44x_TLB_PAGEID isync 10: -#else /* !(CONFIG_40x || CONFIG_44x) */ +#elif defined(CONFIG_FSL_BOOKE) + rlwinm r4, r3, 0, 0, 19 + ori r5, r4, 0x08 /* TLBSEL = 1 */ + ori r6, r4, 0x10 /* TLBSEL = 2 */ + ori r7, r4, 0x18 /* TLBSEL = 3 */ + tlbivax 0, r4 + tlbivax 0, r5 + tlbivax 0, r6 + tlbivax 0, r7 + msync +#if defined(CONFIG_SMP) + tlbsync +#endif /* CONFIG_SMP */ +#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -544,6 +592,10 @@ lis r3, KERNELBASE@h iccci 0,r3 #endif +#elif CONFIG_FSL_BOOKE + mfspr r3,SPRN_L1CSR1 + ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR + mtspr SPRN_L1CSR1,r3 #else mfspr r3,PVR rlwinm r3,r3,16,16,31 @@ -1047,7 +1099,7 @@ * and exceptions as if the cpu had performed the load or store. */ -#if defined(CONFIG_4xx) +#if defined(CONFIG_4xx) || defined(CONFIG_E500) _GLOBAL(cvt_fd) lfs 0,0(r3) stfd 0,0(r4) diff -Nru a/arch/ppc/kernel/ppc-stub.c b/arch/ppc/kernel/ppc-stub.c --- a/arch/ppc/kernel/ppc-stub.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/kernel/ppc-stub.c 2004-06-26 17:09:20 -07:00 @@ -105,6 +105,8 @@ #include #include #include +#include +#include #include #include @@ -855,3 +857,23 @@ return 1; } #endif + +static void sysrq_handle_gdb(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + printk("Entering GDB stub\n"); + breakpoint(); +} +static struct sysrq_key_op sysrq_gdb_op = { + .handler = sysrq_handle_gdb, + .help_msg = "Gdb", + .action_msg = "GDB", +}; + +static int gdb_register_sysrq(void) +{ + printk("Registering GDB sysrq handler\n"); + register_sysrq_key('g', &sysrq_gdb_op); + return 0; +} +module_init(gdb_register_sysrq); diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c --- a/arch/ppc/kernel/ppc_ksyms.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/kernel/ppc_ksyms.c 2004-06-26 17:09:20 -07:00 @@ -68,7 +68,6 @@ long long __ashrdi3(long long, int); long long __ashldi3(long long, int); long long __lshrdi3(long long, int); -int abs(int); extern unsigned long mm_ptov (unsigned long paddr); @@ -199,6 +198,10 @@ EXPORT_SYMBOL(last_task_used_altivec); EXPORT_SYMBOL(giveup_altivec); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE +EXPORT_SYMBOL(last_task_used_spe); +EXPORT_SYMBOL(giveup_spe); +#endif /* CONFIG_SPE */ #ifdef CONFIG_SMP EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_hw_index); @@ -272,8 +275,6 @@ EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memchr); -EXPORT_SYMBOL(abs); - #if defined(CONFIG_FB_VGA16_MODULE) EXPORT_SYMBOL(screen_info); #endif @@ -324,7 +325,7 @@ EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); #endif /* CONFIG_8xx */ -#if defined(CONFIG_8xx) || defined(CONFIG_40x) +#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) EXPORT_SYMBOL(__res); #endif #if defined(CONFIG_8xx) diff -Nru a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c --- a/arch/ppc/kernel/process.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/kernel/process.c 2004-06-26 17:09:18 -07:00 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,7 @@ struct task_struct *last_task_used_math = NULL; struct task_struct *last_task_used_altivec = NULL; +struct task_struct *last_task_used_spe = NULL; static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; @@ -177,6 +179,34 @@ EXPORT_SYMBOL(enable_kernel_altivec); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE +int +dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs) +{ + if (regs->msr & MSR_SPE) + giveup_spe(current); + /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */ + memcpy(evrregs, ¤t->thread.evr[0], sizeof(u32) * 35); + return 1; +} + +void +enable_kernel_spe(void) +{ + WARN_ON(preemptible()); + +#ifdef CONFIG_SMP + if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) + giveup_spe(current); + else + giveup_spe(NULL); /* just enable SPE for kernel - force */ +#else + giveup_spe(last_task_used_spe); +#endif /* __SMP __ */ +} +EXPORT_SYMBOL(enable_kernel_spe); +#endif /* CONFIG_SPE */ + void enable_kernel_fp(void) { @@ -244,6 +274,17 @@ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))) giveup_altivec(prev); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + /* + * If the previous thread used spe in the last quantum + * (thus changing spe regs) then save them. + * + * On SMP we always save/restore spe regs just to avoid the + * complexity of changing processors. + */ + if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE))) + giveup_spe(prev); +#endif /* CONFIG_SPE */ #endif /* CONFIG_SMP */ /* Avoid the trap. On smp this this never happens since @@ -251,6 +292,13 @@ */ if (new->thread.regs && last_task_used_altivec == new) new->thread.regs->msr |= MSR_VEC; +#ifdef CONFIG_SPE + /* Avoid the trap. On smp this this never happens since + * we don't set last_task_used_spe + */ + if (new->thread.regs && last_task_used_spe == new) + new->thread.regs->msr |= MSR_SPE; +#endif /* CONFIG_SPE */ new_thread = &new->thread; old_thread = ¤t->thread; last = _switch(old_thread, new_thread); @@ -354,6 +402,10 @@ if (regs->msr & MSR_VEC) giveup_altivec(current); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + if (regs->msr & MSR_SPE) + giveup_spe(current); +#endif /* CONFIG_SPE */ preempt_enable(); } @@ -438,18 +490,45 @@ current->thread.vrsave = 0; current->thread.used_vr = 0; #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + memset(current->thread.evr, 0, sizeof(current->thread.evr)); + current->thread.acc = 0; + current->thread.spefscr = 0; + current->thread.used_spe = 0; +#endif /* CONFIG_SPE */ } +#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \ + | PR_FP_EXC_RES | PR_FP_EXC_INV) + int set_fpexc_mode(struct task_struct *tsk, unsigned int val) { struct pt_regs *regs = tsk->thread.regs; - if (val > PR_FP_EXC_PRECISE) + /* This is a bit hairy. If we are an SPE enabled processor + * (have embedded fp) we store the IEEE exception enable flags in + * fpexc_mode. fpexc_mode is also used for setting FP exception + * mode (asyn, precise, disabled) for 'Classic' FP. */ + if (val & PR_FP_EXC_SW_ENABLE) { +#ifdef CONFIG_SPE + tsk->thread.fpexc_mode = val & + (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); +#else return -EINVAL; - tsk->thread.fpexc_mode = __pack_fe01(val); - if (regs != NULL && (regs->msr & MSR_FP) != 0) - regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1)) - | tsk->thread.fpexc_mode; +#endif + } else { + /* on a CONFIG_SPE this does not hurt us. The bits that + * __pack_fe01 use do not overlap with bits used for + * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits + * on CONFIG_SPE implementations are reserved so writing to + * them does not change anything */ + if (val > PR_FP_EXC_PRECISE) + return -EINVAL; + tsk->thread.fpexc_mode = __pack_fe01(val); + if (regs != NULL && (regs->msr & MSR_FP) != 0) + regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1)) + | tsk->thread.fpexc_mode; + } return 0; } @@ -457,7 +536,14 @@ { unsigned int val; - val = __unpack_fe01(tsk->thread.fpexc_mode); + if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) +#ifdef CONFIG_SPE + val = tsk->thread.fpexc_mode; +#else + return -EINVAL; +#endif + else + val = __unpack_fe01(tsk->thread.fpexc_mode); return put_user(val, (unsigned int *) adr); } @@ -506,6 +592,10 @@ if (regs->msr & MSR_VEC) giveup_altivec(current); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + if (regs->msr & MSR_SPE) + giveup_spe(current); +#endif /* CONFIG_SPE */ preempt_enable(); error = do_execve(filename, (char __user *__user *) a1, (char __user *__user *) a2, regs); diff -Nru a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c --- a/arch/ppc/kernel/ptrace.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc/kernel/ptrace.c 2004-06-26 17:09:16 -07:00 @@ -35,7 +35,7 @@ /* * Set of msr bits that gdb can change on behalf of a process. */ -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) #define MSR_DEBUGCHANGE 0 #else #define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) @@ -131,13 +131,77 @@ } #endif +#ifdef CONFIG_SPE + +/* + * For get_evrregs/set_evrregs functions 'data' has the following layout: + * + * struct { + * u32 evr[32]; + * u64 acc; + * u32 spefscr; + * } + */ + +/* + * Get contents of SPE register state in task TASK. + */ +static inline int get_evrregs(unsigned long *data, struct task_struct *task) +{ + int i; + + if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long))) + return -EFAULT; + + /* copy SPEFSCR */ + if (__put_user(task->thread.spefscr, &data[34])) + return -EFAULT; + + /* copy SPE registers EVR[0] .. EVR[31] */ + for (i = 0; i < 32; i++, data++) + if (__put_user(task->thread.evr[i], data)) + return -EFAULT; + + /* copy ACC */ + if (__put_user64(task->thread.acc, (unsigned long long *)data)) + return -EFAULT; + + return 0; +} + +/* + * Write contents of SPE register state into task TASK. + */ +static inline int set_evrregs(struct task_struct *task, unsigned long *data) +{ + int i; + + if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long))) + return -EFAULT; + + /* copy SPEFSCR */ + if (__get_user(task->thread.spefscr, &data[34])) + return -EFAULT; + + /* copy SPE registers EVR[0] .. EVR[31] */ + for (i = 0; i < 32; i++, data++) + if (__get_user(task->thread.evr[i], data)) + return -EFAULT; + /* copy ACC */ + if (__get_user64(task->thread.acc, (unsigned long long*)data)) + return -EFAULT; + + return 0; +} +#endif /* CONFIG_SPE */ + static inline void set_single_step(struct task_struct *task) { struct pt_regs *regs = task->thread.regs; if (regs != NULL) { -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC; /* MSR.DE should already be set */ #else @@ -152,7 +216,7 @@ struct pt_regs *regs = task->thread.regs; if (regs != NULL) { -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) task->thread.dbcr0 = 0; #else regs->msr &= ~MSR_SE; @@ -358,6 +422,23 @@ giveup_altivec(child); preempt_enable(); ret = set_vrregs(child, (unsigned long *)data); + break; +#endif +#ifdef CONFIG_SPE + case PTRACE_GETEVRREGS: + /* Get the child spe register state. */ + if (child->thread.regs->msr & MSR_SPE) + giveup_spe(child); + ret = get_evrregs((unsigned long *)data, child); + break; + + case PTRACE_SETEVRREGS: + /* Set the child spe register state. */ + /* this is to clear the MSR_SPE bit to force a reload + * of register state from memory */ + if (child->thread.regs->msr & MSR_SPE) + giveup_spe(child); + ret = set_evrregs(child, (unsigned long *)data); break; #endif diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c --- a/arch/ppc/kernel/setup.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/kernel/setup.c 2004-06-26 17:09:20 -07:00 @@ -54,7 +54,6 @@ extern void power4_idle(void); extern boot_infos_t *boot_infos; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned char aux_device_present; struct ide_machdep_calls ppc_ide_md; char *sysmap; diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c --- a/arch/ppc/kernel/signal.c 2004-06-26 17:09:21 -07:00 +++ b/arch/ppc/kernel/signal.c 2004-06-26 17:09:21 -07:00 @@ -183,8 +183,8 @@ /* * Save the current user registers on the user stack. - * We only save the altivec registers if the process has used - * altivec instructions at some point. + * We only save the altivec/spe registers if the process has used + * altivec/spe instructions at some point. */ static int save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret) @@ -198,6 +198,10 @@ if (current->thread.used_vr && (regs->msr & MSR_VEC)) giveup_altivec(current); #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + if (current->thread.used_spe && (regs->msr & MSR_SPE)) + giveup_spe(current); +#endif /* CONFIG_ALTIVEC */ preempt_enable(); if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE) @@ -229,6 +233,24 @@ return 1; #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + /* save spe registers */ + if (current->thread.used_spe) { + if (__copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32))) + return 1; + /* set MSR_SPE in the saved MSR value to indicate that + frame->mc_vregs contains valid data */ + if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR])) + return 1; + } + /* else assert((regs->msr & MSR_SPE) == 0) */ + + /* We always copy to/from spefscr */ + if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG)) + return 1; +#endif /* CONFIG_SPE */ + if (sigret) { /* Set up the sigreturn trampoline: li r0,sigret; sc */ if (__put_user(0x38000000UL + sigret, &frame->tramp[0]) @@ -249,7 +271,7 @@ restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig) { unsigned long save_r2; -#ifdef CONFIG_ALTIVEC +#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE) unsigned long msr; #endif @@ -289,6 +311,23 @@ if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32])) return 1; #endif /* CONFIG_ALTIVEC */ + +#ifdef CONFIG_SPE + /* force the process to reload the spe registers from + current->thread when it next does spe instructions */ + regs->msr &= ~MSR_SPE; + if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { + /* restore spe registers from the stack */ + if (__copy_from_user(current->thread.evr, &sr->mc_vregs, + sizeof(sr->mc_vregs))) + return 1; + } else if (current->thread.used_spe) + memset(¤t->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); + + /* Always get SPEFSCR back */ + if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG)) + return 1; +#endif /* CONFIG_SPE */ return 0; } diff -Nru a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c --- a/arch/ppc/kernel/time.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc/kernel/time.c 2004-06-26 17:09:19 -07:00 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -107,17 +108,23 @@ return delta; } -extern unsigned long prof_cpu_mask; -extern unsigned int * prof_buffer; -extern unsigned long prof_len; -extern unsigned long prof_shift; extern char _stext; -static inline void ppc_do_profile (unsigned long nip) +static inline void ppc_do_profile (struct pt_regs *regs) { + unsigned long nip; + extern unsigned long prof_cpu_mask; + + profile_hook(regs); + + if (user_mode(regs)) + return; + if (!prof_buffer) return; + nip = instruction_pointer(regs); + /* * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. * (default is all CPUs.) @@ -156,8 +163,9 @@ while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) { jiffy_stamp += tb_ticks_per_jiffy; - if (!user_mode(regs)) - ppc_do_profile(instruction_pointer(regs)); + + ppc_do_profile(regs); + if (smp_processor_id()) continue; diff -Nru a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c --- a/arch/ppc/kernel/traps.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc/kernel/traps.c 2004-06-26 17:09:16 -07:00 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -102,8 +103,7 @@ do_exit(err); } -void -_exception(int signr, struct pt_regs *regs, int code, unsigned long addr) +void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) { siginfo_t info; @@ -171,6 +171,11 @@ /* On 4xx, the reason for the machine check or program exception is in the ESR. */ #define get_reason(regs) ((regs)->dsisr) +#ifndef CONFIG_E500 +#define get_mc_reason(regs) ((regs)->dsisr) +#else +#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) +#endif #define REASON_FP 0 #define REASON_ILLEGAL ESR_PIL #define REASON_PRIVILEGED ESR_PPR @@ -184,6 +189,7 @@ /* On non-4xx, the reason for the machine check or program exception is in the MSR. */ #define get_reason(regs) ((regs)->msr) +#define get_mc_reason(regs) ((regs)->msr) #define REASON_FP 0x100000 #define REASON_ILLEGAL 0x80000 #define REASON_PRIVILEGED 0x40000 @@ -193,10 +199,9 @@ #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif -void -MachineCheckException(struct pt_regs *regs) +void MachineCheckException(struct pt_regs *regs) { - unsigned long reason = get_reason(regs); + unsigned long reason = get_mc_reason(regs); if (user_mode(regs)) { regs->msr |= MSR_RI; @@ -256,7 +261,37 @@ /* Clear MCSR */ mtspr(SPRN_MCSR, mcsr); } -#else /* !CONFIG_4xx */ +#elif defined (CONFIG_E500) + printk("Machine check in kernel mode.\n"); + printk("Caused by (from MCSR=%lx): ", reason); + + if (reason & MCSR_MCP) + printk("Machine Check Signal\n"); + if (reason & MCSR_ICPERR) + printk("Instruction Cache Parity Error\n"); + if (reason & MCSR_DCP_PERR) + printk("Data Cache Push Parity Error\n"); + if (reason & MCSR_DCPERR) + printk("Data Cache Parity Error\n"); + if (reason & MCSR_GL_CI) + printk("Guarded Load or Cache-Inhibited stwcx.\n"); + if (reason & MCSR_BUS_IAERR) + printk("Bus - Instruction Address Error\n"); + if (reason & MCSR_BUS_RAERR) + printk("Bus - Read Address Error\n"); + if (reason & MCSR_BUS_WAERR) + printk("Bus - Write Address Error\n"); + if (reason & MCSR_BUS_IBERR) + printk("Bus - Instruction Data Error\n"); + if (reason & MCSR_BUS_RBERR) + printk("Bus - Read Data Bus Error\n"); + if (reason & MCSR_BUS_WBERR) + printk("Bus - Read Data Bus Error\n"); + if (reason & MCSR_BUS_IPERR) + printk("Bus - Instruction Parity Error\n"); + if (reason & MCSR_BUS_RPERR) + printk("Bus - Read Parity Error\n"); +#else /* !CONFIG_4xx && !CONFIG_E500 */ printk("Machine check in kernel mode.\n"); printk("Caused by (from SRR1=%lx): ", reason); switch (reason & 0x601F0000) { @@ -292,8 +327,7 @@ die("machine check", regs, SIGBUS); } -void -SMIException(struct pt_regs *regs) +void SMIException(struct pt_regs *regs) { debugger(regs); #if !(defined(CONFIG_XMON) || defined(CONFIG_KGDB)) @@ -302,24 +336,21 @@ #endif } -void -UnknownException(struct pt_regs *regs) +void UnknownException(struct pt_regs *regs) { printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx %s\n", regs->nip, regs->msr, regs->trap, print_tainted()); _exception(SIGTRAP, regs, 0, 0); } -void -InstructionBreakpoint(struct pt_regs *regs) +void InstructionBreakpoint(struct pt_regs *regs) { if (debugger_iabr_match(regs)) return; _exception(SIGTRAP, regs, TRAP_BRKPT, 0); } -void -RunModeException(struct pt_regs *regs) +void RunModeException(struct pt_regs *regs) { _exception(SIGTRAP, regs, 0, 0); } @@ -337,8 +368,7 @@ #define INST_MFSPR_PVR 0x7c1f42a6 #define INST_MFSPR_PVR_MASK 0xfc1fffff -static int -emulate_instruction(struct pt_regs *regs) +static int emulate_instruction(struct pt_regs *regs) { u32 instword; u32 rd; @@ -401,8 +431,7 @@ return module_find_bug(bugaddr); } -int -check_bug_trap(struct pt_regs *regs) +int check_bug_trap(struct pt_regs *regs) { struct bug_entry *bug; unsigned long addr; @@ -439,8 +468,7 @@ return 0; } -void -ProgramCheckException(struct pt_regs *regs) +void ProgramCheckException(struct pt_regs *regs) { unsigned int reason = get_reason(regs); extern int do_mathemu(struct pt_regs *regs); @@ -513,8 +541,7 @@ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); } -void -SingleStepException(struct pt_regs *regs) +void SingleStepException(struct pt_regs *regs) { regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ if (debugger_sstep(regs)) @@ -522,8 +549,7 @@ _exception(SIGTRAP, regs, TRAP_TRACE, 0); } -void -AlignmentException(struct pt_regs *regs) +void AlignmentException(struct pt_regs *regs) { int fixed; @@ -543,8 +569,7 @@ _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); } -void -StackOverflow(struct pt_regs *regs) +void StackOverflow(struct pt_regs *regs) { printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n", current, regs->gpr[1]); @@ -561,8 +586,7 @@ die("nonrecoverable exception", regs, SIGKILL); } -void -trace_syscall(struct pt_regs *regs) +void trace_syscall(struct pt_regs *regs) { printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], @@ -570,8 +594,7 @@ } #ifdef CONFIG_8xx -void -SoftwareEmulation(struct pt_regs *regs) +void SoftwareEmulation(struct pt_regs *regs) { extern int do_mathemu(struct pt_regs *); extern int Soft_emulate_8xx(struct pt_regs *); @@ -623,8 +646,7 @@ #endif /* CONFIG_4xx || CONFIG_BOOKE */ #if !defined(CONFIG_TAU_INT) -void -TAUException(struct pt_regs *regs) +void TAUException(struct pt_regs *regs) { printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n", regs->nip, regs->msr, regs->trap, print_tainted()); @@ -646,14 +668,13 @@ /* The kernel has executed an altivec instruction without first enabling altivec. Whinge but let it do it. */ if (++kernel_altivec_count < 10) - printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%x)\n", + printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n", current, regs->nip); regs->msr |= MSR_VEC; } #ifdef CONFIG_ALTIVEC -void -AltivecAssistException(struct pt_regs *regs) +void AltivecAssistException(struct pt_regs *regs) { int err; @@ -682,6 +703,55 @@ } #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_FSL_BOOKE +void CacheLockingException(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ + /* We treat cache locking instructions from the user + * as priv ops, in the future we could try to do + * something smarter + */ + if (error_code & (ESR_DLK|ESR_ILK)) + _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); + return; +} +#endif /* CONFIG_FSL_BOOKE */ + +#ifdef CONFIG_SPE +void SPEFloatingPointException(struct pt_regs *regs) +{ + unsigned long spefscr; + int fpexc_mode; + int code = 0; + + spefscr = current->thread.spefscr; + fpexc_mode = current->thread.fpexc_mode; + + /* Hardware does not neccessarily set sticky + * underflow/overflow/invalid flags */ + if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) { + code = FPE_FLTOVF; + spefscr |= SPEFSCR_FOVFS; + } + else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) { + code = FPE_FLTUND; + spefscr |= SPEFSCR_FUNFS; + } + else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV)) + code = FPE_FLTDIV; + else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) { + code = FPE_FLTINV; + spefscr |= SPEFSCR_FINVS; + } + else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES)) + code = FPE_FLTRES; + + current->thread.spefscr = spefscr; + + _exception(SIGFPE, regs, code, regs->nip); + return; +} +#endif void __init trap_init(void) { diff -Nru a/arch/ppc/kernel/vecemu.c b/arch/ppc/kernel/vecemu.c --- a/arch/ppc/kernel/vecemu.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/kernel/vecemu.c 2004-06-26 17:09:15 -07:00 @@ -256,8 +256,7 @@ return (x + half) & ~(0x7fffff >> exp); } -int -emulate_altivec(struct pt_regs *regs) +int emulate_altivec(struct pt_regs *regs) { unsigned int instr, i; unsigned int va, vb, vc, vd; diff -Nru a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile --- a/arch/ppc/lib/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/lib/Makefile 2004-06-26 17:09:15 -07:00 @@ -5,3 +5,5 @@ obj-y := checksum.o string.o strcase.o dec_and_lock.o div64.o obj-$(CONFIG_SMP) += locks.o +obj-$(CONFIG_8xx) += rheap.o +obj-$(CONFIG_CPM2) += rheap.o diff -Nru a/arch/ppc/lib/rheap.c b/arch/ppc/lib/rheap.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/lib/rheap.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,692 @@ +/* + * arch/ppc/syslib/rheap.c + * + * A Remote Heap. Remote means that we don't touch the memory that the + * heap points to. Normal heap implementations use the memory they manage + * to place their list. We cannot do that because the memory we manage may + * have special properties, for example it is uncachable or of different + * endianess. + * + * Author: Pantelis Antoniou + * + * 2004 (c) INTRACOM S.A. Greece. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include +#include +#include +#include + +#include + +/* + * Fixup a list_head, needed when copying lists. If the pointers fall + * between s and e, apply the delta. This assumes that + * sizeof(struct list_head *) == sizeof(unsigned long *). + */ +static inline void fixup(unsigned long s, unsigned long e, int d, + struct list_head *l) +{ + unsigned long *pp; + + pp = (unsigned long *)&l->next; + if (*pp >= s && *pp < e) + *pp += d; + + pp = (unsigned long *)&l->prev; + if (*pp >= s && *pp < e) + *pp += d; +} + +/* Grow the allocated blocks */ +static int grow(rh_info_t * info, int max_blocks) +{ + rh_block_t *block, *blk; + int i, new_blocks; + int delta; + unsigned long blks, blke; + + if (max_blocks <= info->max_blocks) + return -EINVAL; + + new_blocks = max_blocks - info->max_blocks; + + block = kmalloc(sizeof(rh_block_t) * max_blocks, GFP_KERNEL); + if (block == NULL) + return -ENOMEM; + + if (info->max_blocks > 0) { + + /* copy old block area */ + memcpy(block, info->block, + sizeof(rh_block_t) * info->max_blocks); + + delta = (char *)block - (char *)info->block; + + /* and fixup list pointers */ + blks = (unsigned long)info->block; + blke = (unsigned long)(info->block + info->max_blocks); + + for (i = 0, blk = block; i < info->max_blocks; i++, blk++) + fixup(blks, blke, delta, &blk->list); + + fixup(blks, blke, delta, &info->empty_list); + fixup(blks, blke, delta, &info->free_list); + fixup(blks, blke, delta, &info->taken_list); + + /* free the old allocated memory */ + if ((info->flags & RHIF_STATIC_BLOCK) == 0) + kfree(info->block); + } + + info->block = block; + info->empty_slots += new_blocks; + info->max_blocks = max_blocks; + info->flags &= ~RHIF_STATIC_BLOCK; + + /* add all new blocks to the free list */ + for (i = 0, blk = block + info->max_blocks; i < new_blocks; i++, blk++) + list_add(&blk->list, &info->empty_list); + + return 0; +} + +/* + * Assure at least the required amount of empty slots. If this function + * causes a grow in the block area then all pointers kept to the block + * area are invalid! + */ +static int assure_empty(rh_info_t * info, int slots) +{ + int max_blocks; + + /* This function is not meant to be used to grow uncontrollably */ + if (slots >= 4) + return -EINVAL; + + /* Enough space */ + if (info->empty_slots >= slots) + return 0; + + /* Next 16 sized block */ + max_blocks = ((info->max_blocks + slots) + 15) & ~15; + + return grow(info, max_blocks); +} + +static rh_block_t *get_slot(rh_info_t * info) +{ + rh_block_t *blk; + + /* If no more free slots, and failure to extend. */ + /* XXX: You should have called assure_empty before */ + if (info->empty_slots == 0) { + printk(KERN_ERR "rh: out of slots; crash is imminent.\n"); + return NULL; + } + + /* Get empty slot to use */ + blk = list_entry(info->empty_list.next, rh_block_t, list); + list_del_init(&blk->list); + info->empty_slots--; + + /* Initialize */ + blk->start = NULL; + blk->size = 0; + blk->owner = NULL; + + return blk; +} + +static inline void release_slot(rh_info_t * info, rh_block_t * blk) +{ + list_add(&blk->list, &info->empty_list); + info->empty_slots++; +} + +static void attach_free_block(rh_info_t * info, rh_block_t * blkn) +{ + rh_block_t *blk; + rh_block_t *before; + rh_block_t *after; + rh_block_t *next; + int size; + unsigned long s, e, bs, be; + struct list_head *l; + + /* We assume that they are aligned properly */ + size = blkn->size; + s = (unsigned long)blkn->start; + e = s + size; + + /* Find the blocks immediately before and after the given one + * (if any) */ + before = NULL; + after = NULL; + next = NULL; + + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + + bs = (unsigned long)blk->start; + be = bs + blk->size; + + if (next == NULL && s >= bs) + next = blk; + + if (be == s) + before = blk; + + if (e == bs) + after = blk; + + /* If both are not null, break now */ + if (before != NULL && after != NULL) + break; + } + + /* Now check if they are really adjacent */ + if (before != NULL && s != (unsigned long)before->start + before->size) + before = NULL; + + if (after != NULL && e != (unsigned long)after->start) + after = NULL; + + /* No coalescing; list insert and return */ + if (before == NULL && after == NULL) { + + if (next != NULL) + list_add(&blkn->list, &next->list); + else + list_add(&blkn->list, &info->free_list); + + return; + } + + /* We don't need it anymore */ + release_slot(info, blkn); + + /* Grow the before block */ + if (before != NULL && after == NULL) { + before->size += size; + return; + } + + /* Grow the after block backwards */ + if (before == NULL && after != NULL) { + (int8_t *) after->start -= size; + after->size += size; + return; + } + + /* Grow the before block, and release the after block */ + before->size += size + after->size; + list_del(&after->list); + release_slot(info, after); +} + +static void attach_taken_block(rh_info_t * info, rh_block_t * blkn) +{ + rh_block_t *blk; + struct list_head *l; + + /* Find the block immediately before the given one (if any) */ + list_for_each(l, &info->taken_list) { + blk = list_entry(l, rh_block_t, list); + if (blk->start > blkn->start) { + list_add_tail(&blkn->list, &blk->list); + return; + } + } + + list_add_tail(&blkn->list, &info->taken_list); +} + +/* + * Create a remote heap dynamically. Note that no memory for the blocks + * are allocated. It will upon the first allocation + */ +rh_info_t *rh_create(unsigned int alignment) +{ + rh_info_t *info; + + /* Alignment must be a power of two */ + if ((alignment & (alignment - 1)) != 0) + return NULL; + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (info == NULL) + return NULL; + + info->alignment = alignment; + + /* Initially everything as empty */ + info->block = NULL; + info->max_blocks = 0; + info->empty_slots = 0; + info->flags = 0; + + INIT_LIST_HEAD(&info->empty_list); + INIT_LIST_HEAD(&info->free_list); + INIT_LIST_HEAD(&info->taken_list); + + return info; +} + +/* + * Destroy a dynamically created remote heap. Deallocate only if the areas + * are not static + */ +void rh_destroy(rh_info_t * info) +{ + if ((info->flags & RHIF_STATIC_BLOCK) == 0 && info->block != NULL) + kfree(info->block); + + if ((info->flags & RHIF_STATIC_INFO) == 0) + kfree(info); +} + +/* + * Initialize in place a remote heap info block. This is needed to support + * operation very early in the startup of the kernel, when it is not yet safe + * to call kmalloc. + */ +void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks, + rh_block_t * block) +{ + int i; + rh_block_t *blk; + + /* Alignment must be a power of two */ + if ((alignment & (alignment - 1)) != 0) + return; + + info->alignment = alignment; + + /* Initially everything as empty */ + info->block = block; + info->max_blocks = max_blocks; + info->empty_slots = max_blocks; + info->flags = RHIF_STATIC_INFO | RHIF_STATIC_BLOCK; + + INIT_LIST_HEAD(&info->empty_list); + INIT_LIST_HEAD(&info->free_list); + INIT_LIST_HEAD(&info->taken_list); + + /* Add all new blocks to the free list */ + for (i = 0, blk = block; i < max_blocks; i++, blk++) + list_add(&blk->list, &info->empty_list); +} + +/* Attach a free memory region, coalesces regions if adjuscent */ +int rh_attach_region(rh_info_t * info, void *start, int size) +{ + rh_block_t *blk; + unsigned long s, e, m; + int r; + + /* The region must be aligned */ + s = (unsigned long)start; + e = s + size; + m = info->alignment - 1; + + /* Round start up */ + s = (s + m) & ~m; + + /* Round end down */ + e = e & ~m; + + /* Take final values */ + start = (void *)s; + size = (int)(e - s); + + /* Grow the blocks, if needed */ + r = assure_empty(info, 1); + if (r < 0) + return r; + + blk = get_slot(info); + blk->start = start; + blk->size = size; + blk->owner = NULL; + + attach_free_block(info, blk); + + return 0; +} + +/* Detatch given address range, splits free block if needed. */ +void *rh_detach_region(rh_info_t * info, void *start, int size) +{ + struct list_head *l; + rh_block_t *blk, *newblk; + unsigned long s, e, m, bs, be; + + /* Validate size */ + if (size <= 0) + return NULL; + + /* The region must be aligned */ + s = (unsigned long)start; + e = s + size; + m = info->alignment - 1; + + /* Round start up */ + s = (s + m) & ~m; + + /* Round end down */ + e = e & ~m; + + if (assure_empty(info, 1) < 0) + return NULL; + + blk = NULL; + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + /* The range must lie entirely inside one free block */ + bs = (unsigned long)blk->start; + be = (unsigned long)blk->start + blk->size; + if (s >= bs && e <= be) + break; + blk = NULL; + } + + if (blk == NULL) + return NULL; + + /* Perfect fit */ + if (bs == s && be == e) { + /* Delete from free list, release slot */ + list_del(&blk->list); + release_slot(info, blk); + return (void *)s; + } + + /* blk still in free list, with updated start and/or size */ + if (bs == s || be == e) { + if (bs == s) + (int8_t *) blk->start += size; + blk->size -= size; + + } else { + /* The front free fragment */ + blk->size = s - bs; + + /* the back free fragment */ + newblk = get_slot(info); + newblk->start = (void *)e; + newblk->size = be - e; + + list_add(&newblk->list, &blk->list); + } + + return (void *)s; +} + +void *rh_alloc(rh_info_t * info, int size, const char *owner) +{ + struct list_head *l; + rh_block_t *blk; + rh_block_t *newblk; + void *start; + + /* Validate size */ + if (size <= 0) + return NULL; + + /* Align to configured alignment */ + size = (size + (info->alignment - 1)) & ~(info->alignment - 1); + + if (assure_empty(info, 1) < 0) + return NULL; + + blk = NULL; + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + if (size <= blk->size) + break; + blk = NULL; + } + + if (blk == NULL) + return NULL; + + /* Just fits */ + if (blk->size == size) { + /* Move from free list to taken list */ + list_del(&blk->list); + blk->owner = owner; + start = blk->start; + + attach_taken_block(info, blk); + + return start; + } + + newblk = get_slot(info); + newblk->start = blk->start; + newblk->size = size; + newblk->owner = owner; + + /* blk still in free list, with updated start, size */ + (int8_t *) blk->start += size; + blk->size -= size; + + start = newblk->start; + + attach_taken_block(info, newblk); + + return start; +} + +/* allocate at precisely the given address */ +void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner) +{ + struct list_head *l; + rh_block_t *blk, *newblk1, *newblk2; + unsigned long s, e, m, bs, be; + + /* Validate size */ + if (size <= 0) + return NULL; + + /* The region must be aligned */ + s = (unsigned long)start; + e = s + size; + m = info->alignment - 1; + + /* Round start up */ + s = (s + m) & ~m; + + /* Round end down */ + e = e & ~m; + + if (assure_empty(info, 2) < 0) + return NULL; + + blk = NULL; + list_for_each(l, &info->free_list) { + blk = list_entry(l, rh_block_t, list); + /* The range must lie entirely inside one free block */ + bs = (unsigned long)blk->start; + be = (unsigned long)blk->start + blk->size; + if (s >= bs && e <= be) + break; + } + + if (blk == NULL) + return NULL; + + /* Perfect fit */ + if (bs == s && be == e) { + /* Move from free list to taken list */ + list_del(&blk->list); + blk->owner = owner; + + start = blk->start; + attach_taken_block(info, blk); + + return start; + + } + + /* blk still in free list, with updated start and/or size */ + if (bs == s || be == e) { + if (bs == s) + (int8_t *) blk->start += size; + blk->size -= size; + + } else { + /* The front free fragment */ + blk->size = s - bs; + + /* The back free fragment */ + newblk2 = get_slot(info); + newblk2->start = (void *)e; + newblk2->size = be - e; + + list_add(&newblk2->list, &blk->list); + } + + newblk1 = get_slot(info); + newblk1->start = (void *)s; + newblk1->size = e - s; + newblk1->owner = owner; + + start = newblk1->start; + attach_taken_block(info, newblk1); + + return start; +} + +int rh_free(rh_info_t * info, void *start) +{ + rh_block_t *blk, *blk2; + struct list_head *l; + int size; + + /* Linear search for block */ + blk = NULL; + list_for_each(l, &info->taken_list) { + blk2 = list_entry(l, rh_block_t, list); + if (start < blk2->start) + break; + blk = blk2; + } + + if (blk == NULL || start > (blk->start + blk->size)) + return -EINVAL; + + /* Remove from taken list */ + list_del(&blk->list); + + /* Get size of freed block */ + size = blk->size; + attach_free_block(info, blk); + + return size; +} + +int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats) +{ + rh_block_t *blk; + struct list_head *l; + struct list_head *h; + int nr; + + switch (what) { + + case RHGS_FREE: + h = &info->free_list; + break; + + case RHGS_TAKEN: + h = &info->taken_list; + break; + + default: + return -EINVAL; + } + + /* Linear search for block */ + nr = 0; + list_for_each(l, h) { + blk = list_entry(l, rh_block_t, list); + if (stats != NULL && nr < max_stats) { + stats->start = blk->start; + stats->size = blk->size; + stats->owner = blk->owner; + stats++; + } + nr++; + } + + return nr; +} + +int rh_set_owner(rh_info_t * info, void *start, const char *owner) +{ + rh_block_t *blk, *blk2; + struct list_head *l; + int size; + + /* Linear search for block */ + blk = NULL; + list_for_each(l, &info->taken_list) { + blk2 = list_entry(l, rh_block_t, list); + if (start < blk2->start) + break; + blk = blk2; + } + + if (blk == NULL || start > (blk->start + blk->size)) + return -EINVAL; + + blk->owner = owner; + + return size; +} + +void rh_dump(rh_info_t * info) +{ + static rh_stats_t st[32]; /* XXX maximum 32 blocks */ + int maxnr; + int i, nr; + + maxnr = sizeof(st) / sizeof(st[0]); + + printk(KERN_INFO + "info @0x%p (%d slots empty / %d max)\n", + info, info->empty_slots, info->max_blocks); + + printk(KERN_INFO " Free:\n"); + nr = rh_get_stats(info, RHGS_FREE, maxnr, st); + if (nr > maxnr) + nr = maxnr; + for (i = 0; i < nr; i++) + printk(KERN_INFO + " 0x%p-0x%p (%u)\n", + st[i].start, (int8_t *) st[i].start + st[i].size, + st[i].size); + printk(KERN_INFO "\n"); + + printk(KERN_INFO " Taken:\n"); + nr = rh_get_stats(info, RHGS_TAKEN, maxnr, st); + if (nr > maxnr) + nr = maxnr; + for (i = 0; i < nr; i++) + printk(KERN_INFO + " 0x%p-0x%p (%u) %s\n", + st[i].start, (int8_t *) st[i].start + st[i].size, + st[i].size, st[i].owner != NULL ? st[i].owner : ""); + printk(KERN_INFO "\n"); +} + +void rh_dump_blk(rh_info_t * info, rh_block_t * blk) +{ + printk(KERN_INFO + "blk @0x%p: 0x%p-0x%p (%u)\n", + blk, blk->start, (int8_t *) blk->start + blk->size, blk->size); +} diff -Nru a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile --- a/arch/ppc/mm/Makefile 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/mm/Makefile 2004-06-26 17:09:20 -07:00 @@ -12,3 +12,4 @@ obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o obj-$(CONFIG_40x) += 4xx_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o +obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o diff -Nru a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c --- a/arch/ppc/mm/fault.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc/mm/fault.c 2004-06-26 17:09:16 -07:00 @@ -99,7 +99,7 @@ struct mm_struct *mm = current->mm; siginfo_t info; int code = SEGV_MAPERR; -#if defined(CONFIG_4xx) +#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE) int is_write = error_code & ESR_DST; #else int is_write = 0; @@ -114,20 +114,20 @@ error_code &= 0x48200000; else is_write = error_code & 0x02000000; -#endif /* CONFIG_4xx */ +#endif /* CONFIG_4xx || CONFIG_BOOKE */ #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_fault_handler && TRAP(regs) == 0x300) { debugger_fault_handler(regs); return 0; } -#if !defined(CONFIG_4xx) +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) if (error_code & 0x00400000) { /* DABR match */ if (debugger_dabr_match(regs)) return 0; } -#endif /* !CONFIG_4xx */ +#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ #endif /* CONFIG_XMON || CONFIG_KGDB */ if (in_atomic() || mm == NULL) @@ -200,8 +200,8 @@ if (is_write) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; -#if defined(CONFIG_4xx) - /* an exec - 4xx allows for per-page execute permission */ +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + /* an exec - 4xx/Book-E allows for per-page execute permission */ } else if (TRAP(regs) == 0x400) { pte_t *ptep; @@ -214,7 +214,7 @@ goto bad_area; #endif - /* Since 4xx supports per-page execute permission, + /* Since 4xx/Book-E supports per-page execute permission, * we lazily flush dcache to icache. */ ptep = NULL; if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { diff -Nru a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/mm/fsl_booke_mmu.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,236 @@ +/* + * Modifications by Kumar Gala (kumar.gala@freescale.com) to support + * E500 Book E processors. + * + * Copyright 2004 Freescale Semiconductor, Inc + * + * This file contains the routines for initializing the MMU + * on the 4xx series of chips. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void loadcam_entry(unsigned int index); +unsigned int tlbcam_index; +unsigned int num_tlbcam_entries; +static unsigned long __cam0, __cam1, __cam2; +extern unsigned long total_lowmem; +extern unsigned long __max_low_memory; +#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE + +struct tlbcam { + u32 MAS0; + u32 MAS1; + u32 MAS2; + u32 MAS3; + u32 MAS7; +} TLBCAM[NUM_TLBCAMS]; + +struct tlbcamrange { + unsigned long start; + unsigned long limit; + phys_addr_t phys; +} tlbcam_addrs[NUM_TLBCAMS]; + +extern unsigned int tlbcam_index; + +/* + * Return PA for this VA if it is mapped by a CAM, or 0 + */ +unsigned long v_mapped_by_tlbcam(unsigned long va) +{ + int b; + for (b = 0; b < tlbcam_index; ++b) + if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit) + return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start); + return 0; +} + +/* + * Return VA for a given PA or 0 if not mapped + */ +unsigned long p_mapped_by_tlbcam(unsigned long pa) +{ + int b; + for (b = 0; b < tlbcam_index; ++b) + if (pa >= tlbcam_addrs[b].phys + && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start) + +tlbcam_addrs[b].phys) + return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys); + return 0; +} + +/* + * Set up one of the I/D BAT (block address translation) register pairs. + * The parameters are not checked; in particular size must be a power + * of 4 between 4k and 256M. + */ +void settlbcam(int index, unsigned long virt, phys_addr_t phys, + unsigned int size, int flags, unsigned int pid) +{ + unsigned int tsize, lz; + + asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size)); + tsize = (21 - lz) / 2; + +#ifdef CONFIG_SMP + if ((flags & _PAGE_NO_CACHE) == 0) + flags |= _PAGE_COHERENT; +#endif + + TLBCAM[index].MAS0 = MAS0_TLBSEL | (index << 16); + TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | ((pid << 16) & MAS1_TID); + TLBCAM[index].MAS2 = virt & PAGE_MASK; + + TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_NO_CACHE) ? MAS2_I : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_COHERENT) ? MAS2_M : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0; + TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0; + + TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR; + TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0); + +#ifndef CONFIG_KGDB /* want user access for breakpoints */ + if (flags & _PAGE_USER) { + TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; + TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); + } +#else + TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; + TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); +#endif + + tlbcam_addrs[index].start = virt; + tlbcam_addrs[index].limit = virt + size - 1; + tlbcam_addrs[index].phys = phys; + + loadcam_entry(index); +} + +void invalidate_tlbcam_entry(int index) +{ + TLBCAM[index].MAS0 = MAS0_TLBSEL | (index << 16); + TLBCAM[index].MAS1 = ~MAS1_VALID; + + loadcam_entry(index); +} + +void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1, + unsigned long cam2) +{ + settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0); + tlbcam_index++; + if (cam1) { + tlbcam_index++; + settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0); + } + if (cam2) { + tlbcam_index++; + settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0); + } +} + +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ +void __init MMU_init_hw(void) +{ + flush_instruction_cache(); +} + +unsigned long __init mmu_mapin_ram(void) +{ + cam_mapin_ram(__cam0, __cam1, __cam2); + + return __cam0 + __cam1 + __cam2; +} + + +void __init +adjust_total_lowmem(void) +{ + unsigned long max_low_mem = MAX_LOW_MEM; + unsigned long cam_max = 0x10000000; + unsigned long ram; + + /* adjust CAM size to max_low_mem */ + if (max_low_mem < cam_max) + cam_max = max_low_mem; + + /* adjust lowmem size to max_low_mem */ + if (max_low_mem < total_lowmem) + ram = max_low_mem; + else + ram = total_lowmem; + + /* Calculate CAM values */ + __cam0 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam0 > cam_max) + __cam0 = cam_max; + ram -= __cam0; + if (ram) { + __cam1 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam1 > cam_max) + __cam1 = cam_max; + ram -= __cam1; + } + if (ram) { + __cam2 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam2 > cam_max) + __cam2 = cam_max; + ram -= __cam2; + } + + printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb," + " CAM2=%ldMb residual: %ldMb\n", + __cam0 >> 20, __cam1 >> 20, __cam2 >> 20, + (total_lowmem - __cam0 - __cam1 - __cam2) >> 20); + __max_low_memory = max_low_mem = __cam0 + __cam1 + __cam2; +} diff -Nru a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c --- a/arch/ppc/mm/init.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc/mm/init.c 2004-06-26 17:09:16 -07:00 @@ -118,7 +118,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; @@ -253,6 +253,12 @@ if (__max_memory && total_memory > __max_memory) total_memory = __max_memory; total_lowmem = total_memory; +#ifdef CONFIG_FSL_BOOKE + /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB + * entries, so we need to adjust lowmem to match the amount we can map + * in the fixed entries */ + adjust_total_lowmem(); +#endif /* CONFIG_FSL_BOOKE */ if (total_lowmem > __max_low_memory) { total_lowmem = __max_low_memory; #ifndef CONFIG_HIGHMEM diff -Nru a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h --- a/arch/ppc/mm/mmu_decl.h 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/mm/mmu_decl.h 2004-06-26 17:09:18 -07:00 @@ -27,6 +27,9 @@ extern void setbat(int index, unsigned long virt, unsigned long phys, unsigned int size, int flags); extern void reserve_phys_mem(unsigned long start, unsigned long size); +extern void settlbcam(int index, unsigned long virt, phys_addr_t phys, + unsigned int size, int flags, unsigned int pid); +extern void invalidate_tlbcam_entry(int index); extern int __map_without_bats; extern unsigned long ioremap_base; @@ -52,6 +55,12 @@ #define flush_HPTE(X, va, pg) _tlbie(va) extern void MMU_init_hw(void); extern unsigned long mmu_mapin_ram(void); + +#elif defined(CONFIG_FSL_BOOKE) +#define flush_HPTE(X, va, pg) _tlbie(va) +extern void MMU_init_hw(void); +extern unsigned long mmu_mapin_ram(void); +extern void adjust_total_lowmem(void); #else /* anything except 4xx or 8xx */ diff -Nru a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c --- a/arch/ppc/mm/pgtable.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc/mm/pgtable.c 2004-06-26 17:09:16 -07:00 @@ -42,6 +42,10 @@ #define HAVE_BATS 1 #endif +#if defined(CONFIG_FSL_BOOKE) +#define HAVE_TLBCAM 1 +#endif + extern char etext[], _stext[]; #ifdef CONFIG_SMP @@ -59,6 +63,16 @@ #define p_mapped_by_bats(x) (0UL) #endif /* HAVE_BATS */ +#ifdef HAVE_TLBCAM +extern unsigned int tlbcam_index; +extern unsigned int num_tlbcam_entries; +extern unsigned long v_mapped_by_tlbcam(unsigned long va); +extern unsigned long p_mapped_by_tlbcam(unsigned long pa); +#else /* !HAVE_TLBCAM */ +#define v_mapped_by_tlbcam(x) (0UL) +#define p_mapped_by_tlbcam(x) (0UL) +#endif /* HAVE_TLBCAM */ + #ifdef CONFIG_44x /* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */ #define PGDIR_ORDER 1 @@ -210,6 +224,9 @@ if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) goto out; + if ((v = p_mapped_by_tlbcam(p))) + goto out; + if (mem_init_done) { struct vm_struct *area; area = get_vm_area(size, VM_IOREMAP); @@ -300,6 +317,9 @@ /* is x a power of 2? */ #define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) +/* is x a power of 4? */ +#define is_power_of_4(x) ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1)) + /* * Set up a mapping for a block of I/O. * virt, phys, size must all be page-aligned. @@ -324,6 +344,18 @@ return; } #endif /* HAVE_BATS */ + +#ifdef HAVE_TLBCAM + /* + * Use a CAM for this if possible... + */ + if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size) + && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) { + settlbcam(tlbcam_index, virt, phys, size, flags, 0); + ++tlbcam_index; + return; + } +#endif /* HAVE_TLBCAM */ /* No BATs available, put it in the page tables. */ for (i = 0; i < size; i += PAGE_SIZE) diff -Nru a/arch/ppc/oprofile/Kconfig b/arch/ppc/oprofile/Kconfig --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/oprofile/Kconfig 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff -Nru a/arch/ppc/oprofile/Makefile b/arch/ppc/oprofile/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/oprofile/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,9 @@ +obj-$(CONFIG_OPROFILE) += oprofile.o + +DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ + oprof.o cpu_buffer.o buffer_sync.o \ + event_buffer.o oprofile_files.o \ + oprofilefs.o oprofile_stats.o \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) init.o diff -Nru a/arch/ppc/oprofile/init.c b/arch/ppc/oprofile/init.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/oprofile/init.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,23 @@ +/** + * @file init.c + * + * @remark Copyright 2002 OProfile authors + * @remark Read the file COPYING + * + * @author John Levon + */ + +#include +#include +#include +#include + +int __init oprofile_arch_init(struct oprofile_operations ** ops) +{ + return -ENODEV; +} + + +void oprofile_arch_exit(void) +{ +} diff -Nru a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/Kconfig 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,55 @@ +config 85xx + bool + depends on E500 + default y + +config PPC_INDIRECT_PCI_BE + bool + depends on 85xx + default y + +menu "Freescale 85xx options" + depends on E500 + +choice + prompt "Machine Type" + depends on 85xx + default MPC8540_ADS + +config MPC8540_ADS + bool "MPC8540ADS" + help + This option enables support for the MPC 8540 ADS evaluation board. + +config SBC8560 + bool "WindRiver PowerQUICC III SBC8560" + help + This option enables support for the WindRiver PowerQUICC III + SBC8560 board. + +endchoice + +# It's often necessary to know the specific 85xx processor type. +# Fortunately, it is implied (so far) from the board type, so we +# don't need to ask more redundant questions. +config MPC8540 + bool + depends on MPC8540_ADS + default y + +config MPC8560 + bool + depends on SBC8560 + default y + +config FSL_OCP + bool + depends on 85xx + default y + +config PPC_GEN550 + bool + depends on MPC8540 || SBC8560 + default y + +endmenu diff -Nru a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,9 @@ +# +# Makefile for the PowerPC 85xx linux kernel. +# + +obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads_common.o mpc8540_ads.o +obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o + +obj-$(CONFIG_MPC8540) += mpc8540.o +obj-$(CONFIG_MPC8560) += mpc8560.o diff -Nru a/arch/ppc/platforms/85xx/mpc8540.c b/arch/ppc/platforms/85xx/mpc8540.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/mpc8540.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,97 @@ +/* + * arch/ppc/platforms/85xx/mpc8540.c + * + * MPC8540 I/O descriptions + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +/* These should be defined in platform code */ +extern struct ocp_gfar_data mpc85xx_tsec1_def; +extern struct ocp_gfar_data mpc85xx_tsec2_def; +extern struct ocp_gfar_data mpc85xx_fec_def; +extern struct ocp_mpc_i2c_data mpc85xx_i2c1_def; + +/* We use offsets for paddr since we do not know at compile time + * what CCSRBAR is, platform code should fix this up in + * setup_arch + * + * Only the first IRQ is given even if a device has + * multiple lines associated with ita + */ +struct ocp_def core_ocp[] = { + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_IIC, + .index = 0, + .paddr = MPC85xx_IIC1_OFFSET, + .irq = MPC85xx_IRQ_IIC1, + .pm = OCP_CPM_NA, + .additions = &mpc85xx_i2c1_def, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_16550, + .index = 0, + .paddr = MPC85xx_UART0_OFFSET, + .irq = MPC85xx_IRQ_DUART, + .pm = OCP_CPM_NA, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_16550, + .index = 1, + .paddr = MPC85xx_UART1_OFFSET, + .irq = MPC85xx_IRQ_DUART, + .pm = OCP_CPM_NA, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_GFAR, + .index = 0, + .paddr = MPC85xx_ENET1_OFFSET, + .irq = MPC85xx_IRQ_TSEC1_TX, + .pm = OCP_CPM_NA, + .additions = &mpc85xx_tsec1_def, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_GFAR, + .index = 1, + .paddr = MPC85xx_ENET2_OFFSET, + .irq = MPC85xx_IRQ_TSEC2_TX, + .pm = OCP_CPM_NA, + .additions = &mpc85xx_tsec2_def, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_GFAR, + .index = 2, + .paddr = MPC85xx_ENET3_OFFSET, + .irq = MPC85xx_IRQ_FEC, + .pm = OCP_CPM_NA, + .additions = &mpc85xx_fec_def, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_DMA, + .index = 0, + .paddr = MPC85xx_DMA_OFFSET, + .irq = MPC85xx_IRQ_DMA0, + .pm = OCP_CPM_NA, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_PERFMON, + .index = 0, + .paddr = MPC85xx_PERFMON_OFFSET, + .irq = MPC85xx_IRQ_PERFMON, + .pm = OCP_CPM_NA, + }, + { .vendor = OCP_VENDOR_INVALID + } +}; diff -Nru a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,238 @@ +/* + * arch/ppc/platforms/85xx/mpc8540_ads.c + * + * MPC8540ADS board specific routines + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for linux/serial_core.h */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct ocp_gfar_data mpc85xx_tsec1_def = { + .interruptTransmit = MPC85xx_IRQ_TSEC1_TX, + .interruptError = MPC85xx_IRQ_TSEC1_ERROR, + .interruptReceive = MPC85xx_IRQ_TSEC1_RX, + .interruptPHY = MPC85xx_IRQ_EXT5, + .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR + | GFAR_HAS_RMON + | GFAR_HAS_PHY_INTR | GFAR_HAS_COALESCE), + .phyid = 0, + .phyregidx = 0, +}; + +struct ocp_gfar_data mpc85xx_tsec2_def = { + .interruptTransmit = MPC85xx_IRQ_TSEC2_TX, + .interruptError = MPC85xx_IRQ_TSEC2_ERROR, + .interruptReceive = MPC85xx_IRQ_TSEC2_RX, + .interruptPHY = MPC85xx_IRQ_EXT5, + .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR + | GFAR_HAS_RMON + | GFAR_HAS_PHY_INTR | GFAR_HAS_COALESCE), + .phyid = 1, + .phyregidx = 0, +}; + +struct ocp_gfar_data mpc85xx_fec_def = { + .interruptTransmit = MPC85xx_IRQ_FEC, + .interruptError = MPC85xx_IRQ_FEC, + .interruptReceive = MPC85xx_IRQ_FEC, + .interruptPHY = MPC85xx_IRQ_EXT5, + .flags = 0, + .phyid = 3, + .phyregidx = 0, +}; + +struct ocp_fs_i2c_data mpc85xx_i2c1_def = { + .flags = FS_I2C_SEPARATE_DFSRR, +}; + +/* ************************************************************************ + * + * Setup the architecture + * + */ +static void __init +mpc8540ads_setup_arch(void) +{ + struct ocp_def *def; + struct ocp_gfar_data *einfo; + bd_t *binfo = (bd_t *) __res; + unsigned int freq; + + /* get the core frequency */ + freq = binfo->bi_intfreq; + + if (ppc_md.progress) + ppc_md.progress("mpc8540ads_setup_arch()", 0); + + /* Set loops_per_jiffy to a half-way reasonable value, + for use until calibrate_delay gets called. */ + loops_per_jiffy = freq / HZ; + +#ifdef CONFIG_PCI + /* setup PCI host bridges */ + mpc85xx_setup_hose(); +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_SERIAL_8250 + mpc85xx_early_serial_map(); +#endif + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + /* Invalidate the entry we stole earlier the serial ports + * should be properly mapped */ + invalidate_tlbcam_entry(NUM_TLBCAMS - 1); +#endif + + def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 0); + if (def) { + einfo = (struct ocp_gfar_data *) def->additions; + memcpy(einfo->mac_addr, binfo->bi_enetaddr, 6); + } + + def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 1); + if (def) { + einfo = (struct ocp_gfar_data *) def->additions; + memcpy(einfo->mac_addr, binfo->bi_enet1addr, 6); + } + + def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 2); + if (def) { + einfo = (struct ocp_gfar_data *) def->additions; + memcpy(einfo->mac_addr, binfo->bi_enet2addr, 6); + } + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + + ocp_for_each_device(mpc85xx_update_paddr_ocp, &(binfo->bi_immr_base)); +} + +/* ************************************************************************ */ +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* parse_bootinfo must always be called first */ + parse_bootinfo(find_bootinfo()); + + /* + * If we were passed in a board information, copy it into the + * residual data area. + */ + if (r3) { + memcpy((void *) __res, (void *) (r3 + KERNELBASE), + sizeof (bd_t)); + } +#ifdef CONFIG_SERIAL_TEXT_DEBUG + { + bd_t *binfo = (bd_t *) __res; + + /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ + settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base, + binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); + } +#endif + +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured in, and there's a valid + * starting address for it, set it up. + */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *) (r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *) (r6 + KERNELBASE)); + } + + /* setup the PowerPC module struct */ + ppc_md.setup_arch = mpc8540ads_setup_arch; + ppc_md.show_cpuinfo = mpc85xx_ads_show_cpuinfo; + + ppc_md.init_IRQ = mpc85xx_ads_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + + ppc_md.restart = mpc85xx_restart; + ppc_md.power_off = mpc85xx_power_off; + ppc_md.halt = mpc85xx_halt; + + ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory; + + ppc_md.time_init = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.calibrate_decr = mpc85xx_calibrate_decr; + +#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) + ppc_md.progress = gen550_progress; +#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ + + if (ppc_md.progress) + ppc_md.progress("mpc8540ads_init(): exit", 0); + + return; +} diff -Nru a/arch/ppc/platforms/85xx/mpc8540_ads.h b/arch/ppc/platforms/85xx/mpc8540_ads.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/mpc8540_ads.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,30 @@ +/* + * arch/ppc/platforms/85xx/mpc8540_ads.h + * + * MPC8540ADS board definitions + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __MACH_MPC8540ADS_H__ +#define __MACH_MPC8540ADS_H__ + +#include +#include +#include +#include +#include + +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) + +#endif /* __MACH_MPC8540ADS_H__ */ diff -Nru a/arch/ppc/platforms/85xx/mpc8560.c b/arch/ppc/platforms/85xx/mpc8560.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/mpc8560.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,74 @@ +/* + * arch/ppc/platforms/85xx/mpc8560.c + * + * MPC8560 I/O descriptions + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +/* These should be defined in platform code */ +extern struct ocp_gfar_data mpc85xx_tsec1_def; +extern struct ocp_gfar_data mpc85xx_tsec2_def; +extern struct ocp_mpc_i2c_data mpc85xx_i2c1_def; + +/* We use offsets for paddr since we do not know at compile time + * what CCSRBAR is, platform code should fix this up in + * setup_arch + * + * Only the first IRQ is given even if a device has + * multiple lines associated with ita + */ +struct ocp_def core_ocp[] = { + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_IIC, + .index = 0, + .paddr = MPC85xx_IIC1_OFFSET, + .irq = MPC85xx_IRQ_IIC1, + .pm = OCP_CPM_NA, + .additions = &mpc85xx_i2c1_def, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_GFAR, + .index = 0, + .paddr = MPC85xx_ENET1_OFFSET, + .irq = MPC85xx_IRQ_TSEC1_TX, + .pm = OCP_CPM_NA, + .additions = &mpc85xx_tsec1_def, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_GFAR, + .index = 1, + .paddr = MPC85xx_ENET2_OFFSET, + .irq = MPC85xx_IRQ_TSEC2_TX, + .pm = OCP_CPM_NA, + .additions = &mpc85xx_tsec2_def, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_DMA, + .index = 0, + .paddr = MPC85xx_DMA_OFFSET, + .irq = MPC85xx_IRQ_DMA0, + .pm = OCP_CPM_NA, + }, + { .vendor = OCP_VENDOR_FREESCALE, + .function = OCP_FUNC_PERFMON, + .index = 0, + .paddr = MPC85xx_PERFMON_OFFSET, + .irq = MPC85xx_IRQ_PERFMON, + .pm = OCP_CPM_NA, + }, + { .vendor = OCP_VENDOR_INVALID + } +}; diff -Nru a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,237 @@ +/* + * arch/ppc/platforms/85xx/mpc85xx_ads_common.c + * + * MPC85xx ADS board common routines + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#ifndef CONFIG_PCI +unsigned long isa_io_base = 0; +unsigned long isa_mem_base = 0; +#endif + +extern unsigned long total_memory; /* in mm/init */ + +unsigned char __res[sizeof (bd_t)]; + +/* Internal interrupts are all Level Sensitive, and Positive Polarity */ + +static u_char mpc85xx_ads_openpic_initsenses[] __initdata = { + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ + 0x0, /* External 0: */ +#if defined(CONFIG_PCI) + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 1: PCI slot 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI slot 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI slot 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 4: PCI slot 3 */ +#else + 0x0, /* External 1: */ + 0x0, /* External 2: */ + 0x0, /* External 3: */ + 0x0, /* External 4: */ +#endif + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ + 0x0, /* External 6: */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */ + 0x0, /* External 8: */ + 0x0, /* External 9: */ + 0x0, /* External 10: */ + 0x0, /* External 11: */ +}; + +/* ************************************************************************ */ +int +mpc85xx_ads_show_cpuinfo(struct seq_file *m) +{ + uint pvid, svid, phid1; + uint memsize = total_memory; + bd_t *binfo = (bd_t *) __res; + unsigned int freq; + + /* get the core frequency */ + freq = binfo->bi_intfreq; + + pvid = mfspr(PVR); + svid = mfspr(SVR); + + seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); + + switch (svid & 0xffff0000) { + case SVR_8540: + seq_printf(m, "Machine\t\t: mpc8540ads\n"); + break; + case SVR_8560: + seq_printf(m, "Machine\t\t: mpc8560ads\n"); + break; + default: + seq_printf(m, "Machine\t\t: unknown\n"); + break; + } + seq_printf(m, "bus freq\t: %u.%.6u MHz\n", freq / 1000000, + freq % 1000000); + seq_printf(m, "PVR\t\t: 0x%x\n", pvid); + seq_printf(m, "SVR\t\t: 0x%x\n", svid); + + /* Display cpu Pll setting */ + phid1 = mfspr(HID1); + seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); + + /* Display the amount of memory */ + seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); + + return 0; +} + +void __init +mpc85xx_ads_init_IRQ(void) +{ + bd_t *binfo = (bd_t *) __res; + /* Determine the Physical Address of the OpenPIC regs */ + phys_addr_t OpenPIC_PAddr = + binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; + OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE); + OpenPIC_InitSenses = mpc85xx_ads_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof (mpc85xx_ads_openpic_initsenses); + + /* Skip reserved space and internal sources */ + openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200); + /* Map PIC IRQs 0-11 */ + openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000); + + /* we let openpic interrupts starting from an offset, to + * leave space for cascading interrupts underneath. + */ + openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); + + return; +} + +#ifdef CONFIG_PCI +/* + * interrupt routing + */ + +int +mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * This is little evil, but works around the fact + * that revA boards have IDSEL starting at 18 + * and others boards (older) start at 12 + * + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 2 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, + {PIRQC, PIRQD, PIRQA, PIRQB}, + {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 5 */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 12 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, + {PIRQC, PIRQD, PIRQA, PIRQB}, + {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 15 */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 18 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, + {PIRQC, PIRQD, PIRQA, PIRQB}, + {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 21 */ + }; + + const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +int +mpc85xx_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + +#endif /* CONFIG_PCI */ diff -Nru a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,50 @@ +/* + * arch/ppc/platforms/85xx/mpc85xx_ads_common.h + * + * MPC85XX ADS common board definitions + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __MACH_MPC85XX_ADS_H__ +#define __MACH_MPC85XX_ADS_H__ + +#include +#include +#include +#include + +#define BOARD_CCSRBAR ((uint)0xe0000000) +#define BCSR_ADDR ((uint)0xf8000000) +#define BCSR_SIZE ((uint)(32 * 1024)) + +extern int mpc85xx_ads_show_cpuinfo(struct seq_file *m); +extern void mpc85xx_ads_init_IRQ(void) __init; +extern void mpc85xx_ads_map_io(void) __init; + +/* PCI interrupt controller */ +#define PIRQA MPC85xx_IRQ_EXT1 +#define PIRQB MPC85xx_IRQ_EXT2 +#define PIRQC MPC85xx_IRQ_EXT3 +#define PIRQD MPC85xx_IRQ_EXT4 + +#define MPC85XX_PCI1_LOWER_IO 0x00000000 +#define MPC85XX_PCI1_UPPER_IO 0x00ffffff + +#define MPC85XX_PCI1_LOWER_MEM 0x80000000 +#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff + +#define MPC85XX_PCI1_IO_BASE 0xe2000000 +#define MPC85XX_PCI1_MEM_OFFSET 0x00000000 + +#define MPC85XX_PCI1_IO_SIZE 0x01000000 + +#endif /* __MACH_MPC85XX_ADS_H__ */ diff -Nru a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/sbc8560.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,249 @@ +/* + * arch/ppc/platforms/85xx/sbc8560.c + * + * Wind River SBC8560 board specific routines + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for linux/serial_core.h */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct ocp_gfar_data mpc85xx_tsec1_def = { + .interruptTransmit = MPC85xx_IRQ_TSEC1_TX, + .interruptError = MPC85xx_IRQ_TSEC1_ERROR, + .interruptReceive = MPC85xx_IRQ_TSEC1_RX, + .interruptPHY = MPC85xx_IRQ_EXT6, + .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR | GFAR_HAS_PHY_INTR), + .phyid = 25, + .phyregidx = 0, +}; + +struct ocp_gfar_data mpc85xx_tsec2_def = { + .interruptTransmit = MPC85xx_IRQ_TSEC2_TX, + .interruptError = MPC85xx_IRQ_TSEC2_ERROR, + .interruptReceive = MPC85xx_IRQ_TSEC2_RX, + .interruptPHY = MPC85xx_IRQ_EXT7, + .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR | GFAR_HAS_PHY_INTR), + .phyid = 26, + .phyregidx = 0, +}; + +struct ocp_fs_i2c_data mpc85xx_i2c1_def = { + .flags = FS_I2C_SEPARATE_DFSRR, +}; + + +#ifdef CONFIG_SERIAL_8250 +static void __init +sbc8560_early_serial_map(void) +{ + struct uart_port uart_req; + + /* Setup serial port access */ + memset(&uart_req, 0, sizeof (uart_req)); + uart_req.irq = MPC85xx_IRQ_EXT9; + uart_req.flags = STD_COM_FLAGS; + uart_req.uartclk = BASE_BAUD * 16; + uart_req.iotype = SERIAL_IO_MEM; + uart_req.mapbase = UARTA_ADDR; + uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE); + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(0, &uart_req); +#endif + + if (early_serial_setup(&uart_req) != 0) + printk("Early serial init of port 0 failed\n"); + + /* Assume early_serial_setup() doesn't modify uart_req */ + uart_req.line = 1; + uart_req.mapbase = UARTB_ADDR; + uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART1_SIZE); + uart_req.irq = MPC85xx_IRQ_EXT10; + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(1, &uart_req); +#endif + + if (early_serial_setup(&uart_req) != 0) + printk("Early serial init of port 1 failed\n"); +} +#endif + +/* ************************************************************************ + * + * Setup the architecture + * + */ +static void __init +sbc8560_setup_arch(void) +{ + struct ocp_def *def; + struct ocp_gfar_data *einfo; + bd_t *binfo = (bd_t *) __res; + unsigned int freq; + + /* get the core frequency */ + freq = binfo->bi_intfreq; + + if (ppc_md.progress) + ppc_md.progress("sbc8560_setup_arch()", 0); + + /* Set loops_per_jiffy to a half-way reasonable value, + for use until calibrate_delay gets called. */ + loops_per_jiffy = freq / HZ; + +#ifdef CONFIG_PCI + /* setup PCI host bridges */ + mpc85xx_setup_hose(); +#endif +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif +#ifdef CONFIG_SERIAL_8250 + sbc8560_early_serial_map(); +#endif +#ifdef CONFIG_SERIAL_TEXT_DEBUG + /* Invalidate the entry we stole earlier the serial ports + * should be properly mapped */ + invalidate_tlbcam_entry(NUM_TLBCAMS - 1); +#endif + + /* Set up MAC addresses for the Ethernet devices */ + def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 0); + if (def) { + einfo = (struct ocp_gfar_data *) def->additions; + memcpy(einfo->mac_addr, binfo->bi_enetaddr, 6); + } + + def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 1); + if (def) { + einfo = (struct ocp_gfar_data *) def->additions; + memcpy(einfo->mac_addr, binfo->bi_enet1addr, 6); + } + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + + ocp_for_each_device(mpc85xx_update_paddr_ocp, &(binfo->bi_immr_base)); +} + +/* ************************************************************************ */ +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* parse_bootinfo must always be called first */ + parse_bootinfo(find_bootinfo()); + + /* + * If we were passed in a board information, copy it into the + * residual data area. + */ + if (r3) { + memcpy((void *) __res, (void *) (r3 + KERNELBASE), + sizeof (bd_t)); + } + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ + settlbcam(NUM_TLBCAMS - 1, UARTA_ADDR, + UARTA_ADDR, 0x1000, _PAGE_IO, 0); +#endif + +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured in, and there's a valid + * starting address for it, set it up. + */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *) (r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *) (r6 + KERNELBASE)); + } + + /* setup the PowerPC module struct */ + ppc_md.setup_arch = sbc8560_setup_arch; + ppc_md.show_cpuinfo = sbc8560_show_cpuinfo; + + ppc_md.init_IRQ = sbc8560_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + + ppc_md.restart = mpc85xx_restart; + ppc_md.power_off = mpc85xx_power_off; + ppc_md.halt = mpc85xx_halt; + + ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory; + + ppc_md.time_init = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.calibrate_decr = mpc85xx_calibrate_decr; + +#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) + ppc_md.progress = gen550_progress; +#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ + + if (ppc_md.progress) + ppc_md.progress("sbc8560_init(): exit", 0); +} diff -Nru a/arch/ppc/platforms/85xx/sbc8560.h b/arch/ppc/platforms/85xx/sbc8560.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/sbc8560.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,48 @@ +/* + * arch/ppc/platforms/85xx/sbc8560.h + * + * Wind River SBC8560 board definitions + * + * Copyright 2003 Motorola Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __MACH_SBC8560_H__ +#define __MACH_SBC8560_H__ + +#include +#include +#include + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 2 +#endif + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD ( 1843200 / 16 ) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, UARTA_ADDR, MPC85xx_IRQ_EXT9, STD_COM_FLAGS, /* ttyS0 */ \ + iomem_base: (u8 *)UARTA_ADDR, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, UARTB_ADDR, MPC85xx_IRQ_EXT10, STD_COM_FLAGS, /* ttyS1 */ \ + iomem_base: (u8 *)UARTB_ADDR, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __MACH_SBC8560_H__ */ diff -Nru a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/sbc85xx.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,215 @@ +/* + * arch/ppc/platform/85xx/sbc85xx.c + * + * WindRiver PowerQUICC III SBC85xx board common routines + * + * Copyright 2002, 2003 Motorola Inc. + * Copyright 2004 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +unsigned char __res[sizeof (bd_t)]; + +#ifndef CONFIG_PCI +unsigned long isa_io_base = 0; +unsigned long isa_mem_base = 0; +unsigned long pci_dram_offset = 0; +#endif + +extern unsigned long total_memory; /* in mm/init */ + +/* Internal interrupts are all Level Sensitive, and Positive Polarity */ + +static u_char sbc8560_openpic_initsenses[] __initdata = { + (IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */ + (IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */ + (IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ + (IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ + (IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ + (IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ + (IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ + (IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ + (IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */ + (IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */ + (IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */ + (IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */ + (IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */ + (IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */ + (IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */ + (IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */ + (IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */ + (IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */ + (IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */ + (IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */ + (IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */ + (IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */ + (IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */ + (IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */ + (IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */ + (IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */ + (IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */ + (IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ + (IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ + (IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ + (IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */ + (IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ + 0x0, /* External 0: */ + 0x0, /* External 1: */ +#if defined(CONFIG_PCI) + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI slot 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI slot 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 4: PCI slot 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PCI slot 3 */ +#else + 0x0, /* External 2: */ + 0x0, /* External 3: */ + 0x0, /* External 4: */ + 0x0, /* External 5: */ +#endif + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 6: PHY */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */ + 0x0, /* External 8: */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: PHY */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 10: PHY */ + 0x0, /* External 11: */ +}; + +/* ************************************************************************ */ +int +sbc8560_show_cpuinfo(struct seq_file *m) +{ + uint pvid, svid, phid1; + uint memsize = total_memory; + bd_t *binfo = (bd_t *) __res; + unsigned int freq; + + /* get the core frequency */ + freq = binfo->bi_intfreq; + + pvid = mfspr(PVR); + svid = mfspr(SVR); + + seq_printf(m, "Vendor\t\t: Wind River\n"); + + switch (svid & 0xffff0000) { + case SVR_8540: + seq_printf(m, "Machine\t\t: hhmmm, this board isn't made yet!\n"); + break; + case SVR_8560: + seq_printf(m, "Machine\t\t: SBC8560\n"); + break; + default: + seq_printf(m, "Machine\t\t: unknown\n"); + break; + } + seq_printf(m, "bus freq\t: %u.%.6u MHz\n", freq / 1000000, + freq % 1000000); + seq_printf(m, "PVR\t\t: 0x%x\n", pvid); + seq_printf(m, "SVR\t\t: 0x%x\n", svid); + + /* Display cpu Pll setting */ + phid1 = mfspr(HID1); + seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); + + /* Display the amount of memory */ + seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); + + return 0; +} + +void __init +sbc8560_init_IRQ(void) +{ + bd_t *binfo = (bd_t *) __res; + /* Determine the Physical Address of the OpenPIC regs */ + phys_addr_t OpenPIC_PAddr = + binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; + OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE); + OpenPIC_InitSenses = sbc8560_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof (sbc8560_openpic_initsenses); + + /* Skip reserved space and internal sources */ + openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200); + /* Map PIC IRQs 0-11 */ + openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000); + + /* we let openpic interrupts starting from an offset, to + * leave space for cascading interrupts underneath. + */ + openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); + + return; +} + +/* + * interrupt routing + */ + +#ifdef CONFIG_PCI +int mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, + unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {PIRQA, PIRQB, PIRQC, PIRQD}, + {PIRQD, PIRQA, PIRQB, PIRQC}, + {PIRQC, PIRQD, PIRQA, PIRQB}, + {PIRQB, PIRQC, PIRQD, PIRQA}, + }; + + const long min_idsel = 12, max_idsel = 15, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +int mpc85xx_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} +#endif /* CONFIG_PCI */ diff -Nru a/arch/ppc/platforms/85xx/sbc85xx.h b/arch/ppc/platforms/85xx/sbc85xx.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/sbc85xx.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,55 @@ +/* + * arch/ppc/platforms/85xx/sbc85xx.h + * + * WindRiver PowerQUICC III SBC85xx common board definitions + * + * Copyright 2003 Motorola Inc. + * Copyright 2004 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __PLATFORMS_85XX_SBC85XX_H__ +#define __PLATFORMS_85XX_SBC85XX_H__ + +#include +#include +#include +#include + +#define BOARD_CCSRBAR ((uint)0xff700000) +#define CCSRBAR_SIZE ((uint)1024*1024) + +#define BCSR_ADDR ((uint)0xfc000000) +#define BCSR_SIZE ((uint)(16 * 1024 * 1024)) + +#define UARTA_ADDR (BCSR_ADDR + 0x00700000) +#define UARTB_ADDR (BCSR_ADDR + 0x00800000) +#define RTC_DEVICE_ADDR (BCSR_ADDR + 0x00900000) +#define EEPROM_ADDR (BCSR_ADDR + 0x00b00000) + +extern int sbc8560_show_cpuinfo(struct seq_file *m); +extern void sbc8560_init_IRQ(void) __init; + +/* PCI interrupt controller */ +#define PIRQA MPC85xx_IRQ_EXT1 +#define PIRQB MPC85xx_IRQ_EXT2 +#define PIRQC MPC85xx_IRQ_EXT3 +#define PIRQD MPC85xx_IRQ_EXT4 + +#define MPC85XX_PCI1_LOWER_IO 0x00000000 +#define MPC85XX_PCI1_UPPER_IO 0x00ffffff + +#define MPC85XX_PCI1_LOWER_MEM 0x80000000 +#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff + +#define MPC85XX_PCI1_IO_BASE 0xe2000000 +#define MPC85XX_PCI1_MEM_OFFSET 0x00000000 + +#define MPC85XX_PCI1_IO_SIZE 0x01000000 + +#endif /* __PLATFORMS_85XX_SBC85XX_H__ */ diff -Nru a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile --- a/arch/ppc/platforms/Makefile 2004-06-26 17:09:21 -07:00 +++ b/arch/ppc/platforms/Makefile 2004-06-26 17:09:21 -07:00 @@ -30,6 +30,7 @@ obj-$(CONFIG_PREP_RESIDUAL) += residual.o obj-$(CONFIG_ADIR) += adir_setup.o adir_pic.o adir_pci.o obj-$(CONFIG_EST8260) += est8260_setup.o +obj-$(CONFIG_PQ2ADS) += pq2ads_setup.o obj-$(CONFIG_TQM8260) += tqm8260_setup.o obj-$(CONFIG_EV64260) += ev64260_setup.o obj-$(CONFIG_GEMINI) += gemini_pci.o gemini_setup.o gemini_prom.o diff -Nru a/arch/ppc/platforms/est8260.h b/arch/ppc/platforms/est8260.h --- a/arch/ppc/platforms/est8260.h 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc/platforms/est8260.h 2004-06-26 17:09:19 -07:00 @@ -6,7 +6,7 @@ #ifndef __EST8260_PLATFORM #define __EST8260_PLATFORM -#define IMAP_ADDR ((uint)0xf0000000) +#define CPM_MAP_ADDR ((uint)0xf0000000) #define BOOTROM_RESTART_ADDR ((uint)0xff000104) diff -Nru a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c --- a/arch/ppc/platforms/lopec_setup.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/platforms/lopec_setup.c 2004-06-26 17:09:18 -07:00 @@ -33,7 +33,6 @@ #include #include -extern char saved_command_line[]; extern void lopec_find_bridges(void); /* diff -Nru a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c --- a/arch/ppc/platforms/pmac_cpufreq.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/platforms/pmac_cpufreq.c 2004-06-26 17:09:18 -07:00 @@ -1,7 +1,8 @@ /* * arch/ppc/platforms/pmac_cpufreq.c * - * Copyright (C) 2002 - 2003 Benjamin Herrenschmidt + * Copyright (C) 2002 - 2004 Benjamin Herrenschmidt + * Copyright (C) 2004 John Steele Scott * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -47,6 +48,7 @@ #warning "WARNING, CPUFREQ not recommended on SMP kernels" #endif +extern void low_choose_7447a_dfs(int dfs); extern void low_choose_750fx_pll(int pll); extern void low_sleep_handler(void); extern void openpic_suspend(struct sys_device *sysdev, u32 state); @@ -54,18 +56,27 @@ extern void enable_kernel_altivec(void); extern void enable_kernel_fp(void); +/* + * Currently, PowerMac cpufreq supports only high & low frequencies + * that are set by the firmware + */ static unsigned int low_freq; static unsigned int hi_freq; static unsigned int cur_freq; -/* Clean that up some day ... use a func ptr or at least an enum... */ -static int cpufreq_uses_pmu; -static int cpufreq_uses_gpios; +/* + * Different models uses different mecanisms to switch the frequency + */ +static int (*set_speed_proc)(int low_speed); +/* + * Some definitions used by the various speedprocs + */ static u32 voltage_gpio; static u32 frequency_gpio; static u32 slew_done_gpio; + #define PMAC_CPU_LOW_SPEED 1 #define PMAC_CPU_HIGH_SPEED 0 @@ -123,9 +134,39 @@ return 0; } +/* Switch CPU speed using DFS */ +static int __pmac dfs_set_cpu_speed(int low_speed) +{ + if (low_speed == 0) { + /* ramping up, set voltage first */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/1000); + } else { + /* ramping down, enable aack delay first */ + pmac_call_feature(PMAC_FTR_AACK_DELAY_ENABLE, NULL, 1, 0); + } + + /* set frequency */ + low_choose_7447a_dfs(low_speed); + + if (low_speed == 1) { + /* ramping down, set voltage last */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/1000); + } else { + /* ramping up, disable aack delay last */ + pmac_call_feature(PMAC_FTR_AACK_DELAY_ENABLE, NULL, 0, 0); + } + + return 0; +} + + /* Switch CPU speed using slewing GPIOs */ -static int __pmac gpios_set_cpu_speed(unsigned int low_speed) +static int __pmac gpios_set_cpu_speed(int low_speed) { int gpio; @@ -138,7 +179,8 @@ } /* Set frequency */ - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, low_speed ? 0x04 : 0x05); + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, + low_speed ? 0x04 : 0x05); udelay(200); do { set_current_state(TASK_UNINTERRUPTIBLE); @@ -163,7 +205,7 @@ /* Switch CPU speed under PMU control */ -static int __pmac pmu_set_cpu_speed(unsigned int low_speed) +static int __pmac pmu_set_cpu_speed(int low_speed) { struct adb_request req; unsigned long save_l2cr; @@ -269,12 +311,7 @@ return 0; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - if (cpufreq_uses_pmu) - rc = pmu_set_cpu_speed(speed_mode); - else if (cpufreq_uses_gpios) - rc = gpios_set_cpu_speed(speed_mode); - else - rc = cpu_750fx_cpu_speed(speed_mode); + set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; @@ -338,20 +375,137 @@ }; +static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) +{ + struct device_node *volt_gpio_np = of_find_node_by_name(NULL, + "voltage-gpio"); + struct device_node *freq_gpio_np = of_find_node_by_name(NULL, + "frequency-gpio"); + struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, + "slewing-done"); + u32 *value; + + /* + * Check to see if it's GPIO driven or PMU only + * + * The way we extract the GPIO address is slightly hackish, but it + * works well enough for now. We need to abstract the whole GPIO + * stuff sooner or later anyway + */ + + if (volt_gpio_np) + voltage_gpio = read_gpio(volt_gpio_np); + if (freq_gpio_np) + frequency_gpio = read_gpio(freq_gpio_np); + if (slew_done_gpio_np) + slew_done_gpio = read_gpio(slew_done_gpio_np); + + /* If we use the frequency GPIOs, calculate the min/max speeds based + * on the bus frequencies + */ + if (frequency_gpio && slew_done_gpio) { + int lenp, rc; + u32 *freqs, *ratio; + + freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); + lenp /= sizeof(u32); + if (freqs == NULL || lenp != 2) { + printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); + return 1; + } + ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); + if (ratio == NULL) { + printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); + return 1; + } + + /* Get the min/max bus frequencies */ + low_freq = min(freqs[0], freqs[1]); + hi_freq = max(freqs[0], freqs[1]); + + /* Grrrr.. It _seems_ that the device-tree is lying on the low bus + * frequency, it claims it to be around 84Mhz on some models while + * it appears to be approx. 101Mhz on all. Let's hack around here... + * fortunately, we don't need to be too precise + */ + if (low_freq < 98000000) + low_freq = 101000000; + + /* Convert those to CPU core clocks */ + low_freq = (low_freq * (*ratio)) / 2000; + hi_freq = (hi_freq * (*ratio)) / 2000; + + /* Now we get the frequencies, we read the GPIO to see what is out current + * speed + */ + rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); + cur_freq = (rc & 0x01) ? hi_freq : low_freq; + + set_speed_proc = gpios_set_cpu_speed; + return 1; + } + + /* If we use the PMU, look for the min & max frequencies in the + * device-tree + */ + value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); + if (!value) + return 1; + low_freq = (*value) / 1000; + /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree + * here */ + if (low_freq < 100000) + low_freq *= 10; + + value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); + if (!value) + return 1; + hi_freq = (*value) / 1000; + set_speed_proc = pmu_set_cpu_speed; + + return 0; +} + +static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode) +{ + struct device_node *volt_gpio_np; + + /* OF only reports the high frequency */ + hi_freq = cur_freq; + low_freq = cur_freq/2; + if (mfspr(HID1) & HID1_DFS) + cur_freq = low_freq; + else + cur_freq = hi_freq; + + volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); + if (!volt_gpio_np){ + printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n"); + return 1; + } + + u32 *reg = (u32 *)get_property(volt_gpio_np, "reg", NULL); + voltage_gpio = *reg; + set_speed_proc = dfs_set_cpu_speed; + + return 0; +} + /* Currently, we support the following machines: * * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz) * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz) + * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz) * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz) * - iBook2 500 (PMU based, 400Mhz & 500Mhz) * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage) - * - Recent MacRISC3 machines + * - Recent MacRISC3 laptops + * - iBook G4s and PowerBook G4s with 7447A CPUs */ static int __init pmac_cpufreq_setup(void) { struct device_node *cpunode; u32 *value; - int has_freq_ctl = 0; if (strstr(cmd_line, "nocpufreq")) return 0; @@ -367,113 +521,36 @@ goto out; cur_freq = (*value) / 1000; - /* Check for newer machines */ - if (machine_is_compatible("PowerBook3,4") || - machine_is_compatible("PowerBook3,5") || - machine_is_compatible("MacRISC3")) { - struct device_node *volt_gpio_np = of_find_node_by_name(NULL, "voltage-gpio"); - struct device_node *freq_gpio_np = of_find_node_by_name(NULL, "frequency-gpio"); - struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, "slewing-done"); - - /* - * Check to see if it's GPIO driven or PMU only - * - * The way we extract the GPIO address is slightly hackish, but it - * works well enough for now. We need to abstract the whole GPIO - * stuff sooner or later anyway - */ - - if (volt_gpio_np) - voltage_gpio = read_gpio(volt_gpio_np); - if (freq_gpio_np) - frequency_gpio = read_gpio(freq_gpio_np); - if (slew_done_gpio_np) - slew_done_gpio = read_gpio(slew_done_gpio_np); - - /* If we use the frequency GPIOs, calculate the min/max speeds based - * on the bus frequencies - */ - if (frequency_gpio && slew_done_gpio) { - int lenp, rc; - u32 *freqs, *ratio; - - freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); - lenp /= sizeof(u32); - if (freqs == NULL || lenp != 2) { - printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); - goto out; - } - ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); - if (ratio == NULL) { - printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); - goto out; - } - - /* Get the min/max bus frequencies */ - low_freq = min(freqs[0], freqs[1]); - hi_freq = max(freqs[0], freqs[1]); - - /* Grrrr.. It _seems_ that the device-tree is lying on the low bus - * frequency, it claims it to be around 84Mhz on some models while - * it appears to be approx. 101Mhz on all. Let's hack around here... - * fortunately, we don't need to be too precise - */ - if (low_freq < 98000000) - low_freq = 101000000; - - /* Convert those to CPU core clocks */ - low_freq = (low_freq * (*ratio)) / 2000; - hi_freq = (hi_freq * (*ratio)) / 2000; - - /* Now we get the frequencies, we read the GPIO to see what is out current - * speed - */ - rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); - cur_freq = (rc & 0x01) ? hi_freq : low_freq; - - has_freq_ctl = 1; - cpufreq_uses_gpios = 1; - goto out; - } - - /* If we use the PMU, look for the min & max frequencies in the - * device-tree - */ - value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); - if (!value) - goto out; - low_freq = (*value) / 1000; - /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree - * here */ - if (low_freq < 100000) - low_freq *= 10; - - value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); - if (!value) - goto out; - hi_freq = (*value) / 1000; - has_freq_ctl = 1; - cpufreq_uses_pmu = 1; - } + /* Check for 7447A based iBook G4 or PowerBook */ + if (machine_is_compatible("PowerBook6,5") || + machine_is_compatible("PowerBook6,4") || + machine_is_compatible("PowerBook5,5") || + machine_is_compatible("PowerBook5,4")) { + pmac_cpufreq_init_7447A(cpunode); + /* Check for other MacRISC3 machines */ + } else if (machine_is_compatible("PowerBook3,4") || + machine_is_compatible("PowerBook3,5") || + machine_is_compatible("MacRISC3")) { + pmac_cpufreq_init_MacRISC3(cpunode); /* Else check for iBook2 500 */ - else if (machine_is_compatible("PowerBook4,1")) { + } else if (machine_is_compatible("PowerBook4,1")) { /* We only know about 500Mhz model */ if (cur_freq < 450000 || cur_freq > 550000) goto out; hi_freq = cur_freq; low_freq = 400000; - has_freq_ctl = 1; - cpufreq_uses_pmu = 1; + set_speed_proc = pmu_set_cpu_speed; } - /* Else check for TiPb 500 */ + /* Else check for TiPb 400 & 500 */ else if (machine_is_compatible("PowerBook3,2")) { - /* We only know about 500Mhz model */ - if (cur_freq < 450000 || cur_freq > 550000) + /* We only know about the 400 MHz and the 500Mhz model + * they both have 300 MHz as low frequency + */ + if (cur_freq < 350000 || cur_freq > 550000) goto out; hi_freq = cur_freq; low_freq = 300000; - has_freq_ctl = 1; - cpufreq_uses_pmu = 1; + set_speed_proc = pmu_set_cpu_speed; } /* Else check for 750FX */ else if (PVR_VER(mfspr(PVR)) == 0x7000) { @@ -483,21 +560,19 @@ value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); if (!value) goto out; - low_freq = (*value) / 1000; - cpufreq_uses_pmu = 0; - has_freq_ctl = 1; + low_freq = (*value) / 1000; + set_speed_proc = cpu_750fx_cpu_speed; } out: - if (!has_freq_ctl) + if (set_speed_proc == NULL) return -ENODEV; pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq; pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq; printk(KERN_INFO "Registering PowerMac CPU frequency driver\n"); - printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz, switch method: %s\n", - low_freq/1000, hi_freq/1000, cur_freq/1000, - cpufreq_uses_pmu ? "PMU" : (cpufreq_uses_gpios ? "GPIOs" : "CPU")); + printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n", + low_freq/1000, hi_freq/1000, cur_freq/1000); return cpufreq_register_driver(&pmac_cpufreq_driver); } diff -Nru a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c --- a/arch/ppc/platforms/pmac_feature.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/platforms/pmac_feature.c 2004-06-26 17:09:20 -07:00 @@ -1282,6 +1282,25 @@ return 0; } +static long __pmac +intrepid_aack_delay_enable(struct device_node* node, long param, long value) +{ + unsigned long flags; + + if (uninorth_rev < 0xd2) + return -ENODEV; + + LOCK(flags); + if (param) + UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); + else + UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); + UNLOCK(flags); + + return 0; +} + + #endif /* CONFIG_POWER4 */ static long __pmac @@ -1914,6 +1933,7 @@ { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, { PMAC_FTR_READ_GPIO, core99_read_gpio }, { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, + { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable }, { 0, NULL } }; @@ -2116,6 +2136,14 @@ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, }, + { "PowerBook5,4", "PowerBook G4 15\"", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, + { "PowerBook5,5", "PowerBook G4 17\"", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, { "PowerBook6,1", "PowerBook G4 12\"", PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, @@ -2125,6 +2153,10 @@ PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, }, { "PowerBook6,3", "iBook G4", + PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, + PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, + }, + { "PowerBook6,4", "PowerBook G4 12\"", PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, }, diff -Nru a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c --- a/arch/ppc/platforms/pmac_setup.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc/platforms/pmac_setup.c 2004-06-26 17:09:19 -07:00 @@ -103,8 +103,6 @@ static int current_root_goodness = -1; -extern char saved_command_line[]; - extern int pmac_newworld; #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ diff -Nru a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c --- a/arch/ppc/platforms/pplus.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/platforms/pplus.c 2004-06-26 17:09:20 -07:00 @@ -48,8 +48,6 @@ TODC_ALLOC(); -extern char saved_command_line[]; - extern void pplus_setup_hose(void); extern void pplus_set_VIA_IDE_native(void); diff -Nru a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/pq2ads.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,90 @@ +/* + * A collection of structures, addresses, and values associated with + * the Motorola MPC8260ADS/MPC8266ADS-PCI boards. + * Copied from the RPX-Classic and SBS8260 stuff. + * + * Copyright (c) 2001 Dan Malek (dan@mvista.com) + */ +#ifdef __KERNEL__ +#ifndef __MACH_ADS8260_DEFS +#define __MACH_ADS8260_DEFS + +#include + +#include + +/* Memory map is configured by the PROM startup. + * We just map a few things we need. The CSR is actually 4 byte-wide + * registers that can be accessed as 8-, 16-, or 32-bit values. + */ +#define CPM_MAP_ADDR ((uint)0xf0000000) +#define BCSR_ADDR ((uint)0xf4500000) +#define BCSR_SIZE ((uint)(32 * 1024)) + +#define BOOTROM_RESTART_ADDR ((uint)0xff000104) + +/* The ADS8260 has 16, 32-bit wide control/status registers, accessed + * only on word boundaries. + * Not all are used (yet), or are interesting to us (yet). + */ + +/* Things of interest in the CSR. +*/ +#define BCSR0_LED0 ((uint)0x02000000) /* 0 == on */ +#define BCSR0_LED1 ((uint)0x01000000) /* 0 == on */ +#define BCSR1_FETHIEN ((uint)0x08000000) /* 0 == enable */ +#define BCSR1_FETH_RST ((uint)0x04000000) /* 0 == reset */ +#define BCSR1_RS232_EN1 ((uint)0x02000000) /* 0 == enable */ +#define BCSR1_RS232_EN2 ((uint)0x01000000) /* 0 == enable */ + +#define PHY_INTERRUPT SIU_INT_IRQ7 + +#ifdef CONFIG_PCI +/* PCI interrupt controller */ +#define PCI_INT_STAT_REG 0xF8200000 +#define PCI_INT_MASK_REG 0xF8200004 +#define PIRQA (NR_SIU_INTS + 0) +#define PIRQB (NR_SIU_INTS + 1) +#define PIRQC (NR_SIU_INTS + 2) +#define PIRQD (NR_SIU_INTS + 3) + +/* + * PCI memory map definitions for MPC8266ADS-PCI. + * + * processor view + * local address PCI address target + * 0x80000000-0x9FFFFFFF 0x80000000-0x9FFFFFFF PCI mem with prefetch + * 0xA0000000-0xBFFFFFFF 0xA0000000-0xBFFFFFFF PCI mem w/o prefetch + * 0xF4000000-0xF7FFFFFF 0x00000000-0x03FFFFFF PCI IO + * + * PCI master view + * local address PCI address target + * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory + */ + +/* window for a PCI master to access MPC8266 memory */ +#define PCI_SLV_MEM_LOCAL 0x00000000 /* Local base */ +#define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */ + +/* window for the processor to access PCI memory with prefetching */ +#define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */ +#define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */ +#define PCI_MSTR_MEM_SIZE 0x20000000 /* 512MB */ + +/* window for the processor to access PCI memory without prefetching */ +#define PCI_MSTR_MEMIO_LOCAL 0xA0000000 /* Local base */ +#define PCI_MSTR_MEMIO_BUS 0xA0000000 /* PCI base */ +#define PCI_MSTR_MEMIO_SIZE 0x20000000 /* 512MB */ + +/* window for the processor to access PCI I/O */ +#define PCI_MSTR_IO_LOCAL 0xF4000000 /* Local base */ +#define PCI_MSTR_IO_BUS 0x00000000 /* PCI base */ +#define PCI_MSTR_IO_SIZE 0x04000000 /* 64MB */ + +#define _IO_BASE PCI_MSTR_IO_LOCAL +#define _ISA_MEM_BASE PCI_MSTR_MEMIO_LOCAL +#define PCI_DRAM_OFFSET PCI_SLV_MEM_BUS +#endif /* CONFIG_PCI */ + +#endif /* __MACH_ADS8260_DEFS */ +#endif /* __KERNEL__ */ diff -Nru a/arch/ppc/platforms/pq2ads_setup.c b/arch/ppc/platforms/pq2ads_setup.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/pq2ads_setup.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,66 @@ +/* + * arch/ppc/platforms/pq2ads_setup.c + * + * PQ2ADS platform support + * + * Author: Kumar Gala + * Derived from: est8260_setup.c by Allen Curtis + * + * Copyright 2004 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include + +static void (*callback_setup_arch)(void); + +extern unsigned char __res[sizeof(bd_t)]; + +extern void m8260_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7); + +static int +pq2ads_show_cpuinfo(struct seq_file *m) +{ + bd_t *binfo = (bd_t *)__res; + + seq_printf(m, "vendor\t\t: Motorola\n" + "machine\t\t: PQ2 ADS PowerPC\n" + "\n" + "mem size\t\t: 0x%08lx\n" + "console baud\t\t: %ld\n" + "\n", + binfo->bi_memsize, + binfo->bi_baudrate); + return 0; +} + +static void __init +pq2ads_setup_arch(void) +{ + printk("PQ2 ADS Port\n"); + callback_setup_arch(); + *(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2; +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* Generic 8260 platform initialization */ + m8260_init(r3, r4, r5, r6, r7); + + /* Anything special for this platform */ + ppc_md.show_cpuinfo = pq2ads_show_cpuinfo; + + callback_setup_arch = ppc_md.setup_arch; + ppc_md.setup_arch = pq2ads_setup_arch; +} diff -Nru a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c --- a/arch/ppc/platforms/prep_setup.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/platforms/prep_setup.c 2004-06-26 17:09:20 -07:00 @@ -76,7 +76,6 @@ extern void ibm_prep_init(void); extern void prep_find_bridges(void); -extern char saved_command_line[]; int _prep_type; diff -Nru a/arch/ppc/platforms/rpxsuper.h b/arch/ppc/platforms/rpxsuper.h --- a/arch/ppc/platforms/rpxsuper.h 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/platforms/rpxsuper.h 2004-06-26 17:09:18 -07:00 @@ -32,7 +32,7 @@ * We just map a few things we need. The CSR is actually 4 byte-wide * registers that can be accessed as 8-, 16-, or 32-bit values. */ -#define IMAP_ADDR ((uint)0xf0000000) +#define CPM_MAP_ADDR ((uint)0xf0000000) #define RPX_CSR_ADDR ((uint)0xfa000000) #define RPX_CSR_SIZE ((uint)(512 * 1024)) #define RPX_NVRTC_ADDR ((uint)0xfa080000) diff -Nru a/arch/ppc/platforms/sbc82xx.c b/arch/ppc/platforms/sbc82xx.c --- a/arch/ppc/platforms/sbc82xx.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc/platforms/sbc82xx.c 2004-06-26 17:09:16 -07:00 @@ -18,14 +18,18 @@ #include #include #include +#include +#include #include #include #include #include -#include +#include +#include static void (*callback_setup_arch)(void); +static void (*callback_init_IRQ)(void); extern unsigned char __res[sizeof(bd_t)]; @@ -57,6 +61,7 @@ callback_setup_arch(); } +#ifdef CONFIG_GEN_RTC TODC_ALLOC(); /* @@ -64,16 +69,17 @@ * directly use ioremap() at that time. * late_time_init() is call after paging init. */ -#ifdef CONFIG_GEN_RTC + static void sbc82xx_time_init(void) { - volatile memctl8260_t *mc = &immr->im_memctl; - TODC_INIT(TODC_TYPE_MK48T59, 0, 0, SBC82xx_TODC_NVRAM_ADDR, 0); + volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl; /* Set up CS11 for RTC chip */ mc->memc_br11=0; mc->memc_or11=0xffff0836; - mc->memc_br11=0x80000801; + mc->memc_br11=SBC82xx_TODC_NVRAM_ADDR | 0x0801; + + TODC_INIT(TODC_TYPE_MK48T59, 0, 0, SBC82xx_TODC_NVRAM_ADDR, 0); todc_info->nvram_data = (unsigned int)ioremap(todc_info->nvram_data, 0x2000); @@ -86,6 +92,152 @@ } #endif /* CONFIG_GEN_RTC */ +static volatile char *sbc82xx_i8259_map; +static char sbc82xx_i8259_mask = 0xff; +static spinlock_t sbc82xx_i8259_lock = SPIN_LOCK_UNLOCKED; + +static void sbc82xx_i8259_mask_and_ack_irq(unsigned int irq_nr) +{ + unsigned long flags; + + irq_nr -= NR_SIU_INTS; + + spin_lock_irqsave(&sbc82xx_i8259_lock, flags); + sbc82xx_i8259_mask |= 1 << irq_nr; + (void) sbc82xx_i8259_map[1]; /* Dummy read */ + sbc82xx_i8259_map[1] = sbc82xx_i8259_mask; + sbc82xx_i8259_map[0] = 0x20; /* OCW2: Non-specific EOI */ + spin_unlock_irqrestore(&sbc82xx_i8259_lock, flags); +} + +static void sbc82xx_i8259_mask_irq(unsigned int irq_nr) +{ + unsigned long flags; + + irq_nr -= NR_SIU_INTS; + + spin_lock_irqsave(&sbc82xx_i8259_lock, flags); + sbc82xx_i8259_mask |= 1 << irq_nr; + sbc82xx_i8259_map[1] = sbc82xx_i8259_mask; + spin_unlock_irqrestore(&sbc82xx_i8259_lock, flags); +} + +static void sbc82xx_i8259_unmask_irq(unsigned int irq_nr) +{ + unsigned long flags; + + irq_nr -= NR_SIU_INTS; + + spin_lock_irqsave(&sbc82xx_i8259_lock, flags); + sbc82xx_i8259_mask &= ~(1 << irq_nr); + sbc82xx_i8259_map[1] = sbc82xx_i8259_mask; + spin_unlock_irqrestore(&sbc82xx_i8259_lock, flags); +} + +static void sbc82xx_i8259_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) + && irq_desc[irq].action) + sbc82xx_i8259_unmask_irq(irq); +} + + +struct hw_interrupt_type sbc82xx_i8259_ic = { + .typename = " i8259 ", + .enable = sbc82xx_i8259_unmask_irq, + .disable = sbc82xx_i8259_mask_irq, + .ack = sbc82xx_i8259_mask_and_ack_irq, + .end = sbc82xx_i8259_end_irq, +}; + +static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id, struct pt_regs *regs) +{ + spin_lock(&sbc82xx_i8259_lock); + + sbc82xx_i8259_map[0] = 0x0c; /* OCW3: Read IR register on RD# pulse */ + irq = sbc82xx_i8259_map[0] & 7; /* Read IRR */ + + if (irq == 7) { + /* Possible spurious interrupt */ + int isr; + sbc82xx_i8259_map[0] = 0x0b; /* OCW3: Read IS register on RD# pulse */ + isr = sbc82xx_i8259_map[0]; /* Read ISR */ + + if (!(isr & 0x80)) { + printk(KERN_INFO "Spurious i8259 interrupt\n"); + return IRQ_HANDLED; + } + } + ppc_irq_dispatch_handler(regs, NR_SIU_INTS + irq); + return IRQ_HANDLED; +} + +void __init sbc82xx_init_IRQ(void) +{ + volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl; + volatile intctl_cpm2_t *ic = &cpm2_immr->im_intctl; + int i; + + callback_init_IRQ(); + + /* u-boot doesn't always set the board up correctly */ + mc->memc_br5 = 0; + mc->memc_or5 = 0xfff00856; + mc->memc_br5 = 0x22000801; + + sbc82xx_i8259_map = ioremap(0x22008000, 2); + if (!sbc82xx_i8259_map) { + printk(KERN_CRIT "Mapping i8259 interrupt controller failed\n"); + return; + } + + /* Set up the interrupt handlers for the i8259 IRQs */ + for (i = NR_SIU_INTS; i < NR_SIU_INTS + 8; i++) { + irq_desc[i].handler = &sbc82xx_i8259_ic; + irq_desc[i].status |= IRQ_LEVEL; + } + + /* make IRQ6 level sensitive */ + ic->ic_siexr &= ~(1 << (14 - (SIU_INT_IRQ6 - SIU_INT_IRQ1))); + irq_desc[SIU_INT_IRQ6].status |= IRQ_LEVEL; + + /* Initialise the i8259 */ + sbc82xx_i8259_map[0] = 0x1b; /* ICW1: Level, no cascade, ICW4 */ + sbc82xx_i8259_map[1] = 0x00; /* ICW2: vector base */ + /* No ICW3 (no cascade) */ + sbc82xx_i8259_map[1] = 0x01; /* ICW4: 8086 mode, normal EOI */ + + sbc82xx_i8259_map[0] = 0x0b; /* OCW3: Read IS register on RD# pulse */ + + sbc82xx_i8259_map[1] = sbc82xx_i8259_mask; /* Set interrupt mask */ + + /* Request cascade IRQ */ + if (request_irq(SIU_INT_IRQ6, sbc82xx_i8259_demux, SA_INTERRUPT, + "i8259 demux", 0)) { + printk("Installation of i8259 IRQ demultiplexer failed.\n"); + } +} + +static int sbc82xx_pci_map_irq(struct pci_dev *dev, unsigned char idsel, + unsigned char pin) +{ + static char pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { SBC82xx_PIRQA, SBC82xx_PIRQB, SBC82xx_PIRQC, SBC82xx_PIRQD }, /* IDSEL 16 - PMC slot */ + { SBC82xx_PC_IRQA, SBC82xx_PC_IRQB, -1, -1 }, /* IDSEL 17 - CardBus */ + { SBC82xx_PIRQA, SBC82xx_PIRQB, SBC82xx_PIRQC, SBC82xx_PIRQD }, /* IDSEL 18 - PCI-X bridge */ + }; + + const long min_idsel = 16, max_idsel = 18, irqs_per_slot = 4; + + return PCI_IRQ_TABLE_LOOKUP; +} + + + void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) @@ -101,7 +253,11 @@ ppc_md.show_cpuinfo = sbc82xx_show_cpuinfo; callback_setup_arch = ppc_md.setup_arch; + callback_init_IRQ = ppc_md.init_IRQ; + ppc_md.setup_arch = sbc82xx_setup_arch; + ppc_md.init_IRQ = sbc82xx_init_IRQ; + ppc_md.pci_map_irq = sbc82xx_pci_map_irq; #ifdef CONFIG_GEN_RTC ppc_md.time_init = NULL; ppc_md.get_rtc_time = NULL; diff -Nru a/arch/ppc/platforms/sbc82xx.h b/arch/ppc/platforms/sbc82xx.h --- a/arch/ppc/platforms/sbc82xx.h 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc/platforms/sbc82xx.h 2004-06-26 17:09:20 -07:00 @@ -9,10 +9,9 @@ #include -#define IMAP_ADDR 0xf0000000 #define CPM_MAP_ADDR 0xf0000000 -#define SBC82xx_TODC_NVRAM_ADDR 0x80000000 +#define SBC82xx_TODC_NVRAM_ADDR 0xd0000000 #define SBC82xx_MACADDR_NVRAM_FCC1 0x220000c9 /* JP6B */ #define SBC82xx_MACADDR_NVRAM_SCC1 0x220000cf /* JP6A */ @@ -20,5 +19,14 @@ #define SBC82xx_MACADDR_NVRAM_FCC3 0x220000db /* JP7B */ #define BOOTROM_RESTART_ADDR ((uint)0x40000104) + +#define SBC82xx_PC_IRQA (NR_SIU_INTS+0) +#define SBC82xx_PC_IRQB (NR_SIU_INTS+1) +#define SBC82xx_MPC185_IRQ (NR_SIU_INTS+2) +#define SBC82xx_ATM_IRQ (NR_SIU_INTS+3) +#define SBC82xx_PIRQA (NR_SIU_INTS+4) +#define SBC82xx_PIRQB (NR_SIU_INTS+5) +#define SBC82xx_PIRQC (NR_SIU_INTS+6) +#define SBC82xx_PIRQD (NR_SIU_INTS+7) #endif /* __PPC_SBC82xx_H__ */ diff -Nru a/arch/ppc/platforms/sbs8260.h b/arch/ppc/platforms/sbs8260.h --- a/arch/ppc/platforms/sbs8260.h 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/platforms/sbs8260.h 2004-06-26 17:09:15 -07:00 @@ -5,7 +5,7 @@ * the configuration SCMR and the Power-On-Reset word. */ -#define IMAP_ADDR ((uint)0xfe000000) +#define CPM_MAP_ADDR ((uint)0xfe000000) /* A Board Information structure that is given to a program when diff -Nru a/arch/ppc/platforms/tqm8260.h b/arch/ppc/platforms/tqm8260.h --- a/arch/ppc/platforms/tqm8260.h 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/platforms/tqm8260.h 2004-06-26 17:09:18 -07:00 @@ -11,7 +11,7 @@ #include -#define IMAP_ADDR ((uint)0xFFF00000) +#define CPM_MAP_ADDR ((uint)0xFFF00000) #define PHY_INTERRUPT 25 #define BOOTROM_RESTART_ADDR ((uint)0x40000104) diff -Nru a/arch/ppc/platforms/tqm8260_setup.c b/arch/ppc/platforms/tqm8260_setup.c --- a/arch/ppc/platforms/tqm8260_setup.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ppc/platforms/tqm8260_setup.c 2004-06-26 17:09:17 -07:00 @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -44,8 +44,8 @@ static int tqm8260_set_rtc_time(unsigned long time) { - ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt = time; - ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcntsc = 0x3; + ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt = time; + ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcntsc = 0x3; return(0); } @@ -53,7 +53,7 @@ static unsigned long tqm8260_get_rtc_time(void) { - return ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt; + return ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt; } static void __init diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile --- a/arch/ppc/syslib/Makefile 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc/syslib/Makefile 2004-06-26 17:09:15 -07:00 @@ -8,6 +8,9 @@ ifdef CONFIG_4xx EXTRA_AFLAGS := -Wa,-m405 endif +ifdef CONFIG_E500 +EXTRA_AFLAGS := -Wa,-me500 +endif CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC @@ -66,7 +69,10 @@ obj-$(CONFIG_SBC82xx) += todc_time.o obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ todc_time.o -obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o +obj-$(CONFIG_8260) += m8260_setup.o cpm2_pic.o +obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o +obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o +obj-$(CONFIG_CPM2) += cpm2_common.o ifeq ($(CONFIG_PPC_GEN550),y) obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o obj-$(CONFIG_SERIAL_TEXT_DEBUG) += gen550_dbg.o @@ -75,3 +81,7 @@ obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_BOOKE) += dcr.o +obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o +ifeq ($(CONFIG_85xx),y) +obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o +endif diff -Nru a/arch/ppc/syslib/cpm2_common.c b/arch/ppc/syslib/cpm2_common.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/cpm2_common.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,205 @@ +/* + * General Purpose functions for the global management of the + * 8260 Communication Processor Module. + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) + * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) + * 2.3.99 Updates + * + * In addition to the individual control of the communication + * channels, there are a few functions that globally affect the + * communication processor. + * + * Buffer descriptors must be allocated from the dual ported memory + * space. The allocator for that is here. When the communication + * process is reset, we reclaim the memory available. There is + * currently no deallocator for this memory. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void cpm2_dpinit(void); +cpm_cpm2_t *cpmp; /* Pointer to comm processor space */ + +/* We allocate this here because it is used almost exclusively for + * the communication processor devices. + */ +cpm2_map_t *cpm2_immr; + +void +cpm2_reset(void) +{ + cpm2_immr = (cpm2_map_t *)CPM_MAP_ADDR; + + /* Reclaim the DP memory for our use. + */ + cpm2_dpinit(); + + /* Tell everyone where the comm processor resides. + */ + cpmp = &cpm2_immr->im_cpm; +} + +/* Set a baud rate generator. This needs lots of work. There are + * eight BRGs, which can be connected to the CPM channels or output + * as clocks. The BRGs are in two different block of internal + * memory mapped space. + * The baud rate clock is the system clock divided by something. + * It was set up long ago during the initial boot phase and is + * is given to us. + * Baud rate clocks are zero-based in the driver code (as that maps + * to port numbers). Documentation uses 1-based numbering. + */ +#define BRG_INT_CLK (((bd_t *)__res)->bi_brgfreq) +#define BRG_UART_CLK (BRG_INT_CLK/16) + +/* This function is used by UARTS, or anything else that uses a 16x + * oversampled clock. + */ +void +cpm2_setbrg(uint brg, uint rate) +{ + volatile uint *bp; + + /* This is good enough to get SMCs running..... + */ + if (brg < 4) { + bp = (uint *)&cpm2_immr->im_brgc1; + } + else { + bp = (uint *)&cpm2_immr->im_brgc5; + brg -= 4; + } + bp += brg; + *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN; +} + +/* This function is used to set high speed synchronous baud rate + * clocks. + */ +void +cpm2_fastbrg(uint brg, uint rate, int div16) +{ + volatile uint *bp; + + if (brg < 4) { + bp = (uint *)&cpm2_immr->im_brgc1; + } + else { + bp = (uint *)&cpm2_immr->im_brgc5; + brg -= 4; + } + bp += brg; + *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN; + if (div16) + *bp |= CPM_BRG_DIV16; +} + +/* + * dpalloc / dpfree bits. + */ +static spinlock_t cpm_dpmem_lock; +/* 16 blocks should be enough to satisfy all requests + * until the memory subsystem goes up... */ +static rh_block_t cpm_boot_dpmem_rh_block[16]; +static rh_info_t cpm_dpmem_info; + +static void cpm2_dpinit(void) +{ + void *dprambase = &((cpm2_map_t *)CPM_MAP_ADDR)->im_dprambase; + + spin_lock_init(&cpm_dpmem_lock); + + /* initialize the info header */ + rh_init(&cpm_dpmem_info, 1, + sizeof(cpm_boot_dpmem_rh_block) / + sizeof(cpm_boot_dpmem_rh_block[0]), + cpm_boot_dpmem_rh_block); + + /* Attach the usable dpmem area */ + /* XXX: This is actually crap. CPM_DATAONLY_BASE and + * CPM_DATAONLY_SIZE is only a subset of the available dpram. It + * varies with the processor and the microcode patches activated. + * But the following should be at least safe. + */ + rh_attach_region(&cpm_dpmem_info, dprambase + CPM_DATAONLY_BASE, + CPM_DATAONLY_SIZE); +} + +/* This function used to return an index into the DPRAM area. + * Now it returns the actuall physical address of that area. + * use cpm2_dpram_offset() to get the index + */ +void *cpm2_dpalloc(uint size, uint align) +{ + void *start; + unsigned long flags; + + spin_lock_irqsave(&cpm_dpmem_lock, flags); + cpm_dpmem_info.alignment = align; + start = rh_alloc(&cpm_dpmem_info, size, "commproc"); + spin_unlock_irqrestore(&cpm_dpmem_lock, flags); + + return start; +} +EXPORT_SYMBOL(cpm2_dpalloc); + +int cpm2_dpfree(void *addr) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&cpm_dpmem_lock, flags); + ret = rh_free(&cpm_dpmem_info, addr); + spin_unlock_irqrestore(&cpm_dpmem_lock, flags); + + return ret; +} +EXPORT_SYMBOL(cpm2_dpfree); + +/* not sure if this is ever needed */ +void *cpm2_dpalloc_fixed(void *addr, uint size, uint align) +{ + void *start; + unsigned long flags; + + spin_lock_irqsave(&cpm_dpmem_lock, flags); + cpm_dpmem_info.alignment = align; + start = rh_alloc_fixed(&cpm_dpmem_info, addr, size, "commproc"); + spin_unlock_irqrestore(&cpm_dpmem_lock, flags); + + return start; +} +EXPORT_SYMBOL(cpm2_dpalloc_fixed); + +void cpm2_dpdump(void) +{ + rh_dump(&cpm_dpmem_info); +} +EXPORT_SYMBOL(cpm2_dpdump); + +uint cpm2_dpram_offset(void *addr) +{ + return (uint)((u_char *)addr - + ((uint)((cpm2_map_t *)CPM_MAP_ADDR)->im_dprambase)); +} +EXPORT_SYMBOL(cpm2_dpram_offset); + +void *cpm2_dpram_addr(int offset) +{ + return (void *)&((cpm2_map_t *)CPM_MAP_ADDR)->im_dprambase[offset]; +} +EXPORT_SYMBOL(cpm2_dpram_addr); diff -Nru a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/cpm2_pic.c 2004-06-26 17:09:18 -07:00 @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include +#include +#include +#include "cpm2_pic.h" + +/* The CPM2 internal interrupt controller. It is usually + * the only interrupt controller. + * There are two 32-bit registers (high/low) for up to 64 + * possible interrupts. + * + * Now, the fun starts.....Interrupt Numbers DO NOT MAP + * in a simple arithmetic fashion to mask or pending registers. + * That is, interrupt 4 does not map to bit position 4. + * We create two tables, indexed by vector number, to indicate + * which register to use and which bit in the register to use. + */ +static u_char irq_to_siureg[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static u_char irq_to_siubit[] = { + 31, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 29, 30, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 31, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0 +}; + +static void cpm2_mask_irq(unsigned int irq_nr) +{ + int bit, word; + volatile uint *simr; + + bit = irq_to_siubit[irq_nr]; + word = irq_to_siureg[irq_nr]; + + simr = &(cpm2_immr->im_intctl.ic_simrh); + ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); + simr[word] = ppc_cached_irq_mask[word]; +} + +static void cpm2_unmask_irq(unsigned int irq_nr) +{ + int bit, word; + volatile uint *simr; + + bit = irq_to_siubit[irq_nr]; + word = irq_to_siureg[irq_nr]; + + simr = &(cpm2_immr->im_intctl.ic_simrh); + ppc_cached_irq_mask[word] |= (1 << (31 - bit)); + simr[word] = ppc_cached_irq_mask[word]; +} + +static void cpm2_mask_and_ack(unsigned int irq_nr) +{ + int bit, word; + volatile uint *simr, *sipnr; + + bit = irq_to_siubit[irq_nr]; + word = irq_to_siureg[irq_nr]; + + simr = &(cpm2_immr->im_intctl.ic_simrh); + sipnr = &(cpm2_immr->im_intctl.ic_sipnrh); + ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); + simr[word] = ppc_cached_irq_mask[word]; + sipnr[word] = 1 << (31 - bit); +} + +static void cpm2_end_irq(unsigned int irq_nr) +{ + int bit, word; + volatile uint *simr; + + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) + && irq_desc[irq_nr].action) { + + bit = irq_to_siubit[irq_nr]; + word = irq_to_siureg[irq_nr]; + + simr = &(cpm2_immr->im_intctl.ic_simrh); + ppc_cached_irq_mask[word] |= (1 << (31 - bit)); + simr[word] = ppc_cached_irq_mask[word]; + } +} + +struct hw_interrupt_type cpm2_pic = { + " CPM2 SIU ", + NULL, + NULL, + cpm2_unmask_irq, + cpm2_mask_irq, + cpm2_mask_and_ack, + cpm2_end_irq, + 0 +}; + + +int +cpm2_get_irq(struct pt_regs *regs) +{ + int irq; + unsigned long bits; + + /* For CPM2, read the SIVEC register and shift the bits down + * to get the irq number. */ + bits = cpm2_immr->im_intctl.ic_sivec; + irq = bits >> 26; + + if (irq == 0) + return(-1); +#if 0 + irq += ppc8260_pic.irq_offset; +#endif + return irq; +} + diff -Nru a/arch/ppc/syslib/cpm2_pic.h b/arch/ppc/syslib/cpm2_pic.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/cpm2_pic.h 2004-06-26 17:09:20 -07:00 @@ -0,0 +1,13 @@ +#ifndef _PPC_KERNEL_CPM2_H +#define _PPC_KERNEL_CPM2_H + +#include + +extern struct hw_interrupt_type cpm2_pic; + +void cpm2_pic_init(void); +void cpm2_do_IRQ(struct pt_regs *regs, + int cpu); +int cpm2_get_irq(struct pt_regs *regs); + +#endif /* _PPC_KERNEL_CPM2_H */ diff -Nru a/arch/ppc/syslib/m8260_pci.c b/arch/ppc/syslib/m8260_pci.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/m8260_pci.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,194 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004 Red Hat, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "m8260_pci.h" + + +/* PCI bus configuration registers. + */ + +static void __init m8260_setup_pci(struct pci_controller *hose) +{ + volatile cpm2_map_t *immap = cpm2_immr; + unsigned long pocmr; + u16 tempShort; + +#ifndef CONFIG_ATC /* already done in U-Boot */ + /* + * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), + * and local bus for PCI (SIUMCR [LBPC]). + */ + immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000; +#endif + + /* Make PCI lowest priority */ + /* Each 4 bits is a device bus request and the MS 4bits + is highest priority */ + /* Bus 4bit value + --- ---------- + CPM high 0b0000 + CPM middle 0b0001 + CPM low 0b0010 + PCI reguest 0b0011 + Reserved 0b0100 + Reserved 0b0101 + Internal Core 0b0110 + External Master 1 0b0111 + External Master 2 0b1000 + External Master 3 0b1001 + The rest are reserved */ + immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; + + /* Park bus on core while modifying PCI Bus accesses */ + immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6; + + /* + * Set up master window that allows the CPU to access PCI space. This + * window is set up using the first SIU PCIBR registers. + */ + immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK; + immap->im_memctl.memc_pcibr0 = MPC826x_PCI_BASE | PCIBR_ENABLE; + + /* Disable machine check on no response or target abort */ + immap->im_pci.pci_emr = cpu_to_le32(0x1fe7); + /* Release PCI RST (by default the PCI RST signal is held low) */ + immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); + + /* give it some time */ + mdelay(1); + + /* + * Set up master window that allows the CPU to access PCI Memory (prefetch) + * space. This window is set up using the first set of Outbound ATU registers. + */ + immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12); + immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12); + pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff; + immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN); + + /* + * Set up master window that allows the CPU to access PCI Memory (non-prefetch) + * space. This window is set up using the second set of Outbound ATU registers. + */ + immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12); + immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12); + pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff; + immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE); + + /* + * Set up master window that allows the CPU to access PCI IO space. This window + * is set up using the third set of Outbound ATU registers. + */ + immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12); + immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12); + pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff; + immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO); + + /* + * Set up slave window that allows PCI masters to access MPC826x local memory. + * This window is set up using the first set of Inbound ATU registers + */ + + immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12); + immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12); + pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff; + immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN); + + /* See above for description - puts PCI request as highest priority */ + immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; + + /* Park the bus on the PCI */ + immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; + + /* Host mode - specify the bridge as a host-PCI bridge */ + early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST); + + /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */ + early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort); + early_write_config_word(hose, 0, 0, PCI_COMMAND, + tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); +} + +void __init m8260_find_bridges(void) +{ + extern int pci_assign_all_busses; + struct pci_controller * hose; + + pci_assign_all_busses = 1; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + ppc_md.pci_swizzle = common_swizzle; + + hose->first_busno = 0; + hose->bus_offset = 0; + hose->last_busno = 0xff; + + setup_m8260_indirect_pci(hose, + (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, + (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); + + m8260_setup_pci(hose); + hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET; + + isa_io_base = + (unsigned long) ioremap(MPC826x_PCI_IO_BASE, + MPC826x_PCI_IO_SIZE); + hose->io_base_virt = (void *) isa_io_base; + + /* setup resources */ + pci_init_resource(&hose->mem_resources[0], + MPC826x_PCI_LOWER_MEM, + MPC826x_PCI_UPPER_MEM, + IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); + + pci_init_resource(&hose->mem_resources[1], + MPC826x_PCI_LOWER_MMIO, + MPC826x_PCI_UPPER_MMIO, + IORESOURCE_MEM, "PCI memory"); + + pci_init_resource(&hose->io_resource, + MPC826x_PCI_LOWER_IO, + MPC826x_PCI_UPPER_IO, + IORESOURCE_IO, "PCI I/O"); +} diff -Nru a/arch/ppc/syslib/m8260_pci.h b/arch/ppc/syslib/m8260_pci.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/m8260_pci.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,75 @@ + +#ifndef _PPC_KERNEL_M8260_PCI_H +#define _PPC_KERNEL_M8260_PCI_H + +#include + +/* + * Local->PCI map (from CPU) controlled by + * MPC826x master window + * + * 0x80000000 - 0xBFFFFFFF Total CPU2PCI space PCIBR0 + * + * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1) + * 0xA0000000 - 0xAFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2) + * 0xB0000000 - 0xB0FFFFFF 32-bit PCI IO (Outbound ATU #3) + * + * PCI->Local map (from PCI) + * MPC826x slave window controlled by + * + * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1) + */ + +/* + * Slave window that allows PCI masters to access MPC826x local memory. + * This window is set up using the first set of Inbound ATU registers + */ + +#ifndef MPC826x_PCI_SLAVE_MEM_LOCAL +#define MPC826x_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart) +#define MPC826x_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart) +#define MPC826x_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize) +#endif + +/* + * This is the window that allows the CPU to access PCI address space. + * It will be setup with the SIU PCIBR0 register. All three PCI master + * windows, which allow the CPU to access PCI prefetch, non prefetch, + * and IO space (see below), must all fit within this window. + */ +#ifndef MPC826x_PCI_BASE +#define MPC826x_PCI_BASE 0x80000000 +#define MPC826x_PCI_MASK 0xc0000000 +#endif + +#ifndef MPC826x_PCI_LOWER_MEM +#define MPC826x_PCI_LOWER_MEM 0x80000000 +#define MPC826x_PCI_UPPER_MEM 0x9fffffff +#define MPC826x_PCI_MEM_OFFSET 0x00000000 +#endif + +#ifndef MPC826x_PCI_LOWER_MMIO +#define MPC826x_PCI_LOWER_MMIO 0xa0000000 +#define MPC826x_PCI_UPPER_MMIO 0xafffffff +#define MPC826x_PCI_MMIO_OFFSET 0x00000000 +#endif + +#ifndef MPC826x_PCI_LOWER_IO +#define MPC826x_PCI_LOWER_IO 0x00000000 +#define MPC826x_PCI_UPPER_IO 0x00ffffff +#define MPC826x_PCI_IO_BASE 0xb0000000 +#define MPC826x_PCI_IO_SIZE 0x01000000 +#endif + +#ifndef _IO_BASE +#define _IO_BASE isa_io_base +#endif + +#ifdef CONFIG_8260_PCI9 +extern void setup_m8260_indirect_pci(struct pci_controller* hose, + u32 cfg_addr, u32 cfg_data); +#else +#define setup_m8260_indirect_pci setup_indirect_pci +#endif + +#endif /* _PPC_KERNEL_M8260_PCI_H */ diff -Nru a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/m8260_pci_erratum9.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,474 @@ +/* + * arch/ppc/platforms/mpc8260_pci9.c + * + * Workaround for device erratum PCI 9. + * See Motorola's "XPC826xA Family Device Errata Reference." + * The erratum applies to all 8260 family Hip4 processors. It is scheduled + * to be fixed in HiP4 Rev C. Erratum PCI 9 states that a simultaneous PCI + * inbound write transaction and PCI outbound read transaction can result in a + * bus deadlock. The suggested workaround is to use the IDMA controller to + * perform all reads from PCI configuration, memory, and I/O space. + * + * Author: andy_lowe@mvista.com + * + * 2003 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "m8260_pci.h" + +#ifdef CONFIG_8260_PCI9 +/*#include */ /* included in asm/io.h */ + +#define IDMA_XFER_BUF_SIZE 64 /* size of the IDMA transfer buffer */ + +/* define a structure for the IDMA dpram usage */ +typedef struct idma_dpram_s { + idma_t pram; /* IDMA parameter RAM */ + u_char xfer_buf[IDMA_XFER_BUF_SIZE]; /* IDMA transfer buffer */ + idma_bd_t bd; /* buffer descriptor */ +} idma_dpram_t; + +/* define offsets relative to start of IDMA dpram */ +#define IDMA_XFER_BUF_OFFSET (sizeof(idma_t)) +#define IDMA_BD_OFFSET (sizeof(idma_t) + IDMA_XFER_BUF_SIZE) + +/* define globals */ +static volatile idma_dpram_t *idma_dpram; + +/* Exactly one of CONFIG_8260_PCI9_IDMAn must be defined, + * where n is 1, 2, 3, or 4. This selects the IDMA channel used for + * the PCI9 workaround. + */ +#ifdef CONFIG_8260_PCI9_IDMA1 +#define IDMA_CHAN 0 +#define PROFF_IDMA PROFF_IDMA1_BASE +#define IDMA_PAGE CPM_CR_IDMA1_PAGE +#define IDMA_SBLOCK CPM_CR_IDMA1_SBLOCK +#endif +#ifdef CONFIG_8260_PCI9_IDMA2 +#define IDMA_CHAN 1 +#define PROFF_IDMA PROFF_IDMA2_BASE +#define IDMA_PAGE CPM_CR_IDMA2_PAGE +#define IDMA_SBLOCK CPM_CR_IDMA2_SBLOCK +#endif +#ifdef CONFIG_8260_PCI9_IDMA3 +#define IDMA_CHAN 2 +#define PROFF_IDMA PROFF_IDMA3_BASE +#define IDMA_PAGE CPM_CR_IDMA3_PAGE +#define IDMA_SBLOCK CPM_CR_IDMA3_SBLOCK +#endif +#ifdef CONFIG_8260_PCI9_IDMA4 +#define IDMA_CHAN 3 +#define PROFF_IDMA PROFF_IDMA4_BASE +#define IDMA_PAGE CPM_CR_IDMA4_PAGE +#define IDMA_SBLOCK CPM_CR_IDMA4_SBLOCK +#endif + +void idma_pci9_init(void) +{ + uint dpram_offset; + volatile idma_t *pram; + volatile im_idma_t *idma_reg; + volatile cpm2_map_t *immap = cpm2_immr; + + /* allocate IDMA dpram */ + dpram_offset = cpm2_dpalloc(sizeof(idma_dpram_t), 64); + idma_dpram = + (volatile idma_dpram_t *)&immap->im_dprambase[dpram_offset]; + + /* initialize the IDMA parameter RAM */ + memset((void *)idma_dpram, 0, sizeof(idma_dpram_t)); + pram = &idma_dpram->pram; + pram->ibase = dpram_offset + IDMA_BD_OFFSET; + pram->dpr_buf = dpram_offset + IDMA_XFER_BUF_OFFSET; + pram->ss_max = 32; + pram->dts = 32; + + /* initialize the IDMA_BASE pointer to the IDMA parameter RAM */ + *((ushort *) &immap->im_dprambase[PROFF_IDMA]) = dpram_offset; + + /* initialize the IDMA registers */ + idma_reg = (volatile im_idma_t *) &immap->im_sdma.sdma_idsr1; + idma_reg[IDMA_CHAN].idmr = 0; /* mask all IDMA interrupts */ + idma_reg[IDMA_CHAN].idsr = 0xff; /* clear all event flags */ + + printk("<4>Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n", + IDMA_CHAN + 1); + + return; +} + +/* Use the IDMA controller to transfer data from I/O memory to local RAM. + * The src address must be a physical address suitable for use by the DMA + * controller with no translation. The dst address must be a kernel virtual + * address. The dst address is translated to a physical address via + * virt_to_phys(). + * The sinc argument specifies whether or not the source address is incremented + * by the DMA controller. The source address is incremented if and only if sinc + * is non-zero. The destination address is always incremented since the + * destination is always host RAM. + */ +static void +idma_pci9_read(u8 *dst, u8 *src, int bytes, int unit_size, int sinc) +{ + unsigned long flags; + volatile idma_t *pram = &idma_dpram->pram; + volatile idma_bd_t *bd = &idma_dpram->bd; + volatile cpm2_map_t *immap = cpm2_immr; + + local_irq_save(flags); + + /* initialize IDMA parameter RAM for this transfer */ + if (sinc) + pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC + | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM; + else + pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_DINC + | IDMA_DCM_SD_MEM2MEM; + pram->ibdptr = pram->ibase; + pram->sts = unit_size; + pram->istate = 0; + + /* initialize the buffer descriptor */ + bd->dst = virt_to_phys(dst); + bd->src = (uint) src; + bd->len = bytes; + bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL + | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB; + + /* issue the START_IDMA command to the CP */ + while (immap->im_cpm.cp_cpcr & CPM_CR_FLG); + immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0, + CPM_CR_START_IDMA) | CPM_CR_FLG; + while (immap->im_cpm.cp_cpcr & CPM_CR_FLG); + + /* wait for transfer to complete */ + while(bd->flags & IDMA_BD_V); + + local_irq_restore(flags); + + return; +} + +/* Use the IDMA controller to transfer data from I/O memory to local RAM. + * The dst address must be a physical address suitable for use by the DMA + * controller with no translation. The src address must be a kernel virtual + * address. The src address is translated to a physical address via + * virt_to_phys(). + * The dinc argument specifies whether or not the dest address is incremented + * by the DMA controller. The source address is incremented if and only if sinc + * is non-zero. The source address is always incremented since the + * source is always host RAM. + */ +static void +idma_pci9_write(u8 *dst, u8 *src, int bytes, int unit_size, int dinc) +{ + unsigned long flags; + volatile idma_t *pram = &idma_dpram->pram; + volatile idma_bd_t *bd = &idma_dpram->bd; + volatile cpm2_map_t *immap = cpm2_immr; + + local_irq_save(flags); + + /* initialize IDMA parameter RAM for this transfer */ + if (dinc) + pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC + | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM; + else + pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC + | IDMA_DCM_SD_MEM2MEM; + pram->ibdptr = pram->ibase; + pram->sts = unit_size; + pram->istate = 0; + + /* initialize the buffer descriptor */ + bd->dst = (uint) dst; + bd->src = virt_to_phys(src); + bd->len = bytes; + bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL + | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB; + + /* issue the START_IDMA command to the CP */ + while (immap->im_cpm.cp_cpcr & CPM_CR_FLG); + immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0, + CPM_CR_START_IDMA) | CPM_CR_FLG; + while (immap->im_cpm.cp_cpcr & CPM_CR_FLG); + + /* wait for transfer to complete */ + while(bd->flags & IDMA_BD_V); + + local_irq_restore(flags); + + return; +} + +/* Same as idma_pci9_read, but 16-bit little-endian byte swapping is performed + * if the unit_size is 2, and 32-bit little-endian byte swapping is performed if + * the unit_size is 4. + */ +static void +idma_pci9_read_le(u8 *dst, u8 *src, int bytes, int unit_size, int sinc) +{ + int i; + u8 *p; + + idma_pci9_read(dst, src, bytes, unit_size, sinc); + switch(unit_size) { + case 2: + for (i = 0, p = dst; i < bytes; i += 2, p += 2) + swab16s((u16 *) p); + break; + case 4: + for (i = 0, p = dst; i < bytes; i += 4, p += 4) + swab32s((u32 *) p); + break; + default: + break; + } +} +EXPORT_SYMBOL(idma_pci9_init); +EXPORT_SYMBOL(idma_pci9_read); +EXPORT_SYMBOL(idma_pci9_read_le); + +static inline int is_pci_mem(unsigned long addr) +{ + if (addr >= MPC826x_PCI_LOWER_MMIO && + addr <= MPC826x_PCI_UPPER_MMIO) + return 1; + if (addr >= MPC826x_PCI_LOWER_MEM && + addr <= MPC826x_PCI_UPPER_MEM) + return 1; + return 0; +} + +#define is_pci_mem(pa) ( (pa > 0x80000000) && (pa < 0xc0000000)) +int readb(volatile unsigned char *addr) +{ + u8 val; + unsigned long pa = iopa((unsigned long) addr); + + if (!is_pci_mem(pa)) + return in_8(addr); + + idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0); + return val; +} + +int readw(volatile unsigned short *addr) +{ + u16 val; + unsigned long pa = iopa((unsigned long) addr); + + if (!is_pci_mem(pa)) + return in_le16(addr); + + idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0); + return swab16(val); +} + +unsigned readl(volatile unsigned *addr) +{ + u32 val; + unsigned long pa = iopa((unsigned long) addr); + + if (!is_pci_mem(pa)) + return in_le32(addr); + + idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0); + return swab32(val); +} + +int inb(unsigned port) +{ + u8 val; + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0); + return val; +} + +int inw(unsigned port) +{ + u16 val; + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0); + return swab16(val); +} + +unsigned inl(unsigned port) +{ + u32 val; + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0); + return swab32(val); +} + +void insb(unsigned port, void *buf, int ns) +{ + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u8), sizeof(u8), 0); +} + +void insw(unsigned port, void *buf, int ns) +{ + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0); +} + +void insl(unsigned port, void *buf, int nl) +{ + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0); +} + +void insw_ns(unsigned port, void *buf, int ns) +{ + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0); +} + +void insl_ns(unsigned port, void *buf, int nl) +{ + u8 *addr = (u8 *)(port + _IO_BASE); + + idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0); +} + +void *memcpy_fromio(void *dest, unsigned long src, size_t count) +{ + unsigned long pa = iopa((unsigned long) src); + + if (is_pci_mem(pa)) + idma_pci9_read((u8 *)dest, (u8 *)pa, count, 32, 1); + else + memcpy(dest, (void *)src, count); + return dest; +} + +EXPORT_SYMBOL(readb); +EXPORT_SYMBOL(readw); +EXPORT_SYMBOL(readl); +EXPORT_SYMBOL(inb); +EXPORT_SYMBOL(inw); +EXPORT_SYMBOL(inl); +EXPORT_SYMBOL(insb); +EXPORT_SYMBOL(insw); +EXPORT_SYMBOL(insl); +EXPORT_SYMBOL(insw_ns); +EXPORT_SYMBOL(insl_ns); +EXPORT_SYMBOL(memcpy_fromio); + +#endif /* ifdef CONFIG_8260_PCI9 */ + +/* Indirect PCI routines adapted from arch/ppc/kernel/indirect_pci.c. + * Copyright (C) 1998 Gabriel Paubert. + */ +#ifndef CONFIG_8260_PCI9 +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#else +#define cfg_read(val, addr, type, op) \ + idma_pci9_read_le((u8*)(val),(u8*)(addr),sizeof(*(val)),sizeof(*(val)),0) +#endif + +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +static int indirect_write_config(struct pci_bus *pbus, unsigned int devfn, int where, + int size, u32 value) +{ + struct pci_controller *hose = pbus->sysdata; + u8 cfg_type = 0; + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(pbus->number, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (hose->set_cfg_type) + if (pbus->number != hose->first_busno) + cfg_type = 1; + + out_be32(hose->cfg_addr, + (((where & 0xfc) | cfg_type) << 24) | (devfn << 16) + | ((pbus->number - hose->bus_offset) << 8) | 0x80); + + switch (size) + { + case 1: + cfg_write(value, hose->cfg_data + (where & 3), u8, out_8); + break; + case 2: + cfg_write(value, hose->cfg_data + (where & 2), u16, out_le16); + break; + case 4: + cfg_write(value, hose->cfg_data + (where & 0), u32, out_le32); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int indirect_read_config(struct pci_bus *pbus, unsigned int devfn, int where, + int size, u32 *value) +{ + struct pci_controller *hose = pbus->sysdata; + u8 cfg_type = 0; + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(pbus->number, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (hose->set_cfg_type) + if (pbus->number != hose->first_busno) + cfg_type = 1; + + out_be32(hose->cfg_addr, + (((where & 0xfc) | cfg_type) << 24) | (devfn << 16) + | ((pbus->number - hose->bus_offset) << 8) | 0x80); + + switch (size) + { + case 1: + cfg_read(value, hose->cfg_data + (where & 3), u8 *, in_8); + break; + case 2: + cfg_read(value, hose->cfg_data + (where & 2), u16 *, in_le16); + break; + case 4: + cfg_read(value, hose->cfg_data + (where & 0), u32 *, in_le32); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops indirect_pci_ops = +{ + .read = indirect_read_config, + .write = indirect_write_config, +}; + +void +setup_m8260_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) +{ + hose->ops = &indirect_pci_ops; + hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4); + hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4); +} diff -Nru a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c --- a/arch/ppc/syslib/m8260_setup.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/syslib/m8260_setup.c 2004-06-26 17:09:18 -07:00 @@ -39,12 +39,12 @@ #include #include #include -#include +#include #include #include #include -#include "ppc8260_pic.h" +#include "cpm2_pic.h" static int m8260_set_rtc_time(unsigned long time); static unsigned long m8260_get_rtc_time(void); @@ -52,14 +52,23 @@ unsigned char __res[sizeof(bd_t)]; -extern void m8260_cpm_reset(void); +extern void cpm2_reset(void); +extern void m8260_find_bridges(void); +extern void idma_pci9_init(void); static void __init m8260_setup_arch(void) { /* Reset the Communication Processor Module. */ - m8260_cpm_reset(); + cpm2_reset(); +#ifdef CONFIG_8260_PCI9 + /* Initialise IDMA for PCI erratum workaround */ + idma_pci9_init(); +#endif +#ifdef CONFIG_PCI_8260 + m8260_find_bridges(); +#endif } /* The decrementer counts at the system (internal) clock frequency @@ -142,9 +151,9 @@ bp = (bd_t *)__res; - seq_printf(m, "core clock\t: %d MHz\n" - "CPM clock\t: %d MHz\n" - "bus clock\t: %d MHz\n", + seq_printf(m, "core clock\t: %ld MHz\n" + "CPM clock\t: %ld MHz\n" + "bus clock\t: %ld MHz\n", bp->bi_intfreq / 1000000, bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000); @@ -164,15 +173,15 @@ void cpm_interrupt_init(void); for ( i = 0 ; i < NR_SIU_INTS ; i++ ) - irq_desc[i].handler = &ppc8260_pic; + irq_desc[i].handler = &cpm2_pic; /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. */ - immr->im_intctl.ic_sicr = 0; - immr->im_intctl.ic_siprr = 0x05309770; - immr->im_intctl.ic_scprrh = 0x05309770; - immr->im_intctl.ic_scprrl = 0x05309770; + cpm2_immr->im_intctl.ic_sicr = 0; + cpm2_immr->im_intctl.ic_siprr = 0x05309770; + cpm2_immr->im_intctl.ic_scprrh = 0x05309770; + cpm2_immr->im_intctl.ic_scprrl = 0x05309770; } /* @@ -200,7 +209,7 @@ uint addr; /* Map IMMR region to a 256MB BAT */ - addr = (immr != NULL) ? (uint)immr : IMAP_ADDR; + addr = (cpm2_immr != NULL) ? (uint)cpm2_immr : CPM_MAP_ADDR; io_block_mapping(addr, addr, 0x10000000, _PAGE_IO); /* Map I/O region to a 256MB BAT */ @@ -244,7 +253,7 @@ ppc_md.show_percpuinfo = m8260_show_percpuinfo; ppc_md.irq_canonicalize = NULL; ppc_md.init_IRQ = m8260_init_IRQ; - ppc_md.get_irq = m8260_get_irq; + ppc_md.get_irq = cpm2_get_irq; ppc_md.init = NULL; ppc_md.restart = m8260_restart; diff -Nru a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c --- a/arch/ppc/syslib/open_pic.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc/syslib/open_pic.c 2004-06-26 17:09:18 -07:00 @@ -28,7 +28,7 @@ #include "open_pic_defs.h" -#ifdef CONFIG_PRPMC800 +#if defined(CONFIG_PRPMC800) || defined(CONFIG_85xx) #define OPENPIC_BIG_ENDIAN #endif diff -Nru a/arch/ppc/syslib/ppc8260_pic.c b/arch/ppc/syslib/ppc8260_pic.c --- a/arch/ppc/syslib/ppc8260_pic.c 2004-06-26 17:09:18 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,131 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "ppc8260_pic.h" - -/* The 8260 internal interrupt controller. It is usually - * the only interrupt controller. - * There are two 32-bit registers (high/low) for up to 64 - * possible interrupts. - * - * Now, the fun starts.....Interrupt Numbers DO NOT MAP - * in a simple arithmetic fashion to mask or pending registers. - * That is, interrupt 4 does not map to bit position 4. - * We create two tables, indexed by vector number, to indicate - * which register to use and which bit in the register to use. - */ -static u_char irq_to_siureg[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static u_char irq_to_siubit[] = { - 31, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 29, 30, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 31, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 15, 14, 13, 12, 11, 10, 9, 8, - 7, 6, 5, 4, 3, 2, 1, 0 -}; - -static void m8260_mask_irq(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; -} - -static void m8260_unmask_irq(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] |= (1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; -} - -static void m8260_mask_and_ack(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr, *sipnr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - sipnr = &(immr->im_intctl.ic_sipnrh); - ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; - sipnr[word] = 1 << (31 - bit); -} - -static void m8260_end_irq(unsigned int irq_nr) -{ - int bit, word; - volatile uint *simr; - - if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) - && irq_desc[irq_nr].action) { - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] |= (1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; - } -} - -struct hw_interrupt_type ppc8260_pic = { - " 8260 SIU ", - NULL, - NULL, - m8260_unmask_irq, - m8260_mask_irq, - m8260_mask_and_ack, - m8260_end_irq, - 0 -}; - - -int -m8260_get_irq(struct pt_regs *regs) -{ - int irq; - unsigned long bits; - - /* For MPC8260, read the SIVEC register and shift the bits down - * to get the irq number. */ - bits = immr->im_intctl.ic_sivec; - irq = bits >> 26; - - if (irq == 0) - return(-1); -#if 0 - irq += ppc8260_pic.irq_offset; -#endif - return irq; -} - diff -Nru a/arch/ppc/syslib/ppc8260_pic.h b/arch/ppc/syslib/ppc8260_pic.h --- a/arch/ppc/syslib/ppc8260_pic.h 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,13 +0,0 @@ -#ifndef _PPC_KERNEL_PPC8260_H -#define _PPC_KERNEL_PPC8260_H - -#include - -extern struct hw_interrupt_type ppc8260_pic; - -void m8260_pic_init(void); -void m8260_do_IRQ(struct pt_regs *regs, - int cpu); -int m8260_get_irq(struct pt_regs *regs); - -#endif /* _PPC_KERNEL_PPC8260_H */ diff -Nru a/arch/ppc/syslib/ppc85xx_common.c b/arch/ppc/syslib/ppc85xx_common.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/ppc85xx_common.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,46 @@ +/* + * arch/ppc/syslib/ppc85xx_common.c + * + * MPC85xx support routines + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* ************************************************************************ */ +/* Return the value of CCSRBAR for the current board */ + +phys_addr_t +get_ccsrbar(void) +{ + return BOARD_CCSRBAR; +} + +/* ************************************************************************ */ +/* Update the 85xx OCP tables paddr field */ +void +mpc85xx_update_paddr_ocp(struct ocp_device *dev, void *arg) +{ + phys_addr_t ccsrbar; + if (arg) { + ccsrbar = *(phys_addr_t *)arg; + dev->def->paddr += ccsrbar; + } +} + +EXPORT_SYMBOL(get_ccsrbar); diff -Nru a/arch/ppc/syslib/ppc85xx_common.h b/arch/ppc/syslib/ppc85xx_common.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/ppc85xx_common.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,29 @@ +/* + * arch/ppc/syslib/ppc85xx_common.h + * + * MPC85xx support routines + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_SYSLIB_PPC85XX_COMMON_H +#define __PPC_SYSLIB_PPC85XX_COMMON_H + +#include +#include +#include + +/* Provide access to ccsrbar for any modules, etc */ +phys_addr_t get_ccsrbar(void); + +/* Update the 85xx OCP tables paddr field */ +void mpc85xx_update_paddr_ocp(struct ocp_device *dev, void *ccsrbar); + +#endif /* __PPC_SYSLIB_PPC85XX_COMMON_H */ diff -Nru a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/ppc85xx_setup.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,343 @@ +/* + * arch/ppc/syslib/ppc85xx_setup.c + * + * MPC85XX common board code + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include /* for linux/serial_core.h */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Return the amount of memory */ +unsigned long __init +mpc85xx_find_end_of_memory(void) +{ + bd_t *binfo; + + binfo = (bd_t *) __res; + + return binfo->bi_memsize; +} + +/* The decrementer counts at the system (internal) clock freq divided by 8 */ +void __init +mpc85xx_calibrate_decr(void) +{ + bd_t *binfo = (bd_t *) __res; + unsigned int freq, divisor; + + /* get the core frequency */ + freq = binfo->bi_busfreq; + + /* The timebase is updated every 8 bus clocks, HID0[SEL_TBCLK] = 0 */ + divisor = 8; + tb_ticks_per_jiffy = freq / divisor / HZ; + tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); + + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + + /* Enable decrementer interrupt */ + mtspr(SPRN_TCR, TCR_DIE); +} + +#ifdef CONFIG_SERIAL_8250 +void __init +mpc85xx_early_serial_map(void) +{ + struct uart_port serial_req; + bd_t *binfo = (bd_t *) __res; + phys_addr_t duart_paddr = binfo->bi_immr_base + MPC85xx_UART0_OFFSET; + + /* Setup serial port access */ + memset(&serial_req, 0, sizeof (serial_req)); + serial_req.uartclk = binfo->bi_busfreq; + serial_req.line = 0; + serial_req.irq = MPC85xx_IRQ_DUART; + serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + serial_req.iotype = SERIAL_IO_MEM; + serial_req.membase = ioremap(duart_paddr, MPC85xx_UART0_SIZE); + serial_req.mapbase = duart_paddr; + serial_req.regshift = 0; + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(0, &serial_req); +#endif + + if (early_serial_setup(&serial_req) != 0) + printk("Early serial init of port 0 failed\n"); + + /* Assume early_serial_setup() doesn't modify serial_req */ + duart_paddr = binfo->bi_immr_base + MPC85xx_UART1_OFFSET; + serial_req.line = 1; + serial_req.mapbase = duart_paddr; + serial_req.membase = ioremap(duart_paddr, MPC85xx_UART1_SIZE); + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(1, &serial_req); +#endif + + if (early_serial_setup(&serial_req) != 0) + printk("Early serial init of port 1 failed\n"); +} +#endif + +void +mpc85xx_restart(char *cmd) +{ + local_irq_disable(); + abort(); +} + +void +mpc85xx_power_off(void) +{ + local_irq_disable(); + for(;;); +} + +void +mpc85xx_halt(void) +{ + local_irq_disable(); + for(;;); +} + +#ifdef CONFIG_PCI +static void __init +mpc85xx_setup_pci1(struct pci_controller *hose) +{ + volatile struct ccsr_pci *pci; + volatile struct ccsr_guts *guts; + unsigned short temps; + bd_t *binfo = (bd_t *) __res; + + pci = ioremap(binfo->bi_immr_base + MPC85xx_PCI1_OFFSET, + MPC85xx_PCI1_SIZE); + + guts = ioremap(binfo->bi_immr_base + MPC85xx_GUTS_OFFSET, + MPC85xx_GUTS_SIZE); + + early_read_config_word(hose, 0, 0, PCI_COMMAND, &temps); + temps |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + early_write_config_word(hose, 0, 0, PCI_COMMAND, temps); + +#define PORDEVSR_PCI (0x00800000) /* PCI Mode */ + if (guts->pordevsr & PORDEVSR_PCI) { + early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); + } else { + /* PCI-X init */ + temps = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ + | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E; + early_write_config_word(hose, 0, 0, PCIX_COMMAND, temps); + } + + /* Disable all windows (except powar0 since its ignored) */ + pci->powar1 = 0; + pci->powar2 = 0; + pci->powar3 = 0; + pci->powar4 = 0; + pci->piwar1 = 0; + pci->piwar2 = 0; + pci->piwar3 = 0; + + /* Setup 512M Phys:PCI 1:1 outbound mem window @ 0x80000000 */ + pci->potar1 = (MPC85XX_PCI1_LOWER_MEM >> 12) & 0x000fffff; + pci->potear1 = 0x00000000; + pci->powbar1 = (MPC85XX_PCI1_LOWER_MEM >> 12) & 0x000fffff; + pci->powar1 = 0x8004401c; /* Enable, Mem R/W, 512M */ + + /* Setup 16M outboud IO windows @ 0xe2000000 */ + pci->potar2 = 0x00000000; + pci->potear2 = 0x00000000; + pci->powbar2 = (MPC85XX_PCI1_IO_BASE >> 12) & 0x000fffff; + pci->powar2 = 0x80088017; /* Enable, IO R/W, 16M */ + + /* Setup 2G inbound Memory Window @ 0 */ + pci->pitar1 = 0x00000000; + pci->piwbar1 = 0x00000000; + pci->piwar1 = 0xa0f5501e; /* Enable, Prefetch, Local + Mem, Snoop R/W, 2G */ +} + + +extern int mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin); +extern int mpc85xx_exclude_device(u_char bus, u_char devfn); + +#if CONFIG_85xx_PCI2 +static void __init +mpc85xx_setup_pci2(struct pci_controller *hose) +{ + volatile struct ccsr_pci *pci; + unsigned short temps; + bd_t *binfo = (bd_t *) __res; + + pci = ioremap(binfo->bi_immr_base + MPC85xx_PCI2_OFFSET, + MPC85xx_PCI2_SIZE); + + early_read_config_word(hose, 0, 0, PCI_COMMAND, &temps); + temps |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + early_write_config_word(hose, 0, 0, PCI_COMMAND, temps); + early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); + + /* Disable all windows (except powar0 since its ignored) */ + pci->powar1 = 0; + pci->powar2 = 0; + pci->powar3 = 0; + pci->powar4 = 0; + pci->piwar1 = 0; + pci->piwar2 = 0; + pci->piwar3 = 0; + + /* Setup 512M Phys:PCI 1:1 outbound mem window @ 0xa0000000 */ + pci->potar1 = (MPC85XX_PCI2_LOWER_MEM >> 12) & 0x000fffff; + pci->potear1 = 0x00000000; + pci->powbar1 = (MPC85XX_PCI2_LOWER_MEM >> 12) & 0x000fffff; + pci->powar1 = 0x8004401c; /* Enable, Mem R/W, 512M */ + + /* Setup 16M outboud IO windows @ 0xe3000000 */ + pci->potar2 = 0x00000000; + pci->potear2 = 0x00000000; + pci->powbar2 = (MPC85XX_PCI2_IO_BASE >> 12) & 0x000fffff; + pci->powar2 = 0x80088017; /* Enable, IO R/W, 16M */ + + /* Setup 2G inbound Memory Window @ 0 */ + pci->pitar1 = 0x00000000; + pci->piwbar1 = 0x00000000; + pci->piwar1 = 0xa0f5501e; /* Enable, Prefetch, Local + Mem, Snoop R/W, 2G */ +} +#endif /* CONFIG_85xx_PCI2 */ + +void __init +mpc85xx_setup_hose(void) +{ + struct pci_controller *hose_a; +#ifdef CONFIG_85xx_PCI2 + struct pci_controller *hose_b; +#endif + bd_t *binfo = (bd_t *) __res; + + hose_a = pcibios_alloc_controller(); + + if (!hose_a) + return; + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mpc85xx_map_irq; + + hose_a->first_busno = 0; + hose_a->bus_offset = 0; + hose_a->last_busno = 0xff; + + setup_indirect_pci(hose_a, binfo->bi_immr_base + PCI1_CFG_ADDR_OFFSET, + binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET); + hose_a->set_cfg_type = 1; + + mpc85xx_setup_pci1(hose_a); + + hose_a->pci_mem_offset = MPC85XX_PCI1_MEM_OFFSET; + hose_a->mem_space.start = MPC85XX_PCI1_LOWER_MEM; + hose_a->mem_space.end = MPC85XX_PCI1_UPPER_MEM; + + hose_a->io_space.start = MPC85XX_PCI1_LOWER_IO; + hose_a->io_space.end = MPC85XX_PCI1_UPPER_IO; + hose_a->io_base_phys = MPC85XX_PCI1_IO_BASE; +#if CONFIG_85xx_PCI2 + isa_io_base = + (unsigned long) ioremap(MPC85XX_PCI1_IO_BASE, + MPC85XX_PCI1_IO_SIZE + + MPC85XX_PCI2_IO_SIZE); +#else + isa_io_base = + (unsigned long) ioremap(MPC85XX_PCI1_IO_BASE, + MPC85XX_PCI1_IO_SIZE); +#endif + hose_a->io_base_virt = (void *) isa_io_base; + + /* setup resources */ + pci_init_resource(&hose_a->mem_resources[0], + MPC85XX_PCI1_LOWER_MEM, + MPC85XX_PCI1_UPPER_MEM, + IORESOURCE_MEM, "PCI1 host bridge"); + + pci_init_resource(&hose_a->io_resource, + MPC85XX_PCI1_LOWER_IO, + MPC85XX_PCI1_UPPER_IO, + IORESOURCE_IO, "PCI1 host bridge"); + + ppc_md.pci_exclude_device = mpc85xx_exclude_device; + + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + +#if CONFIG_85xx_PCI2 + hose_b = pcibios_alloc_controller(); + + if (!hose_b) + return; + + hose_b->bus_offset = hose_a->last_busno + 1; + hose_b->first_busno = hose_a->last_busno + 1; + hose_b->last_busno = 0xff; + + setup_indirect_pci(hose_b, binfo->bi_immr_base + PCI2_CFG_ADDR_OFFSET, + binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET); + hose_b->set_cfg_type = 1; + + mpc85xx_setup_pci2(hose_b); + + hose_b->pci_mem_offset = MPC85XX_PCI2_MEM_OFFSET; + hose_b->mem_space.start = MPC85XX_PCI2_LOWER_MEM; + hose_b->mem_space.end = MPC85XX_PCI2_UPPER_MEM; + + hose_b->io_space.start = MPC85XX_PCI2_LOWER_IO; + hose_b->io_space.end = MPC85XX_PCI2_UPPER_IO; + hose_b->io_base_phys = MPC85XX_PCI2_IO_BASE; + hose_b->io_base_virt = (void *) isa_io_base + MPC85XX_PCI1_IO_SIZE; + + /* setup resources */ + pci_init_resource(&hose_b->mem_resources[0], + MPC85XX_PCI2_LOWER_MEM, + MPC85XX_PCI2_UPPER_MEM, + IORESOURCE_MEM, "PCI2 host bridge"); + + pci_init_resource(&hose_b->io_resource, + MPC85XX_PCI2_LOWER_IO, + MPC85XX_PCI2_UPPER_IO, + IORESOURCE_IO, "PCI2 host bridge"); + + hose_b->last_busno = pciauto_bus_scan(hose_b, hose_b->first_busno); +#endif + return; +} +#endif /* CONFIG_PCI */ + + diff -Nru a/arch/ppc/syslib/ppc85xx_setup.h b/arch/ppc/syslib/ppc85xx_setup.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/syslib/ppc85xx_setup.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,69 @@ +/* + * arch/ppc/syslib/ppc85xx_setup.h + * + * MPC85XX common board definitions + * + * Maintainer: Kumar Gala + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __PPC_SYSLIB_PPC85XX_SETUP_H +#define __PPC_SYSLIB_PPC85XX_SETUP_H + +#include +#include +#include +#include + +extern unsigned long mpc85xx_find_end_of_memory(void) __init; +extern void mpc85xx_calibrate_decr(void) __init; +extern void mpc85xx_early_serial_map(void) __init; +extern void mpc85xx_restart(char *cmd); +extern void mpc85xx_power_off(void); +extern void mpc85xx_halt(void); +extern void mpc85xx_setup_hose(void) __init; + +/* PCI config */ +#define PCI1_CFG_ADDR_OFFSET (0x8000) +#define PCI1_CFG_DATA_OFFSET (0x8004) + +#define PCI2_CFG_ADDR_OFFSET (0x9000) +#define PCI2_CFG_DATA_OFFSET (0x9004) + +/* Additional register for PCI-X configuration */ +#define PCIX_NEXT_CAP 0x60 +#define PCIX_CAP_ID 0x61 +#define PCIX_COMMAND 0x62 +#define PCIX_STATUS 0x64 + +/* Serial Config */ +#define MPC85XX_0_SERIAL (CCSRBAR + 0x4500) +#define MPC85XX_1_SERIAL (CCSRBAR + 0x4600) + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 2 +#endif + +#ifndef BASE_BAUD +#define BASE_BAUD 115200 +#endif + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, num, MPC85xx_IRQ_DUART, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: (u8 *)MPC85XX_##num##_SERIAL, \ + io_type: SERIAL_IO_MEM}, + +/* Offset of CPM register space */ +#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET) + +#endif /* __PPC_SYSLIB_PPC85XX_SETUP_H */ diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig --- a/arch/ppc64/Kconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/Kconfig 2004-06-26 17:09:18 -07:00 @@ -198,7 +198,6 @@ config PREEMPT bool "Preemptible Kernel" - depends on BROKEN help This option reduces the latency of the kernel when reacting to real-time or interactive events by allowing a low priority process to diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile --- a/arch/ppc64/kernel/Makefile 2004-06-26 17:09:21 -07:00 +++ b/arch/ppc64/kernel/Makefile 2004-06-26 17:09:21 -07:00 @@ -56,4 +56,6 @@ obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o endif +obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o + CFLAGS_ioctl32.o += -Ifs/ diff -Nru a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c --- a/arch/ppc64/kernel/align.c 2004-06-26 17:09:21 -07:00 +++ b/arch/ppc64/kernel/align.c 2004-06-26 17:09:21 -07:00 @@ -22,8 +22,6 @@ #include #include -void disable_kernel_fp(void); /* asm function from head.S */ - struct aligninfo { unsigned char len; unsigned char flags; @@ -280,8 +278,11 @@ } /* Force the fprs into the save area so we can reference them */ - if ((flags & F) && (regs->msr & MSR_FP)) - giveup_fpu(current); + if (flags & F) { + if (!user_mode(regs)) + return 0; + flush_fp_to_thread(current); + } /* If we are loading, get the data from user space */ if (flags & LD) { @@ -310,9 +311,11 @@ if (flags & F) { if (nb == 4) { /* Doing stfs, have to convert to single */ + preempt_disable(); enable_kernel_fp(); cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread.fpscr); disable_kernel_fp(); + preempt_enable(); } else data.dd = current->thread.fpr[reg]; @@ -344,9 +347,11 @@ if (flags & F) { if (nb == 4) { /* Doing lfs, have to convert to double */ + preempt_disable(); enable_kernel_fp(); cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread.fpscr); disable_kernel_fp(); + preempt_enable(); } else current->thread.fpr[reg] = data.dd; diff -Nru a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c --- a/arch/ppc64/kernel/asm-offsets.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/asm-offsets.c 2004-06-26 17:09:19 -07:00 @@ -48,6 +48,8 @@ DEFINE(THREAD_SHIFT, THREAD_SHIFT); DEFINE(THREAD_SIZE, THREAD_SIZE); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); + DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); /* task_struct->thread */ DEFINE(THREAD, offsetof(struct task_struct, thread)); @@ -99,7 +101,10 @@ DEFINE(PACALPPACA, offsetof(struct paca_struct, xLpPaca)); DEFINE(LPPACA, offsetof(struct paca_struct, xLpPaca)); DEFINE(PACAREGSAV, offsetof(struct paca_struct, xRegSav)); - DEFINE(PACAEXC, offsetof(struct paca_struct, exception_stack)); + DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); + DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); + DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); + DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi)); DEFINE(PACAGUARD, offsetof(struct paca_struct, guard)); DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0)); DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1)); @@ -136,6 +141,10 @@ DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7])); DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8])); DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9])); + DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10])); + DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11])); + DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12])); + DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13])); DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20])); DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21])); DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22])); @@ -154,7 +163,7 @@ DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3)); DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result)); - DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); + DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe)); /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */ diff -Nru a/arch/ppc64/kernel/bitops.c b/arch/ppc64/kernel/bitops.c --- a/arch/ppc64/kernel/bitops.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/bitops.c 2004-06-26 17:09:19 -07:00 @@ -7,10 +7,10 @@ #include #include -unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> 6); unsigned long result = offset & ~63UL; unsigned long tmp; @@ -48,10 +48,10 @@ EXPORT_SYMBOL(find_next_zero_bit); -unsigned long find_next_bit(unsigned long *addr, unsigned long size, +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> 6); unsigned long result = offset & ~63UL; unsigned long tmp; @@ -106,10 +106,10 @@ return rc; } -unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, +unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - unsigned int *p = ((unsigned int *)addr) + (offset >> 5); + const unsigned int *p = ((const unsigned int *)addr) + (offset >> 5); unsigned int result = offset & ~31; unsigned int tmp; diff -Nru a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c --- a/arch/ppc64/kernel/eeh.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/eeh.c 2004-06-26 17:09:19 -07:00 @@ -365,7 +365,8 @@ unsigned long addr; struct pci_dev *dev; struct device_node *dn; - unsigned long ret, rets[2]; + unsigned long ret; + int rets[2]; static spinlock_t lock = SPIN_LOCK_UNLOCKED; /* dont want this on the stack */ static unsigned char slot_err_buf[RTAS_ERROR_LOG_MAX]; @@ -444,11 +445,11 @@ * can use it here. */ if (panic_on_oops) { - panic("EEH: MMIO failure (%ld) on device:%s %s\n", + panic("EEH: MMIO failure (%d) on device:%s %s\n", rets[0], pci_name(dev), pci_pretty_name(dev)); } else { __get_cpu_var(ignored_failures)++; - printk(KERN_INFO "EEH: MMIO failure (%ld) on device:%s %s\n", + printk(KERN_INFO "EEH: MMIO failure (%d) on device:%s %s\n", rets[0], pci_name(dev), pci_pretty_name(dev)); } } else { diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S --- a/arch/ppc64/kernel/entry.S 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc64/kernel/entry.S 2004-06-26 17:09:15 -07:00 @@ -35,15 +35,9 @@ #define DO_SOFT_DISABLE #endif -#undef SHOW_SYSCALLS -#undef SHOW_SYSCALLS_TASK - -#ifdef SHOW_SYSCALLS_TASK - .data -show_syscalls_task: - .long -1 -#endif - +/* + * System calls. + */ .section ".toc","aw" .SYS_CALL_TABLE: .tc .sys_call_table[TC],.sys_call_table @@ -51,107 +45,175 @@ .SYS_CALL_TABLE32: .tc .sys_call_table32[TC],.sys_call_table32 +/* This value is used to mark exception frames on the stack. */ +exception_marker: + .tc ID_72656773_68657265[TC],0x7265677368657265 + .section ".text" - .align 3 + .align 7 -/* - * Handle a system call. - */ -_GLOBAL(DoSyscall) +#undef SHOW_SYSCALLS + + .globl SystemCall_common +SystemCall_common: + andi. r10,r12,MSR_PR + mr r10,r1 + addi r1,r1,-INT_FRAME_SIZE + beq- 1f + ld r1,PACAKSAVE(r13) +1: std r10,0(r1) + std r11,_NIP(r1) + std r12,_MSR(r1) + std r0,GPR0(r1) + std r10,GPR1(r1) + std r2,GPR2(r1) + std r3,GPR3(r1) + std r4,GPR4(r1) + std r5,GPR5(r1) + std r6,GPR6(r1) + std r7,GPR7(r1) + std r8,GPR8(r1) + li r11,0 + std r11,GPR9(r1) + std r11,GPR10(r1) + std r11,GPR11(r1) + std r11,GPR12(r1) + std r9,GPR13(r1) + crclr so + mfcr r9 + mflr r10 + li r11,0xc01 + std r9,_CCR(r1) + std r10,_LINK(r1) + std r11,_TRAP(r1) + mfxer r9 + mfctr r10 + std r9,_XER(r1) + std r10,_CTR(r1) std r3,ORIG_GPR3(r1) - ld r11,_CCR(r1) /* Clear SO bit in CR */ - lis r10,0x1000 - andc r11,r11,r10 - std r11,_CCR(r1) + ld r2,PACATOC(r13) + addi r9,r1,STACK_FRAME_OVERHEAD + ld r11,exception_marker@toc(r2) + std r11,-16(r9) /* "regshere" marker */ +#ifdef CONFIG_PPC_ISERIES + /* Hack for handling interrupts when soft-enabling on iSeries */ + cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ + andi. r10,r12,MSR_PR /* from kernel */ + crand 4*cr0+eq,4*cr1+eq,4*cr0+eq + beq HardwareInterrupt_entry + lbz r10,PACAPROCENABLED(r13) + std r10,SOFTE(r1) +#endif + mfmsr r11 + ori r11,r11,MSR_EE + mtmsrd r11,1 + #ifdef SHOW_SYSCALLS -#ifdef SHOW_SYSCALLS_TASK - LOADBASE(r31,show_syscalls_task) - ld r31,show_syscalls_task@l(r31) - ld r10,PACACURRENT(r13) - cmp 0,r10,r31 - bne 1f + bl .do_show_syscall + REST_GPR(0,r1) + REST_4GPRS(3,r1) + REST_2GPRS(7,r1) + addi r9,r1,STACK_FRAME_OVERHEAD #endif - LOADADDR(r3,7f) - ld r4,GPR0(r1) - ld r5,GPR3(r1) - ld r6,GPR4(r1) - ld r7,GPR5(r1) - ld r8,GPR6(r1) - ld r9,GPR7(r1) - bl .printk - LOADADDR(r3,77f) - ld r4,GPR8(r1) - ld r5,GPR9(r1) - ld r6, PACACURRENT(r13) - bl .printk - ld r0,GPR0(r1) - ld r3,GPR3(r1) - ld r4,GPR4(r1) - ld r5,GPR5(r1) - ld r6,GPR6(r1) - ld r7,GPR7(r1) - ld r8,GPR8(r1) -1: -#endif /* SHOW_SYSCALLS */ - clrrdi r10,r1,THREAD_SHIFT - ld r10,TI_FLAGS(r10) + clrrdi r11,r1,THREAD_SHIFT + li r12,0 + ld r10,TI_FLAGS(r11) + stb r12,TI_SC_NOERR(r11) andi. r11,r10,_TIF_SYSCALL_T_OR_A - bne- 50f + bne- syscall_dotrace +syscall_dotrace_cont: cmpli 0,r0,NR_syscalls - bge- 66f + bge- syscall_enosys + +system_call: /* label this so stack traces look sane */ /* * Need to vector to 32 Bit or default sys_call_table here, * based on caller's run-mode / personality. */ - andi. r11,r10,_TIF_32BIT + ld r11,.SYS_CALL_TABLE@toc(2) + andi. r10,r10,_TIF_32BIT beq- 15f - ld r10,.SYS_CALL_TABLE32@toc(2) -/* - * We now zero extend all six arguments (r3 - r8), the compatibility - * layer assumes this. - */ + ld r11,.SYS_CALL_TABLE32@toc(2) clrldi r3,r3,32 clrldi r4,r4,32 clrldi r5,r5,32 clrldi r6,r6,32 clrldi r7,r7,32 clrldi r8,r8,32 - b 17f 15: - ld r10,.SYS_CALL_TABLE@toc(2) -17: slwi r0,r0,3 - ldx r10,r10,r0 /* Fetch system call handler [ptr] */ + slwi r0,r0,3 + ldx r10,r11,r0 /* Fetch system call handler [ptr] */ mtlr r10 - addi r9,r1,STACK_FRAME_OVERHEAD blrl /* Call handler */ -_GLOBAL(ret_from_syscall_1) - std r3,RESULT(r1) /* Save result */ + +syscall_exit: #ifdef SHOW_SYSCALLS -#ifdef SHOW_SYSCALLS_TASK - ld r10, PACACURRENT(13) - cmp 0,r10,r31 - bne 91f -#endif - mr r4,r3 - LOADADDR(r3,79f) - bl .printk - ld r3,RESULT(r1) -91: + std r3,GPR3(r1) + bl .do_show_syscall_exit + ld r3,GPR3(r1) #endif + std r3,RESULT(r1) + ld r5,_CCR(r1) li r10,-_LAST_ERRNO - cmpld 0,r3,r10 - blt 30f + cmpld r3,r10 + clrrdi r12,r1,THREAD_SHIFT + bge- syscall_error +syscall_error_cont: + + /* check for syscall tracing or audit */ + ld r9,TI_FLAGS(r12) + andi. r0,r9,_TIF_SYSCALL_T_OR_A + bne- syscall_exit_trace +syscall_exit_trace_cont: + + /* disable interrupts so current_thread_info()->flags can't change, + and so that we don't get interrupted after loading SRR0/1. */ + ld r8,_MSR(r1) + andi. r10,r8,MSR_RI + beq- unrecov_restore + mfmsr r10 + rldicl r10,r10,48,1 + rotldi r10,r10,16 + mtmsrd r10,1 + ld r9,TI_FLAGS(r12) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) + bne- syscall_exit_work + ld r7,_NIP(r1) + stdcx. r0,0,r1 /* to clear the reservation */ + andi. r6,r8,MSR_PR + ld r4,_LINK(r1) + beq 1f /* only restore r13 if */ + ld r13,GPR13(r1) /* returning to usermode */ +1: ld r2,GPR2(r1) + ld r1,GPR1(r1) + li r12,MSR_RI + andc r10,r10,r12 + mtmsrd r10,1 /* clear MSR.RI */ + mtlr r4 + mtcr r5 + mtspr SRR0,r7 + mtspr SRR1,r8 + rfid + +syscall_enosys: + li r3,-ENOSYS + std r3,RESULT(r1) + clrrdi r12,r1,THREAD_SHIFT + ld r5,_CCR(r1) + +syscall_error: + lbz r11,TI_SC_NOERR(r12) + cmpi 0,r11,0 + bne- syscall_error_cont neg r3,r3 -22: ld r10,_CCR(r1) /* Set SO bit in CR */ - oris r10,r10,0x1000 - std r10,_CCR(r1) -30: std r3,GPR3(r1) /* Update return value */ - b .ret_from_except -66: li r3,ENOSYS - b 22b + oris r5,r5,0x1000 /* Set SO bit in CR */ + std r5,_CCR(r1) + b syscall_error_cont /* Traced system call support */ -50: addi r3,r1,STACK_FRAME_OVERHEAD +syscall_dotrace: + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD bl .do_syscall_trace_enter ld r0,GPR0(r1) /* Restore original registers */ ld r3,GPR3(r1) @@ -160,65 +222,82 @@ ld r6,GPR6(r1) ld r7,GPR7(r1) ld r8,GPR8(r1) - /* XXX check this - Anton */ - ld r9,GPR9(r1) - cmpli 0,r0,NR_syscalls - bge- 66f -/* - * Need to vector to 32 Bit or default sys_call_table here, - * based on caller's run-mode / personality. - */ + addi r9,r1,STACK_FRAME_OVERHEAD clrrdi r10,r1,THREAD_SHIFT ld r10,TI_FLAGS(r10) - andi. r11,r10,_TIF_32BIT - beq- 55f - ld r10,.SYS_CALL_TABLE32@toc(2) + b syscall_dotrace_cont + +syscall_exit_trace: + std r3,GPR3(r1) + bl .save_nvgprs + bl .do_syscall_trace_leave + REST_NVGPRS(r1) + ld r3,GPR3(r1) + ld r5,_CCR(r1) + clrrdi r12,r1,THREAD_SHIFT + b syscall_exit_trace_cont + +/* Stuff to do on exit from a system call. */ +syscall_exit_work: + std r3,GPR3(r1) + std r5,_CCR(r1) + b .ret_from_except_lite + +/* Save non-volatile GPRs, if not already saved. */ +_GLOBAL(save_nvgprs) + ld r11,_TRAP(r1) + andi. r0,r11,1 + beqlr- + SAVE_NVGPRS(r1) + clrrdi r0,r11,1 + std r0,_TRAP(r1) + blr + /* - * We now zero extend all six arguments (r3 - r8), the compatibility - * layer assumes this. + * The sigsuspend and rt_sigsuspend system calls can call do_signal + * and thus put the process into the stopped state where we might + * want to examine its user state with ptrace. Therefore we need + * to save all the nonvolatile registers (r14 - r31) before calling + * the C code. Similarly, fork, vfork and clone need the full + * register state on the stack so that it can be copied to the child. */ - clrldi r3,r3,32 - clrldi r4,r4,32 - clrldi r5,r5,32 - clrldi r6,r6,32 - clrldi r7,r7,32 - clrldi r8,r8,32 - b 57f -55: - ld r10,.SYS_CALL_TABLE@toc(2) -57: - slwi r0,r0,3 - ldx r10,r10,r0 /* Fetch system call handler [ptr] */ - mtlr r10 - addi r9,r1,STACK_FRAME_OVERHEAD - blrl /* Call handler */ -_GLOBAL(ret_from_syscall_2) - std r3,RESULT(r1) /* Save result */ - li r10,-_LAST_ERRNO - cmpld 0,r3,r10 - blt 60f - neg r3,r3 -57: ld r10,_CCR(r1) /* Set SO bit in CR */ - oris r10,r10,0x1000 - std r10,_CCR(r1) -60: std r3,GPR3(r1) /* Update return value */ - bl .do_syscall_trace_leave - b .ret_from_except -66: li r3,ENOSYS - b 57b -#ifdef SHOW_SYSCALLS -7: .string "syscall %d(%x, %x, %x, %x, %x, " -77: .string "%x, %x), current=%p\n" -79: .string " -> %x\n" - .align 2,0 -#endif +_GLOBAL(ppc32_sigsuspend) + bl .save_nvgprs + bl .sys32_sigsuspend + b syscall_exit + +_GLOBAL(ppc64_rt_sigsuspend) + bl .save_nvgprs + bl .sys_rt_sigsuspend + b syscall_exit + +_GLOBAL(ppc32_rt_sigsuspend) + bl .save_nvgprs + bl .sys32_rt_sigsuspend + b syscall_exit + +_GLOBAL(ppc_fork) + bl .save_nvgprs + bl .sys_fork + b syscall_exit + +_GLOBAL(ppc_vfork) + bl .save_nvgprs + bl .sys_vfork + b syscall_exit + +_GLOBAL(ppc_clone) + bl .save_nvgprs + bl .sys_clone + b syscall_exit - _GLOBAL(ppc32_swapcontext) + bl .save_nvgprs bl .sys32_swapcontext b 80f _GLOBAL(ppc64_swapcontext) + bl .save_nvgprs bl .sys_swapcontext b 80f @@ -233,17 +312,20 @@ _GLOBAL(ppc64_rt_sigreturn) bl .sys_rt_sigreturn -80: clrrdi r4,r1,THREAD_SHIFT +80: cmpdi 0,r3,0 + blt syscall_exit + clrrdi r4,r1,THREAD_SHIFT ld r4,TI_FLAGS(r4) andi. r4,r4,_TIF_SYSCALL_T_OR_A - bne- 81f - cmpi 0,r3,0 - bge .ret_from_except - b .ret_from_syscall_1 -81: cmpi 0,r3,0 - blt .ret_from_syscall_2 + beq+ 81f bl .do_syscall_trace_leave - b .ret_from_except +81: b .ret_from_except + +_GLOBAL(ret_from_fork) + bl .schedule_tail + REST_NVGPRS(r1) + li r3,0 + b syscall_exit /* * This routine switches between two different tasks. The process @@ -263,6 +345,7 @@ * The code which creates the new task context is in 'copy_thread' * in arch/ppc64/kernel/process.c */ + .align 7 _GLOBAL(_switch) mflr r0 std r0,16(r1) @@ -315,7 +398,10 @@ 2: END_FTR_SECTION_IFSET(CPU_FTR_SLB) clrrdi r7,r8,THREAD_SHIFT /* base of new stack */ - addi r7,r7,THREAD_SIZE-INT_FRAME_SIZE + /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE + because we don't need to leave the 288-byte ABI gap at the + top of the kernel stack. */ + addi r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE mr r1,r8 /* start using new stack pointer */ std r7,PACAKSAVE(r13) @@ -350,60 +436,56 @@ addi r1,r1,SWITCH_FRAME_SIZE blr -_GLOBAL(ret_from_fork) - bl .schedule_tail - clrrdi r4,r1,THREAD_SHIFT - ld r4,TI_FLAGS(r4) - andi. r4,r4,_TIF_SYSCALL_T_OR_A - beq+ .ret_from_except - bl .do_syscall_trace_leave - b .ret_from_except - + .align 7 _GLOBAL(ret_from_except) + ld r11,_TRAP(r1) + andi. r0,r11,1 + bne .ret_from_except_lite + REST_NVGPRS(r1) + +_GLOBAL(ret_from_except_lite) /* * Disable interrupts so that current_thread_info()->flags * can't change between when we test it and when we return * from the interrupt. */ mfmsr r10 /* Get current interrupt state */ - li r4,0 - ori r4,r4,MSR_EE - andc r9,r10,r4 /* clear MSR_EE */ + rldicl r9,r10,48,1 /* clear MSR_EE */ + rotldi r9,r9,16 mtmsrd r9,1 /* Update machine state */ +#ifdef CONFIG_PREEMPT + clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ + li r0,_TIF_NEED_RESCHED /* bits to check */ + ld r3,_MSR(r1) + ld r4,TI_FLAGS(r9) + /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ + rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING + and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */ + bne do_work + +#else /* !CONFIG_PREEMPT */ ld r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR beq restore /* if not, just restore regs and return */ /* Check current_thread_info()->flags */ - clrrdi r3,r1,THREAD_SHIFT - ld r3,TI_FLAGS(r3) - andi. r0,r3,_TIF_USER_WORK_MASK + clrrdi r9,r1,THREAD_SHIFT + ld r4,TI_FLAGS(r9) + andi. r0,r4,_TIF_USER_WORK_MASK bne do_work - - addi r0,r1,INT_FRAME_SIZE /* size of frame */ - ld r4,PACACURRENT(r13) - std r0,THREAD+KSP(r4) /* save kernel stack pointer */ - - /* - * r13 is our per cpu area, only restore it if we are returning to - * userspace - */ - REST_GPR(13,r1) +#endif restore: #ifdef CONFIG_PPC_ISERIES ld r5,SOFTE(r1) - mfspr r4,SPRG3 /* get paca address */ cmpdi 0,r5,0 beq 4f /* Check for pending interrupts (iSeries) */ - /* this is CHECKANYINT except that we already have the paca address */ - ld r3,PACALPPACA+LPPACAANYINT(r4) + ld r3,PACALPPACA+LPPACAANYINT(r13) cmpdi r3,0 beq+ 4f /* skip do_IRQ if no interrupts */ - mfspr r13,SPRG3 /* get paca pointer back */ li r3,0 stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */ mtmsrd r10 /* hard-enable again */ @@ -411,13 +493,22 @@ bl .do_IRQ b .ret_from_except /* loop back and handle more */ -4: stb r5,PACAPROCENABLED(r4) +4: stb r5,PACAPROCENABLED(r13) #endif ld r3,_MSR(r1) - andi. r3,r3,MSR_RI + andi. r0,r3,MSR_RI beq- unrecov_restore + andi. r0,r3,MSR_PR + + /* + * r13 is our per cpu area, only restore it if we are returning to + * userspace + */ + beq 1f + REST_GPR(13, r1) +1: ld r3,_CTR(r1) ld r0,_LINK(r1) mtctr r3 @@ -426,8 +517,6 @@ mtspr XER,r3 REST_8GPRS(5, r1) - REST_10GPRS(14, r1) - REST_8GPRS(24, r1) stdcx. r0,0,r1 /* to clear the reservation */ @@ -451,26 +540,62 @@ ld r1,GPR1(r1) rfid + b . -/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */ +/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */ do_work: +#ifdef CONFIG_PREEMPT + andi. r0,r3,MSR_PR /* Returning to user mode? */ + bne user_work + /* Check that preempt_count() == 0 and interrupts are enabled */ + lwz r8,TI_PREEMPT(r9) + cmpwi cr1,r8,0 +#ifdef CONFIG_PPC_ISERIES + ld r0,SOFTE(r1) + cmpdi r0,0 +#else + andi. r0,r3,MSR_EE +#endif + crandc eq,cr1*4+eq,eq + bne restore + /* here we are preempting the current task */ +1: lis r0,PREEMPT_ACTIVE@h + stw r0,TI_PREEMPT(r9) +#ifdef CONFIG_PPC_ISERIES + li r0,1 + stb r0,PACAPROCENABLED(r13) +#endif + mtmsrd r10,1 /* reenable interrupts */ + bl .schedule + mfmsr r10 + clrrdi r9,r1,THREAD_SHIFT + rldicl r10,r10,48,1 /* disable interrupts again */ + li r0,0 + rotldi r10,r10,16 + mtmsrd r10,1 + ld r4,TI_FLAGS(r9) + andi. r0,r4,_TIF_NEED_RESCHED + bne 1b + stw r0,TI_PREEMPT(r9) + b restore + +user_work: +#endif /* Enable interrupts */ mtmsrd r10,1 - andi. r0,r3,_TIF_NEED_RESCHED + andi. r0,r4,_TIF_NEED_RESCHED beq 1f bl .schedule - b .ret_from_except + b .ret_from_except_lite -1: andi. r0,r3,_TIF_SIGPENDING - beq .ret_from_except +1: bl .save_nvgprs li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD bl .do_signal b .ret_from_except unrecov_restore: - mfspr r13,SPRG3 addi r3,r1,STACK_FRAME_OVERHEAD bl .unrecoverable_exception b unrecov_restore @@ -488,7 +613,7 @@ mflr r0 std r0,16(r1) stdu r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */ - + /* Because RTAS is running in 32b mode, it clobbers the high order half * of all registers that it saves. We therefore save those registers * RTAS might touch to the stack. (r0, r3-r13 are caller saved) diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S --- a/arch/ppc64/kernel/head.S 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/head.S 2004-06-26 17:09:18 -07:00 @@ -35,25 +35,17 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE #endif -/* copy saved SOFTE bit or EE bit from saved MSR depending - * if we are doing soft-disable or not - */ -#ifdef DO_SOFT_DISABLE -#define DO_COPY_EE() ld r20,SOFTE(r1) -#else -#define DO_COPY_EE() rldicl r20,r23,49,63 -#endif - /* * hcall interface to pSeries LPAR */ -#define HVSC .long 0x44000022 -#define H_SET_ASR 0x30 +#define HVSC .long 0x44000022 +#define H_SET_ASR 0x30 /* * We layout physical memory as follows: @@ -62,19 +54,19 @@ * 0x3000 - 0x3fff : Interrupt support * 0x4000 - 0x4fff : NACA * 0x5000 - 0x5fff : SystemCfg - * 0x6000 : iSeries and common interrupt prologs + * 0x6000 : iSeries and common interrupt prologs * 0x9000 - 0x9fff : Initial segment table */ /* * SPRG Usage * - * Register Definition + * Register Definition * - * SPRG0 reserved for hypervisor - * SPRG1 temp - used to save gpr - * SPRG2 temp - used to save gpr - * SPRG3 virt addr of paca + * SPRG0 reserved for hypervisor + * SPRG1 temp - used to save gpr + * SPRG2 temp - used to save gpr + * SPRG3 virt addr of paca */ /* @@ -115,7 +107,7 @@ * to the pidhash table (also used by the debugger) */ .llong msChunks-KERNELBASE - .llong 0 /* pidhash-KERNELBASE SFRXXX */ + .llong 0 /* pidhash-KERNELBASE SFRXXX */ /* Offset 0x38 - Pointer to start of embedded System.map */ .globl embedded_sysmap_start @@ -130,13 +122,13 @@ /* Secondary processors spin on this value until it goes to 1. */ .globl __secondary_hold_spinloop __secondary_hold_spinloop: - .llong 0x0 + .llong 0x0 /* Secondary processors write this value with their cpu # */ - /* after they enter the spin loop immediately below. */ - .globl __secondary_hold_acknowledge + /* after they enter the spin loop immediately below. */ + .globl __secondary_hold_acknowledge __secondary_hold_acknowledge: - .llong 0x0 + .llong 0x0 . = 0x60 /* @@ -152,36 +144,43 @@ mtmsrd r24 /* RI on */ /* Grab our linux cpu number */ - mr r24,r3 + mr r24,r3 /* Tell the master cpu we're here */ /* Relocation is off & we are located at an address less */ /* than 0x100, so only need to grab low order offset. */ - std r24,__secondary_hold_acknowledge@l(0) + std r24,__secondary_hold_acknowledge@l(0) sync /* All secondary cpu's wait here until told to start. */ -100: ld r4,__secondary_hold_spinloop@l(0) - cmpdi 0,r4,1 - bne 100b +100: ld r4,__secondary_hold_spinloop@l(0) + cmpdi 0,r4,1 + bne 100b #ifdef CONFIG_HMT b .hmt_init #else #ifdef CONFIG_SMP - mr r3,r24 - b .pseries_secondary_smp_init + mr r3,r24 + b .pseries_secondary_smp_init #else BUG_OPCODE #endif #endif #endif +/* This value is used to mark exception frames on the stack. */ + .section ".toc","aw" +exception_marker: + .tc ID_72656773_68657265[TC],0x7265677368657265 + .text + /* * The following macros define the code that appears as * the prologue to each of the exception handlers. They * are split into two parts to allow a single kernel binary - * to be used for pSeries, and iSeries. + * to be used for pSeries and iSeries. + * LOL. One day... - paulus */ /* @@ -194,81 +193,55 @@ * This is the start of the interrupt handlers for pSeries * This code runs with relocation off. */ -#define EX_SRR0 0 -#define EX_SRR1 8 -#define EX_R20 16 -#define EX_R21 24 -#define EX_R22 32 -#define EX_R23 40 +#define EX_R9 0 +#define EX_R10 8 +#define EX_R11 16 +#define EX_R12 24 +#define EX_R13 32 +#define EX_SRR0 40 #define EX_DAR 48 #define EX_DSISR 56 -#define EX_CCR 60 -#define EX_TRAP 60 +#define EX_CCR 60 -#define EXCEPTION_PROLOG_PSERIES(n,label) \ - mtspr SPRG2,r20; /* use SPRG2 as scratch reg */ \ - mtspr SPRG1,r21; /* save r21 */ \ - mfspr r20,SPRG3; /* get paca virt addr */ \ - ld r21,PACAEXCSP(r20); /* get exception stack ptr */ \ - addi r21,r21,EXC_FRAME_SIZE; /* make exception frame */ \ - std r22,EX_R22(r21); /* Save r22 in exc. frame */ \ - li r22,n; /* Save the ex # in exc. frame*/ \ - stw r22,EX_TRAP(r21); /* */ \ - std r23,EX_R23(r21); /* Save r23 in exc. frame */ \ - mfspr r22,SRR0; /* EA of interrupted instr */ \ - std r22,EX_SRR0(r21); /* Save SRR0 in exc. frame */ \ - mfspr r23,SRR1; /* machine state at interrupt */ \ - std r23,EX_SRR1(r21); /* Save SRR1 in exc. frame */ \ - \ - mfspr r23,DAR; /* Save DAR in exc. frame */ \ - std r23,EX_DAR(r21); \ - mfspr r23,DSISR; /* Save DSISR in exc. frame */ \ - stw r23,EX_DSISR(r21); \ - mfspr r23,SPRG2; /* Save r20 in exc. frame */ \ - std r23,EX_R20(r21); \ - \ - clrrdi r22,r20,60; /* Get 0xc part of the vaddr */ \ - ori r22,r22,(label)@l; /* add in the vaddr offset */ \ - /* assumes *_common < 16b */ \ - mfmsr r23; \ - rotldi r23,r23,4; \ - ori r23,r23,0x32B; /* Set IR, DR, RI, SF, ISF, HV*/ \ - rotldi r23,r23,60; /* for generic handlers */ \ - mtspr SRR0,r22; \ - mtspr SRR1,r23; \ - mfcr r23; /* save CR in r23 */ \ +#define EXCEPTION_PROLOG_PSERIES(area, label) \ + mfspr r13,SPRG3; /* get paca address into r13 */ \ + std r9,area+EX_R9(r13); /* save r9 - r12 */ \ + std r10,area+EX_R10(r13); \ + std r11,area+EX_R11(r13); \ + std r12,area+EX_R12(r13); \ + mfspr r9,SPRG1; \ + std r9,area+EX_R13(r13); \ + mfcr r9; \ + clrrdi r12,r13,32; /* get high part of &label */ \ + mfmsr r10; \ + mfspr r11,SRR0; /* save SRR0 */ \ + ori r12,r12,(label)@l; /* virt addr of handler */ \ + ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ + mtspr SRR0,r12; \ + mfspr r12,SRR1; /* and SRR1 */ \ + mtspr SRR1,r10; \ rfid /* * This is the start of the interrupt handlers for iSeries * This code runs with relocation on. */ -#define EXCEPTION_PROLOG_ISERIES(n) \ - mtspr SPRG2,r20; /* use SPRG2 as scratch reg */ \ - mtspr SPRG1,r21; /* save r21 */ \ - mfspr r20,SPRG3; /* get paca */ \ - ld r21,PACAEXCSP(r20); /* get exception stack ptr */ \ - addi r21,r21,EXC_FRAME_SIZE; /* make exception frame */ \ - std r22,EX_R22(r21); /* save r22 on exception frame */ \ - li r22,n; /* Save the ex # in exc. frame */ \ - stw r22,EX_TRAP(r21); /* */ \ - std r23,EX_R23(r21); /* Save r23 in exc. frame */ \ - ld r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */ \ - std r22,EX_SRR0(r21); /* save SRR0 in exc. frame */ \ - ld r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */ \ - std r23,EX_SRR1(r21); /* save SRR1 in exc. frame */ \ - \ - mfspr r23,DAR; /* Save DAR in exc. frame */ \ - std r23,EX_DAR(r21); \ - mfspr r23,DSISR; /* Save DSISR in exc. frame */ \ - stw r23,EX_DSISR(r21); \ - mfspr r23,SPRG2; /* Save r20 in exc. frame */ \ - std r23,EX_R20(r21); \ - \ - mfmsr r22; /* set MSR.RI */ \ - ori r22,r22,MSR_RI; \ - mtmsrd r22,1; \ - mfcr r23; /* save CR in r23 */ +#define EXCEPTION_PROLOG_ISERIES_1(area) \ + mfspr r13,SPRG3; /* get paca address into r13 */ \ + std r9,area+EX_R9(r13); /* save r9 - r12 */ \ + std r10,area+EX_R10(r13); \ + std r11,area+EX_R11(r13); \ + std r12,area+EX_R12(r13); \ + mfspr r9,SPRG1; \ + std r9,area+EX_R13(r13); \ + mfcr r9 + +#define EXCEPTION_PROLOG_ISERIES_2 \ + mfmsr r10; \ + ld r11,LPPACA+LPPACASRR0(r13); \ + ld r12,LPPACA+LPPACASRR1(r13); \ + ori r10,r10,MSR_RI; \ + mtmsrd r10,1 /* * The common exception prolog is used for all except a few exceptions @@ -276,106 +249,153 @@ * to take another exception from the point where we first touch the * kernel stack onwards. * - * On entry r20 points to the paca and r21 points to the exception - * frame on entry, r23 contains the saved CR, and relocation is on. - */ -#define EXCEPTION_PROLOG_COMMON \ - mfspr r22,SPRG1; /* Save r21 in exc. frame */ \ - std r22,EX_R21(r21); \ - std r21,PACAEXCSP(r20); /* update exception stack ptr */ \ - ld r22,EX_SRR1(r21); /* Get SRR1 from exc. frame */ \ - andi. r22,r22,MSR_PR; /* Set CR for later branch */ \ - mr r22,r1; /* Save r1 */ \ - subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ - beq- 1f; \ - ld r1,PACAKSAVE(r20); /* kernel stack to use */ \ -1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ - bge cr1,bad_stack; /* abort if it is */ \ - std r22,GPR1(r1); /* save r1 in stackframe */ \ - std r22,0(r1); /* make stack chain pointer */ \ - std r23,_CCR(r1); /* save CR in stackframe */ \ - ld r22,EX_R20(r21); /* move r20 to stackframe */ \ - std r22,GPR20(r1); \ - ld r23,EX_R21(r21); /* move r21 to stackframe */ \ - std r23,GPR21(r1); \ - ld r22,EX_R22(r21); /* move r22 to stackframe */ \ - std r22,GPR22(r1); \ - ld r23,EX_R23(r21); /* move r23 to stackframe */ \ - std r23,GPR23(r1); \ - mflr r22; /* save LR in stackframe */ \ - std r22,_LINK(r1); \ - mfctr r23; /* save CTR in stackframe */ \ - std r23,_CTR(r1); \ - mfspr r22,XER; /* save XER in stackframe */ \ - std r22,_XER(r1); \ - ld r23,EX_DAR(r21); /* move DAR to stackframe */ \ - std r23,_DAR(r1); \ - lwz r22,EX_DSISR(r21); /* move DSISR to stackframe */ \ - std r22,_DSISR(r1); \ - lbz r22,PACAPROCENABLED(r20); \ - std r22,SOFTE(r1); \ - ld r22,EX_SRR0(r21); /* get SRR0 from exc. frame */ \ - ld r23,EX_SRR1(r21); /* get SRR1 from exc. frame */ \ - addi r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame */ \ - std r21,PACAEXCSP(r20); \ - SAVE_GPR(0, r1); /* save r0 in stackframe */ \ - SAVE_8GPRS(2, r1); /* save r2 - r13 in stackframe */ \ - SAVE_4GPRS(10, r1); \ - ld r2,PACATOC(r20); \ - mr r13,r20 - -/* - * Note: code which follows this uses cr0.eq (set if from kernel), - * r1, r22 (SRR0), and r23 (SRR1). - */ + * On entry r13 points to the paca, r9-r13 are saved in the paca, + * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and + * SRR1, and relocation is on. + */ +#define EXCEPTION_PROLOG_COMMON(n, area) \ + andi. r10,r12,MSR_PR; /* See if coming from user */ \ + mr r10,r1; /* Save r1 */ \ + subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ + beq- 1f; \ + ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ +1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ + bge- cr1,bad_stack; /* abort if it is */ \ + std r9,_CCR(r1); /* save CR in stackframe */ \ + std r11,_NIP(r1); /* save SRR0 in stackframe */ \ + std r12,_MSR(r1); /* save SRR1 in stackframe */ \ + std r10,0(r1); /* make stack chain pointer */ \ + std r0,GPR0(r1); /* save r0 in stackframe */ \ + std r10,GPR1(r1); /* save r1 in stackframe */ \ + std r2,GPR2(r1); /* save r2 in stackframe */ \ + SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ + SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ + ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \ + ld r10,area+EX_R10(r13); \ + std r9,GPR9(r1); \ + std r10,GPR10(r1); \ + ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \ + ld r10,area+EX_R12(r13); \ + ld r11,area+EX_R13(r13); \ + std r9,GPR11(r1); \ + std r10,GPR12(r1); \ + std r11,GPR13(r1); \ + ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ + mflr r9; /* save LR in stackframe */ \ + std r9,_LINK(r1); \ + mfctr r10; /* save CTR in stackframe */ \ + std r10,_CTR(r1); \ + mfspr r11,XER; /* save XER in stackframe */ \ + std r11,_XER(r1); \ + li r9,(n)+1; \ + std r9,_TRAP(r1); /* set trap number */ \ + li r10,0; \ + ld r11,exception_marker@toc(r2); \ + std r10,RESULT(r1); /* clear regs->result */ \ + std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ /* * Exception vectors. */ -#define STD_EXCEPTION_PSERIES(n, label ) \ - . = n; \ - .globl label##_Pseries; \ -label##_Pseries: \ - EXCEPTION_PROLOG_PSERIES( n, label##_common ) - -#define STD_EXCEPTION_ISERIES( n, label ) \ - .globl label##_Iseries; \ -label##_Iseries: \ - EXCEPTION_PROLOG_ISERIES( n ); \ +#define STD_EXCEPTION_PSERIES(n, label) \ + . = n; \ + .globl label##_Pseries; \ +label##_Pseries: \ + mtspr SPRG1,r13; /* save r13 */ \ + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) + +#define STD_EXCEPTION_ISERIES(n, label, area) \ + .globl label##_Iseries; \ +label##_Iseries: \ + mtspr SPRG1,r13; /* save r13 */ \ + EXCEPTION_PROLOG_ISERIES_1(area); \ + EXCEPTION_PROLOG_ISERIES_2; \ b label##_common -#define MASKABLE_EXCEPTION_ISERIES( n, label ) \ - .globl label##_Iseries; \ -label##_Iseries: \ - EXCEPTION_PROLOG_ISERIES( n ); \ - lbz r22,PACAPROFENABLED(r20); \ - cmpi 0,r22,0; \ - bne- label##_Iseries_profile; \ -label##_Iseries_prof_ret: \ - lbz r22,PACAPROCENABLED(r20); \ - cmpi 0,r22,0; \ - beq- label##_Iseries_masked; \ - b label##_common; \ -label##_Iseries_profile: \ - std r24,48(r21); \ - std r25,56(r21); \ - mflr r24; \ - bl do_profile; \ - mtlr r24; \ - ld r24,48(r21); \ - ld r25,56(r21); \ +#define MASKABLE_EXCEPTION_ISERIES(n, label) \ + .globl label##_Iseries; \ +label##_Iseries: \ + mtspr SPRG1,r13; /* save r13 */ \ + EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ + lbz r10,PACAPROFENABLED(r13); \ + cmpwi r10,0; \ + bne- label##_Iseries_profile; \ +label##_Iseries_prof_ret: \ + lbz r10,PACAPROCENABLED(r13); \ + cmpwi 0,r10,0; \ + beq- label##_Iseries_masked; \ + EXCEPTION_PROLOG_ISERIES_2; \ + b label##_common; \ +label##_Iseries_profile: \ + ld r12,LPPACA+LPPACASRR1(r13); \ + andi. r12,r12,MSR_PR; /* Test if in kernel */ \ + bne label##_Iseries_prof_ret; \ + ld r11,LPPACA+LPPACASRR0(r13); \ + ld r12,PACAPROFSTEXT(r13); /* _stext */ \ + subf r11,r12,r11; /* offset into kernel */ \ + lwz r12,PACAPROFSHIFT(r13); \ + srd r11,r11,r12; \ + lwz r12,PACAPROFLEN(r13); /* profile table length - 1 */ \ + cmpd r11,r12; /* off end? */ \ + ble 1f; \ + mr r11,r12; /* force into last entry */ \ +1: sldi r11,r11,2; /* convert to offset */ \ + ld r12,PACAPROFBUFFER(r13);/* profile buffer */ \ + add r12,r12,r11; \ +2: lwarx r11,0,r12; /* atomically increment */ \ + addi r11,r11,1; \ + stwcx. r11,0,r12; \ + bne- 2b; \ b label##_Iseries_prof_ret -#define STD_EXCEPTION_COMMON( trap, label, hdlr ) \ - .globl label##_common; \ -label##_common: \ - EXCEPTION_PROLOG_COMMON; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - li r20,0; \ - li r6,trap; \ - bl .save_remaining_regs; \ - bl hdlr; \ - b .ret_from_except +#ifdef DO_SOFT_DISABLE +#define DISABLE_INTS \ + lbz r10,PACAPROCENABLED(r13); \ + li r11,0; \ + std r10,SOFTE(r1); \ + mfmsr r10; \ + stb r11,PACAPROCENABLED(r13); \ + ori r10,r10,MSR_EE; \ + mtmsrd r10,1 + +#define ENABLE_INTS \ + lbz r10,PACAPROCENABLED(r13); \ + mfmsr r11; \ + std r10,SOFTE(r1); \ + ori r11,r11,MSR_EE; \ + mtmsrd r11,1 + +#else /* hard enable/disable interrupts */ +#define DISABLE_INTS + +#define ENABLE_INTS \ + ld r12,_MSR(r1); \ + mfmsr r11; \ + rlwimi r11,r12,0,MSR_EE; \ + mtmsrd r11,1 + +#endif + +#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ + .align 7; \ + .globl label##_common; \ +label##_common: \ + EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ + DISABLE_INTS; \ + bl .save_nvgprs; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b .ret_from_except + +#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ + .align 7; \ + .globl label##_common; \ +label##_common: \ + EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ + DISABLE_INTS; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b .ret_from_except_lite /* * Start of pSeries system interrupt routines @@ -384,22 +404,74 @@ .globl __start_interrupts __start_interrupts: - STD_EXCEPTION_PSERIES( 0x100, SystemReset ) - STD_EXCEPTION_PSERIES( 0x200, MachineCheck ) - STD_EXCEPTION_PSERIES( 0x300, DataAccess ) - STD_EXCEPTION_PSERIES( 0x380, DataAccessSLB ) - STD_EXCEPTION_PSERIES( 0x400, InstructionAccess ) - STD_EXCEPTION_PSERIES( 0x480, InstructionAccessSLB ) - STD_EXCEPTION_PSERIES( 0x500, HardwareInterrupt ) - STD_EXCEPTION_PSERIES( 0x600, Alignment ) - STD_EXCEPTION_PSERIES( 0x700, ProgramCheck ) - STD_EXCEPTION_PSERIES( 0x800, FPUnavailable ) - STD_EXCEPTION_PSERIES( 0x900, Decrementer ) - STD_EXCEPTION_PSERIES( 0xa00, Trap_0a ) - STD_EXCEPTION_PSERIES( 0xb00, Trap_0b ) - STD_EXCEPTION_PSERIES( 0xc00, SystemCall ) - STD_EXCEPTION_PSERIES( 0xd00, SingleStep ) - STD_EXCEPTION_PSERIES( 0xe00, Trap_0e ) + STD_EXCEPTION_PSERIES(0x100, SystemReset) + + . = 0x200 + .globl MachineCheck_Pseries +_MachineCheckPseries: + mtspr SPRG1,r13 /* save r13 */ + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common) + + . = 0x300 + .globl DataAccess_Pseries +DataAccess_Pseries: + mtspr SPRG1,r13 +BEGIN_FTR_SECTION + mtspr SPRG2,r12 + mfspr r13,DAR + mfspr r12,DSISR + srdi r13,r13,60 + rlwimi r13,r12,16,0x20 + mfcr r12 + cmpwi r13,0x2c + beq .do_stab_bolted_Pseries + mtcrf 0x80,r12 + mfspr r12,SPRG2 +END_FTR_SECTION_IFCLR(CPU_FTR_SLB) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccess_common) + + . = 0x380 + .globl DataAccessSLB_Pseries +DataAccessSLB_Pseries: + mtspr SPRG1,r13 + mtspr SPRG2,r12 + mfspr r13,DAR + mfcr r12 + srdi r13,r13,60 + cmpdi r13,0xc + beq .do_slb_bolted_Pseries + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccessSLB_common) + + STD_EXCEPTION_PSERIES(0x400, InstructionAccess) + STD_EXCEPTION_PSERIES(0x480, InstructionAccessSLB) + STD_EXCEPTION_PSERIES(0x500, HardwareInterrupt) + STD_EXCEPTION_PSERIES(0x600, Alignment) + STD_EXCEPTION_PSERIES(0x700, ProgramCheck) + STD_EXCEPTION_PSERIES(0x800, FPUnavailable) + STD_EXCEPTION_PSERIES(0x900, Decrementer) + STD_EXCEPTION_PSERIES(0xa00, Trap_0a) + STD_EXCEPTION_PSERIES(0xb00, Trap_0b) + + . = 0xc00 + .globl SystemCall_Pseries +SystemCall_Pseries: + mr r9,r13 + mfmsr r10 + mfspr r13,SPRG3 + mfspr r11,SRR0 + clrrdi r12,r13,32 + oris r12,r12,SystemCall_common@h + ori r12,r12,SystemCall_common@l + mtspr SRR0,r12 + ori r10,r10,MSR_IR|MSR_DR|MSR_RI + mfspr r12,SRR1 + mtspr SRR1,r10 + rfid + + STD_EXCEPTION_PSERIES(0xd00, SingleStep) + STD_EXCEPTION_PSERIES(0xe00, Trap_0e) /* We need to deal with the Altivec unavailable exception * here which is at 0xf20, thus in the middle of the @@ -407,27 +479,28 @@ * trickery is thus necessary */ . = 0xf00 - b .PerformanceMonitor_Pseries - . = 0xf20 - b .AltivecUnavailable_Pseries + b PerformanceMonitor_Pseries - STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint ) - STD_EXCEPTION_PSERIES( 0x1700, AltivecAssist ) + STD_EXCEPTION_PSERIES(0xf20, AltivecUnavailable) + + STD_EXCEPTION_PSERIES(0x1300, InstructionBreakpoint) + STD_EXCEPTION_PSERIES(0x1700, AltivecAssist) + + /* moved from 0xf00 */ + STD_EXCEPTION_PSERIES(0x3000, PerformanceMonitor) - /* Here are the "moved" performance monitor and - * altivec unavailable exceptions - */ - . = 0x3000 - .globl PerformanceMonitor_Pseries; -.PerformanceMonitor_Pseries: - EXCEPTION_PROLOG_PSERIES(0xf00, PerformanceMonitor_common) - . = 0x3100 - .globl AltivecUnavailable_Pseries; -.AltivecUnavailable_Pseries: - EXCEPTION_PROLOG_PSERIES(0xf20, AltivecUnavailable_common) +_GLOBAL(do_stab_bolted_Pseries) + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) + +_GLOBAL(do_slb_bolted_Pseries) + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_slb_bolted) + - /* Space for the naca. Architected to be located at real address * NACA_PHYS_ADDR. Various tools rely on this location being fixed. * The first dword of the naca is required by iSeries LPAR to @@ -466,16 +539,16 @@ * VSID generation algorithm. See include/asm/mmu_context.h. */ - .llong 1 /* # ESIDs to be mapped by hypervisor */ + .llong 1 /* # ESIDs to be mapped by hypervisor */ .llong 1 /* # memory ranges to be mapped by hypervisor */ - .llong STAB0_PAGE /* Page # of segment table within load area */ + .llong STAB0_PAGE /* Page # of segment table within load area */ + .llong 0 /* Reserved */ + .llong 0 /* Reserved */ .llong 0 /* Reserved */ - .llong 0 /* Reserved */ - .llong 0 /* Reserved */ .llong 0 /* Reserved */ .llong 0 /* Reserved */ .llong 0x0c00000000 /* ESID to map (Kernel at EA = 0xC000000000000000) */ - .llong 0x06a99b4b14 /* VSID to map (Kernel at VA = 0x6a99b4b140000000) */ + .llong 0x06a99b4b14 /* VSID to map (Kernel at VA = 0x6a99b4b140000000) */ .llong 8192 /* # pages to map (32 MB) */ .llong 0 /* Offset from start of loadarea to start of map */ .llong 0x0006a99b4b140000 /* VPN of first page to map */ @@ -484,31 +557,82 @@ /*** ISeries-LPAR interrupt handlers ***/ - STD_EXCEPTION_ISERIES( 0x200, MachineCheck ) - STD_EXCEPTION_ISERIES( 0x300, DataAccess ) - STD_EXCEPTION_ISERIES( 0x380, DataAccessSLB ) - STD_EXCEPTION_ISERIES( 0x400, InstructionAccess ) - STD_EXCEPTION_ISERIES( 0x480, InstructionAccessSLB ) - MASKABLE_EXCEPTION_ISERIES( 0x500, HardwareInterrupt ) - STD_EXCEPTION_ISERIES( 0x600, Alignment ) - STD_EXCEPTION_ISERIES( 0x700, ProgramCheck ) - STD_EXCEPTION_ISERIES( 0x800, FPUnavailable ) - MASKABLE_EXCEPTION_ISERIES( 0x900, Decrementer ) - STD_EXCEPTION_ISERIES( 0xa00, Trap_0a ) - STD_EXCEPTION_ISERIES( 0xb00, Trap_0b ) - STD_EXCEPTION_ISERIES( 0xc00, SystemCall ) - STD_EXCEPTION_ISERIES( 0xd00, SingleStep ) - STD_EXCEPTION_ISERIES( 0xe00, Trap_0e ) - STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor ) + STD_EXCEPTION_ISERIES(0x200, MachineCheck, PACA_EXMC) + + .globl DataAccess_Iseries +DataAccess_Iseries: + mtspr SPRG1,r13 +BEGIN_FTR_SECTION + mtspr SPRG2,r12 + mfspr r13,DAR + mfspr r12,DSISR + srdi r13,r13,60 + rlwimi r13,r12,16,0x20 + mfcr r12 + cmpwi r13,0x2c + beq .do_stab_bolted_Iseries + mtcrf 0x80,r12 + mfspr r12,SPRG2 +END_FTR_SECTION_IFCLR(CPU_FTR_SLB) + EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN) + EXCEPTION_PROLOG_ISERIES_2 + b DataAccess_common + +.do_stab_bolted_Iseries: + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) + EXCEPTION_PROLOG_ISERIES_2 + b .do_stab_bolted + + .globl DataAccessSLB_Iseries +DataAccessSLB_Iseries: + mtspr SPRG1,r13 /* save r13 */ + mtspr SPRG2,r12 + mfspr r13,DAR + mfcr r12 + srdi r13,r13,60 + cmpdi r13,0xc + beq .do_slb_bolted_Iseries + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN) + EXCEPTION_PROLOG_ISERIES_2 + b DataAccessSLB_common + +.do_slb_bolted_Iseries: + mtcrf 0x80,r12 + mfspr r12,SPRG2 + EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) + EXCEPTION_PROLOG_ISERIES_2 + b .do_slb_bolted + + STD_EXCEPTION_ISERIES(0x400, InstructionAccess, PACA_EXGEN) + STD_EXCEPTION_ISERIES(0x480, InstructionAccessSLB, PACA_EXGEN) + MASKABLE_EXCEPTION_ISERIES(0x500, HardwareInterrupt) + STD_EXCEPTION_ISERIES(0x600, Alignment, PACA_EXGEN) + STD_EXCEPTION_ISERIES(0x700, ProgramCheck, PACA_EXGEN) + STD_EXCEPTION_ISERIES(0x800, FPUnavailable, PACA_EXGEN) + MASKABLE_EXCEPTION_ISERIES(0x900, Decrementer) + STD_EXCEPTION_ISERIES(0xa00, Trap_0a, PACA_EXGEN) + STD_EXCEPTION_ISERIES(0xb00, Trap_0b, PACA_EXGEN) + + .globl SystemCall_Iseries +SystemCall_Iseries: + mr r9,r13 + mfspr r13,SPRG3 + EXCEPTION_PROLOG_ISERIES_2 + b SystemCall_common + + STD_EXCEPTION_ISERIES( 0xd00, SingleStep, PACA_EXGEN) + STD_EXCEPTION_ISERIES( 0xe00, Trap_0e, PACA_EXGEN) + STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor, PACA_EXGEN) .globl SystemReset_Iseries SystemReset_Iseries: mfspr r13,SPRG3 /* Get paca address */ - mfmsr r24 - ori r24,r24,MSR_RI - mtmsrd r24 /* RI on */ lhz r24,PACAPACAINDEX(r13) /* Get processor # */ - cmpi 0,r24,0 /* Are we processor 0? */ + cmpwi 0,r24,0 /* Are we processor 0? */ beq .__start_initialization_iSeries /* Start up the first processor */ mfspr r4,CTRLF li r5,RUNLATCH /* Turn off the run light */ @@ -527,7 +651,7 @@ addi r1,r3,THREAD_SIZE subi r1,r1,STACK_FRAME_OVERHEAD - cmpi 0,r23,0 + cmpwi 0,r23,0 beq iseries_secondary_smp_loop /* Loop until told to go */ #ifdef SECONDARY_PROCESSORS bne .__secondary_start /* Loop until told to go */ @@ -539,7 +663,7 @@ rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ #else /* CONFIG_SMP */ /* Yield the processor. This is required for non-SMP kernels - which are running on multi-threaded machines. */ + which are running on multi-threaded machines. */ lis r3,0x8000 rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */ addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */ @@ -552,32 +676,33 @@ b 1b /* If SMP not configured, secondaries * loop forever */ - .globl HardwareInterrupt_Iseries_masked -HardwareInterrupt_Iseries_masked: - b maskable_exception_exit - .globl Decrementer_Iseries_masked Decrementer_Iseries_masked: - li r22,1 - stb r22,PACALPPACA+LPPACADECRINT(r20) - lwz r22,PACADEFAULTDECR(r20) - mtspr DEC,r22 -maskable_exception_exit: - mtcrf 0xff,r23 /* Restore regs and free exception frame */ - ld r22,EX_SRR0(r21) - ld r23,EX_SRR1(r21) - mtspr SRR0,r22 - mtspr SRR1,r23 - ld r22,EX_R22(r21) - ld r23,EX_R23(r21) - mfspr r21,SPRG1 - mfspr r20,SPRG2 + li r11,1 + stb r11,PACALPPACA+LPPACADECRINT(r13) + lwz r12,PACADEFAULTDECR(r13) + mtspr DEC,r12 + /* fall through */ + + .globl HardwareInterrupt_Iseries_masked +HardwareInterrupt_Iseries_masked: + mtcrf 0x80,r9 /* Restore regs */ + ld r11,LPPACA+LPPACASRR0(r13) + ld r12,LPPACA+LPPACASRR1(r13) + mtspr SRR0,r11 + mtspr SRR1,r12 + ld r9,PACA_EXGEN+EX_R9(r13) + ld r10,PACA_EXGEN+EX_R10(r13) + ld r11,PACA_EXGEN+EX_R11(r13) + ld r12,PACA_EXGEN+EX_R12(r13) + ld r13,PACA_EXGEN+EX_R13(r13) rfid #endif + /* * Data area reserved for FWNMI option. */ - .= 0x7000 + .= 0x7000 .globl fwnmi_data_area fwnmi_data_area: @@ -587,10 +712,12 @@ . = 0x8000 .globl SystemReset_FWNMI SystemReset_FWNMI: - EXCEPTION_PROLOG_PSERIES(0x100, SystemReset_common) + mtspr SPRG1,r13 /* save r13 */ + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, SystemReset_common) .globl MachineCheck_FWNMI MachineCheck_FWNMI: - EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common) + mtspr SPRG1,r13 /* save r13 */ + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common) /* * Space for the initial segment table @@ -608,327 +735,266 @@ /*** Common interrupt handlers ***/ - STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException ) - STD_EXCEPTION_COMMON( 0x200, MachineCheck, .MachineCheckException ) - STD_EXCEPTION_COMMON( 0x900, Decrementer, .timer_interrupt ) - STD_EXCEPTION_COMMON( 0xa00, Trap_0a, .UnknownException ) - STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException ) - STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException ) - STD_EXCEPTION_COMMON( 0xe00, Trap_0e, .UnknownException ) - STD_EXCEPTION_COMMON( 0xf00, PerformanceMonitor, .PerformanceMonitorException ) - STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException ) + STD_EXCEPTION_COMMON(0x100, SystemReset, .SystemResetException) + + /* + * Machine check is different because we use a different + * save area: PACA_EXMC instead of PACA_EXGEN. + */ + .align 7 + .globl MachineCheck_common +MachineCheck_common: + EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) + DISABLE_INTS + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + bl .MachineCheckException + b .ret_from_except + + STD_EXCEPTION_COMMON_LITE(0x900, Decrementer, .timer_interrupt) + STD_EXCEPTION_COMMON(0xa00, Trap_0a, .UnknownException) + STD_EXCEPTION_COMMON(0xb00, Trap_0b, .UnknownException) + STD_EXCEPTION_COMMON(0xd00, SingleStep, .SingleStepException) + STD_EXCEPTION_COMMON(0xe00, Trap_0e, .UnknownException) + STD_EXCEPTION_COMMON(0xf00, PerformanceMonitor, .PerformanceMonitorException) + STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException) #ifdef CONFIG_ALTIVEC - STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .AltivecAssistException ) + STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .AltivecAssistException) #else - STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .UnknownException ) + STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .UnknownException) #endif /* - * Here the exception frame is filled out and we have detected that - * the kernel stack pointer is bad. R23 contains the saved CR, r20 - * points to the paca, r21 points to the exception frame, and r22 - * contains the (bad) kernel stack pointer. + * Here we have detected that the kernel stack pointer is bad. + * R9 contains the saved CR, r13 points to the paca, + * r10 contains the (bad) kernel stack pointer, + * r11 and r12 contain the saved SRR0 and SRR1. * We switch to using the paca guard page as an emergency stack, - * save the registers on there, and call kernel_bad_stack(), - * which panics. + * save the registers there, and call kernel_bad_stack(), which panics. */ bad_stack: - addi r1,r20,8192-64-INT_FRAME_SIZE - std r22,GPR1(r1) - std r23,_CCR(r1) - ld r22,EX_R20(r21) - std r22,GPR20(r1) - ld r23,EX_R21(r21) - std r23,GPR21(r1) - ld r22,EX_R22(r21) - std r22,GPR22(r1) - ld r23,EX_R23(r21) - std r23,GPR23(r1) - ld r23,EX_DAR(r21) - std r23,_DAR(r1) - lwz r22,EX_DSISR(r21) - std r22,_DSISR(r1) - lwz r23,EX_TRAP(r21) - std r23,TRAP(r1) - ld r22,EX_SRR0(r21) - ld r23,EX_SRR1(r21) - std r22,_NIP(r1) - std r23,_MSR(r1) - addi r21,r21,-EXC_FRAME_SIZE - std r21,PACAEXCSP(r20) - mflr r22 - std r22,_LINK(r1) - mfctr r23 - std r23,_CTR(r1) - mfspr r22,XER - std r22,_XER(r1) - SAVE_GPR(0, r1) - SAVE_10GPRS(2, r1) - SAVE_8GPRS(12, r1) - SAVE_8GPRS(24, r1) - addi r21,r1,INT_FRAME_SIZE - std r21,0(r1) - li r22,0 - std r22,0(r21) - ld r2,PACATOC(r20) - mr r13,r20 + addi r1,r13,8192-64-INT_FRAME_SIZE + std r9,_CCR(r1) + std r10,GPR1(r1) + std r11,_NIP(r1) + std r12,_MSR(r1) + mfspr r11,DAR + mfspr r12,DSISR + std r11,_DAR(r1) + std r12,_DSISR(r1) + mflr r10 + mfctr r11 + mfxer r12 + std r10,_LINK(r1) + std r11,_CTR(r1) + std r12,_XER(r1) + SAVE_GPR(0,r1) + SAVE_GPR(2,r1) + SAVE_4GPRS(3,r1) + SAVE_2GPRS(7,r1) + SAVE_10GPRS(12,r1) + SAVE_10GPRS(22,r1) + addi r11,r1,INT_FRAME_SIZE + std r11,0(r1) + li r12,0 + std r12,0(r11) + ld r2,PACATOC(r13) 1: addi r3,r1,STACK_FRAME_OVERHEAD bl .kernel_bad_stack b 1b /* - * Return from an exception which is handled without calling - * save_remaining_regs. The caller is assumed to have done - * EXCEPTION_PROLOG_COMMON. + * Return from an exception with minimal checks. + * The caller is assumed to have done EXCEPTION_PROLOG_COMMON. + * If interrupts have been enabled, or anything has been + * done that might have changed the scheduling status of + * any task or sent any task a signal, you should use + * ret_from_except or ret_from_except_lite instead of this. */ fast_exception_return: - andi. r3,r23,MSR_RI /* check if RI is set */ + ld r12,_MSR(r1) + ld r11,_NIP(r1) + andi. r3,r12,MSR_RI /* check if RI is set */ beq- unrecov_fer - ld r3,_CCR(r1) - ld r4,_LINK(r1) - ld r5,_CTR(r1) - ld r6,_XER(r1) - mtcr r3 - mtlr r4 - mtctr r5 - mtspr XER,r6 + ld r3,_CCR(r1) + ld r4,_LINK(r1) + ld r5,_CTR(r1) + ld r6,_XER(r1) + mtcr r3 + mtlr r4 + mtctr r5 + mtxer r6 REST_GPR(0, r1) REST_8GPRS(2, r1) - REST_4GPRS(10, r1) - mfmsr r20 - li r21, MSR_RI - andc r20,r20,r21 - mtmsrd r20,1 - - mtspr SRR1,r23 - mtspr SRR0,r22 - REST_4GPRS(20, r1) - ld r1,GPR1(r1) + mfmsr r10 + clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ + mtmsrd r10,1 + + mtspr SRR1,r12 + mtspr SRR0,r11 + REST_4GPRS(10, r1) + ld r1,GPR1(r1) rfid unrecov_fer: - li r6,0x4000 - li r20,0 - bl .save_remaining_regs + bl .save_nvgprs 1: addi r3,r1,STACK_FRAME_OVERHEAD bl .unrecoverable_exception b 1b /* - * Here r20 points to the PACA, r21 to the exception frame, - * r23 contains the saved CR. - * r20 - r23, SRR0 and SRR1 are saved in the exception frame. + * Here r13 points to the paca, r9 contains the saved CR, + * SRR0 and SRR1 are saved in r11 and r12, + * r9 - r13 are saved in paca->exgen. */ + .align 7 .globl DataAccess_common DataAccess_common: -BEGIN_FTR_SECTION - mfspr r22,DAR - srdi r22,r22,60 - cmpi 0,r22,0xc - - /* Segment fault on a bolted segment. Go off and map that segment. */ - beq- .do_stab_bolted -END_FTR_SECTION_IFCLR(CPU_FTR_SLB) -stab_bolted_user_return: - EXCEPTION_PROLOG_COMMON - ld r3,_DSISR(r1) - andis. r0,r3,0xa450 /* weird error? */ - bne 1f /* if not, try to put a PTE */ - andis. r0,r3,0x0020 /* Is it a page table fault? */ - rlwinm r4,r3,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */ - ld r3,_DAR(r1) /* into the hash table */ - -BEGIN_FTR_SECTION - beq+ 2f /* If so handle it */ - li r4,0x300 /* Trap number */ - bl .do_stab_SI - b 1f -END_FTR_SECTION_IFCLR(CPU_FTR_SLB) - -2: li r5,0x300 - bl .do_hash_page_DSI /* Try to handle as hpte fault */ -1: - ld r4,_DAR(r1) - ld r5,_DSISR(r1) - addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - li r6,0x300 - bl .save_remaining_regs - bl .do_page_fault - b .ret_from_except + mfspr r10,DAR + std r10,PACA_EXGEN+EX_DAR(r13) + mfspr r10,DSISR + stw r10,PACA_EXGEN+EX_DSISR(r13) + EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) + ld r3,PACA_EXGEN+EX_DAR(r13) + lwz r4,PACA_EXGEN+EX_DSISR(r13) + li r5,0x300 + b .do_hash_page /* Try to handle as hpte fault */ + .align 7 .globl DataAccessSLB_common DataAccessSLB_common: - mfspr r22,DAR - srdi r22,r22,60 - cmpi 0,r22,0xc - - /* Segment fault on a bolted segment. Go off and map that segment. */ - beq .do_slb_bolted - - EXCEPTION_PROLOG_COMMON - ld r3,_DAR(r1) - li r4,0x380 /* Exception vector */ + mfspr r10,DAR + std r10,PACA_EXGEN+EX_DAR(r13) + EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN) + ld r3,PACA_EXGEN+EX_DAR(r13) + std r3,_DAR(r1) bl .slb_allocate - or. r3,r3,r3 /* Check return code */ - beq fast_exception_return /* Return if we succeeded */ - addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - ld r4,_DAR(r1) - li r6,0x380 + cmpdi r3,0 /* Check return code */ + beq fast_exception_return /* Return if we succeeded */ li r5,0 - bl .save_remaining_regs - bl .do_page_fault - b .ret_from_except + std r5,_DSISR(r1) + b .handle_page_fault + .align 7 .globl InstructionAccess_common InstructionAccess_common: - EXCEPTION_PROLOG_COMMON - -BEGIN_FTR_SECTION - andis. r0,r23,0x0020 /* no ste found? */ - beq+ 2f - mr r3,r22 /* SRR0 at interrupt */ - li r4,0x400 /* Trap number */ - bl .do_stab_SI - b 1f -END_FTR_SECTION_IFCLR(CPU_FTR_SLB) - -2: mr r3,r22 + EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN) + ld r3,_NIP(r1) + andis. r4,r12,0x5820 li r5,0x400 - bl .do_hash_page_ISI /* Try to handle as hpte fault */ -1: - mr r4,r22 - rlwinm r5,r23,0,4,4 /* We only care about PR in error_code */ - addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - li r6,0x400 - bl .save_remaining_regs - bl .do_page_fault - b .ret_from_except + b .do_hash_page /* Try to handle as hpte fault */ + .align 7 .globl InstructionAccessSLB_common InstructionAccessSLB_common: - EXCEPTION_PROLOG_COMMON - mr r3,r22 /* SRR0 = NIA */ - li r4,0x480 /* Exception vector */ + EXCEPTION_PROLOG_COMMON(0x480, PACA_EXGEN) + ld r3,_NIP(r1) /* SRR0 = NIA */ bl .slb_allocate or. r3,r3,r3 /* Check return code */ - beq+ fast_exception_return /* Return if we succeeded */ + beq+ fast_exception_return /* Return if we succeeded */ - addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - mr r4,r22 /* SRR0 = NIA */ - li r6,0x480 + ld r4,_NIP(r1) li r5,0 - bl .save_remaining_regs - bl .do_page_fault - b .ret_from_except + std r4,_DAR(r1) + std r5,_DSISR(r1) + b .handle_page_fault + .align 7 .globl HardwareInterrupt_common + .globl HardwareInterrupt_entry HardwareInterrupt_common: - EXCEPTION_PROLOG_COMMON + EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) HardwareInterrupt_entry: + DISABLE_INTS addi r3,r1,STACK_FRAME_OVERHEAD - li r20,0 - li r6,0x500 - bl .save_remaining_regs - bl .do_IRQ - b .ret_from_except + bl .do_IRQ + b .ret_from_except_lite + .align 7 .globl Alignment_common Alignment_common: - EXCEPTION_PROLOG_COMMON + mfspr r10,DAR + std r10,PACA_EXGEN+EX_DAR(r13) + mfspr r10,DSISR + stw r10,PACA_EXGEN+EX_DSISR(r13) + EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN) + ld r3,PACA_EXGEN+EX_DAR(r13) + lwz r4,PACA_EXGEN+EX_DSISR(r13) + std r3,_DAR(r1) + std r4,_DSISR(r1) + bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - li r6,0x600 - bl .save_remaining_regs - bl .AlignmentException - b .ret_from_except + ENABLE_INTS + bl .AlignmentException + b .ret_from_except + .align 7 .globl ProgramCheck_common ProgramCheck_common: - EXCEPTION_PROLOG_COMMON + EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) + bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - li r6,0x700 - bl .save_remaining_regs - bl .ProgramCheckException - b .ret_from_except + ENABLE_INTS + bl .ProgramCheckException + b .ret_from_except + .align 7 .globl FPUnavailable_common FPUnavailable_common: - EXCEPTION_PROLOG_COMMON + EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) bne .load_up_fpu /* if from user, just load it up */ + bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - li r6,0x800 - bl .save_remaining_regs - bl .KernelFPUnavailableException + ENABLE_INTS + bl .KernelFPUnavailableException BUG_OPCODE + .align 7 .globl AltivecUnavailable_common AltivecUnavailable_common: - EXCEPTION_PROLOG_COMMON + EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN) #ifdef CONFIG_ALTIVEC - bne .load_up_altivec /* if from user, just load it up */ + bne .load_up_altivec /* if from user, just load it up */ #endif + bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD - DO_COPY_EE() - li r6,0xf20 - bl .save_remaining_regs -#ifdef CONFIG_ALTIVEC - bl .KernelAltivecUnavailableException -#else - bl .UnknownException -#endif - BUG_OPCODE - - .globl SystemCall_common -SystemCall_common: - EXCEPTION_PROLOG_COMMON -#ifdef CONFIG_PPC_ISERIES - cmpi 0,r0,0x5555 /* Special syscall to handle pending */ - bne+ 1f /* interrupts */ - andi. r6,r23,MSR_PR /* Only allowed from kernel */ - beq+ HardwareInterrupt_entry -1: -#endif - DO_COPY_EE() - li r6,0xC00 - bl .save_remaining_regs - bl .DoSyscall - b .ret_from_except - -_GLOBAL(do_hash_page_ISI) - li r4,0 -_GLOBAL(do_hash_page_DSI) + ENABLE_INTS + bl .AltivecUnavailableException + b .ret_from_except + +/* + * Hash table stuff + */ + .align 7 +_GLOBAL(do_hash_page) + std r3,_DAR(r1) + std r4,_DSISR(r1) + + andis. r0,r4,0xa450 /* weird error? */ + bne- .handle_page_fault /* if not, try to insert a HPTE */ +BEGIN_FTR_SECTION + andis. r0,r4,0x0020 /* Is it a segment table fault? */ + bne- .do_ste_alloc /* If so handle it */ +END_FTR_SECTION_IFCLR(CPU_FTR_SLB) + /* * We need to set the _PAGE_USER bit if MSR_PR is set or if we are * accessing a userspace segment (even from the kernel). We assume * kernel addresses always have the high bit set. */ - rotldi r0,r3,15 /* Move high bit into MSR_PR position */ - orc r0,r23,r0 - rlwimi r4,r0,32-13,30,30 /* Insert into _PAGE_USER */ + rlwinm r4,r4,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */ + rotldi r0,r3,15 /* Move high bit into MSR_PR posn */ + orc r0,r12,r0 /* MSR_PR | ~high_bit */ + rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */ ori r4,r4,1 /* add _PAGE_PRESENT */ - mflr r21 /* Save LR in r21 */ - -#ifdef DO_SOFT_DISABLE /* - * We hard enable here (but first soft disable) so that the hash_page - * code can spin on the hash_table_lock with problem on a shared - * processor. + * On iSeries, we soft-disable interrupts here, then + * hard-enable interrupts so that the hash_page code can spin on + * the hash_table_lock without problems on a shared processor. */ - li r0,0 - stb r0,PACAPROCENABLED(r20) /* Soft Disabled */ - - mfmsr r0 - ori r0,r0,MSR_EE - mtmsrd r0,1 /* Hard Enable */ -#endif + DISABLE_INTS /* * r3 contains the faulting address @@ -937,184 +1003,159 @@ * * at return r3 = 0 for success */ - bl .hash_page /* build HPTE if possible */ + cmpdi r3,0 /* see if hash_page succeeded */ #ifdef DO_SOFT_DISABLE /* - * Now go back to hard disabled. + * If we had interrupts soft-enabled at the point where the + * DSI/ISI occurred, and an interrupt came in during hash_page, + * handle it now. + * We jump to ret_from_except_lite rather than fast_exception_return + * because ret_from_except_lite will check for and handle pending + * interrupts if necessary. */ - mfmsr r0 - li r4,0 - ori r4,r4,MSR_EE - andc r0,r0,r4 - mtmsrd r0,1 /* Hard Disable */ - - ld r0,SOFTE(r1) - cmpdi 0,r0,0 /* See if we will soft enable in */ - /* save_remaining_regs */ - beq 5f - CHECKANYINT(r4,r5) - bne- HardwareInterrupt_entry /* Convert this DSI into an External */ - /* to process interrupts which occurred */ - /* during hash_page */ -5: - stb r0,PACAPROCENABLED(r20) /* Restore soft enable/disable status */ + beq .ret_from_except_lite + /* + * hash_page couldn't handle it, set soft interrupt enable back + * to what it was before the trap. Note that .local_irq_restore + * handles any interrupts pending at this point. + */ + ld r3,SOFTE(r1) + bl .local_irq_restore + b 11f +#else + beq+ fast_exception_return /* Return from exception on success */ + /* fall through */ #endif - or. r3,r3,r3 /* Check return code */ - beq fast_exception_return /* Return from exception on success */ - mtlr r21 /* restore LR */ - blr /* Return to DSI or ISI on failure */ +/* Here we have a page fault that hash_page can't handle. */ +_GLOBAL(handle_page_fault) + ENABLE_INTS +11: ld r4,_DAR(r1) + ld r5,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_page_fault + cmpdi r3,0 + beq+ .ret_from_except_lite + bl .save_nvgprs + mr r5,r3 + addi r3,r1,STACK_FRAME_OVERHEAD + lwz r4,_DAR(r1) + bl .bad_page_fault + b .ret_from_except + + /* here we have a segment miss */ +_GLOBAL(do_ste_alloc) + bl .ste_allocate /* try to insert stab entry */ + cmpdi r3,0 + beq+ fast_exception_return + b .handle_page_fault /* - * r20 points to the PACA, r21 to the exception frame, - * r23 contains the saved CR. - * r20 - r23, SRR0 and SRR1 are saved in the exception frame. + * r13 points to the PACA, r9 contains the saved CR, + * r11 and r12 contain the saved SRR0 and SRR1. + * r9 - r13 are saved in paca->exslb. * We assume we aren't going to take any exceptions during this procedure. + * We assume (DAR >> 60) == 0xc. */ + .align 7 _GLOBAL(do_stab_bolted) - stw r23,EX_CCR(r21) /* save CR in exc. frame */ + stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ + std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ - mfspr r22,DSISR - andis. r22,r22,0x0020 - beq- stab_bolted_user_return + /* Hash to the primary group */ + ld r10,PACASTABVIRT(r13) + mfspr r11,DAR + srdi r11,r11,28 + rldimi r10,r11,7,52 /* r10 = first ste of the group */ + /* Calculate VSID */ /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */ - mfspr r21,DAR - rldicl r20,r21,36,51 - sldi r20,r20,15 - srdi r21,r21,60 - or r20,r20,r21 + rldic r11,r11,15,36 + ori r11,r11,0xc /* VSID_RANDOMIZER */ - li r21,9 - sldi r21,r21,32 - oris r21,r21,58231 - ori r21,r21,39831 - - mulld r20,r20,r21 - clrldi r20,r20,28 /* r20 = vsid */ + li r9,9 + sldi r9,r9,32 + oris r9,r9,58231 + ori r9,r9,39831 - mfsprg r21,3 - ld r21,PACASTABVIRT(r21) - - /* Hash to the primary group */ - mfspr r22,DAR - rldicl r22,r22,36,59 - rldicr r22,r22,7,56 - or r21,r21,r22 /* r21 = first ste of the group */ + mulld r9,r11,r9 + rldic r9,r9,12,16 /* r9 = vsid << 12 */ /* Search the primary group for a free entry */ - li r22,0 -1: - ld r23,0(r21) /* Test valid bit of the current ste */ - rldicl r23,r23,57,63 - cmpwi r23,0 - bne 2f - li r23,0 - rldimi r23,r20,12,0 /* Insert the new vsid value */ - std r23,8(r21) /* Put new entry back into the stab */ - eieio /* Order vsid update */ - li r23,0 - mfspr r20,DAR /* Get the new esid */ - rldicl r20,r20,36,28 /* Permits a full 36b of ESID */ - rldimi r23,r20,28,0 /* Insert the new esid value */ - ori r23,r23,144 /* Turn on valid and kp */ - std r23,0(r21) /* Put new entry back into the stab */ - sync /* Order the update */ - b 3f -2: - addi r22,r22,1 - addi r21,r21,16 - cmpldi r22,7 - ble 1b +1: ld r11,0(r10) /* Test valid bit of the current ste */ + andi. r11,r11,0x80 + beq 2f + addi r10,r10,16 + andi. r11,r10,0x70 + bne 1b - /* Stick for only searching the primary group for now. */ + /* Stick for only searching the primary group for now. */ /* At least for now, we use a very simple random castout scheme */ - /* Use the TB as a random number ; OR in 1 to avoid entry 0 */ - mftb r22 - andi. r22,r22,7 - ori r22,r22,1 - sldi r22,r22,4 - - /* r21 currently points to and ste one past the group of interest */ - /* make it point to the randomly selected entry */ - subi r21,r21,128 - or r21,r21,r22 /* r21 is the entry to invalidate */ - - isync /* mark the entry invalid */ - ld r23,0(r21) - li r22,-129 - and r23,r23,r22 - std r23,0(r21) + /* Use the TB as a random number ; OR in 1 to avoid entry 0 */ + mftb r11 + rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */ + ori r11,r11,0x10 + + /* r10 currently points to an ste one past the group of interest */ + /* make it point to the randomly selected entry */ + subi r10,r10,128 + or r10,r10,r11 /* r10 is the entry to invalidate */ + + isync /* mark the entry invalid */ + ld r11,0(r10) + rldicl r11,r11,56,1 /* clear the valid bit */ + rotldi r11,r11,8 + std r11,0(r10) sync - li r23,0 - rldimi r23,r20,12,0 - std r23,8(r21) + clrrdi r11,r11,28 /* Get the esid part of the ste */ + slbie r11 + +2: std r9,8(r10) /* Store the vsid part of the ste */ eieio - ld r22,0(r21) /* Get the esid part of the ste */ - li r23,0 - mfspr r20,DAR /* Get the new esid */ - rldicl r20,r20,36,28 /* Permits a full 32b of ESID */ - rldimi r23,r20,28,0 /* Insert the new esid value */ - ori r23,r23,144 /* Turn on valid and kp */ - std r23,0(r21) /* Put new entry back into the stab */ - - rldicl r22,r22,36,28 - rldicr r22,r22,28,35 - slbie r22 + mfspr r11,DAR /* Get the new esid */ + clrrdi r11,r11,28 /* Permits a full 32b of ESID */ + ori r11,r11,0x90 /* Turn on valid and kp */ + std r11,0(r10) /* Put new entry back into the stab */ + sync -3: /* All done -- return from exception. */ - mfsprg r20,3 /* Load the PACA pointer */ - ld r21,PACAEXCSP(r20) /* Get the exception frame pointer */ - addi r21,r21,EXC_FRAME_SIZE - lwz r23,EX_CCR(r21) /* get saved CR */ - - ld r22,EX_SRR1(r21) - andi. r22,r22,MSR_RI - beq- unrecov_stab - - /* note that this is almost identical to maskable_exception_exit */ - mtcr r23 /* restore CR */ - - mfmsr r22 - li r23, MSR_RI - andc r22,r22,r23 - mtmsrd r22,1 - - ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */ - ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */ - mtspr SRR0,r22 - mtspr SRR1,r23 - ld r22,EX_R22(r21) /* restore r22 and r23 */ - ld r23,EX_R23(r21) - mfspr r20,SPRG2 - mfspr r21,SPRG1 - rfid + lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ + ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */ -unrecov_stab: - EXCEPTION_PROLOG_COMMON - li r6,0x4100 - li r20,0 - bl .save_remaining_regs -1: addi r3,r1,STACK_FRAME_OVERHEAD - bl .unrecoverable_exception - b 1b + andi. r10,r12,MSR_RI + beq- unrecov_slb + + mtcrf 0x80,r9 /* restore CR */ + + mfmsr r10 + clrrdi r10,r10,2 + mtmsrd r10,1 + + mtspr SRR0,r11 + mtspr SRR1,r12 + ld r9,PACA_EXSLB+EX_R9(r13) + ld r10,PACA_EXSLB+EX_R10(r13) + ld r11,PACA_EXSLB+EX_R11(r13) + ld r12,PACA_EXSLB+EX_R12(r13) + ld r13,PACA_EXSLB+EX_R13(r13) + rfid /* - * r20 points to the PACA, r21 to the exception frame, - * r23 contains the saved CR. - * r20 - r23, SRR0 and SRR1 are saved in the exception frame. + * r13 points to the PACA, r9 contains the saved CR, + * r11 and r12 contain the saved SRR0 and SRR1. + * r9 - r13 are saved in paca->exslb. * We assume we aren't going to take any exceptions during this procedure. */ /* XXX note fix masking in get_kernel_vsid to match */ _GLOBAL(do_slb_bolted) - stw r23,EX_CCR(r21) /* save CR in exc. frame */ + stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ + std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ /* * We take the next entry, round robin. Previously we tried @@ -1122,15 +1163,15 @@ * we dont have any LRU information to help us choose a slot. */ - /* r20 = paca */ -1: ld r22,PACASTABRR(r20) - addi r21,r22,1 - cmpdi r21,SLB_NUM_ENTRIES + /* r13 = paca */ +1: ld r10,PACASTABRR(r13) + addi r9,r10,1 + cmpdi r9,SLB_NUM_ENTRIES blt+ 2f - li r21,2 /* dont touch slot 0 or 1 */ -2: std r21,PACASTABRR(r20) + li r9,2 /* dont touch slot 0 or 1 */ +2: std r9,PACASTABRR(r13) - /* r20 = paca, r22 = entry */ + /* r13 = paca, r10 = entry */ /* * Never cast out the segment for our kernel stack. Since we @@ -1139,8 +1180,8 @@ * which gets invalidated due to a tlbie from another cpu at a * non recoverable point (after setting srr0/1) - Anton */ - slbmfee r21,r22 - srdi r21,r21,27 + slbmfee r9,r10 + srdi r9,r9,27 /* * Use paca->ksave as the value of the kernel stack pointer, * because this is valid at all times. @@ -1150,74 +1191,71 @@ * switch (between updating r1 and updating paca->ksave), * we check against both r1 and paca->ksave. */ - srdi r23,r1,27 - ori r23,r23,1 - cmpd r23,r21 + srdi r11,r1,27 + ori r11,r11,1 + cmpd r11,r9 beq- 1b - ld r23,PACAKSAVE(r20) - srdi r23,r23,27 - ori r23,r23,1 - cmpd r23,r21 + ld r11,PACAKSAVE(r13) + srdi r11,r11,27 + ori r11,r11,1 + cmpd r11,r9 beq- 1b - /* r20 = paca, r22 = entry */ + /* r13 = paca, r10 = entry */ /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */ - mfspr r21,DAR - rldicl r23,r21,36,51 - sldi r23,r23,15 - srdi r21,r21,60 - or r23,r23,r21 + mfspr r9,DAR + rldicl r11,r9,36,51 + sldi r11,r11,15 + srdi r9,r9,60 + or r11,r11,r9 /* VSID_RANDOMIZER */ - li r21,9 - sldi r21,r21,32 - oris r21,r21,58231 - ori r21,r21,39831 + li r9,9 + sldi r9,r9,32 + oris r9,r9,58231 + ori r9,r9,39831 /* vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK */ - mulld r23,r23,r21 - clrldi r23,r23,28 + mulld r11,r11,r9 + clrldi r11,r11,28 - /* r20 = paca, r22 = entry, r23 = vsid */ + /* r13 = paca, r10 = entry, r11 = vsid */ /* Put together slb word1 */ - sldi r23,r23,12 + sldi r11,r11,12 BEGIN_FTR_SECTION /* set kp and c bits */ - ori r23,r23,0x480 + ori r11,r11,0x480 END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE) BEGIN_FTR_SECTION /* set kp, l and c bits */ - ori r23,r23,0x580 + ori r11,r11,0x580 END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE) - /* r20 = paca, r22 = entry, r23 = slb word1 */ + /* r13 = paca, r10 = entry, r11 = slb word1 */ /* Put together slb word0 */ - mfspr r21,DAR - rldicr r21,r21,0,35 /* get the new esid */ - oris r21,r21,2048 /* set valid bit */ - rldimi r21,r22,0,52 /* insert entry */ + mfspr r9,DAR + clrrdi r9,r9,28 /* get the new esid */ + oris r9,r9,0x800 /* set valid bit */ + rldimi r9,r10,0,52 /* insert entry */ - /* r20 = paca, r21 = slb word0, r23 = slb word1 */ + /* r13 = paca, r9 = slb word0, r11 = slb word1 */ /* * No need for an isync before or after this slbmte. The exception * we enter with and the rfid we exit with are context synchronizing . */ - slbmte r23,r21 + slbmte r11,r9 /* All done -- return from exception. */ - ld r21,PACAEXCSP(r20) /* Get the exception frame pointer */ - addi r21,r21,EXC_FRAME_SIZE - lwz r23,EX_CCR(r21) /* get saved CR */ - /* note that this is almost identical to maskable_exception_exit */ - - ld r22,EX_SRR1(r21) - andi. r22,r22,MSR_RI - beq- unrecov_stab + lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ + ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */ + + andi. r10,r12,MSR_RI /* check for unrecoverable exception */ + beq- unrecov_slb /* * Until everyone updates binutils hardwire the POWER4 optimised @@ -1226,124 +1264,32 @@ #if 0 .machine push .machine "power4" - mtcrf 0x80,r23 + mtcrf 0x80,r9 .machine pop #else - .long 0x7ef80120 + .long 0x7d380120 #endif - mfmsr r22 - li r23, MSR_RI - andc r22,r22,r23 - mtmsrd r22,1 - - ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */ - ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */ - mtspr SRR0,r22 - mtspr SRR1,r23 - ld r22,EX_R22(r21) /* restore r22 and r23 */ - ld r23,EX_R23(r21) - ld r20,EX_R20(r21) - mfspr r21,SPRG1 + mfmsr r10 + clrrdi r10,r10,2 + mtmsrd r10,1 + + mtspr SRR0,r11 + mtspr SRR1,r12 + ld r9,PACA_EXSLB+EX_R9(r13) + ld r10,PACA_EXSLB+EX_R10(r13) + ld r11,PACA_EXSLB+EX_R11(r13) + ld r12,PACA_EXSLB+EX_R12(r13) + ld r13,PACA_EXSLB+EX_R13(r13) rfid -_GLOBAL(do_stab_SI) - mflr r21 /* Save LR in r21 */ - - /* - * r3 contains the faulting address - * r4 contains the required access permissions - * - * at return r3 = 0 for success - */ - - bl .ste_allocate /* build STE if possible */ - or. r3,r3,r3 /* Check return code */ - beq fast_exception_return /* Return from exception on success */ - mtlr r21 /* restore LR */ - blr /* Return to DSI or ISI on failure */ - -/* - * This code finishes saving the registers to the exception frame. - * Address translation is already on. - */ -_GLOBAL(save_remaining_regs) - /* - * Save the rest of the registers into the pt_regs structure - */ - std r22,_NIP(r1) - std r23,_MSR(r1) - std r6,TRAP(r1) - ld r6,GPR6(r1) - SAVE_2GPRS(14, r1) - SAVE_4GPRS(16, r1) - SAVE_8GPRS(24, r1) - - /* Set the marker value "regshere" just before the reg values */ - SET_REG_TO_CONST(r22, 0x7265677368657265) - std r22,STACK_FRAME_OVERHEAD-16(r1) - - /* - * Clear the RESULT field - */ - li r22,0 - std r22,RESULT(r1) - - /* - * Test if from user state; result will be tested later - */ - andi. r23,r23,MSR_PR /* Set CR for later branch */ - - /* - * Indicate that r1 contains the kernel stack and - * get the Kernel TOC pointer from the paca - */ - ld r2,PACATOC(r13) /* Get Kernel TOC pointer */ - - /* - * If from user state, update THREAD.regs - */ - beq 2f /* Modify THREAD.regs if from user */ - addi r23,r1,STACK_FRAME_OVERHEAD - ld r22, PACACURRENT(r13) - std r23,THREAD+PT_REGS(r22) -2: - SET_REG_TO_CONST(r22, MSR_KERNEL) - -#ifdef DO_SOFT_DISABLE - stb r20,PACAPROCENABLED(r13) /* possibly soft enable */ - ori r22,r22,MSR_EE /* always hard enable */ -#else - rldimi r22,r20,15,48 /* Insert desired EE value */ -#endif - - mtmsrd r22,1 - blr - -/* - * Kernel profiling with soft disable on iSeries - */ -do_profile: - ld r22,8(r21) /* Get SRR1 */ - andi. r22,r22,MSR_PR /* Test if in kernel */ - bnelr /* return if not in kernel */ - ld r22,0(r21) /* Get SRR0 */ - ld r25,PACAPROFSTEXT(r20) /* _stext */ - subf r22,r25,r22 /* offset into kernel */ - lwz r25,PACAPROFSHIFT(r20) - srd r22,r22,r25 - lwz r25,PACAPROFLEN(r20) /* length of profile table (-1) */ - cmp 0,r22,r25 /* off end? */ - ble 1f - mr r22,r25 /* force into last entry */ -1: sldi r22,r22,2 /* convert to offset into buffer */ - ld r25,PACAPROFBUFFER(r20) /* profile buffer */ - add r25,r25,r22 -2: lwarx r22,0,r25 /* atomically increment */ - addi r22,r22,1 - stwcx. r22,0,r25 - bne- 2b - blr +unrecov_slb: + EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) + DISABLE_INTS + bl .save_nvgprs +1: addi r3,r1,STACK_FRAME_OVERHEAD + bl .unrecoverable_exception + b 1b /* @@ -1356,32 +1302,32 @@ isync /* Set up a paca value for this processor. */ - LOADADDR(r24, paca) /* Get base vaddr of paca array */ - mulli r13,r3,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r13,r24 /* for this processor. */ + LOADADDR(r24, paca) /* Get base vaddr of paca array */ + mulli r13,r3,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r24 /* for this processor. */ - mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ - mr r24,r3 /* __secondary_start needs cpu# */ + mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ + mr r24,r3 /* __secondary_start needs cpu# */ 1: HMT_LOW - lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ - /* start. */ + lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ + /* start. */ sync - /* Create a temp kernel stack for use before relocation is on. */ - mr r1,r13 - addi r1,r1,PACAGUARD - addi r1,r1,0x1000 - subi r1,r1,STACK_FRAME_OVERHEAD + /* Create a temp kernel stack for use before relocation is on. */ + mr r1,r13 + addi r1,r1,PACAGUARD + addi r1,r1,0x1000 + subi r1,r1,STACK_FRAME_OVERHEAD - cmpi 0,r23,0 + cmpwi 0,r23,0 #ifdef CONFIG_SMP #ifdef SECONDARY_PROCESSORS bne .__secondary_start #endif #endif - b 1b /* Loop until told to go */ + b 1b /* Loop until told to go */ #ifdef CONFIG_PPC_ISERIES _GLOBAL(__start_initialization_iSeries) /* Clear out the BSS */ @@ -1389,13 +1335,13 @@ LOADADDR(r8,__bss_start) - sub r11,r11,r8 /* bss size */ - addi r11,r11,7 /* round up to an even double word */ - rldicl. r11,r11,61,3 /* shift right by 3 */ + sub r11,r11,r8 /* bss size */ + addi r11,r11,7 /* round up to an even double word */ + rldicl. r11,r11,61,3 /* shift right by 3 */ beq 4f addi r8,r8,-8 li r0,0 - mtctr r11 /* zero this many doublewords */ + mtctr r11 /* zero this many doublewords */ 3: stdu r0,8(r8) bdnz 3b 4: @@ -1422,10 +1368,10 @@ std r4,0(r9) /* set the naca pointer */ /* Get the pointer to the segment table */ - ld r6,PACA(r4) /* Get the base paca pointer */ + ld r6,PACA(r4) /* Get the base paca pointer */ ld r4,PACASTABVIRT(r6) - bl .iSeries_fixup_klimit + bl .iSeries_fixup_klimit /* relocation is on at this point */ @@ -1456,8 +1402,8 @@ bl .reloc_offset LOADADDR(r2,__toc_start) - addi r2,r2,0x4000 - addi r2,r2,0x4000 + addi r2,r2,0x4000 + addi r2,r2,0x4000 /* Relocate the TOC from a virt addr to a real addr */ sub r2,r2,r3 @@ -1498,33 +1444,33 @@ * unknown exception placeholders. * * Note: This process overwrites the OF exception vectors. - * r26 == relocation offset - * r27 == KERNELBASE + * r26 == relocation offset + * r27 == KERNELBASE */ bl .reloc_offset mr r26,r3 SET_REG_TO_CONST(r27,KERNELBASE) - li r3,0 /* target addr */ + li r3,0 /* target addr */ // XXX FIXME: Use phys returned by OF (r23) - sub r4,r27,r26 /* source addr */ - /* current address of _start */ - /* i.e. where we are running */ - /* the source addr */ + sub r4,r27,r26 /* source addr */ + /* current address of _start */ + /* i.e. where we are running */ + /* the source addr */ - LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ + LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 - li r6,0x100 /* Start offset, the first 0x100 */ - /* bytes were copied earlier. */ + li r6,0x100 /* Start offset, the first 0x100 */ + /* bytes were copied earlier. */ - bl .copy_and_flush /* copy the first n bytes */ - /* this includes the code being */ - /* executed here. */ + bl .copy_and_flush /* copy the first n bytes */ + /* this includes the code being */ + /* executed here. */ - LOADADDR(r0, 4f) /* Jump to the copy of this code */ - mtctr r0 /* that we just made/relocated */ + LOADADDR(r0, 4f) /* Jump to the copy of this code */ + mtctr r0 /* that we just made/relocated */ bctr 4: LOADADDR(r5,klimit) @@ -1546,23 +1492,23 @@ _GLOBAL(copy_and_flush) addi r5,r5,-8 addi r6,r6,-8 -4: li r0,16 /* Use the least common */ - /* denominator cache line */ - /* size. This results in */ - /* extra cache line flushes */ - /* but operation is correct. */ - /* Can't get cache line size */ - /* from NACA as it is being */ - /* moved too. */ +4: li r0,16 /* Use the least common */ + /* denominator cache line */ + /* size. This results in */ + /* extra cache line flushes */ + /* but operation is correct. */ + /* Can't get cache line size */ + /* from NACA as it is being */ + /* moved too. */ - mtctr r0 /* put # words/line in ctr */ -3: addi r6,r6,8 /* copy a cache line */ + mtctr r0 /* put # words/line in ctr */ +3: addi r6,r6,8 /* copy a cache line */ ldx r0,r6,r4 stdx r0,r6,r3 bdnz 3b - dcbst r6,r3 /* write it to memory */ + dcbst r6,r3 /* write it to memory */ sync - icbi r6,r3 /* flush the icache line */ + icbi r6,r3 /* flush the icache line */ cmpld 0,r6,r5 blt 4b sync @@ -1583,9 +1529,9 @@ * On entry: r13 == 'current' && last_task_used_math != 'current' */ _STATIC(load_up_fpu) - mfmsr r5 /* grab the current MSR */ + mfmsr r5 /* grab the current MSR */ ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ + mtmsrd r5 /* enable use of fpu now */ isync /* * For SMP, we don't do lazy FPU switching because it just gets too @@ -1594,9 +1540,9 @@ * */ #ifndef CONFIG_SMP - LOADBASE(r3,last_task_used_math) - ld r4,last_task_used_math@l(r3) - cmpi 0,r4,0 + ld r3,last_task_used_math@got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 beq 1f /* Save FP state to last_task_used_math's THREAD struct */ addi r4,r4,THREAD @@ -1606,8 +1552,8 @@ /* Disable FP for last_task_used_math */ ld r5,PT_REGS(r4) ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r20,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r20 + li r6,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r6 std r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: #endif /* CONFIG_SMP */ @@ -1615,15 +1561,16 @@ ld r4,PACACURRENT(r13) addi r5,r4,THREAD /* Get THREAD */ ld r4,THREAD_FPEXC_MODE(r5) - ori r23,r23,MSR_FP - or r23,r23,r4 + ori r12,r12,MSR_FP + or r12,r12,r4 + std r12,_MSR(r1) lfd fr0,THREAD_FPSCR(r5) mtfsf 0xff,fr0 REST_32FPRS(0, r5) #ifndef CONFIG_SMP /* Update last_task_used_math to 'current' */ subi r4,r5,THREAD /* Back to 'current' */ - std r4,last_task_used_math@l(r3) + std r4,0(r3) #endif /* CONFIG_SMP */ /* restore registers and return */ b fast_exception_return @@ -1633,10 +1580,10 @@ * Disable the FPU. */ _GLOBAL(disable_kernel_fp) - mfmsr r3 - rldicl r0,r3,(63-MSR_FP_LG),1 - rldicl r3,r0,(MSR_FP_LG+1),0 - mtmsrd r3 /* disable use of fpu now */ + mfmsr r3 + rldicl r0,r3,(63-MSR_FP_LG),1 + rldicl r3,r0,(MSR_FP_LG+1),0 + mtmsrd r3 /* disable use of fpu now */ isync blr @@ -1651,11 +1598,11 @@ ori r5,r5,MSR_FP mtmsrd r5 /* enable use of fpu now */ isync - cmpi 0,r3,0 + cmpdi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ ld r5,PT_REGS(r3) - cmpi 0,r5,0 + cmpdi 0,r5,0 SAVE_32FPRS(0, r3) mffs fr0 stfd fr0,THREAD_FPSCR(r3) @@ -1667,8 +1614,8 @@ 1: #ifndef CONFIG_SMP li r5,0 - LOADBASE(r4,last_task_used_math) - std r5,last_task_used_math@l(r4) + ld r4,last_task_used_math@got(r2) + std r5,0(r4) #endif /* CONFIG_SMP */ blr @@ -1685,9 +1632,9 @@ * On entry: r13 == 'current' && last_task_used_altivec != 'current' */ _STATIC(load_up_altivec) - mfmsr r5 /* grab the current MSR */ + mfmsr r5 /* grab the current MSR */ oris r5,r5,MSR_VEC@h - mtmsrd r5 /* enable use of VMX now */ + mtmsrd r5 /* enable use of VMX now */ isync /* @@ -1699,9 +1646,9 @@ * avoid saving all of the VREGs here... */ #ifndef CONFIG_SMP - LOADBASE(r3,last_task_used_altivec) - ld r4,last_task_used_altivec@l(r3) - cmpi 0,r4,0 + ld r3,last_task_used_altivec@got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 beq 1f /* Save VMX state to last_task_used_altivec's THREAD struct */ addi r4,r4,THREAD @@ -1712,8 +1659,8 @@ /* Disable VMX for last_task_used_altivec */ ld r5,PT_REGS(r4) ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r20,MSR_VEC@h - andc r4,r4,r20 + lis r6,MSR_VEC@h + andc r4,r4,r6 std r4,_MSR-STACK_FRAME_OVERHEAD(r5) 1: #endif /* CONFIG_SMP */ @@ -1723,7 +1670,7 @@ * all 1's */ mfspr r4,SPRN_VRSAVE - cmpi 0,r4,0 + cmpdi 0,r4,0 bne+ 1f li r4,-1 mtspr SPRN_VRSAVE,r4 @@ -1731,7 +1678,8 @@ /* enable use of VMX after return */ ld r4,PACACURRENT(r13) addi r5,r4,THREAD /* Get THREAD */ - oris r23,r23,MSR_VEC@h + oris r12,r12,MSR_VEC@h + std r12,_MSR(r1) li r4,1 li r10,THREAD_VSCR stw r4,THREAD_USED_VR(r5) @@ -1740,7 +1688,7 @@ #ifndef CONFIG_SMP /* Update last_task_used_math to 'current' */ subi r4,r5,THREAD /* Back to 'current' */ - std r4,last_task_used_altivec@l(r3) + std r4,0(r3) #endif /* CONFIG_SMP */ /* restore registers and return */ b fast_exception_return @@ -1750,10 +1698,10 @@ * Disable the VMX. */ _GLOBAL(disable_kernel_altivec) - mfmsr r3 - rldicl r0,r3,(63-MSR_VEC_LG),1 - rldicl r3,r0,(MSR_VEC_LG+1),0 - mtmsrd r3 /* disable use of VMX now */ + mfmsr r3 + rldicl r0,r3,(63-MSR_VEC_LG),1 + rldicl r3,r0,(MSR_VEC_LG+1),0 + mtmsrd r3 /* disable use of VMX now */ isync blr @@ -1768,11 +1716,11 @@ oris r5,r5,MSR_VEC@h mtmsrd r5 /* enable use of VMX now */ isync - cmpi 0,r3,0 + cmpdi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ ld r5,PT_REGS(r3) - cmpi 0,r5,0 + cmpdi 0,r5,0 SAVE_32VRS(0,r4,r3) mfvscr vr0 li r4,THREAD_VSCR @@ -1785,8 +1733,8 @@ 1: #ifndef CONFIG_SMP li r5,0 - LOADBASE(r4,last_task_used_altivec) - std r5,last_task_used_altivec@l(r4) + ld r4,last_task_used_altivec@got(r2) + std r5,0(r4) #endif /* CONFIG_SMP */ blr @@ -1830,16 +1778,16 @@ mtmsrd r3 /* RI on */ /* Set up a paca value for this processor. */ - LOADADDR(r4, paca) /* Get base vaddr of paca array */ + LOADADDR(r4, paca) /* Get base vaddr of paca array */ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r13,r4 /* for this processor. */ - mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ + add r13,r13,r4 /* for this processor. */ + mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ - /* Create a temp kernel stack for use before relocation is on. */ - mr r1,r13 - addi r1,r1,PACAGUARD - addi r1,r1,0x1000 - subi r1,r1,STACK_FRAME_OVERHEAD + /* Create a temp kernel stack for use before relocation is on. */ + mr r1,r13 + addi r1,r1,PACAGUARD + addi r1,r1,0x1000 + subi r1,r1,STACK_FRAME_OVERHEAD b .__secondary_start @@ -1853,7 +1801,7 @@ * 1. Processor number * 2. Segment table pointer (virtual address) * On entry the following are set: - * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries + * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries * r24 = cpu# (in Linux terms) * r13 = paca virtual address * SPRG3 = paca virtual address @@ -1864,8 +1812,8 @@ /* set up the TOC (virtual address) */ LOADADDR(r2,__toc_start) - addi r2,r2,0x4000 - addi r2,r2,0x4000 + addi r2,r2,0x4000 + addi r2,r2,0x4000 std r2,PACATOC(r13) li r6,0 @@ -1874,23 +1822,22 @@ #ifndef CONFIG_PPC_ISERIES /* Initialize the page table pointer register. */ LOADADDR(r6,_SDR1) - ld r6,0(r6) /* get the value of _SDR1 */ - mtspr SDR1,r6 /* set the htab location */ + ld r6,0(r6) /* get the value of _SDR1 */ + mtspr SDR1,r6 /* set the htab location */ #endif - /* Initialize the first segment table (or SLB) entry */ - ld r3,PACASTABVIRT(r13) /* get addr of segment table */ + /* Initialize the first segment table (or SLB) entry */ + ld r3,PACASTABVIRT(r13) /* get addr of segment table */ bl .stab_initialize - /* Initialize the kernel stack. Just a repeat for iSeries. */ + /* Initialize the kernel stack. Just a repeat for iSeries. */ LOADADDR(r3,current_set) - sldi r28,r24,3 /* get current_set[cpu#] */ + sldi r28,r24,3 /* get current_set[cpu#] */ ldx r1,r3,r28 - addi r1,r1,THREAD_SIZE - subi r1,r1,STACK_FRAME_OVERHEAD + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD std r1,PACAKSAVE(r13) - ld r3,PACASTABREAL(r13) /* get raddr of segment table */ - ori r4,r3,1 /* turn on valid bit */ + ld r3,PACASTABREAL(r13) /* get raddr of segment table */ + ori r4,r3,1 /* turn on valid bit */ #ifdef CONFIG_PPC_ISERIES li r0,-1 /* hypervisor call */ @@ -1900,23 +1847,23 @@ sc /* HvCall_setASR */ #else /* set the ASR */ - li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */ - lwz r3,PLATFORM(r3) /* r3 = platform flags */ + li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */ + lwz r3,PLATFORM(r3) /* r3 = platform flags */ cmpldi r3,PLATFORM_PSERIES_LPAR - bne 98f + bne 98f mfspr r3,PVR srwi r3,r3,16 - cmpwi r3,0x37 /* SStar */ + cmpwi r3,0x37 /* SStar */ beq 97f - cmpwi r3,0x36 /* IStar */ + cmpwi r3,0x36 /* IStar */ beq 97f - cmpwi r3,0x34 /* Pulsar */ + cmpwi r3,0x34 /* Pulsar */ bne 98f -97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ - HVSC /* Invoking hcall */ +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ + HVSC /* Invoking hcall */ b 99f -98: /* !(rpa hypervisor) || !(star) */ - mtasr r4 /* set the stab location */ +98: /* !(rpa hypervisor) || !(star) */ + mtasr r4 /* set the stab location */ 99: #endif li r7,0 @@ -1938,22 +1885,22 @@ */ _GLOBAL(start_secondary_prolog) li r3,0 - std r3,0(r1) /* Zero the stack frame pointer */ + std r3,0(r1) /* Zero the stack frame pointer */ bl .start_secondary #endif /* - * This subroutine clobbers r11, r12 and the LR + * This subroutine clobbers r11 and r12 */ _GLOBAL(enable_64b_mode) - mfmsr r11 /* grab the current MSR */ - li r12,1 - rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) - or r11,r11,r12 - li r12,1 - rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) - or r11,r11,r12 - mtmsrd r11 + mfmsr r11 /* grab the current MSR */ + li r12,1 + rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) + or r11,r11,r12 + li r12,1 + rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) + or r11,r11,r12 + mtmsrd r11 isync blr @@ -1970,30 +1917,30 @@ ori r6,r6,MSR_RI mtmsrd r6 /* RI on */ - /* setup the systemcfg pointer which is needed by *tab_initialize */ + /* setup the systemcfg pointer which is needed by *tab_initialize */ LOADADDR(r6,systemcfg) - sub r6,r6,r26 /* addr of the variable systemcfg */ + sub r6,r6,r26 /* addr of the variable systemcfg */ li r27,SYSTEMCFG_PHYS_ADDR - std r27,0(r6) /* set the value of systemcfg */ + std r27,0(r6) /* set the value of systemcfg */ - /* setup the naca pointer which is needed by *tab_initialize */ + /* setup the naca pointer which is needed by *tab_initialize */ LOADADDR(r6,naca) - sub r6,r6,r26 /* addr of the variable naca */ + sub r6,r6,r26 /* addr of the variable naca */ li r27,NACA_PHYS_ADDR - std r27,0(r6) /* set the value of naca */ + std r27,0(r6) /* set the value of naca */ #ifdef CONFIG_HMT /* Start up the second thread on cpu 0 */ mfspr r3,PVR srwi r3,r3,16 - cmpwi r3,0x34 /* Pulsar */ + cmpwi r3,0x34 /* Pulsar */ beq 90f - cmpwi r3,0x36 /* Icestar */ + cmpwi r3,0x36 /* Icestar */ beq 90f - cmpwi r3,0x37 /* SStar */ + cmpwi r3,0x37 /* SStar */ beq 90f - b 91f /* HMT not supported */ -90: li r3,0 + b 91f /* HMT not supported */ +90: li r3,0 bl .hmt_start_secondary 91: #endif @@ -2008,7 +1955,7 @@ li r3,1 LOADADDR(r5,__secondary_hold_spinloop) tophys(r4,r5) - std r3,0(r4) + std r3,0(r4) #endif /* The following gets the stack and TOC set up with the regs */ @@ -2027,8 +1974,8 @@ /* set up the TOC (physical address) */ LOADADDR(r2,__toc_start) - addi r2,r2,0x4000 - addi r2,r2,0x4000 + addi r2,r2,0x4000 + addi r2,r2,0x4000 sub r2,r2,r26 LOADADDR(r3,cpu_specs) @@ -2038,44 +1985,44 @@ mr r5,r26 bl .identify_cpu - /* Get the pointer to the segment table which is used by */ - /* stab_initialize */ + /* Get the pointer to the segment table which is used by */ + /* stab_initialize */ LOADADDR(r27, boot_cpuid) sub r27,r27,r26 lwz r27,0(r27) - LOADADDR(r24, paca) /* Get base vaddr of paca array */ - mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r13,r24 /* for this processor. */ - sub r13,r13,r26 /* convert to physical addr */ + LOADADDR(r24, paca) /* Get base vaddr of paca array */ + mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r24 /* for this processor. */ + sub r13,r13,r26 /* convert to physical addr */ mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ ld r3,PACASTABREAL(r13) - ori r4,r3,1 /* turn on valid bit */ + ori r4,r3,1 /* turn on valid bit */ /* set the ASR */ li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */ - lwz r3,PLATFORM(r3) /* r3 = platform flags */ + lwz r3,PLATFORM(r3) /* r3 = platform flags */ cmpldi r3,PLATFORM_PSERIES_LPAR - bne 98f + bne 98f mfspr r3,PVR srwi r3,r3,16 - cmpwi r3,0x37 /* SStar */ + cmpwi r3,0x37 /* SStar */ beq 97f - cmpwi r3,0x36 /* IStar */ + cmpwi r3,0x36 /* IStar */ beq 97f - cmpwi r3,0x34 /* Pulsar */ + cmpwi r3,0x34 /* Pulsar */ bne 98f -97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ - HVSC /* Invoking hcall */ - b 99f -98: /* !(rpa hypervisor) || !(star) */ - mtasr r4 /* set the stab location */ +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ + HVSC /* Invoking hcall */ + b 99f +98: /* !(rpa hypervisor) || !(star) */ + mtasr r4 /* set the stab location */ 99: mfspr r6,SPRG3 - ld r3,PACASTABREAL(r6) /* restore r3 for stab_initialize */ + ld r3,PACASTABREAL(r6) /* restore r3 for stab_initialize */ - /* Initialize an initial memory mapping and turn on relocation. */ + /* Initialize an initial memory mapping and turn on relocation. */ bl .stab_initialize bl .htab_initialize @@ -2083,7 +2030,7 @@ lwz r3,PLATFORM(r3) /* r3 = platform flags */ /* Test if bit 0 is set (LPAR bit) */ andi. r3,r3,0x1 - bne 98f + bne 98f LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ @@ -2112,8 +2059,8 @@ /* set up the TOC */ LOADADDR(r2,__toc_start) - addi r2,r2,0x4000 - addi r2,r2,0x4000 + addi r2,r2,0x4000 + addi r2,r2,0x4000 /* Apply the CPUs-specific fixups (nop out sections not relevant * to this CPU @@ -2129,14 +2076,14 @@ /* setup the naca pointer */ LOADADDR(r9,naca) SET_REG_TO_CONST(r8, NACA_VIRT_ADDR) - std r8,0(r9) /* set the value of the naca ptr */ + std r8,0(r9) /* set the value of the naca ptr */ LOADADDR(r26, boot_cpuid) lwz r26,0(r26) - LOADADDR(r24, paca) /* Get base vaddr of paca array */ - mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r13,r24 /* for this processor. */ + LOADADDR(r24, paca) /* Get base vaddr of paca array */ + mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r24 /* for this processor. */ mtspr SPRG3,r13 /* ptr to current */ @@ -2144,7 +2091,6 @@ std r4,PACACURRENT(r13) std r2,PACATOC(r13) - li r5,0 std r1,PACAKSAVE(r13) /* Restore the parms passed in from the bootloader. */ @@ -2176,11 +2122,11 @@ LOADADDR(r5, hmt_thread_data) mfspr r7,PVR srwi r7,r7,16 - cmpwi r7,0x34 /* Pulsar */ + cmpwi r7,0x34 /* Pulsar */ beq 90f - cmpwi r7,0x36 /* Icestar */ + cmpwi r7,0x36 /* Icestar */ beq 91f - cmpwi r7,0x37 /* SStar */ + cmpwi r7,0x37 /* SStar */ beq 91f b 101f 90: mfspr r6,PIR @@ -2214,32 +2160,32 @@ 104: addi r7,r7,4 lwzx r9,r5,r7 - mr r24,r9 + mr r24,r9 101: #endif - mr r3,r24 - b .pseries_secondary_smp_init + mr r3,r24 + b .pseries_secondary_smp_init #ifdef CONFIG_HMT _GLOBAL(hmt_start_secondary) LOADADDR(r4,__hmt_secondary_hold) clrldi r4,r4,4 - mtspr NIADORM, r4 - mfspr r4, MSRDORM - li r5, -65 - and r4, r4, r5 - mtspr MSRDORM, r4 + mtspr NIADORM, r4 + mfspr r4, MSRDORM + li r5, -65 + and r4, r4, r5 + mtspr MSRDORM, r4 lis r4,0xffef ori r4,r4,0x7403 mtspr TSC, r4 li r4,0x1f4 mtspr TST, r4 - mfspr r4, HID0 - ori r4, r4, 0x1 - mtspr HID0, r4 - mfspr r4, CTRLF - oris r4, r4, 0x40 - mtspr CTRLT, r4 + mfspr r4, HID0 + ori r4, r4, 0x1 + mtspr HID0, r4 + mfspr r4, CTRLF + oris r4, r4, 0x40 + mtspr CTRLT, r4 blr #endif @@ -2249,7 +2195,7 @@ * which is page-aligned. */ .data - .align 12 + .align 12 .globl sdata sdata: .globl empty_zero_page @@ -2267,7 +2213,7 @@ /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */ .globl stab_array stab_array: - .space 4096 * 48 + .space 4096 * 48 /* * This space gets a copy of optional info passed to us by the bootstrap @@ -2275,4 +2221,4 @@ */ .globl cmd_line cmd_line: - .space 512 /* COMMAND_LINE_SIZE */ + .space COMMAND_LINE_SIZE diff -Nru a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c --- a/arch/ppc64/kernel/iSeries_setup.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/iSeries_setup.c 2004-06-26 17:09:19 -07:00 @@ -357,15 +357,14 @@ HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256, HvLpDma_Direction_RemoteToLocal); - p = q = cmd_line + 255; - while (p > cmd_line) { - if ((*p == 0) || (*p == ' ') || (*p == '\n')) - --p; - else + p = cmd_line; + q = cmd_line + 255; + while( p < q ) { + if (!*p || *p == '\n') break; + ++p; } - if (p < q) - *(p + 1) = 0; + *p = 0; if (strstr(cmd_line, "dprofile=")) { for (q = cmd_line; (p = strstr(q, "dprofile=")) != 0; ) { diff -Nru a/arch/ppc64/kernel/init_task.c b/arch/ppc64/kernel/init_task.c --- a/arch/ppc64/kernel/init_task.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc64/kernel/init_task.c 2004-06-26 17:09:16 -07:00 @@ -4,6 +4,7 @@ #include #include #include +#include #include static struct fs_struct init_fs = INIT_FS; diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c --- a/arch/ppc64/kernel/irq.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ppc64/kernel/irq.c 2004-06-26 17:09:17 -07:00 @@ -206,7 +206,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = dev_id; action->next = NULL; @@ -738,7 +738,6 @@ irq_desc_t *desc = get_irq_desc(irq); int ret; cpumask_t new_value, tmp; - cpumask_t allcpus = CPU_MASK_ALL; if (!desc->handler->set_affinity) return -EIO; @@ -753,7 +752,7 @@ * NR_CPUS == 32 and cpumask is a long), so we mask it here to * be consistent. */ - cpus_and(new_value, new_value, allcpus); + cpus_and(new_value, new_value, CPU_MASK_ALL); /* * Grab lock here so cpu_online_map can't change, and also diff -Nru a/arch/ppc64/kernel/mf_proc.c b/arch/ppc64/kernel/mf_proc.c --- a/arch/ppc64/kernel/mf_proc.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ppc64/kernel/mf_proc.c 2004-06-26 17:09:17 -07:00 @@ -25,33 +25,26 @@ { int len = count; char *p; - + + if (off) { + *eof = 1; + return 0; + } + len = mf_getCmdLine(page, &len, (u64)data); - p = page + len - 1; - while (p > page) { - if ((*p == 0) || (*p == ' ')) - --p; - else + p = page; + while (len < (count - 1)) { + if (!*p || *p == '\n') break; + p++; + len++; } - if (*p != '\n') { - ++p; - *p = '\n'; - } - ++p; + *p = '\n'; + p++; *p = 0; - len = p - page; - - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else - len = count; - *start = page + off; - return len; + + return p - page; } #if 0 diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S --- a/arch/ppc64/kernel/misc.S 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc64/kernel/misc.S 2004-06-26 17:09:20 -07:00 @@ -85,16 +85,17 @@ cmpw 0,r3,r5 beqlr /* are we enabling interrupts? */ - cmpi 0,r3,0 + cmpdi 0,r3,0 stb r3,PACAPROCENABLED(r13) beqlr /* Check pending interrupts */ /* A decrementer, IPI or PMC interrupt may have occurred * while we were in the hypervisor (which enables) */ - CHECKANYINT(r4,r5) + ld r4,PACALPPACA+LPPACAANYINT(r13) + cmpdi r4,0 beqlr - /* + /* * Handle pending interrupts in interrupt context */ li r0,0x5555 @@ -608,7 +609,7 @@ _GLOBAL(sys_call_table32) .llong .sys_restart_syscall /* 0 */ .llong .sys_exit - .llong .sys_fork + .llong .ppc_fork .llong .sys_read .llong .sys_write .llong .sys32_open /* 5 */ @@ -678,7 +679,7 @@ .llong .sys32_ssetmask .llong .sys_setreuid /* 70 */ .llong .sys_setregid - .llong .sys32_sigsuspend + .llong .ppc32_sigsuspend .llong .compat_sys_sigpending .llong .sys32_sethostname .llong .compat_sys_setrlimit /* 75 */ @@ -726,7 +727,7 @@ .llong .sys32_ipc .llong .sys_fsync .llong .ppc32_sigreturn - .llong .sys_clone /* 120 */ + .llong .ppc_clone /* 120 */ .llong .sys32_setdomainname .llong .ppc64_newuname .llong .sys_ni_syscall /* old modify_ldt syscall */ @@ -784,7 +785,7 @@ .llong .sys32_rt_sigpending /* 175 */ .llong .sys32_rt_sigtimedwait .llong .sys32_rt_sigqueueinfo - .llong .sys32_rt_sigsuspend + .llong .ppc32_rt_sigsuspend .llong .sys32_pread64 .llong .sys32_pwrite64 /* 180 */ .llong .sys_chown @@ -795,7 +796,7 @@ .llong .sys32_sendfile .llong .sys_ni_syscall /* reserved for streams1 */ .llong .sys_ni_syscall /* reserved for streams2 */ - .llong .sys_vfork + .llong .ppc_vfork .llong .compat_sys_getrlimit /* 190 */ .llong .sys32_readahead .llong .sys32_mmap2 @@ -880,7 +881,7 @@ _GLOBAL(sys_call_table) .llong .sys_restart_syscall /* 0 */ .llong .sys_exit - .llong .sys_fork + .llong .ppc_fork .llong .sys_read .llong .sys_write .llong .sys_open /* 5 */ @@ -998,7 +999,7 @@ .llong .sys_ipc .llong .sys_fsync .llong .sys_ni_syscall - .llong .sys_clone /* 120 */ + .llong .ppc_clone /* 120 */ .llong .sys_setdomainname .llong .ppc64_newuname .llong .sys_ni_syscall /* old modify_ldt syscall */ @@ -1056,7 +1057,7 @@ .llong .sys_rt_sigpending /* 175 */ .llong .sys_rt_sigtimedwait .llong .sys_rt_sigqueueinfo - .llong .sys_rt_sigsuspend + .llong .ppc64_rt_sigsuspend .llong .sys_pread64 .llong .sys_pwrite64 /* 180 */ .llong .sys_chown @@ -1067,7 +1068,7 @@ .llong .sys_sendfile64 .llong .sys_ni_syscall /* reserved for streams1 */ .llong .sys_ni_syscall /* reserved for streams2 */ - .llong .sys_vfork + .llong .ppc_vfork .llong .sys_getrlimit /* 190 */ .llong .sys_readahead .llong .sys_ni_syscall /* 32bit only mmap2 */ diff -Nru a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c --- a/arch/ppc64/kernel/open_pic.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/open_pic.c 2004-06-26 17:09:18 -07:00 @@ -591,7 +591,7 @@ void openpic_init_processor(u_int cpumask) { openpic_write(&OpenPIC->Global.Processor_Initialization, - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } #ifdef CONFIG_SMP @@ -625,7 +625,7 @@ CHECK_THIS_CPU; check_arg_ipi(ipi); openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } void openpic_request_IPIs(void) @@ -711,7 +711,7 @@ { check_arg_timer(timer); openpic_write(&OpenPIC->Global.Timer[timer].Destination, - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } @@ -844,7 +844,7 @@ cpumask_t tmp; cpus_and(tmp, cpumask, cpu_online_map); - openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_coerce(tmp))); + openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_addr(tmp)[0])); } #ifdef CONFIG_SMP diff -Nru a/arch/ppc64/kernel/pSeries_nvram.c b/arch/ppc64/kernel/pSeries_nvram.c --- a/arch/ppc64/kernel/pSeries_nvram.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc64/kernel/pSeries_nvram.c 2004-06-26 17:09:20 -07:00 @@ -37,7 +37,8 @@ static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) { unsigned int i; - unsigned long len, done; + unsigned long len; + int done; unsigned long flags; char *p = buf; @@ -80,7 +81,8 @@ static ssize_t pSeries_nvram_write(char *buf, size_t count, loff_t *index) { unsigned int i; - unsigned long len, done; + unsigned long len; + int done; unsigned long flags; const char *p = buf; diff -Nru a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c --- a/arch/ppc64/kernel/pSeries_pci.c 2004-06-26 17:09:21 -07:00 +++ b/arch/ppc64/kernel/pSeries_pci.c 2004-06-26 17:09:21 -07:00 @@ -62,7 +62,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) { - unsigned long returnval = ~0L; + int returnval = -1; unsigned long buid, addr; int ret; @@ -72,7 +72,8 @@ addr = (dn->busno << 16) | (dn->devfn << 8) | where; buid = dn->phb->buid; if (buid) { - ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, addr, buid >> 32, buid & 0xffffffff, size); + ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, + addr, buid >> 32, buid & 0xffffffff, size); } else { ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); } diff -Nru a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c --- a/arch/ppc64/kernel/pacaData.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/pacaData.c 2004-06-26 17:09:19 -07:00 @@ -62,8 +62,6 @@ .xDesc = 0xd397d9e2, /* "LpRS" */ \ .xSize = sizeof(struct ItLpRegSave) \ }, \ - .exception_sp = \ - (&paca[number].exception_stack[0]) - EXC_FRAME_SIZE, \ } struct paca_struct paca[] __page_aligned = { diff -Nru a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c --- a/arch/ppc64/kernel/ppc_ksyms.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc64/kernel/ppc_ksyms.c 2004-06-26 17:09:16 -07:00 @@ -47,10 +47,7 @@ extern int do_signal(sigset_t *, struct pt_regs *); -int abs(int); - EXPORT_SYMBOL(do_signal); -EXPORT_SYMBOL(sys_ioctl); EXPORT_SYMBOL(isa_io_base); EXPORT_SYMBOL(pci_io_base); @@ -157,8 +154,6 @@ EXPORT_SYMBOL_NOVERS(memscan); EXPORT_SYMBOL_NOVERS(memcmp); EXPORT_SYMBOL_NOVERS(memchr); - -EXPORT_SYMBOL(abs); EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(irq_desc); diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c --- a/arch/ppc64/kernel/process.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/process.c 2004-06-26 17:09:18 -07:00 @@ -65,8 +65,43 @@ .page_table_lock = SPIN_LOCK_UNLOCKED, }; +/* + * Make sure the floating-point register state in the + * the thread_struct is up to date for task tsk. + */ +void flush_fp_to_thread(struct task_struct *tsk) +{ + if (tsk->thread.regs) { + /* + * We need to disable preemption here because if we didn't, + * another process could get scheduled after the regs->msr + * test but before we have finished saving the FP registers + * to the thread_struct. That process could take over the + * FPU, and then when we get scheduled again we would store + * bogus values for the remaining FP registers. + */ + preempt_disable(); + if (tsk->thread.regs->msr & MSR_FP) { +#ifdef CONFIG_SMP + /* + * This should only ever be called for current or + * for a stopped child process. Since we save away + * the FP register state on context switch on SMP, + * there is something wrong if a stopped child appears + * to still have its FP state in the CPU registers. + */ + BUG_ON(tsk != current); +#endif + giveup_fpu(current); + } + preempt_enable(); + } +} + void enable_kernel_fp(void) { + WARN_ON(preemptible()); + #ifdef CONFIG_SMP if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) giveup_fpu(current); @@ -80,12 +115,9 @@ int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) { - struct pt_regs *regs = tsk->thread.regs; - - if (!regs) + if (!tsk->thread.regs) return 0; - if (tsk == current && (regs->msr & MSR_FP)) - giveup_fpu(current); + flush_fp_to_thread(current); memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs)); @@ -96,6 +128,8 @@ void enable_kernel_altivec(void) { + WARN_ON(preemptible()); + #ifdef CONFIG_SMP if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) giveup_altivec(current); @@ -107,10 +141,29 @@ } EXPORT_SYMBOL(enable_kernel_altivec); +/* + * Make sure the VMX/Altivec register state in the + * the thread_struct is up to date for task tsk. + */ +void flush_altivec_to_thread(struct task_struct *tsk) +{ +#ifdef CONFIG_ALTIVEC + if (tsk->thread.regs) { + preempt_disable(); + if (tsk->thread.regs->msr & MSR_VEC) { +#ifdef CONFIG_SMP + BUG_ON(tsk != current); +#endif + giveup_altivec(current); + } + preempt_enable(); + } +#endif +} + int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) { - if (regs->msr & MSR_VEC) - giveup_altivec(current); + flush_altivec_to_thread(current); memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs)); return 1; } @@ -166,6 +219,7 @@ void show_regs(struct pt_regs * regs) { int i; + unsigned long trap; printk("NIP: %016lX XER: %016lX LR: %016lX\n", regs->nip, regs->xer, regs->link); @@ -176,7 +230,8 @@ regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, regs->msr&MSR_IR ? 1 : 0, regs->msr&MSR_DR ? 1 : 0); - if (regs->trap == 0x300 || regs->trap == 0x380 || regs->trap == 0x600) + trap = TRAP(regs); + if (trap == 0x300 || trap == 0x380 || trap == 0x600) printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr); printk("TASK: %p[%d] '%s' THREAD: %p", current, current->pid, current->comm, current->thread_info); @@ -191,6 +246,8 @@ } printk("%016lX ", regs->gpr[i]); + if (i == 13 && !FULL_REGS(regs)) + break; } printk("\n"); /* @@ -245,16 +302,8 @@ */ void prepare_to_copy(struct task_struct *tsk) { - struct pt_regs *regs = tsk->thread.regs; - - if (regs == NULL) - return; - if (regs->msr & MSR_FP) - giveup_fpu(current); -#ifdef CONFIG_ALTIVEC - if (regs->msr & MSR_VEC) - giveup_altivec(current); -#endif /* CONFIG_ALTIVEC */ + flush_fp_to_thread(current); + flush_altivec_to_thread(current); } /* @@ -439,12 +488,8 @@ error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - if (regs->msr & MSR_FP) - giveup_fpu(current); -#ifdef CONFIG_ALTIVEC - if (regs->msr & MSR_VEC) - giveup_altivec(current); -#endif /* CONFIG_ALTIVEC */ + flush_fp_to_thread(current); + flush_altivec_to_thread(current); error = do_execve(filename, (char __user * __user *) a1, (char __user * __user *) a2, regs); diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c --- a/arch/ppc64/kernel/prom.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/prom.c 2004-06-26 17:09:19 -07:00 @@ -15,9 +15,7 @@ * 2 of the License, or (at your option) any later version. */ -#if 0 -#define DEBUG_PROM -#endif +#undef DEBUG_PROM #include #include @@ -91,15 +89,17 @@ */ -#define PROM_BUG() do { \ - prom_print(RELOC("kernel BUG at ")); \ - prom_print(RELOC(__FILE__)); \ - prom_print(RELOC(":")); \ - prom_print_hex(__LINE__); \ - prom_print(RELOC("!\n")); \ - __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \ +#define PROM_BUG() do { \ + prom_printf("kernel BUG at %s line 0x%x!\n", \ + RELOC(__FILE__), __LINE__); \ + __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \ } while (0) +#ifdef DEBUG_PROM +#define prom_debug(x...) prom_printf(x) +#else +#define prom_debug(x...) +#endif struct pci_reg_property { @@ -178,29 +178,36 @@ char testString[] = "LINUX\n"; +/* + * This are used in calls to call_prom. The 4th and following + * arguments to call_prom should be 32-bit values. 64 bit values + * are truncated to 32 bits (and fortunately don't get interpreted + * as two arguments). + */ +#define ADDR(x) (u32) ((unsigned long)(x) - offset) /* This is the one and *ONLY* place where we actually call open * firmware from, since we need to make sure we're running in 32b * mode when we do. We switch back to 64b mode upon return. */ -#define PROM_ERROR (0x00000000fffffffful) +#define PROM_ERROR (-1) -static unsigned long __init call_prom(const char *service, int nargs, int nret, ...) +static int __init call_prom(const char *service, int nargs, int nret, ...) { int i; unsigned long offset = reloc_offset(); struct prom_t *_prom = PTRRELOC(&prom); va_list list; - _prom->args.service = (u32)LONG_LSW(service); + _prom->args.service = ADDR(service); _prom->args.nargs = nargs; _prom->args.nret = nret; _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]); va_start(list, nret); - for (i=0; i < nargs ;i++) - _prom->args.args[i] = (prom_arg_t)LONG_LSW(va_arg(list, unsigned long)); + for (i=0; i < nargs; i++) + _prom->args.args[i] = va_arg(list, prom_arg_t); va_end(list); for (i=0; i < nret ;i++) @@ -208,7 +215,7 @@ enter_prom(&_prom->args); - return (unsigned long)((nret > 0) ? _prom->args.rets[0] : 0); + return (nret > 0)? _prom->args.rets[0]: 0; } @@ -225,21 +232,21 @@ for (q = p; *q != 0 && *q != '\n'; ++q) ; if (q > p) - call_prom(RELOC("write"), 3, 1, _prom->stdout, - p, q - p); - if (*q != 0) { - ++q; - call_prom(RELOC("write"), 3, 1, _prom->stdout, - RELOC("\r\n"), 2); - } + call_prom("write", 3, 1, _prom->stdout, p, q - p); + if (*q == 0) + break; + ++q; + call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2); } } static void __init prom_print_hex(unsigned long val) { + unsigned long offset = reloc_offset(); int i, nibbles = sizeof(val)*2; char buf[sizeof(val)*2+1]; + struct prom_t *_prom = PTRRELOC(&prom); for (i = nibbles-1; i >= 0; i--) { buf[i] = (val & 0xf) + '0'; @@ -248,24 +255,58 @@ val >>= 4; } buf[nibbles] = '\0'; - prom_print(buf); + call_prom("write", 3, 1, _prom->stdout, buf, nibbles); } -static void __init prom_print_nl(void) +static void __init prom_printf(const char *format, ...) { unsigned long offset = reloc_offset(); - prom_print(RELOC("\n")); + const char *p, *q, *s; + va_list args; + unsigned long v; + struct prom_t *_prom = PTRRELOC(&prom); + + va_start(args, format); + for (p = PTRRELOC(format); *p != 0; p = q) { + for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q) + ; + if (q > p) + call_prom("write", 3, 1, _prom->stdout, p, q - p); + if (*q == 0) + break; + if (*q == '\n') { + ++q; + call_prom("write", 3, 1, _prom->stdout, + ADDR("\r\n"), 2); + continue; + } + ++q; + if (*q == 0) + break; + switch (*q) { + case 's': + ++q; + s = va_arg(args, const char *); + prom_print(s); + break; + case 'x': + ++q; + v = va_arg(args, unsigned long); + prom_print_hex(v); + break; + } + } } -static void __init prom_panic(const char *reason) +static void __init __attribute__((noreturn)) prom_panic(const char *reason) { unsigned long offset = reloc_offset(); - prom_print(reason); + prom_print(PTRRELOC(reason)); /* ToDo: should put up an SRC here */ - call_prom(RELOC("exit"), 0, 0); + call_prom("exit", 0, 0); for (;;) /* should never get here */ ; @@ -275,21 +316,28 @@ static int __init prom_next_node(phandle *nodep) { phandle node; - unsigned long offset = reloc_offset(); if ((node = *nodep) != 0 - && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0) + && (*nodep = call_prom("child", 1, 1, node)) != 0) return 1; - if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0) + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) return 1; for (;;) { - if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0) + if ((node = call_prom("parent", 1, 1, node)) == 0) return 0; - if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0) + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) return 1; } } +static int __init prom_getprop(phandle node, const char *pname, + void *value, size_t valuelen) +{ + unsigned long offset = reloc_offset(); + + return call_prom("getprop", 4, 1, node, ADDR(pname), + (u32)(unsigned long) value, (u32) valuelen); +} static void __init prom_initialize_naca(void) { @@ -302,16 +350,13 @@ struct systemcfg *_systemcfg = RELOC(systemcfg); /* NOTE: _naca->debug_switch is already initialized. */ -#ifdef DEBUG_PROM - prom_print(RELOC("prom_initialize_naca: start...\n")); -#endif + prom_debug("prom_initialize_naca: start...\n"); _naca->pftSize = 0; /* ilog2 of htab size. computed below. */ for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (!strcmp(type, RELOC("cpu"))) { num_cpus += 1; @@ -321,37 +366,30 @@ */ if ( num_cpus == 1 ) { u32 size, lsize; + const char *dc, *ic; - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("d-cache-size"), - &size, sizeof(size)); - - if (_systemcfg->platform == PLATFORM_POWERMAC) - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("d-cache-block-size"), - &lsize, sizeof(lsize)); - else - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("d-cache-line-size"), - &lsize, sizeof(lsize)); + if (_systemcfg->platform == PLATFORM_POWERMAC){ + dc = "d-cache-block-size"; + ic = "i-cache-block-size"; + } else { + dc = "d-cache-line-size"; + ic = "i-cache-line-size"; + } + + prom_getprop(node, "d-cache-size", + &size, sizeof(size)); + + prom_getprop(node, dc, &lsize, sizeof(lsize)); _systemcfg->dCacheL1Size = size; _systemcfg->dCacheL1LineSize = lsize; _naca->dCacheL1LogLineSize = __ilog2(lsize); _naca->dCacheL1LinesPerPage = PAGE_SIZE/lsize; - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("i-cache-size"), - &size, sizeof(size)); - - if (_systemcfg->platform == PLATFORM_POWERMAC) - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("i-cache-block-size"), - &lsize, sizeof(lsize)); - else - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("i-cache-line-size"), - &lsize, sizeof(lsize)); + prom_getprop(node, "i-cache-size", + &size, sizeof(size)); + + prom_getprop(node, ic, &lsize, sizeof(lsize)); _systemcfg->iCacheL1Size = size; _systemcfg->iCacheL1LineSize = lsize; @@ -360,9 +398,8 @@ if (_systemcfg->platform == PLATFORM_PSERIES_LPAR) { u32 pft_size[2]; - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("ibm,pft-size"), - &pft_size, sizeof(pft_size)); + prom_getprop(node, "ibm,pft-size", + &pft_size, sizeof(pft_size)); /* pft_size[0] is the NUMA CEC cookie */ _naca->pftSize = pft_size[1]; } @@ -375,24 +412,21 @@ if (_systemcfg->platform == PLATFORM_POWERMAC) continue; type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, - RELOC("ibm,aix-loc"), type, sizeof(type)); + prom_getprop(node, "ibm,aix-loc", type, sizeof(type)); if (strcmp(type, RELOC("S1"))) continue; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)); + prom_getprop(node, "reg", ®, sizeof(reg)); - isa = call_prom(RELOC("parent"), 1, 1, node); + isa = call_prom("parent", 1, 1, node); if (!isa) PROM_BUG(); - pci = call_prom(RELOC("parent"), 1, 1, isa); + pci = call_prom("parent", 1, 1, isa); if (!pci) PROM_BUG(); - call_prom(RELOC("getprop"), 4, 1, pci, RELOC("ranges"), - &ranges, sizeof(ranges)); + prom_getprop(pci, "ranges", &ranges, sizeof(ranges)); if ( _prom->encode_phys_size == 32 ) _naca->serialPortAddr = ranges.pci32.phys+reg.address; @@ -410,25 +444,23 @@ _naca->interrupt_controller = IC_INVALID; for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("name"), - type, sizeof(type)); + prom_getprop(node, "name", type, sizeof(type)); if (strcmp(type, RELOC("interrupt-controller"))) continue; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"), - type, sizeof(type)); + prom_getprop(node, "compatible", type, sizeof(type)); if (strstr(type, RELOC("open-pic"))) _naca->interrupt_controller = IC_OPEN_PIC; else if (strstr(type, RELOC("ppc-xicp"))) _naca->interrupt_controller = IC_PPC_XIC; else - prom_print(RELOC("prom: failed to recognize" - " interrupt-controller\n")); + prom_printf("prom: failed to recognize" + " interrupt-controller\n"); break; } } if (_naca->interrupt_controller == IC_INVALID) { - prom_print(RELOC("prom: failed to find interrupt-controller\n")); + prom_printf("prom: failed to find interrupt-controller\n"); PROM_BUG(); } @@ -454,7 +486,7 @@ } if (_naca->pftSize == 0) { - prom_print(RELOC("prom: failed to compute pftSize!\n")); + prom_printf("prom: failed to compute pftSize!\n"); PROM_BUG(); } @@ -464,41 +496,23 @@ _systemcfg->version.minor = SYSTEMCFG_MINOR; _systemcfg->processor = _get_PVR(); -#ifdef DEBUG_PROM - prom_print(RELOC("systemcfg->processorCount = 0x")); - prom_print_hex(_systemcfg->processorCount); - prom_print_nl(); - - prom_print(RELOC("systemcfg->physicalMemorySize = 0x")); - prom_print_hex(_systemcfg->physicalMemorySize); - prom_print_nl(); - - prom_print(RELOC("naca->pftSize = 0x")); - prom_print_hex(_naca->pftSize); - prom_print_nl(); - - prom_print(RELOC("systemcfg->dCacheL1LineSize = 0x")); - prom_print_hex(_systemcfg->dCacheL1LineSize); - prom_print_nl(); - - prom_print(RELOC("systemcfg->iCacheL1LineSize = 0x")); - prom_print_hex(_systemcfg->iCacheL1LineSize); - prom_print_nl(); - - prom_print(RELOC("naca->serialPortAddr = 0x")); - prom_print_hex(_naca->serialPortAddr); - prom_print_nl(); - - prom_print(RELOC("naca->interrupt_controller = 0x")); - prom_print_hex(_naca->interrupt_controller); - prom_print_nl(); - - prom_print(RELOC("systemcfg->platform = 0x")); - prom_print_hex(_systemcfg->platform); - prom_print_nl(); - - prom_print(RELOC("prom_initialize_naca: end...\n")); -#endif + prom_debug("systemcfg->processorCount = 0x%x\n", + _systemcfg->processorCount); + prom_debug("systemcfg->physicalMemorySize = 0x%x\n", + _systemcfg->physicalMemorySize); + prom_debug("naca->pftSize = 0x%x\n", + _naca->pftSize); + prom_debug("systemcfg->dCacheL1LineSize = 0x%x\n", + _systemcfg->dCacheL1LineSize); + prom_debug("systemcfg->iCacheL1LineSize = 0x%x\n", + _systemcfg->iCacheL1LineSize); + prom_debug("naca->serialPortAddr = 0x%x\n", + _naca->serialPortAddr); + prom_debug("naca->interrupt_controller = 0x%x\n", + _naca->interrupt_controller); + prom_debug("systemcfg->platform = 0x%x\n", + _systemcfg->platform); + prom_debug("prom_initialize_naca: end...\n"); } @@ -512,9 +526,7 @@ opt = strstr(RELOC(cmd_line), RELOC("iommu=")); if (opt) { - prom_print(RELOC("opt is:")); - prom_print(opt); - prom_print(RELOC("\n")); + prom_printf("opt is:%s\n", opt); opt += 6; while (*opt && *opt == ' ') opt++; @@ -527,7 +539,7 @@ #ifndef CONFIG_PMAC_DART if (_systemcfg->platform == PLATFORM_POWERMAC) { RELOC(ppc64_iommu_off) = 1; - prom_print(RELOC("DART disabled on PowerMac !\n")); + prom_printf("DART disabled on PowerMac !\n"); } #endif } @@ -539,46 +551,31 @@ unsigned long offset = reloc_offset(); struct lmb *_lmb = PTRRELOC(&lmb); - prom_print(RELOC("\nprom_dump_lmb:\n")); - prom_print(RELOC(" memory.cnt = 0x")); - prom_print_hex(_lmb->memory.cnt); - prom_print_nl(); - prom_print(RELOC(" memory.size = 0x")); - prom_print_hex(_lmb->memory.size); - prom_print_nl(); + prom_printf("\nprom_dump_lmb:\n"); + prom_printf(" memory.cnt = 0x%x\n", + _lmb->memory.cnt); + prom_printf(" memory.size = 0x%x\n", + _lmb->memory.size); for (i=0; i < _lmb->memory.cnt ;i++) { - prom_print(RELOC(" memory.region[0x")); - prom_print_hex(i); - prom_print(RELOC("].base = 0x")); - prom_print_hex(_lmb->memory.region[i].base); - prom_print_nl(); - prom_print(RELOC(" .physbase = 0x")); - prom_print_hex(_lmb->memory.region[i].physbase); - prom_print_nl(); - prom_print(RELOC(" .size = 0x")); - prom_print_hex(_lmb->memory.region[i].size); - prom_print_nl(); + prom_printf(" memory.region[0x%x].base = 0x%x\n", + i, _lmb->memory.region[i].base); + prom_printf(" .physbase = 0x%x\n", + _lmb->memory.region[i].physbase); + prom_printf(" .size = 0x%x\n", + _lmb->memory.region[i].size); } - prom_print_nl(); - prom_print(RELOC(" reserved.cnt = 0x")); - prom_print_hex(_lmb->reserved.cnt); - prom_print_nl(); - prom_print(RELOC(" reserved.size = 0x")); - prom_print_hex(_lmb->reserved.size); - prom_print_nl(); + prom_printf("\n reserved.cnt = 0x%x\n", + _lmb->reserved.cnt); + prom_printf(" reserved.size = 0x%x\n", + _lmb->reserved.size); for (i=0; i < _lmb->reserved.cnt ;i++) { - prom_print(RELOC(" reserved.region[0x")); - prom_print_hex(i); - prom_print(RELOC("].base = 0x")); - prom_print_hex(_lmb->reserved.region[i].base); - prom_print_nl(); - prom_print(RELOC(" .physbase = 0x")); - prom_print_hex(_lmb->reserved.region[i].physbase); - prom_print_nl(); - prom_print(RELOC(" .size = 0x")); - prom_print_hex(_lmb->reserved.region[i].size); - prom_print_nl(); + prom_printf(" reserved.region[0x%x\n].base = 0x%x\n", + i, _lmb->reserved.region[i].base); + prom_printf(" .physbase = 0x%x\n", + _lmb->reserved.region[i].physbase); + prom_printf(" .size = 0x%x\n", + _lmb->reserved.region[i].size); } } #endif /* DEBUG_PROM */ @@ -604,14 +601,13 @@ for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("memory"))) continue; - num_regs = call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)) / bytes_per_reg; + num_regs = prom_getprop(node, "reg", ®, sizeof(reg)) + / bytes_per_reg; for (i=0; i < num_regs ;i++) { if (_systemcfg->platform == PLATFORM_POWERMAC) { @@ -636,7 +632,7 @@ } if (lmb_add(lmb_base, lmb_size) < 0) - prom_print(RELOC("Too many LMB's, discarding this one...\n")); + prom_printf("Too many LMB's, discarding this one...\n"); } } @@ -658,30 +654,23 @@ u32 getprop_rval; char hypertas_funcs[4]; -#ifdef DEBUG_PROM - prom_print(RELOC("prom_instantiate_rtas: start...\n")); -#endif - prom_rtas = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas")); + prom_debug("prom_instantiate_rtas: start...\n"); + + prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); if (prom_rtas != (ihandle) -1) { unsigned long x; - x = call_prom(RELOC("getprop"), - 4, 1, prom_rtas, - RELOC("ibm,hypertas-functions"), - hypertas_funcs, - sizeof(hypertas_funcs)); + x = prom_getprop(prom_rtas, "ibm,hypertas-functions", + hypertas_funcs, sizeof(hypertas_funcs)); if (x != PROM_ERROR) { - prom_print(RELOC("Hypertas detected, assuming LPAR !\n")); + prom_printf("Hypertas detected, assuming LPAR !\n"); _systemcfg->platform = PLATFORM_PSERIES_LPAR; } - call_prom(RELOC("getprop"), - 4, 1, prom_rtas, - RELOC("rtas-size"), - &getprop_rval, - sizeof(getprop_rval)); + prom_getprop(prom_rtas, "rtas-size", + &getprop_rval, sizeof(getprop_rval)); _rtas->size = getprop_rval; - prom_print(RELOC("instantiating rtas")); + prom_printf("instantiating rtas"); if (_rtas->size != 0) { unsigned long rtas_region = RTAS_INSTANTIATE_MAX; @@ -696,17 +685,15 @@ _rtas->base = lmb_alloc_base(_rtas->size, PAGE_SIZE, rtas_region); - prom_print(RELOC(" at 0x")); - prom_print_hex(_rtas->base); + prom_printf(" at 0x%x", _rtas->base); + + prom_rtas = call_prom("open", 1, 1, ADDR("/rtas")); + prom_printf("..."); - prom_rtas = (ihandle)call_prom(RELOC("open"), - 1, 1, RELOC("/rtas")); - prom_print(RELOC("...")); - - if (call_prom(RELOC("call-method"), 3, 2, - RELOC("instantiate-rtas"), - prom_rtas, - _rtas->base) != PROM_ERROR) { + if (call_prom("call-method", 3, 2, + ADDR("instantiate-rtas"), + prom_rtas, + _rtas->base) != PROM_ERROR) { _rtas->entry = (long)_prom->args.rets[1]; } RELOC(rtas_rmo_buf) @@ -715,26 +702,16 @@ } if (_rtas->entry <= 0) { - prom_print(RELOC(" failed\n")); + prom_printf(" failed\n"); } else { - prom_print(RELOC(" done\n")); + prom_printf(" done\n"); } -#ifdef DEBUG_PROM - prom_print(RELOC("rtas->base = 0x")); - prom_print_hex(_rtas->base); - prom_print_nl(); - prom_print(RELOC("rtas->entry = 0x")); - prom_print_hex(_rtas->entry); - prom_print_nl(); - prom_print(RELOC("rtas->size = 0x")); - prom_print_hex(_rtas->size); - prom_print_nl(); -#endif + prom_debug("rtas->base = 0x%x\n", _rtas->base); + prom_debug("rtas->entry = 0x%x\n", _rtas->entry); + prom_debug("rtas->size = 0x%x\n", _rtas->size); } -#ifdef DEBUG_PROM - prom_print(RELOC("prom_instantiate_rtas: end...\n")); -#endif + prom_debug("prom_instantiate_rtas: end...\n"); } @@ -759,9 +736,7 @@ RELOC(dart_tablebase) = (unsigned long) abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); - prom_print(RELOC("Dart at: ")); - prom_print_hex(RELOC(dart_tablebase)); - prom_print(RELOC("\n")); + prom_printf("Dart at: %x\n", RELOC(dart_tablebase)); } #endif /* CONFIG_PMAC_DART */ @@ -780,27 +755,23 @@ if (RELOC(ppc64_iommu_off)) return; -#ifdef DEBUG_PROM - prom_print(RELOC("starting prom_initialize_tce_table\n")); -#endif + prom_debug("starting prom_initialize_tce_table\n"); /* Search all nodes looking for PHBs. */ for (node = 0; prom_next_node(&node); ) { if (table == MAX_PHB) { - prom_print(RELOC("WARNING: PCI host bridge ignored, " - "need to increase MAX_PHB\n")); + prom_printf("WARNING: PCI host bridge ignored, " + "need to increase MAX_PHB\n"); continue; } compatible[0] = 0; type[0] = 0; model[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"), - compatible, sizeof(compatible)); - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); - call_prom(RELOC("getprop"), 4, 1, node, RELOC("model"), - model, sizeof(model)); + prom_getprop(node, "compatible", + compatible, sizeof(compatible)); + prom_getprop(node, "device_type", type, sizeof(type)); + prom_getprop(node, "model", model, sizeof(model)); /* Keep the old logic in tack to avoid regression. */ if (compatible[0] != 0) { @@ -819,15 +790,13 @@ continue; } - if (call_prom(RELOC("getprop"), 4, 1, node, - RELOC("tce-table-minalign"), &minalign, - sizeof(minalign)) == PROM_ERROR) { + if (prom_getprop(node, "tce-table-minalign", &minalign, + sizeof(minalign)) == PROM_ERROR) { minalign = 0; } - if (call_prom(RELOC("getprop"), 4, 1, node, - RELOC("tce-table-minsize"), &minsize, - sizeof(minsize)) == PROM_ERROR) { + if (prom_getprop(node, "tce-table-minsize", &minsize, + sizeof(minsize)) == PROM_ERROR) { minsize = 4UL << 20; } @@ -854,7 +823,7 @@ base = lmb_alloc(minsize, align); if ( !base ) { - prom_panic(RELOC("ERROR, cannot find space for TCE table.\n")); + prom_panic("ERROR, cannot find space for TCE table.\n"); } vbase = (unsigned long)abs_to_virt(base); @@ -864,23 +833,10 @@ prom_tce_table[table].base = vbase; prom_tce_table[table].size = minsize; -#ifdef DEBUG_PROM - prom_print(RELOC("TCE table: 0x")); - prom_print_hex(table); - prom_print_nl(); - - prom_print(RELOC("\tnode = 0x")); - prom_print_hex(node); - prom_print_nl(); - - prom_print(RELOC("\tbase = 0x")); - prom_print_hex(vbase); - prom_print_nl(); - - prom_print(RELOC("\tsize = 0x")); - prom_print_hex(minsize); - prom_print_nl(); -#endif + prom_debug("TCE table: 0x%x\n", table); + prom_debug("\tnode = 0x%x\n", node); + prom_debug("\tbase = 0x%x\n", vbase); + prom_debug("\tsize = 0x%x\n", minsize); /* Initialize the table to have a one-to-one mapping * over the allocated size. @@ -895,37 +851,30 @@ /* It seems OF doesn't null-terminate the path :-( */ memset(path, 0, sizeof(path)); /* Call OF to setup the TCE hardware */ - if (call_prom(RELOC("package-to-path"), 3, 1, node, - path, sizeof(path)-1) == PROM_ERROR) { - prom_print(RELOC("package-to-path failed\n")); + if (call_prom("package-to-path", 3, 1, node, + path, sizeof(path)-1) == PROM_ERROR) { + prom_printf("package-to-path failed\n"); } else { - prom_print(RELOC("opening PHB ")); - prom_print(path); + prom_printf("opening PHB %s", path); } - phb_node = (ihandle)call_prom(RELOC("open"), 1, 1, path); + phb_node = call_prom("open", 1, 1, path); if ( (long)phb_node <= 0) { - prom_print(RELOC("... failed\n")); + prom_printf("... failed\n"); } else { - prom_print(RELOC("... done\n")); + prom_printf("... done\n"); } - call_prom(RELOC("call-method"), 6, 0, - RELOC("set-64-bit-addressing"), - phb_node, - -1, - minsize, - base & 0xffffffff, - (base >> 32) & 0xffffffff); - call_prom(RELOC("close"), 1, 0, phb_node); + call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"), + phb_node, -1, minsize, + (u32) base, (u32) (base >> 32)); + call_prom("close", 1, 0, phb_node); table++; } /* Flag the first invalid entry */ prom_tce_table[table].node = 0; -#ifdef DEBUG_PROM - prom_print(RELOC("ending prom_initialize_tce_table\n")); -#endif + prom_debug("ending prom_initialize_tce_table\n"); } /* @@ -983,13 +932,11 @@ if (_systemcfg->platform == PLATFORM_POWERMAC) { for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("cpu")) != 0) continue; reg = -1; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)); + prom_getprop(node, "reg", ®, sizeof(reg)); _xPaca[cpuid].xHwProcNum = reg; #ifdef CONFIG_SMP @@ -1007,24 +954,13 @@ /* Initially, we must have one active CPU. */ _systemcfg->processorCount = 1; -#ifdef DEBUG_PROM - prom_print(RELOC("prom_hold_cpus: start...\n")); - prom_print(RELOC(" 1) spinloop = 0x")); - prom_print_hex((unsigned long)spinloop); - prom_print_nl(); - prom_print(RELOC(" 1) *spinloop = 0x")); - prom_print_hex(*spinloop); - prom_print_nl(); - prom_print(RELOC(" 1) acknowledge = 0x")); - prom_print_hex((unsigned long)acknowledge); - prom_print_nl(); - prom_print(RELOC(" 1) *acknowledge = 0x")); - prom_print_hex(*acknowledge); - prom_print_nl(); - prom_print(RELOC(" 1) secondary_hold = 0x")); - prom_print_hex(secondary_hold); - prom_print_nl(); -#endif + prom_debug("prom_hold_cpus: start...\n"); + prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); + prom_debug(" 1) *spinloop = 0x%x\n", *spinloop); + prom_debug(" 1) acknowledge = 0x%x\n", + (unsigned long)acknowledge); + prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge); + prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold); /* Set the common spinloop variable, so all of the secondary cpus * will block when they are awakened from their OF spinloop. @@ -1041,36 +977,26 @@ /* look for cpus */ for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("cpu")) != 0) continue; /* Skip non-configured cpus. */ - call_prom(RELOC("getprop"), 4, 1, node, RELOC("status"), - type, sizeof(type)); + prom_getprop(node, "status", type, sizeof(type)); if (strcmp(type, RELOC("okay")) != 0) continue; reg = -1; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)); + prom_getprop(node, "reg", ®, sizeof(reg)); path = (char *) mem; memset(path, 0, 256); - if ((long) call_prom(RELOC("package-to-path"), 3, 1, - node, path, 255) == PROM_ERROR) + if (call_prom("package-to-path", 3, 1, + node, path, 255) == PROM_ERROR) continue; -#ifdef DEBUG_PROM - prom_print_nl(); - prom_print(RELOC("cpuid = 0x")); - prom_print_hex(cpuid); - prom_print_nl(); - prom_print(RELOC("cpu hw idx = 0x")); - prom_print_hex(reg); - prom_print_nl(); -#endif + prom_debug("\ncpuid = 0x%x\n", cpuid); + prom_debug("cpu hw idx = 0x%x\n", reg); _xPaca[cpuid].xHwProcNum = reg; /* Init the acknowledge var which will be reset by @@ -1079,10 +1005,9 @@ */ *acknowledge = (unsigned long)-1; - propsize = call_prom(RELOC("getprop"), 4, 1, node, - RELOC("ibm,ppc-interrupt-server#s"), - &interrupt_server, - sizeof(interrupt_server)); + propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s", + &interrupt_server, + sizeof(interrupt_server)); if (propsize < 0) { /* no property. old hardware has no SMT */ cpu_threads = 1; @@ -1091,11 +1016,9 @@ /* We have a threaded processor */ cpu_threads = propsize / sizeof(u32); if (cpu_threads > MAX_CPU_THREADS) { - prom_print(RELOC("SMT: too many threads!\nSMT: found ")); - prom_print_hex(cpu_threads); - prom_print(RELOC(", max is ")); - prom_print_hex(MAX_CPU_THREADS); - prom_print_nl(); + prom_printf("SMT: too many threads!\n" + "SMT: found %x, max is %x\n", + cpu_threads, MAX_CPU_THREADS); cpu_threads = 1; /* ToDo: panic? */ } } @@ -1103,18 +1026,15 @@ hw_cpu_num = interrupt_server[0]; if (hw_cpu_num != _prom->cpu) { /* Primary Thread of non-boot cpu */ - prom_print_hex(cpuid); - prom_print(RELOC(" : starting cpu ")); - prom_print(path); - prom_print(RELOC("... ")); - call_prom(RELOC("start-cpu"), 3, 0, node, + prom_printf("%x : starting cpu %s... ", cpuid, path); + call_prom("start-cpu", 3, 0, node, secondary_hold, cpuid); for ( i = 0 ; (i < 100000000) && (*acknowledge == ((unsigned long)-1)); i++ ) ; if (*acknowledge == cpuid) { - prom_print(RELOC("... done\n")); + prom_printf("... done\n"); /* We have to get every CPU out of OF, * even if we never start it. */ if (cpuid >= NR_CPUS) @@ -1127,17 +1047,12 @@ cpu_set(cpuid, RELOC(cpu_present_at_boot)); #endif } else { - prom_print(RELOC("... failed: ")); - prom_print_hex(*acknowledge); - prom_print_nl(); + prom_printf("... failed: %x\n", *acknowledge); } } #ifdef CONFIG_SMP else { - prom_print_hex(cpuid); - prom_print(RELOC(" : booting cpu ")); - prom_print(path); - prom_print_nl(); + prom_printf("%x : booting cpu %s\n", cpuid, path); cpu_set(cpuid, RELOC(cpu_available_map)); cpu_set(cpuid, RELOC(cpu_possible_map)); cpu_set(cpuid, RELOC(cpu_online_map)); @@ -1152,16 +1067,15 @@ if (cpuid >= NR_CPUS) continue; _xPaca[cpuid].xHwProcNum = interrupt_server[i]; - prom_print_hex(interrupt_server[i]); - prom_print(RELOC(" : preparing thread ... ")); + prom_printf("%x : preparing thread ... ", + interrupt_server[i]); if (_naca->smt_state) { cpu_set(cpuid, RELOC(cpu_available_map)); cpu_set(cpuid, RELOC(cpu_present_at_boot)); - prom_print(RELOC("available")); + prom_printf("available\n"); } else { - prom_print(RELOC("not available")); + prom_printf("not available\n"); } - prom_print_nl(); } #endif cpuid++; @@ -1171,7 +1085,7 @@ if (__is_processor(PV_PULSAR) || __is_processor(PV_ICESTAR) || __is_processor(PV_SSTAR)) { - prom_print(RELOC(" starting secondary threads\n")); + prom_printf(" starting secondary threads\n"); for (i = 0; i < NR_CPUS; i += 2) { if (!cpu_online(i)) @@ -1192,24 +1106,22 @@ } _systemcfg->processorCount *= 2; } else { - prom_print(RELOC("Processor is not HMT capable\n")); + prom_printf("Processor is not HMT capable\n"); } #endif - if (cpuid >= NR_CPUS) - prom_print(RELOC("WARNING: maximum CPUs (" __stringify(NR_CPUS) - ") exceeded: ignoring extras\n")); + if (cpuid > NR_CPUS) + prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS) + ") exceeded: ignoring extras\n"); -#ifdef DEBUG_PROM - prom_print(RELOC("prom_hold_cpus: end...\n")); -#endif + prom_debug("prom_hold_cpus: end...\n"); } static void __init smt_setup(void) { char *p, *q; char my_smt_enabled = SMT_DYNAMIC; - ihandle prom_options = NULL; + ihandle prom_options = 0; char option[9]; unsigned long offset = reloc_offset(); struct naca_struct *_naca = RELOC(naca); @@ -1233,13 +1145,10 @@ } } if (!found) { - prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + prom_options = call_prom("finddevice", 1, 1, ADDR("/options")); if (prom_options != (ihandle) -1) { - call_prom(RELOC("getprop"), - 4, 1, prom_options, - RELOC("ibm,smt-enabled"), - option, - sizeof(option)); + prom_getprop(prom_options, "ibm,smt-enabled", + option, sizeof(option)); if (option[0] != 0) { found = 1; if (!strcmp(option, RELOC("off"))) @@ -1272,43 +1181,29 @@ int i, naddrs; char name[64]; unsigned long offset = reloc_offset(); - char *getprop = RELOC("getprop"); - - prom_print(RELOC("Initializing fake screen: ")); memset(name, 0, sizeof(name)); - call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name)); + prom_getprop(dp, "name", name, sizeof(name)); name[sizeof(name)-1] = 0; - prom_print(name); - prom_print(RELOC("\n")); - call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width)); - call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height)); - call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth)); + prom_printf("Initializing fake screen: %s\n", name); + + prom_getprop(dp, "width", &width, sizeof(width)); + prom_getprop(dp, "height", &height, sizeof(height)); + prom_getprop(dp, "depth", &depth, sizeof(depth)); pitch = width * ((depth + 7) / 8); - call_prom(getprop, 4, 1, dp, RELOC("linebytes"), - &pitch, sizeof(pitch)); + prom_getprop(dp, "linebytes", &pitch, sizeof(pitch)); if (pitch == 1) pitch = 0x1000; /* for strange IBM display */ address = 0; - prom_print(RELOC("width ")); - prom_print_hex(width); - prom_print(RELOC(" height ")); - prom_print_hex(height); - prom_print(RELOC(" depth ")); - prom_print_hex(depth); - prom_print(RELOC(" linebytes ")); - prom_print_hex(pitch); - prom_print(RELOC("\n")); - + prom_printf("width %x height %x depth %x linebytes %x\n", + width, height, depth, depth); - call_prom(getprop, 4, 1, dp, RELOC("address"), - &address, sizeof(address)); + prom_getprop(dp, "address", &address, sizeof(address)); if (address == 0) { /* look for an assigned address with a size of >= 1MB */ - naddrs = (int) call_prom(getprop, 4, 1, dp, - RELOC("assigned-addresses"), - addrs, sizeof(addrs)); + naddrs = prom_getprop(dp, "assigned-addresses", + addrs, sizeof(addrs)); naddrs /= sizeof(struct pci_reg_property); for (i = 0; i < naddrs; ++i) { if (addrs[i].size_lo >= (1 << 20)) { @@ -1320,14 +1215,12 @@ } } if (address == 0) { - prom_print(RELOC("Failed to get address of frame buffer\n")); + prom_printf("Failed to get address of frame buffer\n"); return; } } btext_setup_display(width, height, depth, pitch, address); - prom_print(RELOC("Addr of fb: ")); - prom_print_hex(address); - prom_print_nl(); + prom_printf("Addr of fb: %x\n", address); RELOC(boot_text_mapped) = 0; } #endif /* CONFIG_BOOTX_TEXT */ @@ -1344,15 +1237,14 @@ _prom->encode_phys_size = 32; /* get a handle for the stdout device */ - _prom->chosen = (ihandle)call_prom(RELOC("finddevice"), 1, 1, - RELOC("/chosen")); + _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); if ((long)_prom->chosen <= 0) - prom_panic(RELOC("cannot find chosen")); /* msg won't be printed :( */ + prom_panic("cannot find chosen"); /* msg won't be printed :( */ /* get device tree root */ - _prom->root = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/")); + _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); if ((long)_prom->root <= 0) - prom_panic(RELOC("cannot find device tree root")); /* msg won't be printed :( */ + prom_panic("cannot find device tree root"); /* msg won't be printed :( */ } static void __init prom_init_stdout(void) @@ -1361,12 +1253,10 @@ struct prom_t *_prom = PTRRELOC(&prom); u32 val; - if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("stdout"), &val, - sizeof(val)) <= 0) - prom_panic(RELOC("cannot find stdout")); + if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0) + prom_panic("cannot find stdout"); - _prom->stdout = (ihandle)(unsigned long)val; + _prom->stdout = val; } static int __init prom_find_machine_type(void) @@ -1376,9 +1266,8 @@ char compat[256]; int len, i = 0; - len = (int)(long)call_prom(RELOC("getprop"), 4, 1, _prom->root, - RELOC("compatible"), - compat, sizeof(compat)-1); + len = prom_getprop(_prom->root, "compatible", + compat, sizeof(compat)-1); if (len > 0) { compat[len] = 0; while (i < len) { @@ -1400,13 +1289,7 @@ { unsigned long offset = reloc_offset(); - return (int)(long)call_prom(RELOC("call-method"), 6, 1, - RELOC("color!"), - ih, - (void *)(long) i, - (void *)(long) b, - (void *)(long) g, - (void *)(long) r ); + return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r); } /* @@ -1447,16 +1330,13 @@ _prom->disp_node = 0; - prom_print(RELOC("Looking for displays\n")); - if (RELOC(of_stdout_device) != 0) { - prom_print(RELOC("OF stdout is : ")); - prom_print(PTRRELOC(RELOC(of_stdout_device))); - prom_print(RELOC("\n")); - } + prom_printf("Looking for displays\n"); + if (RELOC(of_stdout_device) != 0) + prom_printf("OF stdout is : %s\n", + PTRRELOC(RELOC(of_stdout_device))); for (node = 0; prom_next_node(&node); ) { type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); + prom_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, RELOC("display")) != 0) continue; /* It seems OF doesn't null-terminate the path :-( */ @@ -1467,12 +1347,9 @@ * leave some room at the end of the path for appending extra * arguments */ - if ((long) call_prom(RELOC("package-to-path"), 3, 1, - node, path, 250) < 0) + if (call_prom("package-to-path", 3, 1, node, path, 250) < 0) continue; - prom_print(RELOC("found display : ")); - prom_print(path); - prom_print(RELOC("\n")); + prom_printf("found display : %s\n", path); /* * If this display is the device that OF is using for stdout, @@ -1489,27 +1366,26 @@ RELOC(prom_display_nodes[i]) = RELOC(prom_display_nodes[i-1]); } - _prom->disp_node = (ihandle)(unsigned long)node; + _prom->disp_node = node; } RELOC(prom_display_paths[i]) = PTRUNRELOC(path); RELOC(prom_display_nodes[i]) = node; if (_prom->disp_node == 0) - _prom->disp_node = (ihandle)(unsigned long)node; + _prom->disp_node = node; if (RELOC(prom_num_displays) >= FB_MAX) break; } - prom_print(RELOC("Opening displays...\n")); + prom_printf("Opening displays...\n"); for (j = RELOC(prom_num_displays) - 1; j >= 0; j--) { path = PTRRELOC(RELOC(prom_display_paths[j])); - prom_print(RELOC("opening display : ")); - prom_print(path); - ih = (ihandle)call_prom(RELOC("open"), 1, 1, path); + prom_printf("opening display : %s", path); + ih = call_prom("open", 1, 1, path); if (ih == (ihandle)0 || ih == (ihandle)-1) { - prom_print(RELOC("... failed\n")); + prom_printf("... failed\n"); continue; } - prom_print(RELOC("... done\n")); + prom_printf("... done\n"); /* Setup a useable color table when the appropriate * method is available. Should update this to set-colors */ @@ -1546,9 +1422,9 @@ unsigned long initrd_len; if (*mem_end != RELOC(initrd_start)) - prom_panic(RELOC("No memory for copy_device_tree")); + prom_panic("No memory for copy_device_tree"); - prom_print(RELOC("Huge device_tree: moving initrd\n")); + prom_printf("Huge device_tree: moving initrd\n"); /* Move by 4M. */ initrd_len = RELOC(initrd_end) - RELOC(initrd_start); *mem_end = RELOC(initrd_start) + 4 * 1024 * 1024; @@ -1557,7 +1433,7 @@ RELOC(initrd_start) = *mem_end; RELOC(initrd_end) = RELOC(initrd_start) + initrd_len; #else - prom_panic(RELOC("No memory for copy_device_tree")); + prom_panic("No memory for copy_device_tree"); #endif } @@ -1606,8 +1482,7 @@ for (;;) { /* 32 is max len of name including nul. */ namep = make_room(mem_start, mem_end, char[32]); - if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name, - namep) <= 0) { + if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { /* No more nodes: unwind alloc */ *mem_start = (unsigned long)namep; break; @@ -1619,28 +1494,24 @@ pp->name = PTRUNRELOC(namep); prev_name = namep; - pp->length = call_prom(RELOC("getproplen"), 2, 1, node, namep); + pp->length = call_prom("getproplen", 2, 1, node, namep); if (pp->length < 0) continue; if (pp->length > MAX_PROPERTY_LENGTH) { char path[128]; - prom_print(RELOC("WARNING: ignoring large property ")); + prom_printf("WARNING: ignoring large property "); /* It seems OF doesn't null-terminate the path :-( */ memset(path, 0, sizeof(path)); - if (call_prom(RELOC("package-to-path"), 3, 1, node, - path, sizeof(path)-1) > 0) - prom_print(path); - prom_print(namep); - prom_print(RELOC(" length 0x")); - prom_print_hex(pp->length); - prom_print_nl(); - + if (call_prom("package-to-path", 3, 1, node, + path, sizeof(path)-1) > 0) + prom_printf("[%s] ", path); + prom_printf("%s length 0x%x\n", namep, pp->length); continue; } valp = __make_room(mem_start, mem_end, pp->length, 1); pp->value = PTRUNRELOC(valp); - call_prom(RELOC("getprop"), 4, 1, node, namep,valp,pp->length); + call_prom("getprop", 4, 1, node, namep, valp, pp->length); *prev_propp = PTRUNRELOC(pp); prev_propp = &pp->next; } @@ -1660,19 +1531,19 @@ /* Set np->linux_phandle to the value of the ibm,phandle property if it exists, otherwise to the phandle for this node. */ np->linux_phandle = node; - if ((int)call_prom(RELOC("getprop"), 4, 1, node, RELOC("ibm,phandle"), - &ibm_phandle, sizeof(ibm_phandle)) > 0) + if (prom_getprop(node, "ibm,phandle", + &ibm_phandle, sizeof(ibm_phandle)) > 0) np->linux_phandle = ibm_phandle; /* get the node's full name */ namep = (char *)*mem_start; - l = (long) call_prom(RELOC("package-to-path"), 3, 1, node, - namep, *mem_end - *mem_start); + l = call_prom("package-to-path", 3, 1, node, + namep, *mem_end - *mem_start); if (l >= 0) { /* Didn't fit? Get more room. */ if (l+1 > *mem_end - *mem_start) { namep = __make_room(mem_start, mem_end, l+1, 1); - call_prom(RELOC("package-to-path"),3,1,node,namep,l); + call_prom("package-to-path", 3, 1, node, namep, l); } np->full_name = PTRUNRELOC(namep); namep[l] = '\0'; @@ -1680,11 +1551,11 @@ } /* do all our children */ - child = call_prom(RELOC("child"), 1, 1, node); + child = call_prom("child", 1, 1, node); while (child != (phandle)0) { inspect_node(child, np, mem_start, mem_end, allnextpp); - child = call_prom(RELOC("peer"), 1, 1, child); + child = call_prom("peer", 1, 1, child); } } @@ -1706,9 +1577,9 @@ mem_end = RELOC(initrd_start); #endif /* CONFIG_BLK_DEV_INITRD */ - root = call_prom(RELOC("peer"), 1, 1, (phandle)0); + root = call_prom("peer", 1, 1, (phandle)0); if (root == (phandle)0) { - prom_panic(RELOC("couldn't get device tree root\n")); + prom_panic("couldn't get device tree root\n"); } allnextp = &RELOC(allnodes); inspect_node(root, 0, &mem_start, &mem_end, &allnextp); @@ -1720,44 +1591,25 @@ static struct bi_record * __init prom_bi_rec_verify(struct bi_record *bi_recs) { struct bi_record *first, *last; -#ifdef DEBUG_PROM - unsigned long offset = reloc_offset(); - prom_print(RELOC("birec_verify: r6=0x")); - prom_print_hex((unsigned long)bi_recs); - prom_print_nl(); - if (bi_recs != NULL) { - prom_print(RELOC(" tag=0x")); - prom_print_hex(bi_recs->tag); - prom_print_nl(); - } -#endif /* DEBUG_PROM */ + prom_debug("birec_verify: r6=0x%x\n", (unsigned long)bi_recs); + if (bi_recs != NULL) + prom_debug(" tag=0x%x\n", bi_recs->tag); if ( bi_recs == NULL || bi_recs->tag != BI_FIRST ) return NULL; last = (struct bi_record *)(long)bi_recs->data[0]; -#ifdef DEBUG_PROM - prom_print(RELOC(" last=0x")); - prom_print_hex((unsigned long)last); - prom_print_nl(); - if (last != NULL) { - prom_print(RELOC(" last_tag=0x")); - prom_print_hex(last->tag); - prom_print_nl(); - } -#endif /* DEBUG_PROM */ + prom_debug(" last=0x%x\n", (unsigned long)last); + if (last != NULL) + prom_debug(" last_tag=0x%x\n", last->tag); if ( last == NULL || last->tag != BI_LAST ) return NULL; first = (struct bi_record *)(long)last->data[0]; -#ifdef DEBUG_PROM - prom_print(RELOC(" first=0x")); - prom_print_hex((unsigned long)first); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug(" first=0x%x\n", (unsigned long)first); if ( first == NULL || first != bi_recs ) return NULL; @@ -1776,11 +1628,7 @@ for ( rec=_prom->bi_recs; rec->tag != BI_LAST; rec=bi_rec_next(rec) ) { -#ifdef DEBUG_PROM - prom_print(RELOC("bi: 0x")); - prom_print_hex(rec->tag); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("bi: 0x%x\n", rec->tag); switch (rec->tag) { #ifdef CONFIG_BLK_DEV_INITRD case BI_INITRD: @@ -1833,31 +1681,17 @@ /* Init prom stdout device */ prom_init_stdout(); -#ifdef DEBUG_PROM - prom_print(RELOC("klimit=0x")); - prom_print_hex(RELOC(klimit)); - prom_print_nl(); - prom_print(RELOC("offset=0x")); - prom_print_hex(offset); - prom_print_nl(); - prom_print(RELOC("->mem=0x")); - prom_print_hex(RELOC(klimit) - offset); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("klimit=0x%x\n", RELOC(klimit)); + prom_debug("offset=0x%x\n", offset); + prom_debug("->mem=0x%x\n", RELOC(klimit) - offset); /* check out if we have bi_recs */ _prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6); if ( _prom->bi_recs != NULL ) { RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs + _prom->bi_recs->data[1]); -#ifdef DEBUG_PROM - prom_print(RELOC("bi_recs=0x")); - prom_print_hex((unsigned long)_prom->bi_recs); - prom_print_nl(); - prom_print(RELOC("new mem=0x")); - prom_print_hex(RELOC(klimit) - offset); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("bi_recs=0x%x\n", (unsigned long)_prom->bi_recs); + prom_debug("new mem=0x%x\n", RELOC(klimit) - offset); } /* If we don't have birec's or didn't find them, check for an initrd @@ -1884,57 +1718,46 @@ /* Get the full OF pathname of the stdout device */ p = (char *) mem; memset(p, 0, 256); - call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255); + call_prom("instance-to-path", 3, 1, _prom->stdout, p, 255); RELOC(of_stdout_device) = PTRUNRELOC(p); mem += strlen(p) + 1; getprop_rval = 1; - call_prom(RELOC("getprop"), 4, 1, - _prom->root, RELOC("#size-cells"), - &getprop_rval, sizeof(getprop_rval)); + prom_getprop(_prom->root, "#size-cells", + &getprop_rval, sizeof(getprop_rval)); _prom->encode_phys_size = (getprop_rval == 1) ? 32 : 64; /* Determine which cpu is actually running right _now_ */ - if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("cpu"), &getprop_rval, - sizeof(getprop_rval)) <= 0) - prom_panic(RELOC("cannot find boot cpu")); - - prom_cpu = (ihandle)(unsigned long)getprop_rval; - cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu); - call_prom(RELOC("getprop"), 4, 1, - cpu_pkg, RELOC("reg"), - &getprop_rval, sizeof(getprop_rval)); - _prom->cpu = (int)(unsigned long)getprop_rval; + if (prom_getprop(_prom->chosen, "cpu", + &prom_cpu, sizeof(prom_cpu)) <= 0) + prom_panic("cannot find boot cpu"); + + cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu); + prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); + _prom->cpu = getprop_rval; _xPaca[0].xHwProcNum = _prom->cpu; RELOC(boot_cpuid) = 0; -#ifdef DEBUG_PROM - prom_print(RELOC("Booting CPU hw index = 0x")); - prom_print_hex(_prom->cpu); - prom_print_nl(); -#endif + prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu); /* Get the boot device and translate it to a full OF pathname. */ p = (char *) mem; - l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("bootpath"), p, 1<<20); + l = prom_getprop(_prom->chosen, "bootpath", p, 1<<20); if (l > 0) { p[l] = 0; /* should already be null-terminated */ RELOC(bootpath) = PTRUNRELOC(p); mem += l + 1; d = (char *) mem; *d = 0; - call_prom(RELOC("canon"), 3, 1, p, d, 1<<20); + call_prom("canon", 3, 1, p, d, 1<<20); RELOC(bootdevice) = PTRUNRELOC(d); mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1); } RELOC(cmd_line[0]) = 0; if ((long)_prom->chosen > 0) { - call_prom(RELOC("getprop"), 4, 1, _prom->chosen, - RELOC("bootargs"), p, sizeof(cmd_line)); + prom_getprop(_prom->chosen, "bootargs", p, sizeof(cmd_line)); if (p != NULL && p[0] != 0) strlcpy(RELOC(cmd_line), p, sizeof(cmd_line)); } @@ -1961,33 +1784,20 @@ */ prom_hold_cpus(mem); -#ifdef DEBUG_PROM - prom_print(RELOC("after basic inits, mem=0x")); - prom_print_hex(mem); - prom_print_nl(); + prom_debug("after basic inits, mem=0x%x\n", mem); #ifdef CONFIG_BLK_DEV_INITRD - prom_print(RELOC("initrd_start=0x")); - prom_print_hex(RELOC(initrd_start)); - prom_print_nl(); - prom_print(RELOC("initrd_end=0x")); - prom_print_hex(RELOC(initrd_end)); - prom_print_nl(); + prom_debug("initrd_start=0x%x\n", RELOC(initrd_start)); + prom_debug("initrd_end=0x%x\n", RELOC(initrd_end)); #endif /* CONFIG_BLK_DEV_INITRD */ - prom_print(RELOC("copying OF device tree...\n")); -#endif /* DEBUG_PROM */ + prom_debug("copying OF device tree...\n"); + mem = copy_device_tree(mem); RELOC(klimit) = mem + offset; -#ifdef DEBUG_PROM - prom_print(RELOC("new klimit is\n")); - prom_print(RELOC("klimit=0x")); - prom_print_hex(RELOC(klimit)); - prom_print(RELOC(" ->mem=0x\n")); - prom_print(RELOC("klimit=0x")); - prom_print_hex(mem); - prom_print_nl(); -#endif /* DEBUG_PROM */ + prom_debug("new klimit is\n"); + prom_debug("klimit=0x%x\n", RELOC(klimit)); + prom_debug(" ->mem=0x%x\n", mem); lmb_reserve(0, __pa(RELOC(klimit))); @@ -2017,14 +1827,14 @@ #endif #ifdef CONFIG_BOOTX_TEXT - if(_prom->disp_node) { - prom_print(RELOC("Setting up bi display...\n")); + if (_prom->disp_node) { + prom_printf("Setting up bi display...\n"); setup_disp_fake_bi(_prom->disp_node); } #endif /* CONFIG_BOOTX_TEXT */ - prom_print(RELOC("Calling quiesce ...\n")); - call_prom(RELOC("quiesce"), 0, 0); + prom_printf("Calling quiesce ...\n"); + call_prom("quiesce", 0, 0); phys = KERNELBASE - offset; #ifdef CONFIG_BLK_DEV_INITRD @@ -2035,7 +1845,7 @@ } #endif /* CONFIG_BLK_DEV_INITRD */ - prom_print(RELOC("returning from prom_init\n")); + prom_printf("returning from prom_init\n"); return phys; } diff -Nru a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c --- a/arch/ppc64/kernel/ptrace.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc64/kernel/ptrace.c 2004-06-26 17:09:20 -07:00 @@ -119,8 +119,7 @@ if (index < PT_FPR0) { tmp = get_reg(child, (int)index); } else { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0]; } ret = put_user(tmp,(unsigned long __user *) data); @@ -152,8 +151,7 @@ if (index < PT_FPR0) { ret = put_reg(child, index, data); } else { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data; ret = 0; } @@ -245,8 +243,7 @@ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; unsigned long __user *tmp = (unsigned long __user *)addr; - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); for (i = 0; i < 32; i++) { ret = put_user(*reg, tmp); @@ -263,8 +260,7 @@ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; unsigned long __user *tmp = (unsigned long __user *)addr; - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); for (i = 0; i < 32; i++) { ret = get_user(*reg, tmp); diff -Nru a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c --- a/arch/ppc64/kernel/ptrace32.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/ptrace32.c 2004-06-26 17:09:18 -07:00 @@ -136,8 +136,7 @@ if (index < PT_FPR0) { tmp = get_reg(child, index); } else { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); /* * the user space code considers the floating point * to be an array of unsigned int (32 bits) - the @@ -179,8 +178,7 @@ break; if (numReg >= PT_FPR0) { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0]; } else { /* register within PT_REGS struct */ tmp = get_reg(child, numReg); @@ -244,8 +242,7 @@ if (index < PT_FPR0) { ret = put_reg(child, index, data); } else { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); /* * the user space code considers the floating point * to be an array of unsigned int (32 bits) - the @@ -283,8 +280,7 @@ || ((numReg > PT_CCR) && (numReg < PT_FPR0))) break; if (numReg >= PT_FPR0) { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); } if (numReg == PT_MSR) data = (data & MSR_DEBUGCHANGE) @@ -379,8 +375,7 @@ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; unsigned int __user *tmp = (unsigned int __user *)addr; - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); for (i = 0; i < 32; i++) { ret = put_user(*reg, tmp); @@ -397,8 +392,7 @@ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; unsigned int __user *tmp = (unsigned int __user *)addr; - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); + flush_fp_to_thread(child); for (i = 0; i < 32; i++) { ret = get_user(*reg, tmp); diff -Nru a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c --- a/arch/ppc64/kernel/rtas-proc.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ppc64/kernel/rtas-proc.c 2004-06-26 17:09:17 -07:00 @@ -394,7 +394,7 @@ size_t count, loff_t *ppos) { unsigned int year, mon, day, hour, min, sec; - unsigned long *ret = kmalloc(4*8, GFP_KERNEL); + int ret[8]; int n, sn, error; char stkbuf[40]; /* its small, its on stack */ @@ -411,7 +411,6 @@ n = scnprintf (stkbuf, sizeof(stkbuf), "%lu\n", mktime(year, mon, day, hour, min, sec)); } - kfree(ret); sn = strlen (stkbuf) +1; if (*ppos >= sn) @@ -434,7 +433,6 @@ int count, int *eof, void *data) { int i,j,n; - unsigned long ret; int state, error; char *buffer; int get_sensor_state = rtas_token("get-sensor-state"); @@ -464,11 +462,10 @@ /* A sensor may have multiple instances */ while (j >= 0) { - error = rtas_call(get_sensor_state, 2, 2, &ret, + error = rtas_call(get_sensor_state, 2, 2, &state, sensors.sensor[i].token, sensors.sensor[i].quant - j); - state = (int) ret; n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); n += sprintf (buffer+n, "\n"); diff -Nru a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c --- a/arch/ppc64/kernel/rtas.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc64/kernel/rtas.c 2004-06-26 17:09:16 -07:00 @@ -68,10 +68,11 @@ void call_rtas_display_status(char c) { - struct rtas_args *args = &(get_paca()->xRtas); + struct rtas_args *args; unsigned long s; spin_lock_irqsave(&rtas.lock, s); + args = &(get_paca()->xRtas); args->token = 10; args->nargs = 1; @@ -138,15 +139,13 @@ log_error(rtas_err_buf, ERR_TYPE_RTAS_LOG, 0); } -long -rtas_call(int token, int nargs, int nret, - unsigned long *outputs, ...) +int rtas_call(int token, int nargs, int nret, int *outputs, ...) { va_list list; int i, logit = 0; unsigned long s; - struct rtas_args *rtas_args = &(get_paca()->xRtas); - long ret; + struct rtas_args *rtas_args; + int ret; PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n"); PPCDBG(PPCDBG_RTAS, "\ttoken = 0x%x\n", token); @@ -158,6 +157,7 @@ /* Gotta do something different here, use global lock for now... */ spin_lock_irqsave(&rtas.lock, s); + rtas_args = &(get_paca()->xRtas); rtas_args->token = token; rtas_args->nargs = nargs; @@ -165,8 +165,8 @@ rtas_args->rets = (rtas_arg_t *)&(rtas_args->args[nargs]); va_start(list, outputs); for (i = 0; i < nargs; ++i) { - rtas_args->args[i] = (rtas_arg_t)LONG_LSW(va_arg(list, ulong)); - PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%lx\n", i, rtas_args->args[i]); + rtas_args->args[i] = va_arg(list, rtas_arg_t); + PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%x\n", i, rtas_args->args[i]); } va_end(list); @@ -189,7 +189,7 @@ if (nret > 1 && outputs != NULL) for (i = 0; i < nret-1; ++i) outputs[i] = rtas_args->rets[i+1]; - ret = (ulong)((nret > 0) ? rtas_args->rets[0] : 0); + ret = (nret > 0)? rtas_args->rets[0]: 0; /* Gotta do something different here, use global lock for now... */ spin_unlock_irqrestore(&rtas.lock, s); @@ -225,20 +225,13 @@ rtas_get_power_level(int powerdomain, int *level) { int token = rtas_token("get-power-level"); - long powerlevel; int rc; if (token == RTAS_UNKNOWN_SERVICE) return RTAS_UNKNOWN_OP; - while(1) { - rc = (int) rtas_call(token, 1, 2, &powerlevel, powerdomain); - if (rc == RTAS_BUSY) - udelay(1); - else - break; - } - *level = (int) powerlevel; + while ((rc = rtas_call(token, 1, 2, level, powerdomain)) == RTAS_BUSY) + udelay(1); return rc; } @@ -247,25 +240,21 @@ { int token = rtas_token("set-power-level"); unsigned int wait_time; - long returned_level; int rc; if (token == RTAS_UNKNOWN_SERVICE) return RTAS_UNKNOWN_OP; while (1) { - rc = (int) rtas_call(token, 2, 2, &returned_level, powerdomain, - level); + rc = rtas_call(token, 2, 2, setlevel, powerdomain, level); if (rc == RTAS_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { wait_time = rtas_extended_busy_delay_time(rc); udelay(wait_time * 1000); - } - else + } else break; } - *setlevel = (int) returned_level; return rc; } @@ -274,25 +263,21 @@ { int token = rtas_token("get-sensor-state"); unsigned int wait_time; - long returned_state; int rc; if (token == RTAS_UNKNOWN_SERVICE) return RTAS_UNKNOWN_OP; while (1) { - rc = (int) rtas_call(token, 2, 2, &returned_state, sensor, - index); + rc = rtas_call(token, 2, 2, state, sensor, index); if (rc == RTAS_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { wait_time = rtas_extended_busy_delay_time(rc); udelay(wait_time * 1000); - } - else + } else break; } - *state = (int) returned_state; return rc; } @@ -307,8 +292,7 @@ return RTAS_UNKNOWN_OP; while (1) { - rc = (int) rtas_call(token, 3, 1, NULL, indicator, index, - new_value); + rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value); if (rc == RTAS_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { @@ -407,7 +391,7 @@ if (rtas_firmware_flash_list.next) rtas_flash_firmware(); - printk("RTAS system-reboot returned %ld\n", + printk("RTAS system-reboot returned %d\n", rtas_call(rtas_token("system-reboot"), 0, 1, NULL)); for (;;); } @@ -418,8 +402,8 @@ if (rtas_firmware_flash_list.next) rtas_flash_bypass_warning(); /* allow power on only with power button press */ - printk("RTAS power-off returned %ld\n", - rtas_call(rtas_token("power-off"), 2, 1, NULL,0xffffffff,0xffffffff)); + printk("RTAS power-off returned %d\n", + rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); for (;;); } @@ -436,7 +420,7 @@ void rtas_os_term(char *str) { - long status; + int status; snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str); @@ -447,7 +431,7 @@ if (status == RTAS_BUSY) udelay(1); else if (status != 0) - printk(KERN_EMERG "ibm,os-term call failed %ld\n", + printk(KERN_EMERG "ibm,os-term call failed %d\n", status); } while (status == RTAS_BUSY); } diff -Nru a/arch/ppc64/kernel/rtas_flash.c b/arch/ppc64/kernel/rtas_flash.c --- a/arch/ppc64/kernel/rtas_flash.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc64/kernel/rtas_flash.c 2004-06-26 17:09:20 -07:00 @@ -344,8 +344,8 @@ s32 rc; while (1) { - rc = (s32) rtas_call(rtas_token("ibm,manage-flash-image"), 1, - 1, NULL, (long) args_buf->op); + rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, + 1, NULL, args_buf->op); if (rc == RTAS_RC_BUSY) udelay(1); else if (rtas_is_extended_busy(rc)) { @@ -429,15 +429,15 @@ { int token = rtas_token("ibm,validate-flash-image"); unsigned int wait_time; - long update_results; + int update_results; s32 rc; rc = 0; while(1) { spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE); - rc = (s32) rtas_call(token, 2, 2, &update_results, - __pa(rtas_data_buf), args_buf->buf_size); + rc = rtas_call(token, 2, 2, &update_results, + (u32) __pa(rtas_data_buf), args_buf->buf_size); memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE); spin_unlock(&rtas_data_buf_lock); @@ -451,7 +451,7 @@ } args_buf->status = rc; - args_buf->update_results = (u32) update_results; + args_buf->update_results = update_results; } static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, diff -Nru a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c --- a/arch/ppc64/kernel/rtasd.c 2004-06-26 17:09:17 -07:00 +++ b/arch/ppc64/kernel/rtasd.c 2004-06-26 17:09:17 -07:00 @@ -364,7 +364,6 @@ unsigned int err_type; int cpu = 0; int event_scan = rtas_token("event-scan"); - cpumask_t all = CPU_MASK_ALL; int rc; daemonize("rtasd"); @@ -415,11 +414,11 @@ } lock_cpu_hotplug(); - cpu = first_cpu_const(mk_cpumask_const(cpu_online_map)); + cpu = first_cpu(cpu_online_map); for (;;) { set_cpus_allowed(current, cpumask_of_cpu(cpu)); do_event_scan(event_scan); - set_cpus_allowed(current, all); + set_cpus_allowed(current, CPU_MASK_ALL); /* Drop hotplug lock, and sleep for a bit (at least * one second since some machines have problems if we @@ -429,9 +428,9 @@ schedule_timeout((HZ*60/rtas_event_scan_rate) / 2); lock_cpu_hotplug(); - cpu = next_cpu_const(cpu, mk_cpumask_const(cpu_online_map)); + cpu = next_cpu(cpu, cpu_online_map); if (cpu == NR_CPUS) - cpu = first_cpu_const(mk_cpumask_const(cpu_online_map)); + cpu = first_cpu(cpu_online_map); } error: diff -Nru a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c --- a/arch/ppc64/kernel/rtc.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/rtc.c 2004-06-26 17:09:18 -07:00 @@ -346,13 +346,13 @@ #define RTAS_CLOCK_BUSY (-2) void pSeries_get_boot_time(struct rtc_time *rtc_tm) { - unsigned long ret[8]; + int ret[8]; int error, wait_time; unsigned long max_wait_tb; max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { - error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); + error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { wait_time = rtas_extended_busy_delay_time(error); /* This is boot time so we spin. */ @@ -381,13 +381,13 @@ */ void pSeries_get_rtc_time(struct rtc_time *rtc_tm) { - unsigned long ret[8]; + int ret[8]; int error, wait_time; unsigned long max_wait_tb; max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { - error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); + error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { if (in_interrupt()) { printk(KERN_WARNING "error: reading clock would delay interrupt\n"); diff -Nru a/arch/ppc64/kernel/scanlog.c b/arch/ppc64/kernel/scanlog.c --- a/arch/ppc64/kernel/scanlog.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc64/kernel/scanlog.c 2004-06-26 17:09:20 -07:00 @@ -49,7 +49,7 @@ struct inode * inode = file->f_dentry->d_inode; struct proc_dir_entry *dp; unsigned int *data; - unsigned long status; + int status; unsigned long len, off; unsigned int wait_time; @@ -81,11 +81,11 @@ spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, data, RTAS_DATA_BUF_SIZE); status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, - __pa(rtas_data_buf), count); + (u32) __pa(rtas_data_buf), (u32) count); memcpy(data, rtas_data_buf, RTAS_DATA_BUF_SIZE); spin_unlock(&rtas_data_buf_lock); - DEBUG("status=%ld, data[0]=%x, data[1]=%x, data[2]=%x\n", + DEBUG("status=%d, data[0]=%x, data[1]=%x, data[2]=%x\n", status, data[0], data[1], data[2]); switch (status) { case SCANLOG_COMPLETE: @@ -133,7 +133,7 @@ size_t count, loff_t *ppos) { char stkbuf[20]; - unsigned long status; + int status; if (count > 19) count = 19; if (copy_from_user (stkbuf, buf, count)) { @@ -144,8 +144,8 @@ if (buf) { if (strncmp(stkbuf, "reset", 5) == 0) { DEBUG("reset scanlog\n"); - status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, NULL, 0); - DEBUG("rtas returns %ld\n", status); + status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, 0, 0); + DEBUG("rtas returns %d\n", status); } else if (strncmp(stkbuf, "debugon", 7) == 0) { printk(KERN_ERR "scanlog: debug on\n"); scanlog_debug = 1; diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c --- a/arch/ppc64/kernel/setup.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/setup.c 2004-06-26 17:09:18 -07:00 @@ -82,7 +82,6 @@ int powersave_nap; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned char aux_device_present; void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5, @@ -165,7 +164,7 @@ unsigned long r6, unsigned long r7) { #if defined(CONFIG_SMP) && defined(CONFIG_PPC_PSERIES) - unsigned int ret, i; + int ret, i; #endif #ifdef CONFIG_XMON_DEFAULT @@ -233,12 +232,11 @@ #ifdef CONFIG_SMP /* Start secondary threads on SMT systems */ for (i = 0; i < NR_CPUS; i++) { - if(cpu_available(i) && !cpu_possible(i)) { + if (cpu_available(i) && !cpu_possible(i)) { printk("%16.16x : starting thread\n", i); - rtas_call(rtas_token("start-cpu"), 3, 1, - (void *)&ret, + rtas_call(rtas_token("start-cpu"), 3, 1, &ret, get_hard_smp_processor_id(i), - *((unsigned long *)pseries_secondary_smp_init), + (u32)*((unsigned long *)pseries_secondary_smp_init), i); cpu_set(i, cpu_possible_map); systemcfg->processorCount++; diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c --- a/arch/ppc64/kernel/signal.c 2004-06-26 17:09:15 -07:00 +++ b/arch/ppc64/kernel/signal.c 2004-06-26 17:09:15 -07:00 @@ -131,8 +131,7 @@ #endif long err = 0; - if (regs->msr & MSR_FP) - giveup_fpu(current); + flush_fp_to_thread(current); /* Make sure signal doesn't get spurrious FP exceptions */ current->thread.fpscr = 0; @@ -141,9 +140,8 @@ err |= __put_user(v_regs, &sc->v_regs); /* save altivec registers */ - if (current->thread.used_vr) { - if (regs->msr & MSR_VEC) - giveup_altivec(current); + if (current->thread.used_vr) { + flush_altivec_to_thread(current); /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128)); /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) @@ -530,13 +528,13 @@ struct k_sigaction *ka = ¤t->sighand->action[signr-1]; /* Whee! Actually deliver the signal. */ - if (regs->trap == 0x0C00) + if (TRAP(regs) == 0x0C00) syscall_restart(regs, ka); handle_signal(signr, ka, &info, oldset, regs); return 1; } - if (regs->trap == 0x0C00) { /* System Call! */ + if (TRAP(regs) == 0x0C00) { /* System Call! */ if ((int)regs->result == -ERESTARTNOHAND || (int)regs->result == -ERESTARTSYS || (int)regs->result == -ERESTARTNOINTR) { diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c --- a/arch/ppc64/kernel/signal32.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc64/kernel/signal32.c 2004-06-26 17:09:20 -07:00 @@ -130,11 +130,10 @@ { elf_greg_t64 *gregs = (elf_greg_t64 *)regs; int i, err = 0; - - /* Make sure floating point registers are stored in regs */ - if (regs->msr & MSR_FP) - giveup_fpu(current); - + + /* Make sure floating point registers are stored in regs */ + flush_fp_to_thread(current); + /* save general and floating-point registers */ for (i = 0; i <= PT_RESULT; i ++) err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]); @@ -148,8 +147,7 @@ #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - if (regs->msr & MSR_VEC) - giveup_altivec(current); + flush_altivec_to_thread(current); if (__copy_to_user(&frame->mc_vregs, current->thread.vr, ELF_NVRREG32 * sizeof(vector128))) return 1; @@ -934,7 +932,7 @@ ka = (signr == 0)? NULL: ¤t->sighand->action[signr-1]; - if (regs->trap == 0x0C00 /* System Call! */ + if (TRAP(regs) == 0x0C00 /* System Call! */ && regs->ccr & 0x10000000 /* error signalled */ && ((ret = regs->gpr[3]) == ERESTARTSYS || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c --- a/arch/ppc64/kernel/smp.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/smp.c 2004-06-26 17:09:19 -07:00 @@ -241,7 +241,7 @@ */ static int query_cpu_stopped(unsigned int pcpu) { - long cpu_status; + int cpu_status; int status, qcss_tok; qcss_tok = rtas_token("query-cpu-stopped-state"); diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c --- a/arch/ppc64/kernel/sys_ppc32.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/sys_ppc32.c 2004-06-26 17:09:19 -07:00 @@ -617,12 +617,8 @@ error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - if (regs->msr & MSR_FP) - giveup_fpu(current); -#ifdef CONFIG_ALTIVEC - if (regs->msr & MSR_VEC) - giveup_altivec(current); -#endif /* CONFIG_ALTIVEC */ + flush_fp_to_thread(current); + flush_altivec_to_thread(current); error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs); diff -Nru a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c --- a/arch/ppc64/kernel/syscalls.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/kernel/syscalls.c 2004-06-26 17:09:19 -07:00 @@ -237,5 +237,19 @@ return secs; } +void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, unsigned long r8, + struct pt_regs *regs) +{ + printk("syscall %ld(%lx, %lx, %lx, %lx, %lx, %lx) regs=%p current=%p" + " cpu=%d\n", regs->gpr[0], r3, r4, r5, r6, r7, r8, regs, + current, smp_processor_id()); +} + +void do_show_syscall_exit(unsigned long r3) +{ + printk(" -> %lx, current=%p cpu=%d\n", r3, current, smp_processor_id()); +} + /* Only exists on P-series. */ cond_syscall(ppc_rtas); diff -Nru a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c --- a/arch/ppc64/kernel/sysfs.c 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc64/kernel/sysfs.c 2004-06-26 17:09:16 -07:00 @@ -325,6 +325,16 @@ #ifdef CONFIG_NUMA parent = &node_devices[cpu_to_node(cpu)]; #endif + /* + * For now, we just see if the system supports making + * the RTAS calls for CPU hotplug. But, there may be a + * more comprehensive way to do this for an individual + * CPU. For instance, the boot cpu might never be valid + * for hotplugging. + */ + if (systemcfg->platform != PLATFORM_PSERIES_LPAR) + c->no_control = 1; + register_cpu(c, cpu, parent); register_cpu_pmc(&c->sysdev); diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c --- a/arch/ppc64/kernel/traps.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/traps.c 2004-06-26 17:09:18 -07:00 @@ -172,9 +172,9 @@ */ static void FWNMI_release_errinfo(void) { - unsigned long ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL); + int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL); if (ret != 0) - printk("FWNMI: nmi-interlock failed: %ld\n", ret); + printk("FWNMI: nmi-interlock failed: %d\n", ret); } #endif @@ -308,8 +308,7 @@ siginfo_t info; unsigned long fpscr; - if (regs->msr & MSR_FP) - giveup_fpu(current); + flush_fp_to_thread(current); fpscr = current->thread.fpscr; @@ -442,8 +441,22 @@ die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); } -void KernelAltivecUnavailableException(struct pt_regs *regs) +void AltivecUnavailableException(struct pt_regs *regs) { +#ifndef CONFIG_ALTIVEC + if (user_mode(regs)) { + /* A user program has executed an altivec instruction, + but this kernel doesn't support altivec. */ + siginfo_t info; + + memset(&info, 0, sizeof(info)); + info.si_signo = SIGILL; + info.si_code = ILL_ILLOPC; + info.si_addr = (void *) regs->nip; + _exception(SIGILL, &info, regs); + return; + } +#endif printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); @@ -531,10 +544,39 @@ void AltivecAssistException(struct pt_regs *regs) { - if (regs->msr & MSR_VEC) - giveup_altivec(current); - /* XXX quick hack for now: set the non-Java bit in the VSCR */ - current->thread.vscr.u[3] |= 0x10000; + int err; + siginfo_t info; + + if (!user_mode(regs)) { + printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode" + " at %lx\n", regs->nip); + die("Kernel VMX/Altivec assist exception", regs, SIGILL); + } + + flush_altivec_to_thread(current); + + err = emulate_altivec(regs); + if (err == 0) { + regs->nip += 4; /* skip emulated instruction */ + emulate_single_step(regs); + return; + } + + if (err == -EFAULT) { + /* got an error reading the instruction */ + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = (void *) regs->nip; + force_sig_info(SIGSEGV, &info, current); + } else { + /* didn't recognize the instruction */ + /* XXX quick hack for now: set the non-Java bit in the VSCR */ + if (printk_ratelimit()) + printk(KERN_ERR "Unrecognized altivec instruction " + "in %s at %lx\n", current->comm, regs->nip); + current->thread.vscr.u[3] |= 0x10000; + } } #endif /* CONFIG_ALTIVEC */ diff -Nru a/arch/ppc64/kernel/vecemu.c b/arch/ppc64/kernel/vecemu.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc64/kernel/vecemu.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,346 @@ +/* + * Routines to emulate some Altivec/VMX instructions, specifically + * those that can trap when given denormalized operands in Java mode. + */ +#include +#include +#include +#include +#include +#include + +/* Functions in vector.S */ +extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b); +extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b); +extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c); +extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c); +extern void vrefp(vector128 *dst, vector128 *src); +extern void vrsqrtefp(vector128 *dst, vector128 *src); +extern void vexptep(vector128 *dst, vector128 *src); + +static unsigned int exp2s[8] = { + 0x800000, + 0x8b95c2, + 0x9837f0, + 0xa5fed7, + 0xb504f3, + 0xc5672a, + 0xd744fd, + 0xeac0c7 +}; + +/* + * Computes an estimate of 2^x. The `s' argument is the 32-bit + * single-precision floating-point representation of x. + */ +static unsigned int eexp2(unsigned int s) +{ + int exp, pwr; + unsigned int mant, frac; + + /* extract exponent field from input */ + exp = ((s >> 23) & 0xff) - 127; + if (exp > 7) { + /* check for NaN input */ + if (exp == 128 && (s & 0x7fffff) != 0) + return s | 0x400000; /* return QNaN */ + /* 2^-big = 0, 2^+big = +Inf */ + return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */ + } + if (exp < -23) + return 0x3f800000; /* 1.0 */ + + /* convert to fixed point integer in 9.23 representation */ + pwr = (s & 0x7fffff) | 0x800000; + if (exp > 0) + pwr <<= exp; + else + pwr >>= -exp; + if (s & 0x80000000) + pwr = -pwr; + + /* extract integer part, which becomes exponent part of result */ + exp = (pwr >> 23) + 126; + if (exp >= 254) + return 0x7f800000; + if (exp < -23) + return 0; + + /* table lookup on top 3 bits of fraction to get mantissa */ + mant = exp2s[(pwr >> 20) & 7]; + + /* linear interpolation using remaining 20 bits of fraction */ + asm("mulhwu %0,%1,%2" : "=r" (frac) + : "r" (pwr << 12), "r" (0x172b83ff)); + asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant)); + mant += frac; + + if (exp >= 0) + return mant + (exp << 23); + + /* denormalized result */ + exp = -exp; + mant += 1 << (exp - 1); + return mant >> exp; +} + +/* + * Computes an estimate of log_2(x). The `s' argument is the 32-bit + * single-precision floating-point representation of x. + */ +static unsigned int elog2(unsigned int s) +{ + int exp, mant, lz, frac; + + exp = s & 0x7f800000; + mant = s & 0x7fffff; + if (exp == 0x7f800000) { /* Inf or NaN */ + if (mant != 0) + s |= 0x400000; /* turn NaN into QNaN */ + return s; + } + if ((exp | mant) == 0) /* +0 or -0 */ + return 0xff800000; /* return -Inf */ + + if (exp == 0) { + /* denormalized */ + asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant)); + mant <<= lz - 8; + exp = (-118 - lz) << 23; + } else { + mant |= 0x800000; + exp -= 127 << 23; + } + + if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */ + exp |= 0x400000; /* 0.5 * 2^23 */ + asm("mulhwu %0,%1,%2" : "=r" (mant) + : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */ + } + if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */ + exp |= 0x200000; /* 0.25 * 2^23 */ + asm("mulhwu %0,%1,%2" : "=r" (mant) + : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */ + } + if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */ + exp |= 0x100000; /* 0.125 * 2^23 */ + asm("mulhwu %0,%1,%2" : "=r" (mant) + : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */ + } + if (mant > 0x800000) { /* 1.0 * 2^23 */ + /* calculate (mant - 1) * 1.381097463 */ + /* 1.381097463 == 0.125 / (2^0.125 - 1) */ + asm("mulhwu %0,%1,%2" : "=r" (frac) + : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a)); + exp += frac; + } + s = exp & 0x80000000; + if (exp != 0) { + if (s) + exp = -exp; + asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp)); + lz = 8 - lz; + if (lz > 0) + exp >>= lz; + else if (lz < 0) + exp <<= -lz; + s += ((lz + 126) << 23) + exp; + } + return s; +} + +#define VSCR_SAT 1 + +static int ctsxs(unsigned int x, int scale, unsigned int *vscrp) +{ + int exp, mant; + + exp = (x >> 23) & 0xff; + mant = x & 0x7fffff; + if (exp == 255 && mant != 0) + return 0; /* NaN -> 0 */ + exp = exp - 127 + scale; + if (exp < 0) + return 0; /* round towards zero */ + if (exp >= 31) { + /* saturate, unless the result would be -2^31 */ + if (x + (scale << 23) != 0xcf000000) + *vscrp |= VSCR_SAT; + return (x & 0x80000000)? 0x80000000: 0x7fffffff; + } + mant |= 0x800000; + mant = (mant << 7) >> (30 - exp); + return (x & 0x80000000)? -mant: mant; +} + +static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp) +{ + int exp; + unsigned int mant; + + exp = (x >> 23) & 0xff; + mant = x & 0x7fffff; + if (exp == 255 && mant != 0) + return 0; /* NaN -> 0 */ + exp = exp - 127 + scale; + if (exp < 0) + return 0; /* round towards zero */ + if (x & 0x80000000) { + /* negative => saturate to 0 */ + *vscrp |= VSCR_SAT; + return 0; + } + if (exp >= 32) { + /* saturate */ + *vscrp |= VSCR_SAT; + return 0xffffffff; + } + mant |= 0x800000; + mant = (mant << 8) >> (31 - exp); + return mant; +} + +/* Round to floating integer, towards 0 */ +static unsigned int rfiz(unsigned int x) +{ + int exp; + + exp = ((x >> 23) & 0xff) - 127; + if (exp == 128 && (x & 0x7fffff) != 0) + return x | 0x400000; /* NaN -> make it a QNaN */ + if (exp >= 23) + return x; /* it's an integer already (or Inf) */ + if (exp < 0) + return x & 0x80000000; /* |x| < 1.0 rounds to 0 */ + return x & ~(0x7fffff >> exp); +} + +/* Round to floating integer, towards +/- Inf */ +static unsigned int rfii(unsigned int x) +{ + int exp, mask; + + exp = ((x >> 23) & 0xff) - 127; + if (exp == 128 && (x & 0x7fffff) != 0) + return x | 0x400000; /* NaN -> make it a QNaN */ + if (exp >= 23) + return x; /* it's an integer already (or Inf) */ + if ((x & 0x7fffffff) == 0) + return x; /* +/-0 -> +/-0 */ + if (exp < 0) + /* 0 < |x| < 1.0 rounds to +/- 1.0 */ + return (x & 0x80000000) | 0x3f800000; + mask = 0x7fffff >> exp; + /* mantissa overflows into exponent - that's OK, + it can't overflow into the sign bit */ + return (x + mask) & ~mask; +} + +/* Round to floating integer, to nearest */ +static unsigned int rfin(unsigned int x) +{ + int exp, half; + + exp = ((x >> 23) & 0xff) - 127; + if (exp == 128 && (x & 0x7fffff) != 0) + return x | 0x400000; /* NaN -> make it a QNaN */ + if (exp >= 23) + return x; /* it's an integer already (or Inf) */ + if (exp < -1) + return x & 0x80000000; /* |x| < 0.5 -> +/-0 */ + if (exp == -1) + /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */ + return (x & 0x80000000) | 0x3f800000; + half = 0x400000 >> exp; + /* add 0.5 to the magnitude and chop off the fraction bits */ + return (x + half) & ~(0x7fffff >> exp); +} + +int +emulate_altivec(struct pt_regs *regs) +{ + unsigned int instr, i; + unsigned int va, vb, vc, vd; + vector128 *vrs; + + if (get_user(instr, (unsigned int *) regs->nip)) + return -EFAULT; + if ((instr >> 26) != 4) + return -EINVAL; /* not an altivec instruction */ + vd = (instr >> 21) & 0x1f; + va = (instr >> 16) & 0x1f; + vb = (instr >> 11) & 0x1f; + vc = (instr >> 6) & 0x1f; + + vrs = current->thread.vr; + switch (instr & 0x3f) { + case 10: + switch (vc) { + case 0: /* vaddfp */ + vaddfp(&vrs[vd], &vrs[va], &vrs[vb]); + break; + case 1: /* vsubfp */ + vsubfp(&vrs[vd], &vrs[va], &vrs[vb]); + break; + case 4: /* vrefp */ + vrefp(&vrs[vd], &vrs[vb]); + break; + case 5: /* vrsqrtefp */ + vrsqrtefp(&vrs[vd], &vrs[vb]); + break; + case 6: /* vexptefp */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = eexp2(vrs[vb].u[i]); + break; + case 7: /* vlogefp */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = elog2(vrs[vb].u[i]); + break; + case 8: /* vrfin */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = rfin(vrs[vb].u[i]); + break; + case 9: /* vrfiz */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = rfiz(vrs[vb].u[i]); + break; + case 10: /* vrfip */ + for (i = 0; i < 4; ++i) { + u32 x = vrs[vb].u[i]; + x = (x & 0x80000000)? rfiz(x): rfii(x); + vrs[vd].u[i] = x; + } + break; + case 11: /* vrfim */ + for (i = 0; i < 4; ++i) { + u32 x = vrs[vb].u[i]; + x = (x & 0x80000000)? rfii(x): rfiz(x); + vrs[vd].u[i] = x; + } + break; + case 14: /* vctuxs */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va, + ¤t->thread.vscr.u[3]); + break; + case 15: /* vctsxs */ + for (i = 0; i < 4; ++i) + vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va, + ¤t->thread.vscr.u[3]); + break; + default: + return -EINVAL; + } + break; + case 46: /* vmaddfp */ + vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]); + break; + case 47: /* vnmsubfp */ + vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]); + break; + default: + return -EINVAL; + } + + return 0; +} diff -Nru a/arch/ppc64/kernel/vector.S b/arch/ppc64/kernel/vector.S --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc64/kernel/vector.S 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,172 @@ +#include +#include + +/* + * The routines below are in assembler so we can closely control the + * usage of floating-point registers. These routines must be called + * with preempt disabled. + */ + .section ".toc","aw" +fpzero: + .tc FD_0_0[TC],0 +fpone: + .tc FD_3ff00000_0[TC],0x3ff0000000000000 /* 1.0 */ +fphalf: + .tc FD_3fe00000_0[TC],0x3fe0000000000000 /* 0.5 */ + + .text +/* + * Internal routine to enable floating point and set FPSCR to 0. + * Don't call it from C; it doesn't use the normal calling convention. + */ +fpenable: + mfmsr r10 + ori r11,r10,MSR_FP + mtmsr r11 + isync + stfd fr31,-8(r1) + stfd fr0,-16(r1) + stfd fr1,-24(r1) + mffs fr31 + lfd fr1,fpzero@toc(r2) + mtfsf 0xff,fr1 + blr + +fpdisable: + mtlr r12 + mtfsf 0xff,fr31 + lfd fr1,-24(r1) + lfd fr0,-16(r1) + lfd fr31,-8(r1) + mtmsr r10 + isync + blr + +/* + * Vector add, floating point. + */ +_GLOBAL(vaddfp) + mflr r12 + bl fpenable + li r0,4 + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + lfsx fr1,r5,r6 + fadds fr0,fr0,fr1 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector subtract, floating point. + */ +_GLOBAL(vsubfp) + mflr r12 + bl fpenable + li r0,4 + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + lfsx fr1,r5,r6 + fsubs fr0,fr0,fr1 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector multiply and add, floating point. + */ +_GLOBAL(vmaddfp) + mflr r12 + bl fpenable + stfd fr2,-32(r1) + li r0,4 + mtctr r0 + li r7,0 +1: lfsx fr0,r4,r7 + lfsx fr1,r5,r7 + lfsx fr2,r6,r7 + fmadds fr0,fr0,fr1,fr2 + stfsx fr0,r3,r7 + addi r7,r7,4 + bdnz 1b + lfd fr2,-32(r1) + b fpdisable + +/* + * Vector negative multiply and subtract, floating point. + */ +_GLOBAL(vnmsubfp) + mflr r12 + bl fpenable + stfd fr2,-32(r1) + li r0,4 + mtctr r0 + li r7,0 +1: lfsx fr0,r4,r7 + lfsx fr1,r5,r7 + lfsx fr2,r6,r7 + fnmsubs fr0,fr0,fr1,fr2 + stfsx fr0,r3,r7 + addi r7,r7,4 + bdnz 1b + lfd fr2,-32(r1) + b fpdisable + +/* + * Vector reciprocal estimate. We just compute 1.0/x. + * r3 -> destination, r4 -> source. + */ +_GLOBAL(vrefp) + mflr r12 + bl fpenable + li r0,4 + lfd fr1,fpone@toc(r2) + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + fdivs fr0,fr1,fr0 + stfsx fr0,r3,r6 + addi r6,r6,4 + bdnz 1b + b fpdisable + +/* + * Vector reciprocal square-root estimate, floating point. + * We use the frsqrte instruction for the initial estimate followed + * by 2 iterations of Newton-Raphson to get sufficient accuracy. + * r3 -> destination, r4 -> source. + */ +_GLOBAL(vrsqrtefp) + mflr r12 + bl fpenable + stfd fr2,-32(r1) + stfd fr3,-40(r1) + stfd fr4,-48(r1) + stfd fr5,-56(r1) + li r0,4 + lfd fr4,fpone@toc(r2) + lfd fr5,fphalf@toc(r2) + mtctr r0 + li r6,0 +1: lfsx fr0,r4,r6 + frsqrte fr1,fr0 /* r = frsqrte(s) */ + fmuls fr3,fr1,fr0 /* r * s */ + fmuls fr2,fr1,fr5 /* r * 0.5 */ + fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ + fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ + fmuls fr3,fr1,fr0 /* r * s */ + fmuls fr2,fr1,fr5 /* r * 0.5 */ + fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */ + fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */ + stfsx fr1,r3,r6 + addi r6,r6,4 + bdnz 1b + lfd fr5,-56(r1) + lfd fr4,-48(r1) + lfd fr3,-40(r1) + lfd fr2,-32(r1) + b fpdisable diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c --- a/arch/ppc64/kernel/xics.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/kernel/xics.c 2004-06-26 17:09:18 -07:00 @@ -240,14 +240,13 @@ static int get_irq_server(unsigned int irq) { cpumask_t cpumask = irq_affinity[irq]; - cpumask_t allcpus = CPU_MASK_ALL; cpumask_t tmp = CPU_MASK_NONE; unsigned int server; #ifdef CONFIG_IRQ_ALL_CPUS /* For the moment only implement delivery to all cpus or one cpu */ if (smp_threads_ready) { - if (cpus_equal(cpumask, allcpus)) { + if (cpus_equal(cpumask, CPU_MASK_ALL)) { server = default_distrib_server; } else { cpus_and(tmp, cpu_online_map, cpumask); @@ -276,7 +275,7 @@ static void xics_enable_irq(unsigned int virq) { unsigned int irq; - long call_status; + int call_status; unsigned int server; irq = virt_irq_to_real(irq_offset_down(virq)); @@ -288,7 +287,7 @@ DEFAULT_PRIORITY); if (call_status != 0) { printk(KERN_ERR "xics_enable_irq: irq=%x: ibm_set_xive " - "returned %lx\n", irq, call_status); + "returned %x\n", irq, call_status); return; } @@ -296,14 +295,14 @@ call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq); if (call_status != 0) { printk(KERN_ERR "xics_enable_irq: irq=%x: ibm_int_on " - "returned %lx\n", irq, call_status); + "returned %x\n", irq, call_status); return; } } static void xics_disable_real_irq(unsigned int irq) { - long call_status; + int call_status; unsigned int server; if (irq == XICS_IPI) @@ -312,7 +311,7 @@ call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); if (call_status != 0) { printk(KERN_ERR "xics_disable_real_irq: irq=%x: " - "ibm_int_off returned %lx\n", irq, call_status); + "ibm_int_off returned %x\n", irq, call_status); return; } @@ -321,7 +320,7 @@ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff); if (call_status != 0) { printk(KERN_ERR "xics_disable_irq: irq=%x: ibm_set_xive(0xff)" - " returned %lx\n", irq, call_status); + " returned %x\n", irq, call_status); return; } } @@ -613,26 +612,25 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) { unsigned int irq; - long status; - unsigned long xics_status[2]; + int status; + int xics_status[2]; unsigned long newmask; - cpumask_t allcpus = CPU_MASK_ALL; cpumask_t tmp = CPU_MASK_NONE; irq = virt_irq_to_real(irq_offset_down(virq)); if (irq == XICS_IPI || irq == NO_IRQ) return; - status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq); + status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); if (status) { printk(KERN_ERR "xics_set_affinity: irq=%d ibm,get-xive " - "returns %ld\n", irq, status); + "returns %d\n", irq, status); return; } /* For the moment only implement delivery to all cpus or one cpu */ - if (cpus_equal(cpumask, allcpus)) { + if (cpus_equal(cpumask, CPU_MASK_ALL)) { newmask = default_distrib_server; } else { cpus_and(tmp, cpu_online_map, cpumask); @@ -646,7 +644,7 @@ if (status) { printk(KERN_ERR "xics_set_affinity irq=%d ibm,set-xive " - "returns %ld\n", irq, status); + "returns %d\n", irq, status); return; } } @@ -657,10 +655,10 @@ void xics_migrate_irqs_away(void) { int set_indicator = rtas_token("set-indicator"); - const unsigned long giqs = 9005UL; /* Global Interrupt Queue Server */ - unsigned long status = 0; + const unsigned int giqs = 9005UL; /* Global Interrupt Queue Server */ + int status = 0; unsigned int irq, cpu = smp_processor_id(); - unsigned long xics_status[2]; + int xics_status[2]; unsigned long flags; BUG_ON(set_indicator == RTAS_UNKNOWN_SERVICE); @@ -671,7 +669,7 @@ /* Refuse any new interrupts... */ rtas_call(set_indicator, 3, 1, &status, giqs, - hard_smp_processor_id(), 0UL); + hard_smp_processor_id(), 0); WARN_ON(status != 0); /* Allow IPIs again... */ @@ -694,11 +692,10 @@ spin_lock_irqsave(&desc->lock, flags); - status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, - irq); + status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); if (status) { printk(KERN_ERR "migrate_irqs_away: irq=%d " - "ibm,get-xive returns %ld\n", + "ibm,get-xive returns %d\n", irq, status); goto unlock; } @@ -721,7 +718,7 @@ irq, xics_status[0], xics_status[1]); if (status) printk(KERN_ERR "migrate_irqs_away irq=%d " - "ibm,set-xive returns %ld\n", + "ibm,set-xive returns %d\n", irq, status); unlock: diff -Nru a/arch/ppc64/lib/string.S b/arch/ppc64/lib/string.S --- a/arch/ppc64/lib/string.S 2004-06-26 17:09:16 -07:00 +++ b/arch/ppc64/lib/string.S 2004-06-26 17:09:16 -07:00 @@ -66,28 +66,69 @@ blr _GLOBAL(memset) + neg r0,r5 rlwimi r4,r4,8,16,23 + andi. r0,r0,7 /* # bytes to be 8-byte aligned */ rlwimi r4,r4,16,0,15 - addi r6,r3,-4 - cmplwi 0,r5,4 - blt 7f - stwu r4,4(r6) - beqlr - andi. r0,r6,3 - add r5,r0,r5 - subf r6,r0,r6 - srwi r0,r5,2 + cmplw cr1,r5,r0 /* do we get that far? */ + rldimi r4,r4,32,0 + mr r6,r3 + mtcrf 1,r0 + mr r6,r3 + blt cr1,8f + beq+ 3f /* if already 8-byte aligned */ + subf r5,r0,r5 + bf 31,1f + stb r4,0(r6) + addi r6,r6,1 +1: bf 30,2f + sth r4,0(r6) + addi r6,r6,2 +2: bf 29,3f + stw r4,0(r6) + addi r6,r6,4 +3: srdi. r0,r5,6 + clrldi r5,r5,58 mtctr r0 - bdz 6f -1: stwu r4,4(r6) - bdnz 1b -6: andi. r5,r5,3 -7: cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r6,r6,3 -8: stbu r4,1(r6) - bdnz 8b + beq 5f +4: std r4,0(r6) + std r4,8(r6) + std r4,16(r6) + std r4,24(r6) + std r4,32(r6) + std r4,40(r6) + std r4,48(r6) + std r4,56(r6) + addi r6,r6,64 + bdnz 4b +5: srwi. r0,r5,3 + clrlwi r5,r5,29 + mtcrf 1,r0 + beq 8f + bf 29,6f + std r4,0(r6) + std r4,8(r6) + std r4,16(r6) + std r4,24(r6) + addi r6,r6,32 +6: bf 30,7f + std r4,0(r6) + std r4,8(r6) + addi r6,r6,16 +7: bf 31,8f + std r4,0(r6) + addi r6,r6,8 +8: cmpwi r5,0 + mtcrf 1,r5 + beqlr+ + bf 29,9f + stw r4,0(r6) + addi r6,r6,4 +9: bf 30,10f + sth r4,0(r6) + addi r6,r6,2 +10: bflr 31 + stb r4,0(r6) blr _GLOBAL(memmove) diff -Nru a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c --- a/arch/ppc64/mm/fault.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/mm/fault.c 2004-06-26 17:09:19 -07:00 @@ -80,36 +80,45 @@ * - DSISR for a non-SLB data access fault, * - SRR1 & 0x08000000 for a non-SLB instruction access fault * - 0 any SLB fault. + * The return value is 0 if the fault was handled, or the signal + * number if this is a kernel fault that can't be handled here. */ -void do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) +int do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) { struct vm_area_struct * vma; struct mm_struct *mm = current->mm; siginfo_t info; unsigned long code = SEGV_MAPERR; unsigned long is_write = error_code & 0x02000000; + unsigned long trap = TRAP(regs); - if (regs->trap == 0x300 || regs->trap == 0x380) { + if (trap == 0x300 || trap == 0x380) { if (debugger_fault_handler(regs)) - return; + return 0; } /* On a kernel SLB miss we can only check for a valid exception entry */ - if (!user_mode(regs) && (regs->trap == 0x380)) { - bad_page_fault(regs, address, SIGSEGV); - return; - } + if (!user_mode(regs) && (trap == 0x380 || address >= TASK_SIZE)) + return SIGSEGV; if (error_code & 0x00400000) { if (debugger_dabr_match(regs)) - return; + return 0; } if (in_atomic() || mm == NULL) { - bad_page_fault(regs, address, SIGSEGV); - return; + if (!user_mode(regs)) + return SIGSEGV; + /* in_atomic() in user mode is really bad, + as is current->mm == NULL. */ + printk(KERN_EMERG "Page fault in user mode with" + "in_atomic() = %d mm = %p\n", in_atomic(), mm); + printk(KERN_EMERG "NIP = %lx MSR = %lx\n", + regs->nip, regs->msr); + die("Weird page fault", regs, SIGSEGV); } + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -195,7 +204,7 @@ } up_read(&mm->mmap_sem); - return; + return 0; bad_area: up_read(&mm->mmap_sem); @@ -207,11 +216,10 @@ info.si_code = code; info.si_addr = (void *) address; force_sig_info(SIGSEGV, &info, current); - return; + return 0; } - bad_page_fault(regs, address, SIGSEGV); - return; + return SIGSEGV; /* * We ran out of memory, or some other thing happened to us that made @@ -227,18 +235,19 @@ printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); - bad_page_fault(regs, address, SIGKILL); - return; + return SIGKILL; do_sigbus: up_read(&mm->mmap_sem); - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRERR; - info.si_addr = (void *)address; - force_sig_info (SIGBUS, &info, current); - if (!user_mode(regs)) - bad_page_fault(regs, address, SIGBUS); + if (user_mode(regs)) { + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRERR; + info.si_addr = (void *)address; + force_sig_info(SIGBUS, &info, current); + return 0; + } + return SIGBUS; } /* diff -Nru a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c --- a/arch/ppc64/mm/hash_utils.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/mm/hash_utils.c 2004-06-26 17:09:18 -07:00 @@ -251,6 +251,7 @@ struct mm_struct *mm; pte_t *ptep; int ret; + int cpu; int user_region = 0; int local = 0; cpumask_t tmp; @@ -302,7 +303,8 @@ if (pgdir == NULL) return 1; - tmp = cpumask_of_cpu(smp_processor_id()); + cpu = get_cpu(); + tmp = cpumask_of_cpu(cpu); if (user_region && cpus_equal(mm->cpu_vm_mask, tmp)) local = 1; @@ -311,11 +313,13 @@ ret = hash_huge_page(mm, access, ea, vsid, local); else { ptep = find_linux_pte(pgdir, ea); - if (ptep == NULL) + if (ptep == NULL) { + put_cpu(); return 1; + } ret = __hash_page(ea, access, vsid, ptep, trap, local); } - + put_cpu(); return ret; } diff -Nru a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c --- a/arch/ppc64/mm/hugetlbpage.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/mm/hugetlbpage.c 2004-06-26 17:09:18 -07:00 @@ -375,6 +375,7 @@ unsigned long addr; hugepte_t *ptep; struct page *page; + int cpu; int local = 0; cpumask_t tmp; @@ -383,7 +384,8 @@ BUG_ON((end % HPAGE_SIZE) != 0); /* XXX are there races with checking cpu_vm_mask? - Anton */ - tmp = cpumask_of_cpu(smp_processor_id()); + cpu = get_cpu(); + tmp = cpumask_of_cpu(cpu); if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) local = 1; @@ -406,6 +408,7 @@ put_page(page); } + put_cpu(); mm->rss -= (end - start) >> PAGE_SHIFT; } diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c --- a/arch/ppc64/mm/init.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/mm/init.c 2004-06-26 17:09:18 -07:00 @@ -89,15 +89,15 @@ void show_mem(void) { - int total = 0, reserved = 0; - int shared = 0, cached = 0; + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; struct page *page; pg_data_t *pgdat; unsigned long i; printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; i++) { page = pgdat->node_mem_map + i; @@ -110,10 +110,10 @@ shared += page_count(page) - 1; } } - printk("%d pages of RAM\n",total); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); + printk("%ld pages of RAM\n", total); + printk("%ld reserved pages\n", reserved); + printk("%ld pages shared\n", shared); + printk("%ld pages swap cached\n", cached); } #ifdef CONFIG_PPC_ISERIES @@ -764,6 +764,7 @@ void *pgdir; pte_t *ptep; int local = 0; + int cpu; cpumask_t tmp; /* handle i-cache coherency */ @@ -794,12 +795,14 @@ vsid = get_vsid(vma->vm_mm->context.id, ea); - tmp = cpumask_of_cpu(smp_processor_id()); + cpu = get_cpu(); + tmp = cpumask_of_cpu(cpu); if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) local = 1; __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, 0x300, local); + put_cpu(); } void * reserve_phb_iospace(unsigned long size) diff -Nru a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c --- a/arch/ppc64/mm/numa.c 2004-06-26 17:09:19 -07:00 +++ b/arch/ppc64/mm/numa.c 2004-06-26 17:09:19 -07:00 @@ -457,7 +457,7 @@ zones_size[ZONE_DMA] = end_pfn - start_pfn; zholes_size[ZONE_DMA] = 0; if (nid == 0) - zholes_size[ZONE_DMA] = node0_io_hole_size; + zholes_size[ZONE_DMA] = node0_io_hole_size >> PAGE_SHIFT; dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid, zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]); diff -Nru a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c --- a/arch/ppc64/mm/tlb.c 2004-06-26 17:09:18 -07:00 +++ b/arch/ppc64/mm/tlb.c 2004-06-26 17:09:18 -07:00 @@ -41,6 +41,33 @@ DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); unsigned long pte_freelist_forced_free; +void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage) +{ + /* This is safe as we are holding page_table_lock */ + cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id()); + struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur); + + if (atomic_read(&tlb->mm->mm_users) < 2 || + cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) { + pte_free(ptepage); + return; + } + + if (*batchp == NULL) { + *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC); + if (*batchp == NULL) { + pte_free_now(ptepage); + return; + } + (*batchp)->index = 0; + } + (*batchp)->pages[(*batchp)->index++] = ptepage; + if ((*batchp)->index == PTE_FREELIST_SIZE) { + pte_free_submit(*batchp); + *batchp = NULL; + } +} + /* * Update the MMU hash table to correspond with a change to * a Linux PTE. If wrprot is true, it is permissible to @@ -91,12 +118,15 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) { int i; - cpumask_t tmp = cpumask_of_cpu(smp_processor_id()); + int cpu; + cpumask_t tmp; int local = 0; BUG_ON(in_interrupt()); + cpu = get_cpu(); i = batch->index; + tmp = cpumask_of_cpu(cpu); if (cpus_equal(batch->mm->cpu_vm_mask, tmp)) local = 1; @@ -106,6 +136,7 @@ else flush_hash_range(batch->context, i, local); batch->index = 0; + put_cpu(); } #ifdef CONFIG_SMP @@ -127,9 +158,10 @@ pte_free(ptepage); } -static void pte_free_rcu_callback(void *arg) +static void pte_free_rcu_callback(struct rcu_head *head) { - struct pte_freelist_batch *batch = arg; + struct pte_freelist_batch *batch = + container_of(head, struct pte_freelist_batch, rcu); unsigned int i; for (i = 0; i < batch->index; i++) @@ -140,7 +172,7 @@ void pte_free_submit(struct pte_freelist_batch *batch) { INIT_RCU_HEAD(&batch->rcu); - call_rcu(&batch->rcu, pte_free_rcu_callback, batch); + call_rcu(&batch->rcu, pte_free_rcu_callback); } void pte_free_finish(void) diff -Nru a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c --- a/arch/ppc64/xmon/xmon.c 2004-06-26 17:09:20 -07:00 +++ b/arch/ppc64/xmon/xmon.c 2004-06-26 17:09:20 -07:00 @@ -44,9 +44,6 @@ static int xmon_gate; #endif /* CONFIG_SMP */ -#define TRAP(regs) ((regs)->trap) -#define FULL_REGS(regs) 1 - static unsigned long in_xmon = 0; static unsigned long adrs; diff -Nru a/arch/s390/kernel/init_task.c b/arch/s390/kernel/init_task.c --- a/arch/s390/kernel/init_task.c 2004-06-26 17:09:19 -07:00 +++ b/arch/s390/kernel/init_task.c 2004-06-26 17:09:19 -07:00 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c --- a/arch/s390/kernel/s390_ksyms.c 2004-06-26 17:09:18 -07:00 +++ b/arch/s390/kernel/s390_ksyms.c 2004-06-26 17:09:18 -07:00 @@ -76,4 +76,3 @@ EXPORT_SYMBOL_NOVERS(do_call_softirq); EXPORT_SYMBOL(sys_wait4); EXPORT_SYMBOL(cpcmd); -EXPORT_SYMBOL(sys_ioctl); diff -Nru a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c --- a/arch/s390/kernel/setup.c 2004-06-26 17:09:15 -07:00 +++ b/arch/s390/kernel/setup.c 2004-06-26 17:09:15 -07:00 @@ -76,7 +76,6 @@ #include static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; static struct resource code_resource = { "Kernel code", 0x100000, 0 }; static struct resource data_resource = { "Kernel data", 0, 0 }; diff -Nru a/arch/s390/mm/init.c b/arch/s390/mm/init.c --- a/arch/s390/mm/init.c 2004-06-26 17:09:19 -07:00 +++ b/arch/s390/mm/init.c 2004-06-26 17:09:19 -07:00 @@ -60,7 +60,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig --- a/arch/sh/Kconfig 2004-06-26 17:09:21 -07:00 +++ b/arch/sh/Kconfig 2004-06-26 17:09:21 -07:00 @@ -45,6 +45,12 @@ Select 7751 SolutionEngine if configuring for a Hitachi SH7751 evalutation board. +config SH_7300_SOLUTION_ENGINE + bool "SolutionEngine7300" + help + Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) + evalutation board. + config SH_7751_SYSTEMH bool "SystemH7751R" help @@ -138,6 +144,18 @@ This includes both the OEM SecureEdge products as well as the SME product line. +config SH_HS7751RVOIP + bool "HS7751RVOIP" + help + Select HS7751RVOIP if configuring for a Renesas Technology + Sales VoIP board. + +config SH_RTS7751R2D + bool "RTS7751R2D" + help + Select RTS7751R2D if configuring for a Renesas Technology + Sales SH-Graphics board. + config SH_UNKNOWN bool "BareCPU" help @@ -186,7 +204,11 @@ config CPU_SUBTYPE_SH7300 bool "SH7300" depends on CPU_SH3 - + +config CPU_SUBTYPE_SH7705 + bool "SH7705" + depends on CPU_SH3 + config CPU_SUBTYPE_SH7707 bool "SH7707" depends on CPU_SH3 @@ -224,10 +246,17 @@ depends on CPU_SH4 config CPU_SUBTYPE_ST40STB1 - bool "ST40STB1" - depends on CPU_SH4 - help - Select ST40STB1 if you have a ST40STB1 CPU. + bool "ST40STB1 / ST40RA" + depends on CPU_SH4 + help + Select ST40STB1 if you have a ST40RA CPU. + This was previously called the ST40STB1, hence the option name. + +config CPU_SUBTYPE_ST40GX1 + bool "ST40GX1" + depends on CPU_SH4 + help + Select ST40GX1 if you have a ST40GX1 CPU. endchoice @@ -268,7 +297,7 @@ config MEMORY_START hex "Physical memory start address" if !MEMORY_SET || MEMORY_OVERRIDE default "0x08000000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || SH_MPC1211 || SH_SECUREEDGE5410 - default "0x0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE) + default "0x0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D) ---help--- Computers built with Hitachi SuperH processors always map the ROM starting at address zero. But the processor @@ -287,7 +316,7 @@ hex "Physical memory size" if !MEMORY_SET || MEMORY_OVERRIDE default "0x00400000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || !MEMORY_OVERRIDE && (SH_HP600 || SH_BIGSUR || SH_SH2000) default "0x01000000" if !MEMORY_OVERRIDE && SH_DREAMCAST || SH_SECUREEDGE5410 - default "0x04000000" if !MEMORY_OVERRIDE && SH_7751_SOLUTION_ENGINE + default "0x04000000" if !MEMORY_OVERRIDE && (SH_7751_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D) default "0x02000000" if !MEMORY_OVERRIDE && SH_SOLUTION_ENGINE default "0x08000000" if SH_MPC1211 help @@ -299,7 +328,7 @@ config MEMORY_SET bool - depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_SECUREEDGE5410) + depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_SECUREEDGE5410 || SH_HS7751RVOIP || SH_RTS7751R2D) default y help This is an option about which you will never be asked a question. @@ -358,7 +387,7 @@ # The SH7750 RTC module is disabled in the Dreamcast config SH_RTC bool - depends on !SH_DREAMCAST && !SH_SATURN + depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE default y help Selecting this option will allow the Linux kernel to emulate @@ -377,11 +406,26 @@ This option must be set in order to enable the DSP. +config SH_ADC + bool "ADC support" + depends on CPU_SH3 + default y + help + Selecting this option will allow the Linux kernel to use SH3 on-chip + ADC module. + + If unsure, say N. + config SH_HP600 bool depends on SH_HP620 || SH_HP680 || SH_HP690 default y +config CPU_SUBTYPE_ST40 + bool + depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1 + default y + config DISCONTIGMEM bool depends on SH_HP690 @@ -514,10 +558,32 @@ This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. +config HS7751RVOIP_CODEC + bool "Support VoIP Codec section" + depends on SH_HS7751RVOIP + help + Selecting this option will support CODEC section. + +config RTS7751R2D_REV11 + bool "RTS7751R2D Rev. 1.1 board support" + depends on SH_RTS7751R2D + help + Selecting this option will support version rev. 1.1. + +config SH_PCLK_CALC + bool + default n if CPU_SUBTYPE_SH7300 + default y + help + This option will cause the PCLK value to be probed at run-time. It + will display a notification if the probed value has greater than a + 1% variance of the hardcoded CONFIG_SH_PCLK_FREQ. + config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" default "49876504" if CPU_SUBTYPE_SH7750 default "60013568" if CPU_SUBTYPE_SH7751 + default "33333333" if CPU_SUBTYPE_SH7300 default "1193182" help This option is used to specify the peripheral clock frequency. This @@ -570,12 +636,18 @@ config HEARTBEAT bool "Heartbeat LED" - depends on SH_MPC1211 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE + depends on SH_MPC1211 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_RTS7751R2D help Use the power-on LED on your machine as a load meter. The exact behavior is platform-dependent, but normally the flash frequency is a hyperbolic function of the 5-minute load average. +config RTC_9701JE + tristate "EPSON RTC-9701JE support" + depends on SH_RTS7751R2D + help + Selecting this option will support EPSON RTC-9701JE. + endmenu @@ -646,6 +718,24 @@ endmenu +menu "SH initrd options" + depends on BLK_DEV_INITRD + +config EMBEDDED_RAMDISK + bool "Embed root filesystem ramdisk into the kernel" + +config EMBEDDED_RAMDISK_IMAGE + string "Filename of gziped ramdisk image" + depends on EMBEDDED_RAMDISK + default "ramdisk.gz" + help + This is the filename of the ramdisk image to be built into the + kernel. Relative pathnames are relative to arch/mips/ramdisk/. + The ramdisk image is not part of the kernel distribution; you must + provide one yourself. + +endmenu + source "drivers/Kconfig" source "fs/Kconfig" @@ -675,6 +765,14 @@ best used in conjunction with the NMI watchdog so that spinlock deadlocks are also debuggable. +config DEBUG_INFO + bool "Compile the kernel with debug info" + help + If you say Y here the resulting kernel image will include + debugging info resulting in a larger kernel image. + Say Y here only if you plan to use gdb to debug the kernel. + If you don't debug the kernel, you can say N. + config SH_STANDARD_BIOS bool "Use LinuxSH standard BIOS" help @@ -688,9 +786,13 @@ mask ROM and no flash (WindowsCE machines fall in this category). If unsure, say N. -config SH_EARLY_PRINTK +config EARLY_SCIF_CONSOLE + bool "Use early SCIF console" + depends on CPU_SH4 + +config EARLY_PRINTK bool "Early printk support" - depends on SH_STANDARD_BIOS + depends on SH_STANDARD_BIOS || EARLY_SCIF_CONSOLE help Say Y here to redirect kernel printk messages to the serial port used by the SH-IPL bootloader, starting very early in the boot diff -Nru a/arch/sh/Makefile b/arch/sh/Makefile --- a/arch/sh/Makefile 2004-06-26 17:09:19 -07:00 +++ b/arch/sh/Makefile 2004-06-26 17:09:19 -07:00 @@ -1,11 +1,11 @@ -# $Id: Makefile,v 1.34 2004/03/21 17:31:06 lethal Exp $ +# $Id: Makefile,v 1.35 2004/04/15 03:39:20 sugioka Exp $ # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive # for more details. # # Copyright (C) 1999 Kaz Kojima -# Copyright (C) 2002, 2003 Paul Mundt +# Copyright (C) 2002, 2003, 2004 Paul Mundt # Copyright (C) 2002 M. R. Brown # # This file is included by the global makefile so that you can add your own @@ -64,10 +64,18 @@ core-y += arch/sh/kernel/ arch/sh/mm/ +# +# ramdisk/initrd support +# You need a compressed ramdisk image, named +# CONFIG_EMBEDDED_RAMDISK_IMAGE. Relative pathnames +# are relative to arch/sh/ramdisk/. +# +core-$(CONFIG_EMBEDDED_RAMDISK) += arch/sh/ramdisk/ + # Boards machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 -machdir-$(CONFIG_SH_7751_SYSTEMH) := systemh +machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 machdir-$(CONFIG_SH_STB1_HARP) := harp machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive machdir-$(CONFIG_SH_HP620) := hp6xx/hp620 @@ -84,19 +92,24 @@ machdir-$(CONFIG_SH_ADX) := adx machdir-$(CONFIG_SH_MPC1211) := mpc1211 machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear +machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip +machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d +machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh machdir-$(CONFIG_SH_UNKNOWN) := unknown -incdir-y := $(machdir-y) +incdir-y := $(notdir $(machdir-y)) incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751 +incdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se7300 incdir-$(CONFIG_SH_HP600) := hp6xx core-y += arch/sh/boards/$(machdir-y)/ # Companion chips -core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/ -core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ +core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/ +core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ +core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3 @@ -114,6 +127,9 @@ prepare: target_links .PHONY: target_links FORCE + +all: zImage + target_links: @echo ' Making asm-sh/cpu -> asm-sh/$(cpuincdir-y) link' @rm -f include/asm-sh/cpu diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/Makefile b/arch/sh/boards/renesas/hs7751rvoip/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/hs7751rvoip/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,12 @@ +# +# Makefile for the HS7751RVoIP specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y := mach.o setup.o io.o irq.o led.o + +obj-$(CONFIG_PCI) += pci.o + diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/hs7751rvoip/io.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,310 @@ +/* + * linux/arch/sh/kernel/io_hs7751rvoip.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Renesas Technology sales HS7751RVoIP + * + * Initial version only to support LAN access; some + * placeholder code from io_hs7751rvoip.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../../../drivers/pci/pci-sh7751.h" + +extern void *area5_io8_base; /* Area 5 8bit I/O Base address */ +extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ +extern void *area5_io16_base; /* Area 5 16bit I/O Base address */ +extern void *area6_io16_base; /* Area 6 16bit I/O Base address */ + +/* + * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC) + * of the 7751R processor, and has a SuperIO accessible via the PCI. + * The board also includes a PCMCIA controller on its memory bus, + * like the other Solution Engine boards. + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + +#if defined(CONFIG_HS7751RVOIP_CODEC) +#define CODEC_IO_BASE 0x1000 +#endif + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +static inline unsigned long port2adr(unsigned int port) +{ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + if (port == 0x3f6) + return ((unsigned long)area5_io16_base + 0x0c); + else + return ((unsigned long)area5_io16_base + 0x800 + ((port-0x1f0) << 1)); + else + maybebadio(port2adr, (unsigned long)port); + return port; +} + +/* The 7751R HS7751RVoIP seems to have everything hooked */ +/* up pretty normally (nothing on high-bytes only...) so this */ +/* shouldn't be needed */ +static inline int shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return 0; + else + return 1; +} + +#if defined(CONFIG_HS7751RVOIP_CODEC) +static inline int +codec_port(unsigned long port) +{ + if (CODEC_IO_BASE <= port && port < (CODEC_IO_BASE+0x20)) + return 1; + else + return 0; +} +#endif + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char hs7751rvoip_inb(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + return *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); + else + return (*(volatile unsigned short *)port2adr(port) & 0xff); +} + +unsigned char hs7751rvoip_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)) + v = *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + v = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); + else + v = (*(volatile unsigned short *)port2adr(port) & 0xff); + delay(); + return v; +} + +unsigned short hs7751rvoip_inw(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); + else + maybebadio(inw, port); + return 0; +} + +unsigned int hs7751rvoip_inl(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned long *)PCI_IOMAP(port); + else + maybebadio(inl, port); + return 0; +} + +void hs7751rvoip_outb(unsigned char value, unsigned long port) +{ + + if (PXSEG(port)) + *(volatile unsigned char *)port = value; +#if defined(CONFIG_HS7751RVOIP_CIDEC) + else if (codec_port(port)) + *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; +} + +void hs7751rvoip_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned char *)port = value; +#if defined(CONFIG_HS7751RVOIP_CIDEC) + else if (codec_port(port)) + *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; + delay(); +} + +void hs7751rvoip_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned short *)PCI_IOMAP(port) = value; + else + maybebadio(outw, port); +} + +void hs7751rvoip_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *((unsigned long *)PCI_IOMAP(port)) = value; + else + maybebadio(outl, port); +} + +void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count) +{ + if (PXSEG(port)) + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); + + while (count--) *((volatile unsigned char *) addr)++ = *bp; + } else { + volatile __u16 *p = (volatile unsigned short *)port2adr(port); + + while (count--) *((unsigned char *) addr)++ = *p & 0xff; + } +} + +void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *((__u16 *) addr)++ = *p; +} + +void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count) +{ + if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *((__u32 *) addr)++ = *p; + } else + maybebadio(insl, port); +} + +void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count) +{ + if (PXSEG(port)) + while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; +#if defined(CONFIG_HS7751RVOIP_CODEC) + else if (codec_port(port)) + while (count--) *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = *((unsigned char *) addr)++; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); + + while (count--) *bp = *((volatile unsigned char *) addr)++; + } else { + volatile __u16 *p = (volatile unsigned short *)port2adr(port); + + while (count--) *p = *((unsigned char *) addr)++; + } +} + +void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *p = *((__u16 *) addr)++; +} + +void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count) +{ + if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *p = *((__u32 *) addr)++; + } else + maybebadio(outsl, port); +} + +void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size) +{ + if (offset >= 0xfd000000) + return (void *)offset; + else + return (void *)P2SEGADDR(offset); +} +EXPORT_SYMBOL(hs7751rvoip_ioremap); + +unsigned long hs7751rvoip_isa_port2addr(unsigned long offset) +{ + return port2adr(offset); +} diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,122 @@ +/* + * linux/arch/sh/boards/renesas/hs7751rvoip/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales HS7751RVoIP Support. + * + * Modified for HS7751RVoIP by + * Atom Create Engineering Co., Ltd. 2002. + * Lineo uSolutions, Inc. 2003. + */ + +#include +#include +#include +#include +#include +#include + +static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7}; + +static void enable_hs7751rvoip_irq(unsigned int irq); +static void disable_hs7751rvoip_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_hs7751rvoip_irq disable_hs7751rvoip_irq + +static void ack_hs7751rvoip_irq(unsigned int irq); +static void end_hs7751rvoip_irq(unsigned int irq); + +static unsigned int startup_hs7751rvoip_irq(unsigned int irq) +{ + enable_hs7751rvoip_irq(irq); + return 0; /* never anything pending */ +} + +static void disable_hs7751rvoip_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); + + /* Set the priority in IPR to 0 */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR3); + val &= mask; + ctrl_outw(val, IRLCNTR3); + local_irq_restore(flags); +} + +static void enable_hs7751rvoip_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short value = (0x0001 << mask_pos[irq]); + + /* Set priority in IPR back to original value */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR3); + val |= value; + ctrl_outw(val, IRLCNTR3); + local_irq_restore(flags); +} + +static void ack_hs7751rvoip_irq(unsigned int irq) +{ + disable_hs7751rvoip_irq(irq); +} + +static void end_hs7751rvoip_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_hs7751rvoip_irq(irq); +} + +static struct hw_interrupt_type hs7751rvoip_irq_type = { + "HS7751RVoIP IRQ", + startup_hs7751rvoip_irq, + shutdown_hs7751rvoip_irq, + enable_hs7751rvoip_irq, + disable_hs7751rvoip_irq, + ack_hs7751rvoip_irq, + end_hs7751rvoip_irq, +}; + +static void make_hs7751rvoip_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &hs7751rvoip_irq_type; + disable_hs7751rvoip_irq(irq); +} + +/* + * Initialize IRQ setting + */ +void __init init_hs7751rvoip_IRQ(void) +{ + int i; + + /* IRL0=ON HOOK1 + * IRL1=OFF HOOK1 + * IRL2=ON HOOK2 + * IRL3=OFF HOOK2 + * IRL4=Ringing Detection + * IRL5=CODEC + * IRL6=Ethernet + * IRL7=Ethernet Hub + * IRL8=USB Communication + * IRL9=USB Connection + * IRL10=USB DMA + * IRL11=CF Card + * IRL12=PCMCIA + * IRL13=PCI Slot + */ + ctrl_outw(0x9876, IRLCNTR1); + ctrl_outw(0xdcba, IRLCNTR2); + ctrl_outw(0x0050, IRLCNTR4); + ctrl_outw(0x4321, IRLCNTR5); + + for (i=0; i<14; i++) + make_hs7751rvoip_irq(i); +} diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/led.c b/arch/sh/boards/renesas/hs7751rvoip/led.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/hs7751rvoip/led.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,27 @@ +/* + * linux/arch/sh/kernel/setup_hs7751rvoip.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales HS7751RVoIP Support. + * + * Modified for HS7751RVoIP by + * Atom Create Engineering Co., Ltd. 2002. + * Lineo uSolutions, Inc. 2003. + */ + +#include +#include +#include + +extern unsigned int debug_counter; + +void debug_led_disp(void) +{ + unsigned short value; + + value = (unsigned char)debug_counter++; + ctrl_outb((0xf0|value), PA_OUTPORTR); + if (value == 0x0f) + debug_counter = 0; +} diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/mach.c b/arch/sh/boards/renesas/hs7751rvoip/mach.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/hs7751rvoip/mach.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,55 @@ +/* + * linux/arch/sh/kernel/mach_hs7751rvoip.c + * + * Minor tweak of mach_se.c file to reference hs7751rvoip-specific items. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Renesas Technology sales HS7751RVoIP + */ + +#include +#include + +#include +#include +#include +#include + +extern void init_hs7751rvoip_IRQ(void); +extern void *hs7751rvoip_ioremap(unsigned long, unsigned long); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_hs7751rvoip __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = hs7751rvoip_inb, + .mv_inw = hs7751rvoip_inw, + .mv_inl = hs7751rvoip_inl, + .mv_outb = hs7751rvoip_outb, + .mv_outw = hs7751rvoip_outw, + .mv_outl = hs7751rvoip_outl, + + .mv_inb_p = hs7751rvoip_inb_p, + .mv_inw_p = hs7751rvoip_inw, + .mv_inl_p = hs7751rvoip_inl, + .mv_outb_p = hs7751rvoip_outb_p, + .mv_outw_p = hs7751rvoip_outw, + .mv_outl_p = hs7751rvoip_outl, + + .mv_insb = hs7751rvoip_insb, + .mv_insw = hs7751rvoip_insw, + .mv_insl = hs7751rvoip_insl, + .mv_outsb = hs7751rvoip_outsb, + .mv_outsw = hs7751rvoip_outsw, + .mv_outsl = hs7751rvoip_outsl, + + .mv_ioremap = hs7751rvoip_ioremap, + .mv_isa_port2addr = hs7751rvoip_isa_port2addr, + .mv_init_irq = init_hs7751rvoip_IRQ, +}; +ALIAS_MV(hs7751rvoip) diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/pci.c b/arch/sh/boards/renesas/hs7751rvoip/pci.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/hs7751rvoip/pci.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,150 @@ +/* + * linux/arch/sh/kernel/pci-hs7751rvoip.c + * + * Author: Ian DaSilva (idasilva@mvista.com) + * + * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * PCI initialization for the Renesas SH7751R HS7751RVoIP board + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../../../drivers/pci/pci-sh7751.h" +#include + +#define PCIMCR_MRSET_OFF 0xBFFFFFFF +#define PCIMCR_RFSH_OFF 0xFFFFFFFB + +/* + * Only long word accesses of the PCIC's internal local registers and the + * configuration registers from the CPU is supported. + */ +#define PCIC_WRITE(x,v) writel((v), PCI_REG(x)) +#define PCIC_READ(x) readl(PCI_REG(x)) + +/* + * Description: This function sets up and initializes the pcic, sets + * up the BARS, maps the DRAM into the address space etc, etc. + */ +int __init pcibios_init_platform(void) +{ + unsigned long bcr1, wcr1, wcr2, wcr3, mcr; + unsigned short bcr2, bcr3; + + /* + * Initialize the slave bus controller on the pcic. The values used + * here should not be hardcoded, but they should be taken from the bsc + * on the processor, to make this function as generic as possible. + * (i.e. Another sbc may usr different SDRAM timing settings -- in order + * for the pcic to work, its settings need to be exactly the same.) + */ + bcr1 = (*(volatile unsigned long *)(SH7751_BCR1)); + bcr2 = (*(volatile unsigned short *)(SH7751_BCR2)); + bcr3 = (*(volatile unsigned short *)(SH7751_BCR3)); + wcr1 = (*(volatile unsigned long *)(SH7751_WCR1)); + wcr2 = (*(volatile unsigned long *)(SH7751_WCR2)); + wcr3 = (*(volatile unsigned long *)(SH7751_WCR3)); + mcr = (*(volatile unsigned long *)(SH7751_MCR)); + + bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */ + (*(volatile unsigned long *)(SH7751_BCR1)) = bcr1; + + bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ + PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */ + PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */ + PCIC_WRITE(SH7751_PCIBCR3, bcr3); /* PCIC BCR3 */ + PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */ + PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */ + PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */ + mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; + PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */ + + /* Enable all interrupts, so we know what to fix */ + PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff); + PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f); + + /* Set up standard PCI config registers */ + PCIC_WRITE(SH7751_PCICONF1, 0xFB900047); /* Bus Master, Mem & I/O access */ + PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */ + PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */ + PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */ + PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */ + PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */ + PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */ + PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */ + PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */ + PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */ + + /* Now turn it on... */ + PCIC_WRITE(SH7751_PCICR, 0xa5000001); + + /* + * Set PCIMBR and PCIIOBR here, assuming a single window + * (16M MEM, 256K IO) is enough. If a larger space is + * needed, the readx/writex and inx/outx functions will + * have to do more (e.g. setting registers for each call). + */ + + /* + * Set the MBR so PCI address is one-to-one with window, + * meaning all calls go straight through... use ifdef to + * catch erroneous assumption. + */ + BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE); + + PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM); + + /* Set IOBR for window containing area specified in pci.h */ + PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK)); + + /* All done, may as well say so... */ + printk("SH7751R PCI: Finished initialization of the PCI controller\n"); + + return 1; +} + +int __init pcibios_map_platform_irq(u8 slot, u8 pin) +{ + switch (slot) { + case 0: return IRQ_PCISLOT; /* PCI Extend slot */ + case 1: return IRQ_PCMCIA; /* PCI Cardbus Bridge */ + case 2: return IRQ_PCIETH; /* Realtek Ethernet controller */ + case 3: return IRQ_PCIHUB; /* Realtek Ethernet Hub controller */ + default: + printk("PCI: Bad IRQ mapping request for slot %d\n", slot); + return -1; + } +} + +static struct resource sh7751_io_resource = { + .name = "SH7751_IO", + .start = 0x4000, + .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7751_mem_resource = { + .name = "SH7751_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops sh7751_pci_ops; + +struct pci_channel board_pci_channels[] = { + { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; +EXPORT_SYMBOL(board_pci_channels); diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,89 @@ +/* + * linux/arch/sh/kernel/setup_hs7751rvoip.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales HS7751RVoIP Support. + * + * Modified for HS7751RVoIP by + * Atom Create Engineering Co., Ltd. 2002. + * Lineo uSolutions, Inc. 2003. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* defined in mm/ioremap.c */ +extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); + +unsigned int debug_counter; + +const char *get_system_type(void) +{ + return "HS7751RVoIP"; +} + +/* + * Initialize the board + */ +void __init platform_setup(void) +{ + printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); + ctrl_outb(0xf0, PA_OUTPORTR); + debug_counter = 0; +} + +void *area5_io8_base; +void *area6_io8_base; +void *area5_io16_base; +void *area6_io16_base; + +int __init cf_init(void) +{ + pgprot_t prot; + unsigned long paddrbase, psize; + + /* open I/O area window */ + paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800)); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16); + area5_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area5_io16_base) { + printk("allocate_cf_area : can't open CF I/O window!\n"); + return -ENOMEM; + } + + /* XXX : do we need attribute and common-memory area also? */ + + paddrbase = virt_to_phys((void *)PA_AREA6_IO); + psize = PAGE_SIZE; +#if defined(CONFIG_HS7751RVOIP_CODEC) + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8); +#else + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8); +#endif + area6_io8_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area6_io8_base) { + printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n"); + return -ENOMEM; + } + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); + area6_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area6_io16_base) { + printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n"); + return -ENOMEM; + } + + return 0; +} + +__initcall (cf_init); diff -Nru a/arch/sh/boards/renesas/rts7751r2d/Makefile b/arch/sh/boards/renesas/rts7751r2d/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/rts7751r2d/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,10 @@ +# +# Makefile for the RTS7751R2D specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y := mach.o setup.o io.o irq.o led.o + diff -Nru a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/rts7751r2d/io.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,319 @@ +/* + * linux/arch/sh/kernel/io_rts7751r2d.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Renesas Technology sales RTS7751R2D. + * + * Initial version only to support LAN access; some + * placeholder code from io_rts7751r2d.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "../../../drivers/pci/pci-sh7751.h" + +/* + * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC) + * of the 7751R processor, and has a SuperIO accessible via the PCI. + * The board also includes a PCMCIA controller on its memory bus, + * like the other Solution Engine boards. + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +static inline unsigned long port2adr(unsigned int port) +{ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + if (port == 0x3f6) + return (PA_AREA5_IO + 0x80c); + else + return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); + else + maybebadio(port2adr, (unsigned long)port); + + return port; +} + +static inline unsigned long port88796l(unsigned int port, int flag) +{ + unsigned long addr; + + if (flag) + addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1); + else + addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000; + + return addr; +} + +/* The 7751R RTS7751R2D seems to have everything hooked */ +/* up pretty normally (nothing on high-bytes only...) so this */ +/* shouldn't be needed */ +static inline int shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return 0; + else + return 1; +} + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + +#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE) +#define CHECK_AX88796L_PORT(port) \ + ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20))) +#else +#define CHECK_AX88796L_PORT(port) (0) +#endif + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char rts7751r2d_inb(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; + else if (PXSEG(port)) + return *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); + else + return (*(volatile unsigned short *)port2adr(port) & 0xff); +} + +unsigned char rts7751r2d_inb_p(unsigned long port) +{ + unsigned char v; + + if (CHECK_AX88796L_PORT(port)) + v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; + else if (PXSEG(port)) + v = *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); + else + v = (*(volatile unsigned short *)port2adr(port) & 0xff); + delay(); + + return v; +} + +unsigned short rts7751r2d_inw(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(inw, port); + else if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); + else + maybebadio(inw, port); + + return 0; +} + +unsigned int rts7751r2d_inl(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(inl, port); + else if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned long *)PCI_IOMAP(port); + else + maybebadio(inl, port); + + return 0; +} + +void rts7751r2d_outb(unsigned char value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + *((volatile unsigned short *)port88796l(port, 0)) = value; + else if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; +} + +void rts7751r2d_outb_p(unsigned char value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + *((volatile unsigned short *)port88796l(port, 0)) = value; + else if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned char *)PCI_IOMAP(port) = value; + else + *(volatile unsigned short *)port2adr(port) = value; + delay(); +} + +void rts7751r2d_outw(unsigned short value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(outw, port); + else if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned short *)PCI_IOMAP(port) = value; + else + maybebadio(outw, port); +} + +void rts7751r2d_outl(unsigned int value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(outl, port); + else if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned long *)PCI_IOMAP(port) = value; + else + maybebadio(outl, port); +} + +void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count) +{ + volatile __u8 *bp; + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) { + p = (volatile unsigned short *)port88796l(port, 0); + while (count--) *((unsigned char *) addr)++ = *p & 0xff; + } else if (PXSEG(port)) + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + bp = (__u8 *)PCI_IOMAP(port); + while (count--) *((volatile unsigned char *) addr)++ = *bp; + } else { + p = (volatile unsigned short *)port2adr(port); + while (count--) *((unsigned char *) addr)++ = *p & 0xff; + } +} + +void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) + p = (volatile unsigned short *)port88796l(port, 1); + else if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *((__u16 *) addr)++ = *p; +} + +void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(insl, port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *((__u32 *) addr)++ = *p; + } else + maybebadio(insl, port); +} + +void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u8 *bp; + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) { + p = (volatile unsigned short *)port88796l(port, 0); + while (count--) *p = *((unsigned char *) addr)++; + } else if (PXSEG(port)) + while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + bp = (__u8 *)PCI_IOMAP(port); + while (count--) *bp = *((volatile unsigned char *) addr)++; + } else { + p = (volatile unsigned short *)port2adr(port); + while (count--) *p = *((unsigned char *) addr)++; + } +} + +void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p; + + if (CHECK_AX88796L_PORT(port)) + p = (volatile unsigned short *)port88796l(port, 1); + else if (PXSEG(port)) + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); + else + p = (volatile unsigned short *)port2adr(port); + while (count--) *p = *((__u16 *) addr)++; +} + +void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(outsl, port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + + while (count--) *p = *((__u32 *) addr)++; + } else + maybebadio(outsl, port); +} + +void *rts7751r2d_ioremap(unsigned long offset, unsigned long size) +{ + if (offset >= 0xfd000000) + return (void *)offset; + else + return (void *)P2SEGADDR(offset); +} +EXPORT_SYMBOL(rts7751r2d_ioremap); + +unsigned long rts7751r2d_isa_port2addr(unsigned long offset) +{ + return port2adr(offset); +} diff -Nru a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,135 @@ +/* + * linux/arch/sh/boards/renesas/rts7751r2d/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales RTS7751R2D Support. + * + * Modified for RTS7751R2D by + * Atom Create Engineering Co., Ltd. 2002. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_RTS7751R2D_REV11) +static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; +#else +static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; +#endif + +extern int voyagergx_irq_demux(int irq); +extern void setup_voyagergx_irq(void); + +static void enable_rts7751r2d_irq(unsigned int irq); +static void disable_rts7751r2d_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_rts7751r2d_irq disable_rts7751r2d_irq + +static void ack_rts7751r2d_irq(unsigned int irq); +static void end_rts7751r2d_irq(unsigned int irq); + +static unsigned int startup_rts7751r2d_irq(unsigned int irq) +{ + enable_rts7751r2d_irq(irq); + return 0; /* never anything pending */ +} + +static void disable_rts7751r2d_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); + + /* Set the priority in IPR to 0 */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR1); + val &= mask; + ctrl_outw(val, IRLCNTR1); + local_irq_restore(flags); +} + +static void enable_rts7751r2d_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short val; + unsigned short value = (0x0001 << mask_pos[irq]); + + /* Set priority in IPR back to original value */ + local_irq_save(flags); + val = ctrl_inw(IRLCNTR1); + val |= value; + ctrl_outw(val, IRLCNTR1); + local_irq_restore(flags); +} + +int rts7751r2d_irq_demux(int irq) +{ + int demux_irq; + + demux_irq = voyagergx_irq_demux(irq); + return demux_irq; +} + +static void ack_rts7751r2d_irq(unsigned int irq) +{ + disable_rts7751r2d_irq(irq); +} + +static void end_rts7751r2d_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_rts7751r2d_irq(irq); +} + +static struct hw_interrupt_type rts7751r2d_irq_type = { + "RTS7751R2D IRQ", + startup_rts7751r2d_irq, + shutdown_rts7751r2d_irq, + enable_rts7751r2d_irq, + disable_rts7751r2d_irq, + ack_rts7751r2d_irq, + end_rts7751r2d_irq, +}; + +static void make_rts7751r2d_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &rts7751r2d_irq_type; + disable_rts7751r2d_irq(irq); +} + +/* + * Initialize IRQ setting + */ +void __init init_rts7751r2d_IRQ(void) +{ + int i; + + /* IRL0=KEY Input + * IRL1=Ethernet + * IRL2=CF Card + * IRL3=CF Card Insert + * IRL4=PCMCIA + * IRL5=VOYAGER + * IRL6=RTC Alarm + * IRL7=RTC Timer + * IRL8=SD Card + * IRL9=PCI Slot #1 + * IRL10=PCI Slot #2 + * IRL11=Extention #0 + * IRL12=Extention #1 + * IRL13=Extention #2 + * IRL14=Extention #3 + */ + + for (i=0; i<15; i++) + make_rts7751r2d_irq(i); + + setup_voyagergx_irq(); +} diff -Nru a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/rts7751r2d/led.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,67 @@ +/* + * linux/arch/sh/kernel/led_rts7751r2d.c + * + * Copyright (C) Atom Create Engineering Co., Ltd. + * + * May be copied or modified under the terms of GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains Renesas Technology Sales RTS7751R2D specific LED code. + */ + +#include +#include +#include + +extern unsigned int debug_counter; + +#ifdef CONFIG_HEARTBEAT + +#include + +/* Cycle the LED's in the clasic Knightriger/Sun pattern */ +void heartbeat_rts7751r2d(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short *p = (volatile unsigned short *)PA_OUTPORT; + static unsigned bit = 0, up = 1; + + cnt += 1; + if (cnt < period) + return; + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110 + */ + period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3< +#include +#include + +#include +#include +#include +#include + +extern void heartbeat_rts7751r2d(void); +extern void init_rts7751r2d_IRQ(void); +extern void *rts7751r2d_ioremap(unsigned long, unsigned long); +extern int rts7751r2d_irq_demux(int irq); + +extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int); +extern void voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_rts7751r2d __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = rts7751r2d_inb, + .mv_inw = rts7751r2d_inw, + .mv_inl = rts7751r2d_inl, + .mv_outb = rts7751r2d_outb, + .mv_outw = rts7751r2d_outw, + .mv_outl = rts7751r2d_outl, + + .mv_inb_p = rts7751r2d_inb_p, + .mv_inw_p = rts7751r2d_inw, + .mv_inl_p = rts7751r2d_inl, + .mv_outb_p = rts7751r2d_outb_p, + .mv_outw_p = rts7751r2d_outw, + .mv_outl_p = rts7751r2d_outl, + + .mv_insb = rts7751r2d_insb, + .mv_insw = rts7751r2d_insw, + .mv_insl = rts7751r2d_insl, + .mv_outsb = rts7751r2d_outsb, + .mv_outsw = rts7751r2d_outsw, + .mv_outsl = rts7751r2d_outsl, + + .mv_ioremap = rts7751r2d_ioremap, + .mv_isa_port2addr = rts7751r2d_isa_port2addr, + .mv_init_irq = init_rts7751r2d_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_rts7751r2d, +#endif + .mv_irq_demux = rts7751r2d_irq_demux, + + .mv_consistent_alloc = voyagergx_consistent_alloc, + .mv_consistent_free = voyagergx_consistent_free, +}; +ALIAS_MV(rts7751r2d) diff -Nru a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,31 @@ +/* + * linux/arch/sh/kernel/setup_rts7751r2d.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales RTS7751R2D Support. + * + * Modified for RTS7751R2D by + * Atom Create Engineering Co., Ltd. 2002. + */ + +#include +#include +#include + +unsigned int debug_counter; + +const char *get_system_type(void) +{ + return "RTS7751R2D"; +} + +/* + * Initialize the board + */ +void __init platform_setup(void) +{ + printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); + ctrl_outw(0x0000, PA_OUTPORT); + debug_counter = 0; +} diff -Nru a/arch/sh/boards/renesas/systemh/Makefile b/arch/sh/boards/renesas/systemh/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/systemh/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,13 @@ +# +# Makefile for the SystemH specific parts of the kernel +# + +obj-y := setup.o irq.o io.o + +# XXX: This wants to be consolidated in arch/sh/drivers/pci, and more +# importantly, with the generic sh7751_pcic_init() code. For now, we'll +# just abuse the hell out of kbuild, because we can.. + +obj-$(CONFIG_PCI) += pci.o +pci-y := ../../se/7751/pci.o + diff -Nru a/arch/sh/boards/renesas/systemh/io.c b/arch/sh/boards/renesas/systemh/io.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/systemh/io.c 2004-06-26 17:09:16 -07:00 @@ -0,0 +1,283 @@ +/* + * linux/arch/sh/boards/systemh/io.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Hitachi 7751 Systemh. + * + */ + +#include +#include +#include +#include +#include + +#include +#include "../../drivers/pci/pci-sh7751.h" + +/* + * The 7751 SystemH Engine uses the built-in PCI controller (PCIC) + * of the 7751 processor, and has a SuperIO accessible on its memory + * bus. + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) +#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area + of smc lan chip*/ + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +static inline volatile __u16 * +port2adr(unsigned int port) +{ + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); +#if 0 + else + return (volatile __u16 *) (PA_SUPERIO + (port << 1)); +#endif + maybebadio(name,(unsigned long)port); + return (volatile __u16*)port; +} + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char sh7751systemh_inb(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); + else if (port <= 0x3F1) + return *(volatile unsigned char *)ETHER_IOMAP(port); + else + return (*port2adr(port))&0xff; +} + +unsigned char sh7751systemh_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)) + v = *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (port <= 0x3F1) + v = *(volatile unsigned char *)ETHER_IOMAP(port); + else + v = (*port2adr(port))&0xff; + delay(); + return v; +} + +unsigned short sh7751systemh_inw(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); + else if (port >= 0x2000) + return *port2adr(port); + else if (port <= 0x3F1) + return *(volatile unsigned int *)ETHER_IOMAP(port); + else + maybebadio(inw, port); + return 0; +} + +unsigned int sh7751systemh_inl(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned int *)PCI_IOMAP(port); + else if (port >= 0x2000) + return *port2adr(port); + else if (port <= 0x3F1) + return *(volatile unsigned int *)ETHER_IOMAP(port); + else + maybebadio(inl, port); + return 0; +} + +void sh7751systemh_outb(unsigned char value, unsigned long port) +{ + + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; + else if (port <= 0x3F1) + *(volatile unsigned char *)ETHER_IOMAP(port) = value; + else + *(port2adr(port)) = value; +} + +void sh7751systemh_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; + else if (port <= 0x3F1) + *(volatile unsigned char *)ETHER_IOMAP(port) = value; + else + *(port2adr(port)) = value; + delay(); +} + +void sh7751systemh_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned short *)PCI_IOMAP(port)) = value; + else if (port >= 0x2000) + *port2adr(port) = value; + else if (port <= 0x3F1) + *(volatile unsigned short *)ETHER_IOMAP(port) = value; + else + maybebadio(outw, port); +} + +void sh7751systemh_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned long*)PCI_IOMAP(port)) = value; + else + maybebadio(outl, port); +} + +void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *p = addr; + while (count--) *p++ = sh7751systemh_inb(port); +} + +void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) +{ + unsigned short *p = addr; + while (count--) *p++ = sh7751systemh_inw(port); +} + +void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(insl, port); +} + +void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *p = (unsigned char*)addr; + while (count--) sh7751systemh_outb(*p++, port); +} + +void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count) +{ + unsigned short *p = (unsigned short*)addr; + while (count--) sh7751systemh_outw(*p++, port); +} + +void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(outsw, port); +} + +/* For read/write calls, just copy generic (pass-thru); PCIMBR is */ +/* already set up. For a larger memory space, these would need to */ +/* reset PCIMBR as needed on a per-call basis... */ + +unsigned char sh7751systemh_readb(unsigned long addr) +{ + return *(volatile unsigned char*)addr; +} + +unsigned short sh7751systemh_readw(unsigned long addr) +{ + return *(volatile unsigned short*)addr; +} + +unsigned int sh7751systemh_readl(unsigned long addr) +{ + return *(volatile unsigned long*)addr; +} + +void sh7751systemh_writeb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned char*)addr = b; +} + +void sh7751systemh_writew(unsigned short b, unsigned long addr) +{ + *(volatile unsigned short*)addr = b; +} + +void sh7751systemh_writel(unsigned int b, unsigned long addr) +{ + *(volatile unsigned long*)addr = b; +} + + + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + +#if 0 +static int +sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); + return 0; +} +#endif + +unsigned long +sh7751systemh_isa_port2addr(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; +} diff -Nru a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/systemh/irq.c 2004-06-26 17:09:17 -07:00 @@ -0,0 +1,111 @@ +/* + * linux/arch/sh/boards/systemh/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi SystemH Support. + * + * Modified for 7751 SystemH by + * Jonathan Short. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* address of external interrupt mask register + * address must be set prior to use these (maybe in init_XXX_irq()) + * XXX : is it better to use .config than specifying it in code? */ +static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; +static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; + +/* forward declaration */ +static unsigned int startup_systemh_irq(unsigned int irq); +static void shutdown_systemh_irq(unsigned int irq); +static void enable_systemh_irq(unsigned int irq); +static void disable_systemh_irq(unsigned int irq); +static void mask_and_ack_systemh(unsigned int); +static void end_systemh_irq(unsigned int irq); + +/* hw_interrupt_type */ +static struct hw_interrupt_type systemh_irq_type = { + " SystemH Register", + startup_systemh_irq, + shutdown_systemh_irq, + enable_systemh_irq, + disable_systemh_irq, + mask_and_ack_systemh, + end_systemh_irq +}; + +static unsigned int startup_systemh_irq(unsigned int irq) +{ + enable_systemh_irq(irq); + return 0; /* never anything pending */ +} + +static void shutdown_systemh_irq(unsigned int irq) +{ + disable_systemh_irq(irq); +} + +static void disable_systemh_irq(unsigned int irq) +{ + if (systemh_irq_mask_register) { + unsigned long flags; + unsigned long val, mask = 0x01 << 1; + + /* Clear the "irq"th bit in the mask and set it in the request */ + local_irq_save(flags); + + val = ctrl_inl((unsigned long)systemh_irq_mask_register); + val &= ~mask; + ctrl_outl(val, (unsigned long)systemh_irq_mask_register); + + val = ctrl_inl((unsigned long)systemh_irq_request_register); + val |= mask; + ctrl_outl(val, (unsigned long)systemh_irq_request_register); + + local_irq_restore(flags); + } +} + +static void enable_systemh_irq(unsigned int irq) +{ + if (systemh_irq_mask_register) { + unsigned long flags; + unsigned long val, mask = 0x01 << 1; + + /* Set "irq"th bit in the mask register */ + local_irq_save(flags); + val = ctrl_inl((unsigned long)systemh_irq_mask_register); + val |= mask; + ctrl_outl(val, (unsigned long)systemh_irq_mask_register); + local_irq_restore(flags); + } +} + +static void mask_and_ack_systemh(unsigned int irq) +{ + disable_systemh_irq(irq); +} + +static void end_systemh_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_systemh_irq(irq); +} + +void make_systemh_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &systemh_irq_type; + disable_systemh_irq(irq); +} + diff -Nru a/arch/sh/boards/renesas/systemh/setup.c b/arch/sh/boards/renesas/systemh/setup.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/renesas/systemh/setup.c 2004-06-26 17:09:17 -07:00 @@ -0,0 +1,80 @@ +/* + * linux/arch/sh/boards/systemh/setup.c + * + * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2003 Paul Mundt + * + * Hitachi SystemH Support. + * + * Modified for 7751 SystemH by Jonathan Short. + * + * Rewritten for 2.6 by Paul Mundt. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +extern void make_systemh_irq(unsigned int irq); + +const char *get_system_type(void) +{ + return "7751 SystemH"; +} + +/* + * Initialize IRQ setting + */ +void __init init_7751systemh_IRQ(void) +{ +/* make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); LAN */ +/* make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-4); */ + make_systemh_irq(0xb); /* Ethernet interrupt */ +} + +struct sh_machine_vector mv_7751systemh __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = sh7751systemh_inb, + .mv_inw = sh7751systemh_inw, + .mv_inl = sh7751systemh_inl, + .mv_outb = sh7751systemh_outb, + .mv_outw = sh7751systemh_outw, + .mv_outl = sh7751systemh_outl, + + .mv_inb_p = sh7751systemh_inb_p, + .mv_inw_p = sh7751systemh_inw, + .mv_inl_p = sh7751systemh_inl, + .mv_outb_p = sh7751systemh_outb_p, + .mv_outw_p = sh7751systemh_outw, + .mv_outl_p = sh7751systemh_outl, + + .mv_insb = sh7751systemh_insb, + .mv_insw = sh7751systemh_insw, + .mv_insl = sh7751systemh_insl, + .mv_outsb = sh7751systemh_outsb, + .mv_outsw = sh7751systemh_outsw, + .mv_outsl = sh7751systemh_outsl, + + .mv_readb = sh7751systemh_readb, + .mv_readw = sh7751systemh_readw, + .mv_readl = sh7751systemh_readl, + .mv_writeb = sh7751systemh_writeb, + .mv_writew = sh7751systemh_writew, + .mv_writel = sh7751systemh_writel, + + .mv_isa_port2addr = sh7751systemh_isa_port2addr, + + .mv_init_irq = init_7751systemh_IRQ, +}; +ALIAS_MV(7751systemh) + +int __init platform_setup(void) +{ + return 0; +} + diff -Nru a/arch/sh/boards/se/7300/Makefile b/arch/sh/boards/se/7300/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/se/7300/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,7 @@ +# +# Makefile for the 7300 SolutionEngine specific parts of the kernel +# + +obj-y := setup.o io.o irq.o + +obj-$(CONFIG_HEARTBEAT) += led.o diff -Nru a/arch/sh/boards/se/7300/io.c b/arch/sh/boards/se/7300/io.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/se/7300/io.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,261 @@ +/* + * linux/arch/sh/boards/se/7300/io.c + * + * Copyright (C) 2003 YOSHII Takashi + */ + +#include +#include +#include +#include + +#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) + +struct iop { + unsigned long start, end; + unsigned long base; + struct iop *(*check) (struct iop * p, unsigned long port); + unsigned char (*inb) (struct iop * p, unsigned long port); + unsigned short (*inw) (struct iop * p, unsigned long port); + void (*outb) (struct iop * p, unsigned char value, unsigned long port); + void (*outw) (struct iop * p, unsigned short value, unsigned long port); +}; + +struct iop * +simple_check(struct iop *p, unsigned long port) +{ + if ((p->start <= port) && (port <= p->end)) + return p; + else + badio(check, port); +} + +struct iop * +ide_check(struct iop *p, unsigned long port) +{ + if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) + return p; + return NULL; +} + +unsigned char +simple_inb(struct iop *p, unsigned long port) +{ + return *(unsigned char *) (p->base + port); +} + +unsigned short +simple_inw(struct iop *p, unsigned long port) +{ + return *(unsigned short *) (p->base + port); +} + +void +simple_outb(struct iop *p, unsigned char value, unsigned long port) +{ + *(unsigned char *) (p->base + port) = value; +} + +void +simple_outw(struct iop *p, unsigned short value, unsigned long port) +{ + *(unsigned short *) (p->base + port) = value; +} + +unsigned char +pcc_inb(struct iop *p, unsigned long port) +{ + unsigned long addr = p->base + port + 0x40000; + unsigned long v; + + if (port & 1) + addr += 0x00400000; + v = *(volatile unsigned char *) addr; + return v; +} + +void +pcc_outb(struct iop *p, unsigned char value, unsigned long port) +{ + unsigned long addr = p->base + port + 0x40000; + + if (port & 1) + addr += 0x00400000; + *(volatile unsigned char *) addr = value; +} + +unsigned char +bad_inb(struct iop *p, unsigned long port) +{ + badio(inb, port); +} + +void +bad_outb(struct iop *p, unsigned char value, unsigned long port) +{ + badio(inw, port); +} + +/* MSTLANEX01 LAN at 0xb400:0000 */ +static struct iop laniop = { + .start = 0x300, + .end = 0x30f, + .base = 0xb4000000, + .check = simple_check, + .inb = simple_inb, + .inw = simple_inw, + .outb = simple_outb, + .outw = simple_outw, +}; + +/* NE2000 pc card NIC */ +static struct iop neiop = { + .start = 0x280, + .end = 0x29f, + .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */ + .check = simple_check, + .inb = pcc_inb, + .inw = simple_inw, + .outb = pcc_outb, + .outw = simple_outw, +}; + +/* CF in CF slot */ +static struct iop cfiop = { + .base = 0xb0600000, + .check = ide_check, + .inb = pcc_inb, + .inw = simple_inw, + .outb = pcc_outb, + .outw = simple_outw, +}; + +static __inline__ struct iop * +port2iop(unsigned long port) +{ + if (0) ; +#if defined(CONFIG_SMC91111) + else if (laniop.check(&laniop, port)) + return &laniop; +#endif +#if defined(CONFIG_NE2000) + else if (neiop.check(&neiop, port)) + return &neiop; +#endif +#if defined(CONFIG_IDE) + else if (cfiop.check(&cfiop, port)) + return &cfiop; +#endif + else + return &neiop; /* fallback */ +} + +static inline void +delay(void) +{ + ctrl_inw(0xac000000); + ctrl_inw(0xac000000); +} + +unsigned char +sh7300se_inb(unsigned long port) +{ + struct iop *p = port2iop(port); + return (p->inb) (p, port); +} + +unsigned char +sh7300se_inb_p(unsigned long port) +{ + unsigned char v = sh7300se_inb(port); + delay(); + return v; +} + +unsigned short +sh7300se_inw(unsigned long port) +{ + struct iop *p = port2iop(port); + return (p->inw) (p, port); +} + +unsigned int +sh7300se_inl(unsigned long port) +{ + badio(inl, port); +} + +void +sh7300se_outb(unsigned char value, unsigned long port) +{ + struct iop *p = port2iop(port); + (p->outb) (p, value, port); +} + +void +sh7300se_outb_p(unsigned char value, unsigned long port) +{ + sh7300se_outb(value, port); + delay(); +} + +void +sh7300se_outw(unsigned short value, unsigned long port) +{ + struct iop *p = port2iop(port); + (p->outw) (p, value, port); +} + +void +sh7300se_outl(unsigned int value, unsigned long port) +{ + badio(outl, port); +} + +void +sh7300se_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *a = addr; + struct iop *p = port2iop(port); + while (count--) + *a++ = (p->inb) (p, port); +} + +void +sh7300se_insw(unsigned long port, void *addr, unsigned long count) +{ + unsigned short *a = addr; + struct iop *p = port2iop(port); + while (count--) + *a++ = (p->inw) (p, port); +} + +void +sh7300se_insl(unsigned long port, void *addr, unsigned long count) +{ + badio(insl, port); +} + +void +sh7300se_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *a = (unsigned char *) addr; + struct iop *p = port2iop(port); + while (count--) + (p->outb) (p, *a++, port); +} + +void +sh7300se_outsw(unsigned long port, const void *addr, unsigned long count) +{ + unsigned short *a = (unsigned short *) addr; + struct iop *p = port2iop(port); + while (count--) + (p->outw) (p, *a++, port); +} + +void +sh7300se_outsl(unsigned long port, const void *addr, unsigned long count) +{ + badio(outsw, port); +} diff -Nru a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/se/7300/irq.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,37 @@ +/* + * linux/arch/sh/boards/se/7300/irq.c + * + * Copyright (C) 2003 Takashi Kusuda + * + * SH-Mobile SolutionEngine 7300 Support. + * + */ + +#include +#include +#include +#include +#include +#include + +/* + * Initialize IRQ setting + */ +void __init +init_7300se_IRQ(void) +{ + ctrl_outw(0x0028, PA_EPLD_MODESET); /* mode set IRQ0,1 active low. */ + ctrl_outw(0xa000, INTC_ICR1); /* IRQ mode; IRQ0,1 enable. */ + ctrl_outw(0x0000, PORT_PFCR); /* use F for IRQ[3:0] and SIU. */ + + /* PC_IRQ[0-3] -> IRQ0 (32) */ + make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ); + /* A_IRQ[0-3] -> IRQ1 (33) */ + make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ); + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + + ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ +} diff -Nru a/arch/sh/boards/se/7300/led.c b/arch/sh/boards/se/7300/led.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/se/7300/led.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,69 @@ +/* + * linux/arch/sh/boards/se/7300/led.c + * + * Derived from linux/arch/sh/boards/se/770x/led.c + * + * Copyright (C) 2000 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains Solution Engine specific LED code. + */ + +#include +#include +#include + +static void +mach_led(int position, int value) +{ + volatile unsigned short *p = (volatile unsigned short *) PA_LED; + + if (value) { + *p |= (1 << 8); + } else { + *p &= ~(1 << 8); + } +} + + +/* Cycle the LED's in the clasic Knightrider/Sun pattern */ +void +heartbeat_7300se(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short *p = (volatile unsigned short *) PA_LED; + static unsigned bit = 0, up = 1; + + cnt += 1; + if (cnt < period) { + return; + } + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 + */ + period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))); + + if (up) { + if (bit == 7) { + bit--; + up = 0; + } else { + bit++; + } + } else { + if (bit == 0) { + bit++; + up = 1; + } else { + bit--; + } + } + *p = 1 << (bit + 8); + +} + diff -Nru a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/boards/se/7300/setup.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,66 @@ +/* + * linux/arch/sh/boards/se/7300/setup.c + * + * Copyright (C) 2003 Takashi Kusuda + * + * SH-Mobile SolutionEngine 7300 Support. + * + */ + +#include +#include +#include +#include +#include + +void heartbeat_7300se(void); +void init_7300se_IRQ(void); + +const char * +get_system_type(void) +{ + return "SolutionEngine 7300"; +} + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_7300se __initmv = { + .mv_nr_irqs = 109, + .mv_inb = sh7300se_inb, + .mv_inw = sh7300se_inw, + .mv_inl = sh7300se_inl, + .mv_outb = sh7300se_outb, + .mv_outw = sh7300se_outw, + .mv_outl = sh7300se_outl, + + .mv_inb_p = sh7300se_inb_p, + .mv_inw_p = sh7300se_inw, + .mv_inl_p = sh7300se_inl, + .mv_outb_p = sh7300se_outb_p, + .mv_outw_p = sh7300se_outw, + .mv_outl_p = sh7300se_outl, + + .mv_insb = sh7300se_insb, + .mv_insw = sh7300se_insw, + .mv_insl = sh7300se_insl, + .mv_outsb = sh7300se_outsb, + .mv_outsw = sh7300se_outsw, + .mv_outsl = sh7300se_outsl, + + .mv_init_irq = init_7300se_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_7300se, +#endif +}; + +ALIAS_MV(7300se) +/* + * Initialize the board + */ +void __init +platform_setup(void) +{ + +} diff -Nru a/arch/sh/boards/systemh/Makefile b/arch/sh/boards/systemh/Makefile --- a/arch/sh/boards/systemh/Makefile 2004-06-26 17:09:21 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,13 +0,0 @@ -# -# Makefile for the SystemH specific parts of the kernel -# - -obj-y := setup.o irq.o io.o - -# XXX: This wants to be consolidated in arch/sh/drivers/pci, and more -# importantly, with the generic sh7751_pcic_init() code. For now, we'll -# just abuse the hell out of kbuild, because we can.. - -obj-$(CONFIG_PCI) += pci.o -pci-y := ../se/7751/pci.o - diff -Nru a/arch/sh/boards/systemh/io.c b/arch/sh/boards/systemh/io.c --- a/arch/sh/boards/systemh/io.c 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,283 +0,0 @@ -/* - * linux/arch/sh/boards/systemh/io.c - * - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for Hitachi 7751 Systemh. - * - */ - -#include -#include -#include -#include -#include - -#include -#include "../../drivers/pci/pci-sh7751.h" - -/* - * The 7751 SystemH Engine uses the built-in PCI controller (PCIC) - * of the 7751 processor, and has a SuperIO accessible on its memory - * bus. - */ - -#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) -#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) -#define PCI_IO_AREA SH7751_PCI_IO_BASE -#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE - -#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) -#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area - of smc lan chip*/ - -#define maybebadio(name,port) \ - printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); -} - -static inline volatile __u16 * -port2adr(unsigned int port) -{ - if (port >= 0x2000) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); -#if 0 - else - return (volatile __u16 *) (PA_SUPERIO + (port << 1)); -#endif - maybebadio(name,(unsigned long)port); - return (volatile __u16*)port; -} - -/* In case someone configures the kernel w/o PCI support: in that */ -/* scenario, don't ever bother to check for PCI-window addresses */ - -/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ -#if defined(CONFIG_PCI) -#define CHECK_SH7751_PCIIO(port) \ - ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) -#else -#define CHECK_SH7751_PCIIO(port) (0) -#endif - -/* - * General outline: remap really low stuff [eventually] to SuperIO, - * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) - * is mapped through the PCI IO window. Stuff with high bits (PXSEG) - * should be way beyond the window, and is used w/o translation for - * compatibility. - */ -unsigned char sh7751systemh_inb(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); - else if (port <= 0x3F1) - return *(volatile unsigned char *)ETHER_IOMAP(port); - else - return (*port2adr(port))&0xff; -} - -unsigned char sh7751systemh_inb_p(unsigned long port) -{ - unsigned char v; - - if (PXSEG(port)) - v = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); - else if (port <= 0x3F1) - v = *(volatile unsigned char *)ETHER_IOMAP(port); - else - v = (*port2adr(port))&0xff; - delay(); - return v; -} - -unsigned short sh7751systemh_inw(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); - else if (port >= 0x2000) - return *port2adr(port); - else if (port <= 0x3F1) - return *(volatile unsigned int *)ETHER_IOMAP(port); - else - maybebadio(inw, port); - return 0; -} - -unsigned int sh7751systemh_inl(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned int *)PCI_IOMAP(port); - else if (port >= 0x2000) - return *port2adr(port); - else if (port <= 0x3F1) - return *(volatile unsigned int *)ETHER_IOMAP(port); - else - maybebadio(inl, port); - return 0; -} - -void sh7751systemh_outb(unsigned char value, unsigned long port) -{ - - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; - else if (port <= 0x3F1) - *(volatile unsigned char *)ETHER_IOMAP(port) = value; - else - *(port2adr(port)) = value; -} - -void sh7751systemh_outb_p(unsigned char value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; - else if (port <= 0x3F1) - *(volatile unsigned char *)ETHER_IOMAP(port) = value; - else - *(port2adr(port)) = value; - delay(); -} - -void sh7751systemh_outw(unsigned short value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned short *)PCI_IOMAP(port)) = value; - else if (port >= 0x2000) - *port2adr(port) = value; - else if (port <= 0x3F1) - *(volatile unsigned short *)ETHER_IOMAP(port) = value; - else - maybebadio(outw, port); -} - -void sh7751systemh_outl(unsigned int value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned long*)PCI_IOMAP(port)) = value; - else - maybebadio(outl, port); -} - -void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) -{ - unsigned char *p = addr; - while (count--) *p++ = sh7751systemh_inb(port); -} - -void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) -{ - unsigned short *p = addr; - while (count--) *p++ = sh7751systemh_inw(port); -} - -void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) -{ - maybebadio(insl, port); -} - -void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) -{ - unsigned char *p = (unsigned char*)addr; - while (count--) sh7751systemh_outb(*p++, port); -} - -void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count) -{ - unsigned short *p = (unsigned short*)addr; - while (count--) sh7751systemh_outw(*p++, port); -} - -void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) -{ - maybebadio(outsw, port); -} - -/* For read/write calls, just copy generic (pass-thru); PCIMBR is */ -/* already set up. For a larger memory space, these would need to */ -/* reset PCIMBR as needed on a per-call basis... */ - -unsigned char sh7751systemh_readb(unsigned long addr) -{ - return *(volatile unsigned char*)addr; -} - -unsigned short sh7751systemh_readw(unsigned long addr) -{ - return *(volatile unsigned short*)addr; -} - -unsigned int sh7751systemh_readl(unsigned long addr) -{ - return *(volatile unsigned long*)addr; -} - -void sh7751systemh_writeb(unsigned char b, unsigned long addr) -{ - *(volatile unsigned char*)addr = b; -} - -void sh7751systemh_writew(unsigned short b, unsigned long addr) -{ - *(volatile unsigned short*)addr = b; -} - -void sh7751systemh_writel(unsigned int b, unsigned long addr) -{ - *(volatile unsigned long*)addr = b; -} - - - -/* Map ISA bus address to the real address. Only for PCMCIA. */ - -/* ISA page descriptor. */ -static __u32 sh_isa_memmap[256]; - -#if 0 -static int -sh_isa_mmap(__u32 start, __u32 length, __u32 offset) -{ - int idx; - - if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) - return -1; - - idx = start >> 12; - sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); - printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", - start, length, offset, idx, sh_isa_memmap[idx]); - return 0; -} -#endif - -unsigned long -sh7751systemh_isa_port2addr(unsigned long offset) -{ - int idx; - - idx = (offset >> 12) & 0xff; - offset &= 0xfff; - return sh_isa_memmap[idx] + offset; -} diff -Nru a/arch/sh/boards/systemh/irq.c b/arch/sh/boards/systemh/irq.c --- a/arch/sh/boards/systemh/irq.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,111 +0,0 @@ -/* - * linux/arch/sh/boards/systemh/irq.c - * - * Copyright (C) 2000 Kazumoto Kojima - * - * Hitachi SystemH Support. - * - * Modified for 7751 SystemH by - * Jonathan Short. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -/* address of external interrupt mask register - * address must be set prior to use these (maybe in init_XXX_irq()) - * XXX : is it better to use .config than specifying it in code? */ -static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; -static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; - -/* forward declaration */ -static unsigned int startup_systemh_irq(unsigned int irq); -static void shutdown_systemh_irq(unsigned int irq); -static void enable_systemh_irq(unsigned int irq); -static void disable_systemh_irq(unsigned int irq); -static void mask_and_ack_systemh(unsigned int); -static void end_systemh_irq(unsigned int irq); - -/* hw_interrupt_type */ -static struct hw_interrupt_type systemh_irq_type = { - " SystemH Register", - startup_systemh_irq, - shutdown_systemh_irq, - enable_systemh_irq, - disable_systemh_irq, - mask_and_ack_systemh, - end_systemh_irq -}; - -static unsigned int startup_systemh_irq(unsigned int irq) -{ - enable_systemh_irq(irq); - return 0; /* never anything pending */ -} - -static void shutdown_systemh_irq(unsigned int irq) -{ - disable_systemh_irq(irq); -} - -static void disable_systemh_irq(unsigned int irq) -{ - if (systemh_irq_mask_register) { - unsigned long flags; - unsigned long val, mask = 0x01 << 1; - - /* Clear the "irq"th bit in the mask and set it in the request */ - local_irq_save(flags); - - val = ctrl_inl((unsigned long)systemh_irq_mask_register); - val &= ~mask; - ctrl_outl(val, (unsigned long)systemh_irq_mask_register); - - val = ctrl_inl((unsigned long)systemh_irq_request_register); - val |= mask; - ctrl_outl(val, (unsigned long)systemh_irq_request_register); - - local_irq_restore(flags); - } -} - -static void enable_systemh_irq(unsigned int irq) -{ - if (systemh_irq_mask_register) { - unsigned long flags; - unsigned long val, mask = 0x01 << 1; - - /* Set "irq"th bit in the mask register */ - local_irq_save(flags); - val = ctrl_inl((unsigned long)systemh_irq_mask_register); - val |= mask; - ctrl_outl(val, (unsigned long)systemh_irq_mask_register); - local_irq_restore(flags); - } -} - -static void mask_and_ack_systemh(unsigned int irq) -{ - disable_systemh_irq(irq); -} - -static void end_systemh_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_systemh_irq(irq); -} - -void make_systemh_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].handler = &systemh_irq_type; - disable_systemh_irq(irq); -} - diff -Nru a/arch/sh/boards/systemh/setup.c b/arch/sh/boards/systemh/setup.c --- a/arch/sh/boards/systemh/setup.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,80 +0,0 @@ -/* - * linux/arch/sh/boards/systemh/setup.c - * - * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2003 Paul Mundt - * - * Hitachi SystemH Support. - * - * Modified for 7751 SystemH by Jonathan Short. - * - * Rewritten for 2.6 by Paul Mundt. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -extern void make_systemh_irq(unsigned int irq); - -const char *get_system_type(void) -{ - return "7751 SystemH"; -} - -/* - * Initialize IRQ setting - */ -void __init init_7751systemh_IRQ(void) -{ -/* make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); LAN */ -/* make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-4); */ - make_systemh_irq(0xb); /* Ethernet interrupt */ -} - -struct sh_machine_vector mv_7751systemh __initmv = { - .mv_nr_irqs = 72, - - .mv_inb = sh7751systemh_inb, - .mv_inw = sh7751systemh_inw, - .mv_inl = sh7751systemh_inl, - .mv_outb = sh7751systemh_outb, - .mv_outw = sh7751systemh_outw, - .mv_outl = sh7751systemh_outl, - - .mv_inb_p = sh7751systemh_inb_p, - .mv_inw_p = sh7751systemh_inw, - .mv_inl_p = sh7751systemh_inl, - .mv_outb_p = sh7751systemh_outb_p, - .mv_outw_p = sh7751systemh_outw, - .mv_outl_p = sh7751systemh_outl, - - .mv_insb = sh7751systemh_insb, - .mv_insw = sh7751systemh_insw, - .mv_insl = sh7751systemh_insl, - .mv_outsb = sh7751systemh_outsb, - .mv_outsw = sh7751systemh_outsw, - .mv_outsl = sh7751systemh_outsl, - - .mv_readb = sh7751systemh_readb, - .mv_readw = sh7751systemh_readw, - .mv_readl = sh7751systemh_readl, - .mv_writeb = sh7751systemh_writeb, - .mv_writew = sh7751systemh_writew, - .mv_writel = sh7751systemh_writel, - - .mv_isa_port2addr = sh7751systemh_isa_port2addr, - - .mv_init_irq = init_7751systemh_IRQ, -}; -ALIAS_MV(7751systemh) - -int __init platform_setup(void) -{ - return 0; -} - diff -Nru a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile --- a/arch/sh/boot/compressed/Makefile 2004-06-26 17:09:18 -07:00 +++ b/arch/sh/boot/compressed/Makefile 2004-06-26 17:09:18 -07:00 @@ -15,7 +15,11 @@ # # IMAGE_OFFSET is the load offset of the compression loader +# Assign dummy values if these 2 variables are not defined, +# in order to suppress error message. # +CONFIG_MEMORY_START ?= 0x0c000000 +CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 IMAGE_OFFSET := $(shell printf "0x%8x" $$[0x80000000+$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds.s diff -Nru a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c --- a/arch/sh/boot/compressed/misc.c 2004-06-26 17:09:16 -07:00 +++ b/arch/sh/boot/compressed/misc.c 2004-06-26 17:09:16 -07:00 @@ -1,7 +1,7 @@ /* * arch/sh/boot/compressed/misc.c - * - * This is a collection of several routines from gzip-1.0.3 + * + * This is a collection of several routines from gzip-1.0.3 * adapted for Linux. * * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 @@ -52,7 +52,7 @@ #define RESERVED 0xC0 /* bit 6,7: reserved */ #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - + /* Diagnostic functions */ #ifdef DEBUG # define Assert(cond,msg) {if(!(cond)) error(msg);} @@ -75,7 +75,7 @@ static void error(char *m); static void gzip_mark(void **); static void gzip_release(void **); - + extern char input_data[]; extern int input_len; @@ -83,20 +83,19 @@ static uch *output_data; static unsigned long output_ptr = 0; - static void *malloc(int size); static void free(void *where); static void error(char *m); static void gzip_mark(void **); static void gzip_release(void **); - -static void puts(const char *); - + +int puts(const char *); + extern int _text; /* Defined in vmlinux.lds.S */ extern int _end; static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; - + #define HEAP_SIZE 0x10000 #include "../../../../lib/inflate.c" @@ -134,7 +133,7 @@ } #ifdef CONFIG_SH_STANDARD_BIOS -static int strlen(const char *s) +size_t strlen(const char *s) { int i = 0; @@ -143,14 +142,17 @@ return i; } -void puts(const char *s) +int puts(const char *s) { - sh_bios_console_write(s, strlen(s)); + int len = strlen(s); + sh_bios_console_write(s, len); + return len; } #else -void puts(const char *s) +int puts(const char *s) { - /* This should be updated to use the sh-sci routines */ + /* This should be updated to use the sh-sci routines */ + return 0; } #endif @@ -198,9 +200,9 @@ ulg c = crc; /* temporary variable */ unsigned n; uch *in, *out, ch; - + in = window; - out = &output_data[output_ptr]; + out = &output_data[output_ptr]; for (n = 0; n < outcnt; n++) { ch = *out++ = *in++; c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); diff -Nru a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig --- a/arch/sh/cchips/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/arch/sh/cchips/Kconfig 2004-06-26 17:09:20 -07:00 @@ -1,5 +1,18 @@ menu "Companion Chips" +config VOYAGERGX + bool "VoyagerGX chip support" + depends on SH_RTS7751R2D + help + Selecting this option will support Silicon Motion, Inc. SM501. + Designed to complement needs for the embedded industry, it + provides video and 2D capability. To reduce system cost a + wide variety of include I/O is supported, including analog RGB + and digital LCD Panel interface, 8-bit parallel interface, USB, + UART, IrDA, Zoom Video, AC97 or I2S, SSP, PWM, and I2C. There + are additional GPIO bits that can be used to interface to + external as well. + # A board must have defined HD6446X_SERIES in order to see these config HD6446X_SERIES bool "HD6446x support" diff -Nru a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c --- a/arch/sh/cchips/hd6446x/hd64461/setup.c 2004-06-26 17:09:20 -07:00 +++ b/arch/sh/cchips/hd6446x/hd64461/setup.c 2004-06-26 17:09:20 -07:00 @@ -134,7 +134,7 @@ return __irq_demux(irq); } -static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL }; +static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64461", NULL, NULL }; int __init setup_hd64461(void) { diff -Nru a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c --- a/arch/sh/cchips/hd6446x/hd64465/setup.c 2004-06-26 17:09:21 -07:00 +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c 2004-06-26 17:09:21 -07:00 @@ -154,7 +154,7 @@ return irq; } -static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, 0, "HD64465", NULL, NULL}; +static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64465", NULL, NULL}; static int __init setup_hd64465(void) diff -Nru a/arch/sh/cchips/voyagergx/Makefile b/arch/sh/cchips/voyagergx/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/cchips/voyagergx/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,8 @@ +# +# Makefile for VoyagerGX +# + +obj-y := irq.o setup.o + +obj-$(CONFIG_USB_OHCI_HCD) += consistent.o + diff -Nru a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/cchips/voyagergx/consistent.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,126 @@ +/* + * arch/sh/cchips/voyagergx/consistent.c + * + * Copyright (C) 2004 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct voya_alloc_entry { + struct list_head list; + unsigned long ofs; + unsigned long len; +}; + +static spinlock_t voya_list_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(voya_alloc_list); + +#define OHCI_SRAM_START 0xb0000000 +#define OHCI_HCCA_SIZE 0x100 +#define OHCI_SRAM_SIZE 0x10000 + +void *voyagergx_consistent_alloc(struct device *dev, size_t size, + dma_addr_t *handle, int flag) +{ + struct list_head *list = &voya_alloc_list; + struct voya_alloc_entry *entry; + struct sh_dev *shdev = to_sh_dev(dev); + unsigned long start, end; + unsigned long flags; + + /* + * The SM501 contains an integrated 8051 with its own SRAM. + * Devices within the cchip can all hook into the 8051 SRAM. + * We presently use this for the OHCI. + * + * Everything else goes through consistent_alloc(). + */ + if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] || + (dev->bus == &sh_bus_types[SH_BUS_VIRT] && + shdev->dev_id != SH_DEV_ID_USB_OHCI)) + return consistent_alloc(flag, size, handle); + + start = OHCI_SRAM_START + OHCI_HCCA_SIZE; + + entry = kmalloc(sizeof(struct voya_alloc_entry), GFP_ATOMIC); + if (!entry) + return NULL; + + entry->len = (size + 15) & ~15; + + /* + * The basis for this allocator is dwmw2's malloc.. the + * Matrox allocator :-) + */ + spin_lock_irqsave(&voya_list_lock, flags); + list_for_each(list, &voya_alloc_list) { + struct voya_alloc_entry *p; + + p = list_entry(list, struct voya_alloc_entry, list); + + if (p->ofs - start >= size) + goto out; + + start = p->ofs + p->len; + } + + end = start + (OHCI_SRAM_SIZE - OHCI_HCCA_SIZE); + list = &voya_alloc_list; + + if (end - start >= size) { +out: + entry->ofs = start; + list_add_tail(&entry->list, list); + spin_unlock_irqrestore(&voya_list_lock, flags); + + *handle = start; + return (void *)start; + } + + kfree(entry); + spin_unlock_irqrestore(&voya_list_lock, flags); + + return NULL; +} + +void voyagergx_consistent_free(struct device *dev, size_t size, + void *vaddr, dma_addr_t handle) +{ + struct voya_alloc_entry *entry; + struct sh_dev *shdev = to_sh_dev(dev); + unsigned long flags; + + if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] || + (dev->bus == &sh_bus_types[SH_BUS_VIRT] && + shdev->dev_id != SH_DEV_ID_USB_OHCI)) { + consistent_free(vaddr, size); + return; + } + + spin_lock_irqsave(&voya_list_lock, flags); + list_for_each_entry(entry, &voya_alloc_list, list) { + if (entry->ofs != handle) + continue; + + list_del(&entry->list); + kfree(entry); + + break; + } + spin_unlock_irqrestore(&voya_list_lock, flags); +} + +EXPORT_SYMBOL(voyagergx_consistent_alloc); +EXPORT_SYMBOL(voyagergx_consistent_free); + diff -Nru a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/cchips/voyagergx/irq.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,194 @@ +/* -------------------------------------------------------------------- */ +/* setup_voyagergx.c: */ +/* -------------------------------------------------------------------- */ +/* This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Copyright 2003 (c) Lineo uSolutions,Inc. +*/ +/* -------------------------------------------------------------------- */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void disable_voyagergx_irq(unsigned int irq) +{ + unsigned long flags, val; + unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); + + pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); + local_irq_save(flags); + val = inl(VOYAGER_INT_MASK); + val &= ~mask; + outl(val, VOYAGER_INT_MASK); + local_irq_restore(flags); +} + + +static void enable_voyagergx_irq(unsigned int irq) +{ + unsigned long flags, val; + unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); + + pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); + local_irq_save(flags); + val = inl(VOYAGER_INT_MASK); + val |= mask; + outl(val, VOYAGER_INT_MASK); + local_irq_restore(flags); +} + + +static void mask_and_ack_voyagergx(unsigned int irq) +{ + disable_voyagergx_irq(irq); +} + +static void end_voyagergx_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_voyagergx_irq(irq); +} + +static unsigned int startup_voyagergx_irq(unsigned int irq) +{ + enable_voyagergx_irq(irq); + return 0; +} + +static void shutdown_voyagergx_irq(unsigned int irq) +{ + disable_voyagergx_irq(irq); +} + +static struct hw_interrupt_type voyagergx_irq_type = { + "VOYAGERGX-IRQ", + startup_voyagergx_irq, + shutdown_voyagergx_irq, + enable_voyagergx_irq, + disable_voyagergx_irq, + mask_and_ack_voyagergx, + end_voyagergx_irq, +}; + +static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + printk(KERN_INFO + "VoyagerGX: spurious interrupt, status: 0x%x\n", + inl(INT_STATUS)); + return IRQ_HANDLED; +} + + +/*====================================================*/ + +static struct { + int (*func)(int, void *); + void *dev; +} voyagergx_demux[VOYAGER_IRQ_NUM]; + +void voyagergx_register_irq_demux(int irq, + int (*demux)(int irq, void *dev), void *dev) +{ + voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux; + voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev; +} + +void voyagergx_unregister_irq_demux(int irq) +{ + voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0; +} + +int voyagergx_irq_demux(int irq) +{ + + if (irq == IRQ_VOYAGER ) { + unsigned long i = 0, bit __attribute__ ((unused)); + unsigned long val = inl(INT_STATUS); +#if 1 + if ( val & ( 1 << 1 )){ + i = 1; + } else if ( val & ( 1 << 2 )){ + i = 2; + } else if ( val & ( 1 << 6 )){ + i = 6; + } else if( val & ( 1 << 10 )){ + i = 10; + } else if( val & ( 1 << 11 )){ + i = 11; + } else if( val & ( 1 << 12 )){ + i = 12; + } else if( val & ( 1 << 17 )){ + i = 17; + } else { + printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); + } + pr_debug("voyagergx_irq_demux %d \n", i); +#else + for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++) + if (val & bit) + break; +#endif + if (i < VOYAGER_IRQ_NUM) { + irq = VOYAGER_IRQ_BASE + i; + if (voyagergx_demux[i].func != 0) + irq = voyagergx_demux[i].func(irq, voyagergx_demux[i].dev); + } + } + return irq; +} + +static struct irqaction irq0 = { voyagergx_interrupt, SA_INTERRUPT, 0, "VOYAGERGX", NULL, NULL}; + +void __init setup_voyagergx_irq(void) +{ + int i, flag; + + printk(KERN_INFO "VoyagerGX configured at 0x%x on irq %d(mapped into %d to %d)\n", + VOYAGER_BASE, + IRQ_VOYAGER, + VOYAGER_IRQ_BASE, + VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1); + + for (i=0; i +#include +#include +#include + +static int __init setup_voyagergx(void) +{ + unsigned long val; + + val = inl(DRAM_CTRL); + val |= (DRAM_CTRL_CPU_COLUMN_SIZE_256 | + DRAM_CTRL_CPU_ACTIVE_PRECHARGE | + DRAM_CTRL_CPU_RESET | + DRAM_CTRL_REFRESH_COMMAND | + DRAM_CTRL_BLOCK_WRITE_TIME | + DRAM_CTRL_BLOCK_WRITE_PRECHARGE | + DRAM_CTRL_ACTIVE_PRECHARGE | + DRAM_CTRL_RESET | + DRAM_CTRL_REMAIN_ACTIVE); + outl(val, DRAM_CTRL); + + return 0; +} + +module_init(setup_voyagergx); diff -Nru a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/configs/rts7751r2d_defconfig 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,809 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_SUPERH=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_STB1_HARP is not set +# CONFIG_SH_STB1_OVERDRIVE is not set +# CONFIG_SH_HP620 is not set +# CONFIG_SH_HP680 is not set +# CONFIG_SH_HP690 is not set +# CONFIG_SH_CQREEK is not set +# CONFIG_SH_DMIDA is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_CAT68701 is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_SH2000 is not set +# CONFIG_SH_ADX is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +CONFIG_SH_RTS7751R2D=y +# CONFIG_SH_UNKNOWN is not set +# CONFIG_CPU_SH2 is not set +# CONFIG_CPU_SH3 is not set +CONFIG_CPU_SH4=y +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set +CONFIG_CPU_SUBTYPE_SH7751=y +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +CONFIG_MMU=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1" +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_MEMORY_SET=y +# CONFIG_MEMORY_OVERRIDE is not set +CONFIG_SH_RTC=y +CONFIG_ZERO_PAGE_OFFSET=0x00010000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_PREEMPT is not set +# CONFIG_UBC_WAKEUP is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set +# CONFIG_SH_STORE_QUEUES is not set +# CONFIG_SMP is not set +CONFIG_VOYAGERGX=y +CONFIG_RTS7751R2D_REV11=y +CONFIG_SH_PCLK_FREQ=60000000 +# CONFIG_CPU_FREQ is not set +CONFIG_SH_DMA=y +CONFIG_NR_ONCHIP_DMA_CHANNELS=8 +# CONFIG_NR_DMA_CHANNELS_BOOL is not set +# CONFIG_DMA_PAGE_OPS is not set + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +CONFIG_ISA=y +CONFIG_PCI=y +CONFIG_SH_PCIDMA_NONCOHERENT=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_AUTO_UPDATE_RESOURCES=y +CONFIG_PCI_DMA=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +CONFIG_YENTA=m +CONFIG_CARDBUS=y +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_PROBE=y + +# +# PCI Hotplug Support +# +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_LBD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +CONFIG_NET_ISA=y +# CONFIG_E2100 is not set +# CONFIG_EWRK3 is not set +# CONFIG_EEXPRESS is not set +# CONFIG_EEXPRESS_PRO is not set +# CONFIG_HPLAN_PLUS is not set +# CONFIG_HPLAN is not set +# CONFIG_LP486E is not set +# CONFIG_ETH16I is not set +CONFIG_NE2000=m +# CONFIG_ZNET is not set +# CONFIG_SEEQ8005 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_AIRO is not set +CONFIG_HERMES=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_ATMEL is not set +# CONFIG_PCMCIA_WL3501 is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Userland interfaces +# + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set + +# +# Input Device Drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +CONFIG_SH_SCI=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_RTC_9701JE=y + +# +# Unix 98 PTY support +# +# CONFIG_UNIX98_PTYS is not set +CONFIG_HEARTBEAT=y +# CONFIG_PSMOUSE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_SH_SCI is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Algorithms +# + +# +# I2C Hardware Bus support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=y +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_OSSEMUL is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ISA devices +# +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_YMFPCI=m +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VX222 is not set + +# +# PCMCIA devices +# +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_VXP440 is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_BT878 is not set +CONFIG_SOUND_CMPCI=m +# CONFIG_SOUND_CMPCI_FM is not set +# CONFIG_SOUND_CMPCI_MIDI is not set +# CONFIG_SOUND_CMPCI_JOYSTICK is not set +# CONFIG_SOUND_CMPCI_CM8738 is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_AD1980 is not set +CONFIG_SOUND_VOYAGERGX=m + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_KGDB is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y diff -Nru a/arch/sh/configs/se7300_defconfig b/arch/sh/configs/se7300_defconfig --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/configs/se7300_defconfig 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,461 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_SUPERH=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +# CONFIG_SWAP is not set +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +CONFIG_SH_7300_SOLUTION_ENGINE=y +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_STB1_HARP is not set +# CONFIG_SH_STB1_OVERDRIVE is not set +# CONFIG_SH_HP620 is not set +# CONFIG_SH_HP680 is not set +# CONFIG_SH_HP690 is not set +# CONFIG_SH_CQREEK is not set +# CONFIG_SH_DMIDA is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_CAT68701 is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_SH2000 is not set +# CONFIG_SH_ADX is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_UNKNOWN is not set +# CONFIG_CPU_SH2 is not set +CONFIG_CPU_SH3=y +# CONFIG_CPU_SH4 is not set +# CONFIG_CPU_SUBTYPE_SH7604 is not set +CONFIG_CPU_SUBTYPE_SH7300=y +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set +CONFIG_MMU=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0" +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +# CONFIG_MEMORY_OVERRIDE is not set +CONFIG_SH_DSP=y +# CONFIG_SH_ADC is not set +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00210000 +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_PREEMPT is not set +# CONFIG_UBC_WAKEUP is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set +# CONFIG_SMP is not set +# CONFIG_SH_PCLK_CALC is not set +CONFIG_SH_PCLK_FREQ=33333333 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set +CONFIG_HEARTBEAT=y + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# SH initrd options +# +CONFIG_EMBEDDED_RAMDISK=y +CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz" + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_LBD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Networking support +# +# CONFIG_NET is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +CONFIG_IPMI_HANDLER=y +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=y +# CONFIG_IPMI_SI is not set +CONFIG_IPMI_WATCHDOG=y + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=y +# CONFIG_SH_WDT is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_SH_STANDARD_BIOS=y +CONFIG_EARLY_PRINTK=y +CONFIG_KGDB=y + +# +# KGDB configuration options +# +# CONFIG_MORE_COMPILE_OPTIONS is not set +# CONFIG_KGDB_NMI is not set +# CONFIG_KGDB_THREAD is not set +# CONFIG_SH_KGDB_CONSOLE is not set +# CONFIG_KGDB_SYSRQ is not set +# CONFIG_KGDB_KERNEL_ASSERTS is not set + +# +# Serial port setup +# +CONFIG_KGDB_DEFPORT=1 +CONFIG_KGDB_DEFBAUD=115200 +CONFIG_KGDB_DEFPARITY_N=y +# CONFIG_KGDB_DEFPARITY_E is not set +# CONFIG_KGDB_DEFPARITY_O is not set +CONFIG_KGDB_DEFBITS_8=y +# CONFIG_KGDB_DEFBITS_7 is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff -Nru a/arch/sh/defconfig b/arch/sh/defconfig --- a/arch/sh/defconfig 2004-06-26 17:09:18 -07:00 +++ b/arch/sh/defconfig 2004-06-26 17:09:18 -07:00 @@ -352,7 +352,7 @@ # CONFIG_MAGIC_SYSRQ is not set # CONFIG_DEBUG_SPINLOCK is not set CONFIG_SH_STANDARD_BIOS=y -CONFIG_SH_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK=y # CONFIG_KGDB is not set # CONFIG_FRAME_POINTER is not set diff -Nru a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile --- a/arch/sh/drivers/dma/Makefile 2004-06-26 17:09:17 -07:00 +++ b/arch/sh/drivers/dma/Makefile 2004-06-26 17:09:17 -07:00 @@ -3,6 +3,7 @@ # obj-y += dma-api.o dma-isa.o +obj-$(CONFIG_SYSFS) += dma-sysfs.o obj-$(CONFIG_SH_DMA) += dma-sh.o obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o diff -Nru a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c --- a/arch/sh/drivers/dma/dma-api.c 2004-06-26 17:09:20 -07:00 +++ b/arch/sh/drivers/dma/dma-api.c 2004-06-26 17:09:20 -07:00 @@ -3,23 +3,24 @@ * * SuperH-specific DMA management API * - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003, 2004 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. - */ + */ #include #include #include #include #include +#include #include -struct dma_info dma_info[MAX_DMA_CHANNELS] = { { 0, } }; spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(registered_dmac_list); -/* +/* * A brief note about the reasons for this API as it stands. * * For starters, the old ISA DMA API didn't work for us for a number of @@ -54,124 +55,213 @@ struct dma_info *get_dma_info(unsigned int chan) { - return dma_info + chan; + struct list_head *pos, *tmp; + unsigned int total = 0; + + /* + * Look for each DMAC's range to determine who the owner of + * the channel is. + */ + list_for_each_safe(pos, tmp, ®istered_dmac_list) { + struct dma_info *info = list_entry(pos, struct dma_info, list); + + total += info->nr_channels; + if (chan > total) + continue; + + return info; + } + + return NULL; +} + +struct dma_channel *get_dma_channel(unsigned int chan) +{ + struct dma_info *info = get_dma_info(chan); + + if (!info) + return ERR_PTR(-EINVAL); + + return info->channels + chan; } int get_dma_residue(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->get_residue) - return info->ops->get_residue(info); - + return info->ops->get_residue(channel); + return 0; } int request_dma(unsigned int chan, const char *dev_id) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - down(&info->sem); + down(&channel->sem); if (!info->ops || chan >= MAX_DMA_CHANNELS) { - up(&info->sem); + up(&channel->sem); return -EINVAL; } - - atomic_set(&info->busy, 1); - info->dev_id = dev_id; + atomic_set(&channel->busy, 1); - up(&info->sem); + strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id)); + + up(&channel->sem); if (info->ops->request) - return info->ops->request(info); - + return info->ops->request(channel); + return 0; } void free_dma(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->free) - info->ops->free(info); - - atomic_set(&info->busy, 0); + info->ops->free(channel); + + atomic_set(&channel->busy, 0); } void dma_wait_for_completion(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - if (info->tei_capable) { - wait_event(info->wait_queue, (info->ops->get_residue(info) == 0)); + if (channel->flags & DMA_TEI_CAPABLE) { + wait_event(channel->wait_queue, + (info->ops->get_residue(channel) == 0)); return; } - while (info->ops->get_residue(info)) + while (info->ops->get_residue(channel)) cpu_relax(); } void dma_configure_channel(unsigned int chan, unsigned long flags) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->configure) - info->ops->configure(info, flags); + info->ops->configure(channel, flags); } int dma_xfer(unsigned int chan, unsigned long from, unsigned long to, size_t size, unsigned int mode) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->sar = from; - info->dar = to; - info->count = size; - info->mode = mode; + channel->sar = from; + channel->dar = to; + channel->count = size; + channel->mode = mode; - return info->ops->xfer(info); + return info->ops->xfer(channel); } #ifdef CONFIG_PROC_FS static int dma_read_proc(char *buf, char **start, off_t off, int len, int *eof, void *data) { - struct dma_info *info; + struct list_head *pos, *tmp; char *p = buf; - int i; - for (i = 0, info = dma_info; i < MAX_DMA_CHANNELS; i++, info++) { - if (!atomic_read(&info->busy)) - continue; + if (list_empty(®istered_dmac_list)) + return 0; - p += sprintf(p, "%2d: %14s %s\n", i, - info->ops->name, info->dev_id); + /* + * Iterate over each registered DMAC + */ + list_for_each_safe(pos, tmp, ®istered_dmac_list) { + struct dma_info *info = list_entry(pos, struct dma_info, list); + int i; + + /* + * Iterate over each channel + */ + for (i = 0; i < info->nr_channels; i++) { + struct dma_channel *channel = info->channels + i; + + if (!(channel->flags & DMA_CONFIGURED)) + continue; + + p += sprintf(p, "%2d: %14s %s\n", i, + info->name, channel->dev_id); + } } return p - buf; } #endif -int __init register_dmac(struct dma_ops *ops) + +int __init register_dmac(struct dma_info *info) { int i; - printk("DMA: Registering %s handler.\n", ops->name); + INIT_LIST_HEAD(&info->list); + + printk(KERN_INFO "DMA: Registering %s handler (%d channels).\n", + info->name, info->nr_channels); + + BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); + + /* + * Don't touch pre-configured channels + */ + if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) { + unsigned int size; + + size = sizeof(struct dma_channel) * info->nr_channels; + + info->channels = kmalloc(size, GFP_KERNEL); + if (!info->channels) + return -ENOMEM; + + memset(info->channels, 0, size); + } + + for (i = 0; i < info->nr_channels; i++) { + struct dma_channel *chan = info->channels + i; + + chan->chan = i; + + memcpy(chan->dev_id, "Unused", 7); - for (i = 0; i < MAX_DMA_CHANNELS; i++) { - struct dma_info *info = get_dma_info(i); + if (info->flags & DMAC_CHANNELS_TEI_CAPABLE) + chan->flags |= DMA_TEI_CAPABLE; - info->chan = i; + init_MUTEX(&chan->sem); + init_waitqueue_head(&chan->wait_queue); - init_MUTEX(&info->sem); - init_waitqueue_head(&info->wait_queue); +#ifdef CONFIG_SYSFS + dma_create_sysfs_files(chan); +#endif } + list_add(&info->list, ®istered_dmac_list); + return 0; } +void __exit unregister_dmac(struct dma_info *info) +{ + if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) + kfree(info->channels); + + list_del(&info->list); +} + static int __init dma_api_init(void) { printk("DMA: Registering DMA API.\n"); @@ -191,8 +281,11 @@ EXPORT_SYMBOL(request_dma); EXPORT_SYMBOL(free_dma); +EXPORT_SYMBOL(register_dmac); +EXPORT_SYMBOL(unregister_dmac); EXPORT_SYMBOL(get_dma_residue); EXPORT_SYMBOL(get_dma_info); +EXPORT_SYMBOL(get_dma_channel); EXPORT_SYMBOL(dma_xfer); EXPORT_SYMBOL(dma_wait_for_completion); EXPORT_SYMBOL(dma_configure_channel); diff -Nru a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c --- a/arch/sh/drivers/dma/dma-isa.c 2004-06-26 17:09:18 -07:00 +++ b/arch/sh/drivers/dma/dma-isa.c 2004-06-26 17:09:18 -07:00 @@ -3,13 +3,14 @@ * * Generic ISA DMA wrapper for SH DMA API * - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003, 2004 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. - */ + */ #include +#include #include /* @@ -39,55 +40,67 @@ return flags; } +EXPORT_SYMBOL(claim_dma_lock); void __deprecated release_dma_lock(unsigned long flags) { spin_unlock_irqrestore(&dma_spin_lock, flags); } +EXPORT_SYMBOL(release_dma_lock); void __deprecated disable_dma(unsigned int chan) { /* Nothing */ } +EXPORT_SYMBOL(disable_dma); void __deprecated enable_dma(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->ops->xfer(info); + info->ops->xfer(channel); } +EXPORT_SYMBOL(enable_dma); void clear_dma_ff(unsigned int chan) { /* Nothing */ } +EXPORT_SYMBOL(clear_dma_ff); void set_dma_mode(unsigned int chan, char mode) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->mode = mode; + channel->mode = mode; } +EXPORT_SYMBOL(set_dma_mode); void set_dma_addr(unsigned int chan, unsigned int addr) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; /* * Single address mode is the only thing supported through * this interface. */ - if ((info->mode & DMA_MODE_MASK) == DMA_MODE_READ) { - info->sar = addr; + if ((channel->mode & DMA_MODE_MASK) == DMA_MODE_READ) { + channel->sar = addr; } else { - info->dar = addr; + channel->dar = addr; } } +EXPORT_SYMBOL(set_dma_addr); void set_dma_count(unsigned int chan, unsigned int count) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - info->count = count; + channel->count = count; } +EXPORT_SYMBOL(set_dma_count); diff -Nru a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c --- a/arch/sh/drivers/dma/dma-sh.c 2004-06-26 17:09:20 -07:00 +++ b/arch/sh/drivers/dma/dma-sh.c 2004-06-26 17:09:20 -07:00 @@ -1,10 +1,10 @@ /* - * arch/sh/kernel/cpu/dma.c + * arch/sh/drivers/dma/dma-sh.c * - * Copyright (C) 2000 Takashi YOSHII - * Copyright (C) 2003 Paul Mundt + * SuperH On-chip DMAC Support * - * PC like DMA API for SuperH's DMAC. + * Copyright (C) 2000 Takashi YOSHII + * Copyright (C) 2003, 2004 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -29,43 +29,29 @@ * Defaults to a 64-bit transfer size. */ enum { - XMIT_SZ_64BIT = 0, - XMIT_SZ_8BIT = 1, - XMIT_SZ_16BIT = 2, - XMIT_SZ_32BIT = 3, - XMIT_SZ_256BIT = 4, + XMIT_SZ_64BIT, + XMIT_SZ_8BIT, + XMIT_SZ_16BIT, + XMIT_SZ_32BIT, + XMIT_SZ_256BIT, }; /* * The DMA count is defined as the number of bytes to transfer. */ static unsigned int ts_shift[] = { - [XMIT_SZ_64BIT] 3, - [XMIT_SZ_8BIT] 0, - [XMIT_SZ_16BIT] 1, - [XMIT_SZ_32BIT] 2, - [XMIT_SZ_256BIT] 5, + [XMIT_SZ_64BIT] = 3, + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + [XMIT_SZ_256BIT] = 5, }; -struct sh_dmac_channel { - unsigned long sar; - unsigned long dar; - unsigned long dmatcr; - unsigned long chcr; -} __attribute__ ((aligned(16))); - -struct sh_dmac_info { - struct sh_dmac_channel channel[4]; - unsigned long dmaor; -}; - -static volatile struct sh_dmac_info *sh_dmac = (volatile struct sh_dmac_info *)SH_DMAC_BASE; - static inline unsigned int get_dmte_irq(unsigned int chan) { unsigned int irq; - /* + /* * Normally we could just do DMTE0_IRQ + chan outright, though in the * case of the 7751R, the DMTE IRQs for channels > 4 start right above * the SCIF @@ -84,13 +70,17 @@ * We determine the correct shift size based off of the CHCR transmit size * for the given channel. Since we know that it will take: * - * info->count >> ts_shift[transmit_size] + * info->count >> ts_shift[transmit_size] * * iterations to complete the transfer. */ -static inline unsigned int calc_xmit_shift(struct dma_info *info) +static inline unsigned int calc_xmit_shift(struct dma_channel *chan) { - return ts_shift[(sh_dmac->channel[info->chan].chcr >> 4) & 0x0007]; + u32 chcr = ctrl_inl(CHCR[chan->chan]); + + chcr >>= 4; + + return ts_shift[chcr & 0x0007]; } /* @@ -101,68 +91,79 @@ */ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) { - struct dma_info * info = (struct dma_info *)dev_id; - u32 chcr = sh_dmac->channel[info->chan].chcr; + struct dma_channel *chan = (struct dma_channel *)dev_id; + u32 chcr; + + chcr = ctrl_inl(CHCR[chan->chan]); if (!(chcr & CHCR_TE)) return IRQ_NONE; - sh_dmac->channel[info->chan].chcr = chcr & ~(CHCR_IE | CHCR_DE); + chcr &= ~(CHCR_IE | CHCR_DE); + ctrl_outl(chcr, CHCR[chan->chan]); - wake_up(&info->wait_queue); + wake_up(&chan->wait_queue); return IRQ_HANDLED; } -static int sh_dmac_request_dma(struct dma_info *info) +static int sh_dmac_request_dma(struct dma_channel *chan) { - return request_irq(get_dmte_irq(info->chan), dma_tei, - SA_INTERRUPT, "DMAC Transfer End", info); + return request_irq(get_dmte_irq(chan->chan), dma_tei, + SA_INTERRUPT, "DMAC Transfer End", chan); } -static void sh_dmac_free_dma(struct dma_info *info) +static void sh_dmac_free_dma(struct dma_channel *chan) { - free_irq(get_dmte_irq(info->chan), info); + free_irq(get_dmte_irq(chan->chan), chan); } -static void sh_dmac_configure_channel(struct dma_info *info, unsigned long chcr) +static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr) { if (!chcr) chcr = RS_DUAL; - sh_dmac->channel[info->chan].chcr = chcr; + ctrl_outl(chcr, CHCR[chan->chan]); - info->configured = 1; + chan->flags |= DMA_CONFIGURED; } -static void sh_dmac_enable_dma(struct dma_info *info) +static void sh_dmac_enable_dma(struct dma_channel *chan) { - int irq = get_dmte_irq(info->chan); + int irq = get_dmte_irq(chan->chan); + u32 chcr; + + chcr = ctrl_inl(CHCR[chan->chan]); + chcr |= CHCR_DE | CHCR_IE; + ctrl_outl(chcr, CHCR[chan->chan]); - sh_dmac->channel[info->chan].chcr |= (CHCR_DE | CHCR_IE); enable_irq(irq); } -static void sh_dmac_disable_dma(struct dma_info *info) +static void sh_dmac_disable_dma(struct dma_channel *chan) { - int irq = get_dmte_irq(info->chan); + int irq = get_dmte_irq(chan->chan); + u32 chcr; disable_irq(irq); - sh_dmac->channel[info->chan].chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); + + chcr = ctrl_inl(CHCR[chan->chan]); + chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); + ctrl_outl(chcr, CHCR[chan->chan]); } -static int sh_dmac_xfer_dma(struct dma_info *info) +static int sh_dmac_xfer_dma(struct dma_channel *chan) { - /* + /* * If we haven't pre-configured the channel with special flags, use * the defaults. */ - if (!info->configured) - sh_dmac_configure_channel(info, 0); + if (!(chan->flags & DMA_CONFIGURED)) + sh_dmac_configure_channel(chan, 0); - sh_dmac_disable_dma(info); - - /* + sh_dmac_disable_dma(chan); + + /* * Single-address mode usage note! * * It's important that we don't accidentally write any value to SAR/DAR @@ -177,33 +178,36 @@ * cascading to the PVR2 DMAC. In this case, we still need to write * SAR and DAR, regardless of value, in order for cascading to work. */ - if (info->sar || (mach_is_dreamcast() && info->chan == 2)) - sh_dmac->channel[info->chan].sar = info->sar; - if (info->dar || (mach_is_dreamcast() && info->chan == 2)) - sh_dmac->channel[info->chan].dar = info->dar; - - sh_dmac->channel[info->chan].dmatcr = info->count >> calc_xmit_shift(info); + if (chan->sar || (mach_is_dreamcast() && chan->chan == 2)) + ctrl_outl(chan->sar, SAR[chan->chan]); + if (chan->dar || (mach_is_dreamcast() && chan->chan == 2)) + ctrl_outl(chan->dar, DAR[chan->chan]); + + ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]); - sh_dmac_enable_dma(info); + sh_dmac_enable_dma(chan); return 0; } -static int sh_dmac_get_dma_residue(struct dma_info *info) +static int sh_dmac_get_dma_residue(struct dma_channel *chan) { - if (!(sh_dmac->channel[info->chan].chcr & CHCR_DE)) + if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE)) return 0; - return sh_dmac->channel[info->chan].dmatcr << calc_xmit_shift(info); + return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); } #if defined(CONFIG_CPU_SH4) static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) { - printk("DMAE: DMAOR=%lx\n", sh_dmac->dmaor); + unsigned long dmaor = ctrl_inl(DMAOR); + + printk("DMAE: DMAOR=%lx\n", dmaor); - sh_dmac->dmaor &= ~(DMAOR_NMIF | DMAOR_AE); - sh_dmac->dmaor |= DMAOR_DME; + ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR); + ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR); + ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR); disable_irq(irq); @@ -212,16 +216,23 @@ #endif static struct dma_ops sh_dmac_ops = { - .name = "SuperH DMAC", .request = sh_dmac_request_dma, .free = sh_dmac_free_dma, .get_residue = sh_dmac_get_dma_residue, .xfer = sh_dmac_xfer_dma, .configure = sh_dmac_configure_channel, }; - + +static struct dma_info sh_dmac_info = { + .name = "SuperH DMAC", + .nr_channels = 4, + .ops = &sh_dmac_ops, + .flags = DMAC_CHANNELS_TEI_CAPABLE, +}; + static int __init sh_dmac_init(void) { + struct dma_info *info = &sh_dmac_info; int i; #ifdef CONFIG_CPU_SH4 @@ -231,18 +242,15 @@ return i; #endif - for (i = 0; i < MAX_DMAC_CHANNELS; i++) { + for (i = 0; i < info->nr_channels; i++) { int irq = get_dmte_irq(i); make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - - dma_info[i].ops = &sh_dmac_ops; - dma_info[i].tei_capable = 1; } - sh_dmac->dmaor |= 0x8000 | DMAOR_DME; + ctrl_outl(0x8000 | DMAOR_DME, DMAOR); - return register_dmac(&sh_dmac_ops); + return register_dmac(info); } static void __exit sh_dmac_exit(void) diff -Nru a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/drivers/dma/dma-sysfs.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,133 @@ +/* + * arch/sh/drivers/dma/dma-sysfs.c + * + * sysfs interface for SH DMA API + * + * Copyright (C) 2004 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +static struct sysdev_class dma_sysclass = { + set_kset_name("dma"), +}; + +EXPORT_SYMBOL(dma_sysclass); + +static ssize_t dma_show_devices(struct sys_device *dev, char *buf) +{ + ssize_t len = 0; + int i; + + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + struct dma_info *info = get_dma_info(i); + struct dma_channel *channel = &info->channels[i]; + + len += sprintf(buf + len, "%2d: %14s %s\n", + channel->chan, info->name, + channel->dev_id); + } + + return len; +} + +static SYSDEV_ATTR(devices, S_IRUGO, dma_show_devices, NULL); + +static int __init dma_sysclass_init(void) +{ + int ret; + + ret = sysdev_class_register(&dma_sysclass); + if (ret == 0) + sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr); + + return ret; +} + +postcore_initcall(dma_sysclass_init); + +static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf) +{ + struct dma_channel *channel = to_dma_channel(dev); + return sprintf(buf, "%s\n", channel->dev_id); +} + +static ssize_t dma_store_dev_id(struct sys_device *dev, + const char *buf, size_t count) +{ + struct dma_channel *channel = to_dma_channel(dev); + strcpy(channel->dev_id, buf); + return count; +} + +static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id); + +static ssize_t dma_store_config(struct sys_device *dev, + const char *buf, size_t count) +{ + struct dma_channel *channel = to_dma_channel(dev); + unsigned long config; + + config = simple_strtoul(buf, NULL, 0); + dma_configure_channel(channel->chan, config); + + return count; +} + +static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config); + +static ssize_t dma_show_mode(struct sys_device *dev, char *buf) +{ + struct dma_channel *channel = to_dma_channel(dev); + return sprintf(buf, "0x%08x\n", channel->mode); +} + +static ssize_t dma_store_mode(struct sys_device *dev, + const char *buf, size_t count) +{ + struct dma_channel *channel = to_dma_channel(dev); + channel->mode = simple_strtoul(buf, NULL, 0); + return count; +} + +static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode); + +#define dma_ro_attr(field, fmt) \ +static ssize_t dma_show_##field(struct sys_device *dev, char *buf) \ +{ \ + struct dma_channel *channel = to_dma_channel(dev); \ + return sprintf(buf, fmt, channel->field); \ +} \ +static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL); + +dma_ro_attr(count, "0x%08x\n"); +dma_ro_attr(flags, "0x%08lx\n"); + +int __init dma_create_sysfs_files(struct dma_channel *chan) +{ + struct sys_device *dev = &chan->dev; + int ret; + + dev->id = chan->chan; + dev->cls = &dma_sysclass; + + ret = sysdev_register(dev); + if (ret) + return ret; + + sysdev_create_file(dev, &attr_dev_id); + sysdev_create_file(dev, &attr_count); + sysdev_create_file(dev, &attr_mode); + sysdev_create_file(dev, &attr_flags); + sysdev_create_file(dev, &attr_config); + + return 0; +} + diff -Nru a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile --- a/arch/sh/drivers/pci/Makefile 2004-06-26 17:09:17 -07:00 +++ b/arch/sh/drivers/pci/Makefile 2004-06-26 17:09:17 -07:00 @@ -12,4 +12,5 @@ dma-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o +obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o diff -Nru a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,32 @@ +/* + * arch/sh/drivers/pci/fixups-rts7751r2d.c + * + * RTS7751R2D PCI fixups + * + * Copyright (C) 2003 Lineo uSolutions, Inc. + * Copyright (C) 2004 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include "pci-sh7751.h" +#include + +#define PCIMCR_MRSET_OFF 0xBFFFFFFF +#define PCIMCR_RFSH_OFF 0xFFFFFFFB + +int pci_fixup_pcic(void) +{ + unsigned long mcr; + + outl(0xfb900047, SH7751_PCICONF1); + outl(0xab000001, SH7751_PCICONF4); + + mcr = inl(SH7751_MCR); + mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; + outl(mcr, SH7751_PCIMCR); + + return 0; +} + diff -Nru a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,74 @@ +/* + * linux/arch/sh/kernel/pci-rts7751r2d.c + * + * Author: Ian DaSilva (idasilva@mvista.com) + * + * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * PCI initialization for the Renesas SH7751R RTS7751R2D board + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "pci-sh7751.h" +#include + +int __init pcibios_map_platform_irq(u8 slot, u8 pin) +{ + switch (slot) { + case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ + case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */ + case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */ + case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */ + default: + printk("PCI: Bad IRQ mapping request for slot %d\n", slot); + return -1; + } +} + +static struct resource sh7751_io_resource = { + .name = "SH7751_IO", + .start = 0x4000, + .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7751_mem_resource = { + .name = "SH7751_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops sh7751_pci_ops; + +struct pci_channel board_pci_channels[] = { + { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; +EXPORT_SYMBOL(board_pci_channels); + +static struct sh7751_pci_address_map sh7751_pci_map = { + .window0 = { + .base = SH7751_CS3_BASE_ADDR, + .size = 0x03f00000, + }, + + .flags = SH7751_PCIC_NO_RESET, +}; + +int __init pcibios_init_platform(void) +{ + return sh7751_pcic_init(&sh7751_pci_map); +} + diff -Nru a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c --- a/arch/sh/drivers/pci/ops-snapgear.c 2004-06-26 17:09:19 -07:00 +++ b/arch/sh/drivers/pci/ops-snapgear.c 2004-06-26 17:09:19 -07:00 @@ -61,6 +61,8 @@ .base = SH7751_CS2_BASE_ADDR, .size = SNAPGEAR_LSR1_SIZE, }, + + .flags = SH7751_PCIC_NO_RESET, }; /* diff -Nru a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c --- a/arch/sh/drivers/pci/pci-auto.c 2004-06-26 17:09:21 -07:00 +++ b/arch/sh/drivers/pci/pci-auto.c 2004-06-26 17:09:21 -07:00 @@ -45,7 +45,7 @@ #include #include -#define DEBUG +#undef DEBUG #ifdef DEBUG #define DBG(x...) printk(x) #else @@ -106,7 +106,8 @@ pciauto_setup_bars(struct pci_channel *hose, int top_bus, int current_bus, - int pci_devfn) + int pci_devfn, + int bar_limit) { u32 bar_response, bar_size, bar_value; u32 bar, addr_mask, bar_nr = 0; @@ -114,7 +115,8 @@ u32 * lower_limit; int found_mem64 = 0; - for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4) { + for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) u32 bar_addr; /* Read the old BAR value */ @@ -123,6 +125,7 @@ pci_devfn, bar, &bar_addr); +#endif /* Tickle the BAR and get the response */ early_write_config_dword(hose, top_bus, @@ -137,6 +140,7 @@ bar, &bar_response); +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) /* * Write the old BAR value back out, only update the BAR * if we implicitly want resources to be updated, which @@ -147,6 +151,7 @@ pci_devfn, bar, bar_addr); +#endif /* If BAR is not implemented go to the next BAR */ if (!bar_response) @@ -287,6 +292,11 @@ { u32 temp; + /* + * [jsun] we always bump up baselines a little, so that if there + * nothing behind P2P bridge, we don't wind up overlapping IO/MEM + * spaces. + */ pciauto_lower_memspc += 1; pciauto_lower_iospc += 1; @@ -318,93 +328,99 @@ static void __init pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) { - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_PRIMARY_BUS, current_bus); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SECONDARY_BUS, sub_bus + 1); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, 0xff); - - /* Align memory and I/O to 4KB and 4 byte boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) - & ~(0x1000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) - & ~(0x4 - 1); - - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_IO_BASE_0, pciauto_lower_iospc); + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_PRIMARY_BUS, current_bus); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SECONDARY_BUS, sub_bus + 1); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, 0xff); + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_BASE_0, pciauto_lower_iospc); } static void __init pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) { - u32 temp; + u32 temp; + +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) + /* + * [jsun] we always bump up baselines a little, so that if there + * nothing behind P2P bridge, we don't wind up overlapping IO/MEM + * spaces. + */ + pciauto_lower_memspc += 1; + pciauto_lower_iospc += 1; +#endif + + /* + * Configure subordinate bus number. The PCI subsystem + * bus scan will renumber buses (reserving three additional + * for this PCI<->CardBus bridge for the case where a CardBus + * adapter contains a P2P or CB2CB bridge. + */ + + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, sub_bus); + + /* + * Reserve an additional 4MB for mem space and 16KB for + * I/O space. This should cover any additional space + * requirement of unusual CardBus devices with + * additional bridges that can consume more address space. + * + * Although pcmcia-cs currently will reprogram bridge + * windows, the goal is to add an option to leave them + * alone and use the bridge window ranges as the regions + * that are searched for free resources upon hot-insertion + * of a device. This will allow a PCI<->CardBus bridge + * configured by this routine to happily live behind a + * P2P bridge in a system. + */ +#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) + pciauto_lower_memspc += 0x00400000; + pciauto_lower_iospc += 0x00004000; +#endif + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + /* Set up memory and I/O filter limits, assume 32-bit I/O space */ + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1); - /* - * [jsun] we always bump up baselines a little, so that if there - * nothing behind P2P bridge, we don't wind up overlapping IO/MEM - * spaces. - */ - pciauto_lower_memspc += 1; - pciauto_lower_iospc += 1; - - /* - * Configure subordinate bus number. The PCI subsystem - * bus scan will renumber buses (reserving three additional - * for this PCI<->CardBus bridge for the case where a CardBus - * adapter contains a P2P or CB2CB bridge. - */ - - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, sub_bus); - - /* - * Reserve an additional 4MB for mem space and 16KB for - * I/O space. This should cover any additional space - * requirement of unusual CardBus devices with - * additional bridges that can consume more address space. - * - * Although pcmcia-cs currently will reprogram bridge - * windows, the goal is to add an option to leave them - * alone and use the bridge window ranges as the regions - * that are searched for free resources upon hot-insertion - * of a device. This will allow a PCI<->CardBus bridge - * configured by this routine to happily live behind a - * P2P bridge in a system. - */ - - /* Align memory and I/O to 4KB and 4 byte boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) - & ~(0x1000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) - & ~(0x4 - 1); - /* Set up memory and I/O filter limits, assume 32-bit I/O space */ - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1); - - /* Enable memory and I/O accesses, enable bus master */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &temp); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY - | PCI_COMMAND_MASTER); + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &temp); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); } -#define PCIAUTO_IDE_MODE_MASK 0x05 +#define PCIAUTO_IDE_MODE_MASK 0x05 static int __init pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) @@ -455,6 +471,9 @@ if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { DBG(" Bridge: primary=%.2x, secondary=%.2x\n", current_bus, sub_bus + 1); +#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1); +#endif pciauto_prescan_setup_bridge(hose, top_bus, current_bus, pci_devfn, sub_bus); DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", @@ -463,26 +482,26 @@ sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); DBG("Back to bus %.2x\n", current_bus); pciauto_postscan_setup_bridge(hose, top_bus, current_bus, - pci_devfn, sub_bus); + pci_devfn, sub_bus); continue; - } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { - DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n", - current_bus, sub_bus + 1); - DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); - /* Place CardBus Socket/ExCA registers */ - pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn); + } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { + DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n", + current_bus, sub_bus + 1); + DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); + /* Place CardBus Socket/ExCA registers */ + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); - pciauto_prescan_setup_cardbus_bridge(hose, top_bus, - current_bus, pci_devfn, sub_bus); + pciauto_prescan_setup_cardbus_bridge(hose, top_bus, + current_bus, pci_devfn, sub_bus); - DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", - sub_bus + 1, - pciauto_lower_iospc, pciauto_lower_memspc); - sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); - DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus); - pciauto_postscan_setup_cardbus_bridge(hose, top_bus, - current_bus, pci_devfn, sub_bus); - continue; + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", + sub_bus + 1, + pciauto_lower_iospc, pciauto_lower_memspc); + sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); + DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus); + pciauto_postscan_setup_cardbus_bridge(hose, top_bus, + current_bus, pci_devfn, sub_bus); + continue; } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { unsigned char prg_iface; @@ -495,7 +514,7 @@ } } - /* + /* * Found a peripheral, enable some standard * settings */ @@ -509,7 +528,7 @@ PCI_LATENCY_TIMER, 0x80); /* Allocate PCI I/O and/or memory space */ - pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn); + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5); } return sub_bus; } diff -Nru a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c --- a/arch/sh/drivers/pci/pci-sh7751.c 2004-06-26 17:09:20 -07:00 +++ b/arch/sh/drivers/pci/pci-sh7751.c 2004-06-26 17:09:20 -07:00 @@ -31,6 +31,7 @@ #include "pci-sh7751.h" static unsigned int pci_probe = PCI_PROBE_CONF1; +extern int pci_fixup_pcic(void); /* * Direct access to PCI hardware... @@ -74,7 +75,8 @@ } /* - * Since SH7751 only does 32bit access we'll have to do a read,mask,write operation. + * Since SH7751 only does 32bit access we'll have to do a read, + * mask,write operation. * We'll allow an odd byte offset, though it should be illegal. */ static int sh7751_pci_write(struct pci_bus *bus, unsigned int devfn, @@ -156,6 +158,7 @@ * Handle bus scanning and fixups .... */ +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) static void __init pci_fixup_ide_bases(struct pci_dev *d) { int i; @@ -174,11 +177,13 @@ } } } - +#endif /* Add future fixups here... */ struct pci_fixup pcibios_fixups[] = { +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases }, +#endif { 0 } }; @@ -261,19 +266,19 @@ outl(word, PCI_REG(SH7751_PCICLKR)); /* - * XXX: This code is unused for the SnapGear boards as it is done in - * the bootloader and doing it here means the MAC addresses loaded by - * the bootloader get lost. + * This code is unused for some boards as it is done in the + * bootloader and doing it here means the MAC addresses loaded + * by the bootloader get lost. */ -#ifndef CONFIG_SH_SECUREEDGE5410 - /* toggle PCI reset pin */ - word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST; - outl(word,PCI_REG(SH7751_PCICR)); - /* Wait for a long time... not 1 sec. but long enough */ - mdelay(100); - word = SH7751_PCICR_PREFIX; - outl(word,PCI_REG(SH7751_PCICR)); -#endif + if (!(map->flags & SH7751_PCIC_NO_RESET)) { + /* toggle PCI reset pin */ + word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST; + outl(word,PCI_REG(SH7751_PCICR)); + /* Wait for a long time... not 1 sec. but long enough */ + mdelay(100); + word = SH7751_PCICR_PREFIX; + outl(word,PCI_REG(SH7751_PCICR)); + } /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + @@ -364,6 +369,10 @@ * DMA interrupts... */ +#ifdef CONFIG_SH_RTS7751R2D + pci_fixup_pcic(); +#endif + /* SH7751 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM; diff -Nru a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h --- a/arch/sh/drivers/pci/pci-sh7751.h 2004-06-26 17:09:21 -07:00 +++ b/arch/sh/drivers/pci/pci-sh7751.h 2004-06-26 17:09:21 -07:00 @@ -234,6 +234,7 @@ #define SH7751_PCIWCR2 0x1EC /* Wait Control 2 Register */ #define SH7751_PCIWCR3 0x1F0 /* Wait Control 3 Register */ #define SH7751_PCIMCR 0x1F4 /* Memory Control Register */ +#define SH7751_PCIBCR3 0x1f8 /* Memory BCR3 Register */ #define SH7751_PCIPCTR 0x200 /* Port Control Register */ #define SH7751_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */ #define SH7751_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */ @@ -256,6 +257,8 @@ /* Memory Control Registers */ #define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */ #define SH7751_BCR2 0xFF800004 /* Memory BCR2 Register */ +#define SH7751_BCR3 0xFF800050 /* Memory BCR3 Register */ +#define SH7751_BCR4 0xFE0A00F0 /* Memory BCR4 Register */ #define SH7751_WCR1 0xFF800008 /* Wait Control 1 Register */ #define SH7751_WCR2 0xFF80000C /* Wait Control 2 Register */ #define SH7751_WCR3 0xFF800010 /* Wait Control 3 Register */ @@ -274,6 +277,9 @@ /* General PCI values */ #define SH7751_PCI_HOST_BRIDGE 0x6 +/* Flags */ +#define SH7751_PCIC_NO_RESET 0x0001 + /* External functions defined per platform i.e. Big Sur, SE... (these could be routed * through the machine vectors... */ extern int pcibios_init_platform(void); @@ -287,6 +293,7 @@ struct sh7751_pci_address_map { struct sh7751_pci_address_space window0; struct sh7751_pci_address_space window1; + unsigned long flags; }; /* arch/sh/drivers/pci/pci-sh7751.c */ diff -Nru a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c --- a/arch/sh/drivers/pci/pci.c 2004-06-26 17:09:20 -07:00 +++ b/arch/sh/drivers/pci/pci.c 2004-06-26 17:09:20 -07:00 @@ -25,7 +25,7 @@ #ifdef CONFIG_PCI_AUTO /* assign resources */ - busno=0; + busno = 0; for (p = board_pci_channels; p->pci_ops != NULL; p++) { busno = pciauto_assign_resources(busno, p) + 1; } diff -Nru a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile --- a/arch/sh/kernel/Makefile 2004-06-26 17:09:18 -07:00 +++ b/arch/sh/kernel/Makefile 2004-06-26 17:09:18 -07:00 @@ -16,6 +16,7 @@ obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o USE_STANDARD_AS_RULE := true diff -Nru a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile --- a/arch/sh/kernel/cpu/Makefile 2004-06-26 17:09:19 -07:00 +++ b/arch/sh/kernel/cpu/Makefile 2004-06-26 17:09:19 -07:00 @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH CPU-specifc backends. # -obj-y := irq_ipr.o irq_imask.o init.o +obj-y := irq_ipr.o irq_imask.o init.o bus.o obj-$(CONFIG_CPU_SH2) += sh2/ obj-$(CONFIG_CPU_SH3) += sh3/ @@ -10,6 +10,7 @@ obj-$(CONFIG_SH_RTC) += rtc.o obj-$(CONFIG_UBC_WAKEUP) += ubc.o +obj-$(CONFIG_SH_ADC) += adc.o USE_STANDARD_AS_RULE := true diff -Nru a/arch/sh/kernel/cpu/adc.c b/arch/sh/kernel/cpu/adc.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/kernel/cpu/adc.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,36 @@ +/* + * linux/arch/sh/kernel/adc.c -- SH3 on-chip ADC support + * + * Copyright (C) 2004 Andriy Skulysh + */ + +#include +#include +#include + + +int adc_single(unsigned int channel) +{ + int off; + unsigned char csr; + + if (channel >= 8) return -1; + + off = (channel & 0x03) << 2; + + csr = ctrl_inb(ADCSR); + csr = channel | ADCSR_ADST | ADCSR_CKS; + ctrl_outb(csr, ADCSR); + + do { + csr = ctrl_inb(ADCSR); + } while ((csr & ADCSR_ADF) == 0); + + csr &= ~(ADCSR_ADF | ADCSR_ADST); + ctrl_outb(csr, ADCSR); + + return (((ctrl_inb(ADDRAH + off) << 8) | + ctrl_inb(ADDRAL + off)) >> 6); +} + +EXPORT_SYMBOL(adc_single); diff -Nru a/arch/sh/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/kernel/cpu/bus.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,195 @@ +/* + * arch/sh/kernel/cpu/bus.c + * + * Virtual bus for SuperH. + * + * Copyright (C) 2004 Paul Mundt + * + * Shamelessly cloned from arch/arm/mach-omap/bus.c, which was written + * by: + * + * Copyright (C) 2003 - 2004 Nokia Corporation + * Written by Tony Lindgren + * Portions of code based on sa1111.c. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +static int sh_bus_match(struct device *dev, struct device_driver *drv) +{ + struct sh_driver *shdrv = to_sh_driver(drv); + struct sh_dev *shdev = to_sh_dev(dev); + + return shdev->dev_id == shdrv->dev_id; +} + +static int sh_bus_suspend(struct device *dev, u32 state) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->suspend) + return shdrv->suspend(shdev, state); + + return 0; +} + +static int sh_bus_resume(struct device *dev) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->resume) + return shdrv->resume(shdev); + + return 0; +} + +static struct device sh_bus_devices[SH_NR_BUSES] = { + { + .bus_id = SH_BUS_NAME_VIRT, + }, +}; + +struct bus_type sh_bus_types[SH_NR_BUSES] = { + { + .name = SH_BUS_NAME_VIRT, + .match = sh_bus_match, + .suspend = sh_bus_suspend, + .resume = sh_bus_resume, + }, +}; + +static int sh_device_probe(struct device *dev) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->probe) + return shdrv->probe(shdev); + + return -ENODEV; +} + +static int sh_device_remove(struct device *dev) +{ + struct sh_dev *shdev = to_sh_dev(dev); + struct sh_driver *shdrv = to_sh_driver(dev->driver); + + if (shdrv && shdrv->remove) + return shdrv->remove(shdev); + + return 0; +} + +int sh_device_register(struct sh_dev *dev) +{ + if (!dev) + return -EINVAL; + + if (dev->bus_id < 0 || dev->bus_id >= SH_NR_BUSES) { + printk(KERN_ERR "%s: bus_id invalid: %s bus: %d\n", + __FUNCTION__, dev->name, dev->bus_id); + return -EINVAL; + } + + dev->dev.parent = &sh_bus_devices[dev->bus_id]; + dev->dev.bus = &sh_bus_types[dev->bus_id]; + + /* This is needed for USB OHCI to work */ + if (dev->dma_mask) + dev->dev.dma_mask = dev->dma_mask; + + snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u", + dev->name, dev->dev_id); + + printk(KERN_INFO "Registering SH device '%s'. Parent at %s\n", + dev->dev.bus_id, dev->dev.parent->bus_id); + + return device_register(&dev->dev); +} + +void sh_device_unregister(struct sh_dev *dev) +{ + device_unregister(&dev->dev); +} + +int sh_driver_register(struct sh_driver *drv) +{ + if (!drv) + return -EINVAL; + + if (drv->bus_id < 0 || drv->bus_id >= SH_NR_BUSES) { + printk(KERN_ERR "%s: bus_id invalid: bus: %d device %d\n", + __FUNCTION__, drv->bus_id, drv->dev_id); + return -EINVAL; + } + + drv->drv.probe = sh_device_probe; + drv->drv.remove = sh_device_remove; + drv->drv.bus = &sh_bus_types[drv->bus_id]; + + return driver_register(&drv->drv); +} + +void sh_driver_unregister(struct sh_driver *drv) +{ + driver_unregister(&drv->drv); +} + +static int __init sh_bus_init(void) +{ + int i, ret = 0; + + for (i = 0; i < SH_NR_BUSES; i++) { + ret = device_register(&sh_bus_devices[i]); + if (ret != 0) { + printk(KERN_ERR "Unable to register bus device %s\n", + sh_bus_devices[i].bus_id); + continue; + } + + ret = bus_register(&sh_bus_types[i]); + if (ret != 0) { + printk(KERN_ERR "Unable to register bus %s\n", + sh_bus_types[i].name); + device_unregister(&sh_bus_devices[i]); + } + } + + printk(KERN_INFO "SH Virtual Bus initialized\n"); + + return ret; +} + +static void __exit sh_bus_exit(void) +{ + int i; + + for (i = 0; i < SH_NR_BUSES; i++) { + bus_unregister(&sh_bus_types[i]); + device_unregister(&sh_bus_devices[i]); + } +} + +module_init(sh_bus_init); +module_exit(sh_bus_exit); + +MODULE_AUTHOR("Paul Mundt "); +MODULE_DESCRIPTION("SH Virtual Bus"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(sh_bus_types); +EXPORT_SYMBOL(sh_device_register); +EXPORT_SYMBOL(sh_device_unregister); +EXPORT_SYMBOL(sh_driver_register); +EXPORT_SYMBOL(sh_driver_unregister); + diff -Nru a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c --- a/arch/sh/kernel/cpu/init.c 2004-06-26 17:09:21 -07:00 +++ b/arch/sh/kernel/cpu/init.c 2004-06-26 17:09:21 -07:00 @@ -42,7 +42,7 @@ */ static void __init cache_init(void) { - unsigned long ccr, flags = 0; + unsigned long ccr, flags; if (cpu_data->type == CPU_SH_NONE) panic("Unknown CPU"); @@ -54,42 +54,50 @@ * If the cache is already enabled .. flush it. */ if (ccr & CCR_CACHE_ENABLE) { - unsigned long entries, i, j; + unsigned long ways, waysize, addrstart; - entries = cpu_data->dcache.sets; + waysize = cpu_data->dcache.sets; /* * If the OC is already in RAM mode, we only have * half of the entries to flush.. */ if (ccr & CCR_CACHE_ORA) - entries >>= 1; + waysize >>= 1; - for (i = 0; i < entries; i++) { - for (j = 0; j < cpu_data->dcache.ways; j++) { - unsigned long data, addr; - - addr = CACHE_OC_ADDRESS_ARRAY | - (j << cpu_data->dcache.way_shift) | - (i << cpu_data->dcache.entry_shift); - - data = ctrl_inl(addr); - - if ((data & (SH_CACHE_UPDATED | SH_CACHE_VALID)) - == (SH_CACHE_UPDATED | SH_CACHE_VALID)) - ctrl_outl(data & ~SH_CACHE_UPDATED, addr); - } - } + waysize <<= cpu_data->dcache.entry_shift; + +#ifdef CCR_CACHE_EMODE + /* If EMODE is not set, we only have 1 way to flush. */ + if (!(ccr & CCR_CACHE_EMODE)) + ways = 1; + else +#endif + ways = cpu_data->dcache.ways; + + addrstart = CACHE_OC_ADDRESS_ARRAY; + do { + unsigned long addr; + + for (addr = addrstart; + addr < addrstart + waysize; + addr += cpu_data->dcache.linesz) + ctrl_outl(0, addr); + + addrstart += cpu_data->dcache.way_incr; + } while (--ways); } /* * Default CCR values .. enable the caches - * and flush them immediately.. + * and invalidate them immediately.. */ - flags |= CCR_CACHE_ENABLE | CCR_CACHE_INVALIDATE; - + flags = CCR_CACHE_ENABLE | CCR_CACHE_INVALIDATE; + #ifdef CCR_CACHE_EMODE - flags |= (ccr & CCR_CACHE_EMODE); + /* Force EMODE if possible */ + if (cpu_data->dcache.ways > 1) + flags |= CCR_CACHE_EMODE; #endif #ifdef CONFIG_SH_WRITETHROUGH @@ -145,8 +153,8 @@ /* If the DSP bit is still set, this CPU has a DSP */ if (sr & SR_DSP) - set_bit(CPU_HAS_DSP, &(cpu_data->flags)); - + cpu_data->flags |= CPU_HAS_DSP; + /* Now that we've determined the DSP status, clear the DSP bit. */ release_dsp(); } @@ -184,7 +192,7 @@ } /* FPU initialization */ - if (test_bit(CPU_HAS_FPU, &(cpu_data->flags))) { + if ((cpu_data->flags & CPU_HAS_FPU)) { clear_thread_flag(TIF_USEDFPU); current->used_math = 0; } diff -Nru a/arch/sh/kernel/cpu/irq_ipr.c b/arch/sh/kernel/cpu/irq_ipr.c --- a/arch/sh/kernel/cpu/irq_ipr.c 2004-06-26 17:09:16 -07:00 +++ b/arch/sh/kernel/cpu/irq_ipr.c 2004-06-26 17:09:16 -07:00 @@ -4,12 +4,13 @@ * * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2003 Takashi Kusuda * * Interrupt handling for IPR-based IRQ. * * Supported system: * On-chip supporting modules (TMU, RTC, etc.). - * On-chip supporting modules for SH7709/SH7709A/SH7729. + * On-chip supporting modules for SH7709/SH7709A/SH7729/SH7300. * Hitachi SolutionEngine external I/O: * MS7709SE01, MS7709ASE01, and MS7750SE01 * @@ -88,7 +89,8 @@ { disable_ipr_irq(irq); -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is needed when we use edge triggered setting */ /* XXX: Is it really needed? */ if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { @@ -117,7 +119,9 @@ disable_ipr_irq(irq); } -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) static unsigned char pint_map[256]; static unsigned long portcr_mask = 0; @@ -131,7 +135,7 @@ static void end_pint_irq(unsigned int irq); static unsigned int startup_pint_irq(unsigned int irq) -{ +{ enable_pint_irq(irq); return 0; /* never anything pending */ } @@ -191,13 +195,17 @@ void __init init_IRQ(void) { -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) int i; #endif make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); +#if defined(CONFIG_SH_RTC) make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); +#endif #ifdef SCI_ERI_IRQ make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); @@ -212,6 +220,13 @@ make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); +#endif + #ifdef SCIF_ERI_IRQ make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); @@ -226,11 +241,12 @@ make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* * Initialize the Interrupt Controller (INTC) * registers to their power on values - */ + */ /* * Enable external irq (INTC IRQ mode). @@ -243,6 +259,7 @@ make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY); make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY); make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); enable_ipr_irq(PINT0_IRQ); @@ -261,16 +278,19 @@ else if(i & 0x40) pint_map[i] = 6; else if(i & 0x80) pint_map[i] = 7; } -#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */ +#endif /* !CONFIG_CPU_SUBTYPE_SH7300 */ +#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 || CONFIG_CPU_SUBTYPE_SH7300*/ /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq != NULL) { sh_mv.mv_init_irq(); } } -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) int ipr_irq_demux(int irq) { +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) unsigned long creg, dreg, d, sav; if(irq == PINT0_IRQ) @@ -305,6 +325,7 @@ if(d == 0) return irq; return PINT_IRQ_BASE + 8 + pint_map[d]; } +#endif return irq; } #endif diff -Nru a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S --- a/arch/sh/kernel/cpu/sh3/ex.S 2004-06-26 17:09:19 -07:00 +++ b/arch/sh/kernel/cpu/sh3/ex.S 2004-06-26 17:09:19 -07:00 @@ -85,7 +85,8 @@ .long do_IRQ ! rovi .long do_IRQ .long do_IRQ /* 5E0 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) .long do_IRQ ! 32 IRQ irq0 /* 600 */ .long do_IRQ ! 33 irq1 .long do_IRQ ! 34 irq2 @@ -115,10 +116,84 @@ .long do_IRQ ! 58 bri2 .long do_IRQ ! 59 txi2 .long do_IRQ ! 60 ADC adi /* 980 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) + .long exception_none ! 61 /* 9A0 */ + .long exception_none ! 62 + .long exception_none ! 63 + .long exception_none ! 64 /* A00 */ + .long do_IRQ ! 65 USB usi0 + .long do_IRQ ! 66 usi1 + .long exception_none ! 67 + .long exception_none ! 68 + .long exception_none ! 69 + .long exception_none ! 70 + .long exception_none ! 71 + .long exception_none ! 72 /* B00 */ + .long exception_none ! 73 + .long exception_none ! 74 + .long exception_none ! 75 + .long exception_none ! 76 + .long exception_none ! 77 + .long exception_none ! 78 + .long exception_none ! 79 + .long do_IRQ ! 80 TPU0 tpi0 /* C00 */ + .long do_IRQ ! 81 TPU1 tpi1 + .long exception_none ! 82 + .long exception_none ! 83 + .long do_IRQ ! 84 TPU2 tpi2 + .long do_IRQ ! 85 TPU3 tpi3 /* CA0 */ +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300) .long do_IRQ ! 61 LCDC lcdi /* 9A0 */ .long do_IRQ ! 62 PCC pcc0i .long do_IRQ ! 63 pcc1i /* 9E0 */ +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + .long do_IRQ ! 64 + .long do_IRQ ! 65 + .long do_IRQ ! 66 + .long do_IRQ ! 67 + .long do_IRQ ! 68 + .long do_IRQ ! 69 + .long do_IRQ ! 70 + .long do_IRQ ! 71 + .long do_IRQ ! 72 + .long do_IRQ ! 73 + .long do_IRQ ! 74 + .long do_IRQ ! 75 + .long do_IRQ ! 76 + .long do_IRQ ! 77 + .long do_IRQ ! 78 + .long do_IRQ ! 79 + .long do_IRQ ! 80 SCIF0(SH7300) + .long do_IRQ ! 81 + .long do_IRQ ! 82 + .long do_IRQ ! 83 + .long do_IRQ ! 84 + .long do_IRQ ! 85 + .long do_IRQ ! 86 + .long do_IRQ ! 87 + .long do_IRQ ! 88 + .long do_IRQ ! 89 + .long do_IRQ ! 90 + .long do_IRQ ! 91 + .long do_IRQ ! 92 + .long do_IRQ ! 93 + .long do_IRQ ! 94 + .long do_IRQ ! 95 + .long do_IRQ ! 96 + .long do_IRQ ! 97 + .long do_IRQ ! 98 + .long do_IRQ ! 99 + .long do_IRQ ! 100 + .long do_IRQ ! 101 + .long do_IRQ ! 102 + .long do_IRQ ! 103 + .long do_IRQ ! 104 + .long do_IRQ ! 105 + .long do_IRQ ! 106 + .long do_IRQ ! 107 + .long do_IRQ ! 108 #endif #endif diff -Nru a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/kernel/early_printk.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,135 @@ +/* + * arch/sh/kernel/early_printk.c + * + * Copyright (C) 1999, 2000 Niibe Yutaka + * Copyright (C) 2002 M. R. Brown + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +#ifdef CONFIG_SH_STANDARD_BIOS +#include + +/* + * Print a string through the BIOS + */ +static void sh_console_write(struct console *co, const char *s, + unsigned count) +{ + sh_bios_console_write(s, count); +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +static int __init sh_console_setup(struct console *co, char *options) +{ + int cflag = CREAD | HUPCL | CLOCAL; + + /* + * Now construct a cflag setting. + * TODO: this is a totally bogus cflag, as we have + * no idea what serial settings the BIOS is using, or + * even if its using the serial port at all. + */ + cflag |= B115200 | CS8 | /*no parity*/0; + + co->cflag = cflag; + + return 0; +} + +static struct console early_console = { + .name = "bios", + .write = sh_console_write, + .setup = sh_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; +#endif + +#ifdef CONFIG_EARLY_SCIF_CONSOLE +#define SCIF_REG 0xffe80000 + +static void scif_sercon_putc(int c) +{ + while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ; + + ctrl_outb(c, SCIF_REG + 12); + ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10); + + if (c == '\n') + scif_sercon_putc('\r'); +} + +static void scif_sercon_flush(void) +{ + ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); + + while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ; + + ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); +} + +static void scif_sercon_write(struct console *con, const char *s, unsigned count) +{ + while (count-- > 0) + scif_sercon_putc(*s++); + + scif_sercon_flush(); +} + +static int __init scif_sercon_setup(struct console *con, char *options) +{ + con->cflag = CREAD | HUPCL | CLOCAL | B115200 | CS8; + + return 0; +} + +static struct console early_console = { + .name = "sercon", + .write = scif_sercon_write, + .setup = scif_sercon_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +void scif_sercon_init(int baud) +{ + ctrl_outw(0, SCIF_REG + 8); + ctrl_outw(0, SCIF_REG); + + /* Set baud rate */ + ctrl_outb((50000000 / (32 * baud)) - 1, SCIF_REG + 4); + + ctrl_outw(12, SCIF_REG + 24); + ctrl_outw(8, SCIF_REG + 24); + ctrl_outw(0, SCIF_REG + 32); + ctrl_outw(0x60, SCIF_REG + 16); + ctrl_outw(0, SCIF_REG + 36); + ctrl_outw(0x30, SCIF_REG + 8); +} +#endif + +void __init enable_early_printk(void) +{ +#ifdef CONFIG_EARLY_SCIF_CONSOLE + scif_sercon_init(115200); +#endif + register_console(&early_console); +} + +void disable_early_printk(void) +{ + unregister_console(&early_console); +} + diff -Nru a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S --- a/arch/sh/kernel/entry.S 2004-06-26 17:09:17 -07:00 +++ b/arch/sh/kernel/entry.S 2004-06-26 17:09:17 -07:00 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.35 2004/02/21 14:45:47 lethal Exp $ +/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ * * linux/arch/sh/entry.S * @@ -77,7 +77,8 @@ #if defined(CONFIG_CPU_SH3) TRA = 0xffffffd0 EXPEVT = 0xffffffd4 -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000) #else INTEVT = 0xffffffd8 @@ -1129,6 +1130,14 @@ .long sys_utimes .long sys_fadvise64_64_wrapper .long sys_ni_syscall /* Reserved for vserver */ - .long sys_ni_syscall + .long sys_ni_syscall /* Reserved for mbind */ + .long sys_ni_syscall /* 275 - get_mempolicy */ + .long sys_ni_syscall /* set_mempolicy */ + .long sys_mq_open + .long sys_mq_unlink + .long sys_mq_timedsend + .long sys_mq_timedreceive /* 280 */ + .long sys_mq_notify + .long sys_mq_getsetattr /* End of entry.S */ diff -Nru a/arch/sh/kernel/init_task.c b/arch/sh/kernel/init_task.c --- a/arch/sh/kernel/init_task.c 2004-06-26 17:09:16 -07:00 +++ b/arch/sh/kernel/init_task.c 2004-06-26 17:09:16 -07:00 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c --- a/arch/sh/kernel/io_generic.c 2004-06-26 17:09:17 -07:00 +++ b/arch/sh/kernel/io_generic.c 2004-06-26 17:09:17 -07:00 @@ -1,4 +1,4 @@ -/* $Id: io_generic.c,v 1.1.1.1.4.2.2.1 2003/01/10 17:26:56 lethal Exp $ +/* $Id: io_generic.c,v 1.2 2003/05/04 19:29:53 lethal Exp $ * * linux/arch/sh/kernel/io_generic.c * @@ -71,16 +71,32 @@ return v; } +/* + * insb/w/l all read a series of bytes/words/longs from a fixed port + * address. However as the port address doesn't change we only need to + * convert the port address to real address once. + */ + void generic_insb(unsigned long port, void *buffer, unsigned long count) { + volatile unsigned char *port_addr; unsigned char *buf=buffer; - while(count--) *buf++=inb(port); + + port_addr = (volatile unsigned char *)PORT2ADDR(port); + + while(count--) + *buf++ = *port_addr; } void generic_insw(unsigned long port, void *buffer, unsigned long count) { + volatile unsigned short *port_addr; unsigned short *buf=buffer; - while(count--) *buf++=inw(port); + + port_addr = (volatile unsigned short *)PORT2ADDR(port); + + while(count--) + *buf++ = *port_addr; #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif @@ -88,8 +104,13 @@ void generic_insl(unsigned long port, void *buffer, unsigned long count) { + volatile unsigned long *port_addr; unsigned long *buf=buffer; - while(count--) *buf++=inl(port); + + port_addr = (volatile unsigned long *)PORT2ADDR(port); + + while(count--) + *buf++ = *port_addr; #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif @@ -128,16 +149,33 @@ delay(); } +/* + * outsb/w/l all write a series of bytes/words/longs to a fixed port + * address. However as the port address doesn't change we only need to + * convert the port address to real address once. + */ + void generic_outsb(unsigned long port, const void *buffer, unsigned long count) { + volatile unsigned char *port_addr; const unsigned char *buf=buffer; - while(count--) outb(*buf++, port); + + port_addr = (volatile unsigned char *)PORT2ADDR(port); + + while(count--) + *port_addr = *buf++; } void generic_outsw(unsigned long port, const void *buffer, unsigned long count) { + volatile unsigned short *port_addr; const unsigned short *buf=buffer; - while(count--) outw(*buf++, port); + + port_addr = (volatile unsigned short *)PORT2ADDR(port); + + while(count--) + *port_addr = *buf++; + #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif @@ -145,8 +183,14 @@ void generic_outsl(unsigned long port, const void *buffer, unsigned long count) { + volatile unsigned long *port_addr; const unsigned long *buf=buffer; - while(count--) outl(*buf++, port); + + port_addr = (volatile unsigned long *)PORT2ADDR(port); + + while(count--) + *port_addr = *buf++; + #ifdef SH3_PCMCIA_BUG_WORKAROUND ctrl_inb (DUMMY_READ_AREA6); #endif diff -Nru a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c --- a/arch/sh/kernel/irq.c 2004-06-26 17:09:17 -07:00 +++ b/arch/sh/kernel/irq.c 2004-06-26 17:09:17 -07:00 @@ -436,7 +436,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; @@ -574,6 +574,49 @@ } EXPORT_SYMBOL(probe_irq_on); + +/* Return a mask of triggered interrupts (this + * can handle only legacy ISA interrupts). + */ + +/* + * probe_irq_mask - scan a bitmap of interrupt lines + * @val: mask of interrupts to consider + * + * Scan the ISA bus interrupt lines and return a bitmap of + * active interrupts. The interrupt probe logic state is then + * returned to its previous value. + * + * Note: we need to scan all the irq's even though we will + * only return ISA irq numbers - just so that we reset them + * all to a known state. + */ +unsigned int probe_irq_mask(unsigned long val) +{ + int i; + unsigned int mask; + + mask = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc_t *desc = irq_desc + i; + unsigned int status; + + spin_lock_irq(&desc->lock); + status = desc->status; + + if (status & IRQ_AUTODETECT) { + if (i < 16 && !(status & IRQ_WAITING)) + mask |= 1 << i; + + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } + spin_unlock_irq(&desc->lock); + } + up(&probe_sem); + + return mask & val; +} int probe_irq_off(unsigned long val) { diff -Nru a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c --- a/arch/sh/kernel/process.c 2004-06-26 17:09:19 -07:00 +++ b/arch/sh/kernel/process.c 2004-06-26 17:09:19 -07:00 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.26 2004/02/06 14:14:14 kkojima Exp $ +/* $Id: process.c,v 1.28 2004/05/05 16:54:23 lethal Exp $ * * linux/arch/sh/kernel/process.c * @@ -25,6 +25,11 @@ #include #include #include +#if defined(CONFIG_SH_HS7751RVOIP) +#include +#elif defined(CONFIG_SH_RTS7751R2D) +#include +#endif static int hlt_counter=0; @@ -50,8 +55,14 @@ { /* endless idle loop with no priority at all */ while (1) { - while (!need_resched()) - cpu_relax(); + if (hlt_counter) { + while (1) + if (need_resched()) + break; + } else { + while (!need_resched()) + cpu_sleep(); + } schedule(); } @@ -73,14 +84,30 @@ void machine_halt(void) { +#if defined(CONFIG_SH_HS7751RVOIP) + unsigned short value; + + value = ctrl_inw(PA_OUTPORTR); + ctrl_outw((value & 0xffdf), PA_OUTPORTR); +#elif defined(CONFIG_SH_RTS7751R2D) + ctrl_outw(0x0001, PA_POWOFF); +#endif while (1) - cpu_relax(); + cpu_sleep(); } EXPORT_SYMBOL(machine_halt); void machine_power_off(void) { +#if defined(CONFIG_SH_HS7751RVOIP) + unsigned short value; + + value = ctrl_inw(PA_OUTPORTR); + ctrl_outw((value & 0xffdf), PA_OUTPORTR); +#elif defined(CONFIG_SH_RTS7751R2D) + ctrl_outw(0x0001, PA_POWOFF); +#endif } EXPORT_SYMBOL(machine_power_off); diff -Nru a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c --- a/arch/sh/kernel/ptrace.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sh/kernel/ptrace.c 2004-06-26 17:09:15 -07:00 @@ -1,4 +1,4 @@ -/* $Id: ptrace.c,v 1.14 2003/11/28 23:05:43 kkojima Exp $ +/* $Id: ptrace.c,v 1.15 2004/05/07 05:32:05 sugioka Exp $ * * linux/arch/sh/kernel/ptrace.c * @@ -255,13 +255,6 @@ ret = ptrace_detach(child, data); break; - case PTRACE_SETOPTIONS: - if (data & PTRACE_O_TRACESYSGOOD) - child->ptrace |= PT_TRACESYSGOOD; - else - child->ptrace &= ~PT_TRACESYSGOOD; - ret = 0; - break; #ifdef CONFIG_SH_DSP case PTRACE_GETDSPREGS: { unsigned long dp; diff -Nru a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c --- a/arch/sh/kernel/setup.c 2004-06-26 17:09:19 -07:00 +++ b/arch/sh/kernel/setup.c 2004-06-26 17:09:19 -07:00 @@ -25,15 +25,12 @@ #include #include #include -#ifdef CONFIG_SH_EARLY_PRINTK -#include -#endif #ifdef CONFIG_SH_KGDB #include static int kgdb_parse_options(char *options); #endif - +extern void * __rd_start, * __rd_end; /* * Machine setup.. */ @@ -85,14 +82,12 @@ #define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) /* ... */ #define COMMAND_LINE ((char *) (PARAM+0x100)) -#define COMMAND_LINE_SIZE 256 #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f }, @@ -120,130 +115,6 @@ unsigned long memory_start, memory_end; -/* XXX: MRB-remove - blatant hack */ -#if 1 -#define SCIF_REG 0xffe80000 - -static void scif_sercon_putc(int c) -{ - while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ; - - ctrl_outb(c, SCIF_REG + 12); - ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10); - - if (c == '\n') - scif_sercon_putc('\r'); -} - -static void scif_sercon_flush(void) -{ - ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); - - while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ; - - ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); -} - -static void scif_sercon_write(struct console *con, const char *s, unsigned count) -{ - while (count-- > 0) - scif_sercon_putc(*s++); - - scif_sercon_flush(); -} - -static int __init scif_sercon_setup(struct console *con, char *options) -{ - con->cflag = CREAD | HUPCL | CLOCAL | B57600 | CS8; - - return 0; -} - -static struct console scif_sercon = { - .name = "sercon", - .write = scif_sercon_write, - .setup = scif_sercon_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -void scif_sercon_init(int baud) -{ - ctrl_outw(0, SCIF_REG + 8); - ctrl_outw(0, SCIF_REG); - - /* Set baud rate */ - ctrl_outb((50000000 / (32 * baud)) - 1, SCIF_REG + 4); - - ctrl_outw(12, SCIF_REG + 24); - ctrl_outw(8, SCIF_REG + 24); - ctrl_outw(0, SCIF_REG + 32); - ctrl_outw(0x60, SCIF_REG + 16); - ctrl_outw(0, SCIF_REG + 36); - ctrl_outw(0x30, SCIF_REG + 8); - - register_console(&scif_sercon); -} - -void scif_sercon_unregister(void) -{ - unregister_console(&scif_sercon); -} -#endif - -#ifdef CONFIG_SH_EARLY_PRINTK -/* - * Print a string through the BIOS - */ -static void sh_console_write(struct console *co, const char *s, - unsigned count) -{ - sh_bios_console_write(s, count); -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init sh_console_setup(struct console *co, char *options) -{ - int cflag = CREAD | HUPCL | CLOCAL; - - /* - * Now construct a cflag setting. - * TODO: this is a totally bogus cflag, as we have - * no idea what serial settings the BIOS is using, or - * even if its using the serial port at all. - */ - cflag |= B115200 | CS8 | /*no parity*/0; - - co->cflag = cflag; - - return 0; -} - -static struct console sh_console = { - .name = "bios", - .write = sh_console_write, - .setup = sh_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -void sh_console_init(void) -{ - register_console(&sh_console); -} - -void sh_console_unregister(void) -{ - unregister_console(&sh_console); -} - -#endif - static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], struct sh_machine_vector** mvp, unsigned long *mv_io_base, @@ -325,10 +196,6 @@ parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable); -#ifdef CONFIG_CMDLINE_BOOL - sprintf(*cmdline_p, CONFIG_CMDLINE); -#endif - #ifdef CONFIG_SH_GENERIC if (mv == NULL) { mv = &mv_unknown; @@ -382,14 +249,15 @@ unsigned long bootmap_size; unsigned long start_pfn, max_pfn, max_low_pfn; -/* XXX: MRB-remove */ -#if 0 - scif_sercon_init(57600); +#ifdef CONFIG_EARLY_PRINTK + extern void enable_early_printk(void); + + enable_early_printk(); #endif -#ifdef CONFIG_SH_EARLY_PRINTK - sh_console_init(); +#ifdef CONFIG_CMDLINE_BOOL + strcpy(COMMAND_LINE, CONFIG_CMDLINE); #endif - + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); #ifdef CONFIG_BLK_DEV_RAM @@ -492,6 +360,13 @@ reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); #ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + if (&__rd_start != &__rd_end) { + LOADER_TYPE = 1; + INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START; + INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start; + } + if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE); @@ -557,8 +432,10 @@ static const char *cpu_name[] = { [CPU_SH7604] = "SH7604", + [CPU_SH7705] = "SH7705", [CPU_SH7708] = "SH7708", [CPU_SH7729] = "SH7729", + [CPU_SH7300] = "SH7300", [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", @@ -595,8 +472,8 @@ for (i = 0; i < cpu_data->flags; i++) if ((cpu_data->flags & (1 << i))) - seq_printf(m, " %s", cpu_flags[i]); - + seq_printf(m, " %s", cpu_flags[i+1]); + seq_printf(m, "\n"); } diff -Nru a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c --- a/arch/sh/kernel/sh_ksyms.c 2004-06-26 17:09:16 -07:00 +++ b/arch/sh/kernel/sh_ksyms.c 2004-06-26 17:09:16 -07:00 @@ -33,6 +33,7 @@ EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(irq_desc); @@ -83,6 +84,7 @@ EXPORT_SYMBOL(__down_interruptible); EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__ndelay); EXPORT_SYMBOL(__const_udelay); #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name) @@ -100,6 +102,7 @@ DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); +DECLARE_EXPORT(__movstrSI12_i4); /* needed by some modules */ EXPORT_SYMBOL(flush_cache_all); @@ -115,3 +118,4 @@ #endif EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(consistent_sync); diff -Nru a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c --- a/arch/sh/kernel/time.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sh/kernel/time.c 2004-06-26 17:09:15 -07:00 @@ -1,10 +1,10 @@ -/* $Id: time.c,v 1.19 2004/02/27 00:40:48 lethal Exp $ +/* $Id: time.c,v 1.21 2004/04/21 00:09:15 lethal Exp $ * * linux/arch/sh/kernel/time.c * * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2002, 2003, 2004 Paul Mundt * Copyright (C) 2002 M. R. Brown * * Some code taken from i386 version. @@ -47,12 +47,26 @@ #define TMU0_TCR_CALIB 0x0000 #if defined(CONFIG_CPU_SH3) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define TMU_TSTR 0xA412FE92 /* Byte access */ + +#define TMU0_TCOR 0xA412FE94 /* Long access */ +#define TMU0_TCNT 0xA412FE98 /* Long access */ +#define TMU0_TCR 0xA412FE9C /* Word access */ + +#define TMU1_TCOR 0xA412FEA0 /* Long access */ +#define TMU1_TCNT 0xA412FEA4 /* Long access */ +#define TMU1_TCR 0xA412FEA8 /* Word access */ + +#define FRQCR 0xA415FF80 +#else #define TMU_TOCR 0xfffffe90 /* Byte access */ #define TMU_TSTR 0xfffffe92 /* Byte access */ #define TMU0_TCOR 0xfffffe94 /* Long access */ #define TMU0_TCNT 0xfffffe98 /* Long access */ #define TMU0_TCR 0xfffffe9c /* Word access */ +#endif #elif defined(CONFIG_CPU_SH4) #define TMU_TOCR 0xffd80000 /* Byte access */ #define TMU_TSTR 0xffd80004 /* Byte access */ @@ -85,6 +99,9 @@ int (*rtc_set_time)(const time_t) = 0; #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; +#endif #if defined(CONFIG_CPU_SH3) static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; static int stc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; @@ -337,7 +354,9 @@ * have it count down at its natural rate. */ ctrl_outb(0, TMU_TSTR); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); +#endif ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); ctrl_outl(0xffffffff, TMU0_TCOR); ctrl_outl(0xffffffff, TMU0_TCNT); @@ -391,13 +410,22 @@ } __setup("sh_pclk=", sh_pclk_setup); -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsigned int *pfc) { unsigned int frqcr = ctrl_inw(FRQCR); #if defined(CONFIG_CPU_SH3) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + *ifc = md_table[((frqcr & 0x0070) >> 4)]; + *bfc = md_table[((frqcr & 0x0700) >> 8)]; + *pfc = md_table[frqcr & 0x0007]; +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) + *bfc = stc_multipliers[(frqcr & 0x0300) >> 8]; + *ifc = ifc_divisors[(frqcr & 0x0030) >> 4]; + *pfc = pfc_divisors[frqcr & 0x0003]; +#else unsigned int tmp; tmp = (frqcr & 0x8000) >> 13; @@ -409,6 +437,7 @@ tmp = (frqcr & 0x2000) >> 11; tmp |= frqcr & 0x0003; *pfc = pfc_divisors[tmp]; +#endif #elif defined(CONFIG_CPU_SH4) *ifc = ifc_divisors[(frqcr >> 6) & 0x0007]; *bfc = bfc_divisors[(frqcr >> 3) & 0x0007]; @@ -431,26 +460,139 @@ _FREQ_TABLE(bfc); _FREQ_TABLE(pfc); +#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 + +/* The ST40 divisors are totally different so we set the cpu data +** clocks using a different algorithm +** +** I've just plugged this from the 2.4 code - Alex Bennee +*/ +#define CCN_PVR_CHIP_SHIFT 24 +#define CCN_PVR_CHIP_MASK 0xff +#define CCN_PVR_CHIP_ST40STB1 0x4 + + +struct frqcr_data { + unsigned short frqcr; + struct { + unsigned char multiplier; + unsigned char divisor; + } factor[3]; +}; + +static struct frqcr_data st40_frqcr_table[] = { + { 0x000, {{1,1}, {1,1}, {1,2}}}, + { 0x002, {{1,1}, {1,1}, {1,4}}}, + { 0x004, {{1,1}, {1,1}, {1,8}}}, + { 0x008, {{1,1}, {1,2}, {1,2}}}, + { 0x00A, {{1,1}, {1,2}, {1,4}}}, + { 0x00C, {{1,1}, {1,2}, {1,8}}}, + { 0x011, {{1,1}, {2,3}, {1,6}}}, + { 0x013, {{1,1}, {2,3}, {1,3}}}, + { 0x01A, {{1,1}, {1,2}, {1,4}}}, + { 0x01C, {{1,1}, {1,2}, {1,8}}}, + { 0x023, {{1,1}, {2,3}, {1,3}}}, + { 0x02C, {{1,1}, {1,2}, {1,8}}}, + { 0x048, {{1,2}, {1,2}, {1,4}}}, + { 0x04A, {{1,2}, {1,2}, {1,6}}}, + { 0x04C, {{1,2}, {1,2}, {1,8}}}, + { 0x05A, {{1,2}, {1,3}, {1,6}}}, + { 0x05C, {{1,2}, {1,3}, {1,6}}}, + { 0x063, {{1,2}, {1,4}, {1,4}}}, + { 0x06C, {{1,2}, {1,4}, {1,8}}}, + { 0x091, {{1,3}, {1,3}, {1,6}}}, + { 0x093, {{1,3}, {1,3}, {1,6}}}, + { 0x0A3, {{1,3}, {1,6}, {1,6}}}, + { 0x0DA, {{1,4}, {1,4}, {1,8}}}, + { 0x0DC, {{1,4}, {1,4}, {1,8}}}, + { 0x0EC, {{1,4}, {1,8}, {1,8}}}, + { 0x123, {{1,4}, {1,4}, {1,8}}}, + { 0x16C, {{1,4}, {1,8}, {1,8}}}, +}; + +struct memclk_data { + unsigned char multiplier; + unsigned char divisor; +}; +static struct memclk_data st40_memclk_table[8] = { + {1,1}, // 000 + {1,2}, // 001 + {1,3}, // 010 + {2,3}, // 011 + {1,4}, // 100 + {1,6}, // 101 + {1,8}, // 110 + {1,8} // 111 +}; + +static void st40_specific_time_init(unsigned int module_clock, unsigned short frqcr) +{ + unsigned int cpu_clock, master_clock, bus_clock, memory_clock; + struct frqcr_data *d; + int a; + unsigned long memclkcr; + struct memclk_data *e; + + for (a=0; afrqcr == (frqcr & 0x1ff)) + break; + } + if (a == ARRAY_SIZE(st40_frqcr_table)) { + d = st40_frqcr_table; + printk("ERROR: Unrecognised FRQCR value (0x%x), using default multipliers\n",frqcr); + } + + memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR); + e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK]; + + printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n", + d->factor[0].multiplier, d->factor[0].divisor, + d->factor[1].multiplier, d->factor[1].divisor, + e->multiplier, e->divisor, + d->factor[2].multiplier, d->factor[2].divisor); + + master_clock = module_clock * d->factor[2].divisor / d->factor[2].multiplier; + bus_clock = master_clock * d->factor[1].multiplier / d->factor[1].divisor; + memory_clock = master_clock * e->multiplier / e->divisor; + cpu_clock = master_clock * d->factor[0].multiplier / d->factor[0].divisor; + + current_cpu_data.cpu_clock = cpu_clock; + current_cpu_data.master_clock = master_clock; + current_cpu_data.bus_clock = bus_clock; + current_cpu_data.memory_clock = memory_clock; + current_cpu_data.module_clock = module_clock; + +} + +#endif + void __init time_init(void) { unsigned int timer_freq = 0; unsigned int ifc, pfc, bfc; unsigned long interval; +#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 + unsigned long pvr; + unsigned short frqcr; +#endif if (board_time_init) board_time_init(); - get_current_frequency_divisors(&ifc, &bfc, &pfc); /* * If we don't have an RTC (such as with the SH7300), don't attempt to * probe the timer frequency. Rely on an either hardcoded peripheral - * clock value, or on the sh_pclk command line option. + * clock value, or on the sh_pclk command line option. Note that we + * still need to have CONFIG_SH_PCLK_FREQ set in order for things like + * CLOCK_TICK_RATE to be sane. */ current_cpu_data.module_clock = sh_pclk_freq; +#ifdef CONFIG_SH_PCLK_CALC /* XXX: Switch this over to a more generic test. */ - if (current_cpu_data.type != CPU_SH7300) { + { unsigned int freq; /* @@ -466,15 +608,31 @@ timer_freq = get_timer_frequency(); freq = timer_freq * 4; - if (sh_pclk_freq && sh_pclk_freq != freq) { + if (sh_pclk_freq && (sh_pclk_freq/100*99 > freq || sh_pclk_freq/100*101 < freq)) { printk(KERN_NOTICE "Calculated peripheral clock value " "%d differs from sh_pclk value %d, fixing..\n", freq, sh_pclk_freq); current_cpu_data.module_clock = freq; } } +#endif - rtc_get_time(&xtime); +#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 + pvr = ctrl_inl(CCN_PVR); + frqcr = ctrl_inw(FRQCR); + printk("time.c ST40 Probe: PVR %08lx, FRQCR %04hx\n", pvr, frqcr); + if (((pvr >>CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) + st40_specific_time_init(current_cpu_data.module_clock, frqcr); + else +#endif + get_current_frequency_divisors(&ifc, &bfc, &pfc); + + if (rtc_get_time) + rtc_get_time(&xtime); + else { + xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0); + xtime.tv_nsec = 0; + } set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); @@ -485,6 +643,10 @@ setup_irq(TIMER_IRQ, &irq0); } + /* + ** for ST40 chips the current_cpu_data should already be set + ** so not having valid pfc/bfc/ifc shouldn't be a problem + */ if (!current_cpu_data.master_clock) current_cpu_data.master_clock = current_cpu_data.module_clock * pfc; if (!current_cpu_data.bus_clock) @@ -506,13 +668,19 @@ printk("Module clock: %d.%02dMHz\n", (current_cpu_data.module_clock / 1000000), (current_cpu_data.module_clock % 1000000)/10000); +#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) + interval = ((current_cpu_data.module_clock/4 + HZ/2) / HZ) - 1; +#else interval = (current_cpu_data.module_clock/4 + HZ/2) / HZ; +#endif printk("Interval = %ld\n", interval); /* Start TMU0 */ ctrl_outb(0, TMU_TSTR); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); +#endif ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); ctrl_outl(interval, TMU0_TCOR); ctrl_outl(interval, TMU0_TCNT); diff -Nru a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c --- a/arch/sh/kernel/traps.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sh/kernel/traps.c 2004-06-26 17:09:15 -07:00 @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.16 2004/03/16 00:10:54 lethal Exp $ +/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $ * * linux/arch/sh/traps.c * @@ -559,7 +559,7 @@ * Safe guard if DSP mode is already enabled or we're lacking * the DSP altogether. */ - if (!test_bit(CPU_HAS_DSP, &(cpu_data->flags)) || (regs->sr & SR_DSP)) + if (!(cpu_data->flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) return 0; get_user(inst, ((unsigned short *) regs->pc)); @@ -636,7 +636,7 @@ = (void *)do_illegal_slot_inst; #ifdef CONFIG_CPU_SH4 - if (!test_bit(CPU_HAS_FPU, &(cpu_data->flags))) { + if (!(cpu_data->flags & CPU_HAS_FPU)) { /* For SH-4 lacking an FPU, treat floating point instructions as reserved. */ /* entry 64 corresponds to EXPEVT=0x800 */ diff -Nru a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S --- a/arch/sh/kernel/vmlinux.lds.S 2004-06-26 17:09:18 -07:00 +++ b/arch/sh/kernel/vmlinux.lds.S 2004-06-26 17:09:18 -07:00 @@ -38,6 +38,14 @@ .data : { /* Data */ *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } diff -Nru a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c --- a/arch/sh/lib/delay.c 2004-06-26 17:09:18 -07:00 +++ b/arch/sh/lib/delay.c 2004-06-26 17:09:18 -07:00 @@ -33,3 +33,9 @@ { __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 0x00000005); +} + diff -Nru a/arch/sh/mm/cache-sh3.c b/arch/sh/mm/cache-sh3.c --- a/arch/sh/mm/cache-sh3.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sh/mm/cache-sh3.c 2004-06-26 17:09:15 -07:00 @@ -1,4 +1,4 @@ -/* $Id: cache-sh3.c,v 1.8 2004/02/01 16:26:27 lethal Exp $ +/* $Id: cache-sh3.c,v 1.9 2004/05/02 01:46:30 sugioka Exp $ * * linux/arch/sh/mm/cache-sh3.c * @@ -65,14 +65,14 @@ * 2K(direct) 7702 is not supported (yet) */ if (data0 == data1 && data2 == data3) { /* Shadow */ - cpu_data->dcache.way_shift = 11; + cpu_data->dcache.way_incr = (1 << 11); cpu_data->dcache.entry_mask = 0x7f0; cpu_data->dcache.sets = 128; cpu_data->type = CPU_SH7708; - set_bit(CPU_HAS_MMU_PAGE_ASSOC, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC; } else { /* 7709A or 7729 */ - cpu_data->dcache.way_shift = 12; + cpu_data->dcache.way_incr = (1 << 12); cpu_data->dcache.entry_mask = 0xff0; cpu_data->dcache.sets = 256; cpu_data->type = CPU_SH7729; @@ -108,13 +108,12 @@ & ~(L1_CACHE_BYTES-1); for (v = begin; v < end; v+=L1_CACHE_BYTES) { + unsigned long addrstart = CACHE_OC_ADDRESS_ARRAY; for (j = 0; j < cpu_data->dcache.ways; j++) { unsigned long data, addr, p; p = __pa(v); - addr = CACHE_OC_ADDRESS_ARRAY | - (j << cpu_data->dcache.way_shift)| - (v & cpu_data->dcache.entry_mask); + addr = addrstart | (v & cpu_data->dcache.entry_mask); local_irq_save(flags); data = ctrl_inl(addr); @@ -126,6 +125,7 @@ break; } local_irq_restore(flags); + addrstart += cpu_data->dcache.way_incr; } } } diff -Nru a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c --- a/arch/sh/mm/cache-sh4.c 2004-06-26 17:09:16 -07:00 +++ b/arch/sh/mm/cache-sh4.c 2004-06-26 17:09:16 -07:00 @@ -30,7 +30,7 @@ int __init detect_cpu_and_cache_system(void) { - unsigned long pvr, prr, ccr, cvr; + unsigned long pvr, prr, cvr; unsigned long size; static unsigned long sizes[16] = { @@ -48,7 +48,7 @@ /* * Setup some sane SH-4 defaults for the icache */ - cpu_data->icache.way_shift = 13; + cpu_data->icache.way_incr = (1 << 13); cpu_data->icache.entry_shift = 5; cpu_data->icache.entry_mask = 0x1fe0; cpu_data->icache.sets = 256; @@ -58,7 +58,7 @@ /* * And again for the dcache .. */ - cpu_data->dcache.way_shift = 14; + cpu_data->dcache.way_incr = (1 << 14); cpu_data->dcache.entry_shift = 5; cpu_data->dcache.entry_mask = 0x3fe0; cpu_data->dcache.sets = 512; @@ -66,7 +66,7 @@ cpu_data->dcache.linesz = L1_CACHE_BYTES; /* Set the FPU flag, virtually all SH-4's have one */ - set_bit(CPU_HAS_FPU, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_FPU; /* * Probe the underlying processor version/revision and @@ -75,7 +75,7 @@ switch (pvr) { case 0x205: cpu_data->type = CPU_SH7750; - set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG; break; case 0x206: cpu_data->type = CPU_SH7750S; @@ -84,7 +84,7 @@ * FIXME: This is needed for 7750, but do we need it for the * 7750S too? For now, assume we do.. -- PFM */ - set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags)); + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG; break; case 0x1100: @@ -102,7 +102,7 @@ cpu_data->dcache.ways = 2; /* No FPU on the SH4-500 series.. */ - clear_bit(CPU_HAS_FPU, &(cpu_data->flags)); + cpu_data->flags &= ~CPU_HAS_FPU; break; case 0x600: cpu_data->type = CPU_SH4_202; @@ -129,27 +129,20 @@ * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. */ - if (cpu_data->dcache.ways > 1) { - jump_to_P2(); - ccr = ctrl_inl(CCR); - - /* Force EMODE */ - if (!(ccr & CCR_CACHE_EMODE)) { - ccr |= CCR_CACHE_EMODE; - ctrl_outl(ccr, CCR); - } - - back_to_P1(); - + if (cpu_data->icache.ways > 1) { size = sizes[(cvr >> 20) & 0xf]; - cpu_data->icache.way_shift = (size >> 1); - cpu_data->icache.entry_mask = ((size >> 2) - (1 << 5)); - cpu_data->icache.sets = (size >> 6); + cpu_data->icache.way_incr = size / cpu_data->icache.ways; + cpu_data->icache.sets = (size >> 6); + cpu_data->icache.entry_mask = + ((size / cpu_data->icache.ways) - (1 << 5)); + } + if (cpu_data->dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; - cpu_data->dcache.way_shift = (size >> 1); - cpu_data->dcache.entry_mask = ((size >> 2) - (1 << 5)); - cpu_data->dcache.sets = (size >> 6); + cpu_data->dcache.way_incr = size / cpu_data->dcache.ways; + cpu_data->dcache.sets = (size >> 6); + cpu_data->dcache.entry_mask = + ((size / cpu_data->dcache.ways) - (1 << 5)); } return 0; @@ -250,7 +243,7 @@ int i; entry_offset = 1 << cpu_data->dcache.entry_shift; - for (i = 0; i < cpu_data->dcache.ways; i++, start += (1 << cpu_data->dcache.way_shift)) { + for (i = 0; i < cpu_data->dcache.ways; i++, start += cpu_data->dcache.way_incr) { for (addr = CACHE_OC_ADDRESS_ARRAY + start; addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start; addr += entry_offset) { @@ -297,7 +290,7 @@ local_irq_save(flags); jump_to_P2(); - for(i = 0; i < cpu_data->icache.ways; i++, index += (1 << cpu_data->icache.way_shift)) + for(i = 0; i < cpu_data->icache.ways; i++, index += cpu_data->icache.way_incr) ctrl_outl(0, index); /* Clear out Valid-bit */ back_to_P1(); local_irq_restore(flags); @@ -313,12 +306,13 @@ * SH7751, SH7751R, and ST40 have no restriction to handle cache. * (While SH7750 must do that at P2 area.) */ - if (test_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags))) { + if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) + || start < CACHE_OC_ADDRESS_ARRAY) { local_irq_save(flags); - __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0x20000000); + __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0x20000000); local_irq_restore(flags); - } else if (start >= CACHE_OC_ADDRESS_ARRAY) { - __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0); + } else { + __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0); } } diff -Nru a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c --- a/arch/sh/mm/consistent.c 2004-06-26 17:09:21 -07:00 +++ b/arch/sh/mm/consistent.c 2004-06-26 17:09:21 -07:00 @@ -24,56 +24,58 @@ if (!page) return NULL; - ret = (void *)P2SEGADDR(page_to_bus(page)); + ret = page_address(page); + *handle = virt_to_phys(ret); /* * We must flush the cache before we pass it on to the device */ dma_cache_wback_inv(ret, size); - *handle = (unsigned long)ret; - + page = virt_to_page(ret); free = page + (size >> PAGE_SHIFT); end = page + (1 << order); - do { + while (++page < end) { set_page_count(page, 1); - page++; - } while (size -= PAGE_SIZE); - /* - * Free any unused pages - */ - while (page < end) { - set_page_count(page, 1); - __free_page(page); - page++; + /* Free any unused pages */ + if (page >= free) { + __free_page(page); + } } - return ret; + return P2SEGADDR(ret); } void consistent_free(void *vaddr, size_t size) { unsigned long addr = P1SEGADDR((unsigned long)vaddr); + struct page *page=virt_to_page(addr); + int num_pages=(size+PAGE_SIZE-1) >> PAGE_SHIFT; + int i; - free_pages(addr, get_order(size)); + for(i=0;i 0) { total++; @@ -81,6 +81,66 @@ printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); printk("%d pages swap cached\n",cached); +} + +static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + + pgd = swapper_pg_dir + pgd_index(addr); + if (pgd_none(*pgd)) { + pgd_ERROR(*pgd); + return; + } + + pmd = pmd_offset(pgd, addr); + if (pmd_none(*pmd)) { + pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); + if (pte != pte_offset_kernel(pmd, 0)) { + pmd_ERROR(*pmd); + return; + } + } + + pte = pte_offset_kernel(pmd, addr); + if (!pte_none(*pte)) { + pte_ERROR(*pte); + return; + } + + set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); + + __flush_tlb_page(get_asid(), addr); +} + +/* + * As a performance optimization, other platforms preserve the fixmap mapping + * across a context switch, we don't presently do this, but this could be done + * in a similar fashion as to the wired TLB interface that sh64 uses (by way + * of the memorry mapped UTLB configuration) -- this unfortunately forces us to + * give up a TLB entry for each mapping we want to preserve. While this may be + * viable for a small number of fixmaps, it's not particularly useful for + * everything and needs to be carefully evaluated. (ie, we may want this for + * the vsyscall page). + * + * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass + * in at __set_fixmap() time to determine the appropriate behavior to follow. + * + * -- PFM. + */ +void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) +{ + unsigned long address = __fix_to_virt(idx); + + if (idx >= __end_of_fixed_addresses) { + BUG(); + return; + } + + set_pte_phys(address, phys, prot); } /* References to section boundaries */ diff -Nru a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c --- a/arch/sh/mm/pg-sh4.c 2004-06-26 17:09:17 -07:00 +++ b/arch/sh/mm/pg-sh4.c 2004-06-26 17:09:17 -07:00 @@ -1,7 +1,5 @@ -/* - * $Id: pg-sh4.c,v 1.1.2.2 2002/11/17 17:56:18 lethal Exp $ - * - * arch/sh/mm/pg-sh4.c +/* + * arch/sh/mm/pg-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka * Copyright (C) 2002 Paul Mundt @@ -101,3 +99,24 @@ up(&p3map_sem[(address & CACHE_ALIAS)>>12]); } } + +/* + * For SH-4, we have our own implementation for ptep_get_and_clear + */ +inline pte_t ptep_get_and_clear(pte_t *ptep) +{ + pte_t pte = *ptep; + + pte_clear(ptep); + if (!pte_not_present(pte)) { + unsigned long pfn = pte_pfn(pte); + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + struct address_space *mapping = page_mapping(page); + if (!mapping || !mapping_writably_mapped(mapping)) + __clear_bit(PG_mapped, &page->flags); + } + } + return pte; +} + diff -Nru a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c --- a/arch/sh/mm/tlb-sh3.c 2004-06-26 17:09:17 -07:00 +++ b/arch/sh/mm/tlb-sh3.c 2004-06-26 17:09:17 -07:00 @@ -72,7 +72,7 @@ addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000); data = (page & 0xfffe0000) | asid; /* VALID bit is off */ - if (test_bit(CPU_HAS_MMU_PAGE_ASSOC, &(cpu_data->flags))) { + if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) { addr |= MMU_PAGE_ASSOC_BIT; ways = 1; /* we already know the way .. */ } diff -Nru a/arch/sh/ramdisk/Makefile b/arch/sh/ramdisk/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/ramdisk/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,19 @@ +# +# Makefile for a ramdisk image +# + +obj-y += ramdisk.o + + +O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32) +img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE)) +# add $(src) when $(img) is relative +img := $(subst $(src)//,/,$(src)/$(img)) + +quiet_cmd_ramdisk = LD $@ +define cmd_ramdisk + $(LD) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) +endef + +$(obj)/ramdisk.o: $(img) $(src)/ld.script + $(call cmd,ramdisk) diff -Nru a/arch/sh/ramdisk/ld.script b/arch/sh/ramdisk/ld.script --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/sh/ramdisk/ld.script 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,9 @@ +OUTPUT_ARCH(sh) +SECTIONS +{ + .initrd : + { + *(.data) + } +} + diff -Nru a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types --- a/arch/sh/tools/mach-types 2004-06-26 17:09:21 -07:00 +++ b/arch/sh/tools/mach-types 2004-06-26 17:09:21 -07:00 @@ -7,6 +7,7 @@ # SE SH_SOLUTION_ENGINE 7751SE SH_7751_SOLUTION_ENGINE +7300SE SH_7300_SOLUTION_ENGINE 7751SYSTEMH SH_7751_SYSTEMH HP600 SH_HP600 HP620 SH_HP620 @@ -21,4 +22,6 @@ ADX SH_ADX MPC1211 SH_MPC1211 SNAPGEAR SH_SECUREEDGE5410 +HS7751RVOIP SH_HS7751RVOIP +RTS7751R2D SH_RTS7751R2D diff -Nru a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c --- a/arch/sparc/kernel/init_task.c 2004-06-26 17:09:18 -07:00 +++ b/arch/sparc/kernel/init_task.c 2004-06-26 17:09:18 -07:00 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c --- a/arch/sparc/kernel/irq.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sparc/kernel/irq.c 2004-06-26 17:09:15 -07:00 @@ -449,7 +449,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = NULL; action->next = NULL; @@ -529,7 +529,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c --- a/arch/sparc/kernel/setup.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sparc/kernel/setup.c 2004-06-26 17:09:15 -07:00 @@ -244,8 +244,7 @@ extern int root_mountflags; -char saved_command_line[256]; -char reboot_command[256]; +char reboot_command[COMMAND_LINE_SIZE]; enum sparc_cpu sparc_cpu_model; struct tt_entry *sparc_ttable; diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c --- a/arch/sparc/kernel/sparc_ksyms.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sparc/kernel/sparc_ksyms.c 2004-06-26 17:09:15 -07:00 @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -74,7 +75,6 @@ extern void *__memscan_generic(void *, int, size_t); extern int __memcmp(const void *, const void *, __kernel_size_t); extern int __strncmp(const char *, const char *, __kernel_size_t); -extern char saved_command_line[]; extern void bcopy (const char *, char *, int); extern int __ashrdi3(int, int); diff -Nru a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c --- a/arch/sparc/kernel/sun4d_irq.c 2004-06-26 17:09:14 -07:00 +++ b/arch/sparc/kernel/sun4d_irq.c 2004-06-26 17:09:14 -07:00 @@ -336,7 +336,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c --- a/arch/sparc/mm/init.c 2004-06-26 17:09:17 -07:00 +++ b/arch/sparc/mm/init.c 2004-06-26 17:09:17 -07:00 @@ -76,7 +76,7 @@ { printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", + printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", totalram_pages); printk("%d free pages\n", nr_free_pages()); diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig --- a/arch/sparc64/defconfig 2004-06-26 17:09:17 -07:00 +++ b/arch/sparc64/defconfig 2004-06-26 17:09:17 -07:00 @@ -110,6 +110,7 @@ # # Generic Driver Options # +# CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set @@ -117,6 +118,7 @@ # Graphics support # CONFIG_FB=y +# CONFIG_FB_CIRRUS is not set CONFIG_FB_PM2=y # CONFIG_FB_PM2_FIFO_DISCONNECT is not set # CONFIG_FB_CYBER2000 is not set @@ -219,7 +221,7 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_CARMEL=m +CONFIG_BLK_DEV_SX8=m # CONFIG_BLK_DEV_RAM is not set # @@ -231,6 +233,7 @@ # # Please see Documentation/ide.txt for help/info on IDE drives # +# CONFIG_BLK_DEV_IDE_SATA is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set CONFIG_BLK_DEV_IDECD=y @@ -317,6 +320,7 @@ # SCSI low-level drivers # CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m CONFIG_SCSI_ACARD=m CONFIG_SCSI_AACRAID=m # CONFIG_SCSI_AIC7XXX is not set @@ -334,6 +338,7 @@ CONFIG_SCSI_SATA=y CONFIG_SCSI_SATA_SVW=m CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_NV=m CONFIG_SCSI_SATA_PROMISE=m CONFIG_SCSI_SATA_SX4=m CONFIG_SCSI_SATA_SIL=m @@ -407,6 +412,9 @@ CONFIG_MD_MULTIPATH=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m # # Fusion MPT device support @@ -579,6 +587,8 @@ CONFIG_IP_NF_COMPAT_IPFWADM=m CONFIG_IP_NF_TARGET_NOTRACK=m CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m # # IPv6: Netfilter Configuration @@ -696,9 +706,12 @@ CONFIG_NET_CLS_ROUTE=y CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_POLICE=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m # # Network testing @@ -860,6 +873,7 @@ CONFIG_SUNDANCE_MMIO=y CONFIG_VIA_RHINE=m # CONFIG_VIA_RHINE_MMIO is not set +CONFIG_VIA_VELOCITY=m # # Ethernet (1000 Mbit) @@ -1195,6 +1209,8 @@ CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -1255,6 +1271,7 @@ # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +CONFIG_CIFS_POSIX=y CONFIG_NCP_FS=m # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set @@ -1281,43 +1298,44 @@ # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m # # Multimedia devices @@ -1349,6 +1367,7 @@ CONFIG_VIDEO_HEXIUM_ORION=m CONFIG_VIDEO_HEXIUM_GEMINI=m CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_OVCAMCHIP=m # # Radio Adapters @@ -1544,6 +1563,7 @@ CONFIG_USB_PRINTER=m CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_RW_DETECT=y # CONFIG_USB_STORAGE_DATAFAB is not set CONFIG_USB_STORAGE_FREECOM=y CONFIG_USB_STORAGE_ISD200=y @@ -1585,7 +1605,6 @@ # CONFIG_USB_IBMCAM is not set # CONFIG_USB_KONICAWC is not set # CONFIG_USB_OV511 is not set -CONFIG_USB_PWC=m # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set CONFIG_USB_W9968CF=m diff -Nru a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S --- a/arch/sparc64/kernel/entry.S 2004-06-26 17:09:14 -07:00 +++ b/arch/sparc64/kernel/entry.S 2004-06-26 17:09:14 -07:00 @@ -1751,42 +1751,44 @@ ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 - cmp %o0, -ENOIOCTLCMD sllx %g2, 32, %g2 + + /* Check if force_successful_syscall_return() + * was invoked. + */ + ldx [%curptr + TI_FLAGS], %l0 + andcc %l0, _TIF_SYSCALL_SUCCESS, %g0 + be,pt %icc, 1f + andn %l0, _TIF_SYSCALL_SUCCESS, %l0 + ba,pt %xcc, 80f + stx %l0, [%curptr + TI_FLAGS] + +1: + cmp %o0, -ENOIOCTLCMD bgeu,pn %xcc, 1f andcc %l0, _TIF_SYSCALL_TRACE, %l6 80: - andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ + /* System call success, clear Carry condition code. */ + andn %g3, %g2, %g3 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 - add %l1, 0x4, %l2 ! npc = npc+4 + add %l1, 0x4, %l2 ! npc = npc+4 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ba,pt %xcc, rtrap_clr_l6 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 1: - /* Really a failure? Check if force_successful_syscall_return() - * was invoked. - */ - ldx [%curptr + TI_FLAGS], %l0 ! Load - andcc %l0, _TIF_SYSCALL_SUCCESS, %g0 - be,pt %icc, 1f - andcc %l0, _TIF_SYSCALL_TRACE, %l6 - andn %l0, _TIF_SYSCALL_SUCCESS, %l0 - ba,pt %xcc, 80b - stx %l0, [%curptr + TI_FLAGS] - /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ -1: + andcc %l0, _TIF_SYSCALL_TRACE, %l6 sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] mov 1, %l6 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 - add %l1, 0x4, %l2 !npc = npc+4 + add %l1, 0x4, %l2 ! npc = npc+4 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] b,pt %xcc, rtrap diff -Nru a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c --- a/arch/sparc64/kernel/init_task.c 2004-06-26 17:09:21 -07:00 +++ b/arch/sparc64/kernel/init_task.c 2004-06-26 17:09:21 -07:00 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c --- a/arch/sparc64/kernel/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/sparc64/kernel/irq.c 2004-06-26 17:09:20 -07:00 @@ -118,10 +118,6 @@ action->flags |= __irq_ino(irq) << 48; #define get_ino_in_irqaction(action) (action->flags >> 48) -#if NR_CPUS > 64 -#error irqaction embedded smp affinity does not work with > 64 cpus, FIXME -#endif - #define put_smpaff_in_irqaction(action, smpaff) (action)->mask = (smpaff) #define get_smpaff_in_irqaction(action) ((action)->mask) @@ -458,7 +454,7 @@ action->next = NULL; action->dev_id = dev_id; put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, 0); + put_smpaff_in_irqaction(action, CPU_MASK_NONE); if (tmp) tmp->next = action; @@ -691,9 +687,10 @@ * Just Do It. */ struct irqaction *ap = bp->irq_info; - cpumask_t cpu_mask = get_smpaff_in_irqaction(ap); + cpumask_t cpu_mask; unsigned int buddy, ticks; + cpu_mask = get_smpaff_in_irqaction(ap); cpus_and(cpu_mask, cpu_mask, cpu_online_map); if (cpus_empty(cpu_mask)) cpu_mask = cpu_online_map; @@ -714,7 +711,7 @@ if (++buddy >= NR_CPUS) buddy = 0; if (++ticks > NR_CPUS) { - put_smpaff_in_irqaction(ap, 0); + put_smpaff_in_irqaction(ap, CPU_MASK_NONE); goto out; } } @@ -948,7 +945,7 @@ action->name = name; action->next = NULL; put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, 0); + put_smpaff_in_irqaction(action, CPU_MASK_NONE); *(bucket->pil + irq_action) = action; enable_irq(irq); @@ -1166,53 +1163,15 @@ #ifdef CONFIG_SMP -#define HEX_DIGITS 16 - -static unsigned int parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) -{ - unsigned char hexnum [HEX_DIGITS]; - unsigned long value; - int i; - - if (!count) - return -EINVAL; - if (count > HEX_DIGITS) - count = HEX_DIGITS; - if (copy_from_user(hexnum, buffer, count)) - return -EFAULT; - - /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. - */ - value = 0; - - for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; - - switch (c) { - case '0' ... '9': c -= '0'; break; - case 'a' ... 'f': c -= 'a'-10; break; - case 'A' ... 'F': c -= 'A'-10; break; - default: - goto out; - } - value = (value << 4) | c; - } -out: - *ret = value; - return 0; -} - static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { struct ino_bucket *bp = ivector_table + (long)data; struct irqaction *ap = bp->irq_info; - cpumask_t mask = get_smpaff_in_irqaction(ap); + cpumask_t mask; int len; + mask = get_smpaff_in_irqaction(ap); if (cpus_empty(mask)) mask = cpu_online_map; @@ -1223,7 +1182,7 @@ return len; } -static inline void set_intr_affinity(int irq, unsigned long hw_aff) +static inline void set_intr_affinity(int irq, cpumask_t hw_aff) { struct ino_bucket *bp = ivector_table + irq; @@ -1241,22 +1200,17 @@ unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value, i; + cpumask_t new_value; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); /* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - for (i = 0; i < NR_CPUS; i++) { - if ((new_value & (1UL << i)) != 0 && - !cpu_online(i)) - new_value &= ~(1UL << i); - } - - if (!new_value) + cpus_and(new_value, new_value, cpu_online_map); + if (cpus_empty(new_value)) return -EINVAL; set_intr_affinity(irq, new_value); diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c --- a/arch/sparc64/kernel/setup.c 2004-06-26 17:09:17 -07:00 +++ b/arch/sparc64/kernel/setup.c 2004-06-26 17:09:17 -07:00 @@ -451,8 +451,7 @@ extern int root_mountflags; -char saved_command_line[256]; -char reboot_command[256]; +char reboot_command[COMMAND_LINE_SIZE]; static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c --- a/arch/sparc64/kernel/smp.c 2004-06-26 17:09:15 -07:00 +++ b/arch/sparc64/kernel/smp.c 2004-06-26 17:09:15 -07:00 @@ -406,23 +406,14 @@ int i; __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, mask)) { - spitfire_xcall_helper(data0, data1, data2, pstate, i); - cpu_clear(i, mask); - if (cpus_empty(mask)) - break; - } - } + for_each_cpu_mask(i, mask) + spitfire_xcall_helper(data0, data1, data2, pstate, i); } /* Cheetah now allows to send the whole 64-bytes of data in the interrupt * packet, but we have no use for that. However we do take advantage of * the new pipelining feature (ie. dispatch to multiple cpus simultaneously). */ -#if NR_CPUS > 32 -#error Fixup cheetah_xcall_deliver Dave... -#endif static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { u64 pstate, ver; @@ -456,25 +447,19 @@ nack_busy_id = 0; { - cpumask_t work_mask = mask; int i; - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, work_mask)) { - u64 target = (i << 14) | 0x70; - - if (!is_jalapeno) - target |= (nack_busy_id << 24); - __asm__ __volatile__( - "stxa %%g0, [%0] %1\n\t" - "membar #Sync\n\t" - : /* no outputs */ - : "r" (target), "i" (ASI_INTR_W)); - nack_busy_id++; - cpu_clear(i, work_mask); - if (cpus_empty(work_mask)) - break; - } + for_each_cpu_mask(i, mask) { + u64 target = (i << 14) | 0x70; + + if (!is_jalapeno) + target |= (nack_busy_id << 24); + __asm__ __volatile__( + "stxa %%g0, [%0] %1\n\t" + "membar #Sync\n\t" + : /* no outputs */ + : "r" (target), "i" (ASI_INTR_W)); + nack_busy_id++; } } @@ -507,7 +492,6 @@ printk("CPU[%d]: mondo stuckage result[%016lx]\n", smp_processor_id(), dispatch_stat); } else { - cpumask_t work_mask = mask; int i, this_busy_nack = 0; /* Delay some random time with interrupts enabled @@ -518,22 +502,17 @@ /* Clear out the mask bits for cpus which did not * NACK us. */ - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, work_mask)) { - u64 check_mask; - - if (is_jalapeno) - check_mask = (0x2UL << (2*i)); - else - check_mask = (0x2UL << - this_busy_nack); - if ((dispatch_stat & check_mask) == 0) - cpu_clear(i, mask); - this_busy_nack += 2; - cpu_clear(i, work_mask); - if (cpus_empty(work_mask)) - break; - } + for_each_cpu_mask(i, mask) { + u64 check_mask; + + if (is_jalapeno) + check_mask = (0x2UL << (2*i)); + else + check_mask = (0x2UL << + this_busy_nack); + if ((dispatch_stat & check_mask) == 0) + cpu_clear(i, mask); + this_busy_nack += 2; } goto retry; diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c --- a/arch/sparc64/kernel/sparc64_ksyms.c 2004-06-26 17:09:20 -07:00 +++ b/arch/sparc64/kernel/sparc64_ksyms.c 2004-06-26 17:09:20 -07:00 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -76,7 +77,6 @@ extern int __strncmp(const char *, const char *, __kernel_size_t); extern __kernel_size_t __strlen(const char *); extern __kernel_size_t strlen(const char *); -extern char saved_command_line[]; extern void linux_sparc_syscall(void); extern void rtrap(void); extern void show_regs(struct pt_regs *); @@ -327,7 +327,6 @@ EXPORT_SYMBOL(sys_getgid); EXPORT_SYMBOL(svr4_getcontext); EXPORT_SYMBOL(svr4_setcontext); -EXPORT_SYMBOL(sys_ioctl); EXPORT_SYMBOL(compat_sys_ioctl); EXPORT_SYMBOL(sparc32_open); EXPORT_SYMBOL(sys_close); diff -Nru a/arch/sparc64/lib/find_bit.c b/arch/sparc64/lib/find_bit.c --- a/arch/sparc64/lib/find_bit.c 2004-06-26 17:09:18 -07:00 +++ b/arch/sparc64/lib/find_bit.c 2004-06-26 17:09:18 -07:00 @@ -6,9 +6,10 @@ * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset) +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) { - unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> 6); unsigned long result = offset & ~63UL; unsigned long tmp; diff -Nru a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c --- a/arch/sparc64/mm/init.c 2004-06-26 17:09:17 -07:00 +++ b/arch/sparc64/mm/init.c 2004-06-26 17:09:17 -07:00 @@ -348,7 +348,7 @@ { printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", + printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", num_physpages); printk("%d free pages\n", nr_free_pages()); diff -Nru a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c --- a/arch/um/kernel/init_task.c 2004-06-26 17:09:21 -07:00 +++ b/arch/um/kernel/init_task.c 2004-06-26 17:09:21 -07:00 @@ -9,6 +9,7 @@ #include "linux/sched.h" #include "linux/init_task.h" #include "linux/version.h" +#include "linux/mqueue.h" #include "asm/uaccess.h" #include "asm/pgtable.h" #include "user_util.h" diff -Nru a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c --- a/arch/um/kernel/irq.c 2004-06-26 17:09:20 -07:00 +++ b/arch/um/kernel/irq.c 2004-06-26 17:09:20 -07:00 @@ -419,7 +419,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c --- a/arch/um/kernel/mem.c 2004-06-26 17:09:17 -07:00 +++ b/arch/um/kernel/mem.c 2004-06-26 17:09:17 -07:00 @@ -380,7 +380,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); pfn = max_mapnr; while(pfn-- > 0) { page = pfn_to_page(pfn); diff -Nru a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c --- a/arch/um/kernel/user_util.c 2004-06-26 17:09:16 -07:00 +++ b/arch/um/kernel/user_util.c 2004-06-26 17:09:16 -07:00 @@ -34,7 +34,6 @@ #define COMMAND_LINE_SIZE _POSIX_ARG_MAX /* Changed in linux_main and setup_arch, which run before SMP is started */ -char saved_command_line[COMMAND_LINE_SIZE] = { 0 }; char command_line[COMMAND_LINE_SIZE] = { 0 }; void add_arg(char *cmd_line, char *arg) diff -Nru a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c --- a/arch/v850/kernel/fpga85e2c.c 2004-06-26 17:09:20 -07:00 +++ b/arch/v850/kernel/fpga85e2c.c 2004-06-26 17:09:20 -07:00 @@ -168,5 +168,5 @@ static int reg_snap_dev_id; static struct irqaction reg_snap_action = { - make_reg_snap, 0, 0, "reg_snap", ®_snap_dev_id, 0 + make_reg_snap, 0, CPU_MASK_NONE, "reg_snap", ®_snap_dev_id, 0 }; diff -Nru a/arch/v850/kernel/init_task.c b/arch/v850/kernel/init_task.c --- a/arch/v850/kernel/init_task.c 2004-06-26 17:09:16 -07:00 +++ b/arch/v850/kernel/init_task.c 2004-06-26 17:09:16 -07:00 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c --- a/arch/v850/kernel/irq.c 2004-06-26 17:09:19 -07:00 +++ b/arch/v850/kernel/irq.c 2004-06-26 17:09:19 -07:00 @@ -392,7 +392,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/v850/kernel/setup.c b/arch/v850/kernel/setup.c --- a/arch/v850/kernel/setup.c 2004-06-26 17:09:17 -07:00 +++ b/arch/v850/kernel/setup.c 2004-06-26 17:09:17 -07:00 @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -40,8 +41,7 @@ extern char _root_fs_image_end __attribute__ ((__weak__)); -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; /* Memory not used by the kernel. */ static unsigned long total_ram_pages; diff -Nru a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c --- a/arch/v850/kernel/time.c 2004-06-26 17:09:19 -07:00 +++ b/arch/v850/kernel/time.c 2004-06-26 17:09:19 -07:00 @@ -203,7 +203,7 @@ static struct irqaction timer_irqaction = { timer_interrupt, SA_INTERRUPT, - 0, + CPU_MASK_NONE, "timer", &timer_dev_id, NULL diff -Nru a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S --- a/arch/v850/kernel/vmlinux.lds.S 2004-06-26 17:09:19 -07:00 +++ b/arch/v850/kernel/vmlinux.lds.S 2004-06-26 17:09:19 -07:00 @@ -1,8 +1,8 @@ /* * arch/v850/vmlinux.lds.S -- kernel linker script for v850 platforms * - * Copyright (C) 2002,03 NEC Electronics Corporation - * Copyright (C) 2002,03 Miles Bader + * Copyright (C) 2002,03,04 NEC Electronics Corporation + * Copyright (C) 2002,03,04 Miles Bader * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this @@ -65,7 +65,7 @@ #define TEXT_CONTENTS \ __stext = . ; \ *(.text) \ - SCHED_TEXT + SCHED_TEXT \ *(.exit.text) /* 2.5 convention */ \ *(.text.exit) /* 2.4 convention */ \ *(.text.lock) \ diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile --- a/arch/x86_64/Makefile 2004-06-26 17:09:20 -07:00 +++ b/arch/x86_64/Makefile 2004-06-26 17:09:20 -07:00 @@ -37,6 +37,8 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S LDFLAGS_vmlinux := -e stext +CHECK := $(CHECK) -D__x86_64__=1 + cflags-$(CONFIG_MK8) += $(call check_gcc,-march=k8,) cflags-$(CONFIG_MPSC) += $(call check_gcc,-march=nocona,) CFLAGS += $(cflags-y) diff -Nru a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c --- a/arch/x86_64/kernel/e820.c 2004-06-26 17:09:16 -07:00 +++ b/arch/x86_64/kernel/e820.c 2004-06-26 17:09:16 -07:00 @@ -34,7 +34,7 @@ */ unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT; -extern struct resource code_resource, data_resource, vram_resource; +extern struct resource code_resource, data_resource; /* Check for some hardcoded bad areas that early boot is not allowed to touch */ static inline int bad_addr(unsigned long *addrp, unsigned long size) diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c --- a/arch/x86_64/kernel/i8259.c 2004-06-26 17:09:16 -07:00 +++ b/arch/x86_64/kernel/i8259.c 2004-06-26 17:09:16 -07:00 @@ -47,6 +47,12 @@ BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ BI(x,c) BI(x,d) BI(x,e) BI(x,f) +#define BUILD_14_IRQS(x) \ + BI(x,0) BI(x,1) BI(x,2) BI(x,3) \ + BI(x,4) BI(x,5) BI(x,6) BI(x,7) \ + BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ + BI(x,c) BI(x,d) + /* * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: * (these are usually mapped to vectors 0x20-0x2f) @@ -68,9 +74,15 @@ BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) + +#ifdef CONFIG_PCI_USE_VECTOR + BUILD_14_IRQS(0xe) +#endif + #endif #undef BUILD_16_IRQS +#undef BUILD_14_IRQS #undef BI @@ -83,6 +95,12 @@ IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) +#define IRQLIST_14(x) \ + IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \ + IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \ + IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ + IRQ(x,c), IRQ(x,d) + void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), @@ -91,11 +109,17 @@ IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), IRQLIST_16(0xc), IRQLIST_16(0xd) + +#ifdef CONFIG_PCI_USE_VECTOR + , IRQLIST_14(0xe) +#endif + #endif }; #undef IRQ #undef IRQLIST_16 +#undef IRQLIST_14 /* * This is the 'legacy' 8259A Programmable Interrupt Controller, @@ -365,7 +389,7 @@ * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init init_ISA_irqs (void) { diff -Nru a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c --- a/arch/x86_64/kernel/init_task.c 2004-06-26 17:09:18 -07:00 +++ b/arch/x86_64/kernel/init_task.c 2004-06-26 17:09:18 -07:00 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c --- a/arch/x86_64/kernel/io_apic.c 2004-06-26 17:09:18 -07:00 +++ b/arch/x86_64/kernel/io_apic.c 2004-06-26 17:09:18 -07:00 @@ -67,8 +67,8 @@ short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; #ifdef CONFIG_PCI_USE_VECTOR -int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; #define vector_to_irq(vector) \ (platform_legacy_irq(vector) ? vector : vector_irq[vector]) #else @@ -656,10 +656,14 @@ /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; -#ifndef CONFIG_PCI_USE_VECTOR +#ifdef CONFIG_PCI_USE_VECTOR +int assign_irq_vector(int irq) +#else int __init assign_irq_vector(int irq) +#endif { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; + BUG_ON(irq >= NR_IRQ_VECTORS); if (IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); @@ -668,18 +672,19 @@ if (current_vector == IA32_SYSCALL_VECTOR) goto next; - if (current_vector > FIRST_SYSTEM_VECTOR) { + if (current_vector >= FIRST_SYSTEM_VECTOR) { offset++; + if (!(offset%8)) + return -ENOSPC; current_vector = FIRST_DEVICE_VECTOR + offset; } - if (current_vector == FIRST_SYSTEM_VECTOR) - panic("ran out of interrupt sources!"); + vector_irq[current_vector] = irq; + if (irq != AUTO_ASSIGN) + IO_APIC_VECTOR(irq) = current_vector; - IO_APIC_VECTOR(irq) = current_vector; return current_vector; } -#endif extern void (*interrupt[NR_IRQS])(void); static struct hw_interrupt_type ioapic_level_type; @@ -925,12 +930,17 @@ ); } } + if (use_pci_vector()) + printk(KERN_INFO "Using vector-based indexing\n"); printk(KERN_DEBUG "IRQ to pin mappings:\n"); for (i = 0; i < NR_IRQS; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; - printk(KERN_DEBUG "IRQ%d ", i); + if (use_pci_vector() && !platform_legacy_irq(i)) + printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); + else + printk(KERN_DEBUG "IRQ%d ", i); for (;;) { printk("-> %d:%d", entry->apic, entry->pin); if (!entry->next) @@ -1384,7 +1394,7 @@ unsigned long flags; unsigned int dest; - dest = cpu_mask_to_apicid(mk_cpumask_const(mask)); + dest = cpu_mask_to_apicid(mask); /* * Only the first 8 bits are valid. diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c --- a/arch/x86_64/kernel/irq.c 2004-06-26 17:09:17 -07:00 +++ b/arch/x86_64/kernel/irq.c 2004-06-26 17:09:17 -07:00 @@ -488,7 +488,7 @@ action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c --- a/arch/x86_64/kernel/mpparse.c 2004-06-26 17:09:17 -07:00 +++ b/arch/x86_64/kernel/mpparse.c 2004-06-26 17:09:17 -07:00 @@ -716,7 +716,7 @@ } mp_ioapic_routing[MAX_IO_APICS]; -static int __init mp_find_ioapic ( +static int mp_find_ioapic ( int gsi) { int i = 0; @@ -859,15 +859,22 @@ for (i = 0; i < 16; i++) { int idx; - for (idx = 0; idx < mp_irq_entries; idx++) - if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS && - (mp_irqs[idx].mpc_srcbusirq == i || - mp_irqs[idx].mpc_dstirq == i)) - break; + for (idx = 0; idx < mp_irq_entries; idx++) { + struct mpc_config_intsrc *irq = mp_irqs + idx; + + /* Do we already have a mapping for this ISA IRQ? */ + if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i) + break; + + /* Do we already have a mapping for this IOAPIC pin */ + if ((irq->mpc_dstapic == intsrc.mpc_dstapic) && + (irq->mpc_dstirq == i)) + break; + } if (idx != mp_irq_entries) { printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i); - continue; /* IRQ already used */ + continue; /* IRQ already used */ } intsrc.mpc_irqtype = mp_INT; @@ -888,91 +895,54 @@ return; } - -extern FADT_DESCRIPTOR acpi_fadt; - -#ifdef CONFIG_ACPI_PCI - -void __init mp_parse_prt (void) +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) { - struct list_head *node = NULL; - struct acpi_prt_entry *entry = NULL; int ioapic = -1; int ioapic_pin = 0; - int gsi = 0; int idx, bit = 0; - int edge_level = 0; - int active_high_low = 0; - /* - * Parsing through the PCI Interrupt Routing Table (PRT) and program - * routing for all static (IOAPIC-direct) entries. - */ - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); + if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) + return; - /* Need to get gsi for dynamic entry */ - if (entry->link.handle) { - gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); - if (!gsi) - continue; - } else { - /* Hardwired GSI. Assume PCI standard settings */ - gsi = entry->link.index; - edge_level = 1; - active_high_low = 1; - } +#ifdef CONFIG_ACPI_BUS + /* Don't set up the ACPI SCI because it's already set up */ + if (acpi_fadt.sci_int == gsi) + return; +#endif - /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_fadt.sci_int == gsi) { - /* we still need to set up the entry's irq */ - acpi_gsi_to_irq(gsi, &entry->irq); - continue; - } + ioapic = mp_find_ioapic(gsi); + if (ioapic < 0) { + printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); + return; + } - ioapic = mp_find_ioapic(gsi); - if (ioapic < 0) - continue; - ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; - - /* - * Avoid pin reprogramming. PRTs typically include entries - * with redundant pin->gsi mappings (but unique PCI devices); - * we only only program the IOAPIC on the first. - */ - bit = ioapic_pin % 32; - idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); - if (idx > 3) { - printk(KERN_ERR "Invalid reference to IOAPIC pin " - "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, - ioapic_pin); - continue; - } - if ((1<irq); - continue; - } + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; - mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq); - } - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", - entry->id.segment, entry->id.bus, - entry->id.device, ('A' + entry->pin), - mp_ioapic_routing[ioapic].apic_id, ioapic_pin, - entry->irq); + /* + * Avoid pin reprogramming. PRTs typically include entries + * with redundant pin->gsi mappings (but unique PCI devices); + * we only program the IOAPIC on the first. + */ + bit = ioapic_pin % 32; + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); + if (idx > 3) { + printk(KERN_ERR "Invalid reference to IOAPIC pin " + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, + ioapic_pin); + return; + } + if ((1<bus->number : -1; - cpumask_const_t bus_cpumask = pcibus_to_cpumask(bus); + cpumask_t bus_cpumask = pcibus_to_cpumask(bus); int flushed = 0; int i; @@ -158,7 +158,7 @@ u32 w; if (!northbridges[i]) continue; - if (bus >= 0 && !(cpu_isset_const(i, bus_cpumask))) + if (bus >= 0 && !(cpu_isset(i, bus_cpumask))) continue; pci_write_config_dword(northbridges[i], 0x9c, northbridge_flush_word[i] | 1); diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c 2004-06-26 17:09:15 -07:00 +++ b/arch/x86_64/kernel/setup.c 2004-06-26 17:09:15 -07:00 @@ -100,7 +100,6 @@ extern char _text, _etext, _edata, _end; char command_line[COMMAND_LINE_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f, IORESOURCE_BUSY | IORESOURCE_IO }, @@ -116,9 +115,10 @@ #define STANDARD_IO_RESOURCES \ (sizeof standard_io_resources / sizeof standard_io_resources[0]) -struct resource code_resource = { "Kernel code", 0x100000, 0, IORESOURCE_MEM }; -struct resource data_resource = { "Kernel data", 0, 0, IORESOURCE_MEM }; -struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY | IORESOURCE_MEM }; +#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM) + +struct resource data_resource = { "Kernel data", 0, 0, IORESOURCE_RAM }; +struct resource code_resource = { "Kernel code", 0, 0, IORESOURCE_RAM }; #define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM) @@ -138,10 +138,11 @@ (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) static struct resource video_rom_resource = { "Video ROM", 0xc0000, 0xc7fff, IORESOURCE_ROM }; +static struct resource video_ram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_RAM }; #define romsignature(x) (*(unsigned short *)(x) == 0xaa55) -static int __init checksum(unsigned char *rom, unsigned long length) +static int __init romchecksum(unsigned char *rom, unsigned long length) { unsigned char *p, sum = 0; @@ -169,7 +170,7 @@ length = rom[2] * 512; /* if checksum okay, trust length byte */ - if (length && checksum(rom, length)) + if (length && romchecksum(rom, length)) video_rom_resource.end = start + length - 1; request_resource(&iomem_resource, &video_rom_resource); @@ -188,7 +189,7 @@ rom = isa_bus_to_virt(extension_rom_resource.start); if (romsignature(rom)) { length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (checksum(rom, length)) { + if (romchecksum(rom, length)) { request_resource(&iomem_resource, &extension_rom_resource); upper = extension_rom_resource.start; } @@ -204,7 +205,7 @@ length = rom[2] * 512; /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !checksum(rom, length)) + if (!length || start + length > upper || !romchecksum(rom, length)) continue; adapter_rom_resources[i].start = start; @@ -555,13 +556,13 @@ probe_roms(); e820_reserve_resources(); - request_resource(&iomem_resource, &vram_resource); + request_resource(&iomem_resource, &video_ram_resource); { unsigned i; /* request I/O space for devices used on all i[345]86 PCs */ for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, standard_io_resources+i); + request_resource(&ioport_resource, &standard_io_resources[i]); } /* Will likely break when you have unassigned resources with more diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c --- a/arch/x86_64/kernel/smp.c 2004-06-26 17:09:21 -07:00 +++ b/arch/x86_64/kernel/smp.c 2004-06-26 17:09:21 -07:00 @@ -94,7 +94,7 @@ static inline void send_IPI_mask(cpumask_t cpumask, int vector) { - unsigned long mask = cpus_coerce(cpumask); + unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; unsigned long flags; diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c --- a/arch/x86_64/kernel/smpboot.c 2004-06-26 17:09:21 -07:00 +++ b/arch/x86_64/kernel/smpboot.c 2004-06-26 17:09:21 -07:00 @@ -827,7 +827,7 @@ if (apicid == boot_cpu_id || (apicid == BAD_APICID)) continue; - if (!cpu_isset(apicid, phys_cpu_present_map)) + if (!physid_isset(apicid, phys_cpu_present_map)) continue; if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) continue; diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c --- a/arch/x86_64/kernel/time.c 2004-06-26 17:09:19 -07:00 +++ b/arch/x86_64/kernel/time.c 2004-06-26 17:09:19 -07:00 @@ -689,7 +689,7 @@ } static struct irqaction irq0 = { - timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL + timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL }; extern void __init config_acpi_tables(void); diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c --- a/arch/x86_64/kernel/x8664_ksyms.c 2004-06-26 17:09:16 -07:00 +++ b/arch/x86_64/kernel/x8664_ksyms.c 2004-06-26 17:09:16 -07:00 @@ -218,4 +218,3 @@ EXPORT_SYMBOL_GPL(flush_tlb_all); #endif -EXPORT_SYMBOL(sys_ioctl); diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c --- a/arch/x86_64/mm/init.c 2004-06-26 17:09:16 -07:00 +++ b/arch/x86_64/mm/init.c 2004-06-26 17:09:16 -07:00 @@ -60,7 +60,7 @@ printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c --- a/arch/x86_64/mm/numa.c 2004-06-26 17:09:20 -07:00 +++ b/arch/x86_64/mm/numa.c 2004-06-26 17:09:20 -07:00 @@ -182,7 +182,7 @@ numnodes = 1; for (i = 0; i < NR_CPUS; i++) cpu_to_node[i] = 0; - node_to_cpumask[0] = 1; + node_to_cpumask[0] = cpumask_of_cpu(0); setup_node_bootmem(0, start_pfn< #include #include -#ifdef CONFIG_X86_IO_APIC -#include -#endif -#ifdef CONFIG_IOSAPIC -# include -#endif #include #include @@ -50,10 +44,6 @@ struct acpi_prt_list acpi_prt; -#ifdef CONFIG_X86 -extern void eisa_set_level_irq(unsigned int irq); -#endif - /* -------------------------------------------------------------------------- PCI IRQ Routing Table (PRT) Support @@ -237,12 +227,18 @@ PCI Interrupt Routing Support -------------------------------------------------------------------------- */ -int -acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin) +static int +acpi_pci_irq_lookup ( + struct pci_bus *bus, + int device, + int pin, + int *edge_level, + int *active_high_low) { struct acpi_prt_entry *entry = NULL; int segment = pci_domain_nr(bus); int bus_nr = bus->number; + int irq; ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); @@ -255,28 +251,30 @@ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); return_VALUE(0); } - - if (!entry->irq && entry->link.handle) { - entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL); - if (!entry->irq) { + + if (entry->link.handle) { + irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, edge_level, active_high_low); + if (!irq) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); return_VALUE(0); } - } - else if (!entry->irq) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry (IRQ 0)\n")); - return_VALUE(0); + } else { + irq = entry->link.index; + *edge_level = ACPI_LEVEL_SENSITIVE; + *active_high_low = ACPI_ACTIVE_LOW; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); - return_VALUE(entry->irq); + return_VALUE(irq); } static int acpi_pci_irq_derive ( struct pci_dev *dev, - int pin) + int pin, + int *edge_level, + int *active_high_low) { struct pci_dev *bridge = dev; int irq = 0; @@ -308,8 +306,8 @@ pin = bridge_pin; } - irq = acpi_pci_irq_lookup(bridge->bus, - PCI_SLOT(bridge->devfn), pin); + irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), + pin, edge_level, active_high_low); } if (!irq) { @@ -330,6 +328,8 @@ { int irq = 0; u8 pin = 0; + int edge_level = ACPI_LEVEL_SENSITIVE; + int active_high_low = ACPI_ACTIVE_LOW; ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); @@ -352,21 +352,22 @@ * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT * values override any BIOS-assigned IRQs set during boot. */ - irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin); + irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, &edge_level, &active_high_low); /* * If no PRT entry was found, we'll try to derive an IRQ from the * device's parent bridge. */ if (!irq) - irq = acpi_pci_irq_derive(dev, pin); + irq = acpi_pci_irq_derive(dev, pin, &edge_level, &active_high_low); /* * No IRQ known to the ACPI subsystem - maybe the BIOS / * driver reported one, then use it. Exit in any case. */ if (!irq) { - printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), pci_name(dev)); + printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI", + pci_name(dev), ('A' + pin)); /* Interrupt Line values above 0xF are forbidden */ if (dev->irq && (dev->irq <= 0xF)) { printk(" - using IRQ %d\n", dev->irq); @@ -378,62 +379,14 @@ } } - dev->irq = irq; + dev->irq = acpi_register_gsi(irq, edge_level, active_high_low); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", pci_name(dev), dev->irq)); - - /* - * Make sure all (legacy) PCI IRQs are set as level-triggered. - */ -#ifdef CONFIG_X86 - { - static u16 irq_mask; - if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq)); - irq_mask |= (1 << dev->irq); - eisa_set_level_irq(dev->irq); - } - } -#endif -#ifdef CONFIG_IOSAPIC - if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC) - iosapic_enable_intr(dev->irq); -#endif + printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI %u " + "(%s, %s) -> IRQ %d\n", + pci_name(dev), 'A' + pin, irq, + (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", + (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high", + dev->irq); return_VALUE(dev->irq); -} - - -int __init -acpi_pci_irq_init (void) -{ - struct pci_dev *dev = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_init"); - - if (!acpi_prt.count) { - printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ " - "routing entries\n"); - return_VALUE(-ENODEV); - } - - /* Make sure all link devices have a valid IRQ. */ - if (acpi_pci_link_check()) { - return_VALUE(-ENODEV); - } - -#ifdef CONFIG_X86_IO_APIC - /* Program IOAPICs using data from PRT entries. */ - if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) - mp_parse_prt(); -#endif -#ifdef CONFIG_IOSAPIC - if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC) - iosapic_parse_prt(); -#endif - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) - acpi_pci_irq_enable(dev); - - return_VALUE(0); } diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/acpi/pci_link.c 2004-06-26 17:09:15 -07:00 @@ -308,31 +308,12 @@ struct acpi_resource end; } resource; struct acpi_buffer buffer = {sizeof(resource)+1, &resource}; - int i = 0; - int valid = 0; ACPI_FUNCTION_TRACE("acpi_pci_link_set"); if (!link || !irq) return_VALUE(-EINVAL); - /* We don't check irqs the first time around */ - if (link->irq.setonboot) { - /* See if we're already at the target IRQ. */ - if (irq == link->irq.active) - return_VALUE(0); - - /* Make sure the target IRQ in the list of possible IRQs. */ - for (i=0; iirq.possible_count; i++) { - if (irq == link->irq.possible[i]) - valid = 1; - } - if (!valid) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq)); - return_VALUE(-EINVAL); - } - } - memset(&resource, 0, sizeof(resource)); switch(link->irq.resource_type) { @@ -487,13 +468,13 @@ }; int -acpi_pci_link_check (void) +acpi_irq_penalty_init(void) { struct list_head *node = NULL; struct acpi_pci_link *link = NULL; int i = 0; - ACPI_FUNCTION_TRACE("acpi_pci_link_check"); + ACPI_FUNCTION_TRACE("acpi_irq_penalty_init"); /* * Update penalties to facilitate IRQ balancing. @@ -703,6 +684,9 @@ acpi_link.count++; end: + /* disable all links -- to be activated on use */ + acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); + if (result) kfree(link); diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c --- a/drivers/acpi/pci_root.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/acpi/pci_root.c 2004-06-26 17:09:16 -07:00 @@ -113,6 +113,40 @@ } } +static acpi_status +get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data) +{ + int *busnr = (int *)data; + struct acpi_resource_address64 address; + + if (resource->id != ACPI_RSTYPE_ADDRESS16 && + resource->id != ACPI_RSTYPE_ADDRESS32 && + resource->id != ACPI_RSTYPE_ADDRESS64) + return AE_OK; + + acpi_resource_to_address64(resource, &address); + if ((address.address_length > 0) && + (address.resource_type == ACPI_BUS_NUMBER_RANGE)) + *busnr = address.min_address_range; + + return AE_OK; +} + +static acpi_status +try_get_root_bridge_busnr(acpi_handle handle, int *busnum) +{ + acpi_status status; + + *busnum = -1; + status = acpi_walk_resources(handle, METHOD_NAME__CRS, get_root_bridge_busnr_callback, busnum); + if (ACPI_FAILURE(status)) + return status; + /* Check if we really get a bus number from _CRS */ + if (*busnum == -1) + return AE_ERROR; + return AE_OK; +} + static int acpi_pci_root_add ( struct acpi_device *device) @@ -190,9 +224,22 @@ /* Some systems have wrong _BBN */ list_for_each_entry(tmp, &acpi_pci_roots, node) { if ((tmp->id.segment == root->id.segment) - && (tmp->id.bus == root->id.bus)) + && (tmp->id.bus == root->id.bus)) { + int bus = 0; + acpi_status status; + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Wrong _BBN value, please reboot and using option 'pci=noacpi'\n")); + + status = try_get_root_bridge_busnr(root->handle, &bus); + if (ACPI_FAILURE(status)) + break; + if (bus != root->id.bus) { + printk(KERN_INFO PREFIX "PCI _CRS %d overrides _BBN 0\n", bus); + root->id.bus = bus; + } + break; + } } /* * Device & Function diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/acpi/tables.c 2004-06-26 17:09:17 -07:00 @@ -131,7 +131,7 @@ { struct acpi_table_ioapic *p = (struct acpi_table_ioapic*) header; - printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] global_irq_base[0x%x])\n", + printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", p->id, p->address, p->global_irq_base); } break; @@ -185,8 +185,8 @@ { struct acpi_table_iosapic *p = (struct acpi_table_iosapic*) header; - printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] global_irq_base[0x%x] address[%p])\n", - p->id, p->global_irq_base, (void *) (unsigned long) p->address); + printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", + p->id, (void *) (unsigned long) p->address, p->global_irq_base); } break; diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c --- a/drivers/acpi/thermal.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/acpi/thermal.c 2004-06-26 17:09:20 -07:00 @@ -289,6 +289,13 @@ status = acpi_get_handle(tz->handle, "_SCP", &handle); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); + status = acpi_get_handle(tz->handle, "_PSV", &handle); + if(!ACPI_FAILURE(status)) { + tz->cooling_mode = 1; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", + mode?"passive":"active")); + return_VALUE(0); + } return_VALUE(-ENODEV); } diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig --- a/drivers/base/Kconfig 2004-06-26 17:09:16 -07:00 +++ b/drivers/base/Kconfig 2004-06-26 17:09:16 -07:00 @@ -1,5 +1,14 @@ menu "Generic Driver Options" +config PREVENT_FIRMWARE_BUILD + bool "Prevent firmware from being built" + default y + help + Say yes to avoid building firmware. Firmware is usually shipped + with the driver, and only when updating the firware a rebuild + should be made. + If unsure say Y here. + config FW_LOADER tristate "Hotplug firmware loading support" depends on HOTPLUG diff -Nru a/drivers/base/base.h b/drivers/base/base.h --- a/drivers/base/base.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/base/base.h 2004-06-26 17:09:17 -07:00 @@ -6,12 +6,13 @@ static inline struct class_device *to_class_dev(struct kobject *obj) { - return container_of(obj,struct class_device,kobj); + return container_of(obj, struct class_device, kobj); } + static inline struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) { - return container_of(_attr,struct class_device_attribute,attr); + return container_of(_attr, struct class_device_attribute, attr); } diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c --- a/drivers/base/bus.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/base/bus.c 2004-06-26 17:09:16 -07:00 @@ -3,7 +3,7 @@ * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * + * * This file is released under the GPLv2 * */ @@ -17,17 +17,17 @@ #include "base.h" #include "power/power.h" -#define to_dev(node) container_of(node,struct device,bus_list) -#define to_drv(node) container_of(node,struct device_driver,kobj.entry) +#define to_dev(node) container_of(node, struct device, bus_list) +#define to_drv(node) container_of(node, struct device_driver, kobj.entry) -#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr) -#define to_bus(obj) container_of(obj,struct bus_type,subsys.kset.kobj) +#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) +#define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj) /* * sysfs bindings for drivers */ -#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr) +#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) #define to_driver(obj) container_of(obj, struct device_driver, kobj) @@ -39,12 +39,12 @@ ssize_t ret = 0; if (drv_attr->show) - ret = drv_attr->show(drv,buf); + ret = drv_attr->show(drv, buf); return ret; } static ssize_t -drv_attr_store(struct kobject * kobj, struct attribute * attr, +drv_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t count) { struct driver_attribute * drv_attr = to_drv_attr(attr); @@ -52,7 +52,7 @@ ssize_t ret = 0; if (drv_attr->store) - ret = drv_attr->store(drv,buf,count); + ret = drv_attr->store(drv, buf, count); return ret; } @@ -87,12 +87,12 @@ ssize_t ret = 0; if (bus_attr->show) - ret = bus_attr->show(bus,buf); + ret = bus_attr->show(bus, buf); return ret; } static ssize_t -bus_attr_store(struct kobject * kobj, struct attribute * attr, +bus_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t count) { struct bus_attribute * bus_attr = to_bus_attr(attr); @@ -100,7 +100,7 @@ ssize_t ret = 0; if (bus_attr->store) - ret = bus_attr->store(bus,buf,count); + ret = bus_attr->store(bus, buf, count); return ret; } @@ -113,7 +113,7 @@ { int error; if (get_bus(bus)) { - error = sysfs_create_file(&bus->subsys.kset.kobj,&attr->attr); + error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr); put_bus(bus); } else error = -EINVAL; @@ -123,7 +123,7 @@ void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) { if (get_bus(bus)) { - sysfs_remove_file(&bus->subsys.kset.kobj,&attr->attr); + sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr); put_bus(bus); } } @@ -133,7 +133,7 @@ }; -decl_subsys(bus,&ktype_bus,NULL); +decl_subsys(bus, &ktype_bus, NULL); /** * bus_for_each_dev - device iterator. @@ -151,10 +151,10 @@ * * NOTE: The device that returns a non-zero value is not retained * in any way, nor is its refcount incremented. If the caller needs - * to retain this data, it should do, and increment the reference + * to retain this data, it should do, and increment the reference * count in the supplied callback. */ -int bus_for_each_dev(struct bus_type * bus, struct device * start, +int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, int (*fn)(struct device *, void *)) { struct device *dev; @@ -170,7 +170,7 @@ down_read(&bus->subsys.rwsem); list_for_each_entry_continue(dev, head, bus_list) { get_device(dev); - error = fn(dev,data); + error = fn(dev, data); put_device(dev); if (error) break; @@ -193,7 +193,7 @@ * and return it. If @start is not NULL, we use it as the head * of the list. * - * NOTE: we don't return the driver that returns a non-zero + * NOTE: we don't return the driver that returns a non-zero * value, nor do we leave the reference count incremented for that * driver. If the caller needs to know that info, it must set it * in the callback. It must also be sure to increment the refcount @@ -216,7 +216,7 @@ down_read(&bus->subsys.rwsem); list_for_each_entry_continue(drv, head, kobj.entry) { get_driver(drv); - error = fn(drv,data); + error = fn(drv, data); put_driver(drv); if(error) break; @@ -233,8 +233,8 @@ * Allow manual attachment of a driver to a deivce. * Caller must have already set @dev->driver. * - * Note that this does not modify the bus reference count - * nor take the bus's rwsem. Please verify those are accounted + * Note that this does not modify the bus reference count + * nor take the bus's rwsem. Please verify those are accounted * for before calling this. (It is ok to call with no other effort * from a driver's probe() method.) */ @@ -242,9 +242,9 @@ void device_bind_driver(struct device * dev) { pr_debug("bound device '%s' to driver '%s'\n", - dev->bus_id,dev->driver->name); - list_add_tail(&dev->driver_list,&dev->driver->devices); - sysfs_create_link(&dev->driver->kobj,&dev->kobj, + dev->bus_id, dev->driver->name); + list_add_tail(&dev->driver_list, &dev->driver->devices); + sysfs_create_link(&dev->driver->kobj, &dev->kobj, kobject_name(&dev->kobj)); } @@ -255,18 +255,18 @@ * @drv: driver. * * First, we call the bus's match function, which should compare - * the device IDs the driver supports with the device IDs of the - * device. Note we don't do this ourselves because we don't know + * the device IDs the driver supports with the device IDs of the + * device. Note we don't do this ourselves because we don't know * the format of the ID structures, nor what is to be considered * a match and what is not. - * - * If we find a match, we call @drv->probe(@dev) if it exists, and + * + * If we find a match, we call @drv->probe(@dev) if it exists, and * call attach() above. */ static int bus_match(struct device * dev, struct device_driver * drv) { int error = -ENODEV; - if (dev->bus->match(dev,drv)) { + if (dev->bus->match(dev, drv)) { dev->driver = drv; if (drv->probe) { if ((error = drv->probe(dev))) { @@ -285,7 +285,7 @@ * device_attach - try to attach device to a driver. * @dev: device. * - * Walk the list of drivers that the bus has and call bus_match() + * Walk the list of drivers that the bus has and call bus_match() * for each pair. If a compatible pair is found, break out and return. */ static int device_attach(struct device * dev) @@ -300,15 +300,15 @@ } if (bus->match) { - list_for_each(entry,&bus->drivers.list) { + list_for_each(entry, &bus->drivers.list) { struct device_driver * drv = to_drv(entry); - error = bus_match(dev,drv); - if (!error ) + error = bus_match(dev, drv); + if (!error) /* success, driver matched */ - return 1; - if (error != -ENODEV) + return 1; + if (error != -ENODEV) /* driver matched but the probe failed */ - printk(KERN_WARNING + printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev->bus_id, error); } @@ -327,7 +327,7 @@ * If bus_match() returns 0 and the @dev->driver is set, we've found * a compatible pair. * - * Note that we ignore the -ENODEV error from bus_match(), since it's + * Note that we ignore the -ENODEV error from bus_match(), since it's * perfectly valid for a driver not to bind to any devices. */ void driver_attach(struct device_driver * drv) @@ -339,13 +339,13 @@ if (!bus->match) return; - list_for_each(entry,&bus->devices.list) { - struct device * dev = container_of(entry,struct device,bus_list); + list_for_each(entry, &bus->devices.list) { + struct device * dev = container_of(entry, struct device, bus_list); if (!dev->driver) { - error = bus_match(dev,drv); + error = bus_match(dev, drv); if (error && (error != -ENODEV)) /* driver matched but the probe failed */ - printk(KERN_WARNING + printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev->bus_id, error); } @@ -367,7 +367,7 @@ { struct device_driver * drv = dev->driver; if (drv) { - sysfs_remove_link(&drv->kobj,kobject_name(&dev->kobj)); + sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); list_del_init(&dev->driver_list); device_detach_shutdown(dev); if (drv->remove) @@ -385,13 +385,44 @@ static void driver_detach(struct device_driver * drv) { struct list_head * entry, * next; - list_for_each_safe(entry,next,&drv->devices) { - struct device * dev = container_of(entry,struct device,driver_list); + list_for_each_safe(entry, next, &drv->devices) { + struct device * dev = container_of(entry, struct device, driver_list); device_release_driver(dev); } +} + +static int device_add_attrs(struct bus_type * bus, struct device * dev) +{ + int error = 0; + int i; + + if (bus->dev_attrs) { + for (i = 0; attr_name(bus->dev_attrs[i]); i++) { + error = device_create_file(dev,&bus->dev_attrs[i]); + if (error) + goto Err; + } + } + Done: + return error; + Err: + while (--i >= 0) + device_remove_file(dev,&bus->dev_attrs[i]); + goto Done; +} + + +static void device_remove_attrs(struct bus_type * bus, struct device * dev) +{ + int i; + if (bus->dev_attrs) { + for (i = 0; attr_name(bus->dev_attrs[i]); i++) + device_remove_file(dev,&bus->dev_attrs[i]); + } } + /** * bus_add_device - add device to bus * @dev: device being added @@ -407,11 +438,12 @@ if (bus) { down_write(&dev->bus->subsys.rwsem); - pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id); - list_add_tail(&dev->bus_list,&dev->bus->devices.list); + pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); + list_add_tail(&dev->bus_list, &dev->bus->devices.list); device_attach(dev); up_write(&dev->bus->subsys.rwsem); - sysfs_create_link(&bus->devices.kobj,&dev->kobj,dev->bus_id); + device_add_attrs(bus, dev); + sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); } return error; } @@ -428,9 +460,10 @@ void bus_remove_device(struct device * dev) { if (dev->bus) { - sysfs_remove_link(&dev->bus->devices.kobj,dev->bus_id); + sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); + device_remove_attrs(dev->bus, dev); down_write(&dev->bus->subsys.rwsem); - pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id); + pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); list_del_init(&dev->bus_list); up_write(&dev->bus->subsys.rwsem); @@ -450,8 +483,8 @@ int error = 0; if (bus) { - pr_debug("bus %s: add driver %s\n",bus->name,drv->name); - error = kobject_set_name(&drv->kobj,drv->name); + pr_debug("bus %s: add driver %s\n", bus->name, drv->name); + error = kobject_set_name(&drv->kobj, drv->name); if (error) { put_bus(bus); return error; @@ -484,7 +517,7 @@ { if (drv->bus) { down_write(&drv->bus->subsys.rwsem); - pr_debug("bus %s: remove driver %s\n",drv->bus->name,drv->name); + pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); driver_detach(drv); up_write(&drv->bus->subsys.rwsem); kobject_unregister(&drv->kobj); @@ -526,7 +559,7 @@ struct bus_type * get_bus(struct bus_type * bus) { - return bus ? container_of(subsys_get(&bus->subsys),struct bus_type,subsys) : NULL; + return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL; } void put_bus(struct bus_type * bus) @@ -545,29 +578,64 @@ struct bus_type * find_bus(char * name) { - struct kobject * k = kset_find_obj(&bus_subsys.kset,name); + struct kobject * k = kset_find_obj(&bus_subsys.kset, name); return k ? to_bus(k) : NULL; } + +/** + * bus_add_attrs - Add default attributes for this bus. + * @bus: Bus that has just been registered. + */ + +static int bus_add_attrs(struct bus_type * bus) +{ + int error = 0; + int i; + + if (bus->bus_attrs) { + for (i = 0; attr_name(bus->bus_attrs[i]); i++) { + if ((error = bus_create_file(bus,&bus->bus_attrs[i]))) + goto Err; + } + } + Done: + return error; + Err: + while (--i >= 0) + bus_remove_file(bus,&bus->bus_attrs[i]); + goto Done; +} + +static void bus_remove_attrs(struct bus_type * bus) +{ + int i; + + if (bus->bus_attrs) { + for (i = 0; attr_name(bus->bus_attrs[i]); i++) + bus_remove_file(bus,&bus->bus_attrs[i]); + } +} + /** * bus_register - register a bus with the system. * @bus: bus. * * Once we have that, we registered the bus with the kobject * infrastructure, then register the children subsystems it has: - * the devices and drivers that belong to the bus. + * the devices and drivers that belong to the bus. */ int bus_register(struct bus_type * bus) { int retval; - retval = kobject_set_name(&bus->subsys.kset.kobj,bus->name); + retval = kobject_set_name(&bus->subsys.kset.kobj, bus->name); if (retval) goto out; - subsys_set_kset(bus,bus_subsys); + subsys_set_kset(bus, bus_subsys); retval = subsystem_register(&bus->subsys); - if (retval) + if (retval) goto out; kobject_set_name(&bus->devices.kobj, "devices"); @@ -582,8 +650,9 @@ retval = kset_register(&bus->drivers); if (retval) goto bus_drivers_fail; + bus_add_attrs(bus); - pr_debug("bus type '%s' registered\n",bus->name); + pr_debug("bus type '%s' registered\n", bus->name); return 0; bus_drivers_fail: @@ -596,7 +665,7 @@ /** - * bus_unregister - remove a bus from the system + * bus_unregister - remove a bus from the system * @bus: bus. * * Unregister the child subsystems and the bus itself. @@ -604,7 +673,8 @@ */ void bus_unregister(struct bus_type * bus) { - pr_debug("bus %s: unregistering\n",bus->name); + pr_debug("bus %s: unregistering\n", bus->name); + bus_remove_attrs(bus); kset_unregister(&bus->drivers); kset_unregister(&bus->devices); subsystem_unregister(&bus->subsys); diff -Nru a/drivers/base/class.c b/drivers/base/class.c --- a/drivers/base/class.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/base/class.c 2004-06-26 17:09:21 -07:00 @@ -5,7 +5,7 @@ * Copyright (c) 2002-3 Open Source Development Labs * Copyright (c) 2003-2004 Greg Kroah-Hartman * Copyright (c) 2003-2004 IBM Corp. - * + * * This file is released under the GPLv2 * */ @@ -17,8 +17,8 @@ #include #include "base.h" -#define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr) -#define to_class(obj) container_of(obj,struct class,subsys.kset.kobj) +#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) +#define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) static ssize_t class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) @@ -28,12 +28,12 @@ ssize_t ret = 0; if (class_attr->show) - ret = class_attr->show(dc,buf); + ret = class_attr->show(dc, buf); return ret; } static ssize_t -class_attr_store(struct kobject * kobj, struct attribute * attr, +class_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t count) { struct class_attribute * class_attr = to_class_attr(attr); @@ -41,7 +41,7 @@ ssize_t ret = 0; if (class_attr->store) - ret = class_attr->store(dc,buf,count); + ret = class_attr->store(dc, buf, count); return ret; } @@ -69,14 +69,14 @@ }; /* Hotplug events for classes go to the class_obj subsys */ -static decl_subsys(class,&ktype_class,NULL); +static decl_subsys(class, &ktype_class, NULL); int class_create_file(struct class * cls, const struct class_attribute * attr) { int error; if (cls) { - error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr); + error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr); } else error = -EINVAL; return error; @@ -85,13 +85,13 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr) { if (cls) - sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr); + sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); } struct class * class_get(struct class * cls) { if (cls) - return container_of(subsys_get(&cls->subsys),struct class,subsys); + return container_of(subsys_get(&cls->subsys), struct class, subsys); return NULL; } @@ -100,33 +100,67 @@ subsys_put(&cls->subsys); } + +static int add_class_attrs(struct class * cls) +{ + int i; + int error = 0; + + if (cls->class_attrs) { + for (i = 0; attr_name(cls->class_attrs[i]); i++) { + error = class_create_file(cls,&cls->class_attrs[i]); + if (error) + goto Err; + } + } + Done: + return error; + Err: + while (--i >= 0) + class_remove_file(cls,&cls->class_attrs[i]); + goto Done; +} + +static void remove_class_attrs(struct class * cls) +{ + int i; + + if (cls->class_attrs) { + for (i = 0; attr_name(cls->class_attrs[i]); i++) + class_remove_file(cls,&cls->class_attrs[i]); + } +} + int class_register(struct class * cls) { int error; - pr_debug("device class '%s': registering\n",cls->name); + pr_debug("device class '%s': registering\n", cls->name); INIT_LIST_HEAD(&cls->children); INIT_LIST_HEAD(&cls->interfaces); - error = kobject_set_name(&cls->subsys.kset.kobj,cls->name); + error = kobject_set_name(&cls->subsys.kset.kobj, cls->name); if (error) return error; - subsys_set_kset(cls,class_subsys); + subsys_set_kset(cls, class_subsys); error = subsystem_register(&cls->subsys); - if (error) - return error; - - return 0; + if (!error) { + error = add_class_attrs(class_get(cls)); + class_put(cls); + } + return error; } void class_unregister(struct class * cls) { - pr_debug("device class '%s': unregistering\n",cls->name); + pr_debug("device class '%s': unregistering\n", cls->name); + remove_class_attrs(cls); subsystem_unregister(&cls->subsys); } + /* Class Device Stuff */ int class_device_create_file(struct class_device * class_dev, @@ -181,12 +215,12 @@ ssize_t ret = 0; if (class_dev_attr->show) - ret = class_dev_attr->show(cd,buf); + ret = class_dev_attr->show(cd, buf); return ret; } static ssize_t -class_device_attr_store(struct kobject * kobj, struct attribute * attr, +class_device_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t count) { struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); @@ -194,7 +228,7 @@ ssize_t ret = 0; if (class_dev_attr->store) - ret = class_dev_attr->store(cd,buf,count); + ret = class_dev_attr->store(cd, buf, count); return ret; } @@ -208,7 +242,7 @@ struct class_device *cd = to_class_dev(kobj); struct class * cls = cd->class; - pr_debug("device class '%s': release.\n",cd->class_id); + pr_debug("device class '%s': release.\n", cd->class_id); if (cls->release) cls->release(cd); @@ -272,6 +306,40 @@ static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops); + +static int class_device_add_attrs(struct class_device * cd) +{ + int i; + int error = 0; + struct class * cls = cd->class; + + if (cls->class_dev_attrs) { + for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { + error = class_device_create_file(cd, + &cls->class_dev_attrs[i]); + if (error) + goto Err; + } + } + Done: + return error; + Err: + while (--i >= 0) + class_device_remove_file(cd,&cls->class_dev_attrs[i]); + goto Done; +} + +static void class_device_remove_attrs(struct class_device * cd) +{ + int i; + struct class * cls = cd->class; + + if (cls->class_dev_attrs) { + for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) + class_device_remove_file(cd,&cls->class_dev_attrs[i]); + } +} + void class_device_initialize(struct class_device *class_dev) { kobj_set_kset_s(class_dev, class_obj_subsys); @@ -311,7 +379,7 @@ class_intf->add(class_dev); up_write(&parent->subsys.rwsem); } - + class_device_add_attrs(class_dev); class_device_dev_link(class_dev); class_device_driver_link(class_dev); @@ -344,7 +412,8 @@ class_device_dev_unlink(class_dev); class_device_driver_unlink(class_dev); - + class_device_remove_attrs(class_dev); + kobject_del(&class_dev->kobj); if (parent) diff -Nru a/drivers/base/class_simple.c b/drivers/base/class_simple.c --- a/drivers/base/class_simple.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/base/class_simple.c 2004-06-26 17:09:17 -07:00 @@ -3,7 +3,7 @@ * * Copyright (c) 2003-2004 Greg Kroah-Hartman * Copyright (c) 2003-2004 IBM Corp. - * + * * This file is released under the GPLv2 * */ @@ -111,7 +111,7 @@ /** * class_simple_device_add - adds a class device to sysfs for a character driver - * @cs: pointer to the struct class_simple that this device should be registered to. + * @cs: pointer to the struct class_simple that this device should be registered to. * @dev: the dev_t for the device to be added. * @device: a pointer to a struct device that is assiociated with this class device. * @fmt: string for the class device's name @@ -146,8 +146,8 @@ s_dev->dev = dev; s_dev->class_dev.dev = device; s_dev->class_dev.class = &cs->class; - - va_start(args,fmt); + + va_start(args, fmt); vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args); va_end(args); retval = class_device_register(&s_dev->class_dev); @@ -173,10 +173,10 @@ * @cs: pointer to the struct class_simple to hold the pointer * @hotplug: function pointer to the hotplug function * - * Implement and set a hotplug function to add environment variables specific to this + * Implement and set a hotplug function to add environment variables specific to this * class on the hotplug event. */ -int class_simple_set_hotplug(struct class_simple *cs, +int class_simple_set_hotplug(struct class_simple *cs, int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size)) { if ((cs == NULL) || (IS_ERR(cs))) diff -Nru a/drivers/base/core.c b/drivers/base/core.c --- a/drivers/base/core.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/base/core.c 2004-06-26 17:09:15 -07:00 @@ -3,7 +3,7 @@ * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * + * * This file is released under the GPLv2 * */ @@ -28,8 +28,8 @@ * sysfs bindings for devices. */ -#define to_dev(obj) container_of(obj,struct device,kobj) -#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr) +#define to_dev(obj) container_of(obj, struct device, kobj) +#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) extern struct attribute * dev_default_attrs[]; @@ -41,12 +41,12 @@ ssize_t ret = 0; if (dev_attr->show) - ret = dev_attr->show(dev,buf); + ret = dev_attr->show(dev, buf); return ret; } static ssize_t -dev_attr_store(struct kobject * kobj, struct attribute * attr, +dev_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t count) { struct device_attribute * dev_attr = to_dev_attr(attr); @@ -54,7 +54,7 @@ ssize_t ret = 0; if (dev_attr->store) - ret = dev_attr->store(dev,buf,count); + ret = dev_attr->store(dev, buf, count); return ret; } @@ -153,7 +153,7 @@ { int error = 0; if (get_device(dev)) { - error = sysfs_create_file(&dev->kobj,&attr->attr); + error = sysfs_create_file(&dev->kobj, &attr->attr); put_device(dev); } return error; @@ -168,7 +168,7 @@ void device_remove_file(struct device * dev, struct device_attribute * attr) { if (get_device(dev)) { - sysfs_remove_file(&dev->kobj,&attr->attr); + sysfs_remove_file(&dev->kobj, &attr->attr); put_device(dev); } } @@ -179,7 +179,7 @@ * @dev: device. * * This prepares the device for use by other layers, - * including adding it to the device hierarchy. + * including adding it to the device hierarchy. * It is the first half of device_register(), if called by * that, though it can also be called separately, so one * may use @dev's fields (e.g. the refcount). @@ -187,7 +187,7 @@ void device_initialize(struct device *dev) { - kobj_set_kset_s(dev,devices_subsys); + kobj_set_kset_s(dev, devices_subsys); kobject_init(&dev->kobj); INIT_LIST_HEAD(&dev->node); INIT_LIST_HEAD(&dev->children); @@ -200,7 +200,7 @@ * device_add - add device to device hierarchy. * @dev: device. * - * This is part 2 of device_register(), though may be called + * This is part 2 of device_register(), though may be called * separately _iff_ device_initialize() has been called separately. * * This adds it to the kobject hierarchy via kobject_add(), adds it @@ -221,7 +221,7 @@ pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); /* first, register with generic layer. */ - kobject_set_name(&dev->kobj,dev->bus_id); + kobject_set_name(&dev->kobj, dev->bus_id); if (parent) dev->kobj.parent = &parent->kobj; @@ -233,7 +233,7 @@ goto BusError; down_write(&devices_subsys.rwsem); if (parent) - list_add_tail(&dev->node,&parent->children); + list_add_tail(&dev->node, &parent->children); up_write(&devices_subsys.rwsem); /* notify platform of device entry */ @@ -245,7 +245,7 @@ BusError: device_pm_remove(dev); PMError: - kobject_unregister(&dev->kobj); + kobject_del(&dev->kobj); Error: if (parent) put_device(parent); @@ -258,9 +258,9 @@ * @dev: pointer to the device structure * * This happens in two clean steps - initialize the device - * and add it to the system. The two steps can be called - * separately, but this is the easiest and most common. - * I.e. you should only call the two helpers separately if + * and add it to the system. The two steps can be called + * separately, but this is the easiest and most common. + * I.e. you should only call the two helpers separately if * have a clearly defined need to use and refcount the device * before it is added to the hierarchy. */ @@ -301,13 +301,13 @@ * device_del - delete device from system. * @dev: device. * - * This is the first part of the device unregistration + * This is the first part of the device unregistration * sequence. This removes the device from the lists we control - * from here, has it removed from the other driver model + * from here, has it removed from the other driver model * subsystems it was added to in device_add(), and removes it * from the kobject hierarchy. * - * NOTE: this should be called manually _iff_ device_add() was + * NOTE: this should be called manually _iff_ device_add() was * also called manually. */ @@ -340,7 +340,7 @@ * we remove it from all the subsystems with device_del(), then * we decrement the reference count via put_device(). If that * is the final reference count, the device will be cleaned up - * via device_release() above. Otherwise, the structure will + * via device_release() above. Otherwise, the structure will * stick around until the final reference to the device is dropped. */ void device_unregister(struct device * dev) @@ -358,7 +358,7 @@ * @fn: function to be called for each device. * * Iterate over @dev's child devices, and call @fn for each, - * passing it @data. + * passing it @data. * * We check the return of @fn each time. If it returns anything * other than 0, we break out and return that value. @@ -370,8 +370,8 @@ int error = 0; down_read(&devices_subsys.rwsem); - list_for_each_entry(child,&dev->children,node) { - if((error = fn(child,data))) + list_for_each_entry(child, &dev->children, node) { + if((error = fn(child, data))) break; } up_read(&devices_subsys.rwsem); diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c --- a/drivers/base/cpu.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/base/cpu.c 2004-06-26 17:09:17 -07:00 @@ -58,6 +58,8 @@ /* * register_cpu - Setup a driverfs device for a CPU. + * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to + * generate a control file in sysfs for this CPU. * @num - CPU number to use when creating the device. * * Initialize and register the CPU device. @@ -75,7 +77,7 @@ error = sysfs_create_link(&root->sysdev.kobj, &cpu->sysdev.kobj, kobject_name(&cpu->sysdev.kobj)); - if (!error) + if (!error && !cpu->no_control) register_cpu_control(cpu); return error; } diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c --- a/drivers/base/driver.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/base/driver.c 2004-06-26 17:09:20 -07:00 @@ -3,7 +3,7 @@ * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * + * * This file is released under the GPLv2 * */ @@ -15,8 +15,8 @@ #include #include "base.h" -#define to_dev(node) container_of(node,struct device,driver_list) -#define to_drv(obj) container_of(obj,struct device_driver,kobj) +#define to_dev(node) container_of(node, struct device, driver_list) +#define to_drv(obj) container_of(obj, struct device_driver, kobj) /** * driver_create_file - create sysfs file for driver. @@ -28,7 +28,7 @@ { int error; if (get_driver(drv)) { - error = sysfs_create_file(&drv->kobj,&attr->attr); + error = sysfs_create_file(&drv->kobj, &attr->attr); put_driver(drv); } else error = -EINVAL; @@ -45,7 +45,7 @@ void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) { if (get_driver(drv)) { - sysfs_remove_file(&drv->kobj,&attr->attr); + sysfs_remove_file(&drv->kobj, &attr->attr); put_driver(drv); } } @@ -76,7 +76,7 @@ * @drv: driver to register * * We pass off most of the work to the bus_add_driver() call, - * since most of the things we have to do deal with the bus + * since most of the things we have to do deal with the bus * structures. * * The one interesting aspect is that we initialize @drv->unload_sem @@ -99,8 +99,8 @@ * * Though, once that is done, we attempt to take @drv->unload_sem. * This will block until the driver refcount reaches 0, and it is - * released. Only modular drivers will call this function, and we - * have to guarantee that it won't complete, letting the driver + * released. Only modular drivers will call this function, and we + * have to guarantee that it won't complete, letting the driver * unload until all references are gone. */ diff -Nru a/drivers/base/firmware.c b/drivers/base/firmware.c --- a/drivers/base/firmware.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/base/firmware.c 2004-06-26 17:09:18 -07:00 @@ -3,7 +3,7 @@ * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * + * * This file is released under the GPLv2 * */ @@ -12,11 +12,11 @@ #include #include -static decl_subsys(firmware,NULL,NULL); +static decl_subsys(firmware, NULL, NULL); int firmware_register(struct subsystem * s) { - kset_set_kset_s(s,firmware_subsys); + kset_set_kset_s(s, firmware_subsys); return subsystem_register(s); } diff -Nru a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c --- a/drivers/base/firmware_class.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/base/firmware_class.c 2004-06-26 17:09:15 -07:00 @@ -68,7 +68,7 @@ * firmware will be provided. * * Note: zero means 'wait for ever' - * + * **/ static ssize_t firmware_timeout_store(struct class *class, const char *buf, size_t count) @@ -121,7 +121,7 @@ /** * firmware_loading_store: - loading control file * Description: - * The relevant values are: + * The relevant values are: * * 1: Start a load, discarding any previous partial load. * 0: Conclude the load and handle the data to the driver code. @@ -376,7 +376,7 @@ return retval; } -/** +/** * request_firmware: - request firmware to hotplug and wait for it * Description: * @firmware will be used to return a firmware image by the name @@ -457,7 +457,7 @@ /** * register_firmware: - provide a firmware image for later usage - * + * * Description: * Make sure that @data will be available by requesting firmware @name. * @@ -541,7 +541,7 @@ ret = kernel_thread(request_firmware_work_func, fw_work, CLONE_FS | CLONE_FILES); - + if (ret < 0) { fw_work->cont(NULL, fw_work->context); return ret; diff -Nru a/drivers/base/init.c b/drivers/base/init.c --- a/drivers/base/init.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/base/init.c 2004-06-26 17:09:15 -07:00 @@ -2,7 +2,7 @@ * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * + * * This file is released under the GPLv2 * */ @@ -33,7 +33,7 @@ classes_init(); firmware_init(); - /* These are also core pieces, but must come after the + /* These are also core pieces, but must come after the * core core pieces. */ platform_bus_init(); diff -Nru a/drivers/base/interface.c b/drivers/base/interface.c --- a/drivers/base/interface.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/base/interface.c 2004-06-26 17:09:15 -07:00 @@ -1,10 +1,10 @@ /* - * drivers/base/interface.c - common driverfs interface that's exported to + * drivers/base/interface.c - common driverfs interface that's exported to * the world for all devices. * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * + * * This file is released under the GPLv2 * */ @@ -16,33 +16,33 @@ /** * detach_state - control the default power state for the device. - * - * This is the state the device enters when it's driver module is + * + * This is the state the device enters when it's driver module is * unloaded. The value is an unsigned integer, in the range of 0-4. * '0' indicates 'On', so no action will be taken when the driver is * unloaded. This is the default behavior. * '4' indicates 'Off', meaning the driver core will call the driver's * shutdown method to quiesce the device. - * 1-3 indicate a low-power state for the device to enter via the - * driver's suspend method. + * 1-3 indicate a low-power state for the device to enter via the + * driver's suspend method. */ static ssize_t detach_show(struct device * dev, char * buf) { - return sprintf(buf,"%u\n",dev->detach_state); + return sprintf(buf, "%u\n", dev->detach_state); } static ssize_t detach_store(struct device * dev, const char * buf, size_t n) { u32 state; - state = simple_strtoul(buf,NULL,10); + state = simple_strtoul(buf, NULL, 10); if (state > 4) return -EINVAL; dev->detach_state = state; return n; } -static DEVICE_ATTR(detach_state,0644,detach_show,detach_store); +static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store); struct attribute * dev_default_attrs[] = { diff -Nru a/drivers/base/node.c b/drivers/base/node.c --- a/drivers/base/node.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/base/node.c 2004-06-26 17:09:16 -07:00 @@ -29,7 +29,7 @@ return len; } -static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL); +static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumap, NULL); /* Can be overwritten by architecture specific code. */ int __attribute__((weak)) hugetlb_report_node_meminfo(int node, char *buf) @@ -54,17 +54,17 @@ "Node %d LowFree: %8lu kB\n", nid, K(i.totalram), nid, K(i.freeram), - nid, K(i.totalram-i.freeram), + nid, K(i.totalram - i.freeram), nid, K(i.totalhigh), nid, K(i.freehigh), - nid, K(i.totalram-i.totalhigh), - nid, K(i.freeram-i.freehigh)); + nid, K(i.totalram - i.totalhigh), + nid, K(i.freeram - i.freehigh)); n += hugetlb_report_node_meminfo(nid, buf + n); return n; } -#undef K -static SYSDEV_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL); +#undef K +static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL); static ssize_t node_read_numastat(struct sys_device * dev, char * buf) { @@ -104,7 +104,7 @@ local_node, other_node); } -static SYSDEV_ATTR(numastat,S_IRUGO,node_read_numastat,NULL); +static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL); /* * register_node - Setup a driverfs device for a node. diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c --- a/drivers/base/platform.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/base/platform.c 2004-06-26 17:09:15 -07:00 @@ -3,7 +3,7 @@ * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * + * * This file is released under the GPLv2 * * Please see Documentation/driver-model/platform.txt for more @@ -19,12 +19,71 @@ }; /** + * platform_get_resource - get a resource for a device + * @dev: platform device + * @type: resource type + * @num: resource index + */ +struct resource * +platform_get_resource(struct platform_device *dev, unsigned int type, + unsigned int num) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) { + struct resource *r = &dev->resource[i]; + + if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| + IORESOURCE_IRQ|IORESOURCE_DMA)) + == type) + if (num-- == 0) + return r; + } + return NULL; +} + +/** + * platform_get_irq - get an IRQ for a device + * @dev: platform device + * @num: IRQ number index + */ +int platform_get_irq(struct platform_device *dev, unsigned int num) +{ + struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); + + return r ? r->start : 0; +} + +/** + * platform_add_devices - add a numbers of platform devices + * @devs: array of platform devices to add + * @num: number of platform devices in array + */ +int platform_add_devices(struct platform_device **devs, int num) +{ + int i, ret = 0; + + for (i = 0; i < num; i++) { + ret = platform_device_register(devs[i]); + if (ret) { + while (--i >= 0) + platform_device_unregister(devs[i]); + break; + } + } + + return ret; +} + +/** * platform_device_register - add a platform-level device * @dev: platform device we're adding * */ int platform_device_register(struct platform_device * pdev) { + int i, ret = 0; + if (!pdev) return -EINVAL; @@ -32,18 +91,59 @@ pdev->dev.parent = &platform_bus; pdev->dev.bus = &platform_bus_type; - - snprintf(pdev->dev.bus_id,BUS_ID_SIZE,"%s%u",pdev->name,pdev->id); + + if (pdev->id != -1) + snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s%u", pdev->name, pdev->id); + else + strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE); + + for (i = 0; i < pdev->num_resources; i++) { + struct resource *p, *r = &pdev->resource[i]; + + r->name = pdev->dev.bus_id; + + p = NULL; + if (r->flags & IORESOURCE_MEM) + p = &iomem_resource; + else if (r->flags & IORESOURCE_IO) + p = &ioport_resource; + + if (p && request_resource(p, r)) { + printk(KERN_ERR + "%s: failed to claim resource %d\n", + pdev->dev.bus_id, i); + ret = -EBUSY; + goto failed; + } + } pr_debug("Registering platform device '%s'. Parent at %s\n", - pdev->dev.bus_id,pdev->dev.parent->bus_id); - return device_register(&pdev->dev); + pdev->dev.bus_id, pdev->dev.parent->bus_id); + + ret = device_register(&pdev->dev); + if (ret == 0) + return ret; + + failed: + while (--i >= 0) + if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO)) + release_resource(&pdev->resource[i]); + return ret; } void platform_device_unregister(struct platform_device * pdev) { - if (pdev) + int i; + + if (pdev) { device_unregister(&pdev->dev); + + for (i = 0; i < pdev->num_resources; i++) { + struct resource *r = &pdev->resource[i]; + if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO)) + release_resource(r); + } + } } @@ -52,13 +152,13 @@ * @dev: device. * @drv: driver. * - * Platform device IDs are assumed to be encoded like this: - * "", where is a short description of the - * type of device, like "pci" or "floppy", and is the + * Platform device IDs are assumed to be encoded like this: + * "", where is a short description of the + * type of device, like "pci" or "floppy", and is the * enumerated instance of the device, like '0' or '42'. - * Driver IDs are simply "". - * So, extract the from the platform_device structure, - * and compare it against the name of the driver. Return whether + * Driver IDs are simply "". + * So, extract the from the platform_device structure, + * and compare it against the name of the driver. Return whether * they match or not. */ @@ -114,3 +214,5 @@ EXPORT_SYMBOL(platform_bus_type); EXPORT_SYMBOL(platform_device_register); EXPORT_SYMBOL(platform_device_unregister); +EXPORT_SYMBOL(platform_get_irq); +EXPORT_SYMBOL(platform_get_resource); diff -Nru a/drivers/base/power/main.c b/drivers/base/power/main.c --- a/drivers/base/power/main.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/base/power/main.c 2004-06-26 17:09:20 -07:00 @@ -12,10 +12,10 @@ * and add it to the list of power-controlled devices. sysfs entries for * controlling device power management will also be added. * - * A different set of lists than the global subsystem list are used to - * keep track of power info because we use different lists to hold - * devices based on what stage of the power management process they - * are in. The power domain dependencies may also differ from the + * A different set of lists than the global subsystem list are used to + * keep track of power info because we use different lists to hold + * devices based on what stage of the power management process they + * are in. The power domain dependencies may also differ from the * ancestral dependencies that the subsystem list maintains. */ @@ -74,10 +74,10 @@ pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); - atomic_set(&dev->power.pm_users,0); + atomic_set(&dev->power.pm_users, 0); down(&dpm_sem); - list_add_tail(&dev->power.entry,&dpm_active); - device_pm_set_parent(dev,dev->parent); + list_add_tail(&dev->power.entry, &dpm_active); + device_pm_set_parent(dev, dev->parent); if ((error = dpm_sysfs_add(dev))) list_del(&dev->power.entry); up(&dpm_sem); diff -Nru a/drivers/base/power/power.h b/drivers/base/power/power.h --- a/drivers/base/power/power.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/base/power/power.h 2004-06-26 17:09:15 -07:00 @@ -27,7 +27,7 @@ */ extern struct semaphore dpm_sem; -/* +/* * The PM lists. */ extern struct list_head dpm_active; @@ -37,12 +37,12 @@ static inline struct dev_pm_info * to_pm_info(struct list_head * entry) { - return container_of(entry,struct dev_pm_info,entry); + return container_of(entry, struct dev_pm_info, entry); } static inline struct device * to_device(struct list_head * entry) { - return container_of(to_pm_info(entry),struct device,power); + return container_of(to_pm_info(entry), struct device, power); } extern int device_pm_add(struct device *); @@ -56,7 +56,7 @@ extern void dpm_sysfs_remove(struct device *); /* - * resume.c + * resume.c */ extern void dpm_resume(void); diff -Nru a/drivers/base/power/resume.c b/drivers/base/power/resume.c --- a/drivers/base/power/resume.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/base/power/resume.c 2004-06-26 17:09:20 -07:00 @@ -39,7 +39,7 @@ if (!dev->power.prev_state) resume_device(dev); - list_add_tail(entry,&dpm_active); + list_add_tail(entry, &dpm_active); } } @@ -48,7 +48,7 @@ * device_resume - Restore state of each device in system. * * Walk the dpm_off list, remove each entry, resume the device, - * then add it to the dpm_active list. + * then add it to the dpm_active list. */ void device_resume(void) @@ -62,14 +62,14 @@ /** - * device_power_up_irq - Power on some devices. + * device_power_up_irq - Power on some devices. * - * Walk the dpm_off_irq list and power each device up. This + * Walk the dpm_off_irq list and power each device up. This * is used for devices that required they be powered down with * interrupts disabled. As devices are powered on, they are moved to * the dpm_suspended list. * - * Interrupts must be disabled when calling this. + * Interrupts must be disabled when calling this. */ void dpm_power_up(void) @@ -78,7 +78,7 @@ struct list_head * entry = dpm_off_irq.next; list_del_init(entry); resume_device(to_device(entry)); - list_add_tail(entry,&dpm_active); + list_add_tail(entry, &dpm_active); } } diff -Nru a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c --- a/drivers/base/power/runtime.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/base/power/runtime.c 2004-06-26 17:09:19 -07:00 @@ -24,9 +24,9 @@ * dpm_runtime_resume - Power one device back on. * @dev: Device. * - * Bring one device back to the on state by first powering it + * Bring one device back to the on state by first powering it * on, then restoring state. We only operate on devices that aren't - * already on. + * already on. * FIXME: We need to handle devices that are in an unknown state. */ @@ -55,7 +55,7 @@ if (dev->power.power_state) runtime_resume(dev); - if (!(error = suspend_device(dev,state))) + if (!(error = suspend_device(dev, state))) dev->power.power_state = state; Done: up(&dpm_sem); @@ -70,7 +70,7 @@ * * This is an update mechanism for drivers to notify the core * what power state a device is in. Device probing code may not - * always be able to tell, but we need accurate information to + * always be able to tell, but we need accurate information to * work reliably. */ void dpm_set_power_state(struct device * dev, u32 state) diff -Nru a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c --- a/drivers/base/power/shutdown.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/base/power/shutdown.c 2004-06-26 17:09:19 -07:00 @@ -1,9 +1,9 @@ /* * shutdown.c - power management functions for the device tree. - * + * * Copyright (c) 2002-3 Patrick Mochel * 2002-3 Open Source Development Lab - * + * * This file is released under the GPLv2 * */ @@ -14,7 +14,7 @@ #include "power.h" -#define to_dev(node) container_of(node,struct device,kobj.entry) +#define to_dev(node) container_of(node, struct device, kobj.entry) extern struct subsystem devices_subsys; @@ -29,7 +29,7 @@ dev->driver->shutdown(dev); return 0; } - return dpm_runtime_suspend(dev,dev->detach_state); + return dpm_runtime_suspend(dev, dev->detach_state); } @@ -38,8 +38,8 @@ * down last and resume them first. That way, we don't do anything stupid like * shutting down the interrupt controller before any devices.. * - * Note that there are not different stages for power management calls - - * they only get one called once when interrupts are disabled. + * Note that there are not different stages for power management calls - + * they only get one called once when interrupts are disabled. */ extern int sysdev_shutdown(void); @@ -50,10 +50,10 @@ void device_shutdown(void) { struct device * dev; - + down_write(&devices_subsys.rwsem); - list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) { - pr_debug("shutting down %s: ",dev->bus_id); + list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) { + pr_debug("shutting down %s: ", dev->bus_id); if (dev->driver && dev->driver->shutdown) { pr_debug("Ok\n"); dev->driver->shutdown(dev); diff -Nru a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c --- a/drivers/base/power/suspend.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/base/power/suspend.c 2004-06-26 17:09:20 -07:00 @@ -1,5 +1,5 @@ /* - * suspend.c - Functions for putting devices to sleep. + * suspend.c - Functions for putting devices to sleep. * * Copyright (c) 2003 Patrick Mochel * Copyright (c) 2003 Open Source Development Labs @@ -10,18 +10,18 @@ #include #include "power.h" - + extern int sysdev_suspend(u32 state); /* * The entries in the dpm_active list are in a depth first order, simply - * because children are guaranteed to be discovered after parents, and - * are inserted at the back of the list on discovery. - * + * because children are guaranteed to be discovered after parents, and + * are inserted at the back of the list on discovery. + * * All list on the suspend path are done in reverse order, so we operate * on the leaves of the device tree (or forests, depending on how you want - * to look at it ;) first. As nodes are removed from the back of the list, - * they are inserted into the front of their destintation lists. + * to look at it ;) first. As nodes are removed from the back of the list, + * they are inserted into the front of their destintation lists. * * Things are the reverse on the resume path - iterations are done in * forward order, and nodes are inserted at the back of their destination @@ -44,7 +44,7 @@ dev->power.prev_state = dev->power.power_state; if (dev->bus && dev->bus->suspend && !dev->power.power_state) - error = dev->bus->suspend(dev,state); + error = dev->bus->suspend(dev, state); return error; } @@ -52,16 +52,16 @@ /** * device_suspend - Save state and stop all devices in system. - * @state: Power state to put each device in. + * @state: Power state to put each device in. * * Walk the dpm_active list, call ->suspend() for each device, and move - * it to dpm_off. + * it to dpm_off. * Check the return value for each. If it returns 0, then we move the - * the device to the dpm_off list. If it returns -EAGAIN, we move it to - * the dpm_off_irq list. If we get a different error, try and back out. + * the device to the dpm_off list. If it returns -EAGAIN, we move it to + * the dpm_off_irq list. If we get a different error, try and back out. * * If we hit a failure with any of the devices, call device_resume() - * above to bring the suspended devices back to life. + * above to bring the suspended devices back to life. * * Note this function leaves dpm_sem held to * a) block other devices from registering. @@ -78,14 +78,14 @@ while(!list_empty(&dpm_active)) { struct list_head * entry = dpm_active.prev; struct device * dev = to_device(entry); - error = suspend_device(dev,state); + error = suspend_device(dev, state); if (!error) { list_del(&dev->power.entry); - list_add(&dev->power.entry,&dpm_off); + list_add(&dev->power.entry, &dpm_off); } else if (error == -EAGAIN) { list_del(&dev->power.entry); - list_add(&dev->power.entry,&dpm_off_irq); + list_add(&dev->power.entry, &dpm_off_irq); } else { printk(KERN_ERR "Could not suspend device %s: " "error %d\n", kobject_name(&dev->kobj), error); @@ -108,8 +108,8 @@ * @state: Power state to enter. * * Walk the dpm_off_irq list, calling ->power_down() for each device that - * couldn't power down the device with interrupts enabled. When we're - * done, power down system devices. + * couldn't power down the device with interrupts enabled. When we're + * done, power down system devices. */ int device_power_down(u32 state) @@ -117,10 +117,10 @@ int error = 0; struct device * dev; - list_for_each_entry_reverse(dev,&dpm_off_irq,power.entry) { - if ((error = suspend_device(dev,state))) + list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) { + if ((error = suspend_device(dev, state))) break; - } + } if (error) goto Error; if ((error = sysdev_suspend(state))) diff -Nru a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c --- a/drivers/base/power/sysfs.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/base/power/sysfs.c 2004-06-26 17:09:21 -07:00 @@ -11,10 +11,10 @@ * * show() returns the current power state of the device. '0' indicates * the device is on. Other values (1-3) indicate the device is in a low - * power state. + * power state. * - * store() sets the current power state, which is an integer value - * between 0-3. If the device is on ('0'), and the value written is + * store() sets the current power state, which is an integer value + * between 0-3. If the device is on ('0'), and the value written is * greater than 0, then the device is placed directly into the low-power * state (via its driver's ->suspend() method). * If the device is currently in a low-power state, and the value is 0, @@ -26,7 +26,7 @@ static ssize_t state_show(struct device * dev, char * buf) { - return sprintf(buf,"%u\n",dev->power.power_state); + return sprintf(buf, "%u\n", dev->power.power_state); } static ssize_t state_store(struct device * dev, const char * buf, size_t n) @@ -35,17 +35,17 @@ char * rest; int error = 0; - state = simple_strtoul(buf,&rest,10); + state = simple_strtoul(buf, &rest, 10); if (*rest) return -EINVAL; if (state) - error = dpm_runtime_suspend(dev,state); + error = dpm_runtime_suspend(dev, state); else dpm_runtime_resume(dev); return error ? error : n; } -static DEVICE_ATTR(state,0644,state_show,state_store); +static DEVICE_ATTR(state, 0644, state_show, state_store); static struct attribute * power_attrs[] = { @@ -59,10 +59,10 @@ int dpm_sysfs_add(struct device * dev) { - return sysfs_create_group(&dev->kobj,&pm_attr_group); + return sysfs_create_group(&dev->kobj, &pm_attr_group); } void dpm_sysfs_remove(struct device * dev) { - sysfs_remove_group(&dev->kobj,&pm_attr_group); + sysfs_remove_group(&dev->kobj, &pm_attr_group); } diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c --- a/drivers/base/sys.c 2004-06-26 17:09:14 -07:00 +++ b/drivers/base/sys.c 2004-06-26 17:09:14 -07:00 @@ -5,8 +5,8 @@ * 2002-3 Open Source Development Lab * * This file is released under the GPLv2 - * - * This exports a 'system' bus type. + * + * This exports a 'system' bus type. * By default, a 'sys' bus gets added to the root of the system. There will * always be core system devices. Devices can use sysdev_register() to * add themselves as children of the system bus. @@ -24,31 +24,31 @@ extern struct subsystem devices_subsys; -#define to_sysdev(k) container_of(k,struct sys_device,kobj) -#define to_sysdev_attr(a) container_of(a,struct sysdev_attribute,attr) +#define to_sysdev(k) container_of(k, struct sys_device, kobj) +#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) -static ssize_t +static ssize_t sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) { struct sys_device * sysdev = to_sysdev(kobj); struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); if (sysdev_attr->show) - return sysdev_attr->show(sysdev,buffer); + return sysdev_attr->show(sysdev, buffer); return 0; } static ssize_t -sysdev_store(struct kobject * kobj, struct attribute * attr, +sysdev_store(struct kobject * kobj, struct attribute * attr, const char * buffer, size_t count) { struct sys_device * sysdev = to_sysdev(kobj); struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); if (sysdev_attr->store) - return sysdev_attr->store(sysdev,buffer,count); + return sysdev_attr->store(sysdev, buffer, count); return 0; } @@ -64,22 +64,22 @@ int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a) { - return sysfs_create_file(&s->kobj,&a->attr); + return sysfs_create_file(&s->kobj, &a->attr); } void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a) { - sysfs_remove_file(&s->kobj,&a->attr); + sysfs_remove_file(&s->kobj, &a->attr); } EXPORT_SYMBOL(sysdev_create_file); EXPORT_SYMBOL(sysdev_remove_file); -/* - * declare system_subsys +/* + * declare system_subsys */ -decl_subsys(system,&ktype_sysdev,NULL); +decl_subsys(system, &ktype_sysdev, NULL); int sysdev_class_register(struct sysdev_class * cls) { @@ -87,7 +87,7 @@ kobject_name(&cls->kset.kobj)); INIT_LIST_HEAD(&cls->drivers); cls->kset.subsys = &system_subsys; - kset_set_kset_s(cls,system_subsys); + kset_set_kset_s(cls, system_subsys); return kset_register(&cls->kset); } @@ -109,19 +109,19 @@ * @cls: Device class driver belongs to. * @drv: Driver. * - * If @cls is valid, then @drv is inserted into @cls->drivers to be + * If @cls is valid, then @drv is inserted into @cls->drivers to be * called on each operation on devices of that class. The refcount - * of @cls is incremented. - * Otherwise, @drv is inserted into global_drivers, and called for + * of @cls is incremented. + * Otherwise, @drv is inserted into global_drivers, and called for * each device. */ -int sysdev_driver_register(struct sysdev_class * cls, +int sysdev_driver_register(struct sysdev_class * cls, struct sysdev_driver * drv) { down_write(&system_subsys.rwsem); if (cls && kset_get(&cls->kset)) { - list_add_tail(&drv->entry,&cls->drivers); + list_add_tail(&drv->entry, &cls->drivers); /* If devices of this class already exist, tell the driver */ if (drv->add) { @@ -130,7 +130,7 @@ drv->add(dev); } } else - list_add_tail(&drv->entry,&global_drivers); + list_add_tail(&drv->entry, &global_drivers); up_write(&system_subsys.rwsem); return 0; } @@ -180,12 +180,12 @@ /* But make sure we point to the right type for sysfs translation */ sysdev->kobj.ktype = &ktype_sysdev; - error = kobject_set_name(&sysdev->kobj,"%s%d", - kobject_name(&cls->kset.kobj),sysdev->id); + error = kobject_set_name(&sysdev->kobj, "%s%d", + kobject_name(&cls->kset.kobj), sysdev->id); if (error) return error; - pr_debug("Registering sys device '%s'\n",kobject_name(&sysdev->kobj)); + pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); /* Register the object */ error = kobject_register(&sysdev->kobj); @@ -194,18 +194,18 @@ struct sysdev_driver * drv; down_write(&system_subsys.rwsem); - /* Generic notification is implicit, because it's that - * code that should have called us. + /* Generic notification is implicit, because it's that + * code that should have called us. */ /* Notify global drivers */ - list_for_each_entry(drv,&global_drivers,entry) { + list_for_each_entry(drv, &global_drivers, entry) { if (drv->add) drv->add(sysdev); } /* Notify class auxillary drivers */ - list_for_each_entry(drv,&cls->drivers,entry) { + list_for_each_entry(drv, &cls->drivers, entry) { if (drv->add) drv->add(sysdev); } @@ -219,12 +219,12 @@ struct sysdev_driver * drv; down_write(&system_subsys.rwsem); - list_for_each_entry(drv,&global_drivers,entry) { + list_for_each_entry(drv, &global_drivers, entry) { if (drv->remove) drv->remove(sysdev); } - list_for_each_entry(drv,&sysdev->cls->drivers,entry) { + list_for_each_entry(drv, &sysdev->cls->drivers, entry) { if (drv->remove) drv->remove(sysdev); } @@ -241,12 +241,12 @@ * Loop over each class of system devices, and the devices in each * of those classes. For each device, we call the shutdown method for * each driver registered for the device - the globals, the auxillaries, - * and the class driver. + * and the class driver. * * Note: The list is iterated in reverse order, so that we shut down * child devices before we shut down thier parents. The list ordering * is guaranteed by virtue of the fact that child devices are registered - * after their parents. + * after their parents. */ void sysdev_shutdown(void) @@ -256,25 +256,25 @@ pr_debug("Shutting Down System Devices\n"); down_write(&system_subsys.rwsem); - list_for_each_entry_reverse(cls,&system_subsys.kset.list, + list_for_each_entry_reverse(cls, &system_subsys.kset.list, kset.kobj.entry) { struct sys_device * sysdev; pr_debug("Shutting down type '%s':\n", kobject_name(&cls->kset.kobj)); - list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) { + list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { struct sysdev_driver * drv; - pr_debug(" %s\n",kobject_name(&sysdev->kobj)); + pr_debug(" %s\n", kobject_name(&sysdev->kobj)); /* Call global drivers first. */ - list_for_each_entry(drv,&global_drivers,entry) { + list_for_each_entry(drv, &global_drivers, entry) { if (drv->shutdown) drv->shutdown(sysdev); } /* Call auxillary drivers next. */ - list_for_each_entry(drv,&cls->drivers,entry) { + list_for_each_entry(drv, &cls->drivers, entry) { if (drv->shutdown) drv->shutdown(sysdev); } @@ -295,7 +295,7 @@ * We perform an almost identical operation as sys_device_shutdown() * above, though calling ->suspend() instead. Interrupts are disabled * when this called. Devices are responsible for both saving state and - * quiescing or powering down the device. + * quiescing or powering down the device. * * This is only called by the device PM core, so we let them handle * all synchronization. @@ -307,32 +307,32 @@ pr_debug("Suspending System Devices\n"); - list_for_each_entry_reverse(cls,&system_subsys.kset.list, + list_for_each_entry_reverse(cls, &system_subsys.kset.list, kset.kobj.entry) { struct sys_device * sysdev; pr_debug("Suspending type '%s':\n", kobject_name(&cls->kset.kobj)); - list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) { + list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { struct sysdev_driver * drv; - pr_debug(" %s\n",kobject_name(&sysdev->kobj)); + pr_debug(" %s\n", kobject_name(&sysdev->kobj)); /* Call global drivers first. */ - list_for_each_entry(drv,&global_drivers,entry) { + list_for_each_entry(drv, &global_drivers, entry) { if (drv->suspend) - drv->suspend(sysdev,state); + drv->suspend(sysdev, state); } /* Call auxillary drivers next. */ - list_for_each_entry(drv,&cls->drivers,entry) { + list_for_each_entry(drv, &cls->drivers, entry) { if (drv->suspend) - drv->suspend(sysdev,state); + drv->suspend(sysdev, state); } /* Now call the generic one */ if (cls->suspend) - cls->suspend(sysdev,state); + cls->suspend(sysdev, state); } } return 0; @@ -345,7 +345,7 @@ * Similar to sys_device_suspend(), but we iterate the list forwards * to guarantee that parent devices are resumed before their children. * - * Note: Interrupts are disabled when called. + * Note: Interrupts are disabled when called. */ int sysdev_resume(void) @@ -354,28 +354,28 @@ pr_debug("Resuming System Devices\n"); - list_for_each_entry(cls,&system_subsys.kset.list,kset.kobj.entry) { + list_for_each_entry(cls, &system_subsys.kset.list, kset.kobj.entry) { struct sys_device * sysdev; pr_debug("Resuming type '%s':\n", kobject_name(&cls->kset.kobj)); - list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) { + list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { struct sysdev_driver * drv; - pr_debug(" %s\n",kobject_name(&sysdev->kobj)); + pr_debug(" %s\n", kobject_name(&sysdev->kobj)); /* First, call the class-specific one */ if (cls->resume) cls->resume(sysdev); /* Call auxillary drivers next. */ - list_for_each_entry(drv,&cls->drivers,entry) { + list_for_each_entry(drv, &cls->drivers, entry) { if (drv->resume) drv->resume(sysdev); } /* Call global drivers. */ - list_for_each_entry(drv,&global_drivers,entry) { + list_for_each_entry(drv, &global_drivers, entry) { if (drv->resume) drv->resume(sysdev); } diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig --- a/drivers/block/Kconfig 2004-06-26 17:09:16 -07:00 +++ b/drivers/block/Kconfig 2004-06-26 17:09:16 -07:00 @@ -6,7 +6,7 @@ config BLK_DEV_FD tristate "Normal floppy disk support" - depends on (!X86_PC9800 && !ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN) + depends on (!ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN) ---help--- If you want to use the floppy disk drive(s) of your PC under Linux, say Y. Information about this driver, especially important for IBM @@ -26,13 +26,6 @@ tristate "Atari floppy support" depends on ATARI -config BLK_DEV_FD98 - tristate "NEC PC-9800 floppy disk support" - depends on X86_PC9800 - ---help--- - If you want to use the floppy disk drive(s) of NEC PC-9801/PC-9821, - say Y. - config BLK_DEV_SWIM_IOP bool "Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)" depends on MAC && EXPERIMENTAL && BROKEN @@ -292,14 +285,14 @@ If unsure, say N. -config BLK_DEV_CARMEL - tristate "Promise SATA SX8 (carmel) support" +config BLK_DEV_SX8 + tristate "Promise SATA SX8 support" depends on PCI ---help--- Saying Y or M here will enable support for the - Promise SATA SX8 ("carmel") controllers. + Promise SATA SX8 controllers. - Use devices /dev/carmel/$N and /dev/carmel/$Np$M. + Use devices /dev/sx8/$N and /dev/sx8/$Np$M. config BLK_DEV_RAM tristate "RAM disk support" diff -Nru a/drivers/block/Makefile b/drivers/block/Makefile --- a/drivers/block/Makefile 2004-06-26 17:09:20 -07:00 +++ b/drivers/block/Makefile 2004-06-26 17:09:20 -07:00 @@ -41,5 +41,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o obj-$(CONFIG_VIODASD) += viodasd.o -obj-$(CONFIG_BLK_DEV_CARMEL) += carmel.o +obj-$(CONFIG_BLK_DEV_SX8) += sx8.o diff -Nru a/drivers/block/carmel.c b/drivers/block/carmel.c --- a/drivers/block/carmel.c 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,1763 +0,0 @@ -/* - * carmel.c: Driver for Promise SATA SX8 looks-like-I2O hardware - * - * Copyright 2004 Red Hat, Inc. - * - * Author/maintainer: Jeff Garzik - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Jeff Garzik"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Promise SATA SX8 (carmel) block driver"); - -#if 0 -#define CARM_DEBUG -#define CARM_VERBOSE_DEBUG -#else -#undef CARM_DEBUG -#undef CARM_VERBOSE_DEBUG -#endif -#undef CARM_NDEBUG - -#define DRV_NAME "carmel" -#define DRV_VERSION "0.8" -#define PFX DRV_NAME ": " - -#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN) - -/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */ -#define TAG_ENCODE(tag) (((tag) << 16) | 0xf) -#define TAG_DECODE(tag) (((tag) >> 16) & 0x1f) -#define TAG_VALID(tag) ((((tag) & 0xf) == 0xf) && (TAG_DECODE(tag) < 32)) - -/* note: prints function name for you */ -#ifdef CARM_DEBUG -#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) -#ifdef CARM_VERBOSE_DEBUG -#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) -#else -#define VPRINTK(fmt, args...) -#endif /* CARM_VERBOSE_DEBUG */ -#else -#define DPRINTK(fmt, args...) -#define VPRINTK(fmt, args...) -#endif /* CARM_DEBUG */ - -#ifdef CARM_NDEBUG -#define assert(expr) -#else -#define assert(expr) \ - if(unlikely(!(expr))) { \ - printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr,__FILE__,__FUNCTION__,__LINE__); \ - } -#endif - -/* defines only for the constants which don't work well as enums */ -struct carm_host; - -enum { - /* adapter-wide limits */ - CARM_MAX_PORTS = 8, - CARM_SHM_SIZE = (4096 << 7), - CARM_MINORS_PER_MAJOR = 256 / CARM_MAX_PORTS, - CARM_MAX_WAIT_Q = CARM_MAX_PORTS + 1, - - /* command message queue limits */ - CARM_MAX_REQ = 64, /* max command msgs per host */ - CARM_MAX_Q = 1, /* one command at a time */ - CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */ - - /* S/G limits, host-wide and per-request */ - CARM_MAX_REQ_SG = 32, /* max s/g entries per request */ - CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */ - CARM_MAX_HOST_SG = 600, /* max s/g entries per host */ - CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */ - - /* hardware registers */ - CARM_IHQP = 0x1c, - CARM_INT_STAT = 0x10, /* interrupt status */ - CARM_INT_MASK = 0x14, /* interrupt mask */ - CARM_HMUC = 0x18, /* host message unit control */ - RBUF_ADDR_LO = 0x20, /* response msg DMA buf low 32 bits */ - RBUF_ADDR_HI = 0x24, /* response msg DMA buf high 32 bits */ - RBUF_BYTE_SZ = 0x28, - CARM_RESP_IDX = 0x2c, - CARM_CMS0 = 0x30, /* command message size reg 0 */ - CARM_LMUC = 0x48, - CARM_HMPHA = 0x6c, - CARM_INITC = 0xb5, - - /* bits in CARM_INT_{STAT,MASK} */ - INT_RESERVED = 0xfffffff0, - INT_WATCHDOG = (1 << 3), /* watchdog timer */ - INT_Q_OVERFLOW = (1 << 2), /* cmd msg q overflow */ - INT_Q_AVAILABLE = (1 << 1), /* cmd msg q has free space */ - INT_RESPONSE = (1 << 0), /* response msg available */ - INT_ACK_MASK = INT_WATCHDOG | INT_Q_OVERFLOW, - INT_DEF_MASK = INT_RESERVED | INT_Q_OVERFLOW | - INT_RESPONSE, - - /* command messages, and related register bits */ - CARM_HAVE_RESP = 0x01, - CARM_MSG_READ = 1, - CARM_MSG_WRITE = 2, - CARM_MSG_VERIFY = 3, - CARM_MSG_GET_CAPACITY = 4, - CARM_MSG_FLUSH = 5, - CARM_MSG_IOCTL = 6, - CARM_MSG_ARRAY = 8, - CARM_MSG_MISC = 9, - CARM_CME = (1 << 2), - CARM_RME = (1 << 1), - CARM_WZBC = (1 << 0), - CARM_RMI = (1 << 0), - CARM_Q_FULL = (1 << 3), - CARM_MSG_SIZE = 288, - CARM_Q_LEN = 48, - - /* CARM_MSG_IOCTL messages */ - CARM_IOC_SCAN_CHAN = 5, /* scan channels for devices */ - CARM_IOC_GET_TCQ = 13, /* get tcq/ncq depth */ - CARM_IOC_SET_TCQ = 14, /* set tcq/ncq depth */ - - IOC_SCAN_CHAN_NODEV = 0x1f, - IOC_SCAN_CHAN_OFFSET = 0x40, - - /* CARM_MSG_ARRAY messages */ - CARM_ARRAY_INFO = 0, - - ARRAY_NO_EXIST = (1 << 31), - - /* response messages */ - RMSG_SZ = 8, /* sizeof(struct carm_response) */ - RMSG_Q_LEN = 48, /* resp. msg list length */ - RMSG_OK = 1, /* bit indicating msg was successful */ - /* length of entire resp. msg buffer */ - RBUF_LEN = RMSG_SZ * RMSG_Q_LEN, - - PDC_SHM_SIZE = (4096 << 7), /* length of entire h/w buffer */ - - /* CARM_MSG_MISC messages */ - MISC_GET_FW_VER = 2, - MISC_ALLOC_MEM = 3, - MISC_SET_TIME = 5, - - /* MISC_GET_FW_VER feature bits */ - FW_VER_4PORT = (1 << 2), /* 1=4 ports, 0=8 ports */ - FW_VER_NON_RAID = (1 << 1), /* 1=non-RAID firmware, 0=RAID */ - FW_VER_ZCR = (1 << 0), /* zero channel RAID (whatever that is) */ - - /* carm_host flags */ - FL_NON_RAID = FW_VER_NON_RAID, - FL_4PORT = FW_VER_4PORT, - FL_FW_VER_MASK = (FW_VER_NON_RAID | FW_VER_4PORT), - FL_DAC = (1 << 16), - FL_DYN_MAJOR = (1 << 17), -}; - -enum scatter_gather_types { - SGT_32BIT = 0, - SGT_64BIT = 1, -}; - -enum host_states { - HST_INVALID, /* invalid state; never used */ - HST_ALLOC_BUF, /* setting up master SHM area */ - HST_ERROR, /* we never leave here */ - HST_PORT_SCAN, /* start dev scan */ - HST_DEV_SCAN_START, /* start per-device probe */ - HST_DEV_SCAN, /* continue per-device probe */ - HST_DEV_ACTIVATE, /* activate devices we found */ - HST_PROBE_FINISHED, /* probe is complete */ - HST_PROBE_START, /* initiate probe */ - HST_SYNC_TIME, /* tell firmware what time it is */ - HST_GET_FW_VER, /* get firmware version, adapter port cnt */ -}; - -#ifdef CARM_DEBUG -static const char *state_name[] = { - "HST_INVALID", - "HST_ALLOC_BUF", - "HST_ERROR", - "HST_PORT_SCAN", - "HST_DEV_SCAN_START", - "HST_DEV_SCAN", - "HST_DEV_ACTIVATE", - "HST_PROBE_FINISHED", - "HST_PROBE_START", - "HST_SYNC_TIME", - "HST_GET_FW_VER", -}; -#endif - -struct carm_port { - unsigned int port_no; - unsigned int n_queued; - struct gendisk *disk; - struct carm_host *host; - - /* attached device characteristics */ - u64 capacity; - char name[41]; - u16 dev_geom_head; - u16 dev_geom_sect; - u16 dev_geom_cyl; -}; - -struct carm_request { - unsigned int tag; - int n_elem; - unsigned int msg_type; - unsigned int msg_subtype; - unsigned int msg_bucket; - struct request *rq; - struct carm_port *port; - struct scatterlist sg[CARM_MAX_REQ_SG]; -}; - -struct carm_host { - unsigned long flags; - void *mmio; - void *shm; - dma_addr_t shm_dma; - - int major; - int id; - char name[32]; - - spinlock_t lock; - struct pci_dev *pdev; - unsigned int state; - u32 fw_ver; - - request_queue_t *oob_q; - unsigned int n_oob; - - unsigned int hw_sg_used; - - unsigned int resp_idx; - - unsigned int wait_q_prod; - unsigned int wait_q_cons; - request_queue_t *wait_q[CARM_MAX_WAIT_Q]; - - unsigned int n_msgs; - u64 msg_alloc; - struct carm_request req[CARM_MAX_REQ]; - void *msg_base; - dma_addr_t msg_dma; - - int cur_scan_dev; - unsigned long dev_active; - unsigned long dev_present; - struct carm_port port[CARM_MAX_PORTS]; - - struct work_struct fsm_task; - - struct semaphore probe_sem; -}; - -struct carm_response { - u32 ret_handle; - u32 status; -} __attribute__((packed)); - -struct carm_msg_sg { - u32 start; - u32 len; -} __attribute__((packed)); - -struct carm_msg_rw { - u8 type; - u8 id; - u8 sg_count; - u8 sg_type; - u32 handle; - u32 lba; - u16 lba_count; - u16 lba_high; - struct carm_msg_sg sg[32]; -} __attribute__((packed)); - -struct carm_msg_allocbuf { - u8 type; - u8 subtype; - u8 n_sg; - u8 sg_type; - u32 handle; - u32 addr; - u32 len; - u32 evt_pool; - u32 n_evt; - u32 rbuf_pool; - u32 n_rbuf; - u32 msg_pool; - u32 n_msg; - struct carm_msg_sg sg[8]; -} __attribute__((packed)); - -struct carm_msg_ioctl { - u8 type; - u8 subtype; - u8 array_id; - u8 reserved1; - u32 handle; - u32 data_addr; - u32 reserved2; -} __attribute__((packed)); - -struct carm_msg_sync_time { - u8 type; - u8 subtype; - u16 reserved1; - u32 handle; - u32 reserved2; - u32 timestamp; -} __attribute__((packed)); - -struct carm_msg_get_fw_ver { - u8 type; - u8 subtype; - u16 reserved1; - u32 handle; - u32 data_addr; - u32 reserved2; -} __attribute__((packed)); - -struct carm_fw_ver { - u32 version; - u8 features; - u8 reserved1; - u16 reserved2; -} __attribute__((packed)); - -struct carm_array_info { - u32 size; - - u16 size_hi; - u16 stripe_size; - - u32 mode; - - u16 stripe_blk_sz; - u16 reserved1; - - u16 cyl; - u16 head; - - u16 sect; - u8 array_id; - u8 reserved2; - - char name[40]; - - u32 array_status; - - /* device list continues beyond this point? */ -} __attribute__((packed)); - -static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static void carm_remove_one (struct pci_dev *pdev); -static int carm_bdev_ioctl(struct inode *ino, struct file *fil, - unsigned int cmd, unsigned long arg); - -static struct pci_device_id carm_pci_tbl[] = { - { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, - { PCI_VENDOR_ID_PROMISE, 0x8002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, - { } /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, carm_pci_tbl); - -static struct pci_driver carm_driver = { - .name = DRV_NAME, - .id_table = carm_pci_tbl, - .probe = carm_init_one, - .remove = carm_remove_one, -}; - -static struct block_device_operations carm_bd_ops = { - .owner = THIS_MODULE, - .ioctl = carm_bdev_ioctl, -}; - -static unsigned int carm_host_id; -static unsigned long carm_major_alloc; - - - -static int carm_bdev_ioctl(struct inode *ino, struct file *fil, - unsigned int cmd, unsigned long arg) -{ - void __user *usermem = (void __user *) arg; - struct carm_port *port = ino->i_bdev->bd_disk->private_data; - struct hd_geometry geom; - - switch (cmd) { - case HDIO_GETGEO: - if (!usermem) - return -EINVAL; - - geom.heads = (u8) port->dev_geom_head; - geom.sectors = (u8) port->dev_geom_sect; - geom.cylinders = port->dev_geom_cyl; - geom.start = get_start_sect(ino->i_bdev); - - if (copy_to_user(usermem, &geom, sizeof(geom))) - return -EFAULT; - return 0; - - default: - break; - } - - return -EOPNOTSUPP; -} - -static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE }; - -static inline int carm_lookup_bucket(u32 msg_size) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) - if (msg_size <= msg_sizes[i]) - return i; - - return -ENOENT; -} - -static void carm_init_buckets(void *mmio) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) - writel(msg_sizes[i], mmio + CARM_CMS0 + (4 * i)); -} - -static inline void *carm_ref_msg(struct carm_host *host, - unsigned int msg_idx) -{ - return host->msg_base + (msg_idx * CARM_MSG_SIZE); -} - -static inline dma_addr_t carm_ref_msg_dma(struct carm_host *host, - unsigned int msg_idx) -{ - return host->msg_dma + (msg_idx * CARM_MSG_SIZE); -} - -static int carm_send_msg(struct carm_host *host, - struct carm_request *crq) -{ - void *mmio = host->mmio; - u32 msg = (u32) carm_ref_msg_dma(host, crq->tag); - u32 cm_bucket = crq->msg_bucket; - u32 tmp; - int rc = 0; - - VPRINTK("ENTER\n"); - - tmp = readl(mmio + CARM_HMUC); - if (tmp & CARM_Q_FULL) { -#if 0 - tmp = readl(mmio + CARM_INT_MASK); - tmp |= INT_Q_AVAILABLE; - writel(tmp, mmio + CARM_INT_MASK); - readl(mmio + CARM_INT_MASK); /* flush */ -#endif - DPRINTK("host msg queue full\n"); - rc = -EBUSY; - } else { - writel(msg | (cm_bucket << 1), mmio + CARM_IHQP); - readl(mmio + CARM_IHQP); /* flush */ - } - - return rc; -} - -static struct carm_request *carm_get_request(struct carm_host *host) -{ - unsigned int i; - - /* obey global hardware limit on S/G entries */ - if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG)) - return NULL; - - for (i = 0; i < CARM_MAX_Q; i++) - if ((host->msg_alloc & (1ULL << i)) == 0) { - struct carm_request *crq = &host->req[i]; - crq->port = NULL; - crq->n_elem = 0; - - host->msg_alloc |= (1ULL << i); - host->n_msgs++; - - assert(host->n_msgs <= CARM_MAX_REQ); - return crq; - } - - DPRINTK("no request available, returning NULL\n"); - return NULL; -} - -static int carm_put_request(struct carm_host *host, struct carm_request *crq) -{ - assert(crq->tag < CARM_MAX_Q); - - if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0)) - return -EINVAL; /* tried to clear a tag that was not active */ - - assert(host->hw_sg_used >= crq->n_elem); - - host->msg_alloc &= ~(1ULL << crq->tag); - host->hw_sg_used -= crq->n_elem; - host->n_msgs--; - - return 0; -} - -static struct carm_request *carm_get_special(struct carm_host *host) -{ - unsigned long flags; - struct carm_request *crq = NULL; - struct request *rq; - int tries = 5000; - - while (tries-- > 0) { - spin_lock_irqsave(&host->lock, flags); - crq = carm_get_request(host); - spin_unlock_irqrestore(&host->lock, flags); - - if (crq) - break; - msleep(10); - } - - if (!crq) - return NULL; - - rq = blk_get_request(host->oob_q, WRITE /* bogus */, GFP_KERNEL); - if (!rq) { - spin_lock_irqsave(&host->lock, flags); - carm_put_request(host, crq); - spin_unlock_irqrestore(&host->lock, flags); - return NULL; - } - - crq->rq = rq; - return crq; -} - -static int carm_array_info (struct carm_host *host, unsigned int array_idx) -{ - struct carm_msg_ioctl *ioc; - unsigned int idx; - u32 msg_data; - dma_addr_t msg_dma; - struct carm_request *crq; - int rc; - - crq = carm_get_special(host); - if (!crq) { - rc = -ENOMEM; - goto err_out; - } - - idx = crq->tag; - - ioc = carm_ref_msg(host, idx); - msg_dma = carm_ref_msg_dma(host, idx); - msg_data = (u32) (msg_dma + sizeof(struct carm_array_info)); - - crq->msg_type = CARM_MSG_ARRAY; - crq->msg_subtype = CARM_ARRAY_INFO; - rc = carm_lookup_bucket(sizeof(struct carm_msg_ioctl) + - sizeof(struct carm_array_info)); - BUG_ON(rc < 0); - crq->msg_bucket = (u32) rc; - - memset(ioc, 0, sizeof(*ioc)); - ioc->type = CARM_MSG_ARRAY; - ioc->subtype = CARM_ARRAY_INFO; - ioc->array_id = (u8) array_idx; - ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); - ioc->data_addr = cpu_to_le32(msg_data); - - spin_lock_irq(&host->lock); - assert(host->state == HST_DEV_SCAN_START || - host->state == HST_DEV_SCAN); - spin_unlock_irq(&host->lock); - - DPRINTK("blk_insert_request, tag == %u\n", idx); - blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); - - return 0; - -err_out: - spin_lock_irq(&host->lock); - host->state = HST_ERROR; - spin_unlock_irq(&host->lock); - return rc; -} - -typedef unsigned int (*carm_sspc_t)(struct carm_host *, unsigned int, void *); - -static int carm_send_special (struct carm_host *host, carm_sspc_t func) -{ - struct carm_request *crq; - struct carm_msg_ioctl *ioc; - void *mem; - unsigned int idx, msg_size; - int rc; - - crq = carm_get_special(host); - if (!crq) - return -ENOMEM; - - idx = crq->tag; - - mem = carm_ref_msg(host, idx); - - msg_size = func(host, idx, mem); - - ioc = mem; - crq->msg_type = ioc->type; - crq->msg_subtype = ioc->subtype; - rc = carm_lookup_bucket(msg_size); - BUG_ON(rc < 0); - crq->msg_bucket = (u32) rc; - - DPRINTK("blk_insert_request, tag == %u\n", idx); - blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); - - return 0; -} - -static unsigned int carm_fill_sync_time(struct carm_host *host, - unsigned int idx, void *mem) -{ - struct timeval tv; - struct carm_msg_sync_time *st = mem; - - do_gettimeofday(&tv); - - memset(st, 0, sizeof(*st)); - st->type = CARM_MSG_MISC; - st->subtype = MISC_SET_TIME; - st->handle = cpu_to_le32(TAG_ENCODE(idx)); - st->timestamp = cpu_to_le32(tv.tv_sec); - - return sizeof(struct carm_msg_sync_time); -} - -static unsigned int carm_fill_alloc_buf(struct carm_host *host, - unsigned int idx, void *mem) -{ - struct carm_msg_allocbuf *ab = mem; - - memset(ab, 0, sizeof(*ab)); - ab->type = CARM_MSG_MISC; - ab->subtype = MISC_ALLOC_MEM; - ab->handle = cpu_to_le32(TAG_ENCODE(idx)); - ab->n_sg = 1; - ab->sg_type = SGT_32BIT; - ab->addr = cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1)); - ab->len = cpu_to_le32(PDC_SHM_SIZE >> 1); - ab->evt_pool = cpu_to_le32(host->shm_dma + (16 * 1024)); - ab->n_evt = cpu_to_le32(1024); - ab->rbuf_pool = cpu_to_le32(host->shm_dma); - ab->n_rbuf = cpu_to_le32(RMSG_Q_LEN); - ab->msg_pool = cpu_to_le32(host->shm_dma + RBUF_LEN); - ab->n_msg = cpu_to_le32(CARM_Q_LEN); - ab->sg[0].start = cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1)); - ab->sg[0].len = cpu_to_le32(65536); - - return sizeof(struct carm_msg_allocbuf); -} - -static unsigned int carm_fill_scan_channels(struct carm_host *host, - unsigned int idx, void *mem) -{ - struct carm_msg_ioctl *ioc = mem; - u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) + - IOC_SCAN_CHAN_OFFSET); - - memset(ioc, 0, sizeof(*ioc)); - ioc->type = CARM_MSG_IOCTL; - ioc->subtype = CARM_IOC_SCAN_CHAN; - ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); - ioc->data_addr = cpu_to_le32(msg_data); - - /* fill output data area with "no device" default values */ - mem += IOC_SCAN_CHAN_OFFSET; - memset(mem, IOC_SCAN_CHAN_NODEV, CARM_MAX_PORTS); - - return IOC_SCAN_CHAN_OFFSET + CARM_MAX_PORTS; -} - -static unsigned int carm_fill_get_fw_ver(struct carm_host *host, - unsigned int idx, void *mem) -{ - struct carm_msg_get_fw_ver *ioc = mem; - u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) + sizeof(*ioc)); - - memset(ioc, 0, sizeof(*ioc)); - ioc->type = CARM_MSG_MISC; - ioc->subtype = MISC_GET_FW_VER; - ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); - ioc->data_addr = cpu_to_le32(msg_data); - - return sizeof(struct carm_msg_get_fw_ver) + - sizeof(struct carm_fw_ver); -} - -static inline void carm_end_request_queued(struct carm_host *host, - struct carm_request *crq, - int uptodate) -{ - struct request *req = crq->rq; - int rc; - - rc = end_that_request_first(req, uptodate, req->hard_nr_sectors); - assert(rc == 0); - - end_that_request_last(req); - - rc = carm_put_request(host, crq); - assert(rc == 0); -} - -static inline void carm_push_q (struct carm_host *host, request_queue_t *q) -{ - unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q; - - blk_stop_queue(q); - VPRINTK("STOPPED QUEUE %p\n", q); - - host->wait_q[idx] = q; - host->wait_q_prod++; - BUG_ON(host->wait_q_prod == host->wait_q_cons); /* overrun */ -} - -static inline request_queue_t *carm_pop_q(struct carm_host *host) -{ - unsigned int idx; - - if (host->wait_q_prod == host->wait_q_cons) - return NULL; - - idx = host->wait_q_cons % CARM_MAX_WAIT_Q; - host->wait_q_cons++; - - return host->wait_q[idx]; -} - -static inline void carm_round_robin(struct carm_host *host) -{ - request_queue_t *q = carm_pop_q(host); - if (q) { - blk_start_queue(q); - VPRINTK("STARTED QUEUE %p\n", q); - } -} - -static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, - int is_ok) -{ - carm_end_request_queued(host, crq, is_ok); - if (CARM_MAX_Q == 1) - carm_round_robin(host); - else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && - (host->hw_sg_used <= CARM_SG_LOW_WATER)) { - carm_round_robin(host); - } -} - -static void carm_oob_rq_fn(request_queue_t *q) -{ - struct carm_host *host = q->queuedata; - struct carm_request *crq; - struct request *rq; - int rc; - - while (1) { - DPRINTK("get req\n"); - rq = elv_next_request(q); - if (!rq) - break; - - blkdev_dequeue_request(rq); - - crq = rq->special; - assert(crq != NULL); - assert(crq->rq == rq); - - crq->n_elem = 0; - - DPRINTK("send req\n"); - rc = carm_send_msg(host, crq); - if (rc) { - blk_requeue_request(q, rq); - carm_push_q(host, q); - return; /* call us again later, eventually */ - } - } -} - -static void carm_rq_fn(request_queue_t *q) -{ - struct carm_port *port = q->queuedata; - struct carm_host *host = port->host; - struct carm_msg_rw *msg; - struct carm_request *crq; - struct request *rq; - struct scatterlist *sg; - int writing = 0, pci_dir, i, n_elem, rc; - u32 tmp; - unsigned int msg_size; - -queue_one_request: - VPRINTK("get req\n"); - rq = elv_next_request(q); - if (!rq) - return; - - crq = carm_get_request(host); - if (!crq) { - carm_push_q(host, q); - return; /* call us again later, eventually */ - } - crq->rq = rq; - - blkdev_dequeue_request(rq); - - if (rq_data_dir(rq) == WRITE) { - writing = 1; - pci_dir = PCI_DMA_TODEVICE; - } else { - pci_dir = PCI_DMA_FROMDEVICE; - } - - /* get scatterlist from block layer */ - sg = &crq->sg[0]; - n_elem = blk_rq_map_sg(q, rq, sg); - if (n_elem <= 0) { - carm_end_rq(host, crq, 0); - return; /* request with no s/g entries? */ - } - - /* map scatterlist to PCI bus addresses */ - n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); - if (n_elem <= 0) { - carm_end_rq(host, crq, 0); - return; /* request with no s/g entries? */ - } - crq->n_elem = n_elem; - crq->port = port; - host->hw_sg_used += n_elem; - - /* - * build read/write message - */ - - VPRINTK("build msg\n"); - msg = (struct carm_msg_rw *) carm_ref_msg(host, crq->tag); - - if (writing) { - msg->type = CARM_MSG_WRITE; - crq->msg_type = CARM_MSG_WRITE; - } else { - msg->type = CARM_MSG_READ; - crq->msg_type = CARM_MSG_READ; - } - - msg->id = port->port_no; - msg->sg_count = n_elem; - msg->sg_type = SGT_32BIT; - msg->handle = cpu_to_le32(TAG_ENCODE(crq->tag)); - msg->lba = cpu_to_le32(rq->sector & 0xffffffff); - tmp = (rq->sector >> 16) >> 16; - msg->lba_high = cpu_to_le16( (u16) tmp ); - msg->lba_count = cpu_to_le16(rq->nr_sectors); - - msg_size = sizeof(struct carm_msg_rw) - sizeof(msg->sg); - for (i = 0; i < n_elem; i++) { - struct carm_msg_sg *carm_sg = &msg->sg[i]; - carm_sg->start = cpu_to_le32(sg_dma_address(&crq->sg[i])); - carm_sg->len = cpu_to_le32(sg_dma_len(&crq->sg[i])); - msg_size += sizeof(struct carm_msg_sg); - } - - rc = carm_lookup_bucket(msg_size); - BUG_ON(rc < 0); - crq->msg_bucket = (u32) rc; - - /* - * queue read/write message to hardware - */ - - VPRINTK("send msg, tag == %u\n", crq->tag); - rc = carm_send_msg(host, crq); - if (rc) { - carm_put_request(host, crq); - blk_requeue_request(q, rq); - carm_push_q(host, q); - return; /* call us again later, eventually */ - } - - goto queue_one_request; -} - -static void carm_handle_array_info(struct carm_host *host, - struct carm_request *crq, u8 *mem, - int is_ok) -{ - struct carm_port *port; - u8 *msg_data = mem + sizeof(struct carm_array_info); - struct carm_array_info *desc = (struct carm_array_info *) msg_data; - u64 lo, hi; - int cur_port; - size_t slen; - - DPRINTK("ENTER\n"); - - carm_end_rq(host, crq, is_ok); - - if (!is_ok) - goto out; - if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST) - goto out; - - cur_port = host->cur_scan_dev; - - /* should never occur */ - if ((cur_port < 0) || (cur_port >= CARM_MAX_PORTS)) { - printk(KERN_ERR PFX "BUG: cur_scan_dev==%d, array_id==%d\n", - cur_port, (int) desc->array_id); - goto out; - } - - port = &host->port[cur_port]; - - lo = (u64) le32_to_cpu(desc->size); - hi = (u64) le32_to_cpu(desc->size_hi); - - port->capacity = lo | (hi << 32); - port->dev_geom_head = le16_to_cpu(desc->head); - port->dev_geom_sect = le16_to_cpu(desc->sect); - port->dev_geom_cyl = le16_to_cpu(desc->cyl); - - host->dev_active |= (1 << cur_port); - - strncpy(port->name, desc->name, sizeof(port->name)); - port->name[sizeof(port->name) - 1] = 0; - slen = strlen(port->name); - while (slen && (port->name[slen - 1] == ' ')) { - port->name[slen - 1] = 0; - slen--; - } - - printk(KERN_INFO DRV_NAME "(%s): port %u device %Lu sectors\n", - pci_name(host->pdev), port->port_no, - (unsigned long long) port->capacity); - printk(KERN_INFO DRV_NAME "(%s): port %u device \"%s\"\n", - pci_name(host->pdev), port->port_no, port->name); - -out: - assert(host->state == HST_DEV_SCAN); - schedule_work(&host->fsm_task); -} - -static void carm_handle_scan_chan(struct carm_host *host, - struct carm_request *crq, u8 *mem, - int is_ok) -{ - u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET; - unsigned int i, dev_count = 0; - int new_state = HST_DEV_SCAN_START; - - DPRINTK("ENTER\n"); - - carm_end_rq(host, crq, is_ok); - - if (!is_ok) { - new_state = HST_ERROR; - goto out; - } - - /* TODO: scan and support non-disk devices */ - for (i = 0; i < 8; i++) - if (msg_data[i] == 0) { /* direct-access device (disk) */ - host->dev_present |= (1 << i); - dev_count++; - } - - printk(KERN_INFO DRV_NAME "(%s): found %u interesting devices\n", - pci_name(host->pdev), dev_count); - -out: - assert(host->state == HST_PORT_SCAN); - host->state = new_state; - schedule_work(&host->fsm_task); -} - -static void carm_handle_generic(struct carm_host *host, - struct carm_request *crq, int is_ok, - int cur_state, int next_state) -{ - DPRINTK("ENTER\n"); - - carm_end_rq(host, crq, is_ok); - - assert(host->state == cur_state); - if (is_ok) - host->state = next_state; - else - host->state = HST_ERROR; - schedule_work(&host->fsm_task); -} - -static inline void carm_handle_rw(struct carm_host *host, - struct carm_request *crq, int is_ok) -{ - int pci_dir; - - VPRINTK("ENTER\n"); - - if (rq_data_dir(crq->rq) == WRITE) - pci_dir = PCI_DMA_TODEVICE; - else - pci_dir = PCI_DMA_FROMDEVICE; - - pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); - - carm_end_rq(host, crq, is_ok); -} - -static inline void carm_handle_resp(struct carm_host *host, - u32 ret_handle_le, u32 status) -{ - u32 handle = le32_to_cpu(ret_handle_le); - unsigned int msg_idx; - struct carm_request *crq; - int is_ok = (status == RMSG_OK); - u8 *mem; - - VPRINTK("ENTER, handle == 0x%x\n", handle); - - if (unlikely(!TAG_VALID(handle))) { - printk(KERN_ERR DRV_NAME "(%s): BUG: invalid tag 0x%x\n", - pci_name(host->pdev), handle); - return; - } - - msg_idx = TAG_DECODE(handle); - VPRINTK("tag == %u\n", msg_idx); - - crq = &host->req[msg_idx]; - - /* fast path */ - if (likely(crq->msg_type == CARM_MSG_READ || - crq->msg_type == CARM_MSG_WRITE)) { - carm_handle_rw(host, crq, is_ok); - return; - } - - mem = carm_ref_msg(host, msg_idx); - - switch (crq->msg_type) { - case CARM_MSG_IOCTL: { - switch (crq->msg_subtype) { - case CARM_IOC_SCAN_CHAN: - carm_handle_scan_chan(host, crq, mem, is_ok); - break; - default: - /* unknown / invalid response */ - goto err_out; - } - break; - } - - case CARM_MSG_MISC: { - switch (crq->msg_subtype) { - case MISC_ALLOC_MEM: - carm_handle_generic(host, crq, is_ok, - HST_ALLOC_BUF, HST_SYNC_TIME); - break; - case MISC_SET_TIME: - carm_handle_generic(host, crq, is_ok, - HST_SYNC_TIME, HST_GET_FW_VER); - break; - case MISC_GET_FW_VER: { - struct carm_fw_ver *ver = (struct carm_fw_ver *) - mem + sizeof(struct carm_msg_get_fw_ver); - if (is_ok) { - host->fw_ver = le32_to_cpu(ver->version); - host->flags |= (ver->features & FL_FW_VER_MASK); - } - carm_handle_generic(host, crq, is_ok, - HST_GET_FW_VER, HST_PORT_SCAN); - break; - } - default: - /* unknown / invalid response */ - goto err_out; - } - break; - } - - case CARM_MSG_ARRAY: { - switch (crq->msg_subtype) { - case CARM_ARRAY_INFO: - carm_handle_array_info(host, crq, mem, is_ok); - break; - default: - /* unknown / invalid response */ - goto err_out; - } - break; - } - - default: - /* unknown / invalid response */ - goto err_out; - } - - return; - -err_out: - printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", - pci_name(host->pdev), crq->msg_type, crq->msg_subtype); - carm_end_rq(host, crq, 0); -} - -static inline void carm_handle_responses(struct carm_host *host) -{ - void *mmio = host->mmio; - struct carm_response *resp = (struct carm_response *) host->shm; - unsigned int work = 0; - unsigned int idx = host->resp_idx % RMSG_Q_LEN; - - while (1) { - u32 status = le32_to_cpu(resp[idx].status); - - if (status == 0xffffffff) { - VPRINTK("ending response on index %u\n", idx); - writel(idx << 3, mmio + CARM_RESP_IDX); - break; - } - - /* response to a message we sent */ - else if ((status & (1 << 31)) == 0) { - VPRINTK("handling msg response on index %u\n", idx); - carm_handle_resp(host, resp[idx].ret_handle, status); - resp[idx].status = 0xffffffff; - } - - /* asynchronous events the hardware throws our way */ - else if ((status & 0xff000000) == (1 << 31)) { - u8 *evt_type_ptr = (u8 *) &resp[idx]; - u8 evt_type = *evt_type_ptr; - printk(KERN_WARNING DRV_NAME "(%s): unhandled event type %d\n", - pci_name(host->pdev), (int) evt_type); - resp[idx].status = 0xffffffff; - } - - idx = NEXT_RESP(idx); - work++; - } - - VPRINTK("EXIT, work==%u\n", work); - host->resp_idx += work; -} - -static irqreturn_t carm_interrupt(int irq, void *__host, struct pt_regs *regs) -{ - struct carm_host *host = __host; - void *mmio; - u32 mask; - int handled = 0; - unsigned long flags; - - if (!host) { - VPRINTK("no host\n"); - return IRQ_NONE; - } - - spin_lock_irqsave(&host->lock, flags); - - mmio = host->mmio; - - /* reading should also clear interrupts */ - mask = readl(mmio + CARM_INT_STAT); - - if (mask == 0 || mask == 0xffffffff) { - VPRINTK("no work, mask == 0x%x\n", mask); - goto out; - } - - if (mask & INT_ACK_MASK) - writel(mask, mmio + CARM_INT_STAT); - - if (unlikely(host->state == HST_INVALID)) { - VPRINTK("not initialized yet, mask = 0x%x\n", mask); - goto out; - } - - if (mask & CARM_HAVE_RESP) { - handled = 1; - carm_handle_responses(host); - } - -out: - spin_unlock_irqrestore(&host->lock, flags); - VPRINTK("EXIT\n"); - return IRQ_RETVAL(handled); -} - -static void carm_fsm_task (void *_data) -{ - struct carm_host *host = _data; - unsigned long flags; - unsigned int state; - int rc, i, next_dev; - int reschedule = 0; - int new_state = HST_INVALID; - - spin_lock_irqsave(&host->lock, flags); - state = host->state; - spin_unlock_irqrestore(&host->lock, flags); - - DPRINTK("ENTER, state == %s\n", state_name[state]); - - switch (state) { - case HST_PROBE_START: - new_state = HST_ALLOC_BUF; - reschedule = 1; - break; - - case HST_ALLOC_BUF: - rc = carm_send_special(host, carm_fill_alloc_buf); - if (rc) { - new_state = HST_ERROR; - reschedule = 1; - } - break; - - case HST_SYNC_TIME: - rc = carm_send_special(host, carm_fill_sync_time); - if (rc) { - new_state = HST_ERROR; - reschedule = 1; - } - break; - - case HST_GET_FW_VER: - rc = carm_send_special(host, carm_fill_get_fw_ver); - if (rc) { - new_state = HST_ERROR; - reschedule = 1; - } - break; - - case HST_PORT_SCAN: - rc = carm_send_special(host, carm_fill_scan_channels); - if (rc) { - new_state = HST_ERROR; - reschedule = 1; - } - break; - - case HST_DEV_SCAN_START: - host->cur_scan_dev = -1; - new_state = HST_DEV_SCAN; - reschedule = 1; - break; - - case HST_DEV_SCAN: - next_dev = -1; - for (i = host->cur_scan_dev + 1; i < CARM_MAX_PORTS; i++) - if (host->dev_present & (1 << i)) { - next_dev = i; - break; - } - - if (next_dev >= 0) { - host->cur_scan_dev = next_dev; - rc = carm_array_info(host, next_dev); - if (rc) { - new_state = HST_ERROR; - reschedule = 1; - } - } else { - new_state = HST_DEV_ACTIVATE; - reschedule = 1; - } - break; - - case HST_DEV_ACTIVATE: { - int activated = 0; - for (i = 0; i < CARM_MAX_PORTS; i++) - if (host->dev_active & (1 << i)) { - struct carm_port *port = &host->port[i]; - struct gendisk *disk = port->disk; - - set_capacity(disk, port->capacity); - add_disk(disk); - activated++; - } - - printk(KERN_INFO DRV_NAME "(%s): %d ports activated\n", - pci_name(host->pdev), activated); - - new_state = HST_PROBE_FINISHED; - reschedule = 1; - break; - } - - case HST_PROBE_FINISHED: - up(&host->probe_sem); - break; - - case HST_ERROR: - /* FIXME: TODO */ - break; - - default: - /* should never occur */ - printk(KERN_ERR PFX "BUG: unknown state %d\n", state); - assert(0); - break; - } - - if (new_state != HST_INVALID) { - spin_lock_irqsave(&host->lock, flags); - host->state = new_state; - spin_unlock_irqrestore(&host->lock, flags); - } - if (reschedule) - schedule_work(&host->fsm_task); -} - -static int carm_init_wait(void *mmio, u32 bits, unsigned int test_bit) -{ - unsigned int i; - - for (i = 0; i < 50000; i++) { - u32 tmp = readl(mmio + CARM_LMUC); - udelay(100); - - if (test_bit) { - if ((tmp & bits) == bits) - return 0; - } else { - if ((tmp & bits) == 0) - return 0; - } - - cond_resched(); - } - - printk(KERN_ERR PFX "carm_init_wait timeout, bits == 0x%x, test_bit == %s\n", - bits, test_bit ? "yes" : "no"); - return -EBUSY; -} - -static void carm_init_responses(struct carm_host *host) -{ - void *mmio = host->mmio; - unsigned int i; - struct carm_response *resp = (struct carm_response *) host->shm; - - for (i = 0; i < RMSG_Q_LEN; i++) - resp[i].status = 0xffffffff; - - writel(0, mmio + CARM_RESP_IDX); -} - -static int carm_init_host(struct carm_host *host) -{ - void *mmio = host->mmio; - u32 tmp; - u8 tmp8; - int rc; - - DPRINTK("ENTER\n"); - - writel(0, mmio + CARM_INT_MASK); - - tmp8 = readb(mmio + CARM_INITC); - if (tmp8 & 0x01) { - tmp8 &= ~0x01; - writeb(tmp8, CARM_INITC); - readb(mmio + CARM_INITC); /* flush */ - - DPRINTK("snooze...\n"); - msleep(5000); - } - - tmp = readl(mmio + CARM_HMUC); - if (tmp & CARM_CME) { - DPRINTK("CME bit present, waiting\n"); - rc = carm_init_wait(mmio, CARM_CME, 1); - if (rc) { - DPRINTK("EXIT, carm_init_wait 1 failed\n"); - return rc; - } - } - if (tmp & CARM_RME) { - DPRINTK("RME bit present, waiting\n"); - rc = carm_init_wait(mmio, CARM_RME, 1); - if (rc) { - DPRINTK("EXIT, carm_init_wait 2 failed\n"); - return rc; - } - } - - tmp &= ~(CARM_RME | CARM_CME); - writel(tmp, mmio + CARM_HMUC); - readl(mmio + CARM_HMUC); /* flush */ - - rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 0); - if (rc) { - DPRINTK("EXIT, carm_init_wait 3 failed\n"); - return rc; - } - - carm_init_buckets(mmio); - - writel(host->shm_dma & 0xffffffff, mmio + RBUF_ADDR_LO); - writel((host->shm_dma >> 16) >> 16, mmio + RBUF_ADDR_HI); - writel(RBUF_LEN, mmio + RBUF_BYTE_SZ); - - tmp = readl(mmio + CARM_HMUC); - tmp |= (CARM_RME | CARM_CME | CARM_WZBC); - writel(tmp, mmio + CARM_HMUC); - readl(mmio + CARM_HMUC); /* flush */ - - rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 1); - if (rc) { - DPRINTK("EXIT, carm_init_wait 4 failed\n"); - return rc; - } - - writel(0, mmio + CARM_HMPHA); - writel(INT_DEF_MASK, mmio + CARM_INT_MASK); - - carm_init_responses(host); - - /* start initialization, probing state machine */ - spin_lock_irq(&host->lock); - assert(host->state == HST_INVALID); - host->state = HST_PROBE_START; - spin_unlock_irq(&host->lock); - schedule_work(&host->fsm_task); - - DPRINTK("EXIT\n"); - return 0; -} - -static int carm_init_disks(struct carm_host *host) -{ - unsigned int i; - int rc = 0; - - for (i = 0; i < CARM_MAX_PORTS; i++) { - struct gendisk *disk; - request_queue_t *q; - struct carm_port *port; - - port = &host->port[i]; - port->host = host; - port->port_no = i; - - disk = alloc_disk(CARM_MINORS_PER_MAJOR); - if (!disk) { - rc = -ENOMEM; - break; - } - - port->disk = disk; - sprintf(disk->disk_name, DRV_NAME "%u_%u", host->id, i); - sprintf(disk->devfs_name, DRV_NAME "/%u_%u", host->id, i); - disk->major = host->major; - disk->first_minor = i * CARM_MINORS_PER_MAJOR; - disk->fops = &carm_bd_ops; - disk->private_data = port; - - q = blk_init_queue(carm_rq_fn, &host->lock); - if (!q) { - rc = -ENOMEM; - break; - } - disk->queue = q; - blk_queue_max_hw_segments(q, CARM_MAX_REQ_SG); - blk_queue_max_phys_segments(q, CARM_MAX_REQ_SG); - blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); - - q->queuedata = port; - } - - return rc; -} - -static void carm_free_disks(struct carm_host *host) -{ - unsigned int i; - - for (i = 0; i < CARM_MAX_PORTS; i++) { - struct gendisk *disk = host->port[i].disk; - if (disk) { - request_queue_t *q = disk->queue; - - if (disk->flags & GENHD_FL_UP) - del_gendisk(disk); - if (q) - blk_cleanup_queue(q); - put_disk(disk); - } - } -} - -static int carm_init_shm(struct carm_host *host) -{ - host->shm = pci_alloc_consistent(host->pdev, CARM_SHM_SIZE, - &host->shm_dma); - if (!host->shm) - return -ENOMEM; - - host->msg_base = host->shm + RBUF_LEN; - host->msg_dma = host->shm_dma + RBUF_LEN; - - memset(host->shm, 0xff, RBUF_LEN); - memset(host->msg_base, 0, PDC_SHM_SIZE - RBUF_LEN); - - return 0; -} - -static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -{ - static unsigned int printed_version; - struct carm_host *host; - unsigned int pci_dac; - int rc; - request_queue_t *q; - unsigned int i; - - if (!printed_version++) - printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); - - rc = pci_enable_device(pdev); - if (rc) - return rc; - - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) - goto err_out; - -#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ - rc = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); - if (!rc) { - rc = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); - if (rc) { - printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n", - pci_name(pdev)); - goto err_out_regions; - } - pci_dac = 1; - } else { -#endif - rc = pci_set_dma_mask(pdev, 0xffffffffULL); - if (rc) { - printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", - pci_name(pdev)); - goto err_out_regions; - } - pci_dac = 0; -#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ - } -#endif - - host = kmalloc(sizeof(*host), GFP_KERNEL); - if (!host) { - printk(KERN_ERR DRV_NAME "(%s): memory alloc failure\n", - pci_name(pdev)); - rc = -ENOMEM; - goto err_out_regions; - } - - memset(host, 0, sizeof(*host)); - host->pdev = pdev; - host->flags = pci_dac ? FL_DAC : 0; - spin_lock_init(&host->lock); - INIT_WORK(&host->fsm_task, carm_fsm_task, host); - init_MUTEX_LOCKED(&host->probe_sem); - - for (i = 0; i < ARRAY_SIZE(host->req); i++) - host->req[i].tag = i; - - host->mmio = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (!host->mmio) { - printk(KERN_ERR DRV_NAME "(%s): MMIO alloc failure\n", - pci_name(pdev)); - rc = -ENOMEM; - goto err_out_kfree; - } - - rc = carm_init_shm(host); - if (rc) { - printk(KERN_ERR DRV_NAME "(%s): DMA SHM alloc failure\n", - pci_name(pdev)); - goto err_out_iounmap; - } - - q = blk_init_queue(carm_oob_rq_fn, &host->lock); - if (!q) { - printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n", - pci_name(pdev)); - rc = -ENOMEM; - goto err_out_pci_free; - } - host->oob_q = q; - q->queuedata = host; - - /* - * Figure out which major to use: 160, 161, or dynamic - */ - if (!test_and_set_bit(0, &carm_major_alloc)) - host->major = 160; - else if (!test_and_set_bit(1, &carm_major_alloc)) - host->major = 161; - else - host->flags |= FL_DYN_MAJOR; - - host->id = carm_host_id; - sprintf(host->name, DRV_NAME "%d", carm_host_id); - - rc = register_blkdev(host->major, host->name); - if (rc < 0) - goto err_out_free_majors; - if (host->flags & FL_DYN_MAJOR) - host->major = rc; - - devfs_mk_dir(DRV_NAME); - - rc = carm_init_disks(host); - if (rc) - goto err_out_blkdev_disks; - - pci_set_master(pdev); - - rc = request_irq(pdev->irq, carm_interrupt, SA_SHIRQ, DRV_NAME, host); - if (rc) { - printk(KERN_ERR DRV_NAME "(%s): irq alloc failure\n", - pci_name(pdev)); - goto err_out_blkdev_disks; - } - - rc = carm_init_host(host); - if (rc) - goto err_out_free_irq; - - DPRINTK("waiting for probe_sem\n"); - down(&host->probe_sem); - - printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n", - host->name, pci_name(pdev), (int) CARM_MAX_PORTS, - pci_resource_start(pdev, 0), pdev->irq, host->major); - - carm_host_id++; - pci_set_drvdata(pdev, host); - return 0; - -err_out_free_irq: - free_irq(pdev->irq, host); -err_out_blkdev_disks: - carm_free_disks(host); - unregister_blkdev(host->major, host->name); -err_out_free_majors: - if (host->major == 160) - clear_bit(0, &carm_major_alloc); - else if (host->major == 161) - clear_bit(1, &carm_major_alloc); - blk_cleanup_queue(host->oob_q); -err_out_pci_free: - pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); -err_out_iounmap: - iounmap(host->mmio); -err_out_kfree: - kfree(host); -err_out_regions: - pci_release_regions(pdev); -err_out: - pci_disable_device(pdev); - return rc; -} - -static void carm_remove_one (struct pci_dev *pdev) -{ - struct carm_host *host = pci_get_drvdata(pdev); - - if (!host) { - printk(KERN_ERR PFX "BUG: no host data for PCI(%s)\n", - pci_name(pdev)); - return; - } - - free_irq(pdev->irq, host); - carm_free_disks(host); - devfs_remove(DRV_NAME); - unregister_blkdev(host->major, host->name); - if (host->major == 160) - clear_bit(0, &carm_major_alloc); - else if (host->major == 161) - clear_bit(1, &carm_major_alloc); - blk_cleanup_queue(host->oob_q); - pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); - iounmap(host->mmio); - kfree(host); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); -} - -static int __init carm_init(void) -{ - return pci_module_init(&carm_driver); -} - -static void __exit carm_exit(void) -{ - pci_unregister_driver(&carm_driver); -} - -module_init(carm_init); -module_exit(carm_exit); - - diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c --- a/drivers/block/cciss.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/block/cciss.c 2004-06-26 17:09:20 -07:00 @@ -479,6 +479,148 @@ return 0; } +#ifdef CONFIG_COMPAT +/* for AMD 64 bit kernel compatibility with 32-bit userland ioctls */ +extern long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); +extern int +register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, + unsigned int, unsigned long, struct file *)); +extern int unregister_ioctl32_conversion(unsigned int cmd); + +static int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg, struct file *file); +static int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg, + struct file *file); + +typedef int (*handler_type) (unsigned int, unsigned int, unsigned long, struct file *); + +static struct ioctl32_map { + unsigned int cmd; + handler_type handler; + int registered; +} cciss_ioctl32_map[] = { + { CCISS_GETPCIINFO, (handler_type) sys_ioctl, 0 }, + { CCISS_GETINTINFO, (handler_type) sys_ioctl, 0 }, + { CCISS_SETINTINFO, (handler_type) sys_ioctl, 0 }, + { CCISS_GETNODENAME, (handler_type) sys_ioctl, 0 }, + { CCISS_SETNODENAME, (handler_type) sys_ioctl, 0 }, + { CCISS_GETHEARTBEAT, (handler_type) sys_ioctl, 0 }, + { CCISS_GETBUSTYPES, (handler_type) sys_ioctl, 0 }, + { CCISS_GETFIRMVER, (handler_type) sys_ioctl, 0 }, + { CCISS_GETDRIVVER, (handler_type) sys_ioctl, 0 }, + { CCISS_REVALIDVOLS, (handler_type) sys_ioctl, 0 }, + { CCISS_PASSTHRU32, cciss_ioctl32_passthru, 0 }, + { CCISS_DEREGDISK, (handler_type) sys_ioctl, 0 }, + { CCISS_REGNEWDISK, (handler_type) sys_ioctl, 0 }, + { CCISS_REGNEWD, (handler_type) sys_ioctl, 0 }, + { CCISS_RESCANDISK, (handler_type) sys_ioctl, 0 }, + { CCISS_GETLUNINFO, (handler_type) sys_ioctl, 0 }, + { CCISS_BIG_PASSTHRU32, cciss_ioctl32_big_passthru, 0 }, +}; +#define NCCISS_IOCTL32_ENTRIES (sizeof(cciss_ioctl32_map) / sizeof(cciss_ioctl32_map[0])) +static void register_cciss_ioctl32(void) +{ + int i, rc; + + for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) { + rc = register_ioctl32_conversion( + cciss_ioctl32_map[i].cmd, + cciss_ioctl32_map[i].handler); + if (rc != 0) { + printk(KERN_WARNING "cciss: failed to register " + "32 bit compatible ioctl 0x%08x\n", + cciss_ioctl32_map[i].cmd); + cciss_ioctl32_map[i].registered = 0; + } else + cciss_ioctl32_map[i].registered = 1; + } +} +static void unregister_cciss_ioctl32(void) +{ + int i, rc; + + for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) { + if (!cciss_ioctl32_map[i].registered) + continue; + rc = unregister_ioctl32_conversion( + cciss_ioctl32_map[i].cmd); + if (rc == 0) { + cciss_ioctl32_map[i].registered = 0; + continue; + } + printk(KERN_WARNING "cciss: failed to unregister " + "32 bit compatible ioctl 0x%08x\n", + cciss_ioctl32_map[i].cmd); + } +} +int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg, + struct file *file) +{ + IOCTL32_Command_struct *arg32 = + (IOCTL32_Command_struct *) arg; + IOCTL_Command_struct arg64; + mm_segment_t old_fs; + int err; + unsigned long cp; + + err = 0; + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info)); + err |= get_user(arg64.buf_size, &arg32->buf_size); + err |= get_user(cp, &arg32->buf); + arg64.buf = (BYTE *)cp; + + if (err) + return -EFAULT; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_ioctl(fd, CCISS_PASSTHRU, (unsigned long) &arg64); + set_fs(old_fs); + if (err) + return err; + err |= copy_to_user(&arg32->error_info, &arg64.error_info, sizeof(&arg32->error_info)); + if (err) + return -EFAULT; + return err; +} +int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg, + struct file *file) +{ + BIG_IOCTL32_Command_struct *arg32 = + (BIG_IOCTL32_Command_struct *) arg; + BIG_IOCTL_Command_struct arg64; + mm_segment_t old_fs; + int err; + unsigned long cp; + + err = 0; + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info)); + err |= get_user(arg64.buf_size, &arg32->buf_size); + err |= get_user(arg64.malloc_size, &arg32->malloc_size); + err |= get_user(cp, &arg32->buf); + arg64.buf = (BYTE *)cp; + + if (err) + return -EFAULT; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_ioctl(fd, CCISS_BIG_PASSTHRU, (unsigned long) &arg64); + set_fs(old_fs); + if (err) + return err; + err |= copy_to_user(&arg32->error_info, &arg64.error_info, sizeof(&arg32->error_info)); + if (err) + return -EFAULT; + return err; +} +#else +static inline void register_cciss_ioctl32(void) {} +static inline void unregister_cciss_ioctl32(void) {} +#endif /* * ioctl */ @@ -2728,6 +2870,7 @@ static int __init init_cciss_module(void) { + register_cciss_ioctl32(); return ( cciss_init()); } @@ -2735,6 +2878,7 @@ { int i; + unregister_cciss_ioctl32(); pci_unregister_driver(&cciss_pci_driver); /* double check that all controller entrys have been removed */ for (i=0; i< MAX_CTLR; i++) diff -Nru a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c --- a/drivers/block/cfq-iosched.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/block/cfq-iosched.c 2004-06-26 17:09:19 -07:00 @@ -59,6 +59,14 @@ unsigned int max_queued; mempool_t *crq_pool; + + request_queue_t *queue; + + /* + * tunables + */ + unsigned int cfq_quantum; + unsigned int cfq_queued; }; struct cfq_queue { @@ -89,7 +97,8 @@ static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq); static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid); -static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq); +static void cfq_dispatch_sort(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct cfq_rq *crq); /* * lots of deadline iosched dupes, can be abstracted later... @@ -206,8 +215,7 @@ return; } - cfq_del_crq_rb(cfqq, __alias); - cfq_dispatch_sort(cfqd->dispatch, __alias); + cfq_dispatch_sort(cfqd, cfqq, __alias); goto retry; } @@ -321,11 +329,16 @@ cfq_remove_request(q, next); } -static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq) +static void +cfq_dispatch_sort(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct cfq_rq *crq) { - struct list_head *entry = head; + struct list_head *head = cfqd->dispatch, *entry = head; struct request *__rq; + cfq_del_crq_rb(cfqq, crq); + cfq_remove_merge_hints(cfqd->queue, crq); + if (!list_empty(head)) { __rq = list_entry_rq(head->next); @@ -352,9 +365,7 @@ { struct cfq_rq *crq = rb_entry_crq(rb_first(&cfqq->sort_list)); - cfq_del_crq_rb(cfqq, crq); - cfq_remove_merge_hints(q, crq); - cfq_dispatch_sort(cfqd->dispatch, crq); + cfq_dispatch_sort(cfqd, cfqq, crq); } static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd) @@ -385,7 +396,7 @@ ret = 1; } - if ((queued < cfq_quantum) && good_queues) + if ((queued < cfqd->cfq_quantum) && good_queues) goto restart; return ret; @@ -556,7 +567,7 @@ cfqq = cfq_find_cfq_hash(cfqd, current->tgid); if (cfqq) { - int limit = (q->nr_requests - cfq_queued) / cfqd->busy_queues; + int limit = (q->nr_requests - cfqd->cfq_queued) / cfqd->busy_queues; if (limit < 3) limit = 3; @@ -574,6 +585,8 @@ { struct cfq_data *cfqd = q->elevator.elevator_data; struct cfq_rq *crq = RQ_DATA(rq); + struct request_list *rl; + int other_rw; if (crq) { BUG_ON(q->last_merge == rq); @@ -582,6 +595,23 @@ mempool_free(crq, cfqd->crq_pool); rq->elevator_private = NULL; } + + /* + * work-around for may_queue "bug": if a read gets issued and refused + * to queue because writes ate all the allowed slots and no other + * reads are pending for this queue, it could get stuck infinitely + * since freed_request() only checks the waitqueue for writes when + * freeing them. or vice versa for a single write vs many reads. + * so check here whether "the other" data direction might be able + * to queue and wake them + */ + rl = &q->rq; + other_rw = rq_data_dir(rq) ^ 1; + if (rl->count[other_rw] <= q->nr_requests) { + smp_mb(); + if (waitqueue_active(&rl->wait[other_rw])) + wake_up(&rl->wait[other_rw]); + } } static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask) @@ -643,6 +673,7 @@ cfqd->dispatch = &q->queue_head; e->elevator_data = cfqd; + cfqd->queue = q; /* * just set it to some high value, we want anyone to be able to queue @@ -651,6 +682,9 @@ cfqd->max_queued = q->nr_requests; q->nr_requests = 8192; + cfqd->cfq_queued = cfq_queued; + cfqd->cfq_quantum = cfq_quantum; + return 0; out_crqpool: kfree(cfqd->cfq_hash); @@ -685,8 +719,110 @@ subsys_initcall(cfq_slab_setup); +/* + * sysfs parts below --> + */ +struct cfq_fs_entry { + struct attribute attr; + ssize_t (*show)(struct cfq_data *, char *); + ssize_t (*store)(struct cfq_data *, const char *, size_t); +}; + +static ssize_t +cfq_var_show(unsigned int var, char *page) +{ + return sprintf(page, "%d\n", var); +} + +static ssize_t +cfq_var_store(unsigned int *var, const char *page, size_t count) +{ + char *p = (char *) page; + + *var = simple_strtoul(p, &p, 10); + return count; +} + +#define SHOW_FUNCTION(__FUNC, __VAR) \ +static ssize_t __FUNC(struct cfq_data *cfqd, char *page) \ +{ \ + return cfq_var_show(__VAR, (page)); \ +} +SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum); +SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued); +#undef SHOW_FUNCTION + +#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX) \ +static ssize_t __FUNC(struct cfq_data *cfqd, const char *page, size_t count) \ +{ \ + int ret = cfq_var_store(__PTR, (page), count); \ + if (*(__PTR) < (MIN)) \ + *(__PTR) = (MIN); \ + else if (*(__PTR) > (MAX)) \ + *(__PTR) = (MAX); \ + return ret; \ +} +STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, INT_MAX); +STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, INT_MAX); +#undef STORE_FUNCTION + +static struct cfq_fs_entry cfq_quantum_entry = { + .attr = {.name = "quantum", .mode = S_IRUGO | S_IWUSR }, + .show = cfq_quantum_show, + .store = cfq_quantum_store, +}; +static struct cfq_fs_entry cfq_queued_entry = { + .attr = {.name = "queued", .mode = S_IRUGO | S_IWUSR }, + .show = cfq_queued_show, + .store = cfq_queued_store, +}; + +static struct attribute *default_attrs[] = { + &cfq_quantum_entry.attr, + &cfq_queued_entry.attr, + NULL, +}; + +#define to_cfq(atr) container_of((atr), struct cfq_fs_entry, attr) + +static ssize_t +cfq_attr_show(struct kobject *kobj, struct attribute *attr, char *page) +{ + elevator_t *e = container_of(kobj, elevator_t, kobj); + struct cfq_fs_entry *entry = to_cfq(attr); + + if (!entry->show) + return 0; + + return entry->show(e->elevator_data, page); +} + +static ssize_t +cfq_attr_store(struct kobject *kobj, struct attribute *attr, + const char *page, size_t length) +{ + elevator_t *e = container_of(kobj, elevator_t, kobj); + struct cfq_fs_entry *entry = to_cfq(attr); + + if (!entry->store) + return -EINVAL; + + return entry->store(e->elevator_data, page, length); +} + +static struct sysfs_ops cfq_sysfs_ops = { + .show = cfq_attr_show, + .store = cfq_attr_store, +}; + +struct kobj_type cfq_ktype = { + .sysfs_ops = &cfq_sysfs_ops, + .default_attrs = default_attrs, +}; + elevator_t iosched_cfq = { .elevator_name = "cfq", + .elevator_ktype = &cfq_ktype, .elevator_merge_fn = cfq_merge, .elevator_merged_fn = cfq_merged_request, .elevator_merge_req_fn = cfq_merged_requests, diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c --- a/drivers/block/elevator.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/block/elevator.c 2004-06-26 17:09:19 -07:00 @@ -181,6 +181,14 @@ rq->q = q; q->elevator.elevator_add_req_fn(q, rq, where); + + if (blk_queue_plugged(q)) { + int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight; + + if (nrq == q->unplug_thresh) + __generic_unplug_device(q); + } + } void elv_add_request(request_queue_t *q, struct request *rq, int where, diff -Nru a/drivers/block/floppy98.c b/drivers/block/floppy98.c --- a/drivers/block/floppy98.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,4682 +0,0 @@ -/* - * linux/drivers/block/floppy.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1993, 1994 Alain Knaff - * Copyright (C) 1998 Alan Cox - */ -/* - * 02.12.91 - Changed to static variables to indicate need for reset - * and recalibrate. This makes some things easier (output_byte reset - * checking etc), and means less interrupt jumping in case of errors, - * so the code is hopefully easier to understand. - */ - -/* - * This file is certainly a mess. I've tried my best to get it working, - * but I don't like programming floppies, and I have only one anyway. - * Urgel. I should check for more errors, and do more graceful error - * recovery. Seems there are problems with several drives. I've tried to - * correct them. No promises. - */ - -/* - * As with hd.c, all routines within this file can (and will) be called - * by interrupts, so extreme caution is needed. A hardware interrupt - * handler may not sleep, or a kernel panic will happen. Thus I cannot - * call "floppy-on" directly, but have to set a special timer interrupt - * etc. - */ - -/* - * 28.02.92 - made track-buffering routines, based on the routines written - * by entropy@wintermute.wpi.edu (Lawrence Foard). Linus. - */ - -/* - * Automatic floppy-detection and formatting written by Werner Almesberger - * (almesber@nessie.cs.id.ethz.ch), who also corrected some problems with - * the floppy-change signal detection. - */ - -/* - * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed - * FDC data overrun bug, added some preliminary stuff for vertical - * recording support. - * - * 1992/9/17: Added DMA allocation & DMA functions. -- hhb. - * - * TODO: Errors are still not counted properly. - */ - -/* 1992/9/20 - * Modifications for ``Sector Shifting'' by Rob Hooft (hooft@chem.ruu.nl) - * modeled after the freeware MS-DOS program fdformat/88 V1.8 by - * Christoph H. Hochst\"atter. - * I have fixed the shift values to the ones I always use. Maybe a new - * ioctl() should be created to be able to modify them. - * There is a bug in the driver that makes it impossible to format a - * floppy as the first thing after bootup. - */ - -/* - * 1993/4/29 -- Linus -- cleaned up the timer handling in the kernel, and - * this helped the floppy driver as well. Much cleaner, and still seems to - * work. - */ - -/* 1994/6/24 --bbroad-- added the floppy table entries and made - * minor modifications to allow 2.88 floppies to be run. - */ - -/* 1994/7/13 -- Paul Vojta -- modified the probing code to allow three or more - * disk types. - */ - -/* - * 1994/8/8 -- Alain Knaff -- Switched to fdpatch driver: Support for bigger - * format bug fixes, but unfortunately some new bugs too... - */ - -/* 1994/9/17 -- Koen Holtman -- added logging of physical floppy write - * errors to allow safe writing by specialized programs. - */ - -/* 1995/4/24 -- Dan Fandrich -- added support for Commodore 1581 3.5" disks - * by defining bit 1 of the "stretch" parameter to mean put sectors on the - * opposite side of the disk, leaving the sector IDs alone (i.e. Commodore's - * drives are "upside-down"). - */ - -/* - * 1995/8/26 -- Andreas Busse -- added Mips support. - */ - -/* - * 1995/10/18 -- Ralf Baechle -- Portability cleanup; move machine dependent - * features to asm/floppy.h. - */ - -/* - * 1998/05/07 -- Russell King -- More portability cleanups; moved definition of - * interrupt and dma channel to asm/floppy.h. Cleaned up some formatting & - * use of '0' for NULL. - */ - -/* - * 1998/06/07 -- Alan Cox -- Merged the 2.0.34 fixes for resource allocation - * failures. - */ - -/* - * 1998/09/20 -- David Weinehall -- Added slow-down code for buggy PS/2-drives. - */ - -/* - * 1999/01/19 -- N.Fujita & Linux/98 Project -- Added code for NEC PC-9800 - * series. - */ - -/* - * 1999/08/13 -- Paul Slootman -- floppy stopped working on Alpha after 24 - * days, 6 hours, 32 minutes and 32 seconds (i.e. MAXINT jiffies; ints were - * being used to store jiffies, which are unsigned longs). - */ - -/* - * 2000/08/28 -- Arnaldo Carvalho de Melo - * - get rid of check_region - * - s/suser/capable/ - */ - -/* - * 2001/08/26 -- Paul Gortmaker - fix insmod oops on machines with no - * floppy controller (lingering task on list after module is gone... boom.) - */ - -/* - * 2002/02/07 -- Anton Altaparmakov - Fix io ports reservation to correct range - * (0x3f2-0x3f5, 0x3f7). This fix is a bit of a hack but the proper fix - * requires many non-obvious changes in arch dependent code. - */ - -/* - * 2002/10/12 -- Osamu Tomita - * split code from floppy.c - * support NEC PC-9800 only - */ - -#define FLOPPY_SANITY_CHECK -#undef FLOPPY_SILENT_DCL_CLEAR - -/* -#define PC9800_DEBUG_FLOPPY -#define PC9800_DEBUG_FLOPPY2 -*/ - -#define REALLY_SLOW_IO - -#define DEBUGT 2 -#define DCL_DEBUG /* debug disk change line */ - -/* do print messages for unexpected interrupts */ -static int print_unex=1; -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for the compatibility eject ioctl */ -#include - -/* - * 1998/1/21 -- Richard Gooch -- devfs support - */ - - -#include -#define FLOPPY98_MOTOR_MASK 0x08 - -#include -#define FD98_STATUS (0 + FD_IOPORT ) -#define FD98_DATA (2 + FD_IOPORT ) -#define FD_MODE (4 + FD_IOPORT ) -#define FD_MODE_CHANGE 0xbe -#define FD_EMODE_CHANGE 0x4be - -#include -#include -#include -#include -#include -#include -#include -#include /* CMOS defines */ -#include -#include -#include -#include -#include -#include /* for invalidate_buffers() */ - -/* - * PS/2 floppies have much slower step rates than regular floppies. - * It's been recommended that take about 1/4 of the default speed - * in some more extreme cases. - */ -static int slow_floppy; - -#include -#include -#include -#include -#include - -#ifndef DEFAULT_FLOPPY_IRQ -# define DEFAULT_FLOPPY_IRQ 11 -#endif -#ifndef DEFAULT_FLOPPY_DMA -# define DEFAULT_FLOPPY_DMA 2 -#endif - -static int FLOPPY_IRQ=DEFAULT_FLOPPY_IRQ; -static int FLOPPY_DMA=DEFAULT_FLOPPY_DMA; -static int can_use_virtual_dma=2; -static int auto_detect_mode = 0; -static int retry_auto_detect = 0; -#define FD_AFTER_RESET_DELAY 1000 - -/* ======= - * can use virtual DMA: - * 0 = use of virtual DMA disallowed by config - * 1 = use of virtual DMA prescribed by config - * 2 = no virtual DMA preference configured. By default try hard DMA, - * but fall back on virtual DMA when not enough memory available - */ - -static int use_virtual_dma; -/* ======= - * use virtual DMA - * 0 using hard DMA - * 1 using virtual DMA - * This variable is set to virtual when a DMA mem problem arises, and - * reset back in floppy_grab_irq_and_dma. - * It is not safe to reset it in other circumstances, because the floppy - * driver may have several buffers in use at once, and we do currently not - * record each buffers capabilities - */ - -static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED; -static struct completion device_release; - -static unsigned short virtual_dma_port=0x3f0; -irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs); -static int set_mode(char mask, char data); -static void register_devfs_entries (int drive) __init; - -#define K_64 0x10000 /* 64KB */ - -/* the following is the mask of allowed drives. By default units 2 and - * 3 of both floppy controllers are disabled, because switching on the - * motor of these drives causes system hangs on some PCI computers. drive - * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if - * a drive is allowed. - * - * NOTE: This must come before we include the arch floppy header because - * some ports reference this variable from there. -DaveM - */ - -static int allowed_drive_mask = 0x0f; - -#include - -static int irqdma_allocated; - -#define LOCAL_END_REQUEST -#define DEVICE_NAME "floppy" - -#include -#include /* for the compatibility eject ioctl */ -#include - -static struct request *current_req; -static struct request_queue *floppy_queue; - -#ifndef fd_get_dma_residue -#define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) -#endif - -/* Dma Memory related stuff */ - -#ifndef fd_dma_mem_free -#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size)) -#endif - -#ifndef fd_dma_mem_alloc -#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size)) -#endif - -static inline void fallback_on_nodma_alloc(char **addr, size_t l) -{ -#ifdef FLOPPY_CAN_FALLBACK_ON_NODMA - if (*addr) - return; /* we have the memory */ - if (can_use_virtual_dma != 2) - return; /* no fallback allowed */ - printk("DMA memory shortage. Temporarily falling back on virtual DMA\n"); - *addr = (char *) nodma_mem_alloc(l); -#else - return; -#endif -} - -/* End dma memory related stuff */ - -static unsigned long fake_change; -static int initialising=1; - -#define ITYPE(x) (((x)>>2) & 0x1f) -#define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) -#define UNIT(x) ((x) & 0x03) /* drive on fdc */ -#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ -#define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2)) - /* reverse mapping from unit and fdc to drive */ -#define DP (&drive_params[current_drive]) -#define DRS (&drive_state[current_drive]) -#define DRWE (&write_errors[current_drive]) -#define FDCS (&fdc_state[fdc]) -#define CLEARF(x) (clear_bit(x##_BIT, &DRS->flags)) -#define SETF(x) (set_bit(x##_BIT, &DRS->flags)) -#define TESTF(x) (test_bit(x##_BIT, &DRS->flags)) - -#define UDP (&drive_params[drive]) -#define UDRS (&drive_state[drive]) -#define UDRWE (&write_errors[drive]) -#define UFDCS (&fdc_state[FDC(drive)]) -#define UCLEARF(x) (clear_bit(x##_BIT, &UDRS->flags)) -#define USETF(x) (set_bit(x##_BIT, &UDRS->flags)) -#define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags)) - -#define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args) - -#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2) -#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH) - -#define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x))) - -/* read/write */ -#define COMMAND raw_cmd->cmd[0] -#define DR_SELECT raw_cmd->cmd[1] -#define TRACK raw_cmd->cmd[2] -#define HEAD raw_cmd->cmd[3] -#define SECTOR raw_cmd->cmd[4] -#define SIZECODE raw_cmd->cmd[5] -#define SECT_PER_TRACK raw_cmd->cmd[6] -#define GAP raw_cmd->cmd[7] -#define SIZECODE2 raw_cmd->cmd[8] -#define NR_RW 9 - -/* format */ -#define F_SIZECODE raw_cmd->cmd[2] -#define F_SECT_PER_TRACK raw_cmd->cmd[3] -#define F_GAP raw_cmd->cmd[4] -#define F_FILL raw_cmd->cmd[5] -#define NR_F 6 - -/* - * Maximum disk size (in kilobytes). This default is used whenever the - * current disk size is unknown. - * [Now it is rather a minimum] - */ -#define MAX_DISK_SIZE 4 /* 3984*/ - - -/* - * globals used by 'result()' - */ -#define MAX_REPLIES 16 -static unsigned char reply_buffer[MAX_REPLIES]; -static int inr; /* size of reply buffer, when called from interrupt */ -#define ST0 (reply_buffer[0]) -#define ST1 (reply_buffer[1]) -#define ST2 (reply_buffer[2]) -#define ST3 (reply_buffer[0]) /* result of GETSTATUS */ -#define R_TRACK (reply_buffer[3]) -#define R_HEAD (reply_buffer[4]) -#define R_SECTOR (reply_buffer[5]) -#define R_SIZECODE (reply_buffer[6]) - -#define SEL_DLY (2*HZ/100) - -/* - * this struct defines the different floppy drive types. - */ -static struct { - struct floppy_drive_params params; - const char *name; /* name printed while booting */ -} default_drive_params[]= { -/* NOTE: the time values in jiffies should be in msec! - CMOS drive type - | Maximum data rate supported by drive type - | | Head load time, msec - | | | Head unload time, msec (not used) - | | | | Step rate interval, usec - | | | | | Time needed for spinup time (jiffies) - | | | | | | Timeout for spinning down (jiffies) - | | | | | | | Spindown offset (where disk stops) - | | | | | | | | Select delay - | | | | | | | | | RPS - | | | | | | | | | | Max number of tracks - | | | | | | | | | | | Interrupt timeout - | | | | | | | | | | | | Max nonintlv. sectors - | | | | | | | | | | | | | -Max Errors- flags */ -{{0, 500, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0, - 0, { 7, 4, 8, 2, 1, 5, 3,10}, 3*HZ/2, 0 }, "unknown" }, - -{{1, 300, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0, - 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/ - -{{2, 500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0, - 0, { 2, 6, 4, 0, 0, 0, 0, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/ - -{{3, 250, 16, 16, 3000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, - 0, { 4, 6, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/ - -{{4, 500, 16, 16, 4000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, - 0, { 7,10, 2, 4, 6, 0, 0, 0}, 3*HZ/2, 7 }, "1.44M" }, /*3 1/2 HD*/ - -{{5, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0, - 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M AMI BIOS" }, /*3 1/2 ED*/ - -{{6, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0, - 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M" } /*3 1/2 ED*/ -/* | --autodetected formats--- | | | - * read_track | | Name printed when booting - * | Native format - * Frequency of disk change checks */ -}; - -static struct floppy_drive_params drive_params[N_DRIVE]; -static struct floppy_drive_struct drive_state[N_DRIVE]; -static struct floppy_write_errors write_errors[N_DRIVE]; -static struct timer_list motor_off_timer[N_DRIVE]; -static struct gendisk *disks[N_DRIVE]; -static struct block_device *opened_bdev[N_DRIVE]; -static DECLARE_MUTEX(open_lock); -static struct floppy_raw_cmd *raw_cmd, default_raw_cmd; - -/* - * This struct defines the different floppy types. - * - * Bit 0 of 'stretch' tells if the tracks need to be doubled for some - * types (e.g. 360kB diskette in 1.2MB drive, etc.). Bit 1 of 'stretch' - * tells if the disk is in Commodore 1581 format, which means side 0 sectors - * are located on side 1 of the disk but with a side 0 ID, and vice-versa. - * This is the same as the Sharp MZ-80 5.25" CP/M disk format, except that the - * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical - * side 0 is on physical side 0 (but with the misnamed sector IDs). - * 'stretch' should probably be renamed to something more general, like - * 'options'. Other parameters should be self-explanatory (see also - * setfdprm(8)). - */ -/* - Size - | Sectors per track - | | Head - | | | Tracks - | | | | Stretch - | | | | | Gap 1 size - | | | | | | Data rate, | 0x40 for perp - | | | | | | | Spec1 (stepping rate, head unload - | | | | | | | | /fmt gap (gap2) */ -static struct floppy_struct floppy_type[32] = { - { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL }, /* 0 no testing */ -#if 0 - { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360" }, /* 1 360KB PC */ -#else - { 2464,16,2,77,0,0x35,0x48,0xDF,0x74,"d360" }, /* 1 1.25MB 98 */ -#endif - { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" }, /* 2 1.2MB AT */ - { 720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360" }, /* 3 360KB SS 3.5" */ - { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720" }, /* 4 720KB 3.5" */ - { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360" }, /* 5 360KB AT */ - { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720" }, /* 6 720KB AT */ - { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" }, /* 7 1.44MB 3.5" */ - { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" }, /* 8 2.88MB 3.5" */ - { 6240,39,2,80,0,0x1B,0x43,0xAF,0x28,"E3120" }, /* 9 3.12MB 3.5" */ - - { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" }, /* 10 1.44MB 5.25" */ - { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" }, /* 11 1.68MB 3.5" */ - { 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" }, /* 12 410KB 5.25" */ - { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" }, /* 13 820KB 3.5" */ - { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" }, /* 14 1.48MB 5.25" */ - { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" }, /* 15 1.72MB 3.5" */ - { 840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420" }, /* 16 420KB 5.25" */ - { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830" }, /* 17 830KB 3.5" */ - { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" }, /* 18 1.49MB 5.25" */ - { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" }, /* 19 1.74 MB 3.5" */ - - { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880" }, /* 20 880KB 5.25" */ - { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" }, /* 21 1.04MB 3.5" */ - { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" }, /* 22 1.12MB 3.5" */ - { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" }, /* 23 1.6MB 5.25" */ - { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" }, /* 24 1.76MB 3.5" */ - { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" }, /* 25 1.92MB 3.5" */ - { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5" */ - { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5" */ - { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5" */ - - { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5" */ - { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */ - { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */ -}; - -#define NUMBER(x) (sizeof(x) / sizeof(*(x))) -#define SECTSIZE (_FD_SECTSIZE(*floppy)) - -/* Auto-detection: Disk type used until the next media change occurs. */ -static struct floppy_struct *current_type[N_DRIVE]; - -/* - * User-provided type information. current_type points to - * the respective entry of this array. - */ -static struct floppy_struct user_params[N_DRIVE]; - -static sector_t floppy_sizes[256]; - -/* - * The driver is trying to determine the correct media format - * while probing is set. rw_interrupt() clears it after a - * successful access. - */ -static int probing; - -/* Synchronization of FDC access. */ -#define FD_COMMAND_NONE -1 -#define FD_COMMAND_ERROR 2 -#define FD_COMMAND_OKAY 3 - -static volatile int command_status = FD_COMMAND_NONE; -static unsigned long fdc_busy; -static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); -static DECLARE_WAIT_QUEUE_HEAD(command_done); - -#define NO_SIGNAL (!interruptible || !signal_pending(current)) -#define CALL(x) if ((x) == -EINTR) return -EINTR -#define ECALL(x) if ((ret = (x))) return ret; -#define _WAIT(x,i) CALL(ret=wait_til_done((x),i)) -#define WAIT(x) _WAIT((x),interruptible) -#define IWAIT(x) _WAIT((x),1) - -/* Errors during formatting are counted here. */ -static int format_errors; - -/* Format request descriptor. */ -static struct format_descr format_req; - -/* - * Rate is 0 for 500kb/s, 1 for 300kbps, 2 for 250kbps - * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc), - * H is head unload time (1=16ms, 2=32ms, etc) - */ - -/* - * Track buffer - * Because these are written to by the DMA controller, they must - * not contain a 64k byte boundary crossing, or data will be - * corrupted/lost. - */ -static char *floppy_track_buffer; -static int max_buffer_sectors; - -static int *errors; -typedef void (*done_f)(int); -static struct cont_t { - void (*interrupt)(void); /* this is called after the interrupt of the - * main command */ - void (*redo)(void); /* this is called to retry the operation */ - void (*error)(void); /* this is called to tally an error */ - done_f done; /* this is called to say if the operation has - * succeeded/failed */ -} *cont; - -static void floppy_ready(void); -static void floppy_start(void); -static void process_fd_request(void); -static void recalibrate_floppy(void); -static void floppy_shutdown(unsigned long); - -static int floppy_grab_irq_and_dma(void); -static void floppy_release_irq_and_dma(void); - -/* - * The "reset" variable should be tested whenever an interrupt is scheduled, - * after the commands have been sent. This is to ensure that the driver doesn't - * get wedged when the interrupt doesn't come because of a failed command. - * reset doesn't need to be tested before sending commands, because - * output_byte is automatically disabled when reset is set. - */ -#define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } } -static void reset_fdc(void); - -/* - * These are global variables, as that's the easiest way to give - * information to interrupts. They are the data used for the current - * request. - */ -#define NO_TRACK -1 -#define NEED_1_RECAL -2 -#define NEED_2_RECAL -3 - -static int usage_count; - -/* buffer related variables */ -static int buffer_track = -1; -static int buffer_drive = -1; -static int buffer_min = -1; -static int buffer_max = -1; - -/* fdc related variables, should end up in a struct */ -static struct floppy_fdc_state fdc_state[N_FDC]; -static int fdc; /* current fdc */ - -static struct floppy_struct *_floppy = floppy_type; -static unsigned char current_drive; -static long current_count_sectors; -static unsigned char fsector_t; /* sector in track */ -static unsigned char in_sector_offset; /* offset within physical sector, - * expressed in units of 512 bytes */ - -#ifndef fd_eject -static inline int fd_eject(int drive) -{ - return -EINVAL; -} -#endif - -#ifdef DEBUGT -static long unsigned debugtimer; -#endif - -/* - * Debugging - * ========= - */ -static inline void set_debugt(void) -{ -#ifdef DEBUGT - debugtimer = jiffies; -#endif -} - -static inline void debugt(const char *message) -{ -#ifdef DEBUGT - if (DP->flags & DEBUGT) - printk("%s dtime=%lu\n", message, jiffies-debugtimer); -#endif -} - -typedef void (*timeout_fn)(unsigned long); -static struct timer_list fd_timeout = TIMER_INITIALIZER(floppy_shutdown, 0, 0); - -static const char *timeout_message; - -#ifdef FLOPPY_SANITY_CHECK -static void is_alive(const char *message) -{ - /* this routine checks whether the floppy driver is "alive" */ - if (fdc_busy && command_status < 2 && !timer_pending(&fd_timeout)){ - DPRINT("timeout handler died: %s\n",message); - } -} -#endif - -static void (*do_floppy)(void) = NULL; - -#ifdef FLOPPY_SANITY_CHECK - -#define OLOGSIZE 20 - -static void (*lasthandler)(void); -static unsigned long interruptjiffies; -static unsigned long resultjiffies; -static int resultsize; -static unsigned long lastredo; - -static struct output_log { - unsigned char data; - unsigned char status; - unsigned long jiffies; -} output_log[OLOGSIZE]; - -static int output_log_pos; -#endif - -#define current_reqD -1 -#define MAXTIMEOUT -2 - -static void reschedule_timeout(int drive, const char *message, int marg) -{ - unsigned long delay; - - if (drive == current_reqD) - drive = current_drive; - if (drive < 0 || drive > N_DRIVE) { - delay = 20UL*HZ; - drive=0; - } else - delay = UDP->timeout; - mod_timer(&fd_timeout, delay + jiffies); - if (UDP->flags & FD_DEBUG){ - DPRINT("reschedule timeout "); - printk(message, marg); - printk("\n"); - } - timeout_message = message; -} - -static int maximum(int a, int b) -{ - if (a > b) - return a; - else - return b; -} -#define INFBOUND(a,b) (a)=maximum((a),(b)); - -static int minimum(int a, int b) -{ - if (a < b) - return a; - else - return b; -} -#define SUPBOUND(a,b) (a)=minimum((a),(b)); - - -/* - * Bottom half floppy driver. - * ========================== - * - * This part of the file contains the code talking directly to the hardware, - * and also the main service loop (seek-configure-spinup-command) - */ - -/* - * disk change. - * This routine is responsible for maintaining the FD_DISK_CHANGE flag, - * and the last_checked date. - * - * last_checked is the date of the last check which showed 'no disk change' - * FD_DISK_CHANGE is set under two conditions: - * 1. The floppy has been changed after some i/o to that floppy already - * took place. - * 2. No floppy disk is in the drive. This is done in order to ensure that - * requests are quickly flushed in case there is no disk in the drive. It - * follows that FD_DISK_CHANGE can only be cleared if there is a disk in - * the drive. - * - * For 1., maxblock is observed. Maxblock is 0 if no i/o has taken place yet. - * For 2., FD_DISK_NEWCHANGE is watched. FD_DISK_NEWCHANGE is cleared on - * each seek. If a disk is present, the disk change line should also be - * cleared on each seek. Thus, if FD_DISK_NEWCHANGE is clear, but the disk - * change line is set, this means either that no disk is in the drive, or - * that it has been removed since the last seek. - * - * This means that we really have a third possibility too: - * The floppy has been changed after the last seek. - */ - -static int disk_change(int drive) -{ - return UTESTF(FD_DISK_CHANGED); -} - -static int set_mode(char mask, char data) -{ - register unsigned char newdor, olddor; - - olddor = FDCS->dor; - newdor = (olddor & mask) | data; - if (newdor != olddor) { - FDCS->dor = newdor; - fd_outb(newdor, FD_MODE); - } - - if (newdor & FLOPPY98_MOTOR_MASK) - floppy_grab_irq_and_dma(); - - if (olddor & FLOPPY98_MOTOR_MASK) - floppy_release_irq_and_dma(); - - return olddor; -} - -static void twaddle(void) -{ - if (DP->select_delay) - return; - - fd_outb(FDCS->dor & 0xf7, FD_MODE); - fd_outb(FDCS->dor, FD_MODE); - DRS->select_date = jiffies; -} - -/* reset all driver information about the current fdc. This is needed after - * a reset, and after a raw command. */ -static void reset_fdc_info(int mode) -{ - int drive; - - FDCS->spec1 = FDCS->spec2 = -1; - FDCS->need_configure = 1; - FDCS->perp_mode = 1; - FDCS->rawcmd = 0; - for (drive = 0; drive < N_DRIVE; drive++) - if (FDC(drive) == fdc && - (mode || UDRS->track != NEED_1_RECAL)) - UDRS->track = NEED_2_RECAL; -} - -/* selects the fdc and drive, and enables the fdc's input/dma. */ -static void set_fdc(int drive) -{ - fdc = 0; - current_drive = drive; - set_mode(~0, 0x10); - if (FDCS->rawcmd == 2) - reset_fdc_info(1); - - if (fd_inb(FD98_STATUS) != STATUS_READY) - FDCS->reset = 1; -} - -/* locks the driver */ -static int _lock_fdc(int drive, int interruptible, int line) -{ - if (!usage_count){ - printk(KERN_ERR "Trying to lock fdc while usage count=0 at line %d\n", line); - return -1; - } - if(floppy_grab_irq_and_dma()==-1) - return -EBUSY; - - if (test_and_set_bit(0, &fdc_busy)) { - DECLARE_WAITQUEUE(wait, current); - add_wait_queue(&fdc_wait, &wait); - - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - - if (!test_and_set_bit(0, &fdc_busy)) - break; - - schedule(); - - if (!NO_SIGNAL) { - remove_wait_queue(&fdc_wait, &wait); - return -EINTR; - } - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&fdc_wait, &wait); - } - command_status = FD_COMMAND_NONE; - - reschedule_timeout(drive, "lock fdc", 0); - set_fdc(drive); - return 0; -} - -#define lock_fdc(drive,interruptible) _lock_fdc(drive,interruptible, __LINE__) - -#define LOCK_FDC(drive,interruptible) \ -if (lock_fdc(drive,interruptible)) return -EINTR; - - -/* unlocks the driver */ -static inline void unlock_fdc(void) -{ - raw_cmd = 0; - if (!fdc_busy) - DPRINT("FDC access conflict!\n"); - - if (do_floppy) - DPRINT("device interrupt still active at FDC release: %p!\n", - do_floppy); - command_status = FD_COMMAND_NONE; - del_timer(&fd_timeout); - cont = NULL; - clear_bit(0, &fdc_busy); - floppy_release_irq_and_dma(); - wake_up(&fdc_wait); -} - -#ifndef CONFIG_PC9800_MOTOR_OFF /* tomita */ - -/* switches the motor off after a given timeout */ -static void motor_off_callback(unsigned long nr) -{ - printk(KERN_DEBUG "fdc%lu: turn off motor\n", nr); -} - -/* schedules motor off */ -static void floppy_off(unsigned int drive) -{ -} - -#else /* CONFIG_PC9800_MOTOR_OFF */ - -/* switches the motor off after a given timeout */ -static void motor_off_callback(unsigned long fdc) -{ - printk(KERN_DEBUG "fdc%u: turn off motor\n", (unsigned int) fdc); - - fd_outb(0, FD_MODE); /* MTON = 0 */ -} - -static struct timer_list motor_off_timer[N_FDC] = { - { data: 0, function: motor_off_callback }, -#if N_FDC > 1 - { data: 1, function: motor_off_callback }, -#endif -#if N_FDC > 2 -# error "N_FDC > 2; please fix initializer for motor_off_timer[]" -#endif -}; - -/* schedules motor off */ -static void floppy_off(unsigned int drive) -{ - unsigned long volatile delta; - register int fdc = FDC(drive); - - if (!(FDCS->dor & (0x10 << UNIT(drive)))) - return; - - del_timer(motor_off_timer + fdc); - -#if 0 - /* make spindle stop in a position which minimizes spinup time - * next time */ - if (UDP->rps){ - delta = jiffies - UDRS->first_read_date + HZ - - UDP->spindown_offset; - delta = ((delta * UDP->rps) % HZ) / UDP->rps; - motor_off_timer[drive].expires = jiffies + UDP->spindown - delta; - } -#else - if (UDP->rps) - motor_off_timer[drive].expires = jiffies + UDP->spindown; -#endif - - add_timer(motor_off_timer + fdc); -} - -#endif /* CONFIG_PC9800_MOTOR_OFF */ - -/* - * cycle through all N_DRIVE floppy drives, for disk change testing. - * stopping at current drive. This is done before any long operation, to - * be sure to have up to date disk change information. - */ -static void scandrives(void) -{ - int i, drive, saved_drive; - - if (DP->select_delay) - return; - - saved_drive = current_drive; - for (i=0; i < N_DRIVE; i++){ - drive = (saved_drive + i + 1) % N_DRIVE; - if (UDRS->fd_ref == 0 || UDP->select_delay != 0) - continue; /* skip closed drives */ - set_fdc(drive); - } - set_fdc(saved_drive); -} - -static void empty(void) -{ -} - -static DECLARE_WORK(floppy_work, NULL, NULL); - -static void schedule_bh(void (*handler) (void)) -{ - PREPARE_WORK(&floppy_work, (void (*)(void *))handler, NULL); - schedule_work(&floppy_work); -} - -static struct timer_list fd_timer = TIMER_INITIALIZER(NULL, 0, 0); - -static void cancel_activity(void) -{ - do_floppy = NULL; - PREPARE_WORK(&floppy_work, (void*)(void*)empty, NULL); - del_timer(&fd_timer); -} - -/* this function makes sure that the disk stays in the drive during the - * transfer */ -static void fd_watchdog(void) -{ -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("calling disk change from watchdog\n"); - } -#endif - - if (disk_change(current_drive)){ - DPRINT("disk removed during i/o\n"); - cancel_activity(); - cont->done(0); - reset_fdc(); - } else { - del_timer(&fd_timer); - fd_timer.function = (timeout_fn) fd_watchdog; - fd_timer.expires = jiffies + HZ / 10; - add_timer(&fd_timer); - } -} - -static void main_command_interrupt(void) -{ - del_timer(&fd_timer); - cont->interrupt(); -} - -/* waits for a delay (spinup or select) to pass */ -static int fd_wait_for_completion(unsigned long delay, timeout_fn function) -{ - if (FDCS->reset){ - reset_fdc(); /* do the reset during sleep to win time - * if we don't need to sleep, it's a good - * occasion anyways */ - return 1; - } - - if ((signed) (jiffies - delay) < 0){ - del_timer(&fd_timer); - fd_timer.function = function; - fd_timer.expires = delay; - add_timer(&fd_timer); - return 1; - } - return 0; -} - -static spinlock_t floppy_hlt_lock = SPIN_LOCK_UNLOCKED; -static int hlt_disabled; -static void floppy_disable_hlt(void) -{ - unsigned long flags; - - spin_lock_irqsave(&floppy_hlt_lock, flags); - if (!hlt_disabled) { - hlt_disabled=1; -#ifdef HAVE_DISABLE_HLT - disable_hlt(); -#endif - } - spin_unlock_irqrestore(&floppy_hlt_lock, flags); -} - -static void floppy_enable_hlt(void) -{ - unsigned long flags; - - spin_lock_irqsave(&floppy_hlt_lock, flags); - if (hlt_disabled){ - hlt_disabled=0; -#ifdef HAVE_DISABLE_HLT - enable_hlt(); -#endif - } - spin_unlock_irqrestore(&floppy_hlt_lock, flags); -} - - -static void setup_DMA(void) -{ - unsigned long f; - -#ifdef FLOPPY_SANITY_CHECK - if (raw_cmd->length == 0){ - int i; - - printk("zero dma transfer size:"); - for (i=0; i < raw_cmd->cmd_count; i++) - printk("%x,", raw_cmd->cmd[i]); - printk("\n"); - cont->done(0); - FDCS->reset = 1; - return; - } - if (((unsigned long) raw_cmd->kernel_data) % 512){ - printk("non aligned address: %p\n", raw_cmd->kernel_data); - cont->done(0); - FDCS->reset=1; - return; - } -#endif - f=claim_dma_lock(); - fd_disable_dma(); -#ifdef fd_dma_setup - if (fd_dma_setup(raw_cmd->kernel_data, raw_cmd->length, - (raw_cmd->flags & FD_RAW_READ)? - DMA_MODE_READ : DMA_MODE_WRITE, - FDCS->address) < 0) { - release_dma_lock(f); - cont->done(0); - FDCS->reset=1; - return; - } - release_dma_lock(f); -#else - fd_clear_dma_ff(); - fd_cacheflush(raw_cmd->kernel_data, raw_cmd->length); - fd_set_dma_mode((raw_cmd->flags & FD_RAW_READ)? - DMA_MODE_READ : DMA_MODE_WRITE); - fd_set_dma_addr(raw_cmd->kernel_data); - fd_set_dma_count(raw_cmd->length); - virtual_dma_port = FDCS->address; - fd_enable_dma(); - release_dma_lock(f); -#endif - floppy_disable_hlt(); -} - -static void show_floppy(void); - -/* waits until the fdc becomes ready */ - -#ifdef PC9800_DEBUG_FLOPPY -#define READY_DELAY 10000000 -#else -#define READY_DELAY 100000 -#endif - -static int wait_til_ready(void) -{ - int counter, status; - if (FDCS->reset) - return -1; - for (counter = 0; counter < READY_DELAY; counter++) { - status = fd_inb(FD98_STATUS); - if (status & STATUS_READY) - return status; - } - if (!initialising) { - DPRINT("Getstatus times out (%x) on fdc %d\n", - status, fdc); - show_floppy(); - } - FDCS->reset = 1; - return -1; -} - -/* sends a command byte to the fdc */ -static int output_byte(char byte) -{ - int status; - - if ((status = wait_til_ready()) < 0) - return -1; - if ((status & (STATUS_READY|STATUS_DIR|STATUS_DMA)) == STATUS_READY){ - fd_outb(byte,FD98_DATA); -#ifdef FLOPPY_SANITY_CHECK - output_log[output_log_pos].data = byte; - output_log[output_log_pos].status = status; - output_log[output_log_pos].jiffies = jiffies; - output_log_pos = (output_log_pos + 1) % OLOGSIZE; -#endif - return 0; - } - FDCS->reset = 1; - if (!initialising) { - DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n", - byte, fdc, status); - show_floppy(); - } - return -1; -} -#define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;} - -/* gets the response from the fdc */ -static int result(void) -{ - int i, status=0; - - for(i=0; i < MAX_REPLIES; i++) { - if ((status = wait_til_ready()) < 0) - break; - status &= STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA; - if ((status & ~STATUS_BUSY) == STATUS_READY){ -#ifdef FLOPPY_SANITY_CHECK - resultjiffies = jiffies; - resultsize = i; -#endif - return i; - } - if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) - reply_buffer[i] = fd_inb(FD98_DATA); - else - break; - } - if (!initialising) { - DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n", - fdc, status, i); - show_floppy(); - } - FDCS->reset = 1; - return -1; -} - -static int fifo_depth = 0xa; -static int no_fifo; - -#define NOMINAL_DTR 500 - -/* Issue a "SPECIFY" command to set the step rate time, head unload time, - * head load time, and DMA disable flag to values needed by floppy. - * - * The value "dtr" is the data transfer rate in Kbps. It is needed - * to account for the data rate-based scaling done by the 82072 and 82077 - * FDC types. This parameter is ignored for other types of FDCs (i.e. - * 8272a). - * - * Note that changing the data transfer rate has a (probably deleterious) - * effect on the parameters subject to scaling for 82072/82077 FDCs, so - * fdc_specify is called again after each data transfer rate - * change. - * - * srt: 1000 to 16000 in microseconds - * hut: 16 to 240 milliseconds - * hlt: 2 to 254 milliseconds - * - * These values are rounded up to the next highest available delay time. - */ -static void fdc_specify(void) -{ - output_byte(FD_SPECIFY); - output_byte(FDCS->spec1 = 0xdf); - output_byte(FDCS->spec2 = 0x24); -} - -static void tell_sector(void) -{ - printk(": track %d, head %d, sector %d, size %d", - R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE); -} /* tell_sector */ - -static int auto_detect_mode_pc9800(void) -{ -#ifdef PC9800_DEBUG_FLOPPY - printk("auto_detect_mode_pc9800: retry_auto_detect=%d\n", - retry_auto_detect); -#endif - if (retry_auto_detect > 4) { - retry_auto_detect = 0; - return 1; - } - - switch ((int)(_floppy - floppy_type)) { - case 2: - _floppy = floppy_type + 4; - break; - - case 4: - case 6: - _floppy = floppy_type + 7; - break; - - case 7: - case 10: - _floppy = floppy_type + 2; - break; - - default: - _floppy = floppy_type + 7; - } - - retry_auto_detect++; - return 0; -} - -static void access_mode_change_pc9800(void); - -/* - * OK, this error interpreting routine is called after a - * DMA read/write has succeeded - * or failed, so we check the results, and copy any buffers. - * hhb: Added better error reporting. - * ak: Made this into a separate routine. - */ -static int interpret_errors(void) -{ - char bad; - - if (inr!=7) { - DPRINT("-- FDC reply error"); - FDCS->reset = 1; - return 1; - } - - /* check IC to find cause of interrupt */ - switch (ST0 & ST0_INTR) { - case 0x40: /* error occurred during command execution */ - if (ST1 & ST1_EOC) - return 0; /* occurs with pseudo-DMA */ - bad = 1; - if (ST1 & ST1_WP) { - DPRINT("Drive is write protected\n"); - CLEARF(FD_DISK_WRITABLE); - cont->done(0); - bad = 2; - } else if (ST1 & ST1_ND) { - SETF(FD_NEED_TWADDLE); - } else if (ST1 & ST1_OR) { - if (DP->flags & FTD_MSG) - DPRINT("Over/Underrun - retrying\n"); - bad = 0; - }else if (*errors >= DP->max_errors.reporting){ - if (ST0 & ST0_ECE) { - printk("Recalibrate failed!"); - } else if (ST2 & ST2_CRC) { - printk("data CRC error"); - tell_sector(); - } else if (ST1 & ST1_CRC) { - printk("CRC error"); - tell_sector(); - } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) { - if (auto_detect_mode) { - bad = (char)auto_detect_mode_pc9800(); - access_mode_change_pc9800(); - } - - if (bad) { - printk("floppy error: MA: _floppy - floppy_type=%d\n", (int)(_floppy - floppy_type)); - printk("bad=%d\n", (int)bad); - if (!probing) { - printk("sector not found"); - tell_sector(); - } else - printk("probe failed..."); - } - } else if (ST2 & ST2_WC) { /* seek error */ - printk("wrong cylinder"); - } else if (ST2 & ST2_BC) { /* cylinder marked as bad */ - printk("bad cylinder"); - } else { - printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2); - tell_sector(); - } - printk("\n"); - - } - if (ST2 & ST2_WC || ST2 & ST2_BC) - /* wrong cylinder => recal */ - DRS->track = NEED_2_RECAL; - return bad; - case 0x80: /* invalid command given */ - DPRINT("Invalid FDC command given!\n"); - cont->done(0); - return 2; - case 0xc0: - SETF(FD_DISK_CHANGED); - SETF(FD_DISK_WRITABLE); - DPRINT("Abnormal termination caused by polling\n"); - cont->error(); - return 2; - default: /* (0) Normal command termination */ - auto_detect_mode = 0; - return 0; - } -} - -/* - * This routine is called when everything should be correctly set up - * for the transfer (i.e. floppy motor is on, the correct floppy is - * selected, and the head is sitting on the right track). - */ -static void setup_rw_floppy(void) -{ - int i,r, flags,dflags; - unsigned long ready_date; - timeout_fn function; - - access_mode_change_pc9800(); - flags = raw_cmd->flags; - if (flags & (FD_RAW_READ | FD_RAW_WRITE)) - flags |= FD_RAW_INTR; - - if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){ - ready_date = DRS->spinup_date + DP->spinup; - /* If spinup will take a long time, rerun scandrives - * again just before spinup completion. Beware that - * after scandrives, we must again wait for selection. - */ - if ((signed) (ready_date - jiffies) > DP->select_delay){ - ready_date -= DP->select_delay; - function = (timeout_fn) floppy_start; - } else - function = (timeout_fn) setup_rw_floppy; - - /* wait until the floppy is spinning fast enough */ - if (fd_wait_for_completion(ready_date,function)) - return; - } - dflags = DRS->flags; - - if ((flags & FD_RAW_READ) || (flags & FD_RAW_WRITE)) - setup_DMA(); - - if (flags & FD_RAW_INTR) - do_floppy = main_command_interrupt; - - r=0; - for (i=0; i< raw_cmd->cmd_count; i++) - r|=output_byte(raw_cmd->cmd[i]); - -#ifdef DEBUGT - debugt("rw_command: "); -#endif - if (r){ - cont->error(); - reset_fdc(); - return; - } - - if (!(flags & FD_RAW_INTR)){ - inr = result(); - cont->interrupt(); - } else if (flags & FD_RAW_NEED_DISK) - fd_watchdog(); -} - -static int blind_seek; - -/* - * This is the routine called after every seek (or recalibrate) interrupt - * from the floppy controller. - */ -static void seek_interrupt(void) -{ -#ifdef DEBUGT - debugt("seek interrupt:"); -#endif - if (inr != 2 || (ST0 & 0xF8) != 0x20) { - DRS->track = NEED_2_RECAL; - cont->error(); - cont->redo(); - return; - } - if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek){ -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("clearing NEWCHANGE flag because of effective seek\n"); - DPRINT("jiffies=%lu\n", jiffies); - } -#endif - CLEARF(FD_DISK_NEWCHANGE); /* effective seek */ - CLEARF(FD_DISK_CHANGED); /* effective seek */ - DRS->select_date = jiffies; - } - DRS->track = ST1; - floppy_ready(); -} - -static void check_wp(void) -{ - if (TESTF(FD_VERIFY)) { - /* check write protection */ - output_byte(FD_GETSTATUS); - output_byte(UNIT(current_drive)); - if (result() != 1){ - FDCS->reset = 1; - return; - } - CLEARF(FD_VERIFY); - CLEARF(FD_NEED_TWADDLE); -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("checking whether disk is write protected\n"); - DPRINT("wp=%x\n",ST3 & 0x40); - } -#endif - if (!(ST3 & 0x40)) - SETF(FD_DISK_WRITABLE); - else - CLEARF(FD_DISK_WRITABLE); - } -} - -static void seek_floppy(void) -{ - int track; - - blind_seek=0; - -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("calling disk change from seek\n"); - } -#endif - - if (!TESTF(FD_DISK_NEWCHANGE) && - disk_change(current_drive) && - (raw_cmd->flags & FD_RAW_NEED_DISK)){ - /* the media changed flag should be cleared after the seek. - * If it isn't, this means that there is really no disk in - * the drive. - */ - SETF(FD_DISK_CHANGED); - cont->done(0); - cont->redo(); - return; - } - if (DRS->track <= NEED_1_RECAL){ - recalibrate_floppy(); - return; - } else if (TESTF(FD_DISK_NEWCHANGE) && - (raw_cmd->flags & FD_RAW_NEED_DISK) && - (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) { - /* we seek to clear the media-changed condition. Does anybody - * know a more elegant way, which works on all drives? */ - if (raw_cmd->track) - track = raw_cmd->track - 1; - else { - if (DP->flags & FD_SILENT_DCL_CLEAR){ - blind_seek = 1; - raw_cmd->flags |= FD_RAW_NEED_SEEK; - } - track = 1; - } - } else { - check_wp(); - if (raw_cmd->track != DRS->track && - (raw_cmd->flags & FD_RAW_NEED_SEEK)) - track = raw_cmd->track; - else { - setup_rw_floppy(); - return; - } - } - - do_floppy = seek_interrupt; - output_byte(FD_SEEK); - output_byte(UNIT(current_drive)); - LAST_OUT(track); -#ifdef DEBUGT - debugt("seek command:"); -#endif -} - -static void recal_interrupt(void) -{ -#ifdef DEBUGT - debugt("recal interrupt:"); -#endif - if (inr !=2) - FDCS->reset = 1; - else if (ST0 & ST0_ECE) { - switch(DRS->track){ - case NEED_1_RECAL: -#ifdef DEBUGT - debugt("recal interrupt need 1 recal:"); -#endif - /* after a second recalibrate, we still haven't - * reached track 0. Probably no drive. Raise an - * error, as failing immediately might upset - * computers possessed by the Devil :-) */ - cont->error(); - cont->redo(); - return; - case NEED_2_RECAL: -#ifdef DEBUGT - debugt("recal interrupt need 2 recal:"); -#endif - /* If we already did a recalibrate, - * and we are not at track 0, this - * means we have moved. (The only way - * not to move at recalibration is to - * be already at track 0.) Clear the - * new change flag */ -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("clearing NEWCHANGE flag because of second recalibrate\n"); - } -#endif - - CLEARF(FD_DISK_NEWCHANGE); - DRS->select_date = jiffies; - /* fall through */ - default: -#ifdef DEBUGT - debugt("recal interrupt default:"); -#endif - /* Recalibrate moves the head by at - * most 80 steps. If after one - * recalibrate we don't have reached - * track 0, this might mean that we - * started beyond track 80. Try - * again. */ - DRS->track = NEED_1_RECAL; - break; - } - } else - DRS->track = ST1; - floppy_ready(); -} - -static void print_result(char *message, int inr) -{ - int i; - - DPRINT("%s ", message); - if (inr >= 0) - for (i=0; i= N_FDC || FDCS->address == -1){ - /* we don't even know which FDC is the culprit */ - printk("DOR0=%x\n", fdc_state[0].dor); - printk("floppy interrupt on bizarre fdc %d\n",fdc); - printk("handler=%p\n", handler); - is_alive("bizarre fdc"); - return IRQ_NONE; - } - - FDCS->reset = 0; - /* We have to clear the reset flag here, because apparently on boxes - * with level triggered interrupts (PS/2, Sparc, ...), it is needed to - * emit SENSEI's to clear the interrupt line. And FDCS->reset blocks the - * emission of the SENSEI's. - * It is OK to emit floppy commands because we are in an interrupt - * handler here, and thus we have to fear no interference of other - * activity. - */ - - do_print = !handler && print_unex && !initialising; - - inr = result(); - if (inr && do_print) - print_result("unexpected interrupt", inr); - if (inr == 0){ - do { - output_byte(FD_SENSEI); - inr = result(); - if ((ST0 & ST0_INTR) == 0xC0) { - int drive = ST0 & ST0_DS; - - /* Attention Interrupt. */ - if (ST0 & ST0_NR) { -#ifdef PC9800_DEBUG_FLOPPY - if (do_print) - printk(KERN_DEBUG - "floppy debug: floppy ejected (drive %d)\n", - drive); -#endif - USETF(FD_DISK_CHANGED); - USETF(FD_VERIFY); - } else { -#ifdef PC9800_DEBUG_FLOPPY - if (do_print) - printk(KERN_DEBUG - "floppy debug: floppy inserted (drive %d)\n", - drive); -#endif - } - } /* Attention Interrupt */ -#ifdef PC9800_DEBUG_FLOPPY - else { - printk(KERN_DEBUG - "floppy debug : unknown interrupt\n"); - } -#endif - } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2); - } - if (handler) { - schedule_bh(handler); - } else { -#if 0 - FDCS->reset = 1; -#endif - } - is_alive("normal interrupt end"); - - /* FIXME! Was it really for us? */ - return IRQ_HANDLED; -} - -static void recalibrate_floppy(void) -{ -#ifdef DEBUGT - debugt("recalibrate floppy:"); -#endif - do_floppy = recal_interrupt; - output_byte(FD_RECALIBRATE); - LAST_OUT(UNIT(current_drive)); -} - -/* - * Must do 4 FD_SENSEIs after reset because of ``drive polling''. - */ -static void reset_interrupt(void) -{ -#ifdef PC9800_DEBUG_FLOPPY - printk("floppy debug: reset interrupt\n"); -#endif -#ifdef DEBUGT - debugt("reset interrupt:"); -#endif - result(); /* get the status ready for set_fdc */ - if (FDCS->reset) { - printk("reset set in interrupt, calling %p\n", cont->error); - cont->error(); /* a reset just after a reset. BAD! */ - } - cont->redo(); -} - -/* - * reset is done by pulling bit 2 of DOR low for a while (old FDCs), - * or by setting the self clearing bit 7 of STATUS (newer FDCs) - */ -static void reset_fdc(void) -{ - unsigned long flags; - -#ifdef PC9800_DEBUG_FLOPPY - printk("floppy debug: reset_fdc\n"); -#endif - - do_floppy = reset_interrupt; - FDCS->reset = 0; - reset_fdc_info(0); - - /* Pseudo-DMA may intercept 'reset finished' interrupt. */ - /* Irrelevant for systems with true DMA (i386). */ - - flags=claim_dma_lock(); - fd_disable_dma(); - release_dma_lock(flags); - - fd_outb(FDCS->dor | 0x80, FD_MODE); - udelay(FD_RESET_DELAY); - fd_outb(FDCS->dor, FD_MODE); - udelay(FD_AFTER_RESET_DELAY); -} - -static void show_floppy(void) -{ - int i; - - printk("\n"); - printk("floppy driver state\n"); - printk("-------------------\n"); - printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n", - jiffies, interruptjiffies, jiffies-interruptjiffies, lasthandler); - - -#ifdef FLOPPY_SANITY_CHECK - printk("timeout_message=%s\n", timeout_message); - printk("last output bytes:\n"); - for (i=0; i < OLOGSIZE; i++) - printk("%2x %2x %lu\n", - output_log[(i+output_log_pos) % OLOGSIZE].data, - output_log[(i+output_log_pos) % OLOGSIZE].status, - output_log[(i+output_log_pos) % OLOGSIZE].jiffies); - printk("last result at %lu\n", resultjiffies); - printk("last redo_fd_request at %lu\n", lastredo); - for (i=0; ireset = 1; - if (cont){ - cont->done(0); - cont->redo(); /* this will recall reset when needed */ - } else { - printk("no cont in shutdown!\n"); - process_fd_request(); - } - is_alive("floppy shutdown"); -} -/*typedef void (*timeout_fn)(unsigned long);*/ - -static void access_mode_change_pc9800(void) -{ - static int access_mode, mode_change_now, old_mode, new_set = 1; -#ifdef PC9800_DEBUG_FLOPPY2 - printk("enter access_mode_change\n"); -#endif - access_mode = mode_change_now = 0; - if (DP->cmos==4) { - switch ((int)(_floppy - &floppy_type[0])) { - case 1: - case 2: - new_set = 1; - access_mode = 2; - break; - - case 4: - case 6: - new_set = 1; - access_mode = 3; - break; - - case 7: - case 10: - new_set = 1; - access_mode = 1; - break; - - default: - access_mode = 1; - break; - } - - old_mode = fd_inb(FD_MODE_CHANGE) & 3; - - switch (access_mode) { - case 1: - if ((old_mode & 2) == 0) { - fd_outb(old_mode | 2, FD_MODE_CHANGE); - mode_change_now = 1; - } else { - fd_outb(current_drive << 5, FD_EMODE_CHANGE); - if (fd_inb(FD_EMODE_CHANGE) == 0xff) - return; - } - - fd_outb((current_drive << 5) | 0x11, FD_EMODE_CHANGE); - mode_change_now = 1; - break; - - case 2: - if ((old_mode & 2) == 0) { - fd_outb(old_mode | 2, FD_MODE_CHANGE); - mode_change_now = 1; - } else { - fd_outb(current_drive << 5, FD_EMODE_CHANGE); - if ((fd_inb(FD_EMODE_CHANGE) & 1) == 0) - return; - fd_outb((current_drive << 5) | 0x10, FD_EMODE_CHANGE); - mode_change_now = 1; - } - - break; - - case 3: - if ((old_mode & 2) == 0) - return; - fd_outb(current_drive << 5, FD_EMODE_CHANGE); - if (fd_inb(FD_EMODE_CHANGE) & 1) - fd_outb((current_drive << 5) | 0x10, FD_EMODE_CHANGE); - fd_outb(old_mode & 0xfd, FD_MODE_CHANGE); - mode_change_now = 1; - break; - - default: - break; - } - } else { - switch ((int)(_floppy - &floppy_type[0])) { - case 1: - case 2: - new_set = 1; - access_mode = 2; - break; - - case 4: - case 6: - new_set = 1; - access_mode = 3; - break; - - default: - switch (DP->cmos) { - case 2: - access_mode = 2; - break; - - case 3: - access_mode = 3; - break; - - default: - break; - } - - break; - } - - old_mode = fd_inb(FD_MODE_CHANGE) & 3; - - switch (access_mode) { - case 2: - if ((old_mode & 2) == 0) { - fd_outb(old_mode | 2, FD_MODE_CHANGE); - mode_change_now = 1; - } - - break; - - case 3: - if (old_mode & 2) { - fd_outb(old_mode & 0xfd, FD_MODE_CHANGE); - mode_change_now = 1; - } - - break; - - default: - break; - } - } -#ifdef PC9800_DEBUG_FLOPPY2 - printk("floppy debug: DP->cmos=%d\n", DP->cmos); - printk("floppy debug: mode_change_now=%d\n", mode_change_now); - printk("floppy debug: access_mode=%d\n", access_mode); - printk("floppy debug: old_mode=%d\n", old_mode); - printk("floppy debug: _floppy - &floppy_type[0]=%d\n", (int)(_floppy - &floppy_type[0])); -#endif /* PC9800_DEBUG_FLOPPY2 */ - if(mode_change_now) - reset_fdc(); -} - -/* start motor, check media-changed condition and write protection */ -static int start_motor(void (*function)(void) ) -{ - access_mode_change_pc9800(); - set_mode(~0, 0x8); - - /* wait_for_completion also schedules reset if needed. */ - return(fd_wait_for_completion(DRS->select_date+DP->select_delay, - (timeout_fn) function)); -} - -static void floppy_ready(void) -{ - CHECK_RESET; - if (start_motor(floppy_ready)) return; - -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("calling disk change from floppy_ready\n"); - } -#endif - if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && - disk_change(current_drive) && - !DP->select_delay) - twaddle(); /* this clears the dcl on certain drive/controller - * combinations */ - -#ifdef fd_chose_dma_mode - if ((raw_cmd->flags & FD_RAW_READ) || - (raw_cmd->flags & FD_RAW_WRITE)) - { - unsigned long flags = claim_dma_lock(); - fd_chose_dma_mode(raw_cmd->kernel_data, - raw_cmd->length); - release_dma_lock(flags); - } -#endif - -#if 0 - access_mode_change_pc9800(); -#endif - if (raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){ - fdc_specify(); /* must be done here because of hut, hlt ... */ - seek_floppy(); - } else { - if ((raw_cmd->flags & FD_RAW_READ) || - (raw_cmd->flags & FD_RAW_WRITE)) - fdc_specify(); - setup_rw_floppy(); - } -} - -static void floppy_start(void) -{ - reschedule_timeout(current_reqD, "floppy start", 0); - - scandrives(); -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("setting NEWCHANGE in floppy_start\n"); - } -#endif - SETF(FD_DISK_NEWCHANGE); - floppy_ready(); -} - -/* - * ======================================================================== - * here ends the bottom half. Exported routines are: - * floppy_start, floppy_off, floppy_ready, lock_fdc, unlock_fdc, set_fdc, - * start_motor, reset_fdc, reset_fdc_info, interpret_errors. - * Initialization also uses output_byte, result, set_dor, floppy_interrupt - * and set_dor. - * ======================================================================== - */ -/* - * General purpose continuations. - * ============================== - */ - -static void do_wakeup(void) -{ - reschedule_timeout(MAXTIMEOUT, "do wakeup", 0); - cont = 0; - command_status += 2; - wake_up(&command_done); -} - -static struct cont_t wakeup_cont={ - empty, - do_wakeup, - empty, - (done_f)empty -}; - - -static struct cont_t intr_cont={ - empty, - process_fd_request, - empty, - (done_f) empty -}; - -static int wait_til_done(void (*handler)(void), int interruptible) -{ - int ret; - - schedule_bh((void *)(void *)handler); - - if (command_status < 2 && NO_SIGNAL) { - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&command_done, &wait); - for (;;) { - set_current_state(interruptible? - TASK_INTERRUPTIBLE: - TASK_UNINTERRUPTIBLE); - - if (command_status >= 2 || !NO_SIGNAL) - break; - - is_alive("wait_til_done"); - - schedule(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&command_done, &wait); - } - - if (command_status < 2){ - cancel_activity(); - cont = &intr_cont; - reset_fdc(); - return -EINTR; - } - -#ifdef PC9800_DEBUG_FLOPPY - if (command_status != FD_COMMAND_OKAY) - printk("floppy check: wait_til_done out:%d\n", command_status); -#endif - if (FDCS->reset) - command_status = FD_COMMAND_ERROR; - if (command_status == FD_COMMAND_OKAY) - ret=0; - else - ret=-EIO; - command_status = FD_COMMAND_NONE; - return ret; -} - -static void generic_done(int result) -{ - command_status = result; - cont = &wakeup_cont; -} - -static void generic_success(void) -{ - cont->done(1); -} - -static void generic_failure(void) -{ - cont->done(0); -} - -static void success_and_wakeup(void) -{ - generic_success(); - cont->redo(); -} - - -/* - * formatting and rw support. - * ========================== - */ - -static int next_valid_format(void) -{ - int probed_format; - - probed_format = DRS->probed_format; - while(1){ - if (probed_format >= 8 || - !DP->autodetect[probed_format]){ - DRS->probed_format = 0; - return 1; - } - if (floppy_type[DP->autodetect[probed_format]].sect){ - DRS->probed_format = probed_format; - return 0; - } - probed_format++; - } -} - -static void bad_flp_intr(void) -{ - if (probing){ - DRS->probed_format++; - if (!next_valid_format()) - return; - } - (*errors)++; - INFBOUND(DRWE->badness, *errors); - if (*errors > DP->max_errors.abort) - cont->done(0); - if (*errors > DP->max_errors.reset) - FDCS->reset = 1; - else if (*errors > DP->max_errors.recal) - DRS->track = NEED_2_RECAL; -} - -static void set_floppy(int drive) -{ - int type = ITYPE(UDRS->fd_device); - if (type) { - auto_detect_mode = 0; - _floppy = floppy_type + type; - } else if (auto_detect_mode == 0) { - auto_detect_mode = 1; - retry_auto_detect = 0; - _floppy = current_type[drive]; - } -#ifdef PC9800_DEBUG_FLOPPY2 - printk("set_floppy: set floppy type=%d\n", (int)(_floppy - floppy_type)); -#endif -} - -/* - * formatting support. - * =================== - */ -static void format_interrupt(void) -{ - switch (interpret_errors()){ - case 1: - cont->error(); - case 2: - break; - case 0: - cont->done(1); - } - cont->redo(); -} - -#define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2) -#define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1)) -#define CT(x) ((x) | 0xc0) -static void setup_format_params(int track) -{ - struct fparm { - unsigned char track,head,sect,size; - } *here = (struct fparm *)floppy_track_buffer; - int il,n; - int count,head_shift,track_shift; - - raw_cmd = &default_raw_cmd; - raw_cmd->track = track; - - raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | - FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; - raw_cmd->rate = _floppy->rate & 0x43; - raw_cmd->cmd_count = NR_F; - COMMAND = FM_MODE(_floppy,FD_FORMAT); - DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy,format_req.head); - F_SIZECODE = FD_SIZECODE(_floppy); - F_SECT_PER_TRACK = _floppy->sect << 2 >> F_SIZECODE; - F_GAP = _floppy->fmt_gap; - F_FILL = FD_FILL_BYTE; - - raw_cmd->kernel_data = floppy_track_buffer; - raw_cmd->length = 4 * F_SECT_PER_TRACK; - - /* allow for about 30ms for data transport per track */ - head_shift = (F_SECT_PER_TRACK + 5) / 6; - - /* a ``cylinder'' is two tracks plus a little stepping time */ - track_shift = 2 * head_shift + 3; - - /* position of logical sector 1 on this track */ - n = (track_shift * format_req.track + head_shift * format_req.head) - % F_SECT_PER_TRACK; - - /* determine interleave */ - il = 1; - if (_floppy->fmt_gap < 0x22) - il++; - - /* initialize field */ - for (count = 0; count < F_SECT_PER_TRACK; ++count) { - here[count].track = format_req.track; - here[count].head = format_req.head; - here[count].sect = 0; - here[count].size = F_SIZECODE; - } - /* place logical sectors */ - for (count = 1; count <= F_SECT_PER_TRACK; ++count) { - here[n].sect = count; - n = (n+il) % F_SECT_PER_TRACK; - if (here[n].sect) { /* sector busy, find next free sector */ - ++n; - if (n>= F_SECT_PER_TRACK) { - n-=F_SECT_PER_TRACK; - while (here[n].sect) ++n; - } - } - } -} - -static void redo_format(void) -{ - buffer_track = -1; - setup_format_params(format_req.track << STRETCH(_floppy)); - floppy_start(); -#ifdef DEBUGT - debugt("queue format request"); -#endif -} - -static struct cont_t format_cont={ - format_interrupt, - redo_format, - bad_flp_intr, - generic_done }; - -static int do_format(int drive, struct format_descr *tmp_format_req) -{ - int ret; - - LOCK_FDC(drive,1); - set_floppy(drive); - if (!_floppy || - _floppy->track > DP->tracks || - tmp_format_req->track >= _floppy->track || - tmp_format_req->head >= _floppy->head || - (_floppy->sect << 2) % (1 << FD_SIZECODE(_floppy)) || - !_floppy->fmt_gap) { - process_fd_request(); - return -EINVAL; - } - format_req = *tmp_format_req; - format_errors = 0; - cont = &format_cont; - errors = &format_errors; - IWAIT(redo_format); - process_fd_request(); - return ret; -} - -/* - * Buffer read/write and support - * ============================= - */ - -static void floppy_end_request(struct request *req, int uptodate) -{ - if (end_that_request_first(req, uptodate, current_count_sectors)) - return; - add_disk_randomness(req->rq_disk); - floppy_off((long)req->rq_disk->private_data); - blkdev_dequeue_request(req); - end_that_request_last(req); - - /* We're done with the request */ - current_req = NULL; -} - - -/* new request_done. Can handle physical sectors which are smaller than a - * logical buffer */ -static void request_done(int uptodate) -{ - struct request_queue *q = floppy_queue; - struct request *req = current_req; - unsigned long flags; - int block; - - probing = 0; - reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate); - - if (!req) { - printk("floppy.c: no request in request_done\n"); - return; - } - - if (uptodate){ - /* maintain values for invalidation on geometry - * change */ - block = current_count_sectors + req->sector; - INFBOUND(DRS->maxblock, block); - if (block > _floppy->sect) - DRS->maxtrack = 1; - - /* unlock chained buffers */ - spin_lock_irqsave(q->queue_lock, flags); - floppy_end_request(req, 1); - spin_unlock_irqrestore(q->queue_lock, flags); - } else { - if (rq_data_dir(req) == WRITE) { - /* record write error information */ - DRWE->write_errors++; - if (DRWE->write_errors == 1) { - DRWE->first_error_sector = req->sector; - DRWE->first_error_generation = DRS->generation; - } - DRWE->last_error_sector = req->sector; - DRWE->last_error_generation = DRS->generation; - } - spin_lock_irqsave(q->queue_lock, flags); - floppy_end_request(req, 0); - spin_unlock_irqrestore(q->queue_lock, flags); - } -} - -/* Interrupt handler evaluating the result of the r/w operation */ -static void rw_interrupt(void) -{ - int nr_sectors, ssize, eoc, heads; - - if (R_HEAD >= 2) { - /* some Toshiba floppy controllers occasionnally seem to - * return bogus interrupts after read/write operations, which - * can be recognized by a bad head number (>= 2) */ - return; - } - - if (!DRS->first_read_date) - DRS->first_read_date = jiffies; - - nr_sectors = 0; - CODE2SIZE; - - if (ST1 & ST1_EOC) - eoc = 1; - else - eoc = 0; - - if (COMMAND & 0x80) - heads = 2; - else - heads = 1; - - nr_sectors = (((R_TRACK-TRACK) * heads + - R_HEAD-HEAD) * SECT_PER_TRACK + - R_SECTOR-SECTOR + eoc) << SIZECODE >> 2; - -#ifdef FLOPPY_SANITY_CHECK - if (nr_sectors / ssize > - (in_sector_offset + current_count_sectors + ssize - 1) / ssize) { - DPRINT("long rw: %x instead of %lx\n", - nr_sectors, current_count_sectors); - printk("rs=%d s=%d\n", R_SECTOR, SECTOR); - printk("rh=%d h=%d\n", R_HEAD, HEAD); - printk("rt=%d t=%d\n", R_TRACK, TRACK); - printk("heads=%d eoc=%d\n", heads, eoc); - printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK, - fsector_t, ssize); - printk("in_sector_offset=%d\n", in_sector_offset); - } -#endif - - nr_sectors -= in_sector_offset; - INFBOUND(nr_sectors,0); - SUPBOUND(current_count_sectors, nr_sectors); - - switch (interpret_errors()){ - case 2: - cont->redo(); - return; - case 1: - if (!current_count_sectors){ - cont->error(); - cont->redo(); - return; - } - break; - case 0: - if (!current_count_sectors){ - cont->redo(); - return; - } - current_type[current_drive] = _floppy; - floppy_sizes[TOMINOR(current_drive) ]= _floppy->size; - break; - } - - if (probing) { - if (DP->flags & FTD_MSG) - DPRINT("Auto-detected floppy type %s in fd%d\n", - _floppy->name,current_drive); - current_type[current_drive] = _floppy; - floppy_sizes[TOMINOR(current_drive)] = _floppy->size; - probing = 0; - } - - if (CT(COMMAND) != FD_READ || - raw_cmd->kernel_data == current_req->buffer){ - /* transfer directly from buffer */ - cont->done(1); - } else if (CT(COMMAND) == FD_READ){ - buffer_track = raw_cmd->track; - buffer_drive = current_drive; - INFBOUND(buffer_max, nr_sectors + fsector_t); - } - cont->redo(); -} - -/* Compute maximal contiguous buffer size. */ -static int buffer_chain_size(void) -{ - struct bio *bio; - struct bio_vec *bv; - int size, i; - char *base; - - base = bio_data(current_req->bio); - size = 0; - - rq_for_each_bio(bio, current_req) { - bio_for_each_segment(bv, bio, i) { - if (page_address(bv->bv_page) + bv->bv_offset != base + size) - break; - - size += bv->bv_len; - } - } - - return size >> 9; -} - -/* Compute the maximal transfer size */ -static int transfer_size(int ssize, int max_sector, int max_size) -{ - SUPBOUND(max_sector, fsector_t + max_size); - - /* alignment */ - max_sector -= (max_sector % _floppy->sect) % ssize; - - /* transfer size, beginning not aligned */ - current_count_sectors = max_sector - fsector_t ; - - return max_sector; -} - -/* - * Move data from/to the track buffer to/from the buffer cache. - */ -static void copy_buffer(int ssize, int max_sector, int max_sector_2) -{ - int remaining; /* number of transferred 512-byte sectors */ - struct bio_vec *bv; - struct bio *bio; - char *buffer, *dma_buffer; - int size, i; - - max_sector = transfer_size(ssize, - minimum(max_sector, max_sector_2), - current_req->nr_sectors); - - if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE && - buffer_max > fsector_t + current_req->nr_sectors) - current_count_sectors = minimum(buffer_max - fsector_t, - current_req->nr_sectors); - - remaining = current_count_sectors << 9; -#ifdef FLOPPY_SANITY_CHECK - if ((remaining >> 9) > current_req->nr_sectors && - CT(COMMAND) == FD_WRITE){ - DPRINT("in copy buffer\n"); - printk("current_count_sectors=%ld\n", current_count_sectors); - printk("remaining=%d\n", remaining >> 9); - printk("current_req->nr_sectors=%ld\n",current_req->nr_sectors); - printk("current_req->current_nr_sectors=%u\n", - current_req->current_nr_sectors); - printk("max_sector=%d\n", max_sector); - printk("ssize=%d\n", ssize); - } -#endif - - buffer_max = maximum(max_sector, buffer_max); - - dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9); - - size = current_req->current_nr_sectors << 9; - - rq_for_each_bio(bio, current_req) { - bio_for_each_segment(bv, bio, i) { - if (!remaining) - break; - - size = bv->bv_len; - SUPBOUND(size, remaining); - - buffer = page_address(bv->bv_page) + bv->bv_offset; -#ifdef FLOPPY_SANITY_CHECK - if (dma_buffer + size > - floppy_track_buffer + (max_buffer_sectors << 10) || - dma_buffer < floppy_track_buffer){ - DPRINT("buffer overrun in copy buffer %d\n", - (int) ((floppy_track_buffer - dma_buffer) >>9)); - printk("fsector_t=%d buffer_min=%d\n", - fsector_t, buffer_min); - printk("current_count_sectors=%ld\n", - current_count_sectors); - if (CT(COMMAND) == FD_READ) - printk("read\n"); - if (CT(COMMAND) == FD_WRITE) - printk("write\n"); - break; - } - if (((unsigned long)buffer) % 512) - DPRINT("%p buffer not aligned\n", buffer); -#endif - if (CT(COMMAND) == FD_READ) - memcpy(buffer, dma_buffer, size); - else - memcpy(dma_buffer, buffer, size); - - remaining -= size; - dma_buffer += size; - } - } -#ifdef FLOPPY_SANITY_CHECK - if (remaining){ - if (remaining > 0) - max_sector -= remaining >> 9; - DPRINT("weirdness: remaining %d\n", remaining>>9); - } -#endif -} - -#if 0 -static inline int check_dma_crossing(char *start, - unsigned long length, char *message) -{ - if (CROSS_64KB(start, length)) { - printk("DMA xfer crosses 64KB boundary in %s %p-%p\n", - message, start, start+length); - return 1; - } else - return 0; -} -#endif - -/* work around a bug in pseudo DMA - * (on some FDCs) pseudo DMA does not stop when the CPU stops - * sending data. Hence we need a different way to signal the - * transfer length: We use SECT_PER_TRACK. Unfortunately, this - * does not work with MT, hence we can only transfer one head at - * a time - */ -static void virtualdmabug_workaround(void) -{ - int hard_sectors, end_sector; - - if(CT(COMMAND) == FD_WRITE) { - COMMAND &= ~0x80; /* switch off multiple track mode */ - - hard_sectors = raw_cmd->length >> (7 + SIZECODE); - end_sector = SECTOR + hard_sectors - 1; -#ifdef FLOPPY_SANITY_CHECK - if(end_sector > SECT_PER_TRACK) { - printk("too many sectors %d > %d\n", - end_sector, SECT_PER_TRACK); - return; - } -#endif - SECT_PER_TRACK = end_sector; /* make sure SECT_PER_TRACK points - * to end of transfer */ - } -} - -/* - * Formulate a read/write request. - * this routine decides where to load the data (directly to buffer, or to - * tmp floppy area), how much data to load (the size of the buffer, the whole - * track, or a single sector) - * All floppy_track_buffer handling goes in here. If we ever add track buffer - * allocation on the fly, it should be done here. No other part should need - * modification. - */ - -static int make_raw_rw_request(void) -{ - int aligned_sector_t; - int max_sector, max_size, tracksize, ssize; - - if(max_buffer_sectors == 0) { - printk("VFS: Block I/O scheduled on unopened device\n"); - return 0; - } - - set_fdc((long)current_req->rq_disk->private_data); - - raw_cmd = &default_raw_cmd; - raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK | - FD_RAW_NEED_SEEK; - raw_cmd->cmd_count = NR_RW; - if (rq_data_dir(current_req) == READ) { - raw_cmd->flags |= FD_RAW_READ; - COMMAND = FM_MODE(_floppy,FD_READ); - } else if (rq_data_dir(current_req) == WRITE){ - raw_cmd->flags |= FD_RAW_WRITE; - COMMAND = FM_MODE(_floppy,FD_WRITE); - } else { - DPRINT("make_raw_rw_request: unknown command\n"); - return 0; - } - - max_sector = _floppy->sect * _floppy->head; - - TRACK = (int)current_req->sector / max_sector; - fsector_t = (int)current_req->sector % max_sector; - if (_floppy->track && TRACK >= _floppy->track) { - if (current_req->current_nr_sectors & 1) { - current_count_sectors = 1; - return 1; - } else - return 0; - } - HEAD = fsector_t / _floppy->sect; - - if (((_floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) && - fsector_t < _floppy->sect) - max_sector = _floppy->sect; - - /* 2M disks have phantom sectors on the first track */ - if ((_floppy->rate & FD_2M) && (!TRACK) && (!HEAD)){ - max_sector = 2 * _floppy->sect / 3; - if (fsector_t >= max_sector){ - current_count_sectors = minimum(_floppy->sect - fsector_t, - current_req->nr_sectors); - return 1; - } - SIZECODE = 2; - } else - SIZECODE = FD_SIZECODE(_floppy); - raw_cmd->rate = _floppy->rate & 0x43; - if ((_floppy->rate & FD_2M) && - (TRACK || HEAD) && - raw_cmd->rate == 2) - raw_cmd->rate = 1; - - if (SIZECODE) - SIZECODE2 = 0xff; - else - SIZECODE2 = 0x80; - raw_cmd->track = TRACK << STRETCH(_floppy); - DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy,HEAD); - GAP = _floppy->gap; - CODE2SIZE; - SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; - SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + 1; - - /* tracksize describes the size which can be filled up with sectors - * of size ssize. - */ - tracksize = _floppy->sect - _floppy->sect % ssize; - if (tracksize < _floppy->sect){ - SECT_PER_TRACK ++; - if (tracksize <= fsector_t % _floppy->sect) - SECTOR--; - - /* if we are beyond tracksize, fill up using smaller sectors */ - while (tracksize <= fsector_t % _floppy->sect){ - while(tracksize + ssize > _floppy->sect){ - SIZECODE--; - ssize >>= 1; - } - SECTOR++; SECT_PER_TRACK ++; - tracksize += ssize; - } - max_sector = HEAD * _floppy->sect + tracksize; - } else if (!TRACK && !HEAD && !(_floppy->rate & FD_2M) && probing) { - max_sector = _floppy->sect; - } else if (!HEAD && CT(COMMAND) == FD_WRITE) { - /* for virtual DMA bug workaround */ - max_sector = _floppy->sect; - } - - in_sector_offset = (fsector_t % _floppy->sect) % ssize; - aligned_sector_t = fsector_t - in_sector_offset; - max_size = current_req->nr_sectors; - if ((raw_cmd->track == buffer_track) && - (current_drive == buffer_drive) && - (fsector_t >= buffer_min) && (fsector_t < buffer_max)) { - /* data already in track buffer */ - if (CT(COMMAND) == FD_READ) { - copy_buffer(1, max_sector, buffer_max); - return 1; - } - } else if (in_sector_offset || current_req->nr_sectors < ssize){ - if (CT(COMMAND) == FD_WRITE){ - if (fsector_t + current_req->nr_sectors > ssize && - fsector_t + current_req->nr_sectors < ssize + ssize) - max_size = ssize + ssize; - else - max_size = ssize; - } - raw_cmd->flags &= ~FD_RAW_WRITE; - raw_cmd->flags |= FD_RAW_READ; - COMMAND = FM_MODE(_floppy,FD_READ); - } else if ((unsigned long)current_req->buffer < MAX_DMA_ADDRESS) { - unsigned long dma_limit; - int direct, indirect; - - indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) - - fsector_t; - - /* - * Do NOT use minimum() here---MAX_DMA_ADDRESS is 64 bits wide - * on a 64 bit machine! - */ - max_size = buffer_chain_size(); - dma_limit = (MAX_DMA_ADDRESS - ((unsigned long) current_req->buffer)) >> 9; - if ((unsigned long) max_size > dma_limit) { - max_size = dma_limit; - } - /* 64 kb boundaries */ - if (CROSS_64KB(current_req->buffer, max_size << 9)) - max_size = (K_64 - - ((unsigned long)current_req->buffer) % K_64)>>9; - direct = transfer_size(ssize,max_sector,max_size) - fsector_t; - /* - * We try to read tracks, but if we get too many errors, we - * go back to reading just one sector at a time. - * - * This means we should be able to read a sector even if there - * are other bad sectors on this track. - */ - if (!direct || - (indirect * 2 > direct * 3 && - *errors < DP->max_errors.read_track && - /*!TESTF(FD_NEED_TWADDLE) &&*/ - ((!probing || (DP->read_track&(1<probed_format)))))){ - max_size = current_req->nr_sectors; - } else { - raw_cmd->kernel_data = current_req->buffer; - raw_cmd->length = current_count_sectors << 9; - if (raw_cmd->length == 0){ - DPRINT("zero dma transfer attempted from make_raw_request\n"); - DPRINT("indirect=%d direct=%d fsector_t=%d", - indirect, direct, fsector_t); - return 0; - } -/* check_dma_crossing(raw_cmd->kernel_data, - raw_cmd->length, - "end of make_raw_request [1]");*/ - - virtualdmabug_workaround(); - return 2; - } - } - - if (CT(COMMAND) == FD_READ) - max_size = max_sector; /* unbounded */ - - /* claim buffer track if needed */ - if (buffer_track != raw_cmd->track || /* bad track */ - buffer_drive !=current_drive || /* bad drive */ - fsector_t > buffer_max || - fsector_t < buffer_min || - ((CT(COMMAND) == FD_READ || - (!in_sector_offset && current_req->nr_sectors >= ssize))&& - max_sector > 2 * max_buffer_sectors + buffer_min && - max_size + fsector_t > 2 * max_buffer_sectors + buffer_min) - /* not enough space */){ - buffer_track = -1; - buffer_drive = current_drive; - buffer_max = buffer_min = aligned_sector_t; - } - raw_cmd->kernel_data = floppy_track_buffer + - ((aligned_sector_t-buffer_min)<<9); - - if (CT(COMMAND) == FD_WRITE){ - /* copy write buffer to track buffer. - * if we get here, we know that the write - * is either aligned or the data already in the buffer - * (buffer will be overwritten) */ -#ifdef FLOPPY_SANITY_CHECK - if (in_sector_offset && buffer_track == -1) - DPRINT("internal error offset !=0 on write\n"); -#endif - buffer_track = raw_cmd->track; - buffer_drive = current_drive; - copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min); - } else - transfer_size(ssize, max_sector, - 2*max_buffer_sectors+buffer_min-aligned_sector_t); - - /* round up current_count_sectors to get dma xfer size */ - raw_cmd->length = in_sector_offset+current_count_sectors; - raw_cmd->length = ((raw_cmd->length -1)|(ssize-1))+1; - raw_cmd->length <<= 9; -#ifdef FLOPPY_SANITY_CHECK - /*check_dma_crossing(raw_cmd->kernel_data, raw_cmd->length, - "end of make_raw_request");*/ - if ((raw_cmd->length < current_count_sectors << 9) || - (raw_cmd->kernel_data != current_req->buffer && - CT(COMMAND) == FD_WRITE && - (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max || - aligned_sector_t < buffer_min)) || - raw_cmd->length % (128 << SIZECODE) || - raw_cmd->length <= 0 || current_count_sectors <= 0){ - DPRINT("fractionary current count b=%lx s=%lx\n", - raw_cmd->length, current_count_sectors); - if (raw_cmd->kernel_data != current_req->buffer) - printk("addr=%d, length=%ld\n", - (int) ((raw_cmd->kernel_data - - floppy_track_buffer) >> 9), - current_count_sectors); - printk("st=%d ast=%d mse=%d msi=%d\n", - fsector_t, aligned_sector_t, max_sector, max_size); - printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); - printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", - COMMAND, SECTOR, HEAD, TRACK); - printk("buffer drive=%d\n", buffer_drive); - printk("buffer track=%d\n", buffer_track); - printk("buffer_min=%d\n", buffer_min); - printk("buffer_max=%d\n", buffer_max); - return 0; - } - - if (raw_cmd->kernel_data != current_req->buffer){ - if (raw_cmd->kernel_data < floppy_track_buffer || - current_count_sectors < 0 || - raw_cmd->length < 0 || - raw_cmd->kernel_data + raw_cmd->length > - floppy_track_buffer + (max_buffer_sectors << 10)){ - DPRINT("buffer overrun in schedule dma\n"); - printk("fsector_t=%d buffer_min=%d current_count=%ld\n", - fsector_t, buffer_min, - raw_cmd->length >> 9); - printk("current_count_sectors=%ld\n", - current_count_sectors); - if (CT(COMMAND) == FD_READ) - printk("read\n"); - if (CT(COMMAND) == FD_WRITE) - printk("write\n"); - return 0; - } - } else if (raw_cmd->length > current_req->nr_sectors << 9 || - current_count_sectors > current_req->nr_sectors){ - DPRINT("buffer overrun in direct transfer\n"); - return 0; - } else if (raw_cmd->length < current_count_sectors << 9){ - DPRINT("more sectors than bytes\n"); - printk("bytes=%ld\n", raw_cmd->length >> 9); - printk("sectors=%ld\n", current_count_sectors); - } - if (raw_cmd->length == 0){ - DPRINT("zero dma transfer attempted from make_raw_request\n"); - return 0; - } -#endif - - virtualdmabug_workaround(); - return 2; -} - -static void redo_fd_request(void) -{ -#define REPEAT {request_done(0); continue; } - int drive; - int tmp; - - lastredo = jiffies; - if (current_drive < N_DRIVE) - floppy_off(current_drive); - - for (;;) { - if (!current_req) { - struct request *req; - - spin_lock_irq(floppy_queue->queue_lock); - req = elv_next_request(floppy_queue); - spin_unlock_irq(floppy_queue->queue_lock); - if (!req) { - do_floppy = NULL; - unlock_fdc(); - return; - } - current_req = req; - } - drive = (long)current_req->rq_disk->private_data; - set_fdc(drive); - reschedule_timeout(current_reqD, "redo fd request", 0); - - set_floppy(drive); - raw_cmd = & default_raw_cmd; - raw_cmd->flags = 0; - if (start_motor(redo_fd_request)) return; - disk_change(current_drive); - if (test_bit(current_drive, &fake_change) || - TESTF(FD_DISK_CHANGED)){ - DPRINT("disk absent or changed during operation\n"); - REPEAT; - } - if (!_floppy) { /* Autodetection */ - if (!probing){ - DRS->probed_format = 0; - if (next_valid_format()){ - DPRINT("no autodetectable formats\n"); - _floppy = NULL; - REPEAT; - } - } - probing = 1; - _floppy = floppy_type+DP->autodetect[DRS->probed_format]; - } else - probing = 0; - errors = & (current_req->errors); - tmp = make_raw_rw_request(); - if (tmp < 2){ - request_done(tmp); - continue; - } - - if (TESTF(FD_NEED_TWADDLE)) - twaddle(); - schedule_bh( (void *)(void *) floppy_start); -#ifdef DEBUGT - debugt("queue fd request"); -#endif - return; - } -#undef REPEAT -} - -static struct cont_t rw_cont={ - rw_interrupt, - redo_fd_request, - bad_flp_intr, - request_done }; - -static void process_fd_request(void) -{ - cont = &rw_cont; - schedule_bh( (void *)(void *) redo_fd_request); -} - -static void do_fd_request(request_queue_t * q) -{ - if(max_buffer_sectors == 0) { - printk("VFS: do_fd_request called on non-open device\n"); - return; - } - - if (usage_count == 0) { - printk("warning: usage count=0, current_req=%p exiting\n", current_req); - printk("sect=%ld flags=%lx\n", (long)current_req->sector, current_req->flags); - return; - } - if (fdc_busy){ - /* fdc busy, this new request will be treated when the - current one is done */ - is_alive("do fd request, old request running"); - return; - } - lock_fdc(MAXTIMEOUT,0); - process_fd_request(); - is_alive("do fd request"); -} - -static struct cont_t poll_cont={ - success_and_wakeup, - floppy_ready, - generic_failure, - generic_done }; - -static int poll_drive(int interruptible, int flag) -{ - int ret; - /* no auto-sense, just clear dcl */ - raw_cmd = &default_raw_cmd; - raw_cmd->flags= flag; - raw_cmd->track=0; - raw_cmd->cmd_count=0; - cont = &poll_cont; -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("setting NEWCHANGE in poll_drive\n"); - } -#endif - SETF(FD_DISK_NEWCHANGE); - WAIT(floppy_ready); - return ret; -} - -/* - * User triggered reset - * ==================== - */ - -static void reset_intr(void) -{ - printk("weird, reset interrupt called\n"); -} - -static struct cont_t reset_cont={ - reset_intr, - success_and_wakeup, - generic_failure, - generic_done }; - -static int user_reset_fdc(int drive, int arg, int interruptible) -{ - int ret; - - ret=0; - LOCK_FDC(drive,interruptible); - if (arg == FD_RESET_ALWAYS) - FDCS->reset=1; - if (FDCS->reset){ - cont = &reset_cont; - WAIT(reset_fdc); - } - process_fd_request(); - return ret; -} - -/* - * Misc Ioctl's and support - * ======================== - */ -static inline int fd_copyout(void *param, const void *address, unsigned long size) -{ - return copy_to_user(param,address, size) ? -EFAULT : 0; -} - -static inline int fd_copyin(void *param, void *address, unsigned long size) -{ - return copy_from_user(address, param, size) ? -EFAULT : 0; -} - -#define _COPYOUT(x) (copy_to_user((void *)param, &(x), sizeof(x)) ? -EFAULT : 0) -#define _COPYIN(x) (copy_from_user(&(x), (void *)param, sizeof(x)) ? -EFAULT : 0) - -#define COPYOUT(x) ECALL(_COPYOUT(x)) -#define COPYIN(x) ECALL(_COPYIN(x)) - -static inline const char *drive_name(int type, int drive) -{ - struct floppy_struct *floppy; - - if (type) - floppy = floppy_type + type; - else { - if (UDP->native_format) - floppy = floppy_type + UDP->native_format; - else - return "(null)"; - } - if (floppy->name) - return floppy->name; - else - return "(null)"; -} - - -/* raw commands */ -static void raw_cmd_done(int flag) -{ - int i; - - if (!flag) { - raw_cmd->flags |= FD_RAW_FAILURE; - raw_cmd->flags |= FD_RAW_HARDFAILURE; - } else { - raw_cmd->reply_count = inr; - if (raw_cmd->reply_count > MAX_REPLIES) - raw_cmd->reply_count=0; - for (i=0; i< raw_cmd->reply_count; i++) - raw_cmd->reply[i] = reply_buffer[i]; - - if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE)) - { - unsigned long flags; - flags=claim_dma_lock(); - raw_cmd->length = fd_get_dma_residue(); - release_dma_lock(flags); - } - - if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) && - (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0))) - raw_cmd->flags |= FD_RAW_FAILURE; - - if (disk_change(current_drive)) - raw_cmd->flags |= FD_RAW_DISK_CHANGE; - else - raw_cmd->flags &= ~FD_RAW_DISK_CHANGE; - if (raw_cmd->flags & FD_RAW_NO_MOTOR_AFTER) - motor_off_callback(current_drive); - - if (raw_cmd->next && - (!(raw_cmd->flags & FD_RAW_FAILURE) || - !(raw_cmd->flags & FD_RAW_STOP_IF_FAILURE)) && - ((raw_cmd->flags & FD_RAW_FAILURE) || - !(raw_cmd->flags &FD_RAW_STOP_IF_SUCCESS))) { - raw_cmd = raw_cmd->next; - return; - } - } - generic_done(flag); -} - - -static struct cont_t raw_cmd_cont={ - success_and_wakeup, - floppy_start, - generic_failure, - raw_cmd_done -}; - -static inline int raw_cmd_copyout(int cmd, char *param, - struct floppy_raw_cmd *ptr) -{ - int ret; - - while(ptr) { - COPYOUT(*ptr); - param += sizeof(struct floppy_raw_cmd); - if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length){ - if (ptr->length>=0 && ptr->length<=ptr->buffer_length) - ECALL(fd_copyout(ptr->data, - ptr->kernel_data, - ptr->buffer_length - - ptr->length)); - } - ptr = ptr->next; - } - return 0; -} - - -static void raw_cmd_free(struct floppy_raw_cmd **ptr) -{ - struct floppy_raw_cmd *next,*this; - - this = *ptr; - *ptr = 0; - while(this) { - if (this->buffer_length) { - fd_dma_mem_free((unsigned long)this->kernel_data, - this->buffer_length); - this->buffer_length = 0; - } - next = this->next; - kfree(this); - this = next; - } -} - - -static inline int raw_cmd_copyin(int cmd, char *param, - struct floppy_raw_cmd **rcmd) -{ - struct floppy_raw_cmd *ptr; - int ret; - int i; - - *rcmd = 0; - while(1) { - ptr = (struct floppy_raw_cmd *) - kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); - if (!ptr) - return -ENOMEM; - *rcmd = ptr; - COPYIN(*ptr); - ptr->next = 0; - ptr->buffer_length = 0; - param += sizeof(struct floppy_raw_cmd); - if (ptr->cmd_count > 33) - /* the command may now also take up the space - * initially intended for the reply & the - * reply count. Needed for long 82078 commands - * such as RESTORE, which takes ... 17 command - * bytes. Murphy's law #137: When you reserve - * 16 bytes for a structure, you'll one day - * discover that you really need 17... - */ - return -EINVAL; - - for (i=0; i< 16; i++) - ptr->reply[i] = 0; - ptr->resultcode = 0; - ptr->kernel_data = 0; - - if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { - if (ptr->length <= 0) - return -EINVAL; - ptr->kernel_data =(char*)fd_dma_mem_alloc(ptr->length); - fallback_on_nodma_alloc(&ptr->kernel_data, - ptr->length); - if (!ptr->kernel_data) - return -ENOMEM; - ptr->buffer_length = ptr->length; - } - if (ptr->flags & FD_RAW_WRITE) - ECALL(fd_copyin(ptr->data, ptr->kernel_data, - ptr->length)); - rcmd = & (ptr->next); - if (!(ptr->flags & FD_RAW_MORE)) - return 0; - ptr->rate &= 0x43; - } -} - - -static int raw_cmd_ioctl(int cmd, void *param) -{ - int drive, ret, ret2; - struct floppy_raw_cmd *my_raw_cmd; - - if (FDCS->rawcmd <= 1) - FDCS->rawcmd = 1; - for (drive= 0; drive < N_DRIVE; drive++){ - if (FDC(drive) != fdc) - continue; - if (drive == current_drive){ - if (UDRS->fd_ref > 1){ - FDCS->rawcmd = 2; - break; - } - } else if (UDRS->fd_ref){ - FDCS->rawcmd = 2; - break; - } - } - - if (FDCS->reset) - return -EIO; - - ret = raw_cmd_copyin(cmd, param, &my_raw_cmd); - if (ret) { - raw_cmd_free(&my_raw_cmd); - return ret; - } - - raw_cmd = my_raw_cmd; - cont = &raw_cmd_cont; - ret=wait_til_done(floppy_start,1); -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG){ - DPRINT("calling disk change from raw_cmd ioctl\n"); - } -#endif - - if (ret != -EINTR && FDCS->reset) - ret = -EIO; - - DRS->track = NO_TRACK; - - ret2 = raw_cmd_copyout(cmd, param, my_raw_cmd); - if (!ret) - ret = ret2; - raw_cmd_free(&my_raw_cmd); - return ret; -} - -static int invalidate_drive(struct block_device *bdev) -{ - /* invalidate the buffer track to force a reread */ - set_bit((long)bdev->bd_disk->private_data, &fake_change); - process_fd_request(); - check_disk_change(bdev); - return 0; -} - - -static inline void clear_write_error(int drive) -{ - CLEARSTRUCT(UDRWE); -} - -static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, - int drive, int type, struct block_device *bdev) -{ - int cnt; - - /* sanity checking for parameters.*/ - if (g->sect <= 0 || - g->head <= 0 || - g->track <= 0 || - g->track > UDP->tracks>>STRETCH(g) || - /* check if reserved bits are set */ - (g->stretch&~(FD_STRETCH|FD_SWAPSIDES)) != 0) - return -EINVAL; - if (type){ - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - down(&open_lock); - LOCK_FDC(drive,1); - floppy_type[type] = *g; - floppy_type[type].name="user format"; - for (cnt = type << 2; cnt < (type << 2) + 4; cnt++) - floppy_sizes[cnt]= floppy_sizes[cnt+0x80]= - floppy_type[type].size+1; - process_fd_request(); - for (cnt = 0; cnt < N_DRIVE; cnt++) { - struct block_device *bdev = opened_bdev[cnt]; - if (!bdev || ITYPE(drive_state[cnt].fd_device) != type) - continue; - __invalidate_device(bdev, 0); - } - up(&open_lock); - } else { - LOCK_FDC(drive,1); - if (cmd != FDDEFPRM) - /* notice a disk change immediately, else - * we lose our settings immediately*/ - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - user_params[drive] = *g; - if (buffer_drive == drive) - SUPBOUND(buffer_max, user_params[drive].sect); - current_type[drive] = &user_params[drive]; - floppy_sizes[drive] = user_params[drive].size; - if (cmd == FDDEFPRM) - DRS->keep_data = -1; - else - DRS->keep_data = 1; - /* invalidation. Invalidate only when needed, i.e. - * when there are already sectors in the buffer cache - * whose number will change. This is useful, because - * mtools often changes the geometry of the disk after - * looking at the boot block */ - if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack) - invalidate_drive(bdev); - else - process_fd_request(); - } - return 0; -} - -/* handle obsolete ioctl's */ -static int ioctl_table[]= { - FDCLRPRM, - FDSETPRM, - FDDEFPRM, - FDGETPRM, - FDMSGON, - FDMSGOFF, - FDFMTBEG, - FDFMTTRK, - FDFMTEND, - FDSETEMSGTRESH, - FDFLUSH, - FDSETMAXERRS, - FDGETMAXERRS, - FDGETDRVTYP, - FDSETDRVPRM, - FDGETDRVPRM, - FDGETDRVSTAT, - FDPOLLDRVSTAT, - FDRESET, - FDGETFDCSTAT, - FDWERRORCLR, - FDWERRORGET, - FDRAWCMD, - FDEJECT, - FDTWADDLE -}; - -static inline int normalize_ioctl(int *cmd, int *size) -{ - int i; - - for (i=0; i < ARRAY_SIZE(ioctl_table); i++) { - if ((*cmd & 0xffff) == (ioctl_table[i] & 0xffff)){ - *size = _IOC_SIZE(*cmd); - *cmd = ioctl_table[i]; - if (*size > _IOC_SIZE(*cmd)) { - printk("ioctl not yet supported\n"); - return -EFAULT; - } - return 0; - } - } - return -EINVAL; -} - -static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) -{ - if (type) - *g = &floppy_type[type]; - else { - LOCK_FDC(drive,0); - CALL(poll_drive(0,0)); - process_fd_request(); - *g = current_type[drive]; - } - if (!*g) - return -ENODEV; - return 0; -} - -static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long param) -{ -#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data) -#define OUT(c,x) case c: outparam = (const char *) (x); break -#define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0 - - int drive = (long)inode->i_bdev->bd_disk->private_data; - int i, type = ITYPE(UDRS->fd_device); - int ret; - int size; - union inparam { - struct floppy_struct g; /* geometry */ - struct format_descr f; - struct floppy_max_errors max_errors; - struct floppy_drive_params dp; - } inparam; /* parameters coming from user space */ - const char *outparam; /* parameters passed back to user space */ - - /* convert compatibility eject ioctls into floppy eject ioctl. - * We do this in order to provide a means to eject floppy disks before - * installing the new fdutils package */ - if (cmd == CDROMEJECT || /* CD-ROM eject */ - cmd == 0x6470 /* SunOS floppy eject */) { - DPRINT("obsolete eject ioctl\n"); - DPRINT("please use floppycontrol --eject\n"); - cmd = FDEJECT; - } - - /* generic block device ioctls */ - switch(cmd) { - /* the following have been inspired by the corresponding - * code for other block devices. */ - struct floppy_struct *g; - case HDIO_GETGEO: - { - struct hd_geometry loc; - ECALL(get_floppy_geometry(drive, type, &g)); - loc.heads = g->head; - loc.sectors = g->sect; - loc.cylinders = g->track; - loc.start = 0; - return _COPYOUT(loc); - } - } - - /* convert the old style command into a new style command */ - if ((cmd & 0xff00) == 0x0200) { - ECALL(normalize_ioctl(&cmd, &size)); - } else - return -EINVAL; - - /* permission checks */ - if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) || - ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))) - return -EPERM; - - /* copyin */ - CLEARSTRUCT(&inparam); - if (_IOC_DIR(cmd) & _IOC_WRITE) - ECALL(fd_copyin((void *)param, &inparam, size)) - - switch (cmd) { - case FDEJECT: - if (UDRS->fd_ref != 1) - /* somebody else has this drive open */ - return -EBUSY; - LOCK_FDC(drive,1); - - /* do the actual eject. Fails on - * non-Sparc architectures */ - ret=fd_eject(UNIT(drive)); - - USETF(FD_DISK_CHANGED); - USETF(FD_VERIFY); - process_fd_request(); - return ret; - case FDCLRPRM: - LOCK_FDC(drive,1); - current_type[drive] = NULL; - floppy_sizes[drive] = MAX_DISK_SIZE << 1; - UDRS->keep_data = 0; - return invalidate_drive(inode->i_bdev); - case FDSETPRM: - case FDDEFPRM: - return set_geometry(cmd, & inparam.g, - drive, type, inode->i_bdev); - case FDGETPRM: - ECALL(get_floppy_geometry(drive, type, - (struct floppy_struct**) - &outparam)); - break; - - case FDMSGON: - UDP->flags |= FTD_MSG; - return 0; - case FDMSGOFF: - UDP->flags &= ~FTD_MSG; - return 0; - - case FDFMTBEG: - LOCK_FDC(drive,1); - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - ret = UDRS->flags; - if (ret & FD_VERIFY) { - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - ret = UDRS->flags; - } - - if (ret & FD_VERIFY) { - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - ret = UDRS->flags; - } - - if (ret & FD_VERIFY) { - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - ret = UDRS->flags; - } - - if (ret & FD_VERIFY) { - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - ret = UDRS->flags; - } - - if(ret & FD_VERIFY){ - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - ret = UDRS->flags; - } - process_fd_request(); - if (ret & FD_VERIFY) - return -ENODEV; - if (!(ret & FD_DISK_WRITABLE)) - return -EROFS; - return 0; - case FDFMTTRK: - if (UDRS->fd_ref != 1) - return -EBUSY; - return do_format(drive, &inparam.f); - case FDFMTEND: - case FDFLUSH: - LOCK_FDC(drive,1); - return invalidate_drive(inode->i_bdev); - - case FDSETEMSGTRESH: - UDP->max_errors.reporting = - (unsigned short) (param & 0x0f); - return 0; - OUT(FDGETMAXERRS, &UDP->max_errors); - IN(FDSETMAXERRS, &UDP->max_errors, max_errors); - - case FDGETDRVTYP: - outparam = drive_name(type,drive); - SUPBOUND(size,strlen(outparam)+1); - break; - - IN(FDSETDRVPRM, UDP, dp); - OUT(FDGETDRVPRM, UDP); - - case FDPOLLDRVSTAT: - LOCK_FDC(drive,1); - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - process_fd_request(); - /* fall through */ - OUT(FDGETDRVSTAT, UDRS); - - case FDRESET: - return user_reset_fdc(drive, (int)param, 1); - - OUT(FDGETFDCSTAT,UFDCS); - - case FDWERRORCLR: - CLEARSTRUCT(UDRWE); - return 0; - OUT(FDWERRORGET,UDRWE); - - case FDRAWCMD: - if (type) - return -EINVAL; - LOCK_FDC(drive,1); - set_floppy(drive); - CALL(i = raw_cmd_ioctl(cmd,(void *) param)); - process_fd_request(); - return i; - - case FDTWADDLE: - LOCK_FDC(drive,1); - twaddle(); - process_fd_request(); - return 0; - - default: - return -EINVAL; - } - - if (_IOC_DIR(cmd) & _IOC_READ) - return fd_copyout((void *)param, outparam, size); - else - return 0; -#undef OUT -#undef IN -} - -static void __init config_types(void) -{ - int first=1; - int drive; - extern struct fd_info { - unsigned char dummy[4 * 6]; - unsigned char fd_types[8]; - } drive_info; - - for (drive = 0; drive < 4; drive++) - UDP->cmos = drive_info.fd_types[drive]; - - /* XXX */ - /* additional physical CMOS drive detection should go here */ - - for (drive=0; drive < N_DRIVE; drive++){ - unsigned int type = UDP->cmos; - struct floppy_drive_params *params; - const char *name = NULL; - static char temparea[32]; - - if (type < NUMBER(default_drive_params)) { - params = &default_drive_params[type].params; - if (type) { - name = default_drive_params[type].name; - allowed_drive_mask |= 1 << drive; - } - else - allowed_drive_mask &= ~(1 << drive); - } else { - params = &default_drive_params[0].params; - sprintf(temparea, "unknown type %d (usb?)", type); - name = temparea; - } - if (name) { - const char * prepend = ","; - if (first) { - prepend = KERN_INFO "Floppy drive(s):"; - first = 0; - } - printk("%s fd%d is %s", prepend, drive, name); - register_devfs_entries (drive); - } - *UDP = *params; - } - if (!first) - printk("\n"); -} - -static int floppy_release(struct inode * inode, struct file * filp) -{ - int drive = (long)inode->i_bdev->bd_disk->private_data; - - down(&open_lock); - if (UDRS->fd_ref < 0) - UDRS->fd_ref=0; - else if (!UDRS->fd_ref--) { - DPRINT("floppy_release with fd_ref == 0"); - UDRS->fd_ref = 0; - } - if (!UDRS->fd_ref) - opened_bdev[drive] = NULL; - floppy_release_irq_and_dma(); - up(&open_lock); - return 0; -} - -/* - * floppy_open check for aliasing (/dev/fd0 can be the same as - * /dev/PS0 etc), and disallows simultaneous access to the same - * drive with different device numbers. - */ -#define RETERR(x) do{floppy_release(inode,filp); return -(x);}while(0) - -static int floppy_open(struct inode * inode, struct file * filp) -{ - int drive = (long)inode->i_bdev->bd_disk->private_data; - int old_dev; - int try; - int res = -EBUSY; - char *tmp; - -#ifdef PC9800_DEBUG_FLOPPY - printk("floppy open: start\n"); -#endif - filp->private_data = (void*) 0; - -#ifdef PC9800_DEBUG_FLOPPY - printk("floppy open: drive=%d, current_drive=%d, UDP->cmos=%d\n" - "floppy open: FDCS={spec1=%d, spec2=%d, dtr=%d, version=%d, dor=%d, address=%lu}\n", - drive, current_drive, UDP->cmos, FDCS->spec1, FDCS->spec2, - FDCS->dtr, FDCS->version, FDCS->dor, FDCS->address); - if (_floppy) { - printk("floppy open: _floppy={size=%d, sect=%d, head=%d, track=%d, spec1=%d}\n", - _floppy->size, _floppy->sect, _floppy->head, - _floppy->track, _floppy->spec1); - } else { - printk("floppy open: _floppy=NULL\n"); - } -#endif /* PC9800_DEBUG_FLOPPY */ - - down(&open_lock); - old_dev = UDRS->fd_device; - if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev) - goto out2; - - if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){ - USETF(FD_DISK_CHANGED); - USETF(FD_VERIFY); - } - - if (UDRS->fd_ref == -1 || - (UDRS->fd_ref && (filp->f_flags & O_EXCL))) - goto out2; - - if (floppy_grab_irq_and_dma()) - goto out2; - - if (filp->f_flags & O_EXCL) - UDRS->fd_ref = -1; - else - UDRS->fd_ref++; - - opened_bdev[drive] = inode->i_bdev; - - res = -ENXIO; - - if (!floppy_track_buffer){ - /* if opening an ED drive, reserve a big buffer, - * else reserve a small one */ - if ((UDP->cmos == 6) || (UDP->cmos == 5)) - try = 64; /* Only 48 actually useful */ - else - try = 32; /* Only 24 actually useful */ - - tmp=(char *)fd_dma_mem_alloc(1024 * try); - if (!tmp && !floppy_track_buffer) { - try >>= 1; /* buffer only one side */ - INFBOUND(try, 16); - tmp= (char *)fd_dma_mem_alloc(1024*try); - } - if (!tmp && !floppy_track_buffer) { - fallback_on_nodma_alloc(&tmp, 2048 * try); - } - if (!tmp && !floppy_track_buffer) { - DPRINT("Unable to allocate DMA memory\n"); - goto out; - } - if (floppy_track_buffer) { - if (tmp) - fd_dma_mem_free((unsigned long)tmp,try*1024); - } else { - buffer_min = buffer_max = -1; - floppy_track_buffer = tmp; - max_buffer_sectors = try; - } - } - - UDRS->fd_device = iminor(inode); - set_capacity(disks[drive], floppy_sizes[iminor(inode)]); - if (old_dev != -1 && old_dev != iminor(inode)) { - if (buffer_drive == drive) - buffer_track = -1; - } - -#ifdef PC9800_DEBUG_FLOPPY - printk("floppy open: floppy.c:%d passed\n", __LINE__); -#endif - - - /* Allow ioctls if we have write-permissions even if read-only open. - * Needed so that programs such as fdrawcmd still can work on write - * protected disks */ - if (filp->f_mode & 2 || permission(filp->f_dentry->d_inode,2,NULL) == 0) - filp->private_data = (void*) 8; - - if (UFDCS->rawcmd == 1) - UFDCS->rawcmd = 2; - -#ifdef PC9800_DEBUG_FLOPPY - printk("floppy open: floppy.c:%d passed\n", __LINE__); -#endif - - if (!(filp->f_flags & O_NDELAY)) { - if (filp->f_mode & 3) { - UDRS->last_checked = 0; - check_disk_change(inode->i_bdev); - if (UTESTF(FD_DISK_CHANGED)) - goto out; - } - res = -EROFS; - if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE))) - goto out; -#ifdef PC9800_DEBUG_FLOPPY - printk("floppy open: end normally\n"); -#endif - } - up(&open_lock); - return 0; -out: - if (UDRS->fd_ref < 0) - UDRS->fd_ref=0; - else - UDRS->fd_ref--; - if (!UDRS->fd_ref) - opened_bdev[drive] = NULL; - floppy_release_irq_and_dma(); -out2: - up(&open_lock); - return res; -} - -/* - * Check if the disk has been changed or if a change has been faked. - */ -static int check_floppy_change(struct gendisk *disk) -{ - int drive = (long)disk->private_data; - -#ifdef PC9800_DEBUG_FLOPPY - printk("check_floppy_change: MINOR=%d\n", minor(dev)); -#endif - - if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY)) - return 1; - - if (UDP->checkfreq < (int)(jiffies - UDRS->last_checked)) { - if(floppy_grab_irq_and_dma()) { - return 1; - } - - lock_fdc(drive,0); - poll_drive(0,0); - process_fd_request(); - floppy_release_irq_and_dma(); - } - - if (UTESTF(FD_DISK_CHANGED) || - UTESTF(FD_VERIFY) || - test_bit(drive, &fake_change) || - (!ITYPE(UDRS->fd_device) && !current_type[drive])) - return 1; - return 0; -} - -/* - * This implements "read block 0" for floppy_revalidate(). - * Needed for format autodetection, checking whether there is - * a disk in the drive, and whether that disk is writable. - */ - -static int floppy_rb0_complete(struct bio *bio, unsigned int bytes_done, int err) -{ - if (bio->bi_size) - return 1; - - complete((struct completion*)bio->bi_private); - return 0; -} - -static int __floppy_read_block_0(struct block_device *bdev) -{ - struct bio bio; - struct bio_vec bio_vec; - struct completion complete; - struct page *page; - size_t size; - - page = alloc_page(GFP_NOIO); - if (!page) { - process_fd_request(); - return -ENOMEM; - } - - size = bdev->bd_block_size; - if (!size) - size = 1024; - - bio_init(&bio); - bio.bi_io_vec = &bio_vec; - bio_vec.bv_page = page; - bio_vec.bv_len = size; - bio_vec.bv_offset = 0; - bio.bi_vcnt = 1; - bio.bi_idx = 0; - bio.bi_size = size; - bio.bi_bdev = bdev; - bio.bi_sector = 0; - init_completion(&complete); - bio.bi_private = &complete; - bio.bi_end_io = floppy_rb0_complete; - - submit_bio(READ, &bio); - generic_unplug_device(bdev_get_queue(bdev)); - process_fd_request(); - wait_for_completion(&complete); - - __free_page(page); - - return 0; -} - -/* revalidate the floppy disk, i.e. trigger format autodetection by reading - * the bootblock (block 0). "Autodetection" is also needed to check whether - * there is a disk in the drive at all... Thus we also do it for fixed - * geometry formats */ -static int floppy_revalidate(struct gendisk *disk) -{ - int drive=(long)disk->private_data; -#define NO_GEOM (!current_type[drive] && !ITYPE(UDRS->fd_device)) - int cf; - int res = 0; - - if (UTESTF(FD_DISK_CHANGED) || - UTESTF(FD_VERIFY) || - test_bit(drive, &fake_change) || - NO_GEOM){ - if(usage_count == 0) { - printk("VFS: revalidate called on non-open device.\n"); - return -EFAULT; - } - lock_fdc(drive,0); - cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY); - if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)){ - process_fd_request(); /*already done by another thread*/ - return 0; - } - UDRS->maxblock = 0; - UDRS->maxtrack = 0; - if (buffer_drive == drive) - buffer_track = -1; - clear_bit(drive, &fake_change); - UCLEARF(FD_DISK_CHANGED); - if (cf) - UDRS->generation++; - if (NO_GEOM){ - /* auto-sensing */ - res = __floppy_read_block_0(opened_bdev[drive]); - } else { - if (cf) - poll_drive(0, FD_RAW_NEED_DISK); - process_fd_request(); - } - } - set_capacity(disk, floppy_sizes[UDRS->fd_device]); - return res; -} - -static struct block_device_operations floppy_fops = { - .owner = THIS_MODULE, - .open = floppy_open, - .release = floppy_release, - .ioctl = fd_ioctl, - .media_changed = check_floppy_change, - .revalidate_disk= floppy_revalidate, -}; - -static char *table[] = -{"", -#if 0 - "d360", -#else - "h1232", -#endif - "h1200", "u360", "u720", "h360", "h720", - "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410", - "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743", - "h880", "u1040", "u1120", "h1600", "u1760", "u1920", - "u3200", "u3520", "u3840", "u1840", "u800", "u1600", -NULL -}; - -static int t360[] = { - 1,0 -}; -static int t1200[] = { - 2,5,6,10,12,14,16,18,20,23,0 -}; -static int t3in[] = { - 8, 9,26,27,28, 7,11,15,19,24,25, - 29,31, 3, 4,13,17,21,22,30, 0 -}; - -static int *table_sup[] = { - NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in -}; - -static void __init register_devfs_entries (int drive) -{ - int base_minor = (drive < 4) ? drive : (124 + drive); - - if (UDP->cmos < NUMBER(default_drive_params)) { - int i = 0; - do { - int minor = base_minor + (table_sup[UDP->cmos][i] << 2); - - devfs_mk_bdev(MKDEV(FLOPPY_MAJOR, minor), - S_IFBLK|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, - "floppy/%d%s", - drive, table[table_sup[UDP->cmos][i]]); - } while (table_sup[UDP->cmos][i++]); - } -} - -/* - * Floppy Driver initialization - * ============================= - */ - -static inline char __init get_fdc_version(void) -{ - return FDC_8272A; -} - -/* lilo configuration */ - -static void __init floppy_set_flags(int *ints,int param, int param2) -{ - int i; - - for (i=0; i < ARRAY_SIZE(default_drive_params); i++){ - if (param) - default_drive_params[i].params.flags |= param2; - else - default_drive_params[i].params.flags &= ~param2; - } - DPRINT("%s flag 0x%x\n", param2 ? "Setting" : "Clearing", param); -} - -static void __init daring(int *ints,int param, int param2) -{ - int i; - - for (i=0; i < ARRAY_SIZE(default_drive_params); i++){ - if (param){ - default_drive_params[i].params.select_delay = 0; - default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR; - } else { - default_drive_params[i].params.select_delay = 2*HZ/100; - default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR; - } - } - DPRINT("Assuming %s floppy hardware\n", param ? "standard" : "broken"); -} - -static void __init set_cmos(int *ints, int dummy, int dummy2) -{ - int current_drive=0; - - if (ints[0] != 2){ - DPRINT("wrong number of parameters for CMOS\n"); - return; - } - current_drive = ints[1]; - if (current_drive < 0 || current_drive >= 8){ - DPRINT("bad drive for set_cmos\n"); - return; - } -#if N_FDC > 1 - if (current_drive >= 4 && !FDC2) - FDC2 = 0x370; -#endif - DP->cmos = ints[2]; - DPRINT("setting CMOS code to %d\n", ints[2]); -} - -static struct param_table { - const char *name; - void (*fn)(int *ints, int param, int param2); - int *var; - int def_param; - int param2; -} config_params[]={ - { "allowed_drive_mask", 0, &allowed_drive_mask, 0xff, 0}, /* obsolete */ - { "all_drives", 0, &allowed_drive_mask, 0xff, 0 }, /* obsolete */ - { "irq", 0, &FLOPPY_IRQ, DEFAULT_FLOPPY_IRQ, 0 }, - { "dma", 0, &FLOPPY_DMA, DEFAULT_FLOPPY_DMA, 0 }, - - { "daring", daring, 0, 1, 0}, -#if N_FDC > 1 - { "two_fdc", 0, &FDC2, 0x370, 0 }, - { "one_fdc", 0, &FDC2, 0, 0 }, -#endif - { "broken_dcl", floppy_set_flags, 0, 1, FD_BROKEN_DCL }, - { "messages", floppy_set_flags, 0, 1, FTD_MSG }, - { "silent_dcl_clear", floppy_set_flags, 0, 1, FD_SILENT_DCL_CLEAR }, - { "debug", floppy_set_flags, 0, 1, FD_DEBUG }, - - { "nodma", 0, &can_use_virtual_dma, 1, 0 }, - { "yesdma", 0, &can_use_virtual_dma, 0, 0 }, - - { "fifo_depth", 0, &fifo_depth, 0xa, 0 }, - { "nofifo", 0, &no_fifo, 0x20, 0 }, - { "usefifo", 0, &no_fifo, 0, 0 }, - - { "cmos", set_cmos, 0, 0, 0 }, - { "slow", 0, &slow_floppy, 1, 0 }, - - { "unexpected_interrupts", 0, &print_unex, 1, 0 }, - { "no_unexpected_interrupts", 0, &print_unex, 0, 0 }, - - EXTRA_FLOPPY_PARAMS -}; - -static int __init floppy_setup(char *str) -{ - int i; - int param; - int ints[11]; - - str = get_options(str,ARRAY_SIZE(ints),ints); - if (str) { - for (i=0; i< ARRAY_SIZE(config_params); i++){ - if (strcmp(str,config_params[i].name) == 0){ - if (ints[0]) - param = ints[1]; - else - param = config_params[i].def_param; - if (config_params[i].fn) - config_params[i]. - fn(ints,param, - config_params[i].param2); - if (config_params[i].var) { - DPRINT("%s=%d\n", str, param); - *config_params[i].var = param; - } - return 1; - } - } - } - if (str) { - DPRINT("unknown floppy option [%s]\n", str); - - DPRINT("allowed options are:"); - for (i=0; i< ARRAY_SIZE(config_params); i++) - printk(" %s",config_params[i].name); - printk("\n"); - } else - DPRINT("botched floppy option\n"); - DPRINT("Read linux/Documentation/floppy.txt\n"); - return 0; -} - -static int have_no_fdc= -ENODEV; - -static void floppy_device_release(struct device *dev) -{ - complete(&device_release); -} - -static struct platform_device floppy_device = { - .name = "floppy", - .id = 0, - .dev = { - .release = floppy_device_release, - }, -}; - -static struct kobject *floppy_find(dev_t dev, int *part, void *data) -{ - int drive = (*part&3) | ((*part&0x80) >> 5); - if (drive >= N_DRIVE || - !(allowed_drive_mask & (1 << drive)) || - fdc_state[FDC(drive)].version == FDC_NONE) - return NULL; - if (((*part>>2) & 0x1f) >= NUMBER(floppy_type)) - return NULL; - *part = 0; - return get_disk(disks[drive]); -} - -int __init floppy_init(void) -{ - int i,unit,drive; - int err; - - raw_cmd = NULL; - FDC1 = 0x90; - - 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); - - for (i=0; i<256; i++) - if (ITYPE(i)) - floppy_sizes[i] = floppy_type[ITYPE(i)].size; - else - floppy_sizes[i] = MAX_DISK_SIZE << 1; - - floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); - if (!floppy_queue) - goto out_queue; - - reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT); - config_types(); - - for (i = 0; i < N_FDC; i++) { - fdc = i; - CLEARSTRUCT(FDCS); - FDCS->dtr = -1; - FDCS->dor = 0; - } - - if ((fd_inb(FD_MODE_CHANGE) & 1) == 0) - FDC1 = 0xc8; - - use_virtual_dma = can_use_virtual_dma & 1; - fdc_state[0].address = FDC1; - if (fdc_state[0].address == -1) { - err = -ENODEV; - goto out1; - } -#if N_FDC > 1 - fdc_state[1].address = FDC2; -#endif - - fdc = 0; /* reset fdc in case of unexpected interrupt */ - if (floppy_grab_irq_and_dma()){ - err = -EBUSY; - goto out1; - } - - /* initialise drive state */ - for (drive = 0; drive < N_DRIVE; drive++) { - CLEARSTRUCT(UDRS); - CLEARSTRUCT(UDRWE); - USETF(FD_DISK_NEWCHANGE); - USETF(FD_DISK_CHANGED); - USETF(FD_VERIFY); - UDRS->fd_device = -1; - floppy_track_buffer = NULL; - max_buffer_sectors = 0; - } - - for (i = 0; i < N_FDC; i++) { - fdc = i; - FDCS->driver_version = FD_DRIVER_VERSION; - for (unit=0; unit<4; unit++) - FDCS->track[unit] = 0; - if (FDCS->address == -1) - continue; - FDCS->rawcmd = 2; - user_reset_fdc(-1, FD_RESET_ALWAYS, 0); - - /* Try to determine the floppy controller type */ - FDCS->version = get_fdc_version(); - if (FDCS->version == FDC_NONE){ - /* free ioports reserved by floppy_grab_irq_and_dma() */ - release_region(FDCS->address, 1); - release_region(FDCS->address + 2, 1); - release_region(FDCS->address + 4, 1); - release_region(0xbe, 1); - release_region(0x4be, 1); - FDCS->address = -1; - continue; - } - if (can_use_virtual_dma == 2 && FDCS->version < FDC_82072A) - can_use_virtual_dma = 0; - - have_no_fdc = 0; - /* Not all FDCs seem to be able to handle the version command - * properly, so force a reset for the standard FDC clones, - * to avoid interrupt garbage. - */ - user_reset_fdc(-1,FD_RESET_ALWAYS,0); - } - fdc=0; - del_timer(&fd_timeout); - current_drive = 0; - floppy_release_irq_and_dma(); -#if 0 /* no message */ - initialising=0; -#endif - if (have_no_fdc) { - DPRINT("no floppy controllers found\n"); - flush_scheduled_work(); - if (usage_count) - floppy_release_irq_and_dma(); - err = have_no_fdc; - goto out2; - } - - 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) - continue; - /* to be cleaned up... */ - disks[drive]->private_data = (void*)(long)drive; - disks[drive]->queue = floppy_queue; - add_disk(disks[drive]); - } - - platform_device_register(&floppy_device); - return 0; - -out1: - del_timer_sync(&fd_timeout); -out2: - blk_cleanup_queue(floppy_queue); -out_queue: - blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); - unregister_blkdev(FLOPPY_MAJOR,"fd"); -out: - for (i=0; iaddress != -1){ - static char floppy[] = "floppy"; - if (!request_region(FDCS->address, 1, floppy)) - goto cleanup0; - - if (!request_region(FDCS->address + 2, 1, floppy)) { - release_region(FDCS->address, 1); - goto cleanup0; - } - - if (!request_region(FDCS->address + 4, 1, floppy)) { - release_region(FDCS->address, 1); - release_region(FDCS->address + 2, 1); - goto cleanup0; - } - - if (fdc == 0) { /* internal FDC */ - if (request_region(0xbe, 1, "floppy mode change")) { - if (request_region(0x4be, 1, "floppy ex. mode change")) - continue; - else - DPRINT("Floppy io-port 0x4be in use\n"); - - release_region(0xbe, 1); - } else - DPRINT("Floppy io-port 0xbe in use\n"); - - release_region(FDCS->address, 1); - release_region(FDCS->address + 2, 1); - release_region(FDCS->address + 4, 1); - } - - goto cleanup1; - } - } - for (fdc=0; fdc< N_FDC; fdc++){ - if (FDCS->address != -1){ - reset_fdc_info(1); - fd_outb(FDCS->dor, FD_MODE); - } - } - fdc = 0; - fd_outb((FDCS->dor & 8), FD_MODE); - - for (fdc = 0; fdc < N_FDC; fdc++) - if (FDCS->address != -1) - fd_outb(FDCS->dor, FD_MODE); - /* - * The driver will try and free resources and relies on us - * to know if they were allocated or not. - */ - fdc = 0; - irqdma_allocated = 1; - return 0; - -cleanup0: - DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address); -cleanup1: - fd_free_irq(); - fd_free_dma(); - while(--fdc >= 0) { - release_region(FDCS->address, 1); - release_region(FDCS->address + 2, 1); - release_region(FDCS->address + 4, 1); - if (fdc == 0) { - release_region(0x00be, 1); - release_region(0x04be, 1); - } - } - spin_lock_irqsave(&floppy_usage_lock, flags); - usage_count--; - spin_unlock_irqrestore(&floppy_usage_lock, flags); - return -1; -} - -static void floppy_release_irq_and_dma(void) -{ - int old_fdc; -#ifdef FLOPPY_SANITY_CHECK - int drive; -#endif - long tmpsize; - unsigned long tmpaddr; - unsigned long flags; - - spin_lock_irqsave(&floppy_usage_lock, flags); - if (--usage_count){ - spin_unlock_irqrestore(&floppy_usage_lock, flags); - return; - } - spin_unlock_irqrestore(&floppy_usage_lock, flags); - if(irqdma_allocated) - { - fd_disable_dma(); - fd_free_dma(); - fd_free_irq(); - irqdma_allocated=0; - } - fd_outb(0, FD_MODE); - floppy_enable_hlt(); - - if (floppy_track_buffer && max_buffer_sectors) { - tmpsize = max_buffer_sectors*1024; - tmpaddr = (unsigned long)floppy_track_buffer; - floppy_track_buffer = NULL; - max_buffer_sectors = 0; - buffer_min = buffer_max = -1; - fd_dma_mem_free(tmpaddr, tmpsize); - } - -#ifdef FLOPPY_SANITY_CHECK - for (drive=0; drive < N_FDC * 4; drive++) - if (timer_pending(motor_off_timer + drive)) - printk("motor off timer %d still active\n", drive); - - if (timer_pending(&fd_timeout)) - printk("floppy timer still active:%s\n", timeout_message); - if (timer_pending(&fd_timer)) - printk("auxiliary floppy timer still active\n"); - if (floppy_work.pending) - printk("work still pending\n"); -#endif - old_fdc = fdc; - for (fdc = 0; fdc < N_FDC; fdc++) - if (FDCS->address != -1) { - release_region(FDCS->address, 1); - release_region(FDCS->address + 2, 1); - release_region(FDCS->address + 4, 1); - if (fdc == 0) { - release_region(0xbe, 1); - release_region(0x4be, 1); - } - } - fdc = old_fdc; -} - - -#ifdef MODULE - -char *floppy; - -static void unregister_devfs_entries (int drive) -{ - int i; - - if (UDP->cmos < NUMBER(default_drive_params)) { - i = 0; - do { - devfs_remove("floppy/%d%s", drive, table[table_sup[UDP->cmos][i]]); - } while (table_sup[UDP->cmos][i++]); - } -} - -static void __init parse_floppy_cfg_string(char *cfg) -{ - char *ptr; - - while(*cfg) { - for(ptr = cfg;*cfg && *cfg != ' ' && *cfg != '\t'; cfg++); - if (*cfg) { - *cfg = '\0'; - cfg++; - } - if (*ptr) - floppy_setup(ptr); - } -} - -int init_module(void) -{ - printk(KERN_INFO "inserting floppy driver for " UTS_RELEASE "\n"); - - if (floppy) - parse_floppy_cfg_string(floppy); - return floppy_init(); -} - -void cleanup_module(void) -{ - int drive; - - init_completion(&device_release); - platform_device_unregister(&floppy_device); - blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); - unregister_blkdev(FLOPPY_MAJOR, "fd"); - - for (drive = 0; drive < N_DRIVE; drive++) { - del_timer_sync(&motor_off_timer[drive]); - - if ((allowed_drive_mask & (1 << drive)) && - fdc_state[FDC(drive)].version != FDC_NONE) { - del_gendisk(disks[drive]); - unregister_devfs_entries(drive); - } - put_disk(disks[drive]); - } - devfs_remove("floppy"); - - del_timer_sync(&fd_timeout); - del_timer_sync(&fd_timer); - blk_cleanup_queue(floppy_queue); - - if (usage_count) - floppy_release_irq_and_dma(); - - /* eject disk, if any */ - fd_eject(0); - - wait_for_completion(&device_release); -} - -MODULE_PARM(floppy,"s"); -MODULE_PARM(FLOPPY_IRQ,"i"); -MODULE_PARM(FLOPPY_DMA,"i"); -MODULE_AUTHOR("Osamu Tomita"); -MODULE_SUPPORTED_DEVICE("fd"); -MODULE_LICENSE("GPL"); - -#else - -__setup ("floppy=", floppy_setup); -module_init(floppy_init) -#endif diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c --- a/drivers/block/ll_rw_blk.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/block/ll_rw_blk.c 2004-06-26 17:09:15 -07:00 @@ -817,14 +817,14 @@ void blk_recount_segments(request_queue_t *q, struct bio *bio) { struct bio_vec *bv, *bvprv = NULL; - int i, nr_phys_segs, nr_hw_segs, seg_size, cluster; + int i, nr_phys_segs, nr_hw_segs, seg_size, hw_seg_size, cluster; int high, highprv = 1; if (unlikely(!bio->bi_io_vec)) return; cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); - seg_size = nr_phys_segs = nr_hw_segs = 0; + hw_seg_size = seg_size = nr_phys_segs = nr_hw_segs = 0; bio_for_each_segment(bv, bio, i) { /* * the trick here is making sure that a high page is never @@ -841,22 +841,35 @@ goto new_segment; if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) goto new_segment; + if (BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len)) + goto new_hw_segment; seg_size += bv->bv_len; + hw_seg_size += bv->bv_len; bvprv = bv; continue; } new_segment: - if (!BIOVEC_VIRT_MERGEABLE(bvprv, bv)) + if (BIOVEC_VIRT_MERGEABLE(bvprv, bv) && + !BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len)) { + hw_seg_size += bv->bv_len; + } else { new_hw_segment: + if (hw_seg_size > bio->bi_hw_front_size) + bio->bi_hw_front_size = hw_seg_size; + hw_seg_size = BIOVEC_VIRT_START_SIZE(bv) + bv->bv_len; nr_hw_segs++; + } nr_phys_segs++; bvprv = bv; seg_size = bv->bv_len; highprv = high; } - + if (hw_seg_size > bio->bi_hw_back_size) + bio->bi_hw_back_size = hw_seg_size; + if (nr_hw_segs == 1 && hw_seg_size > bio->bi_hw_front_size) + bio->bi_hw_front_size = hw_seg_size; bio->bi_phys_segments = nr_phys_segs; bio->bi_hw_segments = nr_hw_segs; bio->bi_flags |= (1 << BIO_SEG_VALID); @@ -889,22 +902,17 @@ int blk_hw_contig_segment(request_queue_t *q, struct bio *bio, struct bio *nxt) { - if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER))) - return 0; - - if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt))) + if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) + blk_recount_segments(q, bio); + if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID))) + blk_recount_segments(q, nxt); + if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || + BIOVEC_VIRT_OVERSIZE(bio->bi_hw_front_size + bio->bi_hw_back_size)) return 0; if (bio->bi_size + nxt->bi_size > q->max_segment_size) return 0; - /* - * bio and nxt are contigous in memory, check if the queue allows - * these two to be merged into one - */ - if (BIO_SEG_BOUNDARY(q, bio, nxt)) - return 1; - - return 0; + return 1; } EXPORT_SYMBOL(blk_hw_contig_segment); @@ -974,7 +982,8 @@ if (req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { req->flags |= REQ_NOMERGE; - q->last_merge = NULL; + if (req == q->last_merge) + q->last_merge = NULL; return 0; } @@ -996,7 +1005,8 @@ if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments || req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { req->flags |= REQ_NOMERGE; - q->last_merge = NULL; + if (req == q->last_merge) + q->last_merge = NULL; return 0; } @@ -1012,14 +1022,31 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req, struct bio *bio) { + int len; + if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) { req->flags |= REQ_NOMERGE; - q->last_merge = NULL; + if (req == q->last_merge) + q->last_merge = NULL; return 0; } - - if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio))) - return ll_new_mergeable(q, req, bio); + if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID))) + blk_recount_segments(q, req->biotail); + if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) + blk_recount_segments(q, bio); + len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; + if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) && + !BIOVEC_VIRT_OVERSIZE(len)) { + int mergeable = ll_new_mergeable(q, req, bio); + + if (mergeable) { + if (req->nr_hw_segments == 1) + req->bio->bi_hw_front_size = len; + if (bio->bi_hw_segments == 1) + bio->bi_hw_back_size = len; + } + return mergeable; + } return ll_new_hw_segment(q, req, bio); } @@ -1027,14 +1054,31 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req, struct bio *bio) { + int len; + if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) { req->flags |= REQ_NOMERGE; - q->last_merge = NULL; + if (req == q->last_merge) + q->last_merge = NULL; return 0; } - - if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio))) - return ll_new_mergeable(q, req, bio); + len = bio->bi_hw_back_size + req->bio->bi_hw_front_size; + if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) + blk_recount_segments(q, bio); + if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID))) + blk_recount_segments(q, req->bio); + if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && + !BIOVEC_VIRT_OVERSIZE(len)) { + int mergeable = ll_new_mergeable(q, req, bio); + + if (mergeable) { + if (bio->bi_hw_segments == 1) + bio->bi_hw_front_size = len; + if (req->nr_hw_segments == 1) + req->biotail->bi_hw_back_size = len; + } + return mergeable; + } return ll_new_hw_segment(q, req, bio); } @@ -1066,8 +1110,17 @@ return 0; total_hw_segments = req->nr_hw_segments + next->nr_hw_segments; - if (blk_hw_contig_segment(q, req->biotail, next->bio)) + if (blk_hw_contig_segment(q, req->biotail, next->bio)) { + int len = req->biotail->bi_hw_back_size + next->bio->bi_hw_front_size; + /* + * propagate the combined length to the end of the requests + */ + if (req->nr_hw_segments == 1) + req->bio->bi_hw_front_size = len; + if (next->nr_hw_segments == 1) + next->biotail->bi_hw_back_size = len; total_hw_segments--; + } if (total_hw_segments > q->max_hw_segments) return 0; @@ -1123,7 +1176,7 @@ /* * remove the plug and let it rip.. */ -static inline void __generic_unplug_device(request_queue_t *q) +inline void __generic_unplug_device(request_queue_t *q) { if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) return; @@ -1137,6 +1190,7 @@ if (elv_next_request(q)) q->request_fn(q); } +EXPORT_SYMBOL(__generic_unplug_device); /** * generic_unplug_device - fire a request queue @@ -2280,13 +2334,9 @@ out: if (freereq) __blk_put_request(q, freereq); + if (bio_sync(bio)) + __generic_unplug_device(q); - if (blk_queue_plugged(q)) { - int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight; - - if (nrq == q->unplug_thresh || bio_sync(bio)) - __generic_unplug_device(q); - } spin_unlock_irq(q->queue_lock); return 0; @@ -2535,7 +2585,7 @@ void blk_recalc_rq_segments(struct request *rq) { - struct bio *bio; + struct bio *bio, *prevbio = NULL; int nr_phys_segs, nr_hw_segs; if (!rq->bio) @@ -2548,6 +2598,13 @@ nr_phys_segs += bio_phys_segments(rq->q, bio); nr_hw_segs += bio_hw_segments(rq->q, bio); + if (prevbio) { + if (blk_phys_contig_segment(rq->q, prevbio, bio)) + nr_phys_segs--; + if (blk_hw_contig_segment(rq->q, prevbio, bio)) + nr_hw_segs--; + } + prevbio = bio; } rq->nr_phys_segments = nr_phys_segs; @@ -2610,7 +2667,7 @@ } total_bytes = bio_nbytes = 0; - while ((bio = req->bio)) { + while ((bio = req->bio) != NULL) { int nbytes; if (nr_bytes >= bio->bi_size) { diff -Nru a/drivers/block/sx8.c b/drivers/block/sx8.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/block/sx8.c 2004-06-26 17:09:19 -07:00 @@ -0,0 +1,1763 @@ +/* + * sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware + * + * Copyright 2004 Red Hat, Inc. + * + * Author/maintainer: Jeff Garzik + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Jeff Garzik"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Promise SATA SX8 block driver"); + +#if 0 +#define CARM_DEBUG +#define CARM_VERBOSE_DEBUG +#else +#undef CARM_DEBUG +#undef CARM_VERBOSE_DEBUG +#endif +#undef CARM_NDEBUG + +#define DRV_NAME "sx8" +#define DRV_VERSION "0.8" +#define PFX DRV_NAME ": " + +#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN) + +/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */ +#define TAG_ENCODE(tag) (((tag) << 16) | 0xf) +#define TAG_DECODE(tag) (((tag) >> 16) & 0x1f) +#define TAG_VALID(tag) ((((tag) & 0xf) == 0xf) && (TAG_DECODE(tag) < 32)) + +/* note: prints function name for you */ +#ifdef CARM_DEBUG +#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) +#ifdef CARM_VERBOSE_DEBUG +#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) +#else +#define VPRINTK(fmt, args...) +#endif /* CARM_VERBOSE_DEBUG */ +#else +#define DPRINTK(fmt, args...) +#define VPRINTK(fmt, args...) +#endif /* CARM_DEBUG */ + +#ifdef CARM_NDEBUG +#define assert(expr) +#else +#define assert(expr) \ + if(unlikely(!(expr))) { \ + printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + } +#endif + +/* defines only for the constants which don't work well as enums */ +struct carm_host; + +enum { + /* adapter-wide limits */ + CARM_MAX_PORTS = 8, + CARM_SHM_SIZE = (4096 << 7), + CARM_MINORS_PER_MAJOR = 256 / CARM_MAX_PORTS, + CARM_MAX_WAIT_Q = CARM_MAX_PORTS + 1, + + /* command message queue limits */ + CARM_MAX_REQ = 64, /* max command msgs per host */ + CARM_MAX_Q = 1, /* one command at a time */ + CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */ + + /* S/G limits, host-wide and per-request */ + CARM_MAX_REQ_SG = 32, /* max s/g entries per request */ + CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */ + CARM_MAX_HOST_SG = 600, /* max s/g entries per host */ + CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */ + + /* hardware registers */ + CARM_IHQP = 0x1c, + CARM_INT_STAT = 0x10, /* interrupt status */ + CARM_INT_MASK = 0x14, /* interrupt mask */ + CARM_HMUC = 0x18, /* host message unit control */ + RBUF_ADDR_LO = 0x20, /* response msg DMA buf low 32 bits */ + RBUF_ADDR_HI = 0x24, /* response msg DMA buf high 32 bits */ + RBUF_BYTE_SZ = 0x28, + CARM_RESP_IDX = 0x2c, + CARM_CMS0 = 0x30, /* command message size reg 0 */ + CARM_LMUC = 0x48, + CARM_HMPHA = 0x6c, + CARM_INITC = 0xb5, + + /* bits in CARM_INT_{STAT,MASK} */ + INT_RESERVED = 0xfffffff0, + INT_WATCHDOG = (1 << 3), /* watchdog timer */ + INT_Q_OVERFLOW = (1 << 2), /* cmd msg q overflow */ + INT_Q_AVAILABLE = (1 << 1), /* cmd msg q has free space */ + INT_RESPONSE = (1 << 0), /* response msg available */ + INT_ACK_MASK = INT_WATCHDOG | INT_Q_OVERFLOW, + INT_DEF_MASK = INT_RESERVED | INT_Q_OVERFLOW | + INT_RESPONSE, + + /* command messages, and related register bits */ + CARM_HAVE_RESP = 0x01, + CARM_MSG_READ = 1, + CARM_MSG_WRITE = 2, + CARM_MSG_VERIFY = 3, + CARM_MSG_GET_CAPACITY = 4, + CARM_MSG_FLUSH = 5, + CARM_MSG_IOCTL = 6, + CARM_MSG_ARRAY = 8, + CARM_MSG_MISC = 9, + CARM_CME = (1 << 2), + CARM_RME = (1 << 1), + CARM_WZBC = (1 << 0), + CARM_RMI = (1 << 0), + CARM_Q_FULL = (1 << 3), + CARM_MSG_SIZE = 288, + CARM_Q_LEN = 48, + + /* CARM_MSG_IOCTL messages */ + CARM_IOC_SCAN_CHAN = 5, /* scan channels for devices */ + CARM_IOC_GET_TCQ = 13, /* get tcq/ncq depth */ + CARM_IOC_SET_TCQ = 14, /* set tcq/ncq depth */ + + IOC_SCAN_CHAN_NODEV = 0x1f, + IOC_SCAN_CHAN_OFFSET = 0x40, + + /* CARM_MSG_ARRAY messages */ + CARM_ARRAY_INFO = 0, + + ARRAY_NO_EXIST = (1 << 31), + + /* response messages */ + RMSG_SZ = 8, /* sizeof(struct carm_response) */ + RMSG_Q_LEN = 48, /* resp. msg list length */ + RMSG_OK = 1, /* bit indicating msg was successful */ + /* length of entire resp. msg buffer */ + RBUF_LEN = RMSG_SZ * RMSG_Q_LEN, + + PDC_SHM_SIZE = (4096 << 7), /* length of entire h/w buffer */ + + /* CARM_MSG_MISC messages */ + MISC_GET_FW_VER = 2, + MISC_ALLOC_MEM = 3, + MISC_SET_TIME = 5, + + /* MISC_GET_FW_VER feature bits */ + FW_VER_4PORT = (1 << 2), /* 1=4 ports, 0=8 ports */ + FW_VER_NON_RAID = (1 << 1), /* 1=non-RAID firmware, 0=RAID */ + FW_VER_ZCR = (1 << 0), /* zero channel RAID (whatever that is) */ + + /* carm_host flags */ + FL_NON_RAID = FW_VER_NON_RAID, + FL_4PORT = FW_VER_4PORT, + FL_FW_VER_MASK = (FW_VER_NON_RAID | FW_VER_4PORT), + FL_DAC = (1 << 16), + FL_DYN_MAJOR = (1 << 17), +}; + +enum scatter_gather_types { + SGT_32BIT = 0, + SGT_64BIT = 1, +}; + +enum host_states { + HST_INVALID, /* invalid state; never used */ + HST_ALLOC_BUF, /* setting up master SHM area */ + HST_ERROR, /* we never leave here */ + HST_PORT_SCAN, /* start dev scan */ + HST_DEV_SCAN_START, /* start per-device probe */ + HST_DEV_SCAN, /* continue per-device probe */ + HST_DEV_ACTIVATE, /* activate devices we found */ + HST_PROBE_FINISHED, /* probe is complete */ + HST_PROBE_START, /* initiate probe */ + HST_SYNC_TIME, /* tell firmware what time it is */ + HST_GET_FW_VER, /* get firmware version, adapter port cnt */ +}; + +#ifdef CARM_DEBUG +static const char *state_name[] = { + "HST_INVALID", + "HST_ALLOC_BUF", + "HST_ERROR", + "HST_PORT_SCAN", + "HST_DEV_SCAN_START", + "HST_DEV_SCAN", + "HST_DEV_ACTIVATE", + "HST_PROBE_FINISHED", + "HST_PROBE_START", + "HST_SYNC_TIME", + "HST_GET_FW_VER", +}; +#endif + +struct carm_port { + unsigned int port_no; + unsigned int n_queued; + struct gendisk *disk; + struct carm_host *host; + + /* attached device characteristics */ + u64 capacity; + char name[41]; + u16 dev_geom_head; + u16 dev_geom_sect; + u16 dev_geom_cyl; +}; + +struct carm_request { + unsigned int tag; + int n_elem; + unsigned int msg_type; + unsigned int msg_subtype; + unsigned int msg_bucket; + struct request *rq; + struct carm_port *port; + struct scatterlist sg[CARM_MAX_REQ_SG]; +}; + +struct carm_host { + unsigned long flags; + void *mmio; + void *shm; + dma_addr_t shm_dma; + + int major; + int id; + char name[32]; + + spinlock_t lock; + struct pci_dev *pdev; + unsigned int state; + u32 fw_ver; + + request_queue_t *oob_q; + unsigned int n_oob; + + unsigned int hw_sg_used; + + unsigned int resp_idx; + + unsigned int wait_q_prod; + unsigned int wait_q_cons; + request_queue_t *wait_q[CARM_MAX_WAIT_Q]; + + unsigned int n_msgs; + u64 msg_alloc; + struct carm_request req[CARM_MAX_REQ]; + void *msg_base; + dma_addr_t msg_dma; + + int cur_scan_dev; + unsigned long dev_active; + unsigned long dev_present; + struct carm_port port[CARM_MAX_PORTS]; + + struct work_struct fsm_task; + + struct semaphore probe_sem; +}; + +struct carm_response { + u32 ret_handle; + u32 status; +} __attribute__((packed)); + +struct carm_msg_sg { + u32 start; + u32 len; +} __attribute__((packed)); + +struct carm_msg_rw { + u8 type; + u8 id; + u8 sg_count; + u8 sg_type; + u32 handle; + u32 lba; + u16 lba_count; + u16 lba_high; + struct carm_msg_sg sg[32]; +} __attribute__((packed)); + +struct carm_msg_allocbuf { + u8 type; + u8 subtype; + u8 n_sg; + u8 sg_type; + u32 handle; + u32 addr; + u32 len; + u32 evt_pool; + u32 n_evt; + u32 rbuf_pool; + u32 n_rbuf; + u32 msg_pool; + u32 n_msg; + struct carm_msg_sg sg[8]; +} __attribute__((packed)); + +struct carm_msg_ioctl { + u8 type; + u8 subtype; + u8 array_id; + u8 reserved1; + u32 handle; + u32 data_addr; + u32 reserved2; +} __attribute__((packed)); + +struct carm_msg_sync_time { + u8 type; + u8 subtype; + u16 reserved1; + u32 handle; + u32 reserved2; + u32 timestamp; +} __attribute__((packed)); + +struct carm_msg_get_fw_ver { + u8 type; + u8 subtype; + u16 reserved1; + u32 handle; + u32 data_addr; + u32 reserved2; +} __attribute__((packed)); + +struct carm_fw_ver { + u32 version; + u8 features; + u8 reserved1; + u16 reserved2; +} __attribute__((packed)); + +struct carm_array_info { + u32 size; + + u16 size_hi; + u16 stripe_size; + + u32 mode; + + u16 stripe_blk_sz; + u16 reserved1; + + u16 cyl; + u16 head; + + u16 sect; + u8 array_id; + u8 reserved2; + + char name[40]; + + u32 array_status; + + /* device list continues beyond this point? */ +} __attribute__((packed)); + +static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); +static void carm_remove_one (struct pci_dev *pdev); +static int carm_bdev_ioctl(struct inode *ino, struct file *fil, + unsigned int cmd, unsigned long arg); + +static struct pci_device_id carm_pci_tbl[] = { + { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + { PCI_VENDOR_ID_PROMISE, 0x8002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + { } /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, carm_pci_tbl); + +static struct pci_driver carm_driver = { + .name = DRV_NAME, + .id_table = carm_pci_tbl, + .probe = carm_init_one, + .remove = carm_remove_one, +}; + +static struct block_device_operations carm_bd_ops = { + .owner = THIS_MODULE, + .ioctl = carm_bdev_ioctl, +}; + +static unsigned int carm_host_id; +static unsigned long carm_major_alloc; + + + +static int carm_bdev_ioctl(struct inode *ino, struct file *fil, + unsigned int cmd, unsigned long arg) +{ + void __user *usermem = (void __user *) arg; + struct carm_port *port = ino->i_bdev->bd_disk->private_data; + struct hd_geometry geom; + + switch (cmd) { + case HDIO_GETGEO: + if (!usermem) + return -EINVAL; + + geom.heads = (u8) port->dev_geom_head; + geom.sectors = (u8) port->dev_geom_sect; + geom.cylinders = port->dev_geom_cyl; + geom.start = get_start_sect(ino->i_bdev); + + if (copy_to_user(usermem, &geom, sizeof(geom))) + return -EFAULT; + return 0; + + default: + break; + } + + return -EOPNOTSUPP; +} + +static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE }; + +static inline int carm_lookup_bucket(u32 msg_size) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) + if (msg_size <= msg_sizes[i]) + return i; + + return -ENOENT; +} + +static void carm_init_buckets(void *mmio) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) + writel(msg_sizes[i], mmio + CARM_CMS0 + (4 * i)); +} + +static inline void *carm_ref_msg(struct carm_host *host, + unsigned int msg_idx) +{ + return host->msg_base + (msg_idx * CARM_MSG_SIZE); +} + +static inline dma_addr_t carm_ref_msg_dma(struct carm_host *host, + unsigned int msg_idx) +{ + return host->msg_dma + (msg_idx * CARM_MSG_SIZE); +} + +static int carm_send_msg(struct carm_host *host, + struct carm_request *crq) +{ + void *mmio = host->mmio; + u32 msg = (u32) carm_ref_msg_dma(host, crq->tag); + u32 cm_bucket = crq->msg_bucket; + u32 tmp; + int rc = 0; + + VPRINTK("ENTER\n"); + + tmp = readl(mmio + CARM_HMUC); + if (tmp & CARM_Q_FULL) { +#if 0 + tmp = readl(mmio + CARM_INT_MASK); + tmp |= INT_Q_AVAILABLE; + writel(tmp, mmio + CARM_INT_MASK); + readl(mmio + CARM_INT_MASK); /* flush */ +#endif + DPRINTK("host msg queue full\n"); + rc = -EBUSY; + } else { + writel(msg | (cm_bucket << 1), mmio + CARM_IHQP); + readl(mmio + CARM_IHQP); /* flush */ + } + + return rc; +} + +static struct carm_request *carm_get_request(struct carm_host *host) +{ + unsigned int i; + + /* obey global hardware limit on S/G entries */ + if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG)) + return NULL; + + for (i = 0; i < CARM_MAX_Q; i++) + if ((host->msg_alloc & (1ULL << i)) == 0) { + struct carm_request *crq = &host->req[i]; + crq->port = NULL; + crq->n_elem = 0; + + host->msg_alloc |= (1ULL << i); + host->n_msgs++; + + assert(host->n_msgs <= CARM_MAX_REQ); + return crq; + } + + DPRINTK("no request available, returning NULL\n"); + return NULL; +} + +static int carm_put_request(struct carm_host *host, struct carm_request *crq) +{ + assert(crq->tag < CARM_MAX_Q); + + if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0)) + return -EINVAL; /* tried to clear a tag that was not active */ + + assert(host->hw_sg_used >= crq->n_elem); + + host->msg_alloc &= ~(1ULL << crq->tag); + host->hw_sg_used -= crq->n_elem; + host->n_msgs--; + + return 0; +} + +static struct carm_request *carm_get_special(struct carm_host *host) +{ + unsigned long flags; + struct carm_request *crq = NULL; + struct request *rq; + int tries = 5000; + + while (tries-- > 0) { + spin_lock_irqsave(&host->lock, flags); + crq = carm_get_request(host); + spin_unlock_irqrestore(&host->lock, flags); + + if (crq) + break; + msleep(10); + } + + if (!crq) + return NULL; + + rq = blk_get_request(host->oob_q, WRITE /* bogus */, GFP_KERNEL); + if (!rq) { + spin_lock_irqsave(&host->lock, flags); + carm_put_request(host, crq); + spin_unlock_irqrestore(&host->lock, flags); + return NULL; + } + + crq->rq = rq; + return crq; +} + +static int carm_array_info (struct carm_host *host, unsigned int array_idx) +{ + struct carm_msg_ioctl *ioc; + unsigned int idx; + u32 msg_data; + dma_addr_t msg_dma; + struct carm_request *crq; + int rc; + + crq = carm_get_special(host); + if (!crq) { + rc = -ENOMEM; + goto err_out; + } + + idx = crq->tag; + + ioc = carm_ref_msg(host, idx); + msg_dma = carm_ref_msg_dma(host, idx); + msg_data = (u32) (msg_dma + sizeof(struct carm_array_info)); + + crq->msg_type = CARM_MSG_ARRAY; + crq->msg_subtype = CARM_ARRAY_INFO; + rc = carm_lookup_bucket(sizeof(struct carm_msg_ioctl) + + sizeof(struct carm_array_info)); + BUG_ON(rc < 0); + crq->msg_bucket = (u32) rc; + + memset(ioc, 0, sizeof(*ioc)); + ioc->type = CARM_MSG_ARRAY; + ioc->subtype = CARM_ARRAY_INFO; + ioc->array_id = (u8) array_idx; + ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); + ioc->data_addr = cpu_to_le32(msg_data); + + spin_lock_irq(&host->lock); + assert(host->state == HST_DEV_SCAN_START || + host->state == HST_DEV_SCAN); + spin_unlock_irq(&host->lock); + + DPRINTK("blk_insert_request, tag == %u\n", idx); + blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); + + return 0; + +err_out: + spin_lock_irq(&host->lock); + host->state = HST_ERROR; + spin_unlock_irq(&host->lock); + return rc; +} + +typedef unsigned int (*carm_sspc_t)(struct carm_host *, unsigned int, void *); + +static int carm_send_special (struct carm_host *host, carm_sspc_t func) +{ + struct carm_request *crq; + struct carm_msg_ioctl *ioc; + void *mem; + unsigned int idx, msg_size; + int rc; + + crq = carm_get_special(host); + if (!crq) + return -ENOMEM; + + idx = crq->tag; + + mem = carm_ref_msg(host, idx); + + msg_size = func(host, idx, mem); + + ioc = mem; + crq->msg_type = ioc->type; + crq->msg_subtype = ioc->subtype; + rc = carm_lookup_bucket(msg_size); + BUG_ON(rc < 0); + crq->msg_bucket = (u32) rc; + + DPRINTK("blk_insert_request, tag == %u\n", idx); + blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); + + return 0; +} + +static unsigned int carm_fill_sync_time(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct timeval tv; + struct carm_msg_sync_time *st = mem; + + do_gettimeofday(&tv); + + memset(st, 0, sizeof(*st)); + st->type = CARM_MSG_MISC; + st->subtype = MISC_SET_TIME; + st->handle = cpu_to_le32(TAG_ENCODE(idx)); + st->timestamp = cpu_to_le32(tv.tv_sec); + + return sizeof(struct carm_msg_sync_time); +} + +static unsigned int carm_fill_alloc_buf(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct carm_msg_allocbuf *ab = mem; + + memset(ab, 0, sizeof(*ab)); + ab->type = CARM_MSG_MISC; + ab->subtype = MISC_ALLOC_MEM; + ab->handle = cpu_to_le32(TAG_ENCODE(idx)); + ab->n_sg = 1; + ab->sg_type = SGT_32BIT; + ab->addr = cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1)); + ab->len = cpu_to_le32(PDC_SHM_SIZE >> 1); + ab->evt_pool = cpu_to_le32(host->shm_dma + (16 * 1024)); + ab->n_evt = cpu_to_le32(1024); + ab->rbuf_pool = cpu_to_le32(host->shm_dma); + ab->n_rbuf = cpu_to_le32(RMSG_Q_LEN); + ab->msg_pool = cpu_to_le32(host->shm_dma + RBUF_LEN); + ab->n_msg = cpu_to_le32(CARM_Q_LEN); + ab->sg[0].start = cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1)); + ab->sg[0].len = cpu_to_le32(65536); + + return sizeof(struct carm_msg_allocbuf); +} + +static unsigned int carm_fill_scan_channels(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct carm_msg_ioctl *ioc = mem; + u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) + + IOC_SCAN_CHAN_OFFSET); + + memset(ioc, 0, sizeof(*ioc)); + ioc->type = CARM_MSG_IOCTL; + ioc->subtype = CARM_IOC_SCAN_CHAN; + ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); + ioc->data_addr = cpu_to_le32(msg_data); + + /* fill output data area with "no device" default values */ + mem += IOC_SCAN_CHAN_OFFSET; + memset(mem, IOC_SCAN_CHAN_NODEV, CARM_MAX_PORTS); + + return IOC_SCAN_CHAN_OFFSET + CARM_MAX_PORTS; +} + +static unsigned int carm_fill_get_fw_ver(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct carm_msg_get_fw_ver *ioc = mem; + u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) + sizeof(*ioc)); + + memset(ioc, 0, sizeof(*ioc)); + ioc->type = CARM_MSG_MISC; + ioc->subtype = MISC_GET_FW_VER; + ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); + ioc->data_addr = cpu_to_le32(msg_data); + + return sizeof(struct carm_msg_get_fw_ver) + + sizeof(struct carm_fw_ver); +} + +static inline void carm_end_request_queued(struct carm_host *host, + struct carm_request *crq, + int uptodate) +{ + struct request *req = crq->rq; + int rc; + + rc = end_that_request_first(req, uptodate, req->hard_nr_sectors); + assert(rc == 0); + + end_that_request_last(req); + + rc = carm_put_request(host, crq); + assert(rc == 0); +} + +static inline void carm_push_q (struct carm_host *host, request_queue_t *q) +{ + unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q; + + blk_stop_queue(q); + VPRINTK("STOPPED QUEUE %p\n", q); + + host->wait_q[idx] = q; + host->wait_q_prod++; + BUG_ON(host->wait_q_prod == host->wait_q_cons); /* overrun */ +} + +static inline request_queue_t *carm_pop_q(struct carm_host *host) +{ + unsigned int idx; + + if (host->wait_q_prod == host->wait_q_cons) + return NULL; + + idx = host->wait_q_cons % CARM_MAX_WAIT_Q; + host->wait_q_cons++; + + return host->wait_q[idx]; +} + +static inline void carm_round_robin(struct carm_host *host) +{ + request_queue_t *q = carm_pop_q(host); + if (q) { + blk_start_queue(q); + VPRINTK("STARTED QUEUE %p\n", q); + } +} + +static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, + int is_ok) +{ + carm_end_request_queued(host, crq, is_ok); + if (CARM_MAX_Q == 1) + carm_round_robin(host); + else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && + (host->hw_sg_used <= CARM_SG_LOW_WATER)) { + carm_round_robin(host); + } +} + +static void carm_oob_rq_fn(request_queue_t *q) +{ + struct carm_host *host = q->queuedata; + struct carm_request *crq; + struct request *rq; + int rc; + + while (1) { + DPRINTK("get req\n"); + rq = elv_next_request(q); + if (!rq) + break; + + blkdev_dequeue_request(rq); + + crq = rq->special; + assert(crq != NULL); + assert(crq->rq == rq); + + crq->n_elem = 0; + + DPRINTK("send req\n"); + rc = carm_send_msg(host, crq); + if (rc) { + blk_requeue_request(q, rq); + carm_push_q(host, q); + return; /* call us again later, eventually */ + } + } +} + +static void carm_rq_fn(request_queue_t *q) +{ + struct carm_port *port = q->queuedata; + struct carm_host *host = port->host; + struct carm_msg_rw *msg; + struct carm_request *crq; + struct request *rq; + struct scatterlist *sg; + int writing = 0, pci_dir, i, n_elem, rc; + u32 tmp; + unsigned int msg_size; + +queue_one_request: + VPRINTK("get req\n"); + rq = elv_next_request(q); + if (!rq) + return; + + crq = carm_get_request(host); + if (!crq) { + carm_push_q(host, q); + return; /* call us again later, eventually */ + } + crq->rq = rq; + + blkdev_dequeue_request(rq); + + if (rq_data_dir(rq) == WRITE) { + writing = 1; + pci_dir = PCI_DMA_TODEVICE; + } else { + pci_dir = PCI_DMA_FROMDEVICE; + } + + /* get scatterlist from block layer */ + sg = &crq->sg[0]; + n_elem = blk_rq_map_sg(q, rq, sg); + if (n_elem <= 0) { + carm_end_rq(host, crq, 0); + return; /* request with no s/g entries? */ + } + + /* map scatterlist to PCI bus addresses */ + n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); + if (n_elem <= 0) { + carm_end_rq(host, crq, 0); + return; /* request with no s/g entries? */ + } + crq->n_elem = n_elem; + crq->port = port; + host->hw_sg_used += n_elem; + + /* + * build read/write message + */ + + VPRINTK("build msg\n"); + msg = (struct carm_msg_rw *) carm_ref_msg(host, crq->tag); + + if (writing) { + msg->type = CARM_MSG_WRITE; + crq->msg_type = CARM_MSG_WRITE; + } else { + msg->type = CARM_MSG_READ; + crq->msg_type = CARM_MSG_READ; + } + + msg->id = port->port_no; + msg->sg_count = n_elem; + msg->sg_type = SGT_32BIT; + msg->handle = cpu_to_le32(TAG_ENCODE(crq->tag)); + msg->lba = cpu_to_le32(rq->sector & 0xffffffff); + tmp = (rq->sector >> 16) >> 16; + msg->lba_high = cpu_to_le16( (u16) tmp ); + msg->lba_count = cpu_to_le16(rq->nr_sectors); + + msg_size = sizeof(struct carm_msg_rw) - sizeof(msg->sg); + for (i = 0; i < n_elem; i++) { + struct carm_msg_sg *carm_sg = &msg->sg[i]; + carm_sg->start = cpu_to_le32(sg_dma_address(&crq->sg[i])); + carm_sg->len = cpu_to_le32(sg_dma_len(&crq->sg[i])); + msg_size += sizeof(struct carm_msg_sg); + } + + rc = carm_lookup_bucket(msg_size); + BUG_ON(rc < 0); + crq->msg_bucket = (u32) rc; + + /* + * queue read/write message to hardware + */ + + VPRINTK("send msg, tag == %u\n", crq->tag); + rc = carm_send_msg(host, crq); + if (rc) { + carm_put_request(host, crq); + blk_requeue_request(q, rq); + carm_push_q(host, q); + return; /* call us again later, eventually */ + } + + goto queue_one_request; +} + +static void carm_handle_array_info(struct carm_host *host, + struct carm_request *crq, u8 *mem, + int is_ok) +{ + struct carm_port *port; + u8 *msg_data = mem + sizeof(struct carm_array_info); + struct carm_array_info *desc = (struct carm_array_info *) msg_data; + u64 lo, hi; + int cur_port; + size_t slen; + + DPRINTK("ENTER\n"); + + carm_end_rq(host, crq, is_ok); + + if (!is_ok) + goto out; + if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST) + goto out; + + cur_port = host->cur_scan_dev; + + /* should never occur */ + if ((cur_port < 0) || (cur_port >= CARM_MAX_PORTS)) { + printk(KERN_ERR PFX "BUG: cur_scan_dev==%d, array_id==%d\n", + cur_port, (int) desc->array_id); + goto out; + } + + port = &host->port[cur_port]; + + lo = (u64) le32_to_cpu(desc->size); + hi = (u64) le32_to_cpu(desc->size_hi); + + port->capacity = lo | (hi << 32); + port->dev_geom_head = le16_to_cpu(desc->head); + port->dev_geom_sect = le16_to_cpu(desc->sect); + port->dev_geom_cyl = le16_to_cpu(desc->cyl); + + host->dev_active |= (1 << cur_port); + + strncpy(port->name, desc->name, sizeof(port->name)); + port->name[sizeof(port->name) - 1] = 0; + slen = strlen(port->name); + while (slen && (port->name[slen - 1] == ' ')) { + port->name[slen - 1] = 0; + slen--; + } + + printk(KERN_INFO DRV_NAME "(%s): port %u device %Lu sectors\n", + pci_name(host->pdev), port->port_no, + (unsigned long long) port->capacity); + printk(KERN_INFO DRV_NAME "(%s): port %u device \"%s\"\n", + pci_name(host->pdev), port->port_no, port->name); + +out: + assert(host->state == HST_DEV_SCAN); + schedule_work(&host->fsm_task); +} + +static void carm_handle_scan_chan(struct carm_host *host, + struct carm_request *crq, u8 *mem, + int is_ok) +{ + u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET; + unsigned int i, dev_count = 0; + int new_state = HST_DEV_SCAN_START; + + DPRINTK("ENTER\n"); + + carm_end_rq(host, crq, is_ok); + + if (!is_ok) { + new_state = HST_ERROR; + goto out; + } + + /* TODO: scan and support non-disk devices */ + for (i = 0; i < 8; i++) + if (msg_data[i] == 0) { /* direct-access device (disk) */ + host->dev_present |= (1 << i); + dev_count++; + } + + printk(KERN_INFO DRV_NAME "(%s): found %u interesting devices\n", + pci_name(host->pdev), dev_count); + +out: + assert(host->state == HST_PORT_SCAN); + host->state = new_state; + schedule_work(&host->fsm_task); +} + +static void carm_handle_generic(struct carm_host *host, + struct carm_request *crq, int is_ok, + int cur_state, int next_state) +{ + DPRINTK("ENTER\n"); + + carm_end_rq(host, crq, is_ok); + + assert(host->state == cur_state); + if (is_ok) + host->state = next_state; + else + host->state = HST_ERROR; + schedule_work(&host->fsm_task); +} + +static inline void carm_handle_rw(struct carm_host *host, + struct carm_request *crq, int is_ok) +{ + int pci_dir; + + VPRINTK("ENTER\n"); + + if (rq_data_dir(crq->rq) == WRITE) + pci_dir = PCI_DMA_TODEVICE; + else + pci_dir = PCI_DMA_FROMDEVICE; + + pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); + + carm_end_rq(host, crq, is_ok); +} + +static inline void carm_handle_resp(struct carm_host *host, + u32 ret_handle_le, u32 status) +{ + u32 handle = le32_to_cpu(ret_handle_le); + unsigned int msg_idx; + struct carm_request *crq; + int is_ok = (status == RMSG_OK); + u8 *mem; + + VPRINTK("ENTER, handle == 0x%x\n", handle); + + if (unlikely(!TAG_VALID(handle))) { + printk(KERN_ERR DRV_NAME "(%s): BUG: invalid tag 0x%x\n", + pci_name(host->pdev), handle); + return; + } + + msg_idx = TAG_DECODE(handle); + VPRINTK("tag == %u\n", msg_idx); + + crq = &host->req[msg_idx]; + + /* fast path */ + if (likely(crq->msg_type == CARM_MSG_READ || + crq->msg_type == CARM_MSG_WRITE)) { + carm_handle_rw(host, crq, is_ok); + return; + } + + mem = carm_ref_msg(host, msg_idx); + + switch (crq->msg_type) { + case CARM_MSG_IOCTL: { + switch (crq->msg_subtype) { + case CARM_IOC_SCAN_CHAN: + carm_handle_scan_chan(host, crq, mem, is_ok); + break; + default: + /* unknown / invalid response */ + goto err_out; + } + break; + } + + case CARM_MSG_MISC: { + switch (crq->msg_subtype) { + case MISC_ALLOC_MEM: + carm_handle_generic(host, crq, is_ok, + HST_ALLOC_BUF, HST_SYNC_TIME); + break; + case MISC_SET_TIME: + carm_handle_generic(host, crq, is_ok, + HST_SYNC_TIME, HST_GET_FW_VER); + break; + case MISC_GET_FW_VER: { + struct carm_fw_ver *ver = (struct carm_fw_ver *) + mem + sizeof(struct carm_msg_get_fw_ver); + if (is_ok) { + host->fw_ver = le32_to_cpu(ver->version); + host->flags |= (ver->features & FL_FW_VER_MASK); + } + carm_handle_generic(host, crq, is_ok, + HST_GET_FW_VER, HST_PORT_SCAN); + break; + } + default: + /* unknown / invalid response */ + goto err_out; + } + break; + } + + case CARM_MSG_ARRAY: { + switch (crq->msg_subtype) { + case CARM_ARRAY_INFO: + carm_handle_array_info(host, crq, mem, is_ok); + break; + default: + /* unknown / invalid response */ + goto err_out; + } + break; + } + + default: + /* unknown / invalid response */ + goto err_out; + } + + return; + +err_out: + printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", + pci_name(host->pdev), crq->msg_type, crq->msg_subtype); + carm_end_rq(host, crq, 0); +} + +static inline void carm_handle_responses(struct carm_host *host) +{ + void *mmio = host->mmio; + struct carm_response *resp = (struct carm_response *) host->shm; + unsigned int work = 0; + unsigned int idx = host->resp_idx % RMSG_Q_LEN; + + while (1) { + u32 status = le32_to_cpu(resp[idx].status); + + if (status == 0xffffffff) { + VPRINTK("ending response on index %u\n", idx); + writel(idx << 3, mmio + CARM_RESP_IDX); + break; + } + + /* response to a message we sent */ + else if ((status & (1 << 31)) == 0) { + VPRINTK("handling msg response on index %u\n", idx); + carm_handle_resp(host, resp[idx].ret_handle, status); + resp[idx].status = 0xffffffff; + } + + /* asynchronous events the hardware throws our way */ + else if ((status & 0xff000000) == (1 << 31)) { + u8 *evt_type_ptr = (u8 *) &resp[idx]; + u8 evt_type = *evt_type_ptr; + printk(KERN_WARNING DRV_NAME "(%s): unhandled event type %d\n", + pci_name(host->pdev), (int) evt_type); + resp[idx].status = 0xffffffff; + } + + idx = NEXT_RESP(idx); + work++; + } + + VPRINTK("EXIT, work==%u\n", work); + host->resp_idx += work; +} + +static irqreturn_t carm_interrupt(int irq, void *__host, struct pt_regs *regs) +{ + struct carm_host *host = __host; + void *mmio; + u32 mask; + int handled = 0; + unsigned long flags; + + if (!host) { + VPRINTK("no host\n"); + return IRQ_NONE; + } + + spin_lock_irqsave(&host->lock, flags); + + mmio = host->mmio; + + /* reading should also clear interrupts */ + mask = readl(mmio + CARM_INT_STAT); + + if (mask == 0 || mask == 0xffffffff) { + VPRINTK("no work, mask == 0x%x\n", mask); + goto out; + } + + if (mask & INT_ACK_MASK) + writel(mask, mmio + CARM_INT_STAT); + + if (unlikely(host->state == HST_INVALID)) { + VPRINTK("not initialized yet, mask = 0x%x\n", mask); + goto out; + } + + if (mask & CARM_HAVE_RESP) { + handled = 1; + carm_handle_responses(host); + } + +out: + spin_unlock_irqrestore(&host->lock, flags); + VPRINTK("EXIT\n"); + return IRQ_RETVAL(handled); +} + +static void carm_fsm_task (void *_data) +{ + struct carm_host *host = _data; + unsigned long flags; + unsigned int state; + int rc, i, next_dev; + int reschedule = 0; + int new_state = HST_INVALID; + + spin_lock_irqsave(&host->lock, flags); + state = host->state; + spin_unlock_irqrestore(&host->lock, flags); + + DPRINTK("ENTER, state == %s\n", state_name[state]); + + switch (state) { + case HST_PROBE_START: + new_state = HST_ALLOC_BUF; + reschedule = 1; + break; + + case HST_ALLOC_BUF: + rc = carm_send_special(host, carm_fill_alloc_buf); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_SYNC_TIME: + rc = carm_send_special(host, carm_fill_sync_time); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_GET_FW_VER: + rc = carm_send_special(host, carm_fill_get_fw_ver); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_PORT_SCAN: + rc = carm_send_special(host, carm_fill_scan_channels); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_DEV_SCAN_START: + host->cur_scan_dev = -1; + new_state = HST_DEV_SCAN; + reschedule = 1; + break; + + case HST_DEV_SCAN: + next_dev = -1; + for (i = host->cur_scan_dev + 1; i < CARM_MAX_PORTS; i++) + if (host->dev_present & (1 << i)) { + next_dev = i; + break; + } + + if (next_dev >= 0) { + host->cur_scan_dev = next_dev; + rc = carm_array_info(host, next_dev); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + } else { + new_state = HST_DEV_ACTIVATE; + reschedule = 1; + } + break; + + case HST_DEV_ACTIVATE: { + int activated = 0; + for (i = 0; i < CARM_MAX_PORTS; i++) + if (host->dev_active & (1 << i)) { + struct carm_port *port = &host->port[i]; + struct gendisk *disk = port->disk; + + set_capacity(disk, port->capacity); + add_disk(disk); + activated++; + } + + printk(KERN_INFO DRV_NAME "(%s): %d ports activated\n", + pci_name(host->pdev), activated); + + new_state = HST_PROBE_FINISHED; + reschedule = 1; + break; + } + + case HST_PROBE_FINISHED: + up(&host->probe_sem); + break; + + case HST_ERROR: + /* FIXME: TODO */ + break; + + default: + /* should never occur */ + printk(KERN_ERR PFX "BUG: unknown state %d\n", state); + assert(0); + break; + } + + if (new_state != HST_INVALID) { + spin_lock_irqsave(&host->lock, flags); + host->state = new_state; + spin_unlock_irqrestore(&host->lock, flags); + } + if (reschedule) + schedule_work(&host->fsm_task); +} + +static int carm_init_wait(void *mmio, u32 bits, unsigned int test_bit) +{ + unsigned int i; + + for (i = 0; i < 50000; i++) { + u32 tmp = readl(mmio + CARM_LMUC); + udelay(100); + + if (test_bit) { + if ((tmp & bits) == bits) + return 0; + } else { + if ((tmp & bits) == 0) + return 0; + } + + cond_resched(); + } + + printk(KERN_ERR PFX "carm_init_wait timeout, bits == 0x%x, test_bit == %s\n", + bits, test_bit ? "yes" : "no"); + return -EBUSY; +} + +static void carm_init_responses(struct carm_host *host) +{ + void *mmio = host->mmio; + unsigned int i; + struct carm_response *resp = (struct carm_response *) host->shm; + + for (i = 0; i < RMSG_Q_LEN; i++) + resp[i].status = 0xffffffff; + + writel(0, mmio + CARM_RESP_IDX); +} + +static int carm_init_host(struct carm_host *host) +{ + void *mmio = host->mmio; + u32 tmp; + u8 tmp8; + int rc; + + DPRINTK("ENTER\n"); + + writel(0, mmio + CARM_INT_MASK); + + tmp8 = readb(mmio + CARM_INITC); + if (tmp8 & 0x01) { + tmp8 &= ~0x01; + writeb(tmp8, CARM_INITC); + readb(mmio + CARM_INITC); /* flush */ + + DPRINTK("snooze...\n"); + msleep(5000); + } + + tmp = readl(mmio + CARM_HMUC); + if (tmp & CARM_CME) { + DPRINTK("CME bit present, waiting\n"); + rc = carm_init_wait(mmio, CARM_CME, 1); + if (rc) { + DPRINTK("EXIT, carm_init_wait 1 failed\n"); + return rc; + } + } + if (tmp & CARM_RME) { + DPRINTK("RME bit present, waiting\n"); + rc = carm_init_wait(mmio, CARM_RME, 1); + if (rc) { + DPRINTK("EXIT, carm_init_wait 2 failed\n"); + return rc; + } + } + + tmp &= ~(CARM_RME | CARM_CME); + writel(tmp, mmio + CARM_HMUC); + readl(mmio + CARM_HMUC); /* flush */ + + rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 0); + if (rc) { + DPRINTK("EXIT, carm_init_wait 3 failed\n"); + return rc; + } + + carm_init_buckets(mmio); + + writel(host->shm_dma & 0xffffffff, mmio + RBUF_ADDR_LO); + writel((host->shm_dma >> 16) >> 16, mmio + RBUF_ADDR_HI); + writel(RBUF_LEN, mmio + RBUF_BYTE_SZ); + + tmp = readl(mmio + CARM_HMUC); + tmp |= (CARM_RME | CARM_CME | CARM_WZBC); + writel(tmp, mmio + CARM_HMUC); + readl(mmio + CARM_HMUC); /* flush */ + + rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 1); + if (rc) { + DPRINTK("EXIT, carm_init_wait 4 failed\n"); + return rc; + } + + writel(0, mmio + CARM_HMPHA); + writel(INT_DEF_MASK, mmio + CARM_INT_MASK); + + carm_init_responses(host); + + /* start initialization, probing state machine */ + spin_lock_irq(&host->lock); + assert(host->state == HST_INVALID); + host->state = HST_PROBE_START; + spin_unlock_irq(&host->lock); + schedule_work(&host->fsm_task); + + DPRINTK("EXIT\n"); + return 0; +} + +static int carm_init_disks(struct carm_host *host) +{ + unsigned int i; + int rc = 0; + + for (i = 0; i < CARM_MAX_PORTS; i++) { + struct gendisk *disk; + request_queue_t *q; + struct carm_port *port; + + port = &host->port[i]; + port->host = host; + port->port_no = i; + + disk = alloc_disk(CARM_MINORS_PER_MAJOR); + if (!disk) { + rc = -ENOMEM; + break; + } + + port->disk = disk; + sprintf(disk->disk_name, DRV_NAME "%u_%u", host->id, i); + sprintf(disk->devfs_name, DRV_NAME "/%u_%u", host->id, i); + disk->major = host->major; + disk->first_minor = i * CARM_MINORS_PER_MAJOR; + disk->fops = &carm_bd_ops; + disk->private_data = port; + + q = blk_init_queue(carm_rq_fn, &host->lock); + if (!q) { + rc = -ENOMEM; + break; + } + disk->queue = q; + blk_queue_max_hw_segments(q, CARM_MAX_REQ_SG); + blk_queue_max_phys_segments(q, CARM_MAX_REQ_SG); + blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); + + q->queuedata = port; + } + + return rc; +} + +static void carm_free_disks(struct carm_host *host) +{ + unsigned int i; + + for (i = 0; i < CARM_MAX_PORTS; i++) { + struct gendisk *disk = host->port[i].disk; + if (disk) { + request_queue_t *q = disk->queue; + + if (disk->flags & GENHD_FL_UP) + del_gendisk(disk); + if (q) + blk_cleanup_queue(q); + put_disk(disk); + } + } +} + +static int carm_init_shm(struct carm_host *host) +{ + host->shm = pci_alloc_consistent(host->pdev, CARM_SHM_SIZE, + &host->shm_dma); + if (!host->shm) + return -ENOMEM; + + host->msg_base = host->shm + RBUF_LEN; + host->msg_dma = host->shm_dma + RBUF_LEN; + + memset(host->shm, 0xff, RBUF_LEN); + memset(host->msg_base, 0, PDC_SHM_SIZE - RBUF_LEN); + + return 0; +} + +static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static unsigned int printed_version; + struct carm_host *host; + unsigned int pci_dac; + int rc; + request_queue_t *q; + unsigned int i; + + if (!printed_version++) + printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out; + +#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ + rc = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); + if (!rc) { + rc = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n", + pci_name(pdev)); + goto err_out_regions; + } + pci_dac = 1; + } else { +#endif + rc = pci_set_dma_mask(pdev, 0xffffffffULL); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", + pci_name(pdev)); + goto err_out_regions; + } + pci_dac = 0; +#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ + } +#endif + + host = kmalloc(sizeof(*host), GFP_KERNEL); + if (!host) { + printk(KERN_ERR DRV_NAME "(%s): memory alloc failure\n", + pci_name(pdev)); + rc = -ENOMEM; + goto err_out_regions; + } + + memset(host, 0, sizeof(*host)); + host->pdev = pdev; + host->flags = pci_dac ? FL_DAC : 0; + spin_lock_init(&host->lock); + INIT_WORK(&host->fsm_task, carm_fsm_task, host); + init_MUTEX_LOCKED(&host->probe_sem); + + for (i = 0; i < ARRAY_SIZE(host->req); i++) + host->req[i].tag = i; + + host->mmio = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (!host->mmio) { + printk(KERN_ERR DRV_NAME "(%s): MMIO alloc failure\n", + pci_name(pdev)); + rc = -ENOMEM; + goto err_out_kfree; + } + + rc = carm_init_shm(host); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): DMA SHM alloc failure\n", + pci_name(pdev)); + goto err_out_iounmap; + } + + q = blk_init_queue(carm_oob_rq_fn, &host->lock); + if (!q) { + printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n", + pci_name(pdev)); + rc = -ENOMEM; + goto err_out_pci_free; + } + host->oob_q = q; + q->queuedata = host; + + /* + * Figure out which major to use: 160, 161, or dynamic + */ + if (!test_and_set_bit(0, &carm_major_alloc)) + host->major = 160; + else if (!test_and_set_bit(1, &carm_major_alloc)) + host->major = 161; + else + host->flags |= FL_DYN_MAJOR; + + host->id = carm_host_id; + sprintf(host->name, DRV_NAME "%d", carm_host_id); + + rc = register_blkdev(host->major, host->name); + if (rc < 0) + goto err_out_free_majors; + if (host->flags & FL_DYN_MAJOR) + host->major = rc; + + devfs_mk_dir(DRV_NAME); + + rc = carm_init_disks(host); + if (rc) + goto err_out_blkdev_disks; + + pci_set_master(pdev); + + rc = request_irq(pdev->irq, carm_interrupt, SA_SHIRQ, DRV_NAME, host); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): irq alloc failure\n", + pci_name(pdev)); + goto err_out_blkdev_disks; + } + + rc = carm_init_host(host); + if (rc) + goto err_out_free_irq; + + DPRINTK("waiting for probe_sem\n"); + down(&host->probe_sem); + + printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n", + host->name, pci_name(pdev), (int) CARM_MAX_PORTS, + pci_resource_start(pdev, 0), pdev->irq, host->major); + + carm_host_id++; + pci_set_drvdata(pdev, host); + return 0; + +err_out_free_irq: + free_irq(pdev->irq, host); +err_out_blkdev_disks: + carm_free_disks(host); + unregister_blkdev(host->major, host->name); +err_out_free_majors: + if (host->major == 160) + clear_bit(0, &carm_major_alloc); + else if (host->major == 161) + clear_bit(1, &carm_major_alloc); + blk_cleanup_queue(host->oob_q); +err_out_pci_free: + pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); +err_out_iounmap: + iounmap(host->mmio); +err_out_kfree: + kfree(host); +err_out_regions: + pci_release_regions(pdev); +err_out: + pci_disable_device(pdev); + return rc; +} + +static void carm_remove_one (struct pci_dev *pdev) +{ + struct carm_host *host = pci_get_drvdata(pdev); + + if (!host) { + printk(KERN_ERR PFX "BUG: no host data for PCI(%s)\n", + pci_name(pdev)); + return; + } + + free_irq(pdev->irq, host); + carm_free_disks(host); + devfs_remove(DRV_NAME); + unregister_blkdev(host->major, host->name); + if (host->major == 160) + clear_bit(0, &carm_major_alloc); + else if (host->major == 161) + clear_bit(1, &carm_major_alloc); + blk_cleanup_queue(host->oob_q); + pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); + iounmap(host->mmio); + kfree(host); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static int __init carm_init(void) +{ + return pci_module_init(&carm_driver); +} + +static void __exit carm_exit(void) +{ + pci_unregister_driver(&carm_driver); +} + +module_init(carm_init); +module_exit(carm_exit); + + diff -Nru a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c --- a/drivers/cdrom/cdrom.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/cdrom/cdrom.c 2004-06-26 17:09:16 -07:00 @@ -508,6 +508,8 @@ unsigned char buffer[16]; int ret; + *write = 0; + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; @@ -521,8 +523,10 @@ mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; *write = mfd->write; - if ((ret = cdrom_mrw_probe_pc(cdi))) + if ((ret = cdrom_mrw_probe_pc(cdi))) { + *write = 0; return ret; + } return 0; } @@ -822,8 +826,30 @@ */ static int cdrom_open_write(struct cdrom_device_info *cdi) { + int mrw, mrw_write, ram_write; int ret = 1; + mrw = 0; + if (!cdrom_is_mrw(cdi, &mrw_write)) + mrw = 1; + + (void) cdrom_is_random_writable(cdi, &ram_write); + + if (mrw) + cdi->mask &= ~CDC_MRW; + else + cdi->mask |= CDC_MRW; + + if (mrw_write) + cdi->mask &= ~CDC_MRW_W; + else + cdi->mask |= CDC_MRW_W; + + if (ram_write) + cdi->mask &= ~CDC_RAM; + else + cdi->mask |= CDC_RAM; + if (CDROM_CAN(CDC_MRW_W)) ret = cdrom_mrw_open_write(cdi); else if (CDROM_CAN(CDC_DVD_RAM)) @@ -866,6 +892,9 @@ if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) { ret = cdi->ops->open(cdi, 1); } else { + ret = open_for_data(cdi); + if (ret) + goto err; if (fp->f_mode & FMODE_WRITE) { ret = -EROFS; if (!CDROM_CAN(CDC_RAM)) @@ -873,7 +902,6 @@ if (cdrom_open_write(cdi)) goto err; } - ret = open_for_data(cdi); } if (ret) @@ -1448,6 +1476,7 @@ /* LU data send */ case DVD_LU_SEND_AGID: cdinfo(CD_DVD, "entering DVD_LU_SEND_AGID\n"); + cgc.quiet = 1; setup_report_key(&cgc, ai->lsa.agid, 0); if ((ret = cdo->generic_packet(cdi, &cgc))) @@ -1482,6 +1511,7 @@ /* Post-auth key */ case DVD_LU_SEND_TITLE_KEY: cdinfo(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n"); + cgc.quiet = 1; setup_report_key(&cgc, ai->lstk.agid, 4); cgc.cmd[5] = ai->lstk.lba; cgc.cmd[4] = ai->lstk.lba >> 8; diff -Nru a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c --- a/drivers/cdrom/isp16.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/cdrom/isp16.c 2004-06-26 17:09:20 -07:00 @@ -16,6 +16,10 @@ * module_init & module_exit. * Torben Mathiasen * + * 19 June 2004 -- check_region() converted to request_region() + * and return statement cleanups. + * Jesper Juhl + * * Detect cdrom interface on ISP16 sound card. * Configure cdrom interface. * @@ -118,17 +122,17 @@ if (!strcmp(isp16_cdrom_type, "noisp16")) { printk("ISP16: no cdrom interface configured.\n"); - return (0); + return 0; } - if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) { + if (!request_region(ISP16_IO_BASE, ISP16_IO_SIZE, "isp16")) { printk("ISP16: i/o ports already in use.\n"); - return (-EIO); + goto out; } if ((isp16_type = isp16_detect()) < 0) { printk("ISP16: no cdrom interface found.\n"); - return (-EIO); + goto cleanup_out; } printk(KERN_INFO @@ -148,27 +152,32 @@ else { printk("ISP16: %s not supported by cdrom interface.\n", isp16_cdrom_type); - return (-EIO); + goto cleanup_out; } if (isp16_cdi_config(isp16_cdrom_base, expected_drive, isp16_cdrom_irq, isp16_cdrom_dma) < 0) { printk ("ISP16: cdrom interface has not been properly configured.\n"); - return (-EIO); + goto cleanup_out; } printk(KERN_INFO "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d," " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq, isp16_cdrom_dma, isp16_cdrom_type); - return (0); + return 0; + +cleanup_out: + release_region(ISP16_IO_BASE, ISP16_IO_SIZE); +out: + return -EIO; } static short __init isp16_detect(void) { if (isp16_c929__detect() >= 0) - return (2); + return 2; else return (isp16_c928__detect()); } @@ -206,7 +215,7 @@ ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom); } else { /* bits are not the same */ ISP16_OUT(ISP16_CTRL_PORT, ctrl); - return (i); /* -> not detected: possibly incorrect conclusion */ + return i; /* -> not detected: possibly incorrect conclusion */ } } else if (enable_cdrom == 0x20) i = 0; @@ -215,7 +224,7 @@ ISP16_OUT(ISP16_CTRL_PORT, ctrl); - return (i); + return i; } static short __init isp16_c929__detect(void) @@ -236,12 +245,12 @@ tmp = ISP16_IN(ISP16_CTRL_PORT); if (tmp != 2) /* isp16 with 82C929 not detected */ - return (-1); + return -1; /* restore ctrl port value */ ISP16_OUT(ISP16_CTRL_PORT, ctrl); - return (2); + return 2; } static short __init @@ -272,7 +281,7 @@ printk ("ISP16: base address 0x%03X not supported by cdrom interface.\n", base); - return (-1); + return -1; } switch (irq) { case 0: @@ -303,7 +312,7 @@ default: printk("ISP16: irq %d not supported by cdrom interface.\n", irq); - return (-1); + return -1; } switch (dma) { case 0: @@ -312,7 +321,7 @@ case 1: printk("ISP16: dma 1 cannot be used by cdrom interface," " due to conflict with the sound card.\n"); - return (-1); + return -1; break; case 3: dma_code = ISP16_DMA_3; @@ -329,7 +338,7 @@ default: printk("ISP16: dma %d not supported by cdrom interface.\n", dma); - return (-1); + return -1; } if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 && @@ -339,7 +348,7 @@ printk ("ISP16: drive type (code 0x%02X) not supported by cdrom" " interface.\n", drive_type); - return (-1); + return -1; } /* set type of interface */ @@ -354,7 +363,7 @@ i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */ ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code); - return (0); + return 0; } void __exit isp16_exit(void) diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig --- a/drivers/char/Kconfig 2004-06-26 17:09:15 -07:00 +++ b/drivers/char/Kconfig 2004-06-26 17:09:15 -07:00 @@ -586,17 +586,6 @@ console. This driver allows each pSeries partition to have a console which is accessed via the HMC. -config PC9800_OLDLP - tristate "NEC PC-9800 old-style printer port support" - depends on X86_PC9800 && !PARPORT - ---help--- - If you intend to attach a printer to the parallel port of NEC PC-9801 - /PC-9821 with OLD compatibility mode, Say Y. - -config PC9800_OLDLP_CONSOLE - bool "Support for console on line printer" - depends on PC9800_OLDLP - config QIC02_TAPE tristate "QIC-02 tape support" help @@ -740,7 +729,7 @@ config RTC tristate "Enhanced Real Time Clock Support" - depends on !PPC32 && !PARISC && !IA64 && !X86_PC9800 && !M68K + depends on !PPC32 && !PARISC && !IA64 && !M68K ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you @@ -764,6 +753,28 @@ To compile this driver as a module, choose M here: the module will be called rtc. +config SGI_DS1286 + tristate "SGI DS1286 RTC support" + depends on SGI_IP22 + help + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you + will get access to the real time clock built into your computer. + Every SGI has such a clock built in. It reports status information + via the file /proc/rtc and its behaviour is set by various ioctls on + /dev/rtc. + +config SGI_IP27_RTC + bool "SGI M48T35 RTC support" + depends on SGI_IP27 + help + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you + will get access to the real time clock built into your computer. + Every SGI has such a clock built in. It reports status information + via the file /proc/rtc and its behaviour is set by various ioctls on + /dev/rtc. + config GEN_RTC tristate "Generic /dev/rtc emulation" depends on RTC!=y && !IA64 @@ -793,14 +804,12 @@ bool "EFI Real Time Clock Services" depends on IA64 -config RTC98 - tristate "NEC PC-9800 Real Time Clock Support" - depends on X86_PC9800 - default y - ---help--- - If you say Y here and create a character special file /dev/rtc with - major number 10 and minor number 135 using mknod ("man mknod"), you - will get access to the real time clock (or hardware clock) built +config COBALT_LCD + bool "Support for Cobalt LCD" + depends on MIPS_COBALT + help + This option enables support for the LCD display and buttons found + on Cobalt systems through a misc device. config H8 bool "Tadpole ANA H8 Support (OBSOLETE)" @@ -956,6 +965,33 @@ The raw driver is deprecated and may be removed from 2.7 kernels. Applications should simply open the device (eg /dev/hda1) with the O_DIRECT flag. + +config HPET + bool "HPET - High Precision Event Timer" if (X86 || IA64) + default n + depends on ACPI + help + If you say Y here, you will have a device named "/dev/hpet/XX" for + each timer supported by the HPET. The timers are + non-periodioc and/or periodic. + +config HPET_RTC_IRQ + bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC + default n + depends on HPET + help + If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It + is assumed the platform called hpet_alloc with the RTC IRQ values for + the HPET timers. + +config HPET_NOMMAP + bool "HPET - Control mmap capability." + default n + depends on HPET + help + If you say Y here, then the mmap interface for the HPET driver returns ENOSYS. + Some hardware implementations might not want all the memory in the page the + HPET control registers reside to be exposed. config MAX_RAW_DEVS int "Maximum number of RAW devices to support (1-8192)" diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile --- a/drivers/char/Makefile 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/Makefile 2004-06-26 17:09:20 -07:00 @@ -47,15 +47,17 @@ obj-$(CONFIG_PRINTER) += lp.o obj-$(CONFIG_TIPAR) += tipar.o -obj-$(CONFIG_PC9800_OLDLP) += lp_old98.o obj-$(CONFIG_DTLK) += dtlk.o obj-$(CONFIG_R3964) += n_r3964.o obj-$(CONFIG_APPLICOM) += applicom.o obj-$(CONFIG_SONYPI) += sonypi.o obj-$(CONFIG_RTC) += rtc.o +obj-$(CONFIG_HPET) += hpet.o obj-$(CONFIG_GEN_RTC) += genrtc.o obj-$(CONFIG_EFI_RTC) += efirtc.o +obj-$(CONFIG_SGI_DS1286) += ds1286.o +obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o ifeq ($(CONFIG_GENERIC_NVRAM),y) obj-$(CONFIG_NVRAM) += generic_nvram.o else @@ -67,6 +69,7 @@ obj-$(CONFIG_HW_RANDOM) += hw_random.o obj-$(CONFIG_QIC02_TAPE) += tpqic02.o obj-$(CONFIG_FTAPE) += ftape/ +obj-$(CONFIG_COBALT_LCD) += lcd.o obj-$(CONFIG_H8) += h8.o obj-$(CONFIG_PPDEV) += ppdev.o obj-$(CONFIG_NWBUTTON) += nwbutton.o diff -Nru a/drivers/char/applicom.c b/drivers/char/applicom.c --- a/drivers/char/applicom.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/applicom.c 2004-06-26 17:09:20 -07:00 @@ -105,8 +105,8 @@ static unsigned int ReadErrorCount; /* number of read error */ static unsigned int DeviceErrorCount; /* number of device error */ -static ssize_t ac_read (struct file *, char *, size_t, loff_t *); -static ssize_t ac_write (struct file *, const char *, size_t, loff_t *); +static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *); +static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *); static int ac_ioctl(struct inode *, struct file *, unsigned int, unsigned long); static irqreturn_t ac_interrupt(int, void *, struct pt_regs *); @@ -343,7 +343,7 @@ __initcall(applicom_init); #endif -static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t * ppos) +static ssize_t ac_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { unsigned int NumCard; /* Board number 1 -> 8 */ unsigned int IndexCard; /* Index board number 0 -> 7 */ @@ -467,7 +467,7 @@ return 0; } -static int do_ac_read(int IndexCard, char *buf, +static int do_ac_read(int IndexCard, char __user *buf, struct st_ram_io *st_loc, struct mailbox *mailbox) { unsigned long from = (unsigned long)apbs[IndexCard].RamIO + RAM_TO_PC; @@ -521,7 +521,7 @@ return (sizeof(struct st_ram_io) + sizeof(struct mailbox)); } -static ssize_t ac_read (struct file *filp, char *buf, size_t count, loff_t *ptr) +static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_t *ptr) { unsigned long flags; unsigned int i; @@ -689,6 +689,7 @@ int ret = 0; volatile unsigned char byte_reset_it; struct st_ram_io *adgl; + void __user *argp = (void __user *)arg; /* In general, the device is only openable by root anyway, so we're not particularly concerned that bogus ioctls can flood the console. */ @@ -697,7 +698,7 @@ if (!adgl) return -ENOMEM; - if (copy_from_user(adgl, (void *)arg,sizeof(struct st_ram_io))) { + if (copy_from_user(adgl, argp, sizeof(struct st_ram_io))) { kfree(adgl); return -EFAULT; } @@ -721,7 +722,7 @@ pmem = apbs[IndexCard].RamIO; for (i = 0; i < sizeof(struct st_ram_io); i++) ((unsigned char *)adgl)[i]=readb(pmem++); - if (copy_to_user((void *)arg, adgl, sizeof(struct st_ram_io))) + if (copy_to_user(argp, adgl, sizeof(struct st_ram_io))) ret = -EFAULT; break; case 1: @@ -742,7 +743,7 @@ (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 1) << 8) + (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 2) ); - if (copy_to_user((void *)arg, adgl, sizeof(struct st_ram_io))) + if (copy_to_user(argp, adgl, sizeof(struct st_ram_io))) ret = -EFAULT; break; case 2: @@ -768,7 +769,7 @@ pmem = apbs[IndexCard].RamIO + TIC_OWNER_TO_PC; adgl->tic_owner_to_pc = readb(pmem++); adgl->numcard_owner_to_pc = readb(pmem); - if (copy_to_user((void *)arg, adgl,sizeof(struct st_ram_io))) + if (copy_to_user(argp, adgl,sizeof(struct st_ram_io))) ret = -EFAULT; break; case 5: diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c --- a/drivers/char/cyclades.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/cyclades.c 2004-06-26 17:09:16 -07:00 @@ -676,8 +676,6 @@ #include #include -#define cy_put_user put_user - static void cy_throttle (struct tty_struct *tty); static void cy_send_xchar (struct tty_struct *tty, char ch); @@ -3536,7 +3534,7 @@ static int get_serial_info(struct cyclades_port * info, - struct serial_struct * retinfo) + struct serial_struct __user * retinfo) { struct serial_struct tmp; struct cyclades_card *cinfo = &cy_card[info->card]; @@ -3559,7 +3557,7 @@ static int set_serial_info(struct cyclades_port * info, - struct serial_struct * new_info) + struct serial_struct __user * new_info) { struct serial_struct new_serial; struct cyclades_port old_info; @@ -3613,7 +3611,7 @@ * transmit holding register is empty. This functionality * allows an RS485 driver to be written in user space. */ -static int get_lsr_info(struct cyclades_port *info, unsigned int *value) +static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) { int card, chip, channel, index; unsigned char status; @@ -3638,7 +3636,7 @@ /* Not supported yet */ return -EINVAL; } - return cy_put_user(result, (unsigned long *) value); + return put_user(result, (unsigned long __user *) value); } static int @@ -3916,7 +3914,7 @@ } /* cy_break */ static int -get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon) +get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon) { if(copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) @@ -3961,7 +3959,7 @@ static int -get_threshold(struct cyclades_port * info, unsigned long *value) +get_threshold(struct cyclades_port * info, unsigned long __user *value) { unsigned char *base_addr; int card,channel,chip,index; @@ -3978,7 +3976,7 @@ + (cy_chip_offset[chip]<default_threshold,value); + return put_user(info->default_threshold,value); }/* get_default_threshold */ @@ -4029,7 +4027,7 @@ static int -get_timeout(struct cyclades_port * info, unsigned long *value) +get_timeout(struct cyclades_port * info, unsigned long __user *value) { unsigned char *base_addr; int card,channel,chip,index; @@ -4046,7 +4044,7 @@ + (cy_chip_offset[chip]<default_timeout,value); + return put_user(info->default_timeout,value); }/* get_default_timeout */ /* @@ -4079,9 +4077,10 @@ { struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; struct cyclades_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ + struct serial_icounter_struct __user *p_cuser; /* user space */ int ret_val = 0; unsigned long flags; + void __user *argp = (void __user *)arg; if (serial_paranoia_check(info, tty->name, "cy_ioctl")) return -ENODEV; @@ -4093,31 +4092,31 @@ switch (cmd) { case CYGETMON: - ret_val = get_mon_info(info, (struct cyclades_monitor *)arg); + ret_val = get_mon_info(info, argp); break; case CYGETTHRESH: - ret_val = get_threshold(info, (unsigned long *)arg); + ret_val = get_threshold(info, argp); break; case CYSETTHRESH: - ret_val = set_threshold(info, (unsigned long)arg); + ret_val = set_threshold(info, arg); break; case CYGETDEFTHRESH: - ret_val = get_default_threshold(info, (unsigned long *)arg); + ret_val = get_default_threshold(info, argp); break; case CYSETDEFTHRESH: - ret_val = set_default_threshold(info, (unsigned long)arg); + ret_val = set_default_threshold(info, arg); break; case CYGETTIMEOUT: - ret_val = get_timeout(info, (unsigned long *)arg); + ret_val = get_timeout(info, argp); break; case CYSETTIMEOUT: - ret_val = set_timeout(info, (unsigned long)arg); + ret_val = set_timeout(info, arg); break; case CYGETDEFTIMEOUT: - ret_val = get_default_timeout(info, (unsigned long *)arg); + ret_val = get_default_timeout(info, argp); break; case CYSETDEFTIMEOUT: - ret_val = set_default_timeout(info, (unsigned long)arg); + ret_val = set_default_timeout(info, arg); break; case CYSETRFLOW: info->rflow = (int)arg; @@ -4134,7 +4133,7 @@ ret_val = info->rtsdtr_inv; break; case CYGETCARDINFO: - if (copy_to_user((void *)arg, (void *)&cy_card[info->card], + if (copy_to_user(argp, &cy_card[info->card], sizeof (struct cyclades_card))) { ret_val = -EFAULT; break; @@ -4161,13 +4160,13 @@ ret_val = info->closing_wait / (HZ/100); break; case TIOCGSERIAL: - ret_val = get_serial_info(info, (struct serial_struct *) arg); + ret_val = get_serial_info(info, argp); break; case TIOCSSERIAL: - ret_val = set_serial_info(info, (struct serial_struct *) arg); + ret_val = set_serial_info(info, argp); break; case TIOCSERGETLSR: /* Get line status register */ - ret_val = get_lsr_info(info, (unsigned int *) arg); + ret_val = get_lsr_info(info, argp); break; /* * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change @@ -4215,7 +4214,7 @@ CY_LOCK(info, flags); cnow = info->icount; CY_UNLOCK(info, flags); - p_cuser = (struct serial_icounter_struct *) arg; + p_cuser = argp; ret_val = put_user(cnow.cts, &p_cuser->cts); if (ret_val) return ret_val; ret_val = put_user(cnow.dsr, &p_cuser->dsr); diff -Nru a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c --- a/drivers/char/drm/sis_mm.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/drm/sis_mm.c 2004-06-26 17:09:19 -07:00 @@ -113,7 +113,7 @@ DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, fb, sizeof(fb)); - DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); + DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset); return retval; } @@ -130,7 +130,7 @@ if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) retval = DRM_ERR(EINVAL); - sis_free(fb.free); + sis_free((u32)fb.free); DRM_DEBUG("free fb, offset = %lu\n", fb.free); diff -Nru a/drivers/char/ds1286.c b/drivers/char/ds1286.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/char/ds1286.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,578 @@ +/* + * DS1286 Real Time Clock interface for Linux + * + * Copyright (C) 1998, 1999, 2000 Ralf Baechle + * + * Based on code written by Paul Gortmaker. + * + * This driver allows use of the real time clock (built into nearly all + * computers) from user space. It exports the /dev/rtc interface supporting + * various ioctl() and also the /proc/rtc pseudo-file for status + * information. + * + * The ioctls can be used to set the interrupt behaviour and generation rate + * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make + * use of these timer interrupts, be they interval or alarm based. + * + * The /dev/rtc interface will block on reads until an interrupt has been + * received. If a RTC interrupt has already happened, it will output an + * unsigned long and then block. The output value contains the interrupt + * status in the low byte and the number of interrupts since the last read + * in the remaining high bytes. The /dev/rtc interface can also be used with + * the select(2) call. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DS1286_VERSION "1.0" + +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static DECLARE_WAIT_QUEUE_HEAD(ds1286_wait); + +static ssize_t ds1286_read(struct file *file, char *buf, + size_t count, loff_t *ppos); + +static int ds1286_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static unsigned int ds1286_poll(struct file *file, poll_table *wait); + +static void ds1286_get_alm_time (struct rtc_time *alm_tm); +static void ds1286_get_time(struct rtc_time *rtc_tm); +static int ds1286_set_time(struct rtc_time *rtc_tm); + +static inline unsigned char ds1286_is_updating(void); + +static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED; + +static int ds1286_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +/* + * Bits in rtc_status. (7 bits of room for future expansion) + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ +#define RTC_TIMER_ON 0x02 /* missed irq timer active */ + +static unsigned char ds1286_status; /* bitmapped status byte. */ + +static unsigned char days_in_mo[] = { + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +/* + * Now all the various file operations that we export. + */ + +static ssize_t ds1286_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + return -EIO; +} + +static int ds1286_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct rtc_time wtime; + + switch (cmd) { + case RTC_AIE_OFF: /* Mask alarm int. enab. bit */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = rtc_read(RTC_CMD); + val |= RTC_TDM; + rtc_write(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_AIE_ON: /* Allow alarm interrupts. */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = rtc_read(RTC_CMD); + val &= ~RTC_TDM; + rtc_write(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = rtc_read(RTC_CMD); + val |= RTC_WAM; + rtc_write(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_WIE_ON: /* Allow watchdog interrupts. */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = rtc_read(RTC_CMD); + val &= ~RTC_WAM; + rtc_write(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_ALM_READ: /* Read the present alarm time */ + { + /* + * This returns a struct rtc_time. Reading >= 0xc0 + * means "don't care" or "match all". Only the tm_hour, + * tm_min, and tm_sec values are filled in. + */ + + memset(&wtime, 0, sizeof(wtime)); + ds1286_get_alm_time(&wtime); + break; + } + case RTC_ALM_SET: /* Store a time into the alarm */ + { + /* + * This expects a struct rtc_time. Writing 0xff means + * "don't care" or "match all". Only the tm_hour, + * tm_min and tm_sec are used. + */ + unsigned char hrs, min, sec; + struct rtc_time alm_tm; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&alm_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + hrs = alm_tm.tm_hour; + min = alm_tm.tm_min; + + if (hrs >= 24) + hrs = 0xff; + + if (min >= 60) + min = 0xff; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + + spin_lock(&ds1286_lock); + rtc_write(hrs, RTC_HOURS_ALARM); + rtc_write(min, RTC_MINUTES_ALARM); + spin_unlock(&ds1286_lock); + + return 0; + } + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + memset(&wtime, 0, sizeof(wtime)); + ds1286_get_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + return ds1286_set_time(&rtc_tm); + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int ds1286_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&ds1286_lock); + + if (ds1286_status & RTC_IS_OPEN) + goto out_busy; + + ds1286_status |= RTC_IS_OPEN; + + spin_unlock_irq(&ds1286_lock); + return 0; + +out_busy: + spin_lock_irq(&ds1286_lock); + return -EBUSY; +} + +static int ds1286_release(struct inode *inode, struct file *file) +{ + ds1286_status &= ~RTC_IS_OPEN; + + return 0; +} + +static unsigned int ds1286_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &ds1286_wait, wait); + + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations ds1286_fops = { + .llseek = no_llseek, + .read = ds1286_read, + .poll = ds1286_poll, + .ioctl = ds1286_ioctl, + .open = ds1286_open, + .release = ds1286_release, +}; + +static struct miscdevice ds1286_dev= +{ + .minor = RTC_MINOR, + .name = "rtc", + .fops = &ds1286_fops, +}; + +static int __init ds1286_init(void) +{ + int err; + + printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); + + err = misc_register(&ds1286_dev); + if (err) + goto out; + + if (!create_proc_read_entry("driver/rtc", 0, 0, ds1286_read_proc, NULL)) { + err = -ENOMEM; + + goto out_deregister; + } + + return 0; + +out_deregister: + misc_deregister(&ds1286_dev); + +out: + return err; +} + +static void __exit ds1286_exit(void) +{ + remove_proc_entry("driver/rtc", NULL); + misc_deregister(&ds1286_dev); +} + +static char *days[] = { + "***", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +/* + * Info exported via "/proc/rtc". + */ +static int ds1286_proc_output(char *buf) +{ + char *p, *s; + struct rtc_time tm; + unsigned char hundredth, month, cmd, amode; + + p = buf; + + ds1286_get_time(&tm); + hundredth = rtc_read(RTC_HUNDREDTH_SECOND); + BCD_TO_BIN(hundredth); + + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d.%02d\n" + "rtc_date\t: %04d-%02d-%02d\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, hundredth, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + + /* + * We implicitly assume 24hr mode here. Alarm values >= 0xc0 will + * match any value for that particular field. Values that are + * greater than a valid time, but less than 0xc0 shouldn't appear. + */ + ds1286_get_alm_time(&tm); + p += sprintf(p, "alarm\t\t: %s ", days[tm.tm_wday]); + if (tm.tm_hour <= 24) + p += sprintf(p, "%02d:", tm.tm_hour); + else + p += sprintf(p, "**:"); + + if (tm.tm_min <= 59) + p += sprintf(p, "%02d\n", tm.tm_min); + else + p += sprintf(p, "**\n"); + + month = rtc_read(RTC_MONTH); + p += sprintf(p, + "oscillator\t: %s\n" + "square_wave\t: %s\n", + (month & RTC_EOSC) ? "disabled" : "enabled", + (month & RTC_ESQW) ? "disabled" : "enabled"); + + amode = ((rtc_read(RTC_MINUTES_ALARM) & 0x80) >> 5) | + ((rtc_read(RTC_HOURS_ALARM) & 0x80) >> 6) | + ((rtc_read(RTC_DAY_ALARM) & 0x80) >> 7); + if (amode == 7) s = "each minute"; + else if (amode == 3) s = "minutes match"; + else if (amode == 1) s = "hours and minutes match"; + else if (amode == 0) s = "days, hours and minutes match"; + else s = "invalid"; + p += sprintf(p, "alarm_mode\t: %s\n", s); + + cmd = rtc_read(RTC_CMD); + p += sprintf(p, + "alarm_enable\t: %s\n" + "wdog_alarm\t: %s\n" + "alarm_mask\t: %s\n" + "wdog_alarm_mask\t: %s\n" + "interrupt_mode\t: %s\n" + "INTB_mode\t: %s_active\n" + "interrupt_pins\t: %s\n", + (cmd & RTC_TDF) ? "yes" : "no", + (cmd & RTC_WAF) ? "yes" : "no", + (cmd & RTC_TDM) ? "disabled" : "enabled", + (cmd & RTC_WAM) ? "disabled" : "enabled", + (cmd & RTC_PU_LVL) ? "pulse" : "level", + (cmd & RTC_IBH_LO) ? "low" : "high", + (cmd & RTC_IPSW) ? "unswapped" : "swapped"); + + return p - buf; +} + +static int ds1286_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = ds1286_proc_output (page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) + len = count; + if (len<0) + len = 0; + + return len; +} + +/* + * Returns true if a clock update is in progress + */ +static inline unsigned char ds1286_is_updating(void) +{ + return rtc_read(RTC_CMD) & RTC_TE; +} + + +static void ds1286_get_time(struct rtc_time *rtc_tm) +{ + unsigned char save_control; + unsigned int flags; + unsigned long uip_watchdog = jiffies; + + /* + * read RTC once any update in progress is done. The update + * can take just over 2ms. We wait 10 to 20ms. There is no need to + * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. + * If you need to know *exactly* when a second has started, enable + * periodic update complete interrupts, (via ioctl) and then + * immediately read /dev/rtc which will block until you get the IRQ. + * Once the read clears, read the RTC time (again via ioctl). Easy. + */ + + if (ds1286_is_updating() != 0) + while (jiffies - uip_watchdog < 2*HZ/100) + barrier(); + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + spin_lock_irqsave(&ds1286_lock, flags); + save_control = rtc_read(RTC_CMD); + rtc_write((save_control|RTC_TE), RTC_CMD); + + rtc_tm->tm_sec = rtc_read(RTC_SECONDS); + rtc_tm->tm_min = rtc_read(RTC_MINUTES); + rtc_tm->tm_hour = rtc_read(RTC_HOURS) & 0x3f; + rtc_tm->tm_mday = rtc_read(RTC_DATE); + rtc_tm->tm_mon = rtc_read(RTC_MONTH) & 0x1f; + rtc_tm->tm_year = rtc_read(RTC_YEAR); + + rtc_write(save_control, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + BCD_TO_BIN(rtc_tm->tm_sec); + BCD_TO_BIN(rtc_tm->tm_min); + BCD_TO_BIN(rtc_tm->tm_hour); + BCD_TO_BIN(rtc_tm->tm_mday); + BCD_TO_BIN(rtc_tm->tm_mon); + BCD_TO_BIN(rtc_tm->tm_year); + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + if (rtc_tm->tm_year < 45) + rtc_tm->tm_year += 30; + if ((rtc_tm->tm_year += 40) < 70) + rtc_tm->tm_year += 100; + + rtc_tm->tm_mon--; +} + +static int ds1286_set_time(struct rtc_time *rtc_tm) +{ + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned char save_control; + unsigned int yrs, flags; + + + yrs = rtc_tm->tm_year + 1900; + mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm->tm_mday; + hrs = rtc_tm->tm_hour; + min = rtc_tm->tm_min; + sec = rtc_tm->tm_sec; + + if (yrs < 1970) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ((yrs -= 1940) > 255) /* They are unsigned */ + return -EINVAL; + + if (yrs >= 100) + yrs -= 100; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(yrs); + + spin_lock_irqsave(&ds1286_lock, flags); + save_control = rtc_read(RTC_CMD); + rtc_write((save_control|RTC_TE), RTC_CMD); + + rtc_write(yrs, RTC_YEAR); + rtc_write(mon, RTC_MONTH); + rtc_write(day, RTC_DATE); + rtc_write(hrs, RTC_HOURS); + rtc_write(min, RTC_MINUTES); + rtc_write(sec, RTC_SECONDS); + rtc_write(0, RTC_HUNDREDTH_SECOND); + + rtc_write(save_control, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; +} + +static void ds1286_get_alm_time(struct rtc_time *alm_tm) +{ + unsigned char cmd; + unsigned int flags; + + /* + * Only the values that we read from the RTC are set. That + * means only tm_wday, tm_hour, tm_min. + */ + spin_lock_irqsave(&ds1286_lock, flags); + alm_tm->tm_min = rtc_read(RTC_MINUTES_ALARM) & 0x7f; + alm_tm->tm_hour = rtc_read(RTC_HOURS_ALARM) & 0x1f; + alm_tm->tm_wday = rtc_read(RTC_DAY_ALARM) & 0x07; + cmd = rtc_read(RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + BCD_TO_BIN(alm_tm->tm_min); + BCD_TO_BIN(alm_tm->tm_hour); + alm_tm->tm_sec = 0; +} + +module_init(ds1286_init); +module_exit(ds1286_exit); + +MODULE_AUTHOR("Ralf Baechle"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(RTC_MINOR); diff -Nru a/drivers/char/dtlk.c b/drivers/char/dtlk.c --- a/drivers/char/dtlk.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/char/dtlk.c 2004-06-26 17:09:17 -07:00 @@ -85,9 +85,9 @@ static struct timer_list dtlk_timer; /* prototypes for file_operations struct */ -static ssize_t dtlk_read(struct file *, char *, +static ssize_t dtlk_read(struct file *, char __user *, size_t nbytes, loff_t * ppos); -static ssize_t dtlk_write(struct file *, const char *, +static ssize_t dtlk_write(struct file *, const char __user *, size_t nbytes, loff_t * ppos); static unsigned int dtlk_poll(struct file *, poll_table *); static int dtlk_open(struct inode *, struct file *); @@ -121,7 +121,7 @@ */ static void dtlk_timer_tick(unsigned long data); -static ssize_t dtlk_read(struct file *file, char *buf, +static ssize_t dtlk_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) { unsigned int minor = iminor(file->f_dentry->d_inode); @@ -158,7 +158,7 @@ return -EAGAIN; } -static ssize_t dtlk_write(struct file *file, const char *buf, +static ssize_t dtlk_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { int i = 0, retries = 0, ch; @@ -277,6 +277,7 @@ unsigned int cmd, unsigned long arg) { + char __user *argp = (char __user *)arg; struct dtlk_settings *sp; char portval; TRACE_TEXT(" dtlk_ioctl"); @@ -285,14 +286,13 @@ case DTLK_INTERROGATE: sp = dtlk_interrogate(); - if (copy_to_user((char *) arg, (char *) sp, - sizeof(struct dtlk_settings))) + if (copy_to_user(argp, sp, sizeof(struct dtlk_settings))) return -EINVAL; return 0; case DTLK_STATUS: portval = inb_p(dtlk_port_tts); - return put_user(portval, (char *) arg); + return put_user(portval, argp); default: return -EINVAL; diff -Nru a/drivers/char/genrtc.c b/drivers/char/genrtc.c --- a/drivers/char/genrtc.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/genrtc.c 2004-06-26 17:09:20 -07:00 @@ -171,7 +171,7 @@ /* * Now all the various file operations that we export. */ -static ssize_t gen_rtc_read(struct file *file, char *buf, +static ssize_t gen_rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { DECLARE_WAITQUEUE(wait, current); @@ -200,10 +200,10 @@ /* first test allows optimizer to nuke this case for 32-bit machines */ if (sizeof (int) != sizeof (long) && count == sizeof (unsigned int)) { unsigned int uidata = data; - retval = put_user(uidata, (unsigned long *)buf); + retval = put_user(uidata, (unsigned long __user *)buf); } else { - retval = put_user(data, (unsigned long *)buf); + retval = put_user(data, (unsigned long __user *)buf); } if (!retval) retval = sizeof(unsigned long); @@ -278,6 +278,7 @@ { struct rtc_time wtime; struct rtc_pll_info pll; + void __user *argp = (void __user *)arg; switch (cmd) { @@ -285,13 +286,12 @@ if (get_rtc_pll(&pll)) return -EINVAL; else - return copy_to_user((void *)arg, &pll, sizeof pll) ? -EFAULT : 0; + return copy_to_user(argp, &pll, sizeof pll) ? -EFAULT : 0; case RTC_PLL_SET: if (!capable(CAP_SYS_TIME)) return -EACCES; - if (copy_from_user(&pll, (struct rtc_pll_info*)arg, - sizeof(pll))) + if (copy_from_user(&pll, argp, sizeof(pll))) return -EFAULT; return set_rtc_pll(&pll); @@ -307,7 +307,7 @@ memset(&wtime, 0, sizeof(wtime)); get_rtc_time(&wtime); - return copy_to_user((void *)arg, &wtime, sizeof(wtime)) ? -EFAULT : 0; + return copy_to_user(argp, &wtime, sizeof(wtime)) ? -EFAULT : 0; case RTC_SET_TIME: /* Set the RTC */ { @@ -317,8 +317,7 @@ if (!capable(CAP_SYS_TIME)) return -EACCES; - if (copy_from_user(&wtime, (struct rtc_time *)arg, - sizeof(wtime))) + if (copy_from_user(&wtime, argp, sizeof(wtime))) return -EFAULT; year = wtime.tm_year + 1900; diff -Nru a/drivers/char/hpet.c b/drivers/char/hpet.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/char/hpet.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1076 @@ +/* + * Intel & MS High Precision Event Timer Implementation. + * Contributors: + * Venki Pallipadi + * Bob Picco + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * The High Precision Event Timer driver. + * This driver is closely modelled after the rtc.c driver. + * http://www.intel.com/labs/platcomp/hpet/hpetspec.htm + */ +#define HPET_USER_FREQ (64) +#define HPET_DRIFT (500) + +static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; + +/* A lock for concurrent access by app and isr hpet activity. */ +static spinlock_t hpet_lock = SPIN_LOCK_UNLOCKED; +/* A lock for concurrent intermodule access to hpet and isr hpet activity. */ +static spinlock_t hpet_task_lock = SPIN_LOCK_UNLOCKED; + +struct hpet_dev { + struct hpets *hd_hpets; + struct hpet *hd_hpet; + struct hpet_timer *hd_timer; + unsigned long hd_ireqfreq; + unsigned long hd_irqdata; + wait_queue_head_t hd_waitqueue; + struct fasync_struct *hd_async_queue; + struct hpet_task *hd_task; + unsigned int hd_flags; + unsigned int hd_irq; + unsigned int hd_hdwirq; +}; + +struct hpets { + struct hpets *hp_next; + struct hpet *hp_hpet; + unsigned long hp_period; + unsigned long hp_delta; + unsigned int hp_ntimer; + unsigned int hp_which; + struct hpet_dev hp_dev[1]; +}; + +static struct hpets *hpets; + +#define HPET_OPEN 0x0001 +#define HPET_IE 0x0002 /* interrupt enabled */ +#define HPET_PERIODIC 0x0004 + +#if BITS_PER_LONG == 64 +#define write_counter(V, MC) writeq(V, MC) +#define read_counter(MC) readq(MC) +#else +#define write_counter(V, MC) writel(V, MC) +#define read_counter(MC) readl(MC) +#endif + +#ifndef readq +static unsigned long long __inline readq(void *addr) +{ + return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL); +} +#endif + +#ifndef writeq +static void __inline writeq(unsigned long long v, void *addr) +{ + writel(v & 0xffffffff, addr); + writel(v >> 32, addr + 4); +} +#endif + +static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs) +{ + struct hpet_dev *devp; + unsigned long isr; + + devp = data; + + spin_lock(&hpet_lock); + devp->hd_irqdata++; + + /* + * For non-periodic timers, increment the accumulator. + * This has the effect of treating non-periodic like periodic. + */ + if ((devp->hd_flags & (HPET_IE | HPET_PERIODIC)) == HPET_IE) { + unsigned long m, t; + + t = devp->hd_ireqfreq; + m = read_counter(&devp->hd_hpet->hpet_mc); + write_counter(t + m + devp->hd_hpets->hp_delta, + &devp->hd_timer->hpet_compare); + } + + isr = (1 << (devp - devp->hd_hpets->hp_dev)); + writeq(isr, &devp->hd_hpet->hpet_isr); + spin_unlock(&hpet_lock); + + spin_lock(&hpet_task_lock); + if (devp->hd_task) + devp->hd_task->ht_func(devp->hd_task->ht_data); + spin_unlock(&hpet_task_lock); + + wake_up_interruptible(&devp->hd_waitqueue); + + kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN); + + return IRQ_HANDLED; +} + +static int hpet_open(struct inode *inode, struct file *file) +{ + struct hpet_dev *devp; + struct hpets *hpetp; + int i; + + spin_lock_irq(&hpet_lock); + + for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) + for (i = 0; i < hpetp->hp_ntimer; i++) + if (hpetp->hp_dev[i].hd_flags & HPET_OPEN + || hpetp->hp_dev[i].hd_task) + continue; + else { + devp = &hpetp->hp_dev[i]; + break; + } + + if (!devp) { + spin_unlock_irq(&hpet_lock); + return -EBUSY; + } + + file->private_data = devp; + devp->hd_irqdata = 0; + devp->hd_flags |= HPET_OPEN; + spin_unlock_irq(&hpet_lock); + + return 0; +} + +static ssize_t +hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long data; + ssize_t retval; + struct hpet_dev *devp; + + devp = file->private_data; + if (!devp->hd_ireqfreq) + return -EIO; + + if (count < sizeof(unsigned long)) + return -EINVAL; + + add_wait_queue(&devp->hd_waitqueue, &wait); + + do { + __set_current_state(TASK_INTERRUPTIBLE); + + spin_lock_irq(&hpet_lock); + data = devp->hd_irqdata; + devp->hd_irqdata = 0; + spin_unlock_irq(&hpet_lock); + + if (data) + break; + else if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto out; + } else if (signal_pending(current)) { + retval = -ERESTARTSYS; + goto out; + } + + schedule(); + + } while (1); + + retval = put_user(data, (unsigned long __user *)buf); + if (!retval) + retval = sizeof(unsigned long); + out: + current->state = TASK_RUNNING; + remove_wait_queue(&devp->hd_waitqueue, &wait); + + return retval; +} + +static unsigned int hpet_poll(struct file *file, poll_table * wait) +{ + unsigned long v; + struct hpet_dev *devp; + + devp = file->private_data; + + if (!devp->hd_ireqfreq) + return 0; + + poll_wait(file, &devp->hd_waitqueue, wait); + + spin_lock_irq(&hpet_lock); + v = devp->hd_irqdata; + spin_unlock_irq(&hpet_lock); + + if (v != 0) + return POLLIN | POLLRDNORM; + + return 0; +} + +static int hpet_mmap(struct file *file, struct vm_area_struct *vma) +{ +#ifdef CONFIG_HPET_NOMMAP + return -ENOSYS; +#else + struct hpet_dev *devp; + unsigned long addr; + + if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) + return -EINVAL; + + if (vma->vm_flags & VM_WRITE) + return -EPERM; + + devp = file->private_data; + addr = (unsigned long)devp->hd_hpet; + + if (addr & (PAGE_SIZE - 1)) + return -ENOSYS; + + vma->vm_flags |= VM_IO; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + addr = __pa(addr); + + if (remap_page_range + (vma, vma->vm_start, addr, PAGE_SIZE, vma->vm_page_prot)) { + printk(KERN_ERR "remap_page_range failed in hpet.c\n"); + return -EAGAIN; + } + + return 0; +#endif +} + +static int hpet_fasync(int fd, struct file *file, int on) +{ + struct hpet_dev *devp; + + devp = file->private_data; + + if (fasync_helper(fd, file, on, &devp->hd_async_queue) >= 0) + return 0; + else + return -EIO; +} + +static int hpet_release(struct inode *inode, struct file *file) +{ + struct hpet_dev *devp; + struct hpet_timer *timer; + int irq = 0; + + devp = file->private_data; + timer = devp->hd_timer; + + spin_lock_irq(&hpet_lock); + + writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK), + &timer->hpet_config); + + irq = devp->hd_irq; + devp->hd_irq = 0; + + devp->hd_ireqfreq = 0; + + if (devp->hd_flags & HPET_PERIODIC + && readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) { + unsigned long v; + + v = readq(&timer->hpet_config); + v ^= Tn_TYPE_CNF_MASK; + writeq(v, &timer->hpet_config); + } + + devp->hd_flags &= ~(HPET_OPEN | HPET_IE | HPET_PERIODIC); + spin_unlock_irq(&hpet_lock); + + if (irq) + free_irq(irq, devp); + + if (file->f_flags & FASYNC) + hpet_fasync(-1, file, 0); + + file->private_data = 0; + return 0; +} + +static int hpet_ioctl_common(struct hpet_dev *, int, unsigned long, int); + +static int +hpet_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct hpet_dev *devp; + + devp = file->private_data; + return hpet_ioctl_common(devp, cmd, arg, 0); +} + +static int hpet_ioctl_ieon(struct hpet_dev *devp) +{ + struct hpet_timer *timer; + struct hpet *hpet; + struct hpets *hpetp; + int irq; + unsigned long g, v, t, m; + unsigned long flags, isr; + + timer = devp->hd_timer; + hpet = devp->hd_hpet; + hpetp = devp->hd_hpets; + + v = readq(&timer->hpet_config); + spin_lock_irq(&hpet_lock); + + if (devp->hd_flags & HPET_IE) { + spin_unlock_irq(&hpet_lock); + return -EBUSY; + } + + devp->hd_flags |= HPET_IE; + spin_unlock_irq(&hpet_lock); + + t = readq(&timer->hpet_config); + irq = devp->hd_hdwirq; + + if (irq) { + char name[7]; + + sprintf(name, "hpet%d", (int)(devp - hpetp->hp_dev)); + + if (request_irq + (irq, hpet_interrupt, SA_INTERRUPT, name, (void *)devp)) { + printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); + irq = 0; + } + } + + if (irq == 0) { + spin_lock_irq(&hpet_lock); + devp->hd_flags ^= HPET_IE; + spin_unlock_irq(&hpet_lock); + return -EIO; + } + + devp->hd_irq = irq; + t = devp->hd_ireqfreq; + v = readq(&timer->hpet_config); + g = v | Tn_INT_ENB_CNF_MASK; + + if (devp->hd_flags & HPET_PERIODIC) { + write_counter(t, &timer->hpet_compare); + g |= Tn_TYPE_CNF_MASK; + v |= Tn_TYPE_CNF_MASK; + writeq(v, &timer->hpet_config); + v |= Tn_VAL_SET_CNF_MASK; + writeq(v, &timer->hpet_config); + local_irq_save(flags); + m = read_counter(&hpet->hpet_mc); + write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); + } else { + local_irq_save(flags); + m = read_counter(&hpet->hpet_mc); + write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); + } + + isr = (1 << (devp - hpets->hp_dev)); + writeq(isr, &hpet->hpet_isr); + writeq(g, &timer->hpet_config); + local_irq_restore(flags); + + return 0; +} + +static inline unsigned long hpet_time_div(unsigned long dis) +{ + unsigned long long m = 1000000000000000ULL; + + do_div(m, dis); + + return (unsigned long)m; +} + +static int +hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) +{ + struct hpet_timer *timer; + struct hpet *hpet; + struct hpets *hpetp; + int err; + unsigned long v; + + switch (cmd) { + case HPET_IE_OFF: + case HPET_INFO: + case HPET_EPI: + case HPET_DPI: + case HPET_IRQFREQ: + timer = devp->hd_timer; + hpet = devp->hd_hpet; + hpetp = devp->hd_hpets; + break; + case HPET_IE_ON: + return hpet_ioctl_ieon(devp); + default: + return -EINVAL; + } + + err = 0; + + switch (cmd) { + case HPET_IE_OFF: + if ((devp->hd_flags & HPET_IE) == 0) + break; + v = readq(&timer->hpet_config); + v &= ~Tn_INT_ENB_CNF_MASK; + writeq(v, &timer->hpet_config); + if (devp->hd_irq) { + free_irq(devp->hd_irq, devp); + devp->hd_irq = 0; + } + devp->hd_flags ^= HPET_IE; + break; + case HPET_INFO: + { + struct hpet_info info; + + info.hi_ireqfreq = hpet_time_div(hpetp->hp_period * + devp->hd_ireqfreq); + info.hi_flags = + readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; + info.hi_hpet = devp->hd_hpets->hp_which; + info.hi_timer = devp - devp->hd_hpets->hp_dev; + if (copy_to_user((void __user *)arg, &info, sizeof(info))) + err = -EFAULT; + break; + } + case HPET_EPI: + v = readq(&timer->hpet_config); + if ((v & Tn_PER_INT_CAP_MASK) == 0) { + err = -ENXIO; + break; + } + devp->hd_flags |= HPET_PERIODIC; + break; + case HPET_DPI: + v = readq(&timer->hpet_config); + if ((v & Tn_PER_INT_CAP_MASK) == 0) { + err = -ENXIO; + break; + } + if (devp->hd_flags & HPET_PERIODIC && + readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) { + v = readq(&timer->hpet_config); + v ^= Tn_TYPE_CNF_MASK; + writeq(v, &timer->hpet_config); + } + devp->hd_flags &= ~HPET_PERIODIC; + break; + case HPET_IRQFREQ: + if (!kernel && (arg > hpet_max_freq) && + !capable(CAP_SYS_RESOURCE)) { + err = -EACCES; + break; + } + + if (arg & (arg - 1)) { + err = -EINVAL; + break; + } + + devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg); + } + + return err; +} + +static struct file_operations hpet_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = hpet_read, + .poll = hpet_poll, + .ioctl = hpet_ioctl, + .open = hpet_open, + .release = hpet_release, + .fasync = hpet_fasync, + .mmap = hpet_mmap, +}; + +EXPORT_SYMBOL(hpet_alloc); +EXPORT_SYMBOL(hpet_register); +EXPORT_SYMBOL(hpet_unregister); +EXPORT_SYMBOL(hpet_control); + +int hpet_register(struct hpet_task *tp, int periodic) +{ + unsigned int i; + u64 mask; + struct hpet_timer *timer; + struct hpet_dev *devp; + struct hpets *hpetp; + + switch (periodic) { + case 1: + mask = Tn_PER_INT_CAP_MASK; + break; + case 0: + mask = 0; + break; + default: + return -EINVAL; + } + + spin_lock_irq(&hpet_task_lock); + spin_lock(&hpet_lock); + + for (devp = 0, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) + for (timer = hpetp->hp_hpet->hpet_timers, i = 0; + i < hpetp->hp_ntimer; i++, timer++) { + if ((readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK) + != mask) + continue; + + devp = &hpetp->hp_dev[i]; + + if (devp->hd_flags & HPET_OPEN || devp->hd_task) { + devp = 0; + continue; + } + + tp->ht_opaque = devp; + devp->hd_task = tp; + break; + } + + spin_unlock(&hpet_lock); + spin_unlock_irq(&hpet_task_lock); + + if (tp->ht_opaque) + return 0; + else + return -EBUSY; +} + +static inline int hpet_tpcheck(struct hpet_task *tp) +{ + struct hpet_dev *devp; + struct hpets *hpetp; + + devp = tp->ht_opaque; + + if (!devp) + return -ENXIO; + + for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) + if (devp >= hpetp->hp_dev + && devp < (hpetp->hp_dev + hpetp->hp_ntimer) + && devp->hd_hpet == hpetp->hp_hpet) + return 0; + + return -ENXIO; +} + +int hpet_unregister(struct hpet_task *tp) +{ + struct hpet_dev *devp; + struct hpet_timer *timer; + int err; + + if ((err = hpet_tpcheck(tp))) + return err; + + spin_lock_irq(&hpet_task_lock); + spin_lock(&hpet_lock); + + devp = tp->ht_opaque; + if (devp->hd_task != tp) { + spin_unlock(&hpet_lock); + spin_unlock_irq(&hpet_task_lock); + return -ENXIO; + } + + timer = devp->hd_timer; + writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK), + &timer->hpet_config); + devp->hd_flags &= ~(HPET_IE | HPET_PERIODIC); + devp->hd_task = 0; + spin_unlock(&hpet_lock); + spin_unlock_irq(&hpet_task_lock); + + return 0; +} + +int hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg) +{ + struct hpet_dev *devp; + int err; + + if ((err = hpet_tpcheck(tp))) + return err; + + spin_lock_irq(&hpet_lock); + devp = tp->ht_opaque; + if (devp->hd_task != tp) { + spin_unlock_irq(&hpet_lock); + return -ENXIO; + } + spin_unlock_irq(&hpet_lock); + return hpet_ioctl_common(devp, cmd, arg, 1); +} + +#ifdef CONFIG_TIME_INTERPOLATION + +static unsigned long hpet_offset, last_wall_hpet; +static long hpet_nsecs_per_cycle, hpet_cycles_per_sec; + +static unsigned long hpet_getoffset(void) +{ + return hpet_offset + (read_counter(&hpets->hp_hpet->hpet_mc) - + last_wall_hpet) * hpet_nsecs_per_cycle; +} + +static void hpet_update(long delta) +{ + unsigned long mc; + unsigned long offset; + + mc = read_counter(&hpets->hp_hpet->hpet_mc); + offset = hpet_offset + (mc - last_wall_hpet) * hpet_nsecs_per_cycle; + + if (delta < 0 || (unsigned long)delta < offset) + hpet_offset = offset - delta; + else + hpet_offset = 0; + last_wall_hpet = mc; +} + +static void hpet_reset(void) +{ + hpet_offset = 0; + last_wall_hpet = read_counter(&hpets->hp_hpet->hpet_mc); +} + +static struct time_interpolator hpet_interpolator = { + .get_offset = hpet_getoffset, + .update = hpet_update, + .reset = hpet_reset +}; + +#endif + +static ctl_table hpet_table[] = { + { + .ctl_name = 1, + .procname = "max-user-freq", + .data = &hpet_max_freq, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + {.ctl_name = 0} +}; + +static ctl_table hpet_root[] = { + { + .ctl_name = 1, + .procname = "hpet", + .maxlen = 0, + .mode = 0555, + .child = hpet_table, + }, + {.ctl_name = 0} +}; + +static ctl_table dev_root[] = { + { + .ctl_name = CTL_DEV, + .procname = "dev", + .maxlen = 0, + .mode = 0555, + .child = hpet_root, + }, + {.ctl_name = 0} +}; + +static struct ctl_table_header *sysctl_header; + +static void *hpet_start(struct seq_file *s, loff_t * pos) +{ + struct hpets *hpetp; + loff_t n; + + for (n = *pos, hpetp = hpets; hpetp; hpetp = hpetp->hp_next) + if (!n--) + return hpetp; + + return 0; +} + +static void *hpet_next(struct seq_file *s, void *v, loff_t * pos) +{ + struct hpets *hpetp; + + hpetp = v; + ++*pos; + return hpetp->hp_next; +} + +static void hpet_stop(struct seq_file *s, void *v) +{ + return; +} + +static int hpet_show(struct seq_file *s, void *v) +{ + struct hpets *hpetp; + struct hpet *hpet; + u64 cap, vendor, period; + + hpetp = v; + hpet = hpetp->hp_hpet; + + cap = readq(&hpet->hpet_cap); + period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> + HPET_COUNTER_CLK_PERIOD_SHIFT; + vendor = (cap & HPET_VENDOR_ID_MASK) >> HPET_VENDOR_ID_SHIFT; + + seq_printf(s, + "HPET%d period = %d 10**-15 vendor = 0x%x number timer = %d\n", + hpetp->hp_which, (u32) period, (u32) vendor, + hpetp->hp_ntimer); + + return 0; +} + +static struct seq_operations hpet_seq_ops = { + .start = hpet_start, + .next = hpet_next, + .stop = hpet_stop, + .show = hpet_show +}; + +static int hpet_proc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &hpet_seq_ops); +} + +static struct file_operations hpet_proc_fops = { + .open = hpet_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + +/* + * Adjustment for when arming the timer with + * initial conditions. That is, main counter + * ticks expired before interrupts are enabled. + */ +#define TICK_CALIBRATE (1000UL) + +static unsigned long __init hpet_calibrate(struct hpets *hpetp) +{ + struct hpet_timer *timer; + unsigned long t, m, count, i, flags, start; + struct hpet_dev *devp; + int j; + struct hpet *hpet; + + for (timer = 0, j = 0, devp = hpetp->hp_dev; j < hpetp->hp_ntimer; + j++, devp++) + if ((devp->hd_flags & HPET_OPEN) == 0) { + timer = devp->hd_timer; + break; + } + + if (!timer) + return 0; + + hpet = hpets->hp_hpet; + t = read_counter(&timer->hpet_compare); + + i = 0; + count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE); + + local_irq_save(flags); + + start = read_counter(&hpet->hpet_mc); + + do { + m = read_counter(&hpet->hpet_mc); + write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); + } while (i++, (m - start) < count); + + local_irq_restore(flags); + + return (m - start) / i; +} + +int __init hpet_alloc(struct hpet_data *hdp) +{ + u64 cap, mcfg; + struct hpet_dev *devp; + u32 i, ntimer; + struct hpets *hpetp; + size_t siz; + struct hpet *hpet; + static struct hpets *last __initdata = (struct hpets *)0; + + /* + * hpet_alloc can be called by platform dependent code. + * if platform dependent code has allocated the hpet + * ACPI also reports hpet, then we catch it here. + */ + for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) + if (hpetp->hp_hpet == (struct hpet *)(hdp->hd_address)) + return 0; + + siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) * + sizeof(struct hpet_dev)); + + hpetp = kmalloc(siz, GFP_KERNEL); + + if (!hpetp) + return -ENOMEM; + + memset(hpetp, 0, siz); + + hpetp->hp_which = hpet_nhpet++; + hpetp->hp_hpet = (struct hpet *)hdp->hd_address; + + hpetp->hp_ntimer = hdp->hd_nirqs; + + for (i = 0; i < hdp->hd_nirqs; i++) + hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i]; + + hpet = hpetp->hp_hpet; + + cap = readq(&hpet->hpet_cap); + + ntimer = ((cap & HPET_NUM_TIM_CAP_MASK) >> HPET_NUM_TIM_CAP_SHIFT) + 1; + + if (hpetp->hp_ntimer != ntimer) { + printk(KERN_WARNING "hpet: number irqs doesn't agree" + " with number of timers\n"); + kfree(hpetp); + return -ENODEV; + } + + if (last) + last->hp_next = hpetp; + else + hpets = hpetp; + + last = hpetp; + + hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> + HPET_COUNTER_CLK_PERIOD_SHIFT; + + mcfg = readq(&hpet->hpet_config); + if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { + write_counter(0L, &hpet->hpet_mc); + mcfg |= HPET_ENABLE_CNF_MASK; + writeq(mcfg, &hpet->hpet_config); + } + + for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; + i++, hpet_ntimer++, devp++) { + unsigned long v; + struct hpet_timer *timer; + + timer = &hpet->hpet_timers[devp - hpetp->hp_dev]; + v = readq(&timer->hpet_config); + + devp->hd_hpets = hpetp; + devp->hd_hpet = hpet; + devp->hd_timer = timer; + + /* + * If the timer was reserved by platform code, + * then make timer unavailable for opens. + */ + if (hdp->hd_state & (1 << i)) { + devp->hd_flags = HPET_OPEN; + continue; + } + + init_waitqueue_head(&devp->hd_waitqueue); + } + + hpetp->hp_delta = hpet_calibrate(hpetp); + + return 0; +} + +static acpi_status __init hpet_resources(struct acpi_resource *res, void *data) +{ + struct hpet_data *hdp; + acpi_status status; + struct acpi_resource_address64 addr; + struct hpets *hpetp; + + hdp = data; + + status = acpi_resource_to_address64(res, &addr); + + if (ACPI_SUCCESS(status)) { + unsigned long size; + + size = addr.max_address_range - addr.min_address_range + 1; + hdp->hd_address = + (unsigned long)ioremap(addr.min_address_range, size); + + for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) + if (hpetp->hp_hpet == (struct hpet *)(hdp->hd_address)) + return -EBUSY; + } else if (res->id == ACPI_RSTYPE_EXT_IRQ) { + struct acpi_resource_ext_irq *irqp; + int i; + + irqp = &res->data.extended_irq; + + if (irqp->number_of_interrupts > 0) { + hdp->hd_nirqs = irqp->number_of_interrupts; + + for (i = 0; i < hdp->hd_nirqs; i++) +#ifdef CONFIG_IA64 + hdp->hd_irq[i] = + acpi_register_gsi(irqp->interrupts[i], + irqp->edge_level, + irqp->active_high_low); +#else + hdp->hd_irq[i] = irqp->interrupts[i]; +#endif + } + } + + return AE_OK; +} + +static int __init hpet_acpi_add(struct acpi_device *device) +{ + acpi_status result; + struct hpet_data data; + + memset(&data, 0, sizeof(data)); + + result = + acpi_walk_resources(device->handle, METHOD_NAME__CRS, + hpet_resources, &data); + + if (ACPI_FAILURE(result)) + return -ENODEV; + + if (!data.hd_address || !data.hd_nirqs) { + printk("%s: no address or irqs in _CRS\n", __FUNCTION__); + return -ENODEV; + } + + return hpet_alloc(&data); +} + +static int __init hpet_acpi_remove(struct acpi_device *device, int type) +{ + return 0; +} + +static struct acpi_driver hpet_acpi_driver __initdata = { + .name = "hpet", + .class = "", + .ids = "PNP0103", + .ops = { + .add = hpet_acpi_add, + .remove = hpet_acpi_remove, + }, +}; + +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops }; + +static int __init hpet_init(void) +{ + struct proc_dir_entry *entry; + + (void)acpi_bus_register_driver(&hpet_acpi_driver); + + if (hpets) { + if (misc_register(&hpet_misc)) + return -ENODEV; + + entry = create_proc_entry("driver/hpet", 0, 0); + + if (entry) + entry->proc_fops = &hpet_proc_fops; + + sysctl_header = register_sysctl_table(dev_root, 0); + +#ifdef CONFIG_TIME_INTERPOLATION + { + struct hpet *hpet; + + hpet = hpets->hp_hpet; + hpet_cycles_per_sec = hpet_time_div(hpets->hp_period); + hpet_interpolator.frequency = hpet_cycles_per_sec; + hpet_interpolator.drift = hpet_cycles_per_sec * + HPET_DRIFT / 1000000; + hpet_nsecs_per_cycle = 1000000000 / hpet_cycles_per_sec; + register_time_interpolator(&hpet_interpolator); + } +#endif + return 0; + } else + return -ENODEV; +} + +static void __exit hpet_exit(void) +{ + acpi_bus_unregister_driver(&hpet_acpi_driver); + + if (hpets) { + unregister_sysctl_table(sysctl_header); + remove_proc_entry("driver/hpet", NULL); + } + + return; +} + +module_init(hpet_init); +module_exit(hpet_exit); +MODULE_AUTHOR("Bob Picco "); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/char/ip27-rtc.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,327 @@ +/* + * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip + * + * Real Time Clock interface for Linux + * + * TODO: Implement periodic interrupts. + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * + * Based on code written by Paul Gortmaker. + * + * This driver allows use of the real time clock (built into + * nearly all computers) from user space. It exports the /dev/rtc + * interface supporting various ioctl() and also the /proc/rtc + * pseudo-file for status information. + * + * 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. + * + */ + +#define RTC_VERSION "1.09b" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +static void get_rtc_time(struct rtc_time *rtc_tm); + +/* + * Bits in rtc_status. (6 bits of room for future expansion) + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ +#define RTC_TIMER_ON 0x02 /* missed irq timer active */ + +static unsigned char rtc_status; /* bitmapped status byte. */ +static unsigned long rtc_freq; /* Current periodic IRQ rate */ +static struct m48t35_rtc *rtc; + +/* + * If this driver ever becomes modularised, it will be really nice + * to make the epoch retain its value across module reload... + */ + +static unsigned long epoch = 1970; /* year corresponding to 0x00 */ + +static const unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + + struct rtc_time wtime; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + get_rtc_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned int yrs; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + yrs = rtc_tm.tm_year + 1900; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; + + if (yrs < 1970) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ((yrs -= epoch) > 255) /* They are unsigned */ + return -EINVAL; + + if (yrs > 169) + return -EINVAL; + + if (yrs >= 100) + yrs -= 100; + + sec = BIN2BCD(sec); + min = BIN2BCD(min); + hrs = BIN2BCD(hrs); + day = BIN2BCD(day); + mon = BIN2BCD(mon); + yrs = BIN2BCD(yrs); + + spin_lock_irq(&rtc_lock); + rtc->control |= M48T35_RTC_SET; + rtc->year = yrs; + rtc->month = mon; + rtc->date = day; + rtc->hour = hrs; + rtc->min = min; + rtc->sec = sec; + rtc->control &= ~M48T35_RTC_SET; + spin_unlock_irq(&rtc_lock); + + return 0; + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + /* + * Turn off all interrupts once the device is no longer + * in use, and clear the data. + */ + + spin_lock_irq(&rtc_lock); + rtc_status &= ~RTC_IS_OPEN; + spin_unlock_irq(&rtc_lock); + + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + .owner = THIS_MODULE, + .ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, +}; + +static struct miscdevice rtc_dev= +{ + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int __init rtc_init(void) +{ + rtc = (struct m48t35_rtc *) + (KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base + IOC3_BYTEBUS_DEV0); + + printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); + if (misc_register(&rtc_dev)) { + printk(KERN_ERR "rtc: cannot register misc device.\n"); + return -ENODEV; + } + if (!create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL)) { + printk(KERN_ERR "rtc: cannot create /proc/rtc.\n"); + misc_deregister(&rtc_dev); + return -ENOENT; + } + + rtc_freq = 1024; + + return 0; +} + +static void __exit rtc_exit (void) +{ + /* interrupts and timer disabled at this point by rtc_release */ + + remove_proc_entry ("rtc", NULL); + misc_deregister(&rtc_dev); +} + +module_init(rtc_init); +module_exit(rtc_exit); + +/* + * Info exported via "/proc/rtc". + */ + +static int rtc_get_status(char *buf) +{ + char *p; + struct rtc_time tm; + + /* + * Just emulate the standard /proc/rtc + */ + + p = buf; + + get_rtc_time(&tm); + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n" + "24hr\t\t: yes\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_get_status(page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static void get_rtc_time(struct rtc_time *rtc_tm) +{ + /* + * Do we need to wait for the last update to finish? + */ + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + spin_lock_irq(&rtc_lock); + rtc->control |= M48T35_RTC_READ; + rtc_tm->tm_sec = rtc->sec; + rtc_tm->tm_min = rtc->min; + rtc_tm->tm_hour = rtc->hour; + rtc_tm->tm_mday = rtc->date; + rtc_tm->tm_mon = rtc->month; + rtc_tm->tm_year = rtc->year; + rtc->control &= ~M48T35_RTC_READ; + spin_unlock_irq(&rtc_lock); + + rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec); + rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min); + rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour); + rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday); + rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon); + rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year); + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) + rtc_tm->tm_year += 100; + + rtc_tm->tm_mon--; +} diff -Nru a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c --- a/drivers/char/ipmi/ipmi_bt_sm.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/ipmi/ipmi_bt_sm.c 2004-06-26 17:09:20 -07:00 @@ -31,7 +31,7 @@ #include /* for completion codes */ #include "ipmi_si_sm.h" -#define IPMI_BT_VERSION "v31" +#define IPMI_BT_VERSION "v32" static int bt_debug = 0x00; /* Production value 0, see following flags */ diff -Nru a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c --- a/drivers/char/ipmi/ipmi_devintf.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/ipmi/ipmi_devintf.c 2004-06-26 17:09:20 -07:00 @@ -45,7 +45,7 @@ #include #include -#define IPMI_DEVINTF_VERSION "v31" +#define IPMI_DEVINTF_VERSION "v32" struct ipmi_file_private { @@ -199,7 +199,7 @@ goto out; } - if (copy_from_user(&msgdata, + if (copy_from_user(msgdata, req->msg.data, req->msg.data_len)) { @@ -231,6 +231,7 @@ { int rv = -EINVAL; struct ipmi_file_private *priv = file->private_data; + void __user *arg = (void __user *)data; switch (cmd) { @@ -238,7 +239,7 @@ { struct ipmi_req req; - if (copy_from_user(&req, (void *) data, sizeof(req))) { + if (copy_from_user(&req, arg, sizeof(req))) { rv = -EFAULT; break; } @@ -254,7 +255,7 @@ { struct ipmi_req_settime req; - if (copy_from_user(&req, (void *) data, sizeof(req))) { + if (copy_from_user(&req, arg, sizeof(req))) { rv = -EFAULT; break; } @@ -277,7 +278,7 @@ rv = 0; - if (copy_from_user(&rsp, (void *) data, sizeof(rsp))) { + if (copy_from_user(&rsp, arg, sizeof(rsp))) { rv = -EFAULT; break; } @@ -344,7 +345,7 @@ rsp.msg.data_len = 0; } - if (copy_to_user((void *) data, &rsp, sizeof(rsp))) { + if (copy_to_user(arg, &rsp, sizeof(rsp))) { rv = -EFAULT; goto recv_putback_on_err; } @@ -371,7 +372,7 @@ { struct ipmi_cmdspec val; - if (copy_from_user(&val, (void *) data, sizeof(val))) { + if (copy_from_user(&val, arg, sizeof(val))) { rv = -EFAULT; break; } @@ -384,7 +385,7 @@ { struct ipmi_cmdspec val; - if (copy_from_user(&val, (void *) data, sizeof(val))) { + if (copy_from_user(&val, arg, sizeof(val))) { rv = -EFAULT; break; } @@ -397,7 +398,7 @@ { int val; - if (copy_from_user(&val, (void *) data, sizeof(val))) { + if (copy_from_user(&val, arg, sizeof(val))) { rv = -EFAULT; break; } @@ -410,7 +411,7 @@ { unsigned int val; - if (copy_from_user(&val, (void *) data, sizeof(val))) { + if (copy_from_user(&val, arg, sizeof(val))) { rv = -EFAULT; break; } @@ -426,7 +427,7 @@ val = ipmi_get_my_address(priv->user); - if (copy_to_user((void *) data, &val, sizeof(val))) { + if (copy_to_user(arg, &val, sizeof(val))) { rv = -EFAULT; break; } @@ -438,7 +439,7 @@ { unsigned int val; - if (copy_from_user(&val, (void *) data, sizeof(val))) { + if (copy_from_user(&val, arg, sizeof(val))) { rv = -EFAULT; break; } @@ -454,7 +455,7 @@ val = ipmi_get_my_LUN(priv->user); - if (copy_to_user((void *) data, &val, sizeof(val))) { + if (copy_to_user(arg, &val, sizeof(val))) { rv = -EFAULT; break; } @@ -465,7 +466,7 @@ { struct ipmi_timing_parms parms; - if (copy_from_user(&parms, (void *) data, sizeof(parms))) { + if (copy_from_user(&parms, arg, sizeof(parms))) { rv = -EFAULT; break; } @@ -483,7 +484,7 @@ parms.retries = priv->default_retries; parms.retry_time_ms = priv->default_retry_time_ms; - if (copy_to_user((void *) data, &parms, sizeof(parms))) { + if (copy_to_user(arg, &parms, sizeof(parms))) { rv = -EFAULT; break; } diff -Nru a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c --- a/drivers/char/ipmi/ipmi_kcs_sm.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/char/ipmi/ipmi_kcs_sm.c 2004-06-26 17:09:15 -07:00 @@ -42,7 +42,7 @@ #include /* for completion codes */ #include "ipmi_si_sm.h" -#define IPMI_KCS_VERSION "v31" +#define IPMI_KCS_VERSION "v32" /* Set this if you want a printout of why the state machine was hosed when it gets hosed. */ diff -Nru a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c --- a/drivers/char/ipmi/ipmi_msghandler.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/ipmi/ipmi_msghandler.c 2004-06-26 17:09:18 -07:00 @@ -46,7 +46,7 @@ #include #include -#define IPMI_MSGHANDLER_VERSION "v31" +#define IPMI_MSGHANDLER_VERSION "v32" struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); static int ipmi_init_msghandler(void); @@ -1648,6 +1648,22 @@ /* It's the one we want */ if (msg->rsp[2] != 0) { /* Got an error from the channel, just go on. */ + + if (msg->rsp[2] == IPMI_INVALID_COMMAND_ERR) { + /* If the MC does not support this + command, that is legal. We just + assume it has one IPMB at channel + zero. */ + intf->channels[0].medium + = IPMI_CHANNEL_MEDIUM_IPMB; + intf->channels[0].protocol + = IPMI_CHANNEL_PROTOCOL_IPMB; + rv = -ENOSYS; + + intf->curr_channel = IPMI_MAX_CHANNELS; + wake_up(&intf->waitq); + goto out; + } goto next_channel; } if (msg->rsp_size < 6) { @@ -1671,10 +1687,20 @@ wake_up(&intf->waitq); printk(KERN_WARNING "ipmi_msghandler: Error sending" - "channel information: 0x%x\n", + "channel information: %d\n", rv); } } + out: + return; +} + +void ipmi_poll_interface(ipmi_user_t user) +{ + ipmi_smi_t intf = user->intf; + + if (intf->handlers->poll) + intf->handlers->poll(intf->send_info); } int ipmi_register_smi(struct ipmi_smi_handlers *handlers, @@ -3154,6 +3180,7 @@ EXPORT_SYMBOL(ipmi_request_settime); EXPORT_SYMBOL(ipmi_request_supply_msgs); EXPORT_SYMBOL(ipmi_request_with_source); +EXPORT_SYMBOL(ipmi_poll_interface); EXPORT_SYMBOL(ipmi_register_smi); EXPORT_SYMBOL(ipmi_unregister_smi); EXPORT_SYMBOL(ipmi_register_for_cmd); diff -Nru a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c --- a/drivers/char/ipmi/ipmi_si_intf.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/ipmi/ipmi_si_intf.c 2004-06-26 17:09:16 -07:00 @@ -76,7 +76,7 @@ #include "ipmi_si_sm.h" #include -#define IPMI_SI_VERSION "v31" +#define IPMI_SI_VERSION "v32" /* Measure times between events in the driver. */ #undef DEBUG_TIMING @@ -712,6 +712,13 @@ spin_unlock_irqrestore(&(smi_info->si_lock), flags); } +static void poll(void *send_info) +{ + struct smi_info *smi_info = send_info; + + smi_event_handler(smi_info, 0); +} + static void request_events(void *send_info) { struct smi_info *smi_info = send_info; @@ -851,7 +858,8 @@ .owner = THIS_MODULE, .sender = sender, .request_events = request_events, - .set_run_to_completion = set_run_to_completion + .set_run_to_completion = set_run_to_completion, + .poll = poll, }; /* There can be 4 IO ports passed in (with or without IRQs), 4 addresses, @@ -1848,6 +1856,21 @@ atomic_set(&new_smi->req_events, 0); new_smi->run_to_completion = 0; + new_smi->interrupt_disabled = 0; + new_smi->timer_stopped = 0; + new_smi->stop_operation = 0; + + /* The ipmi_register_smi() code does some operations to + determine the channel information, so we must be ready to + handle operations before it is called. This means we have + to stop the timer if we get an error after this point. */ + init_timer(&(new_smi->si_timer)); + new_smi->si_timer.data = (long) new_smi; + new_smi->si_timer.function = smi_timeout; + new_smi->last_timeout_jiffies = jiffies; + new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; + add_timer(&(new_smi->si_timer)); + rv = ipmi_register_smi(&handlers, new_smi, new_smi->ipmi_version_major, @@ -1857,7 +1880,7 @@ printk(KERN_ERR "ipmi_si: Unable to register device: error %d\n", rv); - goto out_err; + goto out_err_stop_timer; } rv = ipmi_smi_add_proc_entry(new_smi->intf, "type", @@ -1867,7 +1890,7 @@ printk(KERN_ERR "ipmi_si: Unable to create proc entry: %d\n", rv); - goto out_err; + goto out_err_stop_timer; } rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats", @@ -1877,7 +1900,7 @@ printk(KERN_ERR "ipmi_si: Unable to create proc entry: %d\n", rv); - goto out_err; + goto out_err_stop_timer; } start_clear_flags(new_smi); @@ -1886,34 +1909,40 @@ if (new_smi->irq) new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; - new_smi->interrupt_disabled = 0; - new_smi->timer_stopped = 0; - new_smi->stop_operation = 0; - - init_timer(&(new_smi->si_timer)); - new_smi->si_timer.data = (long) new_smi; - new_smi->si_timer.function = smi_timeout; - new_smi->last_timeout_jiffies = jiffies; - new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; - add_timer(&(new_smi->si_timer)); - *smi = new_smi; printk(" IPMI %s interface initialized\n", si_type[intf_num]); return 0; + out_err_stop_timer: + new_smi->stop_operation = 1; + + /* Wait for the timer to stop. This avoids problems with race + conditions removing the timer here. */ + while (!new_smi->timer_stopped) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } + out_err: if (new_smi->intf) ipmi_unregister_smi(new_smi->intf); new_smi->irq_cleanup(new_smi); + + /* Wait until we know that we are out of any interrupt + handlers might have been running before we freed the + interrupt. */ + synchronize_kernel(); + if (new_smi->si_sm) { if (new_smi->handlers) new_smi->handlers->cleanup(new_smi->si_sm); kfree(new_smi->si_sm); } new_smi->io_cleanup(new_smi); + return rv; } diff -Nru a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c --- a/drivers/char/ipmi/ipmi_smic_sm.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/ipmi/ipmi_smic_sm.c 2004-06-26 17:09:18 -07:00 @@ -46,7 +46,7 @@ #include /* for completion codes */ #include "ipmi_si_sm.h" -#define IPMI_SMIC_VERSION "v31" +#define IPMI_SMIC_VERSION "v32" /* smic_debug is a bit-field * SMIC_DEBUG_ENABLE - turned on for now diff -Nru a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c --- a/drivers/char/ipmi/ipmi_watchdog.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/char/ipmi/ipmi_watchdog.c 2004-06-26 17:09:21 -07:00 @@ -51,7 +51,7 @@ #include #endif -#define IPMI_WATCHDOG_VERSION "v31" +#define IPMI_WATCHDOG_VERSION "v32" /* * The IPMI command/response information for the watchdog timer. @@ -515,40 +515,37 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; int i; int val; switch(cmd) { case WDIOC_GETSUPPORT: - i = copy_to_user((void*)arg, &ident, sizeof(ident)); + i = copy_to_user(argp, &ident, sizeof(ident)); return i ? -EFAULT : 0; case WDIOC_SETTIMEOUT: - i = copy_from_user(&val, (void *) arg, sizeof(int)); + i = copy_from_user(&val, argp, sizeof(int)); if (i) return -EFAULT; timeout = val; return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); case WDIOC_GETTIMEOUT: - i = copy_to_user((void *) arg, - &timeout, - sizeof(timeout)); + i = copy_to_user(argp, &timeout, sizeof(timeout)); if (i) return -EFAULT; return 0; case WDIOC_SET_PRETIMEOUT: - i = copy_from_user(&val, (void *) arg, sizeof(int)); + i = copy_from_user(&val, argp, sizeof(int)); if (i) return -EFAULT; pretimeout = val; return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); case WDIOC_GET_PRETIMEOUT: - i = copy_to_user((void *) arg, - &pretimeout, - sizeof(pretimeout)); + i = copy_to_user(argp, &pretimeout, sizeof(pretimeout)); if (i) return -EFAULT; return 0; @@ -557,7 +554,7 @@ return ipmi_heartbeat(); case WDIOC_SETOPTIONS: - i = copy_from_user(&val, (void *) arg, sizeof(int)); + i = copy_from_user(&val, argp, sizeof(int)); if (i) return -EFAULT; if (val & WDIOS_DISABLECARD) @@ -576,7 +573,7 @@ case WDIOC_GETSTATUS: val = 0; - i = copy_to_user((void *) arg, &val, sizeof(val)); + i = copy_to_user(argp, &val, sizeof(val)); if (i) return -EFAULT; return 0; @@ -587,7 +584,7 @@ } static ssize_t ipmi_write(struct file *file, - const char *buf, + const char __user *buf, size_t len, loff_t *ppos) { @@ -607,7 +604,7 @@ } static ssize_t ipmi_read(struct file *file, - char *buf, + char __user *buf, size_t count, loff_t *ppos) { @@ -883,14 +880,12 @@ /* On a panic, if we have a panic timeout, make sure that the thing reboots, even if it hangs during that panic. */ - if (watchdog_user && !panic_event_handled && (panic_timeout > 0)) { + if (watchdog_user && !panic_event_handled) { /* Make sure the panic doesn't hang, and make sure we do this only once. */ panic_event_handled = 1; - timeout = panic_timeout + 120; - if (timeout > 255) - timeout = 255; + timeout = 255; pretimeout = 0; ipmi_watchdog_state = WDOG_TIMEOUT_RESET; panic_halt_ipmi_set_timeout(); diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c --- a/drivers/char/istallion.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/istallion.c 2004-06-26 17:09:18 -07:00 @@ -851,7 +851,7 @@ i = tty_unregister_driver(stli_serial); if (i) { printk("STALLION: failed to un-register tty driver, " - "errno=%d,%d\n", -i); + "errno=%d\n", -i); restore_flags(flags); return; } diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c --- a/drivers/char/keyboard.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/char/keyboard.c 2004-06-26 17:09:21 -07:00 @@ -52,13 +52,12 @@ /* * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. - * This seems a good reason to start with NumLock off. On PC9800 and HIL keyboards + * This seems a good reason to start with NumLock off. On HIL keyboards * of PARISC machines however there is no NumLock key and everyone expects the keypad * to be used for numbers. */ -#if defined(CONFIG_X86_PC9800) || \ - defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD)) +#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD)) #define KBD_DEFLEDS (1 << VC_NUMLOCK) #else #define KBD_DEFLEDS 0 diff -Nru a/drivers/char/lcd.c b/drivers/char/lcd.c --- a/drivers/char/lcd.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/char/lcd.c 2004-06-26 17:09:17 -07:00 @@ -12,7 +12,7 @@ * */ -#define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ +#define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ #include #include @@ -32,8 +32,8 @@ #include "lcd.h" -static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg); +static int lcd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); static int lcd_present = 1; @@ -57,8 +57,8 @@ } #endif -static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static int lcd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { struct lcd_display button_display; unsigned long address, a; @@ -69,7 +69,7 @@ udelay(150); BusyCheck(); LCDWriteInst(0x0F); - break; + break; case LCD_Off: udelay(150); @@ -95,7 +95,7 @@ case LCD_Clear: udelay(150); BusyCheck(); - LCDWriteInst(0x01); + LCDWriteInst(0x01); break; case LCD_Cursor_Left: @@ -108,86 +108,95 @@ udelay(150); BusyCheck(); LCDWriteInst(0x14); - break; + break; case LCD_Cursor_Off: udelay(150); - BusyCheck(); - LCDWriteInst(0x0C); - break; - - case LCD_Cursor_On: - udelay(150); - BusyCheck(); - LCDWriteInst(0x0F); - break; - - case LCD_Blink_Off: - udelay(150); - BusyCheck(); - LCDWriteInst(0x0E); - break; - - case LCD_Get_Cursor_Pos:{ - struct lcd_display display; + BusyCheck(); + LCDWriteInst(0x0C); + break; + case LCD_Cursor_On: udelay(150); - BusyCheck(); - display.cursor_address = ( LCDReadInst ); - display.cursor_address = ( display.cursor_address & 0x07F ); - if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) - return -EFAULT; + BusyCheck(); + LCDWriteInst(0x0F); + break; + case LCD_Blink_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0E); break; + + case LCD_Get_Cursor_Pos:{ + struct lcd_display display; + + udelay(150); + BusyCheck(); + display.cursor_address = (LCDReadInst); + display.cursor_address = + (display.cursor_address & 0x07F); + if (copy_to_user + ((struct lcd_display *) arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + + break; } - case LCD_Set_Cursor_Pos: { - struct lcd_display display; + case LCD_Set_Cursor_Pos:{ + struct lcd_display display; - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; + if (copy_from_user + (&display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - a = (display.cursor_address | kLCD_Addr ); + a = (display.cursor_address | kLCD_Addr); - udelay(150); - BusyCheck(); - LCDWriteInst( a ); + udelay(150); + BusyCheck(); + LCDWriteInst(a); - break; + break; } - - case LCD_Get_Cursor: { - struct lcd_display display; - udelay(150); - BusyCheck(); - display.character = LCDReadData; + case LCD_Get_Cursor:{ + struct lcd_display display; - if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) - return -EFAULT; - udelay(150); - BusyCheck(); - LCDWriteInst(0x10); + udelay(150); + BusyCheck(); + display.character = LCDReadData; - break; + if (copy_to_user + ((struct lcd_display *) arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; } case LCD_Set_Cursor:{ - struct lcd_display display; - - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; - - udelay(150); - BusyCheck(); - LCDWriteData( display.character ); - udelay(150); - BusyCheck(); - LCDWriteInst(0x10); + struct lcd_display display; - break; - } + if (copy_from_user + (&display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; + + udelay(150); + BusyCheck(); + LCDWriteData(display.character); + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; + } case LCD_Disp_Left: @@ -208,294 +217,330 @@ LCDWriteInst(0x02); break; - case LCD_Write: { - struct lcd_display display; - + case LCD_Write:{ + struct lcd_display display; + + + if (copy_from_user + (&display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; - - udelay(150); - BusyCheck(); - LCDWriteInst(0x80); - udelay(150); - BusyCheck(); - - for (index = 0; index < (display.size1); index++) { udelay(150); - BusyCheck(); - LCDWriteData( display.line1[index]); - BusyCheck(); - } - - udelay(150); - BusyCheck(); - LCDWriteInst(0xC0); - udelay(150); - BusyCheck(); - for (index = 0; index < (display.size2); index++) { - udelay(150); - BusyCheck(); - LCDWriteData( display.line2[index]); - } - - break; - } - - case LCD_Read: { - struct lcd_display display; + BusyCheck(); + LCDWriteInst(0x80); + udelay(150); + BusyCheck(); - BusyCheck(); - for (address = kDD_R00; address <= kDD_R01; address++) { - a = (address | kLCD_Addr ); + for (index = 0; index < (display.size1); index++) { + udelay(150); + BusyCheck(); + LCDWriteData(display.line1[index]); + BusyCheck(); + } udelay(150); BusyCheck(); - LCDWriteInst( a ); + LCDWriteInst(0xC0); udelay(150); BusyCheck(); - display.line1[address] = LCDReadData; + for (index = 0; index < (display.size2); index++) { + udelay(150); + BusyCheck(); + LCDWriteData(display.line2[index]); + } + + break; } - display.line1[ 0x27 ] = '\0'; - - for (address = kDD_R10; address <= kDD_R11; address++) { - a = (address | kLCD_Addr ); - - udelay(150); - BusyCheck(); - LCDWriteInst( a ); - - udelay(150); - BusyCheck(); - display.line2[address - 0x40 ] = LCDReadData; - } - - display.line2[ 0x27 ] = '\0'; - - if(copy_to_user((struct lcd_display*)arg, &display, - sizeof(struct lcd_display))) - return -EFAULT; - break; - } + case LCD_Read:{ + struct lcd_display display; + + BusyCheck(); + for (address = kDD_R00; address <= kDD_R01; + address++) { + a = (address | kLCD_Addr); + + udelay(150); + BusyCheck(); + LCDWriteInst(a); + udelay(150); + BusyCheck(); + display.line1[address] = LCDReadData; + } -// set all GPIO leds to led_display.leds + display.line1[0x27] = '\0'; - case LED_Set: { - struct lcd_display led_display; - + for (address = kDD_R10; address <= kDD_R11; + address++) { + a = (address | kLCD_Addr); + + udelay(150); + BusyCheck(); + LCDWriteInst(a); + + udelay(150); + BusyCheck(); + display.line2[address - 0x40] = + LCDReadData; + } + + display.line2[0x27] = '\0'; - if(copy_from_user(&led_display, (struct lcd_display*)arg, - sizeof(struct lcd_display))) - return -EFAULT; + if (copy_to_user + ((struct lcd_display *) arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } - led_state = led_display.leds; - LEDSet(led_state); +// set all GPIO leds to led_display.leds - break; - } + case LED_Set:{ + struct lcd_display led_display; + + + if (copy_from_user + (&led_display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; + + led_state = led_display.leds; + LEDSet(led_state); + + break; + } // set only bit led_display.leds - case LED_Bit_Set: { - int i; - int bit=1; - struct lcd_display led_display; + case LED_Bit_Set:{ + int i; + int bit = 1; + struct lcd_display led_display; - if(copy_from_user(&led_display, (struct lcd_display*)arg, - sizeof(struct lcd_display))) - return -EFAULT; + if (copy_from_user + (&led_display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - for (i=0;i<(int)led_display.leds;i++) - { - bit = 2*bit; + for (i = 0; i < (int) led_display.leds; i++) { + bit = 2 * bit; } - led_state = led_state | bit; - LEDSet(led_state); - break; - } + led_state = led_state | bit; + LEDSet(led_state); + break; + } // clear only bit led_display.leds - case LED_Bit_Clear: { - int i; - int bit=1; - struct lcd_display led_display; - - - if(copy_from_user(&led_display, (struct lcd_display*)arg, - sizeof(struct lcd_display))) - return -EFAULT; - - for (i=0;i<(int)led_display.leds;i++) - { - bit = 2*bit; - } - - led_state = led_state & ~bit; - LEDSet(led_state); - break; - } - - - case BUTTON_Read: { - button_display.buttons = GPIRead; - if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) - return -EFAULT; - break; - } + case LED_Bit_Clear:{ + int i; + int bit = 1; + struct lcd_display led_display; - case LINK_Check: { - button_display.buttons = *((volatile unsigned long *) (0xB0100060) ); - if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) - return -EFAULT; - break; - } - - case LINK_Check_2: { - int iface_num; - - /* panel-utils should pass in the desired interface status is wanted for - * in "buttons" of the structure. We will set this to non-zero if the - * link is in fact up for the requested interface. --DaveM - */ - if(copy_from_user(&button_display, (struct lcd_display *)arg, sizeof(button_display))) - return -EFAULT; - iface_num = button_display.buttons; -#if defined(CONFIG_TULIP) && 0 - if (iface_num >= 0 && - iface_num < MAX_INTERFACES && - linkcheck_callbacks[iface_num] != NULL) { - button_display.buttons = - linkcheck_callbacks[iface_num](linkcheck_cookies[iface_num]); - } else -#endif - button_display.buttons = 0; - - if(__copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) - return -EFAULT; - break; - } -// Erase the flash + if (copy_from_user + (&led_display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - case FLASH_Erase: { + for (i = 0; i < (int) led_display.leds; i++) { + bit = 2 * bit; + } - int ctr=0; + led_state = led_state & ~bit; + LEDSet(led_state); + break; + } - // Chip Erase Sequence - WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); - WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); - WRITE_FLASH( kFlash_Addr1, kFlash_Erase3 ); - WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); - WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); - WRITE_FLASH( kFlash_Addr1, kFlash_Erase6 ); - printk( "Erasing Flash.\n"); + case BUTTON_Read:{ + button_display.buttons = GPIRead; + if (copy_to_user + ((struct lcd_display *) arg, &button_display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } - while ( (!dqpoll(0x00000000,0xFF)) && (!timeout(0x00000000)) ) { - ctr++; + case LINK_Check:{ + button_display.buttons = + *((volatile unsigned long *) (0xB0100060)); + if (copy_to_user + ((struct lcd_display *) arg, &button_display, + sizeof(struct lcd_display))) + return -EFAULT; + break; } - printk("\n"); - printk("\n"); - printk("\n"); + case LINK_Check_2:{ + int iface_num; - if (READ_FLASH(0x07FFF0)==0xFF) { printk("Erase Successful\r\n"); } - else if (timeout) { printk("Erase Timed Out\r\n"); } + /* panel-utils should pass in the desired interface status is wanted for + * in "buttons" of the structure. We will set this to non-zero if the + * link is in fact up for the requested interface. --DaveM + */ + if (copy_from_user + (&button_display, (struct lcd_display *) arg, + sizeof(button_display))) + return -EFAULT; + iface_num = button_display.buttons; +#if defined(CONFIG_TULIP) && 0 + if (iface_num >= 0 && + iface_num < MAX_INTERFACES && + linkcheck_callbacks[iface_num] != NULL) { + button_display.buttons = + linkcheck_callbacks[iface_num] + (linkcheck_cookies[iface_num]); + } else +#endif + button_display.buttons = 0; - break; - } + if (__copy_to_user + ((struct lcd_display *) arg, &button_display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } -// burn the flash +// Erase the flash - case FLASH_Burn: { + case FLASH_Erase:{ - volatile unsigned long burn_addr; - unsigned long flags; - int i; - unsigned char *rom; - - - struct lcd_display display; - - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; - rom = (unsigned char *) kmalloc((128),GFP_ATOMIC); - if ( rom == NULL ) { - printk ("broken\n"); - return 1; - } - - printk("Churning and Burning -"); - save_flags(flags); - for (i=0; iRomImage[0]); + printk("Churning and Burning -"); + save_flags(flags); + for (i = 0; i < FLASH_SIZE; i = i + 128) { + + if (copy_from_user + (rom, display.RomImage + i, 128)) + return -EFAULT; + burn_addr = kFlashBase + i; + cli(); + for (index = 0; index < (128); index++) { + + WRITE_FLASH(kFlash_Addr1, + kFlash_Data1); + WRITE_FLASH(kFlash_Addr2, + kFlash_Data2); + WRITE_FLASH(kFlash_Addr1, + kFlash_Prog); + *((volatile unsigned char *) + burn_addr) = + (volatile unsigned char) rom[index]; + + while ((!dqpoll + (burn_addr, + (volatile unsigned char) + rom[index])) + && (!timeout(burn_addr))) { + } + burn_addr++; + } + restore_flags(flags); + if (* + ((volatile unsigned char *) (burn_addr + - 1)) == + (volatile unsigned char) rom[index - + 1]) { + } else if (timeout) { + printk("Program timed out\r\n"); + } - if(!access_ok(VERIFY_WRITE, user_bytes, FLASH_SIZE)) - return -EFAULT; - printk("Reading Flash"); - for (i=0; iRomImage[0]); + + if (!access_ok + (VERIFY_WRITE, user_bytes, FLASH_SIZE)) + return -EFAULT; + + printk("Reading Flash"); + for (i = 0; i < FLASH_SIZE; i++) { + unsigned char tmp_byte; + read_addr = kFlashBase + i; + tmp_byte = + *((volatile unsigned char *) + read_addr); + if (__put_user(tmp_byte, &user_bytes[i])) + return -EFAULT; + } + break; + } default: return 0; - break; + break; } @@ -517,7 +562,8 @@ { unsigned long buttons = GPIRead; - if ( (buttons == BUTTON_Next) || (buttons == BUTTON_Next_B) || (buttons == BUTTON_Reset_B) ) + if ((buttons == BUTTON_Next) || (buttons == BUTTON_Next_B) + || (buttons == BUTTON_Reset_B)) return buttons; return 0; } @@ -526,22 +572,23 @@ static int lcd_waiters = 0; -static long lcd_read(struct inode *inode, struct file *file, char *buf, unsigned long count) +static long lcd_read(struct inode *inode, struct file *file, char *buf, + unsigned long count) { long buttons_now; - if(lcd_waiters > 0) + if (lcd_waiters > 0) return -EINVAL; lcd_waiters++; - while(((buttons_now = (long)button_pressed()) == 0) && - !(signal_pending(current))) { + while (((buttons_now = (long) button_pressed()) == 0) && + !(signal_pending(current))) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(2 * HZ); } lcd_waiters--; - if(signal_pending(current)) + if (signal_pending(current)) return -ERESTARTSYS; return buttons_now; } @@ -551,21 +598,20 @@ */ static struct file_operations lcd_fops = { - .read = lcd_read, - .ioctl = lcd_ioctl, - .open = lcd_open, + .read = lcd_read, + .ioctl = lcd_ioctl, + .open = lcd_open, }; -static struct miscdevice lcd_dev= -{ - LCD_MINOR, +static struct miscdevice lcd_dev = { + MISC_DYNAMIC_MINOR, "lcd", &lcd_fops }; -int lcd_init(void) +static int lcd_init(void) { -unsigned long data; + unsigned long data; printk("%s\n", LCD_DRIVER); misc_register(&lcd_dev); @@ -575,19 +621,22 @@ udelay(150); data = LCDReadData; - if ( (data & 0x000000FF) == (0x00) ) { + if ((data & 0x000000FF) == (0x00)) { lcd_present = 0; printk("LCD Not Present\n"); - } - else { + } else { lcd_present = 1; - WRITE_GAL( kGal_DevBank2PReg, kGal_DevBank2Cfg ); - WRITE_GAL( kGal_DevBank3PReg, kGal_DevBank3Cfg ); - } + WRITE_GAL(kGal_DevBank2PReg, kGal_DevBank2Cfg); + WRITE_GAL(kGal_DevBank3PReg, kGal_DevBank3Cfg); + } return 0; } +static void __exit lcd_exit(void) +{ + misc_deregister(&lcd_dev); +} // // Function: dqpoll @@ -600,17 +649,15 @@ // // -int dqpoll( volatile unsigned long address, volatile unsigned char data ) { - -volatile unsigned char dq7; - -dq7 = data & 0x80; +static int dqpoll(volatile unsigned long address, volatile unsigned char data) +{ + volatile unsigned char dq7; -return ( (READ_FLASH(address) & 0x80) == dq7 ); + dq7 = data & 0x80; + return ((READ_FLASH(address) & 0x80) == dq7); } - // // Function: timeout // @@ -622,12 +669,13 @@ // // Out: 0 = not timed out, 1 = timed out -int timeout( volatile unsigned long address ) { - - -return ( (READ_FLASH(address) & 0x20) == 0x20 ); - +static int timeout(volatile unsigned long address) +{ + return (READ_FLASH(address) & 0x20) == 0x20; } +module_init(lcd_init); +module_exit(lcd_exit); - +MODULE_AUTHOR("Andrew Bose"); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/lcd.h b/drivers/char/lcd.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/char/lcd.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,184 @@ +/* + * LED, LCD and Button panel driver for Cobalt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997 by Andrew Bose + * + * Linux kernel version history: + * March 2001: Ported from 2.0.34 by Liam Davies + * + */ + +// function headers + +static int dqpoll(volatile unsigned long, volatile unsigned char ); +static int timeout(volatile unsigned long); + +#define LCD_CHARS_PER_LINE 40 +#define FLASH_SIZE 524288 +#define MAX_IDLE_TIME 120 + +struct lcd_display { + unsigned long buttons; + int size1; + int size2; + unsigned char line1[LCD_CHARS_PER_LINE]; + unsigned char line2[LCD_CHARS_PER_LINE]; + unsigned char cursor_address; + unsigned char character; + unsigned char leds; + unsigned char *RomImage; +}; + + + +#define LCD_DRIVER "Cobalt LCD Driver v2.10" + +#define kLCD_IR 0x0F000000 +#define kLCD_DR 0x0F000010 +#define kGPI 0x0D000000 +#define kLED 0x0C000000 + +#define kDD_R00 0x00 +#define kDD_R01 0x27 +#define kDD_R10 0x40 +#define kDD_R11 0x67 + +#define kLCD_Addr 0x00000080 + +#define LCDTimeoutValue 0xfff + + +// Flash definitions AMD 29F040 +#define kFlashBase 0x0FC00000 + +#define kFlash_Addr1 0x5555 +#define kFlash_Addr2 0x2AAA +#define kFlash_Data1 0xAA +#define kFlash_Data2 0x55 +#define kFlash_Prog 0xA0 +#define kFlash_Erase3 0x80 +#define kFlash_Erase6 0x10 +#define kFlash_Read 0xF0 + +#define kFlash_ID 0x90 +#define kFlash_VenAddr 0x00 +#define kFlash_DevAddr 0x01 +#define kFlash_VenID 0x01 +#define kFlash_DevID 0xA4 // 29F040 +//#define kFlash_DevID 0xAD // 29F016 + + +// Macros + +#define LCDWriteData(x) outl((x << 24), kLCD_DR) +#define LCDWriteInst(x) outl((x << 24), kLCD_IR) + +#define LCDReadData (inl(kLCD_DR) >> 24) +#define LCDReadInst (inl(kLCD_IR) >> 24) + +#define GPIRead (inl(kGPI) >> 24) + +#define LEDSet(x) outb((char)x, kLED) + +#define WRITE_GAL(x,y) outl(y, 0x04000000 | (x)) +#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80) + +#define WRITE_FLASH(x,y) outb((char)y, kFlashBase | (x)) +#define READ_FLASH(x) (inb(kFlashBase | (x))) + + + +/* + * Function command codes for io_ctl. + */ +#define LCD_On 1 +#define LCD_Off 2 +#define LCD_Clear 3 +#define LCD_Reset 4 +#define LCD_Cursor_Left 5 +#define LCD_Cursor_Right 6 +#define LCD_Disp_Left 7 +#define LCD_Disp_Right 8 +#define LCD_Get_Cursor 9 +#define LCD_Set_Cursor 10 +#define LCD_Home 11 +#define LCD_Read 12 +#define LCD_Write 13 +#define LCD_Cursor_Off 14 +#define LCD_Cursor_On 15 +#define LCD_Get_Cursor_Pos 16 +#define LCD_Set_Cursor_Pos 17 +#define LCD_Blink_Off 18 + +#define LED_Set 40 +#define LED_Bit_Set 41 +#define LED_Bit_Clear 42 + + +// Button defs +#define BUTTON_Read 50 + +// Flash command codes +#define FLASH_Erase 60 +#define FLASH_Burn 61 +#define FLASH_Read 62 + + +// Ethernet LINK check hackaroo +#define LINK_Check 90 +#define LINK_Check_2 91 + +// Button patterns _B - single layer lcd boards + +#define BUTTON_NONE 0x3F +#define BUTTON_NONE_B 0xFE + +#define BUTTON_Left 0x3B +#define BUTTON_Left_B 0xFA + +#define BUTTON_Right 0x37 +#define BUTTON_Right_B 0xDE + +#define BUTTON_Up 0x2F +#define BUTTON_Up_B 0xF6 + +#define BUTTON_Down 0x1F +#define BUTTON_Down_B 0xEE + +#define BUTTON_Next 0x3D +#define BUTTON_Next_B 0x7E + +#define BUTTON_Enter 0x3E +#define BUTTON_Enter_B 0xBE + +#define BUTTON_Reset_B 0xFC + + +// debounce constants + +#define BUTTON_SENSE 160000 +#define BUTTON_DEBOUNCE 5000 + + +// Galileo register stuff + +#define kGal_DevBank2Cfg 0x1466DB33 +#define kGal_DevBank2PReg 0x464 +#define kGal_DevBank3Cfg 0x146FDFFB +#define kGal_DevBank3PReg 0x468 + +// Network + +#define kIPADDR 1 +#define kNETMASK 2 +#define kGATEWAY 3 +#define kDNS 4 + +#define kClassA 5 +#define kClassB 6 +#define kClassC 7 + diff -Nru a/drivers/char/lp_old98.c b/drivers/char/lp_old98.c --- a/drivers/char/lp_old98.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,537 +0,0 @@ -/* - * linux/drivers/char/lp_old98.c - * - * printer port driver for ancient PC-9800s with no bidirectional port support - * - * Copyright (C) 1998,99 Kousuke Takai , - * Kyoto University Microcomputer Club - * - * This driver is based on and has compatibility with `lp.c', - * generic PC printer port driver. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -/* - * I/O port numbers - */ -#define LP_PORT_DATA 0x40 -#define LP_PORT_STATUS (LP_PORT_DATA + 2) -#define LP_PORT_STROBE (LP_PORT_DATA + 4) -#define LP_PORT_CONTROL (LP_PORT_DATA + 6) - -#define LP_PORT_H98MODE 0x0448 -#define LP_PORT_EXTMODE 0x0149 - -/* - * bit mask for I/O - */ -#define LP_MASK_nBUSY (1 << 2) -#define LP_MASK_nSTROBE (1 << 7) - -#define LP_CONTROL_ASSERT_STROBE (0x0e) -#define LP_CONTROL_NEGATE_STROBE (0x0f) - -/* - * Acceptable maximum value for non-privileged user for LPCHARS ioctl. - */ -#define LP_CHARS_NOPRIV_MAX 65535 - -#define DC1 '\x11' -#define DC3 '\x13' - -/* PC-9800s have at least and at most one old-style printer port. */ -static struct lp_struct lp = { - .flags = LP_EXIST | LP_ABORTOPEN, - .chars = LP_INIT_CHAR, - .time = LP_INIT_TIME, - .wait = LP_INIT_WAIT, -}; - -static int dc1_check; -static spinlock_t lp_old98_lock = SPIN_LOCK_UNLOCKED; - - -#undef LP_OLD98_DEBUG - -#ifdef CONFIG_PC9800_OLDLP_CONSOLE -static struct console lp_old98_console; /* defined later */ -static short saved_console_flags; -#endif - -static DECLARE_WAIT_QUEUE_HEAD (lp_old98_waitq); - -static void lp_old98_timer_function(unsigned long data) -{ - if (inb(LP_PORT_STATUS) & LP_MASK_nBUSY) - wake_up_interruptible(&lp_old98_waitq); - else { - struct timer_list *t = (struct timer_list *) data; - - t->expires = jiffies + 1; - add_timer(t); - } -} - -static inline int lp_old98_wait_ready(void) -{ - struct timer_list timer; - - init_timer(&timer); - timer.function = lp_old98_timer_function; - timer.expires = jiffies + 1; - timer.data = (unsigned long)&timer; - add_timer(&timer); - interruptible_sleep_on(&lp_old98_waitq); - del_timer(&timer); - return signal_pending(current); -} - -static inline int lp_old98_char(char lpchar) -{ - unsigned long count = 0; -#ifdef LP_STATS - int tmp; -#endif - - while (!(inb(LP_PORT_STATUS) & LP_MASK_nBUSY)) { - count++; - if (count >= lp.chars) - return 0; - } - - outb(lpchar, LP_PORT_DATA); - -#ifdef LP_STATS - /* - * Update lp statsistics here (and between next two outb()'s). - * Time to compute it is part of storobe delay. - */ - if (count > lp.stats.maxwait) { -#ifdef LP_OLD98_DEBUG - printk(KERN_DEBUG "lp_old98: success after %d counts.\n", - count); -#endif - lp.stats.maxwait = count; - } - count *= 256; - tmp = count - lp.stats.meanwait; - if (tmp < 0) - tmp = -tmp; -#endif - ndelay(lp.wait); - - /* negate PSTB# (activate strobe) */ - outb(LP_CONTROL_ASSERT_STROBE, LP_PORT_CONTROL); - -#ifdef LP_STATS - lp.stats.meanwait = (255 * lp.stats.meanwait + count + 128) / 256; - lp.stats.mdev = (127 * lp.stats.mdev + tmp + 64) / 128; - lp.stats.chars ++; -#endif - - ndelay(lp.wait); - - /* assert PSTB# (deactivate strobe) */ - outb(LP_CONTROL_NEGATE_STROBE, LP_PORT_CONTROL); - - return 1; -} - -static ssize_t lp_old98_write(struct file * file, - const char * buf, size_t count, - loff_t *dummy) -{ - unsigned long total_bytes_written = 0; - - if (!access_ok(VERIFY_READ, buf, count)) - return -EFAULT; - -#ifdef LP_STATS - if (jiffies - lp.lastcall > lp.time) - lp.runchars = 0; - lp.lastcall = jiffies; -#endif - - do { - unsigned long bytes_written = 0; - unsigned long copy_size - = (count < LP_BUFFER_SIZE ? count : LP_BUFFER_SIZE); - - if (__copy_from_user(lp.lp_buffer, buf, copy_size)) - return -EFAULT; - - while (bytes_written < copy_size) { - if (lp_old98_char(lp.lp_buffer[bytes_written])) - bytes_written ++; - else { -#ifdef LP_STATS - int rc = lp.runchars + bytes_written; - - if (rc > lp.stats.maxrun) - lp.stats.maxrun = rc; - - lp.stats.sleeps ++; -#endif -#ifdef LP_OLD98_DEBUG - printk(KERN_DEBUG - "lp_old98: sleeping at %d characters" - " for %d jiffies\n", - lp.runchars, lp.time); - lp.runchars = 0; -#endif - if (lp_old98_wait_ready()) - return ((total_bytes_written - + bytes_written) - ? : -EINTR); - } - } - total_bytes_written += bytes_written; - buf += bytes_written; -#ifdef LP_STATS - lp.runchars += bytes_written; -#endif - count -= bytes_written; - } while (count > 0); - - return total_bytes_written; -} - -static int lp_old98_open(struct inode * inode, struct file * file) -{ - if (iminor(inode) != 0) - return -ENXIO; - - if (lp.flags & LP_BUSY) - return -EBUSY; - - if (dc1_check && (lp.flags & LP_ABORTOPEN) - && !(file->f_flags & O_NONBLOCK)) { - /* - * Check whether printer is on-line. - * PC-9800's old style port have only BUSY# as status input, - * so that it is impossible to distinguish that the printer is - * ready and that the printer is off-line or not connected - * (in both case BUSY# is in the same state). So: - * - * (1) output DC1 (0x11) to printer port and do strobe. - * (2) watch BUSY# line for a while. If BUSY# is pulled - * down, the printer will be ready. Otherwise, - * it will be off-line (or not connected, or power-off, - * ...). - * - * The source of this procedure: - * Terumasa KODAKA, Kazufumi SHIMIZU, Yu HAYAMI: - * `PC-9801 Super Technique', Ascii, 1992. - */ - int count; - unsigned long flags; - - /* interrupts while check is fairly bad */ - spin_lock_irqsave(&lp_old98_lock, flags); - - if (!lp_old98_char(DC1)) { - spin_unlock_irqrestore(&lp_old98_lock, flags); - return -EBUSY; - } - count = (unsigned int)dc1_check > 10000 ? 10000 : dc1_check; - while (inb(LP_PORT_STATUS) & LP_MASK_nBUSY) { - if (--count == 0) { - spin_unlock_irqrestore(&lp_old98_lock, flags); - return -ENODEV; - } - } - spin_unlock_irqrestore(&lp_old98_lock, flags); - } - - if ((lp.lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL)) == NULL) - return -ENOMEM; - - lp.flags |= LP_BUSY; - -#ifdef CONFIG_PC9800_OLDLP_CONSOLE - saved_console_flags = lp_old98_console.flags; - lp_old98_console.flags &= ~CON_ENABLED; -#endif - return 0; -} - -static int lp_old98_release(struct inode * inode, struct file * file) -{ - kfree(lp.lp_buffer); - lp.lp_buffer = NULL; - lp.flags &= ~LP_BUSY; -#ifdef CONFIG_PC9800_OLDLP_CONSOLE - lp_old98_console.flags = saved_console_flags; -#endif - return 0; -} - -static int lp_old98_init_device(void) -{ - unsigned char data; - - if ((data = inb(LP_PORT_EXTMODE)) != 0xFF && (data & 0x10)) { - printk(KERN_INFO - "lp_old98: shutting down extended parallel port mode...\n"); - outb(data & ~0x10, LP_PORT_EXTMODE); - } -#ifdef PC98_HW_H98 - if ((pc98_hw_flags & PC98_HW_H98) - && ((data = inb(LP_PORT_H98MODE)) & 0x01)) { - printk(KERN_INFO - "lp_old98: shutting down H98 full centronics mode...\n"); - outb(data & ~0x01, LP_PORT_H98MODE); - } -#endif - return 0; -} - -static int lp_old98_ioctl(struct inode *inode, struct file *file, - unsigned int command, unsigned long arg) -{ - int retval = 0; - - switch (command) { - case LPTIME: - lp.time = arg * HZ/100; - break; - case LPCHAR: - lp.chars = arg; - break; - case LPABORT: - if (arg) - lp.flags |= LP_ABORT; - else - lp.flags &= ~LP_ABORT; - break; - case LPABORTOPEN: - if (arg) - lp.flags |= LP_ABORTOPEN; - else - lp.flags &= ~LP_ABORTOPEN; - break; - case LPCAREFUL: - /* do nothing */ - break; - case LPWAIT: - lp.wait = arg; - break; - case LPGETIRQ: - retval = put_user(0, (int *)arg); - break; - case LPGETSTATUS: - /* - * convert PC-9800's status to IBM PC's one, so that tunelp(8) - * works in the same way on this driver. - */ - retval = put_user((inb(LP_PORT_STATUS) & LP_MASK_nBUSY) - ? (LP_PBUSY | LP_PERRORP) : LP_PERRORP, - (int *)arg); - break; - case LPRESET: - retval = lp_old98_init_device(); - break; -#ifdef LP_STATS - case LPGETSTATS: - if (copy_to_user((struct lp_stats *)arg, &lp.stats, - sizeof(struct lp_stats))) - retval = -EFAULT; - else if (suser()) - memset(&lp.stats, 0, sizeof(struct lp_stats)); - break; -#endif - case LPGETFLAGS: - retval = put_user(lp.flags, (int *)arg); - break; - case LPSETIRQ: - default: - retval = -EINVAL; - } - return retval; -} - -static struct file_operations lp_old98_fops = { - .owner = THIS_MODULE, - .write = lp_old98_write, - .ioctl = lp_old98_ioctl, - .open = lp_old98_open, - .release = lp_old98_release, -}; - -/* - * Support for console on lp_old98 - */ -#ifdef CONFIG_PC9800_OLDLP_CONSOLE - -static inline void io_delay(void) -{ - unsigned char dummy; /* actually not output */ - - asm volatile ("out%B0 %0,%1" : "=a"(dummy) : "N"(0x5f)); -} - -static void lp_old98_console_write(struct console *console, - const char *s, unsigned int count) -{ - int i; - static unsigned int timeout_run = 0; - - while (count) { - /* wait approx 1.2 seconds */ - for (i = 2000000; !(inb(LP_PORT_STATUS) & LP_MASK_nBUSY); - io_delay()) - if (!--i) { - if (++timeout_run >= 10) - /* disable forever... */ - console->flags &= ~CON_ENABLED; - return; - } - - timeout_run = 0; - - if (*s == '\n') { - outb('\r', LP_PORT_DATA); - io_delay(); - io_delay(); - outb(LP_CONTROL_ASSERT_STROBE, LP_PORT_CONTROL); - io_delay(); - io_delay(); - outb(LP_CONTROL_NEGATE_STROBE, LP_PORT_CONTROL); - io_delay(); - io_delay(); - for (i = 1000000; - !(inb(LP_PORT_STATUS) & LP_MASK_nBUSY); - io_delay()) - if (!--i) - return; - } - - outb(*s++, LP_PORT_DATA); - io_delay(); - io_delay(); - outb(LP_CONTROL_ASSERT_STROBE, LP_PORT_CONTROL); - io_delay(); - io_delay(); - outb(LP_CONTROL_NEGATE_STROBE, LP_PORT_CONTROL); - io_delay(); - io_delay(); - - --count; - } -} - -static struct console lp_old98_console = { - .name = "lp_old98", - .write = lp_old98_console_write, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -#endif /* console on lp_old98 */ - -static int __init lp_old98_init(void) -{ - char *errmsg = "I/O ports already occupied, giving up."; - -#ifdef PC98_HW_H98 - if (pc98_hw_flags & PC98_HW_H98) - if (!request_region(LP_PORT_H98MODE, 1, "lp_old98") - goto err1; -#endif - if (!request_region(LP_PORT_DATA, 1, "lp_old98")) - goto err2; - if (!request_region(LP_PORT_STATUS, 1, "lp_old98")) - goto err3; - if (!request_region(LP_PORT_STROBE, 1, "lp_old98")) - goto err4; - if (!request_region(LP_PORT_EXTMODE, 1, "lp_old98")) - goto err5; - if (!register_chrdev(LP_MAJOR, "lp", &lp_old98_fops)) { -#ifdef CONFIG_PC9800_OLDLP_CONSOLE - register_console(&lp_old98_console); - printk(KERN_INFO "lp_old98: console ready\n"); -#endif - /* - * rest are not needed by this driver, - * but for locking out other printer drivers... - */ - lp_old98_init_device(); - return 0; - } else - errmsg = "unable to register device"; - - release_region(LP_PORT_EXTMODE, 1); -err5: - release_region(LP_PORT_STROBE, 1); -err4: - release_region(LP_PORT_STATUS, 1); -err3: - release_region(LP_PORT_DATA, 1); -err2: -#ifdef PC98_HW_H98 - if (pc98_hw_flags & PC98_HW_H98) - release_region(LP_PORT_H98MODE, 1); - -err1: -#endif - printk(KERN_ERR "lp_old98: %s\n", errmsg); - return -EBUSY; -} - -static void __exit lp_old98_exit(void) -{ -#ifdef CONFIG_PC9800_OLDLP_CONSOLE - unregister_console(&lp_old98_console); -#endif - unregister_chrdev(LP_MAJOR, "lp"); - - release_region(LP_PORT_DATA, 1); - release_region(LP_PORT_STATUS, 1); - release_region(LP_PORT_STROBE, 1); -#ifdef PC98_HW_H98 - if (pc98_hw_flags & PC98_HW_H98) - release_region(LP_PORT_H98MODE, 1); -#endif - release_region(LP_PORT_EXTMODE, 1); -} - -#ifndef MODULE -static int __init lp_old98_setup(char *str) -{ - int ints[4]; - - str = get_options(str, ARRAY_SIZE(ints), ints); - if (ints[0] > 0) - dc1_check = ints[1]; - return 1; -} -__setup("lp_old98_dc1_check=", lp_old98_setup); -#endif - -MODULE_PARM(dc1_check, "i"); -MODULE_AUTHOR("Kousuke Takai "); -MODULE_DESCRIPTION("PC-9800 old printer port driver"); -MODULE_LICENSE("GPL"); - -module_init(lp_old98_init); -module_exit(lp_old98_exit); diff -Nru a/drivers/char/mem.c b/drivers/char/mem.c --- a/drivers/char/mem.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/mem.c 2004-06-26 17:09:18 -07:00 @@ -26,7 +26,6 @@ #include #include -#include #ifdef CONFIG_IA64 # include diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c --- a/drivers/char/misc.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/misc.c 2004-06-26 17:09:20 -07:00 @@ -63,13 +63,8 @@ #define DYNAMIC_MINORS 64 /* like dynamic majors */ static unsigned char misc_minors[DYNAMIC_MINORS / 8]; -#ifdef CONFIG_SGI_NEWPORT_GFX -extern void gfx_register(void); -#endif -extern void streamable_init(void); extern int rtc_DP8570A_init(void); extern int rtc_MK48T08_init(void); -extern int ds1286_init(void); extern int pmu_device_init(void); extern int tosh_init(void); extern int i8k_init(void); @@ -318,20 +313,8 @@ #ifdef CONFIG_BVME6000 rtc_DP8570A_init(); #endif -#ifdef CONFIG_SGI_DS1286 - ds1286_init(); -#endif #ifdef CONFIG_PMAC_PBOOK pmu_device_init(); -#endif -#ifdef CONFIG_SGI_NEWPORT_GFX - gfx_register (); -#endif -#ifdef CONFIG_SGI_IP22 - streamable_init (); -#endif -#ifdef CONFIG_SGI_NEWPORT_GFX - gfx_register (); #endif #ifdef CONFIG_TOSHIBA tosh_init(); diff -Nru a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c --- a/drivers/char/mwave/3780i.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/mwave/3780i.c 2004-06-26 17:09:20 -07:00 @@ -467,10 +467,10 @@ } -int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr) { - unsigned short *pusBuffer = pvBuffer; + unsigned short __user *pusBuffer = pvBuffer; unsigned short val; @@ -508,10 +508,10 @@ } int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, - void *pvBuffer, unsigned uCount, + void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr) { - unsigned short *pusBuffer = pvBuffer; + unsigned short __user *pusBuffer = pvBuffer; unsigned short val; @@ -549,10 +549,10 @@ } -int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr) { - unsigned short *pusBuffer = pvBuffer; + unsigned short __user *pusBuffer = pvBuffer; PRINTK_5(TRACE_3780I, @@ -590,10 +590,10 @@ } -int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr) { - unsigned short *pusBuffer = pvBuffer; + unsigned short __user *pusBuffer = pvBuffer; PRINTK_5(TRACE_3780I, "3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", @@ -637,10 +637,10 @@ } -int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr) { - unsigned short *pusBuffer = pvBuffer; + unsigned short __user *pusBuffer = pvBuffer; PRINTK_5(TRACE_3780I, "3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", diff -Nru a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h --- a/drivers/char/mwave/3780i.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/mwave/3780i.h 2004-06-26 17:09:18 -07:00 @@ -323,16 +323,16 @@ int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings); int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings); int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings); -int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr); int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, - void *pvBuffer, unsigned uCount, + void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr); -int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr); -int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr); -int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer, +int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr); unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, unsigned long ulMsaAddr); diff -Nru a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c --- a/drivers/char/mwave/mwavedd.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/mwave/mwavedd.c 2004-06-26 17:09:16 -07:00 @@ -121,6 +121,7 @@ { unsigned int retval = 0; pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; + void __user *arg = (void __user *)ioarg; PRINTK_5(TRACE_MWAVE, "mwavedd::mwave_ioctl, entry inode %x file %x cmd %x arg %x\n", @@ -164,8 +165,7 @@ " retval %x from tp3780I_QueryAbilities\n", retval); if (retval == 0) { - if( copy_to_user((char *) ioarg, - (char *) &rAbilities, + if( copy_to_user(arg, &rAbilities, sizeof(MW_ABILITIES)) ) return -EFAULT; } @@ -179,13 +179,12 @@ case IOCTL_MW_READ_DATA: case IOCTL_MW_READCLEAR_DATA: { MW_READWRITE rReadData; - unsigned short *pusBuffer = 0; + unsigned short __user *pusBuffer = 0; - if( copy_from_user((char *) &rReadData, - (char *) ioarg, + if( copy_from_user(&rReadData, arg, sizeof(MW_READWRITE)) ) return -EFAULT; - pusBuffer = (unsigned short *) (rReadData.pBuf); + pusBuffer = (unsigned short __user *) (rReadData.pBuf); PRINTK_4(TRACE_MWAVE, "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA," @@ -193,7 +192,7 @@ rReadData.ulDataLength, ioarg, pusBuffer); retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd, - (void *) pusBuffer, + pusBuffer, rReadData.ulDataLength, rReadData.usDspAddress); } @@ -201,12 +200,12 @@ case IOCTL_MW_READ_INST: { MW_READWRITE rReadData; - unsigned short *pusBuffer = 0; + unsigned short __user *pusBuffer = 0; - if( copy_from_user((char *) &rReadData, (char *) ioarg, + if( copy_from_user(&rReadData, arg, sizeof(MW_READWRITE)) ) return -EFAULT; - pusBuffer = (unsigned short *) (rReadData.pBuf); + pusBuffer = (unsigned short __user *) (rReadData.pBuf); PRINTK_4(TRACE_MWAVE, "mwavedd::mwave_ioctl IOCTL_MW_READ_INST," @@ -222,13 +221,12 @@ case IOCTL_MW_WRITE_DATA: { MW_READWRITE rWriteData; - unsigned short *pusBuffer = 0; + unsigned short __user *pusBuffer = 0; - if( copy_from_user((char *) &rWriteData, - (char *) ioarg, + if( copy_from_user(&rWriteData, arg, sizeof(MW_READWRITE)) ) return -EFAULT; - pusBuffer = (unsigned short *) (rWriteData.pBuf); + pusBuffer = (unsigned short __user *) (rWriteData.pBuf); PRINTK_4(TRACE_MWAVE, "mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA," @@ -244,13 +242,12 @@ case IOCTL_MW_WRITE_INST: { MW_READWRITE rWriteData; - unsigned short *pusBuffer = 0; + unsigned short __user *pusBuffer = 0; - if( copy_from_user((char *) &rWriteData, - (char *) ioarg, + if( copy_from_user(&rWriteData, arg, sizeof(MW_READWRITE)) ) return -EFAULT; - pusBuffer = (unsigned short *) (rWriteData.pBuf); + pusBuffer = (unsigned short __user *)(rWriteData.pBuf); PRINTK_4(TRACE_MWAVE, "mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST," @@ -388,7 +385,7 @@ } -static ssize_t mwave_read(struct file *file, char *buf, size_t count, +static ssize_t mwave_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) { PRINTK_5(TRACE_MWAVE, @@ -399,7 +396,7 @@ } -static ssize_t mwave_write(struct file *file, const char *buf, +static ssize_t mwave_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { PRINTK_5(TRACE_MWAVE, diff -Nru a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c --- a/drivers/char/mwave/tp3780i.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/char/mwave/tp3780i.c 2004-06-26 17:09:15 -07:00 @@ -522,7 +522,7 @@ } int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, - void *pvBuffer, unsigned int uCount, + void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr) { int retval = 0; @@ -558,7 +558,7 @@ int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, - void *pvBuffer, unsigned int uCount, + void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr) { int retval = 0; diff -Nru a/drivers/char/mwave/tp3780i.h b/drivers/char/mwave/tp3780i.h --- a/drivers/char/mwave/tp3780i.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/mwave/tp3780i.h 2004-06-26 17:09:16 -07:00 @@ -93,10 +93,10 @@ int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities); int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData); int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, - void *pvBuffer, unsigned int uCount, + void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr); int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, - void *pvBuffer, unsigned int uCount, + void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr); diff -Nru a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c --- a/drivers/char/n_hdlc.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/n_hdlc.c 2004-06-26 17:09:16 -07:00 @@ -182,9 +182,9 @@ /* TTY callbacks */ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, - __u8 *buf, size_t nr); + __u8 __user *buf, size_t nr); static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, - const __u8 *buf, size_t nr); + const __u8 __user *buf, size_t nr); static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, @@ -572,7 +572,7 @@ * Returns the number of bytes returned or error code. */ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, - __u8 *buf, size_t nr) + __u8 __user *buf, size_t nr) { struct n_hdlc *n_hdlc = tty2n_hdlc(tty); int error; @@ -649,7 +649,7 @@ * Returns the number of bytes written (or error code). */ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, - const __u8 *data, size_t count) + const __u8 __user *data, size_t count) { struct n_hdlc *n_hdlc = tty2n_hdlc (tty); int error = 0; @@ -755,7 +755,7 @@ else count = 0; spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags); - error = put_user(count, (int *)arg); + error = put_user(count, (int __user *)arg); break; case TIOCOUTQ: @@ -767,7 +767,7 @@ if (n_hdlc->tx_buf_list.head) count += n_hdlc->tx_buf_list.head->count; spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags); - error = put_user(count, (int*)arg); + error = put_user(count, (int __user *)arg); break; default: diff -Nru a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c --- a/drivers/char/n_r3964.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/n_r3964.c 2004-06-26 17:09:20 -07:00 @@ -126,7 +126,7 @@ static void receive_error(struct r3964_info *pInfo, const char flag); static void on_timeout(unsigned long priv); static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg); -static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char *buf); +static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf); static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, int error_code, struct r3964_block_header *pBlock); static struct r3964_message* remove_msg(struct r3964_info *pInfo, @@ -137,9 +137,9 @@ static int r3964_open(struct tty_struct *tty); static void r3964_close(struct tty_struct *tty); static ssize_t r3964_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t nr); + unsigned char __user *buf, size_t nr); static ssize_t r3964_write(struct tty_struct * tty, struct file * file, - const unsigned char * buf, size_t nr); + const unsigned char __user * buf, size_t nr); static int r3964_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg); static void r3964_set_termios(struct tty_struct *tty, struct termios * old); @@ -910,7 +910,7 @@ return 0; } -static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char *buf) +static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf) { struct r3964_client_info *pClient; struct r3964_block_header *block; @@ -1185,7 +1185,7 @@ } static ssize_t r3964_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t nr) + unsigned char __user *buf, size_t nr) { struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; struct r3964_client_info *pClient; @@ -1246,7 +1246,7 @@ } static ssize_t r3964_write(struct tty_struct * tty, struct file * file, - const unsigned char *data, size_t count) + const unsigned char __user *data, size_t count) { struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; struct r3964_block_header *pHeader; @@ -1348,7 +1348,7 @@ pInfo->flags &= ~R3964_BCC; return 0; case R3964_READ_TELEGRAM: - return read_telegram(pInfo, current->pid, (unsigned char *)arg); + return read_telegram(pInfo, current->pid, (unsigned char __user *)arg); default: return -ENOIOCTLCMD; } diff -Nru a/drivers/char/raw.c b/drivers/char/raw.c --- a/drivers/char/raw.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/raw.c 2004-06-26 17:09:18 -07:00 @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -26,6 +27,7 @@ int inuse; }; +static struct class_simple *raw_class; static struct raw_device_data raw_devices[MAX_RAW_MINORS]; static DECLARE_MUTEX(raw_mutex); static struct file_operations raw_ctl_fops; /* forward declaration */ @@ -123,6 +125,13 @@ return ioctl_by_bdev(bdev, command, arg); } +static void bind_device(struct raw_config_request rq) +{ + class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor)); + class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq.raw_minor), + NULL, "raw%d", rq.raw_minor); +} + /* * Deal with ioctls against the raw-device control interface, to bind * and unbind other raw devices. @@ -191,12 +200,15 @@ if (rq.block_major == 0 && rq.block_minor == 0) { /* unbind */ rawdev->binding = NULL; + class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor)); } else { rawdev->binding = bdget(dev); if (rawdev->binding == NULL) err = -ENOMEM; - else + else { __module_get(THIS_MODULE); + bind_device(rq); + } } up(&raw_mutex); } else { @@ -287,6 +299,15 @@ goto error; } + raw_class = class_simple_create(THIS_MODULE, "raw"); + if (IS_ERR(raw_class)) { + printk(KERN_ERR "Error creating raw class.\n"); + cdev_del(&raw_cdev); + unregister_chrdev_region(dev, MAX_RAW_MINORS); + goto error; + } + class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); + devfs_mk_cdev(MKDEV(RAW_MAJOR, 0), S_IFCHR | S_IRUGO | S_IWUGO, "raw/rawctl"); @@ -309,6 +330,8 @@ devfs_remove("raw/raw%d", i); devfs_remove("raw/rawctl"); devfs_remove("raw"); + class_simple_device_remove(MKDEV(RAW_MAJOR, 0)); + class_simple_destroy(raw_class); cdev_del(&raw_cdev); unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); } diff -Nru a/drivers/char/rocket.c b/drivers/char/rocket.c --- a/drivers/char/rocket.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/rocket.c 2004-06-26 17:09:19 -07:00 @@ -1258,7 +1258,7 @@ return 0; } -static int get_config(struct r_port *info, struct rocket_config *retinfo) +static int get_config(struct r_port *info, struct rocket_config __user *retinfo) { struct rocket_config tmp; @@ -1276,7 +1276,7 @@ return 0; } -static int set_config(struct r_port *info, struct rocket_config *new_info) +static int set_config(struct r_port *info, struct rocket_config __user *new_info) { struct rocket_config new_serial; @@ -1319,7 +1319,7 @@ * to user space. See setrocket.c where the info is used to create * the /dev/ttyRx ports. */ -static int get_ports(struct r_port *info, struct rocket_ports *retports) +static int get_ports(struct r_port *info, struct rocket_ports __user *retports) { struct rocket_ports tmp; int board; @@ -1341,11 +1341,11 @@ return 0; } -static int reset_rm2(struct r_port *info, unsigned long arg) +static int reset_rm2(struct r_port *info, void __user *arg) { int reset; - if (copy_from_user(&reset, (void *) arg, sizeof (int))) + if (copy_from_user(&reset, arg, sizeof (int))) return -EFAULT; if (reset) reset = 1; @@ -1362,7 +1362,7 @@ return 0; } -static int get_version(struct r_port *info, struct rocket_version *retvers) +static int get_version(struct r_port *info, struct rocket_version __user *retvers) { if (copy_to_user(retvers, &driver_version, sizeof (*retvers))) return -EFAULT; @@ -1374,25 +1374,26 @@ unsigned int cmd, unsigned long arg) { struct r_port *info = (struct r_port *) tty->driver_data; + void __user *argp = (void __user *)arg; if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) return -ENXIO; switch (cmd) { case RCKP_GET_STRUCT: - if (copy_to_user((void *) arg, info, sizeof (struct r_port))) + if (copy_to_user(argp, info, sizeof (struct r_port))) return -EFAULT; return 0; case RCKP_GET_CONFIG: - return get_config(info, (struct rocket_config *) arg); + return get_config(info, argp); case RCKP_SET_CONFIG: - return set_config(info, (struct rocket_config *) arg); + return set_config(info, argp); case RCKP_GET_PORTS: - return get_ports(info, (struct rocket_ports *) arg); + return get_ports(info, argp); case RCKP_RESET_RM2: - return reset_rm2(info, arg); + return reset_rm2(info, argp); case RCKP_GET_VERSION: - return get_version(info, (struct rocket_version *) arg); + return get_version(info, argp); default: return -ENOIOCTLCMD; } diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c --- a/drivers/char/rtc.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/char/rtc.c 2004-06-26 17:09:21 -07:00 @@ -97,6 +97,11 @@ static int rtc_irq = PCI_IRQ_NONE; #endif +#ifdef CONFIG_HPET_RTC_IRQ +#undef RTC_IRQ +#define RTC_IRQ 0 +#endif + #ifdef RTC_IRQ static int rtc_has_irq = 1; #endif diff -Nru a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c --- a/drivers/char/synclinkmp.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/synclinkmp.c 2004-06-26 17:09:16 -07:00 @@ -567,17 +567,17 @@ /* ioctl handlers */ -static int get_stats(SLMP_INFO *info, struct mgsl_icount *user_icount); -static int get_params(SLMP_INFO *info, MGSL_PARAMS *params); -static int set_params(SLMP_INFO *info, MGSL_PARAMS *params); -static int get_txidle(SLMP_INFO *info, int*idle_mode); +static int get_stats(SLMP_INFO *info, struct mgsl_icount __user *user_icount); +static int get_params(SLMP_INFO *info, MGSL_PARAMS __user *params); +static int set_params(SLMP_INFO *info, MGSL_PARAMS __user *params); +static int get_txidle(SLMP_INFO *info, int __user *idle_mode); static int set_txidle(SLMP_INFO *info, int idle_mode); static int tx_enable(SLMP_INFO *info, int enable); static int tx_abort(SLMP_INFO *info); static int rx_enable(SLMP_INFO *info, int enable); static int map_status(int signals); static int modem_input_wait(SLMP_INFO *info,int arg); -static int wait_mgsl_event(SLMP_INFO *info, int *mask_ptr); +static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); static int tiocmget(struct tty_struct *tty, struct file *file); static int tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); @@ -692,7 +692,7 @@ * This allows remote debugging of dynamically loadable modules. */ static void* synclinkmp_get_text_ptr(void); -static void* synclinkmp_get_text_ptr() {return synclinkmp_get_text_ptr;} +static void* synclinkmp_get_text_ptr(void) {return synclinkmp_get_text_ptr;} static inline int sanity_check(SLMP_INFO *info, char *name, const char *routine) @@ -1333,8 +1333,9 @@ SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; int error; struct mgsl_icount cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ + struct serial_icounter_struct __user *p_cuser; /* user space */ unsigned long flags; + void __user *argp = (void __user *)arg; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):%s ioctl() cmd=%08X\n", __FILE__,__LINE__, @@ -1351,23 +1352,23 @@ switch (cmd) { case MGSL_IOCGPARAMS: - return get_params(info,(MGSL_PARAMS *)arg); + return get_params(info, argp); case MGSL_IOCSPARAMS: - return set_params(info,(MGSL_PARAMS *)arg); + return set_params(info, argp); case MGSL_IOCGTXIDLE: - return get_txidle(info,(int*)arg); + return get_txidle(info, argp); case MGSL_IOCSTXIDLE: - return set_txidle(info,(int)arg); + return set_txidle(info, (int)arg); case MGSL_IOCTXENABLE: - return tx_enable(info,(int)arg); + return tx_enable(info, (int)arg); case MGSL_IOCRXENABLE: - return rx_enable(info,(int)arg); + return rx_enable(info, (int)arg); case MGSL_IOCTXABORT: return tx_abort(info); case MGSL_IOCGSTATS: - return get_stats(info,(struct mgsl_icount*)arg); + return get_stats(info, argp); case MGSL_IOCWAITEVENT: - return wait_mgsl_event(info,(int*)arg); + return wait_mgsl_event(info, argp); case MGSL_IOCLOOPTXDONE: return 0; // TODO: Not supported, need to document /* Wait for modem input (DCD,RI,DSR,CTS) change @@ -1386,7 +1387,7 @@ spin_lock_irqsave(&info->lock,flags); cnow = info->icount; spin_unlock_irqrestore(&info->lock,flags); - p_cuser = (struct serial_icounter_struct *) arg; + p_cuser = argp; PUT_USER(error,cnow.cts, &p_cuser->cts); if (error) return error; PUT_USER(error,cnow.dsr, &p_cuser->dsr); @@ -2762,7 +2763,7 @@ program_hw(info); } -static int get_stats(SLMP_INFO * info, struct mgsl_icount *user_icount) +static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount) { int err; @@ -2781,7 +2782,7 @@ return 0; } -static int get_params(SLMP_INFO * info, MGSL_PARAMS *user_params) +static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params) { int err; if (debug_level >= DEBUG_LEVEL_INFO) @@ -2799,7 +2800,7 @@ return 0; } -static int set_params(SLMP_INFO * info, MGSL_PARAMS *new_params) +static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params) { unsigned long flags; MGSL_PARAMS tmp_params; @@ -2825,7 +2826,7 @@ return 0; } -static int get_txidle(SLMP_INFO * info, int*idle_mode) +static int get_txidle(SLMP_INFO * info, int __user *idle_mode) { int err; @@ -2938,7 +2939,7 @@ /* wait for specified event to occur */ -static int wait_mgsl_event(SLMP_INFO * info, int * mask_ptr) +static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr) { unsigned long flags; int s; diff -Nru a/drivers/char/tipar.c b/drivers/char/tipar.c --- a/drivers/char/tipar.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/tipar.c 2004-06-26 17:09:19 -07:00 @@ -279,7 +279,7 @@ } static ssize_t -tipar_write(struct file *file, const char *buf, size_t count, loff_t * ppos) +tipar_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR; ssize_t n; @@ -306,7 +306,7 @@ } static ssize_t -tipar_read(struct file *file, char *buf, size_t count, loff_t * ppos) +tipar_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) { int b = 0; unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR; @@ -328,7 +328,7 @@ retval = -ETIMEDOUT; goto out; } else { - if (put_user(b, ((unsigned char *) buf) + n)) { + if (put_user(b, buf + n)) { retval = -EFAULT; break; } else diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c --- a/drivers/char/tty_io.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/tty_io.c 2004-06-26 17:09:18 -07:00 @@ -91,6 +91,7 @@ #include #include #include +#include #include #include @@ -128,6 +129,8 @@ #ifdef CONFIG_UNIX98_PTYS extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ extern int pty_limit; /* Config limit on Unix98 ptys */ +static DEFINE_IDR(allocated_ptys); +static DECLARE_MUTEX(allocated_ptys_lock); #endif extern void disable_early_printk(void); @@ -1065,6 +1068,7 @@ { struct tty_struct *tty, *o_tty; int pty_master, tty_closing, o_tty_closing, do_sleep; + int devpts_master; int idx; char buf[64]; @@ -1079,6 +1083,7 @@ idx = tty->index; pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER); + devpts_master = pty_master && (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM); o_tty = tty->link; #ifdef TTY_PARANOIA_CHECK @@ -1295,11 +1300,21 @@ o_tty->ldisc = ldiscs[N_TTY]; } - /* + /* * The release_mem function takes care of the details of clearing * the slots and preserving the termios structure. */ release_mem(tty, idx); + +#ifdef CONFIG_UNIX98_PTYS + /* Make this pty number available for reallocation */ + if (devpts_master) { + down(&allocated_ptys_lock); + idr_remove(&allocated_ptys, idx); + up(&allocated_ptys_lock); + } +#endif + } /* @@ -1322,8 +1337,12 @@ int index; dev_t device = inode->i_rdev; unsigned short saved_flags = filp->f_flags; + retry_open: noctty = filp->f_flags & O_NOCTTY; + index = -1; + retval = 0; + if (device == MKDEV(TTYAUX_MAJOR,0)) { if (!current->signal->tty) return -ENXIO; @@ -1361,24 +1380,40 @@ #ifdef CONFIG_UNIX98_PTYS if (device == MKDEV(TTYAUX_MAJOR,2)) { + int idr_ret; + /* find a device that is not in use. */ - static int next_ptmx_dev = 0; - retval = -1; + down(&allocated_ptys_lock); + if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) { + up(&allocated_ptys_lock); + return -ENOMEM; + } + idr_ret = idr_get_new(&allocated_ptys, NULL, &index); + if (idr_ret < 0) { + up(&allocated_ptys_lock); + if (idr_ret == -EAGAIN) + return -ENOMEM; + return -EIO; + } + if (index >= pty_limit) { + idr_remove(&allocated_ptys, index); + up(&allocated_ptys_lock); + return -EIO; + } + up(&allocated_ptys_lock); + driver = ptm_driver; - while (driver->refcount < pty_limit) { - index = next_ptmx_dev; - next_ptmx_dev = (next_ptmx_dev+1) % driver->num; - if (!init_dev(driver, index, &tty)) - goto ptmx_found; /* ok! */ + retval = init_dev(driver, index, &tty); + if (retval) { + down(&allocated_ptys_lock); + idr_remove(&allocated_ptys, index); + up(&allocated_ptys_lock); + return retval; } - return -EIO; /* no free ptys */ - ptmx_found: + set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ - if (devpts_pty_new(tty->link)) { - /* BADNESS - need to destroy both ptm and pts! */ - return -ENOMEM; - } - noctty = 1; + if (devpts_pty_new(tty->link)) + retval = -ENOMEM; } else #endif { @@ -1400,10 +1435,12 @@ #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "opening %s...", tty->name); #endif - if (tty->driver->open) - retval = tty->driver->open(tty, filp); - else - retval = -ENODEV; + if (!retval) { + if (tty->driver->open) + retval = tty->driver->open(tty, filp); + else + retval = -ENODEV; + } filp->f_flags = saved_flags; if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) @@ -1413,6 +1450,14 @@ #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "error %d in opening %s...", retval, tty->name); +#endif + +#ifdef CONFIG_UNIX98_PTYS + if (index != -1) { + down(&allocated_ptys_lock); + idr_remove(&allocated_ptys, index); + up(&allocated_ptys_lock); + } #endif release_dev(filp); diff -Nru a/drivers/char/upd4990a.c b/drivers/char/upd4990a.c --- a/drivers/char/upd4990a.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,432 +0,0 @@ -/* - * NEC PC-9800 Real Time Clock interface for Linux - * - * Copyright (C) 1997-2001 Linux/98 project, - * Kyoto University Microcomputer Club. - * - * Based on: - * drivers/char/rtc.c by Paul Gortmaker - * - * Changes: - * 2001-02-09 Call check_region on rtc_init and do not request I/O 0033h. - * Call del_timer and release_region on rtc_exit. -- tak - * 2001-07-14 Rewrite and split to - * and . - * Introduce a lot of spin_lock/unlock (&rtc_lock). - */ - -#define RTC98_VERSION "1.2" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * We sponge a minor off of the misc major. No need slurping - * up another valuable major dev number for this. If you add - * an ioctl, make sure you don't conflict with SPARC's RTC - * ioctls. - */ - -static struct fasync_struct *rtc_async_queue; - -static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); - -static struct timer_list rtc_uie_timer; -static u8 old_refclk; - -static int rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -/* - * Bits in rtc_status. (5 bits of room for future expansion) - */ - -#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ -#define RTC_TIMER_ON 0x02 /* not used */ -#define RTC_UIE_TIMER_ON 0x04 /* UIE emulation timer is active */ - -/* - * rtc_status is never changed by rtc_interrupt, and ioctl/open/close is - * protected by the big kernel lock. However, ioctl can still disable the timer - * in rtc_status and then with del_timer after the interrupt has read - * rtc_status but before mod_timer is called, which would then reenable the - * timer (but you would need to have an awful timing before you'd trip on it) - */ -static unsigned char rtc_status; /* bitmapped status byte. */ -static unsigned long rtc_irq_data; /* our output to the world */ - -static const unsigned char days_in_mo[] = -{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -extern spinlock_t rtc_lock; /* defined in arch/i386/kernel/time.c */ - -static void rtc_uie_intr(unsigned long data) -{ - u8 refclk, tmp; - - /* Kernel timer does del_timer internally before calling - each timer entry, so this is unnecessary. - del_timer(&rtc_uie_timer); */ - spin_lock(&rtc_lock); - - /* Detect rising edge of 1Hz reference clock. */ - refclk = UPD4990A_READ_DATA(); - tmp = old_refclk & refclk; - old_refclk = ~refclk; - if (!(tmp & 1)) - rtc_irq_data += 0x100; - - spin_unlock(&rtc_lock); - - if (!(tmp & 1)) { - /* Now do the rest of the actions */ - wake_up_interruptible(&rtc_wait); - kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); - } - - rtc_uie_timer.expires = jiffies + 1; - add_timer(&rtc_uie_timer); -} - -/* - * Now all the various file operations that we export. - */ - -static ssize_t rtc_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - DECLARE_WAITQUEUE(wait, current); - unsigned long data; - ssize_t retval = 0; - - if (count < sizeof(unsigned long)) - return -EINVAL; - - add_wait_queue(&rtc_wait, &wait); - - set_current_state(TASK_INTERRUPTIBLE); - - do { - /* First make it right. Then make it fast. Putting this whole - * block within the parentheses of a while would be too - * confusing. And no, xchg() is not the answer. */ - spin_lock_irq(&rtc_lock); - data = rtc_irq_data; - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - - if (data != 0) - break; - if (file->f_flags & O_NONBLOCK) { - retval = -EAGAIN; - goto out; - } - if (signal_pending(current)) { - retval = -ERESTARTSYS; - goto out; - } - schedule(); - } while (1); - - retval = put_user(data, (unsigned long *)buf); - if (!retval) - retval = sizeof(unsigned long); - out: - set_current_state(TASK_RUNNING); - remove_wait_queue(&rtc_wait, &wait); - - return retval; -} - -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct rtc_time wtime; - struct upd4990a_raw_data raw; - - switch (cmd) { - case RTC_UIE_OFF: /* Mask ints from RTC updates. */ - spin_lock_irq(&rtc_lock); - if (rtc_status & RTC_UIE_TIMER_ON) { - rtc_status &= ~RTC_UIE_TIMER_ON; - del_timer(&rtc_uie_timer); - } - spin_unlock_irq(&rtc_lock); - return 0; - - case RTC_UIE_ON: /* Allow ints for RTC updates. */ - spin_lock_irq(&rtc_lock); - rtc_irq_data = 0; - if (!(rtc_status & RTC_UIE_TIMER_ON)) { - rtc_status |= RTC_UIE_TIMER_ON; - rtc_uie_timer.expires = jiffies + 1; - add_timer(&rtc_uie_timer); - } - /* Just in case... */ - upd4990a_serial_command(UPD4990A_REGISTER_HOLD); - old_refclk = ~UPD4990A_READ_DATA(); - spin_unlock_irq(&rtc_lock); - return 0; - - case RTC_RD_TIME: /* Read the time/date from RTC */ - spin_lock_irq(&rtc_lock); - upd4990a_get_time(&raw, 0); - spin_unlock_irq(&rtc_lock); - - wtime.tm_sec = BCD2BIN(raw.sec); - wtime.tm_min = BCD2BIN(raw.min); - wtime.tm_hour = BCD2BIN(raw.hour); - wtime.tm_mday = BCD2BIN(raw.mday); - wtime.tm_mon = raw.mon - 1; /* convert to 0-base */ - wtime.tm_wday = raw.wday; - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if ((wtime.tm_year = BCD2BIN(raw.year)) < 95) - wtime.tm_year += 100; - - wtime.tm_isdst = 0; - break; - - case RTC_SET_TIME: /* Set the RTC */ - { - int leap_yr; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&wtime, (struct rtc_time *) arg, - sizeof (struct rtc_time))) - return -EFAULT; - - /* Valid year is 1995 - 2094, inclusive. */ - if (wtime.tm_year < 95 || wtime.tm_year > 194) - return -EINVAL; - - if (wtime.tm_mon > 11 || wtime.tm_mday == 0) - return -EINVAL; - - /* For acceptable year domain (1995 - 2094), - this IS sufficient. */ - leap_yr = !(wtime.tm_year % 4); - - if (wtime.tm_mday > (days_in_mo[wtime.tm_mon] - + (wtime.tm_mon == 2 && leap_yr))) - return -EINVAL; - - if (wtime.tm_hour >= 24 - || wtime.tm_min >= 60 || wtime.tm_sec >= 60) - return -EINVAL; - - if (wtime.tm_wday > 6) - return -EINVAL; - - raw.sec = BIN2BCD(wtime.tm_sec); - raw.min = BIN2BCD(wtime.tm_min); - raw.hour = BIN2BCD(wtime.tm_hour); - raw.mday = BIN2BCD(wtime.tm_mday); - raw.mon = wtime.tm_mon + 1; - raw.wday = wtime.tm_wday; - raw.year = BIN2BCD(wtime.tm_year % 100); - - spin_lock_irq(&rtc_lock); - upd4990a_set_time(&raw, 0); - spin_unlock_irq(&rtc_lock); - - return 0; - } - default: - return -EINVAL; - } - return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; -} - -/* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. - */ - -static int rtc_open(struct inode *inode, struct file *file) -{ - spin_lock_irq(&rtc_lock); - - if(rtc_status & RTC_IS_OPEN) - goto out_busy; - - rtc_status |= RTC_IS_OPEN; - - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - return 0; - - out_busy: - spin_unlock_irq(&rtc_lock); - return -EBUSY; -} - -static int rtc_fasync(int fd, struct file *filp, int on) -{ - return fasync_helper(fd, filp, on, &rtc_async_queue); -} - -static int rtc_release(struct inode *inode, struct file *file) -{ - del_timer(&rtc_uie_timer); - - if (file->f_flags & FASYNC) - rtc_fasync(-1, file, 0); - - rtc_irq_data = 0; - - /* No need for locking -- nobody else can do anything until this rmw is - * committed, and no timer is running. */ - rtc_status &= ~(RTC_IS_OPEN | RTC_UIE_TIMER_ON); - return 0; -} - -static unsigned int rtc_poll(struct file *file, poll_table *wait) -{ - unsigned long l; - - poll_wait(file, &rtc_wait, wait); - - spin_lock_irq(&rtc_lock); - l = rtc_irq_data; - spin_unlock_irq(&rtc_lock); - - if (l != 0) - return POLLIN | POLLRDNORM; - return 0; -} - -/* - * The various file operations we support. - */ - -static struct file_operations rtc_fops = { - .owner = THIS_MODULE, - .read = rtc_read, - .poll = rtc_poll, - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, - .fasync = rtc_fasync, -}; - -static struct miscdevice rtc_dev= -{ - .minor = RTC_MINOR, - .name = "rtc", - .fops = &rtc_fops, -}; - -static int __init rtc_init(void) -{ - int err = 0; - - if (!request_region(UPD4990A_IO, 1, "rtc")) { - printk(KERN_ERR "upd4990a: could not acquire I/O port %#x\n", - UPD4990A_IO); - return -EBUSY; - } - - err = misc_register(&rtc_dev); - if (err) { - printk(KERN_ERR "upd4990a: can't misc_register() on minor=%d\n", - RTC_MINOR); - release_region(UPD4990A_IO, 1); - return err; - } - -#if 0 - printk(KERN_INFO "\xB6\xDA\xDD\xC0\xDE \xC4\xDE\xB9\xB2 Driver\n"); /* Calender Clock Driver */ -#else - printk(KERN_INFO - "Real Time Clock driver for NEC PC-9800 v" RTC98_VERSION "\n"); -#endif - create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL); - - init_timer(&rtc_uie_timer); - rtc_uie_timer.function = rtc_uie_intr; - - return 0; -} - -module_init (rtc_init); - -static void __exit rtc_exit(void) -{ - del_timer(&rtc_uie_timer); - release_region(UPD4990A_IO, 1); - remove_proc_entry("driver/rtc", NULL); - misc_deregister(&rtc_dev); -} - -module_exit (rtc_exit); - -/* - * Info exported via "/proc/driver/rtc". - */ - -static inline int rtc_get_status(char *buf) -{ - char *p; - unsigned int year; - struct upd4990a_raw_data data; - - p = buf; - - upd4990a_get_time(&data, 0); - - /* - * There is no way to tell if the luser has the RTC set for local - * time or for Universal Standard Time (GMT). Probably local though. - */ - if ((year = BCD2BIN(data.year) + 1900) < 1995) - year += 100; - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n", - BCD2BIN(data.hour), BCD2BIN(data.min), - BCD2BIN(data.sec), - year, data.mon, BCD2BIN(data.mday)); - - return p - buf; -} - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = rtc_get_status(page); - - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; -} diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig --- a/drivers/char/watchdog/Kconfig 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/watchdog/Kconfig 2004-06-26 17:09:19 -07:00 @@ -96,12 +96,13 @@ Say N if you are unsure. config SA1100_WATCHDOG - tristate "SA1100 watchdog" - depends on WATCHDOG && ARCH_SA1100 + tristate "SA1100/PXA2xx watchdog" + depends on WATCHDOG && ( ARCH_SA1100 || ARCH_PXA ) help - Watchdog timer embedded into SA11x0 chips. This will reboot your - system when timeout is reached. - NOTE, that once enabled, this timer cannot be disabled. + Watchdog timer embedded into SA11x0 and PXA2xx chips. This will + reboot your system when timeout is reached. + + NOTE: once enabled, this timer cannot be disabled. To compile this driver as a module, choose M here: the module will be called sa1100_wdt. diff -Nru a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c --- a/drivers/char/watchdog/acquirewdt.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/watchdog/acquirewdt.c 2004-06-26 17:09:19 -07:00 @@ -111,7 +111,7 @@ * /dev/watchdog handling. */ -static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -146,6 +146,8 @@ unsigned long arg) { int options, retval = -EINVAL; + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, @@ -156,22 +158,22 @@ switch(cmd) { case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0; + return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: acq_keepalive(); return 0; case WDIOC_GETTIMEOUT: - return put_user(WATCHDOG_HEARTBEAT, (int *)arg); + return put_user(WATCHDOG_HEARTBEAT, p); case WDIOC_SETOPTIONS: { - if (get_user(options, (int *)arg)) + if (get_user(options, p)) return -EFAULT; if (options & WDIOS_DISABLECARD) diff -Nru a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c --- a/drivers/char/watchdog/advantechwdt.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/char/watchdog/advantechwdt.c 2004-06-26 17:09:17 -07:00 @@ -100,7 +100,7 @@ } static ssize_t -advwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -130,6 +130,8 @@ unsigned long arg) { int new_timeout; + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, @@ -138,20 +140,20 @@ switch (cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: advwdt_ping(); break; case WDIOC_SETTIMEOUT: - if (get_user(new_timeout, (int *)arg)) + if (get_user(new_timeout, p)) return -EFAULT; if ((new_timeout < 1) || (new_timeout > 63)) return -EINVAL; @@ -160,13 +162,13 @@ /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; - if (get_user(options, (int *)arg)) + if (get_user(options, p)) return -EFAULT; if (options & WDIOS_DISABLECARD) { diff -Nru a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c --- a/drivers/char/watchdog/alim1535_wdt.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/watchdog/alim1535_wdt.c 2004-06-26 17:09:16 -07:00 @@ -138,7 +138,7 @@ * the next close to turn off the watchdog. */ -static ssize_t ali_write(struct file *file, const char *data, +static ssize_t ali_write(struct file *file, const char __user *data, size_t len, loff_t * ppos) { /* Can't seek (pwrite) on this device */ @@ -184,6 +184,8 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | @@ -194,12 +196,12 @@ switch (cmd) { case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *) arg, &ident, + return copy_to_user(argp, &ident, sizeof (ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *) arg); + return put_user(0, p); case WDIOC_KEEPALIVE: ali_keepalive(); @@ -209,7 +211,7 @@ { int new_options, retval = -EINVAL; - if (get_user (new_options, (int *) arg)) + if (get_user (new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { @@ -229,7 +231,7 @@ { int new_timeout; - if (get_user(new_timeout, (int *) arg)) + if (get_user(new_timeout, p)) return -EFAULT; if (ali_settimer(new_timeout)) @@ -240,7 +242,7 @@ } case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); default: return -ENOIOCTLCMD; diff -Nru a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c --- a/drivers/char/watchdog/alim7101_wdt.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/watchdog/alim7101_wdt.c 2004-06-26 17:09:19 -07:00 @@ -148,7 +148,7 @@ * /dev/watchdog handling */ -static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos) +static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) { /* We can't seek */ if(ppos != &file->f_pos) @@ -203,6 +203,8 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, @@ -213,10 +215,10 @@ switch(cmd) { case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; @@ -224,7 +226,7 @@ { int new_options, retval = -EINVAL; - if(get_user(new_options, (int *)arg)) + if(get_user(new_options, p)) return -EFAULT; if(new_options & WDIOS_DISABLECARD) { @@ -243,7 +245,7 @@ { int new_timeout; - if(get_user(new_timeout, (int *)arg)) + if(get_user(new_timeout, p)) return -EFAULT; if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ @@ -254,7 +256,7 @@ /* Fall through */ } case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); default: return -ENOIOCTLCMD; } diff -Nru a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c --- a/drivers/char/watchdog/cpu5wdt.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/watchdog/cpu5wdt.c 2004-06-26 17:09:16 -07:00 @@ -145,6 +145,7 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; unsigned int value; static struct watchdog_info ident = { @@ -159,15 +160,15 @@ case WDIOC_GETSTATUS: value = inb(port + CPU5WDT_STATUS_REG); value = (value >> 2) & 1; - if ( copy_to_user((int *)arg, (int *)&value, sizeof(int)) ) + if ( copy_to_user(argp, &value, sizeof(int)) ) return -EFAULT; break; case WDIOC_GETSUPPORT: - if ( copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ) + if ( copy_to_user(argp, &ident, sizeof(ident)) ) return -EFAULT; break; case WDIOC_SETOPTIONS: - if ( copy_from_user(&value, (int *)arg, sizeof(int)) ) + if ( copy_from_user(&value, argp, sizeof(int)) ) return -EFAULT; switch(value) { case WDIOS_ENABLECARD: @@ -185,7 +186,7 @@ return 0; } -static ssize_t cpu5wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if ( !count ) return -EIO; diff -Nru a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c --- a/drivers/char/watchdog/eurotechwdt.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/watchdog/eurotechwdt.c 2004-06-26 17:09:16 -07:00 @@ -196,8 +196,8 @@ * write of data will do, as we we don't define content meaning. */ -static ssize_t eurwdt_write(struct file *file, const char *buf, size_t count, -loff_t *ppos) +static ssize_t eurwdt_write(struct file *file, const char __user *buf, +size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -237,6 +237,8 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, @@ -251,19 +253,18 @@ return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, - sizeof(ident)) ? -EFAULT : 0; + return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *) arg); + return put_user(0, p); case WDIOC_KEEPALIVE: eurwdt_ping(); return 0; case WDIOC_SETTIMEOUT: - if (copy_from_user(&time, (int *) arg, sizeof(int))) + if (copy_from_user(&time, p, sizeof(int))) return -EFAULT; /* Sanity check */ @@ -275,10 +276,10 @@ /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(eurwdt_timeout, (int *)arg); + return put_user(eurwdt_timeout, p); case WDIOC_SETOPTIONS: - if (get_user(options, (int *)arg)) + if (get_user(options, p)) return -EFAULT; if (options & WDIOS_DISABLECARD) { eurwdt_disable_timer(); diff -Nru a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c --- a/drivers/char/watchdog/i8xx_tco.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/char/watchdog/i8xx_tco.c 2004-06-26 17:09:15 -07:00 @@ -212,7 +212,7 @@ return 0; } -static ssize_t i8xx_tco_write (struct file *file, const char *data, +static ssize_t i8xx_tco_write (struct file *file, const char __user *data, size_t len, loff_t * ppos) { /* Can't seek (pwrite) on this device */ @@ -249,6 +249,8 @@ { int new_options, retval = -EINVAL; int new_heartbeat; + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | @@ -259,12 +261,12 @@ switch (cmd) { case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *) arg, &ident, + return copy_to_user(argp, &ident, sizeof (ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user (0, (int *) arg); + return put_user (0, p); case WDIOC_KEEPALIVE: tco_timer_keepalive (); @@ -272,7 +274,7 @@ case WDIOC_SETOPTIONS: { - if (get_user (new_options, (int *) arg)) + if (get_user (new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { @@ -291,7 +293,7 @@ case WDIOC_SETTIMEOUT: { - if (get_user(new_heartbeat, (int *) arg)) + if (get_user(new_heartbeat, p)) return -EFAULT; if (tco_timer_set_heartbeat(new_heartbeat)) @@ -302,7 +304,7 @@ } case WDIOC_GETTIMEOUT: - return put_user(heartbeat, (int *)arg); + return put_user(heartbeat, p); default: return -ENOIOCTLCMD; diff -Nru a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c --- a/drivers/char/watchdog/ib700wdt.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/watchdog/ib700wdt.c 2004-06-26 17:09:20 -07:00 @@ -139,7 +139,7 @@ } static ssize_t -ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -170,6 +170,8 @@ unsigned long arg) { int i, new_margin; + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, @@ -179,19 +181,19 @@ switch (cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_GETSTATUS: - return put_user(0, (int *) arg); + return put_user(0, p); case WDIOC_KEEPALIVE: ibwdt_ping(); break; case WDIOC_SETTIMEOUT: - if (get_user(new_margin, (int *)arg)) + if (get_user(new_margin, p)) return -EFAULT; if ((new_margin < 0) || (new_margin > 30)) return -EINVAL; @@ -203,7 +205,7 @@ /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(wd_times[wd_margin], (int *)arg); + return put_user(wd_times[wd_margin], p); break; default: diff -Nru a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c --- a/drivers/char/watchdog/indydog.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/watchdog/indydog.c 2004-06-26 17:09:20 -07:00 @@ -22,16 +22,11 @@ #include #include #include -#include #include -#include +#include #define PFX "indydog: " -#define WATCHDOG_HEARTBEAT 60 - -static unsigned long indydog_alive; -static struct sgimc_misc_ctrl *mcmisc_regs; -static char expect_close; +static int indydog_alive; #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -39,96 +34,78 @@ static int nowayout = 0; #endif +#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ + module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); static void indydog_start(void) { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; + u32 mc_ctrl0 = sgimc->cpuctrl0; - mc_ctrl0 |= SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; - - printk(KERN_INFO PFX "Started watchdog timer.\n"); + mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; } static void indydog_stop(void) { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; + u32 mc_ctrl0 = sgimc->cpuctrl0; mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; + sgimc->cpuctrl0 = mc_ctrl0; printk(KERN_INFO PFX "Stopped watchdog timer.\n"); } static void indydog_ping(void) { - mcmisc_regs->watchdogt = 0; + sgimc->watchdogt = 0; } /* * Allow only one person to hold it open */ - static int indydog_open(struct inode *inode, struct file *file) { - if( test_and_set_bit(0,&indydog_alive) ) + if (indydog_alive) return -EBUSY; if (nowayout) __module_get(THIS_MODULE); - /* - * Activate timer - */ + /* Activate timer */ indydog_start(); indydog_ping(); + indydog_alive = 1; + printk(KERN_INFO "Started watchdog timer.\n"); + return 0; } static int indydog_release(struct inode *inode, struct file *file) { - /* - * Shut off the timer. - * Lock it in if it's a module and we set nowayout - */ - - if (expect_close == 42) { - indydog_stop(); - } else { - printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); - indydog_ping(); + /* Shut off the timer. + * Lock it in if it's a module and we defined ...NOWAYOUT */ + if (!nowayout) { + u32 mc_ctrl0 = sgimc->cpuctrl0; + mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; + printk(KERN_INFO "Stopped watchdog timer.\n"); } - clear_bit(0,&indydog_alive); - expect_close = 0; + indydog_alive = 0; + return 0; } static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) { - /* Can't seek (pwrite) on this device */ + /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) return -ESPIPE; /* Refresh the timer. */ if (len) { - if (!nowayout) { - size_t i; - - /* In case it was set long ago */ - expect_close = 0; - - for (i = 0; i != len; i++) { - char c; - - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - expect_close = 42; - } - } indydog_ping(); } return len; @@ -139,17 +116,18 @@ { int options, retval = -EINVAL; static struct watchdog_info ident = { - .options = WDIOF_KEEPALIVEPING | - WDIOF_MAGICCLOSE, - .firmware_version = 0, - .identity = "Hardware Watchdog for SGI IP22", + .options = WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = "Hardware Watchdog for SGI IP22", }; switch (cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + if (copy_to_user((struct watchdog_info *)arg, + &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: @@ -165,14 +143,12 @@ if (get_user(options, (int *)arg)) return -EFAULT; - if (options & WDIOS_DISABLECARD) - { + if (options & WDIOS_DISABLECARD) { indydog_stop(); retval = 0; } - if (options & WDIOS_ENABLECARD) - { + if (options & WDIOS_ENABLECARD) { indydog_start(); retval = 0; } @@ -184,39 +160,36 @@ static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if (code==SYS_DOWN || code==SYS_HALT) { - /* Turn the WDT off */ - indydog_stop(); - } + if (code == SYS_DOWN || code == SYS_HALT) + indydog_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } static struct file_operations indydog_fops = { - .owner = THIS_MODULE, - .write = indydog_write, - .ioctl = indydog_ioctl, - .open = indydog_open, - .release= indydog_release, + .owner = THIS_MODULE, + .write = indydog_write, + .ioctl = indydog_ioctl, + .open = indydog_open, + .release = indydog_release, }; static struct miscdevice indydog_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &indydog_fops, + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &indydog_fops, }; static struct notifier_block indydog_notifier = { .notifier_call = indydog_notify_sys, }; -static char banner[] __initdata = KERN_INFO PFX "Hardware Watchdog Timer for SGI IP22: 0.3\n"; +static char banner[] __initdata = + KERN_INFO PFX "Hardware Watchdog Timer for SGI IP22: 0.3\n"; static int __init watchdog_init(void) { int ret; - - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); ret = register_reboot_notifier(&indydog_notifier); if (ret) { diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c --- a/drivers/char/watchdog/machzwd.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/watchdog/machzwd.c 2004-06-26 17:09:16 -07:00 @@ -302,7 +302,7 @@ } } -static ssize_t zf_write(struct file *file, const char *buf, size_t count, +static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ @@ -352,15 +352,16 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; switch(cmd){ case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, - &zf_info, sizeof(zf_info))) + if (copy_to_user(argp, &zf_info, sizeof(zf_info))) return -EFAULT; break; case WDIOC_GETSTATUS: - return put_user(0, (int *) arg); + return put_user(0, p); case WDIOC_KEEPALIVE: zf_ping(0); diff -Nru a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c --- a/drivers/char/watchdog/mixcomwd.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/watchdog/mixcomwd.c 2004-06-26 17:09:16 -07:00 @@ -134,7 +134,7 @@ } -static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, loff_t *ppos) +static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { if (ppos != &file->f_pos) { return -ESPIPE; @@ -164,6 +164,8 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; int status; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, @@ -178,13 +180,12 @@ if (!nowayout) { status|=mixcomwd_timer_alive; } - if (copy_to_user((int *)arg, &status, sizeof(int))) { + if (copy_to_user(p, &status, sizeof(int))) { return -EFAULT; } break; case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, &ident, - sizeof(ident))) { + if (copy_to_user(argp, &ident, sizeof(ident))) { return -EFAULT; } break; diff -Nru a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c --- a/drivers/char/watchdog/pcwd_pci.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/char/watchdog/pcwd_pci.c 2004-06-26 17:09:15 -07:00 @@ -258,7 +258,7 @@ * /dev/watchdog handling */ -static ssize_t pcipcwd_write(struct file *file, const char *data, +static ssize_t pcipcwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { /* Can't seek (pwrite) on this device */ @@ -293,6 +293,8 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_OVERHEAT | WDIOF_CARDRESET | @@ -305,7 +307,7 @@ switch (cmd) { case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *) arg, &ident, + return copy_to_user(argp, &ident, sizeof (ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: @@ -314,11 +316,11 @@ pcipcwd_get_status(&status); - return put_user(status, (int *) arg); + return put_user(status, p); } case WDIOC_GETBOOTSTATUS: - return put_user(pcipcwd_private.boot_status, (int *) arg); + return put_user(pcipcwd_private.boot_status, p); case WDIOC_GETTEMP: { @@ -327,7 +329,7 @@ if (pcipcwd_get_temperature(&temperature)) return -EFAULT; - return put_user(temperature, (int *) arg); + return put_user(temperature, p); } case WDIOC_KEEPALIVE: @@ -338,7 +340,7 @@ { int new_options, retval = -EINVAL; - if (get_user (new_options, (int *) arg)) + if (get_user (new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { @@ -363,7 +365,7 @@ { int new_heartbeat; - if (get_user(new_heartbeat, (int *) arg)) + if (get_user(new_heartbeat, p)) return -EFAULT; if (pcipcwd_set_heartbeat(new_heartbeat)) @@ -374,7 +376,7 @@ } case WDIOC_GETTIMEOUT: - return put_user(heartbeat, (int *)arg); + return put_user(heartbeat, p); default: return -ENOIOCTLCMD; @@ -413,7 +415,7 @@ * /dev/temperature handling */ -static ssize_t pcipcwd_temp_read(struct file *file, char *data, +static ssize_t pcipcwd_temp_read(struct file *file, char __user *data, size_t len, loff_t *ppos) { int temperature; diff -Nru a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c --- a/drivers/char/watchdog/pcwd_usb.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/watchdog/pcwd_usb.c 2004-06-26 17:09:16 -07:00 @@ -326,7 +326,7 @@ * /dev/watchdog handling */ -static ssize_t usb_pcwd_write(struct file *file, const char *data, +static ssize_t usb_pcwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { /* Can't seek (pwrite) on this device */ @@ -361,6 +361,8 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | @@ -371,12 +373,12 @@ switch (cmd) { case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *) arg, &ident, + return copy_to_user(argp, &ident, sizeof (ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *) arg); + return put_user(0, p); case WDIOC_GETTEMP: { @@ -385,7 +387,7 @@ if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) return -EFAULT; - return put_user(temperature, (int *) arg); + return put_user(temperature, p); } case WDIOC_KEEPALIVE: @@ -396,7 +398,7 @@ { int new_options, retval = -EINVAL; - if (get_user (new_options, (int *) arg)) + if (get_user (new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { @@ -416,7 +418,7 @@ { int new_heartbeat; - if (get_user(new_heartbeat, (int *) arg)) + if (get_user(new_heartbeat, p)) return -EFAULT; if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat)) @@ -427,7 +429,7 @@ } case WDIOC_GETTIMEOUT: - return put_user(heartbeat, (int *)arg); + return put_user(heartbeat, p); default: return -ENOIOCTLCMD; @@ -466,7 +468,7 @@ * /dev/temperature handling */ -static ssize_t usb_pcwd_temperature_read(struct file *file, char *data, +static ssize_t usb_pcwd_temperature_read(struct file *file, char __user *data, size_t len, loff_t *ppos) { int temperature; @@ -478,7 +480,7 @@ if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) return -EFAULT; - if (copy_to_user (data, &temperature, 1)) + if (copy_to_user(data, &temperature, 1)) return -EFAULT; return 1; diff -Nru a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c --- a/drivers/char/watchdog/sa1100_wdt.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/watchdog/sa1100_wdt.c 2004-06-26 17:09:18 -07:00 @@ -1,5 +1,5 @@ /* - * Watchdog driver for the SA11x0 + * Watchdog driver for the SA11x0/PXA2xx * * (c) Copyright 2000 Oleg Drokin * Based on SoftDog driver by Alan Cox @@ -174,7 +174,7 @@ static struct miscdevice sa1100dog_miscdev = { .minor = WATCHDOG_MINOR, - .name = "SA1100 watchdog", + .name = "SA1100/PXA2xx watchdog", .fops = &sa1100dog_fops, }; @@ -194,7 +194,7 @@ ret = misc_register(&sa1100dog_miscdev); if (ret == 0) - printk("SA1100 Watchdog Timer: timer margin %d sec\n", + printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", margin); return ret; @@ -209,7 +209,7 @@ module_exit(sa1100dog_exit); MODULE_AUTHOR("Oleg Drokin "); -MODULE_DESCRIPTION("SA1100 Watchdog"); +MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog"); module_param(margin, int, 0); MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c --- a/drivers/char/watchdog/sbc60xxwdt.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/watchdog/sbc60xxwdt.c 2004-06-26 17:09:19 -07:00 @@ -166,7 +166,7 @@ * /dev/watchdog handling */ -static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos) +static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) { /* We can't seek */ if(ppos != &file->f_pos) @@ -230,6 +230,8 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident= { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, @@ -242,10 +244,10 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; @@ -253,7 +255,7 @@ { int new_options, retval = -EINVAL; - if(get_user(new_options, (int *)arg)) + if(get_user(new_options, p)) return -EFAULT; if(new_options & WDIOS_DISABLECARD) { @@ -272,7 +274,7 @@ { int new_timeout; - if(get_user(new_timeout, (int *)arg)) + if(get_user(new_timeout, p)) return -EFAULT; if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ @@ -283,7 +285,7 @@ /* Fall through */ } case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); } } diff -Nru a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c --- a/drivers/char/watchdog/sc1200wdt.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/char/watchdog/sc1200wdt.c 2004-06-26 17:09:16 -07:00 @@ -174,6 +174,8 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int new_timeout; + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 0, @@ -185,22 +187,22 @@ return -ENOIOCTLCMD; /* Keep Pavel Machek amused ;) */ case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident)) + if (copy_to_user(argp, &ident, sizeof ident)) return -EFAULT; return 0; case WDIOC_GETSTATUS: - return put_user(sc1200wdt_status(), (int *)arg); + return put_user(sc1200wdt_status(), p); case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: sc1200wdt_write_data(WDTO, timeout); return 0; case WDIOC_SETTIMEOUT: - if (get_user(new_timeout, (int *)arg)) + if (get_user(new_timeout, p)) return -EFAULT; /* the API states this is given in secs */ @@ -213,13 +215,13 @@ /* fall through and return the new timeout */ case WDIOC_GETTIMEOUT: - return put_user(timeout * 60, (int *)arg); + return put_user(timeout * 60, p); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; - if (get_user(options, (int *)arg)) + if (get_user(options, p)) return -EFAULT; if (options & WDIOS_DISABLECARD) { @@ -254,7 +256,7 @@ } -static ssize_t sc1200wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) +static ssize_t sc1200wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { if (ppos != &file->f_pos) return -ESPIPE; diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c --- a/drivers/char/watchdog/sc520_wdt.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/watchdog/sc520_wdt.c 2004-06-26 17:09:18 -07:00 @@ -225,7 +225,7 @@ * /dev/watchdog handling */ -static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos) +static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) { /* We can't seek */ if(ppos != &file->f_pos) @@ -285,6 +285,8 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, @@ -296,10 +298,10 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; @@ -307,7 +309,7 @@ { int new_options, retval = -EINVAL; - if(get_user(new_options, (int *)arg)) + if(get_user(new_options, p)) return -EFAULT; if(new_options & WDIOS_DISABLECARD) { @@ -326,7 +328,7 @@ { int new_timeout; - if(get_user(new_timeout, (int *)arg)) + if(get_user(new_timeout, p)) return -EFAULT; if(wdt_set_heartbeat(new_timeout)) @@ -336,7 +338,7 @@ /* Fall through */ } case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); } } diff -Nru a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c --- a/drivers/char/watchdog/scx200_wdt.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/watchdog/scx200_wdt.c 2004-06-26 17:09:19 -07:00 @@ -132,7 +132,7 @@ .notifier_call = scx200_wdt_notify_sys, }; -static ssize_t scx200_wdt_write(struct file *file, const char *data, +static ssize_t scx200_wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { if (ppos != &file->f_pos) @@ -163,6 +163,8 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .identity = "NatSemi SCx200 Watchdog", .firmware_version = 1, @@ -174,20 +176,19 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - if(copy_to_user((struct watchdog_info *)arg, &ident, - sizeof(ident))) + if(copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - if (put_user(0, (int *)arg)) + if (put_user(0, p)) return -EFAULT; return 0; case WDIOC_KEEPALIVE: scx200_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: - if (get_user(new_margin, (int *)arg)) + if (get_user(new_margin, p)) return -EFAULT; if (new_margin < 1) return -EINVAL; @@ -195,7 +196,7 @@ scx200_wdt_update_margin(); scx200_wdt_ping(); case WDIOC_GETTIMEOUT: - if (put_user(margin, (int *)arg)) + if (put_user(margin, p)) return -EFAULT; return 0; } diff -Nru a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c --- a/drivers/char/watchdog/softdog.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/char/watchdog/softdog.c 2004-06-26 17:09:17 -07:00 @@ -161,7 +161,7 @@ return 0; } -static ssize_t softdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) +static ssize_t softdog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -194,6 +194,8 @@ static int softdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; int new_margin; static struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT | @@ -206,23 +208,23 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, + return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0,(int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: softdog_keepalive(); return 0; case WDIOC_SETTIMEOUT: - if (get_user(new_margin, (int *)arg)) + if (get_user(new_margin, p)) return -EFAULT; if (softdog_set_heartbeat(new_margin)) return -EINVAL; softdog_keepalive(); /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(soft_margin, (int *)arg); + return put_user(soft_margin, p); } } diff -Nru a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c --- a/drivers/char/watchdog/w83627hf_wdt.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/watchdog/w83627hf_wdt.c 2004-06-26 17:09:18 -07:00 @@ -142,7 +142,7 @@ } static ssize_t -wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -171,6 +171,8 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; int new_timeout; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, @@ -180,20 +182,20 @@ switch (cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wdt_ping(); break; case WDIOC_SETTIMEOUT: - if (get_user(new_timeout, (int *)arg)) + if (get_user(new_timeout, p)) return -EFAULT; if (wdt_set_heartbeat(new_timeout)) return -EINVAL; @@ -201,13 +203,13 @@ /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; - if (get_user(options, (int *)arg)) + if (get_user(options, p)) return -EFAULT; if (options & WDIOS_DISABLECARD) { diff -Nru a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c --- a/drivers/char/watchdog/w83877f_wdt.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/watchdog/w83877f_wdt.c 2004-06-26 17:09:19 -07:00 @@ -188,7 +188,7 @@ * /dev/watchdog handling */ -static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos) +static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) { /* We can't seek */ if(ppos != &file->f_pos) @@ -249,6 +249,8 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident= { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, @@ -261,10 +263,10 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; @@ -272,7 +274,7 @@ { int new_options, retval = -EINVAL; - if(get_user(new_options, (int *)arg)) + if(get_user(new_options, p)) return -EFAULT; if(new_options & WDIOS_DISABLECARD) { @@ -291,7 +293,7 @@ { int new_timeout; - if(get_user(new_timeout, (int *)arg)) + if(get_user(new_timeout, p)) return -EFAULT; if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ @@ -302,7 +304,7 @@ /* Fall through */ } case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); } } diff -Nru a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c --- a/drivers/char/watchdog/wafer5823wdt.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/char/watchdog/wafer5823wdt.c 2004-06-26 17:09:20 -07:00 @@ -95,7 +95,7 @@ inb_p(wdt_stop); } -static ssize_t wafwdt_write(struct file *file, const char *buf, size_t count, loff_t * ppos) +static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -128,6 +128,8 @@ unsigned long arg) { int new_timeout; + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, @@ -136,21 +138,20 @@ switch (cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user - ((struct watchdog_info *) arg, &ident, sizeof (ident))) + if (copy_to_user(argp, &ident, sizeof (ident))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wafwdt_ping(); break; case WDIOC_SETTIMEOUT: - if (get_user(new_timeout, (int *)arg)) + if (get_user(new_timeout, p)) return -EFAULT; if ((new_timeout < 1) || (new_timeout > 255)) return -EINVAL; @@ -159,13 +160,13 @@ wafwdt_start(); /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); + return put_user(timeout, p); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; - if (get_user(options, (int *)arg)) + if (get_user(options, p)) return -EFAULT; if (options & WDIOS_DISABLECARD) { diff -Nru a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c --- a/drivers/char/watchdog/wdt.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/char/watchdog/wdt.c 2004-06-26 17:09:18 -07:00 @@ -286,7 +286,7 @@ * write of data will do, as we we don't define content meaning. */ -static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -327,6 +327,8 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; int new_heartbeat; int status; @@ -351,18 +353,18 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: wdt_get_status(&status); - return put_user(status,(int *)arg); + return put_user(status, p); case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wdt_ping(); return 0; case WDIOC_SETTIMEOUT: - if (get_user(new_heartbeat, (int *)arg)) + if (get_user(new_heartbeat, p)) return -EFAULT; if (wdt_set_heartbeat(new_heartbeat)) @@ -371,7 +373,7 @@ wdt_ping(); /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(heartbeat, (int *)arg); + return put_user(heartbeat, p); } } @@ -435,7 +437,7 @@ * farenheit. It was designed by an imperial measurement luddite. */ -static ssize_t wdt_temp_read(struct file *file, char *buf, size_t count, loff_t *ptr) +static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { int temperature; diff -Nru a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c --- a/drivers/char/watchdog/wdt_pci.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/char/watchdog/wdt_pci.c 2004-06-26 17:09:19 -07:00 @@ -331,7 +331,7 @@ * write of data will do, as we we don't define content meaning. */ -static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) @@ -374,6 +374,8 @@ { int new_heartbeat; int status; + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT| @@ -396,18 +398,18 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: wdtpci_get_status(&status); - return put_user(status,(int *)arg); + return put_user(status, p); case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *)arg); + return put_user(0, p); case WDIOC_KEEPALIVE: wdtpci_ping(); return 0; case WDIOC_SETTIMEOUT: - if (get_user(new_heartbeat, (int *)arg)) + if (get_user(new_heartbeat, p)) return -EFAULT; if (wdtpci_set_heartbeat(new_heartbeat)) @@ -416,7 +418,7 @@ wdtpci_ping(); /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(heartbeat, (int *)arg); + return put_user(heartbeat, p); } } @@ -484,7 +486,7 @@ * fahrenheit. It was designed by an imperial measurement luddite. */ -static ssize_t wdtpci_temp_read(struct file *file, char *buf, size_t count, loff_t *ptr) +static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { int temperature; diff -Nru a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c --- a/drivers/firmware/efivars.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/firmware/efivars.c 2004-06-26 17:09:20 -07:00 @@ -134,7 +134,7 @@ #define EFI_ATTR(_name, _mode, _show, _store) \ struct subsys_attribute efi_attr_##_name = { \ - .attr {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \ + .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \ .show = _show, \ .store = _store, \ }; diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c --- a/drivers/i2c/busses/i2c-piix4.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/i2c/busses/i2c-piix4.c 2004-06-26 17:09:16 -07:00 @@ -138,7 +138,7 @@ dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); - if(ibm_dmi_probe()) { + if(ibm_dmi_probe() && PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module " "may corrupt your serial eeprom! Refusing to load " "module!\n"); diff -Nru a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c --- a/drivers/i2c/busses/i2c-rpx.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/i2c/busses/i2c-rpx.c 2004-06-26 17:09:21 -07:00 @@ -50,7 +50,8 @@ /* Allocate space for two transmit and two receive buffer * descriptors in the DP ram. */ - data->dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 4); + data->dp_addr = m8xx_cpm_dpram_offset(m8xx_cpm_dpalloc(sizeof(cbd_t) + * 4)); /* ptr to i2c area */ data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c); diff -Nru a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c --- a/drivers/i2c/chips/asb100.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/i2c/chips/asb100.c 2004-06-26 17:09:18 -07:00 @@ -272,7 +272,7 @@ return show_in(dev, buf, 0x##offset); \ } \ static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ - show_in##offset, NULL) \ + show_in##offset, NULL); \ static ssize_t \ show_in##offset##_min (struct device *dev, char *buf) \ { \ @@ -294,17 +294,17 @@ return set_in_max(dev, buf, count, 0x##offset); \ } \ static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in##offset##_min, set_in##offset##_min) \ + show_in##offset##_min, set_in##offset##_min); \ static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in##offset##_max, set_in##offset##_max) + show_in##offset##_max, set_in##offset##_max); -sysfs_in(0) -sysfs_in(1) -sysfs_in(2) -sysfs_in(3) -sysfs_in(4) -sysfs_in(5) -sysfs_in(6) +sysfs_in(0); +sysfs_in(1); +sysfs_in(2); +sysfs_in(3); +sysfs_in(4); +sysfs_in(5); +sysfs_in(6); #define device_create_file_in(client, offset) do { \ device_create_file(&client->dev, &dev_attr_in##offset##_input); \ @@ -410,15 +410,15 @@ return set_fan_div(dev, buf, count, offset - 1); \ } \ static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ - show_fan##offset, NULL) \ + show_fan##offset, NULL); \ static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan##offset##_min, set_fan##offset##_min) \ + show_fan##offset##_min, set_fan##offset##_min); \ static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ - show_fan##offset##_div, set_fan##offset##_div) + show_fan##offset##_div, set_fan##offset##_div); -sysfs_fan(1) -sysfs_fan(2) -sysfs_fan(3) +sysfs_fan(1); +sysfs_fan(2); +sysfs_fan(3); #define device_create_file_fan(client, offset) do { \ device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ @@ -449,9 +449,9 @@ return sprintf_temp_from_reg(data->reg[nr], buf, nr); \ } -show_temp_reg(temp) -show_temp_reg(temp_max) -show_temp_reg(temp_hyst) +show_temp_reg(temp); +show_temp_reg(temp_max); +show_temp_reg(temp_hyst); #define set_temp_reg(REG, reg) \ static ssize_t set_##reg(struct device *dev, const char *buf, \ @@ -473,15 +473,15 @@ return count; \ } -set_temp_reg(MAX, temp_max) -set_temp_reg(HYST, temp_hyst) +set_temp_reg(MAX, temp_max); +set_temp_reg(HYST, temp_hyst); #define sysfs_temp(num) \ static ssize_t show_temp##num(struct device *dev, char *buf) \ { \ return show_temp(dev, buf, num-1); \ } \ -static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL) \ +static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL); \ static ssize_t show_temp_max##num(struct device *dev, char *buf) \ { \ return show_temp_max(dev, buf, num-1); \ @@ -492,7 +492,7 @@ return set_temp_max(dev, buf, count, num-1); \ } \ static DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \ - show_temp_max##num, set_temp_max##num) \ + show_temp_max##num, set_temp_max##num); \ static ssize_t show_temp_hyst##num(struct device *dev, char *buf) \ { \ return show_temp_hyst(dev, buf, num-1); \ @@ -503,12 +503,12 @@ return set_temp_hyst(dev, buf, count, num-1); \ } \ static DEVICE_ATTR(temp##num##_max_hyst, S_IRUGO | S_IWUSR, \ - show_temp_hyst##num, set_temp_hyst##num) + show_temp_hyst##num, set_temp_hyst##num); -sysfs_temp(1) -sysfs_temp(2) -sysfs_temp(3) -sysfs_temp(4) +sysfs_temp(1); +sysfs_temp(2); +sysfs_temp(3); +sysfs_temp(4); /* VID */ #define device_create_file_temp(client, num) do { \ @@ -523,7 +523,7 @@ return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); } -static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid, NULL) +static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid, NULL); #define device_create_file_vid(client) \ device_create_file(&client->dev, &dev_attr_in0_ref) @@ -544,7 +544,7 @@ } /* Alarms */ -static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm) +static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); #define device_create_file_vrm(client) \ device_create_file(&client->dev, &dev_attr_vrm); @@ -554,7 +554,7 @@ return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms)); } -static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL) +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); #define device_create_file_alarms(client) \ device_create_file(&client->dev, &dev_attr_alarms) @@ -594,9 +594,9 @@ return count; } -static DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1) +static DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1); static DEVICE_ATTR(fan1_pwm_enable, S_IRUGO | S_IWUSR, - show_pwm_enable1, set_pwm_enable1) + show_pwm_enable1, set_pwm_enable1); #define device_create_file_pwm1(client) do { \ device_create_file(&new_client->dev, &dev_attr_fan1_pwm); \ device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable); \ diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c --- a/drivers/i2c/chips/it87.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/i2c/chips/it87.c 2004-06-26 17:09:19 -07:00 @@ -128,15 +128,15 @@ #define IT87_REG_FAN(nr) (0x0d + (nr)) #define IT87_REG_FAN_MIN(nr) (0x10 + (nr)) -#define IT87_REG_FAN_CTRL 0x13 +#define IT87_REG_FAN_MAIN_CTRL 0x13 #define IT87_REG_VIN(nr) (0x20 + (nr)) #define IT87_REG_TEMP(nr) (0x29 + (nr)) #define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2) #define IT87_REG_VIN_MIN(nr) (0x31 + (nr) * 2) -#define IT87_REG_TEMP_HIGH(nr) (0x40 + ((nr) * 2)) -#define IT87_REG_TEMP_LOW(nr) (0x41 + ((nr) * 2)) +#define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2) +#define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2) #define IT87_REG_I2C_ADDR 0x48 @@ -145,8 +145,8 @@ #define IT87_REG_CHIPID 0x58 -#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) -#define IN_FROM_REG(val) (((val) * 16) / 10) +#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255)) +#define IN_FROM_REG(val) ((val) * 16) static inline u8 FAN_TO_REG(long rpm, int div) { @@ -159,9 +159,9 @@ #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) -#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ - ((val)+5)/10),0,255)) -#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) +#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\ + ((val)+500)/1000),-128,127)) +#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000) #define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ 205-(val)*5) @@ -170,7 +170,7 @@ static int DIV_TO_REG(int val) { int answer = 0; - while ((val >>= 1)) + while ((val >>= 1) != 0) answer++; return answer; } @@ -231,19 +231,19 @@ static ssize_t show_in(struct device *dev, char *buf, int nr) { struct it87_data *data = it87_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])*10 ); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); } static ssize_t show_in_min(struct device *dev, char *buf, int nr) { struct it87_data *data = it87_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])*10 ); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); } static ssize_t show_in_max(struct device *dev, char *buf, int nr) { struct it87_data *data = it87_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])*10 ); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); } static ssize_t set_in_min(struct device *dev, const char *buf, @@ -251,7 +251,7 @@ { struct i2c_client *client = to_i2c_client(dev); struct it87_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10)/10; + unsigned long val = simple_strtoul(buf, NULL, 10); data->in_min[nr] = IN_TO_REG(val); it87_write_value(client, IT87_REG_VIN_MIN(nr), data->in_min[nr]); @@ -262,7 +262,7 @@ { struct i2c_client *client = to_i2c_client(dev); struct it87_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10)/10; + unsigned long val = simple_strtoul(buf, NULL, 10); data->in_max[nr] = IN_TO_REG(val); it87_write_value(client, IT87_REG_VIN_MAX(nr), data->in_max[nr]); @@ -275,7 +275,7 @@ { \ return show_in(dev, buf, 0x##offset); \ } \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL) +static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL); #define limit_in_offset(offset) \ static ssize_t \ @@ -299,9 +299,9 @@ return set_in_max(dev, buf, count, 0x##offset); \ } \ static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in##offset##_min, set_in##offset##_min) \ + show_in##offset##_min, set_in##offset##_min); \ static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in##offset##_max, set_in##offset##_max) + show_in##offset##_max, set_in##offset##_max); show_in_offset(0); limit_in_offset(0); @@ -325,24 +325,24 @@ static ssize_t show_temp(struct device *dev, char *buf, int nr) { struct it87_data *data = it87_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])*100 ); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); } static ssize_t show_temp_max(struct device *dev, char *buf, int nr) { struct it87_data *data = it87_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])*100); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])); } static ssize_t show_temp_min(struct device *dev, char *buf, int nr) { struct it87_data *data = it87_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr])*100); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr])); } static ssize_t set_temp_max(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct it87_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10)/100; + int val = simple_strtol(buf, NULL, 10); data->temp_high[nr] = TEMP_TO_REG(val); it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); return count; @@ -352,7 +352,7 @@ { struct i2c_client *client = to_i2c_client(dev); struct it87_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10)/100; + int val = simple_strtol(buf, NULL, 10); data->temp_low[nr] = TEMP_TO_REG(val); it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); return count; @@ -382,11 +382,11 @@ { \ return set_temp_min(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \ +static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \ static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_max, set_temp_##offset##_max) \ + show_temp_##offset##_max, set_temp_##offset##_max); \ static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_min, set_temp_##offset##_min) + show_temp_##offset##_min, set_temp_##offset##_min); show_temp_offset(1); show_temp_offset(2); @@ -430,8 +430,8 @@ { \ return set_sensor(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ - show_sensor_##offset, set_sensor_##offset) +static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ + show_sensor_##offset, set_sensor_##offset); show_sensor_offset(1); show_sensor_offset(2); @@ -525,11 +525,11 @@ { \ return set_fan_div(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL); \ static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan_##offset##_min, set_fan_##offset##_min) \ + show_fan_##offset##_min, set_fan_##offset##_min); \ static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ - show_fan_##offset##_div, set_fan_##offset##_div) + show_fan_##offset##_div, set_fan_##offset##_div); show_fan_offset(1); show_fan_offset(2); @@ -773,9 +773,7 @@ We don't want to lock the whole ISA bus, so we lock each client separately. We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, - would slow down the IT87 access and should not be necessary. - There are some ugly typecasts here, but the good new is - they should - nowhere else be necessary! */ + would slow down the IT87 access and should not be necessary. */ static int it87_read_value(struct i2c_client *client, u8 reg) { struct it87_data *data = i2c_get_clientdata(client); @@ -795,9 +793,7 @@ We don't want to lock the whole ISA bus, so we lock each client separately. We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, - would slow down the IT87 access and should not be necessary. - There are some ugly typecasts here, but the good new is - they should - nowhere else be necessary! */ + would slow down the IT87 access and should not be necessary. */ static int it87_write_value(struct i2c_client *client, u8 reg, u8 value) { struct it87_data *data = i2c_get_clientdata(client); @@ -840,11 +836,11 @@ } /* Check if tachometers are reset manually or by some reason */ - tmp = it87_read_value(client, IT87_REG_FAN_CTRL); + tmp = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL); if ((tmp & 0x70) == 0) { /* Enable all fan tachometers */ tmp = (tmp & 0x8f) | 0x70; - it87_write_value(client, IT87_REG_FAN_CTRL, tmp); + it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, tmp); } /* Start monitoring */ diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c --- a/drivers/i2c/chips/lm78.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/i2c/chips/lm78.c 2004-06-26 17:09:20 -07:00 @@ -281,7 +281,7 @@ return show_in(dev, buf, 0x##offset); \ } \ static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ - show_in##offset, NULL) \ + show_in##offset, NULL); \ static ssize_t \ show_in##offset##_min (struct device *dev, char *buf) \ { \ @@ -303,9 +303,9 @@ return set_in_max(dev, buf, count, 0x##offset); \ } \ static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in##offset##_min, set_in##offset##_min) \ + show_in##offset##_min, set_in##offset##_min); \ static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in##offset##_max, set_in##offset##_max) + show_in##offset##_max, set_in##offset##_max); show_in_offset(0); show_in_offset(1); @@ -354,11 +354,11 @@ return count; } -static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL) +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, - show_temp_over, set_temp_over) + show_temp_over, set_temp_over); static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, - show_temp_hyst, set_temp_hyst) + show_temp_hyst, set_temp_hyst); /* 3 Fans */ static ssize_t show_fan(struct device *dev, char *buf, int nr) @@ -439,9 +439,9 @@ { \ return set_fan_min(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan_##offset##_min, set_fan_##offset##_min) + show_fan_##offset##_min, set_fan_##offset##_min); static ssize_t set_fan_1_div(struct device *dev, const char *buf, size_t count) @@ -461,10 +461,10 @@ /* Fan 3 divisor is locked in H/W */ static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, - show_fan_1_div, set_fan_1_div) + show_fan_1_div, set_fan_1_div); static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, - show_fan_2_div, set_fan_2_div) -static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL) + show_fan_2_div, set_fan_2_div); +static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL); /* VID */ static ssize_t show_vid(struct device *dev, char *buf) diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c --- a/drivers/i2c/chips/lm85.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/i2c/chips/lm85.c 2004-06-26 17:09:17 -07:00 @@ -451,9 +451,9 @@ { \ return set_fan_min(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan_##offset##_min, set_fan_##offset##_min) + show_fan_##offset##_min, set_fan_##offset##_min); show_fan_offset(1); show_fan_offset(2); @@ -468,7 +468,7 @@ return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); } -static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL) +static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL); static ssize_t show_vrm_reg(struct device *dev, char *buf) { @@ -487,7 +487,7 @@ return count; } -static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg) +static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); static ssize_t show_alarms_reg(struct device *dev, char *buf) { @@ -495,7 +495,7 @@ return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms)); } -static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL) +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); /* pwm */ @@ -542,8 +542,8 @@ return show_pwm_enable(dev, buf, 0x##offset - 1); \ } \ static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \ - show_pwm_##offset, set_pwm_##offset) \ -static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL) + show_pwm_##offset, set_pwm_##offset); \ +static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL); show_pwm_reg(1); show_pwm_reg(2); @@ -617,11 +617,11 @@ { \ return set_in_max(dev, buf, count, 0x##offset); \ } \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL) \ +static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL); \ static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in_##offset##_min, set_in_##offset##_min) \ + show_in_##offset##_min, set_in_##offset##_min); \ static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in_##offset##_max, set_in_##offset##_max) + show_in_##offset##_max, set_in_##offset##_max); show_in_reg(0); show_in_reg(1); @@ -697,11 +697,11 @@ { \ return set_temp_max(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \ +static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \ static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_min, set_temp_##offset##_min) \ + show_temp_##offset##_min, set_temp_##offset##_min); \ static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_max, set_temp_##offset##_max) + show_temp_##offset##_max, set_temp_##offset##_max); show_temp_reg(1); show_temp_reg(2); diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c --- a/drivers/i2c/chips/via686a.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/i2c/chips/via686a.c 2004-06-26 17:09:15 -07:00 @@ -405,11 +405,11 @@ { \ return set_in_max(dev, buf, count, 0x##offset); \ } \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL) \ +static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\ static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in##offset##_min, set_in##offset##_min) \ + show_in##offset##_min, set_in##offset##_min); \ static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in##offset##_max, set_in##offset##_max) + show_in##offset##_max, set_in##offset##_max); show_in_offset(0); show_in_offset(1); @@ -473,11 +473,11 @@ { \ return set_temp_hyst(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \ +static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\ static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_over, set_temp_##offset##_over) \ + show_temp_##offset##_over, set_temp_##offset##_over); \ static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_hyst, set_temp_##offset##_hyst) + show_temp_##offset##_hyst, set_temp_##offset##_hyst); show_temp_offset(1); show_temp_offset(2); @@ -542,11 +542,11 @@ { \ return set_fan_div(dev, buf, count, 0x##offset - 1); \ } \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan_##offset##_min, set_fan_##offset##_min) \ + show_fan_##offset##_min, set_fan_##offset##_min); \ static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ - show_fan_##offset##_div, set_fan_##offset##_div) + show_fan_##offset##_div, set_fan_##offset##_div); show_fan_offset(1); show_fan_offset(2); diff -Nru a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c --- a/drivers/i2c/chips/w83627hf.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/i2c/chips/w83627hf.c 2004-06-26 17:09:19 -07:00 @@ -199,7 +199,7 @@ #define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */ #define W83627THF_REG_PWM3 0x11 /* 637HF too */ -#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too, unused yet */ +#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */ static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, @@ -222,7 +222,7 @@ these macros are called: arguments may be evaluated more than once. Fixing this is just not worth it. */ #define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255)) -#define IN_FROM_REG(val) ((val) * 16 + 5) +#define IN_FROM_REG(val) ((val) * 16) static inline u8 FAN_TO_REG(long rpm, int div) { @@ -312,6 +312,7 @@ Default = 3435. Other Betas unimplemented */ u8 vrm; + u8 vrm_ovt; /* Register value, 627thf & 637hf only */ }; @@ -370,7 +371,7 @@ { \ return show_in(dev, buf, 0x##offset); \ } \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL) +static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL); #define sysfs_in_reg_offset(reg, offset) \ static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \ @@ -384,22 +385,104 @@ return store_in_##reg (dev, buf, count, 0x##offset); \ } \ static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \ - show_regs_in_##reg##offset, store_regs_in_##reg##offset) + show_regs_in_##reg##offset, store_regs_in_##reg##offset); #define sysfs_in_offsets(offset) \ sysfs_in_offset(offset) \ sysfs_in_reg_offset(min, offset) \ sysfs_in_reg_offset(max, offset) -sysfs_in_offsets(0) -sysfs_in_offsets(1) -sysfs_in_offsets(2) -sysfs_in_offsets(3) -sysfs_in_offsets(4) -sysfs_in_offsets(5) -sysfs_in_offsets(6) -sysfs_in_offsets(7) -sysfs_in_offsets(8) +sysfs_in_offsets(1); +sysfs_in_offsets(2); +sysfs_in_offsets(3); +sysfs_in_offsets(4); +sysfs_in_offsets(5); +sysfs_in_offsets(6); +sysfs_in_offsets(7); +sysfs_in_offsets(8); + +/* use a different set of functions for in0 */ +static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg) +{ + long in0; + + if ((data->vrm_ovt & 0x01) && + (w83627thf == data->type || w83637hf == data->type)) + + /* use VRM9 calculation */ + in0 = (long)((reg * 488 + 70000 + 50) / 100); + else + /* use VRM8 (standard) calculation */ + in0 = (long)IN_FROM_REG(reg); + + return sprintf(buf,"%ld\n", in0); +} + +static ssize_t show_regs_in_0(struct device *dev, char *buf) +{ + struct w83627hf_data *data = w83627hf_update_device(dev); + return show_in_0(data, buf, data->in[0]); +} + +static ssize_t show_regs_in_min0(struct device *dev, char *buf) +{ + struct w83627hf_data *data = w83627hf_update_device(dev); + return show_in_0(data, buf, data->in_min[0]); +} + +static ssize_t show_regs_in_max0(struct device *dev, char *buf) +{ + struct w83627hf_data *data = w83627hf_update_device(dev); + return show_in_0(data, buf, data->in_max[0]); +} + +static ssize_t store_regs_in_min0(struct device *dev, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); + u32 val; + + val = simple_strtoul(buf, NULL, 10); + if ((data->vrm_ovt & 0x01) && + (w83627thf == data->type || w83637hf == data->type)) + + /* use VRM9 calculation */ + data->in_min[0] = (u8)(((val * 100) - 70000 + 244) / 488); + else + /* use VRM8 (standard) calculation */ + data->in_min[0] = IN_TO_REG(val); + + w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]); + return count; +} + +static ssize_t store_regs_in_max0(struct device *dev, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); + u32 val; + + val = simple_strtoul(buf, NULL, 10); + if ((data->vrm_ovt & 0x01) && + (w83627thf == data->type || w83637hf == data->type)) + + /* use VRM9 calculation */ + data->in_max[0] = (u8)(((val * 100) - 70000 + 244) / 488); + else + /* use VRM8 (standard) calculation */ + data->in_max[0] = IN_TO_REG(val); + + w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]); + return count; +} + +static DEVICE_ATTR(in0_input, S_IRUGO, show_regs_in_0, NULL); +static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, + show_regs_in_min0, store_regs_in_min0); +static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, + show_regs_in_max0, store_regs_in_max0); #define device_create_file_in(client, offset) \ do { \ @@ -416,8 +499,8 @@ FAN_FROM_REG(data->reg[nr-1], \ (long)DIV_FROM_REG(data->fan_div[nr-1]))); \ } -show_fan_reg(fan) -show_fan_reg(fan_min) +show_fan_reg(fan); +show_fan_reg(fan_min); static ssize_t store_fan_min(struct device *dev, const char *buf, size_t count, int nr) @@ -440,7 +523,7 @@ { \ return show_fan(dev, buf, 0x##offset); \ } \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL) +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL); #define sysfs_fan_min_offset(offset) \ static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \ @@ -453,14 +536,14 @@ return store_fan_min(dev, buf, count, 0x##offset); \ } \ static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_regs_fan_min##offset, store_regs_fan_min##offset) + show_regs_fan_min##offset, store_regs_fan_min##offset); -sysfs_fan_offset(1) -sysfs_fan_min_offset(1) -sysfs_fan_offset(2) -sysfs_fan_min_offset(2) -sysfs_fan_offset(3) -sysfs_fan_min_offset(3) +sysfs_fan_offset(1); +sysfs_fan_min_offset(1); +sysfs_fan_offset(2); +sysfs_fan_min_offset(2); +sysfs_fan_offset(3); +sysfs_fan_min_offset(3); #define device_create_file_fan(client, offset) \ do { \ @@ -479,9 +562,9 @@ return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \ } \ } -show_temp_reg(temp) -show_temp_reg(temp_max) -show_temp_reg(temp_max_hyst) +show_temp_reg(temp); +show_temp_reg(temp_max); +show_temp_reg(temp_max_hyst); #define store_temp_reg(REG, reg) \ static ssize_t \ @@ -505,8 +588,8 @@ \ return count; \ } -store_temp_reg(OVER, max) -store_temp_reg(HYST, max_hyst) +store_temp_reg(OVER, max); +store_temp_reg(HYST, max_hyst); #define sysfs_temp_offset(offset) \ static ssize_t \ @@ -514,7 +597,7 @@ { \ return show_temp(dev, buf, 0x##offset); \ } \ -static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL) +static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL); #define sysfs_temp_reg_offset(reg, offset) \ static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \ @@ -528,16 +611,16 @@ return store_temp_##reg (dev, buf, count, 0x##offset); \ } \ static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \ - show_regs_temp_##reg##offset, store_regs_temp_##reg##offset) + show_regs_temp_##reg##offset, store_regs_temp_##reg##offset); #define sysfs_temp_offsets(offset) \ sysfs_temp_offset(offset) \ sysfs_temp_reg_offset(max, offset) \ sysfs_temp_reg_offset(max_hyst, offset) -sysfs_temp_offsets(1) -sysfs_temp_offsets(2) -sysfs_temp_offsets(3) +sysfs_temp_offsets(1); +sysfs_temp_offsets(2); +sysfs_temp_offsets(3); #define device_create_file_temp(client, offset) \ do { \ @@ -552,7 +635,7 @@ struct w83627hf_data *data = w83627hf_update_device(dev); return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); } -static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL) +static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL); #define device_create_file_vid(client) \ device_create_file(&client->dev, &dev_attr_in0_ref) @@ -574,7 +657,7 @@ return count; } -static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg) +static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); #define device_create_file_vrm(client) \ device_create_file(&client->dev, &dev_attr_vrm) @@ -584,7 +667,7 @@ struct w83627hf_data *data = w83627hf_update_device(dev); return sprintf(buf, "%ld\n", (long) data->alarms); } -static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL) +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); #define device_create_file_alarms(client) \ device_create_file(&client->dev, &dev_attr_alarms) @@ -641,10 +724,10 @@ return store_beep_reg(dev, buf, count, BEEP_##REG); \ } \ static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \ - show_regs_beep_##reg, store_regs_beep_##reg) + show_regs_beep_##reg, store_regs_beep_##reg); -sysfs_beep(ENABLE, enable) -sysfs_beep(MASK, mask) +sysfs_beep(ENABLE, enable); +sysfs_beep(MASK, mask); #define device_create_file_beep(client) \ do { \ @@ -707,11 +790,11 @@ return store_fan_div_reg(dev, buf, count, offset - 1); \ } \ static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ - show_regs_fan_div_##offset, store_regs_fan_div_##offset) + show_regs_fan_div_##offset, store_regs_fan_div_##offset); -sysfs_fan_div(1) -sysfs_fan_div(2) -sysfs_fan_div(3) +sysfs_fan_div(1); +sysfs_fan_div(2); +sysfs_fan_div(3); #define device_create_file_fan_div(client, offset) \ do { \ @@ -763,11 +846,11 @@ return store_pwm_reg(dev, buf, count, offset); \ } \ static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \ - show_regs_pwm_##offset, store_regs_pwm_##offset) + show_regs_pwm_##offset, store_regs_pwm_##offset); -sysfs_pwm(1) -sysfs_pwm(2) -sysfs_pwm(3) +sysfs_pwm(1); +sysfs_pwm(2); +sysfs_pwm(3); #define device_create_file_pwm(client, offset) \ do { \ @@ -836,11 +919,11 @@ return store_sensor_reg(dev, buf, count, offset); \ } \ static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ - show_regs_sensor_##offset, store_regs_sensor_##offset) + show_regs_sensor_##offset, store_regs_sensor_##offset); -sysfs_sensor(1) -sysfs_sensor(2) -sysfs_sensor(3) +sysfs_sensor(1); +sysfs_sensor(2); +sysfs_sensor(3); #define device_create_file_sensor(client, offset) \ do { \ @@ -1157,7 +1240,7 @@ static void w83627hf_init_client(struct i2c_client *client) { struct w83627hf_data *data = i2c_get_clientdata(client); - int vid = 0, i; + int i; int type = data->type; u8 tmp; @@ -1191,10 +1274,15 @@ data->vid = w83627thf_read_gpio5(client) & 0x1f; } - /* Convert VID to voltage based on default VRM */ - data->vrm = DEFAULT_VRM; - if (type != w83697hf) - vid = vid_from_reg(vid, data->vrm); + /* Read VRM & OVT Config only once */ + if (w83627thf == data->type || w83637hf == data->type) { + data->vrm_ovt = + w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); + data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82; + } else { + /* Convert VID to voltage based on default VRM */ + data->vrm = DEFAULT_VRM; + } tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); for (i = 1; i <= 3; i++) { diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c --- a/drivers/i2c/chips/w83781d.c 2004-06-26 17:09:14 -07:00 +++ b/drivers/i2c/chips/w83781d.c 2004-06-26 17:09:14 -07:00 @@ -320,7 +320,7 @@ { \ return show_in(dev, buf, 0x##offset); \ } \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL) +static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL); #define sysfs_in_reg_offset(reg, offset) \ static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \ @@ -331,7 +331,7 @@ { \ return store_in_##reg (dev, buf, count, 0x##offset); \ } \ -static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset) +static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset); #define sysfs_in_offsets(offset) \ sysfs_in_offset(offset); \ @@ -386,7 +386,7 @@ { \ return show_fan(dev, buf, 0x##offset); \ } \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL) +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL); #define sysfs_fan_min_offset(offset) \ static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \ @@ -397,7 +397,7 @@ { \ return store_fan_min(dev, buf, count, 0x##offset); \ } \ -static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset) +static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset); sysfs_fan_offset(1); sysfs_fan_min_offset(1); @@ -466,7 +466,7 @@ { \ return show_temp(dev, buf, 0x##offset); \ } \ -static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL) +static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL); #define sysfs_temp_reg_offset(reg, offset) \ static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \ @@ -477,7 +477,7 @@ { \ return store_temp_##reg (dev, buf, count, 0x##offset); \ } \ -static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset) +static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset); #define sysfs_temp_offsets(offset) \ sysfs_temp_offset(offset); \ @@ -503,7 +503,7 @@ } static -DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL) +DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL); #define device_create_file_vid(client) \ device_create_file(&client->dev, &dev_attr_in0_ref); static ssize_t @@ -527,7 +527,7 @@ } static -DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg) +DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); #define device_create_file_vrm(client) \ device_create_file(&client->dev, &dev_attr_vrm); static ssize_t @@ -538,7 +538,7 @@ } static -DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL) +DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); #define device_create_file_alarms(client) \ device_create_file(&client->dev, &dev_attr_alarms); static ssize_t show_beep_mask (struct device *dev, char *buf) @@ -598,7 +598,7 @@ { \ return store_beep_reg(dev, buf, count, BEEP_##REG); \ } \ -static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg) +static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg); sysfs_beep(ENABLE, enable); sysfs_beep(MASK, mask); @@ -665,7 +665,7 @@ { \ return store_fan_div_reg(dev, buf, count, offset - 1); \ } \ -static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset) +static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset); sysfs_fan_div(1); sysfs_fan_div(2); @@ -744,7 +744,7 @@ { \ return store_pwm_reg(dev, buf, count, offset); \ } \ -static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset) +static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset); #define sysfs_pwmenable(offset) \ static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \ @@ -755,7 +755,7 @@ { \ return store_pwmenable_reg(dev, buf, count, offset); \ } \ -static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset) +static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset); sysfs_pwm(1); sysfs_pwm(2); @@ -833,7 +833,7 @@ { \ return store_sensor_reg(dev, buf, count, offset); \ } \ -static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset) +static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset); sysfs_sensor(1); sysfs_sensor(2); @@ -891,7 +891,7 @@ { \ return store_rt_reg(dev, buf, count, offset); \ } \ -static DEVICE_ATTR(rt##offset, S_IRUGO | S_IWUSR, show_regs_rt_##offset, store_regs_rt_##offset) +static DEVICE_ATTR(rt##offset, S_IRUGO | S_IWUSR, show_regs_rt_##offset, store_regs_rt_##offset); sysfs_rt(1); sysfs_rt(2); @@ -1491,7 +1491,7 @@ w83781d_init_client(struct i2c_client *client) { struct w83781d_data *data = i2c_get_clientdata(client); - int vid = 0, i, p; + int i, p; int type = data->type; u8 tmp; @@ -1513,14 +1513,7 @@ w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); } - if (type != w83697hf) { - vid = w83781d_read_value(client, W83781D_REG_VID_FANDIV) & 0x0f; - vid |= - (w83781d_read_value(client, W83781D_REG_CHIPID) & 0x01) << - 4; - data->vrm = DEFAULT_VRM; - vid = vid_from_reg(vid, data->vrm); - } + data->vrm = 82; if ((type != w83781d) && (type != as99127f)) { tmp = w83781d_read_value(client, W83781D_REG_SCFG1); diff -Nru a/drivers/i2c/chips/w83l785ts.c b/drivers/i2c/chips/w83l785ts.c --- a/drivers/i2c/chips/w83l785ts.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/i2c/chips/w83l785ts.c 2004-06-26 17:09:16 -07:00 @@ -137,8 +137,8 @@ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over)); } -static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL) -static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL) +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); +static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL); /* * Real code diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c --- a/drivers/i2c/i2c-core.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/i2c/i2c-core.c 2004-06-26 17:09:16 -07:00 @@ -126,7 +126,13 @@ goto out_unlock; } - id = idr_get_new(&i2c_adapter_idr, NULL); + res = idr_get_new(&i2c_adapter_idr, NULL, &id); + if (res < 0) { + if (res == -EAGAIN) + res = -ENOMEM; + goto out_unlock; + } + adap->nr = id & MAX_ID_MASK; init_MUTEX(&adap->bus_lock); init_MUTEX(&adap->clist_lock); @@ -162,7 +168,7 @@ dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr); - out_unlock: +out_unlock: up(&core_lists); return res; } diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c --- a/drivers/i2c/i2c-dev.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/i2c/i2c-dev.c 2004-06-26 17:09:19 -07:00 @@ -181,7 +181,7 @@ struct i2c_smbus_ioctl_data data_arg; union i2c_smbus_data temp; struct i2c_msg *rdwr_pa; - u8 **data_ptrs; + u8 __user **data_ptrs; int i,datasize,res; unsigned long funcs; @@ -238,8 +238,7 @@ return -EFAULT; } - data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *), - GFP_KERNEL); + data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL); if (data_ptrs == NULL) { kfree(rdwr_pa); return -ENOMEM; @@ -252,7 +251,7 @@ res = -EINVAL; break; } - data_ptrs[i] = rdwr_pa[i].buf; + data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf; rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL); if(rdwr_pa[i].buf == NULL) { res = -ENOMEM; diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig --- a/drivers/ide/Kconfig 2004-06-26 17:09:17 -07:00 +++ b/drivers/ide/Kconfig 2004-06-26 17:09:17 -07:00 @@ -54,7 +54,7 @@ config IDE_MAX_HWIFS int "Max IDE interfaces" - depends on ALPHA + depends on ALPHA || SUPERH default 4 help This is the maximum number of IDE hardware interfaces that will @@ -95,27 +95,29 @@ comment "Please see Documentation/ide.txt for help/info on IDE drives" -config BLK_DEV_HD_IDE - bool "Use old disk-only driver on primary interface" - depends on ((X86 && X86_PC9800!=y) || SH_MPC1211) +config BLK_DEV_IDE_SATA + bool "Support for SATA (deprecated; conflicts with libata SATA driver)" + default n ---help--- - There are two drivers for MFM/RLL/IDE disks. Most people use just - the new enhanced driver by itself. This option however installs the - old hard disk driver to control the primary IDE/disk interface in - the system, leaving the new enhanced IDE driver to take care of only - the 2nd/3rd/4th IDE interfaces. Doing this will prevent you from - having an IDE/ATAPI CD-ROM or tape drive connected to the primary - IDE interface. Choosing this option may be useful for older systems - which have MFM/RLL/ESDI controller+drives at the primary port - address (0x1f0), along with IDE drives at the secondary/3rd/4th port - addresses. + There are two drivers for Serial ATA controllers. + + The main driver, "libata", exists inside the SCSI subsystem + and supports most modern SATA controllers. - Normally, just say N here; you will then use the new driver for all - 4 interfaces. + The IDE driver (which you are currently configuring) supports + a few first-generation SATA controllers. -config BLK_DEV_HD_IDE98 + In order to eliminate conflicts between the two subsystems, + this config option enables the IDE driver's SATA support. + Normally this is disabled, as it is preferred that libata + supports SATA controllers, and this (IDE) driver supports + PATA controllers. + + If unsure, say N. + +config BLK_DEV_HD_IDE bool "Use old disk-only driver on primary interface" - depends on X86 && X86_PC9800 + depends on (X86 || SH_MPC1211) ---help--- There are two drivers for MFM/RLL/IDE disks. Most people use just the new enhanced driver by itself. This option however installs the diff -Nru a/drivers/ide/Makefile b/drivers/ide/Makefile --- a/drivers/ide/Makefile 2004-06-26 17:09:18 -07:00 +++ b/drivers/ide/Makefile 2004-06-26 17:09:18 -07:00 @@ -29,7 +29,6 @@ ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o # built-in only drivers from legacy/ -ide-core-$(CONFIG_BLK_DEV_IDE_PC9800) += legacy/pc9800.o ide-core-$(CONFIG_BLK_DEV_BUDDHA) += legacy/buddha.o ide-core-$(CONFIG_BLK_DEV_FALCON_IDE) += legacy/falconide.o ide-core-$(CONFIG_BLK_DEV_GAYLE) += legacy/gayle.o diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c --- a/drivers/ide/ide-cd.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/ide/ide-cd.c 2004-06-26 17:09:17 -07:00 @@ -2816,7 +2816,6 @@ return 0; } - /* * Close down the device. Invalidate all cached blocks. */ @@ -2890,12 +2889,6 @@ devinfo->mask |= CDC_CLOSE_TRAY; if (!CDROM_CONFIG_FLAGS(drive)->mo_drive) devinfo->mask |= CDC_MO_DRIVE; - if (!CDROM_CONFIG_FLAGS(drive)->mrw) - devinfo->mask |= CDC_MRW; - if (!CDROM_CONFIG_FLAGS(drive)->mrw_w) - devinfo->mask |= CDC_MRW_W; - if (!CDROM_CONFIG_FLAGS(drive)->ram) - devinfo->mask |= CDC_RAM; devinfo->disk = drive->disk; return register_cdrom(devinfo); @@ -2932,7 +2925,7 @@ struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = &info->devinfo; struct atapi_capabilities_page cap; - int nslots = 1, mrw_write = 0, ram_write = 0; + int nslots = 1; if (drive->media == ide_optical) { CDROM_CONFIG_FLAGS(drive)->mo_drive = 1; @@ -2961,17 +2954,6 @@ if (ide_cdrom_get_capabilities(drive, &cap)) return 0; - if (!cdrom_is_mrw(cdi, &mrw_write)) { - CDROM_CONFIG_FLAGS(drive)->mrw = 1; - if (mrw_write) { - CDROM_CONFIG_FLAGS(drive)->mrw_w = 1; - CDROM_CONFIG_FLAGS(drive)->ram = 1; - } - } - if (!cdrom_is_random_writable(cdi, &ram_write)) - if (ram_write) - CDROM_CONFIG_FLAGS(drive)->ram = 1; - if (cap.lock == 0) CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1; if (cap.eject) @@ -3050,9 +3032,6 @@ printk(" CD%s%s", (CDROM_CONFIG_FLAGS(drive)->cd_r)? "-R" : "", (CDROM_CONFIG_FLAGS(drive)->cd_rw)? "/RW" : ""); - - if (CDROM_CONFIG_FLAGS(drive)->mrw || CDROM_CONFIG_FLAGS(drive)->mrw_w) - printk(" CD-MR%s", CDROM_CONFIG_FLAGS(drive)->mrw_w ? "W" : ""); if (CDROM_CONFIG_FLAGS(drive)->is_changer) printk(" changer w/%d slots", nslots); diff -Nru a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h --- a/drivers/ide/ide-cd.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/ide/ide-cd.h 2004-06-26 17:09:21 -07:00 @@ -79,8 +79,6 @@ __u8 dvd : 1; /* Drive is a DVD-ROM */ __u8 dvd_r : 1; /* Drive can write DVD-R */ __u8 dvd_ram : 1; /* Drive can write DVD-RAM */ - __u8 mrw : 1; /* drive can read mrw */ - __u8 mrw_w : 1; /* drive can write mrw */ __u8 ram : 1; /* generic WRITE (dvd-ram/mrw) */ __u8 test_write : 1; /* Drive can fake writes */ __u8 supp_disc_present : 1; /* Changer can report exact contents diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c --- a/drivers/ide/ide-disk.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/ide/ide-disk.c 2004-06-26 17:09:17 -07:00 @@ -1334,7 +1334,8 @@ idedisk_pm_flush_cache = ide_pm_state_start_suspend, idedisk_pm_standby, - idedisk_pm_restore_dma = ide_pm_state_start_resume, + idedisk_pm_idle = ide_pm_state_start_resume, + idedisk_pm_restore_dma, }; static void idedisk_complete_power_step (ide_drive_t *drive, struct request *rq, u8 stat, u8 error) @@ -1349,6 +1350,9 @@ case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ rq->pm->pm_step = ide_pm_state_completed; break; + case idedisk_pm_idle: /* Resume step 1 (idle) complete */ + rq->pm->pm_step = idedisk_pm_restore_dma; + break; } } @@ -1372,13 +1376,20 @@ args->command_type = IDE_DRIVE_TASK_NO_DATA; args->handler = &task_no_data_intr; return do_rw_taskfile(drive, args); + case idedisk_pm_standby: /* Suspend step 2 (standby) */ args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1; args->command_type = IDE_DRIVE_TASK_NO_DATA; args->handler = &task_no_data_intr; return do_rw_taskfile(drive, args); - case idedisk_pm_restore_dma: /* Resume step 1 (restore DMA) */ + case idedisk_pm_idle: /* Resume step 1 (idle) */ + args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; + args->command_type = IDE_DRIVE_TASK_NO_DATA; + args->handler = task_no_data_intr; + return do_rw_taskfile(drive, args); + + case idedisk_pm_restore_dma: /* Resume step 2 (restore DMA) */ /* * Right now, all we do is call hwif->ide_dma_check(drive), * we could be smarter and check for current xfer_speed diff -Nru a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c --- a/drivers/ide/ide-proc.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/ide/ide-proc.c 2004-06-26 17:09:18 -07:00 @@ -321,7 +321,6 @@ case ide_cy82c693: name = "cy82c693"; break; case ide_4drives: name = "4drives"; break; case ide_pmac: name = "mac-io"; break; - case ide_pc9800: name = "pc9800"; break; default: name = "(unknown)"; break; } len = sprintf(page, "%s\n", name); diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c --- a/drivers/ide/ide-tape.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/ide/ide-tape.c 2004-06-26 17:09:17 -07:00 @@ -2674,7 +2674,7 @@ return __idetape_kmalloc_stage(tape, 0, 0); } -static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char *buf, int n) +static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char __user *buf, int n) { struct idetape_bh *bh = tape->bh; int count; @@ -2701,7 +2701,7 @@ tape->bh = bh; } -static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape_stage_t *stage, int n) +static void idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, idetape_stage_t *stage, int n) { struct idetape_bh *bh = tape->bh; int count; @@ -3610,6 +3610,7 @@ { idetape_tape_t *tape = drive->driver_data; idetape_config_t config; + void __user *argp = (void __user *)arg; #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 4) @@ -3617,7 +3618,7 @@ #endif /* IDETAPE_DEBUG_LOG */ switch (cmd) { case 0x0340: - if (copy_from_user ((char *) &config, (char *) arg, sizeof (idetape_config_t))) + if (copy_from_user(&config, argp, sizeof (idetape_config_t))) return -EFAULT; tape->best_dsc_rw_frequency = config.dsc_rw_frequency; tape->max_stages = config.nr_stages; @@ -3625,7 +3626,7 @@ case 0x0350: config.dsc_rw_frequency = (int) tape->best_dsc_rw_frequency; config.nr_stages = tape->max_stages; - if (copy_to_user((char *) arg, (char *) &config, sizeof (idetape_config_t))) + if (copy_to_user(argp, &config, sizeof (idetape_config_t))) return -EFAULT; break; default: @@ -3747,7 +3748,7 @@ * will no longer hit performance. * This is not applicable to Onstream. */ -static ssize_t idetape_chrdev_read (struct file *file, char *buf, +static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, size_t count, loff_t *ppos) { ide_drive_t *drive = file->private_data; @@ -3810,7 +3811,7 @@ return actually_read; } -static ssize_t idetape_chrdev_write (struct file *file, const char *buf, +static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos) { ide_drive_t *drive = file->private_data; @@ -4127,6 +4128,7 @@ struct mtget mtget; struct mtpos mtpos; int block_offset = 0, position = tape->first_frame_position; + void __user *argp = (void __user *)arg; #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 3) @@ -4146,7 +4148,7 @@ } switch (cmd) { case MTIOCTOP: - if (copy_from_user((char *) &mtop, (char *) arg, sizeof (struct mtop))) + if (copy_from_user(&mtop, argp, sizeof (struct mtop))) return -EFAULT; return (idetape_mtioctop(drive,mtop.mt_op,mtop.mt_count)); case MTIOCGET: @@ -4157,12 +4159,12 @@ if (tape->drv_write_prot) { mtget.mt_gstat |= GMT_WR_PROT(0xffffffff); } - if (copy_to_user((char *) arg,(char *) &mtget, sizeof(struct mtget))) + if (copy_to_user(argp, &mtget, sizeof(struct mtget))) return -EFAULT; return 0; case MTIOCPOS: mtpos.mt_blkno = position / tape->user_bs_factor - block_offset; - if (copy_to_user((char *) arg,(char *) &mtpos, sizeof(struct mtpos))) + if (copy_to_user(argp, &mtpos, sizeof(struct mtpos))) return -EFAULT; return 0; default: diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c --- a/drivers/ide/ide-taskfile.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/ide/ide-taskfile.c 2004-06-26 17:09:15 -07:00 @@ -53,12 +53,6 @@ #define DEBUG_TASKFILE 0 /* unset when fixed */ -#if DEBUG_TASKFILE -#define DTF(x...) printk(x) -#else -#define DTF(x...) -#endif - static void ata_bswap_data (void *buffer, int wcount) { u16 *p = buffer; @@ -165,7 +159,7 @@ hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); -#ifdef CONFIG_IDE_TASKFILE_IO + if (task->handler != NULL) { if (task->prehandler != NULL) { hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); @@ -175,14 +169,6 @@ ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); return ide_started; } -#else - if (task->handler != NULL) { - ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); - if (task->prehandler != NULL) - return task->prehandler(drive, task->rq); - return ide_started; - } -#endif if (!drive->using_dma) return ide_stopped; @@ -283,8 +269,6 @@ local_irq_enable(); if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { - DTF("%s: command opcode 0x%02x\n", drive->name, - args->tfRegister[IDE_COMMAND_OFFSET]); return DRIVER(drive)->error(drive, "task_no_data_intr", stat); /* calls ide_end_drive_cmd */ } @@ -296,6 +280,29 @@ EXPORT_SYMBOL(task_no_data_intr); +static void task_buffer_sectors(ide_drive_t *drive, struct request *rq, + unsigned nsect, unsigned rw) +{ + char *buf = rq->buffer + blk_rq_offset(rq); + + rq->sector += nsect; + rq->current_nr_sectors -= nsect; + rq->nr_sectors -= nsect; + __task_sectors(drive, buf, nsect, rw); +} + +static inline void task_buffer_multi_sectors(ide_drive_t *drive, + struct request *rq, unsigned rw) +{ + unsigned int msect = drive->mult_count, nsect; + + nsect = rq->current_nr_sectors; + if (nsect > msect) + nsect = msect; + + task_buffer_sectors(drive, rq, nsect, rw); +} + /* * old taskfile PIO handlers, to be killed as soon as possible. */ @@ -308,7 +315,6 @@ { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); - char *pBuf = NULL; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) { @@ -316,28 +322,18 @@ return DRIVER(drive)->error(drive, "task_in_intr", stat); } if (!(stat & BUSY_STAT)) { - DTF("task_in_intr to Soon wait for next interrupt\n"); - if (HWGROUP(drive)->handler == NULL) - ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); + ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); return ide_started; } } - pBuf = rq->buffer + task_rq_offset(rq); - DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n", - pBuf, (int) rq->current_nr_sectors, stat); - taskfile_input_data(drive, pBuf, SECTOR_WORDS); + task_buffer_sectors(drive, rq, 1, IDE_PIO_IN); /* FIXME: check drive status */ - if (--rq->current_nr_sectors <= 0) + if (!rq->current_nr_sectors) if (!DRIVER(drive)->end_request(drive, 1, 0)) return ide_stopped; - /* - * ERM, it is techincally legal to leave/exit here but it makes - * a mess of the code ... - */ - if (HWGROUP(drive)->handler == NULL) - ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); + ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); return ide_started; } @@ -350,9 +346,6 @@ { ide_hwif_t *hwif = HWIF(drive); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; - unsigned int msect = drive->mult_count; - unsigned int nsect; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) { @@ -360,32 +353,19 @@ return DRIVER(drive)->error(drive, "task_mulin_intr", stat); } /* no data yet, so wait for another interrupt */ - if (HWGROUP(drive)->handler == NULL) - ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL); + ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL); return ide_started; } - do { - nsect = rq->current_nr_sectors; - if (nsect > msect) - nsect = msect; - pBuf = rq->buffer + task_rq_offset(rq); - DTF("Multiread: %p, nsect: %d, msect: %d, " \ - " rq->current_nr_sectors: %d\n", - pBuf, nsect, msect, rq->current_nr_sectors); - taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); - rq->errors = 0; - rq->current_nr_sectors -= nsect; - msect -= nsect; + task_buffer_multi_sectors(drive, rq, IDE_PIO_IN); - /* FIXME: check drive status */ - if (!rq->current_nr_sectors) { - if (!DRIVER(drive)->end_request(drive, 1, 0)) - return ide_stopped; - } - } while (msect); - if (HWGROUP(drive)->handler == NULL) - ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL); + /* FIXME: check drive status */ + if (!rq->current_nr_sectors) { + DRIVER(drive)->end_request(drive, 1, 0); + return ide_stopped; + } + + ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL); return ide_started; } @@ -407,8 +387,9 @@ return startstop; } /* For Write_sectors we need to stuff the first sector */ - taskfile_output_data(drive, rq->buffer + task_rq_offset(rq), SECTOR_WORDS); - rq->current_nr_sectors--; + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); + return ide_started; } @@ -423,7 +404,6 @@ { ide_hwif_t *hwif = HWIF(drive); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) { @@ -437,16 +417,9 @@ if (!DRIVER(drive)->end_request(drive, 1, 0)) return ide_stopped; if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { - rq = HWGROUP(drive)->rq; - pBuf = rq->buffer + task_rq_offset(rq); - DTF("write: %p, rq->current_nr_sectors: %d\n", - pBuf, (int) rq->current_nr_sectors); - taskfile_output_data(drive, pBuf, SECTOR_WORDS); - rq->errors = 0; - rq->current_nr_sectors--; + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); } - if (HWGROUP(drive)->handler == NULL) - ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); return ide_started; } @@ -454,7 +427,6 @@ ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq) { - ide_task_t *args = rq->special; ide_startstop_t startstop; if (ide_wait_stat(&startstop, drive, DATA_READY, @@ -472,28 +444,22 @@ } } - /* - * WARNING :: if the drive as not acked good status we may not - * move the DATA-TRANSFER T-Bar as BSY != 0. - */ - return args->handler(drive); + ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); + task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); + + return ide_started; } EXPORT_SYMBOL(pre_task_mulout_intr); /* * Handler for command write multiple - * Called directly from execute_drive_cmd for the first bunch of sectors, - * afterwards only by the ISR */ ide_startstop_t task_mulout_intr (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; - unsigned int msect = drive->mult_count; - unsigned int nsect; if (!OK_STAT(stat, DATA_READY, BAD_R_STAT) || !rq->current_nr_sectors) { if (stat & (ERR_STAT|DRQ_STAT)) { @@ -505,47 +471,58 @@ return ide_stopped; } /* no data yet, so wait for another interrupt */ - if (HWGROUP(drive)->handler == NULL) - ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); + ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); return ide_started; } - if (HWGROUP(drive)->handler != NULL) { - unsigned long lflags; - spin_lock_irqsave(&ide_lock, lflags); - HWGROUP(drive)->handler = NULL; - del_timer(&HWGROUP(drive)->timer); - spin_unlock_irqrestore(&ide_lock, lflags); - } + task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); + ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); + + return ide_started; +} + +EXPORT_SYMBOL(task_mulout_intr); + +#else /* !CONFIG_IDE_TASKFILE_IO */ + +static void task_sectors(ide_drive_t *drive, struct request *rq, + unsigned nsect, unsigned rw) +{ + if (rq->cbio) { /* fs request */ + rq->errors = 0; + task_bio_sectors(drive, rq, nsect, rw); + } else /* task request */ + task_buffer_sectors(drive, rq, nsect, rw); +} + +static inline void task_bio_multi_sectors(ide_drive_t *drive, + struct request *rq, unsigned rw) +{ + unsigned int nsect, msect = drive->mult_count; do { nsect = rq->current_nr_sectors; if (nsect > msect) nsect = msect; - pBuf = rq->buffer + task_rq_offset(rq); - DTF("Multiwrite: %p, nsect: %d, msect: %d, " \ - "rq->current_nr_sectors: %ld\n", - pBuf, nsect, msect, rq->current_nr_sectors); - msect -= nsect; - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - rq->current_nr_sectors -= nsect; - /* FIXME: check drive status */ - if (!rq->current_nr_sectors) { - if (!DRIVER(drive)->end_request(drive, 1, 0)) - if (!rq->bio) - return ide_stopped; - } + task_bio_sectors(drive, rq, nsect, rw); + + if (!rq->nr_sectors) + msect = 0; + else + msect -= nsect; } while (msect); - rq->errors = 0; - if (HWGROUP(drive)->handler == NULL) - ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); - return ide_started; } -EXPORT_SYMBOL(task_mulout_intr); - -#else /* !CONFIG_IDE_TASKFILE_IO */ +static void task_multi_sectors(ide_drive_t *drive, + struct request *rq, unsigned rw) +{ + if (rq->cbio) { /* fs request */ + rq->errors = 0; + task_bio_multi_sectors(drive, rq, rw); + } else /* task request */ + task_buffer_multi_sectors(drive, rq, rw); +} static u8 wait_drive_not_busy(ide_drive_t *drive) { @@ -573,19 +550,16 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; - u8 stat, good_stat; + u8 stat = HWIF(drive)->INB(IDE_STATUS_REG); - good_stat = DATA_READY; - stat = HWIF(drive)->INB(IDE_STATUS_REG); -check_status: - if (!OK_STAT(stat, good_stat, BAD_R_STAT)) { + if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (stat & (ERR_STAT | DRQ_STAT)) return DRIVER(drive)->error(drive, __FUNCTION__, stat); /* BUSY_STAT: No data yet, so wait for another IRQ. */ ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); return ide_started; } - +finish_rq: /* * Complete previously submitted bios (if any). * Status was already verifyied. @@ -595,18 +569,18 @@ return ide_stopped; /* Complete rq->buffer based request (ioctls). */ if (!rq->bio && !rq->nr_sectors) { - ide_end_drive_cmd(drive, stat, HWIF(drive)->INB(IDE_ERROR_REG)); + DRIVER(drive)->end_request(drive, 1, 0); return ide_stopped; } - rq->errors = 0; task_sectors(drive, rq, 1, IDE_PIO_IN); /* If it was the last datablock check status and finish transfer. */ if (!rq->nr_sectors) { - good_stat = 0; stat = wait_drive_not_busy(drive); - goto check_status; + if (!OK_STAT(stat, 0, BAD_R_STAT)) + return DRIVER(drive)->error(drive, __FUNCTION__, stat); + goto finish_rq; } /* Still data left to transfer. */ @@ -622,21 +596,16 @@ ide_startstop_t task_mulin_intr (ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; - unsigned int msect = drive->mult_count; - unsigned int nsect; - u8 stat, good_stat; + u8 stat = HWIF(drive)->INB(IDE_STATUS_REG); - good_stat = DATA_READY; - stat = HWIF(drive)->INB(IDE_STATUS_REG); -check_status: - if (!OK_STAT(stat, good_stat, BAD_R_STAT)) { + if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (stat & (ERR_STAT | DRQ_STAT)) return DRIVER(drive)->error(drive, __FUNCTION__, stat); /* BUSY_STAT: No data yet, so wait for another IRQ. */ ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL); return ide_started; } - +finish_rq: /* * Complete previously submitted bios (if any). * Status was already verifyied. @@ -646,29 +615,18 @@ return ide_stopped; /* Complete rq->buffer based request (ioctls). */ if (!rq->bio && !rq->nr_sectors) { - ide_end_drive_cmd(drive, stat, HWIF(drive)->INB(IDE_ERROR_REG)); + DRIVER(drive)->end_request(drive, 1, 0); return ide_stopped; } - rq->errors = 0; - do { - nsect = rq->current_nr_sectors; - if (nsect > msect) - nsect = msect; - - task_sectors(drive, rq, nsect, IDE_PIO_IN); - - if (!rq->nr_sectors) - msect = 0; - else - msect -= nsect; - } while (msect); + task_multi_sectors(drive, rq, IDE_PIO_IN); /* If it was the last datablock check status and finish transfer. */ if (!rq->nr_sectors) { - good_stat = 0; stat = wait_drive_not_busy(drive); - goto check_status; + if (!OK_STAT(stat, 0, BAD_R_STAT)) + return DRIVER(drive)->error(drive, __FUNCTION__, stat); + goto finish_rq; } /* Still data left to transfer. */ @@ -712,14 +670,12 @@ return ide_stopped; /* Complete rq->buffer based request (ioctls). */ if (!rq->bio && !rq->nr_sectors) { - ide_end_drive_cmd(drive, stat, HWIF(drive)->INB(IDE_ERROR_REG)); + DRIVER(drive)->end_request(drive, 1, 0); return ide_stopped; } /* Still data left to transfer. */ ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); - - rq->errors = 0; task_sectors(drive, rq, 1, IDE_PIO_OUT); return ide_started; @@ -751,8 +707,6 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; - unsigned int msect = drive->mult_count; - unsigned int nsect; u8 stat; stat = HWIF(drive)->INB(IDE_STATUS_REG); @@ -781,26 +735,13 @@ return ide_stopped; /* Complete rq->buffer based request (ioctls). */ if (!rq->bio && !rq->nr_sectors) { - ide_end_drive_cmd(drive, stat, HWIF(drive)->INB(IDE_ERROR_REG)); + DRIVER(drive)->end_request(drive, 1, 0); return ide_stopped; } /* Still data left to transfer. */ ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL); - - rq->errors = 0; - do { - nsect = rq->current_nr_sectors; - if (nsect > msect) - nsect = msect; - - task_sectors(drive, rq, nsect, IDE_PIO_OUT); - - if (!rq->nr_sectors) - msect = 0; - else - msect -= nsect; - } while (msect); + task_multi_sectors(drive, rq, IDE_PIO_OUT); return ide_started; } @@ -1201,6 +1142,14 @@ void debug_taskfile(drive, task); #endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */ + if (task->data_phase == TASKFILE_MULTI_IN || + task->data_phase == TASKFILE_MULTI_OUT) { + if (!drive->mult_count) { + printk(KERN_ERR "%s: multimode not set!\n", drive->name); + return ide_stopped; + } + } + /* * (ks) Check taskfile in/out flags. * If set, then execute as it is defined. @@ -1333,7 +1282,6 @@ ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; int retries = 5; if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { @@ -1349,12 +1297,9 @@ return DRIVER(drive)->error(drive, "flagged_task_in_intr (unexpected data phase)", stat); } - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Read - rq->current_nr_sectors: %d, status: %02x\n", (int) rq->current_nr_sectors, stat); - - taskfile_input_data(drive, pBuf, SECTOR_WORDS); + task_buffer_sectors(drive, rq, 1, IDE_PIO_IN); - if (--rq->current_nr_sectors != 0) { + if (rq->current_nr_sectors) { /* * (ks) We don't know which command was executed. * So, we wait the 'WORSTCASE' value. @@ -1378,13 +1323,7 @@ ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; int retries = 5; - unsigned int msect, nsect; - - msect = drive->mult_count; - if (msect == 0) - return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (multimode not set)", stat); if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (stat & ERR_STAT) { @@ -1399,15 +1338,8 @@ return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (unexpected data phase)", stat); } - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - - DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n", - pBuf, nsect, rq->current_nr_sectors); + task_buffer_multi_sectors(drive, rq, IDE_PIO_IN); - taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); - - rq->current_nr_sectors -= nsect; if (rq->current_nr_sectors != 0) { /* * (ks) We don't know which command was executed. @@ -1441,8 +1373,7 @@ return startstop; } - taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); - --rq->current_nr_sectors; + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); return ide_started; } @@ -1452,7 +1383,6 @@ ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; if (!OK_STAT(stat, DRIVE_READY, BAD_W_STAT)) return DRIVER(drive)->error(drive, "flagged_task_out_intr", stat); @@ -1472,12 +1402,7 @@ return DRIVER(drive)->error(drive, "flagged_task_out_intr (unexpected data phase)", stat); } - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Write - rq->current_nr_sectors: %d, status: %02x\n", - (int) rq->current_nr_sectors, stat); - - taskfile_output_data(drive, pBuf, SECTOR_WORDS); - --rq->current_nr_sectors; + task_buffer_sectors(drive, rq, 1, IDE_PIO_OUT); /* * (ks) We don't know which command was executed. @@ -1490,15 +1415,7 @@ ide_startstop_t flagged_pre_task_mulout_intr (ide_drive_t *drive, struct request *rq) { - ide_hwif_t *hwif = HWIF(drive); - u8 stat = hwif->INB(IDE_STATUS_REG); - char *pBuf = NULL; ide_startstop_t startstop; - unsigned int msect, nsect; - - msect = drive->mult_count; - if (msect == 0) - return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (multimode not set)", stat); if (ide_wait_stat(&startstop, drive, DATA_READY, BAD_W_STAT, WAIT_DRQ)) { @@ -1506,14 +1423,7 @@ return startstop; } - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", - pBuf, nsect, rq->current_nr_sectors); - - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - - rq->current_nr_sectors -= nsect; + task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); return ide_started; } @@ -1523,12 +1433,6 @@ ide_hwif_t *hwif = HWIF(drive); u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; - char *pBuf = NULL; - unsigned int msect, nsect; - - msect = drive->mult_count; - if (msect == 0) - return DRIVER(drive)->error(drive, "flagged_task_mulout_intr (multimode not set)", stat); if (!OK_STAT(stat, DRIVE_READY, BAD_W_STAT)) return DRIVER(drive)->error(drive, "flagged_task_mulout_intr", stat); @@ -1548,13 +1452,7 @@ return DRIVER(drive)->error(drive, "flagged_task_mulout_intr (unexpected data phase)", stat); } - nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; - pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); - DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", - pBuf, nsect, rq->current_nr_sectors); - - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - rq->current_nr_sectors -= nsect; + task_buffer_multi_sectors(drive, rq, IDE_PIO_OUT); /* * (ks) We don't know which command was executed. diff -Nru a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c --- a/drivers/ide/legacy/hd.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/ide/legacy/hd.c 2004-06-26 17:09:15 -07:00 @@ -660,7 +660,7 @@ unsigned int cmd, unsigned long arg) { struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data; - struct hd_geometry *loc = (struct hd_geometry *) arg; + struct hd_geometry __user *loc = (struct hd_geometry __user *) arg; struct hd_geometry g; if (cmd != HDIO_GETGEO) diff -Nru a/drivers/ide/legacy/hd98.c b/drivers/ide/legacy/hd98.c --- a/drivers/ide/legacy/hd98.c 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,883 +0,0 @@ -/* - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This is the low-level hd interrupt support. It traverses the - * request-list, using interrupts to jump between functions. As - * all the functions are called within interrupts, we may not - * sleep. Special care is recommended. - * - * modified by Drew Eckhardt to check nr of hd's from the CMOS. - * - * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug - * in the early extended-partition checks and added DM partitions - * - * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", - * and general streamlining by Mark Lord. - * - * Removed 99% of above. Use Mark's ide driver for those options. - * This is now a lightweight ST-506 driver. (Paul Gortmaker) - * - * Modified 1995 Russell King for ARM processor. - * - * Bugfix: max_sectors must be <= 255 or the wheels tend to come - * off in a hurry once you queue things up - Paul G. 02/2001 - */ - -/* Uncomment the following if you want verbose error reports. */ -/* #define VERBOSE_ERRORS */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* CMOS defines */ -#include -#include -#include - -#define REALLY_SLOW_IO -#include -#include -#include - -#include "io_ports.h" - -#ifdef __arm__ -#undef HD_IRQ -#endif -#include -#ifdef __arm__ -#define HD_IRQ IRQ_HARDDISK -#endif - -/* Hd controller regster ports */ - -#define HD_DATA 0x640 /* _CTL when writing */ -#define HD_ERROR 0x642 /* see err-bits */ -#define HD_NSECTOR 0x644 /* nr of sectors to read/write */ -#define HD_SECTOR 0x646 /* starting sector */ -#define HD_LCYL 0x648 /* starting cylinder */ -#define HD_HCYL 0x64a /* high byte of starting cyl */ -#define HD_CURRENT 0x64c /* 101dhhhh , d=drive, hhhh=head */ -#define HD_STATUS 0x64e /* see status-bits */ -#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ -#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ -#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ - -#define HD_CMD 0x74c /* used for resets */ -#define HD_ALTSTATUS 0x74c /* same as HD_STATUS but doesn't clear irq */ - -/* Bits of HD_STATUS */ -#define ERR_STAT 0x01 -#define INDEX_STAT 0x02 -#define ECC_STAT 0x04 /* Corrected error */ -#define DRQ_STAT 0x08 -#define SEEK_STAT 0x10 -#define SERVICE_STAT SEEK_STAT -#define WRERR_STAT 0x20 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits for HD_ERROR */ -#define MARK_ERR 0x01 /* Bad address mark */ -#define TRK0_ERR 0x02 /* couldn't find track 0 */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* media change request */ -#define ID_ERR 0x10 /* ID field not found */ -#define MC_ERR 0x20 /* media changed */ -#define ECC_ERR 0x40 /* Uncorrectable ECC error */ -#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ -#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ - -static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED; -static struct request_queue *hd_queue; - -#define CURRENT elv_next_request(hd_queue) - -#define TIMEOUT_VALUE (6*HZ) -#define HD_DELAY 0 - -#define MAX_ERRORS 16 /* Max read/write errors/sector */ -#define RESET_FREQ 8 /* Reset controller every 8th retry */ -#define RECAL_FREQ 4 /* Recalibrate every 4th retry */ -#define MAX_HD 2 - -#define STAT_OK (READY_STAT|SEEK_STAT) -#define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK) - -static void recal_intr(void); -static void bad_rw_intr(void); - -static int reset; -static int hd_error; - -/* - * This struct defines the HD's and their types. - */ -struct hd_i_struct { - unsigned int head,sect,cyl,wpcom,lzone,ctl; - int unit; - int recalibrate; - int special_op; -}; - -#ifdef HD_TYPE -static struct hd_i_struct hd_info[] = { HD_TYPE }; -static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct))); -#else -static struct hd_i_struct hd_info[MAX_HD]; -static int NR_HD; -#endif - -static struct gendisk *hd_gendisk[MAX_HD]; - -static struct timer_list device_timer; - -#define TIMEOUT_VALUE (6*HZ) - -#define SET_TIMER \ - do { \ - mod_timer(&device_timer, jiffies + TIMEOUT_VALUE); \ - } while (0) - -static void (*do_hd)(void) = NULL; -#define SET_HANDLER(x) \ -if ((do_hd = (x)) != NULL) \ - SET_TIMER; \ -else \ - del_timer(&device_timer); - - -#if (HD_DELAY > 0) -unsigned long last_req; - -unsigned long read_timer(void) -{ - extern spinlock_t i8253_lock; - unsigned long t, flags; - int i; - - spin_lock_irqsave(&i8253_lock, flags); - t = jiffies * 11932; - outb_p(0, PIT_MODE); - i = inb_p(PIT_CH0); - i |= inb(PIT_CH0) << 8; - spin_unlock_irqrestore(&i8253_lock, flags); - return(t - i); -} -#endif - -void __init hd_setup(char *str, int *ints) -{ - int hdind = 0; - - if (ints[0] != 3) - return; - if (hd_info[0].head != 0) - hdind=1; - hd_info[hdind].head = ints[2]; - hd_info[hdind].sect = ints[3]; - hd_info[hdind].cyl = ints[1]; - hd_info[hdind].wpcom = 0; - hd_info[hdind].lzone = ints[1]; - hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0); - NR_HD = hdind+1; -} - -static void dump_status (const char *msg, unsigned int stat) -{ - char *name = CURRENT ? - CURRENT->rq_dev->bd_disk->disk_name : - "hd?"; -#ifdef VERBOSE_ERRORS - printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff); - if (stat & BUSY_STAT) printk("Busy "); - if (stat & READY_STAT) printk("DriveReady "); - if (stat & WRERR_STAT) printk("WriteFault "); - if (stat & SEEK_STAT) printk("SeekComplete "); - if (stat & DRQ_STAT) printk("DataRequest "); - if (stat & ECC_STAT) printk("CorrectedError "); - if (stat & INDEX_STAT) printk("Index "); - if (stat & ERR_STAT) printk("Error "); - printk("}\n"); - if ((stat & ERR_STAT) == 0) { - hd_error = 0; - } else { - hd_error = inb(HD_ERROR); - printk("%s: %s: error=0x%02x { ", name, msg, hd_error & 0xff); - if (hd_error & BBD_ERR) printk("BadSector "); - if (hd_error & ECC_ERR) printk("UncorrectableError "); - if (hd_error & ID_ERR) printk("SectorIdNotFound "); - if (hd_error & ABRT_ERR) printk("DriveStatusError "); - if (hd_error & TRK0_ERR) printk("TrackZeroNotFound "); - if (hd_error & MARK_ERR) printk("AddrMarkNotFound "); - printk("}"); - if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) { - printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL), - inb(HD_CURRENT) & 0xf, inb(HD_SECTOR)); - if (CURRENT) - printk(", sector=%ld", CURRENT->sector); - } - printk("\n"); - } -#else - printk("%s: %s: status=0x%02x.\n", name, msg, stat & 0xff); - if ((stat & ERR_STAT) == 0) { - hd_error = 0; - } else { - hd_error = inb(HD_ERROR); - printk("%s: %s: error=0x%02x.\n", name, msg, hd_error & 0xff); - } -#endif -} - -void check_status(void) -{ - int i = inb(HD_STATUS); - - if (!OK_STATUS(i)) { - dump_status("check_status", i); - bad_rw_intr(); - } -} - -static int controller_busy(void) -{ - int retries = 100000; - unsigned char status; - - do { - status = inb(HD_STATUS); - } while ((status & BUSY_STAT) && --retries); - return status; -} - -static int status_ok(void) -{ - unsigned char status = inb(HD_STATUS); - - if (status & BUSY_STAT) - return 1; /* Ancient, but does it make sense??? */ - if (status & WRERR_STAT) - return 0; - if (!(status & READY_STAT)) - return 0; - if (!(status & SEEK_STAT)) - return 0; - return 1; -} - -static int controller_ready(unsigned int drive, unsigned int head) -{ - int retry = 100; - - do { - if (controller_busy() & BUSY_STAT) - return 0; - outb(0xA0 | (drive<<4) | head, HD_CURRENT); - if (status_ok()) - return 1; - } while (--retry); - return 0; -} - -static void hd_out(struct hd_i_struct *disk, - unsigned int nsect, - unsigned int sect, - unsigned int head, - unsigned int cyl, - unsigned int cmd, - void (*intr_addr)(void)) -{ - unsigned short port; - -#if (HD_DELAY > 0) - while (read_timer() - last_req < HD_DELAY) - /* nothing */; -#endif - if (reset) - return; - if (!controller_ready(disk->unit, head)) { - reset = 1; - return; - } - SET_HANDLER(intr_addr); - outb(disk->ctl,HD_CMD); - port=HD_DATA + 2; - outb(disk->wpcom>>2, port); port += 2; - outb(nsect, port); port += 2; - outb(sect, port); port += 2; - outb(cyl, port); port += 2; - outb(cyl>>8, port); port += 2; - outb(0xA0|(disk->unit<<4)|head, port); port += 2; - outb(cmd, port); -} - -static void hd_request (void); - -static int drive_busy(void) -{ - unsigned int i; - unsigned char c; - - for (i = 0; i < 500000 ; i++) { - c = inb(HD_STATUS); - if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK) - return 0; - } - dump_status("reset timed out", c); - return 1; -} - -static void reset_controller(void) -{ - int i; - - outb(4,HD_CMD); - for(i = 0; i < 1000; i++) barrier(); - outb(hd_info[0].ctl & 0x0f,HD_CMD); - for(i = 0; i < 1000; i++) barrier(); - if (drive_busy()) - printk("hd: controller still busy\n"); - else if ((hd_error = inb(HD_ERROR)) != 1) - printk("hd: controller reset failed: %02x\n",hd_error); -} - -static void reset_hd(void) -{ - static int i; - -repeat: - if (reset) { - reset = 0; - i = -1; - reset_controller(); - } else { - check_status(); - if (reset) - goto repeat; - } - if (++i < NR_HD) { - struct hd_i_struct *disk = &hd_info[i]; - disk->special_op = disk->recalibrate = 1; - hd_out(disk, disk->sect, disk->sect, disk->head-1, - disk->cyl, WIN_SPECIFY, &reset_hd); - if (reset) - goto repeat; - } else - hd_request(); -} - -/* - * Ok, don't know what to do with the unexpected interrupts: on some machines - * doing a reset and a retry seems to result in an eternal loop. Right now I - * ignore it, and just set the timeout. - * - * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the - * drive enters "idle", "standby", or "sleep" mode, so if the status looks - * "good", we just ignore the interrupt completely. - */ -void unexpected_hd_interrupt(void) -{ - unsigned int stat = inb(HD_STATUS); - - if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { - dump_status ("unexpected interrupt", stat); - SET_TIMER; - } -} - -/* - * bad_rw_intr() now tries to be a bit smarter and does things - * according to the error returned by the controller. - * -Mika Liljeberg (liljeber@cs.Helsinki.FI) - */ -static void bad_rw_intr(void) -{ - struct request *req = CURRENT; - struct hd_i_struct *disk; - - if (!req) - return; - disk = req->rq_disk->private_data; - if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { - end_request(req, 0); - disk->special_op = disk->recalibrate = 1; - } else if (req->errors % RESET_FREQ == 0) - reset = 1; - else if ((hd_error & TRK0_ERR) || req->errors % RECAL_FREQ == 0) - disk->special_op = disk->recalibrate = 1; - /* Otherwise just retry */ -} - -static inline int wait_DRQ(void) -{ - int retries = 100000, stat; - - while (--retries > 0) - if ((stat = inb(HD_STATUS)) & DRQ_STAT) - return 0; - dump_status("wait_DRQ", stat); - return -1; -} - -static void read_intr(void) -{ - int i, retries = 100000; - struct request *req; - - do { - i = (unsigned) inb(HD_STATUS); - if (i & BUSY_STAT) - continue; - if (!OK_STATUS(i)) - break; - if (i & DRQ_STAT) - goto ok_to_read; - } while (--retries > 0); - dump_status("read_intr", i); - bad_rw_intr(); - hd_request(); - return; -ok_to_read: - req = CURRENT; - insw(HD_DATA,req->buffer,256); - req->sector++; - req->buffer += 512; - req->errors = 0; - i = --req->nr_sectors; - --req->current_nr_sectors; -#ifdef DEBUG - printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", - req->rq_disk->disk_name, req->sector, req->nr_sectors, - req->buffer+512); -#endif - if (req->current_nr_sectors <= 0) - end_request(req, 1); - if (i > 0) { - SET_HANDLER(&read_intr); - return; - } - (void) inb(HD_STATUS); -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - if (CURRENT) - hd_request(); - return; -} - -static void write_intr(void) -{ - int i; - int retries = 100000; - struct request *req = CURRENT; - - do { - i = (unsigned) inb(HD_STATUS); - if (i & BUSY_STAT) - continue; - if (!OK_STATUS(i)) - break; - if ((req->nr_sectors <= 1) || (i & DRQ_STAT)) - goto ok_to_write; - } while (--retries > 0); - dump_status("write_intr", i); - bad_rw_intr(); - hd_request(); - return; -ok_to_write: - req->sector++; - i = --req->nr_sectors; - --req->current_nr_sectors; - req->buffer += 512; - if (!i || (req->bio && req->current_nr_sectors < 1)) - end_request(req, 1); - if (i > 0) { - SET_HANDLER(&write_intr); - outsw(HD_DATA,req->buffer,256); - local_irq_enable(); - } else { -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - hd_request(); - } - return; -} - -static void recal_intr(void) -{ - check_status(); -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - hd_request(); -} - -/* - * This is another of the error-routines I don't know what to do with. The - * best idea seems to just set reset, and start all over again. - */ -static void hd_times_out(unsigned long dummy) -{ - do_hd = NULL; - - if (!CURRENT) - return; - - disable_irq(HD_IRQ); - local_irq_enable(); - reset = 1; - printk("%s: timeout\n", CURRENT->rq_disk->disk_name); - if (++CURRENT->errors >= MAX_ERRORS) { -#ifdef DEBUG - printk("%s: too many errors\n", CURRENT->rq_disk->disk_name); -#endif - end_request(CURRENT, 0); - } - local_irq_disable(); - hd_request(); - enable_irq(HD_IRQ); -} - -int do_special_op(struct hd_i_struct *disk, struct request *req) -{ - if (disk->recalibrate) { - disk->recalibrate = 0; - hd_out(disk, disk->sect,0,0,0,WIN_RESTORE,&recal_intr); - return reset; - } - if (disk->head > 16) { - printk ("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); - end_request(req, 0); - } - disk->special_op = 0; - return 1; -} - -/* - * The driver enables interrupts as much as possible. In order to do this, - * (a) the device-interrupt is disabled before entering hd_request(), - * and (b) the timeout-interrupt is disabled before the sti(). - * - * Interrupts are still masked (by default) whenever we are exchanging - * data/cmds with a drive, because some drives seem to have very poor - * tolerance for latency during I/O. The IDE driver has support to unmask - * interrupts for non-broken hardware, so use that driver if required. - */ -static void hd_request(void) -{ - unsigned int block, nsect, sec, track, head, cyl; - struct hd_i_struct *disk; - struct request *req; - - if (do_hd) - return; -repeat: - del_timer(&device_timer); - local_irq_enable(); - - if (!CURRENT) { - do_hd = NULL; - return; - } - req = CURRENT; - - if (reset) { - local_irq_disable(); - reset_hd(); - return; - } - disk = req->rq_disk->private_data; - block = req->sector; - nsect = req->nr_sectors; - if (block >= get_capacity(req->rq_disk) || - ((block+nsect) > get_capacity(req->rq_disk))) { - printk("%s: bad access: block=%d, count=%d\n", - req->rq_disk->disk_name, block, nsect); - end_request(req, 0); - goto repeat; - } - - if (disk->special_op) { - if (do_special_op(disk, req)) - goto repeat; - return; - } - sec = block % disk->sect + 1; - track = block / disk->sect; - head = track % disk->head; - cyl = track / disk->head; -#ifdef DEBUG - printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n", - req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ", - cyl, head, sec, nsect, req->buffer); -#endif - if (req->flags & REQ_CMD) { - switch (rq_data_dir(req)) { - case READ: - hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr); - if (reset) - goto repeat; - break; - case WRITE: - hd_out(disk,nsect,sec,head,cyl,WIN_WRITE,&write_intr); - if (reset) - goto repeat; - if (wait_DRQ()) { - bad_rw_intr(); - goto repeat; - } - outsw(HD_DATA,req->buffer,256); - break; - default: - printk("unknown hd-command\n"); - end_request(req, 0); - break; - } - } -} - -static void do_hd_request (request_queue_t * q) -{ - disable_irq(HD_IRQ); - hd_request(); - enable_irq(HD_IRQ); -} - -static int hd_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data; - struct hd_geometry *loc = (struct hd_geometry *) arg; - struct hd_geometry g; - - if (cmd != HDIO_GETGEO) - return -EINVAL; - if (!loc) - return -EINVAL; - g.heads = disk->head; - g.sectors = disk->sect; - g.cylinders = disk->cyl; - g.start = get_start_sect(inode->i_bdev); - return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; -} - -/* - * Releasing a block device means we sync() it, so that it can safely - * be forgotten about... - */ - -static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - void (*handler)(void) = do_hd; - - do_hd = NULL; - del_timer(&device_timer); - if (!handler) - handler = unexpected_hd_interrupt; - handler(); - local_irq_enable(); -} - -static struct block_device_operations hd_fops = { - .ioctl = hd_ioctl, -}; - -/* - * This is the hard disk IRQ description. The SA_INTERRUPT in sa_flags - * means we run the IRQ-handler with interrupts disabled: this is bad for - * interrupt latency, but anything else has led to problems on some - * machines. - * - * We enable interrupts in some of the routines after making sure it's - * safe. - */ - -static int __init hd_init(void) -{ - int drive; - if (register_blkdev(HD_MAJOR,"hd")) { - printk("hd: unable to get major %d for hard disk\n",HD_MAJOR); - return -1; - } - hd_queue = blk_init_queue(do_hd_request, &hd_lock); - if (!hd_queue) { - unregister_blkdev(HD_MAJOR,"hd"); - return -1; - } - blk_queue_max_sectors(hd_queue, 255); - init_timer(&device_timer); - device_timer.function = hd_times_out; - blk_queue_hardsect_size(hd_queue, 512); - -#ifdef __i386__ - if (!NR_HD) { - extern struct drive_info drive_info; - unsigned char *BIOS = (unsigned char *) &drive_info; - unsigned long flags; -#ifndef CONFIG_X86_PC9800 - int cmos_disks; -#endif - - for (drive=0 ; drive<2 ; drive++) { - hd_info[drive].cyl = *(unsigned short *) BIOS; - hd_info[drive].head = *(3+BIOS); - hd_info[drive].sect = *(2+BIOS); - hd_info[drive].wpcom = 0; - hd_info[drive].ctl = *(3+BIOS) > 8 ? 8 : 0; - hd_info[drive].lzone = *(unsigned short *) BIOS; - if (hd_info[drive].cyl && NR_HD == drive) - NR_HD++; - BIOS += 6; - } - - } -#endif /* __i386__ */ -#ifdef __arm__ - if (!NR_HD) { - /* We don't know anything about the drive. This means - * that you *MUST* specify the drive parameters to the - * kernel yourself. - */ - printk("hd: no drives specified - use hd=cyl,head,sectors" - " on kernel command line\n"); - } -#endif - if (!NR_HD) - goto out; - - for (drive=0 ; drive < NR_HD ; drive++) { - struct gendisk *disk = alloc_disk(64); - struct hd_i_struct *p = &hd_info[drive]; - if (!disk) - goto Enomem; - disk->major = HD_MAJOR; - disk->first_minor = drive << 6; - disk->fops = &hd_fops; - sprintf(disk->disk_name, "hd%c", 'a'+drive); - disk->private_data = p; - set_capacity(disk, p->head * p->sect * p->cyl); - disk->queue = hd_queue; - p->unit = drive; - hd_gendisk[drive] = disk; - printk ("%s: %luMB, CHS=%d/%d/%d\n", - disk->disk_name, (unsigned long)get_capacity(disk)/2048, - p->cyl, p->head, p->sect); - } - - if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) { - printk("hd: unable to get IRQ%d for the hard disk driver\n", - HD_IRQ); - goto out1; - } - - if (!request_region(HD_DATA, 2, "hd(data)")) { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - NR_HD = 0; - free_irq(HD_IRQ, NULL); - return; - } - - if (!request_region(HD_DATA + 2, 1, "hd")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - goto out2; - } - - if (!request_region(HD_DATA + 4, 1, "hd")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - goto out3; - } - - if (!request_region(HD_DATA + 6, 1, "hd")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - goto out4; - } - - if (!request_region(HD_DATA + 8, 1, "hd")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - goto out5; - } - - if (!request_region(HD_DATA + 10, 1, "hd")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - goto out6; - } - - if (!request_region(HD_DATA + 12, 1, "hd")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - goto out7; - } - - if (!request_region(HD_CMD, 1, "hd(cmd)")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD); - goto out8; - } - - if (!request_region(HD_CMD + 2, 1, "hd(cmd)")) - { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD); - goto out9; - } - - for(drive=0; drive < NR_HD; drive++) - add_disk(hd_gendisk[drive]); - return 0; - -out9: - release_region(HD_CMD, 1); -out8: - release_region(HD_DATA + 12, 1); -out7: - release_region(HD_DATA + 10, 1); -out6: - release_region(HD_DATA + 8, 1); -out5: - release_region(HD_DATA + 6, 1); -out4: - release_region(HD_DATA + 4, 1); -out3: - release_region(HD_DATA + 2, 1); -out2: - release_region(HD_DATA, 2); - free_irq(HD_IRQ, NULL); -out1: - for (drive = 0; drive < NR_HD; drive++) - put_disk(hd_gendisk[drive]); - NR_HD = 0; -out: - del_timer(&device_timer); - unregister_blkdev(HD_MAJOR,"hd"); - blk_cleanup_queue(hd_queue); - return -1; -Enomem: - while (drive--) - put_disk(hd_gendisk[drive]); - goto out; -} - -static int parse_hd_setup (char *line) { - int ints[6]; - - (void) get_options(line, ARRAY_SIZE(ints), ints); - hd_setup(NULL, ints); - - return 1; -} -__setup("hd=", parse_hd_setup); - -module_init(hd_init); diff -Nru a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c --- a/drivers/ide/legacy/ide-cs.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/ide/legacy/ide-cs.c 2004-06-26 17:09:19 -07:00 @@ -199,6 +199,16 @@ } /* ide_detach */ +static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) +{ + hw_regs_t hw; + memset(&hw, 0, sizeof(hw)); + ide_init_hwif_ports(&hw, io, ctl, NULL); + hw.irq = irq; + hw.chipset = ide_pci; + return ide_register_hw(&hw, NULL); +} + /*====================================================================== ide_config() is scheduled to run after a CARD_INSERTION event @@ -210,84 +220,82 @@ #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) -{ - hw_regs_t hw; - memset(&hw, 0, sizeof(hw)); - ide_init_hwif_ports(&hw, io, ctl, NULL); - hw.irq = irq; - hw.chipset = ide_pci; - return ide_register_hw(&hw, NULL); -} - void ide_config(dev_link_t *link) { client_handle_t handle = link->handle; ide_info_t *info = link->priv; tuple_t tuple; - u_short buf[128]; - cisparse_t parse; - config_info_t conf; - cistpl_cftable_entry_t *cfg = &parse.cftable_entry; - cistpl_cftable_entry_t dflt = { 0 }; - int i, pass, last_ret, last_fn, hd, is_kme = 0; + struct { + u_short buf[128]; + cisparse_t parse; + config_info_t conf; + cistpl_cftable_entry_t dflt; + } *stk = 0; + cistpl_cftable_entry_t *cfg; + int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0; unsigned long io_base, ctl_base; DEBUG(0, "ide_config(0x%p)\n", link); - - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + + stk = kmalloc(sizeof(*stk), GFP_KERNEL); + if (!stk) goto err_mem; + memset(stk, 0, sizeof(*stk)); + cfg = &stk->parse.cftable_entry; + + tuple.TupleData = (cisdata_t *)&stk->buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); - link->conf.ConfigBase = parse.config.base; - link->conf.Present = parse.config.rmask[0]; + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse)); + link->conf.ConfigBase = stk->parse.config.base; + link->conf.Present = stk->parse.config.rmask[0]; tuple.DesiredTuple = CISTPL_MANFID; if (!pcmcia_get_first_tuple(handle, &tuple) && !pcmcia_get_tuple_data(handle, &tuple) && - !pcmcia_parse_tuple(handle, &tuple, &parse)) - is_kme = ((parse.manfid.manf == MANFID_KME) && - ((parse.manfid.card == PRODID_KME_KXLC005_A) || - (parse.manfid.card == PRODID_KME_KXLC005_B))); + !pcmcia_parse_tuple(handle, &tuple, &stk->parse)) + is_kme = ((stk->parse.manfid.manf == MANFID_KME) && + ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || + (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); /* Configure card */ link->state |= DEV_CONFIG; /* Not sure if this is right... look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; - + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf)); + link->conf.Vcc = stk->conf.Vcc; + pass = io_base = ctl_base = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry; - if (pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; + if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) goto next_entry; /* Check for matching Vcc, unless we're desperate */ if (!pass) { - if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) goto next_entry; - } else if (dflt.vcc.present & (1<dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) goto next_entry; } } - - if (cfg->vpp1.present & (1<vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = - cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; - else if (dflt.vpp1.present & (1<vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = - dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; - - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; link->conf.ConfigIndex = cfg->index; link->io.BasePort1 = io->win[0].base; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; @@ -307,54 +315,52 @@ if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; io_base = link->io.BasePort1; - ctl_base = link->io.BasePort1+0x0e; + ctl_base = link->io.BasePort1 + 0x0e; } else goto next_entry; /* If we've got this far, we're done */ break; } - + next_entry: - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); if (pass) { CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } else if (pcmcia_get_next_tuple(handle, &tuple) != 0) { CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - memset(&dflt, 0, sizeof(dflt)); + memset(&stk->dflt, 0, sizeof(stk->dflt)); pass++; } } - + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); - /* deal with brain dead IDE resource management */ - release_region(link->io.BasePort1, link->io.NumPorts1); - if (link->io.NumPorts2) - release_region(link->io.BasePort2, link->io.NumPorts2); - /* disable drive interrupts during IDE probe */ outb(0x02, ctl_base); /* special setup for KXLC005 card */ - if (is_kme) outb(0x81, ctl_base+1); + if (is_kme) + outb(0x81, ctl_base+1); /* retry registration in case device is still spinning up */ for (hd = -1, i = 0; i < 10; i++) { hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); if (hd >= 0) break; if (link->io.NumPorts1 == 0x20) { - outb(0x02, ctl_base+0x10); - hd = idecs_register(io_base+0x10, ctl_base+0x10, + outb(0x02, ctl_base + 0x10); + hd = idecs_register(io_base + 0x10, ctl_base + 0x10, link->irq.AssignedIRQ); if (hd >= 0) { - io_base += 0x10; ctl_base += 0x10; + io_base += 0x10; + ctl_base += 0x10; break; } } __set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); } - + if (hd < 0) { printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx" ", irq %u failed\n", io_base, ctl_base, @@ -363,24 +369,29 @@ } info->ndev = 1; - sprintf(info->node.dev_name, "hd%c", 'a'+(hd*2)); + sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2)); info->node.major = ide_major[hd]; info->node.minor = 0; info->hd = hd; link->dev = &info->node; printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n", - info->node.dev_name, link->conf.Vcc/10, link->conf.Vcc%10, - link->conf.Vpp1/10, link->conf.Vpp1%10); + info->node.dev_name, link->conf.Vcc / 10, link->conf.Vcc % 10, + link->conf.Vpp1 / 10, link->conf.Vpp1 % 10); link->state &= ~DEV_CONFIG_PENDING; + kfree(stk); return; - + +err_mem: + printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n"); + goto failed; + cs_failed: cs_error(link->handle, last_fn, last_ret); failed: + kfree(stk); ide_release(link); link->state &= ~DEV_CONFIG_PENDING; - } /* ide_config */ /*====================================================================== diff -Nru a/drivers/ide/legacy/pc9800.c b/drivers/ide/legacy/pc9800.c --- a/drivers/ide/legacy/pc9800.c 2004-06-26 17:09:18 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,84 +0,0 @@ -/* - * ide_pc9800.c - * - * Copyright (C) 1997-2000 Linux/98 project, - * Kyoto University Microcomputer Club. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define PC9800_IDE_BANKSELECT 0x432 - -#undef PC9800_IDE_DEBUG - -static void pc9800_select(ide_drive_t *drive) -{ -#ifdef PC9800_IDE_DEBUG - byte old; - - /* Too noisy: */ - /* printk(KERN_DEBUG "pc9800_select(%s)\n", drive->name); */ - - outb(0x80, PC9800_IDE_BANKSELECT); - old = inb(PC9800_IDE_BANKSELECT); - if (old != HWIF(drive)->index) - printk(KERN_DEBUG "ide-pc9800: switching bank #%d -> #%d\n", - old, HWIF(drive)->index); -#endif - outb(HWIF(drive)->index, PC9800_IDE_BANKSELECT); -} - -void __init ide_probe_for_pc9800(void) -{ - u8 saved_bank; - - if (!PC9800_9821_P() /* || !PC9821_IDEIF_DOUBLE_P() */) - return; - - if (!request_region(PC9800_IDE_BANKSELECT, 1, "ide0/1 bank")) { - printk(KERN_ERR - "ide: bank select port (%#x) is already occupied!\n", - PC9800_IDE_BANKSELECT); - return; - } - - /* Do actual probing. */ - if ((saved_bank = inb(PC9800_IDE_BANKSELECT)) == (u8) ~0 - || (outb(saved_bank ^ 1, PC9800_IDE_BANKSELECT), - /* Next outb is dummy for reading status. */ - outb(0x80, PC9800_IDE_BANKSELECT), - inb(PC9800_IDE_BANKSELECT) != (saved_bank ^ 1))) { - printk(KERN_INFO - "ide: pc9800 type bank selecting port not found\n"); - release_region(PC9800_IDE_BANKSELECT, 1); - return; - } - - /* Restore original value, just in case. */ - outb(saved_bank, PC9800_IDE_BANKSELECT); - - /* These ports are reseved by IDE I/F. */ - if (!request_region(0x430, 1, "ide") || - !request_region(0x435, 1, "ide")) { - printk(KERN_WARNING - "ide: IO port 0x430 and 0x435 are reserved for IDE" - " the card using these ports may not work\n"); - } - - if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET] == HD_DATA && - ide_hwifs[1].io_ports[IDE_DATA_OFFSET] == HD_DATA) { - ide_hwifs[0].chipset = ide_pc9800; - ide_hwifs[0].mate = &ide_hwifs[1]; - ide_hwifs[0].selectproc = pc9800_select; - ide_hwifs[1].chipset = ide_pc9800; - ide_hwifs[1].mate = &ide_hwifs[0]; - ide_hwifs[1].selectproc = pc9800_select; - } -} diff -Nru a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c --- a/drivers/ide/legacy/pdc4030.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/ide/legacy/pdc4030.c 2004-06-26 17:09:18 -07:00 @@ -355,7 +355,7 @@ #endif /* DEBUG_READ */ #ifdef CONFIG_IDE_TASKFILE_IO - task_sectors(drive, rq, nsect, IDE_PIO_IN); + task_bio_sectors(drive, rq, nsect, IDE_PIO_IN); /* FIXME: can we check status after transfer on pdc4030? */ /* Complete previously submitted bios. */ @@ -478,7 +478,7 @@ if (nsect > msect) nsect = msect; - task_sectors(drive, rq, nsect, IDE_PIO_OUT); + task_bio_sectors(drive, rq, nsect, IDE_PIO_OUT); if (!rq->nr_sectors) msect = 0; diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c --- a/drivers/ide/pci/amd74xx.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/ide/pci/amd74xx.c 2004-06-26 17:09:21 -07:00 @@ -71,11 +71,7 @@ { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, 0x50, AMD_UDMA_133 }, { 0 } }; @@ -487,11 +483,7 @@ /* 11 */ DECLARE_NV_DEV("NFORCE3-250-SATA"), /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), - /* 14 */ DECLARE_NV_DEV("NFORCE-CK804-SATA"), - /* 15 */ DECLARE_NV_DEV("NFORCE-CK804-SATA2"), - /* 16 */ DECLARE_NV_DEV("NFORCE-MCP04"), - /* 17 */ DECLARE_NV_DEV("NFORCE-MCP04-SATA"), - /* 18 */ DECLARE_NV_DEV("NFORCE-MCP04-SATA2") + /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -512,17 +504,17 @@ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, +#ifdef CONFIG_BLK_DEV_IDE_SATA { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, +#endif { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, +#ifdef CONFIG_BLK_DEV_IDE_SATA { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, +#endif { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff -Nru a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c --- a/drivers/ide/pci/generic.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/ide/pci/generic.c 2004-06-26 17:09:18 -07:00 @@ -127,7 +127,9 @@ { PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7}, { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8}, +#ifdef CONFIG_BLK_DEV_IDE_SATA { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9}, +#endif { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10}, { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11}, { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, diff -Nru a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c --- a/drivers/ide/pci/hpt366.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/ide/pci/hpt366.c 2004-06-26 17:09:18 -07:00 @@ -292,7 +292,7 @@ return chipset_table->chipset_settings; } -static void hpt366_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed) { struct pci_dev *dev = HWIF(drive)->pci_dev; u8 speed = hpt3xx_ratefilter(drive, xferspeed); @@ -329,14 +329,11 @@ reg2 &= ~0x80000000; pci_write_config_dword(dev, regtime, reg2); -} -static void hpt368_tune_chipset (ide_drive_t *drive, u8 speed) -{ - hpt366_tune_chipset(drive, speed); + return ide_config_drive_speed(drive, speed); } -static void hpt370_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int hpt370_tune_chipset(ide_drive_t *drive, u8 xferspeed) { struct pci_dev *dev = HWIF(drive)->pci_dev; u8 speed = hpt3xx_ratefilter(drive, xferspeed); @@ -378,9 +375,11 @@ } pci_write_config_dword(dev, drive_pci, list_conf); + + return ide_config_drive_speed(drive, speed); } -static void hpt372_tune_chipset (ide_drive_t *drive, u8 xferspeed) +static int hpt372_tune_chipset(ide_drive_t *drive, u8 xferspeed) { struct pci_dev *dev = HWIF(drive)->pci_dev; u8 speed = hpt3xx_ratefilter(drive, xferspeed); @@ -406,11 +405,8 @@ if (speed < XFER_MW_DMA_0) list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ pci_write_config_dword(dev, drive_pci, list_conf); -} -static void hpt374_tune_chipset (ide_drive_t *drive, u8 speed) -{ - hpt372_tune_chipset(drive, speed); + return ide_config_drive_speed(drive, speed); } static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed) @@ -418,7 +414,7 @@ struct pci_dev *dev = HWIF(drive)->pci_dev; if (hpt_minimum_revision(dev, 8)) - hpt374_tune_chipset(drive, speed); + return hpt372_tune_chipset(drive, speed); /* not a typo */ #if 0 else if (hpt_minimum_revision(dev, 7)) hpt371_tune_chipset(drive, speed); @@ -426,15 +422,11 @@ hpt302_tune_chipset(drive, speed); #endif else if (hpt_minimum_revision(dev, 5)) - hpt372_tune_chipset(drive, speed); + return hpt372_tune_chipset(drive, speed); else if (hpt_minimum_revision(dev, 3)) - hpt370_tune_chipset(drive, speed); - else if (hpt_minimum_revision(dev, 2)) - hpt368_tune_chipset(drive, speed); - else - hpt366_tune_chipset(drive, speed); - - return ((int) ide_config_drive_speed(drive, speed)); + return hpt370_tune_chipset(drive, speed); + else /* hpt368: hpt_minimum_revision(dev, 2) */ + return hpt36x_tune_chipset(drive, speed); } static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio) diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c --- a/drivers/ide/pci/pdc202xx_old.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/ide/pci/pdc202xx_old.c 2004-06-26 17:09:21 -07:00 @@ -717,6 +717,12 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) { + struct pci_dev *dev = hwif->pci_dev; + + /* PDC20265 has problems with large LBA48 requests */ + if (dev->device == PCI_DEVICE_ID_PROMISE_20265) + hwif->rqsize = 256; + hwif->autodma = 0; hwif->tuneproc = &config_chipset_for_pio; hwif->quirkproc = &pdc202xx_quirkproc; diff -Nru a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c --- a/drivers/ide/pci/piix.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/ide/pci/piix.c 2004-06-26 17:09:15 -07:00 @@ -793,9 +793,9 @@ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17}, -#ifndef CONFIG_SCSI_SATA +#ifdef CONFIG_BLK_DEV_IDE_SATA { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18}, -#endif /* !CONFIG_SCSI_SATA */ +#endif { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20}, { 0, }, diff -Nru a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c --- a/drivers/ide/pci/siimage.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/ide/pci/siimage.c 2004-06-26 17:09:17 -07:00 @@ -21,6 +21,7 @@ * if neccessary */ +#include #include #include #include @@ -1127,8 +1128,10 @@ static struct pci_device_id siimage_pci_tbl[] = { { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +#ifdef CONFIG_BLK_DEV_IDE_SATA { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, +#endif { 0, }, }; MODULE_DEVICE_TABLE(pci, siimage_pci_tbl); diff -Nru a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c --- a/drivers/ide/pci/trm290.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/ide/pci/trm290.c 2004-06-26 17:09:16 -07:00 @@ -3,6 +3,10 @@ * * Copyright (c) 1997-1998 Mark Lord * May be copied or modified under the terms of the GNU General Public License + * + * June 22, 2004 - get rid of check_region + * Jesper Juhl + * */ /* @@ -372,16 +376,6 @@ if (old != compat && old_mask == 0xff) { /* leave lower 10 bits untouched */ compat += (next_offset += 0x400); -# if 1 - if (check_region(compat + 2, 1)) - printk(KERN_ERR "%s: check_region failure at 0x%04x\n", - hwif->name, (compat + 2)); - /* - * The region check is not needed; however......... - * Since this is the checked in ide-probe.c, - * this is only an assignment. - */ -# endif hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2; hwif->OUTW(compat|1, hwif->config_data); new = hwif->INW(hwif->config_data); diff -Nru a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c --- a/drivers/ieee1394/amdtp.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/ieee1394/amdtp.c 2004-06-26 17:09:18 -07:00 @@ -1095,7 +1095,7 @@ /* File operations */ -static ssize_t amdtp_write(struct file *file, const char *buffer, size_t count, +static ssize_t amdtp_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset_is_ignored) { struct stream *s = file->private_data; @@ -1150,7 +1150,7 @@ { case AMDTP_IOC_PLUG: case AMDTP_IOC_CHANNEL: - if (copy_from_user(&cfg, (struct amdtp_ioctl *) arg, sizeof cfg)) + if (copy_from_user(&cfg, (struct amdtp_ioctl __user *) arg, sizeof cfg)) return -EFAULT; else return stream_configure(s, cmd, &cfg); diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c --- a/drivers/ieee1394/dv1394.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/ieee1394/dv1394.c 2004-06-26 17:09:19 -07:00 @@ -1333,7 +1333,7 @@ return 0; } -static ssize_t dv1394_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct video_card *video = file_to_video_card(file); DECLARE_WAITQUEUE(wait, current); @@ -1430,7 +1430,7 @@ } -static ssize_t dv1394_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct video_card *video = file_to_video_card(file); DECLARE_WAITQUEUE(wait, current); @@ -1549,6 +1549,7 @@ struct video_card *video = file_to_video_card(file); unsigned long flags; int ret = -EINVAL; + void __user *argp = (void __user *)arg; DECLARE_WAITQUEUE(wait, current); @@ -1718,10 +1719,10 @@ case DV1394_IOC_INIT: { struct dv1394_init init; - if (arg == (unsigned long) NULL) { + if (!argp) { ret = do_dv1394_init_default(video); } else { - if (copy_from_user(&init, (void*)arg, sizeof(init))) { + if (copy_from_user(&init, argp, sizeof(init))) { ret = -EFAULT; goto out; } @@ -1767,7 +1768,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); - if (copy_to_user((void*)arg, &status, sizeof(status))) { + if (copy_to_user(argp, &status, sizeof(status))) { ret = -EFAULT; goto out; } diff -Nru a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c --- a/drivers/ieee1394/eth1394.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/ieee1394/eth1394.c 2004-06-26 17:09:18 -07:00 @@ -431,9 +431,12 @@ if (!node) return -ENOMEM; - node_info = kmalloc(sizeof(struct eth1394_node_info), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + if (!node_info) { + kfree(node); + return -ENOMEM; + } spin_lock_init(&node_info->pdg.lock); INIT_LIST_HEAD(&node_info->pdg.list); diff -Nru a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h --- a/drivers/ieee1394/raw1394-private.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/ieee1394/raw1394-private.h 2004-06-26 17:09:20 -07:00 @@ -35,11 +35,11 @@ struct list_head addr_list; - u8 *fcp_buffer; + u8 __user *fcp_buffer; /* old ISO API */ u64 listen_channels; - quadlet_t *iso_buffer; + quadlet_t __user *iso_buffer; size_t iso_buffer_length; u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */ diff -Nru a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c --- a/drivers/ieee1394/raw1394.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/ieee1394/raw1394.c 2004-06-26 17:09:15 -07:00 @@ -56,11 +56,11 @@ #include "raw1394-private.h" #if BITS_PER_LONG == 64 -#define int2ptr(x) ((void *)x) -#define ptr2int(x) ((u64)x) +#define int2ptr(x) ((void __user *)x) +#define ptr2int(x) ((u64)(unsigned long)(void __user *)x) #else -#define int2ptr(x) ((void *)(u32)x) -#define ptr2int(x) ((u64)(u32)x) +#define int2ptr(x) ((void __user *)(u32)x) +#define ptr2int(x) ((u64)(unsigned long)(void __user *)x) #endif #ifdef CONFIG_IEEE1394_VERBOSEDEBUG @@ -410,7 +410,7 @@ } -static ssize_t raw1394_read(struct file *file, char *buffer, size_t count, +static ssize_t raw1394_read(struct file *file, char __user *buffer, size_t count, loff_t *offset_is_ignored) { struct file_info *fi = (struct file_info *)file->private_data; @@ -602,7 +602,7 @@ if (fi->fcp_buffer) { req->req.error = RAW1394_ERROR_ALREADY; } else { - fi->fcp_buffer = (u8 *)int2ptr(req->req.recvb); + fi->fcp_buffer = int2ptr(req->req.recvb); } } else { if (!fi->fcp_buffer) { @@ -826,7 +826,7 @@ return sizeof(struct raw1394_request); } - if (copy_from_user(packet->data, ((u8*) int2ptr(req->req.sendb)) + header_length, + if (copy_from_user(packet->data, int2ptr(req->req.sendb) + header_length, packet->data_size)) { req->req.error = RAW1394_ERROR_MEMFAULT; req->req.length = 0; @@ -964,9 +964,8 @@ arm_req->buffer = NULL; arm_resp->buffer = NULL; if (rcode == RCODE_COMPLETE) { - arm_resp->buffer = ((byte_t *)(arm_resp) + - (sizeof(struct arm_response))); - memcpy (arm_resp->buffer, + byte_t *buf = (byte_t *)arm_resp + sizeof(struct arm_response); + memcpy (buf, (arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), length); arm_resp->buffer = int2ptr((arm_addr->recvb) + @@ -1091,10 +1090,9 @@ (sizeof (struct arm_request_response))); arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (sizeof(struct arm_request))); - arm_req->buffer = ((byte_t *)(arm_resp) + - (sizeof(struct arm_response))); arm_resp->buffer = NULL; - memcpy (arm_req->buffer, data, length); + memcpy ((byte_t *)arm_resp + sizeof(struct arm_response), + data, length); arm_req->buffer = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request) + @@ -1233,6 +1231,7 @@ } } if (arm_addr->notification_options & ARM_LOCK) { + byte_t *buf1, *buf2; DBGMSG("arm_lock -> entering notification-section"); req = __alloc_pending_request(SLAB_ATOMIC); if (!req) { @@ -1258,26 +1257,22 @@ (sizeof (struct arm_request_response))); arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (sizeof(struct arm_request))); - arm_req->buffer = ((byte_t *)(arm_resp) + - (sizeof(struct arm_response))); - arm_resp->buffer = ((byte_t *)(arm_req->buffer) + - (2* sizeof(*store))); + buf1 = (byte_t *)arm_resp + sizeof(struct arm_response); + buf2 = buf1 + 2 * sizeof(*store); if ((ext_tcode == EXTCODE_FETCH_ADD) || (ext_tcode == EXTCODE_LITTLE_ADD)) { arm_req->buffer_length = sizeof(*store); - memcpy (arm_req->buffer, &data, sizeof(*store)); + memcpy (buf1, &data, sizeof(*store)); } else { arm_req->buffer_length = 2 * sizeof(*store); - memcpy (arm_req->buffer, &arg, sizeof(*store)); - memcpy (((arm_req->buffer) + sizeof(*store)), - &data, sizeof(*store)); + memcpy (buf1, &arg, sizeof(*store)); + memcpy (buf1 + sizeof(*store), &data, sizeof(*store)); } if (rcode == RCODE_COMPLETE) { arm_resp->buffer_length = sizeof(*store); - memcpy (arm_resp->buffer, &old, sizeof(*store)); + memcpy (buf2, &old, sizeof(*store)); } else { - arm_resp->buffer = NULL; arm_resp->buffer_length = 0; } req->file_info = fi; @@ -1438,6 +1433,7 @@ } } if (arm_addr->notification_options & ARM_LOCK) { + byte_t *buf1, *buf2; DBGMSG("arm_lock64 -> entering notification-section"); req = __alloc_pending_request(SLAB_ATOMIC); if (!req) { @@ -1463,26 +1459,22 @@ (sizeof (struct arm_request_response))); arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (sizeof(struct arm_request))); - arm_req->buffer = ((byte_t *)(arm_resp) + - (sizeof(struct arm_response))); - arm_resp->buffer = ((byte_t *)(arm_req->buffer) + - (2* sizeof(*store))); + buf1 = (byte_t *)arm_resp + sizeof(struct arm_response); + buf2 = buf1 + 2 * sizeof(*store); if ((ext_tcode == EXTCODE_FETCH_ADD) || (ext_tcode == EXTCODE_LITTLE_ADD)) { arm_req->buffer_length = sizeof(*store); - memcpy (arm_req->buffer, &data, sizeof(*store)); + memcpy (buf1, &data, sizeof(*store)); } else { arm_req->buffer_length = 2 * sizeof(*store); - memcpy (arm_req->buffer, &arg, sizeof(*store)); - memcpy (((arm_req->buffer) + sizeof(*store)), - &data, sizeof(*store)); + memcpy (buf1, &arg, sizeof(*store)); + memcpy (buf1 + sizeof(*store), &data, sizeof(*store)); } if (rcode == RCODE_COMPLETE) { arm_resp->buffer_length = sizeof(*store); - memcpy (arm_resp->buffer, &old, sizeof(*store)); + memcpy (buf2, &old, sizeof(*store)); } else { - arm_resp->buffer = NULL; arm_resp->buffer_length = 0; } req->file_info = fi; @@ -2146,7 +2138,7 @@ } -static ssize_t raw1394_write(struct file *file, const char *buffer, size_t count, +static ssize_t raw1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset_is_ignored) { struct file_info *fi = (struct file_info *)file->private_data; @@ -2262,7 +2254,7 @@ stat->xmit_cycle = iso->xmit_cycle; } -static int raw1394_iso_xmit_init(struct file_info *fi, void *uaddr) +static int raw1394_iso_xmit_init(struct file_info *fi, void __user *uaddr) { struct raw1394_iso_status stat; @@ -2294,7 +2286,7 @@ return 0; } -static int raw1394_iso_recv_init(struct file_info *fi, void *uaddr) +static int raw1394_iso_recv_init(struct file_info *fi, void __user *uaddr) { struct raw1394_iso_status stat; @@ -2322,7 +2314,7 @@ return 0; } -static int raw1394_iso_get_status(struct file_info *fi, void *uaddr) +static int raw1394_iso_get_status(struct file_info *fi, void __user *uaddr) { struct raw1394_iso_status stat; struct hpsb_iso *iso = fi->iso_handle; @@ -2338,7 +2330,7 @@ } /* copy N packet_infos out of the ringbuffer into user-supplied array */ -static int raw1394_iso_recv_packets(struct file_info *fi, void *uaddr) +static int raw1394_iso_recv_packets(struct file_info *fi, void __user *uaddr) { struct raw1394_iso_packets upackets; unsigned int packet = fi->iso_handle->first_packet; @@ -2369,7 +2361,7 @@ } /* copy N packet_infos from user to ringbuffer, and queue them for transmission */ -static int raw1394_iso_send_packets(struct file_info *fi, void *uaddr) +static int raw1394_iso_send_packets(struct file_info *fi, void __user *uaddr) { struct raw1394_iso_packets upackets; int i, rv; @@ -2426,14 +2418,15 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct file_info *fi = file->private_data; + void __user *argp = (void __user *)arg; switch(fi->iso_state) { case RAW1394_ISO_INACTIVE: switch(cmd) { case RAW1394_IOC_ISO_XMIT_INIT: - return raw1394_iso_xmit_init(fi, (void*) arg); + return raw1394_iso_xmit_init(fi, argp); case RAW1394_IOC_ISO_RECV_INIT: - return raw1394_iso_recv_init(fi, (void*) arg); + return raw1394_iso_recv_init(fi, argp); default: break; } @@ -2443,7 +2436,7 @@ case RAW1394_IOC_ISO_RECV_START: { /* copy args from user-space */ int args[3]; - if (copy_from_user(&args[0], (void*) arg, sizeof(args))) + if (copy_from_user(&args[0], argp, sizeof(args))) return -EFAULT; return hpsb_iso_recv_start(fi->iso_handle, args[0], args[1], args[2]); } @@ -2457,14 +2450,14 @@ case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: { /* copy the u64 from user-space */ u64 mask; - if (copy_from_user(&mask, (void*) arg, sizeof(mask))) + if (copy_from_user(&mask, argp, sizeof(mask))) return -EFAULT; return hpsb_iso_recv_set_channel_mask(fi->iso_handle, mask); } case RAW1394_IOC_ISO_GET_STATUS: - return raw1394_iso_get_status(fi, (void*) arg); + return raw1394_iso_get_status(fi, argp); case RAW1394_IOC_ISO_RECV_PACKETS: - return raw1394_iso_recv_packets(fi, (void*) arg); + return raw1394_iso_recv_packets(fi, argp); case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: return hpsb_iso_recv_release_packets(fi->iso_handle, arg); case RAW1394_IOC_ISO_RECV_FLUSH: @@ -2482,7 +2475,7 @@ case RAW1394_IOC_ISO_XMIT_START: { /* copy two ints from user-space */ int args[2]; - if (copy_from_user(&args[0], (void*) arg, sizeof(args))) + if (copy_from_user(&args[0], argp, sizeof(args))) return -EFAULT; return hpsb_iso_xmit_start(fi->iso_handle, args[0], args[1]); } @@ -2492,9 +2485,9 @@ hpsb_iso_stop(fi->iso_handle); return 0; case RAW1394_IOC_ISO_GET_STATUS: - return raw1394_iso_get_status(fi, (void*) arg); + return raw1394_iso_get_status(fi, argp); case RAW1394_IOC_ISO_XMIT_PACKETS: - return raw1394_iso_send_packets(fi, (void*) arg); + return raw1394_iso_send_packets(fi, argp); case RAW1394_IOC_ISO_SHUTDOWN: raw1394_iso_shutdown(fi); return 0; diff -Nru a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h --- a/drivers/ieee1394/raw1394.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/ieee1394/raw1394.h 2004-06-26 17:09:15 -07:00 @@ -105,18 +105,18 @@ __u8 extended_transaction_code; __u32 generation; __u16 buffer_length; - __u8 *buffer; + __u8 __user *buffer; } *arm_request_t; typedef struct arm_response { __s32 response_code; __u16 buffer_length; - __u8 *buffer; + __u8 __user *buffer; } *arm_response_t; typedef struct arm_request_response { - struct arm_request *request; - struct arm_response *response; + struct arm_request __user *request; + struct arm_response __user *response; } *arm_request_response_t; /* rawiso API */ @@ -136,7 +136,7 @@ /* argument for RAW1394_ISO_RECV/XMIT_PACKETS ioctls */ struct raw1394_iso_packets { __u32 n_packets; - struct raw1394_iso_packet_info *infos; + struct raw1394_iso_packet_info __user *infos; }; struct raw1394_iso_config { diff -Nru a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c --- a/drivers/ieee1394/video1394.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/ieee1394/video1394.c 2004-06-26 17:09:16 -07:00 @@ -705,6 +705,7 @@ struct file_ctx *ctx = (struct file_ctx *)file->private_data; struct ti_ohci *ohci = ctx->ohci; unsigned long flags; + void __user *argp = (void __user *)arg; switch(cmd) { @@ -716,7 +717,7 @@ struct dma_iso_ctx *d; int i; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; /* if channel < 0, find lowest available one */ @@ -813,7 +814,7 @@ v.channel); } - if (copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user(argp, &v, sizeof(v))) return -EFAULT; return 0; @@ -825,7 +826,7 @@ u64 mask; struct dma_iso_ctx *d; - if (copy_from_user(&channel, (void *)arg, sizeof(int))) + if (copy_from_user(&channel, argp, sizeof(int))) return -EFAULT; if (channel<0 || channel>(ISO_CHANNELS-1)) { @@ -860,7 +861,7 @@ struct video1394_wait v; struct dma_iso_ctx *d; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -923,7 +924,7 @@ struct dma_iso_ctx *d; int i; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -994,7 +995,7 @@ spin_unlock_irqrestore(&d->lock, flags); v.buffer=i; - if (copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user(argp, &v, sizeof(v))) return -EFAULT; return 0; @@ -1007,7 +1008,7 @@ qv.packet_sizes = NULL; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); @@ -1023,7 +1024,7 @@ unsigned int *psizes; int buf_size = d->nb_cmd * sizeof(unsigned int); - if (copy_from_user(&qv, (void *)arg, sizeof(qv))) + if (copy_from_user(&qv, argp, sizeof(qv))) return -EFAULT; psizes = kmalloc(buf_size, GFP_KERNEL); @@ -1111,7 +1112,7 @@ struct video1394_wait v; struct dma_iso_ctx *d; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); diff -Nru a/drivers/input/joydev.c b/drivers/input/joydev.c --- a/drivers/input/joydev.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/input/joydev.c 2004-06-26 17:09:18 -07:00 @@ -191,12 +191,12 @@ return 0; } -static ssize_t joydev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos) +static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) { return -EINVAL; } -static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct joydev_list *list = file->private_data; struct joydev *joydev = list->joydev; @@ -291,6 +291,7 @@ struct joydev_list *list = file->private_data; struct joydev *joydev = list->joydev; struct input_dev *dev = joydev->handle.dev; + void __user *argp = (void __user *)arg; int i, j; if (!joydev->exist) return -ENODEV; @@ -298,34 +299,34 @@ switch (cmd) { case JS_SET_CAL: - return copy_from_user(&joydev->glue.JS_CORR, (struct JS_DATA_TYPE *) arg, + return copy_from_user(&joydev->glue.JS_CORR, argp, sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0; case JS_GET_CAL: - return copy_to_user((struct JS_DATA_TYPE *) arg, &joydev->glue.JS_CORR, + return copy_to_user(argp, &joydev->glue.JS_CORR, sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0; case JS_SET_TIMEOUT: - return get_user(joydev->glue.JS_TIMEOUT, (int *) arg); + return get_user(joydev->glue.JS_TIMEOUT, (int __user *) arg); case JS_GET_TIMEOUT: - return put_user(joydev->glue.JS_TIMEOUT, (int *) arg); + return put_user(joydev->glue.JS_TIMEOUT, (int __user *) arg); case JS_SET_TIMELIMIT: - return get_user(joydev->glue.JS_TIMELIMIT, (long *) arg); + return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg); case JS_GET_TIMELIMIT: - return put_user(joydev->glue.JS_TIMELIMIT, (long *) arg); + return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg); case JS_SET_ALL: - return copy_from_user(&joydev->glue, (struct JS_DATA_SAVE_TYPE *) arg, + return copy_from_user(&joydev->glue, argp, sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0; case JS_GET_ALL: - return copy_to_user((struct JS_DATA_SAVE_TYPE *) arg, &joydev->glue, + return copy_to_user(argp, &joydev->glue, sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0; case JSIOCGVERSION: - return put_user(JS_VERSION, (__u32 *) arg); + return put_user(JS_VERSION, (__u32 __user *) arg); case JSIOCGAXES: - return put_user(joydev->nabs, (__u8 *) arg); + return put_user(joydev->nabs, (__u8 __user *) arg); case JSIOCGBUTTONS: - return put_user(joydev->nkey, (__u8 *) arg); + return put_user(joydev->nkey, (__u8 __user *) arg); case JSIOCSCORR: - if (copy_from_user(joydev->corr, (struct js_corr *)arg, + if (copy_from_user(joydev->corr, argp, sizeof(struct js_corr) * joydev->nabs)) return -EFAULT; for (i = 0; i < joydev->nabs; i++) { @@ -334,10 +335,10 @@ } return 0; case JSIOCGCORR: - return copy_to_user((struct js_corr *) arg, joydev->corr, + return copy_to_user(argp, joydev->corr, sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0; case JSIOCSAXMAP: - if (copy_from_user(joydev->abspam, (__u8 *) arg, sizeof(__u8) * ABS_MAX)) + if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * ABS_MAX)) return -EFAULT; for (i = 0; i < joydev->nabs; i++) { if (joydev->abspam[i] > ABS_MAX) return -EINVAL; @@ -345,10 +346,10 @@ } return 0; case JSIOCGAXMAP: - return copy_to_user((__u8 *) arg, joydev->abspam, + return copy_to_user(argp, joydev->abspam, sizeof(__u8) * ABS_MAX) ? -EFAULT : 0; case JSIOCSBTNMAP: - if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC))) + if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC))) return -EFAULT; for (i = 0; i < joydev->nkey; i++) { if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; @@ -356,7 +357,7 @@ } return 0; case JSIOCGBTNMAP: - return copy_to_user((__u16 *) arg, joydev->keypam, + return copy_to_user(argp, joydev->keypam, sizeof(__u16) * (KEY_MAX - BTN_MISC)) ? -EFAULT : 0; default: if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) { @@ -364,7 +365,7 @@ if (!dev->name) return 0; len = strlen(dev->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - if (copy_to_user((char *) arg, dev->name, len)) return -EFAULT; + if (copy_to_user(argp, dev->name, len)) return -EFAULT; return len; } } diff -Nru a/drivers/input/keyboard/98kbd.c b/drivers/input/keyboard/98kbd.c --- a/drivers/input/keyboard/98kbd.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,391 +0,0 @@ -/* - * drivers/input/keyboard/98kbd.c - * - * PC-9801 keyboard driver for Linux - * - * Based on atkbd.c and xtkbd.c written by Vojtech Pavlik - * - * Copyright (c) 2002 Osamu Tomita - * Copyright (c) 1999-2001 Vojtech Pavlik - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -MODULE_AUTHOR("Osamu Tomita "); -MODULE_DESCRIPTION("PC-9801 keyboard driver"); -MODULE_LICENSE("GPL"); - -#define KBD98_KEY 0x7f -#define KBD98_RELEASE 0x80 - -static unsigned char kbd98_keycode[256] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 43, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 41, 26, 28, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 27, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 12, 57, 92,109,104,110,111,103,105,106,108,102,107, - 74, 98, 71, 72, 73, 55, 75, 76, 77, 78, 79, 80, 81,117, 82,121, - 83, 94, 87, 88,183,184,185, 0, 0, 0, 0, 0, 0, 0,102, 0, - 99,133, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, 0, - 54, 58, 42, 56, 29 -}; - -struct jis_kbd_conv { - unsigned char scancode; - struct { - unsigned char shift; - unsigned char keycode; - } emul[2]; -}; - -static struct jis_kbd_conv kbd98_jis[] = { - {0x02, {{0, 3}, {1, 40}}}, - {0x06, {{0, 7}, {1, 8}}}, - {0x07, {{0, 8}, {0, 40}}}, - {0x08, {{0, 9}, {1, 10}}}, - {0x09, {{0, 10}, {1, 11}}}, - {0x0a, {{0, 11}, {1, 255}}}, - {0x0b, {{0, 12}, {0, 13}}}, - {0x0c, {{1, 7}, {0, 41}}}, - {0x1a, {{1, 3}, {1, 41}}}, - {0x26, {{0, 39}, {1, 13}}}, - {0x27, {{1, 39}, {1, 9}}}, - {0x33, {{0, 255}, {1, 12}}}, - {0xff, {{0, 255}, {1, 255}}} /* terminater */ -}; - -#define KBD98_CMD_SETEXKEY 0x1095 /* Enable/Disable Windows, Appli key */ -#define KBD98_CMD_SETRATE 0x109c /* Set typematic rate */ -#define KBD98_CMD_SETLEDS 0x109d /* Set keyboard leds */ -#define KBD98_CMD_GETLEDS 0x119d /* Get keyboard leds */ -#define KBD98_CMD_GETID 0x019f - -#define KBD98_RET_ACK 0xfa -#define KBD98_RET_NAK 0xfc /* Command NACK, send the cmd again */ - -#define KBD98_KEY_JIS_EMUL 253 -#define KBD98_KEY_UNKNOWN 254 -#define KBD98_KEY_NULL 255 - -static char *kbd98_name = "PC-9801 Keyboard"; - -struct kbd98 { - unsigned char keycode[256]; - struct input_dev dev; - struct serio *serio; - char phys[32]; - unsigned char cmdbuf[4]; - unsigned char cmdcnt; - signed char ack; - unsigned char shift; - struct { - unsigned char scancode; - unsigned char keycode; - } emul; - struct jis_kbd_conv jis[16]; -}; - -irqreturn_t kbd98_interrupt(struct serio *serio, unsigned char data, - unsigned int flags, struct pt_regs *regs) -{ - struct kbd98 *kbd98 = serio->private; - unsigned char scancode, keycode; - int press, i; - - switch (data) { - case KBD98_RET_ACK: - kbd98->ack = 1; - goto out; - case KBD98_RET_NAK: - kbd98->ack = -1; - goto out; - } - - if (kbd98->cmdcnt) { - kbd98->cmdbuf[--kbd98->cmdcnt] = data; - goto out; - } - - scancode = data & KBD98_KEY; - keycode = kbd98->keycode[scancode]; - press = !(data & KBD98_RELEASE); - if (kbd98->emul.scancode != KBD98_KEY_UNKNOWN - && scancode != kbd98->emul.scancode) { - input_report_key(&kbd98->dev, kbd98->emul.keycode, 0); - kbd98->emul.scancode = KBD98_KEY_UNKNOWN; - } - - if (keycode == KEY_RIGHTSHIFT) - kbd98->shift = press; - - switch (keycode) { - case KEY_2: - case KEY_6: - case KEY_7: - case KEY_8: - case KEY_9: - case KEY_0: - case KEY_MINUS: - case KEY_EQUAL: - case KEY_GRAVE: - case KEY_SEMICOLON: - case KEY_APOSTROPHE: - /* emulation: JIS keyboard to US101 keyboard */ - i = 0; - while (kbd98->jis[i].scancode != 0xff) { - if (scancode == kbd98->jis[i].scancode) - break; - i ++; - } - - keycode = kbd98->jis[i].emul[kbd98->shift].keycode; - if (keycode == KBD98_KEY_NULL) - break; - - if (press) { - kbd98->emul.scancode = scancode; - kbd98->emul.keycode = keycode; - if (kbd98->jis[i].emul[kbd98->shift].shift - != kbd98->shift) - input_report_key(&kbd98->dev, - KEY_RIGHTSHIFT, - !(kbd98->shift)); - } - - input_report_key(&kbd98->dev, keycode, press); - if (!press) { - if (kbd98->jis[i].emul[kbd98->shift].shift - != kbd98->shift) - input_report_key(&kbd98->dev, - KEY_RIGHTSHIFT, - kbd98->shift); - kbd98->emul.scancode = KBD98_KEY_UNKNOWN; - } - - input_sync(&kbd98->dev); - break; - - case KEY_CAPSLOCK: - input_report_key(&kbd98->dev, keycode, 1); - input_sync(&kbd98->dev); - input_report_key(&kbd98->dev, keycode, 0); - input_sync(&kbd98->dev); - break; - - case KBD98_KEY_NULL: - break; - - case 0: - printk(KERN_WARNING "kbd98.c: Unknown key (scancode %#x) %s.\n", - data & KBD98_KEY, data & KBD98_RELEASE ? "released" : "pressed"); - break; - - default: - input_report_key(&kbd98->dev, keycode, press); - input_sync(&kbd98->dev); - break; - } - -out: - return IRQ_HANDLED; -} - -/* - * kbd98_sendbyte() sends a byte to the keyboard, and waits for - * acknowledge. It doesn't handle resends according to the keyboard - * protocol specs, because if these are needed, the keyboard needs - * replacement anyway, and they only make a mess in the protocol. - */ - -static int kbd98_sendbyte(struct kbd98 *kbd98, unsigned char byte) -{ - int timeout = 10000; /* 100 msec */ - kbd98->ack = 0; - - if (serio_write(kbd98->serio, byte)) - return -1; - - while (!kbd98->ack && timeout--) udelay(10); - - return -(kbd98->ack <= 0); -} - -/* - * kbd98_command() sends a command, and its parameters to the keyboard, - * then waits for the response and puts it in the param array. - */ - -static int kbd98_command(struct kbd98 *kbd98, unsigned char *param, int command) -{ - int timeout = 50000; /* 500 msec */ - int send = (command >> 12) & 0xf; - int receive = (command >> 8) & 0xf; - int i; - - kbd98->cmdcnt = receive; - - if (command & 0xff) - if (kbd98_sendbyte(kbd98, command & 0xff)) - return (kbd98->cmdcnt = 0) - 1; - - for (i = 0; i < send; i++) - if (kbd98_sendbyte(kbd98, param[i])) - return (kbd98->cmdcnt = 0) - 1; - - while (kbd98->cmdcnt && timeout--) udelay(10); - - if (param) - for (i = 0; i < receive; i++) - param[i] = kbd98->cmdbuf[(receive - 1) - i]; - - if (kbd98->cmdcnt) - return (kbd98->cmdcnt = 0) - 1; - - return 0; -} - -/* - * Event callback from the input module. Events that change the state of - * the hardware are processed here. - */ - -static int kbd98_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) -{ - struct kbd98 *kbd98 = dev->private; - char param[2]; - - switch (type) { - - case EV_LED: - - if (__PC9800SCA_TEST_BIT(0x481, 3)) { - /* 98note with Num Lock key */ - /* keep Num Lock status */ - *param = 0x60; - if (kbd98_command(kbd98, param, - KBD98_CMD_GETLEDS)) - printk(KERN_DEBUG - "kbd98: Get keyboard LED" - " status Error\n"); - - *param &= 1; - } else { - /* desktop PC-9801 */ - *param = 1; /* Always set Num Lock */ - } - - *param |= 0x70 - | (test_bit(LED_CAPSL, dev->led) ? 4 : 0) - | (test_bit(LED_KANA, dev->led) ? 8 : 0); - kbd98_command(kbd98, param, KBD98_CMD_SETLEDS); - - return 0; - } - - return -1; -} - -void kbd98_connect(struct serio *serio, struct serio_dev *dev) -{ - struct kbd98 *kbd98; - int i; - - if ((serio->type & SERIO_TYPE) != SERIO_PC9800) - return; - - if (!(kbd98 = kmalloc(sizeof(struct kbd98), GFP_KERNEL))) - return; - - memset(kbd98, 0, sizeof(struct kbd98)); - kbd98->emul.scancode = KBD98_KEY_UNKNOWN; - - kbd98->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); - kbd98->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_KANA); - - kbd98->serio = serio; - - init_input_dev(&kbd98->dev); - kbd98->dev.keycode = kbd98->keycode; - kbd98->dev.keycodesize = sizeof(unsigned char); - kbd98->dev.keycodemax = ARRAY_SIZE(kbd98_keycode); - kbd98->dev.event = kbd98_event; - kbd98->dev.private = kbd98; - - serio->private = kbd98; - - if (serio_open(serio, dev)) { - kfree(kbd98); - return; - } - - memcpy(kbd98->jis, kbd98_jis, sizeof(kbd98_jis)); - memcpy(kbd98->keycode, kbd98_keycode, sizeof(kbd98->keycode)); - for (i = 0; i < 255; i++) - set_bit(kbd98->keycode[i], kbd98->dev.keybit); - clear_bit(0, kbd98->dev.keybit); - - sprintf(kbd98->phys, "%s/input0", serio->phys); - - kbd98->dev.name = kbd98_name; - kbd98->dev.phys = kbd98->phys; - kbd98->dev.id.bustype = BUS_XTKBD; - kbd98->dev.id.vendor = 0x0002; - kbd98->dev.id.product = 0x0001; - kbd98->dev.id.version = 0x0100; - - input_register_device(&kbd98->dev); - - printk(KERN_INFO "input: %s on %s\n", kbd98_name, serio->phys); -} - -void kbd98_disconnect(struct serio *serio) -{ - struct kbd98 *kbd98 = serio->private; - input_unregister_device(&kbd98->dev); - serio_close(serio); - kfree(kbd98); -} - -struct serio_dev kbd98_dev = { - .interrupt = kbd98_interrupt, - .connect = kbd98_connect, - .disconnect = kbd98_disconnect -}; - -int __init kbd98_init(void) -{ - serio_register_device(&kbd98_dev); - return 0; -} - -void __exit kbd98_exit(void) -{ - serio_unregister_device(&kbd98_dev); -} - -module_init(kbd98_init); -module_exit(kbd98_exit); diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig --- a/drivers/input/keyboard/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/input/keyboard/Kconfig 2004-06-26 17:09:20 -07:00 @@ -96,15 +96,3 @@ To compile this driver as a module, choose M here: the module will be called amikbd. - -config KEYBOARD_98KBD - tristate "NEC PC-9800 Keyboard support" - depends on X86_PC9800 && INPUT && INPUT_KEYBOARD - select SERIO - help - Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or - compatible) on your system. - - To compile this driver as a module, choose M here: the - module will be called 98kbd. - diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c --- a/drivers/input/keyboard/atkbd.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/input/keyboard/atkbd.c 2004-06-26 17:09:20 -07:00 @@ -288,7 +288,7 @@ atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3); goto out; case ATKBD_RET_ERR: - printk(KERN_WARNING "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); + printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); goto out; } diff -Nru a/drivers/input/misc/98spkr.c b/drivers/input/misc/98spkr.c --- a/drivers/input/misc/98spkr.c 2004-06-26 17:09:16 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,96 +0,0 @@ -/* - * PC-9800 Speaker beeper driver for Linux - * - * Copyright (c) 2002 Osamu Tomita - * Copyright (c) 2002 Vojtech Pavlik - * Copyright (c) 1992 Orest Zborowski - * - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation - */ - -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Osamu Tomita "); -MODULE_DESCRIPTION("PC-9800 Speaker beeper driver"); -MODULE_LICENSE("GPL"); - -static char spkr98_name[] = "PC-9801 Speaker"; -static char spkr98_phys[] = "isa3fdb/input0"; -static struct input_dev spkr98_dev; - -spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED; - -static int spkr98_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) -{ - unsigned int count = 0; - unsigned long flags; - - if (type != EV_SND) - return -1; - - switch (code) { - case SND_BELL: if (value) value = 1000; - case SND_TONE: break; - default: return -1; - } - - if (value > 20 && value < 32767) - count = PIT_TICK_RATE / value; - - spin_lock_irqsave(&i8253_beep_lock, flags); - - if (count) { - outb(0x76, 0x3fdf); - outb(0, 0x5f); - outb(count & 0xff, 0x3fdb); - outb(0, 0x5f); - outb((count >> 8) & 0xff, 0x3fdb); - /* beep on */ - outb(6, 0x37); - } else { - /* beep off */ - outb(7, 0x37); - } - - spin_unlock_irqrestore(&i8253_beep_lock, flags); - - return 0; -} - -static int __init spkr98_init(void) -{ - spkr98_dev.evbit[0] = BIT(EV_SND); - spkr98_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - spkr98_dev.event = spkr98_event; - - spkr98_dev.name = spkr98_name; - spkr98_dev.phys = spkr98_phys; - spkr98_dev.id.bustype = BUS_ISA; - spkr98_dev.id.vendor = 0x001f; - spkr98_dev.id.product = 0x0001; - spkr98_dev.id.version = 0x0100; - - input_register_device(&spkr98_dev); - - printk(KERN_INFO "input: %s\n", spkr98_name); - - return 0; -} - -static void __exit spkr98_exit(void) -{ - input_unregister_device(&spkr98_dev); -} - -module_init(spkr98_init); -module_exit(spkr98_exit); diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig --- a/drivers/input/misc/Kconfig 2004-06-26 17:09:17 -07:00 +++ b/drivers/input/misc/Kconfig 2004-06-26 17:09:17 -07:00 @@ -40,10 +40,6 @@ tristate "M68k Beeper support" depends on M68K && INPUT && INPUT_MISC -config INPUT_98SPKR - tristate "PC-9800 Speaker support" - depends on X86_PC9800 && INPUT && INPUT_MISC - config INPUT_UINPUT tristate "User level driver support" depends on INPUT && INPUT_MISC diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c --- a/drivers/input/misc/uinput.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/input/misc/uinput.c 2004-06-26 17:09:20 -07:00 @@ -166,7 +166,7 @@ return retval; } -static int uinput_alloc_device(struct file *file, const char *buffer, size_t count) +static int uinput_alloc_device(struct file *file, const char __user *buffer, size_t count) { struct uinput_user_dev *user_dev; struct input_dev *dev; @@ -226,7 +226,7 @@ return retval; } -static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct uinput_device *udev = file->private_data; @@ -243,7 +243,7 @@ return count; } -static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct uinput_device *udev = file->private_data; int retval = 0; diff -Nru a/drivers/input/mouse/98busmouse.c b/drivers/input/mouse/98busmouse.c --- a/drivers/input/mouse/98busmouse.c 2004-06-26 17:09:20 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,197 +0,0 @@ -/* - * - * Copyright (c) 2002 Osamu Tomita - * - * Based on the work of: - * James Banks Matthew Dillon - * David Giller Nathan Laredo - * Linus Torvalds Johan Myreen - * Cliff Matthews Philip Blundell - * Russell King Vojtech Pavlik - */ - -/* - * NEC PC-9801 Bus Mouse Driver for Linux - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -MODULE_AUTHOR("Osamu Tomita "); -MODULE_DESCRIPTION("PC-9801 busmouse driver"); -MODULE_LICENSE("GPL"); - -#define PC98BM_BASE 0x7fd9 -#define PC98BM_DATA_PORT PC98BM_BASE + 0 -/* PC98BM_SIGNATURE_PORT does not exist */ -#define PC98BM_CONTROL_PORT PC98BM_BASE + 4 -/* PC98BM_INTERRUPT_PORT does not exist */ -#define PC98BM_CONFIG_PORT PC98BM_BASE + 6 - -#define PC98BM_ENABLE_IRQ 0x00 -#define PC98BM_DISABLE_IRQ 0x10 -#define PC98BM_READ_X_LOW 0x80 -#define PC98BM_READ_X_HIGH 0xa0 -#define PC98BM_READ_Y_LOW 0xc0 -#define PC98BM_READ_Y_HIGH 0xe0 - -#define PC98BM_DEFAULT_MODE 0x93 -/* PC98BM_CONFIG_BYTE is not used */ -/* PC98BM_SIGNATURE_BYTE is not used */ - -#define PC98BM_TIMER_PORT 0xbfdb -#define PC98BM_DEFAULT_TIMER_VAL 0x00 - -#define PC98BM_IRQ 13 - -static int pc98bm_irq = PC98BM_IRQ; -module_param_named(irq, pc98bm_irq, uint, 0); -MODULE_PARM_DESC(irq, "IRQ number (13=default)"); - -__obsolete_setup("pc98bm_irq="); - -static int pc98bm_used = 0; - -static irqreturn_t pc98bm_interrupt(int irq, void *dev_id, struct pt_regs *regs); - -static int pc98bm_open(struct input_dev *dev) -{ - if (pc98bm_used++) - return 0; - if (request_irq(pc98bm_irq, pc98bm_interrupt, 0, "98busmouse", NULL)) { - pc98bm_used--; - printk(KERN_ERR "98busmouse.c: Can't allocate irq %d\n", pc98bm_irq); - return -EBUSY; - } - outb(PC98BM_ENABLE_IRQ, PC98BM_CONTROL_PORT); - return 0; -} - -static void pc98bm_close(struct input_dev *dev) -{ - if (--pc98bm_used) - return; - outb(PC98BM_DISABLE_IRQ, PC98BM_CONTROL_PORT); - free_irq(pc98bm_irq, NULL); -} - -static struct input_dev pc98bm_dev = { - .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, - .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) }, - .relbit = { BIT(REL_X) | BIT(REL_Y) }, - .open = pc98bm_open, - .close = pc98bm_close, - .name = "PC-9801 bus mouse", - .phys = "isa7fd9/input0", - .id = { - .bustype = BUS_ISA, - .vendor = 0x0004, - .product = 0x0001, - .version = 0x0100, - }, -}; - -static irqreturn_t pc98bm_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - char dx, dy; - unsigned char buttons; - - outb(PC98BM_READ_X_LOW, PC98BM_CONTROL_PORT); - dx = (inb(PC98BM_DATA_PORT) & 0xf); - outb(PC98BM_READ_X_HIGH, PC98BM_CONTROL_PORT); - dx |= (inb(PC98BM_DATA_PORT) & 0xf) << 4; - outb(PC98BM_READ_Y_LOW, PC98BM_CONTROL_PORT); - dy = (inb(PC98BM_DATA_PORT) & 0xf); - outb(PC98BM_READ_Y_HIGH, PC98BM_CONTROL_PORT); - buttons = inb(PC98BM_DATA_PORT); - dy |= (buttons & 0xf) << 4; - buttons = ~buttons >> 5; - - input_report_rel(&pc98bm_dev, REL_X, dx); - input_report_rel(&pc98bm_dev, REL_Y, dy); - input_report_key(&pc98bm_dev, BTN_RIGHT, buttons & 1); - input_report_key(&pc98bm_dev, BTN_MIDDLE, buttons & 2); - input_report_key(&pc98bm_dev, BTN_LEFT, buttons & 4); - input_sync(&pc98bm_dev); - - outb(PC98BM_ENABLE_IRQ, PC98BM_CONTROL_PORT); - - return IRQ_HANDLED; -} - -static int __init pc98bm_init(void) -{ - int i; - - for (i = 0; i <= 6; i += 2) { - if (!request_region(PC98BM_BASE + i, 1, "98busmouse")) { - printk(KERN_ERR "98busmouse.c: Can't allocate ports at %#x\n", PC98BM_BASE + i); - while (i > 0) { - i -= 2; - release_region(PC98BM_BASE + i, 1); - } - - return -EBUSY; - } - - } - - if (!request_region(PC98BM_TIMER_PORT, 1, "98busmouse")) { - printk(KERN_ERR "98busmouse.c: Can't allocate ports at %#x\n", PC98BM_TIMER_PORT); - for (i = 0; i <= 6; i += 2) - release_region(PC98BM_BASE + i, 1); - - return -EBUSY; - } - - outb(PC98BM_DEFAULT_MODE, PC98BM_CONFIG_PORT); - outb(PC98BM_DISABLE_IRQ, PC98BM_CONTROL_PORT); - - outb(PC98BM_DEFAULT_TIMER_VAL, PC98BM_TIMER_PORT); - - input_register_device(&pc98bm_dev); - - printk(KERN_INFO "input: PC-9801 bus mouse at %#x irq %d\n", PC98BM_BASE, pc98bm_irq); - - return 0; -} - -static void __exit pc98bm_exit(void) -{ - int i; - - input_unregister_device(&pc98bm_dev); - for (i = 0; i <= 6; i += 2) - release_region(PC98BM_BASE + i, 1); - - release_region(PC98BM_TIMER_PORT, 1); -} - -module_init(pc98bm_init); -module_exit(pc98bm_exit); diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig --- a/drivers/input/mouse/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/input/mouse/Kconfig 2004-06-26 17:09:20 -07:00 @@ -130,14 +130,3 @@ described in the source file). This driver should, in theory, also work with the digitizer DEC produced, but it isn't tested with that (I don't have the hardware yet). - -config MOUSE_PC9800 - tristate "NEC PC-9800 busmouse" - depends on X86_PC9800 && INPUT && INPUT_MOUSE && ISA - help - Say Y here if you have NEC PC-9801/PC-9821 computer and want its - native mouse supported. - - To compile this driver as a module, choose M here: the - module will be called 98busmouse. - diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile --- a/drivers/input/mouse/Makefile 2004-06-26 17:09:16 -07:00 +++ b/drivers/input/mouse/Makefile 2004-06-26 17:09:16 -07:00 @@ -10,7 +10,6 @@ obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o -obj-$(CONFIG_MOUSE_PC9800) += 98busmouse.o obj-$(CONFIG_MOUSE_PS2) += psmouse.o obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o diff -Nru a/drivers/input/serio/98kbd-io.c b/drivers/input/serio/98kbd-io.c --- a/drivers/input/serio/98kbd-io.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,179 +0,0 @@ -/* - * NEC PC-9801 keyboard controller driver for Linux - * - * Copyright (c) 1999-2002 Osamu Tomita - * Based on i8042.c written by Vojtech Pavlik - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -MODULE_AUTHOR("Osamu Tomita "); -MODULE_DESCRIPTION("NEC PC-9801 keyboard controller driver"); -MODULE_LICENSE("GPL"); - -/* - * Names. - */ - -#define KBD98_PHYS_DESC "isa0041/serio0" - -/* - * IRQs. - */ - -#define KBD98_IRQ 1 - -/* - * Register numbers. - */ - -#define KBD98_COMMAND_REG 0x43 -#define KBD98_STATUS_REG 0x43 -#define KBD98_DATA_REG 0x41 - -spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED; - -static struct serio kbd98_port; -extern struct pt_regs *kbd_pt_regs; - -static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs); - -/* - * kbd98_flush() flushes all data that may be in the keyboard buffers - */ - -static int kbd98_flush(void) -{ - unsigned long flags; - - spin_lock_irqsave(&kbd98io_lock, flags); - - while (inb(KBD98_STATUS_REG) & 0x02) /* RxRDY */ - inb(KBD98_DATA_REG); - - if (inb(KBD98_STATUS_REG) & 0x38) - printk("98kbd-io: Keyboard error!\n"); - - spin_unlock_irqrestore(&kbd98io_lock, flags); - - return 0; -} - -/* - * kbd98_write() sends a byte out through the keyboard interface. - */ - -static int kbd98_write(struct serio *port, unsigned char c) -{ - unsigned long flags; - - spin_lock_irqsave(&kbd98io_lock, flags); - - outb(0, 0x5f); /* wait */ - outb(0x17, KBD98_COMMAND_REG); /* enable send command */ - outb(0, 0x5f); /* wait */ - outb(c, KBD98_DATA_REG); - outb(0, 0x5f); /* wait */ - outb(0x16, KBD98_COMMAND_REG); /* disable send command */ - outb(0, 0x5f); /* wait */ - - spin_unlock_irqrestore(&kbd98io_lock, flags); - - return 0; -} - -/* - * kbd98_open() is called when a port is open by the higher layer. - * It allocates the interrupt and enables in in the chip. - */ - -static int kbd98_open(struct serio *port) -{ - kbd98_flush(); - - if (request_irq(KBD98_IRQ, kbd98io_interrupt, 0, "kbd98", NULL)) { - printk(KERN_ERR "98kbd-io.c: Can't get irq %d for %s, unregistering the port.\n", KBD98_IRQ, "KBD"); - serio_unregister_port(port); - return -1; - } - - return 0; -} - -static void kbd98_close(struct serio *port) -{ - free_irq(KBD98_IRQ, NULL); - - kbd98_flush(); -} - -/* - * Structures for registering the devices in the serio.c module. - */ - -static struct serio kbd98_port = -{ - .type = SERIO_PC9800, - .write = kbd98_write, - .open = kbd98_open, - .close = kbd98_close, - .driver = NULL, - .name = "PC-9801 Kbd Port", - .phys = KBD98_PHYS_DESC, -}; - -/* - * kbd98io_interrupt() is the most important function in this driver - - * it handles the interrupts from keyboard, and sends incoming bytes - * to the upper layers. - */ - -static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - unsigned char data; - - spin_lock_irqsave(&kbd98io_lock, flags); - - data = inb(KBD98_DATA_REG); - spin_unlock_irqrestore(&kbd98io_lock, flags); - serio_interrupt(&kbd98_port, data, 0, regs); - - return IRQ_HANDLED; -} - -int __init kbd98io_init(void) -{ - serio_register_port(&kbd98_port); - - printk(KERN_INFO "serio: PC-9801 %s port at %#lx,%#lx irq %d\n", - "KBD", - (unsigned long) KBD98_DATA_REG, - (unsigned long) KBD98_COMMAND_REG, - KBD98_IRQ); - - return 0; -} - -void __exit kbd98io_exit(void) -{ - serio_unregister_port(&kbd98_port); -} - -module_init(kbd98io_init); -module_exit(kbd98io_exit); diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig --- a/drivers/input/serio/Kconfig 2004-06-26 17:09:18 -07:00 +++ b/drivers/input/serio/Kconfig 2004-06-26 17:09:18 -07:00 @@ -97,16 +97,6 @@ tristate "Intel SA1111 keyboard controller" depends on SA1111 && SERIO -config SERIO_98KBD - tristate "NEC PC-9800 keyboard controller" - depends on X86_PC9800 && SERIO - help - Say Y here if you have the NEC PC-9801/PC-9821 and want to use its - standard keyboard connected to its keyboard controller. - - To compile this driver as a module, choose M here: the - module will be called 98kbd-io. - config SERIO_GSCPS2 tristate "HP GSC PS/2 keyboard and PS/2 mouse controller" depends on GSC && SERIO diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c --- a/drivers/input/serio/ambakmi.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/input/serio/ambakmi.c 2004-06-26 17:09:19 -07:00 @@ -18,17 +18,19 @@ #include #include #include +#include #include #include #include #include +#include #define KMI_BASE (kmi->base) struct amba_kmi_port { struct serio io; - struct amba_kmi_port *next; + struct clk *clk; unsigned char *base; unsigned int irq; unsigned int divisor; @@ -67,21 +69,38 @@ static int amba_kmi_open(struct serio *io) { struct amba_kmi_port *kmi = io->driver; + unsigned int divisor; int ret; - writeb(kmi->divisor, KMICLKDIV); + ret = clk_use(kmi->clk); + if (ret) + goto out; + + ret = clk_enable(kmi->clk); + if (ret) + goto clk_unuse; + + divisor = clk_get_rate(kmi->clk) / 8000000 - 1; + writeb(divisor, KMICLKDIV); writeb(KMICR_EN, KMICR); ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi); if (ret) { printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq); writeb(0, KMICR); - return ret; + goto clk_disable; } writeb(KMICR_EN | KMICR_RXINTREN, KMICR); return 0; + + clk_disable: + clk_disable(kmi->clk); + clk_unuse: + clk_unuse(kmi->clk); + out: + return ret; } static void amba_kmi_close(struct serio *io) @@ -91,6 +110,8 @@ writeb(0, KMICR); free_irq(kmi->irq, kmi); + clk_disable(kmi->clk); + clk_unuse(kmi->clk); } static int amba_kmi_probe(struct amba_device *dev, void *id) @@ -124,14 +145,20 @@ goto out; } - kmi->irq = dev->irq[0]; - kmi->divisor = 24 / 8 - 1; + kmi->clk = clk_get(&dev->dev, "KMIREFCLK"); + if (IS_ERR(kmi->clk)) { + ret = PTR_ERR(kmi->clk); + goto unmap; + } + kmi->irq = dev->irq[0]; amba_set_drvdata(dev, kmi); serio_register_port(&kmi->io); return 0; + unmap: + iounmap(kmi->base); out: kfree(kmi); amba_release_regions(dev); @@ -145,6 +172,7 @@ amba_set_drvdata(dev, NULL); serio_unregister_port(&kmi->io); + clk_put(kmi->clk); iounmap(kmi->base); kfree(kmi); amba_release_regions(dev); diff -Nru a/drivers/input/tsdev.c b/drivers/input/tsdev.c --- a/drivers/input/tsdev.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/input/tsdev.c 2004-06-26 17:09:20 -07:00 @@ -151,7 +151,7 @@ return 0; } -static ssize_t tsdev_read(struct file *file, char *buffer, size_t count, +static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) { struct tsdev_list *list = file->private_data; diff -Nru a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c --- a/drivers/isdn/capi/capi.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/isdn/capi/capi.c 2004-06-26 17:09:20 -07:00 @@ -650,7 +650,7 @@ /* -------- file_operations for capidev ----------------------------- */ static ssize_t -capi_read(struct file *file, char *buf, size_t count, loff_t *ppos) +capi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct capidev *cdev = (struct capidev *)file->private_data; struct sk_buff *skb; @@ -693,7 +693,7 @@ } static ssize_t -capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct capidev *cdev = (struct capidev *)file->private_data; struct sk_buff *skb; @@ -766,6 +766,7 @@ struct capi20_appl *ap = &cdev->ap; capi_ioctl_struct data; int retval = -EINVAL; + void __user *argp = (void __user *)arg; switch (cmd) { case CAPI_REGISTER: @@ -773,7 +774,7 @@ if (ap->applid) return -EEXIST; - if (copy_from_user(&cdev->ap.rparam, (void *) arg, + if (copy_from_user(&cdev->ap.rparam, argp, sizeof(struct capi_register_params))) return -EFAULT; @@ -789,14 +790,13 @@ case CAPI_GET_VERSION: { - if (copy_from_user((void *) &data.contr, - (void *) arg, + if (copy_from_user(&data.contr, argp, sizeof(data.contr))) return -EFAULT; cdev->errcode = capi20_get_version(data.contr, &data.version); if (cdev->errcode) return -EIO; - if (copy_to_user((void *)arg, (void *)&data.version, + if (copy_to_user(argp, &data.version, sizeof(data.version))) return -EFAULT; } @@ -804,20 +804,20 @@ case CAPI_GET_SERIAL: { - if (copy_from_user((void *)&data.contr, (void *)arg, + if (copy_from_user(&data.contr, argp, sizeof(data.contr))) return -EFAULT; cdev->errcode = capi20_get_serial (data.contr, data.serial); if (cdev->errcode) return -EIO; - if (copy_to_user((void *)arg, (void *)data.serial, + if (copy_to_user(argp, data.serial, sizeof(data.serial))) return -EFAULT; } return 0; case CAPI_GET_PROFILE: { - if (copy_from_user((void *)&data.contr, (void *)arg, + if (copy_from_user(&data.contr, argp, sizeof(data.contr))) return -EFAULT; @@ -826,8 +826,8 @@ if (cdev->errcode) return -EIO; - retval = copy_to_user((void *) arg, - (void *) &data.profile.ncontroller, + retval = copy_to_user(argp, + &data.profile.ncontroller, sizeof(data.profile.ncontroller)); } else { @@ -835,8 +835,7 @@ if (cdev->errcode) return -EIO; - retval = copy_to_user((void *) arg, - (void *) &data.profile, + retval = copy_to_user(argp, &data.profile, sizeof(data.profile)); } if (retval) @@ -846,14 +845,14 @@ case CAPI_GET_MANUFACTURER: { - if (copy_from_user((void *)&data.contr, (void *)arg, + if (copy_from_user(&data.contr, argp, sizeof(data.contr))) return -EFAULT; cdev->errcode = capi20_get_manufacturer(data.contr, data.manufacturer); if (cdev->errcode) return -EIO; - if (copy_to_user((void *)arg, (void *)data.manufacturer, + if (copy_to_user(argp, data.manufacturer, sizeof(data.manufacturer))) return -EFAULT; @@ -863,7 +862,7 @@ data.errcode = cdev->errcode; cdev->errcode = CAPI_NOERROR; if (arg) { - if (copy_to_user((void *)arg, (void *)&data.errcode, + if (copy_to_user(argp, &data.errcode, sizeof(data.errcode))) return -EFAULT; } @@ -879,7 +878,7 @@ struct capi_manufacturer_cmd mcmd; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (copy_from_user((void *)&mcmd, (void *)arg, + if (copy_from_user(&mcmd, argp, sizeof(mcmd))) return -EFAULT; return capi20_manufacturer(mcmd.cmd, mcmd.data); @@ -890,7 +889,7 @@ case CAPI_CLR_FLAGS: { unsigned userflags; - if (copy_from_user((void *)&userflags, (void *)arg, + if (copy_from_user(&userflags, argp, sizeof(userflags))) return -EFAULT; if (cmd == CAPI_SET_FLAGS) @@ -901,7 +900,7 @@ return 0; case CAPI_GET_FLAGS: - if (copy_to_user((void *)arg, (void *)&cdev->userflags, + if (copy_to_user(argp, &cdev->userflags, sizeof(cdev->userflags))) return -EFAULT; return 0; @@ -914,8 +913,7 @@ #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ unsigned ncci; int count = 0; - if (copy_from_user((void *)&ncci, (void *)arg, - sizeof(ncci))) + if (copy_from_user(&ncci, argp, sizeof(ncci))) return -EFAULT; down(&cdev->ncci_list_sem); @@ -940,7 +938,7 @@ struct capiminor *mp; unsigned ncci; int unit = 0; - if (copy_from_user((void *)&ncci, (void *)arg, + if (copy_from_user(&ncci, argp, sizeof(ncci))) return -EFAULT; down(&cdev->ncci_list_sem); diff -Nru a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c --- a/drivers/isdn/i4l/isdn_common.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/isdn/i4l/isdn_common.c 2004-06-26 17:09:17 -07:00 @@ -64,7 +64,7 @@ #endif /* CONFIG_ISDN_DIVERSION */ -static int isdn_writebuf_stub(int, int, const u_char *, int, int); +static int isdn_writebuf_stub(int, int, const u_char __user *, int); static void set_global_features(void); static int isdn_wildmat(char *s, char *p); @@ -937,7 +937,7 @@ } static ssize_t -isdn_read(struct file *file, char *buf, size_t count, loff_t * off) +isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off) { uint minor = MINOR(file->f_dentry->d_inode->i_rdev); int len = 0; @@ -1044,7 +1044,7 @@ } static ssize_t -isdn_write(struct file *file, const char *buf, size_t count, loff_t * off) +isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off) { uint minor = MINOR(file->f_dentry->d_inode->i_rdev); int drvidx; @@ -1072,7 +1072,7 @@ goto out; } chidx = isdn_minor2chan(minor); - while (isdn_writebuf_stub(drvidx, chidx, buf, count, 1) != count) + while (isdn_writebuf_stub(drvidx, chidx, buf, count) != count) interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); retval = count; goto out; @@ -1159,7 +1159,7 @@ int chidx; int ret; int i; - char *p; + char __user *p; char *s; union iocpar { char name[10]; @@ -1168,6 +1168,7 @@ isdn_net_ioctl_phone phone; isdn_net_ioctl_cfg cfg; } iocpar; + void __user *argp = (void __user *)arg; #define name iocpar.name #define bname iocpar.bname @@ -1183,9 +1184,9 @@ (INF_DV << 16)); case IIOCGETCPS: if (arg) { - ulong *p = (ulong *) arg; + ulong __user *p = argp; int i; - if ((ret = verify_area(VERIFY_WRITE, (void *) arg, + if ((ret = verify_area(VERIFY_WRITE, p, sizeof(ulong) * ISDN_MAX_CHANNELS * 2))) return ret; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { @@ -1201,9 +1202,9 @@ /* Get peer phone number of a connected * isdn network interface */ if (arg) { - if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone))) + if (copy_from_user(&phone, argp, sizeof(phone))) return -EFAULT; - return isdn_net_getpeer(&phone, (isdn_net_ioctl_phone *) arg); + return isdn_net_getpeer(&phone, argp); } else return -EINVAL; #endif @@ -1241,7 +1242,7 @@ case IIOCNETAIF: /* Add a network-interface */ if (arg) { - if (copy_from_user(name, (char *) arg, sizeof(name))) + if (copy_from_user(name, argp, sizeof(name))) return -EFAULT; s = name; } else { @@ -1250,7 +1251,7 @@ ret = down_interruptible(&dev->sem); if( ret ) return ret; if ((s = isdn_net_new(s, NULL))) { - if (copy_to_user((char *) arg, s, strlen(s) + 1)){ + if (copy_to_user(argp, s, strlen(s) + 1)){ ret = -EFAULT; } else { ret = 0; @@ -1262,14 +1263,14 @@ case IIOCNETASL: /* Add a slave to a network-interface */ if (arg) { - if (copy_from_user(bname, (char *) arg, sizeof(bname) - 1)) + if (copy_from_user(bname, argp, sizeof(bname) - 1)) return -EFAULT; } else return -EINVAL; ret = down_interruptible(&dev->sem); if( ret ) return ret; if ((s = isdn_net_newslave(bname))) { - if (copy_to_user((char *) arg, s, strlen(s) + 1)){ + if (copy_to_user(argp, s, strlen(s) + 1)){ ret = -EFAULT; } else { ret = 0; @@ -1281,7 +1282,7 @@ case IIOCNETDIF: /* Delete a network-interface */ if (arg) { - if (copy_from_user(name, (char *) arg, sizeof(name))) + if (copy_from_user(name, argp, sizeof(name))) return -EFAULT; ret = down_interruptible(&dev->sem); if( ret ) return ret; @@ -1293,7 +1294,7 @@ case IIOCNETSCF: /* Set configurable parameters of a network-interface */ if (arg) { - if (copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg))) + if (copy_from_user(&cfg, argp, sizeof(cfg))) return -EFAULT; return isdn_net_setcfg(&cfg); } else @@ -1301,10 +1302,10 @@ case IIOCNETGCF: /* Get configurable parameters of a network-interface */ if (arg) { - if (copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg))) + if (copy_from_user(&cfg, argp, sizeof(cfg))) return -EFAULT; if (!(ret = isdn_net_getcfg(&cfg))) { - if (copy_to_user((char *) arg, (char *) &cfg, sizeof(cfg))) + if (copy_to_user(argp, &cfg, sizeof(cfg))) return -EFAULT; } return ret; @@ -1313,7 +1314,7 @@ case IIOCNETANM: /* Add a phone-number to a network-interface */ if (arg) { - if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone))) + if (copy_from_user(&phone, argp, sizeof(phone))) return -EFAULT; ret = down_interruptible(&dev->sem); if( ret ) return ret; @@ -1325,11 +1326,11 @@ case IIOCNETGNM: /* Get list of phone-numbers of a network-interface */ if (arg) { - if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone))) + if (copy_from_user(&phone, argp, sizeof(phone))) return -EFAULT; ret = down_interruptible(&dev->sem); if( ret ) return ret; - ret = isdn_net_getphones(&phone, (char *) arg); + ret = isdn_net_getphones(&phone, argp); up(&dev->sem); return ret; } else @@ -1337,7 +1338,7 @@ case IIOCNETDNM: /* Delete a phone-number of a network-interface */ if (arg) { - if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone))) + if (copy_from_user(&phone, argp, sizeof(phone))) return -EFAULT; ret = down_interruptible(&dev->sem); if( ret ) return ret; @@ -1349,7 +1350,7 @@ case IIOCNETDIL: /* Force dialing of a network-interface */ if (arg) { - if (copy_from_user(name, (char *) arg, sizeof(name))) + if (copy_from_user(name, argp, sizeof(name))) return -EFAULT; return isdn_net_force_dial(name); } else @@ -1358,13 +1359,13 @@ case IIOCNETALN: if (!arg) return -EINVAL; - if (copy_from_user(name, (char *) arg, sizeof(name))) + if (copy_from_user(name, argp, sizeof(name))) return -EFAULT; return isdn_ppp_dial_slave(name); case IIOCNETDLN: if (!arg) return -EINVAL; - if (copy_from_user(name, (char *) arg, sizeof(name))) + if (copy_from_user(name, argp, sizeof(name))) return -EFAULT; return isdn_ppp_hangup_slave(name); #endif @@ -1372,7 +1373,7 @@ /* Force hangup of a network-interface */ if (!arg) return -EINVAL; - if (copy_from_user(name, (char *) arg, sizeof(name))) + if (copy_from_user(name, argp, sizeof(name))) return -EFAULT; return isdn_net_force_hangup(name); break; @@ -1394,7 +1395,7 @@ if (arg) { int i; char *p; - if (copy_from_user((char *) &iocts, (char *) arg, + if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct))) return -EFAULT; if (strlen(iocts.drvid)) { @@ -1422,10 +1423,10 @@ case IIOCGETPRF: /* Get all Modem-Profiles */ if (arg) { - char *p = (char *) arg; + char __user *p = argp; int i; - if ((ret = verify_area(VERIFY_WRITE, (void *) arg, + if ((ret = verify_area(VERIFY_WRITE, argp, (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS))) return ret; @@ -1449,10 +1450,10 @@ case IIOCSETPRF: /* Set all Modem-Profiles */ if (arg) { - char *p = (char *) arg; + char __user *p = argp; int i; - if ((ret = verify_area(VERIFY_READ, (void *) arg, + if ((ret = verify_area(VERIFY_READ, argp, (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS))) return ret; @@ -1478,8 +1479,7 @@ /* Set/Get MSN->EAZ-Mapping for a driver */ if (arg) { - if (copy_from_user((char *) &iocts, - (char *) arg, + if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct))) return -EFAULT; if (strlen(iocts.drvid)) { @@ -1496,7 +1496,7 @@ if (cmd == IIOCSETMAP) { int loop = 1; - p = (char *) iocts.arg; + p = (char __user *) iocts.arg; i = 0; while (loop) { int j = 0; @@ -1524,7 +1524,7 @@ break; } } else { - p = (char *) iocts.arg; + p = (char __user *) iocts.arg; for (i = 0; i < 10; i++) { sprintf(bname, "%s%s", strlen(dev->drv[drvidx]->msn2eaz[i]) ? @@ -1540,7 +1540,7 @@ return -EINVAL; case IIOCDBGVAR: if (arg) { - if (copy_to_user((char *) arg, (char *) &dev, sizeof(ulong))) + if (copy_to_user(argp, &dev, sizeof(ulong))) return -EFAULT; return 0; } else @@ -1554,7 +1554,7 @@ if (arg) { int i; char *p; - if (copy_from_user((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct))) + if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct))) return -EFAULT; if (strlen(iocts.drvid)) { if ((p = strchr(iocts.drvid, ','))) @@ -1569,16 +1569,16 @@ drvidx = 0; if (drvidx == -1) return -ENODEV; - if ((ret = verify_area(VERIFY_WRITE, (void *) arg, + if ((ret = verify_area(VERIFY_WRITE, argp, sizeof(isdn_ioctl_struct)))) return ret; c.driver = drvidx; c.command = ISDN_CMD_IOCTL; c.arg = cmd; - memcpy(c.parm.num, (char *) &iocts.arg, sizeof(ulong)); + memcpy(c.parm.num, &iocts.arg, sizeof(ulong)); ret = isdn_command(&c); - memcpy((char *) &iocts.arg, c.parm.num, sizeof(ulong)); - if (copy_to_user((char *) arg, &iocts, sizeof(isdn_ioctl_struct))) + memcpy(&iocts.arg, c.parm.num, sizeof(ulong)); + if (copy_to_user(argp, &iocts, sizeof(isdn_ioctl_struct))) return -EFAULT; return ret; } else @@ -1838,8 +1838,7 @@ * writebuf replacement for SKB_ABLE drivers */ static int -isdn_writebuf_stub(int drvidx, int chan, const u_char * buf, int len, - int user) +isdn_writebuf_stub(int drvidx, int chan, const u_char __user * buf, int len) { int ret; int hl = dev->drv[drvidx]->interface->hl_hdrlen; @@ -1848,10 +1847,7 @@ if (!skb) return 0; skb_reserve(skb, hl); - if (user) - copy_from_user(skb_put(skb, len), buf, len); - else - memcpy(skb_put(skb, len), buf, len); + copy_from_user(skb_put(skb, len), buf, len); ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb); if (ret <= 0) dev_kfree_skb(skb); diff -Nru a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c --- a/drivers/isdn/i4l/isdn_net.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/isdn/i4l/isdn_net.c 2004-06-26 17:09:21 -07:00 @@ -315,7 +315,7 @@ unsigned long last_jiffies = -HZ; void -isdn_net_autohup() +isdn_net_autohup(void) { isdn_net_dev *p = dev->netdev; int anymore; @@ -1443,15 +1443,14 @@ /* get/set keepalive period */ case SIOCGKEEPPERIOD: len = (unsigned long)sizeof(lp->cisco_keepalive_period); - if (copy_to_user((char *)ifr->ifr_ifru.ifru_data, - (int *)&lp->cisco_keepalive_period, len)) + if (copy_to_user(ifr->ifr_data, + &lp->cisco_keepalive_period, len)) rc = -EFAULT; break; case SIOCSKEEPPERIOD: tmp = lp->cisco_keepalive_period; len = (unsigned long)sizeof(lp->cisco_keepalive_period); - if (copy_from_user((int *)&period, - (char *)ifr->ifr_ifru.ifru_data, len)) + if (copy_from_user(&period, ifr->ifr_data, len)) rc = -EFAULT; if ((period > 0) && (period <= 32767)) lp->cisco_keepalive_period = period; @@ -1470,14 +1469,14 @@ /* get/set debugging */ case SIOCGDEBSERINT: len = (unsigned long)sizeof(lp->cisco_debserint); - if (copy_to_user((char *)ifr->ifr_ifru.ifru_data, - (char *)&lp->cisco_debserint, len)) + if (copy_to_user(ifr->ifr_data, + &lp->cisco_debserint, len)) rc = -EFAULT; break; case SIOCSDEBSERINT: len = (unsigned long)sizeof(lp->cisco_debserint); - if (copy_from_user((char *)&debserint, - (char *)ifr->ifr_ifru.ifru_data, len)) + if (copy_from_user(&debserint, + ifr->ifr_data, len)) rc = -EFAULT; if ((debserint >= 0) && (debserint <= 64)) lp->cisco_debserint = debserint; @@ -2968,7 +2967,7 @@ * This might sleep and must be called with the isdn semaphore down. */ int -isdn_net_getphones(isdn_net_ioctl_phone * phone, char *phones) +isdn_net_getphones(isdn_net_ioctl_phone * phone, char __user *phones) { isdn_net_dev *p = isdn_net_findif(phone->name); int inout = phone->outgoing & 1; @@ -3001,7 +3000,7 @@ * to user space. */ int -isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone *peer) +isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer) { isdn_net_dev *p = isdn_net_findif(phone->name); int ch, dv, idx; diff -Nru a/drivers/isdn/i4l/isdn_net.h b/drivers/isdn/i4l/isdn_net.h --- a/drivers/isdn/i4l/isdn_net.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/isdn/i4l/isdn_net.h 2004-06-26 17:09:20 -07:00 @@ -39,8 +39,8 @@ extern int isdn_net_setcfg(isdn_net_ioctl_cfg *); extern int isdn_net_getcfg(isdn_net_ioctl_cfg *); extern int isdn_net_addphone(isdn_net_ioctl_phone *); -extern int isdn_net_getphones(isdn_net_ioctl_phone *, char *); -extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone *); +extern int isdn_net_getphones(isdn_net_ioctl_phone *, char __user *); +extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone __user *); extern int isdn_net_delphone(isdn_net_ioctl_phone *); extern int isdn_net_find_icall(int, int, int, setup_parm *); extern void isdn_net_hangup(struct net_device *); diff -Nru a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c --- a/drivers/isdn/i4l/isdn_ppp.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/isdn/i4l/isdn_ppp.c 2004-06-26 17:09:19 -07:00 @@ -320,8 +320,8 @@ is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */ #endif #ifdef CONFIG_IPPP_FILTER - is->pass_filter.filter = NULL; - is->active_filter.filter = NULL; + is->pass_filter = NULL; + is->active_filter = NULL; #endif is->state = IPPP_OPEN; @@ -378,13 +378,13 @@ is->slcomp = NULL; #endif #ifdef CONFIG_IPPP_FILTER - if (is->pass_filter.filter) { - kfree(is->pass_filter.filter); - is->pass_filter.filter = NULL; - } - if (is->active_filter.filter) { - kfree(is->active_filter.filter); - is->active_filter.filter = NULL; + if (is->pass_filter) { + kfree(is->pass_filter); + is->pass_filter = NULL; + } + if (is->active_filter) { + kfree(is->active_filter); + is->active_filter = NULL; } #endif @@ -414,11 +414,11 @@ * get_arg .. ioctl helper */ static int -get_arg(void *b, void *val, int len) +get_arg(void __user *b, void *val, int len) { if (len <= 0) len = sizeof(void *); - if (copy_from_user((void *) val, b, len)) + if (copy_from_user(val, b, len)) return -EFAULT; return 0; } @@ -427,15 +427,50 @@ * set arg .. ioctl helper */ static int -set_arg(void *b, void *val,int len) +set_arg(void __user *b, void *val,int len) { if(len <= 0) len = sizeof(void *); - if (copy_to_user(b, (void *) val, len)) + if (copy_to_user(b, val, len)) return -EFAULT; return 0; } +static int get_filter(void __user *arg, struct sock_filter **p) +{ + struct sock_fprog uprog; + struct sock_filter *code = NULL; + int len, err; + + if (copy_from_user(&uprog, arg, sizeof(uprog))) + return -EFAULT; + + if (!uprog.len) { + *p = NULL; + return 0; + } + + /* uprog.len is unsigned short, so no overflow here */ + len = uprog.len * sizeof(struct sock_filter); + code = kmalloc(len, GFP_KERNEL); + if (code == NULL) + return -ENOMEM; + + if (copy_from_user(code, uprog.filter, len)) { + kfree(code); + return -EFAULT; + } + + err = sk_chk_filter(code, uprog.len); + if (err) { + kfree(code); + return err; + } + + *p = code; + return uprog.len; +} + /* * ippp device ioctl */ @@ -447,6 +482,7 @@ struct ippp_struct *is; isdn_net_local *lp; struct isdn_ppp_comp_data data; + void __user *argp = (void __user *)arg; is = (struct ippp_struct *) file->private_data; lp = is->lp; @@ -462,7 +498,7 @@ #ifdef CONFIG_ISDN_MPP if (!(is->state & IPPP_CONNECT)) return -EINVAL; - if ((r = get_arg((void *) arg, &val, sizeof(val) ))) + if ((r = get_arg(argp, &val, sizeof(val) ))) return r; printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n", (int) min, (int) is->unit, (int) val); @@ -472,30 +508,30 @@ #endif break; case PPPIOCGUNIT: /* get ppp/isdn unit number */ - if ((r = set_arg((void *) arg, &is->unit, sizeof(is->unit) ))) + if ((r = set_arg(argp, &is->unit, sizeof(is->unit) ))) return r; break; case PPPIOCGIFNAME: if(!lp) return -EINVAL; - if ((r = set_arg((void *) arg, lp->name, strlen(lp->name)))) + if ((r = set_arg(argp, lp->name, strlen(lp->name)))) return r; break; case PPPIOCGMPFLAGS: /* get configuration flags */ - if ((r = set_arg((void *) arg, &is->mpppcfg, sizeof(is->mpppcfg) ))) + if ((r = set_arg(argp, &is->mpppcfg, sizeof(is->mpppcfg) ))) return r; break; case PPPIOCSMPFLAGS: /* set configuration flags */ - if ((r = get_arg((void *) arg, &val, sizeof(val) ))) + if ((r = get_arg(argp, &val, sizeof(val) ))) return r; is->mpppcfg = val; break; case PPPIOCGFLAGS: /* get configuration flags */ - if ((r = set_arg((void *) arg, &is->pppcfg,sizeof(is->pppcfg) ))) + if ((r = set_arg(argp, &is->pppcfg,sizeof(is->pppcfg) ))) return r; break; case PPPIOCSFLAGS: /* set configuration flags */ - if ((r = get_arg((void *) arg, &val, sizeof(val) ))) { + if ((r = get_arg(argp, &val, sizeof(val) ))) { return r; } if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) { @@ -512,12 +548,12 @@ if (lp) { struct ppp_idle pidle; pidle.xmit_idle = pidle.recv_idle = lp->huptimer; - if ((r = set_arg((void *) arg, &pidle,sizeof(struct ppp_idle)))) + if ((r = set_arg(argp, &pidle,sizeof(struct ppp_idle)))) return r; } break; case PPPIOCSMRU: /* set receive unit size for PPP */ - if ((r = get_arg((void *) arg, &val, sizeof(val) ))) + if ((r = get_arg(argp, &val, sizeof(val) ))) return r; is->mru = val; break; @@ -526,7 +562,7 @@ case PPPIOCSMPMTU: break; case PPPIOCSMAXCID: /* set the maximum compression slot id */ - if ((r = get_arg((void *) arg, &val, sizeof(val) ))) + if ((r = get_arg(argp, &val, sizeof(val) ))) return r; val++; if (is->maxcid != val) { @@ -549,11 +585,11 @@ } break; case PPPIOCGDEBUG: - if ((r = set_arg((void *) arg, &is->debug, sizeof(is->debug) ))) + if ((r = set_arg(argp, &is->debug, sizeof(is->debug) ))) return r; break; case PPPIOCSDEBUG: - if ((r = get_arg((void *) arg, &val, sizeof(val) ))) + if ((r = get_arg(argp, &val, sizeof(val) ))) return r; is->debug = val; break; @@ -568,12 +604,12 @@ protos[j] |= (0x1<next; } - if ((r = set_arg((void *) arg,protos,8*sizeof(long) ))) + if ((r = set_arg(argp,protos,8*sizeof(long) ))) return r; } break; case PPPIOCSCOMPRESSOR: - if ((r = get_arg((void *) arg, &data, sizeof(struct isdn_ppp_comp_data)))) + if ((r = get_arg(argp, &data, sizeof(struct isdn_ppp_comp_data)))) return r; return isdn_ppp_set_compressor(is, &data); case PPPIOCGCALLINFO: @@ -594,38 +630,29 @@ if(lp->flags & ISDN_NET_CALLBACK) pci.calltype |= CALLTYPE_CALLBACK; } - return set_arg((void *)arg,&pci,sizeof(struct pppcallinfo)); + return set_arg(argp,&pci,sizeof(struct pppcallinfo)); } #ifdef CONFIG_IPPP_FILTER case PPPIOCSPASS: + { + struct sock_filter *code; + int len = get_filter(argp, &code); + if (len < 0) + return len; + kfree(is->pass_filter); + is->pass_filter = code; + is->pass_len = len; + break; + } case PPPIOCSACTIVE: { - struct sock_fprog uprog, *filtp; - struct sock_filter *code = NULL; - int len, err; - - if (copy_from_user(&uprog, (void *) arg, sizeof(uprog))) - return -EFAULT; - if (uprog.len > 0) { - len = uprog.len * sizeof(struct sock_filter); - code = kmalloc(len, GFP_KERNEL); - if (code == NULL) - return -ENOMEM; - if (copy_from_user(code, uprog.filter, len)) { - kfree(code); - return -EFAULT; - } - err = sk_chk_filter(code, uprog.len); - if (err) { - kfree(code); - return err; - } - } - filtp = (cmd == PPPIOCSPASS) ? &is->pass_filter : &is->active_filter; - if (filtp->filter) - kfree(filtp->filter); - filtp->filter = code; - filtp->len = uprog.len; + struct sock_filter *code; + int len = get_filter(argp, &code); + if (len < 0) + return len; + kfree(is->active_filter); + is->active_filter = code; + is->active_len = len; break; } #endif /* CONFIG_IPPP_FILTER */ @@ -733,7 +760,7 @@ */ int -isdn_ppp_read(int min, struct file *file, char *buf, int count) +isdn_ppp_read(int min, struct file *file, char __user *buf, int count) { struct ippp_struct *is; struct ippp_buf_queue *b; @@ -746,7 +773,7 @@ if (!(is->state & IPPP_OPEN)) return 0; - if ((r = verify_area(VERIFY_WRITE, (void *) buf, count))) + if ((r = verify_area(VERIFY_WRITE, buf, count))) return r; spin_lock_irqsave(&is->buflock, flags); @@ -773,7 +800,7 @@ */ int -isdn_ppp_write(int min, struct file *file, const char *buf, int count) +isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) { isdn_net_local *lp; struct ippp_struct *is; @@ -1128,17 +1155,16 @@ *p = 0; /* indicate inbound in DLT_LINUX_SLL */ } - if (is->pass_filter.filter - && sk_run_filter(skb, is->pass_filter.filter, - is->pass_filter.len) == 0) { + if (is->pass_filter + && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: inbound frame filtered.\n"); kfree_skb(skb); return; } - if (!(is->active_filter.filter - && sk_run_filter(skb, is->active_filter.filter, - is->active_filter.len) == 0)) { + if (!(is->active_filter + && sk_run_filter(skb, is->active_filter, + is->active_len) == 0)) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); lp->huptimer = 0; @@ -1276,17 +1302,16 @@ *p = htons(proto); } - if (ipt->pass_filter.filter - && sk_run_filter(skb, ipt->pass_filter.filter, - ipt->pass_filter.len) == 0) { + if (ipt->pass_filter + && sk_run_filter(skb, ipt->pass_filter, ipt->pass_len) == 0) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: outbound frame filtered.\n"); kfree_skb(skb); goto unlock; } - if (!(ipt->active_filter.filter - && sk_run_filter(skb, ipt->active_filter.filter, - ipt->active_filter.len) == 0)) { + if (!(ipt->active_filter + && sk_run_filter(skb, ipt->active_filter, + ipt->active_len) == 0)) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); lp->huptimer = 0; @@ -1475,12 +1500,10 @@ *p = htons(proto); } - drop |= is->pass_filter.filter - && sk_run_filter(skb, is->pass_filter.filter, - is->pass_filter.len) == 0; - drop |= is->active_filter.filter - && sk_run_filter(skb, is->active_filter.filter, - is->active_filter.len) == 0; + drop |= is->pass_filter + && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0; + drop |= is->active_filter + && sk_run_filter(skb, is->active_filter, is->active_len) == 0; skb_push(skb, IPPP_MAX_HEADER - 4); return drop; @@ -1969,12 +1992,11 @@ static int isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev) { - struct ppp_stats *res, - t; + struct ppp_stats __user *res = ifr->ifr_data; + struct ppp_stats t; isdn_net_local *lp = (isdn_net_local *) dev->priv; int err; - res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data; err = verify_area(VERIFY_WRITE, res, sizeof(struct ppp_stats)); if (err) @@ -2004,7 +2026,8 @@ } #endif } - if( copy_to_user(res, &t, sizeof(struct ppp_stats))) return -EFAULT; + if (copy_to_user(res, &t, sizeof(struct ppp_stats))) + return -EFAULT; return 0; } @@ -2012,7 +2035,6 @@ isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int error=0; - char *r; int len; isdn_net_local *lp = (isdn_net_local *) dev->priv; @@ -2023,9 +2045,8 @@ switch (cmd) { #define PPP_VERSION "2.3.7" case SIOCGPPPVER: - r = (char *) ifr->ifr_ifru.ifru_data; len = strlen(PPP_VERSION) + 1; - if (copy_to_user(r, PPP_VERSION, len)) + if (copy_to_user(ifr->ifr_data, PPP_VERSION, len)) error = -EFAULT; break; diff -Nru a/drivers/isdn/i4l/isdn_ppp.h b/drivers/isdn/i4l/isdn_ppp.h --- a/drivers/isdn/i4l/isdn_ppp.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/isdn/i4l/isdn_ppp.h 2004-06-26 17:09:17 -07:00 @@ -12,8 +12,8 @@ #include /* for PPP_PROTOCOL */ #include /* for isdn_ppp info */ -extern int isdn_ppp_read(int, struct file *, char *, int); -extern int isdn_ppp_write(int, struct file *, const char *, int); +extern int isdn_ppp_read(int, struct file *, char __user *, int); +extern int isdn_ppp_write(int, struct file *, const char __user *, int); extern int isdn_ppp_open(int, struct file *); extern int isdn_ppp_init(void); extern void isdn_ppp_cleanup(void); diff -Nru a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c --- a/drivers/isdn/i4l/isdn_tty.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/isdn/i4l/isdn_tty.c 2004-06-26 17:09:19 -07:00 @@ -1359,14 +1359,14 @@ * allows RS485 driver to be written in user space. */ static int -isdn_tty_get_lsr_info(modem_info * info, uint * value) +isdn_tty_get_lsr_info(modem_info * info, uint __user * value) { u_char status; uint result; status = info->lsr; result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - return put_user(result, (uint *) value); + return put_user(result, value); } @@ -1468,12 +1468,12 @@ #ifdef ISDN_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "ttyI%d ioctl TIOCGSOFTCAR\n", info->line); #endif - return put_user(C_CLOCAL(tty) ? 1 : 0, (ulong *) arg); + return put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg); case TIOCSSOFTCAR: #ifdef ISDN_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "ttyI%d ioctl TIOCSSOFTCAR\n", info->line); #endif - if (get_user(arg, (ulong *) arg)) + if (get_user(arg, (ulong __user *) arg)) return -EFAULT; tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | diff -Nru a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c --- a/drivers/isdn/i4l/isdn_x25iface.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/isdn/i4l/isdn_x25iface.c 2004-06-26 17:09:17 -07:00 @@ -79,7 +79,7 @@ /* create a new x25 interface protocol instance */ -struct concap_proto * isdn_x25iface_proto_new() +struct concap_proto * isdn_x25iface_proto_new(void) { ix25_pdata_t * tmp = kmalloc(sizeof(ix25_pdata_t),GFP_KERNEL); IX25DEBUG("isdn_x25iface_proto_new\n"); @@ -275,8 +275,7 @@ int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb) { unsigned char firstbyte = skb->data[0]; - unsigned *state = - &( ( (ix25_pdata_t*) (cprot -> proto_data) ) -> state ); + enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state; int ret = 0; IX25DEBUG( "isdn_x25iface_xmit: %s first=%x state=%d \n", MY_DEVNAME(cprot -> net_dev), firstbyte, *state ); switch ( firstbyte ){ diff -Nru a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c --- a/drivers/isdn/sc/message.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/isdn/sc/message.c 2004-06-26 17:09:20 -07:00 @@ -30,7 +30,6 @@ */ extern int indicate_status(int,ulong,char*); extern int scm_command(isdn_ctrl *); -extern void *memcpy_fromshmem(int, void *, const void *, size_t); /* diff -Nru a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c --- a/drivers/isdn/sc/packet.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/isdn/sc/packet.c 2004-06-26 17:09:21 -07:00 @@ -25,8 +25,8 @@ extern int get_card_from_id(int); extern int indicate_status(int, int,ulong, char*); -extern void *memcpy_toshmem(int, void *, const void *, size_t); -extern void *memcpy_fromshmem(int, void *, const void *, size_t); +extern void memcpy_toshmem(int, void *, const void *, size_t); +extern void memcpy_fromshmem(int, void *, const void *, size_t); extern int sendmessage(int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int *); diff -Nru a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c --- a/drivers/isdn/sc/shmem.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/isdn/sc/shmem.c 2004-06-26 17:09:17 -07:00 @@ -30,19 +30,18 @@ /* * */ -void *memcpy_toshmem(int card, void *dest, const void *src, size_t n) +void memcpy_toshmem(int card, void *dest, const void *src, size_t n) { unsigned long flags; - void *ret; unsigned char ch; if(!IS_VALID_CARD(card)) { pr_debug("Invalid param: %d is not a valid card id\n", card); - return NULL; + return; } if(n > SRAM_PAGESIZE) { - return NULL; + return; } /* @@ -57,7 +56,7 @@ outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]); - ret = memcpy_toio(sc_adapter[card]->rambase + + memcpy_toio(sc_adapter[card]->rambase + ((unsigned long) dest % 0x4000), src, n); spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, @@ -66,26 +65,23 @@ sc_adapter[card]->devicename, n, (unsigned long) src, sc_adapter[card]->rambase + ((unsigned long) dest %0x4000)); - - return ret; } /* * Reverse of above */ -void *memcpy_fromshmem(int card, void *dest, const void *src, size_t n) +void memcpy_fromshmem(int card, void *dest, const void *src, size_t n) { unsigned long flags; - void *ret; unsigned char ch; if(!IS_VALID_CARD(card)) { pr_debug("Invalid param: %d is not a valid card id\n", card); - return NULL; + return; } if(n > SRAM_PAGESIZE) { - return NULL; + return; } /* @@ -102,7 +98,7 @@ outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]); - ret = memcpy_fromio(dest,(void *)(sc_adapter[card]->rambase + + memcpy_fromio(dest,(void *)(sc_adapter[card]->rambase + ((unsigned long) src % 0x4000)), n); spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, @@ -110,23 +106,20 @@ /* pr_debug("%s: copying %d bytes from %#x to %#x\n", sc_adapter[card]->devicename, n, sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */ - - return ret; } -void *memset_shmem(int card, void *dest, int c, size_t n) +void memset_shmem(int card, void *dest, int c, size_t n) { unsigned long flags; unsigned char ch; - void *ret; if(!IS_VALID_CARD(card)) { pr_debug("Invalid param: %d is not a valid card id\n", card); - return NULL; + return; } if(n > SRAM_PAGESIZE) { - return NULL; + return; } /* @@ -142,11 +135,9 @@ outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]); - ret = memset_io(sc_adapter[card]->rambase + + memset_io(sc_adapter[card]->rambase + ((unsigned long) dest % 0x4000), c, n); pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); - - return ret; } diff -Nru a/drivers/md/Kconfig b/drivers/md/Kconfig --- a/drivers/md/Kconfig 2004-06-26 17:09:15 -07:00 +++ b/drivers/md/Kconfig 2004-06-26 17:09:15 -07:00 @@ -180,5 +180,25 @@ If unsure, say N. +config DM_SNAPSHOT + tristate "Snapshot target (EXPERIMENTAL)" + depends on BLK_DEV_DM && EXPERIMENTAL + ---help--- + Allow volume managers to take writeable snapshots of a device. + +config DM_MIRROR + tristate "Mirror target (EXPERIMENTAL)" + depends on BLK_DEV_DM && EXPERIMENTAL + ---help--- + Allow volume managers to mirror logical volumes, also + needed for live data migration tools such as 'pvmove'. + +config DM_ZERO + tristate "Zero target (EXPERIMENTAL)" + depends on BLK_DEV_DM && EXPERIMENTAL + ---help--- + A target that discards writes, and returns all zeroes for + reads. Useful in some recovery situations. + endmenu diff -Nru a/drivers/md/Makefile b/drivers/md/Makefile --- a/drivers/md/Makefile 2004-06-26 17:09:18 -07:00 +++ b/drivers/md/Makefile 2004-06-26 17:09:18 -07:00 @@ -3,7 +3,9 @@ # dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ - dm-ioctl.o + dm-ioctl.o dm-io.o kcopyd.o +dm-snapshot-objs := dm-snap.o dm-exception-store.o +dm-mirror-objs := dm-log.o dm-raid1.o raid6-objs := raid6main.o raid6algos.o raid6recov.o raid6tables.o \ raid6int1.o raid6int2.o raid6int4.o \ raid6int8.o raid6int16.o raid6int32.o \ @@ -24,6 +26,9 @@ obj-$(CONFIG_BLK_DEV_MD) += md.o obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o obj-$(CONFIG_DM_CRYPT) += dm-crypt.o +obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o +obj-$(CONFIG_DM_MIRROR) += dm-mirror.o +obj-$(CONFIG_DM_ZERO) += dm-zero.o quiet_cmd_unroll = UNROLL $@ cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \ diff -Nru a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-exception-store.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,648 @@ +/* + * dm-snapshot.c + * + * Copyright (C) 2001-2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "dm.h" +#include "dm-snap.h" +#include "dm-io.h" +#include "kcopyd.h" + +#include +#include +#include +#include + +/*----------------------------------------------------------------- + * Persistent snapshots, by persistent we mean that the snapshot + * will survive a reboot. + *---------------------------------------------------------------*/ + +/* + * We need to store a record of which parts of the origin have + * been copied to the snapshot device. The snapshot code + * requires that we copy exception chunks to chunk aligned areas + * of the COW store. It makes sense therefore, to store the + * metadata in chunk size blocks. + * + * There is no backward or forward compatibility implemented, + * snapshots with different disk versions than the kernel will + * not be usable. It is expected that "lvcreate" will blank out + * the start of a fresh COW device before calling the snapshot + * constructor. + * + * The first chunk of the COW device just contains the header. + * After this there is a chunk filled with exception metadata, + * followed by as many exception chunks as can fit in the + * metadata areas. + * + * All on disk structures are in little-endian format. The end + * of the exceptions info is indicated by an exception with a + * new_chunk of 0, which is invalid since it would point to the + * header chunk. + */ + +/* + * Magic for persistent snapshots: "SnAp" - Feeble isn't it. + */ +#define SNAP_MAGIC 0x70416e53 + +/* + * The on-disk version of the metadata. + */ +#define SNAPSHOT_DISK_VERSION 1 + +struct disk_header { + uint32_t magic; + + /* + * Is this snapshot valid. There is no way of recovering + * an invalid snapshot. + */ + uint32_t valid; + + /* + * Simple, incrementing version. no backward + * compatibility. + */ + uint32_t version; + + /* In sectors */ + uint32_t chunk_size; +}; + +struct disk_exception { + uint64_t old_chunk; + uint64_t new_chunk; +}; + +struct commit_callback { + void (*callback)(void *, int success); + void *context; +}; + +/* + * The top level structure for a persistent exception store. + */ +struct pstore { + struct dm_snapshot *snap; /* up pointer to my snapshot */ + int version; + int valid; + uint32_t chunk_size; + uint32_t exceptions_per_area; + + /* + * Now that we have an asynchronous kcopyd there is no + * need for large chunk sizes, so it wont hurt to have a + * whole chunks worth of metadata in memory at once. + */ + void *area; + + /* + * Used to keep track of which metadata area the data in + * 'chunk' refers to. + */ + uint32_t current_area; + + /* + * The next free chunk for an exception. + */ + uint32_t next_free; + + /* + * The index of next free exception in the current + * metadata area. + */ + uint32_t current_committed; + + atomic_t pending_count; + uint32_t callback_count; + struct commit_callback *callbacks; +}; + +static inline unsigned int sectors_to_pages(unsigned int sectors) +{ + return sectors / (PAGE_SIZE >> 9); +} + +static int alloc_area(struct pstore *ps) +{ + int r = -ENOMEM; + size_t len; + + len = ps->chunk_size << SECTOR_SHIFT; + + /* + * Allocate the chunk_size block of memory that will hold + * a single metadata area. + */ + ps->area = vmalloc(len); + if (!ps->area) + return r; + + return 0; +} + +static void free_area(struct pstore *ps) +{ + vfree(ps->area); +} + +/* + * Read or write a chunk aligned and sized block of data from a device. + */ +static int chunk_io(struct pstore *ps, uint32_t chunk, int rw) +{ + struct io_region where; + unsigned long bits; + + where.bdev = ps->snap->cow->bdev; + where.sector = ps->chunk_size * chunk; + where.count = ps->chunk_size; + + return dm_io_sync_vm(1, &where, rw, ps->area, &bits); +} + +/* + * Read or write a metadata area. Remembering to skip the first + * chunk which holds the header. + */ +static int area_io(struct pstore *ps, uint32_t area, int rw) +{ + int r; + uint32_t chunk; + + /* convert a metadata area index to a chunk index */ + chunk = 1 + ((ps->exceptions_per_area + 1) * area); + + r = chunk_io(ps, chunk, rw); + if (r) + return r; + + ps->current_area = area; + return 0; +} + +static int zero_area(struct pstore *ps, uint32_t area) +{ + memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); + return area_io(ps, area, WRITE); +} + +static int read_header(struct pstore *ps, int *new_snapshot) +{ + int r; + struct disk_header *dh; + + r = chunk_io(ps, 0, READ); + if (r) + return r; + + dh = (struct disk_header *) ps->area; + + if (le32_to_cpu(dh->magic) == 0) { + *new_snapshot = 1; + + } else if (le32_to_cpu(dh->magic) == SNAP_MAGIC) { + *new_snapshot = 0; + ps->valid = le32_to_cpu(dh->valid); + ps->version = le32_to_cpu(dh->version); + ps->chunk_size = le32_to_cpu(dh->chunk_size); + + } else { + DMWARN("Invalid/corrupt snapshot"); + r = -ENXIO; + } + + return r; +} + +static int write_header(struct pstore *ps) +{ + struct disk_header *dh; + + memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); + + dh = (struct disk_header *) ps->area; + dh->magic = cpu_to_le32(SNAP_MAGIC); + dh->valid = cpu_to_le32(ps->valid); + dh->version = cpu_to_le32(ps->version); + dh->chunk_size = cpu_to_le32(ps->chunk_size); + + return chunk_io(ps, 0, WRITE); +} + +/* + * Access functions for the disk exceptions, these do the endian conversions. + */ +static struct disk_exception *get_exception(struct pstore *ps, uint32_t index) +{ + if (index >= ps->exceptions_per_area) + return NULL; + + return ((struct disk_exception *) ps->area) + index; +} + +static int read_exception(struct pstore *ps, + uint32_t index, struct disk_exception *result) +{ + struct disk_exception *e; + + e = get_exception(ps, index); + if (!e) + return -EINVAL; + + /* copy it */ + result->old_chunk = le64_to_cpu(e->old_chunk); + result->new_chunk = le64_to_cpu(e->new_chunk); + + return 0; +} + +static int write_exception(struct pstore *ps, + uint32_t index, struct disk_exception *de) +{ + struct disk_exception *e; + + e = get_exception(ps, index); + if (!e) + return -EINVAL; + + /* copy it */ + e->old_chunk = cpu_to_le64(de->old_chunk); + e->new_chunk = cpu_to_le64(de->new_chunk); + + return 0; +} + +/* + * Registers the exceptions that are present in the current area. + * 'full' is filled in to indicate if the area has been + * filled. + */ +static int insert_exceptions(struct pstore *ps, int *full) +{ + int r; + unsigned int i; + struct disk_exception de; + + /* presume the area is full */ + *full = 1; + + for (i = 0; i < ps->exceptions_per_area; i++) { + r = read_exception(ps, i, &de); + + if (r) + return r; + + /* + * If the new_chunk is pointing at the start of + * the COW device, where the first metadata area + * is we know that we've hit the end of the + * exceptions. Therefore the area is not full. + */ + if (de.new_chunk == 0LL) { + ps->current_committed = i; + *full = 0; + break; + } + + /* + * Keep track of the start of the free chunks. + */ + if (ps->next_free <= de.new_chunk) + ps->next_free = de.new_chunk + 1; + + /* + * Otherwise we add the exception to the snapshot. + */ + r = dm_add_exception(ps->snap, de.old_chunk, de.new_chunk); + if (r) + return r; + } + + return 0; +} + +static int read_exceptions(struct pstore *ps) +{ + uint32_t area; + int r, full = 1; + + /* + * Keeping reading chunks and inserting exceptions until + * we find a partially full area. + */ + for (area = 0; full; area++) { + r = area_io(ps, area, READ); + if (r) + return r; + + r = insert_exceptions(ps, &full); + if (r) + return r; + } + + return 0; +} + +static inline struct pstore *get_info(struct exception_store *store) +{ + return (struct pstore *) store->context; +} + +static void persistent_fraction_full(struct exception_store *store, + sector_t *numerator, sector_t *denominator) +{ + *numerator = get_info(store)->next_free * store->snap->chunk_size; + *denominator = get_dev_size(store->snap->cow->bdev); +} + +static void persistent_destroy(struct exception_store *store) +{ + struct pstore *ps = get_info(store); + + dm_io_put(sectors_to_pages(ps->chunk_size)); + vfree(ps->callbacks); + free_area(ps); + kfree(ps); +} + +static int persistent_read_metadata(struct exception_store *store) +{ + int r, new_snapshot; + struct pstore *ps = get_info(store); + + /* + * Read the snapshot header. + */ + r = read_header(ps, &new_snapshot); + if (r) + return r; + + /* + * Do we need to setup a new snapshot ? + */ + if (new_snapshot) { + r = write_header(ps); + if (r) { + DMWARN("write_header failed"); + return r; + } + + r = zero_area(ps, 0); + if (r) { + DMWARN("zero_area(0) failed"); + return r; + } + + } else { + /* + * Sanity checks. + */ + if (!ps->valid) { + DMWARN("snapshot is marked invalid"); + return -EINVAL; + } + + if (ps->version != SNAPSHOT_DISK_VERSION) { + DMWARN("unable to handle snapshot disk version %d", + ps->version); + return -EINVAL; + } + + /* + * Read the metadata. + */ + r = read_exceptions(ps); + if (r) + return r; + } + + return 0; +} + +static int persistent_prepare(struct exception_store *store, + struct exception *e) +{ + struct pstore *ps = get_info(store); + uint32_t stride; + sector_t size = get_dev_size(store->snap->cow->bdev); + + /* Is there enough room ? */ + if (size < ((ps->next_free + 1) * store->snap->chunk_size)) + return -ENOSPC; + + e->new_chunk = ps->next_free; + + /* + * Move onto the next free pending, making sure to take + * into account the location of the metadata chunks. + */ + stride = (ps->exceptions_per_area + 1); + if ((++ps->next_free % stride) == 1) + ps->next_free++; + + atomic_inc(&ps->pending_count); + return 0; +} + +static void persistent_commit(struct exception_store *store, + struct exception *e, + void (*callback) (void *, int success), + void *callback_context) +{ + int r; + unsigned int i; + struct pstore *ps = get_info(store); + struct disk_exception de; + struct commit_callback *cb; + + de.old_chunk = e->old_chunk; + de.new_chunk = e->new_chunk; + write_exception(ps, ps->current_committed++, &de); + + /* + * Add the callback to the back of the array. This code + * is the only place where the callback array is + * manipulated, and we know that it will never be called + * multiple times concurrently. + */ + cb = ps->callbacks + ps->callback_count++; + cb->callback = callback; + cb->context = callback_context; + + /* + * If there are no more exceptions in flight, or we have + * filled this metadata area we commit the exceptions to + * disk. + */ + if (atomic_dec_and_test(&ps->pending_count) || + (ps->current_committed == ps->exceptions_per_area)) { + r = area_io(ps, ps->current_area, WRITE); + if (r) + ps->valid = 0; + + for (i = 0; i < ps->callback_count; i++) { + cb = ps->callbacks + i; + cb->callback(cb->context, r == 0 ? 1 : 0); + } + + ps->callback_count = 0; + } + + /* + * Have we completely filled the current area ? + */ + if (ps->current_committed == ps->exceptions_per_area) { + ps->current_committed = 0; + r = zero_area(ps, ps->current_area + 1); + if (r) + ps->valid = 0; + } +} + +static void persistent_drop(struct exception_store *store) +{ + struct pstore *ps = get_info(store); + + ps->valid = 0; + if (write_header(ps)) + DMWARN("write header failed"); +} + +int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) +{ + int r; + struct pstore *ps; + + r = dm_io_get(sectors_to_pages(chunk_size)); + if (r) + return r; + + /* allocate the pstore */ + ps = kmalloc(sizeof(*ps), GFP_KERNEL); + if (!ps) { + r = -ENOMEM; + goto bad; + } + + ps->snap = store->snap; + ps->valid = 1; + ps->version = SNAPSHOT_DISK_VERSION; + ps->chunk_size = chunk_size; + ps->exceptions_per_area = (chunk_size << SECTOR_SHIFT) / + sizeof(struct disk_exception); + ps->next_free = 2; /* skipping the header and first area */ + ps->current_committed = 0; + + r = alloc_area(ps); + if (r) + goto bad; + + /* + * Allocate space for all the callbacks. + */ + ps->callback_count = 0; + atomic_set(&ps->pending_count, 0); + ps->callbacks = dm_vcalloc(ps->exceptions_per_area, + sizeof(*ps->callbacks)); + + if (!ps->callbacks) { + r = -ENOMEM; + goto bad; + } + + store->destroy = persistent_destroy; + store->read_metadata = persistent_read_metadata; + store->prepare_exception = persistent_prepare; + store->commit_exception = persistent_commit; + store->drop_snapshot = persistent_drop; + store->fraction_full = persistent_fraction_full; + store->context = ps; + + return 0; + + bad: + dm_io_put(sectors_to_pages(chunk_size)); + if (ps) { + if (ps->area) + free_area(ps); + + kfree(ps); + } + return r; +} + +/*----------------------------------------------------------------- + * Implementation of the store for non-persistent snapshots. + *---------------------------------------------------------------*/ +struct transient_c { + sector_t next_free; +}; + +static void transient_destroy(struct exception_store *store) +{ + kfree(store->context); +} + +static int transient_read_metadata(struct exception_store *store) +{ + return 0; +} + +static int transient_prepare(struct exception_store *store, struct exception *e) +{ + struct transient_c *tc = (struct transient_c *) store->context; + sector_t size = get_dev_size(store->snap->cow->bdev); + + if (size < (tc->next_free + store->snap->chunk_size)) + return -1; + + e->new_chunk = sector_to_chunk(store->snap, tc->next_free); + tc->next_free += store->snap->chunk_size; + + return 0; +} + +static void transient_commit(struct exception_store *store, + struct exception *e, + void (*callback) (void *, int success), + void *callback_context) +{ + /* Just succeed */ + callback(callback_context, 1); +} + +static void transient_fraction_full(struct exception_store *store, + sector_t *numerator, sector_t *denominator) +{ + *numerator = ((struct transient_c *) store->context)->next_free; + *denominator = get_dev_size(store->snap->cow->bdev); +} + +int dm_create_transient(struct exception_store *store, + struct dm_snapshot *s, int blocksize) +{ + struct transient_c *tc; + + memset(store, 0, sizeof(*store)); + store->destroy = transient_destroy; + store->read_metadata = transient_read_metadata; + store->prepare_exception = transient_prepare; + store->commit_exception = transient_commit; + store->fraction_full = transient_fraction_full; + store->snap = s; + + tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); + if (!tc) + return -ENOMEM; + + tc->next_free = 0; + store->context = tc; + + return 0; +} diff -Nru a/drivers/md/dm-io.c b/drivers/md/dm-io.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-io.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,647 @@ +/* + * Copyright (C) 2003 Sistina Software + * + * This file is released under the GPL. + */ + +#include "dm-io.h" + +#include +#include +#include +#include +#include + +#define BIO_POOL_SIZE 256 + + +/*----------------------------------------------------------------- + * Bio set, move this to bio.c + *---------------------------------------------------------------*/ +#define BV_NAME_SIZE 16 +struct biovec_pool { + int nr_vecs; + char name[BV_NAME_SIZE]; + kmem_cache_t *slab; + mempool_t *pool; + atomic_t allocated; /* FIXME: debug */ +}; + +#define BIOVEC_NR_POOLS 6 +struct bio_set { + char name[BV_NAME_SIZE]; + kmem_cache_t *bio_slab; + mempool_t *bio_pool; + struct biovec_pool pools[BIOVEC_NR_POOLS]; +}; + +static void bio_set_exit(struct bio_set *bs) +{ + unsigned i; + struct biovec_pool *bp; + + if (bs->bio_pool) + mempool_destroy(bs->bio_pool); + + if (bs->bio_slab) + kmem_cache_destroy(bs->bio_slab); + + for (i = 0; i < BIOVEC_NR_POOLS; i++) { + bp = bs->pools + i; + if (bp->pool) + mempool_destroy(bp->pool); + + if (bp->slab) + kmem_cache_destroy(bp->slab); + } +} + +static void mk_name(char *str, size_t len, const char *prefix, unsigned count) +{ + snprintf(str, len, "%s-%u", prefix, count); +} + +static int bio_set_init(struct bio_set *bs, const char *slab_prefix, + unsigned pool_entries, unsigned scale) +{ + /* FIXME: this must match bvec_index(), why not go the + * whole hog and have a pool per power of 2 ? */ + static unsigned _vec_lengths[BIOVEC_NR_POOLS] = { + 1, 4, 16, 64, 128, BIO_MAX_PAGES + }; + + + unsigned i, size; + struct biovec_pool *bp; + + /* zero the bs so we can tear down properly on error */ + memset(bs, 0, sizeof(*bs)); + + /* + * Set up the bio pool. + */ + snprintf(bs->name, sizeof(bs->name), "%s-bio", slab_prefix); + + bs->bio_slab = kmem_cache_create(bs->name, sizeof(struct bio), 0, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!bs->bio_slab) { + DMWARN("can't init bio slab"); + goto bad; + } + + bs->bio_pool = mempool_create(pool_entries, mempool_alloc_slab, + mempool_free_slab, bs->bio_slab); + if (!bs->bio_pool) { + DMWARN("can't init bio pool"); + goto bad; + } + + /* + * Set up the biovec pools. + */ + for (i = 0; i < BIOVEC_NR_POOLS; i++) { + bp = bs->pools + i; + bp->nr_vecs = _vec_lengths[i]; + atomic_set(&bp->allocated, 1); /* FIXME: debug */ + + + size = bp->nr_vecs * sizeof(struct bio_vec); + + mk_name(bp->name, sizeof(bp->name), slab_prefix, i); + bp->slab = kmem_cache_create(bp->name, size, 0, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!bp->slab) { + DMWARN("can't init biovec slab cache"); + goto bad; + } + + if (i >= scale) + pool_entries >>= 1; + + bp->pool = mempool_create(pool_entries, mempool_alloc_slab, + mempool_free_slab, bp->slab); + if (!bp->pool) { + DMWARN("can't init biovec mempool"); + goto bad; + } + } + + return 0; + + bad: + bio_set_exit(bs); + return -ENOMEM; +} + +/* FIXME: blech */ +static inline unsigned bvec_index(unsigned nr) +{ + switch (nr) { + case 1: return 0; + case 2 ... 4: return 1; + case 5 ... 16: return 2; + case 17 ... 64: return 3; + case 65 ... 128:return 4; + case 129 ... BIO_MAX_PAGES: return 5; + } + + BUG(); + return 0; +} + +static inline void bs_bio_init(struct bio *bio) +{ + bio->bi_next = NULL; + bio->bi_flags = 1 << BIO_UPTODATE; + bio->bi_rw = 0; + bio->bi_vcnt = 0; + bio->bi_idx = 0; + bio->bi_phys_segments = 0; + bio->bi_hw_segments = 0; + bio->bi_size = 0; + bio->bi_max_vecs = 0; + bio->bi_end_io = NULL; + atomic_set(&bio->bi_cnt, 1); + bio->bi_private = NULL; +} + +static unsigned _bio_count = 0; +struct bio *bio_set_alloc(struct bio_set *bs, int gfp_mask, int nr_iovecs) +{ + struct biovec_pool *bp; + struct bio_vec *bv = NULL; + unsigned long idx; + struct bio *bio; + + bio = mempool_alloc(bs->bio_pool, gfp_mask); + if (unlikely(!bio)) + return NULL; + + bio_init(bio); + + if (likely(nr_iovecs)) { + idx = bvec_index(nr_iovecs); + bp = bs->pools + idx; + bv = mempool_alloc(bp->pool, gfp_mask); + if (!bv) { + mempool_free(bio, bs->bio_pool); + return NULL; + } + + memset(bv, 0, bp->nr_vecs * sizeof(*bv)); + bio->bi_flags |= idx << BIO_POOL_OFFSET; + bio->bi_max_vecs = bp->nr_vecs; + atomic_inc(&bp->allocated); + } + + bio->bi_io_vec = bv; + return bio; +} + +static void bio_set_free(struct bio_set *bs, struct bio *bio) +{ + struct biovec_pool *bp = bs->pools + BIO_POOL_IDX(bio); + + if (atomic_dec_and_test(&bp->allocated)) + BUG(); + + mempool_free(bio->bi_io_vec, bp->pool); + mempool_free(bio, bs->bio_pool); +} + +/*----------------------------------------------------------------- + * dm-io proper + *---------------------------------------------------------------*/ +static struct bio_set _bios; + +/* FIXME: can we shrink this ? */ +struct io { + unsigned long error; + atomic_t count; + struct task_struct *sleeper; + io_notify_fn callback; + void *context; +}; + +/* + * io contexts are only dynamically allocated for asynchronous + * io. Since async io is likely to be the majority of io we'll + * have the same number of io contexts as buffer heads ! (FIXME: + * must reduce this). + */ +static unsigned _num_ios; +static mempool_t *_io_pool; + +static void *alloc_io(int gfp_mask, void *pool_data) +{ + return kmalloc(sizeof(struct io), gfp_mask); +} + +static void free_io(void *element, void *pool_data) +{ + kfree(element); +} + +static unsigned int pages_to_ios(unsigned int pages) +{ + return 4 * pages; /* too many ? */ +} + +static int resize_pool(unsigned int new_ios) +{ + int r = 0; + + if (_io_pool) { + if (new_ios == 0) { + /* free off the pool */ + mempool_destroy(_io_pool); + _io_pool = NULL; + bio_set_exit(&_bios); + + } else { + /* resize the pool */ + r = mempool_resize(_io_pool, new_ios, GFP_KERNEL); + } + + } else { + /* create new pool */ + _io_pool = mempool_create(new_ios, alloc_io, free_io, NULL); + if (!_io_pool) + r = -ENOMEM; + + r = bio_set_init(&_bios, "dm-io", 512, 1); + if (r) { + mempool_destroy(_io_pool); + _io_pool = NULL; + } + } + + if (!r) + _num_ios = new_ios; + + return r; +} + +int dm_io_get(unsigned int num_pages) +{ + return resize_pool(_num_ios + pages_to_ios(num_pages)); +} + +void dm_io_put(unsigned int num_pages) +{ + resize_pool(_num_ios - pages_to_ios(num_pages)); +} + +/*----------------------------------------------------------------- + * We need to keep track of which region a bio is doing io for. + * In order to save a memory allocation we store this the last + * bvec which we know is unused (blech). + *---------------------------------------------------------------*/ +static inline void bio_set_region(struct bio *bio, unsigned region) +{ + bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len = region; +} + +static inline unsigned bio_get_region(struct bio *bio) +{ + return bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len; +} + +/*----------------------------------------------------------------- + * We need an io object to keep track of the number of bios that + * have been dispatched for a particular io. + *---------------------------------------------------------------*/ +static void dec_count(struct io *io, unsigned int region, int error) +{ + if (error) + set_bit(region, &io->error); + + if (atomic_dec_and_test(&io->count)) { + if (io->sleeper) + wake_up_process(io->sleeper); + + else { + int r = io->error; + io_notify_fn fn = io->callback; + void *context = io->context; + + mempool_free(io, _io_pool); + fn(r, context); + } + } +} + +/* FIXME Move this to bio.h? */ +static void zero_fill_bio(struct bio *bio) +{ + unsigned long flags; + struct bio_vec *bv; + int i; + + bio_for_each_segment(bv, bio, i) { + char *data = bvec_kmap_irq(bv, &flags); + memset(data, 0, bv->bv_len); + flush_dcache_page(bv->bv_page); + bvec_kunmap_irq(data, &flags); + } +} + +static int endio(struct bio *bio, unsigned int done, int error) +{ + struct io *io = (struct io *) bio->bi_private; + + /* keep going until we've finished */ + if (bio->bi_size) + return 1; + + if (error && bio_data_dir(bio) == READ) + zero_fill_bio(bio); + + dec_count(io, bio_get_region(bio), error); + bio_put(bio); + + return 0; +} + +static void bio_dtr(struct bio *bio) +{ + _bio_count--; + bio_set_free(&_bios, bio); +} + +/*----------------------------------------------------------------- + * These little objects provide an abstraction for getting a new + * destination page for io. + *---------------------------------------------------------------*/ +struct dpages { + void (*get_page)(struct dpages *dp, + struct page **p, unsigned long *len, unsigned *offset); + void (*next_page)(struct dpages *dp); + + unsigned context_u; + void *context_ptr; +}; + +/* + * Functions for getting the pages from a list. + */ +static void list_get_page(struct dpages *dp, + struct page **p, unsigned long *len, unsigned *offset) +{ + unsigned o = dp->context_u; + struct page_list *pl = (struct page_list *) dp->context_ptr; + + *p = pl->page; + *len = PAGE_SIZE - o; + *offset = o; +} + +static void list_next_page(struct dpages *dp) +{ + struct page_list *pl = (struct page_list *) dp->context_ptr; + dp->context_ptr = pl->next; + dp->context_u = 0; +} + +static void list_dp_init(struct dpages *dp, struct page_list *pl, unsigned offset) +{ + dp->get_page = list_get_page; + dp->next_page = list_next_page; + dp->context_u = offset; + dp->context_ptr = pl; +} + +/* + * Functions for getting the pages from a bvec. + */ +static void bvec_get_page(struct dpages *dp, + struct page **p, unsigned long *len, unsigned *offset) +{ + struct bio_vec *bvec = (struct bio_vec *) dp->context_ptr; + *p = bvec->bv_page; + *len = bvec->bv_len; + *offset = bvec->bv_offset; +} + +static void bvec_next_page(struct dpages *dp) +{ + struct bio_vec *bvec = (struct bio_vec *) dp->context_ptr; + dp->context_ptr = bvec + 1; +} + +static void bvec_dp_init(struct dpages *dp, struct bio_vec *bvec) +{ + dp->get_page = bvec_get_page; + dp->next_page = bvec_next_page; + dp->context_ptr = bvec; +} + +static void vm_get_page(struct dpages *dp, + struct page **p, unsigned long *len, unsigned *offset) +{ + *p = vmalloc_to_page(dp->context_ptr); + *offset = dp->context_u; + *len = PAGE_SIZE - dp->context_u; +} + +static void vm_next_page(struct dpages *dp) +{ + dp->context_ptr += PAGE_SIZE - dp->context_u; + dp->context_u = 0; +} + +static void vm_dp_init(struct dpages *dp, void *data) +{ + dp->get_page = vm_get_page; + dp->next_page = vm_next_page; + dp->context_u = ((unsigned long) data) & (PAGE_SIZE - 1); + dp->context_ptr = data; +} + +/*----------------------------------------------------------------- + * IO routines that accept a list of pages. + *---------------------------------------------------------------*/ +static void do_region(int rw, unsigned int region, struct io_region *where, + struct dpages *dp, struct io *io) +{ + struct bio *bio; + struct page *page; + unsigned long len; + unsigned offset; + unsigned num_bvecs; + sector_t remaining = where->count; + + while (remaining) { + /* + * Allocate a suitably sized bio, we add an extra + * bvec for bio_get/set_region(). + */ + num_bvecs = (remaining / (PAGE_SIZE >> 9)) + 2; + _bio_count++; + bio = bio_set_alloc(&_bios, GFP_NOIO, num_bvecs); + bio->bi_sector = where->sector + (where->count - remaining); + bio->bi_bdev = where->bdev; + bio->bi_end_io = endio; + bio->bi_private = io; + bio->bi_destructor = bio_dtr; + bio_set_region(bio, region); + + /* + * Try and add as many pages as possible. + */ + while (remaining) { + dp->get_page(dp, &page, &len, &offset); + len = min(len, to_bytes(remaining)); + if (!bio_add_page(bio, page, len, offset)) + break; + + offset = 0; + remaining -= to_sector(len); + dp->next_page(dp); + } + + atomic_inc(&io->count); + submit_bio(rw, bio); + } +} + +static void dispatch_io(int rw, unsigned int num_regions, + struct io_region *where, struct dpages *dp, + struct io *io, int sync) +{ + int i; + struct dpages old_pages = *dp; + + if (sync) + rw |= (1 << BIO_RW_SYNC); + + /* + * For multiple regions we need to be careful to rewind + * the dp object for each call to do_region. + */ + for (i = 0; i < num_regions; i++) { + *dp = old_pages; + if (where[i].count) + do_region(rw, i, where + i, dp, io); + } + + /* + * Drop the extra refence that we were holding to avoid + * the io being completed too early. + */ + dec_count(io, 0, 0); +} + +static int sync_io(unsigned int num_regions, struct io_region *where, + int rw, struct dpages *dp, unsigned long *error_bits) +{ + struct io io; + + if (num_regions > 1 && rw != WRITE) { + WARN_ON(1); + return -EIO; + } + + io.error = 0; + atomic_set(&io.count, 1); /* see dispatch_io() */ + io.sleeper = current; + + dispatch_io(rw, num_regions, where, dp, &io, 1); + + while (1) { + set_current_state(TASK_UNINTERRUPTIBLE); + + if (!atomic_read(&io.count) || signal_pending(current)) + break; + + io_schedule(); + } + set_current_state(TASK_RUNNING); + + if (atomic_read(&io.count)) + return -EINTR; + + *error_bits = io.error; + return io.error ? -EIO : 0; +} + +static int async_io(unsigned int num_regions, struct io_region *where, int rw, + struct dpages *dp, io_notify_fn fn, void *context) +{ + struct io *io; + + if (num_regions > 1 && rw != WRITE) { + WARN_ON(1); + fn(1, context); + return -EIO; + } + + io = mempool_alloc(_io_pool, GFP_NOIO); + io->error = 0; + atomic_set(&io->count, 1); /* see dispatch_io() */ + io->sleeper = NULL; + io->callback = fn; + io->context = context; + + dispatch_io(rw, num_regions, where, dp, io, 0); + return 0; +} + +int dm_io_sync(unsigned int num_regions, struct io_region *where, int rw, + struct page_list *pl, unsigned int offset, + unsigned long *error_bits) +{ + struct dpages dp; + list_dp_init(&dp, pl, offset); + return sync_io(num_regions, where, rw, &dp, error_bits); +} + +int dm_io_sync_bvec(unsigned int num_regions, struct io_region *where, int rw, + struct bio_vec *bvec, unsigned long *error_bits) +{ + struct dpages dp; + bvec_dp_init(&dp, bvec); + return sync_io(num_regions, where, rw, &dp, error_bits); +} + +int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw, + void *data, unsigned long *error_bits) +{ + struct dpages dp; + vm_dp_init(&dp, data); + return sync_io(num_regions, where, rw, &dp, error_bits); +} + +int dm_io_async(unsigned int num_regions, struct io_region *where, int rw, + struct page_list *pl, unsigned int offset, + io_notify_fn fn, void *context) +{ + struct dpages dp; + list_dp_init(&dp, pl, offset); + return async_io(num_regions, where, rw, &dp, fn, context); +} + +int dm_io_async_bvec(unsigned int num_regions, struct io_region *where, int rw, + struct bio_vec *bvec, io_notify_fn fn, void *context) +{ + struct dpages dp; + bvec_dp_init(&dp, bvec); + return async_io(num_regions, where, rw, &dp, fn, context); +} + +int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw, + void *data, io_notify_fn fn, void *context) +{ + struct dpages dp; + vm_dp_init(&dp, data); + return async_io(num_regions, where, rw, &dp, fn, context); +} + +EXPORT_SYMBOL(dm_io_get); +EXPORT_SYMBOL(dm_io_put); +EXPORT_SYMBOL(dm_io_sync); +EXPORT_SYMBOL(dm_io_async); +EXPORT_SYMBOL(dm_io_sync_bvec); +EXPORT_SYMBOL(dm_io_async_bvec); +EXPORT_SYMBOL(dm_io_sync_vm); +EXPORT_SYMBOL(dm_io_async_vm); diff -Nru a/drivers/md/dm-io.h b/drivers/md/dm-io.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-io.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2003 Sistina Software + * + * This file is released under the GPL. + */ + +#ifndef _DM_IO_H +#define _DM_IO_H + +#include "dm.h" + +/* FIXME make this configurable */ +#define DM_MAX_IO_REGIONS 8 + +struct io_region { + struct block_device *bdev; + sector_t sector; + sector_t count; +}; + +struct page_list { + struct page_list *next; + struct page *page; +}; + + +/* + * 'error' is a bitset, with each bit indicating whether an error + * occurred doing io to the corresponding region. + */ +typedef void (*io_notify_fn)(unsigned long error, void *context); + + +/* + * Before anyone uses the IO interface they should call + * dm_io_get(), specifying roughly how many pages they are + * expecting to perform io on concurrently. + * + * This function may block. + */ +int dm_io_get(unsigned int num_pages); +void dm_io_put(unsigned int num_pages); + +/* + * Synchronous IO. + * + * Please ensure that the rw flag in the next two functions is + * either READ or WRITE, ie. we don't take READA. Any + * regions with a zero count field will be ignored. + */ +int dm_io_sync(unsigned int num_regions, struct io_region *where, int rw, + struct page_list *pl, unsigned int offset, + unsigned long *error_bits); + +int dm_io_sync_bvec(unsigned int num_regions, struct io_region *where, int rw, + struct bio_vec *bvec, unsigned long *error_bits); + +int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw, + void *data, unsigned long *error_bits); + +/* + * Aynchronous IO. + * + * The 'where' array may be safely allocated on the stack since + * the function takes a copy. + */ +int dm_io_async(unsigned int num_regions, struct io_region *where, int rw, + struct page_list *pl, unsigned int offset, + io_notify_fn fn, void *context); + +int dm_io_async_bvec(unsigned int num_regions, struct io_region *where, int rw, + struct bio_vec *bvec, io_notify_fn fn, void *context); + +int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw, + void *data, io_notify_fn fn, void *context); + +#endif diff -Nru a/drivers/md/dm-log.c b/drivers/md/dm-log.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-log.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,629 @@ +/* + * Copyright (C) 2003 Sistina Software + * + * This file is released under the LGPL. + */ + +#include +#include +#include +#include + +#include "dm-log.h" +#include "dm-io.h" + +static LIST_HEAD(_log_types); +static spinlock_t _lock = SPIN_LOCK_UNLOCKED; + +int dm_register_dirty_log_type(struct dirty_log_type *type) +{ + if (!try_module_get(type->module)) + return -EINVAL; + + spin_lock(&_lock); + type->use_count = 0; + list_add(&type->list, &_log_types); + spin_unlock(&_lock); + + return 0; +} + +int dm_unregister_dirty_log_type(struct dirty_log_type *type) +{ + spin_lock(&_lock); + + if (type->use_count) + DMWARN("Attempt to unregister a log type that is still in use"); + else { + list_del(&type->list); + module_put(type->module); + } + + spin_unlock(&_lock); + + return 0; +} + +static struct dirty_log_type *get_type(const char *type_name) +{ + struct dirty_log_type *type; + + spin_lock(&_lock); + list_for_each_entry (type, &_log_types, list) + if (!strcmp(type_name, type->name)) { + type->use_count++; + spin_unlock(&_lock); + return type; + } + + spin_unlock(&_lock); + return NULL; +} + +static void put_type(struct dirty_log_type *type) +{ + spin_lock(&_lock); + type->use_count--; + spin_unlock(&_lock); +} + +struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti, + unsigned int argc, char **argv) +{ + struct dirty_log_type *type; + struct dirty_log *log; + + log = kmalloc(sizeof(*log), GFP_KERNEL); + if (!log) + return NULL; + + type = get_type(type_name); + if (!type) { + kfree(log); + return NULL; + } + + log->type = type; + if (type->ctr(log, ti, argc, argv)) { + kfree(log); + put_type(type); + return NULL; + } + + return log; +} + +void dm_destroy_dirty_log(struct dirty_log *log) +{ + log->type->dtr(log); + put_type(log->type); + kfree(log); +} + +/*----------------------------------------------------------------- + * Persistent and core logs share a lot of their implementation. + * FIXME: need a reload method to be called from a resume + *---------------------------------------------------------------*/ +/* + * Magic for persistent mirrors: "MiRr" + */ +#define MIRROR_MAGIC 0x4D695272 + +/* + * The on-disk version of the metadata. + */ +#define MIRROR_DISK_VERSION 1 +#define LOG_OFFSET 2 + +struct log_header { + uint32_t magic; + + /* + * Simple, incrementing version. no backward + * compatibility. + */ + uint32_t version; + sector_t nr_regions; +}; + +struct log_c { + struct dm_target *ti; + int touched; + sector_t region_size; + unsigned int region_count; + region_t sync_count; + + unsigned bitset_uint32_count; + uint32_t *clean_bits; + uint32_t *sync_bits; + uint32_t *recovering_bits; /* FIXME: this seems excessive */ + + int sync_search; + + /* + * Disk log fields + */ + struct dm_dev *log_dev; + struct log_header header; + + struct io_region header_location; + struct log_header *disk_header; + + struct io_region bits_location; + uint32_t *disk_bits; +}; + +/* + * The touched member needs to be updated every time we access + * one of the bitsets. + */ +static inline int log_test_bit(uint32_t *bs, unsigned bit) +{ + return test_bit(bit, (unsigned long *) bs) ? 1 : 0; +} + +static inline void log_set_bit(struct log_c *l, + uint32_t *bs, unsigned bit) +{ + set_bit(bit, (unsigned long *) bs); + l->touched = 1; +} + +static inline void log_clear_bit(struct log_c *l, + uint32_t *bs, unsigned bit) +{ + clear_bit(bit, (unsigned long *) bs); + l->touched = 1; +} + +/*---------------------------------------------------------------- + * Header IO + *--------------------------------------------------------------*/ +static void header_to_disk(struct log_header *core, struct log_header *disk) +{ + disk->magic = cpu_to_le32(core->magic); + disk->version = cpu_to_le32(core->version); + disk->nr_regions = cpu_to_le64(core->nr_regions); +} + +static void header_from_disk(struct log_header *core, struct log_header *disk) +{ + core->magic = le32_to_cpu(disk->magic); + core->version = le32_to_cpu(disk->version); + core->nr_regions = le64_to_cpu(disk->nr_regions); +} + +static int read_header(struct log_c *log) +{ + int r; + unsigned long ebits; + + r = dm_io_sync_vm(1, &log->header_location, READ, + log->disk_header, &ebits); + if (r) + return r; + + header_from_disk(&log->header, log->disk_header); + + if (log->header.magic != MIRROR_MAGIC) { + log->header.magic = MIRROR_MAGIC; + log->header.version = MIRROR_DISK_VERSION; + log->header.nr_regions = 0; + } + + if (log->header.version != MIRROR_DISK_VERSION) { + DMWARN("incompatible disk log version"); + return -EINVAL; + } + + return 0; +} + +static inline int write_header(struct log_c *log) +{ + unsigned long ebits; + + header_to_disk(&log->header, log->disk_header); + return dm_io_sync_vm(1, &log->header_location, WRITE, + log->disk_header, &ebits); +} + +/*---------------------------------------------------------------- + * Bits IO + *--------------------------------------------------------------*/ +static inline void bits_to_core(uint32_t *core, uint32_t *disk, unsigned count) +{ + unsigned i; + + for (i = 0; i < count; i++) + core[i] = le32_to_cpu(disk[i]); +} + +static inline void bits_to_disk(uint32_t *core, uint32_t *disk, unsigned count) +{ + unsigned i; + + /* copy across the clean/dirty bitset */ + for (i = 0; i < count; i++) + disk[i] = cpu_to_le32(core[i]); +} + +static int read_bits(struct log_c *log) +{ + int r; + unsigned long ebits; + + r = dm_io_sync_vm(1, &log->bits_location, READ, + log->disk_bits, &ebits); + if (r) + return r; + + bits_to_core(log->clean_bits, log->disk_bits, + log->bitset_uint32_count); + return 0; +} + +static int write_bits(struct log_c *log) +{ + unsigned long ebits; + bits_to_disk(log->clean_bits, log->disk_bits, + log->bitset_uint32_count); + return dm_io_sync_vm(1, &log->bits_location, WRITE, + log->disk_bits, &ebits); +} + +/*---------------------------------------------------------------- + * constructor/destructor + *--------------------------------------------------------------*/ +#define BYTE_SHIFT 3 +static int core_ctr(struct dirty_log *log, struct dm_target *ti, + unsigned int argc, char **argv) +{ + struct log_c *lc; + sector_t region_size; + unsigned int region_count; + size_t bitset_size; + + if (argc != 1) { + DMWARN("wrong number of arguments to log_c"); + return -EINVAL; + } + + if (sscanf(argv[0], SECTOR_FORMAT, ®ion_size) != 1) { + DMWARN("invalid region size string"); + return -EINVAL; + } + + region_count = dm_div_up(ti->len, region_size); + + lc = kmalloc(sizeof(*lc), GFP_KERNEL); + if (!lc) { + DMWARN("couldn't allocate core log"); + return -ENOMEM; + } + + lc->ti = ti; + lc->touched = 0; + lc->region_size = region_size; + lc->region_count = region_count; + + /* + * Work out how many words we need to hold the bitset. + */ + bitset_size = dm_round_up(region_count, + sizeof(*lc->clean_bits) << BYTE_SHIFT); + bitset_size >>= BYTE_SHIFT; + + lc->bitset_uint32_count = bitset_size / 4; + lc->clean_bits = vmalloc(bitset_size); + if (!lc->clean_bits) { + DMWARN("couldn't allocate clean bitset"); + kfree(lc); + return -ENOMEM; + } + memset(lc->clean_bits, -1, bitset_size); + + lc->sync_bits = vmalloc(bitset_size); + if (!lc->sync_bits) { + DMWARN("couldn't allocate sync bitset"); + vfree(lc->clean_bits); + kfree(lc); + return -ENOMEM; + } + memset(lc->sync_bits, 0, bitset_size); + lc->sync_count = 0; + + lc->recovering_bits = vmalloc(bitset_size); + if (!lc->recovering_bits) { + DMWARN("couldn't allocate sync bitset"); + vfree(lc->sync_bits); + vfree(lc->clean_bits); + kfree(lc); + return -ENOMEM; + } + memset(lc->recovering_bits, 0, bitset_size); + lc->sync_search = 0; + log->context = lc; + return 0; +} + +static void core_dtr(struct dirty_log *log) +{ + struct log_c *lc = (struct log_c *) log->context; + vfree(lc->clean_bits); + vfree(lc->sync_bits); + vfree(lc->recovering_bits); + kfree(lc); +} + +static int disk_ctr(struct dirty_log *log, struct dm_target *ti, + unsigned int argc, char **argv) +{ + int r; + size_t size; + struct log_c *lc; + struct dm_dev *dev; + + if (argc != 2) { + DMWARN("wrong number of arguments to log_d"); + return -EINVAL; + } + + r = dm_get_device(ti, argv[0], 0, 0 /* FIXME */, + FMODE_READ | FMODE_WRITE, &dev); + if (r) + return r; + + r = core_ctr(log, ti, argc - 1, argv + 1); + if (r) { + dm_put_device(ti, dev); + return r; + } + + lc = (struct log_c *) log->context; + lc->log_dev = dev; + + /* setup the disk header fields */ + lc->header_location.bdev = lc->log_dev->bdev; + lc->header_location.sector = 0; + lc->header_location.count = 1; + + /* + * We can't read less than this amount, even though we'll + * not be using most of this space. + */ + lc->disk_header = vmalloc(1 << SECTOR_SHIFT); + if (!lc->disk_header) + goto bad; + + /* setup the disk bitset fields */ + lc->bits_location.bdev = lc->log_dev->bdev; + lc->bits_location.sector = LOG_OFFSET; + + size = dm_round_up(lc->bitset_uint32_count * sizeof(uint32_t), + 1 << SECTOR_SHIFT); + lc->bits_location.count = size >> SECTOR_SHIFT; + lc->disk_bits = vmalloc(size); + if (!lc->disk_bits) { + vfree(lc->disk_header); + goto bad; + } + return 0; + + bad: + dm_put_device(ti, lc->log_dev); + core_dtr(log); + return -ENOMEM; +} + +static void disk_dtr(struct dirty_log *log) +{ + struct log_c *lc = (struct log_c *) log->context; + dm_put_device(lc->ti, lc->log_dev); + vfree(lc->disk_header); + vfree(lc->disk_bits); + core_dtr(log); +} + +static int count_bits32(uint32_t *addr, unsigned size) +{ + int count = 0, i; + + for (i = 0; i < size; i++) { + count += hweight32(*(addr+i)); + } + return count; +} + +static int disk_resume(struct dirty_log *log) +{ + int r; + unsigned i; + struct log_c *lc = (struct log_c *) log->context; + size_t size = lc->bitset_uint32_count * sizeof(uint32_t); + + /* read the disk header */ + r = read_header(lc); + if (r) + return r; + + /* read the bits */ + r = read_bits(lc); + if (r) + return r; + + /* zero any new bits if the mirror has grown */ + for (i = lc->header.nr_regions; i < lc->region_count; i++) + /* FIXME: amazingly inefficient */ + log_clear_bit(lc, lc->clean_bits, i); + + /* copy clean across to sync */ + memcpy(lc->sync_bits, lc->clean_bits, size); + lc->sync_count = count_bits32(lc->clean_bits, lc->bitset_uint32_count); + + /* write the bits */ + r = write_bits(lc); + if (r) + return r; + + /* set the correct number of regions in the header */ + lc->header.nr_regions = lc->region_count; + + /* write the new header */ + return write_header(lc); +} + +static sector_t core_get_region_size(struct dirty_log *log) +{ + struct log_c *lc = (struct log_c *) log->context; + return lc->region_size; +} + +static int core_is_clean(struct dirty_log *log, region_t region) +{ + struct log_c *lc = (struct log_c *) log->context; + return log_test_bit(lc->clean_bits, region); +} + +static int core_in_sync(struct dirty_log *log, region_t region, int block) +{ + struct log_c *lc = (struct log_c *) log->context; + return log_test_bit(lc->sync_bits, region); +} + +static int core_flush(struct dirty_log *log) +{ + /* no op */ + return 0; +} + +static int disk_flush(struct dirty_log *log) +{ + int r; + struct log_c *lc = (struct log_c *) log->context; + + /* only write if the log has changed */ + if (!lc->touched) + return 0; + + r = write_bits(lc); + if (!r) + lc->touched = 0; + + return r; +} + +static void core_mark_region(struct dirty_log *log, region_t region) +{ + struct log_c *lc = (struct log_c *) log->context; + log_clear_bit(lc, lc->clean_bits, region); +} + +static void core_clear_region(struct dirty_log *log, region_t region) +{ + struct log_c *lc = (struct log_c *) log->context; + log_set_bit(lc, lc->clean_bits, region); +} + +static int core_get_resync_work(struct dirty_log *log, region_t *region) +{ + struct log_c *lc = (struct log_c *) log->context; + + if (lc->sync_search >= lc->region_count) + return 0; + + do { + *region = find_next_zero_bit((unsigned long *) lc->sync_bits, + lc->region_count, + lc->sync_search); + lc->sync_search = *region + 1; + + if (*region == lc->region_count) + return 0; + + } while (log_test_bit(lc->recovering_bits, *region)); + + log_set_bit(lc, lc->recovering_bits, *region); + return 1; +} + +static void core_complete_resync_work(struct dirty_log *log, region_t region, + int success) +{ + struct log_c *lc = (struct log_c *) log->context; + + log_clear_bit(lc, lc->recovering_bits, region); + if (success) { + log_set_bit(lc, lc->sync_bits, region); + lc->sync_count++; + } +} + +static region_t core_get_sync_count(struct dirty_log *log) +{ + struct log_c *lc = (struct log_c *) log->context; + + return lc->sync_count; +} + +static struct dirty_log_type _core_type = { + .name = "core", + .module = THIS_MODULE, + .ctr = core_ctr, + .dtr = core_dtr, + .get_region_size = core_get_region_size, + .is_clean = core_is_clean, + .in_sync = core_in_sync, + .flush = core_flush, + .mark_region = core_mark_region, + .clear_region = core_clear_region, + .get_resync_work = core_get_resync_work, + .complete_resync_work = core_complete_resync_work, + .get_sync_count = core_get_sync_count +}; + +static struct dirty_log_type _disk_type = { + .name = "disk", + .module = THIS_MODULE, + .ctr = disk_ctr, + .dtr = disk_dtr, + .suspend = disk_flush, + .resume = disk_resume, + .get_region_size = core_get_region_size, + .is_clean = core_is_clean, + .in_sync = core_in_sync, + .flush = disk_flush, + .mark_region = core_mark_region, + .clear_region = core_clear_region, + .get_resync_work = core_get_resync_work, + .complete_resync_work = core_complete_resync_work, + .get_sync_count = core_get_sync_count +}; + +int __init dm_dirty_log_init(void) +{ + int r; + + r = dm_register_dirty_log_type(&_core_type); + if (r) + DMWARN("couldn't register core log"); + + r = dm_register_dirty_log_type(&_disk_type); + if (r) { + DMWARN("couldn't register disk type"); + dm_unregister_dirty_log_type(&_core_type); + } + + return r; +} + +void dm_dirty_log_exit(void) +{ + dm_unregister_dirty_log_type(&_disk_type); + dm_unregister_dirty_log_type(&_core_type); +} + +EXPORT_SYMBOL(dm_register_dirty_log_type); +EXPORT_SYMBOL(dm_unregister_dirty_log_type); +EXPORT_SYMBOL(dm_create_dirty_log); +EXPORT_SYMBOL(dm_destroy_dirty_log); diff -Nru a/drivers/md/dm-log.h b/drivers/md/dm-log.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-log.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2003 Sistina Software + * + * This file is released under the LGPL. + */ + +#ifndef DM_DIRTY_LOG +#define DM_DIRTY_LOG + +#include "dm.h" + +typedef sector_t region_t; + +struct dirty_log_type; + +struct dirty_log { + struct dirty_log_type *type; + void *context; +}; + +struct dirty_log_type { + struct list_head list; + const char *name; + struct module *module; + unsigned int use_count; + + int (*ctr)(struct dirty_log *log, struct dm_target *ti, + unsigned int argc, char **argv); + void (*dtr)(struct dirty_log *log); + + /* + * There are times when we don't want the log to touch + * the disk. + */ + int (*suspend)(struct dirty_log *log); + int (*resume)(struct dirty_log *log); + + /* + * Retrieves the smallest size of region that the log can + * deal with. + */ + sector_t (*get_region_size)(struct dirty_log *log); + + /* + * A predicate to say whether a region is clean or not. + * May block. + */ + int (*is_clean)(struct dirty_log *log, region_t region); + + /* + * Returns: 0, 1, -EWOULDBLOCK, < 0 + * + * A predicate function to check the area given by + * [sector, sector + len) is in sync. + * + * If -EWOULDBLOCK is returned the state of the region is + * unknown, typically this will result in a read being + * passed to a daemon to deal with, since a daemon is + * allowed to block. + */ + int (*in_sync)(struct dirty_log *log, region_t region, int can_block); + + /* + * Flush the current log state (eg, to disk). This + * function may block. + */ + int (*flush)(struct dirty_log *log); + + /* + * Mark an area as clean or dirty. These functions may + * block, though for performance reasons blocking should + * be extremely rare (eg, allocating another chunk of + * memory for some reason). + */ + void (*mark_region)(struct dirty_log *log, region_t region); + void (*clear_region)(struct dirty_log *log, region_t region); + + /* + * Returns: <0 (error), 0 (no region), 1 (region) + * + * The mirrord will need perform recovery on regions of + * the mirror that are in the NOSYNC state. This + * function asks the log to tell the caller about the + * next region that this machine should recover. + * + * Do not confuse this function with 'in_sync()', one + * tells you if an area is synchronised, the other + * assigns recovery work. + */ + int (*get_resync_work)(struct dirty_log *log, region_t *region); + + /* + * This notifies the log that the resync of an area has + * been completed. The log should then mark this region + * as CLEAN. + */ + void (*complete_resync_work)(struct dirty_log *log, + region_t region, int success); + + /* + * Returns the number of regions that are in sync. + */ + region_t (*get_sync_count)(struct dirty_log *log); +}; + +int dm_register_dirty_log_type(struct dirty_log_type *type); +int dm_unregister_dirty_log_type(struct dirty_log_type *type); + + +/* + * Make sure you use these two functions, rather than calling + * type->constructor/destructor() directly. + */ +struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti, + unsigned int argc, char **argv); +void dm_destroy_dirty_log(struct dirty_log *log); + +/* + * init/exit functions. + */ +int dm_dirty_log_init(void); +void dm_dirty_log_exit(void); + +#endif diff -Nru a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-raid1.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1278 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. + * + * This file is released under the GPL. + */ + +#include "dm.h" +#include "dm-bio-list.h" +#include "dm-io.h" +#include "dm-log.h" +#include "kcopyd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct workqueue_struct *_kmirrord_wq; +static struct work_struct _kmirrord_work; + +static inline void wake(void) +{ + queue_work(_kmirrord_wq, &_kmirrord_work); +} + +/*----------------------------------------------------------------- + * Region hash + * + * The mirror splits itself up into discrete regions. Each + * region can be in one of three states: clean, dirty, + * nosync. There is no need to put clean regions in the hash. + * + * In addition to being present in the hash table a region _may_ + * be present on one of three lists. + * + * clean_regions: Regions on this list have no io pending to + * them, they are in sync, we are no longer interested in them, + * they are dull. rh_update_states() will remove them from the + * hash table. + * + * quiesced_regions: These regions have been spun down, ready + * for recovery. rh_recovery_start() will remove regions from + * this list and hand them to kmirrord, which will schedule the + * recovery io with kcopyd. + * + * recovered_regions: Regions that kcopyd has successfully + * recovered. rh_update_states() will now schedule any delayed + * io, up the recovery_count, and remove the region from the + * hash. + * + * There are 2 locks: + * A rw spin lock 'hash_lock' protects just the hash table, + * this is never held in write mode from interrupt context, + * which I believe means that we only have to disable irqs when + * doing a write lock. + * + * An ordinary spin lock 'region_lock' that protects the three + * lists in the region_hash, with the 'state', 'list' and + * 'bhs_delayed' fields of the regions. This is used from irq + * context, so all other uses will have to suspend local irqs. + *---------------------------------------------------------------*/ +struct mirror_set; +struct region_hash { + struct mirror_set *ms; + sector_t region_size; + unsigned region_shift; + + /* holds persistent region state */ + struct dirty_log *log; + + /* hash table */ + rwlock_t hash_lock; + mempool_t *region_pool; + unsigned int mask; + unsigned int nr_buckets; + struct list_head *buckets; + + spinlock_t region_lock; + struct semaphore recovery_count; + struct list_head clean_regions; + struct list_head quiesced_regions; + struct list_head recovered_regions; +}; + +enum { + RH_CLEAN, + RH_DIRTY, + RH_NOSYNC, + RH_RECOVERING +}; + +struct region { + struct region_hash *rh; /* FIXME: can we get rid of this ? */ + region_t key; + int state; + + struct list_head hash_list; + struct list_head list; + + atomic_t pending; + struct bio_list delayed_bios; +}; + +/* + * Conversion fns + */ +static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio) +{ + return bio->bi_sector >> rh->region_shift; +} + +static inline sector_t region_to_sector(struct region_hash *rh, region_t region) +{ + return region << rh->region_shift; +} + +/* FIXME move this */ +static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw); + +static void *region_alloc(int gfp_mask, void *pool_data) +{ + return kmalloc(sizeof(struct region), gfp_mask); +} + +static void region_free(void *element, void *pool_data) +{ + kfree(element); +} + +#define MIN_REGIONS 64 +#define MAX_RECOVERY 1 +static int rh_init(struct region_hash *rh, struct mirror_set *ms, + struct dirty_log *log, sector_t region_size, + region_t nr_regions) +{ + unsigned int nr_buckets, max_buckets; + size_t i; + + /* + * Calculate a suitable number of buckets for our hash + * table. + */ + max_buckets = nr_regions >> 6; + for (nr_buckets = 128u; nr_buckets < max_buckets; nr_buckets <<= 1) + ; + nr_buckets >>= 1; + + rh->ms = ms; + rh->log = log; + rh->region_size = region_size; + rh->region_shift = ffs(region_size) - 1; + rwlock_init(&rh->hash_lock); + rh->mask = nr_buckets - 1; + rh->nr_buckets = nr_buckets; + + rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets)); + if (!rh->buckets) { + DMERR("unable to allocate region hash memory"); + return -ENOMEM; + } + + for (i = 0; i < nr_buckets; i++) + INIT_LIST_HEAD(rh->buckets + i); + + spin_lock_init(&rh->region_lock); + sema_init(&rh->recovery_count, 0); + INIT_LIST_HEAD(&rh->clean_regions); + INIT_LIST_HEAD(&rh->quiesced_regions); + INIT_LIST_HEAD(&rh->recovered_regions); + + rh->region_pool = mempool_create(MIN_REGIONS, region_alloc, + region_free, NULL); + if (!rh->region_pool) { + vfree(rh->buckets); + rh->buckets = NULL; + return -ENOMEM; + } + + return 0; +} + +static void rh_exit(struct region_hash *rh) +{ + unsigned int h; + struct region *reg, *nreg; + + BUG_ON(!list_empty(&rh->quiesced_regions)); + for (h = 0; h < rh->nr_buckets; h++) { + list_for_each_entry_safe(reg, nreg, rh->buckets + h, hash_list) { + BUG_ON(atomic_read(®->pending)); + mempool_free(reg, rh->region_pool); + } + } + + if (rh->log) + dm_destroy_dirty_log(rh->log); + if (rh->region_pool) + mempool_destroy(rh->region_pool); + vfree(rh->buckets); +} + +#define RH_HASH_MULT 2654435387U + +static inline unsigned int rh_hash(struct region_hash *rh, region_t region) +{ + return (unsigned int) ((region * RH_HASH_MULT) >> 12) & rh->mask; +} + +static struct region *__rh_lookup(struct region_hash *rh, region_t region) +{ + struct region *reg; + + list_for_each_entry (reg, rh->buckets + rh_hash(rh, region), hash_list) + if (reg->key == region) + return reg; + + return NULL; +} + +static void __rh_insert(struct region_hash *rh, struct region *reg) +{ + unsigned int h = rh_hash(rh, reg->key); + list_add(®->hash_list, rh->buckets + h); +} + +static struct region *__rh_alloc(struct region_hash *rh, region_t region) +{ + struct region *reg, *nreg; + + read_unlock(&rh->hash_lock); + nreg = mempool_alloc(rh->region_pool, GFP_NOIO); + nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? + RH_CLEAN : RH_NOSYNC; + nreg->rh = rh; + nreg->key = region; + + INIT_LIST_HEAD(&nreg->list); + + atomic_set(&nreg->pending, 0); + bio_list_init(&nreg->delayed_bios); + write_lock_irq(&rh->hash_lock); + + reg = __rh_lookup(rh, region); + if (reg) + /* we lost the race */ + mempool_free(nreg, rh->region_pool); + + else { + __rh_insert(rh, nreg); + if (nreg->state == RH_CLEAN) { + spin_lock_irq(&rh->region_lock); + list_add(&nreg->list, &rh->clean_regions); + spin_unlock_irq(&rh->region_lock); + } + reg = nreg; + } + write_unlock_irq(&rh->hash_lock); + read_lock(&rh->hash_lock); + + return reg; +} + +static inline struct region *__rh_find(struct region_hash *rh, region_t region) +{ + struct region *reg; + + reg = __rh_lookup(rh, region); + if (!reg) + reg = __rh_alloc(rh, region); + + return reg; +} + +static int rh_state(struct region_hash *rh, region_t region, int may_block) +{ + int r; + struct region *reg; + + read_lock(&rh->hash_lock); + reg = __rh_lookup(rh, region); + read_unlock(&rh->hash_lock); + + if (reg) + return reg->state; + + /* + * The region wasn't in the hash, so we fall back to the + * dirty log. + */ + r = rh->log->type->in_sync(rh->log, region, may_block); + + /* + * Any error from the dirty log (eg. -EWOULDBLOCK) gets + * taken as a RH_NOSYNC + */ + return r == 1 ? RH_CLEAN : RH_NOSYNC; +} + +static inline int rh_in_sync(struct region_hash *rh, + region_t region, int may_block) +{ + int state = rh_state(rh, region, may_block); + return state == RH_CLEAN || state == RH_DIRTY; +} + +static void dispatch_bios(struct mirror_set *ms, struct bio_list *bio_list) +{ + struct bio *bio; + + while ((bio = bio_list_pop(bio_list))) { + queue_bio(ms, bio, WRITE); + } +} + +static void rh_update_states(struct region_hash *rh) +{ + struct region *reg, *next; + + LIST_HEAD(clean); + LIST_HEAD(recovered); + + /* + * Quickly grab the lists. + */ + write_lock_irq(&rh->hash_lock); + spin_lock(&rh->region_lock); + if (!list_empty(&rh->clean_regions)) { + list_splice(&rh->clean_regions, &clean); + INIT_LIST_HEAD(&rh->clean_regions); + + list_for_each_entry (reg, &clean, list) { + rh->log->type->clear_region(rh->log, reg->key); + list_del(®->hash_list); + } + } + + if (!list_empty(&rh->recovered_regions)) { + list_splice(&rh->recovered_regions, &recovered); + INIT_LIST_HEAD(&rh->recovered_regions); + + list_for_each_entry (reg, &recovered, list) + list_del(®->hash_list); + } + spin_unlock(&rh->region_lock); + write_unlock_irq(&rh->hash_lock); + + /* + * All the regions on the recovered and clean lists have + * now been pulled out of the system, so no need to do + * any more locking. + */ + list_for_each_entry_safe (reg, next, &recovered, list) { + rh->log->type->clear_region(rh->log, reg->key); + rh->log->type->complete_resync_work(rh->log, reg->key, 1); + dispatch_bios(rh->ms, ®->delayed_bios); + up(&rh->recovery_count); + mempool_free(reg, rh->region_pool); + } + + if (!list_empty(&recovered)) + rh->log->type->flush(rh->log); + + list_for_each_entry_safe (reg, next, &clean, list) + mempool_free(reg, rh->region_pool); +} + +static void rh_inc(struct region_hash *rh, region_t region) +{ + struct region *reg; + + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + if (reg->state == RH_CLEAN) { + rh->log->type->mark_region(rh->log, reg->key); + + spin_lock_irq(&rh->region_lock); + reg->state = RH_DIRTY; + list_del_init(®->list); /* take off the clean list */ + spin_unlock_irq(&rh->region_lock); + } + + atomic_inc(®->pending); + read_unlock(&rh->hash_lock); +} + +static void rh_inc_pending(struct region_hash *rh, struct bio_list *bios) +{ + struct bio *bio; + + for (bio = bios->head; bio; bio = bio->bi_next) + rh_inc(rh, bio_to_region(rh, bio)); +} + +static void rh_dec(struct region_hash *rh, region_t region) +{ + unsigned long flags; + struct region *reg; + int should_wake = 0; + + read_lock(&rh->hash_lock); + reg = __rh_lookup(rh, region); + read_unlock(&rh->hash_lock); + + if (atomic_dec_and_test(®->pending)) { + spin_lock_irqsave(&rh->region_lock, flags); + if (reg->state == RH_RECOVERING) { + list_add_tail(®->list, &rh->quiesced_regions); + } else { + reg->state = RH_CLEAN; + list_add(®->list, &rh->clean_regions); + } + spin_unlock_irqrestore(&rh->region_lock, flags); + should_wake = 1; + } + + if (should_wake) + wake(); +} + +/* + * Starts quiescing a region in preparation for recovery. + */ +static int __rh_recovery_prepare(struct region_hash *rh) +{ + int r; + struct region *reg; + region_t region; + + /* + * Ask the dirty log what's next. + */ + r = rh->log->type->get_resync_work(rh->log, ®ion); + if (r <= 0) + return r; + + /* + * Get this region, and start it quiescing by setting the + * recovering flag. + */ + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + read_unlock(&rh->hash_lock); + + spin_lock_irq(&rh->region_lock); + reg->state = RH_RECOVERING; + + /* Already quiesced ? */ + if (atomic_read(®->pending)) + list_del_init(®->list); + + else { + list_del_init(®->list); + list_add(®->list, &rh->quiesced_regions); + } + spin_unlock_irq(&rh->region_lock); + + return 1; +} + +static void rh_recovery_prepare(struct region_hash *rh) +{ + while (!down_trylock(&rh->recovery_count)) + if (__rh_recovery_prepare(rh) <= 0) { + up(&rh->recovery_count); + break; + } +} + +/* + * Returns any quiesced regions. + */ +static struct region *rh_recovery_start(struct region_hash *rh) +{ + struct region *reg = NULL; + + spin_lock_irq(&rh->region_lock); + if (!list_empty(&rh->quiesced_regions)) { + reg = list_entry(rh->quiesced_regions.next, + struct region, list); + list_del_init(®->list); /* remove from the quiesced list */ + } + spin_unlock_irq(&rh->region_lock); + + return reg; +} + +/* FIXME: success ignored for now */ +static void rh_recovery_end(struct region *reg, int success) +{ + struct region_hash *rh = reg->rh; + + spin_lock_irq(&rh->region_lock); + list_add(®->list, ®->rh->recovered_regions); + spin_unlock_irq(&rh->region_lock); + + wake(); +} + +static void rh_flush(struct region_hash *rh) +{ + rh->log->type->flush(rh->log); +} + +static void rh_delay(struct region_hash *rh, struct bio *bio) +{ + struct region *reg; + + read_lock(&rh->hash_lock); + reg = __rh_find(rh, bio_to_region(rh, bio)); + bio_list_add(®->delayed_bios, bio); + read_unlock(&rh->hash_lock); +} + +static void rh_stop_recovery(struct region_hash *rh) +{ + int i; + + /* wait for any recovering regions */ + for (i = 0; i < MAX_RECOVERY; i++) + down(&rh->recovery_count); +} + +static void rh_start_recovery(struct region_hash *rh) +{ + int i; + + for (i = 0; i < MAX_RECOVERY; i++) + up(&rh->recovery_count); + + wake(); +} + +/*----------------------------------------------------------------- + * Mirror set structures. + *---------------------------------------------------------------*/ +struct mirror { + atomic_t error_count; + struct dm_dev *dev; + sector_t offset; +}; + +struct mirror_set { + struct dm_target *ti; + struct list_head list; + struct region_hash rh; + struct kcopyd_client *kcopyd_client; + + spinlock_t lock; /* protects the next two lists */ + struct bio_list reads; + struct bio_list writes; + + /* recovery */ + region_t nr_regions; + int in_sync; + + unsigned int nr_mirrors; + struct mirror mirror[0]; +}; + +/* + * Every mirror should look like this one. + */ +#define DEFAULT_MIRROR 0 + +/* + * This is yucky. We squirrel the mirror_set struct away inside + * bi_next for write buffers. This is safe since the bh + * doesn't get submitted to the lower levels of block layer. + */ +static struct mirror_set *bio_get_ms(struct bio *bio) +{ + return (struct mirror_set *) bio->bi_next; +} + +static void bio_set_ms(struct bio *bio, struct mirror_set *ms) +{ + bio->bi_next = (struct bio *) ms; +} + +/*----------------------------------------------------------------- + * Recovery. + * + * When a mirror is first activated we may find that some regions + * are in the no-sync state. We have to recover these by + * recopying from the default mirror to all the others. + *---------------------------------------------------------------*/ +static void recovery_complete(int read_err, unsigned int write_err, + void *context) +{ + struct region *reg = (struct region *) context; + + /* FIXME: better error handling */ + rh_recovery_end(reg, read_err || write_err); +} + +static int recover(struct mirror_set *ms, struct region *reg) +{ + int r; + unsigned int i; + struct io_region from, to[ms->nr_mirrors - 1], *dest; + struct mirror *m; + unsigned long flags = 0; + + /* fill in the source */ + m = ms->mirror + DEFAULT_MIRROR; + from.bdev = m->dev->bdev; + from.sector = m->offset + region_to_sector(reg->rh, reg->key); + if (reg->key == (ms->nr_regions - 1)) { + /* + * The final region may be smaller than + * region_size. + */ + from.count = ms->ti->len & (reg->rh->region_size - 1); + if (!from.count) + from.count = reg->rh->region_size; + } else + from.count = reg->rh->region_size; + + /* fill in the destinations */ + for (i = 0, dest = to; i < ms->nr_mirrors; i++) { + if (i == DEFAULT_MIRROR) + continue; + + m = ms->mirror + i; + dest->bdev = m->dev->bdev; + dest->sector = m->offset + region_to_sector(reg->rh, reg->key); + dest->count = from.count; + dest++; + } + + /* hand to kcopyd */ + set_bit(KCOPYD_IGNORE_ERROR, &flags); + r = kcopyd_copy(ms->kcopyd_client, &from, ms->nr_mirrors - 1, to, flags, + recovery_complete, reg); + + return r; +} + +static void do_recovery(struct mirror_set *ms) +{ + int r; + struct region *reg; + struct dirty_log *log = ms->rh.log; + + /* + * Start quiescing some regions. + */ + rh_recovery_prepare(&ms->rh); + + /* + * Copy any already quiesced regions. + */ + while ((reg = rh_recovery_start(&ms->rh))) { + r = recover(ms, reg); + if (r) + rh_recovery_end(reg, 0); + } + + /* + * Update the in sync flag. + */ + if (!ms->in_sync && + (log->type->get_sync_count(log) == ms->nr_regions)) { + /* the sync is complete */ + dm_table_event(ms->ti->table); + ms->in_sync = 1; + } +} + +/*----------------------------------------------------------------- + * Reads + *---------------------------------------------------------------*/ +static struct mirror *choose_mirror(struct mirror_set *ms, sector_t sector) +{ + /* FIXME: add read balancing */ + return ms->mirror + DEFAULT_MIRROR; +} + +/* + * remap a buffer to a particular mirror. + */ +static void map_bio(struct mirror_set *ms, struct mirror *m, struct bio *bio) +{ + bio->bi_bdev = m->dev->bdev; + bio->bi_sector = m->offset + (bio->bi_sector - ms->ti->begin); +} + +static void do_reads(struct mirror_set *ms, struct bio_list *reads) +{ + region_t region; + struct bio *bio; + struct mirror *m; + + while ((bio = bio_list_pop(reads))) { + region = bio_to_region(&ms->rh, bio); + + /* + * We can only read balance if the region is in sync. + */ + if (rh_in_sync(&ms->rh, region, 0)) + m = choose_mirror(ms, bio->bi_sector); + else + m = ms->mirror + DEFAULT_MIRROR; + + map_bio(ms, m, bio); + generic_make_request(bio); + } +} + +/*----------------------------------------------------------------- + * Writes. + * + * We do different things with the write io depending on the + * state of the region that it's in: + * + * SYNC: increment pending, use kcopyd to write to *all* mirrors + * RECOVERING: delay the io until recovery completes + * NOSYNC: increment pending, just write to the default mirror + *---------------------------------------------------------------*/ +static void write_callback(unsigned long error, void *context) +{ + unsigned int i; + int uptodate = 1; + struct bio *bio = (struct bio *) context; + struct mirror_set *ms; + + ms = bio_get_ms(bio); + bio_set_ms(bio, NULL); + + /* + * NOTE: We don't decrement the pending count here, + * instead it is done by the targets endio function. + * This way we handle both writes to SYNC and NOSYNC + * regions with the same code. + */ + + if (error) { + /* + * only error the io if all mirrors failed. + * FIXME: bogus + */ + uptodate = 0; + for (i = 0; i < ms->nr_mirrors; i++) + if (!test_bit(i, &error)) { + uptodate = 1; + break; + } + } + bio_endio(bio, bio->bi_size, 0); +} + +static void do_write(struct mirror_set *ms, struct bio *bio) +{ + unsigned int i; + struct io_region io[ms->nr_mirrors]; + struct mirror *m; + + for (i = 0; i < ms->nr_mirrors; i++) { + m = ms->mirror + i; + + io[i].bdev = m->dev->bdev; + io[i].sector = m->offset + (bio->bi_sector - ms->ti->begin); + io[i].count = bio->bi_size >> 9; + } + + bio_set_ms(bio, ms); + dm_io_async_bvec(ms->nr_mirrors, io, WRITE, + bio->bi_io_vec + bio->bi_idx, + write_callback, bio); +} + +static void do_writes(struct mirror_set *ms, struct bio_list *writes) +{ + int state; + struct bio *bio; + struct bio_list sync, nosync, recover, *this_list = NULL; + + if (!writes->head) + return; + + /* + * Classify each write. + */ + bio_list_init(&sync); + bio_list_init(&nosync); + bio_list_init(&recover); + + while ((bio = bio_list_pop(writes))) { + state = rh_state(&ms->rh, bio_to_region(&ms->rh, bio), 1); + switch (state) { + case RH_CLEAN: + case RH_DIRTY: + this_list = &sync; + break; + + case RH_NOSYNC: + this_list = &nosync; + break; + + case RH_RECOVERING: + this_list = &recover; + break; + } + + bio_list_add(this_list, bio); + } + + /* + * Increment the pending counts for any regions that will + * be written to (writes to recover regions are going to + * be delayed). + */ + rh_inc_pending(&ms->rh, &sync); + rh_inc_pending(&ms->rh, &nosync); + rh_flush(&ms->rh); + + /* + * Dispatch io. + */ + while ((bio = bio_list_pop(&sync))) + do_write(ms, bio); + + while ((bio = bio_list_pop(&recover))) + rh_delay(&ms->rh, bio); + + while ((bio = bio_list_pop(&nosync))) { + map_bio(ms, ms->mirror + DEFAULT_MIRROR, bio); + generic_make_request(bio); + } +} + +/*----------------------------------------------------------------- + * kmirrord + *---------------------------------------------------------------*/ +static LIST_HEAD(_mirror_sets); +static DECLARE_RWSEM(_mirror_sets_lock); + +static void do_mirror(struct mirror_set *ms) +{ + struct bio_list reads, writes; + + spin_lock(&ms->lock); + reads = ms->reads; + writes = ms->writes; + bio_list_init(&ms->reads); + bio_list_init(&ms->writes); + spin_unlock(&ms->lock); + + rh_update_states(&ms->rh); + do_recovery(ms); + do_reads(ms, &reads); + do_writes(ms, &writes); +} + +static void do_work(void *ignored) +{ + struct mirror_set *ms; + + down_read(&_mirror_sets_lock); + list_for_each_entry (ms, &_mirror_sets, list) + do_mirror(ms); + up_read(&_mirror_sets_lock); +} + +/*----------------------------------------------------------------- + * Target functions + *---------------------------------------------------------------*/ +static struct mirror_set *alloc_context(unsigned int nr_mirrors, + sector_t region_size, + struct dm_target *ti, + struct dirty_log *dl) +{ + size_t len; + struct mirror_set *ms = NULL; + + if (array_too_big(sizeof(*ms), sizeof(ms->mirror[0]), nr_mirrors)) + return NULL; + + len = sizeof(*ms) + (sizeof(ms->mirror[0]) * nr_mirrors); + + ms = kmalloc(len, GFP_KERNEL); + if (!ms) { + ti->error = "dm-mirror: Cannot allocate mirror context"; + return NULL; + } + + memset(ms, 0, len); + spin_lock_init(&ms->lock); + + ms->ti = ti; + ms->nr_mirrors = nr_mirrors; + ms->nr_regions = dm_div_up(ti->len, region_size); + ms->in_sync = 0; + + if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) { + ti->error = "dm-mirror: Error creating dirty region hash"; + kfree(ms); + return NULL; + } + + return ms; +} + +static void free_context(struct mirror_set *ms, struct dm_target *ti, + unsigned int m) +{ + while (m--) + dm_put_device(ti, ms->mirror[m].dev); + + rh_exit(&ms->rh); + kfree(ms); +} + +static inline int _check_region_size(struct dm_target *ti, sector_t size) +{ + return !(size % (PAGE_SIZE >> 9) || (size & (size - 1)) || + size > ti->len); +} + +static int get_mirror(struct mirror_set *ms, struct dm_target *ti, + unsigned int mirror, char **argv) +{ + sector_t offset; + + if (sscanf(argv[1], SECTOR_FORMAT, &offset) != 1) { + ti->error = "dm-mirror: Invalid offset"; + return -EINVAL; + } + + if (dm_get_device(ti, argv[0], offset, ti->len, + dm_table_get_mode(ti->table), + &ms->mirror[mirror].dev)) { + ti->error = "dm-mirror: Device lookup failure"; + return -ENXIO; + } + + ms->mirror[mirror].offset = offset; + + return 0; +} + +static int add_mirror_set(struct mirror_set *ms) +{ + down_write(&_mirror_sets_lock); + list_add_tail(&ms->list, &_mirror_sets); + up_write(&_mirror_sets_lock); + wake(); + + return 0; +} + +static void del_mirror_set(struct mirror_set *ms) +{ + down_write(&_mirror_sets_lock); + list_del(&ms->list); + up_write(&_mirror_sets_lock); +} + +/* + * Create dirty log: log_type #log_params + */ +static struct dirty_log *create_dirty_log(struct dm_target *ti, + unsigned int argc, char **argv, + unsigned int *args_used) +{ + unsigned int param_count; + struct dirty_log *dl; + + if (argc < 2) { + ti->error = "dm-mirror: Insufficient mirror log arguments"; + return NULL; + } + + if (sscanf(argv[1], "%u", ¶m_count) != 1) { + ti->error = "dm-mirror: Invalid mirror log argument count"; + return NULL; + } + + *args_used = 2 + param_count; + + if (argc < *args_used) { + ti->error = "dm-mirror: Insufficient mirror log arguments"; + return NULL; + } + + dl = dm_create_dirty_log(argv[0], ti, param_count, argv + 2); + if (!dl) { + ti->error = "dm-mirror: Error creating mirror dirty log"; + return NULL; + } + + if (!_check_region_size(ti, dl->type->get_region_size(dl))) { + ti->error = "dm-mirror: Invalid region size"; + dm_destroy_dirty_log(dl); + return NULL; + } + + return dl; +} + +/* + * Construct a mirror mapping: + * + * log_type #log_params + * #mirrors [mirror_path offset]{2,} + * + * For now, #log_params = 1, log_type = "core" + * + */ +#define DM_IO_PAGES 64 +static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + int r; + unsigned int nr_mirrors, m, args_used; + struct mirror_set *ms; + struct dirty_log *dl; + + dl = create_dirty_log(ti, argc, argv, &args_used); + if (!dl) + return -EINVAL; + + argv += args_used; + argc -= args_used; + + if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 || + nr_mirrors < 2) { + ti->error = "dm-mirror: Invalid number of mirrors"; + dm_destroy_dirty_log(dl); + return -EINVAL; + } + + argv++, argc--; + + if (argc != nr_mirrors * 2) { + ti->error = "dm-mirror: Wrong number of mirror arguments"; + dm_destroy_dirty_log(dl); + return -EINVAL; + } + + ms = alloc_context(nr_mirrors, dl->type->get_region_size(dl), ti, dl); + if (!ms) { + dm_destroy_dirty_log(dl); + return -ENOMEM; + } + + /* Get the mirror parameter sets */ + for (m = 0; m < nr_mirrors; m++) { + r = get_mirror(ms, ti, m, argv); + if (r) { + free_context(ms, ti, m); + return r; + } + argv += 2; + argc -= 2; + } + + ti->private = ms; + + r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client); + if (r) { + free_context(ms, ti, ms->nr_mirrors); + return r; + } + + add_mirror_set(ms); + return 0; +} + +static void mirror_dtr(struct dm_target *ti) +{ + struct mirror_set *ms = (struct mirror_set *) ti->private; + + del_mirror_set(ms); + kcopyd_client_destroy(ms->kcopyd_client); + free_context(ms, ti, ms->nr_mirrors); +} + +static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw) +{ + int should_wake = 0; + struct bio_list *bl; + + bl = (rw == WRITE) ? &ms->writes : &ms->reads; + spin_lock(&ms->lock); + should_wake = !(bl->head); + bio_list_add(bl, bio); + spin_unlock(&ms->lock); + + if (should_wake) + wake(); +} + +/* + * Mirror mapping function + */ +static int mirror_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + int r, rw = bio_rw(bio); + struct mirror *m; + struct mirror_set *ms = ti->private; + + map_context->ll = bio->bi_sector >> ms->rh.region_shift; + + if (rw == WRITE) { + queue_bio(ms, bio, rw); + return 0; + } + + r = ms->rh.log->type->in_sync(ms->rh.log, + bio_to_region(&ms->rh, bio), 0); + if (r < 0 && r != -EWOULDBLOCK) + return r; + + if (r == -EWOULDBLOCK) /* FIXME: ugly */ + r = 0; + + /* + * We don't want to fast track a recovery just for a read + * ahead. So we just let it silently fail. + * FIXME: get rid of this. + */ + if (!r && rw == READA) + return -EIO; + + if (!r) { + /* Pass this io over to the daemon */ + queue_bio(ms, bio, rw); + return 0; + } + + m = choose_mirror(ms, bio->bi_sector); + if (!m) + return -EIO; + + map_bio(ms, m, bio); + return 1; +} + +static int mirror_end_io(struct dm_target *ti, struct bio *bio, + int error, union map_info *map_context) +{ + int rw = bio_rw(bio); + struct mirror_set *ms = (struct mirror_set *) ti->private; + region_t region = map_context->ll; + + /* + * We need to dec pending if this was a write. + */ + if (rw == WRITE) + rh_dec(&ms->rh, region); + + return 0; +} + +static void mirror_suspend(struct dm_target *ti) +{ + struct mirror_set *ms = (struct mirror_set *) ti->private; + struct dirty_log *log = ms->rh.log; + rh_stop_recovery(&ms->rh); + if (log->type->suspend && log->type->suspend(log)) + /* FIXME: need better error handling */ + DMWARN("log suspend failed"); +} + +static void mirror_resume(struct dm_target *ti) +{ + struct mirror_set *ms = (struct mirror_set *) ti->private; + struct dirty_log *log = ms->rh.log; + if (log->type->resume && log->type->resume(log)) + /* FIXME: need better error handling */ + DMWARN("log resume failed"); + rh_start_recovery(&ms->rh); +} + +static int mirror_status(struct dm_target *ti, status_type_t type, + char *result, unsigned int maxlen) +{ + char buffer[32]; + unsigned int m, sz = 0; + struct mirror_set *ms = (struct mirror_set *) ti->private; + +#define EMIT(x...) sz += ((sz >= maxlen) ? \ + 0 : scnprintf(result + sz, maxlen - sz, x)) + + switch (type) { + case STATUSTYPE_INFO: + EMIT("%d ", ms->nr_mirrors); + + for (m = 0; m < ms->nr_mirrors; m++) { + format_dev_t(buffer, ms->mirror[m].dev->bdev->bd_dev); + EMIT("%s ", buffer); + } + + EMIT(SECTOR_FORMAT "/" SECTOR_FORMAT, + ms->rh.log->type->get_sync_count(ms->rh.log), + ms->nr_regions); + break; + + case STATUSTYPE_TABLE: + EMIT("%s 1 " SECTOR_FORMAT " %d ", + ms->rh.log->type->name, ms->rh.region_size, + ms->nr_mirrors); + + for (m = 0; m < ms->nr_mirrors; m++) { + format_dev_t(buffer, ms->mirror[m].dev->bdev->bd_dev); + EMIT("%s " SECTOR_FORMAT " ", + buffer, ms->mirror[m].offset); + } + } + + return 0; +} + +static struct target_type mirror_target = { + .name = "mirror", + .version = {1, 0, 1}, + .module = THIS_MODULE, + .ctr = mirror_ctr, + .dtr = mirror_dtr, + .map = mirror_map, + .end_io = mirror_end_io, + .suspend = mirror_suspend, + .resume = mirror_resume, + .status = mirror_status, +}; + +static int __init dm_mirror_init(void) +{ + int r; + + r = dm_dirty_log_init(); + if (r) + return r; + + _kmirrord_wq = create_workqueue("kmirrord"); + if (!_kmirrord_wq) { + DMERR("couldn't start kmirrord"); + dm_dirty_log_exit(); + return r; + } + INIT_WORK(&_kmirrord_work, do_work, NULL); + + r = dm_register_target(&mirror_target); + if (r < 0) { + DMERR("%s: Failed to register mirror target", + mirror_target.name); + dm_dirty_log_exit(); + destroy_workqueue(_kmirrord_wq); + } + + return r; +} + +static void __exit dm_mirror_exit(void) +{ + int r; + + r = dm_unregister_target(&mirror_target); + if (r < 0) + DMERR("%s: unregister failed %d", mirror_target.name, r); + + destroy_workqueue(_kmirrord_wq); + dm_dirty_log_exit(); +} + +/* Module hooks */ +module_init(dm_mirror_init); +module_exit(dm_mirror_exit); + +MODULE_DESCRIPTION(DM_NAME " mirror target"); +MODULE_AUTHOR("Joe Thornber"); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-snap.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1213 @@ +/* + * dm-snapshot.c + * + * Copyright (C) 2001-2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm-snap.h" +#include "dm-bio-list.h" +#include "kcopyd.h" + +/* + * The percentage increment we will wake up users at + */ +#define WAKE_UP_PERCENT 5 + +/* + * kcopyd priority of snapshot operations + */ +#define SNAPSHOT_COPY_PRIORITY 2 + +/* + * Each snapshot reserves this many pages for io + */ +#define SNAPSHOT_PAGES 256 + +struct pending_exception { + struct exception e; + + /* + * Origin buffers waiting for this to complete are held + * in a bio list + */ + struct bio_list origin_bios; + struct bio_list snapshot_bios; + + /* + * Other pending_exceptions that are processing this + * chunk. When this list is empty, we know we can + * complete the origins. + */ + struct list_head siblings; + + /* Pointer back to snapshot context */ + struct dm_snapshot *snap; + + /* + * 1 indicates the exception has already been sent to + * kcopyd. + */ + int started; +}; + +/* + * Hash table mapping origin volumes to lists of snapshots and + * a lock to protect it + */ +static kmem_cache_t *exception_cache; +static kmem_cache_t *pending_cache; +static mempool_t *pending_pool; + +/* + * One of these per registered origin, held in the snapshot_origins hash + */ +struct origin { + /* The origin device */ + struct block_device *bdev; + + struct list_head hash_list; + + /* List of snapshots for this origin */ + struct list_head snapshots; +}; + +/* + * Size of the hash table for origin volumes. If we make this + * the size of the minors list then it should be nearly perfect + */ +#define ORIGIN_HASH_SIZE 256 +#define ORIGIN_MASK 0xFF +static struct list_head *_origins; +static struct rw_semaphore _origins_lock; + +static int init_origin_hash(void) +{ + int i; + + _origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head), + GFP_KERNEL); + if (!_origins) { + DMERR("Device mapper: Snapshot: unable to allocate memory"); + return -ENOMEM; + } + + for (i = 0; i < ORIGIN_HASH_SIZE; i++) + INIT_LIST_HEAD(_origins + i); + init_rwsem(&_origins_lock); + + return 0; +} + +static void exit_origin_hash(void) +{ + kfree(_origins); +} + +static inline unsigned int origin_hash(struct block_device *bdev) +{ + return bdev->bd_dev & ORIGIN_MASK; +} + +static struct origin *__lookup_origin(struct block_device *origin) +{ + struct list_head *ol; + struct origin *o; + + ol = &_origins[origin_hash(origin)]; + list_for_each_entry (o, ol, hash_list) + if (bdev_equal(o->bdev, origin)) + return o; + + return NULL; +} + +static void __insert_origin(struct origin *o) +{ + struct list_head *sl = &_origins[origin_hash(o->bdev)]; + list_add_tail(&o->hash_list, sl); +} + +/* + * Make a note of the snapshot and its origin so we can look it + * up when the origin has a write on it. + */ +static int register_snapshot(struct dm_snapshot *snap) +{ + struct origin *o; + struct block_device *bdev = snap->origin->bdev; + + down_write(&_origins_lock); + o = __lookup_origin(bdev); + + if (!o) { + /* New origin */ + o = kmalloc(sizeof(*o), GFP_KERNEL); + if (!o) { + up_write(&_origins_lock); + return -ENOMEM; + } + + /* Initialise the struct */ + INIT_LIST_HEAD(&o->snapshots); + o->bdev = bdev; + + __insert_origin(o); + } + + list_add_tail(&snap->list, &o->snapshots); + + up_write(&_origins_lock); + return 0; +} + +static void unregister_snapshot(struct dm_snapshot *s) +{ + struct origin *o; + + down_write(&_origins_lock); + o = __lookup_origin(s->origin->bdev); + + list_del(&s->list); + if (list_empty(&o->snapshots)) { + list_del(&o->hash_list); + kfree(o); + } + + up_write(&_origins_lock); +} + +/* + * Implementation of the exception hash tables. + */ +static int init_exception_table(struct exception_table *et, uint32_t size) +{ + unsigned int i; + + et->hash_mask = size - 1; + et->table = dm_vcalloc(size, sizeof(struct list_head)); + if (!et->table) + return -ENOMEM; + + for (i = 0; i < size; i++) + INIT_LIST_HEAD(et->table + i); + + return 0; +} + +static void exit_exception_table(struct exception_table *et, kmem_cache_t *mem) +{ + struct list_head *slot; + struct exception *ex, *next; + int i, size; + + size = et->hash_mask + 1; + for (i = 0; i < size; i++) { + slot = et->table + i; + + list_for_each_entry_safe (ex, next, slot, hash_list) + kmem_cache_free(mem, ex); + } + + vfree(et->table); +} + +static inline uint32_t exception_hash(struct exception_table *et, chunk_t chunk) +{ + return chunk & et->hash_mask; +} + +static void insert_exception(struct exception_table *eh, struct exception *e) +{ + struct list_head *l = &eh->table[exception_hash(eh, e->old_chunk)]; + list_add(&e->hash_list, l); +} + +static inline void remove_exception(struct exception *e) +{ + list_del(&e->hash_list); +} + +/* + * Return the exception data for a sector, or NULL if not + * remapped. + */ +static struct exception *lookup_exception(struct exception_table *et, + chunk_t chunk) +{ + struct list_head *slot; + struct exception *e; + + slot = &et->table[exception_hash(et, chunk)]; + list_for_each_entry (e, slot, hash_list) + if (e->old_chunk == chunk) + return e; + + return NULL; +} + +static inline struct exception *alloc_exception(void) +{ + struct exception *e; + + e = kmem_cache_alloc(exception_cache, GFP_NOIO); + if (!e) + e = kmem_cache_alloc(exception_cache, GFP_ATOMIC); + + return e; +} + +static inline void free_exception(struct exception *e) +{ + kmem_cache_free(exception_cache, e); +} + +static inline struct pending_exception *alloc_pending_exception(void) +{ + return mempool_alloc(pending_pool, GFP_NOIO); +} + +static inline void free_pending_exception(struct pending_exception *pe) +{ + mempool_free(pe, pending_pool); +} + +int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new) +{ + struct exception *e; + + e = alloc_exception(); + if (!e) + return -ENOMEM; + + e->old_chunk = old; + e->new_chunk = new; + insert_exception(&s->complete, e); + return 0; +} + +/* + * Hard coded magic. + */ +static int calc_max_buckets(void) +{ + /* use a fixed size of 2MB */ + unsigned long mem = 2 * 1024 * 1024; + mem /= sizeof(struct list_head); + + return mem; +} + +/* + * Rounds a number down to a power of 2. + */ +static inline uint32_t round_down(uint32_t n) +{ + while (n & (n - 1)) + n &= (n - 1); + return n; +} + +/* + * Allocate room for a suitable hash table. + */ +static int init_hash_tables(struct dm_snapshot *s) +{ + sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; + + /* + * Calculate based on the size of the original volume or + * the COW volume... + */ + cow_dev_size = get_dev_size(s->cow->bdev); + origin_dev_size = get_dev_size(s->origin->bdev); + max_buckets = calc_max_buckets(); + + hash_size = min(origin_dev_size, cow_dev_size) >> s->chunk_shift; + hash_size = min(hash_size, max_buckets); + + /* Round it down to a power of 2 */ + hash_size = round_down(hash_size); + if (init_exception_table(&s->complete, hash_size)) + return -ENOMEM; + + /* + * Allocate hash table for in-flight exceptions + * Make this smaller than the real hash table + */ + hash_size >>= 3; + if (hash_size < 64) + hash_size = 64; + + if (init_exception_table(&s->pending, hash_size)) { + exit_exception_table(&s->complete, exception_cache); + return -ENOMEM; + } + + return 0; +} + +/* + * Round a number up to the nearest 'size' boundary. size must + * be a power of 2. + */ +static inline ulong round_up(ulong n, ulong size) +{ + size--; + return (n + size) & ~size; +} + +/* + * Construct a snapshot mapping:

+ */ +static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + struct dm_snapshot *s; + unsigned long chunk_size; + int r = -EINVAL; + char persistent; + char *origin_path; + char *cow_path; + char *value; + int blocksize; + + if (argc < 4) { + ti->error = "dm-snapshot: requires exactly 4 arguments"; + r = -EINVAL; + goto bad1; + } + + origin_path = argv[0]; + cow_path = argv[1]; + persistent = toupper(*argv[2]); + + if (persistent != 'P' && persistent != 'N') { + ti->error = "Persistent flag is not P or N"; + r = -EINVAL; + goto bad1; + } + + chunk_size = simple_strtoul(argv[3], &value, 10); + if (chunk_size == 0 || value == NULL) { + ti->error = "Invalid chunk size"; + r = -EINVAL; + goto bad1; + } + + s = kmalloc(sizeof(*s), GFP_KERNEL); + if (s == NULL) { + ti->error = "Cannot allocate snapshot context private " + "structure"; + r = -ENOMEM; + goto bad1; + } + + r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin); + if (r) { + ti->error = "Cannot get origin device"; + goto bad2; + } + + r = dm_get_device(ti, cow_path, 0, 0, + FMODE_READ | FMODE_WRITE, &s->cow); + if (r) { + dm_put_device(ti, s->origin); + ti->error = "Cannot get COW device"; + goto bad2; + } + + /* + * Chunk size must be multiple of page size. Silently + * round up if it's not. + */ + chunk_size = round_up(chunk_size, PAGE_SIZE >> 9); + + /* Validate the chunk size against the device block size */ + blocksize = s->cow->bdev->bd_disk->queue->hardsect_size; + if (chunk_size % (blocksize >> 9)) { + ti->error = "Chunk size is not a multiple of device blocksize"; + r = -EINVAL; + goto bad3; + } + + /* Check chunk_size is a power of 2 */ + if (chunk_size & (chunk_size - 1)) { + ti->error = "Chunk size is not a power of 2"; + r = -EINVAL; + goto bad3; + } + + s->chunk_size = chunk_size; + s->chunk_mask = chunk_size - 1; + s->type = persistent; + s->chunk_shift = ffs(chunk_size) - 1; + + s->valid = 1; + s->have_metadata = 0; + s->last_percent = 0; + init_rwsem(&s->lock); + s->table = ti->table; + + /* Allocate hash table for COW data */ + if (init_hash_tables(s)) { + ti->error = "Unable to allocate hash table space"; + r = -ENOMEM; + goto bad3; + } + + /* + * Check the persistent flag - done here because we need the iobuf + * to check the LV header + */ + s->store.snap = s; + + if (persistent == 'P') + r = dm_create_persistent(&s->store, chunk_size); + else + r = dm_create_transient(&s->store, s, blocksize); + + if (r) { + ti->error = "Couldn't create exception store"; + r = -EINVAL; + goto bad4; + } + + r = kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); + if (r) { + ti->error = "Could not create kcopyd client"; + goto bad5; + } + + /* Add snapshot to the list of snapshots for this origin */ + if (register_snapshot(s)) { + r = -EINVAL; + ti->error = "Cannot register snapshot origin"; + goto bad6; + } + + ti->private = s; + ti->split_io = chunk_size; + + return 0; + + bad6: + kcopyd_client_destroy(s->kcopyd_client); + + bad5: + s->store.destroy(&s->store); + + bad4: + exit_exception_table(&s->pending, pending_cache); + exit_exception_table(&s->complete, exception_cache); + + bad3: + dm_put_device(ti, s->cow); + dm_put_device(ti, s->origin); + + bad2: + kfree(s); + + bad1: + return r; +} + +static void snapshot_dtr(struct dm_target *ti) +{ + struct dm_snapshot *s = (struct dm_snapshot *) ti->private; + + unregister_snapshot(s); + + exit_exception_table(&s->pending, pending_cache); + exit_exception_table(&s->complete, exception_cache); + + /* Deallocate memory used */ + s->store.destroy(&s->store); + + dm_put_device(ti, s->origin); + dm_put_device(ti, s->cow); + kcopyd_client_destroy(s->kcopyd_client); + kfree(s); +} + +/* + * Flush a list of buffers. + */ +static void flush_bios(struct bio *bio) +{ + struct bio *n; + + while (bio) { + n = bio->bi_next; + bio->bi_next = NULL; + generic_make_request(bio); + bio = n; + } +} + +/* + * Error a list of buffers. + */ +static void error_bios(struct bio *bio) +{ + struct bio *n; + + while (bio) { + n = bio->bi_next; + bio->bi_next = NULL; + bio_io_error(bio, bio->bi_size); + bio = n; + } +} + +static struct bio *__flush_bios(struct pending_exception *pe) +{ + struct pending_exception *sibling; + + if (list_empty(&pe->siblings)) + return bio_list_get(&pe->origin_bios); + + sibling = list_entry(pe->siblings.next, + struct pending_exception, siblings); + + list_del(&pe->siblings); + + /* This is fine as long as kcopyd is single-threaded. If kcopyd + * becomes multi-threaded, we'll need some locking here. + */ + bio_list_merge(&sibling->origin_bios, &pe->origin_bios); + + return NULL; +} + +static void pending_complete(struct pending_exception *pe, int success) +{ + struct exception *e; + struct dm_snapshot *s = pe->snap; + struct bio *flush = NULL; + + if (success) { + e = alloc_exception(); + if (!e) { + DMWARN("Unable to allocate exception."); + down_write(&s->lock); + s->store.drop_snapshot(&s->store); + s->valid = 0; + flush = __flush_bios(pe); + up_write(&s->lock); + + error_bios(bio_list_get(&pe->snapshot_bios)); + goto out; + } + *e = pe->e; + + /* + * Add a proper exception, and remove the + * in-flight exception from the list. + */ + down_write(&s->lock); + insert_exception(&s->complete, e); + remove_exception(&pe->e); + flush = __flush_bios(pe); + + /* Submit any pending write bios */ + up_write(&s->lock); + + flush_bios(bio_list_get(&pe->snapshot_bios)); + } else { + /* Read/write error - snapshot is unusable */ + down_write(&s->lock); + if (s->valid) + DMERR("Error reading/writing snapshot"); + s->store.drop_snapshot(&s->store); + s->valid = 0; + remove_exception(&pe->e); + flush = __flush_bios(pe); + up_write(&s->lock); + + error_bios(bio_list_get(&pe->snapshot_bios)); + + dm_table_event(s->table); + } + + out: + free_pending_exception(pe); + + if (flush) + flush_bios(flush); +} + +static void commit_callback(void *context, int success) +{ + struct pending_exception *pe = (struct pending_exception *) context; + pending_complete(pe, success); +} + +/* + * Called when the copy I/O has finished. kcopyd actually runs + * this code so don't block. + */ +static void copy_callback(int read_err, unsigned int write_err, void *context) +{ + struct pending_exception *pe = (struct pending_exception *) context; + struct dm_snapshot *s = pe->snap; + + if (read_err || write_err) + pending_complete(pe, 0); + + else + /* Update the metadata if we are persistent */ + s->store.commit_exception(&s->store, &pe->e, commit_callback, + pe); +} + +/* + * Dispatches the copy operation to kcopyd. + */ +static inline void start_copy(struct pending_exception *pe) +{ + struct dm_snapshot *s = pe->snap; + struct io_region src, dest; + struct block_device *bdev = s->origin->bdev; + sector_t dev_size; + + dev_size = get_dev_size(bdev); + + src.bdev = bdev; + src.sector = chunk_to_sector(s, pe->e.old_chunk); + src.count = min(s->chunk_size, dev_size - src.sector); + + dest.bdev = s->cow->bdev; + dest.sector = chunk_to_sector(s, pe->e.new_chunk); + dest.count = src.count; + + /* Hand over to kcopyd */ + kcopyd_copy(s->kcopyd_client, + &src, 1, &dest, 0, copy_callback, pe); +} + +/* + * Looks to see if this snapshot already has a pending exception + * for this chunk, otherwise it allocates a new one and inserts + * it into the pending table. + * + * NOTE: a write lock must be held on snap->lock before calling + * this. + */ +static struct pending_exception * +__find_pending_exception(struct dm_snapshot *s, struct bio *bio) +{ + struct exception *e; + struct pending_exception *pe; + chunk_t chunk = sector_to_chunk(s, bio->bi_sector); + + /* + * Is there a pending exception for this already ? + */ + e = lookup_exception(&s->pending, chunk); + if (e) { + /* cast the exception to a pending exception */ + pe = container_of(e, struct pending_exception, e); + + } else { + /* + * Create a new pending exception, we don't want + * to hold the lock while we do this. + */ + up_write(&s->lock); + pe = alloc_pending_exception(); + down_write(&s->lock); + + e = lookup_exception(&s->pending, chunk); + if (e) { + free_pending_exception(pe); + pe = container_of(e, struct pending_exception, e); + } else { + pe->e.old_chunk = chunk; + bio_list_init(&pe->origin_bios); + bio_list_init(&pe->snapshot_bios); + INIT_LIST_HEAD(&pe->siblings); + pe->snap = s; + pe->started = 0; + + if (s->store.prepare_exception(&s->store, &pe->e)) { + free_pending_exception(pe); + s->valid = 0; + return NULL; + } + + insert_exception(&s->pending, &pe->e); + } + } + + return pe; +} + +static inline void remap_exception(struct dm_snapshot *s, struct exception *e, + struct bio *bio) +{ + bio->bi_bdev = s->cow->bdev; + bio->bi_sector = chunk_to_sector(s, e->new_chunk) + + (bio->bi_sector & s->chunk_mask); +} + +static int snapshot_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + struct exception *e; + struct dm_snapshot *s = (struct dm_snapshot *) ti->private; + int r = 1; + chunk_t chunk; + struct pending_exception *pe; + + chunk = sector_to_chunk(s, bio->bi_sector); + + /* Full snapshots are not usable */ + if (!s->valid) + return -1; + + /* + * Write to snapshot - higher level takes care of RW/RO + * flags so we should only get this if we are + * writeable. + */ + if (bio_rw(bio) == WRITE) { + + /* FIXME: should only take write lock if we need + * to copy an exception */ + down_write(&s->lock); + + /* If the block is already remapped - use that, else remap it */ + e = lookup_exception(&s->complete, chunk); + if (e) { + remap_exception(s, e, bio); + up_write(&s->lock); + + } else { + pe = __find_pending_exception(s, bio); + + if (!pe) { + if (s->store.drop_snapshot) + s->store.drop_snapshot(&s->store); + s->valid = 0; + r = -EIO; + up_write(&s->lock); + } else { + remap_exception(s, &pe->e, bio); + bio_list_add(&pe->snapshot_bios, bio); + + if (!pe->started) { + /* this is protected by snap->lock */ + pe->started = 1; + up_write(&s->lock); + start_copy(pe); + } else + up_write(&s->lock); + r = 0; + } + } + + } else { + /* + * FIXME: this read path scares me because we + * always use the origin when we have a pending + * exception. However I can't think of a + * situation where this is wrong - ejt. + */ + + /* Do reads */ + down_read(&s->lock); + + /* See if it it has been remapped */ + e = lookup_exception(&s->complete, chunk); + if (e) + remap_exception(s, e, bio); + else + bio->bi_bdev = s->origin->bdev; + + up_read(&s->lock); + } + + return r; +} + +static void snapshot_resume(struct dm_target *ti) +{ + struct dm_snapshot *s = (struct dm_snapshot *) ti->private; + + if (s->have_metadata) + return; + + if (s->store.read_metadata(&s->store)) { + down_write(&s->lock); + s->valid = 0; + up_write(&s->lock); + } + + s->have_metadata = 1; +} + +static int snapshot_status(struct dm_target *ti, status_type_t type, + char *result, unsigned int maxlen) +{ + struct dm_snapshot *snap = (struct dm_snapshot *) ti->private; + char cow[32]; + char org[32]; + + switch (type) { + case STATUSTYPE_INFO: + if (!snap->valid) + snprintf(result, maxlen, "Invalid"); + else { + if (snap->store.fraction_full) { + sector_t numerator, denominator; + snap->store.fraction_full(&snap->store, + &numerator, + &denominator); + snprintf(result, maxlen, + SECTOR_FORMAT "/" SECTOR_FORMAT, + numerator, denominator); + } + else + snprintf(result, maxlen, "Unknown"); + } + break; + + case STATUSTYPE_TABLE: + /* + * kdevname returns a static pointer so we need + * to make private copies if the output is to + * make sense. + */ + format_dev_t(cow, snap->cow->bdev->bd_dev); + format_dev_t(org, snap->origin->bdev->bd_dev); + snprintf(result, maxlen, "%s %s %c " SECTOR_FORMAT, org, cow, + snap->type, snap->chunk_size); + break; + } + + return 0; +} + +/*----------------------------------------------------------------- + * Origin methods + *---------------------------------------------------------------*/ +static void list_merge(struct list_head *l1, struct list_head *l2) +{ + struct list_head *l1_n, *l2_p; + + l1_n = l1->next; + l2_p = l2->prev; + + l1->next = l2; + l2->prev = l1; + + l2_p->next = l1_n; + l1_n->prev = l2_p; +} + +static int __origin_write(struct list_head *snapshots, struct bio *bio) +{ + int r = 1, first = 1; + struct dm_snapshot *snap; + struct exception *e; + struct pending_exception *pe, *last = NULL; + chunk_t chunk; + + /* Do all the snapshots on this origin */ + list_for_each_entry (snap, snapshots, list) { + + /* Only deal with valid snapshots */ + if (!snap->valid) + continue; + + down_write(&snap->lock); + + /* + * Remember, different snapshots can have + * different chunk sizes. + */ + chunk = sector_to_chunk(snap, bio->bi_sector); + + /* + * Check exception table to see if block + * is already remapped in this snapshot + * and trigger an exception if not. + */ + e = lookup_exception(&snap->complete, chunk); + if (!e) { + pe = __find_pending_exception(snap, bio); + if (!pe) { + snap->store.drop_snapshot(&snap->store); + snap->valid = 0; + + } else { + if (last) + list_merge(&pe->siblings, + &last->siblings); + + last = pe; + r = 0; + } + } + + up_write(&snap->lock); + } + + /* + * Now that we have a complete pe list we can start the copying. + */ + if (last) { + pe = last; + do { + down_write(&pe->snap->lock); + if (first) + bio_list_add(&pe->origin_bios, bio); + if (!pe->started) { + pe->started = 1; + up_write(&pe->snap->lock); + start_copy(pe); + } else + up_write(&pe->snap->lock); + first = 0; + pe = list_entry(pe->siblings.next, + struct pending_exception, siblings); + + } while (pe != last); + } + + return r; +} + +/* + * Called on a write from the origin driver. + */ +static int do_origin(struct dm_dev *origin, struct bio *bio) +{ + struct origin *o; + int r = 1; + + down_read(&_origins_lock); + o = __lookup_origin(origin->bdev); + if (o) + r = __origin_write(&o->snapshots, bio); + up_read(&_origins_lock); + + return r; +} + +/* + * Origin: maps a linear range of a device, with hooks for snapshotting. + */ + +/* + * Construct an origin mapping: + * The context for an origin is merely a 'struct dm_dev *' + * pointing to the real device. + */ +static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + int r; + struct dm_dev *dev; + + if (argc != 1) { + ti->error = "dm-origin: incorrect number of arguments"; + return -EINVAL; + } + + r = dm_get_device(ti, argv[0], 0, ti->len, + dm_table_get_mode(ti->table), &dev); + if (r) { + ti->error = "Cannot get target device"; + return r; + } + + ti->private = dev; + return 0; +} + +static void origin_dtr(struct dm_target *ti) +{ + struct dm_dev *dev = (struct dm_dev *) ti->private; + dm_put_device(ti, dev); +} + +static int origin_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + struct dm_dev *dev = (struct dm_dev *) ti->private; + bio->bi_bdev = dev->bdev; + + /* Only tell snapshots if this is a write */ + return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1; +} + +#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) + +/* + * Set the target "split_io" field to the minimum of all the snapshots' + * chunk sizes. + */ +static void origin_resume(struct dm_target *ti) +{ + struct dm_dev *dev = (struct dm_dev *) ti->private; + struct dm_snapshot *snap; + struct origin *o; + chunk_t chunk_size = 0; + + down_read(&_origins_lock); + o = __lookup_origin(dev->bdev); + if (o) + list_for_each_entry (snap, &o->snapshots, list) + chunk_size = min_not_zero(chunk_size, snap->chunk_size); + up_read(&_origins_lock); + + ti->split_io = chunk_size; +} + +static int origin_status(struct dm_target *ti, status_type_t type, char *result, + unsigned int maxlen) +{ + struct dm_dev *dev = (struct dm_dev *) ti->private; + char buffer[32]; + + switch (type) { + case STATUSTYPE_INFO: + result[0] = '\0'; + break; + + case STATUSTYPE_TABLE: + format_dev_t(buffer, dev->bdev->bd_dev); + snprintf(result, maxlen, "%s", buffer); + break; + } + + return 0; +} + +static struct target_type origin_target = { + .name = "snapshot-origin", + .version = {1, 0, 1}, + .module = THIS_MODULE, + .ctr = origin_ctr, + .dtr = origin_dtr, + .map = origin_map, + .resume = origin_resume, + .status = origin_status, +}; + +static struct target_type snapshot_target = { + .name = "snapshot", + .version = {1, 0, 1}, + .module = THIS_MODULE, + .ctr = snapshot_ctr, + .dtr = snapshot_dtr, + .map = snapshot_map, + .resume = snapshot_resume, + .status = snapshot_status, +}; + +static int __init dm_snapshot_init(void) +{ + int r; + + r = dm_register_target(&snapshot_target); + if (r) { + DMERR("snapshot target register failed %d", r); + return r; + } + + r = dm_register_target(&origin_target); + if (r < 0) { + DMERR("Device mapper: Origin: register failed %d\n", r); + goto bad1; + } + + r = init_origin_hash(); + if (r) { + DMERR("init_origin_hash failed."); + goto bad2; + } + + exception_cache = kmem_cache_create("dm-snapshot-ex", + sizeof(struct exception), + __alignof__(struct exception), + 0, NULL, NULL); + if (!exception_cache) { + DMERR("Couldn't create exception cache."); + r = -ENOMEM; + goto bad3; + } + + pending_cache = + kmem_cache_create("dm-snapshot-in", + sizeof(struct pending_exception), + __alignof__(struct pending_exception), + 0, NULL, NULL); + if (!pending_cache) { + DMERR("Couldn't create pending cache."); + r = -ENOMEM; + goto bad4; + } + + pending_pool = mempool_create(128, mempool_alloc_slab, + mempool_free_slab, pending_cache); + if (!pending_pool) { + DMERR("Couldn't create pending pool."); + r = -ENOMEM; + goto bad5; + } + + return 0; + + bad5: + kmem_cache_destroy(pending_cache); + bad4: + kmem_cache_destroy(exception_cache); + bad3: + exit_origin_hash(); + bad2: + dm_unregister_target(&origin_target); + bad1: + dm_unregister_target(&snapshot_target); + return r; +} + +static void __exit dm_snapshot_exit(void) +{ + int r; + + r = dm_unregister_target(&snapshot_target); + if (r) + DMERR("snapshot unregister failed %d", r); + + r = dm_unregister_target(&origin_target); + if (r) + DMERR("origin unregister failed %d", r); + + exit_origin_hash(); + mempool_destroy(pending_pool); + kmem_cache_destroy(pending_cache); + kmem_cache_destroy(exception_cache); +} + +/* Module hooks */ +module_init(dm_snapshot_init); +module_exit(dm_snapshot_exit); + +MODULE_DESCRIPTION(DM_NAME " snapshot target"); +MODULE_AUTHOR("Joe Thornber"); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-snap.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,161 @@ +/* + * dm-snapshot.c + * + * Copyright (C) 2001-2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#ifndef DM_SNAPSHOT_H +#define DM_SNAPSHOT_H + +#include "dm.h" +#include + +struct exception_table { + uint32_t hash_mask; + struct list_head *table; +}; + +/* + * The snapshot code deals with largish chunks of the disk at a + * time. Typically 64k - 256k. + */ +/* FIXME: can we get away with limiting these to a uint32_t ? */ +typedef sector_t chunk_t; + +/* + * An exception is used where an old chunk of data has been + * replaced by a new one. + */ +struct exception { + struct list_head hash_list; + + chunk_t old_chunk; + chunk_t new_chunk; +}; + +/* + * Abstraction to handle the meta/layout of exception stores (the + * COW device). + */ +struct exception_store { + + /* + * Destroys this object when you've finished with it. + */ + void (*destroy) (struct exception_store *store); + + /* + * The target shouldn't read the COW device until this is + * called. + */ + int (*read_metadata) (struct exception_store *store); + + /* + * Find somewhere to store the next exception. + */ + int (*prepare_exception) (struct exception_store *store, + struct exception *e); + + /* + * Update the metadata with this exception. + */ + void (*commit_exception) (struct exception_store *store, + struct exception *e, + void (*callback) (void *, int success), + void *callback_context); + + /* + * The snapshot is invalid, note this in the metadata. + */ + void (*drop_snapshot) (struct exception_store *store); + + /* + * Return how full the snapshot is. + */ + void (*fraction_full) (struct exception_store *store, + sector_t *numerator, + sector_t *denominator); + + struct dm_snapshot *snap; + void *context; +}; + +struct dm_snapshot { + struct rw_semaphore lock; + struct dm_table *table; + + struct dm_dev *origin; + struct dm_dev *cow; + + /* List of snapshots per Origin */ + struct list_head list; + + /* Size of data blocks saved - must be a power of 2 */ + chunk_t chunk_size; + chunk_t chunk_mask; + chunk_t chunk_shift; + + /* You can't use a snapshot if this is 0 (e.g. if full) */ + int valid; + int have_metadata; + + /* Used for display of table */ + char type; + + /* The last percentage we notified */ + int last_percent; + + struct exception_table pending; + struct exception_table complete; + + /* The on disk metadata handler */ + struct exception_store store; + + struct kcopyd_client *kcopyd_client; +}; + +/* + * Used by the exception stores to load exceptions hen + * initialising. + */ +int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new); + +/* + * Constructor and destructor for the default persistent + * store. + */ +int dm_create_persistent(struct exception_store *store, uint32_t chunk_size); + +int dm_create_transient(struct exception_store *store, + struct dm_snapshot *s, int blocksize); + +/* + * Return the number of sectors in the device. + */ +static inline sector_t get_dev_size(struct block_device *bdev) +{ + return bdev->bd_inode->i_size >> SECTOR_SHIFT; +} + +static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector) +{ + return (sector & ~s->chunk_mask) >> s->chunk_shift; +} + +static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk) +{ + return chunk << s->chunk_shift; +} + +static inline int bdev_equal(struct block_device *lhs, struct block_device *rhs) +{ + /* + * There is only ever one instance of a particular block + * device so we can compare pointers safely. + */ + return lhs == rhs; +} + +#endif diff -Nru a/drivers/md/dm-table.c b/drivers/md/dm-table.c --- a/drivers/md/dm-table.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/md/dm-table.c 2004-06-26 17:09:21 -07:00 @@ -400,7 +400,7 @@ struct dm_dev dd_copy; dev_t dev = dd->bdev->bd_dev; - memcpy(&dd_copy, dd, sizeof(dd_copy)); + dd_copy = *dd; dd->mode |= new_mode; dd->bdev = NULL; @@ -408,7 +408,7 @@ if (!r) close_dev(&dd_copy); else - memcpy(dd, &dd_copy, sizeof(dd_copy)); + *dd = dd_copy; return r; } diff -Nru a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/dm-zero.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2003 Christophe Saout + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include +#include +#include + +/* + * Construct a dummy mapping that only returns zeros + */ +static int zero_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + if (argc != 0) { + ti->error = "dm-zero: No arguments required"; + return -EINVAL; + } + + return 0; +} + +/* + * Fills the bio pages with zeros + */ +static void zero_fill_bio(struct bio *bio) +{ + unsigned long flags; + struct bio_vec *bv; + int i; + + bio_for_each_segment(bv, bio, i) { + char *data = bvec_kmap_irq(bv, &flags); + memset(data, 0, bv->bv_len); + flush_dcache_page(bv->bv_page); + bvec_kunmap_irq(data, &flags); + } +} + +/* + * Return zeros only on reads + */ +static int zero_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + switch(bio_rw(bio)) { + case READ: + zero_fill_bio(bio); + break; + case READA: + /* readahead of null bytes only wastes buffer cache */ + return -EIO; + case WRITE: + /* writes get silently dropped */ + break; + } + + bio_endio(bio, bio->bi_size, 0); + + /* accepted bio, don't make new request */ + return 0; +} + +static struct target_type zero_target = { + .name = "zero", + .version = {1, 0, 0}, + .module = THIS_MODULE, + .ctr = zero_ctr, + .map = zero_map, +}; + +int __init dm_zero_init(void) +{ + int r = dm_register_target(&zero_target); + + if (r < 0) + DMERR("zero: register failed %d", r); + + return r; +} + +void __exit dm_zero_exit(void) +{ + int r = dm_unregister_target(&zero_target); + + if (r < 0) + DMERR("zero: unregister failed %d", r); +} + +module_init(dm_zero_init) +module_exit(dm_zero_exit) + +MODULE_AUTHOR("Christophe Saout "); +MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros"); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/md/dm.c b/drivers/md/dm.c --- a/drivers/md/dm.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/md/dm.c 2004-06-26 17:09:19 -07:00 @@ -394,7 +394,7 @@ struct bio_vec *bv = bio->bi_io_vec + idx; clone = bio_alloc(GFP_NOIO, 1); - memcpy(clone->bi_io_vec, bv, sizeof(*bv)); + *clone->bi_io_vec = *bv; clone->bi_sector = sector; clone->bi_bdev = bio->bi_bdev; diff -Nru a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/kcopyd.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + * + * Kcopyd provides a simple interface for copying an area of one + * block-device to one or more other block-devices, with an asynchronous + * completion notification. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcopyd.h" + +/* FIXME: this is only needed for the DMERR macros */ +#include "dm.h" + +static struct workqueue_struct *_kcopyd_wq; +static struct work_struct _kcopyd_work; + +static inline void wake(void) +{ + queue_work(_kcopyd_wq, &_kcopyd_work); +} + +/*----------------------------------------------------------------- + * Each kcopyd client has its own little pool of preallocated + * pages for kcopyd io. + *---------------------------------------------------------------*/ +struct kcopyd_client { + struct list_head list; + + spinlock_t lock; + struct page_list *pages; + unsigned int nr_pages; + unsigned int nr_free_pages; +}; + +static struct page_list *alloc_pl(void) +{ + struct page_list *pl; + + pl = kmalloc(sizeof(*pl), GFP_KERNEL); + if (!pl) + return NULL; + + pl->page = alloc_page(GFP_KERNEL); + if (!pl->page) { + kfree(pl); + return NULL; + } + + return pl; +} + +static void free_pl(struct page_list *pl) +{ + __free_page(pl->page); + kfree(pl); +} + +static int kcopyd_get_pages(struct kcopyd_client *kc, + unsigned int nr, struct page_list **pages) +{ + struct page_list *pl; + + spin_lock(&kc->lock); + if (kc->nr_free_pages < nr) { + spin_unlock(&kc->lock); + return -ENOMEM; + } + + kc->nr_free_pages -= nr; + for (*pages = pl = kc->pages; --nr; pl = pl->next) + ; + + kc->pages = pl->next; + pl->next = 0; + + spin_unlock(&kc->lock); + + return 0; +} + +static void kcopyd_put_pages(struct kcopyd_client *kc, struct page_list *pl) +{ + struct page_list *cursor; + + spin_lock(&kc->lock); + for (cursor = pl; cursor->next; cursor = cursor->next) + kc->nr_free_pages++; + + kc->nr_free_pages++; + cursor->next = kc->pages; + kc->pages = pl; + spin_unlock(&kc->lock); +} + +/* + * These three functions resize the page pool. + */ +static void drop_pages(struct page_list *pl) +{ + struct page_list *next; + + while (pl) { + next = pl->next; + free_pl(pl); + pl = next; + } +} + +static int client_alloc_pages(struct kcopyd_client *kc, unsigned int nr) +{ + unsigned int i; + struct page_list *pl = NULL, *next; + + for (i = 0; i < nr; i++) { + next = alloc_pl(); + if (!next) { + if (pl) + drop_pages(pl); + return -ENOMEM; + } + next->next = pl; + pl = next; + } + + kcopyd_put_pages(kc, pl); + kc->nr_pages += nr; + return 0; +} + +static void client_free_pages(struct kcopyd_client *kc) +{ + BUG_ON(kc->nr_free_pages != kc->nr_pages); + drop_pages(kc->pages); + kc->pages = NULL; + kc->nr_free_pages = kc->nr_pages = 0; +} + +/*----------------------------------------------------------------- + * kcopyd_jobs need to be allocated by the *clients* of kcopyd, + * for this reason we use a mempool to prevent the client from + * ever having to do io (which could cause a deadlock). + *---------------------------------------------------------------*/ +struct kcopyd_job { + struct kcopyd_client *kc; + struct list_head list; + unsigned long flags; + + /* + * Error state of the job. + */ + int read_err; + unsigned int write_err; + + /* + * Either READ or WRITE + */ + int rw; + struct io_region source; + + /* + * The destinations for the transfer. + */ + unsigned int num_dests; + struct io_region dests[KCOPYD_MAX_REGIONS]; + + sector_t offset; + unsigned int nr_pages; + struct page_list *pages; + + /* + * Set this to ensure you are notified when the job has + * completed. 'context' is for callback to use. + */ + kcopyd_notify_fn fn; + void *context; + + /* + * These fields are only used if the job has been split + * into more manageable parts. + */ + struct semaphore lock; + atomic_t sub_jobs; + sector_t progress; +}; + +/* FIXME: this should scale with the number of pages */ +#define MIN_JOBS 512 + +static kmem_cache_t *_job_cache; +static mempool_t *_job_pool; + +/* + * We maintain three lists of jobs: + * + * i) jobs waiting for pages + * ii) jobs that have pages, and are waiting for the io to be issued. + * iii) jobs that have completed. + * + * All three of these are protected by job_lock. + */ +static spinlock_t _job_lock = SPIN_LOCK_UNLOCKED; + +static LIST_HEAD(_complete_jobs); +static LIST_HEAD(_io_jobs); +static LIST_HEAD(_pages_jobs); + +static int jobs_init(void) +{ + _job_cache = kmem_cache_create("kcopyd-jobs", + sizeof(struct kcopyd_job), + __alignof__(struct kcopyd_job), + 0, NULL, NULL); + if (!_job_cache) + return -ENOMEM; + + _job_pool = mempool_create(MIN_JOBS, mempool_alloc_slab, + mempool_free_slab, _job_cache); + if (!_job_pool) { + kmem_cache_destroy(_job_cache); + return -ENOMEM; + } + + return 0; +} + +static void jobs_exit(void) +{ + BUG_ON(!list_empty(&_complete_jobs)); + BUG_ON(!list_empty(&_io_jobs)); + BUG_ON(!list_empty(&_pages_jobs)); + + mempool_destroy(_job_pool); + kmem_cache_destroy(_job_cache); + _job_pool = NULL; + _job_cache = NULL; +} + +/* + * Functions to push and pop a job onto the head of a given job + * list. + */ +static inline struct kcopyd_job *pop(struct list_head *jobs) +{ + struct kcopyd_job *job = NULL; + unsigned long flags; + + spin_lock_irqsave(&_job_lock, flags); + + if (!list_empty(jobs)) { + job = list_entry(jobs->next, struct kcopyd_job, list); + list_del(&job->list); + } + spin_unlock_irqrestore(&_job_lock, flags); + + return job; +} + +static inline void push(struct list_head *jobs, struct kcopyd_job *job) +{ + unsigned long flags; + + spin_lock_irqsave(&_job_lock, flags); + list_add_tail(&job->list, jobs); + spin_unlock_irqrestore(&_job_lock, flags); +} + +/* + * These three functions process 1 item from the corresponding + * job list. + * + * They return: + * < 0: error + * 0: success + * > 0: can't process yet. + */ +static int run_complete_job(struct kcopyd_job *job) +{ + void *context = job->context; + int read_err = job->read_err; + unsigned int write_err = job->write_err; + kcopyd_notify_fn fn = job->fn; + + kcopyd_put_pages(job->kc, job->pages); + mempool_free(job, _job_pool); + fn(read_err, write_err, context); + return 0; +} + +static void complete_io(unsigned long error, void *context) +{ + struct kcopyd_job *job = (struct kcopyd_job *) context; + + if (error) { + if (job->rw == WRITE) + job->write_err &= error; + else + job->read_err = 1; + + if (!test_bit(KCOPYD_IGNORE_ERROR, &job->flags)) { + push(&_complete_jobs, job); + wake(); + return; + } + } + + if (job->rw == WRITE) + push(&_complete_jobs, job); + + else { + job->rw = WRITE; + push(&_io_jobs, job); + } + + wake(); +} + +/* + * Request io on as many buffer heads as we can currently get for + * a particular job. + */ +static int run_io_job(struct kcopyd_job *job) +{ + int r; + + if (job->rw == READ) + r = dm_io_async(1, &job->source, job->rw, + job->pages, + job->offset, complete_io, job); + + else + r = dm_io_async(job->num_dests, job->dests, job->rw, + job->pages, + job->offset, complete_io, job); + + return r; +} + +static int run_pages_job(struct kcopyd_job *job) +{ + int r; + + job->nr_pages = dm_div_up(job->dests[0].count + job->offset, + PAGE_SIZE >> 9); + r = kcopyd_get_pages(job->kc, job->nr_pages, &job->pages); + if (!r) { + /* this job is ready for io */ + push(&_io_jobs, job); + return 0; + } + + if (r == -ENOMEM) + /* can't complete now */ + return 1; + + return r; +} + +/* + * Run through a list for as long as possible. Returns the count + * of successful jobs. + */ +static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) +{ + struct kcopyd_job *job; + int r, count = 0; + + while ((job = pop(jobs))) { + + r = fn(job); + + if (r < 0) { + /* error this rogue job */ + if (job->rw == WRITE) + job->write_err = (unsigned int) -1; + else + job->read_err = 1; + push(&_complete_jobs, job); + break; + } + + if (r > 0) { + /* + * We couldn't service this job ATM, so + * push this job back onto the list. + */ + push(jobs, job); + break; + } + + count++; + } + + return count; +} + +/* + * kcopyd does this every time it's woken up. + */ +static void do_work(void *ignored) +{ + /* + * The order that these are called is *very* important. + * complete jobs can free some pages for pages jobs. + * Pages jobs when successful will jump onto the io jobs + * list. io jobs call wake when they complete and it all + * starts again. + */ + process_jobs(&_complete_jobs, run_complete_job); + process_jobs(&_pages_jobs, run_pages_job); + process_jobs(&_io_jobs, run_io_job); +} + +/* + * If we are copying a small region we just dispatch a single job + * to do the copy, otherwise the io has to be split up into many + * jobs. + */ +static void dispatch_job(struct kcopyd_job *job) +{ + push(&_pages_jobs, job); + wake(); +} + +#define SUB_JOB_SIZE 128 +static void segment_complete(int read_err, + unsigned int write_err, void *context) +{ + /* FIXME: tidy this function */ + sector_t progress = 0; + sector_t count = 0; + struct kcopyd_job *job = (struct kcopyd_job *) context; + + down(&job->lock); + + /* update the error */ + if (read_err) + job->read_err = 1; + + if (write_err) + job->write_err &= write_err; + + /* + * Only dispatch more work if there hasn't been an error. + */ + if ((!job->read_err && !job->write_err) || + test_bit(KCOPYD_IGNORE_ERROR, &job->flags)) { + /* get the next chunk of work */ + progress = job->progress; + count = job->source.count - progress; + if (count) { + if (count > SUB_JOB_SIZE) + count = SUB_JOB_SIZE; + + job->progress += count; + } + } + up(&job->lock); + + if (count) { + int i; + struct kcopyd_job *sub_job = mempool_alloc(_job_pool, GFP_NOIO); + + *sub_job = *job; + sub_job->source.sector += progress; + sub_job->source.count = count; + + for (i = 0; i < job->num_dests; i++) { + sub_job->dests[i].sector += progress; + sub_job->dests[i].count = count; + } + + sub_job->fn = segment_complete; + sub_job->context = job; + dispatch_job(sub_job); + + } else if (atomic_dec_and_test(&job->sub_jobs)) { + + /* + * To avoid a race we must keep the job around + * until after the notify function has completed. + * Otherwise the client may try and stop the job + * after we've completed. + */ + job->fn(read_err, write_err, job->context); + mempool_free(job, _job_pool); + } +} + +/* + * Create some little jobs that will do the move between + * them. + */ +#define SPLIT_COUNT 8 +static void split_job(struct kcopyd_job *job) +{ + int i; + + atomic_set(&job->sub_jobs, SPLIT_COUNT); + for (i = 0; i < SPLIT_COUNT; i++) + segment_complete(0, 0u, job); +} + +int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, + unsigned int num_dests, struct io_region *dests, + unsigned int flags, kcopyd_notify_fn fn, void *context) +{ + struct kcopyd_job *job; + + /* + * Allocate a new job. + */ + job = mempool_alloc(_job_pool, GFP_NOIO); + + /* + * set up for the read. + */ + job->kc = kc; + job->flags = flags; + job->read_err = 0; + job->write_err = 0; + job->rw = READ; + + job->source = *from; + + job->num_dests = num_dests; + memcpy(&job->dests, dests, sizeof(*dests) * num_dests); + + job->offset = 0; + job->nr_pages = 0; + job->pages = NULL; + + job->fn = fn; + job->context = context; + + if (job->source.count < SUB_JOB_SIZE) + dispatch_job(job); + + else { + init_MUTEX(&job->lock); + job->progress = 0; + split_job(job); + } + + return 0; +} + +/* + * Cancels a kcopyd job, eg. someone might be deactivating a + * mirror. + */ +int kcopyd_cancel(struct kcopyd_job *job, int block) +{ + /* FIXME: finish */ + return -1; +} + +/*----------------------------------------------------------------- + * Unit setup + *---------------------------------------------------------------*/ +static DECLARE_MUTEX(_client_lock); +static LIST_HEAD(_clients); + +static int client_add(struct kcopyd_client *kc) +{ + down(&_client_lock); + list_add(&kc->list, &_clients); + up(&_client_lock); + return 0; +} + +static void client_del(struct kcopyd_client *kc) +{ + down(&_client_lock); + list_del(&kc->list); + up(&_client_lock); +} + +static DECLARE_MUTEX(kcopyd_init_lock); +static int kcopyd_clients = 0; + +static int kcopyd_init(void) +{ + int r; + + down(&kcopyd_init_lock); + + if (kcopyd_clients) { + /* Already initialized. */ + kcopyd_clients++; + up(&kcopyd_init_lock); + return 0; + } + + r = jobs_init(); + if (r) { + up(&kcopyd_init_lock); + return r; + } + + _kcopyd_wq = create_singlethread_workqueue("kcopyd"); + if (!_kcopyd_wq) { + jobs_exit(); + up(&kcopyd_init_lock); + return -ENOMEM; + } + + kcopyd_clients++; + INIT_WORK(&_kcopyd_work, do_work, NULL); + up(&kcopyd_init_lock); + return 0; +} + +static void kcopyd_exit(void) +{ + down(&kcopyd_init_lock); + kcopyd_clients--; + if (!kcopyd_clients) { + jobs_exit(); + destroy_workqueue(_kcopyd_wq); + _kcopyd_wq = NULL; + } + up(&kcopyd_init_lock); +} + +int kcopyd_client_create(unsigned int nr_pages, struct kcopyd_client **result) +{ + int r = 0; + struct kcopyd_client *kc; + + r = kcopyd_init(); + if (r) + return r; + + kc = kmalloc(sizeof(*kc), GFP_KERNEL); + if (!kc) { + kcopyd_exit(); + return -ENOMEM; + } + + kc->lock = SPIN_LOCK_UNLOCKED; + kc->pages = NULL; + kc->nr_pages = kc->nr_free_pages = 0; + r = client_alloc_pages(kc, nr_pages); + if (r) { + kfree(kc); + kcopyd_exit(); + return r; + } + + r = dm_io_get(nr_pages); + if (r) { + client_free_pages(kc); + kfree(kc); + kcopyd_exit(); + return r; + } + + r = client_add(kc); + if (r) { + dm_io_put(nr_pages); + client_free_pages(kc); + kfree(kc); + kcopyd_exit(); + return r; + } + + *result = kc; + return 0; +} + +void kcopyd_client_destroy(struct kcopyd_client *kc) +{ + dm_io_put(kc->nr_pages); + client_free_pages(kc); + client_del(kc); + kfree(kc); + kcopyd_exit(); +} + +EXPORT_SYMBOL(kcopyd_client_create); +EXPORT_SYMBOL(kcopyd_client_destroy); +EXPORT_SYMBOL(kcopyd_copy); +EXPORT_SYMBOL(kcopyd_cancel); diff -Nru a/drivers/md/kcopyd.h b/drivers/md/kcopyd.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/md/kcopyd.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2001 Sistina Software + * + * This file is released under the GPL. + * + * Kcopyd provides a simple interface for copying an area of one + * block-device to one or more other block-devices, with an asynchronous + * completion notification. + */ + +#ifndef DM_KCOPYD_H +#define DM_KCOPYD_H + +#include "dm-io.h" + +/* FIXME: make this configurable */ +#define KCOPYD_MAX_REGIONS 8 + +#define KCOPYD_IGNORE_ERROR 1 + +/* + * To use kcopyd you must first create a kcopyd client object. + */ +struct kcopyd_client; +int kcopyd_client_create(unsigned int num_pages, struct kcopyd_client **result); +void kcopyd_client_destroy(struct kcopyd_client *kc); + +/* + * Submit a copy job to kcopyd. This is built on top of the + * previous three fns. + * + * read_err is a boolean, + * write_err is a bitset, with 1 bit for each destination region + */ +typedef void (*kcopyd_notify_fn)(int read_err, + unsigned int write_err, void *context); + +int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, + unsigned int num_dests, struct io_region *dests, + unsigned int flags, kcopyd_notify_fn fn, void *context); + +#endif diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c --- a/drivers/md/raid1.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/md/raid1.c 2004-06-26 17:09:18 -07:00 @@ -206,7 +206,7 @@ *rdevp = rdev; atomic_inc(&rdev->nr_pending); spin_unlock_irq(&conf->device_lock); - return 0; + return i; } } spin_unlock_irq(&conf->device_lock); @@ -376,7 +376,8 @@ * device if no resync is going on, or below the resync window. * We take the first readable disk when above the resync window. */ - if (!conf->mddev->in_sync && (this_sector + sectors >= conf->next_resync)) { + if (conf->mddev->recovery_cp < MaxSector && + (this_sector + sectors >= conf->next_resync)) { /* make sure that disk is operational */ new_disk = 0; @@ -918,18 +919,22 @@ mddev = r1_bio->mddev; conf = mddev_to_conf(mddev); - bio = r1_bio->master_bio; if (test_bit(R1BIO_IsSync, &r1_bio->state)) { sync_request_write(mddev, r1_bio); unplug = 1; } else { - if (map(mddev, &rdev) == -1) { + int disk; + bio = r1_bio->bios[r1_bio->read_disk]; + if ((disk=map(mddev, &rdev)) == -1) { printk(KERN_ALERT "raid1: %s: unrecoverable I/O" " read error for block %llu\n", bdevname(bio->bi_bdev,b), (unsigned long long)r1_bio->sector); raid_end_bio_io(r1_bio); } else { + r1_bio->bios[r1_bio->read_disk] = NULL; + r1_bio->read_disk = disk; + r1_bio->bios[r1_bio->read_disk] = bio; printk(KERN_ERR "raid1: %s: redirecting sector %llu to" " another mirror\n", bdevname(rdev->bdev,b), diff -Nru a/drivers/md/xor.c b/drivers/md/xor.c --- a/drivers/md/xor.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/md/xor.c 2004-06-26 17:09:18 -07:00 @@ -108,29 +108,40 @@ } b2 = b1 + 2*PAGE_SIZE + BENCH_SIZE; - printk(KERN_INFO "raid5: measuring checksumming speed\n"); + /* + * If this arch/cpu has a short-circuited selection, don't loop through all + * the possible functions, just test the best one + */ + + fastest = NULL; + +#ifdef XOR_SELECT_TEMPLATE + fastest = XOR_SELECT_TEMPLATE(fastest); +#endif #define xor_speed(templ) do_xor_speed((templ), b1, b2) - XOR_TRY_TEMPLATES; + if (fastest) { + printk(KERN_INFO "raid5: automatically using best checksumming function: %s\n", + fastest->name); + xor_speed(fastest); + } else { + printk(KERN_INFO "raid5: measuring checksumming speed\n"); + XOR_TRY_TEMPLATES; + fastest = template_list; + for (f = fastest; f; f = f->next) + if (f->speed > fastest->speed) + fastest = f; + } + + printk("raid5: using function: %s (%d.%03d MB/sec)\n", + fastest->name, fastest->speed / 1000, fastest->speed % 1000); #undef xor_speed free_pages((unsigned long)b1, 2); - fastest = template_list; - for (f = fastest; f; f = f->next) - if (f->speed > fastest->speed) - fastest = f; - -#ifdef XOR_SELECT_TEMPLATE - fastest = XOR_SELECT_TEMPLATE(fastest); -#endif - active_template = fastest; - printk("raid5: using function: %s (%d.%03d MB/sec)\n", - fastest->name, fastest->speed / 1000, fastest->speed % 1000); - return 0; } diff -Nru a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c --- a/drivers/media/common/ir-common.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/media/common/ir-common.c 2004-06-26 17:09:19 -07:00 @@ -75,6 +75,8 @@ [ 0x35 ] = KEY_PLAY, // play [ 0x36 ] = KEY_STOP, // stop [ 0x37 ] = KEY_RECORD, // recording + [ 0x3c ] = KEY_TEXT, // teletext submode (Japan: 12) + [ 0x3d ] = KEY_SUSPEND, // system standby #if 0 /* FIXME */ [ 0x0a ] = KEY_RESERVED, // 1/2/3 digits (japan: 10) @@ -106,8 +108,6 @@ [ 0x39 ] = KEY_RESERVED, // external 2 [ 0x3a ] = KEY_RESERVED, // PIP display mode [ 0x3b ] = KEY_RESERVED, // view data mode / advance - [ 0x3c ] = KEY_RESERVED, // teletext submode (Japan: 12) - [ 0x3d ] = KEY_RESERVED, // system standby [ 0x3e ] = KEY_RESERVED, // crispener on/off [ 0x3f ] = KEY_RESERVED, // system select #endif diff -Nru a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c --- a/drivers/media/radio/radio-zoltrix.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/media/radio/radio-zoltrix.c 2004-06-26 17:09:21 -07:00 @@ -273,7 +273,7 @@ case VIDIOCGAUDIO: { struct video_audio *v = arg; - memset(&v, 0, sizeof(*v)); + memset(v, 0, sizeof(*v)); v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; v->mode |= zol_is_stereo(zol) ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; diff -Nru a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig --- a/drivers/media/video/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/media/video/Kconfig 2004-06-26 17:09:20 -07:00 @@ -295,5 +295,16 @@ To compile this driver as a module, choose M here: the module will be called cx8800 +config VIDEO_OVCAMCHIP + tristate "OmniVision Camera Chip support" + depends on VIDEO_DEV && I2C + ---help--- + Support for the OmniVision OV6xxx and OV7xxx series of camera chips. + This driver is intended to be used with the ov511 and w9968cf USB + camera drivers. + + To compile this driver as a module, choose M here: the + module will be called ovcamchip + endmenu diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile --- a/drivers/media/video/Makefile 2004-06-26 17:09:17 -07:00 +++ b/drivers/media/video/Makefile 2004-06-26 17:09:17 -07:00 @@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ obj-$(CONFIG_VIDEO_CX88) += cx88/ +obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c --- a/drivers/media/video/bttv-cards.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/media/video/bttv-cards.c 2004-06-26 17:09:18 -07:00 @@ -71,6 +71,9 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input); +static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input); +static void picolo_tetra_init(struct bttv *btv); + static int terratec_active_radio_upgrade(struct bttv *btv); static int tea5757_read(struct bttv *btv); static int tea5757_write(struct bttv *btv, int value); @@ -181,6 +184,7 @@ { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, + { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, @@ -260,12 +264,15 @@ { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, - { 0x010115cb, BTTV_GMV1, "AG GMV1" }, - { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, + { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" }, + + { 0x010115cb, BTTV_GMV1, "AG GMV1" }, + { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, + { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" }, { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, @@ -280,14 +287,21 @@ { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" }, + { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, + { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, + { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, + { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, + // likely broken, vendor id doesn't match the other magic views ... //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, // DVB cards (using pci function .1 for mpeg data xfer) { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, + { 0x07611461, BTTV_NEBULA_DIGITV, "AverMedia AverTV DVB-T" }, { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB-T" }, { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, + { 0x07711461, BTTV_AVDVBT_771, "AVermedia DVB-T 771" }, { 0, -1, NULL } }; @@ -835,7 +849,7 @@ .svhs = 2, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 1}, - .audiomux = { 2, 0, 0, 0, 1}, + .audiomux = { 2, 0xd0001, 0, 0, 1}, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = -1, @@ -1646,6 +1660,7 @@ .muxsel = { 3, 0, 1, 2}, .needs_tvaudio = 0, .pll = PLL_28, + .no_gpioirq = 1, },{ .name = "Formac ProTV II (bt878)", .video_inputs = 4, @@ -2012,6 +2027,57 @@ .tuner_type = TUNER_PHILIPS_PAL, .has_remote = 1, .has_radio = 1, +},{ + /*Eric DEBIEF */ + /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ + /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/ + /*0x79 in bttv.h*/ + .name = "Euresys Picolo Tetra", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .gpiomask = 0, + .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ + .pll = PLL_28, + .needs_tvaudio = 0, + .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ +},{ + /* Spirit TV Tuner from http://spiritmodems.com.au */ + /* Stafford Goodsell */ + .name = "Spirit TV Tuner", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x0000000f, + .muxsel = { 2, 1, 1 }, + .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, + .tuner_type = TUNER_TEMIC_PAL, + .no_msp34xx = 1, + .no_tda9875 = 1, +},{ + /* Wolfram Joost */ + .name = "AVerMedia AVerTV DVB-T 771", + .video_inputs = 2, + .svhs = 1, + .tuner = -1, + .tuner_type = TUNER_ABSENT, + .muxsel = { 3 , 3 }, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .pll = PLL_28, + .has_dvb = 1, + .no_gpioirq = 1, +#if 0 /* untested */ + .has_remote = 1, +#endif }}; const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -2381,6 +2447,7 @@ pvr_boot(btv); break; case BTTV_TWINHAN_DST: + case BTTV_AVDVBT_771: btv->use_i2c_hw = 1; break; } @@ -2432,6 +2499,9 @@ case BTTV_PXC200: init_PXC200(btv); break; + case BTTV_PICOLO_TETRA_CHIP: + picolo_tetra_init(btv); + break; case BTTV_VHX: btv->has_radio = 1; btv->has_matchbox = 1; @@ -2668,6 +2738,10 @@ btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", btv->c.nr,&eeprom_data[0x1e]); + } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { + btv->tuner_type=TUNER_PHILIPS_NTSC; + printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", + btv->c.nr,&eeprom_data[0x1e]); } else { printk("bttv%d: Modtec: Unknown TunerString: %s\n", btv->c.nr,&eeprom_data[0x1e]); @@ -3785,6 +3859,21 @@ ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, }; gpio_write(masks[input%16]); +} +static void picolo_tetra_init(struct bttv *btv) +{ + /*This is the video input redirection fonctionality : I DID NOT USED IT. */ + btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */ + btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A] set to 1*/ +} +static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input) +{ + + dprintk (KERN_DEBUG "bttv%d : picolo_tetra_muxsel => input = %d\n",btv->c.nr,input); + /*Just set the right path in the analog multiplexers : channel 1 -> 4 ==> Analog Mux ==> MUX0*/ + /*GPIO[20]&GPIO[21] used to choose the right input*/ + btwrite (input<<20,BT848_GPIO_DATA); + } /* diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c --- a/drivers/media/video/bttv-driver.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/media/video/bttv-driver.c 2004-06-26 17:09:19 -07:00 @@ -1334,7 +1334,8 @@ spin_lock_irqsave(&btv->s_lock,flags); old = btv->screen; btv->screen = new; - bttv_set_dma(btv, 0x03, 1); + btv->curr.irqflags |= 1; + bttv_set_dma(btv, 0x03, btv->curr.irqflags); spin_unlock_irqrestore(&btv->s_lock,flags); if (NULL == new) free_btres(btv,fh,RESOURCE_OVERLAY); @@ -1441,7 +1442,8 @@ buf->vb.state = STATE_QUEUED; list_add_tail(&buf->vb.queue,&fh->btv->capture); - bttv_set_dma(fh->btv, 0x03, 1); + fh->btv->curr.irqflags |= 1; + bttv_set_dma(fh->btv, 0x03, fh->btv->curr.irqflags); } static void buffer_release(struct file *file, struct videobuf_buffer *vb) @@ -3203,8 +3205,8 @@ printk(" main: %08Lx\n", (unsigned long long)btv->main.dma); printk(" vbi : o=%08Lx e=%08Lx\n", - btv->curr.vbi ? (unsigned long long)btv->curr.vbi->top.dma : 0, - btv->curr.vbi ? (unsigned long long)btv->curr.vbi->bottom.dma : 0); + btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, + btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0); printk(" cap : o=%08Lx e=%08Lx\n", btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); @@ -3224,7 +3226,7 @@ if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) { printk("bttv%d: Oh, there (temporarely?) is no input signal. " - "Ok, then this is harmless, don't worry ;)", + "Ok, then this is harmless, don't worry ;)\n", btv->c.nr); return; } @@ -3236,18 +3238,12 @@ } static int -bttv_irq_next_set(struct bttv *btv, struct bttv_buffer_set *set) +bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) { struct bttv_buffer *item; memset(set,0,sizeof(*set)); - /* vbi request ? */ - if (!list_empty(&btv->vcapture)) { - set->irqflags = 1; - set->vbi = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); - } - /* capture request ? */ if (!list_empty(&btv->capture)) { set->irqflags = 1; @@ -3295,27 +3291,20 @@ } } - dprintk("bttv%d: next set: top=%p bottom=%p vbi=%p " - "[screen=%p,irq=%d,%d]\n", - btv->c.nr,set->top, set->bottom, set->vbi, + dprintk("bttv%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n", + btv->c.nr,set->top, set->bottom, btv->screen,set->irqflags,set->topirq); return 0; } static void -bttv_irq_wakeup_set(struct bttv *btv, struct bttv_buffer_set *wakeup, - struct bttv_buffer_set *curr, unsigned int state) +bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup, + struct bttv_buffer_set *curr, unsigned int state) { struct timeval ts; do_gettimeofday(&ts); - if (NULL != wakeup->vbi) { - wakeup->vbi->vb.ts = ts; - wakeup->vbi->vb.field_count = btv->field_count; - wakeup->vbi->vb.state = state; - wake_up(&wakeup->vbi->vb.done); - } if (wakeup->top == wakeup->bottom) { if (NULL != wakeup->top && curr->top != wakeup->top) { if (irq_debug > 1) @@ -3345,10 +3334,27 @@ } } +static void +bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup, + unsigned int state) +{ + struct timeval ts; + + if (NULL == wakeup) + return; + + do_gettimeofday(&ts); + wakeup->vb.ts = ts; + wakeup->vb.field_count = btv->field_count; + wakeup->vb.state = state; + wake_up(&wakeup->vb.done); +} + static void bttv_irq_timeout(unsigned long data) { struct bttv *btv = (struct bttv *)data; struct bttv_buffer_set old,new; + struct bttv_buffer *ovbi; struct bttv_buffer *item; unsigned long flags; @@ -3364,13 +3370,17 @@ /* deactivate stuff */ memset(&new,0,sizeof(new)); - old = btv->curr; + old = btv->curr; + ovbi = btv->cvbi; btv->curr = new; - bttv_buffer_set_activate(btv, &new); + btv->cvbi = NULL; + bttv_buffer_activate_video(btv, &new); + bttv_buffer_activate_vbi(btv, NULL); bttv_set_dma(btv, 0, 0); /* wake up */ - bttv_irq_wakeup_set(btv, &old, &new, STATE_ERROR); + bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR); + bttv_irq_wakeup_vbi(btv, ovbi, STATE_ERROR); /* cancel all outstanding capture / vbi requests */ while (!list_empty(&btv->capture)) { @@ -3410,8 +3420,17 @@ spin_unlock(&btv->s_lock); } +static inline int is_active(struct btcx_riscmem *risc, u32 rc) +{ + if (rc < risc->dma) + return 0; + if (rc > risc->dma + risc->size) + return 0; + return 1; +} + static void -bttv_irq_switch_fields(struct bttv *btv) +bttv_irq_switch_video(struct bttv *btv) { struct bttv_buffer_set new; struct bttv_buffer_set old; @@ -3420,9 +3439,10 @@ spin_lock(&btv->s_lock); /* new buffer set */ - bttv_irq_next_set(btv, &new); + bttv_irq_next_video(btv, &new); rc = btread(BT848_RISC_COUNT); - if (rc < btv->main.dma || rc > btv->main.dma + 0x100) { + if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) || + (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) { btv->framedrop++; if (debug_latency) bttv_irq_debug_low_latency(btv, rc); @@ -3433,7 +3453,7 @@ /* switch over */ old = btv->curr; btv->curr = new; - bttv_buffer_set_activate(btv, &new); + bttv_buffer_activate_video(btv, &new); bttv_set_dma(btv, 0, new.irqflags); /* switch input */ @@ -3443,7 +3463,39 @@ } /* wake up finished buffers */ - bttv_irq_wakeup_set(btv, &old, &new, STATE_DONE); + bttv_irq_wakeup_video(btv, &old, &new, STATE_DONE); + spin_unlock(&btv->s_lock); +} + +static void +bttv_irq_switch_vbi(struct bttv *btv) +{ + struct bttv_buffer *new = NULL; + struct bttv_buffer *old; + u32 rc; + + spin_lock(&btv->s_lock); + + if (!list_empty(&btv->vcapture)) + new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); + old = btv->cvbi; + + rc = btread(BT848_RISC_COUNT); + if (NULL != old && (is_active(&old->top, rc) || + is_active(&old->bottom, rc))) { + btv->framedrop++; + if (debug_latency) + bttv_irq_debug_low_latency(btv, rc); + spin_unlock(&btv->s_lock); + return; + } + + /* switch */ + btv->cvbi = new; + bttv_buffer_activate_vbi(btv, new); + bttv_set_dma(btv, 0, btv->curr.irqflags); + + bttv_irq_wakeup_vbi(btv, old, STATE_DONE); spin_unlock(&btv->s_lock); } @@ -3500,11 +3552,14 @@ wake_up(&btv->i2c_queue); } + if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) + bttv_irq_switch_vbi(btv); + if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) bttv_irq_wakeup_top(btv); if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) - bttv_irq_switch_fields(btv); + bttv_irq_switch_video(btv); if ((astat & BT848_INT_HLOCK) && btv->opt_automute) audio_mux(btv, -1); @@ -3872,9 +3927,11 @@ /* stop dma + irqs */ spin_lock_irqsave(&btv->s_lock,flags); memset(&idle, 0, sizeof(idle)); - btv->state.set = btv->curr; + btv->state.video = btv->curr; + btv->state.vbi = btv->cvbi; btv->curr = idle; - bttv_buffer_set_activate(btv, &idle); + bttv_buffer_activate_video(btv, &idle); + bttv_buffer_activate_vbi(btv, NULL); bttv_set_dma(btv, 0, 0); btwrite(0, BT848_INT_MASK); spin_unlock_irqrestore(&btv->s_lock,flags); @@ -3914,8 +3971,10 @@ /* restart dma */ spin_lock_irqsave(&btv->s_lock,flags); - btv->curr = btv->state.set; - bttv_buffer_set_activate(btv, &btv->curr); + btv->curr = btv->state.video; + btv->cvbi = btv->state.vbi; + bttv_buffer_activate_video(btv, &btv->curr); + bttv_buffer_activate_vbi(btv, btv->cvbi); bttv_set_dma(btv, 0, btv->curr.irqflags); spin_unlock_irqrestore(&btv->s_lock,flags); return 0; diff -Nru a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c --- a/drivers/media/video/bttv-risc.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/media/video/bttv-risc.c 2004-06-26 17:09:18 -07:00 @@ -379,7 +379,7 @@ btv->cap_ctl = 0; if (NULL != btv->curr.top) btv->cap_ctl |= 0x02; if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01; - if (NULL != btv->curr.vbi) btv->cap_ctl |= 0x0c; + if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c; capctl = 0; capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */ @@ -389,9 +389,9 @@ d2printk(KERN_DEBUG "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n", btv->c.nr,capctl,irqflags, - btv->curr.vbi ? (unsigned long long)btv->curr.vbi->top.dma : 0, + btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, - btv->curr.vbi ? (unsigned long long)btv->curr.vbi->bottom.dma : 0, + btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0, btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); cmd = BT848_RISC_JUMP; @@ -399,6 +399,8 @@ cmd |= BT848_RISC_IRQ; cmd |= (irqflags & 0x0f) << 16; cmd |= (~irqflags & 0x0f) << 20; + } + if (irqflags || btv->cvbi) { mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT); } else { del_timer(&btv->timeout); @@ -501,20 +503,26 @@ } int -bttv_buffer_set_activate(struct bttv *btv, - struct bttv_buffer_set *set) +bttv_buffer_activate_vbi(struct bttv *btv, + struct bttv_buffer *vbi) { /* vbi capture */ - if (set->vbi) { - set->vbi->vb.state = STATE_ACTIVE; - list_del(&set->vbi->vb.queue); - bttv_risc_hook(btv, RISC_SLOT_O_VBI, &set->vbi->top, 0); - bttv_risc_hook(btv, RISC_SLOT_E_VBI, &set->vbi->bottom, 0); + if (vbi) { + vbi->vb.state = STATE_ACTIVE; + list_del(&vbi->vb.queue); + bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0); + bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4); } else { bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0); bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0); } + return 0; +} +int +bttv_buffer_activate_video(struct bttv *btv, + struct bttv_buffer_set *set) +{ /* video capture */ if (NULL != set->top && NULL != set->bottom) { if (set->top == set->bottom) { diff -Nru a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c --- a/drivers/media/video/bttv-vbi.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/media/video/bttv-vbi.c 2004-06-26 17:09:19 -07:00 @@ -114,7 +114,10 @@ dprintk("queue %p\n",vb); buf->vb.state = STATE_QUEUED; list_add_tail(&buf->vb.queue,&btv->vcapture); - bttv_set_dma(btv,0x0c,1); + if (NULL == btv->cvbi) { + fh->btv->curr.irqflags |= 4; + bttv_set_dma(btv,0x0c,fh->btv->curr.irqflags); + } } static void vbi_buffer_release(struct file *file, struct videobuf_buffer *vb) diff -Nru a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h --- a/drivers/media/video/bttv.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/media/video/bttv.h 2004-06-26 17:09:15 -07:00 @@ -124,6 +124,8 @@ #define BTTV_SIMUS_GVC1100 0x74 #define BTTV_NGSTV_PLUS 0x75 #define BTTV_LMLBT4 0x76 +#define BTTV_PICOLO_TETRA_CHIP 0x79 +#define BTTV_AVDVBT_771 0x7b /* i2c address list */ #define I2C_TSA5522 0xc2 diff -Nru a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h --- a/drivers/media/video/bttvp.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/media/video/bttvp.h 2004-06-26 17:09:17 -07:00 @@ -25,7 +25,7 @@ #define _BTTVP_H_ #include -#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,14) +#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,15) #include #include @@ -127,7 +127,6 @@ struct bttv_buffer_set { struct bttv_buffer *top; /* top field buffer */ struct bttv_buffer *bottom; /* bottom field buffer */ - struct bttv_buffer *vbi; /* vbi buffer */ unsigned int irqflags; unsigned int topirq; }; @@ -197,8 +196,10 @@ /* capture buffer handling */ int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf); -int bttv_buffer_set_activate(struct bttv *btv, - struct bttv_buffer_set *set); +int bttv_buffer_activate_video(struct bttv *btv, + struct bttv_buffer_set *set); +int bttv_buffer_activate_vbi(struct bttv *btv, + struct bttv_buffer *vbi); void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf); /* overlay handling */ @@ -279,7 +280,8 @@ u32 gpio_enable; u32 gpio_data; int disabled; - struct bttv_buffer_set set; + struct bttv_buffer_set video; + struct bttv_buffer *vbi; }; struct bttv { @@ -377,6 +379,7 @@ struct list_head capture; /* video capture queue */ struct list_head vcapture; /* vbi capture queue */ struct bttv_buffer_set curr; /* active buffers */ + struct bttv_buffer *cvbi; /* active vbi buffer */ int new_input; unsigned long cap_ctl; diff -Nru a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c --- a/drivers/media/video/cx88/cx88-cards.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/media/video/cx88/cx88-cards.c 2004-06-26 17:09:20 -07:00 @@ -99,6 +99,10 @@ .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, + .gpio0 = 0x000003ff, + .gpio1 = 0x000000ff, + .gpio2 = 0x000000ff, + .gpio3 = 0x00000000, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, @@ -111,6 +115,7 @@ [CX88_BOARD_WINFAST2000XP] = { .name = "Leadtek Winfast 2000XP Expert", .tuner_type = 44, + .needs_tda9887 = 1, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -149,22 +154,33 @@ .vmux = 0, }}, }, - [CX88_BOARD_MSI_TVANYWHERE] = { + [CX88_BOARD_MSI_TVANYWHERE_MASTER] = { + //added gpio values thanks to Torsten Seeboth + //values for PAL from DScaler .name = "MSI TV-@nywhere Master", .tuner_type = 33, + .needs_tda9887 = 1, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, + .gpio0 = 0x000040bf, + .gpio1 = 0x000080c0, + .gpio2 = 0x0000ff40, + .gpio3 = 0x00000000, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - },{ - // temporarly for testing ... - .type = CX88_VMUX_COMPOSITE2, - .vmux = 2, + .gpio0 = 0x000040bf, + .gpio1 = 0x000080c0, + .gpio2 = 0x0000ff40, + .gpio3 = 0x00000000, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, + .gpio0 = 0x000040bf, + .gpio1 = 0x000080c0, + .gpio2 = 0x0000ff40, + .gpio3 = 0x00000000, }}, .radio = { .type = CX88_RADIO, @@ -199,8 +215,97 @@ .type = CX88_RADIO, }, }, - - + [CX88_BOARD_IODATA_GVVCP3PCI] = { + .name = "IODATA GV-VCP3/PCI", + .tuner_type = TUNER_ABSENT, + .needs_tda9887 = 0, + .input = {{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 0, + },{ + .type = CX88_VMUX_COMPOSITE2, + .vmux = 1, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + }}, + }, + [CX88_BOARD_PROLINK_PLAYTVPVR] = { + .name = "Prolink PlayTV PVR", + .tuner_type = 43, + .needs_tda9887 = 1, + .input = {{ + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0xff00, + },{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0xff03, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0xff03, + }}, + .radio = { + .type = CX88_RADIO, + .gpio0 = 0xff00, + }, + }, + [CX88_BOARD_ASUS_PVR_416] = { + .name = "ASUS PVR-416", + .tuner_type = 43, + .needs_tda9887 = 1, + .input = {{ + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x0000fde6, + .gpio1 = 0x00000000, // possibly for mpeg data + .gpio2 = 0x000000e9, + .gpio3 = 0x00000000, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? + .gpio1 = 0x00000000, // possibly for mpeg data + .gpio2 = 0x000000e9, + .gpio3 = 0x00000000, + }}, + .radio = { + .type = CX88_RADIO, + .gpio0 = 0x0000fde2, + .gpio1 = 0x00000000, + .gpio2 = 0x000000e9, + .gpio3 = 0x00000000, + }, + }, + [CX88_BOARD_MSI_TVANYWHERE] = { + .name = "MSI TV-@nywhere", + .tuner_type = 33, + .needs_tda9887 = 1, + .input = {{ + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x00000fbf, + .gpio1 = 0x000000c0, + .gpio2 = 0x0000fc08, + .gpio3 = 0x00000000, + },{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0x00000fbf, + .gpio1 = 0x000000c0, + .gpio2 = 0x0000fc68, + .gpio3 = 0x00000000, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x00000fbf, + .gpio1 = 0x000000c0, + .gpio2 = 0x0000fc68, + .gpio3 = 0x00000000, + }}, + }, }; const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); @@ -242,6 +347,10 @@ .card = CX88_BOARD_WINFAST_DV2000, },{ .subvendor = 0x107d, + .subdevice = 0x663b, + .card = CX88_BOARD_LEADTEK_PVR2000, + },{ + .subvendor = 0x107d, .subdevice = 0x663C, .card = CX88_BOARD_LEADTEK_PVR2000, },{ @@ -251,12 +360,19 @@ },{ .subvendor = 0x1462, .subdevice = 0x8606, - .card = CX88_BOARD_MSI_TVANYWHERE, - } + .card = CX88_BOARD_MSI_TVANYWHERE_MASTER, + },{ + .subvendor = 0x10fc, + .subdevice = 0xd003, + .card = CX88_BOARD_IODATA_GVVCP3PCI, + },{ + .subvendor = 0x1043, + .subdevice = 0x4823, /* with mpeg encoder */ + .card = CX88_BOARD_ASUS_PVR_416, + } }; const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); - /* ----------------------------------------------------------------------- */ /* some leadtek specific stuff */ @@ -386,20 +502,22 @@ [ 0x02 ] = { .id = TUNER_ABSENT, .name = "PAL_B" }, [ 0x03 ] = { .id = TUNER_ABSENT, - .name = "BAL_I" }, + .name = "PAL_I" }, [ 0x04 ] = { .id = TUNER_ABSENT, .name = "PAL_D" }, [ 0x05 ] = { .id = TUNER_ABSENT, .name = "SECAM" }, - [ 0x10 ] = { .id = TUNER_ABSENT, .fm = 1, + [ 0x10 ] = { .id = TUNER_ABSENT, + .fm = 1, .name = "TEMIC_4049" }, [ 0x11 ] = { .id = TUNER_TEMIC_4136FY5, .name = "TEMIC_4136" }, [ 0x12 ] = { .id = TUNER_ABSENT, .name = "TEMIC_4146" }, - [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME, .fm = 1, + [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME, + .fm = 1, .name = "PHILIPS_FQ1216_MK3" }, [ 0x21 ] = { .id = TUNER_ABSENT, .fm = 1, .name = "PHILIPS_FQ1236_MK3" }, @@ -454,7 +572,33 @@ return 0; } -void __devinit cx88_card_setup(struct cx8800_dev *dev) +void cx88_card_list(struct cx8800_dev *dev) +{ + int i; + + if (0 == dev->pci->subsystem_vendor && + 0 == dev->pci->subsystem_device) { + printk("%s: Your board has no valid PCI Subsystem ID and thus can't\n" + "%s: be autodetected. Please pass card= insmod option to\n" + "%s: workaround that. Redirect complaints to the vendor of\n" + "%s: the TV card. Best regards,\n" + "%s: -- tux\n", + dev->name,dev->name,dev->name,dev->name,dev->name); + } else { + printk("%s: Your board isn't known (yet) to the driver. You can\n" + "%s: try to pick one of the existing card configs via\n" + "%s: card= insmod option. Updating to the latest\n" + "%s: version might help as well.\n", + dev->name,dev->name,dev->name,dev->name); + } + printk("%s: Here is a list of valid choices for the card= insmod option:\n", + dev->name); + for (i = 0; i < cx88_bcount; i++) + printk("%s: card=%d -> %s\n", + dev->name, i, cx88_boards[i].name); +} + +void cx88_card_setup(struct cx8800_dev *dev) { static u8 eeprom[128]; @@ -474,6 +618,9 @@ i2c_eeprom(&dev->i2c_client,eeprom,sizeof(eeprom)); leadtek_eeprom(dev,eeprom); break; + case CX88_BOARD_ASUS_PVR_416: + dev->has_radio = 1; + break; } } @@ -483,6 +630,7 @@ EXPORT_SYMBOL(cx88_bcount); EXPORT_SYMBOL(cx88_subids); EXPORT_SYMBOL(cx88_idcount); +EXPORT_SYMBOL(cx88_card_list); EXPORT_SYMBOL(cx88_card_setup); /* diff -Nru a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c --- a/drivers/media/video/cx88/cx88-i2c.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/media/video/cx88/cx88-i2c.c 2004-06-26 17:09:17 -07:00 @@ -22,8 +22,6 @@ */ -#define __NO_VERSION__ 1 - #include #include diff -Nru a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h --- a/drivers/media/video/cx88/cx88-reg.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/media/video/cx88/cx88-reg.h 2004-06-26 17:09:17 -07:00 @@ -599,10 +599,20 @@ #define EN_I2SIN_STR2DAC 0x00004000 #define EN_I2SIN_ENABLE 0x00008000 +#if 0 +/* old */ #define EN_DMTRX_SUMDIFF 0x00000800 #define EN_DMTRX_SUMR 0x00000880 #define EN_DMTRX_LR 0x00000900 #define EN_DMTRX_MONO 0x00000980 +#else +/* dscaler cvs */ +#define EN_DMTRX_SUMDIFF (0 << 7) +#define EN_DMTRX_SUMR (1 << 7) +#define EN_DMTRX_LR (2 << 7) +#define EN_DMTRX_MONO (3 << 7) +#define EN_DMTRX_BYPASS (1 << 11) +#endif // Video #define VID_CAPTURE_CONTROL 0x310180 diff -Nru a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c --- a/drivers/media/video/cx88/cx88-tvaudio.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/media/video/cx88/cx88-tvaudio.c 2004-06-26 17:09:17 -07:00 @@ -48,6 +48,7 @@ #include #include #include +#include #include "cx88.h" @@ -60,6 +61,33 @@ /* ----------------------------------------------------------- */ +static char *aud_ctl_names[64] = +{ + [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO", + [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO", + [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP", + [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO", + [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP", + [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1", + [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2", + [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO", + [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2", + [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO", + [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1", + [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2", + [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO", + [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2", + [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO", + [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1", + [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2", + [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO", + [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2", + [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO", + [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO", + [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO", + [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO", +}; + struct rlist { u32 reg; u32 val; @@ -125,26 +153,116 @@ static void set_audio_standard_BTSC(struct cx8800_dev *dev, unsigned int sap) { static const struct rlist btsc[] = { - /* Magic stuff from leadtek driver + datasheet.*/ - { AUD_DBX_IN_GAIN, 0x4734 }, - { AUD_DBX_WBE_GAIN, 0x4640 }, - { AUD_DBX_SE_GAIN, 0x8D31 }, - { AUD_DEEMPH0_G0, 0x1604 }, - { AUD_PHASE_FIX_CTL, 0x0020 }, - + /* from dscaler */ + { AUD_OUT1_SEL, 0x00000013 }, + { AUD_OUT1_SHIFT, 0x00000000 }, + { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, + { AUD_DMD_RA_DDS, 0x00c3e7aa }, + { AUD_DBX_IN_GAIN, 0x00004734 }, + { AUD_DBX_WBE_GAIN, 0x00004640 }, + { AUD_DBX_SE_GAIN, 0x00008d31 }, + { AUD_DCOC_0_SRC, 0x0000001a }, + { AUD_IIR1_4_SEL, 0x00000021 }, + { AUD_DCOC_PASS_IN, 0x00000003 }, + { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, + { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, + { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, + { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, + { AUD_DN0_FREQ, 0x0000283b }, + { AUD_DN2_SRC_SEL, 0x00000008 }, + { AUD_DN2_FREQ, 0x00003000 }, + { AUD_DN2_AFC, 0x00000002 }, + { AUD_DN2_SHFT, 0x00000000 }, + { AUD_IIR2_2_SEL, 0x00000020 }, + { AUD_IIR2_2_SHIFT, 0x00000000 }, + { AUD_IIR2_3_SEL, 0x0000001f }, + { AUD_IIR2_3_SHIFT, 0x00000000 }, + { AUD_CRDC1_SRC_SEL, 0x000003ce }, + { AUD_CRDC1_SHIFT, 0x00000000 }, + { AUD_CORDIC_SHIFT_1, 0x00000007 }, + { AUD_DCOC_1_SRC, 0x0000001b }, + { AUD_DCOC1_SHIFT, 0x00000000 }, + { AUD_RDSI_SEL, 0x00000008 }, + { AUD_RDSQ_SEL, 0x00000008 }, + { AUD_RDSI_SHIFT, 0x00000000 }, + { AUD_RDSQ_SHIFT, 0x00000000 }, + { AUD_POLYPH80SCALEFAC, 0x00000003 }, + { /* end of list */ }, + }; + static const struct rlist btsc_sap[] = { + { AUD_DBX_IN_GAIN, 0x00007200 }, + { AUD_DBX_WBE_GAIN, 0x00006200 }, + { AUD_DBX_SE_GAIN, 0x00006200 }, + { AUD_IIR1_1_SEL, 0x00000000 }, + { AUD_IIR1_3_SEL, 0x00000001 }, + { AUD_DN1_SRC_SEL, 0x00000007 }, + { AUD_IIR1_4_SHIFT, 0x00000006 }, + { AUD_IIR2_1_SHIFT, 0x00000000 }, + { AUD_IIR2_2_SHIFT, 0x00000000 }, + { AUD_IIR3_0_SHIFT, 0x00000000 }, + { AUD_IIR3_1_SHIFT, 0x00000000 }, + { AUD_IIR3_0_SEL, 0x0000000d }, + { AUD_IIR3_1_SEL, 0x0000000e }, + { AUD_DEEMPH1_SRC_SEL, 0x00000014 }, + { AUD_DEEMPH1_SHIFT, 0x00000000 }, + { AUD_DEEMPH1_G0, 0x00004000 }, + { AUD_DEEMPH1_A0, 0x00000000 }, + { AUD_DEEMPH1_B0, 0x00000000 }, + { AUD_DEEMPH1_A1, 0x00000000 }, + { AUD_DEEMPH1_B1, 0x00000000 }, + { AUD_OUT0_SEL, 0x0000003f }, + { AUD_OUT1_SEL, 0x0000003f }, + { AUD_DN1_AFC, 0x00000002 }, + { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, + { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, + { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, + { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, + { AUD_IIR1_0_SEL, 0x0000001d }, + { AUD_IIR1_2_SEL, 0x0000001e }, + { AUD_IIR2_1_SEL, 0x00000002 }, + { AUD_IIR2_2_SEL, 0x00000004 }, + { AUD_IIR3_2_SEL, 0x0000000f }, + { AUD_DCOC2_SHIFT, 0x00000001 }, + { AUD_IIR3_2_SHIFT, 0x00000001 }, + { AUD_DEEMPH0_SRC_SEL, 0x00000014 }, + { AUD_CORDIC_SHIFT_1, 0x00000006 }, + { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 }, + { AUD_DMD_RA_DDS, 0x00f696e6 }, + { AUD_IIR2_3_SEL, 0x00000025 }, + { AUD_IIR1_4_SEL, 0x00000021 }, + { AUD_DN1_FREQ, 0x0000c965 }, + { AUD_DCOC_PASS_IN, 0x00000003 }, + { AUD_DCOC_0_SRC, 0x0000001a }, + { AUD_DCOC_1_SRC, 0x0000001b }, + { AUD_DCOC1_SHIFT, 0x00000000 }, + { AUD_RDSI_SEL, 0x00000009 }, + { AUD_RDSQ_SEL, 0x00000009 }, + { AUD_RDSI_SHIFT, 0x00000000 }, + { AUD_RDSQ_SHIFT, 0x00000000 }, + { AUD_POLYPH80SCALEFAC, 0x00000003 }, { /* end of list */ }, }; - dprintk("%s (status: unknown)\n",__FUNCTION__); - set_audio_start(dev, 0x0001, - EN_BTSC_AUTO_STEREO); - set_audio_registers(dev, btsc); + // dscaler: exactly taken from driver, + // dscaler: don't know why to set EN_FMRADIO_EN_RDS + if (sap) { + dprintk("%s SAP (status: unknown)\n",__FUNCTION__); + set_audio_start(dev, 0x0001, + EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP); + set_audio_registers(dev, btsc_sap); + } else { + dprintk("%s (status: known-good)\n",__FUNCTION__); + set_audio_start(dev, 0x0001, + EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO); + set_audio_registers(dev, btsc); + } set_audio_finish(dev); } static void set_audio_standard_NICAM(struct cx8800_dev *dev) { - static const struct rlist nicam[] = { + static const struct rlist nicam_common[] = { + /* from dscaler */ { AUD_RATE_ADJ1, 0x00000010 }, { AUD_RATE_ADJ2, 0x00000040 }, { AUD_RATE_ADJ3, 0x00000100 }, @@ -152,21 +270,64 @@ { AUD_RATE_ADJ5, 0x00001000 }, // { AUD_DMD_RA_DDS, 0x00c0d5ce }, + // Deemphasis 1: + { AUD_DEEMPHGAIN_R, 0x000023c2 }, + { AUD_DEEMPHNUMER1_R, 0x0002a7bc }, + { AUD_DEEMPHNUMER2_R, 0x0003023e }, + { AUD_DEEMPHDENOM1_R, 0x0000f3d0 }, + { AUD_DEEMPHDENOM2_R, 0x00000000 }, + +#if 0 + // Deemphasis 2: (other tv norm?) + { AUD_DEEMPHGAIN_R, 0x0000c600 }, + { AUD_DEEMPHNUMER1_R, 0x00066738 }, + { AUD_DEEMPHNUMER2_R, 0x00066739 }, + { AUD_DEEMPHDENOM1_R, 0x0001e88c }, + { AUD_DEEMPHDENOM2_R, 0x0001e88c }, +#endif + + { AUD_DEEMPHDENOM2_R, 0x00000000 }, + { AUD_ERRLOGPERIOD_R, 0x00000fff }, + { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff }, + { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff }, + { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f }, + { AUD_POLYPH80SCALEFAC, 0x00000003 }, + // setup QAM registers { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, { AUD_PDF_DDS_CNST_BYTE0, 0x16 }, { AUD_QAM_MODE, 0x05 }, + + { /* end of list */ }, + }; + static const struct rlist nicam_pal_i[] = { + { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, + { AUD_PHACC_FREQ_8MSB, 0x3a }, + { AUD_PHACC_FREQ_8LSB, 0x93 }, + + { /* end of list */ }, + }; + static const struct rlist nicam_default[] = { + { AUD_PDF_DDS_CNST_BYTE0, 0x16 }, { AUD_PHACC_FREQ_8MSB, 0x34 }, { AUD_PHACC_FREQ_8LSB, 0x4c }, { /* end of list */ }, - }; + }; - dprintk("%s (status: unknown)\n",__FUNCTION__); set_audio_start(dev, 0x0010, - EN_DMTRX_LR | EN_NICAM_FORCE_STEREO); - set_audio_registers(dev, nicam); + EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); + set_audio_registers(dev, nicam_common); + switch (dev->tvaudio) { + case WW_NICAM_I: + dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__); + set_audio_registers(dev, nicam_pal_i); + case WW_NICAM_BGDKL: + dprintk("%s PAL NICAM (status: unknown)\n",__FUNCTION__); + set_audio_registers(dev, nicam_default); + break; + }; set_audio_finish(dev); } @@ -297,7 +458,7 @@ static void set_audio_standard_A2(struct cx8800_dev *dev) { /* from dscaler cvs */ - static const struct rlist a2[] = { + static const struct rlist a2_common[] = { { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, @@ -347,16 +508,20 @@ { AUD_RDSQ_SHIFT, 0x00000000 }, { AUD_POLYPH80SCALEFAC, 0x00000001 }, - // Table 1 + { /* end of list */ }, + }; + + static const struct rlist a2_table1[] = { + // PAL-BG { AUD_DMD_RA_DDS, 0x002a73bd }, { AUD_C1_UP_THR, 0x00007000 }, { AUD_C1_LO_THR, 0x00005400 }, { AUD_C2_UP_THR, 0x00005400 }, { AUD_C2_LO_THR, 0x00003000 }, - -#if 0 - // found this in WDM-driver for A2, must country spec. - // Table 2 + { /* end of list */ }, + }; + static const struct rlist a2_table2[] = { + // PAL-DK { AUD_DMD_RA_DDS, 0x002a73bd }, { AUD_C1_UP_THR, 0x00007000 }, { AUD_C1_LO_THR, 0x00005400 }, @@ -364,8 +529,10 @@ { AUD_C2_LO_THR, 0x00003000 }, { AUD_DN0_FREQ, 0x00003a1c }, { AUD_DN2_FREQ, 0x0000d2e0 }, - - // Table 3 + { /* end of list */ }, + }; + static const struct rlist a2_table3[] = { + // unknown, probably NTSC-M { AUD_DMD_RA_DDS, 0x002a2873 }, { AUD_C1_UP_THR, 0x00003c00 }, { AUD_C1_LO_THR, 0x00003000 }, @@ -375,140 +542,26 @@ { AUD_DN1_FREQ, 0x00003418 }, { AUD_DN2_FREQ, 0x000029c7 }, { AUD_POLY0_DDS_CONSTANT, 0x000a7540 }, -#endif - { /* end of list */ }, }; - static const struct rlist a2_old[] = { - { AUD_DN0_FREQ, 0x0000312b }, - { AUD_POLY0_DDS_CONSTANT, 0x000a62b4 }, - { AUD_IIR1_0_SEL, 0x00000000 }, - { AUD_IIR1_1_SEL, 0x00000001 }, - { AUD_IIR1_2_SEL, 0x0000001f }, - { AUD_IIR1_3_SEL, 0x00000020 }, - { AUD_IIR1_4_SEL, 0x00000023 }, - { AUD_IIR1_5_SEL, 0x00000007 }, - { AUD_IIR1_0_SHIFT, 0x00000000 }, - { AUD_IIR1_1_SHIFT, 0x00000000 }, - { AUD_IIR1_2_SHIFT, 0x00000007 }, - { AUD_IIR1_3_SHIFT, 0x00000007 }, - { AUD_IIR1_4_SHIFT, 0x00000007 }, - { AUD_IIR1_5_SHIFT, 0x00000000 }, - { AUD_IIR2_0_SEL, 0x00000002 }, - { AUD_IIR2_1_SEL, 0x00000003 }, - { AUD_IIR2_2_SEL, 0x00000004 }, - { AUD_IIR2_3_SEL, 0x00000005 }, - { AUD_IIR3_0_SEL, 0x00000021 }, - { AUD_IIR3_1_SEL, 0x00000023 }, - { AUD_IIR3_2_SEL, 0x00000016 }, - { AUD_IIR3_0_SHIFT, 0x00000000 }, - { AUD_IIR3_1_SHIFT, 0x00000000 }, - { AUD_IIR3_2_SHIFT, 0x00000000 }, - { AUD_IIR4_0_SEL, 0x0000001d }, - { AUD_IIR4_1_SEL, 0x00000019 }, - { AUD_IIR4_2_SEL, 0x00000008 }, - { AUD_IIR4_0_SHIFT, 0x00000000 }, - { AUD_IIR4_1_SHIFT, 0x00000000 }, - { AUD_IIR4_2_SHIFT, 0x00000001 }, - { AUD_IIR4_0_CA0, 0x0003e57e }, - { AUD_IIR4_0_CA1, 0x00005e11 }, - { AUD_IIR4_0_CA2, 0x0003a7cf }, - { AUD_IIR4_0_CB0, 0x00002368 }, - { AUD_IIR4_0_CB1, 0x0003bf1b }, - { AUD_IIR4_1_CA0, 0x00006349 }, - { AUD_IIR4_1_CA1, 0x00006f27 }, - { AUD_IIR4_1_CA2, 0x0000e7a3 }, - { AUD_IIR4_1_CB0, 0x00005653 }, - { AUD_IIR4_1_CB1, 0x0000cf97 }, - { AUD_IIR4_2_CA0, 0x00006349 }, - { AUD_IIR4_2_CA1, 0x00006f27 }, - { AUD_IIR4_2_CA2, 0x0000e7a3 }, - { AUD_IIR4_2_CB0, 0x00005653 }, - { AUD_IIR4_2_CB1, 0x0000cf97 }, - { AUD_HP_MD_IIR4_1, 0x00000001 }, - { AUD_HP_PROG_IIR4_1, 0x00000017 }, - { AUD_DN1_FREQ, 0x00003618 }, - { AUD_DN1_SRC_SEL, 0x00000017 }, - { AUD_DN1_SHFT, 0x00000007 }, - { AUD_DN1_AFC, 0x00000000 }, - { AUD_DN1_FREQ_SHIFT, 0x00000000 }, - { AUD_DN2_SRC_SEL, 0x00000040 }, - { AUD_DN2_SHFT, 0x00000000 }, - { AUD_DN2_AFC, 0x00000002 }, - { AUD_DN2_FREQ, 0x0000caaf }, - { AUD_DN2_FREQ_SHIFT, 0x00000000 }, - { AUD_PDET_SRC, 0x00000014 }, - { AUD_PDET_SHIFT, 0x00000000 }, - { AUD_DEEMPH0_SRC_SEL, 0x00000011 }, - { AUD_DEEMPH1_SRC_SEL, 0x00000013 }, - { AUD_DEEMPH0_SHIFT, 0x00000000 }, - { AUD_DEEMPH1_SHIFT, 0x00000000 }, - { AUD_DEEMPH0_G0, 0x000004da }, - { AUD_DEEMPH0_A0, 0x0000777a }, - { AUD_DEEMPH0_B0, 0x00000000 }, - { AUD_DEEMPH0_A1, 0x0003f062 }, - { AUD_DEEMPH0_B1, 0x00000000 }, - { AUD_DEEMPH1_G0, 0x000004da }, - { AUD_DEEMPH1_A0, 0x0000777a }, - { AUD_DEEMPH1_B0, 0x00000000 }, - { AUD_DEEMPH1_A1, 0x0003f062 }, - { AUD_DEEMPH1_B1, 0x00000000 }, - { AUD_PLL_EN, 0x00000000 }, - { AUD_DMD_RA_DDS, 0x002a4efb }, - { AUD_RATE_ADJ1, 0x00001000 }, - { AUD_RATE_ADJ2, 0x00002000 }, - { AUD_RATE_ADJ3, 0x00003000 }, - { AUD_RATE_ADJ4, 0x00004000 }, - { AUD_RATE_ADJ5, 0x00005000 }, - { AUD_C2_UP_THR, 0x0000ffff }, - { AUD_C2_LO_THR, 0x0000e800 }, - { AUD_C1_UP_THR, 0x00008c00 }, - { AUD_C1_LO_THR, 0x00006c00 }, - - // ; Completely ditch AFC feedback - { AUD_DCOC_0_SRC, 0x00000021 }, - { AUD_DCOC_1_SRC, 0x0000001a }, - { AUD_DCOC1_SHIFT, 0x00000000 }, - { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, - { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, - { AUD_DCOC_PASS_IN, 0x00000000 }, - { AUD_IIR4_0_SEL, 0x00000023 }, - - // ; Completely ditc FM-2 AFC feedback - { AUD_DN1_AFC, 0x00000000 }, - { AUD_DCOC_2_SRC, 0x0000001b }, - { AUD_IIR4_1_SEL, 0x00000025 }, - - // ; WARNING!!! THIS CHANGE WAS NOT EXPECTED!!! - // ; Swap I & Q inputs into second rotator - // ; to reverse frequency and therefor invert - // ; phase from the cordic FM demodulator - // ; (frequency rotation must also be reversed - { AUD_DN2_SRC_SEL, 0x00000001 }, - { AUD_DN2_FREQ, 0x00003551 }, - - // setup Audio PLL - { AUD_PLL_PRESCALE, 0x00000002 }, - { AUD_PLL_INT, 0x0000001f }, - - { /* end of list */ }, + set_audio_start(dev, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO); + set_audio_registers(dev, a2_common); + switch (dev->tvaudio) { + case WW_A2_BG: + dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); + set_audio_registers(dev, a2_table1); + break; + case WW_A2_DK: + dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); + set_audio_registers(dev, a2_table2); + break; + case WW_A2_M: + dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); + set_audio_registers(dev, a2_table3); + break; }; - - - dprintk("%s (status: WorksForMe[tm])\n",__FUNCTION__); - - if (0) { - /* old code */ - set_audio_start(dev, 0x0004, EN_DMTRX_SUMR | EN_A2_AUTO_STEREO); - set_audio_registers(dev, a2_old); - set_audio_finish(dev); - } else { - /* new code */ - set_audio_start(dev, 0x0004, EN_DMTRX_LR | EN_A2_AUTO_STEREO); - set_audio_registers(dev, a2); - set_audio_finish(dev); - } + set_audio_finish(dev); } static void set_audio_standard_EIAJ(struct cx8800_dev *dev) @@ -617,9 +670,9 @@ reg = cx_read(AUD_STATUS); mode = reg & 0x03; pilot = (reg >> 2) & 0x03; - dprintk("AUD_STATUS: %s / %s [status=0x%x,ctl=0x%x,vol=0x%x]\n", - m[mode], p[pilot], reg, - cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL)); + dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n", + reg, m[mode], p[pilot], + aud_ctl_names[cx_read(AUD_CTL) & 63]); t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; @@ -628,6 +681,8 @@ switch (dev->tvaudio) { case WW_A2_BG: + case WW_A2_DK: + case WW_A2_M: if (1 == pilot) { /* stereo */ t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; @@ -659,6 +714,8 @@ switch (dev->tvaudio) { case WW_A2_BG: + case WW_A2_DK: + case WW_A2_M: switch (mode) { case V4L2_TUNER_MODE_MONO: case V4L2_TUNER_MODE_LANG1: @@ -715,6 +772,32 @@ cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL)); } return; +} + +/* just monitor the audio status for now ... */ +int cx88_audio_thread(void *data) +{ + struct cx8800_dev *dev = data; + struct v4l2_tuner t; + + daemonize("msp3400"); + allow_signal(SIGTERM); + dprintk("cx88: tvaudio thread started\n"); + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ*3); + if (signal_pending(current)) + break; + if (dev->shutdown) + break; + + memset(&t,0,sizeof(t)); + cx88_get_stereo(dev,&t); + } + + dprintk("cx88: tvaudio thread exiting\n"); + complete_and_exit(&dev->texit, 0); } /* diff -Nru a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c --- a/drivers/media/video/cx88/cx88-vbi.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/media/video/cx88/cx88-vbi.c 2004-06-26 17:09:17 -07:00 @@ -28,17 +28,14 @@ f->fmt.vbi.count[0] = VBI_LINE_COUNT; f->fmt.vbi.count[1] = VBI_LINE_COUNT; - switch (dev->tvnorm->id) { - case V4L2_STD_NTSC_M: - case V4L2_STD_NTSC_M_JP: + if (dev->tvnorm->id & V4L2_STD_525_60) { + /* ntsc */ f->fmt.vbi.sampling_rate = 28636363; f->fmt.vbi.start[0] = 10 -1; f->fmt.vbi.start[1] = 273 -1; - break; - case V4L2_STD_PAL_BG: - case V4L2_STD_PAL_DK: - case V4L2_STD_PAL_I: - case V4L2_STD_SECAM: + + } else if (V4L2_STD_625_50) { + /* pal */ f->fmt.vbi.sampling_rate = 35468950; f->fmt.vbi.start[0] = 7 -1; f->fmt.vbi.start[1] = 319 -1; diff -Nru a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c --- a/drivers/media/video/cx88/cx88-video.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/media/video/cx88/cx88-video.c 2004-06-26 17:09:18 -07:00 @@ -2,7 +2,7 @@ * device driver for Conexant 2388x based TV cards * video4linux video interface * - * (c) 2003 Gerd Knorr [SuSE Labs] + * (c) 2003-04 Gerd Knorr [SuSE Labs] * * 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 @@ -19,8 +19,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define __NO_VERSION__ 1 - #include #include #include @@ -32,6 +30,8 @@ #include "cx88.h" +#define V4L2_I2C_CLIENTS 1 + MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -194,8 +194,13 @@ .cxiformat = VideoFormatPAL60, .cxoformat = 0x181f0008, },{ - .name = "SECAM", - .id = V4L2_STD_SECAM, + .name = "SECAM-L", + .id = V4L2_STD_SECAM_L, + .cxiformat = VideoFormatSECAM, + .cxoformat = 0x181f0008, + },{ + .name = "SECAM-DK", + .id = V4L2_STD_SECAM_DK, .cxiformat = VideoFormatSECAM, .cxoformat = 0x181f0008, } @@ -483,35 +488,38 @@ if (CX88_VMUX_TELEVISION != INPUT(dev->input)->type) return 0; - switch (dev->tvnorm->id) { - case V4L2_STD_PAL_BG: + if (V4L2_STD_PAL_BG & dev->tvnorm->id) { dev->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG; - break; - case V4L2_STD_PAL_DK: + + } else if (V4L2_STD_PAL_DK & dev->tvnorm->id) { dev->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK; - break; - case V4L2_STD_PAL_I: + + } else if (V4L2_STD_PAL_I & dev->tvnorm->id) { dev->tvaudio = WW_NICAM_I; - break; - case V4L2_STD_SECAM: - dev->tvaudio = WW_SYSTEM_L_AM; /* FIXME: fr != ru */ - break; - case V4L2_STD_NTSC_M: + + } else if (V4L2_STD_SECAM_L & dev->tvnorm->id) { + dev->tvaudio = WW_SYSTEM_L_AM; + + } else if (V4L2_STD_SECAM_DK & dev->tvnorm->id) { + dev->tvaudio = WW_A2_DK; + + } else if ((V4L2_STD_NTSC_M & dev->tvnorm->id) || + (V4L2_STD_PAL_M & dev->tvnorm->id)) { dev->tvaudio = WW_BTSC; - break; - case V4L2_STD_NTSC_M_JP: + + } else if (V4L2_STD_NTSC_M_JP & dev->tvnorm->id) { dev->tvaudio = WW_EIAJ; - break; - default: - dprintk(1,"tvaudio support needs work for this tv norm [%s], sorry\n", - dev->tvnorm->name); + + } else { + printk("%s: tvaudio support needs work for this tv norm [%s], sorry\n", + dev->name, dev->tvnorm->name); dev->tvaudio = 0; return 0; } cx_andor(MO_AFECFG_IO, 0x1f, 0x0); cx88_set_tvaudio(dev); - cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); + // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); cx_write(MO_AUDD_LNGTH, 128/8); /* fifo size */ cx_write(MO_AUDR_LNGTH, 128/8); /* fifo size */ @@ -526,7 +534,6 @@ u32 vdec_clock; u64 tmp64; u32 bdelay,agcdelay,htotal; - struct video_channel c; dev->tvnorm = norm; fsc8 = norm_fsc8(norm); @@ -592,30 +599,43 @@ set_tvaudio(dev); // tell i2c chips - memset(&c,0,sizeof(c)); - c.channel = dev->input; - c.norm = VIDEO_MODE_PAL; - if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP))) - c.norm = VIDEO_MODE_NTSC; - if (norm->id & V4L2_STD_SECAM) - c.norm = VIDEO_MODE_SECAM; - cx8800_call_i2c_clients(dev,VIDIOCSCHAN,&c); +#ifdef V4L2_I2C_CLIENTS + cx8800_call_i2c_clients(dev,VIDIOC_S_STD,&norm->id); +#else + { + struct video_channel c; + memset(&c,0,sizeof(c)); + c.channel = dev->input; + c.norm = VIDEO_MODE_PAL; + if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP))) + c.norm = VIDEO_MODE_NTSC; + if (norm->id & V4L2_STD_SECAM) + c.norm = VIDEO_MODE_SECAM; + cx8800_call_i2c_clients(dev,VIDIOCSCHAN,&c); + } +#endif // done return 0; } static int set_scale(struct cx8800_dev *dev, unsigned int width, unsigned int height, - int interlaced) + enum v4l2_field field) { unsigned int swidth = norm_swidth(dev->tvnorm); unsigned int sheight = norm_maxh(dev->tvnorm); u32 value; - dprintk(1,"set_scale: %dx%d [%s]\n", width, height, dev->tvnorm->name); + dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height, + V4L2_FIELD_HAS_TOP(field) ? "T" : "", + V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "", + dev->tvnorm->name); + if (!V4L2_FIELD_HAS_BOTH(field)) + height *= 2; // recalc H delay and scale registers value = (width * norm_hdelay(dev->tvnorm)) / swidth; + value &= 0x3fe; cx_write(MO_HDELAY_EVEN, value); cx_write(MO_HDELAY_ODD, value); dprintk(1,"set_scale: hdelay 0x%04x\n", value); @@ -646,7 +666,7 @@ // setup filters value = 0; value |= (1 << 19); // CFILT (default) - if (interlaced) + if (V4L2_FIELD_INTERLACED == field) value |= (1 << 3); // VINT (interlaced vertical scaling) if (width < 385) value |= (1 << 0); // 3-tap interpolation @@ -675,10 +695,12 @@ switch (INPUT(input)->type) { case CX88_VMUX_SVIDEO: - cx_andor(MO_AFECFG_IO, 0x01, 0x01); + cx_set(MO_AFECFG_IO, 0x00000001); + cx_set(MO_INPUT_FORMAT, 0x00010010); break; default: - cx_andor(MO_AFECFG_IO, 0x01, 0x00); + cx_clear(MO_AFECFG_IO, 0x00000001); + cx_clear(MO_INPUT_FORMAT, 0x00010010); break; } return 0; @@ -693,7 +715,7 @@ /* setup fifo + format */ cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH21], buf->bpl, buf->risc.dma); - set_scale(dev, buf->vb.width, buf->vb.height, 1); + set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field); cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma); /* reset counter */ @@ -1350,6 +1372,9 @@ case V4L2_CID_AUDIO_BALANCE: ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f)); break; + case V4L2_CID_AUDIO_VOLUME: + ctl->value = 0x3f - (value & 0x3f); + break; default: ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; break; @@ -1378,6 +1403,9 @@ case V4L2_CID_AUDIO_BALANCE: value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; break; + case V4L2_CID_AUDIO_VOLUME: + value = 0x3f - (ctl->value & 0x3f); + break; case V4L2_CID_SATURATION: /* special v_sat handling */ v_sat_value = ctl->value - (0x7f - 0x5a); @@ -1409,7 +1437,7 @@ }; static struct v4l2_control volume = { .id = V4L2_CID_AUDIO_VOLUME, - .value = 0, + .value = 0x3f, }; set_control(dev,&mute); @@ -1459,15 +1487,12 @@ maxw = norm_maxw(dev->tvnorm); maxh = norm_maxh(dev->tvnorm); -#if 0 if (V4L2_FIELD_ANY == field) { field = (f->fmt.pix.height > maxh/2) ? V4L2_FIELD_INTERLACED : V4L2_FIELD_BOTTOM; } -#else - field = V4L2_FIELD_INTERLACED; -#endif + switch (field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: @@ -1480,14 +1505,15 @@ } f->fmt.pix.field = field; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; if (f->fmt.pix.height < 32) f->fmt.pix.height = 32; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; if (f->fmt.pix.height > maxh) f->fmt.pix.height = maxh; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.width > maxw) + f->fmt.pix.width = maxw; + f->fmt.pix.width &= ~0x03; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = @@ -1783,7 +1809,11 @@ return -EINVAL; down(&dev->lock); dev->freq = f->frequency; +#ifdef V4L2_I2C_CLIENTS + cx8800_call_i2c_clients(dev,VIDIOC_S_FREQUENCY,f); +#else cx8800_call_i2c_clients(dev,VIDIOCSFREQ,&dev->freq); +#endif up(&dev->lock); return 0; } @@ -1885,7 +1915,6 @@ case VIDIOC_G_TUNER: { struct v4l2_tuner *t = arg; - struct video_tuner vt; if (t->index > 0) return -EINVAL; @@ -1895,9 +1924,16 @@ t->rangelow = (int)(65*16); t->rangehigh = (int)(108*16); - memset(&vt,0,sizeof(vt)); - cx8800_call_i2c_clients(dev,VIDIOCGTUNER,&vt); - t->signal = vt.signal; +#ifdef V4L2_I2C_CLIENTS + cx8800_call_i2c_clients(dev,VIDIOC_G_TUNER,t); +#else + { + struct video_tuner vt; + memset(&vt,0,sizeof(vt)); + cx8800_call_i2c_clients(dev,VIDIOCGTUNER,&vt); + t->signal = vt.signal; + } +#endif return 0; } case VIDIOC_ENUMINPUT: @@ -2281,11 +2317,6 @@ } } -/* debug that damn oops ... */ -static unsigned int oops = 0; -MODULE_PARM(oops,"i"); -#define OOPS(msg) if (oops) printk("%s: %s\n",__FUNCTION__,msg); - static int __devinit cx8800_initdev(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { @@ -2299,7 +2330,6 @@ memset(dev,0,sizeof(*dev)); /* pci init */ - OOPS("pci init"); dev->pci = pci_dev; if (pci_enable_device(pci_dev)) { err = -EIO; @@ -2308,7 +2338,6 @@ sprintf(dev->name,"cx%x[%d]",pci_dev->device,cx8800_devcount); /* pci quirks */ - OOPS("pci quirks"); cx88_pci_quirks(dev->name, dev->pci, &latency); if (UNSET != latency) { printk(KERN_INFO "%s: setting pci latency timer to %d\n", @@ -2317,7 +2346,6 @@ } /* print pci info */ - OOPS("pci info"); pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " @@ -2333,14 +2361,15 @@ } /* board config */ - OOPS("board config"); dev->board = card[cx8800_devcount]; for (i = 0; UNSET == dev->board && i < cx88_idcount; i++) if (pci_dev->subsystem_vendor == cx88_subids[i].subvendor && pci_dev->subsystem_device == cx88_subids[i].subdevice) dev->board = cx88_subids[i].card; - if (UNSET == dev->board) + if (UNSET == dev->board) { dev->board = CX88_BOARD_UNKNOWN; + cx88_card_list(dev); + } printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", dev->name,pci_dev->subsystem_vendor, pci_dev->subsystem_device,cx88_boards[dev->board].name, @@ -2352,7 +2381,6 @@ dev->tuner_type = cx88_boards[dev->board].tuner_type; /* get mmio */ - OOPS("get mmio"); if (!request_mem_region(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0), dev->name)) { @@ -2366,7 +2394,6 @@ dev->bmmio = (u8*)dev->lmmio; /* initialize driver struct */ - OOPS("init structs"); init_MUTEX(&dev->lock); dev->slock = SPIN_LOCK_UNLOCKED; dev->tvnorm = tvnorms; @@ -2390,11 +2417,9 @@ MO_VID_DMACNTRL,0x88,0x00); /* initialize hardware */ - OOPS("reset hardware"); cx8800_reset(dev); /* get irq */ - OOPS("install irq handler"); err = request_irq(pci_dev->irq, cx8800_irq, SA_SHIRQ | SA_INTERRUPT, dev->name, dev); if (err < 0) { @@ -2404,13 +2429,10 @@ } /* register i2c bus + load i2c helpers */ - OOPS("i2c setup"); cx8800_i2c_init(dev); - OOPS("card setup"); cx88_card_setup(dev); /* load and configure helper modules */ - OOPS("configure i2c clients"); if (TUNER_ABSENT != dev->tuner_type) request_module("tuner"); if (cx88_boards[dev->board].needs_tda9887) @@ -2419,7 +2441,6 @@ cx8800_call_i2c_clients(dev,TUNER_SET_TYPE,&dev->tuner_type); /* register v4l devices */ - OOPS("register video"); dev->video_dev = vdev_init(dev,&cx8800_video_template,"video"); err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[cx8800_devcount]); @@ -2431,7 +2452,6 @@ printk(KERN_INFO "%s: registered device video%d [v4l2]\n", dev->name,dev->video_dev->minor & 0x1f); - OOPS("register vbi"); dev->vbi_dev = vdev_init(dev,&cx8800_vbi_template,"vbi"); err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[cx8800_devcount]); @@ -2444,7 +2464,6 @@ dev->name,dev->vbi_dev->minor & 0x1f); if (dev->has_radio) { - OOPS("register radio"); dev->radio_dev = vdev_init(dev,&cx8800_radio_template,"radio"); err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, radio_nr[cx8800_devcount]); @@ -2458,32 +2477,31 @@ } /* everything worked */ - OOPS("finalize"); list_add_tail(&dev->devlist,&cx8800_devlist); pci_set_drvdata(pci_dev,dev); cx8800_devcount++; /* initial device configuration */ - OOPS("init device"); down(&dev->lock); init_controls(dev); set_tvnorm(dev,tvnorms); video_mux(dev,0); up(&dev->lock); + + /* start tvaudio thread */ + init_completion(&dev->texit); + dev->tpid = kernel_thread(cx88_audio_thread, dev, 0); return 0; fail3: - OOPS("fail3"); cx8800_unregister_video(dev); if (0 == dev->i2c_rc) i2c_bit_del_bus(&dev->i2c_adap); free_irq(pci_dev->irq, dev); fail2: - OOPS("fail2"); release_mem_region(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0)); fail1: - OOPS("fail1"); kfree(dev); return err; } @@ -2491,6 +2509,11 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) { struct cx8800_dev *dev = pci_get_drvdata(pci_dev); + + /* stop thread */ + dev->shutdown = 1; + if (dev->tpid >= 0) + wait_for_completion(&dev->texit); cx8800_shutdown(dev); pci_disable_device(pci_dev); diff -Nru a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h --- a/drivers/media/video/cx88/cx88.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/media/video/cx88/cx88.h 2004-06-26 17:09:21 -07:00 @@ -32,7 +32,7 @@ #include "cx88-reg.h" #include -#define CX88_VERSION_CODE KERNEL_VERSION(0,0,3) +#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4) #ifndef TRUE # define TRUE (1==1) @@ -114,17 +114,20 @@ /* card configuration */ #define CX88_BOARD_NOAUTO UNSET -#define CX88_BOARD_UNKNOWN 0 -#define CX88_BOARD_HAUPPAUGE 1 -#define CX88_BOARD_GDI 2 -#define CX88_BOARD_PIXELVIEW 3 -#define CX88_BOARD_ATI_WONDER_PRO 4 -#define CX88_BOARD_WINFAST2000XP 5 -#define CX88_BOARD_AVERTV_303 6 -#define CX88_BOARD_MSI_TVANYWHERE 7 -#define CX88_BOARD_WINFAST_DV2000 8 -#define CX88_BOARD_LEADTEK_PVR2000 9 - +#define CX88_BOARD_UNKNOWN 0 +#define CX88_BOARD_HAUPPAUGE 1 +#define CX88_BOARD_GDI 2 +#define CX88_BOARD_PIXELVIEW 3 +#define CX88_BOARD_ATI_WONDER_PRO 4 +#define CX88_BOARD_WINFAST2000XP 5 +#define CX88_BOARD_AVERTV_303 6 +#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 +#define CX88_BOARD_WINFAST_DV2000 8 +#define CX88_BOARD_LEADTEK_PVR2000 9 +#define CX88_BOARD_IODATA_GVVCP3PCI 10 +#define CX88_BOARD_PROLINK_PLAYTVPVR 11 +#define CX88_BOARD_ASUS_PVR_416 12 +#define CX88_BOARD_MSI_TVANYWHERE 13 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -263,6 +266,9 @@ /* other global state info */ u32 shadow[SHADOW_MAX]; + int shutdown; + pid_t tpid; + struct completion texit; struct cx8800_suspend_state state; }; @@ -351,7 +357,8 @@ extern struct cx88_subid cx88_subids[]; extern const unsigned int cx88_idcount; -extern void __devinit cx88_card_setup(struct cx8800_dev *dev); +extern void cx88_card_list(struct cx8800_dev *dev); +extern void cx88_card_setup(struct cx8800_dev *dev); /* ----------------------------------------------------------- */ /* cx88-tvaudio.c */ @@ -372,6 +379,7 @@ void cx88_set_tvaudio(struct cx8800_dev *dev); void cx88_get_stereo(struct cx8800_dev *dev, struct v4l2_tuner *t); void cx88_set_stereo(struct cx8800_dev *dev, u32 mode); +int cx88_audio_thread(void *data); /* * Local variables: diff -Nru a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c --- a/drivers/media/video/ir-kbd-gpio.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/media/video/ir-kbd-gpio.c 2004-06-26 17:09:20 -07:00 @@ -1,3 +1,4 @@ + /* * Copyright (c) 2003 Gerd Knorr * Copyright (c) 2003 Pavel Machek @@ -32,47 +33,45 @@ /* ---------------------------------------------------------------------- */ static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = { - [ 17 ] = KEY_KP0, - [ 20 ] = KEY_KP1, - [ 12 ] = KEY_KP2, - [ 28 ] = KEY_KP3, - [ 18 ] = KEY_KP4, - [ 10 ] = KEY_KP5, - [ 26 ] = KEY_KP6, - [ 22 ] = KEY_KP7, - [ 14 ] = KEY_KP8, - [ 30 ] = KEY_KP9, + [ 34 ] = KEY_KP0, + [ 40 ] = KEY_KP1, + [ 24 ] = KEY_KP2, + [ 56 ] = KEY_KP3, + [ 36 ] = KEY_KP4, + [ 20 ] = KEY_KP5, + [ 52 ] = KEY_KP6, + [ 44 ] = KEY_KP7, + [ 28 ] = KEY_KP8, + [ 60 ] = KEY_KP9, - [ 24 ] = KEY_EJECTCD, // Unmarked on my controller + [ 48 ] = KEY_EJECTCD, // Unmarked on my controller [ 0 ] = KEY_POWER, - [ 9 ] = BTN_LEFT, // DISPLAY/L - [ 25 ] = BTN_RIGHT, // LOOP/R - [ 5 ] = KEY_MUTE, - [ 19 ] = KEY_RECORD, - [ 11 ] = KEY_PAUSE, - [ 27 ] = KEY_STOP, - [ 15 ] = KEY_VOLUMEDOWN, - [ 31 ] = KEY_VOLUMEUP, - - [ 16 ] = KEY_TUNER, // TV/FM - [ 8 ] = KEY_CD, - [ 4 ] = KEY_VIDEO, - [ 2 ] = KEY_AUDIO, - [ 6 ] = KEY_ZOOM, // full screen - [ 1 ] = KEY_INFO, // preview - [ 21 ] = KEY_SEARCH, // autoscan - [ 13 ] = KEY_STOP, // freeze - [ 29 ] = KEY_RECORD, // capture - [ 3 ] = KEY_PLAY, // unmarked - [ 23 ] = KEY_RED, // unmarked - [ 7 ] = KEY_GREEN, // unmarked - -#if 0 - [ 16 ] = KEY_YELLOW, // unmarked - [ 8 ] = KEY_CHANNELDOWN, - [ 24 ] = KEY_CHANNELUP, - [ 0 ] = KEY_BLUE, // unmarked -#endif + [ 18 ] = BTN_LEFT, // DISPLAY/L + [ 50 ] = BTN_RIGHT, // LOOP/R + [ 10 ] = KEY_MUTE, + [ 38 ] = KEY_RECORD, + [ 22 ] = KEY_PAUSE, + [ 54 ] = KEY_STOP, + [ 30 ] = KEY_VOLUMEDOWN, + [ 62 ] = KEY_VOLUMEUP, + + [ 32 ] = KEY_TUNER, // TV/FM + [ 16 ] = KEY_CD, + [ 8 ] = KEY_VIDEO, + [ 4 ] = KEY_AUDIO, + [ 12 ] = KEY_ZOOM, // full screen + [ 2 ] = KEY_INFO, // preview + [ 42 ] = KEY_SEARCH, // autoscan + [ 26 ] = KEY_STOP, // freeze + [ 58 ] = KEY_RECORD, // capture + [ 6 ] = KEY_PLAY, // unmarked + [ 46 ] = KEY_RED, // unmarked + [ 14 ] = KEY_GREEN, // unmarked + + [ 33 ] = KEY_YELLOW, // unmarked + [ 17 ] = KEY_CHANNELDOWN, + [ 49 ] = KEY_CHANNELUP, + [ 1 ] = KEY_BLUE, // unmarked }; static IR_KEYTAB_TYPE winfast_codes[IR_KEYTAB_SIZE] = { @@ -280,8 +279,9 @@ case BTTV_AVPHONE98: case BTTV_AVERMEDIA98: ir_codes = ir_codes_avermedia; - ir->mask_keycode = 0xf80000; + ir->mask_keycode = 0xf88000; ir->mask_keydown = 0x010000; + ir->polling = 50; // ms break; case BTTV_PXELVWPLTVPAK: @@ -300,7 +300,7 @@ case BTTV_WINFAST2000: ir_codes = winfast_codes; - ir->mask_keycode = 0x8f8; + ir->mask_keycode = 0x1f8; break; case BTTV_MAGICTVIEW061: case BTTV_MAGICTVIEW063: diff -Nru a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c --- a/drivers/media/video/ir-kbd-i2c.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/media/video/ir-kbd-i2c.c 2004-06-26 17:09:15 -07:00 @@ -77,6 +77,56 @@ [ 15 ] = KEY_SELECT, // SOURCE [ 10 ] = KEY_KPPLUS, // +100 [ 20 ] = KEY_KPEQUAL, // SYNC + [ 28 ] = KEY_MEDIA, // PC/TV +}; + +static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { + [ 0x3 ] = KEY_POWER, + [ 0x6f ] = KEY_MUTE, + [ 0x10 ] = KEY_BACKSPACE, // Recall + + [ 0x11 ] = KEY_KP0, + [ 0x4 ] = KEY_KP1, + [ 0x5 ] = KEY_KP2, + [ 0x6 ] = KEY_KP3, + [ 0x8 ] = KEY_KP4, + [ 0x9 ] = KEY_KP5, + [ 0xa ] = KEY_KP6, + [ 0xc ] = KEY_KP7, + [ 0xd ] = KEY_KP8, + [ 0xe ] = KEY_KP9, + [ 0x12 ] = KEY_KPDOT, // 100+ + + [ 0x7 ] = KEY_VOLUMEUP, + [ 0xb ] = KEY_VOLUMEDOWN, + [ 0x1a ] = KEY_KPPLUS, + [ 0x18 ] = KEY_KPMINUS, + [ 0x15 ] = KEY_UP, + [ 0x1d ] = KEY_DOWN, + [ 0xf ] = KEY_CHANNELUP, + [ 0x13 ] = KEY_CHANNELDOWN, + [ 0x48 ] = KEY_ZOOM, + + [ 0x1b ] = KEY_VIDEO, // Video source +#if 0 + [ 0x1f ] = KEY_S, // Snapshot +#endif + [ 0x49 ] = KEY_LANGUAGE, // MTS Select + [ 0x19 ] = KEY_SEARCH, // Auto Scan + + [ 0x4b ] = KEY_RECORD, + [ 0x46 ] = KEY_PLAY, + [ 0x45 ] = KEY_PAUSE, // Pause + [ 0x44 ] = KEY_STOP, +#if 0 + [ 0x43 ] = KEY_T, // Time Shift + [ 0x47 ] = KEY_Y, // Time Shift OFF + [ 0x4a ] = KEY_O, // TOP + [ 0x17 ] = KEY_F, // SURF CH +#endif + [ 0x40 ] = KEY_FORWARD, // Forward ? + [ 0x42 ] = KEY_REWIND, // Backward ? + }; struct IR; @@ -202,11 +252,33 @@ return 1; } +static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char b; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c,&b,1)) { + dprintk(1,"read error\n"); + return -EIO; + } + + /* no button press */ + if (b==0) + return 0; + + /* repeating */ + if (b & 0x80) + return 1; + + *ir_key = b; + *ir_raw = b; + return 1; +} /* ----------------------------------------------------------------------- */ static void ir_key_poll(struct IR *ir) { - u32 ir_key, ir_raw; + static u32 ir_key, ir_raw; int rc; dprintk(2,"ir_poll_key\n"); @@ -300,6 +372,12 @@ ir_type = IR_TYPE_OTHER; ir_codes = ir_codes_empty; break; + case 0x7a: + name = "Purple TV"; + ir->get_key = get_key_purpletv; + ir_type = IR_TYPE_OTHER; + ir_codes = ir_codes_purpletv; + break; default: /* shouldn't happen */ printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr); @@ -320,7 +398,8 @@ ir->input.name = ir->c.name; ir->input.phys = ir->phys; input_register_device(&ir->input); - printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys); + printk(DEVNAME ": %s detected at %s [%s]\n", + ir->input.name,ir->input.phys,adap->name); /* start polling via eventd */ INIT_WORK(&ir->work, ir_work, ir); @@ -361,22 +440,33 @@ That's why we probe 0x1a (~0x34) first. CB */ - static const int probe[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; + static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; + static const int probe_saa7134[] = { 0x7a, -1}; + const int *probe = NULL; struct i2c_client c; char buf; int i,rc; - if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) { - memset(&c,0,sizeof(c)); - c.adapter = adap; - for (i = 0; -1 != probe[i]; i++) { - c.addr = probe[i]; - rc = i2c_master_recv(&c,&buf,1); - dprintk(1,"probe 0x%02x @ %s: %s\n", - probe[i], adap->name, - (1 == rc) ? "yes" : "no"); - if (1 == rc) { - ir_attach(adap,probe[i],0,0); - break; - } + switch (adap->id) { + case I2C_ALGO_BIT | I2C_HW_B_BT848: + probe = probe_bttv; + break; + case I2C_ALGO_SAA7134: + probe = probe_saa7134; + break; + } + if (NULL == probe) + return 0; + + memset(&c,0,sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != probe[i]; i++) { + c.addr = probe[i]; + rc = i2c_master_recv(&c,&buf,1); + dprintk(1,"probe 0x%02x @ %s: %s\n", + probe[i], adap->name, + (1 == rc) ? "yes" : "no"); + if (1 == rc) { + ir_attach(adap,probe[i],0,0); + break; } } return 0; diff -Nru a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c --- a/drivers/media/video/msp3400.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/media/video/msp3400.c 2004-06-26 17:09:18 -07:00 @@ -51,6 +51,7 @@ #include #include +#include #include "msp3400.h" /* insmod parameters */ @@ -80,7 +81,7 @@ int input; int muted; - int left, right; /* volume */ + int volume, balance; int bass, treble; /* shadow register set */ @@ -378,26 +379,24 @@ } static void msp3400c_setvolume(struct i2c_client *client, - int muted, int left, int right) + int muted, int volume, int balance) { - int vol = 0,val = 0,balance = 0; + int val = 0, bal = 0; if (!muted) { - vol = (left > right) ? left : right; - val = (vol * 0x73 / 65535) << 8; + val = (volume * 0x73 / 65535) << 8; } - if (vol > 0) { - balance = ((right-left) * 127) / vol; + if (val) { + bal = (balance / 256) - 128; } - dprintk(KERN_DEBUG "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", - muted ? "on" : "off", left, right, val>>8, balance); + muted ? "on" : "off", volume, balance, val>>8, bal); msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ /* scart - on/off only */ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0); - msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, balance << 8); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); } static void msp3400c_setbass(struct i2c_client *client, int bass) @@ -815,7 +814,7 @@ /* no carrier scan, just unmute */ printk("msp3400: thread: no carrier scan\n"); msp3400c_setvolume(client, msp->muted, - msp->left, msp->right); + msp->volume, msp->balance); continue; } msp->restart = 0; @@ -960,7 +959,8 @@ } /* unmute + restore dfp registers */ - msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + msp3400c_setvolume(client, msp->muted, + msp->volume, msp->balance); msp3400c_restore_dfp(client); if (msp->watch_stereo) @@ -1042,7 +1042,7 @@ /* no carrier scan needed, just unmute */ dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n"); msp3400c_setvolume(client, msp->muted, - msp->left, msp->right); + msp->volume, msp->balance); continue; } msp->restart = 0; @@ -1194,7 +1194,8 @@ /* unmute + restore dfp registers */ msp3400c_setbass(client, msp->bass); msp3400c_settreble(client, msp->treble); - msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + msp3400c_setvolume(client, msp->muted, + msp->volume, msp->balance); msp3400c_restore_dfp(client); if (msp->watch_stereo) @@ -1257,8 +1258,8 @@ } memset(msp,0,sizeof(struct msp3400c)); - msp->left = 65535; - msp->right = 65535; + msp->volume = 65535; + msp->balance = 32768; msp->bass = 32768; msp->treble = 32768; msp->input = -1; @@ -1290,7 +1291,7 @@ /* this will turn on a 1kHz beep - might be useful for debugging... */ msp3400c_write(c,I2C_MSP3400C_DFP, 0x0014, 0x1040); #endif - msp3400c_setvolume(c,msp->muted,msp->left,msp->right); + msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance); snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d", (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@', @@ -1440,8 +1441,10 @@ } else { /* set msp3400 to FM radio mode */ msp3400c_setmode(client,MSP_MODE_FM_RADIO); - msp3400c_setcarrier(client, MSP_CARRIER(10.7),MSP_CARRIER(10.7)); - msp3400c_setvolume(client,msp->muted,msp->left,msp->right); + msp3400c_setcarrier(client, MSP_CARRIER(10.7), + MSP_CARRIER(10.7)); + msp3400c_setvolume(client, msp->muted, + msp->volume, msp->balance); } if (msp->active) msp->restart = 1; @@ -1488,16 +1491,9 @@ VIDEO_AUDIO_MUTABLE; if (msp->muted) va->flags |= VIDEO_AUDIO_MUTE; - va->volume=max(msp->left,msp->right); - if (0 == va->volume) { - va->balance = 32768; - } else { - va->balance = (32768 * min(msp->left,msp->right)) - / va->volume; - va->balance = (msp->leftright) ? - (65535 - va->balance) : va->balance; - } + va->volume = msp->volume; + va->balance = (va->volume) ? msp->balance : 32768; va->bass = msp->bass; va->treble = msp->treble; @@ -1513,13 +1509,13 @@ dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); msp->muted = (va->flags & VIDEO_AUDIO_MUTE); - msp->left = (min(65536 - va->balance,32768) * - va->volume) / 32768; - msp->right = (min(va->balance,(__u16)32768) * - va->volume) / 32768; + msp->volume = va->volume; + msp->balance = va->balance; msp->bass = va->bass; msp->treble = va->treble; - msp3400c_setvolume(client,msp->muted,msp->left,msp->right); + + msp3400c_setvolume(client, msp->muted, + msp->volume, msp->balance); msp3400c_setbass(client,msp->bass); msp3400c_settreble(client,msp->treble); diff -Nru a/drivers/media/video/ovcamchip/Makefile b/drivers/media/video/ovcamchip/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,4 @@ +ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \ + ov76be.o + +obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o diff -Nru a/drivers/media/video/ovcamchip/ov6x20.c b/drivers/media/video/ovcamchip/ov6x20.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/ov6x20.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,415 @@ +/* OmniVision OV6620/OV6120 Camera Chip Support Code + * + * Copyright (c) 1999-2004 Mark McClelland + * http://alpha.dyndns.org/ov511/ + * + * 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. NO WARRANTY OF ANY KIND is expressed or implied. + */ + +#define DEBUG + +#include +#include "ovcamchip_priv.h" + +/* Registers */ +#define REG_GAIN 0x00 /* gain [5:0] */ +#define REG_BLUE 0x01 /* blue gain */ +#define REG_RED 0x02 /* red gain */ +#define REG_SAT 0x03 /* saturation */ +#define REG_CNT 0x05 /* Y contrast */ +#define REG_BRT 0x06 /* Y brightness */ +#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */ +#define REG_WB_RED 0x0D /* WB red ratio [5:0] */ +#define REG_EXP 0x10 /* exposure */ + +/* Window parameters */ +#define HWSBASE 0x38 +#define HWEBASE 0x3A +#define VWSBASE 0x05 +#define VWEBASE 0x06 + +struct ov6x20 { + int auto_brt; + int auto_exp; + int backlight; + int bandfilt; + int mirror; +}; + +/* Initial values for use with OV511/OV511+ cameras */ +static struct ovcamchip_regvals regvals_init_6x20_511[] = { + { 0x12, 0x80 }, /* reset */ + { 0x11, 0x01 }, + { 0x03, 0x60 }, + { 0x05, 0x7f }, /* For when autoadjust is off */ + { 0x07, 0xa8 }, + { 0x0c, 0x24 }, + { 0x0d, 0x24 }, + { 0x0f, 0x15 }, /* COMS */ + { 0x10, 0x75 }, /* AEC Exposure time */ + { 0x12, 0x24 }, /* Enable AGC and AWB */ + { 0x14, 0x04 }, + { 0x16, 0x03 }, + { 0x26, 0xb2 }, /* BLC enable */ + /* 0x28: 0x05 Selects RGB format if RGB on */ + { 0x28, 0x05 }, + { 0x2a, 0x04 }, /* Disable framerate adjust */ + { 0x2d, 0x99 }, + { 0x33, 0xa0 }, /* Color Processing Parameter */ + { 0x34, 0xd2 }, /* Max A/D range */ + { 0x38, 0x8b }, + { 0x39, 0x40 }, + + { 0x3c, 0x39 }, /* Enable AEC mode changing */ + { 0x3c, 0x3c }, /* Change AEC mode */ + { 0x3c, 0x24 }, /* Disable AEC mode changing */ + + { 0x3d, 0x80 }, + /* These next two registers (0x4a, 0x4b) are undocumented. They + * control the color balance */ + { 0x4a, 0x80 }, + { 0x4b, 0x80 }, + { 0x4d, 0xd2 }, /* This reduces noise a bit */ + { 0x4e, 0xc1 }, + { 0x4f, 0x04 }, + { 0xff, 0xff }, /* END MARKER */ +}; + +/* Initial values for use with OV518 cameras */ +static struct ovcamchip_regvals regvals_init_6x20_518[] = { + { 0x12, 0x80 }, /* Do a reset */ + { 0x03, 0xc0 }, /* Saturation */ + { 0x05, 0x8a }, /* Contrast */ + { 0x0c, 0x24 }, /* AWB blue */ + { 0x0d, 0x24 }, /* AWB red */ + { 0x0e, 0x8d }, /* Additional 2x gain */ + { 0x0f, 0x25 }, /* Black expanding level = 1.3V */ + { 0x11, 0x01 }, /* Clock div. */ + { 0x12, 0x24 }, /* Enable AGC and AWB */ + { 0x13, 0x01 }, /* (default) */ + { 0x14, 0x80 }, /* Set reserved bit 7 */ + { 0x15, 0x01 }, /* (default) */ + { 0x16, 0x03 }, /* (default) */ + { 0x17, 0x38 }, /* (default) */ + { 0x18, 0xea }, /* (default) */ + { 0x19, 0x04 }, + { 0x1a, 0x93 }, + { 0x1b, 0x00 }, /* (default) */ + { 0x1e, 0xc4 }, /* (default) */ + { 0x1f, 0x04 }, /* (default) */ + { 0x20, 0x20 }, /* Enable 1st stage aperture correction */ + { 0x21, 0x10 }, /* Y offset */ + { 0x22, 0x88 }, /* U offset */ + { 0x23, 0xc0 }, /* Set XTAL power level */ + { 0x24, 0x53 }, /* AEC bright ratio */ + { 0x25, 0x7a }, /* AEC black ratio */ + { 0x26, 0xb2 }, /* BLC enable */ + { 0x27, 0xa2 }, /* Full output range */ + { 0x28, 0x01 }, /* (default) */ + { 0x29, 0x00 }, /* (default) */ + { 0x2a, 0x84 }, /* (default) */ + { 0x2b, 0xa8 }, /* Set custom frame rate */ + { 0x2c, 0xa0 }, /* (reserved) */ + { 0x2d, 0x95 }, /* Enable banding filter */ + { 0x2e, 0x88 }, /* V offset */ + { 0x33, 0x22 }, /* Luminance gamma on */ + { 0x34, 0xc7 }, /* A/D bias */ + { 0x36, 0x12 }, /* (reserved) */ + { 0x37, 0x63 }, /* (reserved) */ + { 0x38, 0x8b }, /* Quick AEC/AEB */ + { 0x39, 0x00 }, /* (default) */ + { 0x3a, 0x0f }, /* (default) */ + { 0x3b, 0x3c }, /* (default) */ + { 0x3c, 0x5c }, /* AEC controls */ + { 0x3d, 0x80 }, /* Drop 1 (bad) frame when AEC change */ + { 0x3e, 0x80 }, /* (default) */ + { 0x3f, 0x02 }, /* (default) */ + { 0x40, 0x10 }, /* (reserved) */ + { 0x41, 0x10 }, /* (reserved) */ + { 0x42, 0x00 }, /* (reserved) */ + { 0x43, 0x7f }, /* (reserved) */ + { 0x44, 0x80 }, /* (reserved) */ + { 0x45, 0x1c }, /* (reserved) */ + { 0x46, 0x1c }, /* (reserved) */ + { 0x47, 0x80 }, /* (reserved) */ + { 0x48, 0x5f }, /* (reserved) */ + { 0x49, 0x00 }, /* (reserved) */ + { 0x4a, 0x00 }, /* Color balance (undocumented) */ + { 0x4b, 0x80 }, /* Color balance (undocumented) */ + { 0x4c, 0x58 }, /* (reserved) */ + { 0x4d, 0xd2 }, /* U *= .938, V *= .838 */ + { 0x4e, 0xa0 }, /* (default) */ + { 0x4f, 0x04 }, /* UV 3-point average */ + { 0x50, 0xff }, /* (reserved) */ + { 0x51, 0x58 }, /* (reserved) */ + { 0x52, 0xc0 }, /* (reserved) */ + { 0x53, 0x42 }, /* (reserved) */ + { 0x27, 0xa6 }, /* Enable manual offset adj. (reg 21 & 22) */ + { 0x12, 0x20 }, + { 0x12, 0x24 }, + + { 0xff, 0xff }, /* END MARKER */ +}; + +/* This initializes the OV6x20 camera chip and relevant variables. */ +static int ov6x20_init(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov6x20 *s; + int rc; + + DDEBUG(4, &c->dev, "entered"); + + switch (c->adapter->id) { + case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511: + rc = ov_write_regvals(c, regvals_init_6x20_511); + break; + case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518: + rc = ov_write_regvals(c, regvals_init_6x20_518); + break; + default: + dev_err(&c->dev, "ov6x20: Unsupported adapter\n"); + rc = -ENODEV; + } + + if (rc < 0) + return rc; + + ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL); + if (!s) + return -ENOMEM; + memset(s, 0, sizeof *s); + + s->auto_brt = 1; + s->auto_exp = 1; + + return rc; +} + +static int ov6x20_free(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + + kfree(ov->spriv); + return 0; +} + +static int ov6x20_set_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov6x20 *s = ov->spriv; + int rc; + int v = ctl->value; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + rc = ov_write(c, REG_CNT, v >> 8); + break; + case OVCAMCHIP_CID_BRIGHT: + rc = ov_write(c, REG_BRT, v >> 8); + break; + case OVCAMCHIP_CID_SAT: + rc = ov_write(c, REG_SAT, v >> 8); + break; + case OVCAMCHIP_CID_HUE: + rc = ov_write(c, REG_RED, 0xFF - (v >> 8)); + if (rc < 0) + goto out; + + rc = ov_write(c, REG_BLUE, v >> 8); + break; + case OVCAMCHIP_CID_EXP: + rc = ov_write(c, REG_EXP, v); + break; + case OVCAMCHIP_CID_FREQ: + { + int sixty = (v == 60); + + rc = ov_write(c, 0x2b, sixty?0xa8:0x28); + if (rc < 0) + goto out; + + rc = ov_write(c, 0x2a, sixty?0x84:0xa4); + break; + } + case OVCAMCHIP_CID_BANDFILT: + rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04); + s->bandfilt = v; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10); + s->auto_brt = v; + break; + case OVCAMCHIP_CID_AUTOEXP: + rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01); + s->auto_exp = v; + break; + case OVCAMCHIP_CID_BACKLIGHT: + { + rc = ov_write_mask(c, 0x4e, v?0xe0:0xc0, 0xe0); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x0e, v?0x80:0x00, 0x80); + s->backlight = v; + break; + } + case OVCAMCHIP_CID_MIRROR: + rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40); + s->mirror = v; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + +out: + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc); + return rc; +} + +static int ov6x20_get_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov6x20 *s = ov->spriv; + int rc = 0; + unsigned char val = 0; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + rc = ov_read(c, REG_CNT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_BRIGHT: + rc = ov_read(c, REG_BRT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_SAT: + rc = ov_read(c, REG_SAT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_HUE: + rc = ov_read(c, REG_BLUE, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_EXP: + rc = ov_read(c, REG_EXP, &val); + ctl->value = val; + break; + case OVCAMCHIP_CID_BANDFILT: + ctl->value = s->bandfilt; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + ctl->value = s->auto_brt; + break; + case OVCAMCHIP_CID_AUTOEXP: + ctl->value = s->auto_exp; + break; + case OVCAMCHIP_CID_BACKLIGHT: + ctl->value = s->backlight; + break; + case OVCAMCHIP_CID_MIRROR: + ctl->value = s->mirror; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc); + return rc; +} + +static int ov6x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win) +{ + /******** QCIF-specific regs ********/ + + ov_write(c, 0x14, win->quarter?0x24:0x04); + + /******** Palette-specific regs ********/ + + /* OV518 needs 8 bit multiplexed in color mode, and 16 bit in B&W */ + if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) { + if (win->format == VIDEO_PALETTE_GREY) + ov_write_mask(c, 0x13, 0x00, 0x20); + else + ov_write_mask(c, 0x13, 0x20, 0x20); + } else { + if (win->format == VIDEO_PALETTE_GREY) + ov_write_mask(c, 0x13, 0x20, 0x20); + else + ov_write_mask(c, 0x13, 0x00, 0x20); + } + + /******** Clock programming ********/ + + /* The OV6620 needs special handling. This prevents the + * severe banding that normally occurs */ + + /* Clock down */ + ov_write(c, 0x2a, 0x04); + + ov_write(c, 0x11, win->clockdiv); + + ov_write(c, 0x2a, 0x84); + /* This next setting is critical. It seems to improve + * the gain or the contrast. The "reserved" bits seem + * to have some effect in this case. */ + ov_write(c, 0x2d, 0x85); /* FIXME: This messes up banding filter */ + + return 0; +} + +static int ov6x20_set_window(struct i2c_client *c, struct ovcamchip_window *win) +{ + int ret, hwscale, vwscale; + + ret = ov6x20_mode_init(c, win); + if (ret < 0) + return ret; + + if (win->quarter) { + hwscale = 0; + vwscale = 0; + } else { + hwscale = 1; + vwscale = 1; /* The datasheet says 0; it's wrong */ + } + + ov_write(c, 0x17, HWSBASE + (win->x >> hwscale)); + ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale)); + ov_write(c, 0x19, VWSBASE + (win->y >> vwscale)); + ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale)); + + return 0; +} + +static int ov6x20_command(struct i2c_client *c, unsigned int cmd, void *arg) +{ + switch (cmd) { + case OVCAMCHIP_CMD_S_CTRL: + return ov6x20_set_control(c, arg); + case OVCAMCHIP_CMD_G_CTRL: + return ov6x20_get_control(c, arg); + case OVCAMCHIP_CMD_S_MODE: + return ov6x20_set_window(c, arg); + default: + DDEBUG(2, &c->dev, "command not supported: %d", cmd); + return -ENOIOCTLCMD; + } +} + +struct ovcamchip_ops ov6x20_ops = { + .init = ov6x20_init, + .free = ov6x20_free, + .command = ov6x20_command, +}; diff -Nru a/drivers/media/video/ovcamchip/ov6x30.c b/drivers/media/video/ovcamchip/ov6x30.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/ov6x30.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,374 @@ +/* OmniVision OV6630/OV6130 Camera Chip Support Code + * + * Copyright (c) 1999-2004 Mark McClelland + * http://alpha.dyndns.org/ov511/ + * + * 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. NO WARRANTY OF ANY KIND is expressed or implied. + */ + +#define DEBUG + +#include +#include "ovcamchip_priv.h" + +/* Registers */ +#define REG_GAIN 0x00 /* gain [5:0] */ +#define REG_BLUE 0x01 /* blue gain */ +#define REG_RED 0x02 /* red gain */ +#define REG_SAT 0x03 /* saturation [7:3] */ +#define REG_CNT 0x05 /* Y contrast [3:0] */ +#define REG_BRT 0x06 /* Y brightness */ +#define REG_SHARP 0x07 /* sharpness */ +#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */ +#define REG_WB_RED 0x0D /* WB red ratio [5:0] */ +#define REG_EXP 0x10 /* exposure */ + +/* Window parameters */ +#define HWSBASE 0x38 +#define HWEBASE 0x3A +#define VWSBASE 0x05 +#define VWEBASE 0x06 + +struct ov6x30 { + int auto_brt; + int auto_exp; + int backlight; + int bandfilt; + int mirror; +}; + +static struct ovcamchip_regvals regvals_init_6x30[] = { + { 0x12, 0x80 }, /* reset */ + { 0x00, 0x1f }, /* Gain */ + { 0x01, 0x99 }, /* Blue gain */ + { 0x02, 0x7c }, /* Red gain */ + { 0x03, 0xc0 }, /* Saturation */ + { 0x05, 0x0a }, /* Contrast */ + { 0x06, 0x95 }, /* Brightness */ + { 0x07, 0x2d }, /* Sharpness */ + { 0x0c, 0x20 }, + { 0x0d, 0x20 }, + { 0x0e, 0x20 }, + { 0x0f, 0x05 }, + { 0x10, 0x9a }, /* "exposure check" */ + { 0x11, 0x00 }, /* Pixel clock = fastest */ + { 0x12, 0x24 }, /* Enable AGC and AWB */ + { 0x13, 0x21 }, + { 0x14, 0x80 }, + { 0x15, 0x01 }, + { 0x16, 0x03 }, + { 0x17, 0x38 }, + { 0x18, 0xea }, + { 0x19, 0x04 }, + { 0x1a, 0x93 }, + { 0x1b, 0x00 }, + { 0x1e, 0xc4 }, + { 0x1f, 0x04 }, + { 0x20, 0x20 }, + { 0x21, 0x10 }, + { 0x22, 0x88 }, + { 0x23, 0xc0 }, /* Crystal circuit power level */ + { 0x25, 0x9a }, /* Increase AEC black pixel ratio */ + { 0x26, 0xb2 }, /* BLC enable */ + { 0x27, 0xa2 }, + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x84 }, /* (keep) */ + { 0x2b, 0xa8 }, /* (keep) */ + { 0x2c, 0xa0 }, + { 0x2d, 0x95 }, /* Enable auto-brightness */ + { 0x2e, 0x88 }, + { 0x33, 0x26 }, + { 0x34, 0x03 }, + { 0x36, 0x8f }, + { 0x37, 0x80 }, + { 0x38, 0x83 }, + { 0x39, 0x80 }, + { 0x3a, 0x0f }, + { 0x3b, 0x3c }, + { 0x3c, 0x1a }, + { 0x3d, 0x80 }, + { 0x3e, 0x80 }, + { 0x3f, 0x0e }, + { 0x40, 0x00 }, /* White bal */ + { 0x41, 0x00 }, /* White bal */ + { 0x42, 0x80 }, + { 0x43, 0x3f }, /* White bal */ + { 0x44, 0x80 }, + { 0x45, 0x20 }, + { 0x46, 0x20 }, + { 0x47, 0x80 }, + { 0x48, 0x7f }, + { 0x49, 0x00 }, + { 0x4a, 0x00 }, + { 0x4b, 0x80 }, + { 0x4c, 0xd0 }, + { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ + { 0x4e, 0x40 }, + { 0x4f, 0x07 }, /* UV average mode, color killer: strongest */ + { 0x50, 0xff }, + { 0x54, 0x23 }, /* Max AGC gain: 18dB */ + { 0x55, 0xff }, + { 0x56, 0x12 }, + { 0x57, 0x81 }, /* (default) */ + { 0x58, 0x75 }, + { 0x59, 0x01 }, /* AGC dark current compensation: +1 */ + { 0x5a, 0x2c }, + { 0x5b, 0x0f }, /* AWB chrominance levels */ + { 0x5c, 0x10 }, + { 0x3d, 0x80 }, + { 0x27, 0xa6 }, + /* Toggle AWB off and on */ + { 0x12, 0x20 }, + { 0x12, 0x24 }, + + { 0xff, 0xff }, /* END MARKER */ +}; + +/* This initializes the OV6x30 camera chip and relevant variables. */ +static int ov6x30_init(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov6x30 *s; + int rc; + + DDEBUG(4, &c->dev, "entered"); + + rc = ov_write_regvals(c, regvals_init_6x30); + if (rc < 0) + return rc; + + ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL); + if (!s) + return -ENOMEM; + memset(s, 0, sizeof *s); + + s->auto_brt = 1; + s->auto_exp = 1; + + return rc; +} + +static int ov6x30_free(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + + kfree(ov->spriv); + return 0; +} + +static int ov6x30_set_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov6x30 *s = ov->spriv; + int rc; + int v = ctl->value; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + rc = ov_write_mask(c, REG_CNT, v >> 12, 0x0f); + break; + case OVCAMCHIP_CID_BRIGHT: + rc = ov_write(c, REG_BRT, v >> 8); + break; + case OVCAMCHIP_CID_SAT: + rc = ov_write(c, REG_SAT, v >> 8); + break; + case OVCAMCHIP_CID_HUE: + rc = ov_write(c, REG_RED, 0xFF - (v >> 8)); + if (rc < 0) + goto out; + + rc = ov_write(c, REG_BLUE, v >> 8); + break; + case OVCAMCHIP_CID_EXP: + rc = ov_write(c, REG_EXP, v); + break; + case OVCAMCHIP_CID_FREQ: + { + int sixty = (v == 60); + + rc = ov_write(c, 0x2b, sixty?0xa8:0x28); + if (rc < 0) + goto out; + + rc = ov_write(c, 0x2a, sixty?0x84:0xa4); + break; + } + case OVCAMCHIP_CID_BANDFILT: + rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04); + s->bandfilt = v; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10); + s->auto_brt = v; + break; + case OVCAMCHIP_CID_AUTOEXP: + rc = ov_write_mask(c, 0x28, v?0x00:0x10, 0x10); + s->auto_exp = v; + break; + case OVCAMCHIP_CID_BACKLIGHT: + { + rc = ov_write_mask(c, 0x4e, v?0x80:0x60, 0xe0); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02); + s->backlight = v; + break; + } + case OVCAMCHIP_CID_MIRROR: + rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40); + s->mirror = v; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + +out: + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc); + return rc; +} + +static int ov6x30_get_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov6x30 *s = ov->spriv; + int rc = 0; + unsigned char val = 0; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + rc = ov_read(c, REG_CNT, &val); + ctl->value = (val & 0x0f) << 12; + break; + case OVCAMCHIP_CID_BRIGHT: + rc = ov_read(c, REG_BRT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_SAT: + rc = ov_read(c, REG_SAT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_HUE: + rc = ov_read(c, REG_BLUE, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_EXP: + rc = ov_read(c, REG_EXP, &val); + ctl->value = val; + break; + case OVCAMCHIP_CID_BANDFILT: + ctl->value = s->bandfilt; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + ctl->value = s->auto_brt; + break; + case OVCAMCHIP_CID_AUTOEXP: + ctl->value = s->auto_exp; + break; + case OVCAMCHIP_CID_BACKLIGHT: + ctl->value = s->backlight; + break; + case OVCAMCHIP_CID_MIRROR: + ctl->value = s->mirror; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc); + return rc; +} + +static int ov6x30_mode_init(struct i2c_client *c, struct ovcamchip_window *win) +{ + /******** QCIF-specific regs ********/ + + ov_write_mask(c, 0x14, win->quarter?0x20:0x00, 0x20); + + /******** Palette-specific regs ********/ + + if (win->format == VIDEO_PALETTE_GREY) { + if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) { + /* Do nothing - we're already in 8-bit mode */ + } else { + ov_write_mask(c, 0x13, 0x20, 0x20); + } + } else { + /* The OV518 needs special treatment. Although both the OV518 + * and the OV6630 support a 16-bit video bus, only the 8 bit Y + * bus is actually used. The UV bus is tied to ground. + * Therefore, the OV6630 needs to be in 8-bit multiplexed + * output mode */ + + if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) { + /* Do nothing - we want to stay in 8-bit mode */ + /* Warning: Messing with reg 0x13 breaks OV518 color */ + } else { + ov_write_mask(c, 0x13, 0x00, 0x20); + } + } + + /******** Clock programming ********/ + + ov_write(c, 0x11, win->clockdiv); + + return 0; +} + +static int ov6x30_set_window(struct i2c_client *c, struct ovcamchip_window *win) +{ + int ret, hwscale, vwscale; + + ret = ov6x30_mode_init(c, win); + if (ret < 0) + return ret; + + if (win->quarter) { + hwscale = 0; + vwscale = 0; + } else { + hwscale = 1; + vwscale = 1; /* The datasheet says 0; it's wrong */ + } + + ov_write(c, 0x17, HWSBASE + (win->x >> hwscale)); + ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale)); + ov_write(c, 0x19, VWSBASE + (win->y >> vwscale)); + ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale)); + + return 0; +} + +static int ov6x30_command(struct i2c_client *c, unsigned int cmd, void *arg) +{ + switch (cmd) { + case OVCAMCHIP_CMD_S_CTRL: + return ov6x30_set_control(c, arg); + case OVCAMCHIP_CMD_G_CTRL: + return ov6x30_get_control(c, arg); + case OVCAMCHIP_CMD_S_MODE: + return ov6x30_set_window(c, arg); + default: + DDEBUG(2, &c->dev, "command not supported: %d", cmd); + return -ENOIOCTLCMD; + } +} + +struct ovcamchip_ops ov6x30_ops = { + .init = ov6x30_init, + .free = ov6x30_free, + .command = ov6x30_command, +}; diff -Nru a/drivers/media/video/ovcamchip/ov76be.c b/drivers/media/video/ovcamchip/ov76be.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/ov76be.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,303 @@ +/* OmniVision OV76BE Camera Chip Support Code + * + * Copyright (c) 1999-2004 Mark McClelland + * http://alpha.dyndns.org/ov511/ + * + * 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. NO WARRANTY OF ANY KIND is expressed or implied. + */ + +#define DEBUG + +#include +#include "ovcamchip_priv.h" + +/* OV7610 registers: Since the OV76BE is undocumented, we'll settle for these + * for now. */ +#define REG_GAIN 0x00 /* gain [5:0] */ +#define REG_BLUE 0x01 /* blue channel balance */ +#define REG_RED 0x02 /* red channel balance */ +#define REG_SAT 0x03 /* saturation */ +#define REG_CNT 0x05 /* Y contrast */ +#define REG_BRT 0x06 /* Y brightness */ +#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */ +#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */ +#define REG_GAMMA_COEFF 0x0E /* gamma settings */ +#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */ +#define REG_EXP 0x10 /* manual exposure setting */ +#define REG_CLOCK 0x11 /* polarity/clock prescaler */ +#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */ +#define REG_HWIN_START 0x17 /* horizontal window start */ +#define REG_HWIN_END 0x18 /* horizontal window end */ +#define REG_VWIN_START 0x19 /* vertical window start */ +#define REG_VWIN_END 0x1A /* vertical window end */ +#define REG_PIXEL_SHIFT 0x1B /* pixel shift */ +#define REG_YOFFSET 0x21 /* Y channel offset */ +#define REG_UOFFSET 0x22 /* U channel offset */ +#define REG_ECW 0x24 /* exposure white level for AEC */ +#define REG_ECB 0x25 /* exposure black level for AEC */ +#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */ +#define REG_FRAMERATE_L 0x2B /* frame rate LSB */ +#define REG_ALC 0x2C /* Auto Level Control settings */ +#define REG_VOFFSET 0x2E /* V channel offset adjustment */ +#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */ +#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */ +#define REG_BIAS_ADJUST 0x34 /* misc bias settings */ + +/* Window parameters */ +#define HWSBASE 0x38 +#define HWEBASE 0x3a +#define VWSBASE 0x05 +#define VWEBASE 0x05 + +struct ov76be { + int auto_brt; + int auto_exp; + int bandfilt; + int mirror; +}; + +/* NOTE: These are the same as the 7x10 settings, but should eventually be + * optimized for the OV76BE */ +static struct ovcamchip_regvals regvals_init_76be[] = { + { 0x10, 0xff }, + { 0x16, 0x03 }, + { 0x28, 0x24 }, + { 0x2b, 0xac }, + { 0x12, 0x00 }, + { 0x38, 0x81 }, + { 0x28, 0x24 }, /* 0c */ + { 0x0f, 0x85 }, /* lg's setting */ + { 0x15, 0x01 }, + { 0x20, 0x1c }, + { 0x23, 0x2a }, + { 0x24, 0x10 }, + { 0x25, 0x8a }, + { 0x26, 0xa2 }, + { 0x27, 0xc2 }, + { 0x2a, 0x04 }, + { 0x2c, 0xfe }, + { 0x2d, 0x93 }, + { 0x30, 0x71 }, + { 0x31, 0x60 }, + { 0x32, 0x26 }, + { 0x33, 0x20 }, + { 0x34, 0x48 }, + { 0x12, 0x24 }, + { 0x11, 0x01 }, + { 0x0c, 0x24 }, + { 0x0d, 0x24 }, + { 0xff, 0xff }, /* END MARKER */ +}; + +/* This initializes the OV76be camera chip and relevant variables. */ +static int ov76be_init(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov76be *s; + int rc; + + DDEBUG(4, &c->dev, "entered"); + + rc = ov_write_regvals(c, regvals_init_76be); + if (rc < 0) + return rc; + + ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL); + if (!s) + return -ENOMEM; + memset(s, 0, sizeof *s); + + s->auto_brt = 1; + s->auto_exp = 1; + + return rc; +} + +static int ov76be_free(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + + kfree(ov->spriv); + return 0; +} + +static int ov76be_set_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov76be *s = ov->spriv; + int rc; + int v = ctl->value; + + switch (ctl->id) { + case OVCAMCHIP_CID_BRIGHT: + rc = ov_write(c, REG_BRT, v >> 8); + break; + case OVCAMCHIP_CID_SAT: + rc = ov_write(c, REG_SAT, v >> 8); + break; + case OVCAMCHIP_CID_EXP: + rc = ov_write(c, REG_EXP, v); + break; + case OVCAMCHIP_CID_FREQ: + { + int sixty = (v == 60); + + rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80); + if (rc < 0) + goto out; + + rc = ov_write(c, 0x2b, sixty?0x00:0xac); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x76, 0x01, 0x01); + break; + } + case OVCAMCHIP_CID_BANDFILT: + rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04); + s->bandfilt = v; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10); + s->auto_brt = v; + break; + case OVCAMCHIP_CID_AUTOEXP: + rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01); + s->auto_exp = v; + break; + case OVCAMCHIP_CID_MIRROR: + rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40); + s->mirror = v; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + +out: + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc); + return rc; +} + +static int ov76be_get_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov76be *s = ov->spriv; + int rc = 0; + unsigned char val = 0; + + switch (ctl->id) { + case OVCAMCHIP_CID_BRIGHT: + rc = ov_read(c, REG_BRT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_SAT: + rc = ov_read(c, REG_SAT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_EXP: + rc = ov_read(c, REG_EXP, &val); + ctl->value = val; + break; + case OVCAMCHIP_CID_BANDFILT: + ctl->value = s->bandfilt; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + ctl->value = s->auto_brt; + break; + case OVCAMCHIP_CID_AUTOEXP: + ctl->value = s->auto_exp; + break; + case OVCAMCHIP_CID_MIRROR: + ctl->value = s->mirror; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc); + return rc; +} + +static int ov76be_mode_init(struct i2c_client *c, struct ovcamchip_window *win) +{ + int qvga = win->quarter; + + /******** QVGA-specific regs ********/ + + ov_write(c, 0x14, qvga?0xa4:0x84); + + /******** Palette-specific regs ********/ + + if (win->format == VIDEO_PALETTE_GREY) { + ov_write_mask(c, 0x0e, 0x40, 0x40); + ov_write_mask(c, 0x13, 0x20, 0x20); + } else { + ov_write_mask(c, 0x0e, 0x00, 0x40); + ov_write_mask(c, 0x13, 0x00, 0x20); + } + + /******** Clock programming ********/ + + ov_write(c, 0x11, win->clockdiv); + + /******** Resolution-specific ********/ + + if (win->width == 640 && win->height == 480) + ov_write(c, 0x35, 0x9e); + else + ov_write(c, 0x35, 0x1e); + + return 0; +} + +static int ov76be_set_window(struct i2c_client *c, struct ovcamchip_window *win) +{ + int ret, hwscale, vwscale; + + ret = ov76be_mode_init(c, win); + if (ret < 0) + return ret; + + if (win->quarter) { + hwscale = 1; + vwscale = 0; + } else { + hwscale = 2; + vwscale = 1; + } + + ov_write(c, 0x17, HWSBASE + (win->x >> hwscale)); + ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale)); + ov_write(c, 0x19, VWSBASE + (win->y >> vwscale)); + ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale)); + + return 0; +} + +static int ov76be_command(struct i2c_client *c, unsigned int cmd, void *arg) +{ + switch (cmd) { + case OVCAMCHIP_CMD_S_CTRL: + return ov76be_set_control(c, arg); + case OVCAMCHIP_CMD_G_CTRL: + return ov76be_get_control(c, arg); + case OVCAMCHIP_CMD_S_MODE: + return ov76be_set_window(c, arg); + default: + DDEBUG(2, &c->dev, "command not supported: %d", cmd); + return -ENOIOCTLCMD; + } +} + +struct ovcamchip_ops ov76be_ops = { + .init = ov76be_init, + .free = ov76be_free, + .command = ov76be_command, +}; diff -Nru a/drivers/media/video/ovcamchip/ov7x10.c b/drivers/media/video/ovcamchip/ov7x10.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/ov7x10.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,335 @@ +/* OmniVision OV7610/OV7110 Camera Chip Support Code + * + * Copyright (c) 1999-2004 Mark McClelland + * http://alpha.dyndns.org/ov511/ + * + * Color fixes by by Orion Sky Lawlor (2/26/2000) + * + * 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. NO WARRANTY OF ANY KIND is expressed or implied. + */ + +#define DEBUG + +#include +#include "ovcamchip_priv.h" + +/* Registers */ +#define REG_GAIN 0x00 /* gain [5:0] */ +#define REG_BLUE 0x01 /* blue channel balance */ +#define REG_RED 0x02 /* red channel balance */ +#define REG_SAT 0x03 /* saturation */ +#define REG_CNT 0x05 /* Y contrast */ +#define REG_BRT 0x06 /* Y brightness */ +#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */ +#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */ +#define REG_GAMMA_COEFF 0x0E /* gamma settings */ +#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */ +#define REG_EXP 0x10 /* manual exposure setting */ +#define REG_CLOCK 0x11 /* polarity/clock prescaler */ +#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */ +#define REG_HWIN_START 0x17 /* horizontal window start */ +#define REG_HWIN_END 0x18 /* horizontal window end */ +#define REG_VWIN_START 0x19 /* vertical window start */ +#define REG_VWIN_END 0x1A /* vertical window end */ +#define REG_PIXEL_SHIFT 0x1B /* pixel shift */ +#define REG_YOFFSET 0x21 /* Y channel offset */ +#define REG_UOFFSET 0x22 /* U channel offset */ +#define REG_ECW 0x24 /* exposure white level for AEC */ +#define REG_ECB 0x25 /* exposure black level for AEC */ +#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */ +#define REG_FRAMERATE_L 0x2B /* frame rate LSB */ +#define REG_ALC 0x2C /* Auto Level Control settings */ +#define REG_VOFFSET 0x2E /* V channel offset adjustment */ +#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */ +#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */ +#define REG_BIAS_ADJUST 0x34 /* misc bias settings */ + +/* Window parameters */ +#define HWSBASE 0x38 +#define HWEBASE 0x3a +#define VWSBASE 0x05 +#define VWEBASE 0x05 + +struct ov7x10 { + int auto_brt; + int auto_exp; + int bandfilt; + int mirror; +}; + +/* Lawrence Glaister reports: + * + * Register 0x0f in the 7610 has the following effects: + * + * 0x85 (AEC method 1): Best overall, good contrast range + * 0x45 (AEC method 2): Very overexposed + * 0xa5 (spec sheet default): Ok, but the black level is + * shifted resulting in loss of contrast + * 0x05 (old driver setting): very overexposed, too much + * contrast + */ +static struct ovcamchip_regvals regvals_init_7x10[] = { + { 0x10, 0xff }, + { 0x16, 0x03 }, + { 0x28, 0x24 }, + { 0x2b, 0xac }, + { 0x12, 0x00 }, + { 0x38, 0x81 }, + { 0x28, 0x24 }, /* 0c */ + { 0x0f, 0x85 }, /* lg's setting */ + { 0x15, 0x01 }, + { 0x20, 0x1c }, + { 0x23, 0x2a }, + { 0x24, 0x10 }, + { 0x25, 0x8a }, + { 0x26, 0xa2 }, + { 0x27, 0xc2 }, + { 0x2a, 0x04 }, + { 0x2c, 0xfe }, + { 0x2d, 0x93 }, + { 0x30, 0x71 }, + { 0x31, 0x60 }, + { 0x32, 0x26 }, + { 0x33, 0x20 }, + { 0x34, 0x48 }, + { 0x12, 0x24 }, + { 0x11, 0x01 }, + { 0x0c, 0x24 }, + { 0x0d, 0x24 }, + { 0xff, 0xff }, /* END MARKER */ +}; + +/* This initializes the OV7x10 camera chip and relevant variables. */ +static int ov7x10_init(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov7x10 *s; + int rc; + + DDEBUG(4, &c->dev, "entered"); + + rc = ov_write_regvals(c, regvals_init_7x10); + if (rc < 0) + return rc; + + ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL); + if (!s) + return -ENOMEM; + memset(s, 0, sizeof *s); + + s->auto_brt = 1; + s->auto_exp = 1; + + return rc; +} + +static int ov7x10_free(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + + kfree(ov->spriv); + return 0; +} + +static int ov7x10_set_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov7x10 *s = ov->spriv; + int rc; + int v = ctl->value; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + rc = ov_write(c, REG_CNT, v >> 8); + break; + case OVCAMCHIP_CID_BRIGHT: + rc = ov_write(c, REG_BRT, v >> 8); + break; + case OVCAMCHIP_CID_SAT: + rc = ov_write(c, REG_SAT, v >> 8); + break; + case OVCAMCHIP_CID_HUE: + rc = ov_write(c, REG_RED, 0xFF - (v >> 8)); + if (rc < 0) + goto out; + + rc = ov_write(c, REG_BLUE, v >> 8); + break; + case OVCAMCHIP_CID_EXP: + rc = ov_write(c, REG_EXP, v); + break; + case OVCAMCHIP_CID_FREQ: + { + int sixty = (v == 60); + + rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80); + if (rc < 0) + goto out; + + rc = ov_write(c, 0x2b, sixty?0x00:0xac); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x13, 0x10, 0x10); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x13, 0x00, 0x10); + break; + } + case OVCAMCHIP_CID_BANDFILT: + rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04); + s->bandfilt = v; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10); + s->auto_brt = v; + break; + case OVCAMCHIP_CID_AUTOEXP: + rc = ov_write_mask(c, 0x29, v?0x00:0x80, 0x80); + s->auto_exp = v; + break; + case OVCAMCHIP_CID_MIRROR: + rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40); + s->mirror = v; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + +out: + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc); + return rc; +} + +static int ov7x10_get_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov7x10 *s = ov->spriv; + int rc = 0; + unsigned char val = 0; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + rc = ov_read(c, REG_CNT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_BRIGHT: + rc = ov_read(c, REG_BRT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_SAT: + rc = ov_read(c, REG_SAT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_HUE: + rc = ov_read(c, REG_BLUE, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_EXP: + rc = ov_read(c, REG_EXP, &val); + ctl->value = val; + break; + case OVCAMCHIP_CID_BANDFILT: + ctl->value = s->bandfilt; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + ctl->value = s->auto_brt; + break; + case OVCAMCHIP_CID_AUTOEXP: + ctl->value = s->auto_exp; + break; + case OVCAMCHIP_CID_MIRROR: + ctl->value = s->mirror; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc); + return rc; +} + +static int ov7x10_mode_init(struct i2c_client *c, struct ovcamchip_window *win) +{ + int qvga = win->quarter; + + /******** QVGA-specific regs ********/ + + ov_write(c, 0x14, qvga?0x24:0x04); + + /******** Palette-specific regs ********/ + + if (win->format == VIDEO_PALETTE_GREY) { + ov_write_mask(c, 0x0e, 0x40, 0x40); + ov_write_mask(c, 0x13, 0x20, 0x20); + } else { + ov_write_mask(c, 0x0e, 0x00, 0x40); + ov_write_mask(c, 0x13, 0x00, 0x20); + } + + /******** Clock programming ********/ + + ov_write(c, 0x11, win->clockdiv); + + /******** Resolution-specific ********/ + + if (win->width == 640 && win->height == 480) + ov_write(c, 0x35, 0x9e); + else + ov_write(c, 0x35, 0x1e); + + return 0; +} + +static int ov7x10_set_window(struct i2c_client *c, struct ovcamchip_window *win) +{ + int ret, hwscale, vwscale; + + ret = ov7x10_mode_init(c, win); + if (ret < 0) + return ret; + + if (win->quarter) { + hwscale = 1; + vwscale = 0; + } else { + hwscale = 2; + vwscale = 1; + } + + ov_write(c, 0x17, HWSBASE + (win->x >> hwscale)); + ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale)); + ov_write(c, 0x19, VWSBASE + (win->y >> vwscale)); + ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale)); + + return 0; +} + +static int ov7x10_command(struct i2c_client *c, unsigned int cmd, void *arg) +{ + switch (cmd) { + case OVCAMCHIP_CMD_S_CTRL: + return ov7x10_set_control(c, arg); + case OVCAMCHIP_CMD_G_CTRL: + return ov7x10_get_control(c, arg); + case OVCAMCHIP_CMD_S_MODE: + return ov7x10_set_window(c, arg); + default: + DDEBUG(2, &c->dev, "command not supported: %d", cmd); + return -ENOIOCTLCMD; + } +} + +struct ovcamchip_ops ov7x10_ops = { + .init = ov7x10_init, + .free = ov7x10_free, + .command = ov7x10_command, +}; diff -Nru a/drivers/media/video/ovcamchip/ov7x20.c b/drivers/media/video/ovcamchip/ov7x20.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/ov7x20.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,455 @@ +/* OmniVision OV7620/OV7120 Camera Chip Support Code + * + * Copyright (c) 1999-2004 Mark McClelland + * http://alpha.dyndns.org/ov511/ + * + * OV7620 fixes by Charl P. Botha + * + * 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. NO WARRANTY OF ANY KIND is expressed or implied. + */ + +#define DEBUG + +#include +#include "ovcamchip_priv.h" + +/* Registers */ +#define REG_GAIN 0x00 /* gain [5:0] */ +#define REG_BLUE 0x01 /* blue gain */ +#define REG_RED 0x02 /* red gain */ +#define REG_SAT 0x03 /* saturation */ +#define REG_BRT 0x06 /* Y brightness */ +#define REG_SHARP 0x07 /* analog sharpness */ +#define REG_BLUE_BIAS 0x0C /* WB blue ratio [5:0] */ +#define REG_RED_BIAS 0x0D /* WB red ratio [5:0] */ +#define REG_EXP 0x10 /* exposure */ + +/* Default control settings. Values are in terms of V4L2 controls. */ +#define OV7120_DFL_BRIGHT 0x60 +#define OV7620_DFL_BRIGHT 0x60 +#define OV7120_DFL_SAT 0xb0 +#define OV7620_DFL_SAT 0xc0 +#define DFL_AUTO_EXP 1 +#define DFL_AUTO_GAIN 1 +#define OV7120_DFL_GAIN 0x00 +#define OV7620_DFL_GAIN 0x00 +/* NOTE: Since autoexposure is the default, these aren't programmed into the + * OV7x20 chip. They are just here because V4L2 expects a default */ +#define OV7120_DFL_EXP 0x7f +#define OV7620_DFL_EXP 0x7f + +/* Window parameters */ +#define HWSBASE 0x2F /* From 7620.SET (spec is wrong) */ +#define HWEBASE 0x2F +#define VWSBASE 0x05 +#define VWEBASE 0x05 + +struct ov7x20 { + int auto_brt; + int auto_exp; + int auto_gain; + int backlight; + int bandfilt; + int mirror; +}; + +/* Contrast look-up table */ +static unsigned char ctab[] = { + 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, + 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff +}; + +/* Settings for (Black & White) OV7120 camera chip */ +static struct ovcamchip_regvals regvals_init_7120[] = { + { 0x12, 0x80 }, /* reset */ + { 0x13, 0x00 }, /* Autoadjust off */ + { 0x12, 0x20 }, /* Disable AWB */ + { 0x13, DFL_AUTO_GAIN?0x01:0x00 }, /* Autoadjust on (if desired) */ + { 0x00, OV7120_DFL_GAIN }, + { 0x01, 0x80 }, + { 0x02, 0x80 }, + { 0x03, OV7120_DFL_SAT }, + { 0x06, OV7120_DFL_BRIGHT }, + { 0x07, 0x00 }, + { 0x0c, 0x20 }, + { 0x0d, 0x20 }, + { 0x11, 0x01 }, + { 0x14, 0x84 }, + { 0x15, 0x01 }, + { 0x16, 0x03 }, + { 0x17, 0x2f }, + { 0x18, 0xcf }, + { 0x19, 0x06 }, + { 0x1a, 0xf5 }, + { 0x1b, 0x00 }, + { 0x20, 0x08 }, + { 0x21, 0x80 }, + { 0x22, 0x80 }, + { 0x23, 0x00 }, + { 0x26, 0xa0 }, + { 0x27, 0xfa }, + { 0x28, 0x20 }, /* DON'T set bit 6. It is for the OV7620 only */ + { 0x29, DFL_AUTO_EXP?0x00:0x80 }, + { 0x2a, 0x10 }, + { 0x2b, 0x00 }, + { 0x2c, 0x88 }, + { 0x2d, 0x95 }, + { 0x2e, 0x80 }, + { 0x2f, 0x44 }, + { 0x60, 0x20 }, + { 0x61, 0x02 }, + { 0x62, 0x5f }, + { 0x63, 0xd5 }, + { 0x64, 0x57 }, + { 0x65, 0x83 }, /* OV says "don't change this value" */ + { 0x66, 0x55 }, + { 0x67, 0x92 }, + { 0x68, 0xcf }, + { 0x69, 0x76 }, + { 0x6a, 0x22 }, + { 0x6b, 0xe2 }, + { 0x6c, 0x40 }, + { 0x6d, 0x48 }, + { 0x6e, 0x80 }, + { 0x6f, 0x0d }, + { 0x70, 0x89 }, + { 0x71, 0x00 }, + { 0x72, 0x14 }, + { 0x73, 0x54 }, + { 0x74, 0xa0 }, + { 0x75, 0x8e }, + { 0x76, 0x00 }, + { 0x77, 0xff }, + { 0x78, 0x80 }, + { 0x79, 0x80 }, + { 0x7a, 0x80 }, + { 0x7b, 0xe6 }, + { 0x7c, 0x00 }, + { 0x24, 0x3a }, + { 0x25, 0x60 }, + { 0xff, 0xff }, /* END MARKER */ +}; + +/* Settings for (color) OV7620 camera chip */ +static struct ovcamchip_regvals regvals_init_7620[] = { + { 0x12, 0x80 }, /* reset */ + { 0x00, OV7620_DFL_GAIN }, + { 0x01, 0x80 }, + { 0x02, 0x80 }, + { 0x03, OV7620_DFL_SAT }, + { 0x06, OV7620_DFL_BRIGHT }, + { 0x07, 0x00 }, + { 0x0c, 0x24 }, + { 0x0c, 0x24 }, + { 0x0d, 0x24 }, + { 0x11, 0x01 }, + { 0x12, 0x24 }, + { 0x13, DFL_AUTO_GAIN?0x01:0x00 }, + { 0x14, 0x84 }, + { 0x15, 0x01 }, + { 0x16, 0x03 }, + { 0x17, 0x2f }, + { 0x18, 0xcf }, + { 0x19, 0x06 }, + { 0x1a, 0xf5 }, + { 0x1b, 0x00 }, + { 0x20, 0x18 }, + { 0x21, 0x80 }, + { 0x22, 0x80 }, + { 0x23, 0x00 }, + { 0x26, 0xa2 }, + { 0x27, 0xea }, + { 0x28, 0x20 }, + { 0x29, DFL_AUTO_EXP?0x00:0x80 }, + { 0x2a, 0x10 }, + { 0x2b, 0x00 }, + { 0x2c, 0x88 }, + { 0x2d, 0x91 }, + { 0x2e, 0x80 }, + { 0x2f, 0x44 }, + { 0x60, 0x27 }, + { 0x61, 0x02 }, + { 0x62, 0x5f }, + { 0x63, 0xd5 }, + { 0x64, 0x57 }, + { 0x65, 0x83 }, + { 0x66, 0x55 }, + { 0x67, 0x92 }, + { 0x68, 0xcf }, + { 0x69, 0x76 }, + { 0x6a, 0x22 }, + { 0x6b, 0x00 }, + { 0x6c, 0x02 }, + { 0x6d, 0x44 }, + { 0x6e, 0x80 }, + { 0x6f, 0x1d }, + { 0x70, 0x8b }, + { 0x71, 0x00 }, + { 0x72, 0x14 }, + { 0x73, 0x54 }, + { 0x74, 0x00 }, + { 0x75, 0x8e }, + { 0x76, 0x00 }, + { 0x77, 0xff }, + { 0x78, 0x80 }, + { 0x79, 0x80 }, + { 0x7a, 0x80 }, + { 0x7b, 0xe2 }, + { 0x7c, 0x00 }, + { 0xff, 0xff }, /* END MARKER */ +}; + +/* Returns index into the specified look-up table, with 'n' elements, for which + * the value is greater than or equal to "val". If a match isn't found, (n-1) + * is returned. The entries in the table must be in ascending order. */ +static inline int ov7x20_lut_find(unsigned char lut[], int n, unsigned char val) +{ + int i = 0; + + while (lut[i] < val && i < n) + i++; + + return i; +} + +/* This initializes the OV7x20 camera chip and relevant variables. */ +static int ov7x20_init(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov7x20 *s; + int rc; + + DDEBUG(4, &c->dev, "entered"); + + if (ov->mono) + rc = ov_write_regvals(c, regvals_init_7120); + else + rc = ov_write_regvals(c, regvals_init_7620); + + if (rc < 0) + return rc; + + ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL); + if (!s) + return -ENOMEM; + memset(s, 0, sizeof *s); + + s->auto_brt = 1; + s->auto_exp = DFL_AUTO_EXP; + s->auto_gain = DFL_AUTO_GAIN; + + return 0; +} + +static int ov7x20_free(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + + kfree(ov->spriv); + return 0; +} + +static int ov7x20_set_v4l1_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov7x20 *s = ov->spriv; + int rc; + int v = ctl->value; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + { + /* Use Y gamma control instead. Bit 0 enables it. */ + rc = ov_write(c, 0x64, ctab[v >> 12]); + break; + } + case OVCAMCHIP_CID_BRIGHT: + /* 7620 doesn't like manual changes when in auto mode */ + if (!s->auto_brt) + rc = ov_write(c, REG_BRT, v >> 8); + else + rc = 0; + break; + case OVCAMCHIP_CID_SAT: + rc = ov_write(c, REG_SAT, v >> 8); + break; + case OVCAMCHIP_CID_EXP: + if (!s->auto_exp) + rc = ov_write(c, REG_EXP, v); + else + rc = -EBUSY; + break; + case OVCAMCHIP_CID_FREQ: + { + int sixty = (v == 60); + + rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80); + if (rc < 0) + goto out; + + rc = ov_write(c, 0x2b, sixty?0x00:0xac); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x76, 0x01, 0x01); + break; + } + case OVCAMCHIP_CID_BANDFILT: + rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04); + s->bandfilt = v; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10); + s->auto_brt = v; + break; + case OVCAMCHIP_CID_AUTOEXP: + rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01); + s->auto_exp = v; + break; + case OVCAMCHIP_CID_BACKLIGHT: + { + rc = ov_write_mask(c, 0x68, v?0xe0:0xc0, 0xe0); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08); + if (rc < 0) + goto out; + + rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02); + s->backlight = v; + break; + } + case OVCAMCHIP_CID_MIRROR: + rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40); + s->mirror = v; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + +out: + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc); + return rc; +} + +static int ov7x20_get_v4l1_control(struct i2c_client *c, + struct ovcamchip_control *ctl) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + struct ov7x20 *s = ov->spriv; + int rc = 0; + unsigned char val = 0; + + switch (ctl->id) { + case OVCAMCHIP_CID_CONT: + rc = ov_read(c, 0x64, &val); + ctl->value = ov7x20_lut_find(ctab, 16, val) << 12; + break; + case OVCAMCHIP_CID_BRIGHT: + rc = ov_read(c, REG_BRT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_SAT: + rc = ov_read(c, REG_SAT, &val); + ctl->value = val << 8; + break; + case OVCAMCHIP_CID_EXP: + rc = ov_read(c, REG_EXP, &val); + ctl->value = val; + break; + case OVCAMCHIP_CID_BANDFILT: + ctl->value = s->bandfilt; + break; + case OVCAMCHIP_CID_AUTOBRIGHT: + ctl->value = s->auto_brt; + break; + case OVCAMCHIP_CID_AUTOEXP: + ctl->value = s->auto_exp; + break; + case OVCAMCHIP_CID_BACKLIGHT: + ctl->value = s->backlight; + break; + case OVCAMCHIP_CID_MIRROR: + ctl->value = s->mirror; + break; + default: + DDEBUG(2, &c->dev, "control not supported: %d", ctl->id); + return -EPERM; + } + + DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc); + return rc; +} + +static int ov7x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + int qvga = win->quarter; + + /******** QVGA-specific regs ********/ + ov_write_mask(c, 0x14, qvga?0x20:0x00, 0x20); + ov_write_mask(c, 0x28, qvga?0x00:0x20, 0x20); + ov_write(c, 0x24, qvga?0x20:0x3a); + ov_write(c, 0x25, qvga?0x30:0x60); + ov_write_mask(c, 0x2d, qvga?0x40:0x00, 0x40); + if (!ov->mono) + ov_write_mask(c, 0x67, qvga?0xf0:0x90, 0xf0); + ov_write_mask(c, 0x74, qvga?0x20:0x00, 0x20); + + /******** Clock programming ********/ + + ov_write(c, 0x11, win->clockdiv); + + return 0; +} + +static int ov7x20_set_window(struct i2c_client *c, struct ovcamchip_window *win) +{ + int ret, hwscale, vwscale; + + ret = ov7x20_mode_init(c, win); + if (ret < 0) + return ret; + + if (win->quarter) { + hwscale = 1; + vwscale = 0; + } else { + hwscale = 2; + vwscale = 1; + } + + ov_write(c, 0x17, HWSBASE + (win->x >> hwscale)); + ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale)); + ov_write(c, 0x19, VWSBASE + (win->y >> vwscale)); + ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale)); + + return 0; +} + +static int ov7x20_command(struct i2c_client *c, unsigned int cmd, void *arg) +{ + switch (cmd) { + case OVCAMCHIP_CMD_S_CTRL: + return ov7x20_set_v4l1_control(c, arg); + case OVCAMCHIP_CMD_G_CTRL: + return ov7x20_get_v4l1_control(c, arg); + case OVCAMCHIP_CMD_S_MODE: + return ov7x20_set_window(c, arg); + default: + DDEBUG(2, &c->dev, "command not supported: %d", cmd); + return -ENOIOCTLCMD; + } +} + +struct ovcamchip_ops ov7x20_ops = { + .init = ov7x20_init, + .free = ov7x20_free, + .command = ov7x20_command, +}; diff -Nru a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/ovcamchip_core.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,446 @@ +/* Shared Code for OmniVision Camera Chip Drivers + * + * Copyright (c) 2004 Mark McClelland + * http://alpha.dyndns.org/ov511/ + * + * 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. NO WARRANTY OF ANY KIND is expressed or implied. + */ + +#define DEBUG + +#include +#include +#include +#include +#include "ovcamchip_priv.h" + +#define DRIVER_VERSION "v2.27 for Linux 2.6" +#define DRIVER_AUTHOR "Mark McClelland " +#define DRIVER_DESC "OV camera chip I2C driver" + +#define PINFO(fmt, args...) printk(KERN_INFO "ovcamchip: " fmt "\n" , ## args); +#define PERROR(fmt, args...) printk(KERN_ERR "ovcamchip: " fmt "\n" , ## args); + +#ifdef DEBUG +int ovcamchip_debug = 0; +static int debug; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, + "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=all"); +#endif + +/* By default, let bridge driver tell us if chip is monochrome. mono=0 + * will ignore that and always treat chips as color. mono=1 will force + * monochrome mode for all chips. */ +static int mono = -1; +module_param(mono, int, 0); +MODULE_PARM_DESC(mono, + "1=chips are monochrome (OVx1xx), 0=force color, -1=autodetect (default)"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +/* Registers common to all chips, that are needed for detection */ +#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */ +#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */ +#define GENERIC_REG_COM_I 0x29 /* misc ID bits */ + +extern struct ovcamchip_ops ov6x20_ops; +extern struct ovcamchip_ops ov6x30_ops; +extern struct ovcamchip_ops ov7x10_ops; +extern struct ovcamchip_ops ov7x20_ops; +extern struct ovcamchip_ops ov76be_ops; + +static char *chip_names[NUM_CC_TYPES] = { + [CC_UNKNOWN] = "Unknown chip", + [CC_OV76BE] = "OV76BE", + [CC_OV7610] = "OV7610", + [CC_OV7620] = "OV7620", + [CC_OV7620AE] = "OV7620AE", + [CC_OV6620] = "OV6620", + [CC_OV6630] = "OV6630", + [CC_OV6630AE] = "OV6630AE", + [CC_OV6630AF] = "OV6630AF", +}; + +/* Forward declarations */ +static struct i2c_driver driver; +static struct i2c_client client_template; + +/* ----------------------------------------------------------------------- */ + +int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals) +{ + int rc; + + while (rvals->reg != 0xff) { + rc = ov_write(c, rvals->reg, rvals->val); + if (rc < 0) + return rc; + rvals++; + } + + return 0; +} + +/* Writes bits at positions specified by mask to an I2C reg. Bits that are in + * the same position as 1's in "mask" are cleared and set to "value". Bits + * that are in the same position as 0's in "mask" are preserved, regardless + * of their respective state in "value". + */ +int ov_write_mask(struct i2c_client *c, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int rc; + unsigned char oldval, newval; + + if (mask == 0xff) { + newval = value; + } else { + rc = ov_read(c, reg, &oldval); + if (rc < 0) + return rc; + + oldval &= (~mask); /* Clear the masked bits */ + value &= mask; /* Enforce mask on value */ + newval = oldval | value; /* Set the desired bits */ + } + + return ov_write(c, reg, newval); +} + +/* ----------------------------------------------------------------------- */ + +/* Reset the chip and ensure that I2C is synchronized. Returns <0 if failure. + */ +static int init_camchip(struct i2c_client *c) +{ + int i, success; + unsigned char high, low; + + /* Reset the chip */ + ov_write(c, 0x12, 0x80); + + /* Wait for it to initialize */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1 + 150 * HZ / 1000); + + for (i = 0, success = 0; i < I2C_DETECT_RETRIES && !success; i++) { + if (ov_read(c, GENERIC_REG_ID_HIGH, &high) >= 0) { + if (ov_read(c, GENERIC_REG_ID_LOW, &low) >= 0) { + if (high == 0x7F && low == 0xA2) { + success = 1; + continue; + } + } + } + + /* Reset the chip */ + ov_write(c, 0x12, 0x80); + + /* Wait for it to initialize */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1 + 150 * HZ / 1000); + + /* Dummy read to sync I2C */ + ov_read(c, 0x00, &low); + } + + if (!success) + return -EIO; + + PDEBUG(1, "I2C synced in %d attempt(s)", i); + + return 0; +} + +/* This detects the OV7610, OV7620, or OV76BE chip. */ +static int ov7xx0_detect(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + int rc; + unsigned char val; + + PDEBUG(4, ""); + + /* Detect chip (sub)type */ + rc = ov_read(c, GENERIC_REG_COM_I, &val); + if (rc < 0) { + PERROR("Error detecting ov7xx0 type"); + return rc; + } + + if ((val & 3) == 3) { + PINFO("Camera chip is an OV7610"); + ov->subtype = CC_OV7610; + } else if ((val & 3) == 1) { + rc = ov_read(c, 0x15, &val); + if (rc < 0) { + PERROR("Error detecting ov7xx0 type"); + return rc; + } + + if (val & 1) { + PINFO("Camera chip is an OV7620AE"); + /* OV7620 is a close enough match for now. There are + * some definite differences though, so this should be + * fixed */ + ov->subtype = CC_OV7620; + } else { + PINFO("Camera chip is an OV76BE"); + ov->subtype = CC_OV76BE; + } + } else if ((val & 3) == 0) { + PINFO("Camera chip is an OV7620"); + ov->subtype = CC_OV7620; + } else { + PERROR("Unknown camera chip version: %d", val & 3); + return -ENOSYS; + } + + if (ov->subtype == CC_OV76BE) + ov->sops = &ov76be_ops; + else if (ov->subtype == CC_OV7620) + ov->sops = &ov7x20_ops; + else + ov->sops = &ov7x10_ops; + + return 0; +} + +/* This detects the OV6620, OV6630, OV6630AE, or OV6630AF chip. */ +static int ov6xx0_detect(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + int rc; + unsigned char val; + + PDEBUG(4, ""); + + /* Detect chip (sub)type */ + rc = ov_read(c, GENERIC_REG_COM_I, &val); + if (rc < 0) { + PERROR("Error detecting ov6xx0 type"); + return -1; + } + + if ((val & 3) == 0) { + ov->subtype = CC_OV6630; + PINFO("Camera chip is an OV6630"); + } else if ((val & 3) == 1) { + ov->subtype = CC_OV6620; + PINFO("Camera chip is an OV6620"); + } else if ((val & 3) == 2) { + ov->subtype = CC_OV6630; + PINFO("Camera chip is an OV6630AE"); + } else if ((val & 3) == 3) { + ov->subtype = CC_OV6630; + PINFO("Camera chip is an OV6630AF"); + } + + if (ov->subtype == CC_OV6620) + ov->sops = &ov6x20_ops; + else + ov->sops = &ov6x30_ops; + + return 0; +} + +static int ovcamchip_detect(struct i2c_client *c) +{ + /* Ideally we would just try a single register write and see if it NAKs. + * That isn't possible since the OV518 can't report I2C transaction + * failures. So, we have to try to initialize the chip (i.e. reset it + * and check the ID registers) to detect its presence. */ + + /* Test for 7xx0 */ + PDEBUG(3, "Testing for 0V7xx0"); + c->addr = OV7xx0_SID; + if (init_camchip(c) < 0) { + /* Test for 6xx0 */ + PDEBUG(3, "Testing for 0V6xx0"); + c->addr = OV6xx0_SID; + if (init_camchip(c) < 0) { + return -ENODEV; + } else { + if (ov6xx0_detect(c) < 0) { + PERROR("Failed to init OV6xx0"); + return -EIO; + } + } + } else { + if (ov7xx0_detect(c) < 0) { + PERROR("Failed to init OV7xx0"); + return -EIO; + } + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static int ovcamchip_attach(struct i2c_adapter *adap) +{ + int rc = 0; + struct ovcamchip *ov; + struct i2c_client *c; + + /* I2C is not a PnP bus, so we can never be certain that we're talking + * to the right chip. To prevent damage to EEPROMS and such, only + * attach to adapters that are known to contain OV camera chips. */ + + switch (adap->id) { + case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511): + case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518): + case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OVFX2): + case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF): + PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id); + break; + default: + PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id); + return -ENODEV; + } + + c = kmalloc(sizeof *c, GFP_KERNEL); + if (!c) { + rc = -ENOMEM; + goto no_client; + } + memcpy(c, &client_template, sizeof *c); + c->adapter = adap; + strcpy(i2c_clientname(c), "OV????"); + + ov = kmalloc(sizeof *ov, GFP_KERNEL); + if (!ov) { + rc = -ENOMEM; + goto no_ov; + } + memset(ov, 0, sizeof *ov); + i2c_set_clientdata(c, ov); + + rc = ovcamchip_detect(c); + if (rc < 0) + goto error; + + strcpy(i2c_clientname(c), chip_names[ov->subtype]); + + PDEBUG(1, "Camera chip detection complete"); + + i2c_attach_client(c); + + return rc; +error: + kfree(ov); +no_ov: + kfree(c); +no_client: + PDEBUG(1, "returning %d", rc); + return rc; +} + +static int ovcamchip_detach(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + int rc; + + rc = ov->sops->free(c); + if (rc < 0) + return rc; + + i2c_detach_client(c); + + kfree(ov); + kfree(c); + return 0; +} + +static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + + if (!ov->initialized && + cmd != OVCAMCHIP_CMD_Q_SUBTYPE && + cmd != OVCAMCHIP_CMD_INITIALIZE) { + dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n"); + return -EPERM; + } + + switch (cmd) { + case OVCAMCHIP_CMD_Q_SUBTYPE: + { + *(int *)arg = ov->subtype; + return 0; + } + case OVCAMCHIP_CMD_INITIALIZE: + { + int rc; + + if (mono == -1) + ov->mono = *(int *)arg; + else + ov->mono = mono; + + if (ov->mono) { + if (ov->subtype != CC_OV7620) + dev_warn(&c->dev, "Warning: Monochrome not " + "implemented for this chip\n"); + else + dev_info(&c->dev, "Initializing chip as " + "monochrome\n"); + } + + rc = ov->sops->init(c); + if (rc < 0) + return rc; + + ov->initialized = 1; + return 0; + } + default: + return ov->sops->command(c, cmd, arg); + } +} + +/* ----------------------------------------------------------------------- */ + +static struct i2c_driver driver = { + .owner = THIS_MODULE, + .name = "ovcamchip", + .id = I2C_DRIVERID_OVCAMCHIP, + .class = I2C_CLASS_CAM_DIGITAL, + .flags = I2C_DF_NOTIFY, + .attach_adapter = ovcamchip_attach, + .detach_client = ovcamchip_detach, + .command = ovcamchip_command, +}; + +static struct i2c_client client_template = { + I2C_DEVNAME("(unset)"), + .id = -1, + .driver = &driver, +}; + +static int __init ovcamchip_init(void) +{ +#ifdef DEBUG + ovcamchip_debug = debug; +#endif + + PINFO(DRIVER_VERSION " : " DRIVER_DESC); + return i2c_add_driver(&driver); +} + +static void __exit ovcamchip_exit(void) +{ + i2c_del_driver(&driver); +} + +module_init(ovcamchip_init); +module_exit(ovcamchip_exit); diff -Nru a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/media/video/ovcamchip/ovcamchip_priv.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,87 @@ +/* OmniVision* camera chip driver private definitions for core code and + * chip-specific code + * + * Copyright (c) 1999-2004 Mark McClelland + * + * 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. NO WARRANTY OF ANY KIND is expressed or implied. + * + * * OmniVision is a trademark of OmniVision Technologies, Inc. This driver + * is not sponsored or developed by them. + */ + +#ifndef __LINUX_OVCAMCHIP_PRIV_H +#define __LINUX_OVCAMCHIP_PRIV_H + +#include + +#ifdef DEBUG +extern int ovcamchip_debug; +#endif + +#define PDEBUG(level, fmt, args...) \ + if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \ + __FUNCTION__, __LINE__ , ## args) + +#define DDEBUG(level, dev, fmt, args...) \ + if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \ + __FUNCTION__, __LINE__ , ## args) + +/* Number of times to retry chip detection. Increase this if you are getting + * "Failed to init camera chip" */ +#define I2C_DETECT_RETRIES 10 + +struct ovcamchip_regvals { + unsigned char reg; + unsigned char val; +}; + +struct ovcamchip_ops { + int (*init)(struct i2c_client *); + int (*free)(struct i2c_client *); + int (*command)(struct i2c_client *, unsigned int, void *); +}; + +struct ovcamchip { + struct ovcamchip_ops *sops; + void *spriv; /* Private data for OV7x10.c etc... */ + int subtype; /* = SEN_OV7610 etc... */ + int mono; /* Monochrome chip? (invalid until init) */ + int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */ +}; + +/* --------------------------------- */ +/* I2C I/O */ +/* --------------------------------- */ + +static inline int ov_read(struct i2c_client *c, unsigned char reg, + unsigned char *value) +{ + int rc; + + rc = i2c_smbus_read_byte_data(c, reg); + *value = (unsigned char) rc; + return rc; +} + +static inline int ov_write(struct i2c_client *c, unsigned char reg, + unsigned char value ) +{ + return i2c_smbus_write_byte_data(c, reg, value); +} + +/* --------------------------------- */ +/* FUNCTION PROTOTYPES */ +/* --------------------------------- */ + +/* Functions in ovcamchip_core.c */ + +extern int ov_write_regvals(struct i2c_client *c, + struct ovcamchip_regvals *rvals); + +extern int ov_write_mask(struct i2c_client *c, unsigned char reg, + unsigned char value, unsigned char mask); + +#endif diff -Nru a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c --- a/drivers/media/video/saa7134/saa6752hs.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/media/video/saa7134/saa6752hs.c 2004-06-26 17:09:21 -07:00 @@ -337,7 +337,6 @@ { if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, saa6752hs_attach); - return 0; } diff -Nru a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c --- a/drivers/media/video/saa7134/saa7134-cards.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/media/video/saa7134/saa7134-cards.c 2004-06-26 17:09:20 -07:00 @@ -420,20 +420,14 @@ .vmux = 1, .amux = TV, .tv = 1, -#if 0 },{ .name = name_comp1, .vmux = 0, .amux = LINE2, },{ - .name = name_comp2, - .vmux = 3, - .amux = LINE2, - },{ .name = name_svideo, .vmux = 8, .amux = LINE2, -#endif }}, .radio = { .name = name_radio, @@ -515,24 +509,14 @@ .vmux = 1, .amux = TV, .tv = 1, -#if 0 /* untested */ },{ .name = name_comp1, .vmux = 4, .amux = LINE2, },{ - .name = name_comp2, - .vmux = 2, - .amux = LINE2, - },{ .name = name_svideo, .vmux = 6, .amux = LINE2, - },{ - .name = "S-Video2", - .vmux = 7, - .amux = LINE2, -#endif }}, .radio = { .name = name_radio, @@ -679,7 +663,7 @@ }}, }, [SAA7134_BOARD_MD2819] = { - .name = "Medion 2819/ AverMedia M156", + .name = "AverMedia M156 / Medion 2819", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, .need_tda9887 = 1, @@ -951,6 +935,96 @@ .vmux = 3, }}, }, + [SAA7134_BOARD_NOVAC_PRIMETV7133] = { + /* toshii@netbsd.org */ + .name = "Noval Prime TV 7133", + .audio_clock = 0x00200000, + .tuner_type = TUNER_ALPS_TSBH1_NTSC, + .inputs = {{ + .name = name_comp1, + .vmux = 3, + },{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_svideo, + .vmux = 8, + }}, + }, + [SAA7134_BOARD_AVERMEDIA_305] = { + .name = "AverMedia 305", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .need_tda9887 = 1, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = LINE2, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 0, + .amux = LINE2, + },{ + .name = name_comp2, + .vmux = 3, + .amux = LINE2, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + .mute = { + .name = name_mute, + .amux = LINE1, + }, + }, + [SAA7133_BOARD_UPMOST_PURPLE_TV] = { + .name = "UPMOST PURPLE TV", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1236_MK3, + .need_tda9887 = 1, + .inputs = {{ + .name = name_tv, + .vmux = 7, + .amux = TV, + .tv = 1, + },{ + .name = name_svideo, + .vmux = 7, + .amux = LINE1, + }}, + }, + [SAA7134_BOARD_ITEMS_MTV005] = { + /* Norman Jonas */ + .name = "Items MuchTV Plus / IT-005", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_PAL, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -1103,12 +1177,11 @@ .subdevice = 0xa70b, .driver_data = SAA7134_BOARD_MD2819, },{ - /* AverMedia Studio 305, using AverMedia M156 entry for now */ .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, .subvendor = 0x1461, /* Avermedia Technologies Inc */ .subdevice = 0x2115, - .driver_data = SAA7134_BOARD_MD2819, + .driver_data = SAA7134_BOARD_AVERMEDIA_305, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7130, @@ -1141,7 +1214,13 @@ .subdevice = 0x4cb5, .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x12ab, + .subdevice = 0x0800, + .driver_data = SAA7133_BOARD_UPMOST_PURPLE_TV, + },{ /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -1249,6 +1328,9 @@ case SAA7134_BOARD_CINERGY600: case SAA7134_BOARD_ECS_TVP3XP: case SAA7134_BOARD_ECS_TVP3XP_4CB5: + dev->has_remote = 1; + break; + case SAA7134_BOARD_AVACSSMARTTV: dev->has_remote = 1; break; } diff -Nru a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c --- a/drivers/media/video/saa7134/saa7134-core.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/media/video/saa7134/saa7134-core.c 2004-06-26 17:09:17 -07:00 @@ -607,10 +607,18 @@ }; if (10 == loop) { print_irqstatus(dev,loop,report,status); - printk(KERN_WARNING "%s/irq: looping -- clearing enable bits\n",dev->name); - /* disable all irqs */ - saa_writel(SAA7134_IRQ1,0); - saa_writel(SAA7134_IRQ2,0); + if (report & SAA7134_IRQ_REPORT_PE) { + /* disable all parity error */ + printk(KERN_WARNING "%s/irq: looping -- " + "clearing PE (parity error!) enable bit\n",dev->name); + saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); + } else { + /* disable all irqs */ + printk(KERN_WARNING "%s/irq: looping -- " + "clearing all enable bits\n",dev->name); + saa_writel(SAA7134_IRQ1,0); + saa_writel(SAA7134_IRQ2,0); + } } out: diff -Nru a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c --- a/drivers/media/video/saa7134/saa7134-input.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/media/video/saa7134/saa7134-input.c 2004-06-26 17:09:19 -07:00 @@ -20,12 +20,24 @@ #include #include #include +#include #include #include #include "saa7134-reg.h" #include "saa7134.h" +static unsigned int disable_ir = 0; +MODULE_PARM(disable_ir,"i"); +MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); + +static unsigned int ir_debug = 0; +MODULE_PARM(ir_debug,"i"); +MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); + +#define dprintk(fmt, arg...) if (ir_debug) \ + printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) + /* ---------------------------------------------------------------------- */ static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = { @@ -156,6 +168,47 @@ [ 33 ] = KEY_KPDOT, // . (decimal dot) }; +static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { + [ 30 ] = KEY_POWER, // power + [ 28 ] = KEY_SEARCH, // scan + [ 7 ] = KEY_SELECT, // source + + [ 22 ] = KEY_VOLUMEUP, + [ 20 ] = KEY_VOLUMEDOWN, + [ 31 ] = KEY_CHANNELUP, + [ 23 ] = KEY_CHANNELDOWN, + [ 24 ] = KEY_MUTE, + + [ 2 ] = KEY_KP0, + [ 1 ] = KEY_KP1, + [ 11 ] = KEY_KP2, + [ 27 ] = KEY_KP3, + [ 5 ] = KEY_KP4, + [ 9 ] = KEY_KP5, + [ 21 ] = KEY_KP6, + [ 6 ] = KEY_KP7, + [ 10 ] = KEY_KP8, + [ 18 ] = KEY_KP9, + [ 16 ] = KEY_KPDOT, + + [ 3 ] = KEY_TUNER, // tv/fm + [ 4 ] = KEY_REWIND, // fm tuning left or function left + [ 12 ] = KEY_FORWARD, // fm tuning right or function right + + [ 0 ] = KEY_RECORD, + [ 8 ] = KEY_STOP, + [ 17 ] = KEY_PLAY, + + [ 25 ] = KEY_ZOOM, + [ 14 ] = KEY_MENU, // function + [ 19 ] = KEY_AGAIN, // recall + [ 29 ] = KEY_RESTART, // reset + +// FIXME + [ 13 ] = KEY_F21, // mts + [ 15 ] = KEY_F22, // min + [ 26 ] = KEY_F23, // freeze +}; /* ---------------------------------------------------------------------- */ static int build_key(struct saa7134_dev *dev) @@ -175,8 +228,8 @@ } data = ir_extract_bits(gpio, ir->mask_keycode); - printk("%s: build_key gpio=0x%x mask=0x%x data=%d\n", - dev->name, gpio, ir->mask_keycode, data); + dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", + gpio, ir->mask_keycode, data); if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { @@ -218,9 +271,12 @@ int polling = 0; int ir_type = IR_TYPE_OTHER; - /* detect & configure */ if (!dev->has_remote) return -ENODEV; + if (disable_ir) + return -ENODEV; + + /* detect & configure */ switch (dev->board) { case SAA7134_BOARD_FLYVIDEO2000: case SAA7134_BOARD_FLYVIDEO3000: @@ -241,6 +297,12 @@ mask_keyup = 0x000002; polling = 50; // ms break; + case SAA7134_BOARD_AVACSSMARTTV: + ir_codes = avacssmart_codes; + mask_keycode = 0x00001F; + mask_keyup = 0x000020; + polling = 50; // ms + break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", diff -Nru a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c --- a/drivers/media/video/saa7134/saa7134-oss.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/media/video/saa7134/saa7134-oss.c 2004-06-26 17:09:18 -07:00 @@ -50,7 +50,7 @@ if (blksize < 0x100) blksize = 0x100; if (blksize > 0x10000) - blksize = 0x100; + blksize = 0x10000; if (blocks < 2) blocks = 2; @@ -74,6 +74,7 @@ if (!dev->oss.bufsize) BUG(); + videobuf_dma_init(&dev->oss.dma); err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, dev->oss.bufsize >> PAGE_SHIFT); if (0 != err) @@ -172,7 +173,7 @@ fmt |= (2 << 4); if (!sign) fmt |= 0x04; - saa_writel(0x588 >> 2, dev->oss.blksize); + saa_writel(0x588 >> 2, dev->oss.blksize -4); saa_writel(0x58c >> 2, 0x543210 | (fmt << 24)); break; } diff -Nru a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c --- a/drivers/media/video/saa7134/saa7134-ts.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/media/video/saa7134/saa7134-ts.c 2004-06-26 17:09:15 -07:00 @@ -33,6 +33,8 @@ /* ------------------------------------------------------------------ */ +#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */ + static unsigned int ts_debug = 0; MODULE_PARM(ts_debug,"i"); MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); @@ -41,8 +43,9 @@ MODULE_PARM(tsbufs,"i"); MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); -#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */ -#define TS_NR_PACKETS 312 +static unsigned int ts_nr_packets = 30; +MODULE_PARM(ts_nr_packets,"i"); +MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); #define dprintk(fmt, arg...) if (ts_debug) \ printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg) @@ -96,7 +99,7 @@ dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); llength = TS_PACKET_SIZE; - lines = TS_NR_PACKETS; + lines = ts_nr_packets; size = lines * llength; if (0 != buf->vb.baddr && buf->vb.bsize < size) @@ -135,7 +138,7 @@ static int buffer_setup(struct file *file, unsigned int *count, unsigned int *size) { - *size = TS_PACKET_SIZE * TS_NR_PACKETS; + *size = TS_PACKET_SIZE * ts_nr_packets; if (0 == *count) *count = tsbufs; *count = saa7134_buffer_count(*size,*count); @@ -353,7 +356,7 @@ f->fmt.pix.width = 720; /* D1 */ f->fmt.pix.height = 576; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.sizeimage = TS_PACKET_SIZE*TS_NR_PACKETS; + f->fmt.pix.sizeimage = TS_PACKET_SIZE*ts_nr_packets; return 0; } @@ -379,7 +382,7 @@ f->fmt.pix.width = 720; /* D1 */ f->fmt.pix.height = 576; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.sizeimage = TS_PACKET_SIZE*TS_NR_PACKETS; + f->fmt.pix.sizeimage = TS_PACKET_SIZE*ts_nr_packets; return 0; } @@ -408,7 +411,7 @@ case MPEG_SETPARAMS: return ts_init_encoder(dev, arg); - + default: return -ENOIOCTLCMD; } @@ -455,6 +458,10 @@ tsbufs = 2; if (tsbufs > VIDEO_MAX_FRAME) tsbufs = VIDEO_MAX_FRAME; + if (ts_nr_packets < 4) + ts_nr_packets = 4; + if (ts_nr_packets > 312) + ts_nr_packets = 312; INIT_LIST_HEAD(&dev->ts_q.queue); init_timer(&dev->ts_q.timeout); @@ -472,9 +479,9 @@ saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* deactivate TS softreset */ saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */ saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1)); - saa_writeb(SAA7134_TS_DMA0, ((TS_NR_PACKETS-1)&0xff)); - saa_writeb(SAA7134_TS_DMA1, (((TS_NR_PACKETS-1)>>8)&0xff)); - saa_writeb(SAA7134_TS_DMA2, ((((TS_NR_PACKETS-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */ + saa_writeb(SAA7134_TS_DMA0, ((ts_nr_packets-1)&0xff)); + saa_writeb(SAA7134_TS_DMA1, (((ts_nr_packets-1)>>8)&0xff)); + saa_writeb(SAA7134_TS_DMA2, ((((ts_nr_packets-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */ return 0; } diff -Nru a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c --- a/drivers/media/video/saa7134/saa7134-tvaudio.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c 2004-06-26 17:09:15 -07:00 @@ -37,10 +37,6 @@ MODULE_PARM(audio_debug,"i"); MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]"); -static unsigned int audio_carrier = 0; -MODULE_PARM(audio_carrier,"i"); -MODULE_PARM_DESC(audio_carrier,"audio carrier location"); - static unsigned int audio_ddep = 0; MODULE_PARM(audio_ddep,"i"); MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite"); @@ -67,6 +63,30 @@ /* ------------------------------------------------------------------ */ /* saa7134 code */ +static struct mainscan { + char *name; + v4l2_std_id std; + int carr; +} mainscan[] = { + { + .name = "M", + .std = V4L2_STD_NTSC | V4L2_STD_PAL_M, + .carr = 4500, + },{ + .name = "BG", + .std = V4L2_STD_PAL_BG, + .carr = 5500, + },{ + .name = "I", + .std = V4L2_STD_PAL_I, + .carr = 6000, + },{ + .name = "DKL", + .std = V4L2_STD_PAL_DK | V4L2_STD_SECAM, + .carr = 6500, + } +}; + static struct saa7134_tvaudio tvaudio[] = { { .name = "PAL-B/G FM-stereo", @@ -314,15 +334,15 @@ return dev->thread.scan1 != dev->thread.scan2; } -static int tvaudio_checkcarrier(struct saa7134_dev *dev, int carrier) +static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan) { __s32 left,right,value; if (audio_debug > 1) { int i; - dprintk("debug %d:",carrier); + dprintk("debug %d:",scan->carr); for (i = -150; i <= 150; i += 30) { - tvaudio_setcarrier(dev,carrier+i,carrier+i); + tvaudio_setcarrier(dev,scan->carr+i,scan->carr+i); saa_readl(SAA7134_LEVEL_READOUT1 >> 2); if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY)) return -1; @@ -334,24 +354,31 @@ } printk("\n"); } - - tvaudio_setcarrier(dev,carrier-90,carrier-90); - saa_readl(SAA7134_LEVEL_READOUT1 >> 2); - if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY)) - return -1; - left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2); - - tvaudio_setcarrier(dev,carrier+90,carrier+90); - saa_readl(SAA7134_LEVEL_READOUT1 >> 2); - if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY)) - return -1; - right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2); - - left >>= 16; - right >>= 16; - value = left > right ? left - right : right - left; - dprintk("scanning %d.%03d MHz => dc is %5d [%d/%d]\n", - carrier/1000,carrier%1000,value,left,right); + + if (dev->tvnorm->id & scan->std) { + tvaudio_setcarrier(dev,scan->carr-90,scan->carr-90); + saa_readl(SAA7134_LEVEL_READOUT1 >> 2); + if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY)) + return -1; + left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2); + + tvaudio_setcarrier(dev,scan->carr+90,scan->carr+90); + saa_readl(SAA7134_LEVEL_READOUT1 >> 2); + if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY)) + return -1; + right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2); + + left >>= 16; + right >>= 16; + value = left > right ? left - right : right - left; + dprintk("scanning %d.%03d MHz [%4s] => dc is %5d [%d/%d]\n", + scan->carr / 1000, scan->carr % 1000, + scan->name, value, left, right); + } else { + value = 0; + dprintk("skipping %d.%03d MHz [%4s]\n", + scan->carr / 1000, scan->carr % 1000, scan->name); + } return value; } @@ -384,6 +411,7 @@ case TVAUDIO_FM_K_STEREO: case TVAUDIO_FM_BG_STEREO: idp = (saa_readb(SAA7134_IDENT_SIF) & 0xe0) >> 5; + dprintk("getstereo: fm/stereo: idp=0x%x\n",idp); if (0x03 == (idp & 0x03)) retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; else if (0x05 == (idp & 0x05)) @@ -397,6 +425,7 @@ case TVAUDIO_NICAM_FM: case TVAUDIO_NICAM_AM: nicam = saa_readb(SAA7134_NICAM_STATUS); + dprintk("getstereo: nicam=0x%x\n",nicam); switch (nicam & 0x0b) { case 0x08: retval = V4L2_TUNER_SUB_MONO; @@ -458,16 +487,10 @@ static int tvaudio_thread(void *data) { -#define MAX_SCAN 4 - static const int carr_pal[MAX_SCAN] = { 5500, 6000, 6500 }; - static const int carr_ntsc[MAX_SCAN] = { 4500 }; - static const int carr_secam[MAX_SCAN] = { 6500 }; - static const int carr_default[MAX_SCAN] = { 4500, 5500, 6000, 6500 }; struct saa7134_dev *dev = data; - const int *carr_scan; - int carr_vals[4]; - unsigned int i, audio; - int max1,max2,carrier,rx,mode,lastmode; + int carr_vals[ARRAY_SIZE(mainscan)]; + unsigned int i, audio, nscan; + int max1,max2,carrier,rx,mode,lastmode,default_carrier; daemonize("%s", dev->name); allow_signal(SIGTERM); @@ -488,32 +511,40 @@ if (tvaudio_sleep(dev,SCAN_INITIAL_DELAY)) goto restart; - /* find the main carrier */ - carr_scan = carr_default; - if (dev->tvnorm->id & V4L2_STD_PAL) - carr_scan = carr_pal; - if (dev->tvnorm->id & V4L2_STD_NTSC) - carr_scan = carr_ntsc; - if (dev->tvnorm->id & V4L2_STD_SECAM) - carr_scan = carr_secam; - saa_writeb(SAA7134_MONITOR_SELECT,0x00); - tvaudio_setmode(dev,&tvaudio[0],NULL); - for (i = 0; i < MAX_SCAN; i++) { - if (!carr_scan[i]) + max1 = 0; + max2 = 0; + nscan = 0; + carrier = 0; + default_carrier = 0; + for (i = 0; i < ARRAY_SIZE(mainscan); i++) { + if (!(dev->tvnorm->id & mainscan[i].std)) continue; - carr_vals[i] = tvaudio_checkcarrier(dev,carr_scan[i]); - if (dev->thread.scan1 != dev->thread.scan2) - goto restart; + if (!default_carrier) + default_carrier = mainscan[i].carr; + nscan++; } - for (carrier = 0, max1 = 0, max2 = 0, i = 0; i < MAX_SCAN; i++) { - if (!carr_scan[i]) - continue; - if (max1 < carr_vals[i]) { - max2 = max1; - max1 = carr_vals[i]; - carrier = carr_scan[i]; - } else if (max2 < carr_vals[i]) { - max2 = carr_vals[i]; + + if (1 == nscan) { + /* only one candidate -- skip scan ;) */ + max1 = 12345; + carrier = default_carrier; + } else { + /* scan for the main carrier */ + saa_writeb(SAA7134_MONITOR_SELECT,0x00); + tvaudio_setmode(dev,&tvaudio[0],NULL); + for (i = 0; i < ARRAY_SIZE(mainscan); i++) { + carr_vals[i] = tvaudio_checkcarrier(dev, mainscan+i); + if (dev->thread.scan1 != dev->thread.scan2) + goto restart; + } + for (max1 = 0, max2 = 0, i = 0; i < ARRAY_SIZE(mainscan); i++) { + if (max1 < carr_vals[i]) { + max2 = max1; + max1 = carr_vals[i]; + carrier = mainscan[i].carr; + } else if (max2 < carr_vals[i]) { + max2 = carr_vals[i]; + } } } @@ -523,21 +554,17 @@ dev->tvnorm->name, carrier/1000, carrier%1000, max1, max2); dev->last_carrier = carrier; - } else if (0 != audio_carrier) { - /* no carrier -- try insmod option as fallback */ - carrier = audio_carrier; - printk(KERN_WARNING "%s/audio: audio carrier scan failed, " - "using %d.%03d MHz [insmod option]\n", - dev->name, carrier/1000, carrier%1000); + } else if (0 != dev->last_carrier) { /* no carrier -- try last detected one as fallback */ carrier = dev->last_carrier; printk(KERN_WARNING "%s/audio: audio carrier scan failed, " "using %d.%03d MHz [last detected]\n", dev->name, carrier/1000, carrier%1000); + } else { - /* no carrier + no fallback -- try first in list */ - carrier = carr_scan[0]; + /* no carrier + no fallback -- use default */ + carrier = default_carrier; printk(KERN_WARNING "%s/audio: audio carrier scan failed, " "using %d.%03d MHz [default]\n", dev->name, carrier/1000, carrier%1000); @@ -550,7 +577,7 @@ /* find the exact tv audio norm */ for (audio = UNSET, i = 0; i < TVAUDIO; i++) { if (dev->tvnorm->id != UNSET && - dev->tvnorm->id != tvaudio[i].std) + !(dev->tvnorm->id & tvaudio[i].std)) continue; if (tvaudio[i].carr1 != carrier) continue; @@ -722,11 +749,16 @@ static int tvaudio_thread_ddep(void *data) { struct saa7134_dev *dev = data; - u32 value, norms; + u32 value, norms, clock; daemonize("%s", dev->name); allow_signal(SIGTERM); + clock = saa7134_boards[dev->board].audio_clock; + if (UNSET != audio_clock_override) + clock = audio_clock_override; + saa_writel(0x598 >> 2, clock); + /* unmute */ saa_dsp_writel(dev, 0x474 >> 2, 0x00); saa_dsp_writel(dev, 0x450 >> 2, 0x00); @@ -769,9 +801,11 @@ (norms & 0x40) ? " M" : ""); } - /* quick & dirty -- to be fixed up later ... */ + /* kick automatic standard detection */ saa_dsp_writel(dev, 0x454 >> 2, 0); saa_dsp_writel(dev, 0x454 >> 2, norms | 0x80); + + /* setup crossbars */ saa_dsp_writel(dev, 0x464 >> 2, 0x000000); saa_dsp_writel(dev, 0x470 >> 2, 0x101010); diff -Nru a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c --- a/drivers/media/video/saa7134/saa7134-video.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/media/video/saa7134/saa7134-video.c 2004-06-26 17:09:16 -07:00 @@ -28,13 +28,15 @@ #include "saa7134-reg.h" #include "saa7134.h" +#define V4L2_I2C_CLIENTS 1 + /* ------------------------------------------------------------------ */ static unsigned int video_debug = 0; static unsigned int gbuffers = 8; static unsigned int noninterlaced = 0; -static unsigned int gbufsize = 768*576*4; -static unsigned int gbufsize_max = 768*576*4; +static unsigned int gbufsize = 720*576*4; +static unsigned int gbufsize_max = 720*576*4; MODULE_PARM(video_debug,"i"); MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); MODULE_PARM(gbuffers,"i"); @@ -148,10 +150,65 @@ }; #define FORMATS ARRAY_SIZE(formats) +#define NORM_625_50 \ + .h_start = 0, \ + .h_stop = 719, \ + .video_v_start = 24, \ + .video_v_stop = 311, \ + .vbi_v_start = 7, \ + .vbi_v_stop = 22, \ + .src_timing = 4 + +#define NORM_525_60 \ + .h_start = 0, \ + .h_stop = 703, \ + .video_v_start = 22, \ + .video_v_stop = 22+239, \ + .vbi_v_start = 10, /* FIXME */ \ + .vbi_v_stop = 21, /* FIXME */ \ + .src_timing = 1 + static struct saa7134_tvnorm tvnorms[] = { { - .name = "PAL", + .name = "PAL", /* autodetect */ .id = V4L2_STD_PAL, + NORM_625_50, + + .sync_control = 0x18, + .luma_control = 0x40, + .chroma_ctrl1 = 0x81, + .chroma_gain = 0x2a, + .chroma_ctrl2 = 0x06, + .vgate_misc = 0x1c, + + },{ + .name = "PAL-BG", + .id = V4L2_STD_PAL_BG, + NORM_625_50, + + .sync_control = 0x18, + .luma_control = 0x40, + .chroma_ctrl1 = 0x81, + .chroma_gain = 0x2a, + .chroma_ctrl2 = 0x06, + .vgate_misc = 0x1c, + + },{ + .name = "PAL-I", + .id = V4L2_STD_PAL_I, + NORM_625_50, + + .sync_control = 0x18, + .luma_control = 0x40, + .chroma_ctrl1 = 0x81, + .chroma_gain = 0x2a, + .chroma_ctrl2 = 0x06, + .vgate_misc = 0x1c, + + },{ + .name = "PAL-DK", + .id = V4L2_STD_PAL_DK, + NORM_625_50, .sync_control = 0x18, .luma_control = 0x40, @@ -160,16 +217,10 @@ .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, - .h_start = 0, - .h_stop = 719, - .video_v_start = 24, - .video_v_stop = 311, - .vbi_v_start = 7, - .vbi_v_stop = 22, - .src_timing = 4, },{ .name = "NTSC", .id = V4L2_STD_NTSC, + NORM_525_60, .sync_control = 0x59, .luma_control = 0x40, @@ -178,16 +229,10 @@ .chroma_ctrl2 = 0x0e, .vgate_misc = 0x18, - .h_start = 0, - .h_stop = 719, - .video_v_start = 22, - .video_v_stop = 22+240, - .vbi_v_start = 10, /* FIXME */ - .vbi_v_stop = 21, /* FIXME */ - .src_timing = 1, },{ .name = "SECAM", .id = V4L2_STD_SECAM, + NORM_625_50, .sync_control = 0x18, /* old: 0x58, */ .luma_control = 0x1b, @@ -196,16 +241,10 @@ .chroma_ctrl2 = 0x00, .vgate_misc = 0x1c, - .h_start = 0, - .h_stop = 719, - .video_v_start = 24, - .video_v_stop = 311, - .vbi_v_start = 7, - .vbi_v_stop = 22, - .src_timing = 4, },{ .name = "PAL-M", .id = V4L2_STD_PAL_M, + NORM_525_60, .sync_control = 0x59, .luma_control = 0x40, @@ -214,16 +253,10 @@ .chroma_ctrl2 = 0x0e, .vgate_misc = 0x18, - .h_start = 0, - .h_stop = 719, - .video_v_start = 22, - .video_v_stop = 22+240, - .vbi_v_start = 10, /* FIXME */ - .vbi_v_stop = 21, /* FIXME */ - .src_timing = 1, },{ .name = "PAL-Nc", .id = V4L2_STD_PAL_Nc, + NORM_625_50, .sync_control = 0x18, .luma_control = 0x40, @@ -232,35 +265,6 @@ .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, - .h_start = 0, - .h_stop = 719, - .video_v_start = 24, - .video_v_stop = 311, - .vbi_v_start = 7, - .vbi_v_stop = 22, - .src_timing = 4, -#if 0 - },{ - .name = "AUTO", - .id = V4L2_STD_PAL|V4L2_STD_NTSC|V4L2_STD_SECAM, - .width = 768, - .height = 576, - - .sync_control = 0x98, - .luma_control = 0x40, - .chroma_ctrl1 = 0x8b, - .chroma_gain = 0x00, - .chroma_ctrl2 = 0x00, - .vgate_misc = 0x18, - - .h_start = 0, - .h_stop = 719, - .video_v_start = 24, - .video_v_stop = 311, - .vbi_v_start = 7, - .vbi_v_stop = 22, - .src_timing = 4, -#endif } }; #define TVNORMS ARRAY_SIZE(tvnorms) @@ -429,7 +433,6 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) { - struct video_channel c; int luma_control,sync_control,mux; dprintk("set tv norm = %s\n",norm->name); @@ -489,15 +492,22 @@ saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40); saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80); - /* pass down info to the i2c chips (v4l1) */ - memset(&c,0,sizeof(c)); - c.channel = dev->ctl_input; - c.norm = VIDEO_MODE_PAL; - if (norm->id & V4L2_STD_NTSC) - c.norm = VIDEO_MODE_NTSC; - if (norm->id & V4L2_STD_SECAM) - c.norm = VIDEO_MODE_SECAM; - saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c); +#ifdef V4L2_I2C_CLIENTS + saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id); +#else + { + /* pass down info to the i2c chips (v4l1) */ + struct video_channel c; + memset(&c,0,sizeof(c)); + c.channel = dev->ctl_input; + c.norm = VIDEO_MODE_PAL; + if (norm->id & V4L2_STD_NTSC) + c.norm = VIDEO_MODE_NTSC; + if (norm->id & V4L2_STD_SECAM) + c.norm = VIDEO_MODE_SECAM; + saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c); + } +#endif } static void video_mux(struct saa7134_dev *dev, int input) @@ -593,11 +603,11 @@ saa_writeb(SAA7134_VIDEO_V_STOP1(task), v_stop & 0xff); saa_writeb(SAA7134_VIDEO_V_STOP2(task), v_stop >> 8); - prescale = dev->crop_defrect.width / width; + prescale = dev->crop_current.width / width; if (0 == prescale) prescale = 1; - xscale = 1024 * dev->crop_defrect.width / prescale / width; - yscale = 512 * div * dev->crop_defrect.height / height; + xscale = 1024 * dev->crop_current.width / prescale / width; + yscale = 512 * div * dev->crop_current.height / height; dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); set_h_prescale(dev,task,prescale); saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); @@ -909,10 +919,12 @@ /* sanity checks */ if (NULL == fh->fmt) return -EINVAL; - if (fh->width < 48 || - fh->height < 32 || - fh->width > dev->crop_current.width || - fh->height > dev->crop_current.height) + if (fh->width < 48 || + fh->height < 32 || + fh->width/4 > dev->crop_current.width || + fh->height/4 > dev->crop_current.height || + fh->width > dev->crop_bounds.width || + fh->height > dev->crop_bounds.height) return -EINVAL; size = (fh->width * fh->height * fh->fmt->depth) >> 3; if (0 != buf->vb.baddr && buf->vb.bsize < size) @@ -1192,7 +1204,7 @@ fh->radio = radio; fh->type = type; fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); - fh->width = 768; + fh->width = 720; fh->height = 576; #ifdef VIDIOC_G_PRIORITY v4l2_prio_open(&dev->prio,&fh->prio); @@ -1409,8 +1421,8 @@ return -EINVAL; field = f->fmt.pix.field; - maxw = dev->crop_current.width; - maxh = dev->crop_current.height; + maxw = min(dev->crop_current.width*4, dev->crop_bounds.width); + maxh = min(dev->crop_current.height*4, dev->crop_bounds.height); if (V4L2_FIELD_ANY == field) { field = (f->fmt.pix.height > maxh/2) @@ -1670,10 +1682,14 @@ v4l2_std_id *id = arg; unsigned int i; - for(i = 0; i < TVNORMS; i++) - if (*id & tvnorms[i].id) + for (i = 0; i < TVNORMS; i++) + if (*id == tvnorms[i].id) break; if (i == TVNORMS) + for (i = 0; i < TVNORMS; i++) + if (*id & tvnorms[i].id) + break; + if (i == TVNORMS) return -EINVAL; down(&dev->lock); @@ -1685,6 +1701,7 @@ spin_unlock_irqrestore(&dev->slock,flags); } else set_tvnorm(dev,&tvnorms[i]); + saa7134_tvaudio_do_scan(dev); up(&dev->lock); return 0; } @@ -1817,7 +1834,11 @@ return -EINVAL; down(&dev->lock); dev->ctl_freq = f->frequency; +#ifdef V4L2_I2C_CLIENTS + saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); +#else saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq); +#endif saa7134_tvaudio_do_scan(dev); up(&dev->lock); return 0; @@ -2064,7 +2085,6 @@ case VIDIOC_G_TUNER: { struct v4l2_tuner *t = arg; - struct video_tuner vt; if (0 != t->index) return -EINVAL; @@ -2073,10 +2093,17 @@ strcpy(t->name, "Radio"); t->rangelow = (int)(65*16); t->rangehigh = (int)(108*16); - - memset(&vt,0,sizeof(vt)); - saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt); - t->signal = vt.signal; + +#ifdef V4L2_I2C_CLIENTS + saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t); +#else + { + struct video_tuner vt; + memset(&vt,0,sizeof(vt)); + saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt); + t->signal = vt.signal; + } +#endif return 0; } case VIDIOC_ENUMINPUT: diff -Nru a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h --- a/drivers/media/video/saa7134/saa7134.h 2004-06-26 17:09:19 -07:00 +++ b/drivers/media/video/saa7134/saa7134.h 2004-06-26 17:09:19 -07:00 @@ -19,7 +19,7 @@ */ #include -#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,11) +#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12) #include #include @@ -152,6 +152,10 @@ #define SAA7134_BOARD_ECS_TVP3XP_4CB5 31 #define SAA7134_BOARD_AVACSSMARTTV 32 #define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33 +#define SAA7134_BOARD_NOVAC_PRIMETV7133 34 +#define SAA7134_BOARD_AVERMEDIA_305 35 +#define SAA7133_BOARD_UPMOST_PURPLE_TV 36 +#define SAA7134_BOARD_ITEMS_MTV005 37 #define SAA7134_INPUT_MAX 8 diff -Nru a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c --- a/drivers/media/video/tda9840.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/media/video/tda9840.c 2004-06-26 17:09:19 -07:00 @@ -268,13 +268,12 @@ .command = tda9840_command, }; -static int tda9840_init_module(void) +static int __init tda9840_init_module(void) { - i2c_add_driver(&driver); - return 0; + return i2c_add_driver(&driver); } -static void tda9840_cleanup_module(void) +static void __exit tda9840_cleanup_module(void) { i2c_del_driver(&driver); } @@ -285,4 +284,3 @@ MODULE_AUTHOR("Michael Hunold "); MODULE_DESCRIPTION("tda9840 driver"); MODULE_LICENSE("GPL"); - diff -Nru a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c --- a/drivers/media/video/tda9887.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/media/video/tda9887.c 2004-06-26 17:09:15 -07:00 @@ -21,7 +21,7 @@ Note: OP2 of tda988x must be set to 1, else MT2032 is disabled! - KNC One TV-Station RDS (saa7134) */ - + /* Addresses to scan */ static unsigned short normal_i2c[] = { @@ -33,22 +33,30 @@ I2C_CLIENT_INSMOD; /* insmod options */ -static int debug = 0; -static char *pal = "b"; -static char *secam = "l"; +static unsigned int debug = 0; MODULE_PARM(debug,"i"); -MODULE_PARM(pal,"s"); -MODULE_PARM(secam,"s"); MODULE_LICENSE("GPL"); /* ---------------------------------------------------------------------- */ +#define UNSET (-1U) +#define PREFIX "tda9885/6/7: " #define dprintk if (debug) printk struct tda9887 { - struct i2c_client client; - int radio,tvnorm; - int pinnacle_id; + struct i2c_client client; + v4l2_std_id std; + unsigned int radio; + unsigned int pinnacle_id; + unsigned int using_v4l2; +}; + +struct tvnorm { + v4l2_std_id std; + char *name; + unsigned char b; + unsigned char c; + unsigned char e; }; static struct i2c_driver driver; @@ -60,7 +68,7 @@ // TDA defines // -//// first reg +//// first reg (b) #define cVideoTrapBypassOFF 0x00 // bit b0 #define cVideoTrapBypassON 0x01 // bit b0 @@ -85,7 +93,7 @@ #define cOutputPort2Inactive 0x80 // bit b7 -//// second reg +//// second reg (c) #define cDeemphasisOFF 0x00 // bit c5 #define cDeemphasisON 0x20 // bit c5 @@ -96,7 +104,7 @@ #define cAudioGain6 0x80 // bit c7 -//// third reg +//// third reg (e) #define cAudioIF_4_5 0x00 // bit e0:1 #define cAudioIF_5_5 0x01 // bit e0:1 #define cAudioIF_6_0 0x02 // bit e0:1 @@ -122,126 +130,287 @@ #define cAgcOutON 0x80 // bit e7 #define cAgcOutOFF 0x00 // bit e7 -static int tda9887_miro(struct tda9887 *t) +/* ---------------------------------------------------------------------- */ + +static struct tvnorm tvnorms[] = { + { + .std = V4L2_STD_PAL_BG, + .name = "PAL-BG", + .b = ( cNegativeFmTV | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis50 ), + .e = ( cAudioIF_5_5 | + cVideoIF_38_90 ), + },{ + .std = V4L2_STD_PAL_I, + .name = "PAL-I", + .b = ( cNegativeFmTV | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis50 ), + .e = ( cAudioIF_6_0 | + cVideoIF_38_90 ), + },{ + .std = V4L2_STD_PAL_DK, + .name = "PAL-DK", + .b = ( cNegativeFmTV | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis50 ), + .e = ( cAudioIF_6_5 | + cVideoIF_38_00 ), + },{ + .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N, + .name = "PAL-M/N", + .b = ( cNegativeFmTV | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis75 ), + .e = ( cAudioIF_4_5 | + cVideoIF_45_75 ), + },{ + .std = V4L2_STD_SECAM_L, + .name = "SECAM-L", + .b = ( cPositiveAmTV | + cQSS ), + .e = ( cAudioIF_6_5 | + cVideoIF_38_90 ), + },{ + .std = V4L2_STD_SECAM_DK, + .name = "SECAM-DK", + .b = ( cNegativeFmTV | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis50 ), + .e = ( cAudioIF_6_5 | + cVideoIF_38_00 ), + },{ + .std = V4L2_STD_NTSC_M, + .name = "NTSC-M", + .b = ( cNegativeFmTV | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis50 ), + .e = ( cGating_36 | + cAudioIF_4_5 | + cVideoIF_45_75 ), + },{ + .std = V4L2_STD_NTSC_M_JP, + .name = "NTSC-JP", + .b = ( cNegativeFmTV | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis50 ), + .e = ( cGating_36 | + cAudioIF_4_5 | + cVideoIF_58_75 ), + } +}; + +static struct tvnorm radio = { + .name = "radio", + .b = ( cFmRadio | + cQSS ), + .c = ( cDeemphasisON | + cDeemphasis50 ), + .e = ( cAudioIF_5_5 | + cRadioIF_38_90 ), +}; + +/* ---------------------------------------------------------------------- */ + +static void dump_read_message(unsigned char *buf) { - int rc; - u8 bData[4] = { 0 }; - u8 bVideoIF = 0; - u8 bAudioIF = 0; - u8 bDeEmphasis = 0; - u8 bDeEmphVal = 0; - u8 bModulation = 0; - u8 bCarrierMode = 0; - u8 bOutPort1 = cOutputPort1Inactive; -#if 0 - u8 bOutPort2 = cOutputPort2Inactive & mbTADState; // store i2c tuner state -#else - u8 bOutPort2 = cOutputPort2Inactive; -#endif - u8 bVideoTrap = cVideoTrapBypassOFF; -#if 1 - u8 bTopAdjust = 0x0e /* -2dB */; -#else - u8 bTopAdjust = 0; -#endif + static char *afc[16] = { + "- 12.5 kHz", + "- 37.5 kHz", + "- 62.5 kHz", + "- 87.5 kHz", + "-112.5 kHz", + "-137.5 kHz", + "-162.5 kHz", + "-187.5 kHz [min]", + "+187.5 kHz [max]", + "+162.5 kHz", + "+137.5 kHz", + "+112.5 kHz", + "+ 87.5 kHz", + "+ 62.5 kHz", + "+ 37.5 kHz", + "+ 12.5 kHz", + }; + printk(PREFIX "read: 0x%2x\n", buf[0]); + printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); + printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); + printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); + printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); +} -#if 0 - if (mParams.fVideoTrap) - bVideoTrap = cVideoTrapBypassON; -#endif +static void dump_write_message(unsigned char *buf) +{ + static char *sound[4] = { + "AM/TV", + "FM/radio", + "FM/TV", + "FM/radio" + }; + static char *adjust[32] = { + "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9", + "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", + "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", + "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15" + }; + static char *deemph[4] = { + "no", "no", "75", "50" + }; + static char *carrier[4] = { + "4.5 MHz", + "5.5 MHz", + "6.0 MHz", + "6.5 MHz / AM" + }; + static char *vif[8] = { + "58.75 MHz", + "45.75 MHz", + "38.9 MHz", + "38.0 MHz", + "33.9 MHz", + "33.4 MHz", + "45.75 MHz + pin13", + "38.9 MHz + pin13", + }; + static char *rif[4] = { + "44 MHz", + "52 MHz", + "52 MHz", + "44 MHz", + }; + + printk(PREFIX "write: byte B 0x%02x\n",buf[1]); + printk(" B0 video mode : %s\n", + (buf[1] & 0x01) ? "video trap" : "sound trap"); + printk(" B1 auto mute fm : %s\n", + (buf[1] & 0x02) ? "yes" : "no"); + printk(" B2 carrier mode : %s\n", + (buf[1] & 0x04) ? "QSS" : "Intercarrier"); + printk(" B3-4 tv sound/radio : %s\n", + sound[(buf[1] & 0x18) >> 3]); + printk(" B5 force mute audio: %s\n", + (buf[1] & 0x20) ? "yes" : "no"); + printk(" B6 output port 1 : %s\n", + (buf[1] & 0x40) ? "high" : "low"); + printk(" B7 output port 2 : %s\n", + (buf[1] & 0x80) ? "high" : "low"); + + printk(PREFIX "write: byte C 0x%02x\n",buf[2]); + printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); + printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); + printk(" C7 audio gain : %s\n", + (buf[2] & 0x80) ? "-6" : "0"); + + printk(PREFIX "write: byte E 0x%02x\n",buf[3]); + printk(" E0-1 sound carrier : %s\n", + carrier[(buf[3] & 0x03)]); + printk(" E6 l pll ganting : %s\n", + (buf[3] & 0x40) ? "36" : "13"); + + if (buf[1] & 0x08) { + /* radio */ + printk(" E2-4 video if : %s\n", + rif[(buf[3] & 0x0c) >> 2]); + printk(" E7 vif agc output : %s\n", + (buf[3] & 0x80) + ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") + : "fm radio carrier afc"); + } else { + /* video */ + printk(" E2-4 video if : %s\n", + vif[(buf[3] & 0x1c) >> 2]); + printk(" E5 tuner gain : %s\n", + (buf[3] & 0x80) + ? ((buf[3] & 0x20) ? "external" : "normal") + : ((buf[3] & 0x20) ? "minimum" : "normal")); + printk(" E7 vif agc output : %s\n", + (buf[3] & 0x80) + ? ((buf[3] & 0x20) + ? "pin3 port, pin22 vif agc out" + : "pin22 port, pin3 vif acg ext in") + : "pin3+pin22 port"); + } + printk("--\n"); +} + +/* ---------------------------------------------------------------------- */ + +static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) +{ + struct tvnorm *norm = NULL; + int i; if (t->radio) { - bVideoTrap = cVideoTrapBypassOFF; - bCarrierMode = cQSS; - bModulation = cFmRadio; - bOutPort1 = cOutputPort1Inactive; - bDeEmphasis = cDeemphasisON; - if (3 == t->pinnacle_id) { - /* ntsc */ - bDeEmphVal = cDeemphasis75; - bAudioIF = cAudioIF_4_5; - bVideoIF = cRadioIF_45_75; - } else { - /* pal */ - bAudioIF = cAudioIF_5_5; - bVideoIF = cRadioIF_38_90; - bDeEmphVal = cDeemphasis50; + norm = &radio; + } else { + for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { + if (tvnorms[i].std & t->std) { + norm = tvnorms+i; + break; + } } + } + if (NULL == norm) { + dprintk(PREFIX "Oops: no tvnorm entry found\n"); + return -1; + } + + dprintk(PREFIX "configure for: %s\n",norm->name); + buf[1] = norm->b; + buf[2] = norm->c; + buf[3] = norm->e; + return 0; +} + +static unsigned int port1 = 1; +static unsigned int port2 = 1; +static unsigned int qss = UNSET; +static unsigned int adjust = 0x10; +MODULE_PARM(port1,"i"); +MODULE_PARM(port2,"i"); +MODULE_PARM(qss,"i"); +MODULE_PARM(adjust,"i"); + +static int tda9887_set_insmod(struct tda9887 *t, char *buf) +{ + if (port1) + buf[1] |= cOutputPort1Inactive; + if (port2) + buf[1] |= cOutputPort2Inactive; + if (UNSET != qss) { + if (qss) + buf[1] |= cQSS; + else + buf[1] &= ~cQSS; + } + + if (adjust >= 0x00 && adjust < 0x20) + buf[2] |= adjust; + return 0; +} + +/* ---------------------------------------------------------------------- */ - } else if (t->tvnorm == VIDEO_MODE_PAL) { - bDeEmphasis = cDeemphasisON; - bDeEmphVal = cDeemphasis50; - bModulation = cNegativeFmTV; - bOutPort1 = cOutputPort1Inactive; +static int tda9887_set_pinnacle(struct tda9887 *t, char *buf) +{ + unsigned int bCarrierMode = UNSET; + + if (t->std & V4L2_STD_PAL) { if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) { bCarrierMode = cIntercarrier; } else { - // stereo boards bCarrierMode = cQSS; } - switch (pal[0]) { - case 'b': - case 'g': - case 'h': - bVideoIF = cVideoIF_38_90; - bAudioIF = cAudioIF_5_5; - break; - case 'd': - bVideoIF = cVideoIF_38_00; - bAudioIF = cAudioIF_6_5; - break; - case 'i': - bVideoIF = cVideoIF_38_90; - bAudioIF = cAudioIF_6_0; - break; - case 'm': - case 'n': - bVideoIF = cVideoIF_45_75; - bAudioIF = cAudioIF_4_5; - bDeEmphVal = cDeemphasis75; - if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { - bCarrierMode = cIntercarrier; - } else { - bCarrierMode = cQSS; - } - break; - } - - } else if (t->tvnorm == VIDEO_MODE_SECAM) { - bAudioIF = cAudioIF_6_5; - bDeEmphasis = cDeemphasisON; - bDeEmphVal = cDeemphasis50; - bModulation = cNegativeFmTV; - bCarrierMode = cQSS; - bOutPort1 = cOutputPort1Inactive; - switch (secam[0]) { - case 'd': - bVideoIF = cVideoIF_38_00; - break; - case 'k': - bVideoIF = cVideoIF_38_90; - break; - case 'l': - bVideoIF = cVideoIF_38_90; - bDeEmphasis = cDeemphasisOFF; - bDeEmphVal = cDeemphasis75; - bModulation = cPositiveAmTV; - break; - case 'L' /* L1 */: - bVideoIF = cVideoIF_33_90; - bDeEmphasis = cDeemphasisOFF; - bDeEmphVal = cDeemphasis75; - bModulation = cPositiveAmTV; - break; - } - - } else if (t->tvnorm == VIDEO_MODE_NTSC) { - bVideoIF = cVideoIF_45_75; - bAudioIF = cAudioIF_4_5; - bDeEmphasis = cDeemphasisON; - bDeEmphVal = cDeemphasis75; - bModulation = cNegativeFmTV; - bOutPort1 = cOutputPort1Inactive; + } + if (t->std & V4L2_STD_NTSC) { if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { bCarrierMode = cIntercarrier; } else { @@ -249,99 +418,102 @@ } } - bData[1] = bVideoTrap | // B0: video trap bypass - cAutoMuteFmInactive | // B1: auto mute - bCarrierMode | // B2: InterCarrier for PAL else QSS - bModulation | // B3 - B4: positive AM TV for SECAM only - cForcedMuteAudioOFF | // B5: forced Audio Mute (off) - bOutPort1 | // B6: Out Port 1 - bOutPort2; // B7: Out Port 2 - bData[2] = bTopAdjust | // C0 - C4: Top Adjust 0 == -16dB 31 == 15dB - bDeEmphasis | // C5: De-emphasis on/off - bDeEmphVal | // C6: De-emphasis 50/75 microsec - cAudioGain0; // C7: normal audio gain - bData[3] = bAudioIF | // E0 - E1: Sound IF - bVideoIF | // E2 - E4: Video IF - cTunerGainNormal | // E5: Tuner gain (normal) - cGating_18 | // E6: Gating (18%) - cAgcOutOFF; // E7: VAGC (off) - - dprintk("tda9885/6/7: 0x%02x 0x%02x 0x%02x [pinnacle_id=%d]\n", - bData[1],bData[2],bData[3],t->pinnacle_id); - if (4 != (rc = i2c_master_send(&t->client,bData,4))) - printk("tda9885/6/7: i2c i/o error: rc == %d (should be 4)\n",rc); + if (bCarrierMode != UNSET) { + buf[1] &= ~0x04; + buf[1] |= bCarrierMode; + } return 0; } /* ---------------------------------------------------------------------- */ -#if 0 -/* just for reference: old knc-one saa7134 stuff */ -static unsigned char buf_pal_bg[] = { 0x00, 0x16, 0x70, 0x49 }; -static unsigned char buf_pal_i[] = { 0x00, 0x16, 0x70, 0x4a }; -static unsigned char buf_pal_dk[] = { 0x00, 0x16, 0x70, 0x4b }; -static unsigned char buf_pal_l[] = { 0x00, 0x06, 0x50, 0x4b }; -static unsigned char buf_fm_stereo[] = { 0x00, 0x0e, 0x0d, 0x77 }; -#endif - -static unsigned char buf_pal_bg[] = { 0x00, 0x96, 0x70, 0x49 }; -static unsigned char buf_pal_i[] = { 0x00, 0x96, 0x70, 0x4a }; -static unsigned char buf_pal_dk[] = { 0x00, 0x96, 0x70, 0x4b }; -static unsigned char buf_pal_l[] = { 0x00, 0x86, 0x50, 0x4b }; -static unsigned char buf_fm_stereo[] = { 0x00, 0x8e, 0x0d, 0x77 }; -static unsigned char buf_ntsc[] = { 0x00, 0x96, 0x70, 0x44 }; -static unsigned char buf_ntsc_jp[] = { 0x00, 0x96, 0x70, 0x40 }; +static char *pal = "-"; +MODULE_PARM(pal,"s"); +static char *secam = "-"; +MODULE_PARM(secam,"s"); -static int tda9887_configure(struct tda9887 *t) +static int tda9887_fixup_std(struct tda9887 *t) { - unsigned char *buf = NULL; - int rc; - - if (t->radio) { - dprintk("tda9885/6/7: FM Radio mode\n"); - buf = buf_fm_stereo; - - } else if (t->tvnorm == VIDEO_MODE_PAL) { - dprintk("tda9885/6/7: PAL-%c mode\n",pal[0]); + /* get more precise norm info from insmod option */ + if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { switch (pal[0]) { case 'b': + case 'B': case 'g': - buf = buf_pal_bg; + case 'G': + dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n"); + t->std = V4L2_STD_PAL_BG; break; case 'i': - buf = buf_pal_i; + case 'I': + dprintk(PREFIX "insmod fixup: PAL => PAL-I\n"); + t->std = V4L2_STD_PAL_I; + break; + case 'd': + case 'D': + case 'k': + case 'K': + dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n"); + t->std = V4L2_STD_PAL_DK; break; + } + } + if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { + switch (secam[0]) { case 'd': + case 'D': case 'k': - buf = buf_pal_dk; + case 'K': + dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n"); + t->std = V4L2_STD_SECAM_DK; break; case 'l': - buf = buf_pal_l; + case 'L': + dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n"); + t->std = V4L2_STD_SECAM_L; break; } + } + return 0; +} - } else if (t->tvnorm == VIDEO_MODE_NTSC) { - dprintk("tda9885/6/7: NTSC mode\n"); - buf = buf_ntsc; +static int tda9887_status(struct tda9887 *t) +{ + unsigned char buf[1]; + int rc; - } else if (t->tvnorm == VIDEO_MODE_SECAM) { - dprintk("tda9885/6/7: SECAM mode\n"); - buf = buf_pal_l; + memset(buf,0,sizeof(buf)); + if (1 != (rc = i2c_master_recv(&t->client,buf,1))) + printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); + dump_read_message(buf); + return 0; +} - } else if (t->tvnorm == 6 /* BTTV hack */) { - dprintk("tda9885/6/7: NTSC-Japan mode\n"); - buf = buf_ntsc_jp; - } +static int tda9887_configure(struct tda9887 *t) +{ + unsigned char buf[4]; + int rc; - if (NULL == buf) { - printk("tda9885/6/7 unknown norm=%d\n",t->tvnorm); - return 0; + memset(buf,0,sizeof(buf)); + tda9887_set_tvnorm(t,buf); + if (UNSET != t->pinnacle_id) { + tda9887_set_pinnacle(t,buf); } + tda9887_set_insmod(t,buf); - dprintk("tda9885/6/7: 0x%02x 0x%02x 0x%02x\n", + dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", buf[1],buf[2],buf[3]); + if (debug > 1) + dump_write_message(buf); + if (4 != (rc = i2c_master_send(&t->client,buf,4))) - printk("tda9885/6/7: i2c i/o error: rc == %d (should be 4)\n",rc); + printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc); + + if (debug > 2) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + tda9887_status(t); + } return 0; } @@ -354,14 +526,14 @@ client_template.adapter = adap; client_template.addr = addr; - printk("tda9887: chip found @ 0x%x\n", addr<<1); + printk(PREFIX "chip found @ 0x%x\n", addr<<1); if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) return -ENOMEM; memset(t,0,sizeof(*t)); - t->client = client_template; - t->pinnacle_id = -1; - t->tvnorm=VIDEO_MODE_PAL; + t->client = client_template; + t->std = 0;; + t->pinnacle_id = UNSET; i2c_set_clientdata(&t->client, t); i2c_attach_client(&t->client); @@ -394,6 +566,13 @@ return 0; } +#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ + printk(PREFIX "switching to v4l2\n"); \ + t->using_v4l2 = 1; +#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ + printk(PREFIX "ignore v4l1 call\n"); \ + return 0; } + static int tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -404,10 +583,7 @@ /* --- configuration --- */ case AUDC_SET_RADIO: t->radio = 1; - if (-1 != t->pinnacle_id) - tda9887_miro(t); - else - tda9887_configure(t); + tda9887_configure(t); break; case AUDC_CONFIG_PINNACLE: @@ -415,7 +591,7 @@ int *i = arg; t->pinnacle_id = *i; - tda9887_miro(t); + tda9887_configure(t); break; } /* --- v4l ioctls --- */ @@ -423,15 +599,51 @@ kernel pointer here... */ case VIDIOCSCHAN: { + static const v4l2_std_id map[] = { + [ VIDEO_MODE_PAL ] = V4L2_STD_PAL, + [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M, + [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM, + [ 4 /* bttv */ ] = V4L2_STD_PAL_M, + [ 5 /* bttv */ ] = V4L2_STD_PAL_N, + [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP, + }; struct video_channel *vc = arg; - t->radio = 0; - t->tvnorm = vc->norm; - if (-1 != t->pinnacle_id) - tda9887_miro(t); - else - tda9887_configure(t); + CHECK_V4L2; + t->radio = 0; + if (vc->norm < ARRAY_SIZE(map)) + t->std = map[vc->norm]; + tda9887_fixup_std(t); + tda9887_configure(t); + break; + } + case VIDIOC_S_STD: + { + v4l2_std_id *id = arg; + + SWITCH_V4L2; + t->radio = 0; + t->std = *id; + tda9887_fixup_std(t); + tda9887_configure(t); break; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; + + SWITCH_V4L2; + if (V4L2_TUNER_ANALOG_TV == f->type) { + if (t->radio == 0) + return 0; + t->radio = 0; + } + if (V4L2_TUNER_RADIO == f->type) { + if (t->radio == 1) + return 0; + t->radio = 1; + } + tda9887_configure(t); } default: /* nothing */ diff -Nru a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c --- a/drivers/media/video/tuner.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/media/video/tuner.c 2004-06-26 17:09:20 -07:00 @@ -26,15 +26,17 @@ static unsigned int debug = 0; static unsigned int type = UNSET; static unsigned int addr = 0; -static char *pal = "b"; static unsigned int tv_range[2] = { 44, 958 }; static unsigned int radio_range[2] = { 65, 108 }; +static unsigned int tv_antenna = 1; +static unsigned int radio_antenna = 0; MODULE_PARM(debug,"i"); MODULE_PARM(type,"i"); MODULE_PARM(addr,"i"); MODULE_PARM(tv_range,"2i"); MODULE_PARM(radio_range,"2i"); -MODULE_PARM(pal,"s"); +MODULE_PARM(tv_antenna,"i"); +MODULE_PARM(radio_antenna,"i"); #define optimize_vco 1 @@ -48,10 +50,10 @@ struct tuner { unsigned int type; /* chip type */ unsigned int freq; /* keep track of the current settings */ - unsigned int std; + v4l2_std_id std; + int using_v4l2; unsigned int radio; - unsigned int mode; /* current norm for multi-norm tuners */ unsigned int input; // only for MT2032 @@ -537,15 +539,16 @@ int if2,from,to; // signal bandwidth and picture carrier - if (t->mode == VIDEO_MODE_NTSC) { - from=40750*1000; - to=46750*1000; - if2=45750*1000; + if (t->std & V4L2_STD_525_60) { + // NTSC + from = 40750*1000; + to = 46750*1000; + if2 = 45750*1000; } else { - // Pal - from=32900*1000; - to=39900*1000; - if2=38900*1000; + // PAL + from = 32900*1000; + to = 39900*1000; + if2 = 38900*1000; } mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, @@ -619,6 +622,17 @@ return(1); } +static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) +{ + unsigned char buf[2]; + int ret; + + buf[0] = 6; + buf[1] = antenna ? 0x11 : 0x10; + ret=i2c_master_send(c,buf,2); + dprintk("mt2050: enabled antenna connector %d\n", antenna); +} + static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2) { unsigned int if1=1218*1000*1000; @@ -683,13 +697,15 @@ struct tuner *t = i2c_get_clientdata(c); unsigned int if2; - if (t->mode == VIDEO_MODE_NTSC) { - if2=45750*1000; + if (t->std & V4L2_STD_525_60) { + // NTSC + if2 = 45750*1000; } else { - // Pal - if2=38900*1000; + // PAL + if2 = 38900*1000; } - mt2050_set_if_freq(c,freq*62500,if2); + mt2050_set_if_freq(c, freq*62500, if2); + mt2050_set_antenna(c, tv_antenna); } static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq) @@ -698,6 +714,7 @@ int if2 = t->radio_if2; mt2050_set_if_freq(c, freq*62500, if2); + mt2050_set_antenna(c, radio_antenna); } static int mt2050_init(struct i2c_client *c) @@ -731,8 +748,8 @@ unsigned char buf[21]; int company_code; - buf[0] = 0; - t->tv_freq = NULL; + memset(buf,0,sizeof(buf)); + t->tv_freq = NULL; t->radio_freq = NULL; name = "unknown"; @@ -751,6 +768,9 @@ company_code = buf[0x11] << 8 | buf[0x12]; printk("tuner: microtune: companycode=%04x part=%02x rev=%02x\n", company_code,buf[0x13],buf[0x14]); + +#if 0 + /* seems to cause more problems than it solves ... */ switch (company_code) { case 0x30bf: case 0x3cbf: @@ -764,6 +784,7 @@ printk("tuner: microtune: unknown companycode\n"); return 0; } +#endif if (buf[0x13] < ARRAY_SIZE(microtune_part) && NULL != microtune_part[buf[0x13]]) @@ -811,54 +832,40 @@ /* 0x02 -> PAL BDGHI / SECAM L */ /* 0x04 -> ??? PAL others / SECAM others ??? */ config &= ~0x02; - if (t->mode == VIDEO_MODE_SECAM) + if (t->std & V4L2_STD_SECAM) config |= 0x02; break; case TUNER_TEMIC_4046FM5: config &= ~0x0f; - switch (pal[0]) { - case 'i': - case 'I': + + if (t->std & V4L2_STD_PAL_BG) { + config |= TEMIC_SET_PAL_BG; + + } else if (t->std & V4L2_STD_PAL_I) { config |= TEMIC_SET_PAL_I; - break; - case 'd': - case 'D': + + } else if (t->std & V4L2_STD_PAL_DK) { config |= TEMIC_SET_PAL_DK; - break; - case 'l': - case 'L': + + } else if (t->std & V4L2_STD_SECAM_L) { config |= TEMIC_SET_PAL_L; - break; - case 'b': - case 'B': - case 'g': - case 'G': - default: - config |= TEMIC_SET_PAL_BG; - break; + } break; case TUNER_PHILIPS_FQ1216ME: config &= ~0x0f; - switch (pal[0]) { - case 'i': - case 'I': + + if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { + config |= PHILIPS_SET_PAL_BGDK; + + } else if (t->std & V4L2_STD_PAL_I) { config |= PHILIPS_SET_PAL_I; - break; - case 'l': - case 'L': + + } else if (t->std & V4L2_STD_SECAM_L) { config |= PHILIPS_SET_PAL_L; - break; - case 'd': - case 'D': - case 'b': - case 'B': - case 'g': - case 'G': - config |= PHILIPS_SET_PAL_BGDK; - break; + } break; @@ -867,12 +874,9 @@ /* 0x01 -> ATSC antenna input 2 */ /* 0x02 -> NTSC antenna input 1 */ /* 0x03 -> NTSC antenna input 2 */ - config &= ~0x03; -#ifdef VIDEO_MODE_ATSC - if (VIDEO_MODE_ATSC != t->mode) + if (t->std & V4L2_STD_ATSC) config |= 2; -#endif /* FIXME: input */ break; } @@ -990,6 +994,22 @@ t->radio_freq(c,freq); } +static void set_freq(struct i2c_client *c, unsigned long freq) +{ + struct tuner *t = i2c_get_clientdata(c); + + if (t->radio) { + dprintk("tuner: radio freq set to %lu.%02lu\n", + freq/16,freq%16*100/16); + set_radio_freq(c,freq); + } else { + dprintk("tuner: tv freq set to %lu.%02lu\n", + freq/16,freq%16*100/16); + set_tv_freq(c, freq); + } + t->freq = freq; +} + static void set_type(struct i2c_client *c, unsigned int type, char *source) { struct tuner *t = i2c_get_clientdata(c); @@ -1019,6 +1039,38 @@ } } +static char *pal = "-"; +MODULE_PARM(pal,"s"); + +static int tuner_fixup_std(struct tuner *t) +{ + if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { + /* get more precise norm info from insmod option */ + switch (pal[0]) { + case 'b': + case 'B': + case 'g': + case 'G': + dprintk("insmod fixup: PAL => PAL-BG\n"); + t->std = V4L2_STD_PAL_BG; + break; + case 'i': + case 'I': + dprintk("insmod fixup: PAL => PAL-I\n"); + t->std = V4L2_STD_PAL_I; + break; + case 'd': + case 'D': + case 'k': + case 'K': + dprintk("insmod fixup: PAL => PAL-DK\n"); + t->std = V4L2_STD_PAL_DK; + break; + } + } + return 0; +} + /* ---------------------------------------------------------------------- */ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) @@ -1054,7 +1106,7 @@ set_type(client, type, "insmod option"); printk("tuner: The type= insmod option will go away soon.\n"); printk("tuner: Please use the tuner= option provided by\n"); - printk("tuner: tv card core driver (bttv, saa7134, ...) instead.\n"); + printk("tuner: tv aard core driver (bttv, saa7134, ...) instead.\n"); } return 0; } @@ -1094,6 +1146,13 @@ return 0; } +#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ + printk("tuner: switching to v4l2\n"); \ + t->using_v4l2 = 1; +#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ + printk("tuner: ignore v4l1 call\n"); \ + return 0; } + static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -1130,10 +1189,21 @@ kernel pointer here... */ case VIDIOCSCHAN: { + static const v4l2_std_id map[] = { + [ VIDEO_MODE_PAL ] = V4L2_STD_PAL, + [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M, + [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM, + [ 4 /* bttv */ ] = V4L2_STD_PAL_M, + [ 5 /* bttv */ ] = V4L2_STD_PAL_N, + [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP, + }; struct video_channel *vc = arg; + CHECK_V4L2; t->radio = 0; - t->mode = vc->norm; + if (vc->norm < ARRAY_SIZE(map)) + t->std = map[vc->norm]; + tuner_fixup_std(t); if (t->freq) set_tv_freq(client,t->freq); return 0; @@ -1142,22 +1212,15 @@ { unsigned long *v = arg; - if (t->radio) { - dprintk("tuner: radio freq set to %lu.%02lu\n", - (*v)/16,(*v)%16*100/16); - set_radio_freq(client,*v); - } else { - dprintk("tuner: tv freq set to %lu.%02lu\n", - (*v)/16,(*v)%16*100/16); - set_tv_freq(client,*v); - } - t->freq = *v; + CHECK_V4L2; + set_freq(client,*v); return 0; } case VIDIOCGTUNER: { struct video_tuner *vt = arg; + CHECK_V4L2; if (t->radio) vt->signal = tuner_signal(client); return 0; @@ -1165,9 +1228,51 @@ case VIDIOCGAUDIO: { struct video_audio *va = arg; + + CHECK_V4L2; if (t->radio) va->mode = (tuner_stereo(client) ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO); return 0; + } + + case VIDIOC_S_STD: + { + v4l2_std_id *id = arg; + + SWITCH_V4L2; + t->radio = 0; + t->std = *id; + tuner_fixup_std(t); + if (t->freq) + set_freq(client,t->freq); + break; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; + + SWITCH_V4L2; + if (V4L2_TUNER_ANALOG_TV == f->type) { + t->radio = 0; + } + if (V4L2_TUNER_RADIO == f->type) { + if (!t->radio) { + set_tv_freq(client,400*16); + t->radio = 1; + } + } + t->freq = f->frequency; + set_freq(client,t->freq); + break; + } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *tuner = arg; + + SWITCH_V4L2; + if (t->radio) + tuner->signal = tuner_signal(client); + break; } default: /* nothing */ diff -Nru a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c --- a/drivers/media/video/video-buf.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/media/video/video-buf.c 2004-06-26 17:09:18 -07:00 @@ -5,10 +5,10 @@ * The functions expect the hardware being able to scatter gatter * (i.e. the buffers are not linear in physical memory, but fragmented * into PAGE_SIZE chunks). They also assume the driver does not need - * to touch the video data (thus it is probably not useful for USB as - * data often must be uncompressed by the drivers). + * to touch the video data (thus it is probably not useful for USB 1.1 + * as data often must be uncompressed by the drivers). * - * (c) 2001,02 Gerd Knorr + * (c) 2001-2004 Gerd Knorr [SUSE Labs] * * 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 @@ -28,6 +28,11 @@ #include +#define MAGIC_DMABUF 0x19721112 +#define MAGIC_BUFFER 0x20040302 +#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ + { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } + static int debug = 0; MODULE_DESCRIPTION("helper module to manage video4linux pci dma buffers"); @@ -109,6 +114,12 @@ /* --------------------------------------------------------------------- */ +void videobuf_dma_init(struct videobuf_dmabuf *dma) +{ + memset(dma,0,sizeof(*dma)); + dma->magic = MAGIC_DMABUF; +} + int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction, unsigned long data, unsigned long size) { @@ -178,8 +189,8 @@ int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma) { - if (0 == dma->nr_pages) - BUG(); + MAGIC_CHECK(dma->magic,MAGIC_DMABUF); + BUG_ON(0 == dma->nr_pages); if (dma->pages) { dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, @@ -211,8 +222,8 @@ int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma) { - if (!dma->sglen) - BUG(); + MAGIC_CHECK(dma->magic,MAGIC_DMABUF); + BUG_ON(!dma->sglen); if (!dma->bus_addr) pci_dma_sync_sg_for_cpu(dev,dma->sglist,dma->nr_pages,dma->direction); @@ -221,6 +232,7 @@ int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma) { + MAGIC_CHECK(dma->magic,MAGIC_DMABUF); if (!dma->sglen) return 0; @@ -234,8 +246,8 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma) { - if (dma->sglen) - BUG(); + MAGIC_CHECK(dma->magic,MAGIC_DMABUF); + BUG_ON(dma->sglen); if (dma->pages) { int i; @@ -264,7 +276,9 @@ vb = kmalloc(size,GFP_KERNEL); if (NULL != vb) { memset(vb,0,size); + videobuf_dma_init(&vb->dma); init_waitqueue_head(&vb->done); + vb->magic = MAGIC_BUFFER; } return vb; } @@ -274,6 +288,7 @@ int retval = 0; DECLARE_WAITQUEUE(wait, current); + MAGIC_CHECK(vb->magic,MAGIC_BUFFER); add_wait_queue(&vb->done, &wait); while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) { if (non_blocking) { @@ -302,6 +317,7 @@ int err,pages; dma_addr_t bus; + MAGIC_CHECK(vb->magic,MAGIC_BUFFER); switch (vb->memory) { case V4L2_MEMORY_MMAP: case V4L2_MEMORY_USERPTR: @@ -453,6 +469,8 @@ videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb, enum v4l2_buf_type type) { + MAGIC_CHECK(vb->magic,MAGIC_BUFFER); + b->index = vb->i; b->type = type; @@ -491,6 +509,11 @@ break; } + if (vb->input != UNSET) { + b->flags |= V4L2_BUF_FLAG_INPUT; + b->input = vb->input; + } + b->field = vb->field; b->timestamp = vb->ts; b->bytesused = vb->size; @@ -513,6 +536,11 @@ req->memory != V4L2_MEMORY_OVERLAY) return -EINVAL; + if (q->streaming) + return -EBUSY; + if (!list_empty(&q->stream)) + return -EBUSY; + down(&q->lock); count = req->count; if (count > VIDEO_MAX_FRAME) @@ -568,12 +596,21 @@ buf = q->bufs[b->index]; if (NULL == buf) goto done; + MAGIC_CHECK(buf->magic,MAGIC_BUFFER); if (buf->memory != b->memory) goto done; if (buf->state == STATE_QUEUED || buf->state == STATE_ACTIVE) goto done; + if (b->flags & V4L2_BUF_FLAG_INPUT) { + if (b->input >= q->inputs) + goto done; + buf->input = b->input; + } else { + buf->input = UNSET; + } + switch (b->memory) { case V4L2_MEMORY_MMAP: if (0 == buf->baddr) @@ -582,6 +619,8 @@ case V4L2_MEMORY_USERPTR: if (b->length < buf->bsize) goto done; + if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr) + q->ops->buf_release(file,buf); buf->baddr = b->m.userptr; break; case V4L2_MEMORY_OVERLAY: @@ -1075,6 +1114,7 @@ for (i = 0; i < bcount; i++) { q->bufs[i] = videobuf_alloc(q->msize); q->bufs[i]->i = i; + q->bufs[i]->input = UNSET; q->bufs[i]->memory = memory; q->bufs[i]->bsize = bsize; switch (memory) { @@ -1085,7 +1125,7 @@ case V4L2_MEMORY_OVERLAY: /* nothing */ break; - }; + } } dprintk(1,"mmap setup: %d buffers, %d bytes each\n", bcount,bsize); @@ -1192,6 +1232,7 @@ EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg); +EXPORT_SYMBOL_GPL(videobuf_dma_init); EXPORT_SYMBOL_GPL(videobuf_dma_init_user); EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel); EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay); diff -Nru a/drivers/message/fusion/isense.c b/drivers/message/fusion/isense.c --- a/drivers/message/fusion/isense.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/message/fusion/isense.c 2004-06-26 17:09:18 -07:00 @@ -56,14 +56,6 @@ #include #include #include -#if defined (__sparc__) -#include -#endif - -/* Hmmm, avoid undefined spinlock_t on lk-2.2.14-5.0 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -#include -#endif #define MODULEAUTHOR "Steven J. Ralston" #define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR diff -Nru a/drivers/message/fusion/linux_compat.h b/drivers/message/fusion/linux_compat.h --- a/drivers/message/fusion/linux_compat.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/message/fusion/linux_compat.h 2004-06-26 17:09:17 -07:00 @@ -2,196 +2,7 @@ #ifndef FUSION_LINUX_COMPAT_H #define FUSION_LINUX_COMPAT_H -/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#include -#include -#include -#include - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -#ifndef rwlock_init -#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) -#endif - -#define SET_NICE(current,x) do {(current)->nice = (x);} while (0) - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) - typedef unsigned int dma_addr_t; -# endif -#else -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42) - typedef unsigned int dma_addr_t; -# endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) -/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -/* This block snipped from lk-2.2.18/include/linux/init.h { */ -/* - * Used for initialization calls.. - */ -typedef int (*initcall_t)(void); -typedef void (*exitcall_t)(void); - -#define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) -#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit"))) - -extern initcall_t __initcall_start, __initcall_end; - -#define __initcall(fn) \ - static initcall_t __initcall_##fn __init_call = fn -#define __exitcall(fn) \ - static exitcall_t __exitcall_##fn __exit_call = fn - -#ifdef MODULE -/* These macros create a dummy inline: gcc 2.9x does not count alias - as usage, hence the `unused function' warning when __init functions - are declared static. We use the dummy __*_module_inline functions - both to kill the warning and check the type of the init/cleanup - function. */ -typedef int (*__init_module_func_t)(void); -typedef void (*__cleanup_module_func_t)(void); -#define module_init(x) \ - int init_module(void) __attribute__((alias(#x))); \ - static inline __init_module_func_t __init_module_inline(void) \ - { return x; } -#define module_exit(x) \ - void cleanup_module(void) __attribute__((alias(#x))); \ - static inline __cleanup_module_func_t __cleanup_module_inline(void) \ - { return x; } - -#else -#define module_init(x) __initcall(x); -#define module_exit(x) __exitcall(x); -#endif -/* } block snipped from lk-2.2.18/include/linux/init.h */ - -/* This block snipped from lk-2.2.18/include/linux/sched.h { */ -/* - * Used prior to schedule_timeout calls.. - */ -#define __set_current_state(state_value) do { current->state = state_value; } while (0) -#ifdef CONFIG_SMP -#define set_current_state(state_value) do { __set_current_state(state_value); mb(); } while (0) -#else -#define set_current_state(state_value) __set_current_state(state_value) -#endif -/* } block snipped from lk-2.2.18/include/linux/sched.h */ - -/* procfs compat stuff... */ -#define proc_mkdir(x,y) create_proc_entry(x, S_IFDIR, y) - -/* MUTEX compat stuff... */ -#define DECLARE_MUTEX(name) struct semaphore name=MUTEX -#define DECLARE_MUTEX_LOCKED(name) struct semaphore name=MUTEX_LOCKED -#define init_MUTEX(x) *(x)=MUTEX -#define init_MUTEX_LOCKED(x) *(x)=MUTEX_LOCKED - -/* Wait queues. */ -#define DECLARE_WAIT_QUEUE_HEAD(name) \ - struct wait_queue * (name) = NULL -#define DECLARE_WAITQUEUE(name, task) \ - struct wait_queue (name) = { (task), NULL } - -#if defined(__sparc__) && defined(__sparc_v9__) -/* The sparc64 ioremap implementation is wrong in 2.2.x, - * but fixing it would break all of the drivers which - * workaround it. Fixed in 2.3.x onward. -DaveM - */ -#define ARCH_IOREMAP(base) ((unsigned long) (base)) -#else -#define ARCH_IOREMAP(base) ioremap(base) -#endif - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#else /* LINUX_VERSION_CODE must be >= KERNEL_VERSION(2,2,18) */ - -/* No ioremap bugs in >2.3.x kernels. */ -#define ARCH_IOREMAP(base) ioremap(base) - -/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */ - - -/* - * Inclined to use: - * #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) - * here, but MODULE_LICENSE defined in 2.4.9-6 and 2.4.9-13 - * breaks the rule:-( - */ -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(license) -#endif - - -/* PCI/driver subsystem { */ -#define PCI_BASEADDR_FLAGS(idx) resource[idx].flags -#define PCI_BASEADDR_START(idx) resource[idx].start -#define PCI_BASEADDR_SIZE(dev,idx) (dev)->resource[idx].end - (dev)->resource[idx].start + 1 - -/* Compatability for the 2.3.x PCI DMA API. */ -#ifndef PCI_DMA_BIDIRECTIONAL -/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -#define PCI_DMA_BIDIRECTIONAL 0 -#define PCI_DMA_TODEVICE 1 -#define PCI_DMA_FROMDEVICE 2 -#define PCI_DMA_NONE 3 - -#ifdef __KERNEL__ -#include -/* Pure 2^n version of get_order */ -static __inline__ int __get_order(unsigned long size) -{ - int order; - - size = (size-1) >> (PAGE_SHIFT-1); - order = -1; - do { - size >>= 1; - order++; - } while (size); - return order; -} -#endif - -#define pci_alloc_consistent(hwdev, size, dma_handle) \ -({ void *__ret = (void *)__get_free_pages(GFP_ATOMIC, __get_order(size)); \ - if (__ret != NULL) { \ - memset(__ret, 0, size); \ - *(dma_handle) = virt_to_bus(__ret); \ - } \ - __ret; \ -}) - -#define pci_free_consistent(hwdev, size, vaddr, dma_handle) \ - free_pages((unsigned long)vaddr, __get_order(size)) - -#define pci_map_single(hwdev, ptr, size, direction) \ - virt_to_bus(ptr); - -#define pci_unmap_single(hwdev, dma_addr, size, direction) \ - do { /* Nothing to do */ } while (0) - -#define pci_map_sg(hwdev, sg, nents, direction) (nents) -#define pci_unmap_sg(hwdev, sg, nents, direction) \ - do { /* Nothing to do */ } while(0) - -#define sg_dma_address(sg) (virt_to_bus((sg)->address)) -#define sg_dma_len(sg) ((sg)->length) - -/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#endif /* PCI_DMA_BIDIRECTIONAL */ - - -#define mpt_work_struct work_struct -#define MPT_INIT_WORK(_task, _func, _data) INIT_WORK(_task, _func, _data) -#define mpt_sync_irq(_irq) synchronize_irq(_irq) /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* _LINUX_COMPAT_H */ - diff -Nru a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h --- a/drivers/message/fusion/lsi/mpi_type.h 2004-06-26 17:09:19 -07:00 +++ b/drivers/message/fusion/lsi/mpi_type.h 2004-06-26 17:09:19 -07:00 @@ -47,18 +47,13 @@ typedef unsigned short U16; -#if defined(unix) || defined(__arm) || defined(ALPHA) - - typedef signed int S32; - typedef unsigned int U32; - -#else - - typedef signed long S32; - typedef unsigned long U32; - -#endif +typedef int32_t S32; +typedef u_int32_t U32; +/* + * The only way crap below could work on big-endian boxen would be if it + * wasn't used at all. + */ typedef struct _S64 { diff -Nru a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c --- a/drivers/message/fusion/mptbase.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/message/fusion/mptbase.c 2004-06-26 17:09:16 -07:00 @@ -1311,14 +1311,14 @@ mem_phys = msize = 0; port = psize = 0; for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { - if (pdev->PCI_BASEADDR_FLAGS(ii) & PCI_BASE_ADDRESS_SPACE_IO) { + if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { /* Get I/O space! */ - port = pdev->PCI_BASEADDR_START(ii); - psize = PCI_BASEADDR_SIZE(pdev,ii); + port = pci_resource_start(pdev, ii); + psize = pci_resource_len(pdev,ii); } else { /* Get memmap */ - mem_phys = pdev->PCI_BASEADDR_START(ii); - msize = PCI_BASEADDR_SIZE(pdev,ii); + mem_phys = pci_resource_start(pdev, ii); + msize = pci_resource_len(pdev,ii); break; } } @@ -1524,7 +1524,7 @@ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); ioc->active = 0; - mpt_sync_irq(pdev->irq); + synchronize_irq(pdev->irq); /* Clear any lingering interrupt */ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); @@ -3799,7 +3799,8 @@ /* Prime reply FIFO... */ dprintk((KERN_INFO MYNAM ": %s.reply_alloc @ %p[%p], sz=%d bytes\n", - ioc->name, mem, (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz)); + ioc->name, ioc->reply_alloc, + (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz)); b = (unsigned long) ioc->reply_alloc; b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */ @@ -3812,7 +3813,8 @@ /* Request FIFO - WE manage this! */ dprintk((KERN_INFO MYNAM ": %s.req_alloc @ %p[%p], sz=%d bytes\n", - ioc->name, mem, (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz)); + ioc->name, ioc->req_alloc, + (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz)); b = (unsigned long) ioc->req_alloc; b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */ diff -Nru a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h --- a/drivers/message/fusion/mptbase.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/message/fusion/mptbase.h 2004-06-26 17:09:16 -07:00 @@ -55,7 +55,11 @@ #define MPTBASE_H_INCLUDED /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#include "linux_compat.h" /* linux-2.2.x (vs. -2.4.x) tweaks */ +#include +#include +#include +#include + #include "scsi3.h" /* SCSI defines */ #include "lsi/mpi_type.h" @@ -81,8 +85,8 @@ #define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.01.06" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.06" +#define MPT_LINUX_VERSION_COMMON "3.01.07" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.07" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ diff -Nru a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c --- a/drivers/message/fusion/mptctl.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/message/fusion/mptctl.c 2004-06-26 17:09:15 -07:00 @@ -83,6 +83,7 @@ #include #include #include +#include #include #include @@ -102,9 +103,6 @@ #define my_VERSION MPT_LINUX_VERSION_COMMON #define MYNAM "mptctl" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62) -EXPORT_NO_SYMBOLS; -#endif MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); @@ -144,8 +142,8 @@ /* * Private function calls. */ -static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local); -static int mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen); +static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr); +static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen); static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags, struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc); static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma, @@ -547,38 +545,6 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* - * struct file_operations functionality. - * Members: - * llseek, write, read, ioctl, open, release - */ -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) -static loff_t -mptctl_llseek(struct file *file, loff_t offset, int origin) -{ - return -ESPIPE; -} -#define no_llseek mptctl_llseek -#endif - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -static ssize_t -mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - printk(KERN_ERR MYNAM ": ioctl WRITE not yet supported\n"); - return 0; -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -static ssize_t -mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr) -{ - printk(KERN_ERR MYNAM ": ioctl READ not yet supported\n"); - return 0; -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* * MPT ioctl handler * cmd - specify the particular IOCTL command to be issued * arg - data specific to the command. Must not be null. @@ -586,7 +552,7 @@ static int mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - mpt_ioctl_header *uhdr = (mpt_ioctl_header *) arg; + mpt_ioctl_header __user *uhdr = (void __user *) arg; mpt_ioctl_header khdr; int iocnum; unsigned iocnumX; @@ -599,7 +565,7 @@ if (copy_from_user(&khdr, uhdr, sizeof(khdr))) { printk(KERN_ERR "%s::mptctl_ioctl() @%d - " "Unable to copy mpt_ioctl_header data @ %p\n", - __FILE__, __LINE__, (void*)uhdr); + __FILE__, __LINE__, uhdr); return -EFAULT; } ret = -ENXIO; /* (-6) No such device or address */ @@ -671,7 +637,7 @@ static int mptctl_do_reset(unsigned long arg) { - struct mpt_ioctl_diag_reset *urinfo = (struct mpt_ioctl_diag_reset *) arg; + struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg; struct mpt_ioctl_diag_reset krinfo; MPT_ADAPTER *iocp; @@ -680,7 +646,7 @@ if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) { printk(KERN_ERR "%s@%d::mptctl_do_reset - " "Unable to copy mpt_ioctl_diag_reset struct @ %p\n", - __FILE__, __LINE__, (void*)urinfo); + __FILE__, __LINE__, urinfo); return -EFAULT; } @@ -700,21 +666,6 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -static int mptctl_open(struct inode *inode, struct file *file) -{ - /* - * Should support multiple management users - */ - return 0; -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -static int mptctl_release(struct inode *inode, struct file *file) -{ - return 0; -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * MPT FW download function. Cast the arg into the mpt_fw_xfer structure. * This structure contains: iocnum, firmware length (bytes), @@ -734,14 +685,14 @@ static int mptctl_fw_download(unsigned long arg) { - struct mpt_fw_xfer *ufwdl = (struct mpt_fw_xfer *) arg; + struct mpt_fw_xfer __user *ufwdl = (void __user *) arg; struct mpt_fw_xfer kfwdl; dctlprintk((KERN_INFO "mptctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) { printk(KERN_ERR "%s@%d::_ioctl_fwdl - " "Unable to copy mpt_fw_xfer struct @ %p\n", - __FILE__, __LINE__, (void*)ufwdl); + __FILE__, __LINE__, ufwdl); return -EFAULT; } @@ -763,7 +714,7 @@ * -ENOMSG if FW upload returned bad status */ static int -mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen) +mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) { FWDownload_t *dlmsg; MPT_FRAME_HDR *mf; @@ -892,7 +843,7 @@ if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) { printk(KERN_ERR "%s@%d::_ioctl_fwdl - " "Unable to copy f/w buffer hunk#%d @ %p\n", - __FILE__, __LINE__, n, (void*)ufwbuf); + __FILE__, __LINE__, n, ufwbuf); goto fwdl_out; } fw_bytes_copied += bl->len; @@ -1198,7 +1149,7 @@ static int mptctl_getiocinfo (unsigned long arg, unsigned int data_size) { - struct mpt_ioctl_iocinfo *uarg = (struct mpt_ioctl_iocinfo *) arg; + struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_iocinfo *karg; MPT_ADAPTER *ioc; struct pci_dev *pdev; @@ -1238,7 +1189,7 @@ if (copy_from_user(karg, uarg, data_size)) { printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " "Unable to read in mpt_ioctl_iocinfo struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); kfree(karg); return -EFAULT; } @@ -1278,10 +1229,8 @@ karg->pciId = pdev->device; pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); karg->hwRev = revision; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) karg->subSystemDevice = pdev->subsystem_device; karg->subSystemVendor = pdev->subsystem_vendor; -#endif if (cim_rev == 1) { /* Get the PCI bus, device, and function numbers for the IOC @@ -1335,10 +1284,10 @@ /* Copy the data from kernel memory to user memory */ - if (copy_to_user((char *)arg, karg, data_size)) { + if (copy_to_user((char __user *)arg, karg, data_size)) { printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " "Unable to write out mpt_ioctl_iocinfo struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); kfree(karg); return -EFAULT; } @@ -1360,7 +1309,7 @@ static int mptctl_gettargetinfo (unsigned long arg) { - struct mpt_ioctl_targetinfo *uarg = (struct mpt_ioctl_targetinfo *) arg; + struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_targetinfo karg; MPT_ADAPTER *ioc; struct Scsi_Host *sh; @@ -1382,7 +1331,7 @@ if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " "Unable to read in mpt_ioctl_targetinfo struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1500,21 +1449,21 @@ /* Copy part of the data from kernel memory to user memory */ - if (copy_to_user((char *)arg, &karg, + if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_targetinfo))) { printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); kfree(pmem); return -EFAULT; } /* Copy the remaining data from kernel memory to user memory */ - if (copy_to_user((char *) uarg->targetInfo, pmem, numBytes)) { + if (copy_to_user(uarg->targetInfo, pmem, numBytes)) { printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n", - __FILE__, __LINE__, (void*)pdata); + __FILE__, __LINE__, pdata); kfree(pmem); return -EFAULT; } @@ -1535,7 +1484,7 @@ static int mptctl_readtest (unsigned long arg) { - struct mpt_ioctl_test *uarg = (struct mpt_ioctl_test *) arg; + struct mpt_ioctl_test __user *uarg = (void __user *) arg; struct mpt_ioctl_test karg; MPT_ADAPTER *ioc; int iocnum; @@ -1544,7 +1493,7 @@ if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) { printk(KERN_ERR "%s@%d::mptctl_readtest - " "Unable to read in mpt_ioctl_test struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1571,10 +1520,10 @@ /* Copy the data from kernel memory to user memory */ - if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_test))) { + if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) { printk(KERN_ERR "%s@%d::mptctl_readtest - " "Unable to write out mpt_ioctl_test struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1595,7 +1544,7 @@ static int mptctl_eventquery (unsigned long arg) { - struct mpt_ioctl_eventquery *uarg = (struct mpt_ioctl_eventquery *) arg; + struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg; struct mpt_ioctl_eventquery karg; MPT_ADAPTER *ioc; int iocnum; @@ -1604,7 +1553,7 @@ if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) { printk(KERN_ERR "%s@%d::mptctl_eventquery - " "Unable to read in mpt_ioctl_eventquery struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1620,10 +1569,10 @@ /* Copy the data from kernel memory to user memory */ - if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) { + if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) { printk(KERN_ERR "%s@%d::mptctl_eventquery - " "Unable to write out mpt_ioctl_eventquery struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } return 0; @@ -1633,7 +1582,7 @@ static int mptctl_eventenable (unsigned long arg) { - struct mpt_ioctl_eventenable *uarg = (struct mpt_ioctl_eventenable *) arg; + struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg; struct mpt_ioctl_eventenable karg; MPT_ADAPTER *ioc; int iocnum; @@ -1642,7 +1591,7 @@ if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) { printk(KERN_ERR "%s@%d::mptctl_eventenable - " "Unable to read in mpt_ioctl_eventenable struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1680,7 +1629,7 @@ static int mptctl_eventreport (unsigned long arg) { - struct mpt_ioctl_eventreport *uarg = (struct mpt_ioctl_eventreport *) arg; + struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg; struct mpt_ioctl_eventreport karg; MPT_ADAPTER *ioc; int iocnum; @@ -1690,7 +1639,7 @@ if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) { printk(KERN_ERR "%s@%d::mptctl_eventreport - " "Unable to read in mpt_ioctl_eventreport struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1716,10 +1665,10 @@ /* Copy the data from kernel memory to user memory */ numBytes = max * sizeof(MPT_IOCTL_EVENTS); - if (copy_to_user((char *) uarg->eventData, ioc->events, numBytes)) { + if (copy_to_user(uarg->eventData, ioc->events, numBytes)) { printk(KERN_ERR "%s@%d::mptctl_eventreport - " "Unable to write out mpt_ioctl_eventreport struct @ %p\n", - __FILE__, __LINE__, (void*)ioc->events); + __FILE__, __LINE__, ioc->events); return -EFAULT; } @@ -1730,7 +1679,7 @@ static int mptctl_replace_fw (unsigned long arg) { - struct mpt_ioctl_replace_fw *uarg = (struct mpt_ioctl_replace_fw *) arg; + struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg; struct mpt_ioctl_replace_fw karg; MPT_ADAPTER *ioc; fw_image_t **fwmem = NULL; @@ -1744,7 +1693,7 @@ if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) { printk(KERN_ERR "%s@%d::mptctl_replace_fw - " "Unable to read in mpt_ioctl_replace_fw struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1774,7 +1723,7 @@ if (copy_from_user(fwmem[ii]->fw, uarg->newImage + offset, fwmem[ii]->size)) { printk(KERN_ERR "%s@%d::mptctl_replace_fw - " "Unable to read in mpt_ioctl_replace_fw image @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); mpt_free_fw_memory(ioc, fwmem); return -EFAULT; @@ -1819,7 +1768,7 @@ static int mptctl_mpt_command (unsigned long arg) { - struct mpt_ioctl_command *uarg = (struct mpt_ioctl_command *) arg; + struct mpt_ioctl_command __user *uarg = (void __user *) arg; struct mpt_ioctl_command karg; MPT_ADAPTER *ioc; int iocnum; @@ -1830,7 +1779,7 @@ if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) { printk(KERN_ERR "%s@%d::mptctl_mpt_command - " "Unable to read in mpt_ioctl_command struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1841,7 +1790,7 @@ return -ENODEV; } - rc = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0); + rc = mptctl_do_mpt_command (karg, &uarg->MF); return rc; } @@ -1859,7 +1808,7 @@ * -EPERM if SCSI I/O and target is untagged */ static int -mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local) +mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) { MPT_ADAPTER *ioc; MPT_FRAME_HDR *mf = NULL; @@ -1923,23 +1872,15 @@ /* Copy the request frame * Reset the saved message context. + * Request frame in user space */ - if (local) { - /* Request frame in kernel space - */ - memcpy((char *)mf, (char *) mfPtr, karg.dataSgeOffset * 4); - } else { - /* Request frame in user space - */ - if (copy_from_user((char *)mf, (char *) mfPtr, - karg.dataSgeOffset * 4)){ - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " - "Unable to read MF from mpt_ioctl_command struct @ %p\n", - __FILE__, __LINE__, (void*)mfPtr); - rc = -EFAULT; - goto done_free_mem; - } - } + if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) { + printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + "Unable to read MF from mpt_ioctl_command struct @ %p\n", + __FILE__, __LINE__, mfPtr); + rc = -EFAULT; + goto done_free_mem; + } hdr->MsgContext = cpu_to_le32(msgContext); @@ -2220,7 +2161,7 @@ "%s@%d::mptctl_do_mpt_command - Unable " "to read user data " "struct @ %p\n", - __FILE__, __LINE__,(void*)karg.dataOutBufPtr); + __FILE__, __LINE__,karg.dataOutBufPtr); rc = -EFAULT; goto done_free_mem; } @@ -2321,12 +2262,12 @@ } if (sz > 0) { - if (copy_to_user((char *)karg.replyFrameBufPtr, + if (copy_to_user(karg.replyFrameBufPtr, &ioc->ioctl->ReplyFrame, sz)){ printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " "Unable to write out reply frame %p\n", - __FILE__, __LINE__, (void*)karg.replyFrameBufPtr); + __FILE__, __LINE__, karg.replyFrameBufPtr); rc = -ENODATA; goto done_free_mem; } @@ -2338,11 +2279,11 @@ if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) { sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE); if (sz > 0) { - if (copy_to_user((char *)karg.senseDataPtr, ioc->ioctl->sense, sz)) { + if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " "Unable to write sense data to user %p\n", __FILE__, __LINE__, - (void*)karg.senseDataPtr); + karg.senseDataPtr); rc = -ENODATA; goto done_free_mem; } @@ -2355,12 +2296,12 @@ if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) && (karg.dataInSize > 0) && (bufIn.kptr)) { - if (copy_to_user((char *)karg.dataInBufPtr, + if (copy_to_user(karg.dataInBufPtr, bufIn.kptr, karg.dataInSize)) { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " "Unable to write data to user %p\n", __FILE__, __LINE__, - (void*)karg.dataInBufPtr); + karg.dataInBufPtr); rc = -ENODATA; } } @@ -2413,7 +2354,7 @@ static int mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) { - hp_host_info_t *uarg = (hp_host_info_t *) arg; + hp_host_info_t __user *uarg = (void __user *) arg; MPT_ADAPTER *ioc; struct pci_dev *pdev; char *pbuf; @@ -2437,7 +2378,7 @@ if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) { printk(KERN_ERR "%s@%d::mptctl_hp_host_info - " "Unable to read in hp_host_info struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -2455,10 +2396,8 @@ karg.vendor = pdev->vendor; karg.device = pdev->device; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) karg.subsystem_id = pdev->subsystem_device; karg.subsystem_vendor = pdev->subsystem_vendor; -#endif karg.devfn = pdev->devfn; karg.bus = pdev->bus->number; @@ -2540,7 +2479,7 @@ break; } - karg.base_io_addr = pdev->PCI_BASEADDR_START(0); + karg.base_io_addr = pci_resource_start(pdev, 0); if ((int)ioc->chip_type <= (int) FC929) karg.bus_phys_width = HP_BUS_WIDTH_UNK; @@ -2576,11 +2515,10 @@ /* Copy the data from kernel memory to user memory */ - if (copy_to_user((char *)arg, &karg, - sizeof(hp_host_info_t))) { + if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - " "Unable to write out hp_host_info @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -2602,7 +2540,7 @@ static int mptctl_hp_targetinfo(unsigned long arg) { - hp_target_info_t *uarg = (hp_target_info_t *) arg; + hp_target_info_t __user *uarg = (void __user *) arg; SCSIDevicePage0_t *pg0_alloc; SCSIDevicePage3_t *pg3_alloc; MPT_ADAPTER *ioc; @@ -2619,7 +2557,7 @@ if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) { printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - " "Unable to read in hp_host_targetinfo struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -2727,10 +2665,10 @@ /* Copy the data from kernel memory to user memory */ - if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) { + if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) { printk(KERN_ERR "%s@%d::mptctl_hp_target_info - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n", - __FILE__, __LINE__, (void*)uarg); + __FILE__, __LINE__, uarg); return -EFAULT; } @@ -2739,20 +2677,10 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51) -#define owner_THIS_MODULE .owner = THIS_MODULE, -#else -#define owner_THIS_MODULE -#endif - static struct file_operations mptctl_fops = { - owner_THIS_MODULE + .owner = THIS_MODULE, .llseek = no_llseek, - .read = mptctl_read, - .write = mptctl_write, .ioctl = mptctl_ioctl, - .open = mptctl_open, - .release = mptctl_release, }; static struct miscdevice mptctl_miscdev = { @@ -2800,7 +2728,7 @@ dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n")); - if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32))) + if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32))) return -EFAULT; /* Verify intended MPT adapter */ @@ -2817,7 +2745,7 @@ kfw.iocnum = iocnum; kfw.fwlen = kfw32.fwlen; - kfw.bufp = (void *)(unsigned long)kfw32.bufp; + kfw.bufp = compat_ptr(kfw32.bufp); ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen); @@ -2831,7 +2759,7 @@ unsigned long arg, struct file *filp) { struct mpt_ioctl_command32 karg32; - struct mpt_ioctl_command32 *uarg = (struct mpt_ioctl_command32 *) arg; + struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg; struct mpt_ioctl_command karg; MPT_ADAPTER *iocp = NULL; int iocnum, iocnumX; @@ -2840,7 +2768,7 @@ dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n")); - if (copy_from_user(&karg32, (char *)arg, sizeof(karg32))) + if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) return -EFAULT; /* Verify intended MPT adapter */ @@ -2866,14 +2794,14 @@ karg.maxSenseBytes = karg32.maxSenseBytes; karg.dataSgeOffset = karg32.dataSgeOffset; - karg.replyFrameBufPtr = (char *)(unsigned long)karg32.replyFrameBufPtr; - karg.dataInBufPtr = (char *)(unsigned long)karg32.dataInBufPtr; - karg.dataOutBufPtr = (char *)(unsigned long)karg32.dataOutBufPtr; - karg.senseDataPtr = (char *)(unsigned long)karg32.senseDataPtr; + karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr; + karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr; + karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr; + karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr; /* Pass new structure to do_mpt_command */ - ret = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0); + ret = mptctl_do_mpt_command (karg, &uarg->MF); up(&mptctl_syscall_sem_ioc[iocp->id]); diff -Nru a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h --- a/drivers/message/fusion/mptctl.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/message/fusion/mptctl.h 2004-06-26 17:09:18 -07:00 @@ -115,7 +115,7 @@ struct mpt_fw_xfer { unsigned int iocnum; /* IOC unit number */ unsigned int fwlen; - void *bufp; /* Pointer to firmware buffer */ + void __user *bufp; /* Pointer to firmware buffer */ }; #if defined(__KERNEL__) && defined(CONFIG_COMPAT) @@ -332,10 +332,10 @@ struct mpt_ioctl_command { mpt_ioctl_header hdr; int timeout; /* optional (seconds) */ - char *replyFrameBufPtr; - char *dataInBufPtr; - char *dataOutBufPtr; - char *senseDataPtr; + char __user *replyFrameBufPtr; + char __user *dataInBufPtr; + char __user *dataOutBufPtr; + char __user *senseDataPtr; int maxReplyBytes; int dataInSize; int dataOutSize; diff -Nru a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c --- a/drivers/message/fusion/mptlan.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/message/fusion/mptlan.c 2004-06-26 17:09:18 -07:00 @@ -133,7 +133,7 @@ u32 total_received; struct net_device_stats stats; /* Per device statistics */ - struct mpt_work_struct post_buckets_task; + struct work_struct post_buckets_task; unsigned long post_buckets_active; }; @@ -880,18 +880,9 @@ if (test_and_set_bit(0, &priv->post_buckets_active) == 0) { if (priority) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41) schedule_work(&priv->post_buckets_task); -#else - queue_task(&priv->post_buckets_task, &tq_immediate); - mark_bh(IMMEDIATE_BH); -#endif } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41) schedule_delayed_work(&priv->post_buckets_task, 1); -#else - queue_task(&priv->post_buckets_task, &tq_timer); -#endif dioprintk((KERN_INFO MYNAM ": post_buckets queued on " "timer.\n")); } @@ -1391,8 +1382,8 @@ priv->mpt_dev = mpt_dev; priv->pnum = pnum; - memset(&priv->post_buckets_task, 0, sizeof(struct mpt_work_struct)); - MPT_INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev); + memset(&priv->post_buckets_task, 0, sizeof(struct work_struct)); + INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev); priv->post_buckets_active = 0; dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n", @@ -1566,10 +1557,6 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59) -MODULE_PARM(tx_max_out_p, "i"); -MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME! -#endif module_init(mpt_lan_init); module_exit(mpt_lan_exit); diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/message/fusion/mptscsih.c 2004-06-26 17:09:21 -07:00 @@ -74,6 +74,8 @@ #include /* for mdelay */ #include /* needed for in_interrupt() proto */ #include /* notifier code */ +#include +#include #include "../../scsi/scsi.h" #include @@ -185,7 +187,7 @@ static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); -static struct mpt_work_struct mptscsih_rstTask; +static struct work_struct mptscsih_rstTask; #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); @@ -231,7 +233,7 @@ static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED; static int dvtaskQ_active = 0; static int dvtaskQ_release = 0; -static struct mpt_work_struct mptscsih_dvTask; +static struct work_struct mptscsih_dvTask; #endif /* @@ -249,31 +251,7 @@ static Scsi_Cmnd *foo_to[8]; #endif -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -/* see mptscsih.h */ - -static struct scsi_host_template driver_template = { - .proc_name = "mptscsih", - .proc_info = x_scsi_proc_info, - .name = "MPT SCSI Host", - .info = x_scsi_info, - .queuecommand = x_scsi_queuecommand, - .slave_alloc = x_scsi_slave_alloc, - .slave_configure = x_scsi_slave_configure, - .slave_destroy = x_scsi_slave_destroy, - .eh_abort_handler = x_scsi_abort, - .eh_device_reset_handler = x_scsi_dev_reset, - .eh_bus_reset_handler = x_scsi_bus_reset, - .eh_host_reset_handler = x_scsi_host_reset, - .bios_param = x_scsi_bios_param, - .can_queue = MPT_SCSI_CAN_QUEUE, - .this_id = -1, - .sg_tablesize = MPT_SCSI_SG_DEPTH, - .max_sectors = MPT_SCSI_MAX_SECTORS, - .cmd_per_lun = MPT_SCSI_CMD_PER_LUN, - .use_clustering = ENABLE_CLUSTERING, -}; +static struct scsi_host_template driver_template; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -1459,7 +1437,6 @@ } sh->max_lun = MPT_LAST_LUN + 1; - sh->max_sectors = MPT_SCSI_MAX_SECTORS; sh->max_channel = 0; sh->this_id = ioc->pfacts[0].PortSCSIID; @@ -1800,8 +1777,8 @@ } dprintk((MYIOC_s_INFO_FMT - "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n", - hd->ioc->name, sz1, szchain, sz3, sztarget)); + "Free'd ScsiLookup (%d) Target (%d+%d) memory\n", + hd->ioc->name, sz1, sz3, sztarget)); dprintk(("Free'd done and free Q (%d) memory\n", szQ)); /* NULL the Scsi_Host pointer @@ -1879,9 +1856,9 @@ if (!dvtaskQ_active) { dvtaskQ_active = 1; spin_unlock_irqrestore(&dvtaskQ_lock, lflags); - MPT_INIT_WORK(&mptscsih_dvTask, + INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd); - SCHEDULE_TASK(&mptscsih_dvTask); + schedule_work(&mptscsih_dvTask); } else { spin_unlock_irqrestore(&dvtaskQ_lock, lflags); } @@ -1902,7 +1879,6 @@ #endif }; - /* SCSI host fops start here... */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** @@ -2434,9 +2410,9 @@ if (!dvtaskQ_active) { dvtaskQ_active = 1; spin_unlock_irqrestore(&dvtaskQ_lock, lflags); - MPT_INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd); + INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd); - SCHEDULE_TASK(&mptscsih_dvTask); + schedule_work(&mptscsih_dvTask); } else { spin_unlock_irqrestore(&dvtaskQ_lock, lflags); } @@ -3905,6 +3881,29 @@ return 1; /* currently means nothing really */ } +static struct scsi_host_template driver_template = { + .proc_name = "mptscsih", + .proc_info = mptscsih_proc_info, + .name = "MPT SCSI Host", + .info = mptscsih_info, + .queuecommand = mptscsih_qcmd, + .slave_alloc = mptscsih_slave_alloc, + .slave_configure = mptscsih_slave_configure, + .slave_destroy = mptscsih_slave_destroy, + .eh_abort_handler = mptscsih_abort, + .eh_device_reset_handler = mptscsih_dev_reset, + .eh_bus_reset_handler = mptscsih_bus_reset, + .eh_host_reset_handler = mptscsih_host_reset, + .bios_param = mptscsih_bios_param, + .can_queue = MPT_SCSI_CAN_QUEUE, + .this_id = -1, + .sg_tablesize = MPT_SCSI_SG_DEPTH, + .max_sectors = 8192, + .cmd_per_lun = 7, + .use_clustering = ENABLE_CLUSTERING, +}; + + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Private data... @@ -4950,8 +4949,8 @@ /* Call the reset handler. Already had a TM request * timeout - so issue a diagnostic reset */ - MPT_INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd); - SCHEDULE_TASK(&mptscsih_rstTask); + INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd); + schedule_work(&mptscsih_rstTask); return; } diff -Nru a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h --- a/drivers/message/fusion/mptscsih.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/message/fusion/mptscsih.h 2004-06-26 17:09:21 -07:00 @@ -108,75 +108,4 @@ MPTSCSIH_SAF_TE, \ } - - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * Various bits and pieces broke within the lk-2.4.0-testN series:-( - * So here are various HACKS to work around them. - */ - -/* - * tq_scheduler disappeared @ lk-2.4.0-test12 - * (right when newly defined TQ_ACTIVE) - * tq_struct reworked in 2.5.41. Include workqueue.h. - */ -# include -# include -#define SCHEDULE_TASK(x) \ - if (schedule_work(x) == 0) { \ - /*MOD_DEC_USE_COUNT*/; \ - } - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -#define x_scsi_info mptscsih_info -#define x_scsi_queuecommand mptscsih_qcmd -#define x_scsi_abort mptscsih_abort -#define x_scsi_bus_reset mptscsih_bus_reset -#define x_scsi_dev_reset mptscsih_dev_reset -#define x_scsi_host_reset mptscsih_host_reset -#define x_scsi_bios_param mptscsih_bios_param - -#define x_scsi_slave_alloc mptscsih_slave_alloc -#define x_scsi_slave_configure mptscsih_slave_configure -#define x_scsi_slave_destroy mptscsih_slave_destroy -#define x_scsi_proc_info mptscsih_proc_info - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * MPT SCSI Host / Initiator decls... - */ -extern const char *x_scsi_info(struct Scsi_Host *); -extern int x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -extern int x_scsi_abort(Scsi_Cmnd *); -extern int x_scsi_bus_reset(Scsi_Cmnd *); -extern int x_scsi_dev_reset(Scsi_Cmnd *); -extern int x_scsi_host_reset(Scsi_Cmnd *); -extern int x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev, - sector_t capacity, int geom[]); -extern int x_scsi_slave_alloc(Scsi_Device *); -extern int x_scsi_slave_configure(Scsi_Device *); -extern void x_scsi_slave_destroy(Scsi_Device *); -extern int x_scsi_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -/* include/scsi/scsi.h may not be quite complete... */ -#ifndef RESERVE_10 -#define RESERVE_10 0x56 #endif -#ifndef RELEASE_10 -#define RELEASE_10 0x57 -#endif -#ifndef PERSISTENT_RESERVE_IN -#define PERSISTENT_RESERVE_IN 0x5e -#endif -#ifndef PERSISTENT_RESERVE_OUT -#define PERSISTENT_RESERVE_OUT 0x5f -#endif - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -#endif - diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c --- a/drivers/message/i2o/i2o_block.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/message/i2o/i2o_block.c 2004-06-26 17:09:19 -07:00 @@ -280,8 +280,8 @@ { struct i2o_controller *c = dev->controller; int tid = dev->tid; - unsigned long msg; - unsigned long mptr; + void *msg; + void *mptr; u64 offset; struct request *req = ireq->req; int count = req->nr_sectors<<9; @@ -291,7 +291,7 @@ // printk(KERN_INFO "i2ob_send called\n"); /* Map the message to a virtual address */ - msg = c->mem_offset + m; + msg = c->msg_virt + m; sgnum = i2ob_build_sglist(dev, ireq); @@ -479,7 +479,7 @@ /* Now flush the message by making it a NOP */ m[0]&=0x00FFFFFF; m[0]|=(I2O_CMD_UTIL_NOP)<<24; - i2o_post_message(c, ((unsigned long)m) - c->mem_offset); + i2o_post_message(c, (unsigned long) m - (unsigned long) c->msg_virt); return; } @@ -861,6 +861,7 @@ { struct gendisk *disk = inode->i_bdev->bd_disk; struct i2ob_device *dev = disk->private_data; + void __user *argp = (void __user *)arg; /* Anyone capable of this syscall can do *real bad* things */ @@ -873,13 +874,13 @@ i2o_block_biosparam(get_capacity(disk), &g.cylinders, &g.heads, &g.sectors); g.start = get_start_sect(inode->i_bdev); - return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0; + return copy_to_user(argp, &g, sizeof(g))?-EFAULT:0; } case BLKI2OGRSTRAT: - return put_user(dev->rcache, (int *)arg); + return put_user(dev->rcache, (int __user *)argp); case BLKI2OGWSTRAT: - return put_user(dev->wcache, (int *)arg); + return put_user(dev->wcache, (int __user *)argp); case BLKI2OSRSTRAT: if(arg<0||arg>CACHE_SMARTFETCH) return -EINVAL; diff -Nru a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c --- a/drivers/message/i2o/i2o_config.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/message/i2o/i2o_config.c 2004-06-26 17:09:20 -07:00 @@ -97,7 +97,7 @@ u32 *msg = (u32 *)m; if (msg[0] & MSG_FAIL) { - u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]); + u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]); printk(KERN_ERR "i2o_config: IOP failed to process the msg.\n"); @@ -194,7 +194,7 @@ 0xffffffff // All classes }; -static ssize_t cfg_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t cfg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { printk(KERN_INFO "i2o_config write not yet supported\n"); @@ -202,7 +202,7 @@ } -static ssize_t cfg_read(struct file *file, char *buf, size_t count, loff_t *ptr) +static ssize_t cfg_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { return 0; } @@ -278,7 +278,7 @@ int ioctl_getiops(unsigned long arg) { - u8 *user_iop_table = (u8*)arg; + u8 __user *user_iop_table = (void __user *)arg; struct i2o_controller *c = NULL; int i; u8 foo[MAX_I2O_CONTROLLERS]; @@ -314,7 +314,7 @@ int ioctl_gethrt(unsigned long arg) { struct i2o_controller *c; - struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg; + struct i2o_cmd_hrtlct __user *cmd = (void __user *)arg; struct i2o_cmd_hrtlct kcmd; i2o_hrt *hrt; int len; @@ -353,7 +353,7 @@ int ioctl_getlct(unsigned long arg) { struct i2o_controller *c; - struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg; + struct i2o_cmd_hrtlct __user *cmd = (void __user *)arg; struct i2o_cmd_hrtlct kcmd; i2o_lct *lct; int len; @@ -390,7 +390,7 @@ { int ret = 0; struct i2o_controller *c; - struct i2o_cmd_psetget *cmd = (struct i2o_cmd_psetget*)arg; + struct i2o_cmd_psetget __user *cmd = (void __user *)arg; struct i2o_cmd_psetget kcmd; u32 reslen; u8 *ops; @@ -460,7 +460,7 @@ int ioctl_html(unsigned long arg) { - struct i2o_html *cmd = (struct i2o_html*)arg; + struct i2o_html __user *cmd = (void __user *)arg; struct i2o_html kcmd; struct i2o_controller *c; u8 *res = NULL; @@ -573,7 +573,7 @@ int ioctl_swdl(unsigned long arg) { struct i2o_sw_xfer kxfer; - struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg; + struct i2o_sw_xfer __user *pxfer = (void __user *)arg; unsigned char maxfrag = 0, curfrag = 1; unsigned char *buffer; u32 msg[9]; @@ -642,7 +642,7 @@ int ioctl_swul(unsigned long arg) { struct i2o_sw_xfer kxfer; - struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg; + struct i2o_sw_xfer __user *pxfer = (void __user *)arg; unsigned char maxfrag = 0, curfrag = 1; unsigned char *buffer; u32 msg[9]; @@ -709,7 +709,8 @@ int ioctl_swdel(unsigned long arg) { struct i2o_controller *c; - struct i2o_sw_xfer kxfer, *pxfer = (struct i2o_sw_xfer *)arg; + struct i2o_sw_xfer kxfer; + struct i2o_sw_xfer __user *pxfer = (void __user *)arg; u32 msg[7]; unsigned int swlen; int token; @@ -776,7 +777,7 @@ static int ioctl_evt_reg(unsigned long arg, struct file *fp) { u32 msg[5]; - struct i2o_evt_id *pdesc = (struct i2o_evt_id *)arg; + struct i2o_evt_id __user *pdesc = (void __user *)arg; struct i2o_evt_id kdesc; struct i2o_controller *iop; struct i2o_device *d; @@ -813,7 +814,7 @@ { u32 id = (u32)fp->private_data; struct i2o_cfg_info *p = NULL; - struct i2o_evt_get *uget = (struct i2o_evt_get*)arg; + struct i2o_evt_get __user *uget = (void __user *)arg; struct i2o_evt_get kget; unsigned long flags; @@ -842,24 +843,28 @@ static int ioctl_passthru(unsigned long arg) { - struct i2o_cmd_passthru *cmd = (struct i2o_cmd_passthru *) arg; + struct i2o_cmd_passthru __user *cmd = (void __user *) arg; struct i2o_controller *c; u32 msg[MSG_FRAME_SIZE]; - u32 *user_msg = (u32*)cmd->msg; + u32 __user *user_msg; u32 *reply = NULL; - u32 *user_reply = NULL; + u32 __user *user_reply = NULL; u32 size = 0; u32 reply_size = 0; u32 rcode = 0; - ulong sg_list[SG_TABLESIZE]; + void *sg_list[SG_TABLESIZE]; u32 sg_offset = 0; u32 sg_count = 0; int sg_index = 0; u32 i = 0; - ulong p = 0; + void *p = 0; + unsigned int iop; - c = i2o_find_controller(cmd->iop); - if(!c) + if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg)) + return -EFAULT; + + c = i2o_find_controller(iop); + if (!c) return -ENXIO; memset(&msg, 0, MSG_FRAME_SIZE*4); @@ -873,7 +878,7 @@ size *= 4; // Convert to bytes /* Copy in the user's I2O command */ - if(copy_from_user((void*)msg, (void*)user_msg, size)) + if(copy_from_user(msg, user_msg, size)) return -EFAULT; if(get_user(reply_size, &user_reply[0]) < 0) return -EFAULT; @@ -916,7 +921,7 @@ } sg_size = sg[i].flag_count & 0xffffff; /* Allocate memory for the transfer */ - p = (ulong)kmalloc(sg_size, GFP_KERNEL); + p = kmalloc(sg_size, GFP_KERNEL); if (!p) { printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", c->name,sg_size,i,sg_count); rcode = -ENOMEM; @@ -926,14 +931,14 @@ /* Copy in the user's SG buffer if necessary */ if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { // TODO 64bit fix - if (copy_from_user((void*)p,(void*)sg[i].addr_bus, sg_size)) { + if (copy_from_user(p,(void __user *)sg[i].addr_bus, sg_size)) { printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",c->name,i); rcode = -EFAULT; goto cleanup; } } //TODO 64bit fix - sg[i].addr_bus = (u32)virt_to_bus((void*)p); + sg[i].addr_bus = (u32)virt_to_bus(p); } } @@ -958,7 +963,7 @@ size = size>>16; size *= 4; /* Copy in the user's I2O command */ - if (copy_from_user ((void*)msg, (void*)user_msg, size)) { + if (copy_from_user (msg, user_msg, size)) { rcode = -EFAULT; goto cleanup; } @@ -971,8 +976,8 @@ if (!(sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { sg_size = sg[j].flag_count & 0xffffff; // TODO 64bit fix - if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) { - printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",c->name, sg_list[j], sg[j].addr_bus); + if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) { + printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",c->name, sg_list[j], sg[j].addr_bus); rcode = -EFAULT; goto cleanup; } diff -Nru a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c --- a/drivers/message/i2o/i2o_core.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/message/i2o/i2o_core.c 2004-06-26 17:09:19 -07:00 @@ -354,7 +354,7 @@ if (msg[0] & MSG_FAIL) // Fail bit is set { - u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]); + u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]); i2o_report_status(KERN_INFO, "i2o_core", msg); i2o_dump_message(preserved_msg); @@ -1794,7 +1794,7 @@ m=i2o_wait_message(c, "AdapterReset"); if(m==0xFFFFFFFF) return -ETIMEDOUT; - msg=(u32 *)(c->mem_offset+m); + msg=(u32 *)(c->msg_virt+m); status = pci_alloc_consistent(c->pdev, 4, &status_phys); if(status == NULL) { @@ -1923,7 +1923,7 @@ m=i2o_wait_message(c, "StatusGet"); if(m==0xFFFFFFFF) return -ETIMEDOUT; - msg=(u32 *)(c->mem_offset+m); + msg=(u32 *)(c->msg_virt+m); msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0; msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID; @@ -2344,7 +2344,7 @@ m=i2o_wait_message(c, "OutboundInit"); if(m==0xFFFFFFFF) return -ETIMEDOUT; - msg=(u32 *)(c->mem_offset+m); + msg=(u32 *)(c->msg_virt+m); status = pci_alloc_consistent(c->pdev, 4, &status_phys); if (status==NULL) { @@ -2618,7 +2618,7 @@ sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ?? sys_tbl->iops[count].iop_capabilities = iop->status_block->iop_capabilities; - sys_tbl->iops[count].inbound_low = iop->post_port; + sys_tbl->iops[count].inbound_low = (u32)iop->post_port; sys_tbl->iops[count].inbound_high = 0; // FIXME: 64-bit support count++; @@ -2666,7 +2666,7 @@ c->name); return -ETIMEDOUT; } - msg = (u32 *)(c->mem_offset + m); + msg = (u32 *)(c->msg_virt + m); memcpy_toio(msg, data, len); i2o_post_message(c,m); return 0; @@ -3592,7 +3592,9 @@ I2O_IRQ_WRITE32(c,0xFFFFFFFF); if(c->irq > 0) free_irq(c->irq, c); - iounmap(((u8 *)c->post_port)-0x40); + iounmap(c->base_virt); + if(c->raptor) + iounmap(c->msg_virt); #ifdef CONFIG_MTRR if(c->mtrr_reg0 > 0) @@ -3633,9 +3635,12 @@ { struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller), GFP_KERNEL); - unsigned long mem; - u32 memptr = 0; - u32 size; + void *bar0_virt; + void *bar1_virt; + unsigned long bar0_phys = 0; + unsigned long bar1_phys = 0; + unsigned long bar0_size = 0; + unsigned long bar1_size = 0; int i; @@ -3646,37 +3651,9 @@ } memset(c, 0, sizeof(*c)); - for(i=0; i<6; i++) - { - /* Skip I/O spaces */ - if(!(pci_resource_flags(dev, i) & IORESOURCE_IO)) - { - memptr = pci_resource_start(dev, i); - break; - } - } - - if(i==6) - { - printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n"); - kfree(c); - return -EINVAL; - } - - size = dev->resource[i].end-dev->resource[i].start+1; - /* Map the I2O controller */ - - printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size); - mem = (unsigned long)ioremap(memptr, size); - if(mem==0) - { - printk(KERN_ERR "i2o: Unable to map controller.\n"); - kfree(c); - return -EINVAL; - } - c->irq = -1; c->dpt = 0; + c->raptor = 0; c->short_req = 0; c->pdev = dev; @@ -3684,13 +3661,6 @@ c->context_list_lock = SPIN_LOCK_UNLOCKED; #endif - c->irq_mask = mem+0x34; - c->post_port = mem+0x40; - c->reply_port = mem+0x44; - - c->mem_phys = memptr; - c->mem_offset = mem; - /* * Cards that fall apart if you hit them with large I/O * loads... @@ -3701,6 +3671,7 @@ c->short_req = 1; printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n"); } + if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) { c->promise = 1; @@ -3712,15 +3683,85 @@ * them */ - if(dev->vendor == PCI_VENDOR_ID_DPT) + if(dev->vendor == PCI_VENDOR_ID_DPT) { c->dpt=1; + if(dev->device == 0xA511) + c->raptor=1; + } + + for(i=0; i<6; i++) + { + /* Skip I/O spaces */ + if(!(pci_resource_flags(dev, i) & IORESOURCE_IO)) + { + if(!bar0_phys) + { + bar0_phys = pci_resource_start(dev, i); + bar0_size = pci_resource_len(dev, i); + if(!c->raptor) + break; + } + else + { + bar1_phys = pci_resource_start(dev, i); + bar1_size = pci_resource_len(dev, i); + break; + } + } + } + + if(i==6) + { + printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n"); + kfree(c); + return -EINVAL; + } + + + /* Map the I2O controller */ + if(!c->raptor) + printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n", bar0_phys, bar0_size); + else + printk(KERN_INFO "i2o: PCI I2O controller\n BAR0 at 0x%08lX size=%ld\n BAR1 at 0x%08lX size=%ld\n", bar0_phys, bar0_size, bar1_phys, bar1_size); + + bar0_virt = ioremap(bar0_phys, bar0_size); + if(bar0_virt==0) + { + printk(KERN_ERR "i2o: Unable to map controller.\n"); + kfree(c); + return -EINVAL; + } + + if(c->raptor) + { + bar1_virt = ioremap(bar1_phys, bar1_size); + if(bar1_virt==0) + { + printk(KERN_ERR "i2o: Unable to map controller.\n"); + kfree(c); + iounmap(bar0_virt); + return -EINVAL; + } + } else { + bar1_virt = bar0_virt; + bar1_phys = bar0_phys; + bar1_size = bar0_size; + } + + c->irq_mask = bar0_virt+0x34; + c->post_port = bar0_virt+0x40; + c->reply_port = bar0_virt+0x44; + + c->base_phys = bar0_phys; + c->base_virt = bar0_virt; + c->msg_phys = bar1_phys; + c->msg_virt = bar1_virt; /* * Enable Write Combining MTRR for IOP's memory region */ #ifdef CONFIG_MTRR - c->mtrr_reg0 = - mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1); + c->mtrr_reg0 = mtrr_add(c->base_phys, bar0_size, MTRR_TYPE_WRCOMB, 1); /* * If it is an INTEL i960 I/O processor then set the first 64K to * Uncacheable since the region contains the Messaging unit which @@ -3730,14 +3771,16 @@ if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT) { printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); - c->mtrr_reg1 = mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1); + c->mtrr_reg1 = mtrr_add(c->base_phys, 65536, MTRR_TYPE_UNCACHABLE, 1); if(c->mtrr_reg1< 0) { printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n"); - mtrr_del(c->mtrr_reg0, c->mem_phys, size); + mtrr_del(c->mtrr_reg0, c->msg_phys, bar1_size); c->mtrr_reg0 = -1; } } + if(c->raptor) + c->mtrr_reg1 = mtrr_add(c->msg_phys, bar1_size, MTRR_TYPE_WRCOMB, 1); #endif @@ -3749,7 +3792,9 @@ { printk(KERN_ERR "i2o: Unable to install controller.\n"); kfree(c); - iounmap((void *)mem); + iounmap(bar0_virt); + if(c->raptor) + iounmap(bar1_virt); return i; } @@ -3764,7 +3809,9 @@ c->name, dev->irq); c->irq = -1; i2o_delete_controller(c); - iounmap((void *)mem); + iounmap(bar0_virt); + if(c->raptor) + iounmap(bar1_virt); return -EBUSY; } } @@ -3797,10 +3844,12 @@ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O) + if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O && + (dev->vendor!=PCI_VENDOR_ID_DPT || dev->device!=0xA511)) continue; - if((dev->class&0xFF)>1) + if((dev->class>>8)==PCI_CLASS_INTELLIGENT_I2O && + (dev->class&0xFF)>1) { printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n"); continue; diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c --- a/drivers/message/i2o/i2o_scsi.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/message/i2o/i2o_scsi.c 2004-06-26 17:09:20 -07:00 @@ -59,9 +59,11 @@ #include #include #include -#include "../../scsi/scsi.h" -#include "../../scsi/hosts.h" +#include +#include +#include +#include #define VERSION_STRING "Version 0.1.2" @@ -186,7 +188,7 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg) { - Scsi_Cmnd *current_command; + struct scsi_cmnd *current_command; spinlock_t *lock; u32 *m = (u32 *)msg; u8 as,ds,st; @@ -230,7 +232,7 @@ { spin_unlock_irqrestore(&retry_lock, flags); /* Create a scsi error for this */ - current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c); + current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c); if(!current_command) return; @@ -277,7 +279,7 @@ return; } - current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c); + current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c); /* * Is this a control request coming back - eg an abort ? @@ -330,10 +332,17 @@ */ current_command->result = DID_OK << 16 | ds; - if (current_command->use_sg) - pci_unmap_sg(c->pdev, (struct scatterlist *)current_command->buffer, current_command->use_sg, scsi_to_pci_dma_dir(current_command->sc_data_direction)); - else if (current_command->request_bufflen) - pci_unmap_single(c->pdev, (dma_addr_t)((long)current_command->SCp.ptr), current_command->request_bufflen, scsi_to_pci_dma_dir(current_command->sc_data_direction)); + if (current_command->use_sg) { + pci_unmap_sg(c->pdev, + (struct scatterlist *)current_command->buffer, + current_command->use_sg, + current_command->sc_data_direction); + } else if (current_command->request_bufflen) { + pci_unmap_single(c->pdev, + (dma_addr_t)((long)current_command->SCp.ptr), + current_command->request_bufflen, + current_command->sc_data_direction); + } lock = current_command->device->host->host_lock; spin_lock_irqsave(lock, flags); @@ -461,7 +470,7 @@ * scsi controller and then let the enumeration fake up the rest */ -static int i2o_scsi_detect(Scsi_Host_Template * tpnt) +static int i2o_scsi_detect(struct scsi_host_template * tpnt) { struct Scsi_Host *shpnt = NULL; int i; @@ -592,12 +601,13 @@ * Locks: takes the controller lock on error path only */ -static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) +static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, + void (*done) (struct scsi_cmnd *)) { int i; int tid; struct i2o_controller *c; - Scsi_Cmnd *current_command; + struct scsi_cmnd *current_command; struct Scsi_Host *host; struct i2o_scsi_host *hostdata; u32 *msg, *mptr; @@ -659,7 +669,7 @@ if(m==0xFFFFFFFF) return 1; - msg = (u32 *)(c->mem_offset + m); + msg = (u32 *)(c->msg_virt + m); /* * Put together a scsi execscb message @@ -668,19 +678,14 @@ len = SCpnt->request_bufflen; direction = 0x00000000; // SGL IN (osm<--iop) - if(SCpnt->sc_data_direction == SCSI_DATA_NONE) + if (SCpnt->sc_data_direction == DMA_NONE) { scsidir = 0x00000000; // DATA NO XFER - else if(SCpnt->sc_data_direction == SCSI_DATA_WRITE) - { - direction=0x04000000; // SGL OUT (osm-->iop) - scsidir =0x80000000; // DATA OUT (iop-->dev) - } - else if(SCpnt->sc_data_direction == SCSI_DATA_READ) - { - scsidir =0x40000000; // DATA IN (iop<--dev) - } - else - { + } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) { + direction = 0x04000000; // SGL OUT (osm-->iop) + scsidir = 0x80000000; // DATA OUT (iop-->dev) + } else if(SCpnt->sc_data_direction == DMA_FROM_DEVICE) { + scsidir = 0x40000000; // DATA IN (iop<--dev) + } else { /* Unknown - kill the command */ SCpnt->result = DID_NO_CONNECT << 16; @@ -768,7 +773,7 @@ len = 0; sg_count = pci_map_sg(c->pdev, sg, SCpnt->use_sg, - scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + SCpnt->sc_data_direction); /* FIXME: handle fail */ if(!sg_count) @@ -840,7 +845,7 @@ dma_addr = pci_map_single(c->pdev, SCpnt->request_buffer, SCpnt->request_bufflen, - scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + SCpnt->sc_data_direction); if(dma_addr == 0) BUG(); /* How to handle ?? */ SCpnt->SCp.ptr = (char *)(unsigned long) dma_addr; @@ -883,7 +888,7 @@ * Locks: no locks are held or needed */ -int i2o_scsi_abort(Scsi_Cmnd * SCpnt) +static int i2o_scsi_abort(struct scsi_cmnd * SCpnt) { struct i2o_controller *c; struct Scsi_Host *host; @@ -929,14 +934,14 @@ * Locks: called with no lock held, requires no locks. */ -static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt) +static int i2o_scsi_bus_reset(struct scsi_cmnd * SCpnt) { int tid; struct i2o_controller *c; struct Scsi_Host *host; struct i2o_scsi_host *hostdata; u32 m; - unsigned long msg; + void *msg; unsigned long timeout; @@ -974,7 +979,7 @@ while(time_before(jiffies, timeout)); - msg = c->mem_offset + m; + msg = c->msg_virt + m; i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg); i2o_raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, msg+4); i2o_raw_writel(scsi_context|0x80000000, msg+8); @@ -992,32 +997,6 @@ } /** - * i2o_scsi_host_reset - host reset callback - * @SCpnt: command causing the reset - * - * An I2O controller can be many things at once. While we can - * reset a controller the potential mess from doing so is vast, and - * it's better to simply hold on and pray - */ - -static int i2o_scsi_host_reset(Scsi_Cmnd * SCpnt) -{ - return FAILED; -} - -/** - * i2o_scsi_device_reset - device reset callback - * @SCpnt: command causing the reset - * - * I2O does not (AFAIK) support doing a device reset - */ - -static int i2o_scsi_device_reset(Scsi_Cmnd * SCpnt) -{ - return FAILED; -} - -/** * i2o_scsi_bios_param - Invent disk geometry * @sdev: scsi device * @dev: block layer device @@ -1048,7 +1027,7 @@ MODULE_LICENSE("GPL"); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "i2o_scsi", .name = "I2O SCSI Layer", .detect = i2o_scsi_detect, @@ -1057,8 +1036,6 @@ .queuecommand = i2o_scsi_queuecommand, .eh_abort_handler = i2o_scsi_abort, .eh_bus_reset_handler = i2o_scsi_bus_reset, - .eh_device_reset_handler= i2o_scsi_device_reset, - .eh_host_reset_handler = i2o_scsi_host_reset, .bios_param = i2o_scsi_bios_param, .can_queue = I2O_SCSI_CAN_QUEUE, .this_id = 15, diff -Nru a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c --- a/drivers/misc/ibmasm/ibmasmfs.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/misc/ibmasm/ibmasmfs.c 2004-06-26 17:09:19 -07:00 @@ -224,12 +224,12 @@ return dentry; } -int ibmasmfs_register() +int ibmasmfs_register(void) { return register_filesystem(&ibmasmfs_type); } -void ibmasmfs_unregister() +void ibmasmfs_unregister(void) { unregister_filesystem(&ibmasmfs_type); } @@ -287,7 +287,7 @@ return 0; } -static ssize_t command_file_read(struct file *file, char *buf, size_t count, loff_t *offset) +static ssize_t command_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { struct ibmasmfs_command_data *command_data = file->private_data; struct command *cmd; @@ -324,7 +324,7 @@ return len; } -static ssize_t command_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset) +static ssize_t command_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset) { struct ibmasmfs_command_data *command_data = file->private_data; struct command *cmd; @@ -345,7 +345,7 @@ if (!cmd) return -ENOMEM; - if (copy_from_user((void *)cmd->buffer, (void *)ubuff, count)) { + if (copy_from_user(cmd->buffer, ubuff, count)) { command_put(cmd); return -EFAULT; } @@ -395,7 +395,7 @@ return 0; } -static ssize_t event_file_read(struct file *file, char *buf, size_t count, loff_t *offset) +static ssize_t event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { struct ibmasmfs_event_data *event_data = file->private_data; struct event_reader *reader = &event_data->reader; @@ -421,7 +421,7 @@ return reader->data_size; } -static ssize_t event_file_write(struct file *file, const char *buf, size_t count, loff_t *offset) +static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { struct ibmasmfs_event_data *event_data = file->private_data; @@ -462,7 +462,7 @@ return 0; } -static ssize_t r_heartbeat_file_read(struct file *file, char *buf, size_t count, loff_t *offset) +static ssize_t r_heartbeat_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { struct ibmasmfs_heartbeat_data *rhbeat = file->private_data; unsigned long flags; @@ -490,7 +490,7 @@ return result; } -static ssize_t r_heartbeat_file_write(struct file *file, const char *buf, size_t count, loff_t *offset) +static ssize_t r_heartbeat_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { struct ibmasmfs_heartbeat_data *rhbeat = file->private_data; @@ -518,7 +518,7 @@ return 0; } -static ssize_t remote_settings_file_read(struct file *file, char *buf, size_t count, loff_t *offset) +static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { unsigned long address = (unsigned long)file->private_data; unsigned char *page; @@ -552,7 +552,7 @@ return retval; } -static ssize_t remote_settings_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset) +static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset) { unsigned long address = (unsigned long)file->private_data; char *buff; @@ -571,7 +571,7 @@ memset(buff, 0x0, count + 1); - if (copy_from_user((void *)buff, (void *)ubuff, count)) { + if (copy_from_user(buff, ubuff, count)) { kfree(buff); return -EFAULT; } @@ -618,7 +618,7 @@ return 0; } -static ssize_t remote_event_file_read(struct file *file, char *buf, size_t count, loff_t *offset) +static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { struct service_processor *sp = file->private_data; struct remote_queue *q = &sp->remote_queue; @@ -663,7 +663,7 @@ .open = event_file_open, .release = event_file_close, .read = event_file_read, - .write event_file_write, + .write = event_file_write, }; static struct file_operations r_heartbeat_fops = { diff -Nru a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c --- a/drivers/mtd/chips/cfi_cmdset_0001.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/mtd/chips/cfi_cmdset_0001.c 2004-06-26 17:09:16 -07:00 @@ -378,7 +378,7 @@ chip->state = FL_ERASING; chip->oldstate = FL_READY; printk(KERN_ERR "Chip not ready after erase " - "suspended: status = 0x%x\n", status); + "suspended: status = 0x%llx\n", status); return -EIO; } @@ -963,7 +963,7 @@ So we must check here and reset those bits if they're set. Otherwise we're just pissing in the wind */ if (status & CMD(0x30)) { - printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %x). Clearing.\n", status); + printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %llx). Clearing.\n", status); cfi_write(map, CMD(0x50), cmd_adr); cfi_write(map, CMD(0x70), cmd_adr); } diff -Nru a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c --- a/drivers/mtd/chips/cfi_cmdset_0002.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c 2004-06-26 17:09:17 -07:00 @@ -509,7 +509,7 @@ chip->state = FL_WRITING; adr += chip->start; - DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n", + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8llx)\n", __func__, adr, datum ); ENABLE_VPP(map); @@ -645,7 +645,7 @@ __func__ ); printk(KERN_WARNING - "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", + "MTD %s(): 0x%.8lx(0x%.8llx): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", __func__, adr, datum, prev_oldstatus, prev_status, oldstatus, status); @@ -971,7 +971,7 @@ __func__ ); printk(KERN_WARNING - "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", + "MTD %s(): 0x%.8lx(0x%.8llx): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", __func__, adr, ones, prev_oldstatus, prev_status, oldstatus, status); @@ -1151,7 +1151,7 @@ __func__ ); printk(KERN_WARNING - "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", + "MTD %s(): 0x%.8lx(0x%.8llx): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", __func__, adr, ones, prev_oldstatus, prev_status, oldstatus, status); 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 2004-06-26 17:09:17 -07:00 +++ b/drivers/mtd/chips/cfi_cmdset_0020.c 2004-06-26 17:09:17 -07:00 @@ -489,7 +489,7 @@ /* Urgh. Chip not yet ready to talk to us. */ if (time_after(jiffies, timeo)) { spin_unlock_bh(chip->mutex); - printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %x, status = %x\n", + printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %x, status = %llx\n", status, cfi_read(map, cmd_adr)); return -EIO; } @@ -859,7 +859,7 @@ if (time_after(jiffies, timeo)) { cfi_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %x, status = %llx.\n", status, cfi_read(map, adr)); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; @@ -1145,7 +1145,7 @@ if (time_after(jiffies, timeo)) { cfi_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %x, status = %llx.\n", status, cfi_read(map, adr)); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; @@ -1294,7 +1294,7 @@ if (time_after(jiffies, timeo)) { cfi_write(map, CMD(0x70), adr); chip->state = FL_STATUS; - printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr)); + printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %x, status = %llx.\n", status, cfi_read(map, adr)); DISABLE_VPP(map); spin_unlock_bh(chip->mutex); return -EIO; diff -Nru a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c --- a/drivers/mtd/devices/doc2000.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/mtd/devices/doc2000.c 2004-06-26 17:09:15 -07:00 @@ -53,9 +53,11 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf); static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, @@ -601,7 +603,8 @@ } static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, u_char * buf, u_char * eccbuf, int oobsel) + size_t * retlen, u_char * buf, u_char * eccbuf, + struct nand_oobinfo *unused) { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; unsigned long docptr; @@ -750,7 +753,8 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf, - u_char * eccbuf, int oobsel) + u_char * eccbuf, + struct nand_oobinfo *unused) { struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ diff -Nru a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c --- a/drivers/mtd/devices/doc2001.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/mtd/devices/doc2001.c 2004-06-26 17:09:16 -07:00 @@ -37,9 +37,12 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused); + static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf); static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, @@ -407,7 +410,8 @@ } static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel) + size_t *retlen, u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused) { int i, ret; volatile char dummy; @@ -533,7 +537,8 @@ } static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel) + size_t *retlen, const u_char *buf, u_char *eccbuf, + struct nand_oobinfo *unused) { int i,ret = 0; volatile char dummy; diff -Nru a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c --- a/drivers/mtd/maps/wr_sbc82xx_flash.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/mtd/maps/wr_sbc82xx_flash.c 2004-06-26 17:09:15 -07:00 @@ -20,7 +20,7 @@ #include #include -#include +#include static struct mtd_info *sbcmtd[3]; static struct mtd_partition *sbcmtd_parts[3]; @@ -59,7 +59,7 @@ int __init init_sbc82xx_flash(void) { - volatile memctl8260_t *mc = &immr->im_memctl; + volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl; int bigflash; int i; diff -Nru a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c --- a/drivers/mtd/mtd_blkdevs.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/mtd/mtd_blkdevs.c 2004-06-26 17:09:15 -07:00 @@ -220,7 +220,7 @@ return ret; g.start = get_start_sect(inode->i_bdev); - if (copy_to_user((void *)arg, &g, sizeof(g))) + if (copy_to_user((void __user *)arg, &g, sizeof(g))) return -EFAULT; return 0; } /* else */ diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c --- a/drivers/mtd/mtdblock.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/mtd/mtdblock.c 2004-06-26 17:09:17 -07:00 @@ -275,7 +275,7 @@ /* OK, it's not open. Create cache info for it */ mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); - if (!mtdblks) + if (!mtdblk) return -ENOMEM; memset(mtdblk, 0, sizeof(*mtdblk)); diff -Nru a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c --- a/drivers/mtd/mtdchar.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/mtd/mtdchar.c 2004-06-26 17:09:19 -07:00 @@ -116,7 +116,7 @@ */ #define MAX_KMALLOC_SIZE 0x20000 -static ssize_t mtd_read(struct file *file, char *buf, size_t count,loff_t *ppos) +static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) { struct mtd_info *mtd = (struct mtd_info *)file->private_data; size_t retlen=0; @@ -169,7 +169,7 @@ return total_retlen; } /* mtd_read */ -static ssize_t mtd_write(struct file *file, const char *buf, size_t count,loff_t *ppos) +static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) { struct mtd_info *mtd = (struct mtd_info *)file->private_data; char *kbuf; @@ -238,6 +238,7 @@ u_int cmd, u_long arg) { struct mtd_info *mtd = (struct mtd_info *)file->private_data; + void __user *argp = (void __user *)arg; int ret = 0; u_long size; @@ -245,17 +246,17 @@ size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; if (cmd & IOC_IN) { - ret = verify_area(VERIFY_READ, (char *)arg, size); + ret = verify_area(VERIFY_READ, argp, size); if (ret) return ret; } if (cmd & IOC_OUT) { - ret = verify_area(VERIFY_WRITE, (char *)arg, size); + ret = verify_area(VERIFY_WRITE, argp, size); if (ret) return ret; } switch (cmd) { case MEMGETREGIONCOUNT: - if (copy_to_user((int *) arg, &(mtd->numeraseregions), sizeof(int))) + if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) return -EFAULT; break; @@ -263,24 +264,19 @@ { struct region_info_user ur; - if (copy_from_user( &ur, - (struct region_info_user *)arg, - sizeof(struct region_info_user))) { + if (copy_from_user(&ur, argp, sizeof(struct region_info_user))) return -EFAULT; - } if (ur.regionindex >= mtd->numeraseregions) return -EINVAL; - if (copy_to_user((struct mtd_erase_region_info *) arg, - &(mtd->eraseregions[ur.regionindex]), + if (copy_to_user(argp, &(mtd->eraseregions[ur.regionindex]), sizeof(struct mtd_erase_region_info))) return -EFAULT; break; } case MEMGETINFO: - if (copy_to_user((struct mtd_info *)arg, mtd, - sizeof(struct mtd_info_user))) + if (copy_to_user(argp, mtd, sizeof(struct mtd_info_user))) return -EFAULT; break; @@ -301,7 +297,7 @@ init_waitqueue_head(&waitq); memset (erase,0,sizeof(struct erase_info)); - if (copy_from_user(&erase->addr, (u_long *)arg, + if (copy_from_user(&erase->addr, argp, 2 * sizeof(u_long))) { kfree(erase); return -EFAULT; @@ -345,7 +341,7 @@ if(!(file->f_mode & 2)) return -EPERM; - if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) + if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) return -EFAULT; if (buf.length > 0x4096) @@ -354,7 +350,7 @@ if (!mtd->write_oob) ret = -EOPNOTSUPP; else - ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length); + ret = verify_area(VERIFY_READ, buf.ptr, buf.length); if (ret) return ret; @@ -370,7 +366,7 @@ ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf); - if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) + if (copy_to_user(argp + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) ret = -EFAULT; kfree(databuf); @@ -384,7 +380,7 @@ void *databuf; ssize_t retlen; - if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) + if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) return -EFAULT; if (buf.length > 0x4096) @@ -393,7 +389,7 @@ if (!mtd->read_oob) ret = -EOPNOTSUPP; else - ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length); + ret = verify_area(VERIFY_WRITE, buf.ptr, buf.length); if (ret) return ret; @@ -404,7 +400,7 @@ ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); - if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) + if (copy_to_user(argp + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) ret = -EFAULT; else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) ret = -EFAULT; @@ -417,7 +413,7 @@ { unsigned long adrs[2]; - if (copy_from_user(adrs ,(void *)arg, 2* sizeof(unsigned long))) + if (copy_from_user(adrs, argp, 2* sizeof(unsigned long))) return -EFAULT; if (!mtd->lock) @@ -431,7 +427,7 @@ { unsigned long adrs[2]; - if (copy_from_user(adrs, (void *)arg, 2* sizeof(unsigned long))) + if (copy_from_user(adrs, argp, 2* sizeof(unsigned long))) return -EFAULT; if (!mtd->unlock) @@ -443,7 +439,7 @@ case MEMSETOOBSEL: { - if (copy_from_user(&mtd->oobinfo ,(void *)arg, sizeof(struct nand_oobinfo))) + if (copy_from_user(&mtd->oobinfo, argp, sizeof(struct nand_oobinfo))) return -EFAULT; break; } diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c --- a/drivers/net/3c501.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/3c501.c 2004-06-26 17:09:15 -07:00 @@ -225,7 +225,7 @@ * Reserve I/O resource for exclusive use by this driver */ - if (!request_region(ioaddr, EL1_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, EL1_IO_EXTENT, DRV_NAME)) return -ENODEV; /* diff -Nru a/drivers/net/3c503.c b/drivers/net/3c503.c --- a/drivers/net/3c503.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/3c503.c 2004-06-26 17:09:19 -07:00 @@ -147,6 +147,7 @@ release_region(dev->base_addr, EL2_IO_EXTENT); } +#ifndef MODULE struct net_device * __init el2_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -171,6 +172,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif /* Probe for the Etherlink II card at I/O port base IOADDR, returning non-zero on success. If found, set the station @@ -182,10 +184,10 @@ static unsigned version_printed; unsigned long vendor_id; - if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME)) return -EBUSY; - if (!request_region(ioaddr + 0x400, 8, dev->name)) { + if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) { retval = -EBUSY; goto out; } diff -Nru a/drivers/net/3c505.c b/drivers/net/3c505.c --- a/drivers/net/3c505.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/3c505.c 2004-06-26 17:09:21 -07:00 @@ -1614,6 +1614,7 @@ return err; } +#ifndef MODULE struct net_device * __init elplus_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(elp_device)); @@ -1632,7 +1633,7 @@ return dev; } -#ifdef MODULE +#else static struct net_device *dev_3c505[ELP_MAX_CARDS]; static int io[ELP_MAX_CARDS]; static int irq[ELP_MAX_CARDS]; diff -Nru a/drivers/net/3c507.c b/drivers/net/3c507.c --- a/drivers/net/3c507.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/3c507.c 2004-06-26 17:09:19 -07:00 @@ -373,7 +373,7 @@ init_ID_done = 1; } - if (!request_region(ioaddr, EL16_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, EL16_IO_EXTENT, DRV_NAME)) return -ENODEV; if ((inb(ioaddr) != '*') || (inb(ioaddr + 1) != '3') || @@ -392,7 +392,7 @@ irq = inb(ioaddr + IRQ_CONFIG) & 0x0f; - irqval = request_irq(irq, &el16_interrupt, 0, dev->name, dev); + irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev); if (irqval) { printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval); retval = -EAGAIN; diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c --- a/drivers/net/3c509.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/3c509.c 2004-06-26 17:09:15 -07:00 @@ -56,10 +56,6 @@ v1.19b 08Nov2002 Marc Zyngier - Introduce driver model for EISA cards. */ -/* - FIXES for PC-9800: - Shu Iwanaga: 3c569B(PC-9801 C-bus) support -*/ #define DRV_NAME "3c509" #define DRV_VERSION "1.19b" @@ -265,7 +261,7 @@ }; #endif /* CONFIG_MCA */ -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) static struct isapnp_device_id el3_isapnp_adapters[] __initdata = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090), @@ -362,7 +358,7 @@ if (lp->pmdev) pm_unregister(lp->pmdev); #endif -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) if (lp->type == EL3_PNP) pnp_device_detach(to_pnp_dev(lp->dev)); #endif @@ -381,7 +377,7 @@ u16 phys_addr[3]; static int current_tag; int err = -ENODEV; -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) static int pnp_cards; struct pnp_dev *idev = NULL; @@ -436,9 +432,6 @@ no_pnp: #endif /* __ISAPNP__ */ -#ifdef CONFIG_X86_PC9800 - id_port = 0x71d0; -#else /* Select an open I/O location at 0x1*0 to do contention select. */ for ( ; id_port < 0x200; id_port += 0x10) { if (!request_region(id_port, 1, "3c509")) @@ -456,7 +449,7 @@ printk(" WARNING: No I/O port available for 3c509 activation.\n"); return -ENODEV; } -#endif /* CONFIG_X86_PC9800 */ + /* Next check for all ISA bus boards by sending the ID sequence to the ID_PORT. We find cards past the first by setting the 'current_tag' on cards as they are found. Cards with their tag set will not @@ -487,7 +480,7 @@ phys_addr[i] = htons(id_read_eeprom(i)); } -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) if (nopnp == 0) { /* The ISA PnP 3c509 cards respond to the ID sequence. This check is needed in order not to register them twice. */ @@ -512,19 +505,9 @@ { unsigned int iobase = id_read_eeprom(8); if_port = iobase >> 14; -#ifdef CONFIG_X86_PC9800 - ioaddr = 0x40d0 + ((iobase & 0x1f) << 8); -#else ioaddr = 0x200 + ((iobase & 0x1f) << 4); -#endif } irq = id_read_eeprom(9) >> 12; -#ifdef CONFIG_X86_PC9800 - if (irq == 7) - irq = 6; - else if (irq == 15) - irq = 13; -#endif dev = alloc_etherdev(sizeof (struct el3_private)); if (!dev) @@ -555,11 +538,7 @@ outb(0xd0 + ++current_tag, id_port); /* Activate the adaptor at the EEPROM location. */ -#ifdef CONFIG_X86_PC9800 - outb((ioaddr >> 8) | 0xe0, id_port); -#else outb((ioaddr >> 4) | 0xe0, id_port); -#endif EL3WINDOW(0); if (inw(ioaddr) != 0x6d50) @@ -568,7 +547,7 @@ /* Free the interrupt so that some other card can use it. */ outw(0x0f00, ioaddr + WN0_IRQ); -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) found: /* PNP jumps here... */ #endif /* __ISAPNP__ */ @@ -577,7 +556,7 @@ dev->irq = irq; dev->if_port = if_port; lp = netdev_priv(dev); -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) lp->dev = &idev->dev; #endif err = el3_common_init(dev); @@ -601,7 +580,7 @@ return 0; out1: -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) if (idev) pnp_device_detach(idev); #endif @@ -1461,12 +1440,6 @@ outw(0x0001, ioaddr + 4); /* Set the IRQ line. */ -#ifdef CONFIG_X86_PC9800 - if (dev->irq == 6) - dev->irq = 7; - else if (dev->irq == 13) - dev->irq = 15; -#endif outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ); /* Set the station address in window 2 each time opened. */ @@ -1629,7 +1602,7 @@ MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)"); MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt"); -#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) +#if defined(__ISAPNP__) MODULE_PARM(nopnp, "i"); MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)"); MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters); diff -Nru a/drivers/net/3c523.c b/drivers/net/3c523.c --- a/drivers/net/3c523.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/3c523.c 2004-06-26 17:09:18 -07:00 @@ -445,7 +445,7 @@ slot = mca_find_adapter(ELMC_MCA_ID, slot + 1); continue; } - if (!request_region(dev->base_addr, ELMC_IO_EXTENT, dev->name)) { + if (!request_region(dev->base_addr, ELMC_IO_EXTENT, DRV_NAME)) { slot = mca_find_adapter(ELMC_MCA_ID, slot + 1); continue; } @@ -585,6 +585,7 @@ release_region(dev->base_addr, ELMC_IO_EXTENT); } +#ifndef MODULE struct net_device * __init elmc_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct priv)); @@ -609,6 +610,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif /********************************************** * init the chip (elmc-interrupt should be disabled?!) diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c --- a/drivers/net/3c527.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/3c527.c 2004-06-26 17:09:18 -07:00 @@ -435,10 +435,10 @@ * Grab the IRQ */ - err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, DRV_NAME, dev); if (err) { release_region(dev->base_addr, MC32_IO_EXTENT); - printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq); + printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq); goto err_exit_ports; } diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c --- a/drivers/net/3c59x.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/3c59x.c 2004-06-26 17:09:15 -07:00 @@ -446,6 +446,7 @@ CH_3C905B_2, CH_3C905B_FX, CH_3C905C, + CH_3C9202, CH_3C980, CH_3C9805, @@ -520,12 +521,14 @@ {"3c905B-FX Cyclone 100baseFx", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c905C Tornado", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, + {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, {"3c980 Cyclone", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + {"3c980C Python-T", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, - {"3cSOHO100-TX Hurricane", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c555 Laptop Hurricane", @@ -536,9 +539,9 @@ {"3c556B Laptop Hurricane", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| WNO_XCVR_PWR|HAS_HWCKSM, 128, }, + {"3c575 [Megahertz] 10/100 LAN CardBus", PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, - {"3c575 Boomerang CardBus", PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, {"3CCFE575BT Cyclone CardBus", @@ -550,10 +553,10 @@ {"3CCFE656 Cyclone CardBus", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| INVERT_LED_PWR|HAS_HWCKSM, 128, }, + {"3CCFEM656B Cyclone+Winmodem CardBus", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| INVERT_LED_PWR|HAS_HWCKSM, 128, }, - {"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, @@ -563,9 +566,9 @@ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c982 Hydra Dual Port A", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + {"3c982 Hydra Dual Port B", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, - {"3c905B-T4", PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c920B-EMB-WNM Tornado", @@ -597,6 +600,7 @@ { 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 }, { 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX }, { 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C }, + { 0x10B7, 0x9202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9202 }, { 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 }, { 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 }, @@ -884,7 +888,7 @@ static int vortex_probe1(struct device *gendev, long ioaddr, int irq, int chip_idx, int card_idx); static void vortex_up(struct net_device *dev); -static void vortex_down(struct net_device *dev); +static void vortex_down(struct net_device *dev, int final); static int vortex_open(struct net_device *dev); static void mdio_sync(long ioaddr, int bits); static int mdio_read(struct net_device *dev, int phy_id, int location); @@ -948,7 +952,7 @@ if (dev && dev->priv) { if (netif_running(dev)) { netif_device_detach(dev); - vortex_down(dev); + vortex_down(dev, 1); } } return 0; @@ -2059,7 +2063,8 @@ printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status); /* In this case, blow the card away */ - vortex_down(dev); + /* Must not enter D3 or we can't legally issue the reset! */ + vortex_down(dev, 0); issue_and_wait(dev, TotalReset | 0xff); vortex_up(dev); /* AKPM: bug. vortex_up() assumes that the rx ring is full. It may not be. */ } else if (fifo_diag & 0x0400) @@ -2656,7 +2661,7 @@ } static void -vortex_down(struct net_device *dev) +vortex_down(struct net_device *dev, int final_down) { struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; @@ -2685,7 +2690,7 @@ if (vp->full_bus_master_tx) outl(0, ioaddr + DownListPtr); - if (VORTEX_PCI(vp) && vp->enable_wol) { + if (final_down && VORTEX_PCI(vp) && vp->enable_wol) { pci_save_state(VORTEX_PCI(vp), vp->power_state); acpi_set_WOL(dev); } @@ -2699,7 +2704,7 @@ int i; if (netif_device_present(dev)) - vortex_down(dev); + vortex_down(dev, 1); if (vortex_debug > 1) { printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n", @@ -2869,7 +2874,7 @@ .get_drvinfo = vortex_get_drvinfo, }; -static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int vortex_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; @@ -2904,6 +2909,30 @@ return retval; } +/* + * Must power the device up to do MDIO operations + */ +static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + int err; + struct vortex_private *vp = netdev_priv(dev); + int state = 0; + + if(VORTEX_PCI(vp)) + state = VORTEX_PCI(vp)->current_state; + + /* The kernel core really should have pci_get_power_state() */ + + if(state != 0) + pci_set_power_state(VORTEX_PCI(vp), 0); + err = vortex_do_ioctl(dev, rq, cmd); + if(state != 0) + pci_set_power_state(VORTEX_PCI(vp), state); + + return err; +} + + /* Pre-Cyclone chips have no documented multicast filter, so the only multicast setting is to receive all multicast frames. At least the chip has a very clean way to set the mode, unlike many others. */ @@ -3059,14 +3088,14 @@ * here */ unregister_netdev(dev); - /* Should really use issue_and_wait() here */ - outw(TotalReset|0x14, dev->base_addr + EL3_CMD); if (VORTEX_PCI(vp) && vp->enable_wol) { pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */ if (vp->pm_state_valid) pci_restore_state(VORTEX_PCI(vp), vp->power_state); } + /* Should really use issue_and_wait() here */ + outw(TotalReset|0x14, dev->base_addr + EL3_CMD); pci_free_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c 2004-06-26 17:09:14 -07:00 +++ b/drivers/net/8139too.c 2004-06-26 17:09:14 -07:00 @@ -87,8 +87,6 @@ "rtl8139-diag -mmmaaavvveefN" output enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log - See 8139too.txt for more details. - */ #define DRV_NAME "8139too" diff -Nru a/drivers/net/82596.c b/drivers/net/82596.c --- a/drivers/net/82596.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/82596.c 2004-06-26 17:09:19 -07:00 @@ -58,11 +58,12 @@ #include #include #include -#include static char version[] __initdata = "82596.c $Revision: 1.5 $\n"; +#define DRV_NAME "82596" + /* DEBUG flags */ @@ -1191,7 +1192,7 @@ /* this is easy the ethernet interface can only be at 0x300 */ /* first check nothing is already registered here */ - if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) { + if (!request_region(ioaddr, I596_TOTAL_SIZE, DRV_NAME)) { printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr); err = -EBUSY; goto out; diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig --- a/drivers/net/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/Kconfig 2004-06-26 17:09:20 -07:00 @@ -922,7 +922,7 @@ config NET_ISA bool "Other ISA cards" - depends on NET_ETHERNET && ISA && !X86_PC9800 + depends on NET_ETHERNET && ISA ---help--- If your network (Ethernet) card hasn't been mentioned yet and its bus system (that's the way the cards talks to the other components @@ -1105,56 +1105,6 @@ the Ethernet-HOWTO, available from . -config NET_CBUS - bool "NEC PC-9800 C-bus cards" - depends on NET_ETHERNET && ISA && X86_PC9800 - ---help--- - If your network (Ethernet) card hasn't been mentioned yet and its - bus system (that's the way the cards talks to the other components - of your computer) is NEC PC-9800 C-Bus, say Y. - -config NE2K_CBUS - tristate "Most NE2000-based Ethernet support" - depends on NET_CBUS - select CRC32 - -config NE2K_CBUS_EGY98 - bool "Melco EGY-98 support" - depends on NE2K_CBUS - -config NE2K_CBUS_LGY98 - bool "Melco LGY-98 support" - depends on NE2K_CBUS - -config NE2K_CBUS_ICM - bool "ICM IF-27xxET support" - depends on NE2K_CBUS - -config NE2K_CBUS_IOLA98 - bool "I-O DATA LA-98 support" - depends on NE2K_CBUS - -config NE2K_CBUS_CNET98EL - bool "Contec C-NET(98)E/L support" - depends on NE2K_CBUS - -config NE2K_CBUS_CNET98EL_IO_BASE - hex "C-NET(98)E/L I/O base address (0xaaed or 0x55ed)" - depends on NE2K_CBUS_CNET98EL - default "0xaaed" - -config NE2K_CBUS_ATLA98 - bool "Allied Telesis LA-98 Support" - depends on NE2K_CBUS - -config NE2K_CBUS_BDN - bool "ELECOM Laneed LD-BDN[123]A Support" - depends on NE2K_CBUS - -config NE2K_CBUS_NEC108 - bool "NEC PC-9801-108 Support" - depends on NE2K_CBUS - config SKMC tristate "SKnet MCA support" depends on NET_ETHERNET && MCA && BROKEN @@ -1287,6 +1237,19 @@ config AMD8111E_NAPI bool "Enable NAPI support" depends on AMD8111_ETH + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + + See for more + information. + + If in doubt, say N. config ADAPTEC_STARFIRE tristate "Adaptec Starfire/DuraLAN support" @@ -1314,6 +1277,11 @@ deployed on potentially unfriendly networks (e.g. in a firewall), then say Y here. + See for more + information. + + If in doubt, say N. + config AC3200 tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)" depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL @@ -1501,6 +1469,19 @@ config E100_NAPI bool "Use Rx Polling (NAPI)" depends on E100 + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + + See for more + information. + + If in doubt, say N. config LNE390 tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)" @@ -1605,9 +1586,7 @@ ---help--- This is a driver for the Fast Ethernet PCI network cards based on the RTL8139 chips. If you have one of those, say Y and read - as well as the - Ethernet-HOWTO, available from - . + the Ethernet-HOWTO . To compile this driver as a module, choose M here: the module will be called 8139too. This is recommended. @@ -1745,6 +1724,17 @@ If unsure, say Y. +config VIA_VELOCITY + tristate "VIA Velocity support" + depends on NET_PCI && PCI + select CRC32 + select MII + help + If you have a VIA "Velocity" based network card say Y here. + + To compile this driver as a module, choose M here. The module + will be called via-rhine. + config LAN_SAA9730 bool "Philips SAA9730 Ethernet support (EXPERIMENTAL)" depends on NET_PCI && EXPERIMENTAL && MIPS @@ -1963,6 +1953,19 @@ config E1000_NAPI bool "Use Rx Polling (NAPI)" depends on E1000 + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + + See for more + information. + + If in doubt, say N. config MYRI_SBUS tristate "MyriCOM Gigabit Ethernet support" @@ -2148,6 +2151,19 @@ config IXGB_NAPI bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" depends on IXGB && EXPERIMENTAL + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + + See for more + information. + + If in doubt, say N. config S2IO tristate "S2IO 10Gbe XFrame NIC" @@ -2160,6 +2176,19 @@ config S2IO_NAPI bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" depends on S2IO && EXPERIMENTAL + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + + See for more + information. + + If in doubt, say N. endmenu diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/Makefile 2004-06-26 17:09:16 -07:00 @@ -52,6 +52,7 @@ obj-$(CONFIG_SK98LIN) += sk98lin/ obj-$(CONFIG_SKFP) += skfp/ obj-$(CONFIG_VIA_RHINE) += via-rhine.o +obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o # @@ -79,7 +80,6 @@ obj-$(CONFIG_WD80x3) += wd.o 8390.o obj-$(CONFIG_EL2) += 3c503.o 8390.o obj-$(CONFIG_NE2000) += ne.o 8390.o -obj-$(CONFIG_NE2K_CBUS) += ne2k_cbus.o 8390.o obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o obj-$(CONFIG_HPLAN) += hp.o 8390.o obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c --- a/drivers/net/Space.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/Space.c 2004-06-26 17:09:15 -07:00 @@ -191,8 +191,8 @@ #ifdef CONFIG_E2100 /* Cabletron E21xx series. */ {e2100_probe, 0}, #endif -#if defined(CONFIG_NE2000) || defined(CONFIG_NE2K_CBUS) || \ - defined(CONFIG_NE_H8300) /* ISA & PC-9800 CBUS (use ne2k-pci for PCI cards) */ +#if defined(CONFIG_NE2000) || \ + defined(CONFIG_NE_H8300) /* ISA (use ne2k-pci for PCI cards) */ {ne_probe, 0}, #endif #ifdef CONFIG_LANCE /* ISA/VLB (use pcnet32 for PCI cards) */ diff -Nru a/drivers/net/ac3200.c b/drivers/net/ac3200.c --- a/drivers/net/ac3200.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/ac3200.c 2004-06-26 17:09:19 -07:00 @@ -39,6 +39,8 @@ #include "8390.h" +#define DRV_NAME "ac3200" + /* Offsets from the base address. */ #define AC_NIC_BASE 0x00 #define AC_SA_PROM 0x16 /* The station address PROM. */ @@ -130,6 +132,7 @@ iounmap((void *)dev->mem_start); } +#ifndef MODULE struct net_device * __init ac3200_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -154,12 +157,13 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init ac_probe1(int ioaddr, struct net_device *dev) { int i, retval; - if (!request_region(ioaddr, AC_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME)) return -EBUSY; if (inb_p(ioaddr + AC_ID_PORT) == 0xff) { @@ -203,7 +207,7 @@ printk(", assigning"); } - retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); + retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); if (retval) { printk (" nothing! Unable to get IRQ %d.\n", dev->irq); goto out1; diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c --- a/drivers/net/acenic.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/acenic.c 2004-06-26 17:09:18 -07:00 @@ -85,6 +85,8 @@ #include +#define DRV_NAME "acenic" + #undef INDEX_DEBUG #ifdef CONFIG_ACENIC_OMIT_TIGON_I @@ -443,6 +445,16 @@ "acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n" " http://home.cern.ch/~jes/gige/acenic.html\n"; +static int ace_get_settings(struct net_device *, struct ethtool_cmd *); +static int ace_set_settings(struct net_device *, struct ethtool_cmd *); +static void ace_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); + +static struct ethtool_ops ace_ethtool_ops = { + .get_settings = ace_get_settings, + .set_settings = ace_set_settings, + .get_drvinfo = ace_get_drvinfo, +}; + static int __devinit acenic_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -480,7 +492,7 @@ dev->hard_start_xmit = &ace_start_xmit; dev->get_stats = &ace_get_stats; dev->set_multicast_list = &ace_set_multicast_list; - dev->do_ioctl = &ace_ioctl; + SET_ETHTOOL_OPS(dev, &ace_ethtool_ops); dev->set_mac_address = &ace_set_mac_addr; dev->change_mtu = &ace_change_mtu; @@ -1195,10 +1207,10 @@ } ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ, - dev->name, dev); + DRV_NAME, dev); if (ecode) { printk(KERN_WARNING "%s: Requested IRQ %d is busy\n", - dev->name, pdev->irq); + DRV_NAME, pdev->irq); goto init_error; } else dev->irq = pdev->irq; @@ -2688,146 +2700,136 @@ return 0; } - -static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct ace_private *ap = dev->priv; struct ace_regs *regs = ap->regs; -#ifdef SIOCETHTOOL - struct ethtool_cmd ecmd; - u32 link, speed; + u32 link; - if (cmd != SIOCETHTOOL) - return -EOPNOTSUPP; - if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd))) - return -EFAULT; - switch (ecmd.cmd) { - case ETHTOOL_GSET: - ecmd.supported = - (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_FIBRE); - - ecmd.port = PORT_FIBRE; - ecmd.transceiver = XCVR_INTERNAL; - ecmd.phy_address = 0; - - link = readl(®s->GigLnkState); - if (link & LNK_1000MB) - ecmd.speed = SPEED_1000; - else { - link = readl(®s->FastLnkState); - if (link & LNK_100MB) - ecmd.speed = SPEED_100; - else if (link & LNK_100MB) - ecmd.speed = SPEED_10; - else - ecmd.speed = 0; - } - if (link & LNK_FULL_DUPLEX) - ecmd.duplex = DUPLEX_FULL; + memset(ecmd, 0, sizeof(struct ethtool_cmd)); + ecmd->supported = + (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | SUPPORTED_FIBRE); + + ecmd->port = PORT_FIBRE; + ecmd->transceiver = XCVR_INTERNAL; + + link = readl(®s->GigLnkState); + if (link & LNK_1000MB) + ecmd->speed = SPEED_1000; + else { + link = readl(®s->FastLnkState); + if (link & LNK_100MB) + ecmd->speed = SPEED_100; + else if (link & LNK_10MB) + ecmd->speed = SPEED_10; else - ecmd.duplex = DUPLEX_HALF; + ecmd->speed = 0; + } + if (link & LNK_FULL_DUPLEX) + ecmd->duplex = DUPLEX_FULL; + else + ecmd->duplex = DUPLEX_HALF; - if (link & LNK_NEGOTIATE) - ecmd.autoneg = AUTONEG_ENABLE; - else - ecmd.autoneg = AUTONEG_DISABLE; + if (link & LNK_NEGOTIATE) + ecmd->autoneg = AUTONEG_ENABLE; + else + ecmd->autoneg = AUTONEG_DISABLE; #if 0 - /* - * Current struct ethtool_cmd is insufficient - */ - ecmd.trace = readl(®s->TuneTrace); + /* + * Current struct ethtool_cmd is insufficient + */ + ecmd->trace = readl(®s->TuneTrace); - ecmd.txcoal = readl(®s->TuneTxCoalTicks); - ecmd.rxcoal = readl(®s->TuneRxCoalTicks); + ecmd->txcoal = readl(®s->TuneTxCoalTicks); + ecmd->rxcoal = readl(®s->TuneRxCoalTicks); #endif - ecmd.maxtxpkt = readl(®s->TuneMaxTxDesc); - ecmd.maxrxpkt = readl(®s->TuneMaxRxDesc); + ecmd->maxtxpkt = readl(®s->TuneMaxTxDesc); + ecmd->maxrxpkt = readl(®s->TuneMaxRxDesc); - if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - - case ETHTOOL_SSET: - link = readl(®s->GigLnkState); - if (link & LNK_1000MB) - speed = SPEED_1000; - else { - link = readl(®s->FastLnkState); - if (link & LNK_100MB) - speed = SPEED_100; - else if (link & LNK_100MB) - speed = SPEED_10; - else - speed = SPEED_100; - } + return 0; +} - link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB | - LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL; - if (!ACE_IS_TIGON_I(ap)) - link |= LNK_TX_FLOW_CTL_Y; - if (ecmd.autoneg == AUTONEG_ENABLE) - link |= LNK_NEGOTIATE; - if (ecmd.speed != speed) { - link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB); - switch (speed) { - case SPEED_1000: - link |= LNK_1000MB; - break; - case SPEED_100: - link |= LNK_100MB; - break; - case SPEED_10: - link |= LNK_10MB; - break; - } +static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct ace_private *ap = dev->priv; + struct ace_regs *regs = ap->regs; + u32 link, speed; + + link = readl(®s->GigLnkState); + if (link & LNK_1000MB) + speed = SPEED_1000; + else { + link = readl(®s->FastLnkState); + if (link & LNK_100MB) + speed = SPEED_100; + else if (link & LNK_10MB) + speed = SPEED_10; + else + speed = SPEED_100; + } + + link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB | + LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL; + if (!ACE_IS_TIGON_I(ap)) + link |= LNK_TX_FLOW_CTL_Y; + if (ecmd->autoneg == AUTONEG_ENABLE) + link |= LNK_NEGOTIATE; + if (ecmd->speed != speed) { + link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB); + switch (speed) { + case SPEED_1000: + link |= LNK_1000MB; + break; + case SPEED_100: + link |= LNK_100MB; + break; + case SPEED_10: + link |= LNK_10MB; + break; } - if (ecmd.duplex == DUPLEX_FULL) - link |= LNK_FULL_DUPLEX; + } - if (link != ap->link) { - struct cmd cmd; - printk(KERN_INFO "%s: Renegotiating link state\n", - dev->name); + if (ecmd->duplex == DUPLEX_FULL) + link |= LNK_FULL_DUPLEX; - ap->link = link; - writel(link, ®s->TuneLink); - if (!ACE_IS_TIGON_I(ap)) - writel(link, ®s->TuneFastLink); - wmb(); + if (link != ap->link) { + struct cmd cmd; + printk(KERN_INFO "%s: Renegotiating link state\n", + dev->name); - cmd.evt = C_LNK_NEGOTIATION; - cmd.code = 0; - cmd.idx = 0; - ace_issue_cmd(regs, &cmd); - } - return 0; + ap->link = link; + writel(link, ®s->TuneLink); + if (!ACE_IS_TIGON_I(ap)) + writel(link, ®s->TuneFastLink); + wmb(); - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "acenic", sizeof(info.driver) - 1); - sprintf(info.fw_version, "%i.%i.%i", - tigonFwReleaseMajor, tigonFwReleaseMinor, - tigonFwReleaseFix); - strncpy(info.version, version, sizeof(info.version) - 1); - if (ap && ap->pdev) - strcpy(info.bus_info, pci_name(ap->pdev)); - if (copy_to_user(ifr->ifr_data, &info, sizeof(info))) - return -EFAULT; - return 0; - } - default: - break; + cmd.evt = C_LNK_NEGOTIATION; + cmd.code = 0; + cmd.idx = 0; + ace_issue_cmd(regs, &cmd); } - -#endif - - return -EOPNOTSUPP; + return 0; } +static void ace_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct ace_private *ap = dev->priv; + + strlcpy(info->driver, "acenic", sizeof(info->driver)); + snprintf(info->version, sizeof(info->version), "%i.%i.%i", + tigonFwReleaseMajor, tigonFwReleaseMinor, + tigonFwReleaseFix); + + if (ap->pdev) + strlcpy(info->bus_info, pci_name(ap->pdev), + sizeof(info->bus_info)); + +} /* * Set the hardware MAC address. diff -Nru a/drivers/net/acenic.h b/drivers/net/acenic.h --- a/drivers/net/acenic.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/acenic.h 2004-06-26 17:09:18 -07:00 @@ -790,7 +790,6 @@ static void ace_dump_trace(struct ace_private *ap); static void ace_set_multicast_list(struct net_device *dev); static int ace_change_mtu(struct net_device *dev, int new_mtu); -static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int ace_set_mac_addr(struct net_device *dev, void *p); static void ace_set_rxtx_parms(struct net_device *dev, int jumbo); static int ace_allocate_descriptors(struct net_device *dev); diff -Nru a/drivers/net/apne.c b/drivers/net/apne.c --- a/drivers/net/apne.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/apne.c 2004-06-26 17:09:21 -07:00 @@ -49,6 +49,8 @@ /* ---- No user-serviceable parts below ---- */ +#define DRV_NAME "apne" + #define NE_BASE (dev->base_addr) #define NE_CMD 0x00 #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ @@ -168,7 +170,7 @@ return ERR_PTR(-ENODEV); } - if (!request_region(IOBASE, 0x20, dev->name)) { + if (!request_region(IOBASE, 0x20, DRV_NAME)) { free_netdev(dev); return ERR_PTR(-EBUSY); } @@ -310,7 +312,7 @@ dev->base_addr = ioaddr; /* Install the Interrupt handler */ - i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, dev->name, dev); + i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, DRV_NAME, dev); if (i) return i; for(i = 0; i < ETHER_ADDR_LEN; i++) { diff -Nru a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig --- a/drivers/net/arm/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/arm/Kconfig 2004-06-26 17:09:20 -07:00 @@ -45,3 +45,20 @@ number (MTD support is required for this). Otherwise you will need to set a suitable hw address using ifconfig. +config SMC91X + tristate "SMC 91C9x/91C1xxx support" + select CRC32 + select MII + depends on ARM + help + This is a driver for SMC's 91x series of Ethernet chipsets, + including the SMC91C94 and the SMC91C111. Say Y if you want it + compiled into the kernel, and read the file + and the Ethernet-HOWTO, + available from . + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called smc91x. If you want to compile it as a + module, say M here and read as well + as . diff -Nru a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile --- a/drivers/net/arm/Makefile 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/arm/Makefile 2004-06-26 17:09:19 -07:00 @@ -8,3 +8,4 @@ obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o +obj-$(CONFIG_SMC91X) += smc91x.o diff -Nru a/drivers/net/arm/smc91x.c b/drivers/net/arm/smc91x.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/net/arm/smc91x.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,2171 @@ +/* + * smc91x.c + * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices. + * + * Copyright (C) 1996 by Erik Stahlman + * Copyright (C) 2001 Standard Microsystems Corporation + * Developed by Simple Network Magic Corporation + * Copyright (C) 2003 Monta Vista Software, Inc. + * Unified SMC91x driver by Nicolas Pitre + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Arguments: + * io = for the base address + * irq = for the IRQ + * nowait = 0 for normal wait states, 1 eliminates additional wait states + * + * original author: + * Erik Stahlman + * + * hardware multicast code: + * Peter Cammaert + * + * contributors: + * Daris A Nevil + * Nicolas Pitre + * Russell King + * + * History: + * 08/20/00 Arnaldo Melo fix kfree(skb) in smc_hardware_send_packet + * 12/15/00 Christian Jullien fix "Warning: kfree_skb on hard IRQ" + * 03/16/01 Daris A Nevil modified smc9194.c for use with LAN91C111 + * 08/22/01 Scott Anderson merge changes from smc9194 to smc91111 + * 08/21/01 Pramod B Bhardwaj added support for RevB of LAN91C111 + * 12/20/01 Jeff Sutherland initial port to Xscale PXA with DMA support + * 04/07/03 Nicolas Pitre unified SMC91x driver, killed irq races, + * more bus abstraction, big cleanup, etc. + * 29/09/03 Russell King - add driver model support + * - ethtool support + * - convert to use generic MII interface + * - add link up/down notification + * - don't try to handle full negotiation in + * smc_phy_configure + * - clean up (and fix stack overrun) in PHY + * MII read/write functions + */ +static const char version[] = + "smc91x.c: v1.0, mar 07 2003 by Nicolas Pitre \n"; + +/* Debugging level */ +#ifndef SMC_DEBUG +#define SMC_DEBUG 0 +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "smc91x.h" + +#ifdef CONFIG_ISA +/* + * the LAN91C111 can be at any of the following port addresses. To change, + * for a slightly different card, you can add it to the array. Keep in + * mind that the array must end in zero. + */ +static unsigned int smc_portlist[] __initdata = { + 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, + 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0 +}; + +#ifndef SMC_IOADDR +# define SMC_IOADDR -1 +#endif +static unsigned long io = SMC_IOADDR; +module_param(io, ulong, 0400); +MODULE_PARM_DESC(io, "I/O base address"); + +#ifndef SMC_IRQ +# define SMC_IRQ -1 +#endif +static int irq = SMC_IRQ; +module_param(irq, int, 0400); +MODULE_PARM_DESC(irq, "IRQ number"); + +#endif /* CONFIG_ISA */ + +#ifndef SMC_NOWAIT +# define SMC_NOWAIT 0 +#endif +static int nowait = SMC_NOWAIT; +module_param(nowait, int, 0400); +MODULE_PARM_DESC(nowait, "set to 1 for no wait state"); + +/* + * Transmit timeout, default 5 seconds. + */ +static int watchdog = 5000; +module_param(watchdog, int, 0400); +MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); + +MODULE_LICENSE("GPL"); + +/* + * The internal workings of the driver. If you are changing anything + * here with the SMC stuff, you should have the datasheet and know + * what you are doing. + */ +#define CARDNAME "smc91x" + +/* + * Use power-down feature of the chip + */ +#define POWER_DOWN 1 + +/* + * Wait time for memory to be free. This probably shouldn't be + * tuned that much, as waiting for this means nothing else happens + * in the system + */ +#define MEMORY_WAIT_TIME 16 + +/* + * This selects whether TX packets are sent one by one to the SMC91x internal + * memory and throttled until transmission completes. This may prevent + * RX overruns a litle by keeping much of the memory free for RX packets + * but to the expense of reduced TX throughput and increased IRQ overhead. + * Note this is not a cure for a too slow data bus or too high IRQ latency. + */ +#define THROTTLE_TX_PKTS 0 + +/* + * The MII clock high/low times. 2x this number gives the MII clock period + * in microseconds. (was 50, but this gives 6.4ms for each MII transaction!) + */ +#define MII_DELAY 1 + +/* store this information for the driver.. */ +struct smc_local { + /* + * If I have to wait until memory is available to send a + * packet, I will store the skbuff here, until I get the + * desired memory. Then, I'll send it out and free it. + */ + struct sk_buff *saved_skb; + + /* + * these are things that the kernel wants me to keep, so users + * can find out semi-useless statistics of how well the card is + * performing + */ + struct net_device_stats stats; + + /* version/revision of the SMC91x chip */ + int version; + + /* Contains the current active transmission mode */ + int tcr_cur_mode; + + /* Contains the current active receive mode */ + int rcr_cur_mode; + + /* Contains the current active receive/phy mode */ + int rpc_cur_mode; + int ctl_rfduplx; + int ctl_rspeed; + + u32 msg_enable; + u32 phy_type; + struct mii_if_info mii; + spinlock_t lock; + +#ifdef SMC_USE_PXA_DMA + /* DMA needs the physical address of the chip */ + u_long physaddr; +#endif +}; + +#if SMC_DEBUG > 0 +#define DBG(n, args...) \ + do { \ + if (SMC_DEBUG >= (n)) \ + printk(KERN_DEBUG args); \ + } while (0) + +#define PRINTK(args...) printk(args) +#else +#define DBG(n, args...) do { } while(0) +#define PRINTK(args...) printk(KERN_DEBUG args) +#endif + +#if SMC_DEBUG > 3 +static void PRINT_PKT(u_char *buf, int length) +{ + int i; + int remainder; + int lines; + + lines = length / 16; + remainder = length % 16; + + for (i = 0; i < lines ; i ++) { + int cur; + for (cur = 0; cur < 8; cur++) { + u_char a, b; + a = *buf++; + b = *buf++; + printk("%02x%02x ", a, b); + } + printk("\n"); + } + for (i = 0; i < remainder/2 ; i++) { + u_char a, b; + a = *buf++; + b = *buf++; + printk("%02x%02x ", a, b); + } + printk("\n"); +} +#else +#define PRINT_PKT(x...) do { } while(0) +#endif + + +/* this enables an interrupt in the interrupt mask register */ +#define SMC_ENABLE_INT(x) do { \ + unsigned long flags; \ + unsigned char mask; \ + spin_lock_irqsave(&lp->lock, flags); \ + mask = SMC_GET_INT_MASK(); \ + mask |= (x); \ + SMC_SET_INT_MASK(mask); \ + spin_unlock_irqrestore(&lp->lock, flags); \ +} while (0) + +/* this disables an interrupt from the interrupt mask register */ +#define SMC_DISABLE_INT(x) do { \ + unsigned long flags; \ + unsigned char mask; \ + spin_lock_irqsave(&lp->lock, flags); \ + mask = SMC_GET_INT_MASK(); \ + mask &= ~(x); \ + SMC_SET_INT_MASK(mask); \ + spin_unlock_irqrestore(&lp->lock, flags); \ +} while (0) + +/* + * Wait while MMU is busy. This is usually in the order of a few nanosecs + * if at all, but let's avoid deadlocking the system if the hardware + * decides to go south. + */ +#define SMC_WAIT_MMU_BUSY() do { \ + if (unlikely(SMC_GET_MMU_CMD() & MC_BUSY)) { \ + unsigned long timeout = jiffies + 2; \ + while (SMC_GET_MMU_CMD() & MC_BUSY) { \ + if (time_after(jiffies, timeout)) { \ + printk("%s: timeout %s line %d\n", \ + dev->name, __FILE__, __LINE__); \ + break; \ + } \ + cpu_relax(); \ + } \ + } \ +} while (0) + + +/* + * this does a soft reset on the device + */ +static void smc_reset(struct net_device *dev) +{ + unsigned long ioaddr = dev->base_addr; + unsigned int ctl, cfg; + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + /* + * This resets the registers mostly to defaults, but doesn't + * affect EEPROM. That seems unnecessary + */ + SMC_SELECT_BANK(0); + SMC_SET_RCR(RCR_SOFTRST); + + /* + * Setup the Configuration Register + * This is necessary because the CONFIG_REG is not affected + * by a soft reset + */ + SMC_SELECT_BANK(1); + + cfg = CONFIG_DEFAULT; + + /* + * Setup for fast accesses if requested. If the card/system + * can't handle it then there will be no recovery except for + * a hard reset or power cycle + */ + if (nowait) + cfg |= CONFIG_NO_WAIT; + + /* + * Release from possible power-down state + * Configuration register is not affected by Soft Reset + */ + cfg |= CONFIG_EPH_POWER_EN; + + SMC_SET_CONFIG(cfg); + + /* this should pause enough for the chip to be happy */ + /* + * elaborate? What does the chip _need_? --jgarzik + * + * This seems to be undocumented, but something the original + * driver(s) have always done. Suspect undocumented timing + * info/determined empirically. --rmk + */ + udelay(1); + + /* Disable transmit and receive functionality */ + SMC_SELECT_BANK(0); + SMC_SET_RCR(RCR_CLEAR); + SMC_SET_TCR(TCR_CLEAR); + + SMC_SELECT_BANK(1); + ctl = SMC_GET_CTL() | CTL_LE_ENABLE; + + /* + * Set the control register to automatically release successfully + * transmitted packets, to make the best use out of our limited + * memory + */ +#if ! THROTTLE_TX_PKTS + ctl |= CTL_AUTO_RELEASE; +#else + ctl &= ~CTL_AUTO_RELEASE; +#endif + SMC_SET_CTL(ctl); + + /* Disable all interrupts */ + SMC_SELECT_BANK(2); + SMC_SET_INT_MASK(0); + + /* Reset the MMU */ + SMC_SET_MMU_CMD(MC_RESET); + SMC_WAIT_MMU_BUSY(); +} + +/* + * Enable Interrupts, Receive, and Transmit + */ +static void smc_enable(struct net_device *dev) +{ + unsigned long ioaddr = dev->base_addr; + struct smc_local *lp = netdev_priv(dev); + int mask; + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + /* see the header file for options in TCR/RCR DEFAULT */ + SMC_SELECT_BANK(0); + SMC_SET_TCR(lp->tcr_cur_mode); + SMC_SET_RCR(lp->rcr_cur_mode); + + /* now, enable interrupts */ + mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT; + if (lp->version >= (CHIP_91100 << 4)) + mask |= IM_MDINT; + SMC_SELECT_BANK(2); + SMC_SET_INT_MASK(mask); +} + +/* + * this puts the device in an inactive state + */ +static void smc_shutdown(unsigned long ioaddr) +{ + DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); + + /* no more interrupts for me */ + SMC_SELECT_BANK(2); + SMC_SET_INT_MASK(0); + + /* and tell the card to stay away from that nasty outside world */ + SMC_SELECT_BANK(0); + SMC_SET_RCR(RCR_CLEAR); + SMC_SET_TCR(TCR_CLEAR); + +#ifdef POWER_DOWN + /* finally, shut the chip down */ + SMC_SELECT_BANK(1); + SMC_SET_CONFIG(SMC_GET_CONFIG() & ~CONFIG_EPH_POWER_EN); +#endif +} + +/* + * This is the procedure to handle the receipt of a packet. + */ +static inline void smc_rcv(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + unsigned int packet_number, status, packet_len; + + DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + + packet_number = SMC_GET_RXFIFO(); + if (unlikely(packet_number & RXFIFO_REMPTY)) { + PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name); + return; + } + + /* read from start of packet */ + SMC_SET_PTR(PTR_READ | PTR_RCV | PTR_AUTOINC); + + /* First two words are status and packet length */ + SMC_GET_PKT_HDR(status, packet_len); + packet_len &= 0x07ff; /* mask off top bits */ + DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", + dev->name, packet_number, status, + packet_len, packet_len); + + if (unlikely(status & RS_ERRORS)) { + lp->stats.rx_errors++; + if (status & RS_ALGNERR) + lp->stats.rx_frame_errors++; + if (status & (RS_TOOSHORT | RS_TOOLONG)) + lp->stats.rx_length_errors++; + if (status & RS_BADCRC) + lp->stats.rx_crc_errors++; + } else { + struct sk_buff *skb; + unsigned char *data; + unsigned int data_len; + + /* set multicast stats */ + if (status & RS_MULTICAST) + lp->stats.multicast++; + + /* + * Actual payload is packet_len - 4 (or 3 if odd byte). + * We want skb_reserve(2) and the final ctrl word + * (2 bytes, possibly containing the payload odd byte). + * Ence packet_len - 4 + 2 + 2. + */ + skb = dev_alloc_skb(packet_len); + if (unlikely(skb == NULL)) { + printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", + dev->name); + lp->stats.rx_dropped++; + goto done; + } + + /* Align IP header to 32 bits */ + skb_reserve(skb, 2); + + /* BUG: the LAN91C111 rev A never sets this bit. Force it. */ + if (lp->version == 0x90) + status |= RS_ODDFRAME; + + /* + * If odd length: packet_len - 3, + * otherwise packet_len - 4. + */ + data_len = packet_len - ((status & RS_ODDFRAME) ? 3 : 4); + data = skb_put(skb, data_len); + SMC_PULL_DATA(data, packet_len - 2); + + PRINT_PKT(data, packet_len - 2); + + dev->last_rx = jiffies; + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + lp->stats.rx_packets++; + lp->stats.rx_bytes += data_len; + } + +done: + SMC_WAIT_MMU_BUSY(); + SMC_SET_MMU_CMD(MC_RELEASE); +} + +/* + * This is called to actually send a packet to the chip. + * Returns non-zero when successful. + */ +static void smc_hardware_send_packet(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + struct sk_buff *skb = lp->saved_skb; + unsigned int packet_no, len; + unsigned char *buf; + + DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + + packet_no = SMC_GET_AR(); + if (unlikely(packet_no & AR_FAILED)) { + printk("%s: Memory allocation failed.\n", dev->name); + lp->saved_skb = NULL; + lp->stats.tx_errors++; + lp->stats.tx_fifo_errors++; + dev_kfree_skb_any(skb); + return; + } + + /* point to the beginning of the packet */ + SMC_SET_PN(packet_no); + SMC_SET_PTR(PTR_AUTOINC); + + buf = skb->data; + len = skb->len; + DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n", + dev->name, packet_no, len, len, buf); + PRINT_PKT(buf, len); + + /* + * Send the packet length (+6 for status words, length, and ctl. + * The card will pad to 64 bytes with zeroes if packet is too small. + */ + SMC_PUT_PKT_HDR(0, len + 6); + + /* send the actual data */ + SMC_PUSH_DATA(buf, len & ~1); + + /* Send final ctl word with the last byte if there is one */ + SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG); + + /* and let the chipset deal with it */ + SMC_SET_MMU_CMD(MC_ENQUEUE); + SMC_ACK_INT(IM_TX_EMPTY_INT); + + dev->trans_start = jiffies; + dev_kfree_skb_any(skb); + lp->saved_skb = NULL; + lp->stats.tx_packets++; + lp->stats.tx_bytes += len; +} + +/* + * Since I am not sure if I will have enough room in the chip's ram + * to store the packet, I call this routine which either sends it + * now, or set the card to generates an interrupt when ready + * for the packet. + */ +static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + unsigned int numPages, poll_count, status, saved_bank; + + DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + + BUG_ON(lp->saved_skb != NULL); + lp->saved_skb = skb; + + /* + * The MMU wants the number of pages to be the number of 256 bytes + * 'pages', minus 1 (since a packet can't ever have 0 pages :)) + * + * The 91C111 ignores the size bits, but earlier models don't. + * + * Pkt size for allocating is data length +6 (for additional status + * words, length and ctl) + * + * If odd size then last byte is included in ctl word. + */ + numPages = ((skb->len & ~1) + (6 - 1)) >> 8; + if (unlikely(numPages > 7)) { + printk("%s: Far too big packet error.\n", dev->name); + lp->saved_skb = NULL; + lp->stats.tx_errors++; + lp->stats.tx_dropped++; + dev_kfree_skb(skb); + return 0; + } + + /* now, try to allocate the memory */ + saved_bank = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(2); + SMC_SET_MMU_CMD(MC_ALLOC | numPages); + + /* + * Poll the chip for a short amount of time in case the + * allocation succeeds quickly. + */ + poll_count = MEMORY_WAIT_TIME; + do { + status = SMC_GET_INT(); + if (status & IM_ALLOC_INT) { + SMC_ACK_INT(IM_ALLOC_INT); + break; + } + } while (--poll_count); + + if (!poll_count) { + /* oh well, wait until the chip finds memory later */ + netif_stop_queue(dev); + DBG(2, "%s: TX memory allocation deferred.\n", dev->name); + SMC_ENABLE_INT(IM_ALLOC_INT); + } else { + /* + * Allocation succeeded: push packet to the chip's own memory + * immediately. + * + * If THROTTLE_TX_PKTS is selected that means we don't want + * more than a single TX packet taking up space in the chip's + * internal memory at all time, in which case we stop the + * queue right here until we're notified of TX completion. + * + * Otherwise we're quite happy to feed more TX packets right + * away for better TX throughput, in which case the queue is + * left active. + */ +#if THROTTLE_TX_PKTS + netif_stop_queue(dev); +#endif + smc_hardware_send_packet(dev); + SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT); + } + + SMC_SELECT_BANK(saved_bank); + return 0; +} + +/* + * This handles a TX interrupt, which is only called when: + * - a TX error occurred, or + * - CTL_AUTO_RELEASE is not set and TX of a packet completed. + */ +static void smc_tx(struct net_device *dev) +{ + unsigned long ioaddr = dev->base_addr; + struct smc_local *lp = netdev_priv(dev); + unsigned int saved_packet, packet_no, tx_status, pkt_len; + + DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + + /* If the TX FIFO is empty then nothing to do */ + packet_no = SMC_GET_TXFIFO(); + if (unlikely(packet_no & TXFIFO_TEMPTY)) { + PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name); + return; + } + + /* select packet to read from */ + saved_packet = SMC_GET_PN(); + SMC_SET_PN(packet_no); + + /* read the first word (status word) from this packet */ + SMC_SET_PTR(PTR_AUTOINC | PTR_READ); + SMC_GET_PKT_HDR(tx_status, pkt_len); + DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n", + dev->name, tx_status, packet_no); + + if (!(tx_status & TS_SUCCESS)) + lp->stats.tx_errors++; + if (tx_status & TS_LOSTCAR) + lp->stats.tx_carrier_errors++; + + SMC_WAIT_MMU_BUSY(); + + if (tx_status & TS_LATCOL) { + PRINTK("%s: late collision occurred on last xmit\n", dev->name); + lp->stats.tx_window_errors++; + /* It's really cheap to requeue the pkt here */ + SMC_SET_MMU_CMD( MC_ENQUEUE ); + } else { + /* kill the packet */ + SMC_SET_MMU_CMD(MC_FREEPKT); + } + + /* Don't restore Packet Number Reg until busy bit is cleared */ + SMC_WAIT_MMU_BUSY(); + SMC_SET_PN(saved_packet); + + /* re-enable transmit */ + SMC_SELECT_BANK(0); + SMC_SET_TCR(lp->tcr_cur_mode); + SMC_SELECT_BANK(2); +} + + +/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/ + +static void smc_mii_out(struct net_device *dev, unsigned int val, int bits) +{ + unsigned long ioaddr = dev->base_addr; + unsigned int mii_reg, mask; + + mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO); + mii_reg |= MII_MDOE; + + for (mask = 1 << (bits - 1); mask; mask >>= 1) { + if (val & mask) + mii_reg |= MII_MDO; + else + mii_reg &= ~MII_MDO; + + SMC_SET_MII(mii_reg); + udelay(MII_DELAY); + SMC_SET_MII(mii_reg | MII_MCLK); + udelay(MII_DELAY); + } +} + +static unsigned int smc_mii_in(struct net_device *dev, int bits) +{ + unsigned long ioaddr = dev->base_addr; + unsigned int mii_reg, mask, val; + + mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO); + SMC_SET_MII(mii_reg); + + for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) { + if (SMC_GET_MII() & MII_MDI) + val |= mask; + + SMC_SET_MII(mii_reg); + udelay(MII_DELAY); + SMC_SET_MII(mii_reg | MII_MCLK); + udelay(MII_DELAY); + } + + return val; +} + +/* + * Reads a register from the MII Management serial interface + */ +static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg) +{ + unsigned long ioaddr = dev->base_addr; + unsigned int phydata, old_bank; + + /* Save the current bank, and select bank 3 */ + old_bank = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(3); + + /* Idle - 32 ones */ + smc_mii_out(dev, 0xffffffff, 32); + + /* Start code (01) + read (10) + phyaddr + phyreg */ + smc_mii_out(dev, 6 << 10 | phyaddr << 5 | phyreg, 14); + + /* Turnaround (2bits) + phydata */ + phydata = smc_mii_in(dev, 18); + + /* Return to idle state */ + SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO)); + + /* And select original bank */ + SMC_SELECT_BANK(old_bank); + + DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", + __FUNCTION__, phyaddr, phyreg, phydata); + + return phydata; +} + +/* + * Writes a register to the MII Management serial interface + */ +static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg, + int phydata) +{ + unsigned long ioaddr = dev->base_addr; + unsigned int old_bank; + + /* Save the current bank, and select bank 3 */ + old_bank = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(3); + + /* Idle - 32 ones */ + smc_mii_out(dev, 0xffffffff, 32); + + /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */ + smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32); + + /* Return to idle state */ + SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO)); + + /* And select original bank */ + SMC_SELECT_BANK(old_bank); + + DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", + __FUNCTION__, phyaddr, phyreg, phydata); +} + +/* + * Finds and reports the PHY address + */ +static void smc_detect_phy(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + int phyaddr; + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + lp->phy_type = 0; + + /* + * Scan all 32 PHY addresses if necessary, starting at + * PHY#1 to PHY#31, and then PHY#0 last. + */ + for (phyaddr = 1; phyaddr < 33; ++phyaddr) { + unsigned int id1, id2; + + /* Read the PHY identifiers */ + id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1); + id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2); + + DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", + dev->name, id1, id2); + + /* Make sure it is a valid identifier */ + if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 && + id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) { + /* Save the PHY's address */ + lp->mii.phy_id = phyaddr & 31; + lp->phy_type = id1 << 16 | id2; + break; + } + } +} + +/* + * Sets the PHY to a configuration as determined by the user + */ +static int smc_phy_fixed(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + int phyaddr = lp->mii.phy_id; + int bmcr, cfg1; + + DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + + /* Enter Link Disable state */ + cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG); + cfg1 |= PHY_CFG1_LNKDIS; + smc_phy_write(dev, phyaddr, PHY_CFG1_REG, cfg1); + + /* + * Set our fixed capabilities + * Disable auto-negotiation + */ + bmcr = 0; + + if (lp->ctl_rfduplx) + bmcr |= BMCR_FULLDPLX; + + if (lp->ctl_rspeed == 100) + bmcr |= BMCR_SPEED100; + + /* Write our capabilities to the phy control register */ + smc_phy_write(dev, phyaddr, MII_BMCR, bmcr); + + /* Re-Configure the Receive/Phy Control register */ + SMC_SET_RPC(lp->rpc_cur_mode); + + return 1; +} + +/* + * smc_phy_reset - reset the phy + * @dev: net device + * @phy: phy address + * + * Issue a software reset for the specified PHY and + * wait up to 100ms for the reset to complete. We should + * not access the PHY for 50ms after issuing the reset. + * + * The time to wait appears to be dependent on the PHY. + * + * Must be called with lp->lock locked. + */ +static int smc_phy_reset(struct net_device *dev, int phy) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned int bmcr; + int timeout; + + smc_phy_write(dev, phy, MII_BMCR, BMCR_RESET); + + for (timeout = 2; timeout; timeout--) { + spin_unlock_irq(&lp->lock); + msleep(50); + spin_lock_irq(&lp->lock); + + bmcr = smc_phy_read(dev, phy, MII_BMCR); + if (!(bmcr & BMCR_RESET)) + break; + } + + return bmcr & BMCR_RESET; +} + +/* + * smc_phy_powerdown - powerdown phy + * @dev: net device + * @phy: phy address + * + * Power down the specified PHY + */ +static void smc_phy_powerdown(struct net_device *dev, int phy) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned int bmcr; + + spin_lock_irq(&lp->lock); + bmcr = smc_phy_read(dev, phy, MII_BMCR); + smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); + spin_unlock_irq(&lp->lock); +} + +/* + * smc_phy_check_media - check the media status and adjust TCR + * @dev: net device + * @init: set true for initialisation + * + * Select duplex mode depending on negotiation state. This + * also updates our carrier state. + */ +static void smc_phy_check_media(struct net_device *dev, int init) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + + if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { + unsigned int old_bank; + + /* duplex state has changed */ + if (lp->mii.full_duplex) { + lp->tcr_cur_mode |= TCR_SWFDUP; + } else { + lp->tcr_cur_mode &= ~TCR_SWFDUP; + } + + old_bank = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(0); + SMC_SET_TCR(lp->tcr_cur_mode); + SMC_SELECT_BANK(old_bank); + } +} + +/* + * Configures the specified PHY through the MII management interface + * using Autonegotiation. + * Calls smc_phy_fixed() if the user has requested a certain config. + * If RPC ANEG bit is set, the media selection is dependent purely on + * the selection by the MII (either in the MII BMCR reg or the result + * of autonegotiation.) If the RPC ANEG bit is cleared, the selection + * is controlled by the RPC SPEED and RPC DPLX bits. + */ +static void smc_phy_configure(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + int phyaddr = lp->mii.phy_id; + int my_phy_caps; /* My PHY capabilities */ + int my_ad_caps; /* My Advertised capabilities */ + int status; + + DBG(3, "%s:smc_program_phy()\n", dev->name); + + spin_lock_irq(&lp->lock); + + /* + * We should not be called if phy_type is zero. + */ + if (lp->phy_type == 0) + goto smc_phy_configure_exit; + + if (smc_phy_reset(dev, phyaddr)) { + printk("%s: PHY reset timed out\n", dev->name); + goto smc_phy_configure_exit; + } + + /* + * Enable PHY Interrupts (for register 18) + * Interrupts listed here are disabled + */ + smc_phy_write(dev, phyaddr, PHY_MASK_REG, + PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD | + PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB | + PHY_INT_SPDDET | PHY_INT_DPLXDET); + + /* Configure the Receive/Phy Control register */ + SMC_SELECT_BANK(0); + SMC_SET_RPC(lp->rpc_cur_mode); + + /* If the user requested no auto neg, then go set his request */ + if (lp->mii.force_media) { + smc_phy_fixed(dev); + goto smc_phy_configure_exit; + } + + /* Copy our capabilities from MII_BMSR to MII_ADVERTISE */ + my_phy_caps = smc_phy_read(dev, phyaddr, MII_BMSR); + + if (!(my_phy_caps & BMSR_ANEGCAPABLE)) { + printk(KERN_INFO "Auto negotiation NOT supported\n"); + smc_phy_fixed(dev); + goto smc_phy_configure_exit; + } + + my_ad_caps = ADVERTISE_CSMA; /* I am CSMA capable */ + + if (my_phy_caps & BMSR_100BASE4) + my_ad_caps |= ADVERTISE_100BASE4; + if (my_phy_caps & BMSR_100FULL) + my_ad_caps |= ADVERTISE_100FULL; + if (my_phy_caps & BMSR_100HALF) + my_ad_caps |= ADVERTISE_100HALF; + if (my_phy_caps & BMSR_10FULL) + my_ad_caps |= ADVERTISE_10FULL; + if (my_phy_caps & BMSR_10HALF) + my_ad_caps |= ADVERTISE_10HALF; + + /* Disable capabilities not selected by our user */ + if (lp->ctl_rspeed != 100) + my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF); + + if (!lp->ctl_rfduplx) + my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL); + + /* Update our Auto-Neg Advertisement Register */ + smc_phy_write(dev, phyaddr, MII_ADVERTISE, my_ad_caps); + lp->mii.advertising = my_ad_caps; + + /* + * Read the register back. Without this, it appears that when + * auto-negotiation is restarted, sometimes it isn't ready and + * the link does not come up. + */ + status = smc_phy_read(dev, phyaddr, MII_ADVERTISE); + + DBG(2, "%s: phy caps=%x\n", dev->name, my_phy_caps); + DBG(2, "%s: phy advertised caps=%x\n", dev->name, my_ad_caps); + + /* Restart auto-negotiation process in order to advertise my caps */ + smc_phy_write(dev, phyaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); + + smc_phy_check_media(dev, 1); + +smc_phy_configure_exit: + spin_unlock_irq(&lp->lock); +} + +/* + * smc_phy_interrupt + * + * Purpose: Handle interrupts relating to PHY register 18. This is + * called from the "hard" interrupt handler under our private spinlock. + */ +static void smc_phy_interrupt(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + int phyaddr = lp->mii.phy_id; + int phy18; + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + if (lp->phy_type == 0) + return; + + for(;;) { + smc_phy_check_media(dev, 0); + + /* Read PHY Register 18, Status Output */ + phy18 = smc_phy_read(dev, phyaddr, PHY_INT_REG); + if ((phy18 & PHY_INT_INT) == 0) + break; + } +} + +/*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/ + +static void smc_10bt_check_media(struct net_device *dev, int init) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + unsigned int old_carrier, new_carrier, old_bank; + + old_bank = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(0); + old_carrier = netif_carrier_ok(dev) ? 1 : 0; + new_carrier = SMC_inw(ioaddr, EPH_STATUS_REG) & ES_LINK_OK ? 1 : 0; + + if (init || (old_carrier != new_carrier)) { + if (!new_carrier) { + netif_carrier_off(dev); + } else { + netif_carrier_on(dev); + } + if (netif_msg_link(lp)) + printk(KERN_INFO "%s: link %s\n", dev->name, + new_carrier ? "up" : "down"); + } + SMC_SELECT_BANK(old_bank); +} + +static void smc_eph_interrupt(struct net_device *dev) +{ + unsigned long ioaddr = dev->base_addr; + unsigned int old_bank, ctl; + + smc_10bt_check_media(dev, 0); + + old_bank = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(1); + + ctl = SMC_GET_CTL(); + SMC_SET_CTL(ctl & ~CTL_LE_ENABLE); + SMC_SET_CTL(ctl); + + SMC_SELECT_BANK(old_bank); +} + +/* + * This is the main routine of the driver, to handle the device when + * it needs some attention. + */ +static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + unsigned long ioaddr = dev->base_addr; + struct smc_local *lp = netdev_priv(dev); + int status, mask, timeout, card_stats; + int saved_bank, saved_pointer; + + DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + + saved_bank = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(2); + saved_pointer = SMC_GET_PTR(); + mask = SMC_GET_INT_MASK(); + SMC_SET_INT_MASK(0); + + /* set a timeout value, so I don't stay here forever */ + timeout = 8; + + do { + status = SMC_GET_INT(); + + DBG(2, "%s: IRQ 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", + dev->name, status, mask, + ({ int meminfo; SMC_SELECT_BANK(0); + meminfo = SMC_GET_MIR(); + SMC_SELECT_BANK(2); meminfo; }), + SMC_GET_FIFO()); + + status &= mask; + if (!status) + break; + + spin_lock(&lp->lock); + + if (status & IM_RCV_INT) { + DBG(3, "%s: RX irq\n", dev->name); + smc_rcv(dev); + } else if (status & IM_TX_INT) { + DBG(3, "%s: TX int\n", dev->name); + smc_tx(dev); + SMC_ACK_INT(IM_TX_INT); +#if THROTTLE_TX_PKTS + netif_wake_queue(dev); +#endif + } else if (status & IM_ALLOC_INT) { + DBG(3, "%s: Allocation irq\n", dev->name); + smc_hardware_send_packet(dev); + mask |= (IM_TX_INT | IM_TX_EMPTY_INT); + mask &= ~IM_ALLOC_INT; +#if ! THROTTLE_TX_PKTS + netif_wake_queue(dev); +#endif + } else if (status & IM_TX_EMPTY_INT) { + DBG(3, "%s: TX empty\n", dev->name); + mask &= ~IM_TX_EMPTY_INT; + + /* update stats */ + SMC_SELECT_BANK(0); + card_stats = SMC_GET_COUNTER(); + SMC_SELECT_BANK(2); + + /* single collisions */ + lp->stats.collisions += card_stats & 0xF; + card_stats >>= 4; + + /* multiple collisions */ + lp->stats.collisions += card_stats & 0xF; + } else if (status & IM_RX_OVRN_INT) { + DBG(1, "%s: RX overrun\n", dev->name); + SMC_ACK_INT(IM_RX_OVRN_INT); + lp->stats.rx_errors++; + lp->stats.rx_fifo_errors++; + } else if (status & IM_EPH_INT) { + smc_eph_interrupt(dev); + } else if (status & IM_MDINT) { + SMC_ACK_INT(IM_MDINT); + smc_phy_interrupt(dev); + } else if (status & IM_ERCV_INT) { + SMC_ACK_INT(IM_ERCV_INT); + PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name); + } + + spin_unlock(&lp->lock); + } while (--timeout); + + /* restore register states */ + SMC_SET_INT_MASK(mask); + SMC_SET_PTR(saved_pointer); + SMC_SELECT_BANK(saved_bank); + + DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout); + + /* + * We return IRQ_HANDLED unconditionally here even if there was + * nothing to do. There is a possibility that a packet might + * get enqueued into the chip right after TX_EMPTY_INT is raised + * but just before the CPU acknowledges the IRQ. + * Better take an unneeded IRQ in some occasions than complexifying + * the code for all cases. + */ + return IRQ_HANDLED; +} + +/* Our watchdog timed out. Called by the networking layer */ +static void smc_timeout(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + smc_reset(dev); + smc_enable(dev); + +#if 0 + /* + * Reconfiguring the PHY doesn't seem like a bad idea here, but + * it introduced a problem. Now that this is a timeout routine, + * we are getting called from within an interrupt context. + * smc_phy_configure() calls msleep() which calls + * schedule_timeout() which calls schedule(). When schedule() + * is called from an interrupt context, it prints out + * "Scheduling in interrupt" and then calls BUG(). This is + * obviously not desirable. This was worked around by removing + * the call to smc_phy_configure() here because it didn't seem + * absolutely necessary. Ultimately, if msleep() is + * supposed to be usable from an interrupt context (which it + * looks like it thinks it should handle), it should be fixed. + */ + if (lp->phy_type != 0) + smc_phy_configure(dev); +#endif + + /* clear anything saved */ + if (lp->saved_skb != NULL) { + dev_kfree_skb (lp->saved_skb); + lp->saved_skb = NULL; + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + } + /* We can accept TX packets again */ + dev->trans_start = jiffies; + netif_wake_queue(dev); +} + +/* + * This sets the internal hardware table to filter out unwanted multicast + * packets before they take up memory. + * + * The SMC chip uses a hash table where the high 6 bits of the CRC of + * address are the offset into the table. If that bit is 1, then the + * multicast packet is accepted. Otherwise, it's dropped silently. + * + * To use the 6 bits as an offset into the table, the high 3 bits are the + * number of the 8 bit register, while the low 3 bits are the bit within + * that register. + * + * This routine is based very heavily on the one provided by Peter Cammaert. + */ +static void +smc_setmulticast(unsigned long ioaddr, int count, struct dev_mc_list *addrs) +{ + int i; + unsigned char multicast_table[8]; + struct dev_mc_list *cur_addr; + + /* table for flipping the order of 3 bits */ + static unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + + /* start with a table of all zeros: reject all */ + memset(multicast_table, 0, sizeof(multicast_table)); + + cur_addr = addrs; + for (i = 0; i < count; i++, cur_addr = cur_addr->next) { + int position; + + /* do we have a pointer here? */ + if (!cur_addr) + break; + /* make sure this is a multicast address - shouldn't this + be a given if we have it here ? */ + if (!(*cur_addr->dmi_addr & 1)) + continue; + + /* only use the low order bits */ + position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f; + + /* do some messy swapping to put the bit in the right spot */ + multicast_table[invert3[position&7]] |= + (1<>3)&7]); + + } + /* now, the table can be loaded into the chipset */ + SMC_SELECT_BANK(3); + SMC_SET_MCAST(multicast_table); +} + +/* + * This routine will, depending on the values passed to it, + * either make it accept multicast packets, go into + * promiscuous mode (for TCPDUMP and cousins) or accept + * a select set of multicast packets + */ +static void smc_set_multicast_list(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + SMC_SELECT_BANK(0); + if (dev->flags & IFF_PROMISC) { + DBG(2, "%s: RCR_PRMS\n", dev->name); + lp->rcr_cur_mode |= RCR_PRMS; + SMC_SET_RCR(lp->rcr_cur_mode); + } + +/* BUG? I never disable promiscuous mode if multicasting was turned on. + Now, I turn off promiscuous mode, but I don't do anything to multicasting + when promiscuous mode is turned on. +*/ + + /* + * Here, I am setting this to accept all multicast packets. + * I don't need to zero the multicast table, because the flag is + * checked before the table is + */ + else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) { + lp->rcr_cur_mode |= RCR_ALMUL; + SMC_SET_RCR(lp->rcr_cur_mode); + DBG(2, "%s: RCR_ALMUL\n", dev->name); + } + + /* + * We just get all multicast packets even if we only want them + * from one source. This will be changed at some future point. + */ + else if (dev->mc_count) { + /* support hardware multicasting */ + + /* be sure I get rid of flags I might have set */ + lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); + SMC_SET_RCR(lp->rcr_cur_mode); + /* + * NOTE: this has to set the bank, so make sure it is the + * last thing called. The bank is set to zero at the top + */ + smc_setmulticast(ioaddr, dev->mc_count, dev->mc_list); + } else { + DBG(2, "%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name); + lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); + SMC_SET_RCR(lp->rcr_cur_mode); + + /* + * since I'm disabling all multicast entirely, I need to + * clear the multicast list + */ + SMC_SELECT_BANK(3); + SMC_CLEAR_MCAST(); + } +} + + +/* + * Open and Initialize the board + * + * Set up everything, reset the card, etc.. + */ +static int +smc_open(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + /* + * Check that the address is valid. If its not, refuse + * to bring the device up. The user must specify an + * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx + */ + if (!is_valid_ether_addr(dev->dev_addr)) { + DBG(2, (KERN_DEBUG "smc_open: no valid ethernet hw addr\n")); + return -EINVAL; + } + + /* clear out all the junk that was put here before... */ + lp->saved_skb = NULL; + + /* Setup the default Register Modes */ + lp->tcr_cur_mode = TCR_DEFAULT; + lp->rcr_cur_mode = RCR_DEFAULT; + lp->rpc_cur_mode = RPC_DEFAULT; + + /* + * If we are not using a MII interface, we need to + * monitor our own carrier signal to detect faults. + */ + if (lp->phy_type == 0) + lp->tcr_cur_mode |= TCR_MON_CSN; + + /* reset the hardware */ + smc_reset(dev); + smc_enable(dev); + + SMC_SELECT_BANK(1); + SMC_SET_MAC_ADDR(dev->dev_addr); + + /* Configure the PHY */ + if (lp->phy_type != 0) + smc_phy_configure(dev); + else { + spin_lock_irq(&lp->lock); + smc_10bt_check_media(dev, 1); + spin_unlock_irq(&lp->lock); + } + + /* + * make sure to initialize the link state with netif_carrier_off() + * somewhere, too --jgarzik + * + * smc_phy_configure() and smc_10bt_check_media() does that. --rmk + */ + netif_start_queue(dev); + return 0; +} + +/* + * smc_close + * + * this makes the board clean up everything that it can + * and not talk to the outside world. Caused by + * an 'ifconfig ethX down' + */ +static int smc_close(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + netif_stop_queue(dev); + netif_carrier_off(dev); + + /* clear everything */ + smc_shutdown(dev->base_addr); + + if (lp->phy_type != 0) + smc_phy_powerdown(dev, lp->mii.phy_id); + + return 0; +} + +/* + * Get the current statistics. + * This may be called with the card open or closed. + */ +static struct net_device_stats *smc_query_statistics(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + + DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + + return &lp->stats; +} + +/* + * Ethtool support + */ +static int +smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct smc_local *lp = netdev_priv(dev); + int ret; + + cmd->maxtxpkt = 1; + cmd->maxrxpkt = 1; + + if (lp->phy_type != 0) { + spin_lock_irq(&lp->lock); + ret = mii_ethtool_gset(&lp->mii, cmd); + spin_unlock_irq(&lp->lock); + } else { + cmd->supported = SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_TP | SUPPORTED_AUI; + + if (lp->ctl_rspeed == 10) + cmd->speed = SPEED_10; + else if (lp->ctl_rspeed == 100) + cmd->speed = SPEED_100; + + cmd->autoneg = AUTONEG_DISABLE; + cmd->transceiver = XCVR_INTERNAL; + cmd->port = 0; + cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF; + + ret = 0; + } + + return ret; +} + +static int +smc_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct smc_local *lp = netdev_priv(dev); + int ret; + + if (lp->phy_type != 0) { + spin_lock_irq(&lp->lock); + ret = mii_ethtool_sset(&lp->mii, cmd); + spin_unlock_irq(&lp->lock); + } else { + if (cmd->autoneg != AUTONEG_DISABLE || + cmd->speed != SPEED_10 || + (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) || + (cmd->port != PORT_TP && cmd->port != PORT_AUI)) + return -EINVAL; + +// lp->port = cmd->port; + lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL; + +// if (netif_running(dev)) +// smc_set_port(dev); + + ret = 0; + } + + return ret; +} + +static void +smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + strncpy(info->driver, CARDNAME, sizeof(info->driver)); + strncpy(info->version, version, sizeof(info->version)); + strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info)); +} + +static int smc_ethtool_nwayreset(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + int ret = -EINVAL; + + if (lp->phy_type != 0) { + spin_lock_irq(&lp->lock); + ret = mii_nway_restart(&lp->mii); + spin_unlock_irq(&lp->lock); + } + + return ret; +} + +static u32 smc_ethtool_getmsglevel(struct net_device *dev) +{ + struct smc_local *lp = netdev_priv(dev); + return lp->msg_enable; +} + +static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level) +{ + struct smc_local *lp = netdev_priv(dev); + lp->msg_enable = level; +} + +static struct ethtool_ops smc_ethtool_ops = { + .get_settings = smc_ethtool_getsettings, + .set_settings = smc_ethtool_setsettings, + .get_drvinfo = smc_ethtool_getdrvinfo, + + .get_msglevel = smc_ethtool_getmsglevel, + .set_msglevel = smc_ethtool_setmsglevel, + .nway_reset = smc_ethtool_nwayreset, + .get_link = ethtool_op_get_link, +// .get_eeprom = smc_ethtool_geteeprom, +// .set_eeprom = smc_ethtool_seteeprom, +}; + +/* + * smc_findirq + * + * This routine has a simple purpose -- make the SMC chip generate an + * interrupt, so an auto-detect routine can detect it, and find the IRQ, + */ +/* + * does this still work? + * + * I just deleted auto_irq.c, since it was never built... + * --jgarzik + */ +static int __init smc_findirq(unsigned long ioaddr) +{ + int timeout = 20; + unsigned long cookie; + + DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); + + cookie = probe_irq_on(); + + /* + * What I try to do here is trigger an ALLOC_INT. This is done + * by allocating a small chunk of memory, which will give an interrupt + * when done. + */ + /* enable ALLOCation interrupts ONLY */ + SMC_SELECT_BANK(2); + SMC_SET_INT_MASK(IM_ALLOC_INT); + + /* + * Allocate 512 bytes of memory. Note that the chip was just + * reset so all the memory is available + */ + SMC_SET_MMU_CMD(MC_ALLOC | 1); + + /* + * Wait until positive that the interrupt has been generated + */ + do { + int int_status; + udelay(10); + int_status = SMC_GET_INT(); + if (int_status & IM_ALLOC_INT) + break; /* got the interrupt */ + } while (--timeout); + + /* + * there is really nothing that I can do here if timeout fails, + * as autoirq_report will return a 0 anyway, which is what I + * want in this case. Plus, the clean up is needed in both + * cases. + */ + + /* and disable all interrupts again */ + SMC_SET_INT_MASK(0); + + /* and return what I found */ + return probe_irq_off(cookie); +} + +/* + * Function: smc_probe(unsigned long ioaddr) + * + * Purpose: + * Tests to see if a given ioaddr points to an SMC91x chip. + * Returns a 0 on success + * + * Algorithm: + * (1) see if the high byte of BANK_SELECT is 0x33 + * (2) compare the ioaddr with the base register's address + * (3) see if I recognize the chip ID in the appropriate register + * + * Here I do typical initialization tasks. + * + * o Initialize the structure if needed + * o print out my vanity message if not done so already + * o print out what type of hardware is detected + * o print out the ethernet address + * o find the IRQ + * o set up my private data + * o configure the dev structure with my subroutines + * o actually GRAB the irq. + * o GRAB the region + */ +static int __init smc_probe(struct net_device *dev, unsigned long ioaddr) +{ + struct smc_local *lp = netdev_priv(dev); + static int version_printed = 0; + int i, retval; + unsigned int val, revision_register; + const char *version_string; + + DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); + + /* First, see if the high byte is 0x33 */ + val = SMC_CURRENT_BANK(); + DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val); + if ((val & 0xFF00) != 0x3300) { + if ((val & 0xFF) == 0x33) { + printk(KERN_WARNING + "%s: Detected possible byte-swapped interface" + " at IOADDR 0x%lx\n", CARDNAME, ioaddr); + } + retval = -ENODEV; + goto err_out; + } + + /* + * The above MIGHT indicate a device, but I need to write to + * further test this. + */ + SMC_SELECT_BANK(0); + val = SMC_CURRENT_BANK(); + if ((val & 0xFF00) != 0x3300) { + retval = -ENODEV; + goto err_out; + } + + /* + * well, we've already written once, so hopefully another + * time won't hurt. This time, I need to switch the bank + * register to bank 1, so I can access the base address + * register + */ + SMC_SELECT_BANK(1); + val = SMC_GET_BASE(); + val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; + if ((ioaddr & ((PAGE_SIZE-1)<> 4) & 0xF]; + if (!version_string || (revision_register & 0xff00) != 0x3300) { + /* I don't recognize this chip, so... */ + printk("%s: IO 0x%lx: Unrecognized revision register 0x%04x" + ", Contact author.\n", CARDNAME, + ioaddr, revision_register); + + retval = -ENODEV; + goto err_out; + } + + /* At this point I'll assume that the chip is an SMC91x. */ + if (version_printed++ == 0) + printk("%s", version); + + /* fill in some of the fields */ + dev->base_addr = ioaddr; + lp->version = revision_register & 0xff; + + /* Get the MAC address */ + SMC_SELECT_BANK(1); + SMC_GET_MAC_ADDR(dev->dev_addr); + + /* now, reset the chip, and put it into a known state */ + smc_reset(dev); + + /* + * If dev->irq is 0, then the device has to be banged on to see + * what the IRQ is. + * + * This banging doesn't always detect the IRQ, for unknown reasons. + * a workaround is to reset the chip and try again. + * + * Interestingly, the DOS packet driver *SETS* the IRQ on the card to + * be what is requested on the command line. I don't do that, mostly + * because the card that I have uses a non-standard method of accessing + * the IRQs, and because this _should_ work in most configurations. + * + * Specifying an IRQ is done with the assumption that the user knows + * what (s)he is doing. No checking is done!!!! + */ + if (dev->irq < 1) { + int trials; + + trials = 3; + while (trials--) { + dev->irq = smc_findirq(ioaddr); + if (dev->irq) + break; + /* kick the card and try again */ + smc_reset(dev); + } + } + if (dev->irq == 0) { + printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n", + dev->name); + retval = -ENODEV; + goto err_out; + } + dev->irq = irq_canonicalize(dev->irq); + + /* Fill in the fields of the device structure with ethernet values. */ + ether_setup(dev); + + dev->open = smc_open; + dev->stop = smc_close; + dev->hard_start_xmit = smc_hard_start_xmit; + dev->tx_timeout = smc_timeout; + dev->watchdog_timeo = msecs_to_jiffies(watchdog); + dev->get_stats = smc_query_statistics; + dev->set_multicast_list = smc_set_multicast_list; + dev->ethtool_ops = &smc_ethtool_ops; + + spin_lock_init(&lp->lock); + lp->mii.phy_id_mask = 0x1f; + lp->mii.reg_num_mask = 0x1f; + lp->mii.force_media = 0; + lp->mii.full_duplex = 0; + lp->mii.dev = dev; + lp->mii.mdio_read = smc_phy_read; + lp->mii.mdio_write = smc_phy_write; + + /* + * Locate the phy, if any. + */ + if (lp->version >= (CHIP_91100 << 4)) + smc_detect_phy(dev); + + /* Set default parameters */ + lp->msg_enable = NETIF_MSG_LINK; + lp->ctl_rfduplx = 0; + lp->ctl_rspeed = 10; + + if (lp->version >= (CHIP_91100 << 4)) { + lp->ctl_rfduplx = 1; + lp->ctl_rspeed = 100; + } + + /* Grab the IRQ */ + retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev); + if (retval) + goto err_out; + + set_irq_type(dev->irq, IRQT_RISING); +#ifdef SMC_USE_PXA_DMA + { + int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, + smc_pxa_dma_irq, NULL); + if (dma >= 0) + dev->dma = dma; + } +#endif + + retval = register_netdev(dev); + if (retval == 0) { + /* now, print out the card info, in a short format.. */ + printk("%s: %s (rev %d) at %#lx IRQ %d", + dev->name, version_string, revision_register & 0x0f, + dev->base_addr, dev->irq); + + if (dev->dma != (unsigned char)-1) + printk(" DMA %d", dev->dma); + + printk("%s%s\n", nowait ? " [nowait]" : "", + THROTTLE_TX_PKTS ? " [throttle_tx]" : ""); + + if (!is_valid_ether_addr(dev->dev_addr)) { + printk("%s: Invalid ethernet MAC address. Please " + "set using ifconfig\n", dev->name); + } else { + /* Print the Ethernet address */ + printk("%s: Ethernet addr: ", dev->name); + for (i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x\n", dev->dev_addr[5]); + } + + if (lp->phy_type == 0) { + PRINTK("%s: No PHY found\n", dev->name); + } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) { + PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name); + } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) { + PRINTK("%s: PHY LAN83C180\n", dev->name); + } + } + +err_out: +#ifdef SMC_USE_PXA_DMA + if (retval && dev->dma != (unsigned char)-1) + pxa_free_dma(dev->dma); +#endif + return retval; +} + +static int smc_enable_device(unsigned long attrib_phys) +{ + unsigned long flags; + unsigned char ecor, ecsr; + void *addr; + + /* + * Map the attribute space. This is overkill, but clean. + */ + addr = ioremap(attrib_phys, ATTRIB_SIZE); + if (!addr) + return -ENOMEM; + + /* + * Reset the device. We must disable IRQs around this + * since a reset causes the IRQ line become active. + */ + local_irq_save(flags); + ecor = readb(addr + (ECOR << SMC_IO_SHIFT)) & ~ECOR_RESET; + writeb(ecor | ECOR_RESET, addr + (ECOR << SMC_IO_SHIFT)); + readb(addr + (ECOR << SMC_IO_SHIFT)); + + /* + * Wait 100us for the chip to reset. + */ + udelay(100); + + /* + * The device will ignore all writes to the enable bit while + * reset is asserted, even if the reset bit is cleared in the + * same write. Must clear reset first, then enable the device. + */ + writeb(ecor, addr + (ECOR << SMC_IO_SHIFT)); + writeb(ecor | ECOR_ENABLE, addr + (ECOR << SMC_IO_SHIFT)); + + /* + * Set the appropriate byte/word mode. + */ + ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; +#ifndef SMC_CAN_USE_16BIT + ecsr |= ECSR_IOIS8; +#endif + writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); + local_irq_restore(flags); + + iounmap(addr); + + /* + * Wait for the chip to wake up. We could poll the control + * register in the main register space, but that isn't mapped + * yet. We know this is going to take 750us. + */ + msleep(1); + + return 0; +} + +/* + * smc_init(void) + * Input parameters: + * dev->base_addr == 0, try to find all possible locations + * dev->base_addr > 0x1ff, this is the address to check + * dev->base_addr == , return failure code + * + * Output: + * 0 --> there is a device + * anything else, error + */ +static int smc_drv_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev; + struct resource *res, *ext = NULL; + unsigned int *addr; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto out; + } + + /* + * Request the regions. + */ + if (!request_mem_region(res->start, SMC_IO_EXTENT, "smc91x")) { + ret = -EBUSY; + goto out; + } + + ndev = alloc_etherdev(sizeof(struct smc_local)); + if (!ndev) { + printk("%s: could not allocate device.\n", CARDNAME); + ret = -ENOMEM; + goto release_1; + } + SET_MODULE_OWNER(ndev); + SET_NETDEV_DEV(ndev, dev); + + ndev->dma = (unsigned char)-1; + ndev->irq = platform_get_irq(pdev, 0); + + ext = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (ext) { + if (!request_mem_region(ext->start, ATTRIB_SIZE, ndev->name)) { + ret = -EBUSY; + goto release_1; + } + +#if defined(CONFIG_SA1100_ASSABET) + NCR_0 |= NCR_ENET_OSC_EN; +#endif + + ret = smc_enable_device(ext->start); + if (ret) + goto release_both; + } + + addr = ioremap(res->start, SMC_IO_EXTENT); + if (!addr) { + ret = -ENOMEM; + goto release_both; + } + + dev_set_drvdata(dev, ndev); + ret = smc_probe(ndev, (unsigned long)addr); + if (ret != 0) { + dev_set_drvdata(dev, NULL); + iounmap(addr); + release_both: + if (ext) + release_mem_region(ext->start, ATTRIB_SIZE); + free_netdev(ndev); + release_1: + release_mem_region(res->start, SMC_IO_EXTENT); + out: + printk("%s: not found (%d).\n", CARDNAME, ret); + } +#ifdef SMC_USE_PXA_DMA + else { + struct smc_local *lp = netdev_priv(ndev); + lp->physaddr = res->start; + } +#endif + + return ret; +} + +static int smc_drv_remove(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev = dev_get_drvdata(dev); + struct resource *res; + + dev_set_drvdata(dev, NULL); + + unregister_netdev(ndev); + + free_irq(ndev->irq, ndev); + +#ifdef SMC_USE_PXA_DMA + if (ndev->dma != (unsigned char)-1) + pxa_free_dma(ndev->dma); +#endif + iounmap((void *)ndev->base_addr); + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res) + release_mem_region(res->start, ATTRIB_SIZE); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, SMC_IO_EXTENT); + + free_netdev(ndev); + + return 0; +} + +static int smc_drv_suspend(struct device *dev, u32 state, u32 level) +{ + struct net_device *ndev = dev_get_drvdata(dev); + + if (ndev && level == SUSPEND_DISABLE) { + if (netif_running(ndev)) { + netif_device_detach(ndev); + smc_shutdown(ndev->base_addr); + } + } + return 0; +} + +static int smc_drv_resume(struct device *dev, u32 level) +{ + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev = dev_get_drvdata(dev); + + if (ndev && level == RESUME_ENABLE) { + struct smc_local *lp = netdev_priv(ndev); + unsigned long ioaddr = ndev->base_addr; + + if (pdev->num_resources == 3) + smc_enable_device(pdev->resource[2].start); + if (netif_running(ndev)) { + smc_reset(ndev); + smc_enable(ndev); + SMC_SELECT_BANK(1); + SMC_SET_MAC_ADDR(ndev->dev_addr); + if (lp->phy_type != 0) + smc_phy_configure(ndev); + netif_device_attach(ndev); + } + } + return 0; +} + +static struct device_driver smc_driver = { + .name = CARDNAME, + .bus = &platform_bus_type, + .probe = smc_drv_probe, + .remove = smc_drv_remove, + .suspend = smc_drv_suspend, + .resume = smc_drv_resume, +}; + +static int __init smc_init(void) +{ +#ifdef MODULE + if (io == -1) + printk(KERN_WARNING + "%s: You shouldn't use auto-probing with insmod!\n", + CARDNAME); +#endif + + return driver_register(&smc_driver); +} + +static void __exit smc_cleanup(void) +{ + driver_unregister(&smc_driver); +} + +module_init(smc_init); +module_exit(smc_cleanup); diff -Nru a/drivers/net/arm/smc91x.h b/drivers/net/arm/smc91x.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/net/arm/smc91x.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,829 @@ +/*------------------------------------------------------------------------ + . smc91x.h - macros for SMSC's 91C9x/91C1xx single-chip Ethernet device. + . + . Copyright (C) 1996 by Erik Stahlman + . Copyright (C) 2001 Standard Microsystems Corporation + . Developed by Simple Network Magic Corporation + . Copyright (C) 2003 Monta Vista Software, Inc. + . Unified SMC91x driver by Nicolas Pitre + . + . This program is free software; you can redistribute it and/or modify + . it under the terms of the GNU General Public License as published by + . the Free Software Foundation; either version 2 of the License, or + . (at your option) any later version. + . + . This program is distributed in the hope that it will be useful, + . but WITHOUT ANY WARRANTY; without even the implied warranty of + . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + . GNU General Public License for more details. + . + . You should have received a copy of the GNU General Public License + . along with this program; if not, write to the Free Software + . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + . + . Information contained in this file was obtained from the LAN91C111 + . manual from SMC. To get a copy, if you really want one, you can find + . information under www.smsc.com. + . + . Authors + . Erik Stahlman + . Daris A Nevil + . Nicolas Pitre + . + ---------------------------------------------------------------------------*/ +#ifndef _SMC91X_H_ +#define _SMC91X_H_ + + +/* + * Define your architecture specific bus configuration parameters here. + */ + +#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || \ + defined(CONFIG_SA1100_PFS168) || \ + defined(CONFIG_SA1100_FLEXANET) || \ + defined(CONFIG_SA1100_GRAPHICSMASTER) || \ + defined(CONFIG_ARCH_LUBBOCK) + +/* We can only do 16-bit reads and writes in the static memory space. */ +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_NOWAIT 1 + +/* The first two address lines aren't connected... */ +#define SMC_IO_SHIFT 2 + +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) + +#elif defined(CONFIG_SA1100_ASSABET) + +#include + +/* We can only do 8-bit reads and writes in the static memory space. */ +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 0 +#define SMC_CAN_USE_32BIT 0 +#define SMC_NOWAIT 1 + +/* The first two address lines aren't connected... */ +#define SMC_IO_SHIFT 2 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) +#define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) + +#elif defined(CONFIG_ARCH_INNOKOM) || \ + defined(CONFIG_MACH_MAINSTONE) || \ + defined(CONFIG_ARCH_PXA_IDP) || \ + defined(CONFIG_ARCH_RAMSES) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_IO_SHIFT 0 +#define SMC_NOWAIT 1 +#define SMC_USE_PXA_DMA 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +/* We actually can't write halfwords properly if not word aligned */ +static inline void +SMC_outw(u16 val, unsigned long ioaddr, int reg) +{ + if (reg & 2) { + unsigned int v = val << 16; + v |= readl(ioaddr + (reg & ~2)) & 0xffff; + writel(v, ioaddr + (reg & ~2)); + } else { + writew(val, ioaddr + reg); + } +} + +#elif defined(CONFIG_ISA) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 + +#define SMC_inb(a, r) inb((a) + (r)) +#define SMC_inw(a, r) inw((a) + (r)) +#define SMC_outb(v, a, r) outb(v, (a) + (r)) +#define SMC_outw(v, a, r) outw(v, (a) + (r)) +#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) + +#else + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define RPC_LSA_DEFAULT RPC_LED_100_10 +#define RPC_LSB_DEFAULT RPC_LED_TX_RX + +#endif + + +#ifdef SMC_USE_PXA_DMA +/* + * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is + * always happening in irq context so no need to worry about races. TX is + * different and probably not worth it for that reason, and not as critical + * as RX which can overrun memory and lose packets. + */ +#include +#include + +#ifdef SMC_insl +#undef SMC_insl +#define SMC_insl(a, r, p, l) \ + smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l) +static inline void +smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma, + u_char *buf, int len) +{ + dma_addr_t dmabuf; + + /* fallback if no DMA available */ + if (dma == (unsigned char)-1) { + readsl(ioaddr + reg, buf, len); + return; + } + + /* 64 bit alignment is required for memory to memory DMA */ + if ((long)buf & 4) { + *((u32 *)buf)++ = SMC_inl(ioaddr, reg); + len--; + } + + len *= 4; + dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE); + DCSR(dma) = DCSR_NODESC; + DTADR(dma) = dmabuf; + DSADR(dma) = physaddr + reg; + DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | + DCMD_WIDTH4 | (DCMD_LENGTH & len)); + DCSR(dma) = DCSR_NODESC | DCSR_RUN; + while (!(DCSR(dma) & DCSR_STOPSTATE)); + DCSR(dma) = 0; + dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE); +} +#endif + +#ifdef SMC_insw +#undef SMC_insw +#define SMC_insw(a, r, p, l) \ + smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l) +static inline void +smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma, + u_char *buf, int len) +{ + dma_addr_t dmabuf; + + /* fallback if no DMA available */ + if (dma == (unsigned char)-1) { + readsw(ioaddr + reg, buf, len); + return; + } + + /* 64 bit alignment is required for memory to memory DMA */ + while ((long)buf & 6) { + *((u16 *)buf)++ = SMC_inw(ioaddr, reg); + len--; + } + + len *= 2; + dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE); + DCSR(dma) = DCSR_NODESC; + DTADR(dma) = dmabuf; + DSADR(dma) = physaddr + reg; + DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | + DCMD_WIDTH2 | (DCMD_LENGTH & len)); + DCSR(dma) = DCSR_NODESC | DCSR_RUN; + while (!(DCSR(dma) & DCSR_STOPSTATE)); + DCSR(dma) = 0; + dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE); +} +#endif + +static void +smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs) +{ + DCSR(dma) = 0; +} +#endif /* SMC_USE_PXA_DMA */ + + +/* Because of bank switching, the LAN91x uses only 16 I/O ports */ +#ifndef SMC_IO_SHIFT +#define SMC_IO_SHIFT 0 +#endif +#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) + + +/* + . Bank Select Register: + . + . yyyy yyyy 0000 00xx + . xx = bank number + . yyyy yyyy = 0x33, for identification purposes. +*/ +#define BANK_SELECT (14 << SMC_IO_SHIFT) + + +// Transmit Control Register +/* BANK 0 */ +#define TCR_REG SMC_REG(0x0000, 0) +#define TCR_ENABLE 0x0001 // When 1 we can transmit +#define TCR_LOOP 0x0002 // Controls output pin LBK +#define TCR_FORCOL 0x0004 // When 1 will force a collision +#define TCR_PAD_EN 0x0080 // When 1 will pad tx frames < 64 bytes w/0 +#define TCR_NOCRC 0x0100 // When 1 will not append CRC to tx frames +#define TCR_MON_CSN 0x0400 // When 1 tx monitors carrier +#define TCR_FDUPLX 0x0800 // When 1 enables full duplex operation +#define TCR_STP_SQET 0x1000 // When 1 stops tx if Signal Quality Error +#define TCR_EPH_LOOP 0x2000 // When 1 enables EPH block loopback +#define TCR_SWFDUP 0x8000 // When 1 enables Switched Full Duplex mode + +#define TCR_CLEAR 0 /* do NOTHING */ +/* the default settings for the TCR register : */ +#define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN) + + +// EPH Status Register +/* BANK 0 */ +#define EPH_STATUS_REG SMC_REG(0x0002, 0) +#define ES_TX_SUC 0x0001 // Last TX was successful +#define ES_SNGL_COL 0x0002 // Single collision detected for last tx +#define ES_MUL_COL 0x0004 // Multiple collisions detected for last tx +#define ES_LTX_MULT 0x0008 // Last tx was a multicast +#define ES_16COL 0x0010 // 16 Collisions Reached +#define ES_SQET 0x0020 // Signal Quality Error Test +#define ES_LTXBRD 0x0040 // Last tx was a broadcast +#define ES_TXDEFR 0x0080 // Transmit Deferred +#define ES_LATCOL 0x0200 // Late collision detected on last tx +#define ES_LOSTCARR 0x0400 // Lost Carrier Sense +#define ES_EXC_DEF 0x0800 // Excessive Deferral +#define ES_CTR_ROL 0x1000 // Counter Roll Over indication +#define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin +#define ES_TXUNRN 0x8000 // Tx Underrun + + +// Receive Control Register +/* BANK 0 */ +#define RCR_REG SMC_REG(0x0004, 0) +#define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted +#define RCR_PRMS 0x0002 // Enable promiscuous mode +#define RCR_ALMUL 0x0004 // When set accepts all multicast frames +#define RCR_RXEN 0x0100 // IFF this is set, we can receive packets +#define RCR_STRIP_CRC 0x0200 // When set strips CRC from rx packets +#define RCR_ABORT_ENB 0x0200 // When set will abort rx on collision +#define RCR_FILT_CAR 0x0400 // When set filters leading 12 bit s of carrier +#define RCR_SOFTRST 0x8000 // resets the chip + +/* the normal settings for the RCR register : */ +#define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN) +#define RCR_CLEAR 0x0 // set it to a base state + + +// Counter Register +/* BANK 0 */ +#define COUNTER_REG SMC_REG(0x0006, 0) + + +// Memory Information Register +/* BANK 0 */ +#define MIR_REG SMC_REG(0x0008, 0) + + +// Receive/Phy Control Register +/* BANK 0 */ +#define RPC_REG SMC_REG(0x000A, 0) +#define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. +#define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode +#define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode +#define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb +#define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb +#define RPC_LED_100_10 (0x00) // LED = 100Mbps OR's with 10Mbps link detect +#define RPC_LED_RES (0x01) // LED = Reserved +#define RPC_LED_10 (0x02) // LED = 10Mbps link detect +#define RPC_LED_FD (0x03) // LED = Full Duplex Mode +#define RPC_LED_TX_RX (0x04) // LED = TX or RX packet occurred +#define RPC_LED_100 (0x05) // LED = 100Mbps link dectect +#define RPC_LED_TX (0x06) // LED = TX packet occurred +#define RPC_LED_RX (0x07) // LED = RX packet occurred + +#ifndef RPC_LSA_DEFAULT +#define RPC_LSA_DEFAULT RPC_LED_100 +#endif +#ifndef RPC_LSB_DEFAULT +#define RPC_LSB_DEFAULT RPC_LED_FD +#endif + +#define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX) + + +/* Bank 0 0x0C is reserved */ + +// Bank Select Register +/* All Banks */ +#define BSR_REG 0x000E + + +// Configuration Reg +/* BANK 1 */ +#define CONFIG_REG SMC_REG(0x0000, 1) +#define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy +#define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL +#define CONFIG_NO_WAIT 0x1000 // When 1 no extra wait states on ISA bus +#define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode. + +// Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low +#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN) + + +// Base Address Register +/* BANK 1 */ +#define BASE_REG SMC_REG(0x0002, 1) + + +// Individual Address Registers +/* BANK 1 */ +#define ADDR0_REG SMC_REG(0x0004, 1) +#define ADDR1_REG SMC_REG(0x0006, 1) +#define ADDR2_REG SMC_REG(0x0008, 1) + + +// General Purpose Register +/* BANK 1 */ +#define GP_REG SMC_REG(0x000A, 1) + + +// Control Register +/* BANK 1 */ +#define CTL_REG SMC_REG(0x000C, 1) +#define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received +#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically +#define CTL_LE_ENABLE 0x0080 // When 1 enables Link Error interrupt +#define CTL_CR_ENABLE 0x0040 // When 1 enables Counter Rollover interrupt +#define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt +#define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store +#define CTL_RELOAD 0x0002 // When set reads EEPROM into registers +#define CTL_STORE 0x0001 // When set stores registers into EEPROM + + +// MMU Command Register +/* BANK 2 */ +#define MMU_CMD_REG SMC_REG(0x0000, 2) +#define MC_BUSY 1 // When 1 the last release has not completed +#define MC_NOP (0<<5) // No Op +#define MC_ALLOC (1<<5) // OR with number of 256 byte packets +#define MC_RESET (2<<5) // Reset MMU to initial state +#define MC_REMOVE (3<<5) // Remove the current rx packet +#define MC_RELEASE (4<<5) // Remove and release the current rx packet +#define MC_FREEPKT (5<<5) // Release packet in PNR register +#define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit +#define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs + + +// Packet Number Register +/* BANK 2 */ +#define PN_REG SMC_REG(0x0002, 2) + + +// Allocation Result Register +/* BANK 2 */ +#define AR_REG SMC_REG(0x0003, 2) +#define AR_FAILED 0x80 // Alocation Failed + + +// TX FIFO Ports Register +/* BANK 2 */ +#define TXFIFO_REG SMC_REG(0x0004, 2) +#define TXFIFO_TEMPTY 0x80 // TX FIFO Empty + +// RX FIFO Ports Register +/* BANK 2 */ +#define RXFIFO_REG SMC_REG(0x0005, 2) +#define RXFIFO_REMPTY 0x80 // RX FIFO Empty + +#define FIFO_REG SMC_REG(0x0004, 2) + +// Pointer Register +/* BANK 2 */ +#define PTR_REG SMC_REG(0x0006, 2) +#define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area +#define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access +#define PTR_READ 0x2000 // When 1 the operation is a read + + +// Data Register +/* BANK 2 */ +#define DATA_REG SMC_REG(0x0008, 2) + + +// Interrupt Status/Acknowledge Register +/* BANK 2 */ +#define INT_REG SMC_REG(0x000C, 2) + + +// Interrupt Mask Register +/* BANK 2 */ +#define IM_REG SMC_REG(0x000D, 2) +#define IM_MDINT 0x80 // PHY MI Register 18 Interrupt +#define IM_ERCV_INT 0x40 // Early Receive Interrupt +#define IM_EPH_INT 0x20 // Set by Ethernet Protocol Handler section +#define IM_RX_OVRN_INT 0x10 // Set by Receiver Overruns +#define IM_ALLOC_INT 0x08 // Set when allocation request is completed +#define IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty +#define IM_TX_INT 0x02 // Transmit Interrupt +#define IM_RCV_INT 0x01 // Receive Interrupt + + +// Multicast Table Registers +/* BANK 3 */ +#define MCAST_REG1 SMC_REG(0x0000, 3) +#define MCAST_REG2 SMC_REG(0x0002, 3) +#define MCAST_REG3 SMC_REG(0x0004, 3) +#define MCAST_REG4 SMC_REG(0x0006, 3) + + +// Management Interface Register (MII) +/* BANK 3 */ +#define MII_REG SMC_REG(0x0008, 3) +#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup +#define MII_MDOE 0x0008 // MII Output Enable +#define MII_MCLK 0x0004 // MII Clock, pin MDCLK +#define MII_MDI 0x0002 // MII Input, pin MDI +#define MII_MDO 0x0001 // MII Output, pin MDO + + +// Revision Register +/* BANK 3 */ +/* ( hi: chip id low: rev # ) */ +#define REV_REG SMC_REG(0x000A, 3) + + +// Early RCV Register +/* BANK 3 */ +/* this is NOT on SMC9192 */ +#define ERCV_REG SMC_REG(0x000C, 3) +#define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received +#define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask + + +// External Register +/* BANK 7 */ +#define EXT_REG SMC_REG(0x0000, 7) + + +#define CHIP_9192 3 +#define CHIP_9194 4 +#define CHIP_9195 5 +#define CHIP_9196 6 +#define CHIP_91100 7 +#define CHIP_91100FD 8 +#define CHIP_91111FD 9 + +static const char * chip_ids[ 16 ] = { + NULL, NULL, NULL, + /* 3 */ "SMC91C90/91C92", + /* 4 */ "SMC91C94", + /* 5 */ "SMC91C95", + /* 6 */ "SMC91C96", + /* 7 */ "SMC91C100", + /* 8 */ "SMC91C100FD", + /* 9 */ "SMC91C11xFD", + NULL, NULL, NULL, + NULL, NULL, NULL}; + + +/* + . Transmit status bits +*/ +#define TS_SUCCESS 0x0001 +#define TS_LOSTCAR 0x0400 +#define TS_LATCOL 0x0200 +#define TS_16COL 0x0010 + +/* + . Receive status bits +*/ +#define RS_ALGNERR 0x8000 +#define RS_BRODCAST 0x4000 +#define RS_BADCRC 0x2000 +#define RS_ODDFRAME 0x1000 +#define RS_TOOLONG 0x0800 +#define RS_TOOSHORT 0x0400 +#define RS_MULTICAST 0x0001 +#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) + + +/* + * PHY IDs + * LAN83C183 == LAN91C111 Internal PHY + */ +#define PHY_LAN83C183 0x0016f840 +#define PHY_LAN83C180 0x02821c50 + +/* + * PHY Register Addresses (LAN91C111 Internal PHY) + * + * Generic PHY registers can be found in + * + * These phy registers are specific to our on-board phy. + */ + +// PHY Configuration Register 1 +#define PHY_CFG1_REG 0x10 +#define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled +#define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled +#define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down +#define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler +#define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable +#define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled +#define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm) +#define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db +#define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust +#define PHY_CFG1_TLVL_MASK 0x003C +#define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time + + +// PHY Configuration Register 2 +#define PHY_CFG2_REG 0x11 +#define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled +#define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled +#define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) +#define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo + +// PHY Status Output (and Interrupt status) Register +#define PHY_INT_REG 0x12 // Status Output (Interrupt Status) +#define PHY_INT_INT 0x8000 // 1=bits have changed since last read +#define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected +#define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync +#define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx +#define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx +#define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx +#define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected +#define PHY_INT_JAB 0x0100 // 1=Jabber detected +#define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode +#define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex + +// PHY Interrupt/Status Mask Register +#define PHY_MASK_REG 0x13 // Interrupt Mask +// Uses the same bit definitions as PHY_INT_REG + + +/* + * SMC91C96 ethernet config and status registers. + * These are in the "attribute" space. + */ +#define ECOR 0x8000 +#define ECOR_RESET 0x80 +#define ECOR_LEVEL_IRQ 0x40 +#define ECOR_WR_ATTRIB 0x04 +#define ECOR_ENABLE 0x01 + +#define ECSR 0x8002 +#define ECSR_IOIS8 0x20 +#define ECSR_PWRDWN 0x04 +#define ECSR_INT 0x02 + +#define ATTRIB_SIZE ((64*1024) << SMC_IO_SHIFT) + + +/* + * Macros to abstract register access according to the data bus + * capabilities. Please use those and not the in/out primitives. + * Note: the following macros do *not* select the bank -- this must + * be done separately as needed in the main code. The SMC_REG() macro + * only uses the bank argument for debugging purposes (when enabled). + */ + +#if SMC_DEBUG > 0 +#define SMC_REG(reg, bank) \ + ({ \ + int __b = SMC_CURRENT_BANK(); \ + if (unlikely((__b & ~0xf0) != (0x3300 | bank))) { \ + printk( "%s: bank reg screwed (0x%04x)\n", \ + CARDNAME, __b ); \ + BUG(); \ + } \ + reg<> 8) +#define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF) +#define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8) +#define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF) +#define SMC_ACK_INT(x) \ + do { \ + unsigned long __flags; \ + int __mask; \ + local_irq_save(__flags); \ + __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ + SMC_outw( __mask | (x), ioaddr, INT_REG ); \ + local_irq_restore(__flags); \ + } while (0) +#define SMC_GET_INT_MASK() (SMC_inw( ioaddr, INT_REG ) >> 8) +#define SMC_SET_INT_MASK(x) SMC_outw( (x) << 8, ioaddr, INT_REG ) +#endif + +#define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT ) +#define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT ) +#define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG ) +#define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG ) +#define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG ) +#define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG ) +#define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG ) +#define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG ) +#define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG ) +#define SMC_GET_MII() SMC_inw( ioaddr, MII_REG ) +#define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG ) +#define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG ) +#define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG ) +#define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG ) +#define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG ) +#define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG ) +#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG ) +#define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG ) +#define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG ) +#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG ) +#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG ) +#define SMC_GET_RPC() SMC_inw( ioaddr, RPC_REG ) +#define SMC_SET_RPC(x) SMC_outw( x, ioaddr, RPC_REG ) +#define SMC_GET_TCR() SMC_inw( ioaddr, TCR_REG ) +#define SMC_SET_TCR(x) SMC_outw( x, ioaddr, TCR_REG ) + +#ifndef SMC_GET_MAC_ADDR +#define SMC_GET_MAC_ADDR(addr) \ + do { \ + unsigned int __v; \ + __v = SMC_inw( ioaddr, ADDR0_REG ); \ + addr[0] = __v; addr[1] = __v >> 8; \ + __v = SMC_inw( ioaddr, ADDR1_REG ); \ + addr[2] = __v; addr[3] = __v >> 8; \ + __v = SMC_inw( ioaddr, ADDR2_REG ); \ + addr[4] = __v; addr[5] = __v >> 8; \ + } while (0) +#endif + +#define SMC_SET_MAC_ADDR(addr) \ + do { \ + SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG ); \ + SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG ); \ + SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG ); \ + } while (0) + +#define SMC_CLEAR_MCAST() \ + do { \ + SMC_outw( 0, ioaddr, MCAST_REG1 ); \ + SMC_outw( 0, ioaddr, MCAST_REG2 ); \ + SMC_outw( 0, ioaddr, MCAST_REG3 ); \ + SMC_outw( 0, ioaddr, MCAST_REG4 ); \ + } while (0) +#define SMC_SET_MCAST(x) \ + do { \ + unsigned char *mt = (x); \ + SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 ); \ + SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 ); \ + SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 ); \ + SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ + } while (0) + +#if SMC_CAN_USE_32BIT +/* + * Some setups just can't write 8 or 16 bits reliably when not aligned + * to a 32 bit boundary. I tell you that exists! + * We re-do the ones here that can be easily worked around if they can have + * their low parts written to 0 without adverse effects. + */ +#undef SMC_SELECT_BANK +#define SMC_SELECT_BANK(x) SMC_outl( (x)<<16, ioaddr, 12<> 16; \ + } while (0) +#else +#define SMC_PUT_PKT_HDR(status, length) \ + do { \ + SMC_outw( status, ioaddr, DATA_REG ); \ + SMC_outw( length, ioaddr, DATA_REG ); \ + } while (0) +#define SMC_GET_PKT_HDR(status, length) \ + do { \ + (status) = SMC_inw( ioaddr, DATA_REG ); \ + (length) = SMC_inw( ioaddr, DATA_REG ); \ + } while (0) +#endif + +#if SMC_CAN_USE_32BIT +#define SMC_PUSH_DATA(p, l) \ + do { \ + char *__ptr = (p); \ + int __len = (l); \ + if (__len >= 2 && (long)__ptr & 2) { \ + __len -= 2; \ + SMC_outw( *((u16 *)__ptr)++, ioaddr, DATA_REG );\ + } \ + SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2); \ + if (__len & 2) { \ + __ptr += (__len & ~3); \ + SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ + } \ + } while (0) +#define SMC_PULL_DATA(p, l) \ + do { \ + char *__ptr = (p); \ + int __len = (l); \ + if ((long)__ptr & 2) { \ + /* \ + * We want 32bit alignment here. \ + * Since some buses perform a full 32bit \ + * fetch even for 16bit data we can't use \ + * SMC_inw() here. Back both source (on chip \ + * and destination) pointers of 2 bytes. \ + */ \ + (long)__ptr &= ~2; \ + __len += 2; \ + SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ + } \ + __len += 2; \ + SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \ + } while (0) +#elif SMC_CAN_USE_16BIT +#define SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 ) +#define SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 ) +#elif SMC_CAN_USE_8BIT +#define SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l ) +#define SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l ) +#endif + +#if ! SMC_CAN_USE_16BIT +#define SMC_outw(x, ioaddr, reg) \ + do { \ + unsigned int __val16 = (x); \ + SMC_outb( __val16, ioaddr, reg ); \ + SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ + } while (0) +#define SMC_inw(ioaddr, reg) \ + ({ \ + unsigned int __val16; \ + __val16 = SMC_inb( ioaddr, reg ); \ + __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ + __val16; \ + }) +#endif + + +#endif /* _SMC91X_H_ */ diff -Nru a/drivers/net/at1700.c b/drivers/net/at1700.c --- a/drivers/net/at1700.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/at1700.c 2004-06-26 17:09:17 -07:00 @@ -65,6 +65,8 @@ static char version[] __initdata = "at1700.c:v1.15 4/7/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; +#define DRV_NAME "at1700" + /* Tunable parameters. */ /* When to switch from the 64-entry multicast filter to Rx-all-multicast. */ @@ -80,17 +82,10 @@ * ISA */ -#ifndef CONFIG_X86_PC9800 static unsigned at1700_probe_list[] __initdata = { 0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 }; -#else /* CONFIG_X86_PC9800 */ -static unsigned at1700_probe_list[] __initdata = { - 0x1d6, 0x1d8, 0x1da, 0x1d4, 0xd4, 0xd2, 0xd8, 0xd0, 0 -}; - -#endif /* CONFIG_X86_PC9800 */ /* * MCA */ @@ -133,7 +128,6 @@ /* Offsets from the base address. */ -#ifndef CONFIG_X86_PC9800 #define STATUS 0 #define TX_STATUS 0 #define RX_STATUS 1 @@ -161,34 +155,6 @@ #define RESET 31 /* Write to reset some parts of the chip. */ #define AT1700_IO_EXTENT 32 #define PORT_OFFSET(o) (o) -#else /* CONFIG_X86_PC9800 */ -#define STATUS (0x0000) -#define TX_STATUS (0x0000) -#define RX_STATUS (0x0001) -#define TX_INTR (0x0200)/* Bit-mapped interrupt enable registers. */ -#define RX_INTR (0x0201) -#define TX_MODE (0x0400) -#define RX_MODE (0x0401) -#define CONFIG_0 (0x0600)/* Misc. configuration settings. */ -#define CONFIG_1 (0x0601) -/* Run-time register bank 2 definitions. */ -#define DATAPORT (0x0800)/* Word-wide DMA or programmed-I/O dataport. */ -#define TX_START (0x0a00) -#define COL16CNTL (0x0a01)/* Controll Reg for 16 collisions */ -#define MODE13 (0x0c01) -#define RX_CTRL (0x0e00) -/* Configuration registers only on the '865A/B chips. */ -#define EEPROM_Ctrl (0x1000) -#define EEPROM_Data (0x1200) -#define CARDSTATUS 16 /* FMV-18x Card Status */ -#define CARDSTATUS1 17 /* FMV-18x Card Status */ -#define IOCONFIG (0x1400)/* Either read the jumper, or move the I/O. */ -#define IOCONFIG1 (0x1600) -#define SAPROM 20 /* The station address PROM, if no EEPROM. */ -#define MODE24 (0x1800)/* The station address PROM, if no EEPROM. */ -#define RESET (0x1e01)/* Write to reset some parts of the chip. */ -#define PORT_OFFSET(o) ({ int _o_ = (o); (_o_ & ~1) * 0x100 + (_o_ & 1); }) -#endif /* CONFIG_X86_PC9800 */ #define TX_TIMEOUT 10 @@ -230,11 +196,7 @@ (detachable devices only). */ -#ifndef CONFIG_X86_PC9800 static int io = 0x260; -#else -static int io = 0xd0; -#endif static int irq; @@ -246,15 +208,7 @@ mca_mark_as_unused(lp->mca_slot); #endif free_irq(dev->irq, NULL); -#ifndef CONFIG_X86_PC9800 release_region(dev->base_addr, AT1700_IO_EXTENT); -#else - { - int i; - for (i = 0; i < 0x2000; i += 0x200) - release_region(dev->base_addr + i, 2); - } -#endif } struct net_device * __init at1700_probe(int unit) @@ -321,20 +275,8 @@ int slot, ret = -ENODEV; struct net_local *lp = netdev_priv(dev); -#ifndef CONFIG_X86_PC9800 - if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME)) return -EBUSY; -#else - for (i = 0; i < 0x2000; i += 0x0200) { - if (!request_region(ioaddr + i, 2, dev->name)) { - while (i > 0) { - i -= 0x0200; - release_region(ioaddr + i, 2); - } - return -EBUSY; - } - } -#endif /* Resetting the chip doesn't reset the ISA interface, so don't bother. That means we have to be careful with the register values we probe @@ -425,15 +367,8 @@ outb(0, ioaddr + RESET); if (is_at1700) { -#ifndef CONFIG_X86_PC9800 irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04) | (read_eeprom(ioaddr, 0)>>14)]; -#else - { - char re1000plus_irqmap[4] = {3, 5, 6, 12}; - irq = re1000plus_irqmap[inb(ioaddr + IOCONFIG1) >> 6]; - } -#endif } else { /* Check PnP mode for FMV-183/184/183A/184A. */ /* This PnP routine is very poor. IO and IRQ should be known. */ @@ -517,11 +452,7 @@ /* Switch to bank 2 */ /* Lock our I/O address, and set manual processing mode for 16 collisions. */ outb(0x08, ioaddr + CONFIG_1); -#ifndef CONFIG_X86_PC9800 outb(dev->if_port, ioaddr + MODE13); -#else - outb(0, ioaddr + MODE13); -#endif outb(0x00, ioaddr + COL16CNTL); if (net_debug) @@ -542,7 +473,7 @@ lp->jumpered = is_fmv18x; lp->mca_slot = slot; /* Snarf the interrupt vector now. */ - ret = request_irq(irq, &net_interrupt, 0, dev->name, dev); + ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev); if (ret) { printk (" AT1700 at %#3x is unusable due to a conflict on" "IRQ %d.\n", ioaddr, irq); @@ -557,12 +488,7 @@ mca_mark_as_unused(slot); #endif err_out: -#ifndef CONFIG_X86_PC9800 release_region(ioaddr, AT1700_IO_EXTENT); -#else - for (i = 0; i < 0x2000; i += 0x0200) - release_region(ioaddr + i, 2); -#endif return ret; } @@ -573,13 +499,6 @@ #define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */ #define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */ -/* Delay between EEPROM clock transitions. */ -#ifndef CONFIG_X86_PC9800 -#define eeprom_delay() do { } while (0) -#else -#define eeprom_delay() __asm__ ("out%B0 %%al,%0" :: "N"(0x5f)) -#endif - /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD (5 << 6) #define EE_READ_CMD (6 << 6) @@ -598,22 +517,17 @@ short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outb(EE_CS, ee_addr); outb(dataval, ee_daddr); - eeprom_delay(); outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */ - eeprom_delay(); } outb(EE_DATA_WRITE, ee_daddr); for (i = 16; i > 0; i--) { outb(EE_CS, ee_addr); - eeprom_delay(); outb(EE_CS | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0); } /* Terminate the EEPROM access. */ outb(EE_CS, ee_addr); - eeprom_delay(); outb(EE_SHIFT_CLK, ee_addr); outb(0, ee_addr); return retval; diff -Nru a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c --- a/drivers/net/cs89x0.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/cs89x0.c 2004-06-26 17:09:20 -07:00 @@ -141,6 +141,8 @@ static char version[] __initdata = "cs89x0.c: v2.4.3-pre1 Russell Nelson , Andrew Morton \n"; +#define DRV_NAME "cs89x0" + /* First, a few definitions that the brave might change. A zero-terminated list of I/O addresses to be probed. Some special flags.. Addr & 1 = Read back the address port, look for signature and reset @@ -261,7 +263,6 @@ } __setup("cs89x0_media=", media_fn); -#endif /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -318,6 +319,7 @@ printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); return ERR_PTR(err); } +#endif static int readreg(struct net_device *dev, int portno) @@ -425,9 +427,9 @@ /* Grab the region so we can find another board if autoIRQ fails. */ /* WTF is going on here? */ - if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) { + if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) { printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n", - dev->name, ioaddr, NETCARD_IO_EXTENT); + DRV_NAME, ioaddr, NETCARD_IO_EXTENT); retval = -EBUSY; goto out1; } diff -Nru a/drivers/net/defxx.c b/drivers/net/defxx.c --- a/drivers/net/defxx.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/defxx.c 2004-06-26 17:09:15 -07:00 @@ -219,6 +219,8 @@ static char version[] __devinitdata = "defxx.c:v1.06 2003/08/04 Lawrence V. Stefani and others\n"; +#define DRV_NAME "defxx" + #define DYNAMIC_BUFFERS 1 #define SKBUFF_RX_COPYBREAK 200 @@ -435,9 +437,9 @@ bp = dev->priv; - if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, dev->name)) { + if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, DRV_NAME)) { printk (KERN_ERR "%s: Cannot reserve I/O resource 0x%x @ 0x%lx, aborting\n", - dev->name, PFI_K_CSR_IO_LEN, ioaddr); + DRV_NAME, PFI_K_CSR_IO_LEN, ioaddr); err = -EBUSY; goto err_out; } diff -Nru a/drivers/net/dgrs.h b/drivers/net/dgrs.h --- a/drivers/net/dgrs.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/dgrs.h 2004-06-26 17:09:16 -07:00 @@ -26,7 +26,7 @@ typedef struct dgrs_ioctl { unsigned short cmd; /* Command to run */ unsigned short len; /* Length of the data buffer */ - unsigned char *data; /* Pointer to the data buffer */ + unsigned char __user *data; /* Pointer to the data buffer */ unsigned short port; /* port number for command, if needed */ unsigned short filter; /* filter number for command, if needed */ } DGRS_IOCTL; diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h --- a/drivers/net/e1000/e1000.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/e1000/e1000.h 2004-06-26 17:09:15 -07:00 @@ -196,6 +196,7 @@ uint32_t part_num; uint32_t wol; uint32_t smartspeed; + uint32_t en_mng_pt; uint16_t link_speed; uint16_t link_duplex; spinlock_t stats_lock; diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c --- a/drivers/net/e1000/e1000_ethtool.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/e1000/e1000_ethtool.c 2004-06-26 17:09:17 -07:00 @@ -1004,11 +1004,12 @@ struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i); struct sk_buff *skb; - if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + 2, GFP_KERNEL))) { + if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, + GFP_KERNEL))) { ret_val = 6; goto err_nomem; } - skb_reserve(skb, 2); + skb_reserve(skb, NET_IP_ALIGN); rxdr->buffer_info[i].skb = skb; rxdr->buffer_info[i].length = E1000_RXBUFFER_2048; rxdr->buffer_info[i].dma = diff -Nru a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c --- a/drivers/net/e1000/e1000_hw.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/e1000/e1000_hw.c 2004-06-26 17:09:21 -07:00 @@ -265,6 +265,17 @@ return -E1000_ERR_MAC_TYPE; } + switch(hw->mac_type) { + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + hw->asf_firmware_present = TRUE; + break; + default: + break; + } + return E1000_SUCCESS; } @@ -5189,3 +5200,27 @@ return E1000_SUCCESS; } +/****************************************************************************** + * Verifies the hardware needs to allow ARPs to be processed by the host + * + * hw - Struct containing variables accessed by shared code + * + * returns: - TRUE/FALSE + * + *****************************************************************************/ +uint32_t +e1000_enable_mng_pass_thru(struct e1000_hw *hw) +{ + uint32_t manc; + + if (hw->asf_firmware_present) { + manc = E1000_READ_REG(hw, MANC); + + if (!(manc & E1000_MANC_RCV_TCO_EN) || + !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) + return FALSE; + if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) + return TRUE; + } + return FALSE; +} diff -Nru a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h --- a/drivers/net/e1000/e1000_hw.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/e1000/e1000_hw.h 2004-06-26 17:09:20 -07:00 @@ -307,6 +307,7 @@ /* Adaptive IFS Functions */ /* Everything else */ +uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw); void e1000_clear_hw_cntrs(struct e1000_hw *hw); void e1000_reset_adaptive(struct e1000_hw *hw); void e1000_update_adaptive(struct e1000_hw *hw); @@ -983,6 +984,7 @@ e1000_ms_type master_slave; e1000_ms_type original_master_slave; e1000_ffe_config ffe_config_state; + uint32_t asf_firmware_present; unsigned long io_base; uint32_t phy_id; uint32_t phy_revision; diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c --- a/drivers/net/e1000/e1000_main.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/e1000/e1000_main.c 2004-06-26 17:09:17 -07:00 @@ -299,7 +299,7 @@ void e1000_reset(struct e1000_adapter *adapter) { - uint32_t pba; + uint32_t pba, manc; /* Repartition Pba for greater than 9k mtu * To take effect CTRL.RST is required. */ @@ -341,6 +341,12 @@ e1000_reset_adaptive(&adapter->hw); e1000_phy_get_info(&adapter->hw, &adapter->phy_info); + + if(adapter->en_mng_pt) { + manc = E1000_READ_REG(&adapter->hw, MANC); + manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } } /** @@ -483,6 +489,8 @@ if(pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; + adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw); + /* before reading the EEPROM, reset the controller to * put the device in a known good starting state */ @@ -2367,7 +2375,6 @@ struct e1000_rx_desc *rx_desc; struct e1000_buffer *buffer_info; struct sk_buff *skb; - int reserve_len = 2; unsigned int i; i = rx_ring->next_to_use; @@ -2376,7 +2383,7 @@ while(!buffer_info->skb) { rx_desc = E1000_RX_DESC(*rx_ring, i); - skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len); + skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN); if(!skb) { /* Better luck next round */ @@ -2387,7 +2394,7 @@ * this will result in a 16 byte aligned IP header after * the 14 byte MAC header is removed */ - skb_reserve(skb, reserve_len); + skb_reserve(skb, NET_IP_ALIGN); skb->dev = netdev; diff -Nru a/drivers/net/e2100.c b/drivers/net/e2100.c --- a/drivers/net/e2100.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/e2100.c 2004-06-26 17:09:20 -07:00 @@ -51,6 +51,8 @@ #include "8390.h" +#define DRV_NAME "e2100" + static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0}; /* Offsets from the base_addr. @@ -144,6 +146,7 @@ release_region(dev->base_addr, E21_IO_EXTENT); } +#ifndef MODULE struct net_device * __init e2100_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -168,6 +171,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init e21_probe1(struct net_device *dev, int ioaddr) { @@ -175,7 +179,7 @@ unsigned char *station_addr = dev->dev_addr; static unsigned version_printed; - if (!request_region(ioaddr, E21_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME)) return -EBUSY; /* First check the station address for the Ctron prefix. */ diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c --- a/drivers/net/eepro.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/eepro.c 2004-06-26 17:09:19 -07:00 @@ -151,6 +151,8 @@ #include #include +#define DRV_NAME "eepro" + #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) ) /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */ #define SLOW_DOWN inb(0x80) @@ -577,6 +579,7 @@ return -ENODEV; } +#ifndef MODULE struct net_device * __init eepro_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct eepro_local)); @@ -603,6 +606,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static void __init printEEPROMInfo(short ioaddr, struct net_device *dev) { @@ -745,7 +749,7 @@ int ioaddr = dev->base_addr; /* Grab the region so we can find another board if autoIRQ fails. */ - if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) { + if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) { if (!autoprobe) printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n", ioaddr); diff -Nru a/drivers/net/eexpress.c b/drivers/net/eexpress.c --- a/drivers/net/eexpress.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/eexpress.c 2004-06-26 17:09:15 -07:00 @@ -423,6 +423,7 @@ return -ENODEV; } +#ifndef MODULE struct net_device * __init express_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); @@ -443,6 +444,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif /* * open and initialize the adapter, ready for use diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c --- a/drivers/net/epic100.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/epic100.c 2004-06-26 17:09:17 -07:00 @@ -1218,13 +1218,8 @@ ep->rx_ring[entry].bufaddr, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); -#if 1 /* HAS_IP_COPYSUM */ eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0); skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), ep->rx_skbuff[entry]->tail, - pkt_len); -#endif pci_dma_sync_single_for_device(ep->pci_dev, ep->rx_ring[entry].bufaddr, ep->rx_buf_sz, diff -Nru a/drivers/net/eql.c b/drivers/net/eql.c --- a/drivers/net/eql.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/eql.c 2004-06-26 17:09:20 -07:00 @@ -495,8 +495,12 @@ return -EFAULT; slave_dev = dev_get_by_name(sc.slave_name); + if (!slave_dev) + return -ENODEV; ret = -EINVAL; + if (!slave_dev) + return ret; spin_lock_bh(&eql->queue.lock); if (eql_is_slave(slave_dev)) { @@ -527,11 +531,15 @@ if (copy_from_user(&sc, scp, sizeof (slave_config_t))) return -EFAULT; - eql = dev->priv; slave_dev = dev_get_by_name(sc.slave_name); + if (!slave_dev) + return -ENODEV; ret = -EINVAL; + if (!slave_dev) + return ret; + eql = dev->priv; spin_lock_bh(&eql->queue.lock); if (eql_is_slave(slave_dev)) { slave = __eql_find_slave_dev(&eql->queue, slave_dev); diff -Nru a/drivers/net/es3210.c b/drivers/net/es3210.c --- a/drivers/net/es3210.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/es3210.c 2004-06-26 17:09:20 -07:00 @@ -161,6 +161,7 @@ release_region(dev->base_addr, ES_IO_EXTENT); } +#ifndef MODULE struct net_device * __init es_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -185,6 +186,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init es_probe1(struct net_device *dev, int ioaddr) { diff -Nru a/drivers/net/eth16i.c b/drivers/net/eth16i.c --- a/drivers/net/eth16i.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/eth16i.c 2004-06-26 17:09:20 -07:00 @@ -458,6 +458,7 @@ return -ENODEV; } +#ifndef MODULE struct net_device * __init eth16i_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local)); @@ -483,6 +484,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init eth16i_probe1(struct net_device *dev, int ioaddr) { @@ -491,7 +493,7 @@ int retval; /* Let's grab the region */ - if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, ETH16I_IO_EXTENT, cardname)) return -EBUSY; /* @@ -538,9 +540,9 @@ /* Try to obtain interrupt vector */ - if ((retval = request_irq(dev->irq, (void *)ð16i_interrupt, 0, dev->name, dev))) { - printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n", - dev->name, cardname, ioaddr, dev->irq); + if ((retval = request_irq(dev->irq, (void *)ð16i_interrupt, 0, cardname, dev))) { + printk(KERN_WARNING "%s at %#3x, but is unusable due to conflicting IRQ %d.\n", + cardname, ioaddr, dev->irq); goto out; } diff -Nru a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c --- a/drivers/net/ewrk3.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/ewrk3.c 2004-06-26 17:09:21 -07:00 @@ -341,6 +341,7 @@ mdelay(1);\ } +#ifndef MODULE struct net_device * __init ewrk3_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct ewrk3_private)); @@ -364,6 +365,7 @@ return ERR_PTR(err); } +#endif static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq) { @@ -1269,7 +1271,7 @@ for (; (i < maxSlots) && (dev != NULL); iobase += EWRK3_IOP_INC, i++) { - if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name)) { + if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME)) { if (DevicePresent(iobase) == 0) { int irq = dev->irq; ret = ewrk3_hw_init(dev, iobase); @@ -1310,7 +1312,7 @@ for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) { if (EISA_signature(name, EISA_ID) == 0) { - if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name) && + if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME) && DevicePresent(iobase) == 0) { int irq = dev->irq; ret = ewrk3_hw_init(dev, iobase); diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c --- a/drivers/net/fealnx.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/fealnx.c 2004-06-26 17:09:19 -07:00 @@ -858,11 +858,16 @@ { struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; + int i; writel(0x00000001, ioaddr + BCR); /* Reset */ if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) return -EAGAIN; + + for (i = 0; i < 3; i++) + writew(((unsigned short*)dev->dev_addr)[i], + ioaddr + PAR0 + i*2); init_ring(dev); diff -Nru a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c --- a/drivers/net/fmv18x.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/fmv18x.c 2004-06-26 17:09:15 -07:00 @@ -57,6 +57,8 @@ #include #include +#define DRV_NAME "fmv18x" + static unsigned fmv18x_probe_list[] __initdata = { 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0 }; @@ -192,7 +194,7 @@ That means we have to be careful with the register values we probe for. */ - if (!request_region(ioaddr, FMV18X_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, FMV18X_IO_EXTENT, DRV_NAME)) return -EBUSY; dev->irq = irq; @@ -224,7 +226,7 @@ } /* Snarf the interrupt vector now. */ - retval = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev); + retval = request_irq(dev->irq, &net_interrupt, 0, DRV_NAME, dev); if (retval) { printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on" "IRQ %d.\n", ioaddr, dev->irq); diff -Nru a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c --- a/drivers/net/forcedeth.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/forcedeth.c 2004-06-26 17:09:15 -07:00 @@ -81,6 +81,7 @@ * superfluous timer interrupts from the nic. */ #define FORCEDETH_VERSION "0.25" +#define DRV_NAME "forcedeth" #include #include @@ -1424,7 +1425,7 @@ pci_set_master(pci_dev); - err = pci_request_regions(pci_dev, dev->name); + err = pci_request_regions(pci_dev, DRV_NAME); if (err < 0) goto out_disable; diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c --- a/drivers/net/hamachi.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/hamachi.c 2004-06-26 17:09:21 -07:00 @@ -207,10 +207,8 @@ /* Condensed bus+endian portability operations. */ #if ADDRLEN == 64 #define cpu_to_leXX(addr) cpu_to_le64(addr) -#define desc_to_virt(addr) bus_to_virt(le64_to_cpu(addr)) #else #define cpu_to_leXX(addr) cpu_to_le32(addr) -#define desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) #endif @@ -1502,7 +1500,7 @@ desc->addr, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE); - buf_addr = desc_to_virt(desc->addr); + buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail; frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12]))); if (hamachi_debug > 4) printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n", diff -Nru a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c --- a/drivers/net/hamradio/hdlcdrv.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/hamradio/hdlcdrv.c 2004-06-26 17:09:19 -07:00 @@ -588,6 +588,8 @@ return -EINVAL; s = (struct hdlcdrv_state *)dev->priv; + netif_stop_queue(dev); + if (s->ops && s->ops->close) i = s->ops->close(dev); if (s->skb) diff -Nru a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c --- a/drivers/net/hp-plus.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/hp-plus.c 2004-06-26 17:09:15 -07:00 @@ -37,6 +37,8 @@ #include "8390.h" +#define DRV_NAME "hp-plus" + /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int hpplus_portlist[] __initdata = {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0}; @@ -142,6 +144,7 @@ release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); } +#ifndef MODULE struct net_device * __init hp_plus_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -166,6 +169,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif /* Do the interesting part of the probe at a single address. */ static int __init hpp_probe1(struct net_device *dev, int ioaddr) @@ -176,7 +180,7 @@ int mem_start; static unsigned version_printed; - if (!request_region(ioaddr, HP_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME)) return -EBUSY; /* Check for the HP+ signature, 50 48 0x 53. */ diff -Nru a/drivers/net/hp.c b/drivers/net/hp.c --- a/drivers/net/hp.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/hp.c 2004-06-26 17:09:16 -07:00 @@ -37,6 +37,8 @@ #include "8390.h" +#define DRV_NAME "hp" + /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int hppclan_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0}; @@ -106,6 +108,7 @@ release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); } +#ifndef MODULE struct net_device * __init hp_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -130,6 +133,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init hp_probe1(struct net_device *dev, int ioaddr) { @@ -137,7 +141,7 @@ const char *name; static unsigned version_printed; - if (!request_region(ioaddr, HP_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME)) return -EBUSY; /* Check for the HP physical address, 08 00 09 xx xx xx. */ @@ -182,7 +186,7 @@ outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE); outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE); if (irq == probe_irq_off(cookie) /* It's a good IRQ line! */ - && request_irq (irq, ei_interrupt, 0, dev->name, dev) == 0) { + && request_irq (irq, ei_interrupt, 0, DRV_NAME, dev) == 0) { printk(" selecting IRQ %d.\n", irq); dev->irq = *irqp; break; @@ -197,7 +201,7 @@ } else { if (dev->irq == 2) dev->irq = 9; - if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) { + if ((retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) { printk (" unable to get IRQ %d.\n", dev->irq); goto out; } diff -Nru a/drivers/net/hp100.c b/drivers/net/hp100.c --- a/drivers/net/hp100.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/hp100.c 2004-06-26 17:09:17 -07:00 @@ -386,6 +386,7 @@ } +#ifndef MODULE struct net_device * __init hp100_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); @@ -420,6 +421,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init hp100_probe1(struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev) diff -Nru a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c --- a/drivers/net/ibmlana.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/ibmlana.c 2004-06-26 17:09:16 -07:00 @@ -98,6 +98,8 @@ #undef DEBUG +#define DRV_NAME "ibmlana" + /* ------------------------------------------------------------------------ * global static data - not more since we can handle multiple boards and * have to pack all state info into the device struct! @@ -952,8 +954,8 @@ printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1); /* try to obtain I/O range */ - if (!request_region(iobase, IBM_LANA_IORANGE, dev->name)) { - printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", dev->name, iobase); + if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) { + printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase); startslot = slot + 1; return -EBUSY; } diff -Nru a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c --- a/drivers/net/irda/ali-ircc.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/irda/ali-ircc.c 2004-06-26 17:09:17 -07:00 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -304,16 +305,18 @@ self->tx_buff.truesize = 14384; /* Allocate memory if needed */ - self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, - GFP_KERNEL |GFP_DMA); + self->rx_buff.head = + dma_alloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } memset(self->rx_buff.head, 0, self->rx_buff.truesize); - self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, - GFP_KERNEL|GFP_DMA); + self->tx_buff.head = + dma_alloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out3; @@ -362,9 +365,11 @@ return 0; err_out4: - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); err_out3: - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); err_out2: release_region(self->io.fir_base, self->io.fir_ext); err_out1: @@ -398,10 +403,12 @@ release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); dev_self[self->index] = NULL; free_netdev(self->netdev); @@ -1572,7 +1579,8 @@ self->io.direction = IO_XMIT; irda_setup_dma(self->io.dma, - self->tx_fifo.queue[self->tx_fifo.ptr].start, + ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start - + self->tx_buff.head) + self->tx_buff_dma, self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE); @@ -1724,8 +1732,8 @@ self->st_fifo.len = self->st_fifo.pending_bytes = 0; self->st_fifo.tail = self->st_fifo.head = 0; - irda_setup_dma(self->io.dma, self->rx_buff.data, - self->rx_buff.truesize, DMA_RX_MODE); + irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize, + DMA_RX_MODE); /* Set Receive Mode,Brick Wall */ //switch_bank(iobase, BANK0); diff -Nru a/drivers/net/irda/ali-ircc.h b/drivers/net/irda/ali-ircc.h --- a/drivers/net/irda/ali-ircc.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/irda/ali-ircc.h 2004-06-26 17:09:18 -07:00 @@ -26,6 +26,7 @@ #include #include +#include #include /* SIR Register */ @@ -198,6 +199,8 @@ chipio_t io; /* IrDA controller information */ iobuff_t tx_buff; /* Transmit buffer */ iobuff_t rx_buff; /* Receive buffer */ + dma_addr_t tx_buff_dma; + dma_addr_t rx_buff_dma; __u8 ier; /* Interrupt enable register */ diff -Nru a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c --- a/drivers/net/irda/irtty-sir.c 2004-06-26 17:09:14 -07:00 +++ b/drivers/net/irda/irtty-sir.c 2004-06-26 17:09:14 -07:00 @@ -438,7 +438,6 @@ struct irtty_info { char name[6]; } info; struct sir_dev *dev; struct sirtty_cb *priv = tty->disc_data; - int size = _IOC_SIZE(cmd); int err = 0; ASSERT(priv != NULL, return -ENODEV;); @@ -449,13 +448,6 @@ dev = priv->dev; ASSERT(dev != NULL, return -1;); - if (_IOC_DIR(cmd) & _IOC_READ) - err = verify_area(VERIFY_WRITE, (void *) arg, size); - else if (_IOC_DIR(cmd) & _IOC_WRITE) - err = verify_area(VERIFY_READ, (void *) arg, size); - if (err) - return err; - switch (cmd) { case TCGETS: case TCGETA: @@ -473,7 +465,7 @@ memset(&info, 0, sizeof(info)); strncpy(info.name, dev->netdev->name, sizeof(info.name)-1); - if (copy_to_user((void *)arg, &info, sizeof(info))) + if (copy_to_user((void __user *)arg, &info, sizeof(info))) err = -EFAULT; break; default: diff -Nru a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c --- a/drivers/net/irda/nsc-ircc.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/irda/nsc-ircc.c 2004-06-26 17:09:15 -07:00 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -307,8 +308,9 @@ self->tx_buff.truesize = 14384; /* Allocate memory if needed */ - self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, - GFP_KERNEL|GFP_DMA); + self->rx_buff.head = + dma_alloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto out2; @@ -316,8 +318,9 @@ } memset(self->rx_buff.head, 0, self->rx_buff.truesize); - self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, - GFP_KERNEL|GFP_DMA); + self->tx_buff.head = + dma_alloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto out3; @@ -368,9 +371,11 @@ return 0; out4: - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); out3: - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); out2: release_region(self->io.fir_base, self->io.fir_ext); out1: @@ -404,10 +409,12 @@ release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); dev_self[self->index] = NULL; free_netdev(self->netdev); @@ -1409,7 +1416,8 @@ outb(ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1); irda_setup_dma(self->io.dma, - self->tx_fifo.queue[self->tx_fifo.ptr].start, + ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start - + self->tx_buff.head) + self->tx_buff_dma, self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE); @@ -1566,8 +1574,8 @@ self->st_fifo.len = self->st_fifo.pending_bytes = 0; self->st_fifo.tail = self->st_fifo.head = 0; - irda_setup_dma(self->io.dma, self->rx_buff.data, - self->rx_buff.truesize, DMA_RX_MODE); + irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize, + DMA_RX_MODE); /* Enable DMA */ switch_bank(iobase, BANK0); diff -Nru a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h --- a/drivers/net/irda/nsc-ircc.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/irda/nsc-ircc.h 2004-06-26 17:09:18 -07:00 @@ -32,6 +32,7 @@ #include #include +#include #include /* DMA modes needed */ @@ -255,6 +256,8 @@ chipio_t io; /* IrDA controller information */ iobuff_t tx_buff; /* Transmit buffer */ iobuff_t rx_buff; /* Receive buffer */ + dma_addr_t tx_buff_dma; + dma_addr_t rx_buff_dma; __u8 ier; /* Interrupt enable register */ diff -Nru a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c --- a/drivers/net/irda/smsc-ircc2.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/irda/smsc-ircc2.c 2004-06-26 17:09:19 -07:00 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -112,6 +113,8 @@ chipio_t io; /* IrDA controller information */ iobuff_t tx_buff; /* Transmit buffer */ iobuff_t rx_buff; /* Receive buffer */ + dma_addr_t tx_buff_dma; + dma_addr_t rx_buff_dma; struct qos_info qos; /* QoS capabilities for this device */ @@ -413,16 +416,18 @@ self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE; self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE; - self->rx_buff.head = (u8 *) kmalloc(self->rx_buff.truesize, - GFP_KERNEL|GFP_DMA); + self->rx_buff.head = + dma_alloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { ERROR("%s, Can't allocate memory for receive buffer!\n", driver_name); goto err_out2; } - self->tx_buff.head = (u8 *) kmalloc(self->tx_buff.truesize, - GFP_KERNEL|GFP_DMA); + self->tx_buff.head = + dma_alloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { ERROR("%s, Can't allocate memory for transmit buffer!\n", driver_name); @@ -464,9 +469,11 @@ return 0; err_out4: - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); err_out3: - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); err_out2: free_netdev(self->netdev); dev_self[--dev_count] = NULL; @@ -1159,7 +1166,7 @@ IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB); /* Setup DMA controller (must be done after enabling chip DMA) */ - irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, + irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len, DMA_TX_MODE); /* Enable interrupt */ @@ -1249,8 +1256,8 @@ outb(2050 & 0xff, iobase+IRCC_RX_SIZE_LO); /* Setup DMA controller */ - irda_setup_dma(self->io.dma, self->rx_buff.data, - self->rx_buff.truesize, DMA_RX_MODE); + irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize, + DMA_RX_MODE); /* Enable burst mode chip Rx DMA */ register_bank(iobase, 1); @@ -1717,10 +1724,12 @@ release_region(self->io.sir_base, self->io.sir_ext); if (self->tx_buff.head) - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); free_netdev(self->netdev); diff -Nru a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c --- a/drivers/net/irda/via-ircc.c 2004-06-26 17:09:14 -07:00 +++ b/drivers/net/irda/via-ircc.c 2004-06-26 17:09:14 -07:00 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -383,7 +384,8 @@ /* Allocate memory if needed */ self->rx_buff.head = - (__u8 *) kmalloc(self->rx_buff.truesize, GFP_KERNEL | GFP_DMA); + dma_alloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out2; @@ -391,7 +393,8 @@ memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = - (__u8 *) kmalloc(self->tx_buff.truesize, GFP_KERNEL | GFP_DMA); + dma_alloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out3; @@ -432,9 +435,11 @@ return 0; err_out4: - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); err_out3: - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); err_out2: release_region(self->io.fir_base, self->io.fir_ext); err_out1: @@ -468,9 +473,11 @@ __FUNCTION__, self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); dev_self[self->index] = NULL; free_netdev(self->netdev); @@ -816,7 +823,7 @@ EnTXDMA(iobase, ON); EnRXDMA(iobase, OFF); - irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, + irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len, DMA_TX_MODE); SetSendByte(iobase, self->tx_buff.len); @@ -897,7 +904,8 @@ EnTXDMA(iobase, ON); EnRXDMA(iobase, OFF); irda_setup_dma(self->io.dma, - self->tx_fifo.queue[self->tx_fifo.ptr].start, + ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start - + self->tx_buff.head) + self->tx_buff_dma, self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE); #ifdef DBGMSG DBG(printk @@ -1022,8 +1030,8 @@ EnAllInt(iobase, ON); EnTXDMA(iobase, OFF); EnRXDMA(iobase, ON); - irda_setup_dma(self->io.dma2, self->rx_buff.data, - self->rx_buff.truesize, DMA_RX_MODE); + irda_setup_dma(self->io.dma2, self->rx_buff_dma, + self->rx_buff.truesize, DMA_RX_MODE); TXStart(iobase, OFF); RXStart(iobase, ON); diff -Nru a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h --- a/drivers/net/irda/via-ircc.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/irda/via-ircc.h 2004-06-26 17:09:20 -07:00 @@ -33,6 +33,7 @@ #include #include #include +#include #include #define MAX_TX_WINDOW 7 @@ -102,6 +103,8 @@ chipio_t io; /* IrDA controller information */ iobuff_t tx_buff; /* Transmit buffer */ iobuff_t rx_buff; /* Receive buffer */ + dma_addr_t tx_buff_dma; + dma_addr_t rx_buff_dma; __u8 ier; /* Interrupt enable register */ diff -Nru a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c --- a/drivers/net/irda/w83977af_ir.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/irda/w83977af_ir.c 2004-06-26 17:09:17 -07:00 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -207,8 +208,9 @@ self->tx_buff.truesize = 4000; /* Allocate memory if needed */ - self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, - GFP_KERNEL|GFP_DMA); + self->rx_buff.head = + dma_alloc_coherent(NULL, self->rx_buff.truesize, + &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out1; @@ -216,8 +218,9 @@ memset(self->rx_buff.head, 0, self->rx_buff.truesize); - self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, - GFP_KERNEL|GFP_DMA); + self->tx_buff.head = + dma_alloc_coherent(NULL, self->tx_buff.truesize, + &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out2; @@ -252,9 +255,11 @@ return 0; err_out3: - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); err_out2: - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); err_out1: free_netdev(dev); err_out: @@ -297,10 +302,12 @@ release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) - kfree(self->tx_buff.head); + dma_free_coherent(NULL, self->tx_buff.truesize, + self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - kfree(self->rx_buff.head); + dma_free_coherent(NULL, self->rx_buff.truesize, + self->rx_buff.head, self->rx_buff_dma); free_netdev(self->netdev); @@ -606,10 +613,10 @@ disable_dma(self->io.dma); clear_dma_ff(self->io.dma); set_dma_mode(self->io.dma, DMA_MODE_READ); - set_dma_addr(self->io.dma, isa_virt_to_bus(self->tx_buff.data)); + set_dma_addr(self->io.dma, self->tx_buff_dma); set_dma_count(self->io.dma, self->tx_buff.len); #else - irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, + irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len, DMA_MODE_WRITE); #endif self->io.direction = IO_XMIT; @@ -763,10 +770,10 @@ disable_dma(self->io.dma); clear_dma_ff(self->io.dma); set_dma_mode(self->io.dma, DMA_MODE_READ); - set_dma_addr(self->io.dma, isa_virt_to_bus(self->rx_buff.data)); + set_dma_addr(self->io.dma, self->rx_buff_dma); set_dma_count(self->io.dma, self->rx_buff.truesize); #else - irda_setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, + irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize, DMA_MODE_READ); #endif /* diff -Nru a/drivers/net/irda/w83977af_ir.h b/drivers/net/irda/w83977af_ir.h --- a/drivers/net/irda/w83977af_ir.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/irda/w83977af_ir.h 2004-06-26 17:09:15 -07:00 @@ -26,6 +26,7 @@ #define W83977AF_IR_H #include +#include /* Flags for configuration register CRF0 */ #define ENBNKSEL 0x01 @@ -179,6 +180,8 @@ chipio_t io; /* IrDA controller information */ iobuff_t tx_buff; /* Transmit buffer */ iobuff_t rx_buff; /* Receive buffer */ + dma_addr_t tx_buff_dma; + dma_addr_t rx_buff_dma; /* Note : currently locking is *very* incomplete, but this * will get you started. Check in nsc-ircc.c for a proper diff -Nru a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c --- a/drivers/net/isa-skeleton.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/isa-skeleton.c 2004-06-26 17:09:21 -07:00 @@ -161,6 +161,7 @@ release_region(dev->base_addr, NETCARD_IO_EXTENT); } +#ifndef MODULE struct net_device * __init netcard_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); @@ -185,6 +186,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif /* * This is the real probe routine. Linux has a history of friendly device diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c --- a/drivers/net/ixgb/ixgb_main.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/ixgb/ixgb_main.c 2004-06-26 17:09:16 -07:00 @@ -1876,7 +1876,6 @@ struct ixgb_rx_desc *rx_desc; struct ixgb_buffer *buffer_info; struct sk_buff *skb; - int reserve_len = 2; unsigned int i; int num_group_tail_writes; long cleancount; @@ -1895,7 +1894,7 @@ while (--cleancount > 0) { rx_desc = IXGB_RX_DESC(*rx_ring, i); - skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len); + skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN); if (unlikely(!skb)) { /* Better luck next round */ @@ -1906,7 +1905,7 @@ * this will result in a 16 byte aligned IP header after * the 14 byte MAC header is removed */ - skb_reserve(skb, reserve_len); + skb_reserve(skb, NET_IP_ALIGN); skb->dev = netdev; diff -Nru a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c --- a/drivers/net/jazzsonic.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/jazzsonic.c 2004-06-26 17:09:16 -07:00 @@ -37,6 +37,8 @@ #include #include +#define DRV_NAME "jazzsonic" + #define SREGS_PAD(n) u16 n; #include "sonic.h" @@ -151,7 +153,7 @@ int err = -ENODEV; int i; - if (!request_region(base_addr, 0x100, dev->name)) + if (!request_region(base_addr, 0x100, DRV_NAME)) return -EBUSY; /* * get the Silicon Revision ID. If this is one of the known diff -Nru a/drivers/net/lance.c b/drivers/net/lance.c --- a/drivers/net/lance.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/lance.c 2004-06-26 17:09:15 -07:00 @@ -432,6 +432,7 @@ return -ENODEV; } +#ifndef MODULE struct net_device * __init lance_probe(int unit) { struct net_device *dev = alloc_etherdev(0); @@ -456,6 +457,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options) { diff -Nru a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c --- a/drivers/net/lasi_82596.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/lasi_82596.c 2004-06-26 17:09:16 -07:00 @@ -87,7 +87,6 @@ #include #include #include -#include #include #include #include diff -Nru a/drivers/net/lne390.c b/drivers/net/lne390.c --- a/drivers/net/lne390.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/lne390.c 2004-06-26 17:09:20 -07:00 @@ -49,6 +49,8 @@ #include "8390.h" +#define DRV_NAME "lne390" + static int lne390_probe1(struct net_device *dev, int ioaddr); static int lne390_open(struct net_device *dev); @@ -112,7 +114,7 @@ SET_MODULE_OWNER(dev); if (ioaddr > 0x1ff) { /* Check a single specified location. */ - if (!request_region(ioaddr, LNE390_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME)) return -EBUSY; ret = lne390_probe1(dev, ioaddr); if (ret) @@ -131,7 +133,7 @@ /* EISA spec allows for up to 16 slots, but 8 is typical. */ for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { - if (!request_region(ioaddr, LNE390_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME)) continue; if (lne390_probe1(dev, ioaddr) == 0) return 0; @@ -151,6 +153,7 @@ iounmap((void *)dev->mem_start); } +#ifndef MODULE struct net_device * __init lne390_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -175,6 +178,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init lne390_probe1(struct net_device *dev, int ioaddr) { @@ -228,7 +232,7 @@ } printk(" IRQ %d,", dev->irq); - if ((ret = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) { + if ((ret = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) { printk (" unable to get IRQ %d.\n", dev->irq); return ret; } diff -Nru a/drivers/net/loopback.c b/drivers/net/loopback.c --- a/drivers/net/loopback.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/loopback.c 2004-06-26 17:09:16 -07:00 @@ -55,7 +55,9 @@ #include /* For ARPHRD_ETHER */ #include #include +#include +static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16) @@ -123,7 +125,7 @@ */ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) { - struct net_device_stats *stats = dev->priv; + struct net_device_stats *lb_stats; skb_orphan(skb); @@ -142,12 +144,13 @@ } dev->last_rx = jiffies; - if (likely(stats)) { - stats->rx_bytes+=skb->len; - stats->tx_bytes+=skb->len; - stats->rx_packets++; - stats->tx_packets++; - } + + lb_stats = &per_cpu(loopback_stats, get_cpu()); + lb_stats->rx_bytes += skb->len; + lb_stats->tx_bytes += skb->len; + lb_stats->rx_packets++; + lb_stats->tx_packets++; + put_cpu(); netif_rx(skb); @@ -156,7 +159,28 @@ static struct net_device_stats *get_stats(struct net_device *dev) { - return (struct net_device_stats *)dev->priv; + struct net_device_stats *stats = dev->priv; + int i; + + if (!stats) { + return NULL; + } + + memset(stats, 0, sizeof(struct net_device_stats)); + + for (i=0; i < NR_CPUS; i++) { + struct net_device_stats *lb_stats; + + if (!cpu_possible(i)) + continue; + lb_stats = &per_cpu(loopback_stats, i); + stats->rx_bytes += lb_stats->rx_bytes; + stats->tx_bytes += lb_stats->tx_bytes; + stats->rx_packets += lb_stats->rx_packets; + stats->tx_packets += lb_stats->tx_packets; + } + + return stats; } struct net_device loopback_dev = { @@ -173,7 +197,8 @@ .rebuild_header = eth_rebuild_header, .flags = IFF_LOOPBACK, .features = NETIF_F_SG|NETIF_F_FRAGLIST - |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA, + |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA + |NETIF_F_LLTX, }; /* Setup and register the of the LOOPBACK device. */ diff -Nru a/drivers/net/lp486e.c b/drivers/net/lp486e.c --- a/drivers/net/lp486e.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/lp486e.c 2004-06-26 17:09:16 -07:00 @@ -75,6 +75,8 @@ #include #include +#define DRV_NAME "lp486e" + /* debug print flags */ #define LOG_SRCDST 0x80000000 #define LOG_STATINT 0x40000000 @@ -970,7 +972,7 @@ return -ENODEV; probed++; - if (!request_region(IOADDR, LP486E_TOTAL_SIZE, dev->name)) { + if (!request_region(IOADDR, LP486E_TOTAL_SIZE, DRV_NAME)) { printk(KERN_ERR "lp486e: IO address 0x%x in use\n", IOADDR); return -EBUSY; } diff -Nru a/drivers/net/macsonic.c b/drivers/net/macsonic.c --- a/drivers/net/macsonic.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/macsonic.c 2004-06-26 17:09:15 -07:00 @@ -53,7 +53,6 @@ #include #include #include -#include #define SREGS_PAD(n) u16 n; @@ -613,7 +612,6 @@ MODULE_PARM(sonic_debug, "i"); MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); -MODULE_LICENSE("GPL"); int init_module(void) diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c --- a/drivers/net/natsemi.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/natsemi.c 2004-06-26 17:09:15 -07:00 @@ -766,7 +766,7 @@ SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - i = pci_request_regions(pdev, dev->name); + i = pci_request_regions(pdev, DRV_NAME); if (i) goto err_pci_request_regions; @@ -1798,14 +1798,9 @@ np->rx_dma[entry], buflen, PCI_DMA_FROMDEVICE); -#if HAS_IP_COPYSUM eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), - np->rx_skbuff[entry]->tail, pkt_len); -#endif pci_dma_sync_single_for_device(np->pci_dev, np->rx_dma[entry], buflen, diff -Nru a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c --- a/drivers/net/ne-h8300.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/ne-h8300.c 2004-06-26 17:09:17 -07:00 @@ -34,6 +34,8 @@ #include "8390.h" +#define DRV_NAME "ne-h8300" + /* Some defines that people can play with if so inclined. */ /* Do we perform extra sanity checks on stuff ? */ @@ -156,6 +158,7 @@ release_region(dev->base_addr, NE_IO_EXTENT); } +#ifndef MODULE struct net_device * __init ne_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -187,6 +190,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init ne_probe1(struct net_device *dev, int ioaddr) { @@ -200,7 +204,7 @@ struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned char bus_width; - if (!request_region(ioaddr, NE_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) return -EBUSY; reg0 = inb_p(ioaddr); diff -Nru a/drivers/net/ne.c b/drivers/net/ne.c --- a/drivers/net/ne.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/ne.c 2004-06-26 17:09:17 -07:00 @@ -55,6 +55,8 @@ #include "8390.h" +#define DRV_NAME "ne" + /* Some defines that people can play with if so inclined. */ /* Do we support clones that don't adhere to 14,15 of the SAprom ? */ @@ -203,6 +205,7 @@ release_region(dev->base_addr, NE_IO_EXTENT); } +#ifndef MODULE struct net_device * __init ne_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -227,6 +230,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init ne_probe_isapnp(struct net_device *dev) { @@ -284,7 +288,7 @@ int reg0, ret; static unsigned version_printed; - if (!request_region(ioaddr, NE_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) return -EBUSY; reg0 = inb_p(ioaddr); diff -Nru a/drivers/net/ne2.c b/drivers/net/ne2.c --- a/drivers/net/ne2.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/ne2.c 2004-06-26 17:09:21 -07:00 @@ -82,6 +82,8 @@ #include "8390.h" +#define DRV_NAME "ne2" + /* Some defines that people can play with if so inclined. */ /* Do we perform extra sanity checks on stuff ? */ @@ -284,6 +286,7 @@ release_region(dev->base_addr, NE_IO_EXTENT); } +#ifndef MODULE struct net_device * __init ne2_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -308,6 +311,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int ne2_procinfo(char *buf, int slot, struct net_device *dev) { @@ -368,7 +372,7 @@ irq = irqs[(POS & 0x60)>>5]; } - if (!request_region(base_addr, NE_IO_EXTENT, dev->name)) + if (!request_region(base_addr, NE_IO_EXTENT, DRV_NAME)) return -EBUSY; #ifdef DEBUG @@ -470,7 +474,7 @@ /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ - retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); + retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); if (retval) { printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, retval); diff -Nru a/drivers/net/ne2k_cbus.c b/drivers/net/ne2k_cbus.c --- a/drivers/net/ne2k_cbus.c 2004-06-26 17:09:17 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,887 +0,0 @@ -/* - - ne2k_cbus.c: A driver for the NE2000 like ethernet on NEC PC-9800. - - This is a copy of the 2.5.66 Linux ISA NE2000 driver "ne.c" - (Donald Becker/Paul Gortmaker) with the NEC PC-9800 specific - changes added by Osamu Tomita. - -From ne.c: ------------ - Copyright 1993 United States Government as represented by the - Director, National Security Agency. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. ------------ - -*/ - -/* Routines for the NatSemi-based designs (NE[12]000). */ - -static const char version[] = -"ne2k_cbus.c:v1.0 3/24/03 Osamu Tomita\n"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "8390.h" - -/* Some defines that people can play with if so inclined. */ - -/* Do we support clones that don't adhere to 14,15 of the SAprom ? */ -#define SUPPORT_NE_BAD_CLONES - -/* Do we perform extra sanity checks on stuff ? */ -/* #define NE_SANITY_CHECK */ - -/* Do we implement the read before write bugfix ? */ -/* #define NE_RW_BUGFIX */ - -/* Do we have a non std. amount of memory? (in units of 256 byte pages) */ -/* #define PACKETBUF_MEMSIZE 0x40 */ - -#ifdef SUPPORT_NE_BAD_CLONES -/* A list of bad clones that we none-the-less recognize. */ -static struct { const char *name8, *name16; unsigned char SAprefix[4];} -bad_clone_list[] __initdata = { - {"LA/T-98?", "LA/T-98", {0x00, 0xa0, 0xb0}}, /* I/O Data */ - {"EGY-98?", "EGY-98", {0x00, 0x40, 0x26}}, /* Melco EGY98 */ - {"ICM?", "ICM-27xx-ET", {0x00, 0x80, 0xc8}}, /* ICM IF-27xx-ET */ - {"CNET-98/EL?", "CNET(98)E/L", {0x00, 0x80, 0x4C}}, /* Contec CNET-98/EL */ - {0,} -}; -#endif - -/* ---- No user-serviceable parts below ---- */ - -#define NE_BASE (dev->base_addr) -#define NE_CMD EI_SHIFT(0x00) -#define NE_DATAPORT EI_SHIFT(0x10) /* NatSemi-defined port window offset. */ -#define NE_RESET EI_SHIFT(0x1f) /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT 0x20 - -#define NE1SM_START_PG 0x20 /* First page of TX buffer */ -#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - -#include "ne2k_cbus.h" - -static int ne_probe1(struct net_device *dev, int ioaddr); -static int ne_open(struct net_device *dev); -static int ne_close(struct net_device *dev); - -static void ne_reset_8390(struct net_device *dev); -static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void ne_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void ne_block_output(struct net_device *dev, const int count, - const unsigned char *buf, const int start_page); - - -/* Probe for various non-shared-memory ethercards. - - NEx000-clone boards have a Station Address PROM (SAPROM) in the packet - buffer memory space. NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of - the SAPROM, while other supposed NE2000 clones must be detected by their - SA prefix. - - Reading the SAPROM from a word-wide card with the 8390 set in byte-wide - mode results in doubled values, which can be detected and compensated for. - - The probe is also responsible for initializing the card and filling - in the 'dev' and 'ei_status' structures. - - We use the minimum memory size for some ethercard product lines, iff we can't - distinguish models. You can increase the packet buffer size by setting - PACKETBUF_MEMSIZE. Reported Cabletron packet buffer locations are: - E1010 starts at 0x100 and ends at 0x2000. - E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory") - E2010 starts at 0x100 and ends at 0x4000. - E2010-x starts at 0x100 and ends at 0xffff. */ - -static int __init do_ne_probe(struct net_device *dev) -{ - unsigned int base_addr = dev->base_addr; - int irq = dev->irq; - - SET_MODULE_OWNER(dev); - - if (ei_debug > 2) - printk(KERN_DEBUG "ne_probe(): entered.\n"); - - /* If CONFIG_NET_CBUS, - we need dev->priv->reg_offset BEFORE to probe */ - if (ne2k_cbus_init(dev) != 0) - return -ENOMEM; - - /* First check any supplied i/o locations. User knows best. */ - if (base_addr > 0) { - int result; - const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK)); - - if (ei_debug > 2) - printk(KERN_DEBUG "ne_probe(): call ne_probe_cbus(base_addr=0x%x)\n", base_addr); - - result = ne_probe_cbus(dev, hw, base_addr, irq); - if (result != 0) - ne2k_cbus_destroy(dev); - - return result; - } - - if (ei_debug > 2) - printk(KERN_DEBUG "ne_probe(): base_addr is not specified.\n"); - -#ifndef MODULE - /* Last resort. The semi-risky C-Bus auto-probe. */ - if (ei_debug > 2) - printk(KERN_DEBUG "ne_probe(): auto-probe start.\n"); - - { - const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK)); - - if (hw && hw->hwtype) { - const unsigned short *plist; - for (plist = hw->portlist; *plist; plist++) - if (ne_probe_cbus(dev, hw, *plist, irq) == 0) - return 0; - } else { - for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) { - const unsigned short *plist; - for (plist = hw->portlist; *plist; plist++) - if (ne_probe_cbus(dev, hw, *plist, irq) == 0) - return 0; - } - } - } -#endif - - ne2k_cbus_destroy(dev); - - return -ENODEV; -} - -static void cleanup_card(struct net_device *dev) -{ - const struct ne2k_cbus_region *rlist; - const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK)); - - free_irq(dev->irq, dev); - for (rlist = hw->regionlist; rlist->range; rlist++) { - release_region(dev->base_addr + rlist->start, - rlist->range); - } - ne2k_cbus_destroy(dev); -} - -struct net_device * __init ne_probe(int unit) -{ - struct net_device *dev = alloc_ei_netdev(); - int err; - - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - err = do_ne_probe(dev); - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - return dev; -out1: - cleanup_card(dev); -out: - free_netdev(dev); - return ERR_PTR(err); -} - -static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr, int irq) -{ - if (ei_debug > 2) - printk(KERN_DEBUG "ne_probe_cbus(): entered. (called from %p)\n", - __builtin_return_address(0)); - - if (hw && hw->hwtype) { - ne2k_cbus_set_hwtype(dev, hw, ioaddr); - dev->irq = irq; - return ne_probe1(dev, ioaddr); - } else { - /* auto detect */ - - printk(KERN_DEBUG "ne_probe_cbus(): try to determine hardware types.\n"); - for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) { - ne2k_cbus_set_hwtype(dev, hw, ioaddr); - dev->irq = irq; - if (ne_probe1(dev, ioaddr) == 0) - return 0; - } - } - return -ENODEV; -} - -static int __init ne_probe1(struct net_device *dev, int ioaddr) -{ - int i; - unsigned char SA_prom[32]; - int wordlength = 2; - const char *name = NULL; - int start_page, stop_page; - int neX000, bad_card; - int reg0, ret; - static unsigned version_printed; - const struct ne2k_cbus_region *rlist; - const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK)); - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - -#ifdef CONFIG_NE2K_CBUS_CNET98EL - if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_CNET98EL) { - outb_p(0, CONFIG_NE2K_CBUS_CNET98EL_IO_BASE); - /* udelay(5000); */ - outb_p(1, CONFIG_NE2K_CBUS_CNET98EL_IO_BASE); - /* udelay(5000); */ - outb_p((ioaddr & 0xf000) >> 8 | 0x08 | 0x01, CONFIG_NE2K_CBUS_CNET98EL_IO_BASE + 2); - /* udelay(5000); */ - } -#endif - - for (rlist = hw->regionlist; rlist->range; rlist++) - if (!request_region(ioaddr + rlist->start, - rlist->range, dev->name)) { - ret = -EBUSY; - goto err_out; - } - - reg0 = inb_p(ioaddr + EI_SHIFT(0)); - if (reg0 == 0xFF) { - ret = -ENODEV; - goto err_out; - } - - /* Do a preliminary verification that we have a 8390. */ -#ifdef CONFIG_NE2K_CBUS_CNET98EL - if (hw->hwtype != NE2K_CBUS_HARDWARE_TYPE_CNET98EL) -#endif - { - int regd; - outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); - regd = inb_p(ioaddr + EI_SHIFT(0x0d)); - outb_p(0xff, ioaddr + EI_SHIFT(0x0d)); - outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); - inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ - if (inb_p(ioaddr + EN0_COUNTER0) != 0) { - outb_p(reg0, ioaddr); - outb_p(regd, ioaddr + EI_SHIFT(0x0d)); /* Restore the old values. */ - ret = -ENODEV; - goto err_out; - } - } - - if (ei_debug && version_printed++ == 0) - printk(KERN_INFO "%s", version); - - printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr); - - /* A user with a poor card that fails to ack the reset, or that - does not have a valid 0x57,0x57 signature can still use this - without having to recompile. Specifying an i/o address along - with an otherwise unused dev->mem_end value of "0xBAD" will - cause the driver to skip these parts of the probe. */ - - bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad)); - - /* Reset card. Who knows what dain-bramaged state it was left in. */ - - { - unsigned long reset_start_time = jiffies; - - /* derived from CNET98EL-patch for bad clones */ - outb_p(E8390_NODMA | E8390_STOP, ioaddr + E8390_CMD); - - /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ - outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); - - while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2*HZ/100) { - if (bad_card) { - printk(" (warning: no reset ack)"); - break; - } else { - printk(" not found (no reset ack).\n"); - ret = -ENODEV; - goto err_out; - } - } - - outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ - } - -#ifdef CONFIG_NE2K_CBUS_CNET98EL - if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_CNET98EL) { - static const char pat[32] ="AbcdeFghijKlmnoPqrstUvwxyZ789012"; - char buf[32]; - int maxwait = 200; - - if (ei_debug > 2) - printk(" [CNET98EL-specific initialize..."); - outb_p(E8390_NODMA | E8390_STOP, ioaddr + E8390_CMD); /* 0x20|0x1 */ - ret = -ENODEV; - i = inb(ioaddr); - if ((i & ~0x2) != (0x20 | 0x01)) - goto err_out; - if ((inb(ioaddr + 0x7) & 0x80) != 0x80) - goto err_out; - outb_p(E8390_RXOFF, ioaddr + EN0_RXCR); /* out(ioaddr+0xc, 0x20) */ - /* outb_p(ENDCFG_WTS|ENDCFG_FT1|ENDCFG_LS, ioaddr+EN0_DCFG); */ - outb_p(ENDCFG_WTS | 0x48, ioaddr + EN0_DCFG); /* 0x49 */ - outb_p(CNET98EL_START_PG, ioaddr + EN0_STARTPG); - outb_p(CNET98EL_STOP_PG, ioaddr + EN0_STOPPG); - if (ei_debug > 2) - printk("memory check"); - for (i = 0; i < 65536; i += 1024) { - if (ei_debug > 2) - printk(" %04x", i); - ne2k_cbus_writemem(dev, ioaddr, i, pat, 32); - while (((inb(ioaddr + EN0_ISR) & ENISR_RDC) != ENISR_RDC) && --maxwait) - ; - ne2k_cbus_readmem(dev, ioaddr, i, buf, 32); - if (memcmp(pat, buf, 32)) { - if (ei_debug > 2) - printk(" failed."); - break; - } - } - if (i != 16384) { - if (ei_debug > 2) - printk("] "); - printk("memory failure at %x\n", i); - goto err_out; - } - if (ei_debug > 2) - printk(" good..."); - if (!dev->irq) { - if (ei_debug > 2) - printk("] "); - printk("IRQ must be specified for C-NET(98)E/L. probe failed.\n"); - goto err_out; - } - outb((dev->irq > 5) ? (dev->irq & 4):(dev->irq >> 1), ioaddr + (0x2 | 0x400)); - outb(0x7e, ioaddr + (0x4 | 0x400)); - ne2k_cbus_readmem(dev, ioaddr, 16384, SA_prom, 32); - outb(0xff, ioaddr + EN0_ISR); - if (ei_debug > 2) - printk("done]"); - } else -#endif /* CONFIG_NE2K_CBUS_CNET98EL */ - /* Read the 16 bytes of station address PROM. - We must first initialize registers, similar to NS8390_init(eifdev, 0). - We can't reliably read the SAPROM address without this. - (I learned the hard way!). */ - { - struct {unsigned char value; unsigned short offset;} program_seq[] = - { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ - /* NEC PC-9800: some board can only handle word-wide access? */ - {0x48 | ENDCFG_WTS, EN0_DCFG}, /* Set word-wide (0x48) access. */ - {16384 / 256, EN0_STARTPG}, - {32768 / 256, EN0_STOPPG}, - {0x00, EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, /* Mask completion irq. */ - {0xFF, EN0_ISR}, - {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - - for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) - outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); - insw(ioaddr + NE_DATAPORT, SA_prom, 32 >> 1); - - } - - if (wordlength == 2) - { - for (i = 0; i < 16; i++) - SA_prom[i] = SA_prom[i+i]; - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; -#ifdef CONFIG_NE2K_CBUS_CNET98EL - if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_CNET98EL) { - start_page = CNET98EL_START_PG; - stop_page = CNET98EL_STOP_PG; - } -#endif - } else { - start_page = NE1SM_START_PG; - stop_page = NE1SM_STOP_PG; - } - - neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); - if (neX000) { - name = "C-Bus-NE2K-compat"; - } - else - { -#ifdef SUPPORT_NE_BAD_CLONES - /* Ack! Well, there might be a *bad* NE*000 clone there. - Check for total bogus addresses. */ - for (i = 0; bad_clone_list[i].name8; i++) - { - if (SA_prom[0] == bad_clone_list[i].SAprefix[0] && - SA_prom[1] == bad_clone_list[i].SAprefix[1] && - SA_prom[2] == bad_clone_list[i].SAprefix[2]) - { - if (wordlength == 2) - { - name = bad_clone_list[i].name16; - } else { - name = bad_clone_list[i].name8; - } - break; - } - } - if (bad_clone_list[i].name8 == NULL) - { - printk(" not found (invalid signature %2.2x %2.2x).\n", - SA_prom[14], SA_prom[15]); - ret = -ENXIO; - goto err_out; - } -#else - printk(" not found.\n"); - ret = -ENXIO; - goto err_out; -#endif - } - - if (dev->irq < 2) - { - unsigned long cookie = probe_irq_on(); - outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */ - outb_p(0x00, ioaddr + EN0_RCNTLO); - outb_p(0x00, ioaddr + EN0_RCNTHI); - outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */ - mdelay(10); /* wait 10ms for interrupt to propagate */ - outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ - dev->irq = probe_irq_off(cookie); - if (ei_debug > 2) - printk(" autoirq is %d\n", dev->irq); - } else if (dev->irq == 7) - /* Fixup for users that don't know that IRQ 7 is really IRQ 11, - or don't know which one to set. */ - dev->irq = 11; - - if (! dev->irq) { - printk(" failed to detect IRQ line.\n"); - ret = -EAGAIN; - goto err_out; - } - - /* Snarf the interrupt now. There's no point in waiting since we cannot - share and the board will usually be enabled. */ - ret = request_irq(dev->irq, ei_interrupt, 0, name, dev); - if (ret) { - printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); - goto err_out_kfree; - } - - dev->base_addr = ioaddr; - - for(i = 0; i < ETHER_ADDR_LEN; i++) { - printk(" %2.2x", SA_prom[i]); - dev->dev_addr[i] = SA_prom[i]; - } - - printk("\n%s: %s found at %#x, hardware type %d(%s), using IRQ %d.\n", - dev->name, name, ioaddr, hw->hwtype, hw->hwident, dev->irq); - - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = (wordlength == 2); - - ei_status.rx_start_page = start_page + TX_PAGES; -#ifdef PACKETBUF_MEMSIZE - /* Allow the packet buffer size to be overridden by know-it-alls. */ - ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; -#endif - - ei_status.reset_8390 = &ne_reset_8390; - ei_status.block_input = &ne_block_input; - ei_status.block_output = &ne_block_output; - ei_status.get_8390_hdr = &ne_get_8390_hdr; - ei_status.priv = 0; - dev->open = &ne_open; - dev->stop = &ne_close; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = ei_poll; -#endif - NS8390_init(dev, 0); - return 0; - -err_out_kfree: - ne2k_cbus_destroy(dev); -err_out: - while (rlist > hw->regionlist) { - rlist --; - release_region(ioaddr + rlist->start, rlist->range); - } - return ret; -} - -static int ne_open(struct net_device *dev) -{ - ei_open(dev); - return 0; -} - -static int ne_close(struct net_device *dev) -{ - if (ei_debug > 1) - printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); - ei_close(dev); - return 0; -} - -/* Hard reset the card. This used to pause for the same period that a - 8390 reset command required, but that shouldn't be necessary. */ - -static void ne_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - - if (ei_debug > 1) - printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); - - /* derived from CNET98EL-patch for bad clones... */ - outb_p(E8390_NODMA | E8390_STOP, NE_BASE + E8390_CMD); /* 0x20 | 0x1 */ - - /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ - outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2*HZ/100) { - printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); - break; - } - outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ - -static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) -{ - int nic_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - - if (ei_status.dmaing) - { - printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr " - "[DMAstat:%d][irqlock:%d].\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); - outb_p(0, nic_base + EN0_RCNTHI); - outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ - outb_p(ring_page, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - if (ei_status.word16) - insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); - else - insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; - - le16_to_cpus(&hdr->count); -} - -/* Block input and output, similar to the Crynwr packet driver. If you - are porting to a new ethercard, look at the packet driver source for hints. - The NEx000 doesn't share the on-board packet memory -- you have to put - the packet out through the "remote DMA" dataport using outb. */ - -static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) -{ -#ifdef NE_SANITY_CHECK - int xfer_count = count; -#endif - int nic_base = dev->base_addr; - char *buf = skb->data; - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) - { - printk(KERN_EMERG "%s: DMAing conflict in ne_block_input " - "[DMAstat:%d][irqlock:%d].\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - - /* round up count to a word (derived from ICM-patch) */ - count = (count + 1) & ~1; - - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); - outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) - { - insw(NE_BASE + NE_DATAPORT,buf,count>>1); - if (count & 0x01) - { - buf[count-1] = inb(NE_BASE + NE_DATAPORT); -#ifdef NE_SANITY_CHECK - xfer_count++; -#endif - } - } else { - insb(NE_BASE + NE_DATAPORT, buf, count); - } - -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. If you see - this message you either 1) have a slightly incompatible clone - or 2) have noise/speed problems with your bus. */ - - if (ei_debug > 1) - { - /* DMA termination address check... */ - int addr, tries = 20; - do { - /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here - -- it's broken for Rx on some cards! */ - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if (((ring_offset + xfer_count) & 0xff) == low) - break; - } while (--tries > 0); - if (tries <= 0) - printk(KERN_WARNING "%s: RX transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, ring_offset + xfer_count, addr); - } -#endif - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -static void ne_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) -{ - int nic_base = NE_BASE; - unsigned long dma_start; -#ifdef NE_SANITY_CHECK - int retries = 0; -#endif - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - - if (ei_status.word16 && (count & 0x01)) - count++; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) - { - printk(KERN_EMERG "%s: DMAing conflict in ne_block_output." - "[DMAstat:%d][irqlock:%d]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - -#ifdef NE_SANITY_CHECK -retry: -#endif - -#ifdef NE8390_RW_BUGFIX - /* Handle the read-before-write bug the same way as the - Crynwr packet driver -- the NatSemi method doesn't work. - Actually this doesn't always work either, but if you have - problems with your NEx000 this is better than nothing! */ - - outb_p(0x42, nic_base + EN0_RCNTLO); - outb_p(0x00, nic_base + EN0_RCNTHI); - outb_p(0x42, nic_base + EN0_RSARLO); - outb_p(0x00, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - /* Make certain that the dummy read has occurred. */ - udelay(6); -#endif - - outb_p(ENISR_RDC, nic_base + EN0_ISR); - - /* Now the normal output. */ - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(0x00, nic_base + EN0_RSARLO); - outb_p(start_page, nic_base + EN0_RSARHI); - - outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { - outsw(NE_BASE + NE_DATAPORT, buf, count>>1); - } else { - outsb(NE_BASE + NE_DATAPORT, buf, count); - } - - dma_start = jiffies; - -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. */ - - if (ei_debug > 1) - { - /* DMA termination address check... */ - int addr, tries = 20; - do { - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if ((start_page << 8) + count == addr) - break; - } while (--tries > 0); - - if (tries <= 0) - { - printk(KERN_WARNING "%s: Tx packet transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, (start_page << 8) + count, addr); - if (retries++ == 0) - goto retry; - } - } -#endif - - while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ - printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); - ne_reset_8390(dev); - NS8390_init(dev,1); - break; - } - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; - return; -} - - -#ifdef MODULE -#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ -static struct net_device *dev_ne[MAX_NE_CARDS]; -static int io[MAX_NE_CARDS]; -static int irq[MAX_NE_CARDS]; -static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ -static int hwtype[MAX_NE_CARDS] = { 0, }; /* board type */ - -MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); -MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); -MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); -MODULE_PARM(hwtype, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); -MODULE_PARM_DESC(io, "I/O base address(es),required"); -MODULE_PARM_DESC(irq, "IRQ number(s)"); -MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); -MODULE_PARM_DESC(hwtype, "Board type of PC-9800 C-Bus NIC"); -MODULE_DESCRIPTION("NE1000/NE2000 PC-9800 C-bus Ethernet driver"); -MODULE_LICENSE("GPL"); - -/* This is set up so that no ISA autoprobe takes place. We can't guarantee -that the ne2k probe is the last 8390 based probe to take place (as it -is at boot) and so the probe will get confused by any other 8390 cards. -ISA device autoprobes on a running machine are not recommended anyway. */ - -int init_module(void) -{ - int this_dev, found = 0; - - for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct net_device *dev = alloc_ei_netdev(); - if (!dev) - break; - dev->irq = irq[this_dev]; - dev->mem_end = bad[this_dev]; - dev->base_addr = io[this_dev]; - dev->mem_start = hwtype[this_dev]; - if (do_ne_probe(dev) == 0) { - if (register_netdev(dev) == 0) { - dev_ne[found++] = dev; - continue; - } - cleanup_card(dev); - } - free_netdev(dev); - if (found) - break; - if (io[this_dev] != 0) - printk(KERN_WARNING "ne2k_cbus: No NE*000 card found at i/o = %#x\n", io[this_dev]); - else - printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); - return -ENXIO; - } - if (found) - return 0; - return -ENODEV; -} - -void cleanup_module(void) -{ - int this_dev; - - for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct net_device *dev = dev_ne[this_dev]; - if (dev) { - unregister_netdev(dev); - cleanup_card(dev); - free_netdev(dev); - } - } -} -#endif /* MODULE */ - diff -Nru a/drivers/net/ne2k_cbus.h b/drivers/net/ne2k_cbus.h --- a/drivers/net/ne2k_cbus.h 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,481 +0,0 @@ -/* ne2k_cbus.h: - vender-specific information definition for NEC PC-9800 - C-bus Ethernet Cards - Used in ne.c - - (C)1998,1999 KITAGWA Takurou & Linux/98 project -*/ - -#include - -#undef NE_RESET -#define NE_RESET EI_SHIFT(0x11) /* Issue a read to reset, a write to clear. */ - -#ifdef CONFIG_NE2K_CBUS_CNET98EL -#ifndef CONFIG_NE2K_CBUS_CNET98EL_IO_BASE -#warning CONFIG_NE2K_CBUS_CNET98EL_IO_BASE is not defined(config error?) -#warning use 0xaaed as default -#define CONFIG_NE2K_CBUS_CNET98EL_IO_BASE 0xaaed /* or 0x55ed */ -#endif -#define CNET98EL_START_PG 0x00 -#define CNET98EL_STOP_PG 0x40 -#endif - -/* Hardware type definition (derived from *BSD) */ -#define NE2K_CBUS_HARDWARE_TYPE_MASK 0xff - -/* 0: reserved for auto-detect */ -/* 1: (not tested) - Allied Telesis CentreCom LA-98-T */ -#define NE2K_CBUS_HARDWARE_TYPE_ATLA98 1 -/* 2: (not tested) - ELECOM Laneed - LD-BDN[123]A - PLANET SMART COM 98 EN-2298-C - MACNICA ME98 */ -#define NE2K_CBUS_HARDWARE_TYPE_BDN 2 -/* 3: - Melco EGY-98 - Contec C-NET(98)E*A/L*A,C-NET(98)P */ -#define NE2K_CBUS_HARDWARE_TYPE_EGY98 3 -/* 4: - Melco LGY-98,IND-SP,IND-SS - MACNICA NE2098 */ -#define NE2K_CBUS_HARDWARE_TYPE_LGY98 4 -/* 5: - ICM DT-ET-25,DT-ET-T5,IF-2766ET,IF-2771ET - PLANET SMART COM 98 EN-2298-T,EN-2298P-T - D-Link DE-298PT,DE-298PCAT - ELECOM Laneed LD-98P */ -#define NE2K_CBUS_HARDWARE_TYPE_ICM 5 -/* 6: (reserved for SIC-98, which is not supported in this driver.) */ -/* 7: (unused in *BSD?) - - -*/ -#define NE2K_CBUS_HARDWARE_TYPE_NE2K 7 -/* 8: - NEC PC-9801-108 */ -#define NE2K_CBUS_HARDWARE_TYPE_NEC108 8 -/* 9: - I-O DATA LA-98,LA/T-98 */ -#define NE2K_CBUS_HARDWARE_TYPE_IOLA98 9 -/* 10: (reserved for C-NET(98), which is not supported in this driver.) */ -/* 11: - Contec C-NET(98)E,L */ -#define NE2K_CBUS_HARDWARE_TYPE_CNET98EL 11 - -#define NE2K_CBUS_HARDWARE_TYPE_MAX 11 - -/* HARDWARE TYPE ID 12-31: reserved */ - -struct ne2k_cbus_offsetinfo { - unsigned short skip; - unsigned short offset8; /* +0x8 - +0xf */ - unsigned short offset10; /* +0x10 */ - unsigned short offset1f; /* +0x1f */ -}; - -struct ne2k_cbus_region { - unsigned short start; - short range; -}; - -struct ne2k_cbus_hwinfo { - const unsigned short hwtype; - const unsigned char *hwident; -#ifndef MODULE - const unsigned short *portlist; -#endif - const struct ne2k_cbus_offsetinfo *offsetinfo; - const struct ne2k_cbus_region *regionlist; -}; - -#ifdef CONFIG_NE2K_CBUS_ATLA98 -#ifndef MODULE -static unsigned short atla98_portlist[] __initdata = { - 0xd0, - 0 -}; -#endif -#define atla98_offsetinfo ne2k_offsetinfo -#define atla98_regionlist ne2k_regionlist -#endif /* CONFIG_NE2K_CBUS_ATLA98 */ - -#ifdef CONFIG_NE2K_CBUS_BDN -#ifndef MODULE -static unsigned short bdn_portlist[] __initdata = { - 0xd0, - 0 -}; -#endif -static struct ne2k_cbus_offsetinfo bdn_offsetinfo __initdata = { -#if 0 - /* comes from FreeBSD(98) ed98.h */ - 0x1000, 0x8000, 0x100, 0xc200 /* ??? */ -#else - /* comes from NetBSD/pc98 if_ne_isa.c */ - 0x1000, 0x8000, 0x100, 0x7f00 /* ??? */ -#endif -}; -static struct ne2k_cbus_region bdn_regionlist[] __initdata = { - {0x0, 1}, {0x1000, 1}, {0x2000, 1}, {0x3000,1}, - {0x4000, 1}, {0x5000, 1}, {0x6000, 1}, {0x7000, 1}, - {0x8000, 1}, {0x9000, 1}, {0xa000, 1}, {0xb000, 1}, - {0xc000, 1}, {0xd000, 1}, {0xe000, 1}, {0xf000, 1}, - {0x100, 1}, {0x7f00, 1}, - {0x0, 0} -}; -#endif /* CONFIG_NE2K_CBUS_BDN */ - -#ifdef CONFIG_NE2K_CBUS_EGY98 -#ifndef MODULE -static unsigned short egy98_portlist[] __initdata = { - 0xd0, - 0 -}; -#endif -static struct ne2k_cbus_offsetinfo egy98_offsetinfo __initdata = { - 0x02, 0x100, 0x200, 0x300 -}; -static struct ne2k_cbus_region egy98_regionlist[] __initdata = { - {0x0, 1}, {0x2, 1}, {0x4, 1}, {0x6, 1}, - {0x8, 1}, {0xa, 1}, {0xc, 1}, {0xe, 1}, - {0x100, 1}, {0x102, 1}, {0x104, 1}, {0x106, 1}, - {0x108, 1}, {0x10a, 1}, {0x10c, 1}, {0x10e, 1}, - {0x200, 1}, {0x300, 1}, - {0x0, 0} -}; -#endif /* CONFIG_NE2K_CBUS_EGY98 */ - -#ifdef CONFIG_NE2K_CBUS_LGY98 -#ifndef MODULE -static unsigned short lgy98_portlist[] __initdata = { - 0xd0, 0x10d0, 0x20d0, 0x30d0, 0x40d0, 0x50d0, 0x60d0, 0x70d0, - 0 -}; -#endif -static struct ne2k_cbus_offsetinfo lgy98_offsetinfo __initdata = { - 0x01, 0x08, 0x200, 0x300 -}; -static struct ne2k_cbus_region lgy98_regionlist[] __initdata = { - {0x0, 16}, {0x200, 1}, {0x300, 1}, - {0x0, 0} -}; -#endif /* CONFIG_NE2K_CBUS_LGY98 */ - -#ifdef CONFIG_NE2K_CBUS_ICM -#ifndef MODULE -static unsigned short icm_portlist[] __initdata = { - /* ICM */ - 0x56d0, - /* LD-98PT */ - 0x46d0, 0x66d0, 0x76d0, 0x86d0, 0x96d0, 0xa6d0, 0xb6d0, 0xc6d0, - 0 -}; -#endif -static struct ne2k_cbus_offsetinfo icm_offsetinfo __initdata = { - 0x01, 0x08, 0x100, 0x10f -}; -static struct ne2k_cbus_region icm_regionlist[] __initdata = { - {0x0, 16}, {0x100, 16}, - {0x0, 0} -}; -#endif /* CONFIG_NE2K_CBUS_ICM */ - -#if defined(CONFIG_NE2K_CBUS_NE2K) && !defined(MODULE) -static unsigned short ne2k_portlist[] __initdata = { - 0xd0, 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, - 0 -}; -#endif -#if defined(CONFIG_NE2K_CBUS_NE2K) || defined(CONFIG_NE2K_CBUS_ATLA98) -static struct ne2k_cbus_offsetinfo ne2k_offsetinfo __initdata = { - 0x01, 0x08, 0x10, 0x1f -}; -static struct ne2k_cbus_region ne2k_regionlist[] __initdata = { - {0x0, 32}, - {0x0, 0} -}; -#endif - -#ifdef CONFIG_NE2K_CBUS_NEC108 -#ifndef MODULE -static unsigned short nec108_portlist[] __initdata = { - 0x770, 0x2770, 0x4770, 0x6770, - 0 -}; -#endif -static struct ne2k_cbus_offsetinfo nec108_offsetinfo __initdata = { - 0x02, 0x1000, 0x888, 0x88a -}; -static struct ne2k_cbus_region nec108_regionlist[] __initdata = { - {0x0, 1}, {0x2, 1}, {0x4, 1}, {0x6, 1}, - {0x8, 1}, {0xa, 1}, {0xc, 1}, {0xe, 1}, - {0x1000, 1}, {0x1002, 1}, {0x1004, 1}, {0x1006, 1}, - {0x1008, 1}, {0x100a, 1}, {0x100c, 1}, {0x100e, 1}, - {0x888, 1}, {0x88a, 1}, {0x88c, 1}, {0x88e, 1}, - {0x0, 0} -}; -#endif - -#ifdef CONFIG_NE2K_CBUS_IOLA98 -#ifndef MODULE -static unsigned short iola98_portlist[] __initdata = { - 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, - 0 -}; -#endif -static struct ne2k_cbus_offsetinfo iola98_offsetinfo __initdata = { - 0x1000, 0x8000, 0x100, 0xf100 -}; -static struct ne2k_cbus_region iola98_regionlist[] __initdata = { - {0x0, 1}, {0x1000, 1}, {0x2000, 1}, {0x3000, 1}, - {0x4000, 1}, {0x5000, 1}, {0x6000, 1}, {0x7000, 1}, - {0x8000, 1}, {0x9000, 1}, {0xa000, 1}, {0xb000, 1}, - {0xc000, 1}, {0xd000, 1}, {0xe000, 1}, {0xf000, 1}, - {0x100, 1}, {0xf100, 1}, - {0x0,0} -}; -#endif /* CONFIG_NE2K_CBUS_IOLA98 */ - -#ifdef CONFIG_NE2K_CBUS_CNET98EL -#ifndef MODULE -static unsigned short cnet98el_portlist[] __initdata = { - 0x3d0, 0x13d0, 0x23d0, 0x33d0, 0x43d0, 0x53d0, 0x60d0, 0x70d0, - 0 -}; -#endif -static struct ne2k_cbus_offsetinfo cnet98el_offsetinfo __initdata = { - 0x01, 0x08, 0x40e, 0x400 -}; -static struct ne2k_cbus_region cnet98el_regionlist[] __initdata = { - {0x0, 16}, {0x400, 16}, - {0x0, 0} -}; -#endif - - -/* port information table (for ne.c initialize/probe process) */ - -static struct ne2k_cbus_hwinfo ne2k_cbus_hwinfo_list[] __initdata = { -#ifdef CONFIG_NE2K_CBUS_ATLA98 -/* NOT TESTED */ - { - NE2K_CBUS_HARDWARE_TYPE_ATLA98, - "LA-98-T", -#ifndef MODULE - atla98_portlist, -#endif - &atla98_offsetinfo, atla98_regionlist - }, -#endif -#ifdef CONFIG_NE2K_CBUS_BDN -/* NOT TESTED */ - { - NE2K_CBUS_HARDWARE_TYPE_BDN, - "LD-BDN[123]A", -#ifndef MODULE - bdn_portlist, -#endif - &bdn_offsetinfo, bdn_regionlist - }, -#endif -#ifdef CONFIG_NE2K_CBUS_ICM - { - NE2K_CBUS_HARDWARE_TYPE_ICM, - "IF-27xxET", -#ifndef MODULE - icm_portlist, -#endif - &icm_offsetinfo, icm_regionlist - }, -#endif -#ifdef CONFIG_NE2K_CBUS_NE2K - { - NE2K_CBUS_HARDWARE_TYPE_NE2K, - "NE2000 compat.", -#ifndef MODULE - ne2k_portlist, -#endif - &ne2k_offsetinfo, ne2k_regionlist - }, -#endif -#ifdef CONFIG_NE2K_CBUS_NEC108 - { - NE2K_CBUS_HARDWARE_TYPE_NEC108, - "PC-9801-108", -#ifndef MODULE - nec108_portlist, -#endif - &nec108_offsetinfo, nec108_regionlist - }, -#endif -#ifdef CONFIG_NE2K_CBUS_IOLA98 - { - NE2K_CBUS_HARDWARE_TYPE_IOLA98, - "LA-98", -#ifndef MODULE - iola98_portlist, -#endif - &iola98_offsetinfo, iola98_regionlist - }, -#endif -#ifdef CONFIG_NE2K_CBUS_CNET98EL - { - NE2K_CBUS_HARDWARE_TYPE_CNET98EL, - "C-NET(98)E/L", -#ifndef MODULE - cnet98el_portlist, -#endif - &cnet98el_offsetinfo, cnet98el_regionlist - }, -#endif -/* NOTE: LGY98 must be probed before EGY98, or system stalled!? */ -#ifdef CONFIG_NE2K_CBUS_LGY98 - { - NE2K_CBUS_HARDWARE_TYPE_LGY98, - "LGY-98", -#ifndef MODULE - lgy98_portlist, -#endif - &lgy98_offsetinfo, lgy98_regionlist - }, -#endif -#ifdef CONFIG_NE2K_CBUS_EGY98 - { - NE2K_CBUS_HARDWARE_TYPE_EGY98, - "EGY-98", -#ifndef MODULE - egy98_portlist, -#endif - &egy98_offsetinfo, egy98_regionlist - }, -#endif - { - 0, - "unsupported hardware", -#ifndef MODULE - NULL, -#endif - NULL, NULL - } -}; - -static int __init ne2k_cbus_init(struct net_device *dev) -{ - struct ei_device *ei_local; - if (dev->priv == NULL) { - ei_local = kmalloc(sizeof(struct ei_device), GFP_KERNEL); - if (ei_local == NULL) - return -ENOMEM; - memset(ei_local, 0, sizeof(struct ei_device)); - ei_local->reg_offset = kmalloc(sizeof(typeof(*ei_local->reg_offset))*18, GFP_KERNEL); - if (ei_local->reg_offset == NULL) { - kfree(ei_local); - return -ENOMEM; - } - spin_lock_init(&ei_local->page_lock); - dev->priv = ei_local; - } - return 0; -} - -static void ne2k_cbus_destroy(struct net_device *dev) -{ - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - if (ei_local != NULL) { - if (ei_local->reg_offset) - kfree(ei_local->reg_offset); - kfree(dev->priv); - dev->priv = NULL; - } -} - -static const struct ne2k_cbus_hwinfo * __init ne2k_cbus_get_hwinfo(int hwtype) -{ - const struct ne2k_cbus_hwinfo *hw; - - for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) { - if (hw->hwtype == hwtype) break; - } - return hw; -} - -static void __init ne2k_cbus_set_hwtype(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr) -{ - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - int i; - int hwtype_old = dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK; - - if (!ei_local) - panic("Gieee! ei_local == NULL!! (from %p)", - __builtin_return_address(0)); - - dev->mem_start &= ~NE2K_CBUS_HARDWARE_TYPE_MASK; - dev->mem_start |= hw->hwtype & NE2K_CBUS_HARDWARE_TYPE_MASK; - - if (ei_debug > 2) { - printk(KERN_DEBUG "hwtype changed: %d -> %d\n",hwtype_old,(int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK)); - } - - if (hw->offsetinfo) { - for (i = 0; i < 8; i++) { - ei_local->reg_offset[i] = hw->offsetinfo->skip * i; - } - for (i = 8; i < 16; i++) { - ei_local->reg_offset[i] = - hw->offsetinfo->skip*(i-8) + hw->offsetinfo->offset8; - } -#ifdef CONFIG_NE2K_CBUS_NEC108 - if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_NEC108) { - int adj = (ioaddr & 0xf000) /2; - ei_local->reg_offset[16] = - (hw->offsetinfo->offset10 | adj) - ioaddr; - ei_local->reg_offset[17] = - (hw->offsetinfo->offset1f | adj) - ioaddr; - } else { -#endif /* CONFIG_NE2K_CBUS_NEC108 */ - ei_local->reg_offset[16] = hw->offsetinfo->offset10; - ei_local->reg_offset[17] = hw->offsetinfo->offset1f; -#ifdef CONFIG_NE2K_CBUS_NEC108 - } -#endif - } else { - /* make dummmy offset list */ - for (i = 0; i < 16; i++) { - ei_local->reg_offset[i] = i; - } - ei_local->reg_offset[16] = 0x10; - ei_local->reg_offset[17] = 0x1f; - } -} - -#if defined(CONFIG_NE2K_CBUS_ICM) || defined(CONFIG_NE2K_CBUS_CNET98EL) -static void __init ne2k_cbus_readmem(struct net_device *dev, int ioaddr, unsigned short memaddr, char *buf, unsigned short len) -{ - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - outb_p(E8390_NODMA | E8390_START, ioaddr+E8390_CMD); - outb_p(len & 0xff, ioaddr+EN0_RCNTLO); - outb_p(len >> 8, ioaddr+EN0_RCNTHI); - outb_p(memaddr & 0xff, ioaddr+EN0_RSARLO); - outb_p(memaddr >> 8, ioaddr+EN0_RSARHI); - outb_p(E8390_RREAD | E8390_START, ioaddr+E8390_CMD); - insw(ioaddr+NE_DATAPORT, buf, len >> 1); -} -static void __init ne2k_cbus_writemem(struct net_device *dev, int ioaddr, unsigned short memaddr, const char *buf, unsigned short len) -{ - struct ei_device *ei_local = (struct ei_device *)(dev->priv); - outb_p(E8390_NODMA | E8390_START, ioaddr+E8390_CMD); - outb_p(ENISR_RDC, ioaddr+EN0_ISR); - outb_p(len & 0xff, ioaddr+EN0_RCNTLO); - outb_p(len >> 8, ioaddr+EN0_RCNTHI); - outb_p(memaddr & 0xff, ioaddr+EN0_RSARLO); - outb_p(memaddr >> 8, ioaddr+EN0_RSARHI); - outb_p(E8390_RWRITE | E8390_START, ioaddr+E8390_CMD); - outsw(ioaddr+NE_DATAPORT, buf, len >> 1); -} -#endif - -static int ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr, int irq); -/* End of ne2k_cbus.h */ diff -Nru a/drivers/net/ne3210.c b/drivers/net/ne3210.c --- a/drivers/net/ne3210.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/ne3210.c 2004-06-26 17:09:17 -07:00 @@ -45,6 +45,8 @@ #include "8390.h" +#define DRV_NAME "ne3210" + static int ne3210_open(struct net_device *dev); static int ne3210_close(struct net_device *dev); @@ -111,13 +113,13 @@ device->driver_data = dev; ioaddr = edev->base_addr; - if (!request_region(ioaddr, NE3210_IO_EXTENT, dev->name)) { + if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) { retval = -EBUSY; goto out; } if (!request_region(ioaddr + NE3210_CFG1, - NE3210_CFG_EXTENT, dev->name)) { + NE3210_CFG_EXTENT, DRV_NAME)) { retval = -EBUSY; goto out1; } @@ -140,7 +142,7 @@ dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07]; printk(".\nne3210.c: using IRQ %d, ", dev->irq); - retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); + retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); if (retval) { printk (" unable to get IRQ %d.\n", dev->irq); goto out2; @@ -163,7 +165,7 @@ } } - if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, dev->name)) { + if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, DRV_NAME)) { printk ("ne3210.c: Unable to request shared memory at physical address %#lx\n", phys_mem); goto out3; diff -Nru a/drivers/net/ni52.c b/drivers/net/ni52.c --- a/drivers/net/ni52.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/ni52.c 2004-06-26 17:09:18 -07:00 @@ -124,6 +124,8 @@ #include "ni52.h" +#define DRV_NAME "ni52" + #define DEBUG /* debug on */ #define SYSBUSVAL 1 /* 8 Bit */ @@ -424,7 +426,7 @@ dev->mem_start = memstart; dev->mem_end = memend; - if (!request_region(ioaddr, NI52_TOTAL_SIZE, dev->name)) + if (!request_region(ioaddr, NI52_TOTAL_SIZE, DRV_NAME)) return -EBUSY; if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c --- a/drivers/net/ns83820.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/ns83820.c 2004-06-26 17:09:20 -07:00 @@ -113,6 +113,8 @@ #include #include +#define DRV_NAME "ns83820" + /* Global parameters. See MODULE_PARM near the bottom. */ static int ihr = 2; static int reset_phy = 0; @@ -1851,7 +1853,7 @@ 0); err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ, - ndev->name, ndev); + DRV_NAME, ndev); if (err) { printk(KERN_INFO "ns83820: unable to register irq %d\n", pci_dev->irq); diff -Nru a/drivers/net/oaknet.c b/drivers/net/oaknet.c --- a/drivers/net/oaknet.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/oaknet.c 2004-06-26 17:09:19 -07:00 @@ -164,7 +164,7 @@ ret = -EAGAIN; if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) { printk("%s: unable to request interrupt %d.\n", - dev->name, dev->irq); + name, dev->irq); goto out_region; } diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c --- a/drivers/net/pcnet32.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/pcnet32.c 2004-06-26 17:09:16 -07:00 @@ -22,8 +22,8 @@ *************************************************************************/ #define DRV_NAME "pcnet32" -#define DRV_VERSION "1.30c" -#define DRV_RELDATE "05.25.2004" +#define DRV_VERSION "1.30f" +#define DRV_RELDATE "06.16.2004" #define PFX DRV_NAME ": " static const char *version = @@ -245,6 +245,11 @@ * v1.30b 24 May 2004 Don Fry fix bogus tx carrier errors with 79c973, * assisted by Bruce Penrod . * v1.30c 25 May 2004 Don Fry added netif_wake_queue after pcnet32_restart. + * v1.30d 01 Jun 2004 Don Fry discard oversize rx packets. + * v1.30e 11 Jun 2004 Don Fry recover after fifo error and rx hang. + * v1.30f 16 Jun 2004 Don Fry cleanup IRQ to allow 0 and 1 for PCI, + * expanding on suggestions from Ralf Baechle , + * and Brian Murphy . */ @@ -360,7 +365,7 @@ static void pcnet32_probe_vlbus(void); static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); -static int pcnet32_probe1(unsigned long, unsigned int, int, struct pci_dev *); +static int pcnet32_probe1(unsigned long, int, struct pci_dev *); static int pcnet32_open(struct net_device *); static int pcnet32_init_ring(struct net_device *); static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); @@ -958,7 +963,7 @@ if (request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_vlbus")) { /* check if there is really a pcnet chip on that ioaddr */ if ((inb(ioaddr + 14) == 0x57) && (inb(ioaddr + 15) == 0x57)) { - pcnet32_probe1(ioaddr, 0, 0, NULL); + pcnet32_probe1(ioaddr, 0, NULL); } else { release_region(ioaddr, PCNET32_TOTAL_SIZE); } @@ -999,7 +1004,7 @@ return -EBUSY; } - return pcnet32_probe1(ioaddr, pdev->irq, 1, pdev); + return pcnet32_probe1(ioaddr, 1, pdev); } @@ -1008,8 +1013,7 @@ * pdev will be NULL when called from pcnet32_probe_vlbus. */ static int __devinit -pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, - struct pci_dev *pdev) +pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) { struct pcnet32_private *lp; dma_addr_t lp_dma_addr; @@ -1270,11 +1274,8 @@ a->write_csr(ioaddr, 2, (lp->dma_addr + offsetof(struct pcnet32_private, init_block)) >> 16); - if (irq_line) { - dev->irq = irq_line; - } - - if (dev->irq >= 2) { + if (pdev) { /* use the IRQ provided by PCI */ + dev->irq = pdev->irq; if (pcnet32_debug & NETIF_MSG_PROBE) printk(" assigned IRQ %d.\n", dev->irq); } else { @@ -1362,8 +1363,7 @@ int rc; unsigned long flags; - if (dev->irq == 0 || - request_irq(dev->irq, &pcnet32_interrupt, + if (request_irq(dev->irq, &pcnet32_interrupt, lp->shared_irq ? SA_SHIRQ : 0, dev->name, (void *)dev)) { return -EAGAIN; } @@ -1531,13 +1531,15 @@ int i; for (i = 0; i < TX_RING_SIZE; i++) { + lp->tx_ring[i].status = 0; /* CPU owns buffer */ + wmb(); /* Make sure adapter sees owner change */ if (lp->tx_skbuff[i]) { pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], lp->tx_skbuff[i]->len, PCI_DMA_TODEVICE); dev_kfree_skb_any(lp->tx_skbuff[i]); - lp->tx_skbuff[i] = NULL; - lp->tx_dma_addr[i] = 0; } + lp->tx_skbuff[i] = NULL; + lp->tx_dma_addr[i] = 0; } } @@ -1566,21 +1568,23 @@ skb_reserve (rx_skbuff, 2); } + rmb(); if (lp->rx_dma_addr[i] == 0) lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ); + wmb(); /* Make sure owner changes after all others are visible */ lp->rx_ring[i].status = le16_to_cpu(0x8000); } /* The Tx buffer address is filled in as needed, but we do need to clear * the upper ownership bit. */ for (i = 0; i < TX_RING_SIZE; i++) { + lp->tx_ring[i].status = 0; /* CPU owns buffer */ + wmb(); /* Make sure adapter sees owner change */ lp->tx_ring[i].base = 0; - lp->tx_ring[i].status = 0; lp->tx_dma_addr[i] = 0; } - wmb(); /* Make sure all changes are visible */ lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); for (i = 0; i < 6; i++) @@ -1589,9 +1593,14 @@ offsetof(struct pcnet32_private, rx_ring)); lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)); + wmb(); /* Make sure all changes are visible */ return 0; } +/* the pcnet32 has been issued a stop or reset. Wait for the stop bit + * then flush the pending transmit operations, re-initialize the ring, + * and tell the chip to initialize. + */ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits) { @@ -1599,6 +1608,15 @@ unsigned long ioaddr = dev->base_addr; int i; + /* wait for stop */ + for (i=0; i<100; i++) + if (lp->a.read_csr(ioaddr, 0) & 0x0004) + break; + + if (i >= 100 && netif_msg_drv(lp)) + printk(KERN_ERR "%s: pcnet32_restart timed out waiting for stop.\n", + dev->name); + pcnet32_purge_tx_ring(dev); if (pcnet32_init_ring(dev)) return; @@ -1857,15 +1875,16 @@ } if (must_restart) { - /* stop the chip to clear the error condition, then restart */ - lp->a.write_csr (ioaddr, 0, 0x0004); + /* reset the chip to clear the error condition, then restart */ + lp->a.reset(ioaddr); + lp->a.write_csr(ioaddr, 4, 0x0915); pcnet32_restart(dev, 0x0002); netif_wake_queue(dev); } } - /* Clear any other interrupt, and set interrupt enable. */ - lp->a.write_csr (ioaddr, 0, 0x7940); + /* Set interrupt enable. */ + lp->a.write_csr (ioaddr, 0, 0x0040); lp->a.write_rap (ioaddr,rap); if (netif_msg_intr(lp)) @@ -1907,7 +1926,13 @@ short pkt_len = (le32_to_cpu(lp->rx_ring[entry].msg_length) & 0xfff)-4; struct sk_buff *skb; - if (pkt_len < 60) { + /* Discard oversize frames. */ + if (unlikely(pkt_len > PKT_BUF_SZ - 2)) { + if (netif_msg_drv(lp)) + printk(KERN_ERR "%s: Impossible packet size %d!\n", + dev->name, pkt_len); + lp->stats.rx_errors++; + } else if (pkt_len < 60) { if (netif_msg_rx_err(lp)) printk(KERN_ERR "%s: Runt packet!\n", dev->name); lp->stats.rx_errors++; diff -Nru a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c --- a/drivers/net/ppp_async.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/ppp_async.c 2004-06-26 17:09:19 -07:00 @@ -238,7 +238,7 @@ */ static ssize_t ppp_asynctty_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t count) + unsigned char __user *buf, size_t count) { return -EAGAIN; } @@ -249,7 +249,7 @@ */ static ssize_t ppp_asynctty_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t count) + const unsigned char __user *buf, size_t count) { return -EAGAIN; } @@ -260,6 +260,7 @@ { struct asyncppp *ap = ap_get(tty); int err, val; + int __user *p = (int __user *)arg; if (ap == 0) return -ENXIO; @@ -270,7 +271,7 @@ if (ap == 0) break; err = -EFAULT; - if (put_user(ppp_channel_index(&ap->chan), (int *) arg)) + if (put_user(ppp_channel_index(&ap->chan), p)) break; err = 0; break; @@ -280,7 +281,7 @@ if (ap == 0) break; err = -EFAULT; - if (put_user(ppp_unit_number(&ap->chan), (int *) arg)) + if (put_user(ppp_unit_number(&ap->chan), p)) break; err = 0; break; @@ -299,7 +300,7 @@ case FIONREAD: val = 0; - if (put_user(val, (int *) arg)) + if (put_user(val, p)) break; err = 0; break; @@ -397,6 +398,8 @@ ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) { struct asyncppp *ap = chan->private; + void __user *argp = (void __user *)arg; + int __user *p = argp; int err, val; u32 accm[8]; @@ -404,12 +407,12 @@ switch (cmd) { case PPPIOCGFLAGS: val = ap->flags | ap->rbits; - if (put_user(val, (int *) arg)) + if (put_user(val, p)) break; err = 0; break; case PPPIOCSFLAGS: - if (get_user(val, (int *) arg)) + if (get_user(val, p)) break; ap->flags = val & ~SC_RCV_BITS; spin_lock_irq(&ap->recv_lock); @@ -419,34 +422,34 @@ break; case PPPIOCGASYNCMAP: - if (put_user(ap->xaccm[0], (u32 *) arg)) + if (put_user(ap->xaccm[0], (u32 __user *)argp)) break; err = 0; break; case PPPIOCSASYNCMAP: - if (get_user(ap->xaccm[0], (u32 *) arg)) + if (get_user(ap->xaccm[0], (u32 __user *)argp)) break; err = 0; break; case PPPIOCGRASYNCMAP: - if (put_user(ap->raccm, (u32 *) arg)) + if (put_user(ap->raccm, (u32 __user *)argp)) break; err = 0; break; case PPPIOCSRASYNCMAP: - if (get_user(ap->raccm, (u32 *) arg)) + if (get_user(ap->raccm, (u32 __user *)argp)) break; err = 0; break; case PPPIOCGXASYNCMAP: - if (copy_to_user((void __user *) arg, ap->xaccm, sizeof(ap->xaccm))) + if (copy_to_user(argp, ap->xaccm, sizeof(ap->xaccm))) break; err = 0; break; case PPPIOCSXASYNCMAP: - if (copy_from_user(accm, (void __user *) arg, sizeof(accm))) + if (copy_from_user(accm, argp, sizeof(accm))) break; accm[2] &= ~0x40000000U; /* can't escape 0x5e */ accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ @@ -455,12 +458,12 @@ break; case PPPIOCGMRU: - if (put_user(ap->mru, (int *) arg)) + if (put_user(ap->mru, p)) break; err = 0; break; case PPPIOCSMRU: - if (get_user(val, (int *) arg)) + if (get_user(val, p)) break; if (val < PPP_MRU) val = PPP_MRU; diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c --- a/drivers/net/ppp_generic.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/ppp_generic.c 2004-06-26 17:09:20 -07:00 @@ -129,8 +129,9 @@ #endif /* CONFIG_PPP_MULTILINK */ struct net_device_stats stats; /* statistics */ #ifdef CONFIG_PPP_FILTER - struct sock_fprog pass_filter; /* filter for packets to pass */ - struct sock_fprog active_filter;/* filter for pkts to reset idle */ + struct sock_filter *pass_filter; /* filter for packets to pass */ + struct sock_filter *active_filter;/* filter for pkts to reset idle */ + unsigned pass_len, active_len; #endif /* CONFIG_PPP_FILTER */ }; @@ -493,6 +494,43 @@ return mask; } +static int get_filter(void __user *arg, struct sock_filter **p) +{ + struct sock_fprog uprog; + struct sock_filter *code = NULL; + int len, err; + + if (copy_from_user(&uprog, arg, sizeof(uprog))) + return -EFAULT; + + if (uprog.len > BPF_MAXINSNS) + return -EINVAL; + + if (!uprog.len) { + *p = NULL; + return 0; + } + + len = uprog.len * sizeof(struct sock_filter); + code = kmalloc(len, GFP_KERNEL); + if (code == NULL) + return -ENOMEM; + + if (copy_from_user(code, uprog.filter, len)) { + kfree(code); + return -EFAULT; + } + + err = sk_chk_filter(code, uprog.len); + if (err) { + kfree(code); + return err; + } + + *p = code; + return uprog.len; +} + static int ppp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -503,6 +541,8 @@ struct npioctl npi; int unit, cflags; struct slcompress *vj; + void __user *argp = (void __user *)arg; + int __user *p = argp; if (pf == 0) return ppp_unattached_ioctl(pf, file, cmd, arg); @@ -540,7 +580,7 @@ switch (cmd) { case PPPIOCCONNECT: - if (get_user(unit, (int *) arg)) + if (get_user(unit, p)) break; err = ppp_connect_channel(pch, unit); break; @@ -569,14 +609,14 @@ ppp = PF_TO_PPP(pf); switch (cmd) { case PPPIOCSMRU: - if (get_user(val, (int *) arg)) + if (get_user(val, p)) break; ppp->mru = val; err = 0; break; case PPPIOCSFLAGS: - if (get_user(val, (int *) arg)) + if (get_user(val, p)) break; ppp_lock(ppp); cflags = ppp->flags & ~val; @@ -589,7 +629,7 @@ case PPPIOCGFLAGS: val = ppp->flags | ppp->xstate | ppp->rstate; - if (put_user(val, (int *) arg)) + if (put_user(val, p)) break; err = 0; break; @@ -599,20 +639,20 @@ break; case PPPIOCGUNIT: - if (put_user(ppp->file.index, (int *) arg)) + if (put_user(ppp->file.index, p)) break; err = 0; break; case PPPIOCSDEBUG: - if (get_user(val, (int *) arg)) + if (get_user(val, p)) break; ppp->debug = val; err = 0; break; case PPPIOCGDEBUG: - if (put_user(ppp->debug, (int *) arg)) + if (put_user(ppp->debug, p)) break; err = 0; break; @@ -620,13 +660,13 @@ case PPPIOCGIDLE: idle.xmit_idle = (jiffies - ppp->last_xmit) / HZ; idle.recv_idle = (jiffies - ppp->last_recv) / HZ; - if (copy_to_user((void __user *) arg, &idle, sizeof(idle))) + if (copy_to_user(argp, &idle, sizeof(idle))) break; err = 0; break; case PPPIOCSMAXCID: - if (get_user(val, (int *) arg)) + if (get_user(val, p)) break; val2 = 15; if ((val >> 16) != 0) { @@ -649,7 +689,7 @@ case PPPIOCGNPMODE: case PPPIOCSNPMODE: - if (copy_from_user(&npi, (void __user *) arg, sizeof(npi))) + if (copy_from_user(&npi, argp, sizeof(npi))) break; err = proto_to_npindex(npi.protocol); if (err < 0) @@ -658,7 +698,7 @@ if (cmd == PPPIOCGNPMODE) { err = -EFAULT; npi.mode = ppp->npmode[i]; - if (copy_to_user((void __user *) arg, &npi, sizeof(npi))) + if (copy_to_user(argp, &npi, sizeof(npi))) break; } else { ppp->npmode[i] = npi.mode; @@ -670,49 +710,38 @@ #ifdef CONFIG_PPP_FILTER case PPPIOCSPASS: + { + struct sock_filter *code; + err = get_filter(argp, &code); + if (err >= 0) { + ppp_lock(ppp); + kfree(ppp->pass_filter); + ppp->pass_filter = code; + ppp->pass_len = err; + ppp_unlock(ppp); + err = 0; + } + break; + } case PPPIOCSACTIVE: { - struct sock_fprog uprog, *filtp; - struct sock_filter *code = NULL; - int len; - - if (copy_from_user(&uprog, (void __user *) arg, sizeof(uprog))) - break; - err = -EINVAL; - if (uprog.len > BPF_MAXINSNS) - break; - err = -ENOMEM; - if (uprog.len > 0) { - len = uprog.len * sizeof(struct sock_filter); - code = kmalloc(len, GFP_KERNEL); - if (code == NULL) - break; - err = -EFAULT; - if (copy_from_user(code, (void __user *) uprog.filter, len)) { - kfree(code); - break; - } - err = sk_chk_filter(code, uprog.len); - if (err) { - kfree(code); - break; - } + struct sock_filter *code; + err = get_filter(argp, &code); + if (err >= 0) { + ppp_lock(ppp); + kfree(ppp->active_filter); + ppp->active_filter = code; + ppp->active_len = err; + ppp_unlock(ppp); + err = 0; } - filtp = (cmd == PPPIOCSPASS)? &ppp->pass_filter: &ppp->active_filter; - ppp_lock(ppp); - if (filtp->filter) - kfree(filtp->filter); - filtp->filter = code; - filtp->len = uprog.len; - ppp_unlock(ppp); - err = 0; break; } #endif /* CONFIG_PPP_FILTER */ #ifdef CONFIG_PPP_MULTILINK case PPPIOCSMRRU: - if (get_user(val, (int *) arg)) + if (get_user(val, p)) break; ppp_recv_lock(ppp); ppp->mrru = val; @@ -734,11 +763,12 @@ int unit, err = -EFAULT; struct ppp *ppp; struct channel *chan; + int __user *p = (int __user *)arg; switch (cmd) { case PPPIOCNEWUNIT: /* Create a new ppp unit */ - if (get_user(unit, (int *) arg)) + if (get_user(unit, p)) break; ppp = ppp_create_interface(unit, &err); if (ppp == 0) @@ -746,14 +776,14 @@ file->private_data = &ppp->file; ppp->owner = file; err = -EFAULT; - if (put_user(ppp->file.index, (int *) arg)) + if (put_user(ppp->file.index, p)) break; err = 0; break; case PPPIOCATTACH: /* Attach to an existing ppp unit */ - if (get_user(unit, (int *) arg)) + if (get_user(unit, p)) break; down(&all_ppp_sem); err = -ENXIO; @@ -767,7 +797,7 @@ break; case PPPIOCATTCHAN: - if (get_user(unit, (int *) arg)) + if (get_user(unit, p)) break; spin_lock_bh(&all_channels_lock); err = -ENXIO; @@ -999,18 +1029,18 @@ *p = htons(4); /* indicate outbound in DLT_LINUX_SLL */; } - if (ppp->pass_filter.filter - && sk_run_filter(skb, ppp->pass_filter.filter, - ppp->pass_filter.len) == 0) { + if (ppp->pass_filter + && sk_run_filter(skb, ppp->pass_filter, + ppp->pass_len) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: outbound frame not passed\n"); kfree_skb(skb); return; } /* if this packet passes the active filter, record the time */ - if (!(ppp->active_filter.filter - && sk_run_filter(skb, ppp->active_filter.filter, - ppp->active_filter.len) == 0)) + if (!(ppp->active_filter + && sk_run_filter(skb, ppp->active_filter, + ppp->active_len) == 0)) ppp->last_xmit = jiffies; skb_pull(skb, 2); #else @@ -1546,17 +1576,17 @@ *p = 0; /* indicate inbound in DLT_LINUX_SLL */ } - if (ppp->pass_filter.filter - && sk_run_filter(skb, ppp->pass_filter.filter, - ppp->pass_filter.len) == 0) { + if (ppp->pass_filter + && sk_run_filter(skb, ppp->pass_filter, + ppp->pass_len) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: inbound frame not passed\n"); kfree_skb(skb); return; } - if (!(ppp->active_filter.filter - && sk_run_filter(skb, ppp->active_filter.filter, - ppp->active_filter.len) == 0)) + if (!(ppp->active_filter + && sk_run_filter(skb, ppp->active_filter, + ppp->active_len) == 0)) ppp->last_recv = jiffies; skb_pull(skb, 2); #else @@ -2423,13 +2453,13 @@ skb_queue_purge(&ppp->mrq); #endif /* CONFIG_PPP_MULTILINK */ #ifdef CONFIG_PPP_FILTER - if (ppp->pass_filter.filter) { - kfree(ppp->pass_filter.filter); - ppp->pass_filter.filter = NULL; - } - if (ppp->active_filter.filter) { - kfree(ppp->active_filter.filter); - ppp->active_filter.filter = 0; + if (ppp->pass_filter) { + kfree(ppp->pass_filter); + ppp->pass_filter = NULL; + } + if (ppp->active_filter) { + kfree(ppp->active_filter); + ppp->active_filter = 0; } #endif /* CONFIG_PPP_FILTER */ diff -Nru a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c --- a/drivers/net/ppp_synctty.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/ppp_synctty.c 2004-06-26 17:09:17 -07:00 @@ -29,7 +29,7 @@ * PPP driver, written by Michael Callahan and Al Longyear, and * subsequently hacked by Paul Mackerras. * - * ==FILEVERSION 20020125== + * ==FILEVERSION 20040616== */ #include @@ -65,7 +65,9 @@ struct sk_buff *tpkt; unsigned long last_xmit; - struct sk_buff *rpkt; + struct sk_buff_head rqueue; + + struct tasklet_struct tsk; atomic_t refcnt; struct semaphore dead_sem; @@ -88,6 +90,7 @@ static int ppp_sync_send(struct ppp_channel *chan, struct sk_buff *skb); static int ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg); +static void ppp_sync_process(unsigned long arg); static int ppp_sync_push(struct syncppp *ap); static void ppp_sync_flush_output(struct syncppp *ap); static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, @@ -217,6 +220,9 @@ ap->xaccm[3] = 0x60000000U; ap->raccm = ~0U; + skb_queue_head_init(&ap->rqueue); + tasklet_init(&ap->tsk, ppp_sync_process, (unsigned long) ap); + atomic_set(&ap->refcnt, 1); init_MUTEX_LOCKED(&ap->dead_sem); @@ -267,10 +273,10 @@ */ if (!atomic_dec_and_test(&ap->refcnt)) down(&ap->dead_sem); + tasklet_kill(&ap->tsk); ppp_unregister_channel(&ap->chan); - if (ap->rpkt != 0) - kfree_skb(ap->rpkt); + skb_queue_purge(&ap->rqueue); if (ap->tpkt != 0) kfree_skb(ap->tpkt); kfree(ap); @@ -282,7 +288,7 @@ */ static ssize_t ppp_sync_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t count) + unsigned char __user *buf, size_t count) { return -EAGAIN; } @@ -293,7 +299,7 @@ */ static ssize_t ppp_sync_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t count) + const unsigned char __user *buf, size_t count) { return -EAGAIN; } @@ -303,6 +309,7 @@ unsigned int cmd, unsigned long arg) { struct syncppp *ap = sp_get(tty); + int __user *p = (int __user *)arg; int err, val; if (ap == 0) @@ -314,7 +321,7 @@ if (ap == 0) break; err = -EFAULT; - if (put_user(ppp_channel_index(&ap->chan), (int *) arg)) + if (put_user(ppp_channel_index(&ap->chan), p)) break; err = 0; break; @@ -324,7 +331,7 @@ if (ap == 0) break; err = -EFAULT; - if (put_user(ppp_unit_number(&ap->chan), (int *) arg)) + if (put_user(ppp_unit_number(&ap->chan), p)) break; err = 0; break; @@ -343,7 +350,7 @@ case FIONREAD: val = 0; - if (put_user(val, (int *) arg)) + if (put_user(val, p)) break; err = 0; break; @@ -369,17 +376,24 @@ return 65535; } +/* + * This can now be called from hard interrupt level as well + * as soft interrupt level or mainline. + */ static void ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, - char *flags, int count) + char *cflags, int count) { struct syncppp *ap = sp_get(tty); + unsigned long flags; if (ap == 0) return; - spin_lock_bh(&ap->recv_lock); - ppp_sync_input(ap, buf, flags, count); - spin_unlock_bh(&ap->recv_lock); + spin_lock_irqsave(&ap->recv_lock, flags); + ppp_sync_input(ap, buf, cflags, count); + spin_unlock_irqrestore(&ap->recv_lock, flags); + if (skb_queue_len(&ap->rqueue)) + tasklet_schedule(&ap->tsk); sp_put(ap); if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && tty->driver->unthrottle) @@ -394,8 +408,8 @@ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); if (ap == 0) return; - if (ppp_sync_push(ap)) - ppp_output_wakeup(&ap->chan); + set_bit(XMIT_WAKEUP, &ap->xmit_flags); + tasklet_schedule(&ap->tsk); sp_put(ap); } @@ -436,54 +450,56 @@ struct syncppp *ap = chan->private; int err, val; u32 accm[8]; + void __user *argp = (void __user *)arg; + u32 __user *p = argp; err = -EFAULT; switch (cmd) { case PPPIOCGFLAGS: val = ap->flags | ap->rbits; - if (put_user(val, (int *) arg)) + if (put_user(val, (int __user *) argp)) break; err = 0; break; case PPPIOCSFLAGS: - if (get_user(val, (int *) arg)) + if (get_user(val, (int __user *) argp)) break; ap->flags = val & ~SC_RCV_BITS; - spin_lock_bh(&ap->recv_lock); + spin_lock_irq(&ap->recv_lock); ap->rbits = val & SC_RCV_BITS; - spin_unlock_bh(&ap->recv_lock); + spin_unlock_irq(&ap->recv_lock); err = 0; break; case PPPIOCGASYNCMAP: - if (put_user(ap->xaccm[0], (u32 *) arg)) + if (put_user(ap->xaccm[0], p)) break; err = 0; break; case PPPIOCSASYNCMAP: - if (get_user(ap->xaccm[0], (u32 *) arg)) + if (get_user(ap->xaccm[0], p)) break; err = 0; break; case PPPIOCGRASYNCMAP: - if (put_user(ap->raccm, (u32 *) arg)) + if (put_user(ap->raccm, p)) break; err = 0; break; case PPPIOCSRASYNCMAP: - if (get_user(ap->raccm, (u32 *) arg)) + if (get_user(ap->raccm, p)) break; err = 0; break; case PPPIOCGXASYNCMAP: - if (copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm))) + if (copy_to_user(argp, ap->xaccm, sizeof(ap->xaccm))) break; err = 0; break; case PPPIOCSXASYNCMAP: - if (copy_from_user(accm, (void *) arg, sizeof(accm))) + if (copy_from_user(accm, argp, sizeof(accm))) break; accm[2] &= ~0x40000000U; /* can't escape 0x5e */ accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ @@ -492,12 +508,12 @@ break; case PPPIOCGMRU: - if (put_user(ap->mru, (int *) arg)) + if (put_user(ap->mru, (int __user *) argp)) break; err = 0; break; case PPPIOCSMRU: - if (get_user(val, (int *) arg)) + if (get_user(val, (int __user *) argp)) break; if (val < PPP_MRU) val = PPP_MRU; @@ -512,6 +528,32 @@ } /* + * This is called at softirq level to deliver received packets + * to the ppp_generic code, and to tell the ppp_generic code + * if we can accept more output now. + */ +static void ppp_sync_process(unsigned long arg) +{ + struct syncppp *ap = (struct syncppp *) arg; + struct sk_buff *skb; + + /* process received packets */ + while ((skb = skb_dequeue(&ap->rqueue)) != NULL) { + if (skb->len == 0) { + /* zero length buffers indicate error */ + ppp_input_error(&ap->chan, 0); + kfree_skb(skb); + } + else + ppp_input(&ap->chan, skb); + } + + /* try to push more stuff out */ + if (test_bit(XMIT_WAKEUP, &ap->xmit_flags) && ppp_sync_push(ap)) + ppp_output_wakeup(&ap->chan); +} + +/* * Procedures for encapsulation and framing. */ @@ -600,7 +642,6 @@ struct tty_struct *tty = ap->tty; int tty_stuffed = 0; - set_bit(XMIT_WAKEUP, &ap->xmit_flags); if (!spin_trylock_bh(&ap->xmit_lock)) return 0; for (;;) { @@ -667,15 +708,44 @@ * Receive-side routines. */ -static inline void -process_input_packet(struct syncppp *ap) +/* called when the tty driver has data for us. + * + * Data is frame oriented: each call to ppp_sync_input is considered + * a whole frame. If the 1st flag byte is non-zero then the whole + * frame is considered to be in error and is tossed. + */ +static void +ppp_sync_input(struct syncppp *ap, const unsigned char *buf, + char *flags, int count) { struct sk_buff *skb; unsigned char *p; - int code = 0; - skb = ap->rpkt; - ap->rpkt = 0; + if (count == 0) + return; + + if (ap->flags & SC_LOG_INPKT) + ppp_print_buffer ("receive buffer", buf, count); + + /* stuff the chars in the skb */ + if ((skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2)) == 0) { + printk(KERN_ERR "PPPsync: no memory (input pkt)\n"); + goto err; + } + /* Try to get the payload 4-byte aligned */ + if (buf[0] != PPP_ALLSTATIONS) + skb_reserve(skb, 2 + (buf[0] & 1)); + + if (flags != 0 && *flags) { + /* error flag set, ignore frame */ + goto err; + } else if (count > skb_tailroom(skb)) { + /* packet overflowed MRU */ + goto err; + } + + p = skb_put(skb, count); + memcpy(p, buf, count); /* strip address/control field if present */ p = skb->data; @@ -693,59 +763,15 @@ } else if (skb->len < 2) goto err; - /* pass to generic layer */ - ppp_input(&ap->chan, skb); + /* queue the frame to be processed */ + skb_queue_tail(&ap->rqueue, skb); return; - err: - kfree_skb(skb); - ppp_input_error(&ap->chan, code); -} - -/* called when the tty driver has data for us. - * - * Data is frame oriented: each call to ppp_sync_input is considered - * a whole frame. If the 1st flag byte is non-zero then the whole - * frame is considered to be in error and is tossed. - */ -static void -ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - char *flags, int count) -{ - struct sk_buff *skb; - unsigned char *sp; - - if (count == 0) - return; - - /* if flag set, then error, ignore frame */ - if (flags != 0 && *flags) { - ppp_input_error(&ap->chan, *flags); - return; - } - - if (ap->flags & SC_LOG_INPKT) - ppp_print_buffer ("receive buffer", buf, count); - - /* stuff the chars in the skb */ - if ((skb = ap->rpkt) == 0) { - if ((skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2)) == 0) { - printk(KERN_ERR "PPPsync: no memory (input pkt)\n"); - ppp_input_error(&ap->chan, 0); - return; - } - /* Try to get the payload 4-byte aligned */ - if (buf[0] != PPP_ALLSTATIONS) - skb_reserve(skb, 2 + (buf[0] & 1)); - ap->rpkt = skb; - } - if (count > skb_tailroom(skb)) { - /* packet overflowed MRU */ - ppp_input_error(&ap->chan, 1); - } else { - sp = skb_put(skb, count); - memcpy(sp, buf, count); - process_input_packet(ap); +err: + /* queue zero length packet as error indication */ + if (skb || (skb = dev_alloc_skb(0))) { + skb_trim(skb, 0); + skb_queue_tail(&ap->rqueue, skb); } } diff -Nru a/drivers/net/pppoe.c b/drivers/net/pppoe.c --- a/drivers/net/pppoe.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/pppoe.c 2004-06-26 17:09:19 -07:00 @@ -691,7 +691,7 @@ if (put_user(po->pppoe_dev->mtu - sizeof(struct pppoe_hdr) - PPP_HDRLEN, - (int *) arg)) + (int __user *) arg)) break; err = 0; break; @@ -702,7 +702,7 @@ break; err = -EFAULT; - if (get_user(val,(int *) arg)) + if (get_user(val,(int __user *) arg)) break; if (val < (po->pppoe_dev->mtu @@ -715,7 +715,7 @@ case PPPIOCSFLAGS: err = -EFAULT; - if (get_user(val, (int *) arg)) + if (get_user(val, (int __user *) arg)) break; err = 0; break; @@ -736,7 +736,7 @@ PPPoE address to which frames are forwarded to */ err = -EFAULT; if (copy_from_user(&po->pppoe_relay, - (void*)arg, + (void __user *)arg, sizeof(struct sockaddr_pppox))) break; diff -Nru a/drivers/net/pppox.c b/drivers/net/pppox.c --- a/drivers/net/pppox.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/pppox.c 2004-06-26 17:09:20 -07:00 @@ -86,7 +86,7 @@ rc = -EINVAL; index = ppp_channel_index(&po->chan); - if (put_user(index , (int *) arg)) + if (put_user(index , (int __user *) arg)) break; rc = 0; diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c --- a/drivers/net/r8169.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/r8169.c 2004-06-26 17:09:18 -07:00 @@ -716,7 +716,7 @@ goto err_out_disable; } - rc = pci_request_regions(pdev, dev->name); + rc = pci_request_regions(pdev, MODULENAME); if (rc) { printk(KERN_ERR PFX "%s: Could not request regions.\n", pdev->slot_name); goto err_out_disable; diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c --- a/drivers/net/s2io.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/s2io.c 2004-06-26 17:09:19 -07:00 @@ -1425,13 +1425,13 @@ goto end; } - skb = dev_alloc_skb(size + HEADER_ALIGN_LAYER_3); + skb = dev_alloc_skb(size + NET_IP_ALIGN); if (!skb) { DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); return -ENOMEM; } - skb_reserve(skb, HEADER_ALIGN_LAYER_3); + skb_reserve(skb, NET_IP_ALIGN); memset(rxdp, 0, sizeof(RxD_t)); rxdp->Buffer0_ptr = pci_map_single (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE); diff -Nru a/drivers/net/s2io.h b/drivers/net/s2io.h --- a/drivers/net/s2io.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/s2io.h 2004-06-26 17:09:16 -07:00 @@ -411,7 +411,6 @@ #define HEADER_802_2_SIZE 3 #define HEADER_SNAP_SIZE 5 #define HEADER_VLAN_SIZE 4 -#define HEADER_ALIGN_LAYER_3 2 #define MIN_MTU 46 #define MAX_PYLD 1500 diff -Nru a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c --- a/drivers/net/sb1250-mac.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/sb1250-mac.c 2004-06-26 17:09:20 -07:00 @@ -2900,15 +2900,15 @@ sbmac_cleanup_module(void) { struct net_device *dev; - sbmac_port_t port; int idx; for (idx = 0; idx < MAX_UNITS; idx++) { + struct sbmac_softc *sc; dev = dev_sbmac[idx]; if (!dev) continue; - struct sbmac_softc *sc = netdev_priv(dev); + sc = netdev_priv(dev); unregister_netdev(dev); sbmac_uninitctx(sc); free_netdev(dev); diff -Nru a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c --- a/drivers/net/sgiseeq.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/sgiseeq.c 2004-06-26 17:09:20 -07:00 @@ -64,13 +64,13 @@ #define DEBUG struct sgiseeq_rx_desc { - struct hpc_dma_desc rdma; - signed int buf_vaddr; + volatile struct hpc_dma_desc rdma; + volatile signed int buf_vaddr; }; struct sgiseeq_tx_desc { - struct hpc_dma_desc tdma; - signed int buf_vaddr; + volatile struct hpc_dma_desc tdma; + volatile signed int buf_vaddr; }; /* @@ -79,17 +79,17 @@ * some care. */ struct sgiseeq_init_block { /* Note the name ;-) */ - /* Ptrs to the descriptors in KSEG1 uncached space. */ - struct sgiseeq_rx_desc *rx_desc; - struct sgiseeq_tx_desc *tx_desc; - unsigned int _padding[30]; /* Pad out to largest cache line size. */ - struct sgiseeq_rx_desc rxvector[SEEQ_RX_BUFFERS]; struct sgiseeq_tx_desc txvector[SEEQ_TX_BUFFERS]; }; struct sgiseeq_private { - volatile struct sgiseeq_init_block srings; + struct sgiseeq_init_block *srings; + + /* Ptrs to the descriptors in uncached space. */ + struct sgiseeq_rx_desc *rx_desc; + struct sgiseeq_tx_desc *tx_desc; + char *name; struct hpc3_ethregs *hregs; struct sgiseeq_regs *sregs; @@ -152,8 +152,7 @@ static int seeq_init_ring(struct net_device *dev) { - struct sgiseeq_private *sp = dev->priv; - volatile struct sgiseeq_init_block *ib = &sp->srings; + struct sgiseeq_private *sp = netdev_priv(dev); int i; netif_stop_queue(dev); @@ -170,32 +169,32 @@ /* Setup tx ring. */ for(i = 0; i < SEEQ_TX_BUFFERS; i++) { - if (!ib->tx_desc[i].tdma.pbuf) { + if (!sp->tx_desc[i].tdma.pbuf) { unsigned long buffer; buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); if (!buffer) return -ENOMEM; - ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer); - ib->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer); + sp->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer); + sp->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer); } - ib->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT; + sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT; } /* And now the rx ring. */ for (i = 0; i < SEEQ_RX_BUFFERS; i++) { - if (!ib->rx_desc[i].rdma.pbuf) { + if (!sp->rx_desc[i].rdma.pbuf) { unsigned long buffer; buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); if (!buffer) return -ENOMEM; - ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer); - ib->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer); + sp->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer); + sp->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer); } - ib->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT; + sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT; } - ib->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR; + sp->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR; return 0; } @@ -206,8 +205,8 @@ void sgiseeq_dump_rings(void) { static int once; - struct sgiseeq_rx_desc *r = gpriv->srings.rx_desc; - struct sgiseeq_tx_desc *t = gpriv->srings.tx_desc; + struct sgiseeq_rx_desc *r = gpriv->rx_desc; + struct sgiseeq_tx_desc *t = gpriv->tx_desc; struct hpc3_ethregs *hregs = gpriv->hregs; int i; @@ -268,8 +267,8 @@ hregs->rx_dconfig |= RDMACFG_INIT; - hregs->rx_ndptr = CPHYSADDR(sp->srings.rx_desc); - hregs->tx_ndptr = CPHYSADDR(sp->srings.tx_desc); + hregs->rx_ndptr = CPHYSADDR(sp->rx_desc); + hregs->tx_ndptr = CPHYSADDR(sp->tx_desc); seeq_go(sp, hregs, sregs); return 0; @@ -294,14 +293,14 @@ struct sgiseeq_regs *sregs) { if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) { - hregs->rx_ndptr = CPHYSADDR(sp->srings.rx_desc + sp->rx_new); + hregs->rx_ndptr = CPHYSADDR(sp->rx_desc + sp->rx_new); seeq_go(sp, hregs, sregs); } } -#define for_each_rx(rd, sp) for((rd) = &(sp)->srings.rx_desc[(sp)->rx_new]; \ +#define for_each_rx(rd, sp) for((rd) = &(sp)->rx_desc[(sp)->rx_new]; \ !((rd)->rdma.cntinfo & HPCDMA_OWN); \ - (rd) = &(sp)->srings.rx_desc[(sp)->rx_new]) + (rd) = &(sp)->rx_desc[(sp)->rx_new]) static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, struct hpc3_ethregs *hregs, @@ -349,8 +348,8 @@ rd->rdma.cntinfo = RCNTINFO_INIT; sp->rx_new = NEXT_RX(sp->rx_new); } - sp->srings.rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR); - sp->srings.rx_desc[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR; + sp->rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR); + sp->rx_desc[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR; rx_maybe_restart(sp, hregs, sregs); } @@ -403,7 +402,7 @@ /* Ack 'em... */ for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) { - td = &sp->srings.tx_desc[j]; + td = &sp->tx_desc[j]; if (!(td->tdma.cntinfo & (HPCDMA_XIU))) break; @@ -424,7 +423,7 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct sgiseeq_private *sp = dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct hpc3_ethregs *hregs = sp->hregs; struct sgiseeq_regs *sregs = sp->sregs; @@ -450,21 +449,33 @@ static int sgiseeq_open(struct net_device *dev) { - struct sgiseeq_private *sp = dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct sgiseeq_regs *sregs = sp->sregs; + unsigned int irq = dev->irq; + int err; - int err = init_seeq(dev, sp, sregs); + if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { + printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq); + err = -EAGAIN; + } + + err = init_seeq(dev, sp, sregs); if (err) - return err; + goto out_free_irq; netif_start_queue(dev); return 0; + +out_free_irq: + free_irq(irq, dev); + + return err; } static int sgiseeq_close(struct net_device *dev) { - struct sgiseeq_private *sp = dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct sgiseeq_regs *sregs = sp->sregs; netif_stop_queue(dev); @@ -477,7 +488,7 @@ static inline int sgiseeq_reset(struct net_device *dev) { - struct sgiseeq_private *sp = dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct sgiseeq_regs *sregs = sp->sregs; int err; @@ -499,7 +510,7 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct sgiseeq_private *sp = dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct hpc3_ethregs *hregs = sp->hregs; unsigned long flags; struct sgiseeq_tx_desc *td; @@ -512,7 +523,7 @@ len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; sp->stats.tx_bytes += len; entry = sp->tx_new; - td = &sp->srings.tx_desc[entry]; + td = &sp->tx_desc[entry]; /* Create entry. There are so many races with adding a new * descriptor to the chain: @@ -535,14 +546,14 @@ if (sp->tx_old != sp->tx_new) { struct sgiseeq_tx_desc *backend; - backend = &sp->srings.tx_desc[PREV_TX(sp->tx_new)]; + backend = &sp->tx_desc[PREV_TX(sp->tx_new)]; backend->tdma.cntinfo &= ~HPCDMA_EOX; } sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */ /* Maybe kick the HPC back into motion. */ if (!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE)) - kick_tx(&sp->srings.tx_desc[sp->tx_old], hregs); + kick_tx(&sp->tx_desc[sp->tx_old], hregs); dev->trans_start = jiffies; dev_kfree_skb(skb); @@ -565,7 +576,7 @@ static struct net_device_stats *sgiseeq_get_stats(struct net_device *dev) { - struct sgiseeq_private *sp = dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); return &sp->stats; } @@ -601,31 +612,29 @@ #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) -int sgiseeq_init(struct hpc3_regs* regs, int irq) +static int sgiseeq_init(struct hpc3_regs* regs, int irq) { - struct net_device *dev; + struct sgiseeq_init_block *sr; struct sgiseeq_private *sp; + struct net_device *dev; int err, i; - dev = alloc_etherdev(0); + dev = alloc_etherdev(sizeof (struct sgiseeq_private)); if (!dev) { printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n"); err = -ENOMEM; goto err_out; } + sp = netdev_priv(dev); + /* Make private data page aligned */ - sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); - if (!sp) { + sr = (struct sgiseeq_init_block *) get_zeroed_page(GFP_KERNEL); + if (!sr) { printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n"); err = -ENOMEM; goto err_out_free_dev; } - - if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { - printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq); - err = -EAGAIN; - goto err_out_free_page; - } + sp->srings = sr; #define EADDR_NVOFS 250 for (i = 0; i < 3; i++) { @@ -643,18 +652,18 @@ sp->hregs = &hpc3c0->ethregs; sp->name = sgiseeqstr; - sp->srings.rx_desc = (struct sgiseeq_rx_desc *) - KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0])); - dma_cache_wback_inv((unsigned long)&sp->srings.rxvector, - sizeof(sp->srings.rxvector)); - sp->srings.tx_desc = (struct sgiseeq_tx_desc *) - KSEG1ADDR(ALIGNED(&sp->srings.txvector[0])); - dma_cache_wback_inv((unsigned long)&sp->srings.txvector, - sizeof(sp->srings.txvector)); + sp->rx_desc = (struct sgiseeq_rx_desc *) + KSEG1ADDR(ALIGNED(&sp->srings->rxvector[0])); + dma_cache_wback_inv((unsigned long)&sp->srings->rxvector, + sizeof(sp->srings->rxvector)); + sp->tx_desc = (struct sgiseeq_tx_desc *) + KSEG1ADDR(ALIGNED(&sp->srings->txvector[0])); + dma_cache_wback_inv((unsigned long)&sp->srings->txvector, + sizeof(sp->srings->txvector)); /* A couple calculations now, saves many cycles later. */ - setup_rx_ring(sp->srings.rx_desc, SEEQ_RX_BUFFERS); - setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS); + setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS); + setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS); /* Reset the chip. */ hpc3_eth_reset(sp->hregs); @@ -673,14 +682,12 @@ dev->get_stats = sgiseeq_get_stats; dev->set_multicast_list = sgiseeq_set_multicast; dev->irq = irq; - dev->dma = 0; - dev->priv = sp; if (register_netdev(dev)) { printk(KERN_ERR "Sgiseeq: Cannot register net device, " "aborting.\n"); err = -ENODEV; - goto err_out_free_irq; + goto err_out_free_page; } printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name); @@ -692,8 +699,6 @@ return 0; -err_out_free_irq: - free_irq(irq, dev); err_out_free_page: free_page((unsigned long) sp); err_out_free_dev: @@ -718,12 +723,12 @@ int irq; for (dev = root_sgiseeq_dev; dev; dev = next) { - sp = (struct sgiseeq_private *) dev->priv; + sp = (struct sgiseeq_private *) netdev_priv(dev); next = sp->next_module; irq = dev->irq; unregister_netdev(dev); free_irq(irq, dev); - free_page((unsigned long) dev->priv); + free_page((unsigned long) sp); free_netdev(dev); } } diff -Nru a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h --- a/drivers/net/sk98lin/h/skdrv2nd.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/sk98lin/h/skdrv2nd.h 2004-06-26 17:09:21 -07:00 @@ -58,7 +58,8 @@ /* 3Com (0x10b7) */ \ if (pdev->vendor == 0x10b7) { \ /* Gigabit Ethernet Adapter (0x1700) */ \ - if ((pdev->device == 0x1700)) { \ + if ((pdev->device == 0x1700) || \ + (pdev->device == 0x80eb)) { \ result = SK_TRUE; \ } \ /* SysKonnect (0x1148) */ \ @@ -169,7 +170,7 @@ typedef struct s_IOCTL SK_GE_IOCTL; struct s_IOCTL { - char* pData; + char __user * pData; unsigned int Len; }; diff -Nru a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c --- a/drivers/net/skfp/cfm.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/skfp/cfm.c 2004-06-26 17:09:18 -07:00 @@ -96,14 +96,13 @@ /* * function declarations */ -static void cfm_fsm() ; +static void cfm_fsm(struct s_smc *smc, int cmd); /* init CFM state machine clear all CFM vars and flags */ -void cfm_init(smc) -struct s_smc *smc ; +void cfm_init(struct s_smc *smc) { smc->mib.fddiSMTCF_State = ACTIONS(SC0_ISOLATED) ; smc->r.rm_join = 0 ; @@ -118,9 +117,7 @@ #define THRU_ENABLED(smc) (smc->y[PA].pc_mode != PM_TREE && \ smc->y[PB].pc_mode != PM_TREE) /* Selection criteria for the ports */ -static void selection_criteria (smc,phy) -struct s_smc *smc ; -struct s_phy *phy ; +static void selection_criteria (struct s_smc *smc, struct s_phy *phy) { switch (phy->mib->fddiPORTMy_Type) { @@ -146,8 +143,7 @@ } -void all_selection_criteria (smc) -struct s_smc *smc ; +void all_selection_criteria(struct s_smc *smc) { struct s_phy *phy ; int p ; @@ -158,9 +154,7 @@ } } -static void cem_priv_state (smc, event) -struct s_smc *smc ; -int event ; +static void cem_priv_state(struct s_smc *smc, int event) /* State machine for private PORT states: used to optimize dual homing */ { int np; /* Number of the port */ @@ -216,9 +210,7 @@ process event until SM is stable */ -void cfm(smc,event) -struct s_smc *smc ; -int event ; +void cfm(struct s_smc *smc, int event) { int state ; /* remember last state */ int cond ; @@ -290,9 +282,7 @@ process CFM event */ /*ARGSUSED1*/ -static void cfm_fsm(smc,cmd) -struct s_smc *smc ; -int cmd ; +static void cfm_fsm(struct s_smc *smc, int cmd) { switch(smc->mib.fddiSMTCF_State) { case ACTIONS(SC0_ISOLATED) : @@ -550,8 +540,7 @@ * return : * PA or PB */ -int cfm_get_mac_input(smc) -struct s_smc *smc ; +int cfm_get_mac_input(struct s_smc *smc) { return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA) ; @@ -562,8 +551,7 @@ * return : * PA or PB */ -int cfm_get_mac_output(smc) -struct s_smc *smc ; +int cfm_get_mac_output(struct s_smc *smc) { return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA) ; @@ -603,10 +591,7 @@ 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_ISO, } ; -int cem_build_path(smc,to,path_index) -struct s_smc *smc ; -char *to ; -int path_index ; +int cem_build_path(struct s_smc *smc, char *to, int path_index) { char *path ; int len ; diff -Nru a/drivers/net/skfp/drvfbi.c b/drivers/net/skfp/drvfbi.c --- a/drivers/net/skfp/drvfbi.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/skfp/drvfbi.c 2004-06-26 17:09:15 -07:00 @@ -100,14 +100,13 @@ #endif /* MULT_OEM */ /* Prototypes of external functions */ -extern void hwt_restart() ; #ifdef AIX extern int AIX_vpdReadByte() ; #endif /* Prototypes of local functions. */ -void smt_stop_watchdog() ; +void smt_stop_watchdog(struct s_smc *smc); #ifdef MCA static int read_card_id() ; @@ -129,8 +128,7 @@ /* * FDDI card reset */ -static void card_start(smc) -struct s_smc *smc ; +static void card_start(struct s_smc *smc) { int i ; #ifdef PCI @@ -250,8 +248,7 @@ GET_PAGE(0) ; /* necessary for BOOT */ } -void card_stop(smc) -struct s_smc *smc ; +void card_stop(struct s_smc *smc) { smt_stop_watchdog(smc) ; smc->hw.mac_ring_is_up = 0 ; /* ring down */ @@ -282,14 +279,11 @@ } /*--------------------------- ISR handling ----------------------------------*/ -#ifndef PCI -void mac1_irq(smc,stu, stl) -struct s_smc *smc ; -u_short stu; -u_short stl; +void mac1_irq(struct s_smc *smc, u_short stu, u_short stl) { int restart_tx = 0 ; again: +#ifndef PCI #ifndef ISA /* * FORMAC+ bug modified the queue pointer if many read/write accesses happens!? @@ -344,14 +338,6 @@ } #else /* PCI */ -void mac1_irq(smc,stu, stl) -struct s_smc *smc ; -u_short stu; -u_short stl; -{ - int restart_tx = 0 ; -again: - /* * parity error: note encoding error is not possible in tag mode */ @@ -396,8 +382,7 @@ * interrupt source= plc1 * this function is called in nwfbisr.asm */ -void plc1_irq(smc) -struct s_smc *smc ; +void plc1_irq(struct s_smc *smc) { u_short st = inpw(PLC(PB,PL_INTR_EVENT)) ; @@ -412,8 +397,7 @@ * interrupt source= plc2 * this function is called in nwfbisr.asm */ -void plc2_irq(smc) -struct s_smc *smc ; +void plc2_irq(struct s_smc *smc) { u_short st = inpw(PLC(PA,PL_INTR_EVENT)) ; @@ -428,8 +412,7 @@ /* * interrupt source= timer */ -void timer_irq(smc) -struct s_smc *smc ; +void timer_irq(struct s_smc *smc) { hwt_restart(smc); smc->hw.t_stop = smc->hw.t_start; @@ -439,8 +422,7 @@ /* * return S-port (PA or PB) */ -int pcm_get_s_port(smc) -struct s_smc *smc ; +int pcm_get_s_port(struct s_smc *smc) { SK_UNUSED(smc) ; return(PS) ; @@ -457,9 +439,7 @@ #define STATION_LABEL_PMD_OFFSET 6 #define STATION_LABEL_PORT_OFFSET 7 -void read_address(smc,mac_addr) -struct s_smc *smc ; -u_char *mac_addr ; +void read_address(struct s_smc *smc, u_char *mac_addr) { char ConnectorType ; char PmdType ; @@ -528,9 +508,7 @@ /* * FDDI card soft reset */ -void init_board(smc,mac_addr) -struct s_smc *smc ; -u_char *mac_addr ; +void init_board(struct s_smc *smc, u_char *mac_addr) { card_start(smc) ; read_address(smc,mac_addr) ; @@ -559,9 +537,7 @@ /* * insert or deinsert optical bypass (called by ECM) */ -void sm_pm_bypass_req(smc,mode) -struct s_smc *smc ; -int mode; +void sm_pm_bypass_req(struct s_smc *smc, int mode) { #if (defined(ISA) || defined(EISA)) int csra_v ; @@ -614,8 +590,7 @@ /* * check if bypass connected */ -int sm_pm_bypass_present(smc) -struct s_smc *smc ; +int sm_pm_bypass_present(struct s_smc *smc) { #ifndef PCI return( (inpw(CSR_A) & CS_BYSTAT) ? FALSE : TRUE ) ; @@ -624,9 +599,7 @@ #endif } -void plc_clear_irq(smc,p) -struct s_smc *smc ; -int p ; +void plc_clear_irq(struct s_smc *smc, int p) { SK_UNUSED(p) ; @@ -658,9 +631,7 @@ * LED_Y_OFF just switch yellow LED off * LED_Y_ON just switch yello LED on */ -void led_indication(smc,led_event) -struct s_smc *smc ; -int led_event; +void led_indication(struct s_smc *smc, int led_event) { /* use smc->hw.mac_ring_is_up == TRUE * as indication for Ring Operational @@ -754,10 +725,7 @@ } -void pcm_state_change(smc,plc,p_state) -struct s_smc *smc; -int plc; -int p_state; +void pcm_state_change(struct s_smc *smc, int plc, int p_state) { /* * the current implementation of pcm_state_change() in the driver @@ -770,9 +738,7 @@ } -void rmt_indication(smc,i) -struct s_smc *smc ; -int i; +void rmt_indication(struct s_smc *smc, int i) { /* Call a driver special function if defined */ DRV_RMT_INDICATION(smc,i) ; @@ -784,8 +750,7 @@ /* * llc_recover_tx called by init_tx (fplus.c) */ -void llc_recover_tx(smc) -struct s_smc *smc ; +void llc_recover_tx(struct s_smc *smc) { #ifdef LOAD_GEN extern int load_gen_flag ; @@ -805,9 +770,7 @@ /* * init DMA */ -void init_dma(smc,dma) -struct s_smc *smc; -int dma; +void init_dma(struct s_smc *smc, int dma) { SK_UNUSED(smc) ; @@ -828,9 +791,7 @@ /* * disable DMA */ -void dis_dma(smc,dma) -struct s_smc *smc ; -int dma; +void dis_dma(struct s_smc *smc, int dma) { SK_UNUSED(smc) ; @@ -854,9 +815,7 @@ static const int base[8] = { 0x000,0x002,0x004,0x006,0,0x0c4,0x0c8,0x0cc } ; static const int page[8] = { 0x087,0x083,0x081,0x082,0,0x08b,0x089,0x08a } ; -void init_dma(smc,dma) -struct s_smc *smc ; -int dma; +void init_dma(struct s_smc *smc, int dma) { /* * extended mode register @@ -885,9 +844,7 @@ } -void dis_dma(smc,dma) -struct s_smc *smc ; -int dma; +void dis_dma(struct s_smc *smc, int dma) { SK_UNUSED(smc) ; @@ -896,16 +853,13 @@ #endif /* EISA */ #ifdef MCA -void init_dma(smc,dma) -struct s_smc *smc; -int dma; +void init_dma(struct s_smc *smc, int dma) { SK_UNUSED(smc) ; SK_UNUSED(dma) ; } -void dis_dma(smc,dma) -struct s_smc *smc; -int dma; + +void dis_dma(struct s_smc *smc, int dma) { SK_UNUSED(smc) ; SK_UNUSED(dma) ; @@ -913,16 +867,13 @@ #endif #ifdef PCI -void init_dma(smc,dma) -struct s_smc *smc; -int dma; +void init_dma(struct s_smc *smc, int dma) { SK_UNUSED(smc) ; SK_UNUSED(dma) ; } -void dis_dma(smc,dma) -struct s_smc *smc; -int dma; + +void dis_dma(struct s_smc *smc, int dma) { SK_UNUSED(smc) ; SK_UNUSED(dma) ; @@ -930,10 +881,7 @@ #endif #ifdef MULT_OEM -static int is_equal_num(comp1,comp2,num) -char comp1[] ; -char comp2[] ; -int num ; +static int is_equal_num(char comp1[], char comp2[], int num) { int i ; @@ -954,8 +902,7 @@ * 2 data base empty * 3 no active entry */ -int set_oi_id_def(smc) -struct s_smc *smc ; +int set_oi_id_def(struct s_smc *smc) { int sel_id ; int i ; @@ -1029,9 +976,7 @@ * ************************/ #define LONG_CARD_ID(lo, hi) ((((hi) & 0xff) << 8) | ((lo) & 0xff)) -int exist_board(smc,slot) -struct s_smc *smc ; -int slot ; +int exist_board(struct s_smc *smc, int slot) { #ifdef MULT_OEM SK_LOC_DECL(u_char,id[2]) ; @@ -1081,9 +1026,8 @@ * number is specified, the function returns zero. * ************************/ -static int read_card_id(smc,slot) -struct s_smc *smc ; /* Do not use. */ -int slot ; +static int read_card_id(struct s_smc *smc, int slot) +/* struct s_smc *smc ; Do not use. */ { int card_id ; @@ -1126,9 +1070,7 @@ * END_MANUAL_ENTRY() * ************************/ -int get_board_para(smc,slot) -struct s_smc *smc ; -int slot ; +int get_board_para(struct s_smc *smc, int slot) { int val ; int i ; @@ -1175,9 +1117,7 @@ } /* Enable access to specified MCA slot. */ -static void EnableSlotAccess(smc,slot) -struct s_smc *smc ; -int slot ; +static void EnableSlotAccess(struct s_smc *smc, int slot) { SK_UNUSED(slot) ; @@ -1195,8 +1135,7 @@ } /* Disable access to MCA slot formerly enabled via EnableSlotAccess(). */ -static void DisableSlotAccess(smc) -struct s_smc *smc ; +static void DisableSlotAccess(struct s_smc *smc) { #ifndef AIX SK_UNUSED(smc) ; @@ -1245,9 +1184,7 @@ * The smc pointer must be valid now. * ************************/ -int exist_board(smc,slot) -struct s_smc *smc ; -int slot ; +int exist_board(struct s_smc *smc, int slot) { int i ; #ifdef MULT_OEM @@ -1284,9 +1221,7 @@ } -int get_board_para(smc,slot) -struct s_smc *smc ; -int slot ; +int get_board_para(struct s_smc *smc, int slot) { int i ; @@ -1327,9 +1262,7 @@ #endif /* MULT_OEM */ -int exist_board(smc,port) -struct s_smc *smc ; -HW_PTR port ; +int exist_board(struct s_smc *smc, HW_PTR port) { int i ; #ifdef MULT_OEM @@ -1400,9 +1333,7 @@ #endif /* MULT_OEM */ } -int get_board_para(smc,slot) -struct s_smc *smc ; -int slot ; +int get_board_para(struct s_smc *smc, int slot) { SK_UNUSED(smc) ; SK_UNUSED(slot) ; @@ -1412,9 +1343,7 @@ #ifdef PCI #ifdef USE_BIOS_FUN -int exist_board(smc,slot) -struct s_smc *smc ; -int slot ; +int exist_board(struct s_smc *smc, int slot) { u_short dev_id ; u_short ven_id ; @@ -1452,9 +1381,7 @@ #endif /* PCI */ #endif /* USE_BIOS_FUNC */ -void driver_get_bia(smc, bia_addr) -struct s_smc *smc ; -struct fddi_addr *bia_addr ; +void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr) { int i ; @@ -1465,8 +1392,7 @@ } } -void smt_start_watchdog(smc) -struct s_smc *smc ; +void smt_start_watchdog(struct s_smc *smc) { SK_UNUSED(smc) ; /* Make LINT happy. */ @@ -1481,8 +1407,7 @@ #endif /* DEBUG */ } -void smt_stop_watchdog(smc) -struct s_smc *smc ; +void smt_stop_watchdog(struct s_smc *smc) { SK_UNUSED(smc) ; /* Make LINT happy. */ #ifndef DEBUG @@ -1497,9 +1422,7 @@ } #ifdef PCI -static char get_rom_byte(smc,addr) -struct s_smc *smc ; -u_short addr ; +static char get_rom_byte(struct s_smc *smc, u_short addr) { GET_PAGE(addr) ; return (READ_PROM(ADDR(B2_FDP))) ; @@ -1544,11 +1467,7 @@ * * END_MANUAL_ENTRY */ -int mac_drv_vpd_read(smc,buf,size,image) -struct s_smc *smc ; -char *buf ; -int size ; -char image ; +int mac_drv_vpd_read(struct s_smc *smc, char *buf, int size, char image) { u_short ibase ; u_short pci_base ; @@ -1597,16 +1516,14 @@ return(len) ; } -void mac_drv_pci_fix(smc,fix_value) -struct s_smc *smc ; -u_long fix_value ; +void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value) { smc->hw.pci_fix_value = fix_value ; } -void mac_do_pci_fix(smc) -struct s_smc *smc ; +void mac_do_pci_fix(struct s_smc *smc) { SK_UNUSED(smc) ; } #endif /* PCI */ + diff -Nru a/drivers/net/skfp/ecm.c b/drivers/net/skfp/ecm.c --- a/drivers/net/skfp/ecm.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/skfp/ecm.c 2004-06-26 17:09:16 -07:00 @@ -94,17 +94,16 @@ * function declarations */ -static void ecm_fsm() ; -static void start_ecm_timer() ; -static void stop_ecm_timer() ; -static void prop_actions() ; +static void ecm_fsm(struct s_smc *smc, int cmd); +static void start_ecm_timer(struct s_smc *smc, u_long value, int event); +static void stop_ecm_timer(struct s_smc *smc); +static void prop_actions(struct s_smc *smc); /* init ECM state machine clear all ECM vars and flags */ -void ecm_init(smc) -struct s_smc *smc ; +void ecm_init(struct s_smc *smc) { smc->e.path_test = PT_PASSED ; smc->e.trace_prop = 0 ; @@ -122,9 +121,7 @@ process event until SM is stable */ -void ecm(smc,event) -struct s_smc *smc ; -int event ; +void ecm(struct s_smc *smc, int event) { int state ; @@ -143,9 +140,7 @@ /* process ECM event */ -static void ecm_fsm(smc,cmd) -struct s_smc *smc ; -int cmd ; +static void ecm_fsm(struct s_smc *smc, int cmd) { int ls_a ; /* current line state PHY A */ int ls_b ; /* current line state PHY B */ @@ -429,8 +424,7 @@ /* * trace propagation actions for SAS & DAS */ -static void prop_actions(smc) -struct s_smc *smc ; +static void prop_actions(struct s_smc *smc) { int port_in = 0 ; int port_out = 0 ; @@ -480,8 +474,7 @@ /* * trace propagation actions for Concentrator */ -static void prop_actions(smc) -struct s_smc *smc ; +static void prop_actions(struct s_smc *smc) { int initiator ; int upstream ; @@ -527,10 +520,7 @@ * SMT timer interface * start ECM timer */ -static void start_ecm_timer(smc,value,event) -struct s_smc *smc ; -u_long value; -int event ; +static void start_ecm_timer(struct s_smc *smc, u_long value, int event) { smt_timer_start(smc,&smc->e.ecm_timer,value,EV_TOKEN(EVENT_ECM,event)); } @@ -539,8 +529,7 @@ * SMT timer interface * stop ECM timer */ -static void stop_ecm_timer(smc) -struct s_smc *smc ; +static void stop_ecm_timer(struct s_smc *smc) { if (smc->e.ecm_timer.tm_active) smt_timer_stop(smc,&smc->e.ecm_timer) ; diff -Nru a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c --- a/drivers/net/skfp/ess.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/skfp/ess.c 2004-06-26 17:09:16 -07:00 @@ -80,8 +80,11 @@ ------------------------------------------------------------- */ -static void ess_send_response(), ess_config_fifo(), - ess_send_alc_req(), ess_send_frame() ; +static void ess_send_response(struct s_smc *smc, struct smt_header *sm, + int sba_cmd); +static void ess_config_fifo(struct s_smc *smc); +static void ess_send_alc_req(struct s_smc *smc); +static void ess_send_frame(struct s_smc *smc, SMbuf *mb); /* ------------------------------------------------------------- @@ -89,26 +92,17 @@ ------------------------------------------------------------- */ -extern void *sm_to_para() ; - -extern void smt_send_frame(), smt_free_mbuf(), - set_formac_tsync(), formac_reinit_tx() ; - -extern int smt_check_para() ; - -extern SMbuf *smt_get_mbuf(), *smt_build_frame() ; - -extern u_long smt_get_tid() ; - /* ------------------------------------------------------------- PUBLIC FUNCTIONS: ------------------------------------------------------------- */ - void ess_timer_poll(), ess_para_change() ; - - int ess_raf_received_pack(), process_bw_alloc() ; +void ess_timer_poll(struct s_smc *smc); +void ess_para_change(struct s_smc *smc); +int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, + int fs); +int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead); /* @@ -120,11 +114,8 @@ /* * evaluate the RAF frame */ -int ess_raf_received_pack(smc,mb,sm,fs) -struct s_smc *smc ; -SMbuf *mb ; -struct smt_header *sm ; -int fs ; +int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, + int fs) { void *p ; /* universal pointer */ struct smt_p_0016 *cmd ; /* para: command for the ESS */ @@ -384,10 +375,7 @@ * determines the synchronous bandwidth, set the TSYNC register and the * mib variables SBAPayload, SBAOverhead and fddiMACT-NEG. */ -int process_bw_alloc(smc,payload,overhead) -struct s_smc *smc ; -long payload ; -long overhead ; +int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead) { /* * determine the synchronous bandwidth (sync_bw) in bytes per T-NEG, @@ -483,10 +471,8 @@ return(TRUE) ; } -static void ess_send_response(smc,sm,sba_cmd) -struct s_smc *smc ; -struct smt_header *sm ; -int sba_cmd ; +static void ess_send_response(struct s_smc *smc, struct smt_header *sm, + int sba_cmd) { struct smt_sba_chg *chg ; SMbuf *mb ; @@ -550,9 +536,7 @@ ess_send_frame(smc,mb) ; } - -void ess_timer_poll(smc) -struct s_smc *smc ; +void ess_timer_poll(struct s_smc *smc) { if (!smc->ess.raf_act_timer_poll) return ; @@ -566,8 +550,7 @@ } } -static void ess_send_alc_req(smc) -struct s_smc *smc ; +static void ess_send_alc_req(struct s_smc *smc) { struct smt_sba_alc_req *req ; SMbuf *mb ; @@ -675,9 +658,7 @@ ess_send_frame(smc,mb) ; } -static void ess_send_frame(smc,mb) -struct s_smc *smc ; -SMbuf *mb ; +static void ess_send_frame(struct s_smc *smc, SMbuf *mb) { /* * check if the frame must be send to the own ESS @@ -703,15 +684,13 @@ } } -void ess_para_change(smc) -struct s_smc *smc ; +void ess_para_change(struct s_smc *smc) { (void)process_bw_alloc(smc,(long)smc->mib.a[PATH0].fddiPATHSbaPayload, (long)smc->mib.a[PATH0].fddiPATHSbaOverhead) ; } -static void ess_config_fifo(smc) -struct s_smc *smc ; +static void ess_config_fifo(struct s_smc *smc) { /* * if nothing to do exit @@ -738,3 +717,4 @@ #endif /* ESS */ #endif /* no SLIM_SMT */ + diff -Nru a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c --- a/drivers/net/skfp/fplustm.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/skfp/fplustm.c 2004-06-26 17:09:17 -07:00 @@ -43,10 +43,10 @@ /* * prototypes for static function */ -static void build_claim_beacon() ; -static int init_mac() ; -static void rtm_init() ; -static void smt_split_up_fifo() ; +static void build_claim_beacon(struct s_smc *smc, u_long t_request); +static int init_mac(struct s_smc *smc, int all); +static void rtm_init(struct s_smc *smc); +static void smt_split_up_fifo(struct s_smc *smc); #if (!defined(NO_SMT_PANIC) || defined(DEBUG)) static char write_mdr_warning [] = "E350 write_mdr() FM_SNPPND is set\n"; @@ -107,8 +107,7 @@ FM_SLOCLM | FM_SHICLM | FM_SMYCLM | FM_SCLM ; -static u_long mac_get_tneg(smc) -struct s_smc *smc ; +static u_long mac_get_tneg(struct s_smc *smc) { u_long tneg ; @@ -117,8 +116,7 @@ 0xffe00000L)) ; } -void mac_update_counter(smc) -struct s_smc *smc ; +void mac_update_counter(struct s_smc *smc) { smc->mib.m[MAC0].fddiMACFrame_Ct = (smc->mib.m[MAC0].fddiMACFrame_Ct & 0xffff0000L) @@ -143,9 +141,7 @@ /* * write long value into buffer memory over memory data register (MDR), */ -void write_mdr(smc,val) -struct s_smc *smc ; -u_long val; +void write_mdr(struct s_smc *smc, u_long val) { CHECK_NPP() ; MDRW(val) ; @@ -154,9 +150,7 @@ /* * read long value from buffer memory over memory data register (MDR), */ -u_long read_mdr(smc,addr) -struct s_smc *smc ; -unsigned int addr; +u_long read_mdr(struct s_smc *smc, unsigned int addr) { long p ; CHECK_NPP() ; @@ -173,8 +167,7 @@ /* * clear buffer memory */ -static void init_ram(smc) -struct s_smc *smc ; +static void init_ram(struct s_smc *smc) { u_short i ; @@ -193,8 +186,7 @@ /* * set receive FIFO pointer */ -static void set_recvptr(smc) -struct s_smc *smc ; +static void set_recvptr(struct s_smc *smc) { /* * initialize the pointer for receive queue 1 @@ -224,8 +216,7 @@ /* * set transmit FIFO pointer */ -static void set_txptr(smc) -struct s_smc *smc ; +static void set_txptr(struct s_smc *smc) { outpw(FM_A(FM_CMDREG2),FM_IRSTQ) ; /* reset transmit queues */ @@ -257,8 +248,7 @@ /* * init memory buffer management registers */ -static void init_rbc(smc) -struct s_smc *smc ; +static void init_rbc(struct s_smc *smc) { u_short rbc_ram_addr ; @@ -279,8 +269,7 @@ /* * init rx pointer */ -static void init_rx(smc) -struct s_smc *smc ; +static void init_rx(struct s_smc *smc) { struct s_smt_rx_queue *queue ; @@ -302,9 +291,7 @@ /* * set the TSYNC register of the FORMAC to regulate synchronous transmission */ -void set_formac_tsync(smc,sync_bw) -struct s_smc *smc ; -long sync_bw ; +void set_formac_tsync(struct s_smc *smc, long sync_bw) { outpw(FM_A(FM_TSYNC),(unsigned int) (((-sync_bw) >> 5) & 0xffff) ) ; } @@ -312,8 +299,7 @@ /* * init all tx data structures */ -static void init_tx(smc) -struct s_smc *smc ; +static void init_tx(struct s_smc *smc) { struct s_smt_tx_queue *queue ; @@ -339,8 +325,7 @@ llc_recover_tx(smc) ; } -static void mac_counter_init(smc) -struct s_smc *smc ; +static void mac_counter_init(struct s_smc *smc) { int i ; u_long *ec ; @@ -363,8 +348,7 @@ /* * set FORMAC address, and t_request */ -static void set_formac_addr(smc) -struct s_smc *smc ; +static void set_formac_addr(struct s_smc *smc) { long t_requ = smc->mib.m[MAC0].fddiMACT_Req ; @@ -390,9 +374,7 @@ outpw(FM_A(FM_TREQ0),(unsigned)t_requ) ; } -static void set_int(p,l) -char *p; -int l; +static void set_int(char *p, int l) { p[0] = (char)(l >> 24) ; p[1] = (char)(l >> 16) ; @@ -408,12 +390,12 @@ * else * append 'end of chain' pointer */ -static void copy_tx_mac(smc,td,mac,off,len) -struct s_smc *smc ; -u_long td; /* transmit descriptor */ -struct fddi_mac *mac; /* mac frame pointer */ -unsigned off; /* start address within buffer memory */ -int len ; /* lenght of the frame including the FC */ +static void copy_tx_mac(struct s_smc *smc, u_long td, struct fddi_mac *mac, + unsigned off, int len) +/* u_long td; transmit descriptor */ +/* struct fddi_mac *mac; mac frame pointer */ +/* unsigned off; start address within buffer memory */ +/* int len ; lenght of the frame including the FC */ { int i ; u_int *p ; @@ -457,8 +439,7 @@ END_MANUAL_ENTRY */ -static void directed_beacon(smc) -struct s_smc *smc ; +static void directed_beacon(struct s_smc *smc) { SK_LOC_DECL(u_int,a[2]) ; @@ -487,9 +468,7 @@ special frame packets end with a pointer to their own descriptor, and the MORE bit is set in the descriptor */ -static void build_claim_beacon(smc,t_request) -struct s_smc *smc ; -u_long t_request; +static void build_claim_beacon(struct s_smc *smc, u_long t_request) { u_int td ; int len ; @@ -550,8 +529,7 @@ outpw(FM_A(FM_RPXSF),0) ; } -void formac_rcv_restart(smc) -struct s_smc *smc ; +void formac_rcv_restart(struct s_smc *smc) { /* enable receive function */ SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ; @@ -559,15 +537,13 @@ outpw(FM_A(FM_CMDREG1),FM_ICLLR) ; /* clear receive lock */ } -void formac_tx_restart(smc) -struct s_smc *smc ; +void formac_tx_restart(struct s_smc *smc) { outpw(FM_A(FM_CMDREG1),FM_ICLLS) ; /* clear s-frame lock */ outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ; /* clear a-frame lock */ } -static void enable_formac(smc) -struct s_smc *smc ; +static void enable_formac(struct s_smc *smc) { /* set formac IMSK : 0 enables irq */ outpw(FM_A(FM_IMSK1U),~mac_imsk1u) ; @@ -607,9 +583,8 @@ END_MANUAL_ENTRY */ -void enable_tx_irq(smc, queue) -struct s_smc *smc ; -u_short queue ; /* 0 = synchronous queue, 1 = asynchronous queue 0 */ +void enable_tx_irq(struct s_smc *smc, u_short queue) +/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */ { u_short imask ; @@ -643,9 +618,8 @@ END_MANUAL_ENTRY */ -void disable_tx_irq(smc, queue) -struct s_smc *smc ; -u_short queue ; /* 0 = synchronous queue, 1 = asynchronous queue 0 */ +void disable_tx_irq(struct s_smc *smc, u_short queue) +/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */ { u_short imask ; @@ -660,8 +634,7 @@ } #endif -static void disable_formac(smc) -struct s_smc *smc ; +static void disable_formac(struct s_smc *smc) { /* clear formac IMSK : 1 disables irq */ outpw(FM_A(FM_IMSK1U),MW) ; @@ -673,9 +646,7 @@ } -static void mac_ring_up(smc,up) -struct s_smc *smc ; -int up; +static void mac_ring_up(struct s_smc *smc, int up) { if (up) { formac_rcv_restart(smc) ; /* enable receive function */ @@ -702,10 +673,7 @@ * mac2_irq: status bits for the receive queue 1, and ring status * ring status indication bits */ -void mac2_irq(smc,code_s2u,code_s2l) -struct s_smc *smc ; -u_short code_s2u ; -u_short code_s2l ; +void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l) { u_short change_s2l ; u_short change_s2u ; @@ -831,10 +799,7 @@ /* * mac3_irq: receive queue 2 bits and address detection bits */ -void mac3_irq(smc,code_s3u,code_s3l) -struct s_smc *smc ; -u_short code_s3u ; -u_short code_s3l ; +void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l) { UNUSED(code_s3l) ; @@ -857,8 +822,7 @@ /* * take formac offline */ -static void formac_offline(smc) -struct s_smc *smc ; +static void formac_offline(struct s_smc *smc) { outpw(FM_A(FM_CMDREG2),FM_IACTR) ;/* abort current transmit activity */ @@ -876,8 +840,7 @@ /* * bring formac online */ -static void formac_online(smc) -struct s_smc *smc ; +static void formac_online(struct s_smc *smc) { enable_formac(smc) ; SETMASK(FM_A(FM_MDREG1),FM_MONLINE | FM_SELRA | MDR1INIT | @@ -887,8 +850,7 @@ /* * FORMAC+ full init. (tx, rx, timer, counter, claim & beacon) */ -int init_fplus(smc) -struct s_smc *smc ; +int init_fplus(struct s_smc *smc) { smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ; smc->hw.fp.rx_mode = FM_MDAMA ; @@ -926,9 +888,7 @@ /* enable_formac(smc) ; */ } -static int init_mac(smc,all) -struct s_smc *smc ; -int all ; +static int init_mac(struct s_smc *smc, int all) { u_short t_max,x ; u_long time=0 ; @@ -1033,9 +993,7 @@ /* * called by CFM */ -void config_mux(smc,mux) -struct s_smc *smc ; -int mux; +void config_mux(struct s_smc *smc, int mux) { plc_config_mux(smc,mux) ; @@ -1049,8 +1007,7 @@ * the interrupt must not be permanently enabled * RMT calls this function periodically (timer driven polling) */ -void sm_mac_check_beacon_claim(smc) -struct s_smc *smc ; +void sm_mac_check_beacon_claim(struct s_smc *smc) { /* set formac IMSK : 0 enables irq */ outpw(FM_A(FM_IMSK2U),~(mac_imsk2u | mac_beacon_imsk2u)) ; @@ -1063,9 +1020,7 @@ /* * control ODL output */ -void sm_pm_control(smc,mode) -struct s_smc *smc ; -int mode; +void sm_pm_control(struct s_smc *smc, int mode) { SK_UNUSED(smc) ; @@ -1084,9 +1039,7 @@ /* * control MAC layer (called by RMT) */ -void sm_ma_control(smc,mode) -struct s_smc *smc ; -int mode; +void sm_ma_control(struct s_smc *smc, int mode) { switch(mode) { case MA_OFFLINE : @@ -1110,8 +1063,7 @@ } } -int sm_mac_get_tx_state(smc) -struct s_smc *smc ; +int sm_mac_get_tx_state(struct s_smc *smc) { return((inpw(FM_A(FM_STMCHN))>>4)&7) ; } @@ -1120,12 +1072,10 @@ * multicast functions */ -static struct s_fpmc *mac_get_mc_table(smc,user,own,del,can) -struct s_smc *smc ; -struct fddi_addr *user ; -struct fddi_addr *own ; -int del ; -int can ; +static struct s_fpmc* mac_get_mc_table(struct s_smc *smc, + struct fddi_addr *user, + struct fddi_addr *own, + int del, int can) { struct s_fpmc *tb ; struct s_fpmc *slot ; @@ -1166,8 +1116,7 @@ END_MANUAL_ENTRY() */ -void mac_clear_multicast(smc) -struct s_smc *smc ; +void mac_clear_multicast(struct s_smc *smc) { struct s_fpmc *tb ; int i ; @@ -1198,9 +1147,7 @@ END_MANUAL_ENTRY() */ -int mac_set_func_addr(smc,f_addr) -struct s_smc *smc ; -u_long f_addr ; +int mac_set_func_addr(struct s_smc *smc, u_long f_addr) { smc->hw.fp.func_addr = f_addr ; return(0) ; @@ -1235,10 +1182,7 @@ END_MANUAL_ENTRY() */ -int mac_add_multicast(smc,addr,can) -struct s_smc *smc ; -struct fddi_addr *addr ; -int can ; +int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) { SK_LOC_DECL(struct fddi_addr,own) ; struct s_fpmc *tb ; @@ -1292,10 +1236,7 @@ END_MANUAL_ENTRY() */ -void mac_del_multicast(smc,addr,can) -struct s_smc *smc ; -struct fddi_addr *addr ; -int can ; +void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) { SK_LOC_DECL(struct fddi_addr,own) ; struct s_fpmc *tb ; @@ -1341,8 +1282,7 @@ END_MANUAL_ENTRY() */ -void mac_update_multicast(smc) -struct s_smc *smc ; +void mac_update_multicast(struct s_smc *smc) { struct s_fpmc *tb ; u_char *fu ; @@ -1418,9 +1358,7 @@ END_MANUAL_ENTRY */ -void mac_set_rx_mode(smc,mode) -struct s_smc *smc ; -int mode ; +void mac_set_rx_mode(struct s_smc *smc, int mode) { switch (mode) { case RX_ENABLE_ALLMULTI : @@ -1476,8 +1414,7 @@ END_MANUAL_ENTRY */ -void rtm_irq(smc) -struct s_smc *smc ; +void rtm_irq(struct s_smc *smc) { outpw(ADDR(B2_RTM_CRTL),TIM_CL_IRQ) ; /* clear IRQ */ if (inpw(ADDR(B2_RTM_CRTL)) & TIM_RES_TOK) { @@ -1490,15 +1427,13 @@ outpw(ADDR(B2_RTM_CRTL),TIM_START) ; /* enable RTM monitoring */ } -static void rtm_init(smc) -struct s_smc *smc ; +static void rtm_init(struct s_smc *smc) { outpd(ADDR(B2_RTM_INI),0) ; /* timer = 0 */ outpw(ADDR(B2_RTM_CRTL),TIM_START) ; /* enable IRQ */ } -void rtm_set_timer(smc) -struct s_smc *smc ; +void rtm_set_timer(struct s_smc *smc) { /* * MIB timer and hardware timer have the same resolution of 80nS @@ -1508,8 +1443,7 @@ outpd(ADDR(B2_RTM_INI),smc->mib.a[PATH0].fddiPATHT_Rmode) ; } -static void smt_split_up_fifo(smc) -struct s_smc *smc ; +static void smt_split_up_fifo(struct s_smc *smc) { /* @@ -1629,8 +1563,7 @@ smc->hw.fp.fifo.tx_a0_start, smc->hw.fp.fifo.rx2_fifo_start) ; } -void formac_reinit_tx(smc) -struct s_smc *smc ; +void formac_reinit_tx(struct s_smc *smc) { /* * Split up the FIFO and reinitialize the MAC if synchronous @@ -1641,5 +1574,4 @@ (void)init_mac(smc,0) ; } } - diff -Nru a/drivers/net/skfp/h/cmtdef.h b/drivers/net/skfp/h/cmtdef.h --- a/drivers/net/skfp/h/cmtdef.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/skfp/h/cmtdef.h 2004-06-26 17:09:16 -07:00 @@ -418,7 +418,6 @@ void *pc_p ; } ; - /* * link error monitor */ @@ -444,7 +443,6 @@ #define NUMBITS 10 - #ifdef AMDPLC /* @@ -480,216 +478,184 @@ * function prototypes */ #include "h/mbuf.h" /* Type definitions for MBUFs */ -void hwt_restart( /* hwt.c */ -#ifdef ANSIC - struct s_smc *smc -#endif - ) ; - -SMbuf *smt_build_frame( /* smt.c */ -#ifdef ANSIC - struct s_smc *smc, - int class, - int type, - int length -#endif - ) ; - -SMbuf *smt_get_mbuf( /* drvsr.c */ -#ifdef ANSIC - struct s_smc *smc -#endif - ) ; - -void *sm_to_para( /* smt.c */ -#ifdef ANSIC - struct s_smc *smc, - struct smt_header *sm, - int para -#endif - ) ; +#include "h/smtstate.h" /* struct smt_state */ + +void hwt_restart(struct s_smc *smc); /* hwt.c */ +SMbuf *smt_build_frame(struct s_smc *smc, int class, int type, + int length); /* smt.c */ +SMbuf *smt_get_mbuf(struct s_smc *smc); /* drvsr.c */ +void *sm_to_para(struct s_smc *smc, struct smt_header *sm, + int para); /* smt.c */ #ifndef SK_UNUSED #define SK_UNUSED(var) (void)(var) #endif -void queue_event() ; -void ecm() ; -void ecm_init() ; -void rmt() ; -void rmt_init() ; -void pcm() ; -void pcm_init() ; -void cfm() ; -void cfm_init() ; -void smt_timer_start() ; -void smt_timer_stop() ; -void pcm_status_state() ; -void plc_config_mux() ; -void sm_lem_evaluate() ; -void smt_clear_una_dna() ; -void mac_status_para() ; -void mac_update_counter() ; -void sm_pm_ls_latch() ; -void sm_ma_control() ; -void sm_mac_check_beacon_claim() ; -void config_mux() ; -void smt_agent_init() ; -void smt_timer_init() ; -void smt_received_pack() ; -void smt_add_para() ; -void smt_swap_para() ; -void ev_init() ; -void hwt_init() ; -u_long hwt_read() ; -void hwt_stop() ; -void hwt_start() ; -void smt_send_mbuf() ; -void smt_free_mbuf() ; -void sm_pm_bypass_req() ; -void rmt_indication() ; -void cfm_state_change() ; -void rx_indication() ; -void tx_indication() ; -#ifndef NO_SMT_PANIC -void smt_panic() ; -#else -#ifdef DEBUG -void smt_panic() ; +void queue_event(struct s_smc *smc, int class, int event); +void ecm(struct s_smc *smc, int event); +void ecm_init(struct s_smc *smc); +void rmt(struct s_smc *smc, int event); +void rmt_init(struct s_smc *smc); +void pcm(struct s_smc *smc, const int np, int event); +void pcm_init(struct s_smc *smc); +void cfm(struct s_smc *smc, int event); +void cfm_init(struct s_smc *smc); +void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time, + u_long token); +void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer); +void pcm_status_state(struct s_smc *smc, int np, int *type, int *state, + int *remote, int *mac); +void plc_config_mux(struct s_smc *smc, int mux); +void sm_lem_evaluate(struct s_smc *smc); +void smt_clear_una_dna(struct s_smc *smc); +void mac_update_counter(struct s_smc *smc); +void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off); +void sm_ma_control(struct s_smc *smc, int mode); +void sm_mac_check_beacon_claim(struct s_smc *smc); +void config_mux(struct s_smc *smc, int mux); +void smt_agent_init(struct s_smc *smc); +void smt_timer_init(struct s_smc *smc); +void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs); +void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, + int index, int local); +void smt_swap_para(struct smt_header *sm, int len, int direction); +void ev_init(struct s_smc *smc); +void hwt_init(struct s_smc *smc); +u_long hwt_read(struct s_smc *smc); +void hwt_stop(struct s_smc *smc); +void hwt_start(struct s_smc *smc, u_long time); +void smt_send_mbuf(struct s_smc *smc, SMbuf *mb, int fc); +void smt_free_mbuf(struct s_smc *smc, SMbuf *mb); +void sm_pm_bypass_req(struct s_smc *smc, int mode); +void rmt_indication(struct s_smc *smc, int i); +void cfm_state_change(struct s_smc *smc, int c_state); + +#if defined(DEBUG) || !defined(NO_SMT_PANIC) +void smt_panic(struct s_smc *smc, char *text); #else #define smt_panic(smc,text) -#endif /* DEBUG */ -#endif /* NO_SMT_PANIC */ -void smt_stat_counter() ; -void smt_timer_poll() ; -u_long smt_get_time() ; -u_long smt_get_tid() ; -void smt_timer_done() ; -void smt_set_defaults() ; -void smt_fixup_mib() ; -void smt_reset_defaults() ; -void smt_agent_task() ; -void smt_please_reconnect() ; -int smt_check_para() ; -void driver_get_bia() ; -#ifdef SUPERNET_3 -void drv_reset_indication() ; +#endif /* DEBUG || !NO_SMT_PANIC */ + +void smt_stat_counter(struct s_smc *smc, int stat); +void smt_timer_poll(struct s_smc *smc); +u_long smt_get_time(void); +u_long smt_get_tid(struct s_smc *smc); +void smt_timer_done(struct s_smc *smc); +void smt_set_defaults(struct s_smc *smc); +void smt_fixup_mib(struct s_smc *smc); +void smt_reset_defaults(struct s_smc *smc, int level); +void smt_agent_task(struct s_smc *smc); +void smt_please_reconnect(struct s_smc *smc, int reconn_time); +int smt_check_para(struct s_smc *smc, struct smt_header *sm, + const u_short list[]); +void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr); + +#ifdef SUPERNET_3 +void drv_reset_indication(struct s_smc *smc); #endif /* SUPERNET_3 */ -void smt_start_watchdog() ; -void smt_event() ; -void pcm_event() ; -void rmt_event() ; -void cfm_event() ; -void timer_event() ; -void ev_dispatcher() ; - -void smt_get_state() ; -void ecm_get_state() ; -void pcm_get_state() ; -void rmt_get_state() ; - -void ecm_state_change() ; -int sm_pm_bypass_present() ; -void pcm_state_change() ; -void rmt_state_change() ; -int sm_pm_get_ls() ; -int pcm_get_s_port() ; -int pcm_rooted_station() ; -int cfm_get_mac_input() ; -int cfm_get_mac_output() ; -int port_to_mib() ; -int cem_build_path() ; -int sm_mac_get_tx_state() ; -int is_individual() ; -int is_my_addr() ; -int is_broadcast() ; -int is_equal() ; -char *get_pcmstate() ; - -int smt_action() ; -u_short smt_online() ; -void smt_force_irq() ; -void smt_pmf_received_pack() ; -void smt_send_frame() ; -void smt_set_timestamp() ; -void mac_set_rx_mode() ; -int mac_add_multicast() ; -int mac_set_func_addr() ; -void mac_del_multicast() ; -void mac_update_multicast() ; -void mac_clear_multicast() ; -void mac_rx_directed_beacon() ; -void set_formac_tsync() ; -void formac_reinit_tx() ; -void formac_tx_restart() ; -void process_receive() ; -void init_driver_fplus() ; - -void rtm_irq() ; -void rtm_set_timer() ; -void ring_status_indication() ; -void llc_recover_tx() ; -void llc_restart_tx() ; -void plc_clear_irq() ; -void plc_irq() ; -int smt_set_mac_opvalues() ; -#ifdef TAG_MODE -void mac_drv_pci_fix() ; -void mac_do_pci_fix() ; -void mac_drv_clear_tx_queue() ; -void mac_drv_repair_descr() ; -u_long hwt_quick_read() ; -void hwt_wait_time() ; +void smt_start_watchdog(struct s_smc *smc); +void smt_event(struct s_smc *smc, int event); +void timer_event(struct s_smc *smc, u_long token); +void ev_dispatcher(struct s_smc *smc); +void pcm_get_state(struct s_smc *smc, struct smt_state *state); +void ecm_state_change(struct s_smc *smc, int e_state); +int sm_pm_bypass_present(struct s_smc *smc); +void pcm_state_change(struct s_smc *smc, int plc, int p_state); +void rmt_state_change(struct s_smc *smc, int r_state); +int sm_pm_get_ls(struct s_smc *smc, int phy); +int pcm_get_s_port(struct s_smc *smc); +int pcm_rooted_station(struct s_smc *smc); +int cfm_get_mac_input(struct s_smc *smc); +int cfm_get_mac_output(struct s_smc *smc); +int port_to_mib(struct s_smc *smc, int p); +int cem_build_path(struct s_smc *smc, char *to, int path_index); +int sm_mac_get_tx_state(struct s_smc *smc); +int is_individual(struct fddi_addr *addr); +int is_my_addr(struct s_smc *smc, struct fddi_addr *addr); +int is_broadcast(struct fddi_addr *addr); +int is_equal(struct fddi_addr *addr1, struct fddi_addr *addr2); +char *get_pcmstate(struct s_smc *smc, int np); +int smt_action(struct s_smc *smc, int class, int code, int index); +u_short smt_online(struct s_smc *smc, int on); +void smt_force_irq(struct s_smc *smc); +void smt_pmf_received_pack(struct s_smc *smc, SMbuf *mb, int local); +void smt_send_frame(struct s_smc *smc, SMbuf *mb, int fc, int local); +void smt_set_timestamp(struct s_smc *smc, u_char *p); +void mac_set_rx_mode(struct s_smc *smc, int mode); +int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can); +int mac_set_func_addr(struct s_smc *smc, u_long f_addr); +void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can); +void mac_update_multicast(struct s_smc *smc); +void mac_clear_multicast(struct s_smc *smc); +void set_formac_tsync(struct s_smc *smc, long sync_bw); +void formac_reinit_tx(struct s_smc *smc); +void formac_tx_restart(struct s_smc *smc); +void process_receive(struct s_smc *smc); +void init_driver_fplus(struct s_smc *smc); +void rtm_irq(struct s_smc *smc); +void rtm_set_timer(struct s_smc *smc); +void ring_status_indication(struct s_smc *smc, u_long status); +void llc_recover_tx(struct s_smc *smc); +void llc_restart_tx(struct s_smc *smc); +void plc_clear_irq(struct s_smc *smc, int p); +void plc_irq(struct s_smc *smc, int np, unsigned int cmd); +int smt_set_mac_opvalues(struct s_smc *smc); + +#ifdef TAG_MODE +void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value); +void mac_do_pci_fix(struct s_smc *smc); +void mac_drv_clear_tx_queue(struct s_smc *smc); +void mac_drv_repair_descr(struct s_smc *smc); +u_long hwt_quick_read(struct s_smc *smc); +void hwt_wait_time(struct s_smc *smc, u_long start, long duration); #endif #ifdef SMT_PNMI -#ifdef ANSIC -int pnmi_init (struct s_smc* smc); -int pnmi_process_ndis_id (struct s_smc* smc, u_long ndis_oid, void* buf, - int len, int* BytesAccessed, int* BytesNeeded, u_char action); -#else -int pnmi_init (); -int pnmi_process_ndis_id (); -#endif +int pnmi_init(struct s_smc* smc); +int pnmi_process_ndis_id(struct s_smc *smc, u_long ndis_oid, void *buf, int len, + int *BytesAccessed, int *BytesNeeded, u_char action); #endif #ifdef SBA #ifndef _H2INC -void sba() ; +void sba(); #endif -void sba_raf_received_pack() ; -void sba_timer_poll() ; -void smt_init_sba() ; +void sba_raf_received_pack(); +void sba_timer_poll(); +void smt_init_sba(); #endif + #ifdef ESS -int ess_raf_received_pack() ; -void ess_timer_poll() ; -void ess_para_change() ; +int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, + int fs); +void ess_timer_poll(struct s_smc *smc); +void ess_para_change(struct s_smc *smc); #endif -#ifdef BOOT -#define smt_srf_event(a,b,c,d) -#define smt_init_evc(a) +#ifndef BOOT +void smt_init_evc(struct s_smc *smc); +void smt_srf_event(struct s_smc *smc, int code, int index, int cond); #else -void smt_init_evc() ; -void smt_srf_event() ; +#define smt_init_evc(smc) +#define smt_srf_event(smc,code,index,cond) #endif #ifndef SMT_REAL_TOKEN_CT -void smt_emulate_token_ct(); +void smt_emulate_token_ct(struct s_smc *smc, int mac_index); #endif #if defined(DEBUG) && !defined(BOOT) -void dump_smt() ; +void dump_smt(struct s_smc *smc, struct smt_header *sm, char *text); #else #define dump_smt(smc,sm,text) #endif #ifdef DEBUG -char *addr_to_string() ; -void dump_hex() ; +char* addr_to_string(struct fddi_addr *addr); +void dump_hex(char *p, int len); #endif + #endif /* PROTOTYP_INC */ /* PNMI default defines */ diff -Nru a/drivers/net/skfp/h/smtstate.h b/drivers/net/skfp/h/smtstate.h --- a/drivers/net/skfp/h/smtstate.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/skfp/h/smtstate.h 2004-06-26 17:09:20 -07:00 @@ -12,6 +12,9 @@ * ******************************************************************************/ +#ifndef _SKFP_H_SMTSTATE_H_ +#define _SKFP_H_SMTSTATE_H_ + /* * SMT state definitions */ @@ -98,3 +101,6 @@ struct smt_state { struct pcm_state pcm_state[NUMPHYS] ; /* port A & port B */ } ; + +#endif + diff -Nru a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c --- a/drivers/net/skfp/hwmtm.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/skfp/hwmtm.c 2004-06-26 17:09:18 -07:00 @@ -75,15 +75,17 @@ ------------------------------------------------------------- */ -static void queue_llc_rx(), smt_to_llc(), - init_txd_ring(), init_rxd_ring(), - queue_txd_mb() ; - -static u_long init_descr_ring(), repair_txd_ring(), - repair_rxd_ring() ; - -static SMbuf *get_llc_rx(), *get_txd_mb() ; - +static void queue_llc_rx(struct s_smc *smc, SMbuf *mb); +static void smt_to_llc(struct s_smc *smc, SMbuf *mb); +static void init_txd_ring(struct s_smc *smc); +static void init_rxd_ring(struct s_smc *smc); +static void queue_txd_mb(struct s_smc *smc, SMbuf *mb); +static u_long init_descr_ring(struct s_smc *smc, union s_fp_descr volatile *start, + int count); +static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue); +static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue); +static SMbuf* get_llc_rx(struct s_smc *smc); +static SMbuf* get_txd_mb(struct s_smc *smc); /* ------------------------------------------------------------- @@ -92,55 +94,81 @@ */ /* The external SMT functions are listed in cmtdef.h */ -extern void *mac_drv_get_space(), *mac_drv_get_desc_mem(), - init_board(), mac_drv_fill_rxd(), - plc1_irq(), mac_drv_tx_complete(), - plc2_irq(), mac1_irq(), - mac2_irq(), mac3_irq(), - timer_irq(), mac_drv_rx_complete(), - mac_drv_requeue_rxd(), init_plc(), - mac_drv_clear_rxd(), llc_restart_tx(), - ev_dispatcher(), smt_force_irq() ; +extern void* mac_drv_get_space(struct s_smc *smc, unsigned int size); +extern void* mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size); +extern void init_board(struct s_smc *smc, u_char *mac_addr); +extern void mac_drv_fill_rxd(struct s_smc *smc); +extern void plc1_irq(struct s_smc *smc); +extern void mac_drv_tx_complete(struct s_smc *smc, + volatile struct s_smt_fp_txd *txd); +extern void plc2_irq(struct s_smc *smc); +extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl); +extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l); +extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l); +extern void timer_irq(struct s_smc *smc); +extern void mac_drv_rx_complete(struct s_smc *smc, + volatile struct s_smt_fp_rxd *rxd, + int frag_count, int len); +extern void mac_drv_requeue_rxd(struct s_smc *smc, + volatile struct s_smt_fp_rxd *rxd, + int frag_count); +extern void init_plc(struct s_smc *smc); +extern void mac_drv_clear_rxd(struct s_smc *smc, + volatile struct s_smt_fp_rxd *rxd, int frag_count); #ifdef USE_OS_CPY -extern void hwm_cpy_rxd2mb(), hwm_cpy_txd2mb() ; +extern void hwm_cpy_rxd2mb(void); +extern void hwm_cpy_txd2mb(void); #endif + #ifdef ALL_RX_COMPLETE -extern void mac_drv_all_receives_complete() ; +extern void mac_drv_all_receives_complete(void); #endif -extern u_long mac_drv_virt2phys(), dma_master() ; +extern u_long mac_drv_virt2phys(struct s_smc *smc, void *virt); +extern u_long dma_master(struct s_smc *smc, void *virt, int len, int flag); #ifdef NDIS_OS2 -extern void post_proc() ; +extern void post_proc(void); #else -extern void dma_complete() ; +extern void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr, + int flag); #endif -extern int init_fplus(), mac_drv_rx_init() ; +extern int init_fplus(struct s_smc *smc); +extern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead, + int la_len); /* ------------------------------------------------------------- PUBLIC FUNCTIONS: ------------------------------------------------------------- */ - void process_receive(), smt_send_mbuf(), - fddi_isr(), mac_drv_clear_txd(), - smt_free_mbuf(), init_driver_fplus(), - mac_drv_rx_mode(), init_fddi_driver(), - mac_drv_clear_tx_queue(), - mac_drv_clear_rx_queue(), - hwm_tx_frag(), hwm_rx_frag() ; - - int mac_drv_rx_frag(), mac_drv_init(), - hwm_tx_init() ; +void process_receive(struct s_smc *smc); +void fddi_isr(struct s_smc *smc); +void mac_drv_clear_txd(struct s_smc *smc); +void smt_free_mbuf(struct s_smc *smc, SMbuf *mb); +void init_driver_fplus(struct s_smc *smc); +void mac_drv_rx_mode(struct s_smc *smc, int mode); +void init_fddi_driver(struct s_smc *smc, u_char *mac_addr); +void mac_drv_clear_tx_queue(struct s_smc *smc); +void mac_drv_clear_rx_queue(struct s_smc *smc); +void hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len, + int frame_status); +void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len, + int frame_status); + +int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len); +int mac_drv_init(struct s_smc *smc); +int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len, + int frame_status); - u_int mac_drv_check_space() ; +u_int mac_drv_check_space(void); - SMbuf *smt_get_mbuf() ; +SMbuf* smt_get_mbuf(struct s_smc *smc); #ifdef DEBUG - void mac_drv_debug_lev() ; + void mac_drv_debug_lev(void); #endif /* @@ -208,7 +236,7 @@ * * END_MANUAL_ENTRY */ -u_int mac_drv_check_space() +u_int mac_drv_check_space(void) { #ifdef MB_OUTSIDE_SMC #ifdef COMMON_MB_POOL @@ -238,8 +266,7 @@ * mac_drv_init once, after the adatper is detected. * END_MANUAL_ENTRY */ -int mac_drv_init(smc) -struct s_smc *smc ; +int mac_drv_init(struct s_smc *smc) { if (sizeof(struct s_smt_fp_rxd) % 16) { SMT_PANIC(smc,HWM_E0001,HWM_E0001_MSG) ; @@ -289,8 +316,7 @@ * least significant byte etc.) * END_MANUAL_ENTRY */ -void init_driver_fplus(smc) -struct s_smc *smc ; +void init_driver_fplus(struct s_smc *smc) { smc->hw.fp.mdr2init = FM_LSB | FM_BMMODE | FM_ENNPRQ | FM_ENHSRQ | 3 ; @@ -305,10 +331,9 @@ #endif } -static u_long init_descr_ring(smc,start,count) -struct s_smc *smc ; -union s_fp_descr volatile *start; -int count ; +static u_long init_descr_ring(struct s_smc *smc, + union s_fp_descr volatile *start, + int count) { int i ; union s_fp_descr volatile *d1 ; @@ -337,8 +362,7 @@ return(phys) ; } -static void init_txd_ring(smc) -struct s_smc *smc ; +static void init_txd_ring(struct s_smc *smc) { struct s_smt_fp_txd volatile *ds ; struct s_smt_tx_queue *queue ; @@ -375,8 +399,7 @@ outpd(ADDR(B5_XS_DA),phys) ; } -static void init_rxd_ring(smc) -struct s_smc *smc ; +static void init_rxd_ring(struct s_smc *smc) { struct s_smt_fp_rxd volatile *ds ; struct s_smt_rx_queue *queue ; @@ -406,9 +429,7 @@ * * END_MANUAL_ENTRY */ -void init_fddi_driver(smc,mac_addr) -struct s_smc *smc ; -u_char *mac_addr ; /* canonical address */ +void init_fddi_driver(struct s_smc *smc, u_char *mac_addr) { SMbuf *mb ; int i ; @@ -472,8 +493,7 @@ } -SMbuf *smt_get_mbuf(smc) -struct s_smc *smc ; +SMbuf *smt_get_mbuf(struct s_smc *smc) { register SMbuf *mb ; @@ -495,9 +515,7 @@ return (mb) ; /* May be NULL */ } -void smt_free_mbuf(smc, mb) -struct s_smc *smc ; -SMbuf *mb; +void smt_free_mbuf(struct s_smc *smc, SMbuf *mb) { if (mb) { @@ -543,8 +561,7 @@ * * END_MANUAL_ENTRY */ -void mac_drv_repair_descr(smc) -struct s_smc *smc ; +void mac_drv_repair_descr(struct s_smc *smc) { u_long phys ; @@ -576,9 +593,7 @@ outpd(ADDR(B0_R1_CSR),CSR_START) ; } -static u_long repair_txd_ring(smc,queue) -struct s_smc *smc ; -struct s_smt_tx_queue *queue ; +static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue) { int i ; int tx_used ; @@ -630,9 +645,7 @@ * RxDs with an OWN bit set but with a reset STF bit should be * skipped and owned by the driver (OWN = 0). */ -static u_long repair_rxd_ring(smc,queue) -struct s_smc *smc ; -struct s_smt_rx_queue *queue ; +static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue) { int i ; int rx_used ; @@ -703,8 +716,7 @@ * * END_MANUAL_ENTRY */ -void fddi_isr(smc) -struct s_smc *smc ; +void fddi_isr(struct s_smc *smc) { u_long is ; /* ISR source */ u_short stu, stl ; @@ -987,9 +999,7 @@ * * END_MANUAL_ENTRY */ -void mac_drv_rx_mode(smc,mode) -struct s_smc *smc ; -int mode ; +void mac_drv_rx_mode(struct s_smc *smc, int mode) { switch(mode) { case RX_ENABLE_PASS_SMT: @@ -1038,8 +1048,7 @@ /* * process receive queue */ -void process_receive(smc) -struct s_smc *smc ; +void process_receive(struct s_smc *smc) { int i ; int n ; @@ -1379,9 +1388,7 @@ return ; /* lint bug: needs return detect end of function */ } -static void smt_to_llc(smc,mb) -struct s_smc *smc ; -SMbuf *mb ; +static void smt_to_llc(struct s_smc *smc, SMbuf *mb) { u_char fc ; @@ -1416,12 +1423,8 @@ * * END_MANUAL_ENTRY */ -void hwm_rx_frag(smc,virt,phys,len,frame_status) -struct s_smc *smc ; -char far *virt ; -u_long phys ; -int len ; -int frame_status ; +void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len, + int frame_status) { struct s_smt_fp_rxd volatile *r ; u_int rbctrl ; @@ -1460,10 +1463,7 @@ * * END_MANUAL_ENTRY */ -int mac_drv_rx_frag(smc,virt,len) -struct s_smc *smc ; -void far *virt ; -int len ; +int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len) { NDD_TRACE("RHSB",virt,len,smc->os.hwm.r.mb_pos) ; @@ -1500,8 +1500,7 @@ * * END_MANUAL_ENTRY */ -void mac_drv_clear_rx_queue(smc) -struct s_smc *smc ; +void mac_drv_clear_rx_queue(struct s_smc *smc) { struct s_smt_fp_rxd volatile *r ; struct s_smt_fp_rxd volatile *next_rxd ; @@ -1588,12 +1587,8 @@ * * END_MANUAL_ENTRY */ -int hwm_tx_init(smc,fc,frag_count,frame_len,frame_status) -struct s_smc *smc ; -u_char fc ; -int frag_count ; -int frame_len ; -int frame_status ; +int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len, + int frame_status) { NDD_TRACE("THiB",fc,frag_count,frame_len) ; smc->os.hwm.tx_p = smc->hw.fp.tx[frame_status & QUEUE_A0] ; @@ -1670,12 +1665,8 @@ * * END_MANUAL_ENTRY */ -void hwm_tx_frag(smc,virt,phys,len,frame_status) -struct s_smc *smc ; -char far *virt ; -u_long phys ; -int len ; -int frame_status ; +void hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len, + int frame_status) { struct s_smt_fp_txd volatile *t ; struct s_smt_tx_queue *queue ; @@ -1780,9 +1771,7 @@ /* * queues a receive for later send */ -static void queue_llc_rx(smc,mb) -struct s_smc *smc ; -SMbuf *mb ; +static void queue_llc_rx(struct s_smc *smc, SMbuf *mb) { DB_GEN("queue_llc_rx: mb = %x",(void *)mb,0,4) ; smc->os.hwm.queued_rx_frames++ ; @@ -1806,8 +1795,7 @@ /* * get a SMbuf from the llc_rx_queue */ -static SMbuf *get_llc_rx(smc) -struct s_smc *smc ; +static SMbuf *get_llc_rx(struct s_smc *smc) { SMbuf *mb ; @@ -1823,9 +1811,7 @@ * queues a transmit SMT MBuf during the time were the MBuf is * queued the TxD ring */ -static void queue_txd_mb(smc,mb) -struct s_smc *smc ; -SMbuf *mb ; +static void queue_txd_mb(struct s_smc *smc, SMbuf *mb) { DB_GEN("_rx: queue_txd_mb = %x",(void *)mb,0,4) ; smc->os.hwm.queued_txd_mb++ ; @@ -1842,8 +1828,7 @@ /* * get a SMbuf from the txd_tx_queue */ -static SMbuf *get_txd_mb(smc) -struct s_smc *smc ; +static SMbuf *get_txd_mb(struct s_smc *smc) { SMbuf *mb ; @@ -1858,10 +1843,7 @@ /* * SMT Send function */ -void smt_send_mbuf(smc,mb,fc) -struct s_smc *smc; -SMbuf *mb; -int fc; +void smt_send_mbuf(struct s_smc *smc, SMbuf *mb, int fc) { char far *data ; int len ; @@ -1995,8 +1977,7 @@ * * END_MANUAL_ENTRY */ -void mac_drv_clear_txd(smc) -struct s_smc *smc ; +void mac_drv_clear_txd(struct s_smc *smc) { struct s_smt_tx_queue *queue ; struct s_smt_fp_txd volatile *t1 ; @@ -2087,8 +2068,7 @@ * * END_MANUAL_ENTRY */ -void mac_drv_clear_tx_queue(smc) -struct s_smc *smc ; +void mac_drv_clear_tx_queue(struct s_smc *smc) { struct s_smt_fp_txd volatile *t ; struct s_smt_tx_queue *queue ; @@ -2180,10 +2160,7 @@ * * END_MANUAL_ENTRY */ -void mac_drv_debug_lev(smc,flag,lev) -struct s_smc *smc ; -int flag ; -int lev ; +void mac_drv_debug_lev(struct s_smc *smc, int flag, int lev) { switch(flag) { case (int)NULL: diff -Nru a/drivers/net/skfp/hwt.c b/drivers/net/skfp/hwt.c --- a/drivers/net/skfp/hwt.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/skfp/hwt.c 2004-06-26 17:09:15 -07:00 @@ -39,7 +39,7 @@ * Prototypes of local functions. */ /* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */ -/*static*/ void hwt_restart() ; +/*static void hwt_restart() ; */ /************************ * @@ -60,9 +60,7 @@ ************************/ #define HWT_MAX (65000) -void hwt_start(smc, time) -struct s_smc *smc ; -u_long time ; +void hwt_start(struct s_smc *smc, u_long time) { u_short cnt ; @@ -115,8 +113,7 @@ * Nothing. * ************************/ -void hwt_stop(smc) -struct s_smc *smc ; +void hwt_stop(struct s_smc *smc) { #ifndef PCI /* stop counter 0 by switching to mode 0 */ @@ -145,8 +142,7 @@ * Nothing. * ************************/ -void hwt_init(smc) -struct s_smc *smc ; +void hwt_init(struct s_smc *smc) { smc->hw.t_start = 0 ; smc->hw.t_stop = 0 ; @@ -169,8 +165,7 @@ * Nothing. * ************************/ -void hwt_restart(smc) -struct s_smc *smc ; +void hwt_restart(struct s_smc *smc) { hwt_stop(smc) ; #ifndef PCI @@ -193,8 +188,7 @@ * The elapsed time since last start in units of 16us. * ************************/ -u_long hwt_read(smc) -struct s_smc *smc ; +u_long hwt_read(struct s_smc *smc) { u_short tr ; #ifndef PCI @@ -238,8 +232,7 @@ * current timer value in units of 80ns. * ************************/ -u_long hwt_quick_read(smc) -struct s_smc *smc ; +u_long hwt_quick_read(struct s_smc *smc) { u_long interval ; u_long time ; @@ -267,10 +260,7 @@ * NOTE: The fuction will return immediately, if the timer is not * started ************************/ -void hwt_wait_time(smc,start,duration) -struct s_smc *smc ; -u_long start ; -long duration ; +void hwt_wait_time(struct s_smc *smc, u_long start, long int duration) { long diff ; long interval ; @@ -312,3 +302,4 @@ } } #endif + diff -Nru a/drivers/net/skfp/lnkstat.c b/drivers/net/skfp/lnkstat.c --- a/drivers/net/skfp/lnkstat.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/skfp/lnkstat.c 2004-06-26 17:09:18 -07:00 @@ -52,8 +52,7 @@ END_MANUAL_ENTRY() */ -u_long smt_get_error_word(smc) -struct s_smc *smc ; +u_long smt_get_error_word(struct s_smc *smc) { u_long st; @@ -92,8 +91,7 @@ END_MANUAL_ENTRY() */ -u_long smt_get_event_word(smc) -struct s_smc *smc ; +u_long smt_get_event_word(struct s_smc *smc) { return (u_long) 0; } @@ -111,8 +109,7 @@ END_MANUAL_ENTRY() */ -u_long smt_get_port_event_word(smc) -struct s_smc *smc ; +u_long smt_get_port_event_word(struct s_smc *smc) { return (u_long) 0; } @@ -135,10 +132,7 @@ END_MANUAL_ENTRY() */ -int smt_read_errorlog(smc,p,len) -struct s_smc *smc ; -char _far *p ; -int len ; +int smt_read_errorlog(struct s_smc *smc, char _far *p, int len) { int i ; int st ; @@ -207,3 +201,4 @@ er->ucode_version_level = 0x0101 ; return(len) ; } + diff -Nru a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c --- a/drivers/net/skfp/pcmplc.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/skfp/pcmplc.c 2004-06-26 17:09:15 -07:00 @@ -199,28 +199,25 @@ PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR; /* external functions */ -void all_selection_criteria (); +void all_selection_criteria(struct s_smc *smc); /* internal functions */ -static void pcm_fsm() ; -static void pc_rcode_actions() ; -static void pc_tcode_actions() ; -static void reset_lem_struct() ; -static void plc_init() ; -static void sm_ph_lem_start() ; -static void sm_ph_lem_stop() ; -static void sm_ph_linestate() ; -static void real_init_plc() ; +static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd); +static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy); +static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy); +static void reset_lem_struct(struct s_phy *phy); +static void plc_init(struct s_smc *smc, int p); +static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold); +static void sm_ph_lem_stop(struct s_smc *smc, int np); +static void sm_ph_linestate(struct s_smc *smc, int phy, int ls); +static void real_init_plc(struct s_smc *smc); /* * SMT timer interface * start PCM timer 0 */ -static void start_pcm_timer0(smc,value,event,phy) -struct s_smc *smc ; -u_long value; -int event; -struct s_phy *phy; +static void start_pcm_timer0(struct s_smc *smc, u_long value, int event, + struct s_phy *phy) { phy->timer0_exp = FALSE ; /* clear timer event flag */ smt_timer_start(smc,&phy->pcm_timer0,value, @@ -230,9 +227,7 @@ * SMT timer interface * stop PCM timer 0 */ -static void stop_pcm_timer0(smc,phy) -struct s_smc *smc ; -struct s_phy *phy; +static void stop_pcm_timer0(struct s_smc *smc, struct s_phy *phy) { if (phy->pcm_timer0.tm_active) smt_timer_stop(smc,&phy->pcm_timer0) ; @@ -242,8 +237,7 @@ init PCM state machine (called by driver) clear all PCM vars and flags */ -void pcm_init(smc) -struct s_smc *smc ; +void pcm_init(struct s_smc *smc) { int i ; int np ; @@ -407,8 +401,7 @@ real_init_plc(smc) ; } -void init_plc(smc) -struct s_smc *smc ; +void init_plc(struct s_smc *smc) { SK_UNUSED(smc) ; @@ -421,8 +414,7 @@ */ } -static void real_init_plc(smc) -struct s_smc *smc ; +static void real_init_plc(struct s_smc *smc) { int p ; @@ -430,9 +422,7 @@ plc_init(smc,p) ; } -static void plc_init(smc,p) -struct s_smc *smc ; -int p; +static void plc_init(struct s_smc *smc, int p) { int i ; #ifndef MOT_ELM @@ -495,10 +485,7 @@ /* * control PCM state machine */ -static void plc_go_state(smc,p,state) -struct s_smc *smc ; -int p; -int state; +static void plc_go_state(struct s_smc *smc, int p, int state) { HW_PTR port ; int val ; @@ -514,9 +501,7 @@ /* * read current line state (called by ECM & PCM) */ -int sm_pm_get_ls(smc,phy) -struct s_smc *smc ; -int phy; +int sm_pm_get_ls(struct s_smc *smc, int phy) { int state ; @@ -549,10 +534,7 @@ return(state) ; } -static int plc_send_bits(smc,phy,len) -struct s_smc *smc ; -struct s_phy *phy; -int len; +static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len) { int np = phy->np ; /* PHY index */ int n ; @@ -589,9 +571,7 @@ /* * config plc muxes */ -void plc_config_mux(smc,mux) -struct s_smc *smc ; -int mux ; +void plc_config_mux(struct s_smc *smc, int mux) { if (smc->s.sas != SMT_DAS) return ; @@ -615,10 +595,7 @@ process event until SM is stable */ -void pcm(smc,np,event) -struct s_smc *smc ; -const int np; -int event; +void pcm(struct s_smc *smc, const int np, int event) { int state ; int oldstate ; @@ -697,10 +674,7 @@ /* * PCM state machine */ -static void pcm_fsm(smc,phy,cmd) -struct s_smc *smc ; -struct s_phy *phy; -int cmd; +static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd) { int i ; int np = phy->np ; /* PHY index */ @@ -1063,10 +1037,7 @@ /* * force line state on a PHY output (only in MAINT state) */ -static void sm_ph_linestate(smc,phy,ls) -struct s_smc *smc ; -int phy; -int ls; +static void sm_ph_linestate(struct s_smc *smc, int phy, int ls) { int cntrl ; @@ -1095,9 +1066,7 @@ outpw(PLC(phy,PL_CNTRL_B),cntrl) ; } - -static void reset_lem_struct(phy) -struct s_phy *phy; +static void reset_lem_struct(struct s_phy *phy) { struct lem_counter *lem = &phy->lem ; @@ -1108,9 +1077,7 @@ /* * link error monitor */ -static void lem_evaluate(smc,phy) -struct s_smc *smc ; -struct s_phy *phy; +static void lem_evaluate(struct s_smc *smc, struct s_phy *phy) { int ber ; u_long errors ; @@ -1210,8 +1177,7 @@ /* * called by SMT to calculate LEM bit error rate */ -void sm_lem_evaluate(smc) -struct s_smc *smc ; +void sm_lem_evaluate(struct s_smc *smc) { int np ; @@ -1219,9 +1185,7 @@ lem_evaluate(smc,&smc->y[np]) ; } -static void lem_check_lct(smc,phy) -struct s_smc *smc ; -struct s_phy *phy ; +static void lem_check_lct(struct s_smc *smc, struct s_phy *phy) { struct lem_counter *lem = &phy->lem ; struct fddi_mib_p *mib ; @@ -1265,10 +1229,7 @@ /* * LEM functions */ -static void sm_ph_lem_start(smc,np,threshold) -struct s_smc *smc ; -int np; -int threshold; +static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold) { struct lem_counter *lem = &smc->y[np].lem ; @@ -1286,9 +1247,7 @@ SETMASK(PLC(np,PL_INTR_MASK),PL_LE_CTR,PL_LE_CTR) ; } -static void sm_ph_lem_stop(smc,np) -struct s_smc *smc ; -int np; +static void sm_ph_lem_stop(struct s_smc *smc, int np) { struct lem_counter *lem = &smc->y[np].lem ; @@ -1297,10 +1256,8 @@ } /* ARGSUSED */ -void sm_pm_ls_latch(smc,phy,on_off) -struct s_smc *smc ; -int phy; -int on_off; /* en- or disable ident. ls */ +void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off) +/* int on_off; en- or disable ident. ls */ { SK_UNUSED(smc) ; @@ -1317,10 +1274,7 @@ /* * PCM pseudo code 5.1 .. 6.1 */ -static void pc_rcode_actions(smc,bit,phy) -struct s_smc *smc ; -int bit; -struct s_phy *phy; +static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy) { struct fddi_mib_p *mib ; @@ -1456,10 +1410,7 @@ /* * PCM pseudo code 5.1 .. 6.1 */ -static void pc_tcode_actions(smc,bit,phy) -struct s_smc *smc ; -const int bit; -struct s_phy *phy; +static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy) { int np = phy->np ; struct fddi_mib_p *mib ; @@ -1638,8 +1589,7 @@ /* * return status twisted (called by SMT) */ -int pcm_status_twisted(smc) -struct s_smc *smc ; +int pcm_status_twisted(struct s_smc *smc) { int twist = 0 ; if (smc->s.sas != SMT_DAS) @@ -1658,13 +1608,8 @@ * remote phy type * remote mac yes/no */ -void pcm_status_state(smc,np,type,state,remote,mac) -struct s_smc *smc ; -int np; -int *type; -int *state; -int *remote; -int *mac; +void pcm_status_state(struct s_smc *smc, int np, int *type, int *state, + int *remote, int *mac) { struct s_phy *phy = &smc->y[np] ; struct fddi_mib_p *mib ; @@ -1687,8 +1632,7 @@ /* * return rooted station status (called by SMT) */ -int pcm_rooted_station(smc) -struct s_smc *smc ; +int pcm_rooted_station(struct s_smc *smc) { int n ; @@ -1703,10 +1647,8 @@ /* * Interrupt actions for PLC & PCM events */ -void plc_irq(smc,np,cmd) -struct s_smc *smc ; -int np; /* PHY index */ -unsigned int cmd; +void plc_irq(struct s_smc *smc, int np, unsigned int cmd) +/* int np; PHY index */ { struct s_phy *phy = &smc->y[np] ; struct s_plc *plc = &phy->plc ; @@ -1919,9 +1861,7 @@ #endif } -void pcm_set_lct_short(smc,n) -struct s_smc *smc ; -int n ; +void pcm_set_lct_short(struct s_smc *smc, int n) { if (n <= 0 || n > 1000) return ; @@ -1932,9 +1872,7 @@ /* * fill state struct */ -void pcm_get_state(smc,state) -struct s_smc *smc ; -struct smt_state *state ; +void pcm_get_state(struct s_smc *smc, struct smt_state *state) { struct s_phy *phy ; struct pcm_state *pcs ; @@ -1968,9 +1906,7 @@ } } -int get_pcm_state(smc,np) -struct s_smc *smc ; -int np; +int get_pcm_state(struct s_smc *smc, int np) { int pcs ; @@ -1992,9 +1928,7 @@ return(pcs) ; } -char *get_linestate(smc,np) -struct s_smc *smc ; -int np; +char *get_linestate(struct s_smc *smc, int np) { char *ls = "" ; @@ -2016,9 +1950,7 @@ return(ls) ; } -char *get_pcmstate(smc,np) -struct s_smc *smc ; -int np; +char *get_pcmstate(struct s_smc *smc, int np) { char *pcs ; @@ -2040,8 +1972,7 @@ return(pcs) ; } -void list_phy(smc) -struct s_smc *smc ; +void list_phy(struct s_smc *smc) { struct s_plc *plc ; int np ; @@ -2069,8 +2000,7 @@ #ifdef CONCENTRATOR -void pcm_lem_dump(smc) -struct s_smc *smc ; +void pcm_lem_dump(struct s_smc *smc) { int i ; struct s_phy *phy ; diff -Nru a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c --- a/drivers/net/skfp/pmf.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/skfp/pmf.c 2004-06-26 17:09:20 -07:00 @@ -32,12 +32,16 @@ static const char ID_sccs[] = "@(#)pmf.c 1.37 97/08/04 (C) SK " ; #endif -static int smt_authorize() ; -static int smt_check_set_count() ; -static const struct s_p_tab *smt_get_ptab() ; -static int smt_mib_phys() ; -int smt_set_para() ; -void smt_add_para() ; +static int smt_authorize(struct s_smc *smc, struct smt_header *sm); +static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm); +static const struct s_p_tab* smt_get_ptab(u_short para); +static int smt_mib_phys(struct s_smc *smc); +int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local, + int set); +void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, + int index, int local); +static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, + int set, int local); #define MOFFSS(e) ((int)&(((struct fddi_mib *)0)->e)) #define MOFFSA(e) ((int) (((struct fddi_mib *)0)->e)) @@ -280,13 +284,7 @@ { 0 } } ; - -static SMbuf *smt_build_pmf_response() ; - -void smt_pmf_received_pack(smc,mb,local) -struct s_smc *smc ; -SMbuf *mb ; -int local ; +void smt_pmf_received_pack(struct s_smc *smc, SMbuf *mb, int local) { struct smt_header *sm ; SMbuf *reply ; @@ -316,13 +314,8 @@ } } -extern SMbuf *smt_get_mbuf() ; - -static SMbuf *smt_build_pmf_response(smc,req,set,local) -struct s_smc *smc ; -struct smt_header *req ; -int set ; -int local ; +static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, + int set, int local) { SMbuf *mb ; struct smt_header *smt ; @@ -509,11 +502,7 @@ return(mb) ; } -extern void *sm_to_para() ; - -static int smt_authorize(smc,sm) -struct s_smc *smc ; -struct smt_header *sm ; +static int smt_authorize(struct s_smc *smc, struct smt_header *sm) { struct smt_para *pa ; int i ; @@ -548,9 +537,7 @@ return(0) ; } -static int smt_check_set_count(smc,sm) -struct s_smc *smc ; -struct smt_header *sm ; +static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm) { struct smt_para *pa ; struct smt_p_setcount *sc ; @@ -566,12 +553,8 @@ return(0) ; } -void smt_add_para(smc,pcon,para,index,local) -struct s_smc *smc ; -struct s_pcon *pcon ; -u_short para ; -int index ; -int local ; +void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, + int index, int local) { struct smt_para *pa ; const struct s_p_tab *pt ; @@ -1095,12 +1078,8 @@ /* * set parameter */ -int smt_set_para(smc,pa,index,local,set) -struct s_smc *smc ; -struct smt_para *pa ; -int index ; -int local ; -int set ; +int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local, + int set) { #define IFSET(x) if (set) (x) @@ -1549,8 +1528,7 @@ #endif } -static const struct s_p_tab *smt_get_ptab(para) -u_short para ; +static const struct s_p_tab *smt_get_ptab(u_short para) { const struct s_p_tab *pt ; for (pt = p_tab ; pt->p_num && pt->p_num != para ; pt++) @@ -1558,8 +1536,7 @@ return(pt->p_num ? pt : 0) ; } -static int smt_mib_phys(smc) -struct s_smc *smc ; +static int smt_mib_phys(struct s_smc *smc) { #ifdef CONCENTRATOR SK_UNUSED(smc) ; @@ -1572,9 +1549,7 @@ #endif } -int port_to_mib(smc,p) -struct s_smc *smc ; -int p ; +int port_to_mib(struct s_smc *smc, int p) { #ifdef CONCENTRATOR SK_UNUSED(smc) ; @@ -1590,10 +1565,7 @@ #ifdef DEBUG #ifndef BOOT -void dump_smt(smc,sm,text) -struct s_smc *smc ; -struct smt_header *sm ; -char *text ; +void dump_smt(struct s_smc *smc, struct smt_header *sm, char *text) { int len ; struct smt_para *pa ; @@ -1680,9 +1652,7 @@ printf("-------------------------------------------------\n\n") ; } -void dump_hex(p,len) -char *p ; -int len ; +void dump_hex(char *p, int len) { int n = 0 ; while (len--) { diff -Nru a/drivers/net/skfp/queue.c b/drivers/net/skfp/queue.c --- a/drivers/net/skfp/queue.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/skfp/queue.c 2004-06-26 17:09:20 -07:00 @@ -31,8 +31,7 @@ /* * init event queue management */ -void ev_init(smc) -struct s_smc *smc ; +void ev_init(struct s_smc *smc) { smc->q.ev_put = smc->q.ev_get = smc->q.ev_queue ; } @@ -40,10 +39,7 @@ /* * add event to queue */ -void queue_event(smc,class,event) -struct s_smc *smc ; -int class ; -int event ; +void queue_event(struct s_smc *smc, int class, int event) { PRINTF("queue class %d event %d\n",class,event) ; smc->q.ev_put->class = class ; @@ -59,9 +55,7 @@ /* * timer_event is called from HW timer package. */ -void timer_event(smc,token) -struct s_smc *smc ; -u_long token ; +void timer_event(struct s_smc *smc, u_long token) { PRINTF("timer event class %d token %d\n", EV_T_CLASS(token), @@ -76,8 +70,7 @@ * send command to state machine * end */ -void ev_dispatcher(smc) -struct s_smc *smc ; +void ev_dispatcher(struct s_smc *smc) { struct event_queue *ev ; /* pointer into queue */ int class ; @@ -131,9 +124,7 @@ * on 0 disconnect * on 1 connect */ -u_short smt_online(smc,on) -struct s_smc *smc ; -int on ; +u_short smt_online(struct s_smc *smc, int on) { queue_event(smc,EVENT_ECM,on ? EC_CONNECT : EC_DISCONNECT) ; ev_dispatcher(smc) ; @@ -147,10 +138,7 @@ * dump current flag setting */ #ifdef CONCENTRATOR -void do_smt_flag(smc,flag,value) -struct s_smc *smc ; -char *flag ; -int value ; +void do_smt_flag(struct s_smc *smc, char *flag, int value) { #ifdef DEBUG struct smt_debug *deb; diff -Nru a/drivers/net/skfp/rmt.c b/drivers/net/skfp/rmt.c --- a/drivers/net/skfp/rmt.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/skfp/rmt.c 2004-06-26 17:09:20 -07:00 @@ -102,17 +102,17 @@ /* * function declarations */ -static void rmt_fsm() ; -static void start_rmt_timer0() ; -static void start_rmt_timer1() ; -static void start_rmt_timer2() ; -static void stop_rmt_timer0() ; -static void stop_rmt_timer1() ; -static void stop_rmt_timer2() ; -static void rmt_dup_actions() ; -static void rmt_reinsert_actions() ; -static void rmt_leave_actions() ; -static void rmt_new_dup_actions() ; +static void rmt_fsm(struct s_smc *smc, int cmd); +static void start_rmt_timer0(struct s_smc *smc, u_long value, int event); +static void start_rmt_timer1(struct s_smc *smc, u_long value, int event); +static void start_rmt_timer2(struct s_smc *smc, u_long value, int event); +static void stop_rmt_timer0(struct s_smc *smc); +static void stop_rmt_timer1(struct s_smc *smc); +static void stop_rmt_timer2(struct s_smc *smc); +static void rmt_dup_actions(struct s_smc *smc); +static void rmt_reinsert_actions(struct s_smc *smc); +static void rmt_leave_actions(struct s_smc *smc); +static void rmt_new_dup_actions(struct s_smc *smc); #ifndef SUPERNET_3 extern void restart_trt_for_dbcn() ; @@ -122,8 +122,7 @@ init RMT state machine clear all RMT vars and flags */ -void rmt_init(smc) -struct s_smc *smc ; +void rmt_init(struct s_smc *smc) { smc->mib.m[MAC0].fddiMACRMTState = ACTIONS(RM0_ISOLATED) ; smc->r.dup_addr_test = DA_NONE ; @@ -145,9 +144,7 @@ process event until SM is stable */ -void rmt(smc,event) -struct s_smc *smc ; -int event ; +void rmt(struct s_smc *smc, int event) { int state ; @@ -166,9 +163,7 @@ /* process RMT event */ -static void rmt_fsm(smc,cmd) -struct s_smc *smc ; -int cmd ; +static void rmt_fsm(struct s_smc *smc, int cmd) { /* * RM00-RM70 : from all states @@ -535,8 +530,7 @@ * (jd) RMT duplicate address actions * leave the ring or reinsert just as configured */ -static void rmt_dup_actions(smc) -struct s_smc *smc ; +static void rmt_dup_actions(struct s_smc *smc) { if (smc->r.jm_flag) { } @@ -555,8 +549,7 @@ /* * Reconnect to the Ring */ -static void rmt_reinsert_actions(smc) -struct s_smc *smc ; +static void rmt_reinsert_actions(struct s_smc *smc) { queue_event(smc,EVENT_ECM,EC_DISCONNECT) ; queue_event(smc,EVENT_ECM,EC_CONNECT) ; @@ -565,8 +558,7 @@ /* * duplicate address detected */ -static void rmt_new_dup_actions(smc) -struct s_smc *smc ; +static void rmt_new_dup_actions(struct s_smc *smc) { smc->r.da_flag = TRUE ; smc->r.bn_flag = FALSE ; @@ -591,8 +583,7 @@ /* * leave the ring */ -static void rmt_leave_actions(smc) -struct s_smc *smc ; +static void rmt_leave_actions(struct s_smc *smc) { queue_event(smc,EVENT_ECM,EC_DISCONNECT) ; /* @@ -605,10 +596,7 @@ * SMT timer interface * start RMT timer 0 */ -static void start_rmt_timer0(smc,value,event) -struct s_smc *smc ; -u_long value ; -int event ; +static void start_rmt_timer0(struct s_smc *smc, u_long value, int event) { smc->r.timer0_exp = FALSE ; /* clear timer event flag */ smt_timer_start(smc,&smc->r.rmt_timer0,value,EV_TOKEN(EVENT_RMT,event)); @@ -618,10 +606,7 @@ * SMT timer interface * start RMT timer 1 */ -static void start_rmt_timer1(smc,value,event) -struct s_smc *smc ; -u_long value ; -int event ; +static void start_rmt_timer1(struct s_smc *smc, u_long value, int event) { smc->r.timer1_exp = FALSE ; /* clear timer event flag */ smt_timer_start(smc,&smc->r.rmt_timer1,value,EV_TOKEN(EVENT_RMT,event)); @@ -631,10 +616,7 @@ * SMT timer interface * start RMT timer 2 */ -static void start_rmt_timer2(smc,value,event) -struct s_smc *smc ; -u_long value ; -int event ; +static void start_rmt_timer2(struct s_smc *smc, u_long value, int event) { smc->r.timer2_exp = FALSE ; /* clear timer event flag */ smt_timer_start(smc,&smc->r.rmt_timer2,value,EV_TOKEN(EVENT_RMT,event)); @@ -644,8 +626,7 @@ * SMT timer interface * stop RMT timer 0 */ -static void stop_rmt_timer0(smc) -struct s_smc *smc ; +static void stop_rmt_timer0(struct s_smc *smc) { if (smc->r.rmt_timer0.tm_active) smt_timer_stop(smc,&smc->r.rmt_timer0) ; @@ -655,8 +636,7 @@ * SMT timer interface * stop RMT timer 1 */ -static void stop_rmt_timer1(smc) -struct s_smc *smc ; +static void stop_rmt_timer1(struct s_smc *smc) { if (smc->r.rmt_timer1.tm_active) smt_timer_stop(smc,&smc->r.rmt_timer1) ; @@ -666,9 +646,9 @@ * SMT timer interface * stop RMT timer 2 */ -static void stop_rmt_timer2(smc) -struct s_smc *smc ; +static void stop_rmt_timer2(struct s_smc *smc) { if (smc->r.rmt_timer2.tm_active) smt_timer_stop(smc,&smc->r.rmt_timer2) ; } + diff -Nru a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c --- a/drivers/net/skfp/skfddi.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/skfp/skfddi.c 2004-06-26 17:09:15 -07:00 @@ -131,20 +131,10 @@ int frag_count); int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead, int la_len); -void smt_timer_poll(struct s_smc *smc); -void ring_status_indication(struct s_smc *smc, u_long status); -unsigned long smt_get_time(void); -void smt_stat_counter(struct s_smc *smc, int stat); -void cfm_state_change(struct s_smc *smc, int c_state); -void ecm_state_change(struct s_smc *smc, int e_state); -void pcm_state_change(struct s_smc *smc, int plc, int p_state); -void rmt_state_change(struct s_smc *smc, int r_state); -void drv_reset_indication(struct s_smc *smc); void dump_data(unsigned char *Data, int length); - // External functions from the hardware module -extern u_int mac_drv_check_space(); +extern u_int mac_drv_check_space(void); extern void read_address(struct s_smc *smc, u_char * mac_addr); extern void card_stop(struct s_smc *smc); extern int mac_drv_init(struct s_smc *smc); @@ -157,9 +147,7 @@ extern void hwm_rx_frag(struct s_smc *smc, char far * virt, u_long phys, int len, int frame_status); extern void mac_drv_rx_mode(struct s_smc *smc, int mode); -extern void mac_drv_clear_tx_queue(struct s_smc *smc); extern void mac_drv_clear_rx_queue(struct s_smc *smc); -extern void mac_clear_multicast(struct s_smc *smc); extern void enable_tx_irq(struct s_smc *smc, u_short queue); extern void mac_drv_clear_txd(struct s_smc *smc); @@ -921,8 +909,7 @@ dmi = dev->mc_list; for (i = 0; i < dev->mc_count; i++) { - mac_add_multicast(smc, - dmi->dmi_addr, 1); + mac_add_multicast(smc, dmi->dmi_addr, 1); PRINTK(KERN_INFO "ENABLE MC ADDRESS:"); PRINTK(" %02x %02x %02x ", dmi->dmi_addr[0], diff -Nru a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c --- a/drivers/net/skfp/smt.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/skfp/smt.c 2004-06-26 17:09:20 -07:00 @@ -62,68 +62,63 @@ /* * external functions */ -int pcm_status_twisted() ; -void pcm_status_state() ; -int pcm_status_type() ; +int pcm_status_twisted(struct s_smc *smc); -extern SMbuf *smt_get_mbuf() ; - -#define EXPORT_PMF /* * function prototypes */ -u_long smt_get_tid() ; -EXPORT_PMF SMbuf *smt_build_frame() ; -EXPORT_PMF void *sm_to_para() ; #ifdef LITTLE_ENDIAN -static int smt_swap_short() ; +static int smt_swap_short(u_short s); #endif -static int mac_index() ; -static int phy_index() ; -static int mac_con_resource_index() ; -static int phy_con_resource_index() ; -EXPORT_PMF void smt_send_frame() ; -EXPORT_PMF void smt_set_timestamp() ; -static void smt_send_rdf() ; -static void smt_send_nif() ; -static void smt_send_ecf() ; -static void smt_echo_test() ; -static void smt_send_sif_config() ; -static void smt_send_sif_operation() ; -EXPORT_PMF void smt_swap_para() ; +static int mac_index(struct s_smc *smc, int mac); +static int phy_index(struct s_smc *smc, int phy); +static int mac_con_resource_index(struct s_smc *smc, int mac); +static int phy_con_resource_index(struct s_smc *smc, int phy); +static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason, + int local); +static void smt_send_nif(struct s_smc *smc, struct fddi_addr *dest, int fc, + u_long tid, int type, int local); +static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc, + u_long tid, int type, int len); +static void smt_echo_test(struct s_smc *smc, int dna); +static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest, + u_long tid, int local); +static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest, + u_long tid, int local); #ifdef LITTLE_ENDIAN -static void smt_string_swap() ; +static void smt_string_swap(void); #endif -static void smt_add_frame_len() ; -static void smt_fill_una() ; -static void smt_fill_sde() ; -static void smt_fill_state() ; -static void smt_fill_timestamp() ; -static void smt_fill_policy() ; -static void smt_fill_latency() ; -static void smt_fill_neighbor() ; -static int smt_fill_path() ; -static void smt_fill_mac_status() ; -static void smt_fill_lem() ; -static void smt_fill_version() ; -static void smt_fill_fsc() ; -static void smt_fill_mac_counter() ; -static void smt_fill_mac_fnc() ; -static void smt_fill_manufacturer() ; -static void smt_fill_user() ; -static void smt_fill_setcount() ; -static void smt_fill_echo() ; -int smt_check_para() ; +static void smt_add_frame_len(SMbuf *mb, int len); +static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una); +static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde); +static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state); +static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts); +static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy); +static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency); +static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor); +static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path); +static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st); +static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy); +static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers); +static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc); +static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc); +static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc); +static void smt_fill_manufacturer(struct s_smc *smc, + struct smp_p_manufacturer *man); +static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user); +static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount); +static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed, + int len); -void smt_clear_una_dna() ; -static void smt_clear_old_una_dna() ; +void smt_clear_una_dna(struct s_smc *smc); +static void smt_clear_old_una_dna(struct s_smc *smc); #ifdef CONCENTRATOR -static int entity_to_index() ; +static int entity_to_index(void); #endif -static void update_dac() ; -static int div_ratio() ; +static void update_dac(struct s_smc *smc, int report); +static int div_ratio(u_long upper, u_long lower); #ifdef USE_CAN_ADDR -void hwm_conv_can() ; +void hwm_conv_can(struct s_smc *smc, char *data, int len); #else #define hwm_conv_can(smc,data,len) #endif @@ -136,8 +131,7 @@ /* * init SMT agent */ -void smt_agent_init(smc) -struct s_smc *smc ; +void smt_agent_init(struct s_smc *smc) { int i ; @@ -183,17 +177,16 @@ * check tvu & tvd * end */ -void smt_agent_task(smc) -struct s_smc *smc ; +void smt_agent_task(struct s_smc *smc) { smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L, EV_TOKEN(EVENT_SMT,SM_TIMER)) ; DB_SMT("SMT agent task\n",0,0) ; } -void smt_please_reconnect(smc,reconn_time) -struct s_smc *smc ; /* Pointer to SMT context */ -int reconn_time ; /* Wait for reconnect time in seconds */ +void smt_please_reconnect(struct s_smc *smc, int reconn_time) +/* struct s_smc *smc; Pointer to SMT context */ +/* int reconn_time; Wait for reconnect time in seconds */ { /* * The please reconnect variable is used as a timer. @@ -210,9 +203,7 @@ } #ifndef SMT_REAL_TOKEN_CT -void smt_emulate_token_ct(smc, mac_index) -struct s_smc *smc; -int mac_index; +void smt_emulate_token_ct(struct s_smc *smc, int mac_index) { u_long count; u_long time; @@ -239,9 +230,7 @@ #endif /*ARGSUSED1*/ -void smt_event(smc,event) -struct s_smc *smc ; -int event ; +void smt_event(struct s_smc *smc, int event) { u_long time ; #ifndef SMT_REAL_TOKEN_CT @@ -457,9 +446,7 @@ EV_TOKEN(EVENT_SMT,SM_TIMER)) ; } -static int div_ratio(upper,lower) -u_long upper ; -u_long lower ; +static int div_ratio(u_long upper, u_long lower) { if ((upper<<16L) < upper) upper = 0xffff0000L ; @@ -475,10 +462,8 @@ /* * receive packet handler */ -void smt_received_pack(smc,mb,fs) -struct s_smc *smc ; -SMbuf *mb ; -int fs ; /* frame status */ +void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs) +/* int fs; frame status */ { struct smt_header *sm ; int local ; @@ -823,9 +808,7 @@ smt_free_mbuf(smc,mb) ; } -static void update_dac(smc,report) -struct s_smc *smc ; -int report ; +static void update_dac(struct s_smc *smc, int report) { int cond ; @@ -843,11 +826,9 @@ * set station ID * send frame */ -EXPORT_PMF void smt_send_frame(smc,mb,fc,local) -struct s_smc *smc ; -SMbuf *mb ; /* buffer to send */ -int fc ; /* FC value */ -int local ; +void smt_send_frame(struct s_smc *smc, SMbuf *mb, int fc, int local) +/* SMbuf *mb; buffer to send */ +/* int fc; FC value */ { struct smt_header *sm ; @@ -868,12 +849,11 @@ /* * generate and send RDF */ -static void smt_send_rdf(smc,rej,fc,reason,local) -struct s_smc *smc ; -SMbuf *rej ; /* mbuf of offending frame */ -int fc ; /* FC of denied frame */ -int reason ; /* reason code */ -int local ; +static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason, + int local) +/* SMbuf *rej; mbuf of offending frame */ +/* int fc; FC of denied frame */ +/* int reason; reason code */ { SMbuf *mb ; struct smt_header *sm ; /* header of offending frame */ @@ -946,13 +926,12 @@ /* * generate and send NIF */ -static void smt_send_nif(smc,dest,fc,tid,type,local) -struct s_smc *smc ; -struct fddi_addr *dest ; /* dest address */ -int fc ; /* frame control */ -u_long tid ; /* transaction id */ -int type ; /* frame type */ -int local ; +static void smt_send_nif(struct s_smc *smc, struct fddi_addr *dest, int fc, + u_long tid, int type, int local) +/* struct fddi_addr *dest; dest address */ +/* int fc; frame control */ +/* u_long tid; transaction id */ +/* int type; frame type */ { struct smt_nif *nif ; SMbuf *mb ; @@ -976,9 +955,7 @@ /* * send NIF request (test purpose) */ -static void smt_send_nif_request(smc,dest) -struct s_smc *smc ; -struct fddi_addr *dest ; +static void smt_send_nif_request(struct s_smc *smc, struct fddi_addr *dest) { smc->sm.pend[SMT_TID_NIF_TEST] = smt_get_tid(smc) ; smt_send_nif(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_NIF_TEST], @@ -988,10 +965,8 @@ /* * send ECF request (test purpose) */ -static void smt_send_ecf_request(smc,dest,len) -struct s_smc *smc ; -struct fddi_addr *dest ; -int len ; +static void smt_send_ecf_request(struct s_smc *smc, struct fddi_addr *dest, + int len) { smc->sm.pend[SMT_TID_ECF] = smt_get_tid(smc) ; smt_send_ecf(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_ECF], @@ -1002,9 +977,7 @@ /* * echo test */ -static void smt_echo_test(smc,dna) -struct s_smc *smc ; -int dna ; +static void smt_echo_test(struct s_smc *smc, int dna) { u_long tid ; @@ -1019,13 +992,13 @@ /* * generate and send ECF */ -static void smt_send_ecf(smc,dest,fc,tid,type,len) -struct s_smc *smc ; -struct fddi_addr *dest ; /* dest address */ -int fc ; /* frame control */ -u_long tid ; /* transaction id */ -int type ; /* frame type */ -int len ; /* frame length */ +static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc, + u_long tid, int type, int len) +/* struct fddi_addr *dest; dest address */ +/* int fc; frame control */ +/* u_long tid; transaction id */ +/* int type; frame type */ +/* int len; frame length */ { struct smt_ecf *ecf ; SMbuf *mb ; @@ -1045,11 +1018,10 @@ * generate and send SIF config response */ -static void smt_send_sif_config(smc,dest,tid,local) -struct s_smc *smc ; -struct fddi_addr *dest ; /* dest address */ -u_long tid ; /* transaction id */ -int local ; +static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest, + u_long tid, int local) +/* struct fddi_addr *dest; dest address */ +/* u_long tid; transaction id */ { struct smt_sif_config *sif ; SMbuf *mb ; @@ -1079,11 +1051,10 @@ * generate and send SIF operation response */ -static void smt_send_sif_operation(smc,dest,tid,local) -struct s_smc *smc ; -struct fddi_addr *dest ; /* dest address */ -u_long tid ; /* transaction id */ -int local ; +static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest, + u_long tid, int local) +/* struct fddi_addr *dest; dest address */ +/* u_long tid; transaction id */ { struct smt_sif_operation *sif ; SMbuf *mb ; @@ -1128,11 +1099,8 @@ /* * get and initialize SMT frame */ -EXPORT_PMF SMbuf *smt_build_frame(smc,class,type,length) -struct s_smc *smc ; -int class ; -int type ; -int length ; +SMbuf *smt_build_frame(struct s_smc *smc, int class, int type, + int length) { SMbuf *mb ; struct smt_header *smt ; @@ -1167,9 +1135,7 @@ return(mb) ; } -static void smt_add_frame_len(mb,len) -SMbuf *mb ; -int len ; +static void smt_add_frame_len(SMbuf *mb, int len) { struct smt_header *smt ; @@ -1183,9 +1149,7 @@ /* * fill values in UNA parameter */ -static void smt_fill_una(smc,una) -struct s_smc *smc ; -struct smt_p_una *una ; +static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una) { SMTSETPARA(una,SMT_P_UNA) ; una->una_pad = 0 ; @@ -1195,9 +1159,7 @@ /* * fill values in SDE parameter */ -static void smt_fill_sde(smc,sde) -struct s_smc *smc ; -struct smt_p_sde *sde ; +static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde) { SMTSETPARA(sde,SMT_P_SDE) ; sde->sde_non_master = smc->mib.fddiSMTNonMaster_Ct ; @@ -1213,9 +1175,7 @@ /* * fill in values in station state parameter */ -static void smt_fill_state(smc,state) -struct s_smc *smc ; -struct smt_p_state *state ; +static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state) { int top ; int twist ; @@ -1255,18 +1215,14 @@ /* * fill values in timestamp parameter */ -static void smt_fill_timestamp(smc,ts) -struct s_smc *smc ; -struct smt_p_timestamp *ts ; +static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts) { SMTSETPARA(ts,SMT_P_TIMESTAMP) ; smt_set_timestamp(smc,ts->ts_time) ; } -EXPORT_PMF void smt_set_timestamp(smc,p) -struct s_smc *smc ; -u_char *p ; +void smt_set_timestamp(struct s_smc *smc, u_char *p) { u_long time ; u_long utime ; @@ -1300,9 +1256,7 @@ /* * fill values in station policy parameter */ -static void smt_fill_policy(smc,policy) -struct s_smc *smc ; -struct smt_p_policy *policy ; +static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy) { int i ; u_char *map ; @@ -1333,9 +1287,7 @@ /* * fill values in latency equivalent parameter */ -static void smt_fill_latency(smc,latency) -struct s_smc *smc ; -struct smt_p_latency *latency ; +static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency) { SMTSETPARA(latency,SMT_P_LATENCY) ; @@ -1358,9 +1310,7 @@ /* * fill values in MAC neighbors parameter */ -static void smt_fill_neighbor(smc,neighbor) -struct s_smc *smc ; -struct smt_p_neighbor *neighbor ; +static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor) { SMTSETPARA(neighbor,SMT_P_NEIGHBORS) ; @@ -1379,9 +1329,7 @@ #define ALLPHYS ((smc->s.sas == SMT_SAS) ? 1 : 2) #endif -static int smt_fill_path(smc,path) -struct s_smc *smc ; -struct smt_p_path *path ; +static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path) { SK_LOC_DECL(int,type) ; SK_LOC_DECL(int,state) ; @@ -1429,9 +1377,7 @@ /* * fill values in mac status */ -static void smt_fill_mac_status(smc,st) -struct s_smc *smc ; -struct smt_p_mac_status *st ; +static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st) { SMTSETPARA(st,SMT_P_MAC_STATUS) ; @@ -1458,11 +1404,7 @@ /* * fill values in LEM status */ - -static void smt_fill_lem(smc,lem,phy) -struct s_smc *smc ; -struct smt_p_lem *lem ; -int phy ; +static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy) { struct fddi_mib_p *mib ; @@ -1484,9 +1426,7 @@ /* * fill version parameter */ -static void smt_fill_version(smc,vers) -struct s_smc *smc ; -struct smt_p_version *vers ; +static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers) { SK_UNUSED(smc) ; SMTSETPARA(vers,SMT_P_VERSION) ; @@ -1505,9 +1445,7 @@ * note: this para 200B is NOT in swap table, because it's also set in * PMF add_para */ -static void smt_fill_fsc(smc,fsc) -struct s_smc *smc ; -struct smt_p_fsc *fsc ; +static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc) { SK_UNUSED(smc) ; SMTSETPARA(fsc,SMT_P_FSC) ; @@ -1527,9 +1465,7 @@ /* * fill mac counter field */ -static void smt_fill_mac_counter(smc,mc) -struct s_smc *smc ; -struct smt_p_mac_counter *mc ; +static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc) { SMTSETPARA(mc,SMT_P_MAC_COUNTER) ; mc->mc_mib_index = INDEX_MAC ; @@ -1541,9 +1477,7 @@ /* * fill mac frame not copied counter */ -static void smt_fill_mac_fnc(smc,fnc) -struct s_smc *smc ; -struct smt_p_mac_fnc *fnc ; +static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc) { SMTSETPARA(fnc,SMT_P_MAC_FNC) ; fnc->nc_mib_index = INDEX_MAC ; @@ -1555,9 +1489,8 @@ /* * fill manufacturer field */ -static void smt_fill_manufacturer(smc,man) -struct s_smc *smc ; -struct smp_p_manufacturer *man ; +static void smt_fill_manufacturer(struct s_smc *smc, + struct smp_p_manufacturer *man) { SMTSETPARA(man,SMT_P_MANUFACTURER) ; memcpy((char *) man->mf_data, @@ -1568,9 +1501,7 @@ /* * fill user field */ -static void smt_fill_user(smc,user) -struct s_smc *smc ; -struct smp_p_user *user ; +static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user) { SMTSETPARA(user,SMT_P_USER) ; memcpy((char *) user->us_data, @@ -1578,14 +1509,10 @@ sizeof(user->us_data)) ; } - - /* * fill set count */ -static void smt_fill_setcount(smc,setcount) -struct s_smc *smc ; -struct smt_p_setcount *setcount ; +static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount) { SK_UNUSED(smc) ; SMTSETPARA(setcount,SMT_P_SETCOUNT) ; @@ -1597,13 +1524,9 @@ /* * fill echo data */ -static void smt_fill_echo(smc,echo,seed,len) -struct s_smc *smc ; -struct smt_p_echo *echo ; -u_long seed ; -int len ; +static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed, + int len) { - u_char *p ; SK_UNUSED(smc) ; @@ -1619,22 +1542,19 @@ * clear DNA and UNA * called from CFM if configuration changes */ -void smt_clear_una_dna(smc) -struct s_smc *smc ; +void smt_clear_una_dna(struct s_smc *smc) { smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ; } -static void smt_clear_old_una_dna(smc) -struct s_smc *smc ; +static void smt_clear_old_una_dna(struct s_smc *smc) { smc->mib.m[MAC0].fddiMACOldUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACOldDownstreamNbr = SMT_Unknown ; } -u_long smt_get_tid(smc) -struct s_smc *smc ; +u_long smt_get_tid(struct s_smc *smc) { u_long tid ; while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0) @@ -1723,10 +1643,8 @@ #define N_SMT_PLEN (sizeof(smt_pdef)/sizeof(smt_pdef[0])) -int smt_check_para(smc,sm,list) -struct s_smc *smc ; -struct smt_header *sm ; -const u_short list[] ; +int smt_check_para(struct s_smc *smc, struct smt_header *sm, + const u_short list[]) { const u_short *p = list ; while (*p) { @@ -1739,10 +1657,7 @@ return(0) ; } -EXPORT_PMF void *sm_to_para(smc,sm,para) -struct s_smc *smc ; -struct smt_header *sm ; -int para ; +void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para) { char *p ; int len ; @@ -1773,9 +1688,7 @@ return(0) ; } -int is_my_addr(smc,addr) -struct s_smc *smc ; -struct fddi_addr *addr ; +int is_my_addr(struct s_smc *smc, struct fddi_addr *addr) { return(*(short *)(&addr->a[0]) == *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[0]) @@ -1785,31 +1698,26 @@ *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[4])) ; } -int is_zero(addr) -struct fddi_addr *addr ; +int is_zero(struct fddi_addr *addr) { return(*(short *)(&addr->a[0]) == 0 && *(short *)(&addr->a[2]) == 0 && *(short *)(&addr->a[4]) == 0 ) ; } -int is_broadcast(addr) -struct fddi_addr *addr ; +int is_broadcast(struct fddi_addr *addr) { return(*(u_short *)(&addr->a[0]) == 0xffff && *(u_short *)(&addr->a[2]) == 0xffff && *(u_short *)(&addr->a[4]) == 0xffff ) ; } -int is_individual(addr) -struct fddi_addr *addr ; +int is_individual(struct fddi_addr *addr) { return(!(addr->a[0] & GROUP_ADDR)) ; } -int is_equal(addr1,addr2) -struct fddi_addr *addr1 ; -struct fddi_addr *addr2 ; +int is_equal(struct fddi_addr *addr1, struct fddi_addr *addr2) { return(*(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) && *(u_short *)(&addr1->a[2]) == *(u_short *)(&addr2->a[2]) && @@ -1821,9 +1729,7 @@ /* * send ANTC data test frame */ -void fddi_send_antc(smc,dest) -struct s_smc *smc ; -struct fddi_addr *dest ; +void fddi_send_antc(struct s_smc *smc, struct fddi_addr *dest) { SK_UNUSED(smc) ; SK_UNUSED(dest) ; @@ -1850,8 +1756,7 @@ #ifdef DEBUG #define hextoasc(x) "0123456789abcdef"[x] -char *addr_to_string(addr) -struct fddi_addr *addr ; +char *addr_to_string(struct fddi_addr *addr) { int i ; static char string[6*3] = "****" ; @@ -1867,9 +1772,7 @@ #endif #ifdef AM29K -smt_ifconfig(argc,argv) -int argc ; -char *argv[] ; +smt_ifconfig(int argc, char *argv[]) { if (argc >= 2 && !strcmp(argv[0],"opt_bypass") && !strcmp(argv[1],"yes")) { @@ -1883,9 +1786,7 @@ /* * return static mac index */ -static int mac_index(smc,mac) -struct s_smc *smc ; -int mac ; +static int mac_index(struct s_smc *smc, int mac) { SK_UNUSED(mac) ; #ifdef CONCENTRATOR @@ -1899,9 +1800,7 @@ /* * return static phy index */ -static int phy_index(smc,phy) -struct s_smc *smc ; -int phy ; +static int phy_index(struct s_smc *smc, int phy) { SK_UNUSED(smc) ; return(phy+1); @@ -1910,9 +1809,7 @@ /* * return dynamic mac connection resource index */ -static int mac_con_resource_index(smc,mac) -struct s_smc *smc ; -int mac ; +static int mac_con_resource_index(struct s_smc *smc, int mac) { #ifdef CONCENTRATOR SK_UNUSED(smc) ; @@ -1936,9 +1833,7 @@ /* * return dynamic phy connection resource index */ -static int phy_con_resource_index(smc,phy) -struct s_smc *smc ; -int phy ; +static int phy_con_resource_index(struct s_smc *smc, int phy) { #ifdef CONCENTRATOR return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_PHY(phy)))) ; @@ -1960,9 +1855,7 @@ } #ifdef CONCENTRATOR -static int entity_to_index(smc,e) -struct s_smc *smc ; -int e ; +static int entity_to_index(struct s_smc *smc, int e) { if (e == ENTITY_MAC) return(mac_index(smc,1)) ; @@ -1972,16 +1865,13 @@ #endif #ifdef LITTLE_ENDIAN -static int smt_swap_short(s) -u_short s ; +static int smt_swap_short(u_short s) { return(((s>>8)&0xff)|((s&0xff)<<8)) ; } -void smt_swap_para(sm,len,direction) -struct smt_header *sm ; -int len ; -int direction ; /* 0 encode 1 decode */ +void smt_swap_para(struct smt_header *sm, int len, int direction) +/* int direction; 0 encode 1 decode */ { struct smt_para *pa ; const struct smt_pdef *pd ; @@ -2027,10 +1917,7 @@ } } -static void smt_string_swap(data,format,len) -char *data ; -const char *format ; -int len ; +static void smt_string_swap(char *data, const char *format, int len) { const char *open_paren = 0 ; int x ; @@ -2081,10 +1968,8 @@ } } #else -void smt_swap_para(sm,len,direction) -struct smt_header *sm ; -int len ; -int direction ; /* 0 encode 1 decode */ +void smt_swap_para(struct smt_header *sm, int len, int direction) +/* int direction; 0 encode 1 decode */ { SK_UNUSED(sm) ; SK_UNUSED(len) ; @@ -2095,11 +1980,7 @@ /* * PMF actions */ -int smt_action(smc,class,code,index) -struct s_smc *smc ; -int class ; -int code ; -int index ; +int smt_action(struct s_smc *smc, int class, int code, int index) { int event ; int port ; @@ -2190,9 +2071,7 @@ * set reconnect * end */ -void smt_change_t_neg(smc,tneg) -struct s_smc *smc ; -u_long tneg ; +void smt_change_t_neg(struct s_smc *smc, u_long tneg) { smc->mib.a[PATH0].fddiPATHMaxT_Req = tneg ; @@ -2207,10 +2086,7 @@ * canonical conversion of bytes beginning form *data */ #ifdef USE_CAN_ADDR -void hwm_conv_can(smc,data,len) -struct s_smc *smc ; -char *data ; -int len ; +void hwm_conv_can(struct s_smc *smc, char *data, int len) { int i ; @@ -2223,3 +2099,4 @@ #endif #endif /* no SLIM_SMT */ + diff -Nru a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c --- a/drivers/net/skfp/smtdef.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/skfp/smtdef.c 2004-06-26 17:09:15 -07:00 @@ -72,13 +72,11 @@ #define DEFAULT_LCT_EXTEND 50 /* Forward declarations */ -extern void smt_reset_defaults (); -static void smt_init_mib (); +void smt_reset_defaults(struct s_smc *smc, int level); +static void smt_init_mib(struct s_smc *smc, int level); +static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper); -static int set_min_max() ; - -void smt_set_defaults(smc) -struct s_smc *smc ; +void smt_set_defaults(struct s_smc *smc) { smt_reset_defaults(smc,0) ; } @@ -86,9 +84,7 @@ #define MS2BCLK(x) ((x)*12500L) #define US2BCLK(x) ((x)*1250L) -void smt_reset_defaults(smc,level) -struct s_smc *smc ; -int level ; +void smt_reset_defaults(struct s_smc *smc, int level) { struct smt_config *smt ; int i ; @@ -170,9 +166,7 @@ /* 01234567890123456789012345678901 */ "xxxSK-NET FDDI SMT 7.3 - V2.8.8" ; -static void smt_init_mib(smc,level) -struct s_smc *smc ; -int level ; +static void smt_init_mib(struct s_smc *smc, int level) { struct fddi_mib *mib ; struct fddi_mib_p *pm ; @@ -292,8 +286,7 @@ (void) smt_set_mac_opvalues(smc) ; } -int smt_set_mac_opvalues(smc) -struct s_smc *smc ; +int smt_set_mac_opvalues(struct s_smc *smc) { int st ; int st2 ; @@ -318,8 +311,7 @@ return(st) ; } -void smt_fixup_mib(smc) -struct s_smc *smc ; +void smt_fixup_mib(struct s_smc *smc) { #ifdef CONCENTRATOR switch (smc->s.sas) { @@ -355,11 +347,7 @@ * use mib * NOTE : numbers are negative, negate comparison ! */ -static int set_min_max(maxflag,mib,limit,oper) -int maxflag ; -u_long mib ; -u_long limit ; -u_long *oper ; +static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper) { u_long old ; old = *oper ; @@ -369,3 +357,4 @@ *oper = mib ; return(old != *oper) ; } + diff -Nru a/drivers/net/skfp/smtinit.c b/drivers/net/skfp/smtinit.c --- a/drivers/net/skfp/smtinit.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/skfp/smtinit.c 2004-06-26 17:09:20 -07:00 @@ -27,7 +27,7 @@ static const char ID_sccs[] = "@(#)smtinit.c 1.15 97/05/06 (C) SK " ; #endif -extern void init_fddi_driver() ; +void init_fddi_driver(struct s_smc *smc, u_char *mac_addr); /* define global debug variable */ #if defined(DEBUG) && !defined(DEBUG_BRD) @@ -48,8 +48,7 @@ * Can not be called in smt_reset_defaults, because it is not sure that * the OEM ID is already defined. */ -static void set_oem_spec_val(smc) -struct s_smc *smc ; +static void set_oem_spec_val(struct s_smc *smc) { struct fddi_mib *mib ; @@ -66,9 +65,8 @@ /* * Init SMT */ -int init_smt(smc,mac_addr) -struct s_smc *smc ; -u_char *mac_addr ; /* canonical address or NULL */ +int init_smt(struct s_smc *smc, u_char *mac_addr) +/* u_char *mac_addr; canonical address or NULL */ { int p ; @@ -124,3 +122,4 @@ return(0) ; } + diff -Nru a/drivers/net/skfp/smtparse.c b/drivers/net/skfp/smtparse.c --- a/drivers/net/skfp/smtparse.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/skfp/smtparse.c 2004-06-26 17:09:18 -07:00 @@ -82,8 +82,9 @@ /* * local function declarations */ -static u_long parse_num() ; -static int parse_word() ; +static u_long parse_num(int type, char _far *value, char *v, u_long mn, + u_long mx, int scale); +static int parse_word(char *buf, char _far *text); #ifdef SIM #define DB_MAIN(a,b,c) printf(a,b,c) @@ -117,11 +118,8 @@ * * END_MANUAL_ENTRY() */ -int smt_parse_arg(smc,keyword,type,value) -struct s_smc *smc ; -char _far *keyword ; -int type ; -char _far *value ; +int smt_parse_arg(struct s_smc *smc, char _far *keyword, int type, + char _far *value) { char keybuf[MAX_VAL+1]; char valbuf[MAX_VAL+1]; @@ -287,9 +285,7 @@ return(0) ; } -static int parse_word(buf,text) -char *buf ; -char _far *text ; +static int parse_word(char *buf, char _far *text) { char c ; char *p ; @@ -364,13 +360,8 @@ return(0) ; } -static u_long parse_num(type,value,v,mn,mx,scale) -int type ; -char _far *value ; -char *v ; -u_long mn ; -u_long mx ; -int scale ; +static u_long parse_num(int type, char _far *value, char *v, u_long mn, + u_long mx, int scale) { u_long x = 0 ; char c ; @@ -473,3 +464,4 @@ exit(0) ; } #endif + diff -Nru a/drivers/net/skfp/smttimer.c b/drivers/net/skfp/smttimer.c --- a/drivers/net/skfp/smttimer.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/skfp/smttimer.c 2004-06-26 17:09:16 -07:00 @@ -26,18 +26,9 @@ static const char ID_sccs[] = "@(#)smttimer.c 2.4 97/08/04 (C) SK " ; #endif -/* - * external function declarations - */ -extern u_long hwt_read() ; -extern void hwt_stop() ; -extern void hwt_start() ; +static void timer_done(struct s_smc *smc, int restart); -static void timer_done() ; - - -void smt_timer_init(smc) -struct s_smc *smc ; +void smt_timer_init(struct s_smc *smc) { smc->t.st_queue = 0 ; smc->t.st_fast.tm_active = FALSE ; @@ -45,9 +36,7 @@ hwt_init(smc) ; } -void smt_timer_stop(smc,timer) -struct s_smc *smc ; -struct smt_timer *timer ; +void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer) { struct smt_timer **prev ; struct smt_timer *tm ; @@ -70,11 +59,8 @@ } } -void smt_timer_start(smc,timer,time,token) -struct s_smc *smc ; -struct smt_timer *timer ; -u_long time ; -u_long token ; +void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time, + u_long token) { struct smt_timer **prev ; struct smt_timer *tm ; @@ -121,21 +107,17 @@ hwt_start(smc,smc->t.st_queue->tm_delta) ; } -void smt_force_irq(smc) -struct s_smc *smc ; +void smt_force_irq(struct s_smc *smc) { smt_timer_start(smc,&smc->t.st_fast,32L, EV_TOKEN(EVENT_SMT,SM_FAST)); } -void smt_timer_done(smc) -struct s_smc *smc ; +void smt_timer_done(struct s_smc *smc) { timer_done(smc,1) ; } -static void timer_done(smc,restart) -struct s_smc *smc ; -int restart ; +static void timer_done(struct s_smc *smc, int restart) { u_long delta ; struct smt_timer *tm ; @@ -171,3 +153,4 @@ if (restart && smc->t.st_queue) hwt_start(smc,smc->t.st_queue->tm_delta) ; } + diff -Nru a/drivers/net/skfp/srf.c b/drivers/net/skfp/srf.c --- a/drivers/net/skfp/srf.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/skfp/srf.c 2004-06-26 17:09:18 -07:00 @@ -38,10 +38,10 @@ /* * function declarations */ -static void clear_all_rep() ; -static void clear_reported() ; -static void smt_send_srf() ; -static struct s_srf_evc *smt_get_evc() ; +static void clear_all_rep(struct s_smc *smc); +static void clear_reported(struct s_smc *smc); +static void smt_send_srf(struct s_smc *smc); +static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index); #define MAX_EVCS (sizeof(smc->evcs)/sizeof(smc->evcs[0])) @@ -69,8 +69,7 @@ #define MAX_INIT_EVC (sizeof(evc_inits)/sizeof(evc_inits[0])) -void smt_init_evc(smc) -struct s_smc *smc ; +void smt_init_evc(struct s_smc *smc) { struct s_srf_evc *evc ; const struct evc_init *init ; @@ -159,10 +158,7 @@ smc->srf.sr_state = SR0_WAIT ; } -static struct s_srf_evc *smt_get_evc(smc,code,index) -struct s_smc *smc ; -int code ; -int index ; +static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index) { int i ; struct s_srf_evc *evc ; @@ -188,11 +184,7 @@ } ; #endif -void smt_srf_event(smc,code,index,cond) -struct s_smc *smc ; -int code ; -int index ; -int cond ; +void smt_srf_event(struct s_smc *smc, int code, int index, int cond) { struct s_srf_evc *evc ; int cond_asserted = 0 ; @@ -340,8 +332,7 @@ } } -static void clear_all_rep(smc) -struct s_smc *smc ; +static void clear_all_rep(struct s_smc *smc) { struct s_srf_evc *evc ; int i ; @@ -354,8 +345,7 @@ smc->srf.any_report = FALSE ; } -static void clear_reported(smc) -struct s_smc *smc ; +static void clear_reported(struct s_smc *smc) { struct s_srf_evc *evc ; int i ; @@ -375,13 +365,10 @@ } } -extern SMbuf *smt_build_frame() ; - /* * build and send SMT SRF frame */ -static void smt_send_srf(smc) -struct s_smc *smc ; +static void smt_send_srf(struct s_smc *smc) { struct smt_header *smt ; @@ -439,3 +426,4 @@ #endif /* no BOOT */ #endif /* no SLIM_SMT */ + diff -Nru a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c --- a/drivers/net/smc-mca.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/smc-mca.c 2004-06-26 17:09:15 -07:00 @@ -51,6 +51,8 @@ #include "8390.h" #include "smc-mca.h" +#define DRV_NAME "smc-mca" + static int ultramca_open(struct net_device *dev); static void ultramca_reset_8390(struct net_device *dev); static void ultramca_get_8390_hdr(struct net_device *dev, @@ -265,7 +267,7 @@ goto err_unclaim; } - if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) { + if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) { rc = -ENODEV; goto err_unclaim; } diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c --- a/drivers/net/smc-ultra.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/smc-ultra.c 2004-06-26 17:09:16 -07:00 @@ -72,6 +72,8 @@ #include "8390.h" +#define DRV_NAME "smc-ultra" + /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int ultra_portlist[] __initdata = {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; @@ -178,6 +180,7 @@ release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT); } +#ifndef MODULE struct net_device * __init ultra_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -202,6 +205,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init ultra_probe1(struct net_device *dev, int ioaddr) { @@ -215,7 +219,7 @@ unsigned char idreg = inb(ioaddr + 7); unsigned char reg4 = inb(ioaddr + 4) & 0x7f; - if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) return -EBUSY; /* Check the ID nibble. */ diff -Nru a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c --- a/drivers/net/smc-ultra32.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/smc-ultra32.c 2004-06-26 17:09:20 -07:00 @@ -61,6 +61,8 @@ #include "8390.h" +#define DRV_NAME "smc-ultra32" + static int ultra32_probe1(struct net_device *dev, int ioaddr); static int ultra32_open(struct net_device *dev); static void ultra32_reset_8390(struct net_device *dev); @@ -163,7 +165,7 @@ unsigned char reg4; const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; - if (!request_region(ioaddr, ULTRA32_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME)) return -EBUSY; if (inb(ioaddr + ULTRA32_IDPORT) == 0xff || diff -Nru a/drivers/net/smc9194.c b/drivers/net/smc9194.c --- a/drivers/net/smc9194.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/smc9194.c 2004-06-26 17:09:19 -07:00 @@ -78,6 +78,8 @@ #include "smc9194.h" +#define DRV_NAME "smc9194" + /*------------------------------------------------------------------------ . . Configuration options, for the experienced user to change. @@ -94,16 +96,51 @@ #define USE_32_BIT 1 #endif +#if defined(__H8300H__) || defined(__H8300S__) +#define NO_AUTOPROBE +#undef insl +#undef outsl +#define insl(a,b,l) io_insl_noswap(a,b,l) +#define outsl(a,b,l) io_outsl_noswap(a,b,l) +#endif + /* .the SMC9194 can be at any of the following port addresses. To change, .for a slightly different card, you can add it to the array. Keep in .mind that the array must end in zero. */ -static unsigned int smc_portlist[] __initdata = { - 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, - 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0 + +struct devlist { + unsigned int port; + unsigned int irq; }; +#if defined(CONFIG_H8S_EDOSK2674) +static struct devlist smc_devlist[] __initdata = { + {.port = 0xf80000, .irq = 16}, + {.port = 0, .irq = 0 }, +}; +#else +static struct devlist smc_devlist[] __initdata = { + {.port = 0x200, .irq = 0}, + {.port = 0x220, .irq = 0}, + {.port = 0x240, .irq = 0}, + {.port = 0x260, .irq = 0}, + {.port = 0x280, .irq = 0}, + {.port = 0x2A0, .irq = 0}, + {.port = 0x2C0, .irq = 0}, + {.port = 0x2E0, .irq = 0}, + {.port = 0x300, .irq = 0}, + {.port = 0x320, .irq = 0}, + {.port = 0x340, .irq = 0}, + {.port = 0x360, .irq = 0}, + {.port = 0x380, .irq = 0}, + {.port = 0x3A0, .irq = 0}, + {.port = 0x3C0, .irq = 0}, + {.port = 0x3E0, .irq = 0}, + {.port = 0, .irq = 0}, +}; +#endif /* . Wait time for memory to be free. This probably shouldn't be . tuned that much, as waiting for this means nothing else happens @@ -466,7 +503,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev ) { struct smc_local *lp = netdev_priv(dev); - unsigned short ioaddr = dev->base_addr; + unsigned int ioaddr = dev->base_addr; word length; unsigned short numPages; word time_out; @@ -580,7 +617,7 @@ byte packet_no; struct sk_buff * skb = lp->saved_skb; word length; - unsigned short ioaddr; + unsigned int ioaddr; byte * buf; ioaddr = dev->base_addr; @@ -635,7 +672,11 @@ #ifdef USE_32_BIT if ( length & 0x2 ) { outsl(ioaddr + DATA_1, buf, length >> 2 ); +#if !defined(__H8300H__) && !defined(__H8300S__) outw( *((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_1); +#else + ctrl_outw( *((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_1); +#endif } else outsl(ioaddr + DATA_1, buf, length >> 2 ); @@ -691,9 +732,12 @@ struct net_device * __init smc_init(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct smc_local)); - unsigned *port; + static struct devlist *smcdev = smc_devlist; int err = 0; +#ifndef NO_AUTOPROBE + smcdev = smc_devlist; +#endif if (!dev) return ERR_PTR(-ENODEV); @@ -711,11 +755,11 @@ } else if (io != 0) { /* Don't probe at all. */ err = -ENXIO; } else { - for (port = smc_portlist; *port; port++) { - if (smc_probe(dev, *port) == 0) + for (;smcdev->port; smcdev++) { + if (smc_probe(dev, smcdev->port) == 0) break; } - if (!*port) + if (!smcdev->port) err = -ENODEV; } if (err) @@ -741,6 +785,7 @@ */ int __init smc_findirq( int ioaddr ) { +#ifndef NO_AUTOPROBE int timeout = 20; unsigned long cookie; @@ -795,6 +840,14 @@ /* and return what I found */ return probe_irq_off(cookie); +#else /* NO_AUTOPROBE */ + struct devlist *smcdev; + for (smcdev = smc_devlist; smcdev->port; smcdev++) { + if (smcdev->port == ioaddr) + return smcdev->irq; + } + return 0; +#endif } /*---------------------------------------------------------------------- @@ -843,7 +896,7 @@ word memory_cfg_register; /* Grab the region so that no one else tries to probe our ioports. */ - if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, SMC_IO_EXTENT, DRV_NAME)) return -EBUSY; dev->irq = irq; @@ -863,6 +916,7 @@ retval = -ENODEV; goto err_out; } +#if !defined(CONFIG_H8S_EDOSK2674) /* well, we've already written once, so hopefully another time won't hurt. This time, I need to switch the bank register to bank 1, so I can access the base address register */ @@ -877,6 +931,10 @@ retval = -ENODEV; goto err_out; } +#else + (void)base_address_register; /* Warning suppression */ +#endif + /* check if the revision register is something that I recognize. These might need to be added to later, as future revisions @@ -1001,9 +1059,9 @@ memset(dev->priv, 0, sizeof(struct smc_local)); /* Grab the IRQ */ - retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev); + retval = request_irq(dev->irq, &smc_interrupt, 0, DRV_NAME, dev); if (retval) { - printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, + printk("%s: unable to get IRQ %d (irqval=%d).\n", DRV_NAME, dev->irq, retval); goto err_out; } diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c --- a/drivers/net/starfire.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/starfire.c 2004-06-26 17:09:21 -07:00 @@ -880,7 +880,7 @@ irq = pdev->irq; - if (pci_request_regions (pdev, dev->name)) { + if (pci_request_regions (pdev, DRV_NAME)) { printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx); goto err_out_free_netdev; } diff -Nru a/drivers/net/stnic.c b/drivers/net/stnic.c --- a/drivers/net/stnic.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/stnic.c 2004-06-26 17:09:19 -07:00 @@ -28,6 +28,8 @@ #include "8390.h" +#define DRV_NAME "stnic" + #define byte unsigned char #define half unsigned short #define word unsigned int @@ -130,7 +132,7 @@ /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ - err = request_irq (dev->irq, ei_interrupt, 0, dev->name, dev); + err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev); if (err) { printk (KERN_EMERG " unable to get IRQ %d.\n", dev->irq); free_netdev(dev); diff -Nru a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c --- a/drivers/net/sun3_82586.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/sun3_82586.c 2004-06-26 17:09:18 -07:00 @@ -53,6 +53,8 @@ #include "sun3_82586.h" +#define DRV_NAME "sun3_82586" + #define DEBUG /* debug on */ #define SYSBUSVAL 0 /* 16 Bit */ #define SUN3_82586_TOTAL_SIZE PAGE_SIZE @@ -336,7 +338,7 @@ { int i, size, retval; - if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name)) + if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, DRV_NAME)) return -EBUSY; /* copy in the ethernet address from the prom */ diff -Nru a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c --- a/drivers/net/sun3lance.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/sun3lance.c 2004-06-26 17:09:20 -07:00 @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c --- a/drivers/net/sungem.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/sungem.c 2004-06-26 17:09:20 -07:00 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -742,7 +743,7 @@ PCI_DMA_FROMDEVICE); gp->rx_skbs[entry] = new_skb; new_skb->dev = gp->dev; - skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET)); + skb_put(new_skb, (gp->rx_buf_sz + RX_OFFSET)); rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev, virt_to_page(new_skb->data), offset_in_page(new_skb->data), @@ -1482,6 +1483,9 @@ gem_clean_rings(gp); + gp->rx_buf_sz = max(dev->mtu + ETH_HLEN + VLAN_HLEN, + (unsigned)VLAN_ETH_FRAME_LEN); + for (i = 0; i < RX_RING_SIZE; i++) { struct sk_buff *skb; struct gem_rxd *rxd = &gb->rxd[i]; @@ -1495,7 +1499,7 @@ gp->rx_skbs[i] = skb; skb->dev = dev; - skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET)); + skb_put(skb, (gp->rx_buf_sz + RX_OFFSET)); dma_addr = pci_map_page(gp->pdev, virt_to_page(skb->data), offset_in_page(skb->data), @@ -1750,7 +1754,7 @@ writel(0x40, gp->regs + MAC_MINFSZ); /* Ethernet payload + header + FCS + optional VLAN tag. */ - writel(0x20000000 | (gp->dev->mtu + ETH_HLEN + 4 + 4), gp->regs + MAC_MAXFSZ); + writel(0x20000000 | (gp->rx_buf_sz + 4), gp->regs + MAC_MAXFSZ); writel(0x07, gp->regs + MAC_PASIZE); writel(0x04, gp->regs + MAC_JAMSIZE); @@ -1827,7 +1831,7 @@ if (gp->rx_fifo_sz <= (2 * 1024)) { gp->rx_pause_off = gp->rx_pause_on = gp->rx_fifo_sz; } else { - int max_frame = (gp->dev->mtu + ETH_HLEN + 4 + 4 + 64) & ~63; + int max_frame = (gp->rx_buf_sz + 4 + 64) & ~63; int off = (gp->rx_fifo_sz - (max_frame * 2)); int on = off - max_frame; @@ -2717,7 +2721,7 @@ gp = dev->priv; - err = pci_request_regions(pdev, dev->name); + err = pci_request_regions(pdev, DRV_NAME); if (err) { printk(KERN_ERR PFX "Cannot obtain PCI resources, " "aborting.\n"); diff -Nru a/drivers/net/sungem.h b/drivers/net/sungem.h --- a/drivers/net/sungem.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/sungem.h 2004-06-26 17:09:18 -07:00 @@ -911,7 +911,7 @@ (GP)->tx_old - (GP)->tx_new - 1) #define RX_OFFSET 2 -#define RX_BUF_ALLOC_SIZE(gp) ((gp)->dev->mtu + 46 + RX_OFFSET + 64) +#define RX_BUF_ALLOC_SIZE(gp) ((gp)->rx_buf_sz + 28 + RX_OFFSET + 64) #define RX_COPY_THRESHOLD 256 @@ -979,6 +979,7 @@ int rx_fifo_sz; int rx_pause_off; int rx_pause_on; + int rx_buf_sz; int mii_phy_addr; u32 mac_rx_cfg; diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c --- a/drivers/net/sunhme.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/sunhme.c 2004-06-26 17:09:17 -07:00 @@ -68,6 +68,8 @@ #include "sunhme.h" +#define DRV_NAME "sunhme" + static int macaddr[6]; /* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */ @@ -526,8 +528,10 @@ ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value)); /* Welcome to Sun Microsystems, can I take your order please? */ - if (!(hp->happy_flags & HFLAG_FENABLE)) - return happy_meal_bb_write(hp, tregs, reg, value); + if (!(hp->happy_flags & HFLAG_FENABLE)) { + happy_meal_bb_write(hp, tregs, reg, value); + return; + } /* Would you like fries with that? */ hme_write32(hp, tregs + TCVR_FRAME, @@ -2920,7 +2924,8 @@ struct list_head *tmp; int n_hmes; - if (busdev->vendor != PCI_VENDOR_ID_DEC || + if (busdev == NULL || + busdev->vendor != PCI_VENDOR_ID_DEC || busdev->device != PCI_DEVICE_ID_DEC_21153) return 0; @@ -3085,7 +3090,7 @@ printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n"); goto err_out_clear_quattro; } - if (pci_request_regions(pdev, dev->name)) { + if (pci_request_regions(pdev, DRV_NAME)) { printk(KERN_ERR "happymeal(PCI): Cannot obtain PCI resources, " "aborting.\n"); goto err_out_clear_quattro; diff -Nru a/drivers/net/tc35815.c b/drivers/net/tc35815.c --- a/drivers/net/tc35815.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/tc35815.c 2004-06-26 17:09:15 -07:00 @@ -1717,7 +1717,7 @@ } static struct pci_driver tc35815_driver = { - .name =TC35815_MODULE_NAME, + .name = TC35815_MODULE_NAME, .probe = tc35815_probe, .remove = NULL, .id_table = tc35815_pci_tbl, diff -Nru a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c --- a/drivers/net/tokenring/ibmtr.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/tokenring/ibmtr.c 2004-06-26 17:09:19 -07:00 @@ -127,6 +127,7 @@ #include #include +#include #include #include diff -Nru a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig --- a/drivers/net/tulip/Kconfig 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/tulip/Kconfig 2004-06-26 17:09:19 -07:00 @@ -71,10 +71,17 @@ config TULIP_NAPI bool "Use NAPI RX polling " depends on TULIP - ---help--- - This is of useful for servers and routers dealing with high network loads. - - See . + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + + See for more + information. If in doubt, say N. diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c --- a/drivers/net/tulip/winbond-840.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/tulip/winbond-840.c 2004-06-26 17:09:16 -07:00 @@ -1292,14 +1292,8 @@ pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, PCI_DMA_FROMDEVICE); - /* Call copy + cksum if available. */ -#if HAS_IP_COPYSUM eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail, - pkt_len); -#endif pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, PCI_DMA_FROMDEVICE); diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c --- a/drivers/net/via-rhine.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/via-rhine.c 2004-06-26 17:09:21 -07:00 @@ -354,59 +354,46 @@ second only the 1234 card. */ -enum pci_flags_bit { - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, +enum rhine_revs { + VT86C100A = 0x00, + VT6102 = 0x40, + VT8231 = 0x50, /* Integrated MAC */ + VT8233 = 0x60, /* Integrated MAC */ + VT8235 = 0x74, /* Integrated MAC */ + VT8237 = 0x78, /* Integrated MAC */ + VTunknown0 = 0x7C, + VT6105 = 0x80, + VT6105_B0 = 0x83, + VT6105L = 0x8A, + VT6107 = 0x8C, + VTunknown1 = 0x8E, + VT6105M = 0x90, }; -enum rhine_chips { - VT86C100A = 0, - VT6102, - VT6105, - VT6105M -}; - -struct rhine_chip_info { - const char *name; - u16 pci_flags; - int io_size; - int drv_flags; -}; - - -enum chip_capability_flags { - CanHaveMII=1, HasESIPhy=2, HasDavicomPhy=4, - ReqTxAlign=0x10, HasWOL=0x20, +enum rhine_quirks { + rqWOL = 0x0001, /* Wake-On-LAN support */ + rqForceReset = 0x0002, + rqDavicomPhy = 0x0020, + rq6patterns = 0x0040, /* 6 instead of 4 patterns for WOL */ + rqStatusWBRace = 0x0080, /* Tx Status Writeback Error possible */ + rqRhineI = 0x0100, /* See comment below */ }; +/* + * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable + * MMIO as well as for the collision counter and the Tx FIFO underflow + * indicator. In addition, Tx and Rx buffers need to 4 byte aligned. + */ -#ifdef USE_MMIO -#define RHINE_IOTYPE (PCI_USES_MEM | PCI_USES_MASTER | PCI_ADDR1) -#else -#define RHINE_IOTYPE (PCI_USES_IO | PCI_USES_MASTER | PCI_ADDR0) -#endif /* Beware of PCI posted writes */ #define IOSYNC do { readb(dev->base_addr + StationAddr); } while (0) -/* directly indexed by enum rhine_chips, above */ -static struct rhine_chip_info rhine_chip_info[] __devinitdata = -{ - { "VIA VT86C100A Rhine", RHINE_IOTYPE, 128, - CanHaveMII | ReqTxAlign | HasDavicomPhy }, - { "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256, - CanHaveMII | HasWOL }, - { "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256, - CanHaveMII | HasWOL }, - { "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256, - CanHaveMII | HasWOL }, -}; - static struct pci_device_id rhine_pci_tbl[] = { - {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A}, - {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102}, - {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, /* 6105{,L,LOM} */ - {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M}, - {0,} /* terminate list */ + {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT86C100A */ + {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6102 */ + {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* 6105{,L,LOM} */ + {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6105M */ + { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, rhine_pci_tbl); @@ -421,8 +408,10 @@ MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74, ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B, RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81, - StickyHW=0x83, IntrStatus2=0x84, WOLcrClr=0xA4, WOLcgClr=0xA7, - PwrcsrClr=0xAC, + StickyHW=0x83, IntrStatus2=0x84, + WOLcrSet=0xA0, WOLcrClr=0xA4, WOLcrClr1=0xA6, + WOLcgClr=0xA7, + PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD, }; /* Bits in ConfigD */ @@ -514,7 +503,7 @@ spinlock_t lock; /* Frequently used values: keep some adjacent for cache effect. */ - int chip_id, drv_flags; + u32 quirks; struct rx_desc *rx_head_desc; unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ unsigned int cur_tx, dirty_tx; @@ -522,7 +511,6 @@ u16 chip_cmd; /* Current setting for ChipCmd */ /* These values are keep track of the transceiver/media in use. */ - unsigned int default_port:4; /* Last dev->if_port value. */ u8 tx_thresh, rx_thresh; /* MII transceiver section. */ @@ -557,12 +545,41 @@ intr_status = readw(ioaddr + IntrStatus); /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */ - if (rp->chip_id == VT6102) + if (rp->quirks & rqStatusWBRace) intr_status |= readb(ioaddr + IntrStatus2) << 16; return intr_status; } -static void wait_for_reset(struct net_device *dev, int chip_id, char *name) +/* + * Get power related registers into sane state. + * Returns content of power-event (WOL) registers. + */ +static void rhine_power_init(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct rhine_private *rp = netdev_priv(dev); + + if (rp->quirks & rqWOL) { + /* Make sure chip is in power state D0 */ + writeb(readb(ioaddr + StickyHW) & 0xFC, ioaddr + StickyHW); + + /* Disable "force PME-enable" */ + writeb(0x80, ioaddr + WOLcgClr); + + /* Clear power-event config bits (WOL) */ + writeb(0xFF, ioaddr + WOLcrClr); + /* More recent cards can manage two additional patterns */ + if (rp->quirks & rq6patterns) + writeb(0x03, ioaddr + WOLcrClr1); + + /* Clear power-event status bits */ + writeb(0xFF, ioaddr + PwrcsrClr); + if (rp->quirks & rq6patterns) + writeb(0x03, ioaddr + PwrcsrClr1); + } +} + +static void wait_for_reset(struct net_device *dev, u32 quirks, char *name) { long ioaddr = dev->base_addr; int boguscnt = 20; @@ -574,7 +591,7 @@ "Trying harder.\n", name); /* Rhine-II needs to be forced sometimes */ - if (chip_id == VT6102) + if (quirks & rqForceReset) writeb(0x40, ioaddr + MiscCmd); /* VT86C100A may need long delay after reset (dlink) */ @@ -590,10 +607,10 @@ } #ifdef USE_MMIO -static void __devinit enable_mmio(long ioaddr, int chip_id) +static void __devinit enable_mmio(long ioaddr, u32 quirks) { int n; - if (chip_id == VT86C100A) { + if (quirks & rqRhineI) { /* More recent docs say that this bit is reserved ... */ n = inb(ioaddr + ConfigA) | 0x20; outb(n, ioaddr + ConfigA); @@ -628,16 +645,18 @@ { struct net_device *dev; struct rhine_private *rp; - int i, option; - int chip_id = (int) ent->driver_data; + int i, option, rc; + u8 pci_rev; + u32 quirks; static int card_idx = -1; long ioaddr; long memaddr; int io_size; - int pci_flags; + int phy, phy_idx = 0; #ifdef USE_MMIO long ioaddr0; #endif + const char *name; /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -648,14 +667,34 @@ card_idx++; option = card_idx < MAX_UNITS ? options[card_idx] : 0; - io_size = rhine_chip_info[chip_id].io_size; - pci_flags = rhine_chip_info[chip_id].pci_flags; + pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); + + io_size = 256; + if (pci_rev < VT6102) { + quirks = rqRhineI | rqDavicomPhy; + io_size = 128; + name = "VT86C100A Rhine"; + } + else { + quirks = rqWOL | rqForceReset; + if (pci_rev < VT6105) { + name = "Rhine II"; + quirks |= rqStatusWBRace; /* Rhine-II exclusive */ + } + else { + name = "Rhine III"; + if (pci_rev >= VT6105_B0) + quirks |= rq6patterns; + } + } - if (pci_enable_device(pdev)) + rc = pci_enable_device(pdev); + if (rc) goto err_out; /* this should always be supported */ - if (pci_set_dma_mask(pdev, 0xffffffff)) { + rc = pci_set_dma_mask(pdev, 0xffffffff); + if (rc) { printk(KERN_ERR "32-bit PCI DMA addresses not supported by " "the card!?\n"); goto err_out; @@ -664,6 +703,7 @@ /* sanity check */ if ((pci_resource_len(pdev, 0) < io_size) || (pci_resource_len(pdev, 1) < io_size)) { + rc = -EIO; printk(KERN_ERR "Insufficient PCI resources, aborting\n"); goto err_out; } @@ -671,11 +711,11 @@ ioaddr = pci_resource_start(pdev, 0); memaddr = pci_resource_start(pdev, 1); - if (pci_flags & PCI_USES_MASTER) - pci_set_master(pdev); + pci_set_master(pdev); dev = alloc_etherdev(sizeof(*rp)); if (dev == NULL) { + rc = -ENOMEM; printk(KERN_ERR "init_ethernet failed for card #%d\n", card_idx); goto err_out; @@ -683,15 +723,17 @@ SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - if (pci_request_regions(pdev, shortname)) + rc = pci_request_regions(pdev, shortname); + if (rc) goto err_out_free_netdev; #ifdef USE_MMIO ioaddr0 = ioaddr; - enable_mmio(ioaddr0, chip_id); + enable_mmio(ioaddr0, quirks); ioaddr = (long) ioremap(memaddr, io_size); if (!ioaddr) { + rc = -EIO; printk(KERN_ERR "ioremap failed for device %s, region 0x%X " "@ 0x%lX\n", pci_name(pdev), io_size, memaddr); goto err_out_free_res; @@ -704,36 +746,21 @@ unsigned char a = inb(ioaddr0+reg); unsigned char b = readb(ioaddr+reg); if (a != b) { + rc = -EIO; printk(KERN_ERR "MMIO do not match PIO [%02x] " "(%02x != %02x)\n", reg, a, b); goto err_out_unmap; } } #endif /* USE_MMIO */ + dev->base_addr = ioaddr; - /* D-Link provided reset code (with comment additions) */ - if (rhine_chip_info[chip_id].drv_flags & HasWOL) { - unsigned char byOrgValue; - - /* clear sticky bit before reset & read ethernet address */ - byOrgValue = readb(ioaddr + StickyHW); - byOrgValue = byOrgValue & 0xFC; - writeb(byOrgValue, ioaddr + StickyHW); - - /* (bits written are cleared?) */ - /* disable force PME-enable */ - writeb(0x80, ioaddr + WOLcgClr); - /* disable power-event config bit */ - writeb(0xFF, ioaddr + WOLcrClr); - /* clear power status (undocumented in vt6102 docs?) */ - writeb(0xFF, ioaddr + PwrcsrClr); - } + rhine_power_init(dev); /* Reset the chip to erase previous misconfiguration. */ writew(CmdReset, ioaddr + ChipCmd); - dev->base_addr = ioaddr; - wait_for_reset(dev, chip_id, shortname); + wait_for_reset(dev, quirks, shortname); /* Reload the station address from the EEPROM. */ #ifdef USE_MMIO @@ -741,7 +768,7 @@ /* Reloading from eeprom overwrites cfgA-D, so we must re-enable MMIO. If reload_eeprom() was done first this could be avoided, but it is not known if that still works with the "win98-reboot" problem. */ - enable_mmio(ioaddr0, chip_id); + enable_mmio(ioaddr0, quirks); #else reload_eeprom(ioaddr); #endif @@ -750,11 +777,12 @@ dev->dev_addr[i] = readb(ioaddr + StationAddr + i); if (!is_valid_ether_addr(dev->dev_addr)) { + rc = -EIO; printk(KERN_ERR "Invalid MAC address for card #%d\n", card_idx); goto err_out_unmap; } - if (chip_id == VT6102) { + if (quirks & rqWOL) { /* * for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA * turned on. it makes MAC receive magic packet @@ -772,9 +800,8 @@ rp = netdev_priv(dev); spin_lock_init(&rp->lock); - rp->chip_id = chip_id; - rp->drv_flags = rhine_chip_info[chip_id].drv_flags; rp->pdev = pdev; + rp->quirks = quirks; rp->mii_if.dev = dev; rp->mii_if.mdio_read = mdio_read; rp->mii_if.mdio_write = mdio_write; @@ -797,19 +824,18 @@ #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = rhine_poll; #endif - if (rp->drv_flags & ReqTxAlign) + if (rp->quirks & rqRhineI) dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; /* dev->name not defined before register_netdev()! */ - i = register_netdev(dev); - if (i) + rc = register_netdev(dev); + if (rc) goto err_out_unmap; /* The lower four bits are the media type. */ if (option > 0) { if (option & 0x220) rp->mii_if.full_duplex = 1; - rp->default_port = option & 15; } if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) rp->mii_if.full_duplex = 1; @@ -820,9 +846,14 @@ rp->mii_if.force_media = 1; } - printk(KERN_INFO "%s: %s at 0x%lx, ", - dev->name, rhine_chip_info[chip_id].name, - (pci_flags & PCI_USES_IO) ? ioaddr : memaddr); + printk(KERN_INFO "%s: VIA %s at 0x%lx, ", + dev->name, name, +#ifdef USE_MMIO + memaddr +#else + ioaddr +#endif + ); for (i = 0; i < 5; i++) printk("%2.2x:", dev->dev_addr[i]); @@ -830,41 +861,35 @@ pci_set_drvdata(pdev, dev); - if (rp->drv_flags & CanHaveMII) { - int phy, phy_idx = 0; - rp->phys[0] = 1; /* Standard for this chip. */ - for (phy = 1; phy < 32 && phy_idx < MAX_MII_CNT; phy++) { - int mii_status = mdio_read(dev, phy, 1); - if (mii_status != 0xffff && mii_status != 0x0000) { - rp->phys[phy_idx++] = phy; - rp->mii_if.advertising = mdio_read(dev, phy, 4); - printk(KERN_INFO "%s: MII PHY found at address " - "%d, status 0x%4.4x advertising %4.4x " - "Link %4.4x.\n", dev->name, phy, - mii_status, rp->mii_if.advertising, - mdio_read(dev, phy, 5)); - - /* set IFF_RUNNING */ - if (mii_status & BMSR_LSTATUS) - netif_carrier_on(dev); - else - netif_carrier_off(dev); + rp->phys[0] = 1; /* Standard for this chip. */ + for (phy = 1; phy < 32 && phy_idx < MAX_MII_CNT; phy++) { + int mii_status = mdio_read(dev, phy, 1); + if (mii_status != 0xffff && mii_status != 0x0000) { + rp->phys[phy_idx++] = phy; + rp->mii_if.advertising = mdio_read(dev, phy, 4); + printk(KERN_INFO "%s: MII PHY found at address " + "%d, status 0x%4.4x advertising %4.4x " + "Link %4.4x.\n", dev->name, phy, + mii_status, rp->mii_if.advertising, + mdio_read(dev, phy, 5)); + + /* set IFF_RUNNING */ + if (mii_status & BMSR_LSTATUS) + netif_carrier_on(dev); + else + netif_carrier_off(dev); - break; - } + break; } - rp->mii_cnt = phy_idx; - rp->mii_if.phy_id = rp->phys[0]; } + rp->mii_cnt = phy_idx; + rp->mii_if.phy_id = rp->phys[0]; /* Allow forcing the media type. */ if (option > 0) { if (option & 0x220) rp->mii_if.full_duplex = 1; - rp->default_port = option & 0x3ff; if (option & 0x330) { - /* FIXME: shouldn't someone check this variable? */ - /* rp->medialock = 1; */ printk(KERN_INFO " Forcing %dMbs %s-duplex " "operation.\n", (option & 0x300 ? 100 : 10), @@ -887,7 +912,7 @@ err_out_free_netdev: free_netdev(dev); err_out: - return -ENODEV; + return rc; } static int alloc_ring(struct net_device* dev) @@ -904,7 +929,7 @@ printk(KERN_ERR "Could not allocate DMA memory.\n"); return -ENOMEM; } - if (rp->drv_flags & ReqTxAlign) { + if (rp->quirks & rqRhineI) { rp->tx_bufs = pci_alloc_consistent(rp->pdev, PKT_BUF_SZ * TX_RING_SIZE, &rp->tx_bufs_dma); @@ -1063,9 +1088,6 @@ rp->rx_thresh = 0x60; /* Written in rhine_set_rx_mode(). */ rp->mii_if.full_duplex = 0; - if (dev->if_port == 0) - dev->if_port = rp->default_port; - writel(rp->rx_ring_dma, ioaddr + RxRingPtr); writel(rp->tx_ring_dma, ioaddr + TxRingPtr); @@ -1087,9 +1109,8 @@ /* The LED outputs of various MII xcvrs should be configured. */ /* For NS or Mison phys, turn on bit 1 in register 0x17 */ - /* For ESI phys, turn on bit 7 in register 0x17. */ mdio_write(dev, rp->phys[0], 0x17, mdio_read(dev, rp->phys[0], 0x17) | - (rp->drv_flags & HasESIPhy) ? 0x0080 : 0x0001); + 0x0001); } /* Read and write over the MII Management Data I/O (MDIO) interface. */ @@ -1166,7 +1187,7 @@ return i; alloc_rbufs(dev); alloc_tbufs(dev); - wait_for_reset(dev, rp->chip_id, dev->name); + wait_for_reset(dev, rp->quirks, dev->name); init_registers(dev); if (debug > 2) printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x " @@ -1257,8 +1278,6 @@ dev->name, readw(ioaddr + IntrStatus), mdio_read(dev, rp->phys[0], MII_BMSR)); - dev->if_port = 0; - /* protect against concurrent rx interrupts */ disable_irq(rp->pdev->irq); @@ -1274,7 +1293,7 @@ alloc_rbufs(dev); /* Reinitialize the hardware. */ - wait_for_reset(dev, rp->chip_id, dev->name); + wait_for_reset(dev, rp->quirks, dev->name); init_registers(dev); spin_unlock(&rp->lock); @@ -1305,7 +1324,7 @@ rp->tx_skbuff[entry] = skb; - if ((rp->drv_flags & ReqTxAlign) && + if ((rp->quirks & rqRhineI) && (((long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)) { /* Must use alignment buffer. */ if (skb->len > PKT_BUF_SZ) { @@ -1454,7 +1473,7 @@ if (txstatus & 0x0200) rp->stats.tx_window_errors++; if (txstatus & 0x0100) rp->stats.tx_aborted_errors++; if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++; - if (((rp->chip_id == VT86C100A) && txstatus & 0x0002) || + if (((rp->quirks & rqRhineI) && txstatus & 0x0002) || (txstatus & 0x0800) || (txstatus & 0x1000)) { rp->stats.tx_fifo_errors++; rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn); @@ -1462,7 +1481,7 @@ } /* Transmitter restarted in 'abnormal' handler. */ } else { - if (rp->chip_id == VT86C100A) + if (rp->quirks & rqRhineI) rp->stats.collisions += (txstatus >> 3) & 0x0F; else rp->stats.collisions += txstatus & 0x0F; @@ -1563,15 +1582,10 @@ eth_copy_and_sum is memcpy for all archs so this is kind of pointless right now ... or? */ -#if HAS_IP_COPYSUM /* Call copy + cksum if available. */ eth_copy_and_sum(skb, rp->rx_skbuff[entry]->tail, pkt_len, 0); skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), - rp->rx_skbuff[entry]->tail, pkt_len); -#endif pci_dma_sync_single_for_device(rp->pdev, rp->rx_skbuff_dma[entry], rp->rx_buf_sz, @@ -1679,7 +1693,7 @@ if (intr_status & (IntrLinkChange)) { if (readb(ioaddr + MIIStatus) & 0x02) { /* Link failed, restart autonegotiation. */ - if (rp->drv_flags & HasDavicomPhy) + if (rp->quirks & rqRhineI) mdio_write(dev, rp->phys[0], MII_BMCR, 0x3300); } else rhine_check_duplex(dev); @@ -1805,9 +1819,6 @@ struct rhine_private *rp = netdev_priv(dev); int rc; - if (!(rp->drv_flags & CanHaveMII)) - return -EINVAL; - spin_lock_irq(&rp->lock); rc = mii_ethtool_gset(&rp->mii_if, cmd); spin_unlock_irq(&rp->lock); @@ -1820,9 +1831,6 @@ struct rhine_private *rp = netdev_priv(dev); int rc; - if (!(rp->drv_flags & CanHaveMII)) - return -EINVAL; - spin_lock_irq(&rp->lock); rc = mii_ethtool_sset(&rp->mii_if, cmd); spin_unlock_irq(&rp->lock); @@ -1834,18 +1842,12 @@ { struct rhine_private *rp = netdev_priv(dev); - if (!(rp->drv_flags & CanHaveMII)) - return -EINVAL; - return mii_nway_restart(&rp->mii_if); } static u32 netdev_get_link(struct net_device *dev) { struct rhine_private *rp = netdev_priv(dev); - - if (!(rp->drv_flags & CanHaveMII)) - return 0; /* -EINVAL */ return mii_link_ok(&rp->mii_if); } diff -Nru a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/net/via-velocity.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,3277 @@ +/* + * This code is derived from the VIA reference driver (copyright message + * below) provided to Red Hat by VIA Networking Technologies, Inc. for + * addition to the Linux kernel. + * + * The code has been merged into one source file, cleaned up to follow + * Linux coding style, ported to the Linux 2.6 kernel tree and cleaned + * for 64bit hardware platforms. + * + * TODO + * Big-endian support + * rx_copybreak/alignment + * Scatter gather + * More testing + * + * The changes are (c) Copyright 2004, Red Hat Inc. + * Additional fixes and clean up: Francois Romieu + * + * This source has not been verified for use in safety critical systems. + * + * Please direct queries about the revamped driver to the linux-kernel + * list not VIA. + * + * Original code: + * + * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. + * All rights reserved. + * + * This software may be redistributed and/or modified under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * Author: Chuang Liang-Shing, AJ Jiang + * + * Date: Jan 24, 2003 + * + * MODULE_LICENSE("GPL"); + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "via-velocity.h" + + +static int velocity_nics = 0; +static int msglevel = MSG_LEVEL_INFO; + + +static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static struct ethtool_ops velocity_ethtool_ops; + +/* + Define module options +*/ + +MODULE_AUTHOR("VIA Networking Technologies, Inc."); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver"); + +#define VELOCITY_PARAM(N,D) \ + static const int N[MAX_UNITS]=OPTION_DEFAULT;\ + MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UNITS) "i");\ + MODULE_PARM_DESC(N, D); + +#define RX_DESC_MIN 64 +#define RX_DESC_MAX 255 +#define RX_DESC_DEF 64 +VELOCITY_PARAM(RxDescriptors, "Number of receive descriptors"); + +#define TX_DESC_MIN 16 +#define TX_DESC_MAX 256 +#define TX_DESC_DEF 64 +VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors"); + +#define VLAN_ID_MIN 0 +#define VLAN_ID_MAX 4095 +#define VLAN_ID_DEF 0 +/* VID_setting[] is used for setting the VID of NIC. + 0: default VID. + 1-4094: other VIDs. +*/ +VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID"); + +#define RX_THRESH_MIN 0 +#define RX_THRESH_MAX 3 +#define RX_THRESH_DEF 0 +/* rx_thresh[] is used for controlling the receive fifo threshold. + 0: indicate the rxfifo threshold is 128 bytes. + 1: indicate the rxfifo threshold is 512 bytes. + 2: indicate the rxfifo threshold is 1024 bytes. + 3: indicate the rxfifo threshold is store & forward. +*/ +VELOCITY_PARAM(rx_thresh, "Receive fifo threshold"); + +#define DMA_LENGTH_MIN 0 +#define DMA_LENGTH_MAX 7 +#define DMA_LENGTH_DEF 0 + +/* DMA_length[] is used for controlling the DMA length + 0: 8 DWORDs + 1: 16 DWORDs + 2: 32 DWORDs + 3: 64 DWORDs + 4: 128 DWORDs + 5: 256 DWORDs + 6: SF(flush till emply) + 7: SF(flush till emply) +*/ +VELOCITY_PARAM(DMA_length, "DMA length"); + +#define TAGGING_DEF 0 +/* enable_tagging[] is used for enabling 802.1Q VID tagging. + 0: disable VID seeting(default). + 1: enable VID setting. +*/ +VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging"); + +#define IP_ALIG_DEF 0 +/* IP_byte_align[] is used for IP header DWORD byte aligned + 0: indicate the IP header won't be DWORD byte aligned.(Default) . + 1: indicate the IP header will be DWORD byte aligned. + In some enviroment, the IP header should be DWORD byte aligned, + or the packet will be droped when we receive it. (eg: IPVS) +*/ +VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned"); + +#define TX_CSUM_DEF 1 +/* txcsum_offload[] is used for setting the checksum offload ability of NIC. + (We only support RX checksum offload now) + 0: disable csum_offload[checksum offload + 1: enable checksum offload. (Default) +*/ +VELOCITY_PARAM(txcsum_offload, "Enable transmit packet checksum offload"); + +#define FLOW_CNTL_DEF 1 +#define FLOW_CNTL_MIN 1 +#define FLOW_CNTL_MAX 5 + +/* flow_control[] is used for setting the flow control ability of NIC. + 1: hardware deafult - AUTO (default). Use Hardware default value in ANAR. + 2: enable TX flow control. + 3: enable RX flow control. + 4: enable RX/TX flow control. + 5: disable +*/ +VELOCITY_PARAM(flow_control, "Enable flow control ability"); + +#define MED_LNK_DEF 0 +#define MED_LNK_MIN 0 +#define MED_LNK_MAX 4 +/* speed_duplex[] is used for setting the speed and duplex mode of NIC. + 0: indicate autonegotiation for both speed and duplex mode + 1: indicate 100Mbps half duplex mode + 2: indicate 100Mbps full duplex mode + 3: indicate 10Mbps half duplex mode + 4: indicate 10Mbps full duplex mode + + Note: + if EEPROM have been set to the force mode, this option is ignored + by driver. +*/ +VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode"); + +#define VAL_PKT_LEN_DEF 0 +/* ValPktLen[] is used for setting the checksum offload ability of NIC. + 0: Receive frame with invalid layer 2 length (Default) + 1: Drop frame with invalid layer 2 length +*/ +VELOCITY_PARAM(ValPktLen, "Receiving or Drop invalid 802.3 frame"); + +#define WOL_OPT_DEF 0 +#define WOL_OPT_MIN 0 +#define WOL_OPT_MAX 7 +/* wol_opts[] is used for controlling wake on lan behavior. + 0: Wake up if recevied a magic packet. (Default) + 1: Wake up if link status is on/off. + 2: Wake up if recevied an arp packet. + 4: Wake up if recevied any unicast packet. + Those value can be sumed up to support more than one option. +*/ +VELOCITY_PARAM(wol_opts, "Wake On Lan options"); + +#define INT_WORKS_DEF 20 +#define INT_WORKS_MIN 10 +#define INT_WORKS_MAX 64 + +VELOCITY_PARAM(int_works, "Number of packets per interrupt services"); + +static int velocity_found1(struct pci_dev *pdev, const struct pci_device_id *ent); +static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info); +static int velocity_get_pci_info(struct velocity_info *, struct pci_dev *pdev); +static void velocity_print_info(struct velocity_info *vptr); +static int velocity_open(struct net_device *dev); +static int velocity_change_mtu(struct net_device *dev, int mtu); +static int velocity_xmit(struct sk_buff *skb, struct net_device *dev); +static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs); +static void velocity_set_multi(struct net_device *dev); +static struct net_device_stats *velocity_get_stats(struct net_device *dev); +static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int velocity_close(struct net_device *dev); +static int velocity_rx_srv(struct velocity_info *vptr, int status); +static int velocity_receive_frame(struct velocity_info *, int idx); +static int velocity_alloc_rx_buf(struct velocity_info *, int idx); +static void velocity_init_registers(struct velocity_info *vptr, enum velocity_init_type type); +static void velocity_free_rd_ring(struct velocity_info *vptr); +static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *); +static int velocity_soft_reset(struct velocity_info *vptr); +static void mii_init(struct velocity_info *vptr, u32 mii_status); +static u32 velocity_get_opt_media_mode(struct velocity_info *vptr); +static void velocity_print_link_status(struct velocity_info *vptr); +static void safe_disable_mii_autopoll(struct mac_regs * regs); +static void velocity_shutdown(struct velocity_info *vptr); +static void enable_flow_control_ability(struct velocity_info *vptr); +static void enable_mii_autopoll(struct mac_regs * regs); +static int velocity_mii_read(struct mac_regs *, u8 byIdx, u16 * pdata); +static int velocity_mii_write(struct mac_regs *, u8 byMiiAddr, u16 data); +static int velocity_set_wol(struct velocity_info *vptr); +static void velocity_save_context(struct velocity_info *vptr, struct velocity_context *context); +static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context); +static u32 mii_check_media_mode(struct mac_regs * regs); +static u32 check_connection_type(struct mac_regs * regs); +static void velocity_init_cam_filter(struct velocity_info *vptr); +static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status); + +#ifdef CONFIG_PM +static int velocity_suspend(struct pci_dev *pdev, u32 state); +static int velocity_resume(struct pci_dev *pdev); + +static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr); + +static struct notifier_block velocity_inetaddr_notifier = { + notifier_call:velocity_netdev_event, +}; + +#endif /* CONFIG_PM */ + +/* + * Internal board variants. At the moment we have only one + */ + +static struct velocity_info_tbl chip_info_table[] = { + {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 256, 1, 0x00FFFFFFUL}, + {0, NULL} +}; + +/* + * Describe the PCI device identifiers that we support in this + * device driver. Used for hotplug autoloading. + */ + +static struct pci_device_id velocity_id_table[] __devinitdata = { + {0x1106, 0x3119, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &chip_info_table[0]}, + {0,} +}; + +MODULE_DEVICE_TABLE(pci, velocity_id_table); + +/** + * get_chip_name - identifier to name + * @id: chip identifier + * + * Given a chip identifier return a suitable description. Returns + * a pointer a static string valid while the driver is loaded. + */ + +static char __devinit *get_chip_name(enum chip_type chip_id) +{ + int i; + for (i = 0; chip_info_table[i].name != NULL; i++) + if (chip_info_table[i].chip_id == chip_id) + break; + return chip_info_table[i].name; +} + +/** + * velocity_remove1 - device unplug + * @pdev: PCI device being removed + * + * Device unload callback. Called on an unplug or on module + * unload for each active device that is present. Disconnects + * the device from the network layer and frees all the resources + */ + +static void __devexit velocity_remove1(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct velocity_info *vptr = dev->priv; + + unregister_netdev(dev); + iounmap(vptr->mac_regs); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + free_netdev(dev); +} + +/** + * velocity_set_int_opt - parser for integer options + * @opt: pointer to option value + * @val: value the user requested (or -1 for default) + * @min: lowest value allowed + * @max: highest value allowed + * @def: default value + * @name: property name + * @dev: device name + * + * Set an integer property in the module options. This function does + * all the verification and checking as well as reporting so that + * we don't duplicate code for each option. + */ + +static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, char *devname) +{ + if (val == -1) + *opt = def; + else if (val < min || val > max) { + VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n", + devname, name, min, max); + *opt = def; + } else { + VELOCITY_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n", + devname, name, val); + *opt = val; + } +} + +/** + * velocity_set_bool_opt - parser for boolean options + * @opt: pointer to option value + * @val: value the user requested (or -1 for default) + * @def: default value (yes/no) + * @flag: numeric value to set for true. + * @name: property name + * @dev: device name + * + * Set a boolean property in the module options. This function does + * all the verification and checking as well as reporting so that + * we don't duplicate code for each option. + */ + +static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag, char *name, char *devname) +{ + (*opt) &= (~flag); + if (val == -1) + *opt |= (def ? flag : 0); + else if (val < 0 || val > 1) { + printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n", + devname, name); + *opt |= (def ? flag : 0); + } else { + printk(KERN_INFO "%s: set parameter %s to %s\n", + devname, name, val ? "TRUE" : "FALSE"); + *opt |= (val ? flag : 0); + } +} + +/** + * velocity_get_options - set options on device + * @opts: option structure for the device + * @index: index of option to use in module options array + * @devname: device name + * + * Turn the module and command options into a single structure + * for the current device + */ + +static void __devinit velocity_get_options(struct velocity_opt *opts, int index, char *devname) +{ + + velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname); + velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname); + velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname); + velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname); + velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting", devname); + velocity_set_bool_opt(&opts->flags, enable_tagging[index], TAGGING_DEF, VELOCITY_FLAGS_TAGGING, "enable_tagging", devname); + velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname); + velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname); + velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname); + velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname); + velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname); + velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname); + velocity_set_int_opt((int *) &opts->int_works, int_works[index], INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF, "Interrupt service works", devname); + opts->numrx = (opts->numrx & ~3); +} + +/** + * velocity_init_cam_filter - initialise CAM + * @vptr: velocity to program + * + * Initialize the content addressable memory used for filters. Load + * appropriately according to the presence of VLAN + */ + +static void velocity_init_cam_filter(struct velocity_info *vptr) +{ + struct mac_regs * regs = vptr->mac_regs; + + /* T urn on MCFG_PQEN, turn off MCFG_RTGOPT */ + WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG); + WORD_REG_BITS_ON(MCFG_VIDFR, ®s->MCFG); + + /* Disable all CAMs */ + memset(vptr->vCAMmask, 0, sizeof(u8) * 8); + memset(vptr->mCAMmask, 0, sizeof(u8) * 8); + mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); + mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); + + /* Enable first VCAM */ + if (vptr->flags & VELOCITY_FLAGS_TAGGING) { + /* If Tagging option is enabled and VLAN ID is not zero, then + turn on MCFG_RTGOPT also */ + if (vptr->options.vid != 0) + WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); + + mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM); + vptr->vCAMmask[0] |= 1; + mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); + } else { + u16 temp = 0; + mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM); + temp = 1; + mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM); + } +} + +/** + * velocity_rx_reset - handle a receive reset + * @vptr: velocity we are resetting + * + * Reset the ownership and status for the receive ring side. + * Hand all the receive queue to the NIC. + */ + +static void velocity_rx_reset(struct velocity_info *vptr) +{ + + struct mac_regs * regs = vptr->mac_regs; + int i; + + vptr->rd_used = vptr->rd_curr = 0; + + /* + * Init state, all RD entries belong to the NIC + */ + for (i = 0; i < vptr->options.numrx; ++i) + vptr->rd_ring[i].rdesc0.owner = cpu_to_le32(OWNED_BY_NIC); + + writew(vptr->options.numrx, ®s->RBRDU); + writel(vptr->rd_pool_dma, ®s->RDBaseLo); + writew(0, ®s->RDIdx); + writew(vptr->options.numrx - 1, ®s->RDCSize); +} + +/** + * velocity_init_registers - initialise MAC registers + * @vptr: velocity to init + * @type: type of initialisation (hot or cold) + * + * Initialise the MAC on a reset or on first set up on the + * hardware. + */ + +static void velocity_init_registers(struct velocity_info *vptr, + enum velocity_init_type type) +{ + struct mac_regs * regs = vptr->mac_regs; + int i, mii_status; + + mac_wol_reset(regs); + + switch (type) { + case VELOCITY_INIT_RESET: + case VELOCITY_INIT_WOL: + + netif_stop_queue(vptr->dev); + + /* + * Reset RX to prevent RX pointer not on the 4X location + */ + velocity_rx_reset(vptr); + mac_rx_queue_run(regs); + mac_rx_queue_wake(regs); + + mii_status = velocity_get_opt_media_mode(vptr); + if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) { + velocity_print_link_status(vptr); + if (!(vptr->mii_status & VELOCITY_LINK_FAIL)) + netif_wake_queue(vptr->dev); + } + + enable_flow_control_ability(vptr); + + mac_clear_isr(regs); + writel(CR0_STOP, ®s->CR0Clr); + writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), + ®s->CR0Set); + + break; + + case VELOCITY_INIT_COLD: + default: + /* + * Do reset + */ + velocity_soft_reset(vptr); + mdelay(5); + + mac_eeprom_reload(regs); + for (i = 0; i < 6; i++) { + writeb(vptr->dev->dev_addr[i], &(regs->PAR[i])); + } + /* + * clear Pre_ACPI bit. + */ + BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA)); + mac_set_rx_thresh(regs, vptr->options.rx_thresh); + mac_set_dma_length(regs, vptr->options.DMA_length); + + writeb(WOLCFG_SAM | WOLCFG_SAB, ®s->WOLCFGSet); + /* + * Bback off algorithm use original IEEE standard + */ + BYTE_REG_BITS_SET(CFGB_OFSET, (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT), ®s->CFGB); + + /* + * Set packet filter: Receive directed and broadcast address + */ + velocity_set_multi(vptr->dev); + + /* + * Enable MII auto-polling + */ + enable_mii_autopoll(regs); + + vptr->int_mask = INT_MASK_DEF; + + writel(cpu_to_le32(vptr->rd_pool_dma), ®s->RDBaseLo); + writew(vptr->options.numrx - 1, ®s->RDCSize); + mac_rx_queue_run(regs); + mac_rx_queue_wake(regs); + + writew(vptr->options.numtx - 1, ®s->TDCSize); + + for (i = 0; i < vptr->num_txq; i++) { + writel(cpu_to_le32(vptr->td_pool_dma[i]), &(regs->TDBaseLo[i])); + mac_tx_queue_run(regs, i); + } + + velocity_init_cam_filter(vptr); + + init_flow_control_register(vptr); + + writel(CR0_STOP, ®s->CR0Clr); + writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), ®s->CR0Set); + + mii_status = velocity_get_opt_media_mode(vptr); + netif_stop_queue(vptr->dev); + mac_clear_isr(regs); + + mii_init(vptr, mii_status); + + if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) { + velocity_print_link_status(vptr); + if (!(vptr->mii_status & VELOCITY_LINK_FAIL)) + netif_wake_queue(vptr->dev); + } + + enable_flow_control_ability(vptr); + mac_hw_mibs_init(regs); + mac_write_int_mask(vptr->int_mask, regs); + mac_clear_isr(regs); + + } +} + +/** + * velocity_soft_reset - soft reset + * @vptr: velocity to reset + * + * Kick off a soft reset of the velocity adapter and then poll + * until the reset sequence has completed before returning. + */ + +static int velocity_soft_reset(struct velocity_info *vptr) +{ + struct mac_regs * regs = vptr->mac_regs; + int i = 0; + + writel(CR0_SFRST, ®s->CR0Set); + + for (i = 0; i < W_MAX_TIMEOUT; i++) { + udelay(5); + if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, ®s->CR0Set)) + break; + } + + if (i == W_MAX_TIMEOUT) { + writel(CR0_FORSRST, ®s->CR0Set); + /* FIXME: PCI POSTING */ + /* delay 2ms */ + mdelay(2); + } + return 0; +} + +/** + * velocity_found1 - set up discovered velocity card + * @pdev: PCI device + * @ent: PCI device table entry that matched + * + * Configure a discovered adapter from scratch. Return a negative + * errno error code on failure paths. + */ + +static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int first = 1; + struct net_device *dev; + int i; + struct velocity_info_tbl *info = (struct velocity_info_tbl *) ent->driver_data; + struct velocity_info *vptr; + struct mac_regs * regs; + int ret = -ENOMEM; + + if (velocity_nics++ >= MAX_UNITS) { + printk(KERN_NOTICE VELOCITY_NAME ": already found %d NICs.\n", + velocity_nics); + return -ENODEV; + } + + dev = alloc_etherdev(sizeof(struct velocity_info)); + + if (dev == NULL) { + printk(KERN_ERR VELOCITY_NAME ": allocate net device failed.\n"); + goto out; + } + + /* Chain it all together */ + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); + vptr = dev->priv; + + + if (first) { + printk(KERN_INFO "%s Ver. %s\n", + VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION); + printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n"); + printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n"); + first = 0; + } + + velocity_init_info(pdev, vptr, info); + + vptr->dev = dev; + + dev->priv = vptr; + dev->irq = pdev->irq; + + ret = pci_enable_device(pdev); + if (ret < 0) + goto err_free_dev; + + ret = velocity_get_pci_info(vptr, pdev); + if (ret < 0) { + printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device.\n"); + goto err_disable; + } + + ret = pci_request_regions(pdev, VELOCITY_NAME); + if (ret < 0) { + printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device.\n"); + goto err_disable; + } + + regs = ioremap(vptr->memaddr, vptr->io_size); + if (regs == NULL) { + ret = -EIO; + goto err_release_res; + } + + vptr->mac_regs = regs; + + mac_wol_reset(regs); + + dev->base_addr = vptr->ioaddr; + + for (i = 0; i < 6; i++) + dev->dev_addr[i] = readb(®s->PAR[i]); + + + velocity_get_options(&vptr->options, velocity_nics - 1, dev->name); + + /* + * Mask out the options cannot be set to the chip + */ + + vptr->options.flags &= info->flags; + + /* + * Enable the chip specified capbilities + */ + + vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL); + + vptr->wol_opts = vptr->options.wol_opts; + vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED; + + vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs); + + dev->irq = pdev->irq; + dev->open = velocity_open; + dev->hard_start_xmit = velocity_xmit; + dev->stop = velocity_close; + dev->get_stats = velocity_get_stats; + dev->set_multicast_list = velocity_set_multi; + dev->do_ioctl = velocity_ioctl; + dev->ethtool_ops = &velocity_ethtool_ops; + dev->change_mtu = velocity_change_mtu; +#ifdef VELOCITY_ZERO_COPY_SUPPORT + dev->features |= NETIF_F_SG; +#endif + + if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) { + dev->features |= NETIF_F_HW_CSUM; + } + + ret = register_netdev(dev); + if (ret < 0) + goto err_iounmap; + + velocity_print_info(vptr); + pci_set_drvdata(pdev, dev); + + /* and leave the chip powered down */ + + pci_set_power_state(pdev, 3); +out: + return ret; + +err_iounmap: + iounmap(regs); +err_release_res: + pci_release_regions(pdev); +err_disable: + pci_disable_device(pdev); +err_free_dev: + free_netdev(dev); + goto out; +} + +/** + * velocity_print_info - per driver data + * @vptr: velocity + * + * Print per driver data as the kernel driver finds Velocity + * hardware + */ + +static void __devinit velocity_print_info(struct velocity_info *vptr) +{ + struct net_device *dev = vptr->dev; + + printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id)); + printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", + dev->name, + dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); +} + +/** + * velocity_init_info - init private data + * @pdev: PCI device + * @vptr: Velocity info + * @info: Board type + * + * Set up the initial velocity_info struct for the device that has been + * discovered. + */ + +static void __devinit velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info) +{ + memset(vptr, 0, sizeof(struct velocity_info)); + + vptr->pdev = pdev; + vptr->chip_id = info->chip_id; + vptr->io_size = info->io_size; + vptr->num_txq = info->txqueue; + vptr->multicast_limit = MCAM_SIZE; + + spin_lock_init(&vptr->lock); + spin_lock_init(&vptr->xmit_lock); +} + +/** + * velocity_get_pci_info - retrieve PCI info for device + * @vptr: velocity device + * @pdev: PCI device it matches + * + * Retrieve the PCI configuration space data that interests us from + * the kernel PCI layer + */ + +static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev) +{ + + if(pci_read_config_byte(pdev, PCI_REVISION_ID, &vptr->rev_id) < 0) + return -EIO; + + pci_set_master(pdev); + + vptr->ioaddr = pci_resource_start(pdev, 0); + vptr->memaddr = pci_resource_start(pdev, 1); + + if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) + { + printk(KERN_ERR "%s: region #0 is not an I/O resource, aborting.\n", + pci_name(pdev)); + return -EINVAL; + } + + if((pci_resource_flags(pdev, 1) & IORESOURCE_IO)) + { + printk(KERN_ERR "%s: region #1 is an I/O resource, aborting.\n", + pci_name(pdev)); + return -EINVAL; + } + + if(pci_resource_len(pdev, 1) < 256) + { + printk(KERN_ERR "%s: region #1 is too small.\n", + pci_name(pdev)); + return -EINVAL; + } + vptr->pdev = pdev; + + return 0; +} + +/** + * velocity_init_rings - set up DMA rings + * @vptr: Velocity to set up + * + * Allocate PCI mapped DMA rings for the receive and transmit layer + * to use. + */ + +static int velocity_init_rings(struct velocity_info *vptr) +{ + int i; + unsigned int psize; + unsigned int tsize; + dma_addr_t pool_dma; + u8 *pool; + + /* + * Allocate all RD/TD rings a single pool + */ + + psize = vptr->options.numrx * sizeof(struct rx_desc) + + vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq; + + /* + * pci_alloc_consistent() fulfills the requirement for 64 bytes + * alignment + */ + pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma); + + if (pool == NULL) { + printk(KERN_ERR "%s : DMA memory allocation failed.\n", + vptr->dev->name); + return -ENOMEM; + } + + memset(pool, 0, psize); + + vptr->rd_ring = (struct rx_desc *) pool; + + vptr->rd_pool_dma = pool_dma; + + tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq; + vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize, + &vptr->tx_bufs_dma); + + if (vptr->tx_bufs == NULL) { + printk(KERN_ERR "%s: DMA memory allocation failed.\n", + vptr->dev->name); + pci_free_consistent(vptr->pdev, psize, pool, pool_dma); + return -ENOMEM; + } + + memset(vptr->tx_bufs, 0, vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq); + + i = vptr->options.numrx * sizeof(struct rx_desc); + pool += i; + pool_dma += i; + for (i = 0; i < vptr->num_txq; i++) { + int offset = vptr->options.numtx * sizeof(struct tx_desc); + + vptr->td_pool_dma[i] = pool_dma; + vptr->td_rings[i] = (struct tx_desc *) pool; + pool += offset; + pool_dma += offset; + } + return 0; +} + +/** + * velocity_free_rings - free PCI ring pointers + * @vptr: Velocity to free from + * + * Clean up the PCI ring buffers allocated to this velocity. + */ + +static void velocity_free_rings(struct velocity_info *vptr) +{ + int size; + + size = vptr->options.numrx * sizeof(struct rx_desc) + + vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq; + + pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma); + + size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq; + + pci_free_consistent(vptr->pdev, size, vptr->tx_bufs, vptr->tx_bufs_dma); +} + +/** + * velocity_init_rd_ring - set up receive ring + * @vptr: velocity to configure + * + * Allocate and set up the receive buffers for each ring slot and + * assign them to the network adapter. + */ + +static int velocity_init_rd_ring(struct velocity_info *vptr) +{ + int i, ret = -ENOMEM; + struct rx_desc *rd; + struct velocity_rd_info *rd_info; + unsigned int rsize = sizeof(struct velocity_rd_info) * + vptr->options.numrx; + + vptr->rd_info = kmalloc(rsize, GFP_KERNEL); + if(vptr->rd_info == NULL) + goto out; + memset(vptr->rd_info, 0, rsize); + + /* Init the RD ring entries */ + for (i = 0; i < vptr->options.numrx; i++) { + rd = &(vptr->rd_ring[i]); + rd_info = &(vptr->rd_info[i]); + + ret = velocity_alloc_rx_buf(vptr, i); + if (ret < 0) { + VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR + "%s: failed to allocate RX buffer.\n", + vptr->dev->name); + velocity_free_rd_ring(vptr); + goto out; + } + rd->rdesc0.owner = OWNED_BY_NIC; + } + vptr->rd_used = vptr->rd_curr = 0; +out: + return ret; +} + +/** + * velocity_free_rd_ring - set up receive ring + * @vptr: velocity to clean up + * + * Free the receive buffers for each ring slot and any + * attached socket buffers that need to go away. + */ + +static void velocity_free_rd_ring(struct velocity_info *vptr) +{ + int i; + + if (vptr->rd_info == NULL) + return; + + for (i = 0; i < vptr->options.numrx; i++) { + struct velocity_rd_info *rd_info = &(vptr->rd_info[i]); + + if (!rd_info->skb_dma) + continue; + pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz, + PCI_DMA_FROMDEVICE); + rd_info->skb_dma = (dma_addr_t) NULL; + + dev_kfree_skb(rd_info->skb); + rd_info->skb = NULL; + } + + kfree(vptr->rd_info); + vptr->rd_info = NULL; +} + +/** + * velocity_init_td_ring - set up transmit ring + * @vptr: velocity + * + * Set up the transmit ring and chain the ring pointers together. + * Returns zero on success or a negative posix errno code for + * failure. + */ + +static int velocity_init_td_ring(struct velocity_info *vptr) +{ + int i, j; + dma_addr_t curr; + struct tx_desc *td; + struct velocity_td_info *td_info; + unsigned int tsize = sizeof(struct velocity_td_info) * + vptr->options.numtx; + + /* Init the TD ring entries */ + for (j = 0; j < vptr->num_txq; j++) { + curr = vptr->td_pool_dma[j]; + + vptr->td_infos[j] = kmalloc(tsize, GFP_KERNEL); + if(vptr->td_infos[j] == NULL) + { + while(--j >= 0) + kfree(vptr->td_infos[j]); + return -ENOMEM; + } + memset(vptr->td_infos[j], 0, tsize); + + for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) { + td = &(vptr->td_rings[j][i]); + td_info = &(vptr->td_infos[j][i]); + td_info->buf = vptr->tx_bufs + (i + j) * PKT_BUF_SZ; + td_info->buf_dma = vptr->tx_bufs_dma + (i + j) * PKT_BUF_SZ; + } + vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0; + } + return 0; +} + +/* + * FIXME: could we merge this with velocity_free_tx_buf ? + */ + +static void velocity_free_td_ring_entry(struct velocity_info *vptr, + int q, int n) +{ + struct velocity_td_info * td_info = &(vptr->td_infos[q][n]); + int i; + + if (td_info == NULL) + return; + + if (td_info->skb) { + for (i = 0; i < td_info->nskb_dma; i++) + { + if (td_info->skb_dma[i]) { + pci_unmap_single(vptr->pdev, td_info->skb_dma[i], + td_info->skb->len, PCI_DMA_TODEVICE); + td_info->skb_dma[i] = (dma_addr_t) NULL; + } + } + dev_kfree_skb(td_info->skb); + td_info->skb = NULL; + } +} + +/** + * velocity_free_td_ring - free td ring + * @vptr: velocity + * + * Free up the transmit ring for this particular velocity adapter. + * We free the ring contents but not the ring itself. + */ + +static void velocity_free_td_ring(struct velocity_info *vptr) +{ + int i, j; + + for (j = 0; j < vptr->num_txq; j++) { + if (vptr->td_infos[j] == NULL) + continue; + for (i = 0; i < vptr->options.numtx; i++) { + velocity_free_td_ring_entry(vptr, j, i); + + } + if (vptr->td_infos[j]) { + kfree(vptr->td_infos[j]); + vptr->td_infos[j] = NULL; + } + } +} + +/** + * velocity_rx_srv - service RX interrupt + * @vptr: velocity + * @status: adapter status (unused) + * + * Walk the receive ring of the velocity adapter and remove + * any received packets from the receive queue. Hand the ring + * slots back to the adapter for reuse. + */ + +static int velocity_rx_srv(struct velocity_info *vptr, int status) +{ + struct rx_desc *rd; + struct net_device_stats *stats = &vptr->stats; + struct mac_regs * regs = vptr->mac_regs; + int rd_curr = vptr->rd_curr; + int works = 0; + + while (1) { + + rd = &(vptr->rd_ring[rd_curr]); + + if ((vptr->rd_info[rd_curr]).skb == NULL) { + if (velocity_alloc_rx_buf(vptr, rd_curr) < 0) + break; + } + + if (works++ > 15) + break; + + if (rd->rdesc0.owner == OWNED_BY_NIC) + break; + + /* + * Don't drop CE or RL error frame although RXOK is off + * FIXME: need to handle copybreak + */ + if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) { + if (velocity_receive_frame(vptr, rd_curr) == 0) { + if (velocity_alloc_rx_buf(vptr, rd_curr) < 0) { + VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not allocate rx buf\n", vptr->dev->name); + break; + } + } else { + stats->rx_dropped++; + } + } else { + if (rd->rdesc0.RSR & RSR_CRC) + stats->rx_crc_errors++; + if (rd->rdesc0.RSR & RSR_FAE) + stats->rx_frame_errors++; + + stats->rx_dropped++; + } + + rd->inten = 1; + + if (++vptr->rd_used >= 4) { + int i, rd_prev = rd_curr; + for (i = 0; i < 4; i++) { + if (--rd_prev < 0) + rd_prev = vptr->options.numrx - 1; + + rd = &(vptr->rd_ring[rd_prev]); + rd->rdesc0.owner = OWNED_BY_NIC; + } + writew(4, &(regs->RBRDU)); + vptr->rd_used -= 4; + } + + vptr->dev->last_rx = jiffies; + + rd_curr++; + if (rd_curr >= vptr->options.numrx) + rd_curr = 0; + } + vptr->rd_curr = rd_curr; + VAR_USED(stats); + return works; +} + +/** + * velocity_rx_csum - checksum process + * @rd: receive packet descriptor + * @skb: network layer packet buffer + * + * Process the status bits for the received packet and determine + * if the checksum was computed and verified by the hardware + */ + +static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb) +{ + skb->ip_summed = CHECKSUM_NONE; + + if (rd->rdesc1.CSM & CSM_IPKT) { + if (rd->rdesc1.CSM & CSM_IPOK) { + if ((rd->rdesc1.CSM & CSM_TCPKT) || + (rd->rdesc1.CSM & CSM_UDPKT)) { + if (!(rd->rdesc1.CSM & CSM_TUPOK)) { + return; + } + } + skb->ip_summed = CHECKSUM_UNNECESSARY; + } + } +} + +/** + * velocity_receive_frame - received packet processor + * @vptr: velocity we are handling + * @idx: ring index + * + * A packet has arrived. We process the packet and if appropriate + * pass the frame up the network stack + */ + +static int velocity_receive_frame(struct velocity_info *vptr, int idx) +{ + struct net_device_stats *stats = &vptr->stats; + struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]); + struct rx_desc *rd = &(vptr->rd_ring[idx]); + struct sk_buff *skb; + + if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) { + VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name); + stats->rx_length_errors++; + return -EINVAL; + } + + if (rd->rdesc0.RSR & RSR_MAR) + vptr->stats.multicast++; + + skb = rd_info->skb; + skb->dev = vptr->dev; + + pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz, + PCI_DMA_FROMDEVICE); + rd_info->skb_dma = (dma_addr_t) NULL; + rd_info->skb = NULL; + + /* FIXME - memmove ? */ + if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) { + int i; + for (i = rd->rdesc0.len + 4; i >= 0; i--) + *(skb->data + i + 2) = *(skb->data + i); + skb->data += 2; + skb->tail += 2; + } + + skb_put(skb, (rd->rdesc0.len - 4)); + skb->protocol = eth_type_trans(skb, skb->dev); + + /* + * Drop frame not meeting IEEE 802.3 + */ + + if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) { + if (rd->rdesc0.RSR & RSR_RL) { + stats->rx_length_errors++; + return -EINVAL; + } + } + + velocity_rx_csum(rd, skb); + + /* + * FIXME: need rx_copybreak handling + */ + + stats->rx_bytes += skb->len; + netif_rx(skb); + + return 0; +} + +/** + * velocity_alloc_rx_buf - allocate aligned receive buffer + * @vptr: velocity + * @idx: ring index + * + * Allocate a new full sized buffer for the reception of a frame and + * map it into PCI space for the hardware to use. The hardware + * requires *64* byte alignment of the buffer which makes life + * less fun than would be ideal. + */ + +static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx) +{ + struct rx_desc *rd = &(vptr->rd_ring[idx]); + struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]); + + rd_info->skb = dev_alloc_skb(vptr->rx_buf_sz + 64); + if (rd_info->skb == NULL) + return -ENOMEM; + + /* + * Do the gymnastics to get the buffer head for data at + * 64byte alignment. + */ + skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63); + rd_info->skb->dev = vptr->dev; + rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); + + /* + * Fill in the descriptor to match + */ + + *((u32 *) & (rd->rdesc0)) = 0; + rd->len = cpu_to_le32(vptr->rx_buf_sz); + rd->inten = 1; + rd->pa_low = cpu_to_le32(rd_info->skb_dma); + rd->pa_high = 0; + return 0; +} + +/** + * tx_srv - transmit interrupt service + * @vptr; Velocity + * @status: + * + * Scan the queues looking for transmitted packets that + * we can complete and clean up. Update any statistics as + * neccessary/ + */ + +static int velocity_tx_srv(struct velocity_info *vptr, u32 status) +{ + struct tx_desc *td; + int qnum; + int full = 0; + int idx; + int works = 0; + struct velocity_td_info *tdinfo; + struct net_device_stats *stats = &vptr->stats; + + for (qnum = 0; qnum < vptr->num_txq; qnum++) { + for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0; + idx = (idx + 1) % vptr->options.numtx) { + + /* + * Get Tx Descriptor + */ + td = &(vptr->td_rings[qnum][idx]); + tdinfo = &(vptr->td_infos[qnum][idx]); + + if (td->tdesc0.owner == OWNED_BY_NIC) + break; + + if ((works++ > 15)) + break; + + if (td->tdesc0.TSR & TSR0_TERR) { + stats->tx_errors++; + stats->tx_dropped++; + if (td->tdesc0.TSR & TSR0_CDH) + stats->tx_heartbeat_errors++; + if (td->tdesc0.TSR & TSR0_CRS) + stats->tx_carrier_errors++; + if (td->tdesc0.TSR & TSR0_ABT) + stats->tx_aborted_errors++; + if (td->tdesc0.TSR & TSR0_OWC) + stats->tx_window_errors++; + } else { + stats->tx_packets++; + stats->tx_bytes += tdinfo->skb->len; + } + velocity_free_tx_buf(vptr, tdinfo); + vptr->td_used[qnum]--; + } + vptr->td_tail[qnum] = idx; + + if (AVAIL_TD(vptr, qnum) < 1) { + full = 1; + } + } + /* + * Look to see if we should kick the transmit network + * layer for more work. + */ + if (netif_queue_stopped(vptr->dev) && (full == 0) + && (!(vptr->mii_status & VELOCITY_LINK_FAIL))) { + netif_wake_queue(vptr->dev); + } + return works; +} + +/** + * velocity_print_link_status - link status reporting + * @vptr: velocity to report on + * + * Turn the link status of the velocity card into a kernel log + * description of the new link state, detailing speed and duplex + * status + */ + +static void velocity_print_link_status(struct velocity_info *vptr) +{ + + if (vptr->mii_status & VELOCITY_LINK_FAIL) { + VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name); + } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) { + VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link autonegation", vptr->dev->name); + + if (vptr->mii_status & VELOCITY_SPEED_1000) + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps"); + else if (vptr->mii_status & VELOCITY_SPEED_100) + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps"); + else + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps"); + + if (vptr->mii_status & VELOCITY_DUPLEX_FULL) + VELOCITY_PRT(MSG_LEVEL_INFO, " full duplex\n"); + else + VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n"); + } else { + VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name); + switch (vptr->options.spd_dpx) { + case SPD_DPX_100_HALF: + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n"); + break; + case SPD_DPX_100_FULL: + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps full duplex\n"); + break; + case SPD_DPX_10_HALF: + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps half duplex\n"); + break; + case SPD_DPX_10_FULL: + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps full duplex\n"); + break; + default: + break; + } + } +} + +/** + * velocity_error - handle error from controller + * @vptr: velocity + * @status: card status + * + * Process an error report from the hardware and attempt to recover + * the card itself. At the moment we cannot recover from some + * theoretically impossible errors but this could be fixed using + * the pci_device_failed logic to bounce the hardware + * + */ + +static void velocity_error(struct velocity_info *vptr, int status) +{ + + if (status & ISR_TXSTLI) { + struct mac_regs * regs = vptr->mac_regs; + + printk(KERN_ERR "TD structure errror TDindex=%hx\n", readw(®s->TDIdx[0])); + BYTE_REG_BITS_ON(TXESR_TDSTR, ®s->TXESR); + writew(TRDCSR_RUN, ®s->TDCSRClr); + netif_stop_queue(vptr->dev); + + /* FIXME: port over the pci_device_failed code and use it + here */ + } + + if (status & ISR_SRCI) { + struct mac_regs * regs = vptr->mac_regs; + int linked; + + if (vptr->options.spd_dpx == SPD_DPX_AUTO) { + vptr->mii_status = check_connection_type(regs); + + /* + * If it is a 3119, disable frame bursting in + * halfduplex mode and enable it in fullduplex + * mode + */ + if (vptr->rev_id < REV_ID_VT3216_A0) { + if (vptr->mii_status | VELOCITY_DUPLEX_FULL) + BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->TCR); + else + BYTE_REG_BITS_OFF(TCR_TB2BDIS, ®s->TCR); + } + /* + * Only enable CD heart beat counter in 10HD mode + */ + if (!(vptr->mii_status & VELOCITY_DUPLEX_FULL) && (vptr->mii_status & VELOCITY_SPEED_10)) { + BYTE_REG_BITS_OFF(TESTCFG_HBDIS, ®s->TESTCFG); + } else { + BYTE_REG_BITS_ON(TESTCFG_HBDIS, ®s->TESTCFG); + } + } + /* + * Get link status from PHYSR0 + */ + linked = readb(®s->PHYSR0) & PHYSR0_LINKGD; + + if (linked) { + vptr->mii_status &= ~VELOCITY_LINK_FAIL; + } else { + vptr->mii_status |= VELOCITY_LINK_FAIL; + } + + velocity_print_link_status(vptr); + enable_flow_control_ability(vptr); + + /* + * Re-enable auto-polling because SRCI will disable + * auto-polling + */ + + enable_mii_autopoll(regs); + + if (vptr->mii_status & VELOCITY_LINK_FAIL) + netif_stop_queue(vptr->dev); + else + netif_wake_queue(vptr->dev); + + }; + if (status & ISR_MIBFI) + velocity_update_hw_mibs(vptr); + if (status & ISR_LSTEI) + mac_rx_queue_wake(vptr->mac_regs); +} + +/** + * velocity_free_tx_buf - free transmit buffer + * @vptr: velocity + * @tdinfo: buffer + * + * Release an transmit buffer. If the buffer was preallocated then + * recycle it, if not then unmap the buffer. + */ + +static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo) +{ + struct sk_buff *skb = tdinfo->skb; + int i; + + /* + * Don't unmap the pre-allocated tx_bufs + */ + if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) { + + for (i = 0; i < tdinfo->nskb_dma; i++) { +#ifdef VELOCITY_ZERO_COPY_SUPPORT + pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], td->tdesc1.len, PCI_DMA_TODEVICE); +#else + pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE); +#endif + tdinfo->skb_dma[i] = 0; + } + } + dev_kfree_skb_irq(skb); + tdinfo->skb = NULL; +} + +/** + * velocity_open - interface activation callback + * @dev: network layer device to open + * + * Called when the network layer brings the interface up. Returns + * a negative posix error code on failure, or zero on success. + * + * All the ring allocation and set up is done on open for this + * adapter to minimise memory usage when inactive + */ + +static int velocity_open(struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + int ret; + + vptr->rx_buf_sz = (dev->mtu <= 1504 ? PKT_BUF_SZ : dev->mtu + 32); + + ret = velocity_init_rings(vptr); + if (ret < 0) + goto out; + + ret = velocity_init_rd_ring(vptr); + if (ret < 0) + goto err_free_desc_rings; + + ret = velocity_init_td_ring(vptr); + if (ret < 0) + goto err_free_rd_ring; + + /* Ensure chip is running */ + pci_set_power_state(vptr->pdev, 0); + + velocity_init_registers(vptr, VELOCITY_INIT_COLD); + + ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ, + dev->name, dev); + if (ret < 0) { + /* Power down the chip */ + pci_set_power_state(vptr->pdev, 3); + goto err_free_td_ring; + } + + mac_enable_int(vptr->mac_regs); + netif_start_queue(dev); + vptr->flags |= VELOCITY_FLAGS_OPENED; +out: + return ret; + +err_free_td_ring: + velocity_free_td_ring(vptr); +err_free_rd_ring: + velocity_free_rd_ring(vptr); +err_free_desc_rings: + velocity_free_rings(vptr); + goto out; +} + +/** + * velocity_change_mtu - MTU change callback + * @dev: network device + * @new_mtu: desired MTU + * + * Handle requests from the networking layer for MTU change on + * this interface. It gets called on a change by the network layer. + * Return zero for success or negative posix error code. + */ + +static int velocity_change_mtu(struct net_device *dev, int new_mtu) +{ + struct velocity_info *vptr = dev->priv; + unsigned long flags; + int oldmtu = dev->mtu; + int ret = 0; + + if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) { + VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n", + vptr->dev->name); + return -EINVAL; + } + + if (new_mtu != oldmtu) { + spin_lock_irqsave(&vptr->lock, flags); + + netif_stop_queue(dev); + velocity_shutdown(vptr); + + velocity_free_td_ring(vptr); + velocity_free_rd_ring(vptr); + + dev->mtu = new_mtu; + if (new_mtu > 8192) + vptr->rx_buf_sz = 9 * 1024; + else if (new_mtu > 4096) + vptr->rx_buf_sz = 8192; + else + vptr->rx_buf_sz = 4 * 1024; + + ret = velocity_init_rd_ring(vptr); + if (ret < 0) + goto out_unlock; + + ret = velocity_init_td_ring(vptr); + if (ret < 0) + goto out_unlock; + + velocity_init_registers(vptr, VELOCITY_INIT_COLD); + + mac_enable_int(vptr->mac_regs); + netif_start_queue(dev); +out_unlock: + spin_unlock_irqrestore(&vptr->lock, flags); + } + + return ret; +} + +/** + * velocity_shutdown - shut down the chip + * @vptr: velocity to deactivate + * + * Shuts down the internal operations of the velocity and + * disables interrupts, autopolling, transmit and receive + */ + +static void velocity_shutdown(struct velocity_info *vptr) +{ + struct mac_regs * regs = vptr->mac_regs; + mac_disable_int(regs); + writel(CR0_STOP, ®s->CR0Set); + writew(0xFFFF, ®s->TDCSRClr); + writeb(0xFF, ®s->RDCSRClr); + safe_disable_mii_autopoll(regs); + mac_clear_isr(regs); +} + +/** + * velocity_close - close adapter callback + * @dev: network device + * + * Callback from the network layer when the velocity is being + * deactivated by the network layer + */ + +static int velocity_close(struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + + netif_stop_queue(dev); + velocity_shutdown(vptr); + + if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) + velocity_get_ip(vptr); + if (dev->irq != 0) + free_irq(dev->irq, dev); + + /* Power down the chip */ + pci_set_power_state(vptr->pdev, 3); + + /* Free the resources */ + velocity_free_td_ring(vptr); + velocity_free_rd_ring(vptr); + velocity_free_rings(vptr); + + vptr->flags &= (~VELOCITY_FLAGS_OPENED); + return 0; +} + +/** + * velocity_xmit - transmit packet callback + * @skb: buffer to transmit + * @dev: network device + * + * Called by the networ layer to request a packet is queued to + * the velocity. Returns zero on success. + */ + +static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + int qnum = 0; + struct tx_desc *td_ptr; + struct velocity_td_info *tdinfo; + unsigned long flags; + int index; + + int pktlen = skb->len; + + spin_lock_irqsave(&vptr->lock, flags); + + index = vptr->td_curr[qnum]; + td_ptr = &(vptr->td_rings[qnum][index]); + tdinfo = &(vptr->td_infos[qnum][index]); + + td_ptr->tdesc1.TCPLS = TCPLS_NORMAL; + td_ptr->tdesc1.TCR = TCR0_TIC; + td_ptr->td_buf[0].queue = 0; + + /* + * Pad short frames. + */ + if (pktlen < ETH_ZLEN) { + /* Cannot occur until ZC support */ + if(skb_linearize(skb, GFP_ATOMIC)) + return 0; + pktlen = ETH_ZLEN; + memcpy(tdinfo->buf, skb->data, skb->len); + memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); + tdinfo->skb = skb; + tdinfo->skb_dma[0] = tdinfo->buf_dma; + td_ptr->tdesc0.pktsize = pktlen; + td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); + td_ptr->td_buf[0].pa_high = 0; + td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; + tdinfo->nskb_dma = 1; + td_ptr->tdesc1.CMDZ = 2; + } else +#ifdef VELOCITY_ZERO_COPY_SUPPORT + if (skb_shinfo(skb)->nr_frags > 0) { + int nfrags = skb_shinfo(skb)->nr_frags; + tdinfo->skb = skb; + if (nfrags > 6) { + skb_linearize(skb, GFP_ATOMIC); + memcpy(tdinfo->buf, skb->data, skb->len); + tdinfo->skb_dma[0] = tdinfo->buf_dma; + td_ptr->tdesc0.pktsize = + td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); + td_ptr->td_buf[0].pa_high = 0; + td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; + tdinfo->nskb_dma = 1; + td_ptr->tdesc1.CMDZ = 2; + } else { + int i = 0; + tdinfo->nskb_dma = 0; + tdinfo->skb_dma[i] = pci_map_single(vptr->pdev, skb->data, skb->len - skb->data_len, PCI_DMA_TODEVICE); + + td_ptr->tdesc0.pktsize = pktlen; + + /* FIXME: support 48bit DMA later */ + td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma); + td_ptr->td_buf[i].pa_high = 0; + td_ptr->td_buf[i].bufsize = skb->len->skb->data_len; + + for (i = 0; i < nfrags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + void *addr = ((void *) page_address(frag->page + frag->page_offset)); + + tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE); + + td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]); + td_ptr->td_buf[i + 1].pa_high = 0; + td_ptr->td_buf[i + 1].bufsize = frag->size; + } + tdinfo->nskb_dma = i - 1; + td_ptr->tdesc1.CMDZ = i; + } + + } else +#endif + { + /* + * Map the linear network buffer into PCI space and + * add it to the transmit ring. + */ + tdinfo->skb = skb; + tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE); + td_ptr->tdesc0.pktsize = pktlen; + td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); + td_ptr->td_buf[0].pa_high = 0; + td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; + tdinfo->nskb_dma = 1; + td_ptr->tdesc1.CMDZ = 2; + } + + if (vptr->flags & VELOCITY_FLAGS_TAGGING) { + td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff); + td_ptr->tdesc1.pqinf.priority = 0; + td_ptr->tdesc1.pqinf.CFI = 0; + td_ptr->tdesc1.TCR |= TCR0_VETAG; + } + + /* + * Handle hardware checksum + */ + if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM) + && (skb->ip_summed == CHECKSUM_HW)) { + struct iphdr *ip = skb->nh.iph; + if (ip->protocol == IPPROTO_TCP) + td_ptr->tdesc1.TCR |= TCR0_TCPCK; + else if (ip->protocol == IPPROTO_UDP) + td_ptr->tdesc1.TCR |= (TCR0_UDPCK); + td_ptr->tdesc1.TCR |= TCR0_IPCK; + } + { + + int prev = index - 1; + + if (prev < 0) + prev = vptr->options.numtx - 1; + td_ptr->tdesc0.owner = OWNED_BY_NIC; + vptr->td_used[qnum]++; + vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx; + + if (AVAIL_TD(vptr, qnum) < 1) + netif_stop_queue(dev); + + td_ptr = &(vptr->td_rings[qnum][prev]); + td_ptr->td_buf[0].queue = 1; + mac_tx_queue_wake(vptr->mac_regs, qnum); + } + dev->trans_start = jiffies; + spin_unlock_irqrestore(&vptr->lock, flags); + return 0; +} + +/** + * velocity_intr - interrupt callback + * @irq: interrupt number + * @dev_instance: interrupting device + * @pt_regs: CPU register state at interrupt + * + * Called whenever an interrupt is generated by the velocity + * adapter IRQ line. We may not be the source of the interrupt + * and need to identify initially if we are, and if not exit as + * efficiently as possible. + */ + +static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = dev_instance; + struct velocity_info *vptr = dev->priv; + u32 isr_status; + int max_count = 0; + + + spin_lock(&vptr->lock); + isr_status = mac_read_isr(vptr->mac_regs); + + /* Not us ? */ + if (isr_status == 0) { + spin_unlock(&vptr->lock); + return IRQ_NONE; + } + + mac_disable_int(vptr->mac_regs); + + /* + * Keep processing the ISR until we have completed + * processing and the isr_status becomes zero + */ + + while (isr_status != 0) { + mac_write_isr(vptr->mac_regs, isr_status); + if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI))) + velocity_error(vptr, isr_status); + if (isr_status & (ISR_PRXI | ISR_PPRXI)) + max_count += velocity_rx_srv(vptr, isr_status); + if (isr_status & (ISR_PTXI | ISR_PPTXI)) + max_count += velocity_tx_srv(vptr, isr_status); + isr_status = mac_read_isr(vptr->mac_regs); + if (max_count > vptr->options.int_works) + { + printk(KERN_WARNING "%s: excessive work at interrupt.\n", + dev->name); + max_count = 0; + } + } + spin_unlock(&vptr->lock); + mac_enable_int(vptr->mac_regs); + return IRQ_HANDLED; + +} + + +/** + * ether_crc - ethernet CRC function + * + * Compute an ethernet CRC hash of the data block provided. This + * is not performance optimised but is not needed in performance + * critical code paths. + * + * FIXME: could we use shared code here ? + */ + +static inline u32 ether_crc(int length, unsigned char *data) +{ + static unsigned const ethernet_polynomial = 0x04c11db7U; + + int crc = -1; + + while (--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) { + crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); + } + } + return crc; +} + +/** + * velocity_set_multi - filter list change callback + * @dev: network device + * + * Called by the network layer when the filter lists need to change + * for a velocity adapter. Reload the CAMs with the new address + * filter ruleset. + */ + +static void velocity_set_multi(struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + struct mac_regs * regs = vptr->mac_regs; + u8 rx_mode; + int i; + struct dev_mc_list *mclist; + + if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ + /* Unconditionally log net taps. */ + printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); + writel(0xffffffff, ®s->MARCAM[0]); + writel(0xffffffff, ®s->MARCAM[4]); + rx_mode = (RCR_AM | RCR_AB | RCR_PROM); + } else if ((dev->mc_count > vptr->multicast_limit) + || (dev->flags & IFF_ALLMULTI)) { + writel(0xffffffff, ®s->MARCAM[0]); + writel(0xffffffff, ®s->MARCAM[4]); + rx_mode = (RCR_AM | RCR_AB); + } else { + int offset = MCAM_SIZE - vptr->multicast_limit; + mac_get_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); + + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { + mac_set_cam(regs, i + offset, mclist->dmi_addr, VELOCITY_MULTICAST_CAM); + vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7); + } + + mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); + rx_mode = (RCR_AM | RCR_AB); + } + if (dev->mtu > 1500) + rx_mode |= RCR_AL; + + BYTE_REG_BITS_ON(rx_mode, ®s->RCR); + +} + +/** + * velocity_get_status - statistics callback + * @dev: network device + * + * Callback from the network layer to allow driver statistics + * to be resynchronized with hardware collected state. In the + * case of the velocity we need to pull the MIB counters from + * the hardware into the counters before letting the network + * layer display them. + */ + +static struct net_device_stats *velocity_get_stats(struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + + /* If the hardware is down, don't touch MII */ + if(!netif_running(dev)) + return &vptr->stats; + + spin_lock_irq(&vptr->lock); + velocity_update_hw_mibs(vptr); + spin_unlock_irq(&vptr->lock); + + vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts]; + vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts]; + vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors]; + +// unsigned long rx_dropped; /* no space in linux buffers */ + vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions]; + /* detailed rx_errors: */ +// unsigned long rx_length_errors; +// unsigned long rx_over_errors; /* receiver ring buff overflow */ + vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE]; +// unsigned long rx_frame_errors; /* recv'd frame alignment error */ +// unsigned long rx_fifo_errors; /* recv'r fifo overrun */ +// unsigned long rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ +// unsigned long tx_fifo_errors; + + return &vptr->stats; +} + + +/** + * velocity_ioctl - ioctl entry point + * @dev: network device + * @rq: interface request ioctl + * @cmd: command code + * + * Called when the user issues an ioctl request to the network + * device in question. The velocity interface supports MII. + */ + +static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct velocity_info *vptr = dev->priv; + int ret; + + /* If we are asked for information and the device is power + saving then we need to bring the device back up to talk to it */ + + if(!netif_running(dev)) + pci_set_power_state(vptr->pdev, 0); + + switch (cmd) { + case SIOCGMIIPHY: /* Get address of MII PHY in use. */ + case SIOCGMIIREG: /* Read MII PHY register. */ + case SIOCSMIIREG: /* Write to MII PHY register. */ + ret = velocity_mii_ioctl(dev, rq, cmd); + break; + + default: + ret = -EOPNOTSUPP; + } + if(!netif_running(dev)) + pci_set_power_state(vptr->pdev, 3); + + + return ret; +} + +/* + * Definition for our device driver. The PCI layer interface + * uses this to handle all our card discover and plugging + */ + +static struct pci_driver velocity_driver = { + name:VELOCITY_NAME, + id_table:velocity_id_table, + probe:velocity_found1, + remove:velocity_remove1, +#ifdef CONFIG_PM + suspend:velocity_suspend, + resume:velocity_resume, +#endif +}; + +/** + * velocity_init_module - load time function + * + * Called when the velocity module is loaded. The PCI driver + * is registered with the PCI layer, and in turn will call + * the probe functions for each velocity adapter installed + * in the system. + */ + +static int __init velocity_init_module(void) +{ + int ret; + ret = pci_module_init(&velocity_driver); + +#ifdef CONFIG_PM + register_inetaddr_notifier(&velocity_inetaddr_notifier); +#endif + return ret; +} + +/** + * velocity_cleanup - module unload + * + * When the velocity hardware is unloaded this function is called. + * It will clean up the notifiers and the unregister the PCI + * driver interface for this hardware. This in turn cleans up + * all discovered interfaces before returning from the function + */ + +static void __exit velocity_cleanup_module(void) +{ +#ifdef CONFIG_PM + unregister_inetaddr_notifier(&velocity_inetaddr_notifier); +#endif + pci_unregister_driver(&velocity_driver); +} + +module_init(velocity_init_module); +module_exit(velocity_cleanup_module); + + +/* + * MII access , media link mode setting functions + */ + + +/** + * mii_init - set up MII + * @vptr: velocity adapter + * @mii_status: links tatus + * + * Set up the PHY for the current link state. + */ + +static void mii_init(struct velocity_info *vptr, u32 mii_status) +{ + u16 BMCR; + + switch (PHYID_GET_PHY_ID(vptr->phy_id)) { + case PHYID_CICADA_CS8201: + /* + * Reset to hardware default + */ + MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs); + /* + * Turn on ECHODIS bit in NWay-forced full mode and turn it + * off it in NWay-forced half mode for NWay-forced v.s. + * legacy-forced issue. + */ + if (vptr->mii_status & VELOCITY_DUPLEX_FULL) + MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs); + else + MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs); + /* + * Turn on Link/Activity LED enable bit for CIS8201 + */ + MII_REG_BITS_ON(PLED_LALBE, MII_REG_PLED, vptr->mac_regs); + break; + case PHYID_VT3216_32BIT: + case PHYID_VT3216_64BIT: + /* + * Reset to hardware default + */ + MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs); + /* + * Turn on ECHODIS bit in NWay-forced full mode and turn it + * off it in NWay-forced half mode for NWay-forced v.s. + * legacy-forced issue + */ + if (vptr->mii_status & VELOCITY_DUPLEX_FULL) + MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs); + else + MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs); + break; + + case PHYID_MARVELL_1000: + case PHYID_MARVELL_1000S: + /* + * Assert CRS on Transmit + */ + MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs); + /* + * Reset to hardware default + */ + MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs); + break; + default: + ; + } + velocity_mii_read(vptr->mac_regs, MII_REG_BMCR, &BMCR); + if (BMCR & BMCR_ISO) { + BMCR &= ~BMCR_ISO; + velocity_mii_write(vptr->mac_regs, MII_REG_BMCR, BMCR); + } +} + +/** + * safe_disable_mii_autopoll - autopoll off + * @regs: velocity registers + * + * Turn off the autopoll and wait for it to disable on the chip + */ + +static void safe_disable_mii_autopoll(struct mac_regs * regs) +{ + u16 ww; + + /* turn off MAUTO */ + writeb(0, ®s->MIICR); + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + udelay(1); + if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->MIISR)) + break; + } +} + +/** + * enable_mii_autopoll - turn on autopolling + * @regs: velocity registers + * + * Enable the MII link status autopoll feature on the Velocity + * hardware. Wait for it to enable. + */ + +static void enable_mii_autopoll(struct mac_regs * regs) +{ + int ii; + + writeb(0, &(regs->MIICR)); + writeb(MIIADR_SWMPL, ®s->MIIADR); + + for (ii = 0; ii < W_MAX_TIMEOUT; ii++) { + udelay(1); + if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->MIISR)) + break; + } + + writeb(MIICR_MAUTO, ®s->MIICR); + + for (ii = 0; ii < W_MAX_TIMEOUT; ii++) { + udelay(1); + if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, ®s->MIISR)) + break; + } + +} + +/** + * velocity_mii_read - read MII data + * @regs: velocity registers + * @index: MII register index + * @data: buffer for received data + * + * Perform a single read of an MII 16bit register. Returns zero + * on success or -ETIMEDOUT if the PHY did not respond. + */ + +static int velocity_mii_read(struct mac_regs * regs, u8 index, u16 *data) +{ + u16 ww; + + /* + * Disable MIICR_MAUTO, so that mii addr can be set normally + */ + safe_disable_mii_autopoll(regs); + + writeb(index, ®s->MIIADR); + + BYTE_REG_BITS_ON(MIICR_RCMD, ®s->MIICR); + + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + if (!(readb(®s->MIICR) & MIICR_RCMD)) + break; + } + + *data = readw(®s->MIIDATA); + + enable_mii_autopoll(regs); + if (ww == W_MAX_TIMEOUT) + return -ETIMEDOUT; + return 0; +} + +/** + * velocity_mii_write - write MII data + * @regs: velocity registers + * @index: MII register index + * @data: 16bit data for the MII register + * + * Perform a single write to an MII 16bit register. Returns zero + * on success or -ETIMEDOUT if the PHY did not respond. + */ + +static int velocity_mii_write(struct mac_regs * regs, u8 mii_addr, u16 data) +{ + u16 ww; + + /* + * Disable MIICR_MAUTO, so that mii addr can be set normally + */ + safe_disable_mii_autopoll(regs); + + /* MII reg offset */ + writeb(mii_addr, ®s->MIIADR); + /* set MII data */ + writew(data, ®s->MIIDATA); + + /* turn on MIICR_WCMD */ + BYTE_REG_BITS_ON(MIICR_WCMD, ®s->MIICR); + + /* W_MAX_TIMEOUT is the timeout period */ + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + udelay(5); + if (!(readb(®s->MIICR) & MIICR_WCMD)) + break; + } + enable_mii_autopoll(regs); + + if (ww == W_MAX_TIMEOUT) + return -ETIMEDOUT; + return 0; +} + +/** + * velocity_get_opt_media_mode - get media selection + * @vptr: velocity adapter + * + * Get the media mode stored in EEPROM or module options and load + * mii_status accordingly. The requested link state information + * is also returned. + */ + +static u32 velocity_get_opt_media_mode(struct velocity_info *vptr) +{ + u32 status = 0; + + switch (vptr->options.spd_dpx) { + case SPD_DPX_AUTO: + status = VELOCITY_AUTONEG_ENABLE; + break; + case SPD_DPX_100_FULL: + status = VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL; + break; + case SPD_DPX_10_FULL: + status = VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL; + break; + case SPD_DPX_100_HALF: + status = VELOCITY_SPEED_100; + break; + case SPD_DPX_10_HALF: + status = VELOCITY_SPEED_10; + break; + } + vptr->mii_status = status; + return status; +} + +/** + * mii_set_auto_on - autonegotiate on + * @vptr: velocity + * + * Enable autonegotation on this interface + */ + +static void mii_set_auto_on(struct velocity_info *vptr) +{ + if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs)) + MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs); + else + MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs); +} + + +/* +static void mii_set_auto_off(struct velocity_info * vptr) +{ + MII_REG_BITS_OFF(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs); +} +*/ + +/** + * set_mii_flow_control - flow control setup + * @vptr: velocity interface + * + * Set up the flow control on this interface according to + * the supplied user/eeprom options. + */ + +static void set_mii_flow_control(struct velocity_info *vptr) +{ + /*Enable or Disable PAUSE in ANAR */ + switch (vptr->options.flow_cntl) { + case FLOW_CNTL_TX: + MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs); + MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs); + break; + + case FLOW_CNTL_RX: + MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs); + MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs); + break; + + case FLOW_CNTL_TX_RX: + MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs); + MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs); + break; + + case FLOW_CNTL_DISABLE: + MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs); + MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs); + break; + default: + break; + } +} + +/** + * velocity_set_media_mode - set media mode + * @mii_status: old MII link state + * + * Check the media link state and configure the flow control + * PHY and also velocity hardware setup accordingly. In particular + * we need to set up CD polling and frame bursting. + */ + +static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) +{ + u32 curr_status; + struct mac_regs * regs = vptr->mac_regs; + + vptr->mii_status = mii_check_media_mode(vptr->mac_regs); + curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL); + + /* Set mii link status */ + set_mii_flow_control(vptr); + + /* + Check if new status is consisent with current status + if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) + || (mii_status==curr_status)) { + vptr->mii_status=mii_check_media_mode(vptr->mac_regs); + vptr->mii_status=check_connection_type(vptr->mac_regs); + VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n"); + return 0; + } + */ + + if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) { + MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs); + } + + /* + * If connection type is AUTO + */ + if (mii_status & VELOCITY_AUTONEG_ENABLE) { + VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity is AUTO mode\n"); + /* clear force MAC mode bit */ + BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR); + /* set duplex mode of MAC according to duplex mode of MII */ + MII_REG_BITS_ON(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10, MII_REG_ANAR, vptr->mac_regs); + MII_REG_BITS_ON(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs); + MII_REG_BITS_ON(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs); + + /* enable AUTO-NEGO mode */ + mii_set_auto_on(vptr); + } else { + u16 ANAR; + u8 CHIPGCR; + + /* + * 1. if it's 3119, disable frame bursting in halfduplex mode + * and enable it in fullduplex mode + * 2. set correct MII/GMII and half/full duplex mode in CHIPGCR + * 3. only enable CD heart beat counter in 10HD mode + */ + + /* set force MAC mode bit */ + BYTE_REG_BITS_ON(CHIPGCR_FCMODE, ®s->CHIPGCR); + + CHIPGCR = readb(®s->CHIPGCR); + CHIPGCR &= ~CHIPGCR_FCGMII; + + if (mii_status & VELOCITY_DUPLEX_FULL) { + CHIPGCR |= CHIPGCR_FCFDX; + writeb(CHIPGCR, ®s->CHIPGCR); + VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced full mode\n"); + if (vptr->rev_id < REV_ID_VT3216_A0) + BYTE_REG_BITS_OFF(TCR_TB2BDIS, ®s->TCR); + } else { + CHIPGCR &= ~CHIPGCR_FCFDX; + VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced half mode\n"); + writeb(CHIPGCR, ®s->CHIPGCR); + if (vptr->rev_id < REV_ID_VT3216_A0) + BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->TCR); + } + + MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs); + + if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10)) { + BYTE_REG_BITS_OFF(TESTCFG_HBDIS, ®s->TESTCFG); + } else { + BYTE_REG_BITS_ON(TESTCFG_HBDIS, ®s->TESTCFG); + } + /* MII_REG_BITS_OFF(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs); */ + velocity_mii_read(vptr->mac_regs, MII_REG_ANAR, &ANAR); + ANAR &= (~(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)); + if (mii_status & VELOCITY_SPEED_100) { + if (mii_status & VELOCITY_DUPLEX_FULL) + ANAR |= ANAR_TXFD; + else + ANAR |= ANAR_TX; + } else { + if (mii_status & VELOCITY_DUPLEX_FULL) + ANAR |= ANAR_10FD; + else + ANAR |= ANAR_10; + } + velocity_mii_write(vptr->mac_regs, MII_REG_ANAR, ANAR); + /* enable AUTO-NEGO mode */ + mii_set_auto_on(vptr); + /* MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs); */ + } + /* vptr->mii_status=mii_check_media_mode(vptr->mac_regs); */ + /* vptr->mii_status=check_connection_type(vptr->mac_regs); */ + return VELOCITY_LINK_CHANGE; +} + +/** + * mii_check_media_mode - check media state + * @regs: velocity registers + * + * Check the current MII status and determine the link status + * accordingly + */ + +static u32 mii_check_media_mode(struct mac_regs * regs) +{ + u32 status = 0; + u16 ANAR; + + if (!MII_REG_BITS_IS_ON(BMSR_LNK, MII_REG_BMSR, regs)) + status |= VELOCITY_LINK_FAIL; + + if (MII_REG_BITS_IS_ON(G1000CR_1000FD, MII_REG_G1000CR, regs)) + status |= VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL; + else if (MII_REG_BITS_IS_ON(G1000CR_1000, MII_REG_G1000CR, regs)) + status |= (VELOCITY_SPEED_1000); + else { + velocity_mii_read(regs, MII_REG_ANAR, &ANAR); + if (ANAR & ANAR_TXFD) + status |= (VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL); + else if (ANAR & ANAR_TX) + status |= VELOCITY_SPEED_100; + else if (ANAR & ANAR_10FD) + status |= (VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL); + else + status |= (VELOCITY_SPEED_10); + } + + if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) { + velocity_mii_read(regs, MII_REG_ANAR, &ANAR); + if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) + == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) { + if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs)) + status |= VELOCITY_AUTONEG_ENABLE; + } + } + + return status; +} + +static u32 check_connection_type(struct mac_regs * regs) +{ + u32 status = 0; + u8 PHYSR0; + u16 ANAR; + PHYSR0 = readb(®s->PHYSR0); + + /* + if (!(PHYSR0 & PHYSR0_LINKGD)) + status|=VELOCITY_LINK_FAIL; + */ + + if (PHYSR0 & PHYSR0_FDPX) + status |= VELOCITY_DUPLEX_FULL; + + if (PHYSR0 & PHYSR0_SPDG) + status |= VELOCITY_SPEED_1000; + if (PHYSR0 & PHYSR0_SPD10) + status |= VELOCITY_SPEED_10; + else + status |= VELOCITY_SPEED_100; + + if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) { + velocity_mii_read(regs, MII_REG_ANAR, &ANAR); + if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) + == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) { + if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs)) + status |= VELOCITY_AUTONEG_ENABLE; + } + } + + return status; +} + +/** + * enable_flow_control_ability - flow control + * @vptr: veloity to configure + * + * Set up flow control according to the flow control options + * determined by the eeprom/configuration. + */ + +static void enable_flow_control_ability(struct velocity_info *vptr) +{ + + struct mac_regs * regs = vptr->mac_regs; + + switch (vptr->options.flow_cntl) { + + case FLOW_CNTL_DEFAULT: + if (BYTE_REG_BITS_IS_ON(PHYSR0_RXFLC, ®s->PHYSR0)) + writel(CR0_FDXRFCEN, ®s->CR0Set); + else + writel(CR0_FDXRFCEN, ®s->CR0Clr); + + if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, ®s->PHYSR0)) + writel(CR0_FDXTFCEN, ®s->CR0Set); + else + writel(CR0_FDXTFCEN, ®s->CR0Clr); + break; + + case FLOW_CNTL_TX: + writel(CR0_FDXTFCEN, ®s->CR0Set); + writel(CR0_FDXRFCEN, ®s->CR0Clr); + break; + + case FLOW_CNTL_RX: + writel(CR0_FDXRFCEN, ®s->CR0Set); + writel(CR0_FDXTFCEN, ®s->CR0Clr); + break; + + case FLOW_CNTL_TX_RX: + writel(CR0_FDXTFCEN, ®s->CR0Set); + writel(CR0_FDXRFCEN, ®s->CR0Set); + break; + + case FLOW_CNTL_DISABLE: + writel(CR0_FDXRFCEN, ®s->CR0Clr); + writel(CR0_FDXTFCEN, ®s->CR0Clr); + break; + + default: + break; + } + +} + + +/** + * velocity_ethtool_up - pre hook for ethtool + * @dev: network device + * + * Called before an ethtool operation. We need to make sure the + * chip is out of D3 state before we poke at it. + */ + +static int velocity_ethtool_up(struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + if(!netif_running(dev)) + pci_set_power_state(vptr->pdev, 0); + return 0; +} + +/** + * velocity_ethtool_down - post hook for ethtool + * @dev: network device + * + * Called after an ethtool operation. Restore the chip back to D3 + * state if it isn't running. + */ + +static void velocity_ethtool_down(struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + if(!netif_running(dev)) + pci_set_power_state(vptr->pdev, 3); +} + +static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct velocity_info *vptr = dev->priv; + struct mac_regs * regs = vptr->mac_regs; + u32 status; + status = check_connection_type(vptr->mac_regs); + + cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; + if (status & VELOCITY_SPEED_100) + cmd->speed = SPEED_100; + else + cmd->speed = SPEED_10; + cmd->autoneg = (status & VELOCITY_AUTONEG_ENABLE) ? AUTONEG_ENABLE : AUTONEG_DISABLE; + cmd->port = PORT_TP; + cmd->transceiver = XCVR_INTERNAL; + cmd->phy_address = readb(®s->MIIADR) & 0x1F; + + if (status & VELOCITY_DUPLEX_FULL) + cmd->duplex = DUPLEX_FULL; + else + cmd->duplex = DUPLEX_HALF; + + return 0; +} + +static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct velocity_info *vptr = dev->priv; + u32 curr_status; + u32 new_status = 0; + int ret = 0; + + curr_status = check_connection_type(vptr->mac_regs); + curr_status &= (~VELOCITY_LINK_FAIL); + + new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0); + new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0); + new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0); + new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0); + + if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) + ret = -EINVAL; + else + velocity_set_media_mode(vptr, new_status); + + return ret; +} + +static u32 velocity_get_link(struct net_device *dev) +{ + struct velocity_info *vptr = dev->priv; + struct mac_regs * regs = vptr->mac_regs; + return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 0 : 1; +} + +static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct velocity_info *vptr = dev->priv; + strcpy(info->driver, VELOCITY_NAME); + strcpy(info->version, VELOCITY_VERSION); + strcpy(info->bus_info, vptr->pdev->slot_name); +} + +static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct velocity_info *vptr = dev->priv; + wol->supported = WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP; + wol->wolopts |= WAKE_MAGIC; + /* + if (vptr->wol_opts & VELOCITY_WOL_PHY) + wol.wolopts|=WAKE_PHY; + */ + if (vptr->wol_opts & VELOCITY_WOL_UCAST) + wol->wolopts |= WAKE_UCAST; + if (vptr->wol_opts & VELOCITY_WOL_ARP) + wol->wolopts |= WAKE_ARP; + memcpy(&wol->sopass, vptr->wol_passwd, 6); +} + +static int velocity_ethtool_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct velocity_info *vptr = dev->priv; + + if (!(wol->wolopts & (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP))) + return -EFAULT; + vptr->wol_opts = VELOCITY_WOL_MAGIC; + + /* + if (wol.wolopts & WAKE_PHY) { + vptr->wol_opts|=VELOCITY_WOL_PHY; + vptr->flags |=VELOCITY_FLAGS_WOL_ENABLED; + } + */ + + if (wol->wolopts & WAKE_MAGIC) { + vptr->wol_opts |= VELOCITY_WOL_MAGIC; + vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED; + } + if (wol->wolopts & WAKE_UCAST) { + vptr->wol_opts |= VELOCITY_WOL_UCAST; + vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED; + } + if (wol->wolopts & WAKE_ARP) { + vptr->wol_opts |= VELOCITY_WOL_ARP; + vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED; + } + memcpy(vptr->wol_passwd, wol->sopass, 6); + return 0; +} + +static u32 velocity_get_msglevel(struct net_device *dev) +{ + return msglevel; +} + +static void velocity_set_msglevel(struct net_device *dev, u32 value) +{ + msglevel = value; +} + +static struct ethtool_ops velocity_ethtool_ops = { + .get_settings = velocity_get_settings, + .set_settings = velocity_set_settings, + .get_drvinfo = velocity_get_drvinfo, + .get_wol = velocity_ethtool_get_wol, + .set_wol = velocity_ethtool_set_wol, + .get_msglevel = velocity_get_msglevel, + .set_msglevel = velocity_set_msglevel, + .get_link = velocity_get_link, + .begin = velocity_ethtool_up, + .complete = velocity_ethtool_down +}; + +/** + * velocity_mii_ioctl - MII ioctl handler + * @dev: network device + * @ifr: the ifreq block for the ioctl + * @cmd: the command + * + * Process MII requests made via ioctl from the network layer. These + * are used by tools like kudzu to interrogate the link state of the + * hardware + */ + +static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct velocity_info *vptr = dev->priv; + struct mac_regs * regs = vptr->mac_regs; + unsigned long flags; + struct mii_ioctl_data *miidata = (struct mii_ioctl_data *) &(ifr->ifr_data); + int err; + + switch (cmd) { + case SIOCGMIIPHY: + miidata->phy_id = readb(®s->MIIADR) & 0x1f; + break; + case SIOCGMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if(velocity_mii_read(vptr->mac_regs, miidata->reg_num & 0x1f, &(miidata->val_out)) < 0) + return -ETIMEDOUT; + break; + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_irqsave(&vptr->lock, flags); + err = velocity_mii_write(vptr->mac_regs, miidata->reg_num & 0x1f, miidata->val_in); + spin_unlock_irqrestore(&vptr->lock, flags); + check_connection_type(vptr->mac_regs); + if(err) + return err; + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + +#ifdef CONFIG_PM + +/** + * velocity_save_context - save registers + * @vptr: velocity + * @context: buffer for stored context + * + * Retrieve the current configuration from the velocity hardware + * and stash it in the context structure, for use by the context + * restore functions. This allows us to save things we need across + * power down states + */ + +static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context) +{ + struct mac_regs * regs = vptr->mac_regs; + u16 i; + u8 *ptr = (u8 *)regs; + + for (i = MAC_REG_PAR; i < MAC_REG_CR0_CLR; i += 4) + *((u32 *) (context->mac_reg + i)) = readl(ptr + i); + + for (i = MAC_REG_MAR; i < MAC_REG_TDCSR_CLR; i += 4) + *((u32 *) (context->mac_reg + i)) = readl(ptr + i); + + for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4) + *((u32 *) (context->mac_reg + i)) = readl(ptr + i); + +} + +/** + * velocity_restore_context - restore registers + * @vptr: velocity + * @context: buffer for stored context + * + * Reload the register configuration from the velocity context + * created by velocity_save_context. + */ + +static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context) +{ + struct mac_regs * regs = vptr->mac_regs; + int i; + u8 *ptr = (u8 *)regs; + + for (i = MAC_REG_PAR; i < MAC_REG_CR0_SET; i += 4) { + writel(*((u32 *) (context->mac_reg + i)), ptr + i); + } + + /* Just skip cr0 */ + for (i = MAC_REG_CR1_SET; i < MAC_REG_CR0_CLR; i++) { + /* Clear */ + writeb(~(*((u8 *) (context->mac_reg + i))), ptr + i + 4); + /* Set */ + writeb(*((u8 *) (context->mac_reg + i)), ptr + i); + } + + for (i = MAC_REG_MAR; i < MAC_REG_IMR; i += 4) { + writel(*((u32 *) (context->mac_reg + i)), ptr + i); + } + + for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4) { + writel(*((u32 *) (context->mac_reg + i)), ptr + i); + } + + for (i = MAC_REG_TDCSR_SET; i <= MAC_REG_RDCSR_SET; i++) { + writeb(*((u8 *) (context->mac_reg + i)), ptr + i); + } + +} + +static int velocity_suspend(struct pci_dev *pdev, u32 state) +{ + struct velocity_info *vptr = pci_get_drvdata(pdev); + unsigned long flags; + + if(!netif_running(vptr->dev)) + return 0; + + netif_device_detach(vptr->dev); + + spin_lock_irqsave(&vptr->lock, flags); + pci_save_state(pdev, vptr->pci_state); +#ifdef ETHTOOL_GWOL + if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) { + velocity_get_ip(vptr); + velocity_save_context(vptr, &vptr->context); + velocity_shutdown(vptr); + velocity_set_wol(vptr); + pci_enable_wake(pdev, 3, 1); + pci_set_power_state(pdev, 3); + } else { + velocity_save_context(vptr, &vptr->context); + velocity_shutdown(vptr); + pci_disable_device(pdev); + pci_set_power_state(pdev, state); + } +#else + pci_set_power_state(pdev, state); +#endif + spin_unlock_irqrestore(&vptr->lock, flags); + return 0; +} + +static int velocity_resume(struct pci_dev *pdev) +{ + struct velocity_info *vptr = pci_get_drvdata(pdev); + unsigned long flags; + int i; + + if(!netif_running(vptr->dev)) + return 0; + + pci_set_power_state(pdev, 0); + pci_enable_wake(pdev, 0, 0); + pci_restore_state(pdev, vptr->pci_state); + + mac_wol_reset(vptr->mac_regs); + + spin_lock_irqsave(&vptr->lock, flags); + velocity_restore_context(vptr, &vptr->context); + velocity_init_registers(vptr, VELOCITY_INIT_WOL); + mac_disable_int(vptr->mac_regs); + + velocity_tx_srv(vptr, 0); + + for (i = 0; i < vptr->num_txq; i++) { + if (vptr->td_used[i]) { + mac_tx_queue_wake(vptr->mac_regs, i); + } + } + + mac_enable_int(vptr->mac_regs); + spin_unlock_irqrestore(&vptr->lock, flags); + netif_device_attach(vptr->dev); + + return 0; +} + +static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *) ptr; + struct net_device *dev; + struct velocity_info *vptr; + + if (ifa) { + dev = ifa->ifa_dev->dev; + vptr = dev->priv; + velocity_get_ip(vptr); + } + return NOTIFY_DONE; +} +#endif + +/* + * Purpose: Functions to set WOL. + */ + +const static unsigned short crc16_tab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + + +static u32 mask_pattern[2][4] = { + {0x00203000, 0x000003C0, 0x00000000, 0x0000000}, /* ARP */ + {0xfffff000, 0xffffffff, 0xffffffff, 0x000ffff} /* Magic Packet */ +}; + +/** + * ether_crc16 - compute ethernet CRC + * @len: buffer length + * @cp: buffer + * @crc16: initial CRC + * + * Compute a CRC value for a block of data. + * FIXME: can we use generic functions ? + */ + +static u16 ether_crc16(int len, u8 * cp, u16 crc16) +{ + while (len--) + crc16 = (crc16 >> 8) ^ crc16_tab[(crc16 ^ *cp++) & 0xff]; + return (crc16); +} + +/** + * bit_reverse - 16bit reverse + * @data: 16bit data t reverse + * + * Reverse the order of a 16bit value and return the reversed bits + */ + +static u16 bit_reverse(u16 data) +{ + u32 new = 0x00000000; + int ii; + + + for (ii = 0; ii < 16; ii++) { + new |= ((u32) (data & 1) << (31 - ii)); + data >>= 1; + } + + return (u16) (new >> 16); +} + +/** + * wol_calc_crc - WOL CRC + * @pattern: data pattern + * @mask_pattern: mask + * + * Compute the wake on lan crc hashes for the packet header + * we are interested in. + */ + +u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern) +{ + u16 crc = 0xFFFF; + u8 mask; + int i, j; + + for (i = 0; i < size; i++) { + mask = mask_pattern[i]; + + /* Skip this loop if the mask equals to zero */ + if (mask == 0x00) + continue; + + for (j = 0; j < 8; j++) { + if ((mask & 0x01) == 0) { + mask >>= 1; + continue; + } + mask >>= 1; + crc = ether_crc16(1, &(pattern[i * 8 + j]), crc); + } + } + /* Finally, invert the result once to get the correct data */ + crc = ~crc; + return bit_reverse(crc); +} + +/** + * velocity_set_wol - set up for wake on lan + * @vptr: velocity to set WOL status on + * + * Set a card up for wake on lan either by unicast or by + * ARP packet. + * + * FIXME: check static buffer is safe here + */ + +static int velocity_set_wol(struct velocity_info *vptr) +{ + struct mac_regs * regs = vptr->mac_regs; + static u8 buf[256]; + int i; + + writew(0xFFFF, ®s->WOLCRClr); + writeb(WOLCFG_SAB | WOLCFG_SAM, ®s->WOLCFGSet); + writew(WOLCR_MAGIC_EN, ®s->WOLCRSet); + + /* + if (vptr->wol_opts & VELOCITY_WOL_PHY) + writew((WOLCR_LINKON_EN|WOLCR_LINKOFF_EN), ®s->WOLCRSet); + */ + + if (vptr->wol_opts & VELOCITY_WOL_UCAST) { + writew(WOLCR_UNICAST_EN, ®s->WOLCRSet); + } + + if (vptr->wol_opts & VELOCITY_WOL_ARP) { + struct arp_packet *arp = (struct arp_packet *) buf; + u16 crc; + memset(buf, 0, sizeof(struct arp_packet) + 7); + + for (i = 0; i < 4; i++) + writel(mask_pattern[0][i], ®s->ByteMask[0][i]); + + arp->type = htons(ETH_P_ARP); + arp->ar_op = htons(1); + + memcpy(arp->ar_tip, vptr->ip_addr, 4); + + crc = wol_calc_crc((sizeof(struct arp_packet) + 7) / 8, buf, (u8 *) & mask_pattern[0][0]); + + writew(crc, ®s->PatternCRC[0]); + writew(WOLCR_ARP_EN, ®s->WOLCRSet); + } + + BYTE_REG_BITS_ON(PWCFG_WOLTYPE, ®s->PWCFGSet); + BYTE_REG_BITS_ON(PWCFG_LEGACY_WOLEN, ®s->PWCFGSet); + + writew(0x0FFF, ®s->WOLSRClr); + + if (vptr->mii_status & VELOCITY_AUTONEG_ENABLE) { + if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) + MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs); + + MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs); + } + + if (vptr->mii_status & VELOCITY_SPEED_1000) + MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs); + + BYTE_REG_BITS_ON(CHIPGCR_FCMODE, ®s->CHIPGCR); + + { + u8 GCR; + GCR = readb(®s->CHIPGCR); + GCR = (GCR & ~CHIPGCR_FCGMII) | CHIPGCR_FCFDX; + writeb(GCR, ®s->CHIPGCR); + } + + BYTE_REG_BITS_OFF(ISR_PWEI, ®s->ISR); + /* Turn on SWPTAG just before entering power mode */ + BYTE_REG_BITS_ON(STICKHW_SWPTAG, ®s->STICKHW); + /* Go to bed ..... */ + BYTE_REG_BITS_ON((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW); + + return 0; +} + diff -Nru a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/net/via-velocity.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1885 @@ +/* + * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. + * All rights reserved. + * + * This software may be redistributed and/or modified under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * File: via-velocity.h + * + * Purpose: Header file to define driver's private structures. + * + * Author: Chuang Liang-Shing, AJ Jiang + * + * Date: Jan 24, 2003 + */ + + +#ifndef VELOCITY_H +#define VELOCITY_H + +#define VELOCITY_TX_CSUM_SUPPORT + +#define VELOCITY_NAME "via-velocity" +#define VELOCITY_FULL_DRV_NAM "VIA Networking Velocity Family Gigabit Ethernet Adapter Driver" +#define VELOCITY_VERSION "1.13" + +#define PKT_BUF_SZ 1540 + +#define MAX_UNITS 8 +#define OPTION_DEFAULT { [0 ... MAX_UNITS-1] = -1} + +#define REV_ID_VT6110 (0) +#define DEVICE_ID (0x3119) + +#define BYTE_REG_BITS_ON(x,p) do { writeb(readb((p))|(x),(p));} while (0) +#define WORD_REG_BITS_ON(x,p) do { writew(readw((p))|(x),(p));} while (0) +#define DWORD_REG_BITS_ON(x,p) do { writel(readl((p))|(x),(p));} while (0) + +#define BYTE_REG_BITS_IS_ON(x,p) (readb((p)) & (x)) +#define WORD_REG_BITS_IS_ON(x,p) (readw((p)) & (x)) +#define DWORD_REG_BITS_IS_ON(x,p) (readl((p)) & (x)) + +#define BYTE_REG_BITS_OFF(x,p) do { writeb(readb((p)) & (~(x)),(p));} while (0) +#define WORD_REG_BITS_OFF(x,p) do { writew(readw((p)) & (~(x)),(p));} while (0) +#define DWORD_REG_BITS_OFF(x,p) do { writel(readl((p)) & (~(x)),(p));} while (0) + +#define BYTE_REG_BITS_SET(x,m,p) do { writeb( (readb((p)) & (~(m))) |(x),(p));} while (0) +#define WORD_REG_BITS_SET(x,m,p) do { writew( (readw((p)) & (~(m))) |(x),(p));} while (0) +#define DWORD_REG_BITS_SET(x,m,p) do { writel( (readl((p)) & (~(m)))|(x),(p));} while (0) + +#define VAR_USED(p) do {(p)=(p);} while (0) + +/* + * Purpose: Structures for MAX RX/TX descriptors. + */ + + +#define B_OWNED_BY_CHIP 1 +#define B_OWNED_BY_HOST 0 + +/* + * Bits in the RSR0 register + */ + +#define RSR_DETAG 0x0080 +#define RSR_SNTAG 0x0040 +#define RSR_RXER 0x0020 +#define RSR_RL 0x0010 +#define RSR_CE 0x0008 +#define RSR_FAE 0x0004 +#define RSR_CRC 0x0002 +#define RSR_VIDM 0x0001 + +/* + * Bits in the RSR1 register + */ + +#define RSR_RXOK 0x8000 // rx OK +#define RSR_PFT 0x4000 // Perfect filtering address match +#define RSR_MAR 0x2000 // MAC accept multicast address packet +#define RSR_BAR 0x1000 // MAC accept broadcast address packet +#define RSR_PHY 0x0800 // MAC accept physical address packet +#define RSR_VTAG 0x0400 // 802.1p/1q tagging packet indicator +#define RSR_STP 0x0200 // start of packet +#define RSR_EDP 0x0100 // end of packet + +/* + * Bits in the RSR1 register + */ + +#define RSR1_RXOK 0x80 // rx OK +#define RSR1_PFT 0x40 // Perfect filtering address match +#define RSR1_MAR 0x20 // MAC accept multicast address packet +#define RSR1_BAR 0x10 // MAC accept broadcast address packet +#define RSR1_PHY 0x08 // MAC accept physical address packet +#define RSR1_VTAG 0x04 // 802.1p/1q tagging packet indicator +#define RSR1_STP 0x02 // start of packet +#define RSR1_EDP 0x01 // end of packet + +/* + * Bits in the CSM register + */ + +#define CSM_IPOK 0x40 //IP Checkusm validatiaon ok +#define CSM_TUPOK 0x20 //TCP/UDP Checkusm validatiaon ok +#define CSM_FRAG 0x10 //Fragment IP datagram +#define CSM_IPKT 0x04 //Received an IP packet +#define CSM_TCPKT 0x02 //Received a TCP packet +#define CSM_UDPKT 0x01 //Received a UDP packet + +/* + * Bits in the TSR0 register + */ + +#define TSR0_ABT 0x0080 // Tx abort because of excessive collision +#define TSR0_OWT 0x0040 // Jumbo frame Tx abort +#define TSR0_OWC 0x0020 // Out of window collision +#define TSR0_COLS 0x0010 // experience collision in this transmit event +#define TSR0_NCR3 0x0008 // collision retry counter[3] +#define TSR0_NCR2 0x0004 // collision retry counter[2] +#define TSR0_NCR1 0x0002 // collision retry counter[1] +#define TSR0_NCR0 0x0001 // collision retry counter[0] +#define TSR0_TERR 0x8000 // +#define TSR0_FDX 0x4000 // current transaction is serviced by full duplex mode +#define TSR0_GMII 0x2000 // current transaction is serviced by GMII mode +#define TSR0_LNKFL 0x1000 // packet serviced during link down +#define TSR0_SHDN 0x0400 // shutdown case +#define TSR0_CRS 0x0200 // carrier sense lost +#define TSR0_CDH 0x0100 // AQE test fail (CD heartbeat) + +/* + * Bits in the TSR1 register + */ + +#define TSR1_TERR 0x80 // +#define TSR1_FDX 0x40 // current transaction is serviced by full duplex mode +#define TSR1_GMII 0x20 // current transaction is serviced by GMII mode +#define TSR1_LNKFL 0x10 // packet serviced during link down +#define TSR1_SHDN 0x04 // shutdown case +#define TSR1_CRS 0x02 // carrier sense lost +#define TSR1_CDH 0x01 // AQE test fail (CD heartbeat) + +// +// Bits in the TCR0 register +// +#define TCR0_TIC 0x80 // assert interrupt immediately while descriptor has been send complete +#define TCR0_PIC 0x40 // priority interrupt request, INA# is issued over adaptive interrupt scheme +#define TCR0_VETAG 0x20 // enable VLAN tag +#define TCR0_IPCK 0x10 // request IP checksum calculation. +#define TCR0_UDPCK 0x08 // request UDP checksum calculation. +#define TCR0_TCPCK 0x04 // request TCP checksum calculation. +#define TCR0_JMBO 0x02 // indicate a jumbo packet in GMAC side +#define TCR0_CRC 0x01 // disable CRC generation + +#define TCPLS_NORMAL 3 +#define TCPLS_START 2 +#define TCPLS_END 1 +#define TCPLS_MED 0 + + +// max transmit or receive buffer size +#define CB_RX_BUF_SIZE 2048UL // max buffer size + // NOTE: must be multiple of 4 + +#define CB_MAX_RD_NUM 512 // MAX # of RD +#define CB_MAX_TD_NUM 256 // MAX # of TD + +#define CB_INIT_RD_NUM_3119 128 // init # of RD, for setup VT3119 +#define CB_INIT_TD_NUM_3119 64 // init # of TD, for setup VT3119 + +#define CB_INIT_RD_NUM 128 // init # of RD, for setup default +#define CB_INIT_TD_NUM 64 // init # of TD, for setup default + +// for 3119 +#define CB_TD_RING_NUM 4 // # of TD rings. +#define CB_MAX_SEG_PER_PKT 7 // max data seg per packet (Tx) + + +/* + * If collisions excess 15 times , tx will abort, and + * if tx fifo underflow, tx will fail + * we should try to resend it + */ + +#define CB_MAX_TX_ABORT_RETRY 3 + +/* + * Receive descriptor + */ + +struct rdesc0 { + u16 RSR; /* Receive status */ + u16 len:14; /* Received packet length */ + u16 reserved:1; + u16 owner:1; /* Who owns this buffer ? */ +}; + +struct rdesc1 { + u16 PQTAG; + u8 CSM; + u8 IPKT; +}; + +struct rx_desc { + struct rdesc0 rdesc0; + struct rdesc1 rdesc1; + u32 pa_low; /* Low 32 bit PCI address */ + u16 pa_high; /* Next 16 bit PCI address (48 total) */ + u16 len:15; /* Frame size */ + u16 inten:1; /* Enable interrupt */ +} __attribute__ ((__packed__)); + +/* + * Transmit descriptor + */ + +struct tdesc0 { + u16 TSR; /* Transmit status register */ + u16 pktsize:14; /* Size of frame */ + u16 reserved:1; + u16 owner:1; /* Who owns the buffer */ +}; + +struct pqinf { /* Priority queue info */ + u16 VID:12; + u16 CFI:1; + u16 priority:3; +} __attribute__ ((__packed__)); + +struct tdesc1 { + struct pqinf pqinf; + u8 TCR; + u8 TCPLS:2; + u8 reserved:2; + u8 CMDZ:4; +} __attribute__ ((__packed__)); + +struct td_buf { + u32 pa_low; + u16 pa_high; + u16 bufsize:14; + u16 reserved:1; + u16 queue:1; +} __attribute__ ((__packed__)); + +struct tx_desc { + struct tdesc0 tdesc0; + struct tdesc1 tdesc1; + struct td_buf td_buf[7]; +}; + +struct velocity_rd_info { + struct sk_buff *skb; + dma_addr_t skb_dma; +}; + +/** + * alloc_rd_info - allocate an rd info block + * + * Alocate and initialize a receive info structure used for keeping + * track of kernel side information related to each receive + * descriptor we are using + */ + +static inline struct velocity_rd_info *alloc_rd_info(void) +{ + struct velocity_rd_info *ptr; + if ((ptr = kmalloc(sizeof(struct velocity_rd_info), GFP_ATOMIC)) == NULL) + return NULL; + else { + memset(ptr, 0, sizeof(struct velocity_rd_info)); + return ptr; + } +} + +/* + * Used to track transmit side buffers. + */ + +struct velocity_td_info { + struct sk_buff *skb; + u8 *buf; + int nskb_dma; + dma_addr_t skb_dma[7]; + dma_addr_t buf_dma; +}; + +enum { + OWNED_BY_HOST = 0, + OWNED_BY_NIC = 1 +} velocity_owner; + + +/* + * MAC registers and macros. + */ + + +#define MCAM_SIZE 64 +#define VCAM_SIZE 64 +#define TX_QUEUE_NO 4 + +#define MAX_HW_MIB_COUNTER 32 +#define VELOCITY_MIN_MTU (1514-14) +#define VELOCITY_MAX_MTU (9000) + +/* + * Registers in the MAC + */ + +#define MAC_REG_PAR 0x00 // physical address +#define MAC_REG_RCR 0x06 +#define MAC_REG_TCR 0x07 +#define MAC_REG_CR0_SET 0x08 +#define MAC_REG_CR1_SET 0x09 +#define MAC_REG_CR2_SET 0x0A +#define MAC_REG_CR3_SET 0x0B +#define MAC_REG_CR0_CLR 0x0C +#define MAC_REG_CR1_CLR 0x0D +#define MAC_REG_CR2_CLR 0x0E +#define MAC_REG_CR3_CLR 0x0F +#define MAC_REG_MAR 0x10 +#define MAC_REG_CAM 0x10 +#define MAC_REG_DEC_BASE_HI 0x18 +#define MAC_REG_DBF_BASE_HI 0x1C +#define MAC_REG_ISR_CTL 0x20 +#define MAC_REG_ISR_HOTMR 0x20 +#define MAC_REG_ISR_TSUPTHR 0x20 +#define MAC_REG_ISR_RSUPTHR 0x20 +#define MAC_REG_ISR_CTL1 0x21 +#define MAC_REG_TXE_SR 0x22 +#define MAC_REG_RXE_SR 0x23 +#define MAC_REG_ISR 0x24 +#define MAC_REG_ISR0 0x24 +#define MAC_REG_ISR1 0x25 +#define MAC_REG_ISR2 0x26 +#define MAC_REG_ISR3 0x27 +#define MAC_REG_IMR 0x28 +#define MAC_REG_IMR0 0x28 +#define MAC_REG_IMR1 0x29 +#define MAC_REG_IMR2 0x2A +#define MAC_REG_IMR3 0x2B +#define MAC_REG_TDCSR_SET 0x30 +#define MAC_REG_RDCSR_SET 0x32 +#define MAC_REG_TDCSR_CLR 0x34 +#define MAC_REG_RDCSR_CLR 0x36 +#define MAC_REG_RDBASE_LO 0x38 +#define MAC_REG_RDINDX 0x3C +#define MAC_REG_TDBASE_LO 0x40 +#define MAC_REG_RDCSIZE 0x50 +#define MAC_REG_TDCSIZE 0x52 +#define MAC_REG_TDINDX 0x54 +#define MAC_REG_TDIDX0 0x54 +#define MAC_REG_TDIDX1 0x56 +#define MAC_REG_TDIDX2 0x58 +#define MAC_REG_TDIDX3 0x5A +#define MAC_REG_PAUSE_TIMER 0x5C +#define MAC_REG_RBRDU 0x5E +#define MAC_REG_FIFO_TEST0 0x60 +#define MAC_REG_FIFO_TEST1 0x64 +#define MAC_REG_CAMADDR 0x68 +#define MAC_REG_CAMCR 0x69 +#define MAC_REG_GFTEST 0x6A +#define MAC_REG_FTSTCMD 0x6B +#define MAC_REG_MIICFG 0x6C +#define MAC_REG_MIISR 0x6D +#define MAC_REG_PHYSR0 0x6E +#define MAC_REG_PHYSR1 0x6F +#define MAC_REG_MIICR 0x70 +#define MAC_REG_MIIADR 0x71 +#define MAC_REG_MIIDATA 0x72 +#define MAC_REG_SOFT_TIMER0 0x74 +#define MAC_REG_SOFT_TIMER1 0x76 +#define MAC_REG_CFGA 0x78 +#define MAC_REG_CFGB 0x79 +#define MAC_REG_CFGC 0x7A +#define MAC_REG_CFGD 0x7B +#define MAC_REG_DCFG0 0x7C +#define MAC_REG_DCFG1 0x7D +#define MAC_REG_MCFG0 0x7E +#define MAC_REG_MCFG1 0x7F + +#define MAC_REG_TBIST 0x80 +#define MAC_REG_RBIST 0x81 +#define MAC_REG_PMCC 0x82 +#define MAC_REG_STICKHW 0x83 +#define MAC_REG_MIBCR 0x84 +#define MAC_REG_EERSV 0x85 +#define MAC_REG_REVID 0x86 +#define MAC_REG_MIBREAD 0x88 +#define MAC_REG_BPMA 0x8C +#define MAC_REG_EEWR_DATA 0x8C +#define MAC_REG_BPMD_WR 0x8F +#define MAC_REG_BPCMD 0x90 +#define MAC_REG_BPMD_RD 0x91 +#define MAC_REG_EECHKSUM 0x92 +#define MAC_REG_EECSR 0x93 +#define MAC_REG_EERD_DATA 0x94 +#define MAC_REG_EADDR 0x96 +#define MAC_REG_EMBCMD 0x97 +#define MAC_REG_JMPSR0 0x98 +#define MAC_REG_JMPSR1 0x99 +#define MAC_REG_JMPSR2 0x9A +#define MAC_REG_JMPSR3 0x9B +#define MAC_REG_CHIPGSR 0x9C +#define MAC_REG_TESTCFG 0x9D +#define MAC_REG_DEBUG 0x9E +#define MAC_REG_CHIPGCR 0x9F +#define MAC_REG_WOLCR0_SET 0xA0 +#define MAC_REG_WOLCR1_SET 0xA1 +#define MAC_REG_PWCFG_SET 0xA2 +#define MAC_REG_WOLCFG_SET 0xA3 +#define MAC_REG_WOLCR0_CLR 0xA4 +#define MAC_REG_WOLCR1_CLR 0xA5 +#define MAC_REG_PWCFG_CLR 0xA6 +#define MAC_REG_WOLCFG_CLR 0xA7 +#define MAC_REG_WOLSR0_SET 0xA8 +#define MAC_REG_WOLSR1_SET 0xA9 +#define MAC_REG_WOLSR0_CLR 0xAC +#define MAC_REG_WOLSR1_CLR 0xAD +#define MAC_REG_PATRN_CRC0 0xB0 +#define MAC_REG_PATRN_CRC1 0xB2 +#define MAC_REG_PATRN_CRC2 0xB4 +#define MAC_REG_PATRN_CRC3 0xB6 +#define MAC_REG_PATRN_CRC4 0xB8 +#define MAC_REG_PATRN_CRC5 0xBA +#define MAC_REG_PATRN_CRC6 0xBC +#define MAC_REG_PATRN_CRC7 0xBE +#define MAC_REG_BYTEMSK0_0 0xC0 +#define MAC_REG_BYTEMSK0_1 0xC4 +#define MAC_REG_BYTEMSK0_2 0xC8 +#define MAC_REG_BYTEMSK0_3 0xCC +#define MAC_REG_BYTEMSK1_0 0xD0 +#define MAC_REG_BYTEMSK1_1 0xD4 +#define MAC_REG_BYTEMSK1_2 0xD8 +#define MAC_REG_BYTEMSK1_3 0xDC +#define MAC_REG_BYTEMSK2_0 0xE0 +#define MAC_REG_BYTEMSK2_1 0xE4 +#define MAC_REG_BYTEMSK2_2 0xE8 +#define MAC_REG_BYTEMSK2_3 0xEC +#define MAC_REG_BYTEMSK3_0 0xF0 +#define MAC_REG_BYTEMSK3_1 0xF4 +#define MAC_REG_BYTEMSK3_2 0xF8 +#define MAC_REG_BYTEMSK3_3 0xFC + +/* + * Bits in the RCR register + */ + +#define RCR_AS 0x80 +#define RCR_AP 0x40 +#define RCR_AL 0x20 +#define RCR_PROM 0x10 +#define RCR_AB 0x08 +#define RCR_AM 0x04 +#define RCR_AR 0x02 +#define RCR_SEP 0x01 + +/* + * Bits in the TCR register + */ + +#define TCR_TB2BDIS 0x80 +#define TCR_COLTMC1 0x08 +#define TCR_COLTMC0 0x04 +#define TCR_LB1 0x02 /* loopback[1] */ +#define TCR_LB0 0x01 /* loopback[0] */ + +/* + * Bits in the CR0 register + */ + +#define CR0_TXON 0x00000008UL +#define CR0_RXON 0x00000004UL +#define CR0_STOP 0x00000002UL /* stop MAC, default = 1 */ +#define CR0_STRT 0x00000001UL /* start MAC */ +#define CR0_SFRST 0x00008000UL /* software reset */ +#define CR0_TM1EN 0x00004000UL +#define CR0_TM0EN 0x00002000UL +#define CR0_DPOLL 0x00000800UL /* disable rx/tx auto polling */ +#define CR0_DISAU 0x00000100UL +#define CR0_XONEN 0x00800000UL +#define CR0_FDXTFCEN 0x00400000UL /* full-duplex TX flow control enable */ +#define CR0_FDXRFCEN 0x00200000UL /* full-duplex RX flow control enable */ +#define CR0_HDXFCEN 0x00100000UL /* half-duplex flow control enable */ +#define CR0_XHITH1 0x00080000UL /* TX XON high threshold 1 */ +#define CR0_XHITH0 0x00040000UL /* TX XON high threshold 0 */ +#define CR0_XLTH1 0x00020000UL /* TX pause frame low threshold 1 */ +#define CR0_XLTH0 0x00010000UL /* TX pause frame low threshold 0 */ +#define CR0_GSPRST 0x80000000UL +#define CR0_FORSRST 0x40000000UL +#define CR0_FPHYRST 0x20000000UL +#define CR0_DIAG 0x10000000UL +#define CR0_INTPCTL 0x04000000UL +#define CR0_GINTMSK1 0x02000000UL +#define CR0_GINTMSK0 0x01000000UL + +/* + * Bits in the CR1 register + */ + +#define CR1_SFRST 0x80 /* software reset */ +#define CR1_TM1EN 0x40 +#define CR1_TM0EN 0x20 +#define CR1_DPOLL 0x08 /* disable rx/tx auto polling */ +#define CR1_DISAU 0x01 + +/* + * Bits in the CR2 register + */ + +#define CR2_XONEN 0x80 +#define CR2_FDXTFCEN 0x40 /* full-duplex TX flow control enable */ +#define CR2_FDXRFCEN 0x20 /* full-duplex RX flow control enable */ +#define CR2_HDXFCEN 0x10 /* half-duplex flow control enable */ +#define CR2_XHITH1 0x08 /* TX XON high threshold 1 */ +#define CR2_XHITH0 0x04 /* TX XON high threshold 0 */ +#define CR2_XLTH1 0x02 /* TX pause frame low threshold 1 */ +#define CR2_XLTH0 0x01 /* TX pause frame low threshold 0 */ + +/* + * Bits in the CR3 register + */ + +#define CR3_GSPRST 0x80 +#define CR3_FORSRST 0x40 +#define CR3_FPHYRST 0x20 +#define CR3_DIAG 0x10 +#define CR3_INTPCTL 0x04 +#define CR3_GINTMSK1 0x02 +#define CR3_GINTMSK0 0x01 + +#define ISRCTL_UDPINT 0x8000 +#define ISRCTL_TSUPDIS 0x4000 +#define ISRCTL_RSUPDIS 0x2000 +#define ISRCTL_PMSK1 0x1000 +#define ISRCTL_PMSK0 0x0800 +#define ISRCTL_INTPD 0x0400 +#define ISRCTL_HCRLD 0x0200 +#define ISRCTL_SCRLD 0x0100 + +/* + * Bits in the ISR_CTL1 register + */ + +#define ISRCTL1_UDPINT 0x80 +#define ISRCTL1_TSUPDIS 0x40 +#define ISRCTL1_RSUPDIS 0x20 +#define ISRCTL1_PMSK1 0x10 +#define ISRCTL1_PMSK0 0x08 +#define ISRCTL1_INTPD 0x04 +#define ISRCTL1_HCRLD 0x02 +#define ISRCTL1_SCRLD 0x01 + +/* + * Bits in the TXE_SR register + */ + +#define TXESR_TFDBS 0x08 +#define TXESR_TDWBS 0x04 +#define TXESR_TDRBS 0x02 +#define TXESR_TDSTR 0x01 + +/* + * Bits in the RXE_SR register + */ + +#define RXESR_RFDBS 0x08 +#define RXESR_RDWBS 0x04 +#define RXESR_RDRBS 0x02 +#define RXESR_RDSTR 0x01 + +/* + * Bits in the ISR register + */ + +#define ISR_ISR3 0x80000000UL +#define ISR_ISR2 0x40000000UL +#define ISR_ISR1 0x20000000UL +#define ISR_ISR0 0x10000000UL +#define ISR_TXSTLI 0x02000000UL +#define ISR_RXSTLI 0x01000000UL +#define ISR_HFLD 0x00800000UL +#define ISR_UDPI 0x00400000UL +#define ISR_MIBFI 0x00200000UL +#define ISR_SHDNI 0x00100000UL +#define ISR_PHYI 0x00080000UL +#define ISR_PWEI 0x00040000UL +#define ISR_TMR1I 0x00020000UL +#define ISR_TMR0I 0x00010000UL +#define ISR_SRCI 0x00008000UL +#define ISR_LSTPEI 0x00004000UL +#define ISR_LSTEI 0x00002000UL +#define ISR_OVFI 0x00001000UL +#define ISR_FLONI 0x00000800UL +#define ISR_RACEI 0x00000400UL +#define ISR_TXWB1I 0x00000200UL +#define ISR_TXWB0I 0x00000100UL +#define ISR_PTX3I 0x00000080UL +#define ISR_PTX2I 0x00000040UL +#define ISR_PTX1I 0x00000020UL +#define ISR_PTX0I 0x00000010UL +#define ISR_PTXI 0x00000008UL +#define ISR_PRXI 0x00000004UL +#define ISR_PPTXI 0x00000002UL +#define ISR_PPRXI 0x00000001UL + +/* + * Bits in the IMR register + */ + +#define IMR_TXSTLM 0x02000000UL +#define IMR_UDPIM 0x00400000UL +#define IMR_MIBFIM 0x00200000UL +#define IMR_SHDNIM 0x00100000UL +#define IMR_PHYIM 0x00080000UL +#define IMR_PWEIM 0x00040000UL +#define IMR_TMR1IM 0x00020000UL +#define IMR_TMR0IM 0x00010000UL + +#define IMR_SRCIM 0x00008000UL +#define IMR_LSTPEIM 0x00004000UL +#define IMR_LSTEIM 0x00002000UL +#define IMR_OVFIM 0x00001000UL +#define IMR_FLONIM 0x00000800UL +#define IMR_RACEIM 0x00000400UL +#define IMR_TXWB1IM 0x00000200UL +#define IMR_TXWB0IM 0x00000100UL + +#define IMR_PTX3IM 0x00000080UL +#define IMR_PTX2IM 0x00000040UL +#define IMR_PTX1IM 0x00000020UL +#define IMR_PTX0IM 0x00000010UL +#define IMR_PTXIM 0x00000008UL +#define IMR_PRXIM 0x00000004UL +#define IMR_PPTXIM 0x00000002UL +#define IMR_PPRXIM 0x00000001UL + +/* 0x0013FB0FUL = initial value of IMR */ + +#define INT_MASK_DEF (IMR_PPTXIM|IMR_PPRXIM|IMR_PTXIM|IMR_PRXIM|\ + IMR_PWEIM|IMR_TXWB0IM|IMR_TXWB1IM|IMR_FLONIM|\ + IMR_OVFIM|IMR_LSTEIM|IMR_LSTPEIM|IMR_SRCIM|IMR_MIBFIM|\ + IMR_SHDNIM|IMR_TMR1IM|IMR_TMR0IM|IMR_TXSTLM) + +/* + * Bits in the TDCSR0/1, RDCSR0 register + */ + +#define TRDCSR_DEAD 0x0008 +#define TRDCSR_WAK 0x0004 +#define TRDCSR_ACT 0x0002 +#define TRDCSR_RUN 0x0001 + +/* + * Bits in the CAMADDR register + */ + +#define CAMADDR_CAMEN 0x80 +#define CAMADDR_VCAMSL 0x40 + +/* + * Bits in the CAMCR register + */ + +#define CAMCR_PS1 0x80 +#define CAMCR_PS0 0x40 +#define CAMCR_AITRPKT 0x20 +#define CAMCR_AITR16 0x10 +#define CAMCR_CAMRD 0x08 +#define CAMCR_CAMWR 0x04 +#define CAMCR_PS_CAM_MASK 0x40 +#define CAMCR_PS_CAM_DATA 0x80 +#define CAMCR_PS_MAR 0x00 + +/* + * Bits in the MIICFG register + */ + +#define MIICFG_MPO1 0x80 +#define MIICFG_MPO0 0x40 +#define MIICFG_MFDC 0x20 + +/* + * Bits in the MIISR register + */ + +#define MIISR_MIDLE 0x80 + +/* + * Bits in the PHYSR0 register + */ + +#define PHYSR0_PHYRST 0x80 +#define PHYSR0_LINKGD 0x40 +#define PHYSR0_FDPX 0x10 +#define PHYSR0_SPDG 0x08 +#define PHYSR0_SPD10 0x04 +#define PHYSR0_RXFLC 0x02 +#define PHYSR0_TXFLC 0x01 + +/* + * Bits in the PHYSR1 register + */ + +#define PHYSR1_PHYTBI 0x01 + +/* + * Bits in the MIICR register + */ + +#define MIICR_MAUTO 0x80 +#define MIICR_RCMD 0x40 +#define MIICR_WCMD 0x20 +#define MIICR_MDPM 0x10 +#define MIICR_MOUT 0x08 +#define MIICR_MDO 0x04 +#define MIICR_MDI 0x02 +#define MIICR_MDC 0x01 + +/* + * Bits in the MIIADR register + */ + +#define MIIADR_SWMPL 0x80 + +/* + * Bits in the CFGA register + */ + +#define CFGA_PMHCTG 0x08 +#define CFGA_GPIO1PD 0x04 +#define CFGA_ABSHDN 0x02 +#define CFGA_PACPI 0x01 + +/* + * Bits in the CFGB register + */ + +#define CFGB_GTCKOPT 0x80 +#define CFGB_MIIOPT 0x40 +#define CFGB_CRSEOPT 0x20 +#define CFGB_OFSET 0x10 +#define CFGB_CRANDOM 0x08 +#define CFGB_CAP 0x04 +#define CFGB_MBA 0x02 +#define CFGB_BAKOPT 0x01 + +/* + * Bits in the CFGC register + */ + +#define CFGC_EELOAD 0x80 +#define CFGC_BROPT 0x40 +#define CFGC_DLYEN 0x20 +#define CFGC_DTSEL 0x10 +#define CFGC_BTSEL 0x08 +#define CFGC_BPS2 0x04 /* bootrom select[2] */ +#define CFGC_BPS1 0x02 /* bootrom select[1] */ +#define CFGC_BPS0 0x01 /* bootrom select[0] */ + +/* + * Bits in the CFGD register + */ + +#define CFGD_IODIS 0x80 +#define CFGD_MSLVDACEN 0x40 +#define CFGD_CFGDACEN 0x20 +#define CFGD_PCI64EN 0x10 +#define CFGD_HTMRL4 0x08 + +/* + * Bits in the DCFG1 register + */ + +#define DCFG_XMWI 0x8000 +#define DCFG_XMRM 0x4000 +#define DCFG_XMRL 0x2000 +#define DCFG_PERDIS 0x1000 +#define DCFG_MRWAIT 0x0400 +#define DCFG_MWWAIT 0x0200 +#define DCFG_LATMEN 0x0100 + +/* + * Bits in the MCFG0 register + */ + +#define MCFG_RXARB 0x0080 +#define MCFG_RFT1 0x0020 +#define MCFG_RFT0 0x0010 +#define MCFG_LOWTHOPT 0x0008 +#define MCFG_PQEN 0x0004 +#define MCFG_RTGOPT 0x0002 +#define MCFG_VIDFR 0x0001 + +/* + * Bits in the MCFG1 register + */ + +#define MCFG_TXARB 0x8000 +#define MCFG_TXQBK1 0x0800 +#define MCFG_TXQBK0 0x0400 +#define MCFG_TXQNOBK 0x0200 +#define MCFG_SNAPOPT 0x0100 + +/* + * Bits in the PMCC register + */ + +#define PMCC_DSI 0x80 +#define PMCC_D2_DIS 0x40 +#define PMCC_D1_DIS 0x20 +#define PMCC_D3C_EN 0x10 +#define PMCC_D3H_EN 0x08 +#define PMCC_D2_EN 0x04 +#define PMCC_D1_EN 0x02 +#define PMCC_D0_EN 0x01 + +/* + * Bits in STICKHW + */ + +#define STICKHW_SWPTAG 0x10 +#define STICKHW_WOLSR 0x08 +#define STICKHW_WOLEN 0x04 +#define STICKHW_DS1 0x02 /* R/W by software/cfg cycle */ +#define STICKHW_DS0 0x01 /* suspend well DS write port */ + +/* + * Bits in the MIBCR register + */ + +#define MIBCR_MIBISTOK 0x80 +#define MIBCR_MIBISTGO 0x40 +#define MIBCR_MIBINC 0x20 +#define MIBCR_MIBHI 0x10 +#define MIBCR_MIBFRZ 0x08 +#define MIBCR_MIBFLSH 0x04 +#define MIBCR_MPTRINI 0x02 +#define MIBCR_MIBCLR 0x01 + +/* + * Bits in the EERSV register + */ + +#define EERSV_BOOT_RPL ((u8) 0x01) /* Boot method selection for VT6110 */ + +#define EERSV_BOOT_MASK ((u8) 0x06) +#define EERSV_BOOT_INT19 ((u8) 0x00) +#define EERSV_BOOT_INT18 ((u8) 0x02) +#define EERSV_BOOT_LOCAL ((u8) 0x04) +#define EERSV_BOOT_BEV ((u8) 0x06) + + +/* + * Bits in BPCMD + */ + +#define BPCMD_BPDNE 0x80 +#define BPCMD_EBPWR 0x02 +#define BPCMD_EBPRD 0x01 + +/* + * Bits in the EECSR register + */ + +#define EECSR_EMBP 0x40 /* eeprom embeded programming */ +#define EECSR_RELOAD 0x20 /* eeprom content reload */ +#define EECSR_DPM 0x10 /* eeprom direct programming */ +#define EECSR_ECS 0x08 /* eeprom CS pin */ +#define EECSR_ECK 0x04 /* eeprom CK pin */ +#define EECSR_EDI 0x02 /* eeprom DI pin */ +#define EECSR_EDO 0x01 /* eeprom DO pin */ + +/* + * Bits in the EMBCMD register + */ + +#define EMBCMD_EDONE 0x80 +#define EMBCMD_EWDIS 0x08 +#define EMBCMD_EWEN 0x04 +#define EMBCMD_EWR 0x02 +#define EMBCMD_ERD 0x01 + +/* + * Bits in TESTCFG register + */ + +#define TESTCFG_HBDIS 0x80 + +/* + * Bits in CHIPGCR register + */ + +#define CHIPGCR_FCGMII 0x80 +#define CHIPGCR_FCFDX 0x40 +#define CHIPGCR_FCRESV 0x20 +#define CHIPGCR_FCMODE 0x10 +#define CHIPGCR_LPSOPT 0x08 +#define CHIPGCR_TM1US 0x04 +#define CHIPGCR_TM0US 0x02 +#define CHIPGCR_PHYINTEN 0x01 + +/* + * Bits in WOLCR0 + */ + +#define WOLCR_MSWOLEN7 0x0080 /* enable pattern match filtering */ +#define WOLCR_MSWOLEN6 0x0040 +#define WOLCR_MSWOLEN5 0x0020 +#define WOLCR_MSWOLEN4 0x0010 +#define WOLCR_MSWOLEN3 0x0008 +#define WOLCR_MSWOLEN2 0x0004 +#define WOLCR_MSWOLEN1 0x0002 +#define WOLCR_MSWOLEN0 0x0001 +#define WOLCR_ARP_EN 0x0001 + +/* + * Bits in WOLCR1 + */ + +#define WOLCR_LINKOFF_EN 0x0800 /* link off detected enable */ +#define WOLCR_LINKON_EN 0x0400 /* link on detected enable */ +#define WOLCR_MAGIC_EN 0x0200 /* magic packet filter enable */ +#define WOLCR_UNICAST_EN 0x0100 /* unicast filter enable */ + + +/* + * Bits in PWCFG + */ + +#define PWCFG_PHYPWOPT 0x80 /* internal MII I/F timing */ +#define PWCFG_PCISTICK 0x40 /* PCI sticky R/W enable */ +#define PWCFG_WOLTYPE 0x20 /* pulse(1) or button (0) */ +#define PWCFG_LEGCY_WOL 0x10 +#define PWCFG_PMCSR_PME_SR 0x08 +#define PWCFG_PMCSR_PME_EN 0x04 /* control by PCISTICK */ +#define PWCFG_LEGACY_WOLSR 0x02 /* Legacy WOL_SR shadow */ +#define PWCFG_LEGACY_WOLEN 0x01 /* Legacy WOL_EN shadow */ + +/* + * Bits in WOLCFG + */ + +#define WOLCFG_PMEOVR 0x80 /* for legacy use, force PMEEN always */ +#define WOLCFG_SAM 0x20 /* accept multicast case reset, default=0 */ +#define WOLCFG_SAB 0x10 /* accept broadcast case reset, default=0 */ +#define WOLCFG_SMIIACC 0x08 /* ?? */ +#define WOLCFG_SGENWH 0x02 +#define WOLCFG_PHYINTEN 0x01 /* 0:PHYINT trigger enable, 1:use internal MII + to report status change */ +/* + * Bits in WOLSR1 + */ + +#define WOLSR_LINKOFF_INT 0x0800 +#define WOLSR_LINKON_INT 0x0400 +#define WOLSR_MAGIC_INT 0x0200 +#define WOLSR_UNICAST_INT 0x0100 + +/* + * Ethernet address filter type + */ + +#define PKT_TYPE_NONE 0x0000 /* Turn off receiver */ +#define PKT_TYPE_DIRECTED 0x0001 /* obselete, directed address is always accepted */ +#define PKT_TYPE_MULTICAST 0x0002 +#define PKT_TYPE_ALL_MULTICAST 0x0004 +#define PKT_TYPE_BROADCAST 0x0008 +#define PKT_TYPE_PROMISCUOUS 0x0020 +#define PKT_TYPE_LONG 0x2000 /* NOTE.... the definition of LONG is >2048 bytes in our chip */ +#define PKT_TYPE_RUNT 0x4000 +#define PKT_TYPE_ERROR 0x8000 /* Accept error packets, e.g. CRC error */ + +/* + * Loopback mode + */ + +#define MAC_LB_NONE 0x00 +#define MAC_LB_INTERNAL 0x01 +#define MAC_LB_EXTERNAL 0x02 + +/* + * Enabled mask value of irq + */ + +#if defined(_SIM) +#define IMR_MASK_VALUE 0x0033FF0FUL /* initial value of IMR + set IMR0 to 0x0F according to spec */ + +#else +#define IMR_MASK_VALUE 0x0013FB0FUL /* initial value of IMR + ignore MIBFI,RACEI to + reduce intr. frequency + NOTE.... do not enable NoBuf int mask at driver driver + when (1) NoBuf -> RxThreshold = SF + (2) OK -> RxThreshold = original value + */ +#endif + +/* + * Revision id + */ + +#define REV_ID_VT3119_A0 0x00 +#define REV_ID_VT3119_A1 0x01 +#define REV_ID_VT3216_A0 0x10 + +/* + * Max time out delay time + */ + +#define W_MAX_TIMEOUT 0x0FFFU + + +/* + * MAC registers as a structure. Cannot be directly accessed this + * way but generates offsets for readl/writel() calls + */ + +struct mac_regs { + volatile u8 PAR[6]; /* 0x00 */ + volatile u8 RCR; + volatile u8 TCR; + + volatile u32 CR0Set; /* 0x08 */ + volatile u32 CR0Clr; /* 0x0C */ + + volatile u8 MARCAM[8]; /* 0x10 */ + + volatile u32 DecBaseHi; /* 0x18 */ + volatile u16 DbfBaseHi; /* 0x1C */ + volatile u16 reserved_1E; + + volatile u16 ISRCTL; /* 0x20 */ + volatile u8 TXESR; + volatile u8 RXESR; + + volatile u32 ISR; /* 0x24 */ + volatile u32 IMR; + + volatile u32 TDStatusPort; /* 0x2C */ + + volatile u16 TDCSRSet; /* 0x30 */ + volatile u8 RDCSRSet; + volatile u8 reserved_33; + volatile u16 TDCSRClr; + volatile u8 RDCSRClr; + volatile u8 reserved_37; + + volatile u32 RDBaseLo; /* 0x38 */ + volatile u16 RDIdx; /* 0x3C */ + volatile u16 reserved_3E; + + volatile u32 TDBaseLo[4]; /* 0x40 */ + + volatile u16 RDCSize; /* 0x50 */ + volatile u16 TDCSize; /* 0x52 */ + volatile u16 TDIdx[4]; /* 0x54 */ + volatile u16 tx_pause_timer; /* 0x5C */ + volatile u16 RBRDU; /* 0x5E */ + + volatile u32 FIFOTest0; /* 0x60 */ + volatile u32 FIFOTest1; /* 0x64 */ + + volatile u8 CAMADDR; /* 0x68 */ + volatile u8 CAMCR; /* 0x69 */ + volatile u8 GFTEST; /* 0x6A */ + volatile u8 FTSTCMD; /* 0x6B */ + + volatile u8 MIICFG; /* 0x6C */ + volatile u8 MIISR; + volatile u8 PHYSR0; + volatile u8 PHYSR1; + volatile u8 MIICR; + volatile u8 MIIADR; + volatile u16 MIIDATA; + + volatile u16 SoftTimer0; /* 0x74 */ + volatile u16 SoftTimer1; + + volatile u8 CFGA; /* 0x78 */ + volatile u8 CFGB; + volatile u8 CFGC; + volatile u8 CFGD; + + volatile u16 DCFG; /* 0x7C */ + volatile u16 MCFG; + + volatile u8 TBIST; /* 0x80 */ + volatile u8 RBIST; + volatile u8 PMCPORT; + volatile u8 STICKHW; + + volatile u8 MIBCR; /* 0x84 */ + volatile u8 reserved_85; + volatile u8 rev_id; + volatile u8 PORSTS; + + volatile u32 MIBData; /* 0x88 */ + + volatile u16 EEWrData; + + volatile u8 reserved_8E; + volatile u8 BPMDWr; + volatile u8 BPCMD; + volatile u8 BPMDRd; + + volatile u8 EECHKSUM; /* 0x92 */ + volatile u8 EECSR; + + volatile u16 EERdData; /* 0x94 */ + volatile u8 EADDR; + volatile u8 EMBCMD; + + + volatile u8 JMPSR0; /* 0x98 */ + volatile u8 JMPSR1; + volatile u8 JMPSR2; + volatile u8 JMPSR3; + volatile u8 CHIPGSR; /* 0x9C */ + volatile u8 TESTCFG; + volatile u8 DEBUG; + volatile u8 CHIPGCR; + + volatile u16 WOLCRSet; /* 0xA0 */ + volatile u8 PWCFGSet; + volatile u8 WOLCFGSet; + + volatile u16 WOLCRClr; /* 0xA4 */ + volatile u8 PWCFGCLR; + volatile u8 WOLCFGClr; + + volatile u16 WOLSRSet; /* 0xA8 */ + volatile u16 reserved_AA; + + volatile u16 WOLSRClr; /* 0xAC */ + volatile u16 reserved_AE; + + volatile u16 PatternCRC[8]; /* 0xB0 */ + volatile u32 ByteMask[4][4]; /* 0xC0 */ +} __attribute__ ((__packed__)); + + +enum hw_mib { + HW_MIB_ifRxAllPkts = 0, + HW_MIB_ifRxOkPkts, + HW_MIB_ifTxOkPkts, + HW_MIB_ifRxErrorPkts, + HW_MIB_ifRxRuntOkPkt, + HW_MIB_ifRxRuntErrPkt, + HW_MIB_ifRx64Pkts, + HW_MIB_ifTx64Pkts, + HW_MIB_ifRx65To127Pkts, + HW_MIB_ifTx65To127Pkts, + HW_MIB_ifRx128To255Pkts, + HW_MIB_ifTx128To255Pkts, + HW_MIB_ifRx256To511Pkts, + HW_MIB_ifTx256To511Pkts, + HW_MIB_ifRx512To1023Pkts, + HW_MIB_ifTx512To1023Pkts, + HW_MIB_ifRx1024To1518Pkts, + HW_MIB_ifTx1024To1518Pkts, + HW_MIB_ifTxEtherCollisions, + HW_MIB_ifRxPktCRCE, + HW_MIB_ifRxJumboPkts, + HW_MIB_ifTxJumboPkts, + HW_MIB_ifRxMacControlFrames, + HW_MIB_ifTxMacControlFrames, + HW_MIB_ifRxPktFAE, + HW_MIB_ifRxLongOkPkt, + HW_MIB_ifRxLongPktErrPkt, + HW_MIB_ifTXSQEErrors, + HW_MIB_ifRxNobuf, + HW_MIB_ifRxSymbolErrors, + HW_MIB_ifInRangeLengthErrors, + HW_MIB_ifLateCollisions, + HW_MIB_SIZE +}; + +enum chip_type { + CHIP_TYPE_VT6110 = 1, +}; + +struct velocity_info_tbl { + enum chip_type chip_id; + char *name; + int io_size; + int txqueue; + u32 flags; +}; + +#define mac_hw_mibs_init(regs) {\ + BYTE_REG_BITS_ON(MIBCR_MIBFRZ,&((regs)->MIBCR));\ + BYTE_REG_BITS_ON(MIBCR_MIBCLR,&((regs)->MIBCR));\ + do {}\ + while (BYTE_REG_BITS_IS_ON(MIBCR_MIBCLR,&((regs)->MIBCR)));\ + BYTE_REG_BITS_OFF(MIBCR_MIBFRZ,&((regs)->MIBCR));\ +} + +#define mac_read_isr(regs) readl(&((regs)->ISR)) +#define mac_write_isr(regs, x) writel((x),&((regs)->ISR)) +#define mac_clear_isr(regs) writel(0xffffffffL,&((regs)->ISR)) + +#define mac_write_int_mask(mask, regs) writel((mask),&((regs)->IMR)); +#define mac_disable_int(regs) writel(CR0_GINTMSK1,&((regs)->CR0Clr)) +#define mac_enable_int(regs) writel(CR0_GINTMSK1,&((regs)->CR0Set)) + +#define mac_hw_mibs_read(regs, MIBs) {\ + int i;\ + BYTE_REG_BITS_ON(MIBCR_MPTRINI,&((regs)->MIBCR));\ + for (i=0;iMIBData));\ + }\ +} + +#define mac_set_dma_length(regs, n) {\ + BYTE_REG_BITS_SET((n),0x07,&((regs)->DCFG));\ +} + +#define mac_set_rx_thresh(regs, n) {\ + BYTE_REG_BITS_SET((n),(MCFG_RFT0|MCFG_RFT1),&((regs)->MCFG));\ +} + +#define mac_rx_queue_run(regs) {\ + writeb(TRDCSR_RUN, &((regs)->RDCSRSet));\ +} + +#define mac_rx_queue_wake(regs) {\ + writeb(TRDCSR_WAK, &((regs)->RDCSRSet));\ +} + +#define mac_tx_queue_run(regs, n) {\ + writew(TRDCSR_RUN<<((n)*4),&((regs)->TDCSRSet));\ +} + +#define mac_tx_queue_wake(regs, n) {\ + writew(TRDCSR_WAK<<(n*4),&((regs)->TDCSRSet));\ +} + +#define mac_eeprom_reload(regs) {\ + int i=0;\ + BYTE_REG_BITS_ON(EECSR_RELOAD,&((regs)->EECSR));\ + do {\ + udelay(10);\ + if (i++>0x1000) {\ + break;\ + }\ + }while (BYTE_REG_BITS_IS_ON(EECSR_RELOAD,&((regs)->EECSR)));\ +} + +enum velocity_cam_type { + VELOCITY_VLAN_ID_CAM = 0, + VELOCITY_MULTICAST_CAM +}; + +/** + * mac_get_cam_mask - Read a CAM mask + * @regs: register block for this velocity + * @mask: buffer to store mask + * @cam_type: CAM to fetch + * + * Fetch the mask bits of the selected CAM and store them into the + * provided mask buffer. + */ + +static inline void mac_get_cam_mask(struct mac_regs * regs, u8 * mask, enum velocity_cam_type cam_type) +{ + int i; + /* Select CAM mask */ + BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); + + if (cam_type == VELOCITY_VLAN_ID_CAM) + writeb(CAMADDR_VCAMSL, ®s->CAMADDR); + else + writeb(0, ®s->CAMADDR); + + /* read mask */ + for (i = 0; i < 8; i++) + *mask++ = readb(&(regs->MARCAM[i])); + + /* disable CAMEN */ + writeb(0, ®s->CAMADDR); + + /* Select mar */ + BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); + +} + +/** + * mac_set_cam_mask - Set a CAM mask + * @regs: register block for this velocity + * @mask: CAM mask to load + * @cam_type: CAM to store + * + * Store a new mask into a CAM + */ + +static inline void mac_set_cam_mask(struct mac_regs * regs, u8 * mask, enum velocity_cam_type cam_type) +{ + int i; + /* Select CAM mask */ + BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); + + if (cam_type == VELOCITY_VLAN_ID_CAM) + writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR); + else + writeb(CAMADDR_CAMEN, ®s->CAMADDR); + + for (i = 0; i < 8; i++) { + writeb(*mask++, &(regs->MARCAM[i])); + } + /* disable CAMEN */ + writeb(0, ®s->CAMADDR); + + /* Select CAM mask */ + BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); +} + +/** + * mac_set_cam - set CAM data + * @regs: register block of this velocity + * @idx: Cam index + * @addr: 2 or 6 bytes of CAM data + * @cam_type: CAM to load + * + * Load an address or vlan tag into a CAM + */ + +static inline void mac_set_cam(struct mac_regs * regs, int idx, u8 *addr, enum velocity_cam_type cam_type) +{ + int i; + + /* Select CAM mask */ + BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); + + idx &= (64 - 1); + + if (cam_type == VELOCITY_VLAN_ID_CAM) + writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR); + else + writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR); + + if (cam_type == VELOCITY_VLAN_ID_CAM) + writew(*((u16 *) addr), ®s->MARCAM[0]); + else { + for (i = 0; i < 6; i++) { + writeb(*addr++, &(regs->MARCAM[i])); + } + } + BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR); + + udelay(10); + + writeb(0, ®s->CAMADDR); + + /* Select CAM mask */ + BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); +} + +/** + * mac_get_cam - fetch CAM data + * @regs: register block of this velocity + * @idx: Cam index + * @addr: buffer to hold up to 6 bytes of CAM data + * @cam_type: CAM to load + * + * Load an address or vlan tag from a CAM into the buffer provided by + * the caller. VLAN tags are 2 bytes the address cam entries are 6. + */ + +static inline void mac_get_cam(struct mac_regs * regs, int idx, u8 *addr, enum velocity_cam_type cam_type) +{ + int i; + + /* Select CAM mask */ + BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); + + idx &= (64 - 1); + + if (cam_type == VELOCITY_VLAN_ID_CAM) + writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR); + else + writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR); + + BYTE_REG_BITS_ON(CAMCR_CAMRD, ®s->CAMCR); + + udelay(10); + + if (cam_type == VELOCITY_VLAN_ID_CAM) + *((u16 *) addr) = readw(&(regs->MARCAM[0])); + else + for (i = 0; i < 6; i++, addr++) + *((u8 *) addr) = readb(&(regs->MARCAM[i])); + + writeb(0, ®s->CAMADDR); + + /* Select CAM mask */ + BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); +} + +/** + * mac_wol_reset - reset WOL after exiting low power + * @regs: register block of this velocity + * + * Called after we drop out of wake on lan mode in order to + * reset the Wake on lan features. This function doesn't restore + * the rest of the logic from the result of sleep/wakeup + */ + +inline static void mac_wol_reset(struct mac_regs * regs) +{ + + /* Turn off SWPTAG right after leaving power mode */ + BYTE_REG_BITS_OFF(STICKHW_SWPTAG, ®s->STICKHW); + /* clear sticky bits */ + BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW); + + BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR); + BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR); + /* disable force PME-enable */ + writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr); + /* disable power-event config bit */ + writew(0xFFFF, ®s->WOLCRClr); + /* clear power status */ + writew(0xFFFF, ®s->WOLSRClr); +} + + +/* + * Header for WOL definitions. Used to compute hashes + */ + +typedef u8 MCAM_ADDR[ETH_ALEN]; + +struct arp_packet { + u8 dest_mac[ETH_ALEN]; + u8 src_mac[ETH_ALEN]; + u16 type; + u16 ar_hrd; + u16 ar_pro; + u8 ar_hln; + u8 ar_pln; + u16 ar_op; + u8 ar_sha[ETH_ALEN]; + u8 ar_sip[4]; + u8 ar_tha[ETH_ALEN]; + u8 ar_tip[4]; +} __attribute__ ((__packed__)); + +struct _magic_packet { + u8 dest_mac[6]; + u8 src_mac[6]; + u16 type; + u8 MAC[16][6]; + u8 password[6]; +} __attribute__ ((__packed__)); + +/* + * Store for chip context when saving and restoring status. Not + * all fields are saved/restored currently. + */ + +struct velocity_context { + u8 mac_reg[256]; + MCAM_ADDR cam_addr[MCAM_SIZE]; + u16 vcam[VCAM_SIZE]; + u32 cammask[2]; + u32 patcrc[2]; + u32 pattern[8]; +}; + + +/* + * MII registers. + */ + + +/* + * Registers in the MII (offset unit is WORD) + */ + +#define MII_REG_BMCR 0x00 // physical address +#define MII_REG_BMSR 0x01 // +#define MII_REG_PHYID1 0x02 // OUI +#define MII_REG_PHYID2 0x03 // OUI + Module ID + REV ID +#define MII_REG_ANAR 0x04 // +#define MII_REG_ANLPAR 0x05 // +#define MII_REG_G1000CR 0x09 // +#define MII_REG_G1000SR 0x0A // +#define MII_REG_MODCFG 0x10 // +#define MII_REG_TCSR 0x16 // +#define MII_REG_PLED 0x1B // +// NS, MYSON only +#define MII_REG_PCR 0x17 // +// ESI only +#define MII_REG_PCSR 0x17 // +#define MII_REG_AUXCR 0x1C // + +// Marvell 88E1000/88E1000S +#define MII_REG_PSCR 0x10 // PHY specific control register + +// +// Bits in the BMCR register +// +#define BMCR_RESET 0x8000 // +#define BMCR_LBK 0x4000 // +#define BMCR_SPEED100 0x2000 // +#define BMCR_AUTO 0x1000 // +#define BMCR_PD 0x0800 // +#define BMCR_ISO 0x0400 // +#define BMCR_REAUTO 0x0200 // +#define BMCR_FDX 0x0100 // +#define BMCR_SPEED1G 0x0040 // +// +// Bits in the BMSR register +// +#define BMSR_AUTOCM 0x0020 // +#define BMSR_LNK 0x0004 // + +// +// Bits in the ANAR register +// +#define ANAR_ASMDIR 0x0800 // Asymmetric PAUSE support +#define ANAR_PAUSE 0x0400 // Symmetric PAUSE Support +#define ANAR_T4 0x0200 // +#define ANAR_TXFD 0x0100 // +#define ANAR_TX 0x0080 // +#define ANAR_10FD 0x0040 // +#define ANAR_10 0x0020 // +// +// Bits in the ANLPAR register +// +#define ANLPAR_ASMDIR 0x0800 // Asymmetric PAUSE support +#define ANLPAR_PAUSE 0x0400 // Symmetric PAUSE Support +#define ANLPAR_T4 0x0200 // +#define ANLPAR_TXFD 0x0100 // +#define ANLPAR_TX 0x0080 // +#define ANLPAR_10FD 0x0040 // +#define ANLPAR_10 0x0020 // + +// +// Bits in the G1000CR register +// +#define G1000CR_1000FD 0x0200 // PHY is 1000-T Full-duplex capable +#define G1000CR_1000 0x0100 // PHY is 1000-T Half-duplex capable + +// +// Bits in the G1000SR register +// +#define G1000SR_1000FD 0x0800 // LP PHY is 1000-T Full-duplex capable +#define G1000SR_1000 0x0400 // LP PHY is 1000-T Half-duplex capable + +#define TCSR_ECHODIS 0x2000 // +#define AUXCR_MDPPS 0x0004 // + +// Bits in the PLED register +#define PLED_LALBE 0x0004 // + +// Marvell 88E1000/88E1000S Bits in the PHY specific control register (10h) +#define PSCR_ACRSTX 0x0800 // Assert CRS on Transmit + +#define PHYID_CICADA_CS8201 0x000FC410UL +#define PHYID_VT3216_32BIT 0x000FC610UL +#define PHYID_VT3216_64BIT 0x000FC600UL +#define PHYID_MARVELL_1000 0x01410C50UL +#define PHYID_MARVELL_1000S 0x01410C40UL + +#define PHYID_REV_ID_MASK 0x0000000FUL + +#define PHYID_GET_PHY_REV_ID(i) ((i) & PHYID_REV_ID_MASK) +#define PHYID_GET_PHY_ID(i) ((i) & ~PHYID_REV_ID_MASK) + +#define MII_REG_BITS_ON(x,i,p) do {\ + u16 w;\ + velocity_mii_read((p),(i),&(w));\ + (w)|=(x);\ + velocity_mii_write((p),(i),(w));\ +} while (0) + +#define MII_REG_BITS_OFF(x,i,p) do {\ + u16 w;\ + velocity_mii_read((p),(i),&(w));\ + (w)&=(~(x));\ + velocity_mii_write((p),(i),(w));\ +} while (0) + +#define MII_REG_BITS_IS_ON(x,i,p) ({\ + u16 w;\ + velocity_mii_read((p),(i),&(w));\ + ((int) ((w) & (x)));}) + +#define MII_GET_PHY_ID(p) ({\ + u32 id;\ + velocity_mii_read((p),MII_REG_PHYID2,(u16 *) &id);\ + velocity_mii_read((p),MII_REG_PHYID1,((u16 *) &id)+1);\ + (id);}) + +/* + * Inline debug routine + */ + + +enum velocity_msg_level { + MSG_LEVEL_ERR = 0, //Errors that will cause abnormal operation. + MSG_LEVEL_NOTICE = 1, //Some errors need users to be notified. + MSG_LEVEL_INFO = 2, //Normal message. + MSG_LEVEL_VERBOSE = 3, //Will report all trival errors. + MSG_LEVEL_DEBUG = 4 //Only for debug purpose. +}; + +#ifdef VELOCITY_DEBUG +#define ASSERT(x) { \ + if (!(x)) { \ + printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\ + __FUNCTION__, __LINE__);\ + BUG(); \ + }\ +} +#define VELOCITY_DBG(p,args...) printk(p, ##args) +#else +#define ASSERT(x) +#define VELOCITY_DBG(x) +#endif + +#define VELOCITY_PRT(l, p, args...) do {if (l<=msglevel) printk( p ,##args);} while (0) + +#define VELOCITY_PRT_CAMMASK(p,t) {\ + int i;\ + if ((t)==VELOCITY_MULTICAST_CAM) {\ + for (i=0;i<(MCAM_SIZE/8);i++)\ + printk("%02X",(p)->mCAMmask[i]);\ + }\ + else {\ + for (i=0;i<(VCAM_SIZE/8);i++)\ + printk("%02X",(p)->vCAMmask[i]);\ + }\ + printk("\n");\ +} + + + +#define VELOCITY_WOL_MAGIC 0x00000000UL +#define VELOCITY_WOL_PHY 0x00000001UL +#define VELOCITY_WOL_ARP 0x00000002UL +#define VELOCITY_WOL_UCAST 0x00000004UL +#define VELOCITY_WOL_BCAST 0x00000010UL +#define VELOCITY_WOL_MCAST 0x00000020UL +#define VELOCITY_WOL_MAGIC_SEC 0x00000040UL + +/* + * Flags for options + */ + +#define VELOCITY_FLAGS_TAGGING 0x00000001UL +#define VELOCITY_FLAGS_TX_CSUM 0x00000002UL +#define VELOCITY_FLAGS_RX_CSUM 0x00000004UL +#define VELOCITY_FLAGS_IP_ALIGN 0x00000008UL +#define VELOCITY_FLAGS_VAL_PKT_LEN 0x00000010UL + +#define VELOCITY_FLAGS_FLOW_CTRL 0x01000000UL + +/* + * Flags for driver status + */ + +#define VELOCITY_FLAGS_OPENED 0x00010000UL +#define VELOCITY_FLAGS_VMNS_CONNECTED 0x00020000UL +#define VELOCITY_FLAGS_VMNS_COMMITTED 0x00040000UL +#define VELOCITY_FLAGS_WOL_ENABLED 0x00080000UL + +/* + * Flags for MII status + */ + +#define VELOCITY_LINK_FAIL 0x00000001UL +#define VELOCITY_SPEED_10 0x00000002UL +#define VELOCITY_SPEED_100 0x00000004UL +#define VELOCITY_SPEED_1000 0x00000008UL +#define VELOCITY_DUPLEX_FULL 0x00000010UL +#define VELOCITY_AUTONEG_ENABLE 0x00000020UL +#define VELOCITY_FORCED_BY_EEPROM 0x00000040UL + +/* + * For velocity_set_media_duplex + */ + +#define VELOCITY_LINK_CHANGE 0x00000001UL + +enum speed_opt { + SPD_DPX_AUTO = 0, + SPD_DPX_100_HALF = 1, + SPD_DPX_100_FULL = 2, + SPD_DPX_10_HALF = 3, + SPD_DPX_10_FULL = 4 +}; + +enum velocity_init_type { + VELOCITY_INIT_COLD = 0, + VELOCITY_INIT_RESET, + VELOCITY_INIT_WOL +}; + +enum velocity_flow_cntl_type { + FLOW_CNTL_DEFAULT = 1, + FLOW_CNTL_TX, + FLOW_CNTL_RX, + FLOW_CNTL_TX_RX, + FLOW_CNTL_DISABLE, +}; + +struct velocity_opt { + int numrx; /* Number of RX descriptors */ + int numtx; /* Number of TX descriptors */ + enum speed_opt spd_dpx; /* Media link mode */ + int vid; /* vlan id */ + int DMA_length; /* DMA length */ + int rx_thresh; /* RX_THRESH */ + int flow_cntl; + int wol_opts; /* Wake on lan options */ + int td_int_count; + int int_works; + int rx_bandwidth_hi; + int rx_bandwidth_lo; + int rx_bandwidth_en; + u32 flags; +}; + +struct velocity_info { + struct velocity_info *next; + struct velocity_info *prev; + + struct pci_dev *pdev; + struct net_device *dev; + struct net_device_stats stats; + +#if CONFIG_PM + u32 pci_state[16]; +#endif + + dma_addr_t rd_pool_dma; + dma_addr_t td_pool_dma[TX_QUEUE_NO]; + + dma_addr_t tx_bufs_dma; + u8 *tx_bufs; + + u8 ip_addr[4]; + enum chip_type chip_id; + + struct mac_regs * mac_regs; + unsigned long memaddr; + unsigned long ioaddr; + u32 io_size; + + u8 rev_id; + +#define AVAIL_TD(p,q) ((p)->options.numtx-((p)->td_used[(q)])) + + int num_txq; + + volatile int td_used[TX_QUEUE_NO]; + int td_curr[TX_QUEUE_NO]; + int td_tail[TX_QUEUE_NO]; + struct tx_desc *td_rings[TX_QUEUE_NO]; + struct velocity_td_info *td_infos[TX_QUEUE_NO]; + + int rd_curr; + int rd_used; + struct rx_desc *rd_ring; + struct velocity_rd_info *rd_info; /* It's an array */ + +#define GET_RD_BY_IDX(vptr, idx) (vptr->rd_ring[idx]) + u32 mib_counter[MAX_HW_MIB_COUNTER]; + struct velocity_opt options; + + u32 int_mask; + + u32 flags; + + int rx_buf_sz; + u32 mii_status; + u32 phy_id; + int multicast_limit; + + u8 vCAMmask[(VCAM_SIZE / 8)]; + u8 mCAMmask[(MCAM_SIZE / 8)]; + + spinlock_t lock; + spinlock_t xmit_lock; + + int wol_opts; + u8 wol_passwd[6]; + + struct velocity_context context; + + u32 ticks; + u32 rx_bytes; + +}; + +/** + * velocity_get_ip - find an IP address for the device + * @vptr: Velocity to query + * + * Dig out an IP address for this interface so that we can + * configure wakeup with WOL for ARP. If there are multiple IP + * addresses on this chain then we use the first - multi-IP WOL is not + * supported. + * + * CHECK ME: locking + */ + +inline static int velocity_get_ip(struct velocity_info *vptr) +{ + struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr; + struct in_ifaddr *ifa; + + if (in_dev != NULL) { + ifa = (struct in_ifaddr *) in_dev->ifa_list; + if (ifa != NULL) { + memcpy(vptr->ip_addr, &ifa->ifa_address, 4); + return 0; + } + } + return -ENOENT; +} + +/** + * velocity_update_hw_mibs - fetch MIB counters from chip + * @vptr: velocity to update + * + * The velocity hardware keeps certain counters in the hardware + * side. We need to read these when the user asks for statistics + * or when they overflow (causing an interrupt). The read of the + * statistic clears it, so we keep running master counters in user + * space. + */ + +static inline void velocity_update_hw_mibs(struct velocity_info *vptr) +{ + u32 tmp; + int i; + BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)); + + while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR))); + + BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR)); + for (i = 0; i < HW_MIB_SIZE; i++) { + tmp = readl(&(vptr->mac_regs->MIBData)) & 0x00FFFFFFUL; + vptr->mib_counter[i] += tmp; + } +} + +/** + * init_flow_control_register - set up flow control + * @vptr: velocity to configure + * + * Configure the flow control registers for this velocity device. + */ + +static inline void init_flow_control_register(struct velocity_info *vptr) +{ + struct mac_regs * regs = vptr->mac_regs; + + /* Set {XHITH1, XHITH0, XLTH1, XLTH0} in FlowCR1 to {1, 0, 1, 1} + depend on RD=64, and Turn on XNOEN in FlowCR1 */ + writel((CR0_XONEN | CR0_XHITH1 | CR0_XLTH1 | CR0_XLTH0), ®s->CR0Set); + writel((CR0_FDXTFCEN | CR0_FDXRFCEN | CR0_HDXFCEN | CR0_XHITH0), ®s->CR0Clr); + + /* Set TxPauseTimer to 0xFFFF */ + writew(0xFFFF, ®s->tx_pause_timer); + + /* Initialize RBRDU to Rx buffer count. */ + writew(vptr->options.numrx, ®s->RBRDU); +} + + +#endif diff -Nru a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig --- a/drivers/net/wan/Kconfig 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/wan/Kconfig 2004-06-26 17:09:16 -07:00 @@ -248,7 +248,7 @@ config WANXL_BUILD_FIRMWARE bool "rebuild wanXL firmware" - depends on WANXL + depends on WANXL && !PREVENT_FIRMWARE_BUILD help Allows you to rebuild firmware run by the QUICC processor. It requires as68k, ld68k and hexdump programs. diff -Nru a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c --- a/drivers/net/wan/c101.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/wan/c101.c 2004-06-26 17:09:19 -07:00 @@ -220,7 +220,8 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync; + sync_serial_settings new_line; + sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; port_t *port = dev_to_port(dev); #ifdef DEBUG_RINGS diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c --- a/drivers/net/wan/cosa.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/wan/cosa.c 2004-06-26 17:09:15 -07:00 @@ -301,9 +301,9 @@ static int chrdev_rx_done(struct channel_data *channel); static int chrdev_tx_done(struct channel_data *channel, int size); static ssize_t cosa_read(struct file *file, - char *buf, size_t count, loff_t *ppos); + char __user *buf, size_t count, loff_t *ppos); static ssize_t cosa_write(struct file *file, - const char *buf, size_t count, loff_t *ppos); + const char __user *buf, size_t count, loff_t *ppos); static unsigned int cosa_poll(struct file *file, poll_table *poll); static int cosa_open(struct inode *inode, struct file *file); static int cosa_release(struct inode *inode, struct file *file); @@ -330,13 +330,13 @@ /* Ioctls */ static int cosa_start(struct cosa_data *cosa, int address); static int cosa_reset(struct cosa_data *cosa); -static int cosa_download(struct cosa_data *cosa, unsigned long a); -static int cosa_readmem(struct cosa_data *cosa, unsigned long a); +static int cosa_download(struct cosa_data *cosa, void __user *a); +static int cosa_readmem(struct cosa_data *cosa, void __user *a); /* COSA/SRP ROM monitor */ -static int download(struct cosa_data *cosa, const char *data, int addr, int len); +static int download(struct cosa_data *cosa, const char __user *data, int addr, int len); static int startmicrocode(struct cosa_data *cosa, int address); -static int readmem(struct cosa_data *cosa, char *data, int addr, int len); +static int readmem(struct cosa_data *cosa, char __user *data, int addr, int len); static int cosa_reset_and_read_id(struct cosa_data *cosa, char *id); /* Auxilliary functions */ @@ -830,7 +830,7 @@ } static ssize_t cosa_read(struct file *file, - char *buf, size_t count, loff_t *ppos) + char __user *buf, size_t count, loff_t *ppos) { DECLARE_WAITQUEUE(wait, current); unsigned long flags; @@ -905,7 +905,7 @@ static ssize_t cosa_write(struct file *file, - const char *buf, size_t count, loff_t *ppos) + const char __user *buf, size_t count, loff_t *ppos) { DECLARE_WAITQUEUE(wait, current); struct channel_data *chan = file->private_data; @@ -1066,7 +1066,7 @@ } /* High-level function to download data into COSA memory. Calls download() */ -static inline int cosa_download(struct cosa_data *cosa, unsigned long arg) +static inline int cosa_download(struct cosa_data *cosa, void __user *arg) { struct cosa_download d; int i; @@ -1080,7 +1080,7 @@ return -EPERM; } - if (copy_from_user(&d, (void __user *) arg, sizeof(d))) + if (copy_from_user(&d, arg, sizeof(d))) return -EFAULT; if (d.addr < 0 || d.addr > COSA_MAX_FIRMWARE_SIZE) @@ -1105,7 +1105,7 @@ } /* High-level function to read COSA memory. Calls readmem() */ -static inline int cosa_readmem(struct cosa_data *cosa, unsigned long arg) +static inline int cosa_readmem(struct cosa_data *cosa, void __user *arg) { struct cosa_download d; int i; @@ -1120,7 +1120,7 @@ return -EPERM; } - if (copy_from_user(&d, (void __user *) arg, sizeof(d))) + if (copy_from_user(&d, arg, sizeof(d))) return -EFAULT; /* If something fails, force the user to reset the card */ @@ -1167,7 +1167,7 @@ } /* Buffer of size at least COSA_MAX_ID_STRING is expected */ -static inline int cosa_getidstr(struct cosa_data *cosa, char *string) +static inline int cosa_getidstr(struct cosa_data *cosa, char __user *string) { int l = strlen(cosa->id_string)+1; if (copy_to_user(string, cosa->id_string, l)) @@ -1176,7 +1176,7 @@ } /* Buffer of size at least COSA_MAX_ID_STRING is expected */ -static inline int cosa_gettype(struct cosa_data *cosa, char *string) +static inline int cosa_gettype(struct cosa_data *cosa, char __user *string) { int l = strlen(cosa->type)+1; if (copy_to_user(string, cosa->type, l)) @@ -1187,6 +1187,7 @@ static int cosa_ioctl_common(struct cosa_data *cosa, struct channel_data *channel, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; switch(cmd) { case COSAIORSET: /* Reset the device */ if (!capable(CAP_NET_ADMIN)) @@ -1200,15 +1201,15 @@ if (!capable(CAP_SYS_RAWIO)) return -EACCES; - return cosa_download(cosa, arg); + return cosa_download(cosa, argp); case COSAIORMEM: if (!capable(CAP_SYS_RAWIO)) return -EACCES; - return cosa_readmem(cosa, arg); + return cosa_readmem(cosa, argp); case COSAIORTYPE: - return cosa_gettype(cosa, (char *)arg); + return cosa_gettype(cosa, argp); case COSAIORIDSTR: - return cosa_getidstr(cosa, (char *)arg); + return cosa_getidstr(cosa, argp); case COSAIONRCARDS: return nr_cards; case COSAIONRCHANS: @@ -1434,7 +1435,7 @@ * by a single space. Monitor has to reply with a space. Now the download * begins. After the download monitor replies with "\r\n." (CR LF dot). */ -static int download(struct cosa_data *cosa, const char *microcode, int length, int address) +static int download(struct cosa_data *cosa, const char __user *microcode, int length, int address) { int i; @@ -1508,7 +1509,7 @@ * This routine is not needed during the normal operation and serves * for debugging purposes only. */ -static int readmem(struct cosa_data *cosa, char *microcode, int length, int address) +static int readmem(struct cosa_data *cosa, char __user *microcode, int length, int address) { if (put_wait_data(cosa, 'r') == -1) return -1; if ((get_wait_data(cosa)) != 'r') return -2; diff -Nru a/drivers/net/wan/cosa.h b/drivers/net/wan/cosa.h --- a/drivers/net/wan/cosa.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/wan/cosa.h 2004-06-26 17:09:18 -07:00 @@ -66,7 +66,7 @@ /* ioctls */ struct cosa_download { int addr, len; - char *code; + char __user *code; }; /* Reset the device */ diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c --- a/drivers/net/wan/dscc4.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/wan/dscc4.c 2004-06-26 17:09:21 -07:00 @@ -1296,7 +1296,7 @@ static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync; + sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; struct dscc4_dev_priv *dpriv = dscc4_priv(dev); const size_t size = sizeof(dpriv->settings); int ret = 0; diff -Nru a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c --- a/drivers/net/wan/farsync.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/wan/farsync.c 2004-06-26 17:09:19 -07:00 @@ -1636,7 +1636,7 @@ */ dbg(DBG_TX, "Tx underflow port %d\n", port->index); hdlc_stats(port_to_dev(port))->tx_errors++; - hdlc_stats(port_to_dev(port))->tx_fifo_errors; + hdlc_stats(port_to_dev(port))->tx_fifo_errors++; dbg(DBG_ASS, "Tx underflow on card %d port %d\n", card->card_no, port->index); break; diff -Nru a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c --- a/drivers/net/wan/hdlc_cisco.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/wan/hdlc_cisco.c 2004-06-26 17:09:17 -07:00 @@ -272,7 +272,7 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) { - cisco_proto *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; + cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; const size_t size = sizeof(cisco_proto); cisco_proto new_settings; hdlc_device *hdlc = dev_to_hdlc(dev); diff -Nru a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c --- a/drivers/net/wan/hdlc_fr.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/wan/hdlc_fr.c 2004-06-26 17:09:20 -07:00 @@ -1137,7 +1137,7 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) { - fr_proto *fr_s = ifr->ifr_settings.ifs_ifsu.fr; + fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; const size_t size = sizeof(fr_proto); fr_proto new_settings; hdlc_device *hdlc = dev_to_hdlc(dev); diff -Nru a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c --- a/drivers/net/wan/hdlc_raw.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/wan/hdlc_raw.c 2004-06-26 17:09:18 -07:00 @@ -34,7 +34,7 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) { - raw_hdlc_proto *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; + raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; const size_t size = sizeof(raw_hdlc_proto); raw_hdlc_proto new_settings; hdlc_device *hdlc = dev_to_hdlc(dev); diff -Nru a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c --- a/drivers/net/wan/hdlc_raw_eth.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/wan/hdlc_raw_eth.c 2004-06-26 17:09:18 -07:00 @@ -46,7 +46,7 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) { - raw_hdlc_proto *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; + raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; const size_t size = sizeof(raw_hdlc_proto); raw_hdlc_proto new_settings; hdlc_device *hdlc = dev_to_hdlc(dev); diff -Nru a/drivers/net/wan/lmc/lmc_ioctl.h b/drivers/net/wan/lmc/lmc_ioctl.h --- a/drivers/net/wan/lmc/lmc_ioctl.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/wan/lmc/lmc_ioctl.h 2004-06-26 17:09:15 -07:00 @@ -234,7 +234,7 @@ int command; int address; int value; - char *data; + char __user *data; } lmc_t1f_control; enum lmc_xilinx_c { @@ -246,7 +246,7 @@ struct lmc_xilinx_control { enum lmc_xilinx_c command; int len; - char *data; + char __user *data; }; /* ------------------ end T1 defs ------------------- */ diff -Nru a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c --- a/drivers/net/wan/n2.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/wan/n2.c 2004-06-26 17:09:16 -07:00 @@ -254,7 +254,8 @@ static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync; + sync_serial_settings new_line; + sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; port_t *port = dev_to_port(dev); #ifdef DEBUG_RINGS diff -Nru a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c --- a/drivers/net/wan/pci200syn.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/wan/pci200syn.c 2004-06-26 17:09:16 -07:00 @@ -204,7 +204,8 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync; + sync_serial_settings new_line; + sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; port_t *port = dev_to_port(dev); #ifdef DEBUG_RINGS diff -Nru a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c --- a/drivers/net/wan/x25_asy.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/wan/x25_asy.c 2004-06-26 17:09:16 -07:00 @@ -733,7 +733,7 @@ switch(cmd) { case SIOCGIFNAME: - if (copy_to_user((void *)arg, sl->dev->name, + if (copy_to_user((void __user *)arg, sl->dev->name, strlen(sl->dev->name) + 1)) return -EFAULT; return 0; diff -Nru a/drivers/net/wd.c b/drivers/net/wd.c --- a/drivers/net/wd.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/wd.c 2004-06-26 17:09:15 -07:00 @@ -43,6 +43,8 @@ #include "8390.h" +#define DRV_NAME "wd" + /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int wd_portlist[] __initdata = {0x300, 0x280, 0x380, 0x240, 0}; @@ -131,6 +133,7 @@ release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT); } +#ifndef MODULE struct net_device * __init wd_probe(int unit) { struct net_device *dev = alloc_ei_netdev(); @@ -155,6 +158,7 @@ free_netdev(dev); return ERR_PTR(err); } +#endif static int __init wd_probe1(struct net_device *dev, int ioaddr) { @@ -300,7 +304,7 @@ /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ - i = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); + i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); if (i) { printk (" unable to get IRQ %d.\n", dev->irq); return i; diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/wireless/airo.c 2004-06-26 17:09:15 -07:00 @@ -1209,6 +1209,7 @@ SsidRid *SSID; APListRid *APList; #define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE + u32 pci_state[16]; }; static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, @@ -1963,7 +1964,7 @@ if ((skb = skb_dequeue(&ai->txq)) == 0) { printk (KERN_ERR - "airo_mpi: %s: Dequeue'd zero in send_packet()\n", + "airo: %s: Dequeue'd zero in send_packet()\n", __FUNCTION__); return 0; } @@ -2745,6 +2746,9 @@ SET_NETDEV_DEV(dev, &pci->dev); } + if (test_bit(FLAG_MPI,&ai->flags)) + reset_card (dev, 1); + rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev ); if (rc) { printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc ); @@ -4047,7 +4051,8 @@ Resp rsp; if (test_bit(FLAG_ENABLED, &ai->flags)) - printk(KERN_ERR "%s: MAC should be disabled (rid=%d)\n", + printk(KERN_ERR + "%s: MAC should be disabled (rid=%04x)\n", __FUNCTION__, rid); memset(&cmd, 0, sizeof(cmd)); memset(&rsp, 0, sizeof(rsp)); @@ -4500,6 +4505,8 @@ len = priv->readlen - pos; if (copy_to_user(buffer, priv->rbuffer + pos, len)) return -EFAULT; + if (pos + len > priv->writelen) + priv->writelen = pos + len; *offset = pos + len; return len; } @@ -4527,6 +4534,8 @@ len = priv->maxwritelen - pos; if (copy_from_user(priv->wbuffer + pos, buffer, len)) return -EFAULT; + if ( pos + len > priv->writelen ) + priv->writelen = len + file->f_pos; *offset = pos + len; return len; } @@ -5470,9 +5479,6 @@ Cmd cmd; Resp rsp; - printk(KERN_DEBUG "%s: airo_mpi entering sleep mode (state=%d)\n", - dev->name, state); - if ((ai->APList == NULL) && (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL) return -ENOMEM; @@ -5490,7 +5496,10 @@ ai->power = state; cmd.cmd=HOSTSLEEP; issuecommand(ai, &cmd, &rsp); - return 0; + + pci_enable_wake(pdev, state, 1); + pci_save_state(pdev, ai->pci_state); + return pci_set_power_state(pdev, state); } static int airo_pci_resume(struct pci_dev *pdev) @@ -5499,12 +5508,12 @@ struct airo_info *ai = dev->priv; Resp rsp; - printk(KERN_DEBUG "%s: airo_mpi waking up\n", dev->name); - - if (!ai->power) - return 0; + pci_set_power_state(pdev, 0); + pci_restore_state(pdev, ai->pci_state); + pci_enable_wake(pdev, ai->power, 0); if (ai->power > 1) { + reset_card(dev, 0); mpi_init_descriptors(ai); setup_card(ai, dev->dev_addr, 0); clear_bit(FLAG_RADIO_OFF, &ai->flags); @@ -7166,6 +7175,7 @@ unsigned char *iobuf; int len; struct airo_info *ai = dev->priv; + Resp rsp; if (test_bit(FLAG_FLASHING, &ai->flags)) return -EIO; @@ -7173,8 +7183,11 @@ switch(comp->command) { case AIROGCAP: ridcode = RID_CAPABILITIES; break; - case AIROGCFG: writeConfigRid (ai, 1); - ridcode = RID_CONFIG; break; + case AIROGCFG: ridcode = RID_CONFIG; + disable_MAC (ai, 1); + writeConfigRid (ai, 1); + enable_MAC (ai, &rsp, 1); + break; case AIROGSLIST: ridcode = RID_SSID; break; case AIROGVLIST: ridcode = RID_APLIST; break; case AIROGDRVNAM: ridcode = RID_DRVNAME; break; @@ -7562,6 +7575,11 @@ set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (HZ); /* Added 12/7/00 */ clear_bit (FLAG_FLASHING, &ai->flags); + if (test_bit(FLAG_MPI, &ai->flags)) { + status = mpi_init_descriptors(ai); + if (status != SUCCESS) + return status; + } status = setup_card(ai, dev->dev_addr, 1); if (!test_bit(FLAG_MPI,&ai->flags)) diff -Nru a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c --- a/drivers/net/wireless/arlan-proc.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/wireless/arlan-proc.c 2004-06-26 17:09:18 -07:00 @@ -399,7 +399,7 @@ static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0"; static int arlan_sysctl_info(ctl_table * ctl, int write, struct file *filp, - void *buffer, size_t * lenp) + void __user *buffer, size_t * lenp) { int i; int retv, pos, devnum; @@ -636,7 +636,7 @@ static int arlan_sysctl_info161719(ctl_table * ctl, int write, struct file *filp, - void *buffer, size_t * lenp) + void __user *buffer, size_t * lenp) { int i; int retv, pos, devnum; @@ -670,7 +670,7 @@ } static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, struct file *filp, - void *buffer, size_t * lenp) + void __user *buffer, size_t * lenp) { int i; int retv, pos, devnum; @@ -699,7 +699,7 @@ } static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, struct file *filp, - void *buffer, size_t * lenp) + void __user *buffer, size_t * lenp) { int i; int retv, pos, devnum; @@ -727,7 +727,7 @@ } static int arlan_sysctl_info18(ctl_table * ctl, int write, struct file *filp, - void *buffer, size_t * lenp) + void __user *buffer, size_t * lenp) { int i; int retv, pos, devnum; @@ -763,7 +763,7 @@ static char conf_reset_result[200]; static int arlan_configure(ctl_table * ctl, int write, struct file *filp, - void *buffer, size_t * lenp) + void __user *buffer, size_t * lenp) { int pos = 0; int devnum = ctl->procname[6] - '0'; @@ -788,7 +788,7 @@ } static int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp, - void *buffer, size_t * lenp) + void __user *buffer, size_t * lenp) { int pos = 0; int devnum = ctl->procname[5] - '0'; diff -Nru a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c --- a/drivers/net/wireless/atmel.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/wireless/atmel.c 2004-06-26 17:09:16 -07:00 @@ -2360,7 +2360,7 @@ typedef struct atmel_priv_ioctl { char id[32]; - unsigned char *data; + unsigned char __user *data; unsigned short len; } atmel_priv_ioctl; diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c --- a/drivers/net/wireless/orinoco.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/wireless/orinoco.c 2004-06-26 17:09:21 -07:00 @@ -1519,7 +1519,8 @@ static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) { - printk(KERN_WARNING "%s: Information frame lost.\n", dev->name); + if (net_ratelimit()) + printk(KERN_WARNING "%s: Information frame lost.\n", dev->name); } static void print_linkstatus(struct net_device *dev, u16 status) diff -Nru a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c --- a/drivers/net/wireless/orinoco_pci.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/wireless/orinoco_pci.c 2004-06-26 17:09:19 -07:00 @@ -384,7 +384,7 @@ return pci_module_init(&orinoco_pci_driver); } -extern void __exit orinoco_pci_exit(void) +void __exit orinoco_pci_exit(void) { pci_unregister_driver(&orinoco_pci_driver); } diff -Nru a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c --- a/drivers/net/wireless/orinoco_plx.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/wireless/orinoco_plx.c 2004-06-26 17:09:21 -07:00 @@ -341,7 +341,7 @@ return pci_module_init(&orinoco_plx_driver); } -extern void __exit orinoco_plx_exit(void) +void __exit orinoco_plx_exit(void) { pci_unregister_driver(&orinoco_plx_driver); current->state = TASK_UNINTERRUPTIBLE; diff -Nru a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c --- a/drivers/net/wireless/orinoco_tmd.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/wireless/orinoco_tmd.c 2004-06-26 17:09:16 -07:00 @@ -219,7 +219,7 @@ return pci_module_init(&orinoco_tmd_driver); } -extern void __exit orinoco_tmd_exit(void) +void __exit orinoco_tmd_exit(void) { pci_unregister_driver(&orinoco_tmd_driver); current->state = TASK_UNINTERRUPTIBLE; diff -Nru a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c --- a/drivers/net/wireless/prism54/isl_38xx.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/wireless/prism54/isl_38xx.c 2004-06-26 17:09:18 -07:00 @@ -25,17 +25,11 @@ #include #include -#include "isl_38xx.h" -#include - #include #include -#include -#if !defined(CONFIG_FW_LOADER) && !defined(CONFIG_FW_LOADER_MODULE) -#error No Firmware Loading configured in the kernel ! -#endif - +#include "prismcompat.h" +#include "isl_38xx.h" #include "islpci_dev.h" #include "islpci_mgt.h" @@ -233,130 +227,6 @@ ISL38XX_INT_IDENT_SLEEP | ISL38XX_INT_IDENT_WAKEUP); isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG); udelay(ISL38XX_WRITEIO_DELAY); -} - -int -isl38xx_upload_firmware(char *fw_id, _REQ_FW_DEV_T dev, void *device_base, - dma_addr_t host_address) -{ - u32 reg, rc; - -#if VERBOSE > SHOW_ERROR_MESSAGES - DEBUG(SHOW_ERROR_MESSAGES, "isl38xx_upload_firmware(0x%lx, 0x%lx)\n", - (long) device_base, (long) host_address); -#endif - - /* clear the RAMBoot and the Reset bit */ - reg = readl(device_base + ISL38XX_CTRL_STAT_REG); - reg &= ~ISL38XX_CTRL_STAT_RESET; - reg &= ~ISL38XX_CTRL_STAT_RAMBOOT; - writel(reg, device_base + ISL38XX_CTRL_STAT_REG); - wmb(); - udelay(ISL38XX_WRITEIO_DELAY); - - /* set the Reset bit without reading the register ! */ - reg |= ISL38XX_CTRL_STAT_RESET; - writel(reg, device_base + ISL38XX_CTRL_STAT_REG); - wmb(); - udelay(ISL38XX_WRITEIO_DELAY); - - /* clear the Reset bit */ - reg &= ~ISL38XX_CTRL_STAT_RESET; - writel(reg, device_base + ISL38XX_CTRL_STAT_REG); - wmb(); - - /* wait a while for the device to reboot */ - mdelay(50); - - { - const struct firmware *fw_entry = 0; - long fw_len; - const u32 *fw_ptr; - - rc = request_firmware(&fw_entry, fw_id, dev); - if (rc) { - printk(KERN_ERR - "%s: request_firmware() failed for '%s'\n", - "prism54", fw_id); - return rc; - } - /* prepare the Direct Memory Base register */ - reg = ISL38XX_DEV_FIRMWARE_ADDRES; - - fw_ptr = (u32 *) fw_entry->data; - fw_len = fw_entry->size; - - if (fw_len % 4) { - printk(KERN_ERR - "%s: firmware '%s' size is not multiple of 32bit, aborting!\n", - "prism54", fw_id); - release_firmware(fw_entry); - return EILSEQ; /* Illegal byte sequence */; - } - - while (fw_len > 0) { - long _fw_len = - (fw_len > - ISL38XX_MEMORY_WINDOW_SIZE) ? - ISL38XX_MEMORY_WINDOW_SIZE : fw_len; - u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN; - - /* set the cards base address for writting the data */ - isl38xx_w32_flush(device_base, reg, - ISL38XX_DIR_MEM_BASE_REG); - wmb(); /* be paranoid */ - - /* increment the write address for next iteration */ - reg += _fw_len; - fw_len -= _fw_len; - - /* write the data to the Direct Memory Window 32bit-wise */ - /* memcpy_toio() doesn't guarantee 32bit writes :-| */ - while (_fw_len > 0) { - /* use non-swapping writel() */ - __raw_writel(*fw_ptr, dev_fw_ptr); - fw_ptr++, dev_fw_ptr++; - _fw_len -= 4; - } - - /* flush PCI posting */ - (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH); - wmb(); /* be paranoid again */ - - BUG_ON(_fw_len != 0); - } - - BUG_ON(fw_len != 0); - - release_firmware(fw_entry); - } - - /* now reset the device - * clear the Reset & ClkRun bit, set the RAMBoot bit */ - reg = readl(device_base + ISL38XX_CTRL_STAT_REG); - reg &= ~ISL38XX_CTRL_STAT_CLKRUN; - reg &= ~ISL38XX_CTRL_STAT_RESET; - reg |= ISL38XX_CTRL_STAT_RAMBOOT; - isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG); - wmb(); - udelay(ISL38XX_WRITEIO_DELAY); - - /* set the reset bit latches the host override and RAMBoot bits - * into the device for operation when the reset bit is reset */ - reg |= ISL38XX_CTRL_STAT_RESET; - writel(reg, device_base + ISL38XX_CTRL_STAT_REG); - /* don't do flush PCI posting here! */ - wmb(); - udelay(ISL38XX_WRITEIO_DELAY); - - /* clear the reset bit should start the whole circus */ - reg &= ~ISL38XX_CTRL_STAT_RESET; - writel(reg, device_base + ISL38XX_CTRL_STAT_REG); - /* don't do flush PCI posting here! */ - wmb(); - udelay(ISL38XX_WRITEIO_DELAY); - - return 0; } int diff -Nru a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h --- a/drivers/net/wireless/prism54/isl_38xx.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/net/wireless/prism54/isl_38xx.h 2004-06-26 17:09:21 -07:00 @@ -22,14 +22,6 @@ #include #include - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75)) -#include -# define _REQ_FW_DEV_T struct device * -#else -# define _REQ_FW_DEV_T char * -#endif - #include #define ISL38XX_CB_RX_QSIZE 8 @@ -173,7 +165,5 @@ void isl38xx_handle_wakeup(isl38xx_control_block *, int *, void *); void isl38xx_trigger_device(int, void *); void isl38xx_interface_reset(void *, dma_addr_t); - -int isl38xx_upload_firmware(char *, _REQ_FW_DEV_T, void *, dma_addr_t); #endif /* _ISL_38XX_H */ diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c --- a/drivers/net/wireless/prism54/isl_ioctl.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/wireless/prism54/isl_ioctl.c 2004-06-26 17:09:17 -07:00 @@ -25,10 +25,10 @@ #include #include #include -#include #include +#include "prismcompat.h" #include "isl_ioctl.h" #include "islpci_mgt.h" #include "isl_oid.h" /* additional types and defs for isl38xx fw */ @@ -166,21 +166,13 @@ * for it save old values */ if (init_mode > IW_MODE_MONITOR || init_mode < IW_MODE_AUTO) { printk(KERN_DEBUG "%s(): You passed a non-valid init_mode. " - "Using default mode\n", __FUNCTION__); + "Using default mode\n", __FUNCTION__); init_mode = CARD_DEFAULT_IW_MODE; } /* This sets all of the mode-dependent values */ prism54_mib_mode_helper(priv, init_mode); } -void -prism54_mib_init_work(islpci_private *priv) -{ - down_write(&priv->mib_sem); - mgt_commit(priv); - up_write(&priv->mib_sem); -} - /* this will be executed outside of atomic context thanks to * schedule_work(), thus we can as well use sleeping semaphore * locking */ @@ -195,16 +187,9 @@ if (down_interruptible(&priv->stats_sem)) return; -/* missing stats are : - * iwstatistics.qual.updated - * iwstatistics.discard.nwid - * iwstatistics.discard.fragment - * iwstatistics.discard.misc - * iwstatistics.miss.beacon */ - /* Noise floor. * I'm not sure if the unit is dBm. - * Note : If we are not connected, this value seems to be irrevelant. */ + * Note : If we are not connected, this value seems to be irrelevant. */ mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r); priv->local_iwstatistics.qual.noise = r.u; @@ -216,8 +201,7 @@ data = r.ptr; /* copy this MAC to the bss */ - for (j = 0; j < 6; j++) - bss.address[j] = data[j]; + memcpy(bss.address, data, 6); kfree(data); /* now ask for the corresponding bss */ @@ -426,7 +410,6 @@ /* by default the card sets this to 20. */ sens = vwrq->disabled ? 20 : vwrq->value; - /* set the ed threshold. */ return mgt_set_request(priv, DOT11_OID_EDTHRESHOLD, 0, &sens); } @@ -505,7 +488,7 @@ return 0; /* Request the device for the supported frequencies - * not really revelant since some devices will report the 5 GHz band + * not really relevant since some devices will report the 5 GHz band * frequencies even if they don't support them. */ rvalue = @@ -515,21 +498,12 @@ range->num_channels = freq->nr; range->num_frequency = freq->nr; - /* Frequencies are not listed in the right order. The reordering is probably - * firmware dependant and thus should work for everyone. - */ m = min(IW_MAX_FREQUENCIES, (int) freq->nr); - for (i = 0; i < m - 12; i++) { - range->freq[i].m = freq->mhz[12 + i]; + for (i = 0; i < m; i++) { + range->freq[i].m = freq->mhz[i]; range->freq[i].e = 6; - range->freq[i].i = i + 1; + range->freq[i].i = channel_of_freq(freq->mhz[i]); } - for (i = m - 12; i < m; i++) { - range->freq[i].m = freq->mhz[i - m + 12]; - range->freq[i].e = 6; - range->freq[i].i = i + 23; - } - kfree(freq); rvalue |= mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r); @@ -544,9 +518,7 @@ i++; data++; } - range->num_bitrates = i; - kfree(r.ptr); return rvalue; @@ -585,7 +557,6 @@ int rvalue; rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r); - memcpy(awrq->sa_data, r.ptr, 6); awrq->sa_family = ARPHRD_ETHER; kfree(r.ptr); @@ -658,8 +629,8 @@ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL); /* Add frequency. (short) bss->channel is the frequency in MHz */ - iwe.u.freq.m = bss->channel; - iwe.u.freq.e = 6; + iwe.u.freq.m = channel_of_freq(bss->channel); + iwe.u.freq.e = 0; iwe.cmd = SIOCGIWFREQ; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); @@ -695,7 +666,6 @@ kfree(buf); } } - return current_ev; } @@ -722,7 +692,7 @@ /* Ask the device for a list of known bss. We can report at most * IW_MAX_AP=64 to the range struct. But the device won't repport anything - * if you change the value of MAXBSS=24. Anyway 24 AP It is probably enough. + * if you change the value of IWMAX_BSS=24. */ rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r); bsslist = r.ptr; @@ -757,7 +727,7 @@ memcpy(essid.octets, extra, dwrq->length); } else essid.length = 0; - + if (priv->iw_mode != IW_MODE_MONITOR) return mgt_set_request(priv, DOT11_OID_SSID, 0, &essid); @@ -843,21 +813,21 @@ char *data; int ret, i; union oid_res_t r; - + if (vwrq->value == -1) { /* auto mode. No limit. */ profile = 1; return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile); } - + if ((ret = mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r))) return ret; - + rate = (u32) (vwrq->value / 500000); data = r.ptr; i = 0; - + while (data[i]) { if (rate && (data[i] == rate)) { break; @@ -868,14 +838,14 @@ data[i] |= 0x80; i++; } - + if (!data[i]) { return -EINVAL; } - + data[i] |= 0x80; data[i + 1] = 0; - + /* Now, check if we want a fixed or auto value */ if (vwrq->fixed) { data[0] = data[i]; @@ -890,14 +860,14 @@ i++; } printk("0\n"); -*/ +*/ profile = -1; ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile); ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data); ret |= mgt_set_request(priv, DOT11_OID_RATES, 0, data); - + kfree(r.ptr); - + return ret; } @@ -923,7 +893,7 @@ data = r.ptr; vwrq->fixed = (data[0] != 0) && (data[1] == 0); kfree(r.ptr); - + return 0; } @@ -979,8 +949,6 @@ * small frame <=> smaller than the rts threshold * This is not really the behavior expected by the wireless tool but it seems * to be a common behavior in other drivers. - * - * It seems that playing with this tends to hang the card -> DISABLED */ static int @@ -1012,18 +980,16 @@ lifetime = vwrq->value / 1024; /* now set what is requested */ - - if (slimit != 0) + if (slimit) rvalue = mgt_set_request(priv, DOT11_OID_SHORTRETRIES, 0, &slimit); - if (llimit != 0) + if (llimit) rvalue |= mgt_set_request(priv, DOT11_OID_LONGRETRIES, 0, &llimit); - if (lifetime != 0) + if (lifetime) rvalue |= mgt_set_request(priv, DOT11_OID_MAXTXLIFETIME, 0, &lifetime); - return rvalue; } @@ -1119,8 +1085,7 @@ } } } - - /* now read the flags */ + /* now read the flags */ if (dwrq->flags & IW_ENCODE_DISABLED) { /* Encoding disabled, * authen = DOT11_AUTH_OS; @@ -1269,13 +1234,8 @@ static int prism54_set_u32(struct net_device *ndev, struct iw_request_info *info, - __u32 * uwrq, char *extra) + __u32 * uwrq, char *extra) { - /* - u32 *i = (int *) extra; - int param = *i; - int u = *(i + 1); - */ u32 oid = uwrq[0], u = uwrq[1]; return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u); @@ -1846,9 +1806,7 @@ 0); break; - /* Note : the following should never happen since we don't run the card in - * extended mode. - * Note : "mlme" is actually a "struct obj_mlmeex *" here, but this + /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this * is backward compatible layout-wise with "struct obj_mlme". */ @@ -1893,7 +1851,8 @@ struct net_device *ndev = frame->ndev; enum oid_num_t n = mgt_oidtonum(frame->header->oid); - prism54_process_trap_helper(netdev_priv(ndev), n, frame->data); + if (n != OID_NUM_LAST) + prism54_process_trap_helper(netdev_priv(ndev), n, frame->data); islpci_mgt_release(frame); } @@ -1966,65 +1925,11 @@ } int -prism54_set_maxframeburst(struct net_device *ndev, struct iw_request_info *info, - __u32 * uwrq, char *extra) -{ - islpci_private *priv = netdev_priv(ndev); - u32 max_burst; - - max_burst = (*uwrq) ? *uwrq : CARD_DEFAULT_MAXFRAMEBURST; - mgt_set_request(priv, DOT11_OID_MAXFRAMEBURST, 0, &max_burst); - - return -EINPROGRESS; /* Call commit handler */ -} - -int -prism54_get_maxframeburst(struct net_device *ndev, struct iw_request_info *info, - __u32 * uwrq, char *extra) -{ - islpci_private *priv = netdev_priv(ndev); - union oid_res_t r; - int rvalue; - - rvalue = mgt_get_request(priv, DOT11_OID_MAXFRAMEBURST, 0, NULL, &r); - *uwrq = r.u; - - return rvalue; -} - -int -prism54_set_profile(struct net_device *ndev, struct iw_request_info *info, - __u32 * uwrq, char *extra) -{ - islpci_private *priv = netdev_priv(ndev); - u32 profile; - - profile = (*uwrq) ? *uwrq : CARD_DEFAULT_PROFILE; - mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile); - - return -EINPROGRESS; /* Call commit handler */ -} - -int -prism54_get_profile(struct net_device *ndev, struct iw_request_info *info, - __u32 * uwrq, char *extra) -{ - islpci_private *priv = netdev_priv(ndev); - union oid_res_t r; - int rvalue; - - rvalue = mgt_get_request(priv, DOT11_OID_PROFILES, 0, NULL, &r); - *uwrq = r.u; - - return rvalue; -} - -int prism54_debug_oid(struct net_device *ndev, struct iw_request_info *info, __u32 * uwrq, char *extra) { islpci_private *priv = netdev_priv(ndev); - + priv->priv_oid = *uwrq; printk("%s: oid 0x%08X\n", ndev->name, *uwrq); @@ -2033,15 +1938,15 @@ int prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info, - struct iw_point *data, char *extra) + struct iw_point *data, char *extra) { islpci_private *priv = netdev_priv(ndev); struct islpci_mgmtframe *response = NULL; int ret = -EIO, response_op = PIMFOR_OP_ERROR; - + printk("%s: get_oid 0x%08X\n", ndev->name, priv->priv_oid); data->length = 0; - + if (islpci_get_state(priv) >= PRV_STATE_INIT) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, @@ -2065,21 +1970,21 @@ printk("%s: len: %i\n", ndev->name, data->length); } } - + return ret; } int prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info, - struct iw_point *data, char *extra) + struct iw_point *data, char *extra) { islpci_private *priv = netdev_priv(ndev); struct islpci_mgmtframe *response = NULL; int ret = 0, response_op = PIMFOR_OP_ERROR; - + printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid, data->length); - + if (islpci_get_state(priv) >= PRV_STATE_INIT) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, @@ -2094,11 +1999,11 @@ } if (ret || response_op == PIMFOR_OP_ERROR) { printk("%s: EIO\n", ndev->name); - ret = -EIO; + ret = -EIO; } } - - return ret; + + return (ret ? ret : -EINPROGRESS); } static int @@ -2196,7 +2101,7 @@ #define PRISM54_DBG_GET_OID SIOCIWFIRSTPRIV+15 #define PRISM54_DBG_SET_OID SIOCIWFIRSTPRIV+16 -#define PRISM54_GET_OID SIOCIWFIRSTPRIV+17 +#define PRISM54_GET_OID SIOCIWFIRSTPRIV+17 #define PRISM54_SET_OID_U32 SIOCIWFIRSTPRIV+18 #define PRISM54_SET_OID_STR SIOCIWFIRSTPRIV+20 #define PRISM54_SET_OID_ADDR SIOCIWFIRSTPRIV+22 @@ -2204,16 +2109,16 @@ #define PRISM54_GET_PRISMHDR SIOCIWFIRSTPRIV+23 #define PRISM54_SET_PRISMHDR SIOCIWFIRSTPRIV+24 -#define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x } -#define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x } -#define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x } -#define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "get_"x } +#define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x } +#define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x } +#define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x } +#define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "g_"x } #define IWPRIV_U32(n,x) IWPRIV_SET_U32(n,x), IWPRIV_GET(n,x) #define IWPRIV_SSID(n,x) IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x) #define IWPRIV_ADDR(n,x) IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x) -/* Note : limited to 128 private ioctls */ +/* Note : limited to 128 private ioctls (wireless tools 26) */ static const struct iw_priv_args prism54_private_args[] = { /*{ cmd, set_args, get_args, name } */ @@ -2241,7 +2146,7 @@ {PRISM54_DBG_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dbg_oid"}, {PRISM54_DBG_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "dbg_get_oid"}, - {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_get_oid"}, + {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_set_oid"}, /* --- sub-ioctls handlers --- */ {PRISM54_GET_OID, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, ""}, @@ -2268,7 +2173,7 @@ IWPRIV_U32(DOT11_OID_AUTHENABLE, "authenable"), IWPRIV_U32(DOT11_OID_PRIVACYINVOKED, "privinvok"), IWPRIV_U32(DOT11_OID_EXUNENCRYPTED, "exunencrypt"), - + IWPRIV_U32(DOT11_OID_REKEYTHRESHOLD, "rekeythresh"), IWPRIV_U32(DOT11_OID_MAXTXLIFETIME, "maxtxlife"), @@ -2351,5 +2256,6 @@ int prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) { + return -EOPNOTSUPP; } diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h --- a/drivers/net/wireless/prism54/isl_ioctl.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/wireless/prism54/isl_ioctl.h 2004-06-26 17:09:18 -07:00 @@ -30,7 +30,6 @@ #define SUPPORTED_WIRELESS_EXT 16 void prism54_mib_init(islpci_private *); -void prism54_mib_init_work(islpci_private *); struct iw_statistics *prism54_get_wireless_stats(struct net_device *); void prism54_update_stats(islpci_private *); diff -Nru a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c --- a/drivers/net/wireless/prism54/islpci_dev.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/wireless/prism54/islpci_dev.c 2004-06-26 17:09:15 -07:00 @@ -30,6 +30,7 @@ #include +#include "prismcompat.h" #include "isl_38xx.h" #include "isl_ioctl.h" #include "islpci_dev.h" @@ -37,12 +38,6 @@ #include "islpci_eth.h" #include "oid_mgt.h" -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) -#define prism54_synchronize_irq(irq) synchronize_irq() -#else -#define prism54_synchronize_irq(irq) synchronize_irq(irq) -#endif - #define ISL3877_IMAGE_FILE "isl3877" #define ISL3890_IMAGE_FILE "isl3890" @@ -55,6 +50,125 @@ * ndev->set_mac_address. Jean II */ const unsigned char dummy_mac[6] = { 0x00, 0x30, 0xB4, 0x00, 0x00, 0x00 }; +static int +isl_upload_firmware(islpci_private *priv) +{ + u32 reg, rc; + void *device_base = priv->device_base; + + /* clear the RAMBoot and the Reset bit */ + reg = readl(device_base + ISL38XX_CTRL_STAT_REG); + reg &= ~ISL38XX_CTRL_STAT_RESET; + reg &= ~ISL38XX_CTRL_STAT_RAMBOOT; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* set the Reset bit without reading the register ! */ + reg |= ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* clear the Reset bit */ + reg &= ~ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + + /* wait a while for the device to reboot */ + mdelay(50); + + { + const struct firmware *fw_entry = 0; + long fw_len; + const u32 *fw_ptr; + + rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV); + if (rc) { + printk(KERN_ERR + "%s: request_firmware() failed for '%s'\n", + "prism54", priv->firmware); + return rc; + } + /* prepare the Direct Memory Base register */ + reg = ISL38XX_DEV_FIRMWARE_ADDRES; + + fw_ptr = (u32 *) fw_entry->data; + fw_len = fw_entry->size; + + if (fw_len % 4) { + printk(KERN_ERR + "%s: firmware '%s' size is not multiple of 32bit, aborting!\n", + "prism54", priv->firmware); + release_firmware(fw_entry); + return EILSEQ; /* Illegal byte sequence */; + } + + while (fw_len > 0) { + long _fw_len = + (fw_len > + ISL38XX_MEMORY_WINDOW_SIZE) ? + ISL38XX_MEMORY_WINDOW_SIZE : fw_len; + u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN; + + /* set the cards base address for writting the data */ + isl38xx_w32_flush(device_base, reg, + ISL38XX_DIR_MEM_BASE_REG); + wmb(); /* be paranoid */ + + /* increment the write address for next iteration */ + reg += _fw_len; + fw_len -= _fw_len; + + /* write the data to the Direct Memory Window 32bit-wise */ + /* memcpy_toio() doesn't guarantee 32bit writes :-| */ + while (_fw_len > 0) { + /* use non-swapping writel() */ + __raw_writel(*fw_ptr, dev_fw_ptr); + fw_ptr++, dev_fw_ptr++; + _fw_len -= 4; + } + + /* flush PCI posting */ + (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH); + wmb(); /* be paranoid again */ + + BUG_ON(_fw_len != 0); + } + + BUG_ON(fw_len != 0); + + release_firmware(fw_entry); + } + + /* now reset the device + * clear the Reset & ClkRun bit, set the RAMBoot bit */ + reg = readl(device_base + ISL38XX_CTRL_STAT_REG); + reg &= ~ISL38XX_CTRL_STAT_CLKRUN; + reg &= ~ISL38XX_CTRL_STAT_RESET; + reg |= ISL38XX_CTRL_STAT_RAMBOOT; + isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* set the reset bit latches the host override and RAMBoot bits + * into the device for operation when the reset bit is reset */ + reg |= ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + /* don't do flush PCI posting here! */ + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* clear the reset bit should start the whole circus */ + reg &= ~ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + /* don't do flush PCI posting here! */ + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + return 0; +} + /****************************************************************************** Device Interrupt Handler ******************************************************************************/ @@ -74,7 +188,9 @@ if (reg & ISL38XX_CTRL_STAT_SLEEPMODE) /* device is in sleep mode, IRQ was generated by someone else */ { - printk(KERN_DEBUG "Assuming someone else called the IRQ\n"); +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n"); +#endif return IRQ_NONE; } @@ -324,14 +440,7 @@ printk(KERN_DEBUG "%s: uploading firmware...\n", priv->ndev->name); - rc = isl38xx_upload_firmware(priv->firmware, -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75)) - &priv->pdev->dev, -#else - pci_name(priv->pdev), -#endif - priv->device_base, - priv->device_host_address); + rc = isl_upload_firmware(priv); if (rc) { /* error uploading the firmware */ printk(KERN_ERR "%s: could not upload firmware ('%s')\n", @@ -357,15 +466,8 @@ int result = -ETIME; int count; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - /* This is 2.6 specific, nicer, shorter, but not in 2.4 yet */ DEFINE_WAIT(wait); prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE); -#else - DECLARE_WAITQUEUE(wait, current); - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&priv->reset_done, &wait); -#endif /* now the last step is to reset the interface */ isl38xx_interface_reset(priv->device_base, priv->device_host_address); @@ -390,13 +492,7 @@ } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - /* 2.6 specific too */ finish_wait(&priv->reset_done, &wait); -#else - remove_wait_queue(&priv->reset_done, &wait); - set_current_state(TASK_RUNNING); -#endif if(result) return result; @@ -410,7 +506,9 @@ * the IRQ line until we know for sure the reset went through */ isl38xx_enable_common_interrupts(priv->device_base); - prism54_mib_init_work(priv); + down_write(&priv->mib_sem); + mgt_commit(priv); + up_write(&priv->mib_sem); islpci_set_state(priv, PRV_STATE_READY); @@ -448,9 +546,9 @@ /* reset the mgmt receive queue */ for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) { isl38xx_fragment *frag = &cb->rx_data_mgmt[counter]; - frag->size = MGMT_FRAME_SIZE; + frag->size = cpu_to_le16(MGMT_FRAME_SIZE); frag->flags = 0; - frag->address = priv->mgmt_rx[counter].pci_addr; + frag->address = cpu_to_le32(priv->mgmt_rx[counter].pci_addr); } for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) { @@ -580,6 +678,7 @@ skb = NULL; goto out_free; } + skb_reserve(skb, (4 - (long) skb->data) & 0x03); /* add the new allocated sk_buff to the buffer array */ priv->data_low_rx[counter] = skb; diff -Nru a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h --- a/drivers/net/wireless/prism54/islpci_dev.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/wireless/prism54/islpci_dev.h 2004-06-26 17:09:17 -07:00 @@ -29,20 +29,6 @@ #include #include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) -# include -#else -# include -# define work_struct tq_struct -# define INIT_WORK INIT_TQUEUE -# define schedule_work schedule_task -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) -#define free_netdev(x) kfree(x) -#define pci_name(x) x->slot_name -#endif - #include "isl_38xx.h" #include "isl_oid.h" #include "islpci_mgt.h" @@ -187,7 +173,7 @@ islpci_state_t state; int state_off; /* enumeration of off-state, if 0 then * we're not in any off-state */ - + /* WPA stuff */ int wpa; /* WPA mode enabled */ struct list_head bss_wpa_list; @@ -209,12 +195,6 @@ islpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state); #define ISLPCI_TX_TIMEOUT (2*HZ) - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,75)) -# define irqreturn_t void -# define IRQ_HANDLED -# define IRQ_NONE -#endif irqreturn_t islpci_interrupt(int, void *, struct pt_regs *); diff -Nru a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c --- a/drivers/net/wireless/prism54/islpci_eth.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/net/wireless/prism54/islpci_eth.c 2004-06-26 17:09:15 -07:00 @@ -26,6 +26,7 @@ #include #include +#include "prismcompat.h" #include "isl_38xx.h" #include "islpci_eth.h" #include "islpci_mgt.h" @@ -104,7 +105,7 @@ /* check whether the destination queue has enough fragments for the frame */ curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]); - if (curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE) { + if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) { printk(KERN_ERR "%s: transmit device queue full when awake\n", ndev->name); netif_stop_queue(ndev); @@ -120,7 +121,7 @@ /* Check alignment and WDS frame formatting. The start of the packet should * be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes * and add WDS address information */ - if (((long) skb->data & 0x03) | init_wds) { + if (unlikely(((long) skb->data & 0x03) | init_wds)) { /* get the number of bytes to add and re-allign */ offset = (4 - (long) skb->data) & 0x03; offset += init_wds ? 6 : 0; @@ -191,7 +192,7 @@ pci_map_address = pci_map_single(priv->pdev, (void *) skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_map_address == 0) { + if (unlikely(pci_map_address == 0)) { printk(KERN_WARNING "%s: cannot map buffer to PCI\n", ndev->name); @@ -207,7 +208,7 @@ priv->data_low_tx[index] = skb; /* set the proper fragment start address and size information */ fragment->size = cpu_to_le16(frame_size); - fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */ + fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */ fragment->address = cpu_to_le32(pci_map_address); curr_frag++; @@ -217,7 +218,7 @@ cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ] = cpu_to_le32(curr_frag); if (curr_frag - priv->free_data_tx + ISL38XX_MIN_QTHRESHOLD - > ISL38XX_CB_TX_QSIZE) { + > ISL38XX_CB_TX_QSIZE) { /* stop sends from upper layers */ netif_stop_queue(ndev); @@ -238,7 +239,7 @@ return 0; - drop_free: + drop_free: /* free the skbuf structure before aborting */ dev_kfree_skb(skb); skb = NULL; @@ -261,9 +262,9 @@ if (priv->ndev->type == ARPHRD_IEEE80211_PRISM) { struct avs_80211_1_header *avs; /* extract the relevant data from the header */ - u32 clock = hdr->clock; + u32 clock = le32_to_cpu(hdr->clock); u8 rate = hdr->rate; - u16 freq = be16_to_cpu(hdr->freq); + u16 freq = le16_to_cpu(hdr->freq); u8 rssi = hdr->rssi; skb_pull(*skb, sizeof (struct rfmon_header)); @@ -274,7 +275,7 @@ avs_80211_1_header), 0, GFP_ATOMIC); if (newskb) { - kfree_skb(*skb); + dev_kfree_skb_irq(*skb); *skb = newskb; } else return -1; @@ -286,21 +287,21 @@ (struct avs_80211_1_header *) skb_push(*skb, sizeof (struct avs_80211_1_header)); - - avs->version = htonl(P80211CAPTURE_VERSION); - avs->length = htonl(sizeof (struct avs_80211_1_header)); - avs->mactime = __cpu_to_be64(clock); - avs->hosttime = __cpu_to_be64(jiffies); - avs->phytype = htonl(6); /*OFDM: 6 for (g), 8 for (a) */ - avs->channel = htonl(channel_of_freq(freq)); - avs->datarate = htonl(rate * 5); - avs->antenna = htonl(0); /*unknown */ - avs->priority = htonl(0); /*unknown */ - avs->ssi_type = htonl(2); /*2: dBm, 3: raw RSSI */ - avs->ssi_signal = htonl(rssi); - avs->ssi_noise = htonl(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */ - avs->preamble = htonl(0); /*unknown */ - avs->encoding = htonl(0); /*unknown */ + + avs->version = cpu_to_be32(P80211CAPTURE_VERSION); + avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); + avs->mactime = cpu_to_be64(le64_to_cpu(clock)); + avs->hosttime = cpu_to_be64(jiffies); + avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */ + avs->channel = cpu_to_be32(channel_of_freq(freq)); + avs->datarate = cpu_to_be32(rate * 5); + avs->antenna = cpu_to_be32(0); /*unknown */ + avs->priority = cpu_to_be32(0); /*unknown */ + avs->ssi_type = cpu_to_be32(3); /*2: dBm, 3: raw RSSI */ + avs->ssi_signal = cpu_to_be32(rssi & 0x7f); + avs->ssi_noise = cpu_to_be32(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */ + avs->preamble = cpu_to_be32(0); /*unknown */ + avs->encoding = cpu_to_be32(0); /*unknown */ } else skb_pull(*skb, sizeof (struct rfmon_header)); @@ -381,10 +382,10 @@ skb->dev = ndev; /* take care of monitor mode and spy monitoring. */ - if (priv->iw_mode == IW_MODE_MONITOR) + if (unlikely(priv->iw_mode == IW_MODE_MONITOR)) discard = islpci_monitor_rx(priv, &skb); else { - if (skb->data[2 * ETH_ALEN] == 0) { + if (unlikely(skb->data[2 * ETH_ALEN] == 0)) { /* The packet has a rx_annex. Read it for spy monitoring, Then * remove it, while keeping the 2 leading MAC addr. */ @@ -417,8 +418,8 @@ skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5]); #endif - if (discard) { - dev_kfree_skb(skb); + if (unlikely(discard)) { + dev_kfree_skb_irq(skb); skb = NULL; } else netif_rx(skb); @@ -433,11 +434,13 @@ index - priv->free_data_rx < ISL38XX_CB_RX_QSIZE) { /* allocate an sk_buff for received data frames storage * include any required allignment operations */ - if (skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2), skb == NULL) { + skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2); + if (unlikely(skb == NULL)) { /* error allocating an sk_buff structure elements */ DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n"); break; } + skb_reserve(skb, (4 - (long) skb->data) & 0x03); /* store the new skb structure pointer */ index = index % ISL38XX_CB_RX_QSIZE; priv->data_low_rx[index] = skb; @@ -453,13 +456,13 @@ pci_map_single(priv->pdev, (void *) skb->data, MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE); - if (priv->pci_map_rx_address[index] == (dma_addr_t) NULL) { + if (unlikely(priv->pci_map_rx_address[index] == (dma_addr_t) NULL)) { /* error mapping the buffer to device accessable memory address */ DEBUG(SHOW_ERROR_MESSAGES, "Error mapping DMA address\n"); /* free the skbuf structure before aborting */ - dev_kfree_skb((struct sk_buff *) skb); + dev_kfree_skb_irq((struct sk_buff *) skb); skb = NULL; break; } @@ -484,10 +487,10 @@ void islpci_do_reset_and_wake(void *data) { - islpci_private *priv = (islpci_private *) data; - islpci_reset(priv, 1); - netif_wake_queue(priv->ndev); - priv->reset_task_pending = 0; + islpci_private *priv = (islpci_private *) data; + islpci_reset(priv, 1); + netif_wake_queue(priv->ndev); + priv->reset_task_pending = 0; } void diff -Nru a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c --- a/drivers/net/wireless/prism54/islpci_hotplug.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/wireless/prism54/islpci_hotplug.c 2004-06-26 17:09:18 -07:00 @@ -24,12 +24,13 @@ #include #include /* For __init, __exit */ +#include "prismcompat.h" #include "islpci_dev.h" #include "islpci_mgt.h" /* for pc_debug */ #include "isl_oid.h" #define DRV_NAME "prism54" -#define DRV_VERSION "1.1" +#define DRV_VERSION "1.2" MODULE_AUTHOR("[Intersil] R.Bastings and W.Termorshuizen, The prism54.org Development Team "); MODULE_DESCRIPTION("The Prism54 802.11 Wireless LAN adapter"); diff -Nru a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c --- a/drivers/net/wireless/prism54/islpci_mgt.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/wireless/prism54/islpci_mgt.c 2004-06-26 17:09:19 -07:00 @@ -22,12 +22,12 @@ #include #include #include -#include #include #include #include +#include "prismcompat.h" #include "isl_38xx.h" #include "islpci_mgt.h" #include "isl_oid.h" /* additional types and defs for isl38xx fw */ @@ -63,7 +63,6 @@ Queue handling for management frames ******************************************************************************/ - /* * Helper function to create a PIMFOR management frame header. */ @@ -86,8 +85,8 @@ { pimfor_header_t *h = data; - while ((void *) h < data + len) { - if(h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) { + while ((void *) h < data + len) { + if (h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) { le32_to_cpus(&h->oid); le32_to_cpus(&h->length); } else { @@ -108,8 +107,8 @@ islpci_mgmt_rx_fill(struct net_device *ndev) { islpci_private *priv = netdev_priv(ndev); - isl38xx_control_block *cb = /* volatile not needed */ - (isl38xx_control_block *) priv->control_block; + isl38xx_control_block *cb = /* volatile not needed */ + (isl38xx_control_block *) priv->control_block; u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]); #if VERBOSE > SHOW_ERROR_MESSAGES @@ -124,7 +123,8 @@ if (buf->mem == NULL) { buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC); if (!buf->mem) { - printk(KERN_WARNING "Error allocating management frame.\n"); + printk(KERN_WARNING + "Error allocating management frame.\n"); return -ENOMEM; } buf->size = MGMT_FRAME_SIZE; @@ -133,24 +133,24 @@ buf->pci_addr = pci_map_single(priv->pdev, buf->mem, MGMT_FRAME_SIZE, PCI_DMA_FROMDEVICE); - if(!buf->pci_addr) { - printk(KERN_WARNING "Failed to make memory DMA'able\n."); + if (!buf->pci_addr) { + printk(KERN_WARNING + "Failed to make memory DMA'able\n."); return -ENOMEM; } } - /* be safe: always reset control block information */ + /* be safe: always reset control block information */ frag->size = cpu_to_le16(MGMT_FRAME_SIZE); frag->flags = 0; frag->address = cpu_to_le32(buf->pci_addr); curr++; - /* The fragment address in the control block must have - * been written before announcing the frame buffer to - * device */ + /* The fragment address in the control block must have + * been written before announcing the frame buffer to + * device */ wmb(); - cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = - cpu_to_le32(curr); + cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = cpu_to_le32(curr); } return 0; } @@ -168,7 +168,7 @@ { islpci_private *priv = netdev_priv(ndev); isl38xx_control_block *cb = - (isl38xx_control_block *) priv->control_block; + (isl38xx_control_block *) priv->control_block; void *p; int err = -EINVAL; unsigned long flags; @@ -242,25 +242,25 @@ priv->mgmt_tx[index] = buf; frag = &cb->tx_data_mgmt[index]; frag->size = cpu_to_le16(frag_len); - frag->flags = 0; /* for any other than the last fragment, set to 1 */ + frag->flags = 0; /* for any other than the last fragment, set to 1 */ frag->address = cpu_to_le32(buf.pci_addr); /* The fragment address in the control block must have * been written before announcing the frame buffer to * device */ wmb(); - cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag+1); + cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag + 1); spin_unlock_irqrestore(&priv->slock, flags); /* trigger the device */ islpci_trigger(priv); return 0; - error_unlock: + error_unlock: spin_unlock_irqrestore(&priv->slock, flags); - error_free: + error_free: kfree(buf.mem); - error: + error: return err; } @@ -274,50 +274,49 @@ { islpci_private *priv = netdev_priv(ndev); isl38xx_control_block *cb = - (isl38xx_control_block *) priv->control_block; + (isl38xx_control_block *) priv->control_block; u32 curr_frag; #if VERBOSE > SHOW_ERROR_MESSAGES DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n"); #endif - - /* Only once per interrupt, determine fragment range to - * process. This avoids an endless loop (i.e. lockup) if - * frames come in faster than we can process them. */ + /* Only once per interrupt, determine fragment range to + * process. This avoids an endless loop (i.e. lockup) if + * frames come in faster than we can process them. */ curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]); barrier(); - for ( ; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) { + for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) { pimfor_header_t *header; u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE; struct islpci_membuf *buf = &priv->mgmt_rx[index]; u16 frag_len; int size; struct islpci_mgmtframe *frame; - - /* I have no idea (and no documentation) if flags != 0 - * is possible. Drop the frame, reuse the buffer. */ - if(le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) { - printk(KERN_WARNING "%s: unknown flags 0x%04x\n", - ndev->name, - le16_to_cpu(cb->rx_data_mgmt[index].flags)); - continue; - } + + /* I have no idea (and no documentation) if flags != 0 + * is possible. Drop the frame, reuse the buffer. */ + if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) { + printk(KERN_WARNING "%s: unknown flags 0x%04x\n", + ndev->name, + le16_to_cpu(cb->rx_data_mgmt[index].flags)); + continue; + } /* The device only returns the size of the header(s) here. */ frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size); /* - * We appear to have no way to tell the device the - * size of a receive buffer. Thus, if this check - * triggers, we likely have kernel heap corruption. */ - if (frag_len > MGMT_FRAME_SIZE) { - printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\ -n", - ndev->name, frag_len, frag_len); - frag_len = MGMT_FRAME_SIZE; - } + * We appear to have no way to tell the device the + * size of a receive buffer. Thus, if this check + * triggers, we likely have kernel heap corruption. */ + if (frag_len > MGMT_FRAME_SIZE) { + printk(KERN_WARNING + "%s: Bogus packet size of %d (%#x).\n", + ndev->name, frag_len, frag_len); + frag_len = MGMT_FRAME_SIZE; + } /* Ensure the results of device DMA are visible to the CPU. */ pci_dma_sync_single(priv->pdev, buf->pci_addr, @@ -339,30 +338,32 @@ #if VERBOSE > SHOW_ERROR_MESSAGES DEBUG(SHOW_PIMFOR_FRAMES, "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n", - header->operation, header->oid, header->device_id, + header->operation, header->oid, header->device_id, header->flags, header->length); /* display the buffer contents for debugging */ display_buffer((char *) header, PIMFOR_HEADER_SIZE); - display_buffer((char *) header + PIMFOR_HEADER_SIZE, header->length); + display_buffer((char *) header + PIMFOR_HEADER_SIZE, + header->length); #endif /* nobody sends these */ if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) { - printk(KERN_DEBUG "%s: errant PIMFOR application frame\n", + printk(KERN_DEBUG + "%s: errant PIMFOR application frame\n", ndev->name); continue; } /* Determine frame size, skipping OID_INL_TUNNEL headers. */ size = PIMFOR_HEADER_SIZE + header->length; - frame = kmalloc(sizeof(struct islpci_mgmtframe) + size, + frame = kmalloc(sizeof (struct islpci_mgmtframe) + size, GFP_ATOMIC); if (!frame) { - printk(KERN_WARNING "%s: Out of memory, cannot handle oid 0x%08x\n", - + printk(KERN_WARNING + "%s: Out of memory, cannot handle oid 0x%08x\n", ndev->name, header->oid); - continue; + continue; } frame->ndev = ndev; memcpy(&frame->buf, header, size); @@ -382,7 +383,7 @@ header->oid, header->device_id, header->flags, header->length); #endif - + /* Create work to handle trap out of interrupt * context. */ INIT_WORK(&frame->ws, prism54_process_trap, frame); @@ -392,14 +393,13 @@ /* Signal the one waiting process that a response * has been received. */ if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) { - printk(KERN_WARNING "%s: mgmt response not collected\n", + printk(KERN_WARNING + "%s: mgmt response not collected\n", ndev->name); kfree(frame); } - #if VERBOSE > SHOW_ERROR_MESSAGES - DEBUG(SHOW_TRACING, - "Wake up Mgmt Queue\n"); + DEBUG(SHOW_TRACING, "Wake up Mgmt Queue\n"); #endif wake_up(&priv->mgmt_wqueue); } @@ -416,22 +416,22 @@ islpci_mgt_cleanup_transmit(struct net_device *ndev) { islpci_private *priv = netdev_priv(ndev); - isl38xx_control_block *cb = /* volatile not needed */ - (isl38xx_control_block *) priv->control_block; + isl38xx_control_block *cb = /* volatile not needed */ + (isl38xx_control_block *) priv->control_block; u32 curr_frag; #if VERBOSE > SHOW_ERROR_MESSAGES - DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n"); + DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n"); #endif /* Only once per cleanup, determine fragment range to * process. This avoids an endless loop (i.e. lockup) if * the device became confused, incrementing device_curr_frag * rapidly. */ - curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]); + curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]); barrier(); - for ( ; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) { + for (; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) { int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE; struct islpci_membuf *buf = &priv->mgmt_tx[index]; pci_unmap_single(priv->pdev, buf->pci_addr, buf->size, @@ -456,23 +456,14 @@ const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000; long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies; int err; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) DEFINE_WAIT(wait); -#else - DECLARE_WAITQUEUE(wait, current); -#endif if (down_interruptible(&priv->mgmt_sem)) return -ERESTARTSYS; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE); -#else - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&priv->mgmt_wqueue, &wait); -#endif err = islpci_mgt_transmit(ndev, operation, oid, senddata, sendlen); - if(err) + if (err) goto out; err = -ETIMEDOUT; @@ -483,13 +474,24 @@ timeleft = schedule_timeout(wait_cycle_jiffies); frame = xchg(&priv->mgmt_received, NULL); if (frame) { - *recvframe = frame; - err = 0; - goto out; - } - if(timeleft == 0) { - printk(KERN_DEBUG "%s: timeout waiting for mgmt response %lu, trigging device\n", - ndev->name, timeout_left); + if (frame->header->oid == oid) { + *recvframe = frame; + err = 0; + goto out; + } else { + printk(KERN_DEBUG + "%s: expecting oid 0x%x, received 0x%x.\n", + ndev->name, (unsigned int) oid, + frame->header->oid); + kfree(frame); + frame = NULL; + } + } + if (timeleft == 0) { + printk(KERN_DEBUG + "%s: timeout waiting for mgmt response %lu, " + "triggering device\n", + ndev->name, timeout_left); islpci_trigger(priv); } timeout_left += timeleft - wait_cycle_jiffies; @@ -499,12 +501,7 @@ /* TODO: we should reset the device here */ out: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) finish_wait(&priv->mgmt_wqueue, &wait); -#else - remove_wait_queue(&priv->mgmt_wqueue, &wait); - set_current_state(TASK_RUNNING); -#endif up(&priv->mgmt_sem); return err; } diff -Nru a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h --- a/drivers/net/wireless/prism54/islpci_mgt.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/net/wireless/prism54/islpci_mgt.h 2004-06-26 17:09:16 -07:00 @@ -24,15 +24,6 @@ #include #include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) -# include -#else -# include -# define work_struct tq_struct -# define INIT_WORK INIT_TQUEUE -# define schedule_work schedule_task -#endif - /* * Function definitions */ @@ -43,7 +34,7 @@ #define TRACE(devname) K_DEBUG(SHOW_TRACING, VERBOSE, "%s: -> " __FUNCTION__ "()\n", devname) extern int pc_debug; -static const int init_wds = 0; /* help compiler optimize away dead code */ +#define init_wds 0 /* help compiler optimize away dead code */ /* General driver definitions */ diff -Nru a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c --- a/drivers/net/wireless/prism54/oid_mgt.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/wireless/prism54/oid_mgt.c 2004-06-26 17:09:20 -07:00 @@ -16,6 +16,7 @@ * */ +#include "prismcompat.h" #include "islpci_dev.h" #include "islpci_mgt.h" #include "isl_oid.h" @@ -39,17 +40,13 @@ if ((f >= 2412) && (f <= 2484)) { while ((c < 14) && (f != frequency_list_bg[c])) c++; - if (c >= 14) - return 0; + return (c >= 14) ? 0 : ++c; } else if ((f >= (int) 5170) && (f <= (int) 5320)) { while ((c < 12) && (f != frequency_list_a[c])) c++; - if (c >= 12) - return 0; + return (c >= 12) ? 0 : (c + 37); } else return 0; - - return ++c; } #define OID_STRUCT(name,oid,s,t) [name] = {oid, 0, sizeof(s), t} @@ -449,7 +446,7 @@ if (cache) down_write(&priv->mib_sem); - if (islpci_get_state(priv) >= PRV_STATE_INIT) { + if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, _data, dlen, &response); if (!ret) { @@ -457,7 +454,7 @@ islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) - ret = -EIO; + ret = -EIO; } else if (!cache) ret = -EIO; @@ -482,7 +479,7 @@ int ret = -EIO; int reslen = 0; struct islpci_mgmtframe *response = NULL; - + int dlen; void *cache, *_res = NULL; u32 oid; @@ -503,11 +500,11 @@ if (cache) down_read(&priv->mib_sem); - if (islpci_get_state(priv) >= PRV_STATE_INIT) { + if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, oid, data, dlen, &response); if (ret || !response || - response->header->operation == PIMFOR_OP_ERROR) { + response->header->operation == PIMFOR_OP_ERROR) { if (response) islpci_mgt_release(response); ret = -EIO; @@ -542,9 +539,9 @@ if (reslen > isl_oid[n].size) printk(KERN_DEBUG "mgt_get_request(0x%x): received data length was bigger " - "than expected (%d > %d). Memory is probably corrupted... ", + "than expected (%d > %d). Memory is probably corrupted...", oid, reslen, isl_oid[n].size); - + return ret; } @@ -564,11 +561,11 @@ while (j <= t->range) { response = NULL; ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, - oid, data, t->size, + oid, data, t->size, &response); if (response) { ret |= (response->header->operation == - PIMFOR_OP_ERROR); + PIMFOR_OP_ERROR); islpci_mgt_release(response); } j++; @@ -625,12 +622,32 @@ OID_INL_OUTPUTPOWER, }; +/* update the MAC addr. */ +static int +mgt_update_addr(islpci_private *priv) +{ + struct islpci_mgmtframe *res; + int ret; + + ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, + isl_oid[GEN_OID_MACADDRESS].oid, NULL, + isl_oid[GEN_OID_MACADDRESS].size, &res); + + if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR)) + memcpy(priv->ndev->dev_addr, res->data, 6); + else + ret = -EIO; + if (res) + islpci_mgt_release(res); + + return ret; +} + void mgt_commit(islpci_private *priv) { int rvalue; u32 u; - union oid_res_t r; if (islpci_get_state(priv) < PRV_STATE_INIT) return; @@ -646,21 +663,14 @@ u = OID_INL_MODE; rvalue |= mgt_commit_list(priv, &u, 1); + rvalue |= mgt_update_addr(priv); if (rvalue) { /* some request have failed. The device might be in an incoherent state. We should reset it ! */ printk(KERN_DEBUG "%s: mgt_commit has failed. Restart the " - "device \n", priv->ndev->name); + "device \n", priv->ndev->name); } - - /* update the MAC addr. As it's not cached, no lock will be acquired by - * the mgt_get_request - */ - mgt_get_request(priv, GEN_OID_MACADDRESS, 0, NULL, &r); - memcpy(priv->ndev->dev_addr, r.ptr, 6); - kfree(r.ptr); - } /* This will tell you if you are allowed to answer a mlme(ex) request .*/ @@ -687,13 +697,13 @@ { int i; - for (i = 0; i < OID_NUM_LAST - 1; i++) + for (i = 0; i < OID_NUM_LAST; i++) if (isl_oid[i].oid == oid) return i; printk(KERN_DEBUG "looking for an unknown oid 0x%x", oid); - return 0; + return OID_NUM_LAST; } int @@ -713,8 +723,11 @@ case OID_TYPE_BSS:{ struct obj_bss *bss = r->ptr; return snprintf(str, PRIV_STR_SIZE, - "age=%u\nchannel=%u\n\ - capinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n", bss->age, bss->channel, bss->capinfo, bss->rates, bss->basic_rates); + "age=%u\nchannel=%u\n" + "capinfo=0x%X\nrates=0x%X\n" + "basic_rates=0x%X\n", bss->age, + bss->channel, bss->capinfo, + bss->rates, bss->basic_rates); } break; case OID_TYPE_BSSLIST:{ @@ -723,7 +736,9 @@ k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr); for (i = 0; i < list->nr; i++) k += snprintf(str + k, PRIV_STR_SIZE - k, - "bss[%u] : \nage=%u\nchannel=%u\ncapinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n", + "bss[%u] : \nage=%u\nchannel=%u\n" + "capinfo=0x%X\nrates=0x%X\n" + "basic_rates=0x%X\n", i, list->bsslist[i].age, list->bsslist[i].channel, list->bsslist[i].capinfo, @@ -745,16 +760,17 @@ break; case OID_TYPE_MLME:{ struct obj_mlme *mlme = r->ptr; - return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\ - code=0x%X\n", mlme->id, mlme->state, - mlme->code); + return snprintf(str, PRIV_STR_SIZE, + "id=0x%X\nstate=0x%X\ncode=0x%X\n", + mlme->id, mlme->state, mlme->code); } break; case OID_TYPE_MLMEEX:{ struct obj_mlmeex *mlme = r->ptr; - return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\ - code=0x%X\nsize=0x%X\n", mlme->id, mlme->state, - mlme->code, mlme->size); + return snprintf(str, PRIV_STR_SIZE, + "id=0x%X\nstate=0x%X\n" + "code=0x%X\nsize=0x%X\n", mlme->id, + mlme->state, mlme->code, mlme->size); } break; case OID_TYPE_SSID:{ diff -Nru a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h --- a/drivers/net/wireless/prism54/oid_mgt.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/net/wireless/prism54/oid_mgt.h 2004-06-26 17:09:21 -07:00 @@ -38,7 +38,7 @@ int mgt_set_request(islpci_private *, enum oid_num_t, int, void *); int mgt_get_request(islpci_private *, enum oid_num_t, int, void *, - union oid_res_t *); + union oid_res_t *); int mgt_commit_list(islpci_private *, enum oid_num_t *, int); diff -Nru a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/net/wireless/prism54/prismcompat.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,46 @@ +/* + * (C) 2004 Margit Schubert-While + * + * 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 + * + * 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 + * + */ + +/* + * Compatibility header file to aid support of different kernel versions + */ + +#ifdef PRISM54_COMPAT24 +#include "prismcompat24.h" +#else /* PRISM54_COMPAT24 */ + +#ifndef _PRISM_COMPAT_H +#define _PRISM_COMPAT_H + +#include +#include +#include +#include +#include +#include + +#if !defined(CONFIG_FW_LOADER) && !defined(CONFIG_FW_LOADER_MODULE) +#error Firmware Loading is not configured in the kernel ! +#endif + +#define prism54_synchronize_irq(irq) synchronize_irq(irq) + +#define PRISM_FW_PDEV &priv->pdev->dev + +#endif /* _PRISM_COMPAT_H */ +#endif /* PRISM54_COMPAT24 */ diff -Nru a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c --- a/drivers/net/wireless/ray_cs.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/wireless/ray_cs.c 2004-06-26 17:09:17 -07:00 @@ -2854,7 +2854,7 @@ } } -static int write_essid(struct file *file, const char *buffer, unsigned long count, void *data) +static int write_essid(struct file *file, const char __user *buffer, unsigned long count, void *data) { static char proc_essid[33]; int len = count; @@ -2868,7 +2868,7 @@ return count; } -static int write_int(struct file *file, const char *buffer, unsigned long count, void *data) +static int write_int(struct file *file, const char __user *buffer, unsigned long count, void *data) { static char proc_number[10]; char *p; diff -Nru a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c --- a/drivers/net/wireless/strip.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/net/wireless/strip.c 2004-06-26 17:09:19 -07:00 @@ -409,12 +409,12 @@ static const MetricomAddress broadcast_address = { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} }; -static const MetricomKey SIP0Key = { {"SIP0"} }; -static const MetricomKey ARP0Key = { {"ARP0"} }; -static const MetricomKey ATR_Key = { {"ATR "} }; -static const MetricomKey ACK_Key = { {"ACK_"} }; -static const MetricomKey INF_Key = { {"INF_"} }; -static const MetricomKey ERR_Key = { {"ERR_"} }; +static const MetricomKey SIP0Key = { "SIP0" }; +static const MetricomKey ARP0Key = { "ARP0" }; +static const MetricomKey ATR_Key = { "ATR " }; +static const MetricomKey ACK_Key = { "ACK_" }; +static const MetricomKey INF_Key = { "INF_" }; +static const MetricomKey ERR_Key = { "ERR_" }; static const long MaxARPInterval = 60 * HZ; /* One minute */ @@ -2733,14 +2733,14 @@ switch (cmd) { case SIOCGIFNAME: - if(copy_to_user((void *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1)) + if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1)) return -EFAULT; break; case SIOCSIFHWADDR: { MetricomAddress addr; //printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name); - if(copy_from_user(&addr, (void *) arg, sizeof(MetricomAddress))) + if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress))) return -EFAULT; return set_mac_address(strip_info, &addr); } @@ -2750,7 +2750,7 @@ case TCGETS: case TCGETA: - return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg); + return n_tty_ioctl(tty, file, cmd, arg); break; default: return -ENOIOCTLCMD; diff -Nru a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c --- a/drivers/net/yellowfin.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/net/yellowfin.c 2004-06-26 17:09:17 -07:00 @@ -448,7 +448,7 @@ np = dev->priv; - if (pci_request_regions(pdev, dev->name)) + if (pci_request_regions(pdev, DRV_NAME)) goto err_out_free_netdev; pci_set_master (pdev); @@ -1201,13 +1201,8 @@ break; skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ -#if HAS_IP_COPYSUM eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0); skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), - rx_skb->tail, pkt_len); -#endif pci_dma_sync_single_for_device(yp->pci_dev, desc->addr, yp->rx_buf_sz, PCI_DMA_FROMDEVICE); diff -Nru a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c --- a/drivers/net/zorro8390.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/net/zorro8390.c 2004-06-26 17:09:18 -07:00 @@ -36,6 +36,8 @@ #include "8390.h" +#define DRV_NAME "zorro8390" + #define NE_BASE (dev->base_addr) #define NE_CMD (0x00*2) #define NE_DATAPORT (0x10*2) /* NatSemi-defined port window offset. */ @@ -115,7 +117,7 @@ if (!dev) return -ENOMEM; SET_MODULE_OWNER(dev); - if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, dev->name)) { + if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, DRV_NAME)) { free_netdev(dev); return -EBUSY; } @@ -198,7 +200,7 @@ dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ - i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, dev->name, dev); + i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, DRV_NAME, dev); if (i) return i; for(i = 0; i < ETHER_ADDR_LEN; i++) { diff -Nru a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c --- a/drivers/oprofile/oprofile_files.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/oprofile/oprofile_files.c 2004-06-26 17:09:18 -07:00 @@ -90,7 +90,7 @@ void oprofile_create_files(struct super_block * sb, struct dentry * root) { oprofilefs_create_file(sb, root, "enable", &enable_fops); - oprofilefs_create_file(sb, root, "dump", &dump_fops); + oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); diff -Nru a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c --- a/drivers/oprofile/oprofilefs.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/oprofile/oprofilefs.c 2004-06-26 17:09:17 -07:00 @@ -165,7 +165,8 @@ static struct dentry * __oprofilefs_create_file(struct super_block * sb, - struct dentry * root, char const * name, struct file_operations * fops) + struct dentry * root, char const * name, struct file_operations * fops, + int perm) { struct dentry * dentry; struct inode * inode; @@ -176,7 +177,7 @@ dentry = d_alloc(root, &qname); if (!dentry) return 0; - inode = oprofilefs_get_inode(sb, S_IFREG | 0644); + inode = oprofilefs_get_inode(sb, S_IFREG | perm); if (!inode) { dput(dentry); return 0; @@ -190,7 +191,8 @@ int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, char const * name, unsigned long * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &ulong_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &ulong_fops, 0644); if (!d) return -EFAULT; @@ -202,7 +204,8 @@ int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root, char const * name, unsigned long * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &ulong_ro_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &ulong_ro_fops, 0444); if (!d) return -EFAULT; @@ -227,7 +230,8 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, char const * name, atomic_t * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &atomic_ro_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &atomic_ro_fops, 0444); if (!d) return -EFAULT; @@ -239,7 +243,16 @@ int oprofilefs_create_file(struct super_block * sb, struct dentry * root, char const * name, struct file_operations * fops) { - if (!__oprofilefs_create_file(sb, root, name, fops)) + if (!__oprofilefs_create_file(sb, root, name, fops, 0644)) + return -EFAULT; + return 0; +} + + +int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, + char const * name, struct file_operations * fops, int perm) +{ + if (!__oprofilefs_create_file(sb, root, name, fops, perm)) return -EFAULT; return 0; } diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c --- a/drivers/parisc/ccio-dma.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/parisc/ccio-dma.c 2004-06-26 17:09:16 -07:00 @@ -44,7 +44,6 @@ #include #include /* for L1_CACHE_BYTES */ #include -#include #include #include #include diff -Nru a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c --- a/drivers/parisc/ccio-rm-dma.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/parisc/ccio-rm-dma.c 2004-06-26 17:09:16 -07:00 @@ -40,7 +40,6 @@ #include #include -#include #include #include diff -Nru a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog --- a/drivers/parport/ChangeLog 2004-06-26 17:09:19 -07:00 +++ b/drivers/parport/ChangeLog 2004-06-26 17:09:19 -07:00 @@ -1,3 +1,7 @@ +2001-10-11 Tim Waugh + * parport_pc.c, parport_serial.c: Support for NetMos cards. + + Patch originally from Michael Reinelt . + 2002-04-25 Tim Waugh * parport_serial.c, parport_pc.c: Move some SIIG cards around. diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c --- a/drivers/parport/parport_pc.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/parport/parport_pc.c 2004-06-26 17:09:21 -07:00 @@ -2632,6 +2632,10 @@ oxsemi_840, aks_0100, mobility_pp, + netmos_9705, + netmos_9805, + netmos_9815, + netmos_9855, }; @@ -2701,6 +2705,10 @@ /* oxsemi_840 */ { 1, { { 0, -1 }, } }, /* aks_0100 */ { 1, { { 0, -1 }, } }, /* mobility_pp */ { 1, { { 0, 1 }, } }, + /* netmos_9705 */ { 1, { { 0, -1 }, } }, /* untested */ + /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ + /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ + /* netmos_9855 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ }; static struct pci_device_id parport_pc_pci_tbl[] = { @@ -2769,6 +2777,15 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_840 }, { PCI_VENDOR_ID_AKS, PCI_DEVICE_ID_AKS_ALADDINCARD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 }, + /* NetMos communication controllers */ + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9705, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9705 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9805, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); diff -Nru a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c --- a/drivers/parport/parport_serial.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/parport/parport_serial.c 2004-06-26 17:09:20 -07:00 @@ -33,6 +33,8 @@ enum parport_pc_pci_cards { titan_110l = 0, titan_210l, + netmos_9735, + netmos_9835, avlab_1s1p, avlab_1s1p_650, avlab_1s1p_850, @@ -71,6 +73,8 @@ } cards[] __devinitdata = { /* titan_110l */ { 1, { { 3, -1 }, } }, /* titan_210l */ { 1, { { 3, -1 }, } }, + /* netmos_9735 (not tested) */ { 1, { { 2, -1 }, } }, + /* netmos_9835 */ { 1, { { 2, -1 }, } }, /* avlab_1s1p */ { 1, { { 1, 2}, } }, /* avlab_1s1p_650 */ { 1, { { 1, 2}, } }, /* avlab_1s1p_850 */ { 1, { { 1, 2}, } }, @@ -93,6 +97,10 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L, PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9735 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9835 }, /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p}, { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650}, @@ -172,6 +180,8 @@ /* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, /* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, +/* netmos_9735 (n/t)*/ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, +/* netmos_9835 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, diff -Nru a/drivers/pci/Kconfig b/drivers/pci/Kconfig --- a/drivers/pci/Kconfig 2004-06-26 17:09:16 -07:00 +++ b/drivers/pci/Kconfig 2004-06-26 17:09:16 -07:00 @@ -3,7 +3,7 @@ # config PCI_USE_VECTOR bool "Vector-based interrupt indexing (MSI)" - depends on (X86_LOCAL_APIC && X86_IO_APIC && !X86_64) || IA64 + depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 default n help This replaces the current existing IRQ-based index interrupt scheme diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c --- a/drivers/pci/hotplug/pciehp_ctrl.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/pci/hotplug/pciehp_ctrl.c 2004-06-26 17:09:16 -07:00 @@ -1058,6 +1058,34 @@ hotplug controller logic */ +static void set_slot_off(struct controller *ctrl, struct slot * pslot) +{ + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + /* turn off slot, turn on Amber LED, turn off Green LED */ + if (pslot->hpc_ops->power_off_slot(pslot)) { + err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); + return; + } + wait_for_ctrl_irq (ctrl); + + pslot->hpc_ops->green_led_off(pslot); + + wait_for_ctrl_irq (ctrl); + + /* turn on Amber LED */ + if (pslot->hpc_ops->set_attention_status(pslot, 1)) { + err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); + return; + } + wait_for_ctrl_irq (ctrl); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); +} /** * board_added - Called after a board has been added to the system. @@ -1071,7 +1099,7 @@ u8 hp_slot; int index; u32 temp_register = 0xFFFFFFFF; - u32 retval, rc = 0; + u32 rc = 0; struct pci_func *new_func = NULL; struct slot *p_slot; struct resource_lists res_lists; @@ -1086,8 +1114,10 @@ /* Power on slot */ rc = p_slot->hpc_ops->power_on_slot(p_slot); - if (rc) + if (rc) { + up(&ctrl->crit_sect); return -1; + } /* Wait for the command to complete */ wait_for_ctrl_irq (ctrl); @@ -1105,11 +1135,12 @@ wait_for_ctrl_irq (ctrl); dbg("%s: afterlong_delay\n", __FUNCTION__); - /* Make this to check for link training status */ + /* Check link training status */ rc = p_slot->hpc_ops->check_lnk_status(ctrl); if (rc) { err("%s: Failed to check link status\n", __FUNCTION__); - return -1; + set_slot_off(ctrl, p_slot); + return rc; } dbg("%s: func status = %x\n", __FUNCTION__, func->status); @@ -1159,36 +1190,7 @@ pciehp_resource_sort_and_combine(&(ctrl->bus_head)); if (rc) { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* turn off slot, turn on Amber LED, turn off Green LED */ - retval = p_slot->hpc_ops->power_off_slot(p_slot); - /* In PCI Express, just power off slot */ - if (retval) { - err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - p_slot->hpc_ops->green_led_off(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* turn on Amber LED */ - retval = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (retval) { - err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - + set_slot_off(ctrl, p_slot); return rc; } pciehp_save_slot_config(ctrl, func); @@ -1223,37 +1225,8 @@ up(&ctrl->crit_sect); } else { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* turn off slot, turn on Amber LED, turn off Green LED */ - retval = p_slot->hpc_ops->power_off_slot(p_slot); - /* In PCI Express, just power off slot */ - if (retval) { - err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - p_slot->hpc_ops->green_led_off(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* turn on Amber LED */ - retval = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (retval) { - err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - return rc; + set_slot_off(ctrl, p_slot); + return -1; } return 0; } @@ -1320,6 +1293,7 @@ rc = p_slot->hpc_ops->power_off_slot(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return rc; } /* Wait for the command to complete */ @@ -1406,7 +1380,6 @@ { struct slot *p_slot = (struct slot *) slot; u8 getstatus; - int rc; pushbutton_pending = 0; @@ -1420,23 +1393,7 @@ p_slot->state = POWEROFF_STATE; dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); - if (pciehp_disable_slot(p_slot)) { - /* Wait for exclusive access to hardware */ - down(&p_slot->ctrl->crit_sect); - - /* Turn on the Attention LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - - /* Done with exclusive hardware access */ - up(&p_slot->ctrl->crit_sect); - } + pciehp_disable_slot(p_slot); p_slot->state = STATIC_STATE; } else { p_slot->state = POWERON_STATE; @@ -1446,15 +1403,6 @@ /* Wait for exclusive access to hardware */ down(&p_slot->ctrl->crit_sect); - /* Turn off the green LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - p_slot->hpc_ops->green_led_off(p_slot); /* Wait for the command to complete */ @@ -1664,7 +1612,10 @@ down(&ctrl->crit_sect); p_slot->hpc_ops->set_attention_status(p_slot, 1); + wait_for_ctrl_irq (ctrl); + p_slot->hpc_ops->green_led_off(p_slot); + wait_for_ctrl_irq (ctrl); /* Done with exclusive hardware access */ up(&ctrl->crit_sect); @@ -1701,21 +1652,21 @@ if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } up(&p_slot->ctrl->crit_sect); @@ -1788,21 +1739,21 @@ if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } up(&p_slot->ctrl->crit_sect); diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c --- a/drivers/pci/hotplug/pciehp_hpc.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/pci/hotplug/pciehp_hpc.c 2004-06-26 17:09:19 -07:00 @@ -349,7 +349,9 @@ return retval; } - if ( (lnk_status & (LNK_TRN | LNK_TRN_ERR)) == 0x0C00) { + dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status); + if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || + !(lnk_status & NEG_LINK_WD)) { err("%s : Link Training Error occurs \n", __FUNCTION__); retval = -1; return retval; diff -Nru a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c --- a/drivers/pci/hotplug/pciehprm_acpi.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/pci/hotplug/pciehprm_acpi.c 2004-06-26 17:09:20 -07:00 @@ -218,6 +218,10 @@ } ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); + if (!ab->_hpp) { + err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name); + goto free_and_return; + } memset(ab->_hpp, 0, sizeof(struct acpi__hpp)); ab->_hpp->cache_line_size = nui[0]; @@ -1393,7 +1397,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -1411,11 +1415,19 @@ if (vid != 0xFFFFFFFF) { dbg("%s: vid = %x\n", __FUNCTION__, vid); func = pciehp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + pciehprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + pciehprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - pciehprm_dump_func_res(func); } } } diff -Nru a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c --- a/drivers/pci/hotplug/pciehprm_nonacpi.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/pci/hotplug/pciehprm_nonacpi.c 2004-06-26 17:09:16 -07:00 @@ -276,7 +276,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -297,11 +297,19 @@ vid, busn, devn, funn); func = pciehp_slot_find(busn, devn, funn); dbg("%s: func = %p\n", __FUNCTION__,func); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + phprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + phprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - phprm_dump_func_res(func); } } } diff -Nru a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c --- a/drivers/pci/hotplug/rpadlpar_core.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pci/hotplug/rpadlpar_core.c 2004-06-26 17:09:18 -07:00 @@ -24,25 +24,6 @@ static DECLARE_MUTEX(rpadlpar_sem); -static inline int is_hotplug_capable(struct device_node *dn) -{ - unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL); - - return (int) (ptr != NULL); -} - -static char *get_node_drc_name(struct device_node *dn) -{ - char *ptr = NULL; - int *drc_names; - - drc_names = (int *) get_property(dn, "ibm,drc-names", NULL); - if (drc_names) - ptr = (char *) &drc_names[1]; - - return ptr; -} - static struct device_node *find_php_slot_vio_node(char *drc_name) { struct device_node *child; @@ -53,9 +34,9 @@ return NULL; for (child = of_get_next_child(parent, NULL); - child; child = of_get_next_child(parent, child)) { + child; child = of_get_next_child(parent, child)) { loc_code = get_property(child, "ibm,loc-code", NULL); - if (loc_code && !strcmp(loc_code, drc_name)) + if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name))) return child; } @@ -69,7 +50,7 @@ while ((np = of_find_node_by_type(np, "pci"))) if (is_hotplug_capable(np)) { - name = get_node_drc_name(np); + name = rpaphp_get_drc_name(np); if (name && (!strcmp(drc_name, name))) break; } @@ -324,6 +305,7 @@ } /* Remove pci bus */ + if (dlpar_pci_remove_bus(bridge_dev)) { printk(KERN_ERR "%s: unable to remove pci bus %s\n", __FUNCTION__, drc_name); @@ -364,7 +346,7 @@ rc = -EINVAL; goto exit; } - + switch (slot->dev_type) { case PCI_DEV: rc = dlpar_remove_pci_slot(slot, drc_name); diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h --- a/drivers/pci/hotplug/rpaphp.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/pci/hotplug/rpaphp.h 2004-06-26 17:09:17 -07:00 @@ -30,6 +30,9 @@ #include #include "pci_hotplug.h" +#define HOTPLUG 1 +#define EMBEDDED 0 + #define DR_INDICATOR 9002 #define DR_ENTITY_SENSE 9003 @@ -73,6 +76,11 @@ #define CONFIGURED 1 #define EMPTY 0 +struct rpaphp_pci_func { + struct pci_dev *pci_dev; + struct list_head sibling; +}; + /* * struct slot - slot information for each *physical* slot */ @@ -83,14 +91,13 @@ u32 power_domain; char *name; char *location; + u8 removable; struct device_node *dn; /* slot's device_node in OFDT */ - /* dn has phb info */ + /* dn has phb info */ struct pci_dev *bridge; /* slot's pci_dev in pci_devices */ union { - struct pci_dev *pci_dev; /* pci_dev of device in this slot */ - /* it will be used for unconfig */ - /* NULL if slot is empty */ - struct vio_dev *vio_dev; /* vio_dev of the device in this slot */ + struct list_head pci_funcs; /* pci_devs in PCI slot */ + struct vio_dev *vio_dev; /* vio_dev in VIO slot */ } dev; u8 dev_type; /* VIO or PCI */ struct hotplug_slot *hotplug_slot; @@ -101,6 +108,13 @@ extern struct list_head rpaphp_slot_head; extern int num_slots; +static inline int is_hotplug_capable(struct device_node *dn) +{ + unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL); + + return (int) (ptr != NULL); +} + /* function prototypes */ /* rpaphp_pci.c */ @@ -110,10 +124,12 @@ extern int register_pci_slot(struct slot *slot); extern int rpaphp_unconfig_pci_adapter(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); +extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); extern int rpaphp_remove_slot(struct slot *slot); +extern char *rpaphp_get_drc_name(struct device_node *dn); /* rpaphp_vio.c */ extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value); @@ -125,8 +141,8 @@ extern void dealloc_slot_struct(struct slot *slot); extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); extern int register_slot(struct slot *slot); +extern int deregister_slot(struct slot *slot); extern int rpaphp_get_power_status(struct slot *slot, u8 * value); extern int rpaphp_set_attention_status(struct slot *slot, u8 status); -extern void rpaphp_sysfs_remove_attr_location(struct hotplug_slot *slot); #endif /* _PPC64PHP_H */ diff -Nru a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c --- a/drivers/pci/hotplug/rpaphp_core.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/pci/hotplug/rpaphp_core.c 2004-06-26 17:09:21 -07:00 @@ -54,6 +54,8 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +void eeh_register_disable_func(int (*)(struct pci_dev *)); + module_param(debug, bool, 0644); static int enable_slot(struct hotplug_slot *slot); @@ -63,6 +65,7 @@ static int get_attention_status(struct hotplug_slot *slot, u8 * value); static int get_adapter_status(struct hotplug_slot *slot, u8 * value); static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); +static int rpaphp_disable_slot(struct pci_dev *dev); struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .owner = THIS_MODULE, @@ -89,7 +92,7 @@ */ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) { - int retval; + int retval = 0; struct slot *slot = (struct slot *)hotplug_slot->private; down(&rpaphp_sem); @@ -208,47 +211,53 @@ int rpaphp_remove_slot(struct slot *slot) { - int retval = 0; - struct hotplug_slot *php_slot = slot->hotplug_slot; - - list_del(&slot->rpaphp_slot_list); - - /* remove "php_location" file */ - rpaphp_sysfs_remove_attr_location(php_slot); - - retval = pci_hp_deregister(php_slot); - if (retval) - err("Problem unregistering a slot %s\n", slot->name); - - num_slots--; - - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); - return retval; + return deregister_slot(slot); } -static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types, - int **power_domains) +static int get_dn_properties(struct device_node *dn, int **indexes, int **names, + int **types, int **power_domains) { *indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL); - if (!*indexes) - return 0; + /* &names[1] contains NULL terminated slot names */ *names = (int *) get_property(dn, "ibm,drc-names", NULL); - if (!*names) - return 0; + /* &types[1] contains NULL terminated slot types */ *types = (int *) get_property(dn, "ibm,drc-types", NULL); - if (!*types) - return 0; + /* power_domains[1...n] are the slot power domains */ - *power_domains = (int *) get_property(dn, - "ibm,drc-power-domains", NULL); - if (!*power_domains) - return 0; - if (strcmp(dn->name, "pci") == 0 && - !get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL)) - return 0; - return 1; + *power_domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL); + + if (*indexes && *names && *types && *power_domains) + return (1); + + return (0); +} + +static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types, + int **power_domains) +{ + if (!is_hotplug_capable(dn)) + return (0); + if (!get_dn_properties(dn, indexes, names, types, power_domains)) + return (0); + return (1); +} + +static int is_dr_dn(struct device_node *dn, int **indexes, int **names, int **types, + int **power_domains, int **my_drc_index) +{ + if (!is_hotplug_capable(dn)) + return (0); + + *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL); + if(!*my_drc_index) + return (0); + + if (!dn->parent) + return (0); + + return get_dn_properties(dn->parent, indexes, names, types, power_domains); } static inline int is_vdevice_root(struct device_node *dn) @@ -256,15 +265,48 @@ return !strcmp(dn->name, "vdevice"); } -/** - * rpaphp_add_slot: Add Hot Plug slot(s) to sysfs - * - */ +char *rpaphp_get_drc_name(struct device_node *dn) +{ + char *name, *ptr = NULL; + int *drc_names, *drc_indexes, i; + struct device_node *parent = dn->parent; + u32 *my_drc_index; + + if (!parent) + return NULL; + + my_drc_index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL); + if (!my_drc_index) + return NULL; + + drc_names = (int *) get_property(parent, "ibm,drc-names", NULL); + drc_indexes = (int *) get_property(parent, "ibm,drc-indexes", NULL); + if (!drc_names || !drc_indexes) + return NULL; + + name = (char *) &drc_names[1]; + for (i = 0; i < drc_indexes[0]; i++, name += (strlen(name) + 1)) { + if (drc_indexes[i + 1] == *my_drc_index) { + ptr = (char *) name; + break; + } + } + + return ptr; +} + +/**************************************************************** + * rpaphp not only registers PCI hotplug slots(HOTPLUG), + * but also logical DR slots(EMBEDDED). + * HOTPLUG slot: An adapter can be physically added/removed. + * EMBEDDED slot: An adapter can be logically removed/added + * from/to a partition with the slot. + ***************************************************************/ int rpaphp_add_slot(struct device_node *dn) { struct slot *slot; int retval = 0; - int i; + int i, *my_drc_index, slot_type; int *indexes, *names, *types, *power_domains; char *name, *type; @@ -277,42 +319,65 @@ } /* register PCI devices */ - if (dn->name != 0 && strcmp(dn->name, "pci") == 0 && - is_php_dn(dn, &indexes, &names, &types, &power_domains)) { + if (dn->name != 0 && strcmp(dn->name, "pci") == 0) { + if (is_php_dn(dn, &indexes, &names, &types, &power_domains)) + slot_type = HOTPLUG; + else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index)) + slot_type = EMBEDDED; + else goto exit; name = (char *) &names[1]; type = (char *) &types[1]; - for (i = 0; i < indexes[0]; - i++, - name += (strlen(name) + 1), - type += (strlen(type) + 1)) { - if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, - power_domains[i + 1]))) { - retval = -ENOMEM; - goto exit; - } - slot->type = simple_strtoul(type, NULL, 10); - if (slot->type < 1 || slot->type > 16) - slot->type = 0; - retval = register_pci_slot(slot); + for (i = 0; i < indexes[0]; i++, + name += (strlen(name) + 1), type += (strlen(type) + 1)) { - } /* for indexes */ - } /* end of PCI device_node */ + if ( slot_type == HOTPLUG || + (slot_type == EMBEDDED && indexes[i + 1] == my_drc_index[0])) { + + if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, + power_domains[i + 1]))) { + retval = -ENOMEM; + goto exit; + } + if (slot_type == EMBEDDED) + slot->type = EMBEDDED; + else + slot->type = simple_strtoul(type, NULL, 10); + + dbg(" Found drc-index:0x%x drc-name:%s drc-type:%s\n", + indexes[i + 1], name, type); + + retval = register_pci_slot(slot); + if (slot_type == EMBEDDED) + goto exit; + } + } + } exit: dbg("%s - Exit: num_slots=%d rc[%d]\n", __FUNCTION__, num_slots, retval); return retval; } -static int __init init_rpa(void) +/* + * init_slots - initialize 'struct slot' structures for each slot + * + */ +static void init_slots(void) { struct device_node *dn; + for (dn = find_all_nodes(); dn; dn = dn->next) + rpaphp_add_slot(dn); +} + +static int __init init_rpa(void) +{ + init_MUTEX(&rpaphp_sem); /* initialize internal data structure etc. */ - for (dn = find_all_nodes(); dn; dn = dn->next) - rpaphp_add_slot(dn); + init_slots(); if (!num_slots) return -ENODEV; @@ -342,12 +407,18 @@ { info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + /* let EEH know they can use hotplug */ + eeh_register_disable_func(&rpaphp_disable_slot); + /* read all the PRA info from the system */ return init_rpa(); } static void __exit rpaphp_exit(void) { + /* let EEH know we are going away */ + eeh_register_disable_func(NULL); + cleanup_slots(); } @@ -374,11 +445,16 @@ retval = -EINVAL; } up(&rpaphp_sem); - exit: +exit: dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; } +static int rpaphp_disable_slot(struct pci_dev *dev) +{ + return disable_slot(rpaphp_find_hotplug_slot(dev)); +} + static int disable_slot(struct hotplug_slot *hotplug_slot) { int retval; @@ -395,9 +471,7 @@ down(&rpaphp_sem); switch (slot->dev_type) { case PCI_DEV: - rpaphp_set_attention_status(slot, LED_ID); retval = rpaphp_unconfig_pci_adapter(slot); - rpaphp_set_attention_status(slot, LED_OFF); break; case VIO_DEV: retval = rpaphp_unconfig_vio_adapter(slot); @@ -406,7 +480,7 @@ retval = -ENODEV; } up(&rpaphp_sem); - exit: +exit: dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; } @@ -417,3 +491,4 @@ EXPORT_SYMBOL_GPL(rpaphp_add_slot); EXPORT_SYMBOL_GPL(rpaphp_remove_slot); EXPORT_SYMBOL_GPL(rpaphp_slot_head); +EXPORT_SYMBOL_GPL(rpaphp_get_drc_name); diff -Nru a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c --- a/drivers/pci/hotplug/rpaphp_pci.c 2004-06-26 17:09:14 -07:00 +++ b/drivers/pci/hotplug/rpaphp_pci.c 2004-06-26 17:09:14 -07:00 @@ -30,24 +30,18 @@ struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn) { - struct pci_dev *retval_dev = NULL, *dev; + struct pci_dev *retval_dev = NULL, *dev = NULL; char bus_id[BUS_ID_SIZE]; sprintf(bus_id, "%04x:%02x:%02x.%d",dn->phb->global_number, dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn)); - - dbg("Enter rpaphp_find_pci_dev() full_name=%s bus_id=%s\n", - dn->full_name, bus_id); - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (!strcmp(pci_name(dev), bus_id)) { + if (!strcmp(pci_name(dev), bus_id)) { retval_dev = dev; - dbg("rpaphp_find_pci_dev(): found dev=%p\n\n", dev); break; } } return retval_dev; - } EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev); @@ -79,11 +73,6 @@ return rpaphp_find_pci_dev(slot->dn); } -static struct pci_dev *rpaphp_find_adapter_pdev(struct slot *slot) -{ - return rpaphp_find_pci_dev(slot->dn->child); -} - static int rpaphp_get_sensor_state(struct slot *slot, int *state) { int rc; @@ -144,7 +133,8 @@ else if (rpaphp_find_pci_dev(slot->dn->child)) *value = CONFIGURED; else { - dbg("%s: can't find pdev of adapter in slot[%s]\n", __FUNCTION__, slot->name); + err("%s: can't find pdev of adapter in slot[%s]\n", + __FUNCTION__, slot->dn->full_name); *value = NOT_CONFIGURED; } } @@ -158,7 +148,8 @@ } /* Must be called before pci_bus_add_devices */ -static void rpaphp_fixup_new_pci_devices(struct pci_bus *bus) +static void +rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) { struct pci_dev *dev; @@ -169,8 +160,9 @@ */ if (list_empty(&dev->global_list)) { int i; - - pcibios_fixup_device_resources(dev, bus); + + if(fix_bus) + pcibios_fixup_device_resources(dev, bus); pci_read_irq_line(dev); for (i = 0; i < PCI_NUM_RESOURCES; i++) { struct resource *r = &dev->resource[i]; @@ -183,69 +175,139 @@ } } -static void -rpaphp_pci_config_device(struct pci_bus *pci_bus, struct device_node *dn) -{ - int num; - - num = pci_scan_slot(pci_bus, PCI_DEVFN(PCI_SLOT(dn->devfn), 0)); - if (num) { - rpaphp_fixup_new_pci_devices(pci_bus); - pci_bus_add_devices(pci_bus); - } -} - -static int rpaphp_pci_config_bridge(struct pci_dev *dev, struct device_node *dn); +static int rpaphp_pci_config_bridge(struct pci_dev *dev); /***************************************************************************** - rpaphp_pci_config_dn() will recursively configure all devices under the - given slot->dn and return the dn's pci_dev. + rpaphp_pci_config_slot() will configure all devices under the + given slot->dn and return the the first pci_dev. *****************************************************************************/ static struct pci_dev * -rpaphp_pci_config_dn(struct device_node *dn, struct pci_bus *bus) +rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus) { - struct device_node *local; + struct device_node *eads_first_child = dn->child; struct pci_dev *dev; + int num; + + dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); - for (local = dn->child; local; local = local->sibling) { - rpaphp_pci_config_device(bus, local); - dev = rpaphp_find_pci_dev(local); - if (!rpaphp_pci_config_bridge(dev, local)) + if (eads_first_child) { + /* pci_scan_slot should find all children of EADs */ + num = pci_scan_slot(bus, PCI_DEVFN(PCI_SLOT(eads_first_child->devfn), 0)); + if (num) { + rpaphp_fixup_new_pci_devices(bus, 1); + pci_bus_add_devices(bus); + } + dev = rpaphp_find_pci_dev(eads_first_child); + if (!dev) { + err("No new device found\n"); return NULL; + } + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + rpaphp_pci_config_bridge(dev); } - return dev; } -static int rpaphp_pci_config_bridge(struct pci_dev *dev, struct device_node *dn) +static int rpaphp_pci_config_bridge(struct pci_dev *dev) { - if (dev && dn->child) { /* dn is a PCI bridge node */ - struct pci_bus *child; - u8 sec_busno; - - /* get busno of downstream bus */ - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); - - /* add to children of PCI bridge dev->bus */ - child = pci_add_new_bus(dev->bus, dev, sec_busno); - if (!child) { - err("%s: could not add second bus\n", __FUNCTION__); - return 0; - } - sprintf(child->name, "PCI Bus #%02x", child->number); - /* Fixup subordinate bridge bases and resureces */ - pcibios_fixup_bus(child); + u8 sec_busno; + struct pci_bus *child_bus; + struct pci_dev *child_dev; + + dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); - /* may need do more stuff here */ - rpaphp_pci_config_dn(dn, dev->subordinate); + /* get busno of downstream bus */ + pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); + + /* add to children of PCI bridge dev->bus */ + child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); + if (!child_bus) { + err("%s: could not add second bus\n", __FUNCTION__); + return -EIO; } - return 1; + sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); + /* do pci_scan_child_bus */ + pci_scan_child_bus(child_bus); + + list_for_each_entry(child_dev, &child_bus->devices, bus_list) { + eeh_add_device_late(child_dev); + } + + /* fixup new pci devices without touching bus struct */ + rpaphp_fixup_new_pci_devices(child_bus, 0); + + /* Make the discovered devices available */ + pci_bus_add_devices(child_bus); + return 0; +} + +static void enable_eeh(struct device_node *dn) +{ + struct device_node *sib; + + for (sib = dn->child; sib; sib = sib->sibling) + enable_eeh(sib); + eeh_add_device_early(dn); + return; + +} + +#ifdef DEBUG +static void print_slot_pci_funcs(struct slot *slot) +{ + struct list_head *l; + + if (slot->dev_type == PCI_DEV) { + printk("pci_funcs of slot[%s]\n", slot->name); + if (list_empty(&slot->dev.pci_funcs)) + printk(" pci_funcs is EMPTY\n"); + + list_for_each (l, &slot->dev.pci_funcs) { + struct rpaphp_pci_func *func = + list_entry(l, struct rpaphp_pci_func, sibling); + printk(" FOUND dev=%s\n", pci_name(func->pci_dev)); + } + } + return; +} +#else +static void print_slot_pci_funcs(struct slot *slot) +{ + return; +} +#endif + +static int init_slot_pci_funcs(struct slot *slot) +{ + struct device_node *child; + + for (child = slot->dn->child; child != NULL; child = child->sibling) { + struct pci_dev *pdev = rpaphp_find_pci_dev(child); + + if (pdev) { + struct rpaphp_pci_func *func; + func = kmalloc(sizeof(struct rpaphp_pci_func), GFP_KERNEL); + if (!func) + return -ENOMEM; + memset(func, 0, sizeof(struct rpaphp_pci_func)); + INIT_LIST_HEAD(&func->sibling); + func->pci_dev = pdev; + list_add_tail(&func->sibling, &slot->dev.pci_funcs); + print_slot_pci_funcs(slot); + } else { + err("%s: dn=%s has no pci_dev\n", + __FUNCTION__, child->full_name); + return -EIO; + } + } + return 0; } -static struct pci_dev *rpaphp_config_pci_adapter(struct slot *slot) +static int rpaphp_config_pci_adapter(struct slot *slot) { struct pci_bus *pci_bus; - struct pci_dev *dev = NULL; + struct pci_dev *dev; + int rc = -ENODEV; dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name); @@ -256,38 +318,74 @@ err("%s: can't find bus structure\n", __FUNCTION__); goto exit; } - - eeh_add_device_early(slot->dn->child); - dev = rpaphp_pci_config_dn(slot->dn, pci_bus); - eeh_add_device_late(dev); + enable_eeh(slot->dn); + dev = rpaphp_pci_config_slot(slot->dn, pci_bus); + if (!dev) { + err("%s: can't find any devices.\n", __FUNCTION__); + goto exit; + } + /* associate corresponding pci_dev */ + rc = init_slot_pci_funcs(slot); + if (rc) + goto exit; + print_slot_pci_funcs(slot); + if (!list_empty(&slot->dev.pci_funcs)) + rc = 0; } else { /* slot is not enabled */ err("slot doesn't have pci_dev structure\n"); - dev = NULL; } - exit: - dbg("Exit %s: pci_dev %s\n", __FUNCTION__, dev ? "found" : "not found"); - return dev; + dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); + return rc; +} + + +static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) +{ + eeh_remove_device(dev); + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + struct pci_bus *bus = dev->subordinate; + struct list_head *ln; + if (!bus) + return; + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *pdev = pci_dev_b(ln); + if (pdev) + rpaphp_eeh_remove_bus_device(pdev); + } + + } + return; } int rpaphp_unconfig_pci_adapter(struct slot *slot) { int retval = 0; + struct list_head *ln; dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name); - if (!slot->dev.pci_dev) { - info("%s: no card in slot[%s]\n", __FUNCTION__, slot->name); + if (list_empty(&slot->dev.pci_funcs)) { + err("%s: slot[%s] doesn't have any devices.\n", __FUNCTION__, + slot->name); retval = -EINVAL; goto exit; } - /* remove the device from the pci core */ - eeh_remove_device(slot->dev.pci_dev); - pci_remove_bus_device(slot->dev.pci_dev); - + /* remove the devices from the pci core */ + list_for_each (ln, &slot->dev.pci_funcs) { + struct rpaphp_pci_func *func; + + func = list_entry(ln, struct rpaphp_pci_func, sibling); + if (func->pci_dev) { + rpaphp_eeh_remove_bus_device(func->pci_dev); + pci_remove_bus_device(func->pci_dev); + } + kfree(func); + } + INIT_LIST_HEAD(&slot->dev.pci_funcs); slot->state = NOT_CONFIGURED; - info("%s: adapter in slot[%s] unconfigured.\n", __FUNCTION__, + info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, slot->name); exit: dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval); @@ -303,7 +401,7 @@ &slot->hotplug_slot->info-> adapter_status); if (slot->hotplug_slot->info->adapter_status == NOT_VALID) { - dbg("%s: NOT_VALID: skip dn->full_name=%s\n", + err("%s: NOT_VALID: skip dn->full_name=%s\n", __FUNCTION__, slot->dn->full_name); return -1; } @@ -314,35 +412,41 @@ { slot->bridge = rpaphp_find_bridge_pdev(slot); if (!slot->bridge) { /* slot being added doesn't have pci_dev yet */ - dbg("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name); - dealloc_slot_struct(slot); - return 1; + err("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name); + goto exit_rc; } - + dbg("%s set slot->name to %s\n", __FUNCTION__, pci_name(slot->bridge)); strcpy(slot->name, pci_name(slot->bridge)); + /* find slot's pci_dev if it's not empty */ if (slot->hotplug_slot->info->adapter_status == EMPTY) { slot->state = EMPTY; /* slot is empty */ - slot->dev.pci_dev = NULL; } else { /* slot is occupied */ if (!(slot->dn->child)) { /* non-empty slot has to have child */ - err("%s: slot[%s]'s device_node doesn't have child for adapter\n", __FUNCTION__, slot->name); - dealloc_slot_struct(slot); - return 1; + err("%s: slot[%s]'s device_node doesn't have child for adapter\n", + __FUNCTION__, slot->name); + goto exit_rc; + } + if (init_slot_pci_funcs(slot)) { + err("%s: init_slot_pci_funcs failed\n", __FUNCTION__); + goto exit_rc; } - slot->dev.pci_dev = rpaphp_find_adapter_pdev(slot); - if (slot->dev.pci_dev) { + print_slot_pci_funcs(slot); + if (!list_empty(&slot->dev.pci_funcs)) { slot->state = CONFIGURED; - + } else { /* DLPAR add as opposed to - * boot time */ + * boot time */ slot->state = NOT_CONFIGURED; } } return 0; +exit_rc: + dealloc_slot_struct(slot); + return 1; } int register_pci_slot(struct slot *slot) @@ -350,14 +454,17 @@ int rc = 1; slot->dev_type = PCI_DEV; + if (slot->type == EMBEDDED) + slot->removable = EMBEDDED; + else + slot->removable = HOTPLUG; + INIT_LIST_HEAD(&slot->dev.pci_funcs); if (setup_pci_hotplug_slot_info(slot)) goto exit_rc; if (setup_pci_slot(slot)) goto exit_rc; rc = register_slot(slot); exit_rc: - if (rc) - dealloc_slot_struct(slot); return rc; } @@ -371,12 +478,12 @@ dbg("%s: sensor state[%d]\n", __FUNCTION__, state); /* if slot is not empty, enable the adapter */ if (state == PRESENT) { - dbg("%s : slot[%s] is occupid.\n", __FUNCTION__, slot->name); - if ((slot->dev.pci_dev = - rpaphp_config_pci_adapter(slot)) != NULL) { + dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); + retval = rpaphp_config_pci_adapter(slot); + if (!retval) { slot->state = CONFIGURED; - dbg("%s: PCI adapter %s in slot[%s] has been configured\n", - __FUNCTION__, pci_name(slot->dev.pci_dev), slot->name); + dbg("%s: PCI devices in slot[%s] has been configured\n", + __FUNCTION__, slot->name); } else { slot->state = NOT_CONFIGURED; dbg("%s: no pci_dev struct for adapter in slot[%s]\n", @@ -392,10 +499,31 @@ retval = -EINVAL; } exit: - if (slot->state != NOT_VALID) - rpaphp_set_attention_status(slot, LED_ON); - else - rpaphp_set_attention_status(slot, LED_ID); dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; } + +struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev) +{ + struct list_head *tmp, *n; + struct slot *slot; + + list_for_each_safe(tmp, n, &rpaphp_slot_head) { + struct pci_bus *bus; + struct list_head *ln; + + slot = list_entry(tmp, struct slot, rpaphp_slot_list); + bus = slot->bridge->subordinate; + if (!bus) + return NULL; /* shouldn't be here */ + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *pdev = pci_dev_b(ln); + if (pdev == dev) + return slot->hotplug_slot; + } + } + + return NULL; +} + +EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot); diff -Nru a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c --- a/drivers/pci/hotplug/rpaphp_slot.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pci/hotplug/rpaphp_slot.c 2004-06-26 17:09:18 -07:00 @@ -29,6 +29,35 @@ #include #include "rpaphp.h" +static ssize_t removable_read_file (struct hotplug_slot *php_slot, char *buf) +{ + u8 value; + int retval = -ENOENT; + struct slot *slot = (struct slot *)php_slot->private; + + if (!slot) + return retval; + + value = slot->removable; + retval = sprintf (buf, "%d\n", value); + return retval; +} + +static struct hotplug_slot_attribute hotplug_slot_attr_removable = { + .attr = {.name = "phy_removable", .mode = S_IFREG | S_IRUGO}, + .show = removable_read_file, +}; + +static void rpaphp_sysfs_add_attr_removable (struct hotplug_slot *slot) +{ + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_removable.attr); +} + +static void rpaphp_sysfs_remove_attr_removable (struct hotplug_slot *slot) +{ + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_removable.attr); +} + static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) { char *value; @@ -53,7 +82,7 @@ sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr); } -void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) +static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) { sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr); } @@ -68,6 +97,17 @@ void dealloc_slot_struct(struct slot *slot) { + struct list_head *ln, *n; + + if (slot->dev_type == PCI_DEV) { + list_for_each_safe (ln, n, &slot->dev.pci_funcs) { + struct rpaphp_pci_func *func; + + func = list_entry(ln, struct rpaphp_pci_func, sibling); + kfree(func); + } + } + kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); @@ -86,7 +126,7 @@ memset(slot, 0, sizeof (struct slot)); slot->hotplug_slot = kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL); if (!slot->hotplug_slot) - goto error_slot; + goto error_slot; memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot)); slot->hotplug_slot->info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); @@ -95,7 +135,7 @@ memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info)); slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL); if (!slot->hotplug_slot->name) - goto error_info; + goto error_info; slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); if (!slot->location) goto error_name; @@ -107,9 +147,8 @@ slot->hotplug_slot->private = slot; slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops; slot->hotplug_slot->release = &rpaphp_release_slot; - slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; - - return slot; + + return (slot); error_name: kfree(slot->hotplug_slot->name); @@ -123,15 +162,56 @@ return NULL; } +static int is_registered(struct slot *slot) +{ + struct slot *tmp_slot; + + list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) { + if (!strcmp(tmp_slot->name, slot->name)) + return 1; + } + return 0; +} + +int deregister_slot(struct slot *slot) +{ + int retval = 0; + struct hotplug_slot *php_slot = slot->hotplug_slot; + + dbg("%s - Entry: deregistering slot=%s\n", + __FUNCTION__, slot->name); + + list_del(&slot->rpaphp_slot_list); + + /* remove "phy_location" file */ + rpaphp_sysfs_remove_attr_location(php_slot); + + /* remove "phy_removable" file */ + rpaphp_sysfs_remove_attr_removable(php_slot); + + retval = pci_hp_deregister(php_slot); + if (retval) + err("Problem unregistering a slot %s\n", slot->name); + else + num_slots--; + + dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); + return retval; +} + int register_slot(struct slot *slot) { int retval; - char *vio_uni_addr = NULL; - dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", - __FUNCTION__, slot->dn->full_name, slot->index, slot->name, + dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", + __FUNCTION__, slot->dn->full_name, slot->index, slot->name, slot->power_domain, slot->type); - + /* should not try to register the same slot twice */ + if (is_registered(slot)) { /* should't be here */ + err("register_slot: slot[%s] is already registered\n", slot->name); + rpaphp_release_slot(slot->hotplug_slot); + return 1; + } retval = pci_hp_register(slot->hotplug_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); @@ -142,30 +222,40 @@ /* create "phy_locatoin" file */ rpaphp_sysfs_add_attr_location(slot->hotplug_slot); + /* create "phy_removable" file */ + rpaphp_sysfs_add_attr_removable(slot->hotplug_slot); + /* add slot to our internal list */ dbg("%s adding slot[%s] to rpaphp_slot_list\n", __FUNCTION__, slot->name); list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); - if (vio_uni_addr) - info("Slot [%s](vio_uni_addr=%s) registered\n", - slot->name, vio_uni_addr); + if (slot->dev_type == VIO_DEV) + info("Slot [%s](VIO location=%s) registered\n", + slot->name, slot->location); else - info("Slot [%s](bus_id=%s) registered\n", - slot->name, pci_name(slot->bridge)); + info("Slot [%s](PCI location=%s) registered\n", + slot->name, slot->location); num_slots++; return 0; } int rpaphp_get_power_status(struct slot *slot, u8 * value) { - int rc; - - rc = rtas_get_power_level(slot->power_domain, (int *) value); - if (rc) - err("failed to get power-level for slot(%s), rc=0x%x\n", - slot->name, rc); + int rc = 0; + + if (slot->type == EMBEDDED) { + dbg("%s set to POWER_ON for EMBEDDED slot %s\n", + __FUNCTION__, slot->location); + *value = POWER_ON; + } + else { + rc = rtas_get_power_level(slot->power_domain, (int *) value); + if (rc) + err("failed to get power-level for slot(%s), rc=0x%x\n", + slot->location, rc); + } return rc; } @@ -177,8 +267,8 @@ /* status: LED_OFF or LED_ON */ rc = rtas_set_indicator(DR_INDICATOR, slot->index, status); if (rc) - err("slot(%s) set attention-status(%d) failed! rc=0x%x\n", - slot->name, status, rc); + err("slot(name=%s location=%s index=0x%x) set attention-status(%d) failed! rc=0x%x\n", + slot->name, slot->location, slot->index, status, rc); return rc; } diff -Nru a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c --- a/drivers/pci/hotplug/rpaphp_vio.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/pci/hotplug/rpaphp_vio.c 2004-06-26 17:09:19 -07:00 @@ -74,11 +74,11 @@ int rc = 1; struct slot *slot = NULL; + name = rpaphp_get_drc_name(dn); + if (!name) + goto exit_rc; index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL); if (!index) - goto exit_rc; - name = get_property(dn, "ibm,loc-code", NULL); - if (!name) goto exit_rc; if (!(slot = alloc_slot_struct(dn, *index, name, 0))) { rc = -ENOMEM; diff -Nru a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h --- a/drivers/pci/hotplug/shpchp.h 2004-06-26 17:09:19 -07:00 +++ b/drivers/pci/hotplug/shpchp.h 2004-06-26 17:09:19 -07:00 @@ -61,6 +61,7 @@ u8 configured; u8 switch_save; u8 presence_save; + u8 pwr_save; u32 base_length[0x06]; u8 base_type[0x06]; u16 reserved2; diff -Nru a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c --- a/drivers/pci/hotplug/shpchp_ctrl.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/pci/hotplug/shpchp_ctrl.c 2004-06-26 17:09:21 -07:00 @@ -137,6 +137,8 @@ p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + dbg("%s: Card present %x Power status %x\n", __FUNCTION__, + func->presence_save, func->pwr_save); if (getstatus) { /* @@ -145,6 +147,10 @@ info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); func->switch_save = 0; taskInfo->event_type = INT_SWITCH_OPEN; + if (func->pwr_save && func->presence_save) { + taskInfo->event_type = INT_POWER_FAULT; + err("Surprise Removal of card\n"); + } } else { /* * Switch closed @@ -1427,6 +1433,7 @@ rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed); if (rc) { err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } @@ -1438,6 +1445,7 @@ err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", __FUNCTION__); err("%s: Error code (%d)\n", __FUNCTION__, rc); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } /* Done with exclusive hardware access */ @@ -1589,8 +1597,9 @@ func->status = 0; func->switch_save = 0x10; func->is_a_board = 0x01; + func->pwr_save = 1; - /* next, we will instantiate the linux pci_dev structures + /* Next, we will instantiate the linux pci_dev structures * (with appropriate driver notification, if already present) */ index = 0; @@ -1781,6 +1790,7 @@ func->function = 0; func->configured = 0; func->switch_save = 0x10; + func->pwr_save = 0; func->is_a_board = 0; } @@ -1807,7 +1817,6 @@ { struct slot *p_slot = (struct slot *) slot; u8 getstatus; - int rc; pushbutton_pending = 0; @@ -1821,23 +1830,7 @@ p_slot->state = POWEROFF_STATE; dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); - if (shpchp_disable_slot(p_slot)) { - /* Wait for exclusive access to hardware */ - down(&p_slot->ctrl->crit_sect); - - /* Turn on the Attention LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - - /* Done with exclusive hardware access */ - up(&p_slot->ctrl->crit_sect); - } + shpchp_disable_slot(p_slot); p_slot->state = STATIC_STATE; } else { p_slot->state = POWERON_STATE; @@ -1847,15 +1840,6 @@ /* Wait for exclusive access to hardware */ down(&p_slot->ctrl->crit_sect); - /* Turn off the green LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - p_slot->hpc_ops->green_led_off(p_slot); /* Wait for the command to complete */ @@ -2096,7 +2080,7 @@ func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); if (!func) { dbg("%s: Error! slot NULL\n", __FUNCTION__); - return (1); + return 1; } /* Check to see if (latch closed, card present, power off) */ @@ -2105,19 +2089,19 @@ if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } up(&p_slot->ctrl->crit_sect); @@ -2125,7 +2109,7 @@ func = shpchp_slot_create(p_slot->bus); if (func == NULL) - return (1); + return 1; func->bus = p_slot->bus; func->device = p_slot->device; @@ -2135,6 +2119,8 @@ /* We have to save the presence info for these slots */ p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); + p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save)); + dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); func->switch_save = !getstatus? 0x10:0; @@ -2181,7 +2167,7 @@ struct pci_func *func; if (!p_slot->ctrl) - return (1); + return 1; /* Check to see if (latch closed, card present, power on) */ down(&p_slot->ctrl->crit_sect); @@ -2190,19 +2176,19 @@ if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } up(&p_slot->ctrl->crit_sect); diff -Nru a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c --- a/drivers/pci/hotplug/shpchp_pci.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pci/hotplug/shpchp_pci.c 2004-06-26 17:09:18 -07:00 @@ -263,6 +263,7 @@ new_slot->function = (u8) function; new_slot->is_a_board = 1; new_slot->switch_save = 0x10; + new_slot->pwr_save = 1; /* In case of unsupported board */ new_slot->status = DevError; new_slot->pci_dev = pci_find_slot(new_slot->bus, diff -Nru a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c --- a/drivers/pci/hotplug/shpchprm_acpi.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/pci/hotplug/shpchprm_acpi.c 2004-06-26 17:09:17 -07:00 @@ -218,6 +218,10 @@ } ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); + if (!ab->_hpp) { + err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name); + goto free_and_return; + } memset(ab->_hpp, 0, sizeof(struct acpi__hpp)); ab->_hpp->cache_line_size = nui[0]; @@ -1391,7 +1395,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->bus; int devn, funn; u32 vid; @@ -1406,11 +1410,19 @@ if (vid != 0xFFFFFFFF) { func = shpchp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + shpchprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + shpchprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - shpchprm_dump_func_res(func); } } } diff -Nru a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c --- a/drivers/pci/hotplug/shpchprm_nonacpi.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/pci/hotplug/shpchprm_nonacpi.c 2004-06-26 17:09:15 -07:00 @@ -208,7 +208,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -226,11 +226,19 @@ if (vid != 0xFFFFFFFF) { func = shpchp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + phprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + phprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - phprm_dump_func_res(func); } } } diff -Nru a/drivers/pci/msi.c b/drivers/pci/msi.c --- a/drivers/pci/msi.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/pci/msi.c 2004-06-26 17:09:20 -07:00 @@ -569,7 +569,7 @@ struct msi_desc *entry; struct msg_address address; struct msg_data data; - int vector = 0, pos, dev_msi_cap; + int vector = 0, pos, dev_msi_cap, i; u32 phys_addr, table_offset; u32 control; u8 bir; @@ -629,12 +629,12 @@ writel(address.hi_address, base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); writel(*(u32*)&data, base + PCI_MSIX_ENTRY_DATA_OFFSET); /* Initialize all entries from 1 up to 0 */ - for (pos = 1; pos < dev_msi_cap; pos++) { - writel(0, base + pos * PCI_MSIX_ENTRY_SIZE + + for (i = 1; i < dev_msi_cap; i++) { + writel(0, base + i * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(0, base + pos * PCI_MSIX_ENTRY_SIZE + + writel(0, base + i * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(0, base + pos * PCI_MSIX_ENTRY_SIZE + + writel(0, base + i * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_DATA_OFFSET); } attach_msi_entry(entry, vector); diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c --- a/drivers/pci/pci-driver.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/pci/pci-driver.c 2004-06-26 17:09:19 -07:00 @@ -539,6 +539,7 @@ .hotplug = pci_hotplug, .suspend = pci_device_suspend, .resume = pci_device_resume, + .dev_attrs = pci_dev_attrs, }; static int __init pci_driver_init(void) diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c --- a/drivers/pci/pci-sysfs.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pci/pci-sysfs.c 2004-06-26 17:09:18 -07:00 @@ -23,14 +23,13 @@ /* show configuration fields */ #define pci_config_attr(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, char *buf) \ +field##_show(struct device *dev, char *buf) \ { \ struct pci_dev *pdev; \ \ pdev = to_pci_dev (dev); \ return sprintf (buf, format_string, pdev->field); \ -} \ -static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); +} pci_config_attr(vendor, "0x%04x\n"); pci_config_attr(device, "0x%04x\n"); @@ -41,7 +40,7 @@ /* show resources */ static ssize_t -pci_show_resources(struct device * dev, char * buf) +resource_show(struct device * dev, char * buf) { struct pci_dev * pci_dev = to_pci_dev(dev); char * str = buf; @@ -60,7 +59,16 @@ return (str - buf); } -static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL); +struct device_attribute pci_dev_attrs[] = { + __ATTR_RO(resource), + __ATTR_RO(vendor), + __ATTR_RO(device), + __ATTR_RO(subsystem_vendor), + __ATTR_RO(subsystem_device), + __ATTR_RO(class), + __ATTR_RO(irq), + __ATTR_NULL, +}; static ssize_t pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) @@ -180,21 +188,10 @@ void pci_create_sysfs_dev_files (struct pci_dev *pdev) { - struct device *dev = &pdev->dev; - - /* current configuration's attributes */ - device_create_file (dev, &dev_attr_vendor); - device_create_file (dev, &dev_attr_device); - device_create_file (dev, &dev_attr_subsystem_vendor); - device_create_file (dev, &dev_attr_subsystem_device); - device_create_file (dev, &dev_attr_class); - device_create_file (dev, &dev_attr_irq); - device_create_file (dev, &dev_attr_resource); - if (pdev->cfg_size < 4096) - sysfs_create_bin_file(&dev->kobj, &pci_config_attr); + sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); else - sysfs_create_bin_file(&dev->kobj, &pcie_config_attr); + sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); /* add platform-specific attributes */ pcibios_add_platform_entries(pdev); diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/pci/pci.c 2004-06-26 17:09:16 -07:00 @@ -442,7 +442,7 @@ pci_read_config_word(dev,pm+PCI_PM_PMC,&value); value &= PCI_PM_CAP_PME_MASK; - value >>= ffs(value); /* First bit of mask */ + value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ /* Check if it can generate PME# from requested state. */ if (!value || !(value & (1 << state))) diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h --- a/drivers/pci/pci.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/pci/pci.h 2004-06-26 17:09:17 -07:00 @@ -62,3 +62,4 @@ extern spinlock_t pci_bus_lock; extern int pciehp_msi_quirk; +extern struct device_attribute pci_dev_attrs[]; diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c --- a/drivers/pci/quirks.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/pci/quirks.c 2004-06-26 17:09:15 -07:00 @@ -705,6 +705,7 @@ } if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) switch(dev->subsystem_device) { + case 0x80b1: /* P4GE-V */ case 0x80b2: /* P4PE */ case 0x8093: /* P4B533-V */ asus_hides_smbus = 1; diff -Nru a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig --- a/drivers/pcmcia/Kconfig 2004-06-26 17:09:19 -07:00 +++ b/drivers/pcmcia/Kconfig 2004-06-26 17:09:19 -07:00 @@ -69,6 +69,13 @@ depends on YENTA default y if YENTA +config PD6729 + tristate "Cirrus PD6729 compatible bridge support" + depends on PCMCIA && PCI + help + This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge + device, found in some older laptops and PCMCIA card readers. + config I82092 tristate "i82092 compatible bridge support" depends on PCMCIA && PCI diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile --- a/drivers/pcmcia/Makefile 2004-06-26 17:09:19 -07:00 +++ b/drivers/pcmcia/Makefile 2004-06-26 17:09:19 -07:00 @@ -9,6 +9,7 @@ obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o obj-$(CONFIG_YENTA) += yenta_socket.o +obj-$(CONFIG_PD6729) += pd6729.o obj-$(CONFIG_I82365) += i82365.o obj-$(CONFIG_I82092) += i82092.o obj-$(CONFIG_TCIC) += tcic.o diff -Nru a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c --- a/drivers/pcmcia/cistpl.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/pcmcia/cistpl.c 2004-06-26 17:09:17 -07:00 @@ -85,13 +85,15 @@ void release_cis_mem(struct pcmcia_socket *s) { - if (s->cis_mem.sys_start != 0) { + if (s->cis_mem.flags & MAP_ACTIVE) { s->cis_mem.flags &= ~MAP_ACTIVE; s->ops->set_mem_map(s, &s->cis_mem); - if (!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(s->cis_mem.sys_start, s->map_size); + if (s->cis_mem.res) { + release_resource(s->cis_mem.res); + kfree(s->cis_mem.res); + s->cis_mem.res = NULL; + } iounmap(s->cis_virt); - s->cis_mem.sys_start = 0; s->cis_virt = NULL; } } @@ -105,17 +107,16 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) { pccard_mem_map *mem = &s->cis_mem; - if (!(s->features & SS_CAP_STATIC_MAP) && - mem->sys_start == 0) { - validate_mem(s); - mem->sys_start = 0; - if (find_mem_region(&mem->sys_start, s->map_size, - s->map_size, 0, "card services", s)) { + if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { + mem->res = find_mem_region(0, s->map_size, s->map_size, 0, + "card services", s); + if (mem->res == NULL) { printk(KERN_NOTICE "cs: unable to map card memory!\n"); return NULL; } - mem->sys_stop = mem->sys_start+s->map_size-1; - s->cis_virt = ioremap(mem->sys_start, s->map_size); + mem->sys_start = mem->res->start; + mem->sys_stop = mem->res->end; + s->cis_virt = ioremap(mem->res->start, s->map_size); } mem->card_start = card_offset; mem->flags = flags; diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c --- a/drivers/pcmcia/cs.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/pcmcia/cs.c 2004-06-26 17:09:16 -07:00 @@ -1100,8 +1100,8 @@ if (w == MAX_WIN) return CS_NO_MORE_ITEMS; win = &s->win[w]; - req->Base = win->ctl.sys_start; - req->Size = win->ctl.sys_stop - win->ctl.sys_start + 1; + req->Base = win->ctl.res->start; + req->Size = win->ctl.res->end - win->ctl.res->start + 1; req->AccessSpeed = win->ctl.speed; req->Attributes = 0; if (win->ctl.flags & MAP_ATTRIB) @@ -1548,8 +1548,11 @@ s->state &= ~SOCKET_WIN_REQ(win->index); /* Release system memory */ - if(!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(win->base, win->size); + if (win->ctl.res) { + release_resource(win->ctl.res); + kfree(win->ctl.res); + win->ctl.res = NULL; + } win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; @@ -1871,14 +1874,19 @@ win->index = w; win->handle = *handle; win->sock = s; - win->base = req->Base; - win->size = req->Size; - if (!(s->features & SS_CAP_STATIC_MAP) && - find_mem_region(&win->base, win->size, align, - (req->Attributes & WIN_MAP_BELOW_1MB), - (*handle)->dev_info, s)) - return CS_IN_USE; + if (!(s->features & SS_CAP_STATIC_MAP)) { + win->ctl.res = find_mem_region(req->Base, req->Size, align, + (req->Attributes & WIN_MAP_BELOW_1MB), + (*handle)->dev_info, s); + if (!win->ctl.res) + return CS_IN_USE; + win->ctl.sys_start = win->ctl.res->start; + win->ctl.sys_stop = win->ctl.res->end; + } else { + win->ctl.sys_start = req->Base; + win->ctl.sys_stop = req->Base + req->Size - 1; + } (*handle)->state |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ @@ -1893,8 +1901,6 @@ win->ctl.flags |= MAP_16BIT; if (req->Attributes & WIN_USE_WAIT) win->ctl.flags |= MAP_USE_WAIT; - win->ctl.sys_start = win->base; - win->ctl.sys_stop = win->base + win->size-1; win->ctl.card_start = 0; if (s->ops->set_mem_map(s, &win->ctl) != 0) return CS_BAD_ARGS; diff -Nru a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h --- a/drivers/pcmcia/cs_internal.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/pcmcia/cs_internal.h 2004-06-26 17:09:21 -07:00 @@ -180,12 +180,12 @@ int copy_memory(memory_handle_t handle, copy_op_t *req); /* In rsrc_mgr */ -void validate_mem(struct pcmcia_socket *s); +void pcmcia_validate_mem(struct pcmcia_socket *s); struct resource *find_io_region(unsigned long base, int num, unsigned long align, char *name, struct pcmcia_socket *s); int adjust_io_region(struct resource *res, unsigned long r_start, unsigned long r_end, struct pcmcia_socket *s); -int find_mem_region(u_long *base, u_long num, u_long align, +struct resource *find_mem_region(u_long base, u_long num, u_long align, int low, char *name, struct pcmcia_socket *s); int try_irq(u_int Attributes, int irq, int specific); void undo_irq(u_int Attributes, int irq); diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c --- a/drivers/pcmcia/ds.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/pcmcia/ds.c 2004-06-26 17:09:19 -07:00 @@ -941,6 +941,7 @@ ret = pcmcia_get_configuration_info(s->handle, &buf.config); break; case DS_GET_FIRST_TUPLE: + pcmcia_validate_mem(s->parent); ret = pcmcia_get_first_tuple(s->handle, &buf.tuple); break; case DS_GET_NEXT_TUPLE: @@ -962,6 +963,7 @@ ret = pcmcia_get_status(s->handle, &buf.status); break; case DS_VALIDATE_CIS: + pcmcia_validate_mem(s->parent); ret = pcmcia_validate_cis(s->handle, &buf.cisinfo); break; case DS_SUSPEND_CARD: diff -Nru a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c --- a/drivers/pcmcia/i82092.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/pcmcia/i82092.c 2004-06-26 17:09:21 -07:00 @@ -420,12 +420,12 @@ static int i82092aa_init(struct pcmcia_socket *sock) { int i; + struct resource res = { .start = 0, .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, }; enter("i82092aa_init"); - mem.sys_stop = 0x0fff; for (i = 0; i < 2; i++) { io.map = i; i82092aa_set_io_map(sock, &io); diff -Nru a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c --- a/drivers/pcmcia/i82365.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/pcmcia/i82365.c 2004-06-26 17:09:20 -07:00 @@ -65,7 +65,6 @@ #include "cirrus.h" #include "vg468.h" #include "ricoh.h" -#include "o2micro.h" #ifdef DEBUG static const char version[] = @@ -1308,10 +1307,10 @@ static int pcic_init(struct pcmcia_socket *s) { int i; + struct resource res = { .start = 0, .end = 0x1000 }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, }; - mem.sys_stop = 0x1000; for (i = 0; i < 2; i++) { io.map = i; pcic_set_io_map(s, &io); @@ -1372,8 +1371,15 @@ { int i, ret; - if (driver_register(&i82365_driver)) - return -1; + ret = driver_register(&i82365_driver); + if (ret) + return ret; + + ret = platform_device_register(&i82365_device); + if (ret) { + driver_unregister(&i82365_driver); + return ret; + } printk(KERN_INFO "Intel ISA PCIC probe: "); sockets = 0; @@ -1382,11 +1388,10 @@ if (sockets == 0) { printk("not found.\n"); + platform_device_unregister(&i82365_device); driver_unregister(&i82365_driver); return -ENODEV; } - - platform_device_register(&i82365_device); /* Set up interrupt handler(s) */ if (grab_irq != 0) diff -Nru a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h --- a/drivers/pcmcia/o2micro.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/pcmcia/o2micro.h 2004-06-26 17:09:20 -07:00 @@ -120,4 +120,30 @@ #define O2_MODE_E_LED_OUT 0x08 #define O2_MODE_E_SKTA_ACTV 0x10 +static int o2micro_override(struct yenta_socket *socket) +{ + /* + * 'reserved' register at 0x94/D4. chaning it to 0xCA (8 bit) enables + * read prefetching which for example makes the RME Hammerfall DSP + * working. for some bridges it is at 0x94, for others at 0xD4. it's + * ok to write to both registers on all O2 bridges. + * from Eric Still, 02Micro. + */ + if (PCI_FUNC(socket->dev->devfn) == 0) { + config_writeb(socket, 0x94, 0xCA); + config_writeb(socket, 0xD4, 0xCA); + } + + return 0; +} + +static void o2micro_restore_state(struct yenta_socket *socket) +{ + /* + * as long as read prefetch is the only thing in + * o2micro_override, it's safe to call it from here + */ + o2micro_override(socket); +} + #endif /* _LINUX_O2MICRO_H */ diff -Nru a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/pcmcia/pd6729.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,732 @@ +/* + * Driver for the Cirrus PD6729 PCI-PCMCIA bridge. + * + * Based on the i82092.c driver. + * + * This software may be used and distributed according to the terms of + * the GNU General Public License, incorporated herein by reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "pd6729.h" +#include "i82365.h" +#include "cirrus.h" + +MODULE_LICENSE("GPL"); + +#define MAX_SOCKETS 2 + +/* simple helper functions */ +/* External clock time, in nanoseconds. 120 ns = 8.33 MHz */ +#define to_cycles(ns) ((ns)/120) + +static spinlock_t port_lock = SPIN_LOCK_UNLOCKED; + +/* basic value read/write functions */ + +static unsigned char indirect_read(struct pd6729_socket *socket, unsigned short reg) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg += socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + val = inb(port + 1); + spin_unlock_irqrestore(&port_lock, flags); + + return val; +} + +static unsigned short indirect_read16(struct pd6729_socket *socket, unsigned short reg) +{ + unsigned long port; + unsigned short tmp; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + tmp = inb(port + 1); + reg++; + outb(reg, port); + tmp = tmp | (inb(port + 1) << 8); + spin_unlock_irqrestore(&port_lock, flags); + + return tmp; +} + +static void indirect_write(struct pd6729_socket *socket, unsigned short reg, unsigned char value) +{ + unsigned long port; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + outb(value, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +static void indirect_setbit(struct pd6729_socket *socket, unsigned short reg, unsigned char mask) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + val = inb(port + 1); + val |= mask; + outb(reg, port); + outb(val, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +static void indirect_resetbit(struct pd6729_socket *socket, unsigned short reg, unsigned char mask) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + val = inb(port + 1); + val &= ~mask; + outb(reg, port); + outb(val, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +static void indirect_write16(struct pd6729_socket *socket, unsigned short reg, unsigned short value) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + + outb(reg, port); + val = value & 255; + outb(val, port + 1); + + reg++; + + outb(reg, port); + val = value >> 8; + outb(val, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +/* Interrupt handler functionality */ + +static irqreturn_t pd6729_interrupt(int irq, void *dev, struct pt_regs *regs) +{ + struct pd6729_socket *socket = (struct pd6729_socket *)dev; + int i; + int loopcount = 0; + int handled = 0; + unsigned int events, active = 0; + + while (1) { + loopcount++; + if (loopcount > 20) { + printk(KERN_ERR "pd6729: infinite eventloop in interrupt\n"); + break; + } + + active = 0; + + for (i = 0; i < MAX_SOCKETS; i++) { + unsigned int csc; + + /* card status change register */ + csc = indirect_read(&socket[i], I365_CSC); + if (csc == 0) /* no events on this socket */ + continue; + + handled = 1; + events = 0; + + if (csc & I365_CSC_DETECT) { + events |= SS_DETECT; + dprintk("Card detected in socket %i!\n", i); + } + + if (indirect_read(&socket[i], I365_INTCTL) & I365_PC_IOCARD) { + /* For IO/CARDS, bit 0 means "read the card" */ + events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0; + } else { + /* Check for battery/ready events */ + events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0; + events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; + events |= (csc & I365_CSC_READY) ? SS_READY : 0; + } + + if (events) { + pcmcia_parse_events(&socket[i].socket, events); + } + active |= events; + } + + if (active == 0) /* no more events to handle */ + break; + } + return IRQ_RETVAL(handled); +} + +/* socket functions */ + +static void set_bridge_state(struct pd6729_socket *socket) +{ + indirect_write(socket, I365_GBLCTL, 0x00); + indirect_write(socket, I365_GENCTL, 0x00); + + indirect_setbit(socket, I365_INTCTL, 0x08); +} + +static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned int status; + unsigned int data; + struct pd6729_socket *t; + + /* Interface Status Register */ + status = indirect_read(socket, I365_STATUS); + *value = 0; + + if ((status & I365_CS_DETECT) == I365_CS_DETECT) { + *value |= SS_DETECT; + } + + /* IO cards have a different meaning of bits 0,1 */ + /* Also notice the inverse-logic on the bits */ + if (indirect_read(socket, I365_INTCTL) & I365_PC_IOCARD) { + /* IO card */ + if (!(status & I365_CS_STSCHG)) + *value |= SS_STSCHG; + } else { + /* non I/O card */ + if (!(status & I365_CS_BVD1)) + *value |= SS_BATDEAD; + if (!(status & I365_CS_BVD2)) + *value |= SS_BATWARN; + } + + if (status & I365_CS_WRPROT) + *value |= SS_WRPROT; /* card is write protected */ + + if (status & I365_CS_READY) + *value |= SS_READY; /* card is not busy */ + + if (status & I365_CS_POWERON) + *value |= SS_POWERON; /* power is applied to the card */ + + t = (socket->number) ? socket : socket + 1; + indirect_write(t, PD67_EXT_INDEX, PD67_EXTERN_DATA); + data = indirect_read16(t, PD67_EXT_DATA); + *value |= (data & PD67_EXD_VS1(socket->number)) ? 0 : SS_3VCARD; + + return 0; +} + + +static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned char reg, vcc, vpp; + + state->flags = 0; + state->Vcc = 0; + state->Vpp = 0; + state->io_irq = 0; + state->csc_mask = 0; + + /* First the power status of the socket */ + /* PCTRL - Power Control Register */ + reg = indirect_read(socket, I365_POWER); + + if (reg & I365_PWR_AUTO) + state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */ + + if (reg & I365_PWR_OUT) + state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ + + vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; + + if (reg & I365_VCC_5V) { + state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) & + PD67_MC1_VCC_3V) ? 33 : 50; + + if (vpp == I365_VPP1_5V) { + if (state->Vcc == 50) + state->Vpp = 50; + else + state->Vpp = 33; + } + if (vpp == I365_VPP1_12V) + state->Vpp = 120; + } + + /* Now the IO card, RESET flags and IO interrupt */ + /* IGENC, Interrupt and General Control */ + reg = indirect_read(socket, I365_INTCTL); + + if ((reg & I365_PC_RESET) == 0) + state->flags |= SS_RESET; + if (reg & I365_PC_IOCARD) + state->flags |= SS_IOCARD; /* This is an IO card */ + + /* Set the IRQ number */ + state->io_irq = socket->socket.pci_irq; + + /* Card status change */ + /* CSCICR, Card Status Change Interrupt Configuration */ + reg = indirect_read(socket, I365_CSCINT); + + if (reg & I365_CSC_DETECT) + state->csc_mask |= SS_DETECT; /* Card detect is enabled */ + + if (state->flags & SS_IOCARD) {/* IO Cards behave different */ + if (reg & I365_CSC_STSCHG) + state->csc_mask |= SS_STSCHG; + } else { + if (reg & I365_CSC_BVD1) + state->csc_mask |= SS_BATDEAD; + if (reg & I365_CSC_BVD2) + state->csc_mask |= SS_BATWARN; + if (reg & I365_CSC_READY) + state->csc_mask |= SS_READY; + } + + return 0; +} + +static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned char reg; + + /* First, set the global controller options */ + + set_bridge_state(socket); + + /* Values for the IGENC register */ + + reg = 0; + /* The reset bit has "inverse" logic */ + if (!(state->flags & SS_RESET)) + reg = reg | I365_PC_RESET; + if (state->flags & SS_IOCARD) + reg = reg | I365_PC_IOCARD; + + /* IGENC, Interrupt and General Control Register */ + indirect_write(socket, I365_INTCTL, reg); + + /* Power registers */ + + reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */ + + if (state->flags & SS_PWR_AUTO) { + dprintk("Auto power\n"); + reg |= I365_PWR_AUTO; /* automatic power mngmnt */ + } + if (state->flags & SS_OUTPUT_ENA) { + dprintk("Power Enabled\n"); + reg |= I365_PWR_OUT; /* enable power */ + } + + switch (state->Vcc) { + case 0: + break; + case 33: + dprintk("setting voltage to Vcc to 3.3V on socket %i\n", + socket->number); + reg |= I365_VCC_5V; + indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); + break; + case 50: + dprintk("setting voltage to Vcc to 5V on socket %i\n", + socket->number); + reg |= I365_VCC_5V; + indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); + break; + default: + dprintk("pd6729: pd6729_set_socket called with invalid VCC power value: %i\n", + state->Vcc); + return -EINVAL; + } + + switch (state->Vpp) { + case 0: + dprintk("not setting Vpp on socket %i\n", socket->number); + break; + case 33: + case 50: + dprintk("setting Vpp to Vcc for socket %i\n", socket->number); + reg |= I365_VPP1_5V; + break; + case 120: + dprintk("setting Vpp to 12.0\n"); + reg |= I365_VPP1_12V; + break; + default: + dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i\n", + state->Vpp); + return -EINVAL; + } + + /* only write if changed */ + if (reg != indirect_read(socket, I365_POWER)) + indirect_write(socket, I365_POWER, reg); + + /* Now, specifiy that all interrupts are to be done as PCI interrupts */ + indirect_write(socket, PD67_EXT_INDEX, PD67_EXT_CTL_1); + indirect_write(socket, PD67_EXT_DATA, PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ); + + /* Enable specific interrupt events */ + + reg = 0x00; + if (state->csc_mask & SS_DETECT) { + reg |= I365_CSC_DETECT; + } + if (state->flags & SS_IOCARD) { + if (state->csc_mask & SS_STSCHG) + reg |= I365_CSC_STSCHG; + } else { + if (state->csc_mask & SS_BATDEAD) + reg |= I365_CSC_BVD1; + if (state->csc_mask & SS_BATWARN) + reg |= I365_CSC_BVD2; + if (state->csc_mask & SS_READY) + reg |= I365_CSC_READY; + } + reg |= 0x30; /* management IRQ: PCI INTA# = "irq 3" */ + indirect_write(socket, I365_CSCINT, reg); + + reg = indirect_read(socket, I365_INTCTL); + reg |= 0x03; /* card IRQ: PCI INTA# = "irq 3" */ + indirect_write(socket, I365_INTCTL, reg); + + /* now clear the (probably bogus) pending stuff by doing a dummy read */ + (void)indirect_read(socket, I365_CSC); + + return 0; +} + +static int pd6729_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned char map, ioctl; + + map = io->map; + + /* Check error conditions */ + if (map > 1) { + dprintk("pd6729_set_io_map with invalid map"); + return -EINVAL; + } + + /* Turn off the window before changing anything */ + if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map)) + indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map)); + +/* dprintk("set_io_map: Setting range to %x - %x\n", io->start, io->stop);*/ + + /* write the new values */ + indirect_write16(socket, I365_IO(map)+I365_W_START, io->start); + indirect_write16(socket, I365_IO(map)+I365_W_STOP, io->stop); + + ioctl = indirect_read(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map); + + if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); + if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); + if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); + + indirect_write(socket, I365_IOCTL, ioctl); + + /* Turn the window back on if needed */ + if (io->flags & MAP_ACTIVE) + indirect_setbit(socket, I365_ADDRWIN, I365_ENA_IO(map)); + + return 0; +} + +static int pd6729_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned short base, i; + unsigned char map; + + map = mem->map; + if (map > 4) { + printk("pd6729_set_mem_map: invalid map"); + return -EINVAL; + } + + if ((mem->sys_start > mem->sys_stop) || (mem->speed > 1000)) { + printk("pd6729_set_mem_map: invalid address / speed"); + /* printk("invalid mem map for socket %i : %lx to %lx with a start of %x\n", + sock, mem->sys_start, mem->sys_stop, mem->card_start); */ + return -EINVAL; + } + + /* Turn off the window before changing anything */ + if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_MEM(map)) + indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_MEM(map)); + + /* write the start address */ + base = I365_MEM(map); + i = (mem->sys_start >> 12) & 0x0fff; + if (mem->flags & MAP_16BIT) + i |= I365_MEM_16BIT; + if (mem->flags & MAP_0WS) + i |= I365_MEM_0WS; + indirect_write16(socket, base + I365_W_START, i); + + /* write the stop address */ + + i= (mem->sys_stop >> 12) & 0x0fff; + switch (to_cycles(mem->speed)) { + case 0: + break; + case 1: + i |= I365_MEM_WS0; + break; + case 2: + i |= I365_MEM_WS1; + break; + default: + i |= I365_MEM_WS1 | I365_MEM_WS0; + break; + } + + indirect_write16(socket, base + I365_W_STOP, i); + + /* Take care of high byte */ + indirect_write(socket, PD67_EXT_INDEX, PD67_MEM_PAGE(map)); + indirect_write(socket, PD67_EXT_DATA, mem->sys_start >> 24); + + /* card start */ + + i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff; + if (mem->flags & MAP_WRPROT) + i |= I365_MEM_WRPROT; + if (mem->flags & MAP_ATTRIB) { +/* dprintk("requesting attribute memory for socket %i\n", + socket->number);*/ + i |= I365_MEM_REG; + } else { +/* dprintk("requesting normal memory for socket %i\n", + socket->number);*/ + } + indirect_write16(socket, base + I365_W_OFF, i); + + /* Enable the window if necessary */ + if (mem->flags & MAP_ACTIVE) + indirect_setbit(socket, I365_ADDRWIN, I365_ENA_MEM(map)); + + return 0; +} + +static int pd6729_suspend(struct pcmcia_socket *sock) +{ + return pd6729_set_socket(sock, &dead_socket); +} + +static int pd6729_init(struct pcmcia_socket *sock) +{ + int i; + struct resource res = { .end = 0x0fff }; + pccard_io_map io = { 0, 0, 0, 0, 1 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff }; + + pd6729_set_socket(sock, &dead_socket); + for (i = 0; i < 2; i++) { + io.map = i; + pd6729_set_io_map(sock, &io); + } + for (i = 0; i < 5; i++) { + mem.map = i; + pd6729_set_mem_map(sock, &mem); + } + + return 0; +} + + +/* the pccard structure and its functions */ +static struct pccard_operations pd6729_operations = { + .init = pd6729_init, + .suspend = pd6729_suspend, + .get_status = pd6729_get_status, + .get_socket = pd6729_get_socket, + .set_socket = pd6729_set_socket, + .set_io_map = pd6729_set_io_map, + .set_mem_map = pd6729_set_mem_map, +}; + +static int __devinit pd6729_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int i, j, ret; + char configbyte; + struct pd6729_socket *socket; + + socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, GFP_KERNEL); + if (!socket) + return -ENOMEM; + + memset(socket, 0, sizeof(struct pd6729_socket) * MAX_SOCKETS); + + if ((ret = pci_enable_device(dev))) + goto err_out_free_mem; + + printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge at 0x%lx on irq %d\n", + pci_resource_start(dev, 0), dev->irq); + printk(KERN_INFO "pd6729: configured as a %d socket device.\n", MAX_SOCKETS); + /* Since we have no memory BARs some firmware we may not + have had PCI_COMMAND_MEM enabled, yet the device needs + it. */ + pci_read_config_byte(dev, PCI_COMMAND, &configbyte); + if (!(configbyte & PCI_COMMAND_MEMORY)) { + printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n"); + configbyte |= PCI_COMMAND_MEMORY; + pci_write_config_byte(dev, PCI_COMMAND, configbyte); + } + + ret = pci_request_regions(dev, "pd6729"); + if (ret) { + printk(KERN_INFO "pd6729: pci request region failed.\n"); + goto err_out_disable; + } + + for (i = 0; i < MAX_SOCKETS; i++) { + socket[i].io_base = pci_resource_start(dev, 0); + socket[i].socket.features |= SS_CAP_PCCARD; + socket[i].socket.map_size = 0x1000; + socket[i].socket.irq_mask = 0; + socket[i].socket.pci_irq = dev->irq; + socket[i].socket.owner = THIS_MODULE; + + socket[i].number = i; + + socket[i].socket.ops = &pd6729_operations; + socket[i].socket.dev.dev = &dev->dev; + socket[i].socket.driver_data = &socket[i]; + } + + pci_set_drvdata(dev, socket); + + /* Register the interrupt handler */ + if ((ret = request_irq(dev->irq, pd6729_interrupt, SA_SHIRQ, "pd6729", socket))) { + printk(KERN_ERR "pd6729: Failed to register irq %d, aborting\n", dev->irq); + goto err_out_free_res; + } + + for (i = 0; i < MAX_SOCKETS; i++) { + ret = pcmcia_register_socket(&socket[i].socket); + if (ret) { + printk(KERN_INFO "pd6729: pcmcia_register_socket failed.\n"); + for (j = 0; j < i ; j++) + pcmcia_unregister_socket(&socket[j].socket); + goto err_out_free_res2; + } + } + + return 0; + + err_out_free_res2: + free_irq(dev->irq, socket); + err_out_free_res: + pci_release_regions(dev); + err_out_disable: + pci_disable_device(dev); + + err_out_free_mem: + kfree(socket); + return ret; +} + +static void __devexit pd6729_pci_remove(struct pci_dev *dev) +{ + int i; + struct pd6729_socket *socket = pci_get_drvdata(dev); + + for (i = 0; i < MAX_SOCKETS; i++) + pcmcia_unregister_socket(&socket[i].socket); + + free_irq(dev->irq, socket); + pci_release_regions(dev); + pci_disable_device(dev); + + kfree(socket); +} + +static int pd6729_socket_suspend(struct pci_dev *dev, u32 state) +{ + return pcmcia_socket_dev_suspend(&dev->dev, state); +} + +static int pd6729_socket_resume(struct pci_dev *dev) +{ + return pcmcia_socket_dev_resume(&dev->dev); +} + +static struct pci_device_id pd6729_pci_ids[] = { + { + .vendor = PCI_VENDOR_ID_CIRRUS, + .device = PCI_DEVICE_ID_CIRRUS_6729, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { } +}; +MODULE_DEVICE_TABLE(pci, pd6729_pci_ids); + +static struct pci_driver pd6729_pci_drv = { + .name = "pd6729", + .id_table = pd6729_pci_ids, + .probe = pd6729_pci_probe, + .remove = __devexit_p(pd6729_pci_remove), + .suspend = pd6729_socket_suspend, + .resume = pd6729_socket_resume, +}; + +static int pd6729_module_init(void) +{ + return pci_module_init(&pd6729_pci_drv); +} + +static void pd6729_module_exit(void) +{ + pci_unregister_driver(&pd6729_pci_drv); +} + +module_init(pd6729_module_init); +module_exit(pd6729_module_exit); diff -Nru a/drivers/pcmcia/pd6729.h b/drivers/pcmcia/pd6729.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/pcmcia/pd6729.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,28 @@ +#ifndef _INCLUDE_GUARD_PD6729_H_ +#define _INCLUDE_GUARD_PD6729_H_ + +/* Debuging defines */ +#ifdef NOTRACE +#define dprintk(fmt, args...) printk(fmt , ## args) +#else +#define dprintk(fmt, args...) do {} while (0) +#endif + +/* Flags for I365_GENCTL */ +#define I365_DF_VS1 0x40 /* DF-step Voltage Sense */ +#define I365_DF_VS2 0x80 + +/* Fields in PD67_EXTERN_DATA */ +#define PD67_EXD_VS1(s) (0x01 << ((s) << 1)) +#define PD67_EXD_VS2(s) (0x02 << ((s) << 1)) + + + + +struct pd6729_socket { + int number; + unsigned long io_base; /* base io address of the socket */ + struct pcmcia_socket socket; +}; + +#endif diff -Nru a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c --- a/drivers/pcmcia/rsrc_mgr.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pcmcia/rsrc_mgr.c 2004-06-26 17:09:18 -07:00 @@ -118,7 +118,7 @@ res->name = name; res->start = b; res->end = b + n - 1; - res->flags = flags | IORESOURCE_BUSY; + res->flags = flags; } return res; } @@ -303,6 +303,7 @@ s->cis_mem.sys_start = res->start; s->cis_mem.sys_stop = res->end; + s->cis_mem.res = res; s->cis_virt = ioremap(res->start, s->map_size); if (s->cis_virt) { ret = pcmcia_validate_cis(s->clients, info); @@ -313,6 +314,7 @@ } s->cis_mem.sys_start = 0; s->cis_mem.sys_stop = 0; + s->cis_mem.res = NULL; if ((ret != 0) || (info->Chains == 0)) return 0; return 1; @@ -332,6 +334,7 @@ map.speed = 0; map.sys_start = res->start; map.sys_stop = res->end; + map.res = res; map.card_start = 0; s->ops->set_mem_map(s, &map); @@ -454,7 +457,7 @@ return do_mem_probe(m->base, m->num, s); } -void validate_mem(struct pcmcia_socket *s) +static void validate_mem(struct pcmcia_socket *s) { resource_map_t *m, mm; static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; @@ -462,9 +465,6 @@ u_long b, i, ok = 0; int force_low = !(s->features & SS_CAP_PAGE_REGS); - if (!probe_mem) - return; - down(&rsrc_sem); /* We do up to four passes through the list */ if (!force_low) { @@ -500,12 +500,12 @@ #else /* CONFIG_PCMCIA_PROBE */ -void validate_mem(struct pcmcia_socket *s) +static void validate_mem(struct pcmcia_socket *s) { resource_map_t *m, mm; static int done = 0; - if (probe_mem && done++ == 0) { + if (done++ == 0) { down(&rsrc_sem); for (m = mem_db.next; m != &mem_db; m = mm.next) { mm = *m; @@ -518,6 +518,18 @@ #endif /* CONFIG_PCMCIA_PROBE */ +void pcmcia_validate_mem(struct pcmcia_socket *s) +{ + down(&s->skt_sem); + + if (probe_mem && s->state & SOCKET_PRESENT) + validate_mem(s); + + up(&s->skt_sem); +} + +EXPORT_SYMBOL(pcmcia_validate_mem); + struct pcmcia_align_data { unsigned long mask; unsigned long offset; @@ -622,7 +634,7 @@ struct resource *find_io_region(unsigned long base, int num, unsigned long align, char *name, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_IO, name); + struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id); struct pcmcia_align_data data; unsigned long min = base; int ret; @@ -641,8 +653,8 @@ min, 0, pcmcia_align, &data); } else #endif - ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, 0, - pcmcia_align, &data); + ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, + 1, pcmcia_align, &data); up(&rsrc_sem); if (ret != 0) { @@ -652,10 +664,10 @@ return res; } -int find_mem_region(u_long *base, u_long num, u_long align, - int low, char *name, struct pcmcia_socket *s) +struct resource *find_mem_region(u_long base, u_long num, u_long align, + int low, char *name, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_MEM, name); + struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id); struct pcmcia_align_data data; unsigned long min, max; int ret, i; @@ -663,16 +675,16 @@ low = low || !(s->features & SS_CAP_PAGE_REGS); data.mask = align - 1; - data.offset = *base & data.mask; + data.offset = base & data.mask; data.map = &mem_db; for (i = 0; i < 2; i++) { if (low) { max = 0x100000UL; - min = *base < max ? *base : 0; + min = base < max ? base : 0; } else { max = ~0UL; - min = 0x100000UL + *base; + min = 0x100000UL + base; } down(&rsrc_sem); @@ -684,7 +696,7 @@ } else #endif ret = allocate_resource(&iomem_resource, res, num, min, - max, 0, pcmcia_align, &data); + max, 1, pcmcia_align, &data); up(&rsrc_sem); if (ret == 0 || low) break; @@ -693,10 +705,9 @@ if (ret != 0) { kfree(res); - } else { - *base = res->start; + res = NULL; } - return ret; + return res; } /*====================================================================== diff -Nru a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c --- a/drivers/pcmcia/tcic.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pcmcia/tcic.c 2004-06-26 17:09:18 -07:00 @@ -868,10 +868,10 @@ static int tcic_init(struct pcmcia_socket *s) { int i; + struct resource res = { .start = 0, .end = 0x1000 }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, }; - mem.sys_stop = 0x1000; for (i = 0; i < 2; i++) { io.map = i; tcic_set_io_map(s, &io); diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c --- a/drivers/pcmcia/yenta_socket.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pcmcia/yenta_socket.c 2004-06-26 17:09:18 -07:00 @@ -445,10 +445,10 @@ static void yenta_clear_maps(struct yenta_socket *socket) { int i; + struct resource res = { .start = 0, .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, }; - mem.sys_stop = 0x0fff; yenta_set_socket(&socket->socket, &dead_socket); for (i = 0; i < 2; i++) { io.map = i; @@ -668,6 +668,7 @@ #include "ti113x.h" #include "ricoh.h" #include "topic.h" +#include "o2micro.h" enum { CARDBUS_TYPE_DEFAULT = -1, @@ -676,7 +677,8 @@ CARDBUS_TYPE_TI12XX, CARDBUS_TYPE_TI1250, CARDBUS_TYPE_RICOH, - CARDBUS_TYPE_TOPIC97 + CARDBUS_TYPE_TOPIC97, + CARDBUS_TYPE_O2MICRO, }; /* @@ -716,6 +718,10 @@ [CARDBUS_TYPE_TOPIC97] = { .override = topic97_override, }, + [CARDBUS_TYPE_O2MICRO] = { + .override = o2micro_override, + .restore_state = o2micro_restore_state, + }, }; @@ -1099,6 +1105,8 @@ CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), + + CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO), /* match any cardbus bridge */ CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c --- a/drivers/pnp/isapnp/core.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/pnp/isapnp/core.c 2004-06-26 17:09:18 -07:00 @@ -68,13 +68,8 @@ MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode"); MODULE_LICENSE("GPL"); -#ifdef CONFIG_X86_PC9800 -#define _PIDXR 0x259 -#define _PNPWRP 0xa59 -#else #define _PIDXR 0x279 #define _PNPWRP 0xa79 -#endif /* short tags */ #define _STAG_PNPVERNO 0x01 diff -Nru a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c --- a/drivers/sbus/char/openprom.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/sbus/char/openprom.c 2004-06-26 17:09:19 -07:00 @@ -149,7 +149,6 @@ char buffer[OPROMMAXPARAM+1], *buf; struct openpromio *opp; int bufsize, len, error = 0; - extern char saved_command_line[]; static int cnt; if (cmd == OPROMSETOPT) diff -Nru a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/scsi/3w-9xxx.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,2153 @@ +/* + 3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux. + + Written By: Adam Radford + + Copyright (C) 2004 Applied Micro Circuits 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; version 2 of the License. + + 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. + + NO WARRANTY + THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT + LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + solely responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to + the risks and costs of program errors, damage to or loss of data, + programs or equipment, and unavailability or interruption of operations. + + DISCLAIMER OF LIABILITY + NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + + 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 + + Bugs/Comments/Suggestions should be mailed to: + linuxraid@amcc.com + + For more information, goto: + http://www.amcc.com + + Note: This version of the driver does not contain a bundled firmware + image. + + History + ------- + 2.26.02.000 - Driver cleanup for kernel submission. + 2.26.02.001 - Replace schedule_timeout() calls with msleep(). +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "3w-9xxx.h" + +/* Globals */ +static const char *twa_driver_version="2.26.02.001"; +static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; +static unsigned int twa_device_extension_count; +static int twa_major = -1; +extern struct timezone sys_tz; + +/* Module parameters */ +MODULE_AUTHOR ("AMCC"); +MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver"); +MODULE_LICENSE("GPL"); + +/* Function prototypes */ +static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header); +static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); +static char *twa_aen_severity_lookup(unsigned char severity_code); +static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id); +static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int twa_chrdev_open(struct inode *inode, struct file *file); +static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host); +static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id); +static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id); +static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, + u32 set_features, unsigned short current_fw_srl, + unsigned short current_fw_arch_id, + unsigned short current_fw_branch, + unsigned short current_fw_build, + unsigned short *fw_on_ctlr_srl, + unsigned short *fw_on_ctlr_arch_id, + unsigned short *fw_on_ctlr_branch, + unsigned short *fw_on_ctlr_build, + u32 *init_connect_result); +static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length); +static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds); +static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds); +static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal); +static int twa_reset_device_extension(TW_Device_Extension *tw_dev); +static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset); +static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg); +static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id); +static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code); +static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id); + +/* Functions */ + +/* Show some statistics about the card */ +static ssize_t twa_show_stats(struct class_device *class_dev, char *buf) +{ + struct Scsi_Host *host = class_to_shost(class_dev); + TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; + unsigned long flags = 0; + ssize_t len; + + spin_lock_irqsave(tw_dev->host->host_lock, flags); + len = snprintf(buf, PAGE_SIZE, "Driver version: %s\n" + "Current commands posted: %4d\n" + "Max commands posted: %4d\n" + "Current pending commands: %4d\n" + "Max pending commands: %4d\n" + "Last sgl length: %4d\n" + "Max sgl length: %4d\n" + "Last sector count: %4d\n" + "Max sector count: %4d\n" + "SCSI Host Resets: %4d\n" + "SCSI Aborts/Timeouts: %4d\n" + "AEN's: %4d\n", + twa_driver_version, + tw_dev->posted_request_count, + tw_dev->max_posted_request_count, + tw_dev->pending_request_count, + tw_dev->max_pending_request_count, + tw_dev->sgl_entries, + tw_dev->max_sgl_entries, + tw_dev->sector_count, + tw_dev->max_sector_count, + tw_dev->num_resets, + tw_dev->num_aborts, + tw_dev->aen_count); + spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + return len; +} /* End twa_show_stats() */ + +/* This function will set a devices queue depth */ +static ssize_t twa_store_queue_depth(struct device *dev, const char *buf, size_t count) +{ + int queue_depth; + struct scsi_device *sdev = to_scsi_device(dev); + + queue_depth = simple_strtoul(buf, NULL, 0); + if (queue_depth > TW_Q_LENGTH-2) + return -EINVAL; + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); + + return count; +} /* End twa_store_queue_depth() */ + +/* Create sysfs 'queue_depth' entry */ +static struct device_attribute twa_queue_depth_attr = { + .attr = { + .name = "queue_depth", + .mode = S_IRUSR | S_IWUSR, + }, + .store = twa_store_queue_depth +}; + +/* Device attributes initializer */ +static struct device_attribute *twa_dev_attrs[] = { + &twa_queue_depth_attr, + NULL, +}; + +/* Create sysfs 'stats' entry */ +static struct class_device_attribute twa_host_stats_attr = { + .attr = { + .name = "stats", + .mode = S_IRUGO, + }, + .show = twa_show_stats +}; + +/* Host attributes initializer */ +static struct class_device_attribute *twa_host_attrs[] = { + &twa_host_stats_attr, + NULL, +}; + +/* File operations struct for character device */ +static struct file_operations twa_fops = { + .owner = THIS_MODULE, + .ioctl = twa_chrdev_ioctl, + .open = twa_chrdev_open, + .release = NULL +}; + +/* This function will complete an aen request from the isr */ +static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id) +{ + TW_Command_Full *full_command_packet; + TW_Command *command_packet; + TW_Command_Apache_Header *header; + unsigned short aen; + int retval = 1; + + header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; + tw_dev->posted_request_count--; + aen = header->status_block.error; + full_command_packet = tw_dev->command_packet_virt[request_id]; + command_packet = &full_command_packet->command.oldcommand; + + /* First check for internal completion of set param for time sync */ + if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) { + /* Keep reading the queue in case there are more aen's */ + if (twa_aen_read_queue(tw_dev, request_id)) + goto out2; + else { + retval = 0; + goto out; + } + } + + switch (aen) { + case TW_AEN_QUEUE_EMPTY: + /* Quit reading the queue if this is the last one */ + break; + case TW_AEN_SYNC_TIME_WITH_HOST: + twa_aen_sync_time(tw_dev, request_id); + retval = 0; + goto out; + default: + twa_aen_queue_event(tw_dev, header); + + /* If there are more aen's, keep reading the queue */ + if (twa_aen_read_queue(tw_dev, request_id)) + goto out2; + else { + retval = 0; + goto out; + } + } + retval = 0; +out2: + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags); +out: + return retval; +} /* End twa_aen_complete() */ + +/* This function will drain aen queue */ +static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset) +{ + int request_id = 0; + char cdb[TW_MAX_CDB_LEN]; + TW_SG_Apache sglist[1]; + int finished = 0, count = 0; + TW_Command_Full *full_command_packet; + TW_Command_Apache_Header *header; + unsigned short aen; + int first_reset = 0, queue = 0, retval = 1; + + if (no_check_reset) + first_reset = 0; + else + first_reset = 1; + + full_command_packet = tw_dev->command_packet_virt[request_id]; + memset(full_command_packet, 0, sizeof(TW_Command_Full)); + + /* Initialize cdb */ + memset(&cdb, 0, TW_MAX_CDB_LEN); + cdb[0] = REQUEST_SENSE; /* opcode */ + cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */ + + /* Initialize sglist */ + memset(&sglist, 0, sizeof(TW_SG_Apache)); + sglist[0].length = TW_SECTOR_SIZE; + sglist[0].address = tw_dev->generic_buffer_phys[request_id]; + + if (sglist[0].address & TW_ALIGNMENT_9000_SGL) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Found unaligned address during AEN drain"); + goto out; + } + + /* Mark internal command */ + tw_dev->srb[request_id] = NULL; + + do { + /* Send command to the board */ + if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Error posting request sense"); + goto out; + } + + /* Now poll for completion */ + if (twa_poll_response(tw_dev, request_id, 30)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "No valid response while draining AEN queue"); + tw_dev->posted_request_count--; + goto out; + } + + tw_dev->posted_request_count--; + header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; + aen = header->status_block.error; + queue = 0; + count++; + + switch (aen) { + case TW_AEN_QUEUE_EMPTY: + if (first_reset != 1) + goto out; + else + finished = 1; + break; + case TW_AEN_SOFT_RESET: + if (first_reset == 0) + first_reset = 1; + else + queue = 1; + break; + case TW_AEN_SYNC_TIME_WITH_HOST: + break; + default: + queue = 1; + } + + /* Now queue an event info */ + if (queue) + twa_aen_queue_event(tw_dev, header); + } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN)); + + if (count == TW_MAX_AEN_DRAIN) + goto out; + + retval = 0; +out: + tw_dev->state[request_id] = TW_S_INITIAL; + return retval; +} /* End twa_aen_drain_queue() */ + +/* This function will queue an event */ +static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header) +{ + u32 local_time; + struct timeval time; + TW_Event *event; + unsigned short aen; + char host[16]; + + tw_dev->aen_count++; + + /* Fill out event info */ + event = tw_dev->event_queue[tw_dev->error_index]; + + /* Check for clobber */ + host[0] = '\0'; + if (tw_dev->host) { + sprintf(host, " scsi%d:", tw_dev->host->host_no); + if (event->retrieved == TW_AEN_NOT_RETRIEVED) + tw_dev->aen_clobber = 1; + } + + aen = header->status_block.error; + memset(event, 0, sizeof(TW_Event)); + + event->severity = TW_SEV_OUT(header->status_block.severity__reserved); + do_gettimeofday(&time); + local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60)); + event->time_stamp_sec = local_time; + event->aen_code = aen; + event->retrieved = TW_AEN_NOT_RETRIEVED; + event->sequence_id = tw_dev->error_sequence_id; + tw_dev->error_sequence_id++; + + header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0'; + event->parameter_len = strlen(header->err_specific_desc); + memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len); + if (event->severity != TW_AEN_SEVERITY_DEBUG) + printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n", + host, + twa_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)), + TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, + twa_string_lookup(twa_aen_table, aen), + header->err_specific_desc); + else + tw_dev->aen_count--; + + if ((tw_dev->error_index + 1) == TW_Q_LENGTH) + tw_dev->event_queue_wrapped = 1; + tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH; +} /* End twa_aen_queue_event() */ + +/* This function will read the aen queue from the isr */ +static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id) +{ + char cdb[TW_MAX_CDB_LEN]; + TW_SG_Apache sglist[1]; + TW_Command_Full *full_command_packet; + int retval = 1; + + full_command_packet = tw_dev->command_packet_virt[request_id]; + memset(full_command_packet, 0, sizeof(TW_Command_Full)); + + /* Initialize cdb */ + memset(&cdb, 0, TW_MAX_CDB_LEN); + cdb[0] = REQUEST_SENSE; /* opcode */ + cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */ + + /* Initialize sglist */ + memset(&sglist, 0, sizeof(TW_SG_Apache)); + sglist[0].length = TW_SECTOR_SIZE; + sglist[0].address = tw_dev->generic_buffer_phys[request_id]; + + /* Mark internal command */ + tw_dev->srb[request_id] = NULL; + + /* Now post the command packet */ + if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "Post failed while reading AEN queue"); + goto out; + } + retval = 0; +out: + return retval; +} /* End twa_aen_read_queue() */ + +/* This function will look up an AEN severity string */ +static char *twa_aen_severity_lookup(unsigned char severity_code) +{ + char *retval = NULL; + + if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) || + (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG)) + goto out; + + retval = twa_aen_severity_table[severity_code]; +out: + return retval; +} /* End twa_aen_severity_lookup() */ + +/* This function will sync firmware time with the host time */ +static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id) +{ + u32 schedulertime; + struct timeval utc; + TW_Command_Full *full_command_packet; + TW_Command *command_packet; + TW_Param_Apache *param; + u32 local_time; + + /* Fill out the command packet */ + full_command_packet = tw_dev->command_packet_virt[request_id]; + memset(full_command_packet, 0, sizeof(TW_Command_Full)); + command_packet = &full_command_packet->command.oldcommand; + command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM); + command_packet->request_id = request_id; + command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id]; + command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE; + command_packet->size = TW_COMMAND_SIZE; + command_packet->byte6_offset.parameter_count = 1; + + /* Setup the param */ + param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; + memset(param, 0, TW_SECTOR_SIZE); + param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */ + param->parameter_id = 0x3; /* SchedulerTime */ + param->parameter_size_bytes = 4; + + /* Convert system time in UTC to local time seconds since last + Sunday 12:00AM */ + do_gettimeofday(&utc); + local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60)); + schedulertime = local_time - (3 * 86400); + schedulertime = schedulertime % 604800; + + memcpy(param->data, &schedulertime, sizeof(u32)); + + /* Mark internal command */ + tw_dev->srb[request_id] = NULL; + + /* Now post the command */ + twa_post_command_packet(tw_dev, request_id, 1); +} /* End twa_aen_sync_time() */ + +/* This function will allocate memory and check if it is correctly aligned */ +static int twa_allocate_memory(TW_Device_Extension *tw_dev, int size, int which) +{ + int i; + dma_addr_t dma_handle; + unsigned long *cpu_addr; + int retval = 1; + + cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle); + if (!cpu_addr) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed"); + goto out; + } + + if ((unsigned long)cpu_addr % (TW_ALIGNMENT_9000)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x6, "Failed to allocate correctly aligned memory"); + pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle); + goto out; + } + + memset(cpu_addr, 0, size*TW_Q_LENGTH); + + for (i = 0; i < TW_Q_LENGTH; i++) { + switch(which) { + case 0: + tw_dev->command_packet_phys[i] = dma_handle+(i*size); + tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size)); + break; + case 1: + tw_dev->generic_buffer_phys[i] = dma_handle+(i*size); + tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size)); + break; + } + } + retval = 0; +out: + return retval; +} /* End twa_allocate_memory() */ + +/* This function will check the status register for unexpected bits */ +static int twa_check_bits(u32 status_reg_value) +{ + int retval = 1; + + if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) + goto out; + if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) + goto out; + + retval = 0; +out: + return retval; +} /* End twa_check_bits() */ + +/* This function will check the srl and decide if we are compatible */ +static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed) +{ + int retval = 1; + unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0; + unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0; + u32 init_connect_result = 0; + + if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS, + TW_EXTENDED_INIT_CONNECT, TW_CURRENT_FW_SRL, + TW_9000_ARCH_ID, TW_CURRENT_FW_BRANCH, + TW_CURRENT_FW_BUILD, &fw_on_ctlr_srl, + &fw_on_ctlr_arch_id, &fw_on_ctlr_branch, + &fw_on_ctlr_build, &init_connect_result)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "Initconnection failed while checking SRL"); + goto out; + } + + tw_dev->working_srl = TW_CURRENT_FW_SRL; + tw_dev->working_branch = TW_CURRENT_FW_BRANCH; + tw_dev->working_build = TW_CURRENT_FW_BUILD; + + /* Try base mode compatibility */ + if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { + if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS, + TW_EXTENDED_INIT_CONNECT, + TW_BASE_FW_SRL, TW_9000_ARCH_ID, + TW_BASE_FW_BRANCH, TW_BASE_FW_BUILD, + &fw_on_ctlr_srl, &fw_on_ctlr_arch_id, + &fw_on_ctlr_branch, &fw_on_ctlr_build, + &init_connect_result)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Initconnection (base mode) failed while checking SRL"); + goto out; + } + if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { + if (TW_CURRENT_FW_SRL > fw_on_ctlr_srl) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x32, "Firmware and driver incompatibility: please upgrade firmware"); + } else { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x33, "Firmware and driver incompatibility: please upgrade driver"); + } + goto out; + } + tw_dev->working_srl = TW_BASE_FW_SRL; + tw_dev->working_branch = TW_BASE_FW_BRANCH; + tw_dev->working_build = TW_BASE_FW_BUILD; + } + retval = 0; +out: + return retval; +} /* End twa_check_srl() */ + +/* This function handles ioctl for the character device */ +static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + long timeout; + unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0; + dma_addr_t dma_handle; + int request_id = 0; + unsigned int sequence_id = 0; + unsigned char event_index, start_index; + TW_Ioctl_Driver_Command driver_command; + TW_Ioctl_Buf_Apache *tw_ioctl; + TW_Lock *tw_lock; + TW_Command_Full *full_command_packet; + TW_Compatibility_Info *tw_compat_info; + TW_Event *event; + struct timeval current_time; + u32 current_time_ms; + TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)]; + int retval = TW_IOCTL_ERROR_OS_EFAULT; + + /* Only let one of these through at a time */ + if (down_interruptible(&tw_dev->ioctl_sem)) { + retval = TW_IOCTL_ERROR_OS_EINTR; + goto out; + } + + /* First copy down the driver command */ + if (copy_from_user(&driver_command, (void *)arg, sizeof(TW_Ioctl_Driver_Command))) + goto out2; + + /* Check data buffer size */ + if (driver_command.buffer_length > TW_MAX_SECTORS * 512) { + retval = TW_IOCTL_ERROR_OS_EINVAL; + goto out2; + } + + /* Hardware can only do multiple of 512 byte transfers */ + data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511; + + /* Now allocate ioctl buf memory */ + cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle); + if (!cpu_addr) { + retval = TW_IOCTL_ERROR_OS_ENOMEM; + goto out2; + } + + tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr; + + /* Now copy down the entire ioctl */ + if (copy_from_user(tw_ioctl, (void *)arg, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1)) + goto out3; + + /* See which ioctl we are doing */ + switch (cmd) { + case TW_IOCTL_FIRMWARE_PASS_THROUGH: + spin_lock_irqsave(tw_dev->host->host_lock, flags); + twa_get_request_id(tw_dev, &request_id); + + /* Flag internal command */ + tw_dev->srb[request_id] = 0; + + /* Flag chrdev ioctl */ + tw_dev->chrdev_request_id = request_id; + + full_command_packet = &tw_ioctl->firmware_command; + + /* Load request id and sglist for both command types */ + twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted); + + memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full)); + + /* Now post the command packet to the controller */ + twa_post_command_packet(tw_dev, request_id, 1); + spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + + timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ; + + /* Now wait for command to complete */ + timeout = wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); + + /* Check if we timed out, got a signal, or didn't get + an interrupt */ + if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) { + /* Now we need to reset the board */ + if (timeout == TW_IOCTL_ERROR_OS_ERESTARTSYS) { + retval = timeout; + } else { + printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n", + tw_dev->host->host_no, TW_DRIVER, 0xc, + cmd); + retval = TW_IOCTL_ERROR_OS_EIO; + } + spin_lock_irqsave(tw_dev->host->host_lock, flags); + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + tw_dev->posted_request_count--; + twa_reset_device_extension(tw_dev); + spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + goto out3; + } + + /* Now copy in the command packet response */ + memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full)); + + /* Now complete the io */ + spin_lock_irqsave(tw_dev->host->host_lock, flags); + tw_dev->posted_request_count--; + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + break; + case TW_IOCTL_GET_COMPATIBILITY_INFO: + tw_ioctl->driver_command.status = 0; + /* Copy compatiblity struct into ioctl data buffer */ + tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer; + strncpy(tw_compat_info->driver_version, twa_driver_version, strlen(twa_driver_version)); + tw_compat_info->working_srl = tw_dev->working_srl; + tw_compat_info->working_branch = tw_dev->working_branch; + tw_compat_info->working_build = tw_dev->working_build; + break; + case TW_IOCTL_GET_LAST_EVENT: + if (tw_dev->event_queue_wrapped) { + if (tw_dev->aen_clobber) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; + tw_dev->aen_clobber = 0; + } else + tw_ioctl->driver_command.status = 0; + } else { + if (!tw_dev->error_index) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; + break; + } + tw_ioctl->driver_command.status = 0; + } + event_index = (tw_dev->error_index - 1 + TW_Q_LENGTH) % TW_Q_LENGTH; + memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); + tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; + break; + case TW_IOCTL_GET_FIRST_EVENT: + if (tw_dev->event_queue_wrapped) { + if (tw_dev->aen_clobber) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; + tw_dev->aen_clobber = 0; + } else + tw_ioctl->driver_command.status = 0; + event_index = tw_dev->error_index; + } else { + if (!tw_dev->error_index) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; + break; + } + tw_ioctl->driver_command.status = 0; + event_index = 0; + } + memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); + tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; + break; + case TW_IOCTL_GET_NEXT_EVENT: + event = (TW_Event *)tw_ioctl->data_buffer; + sequence_id = event->sequence_id; + tw_ioctl->driver_command.status = 0; + + if (tw_dev->event_queue_wrapped) { + if (tw_dev->aen_clobber) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; + tw_dev->aen_clobber = 0; + } + start_index = tw_dev->error_index; + } else { + if (!tw_dev->error_index) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; + break; + } + start_index = 0; + } + event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW_Q_LENGTH; + + if (!(tw_dev->event_queue[event_index]->sequence_id > sequence_id)) { + if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER) + tw_dev->aen_clobber = 1; + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; + break; + } + memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); + tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; + break; + case TW_IOCTL_GET_PREVIOUS_EVENT: + event = (TW_Event *)tw_ioctl->data_buffer; + sequence_id = event->sequence_id; + tw_ioctl->driver_command.status = 0; + + if (tw_dev->event_queue_wrapped) { + if (tw_dev->aen_clobber) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; + tw_dev->aen_clobber = 0; + } + start_index = tw_dev->error_index; + } else { + if (!tw_dev->error_index) { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; + break; + } + start_index = 0; + } + event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW_Q_LENGTH; + + if (!(tw_dev->event_queue[event_index]->sequence_id < sequence_id)) { + if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER) + tw_dev->aen_clobber = 1; + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; + break; + } + memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); + tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; + break; + case TW_IOCTL_GET_LOCK: + tw_lock = (TW_Lock *)tw_ioctl->data_buffer; + do_gettimeofday(¤t_time); + current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000); + + if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) { + tw_dev->ioctl_sem_lock = 1; + tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec; + tw_ioctl->driver_command.status = 0; + tw_lock->time_remaining_msec = tw_lock->timeout_msec; + } else { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED; + tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms; + } + break; + case TW_IOCTL_RELEASE_LOCK: + if (tw_dev->ioctl_sem_lock == 1) { + tw_dev->ioctl_sem_lock = 0; + tw_ioctl->driver_command.status = 0; + } else { + tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NOT_LOCKED; + } + break; + default: + retval = TW_IOCTL_ERROR_OS_ENOTTY; + goto out3; + } + + /* Now copy the entire response to userspace */ + if (copy_to_user((void *)arg, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0) + retval = 0; +out3: + /* Now free ioctl buf memory */ + pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle); +out2: + up(&tw_dev->ioctl_sem); +out: + return retval; +} /* End twa_chrdev_ioctl() */ + +/* This function handles open for the character device */ +static int twa_chrdev_open(struct inode *inode, struct file *file) +{ + unsigned int minor_number; + int retval = TW_IOCTL_ERROR_OS_ENODEV; + + minor_number = iminor(inode); + if (minor_number >= twa_device_extension_count) + goto out; + retval = 0; +out: + return retval; +} /* End twa_chrdev_open() */ + +/* This function will print readable messages from status register errors */ +static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value) +{ + int retval = 1; + + /* Check for various error conditions and handle them appropriately */ + if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "PCI Parity Error: clearing"); + writel(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); + } + + if (status_reg_value & TW_STATUS_PCI_ABORT) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "PCI Abort: clearing"); + writel(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev)); + pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT); + } + + if (status_reg_value & TW_STATUS_QUEUE_ERROR) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); + writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); + } + + if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "SBUF Write Error: clearing"); + writel(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); + } + + if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) { + if (tw_dev->reset_print == 0) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing"); + tw_dev->reset_print = 1; + } + goto out; + } + retval = 0; +out: + return retval; +} /* End twa_decode_bits() */ + +/* This function will empty the response queue */ +static int twa_empty_response_queue(TW_Device_Extension *tw_dev) +{ + u32 status_reg_value, response_que_value; + int count = 0, retval = 1; + + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + + while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) { + response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev)); + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + count++; + } + if (count == TW_MAX_RESPONSE_DRAIN) + goto out; + + retval = 0; +out: + return retval; +} /* End twa_empty_response_queue() */ + +/* This function passes sense keys from firmware to scsi layer */ +static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host) +{ + TW_Command_Full *full_command_packet; + unsigned short error; + int retval = 1; + + full_command_packet = tw_dev->command_packet_virt[request_id]; + /* Don't print error for Logical unit not supported during rollcall */ + error = full_command_packet->header.status_block.error; + if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) { + if (print_host) + printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n", + tw_dev->host->host_no, + TW_MESSAGE_SOURCE_CONTROLLER_ERROR, + full_command_packet->header.status_block.error, + twa_string_lookup(twa_error_table, + full_command_packet->header.status_block.error), + full_command_packet->header.err_specific_desc); + else + printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s:%s.\n", + TW_MESSAGE_SOURCE_CONTROLLER_ERROR, + full_command_packet->header.status_block.error, + twa_string_lookup(twa_error_table, + full_command_packet->header.status_block.error), + full_command_packet->header.err_specific_desc); + } + + if (copy_sense) { + memcpy(tw_dev->srb[request_id]->sense_buffer, full_command_packet->header.sense_data, TW_SENSE_DATA_LENGTH); + tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1); + retval = TW_ISR_DONT_RESULT; + goto out; + } + retval = 0; +out: + return retval; +} /* End twa_fill_sense() */ + +/* This function will free up device extension resources */ +static void twa_free_device_extension(TW_Device_Extension *tw_dev) +{ + if (tw_dev->command_packet_virt[0]) + pci_free_consistent(tw_dev->tw_pci_dev, + sizeof(TW_Command_Full)*TW_Q_LENGTH, + tw_dev->command_packet_virt[0], + tw_dev->command_packet_phys[0]); + + if (tw_dev->generic_buffer_virt[0]) + pci_free_consistent(tw_dev->tw_pci_dev, + TW_SECTOR_SIZE*TW_Q_LENGTH, + tw_dev->generic_buffer_virt[0], + tw_dev->generic_buffer_phys[0]); + + if (tw_dev->event_queue[0]) + kfree(tw_dev->event_queue[0]); +} /* End twa_free_device_extension() */ + +/* This function will free a request id */ +static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id) +{ + tw_dev->free_queue[tw_dev->free_tail] = request_id; + tw_dev->state[request_id] = TW_S_FINISHED; + tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH; +} /* End twa_free_request_id() */ + +/* This function will get parameter table entires from the firmware */ +static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes) +{ + TW_Command_Full *full_command_packet; + TW_Command *command_packet; + TW_Param_Apache *param; + unsigned long param_value; + void *retval = NULL; + + /* Setup the command packet */ + full_command_packet = tw_dev->command_packet_virt[request_id]; + memset(full_command_packet, 0, sizeof(TW_Command_Full)); + command_packet = &full_command_packet->command.oldcommand; + + command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM); + command_packet->size = TW_COMMAND_SIZE; + command_packet->request_id = request_id; + command_packet->byte6_offset.block_count = 1; + + /* Now setup the param */ + param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; + memset(param, 0, TW_SECTOR_SIZE); + param->table_id = table_id | 0x8000; + param->parameter_id = parameter_id; + param->parameter_size_bytes = parameter_size_bytes; + param_value = tw_dev->generic_buffer_phys[request_id]; + + command_packet->byte8_offset.param.sgl[0].address = param_value; + command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE; + + /* Post the command packet to the board */ + twa_post_command_packet(tw_dev, request_id, 1); + + /* Poll for completion */ + if (twa_poll_response(tw_dev, request_id, 30)) + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "No valid response during get param") + else + retval = (void *)&(param->data[0]); + + tw_dev->posted_request_count--; + tw_dev->state[request_id] = TW_S_INITIAL; + + return retval; +} /* End twa_get_param() */ + +/* This function will assign an available request id */ +static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id) +{ + *request_id = tw_dev->free_queue[tw_dev->free_head]; + tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH; + tw_dev->state[*request_id] = TW_S_STARTED; +} /* End twa_get_request_id() */ + +/* This function will send an initconnection command to controller */ +static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, + u32 set_features, unsigned short current_fw_srl, + unsigned short current_fw_arch_id, + unsigned short current_fw_branch, + unsigned short current_fw_build, + unsigned short *fw_on_ctlr_srl, + unsigned short *fw_on_ctlr_arch_id, + unsigned short *fw_on_ctlr_branch, + unsigned short *fw_on_ctlr_build, + u32 *init_connect_result) +{ + TW_Command_Full *full_command_packet; + TW_Initconnect *tw_initconnect; + int request_id = 0, retval = 1; + + /* Initialize InitConnection command packet */ + full_command_packet = tw_dev->command_packet_virt[request_id]; + memset(full_command_packet, 0, sizeof(TW_Command_Full)); + full_command_packet->header.header_desc.size_header = 128; + + tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand; + tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION); + tw_initconnect->request_id = request_id; + tw_initconnect->message_credits = message_credits; + tw_initconnect->features = set_features; +#if BITS_PER_LONG > 32 + /* Turn on 64-bit sgl support */ + tw_initconnect->features |= 1; +#endif + + if (set_features & TW_EXTENDED_INIT_CONNECT) { + tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED; + tw_initconnect->fw_srl = current_fw_srl; + tw_initconnect->fw_arch_id = current_fw_arch_id; + tw_initconnect->fw_branch = current_fw_branch; + tw_initconnect->fw_build = current_fw_build; + } else + tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE; + + /* Send command packet to the board */ + twa_post_command_packet(tw_dev, request_id, 1); + + /* Poll for completion */ + if (twa_poll_response(tw_dev, request_id, 30)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection"); + } else { + if (set_features & TW_EXTENDED_INIT_CONNECT) { + *fw_on_ctlr_srl = tw_initconnect->fw_srl; + *fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id; + *fw_on_ctlr_branch = tw_initconnect->fw_branch; + *fw_on_ctlr_build = tw_initconnect->fw_build; + *init_connect_result = tw_initconnect->result; + } + retval = 0; + } + + tw_dev->posted_request_count--; + tw_dev->state[request_id] = TW_S_INITIAL; + + return retval; +} /* End twa_initconnection() */ + +/* This function will initialize the fields of a device extension */ +static int twa_initialize_device_extension(TW_Device_Extension *tw_dev) +{ + int i, retval = 1; + + /* Initialize command packet buffers */ + if (twa_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Command packet memory allocation failed"); + goto out; + } + + /* Initialize generic buffer */ + if (twa_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x17, "Generic memory allocation failed"); + goto out; + } + + /* Allocate event info space */ + tw_dev->event_queue[0] = kmalloc(sizeof(TW_Event) * TW_Q_LENGTH, GFP_KERNEL); + if (!tw_dev->event_queue[0]) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed"); + goto out; + } + + memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH); + + for (i = 0; i < TW_Q_LENGTH; i++) { + tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event))); + tw_dev->free_queue[i] = i; + tw_dev->state[i] = TW_S_INITIAL; + } + + tw_dev->pending_head = TW_Q_START; + tw_dev->pending_tail = TW_Q_START; + tw_dev->free_head = TW_Q_START; + tw_dev->free_tail = TW_Q_START; + tw_dev->error_sequence_id = 1; + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; + + init_MUTEX(&tw_dev->ioctl_sem); + init_waitqueue_head(&tw_dev->ioctl_wqueue); + + retval = 0; +out: + return retval; +} /* End twa_initialize_device_extension() */ + +/* This function is the interrupt service routine */ +static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +{ + int request_id, error = 0; + u32 status_reg_value; + TW_Response_Queue response_que; + TW_Command_Full *full_command_packet; + TW_Command *command_packet; + TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance; + int handled = 0; + + /* Get the per adapter lock */ + spin_lock(tw_dev->host->host_lock); + + /* See if the interrupt matches this instance */ + if (tw_dev->tw_pci_dev->irq == (unsigned int)irq) { + + handled = 1; + + /* Read the registers */ + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + + /* Check if this is our interrupt, otherwise bail */ + if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT)) + goto twa_interrupt_bail; + + /* Check controller for errors */ + if (twa_check_bits(status_reg_value)) { + if (twa_decode_bits(tw_dev, status_reg_value)) { + TW_CLEAR_ALL_INTERRUPTS(tw_dev); + goto twa_interrupt_bail; + } + } + + /* Handle host interrupt */ + if (status_reg_value & TW_STATUS_HOST_INTERRUPT) + TW_CLEAR_HOST_INTERRUPT(tw_dev); + + /* Handle attention interrupt */ + if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) { + TW_CLEAR_ATTENTION_INTERRUPT(tw_dev); + if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) { + twa_get_request_id(tw_dev, &request_id); + + error = twa_aen_read_queue(tw_dev, request_id); + if (error) { + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags); + } + } + } + + /* Handle command interrupt */ + if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) { + TW_MASK_COMMAND_INTERRUPT(tw_dev); + /* Drain as many pending commands as we can */ + while (tw_dev->pending_request_count > 0) { + request_id = tw_dev->pending_queue[tw_dev->pending_head]; + if (tw_dev->state[request_id] != TW_S_PENDING) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x19, "Found request id that wasn't pending"); + TW_CLEAR_ALL_INTERRUPTS(tw_dev); + goto twa_interrupt_bail; + } + if (twa_post_command_packet(tw_dev, request_id, 1)==0) { + tw_dev->pending_head = (tw_dev->pending_head + 1) % TW_Q_LENGTH; + tw_dev->pending_request_count--; + } else { + /* If we get here, we will continue re-posting on the next command interrupt */ + break; + } + } + } + + /* Handle response interrupt */ + if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) { + + /* Drain the response queue from the board */ + while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) { + /* Complete the response */ + response_que.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev)); + request_id = TW_RESID_OUT(response_que.response_id); + full_command_packet = tw_dev->command_packet_virt[request_id]; + error = 0; + command_packet = &full_command_packet->command.oldcommand; + /* Check for command packet errors */ + if (full_command_packet->command.newcommand.status != 0) { + if (tw_dev->srb[request_id] != 0) { + error = twa_fill_sense(tw_dev, request_id, 1, 1); + } else { + /* Skip ioctl error prints */ + if (request_id != tw_dev->chrdev_request_id) { + error = twa_fill_sense(tw_dev, request_id, 0, 1); + } + } + } + + /* Check for correct state */ + if (tw_dev->state[request_id] != TW_S_POSTED) { + if (tw_dev->srb[request_id] != 0) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted"); + TW_CLEAR_ALL_INTERRUPTS(tw_dev); + goto twa_interrupt_bail; + } + } + + /* Check for internal command completion */ + if (tw_dev->srb[request_id] == 0) { + if (request_id != tw_dev->chrdev_request_id) { + if (twa_aen_complete(tw_dev, request_id)) + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt"); + } else { + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; + wake_up(&tw_dev->ioctl_wqueue); + } + } else { + twa_scsiop_execute_scsi_complete(tw_dev, request_id); + /* If no error command was a success */ + if (error == 0) { + tw_dev->srb[request_id]->result = (DID_OK << 16); + } + + /* If error, command failed */ + if (error == 1) { + /* Ask for a host reset */ + tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1); + } + + /* Now complete the io */ + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + tw_dev->posted_request_count--; + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + twa_unmap_scsi_data(tw_dev, request_id); + } + + /* Check for valid status after each drain */ + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + if (twa_check_bits(status_reg_value)) { + if (twa_decode_bits(tw_dev, status_reg_value)) { + TW_CLEAR_ALL_INTERRUPTS(tw_dev); + goto twa_interrupt_bail; + } + } + } + } + } +twa_interrupt_bail: + spin_unlock(tw_dev->host->host_lock); + return IRQ_RETVAL(handled); +} /* End twa_interrupt() */ + +/* This function will load the request id and various sgls for ioctls */ +static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length) +{ + TW_Command *oldcommand; + TW_Command_Apache *newcommand; + TW_SG_Entry *sgl; + + if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { + newcommand = &full_command_packet->command.newcommand; + newcommand->request_id = request_id; + newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1; + newcommand->sg_list[0].length = length; + } else { + oldcommand = &full_command_packet->command.oldcommand; + oldcommand->request_id = request_id; + + if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { + /* Load the sg list */ + sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); + sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1; + sgl->length = length; + } + } +} /* End twa_load_sgl() */ + +/* This function will perform a pci-dma mapping for a scatter gather list */ +static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id) +{ + int use_sg; + struct scsi_cmnd *cmd = tw_dev->srb[request_id]; + struct pci_dev *pdev = tw_dev->tw_pci_dev; + int retval = 0; + + if (cmd->use_sg == 0) + goto out; + + use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL); + + if (use_sg == 0) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list"); + goto out; + } + + cmd->SCp.phase = TW_PHASE_SGLIST; + cmd->SCp.have_data_in = use_sg; + retval = use_sg; +out: + return retval; +} /* End twa_map_scsi_sg_data() */ + +/* This function will perform a pci-dma map for a single buffer */ +static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int request_id) +{ + dma_addr_t mapping; + struct scsi_cmnd *cmd = tw_dev->srb[request_id]; + struct pci_dev *pdev = tw_dev->tw_pci_dev; + int retval = 0; + + if (cmd->request_bufflen == 0) { + retval = 0; + goto out; + } + + mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL); + + if (mapping == 0) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Failed to map page"); + goto out; + } + + cmd->SCp.phase = TW_PHASE_SINGLE; + cmd->SCp.have_data_in = mapping; + retval = mapping; +out: + return retval; +} /* End twa_map_scsi_single_data() */ + +/* This function will poll for a response interrupt of a request */ +static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds) +{ + int retval = 1, found = 0, response_request_id; + TW_Response_Queue response_queue; + TW_Command_Full *full_command_packet = tw_dev->command_packet_virt[request_id]; + + if (twa_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, seconds) == 0) { + response_queue.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev)); + response_request_id = TW_RESID_OUT(response_queue.response_id); + if (request_id != response_request_id) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "Found unexpected request id while polling for response"); + goto out; + } + if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { + if (full_command_packet->command.newcommand.status != 0) { + /* bad response */ + twa_fill_sense(tw_dev, request_id, 0, 0); + goto out; + } + found = 1; + } else { + if (full_command_packet->command.oldcommand.status != 0) { + /* bad response */ + twa_fill_sense(tw_dev, request_id, 0, 0); + goto out; + } + found = 1; + } + } + + if (found) + retval = 0; +out: + return retval; +} /* End twa_poll_response() */ + +/* This function will poll the status register for a flag */ +static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds) +{ + u32 status_reg_value; + unsigned long before; + int retval = 1; + + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + before = jiffies; + + if (twa_check_bits(status_reg_value)) + twa_decode_bits(tw_dev, status_reg_value); + + while ((status_reg_value & flag) != flag) { + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + + if (twa_check_bits(status_reg_value)) + twa_decode_bits(tw_dev, status_reg_value); + + if (time_after(jiffies, before + HZ * seconds)) + goto out; + + msleep(50); + } + retval = 0; +out: + return retval; +} /* End twa_poll_status() */ + +/* This function will poll the status register for disappearance of a flag */ +static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds) +{ + u32 status_reg_value; + unsigned long before; + int retval = 1; + + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + before = jiffies; + + if (twa_check_bits(status_reg_value)) + twa_decode_bits(tw_dev, status_reg_value); + + while ((status_reg_value & flag) != 0) { + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + if (twa_check_bits(status_reg_value)) + twa_decode_bits(tw_dev, status_reg_value); + + if (time_after(jiffies, before + HZ * seconds)) + goto out; + + msleep(50); + } + retval = 0; +out: + return retval; +} /* End twa_poll_status_gone() */ + +/* This function will attempt to post a command packet to the board */ +static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal) +{ + u32 status_reg_value; + unsigned long command_que_value; + int retval = 1; + + command_que_value = tw_dev->command_packet_phys[request_id]; + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + + if (twa_check_bits(status_reg_value)) + twa_decode_bits(tw_dev, status_reg_value); + + if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL)) { + + /* Only pend internal driver commands */ + if (!internal) { + retval = SCSI_MLQUEUE_HOST_BUSY; + goto out; + } + + /* Couldn't post the command packet, so we do it later */ + if (tw_dev->state[request_id] != TW_S_PENDING) { + tw_dev->state[request_id] = TW_S_PENDING; + tw_dev->pending_request_count++; + if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) { + tw_dev->max_pending_request_count = tw_dev->pending_request_count; + } + tw_dev->pending_queue[tw_dev->pending_tail] = request_id; + tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH; + } + TW_UNMASK_COMMAND_INTERRUPT(tw_dev); + goto out; + } else { + /* We successfully posted the command packet */ +#if BITS_PER_LONG > 32 + writeq(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); +#else + writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); +#endif + tw_dev->state[request_id] = TW_S_POSTED; + tw_dev->posted_request_count++; + if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) { + tw_dev->max_posted_request_count = tw_dev->posted_request_count; + } + } + retval = 0; +out: + return retval; +} /* End twa_post_command_packet() */ + +/* This function will reset a device extension */ +static int twa_reset_device_extension(TW_Device_Extension *tw_dev) +{ + int i = 0; + int retval = 1; + + /* Abort all requests that are in progress */ + for (i = 0; i < TW_Q_LENGTH; i++) { + if ((tw_dev->state[i] != TW_S_FINISHED) && + (tw_dev->state[i] != TW_S_INITIAL) && + (tw_dev->state[i] != TW_S_COMPLETED)) { + if (tw_dev->srb[i]) { + tw_dev->srb[i]->result = (DID_RESET << 16); + tw_dev->srb[i]->scsi_done(tw_dev->srb[i]); + twa_unmap_scsi_data(tw_dev, i); + } + } + } + + /* Reset queues and counts */ + for (i = 0; i < TW_Q_LENGTH; i++) { + tw_dev->free_queue[i] = i; + tw_dev->state[i] = TW_S_INITIAL; + } + tw_dev->free_head = TW_Q_START; + tw_dev->free_tail = TW_Q_START; + tw_dev->posted_request_count = 0; + tw_dev->pending_request_count = 0; + tw_dev->pending_head = TW_Q_START; + tw_dev->pending_tail = TW_Q_START; + tw_dev->reset_print = 0; + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; + tw_dev->flags = 0; + + TW_DISABLE_INTERRUPTS(tw_dev); + + if (twa_reset_sequence(tw_dev, 1)) + goto out; + + TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); + + retval = 0; +out: + return retval; +} /* End twa_reset_device_extension() */ + +/* This function will reset a controller */ +static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset) +{ + int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset; + + while (tries < TW_MAX_RESET_TRIES) { + if (do_soft_reset) + TW_SOFT_RESET(tw_dev); + + /* Make sure controller is in a good state */ + if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 30)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Microcontroller not ready during reset sequence"); + do_soft_reset = 1; + tries++; + continue; + } + + /* Empty response queue */ + if (twa_empty_response_queue(tw_dev)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Response queue empty failed during reset sequence"); + do_soft_reset = 1; + tries++; + continue; + } + + flashed = 0; + + /* Check for compatibility/flash */ + if (twa_check_srl(tw_dev, &flashed)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Compatibility check failed during reset sequence"); + do_soft_reset = 1; + tries++; + continue; + } else { + if (flashed) { + tries++; + continue; + } + } + + /* Drain the AEN queue */ + if (twa_aen_drain_queue(tw_dev, soft_reset)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x22, "AEN drain failed during reset sequence"); + do_soft_reset = 1; + tries++; + continue; + } + + /* If we got here, controller is in a good state */ + retval = 0; + goto out; + } +out: + return retval; +} /* End twa_reset_sequence() */ + +/* This funciton returns unit geometry in cylinders/heads/sectors */ +static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) +{ + int heads, sectors, cylinders; + TW_Device_Extension *tw_dev; + + tw_dev = (TW_Device_Extension *)sdev->host->hostdata; + + if (capacity >= 0x200000) { + heads = 255; + sectors = 63; + cylinders = sector_div(capacity, heads * sectors); + } else { + heads = 64; + sectors = 32; + cylinders = sector_div(capacity, heads * sectors); + } + + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + + return 0; +} /* End twa_scsi_biosparam() */ + +/* This is the new scsi eh abort function */ +static int twa_scsi_eh_abort(struct scsi_cmnd *SCpnt) +{ + int i; + TW_Device_Extension *tw_dev = NULL; + int retval = FAILED; + + tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; + + spin_unlock_irq(tw_dev->host->host_lock); + + tw_dev->num_aborts++; + + /* If we find any IO's in process, we have to reset the card */ + for (i = 0; i < TW_Q_LENGTH; i++) { + if ((tw_dev->state[i] != TW_S_FINISHED) && (tw_dev->state[i] != TW_S_INITIAL)) { + printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", + tw_dev->host->host_no, TW_DRIVER, 0x2c, + SCpnt->device->id, SCpnt->cmnd[0]); + if (twa_reset_device_extension(tw_dev)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2a, "Controller reset failed during scsi abort"); + goto out; + } + break; + } + } + retval = SUCCESS; +out: + spin_lock_irq(tw_dev->host->host_lock); + return retval; +} /* End twa_scsi_eh_abort() */ + +/* This is the new scsi eh reset function */ +static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) +{ + TW_Device_Extension *tw_dev = NULL; + int retval = FAILED; + + tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; + + spin_unlock_irq(tw_dev->host->host_lock); + + tw_dev->num_resets++; + + printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset started.\n", tw_dev->host->host_no); + + /* Now reset the card and some of the device extension data */ + if (twa_reset_device_extension(tw_dev)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); + goto out; + } + printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset succeeded.\n", tw_dev->host->host_no); + retval = SUCCESS; +out: + spin_lock_irq(tw_dev->host->host_lock); + return retval; +} /* End twa_scsi_eh_reset() */ + +/* This is the main scsi queue function to handle scsi opcodes */ +static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +{ + int request_id, retval; + TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; + + /* Save done function into scsi_cmnd struct */ + SCpnt->scsi_done = done; + + /* Get a free request id */ + twa_get_request_id(tw_dev, &request_id); + + /* Save the scsi command for use by the ISR */ + tw_dev->srb[request_id] = SCpnt; + + /* Initialize phase to zero */ + SCpnt->SCp.phase = TW_PHASE_INITIAL; + + retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL); + switch (retval) { + case SCSI_MLQUEUE_HOST_BUSY: + twa_free_request_id(tw_dev, request_id); + break; + case 1: + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + SCpnt->result = (DID_ERROR << 16); + done(SCpnt); + } + + return retval; +} /* End twa_scsi_queue() */ + +/* This function hands scsi cdb's to the firmware */ +static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg) +{ + TW_Command_Full *full_command_packet; + TW_Command_Apache *command_packet; + u32 num_sectors = 0x0; + int i, sg_count; + struct scsi_cmnd *srb = NULL; + struct scatterlist *sglist = NULL; + u32 buffaddr = 0x0; + int retval = 1; + + if (tw_dev->srb[request_id]) { + if (tw_dev->srb[request_id]->request_buffer) { + sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer; + } + srb = tw_dev->srb[request_id]; + } + + /* Initialize command packet */ + full_command_packet = tw_dev->command_packet_virt[request_id]; + full_command_packet->header.header_desc.size_header = 128; + full_command_packet->header.status_block.error = 0; + full_command_packet->header.status_block.severity__reserved = 0; + + command_packet = &full_command_packet->command.newcommand; + command_packet->status = 0; + command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI); + + /* We forced 16 byte cdb use earlier */ + if (!cdb) + memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN); + else + memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN); + + if (srb) + command_packet->unit = srb->device->id; + else + command_packet->unit = 0; + + command_packet->request_id = request_id; + command_packet->sgl_offset = 16; + + if (!sglistarg) { + /* Map sglist from scsi layer to cmd packet */ + if (tw_dev->srb[request_id]->use_sg == 0) { + if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) { + command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id]; + command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH; + } else { + buffaddr = twa_map_scsi_single_data(tw_dev, request_id); + if (buffaddr == 0) + goto out; + + command_packet->sg_list[0].address = buffaddr; + command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen; + } + command_packet->sgl_entries = 1; + + if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi"); + goto out; + } + } + + if (tw_dev->srb[request_id]->use_sg > 0) { + sg_count = twa_map_scsi_sg_data(tw_dev, request_id); + if (sg_count == 0) + goto out; + + for (i = 0; i < sg_count; i++) { + command_packet->sg_list[i].address = sg_dma_address(&sglist[i]); + command_packet->sg_list[i].length = sg_dma_len(&sglist[i]); + if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi"); + goto out; + } + } + command_packet->sgl_entries = tw_dev->srb[request_id]->use_sg; + } + } else { + /* Internal cdb post */ + for (i = 0; i < use_sg; i++) { + command_packet->sg_list[i].address = sglistarg[i].address; + command_packet->sg_list[i].length = sglistarg[i].length; + if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post"); + goto out; + } + } + command_packet->sgl_entries = use_sg; + } + + if (srb) { + if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) + num_sectors = (u32)srb->cmnd[4]; + + if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) + num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8); + } + + /* Update sector statistic */ + tw_dev->sector_count = num_sectors; + if (tw_dev->sector_count > tw_dev->max_sector_count) + tw_dev->max_sector_count = tw_dev->sector_count; + + /* Update SG statistics */ + if (srb) { + tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg; + if (tw_dev->sgl_entries > tw_dev->max_sgl_entries) + tw_dev->max_sgl_entries = tw_dev->sgl_entries; + } + + /* Now post the command to the board */ + if (srb) { + retval = twa_post_command_packet(tw_dev, request_id, 0); + } else { + twa_post_command_packet(tw_dev, request_id, 1); + retval = 0; + } +out: + return retval; +} /* End twa_scsiop_execute_scsi() */ + +/* This function completes an execute scsi operation */ +static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id) +{ + /* Copy the response if too small */ + if ((tw_dev->srb[request_id]->request_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) { + memcpy(tw_dev->srb[request_id]->request_buffer, + tw_dev->generic_buffer_virt[request_id], + tw_dev->srb[request_id]->request_bufflen); + } +} /* End twa_scsiop_execute_scsi_complete() */ + +/* This function tells the controller to shut down */ +static void __twa_shutdown(TW_Device_Extension *tw_dev) +{ + /* Disable interrupts */ + TW_DISABLE_INTERRUPTS(tw_dev); + + printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no); + + /* Tell the card we are shutting down */ + if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x31, "Connection shutdown failed"); + } else { + printk(KERN_WARNING "3w-9xxx: Shutdown complete.\n"); + } + + /* Clear all interrupts just before exit */ + TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); +} /* End __twa_shutdown() */ + +/* Wrapper for __twa_shutdown */ +static void twa_shutdown(struct device *dev) +{ + struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); + TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; + + __twa_shutdown(tw_dev); +} /* End twa_shutdown() */ + +/* This function will look up a string */ +static char *twa_string_lookup(twa_message_type *table, unsigned int code) +{ + int index; + + for (index = 0; ((code != table[index].code) && + (table[index].text != (char *)0)); index++); + return(table[index].text); +} /* End twa_string_lookup() */ + +/* This function will perform a pci-dma unmap */ +static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id) +{ + struct scsi_cmnd *cmd = tw_dev->srb[request_id]; + struct pci_dev *pdev = tw_dev->tw_pci_dev; + + switch(cmd->SCp.phase) { + case TW_PHASE_SINGLE: + pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL); + break; + case TW_PHASE_SGLIST: + pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL); + break; + } +} /* End twa_unmap_scsi_data() */ + +/* scsi_host_template initializer */ +static struct scsi_host_template driver_template = { + .module = THIS_MODULE, + .name = "3ware 9000 Storage Controller", + .queuecommand = twa_scsi_queue, + .eh_abort_handler = twa_scsi_eh_abort, + .eh_host_reset_handler = twa_scsi_eh_reset, + .bios_param = twa_scsi_biosparam, + .can_queue = TW_Q_LENGTH-2, + .this_id = -1, + .sg_tablesize = TW_APACHE_MAX_SGL_LENGTH, + .max_sectors = TW_MAX_SECTORS, + .cmd_per_lun = TW_MAX_CMDS_PER_LUN, + .use_clustering = ENABLE_CLUSTERING, + .shost_attrs = twa_host_attrs, + .sdev_attrs = twa_dev_attrs, + .emulated = 1 +}; + +/* This function will probe and initialize a card */ +static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) +{ + struct Scsi_Host *host = NULL; + TW_Device_Extension *tw_dev; + u32 mem_addr; + int retval = -ENODEV; + + retval = pci_enable_device(pdev); + if (retval) { + TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device"); + goto out_disable_device; + } + + pci_set_master(pdev); + + retval = pci_set_dma_mask(pdev, TW_DMA_MASK); + if (retval) { + TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); + goto out_disable_device; + } + + host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension)); + if (!host) { + TW_PRINTK(host, TW_DRIVER, 0x24, "Failed to allocate memory for device extension"); + retval = -ENOMEM; + goto out_disable_device; + } + tw_dev = (TW_Device_Extension *)host->hostdata; + + memset(tw_dev, 0, sizeof(TW_Device_Extension)); + + /* Save values to device extension */ + tw_dev->host = host; + tw_dev->tw_pci_dev = pdev; + + if (twa_initialize_device_extension(tw_dev)) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x25, "Failed to initialize device extension"); + goto out_free_device_extension; + } + + /* Request IO regions */ + retval = pci_request_regions(pdev, "3w-9xxx"); + if (retval) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Failed to get mem region"); + goto out_free_device_extension; + } + + mem_addr = pci_resource_start(pdev, 1); + + /* Save base address */ + tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE); + if (!tw_dev->base_addr) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap"); + goto out_release_mem_region; + } + + /* Disable interrupts on the card */ + TW_DISABLE_INTERRUPTS(tw_dev); + + /* Initialize the card */ + if (twa_reset_sequence(tw_dev, 0)) + goto out_release_mem_region; + + /* Set host specific parameters */ + host->max_id = TW_MAX_UNITS; + host->max_cmd_len = TW_MAX_CDB_LEN; + + /* Luns and channels aren't supported by adapter */ + host->max_lun = 0; + host->max_channel = 0; + + /* Register the card with the kernel SCSI layer */ + retval = scsi_add_host(host, &pdev->dev); + if (retval) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed"); + goto out_release_mem_region; + } + + pci_set_drvdata(pdev, host); + + printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%x, IRQ: %d.\n", + host->host_no, mem_addr, pdev->irq); + printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n", + host->host_no, + (char *)twa_get_param(tw_dev, 0, TW_VERSION_TABLE, + TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH), + (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE, + TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH), + *(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, + TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH)); + + /* Now setup the interrupt handler */ + retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev); + if (retval) { + TW_PRINTK(tw_dev->host, TW_DRIVER, 0x30, "Error requesting IRQ"); + goto out_remove_host; + } + + twa_device_extension_list[twa_device_extension_count] = tw_dev; + twa_device_extension_count++; + + /* Re-enable interrupts on the card */ + TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); + + /* Finally, scan the host */ + scsi_scan_host(host); + + if (twa_major == -1) { + if ((twa_major = register_chrdev (0, "twa", &twa_fops)) < 0) + TW_PRINTK(host, TW_DRIVER, 0x29, "Failed to register character device"); + } + return 0; + +out_remove_host: + scsi_remove_host(host); +out_release_mem_region: + pci_release_regions(pdev); +out_free_device_extension: + twa_free_device_extension(tw_dev); + scsi_host_put(host); +out_disable_device: + pci_disable_device(pdev); + + return retval; +} /* End twa_probe() */ + +/* This function is called to remove a device */ +static void twa_remove(struct pci_dev *pdev) +{ + struct Scsi_Host *host = pci_get_drvdata(pdev); + TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; + + scsi_remove_host(tw_dev->host); + + __twa_shutdown(tw_dev); + + /* Free up the IRQ */ + free_irq(tw_dev->tw_pci_dev->irq, tw_dev); + + /* Free up the mem region */ + pci_release_regions(pdev); + + /* Free up device extension resources */ + twa_free_device_extension(tw_dev); + + /* Unregister character device */ + if (twa_major >= 0) { + unregister_chrdev(twa_major, "twa"); + twa_major = -1; + } + + scsi_host_put(tw_dev->host); + pci_disable_device(pdev); + twa_device_extension_count--; +} /* End twa_remove() */ + +/* PCI Devices supported by this driver */ +static struct pci_device_id twa_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { } +}; +MODULE_DEVICE_TABLE(pci, twa_pci_tbl); + +/* pci_driver initializer */ +static struct pci_driver twa_driver = { + .name = "3w-9xxx", + .id_table = twa_pci_tbl, + .probe = twa_probe, + .remove = twa_remove, + .driver = { + .shutdown = twa_shutdown + } +}; + +/* This function is called on driver initialization */ +static int __init twa_init(void) +{ + printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", twa_driver_version); + + return pci_module_init(&twa_driver); +} /* End twa_init() */ + +/* This function is called on driver exit */ +static void __exit twa_exit(void) +{ + pci_unregister_driver(&twa_driver); +} /* End twa_exit() */ + +module_init(twa_init); +module_exit(twa_exit); + diff -Nru a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/scsi/3w-9xxx.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,704 @@ +/* + 3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux. + + Written By: Adam Radford + + Copyright (C) 2004 Applied Micro Circuits 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; version 2 of the License. + + 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. + + NO WARRANTY + THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT + LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + solely responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to + the risks and costs of program errors, damage to or loss of data, + programs or equipment, and unavailability or interruption of operations. + + DISCLAIMER OF LIABILITY + NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + + 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 + + Bugs/Comments/Suggestions should be mailed to: + linuxraid@amcc.com + + For more information, goto: + http://www.amcc.com +*/ + +#ifndef _3W_9XXX_H +#define _3W_9XXX_H + +/* AEN string type */ +typedef struct TAG_twa_message_type { + unsigned int code; + char* text; +} twa_message_type; + +/* AEN strings */ +static twa_message_type twa_aen_table[] = { + {0x0000, "AEN queue empty"}, + {0x0001, "Controller reset occurred"}, + {0x0002, "Degraded unit detected"}, + {0x0003, "Controller error occured"}, + {0x0004, "Background rebuild failed"}, + {0x0005, "Background rebuild done"}, + {0x0006, "Incomplete unit detected"}, + {0x0007, "Background initialize done"}, + {0x0008, "Unclean shutdown detected"}, + {0x0009, "Drive timeout detected"}, + {0x000A, "Drive error detected"}, + {0x000B, "Rebuild started"}, + {0x000C, "Background initialize started"}, + {0x000D, "Entire logical unit was deleted"}, + {0x000E, "Background initialize failed"}, + {0x000F, "SMART attribute exceeded threshold"}, + {0x0010, "Power supply reported AC under range"}, + {0x0011, "Power supply reported DC out of range"}, + {0x0012, "Power supply reported a malfunction"}, + {0x0013, "Power supply predicted malfunction"}, + {0x0014, "Battery charge is below threshold"}, + {0x0015, "Fan speed is below threshold"}, + {0x0016, "Temperature sensor is above threshold"}, + {0x0017, "Power supply was removed"}, + {0x0018, "Power supply was inserted"}, + {0x0019, "Drive was removed from a bay"}, + {0x001A, "Drive was inserted into a bay"}, + {0x001B, "Drive bay cover door was opened"}, + {0x001C, "Drive bay cover door was closed"}, + {0x001D, "Product case was opened"}, + {0x0020, "Prepare for shutdown (power-off)"}, + {0x0021, "Downgrade UDMA mode to lower speed"}, + {0x0022, "Upgrade UDMA mode to higher speed"}, + {0x0023, "Sector repair completed"}, + {0x0024, "Sbuf memory test failed"}, + {0x0025, "Error flushing cached write data to array"}, + {0x0026, "Drive reported data ECC error"}, + {0x0027, "DCB has checksum error"}, + {0x0028, "DCB version is unsupported"}, + {0x0029, "Background verify started"}, + {0x002A, "Background verify failed"}, + {0x002B, "Background verify done"}, + {0x002C, "Bad sector overwritten during rebuild"}, + {0x002D, "Background rebuild error on source drive"}, + {0x002E, "Replace failed because replacement drive too small"}, + {0x002F, "Verify failed because array was never initialized"}, + {0x0030, "Unsupported ATA drive"}, + {0x0031, "Synchronize host/controller time"}, + {0x0032, "Spare capacity is inadequate for some units"}, + {0x0033, "Background migration started"}, + {0x0034, "Background migration failed"}, + {0x0035, "Background migration done"}, + {0x0036, "Verify detected and fixed data/parity mismatch"}, + {0x0037, "SO-DIMM incompatible"}, + {0x0038, "SO-DIMM not detected"}, + {0x0039, "Corrected Sbuf ECC error"}, + {0x003A, "Drive power on reset detected"}, + {0x003B, "Background rebuild paused"}, + {0x003C, "Background initialize paused"}, + {0x003D, "Background verify paused"}, + {0x003E, "Background migration paused"}, + {0x003F, "Corrupt flash file system detected"}, + {0x0040, "Flash file system repaired"}, + {0x0041, "Unit number assignments were lost"}, + {0x0042, "Error during read of primary DCB"}, + {0x0043, "Latent error found in backup DCB"}, + {0x00FC, "Recovered/finished array membership update"}, + {0x00FD, "Handler lockup"}, + {0x00FE, "Retrying PCI transfer"}, + {0x00FF, "AEN queue is full"}, + {0xFFFFFFFF, (char*) 0} +}; + +/* AEN severity table */ +static char *twa_aen_severity_table[] = +{ + "None", "ERROR", "WARNING", "INFO", "DEBUG", (char*) 0 +}; + +/* Error strings */ +static twa_message_type twa_error_table[] = { + {0x0100, "SGL entry contains zero data"}, + {0x0101, "Invalid command opcode"}, + {0x0102, "SGL entry has unaligned address"}, + {0x0103, "SGL size does not match command"}, + {0x0104, "SGL entry has illegal length"}, + {0x0105, "Command packet is not aligned"}, + {0x0106, "Invalid request ID"}, + {0x0107, "Duplicate request ID"}, + {0x0108, "ID not locked"}, + {0x0109, "LBA out of range"}, + {0x010A, "Logical unit not supported"}, + {0x010B, "Parameter table does not exist"}, + {0x010C, "Parameter index does not exist"}, + {0x010D, "Invalid field in CDB"}, + {0x010E, "Specified port has invalid drive"}, + {0x010F, "Parameter item size mismatch"}, + {0x0110, "Failed memory allocation"}, + {0x0111, "Memory request too large"}, + {0x0112, "Out of memory segments"}, + {0x0113, "Invalid address to deallocate"}, + {0x0114, "Out of memory"}, + {0x0115, "Out of heap"}, + {0x0120, "Double degrade"}, + {0x0121, "Drive not degraded"}, + {0x0122, "Reconstruct error"}, + {0x0123, "Replace not accepted"}, + {0x0124, "Replace drive capacity too small"}, + {0x0125, "Sector count not allowed"}, + {0x0126, "No spares left"}, + {0x0127, "Reconstruct error"}, + {0x0128, "Unit is offline"}, + {0x0129, "Cannot update status to DCB"}, + {0x0130, "Invalid stripe handle"}, + {0x0131, "Handle that was not locked"}, + {0x0132, "Handle that was not empty"}, + {0x0133, "Handle has different owner"}, + {0x0140, "IPR has parent"}, + {0x0150, "Illegal Pbuf address alignment"}, + {0x0151, "Illegal Pbuf transfer length"}, + {0x0152, "Illegal Sbuf address alignment"}, + {0x0153, "Illegal Sbuf transfer length"}, + {0x0160, "Command packet too large"}, + {0x0161, "SGL exceeds maximum length"}, + {0x0162, "SGL has too many entries"}, + {0x0170, "Insufficient resources for rebuilder"}, + {0x0171, "Verify error (data != parity)"}, + {0x0180, "Requested segment not in directory of this DCB"}, + {0x0181, "DCB segment has unsupported version"}, + {0x0182, "DCB segment has checksum error"}, + {0x0183, "DCB support (settings) segment invalid"}, + {0x0184, "DCB UDB (unit descriptor block) segment invalid"}, + {0x0185, "DCB GUID (globally unique identifier) segment invalid"}, + {0x01A0, "Could not clear Sbuf"}, + {0x01C0, "Flash identify failed"}, + {0x01C1, "Flash out of bounds"}, + {0x01C2, "Flash verify error"}, + {0x01C3, "Flash file object not found"}, + {0x01C4, "Flash file already present"}, + {0x01C5, "Flash file system full"}, + {0x01C6, "Flash file not present"}, + {0x01C7, "Flash file size error"}, + {0x01C8, "Bad flash file checksum"}, + {0x01CA, "Corrupt flash file system detected"}, + {0x01D0, "Invalid field in parameter list"}, + {0x01D1, "Parameter list length error"}, + {0x01D2, "Parameter item is not changeable"}, + {0x01D3, "Parameter item is not saveable"}, + {0x0200, "UDMA CRC error"}, + {0x0201, "Internal CRC error"}, + {0x0202, "Data ECC error"}, + {0x0203, "ADP level 1 error"}, + {0x0204, "Port timeout"}, + {0x0205, "Drive power on reset"}, + {0x0206, "ADP level 2 error"}, + {0x0207, "Soft reset failed"}, + {0x0208, "Drive not ready"}, + {0x0209, "Unclassified port error"}, + {0x020A, "Drive aborted command"}, + {0x0210, "Internal CRC error"}, + {0x0211, "PCI abort error"}, + {0x0212, "PCI parity error"}, + {0x0213, "Port handler error"}, + {0x0214, "Token interrupt count error"}, + {0x0215, "Timeout waiting for PCI transfer"}, + {0x0216, "Corrected buffer ECC"}, + {0x0217, "Uncorrected buffer ECC"}, + {0x0230, "Unsupported command during flash recovery"}, + {0x0231, "Next image buffer expected"}, + {0x0232, "Binary image architecture incompatible"}, + {0x0233, "Binary image has no signature"}, + {0x0234, "Binary image has bad checksum"}, + {0x0235, "Image downloaded overflowed buffer"}, + {0x0240, "I2C device not found"}, + {0x0241, "I2C transaction aborted"}, + {0x0242, "SO-DIMM parameter(s) incompatible using defaults"}, + {0x0243, "SO-DIMM unsupported"}, + {0x0248, "SPI transfer status error"}, + {0x0249, "SPI transfer timeout error"}, + {0x0250, "Invalid unit descriptor size in CreateUnit"}, + {0x0251, "Unit descriptor size exceeds data buffer in CreateUnit"}, + {0x0252, "Invalid value in CreateUnit descriptor"}, + {0x0253, "Inadequate disk space to support descriptor in CreateUnit"}, + {0x0254, "Unable to create data channel for this unit descriptor"}, + {0x0255, "CreateUnit descriptor specifies a drive already in use"}, + {0x0256, "Unable to write configuration to all disks during CreateUnit"}, + {0x0257, "CreateUnit does not support this descriptor version"}, + {0x0258, "Invalid subunit for RAID 0 or 5 in CreateUnit"}, + {0x0259, "Too many descriptors in CreateUnit"}, + {0x025A, "Invalid configuration specified in CreateUnit descriptor"}, + {0x025B, "Invalid LBA offset specified in CreateUnit descriptor"}, + {0x025C, "Invalid stripelet size specified in CreateUnit descriptor"}, + {0x0260, "SMART attribute exceeded threshold"}, + {0xFFFFFFFF, (char*) 0} +}; + +/* Control register bit definitions */ +#define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000 +#define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT 0x00040000 +#define TW_CONTROL_MASK_COMMAND_INTERRUPT 0x00020000 +#define TW_CONTROL_MASK_RESPONSE_INTERRUPT 0x00010000 +#define TW_CONTROL_UNMASK_COMMAND_INTERRUPT 0x00008000 +#define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT 0x00004000 +#define TW_CONTROL_CLEAR_ERROR_STATUS 0x00000200 +#define TW_CONTROL_ISSUE_SOFT_RESET 0x00000100 +#define TW_CONTROL_ENABLE_INTERRUPTS 0x00000080 +#define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040 +#define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020 +#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000 +#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000 +#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000 +#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR 0x00000008 + +/* Status register bit definitions */ +#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000 +#define TW_STATUS_MINOR_VERSION_MASK 0x0F000000 +#define TW_STATUS_PCI_PARITY_ERROR 0x00800000 +#define TW_STATUS_QUEUE_ERROR 0x00400000 +#define TW_STATUS_MICROCONTROLLER_ERROR 0x00200000 +#define TW_STATUS_PCI_ABORT 0x00100000 +#define TW_STATUS_HOST_INTERRUPT 0x00080000 +#define TW_STATUS_ATTENTION_INTERRUPT 0x00040000 +#define TW_STATUS_COMMAND_INTERRUPT 0x00020000 +#define TW_STATUS_RESPONSE_INTERRUPT 0x00010000 +#define TW_STATUS_COMMAND_QUEUE_FULL 0x00008000 +#define TW_STATUS_RESPONSE_QUEUE_EMPTY 0x00004000 +#define TW_STATUS_MICROCONTROLLER_READY 0x00002000 +#define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000 +#define TW_STATUS_EXPECTED_BITS 0x00002000 +#define TW_STATUS_UNEXPECTED_BITS 0x00F00008 +#define TW_STATUS_SBUF_WRITE_ERROR 0x00000008 +#define TW_STATUS_VALID_INTERRUPT 0x00DF0008 + +/* RESPONSE QUEUE BIT DEFINITIONS */ +#define TW_RESPONSE_ID_MASK 0x00000FF0 + +/* PCI related defines */ +#define TW_DEVICE_NAME "3w-9xxx" +#define TW_NUMDEVICES 1 +#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 +#define TW_PCI_CLEAR_PCI_ABORT 0x2000 + +/* Command packet opcodes used by the driver */ +#define TW_OP_INIT_CONNECTION 0x1 +#define TW_OP_GET_PARAM 0x12 +#define TW_OP_SET_PARAM 0x13 +#define TW_OP_EXECUTE_SCSI 0x10 +#define TW_OP_DOWNLOAD_FIRMWARE 0x16 +#define TW_OP_RESET 0x1C + +/* Asynchronous Event Notification (AEN) codes used by the driver */ +#define TW_AEN_QUEUE_EMPTY 0x0000 +#define TW_AEN_SOFT_RESET 0x0001 +#define TW_AEN_SYNC_TIME_WITH_HOST 0x031 +#define TW_AEN_SEVERITY_ERROR 0x1 +#define TW_AEN_SEVERITY_DEBUG 0x4 +#define TW_AEN_NOT_RETRIEVED 0x1 +#define TW_AEN_RETRIEVED 0x2 + +/* Command state defines */ +#define TW_S_INITIAL 0x1 /* Initial state */ +#define TW_S_STARTED 0x2 /* Id in use */ +#define TW_S_POSTED 0x4 /* Posted to the controller */ +#define TW_S_PENDING 0x8 /* Waiting to be posted in isr */ +#define TW_S_COMPLETED 0x10 /* Completed by isr */ +#define TW_S_FINISHED 0x20 /* I/O completely done */ + +/* Compatibility defines */ +#define TW_9000_ARCH_ID 0x5 +#define TW_CURRENT_FW_SRL 24 +#define TW_CURRENT_FW_BUILD 5 +#define TW_CURRENT_FW_BRANCH 1 + +/* Phase defines */ +#define TW_PHASE_INITIAL 0 +#define TW_PHASE_SINGLE 1 +#define TW_PHASE_SGLIST 2 + +/* Misc defines */ +#define TW_SECTOR_SIZE 512 +#define TW_ALIGNMENT_9000 4 /* 4 bytes */ +#define TW_ALIGNMENT_9000_SGL 0x3 +#define TW_MAX_UNITS 16 +#define TW_INIT_MESSAGE_CREDITS 0x100 +#define TW_INIT_COMMAND_PACKET_SIZE 0x3 +#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6 +#define TW_EXTENDED_INIT_CONNECT 0x2 +#define TW_BUNDLED_FW_SAFE_TO_FLASH 0x4 +#define TW_CTLR_FW_RECOMMENDS_FLASH 0x8 +#define TW_CTLR_FW_COMPATIBLE 0x2 +#define TW_BASE_FW_SRL 0x17 +#define TW_BASE_FW_BRANCH 0 +#define TW_BASE_FW_BUILD 1 +#if BITS_PER_LONG > 32 +#define TW_APACHE_MAX_SGL_LENGTH 72 +#define TW_ESCALADE_MAX_SGL_LENGTH 41 +#define TW_APACHE_CMD_PKT_SIZE 5 +#else +#define TW_APACHE_MAX_SGL_LENGTH 109 +#define TW_ESCALADE_MAX_SGL_LENGTH 62 +#define TW_APACHE_CMD_PKT_SIZE 4 +#endif +#define TW_ATA_PASS_SGL_MAX 60 +#define TW_Q_LENGTH 256 +#define TW_Q_START 0 +#define TW_MAX_SLOT 32 +#define TW_MAX_RESET_TRIES 2 +#define TW_MAX_CMDS_PER_LUN 254 +#define TW_MAX_RESPONSE_DRAIN 256 +#define TW_MAX_AEN_DRAIN 40 +#define TW_IN_IOCTL 2 +#define TW_IN_CHRDEV_IOCTL 3 +#define TW_IN_ATTENTION_LOOP 4 +#define TW_MAX_SECTORS 256 +#define TW_AEN_WAIT_TIME 1000 +#define TW_IOCTL_WAIT_TIME (1 * HZ) /* 1 second */ +#define TW_MAX_CDB_LEN 16 +#define TW_ISR_DONT_COMPLETE 2 +#define TW_ISR_DONT_RESULT 3 +#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */ +#define TW_IOCTL_CHRDEV_FREE -1 +#define TW_COMMAND_OFFSET 128 /* 128 bytes */ +#define TW_VERSION_TABLE 0x0402 +#define TW_TIMEKEEP_TABLE 0x040A +#define TW_INFORMATION_TABLE 0x0403 +#define TW_PARAM_FWVER 3 +#define TW_PARAM_FWVER_LENGTH 16 +#define TW_PARAM_BIOSVER 4 +#define TW_PARAM_BIOSVER_LENGTH 16 +#define TW_PARAM_PORTCOUNT 3 +#define TW_PARAM_PORTCOUNT_LENGTH 1 +#define TW_MIN_SGL_LENGTH 0x200 /* 512 bytes */ +#define TW_MAX_SENSE_LENGTH 256 +#define TW_EVENT_SOURCE_AEN 0x1000 +#define TW_EVENT_SOURCE_COMMAND 0x1001 +#define TW_EVENT_SOURCE_PCHIP 0x1002 +#define TW_EVENT_SOURCE_DRIVER 0x1003 +#define TW_IOCTL_GET_COMPATIBILITY_INFO 0x101 +#define TW_IOCTL_GET_LAST_EVENT 0x102 +#define TW_IOCTL_GET_FIRST_EVENT 0x103 +#define TW_IOCTL_GET_NEXT_EVENT 0x104 +#define TW_IOCTL_GET_PREVIOUS_EVENT 0x105 +#define TW_IOCTL_GET_LOCK 0x106 +#define TW_IOCTL_RELEASE_LOCK 0x107 +#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108 +#define TW_IOCTL_ERROR_STATUS_NOT_LOCKED 0x1001 // Not locked +#define TW_IOCTL_ERROR_STATUS_LOCKED 0x1002 // Already locked +#define TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS 0x1003 // No more events +#define TW_IOCTL_ERROR_STATUS_AEN_CLOBBER 0x1004 // AEN clobber occurred +#define TW_IOCTL_ERROR_OS_EFAULT -EFAULT // Bad address +#define TW_IOCTL_ERROR_OS_EINTR -EINTR // Interrupted system call +#define TW_IOCTL_ERROR_OS_EINVAL -EINVAL // Invalid argument +#define TW_IOCTL_ERROR_OS_ENOMEM -ENOMEM // Out of memory +#define TW_IOCTL_ERROR_OS_ERESTARTSYS -ERESTARTSYS // Restart system call +#define TW_IOCTL_ERROR_OS_EIO -EIO // I/O error +#define TW_IOCTL_ERROR_OS_ENOTTY -ENOTTY // Not a typewriter +#define TW_IOCTL_ERROR_OS_ENODEV -ENODEV // No such device +#define TW_ALLOCATION_LENGTH 128 +#define TW_SENSE_DATA_LENGTH 18 +#define TW_STATUS_CHECK_CONDITION 2 +#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x10a +#define TW_ERROR_UNIT_OFFLINE 0x128 +#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR 3 +#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT 4 +#define TW_MESSAGE_SOURCE_LINUX_DRIVER 6 +#define TW_DRIVER TW_MESSAGE_SOURCE_LINUX_DRIVER +#define TW_MESSAGE_SOURCE_LINUX_OS 9 +#define TW_OS TW_MESSAGE_SOURCE_LINUX_OS +#if BITS_PER_LONG > 32 +#define TW_COMMAND_SIZE 5 +#define TW_DMA_MASK DMA_64BIT_MASK +#else +#define TW_COMMAND_SIZE 4 +#define TW_DMA_MASK DMA_32BIT_MASK +#endif +#ifndef PCI_DEVICE_ID_3WARE_9000 +#define PCI_DEVICE_ID_3WARE_9000 0x1002 +#endif + +/* Bitmask macros to eliminate bitfields */ + +/* opcode: 5, reserved: 3 */ +#define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f)) +#define TW_OP_OUT(x) (x & 0x1f) + +/* opcode: 5, sgloffset: 3 */ +#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f)) +#define TW_SGL_OUT(x) ((x >> 5) & 0x7) + +/* severity: 3, reserved: 5 */ +#define TW_SEV_OUT(x) (x & 0x7) + +/* reserved_1: 4, response_id: 8, reserved_2: 20 */ +#define TW_RESID_OUT(x) ((x >> 4) & 0xff) + +/* Macros */ +#define TW_CONTROL_REG_ADDR(x) (x->base_addr) +#define TW_STATUS_REG_ADDR(x) ((unsigned char *)x->base_addr + 0x4) +#if BITS_PER_LONG > 32 +#define TW_COMMAND_QUEUE_REG_ADDR(x) ((unsigned char *)x->base_addr + 0x20) +#else +#define TW_COMMAND_QUEUE_REG_ADDR(x) ((unsigned char *)x->base_addr + 0x8) +#endif +#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char *)x->base_addr + 0xC) +#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) +#define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x))) +#define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x))) +#define TW_DISABLE_INTERRUPTS(x) (writel(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x))) +#define TW_ENABLE_AND_CLEAR_INTERRUPTS(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x))) +#define TW_MASK_COMMAND_INTERRUPT(x) (writel(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x))) +#define TW_UNMASK_COMMAND_INTERRUPT(x) (writel(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x))) +#define TW_SOFT_RESET(x) (writel(TW_CONTROL_ISSUE_SOFT_RESET | \ + TW_CONTROL_CLEAR_HOST_INTERRUPT | \ + TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \ + TW_CONTROL_MASK_COMMAND_INTERRUPT | \ + TW_CONTROL_MASK_RESPONSE_INTERRUPT | \ + TW_CONTROL_CLEAR_ERROR_STATUS | \ + TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x))) +#define TW_PRINTK(h,a,b,c) { \ +if (h) \ +printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \ +else \ +printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \ +} + +#pragma pack(1) + +/* Scatter Gather List Entry */ +typedef struct TAG_TW_SG_Entry { + unsigned long address; + u32 length; +} TW_SG_Entry; + +/* Command Packet */ +typedef struct TW_Command { + unsigned char opcode__sgloffset; + unsigned char size; + unsigned char request_id; + unsigned char unit__hostid; + /* Second DWORD */ + unsigned char status; + unsigned char flags; + union { + unsigned short block_count; + unsigned short parameter_count; + } byte6_offset; + union { + struct { + u32 lba; + TW_SG_Entry sgl[TW_ESCALADE_MAX_SGL_LENGTH]; +#if BITS_PER_LONG > 32 + u32 padding[2]; /* pad to 512 bytes */ +#else + u32 padding; +#endif + } io; + struct { + TW_SG_Entry sgl[TW_ESCALADE_MAX_SGL_LENGTH]; +#if BITS_PER_LONG > 32 + u32 padding[3]; +#else + u32 padding[2]; +#endif + } param; + } byte8_offset; +} TW_Command; + +/* Scatter gather element for 9000+ controllers */ +typedef struct TAG_TW_SG_Apache { + unsigned long address; + u32 length; +} TW_SG_Apache; + +/* Command Packet for 9000+ controllers */ +typedef struct TAG_TW_Command_Apache { + unsigned char opcode__reserved; + unsigned char unit; + unsigned short request_id; + unsigned char status; + unsigned char sgl_offset; + unsigned short sgl_entries; + unsigned char cdb[16]; + TW_SG_Apache sg_list[TW_APACHE_MAX_SGL_LENGTH]; +#if BITS_PER_LONG > 32 + unsigned char padding[8]; +#endif +} TW_Command_Apache; + +/* New command packet header */ +typedef struct TAG_TW_Command_Apache_Header { + unsigned char sense_data[TW_SENSE_DATA_LENGTH]; + struct { + char reserved[4]; + unsigned short error; + unsigned char padding; + unsigned char severity__reserved; + } status_block; + unsigned char err_specific_desc[98]; + struct { + unsigned char size_header; + unsigned short reserved; + unsigned char size_sense; + } header_desc; +} TW_Command_Apache_Header; + +/* This struct is a union of the 2 command packets */ +typedef struct TAG_TW_Command_Full { + TW_Command_Apache_Header header; + union { + TW_Command oldcommand; + TW_Command_Apache newcommand; + } command; +} TW_Command_Full; + +/* Initconnection structure */ +typedef struct TAG_TW_Initconnect { + unsigned char opcode__reserved; + unsigned char size; + unsigned char request_id; + unsigned char res2; + unsigned char status; + unsigned char flags; + unsigned short message_credits; + u32 features; + unsigned short fw_srl; + unsigned short fw_arch_id; + unsigned short fw_branch; + unsigned short fw_build; + u32 result; +} TW_Initconnect; + +/* Event info structure */ +typedef struct TAG_TW_Event +{ + unsigned int sequence_id; + unsigned int time_stamp_sec; + unsigned short aen_code; + unsigned char severity; + unsigned char retrieved; + unsigned char repeat_count; + unsigned char parameter_len; + unsigned char parameter_data[98]; +} TW_Event; + +typedef struct TAG_TW_Ioctl_Driver_Command { + unsigned int control_code; + unsigned int status; + unsigned int unique_id; + unsigned int sequence_id; + unsigned int os_specific; + unsigned int buffer_length; +} TW_Ioctl_Driver_Command; + +typedef struct TAG_TW_Ioctl_Apache { + TW_Ioctl_Driver_Command driver_command; + char padding[488]; + TW_Command_Full firmware_command; + char data_buffer[1]; +} TW_Ioctl_Buf_Apache; + +/* Lock structure for ioctl get/release lock */ +typedef struct TAG_TW_Lock { + unsigned long timeout_msec; + unsigned long time_remaining_msec; + unsigned long force_flag; +} TW_Lock; + +/* GetParam descriptor */ +typedef struct { + unsigned short table_id; + unsigned short parameter_id; + unsigned short parameter_size_bytes; + unsigned short actual_parameter_size_bytes; + unsigned char data[1]; +} TW_Param_Apache, *PTW_Param_Apache; + +/* Response queue */ +typedef union TAG_TW_Response_Queue { + u32 response_id; + u32 value; +} TW_Response_Queue; + +typedef struct TAG_TW_Info { + char *buffer; + int length; + int offset; + int position; +} TW_Info; + +/* Compatibility information structure */ +typedef struct TAG_TW_Compatibility_Info +{ + char driver_version[32]; + unsigned short working_srl; + unsigned short working_branch; + unsigned short working_build; +} TW_Compatibility_Info; + +typedef struct TAG_TW_Device_Extension { + u32 *base_addr; + unsigned long *generic_buffer_virt[TW_Q_LENGTH]; + unsigned long generic_buffer_phys[TW_Q_LENGTH]; + TW_Command_Full *command_packet_virt[TW_Q_LENGTH]; + unsigned long command_packet_phys[TW_Q_LENGTH]; + struct pci_dev *tw_pci_dev; + struct scsi_cmnd *srb[TW_Q_LENGTH]; + unsigned char free_queue[TW_Q_LENGTH]; + unsigned char free_head; + unsigned char free_tail; + unsigned char pending_queue[TW_Q_LENGTH]; + unsigned char pending_head; + unsigned char pending_tail; + int state[TW_Q_LENGTH]; + unsigned int posted_request_count; + unsigned int max_posted_request_count; + unsigned int pending_request_count; + unsigned int max_pending_request_count; + unsigned int max_sgl_entries; + unsigned int sgl_entries; + unsigned int num_aborts; + unsigned int num_resets; + unsigned int sector_count; + unsigned int max_sector_count; + unsigned int aen_count; + struct Scsi_Host *host; + long flags; + int reset_print; + TW_Event *event_queue[TW_Q_LENGTH]; + unsigned char error_index; + unsigned char event_queue_wrapped; + unsigned int error_sequence_id; + int ioctl_sem_lock; + u32 ioctl_msec; + int chrdev_request_id; + wait_queue_head_t ioctl_wqueue; + struct semaphore ioctl_sem; + char aen_clobber; + unsigned short working_srl; + unsigned short working_branch; + unsigned short working_build; +} TW_Device_Extension; + +#pragma pack() + +#endif /* _3W_9XXX_H */ + diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c --- a/drivers/scsi/3w-xxxx.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/3w-xxxx.c 2004-06-26 17:09:20 -07:00 @@ -220,7 +220,7 @@ #define __3W_C /* let 3w-xxxx.h know it is use */ #include "scsi.h" -#include "hosts.h" +#include #include "3w-xxxx.h" diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c --- a/drivers/scsi/53c700.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/53c700.c 2004-06-26 17:09:16 -07:00 @@ -125,18 +125,21 @@ #include #include #include +#include +#include +#include #include #include #include #include #include -#include -#include -#include - -#include "scsi.h" -#include "hosts.h" +#include +#include +#include +#include +#include +#include #include #include @@ -164,15 +167,15 @@ #include "53c700_d.h" -STATIC int NCR_700_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -STATIC int NCR_700_abort(Scsi_Cmnd * SCpnt); -STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt); -STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt); -STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt); +STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); +STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt); +STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt); +STATIC int NCR_700_dev_reset(struct scsi_cmnd * SCpnt); +STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); STATIC void NCR_700_chip_setup(struct Scsi_Host *host); STATIC void NCR_700_chip_reset(struct Scsi_Host *host); -STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt); -STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt); +STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); +STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); STATIC struct device_attribute *NCR_700_dev_attrs[]; @@ -279,7 +282,7 @@ } static inline __u8 -NCR_700_get_SXFER(Scsi_Device *SDp) +NCR_700_get_SXFER(struct scsi_device *SDp) { struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; @@ -289,7 +292,7 @@ } struct Scsi_Host * -NCR_700_detect(Scsi_Host_Template *tpnt, +NCR_700_detect(struct scsi_host_template *tpnt, struct NCR_700_Host_Parameters *hostdata) { dma_addr_t pScript, pSlots; @@ -561,7 +564,7 @@ the ITL and (if tagged) the ITLQ lists in _queuecommand */ STATIC void save_for_reselection(struct NCR_700_Host_Parameters *hostdata, - Scsi_Cmnd *SCp, __u32 dsp) + struct scsi_cmnd *SCp, __u32 dsp) { /* Its just possible that this gets executed twice */ if(SCp != NULL) { @@ -575,27 +578,25 @@ } STATIC inline void -NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp, +NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp, struct NCR_700_command_slot *slot) { - if(SCp->sc_data_direction != SCSI_DATA_NONE && - SCp->sc_data_direction != SCSI_DATA_UNKNOWN) { - enum dma_data_direction direction = SCp->sc_data_direction; + if(SCp->sc_data_direction != DMA_NONE && + SCp->sc_data_direction != DMA_BIDIRECTIONAL) { if(SCp->use_sg) { dma_unmap_sg(hostdata->dev, SCp->buffer, - SCp->use_sg, direction); + SCp->use_sg, SCp->sc_data_direction); } else { - dma_unmap_single(hostdata->dev, - slot->dma_handle, + dma_unmap_single(hostdata->dev, slot->dma_handle, SCp->request_bufflen, - direction); + SCp->sc_data_direction); } } } STATIC inline void NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, - Scsi_Cmnd *SCp, int result) + struct scsi_cmnd *SCp, int result) { hostdata->state = NCR_700_HOST_FREE; hostdata->cmd = NULL; @@ -611,7 +612,7 @@ #ifdef NCR_700_DEBUG printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", SCp, SCp->cmnd[7], result); - print_sense("53c700", SCp); + scsi_print_sense("53c700", SCp); #endif /* restore the old result if the request sense was @@ -780,7 +781,7 @@ STATIC __u32 process_extended_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata, - Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps) + struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps) { __u32 resume_offset = dsp, temp = dsp + 8; __u8 pun = 0xff, lun = 0xff; @@ -849,7 +850,7 @@ printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ", host->host_no, pun, lun, NCR_700_phase[(dsps & 0xf00) >> 8]); - print_msg(hostdata->msgin); + scsi_print_msg(hostdata->msgin); printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; @@ -865,7 +866,7 @@ STATIC __u32 process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata, - Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps) + struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps) { /* work out where to return to */ __u32 temp = dsp + 8, resume_offset = dsp; @@ -879,7 +880,7 @@ #ifdef NCR_700_DEBUG printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun, NCR_700_phase[(dsps & 0xf00) >> 8]); - print_msg(hostdata->msgin); + scsi_print_msg(hostdata->msgin); printk("\n"); #endif @@ -927,7 +928,7 @@ host->host_no, pun, lun, NCR_700_phase[(dsps & 0xf00) >> 8]); - print_msg(hostdata->msgin); + scsi_print_msg(hostdata->msgin); printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; @@ -946,7 +947,7 @@ } STATIC __u32 -process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp, +process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata) { @@ -975,7 +976,7 @@ NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); } else { #ifdef NCR_DEBUG - print_command(SCp->cmnd); + scsi_print_command(SCp); printk(" cmd %p has status %d, requesting sense\n", SCp, hostdata->status[0]); #endif @@ -1004,7 +1005,7 @@ SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; SCp->cmnd[7] = hostdata->status[0]; SCp->use_sg = 0; - SCp->sc_data_direction = SCSI_DATA_READ; + SCp->sc_data_direction = DMA_FROM_DEVICE; dma_sync_single_for_device(hostdata->dev, slot->pCmd, SCp->cmd_len, DMA_TO_DEVICE); SCp->request_bufflen = sizeof(SCp->sense_buffer); @@ -1053,7 +1054,7 @@ NCR_700_phase[i], sbcl_to_string(NCR_700_readb(host, SBCL_REG))); printk(KERN_ERR " len = %d, cmd =", SCp->cmd_len); - print_command(SCp->cmnd); + scsi_print_command(SCp); NCR_700_internal_bus_reset(host); } else if((dsps & 0xfffff000) == A_FATAL) { @@ -1080,7 +1081,7 @@ __u8 lun; struct NCR_700_command_slot *slot; __u8 reselection_id = hostdata->reselection_id; - Scsi_Device *SDp; + struct scsi_device *SDp; lun = hostdata->msgin[0] & 0x1f; @@ -1095,7 +1096,7 @@ BUG(); } if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) { - Scsi_Cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]); + struct scsi_cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]); if(unlikely(SCp == NULL)) { printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n", host->host_no, reselection_id, lun, hostdata->msgin[2]); @@ -1107,7 +1108,7 @@ host->host_no, SDp->id, SDp->lun, hostdata->msgin[2], slot, slot->tag)); } else { - Scsi_Cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG); + struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG); if(unlikely(SCp == NULL)) { printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n", host->host_no, reselection_id, lun); @@ -1234,7 +1235,7 @@ host->host_no, pun, lun, NCR_700_condition[i], NCR_700_phase[j], dsp - hostdata->pScript); if(SCp != NULL) { - print_command(SCp->cmnd); + scsi_print_command(SCp); if(SCp->use_sg) { for(i = 0; i < SCp->use_sg + 1; i++) { @@ -1270,7 +1271,7 @@ __u32 resume_offset = 0; struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; - Scsi_Cmnd *SCp = hostdata->cmd; + struct scsi_cmnd *SCp = hostdata->cmd; __u8 sbcl; for(count = 0; count < 5; count++) { @@ -1373,7 +1374,7 @@ /* The queue lock with interrupts disabled must be held on entry to * this function */ STATIC int -NCR_700_start_command(Scsi_Cmnd *SCp) +NCR_700_start_command(struct scsi_cmnd *SCp) { struct NCR_700_command_slot *slot = (struct NCR_700_command_slot *)SCp->host_scribble; @@ -1481,7 +1482,7 @@ __u32 dsps; __u8 sstat0 = 0, dstat = 0; __u32 dsp; - Scsi_Cmnd *SCp = hostdata->cmd; + struct scsi_cmnd *SCp = hostdata->cmd; enum NCR_700_Host_State state; handled = 1; @@ -1514,7 +1515,7 @@ } if(sstat0 & SCSI_RESET_DETECTED) { - Scsi_Device *SDp; + struct scsi_device *SDp; int i; hostdata->state = NCR_700_HOST_BUSY; @@ -1530,7 +1531,7 @@ /* clear all the slots and their pending commands */ for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { - Scsi_Cmnd *SCp; + struct scsi_cmnd *SCp; struct NCR_700_command_slot *slot = &hostdata->slots[i]; @@ -1590,7 +1591,7 @@ printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n", host->host_no, pun, lun, SGcount, data_transfer); - print_command(SCp->cmnd); + scsi_print_command(SCp); if(residual) { printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n", host->host_no, pun, lun, @@ -1731,7 +1732,7 @@ } STATIC int -NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *)) +NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) { struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0]; @@ -1781,7 +1782,7 @@ #ifdef NCR_700_DEBUG printk("53c700: scsi%d, command ", SCp->device->host->host_no); - print_command(SCp->cmnd); + scsi_print_command(SCp); #endif if(SCp->device->tagged_supported && !SCp->device->simple_tags && (hostdata->tag_negotiated &(1<device->id)) == 0 @@ -1827,13 +1828,13 @@ /* sanity check: some of the commands generated by the mid-layer * have an eccentric idea of their sc_data_direction */ if(!SCp->use_sg && !SCp->request_bufflen - && SCp->sc_data_direction != SCSI_DATA_NONE) { + && SCp->sc_data_direction != DMA_NONE) { #ifdef NCR_700_DEBUG printk("53c700: Command"); - print_command(SCp->cmnd); + scsi_print_command(SCp); printk("Has wrong data direction %d\n", SCp->sc_data_direction); #endif - SCp->sc_data_direction = SCSI_DATA_NONE; + SCp->sc_data_direction = DMA_NONE; } switch (SCp->cmnd[0]) { @@ -1844,20 +1845,20 @@ default: /* OK, get it from the command */ switch(SCp->sc_data_direction) { - case SCSI_DATA_UNKNOWN: + case DMA_BIDIRECTIONAL: default: printk(KERN_ERR "53c700: Unknown command for data direction "); - print_command(SCp->cmnd); + scsi_print_command(SCp); move_ins = 0; break; - case SCSI_DATA_NONE: + case DMA_NONE: move_ins = 0; break; - case SCSI_DATA_READ: + case DMA_FROM_DEVICE: move_ins = SCRIPT_MOVE_DATA_IN; break; - case SCSI_DATA_WRITE: + case DMA_TO_DEVICE: move_ins = SCRIPT_MOVE_DATA_OUT; break; } @@ -1914,13 +1915,13 @@ } STATIC int -NCR_700_abort(Scsi_Cmnd * SCp) +NCR_700_abort(struct scsi_cmnd * SCp) { struct NCR_700_command_slot *slot; printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t", SCp->device->host->host_no, SCp->device->id, SCp->device->lun); - print_command(SCp->cmnd); + scsi_print_command(SCp); slot = (struct NCR_700_command_slot *)SCp->host_scribble; @@ -1946,7 +1947,7 @@ } STATIC int -NCR_700_bus_reset(Scsi_Cmnd * SCp) +NCR_700_bus_reset(struct scsi_cmnd * SCp) { DECLARE_COMPLETION(complete); struct NCR_700_Host_Parameters *hostdata = @@ -1954,7 +1955,7 @@ printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t", SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp); - print_command(SCp->cmnd); + scsi_print_command(SCp); /* In theory, eh_complete should always be null because the * eh is single threaded, but just in case we're handling a * reset via sg or something */ @@ -1976,21 +1977,21 @@ } STATIC int -NCR_700_dev_reset(Scsi_Cmnd * SCp) +NCR_700_dev_reset(struct scsi_cmnd * SCp) { printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t", SCp->device->host->host_no, SCp->device->id, SCp->device->lun); - print_command(SCp->cmnd); + scsi_print_command(SCp); return FAILED; } STATIC int -NCR_700_host_reset(Scsi_Cmnd * SCp) +NCR_700_host_reset(struct scsi_cmnd * SCp) { printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t", SCp->device->host->host_no, SCp->device->id, SCp->device->lun); - print_command(SCp->cmnd); + scsi_print_command(SCp); NCR_700_internal_bus_reset(SCp->device->host); NCR_700_chip_reset(SCp->device->host); @@ -2043,7 +2044,7 @@ STATIC int -NCR_700_slave_configure(Scsi_Device *SDp) +NCR_700_slave_configure(struct scsi_device *SDp) { struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; @@ -2066,7 +2067,7 @@ } STATIC void -NCR_700_slave_destroy(Scsi_Device *SDp) +NCR_700_slave_destroy(struct scsi_device *SDp) { /* to do here: deallocate memory */ } diff -Nru a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h --- a/drivers/scsi/53c700.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/53c700.h 2004-06-26 17:09:15 -07:00 @@ -9,9 +9,11 @@ #define _53C700_H #include - #include +#include + + #if defined(CONFIG_53C700_MEM_MAPPED) && defined(CONFIG_53C700_IO_MAPPED) #define CONFIG_53C700_BOTH_MAPPED #endif @@ -57,7 +59,8 @@ struct NCR_700_Host_Parameters; /* These are the externally used routines */ -struct Scsi_Host *NCR_700_detect(Scsi_Host_Template *, struct NCR_700_Host_Parameters *); +struct Scsi_Host *NCR_700_detect(struct scsi_host_template *, + struct NCR_700_Host_Parameters *); int NCR_700_release(struct Scsi_Host *host); irqreturn_t NCR_700_intr(int, void *, struct pt_regs *); @@ -102,7 +105,7 @@ #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) static inline void -NCR_700_set_depth(Scsi_Device *SDp, __u8 depth) +NCR_700_set_depth(struct scsi_device *SDp, __u8 depth) { long l = (long)SDp->hostdata; @@ -111,27 +114,27 @@ SDp->hostdata = (void *)l; } static inline __u8 -NCR_700_get_depth(Scsi_Device *SDp) +NCR_700_get_depth(struct scsi_device *SDp) { return ((((unsigned long)SDp->hostdata) & 0xff00)>>8); } static inline int -NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag) +NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) { return (((unsigned long)SDp->hostdata) & flag) == flag; } static inline int -NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag) +NCR_700_is_flag_clear(struct scsi_device *SDp, __u32 flag) { return (((unsigned long)SDp->hostdata) & flag) == 0; } static inline void -NCR_700_set_flag(Scsi_Device *SDp, __u32 flag) +NCR_700_set_flag(struct scsi_device *SDp, __u32 flag) { SDp->hostdata = (void *)((long)SDp->hostdata | (flag & 0xffff0000)); } static inline void -NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag) +NCR_700_clear_flag(struct scsi_device *SDp, __u32 flag) { SDp->hostdata = (void *)((long)SDp->hostdata & ~(flag & 0xffff0000)); } @@ -147,7 +150,7 @@ __u8 state; int tag; __u32 resume_offset; - Scsi_Cmnd *cmnd; + struct scsi_cmnd *cmnd; /* The pci_mapped address of the actual command in cmnd */ dma_addr_t pCmd; __u32 temp; @@ -185,7 +188,7 @@ __u32 pScript; /* physical mem addr of script */ enum NCR_700_Host_State state; /* protected by state lock */ - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; /* Note: pScript contains the single consistent block of * memory. All the msgin, msgout and status are allocated in * this memory too (at separate cache lines). TOTAL_MEM_SIZE diff -Nru a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c --- a/drivers/scsi/53c7xx.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/53c7xx.c 2004-06-26 17:09:21 -07:00 @@ -280,7 +280,7 @@ #endif #include "scsi.h" -#include "hosts.h" +#include #include "53c7xx.h" #include #include diff -Nru a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c --- a/drivers/scsi/BusLogic.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/BusLogic.c 2004-06-26 17:09:20 -07:00 @@ -48,7 +48,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "BusLogic.h" #include "FlashPoint.c" diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/Kconfig 2004-06-26 17:09:20 -07:00 @@ -227,7 +227,7 @@ depends on DECSTATION && SCSI config BLK_DEV_3W_XXXX_RAID - tristate "3ware Hardware ATA-RAID support" + tristate "3ware 5/6/7/8xxx ATA-RAID support" depends on PCI && SCSI help 3ware is the only hardware ATA-Raid product in Linux to date. @@ -239,6 +239,17 @@ Please read the comments at the top of . +config SCSI_3W_9XXX + tristate "3ware 9xxx SATA-RAID support" + depends on PCI && SCSI + help + This driver supports the 9000 series 3ware SATA-RAID cards. + + + + Please read the comments at the top of + . + config SCSI_7000FASST tristate "7000FASST SCSI support" depends on ISA && SCSI @@ -422,6 +433,14 @@ If unsure, say N. +config SCSI_SATA_NV + tristate "NVIDIA SATA support" + depends on SCSI_SATA && PCI && EXPERIMENTAL + help + This option enables support for NVIDIA Serial ATA. + + If unsure, say N. + config SCSI_SATA_PROMISE tristate "Promise SATA TX2/TX4 support" depends on SCSI_SATA && PCI @@ -478,9 +497,7 @@ Adapters. Consult the SCSI-HOWTO, available from , and the files and - for more information. If this - driver does not work correctly without modification, please contact - the author, Leonard N. Zubkoff, by email to lnz@dandelion.com. + for more information. To compile this driver as a module, choose M here: the module will be called BusLogic. @@ -1715,18 +1732,6 @@ To compile this driver as a module, choose M here: the module will be called esp. - -config SCSI_PC980155 - tristate "NEC PC-9801-55 SCSI support" - depends on X86_PC9800 && SCSI - help - If you have the NEC PC-9801-55 SCSI interface card or compatibles - for NEC PC-9801/PC-9821, say Y. - -config WD33C93_PIO - bool - depends on SCSI_PC980155 - default y # bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/Makefile 2004-06-26 17:09:20 -07:00 @@ -34,7 +34,6 @@ obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o obj-$(CONFIG_GVP11_SCSI) += gvp11.o wd33c93.o -obj-$(CONFIG_SCSI_PC980155) += pc980155.o wd33c93.o obj-$(CONFIG_MVME147_SCSI) += mvme147.o wd33c93.o obj-$(CONFIG_SGIWD93_SCSI) += sgiwd93.o wd33c93.o obj-$(CONFIG_CYBERSTORM_SCSI) += NCR53C9x.o cyberstorm.o @@ -109,6 +108,7 @@ obj-$(CONFIG_SCSI_PLUTO) += pluto.o obj-$(CONFIG_SCSI_DECNCR) += NCR53C9x.o dec_esp.o obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o +obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o obj-$(CONFIG_SCSI_PPA) += ppa.o obj-$(CONFIG_SCSI_IMM) += imm.o obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o @@ -127,6 +127,7 @@ obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o obj-$(CONFIG_SCSI_SATA_SIS) += libata.o sata_sis.o obj-$(CONFIG_SCSI_SATA_SX4) += libata.o sata_sx4.o +obj-$(CONFIG_SCSI_SATA_NV) += libata.o sata_nv.o obj-$(CONFIG_ARM) += arm/ @@ -142,7 +143,6 @@ scsi_devinfo.o scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o -scsi_mod-$(CONFIG_X86_PC9800) += scsi_pc98.o sd_mod-objs := sd.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o diff -Nru a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c --- a/drivers/scsi/NCR53C9x.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/NCR53C9x.c 2004-06-26 17:09:16 -07:00 @@ -36,7 +36,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include @@ -3645,5 +3645,16 @@ esps_running = esps_in_use; } #endif + +EXPORT_SYMBOL(esp_abort); +EXPORT_SYMBOL(esp_allocate); +EXPORT_SYMBOL(esp_deallocate); +EXPORT_SYMBOL(esp_initialize); +EXPORT_SYMBOL(esp_intr); +EXPORT_SYMBOL(esp_queue); +EXPORT_SYMBOL(esp_reset); +EXPORT_SYMBOL(esp_slave_alloc); +EXPORT_SYMBOL(esp_slave_destroy); +EXPORT_SYMBOL(esps_in_use); MODULE_LICENSE("GPL"); diff -Nru a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c --- a/drivers/scsi/NCR53c406a.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/NCR53c406a.c 2004-06-26 17:09:18 -07:00 @@ -54,7 +54,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include /* ============================================================= */ diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c --- a/drivers/scsi/NCR_D700.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/NCR_D700.c 2004-06-26 17:09:16 -07:00 @@ -98,9 +98,7 @@ #include #include #include - -#include "scsi.h" -#include "hosts.h" +#include #include "53c700.h" #include "NCR_D700.h" @@ -156,7 +154,7 @@ /* Host template. The 53c700 routine NCR_700_detect will * fill in all of the missing routines */ -static Scsi_Host_Template NCR_D700_driver_template = { +static struct scsi_host_template NCR_D700_driver_template = { .module = THIS_MODULE, .name = "NCR Dual 700 MCA", .proc_name = "NCR_D700", diff -Nru a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c --- a/drivers/scsi/NCR_Q720.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/NCR_Q720.c 2004-06-26 17:09:15 -07:00 @@ -16,7 +16,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "ncr53c8xx.h" diff -Nru a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c --- a/drivers/scsi/a2091.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/a2091.c 2004-06-26 17:09:18 -07:00 @@ -16,7 +16,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "wd33c93.h" #include "a2091.h" diff -Nru a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c --- a/drivers/scsi/a3000.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/a3000.c 2004-06-26 17:09:19 -07:00 @@ -15,7 +15,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "wd33c93.h" #include "a3000.h" diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c --- a/drivers/scsi/advansys.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/advansys.c 2004-06-26 17:09:16 -07:00 @@ -756,27 +756,6 @@ */ - -/* - * --- Linux Version - */ - -#ifndef LINUX_VERSION_CODE -#include -#endif /* LINUX_VERSION_CODE */ - -/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */ -#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S)) -#define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0)) -#define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0)) - -/* Driver supported only in version 2.2 and version >= 2.4. */ -#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \ - (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \ - LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0)) -#error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels." -#endif - /* * --- Linux Include Files */ @@ -801,13 +780,14 @@ #include #include #include +#include #include #include #include #include "scsi.h" -#include "hosts.h" +#include #include "advansys.h" #ifdef CONFIG_PCI #include @@ -874,9 +854,6 @@ typedef unsigned char uchar; -#ifndef NULL -#define NULL (0) -#endif #ifndef TRUE #define TRUE (1) #endif @@ -986,49 +963,6 @@ #define ASC_MIN_SENSE_LEN 14 #define ASC_MAX_CDB_LEN 12 #define ASC_SCSI_RESET_HOLD_TIME_US 60 -#define SCSICMD_TestUnitReady 0x00 -#define SCSICMD_Rewind 0x01 -#define SCSICMD_Rezero 0x01 -#define SCSICMD_RequestSense 0x03 -#define SCSICMD_Format 0x04 -#define SCSICMD_FormatUnit 0x04 -#define SCSICMD_Read6 0x08 -#define SCSICMD_Write6 0x0A -#define SCSICMD_Seek6 0x0B -#define SCSICMD_Inquiry 0x12 -#define SCSICMD_Verify6 0x13 -#define SCSICMD_ModeSelect6 0x15 -#define SCSICMD_ModeSense6 0x1A -#define SCSICMD_StartStopUnit 0x1B -#define SCSICMD_LoadUnloadTape 0x1B -#define SCSICMD_ReadCapacity 0x25 -#define SCSICMD_Read10 0x28 -#define SCSICMD_Write10 0x2A -#define SCSICMD_Seek10 0x2B -#define SCSICMD_Erase10 0x2C -#define SCSICMD_WriteAndVerify10 0x2E -#define SCSICMD_Verify10 0x2F -#define SCSICMD_WriteBuffer 0x3B -#define SCSICMD_ReadBuffer 0x3C -#define SCSICMD_ReadLong 0x3E -#define SCSICMD_WriteLong 0x3F -#define SCSICMD_ReadTOC 0x43 -#define SCSICMD_ReadHeader 0x44 -#define SCSICMD_ModeSelect10 0x55 -#define SCSICMD_ModeSense10 0x5A - -/* Inquiry Data Peripheral Device Types */ -#define SCSI_TYPE_DASD 0x00 -#define SCSI_TYPE_SASD 0x01 -#define SCSI_TYPE_PRN 0x02 -#define SCSI_TYPE_PROC 0x03 -#define SCSI_TYPE_WORM 0x04 -#define SCSI_TYPE_CDROM 0x05 -#define SCSI_TYPE_SCANNER 0x06 -#define SCSI_TYPE_OPTMEM 0x07 -#define SCSI_TYPE_MED_CHG 0x08 -#define SCSI_TYPE_COMM 0x09 -#define SCSI_TYPE_UNKNOWN 0x1F #define ADV_INQ_CLOCKING_ST_ONLY 0x0 #define ADV_INQ_CLOCKING_DT_ONLY 0x1 @@ -1047,36 +981,11 @@ #define ASC_SCSIDIR_T2H 0x08 #define ASC_SCSIDIR_H2T 0x10 #define ASC_SCSIDIR_NODATA 0x18 -#define SCSI_SENKEY_NO_SENSE 0x00 -#define SCSI_SENKEY_UNDEFINED 0x01 -#define SCSI_SENKEY_NOT_READY 0x02 -#define SCSI_SENKEY_MEDIUM_ERR 0x03 -#define SCSI_SENKEY_HW_ERR 0x04 -#define SCSI_SENKEY_ILLEGAL 0x05 -#define SCSI_SENKEY_ATTENTION 0x06 -#define SCSI_SENKEY_PROTECTED 0x07 -#define SCSI_SENKEY_BLANK 0x08 -#define SCSI_SENKEY_V_UNIQUE 0x09 -#define SCSI_SENKEY_CPY_ABORT 0x0A -#define SCSI_SENKEY_ABORT 0x0B -#define SCSI_SENKEY_EQUAL 0x0C -#define SCSI_SENKEY_VOL_OVERFLOW 0x0D -#define SCSI_SENKEY_MISCOMP 0x0E -#define SCSI_SENKEY_RESERVED 0x0F #define SCSI_ASC_NOMEDIA 0x3A #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4)) #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F)) #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13)) #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8)) -#define SS_GOOD 0x00 -#define SS_CHK_CONDITION 0x02 -#define SS_CONDITION_MET 0x04 -#define SS_TARGET_BUSY 0x08 -#define SS_INTERMID 0x10 -#define SS_INTERMID_COND_MET 0x14 -#define SS_RSERV_CONFLICT 0x18 -#define SS_CMD_TERMINATED 0x22 -#define SS_QUEUE_FULL 0x28 #define MS_CMD_DONE 0x00 #define MS_EXTEND 0x01 #define MS_SDTR_LEN 0x03 @@ -1085,26 +994,6 @@ #define MS_WDTR_CODE 0x03 #define MS_MDP_LEN 0x05 #define MS_MDP_CODE 0x00 -#define M1_SAVE_DATA_PTR 0x02 -#define M1_RESTORE_PTRS 0x03 -#define M1_DISCONNECT 0x04 -#define M1_INIT_DETECTED_ERR 0x05 -#define M1_ABORT 0x06 -#define M1_MSG_REJECT 0x07 -#define M1_NO_OP 0x08 -#define M1_MSG_PARITY_ERR 0x09 -#define M1_LINK_CMD_DONE 0x0A -#define M1_LINK_CMD_DONE_WFLAG 0x0B -#define M1_BUS_DVC_RESET 0x0C -#define M1_ABORT_TAG 0x0D -#define M1_CLR_QUEUE 0x0E -#define M1_INIT_RECOVERY 0x0F -#define M1_RELEASE_RECOVERY 0x10 -#define M1_KILL_IO_PROC 0x11 -#define M2_QTAG_MSG_SIMPLE 0x20 -#define M2_QTAG_MSG_HEAD 0x21 -#define M2_QTAG_MSG_ORDERED 0x22 -#define M2_IGNORE_WIDE_RESIDUE 0x23 /* * Inquiry data structure and bitfield macros @@ -1576,7 +1465,7 @@ uchar sdtr_period_offset[ASC_MAX_TID + 1]; ushort pci_slot_info; uchar adapter_info[6]; - struct pci_dev *pci_dev; + struct device *dev; } ASC_DVC_CFG; #define ASC_DEF_DVC_CNTL 0xFFFF @@ -3082,7 +2971,7 @@ ushort serial1; /* EEPROM serial number word 1 */ ushort serial2; /* EEPROM serial number word 2 */ ushort serial3; /* EEPROM serial number word 3 */ - struct pci_dev *pci_dev; /* pointer to the pci dev structure for this board */ + struct device *dev; /* pointer to the pci dev structure for this board */ } ADV_DVC_CFG; struct adv_dvc_var; @@ -3581,19 +3470,6 @@ #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */ -/* - * If the Linux kernel version supports freeing initialization code - * and data after loading, define macros for this purpose. These macros - * are not used when the driver is built as a module, cf. linux/init.h. - */ -#if ASC_LINUX_KERNEL24 -#define ASC_INITFUNC(type, func) type __init func -#elif ASC_LINUX_KERNEL22 -#define ASC_INITFUNC(type, func) __initfunc(type func) -#endif -#define ASC_INITDATA __initdata -#define ASC_INIT __init - #define ASC_INFO_SIZE 128 /* advansys_info() line size */ #ifdef CONFIG_PROC_FS @@ -3610,8 +3486,6 @@ } \ cp += len; \ } - -#define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif /* CONFIG_PROC_FS */ /* Asc Library return codes */ @@ -3685,53 +3559,6 @@ /* Return non-zero, if the queue is empty. */ #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0) -/* PCI configuration declarations */ - -#define PCI_BASE_CLASS_PREDEFINED 0x00 -#define PCI_BASE_CLASS_MASS_STORAGE 0x01 -#define PCI_BASE_CLASS_NETWORK 0x02 -#define PCI_BASE_CLASS_DISPLAY 0x03 -#define PCI_BASE_CLASS_MULTIMEDIA 0x04 -#define PCI_BASE_CLASS_MEMORY_CONTROLLER 0x05 -#define PCI_BASE_CLASS_BRIDGE_DEVICE 0x06 - -/* MASS STORAGE */ -#define PCI_SUB_CLASS_SCSI_CONTROLLER 0x00 -#define PCI_SUB_CLASS_IDE_CONTROLLER 0x01 -#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER 0x02 -#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER 0x03 -#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER 0x80 - -/* NETWORK CONTROLLER */ -#define PCI_SUB_CLASS_ETHERNET_CONTROLLER 0x00 -#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER 0x01 -#define PCI_SUB_CLASS_FDDI_CONTROLLER 0x02 -#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER 0x80 - -/* DISPLAY CONTROLLER */ -#define PCI_SUB_CLASS_VGA_CONTROLLER 0x00 -#define PCI_SUB_CLASS_XGA_CONTROLLER 0x01 -#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER 0x80 - -/* MULTIMEDIA CONTROLLER */ -#define PCI_SUB_CLASS_VIDEO_DEVICE 0x00 -#define PCI_SUB_CLASS_AUDIO_DEVICE 0x01 -#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE 0x80 - -/* MEMORY CONTROLLER */ -#define PCI_SUB_CLASS_RAM_CONTROLLER 0x00 -#define PCI_SUB_CLASS_FLASH_CONTROLLER 0x01 -#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER 0x80 - -/* BRIDGE CONTROLLER */ -#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER 0x00 -#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER 0x01 -#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER 0x02 -#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER 0x03 -#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER 0x04 -#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER 0x05 -#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER 0x80 - #define PCI_MAX_SLOT 0x1F #define PCI_MAX_BUS 0xFF #define PCI_IOADDRESS_MASK 0xFFFE @@ -3744,25 +3571,6 @@ #define ASC_PCI_DEVICE_ID_2500 0x2500 /* ASC-38C0800 */ #define ASC_PCI_DEVICE_ID_2700 0x2700 /* ASC-38C1600 */ -/* PCI IO Port Addresses to generate special cycle */ - -#define PCI_CONFIG_ADDRESS_MECH1 0x0CF8 -#define PCI_CONFIG_DATA_MECH1 0x0CFC - -#define PCI_CONFIG_FORWARD_REGISTER 0x0CFA /* 0=type 0; 1=type 1; */ - -#define PCI_CONFIG_BUS_NUMBER_MASK 0x00FF0000 -#define PCI_CONFIG_DEVICE_FUNCTION_MASK 0x0000FF00 -#define PCI_CONFIG_REGISTER_NUMBER_MASK 0x000000F8 - -#define PCI_DEVICE_FOUND 0x0000 -#define PCI_DEVICE_NOT_FOUND 0xffff - -#define SUBCLASS_OFFSET 0x0A -#define CLASSCODE_OFFSET 0x0B -#define VENDORID_OFFSET 0x00 -#define DEVICEID_OFFSET 0x02 - #ifndef ADVANSYS_STATS #define ASC_STATS(shp, counter) #define ASC_STATS_ADD(shp, counter, count) @@ -4145,19 +3953,6 @@ /* Note: All driver global data should be initialized. */ -#if ASC_LINUX_KERNEL22 -#ifdef CONFIG_PROC_FS -struct proc_dir_entry proc_scsi_advansys = -{ - PROC_SCSI_ADVANSYS, /* unsigned short low_ino */ - 8, /* unsigned short namelen */ - "advansys", /* const char *name */ - S_IFDIR | S_IRUGO | S_IXUGO, /* mode_t mode */ - 2 /* nlink_t nlink */ -}; -#endif /* CONFIG_PROC_FS */ -#endif /* ASC_LINUX_KERNEL22 */ - /* Number of boards detected in system. */ STATIC int asc_board_count = 0; STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 }; @@ -4172,7 +3967,7 @@ STATIC ASC_SG_HEAD asc_sg_head = { 0 }; /* List of supported bus types. */ -STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = { +STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = { ASC_IS_ISA, ASC_IS_VL, ASC_IS_EISA, @@ -4210,11 +4005,11 @@ STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *); STATIC int advansys_slave_configure(Scsi_Device *); -STATIC void asc_scsi_done_list(Scsi_Cmnd *, int from_isr); +STATIC void asc_scsi_done_list(Scsi_Cmnd *); STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *); STATIC int asc_build_req(asc_board_t *, Scsi_Cmnd *); STATIC int adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **); -STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *); +STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *, int); STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *); STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); STATIC void adv_async_callback(ADV_DVC_VAR *, uchar); @@ -4505,10 +4300,8 @@ * it must not call SCSI mid-level functions including scsi_malloc() * and scsi_free(). */ -ASC_INITFUNC( -int, +int __init advansys_detect(Scsi_Host_Template *tpnt) -) { static int detect_called = ASC_FALSE; int iop; @@ -4526,6 +4319,7 @@ struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED]; int pci_card_cnt_max = 0; int pci_card_cnt = 0; + struct device *dev = NULL; struct pci_dev *pci_devp = NULL; int pci_device_id_cnt = 0; unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = { @@ -4550,12 +4344,6 @@ ASC_DBG(1, "advansys_detect: begin\n"); -#if ASC_LINUX_KERNEL24 - tpnt->proc_name = "advansys"; -#elif ASC_LINUX_KERNEL22 - tpnt->proc_dir = &proc_scsi_advansys; -#endif - asc_board_count = 0; /* @@ -4681,13 +4469,9 @@ NULL) { pci_device_id_cnt++; } else { -#if ASC_LINUX_KERNEL24 if (pci_enable_device(pci_devp) == 0) { pci_devicep[pci_card_cnt_max++] = pci_devp; } -#elif ASC_LINUX_KERNEL22 - pci_devicep[pci_card_cnt_max++] = pci_devp; -#endif } } @@ -4724,17 +4508,16 @@ ASC_DBG2(2, "advansys_detect: devfn %d, bus number %d\n", pci_devp->devfn, pci_devp->bus->number); -#if ASC_LINUX_KERNEL24 iop = pci_resource_start(pci_devp, 0); -#elif ASC_LINUX_KERNEL22 - iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK; -#endif ASC_DBG2(1, "advansys_detect: vendorID %X, deviceID %X\n", pci_devp->vendor, pci_devp->device); ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n", iop, pci_devp->irq); } + if(pci_devp) + dev = &pci_devp->dev; + #endif /* CONFIG_PCI */ break; @@ -4765,7 +4548,7 @@ continue; } - scsi_set_device(shp, &pci_devp->dev); + scsi_set_device(shp, dev); /* Save a pointer to the Scsi_Host of each board found. */ asc_host[asc_board_count++] = shp; @@ -4849,11 +4632,7 @@ iolen = ADV_38C1600_IOLEN; } #ifdef CONFIG_PCI -#if ASC_LINUX_KERNEL24 pci_memory_address = pci_resource_start(pci_devp, 1); -#elif ASC_LINUX_KERNEL22 - pci_memory_address = pci_devp->base_address[1]; -#endif ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n", (ulong) pci_memory_address); if ((boardp->ioremap_addr = @@ -4904,7 +4683,8 @@ #endif /* CONFIG_PROC_FS */ if (ASC_NARROW_BOARD(boardp)) { - /* + asc_dvc_varp->cfg->dev = dev; + /* * Set the board bus type and PCI IRQ before * calling AscInitGetConfig(). */ @@ -4926,7 +4706,6 @@ #ifdef CONFIG_PCI case ASC_IS_PCI: shp->irq = asc_dvc_varp->irq_no = pci_devp->irq; - asc_dvc_varp->cfg->pci_dev = pci_devp; asc_dvc_varp->cfg->pci_slot_info = ASC_PCI_MKID(pci_devp->bus->number, PCI_SLOT(pci_devp->devfn), @@ -4944,13 +4723,13 @@ break; } } else { + adv_dvc_varp->cfg->dev = dev; /* * For Wide boards set PCI information before calling * AdvInitGetConfig(). */ #ifdef CONFIG_PCI shp->irq = adv_dvc_varp->irq_no = pci_devp->irq; - adv_dvc_varp->cfg->pci_dev = pci_devp; adv_dvc_varp->cfg->pci_slot_info = ASC_PCI_MKID(pci_devp->bus->number, PCI_SLOT(pci_devp->devfn), @@ -5321,11 +5100,7 @@ /* BIOS start address. */ if (ASC_NARROW_BOARD(boardp)) { -#if ASC_LINUX_KERNEL24 shp->base = -#elif ASC_LINUX_KERNEL22 - shp->base = (char *) -#endif ((ulong) AscGetChipBiosAddress( asc_dvc_varp->iop_base, asc_dvc_varp->bus_type)); @@ -5360,11 +5135,7 @@ * Convert x86 realmode code segment to a linear * address by shifting left 4. */ - shp->base = -#if ASC_LINUX_KERNEL22 - (char *) -#endif - ((ulong) boardp->bios_codeseg << 4); + shp->base = ((ulong) boardp->bios_codeseg << 4); } else { shp->base = 0; } @@ -5385,7 +5156,6 @@ ASC_DBG2(2, "advansys_detect: request_region port 0x%lx, len 0x%x\n", (ulong) shp->io_port, boardp->asc_n_io_port); -#if ASC_LINUX_KERNEL24 if (request_region(shp->io_port, boardp->asc_n_io_port, "advansys") == NULL) { ASC_PRINT3( @@ -5398,9 +5168,6 @@ asc_board_count--; continue; } -#elif ASC_LINUX_KERNEL22 - request_region(shp->io_port, boardp->asc_n_io_port, "advansys"); -#endif /* Register DMA Channel for Narrow boards. */ shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */ @@ -5880,7 +5647,7 @@ default: done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL); /* Interrupts could be enabled here. */ - asc_scsi_done_list(done_scp, 0); + asc_scsi_done_list(done_scp); break; } spin_unlock_irqrestore(&boardp->lock, flags); @@ -6063,7 +5830,7 @@ * Complete all the 'done_scp' requests. */ if (done_scp != NULL) { - asc_scsi_done_list(done_scp, 0); + asc_scsi_done_list(done_scp); } ASC_DBG1(1, "advansys_reset: ret %d\n", ret); @@ -6149,10 +5916,8 @@ * ints[2] - second argument * ... */ -ASC_INITFUNC( -void, +void __init advansys_setup(char *str, int *ints) -) { int i; @@ -6328,7 +6093,7 @@ * Complete all requests on the done list. */ - asc_scsi_done_list(done_scp, 1); + asc_scsi_done_list(done_scp); ASC_DBG(1, "advansys_interrupt: end\n"); return IRQ_HANDLED; @@ -6374,23 +6139,38 @@ * Interrupts can be enabled on entry. */ STATIC void -asc_scsi_done_list(Scsi_Cmnd *scp, int from_isr) +asc_scsi_done_list(Scsi_Cmnd *scp) { Scsi_Cmnd *tscp; - ulong flags = 0; ASC_DBG(2, "asc_scsi_done_list: begin\n"); while (scp != NULL) { + asc_board_t *boardp; + struct device *dev; + ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp); tscp = REQPNEXT(scp); scp->host_scribble = NULL; + + boardp = ASC_BOARDP(scp->device->host); + + if (ASC_NARROW_BOARD(boardp)) + dev = boardp->dvc_cfg.asc_dvc_cfg.dev; + else + dev = boardp->dvc_cfg.adv_dvc_cfg.dev; + + if (scp->use_sg) + dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer, + scp->use_sg, scp->sc_data_direction); + else if (scp->request_bufflen) + dma_unmap_single(dev, scp->SCp.dma_handle, + scp->request_bufflen, scp->sc_data_direction); + ASC_STATS(scp->device->host, done); ASC_ASSERT(scp->scsi_done != NULL); - if (from_isr) - spin_lock_irqsave(scp->device->host->host_lock, flags); + scp->scsi_done(scp); - if (from_isr) - spin_unlock_irqrestore(scp->device->host->host_lock, flags); + scp = tscp; } ASC_DBG(2, "asc_scsi_done_list: done\n"); @@ -6619,6 +6399,8 @@ STATIC int asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp) { + struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev; + /* * Mutually exclusive access is required to 'asc_scsi_q' and * 'asc_sg_head' until after the request is started. @@ -6665,9 +6447,9 @@ */ if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && (boardp->reqcnt[scp->device->id] % 255) == 0) { - asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED; + asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG; } else { - asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE; + asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG; } /* @@ -6679,8 +6461,10 @@ * CDB request of single contiguous buffer. */ ASC_STATS(scp->device->host, cont_cnt); - asc_scsi_q.q1.data_addr = - cpu_to_le32(virt_to_bus(scp->request_buffer)); + scp->SCp.dma_handle = scp->request_bufflen ? + dma_map_single(dev, scp->request_buffer, + scp->request_bufflen, scp->sc_data_direction) : 0; + asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); ASC_STATS_ADD(scp->device->host, cont_xfer, ASC_CEILING(scp->request_bufflen, 512)); @@ -6691,12 +6475,17 @@ * CDB scatter-gather request list. */ int sgcnt; + int use_sg; struct scatterlist *slp; - if (scp->use_sg > scp->device->host->sg_tablesize) { + slp = (struct scatterlist *)scp->request_buffer; + use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); + + if (use_sg > scp->device->host->sg_tablesize) { ASC_PRINT3( "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n", - boardp->id, scp->use_sg, scp->device->host->sg_tablesize); + boardp->id, use_sg, scp->device->host->sg_tablesize); + dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); return ASC_ERROR; @@ -6715,19 +6504,16 @@ asc_scsi_q.q1.data_cnt = 0; asc_scsi_q.q1.data_addr = 0; /* This is a byte value, otherwise it would need to be swapped. */ - asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg; + asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg; ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt); /* * Convert scatter-gather list into ASC_SG_HEAD list. */ - slp = (struct scatterlist *) scp->request_buffer; - for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) { - asc_sg_head.sg_list[sgcnt].addr = - cpu_to_le32(virt_to_bus( - (unsigned char *)page_address(slp->page) + slp->offset)); - asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length); - ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512)); + for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { + asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp)); + asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp)); + ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512)); } } @@ -6755,6 +6541,7 @@ ADV_SCSI_REQ_Q *scsiqp; int i; int ret; + struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev; /* * Allocate an adv_req_t structure from the board to execute @@ -6827,15 +6614,23 @@ * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather * buffer command. */ - scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); - scsiqp->vdata_addr = scp->request_buffer; - scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer)); if (scp->use_sg == 0) { /* * CDB request of single contiguous buffer. */ reqp->sgblkp = NULL; + scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); + if (scp->request_bufflen) { + scsiqp->vdata_addr = scp->request_buffer; + scp->SCp.dma_handle = + dma_map_single(dev, scp->request_buffer, + scp->request_bufflen, scp->sc_data_direction); + } else { + scsiqp->vdata_addr = 0; + scp->SCp.dma_handle = 0; + } + scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle); scsiqp->sg_list_ptr = NULL; scsiqp->sg_real_addr = 0; ASC_STATS(scp->device->host, cont_cnt); @@ -6845,10 +6640,21 @@ /* * CDB scatter-gather request list. */ - if (scp->use_sg > ADV_MAX_SG_LIST) { + struct scatterlist *slp; + int use_sg; + + scsiqp->data_cnt = 0; + scsiqp->vdata_addr = 0; + scsiqp->data_addr = 0; + + slp = (struct scatterlist *)scp->request_buffer; + use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); + + if (use_sg > ADV_MAX_SG_LIST) { ASC_PRINT3( "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n", - boardp->id, scp->use_sg, scp->device->host->sg_tablesize); + boardp->id, use_sg, scp->device->host->sg_tablesize); + dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); @@ -6862,7 +6668,7 @@ return ASC_ERROR; } - if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) { + if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) { /* * Free the adv_req_t structure by adding it back to the * board free list. @@ -6874,7 +6680,7 @@ } ASC_STATS(scp->device->host, sg_cnt); - ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg); + ASC_STATS_ADD(scp->device->host, sg_elem, use_sg); } ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); @@ -6898,7 +6704,7 @@ * ADV_ERROR(-1) - SG List creation failed */ STATIC int -adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp) +adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp, int use_sg) { adv_sgblk_t *sgblkp; ADV_SCSI_REQ_Q *scsiqp; @@ -6910,7 +6716,7 @@ scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q); slp = (struct scatterlist *) scp->request_buffer; - sg_elem_cnt = scp->use_sg; + sg_elem_cnt = use_sg; prev_sg_block = NULL; reqp->sgblkp = NULL; @@ -6982,11 +6788,9 @@ for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { - sg_block->sg_list[i].sg_addr = - cpu_to_le32(virt_to_bus( - (unsigned char *)page_address(slp->page) + slp->offset)); - sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length); - ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512)); + sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp)); + sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp)); + ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512)); if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */ @@ -7079,14 +6883,13 @@ * If an INQUIRY command completed successfully, then call * the AscInquiryHandling() function to set-up the device. */ - if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 && + if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 && (scp->request_bufflen - qdonep->remain_bytes) >= 8) { AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7, (ASC_SCSI_INQUIRY *) scp->request_buffer); } -#if ASC_LINUX_KERNEL24 /* * Check for an underrun condition. * @@ -7099,15 +6902,14 @@ (unsigned) qdonep->remain_bytes); scp->resid = qdonep->remain_bytes; } -#endif break; case QD_WITH_ERROR: ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n"); switch (qdonep->d3.host_stat) { case QHSTA_NO_ERROR: - if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) { - ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n"); + if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) { + ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n"); ASC_DBG_PRT_SENSE(2, scp->sense_buffer, sizeof(scp->sense_buffer)); /* @@ -7185,9 +6987,7 @@ Scsi_Cmnd *scp; struct Scsi_Host *shp; int i; -#if ASC_LINUX_KERNEL24 ADV_DCNT resid_cnt; -#endif ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", @@ -7270,7 +7070,6 @@ ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n"); scp->result = 0; -#if ASC_LINUX_KERNEL24 /* * Check for an underrun condition. * @@ -7284,15 +7083,14 @@ (ulong) resid_cnt); scp->resid = resid_cnt; } -#endif break; case QD_WITH_ERROR: ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n"); switch (scsiqp->host_status) { case QHSTA_NO_ERROR: - if (scsiqp->scsi_status == SS_CHK_CONDITION) { - ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n"); + if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) { + ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n"); ASC_DBG_PRT_SENSE(2, scp->sense_buffer, sizeof(scp->sense_buffer)); /* @@ -8858,7 +8656,7 @@ (unsigned) offset, (unsigned) advoffset, cplen); if (offset <= advoffset) { /* Read offset below current offset, copy everything. */ - cnt = ASC_MIN(cplen, leftlen); + cnt = min(cplen, leftlen); ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", (ulong) curbuf, (ulong) cp, cnt); memcpy(curbuf, cp, cnt); @@ -8866,7 +8664,7 @@ /* Read offset within current range, partial copy. */ cnt = (advoffset + cplen) - offset; cp = (cp + cplen) - cnt; - cnt = ASC_MIN(cnt, leftlen); + cnt = min(cnt, leftlen); ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", (ulong) curbuf, (ulong) cp, cnt); memcpy(curbuf, cp, cnt); @@ -8899,7 +8697,7 @@ (void) printk(s); ret = 0; } else { - ret = ASC_MIN(buflen, ret); + ret = min(buflen, ret); memcpy(buf, s, ret); } va_end(args); @@ -9002,16 +8800,14 @@ /* * Read a PCI configuration byte. */ -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init DvcReadPCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort offset) -) { #ifdef CONFIG_PCI uchar byte_data; - pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data); + pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); return byte_data; #else /* !defined(CONFIG_PCI) */ return 0; @@ -9021,16 +8817,14 @@ /* * Write a PCI configuration byte. */ -ASC_INITFUNC( -STATIC void, +STATIC void __init DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) -) { #ifdef CONFIG_PCI - pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data); + pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); #endif /* CONFIG_PCI */ } @@ -9038,13 +8832,10 @@ * Return the BIOS address of the adapter at the specified * I/O port and with the specified bus type. */ -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscGetChipBiosAddress( PortAddr iop_base, - ushort bus_type -) -) + ushort bus_type) { ushort cfg_lsw; ushort bios_addr; @@ -9119,16 +8910,14 @@ /* * Read a PCI configuration byte. */ -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init DvcAdvReadPCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort offset) -) { #ifdef CONFIG_PCI uchar byte_data; - pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data); + pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); return byte_data; #else /* CONFIG_PCI */ return 0; @@ -9138,16 +8927,14 @@ /* * Write a PCI configuration byte. */ -ASC_INITFUNC( -STATIC void, +STATIC void __init DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) -) { #ifdef CONFIG_PCI - pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data); + pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); #else /* CONFIG_PCI */ return 0; #endif /* CONFIG_PCI */ @@ -9358,16 +9145,6 @@ s->host_busy, s->host_no, (unsigned) s->last_reset); -#if ASC_LINUX_KERNEL24 - printk( -" hostt 0x%lx\n", - (ulong) s->hostt); -#elif ASC_LINUX_KERNEL22 - printk( -" host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n", - (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block); -#endif - printk( " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n", (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq); @@ -9404,11 +9181,9 @@ asc_prt_hex(" CDB", s->cmnd, s->cmd_len); -#if ASC_LINUX_KERNEL24 printk ( "sc_data_direction %u, resid %d\n", s->sc_data_direction, s->resid); -#endif printk( " use_sg %u, sglist_len %u, abort_reason 0x%x\n", @@ -9423,15 +9198,9 @@ " timeout_per_command %d, timeout_total %d, timeout %d\n", s->timeout_per_command, s->timeout_total, s->timeout); -#if ASC_LINUX_KERNEL24 printk( " internal_timeout %u, flags %u\n", s->internal_timeout, s->flags); -#elif ASC_LINUX_KERNEL22 - printk( -" internal_timeout %u, flags %u, this_count %d\n", - s->internal_timeout, s->flags,s->this_count); -#endif printk( " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n", @@ -9507,7 +9276,8 @@ printk( " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n", - h->pci_dev->device, h->lib_serial_no, h->lib_version, h->mcode_date); + to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version, + h->mcode_date); printk( " mcode_version %d, overrun_buf 0x%lx\n", @@ -9632,7 +9402,7 @@ printk( " mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n", - h->mcode_version, h->pci_dev->device, h->lib_version); + h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version); printk( " control_flag 0x%x, pci_slot_info 0x%x\n", @@ -9787,12 +9557,9 @@ * --- Asc Library Functions */ -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscGetEisaChipCfg( - PortAddr iop_base -) -) + PortAddr iop_base) { PortAddr eisa_cfg_iop; @@ -9801,13 +9568,11 @@ return (inpw(eisa_cfg_iop)); } -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init AscSetChipScsiID( PortAddr iop_base, uchar new_host_id ) -) { ushort cfg_lsw; @@ -9821,12 +9586,9 @@ return (AscGetChipScsiID(iop_base)); } -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init AscGetChipScsiCtrl( - PortAddr iop_base -) -) + PortAddr iop_base) { uchar sc; @@ -9836,13 +9598,11 @@ return (sc); } -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init AscGetChipVersion( PortAddr iop_base, ushort bus_type ) -) { if ((bus_type & ASC_IS_EISA) != 0) { PortAddr eisa_iop; @@ -9855,12 +9615,9 @@ return (AscGetChipVerNo(iop_base)); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscGetChipBusType( - PortAddr iop_base -) -) + PortAddr iop_base) { ushort chip_ver; @@ -9940,22 +9697,19 @@ return (0); } -STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA = +STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = { 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4, ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8 }; #ifdef CONFIG_ISA -STATIC uchar _isa_pnp_inited ASC_INITDATA = 0; +STATIC uchar _isa_pnp_inited __initdata = 0; -ASC_INITFUNC( -STATIC PortAddr, +STATIC PortAddr __init AscSearchIOPortAddr( PortAddr iop_beg, - ushort bus_type -) -) + ushort bus_type) { if (bus_type & ASC_IS_VL) { while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { @@ -9986,12 +9740,10 @@ return (0); } -ASC_INITFUNC( -STATIC PortAddr, +STATIC PortAddr __init AscSearchIOPortAddr11( PortAddr s_addr ) -) { int i; PortAddr iop_base; @@ -10017,11 +9769,8 @@ return (0); } -ASC_INITFUNC( -STATIC void, -AscSetISAPNPWaitForKey( - void) -) +STATIC void __init +AscSetISAPNPWaitForKey(void) { outp(ASC_ISA_PNP_PORT_ADDR, 0x02); outp(ASC_ISA_PNP_PORT_WRITE, 0x02); @@ -10029,25 +9778,20 @@ } #endif /* CONFIG_ISA */ -ASC_INITFUNC( -STATIC void, +STATIC void __init AscToggleIRQAct( PortAddr iop_base ) -) { AscSetChipStatus(iop_base, CIW_IRQ_ACT); AscSetChipStatus(iop_base, 0); return; } -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init AscGetChipIRQ( PortAddr iop_base, - ushort bus_type -) -) + ushort bus_type) { ushort cfg_lsw; uchar chip_irq; @@ -10077,14 +9821,11 @@ return ((uchar) (chip_irq + ASC_MIN_IRQ_NO)); } -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init AscSetChipIRQ( PortAddr iop_base, uchar irq_no, - ushort bus_type -) -) + ushort bus_type) { ushort cfg_lsw; @@ -10119,12 +9860,9 @@ } #ifdef CONFIG_ISA -ASC_INITFUNC( -STATIC void, +STATIC void __init AscEnableIsaDma( - uchar dma_channel -) -) + uchar dma_channel) { if (dma_channel < 4) { outp(0x000B, (ushort) (0xC0 | dma_channel)); @@ -10285,7 +10023,7 @@ return (0); } else { - ext_msg.msg_type = M1_MSG_REJECT; + ext_msg.msg_type = MESSAGE_REJECT; AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG, (uchar *) &ext_msg, @@ -10385,7 +10123,7 @@ (ushort) ASCV_SCSIBUSY_B, scsi_busy); asc_dvc->queue_full_or_busy |= target_id; - if (scsi_status == SS_QUEUE_FULL) { + if (scsi_status == SAM_STAT_TASK_SET_FULL) { if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) { cur_dvc_qng -= 1; asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng; @@ -10732,7 +10470,7 @@ } else { if ((AscReadLramByte(iop_base, (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) == - SCSICMD_StartStopUnit)) { + START_STOP)) { asc_dvc->unit_not_ready &= ~target_id; if (scsiq->d3.done_stat != QD_NO_ERROR) { asc_dvc->start_motor &= ~target_id; @@ -11005,14 +10743,14 @@ #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = { - SCSICMD_Inquiry, - SCSICMD_RequestSense, - SCSICMD_ReadCapacity, - SCSICMD_ReadTOC, - SCSICMD_ModeSelect6, - SCSICMD_ModeSense6, - SCSICMD_ModeSelect10, - SCSICMD_ModeSense10, + INQUIRY, + REQUEST_SENSE, + READ_CAPACITY, + READ_TOC, + MODE_SELECT, + MODE_SENSE, + MODE_SELECT_10, + MODE_SENSE_10, 0xFF, 0xFF, 0xFF, @@ -11065,7 +10803,7 @@ target_ix = scsiq->q2.target_ix; tid_no = ASC_TIX_TO_TID(target_ix); n_q_required = 1; - if (scsiq->cdbptr[0] == SCSICMD_RequestSense) { + if (scsiq->cdbptr[0] == REQUEST_SENSE) { if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) { asc_dvc->sdtr_done &= ~scsiq->q1.target_id; sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); @@ -11134,7 +10872,7 @@ } } if (disable_syn_offset_one_fix) { - scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE; + scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | ASC_TAG_FLAG_DISABLE_DISCONNECT); } else { @@ -11143,8 +10881,8 @@ if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { if (asc_dvc->bug_fix_cntl) { if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { - if ((scsi_cmd == SCSICMD_Read6) || - (scsi_cmd == SCSICMD_Read10)) { + if ((scsi_cmd == READ_6) || + (scsi_cmd == READ_10)) { addr = (ADV_PADDR) le32_to_cpu( sg_head->sg_list[sg_entry_cnt_minus_one].addr) + @@ -11193,8 +10931,8 @@ } else { if (asc_dvc->bug_fix_cntl) { if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { - if ((scsi_cmd == SCSICMD_Read6) || - (scsi_cmd == SCSICMD_Read10)) { + if ((scsi_cmd == READ_6) || + (scsi_cmd == READ_10)) { addr = le32_to_cpu(scsiq->q1.data_addr) + le32_to_cpu(scsiq->q1.data_cnt); extra_bytes = (uchar) ((ushort) addr & 0x0003); @@ -11365,7 +11103,7 @@ } q_addr = ASC_QNO_TO_QADDR(q_no); if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) { - scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE; + scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ; } scsiq->q1.status = QS_FREE; AscMemWordCopyPtrToLram(iop_base, @@ -11862,12 +11600,9 @@ } #ifdef CONFIG_ISA -ASC_INITFUNC( -STATIC ASC_DCNT, +STATIC ASC_DCNT __init AscGetEisaProductID( - PortAddr iop_base -) -) + PortAddr iop_base) { PortAddr eisa_iop; ushort product_id_high, product_id_low; @@ -11881,12 +11616,9 @@ return (product_id); } -ASC_INITFUNC( -STATIC PortAddr, +STATIC PortAddr __init AscSearchIOPortAddrEISA( - PortAddr iop_base -) -) + PortAddr iop_base) { ASC_DCNT eisa_product_id; @@ -12080,12 +11812,9 @@ return (AscIsChipHalted(iop_base)); } -ASC_INITFUNC( -STATIC ASC_DCNT, +STATIC ASC_DCNT __init AscGetMaxDmaCount( - ushort bus_type -) -) + ushort bus_type) { if (bus_type & ASC_IS_ISA) return (ASC_MAX_ISA_DMA_COUNT); @@ -12095,12 +11824,9 @@ } #ifdef CONFIG_ISA -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscGetIsaDmaChannel( - PortAddr iop_base -) -) + PortAddr iop_base) { ushort channel; @@ -12112,13 +11838,10 @@ return (channel + 4); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscSetIsaDmaChannel( PortAddr iop_base, - ushort dma_channel -) -) + ushort dma_channel) { ushort cfg_lsw; uchar value; @@ -12136,13 +11859,10 @@ return (0); } -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init AscSetIsaDmaSpeed( PortAddr iop_base, - uchar speed_value -) -) + uchar speed_value) { speed_value &= 0x07; AscSetBank(iop_base, 1); @@ -12151,12 +11871,10 @@ return (AscGetIsaDmaSpeed(iop_base)); } -ASC_INITFUNC( -STATIC uchar, +STATIC uchar __init AscGetIsaDmaSpeed( PortAddr iop_base ) -) { uchar speed_value; @@ -12168,12 +11886,10 @@ } #endif /* CONFIG_ISA */ -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscReadPCIConfigWord( ASC_DVC_VAR *asc_dvc, ushort pci_config_offset) -) { uchar lsb, msb; @@ -12182,12 +11898,10 @@ return ((ushort) ((msb << 8) | lsb)); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscInitGetConfig( ASC_DVC_VAR *asc_dvc ) -) { ushort warn_code; PortAddr iop_base; @@ -12267,12 +11981,10 @@ return(warn_code); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscInitSetConfig( ASC_DVC_VAR *asc_dvc ) -) { ushort warn_code = 0; @@ -12288,12 +12000,10 @@ return (warn_code); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscInitFromAscDvcVar( ASC_DVC_VAR *asc_dvc ) -) { PortAddr iop_base; ushort cfg_msw; @@ -12301,7 +12011,7 @@ ushort pci_device_id; iop_base = asc_dvc->iop_base; - pci_device_id = asc_dvc->cfg->pci_dev->device; + pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device; warn_code = 0; cfg_msw = AscGetChipCfgMsw(iop_base); if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { @@ -12393,12 +12103,9 @@ return (warn_code); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscInitAscDvcVar( - ASC_DVC_VAR *asc_dvc -) -) + ASC_DVC_VAR *asc_dvc) { int i; PortAddr iop_base; @@ -12508,12 +12215,8 @@ return (warn_code); } -ASC_INITFUNC( -STATIC ushort, -AscInitFromEEP( - ASC_DVC_VAR *asc_dvc -) -) +STATIC ushort __init +AscInitFromEEP(ASC_DVC_VAR *asc_dvc) { ASCEEP_CONFIG eep_config_buf; ASCEEP_CONFIG *eep_config; @@ -12729,12 +12432,9 @@ return (warn_code); } -ASC_INITFUNC( -STATIC int, +STATIC int __init AscTestExternalLram( - ASC_DVC_VAR *asc_dvc -) -) + ASC_DVC_VAR *asc_dvc) { PortAddr iop_base; ushort q_addr; @@ -12756,13 +12456,11 @@ return (sta); } -ASC_INITFUNC( -STATIC int, +STATIC int __init AscWriteEEPCmdReg( PortAddr iop_base, uchar cmd_reg ) -) { uchar read_back; int retry; @@ -12781,13 +12479,11 @@ } } -ASC_INITFUNC( -STATIC int, +STATIC int __init AscWriteEEPDataReg( PortAddr iop_base, ushort data_reg ) -) { ushort read_back; int retry; @@ -12806,35 +12502,24 @@ } } -ASC_INITFUNC( -STATIC void, -AscWaitEEPRead( - void -) -) +STATIC void __init +AscWaitEEPRead(void) { DvcSleepMilliSecond(1); return; } -ASC_INITFUNC( -STATIC void, -AscWaitEEPWrite( - void -) -) +STATIC void __init +AscWaitEEPWrite(void) { DvcSleepMilliSecond(20); return; } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscReadEEPWord( PortAddr iop_base, - uchar addr -) -) + uchar addr) { ushort read_wval; uchar cmd_reg; @@ -12849,14 +12534,11 @@ return (read_wval); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscWriteEEPWord( PortAddr iop_base, uchar addr, - ushort word_val -) -) + ushort word_val) { ushort read_wval; @@ -12876,13 +12558,10 @@ return (read_wval); } -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AscGetEEPConfig( PortAddr iop_base, - ASCEEP_CONFIG * cfg_buf, ushort bus_type -) -) + ASCEEP_CONFIG * cfg_buf, ushort bus_type) { ushort wval; ushort sum; @@ -12928,13 +12607,10 @@ return (sum); } -ASC_INITFUNC( -STATIC int, +STATIC int __init AscSetEEPConfigOnce( PortAddr iop_base, - ASCEEP_CONFIG * cfg_buf, ushort bus_type -) -) + ASCEEP_CONFIG * cfg_buf, ushort bus_type) { int n_error; ushort *wbuf; @@ -13026,13 +12702,11 @@ return (n_error); } -ASC_INITFUNC( -STATIC int, +STATIC int __init AscSetEEPConfig( PortAddr iop_base, ASCEEP_CONFIG * cfg_buf, ushort bus_type ) -) { int retry; int n_error; @@ -13066,17 +12740,17 @@ { if (!(asc_dvc->init_sdtr & tid_bits)) { - if ((dvc_type == SCSI_TYPE_CDROM) && + if ((dvc_type == TYPE_ROM) && (AscCompareString((uchar *) inq->vendor_id, (uchar *) "HP ", 3) == 0)) { asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; } asc_dvc->pci_fix_asyn_xfer |= tid_bits; - if ((dvc_type == SCSI_TYPE_PROC) || - (dvc_type == SCSI_TYPE_SCANNER) || - (dvc_type == SCSI_TYPE_CDROM) || - (dvc_type == SCSI_TYPE_SASD)) + if ((dvc_type == TYPE_PROCESSOR) || + (dvc_type == TYPE_SCANNER) || + (dvc_type == TYPE_ROM) || + (dvc_type == TYPE_TAPE)) { asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; } @@ -14470,7 +14144,7 @@ * unswapped on big-endian platforms. */ STATIC ADVEEP_3550_CONFIG -Default_3550_EEPROM_Config ASC_INITDATA = { +Default_3550_EEPROM_Config __initdata = { ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */ 0x0000, /* cfg_msw */ 0xFFFF, /* disc_enable */ @@ -14508,7 +14182,7 @@ }; STATIC ADVEEP_3550_CONFIG -ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = { +ADVEEP_3550_Config_Field_IsChar __initdata = { 0, /* cfg_lsw */ 0, /* cfg_msw */ 0, /* -disc_enable */ @@ -14546,7 +14220,7 @@ }; STATIC ADVEEP_38C0800_CONFIG -Default_38C0800_EEPROM_Config ASC_INITDATA = { +Default_38C0800_EEPROM_Config __initdata = { ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ 0x0000, /* 01 cfg_msw */ 0xFFFF, /* 02 disc_enable */ @@ -14611,7 +14285,7 @@ }; STATIC ADVEEP_38C0800_CONFIG -ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = { +ADVEEP_38C0800_Config_Field_IsChar __initdata = { 0, /* 00 cfg_lsw */ 0, /* 01 cfg_msw */ 0, /* 02 disc_enable */ @@ -14676,7 +14350,7 @@ }; STATIC ADVEEP_38C1600_CONFIG -Default_38C1600_EEPROM_Config ASC_INITDATA = { +Default_38C1600_EEPROM_Config __initdata = { ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ 0x0000, /* 01 cfg_msw */ 0xFFFF, /* 02 disc_enable */ @@ -14741,7 +14415,7 @@ }; STATIC ADVEEP_38C1600_CONFIG -ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = { +ADVEEP_38C1600_Config_Field_IsChar __initdata = { 0, /* 00 cfg_lsw */ 0, /* 01 cfg_msw */ 0, /* 02 disc_enable */ @@ -14813,10 +14487,8 @@ * For a non-fatal error return a warning code. If there are no warnings * then 0 is returned. */ -ASC_INITFUNC( -STATIC int, +STATIC int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) -) { ushort warn_code; AdvPortAddr iop_base; @@ -16800,10 +16472,8 @@ * * Note: Chip is stopped on entry. */ -ASC_INITFUNC( -STATIC int, +STATIC int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) -) { AdvPortAddr iop_base; ushort warn_code; @@ -16974,10 +16644,8 @@ * * Note: Chip is stopped on entry. */ -ASC_INITFUNC( -STATIC int, +STATIC int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) -) { AdvPortAddr iop_base; ushort warn_code; @@ -17209,10 +16877,8 @@ * * Note: Chip is stopped on entry. */ -ASC_INITFUNC( -STATIC int, +STATIC int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) -) { AdvPortAddr iop_base; ushort warn_code; @@ -17477,10 +17143,8 @@ * * Return a checksum based on the EEPROM configuration read. */ -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) -) { ushort wval, chksum; ushort *wbuf; @@ -17525,11 +17189,9 @@ * * Return a checksum based on the EEPROM configuration read. */ -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) -) { ushort wval, chksum; ushort *wbuf; @@ -17574,11 +17236,9 @@ * * Return a checksum based on the EEPROM configuration read. */ -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) -) { ushort wval, chksum; ushort *wbuf; @@ -17621,10 +17281,8 @@ /* * Read the EEPROM from specified location */ -ASC_INITFUNC( -STATIC ushort, +STATIC ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) -) { AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_READ | eep_word_addr); @@ -17635,10 +17293,8 @@ /* * Wait for EEPROM command to complete */ -ASC_INITFUNC( -STATIC void, +STATIC void __init AdvWaitEEPCmd(AdvPortAddr iop_base) -) { int eep_delay_ms; @@ -18290,7 +17946,7 @@ * the device, otherwise may erroneously set *_able bits. */ if (scsiq->done_status == QD_NO_ERROR && - scsiq->cdb[0] == SCSICMD_Inquiry && + scsiq->cdb[0] == INQUIRY && scsiq->target_lun == 0 && (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT) == ADV_INQ_RTN_STD_INQUIRY_DATA) diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c --- a/drivers/scsi/aha1542.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/aha1542.c 2004-06-26 17:09:18 -07:00 @@ -47,7 +47,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "aha1542.h" #define SCSI_BUF_PA(address) isa_virt_to_bus(address) diff -Nru a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c --- a/drivers/scsi/aha1740.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/aha1740.c 2004-06-26 17:09:21 -07:00 @@ -56,7 +56,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "aha1740.h" /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h --- a/drivers/scsi/aic7xxx/aic79xx_osm.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h 2004-06-26 17:09:18 -07:00 @@ -68,7 +68,7 @@ /* Core SCSI definitions */ #define AIC_LIB_PREFIX ahd #include "scsi.h" -#include "hosts.h" +#include /* Name space conflict with BSD queue macros */ #ifdef LIST_HEAD diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h 2004-06-26 17:09:17 -07:00 @@ -85,7 +85,7 @@ /* Core SCSI definitions */ #define AIC_LIB_PREFIX ahc #include "scsi.h" -#include "hosts.h" +#include /* Name space conflict with BSD queue macros */ #ifdef LIST_HEAD diff -Nru a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c --- a/drivers/scsi/aic7xxx/aiclib.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/aic7xxx/aiclib.c 2004-06-26 17:09:18 -07:00 @@ -36,7 +36,7 @@ /* Core SCSI definitions */ #include "scsi.h" -#include "hosts.h" +#include #include "aiclib.h" #include "cam.h" diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c --- a/drivers/scsi/aic7xxx_old.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/aic7xxx_old.c 2004-06-26 17:09:17 -07:00 @@ -239,7 +239,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "aic7xxx_old/aic7xxx.h" #include "aic7xxx_old/sequencer.h" diff -Nru a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c --- a/drivers/scsi/amiga7xx.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/amiga7xx.c 2004-06-26 17:09:17 -07:00 @@ -25,7 +25,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "53c7xx.h" #include "amiga7xx.h" diff -Nru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c --- a/drivers/scsi/ata_piix.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/ata_piix.c 2004-06-26 17:09:18 -07:00 @@ -57,6 +57,7 @@ ich5_pata = 0, ich5_sata = 1, piix4_pata = 2, + ich6_sata = 3, }; static int piix_init_one (struct pci_dev *pdev, @@ -91,10 +92,8 @@ * and enhanced mode, with queueing and other fancy stuff. * This is distinguished by PCI class code. */ - { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_STORAGE_IDE << 8, 0xffff00, ich5_sata }, - { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_STORAGE_IDE << 8, 0xffff00, ich5_sata }, + { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, + { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, { } /* terminate list */ }; @@ -138,7 +137,7 @@ .bmdma_setup = ata_bmdma_setup_pio, .bmdma_start = ata_bmdma_start_pio, - .fill_sg = ata_fill_sg, + .qc_prep = ata_qc_prep, .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, @@ -161,7 +160,7 @@ .bmdma_setup = ata_bmdma_setup_pio, .bmdma_start = ata_bmdma_start_pio, - .fill_sg = ata_fill_sg, + .qc_prep = ata_qc_prep, .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, @@ -199,6 +198,17 @@ .udma_mask = ATA_UDMA_MASK_40C, /* FIXME: cbl det */ .port_ops = &piix_pata_ops, }, + + /* ich6_sata */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | + PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR | + ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x03, /* pio3-4 */ + .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .port_ops = &piix_sata_ops, + }, }; static struct pci_bits piix_enable_bits[] = { @@ -327,13 +337,6 @@ static void piix_sata_phy_reset(struct ata_port *ap) { - if (!pci_test_config_bits(ap->host_set->pdev, - &piix_enable_bits[ap->port_no])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return; - } - if (!piix_sata_probe(ap)) { ata_port_disable(ap); printk(KERN_INFO "ata%u: SATA port has no device.\n", ap->id); diff -Nru a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c --- a/drivers/scsi/atari_scsi.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/atari_scsi.c 2004-06-26 17:09:21 -07:00 @@ -102,7 +102,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "atari_scsi.h" #include "NCR5380.h" #include diff -Nru a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c --- a/drivers/scsi/atp870u.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/atp870u.c 2004-06-26 17:09:17 -07:00 @@ -35,7 +35,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "atp870u.h" /* diff -Nru a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c --- a/drivers/scsi/blz1230.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/blz1230.c 2004-06-26 17:09:19 -07:00 @@ -28,7 +28,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c --- a/drivers/scsi/blz2060.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/blz2060.c 2004-06-26 17:09:17 -07:00 @@ -28,7 +28,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c --- a/drivers/scsi/bvme6000.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/bvme6000.c 2004-06-26 17:09:15 -07:00 @@ -17,7 +17,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "53c7xx.h" #include "bvme6000.h" diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c --- a/drivers/scsi/constants.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/constants.c 2004-06-26 17:09:19 -07:00 @@ -12,7 +12,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #define CONST_COMMAND 0x01 #define CONST_STATUS 0x02 @@ -154,7 +154,7 @@ } #endif -void print_command (unsigned char *command) { +void __scsi_print_command (unsigned char *command) { int i,s; print_opcode(command[0]); for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) @@ -173,7 +173,7 @@ * (e.g. "0x2" for Check Condition). **/ void -print_status(unsigned char scsi_status) { +scsi_print_status(unsigned char scsi_status) { #if (CONSTANTS & CONST_STATUS) const char * ccp; @@ -1014,12 +1014,12 @@ #endif } -void print_sense(const char *devclass, struct scsi_cmnd *cmd) +void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd) { print_sense_internal(devclass, cmd->sense_buffer, cmd->request); } -void print_req_sense(const char *devclass, struct scsi_request *sreq) +void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq) { print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request); } @@ -1051,7 +1051,7 @@ #define NO_EXTENDED_MSGS (sizeof(two_byte_msgs) / sizeof (const char *)) #endif /* (CONSTANTS & CONST_MSG) */ -int print_msg (const unsigned char *msg) { +int scsi_print_msg (const unsigned char *msg) { int len = 0, i; if (msg[0] == EXTENDED_MESSAGE) { len = 3 + msg[1]; @@ -1124,13 +1124,13 @@ return len; } -void print_Scsi_Cmnd(struct scsi_cmnd *cmd) { +void scsi_print_command(struct scsi_cmnd *cmd) { printk("scsi%d : destination target %d, lun %d\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun); printk(" command = "); - print_command(cmd->cmnd); + __scsi_print_command(cmd->cmnd); } #if (CONSTANTS & CONST_HOST) @@ -1139,7 +1139,7 @@ "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL}; -void print_hostbyte(int scsiresult) +void scsi_print_hostbyte(int scsiresult) { static int maxcode=0; int i; @@ -1155,7 +1155,7 @@ printk("(%s) ",hostbyte_table[host_byte(scsiresult)]); } #else -void print_hostbyte(int scsiresult) +void scsi_print_hostbyte(int scsiresult) { printk("Hostbyte=0x%02x ",host_byte(scsiresult)); } #endif @@ -1170,7 +1170,7 @@ unknown,unknown,unknown, "SUGGEST_SENSE",NULL}; -void print_driverbyte(int scsiresult) +void scsi_print_driverbyte(int scsiresult) { static int driver_max=0,suggest_max=0; int i,dr=driver_byte(scsiresult)&DRIVER_MASK, su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4; @@ -1187,7 +1187,7 @@ su #include "scsi.h" -#include "hosts.h" // Scsi_Host definition for INT handler +#include // Scsi_Host definition for INT handler #include "cpqfcTSchip.h" #include "cpqfcTSstructs.h" diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c --- a/drivers/scsi/cpqfcTSinit.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/cpqfcTSinit.c 2004-06-26 17:09:15 -07:00 @@ -51,7 +51,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include #include "cpqfcTSchip.h" #include "cpqfcTSstructs.h" @@ -1266,7 +1266,7 @@ -// The file "hosts.h" says not to call scsi_done from +// The file says not to call scsi_done from // inside _queuecommand, so we'll do it from the heartbeat timer // (clarification: Turns out it's ok to call scsi_done from queuecommand // for cases that don't go to the hardware like scsi cmds destined diff -Nru a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c --- a/drivers/scsi/cpqfcTSworker.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/cpqfcTSworker.c 2004-06-26 17:09:19 -07:00 @@ -39,7 +39,7 @@ #include #include "scsi.h" -#include "hosts.h" // struct Scsi_Host definition for T handler +#include // struct Scsi_Host definition for T handler #include "cpqfcTSchip.h" #include "cpqfcTSstructs.h" #include "cpqfcTStrigger.h" diff -Nru a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c --- a/drivers/scsi/cyberstorm.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/cyberstorm.c 2004-06-26 17:09:20 -07:00 @@ -31,7 +31,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c --- a/drivers/scsi/cyberstormII.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/cyberstormII.c 2004-06-26 17:09:20 -07:00 @@ -27,7 +27,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/dc390.h b/drivers/scsi/dc390.h --- a/drivers/scsi/dc390.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/dc390.h 2004-06-26 17:09:16 -07:00 @@ -14,12 +14,9 @@ #define DC390_H #include -#ifndef KERNEL_VERSION -# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#endif #define DC390_BANNER "Tekram DC390/AM53C974" -#define DC390_VERSION "2.1b 2004-04-13" +#define DC390_VERSION "2.1d 2004-05-27" /* We don't have eh_abort_handler, eh_device_reset_handler, * eh_bus_reset_handler, eh_host_reset_handler yet! @@ -32,14 +29,4 @@ # define NEW_EH use_new_eh_code: 1, # define USE_NEW_EH #endif - -static int DC390_detect(Scsi_Host_Template *psht); -static int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)); -static int DC390_abort(Scsi_Cmnd *cmd); -static int DC390_reset(Scsi_Cmnd *cmd); -static int DC390_bios_param(struct scsi_device *sdev, struct block_device *dev, - sector_t capacity, int geom[]); - -static int DC390_release(struct Scsi_Host *); - #endif /* DC390_H */ diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c --- a/drivers/scsi/dc395x.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/dc395x.c 2004-06-26 17:09:16 -07:00 @@ -53,7 +53,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "dc395x.h" #include /* needed for scsicam_bios_param */ #include diff -Nru a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c --- a/drivers/scsi/dec_esp.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/dec_esp.c 2004-06-26 17:09:19 -07:00 @@ -29,7 +29,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c --- a/drivers/scsi/dmx3191d.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/dmx3191d.c 2004-06-26 17:09:18 -07:00 @@ -34,7 +34,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "dmx3191d.h" diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c --- a/drivers/scsi/dpt_i2o.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/dpt_i2o.c 2004-06-26 17:09:20 -07:00 @@ -68,8 +68,11 @@ #include #include /* for virt_to_bus, etc. */ -#include "scsi.h" -#include "hosts.h" +#include +#include +#include +#include +#include #include "dpt/dptsig.h" #include "dpti.h" @@ -86,9 +89,9 @@ #elif defined(__ia64__) PROC_INTEL, PROC_IA64, #elif defined(__sparc__) - PROC_ULTRASPARC, + PROC_ULTRASPARC, PROC_ULTRASPARC, #elif defined(__alpha__) - PROC_ALPHA , + PROC_ALPHA, PROC_ALPHA, #else (-1),(-1), #endif @@ -173,7 +176,7 @@ }; MODULE_DEVICE_TABLE(pci,dptids); -static int adpt_detect(Scsi_Host_Template* sht) +static int adpt_detect(struct scsi_host_template* sht) { struct pci_dev *pDev = NULL; adpt_hba* pHba; @@ -362,7 +365,7 @@ } -static int adpt_slave_configure(Scsi_Device * device) +static int adpt_slave_configure(struct scsi_device * device) { struct Scsi_Host *host = device->host; adpt_hba* pHba; @@ -378,7 +381,7 @@ return 0; } -static int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) +static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *)) { adpt_hba* pHba = NULL; struct adpt_device* pDev = NULL; /* dpt per device information */ @@ -643,7 +646,7 @@ *=========================================================================== */ -static int adpt_abort(Scsi_Cmnd * cmd) +static int adpt_abort(struct scsi_cmnd * cmd) { adpt_hba* pHba = NULL; /* host bus adapter structure */ struct adpt_device* dptdevice; /* dpt per device information */ @@ -683,7 +686,7 @@ // This is the same for BLK and SCSI devices // NOTE this is wrong in the i2o.h definitions // This is not currently supported by our adapter but we issue it anyway -static int adpt_device_reset(Scsi_Cmnd* cmd) +static int adpt_device_reset(struct scsi_cmnd* cmd) { adpt_hba* pHba; u32 msg[4]; @@ -723,7 +726,7 @@ #define I2O_HBA_BUS_RESET 0x87 // This version of bus reset is called by the eh_error handler -static int adpt_bus_reset(Scsi_Cmnd* cmd) +static int adpt_bus_reset(struct scsi_cmnd* cmd) { adpt_hba* pHba; u32 msg[4]; @@ -745,7 +748,7 @@ } // This version of reset is called by the eh_error_handler -static int adpt_reset(Scsi_Cmnd* cmd) +static int adpt_reset(struct scsi_cmnd* cmd) { adpt_hba* pHba; int rcode; @@ -860,7 +863,7 @@ #endif -static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) +static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) { adpt_hba* pHba = NULL; @@ -1997,7 +2000,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs) { - Scsi_Cmnd* cmd; + struct scsi_cmnd* cmd; adpt_hba* pHba = dev_id; u32 m; ulong reply; @@ -2059,14 +2062,14 @@ status = I2O_POST_WAIT_OK; } if(!(context & 0x40000000)) { - cmd = (Scsi_Cmnd*) readl(reply+12); + cmd = (struct scsi_cmnd*) readl(reply+12); if(cmd != NULL) { printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); } } adpt_i2o_post_wait_complete(context, status); } else { // SCSI message - cmd = (Scsi_Cmnd*) readl(reply+12); + cmd = (struct scsi_cmnd*) readl(reply+12); if(cmd != NULL){ if(cmd->serial_number != 0) { // If not timedout adpt_i2o_to_scsi(reply, cmd); @@ -2083,7 +2086,7 @@ return IRQ_RETVAL(handled); } -static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d) +static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* d) { int i; u32 msg[MAX_MESSAGE_SIZE]; @@ -2108,16 +2111,16 @@ * cmd->cmnd[0] is an unsigned char */ switch(cmd->sc_data_direction){ - case SCSI_DATA_READ: + case DMA_FROM_DEVICE: scsidir =0x40000000; // DATA IN (iop<--dev) break; - case SCSI_DATA_WRITE: + case DMA_TO_DEVICE: direction=0x04000000; // SGL OUT scsidir =0x80000000; // DATA OUT (iop-->dev) break; - case SCSI_DATA_NONE: + case DMA_NONE: break; - case SCSI_DATA_UNKNOWN: + case DMA_BIDIRECTIONAL: scsidir =0x40000000; // DATA IN (iop<--dev) // Assume In - and continue; break; @@ -2156,7 +2159,7 @@ if(cmd->use_sg) { struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer; int sg_count = pci_map_sg(pHba->pDev, sg, cmd->use_sg, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->sc_data_direction); len = 0; @@ -2184,7 +2187,7 @@ *mptr++ = pci_map_single(pHba->pDev, cmd->request_buffer, cmd->request_bufflen, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->sc_data_direction); } } @@ -2200,7 +2203,7 @@ } -static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht) +static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht) { struct Scsi_Host *host = NULL; @@ -2231,7 +2234,7 @@ } -static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd) +static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd) { adpt_hba* pHba; u32 hba_status; @@ -2533,8 +2536,8 @@ static void adpt_fail_posted_scbs(adpt_hba* pHba) { - Scsi_Cmnd* cmd = NULL; - Scsi_Device* d = NULL; + struct scsi_cmnd* cmd = NULL; + struct scsi_device* d = NULL; shost_for_each_device(d, pHba->host) { unsigned long flags; @@ -3358,7 +3361,7 @@ #endif -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "dpt_i2o", .proc_name = "dpt_i2o", .proc_info = adpt_proc_info, diff -Nru a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h --- a/drivers/scsi/dpti.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/dpti.h 2004-06-26 17:09:15 -07:00 @@ -37,19 +37,19 @@ * SCSI interface function Prototypes */ -static int adpt_detect(Scsi_Host_Template * sht); -static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *)); -static int adpt_abort(Scsi_Cmnd * cmd); -static int adpt_reset(Scsi_Cmnd* cmd); +static int adpt_detect(struct scsi_host_template * sht); +static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *)); +static int adpt_abort(struct scsi_cmnd * cmd); +static int adpt_reset(struct scsi_cmnd* cmd); static int adpt_release(struct Scsi_Host *host); -static int adpt_slave_configure(Scsi_Device *); +static int adpt_slave_configure(struct scsi_device *); static const char *adpt_info(struct Scsi_Host *pSHost); static int adpt_bios_param(struct scsi_device * sdev, struct block_device *dev, sector_t, int geom[]); -static int adpt_bus_reset(Scsi_Cmnd* cmd); -static int adpt_device_reset(Scsi_Cmnd* cmd); +static int adpt_bus_reset(struct scsi_cmnd* cmd); +static int adpt_device_reset(struct scsi_cmnd* cmd); /* @@ -198,7 +198,7 @@ u8 state; u16 tid; struct i2o_device* pI2o_dev; - Scsi_Device *pScsi_dev; + struct scsi_device *pScsi_dev; }; struct adpt_channel { @@ -296,9 +296,9 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba); static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba); static s32 adpt_i2o_hrt_get(adpt_hba* pHba); -static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice); -static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd); -static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht); +static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice); +static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd); +static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht); static s32 adpt_hba_reset(adpt_hba* pHba); static s32 adpt_i2o_reset_hba(adpt_hba* pHba); static s32 adpt_rescan(adpt_hba* pHba); @@ -308,7 +308,7 @@ static void adpt_inquiry(adpt_hba* pHba); static void adpt_fail_posted_scbs(adpt_hba* pHba); static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun); -static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ; +static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ; static int adpt_i2o_online_hba(adpt_hba* pHba); static void adpt_i2o_post_wait_complete(u32, int); static int adpt_i2o_systab_send(adpt_hba* pHba); diff -Nru a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c --- a/drivers/scsi/dtc.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/dtc.c 2004-06-26 17:09:19 -07:00 @@ -84,7 +84,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "dtc.h" #define AUTOPROBE_IRQ #include "NCR5380.h" diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c --- a/drivers/scsi/eata.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/eata.c 2004-06-26 17:09:20 -07:00 @@ -495,7 +495,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/eata_generic.h b/drivers/scsi/eata_generic.h --- a/drivers/scsi/eata_generic.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/eata_generic.h 2004-06-26 17:09:18 -07:00 @@ -317,7 +317,7 @@ __u8 rw_latency; __u8 retries; __u8 status; /* status of this queueslot */ - Scsi_Cmnd *cmd; /* address of cmd */ + struct scsi_cmnd *cmd; /* address of cmd */ struct eata_sg_list *sg_list; }; diff -Nru a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c --- a/drivers/scsi/eata_pio.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/eata_pio.c 2004-06-26 17:09:19 -07:00 @@ -46,6 +46,7 @@ * last change: 2002/11/02 OS: Linux 2.5.45 * ************************************************************/ +#include #include #include #include @@ -56,15 +57,14 @@ #include #include #include -#include -#include #include #include #include -#include "scsi.h" -#include "hosts.h" -#include +#include +#include +#include +#include #include "eata_generic.h" #include "eata_pio.h" @@ -91,6 +91,8 @@ static unsigned long int_counter; static unsigned long queue_counter; +static struct scsi_host_template driver_template; + /* * eata_proc_info * inout : decides on the direction of the dataflow and the meaning of the @@ -170,15 +172,15 @@ if (sh->io_port && sh->n_io_port) release_region(sh->io_port, sh->n_io_port); } - return (TRUE); + return 1; } -static void IncStat(Scsi_Pointer * SCp, uint Increment) +static void IncStat(struct scsi_pointer *SCp, uint Increment) { SCp->ptr += Increment; if ((SCp->this_residual -= Increment) == 0) { if ((--SCp->buffers_residual) == 0) - SCp->Status = FALSE; + SCp->Status = 0; else { SCp->buffer++; SCp->ptr = page_address(SCp->buffer->page) + SCp->buffer->offset; @@ -204,7 +206,7 @@ static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs) { uint eata_stat = 0xfffff; - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; hostdata *hd; struct eata_ccb *cp; uint base; @@ -233,12 +235,12 @@ if (stat & HA_SDRQ) { if (cp->DataIn) { z = 256; - odd = FALSE; + odd = 0; while ((cmd->SCp.Status) && ((z > 0) || (odd))) { if (odd) { *(cmd->SCp.ptr) = zwickel >> 8; IncStat(&cmd->SCp, 1); - odd = FALSE; + odd = 0; } x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); insw(base + HA_RDATA, cmd->SCp.ptr, x); @@ -249,7 +251,7 @@ *(cmd->SCp.ptr) = zwickel & 0xff; IncStat(&cmd->SCp, 1); z--; - odd = TRUE; + odd = 1; } } while (z > 0) { @@ -258,7 +260,7 @@ } } else { /* cp->DataOut */ - odd = FALSE; + odd = 0; z = 256; while ((cmd->SCp.Status) && ((z > 0) || (odd))) { if (odd) { @@ -266,7 +268,7 @@ IncStat(&cmd->SCp, 1); outw(zwickel, base + HA_RDATA); z--; - odd = FALSE; + odd = 0; } x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); outsw(base + HA_RDATA, cmd->SCp.ptr, x); @@ -276,13 +278,13 @@ zwickel = *(cmd->SCp.ptr); zwickel &= 0xff; IncStat(&cmd->SCp, 1); - odd = TRUE; + odd = 1; } } while (z > 0 || odd) { outw(zwickel, base + HA_RDATA); z--; - odd = FALSE; + odd = 0; } } } @@ -331,7 +333,7 @@ while (inb(base + HA_RSTATUS) & HA_SBUSY) if (--loop == 0) - return (TRUE); + return 1; /* Enable interrupts for HBA. It is not the best way to do it at this * place, but I hope that it doesn't interfere with the IDE driver @@ -340,10 +342,11 @@ outb(HA_CTRL_8HEADS, base + HA_CTRLREG); outb(command, base + HA_WCOMMAND); - return (FALSE); + return 0; } -static int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) +static int eata_pio_queue(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) { uint x, y; uint base; @@ -383,21 +386,21 @@ cmd->scsi_done = (void *) done; - if(cmd->sc_data_direction == SCSI_DATA_WRITE) - cp->DataOut = TRUE; /* Output mode */ + if (cmd->sc_data_direction == DMA_TO_DEVICE) + cp->DataOut = 1; /* Output mode */ else - cp->DataIn = TRUE; /* Input mode */ + cp->DataIn = 0; /* Input mode */ cp->Interpret = (cmd->device->id == hd->hostid); cp->cp_datalen = htonl((unsigned long) cmd->request_bufflen); - cp->Auto_Req_Sen = FALSE; + cp->Auto_Req_Sen = 0; cp->cp_reqDMA = htonl(0); cp->reqlen = 0; cp->cp_id = cmd->device->id; cp->cp_lun = cmd->device->lun; - cp->cp_dispri = FALSE; - cp->cp_identify = TRUE; + cp->cp_dispri = 0; + cp->cp_identify = 1; memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); cp->cp_statDMA = htonl(0); @@ -440,7 +443,7 @@ return (0); } -static int eata_pio_abort(Scsi_Cmnd * cmd) +static int eata_pio_abort(struct scsi_cmnd *cmd) { uint loop = HZ; @@ -472,11 +475,11 @@ panic("eata_pio: abort: invalid slot status\n"); } -static int eata_pio_host_reset(Scsi_Cmnd * cmd) +static int eata_pio_host_reset(struct scsi_cmnd *cmd) { uint x, limit = 0; - unsigned char success = FALSE; - Scsi_Cmnd *sp; + unsigned char success = 0; + struct scsi_cmnd *sp; struct Scsi_Host *host = cmd->device->host; DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason)); @@ -530,7 +533,7 @@ sp->scsi_done(sp); } - HD(cmd)->state = FALSE; + HD(cmd)->state = 0; if (success) { /* hmmm... */ DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n")); @@ -550,8 +553,8 @@ memset(&cp, 0, sizeof(struct eata_ccb)); memset(buff, 0, sizeof(buff)); - cp.DataIn = TRUE; - cp.Interpret = TRUE; /* Interpret command */ + cp.DataIn = 1; + cp.Interpret = 1; /* Interpret command */ cp.cp_datalen = htonl(254); cp.cp_dataDMA = htonl(0); @@ -593,14 +596,14 @@ int z; unsigned short *p; - if (check_region(base, 9)) - return (FALSE); + if (!request_region(base, 9, "eata_pio")) + return 0; memset(buf, 0, sizeof(struct get_conf)); while (inb(base + HA_RSTATUS) & HA_SBUSY) if (--loop == 0) - return (FALSE); + goto fail; DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base)); eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG); @@ -609,30 +612,40 @@ for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) { while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) if (--loop == 0) - return (FALSE); + goto fail; loop = HZ / 2; *p = inw(base + HA_RDATA); } - if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */ - if (htonl(EATA_SIGNATURE) == buf->signature) { - DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " "at %#4x EATA Level: %x\n", base, (uint) (buf->version))); - - while (inb(base + HA_RSTATUS) & HA_SDRQ) - inw(base + HA_RDATA); - if (ALLOW_DMA_BOARDS == FALSE) { - for (z = 0; z < MAXISA; z++) - if (base == ISAbases[z]) { - buf->IRQ = ISAirqs[z]; - break; - } + if (inb(base + HA_RSTATUS) & HA_SERROR) { + DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during " + "transfer for HBA at %x\n", base)); + goto fail; + } + + if (htonl(EATA_SIGNATURE) != buf->signature) + goto fail; + + DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " + "at %#4x EATA Level: %x\n", + base, (uint) (buf->version))); + + while (inb(base + HA_RSTATUS) & HA_SDRQ) + inw(base + HA_RDATA); + + if (!ALLOW_DMA_BOARDS) { + for (z = 0; z < MAXISA; z++) + if (base == ISAbases[z]) { + buf->IRQ = ISAirqs[z]; + break; } - return (TRUE); - } - } else { - DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " "for HBA at %x\n", base)); } - return (FALSE); + + return 1; + + fail: + release_region(base, 9); + return 0; } static void print_pio_config(struct get_conf *gc) @@ -670,7 +683,7 @@ return (!(inb(base + HA_RSTATUS) & HA_SERROR)); } -static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt) +static int register_pio_HBA(long base, struct get_conf *gc) { unsigned long size = 0; char *buff; @@ -681,47 +694,41 @@ DBG(DBG_REGISTER, print_pio_config(gc)); - if (gc->DMA_support == TRUE) { + if (gc->DMA_support) { printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n", base); - if (ALLOW_DMA_BOARDS == FALSE) - return (FALSE); + if (!ALLOW_DMA_BOARDS) + return 0; } if ((buff = get_pio_board_data((uint) base, gc->IRQ, gc->scsi_id[3], cplen = (htonl(gc->cplen) + 1) / 2, cppadlen = (htons(gc->cppadlen) + 1) / 2)) == NULL) { printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (unsigned long) base); - return (FALSE); + return 0; } - if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE) { + if (!print_selftest(base) && !ALLOW_DMA_BOARDS) { printk("HBA at %#lx failed while performing self test & setup.\n", (unsigned long) base); - return (FALSE); + return 0; } - request_region(base, 8, "eata_pio"); - size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz)); - sh = scsi_register(tpnt, size); - if (sh == NULL) { - release_region(base, 8); - return FALSE; - } + sh = scsi_register(&driver_template, size); + if (sh == NULL) + return 0; if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */ if (!request_irq(gc->IRQ, do_eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", sh)) { reg_IRQ[gc->IRQ]++; if (!gc->IRQ_TR) - reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */ + reg_IRQL[gc->IRQ] = 1; /* IRQ is edge triggered */ } else { printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ); - release_region(base, 8); - return (FALSE); + return 0; } } else { /* More than one HBA on this IRQ */ - if (reg_IRQL[gc->IRQ] == TRUE) { + if (reg_IRQL[gc->IRQ]) { printk("Can't support more than one HBA on this IRQ,\n" " if the IRQ is edge triggered. Sorry.\n"); - release_region(base, 8); - return (FALSE); + return 0; } else reg_IRQ[gc->IRQ]++; } @@ -757,9 +764,9 @@ } if (ntohl(gc->len) >= 0x22) { - if (gc->is_PCI == TRUE) + if (gc->is_PCI) hd->bustype = IS_PCI; - else if (gc->is_EISA == TRUE) + else if (gc->is_EISA) hd->bustype = IS_EISA; else hd->bustype = IS_ISA; @@ -780,7 +787,7 @@ sh->unique_id = base; sh->base = base; sh->io_port = base; - sh->n_io_port = 8; + sh->n_io_port = 9; sh->irq = gc->IRQ; sh->dma_channel = PIO; sh->this_id = gc->scsi_id[3]; @@ -794,11 +801,11 @@ sh->max_lun = 8; if (gc->SECOND) - hd->primary = FALSE; + hd->primary = 0; else - hd->primary = TRUE; + hd->primary = 1; - sh->unchecked_isa_dma = FALSE; /* We can only do PIO */ + sh->unchecked_isa_dma = 0; /* We can only do PIO */ hd->next = NULL; /* build a linked list of all HBAs */ hd->prev = last_HBA; @@ -811,22 +818,24 @@ return (1); } -static void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt) +static void find_pio_ISA(struct get_conf *buf) { int i; for (i = 0; i < MAXISA; i++) { - if (ISAbases[i]) { - if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE) { - register_pio_HBA(ISAbases[i], buf, tpnt); - } + if (!ISAbases[i]) + continue; + if (!get_pio_conf_PIO(ISAbases[i], buf)) + continue; + if (!register_pio_HBA(ISAbases[i], buf)) + release_region(ISAbases[i], 9); + else ISAbases[i] = 0; - } } return; } -static void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt) +static void find_pio_EISA(struct get_conf *buf) { u32 base; int i; @@ -836,7 +845,7 @@ #endif for (i = 0; i < MAXEISA; i++) { - if (EISAbases[i] == TRUE) { /* Still a possibility ? */ + if (EISAbases[i]) { /* Still a possibility ? */ base = 0x1c88 + (i * 0x1000); #if CHECKPAL @@ -847,12 +856,15 @@ if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) { DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3)); #endif - if (get_pio_conf_PIO(base, buf) == TRUE) { + if (get_pio_conf_PIO(base, buf)) { DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf)); if (buf->IRQ) { - register_pio_HBA(base, buf, tpnt); - } else + if (!register_pio_HBA(base, buf)) + release_region(base, 9); + } else { printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n"); + release_region(base, 9); + } } /* Nothing found here so we take it from the list */ EISAbases[i] = 0; @@ -864,7 +876,7 @@ return; } -static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt) +static void find_pio_PCI(struct get_conf *buf) { #ifndef CONFIG_PCI printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); @@ -889,16 +901,21 @@ base += 0x10; /* Now, THIS is the real address */ if (base != 0x1f8) { /* We didn't find it in the primary search */ - if (get_pio_conf_PIO(base, buf) == TRUE) { - if (buf->FORCADR) /* If the address is forced */ + if (get_pio_conf_PIO(base, buf)) { + if (buf->FORCADR) { /* If the address is forced */ + release_region(base, 9); continue; /* we'll find it later */ + } /* OK. We made it till here, so we can go now * and register it. We only have to check and * eventually remove it from the EISA and ISA list */ - register_pio_HBA(base, buf, tpnt); + if (!register_pio_HBA(base, buf)) { + release_region(base, 9); + continue; + } if (base < 0x1000) { for (x = 0; x < MAXISA; ++x) { @@ -913,7 +930,7 @@ } } #if CHECK_BLINK - else if (check_blink_state(base) == TRUE) { + else if (check_blink_state(base)) { printk("eata_pio: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n"); } #endif @@ -922,20 +939,15 @@ #endif /* #ifndef CONFIG_PCI */ } - -static int eata_pio_detect(Scsi_Host_Template * tpnt) +static int eata_pio_detect(struct scsi_host_template *tpnt) { struct Scsi_Host *HBA_ptr; struct get_conf gc; int i; - tpnt->proc_name = "eata_pio"; - - find_pio_PCI(&gc, tpnt); - - find_pio_EISA(&gc, tpnt); - - find_pio_ISA(&gc, tpnt); + find_pio_PCI(&gc); + find_pio_EISA(&gc); + find_pio_ISA(&gc); for (i = 0; i <= MAXIRQ; i++) if (reg_IRQ[i]) @@ -955,16 +967,19 @@ HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P') ? "PCI " : (SD(HBA_ptr)->bustype == 'E') ? "EISA" : "ISA ", - (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE) ? 'Y' : 'N', HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun); + (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id, + SD(HBA_ptr)->primary ? 'Y' : 'N', HBA_ptr->can_queue, + HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun); HBA_ptr = SD(HBA_ptr)->next; } } return (registered_HBAs); } -static Scsi_Host_Template driver_template = { - .proc_info = eata_pio_proc_info, +static struct scsi_host_template driver_template = { + .proc_name = "eata_pio", .name = "EATA (Extended Attachment) PIO driver", + .proc_info = eata_pio_proc_info, .detect = eata_pio_detect, .release = eata_pio_release, .queuecommand = eata_pio_queue, diff -Nru a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c --- a/drivers/scsi/fastlane.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/fastlane.c 2004-06-26 17:09:17 -07:00 @@ -36,7 +36,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c --- a/drivers/scsi/fcal.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/fcal.c 2004-06-26 17:09:15 -07:00 @@ -21,7 +21,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "../fc4/fcp_impl.h" #include "fcal.h" diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c --- a/drivers/scsi/fd_mcs.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/fd_mcs.c 2004-06-26 17:09:17 -07:00 @@ -87,13 +87,14 @@ #include #include #include +#include #include #include #include #include "scsi.h" -#include "hosts.h" +#include #include "fd_mcs.h" #define DRIVER_VERSION "v0.2 by ZP Gu" @@ -1337,23 +1338,14 @@ static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev, sector_t capacity, int *info_array) { - unsigned char buf[512 + sizeof(int) * 2]; + unsigned char *p = scsi_bios_ptable(bdev); int size = capacity; - int *sizes = (int *) buf; - unsigned char *data = (unsigned char *) (sizes + 2); - unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 }; - int retcode; /* BIOS >= 3.4 for MCA cards */ /* This algorithm was provided by Future Domain (much thanks!). */ - sizes[0] = 0; /* zero bytes out */ - sizes[1] = 512; /* one sector in */ - memcpy(data, do_read, sizeof(do_read)); - retcode = kernel_scsi_ioctl(disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf); - if (!retcode /* SCSI command ok */ - && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */ - && data[0x1c2]) { /* Partition type */ + if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */ + && p[4]) { /* Partition type */ /* The partition table layout is as follows: Start: 0x1b3h @@ -1383,8 +1375,8 @@ Future Domain algorithm, but it seemed to be a reasonable thing to do, especially in the Linux and BSD worlds. */ - info_array[0] = data[0x1c3] + 1; /* heads */ - info_array[1] = data[0x1c4] & 0x3f; /* sectors */ + info_array[0] = p[5] + 1; /* heads */ + info_array[1] = p[6] & 0x3f; /* sectors */ } else { /* Note that this new method guarantees that there will always be less than 1024 cylinders on a platter. This is good for drives @@ -1403,6 +1395,7 @@ } /* For both methods, compute the cylinders */ info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]); + kfree(p); return 0; } diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c --- a/drivers/scsi/fdomain.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/fdomain.c 2004-06-26 17:09:19 -07:00 @@ -279,12 +279,13 @@ #include #include #include +#include #include #include #include "scsi.h" -#include "hosts.h" +#include MODULE_AUTHOR("Rickard E. Faith"); MODULE_DESCRIPTION("Future domain SCSI driver"); @@ -1564,12 +1565,7 @@ sector_t capacity, int *info_array) { int drive; - unsigned char buf[512 + sizeof (Scsi_Ioctl_Command)]; - Scsi_Ioctl_Command *sic = (Scsi_Ioctl_Command *) buf; int size = capacity; - unsigned char *data = sic->data; - unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 }; - int retcode; unsigned long offset; struct drive_info { unsigned short cylinders; @@ -1657,16 +1653,10 @@ info_array[2] = i.cylinders; } else { /* 3.4 BIOS (and up?) */ /* This algorithm was provided by Future Domain (much thanks!). */ + unsigned char *p = scsi_bios_ptable(bdev); - sic->inlen = 0; /* zero bytes out */ - sic->outlen = 512; /* one sector in */ - memcpy( data, do_read, sizeof( do_read ) ); - retcode = kernel_scsi_ioctl( sdev, - SCSI_IOCTL_SEND_COMMAND, - sic ); - if (!retcode /* SCSI command ok */ - && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */ - && data[0x1c2]) { /* Partition type */ + if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */ + && p[4]) { /* Partition type */ /* The partition table layout is as follows: @@ -1697,8 +1687,8 @@ Future Domain algorithm, but it seemed to be a reasonable thing to do, especially in the Linux and BSD worlds. */ - info_array[0] = data[0x1c3] + 1; /* heads */ - info_array[1] = data[0x1c4] & 0x3f; /* sectors */ + info_array[0] = p[5] + 1; /* heads */ + info_array[1] = p[6] & 0x3f; /* sectors */ } else { /* Note that this new method guarantees that there will always be @@ -1718,6 +1708,7 @@ } /* For both methods, compute the cylinders */ info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] ); + kfree(p); } return 0; diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c --- a/drivers/scsi/g_NCR5380.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/g_NCR5380.c 2004-06-26 17:09:16 -07:00 @@ -107,7 +107,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "g_NCR5380.h" #include "NCR5380.h" #include diff -Nru a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c --- a/drivers/scsi/gvp11.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/gvp11.c 2004-06-26 17:09:20 -07:00 @@ -16,7 +16,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "wd33c93.h" #include "gvp11.h" diff -Nru a/drivers/scsi/i60uscsi.c b/drivers/scsi/i60uscsi.c --- a/drivers/scsi/i60uscsi.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/i60uscsi.c 2004-06-26 17:09:16 -07:00 @@ -81,7 +81,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "inia100.h" #define JIFFIES_TO_MS(t) ((t) * 1000 / HZ) diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c --- a/drivers/scsi/ibmmca.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/ibmmca.c 2004-06-26 17:09:15 -07:00 @@ -45,7 +45,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "ibmmca.h" /* current version of this driver-source: */ diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c --- a/drivers/scsi/ide-scsi.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/ide-scsi.c 2004-06-26 17:09:19 -07:00 @@ -51,7 +51,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #define IDESCSI_DEBUG_LOG 0 diff -Nru a/drivers/scsi/imm.h b/drivers/scsi/imm.h --- a/drivers/scsi/imm.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/imm.h 2004-06-26 17:09:15 -07:00 @@ -79,7 +79,7 @@ #include #include -#include "hosts.h" +#include /* batteries not included :-) */ /* diff -Nru a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c --- a/drivers/scsi/in2000.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/in2000.c 2004-06-26 17:09:19 -07:00 @@ -126,7 +126,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #define IN2000_VERSION "1.33-2.5" #define IN2000_DATE "2002/11/03" diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c --- a/drivers/scsi/ini9100u.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/ini9100u.c 2004-06-26 17:09:16 -07:00 @@ -136,7 +136,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "ini9100u.h" #ifdef DEBUG_i91u diff -Nru a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c --- a/drivers/scsi/ipr.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/ipr.c 2004-06-26 17:09:21 -07:00 @@ -2884,6 +2884,7 @@ (res->cfgte.res_addr.lun == sdev->lun)) { res->sdev = sdev; res->add_to_ml = 0; + res->in_erp = 0; sdev->hostdata = res; res->needs_sync_complete = 1; break; @@ -3435,8 +3436,10 @@ SCSI_SENSE_BUFFERSIZE); } - if (res) + if (res) { res->needs_sync_complete = 1; + res->in_erp = 0; + } ipr_unmap_sglist(ioa_cfg, ipr_cmd); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); scsi_cmd->scsi_done(scsi_cmd); @@ -3479,6 +3482,12 @@ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) { struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; + u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + + if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { + ipr_erp_done(ipr_cmd); + return; + } ipr_reinit_ipr_cmnd_for_erp(ipr_cmd); @@ -3756,6 +3765,7 @@ ipr_erp_cancel_all(ipr_cmd); return; } + res->needs_sync_complete = 1; break; case IPR_IOASC_NR_INIT_CMD_REQUIRED: break; @@ -4808,6 +4818,7 @@ ipr_cmd->timer.data = (unsigned long) ipr_cmd; ipr_cmd->timer.expires = jiffies + IPR_OPERATIONAL_TIMEOUT; ipr_cmd->timer.function = (void (*)(unsigned long))ipr_timeout; + ipr_cmd->done = ipr_reset_ioa_job; add_timer(&ipr_cmd->timer); list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); diff -Nru a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h --- a/drivers/scsi/ipr.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/ipr.h 2004-06-26 17:09:16 -07:00 @@ -36,8 +36,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.0.7" -#define IPR_DRIVER_DATE "(May 21, 2004)" +#define IPR_DRIVER_VERSION "2.0.9" +#define IPR_DRIVER_DATE "(May 26, 2004)" /* * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c --- a/drivers/scsi/ips.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/ips.c 2004-06-26 17:09:15 -07:00 @@ -176,7 +176,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "ips.h" #include diff -Nru a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c --- a/drivers/scsi/jazz_esp.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/jazz_esp.c 2004-06-26 17:09:15 -07:00 @@ -16,7 +16,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c --- a/drivers/scsi/lasi700.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/lasi700.c 2004-06-26 17:09:15 -07:00 @@ -49,8 +49,7 @@ #include #include -#include "scsi.h" -#include "hosts.h" +#include #include "lasi700.h" #include "53c700.h" @@ -65,7 +64,7 @@ { 0 } }; -static Scsi_Host_Template lasi700_template = { +static struct scsi_host_template lasi700_template = { .name = "LASI SCSI 53c700", .proc_name = "lasi700", .this_id = 7, diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/libata-core.c 2004-06-26 17:09:15 -07:00 @@ -50,7 +50,6 @@ unsigned long tmout_pat, unsigned long tmout); static void __ata_dev_select (struct ata_port *ap, unsigned int device); -static void ata_dma_complete(struct ata_queued_cmd *qc, u8 host_stat); static void ata_host_set_pio(struct ata_port *ap); static void ata_host_set_udma(struct ata_port *ap); static void ata_dev_set_pio(struct ata_port *ap, unsigned int device); @@ -65,37 +64,6 @@ MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); -static const char * thr_state_name[] = { - "THR_UNKNOWN", - "THR_PORT_RESET", - "THR_AWAIT_DEATH", - "THR_PROBE_FAILED", - "THR_IDLE", - "THR_PROBE_SUCCESS", - "THR_PROBE_START", -}; - -/** - * ata_thr_state_name - convert thread state enum to string - * @thr_state: thread state to be converted to string - * - * Converts the specified thread state id to a constant C string. - * - * LOCKING: - * None. - * - * RETURNS: - * The THR_xxx-prefixed string naming the specified thread - * state id, or the string "". - */ - -static const char *ata_thr_state_name(unsigned int thr_state) -{ - if (thr_state < ARRAY_SIZE(thr_state_name)) - return thr_state_name[thr_state]; - return ""; -} - /** * ata_tf_load_pio - send taskfile registers to host controller * @ap: Port to which output is sent @@ -1150,13 +1118,16 @@ } /** - * ata_port_reset - - * @ap: + * ata_bus_probe - Reset and probe ATA bus + * @ap: Bus to probe * * LOCKING: + * + * RETURNS: + * Zero on success, non-zero on error. */ -static void ata_port_reset(struct ata_port *ap) +static int ata_bus_probe(struct ata_port *ap) { unsigned int i, found = 0; @@ -1180,14 +1151,12 @@ if (ap->flags & ATA_FLAG_PORT_DISABLED) goto err_out_disable; - ap->thr_state = THR_PROBE_SUCCESS; - - return; + return 0; err_out_disable: ap->ops->port_disable(ap); err_out: - ap->thr_state = THR_PROBE_FAILED; + return -1; } /** @@ -1806,13 +1775,13 @@ } /** - * ata_fill_sg - - * @qc: + * ata_fill_sg - Fill PCI IDE PRD table + * @qc: Metadata associated with taskfile to be transferred * * LOCKING: * */ -void ata_fill_sg(struct ata_queued_cmd *qc) +static void ata_fill_sg(struct ata_queued_cmd *qc) { struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; @@ -1854,6 +1823,21 @@ } /** + * ata_qc_prep - Prepare taskfile for submission + * @qc: Metadata associated with taskfile to be prepared + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ +void ata_qc_prep(struct ata_queued_cmd *qc) +{ + if (!(qc->flags & ATA_QCFLAG_SG)) + return; + + ata_fill_sg(qc); +} + +/** * ata_sg_setup_one - * @qc: * @@ -1870,7 +1854,6 @@ struct scsi_cmnd *cmd = qc->scsicmd; int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); struct scatterlist *sg = qc->sg; - unsigned int have_sg = (qc->flags & ATA_QCFLAG_SG); dma_addr_t dma_address; assert(sg == &qc->sgent); @@ -1880,9 +1863,6 @@ sg->offset = (unsigned long) cmd->request_buffer & ~PAGE_MASK; sg_dma_len(sg) = cmd->request_bufflen; - if (!have_sg) - return 0; - dma_address = pci_map_single(ap->host_set->pdev, cmd->request_buffer, cmd->request_bufflen, dir); if (pci_dma_mapping_error(dma_address)) @@ -1912,22 +1892,19 @@ struct ata_port *ap = qc->ap; struct scsi_cmnd *cmd = qc->scsicmd; struct scatterlist *sg; - int n_elem; - unsigned int have_sg = (qc->flags & ATA_QCFLAG_SG); + int n_elem, dir; VPRINTK("ENTER, ata%u, use_sg %d\n", ap->id, cmd->use_sg); assert(cmd->use_sg > 0); sg = (struct scatterlist *)cmd->request_buffer; - if (have_sg) { - int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); - n_elem = pci_map_sg(ap->host_set->pdev, sg, cmd->use_sg, dir); - if (n_elem < 1) - return -1; - DPRINTK("%d sg elements mapped\n", n_elem); - } else { - n_elem = cmd->use_sg; - } + dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + n_elem = pci_map_sg(ap->host_set->pdev, sg, cmd->use_sg, dir); + if (n_elem < 1) + return -1; + + DPRINTK("%d sg elements mapped\n", n_elem); + qc->n_elem = n_elem; return 0; @@ -2146,8 +2123,8 @@ } /** - * ata_eng_timeout - Handle timeout of queued command - * @ap: Port on which timed-out command is active + * ata_qc_timeout - Handle timeout of queued command + * @qc: Command that timed out * * Some part of the kernel (currently, only the SCSI layer) * has noticed that the active command on port @ap has not @@ -2161,23 +2138,15 @@ * transaction completed successfully. * * LOCKING: - * Inherited from SCSI layer (none, can sleep) */ -void ata_eng_timeout(struct ata_port *ap) +static void ata_qc_timeout(struct ata_queued_cmd *qc) { - u8 host_stat, drv_stat; - struct ata_queued_cmd *qc; + struct ata_port *ap = qc->ap; + u8 host_stat = 0, drv_stat; DPRINTK("ENTER\n"); - qc = ata_qc_from_tag(ap, ap->active_tag); - if (!qc) { - printk(KERN_ERR "ata%u: BUG: timeout without command\n", - ap->id); - goto out; - } - /* hack alert! We cannot use the supplied completion * function from inside the ->eh_strategy_handler() thread. * libata is the only user of ->eh_strategy_handler() in @@ -2187,38 +2156,69 @@ qc->scsidone = scsi_finish_command; switch (qc->tf.protocol) { + case ATA_PROT_DMA: - if (ap->flags & ATA_FLAG_MMIO) { - void *mmio = (void *) ap->ioaddr.bmdma_addr; - host_stat = readb(mmio + ATA_DMA_STATUS); - } else - host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + case ATA_PROT_ATAPI_DMA: + host_stat = ata_bmdma_status(ap); - printk(KERN_ERR "ata%u: DMA timeout, stat 0x%x\n", - ap->id, host_stat); + /* before we do anything else, clear DMA-Start bit */ + ata_bmdma_stop(ap); - ata_dma_complete(qc, host_stat); - break; + /* fall through */ case ATA_PROT_NODATA: - drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); + default: + ata_altstatus(ap); + drv_stat = ata_chk_status(ap); + + /* ack bmdma irq events */ + ata_bmdma_ack_irq(ap); - printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x\n", - ap->id, qc->tf.command, drv_stat); + printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n", + ap->id, qc->tf.command, drv_stat, host_stat); + /* complete taskfile transaction */ ata_qc_complete(qc, drv_stat); break; + } - default: - drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); + DPRINTK("EXIT\n"); +} - printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", - ap->id, qc->tf.command, drv_stat); +/** + * ata_eng_timeout - Handle timeout of queued command + * @ap: Port on which timed-out command is active + * + * Some part of the kernel (currently, only the SCSI layer) + * has noticed that the active command on port @ap has not + * completed after a specified length of time. Handle this + * condition by disabling DMA (if necessary) and completing + * transactions, with error if necessary. + * + * This also handles the case of the "lost interrupt", where + * for some reason (possibly hardware bug, possibly driver bug) + * an interrupt was not delivered to the driver, even though the + * transaction completed successfully. + * + * LOCKING: + * Inherited from SCSI layer (none, can sleep) + */ - ata_qc_complete(qc, drv_stat); - break; +void ata_eng_timeout(struct ata_port *ap) +{ + struct ata_queued_cmd *qc; + + DPRINTK("ENTER\n"); + + qc = ata_qc_from_tag(ap, ap->active_tag); + if (!qc) { + printk(KERN_ERR "ata%u: BUG: timeout without command\n", + ap->id); + goto out; } + ata_qc_timeout(qc); + out: DPRINTK("EXIT\n"); } @@ -2316,7 +2316,7 @@ qc->scsidone(cmd); } - qc->flags &= ~ATA_QCFLAG_ACTIVE; + qc->flags = 0; tag = qc->tag; if (likely(ata_tag_valid(tag))) { if (tag == ap->active_tag) @@ -2362,10 +2362,10 @@ if (ata_sg_setup_one(qc)) goto err_out; } - - ap->ops->fill_sg(qc); } + ap->ops->qc_prep(qc); + qc->ap->active_tag = qc->tag; qc->flags |= ATA_QCFLAG_ACTIVE; @@ -2446,7 +2446,7 @@ { struct ata_port *ap = qc->ap; unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - u8 host_stat, dmactl; + u8 dmactl; void *mmio = (void *) ap->ioaddr.bmdma_addr; /* load PRD table addr. */ @@ -2460,10 +2460,6 @@ dmactl |= ATA_DMA_WR; writeb(dmactl, mmio + ATA_DMA_CMD); - /* clear interrupt, error bits */ - host_stat = readb(mmio + ATA_DMA_STATUS); - writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, mmio + ATA_DMA_STATUS); - /* issue r/w command */ ap->ops->exec_command(ap, &qc->tf); } @@ -2511,7 +2507,7 @@ { struct ata_port *ap = qc->ap; unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - u8 host_stat, dmactl; + u8 dmactl; /* load PRD table addr. */ outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS); @@ -2523,11 +2519,6 @@ dmactl |= ATA_DMA_WR; outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - /* clear interrupt, error bits */ - host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, - ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - /* issue r/w command */ ap->ops->exec_command(ap, &qc->tf); } @@ -2552,50 +2543,6 @@ } /** - * ata_dma_complete - Complete an active ATA BMDMA command - * @qc: Command to complete - * @host_stat: BMDMA status register contents - * - * LOCKING: - */ - -static void ata_dma_complete(struct ata_queued_cmd *qc, u8 host_stat) -{ - struct ata_port *ap = qc->ap; - VPRINTK("ENTER\n"); - - if (ap->flags & ATA_FLAG_MMIO) { - void *mmio = (void *) ap->ioaddr.bmdma_addr; - - /* clear start/stop bit */ - writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START, - mmio + ATA_DMA_CMD); - - /* ack intr, err bits */ - writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, - mmio + ATA_DMA_STATUS); - } else { - /* clear start/stop bit */ - outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - - /* ack intr, err bits */ - outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, - ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - } - - - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_altstatus(ap); /* dummy read */ - - DPRINTK("host %u, host_stat==0x%X, drv_stat==0x%X\n", - ap->id, (u32) host_stat, (u32) ata_chk_status(ap)); - - /* get drive status; clear intr; complete txn */ - ata_qc_complete(qc, ata_wait_idle(ap)); -} - -/** * ata_host_intr - Handle host interrupt for given (port, task) * @ap: Port on which interrupt arrived (possibly...) * @qc: Taskfile currently active in engine @@ -2615,59 +2562,60 @@ struct ata_queued_cmd *qc) { u8 status, host_stat; - unsigned int handled = 0; switch (qc->tf.protocol) { - /* BMDMA completion */ case ATA_PROT_DMA: case ATA_PROT_ATAPI_DMA: - if (ap->flags & ATA_FLAG_MMIO) { - void *mmio = (void *) ap->ioaddr.bmdma_addr; - host_stat = readb(mmio + ATA_DMA_STATUS); - } else - host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + /* check status of DMA engine */ + host_stat = ata_bmdma_status(ap); VPRINTK("BUS_DMA (host_stat 0x%X)\n", host_stat); - if (!(host_stat & ATA_DMA_INTR)) { - ap->stats.idle_irq++; - break; - } + /* if it's not our irq... */ + if (!(host_stat & ATA_DMA_INTR)) + goto idle_irq; - ata_dma_complete(qc, host_stat); - handled = 1; - break; + /* before we do anything else, clear DMA-Start bit */ + ata_bmdma_stop(ap); + + /* fall through */ - /* command completion, but no data xfer */ - /* FIXME: a shared interrupt _will_ cause a non-data command - * to be completed prematurely, with an error. - * - * This doesn't matter right now, since we aren't sending - * non-data commands down this pipe except in development - * situations. - */ - case ATA_PROT_ATAPI: case ATA_PROT_NODATA: - status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); - DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); + /* check altstatus */ + status = ata_altstatus(ap); + if (status & ATA_BUSY) + goto idle_irq; + + /* check main status, clearing INTRQ */ + status = ata_chk_status(ap); + if (unlikely(status & ATA_BUSY)) + goto idle_irq; + DPRINTK("BUS_NODATA (dev_stat 0x%X)\n", status); + + /* ack bmdma irq events */ + ata_bmdma_ack_irq(ap); + + /* complete taskfile transaction */ ata_qc_complete(qc, status); - handled = 1; break; default: - ap->stats.idle_irq++; + goto idle_irq; + } + + return 1; /* irq handled */ + +idle_irq: + ap->stats.idle_irq++; #ifdef ATA_IRQ_TRAP - if ((ap->stats.idle_irq % 1000) == 0) { - handled = 1; - ata_irq_ack(ap, 0); /* debug trap */ - printk(KERN_WARNING "ata%d: irq trap\n", ap->id); - } -#endif - break; + if ((ap->stats.idle_irq % 1000) == 0) { + handled = 1; + ata_irq_ack(ap, 0); /* debug trap */ + printk(KERN_WARNING "ata%d: irq trap\n", ap->id); } - - return handled; +#endif + return 0; /* irq not handled */ } /** @@ -2701,7 +2649,7 @@ qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.ctl & ATA_NIEN))) - handled += ata_host_intr(ap, qc); + handled |= ata_host_intr(ap, qc); } } @@ -2711,62 +2659,6 @@ } /** - * ata_thread_iter - - * @ap: - * - * LOCKING: - * - * RETURNS: - * - */ - -static unsigned long ata_thread_iter(struct ata_port *ap) -{ - long timeout = 0; - - DPRINTK("ata%u: thr_state %s\n", - ap->id, ata_thr_state_name(ap->thr_state)); - - switch (ap->thr_state) { - case THR_UNKNOWN: - ap->thr_state = THR_PORT_RESET; - break; - - case THR_PROBE_START: - ap->thr_state = THR_PORT_RESET; - break; - - case THR_PORT_RESET: - ata_port_reset(ap); - break; - - case THR_PROBE_SUCCESS: - up(&ap->probe_sem); - ap->thr_state = THR_IDLE; - break; - - case THR_PROBE_FAILED: - up(&ap->probe_sem); - ap->thr_state = THR_AWAIT_DEATH; - break; - - case THR_AWAIT_DEATH: - case THR_IDLE: - timeout = -1; - break; - - default: - printk(KERN_DEBUG "ata%u: unknown thr state %s\n", - ap->id, ata_thr_state_name(ap->thr_state)); - break; - } - - DPRINTK("ata%u: new thr_state %s, returning %ld\n", - ap->id, ata_thr_state_name(ap->thr_state), timeout); - return timeout; -} - -/** * atapi_packet_task - Write CDB bytes to hardware * @_data: Port to which ATAPI device is attached. * @@ -2847,21 +2739,6 @@ pci_free_consistent(pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); } -static void ata_probe_task(void *_data) -{ - struct ata_port *ap = _data; - long timeout; - - timeout = ata_thread_iter(ap); - if (timeout < 0) - return; - - if (timeout > 0) - queue_delayed_work(ata_wq, &ap->probe_task, timeout); - else - queue_work(ata_wq, &ap->probe_task); -} - /** * ata_host_remove - Unregister SCSI host structure with upper layers * @ap: Port to unregister @@ -2918,7 +2795,6 @@ ap->udma_mask = ent->udma_mask; ap->flags |= ent->host_flags; ap->ops = ent->port_ops; - ap->thr_state = THR_PROBE_START; ap->cbl = ATA_CBL_NONE; ap->device[0].flags = ATA_DFLAG_MASTER; ap->active_tag = ATA_TAG_POISON; @@ -2926,13 +2802,10 @@ INIT_WORK(&ap->packet_task, atapi_packet_task, ap); INIT_WORK(&ap->pio_task, ata_pio_task, ap); - INIT_WORK(&ap->probe_task, ata_probe_task, ap); for (i = 0; i < ATA_MAX_DEVICES; i++) ap->device[i].devno = i; - init_MUTEX_LOCKED(&ap->probe_sem); - #ifdef ATA_IRQ_TRAP ap->stats.unhandled_irq = 1; ap->stats.idle_irq = 1; @@ -3041,6 +2914,10 @@ return 0; } + /* TODO: ack irq here, to ensure it won't scream + * when we enable it? + */ + /* obtain irq, that is shared between channels */ if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, DRV_NAME, host_set)) @@ -3055,12 +2932,17 @@ ap = host_set->ports[i]; DPRINTK("ata%u: probe begin\n", ap->id); - queue_work(ata_wq, &ap->probe_task); /* start probe */ - - DPRINTK("ata%u: probe-wait begin\n", ap->id); - down(&ap->probe_sem); /* wait for end */ + rc = ata_bus_probe(ap); + DPRINTK("ata%u: probe end\n", ap->id); - DPRINTK("ata%u: probe-wait end\n", ap->id); + if (rc) { + /* FIXME: do something useful here? + * Current libata behavior will + * tear down everything when + * the module is removed + * or the h/w is unplugged. + */ + } rc = scsi_add_host(ap->host, &pdev->dev); if (rc) { @@ -3480,7 +3362,7 @@ EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_port_stop); EXPORT_SYMBOL_GPL(ata_interrupt); -EXPORT_SYMBOL_GPL(ata_fill_sg); +EXPORT_SYMBOL_GPL(ata_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio); EXPORT_SYMBOL_GPL(ata_bmdma_start_pio); EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio); diff -Nru a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c --- a/drivers/scsi/libata-scsi.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/libata-scsi.c 2004-06-26 17:09:17 -07:00 @@ -182,7 +182,8 @@ * 65534 when Jens Axboe's patch for dynamically * determining max_sectors is merged. */ - if (dev->flags & ATA_DFLAG_LBA48) { + if ((dev->flags & ATA_DFLAG_LBA48) && + ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { sdev->host->max_sectors = 2048; blk_queue_max_sectors(sdev->request_queue, 2048); } diff -Nru a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c --- a/drivers/scsi/mac_esp.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/mac_esp.c 2004-06-26 17:09:18 -07:00 @@ -26,7 +26,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c --- a/drivers/scsi/mac_scsi.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/mac_scsi.c 2004-06-26 17:09:15 -07:00 @@ -52,7 +52,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "mac_scsi.h" #include "NCR5380.h" diff -Nru a/drivers/scsi/mca_53c9x.c b/drivers/scsi/mca_53c9x.c --- a/drivers/scsi/mca_53c9x.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/mca_53c9x.c 2004-06-26 17:09:16 -07:00 @@ -43,7 +43,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/megaraid.c 2004-06-26 17:09:15 -07:00 @@ -49,7 +49,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "megaraid.h" @@ -3815,7 +3815,8 @@ umc = MBOX_P(uiocp); - upthru = (mega_passthru *)umc->xferaddr; + if (get_user(upthru, (mega_passthru **)&umc->xferaddr)) + return (-EFAULT); if( put_user(mc->status, (u8 *)&upthru->scsistatus) ) return (-EFAULT); @@ -3831,7 +3832,8 @@ umc = (megacmd_t *)uioc_mimd->mbox; - upthru = (mega_passthru *)umc->xferaddr; + if (get_user(upthru, (mega_passthru **)&umc->xferaddr)) + return (-EFAULT); if( put_user(mc->status, (u8 *)&upthru->scsistatus) ) return (-EFAULT); @@ -4068,7 +4070,6 @@ static int mega_del_logdrv(adapter_t *adapter, int logdrv) { - DECLARE_WAIT_QUEUE_HEAD(wq); unsigned long flags; scb_t *scb; int rval; @@ -4083,11 +4084,9 @@ * Wait till all the issued commands are complete and there are no * commands in the pending queue */ - while( atomic_read(&adapter->pend_cmds) > 0 || - !list_empty(&adapter->pending_list) ) { - - sleep_on_timeout( &wq, 1*HZ ); /* sleep for 1s */ - } + while (atomic_read(&adapter->pend_cmds) > 0 || + !list_empty(&adapter->pending_list)) + msleep(1000); /* sleep for 1s */ rval = mega_do_del_logdrv(adapter, logdrv); @@ -4610,6 +4609,26 @@ pci_bus = pdev->bus->number; pci_dev_func = pdev->devfn; + + /* + * The megaraid3 stuff reports the ID of the Intel part which is not + * remotely specific to the megaraid + */ + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + u16 magic; + /* + * Don't fall over the Compaq management cards using the same + * PCI identifier + */ + if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ && + pdev->subsystem_device == 0xC000) + return -ENODEV; + /* Now check the magic signature byte */ + pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic); + if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE) + return -ENODEV; + /* Ok it is probably a megaraid */ + } /* * For these vendor and device ids, signature offsets are not diff -Nru a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c --- a/drivers/scsi/mvme147.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/mvme147.c 2004-06-26 17:09:16 -07:00 @@ -11,7 +11,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "wd33c93.h" #include "mvme147.h" diff -Nru a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c --- a/drivers/scsi/mvme16x.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/mvme16x.c 2004-06-26 17:09:20 -07:00 @@ -15,7 +15,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "53c7xx.h" #include "mvme16x.h" diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c --- a/drivers/scsi/ncr53c8xx.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/ncr53c8xx.c 2004-06-26 17:09:16 -07:00 @@ -138,7 +138,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "ncr53c8xx.h" diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c --- a/drivers/scsi/nsp32.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/nsp32.c 2004-06-26 17:09:17 -07:00 @@ -44,7 +44,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c --- a/drivers/scsi/oktagon_esp.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/oktagon_esp.c 2004-06-26 17:09:15 -07:00 @@ -29,7 +29,7 @@ #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c --- a/drivers/scsi/osst.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/osst.c 2004-06-26 17:09:18 -07:00 @@ -61,7 +61,7 @@ #define OSST_DEB_MSG KERN_NOTICE #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c --- a/drivers/scsi/pas16.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/pas16.c 2004-06-26 17:09:15 -07:00 @@ -125,7 +125,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "pas16.h" #define AUTOPROBE_IRQ #include "NCR5380.h" diff -Nru a/drivers/scsi/pc980155.c b/drivers/scsi/pc980155.c --- a/drivers/scsi/pc980155.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,299 +0,0 @@ -/* - * - * drivers/scsi/pc980155.c - * - * PC-9801-55 SCSI host adapter driver - * - * Copyright (C) 1997-2003 Kyoto University Microcomputer Club - * (Linux/98 project) - * Tomoharu Ugawa - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "scsi.h" -#include "hosts.h" -#include "wd33c93.h" -#include "pc980155.h" - -extern int pc98_bios_param(struct scsi_device *, struct block_device *, - sector_t, int *); -static int scsi_pc980155_detect(Scsi_Host_Template *); -static int scsi_pc980155_release(struct Scsi_Host *); - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 16 -#endif - -#undef PC_9801_55_DEBUG -#undef PC_9801_55_DEBUG_VERBOSE - -#define NR_BASE_IOS 4 -static int nr_base_ios = NR_BASE_IOS; -static unsigned int base_ios[NR_BASE_IOS] = {0xcc0, 0xcd0, 0xce0, 0xcf0}; -static wd33c93_regs init_regs; -static int io; - -static struct Scsi_Host *pc980155_host = NULL; - -static void pc980155_intr_handle(int irq, void *dev_id, struct pt_regs *regp); - -static inline void pc980155_dma_enable(unsigned int base_io) -{ - outb(0x01, REG_CWRITE); -} - -static inline void pc980155_dma_disable(unsigned int base_io) -{ - outb(0x02, REG_CWRITE); -} - - -static void pc980155_intr_handle(int irq, void *dev_id, struct pt_regs *regp) -{ - wd33c93_intr(pc980155_host); -} - -static int dma_setup(Scsi_Cmnd *sc, int dir_in) -{ - /* - * sc->SCp.this_residual : transfer count - * sc->SCp.ptr : distination address (virtual address) - * dir_in : data direction (DATA_OUT_DIR:0 or DATA_IN_DIR:1) - * - * if success return 0 - */ - - /* - * DMA WRITE MODE - * bit 7,6 01b single mode (this mode only) - * bit 5 inc/dec (default:0 = inc) - * bit 4 auto initialize (normaly:0 = off) - * bit 3,2 01b memory -> io - * 10b io -> memory - * 00b verify - * bit 1,0 channel - */ - disable_dma(sc->device->host->dma_channel); - set_dma_mode(sc->device->host->dma_channel, - 0x40 | (dir_in ? 0x04 : 0x08)); - clear_dma_ff(sc->device->host->dma_channel); - set_dma_addr(sc->device->host->dma_channel, virt_to_phys(sc->SCp.ptr)); - set_dma_count(sc->device->host->dma_channel, sc->SCp.this_residual); -#ifdef PC_9801_55_DEBUG - printk("D%d(%x)D", sc->device->host->dma_channel, - sc->SCp.this_residual); -#endif - enable_dma(sc->device->host->dma_channel); - pc980155_dma_enable(sc->device->host->io_port); - return 0; -} - -static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *sc, int status) -{ - /* - * instance: Hostadapter's instance - * sc: scsi command - * status: True if success - */ - pc980155_dma_disable(sc->device->host->io_port); - disable_dma(sc->device->host->dma_channel); -} - -/* return non-zero on detection */ -static inline int pc980155_test_port(wd33c93_regs regs) -{ - /* Quick and dirty test for presence of the card. */ - if (inb(regs.SASR) == 0xff) - return 0; - - return 1; -} - -static inline int pc980155_getconfig(unsigned int base_io, wd33c93_regs regs, - unsigned char* irq, unsigned char* dma, - unsigned char* scsi_id) -{ - static unsigned char irqs[] = {3, 5, 6, 9, 12, 13}; - unsigned char result; - - printk(KERN_DEBUG "PC-9801-55: base_io=%x SASR=%x SCMD=%x\n", - base_io, regs.SASR, regs.SCMD); - result = read_pc980155_resetint(regs); - printk(KERN_DEBUG "PC-9801-55: getting config (%x)\n", result); - *scsi_id = result & 0x07; - *irq = (result >> 3) & 0x07; - if (*irq > 5) { - printk(KERN_ERR "PC-9801-55 (base %#x): impossible IRQ (%d)" - " - other device here?\n", base_io, *irq); - return 0; - } - - *irq = irqs[*irq]; - result = inb(REG_STATRD); - *dma = result & 0x03; - if (*dma == 1) { - printk(KERN_ERR - "PC-9801-55 (base %#x): impossible DMA channl (%d)" - " - other device here?\n", base_io, *dma); - return 0; - } -#ifdef PC_9801_55_DEBUG - printk("PC-9801-55: end of getconfig\n"); -#endif - return 1; -} - -/* return non-zero on detection */ -static int scsi_pc980155_detect(Scsi_Host_Template* tpnt) -{ - unsigned int base_io; - unsigned char irq, dma, scsi_id; - int i; -#ifdef PC_9801_55_DEBUG - unsigned char debug; -#endif - - if (io) { - base_ios[0] = io; - nr_base_ios = 1; - } - - for (i = 0; i < nr_base_ios; i++) { - base_io = base_ios[i]; - init_regs.SASR = REG_ADDRST; - init_regs.SCMD = REG_CONTRL; -#ifdef PC_9801_55_DEBUG - printk("PC-9801-55: SASR(%x = %x)\n", SASR, REG_ADDRST); -#endif - if (!request_region(base_io, 6, "PC-9801-55")) - continue; - - if (pc980155_test_port(init_regs) && - pc980155_getconfig(base_io, init_regs, - &irq, &dma, &scsi_id)) - goto found; - - release_region(base_io, 6); - } - - printk("PC-9801-55: not found\n"); - return 0; - - found: -#ifdef PC_9801_55_DEBUG - printk("PC-9801-55: config: base io = %x, irq = %d, dma channel = %d, scsi id = %d\n", base_io, irq, dma, scsi_id); -#endif - if (request_irq(irq, pc980155_intr_handle, 0, "PC-9801-55", NULL)) { - printk(KERN_ERR "PC-9801-55: unable to allocate IRQ %d\n", irq); - goto err1; - } - - if (request_dma(dma, "PC-9801-55")) { - printk(KERN_ERR "PC-9801-55: unable to allocate DMA channel %d\n", dma); - goto err2; - } - - pc980155_host = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); - if (pc980155_host) { - pc980155_host->this_id = scsi_id; - pc980155_host->io_port = base_io; - pc980155_host->n_io_port = 6; - pc980155_host->irq = irq; - pc980155_host->dma_channel = dma; - printk("PC-9801-55: scsi host found at %x irq = %d, use dma channel %d.\n", base_io, irq, dma); - pc980155_int_enable(init_regs); - wd33c93_init(pc980155_host, init_regs, dma_setup, dma_stop, - WD33C93_FS_12_15); - return 1; - } - - printk(KERN_ERR "PC-9801-55: failed to register device\n"); - -err2: - free_irq(irq, NULL); -err1: - release_region(base_io, 6); - return 0; -} - -static int scsi_pc980155_release(struct Scsi_Host *shost) -{ - struct WD33C93_hostdata *hostdata - = (struct WD33C93_hostdata *)shost->hostdata; - - pc980155_int_disable(hostdata->regs); - release_region(shost->io_port, shost->n_io_port); - free_irq(shost->irq, NULL); - free_dma(shost->dma_channel); - wd33c93_release(); - return 1; -} - -static int pc980155_bus_reset(Scsi_Cmnd *cmd) -{ - struct WD33C93_hostdata *hostdata - = (struct WD33C93_hostdata *)cmd->device->host->hostdata; - - pc980155_int_disable(hostdata->regs); - pc980155_assert_bus_reset(hostdata->regs); - udelay(50); - pc980155_negate_bus_reset(hostdata->regs); - (void) inb(hostdata->regs.SASR); - (void) read_pc980155(hostdata->regs, WD_SCSI_STATUS); - pc980155_int_enable(hostdata->regs); - wd33c93_host_reset(cmd); - return SUCCESS; -} - - -#ifndef MODULE -static int __init pc980155_setup(char *str) -{ - int ints[4]; - - str = get_options(str, ARRAY_SIZE(ints), ints); - if (ints[0] > 0) - io = ints[1]; - return 1; -} -__setup("pc980155_io=", pc980155_setup); -#endif - -MODULE_PARM(io, "i"); -MODULE_AUTHOR("Tomoharu Ugawa "); -MODULE_DESCRIPTION("PC-9801-55 SCSI host adapter driver"); -MODULE_LICENSE("GPL"); - -static Scsi_Host_Template driver_template = { - .proc_info = wd33c93_proc_info, - .name = "SCSI PC-9801-55", - .detect = scsi_pc980155_detect, - .release = scsi_pc980155_release, - .queuecommand = wd33c93_queuecommand, - .eh_abort_handler = wd33c93_abort, - .eh_bus_reset_handler = pc980155_bus_reset, - .eh_host_reset_handler = wd33c93_host_reset, - .bios_param = pc98_bios_param, - .can_queue = CAN_QUEUE, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, /* dont use link command */ - .unchecked_isa_dma = 1, /* use dma **XXXX***/ - .use_clustering = ENABLE_CLUSTERING, - .proc_name = "PC_9801_55", -}; - -#include "scsi_module.c" diff -Nru a/drivers/scsi/pc980155.h b/drivers/scsi/pc980155.h --- a/drivers/scsi/pc980155.h 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,52 +0,0 @@ -/* - * - * drivers/scsi/pc980155.h - * - * PC-9801-55 SCSI host adapter driver - * - * Copyright (C) 1997-2003 Kyoto University Microcomputer Club - * (Linux/98 project) - * Tomoharu Ugawa - * - */ - -#ifndef __PC980155_H -#define __PC980155_H - -#include "wd33c93.h" - -#define REG_ADDRST (base_io) -#define REG_CONTRL (base_io + 2) -#define REG_CWRITE (base_io + 4) -#define REG_STATRD (base_io + 4) - -#define WD_MEMORYBANK 0x30 -#define WD_RESETINT 0x33 - -static inline uchar read_pc980155(const wd33c93_regs regs, uchar reg_num) -{ - outb(reg_num, regs.SASR); - return (uchar)inb(regs.SCMD); -} - -static inline void write_memorybank(const wd33c93_regs regs, uchar value) -{ - outb(WD_MEMORYBANK, regs.SASR); - outb(value, regs.SCMD); -} - -#define read_pc980155_resetint(regs) \ - read_pc980155((regs), WD_RESETINT) -#define pc980155_int_enable(regs) \ - write_memorybank((regs), read_pc980155((regs), WD_MEMORYBANK) | 0x04) - -#define pc980155_int_disable(regs) \ - write_memorybank((regs), read_pc980155((regs), WD_MEMORYBANK) & ~0x04) - -#define pc980155_assert_bus_reset(regs) \ - write_memorybank((regs), read_pc980155((regs), WD_MEMORYBANK) | 0x02) - -#define pc980155_negate_bus_reset(regs) \ - write_memorybank((regs), read_pc980155((regs), WD_MEMORYBANK) & ~0x02) - -#endif /* __PC980155_H */ diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c --- a/drivers/scsi/pci2000.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/pci2000.c 2004-06-26 17:09:19 -07:00 @@ -54,7 +54,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "pci2000.h" #include "psi_roy.h" diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c --- a/drivers/scsi/pci2220i.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/pci2220i.c 2004-06-26 17:09:15 -07:00 @@ -59,7 +59,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "pci2220i.h" #include "psi_dale.h" diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c --- a/drivers/scsi/pcmcia/aha152x_stub.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/pcmcia/aha152x_stub.c 2004-06-26 17:09:20 -07:00 @@ -47,7 +47,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "aha152x.h" #include diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c --- a/drivers/scsi/pcmcia/fdomain_stub.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/pcmcia/fdomain_stub.c 2004-06-26 17:09:18 -07:00 @@ -44,7 +44,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c --- a/drivers/scsi/pcmcia/nsp_cs.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/pcmcia/nsp_cs.c 2004-06-26 17:09:21 -07:00 @@ -1936,10 +1936,10 @@ nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); for (dev = host->host_queue; dev != NULL; dev = dev->next) { - unsigned long arg[2], id; - kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); - id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) + - ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000); + unsigned long id; + id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) + + ((dev->channel & 0x0f) << 8) + + ((dev->host->host_no & 0x0f) << 12); node = &info->node[info->ndev]; node->minor = 0; switch (dev->type) { diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c --- a/drivers/scsi/pcmcia/qlogic_stub.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/pcmcia/qlogic_stub.c 2004-06-26 17:09:18 -07:00 @@ -46,7 +46,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "../qlogicfas408.h" #include diff -Nru a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c --- a/drivers/scsi/pluto.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/pluto.c 2004-06-26 17:09:17 -07:00 @@ -21,7 +21,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "../fc4/fcp_impl.h" #include "pluto.h" diff -Nru a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h --- a/drivers/scsi/ppa.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/ppa.h 2004-06-26 17:09:20 -07:00 @@ -86,7 +86,7 @@ #include #include -#include "hosts.h" +#include /* batteries not included :-) */ /* diff -Nru a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c --- a/drivers/scsi/psi240i.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/psi240i.c 2004-06-26 17:09:19 -07:00 @@ -41,7 +41,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "psi240i.h" #include "psi_chip.h" diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c --- a/drivers/scsi/qla1280.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/qla1280.c 2004-06-26 17:09:21 -07:00 @@ -357,7 +357,7 @@ #else #include #include "scsi.h" -#include "hosts.h" +#include #include "sd.h" #endif @@ -3119,6 +3119,7 @@ * Returns: * 0 = success, was able to issue command. */ +#ifdef QLA_64BIT_PTR static int qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) { @@ -3381,9 +3382,8 @@ return status; } +#else /* !QLA_64BIT_PTR */ - -#ifndef QLA_64BIT_PTR /* * qla1280_32bit_start_scsi * The start SCSI is responsible for building request packets on diff -Nru a/drivers/scsi/qla2xxx/qla_os.h b/drivers/scsi/qla2xxx/qla_os.h --- a/drivers/scsi/qla2xxx/qla_os.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/qla2xxx/qla_os.h 2004-06-26 17:09:17 -07:00 @@ -59,7 +59,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c --- a/drivers/scsi/qlogicfas.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/qlogicfas.c 2004-06-26 17:09:21 -07:00 @@ -32,7 +32,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "qlogicfas408.h" /* Set the following to 2 to use normal interrupt (active high/totempole- diff -Nru a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c --- a/drivers/scsi/qlogicfas408.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/qlogicfas408.c 2004-06-26 17:09:17 -07:00 @@ -56,7 +56,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "qlogicfas408.h" /*----------------------------------------------------------------*/ diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c --- a/drivers/scsi/qlogicfc.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/qlogicfc.c 2004-06-26 17:09:19 -07:00 @@ -64,7 +64,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #define pci64_dma_hi32(a) ((u32) (0xffffffff & (((u64)(a))>>32))) #define pci64_dma_lo32(a) ((u32) (0xffffffff & (((u64)(a))))) @@ -100,6 +100,7 @@ #define DEFAULT_LOOP_COUNT 1000000000 +#define ISP_TIMEOUT (2*HZ) /* End Configuration section ************************************************ */ #include @@ -1305,7 +1306,7 @@ cmd->control_flags = cpu_to_le16(CFLAG_READ); if (Cmnd->device->tagged_supported) { - if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * SCSI_TIMEOUT)) { + if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * ISP_TIMEOUT)) { cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG); hostdata->tag_ages[Cmnd->device->id] = jiffies; } else diff -Nru a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c --- a/drivers/scsi/qlogicisp.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/qlogicisp.c 2004-06-26 17:09:21 -07:00 @@ -36,7 +36,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "qlogicisp.h" /* Configuration section *****************************************************/ diff -Nru a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/scsi/sata_nv.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,353 @@ +/* + * sata_nv.c - NVIDIA nForce SATA + * + * Copyright 2004 NVIDIA Corp. All rights reserved. + * Copyright 2004 Andrew Chew + * + * The contents of this file are subject to the Open + * Software License version 1.1 that can be found at + * http://www.opensource.org/licenses/osl-1.1.txt and is included herein + * by reference. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License version 2 (the "GPL") as distributed + * in the kernel source COPYING file, in which case the provisions of + * the GPL are applicable instead of the above. If you wish to allow + * the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under + * the OSL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient may use your + * version of this file under either the OSL or the GPL. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi.h" +#include +#include + +#define DRV_NAME "sata_nv" +#define DRV_VERSION "0.01" + +#define NV_PORTS 2 +#define NV_PIO_MASK 0x1f +#define NV_UDMA_MASK 0x7f +#define NV_PORT0_BMDMA_REG_OFFSET 0x00 +#define NV_PORT1_BMDMA_REG_OFFSET 0x08 +#define NV_PORT0_SCR_REG_OFFSET 0x00 +#define NV_PORT1_SCR_REG_OFFSET 0x40 + +#define NV_INT_STATUS 0x10 +#define NV_INT_STATUS_PDEV_INT 0x01 +#define NV_INT_STATUS_PDEV_PM 0x02 +#define NV_INT_STATUS_PDEV_ADDED 0x04 +#define NV_INT_STATUS_PDEV_REMOVED 0x08 +#define NV_INT_STATUS_SDEV_INT 0x10 +#define NV_INT_STATUS_SDEV_PM 0x20 +#define NV_INT_STATUS_SDEV_ADDED 0x40 +#define NV_INT_STATUS_SDEV_REMOVED 0x80 +#define NV_INT_STATUS_PDEV_HOTPLUG (NV_INT_STATUS_PDEV_ADDED | \ + NV_INT_STATUS_PDEV_REMOVED) +#define NV_INT_STATUS_SDEV_HOTPLUG (NV_INT_STATUS_SDEV_ADDED | \ + NV_INT_STATUS_SDEV_REMOVED) +#define NV_INT_STATUS_HOTPLUG (NV_INT_STATUS_PDEV_HOTPLUG | \ + NV_INT_STATUS_SDEV_HOTPLUG) + +#define NV_INT_ENABLE 0x11 +#define NV_INT_ENABLE_PDEV_MASK 0x01 +#define NV_INT_ENABLE_PDEV_PM 0x02 +#define NV_INT_ENABLE_PDEV_ADDED 0x04 +#define NV_INT_ENABLE_PDEV_REMOVED 0x08 +#define NV_INT_ENABLE_SDEV_MASK 0x10 +#define NV_INT_ENABLE_SDEV_PM 0x20 +#define NV_INT_ENABLE_SDEV_ADDED 0x40 +#define NV_INT_ENABLE_SDEV_REMOVED 0x80 +#define NV_INT_ENABLE_PDEV_HOTPLUG (NV_INT_ENABLE_PDEV_ADDED | \ + NV_INT_ENABLE_PDEV_REMOVED) +#define NV_INT_ENABLE_SDEV_HOTPLUG (NV_INT_ENABLE_SDEV_ADDED | \ + NV_INT_ENABLE_SDEV_REMOVED) +#define NV_INT_ENABLE_HOTPLUG (NV_INT_ENABLE_PDEV_HOTPLUG | \ + NV_INT_ENABLE_SDEV_HOTPLUG) + +#define NV_INT_CONFIG 0x12 +#define NV_INT_CONFIG_METHD 0x01 // 0 = INT, 1 = SMI + +static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); +irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static void nv_host_stop (struct ata_host_set *host_set); + +static struct pci_device_id nv_pci_tbl[] = { + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, + PCI_ANY_ID, PCI_ANY_ID, }, + { 0, } /* terminate list */ +}; + +static struct pci_driver nv_pci_driver = { + .name = DRV_NAME, + .id_table = nv_pci_tbl, + .probe = nv_init_one, + .remove = ata_pci_remove_one, +}; + +static Scsi_Host_Template nv_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = ATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .emulated = ATA_SHT_EMULATED, + .use_clustering = ATA_SHT_USE_CLUSTERING, + .proc_name = DRV_NAME, + .dma_boundary = ATA_DMA_BOUNDARY, + .slave_configure = ata_scsi_slave_config, + .bios_param = ata_std_bios_param, +}; + +static struct ata_port_operations nv_ops = { + .port_disable = ata_port_disable, + .tf_load = ata_tf_load_pio, + .tf_read = ata_tf_read_pio, + .exec_command = ata_exec_command_pio, + .check_status = ata_check_status_pio, + .phy_reset = sata_phy_reset, + .bmdma_setup = ata_bmdma_setup_pio, + .bmdma_start = ata_bmdma_start_pio, + .qc_prep = ata_qc_prep, + .eng_timeout = ata_eng_timeout, + .irq_handler = nv_interrupt, + .scr_read = nv_scr_read, + .scr_write = nv_scr_write, + .port_start = ata_port_start, + .port_stop = ata_port_stop, + .host_stop = nv_host_stop, +}; + +MODULE_AUTHOR("NVIDIA"); +MODULE_DESCRIPTION("low-level driver for NVIDIA nForce SATA controller"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, nv_pci_tbl); + +irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ata_host_set *host_set = dev_instance; + unsigned int i; + unsigned int handled = 0; + unsigned long flags; + u8 intr_status; + u8 intr_enable; + + spin_lock_irqsave(&host_set->lock, flags); + + for (i = 0; i < host_set->n_ports; i++) { + struct ata_port *ap; + + ap = host_set->ports[i]; + if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { + struct ata_queued_cmd *qc; + + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc && (!(qc->tf.ctl & ATA_NIEN))) + handled += ata_host_intr(ap, qc); + } + + intr_status = inb(ap->ioaddr.scr_addr + NV_INT_STATUS); + intr_enable = inb(ap->ioaddr.scr_addr + NV_INT_ENABLE); + + // Clear interrupt status. + outb(0xff, ap->ioaddr.scr_addr + NV_INT_STATUS); + + if (intr_status & NV_INT_STATUS_HOTPLUG) { + if (intr_status & NV_INT_STATUS_PDEV_ADDED) { + printk(KERN_WARNING "ata%u: " + "Primary device added\n", ap->id); + } + + if (intr_status & NV_INT_STATUS_PDEV_REMOVED) { + printk(KERN_WARNING "ata%u: " + "Primary device removed\n", ap->id); + } + + if (intr_status & NV_INT_STATUS_SDEV_ADDED) { + printk(KERN_WARNING "ata%u: " + "Secondary device added\n", ap->id); + } + + if (intr_status & NV_INT_STATUS_SDEV_REMOVED) { + printk(KERN_WARNING "ata%u: " + "Secondary device removed\n", ap->id); + } + } + } + + spin_unlock_irqrestore(&host_set->lock, flags); + + return IRQ_RETVAL(handled); +} + +static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) +{ + if (sc_reg > SCR_CONTROL) + return 0xffffffffU; + + return inl(ap->ioaddr.scr_addr + (sc_reg * 4)); +} + +static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) +{ + if (sc_reg > SCR_CONTROL) + return; + + outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)); +} + +static void nv_host_stop (struct ata_host_set *host_set) +{ + int i; + + for (i=0; in_ports; i++) { + u8 intr_mask; + + // Disable hotplug event interrupts. + intr_mask = inb(host_set->ports[i]->ioaddr.scr_addr + + NV_INT_ENABLE); + intr_mask &= ~(NV_INT_ENABLE_HOTPLUG); + outb(intr_mask, host_set->ports[i]->ioaddr.scr_addr + + NV_INT_ENABLE); + } +} + +static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int printed_version = 0; + struct ata_probe_ent *probe_ent = NULL; + int i; + int rc; + + if (!printed_version++) + printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out; + + rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + goto err_out_regions; + rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + goto err_out_regions; + + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); + if (!probe_ent) { + rc = -ENOMEM; + goto err_out_regions; + } + + memset(probe_ent, 0, sizeof(*probe_ent)); + INIT_LIST_HEAD(&probe_ent->node); + + probe_ent->pdev = pdev; + probe_ent->sht = &nv_sht; + probe_ent->host_flags = ATA_FLAG_SATA | + ATA_FLAG_SATA_RESET | + ATA_FLAG_SRST | + ATA_FLAG_NO_LEGACY; + probe_ent->port_ops = &nv_ops; + probe_ent->n_ports = NV_PORTS; + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = SA_SHIRQ; + probe_ent->pio_mask = NV_PIO_MASK; + probe_ent->udma_mask = NV_UDMA_MASK; + + probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0); + ata_std_ports(&probe_ent->port[0]); + probe_ent->port[0].altstatus_addr = + probe_ent->port[0].ctl_addr = + pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; + probe_ent->port[0].bmdma_addr = + pci_resource_start(pdev, 4) | NV_PORT0_BMDMA_REG_OFFSET; + probe_ent->port[0].scr_addr = + pci_resource_start(pdev, 5) | NV_PORT0_SCR_REG_OFFSET; + + probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2); + ata_std_ports(&probe_ent->port[1]); + probe_ent->port[1].altstatus_addr = + probe_ent->port[1].ctl_addr = + pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; + probe_ent->port[1].bmdma_addr = + pci_resource_start(pdev, 4) | NV_PORT1_BMDMA_REG_OFFSET; + probe_ent->port[1].scr_addr = + pci_resource_start(pdev, 5) | NV_PORT1_SCR_REG_OFFSET; + + pci_set_master(pdev); + + rc = ata_device_add(probe_ent); + if (rc != NV_PORTS) + goto err_out_regions; + + // Enable hotplug event interrupts. + for (i=0; in_ports; i++) { + u8 intr_mask; + + outb(NV_INT_STATUS_HOTPLUG, probe_ent->port[i].scr_addr + + NV_INT_STATUS); + + intr_mask = inb(probe_ent->port[i].scr_addr + NV_INT_ENABLE); + intr_mask |= NV_INT_ENABLE_HOTPLUG; + outb(intr_mask, probe_ent->port[i].scr_addr + NV_INT_ENABLE); + } + + kfree(probe_ent); + + return 0; + +err_out_regions: + pci_release_regions(pdev); + +err_out: + pci_disable_device(pdev); + return rc; +} + +static int __init nv_init(void) +{ + return pci_module_init(&nv_pci_driver); +} + +static void __exit nv_exit(void) +{ + pci_unregister_driver(&nv_pci_driver); +} + +module_init(nv_init); +module_exit(nv_exit); diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c --- a/drivers/scsi/sata_promise.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/sata_promise.c 2004-06-26 17:09:19 -07:00 @@ -81,7 +81,7 @@ static int pdc_port_start(struct ata_port *ap); static void pdc_port_stop(struct ata_port *ap); static void pdc_phy_reset(struct ata_port *ap); -static void pdc_fill_sg(struct ata_queued_cmd *qc); +static void pdc_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf); static inline void pdc_dma_complete (struct ata_port *ap, @@ -114,7 +114,7 @@ .phy_reset = pdc_phy_reset, .bmdma_setup = pdc_dma_setup, .bmdma_start = pdc_dma_start, - .fill_sg = pdc_fill_sg, + .qc_prep = pdc_qc_prep, .eng_timeout = pdc_eng_timeout, .irq_handler = pdc_interrupt, .scr_read = pdc_sata_scr_read, @@ -261,14 +261,14 @@ writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); } -static void pdc_fill_sg(struct ata_queued_cmd *qc) +static void pdc_qc_prep(struct ata_queued_cmd *qc) { struct pdc_port_priv *pp = qc->ap->private_data; unsigned int i; VPRINTK("ENTER\n"); - ata_fill_sg(qc); + ata_qc_prep(qc); i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, qc->dev->devno, pp->pkt); diff -Nru a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c --- a/drivers/scsi/sata_sil.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/sata_sil.c 2004-06-26 17:09:15 -07:00 @@ -131,7 +131,7 @@ .post_set_mode = sil_post_set_mode, .bmdma_setup = ata_bmdma_setup_mmio, .bmdma_start = ata_bmdma_start_mmio, - .fill_sg = ata_fill_sg, + .qc_prep = ata_qc_prep, .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .scr_read = sil_scr_read, @@ -302,6 +302,7 @@ ap->id, dev->devno); ap->host->max_sectors = 15; ap->host->hostt->max_sectors = 15; + dev->flags |= ATA_DFLAG_LOCK_SECTORS; return; } diff -Nru a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c --- a/drivers/scsi/sata_sis.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/sata_sis.c 2004-06-26 17:09:18 -07:00 @@ -100,7 +100,7 @@ .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup_pio, .bmdma_start = ata_bmdma_start_pio, - .fill_sg = ata_fill_sg, + .qc_prep = ata_qc_prep, .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .scr_read = sis_scr_read, diff -Nru a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c --- a/drivers/scsi/sata_svw.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/sata_svw.c 2004-06-26 17:09:18 -07:00 @@ -233,7 +233,7 @@ .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup_mmio, .bmdma_start = ata_bmdma_start_mmio, - .fill_sg = ata_fill_sg, + .qc_prep = ata_qc_prep, .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .scr_read = k2_sata_scr_read, diff -Nru a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c --- a/drivers/scsi/sata_sx4.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/sata_sx4.c 2004-06-26 17:09:15 -07:00 @@ -153,7 +153,7 @@ static void pdc_20621_phy_reset (struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); static void pdc_port_stop(struct ata_port *ap); -static void pdc20621_fill_sg(struct ata_queued_cmd *qc); +static void pdc20621_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf); static void pdc20621_host_stop(struct ata_host_set *host_set); @@ -200,7 +200,7 @@ .phy_reset = pdc_20621_phy_reset, .bmdma_setup = pdc20621_dma_setup, .bmdma_start = pdc20621_dma_start, - .fill_sg = pdc20621_fill_sg, + .qc_prep = pdc20621_qc_prep, .eng_timeout = pdc_eng_timeout, .irq_handler = pdc20621_interrupt, .port_start = pdc_port_start, @@ -434,7 +434,7 @@ buf32[dw + 3]); } -static void pdc20621_fill_sg(struct ata_queued_cmd *qc) +static void pdc20621_qc_prep(struct ata_queued_cmd *qc) { struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; @@ -445,6 +445,9 @@ unsigned int portno = ap->port_no; unsigned int i, last, idx, total_len = 0, sgt_len; u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; + + if (!(qc->flags & ATA_QCFLAG_SG)) + return; VPRINTK("ata%u: ENTER\n", ap->id); diff -Nru a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c --- a/drivers/scsi/sata_via.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/sata_via.c 2004-06-26 17:09:16 -07:00 @@ -108,7 +108,7 @@ .bmdma_setup = ata_bmdma_setup_pio, .bmdma_start = ata_bmdma_start_pio, - .fill_sg = ata_fill_sg, + .qc_prep = ata_qc_prep, .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, diff -Nru a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c --- a/drivers/scsi/sata_vsc.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/sata_vsc.c 2004-06-26 17:09:18 -07:00 @@ -215,7 +215,7 @@ .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup_mmio, .bmdma_start = ata_bmdma_start_mmio, - .fill_sg = ata_fill_sg, + .qc_prep = ata_qc_prep, .eng_timeout = ata_eng_timeout, .irq_handler = vsc_sata_interrupt, .scr_read = vsc_sata_scr_read, diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h --- a/drivers/scsi/scsi.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/scsi.h 2004-06-26 17:09:16 -07:00 @@ -11,6 +11,11 @@ * add scatter-gather, multiple outstanding request, and other * enhancements. */ +/* + * NOTE: this file only contains compatibility glue for old drivers. All + * these wrappers will be removed sooner or later. For new code please use + * the interfaces declared in the headers in include/scsi/ + */ #ifndef _SCSI_H #define _SCSI_H @@ -18,6 +23,7 @@ #include /* for CONFIG_SCSI_LOGGING */ #include +#include #include #include #include @@ -34,12 +40,6 @@ #define FALSE 0 #endif -#ifdef DEBUG -#define SCSI_TIMEOUT (5*HZ) -#else -#define SCSI_TIMEOUT (2*HZ) -#endif - struct Scsi_Host; struct scsi_cmnd; struct scsi_device; @@ -47,21 +47,6 @@ struct scatterlist; /* - * Prototypes for functions in constants.c - * Some of these used to live in constants.h - */ -extern void print_Scsi_Cmnd(struct scsi_cmnd *); -extern void print_command(unsigned char *); -extern void print_sense(const char *, struct scsi_cmnd *); -extern void print_req_sense(const char *, struct scsi_request *); -extern void print_driverbyte(int scsiresult); -extern void print_hostbyte(int scsiresult); -extern void print_status(unsigned char status); -extern int print_msg(const unsigned char *); -extern const char *scsi_sense_key_string(unsigned char); -extern const char *scsi_extd_sense_format(unsigned char, unsigned char); - -/* * Legacy dma direction interfaces. * * This assumes the pci/sbus dma mapping flags have the same numercial @@ -75,6 +60,42 @@ #define scsi_to_pci_dma_dir(scsi_dir) ((int)(scsi_dir)) #define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir)) + +/* + * Old names for debug prettyprinting functions. + */ +static inline void print_Scsi_Cmnd(struct scsi_cmnd *cmd) +{ + return scsi_print_command(cmd); +} +static inline void print_command(unsigned char *cdb) +{ + return __scsi_print_command(cdb); +} +static inline void print_sense(const char *devclass, struct scsi_cmnd *cmd) +{ + return scsi_print_sense(devclass, cmd); +} +static inline void print_req_sense(const char *devclass, struct scsi_request *req) +{ + return scsi_print_req_sense(devclass, req); +} +static inline void print_driverbyte(int scsiresult) +{ + return scsi_print_driverbyte(scsiresult); +} +static inline void print_hostbyte(int scsiresult) +{ + return scsi_print_hostbyte(scsiresult); +} +static inline void print_status(unsigned char status) +{ + return scsi_print_status(status); +} +static inline int print_msg(const unsigned char *msg) +{ + return scsi_print_msg(msg); +} /* * This is the crap from the old error handling code. We have it in a special diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c --- a/drivers/scsi/scsi_debug.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/scsi_debug.c 2004-06-26 17:09:18 -07:00 @@ -1,4 +1,4 @@ -/* +/* * linux/kernel/scsi_debug.c * vvvvvvvvvvvvvvvvvvvvvvv Original vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv * Copyright (C) 1992 Eric Youngdale @@ -7,9 +7,9 @@ * anything out of the ordinary is seen. * ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * - * This version is more generic, simulating a variable number of disk - * (or disk like devices) sharing a common amount of RAM - * + * This version is more generic, simulating a variable number of disk + * (or disk like devices) sharing a common amount of RAM + * * * For documentation see http://www.torque.net/sg/sdebug25.html * @@ -43,7 +43,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include @@ -55,7 +55,8 @@ #include "scsi_logging.h" #include "scsi_debug.h" -static const char * scsi_debug_version_str = "Version: 1.71 (20031007)"; +#define SCSI_DEBUG_VERSION "1.73" +static const char * scsi_debug_version_date = "20040518"; /* Additional Sense Code (ASC) used */ #define NO_ADDED_SENSE 0x0 @@ -76,11 +77,13 @@ /* With these defaults, this driver will make 1 host with 1 target * (id 0) containing 1 logical unit (lun 0). That is 1 device. */ +#define DEF_DELAY 1 #define DEF_DEV_SIZE_MB 8 #define DEF_EVERY_NTH 0 -#define DEF_DELAY 1 -#define DEF_SCSI_LEVEL 3 +#define DEF_NUM_PARTS 0 #define DEF_OPTS 0 +#define DEF_SCSI_LEVEL 3 +#define DEF_PTYPE 0 /* bit mask values for scsi_debug_opts */ #define SCSI_DEBUG_OPT_NOISE 1 @@ -101,19 +104,21 @@ * or "peripheral device" addressing (value 0) */ #define SAM2_LUN_ADDRESS_METHOD 0 +static int scsi_debug_add_host = DEF_NUM_HOST; +static int scsi_debug_delay = DEF_DELAY; static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB; -static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */ -static int scsi_debug_opts = DEF_OPTS; static int scsi_debug_every_nth = DEF_EVERY_NTH; -static int scsi_debug_cmnd_count = 0; -static int scsi_debug_delay = DEF_DELAY; static int scsi_debug_max_luns = DEF_MAX_LUNS; +static int scsi_debug_num_parts = DEF_NUM_PARTS; +static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */ +static int scsi_debug_opts = DEF_OPTS; static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; -static int scsi_debug_add_host = DEF_NUM_HOST; +static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ + +static int scsi_debug_cmnd_count = 0; #define DEV_READONLY(TGT) (0) #define DEV_REMOVEABLE(TGT) (0) -#define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK); static unsigned long sdebug_store_size; /* in bytes */ static sector_t sdebug_capacity; /* in sectors */ @@ -129,6 +134,8 @@ #define SECT_SIZE (1 << POW2_SECT_SIZE) #define SECT_SIZE_PER(TGT) SECT_SIZE +#define SDEBUG_MAX_PARTS 4 + #define SDEBUG_SENSE_LEN 32 struct sdebug_dev_info { @@ -215,7 +222,7 @@ .remove = sdebug_driver_remove, }; -static const int check_condition_result = +static const int check_condition_result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; /* function declarations */ @@ -224,7 +231,7 @@ static int resp_mode_sense(unsigned char * cmd, int target, unsigned char * buff, int bufflen, struct sdebug_dev_info * devip); -static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, +static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, int num, struct sdebug_dev_info * devip); static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, int num, struct sdebug_dev_info * devip); @@ -232,14 +239,15 @@ int bufflen, struct sdebug_dev_info * devip); static void timer_intr_handler(unsigned long); static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); -static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, +static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, int asc, int asq, int inbandLen); -static int check_reset(struct scsi_cmnd * SCpnt, +static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip); -static int schedule_resp(struct scsi_cmnd * cmnd, - struct sdebug_dev_info * devip, +static int schedule_resp(struct scsi_cmnd * cmnd, + struct sdebug_dev_info * devip, done_funct_t done, int scsi_result, int delta_jiff); -static void init_all_queued(void); +static void __init sdebug_build_parts(unsigned char * ramp); +static void __init init_all_queued(void); static void stop_all_queued(void); static int stop_queued_cmnd(struct scsi_cmnd * cmnd); static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, @@ -249,6 +257,8 @@ static int sdebug_add_adapter(void); static void sdebug_remove_adapter(void); +static void sdebug_max_tgts_luns(void); + static struct device pseudo_primary; static struct bus_type pseudo_lld_bus; @@ -257,7 +267,7 @@ if (NULL == sclp) return NULL; else if (sclp->page) - return (unsigned char *)page_address(sclp->page) + + return (unsigned char *)page_address(sclp->page) + sclp->offset; else return NULL; @@ -288,7 +298,7 @@ bufflen = sgpnt[0].length; /* READ and WRITE process scatterlist themselves */ } - else + else buff = (unsigned char *) SCpnt->request_buffer; if (NULL == buff) { buff = spare_buff; /* assume cmd moves no data */ @@ -304,11 +314,11 @@ } if (SCpnt->device->lun >= scsi_debug_max_luns) - return schedule_resp(SCpnt, NULL, done, + return schedule_resp(SCpnt, NULL, done, DID_NO_CONNECT << 16, 0); devip = devInfoReg(SCpnt->device); if (NULL == devip) - return schedule_resp(SCpnt, NULL, done, + return schedule_resp(SCpnt, NULL, done, DID_NO_CONNECT << 16, 0); if ((scsi_debug_every_nth > 0) && @@ -331,7 +341,7 @@ * shouldn't need to call REQUEST_SENSE */ if (devip) { sbuff = devip->sense_buff; - memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ? + memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ? bufflen : SDEBUG_SENSE_LEN); mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0, 7); } else { @@ -392,29 +402,29 @@ break; upper_blk = 0; if ((*cmd) == READ_16) { - upper_blk = cmd[5] + (cmd[4] << 8) + + upper_blk = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); - block = cmd[9] + (cmd[8] << 8) + + block = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); - num = cmd[13] + (cmd[12] << 8) + + num = cmd[13] + (cmd[12] << 8) + (cmd[11] << 16) + (cmd[10] << 24); } else if ((*cmd) == READ_12) { - block = cmd[5] + (cmd[4] << 8) + + block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); - num = cmd[9] + (cmd[8] << 8) + + num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); } else if ((*cmd) == READ_10) { - block = cmd[5] + (cmd[4] << 8) + + block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); num = cmd[8] + (cmd[7] << 8); } else { - block = cmd[3] + (cmd[2] << 8) + + block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16); num = cmd[4]; } errsts = resp_read(SCpnt, upper_blk, block, num, devip); if (inj_recovered && (0 == errsts)) { - mk_sense_buffer(devip, RECOVERED_ERROR, + mk_sense_buffer(devip, RECOVERED_ERROR, THRESHHOLD_EXCEEDED, 0, 18); errsts = check_condition_result; } @@ -430,29 +440,29 @@ break; upper_blk = 0; if ((*cmd) == WRITE_16) { - upper_blk = cmd[5] + (cmd[4] << 8) + + upper_blk = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); - block = cmd[9] + (cmd[8] << 8) + + block = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); - num = cmd[13] + (cmd[12] << 8) + + num = cmd[13] + (cmd[12] << 8) + (cmd[11] << 16) + (cmd[10] << 24); } else if ((*cmd) == WRITE_12) { - block = cmd[5] + (cmd[4] << 8) + + block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); - num = cmd[9] + (cmd[8] << 8) + + num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); } else if ((*cmd) == WRITE_10) { - block = cmd[5] + (cmd[4] << 8) + + block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); num = cmd[8] + (cmd[7] << 8); } else { - block = cmd[3] + (cmd[2] << 8) + + block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16); num = cmd[4]; } errsts = resp_write(SCpnt, upper_blk, block, num, devip); if (inj_recovered && (0 == errsts)) { - mk_sense_buffer(devip, RECOVERED_ERROR, + mk_sense_buffer(devip, RECOVERED_ERROR, THRESHHOLD_EXCEEDED, 0, 18); errsts = check_condition_result; } @@ -474,7 +484,7 @@ return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay); } -static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void *arg) +static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) { if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd); @@ -500,7 +510,7 @@ static const char * product_id = "scsi_debug "; static const char * product_rev = "0004"; -static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, +static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, const char * dev_id_str, int dev_id_str_len) { int num; @@ -537,7 +547,7 @@ { unsigned char pq_pdt; unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; - int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ? + int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ? SDEBUG_MAX_INQ_ARR_SZ : bufflen; if (bufflen < cmd[4]) @@ -545,7 +555,7 @@ "< alloc_length=%d\n", bufflen, (int)cmd[4]); memset(buff, 0, bufflen); memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); - pq_pdt = PERIPH_DEVICE_TYPE(target); + pq_pdt = (scsi_debug_ptype & 0x1f); arr[0] = pq_pdt; if (0x2 & cmd[1]) { /* CMDDT bit set */ mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, @@ -573,11 +583,11 @@ dev_id_str, len); } else { /* Illegal request, invalid field in cdb */ - mk_sense_buffer(devip, ILLEGAL_REQUEST, + mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0, 18); return check_condition_result; } - memcpy(buff, arr, min_len); + memcpy(buff, arr, min_len); return 0; } /* drops through here for a standard inquiry */ @@ -592,11 +602,11 @@ return 0; } -/* <> */ +/* <> */ static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) { /* Read-Write Error Recovery page for mode_sense */ - unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, + unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, 5, 0, 0xff, 0xff}; memcpy(p, err_recov_pg, sizeof(err_recov_pg)); @@ -607,7 +617,7 @@ static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target) { /* Disconnect-Reconnect page for mode_sense */ - unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, + unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(p, disconnect_pg, sizeof(disconnect_pg)); @@ -636,7 +646,7 @@ static int resp_caching_pg(unsigned char * p, int pcontrol, int target) { /* Caching page for mode_sense */ - unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, + unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}; memcpy(p, caching_pg, sizeof(caching_pg)); @@ -678,7 +688,7 @@ int alloc_len, msense_6, offset, len; unsigned char * ap; unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; - int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ? + int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ? SDEBUG_MAX_MSENSE_SZ : bufflen; SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen)); @@ -753,14 +763,14 @@ arr[0] = offset - 1; else { offset -= 2; - arr[0] = (offset >> 8) & 0xff; - arr[1] = offset & 0xff; + arr[0] = (offset >> 8) & 0xff; + arr[1] = offset & 0xff; } memcpy(buff, arr, min_len); return 0; } -static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, +static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, int num, struct sdebug_dev_info * devip) { unsigned char *buff = (unsigned char *) SCpnt->request_buffer; @@ -770,14 +780,14 @@ unsigned long iflags; if (upper_blk || (block + num > sdebug_capacity)) { - mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, + mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 0, 18); return check_condition_result; } if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && - (block <= OPT_MEDIUM_ERR_ADDR) && + (block <= OPT_MEDIUM_ERR_ADDR) && ((block + num) > OPT_MEDIUM_ERR_ADDR)) { - mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, + mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0, 18); /* claim unrecoverable read error */ return check_condition_result; @@ -785,7 +795,7 @@ read_lock_irqsave(&atomic_rw, iflags); sgcount = 0; nbytes = bufflen; - /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n", + /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n", block, bufflen); */ if (SCpnt->use_sg) { sgcount = 0; @@ -857,7 +867,7 @@ static int resp_report_luns(unsigned char * cmd, unsigned char * buff, int bufflen, struct sdebug_dev_info * devip) { - unsigned int alloc_len; + unsigned int alloc_len; int lun_cnt, i, upper; int select_report = (int)cmd[2]; struct scsi_lun *one_lun; @@ -868,19 +878,19 @@ 0, 18); return check_condition_result; } - if (bufflen > 8) { /* can produce response with up to 16k luns + if (bufflen > 8) { /* can produce response with up to 16k luns (lun 0 to lun 16383) */ memset(buff, 0, bufflen); lun_cnt = scsi_debug_max_luns; buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff; buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff; - lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)), + lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)), lun_cnt); one_lun = (struct scsi_lun *) &buff[8]; for (i = 0; i < lun_cnt; i++) { upper = (i >> 8) & 0x3f; if (upper) - one_lun[i].scsi_lun[0] = + one_lun[i].scsi_lun[0] = (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); one_lun[i].scsi_lun[1] = i & 0xff; } @@ -926,7 +936,7 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) { - struct sdebug_dev_info * devip; + struct sdebug_dev_info * devip; if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", @@ -936,14 +946,14 @@ devip = devInfoReg(sdp); sdp->hostdata = devip; if (sdp->host->cmd_per_lun) - scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, + scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, sdp->host->cmd_per_lun); return 0; } static void scsi_debug_slave_destroy(struct scsi_device * sdp) { - struct sdebug_dev_info * devip = + struct sdebug_dev_info * devip = (struct sdebug_dev_info *)sdp->hostdata; if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) @@ -980,6 +990,18 @@ open_devip = devip; } } + if (NULL == open_devip) { /* try and make a new one */ + open_devip = kmalloc(sizeof(*open_devip),GFP_KERNEL); + if (NULL == open_devip) { + printk(KERN_ERR "%s: out of memory at line %d\n", + __FUNCTION__, __LINE__); + return NULL; + } + memset(open_devip, 0, sizeof(*open_devip)); + open_devip->sdbg_host = sdbg_host; + list_add_tail(&open_devip->dev_list, + &sdbg_host->dev_info_list); + } if (open_devip) { open_devip->channel = sdev->channel; open_devip->target = sdev->id; @@ -994,7 +1016,7 @@ return NULL; } -static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, +static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, int asc, int asq, int inbandLen) { unsigned char * sbuff; @@ -1029,7 +1051,7 @@ printk(KERN_INFO "scsi_debug: biosparam\n"); buf = scsi_bios_ptable(bdev); if (buf) { - res = scsi_partsize(buf, capacity, + res = scsi_partsize(buf, capacity, &info[2], &info[0], &info[1]); kfree(buf); if (! res) @@ -1138,7 +1160,7 @@ } /* Initializes timers in queued array */ -static void init_all_queued(void) +static void __init init_all_queued(void) { unsigned long iflags; int k; @@ -1154,11 +1176,61 @@ spin_unlock_irqrestore(&queued_arr_lock, iflags); } -static int schedule_resp(struct scsi_cmnd * cmnd, +static void __init sdebug_build_parts(unsigned char * ramp) +{ + struct partition * pp; + int starts[SDEBUG_MAX_PARTS + 2]; + int sectors_per_part, num_sectors, k; + int heads_by_sects, start_sec, end_sec; + + /* assume partition table already zeroed */ + if ((scsi_debug_num_parts < 1) || (sdebug_store_size < 1048576)) + return; + if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { + scsi_debug_num_parts = SDEBUG_MAX_PARTS; + printk(KERN_WARNING "scsi_debug:build_parts: reducing " + "partitions to %d\n", SDEBUG_MAX_PARTS); + } + num_sectors = (int)(sdebug_store_size / SECT_SIZE); + sectors_per_part = (num_sectors - sdebug_sectors_per) + / scsi_debug_num_parts; + heads_by_sects = sdebug_heads * sdebug_sectors_per; + starts[0] = sdebug_sectors_per; + for (k = 1; k < scsi_debug_num_parts; ++k) + starts[k] = ((k * sectors_per_part) / heads_by_sects) + * heads_by_sects; + starts[scsi_debug_num_parts] = num_sectors; + starts[scsi_debug_num_parts + 1] = 0; + + ramp[510] = 0x55; /* magic partition markings */ + ramp[511] = 0xAA; + pp = (struct partition *)(ramp + 0x1be); + for (k = 0; starts[k + 1]; ++k, ++pp) { + start_sec = starts[k]; + end_sec = starts[k + 1] - 1; + pp->boot_ind = 0; + + pp->cyl = start_sec / heads_by_sects; + pp->head = (start_sec - (pp->cyl * heads_by_sects)) + / sdebug_sectors_per; + pp->sector = (start_sec % sdebug_sectors_per) + 1; + + pp->end_cyl = end_sec / heads_by_sects; + pp->end_head = (end_sec - (pp->end_cyl * heads_by_sects)) + / sdebug_sectors_per; + pp->end_sector = (end_sec % sdebug_sectors_per) + 1; + + pp->start_sect = start_sec; + pp->nr_sects = end_sec - start_sec + 1; + pp->sys_ind = 0x83; /* plain Linux partition */ + } +} + +static int schedule_resp(struct scsi_cmnd * cmnd, struct sdebug_dev_info * devip, done_funct_t done, int scsi_result, int delta_jiff) { - int k, num; + int k, num; if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmnd) { printk(KERN_INFO "scsi_debug: cmd "); @@ -1176,7 +1248,7 @@ if (cmnd && devip) { /* simulate autosense by this driver */ if (SAM_STAT_CHECK_CONDITION == (scsi_result & 0xff)) - memcpy(cmnd->sense_buffer, devip->sense_buff, + memcpy(cmnd->sense_buffer, devip->sense_buff, (SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ? SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE); } @@ -1219,38 +1291,43 @@ /* Set 'perm' (4th argument) to 0 to disable module_param's definition * of sysfs parameters (which module_param doesn't yet support). - * Sysfs parameters defined explicitly below. + * Sysfs parameters defined explicitly below. */ -module_param_named(num_tgts, scsi_debug_num_tgts, int, 0); -module_param_named(max_luns, scsi_debug_max_luns, int, 0); -module_param_named(scsi_level, scsi_debug_scsi_level, int, 0); +module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */ +module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */ module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0); -module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */ module_param_named(every_nth, scsi_debug_every_nth, int, 0); -module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */ -module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */ +module_param_named(max_luns, scsi_debug_max_luns, int, 0); +module_param_named(num_parts, scsi_debug_num_parts, int, 0); +module_param_named(num_tgts, scsi_debug_num_tgts, int, 0); +module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */ +module_param_named(ptype, scsi_debug_ptype, int, 0); +module_param_named(scsi_level, scsi_debug_scsi_level, int, 0); MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); MODULE_DESCRIPTION("SCSI debug adapter driver"); MODULE_LICENSE("GPL"); +MODULE_VERSION(SCSI_DEBUG_VERSION); -MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate"); -MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate"); -MODULE_PARM_DESC(scsi_level, "SCSI level to simulate"); +MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); +MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs"); -MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->..."); MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); -MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); -MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); +MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate"); +MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); +MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate"); +MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->..."); +MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); +MODULE_PARM_DESC(scsi_level, "SCSI level to simulate"); static char sdebug_info[256]; static const char * scsi_debug_info(struct Scsi_Host * shp) { - sprintf(sdebug_info, "scsi_debug, %s, num_tgts=%d, " - "dev_size_mb=%d, opts=0x%x", scsi_debug_version_str, - scsi_debug_num_tgts, scsi_debug_dev_size_mb, + sprintf(sdebug_info, "scsi_debug, version %s [%s], " + "dev_size_mb=%d, opts=0x%x", SCSI_DEBUG_VERSION, + scsi_debug_version_date, scsi_debug_dev_size_mb, scsi_debug_opts); return sdebug_info; } @@ -1282,14 +1359,15 @@ return length; } begin = 0; - pos = len = sprintf(buffer, "scsi_debug adapter driver, %s\n" + pos = len = sprintf(buffer, "scsi_debug adapter driver, version " + "%s [%s]\n" "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, " "every_nth=%d(curr:%d)\n" "delay=%d, max_luns=%d, scsi_level=%d\n" "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n" - "number of aborts=%d, device_reset=%d, bus_resets=%d, " + "number of aborts=%d, device_reset=%d, bus_resets=%d, " "host_resets=%d\n", - scsi_debug_version_str, scsi_debug_num_tgts, + SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts, scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth, scsi_debug_cmnd_count, scsi_debug_delay, scsi_debug_max_luns, scsi_debug_scsi_level, @@ -1306,12 +1384,12 @@ return len; } -static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay); } -static ssize_t sdebug_delay_store(struct device_driver * ddp, +static ssize_t sdebug_delay_store(struct device_driver * ddp, const char * buf, size_t count) { int delay; @@ -1325,15 +1403,15 @@ } return -EINVAL; } -DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show, - sdebug_delay_store) +DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show, + sdebug_delay_store); -static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts); } -static ssize_t sdebug_opts_store(struct device_driver * ddp, +static ssize_t sdebug_opts_store(struct device_driver * ddp, const char * buf, size_t count) { int opts; @@ -1354,38 +1432,62 @@ scsi_debug_cmnd_count = 0; return count; } -DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show, - sdebug_opts_store) +DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show, + sdebug_opts_store); + +static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ptype); +} +static ssize_t sdebug_ptype_store(struct device_driver * ddp, + const char * buf, size_t count) +{ + int n; + + if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { + scsi_debug_ptype = n; + return count; + } + return -EINVAL; +} +DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store); -static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); } -static ssize_t sdebug_num_tgts_store(struct device_driver * ddp, +static ssize_t sdebug_num_tgts_store(struct device_driver * ddp, const char * buf, size_t count) { int n; if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { scsi_debug_num_tgts = n; + sdebug_max_tgts_luns(); return count; } return -EINVAL; } -DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show, - sdebug_num_tgts_store) +DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show, + sdebug_num_tgts_store); -static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dev_size_mb); } -DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL) +DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL); + +static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts); +} +DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL); -static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_every_nth); } -static ssize_t sdebug_every_nth_store(struct device_driver * ddp, +static ssize_t sdebug_every_nth_store(struct device_driver * ddp, const char * buf, size_t count) { int nth; @@ -1398,38 +1500,39 @@ return -EINVAL; } DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show, - sdebug_every_nth_store) + sdebug_every_nth_store); -static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_luns); } -static ssize_t sdebug_max_luns_store(struct device_driver * ddp, +static ssize_t sdebug_max_luns_store(struct device_driver * ddp, const char * buf, size_t count) { int n; if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { scsi_debug_max_luns = n; + sdebug_max_tgts_luns(); return count; } return -EINVAL; } -DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show, - sdebug_max_luns_store) +DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show, + sdebug_max_luns_store); -static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level); } -DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL) +DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); -static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) +static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); } -static ssize_t sdebug_add_host_store(struct device_driver * ddp, +static ssize_t sdebug_add_host_store(struct device_driver * ddp, const char * buf, size_t count) { int delta_hosts; @@ -1459,30 +1562,34 @@ return count; } DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, - sdebug_add_host_store) + sdebug_add_host_store); static void do_create_driverfs_files(void) { + driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); - driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); } static void do_remove_driverfs_files(void) { - driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); + driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts); + driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype); + driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts); + driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); - driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); - driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay); + driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host); } static int __init scsi_debug_init(void) @@ -1491,23 +1598,25 @@ int host_to_add; int k; + if (scsi_debug_dev_size_mb < 1) + scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576; sdebug_capacity = sdebug_store_size / SECT_SIZE; /* play around with geometry, don't waste too much on track 0 */ sdebug_heads = 8; sdebug_sectors_per = 32; - if (scsi_debug_dev_size_mb >= 16) + if (scsi_debug_dev_size_mb >= 16) sdebug_heads = 32; else if (scsi_debug_dev_size_mb >= 256) sdebug_heads = 64; - sdebug_cylinders_per = (unsigned long)sdebug_capacity / + sdebug_cylinders_per = (unsigned long)sdebug_capacity / (sdebug_sectors_per * sdebug_heads); - if (sdebug_cylinders_per >= 1024) { + if (sdebug_cylinders_per >= 1024) { /* other LLDs do this; implies >= 1GB ram disk ... */ sdebug_heads = 255; sdebug_sectors_per = 63; - sdebug_cylinders_per = (unsigned long)sdebug_capacity / + sdebug_cylinders_per = (unsigned long)sdebug_capacity / (sdebug_sectors_per * sdebug_heads); } @@ -1518,6 +1627,8 @@ return -ENOMEM; } memset(fake_storep, 0, sz); + if (scsi_debug_num_parts > 0) + sdebug_build_parts(fake_storep); init_all_queued(); @@ -1575,7 +1686,7 @@ .release = pseudo_0_release, }; -static int pseudo_lld_bus_match(struct device *dev, +static int pseudo_lld_bus_match(struct device *dev, struct device_driver *dev_driver) { return 1; @@ -1736,4 +1847,22 @@ scsi_host_put(sdbg_host->shost); return 0; +} + +static void sdebug_max_tgts_luns(void) +{ + struct sdebug_host_info * sdbg_host; + struct Scsi_Host *hpnt; + + spin_lock(&sdebug_host_list_lock); + list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { + hpnt = sdbg_host->shost; + if ((hpnt->this_id >= 0) && + (scsi_debug_num_tgts > hpnt->this_id)) + hpnt->max_id = scsi_debug_num_tgts + 1; + else + hpnt->max_id = scsi_debug_num_tgts; + hpnt->max_lun = scsi_debug_max_luns; + } + spin_unlock(&sdebug_host_list_lock); } diff -Nru a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h --- a/drivers/scsi/scsi_debug.h 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/scsi_debug.h 2004-06-26 17:09:18 -07:00 @@ -5,9 +5,9 @@ static int scsi_debug_slave_alloc(struct scsi_device *); static int scsi_debug_slave_configure(struct scsi_device *); static void scsi_debug_slave_destroy(struct scsi_device *); -static int scsi_debug_queuecommand(struct scsi_cmnd *, +static int scsi_debug_queuecommand(struct scsi_cmnd *, void (*done) (struct scsi_cmnd *)); -static int scsi_debug_ioctl(struct scsi_device *, int, void *); +static int scsi_debug_ioctl(struct scsi_device *, int, void __user *); static int scsi_debug_biosparam(struct scsi_device *, struct block_device *, sector_t, int[]); static int scsi_debug_abort(struct scsi_cmnd *); @@ -17,9 +17,6 @@ static int scsi_debug_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static const char * scsi_debug_info(struct Scsi_Host *); -/* - * This driver is written for the lk 2.5 series - */ #define SCSI_DEBUG_CANQUEUE 255 /* needs to be >= 1 */ #define SCSI_DEBUG_MAX_CMD_LEN 16 diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c --- a/drivers/scsi/scsi_devinfo.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/scsi_devinfo.c 2004-06-26 17:09:17 -07:00 @@ -9,7 +9,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "scsi_priv.h" /* @@ -27,7 +27,7 @@ static const char spaces[] = " "; /* 16 of them */ static unsigned scsi_default_dev_flags; static LIST_HEAD(scsi_dev_info_list); -static __init char scsi_dev_flags[256]; +static __initdata char scsi_dev_flags[256]; /* * scsi_static_device_list: deprecated list of devices that require @@ -117,8 +117,10 @@ */ {"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN}, {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, - {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_SPARSELUN}, + {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN}, + {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN}, {"CANON", "IPUBJD", NULL, BLIST_SPARSELUN}, + {"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN}, {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ {"CNSI", "G7324", NULL, BLIST_SPARSELUN}, /* Chaparral G7324 RAID */ {"CNSi", "G8324", NULL, BLIST_SPARSELUN}, /* Chaparral G8324 RAID */ @@ -139,6 +141,7 @@ {"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN}, {"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN}, {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN}, {"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN}, {"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN}, {"HITACHI", "DF400", "*", BLIST_SPARSELUN}, @@ -171,6 +174,7 @@ {"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, + {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SGI", "RAID3", "*", BLIST_SPARSELUN}, {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, @@ -182,6 +186,7 @@ {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN}, {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, + {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN}, {"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN}, {"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN}, diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c --- a/drivers/scsi/scsi_error.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/scsi_error.c 2004-06-26 17:09:15 -07:00 @@ -26,25 +26,20 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "scsi_priv.h" #include "scsi_logging.h" -#ifdef DEBUG -#define SENSE_TIMEOUT SCSI_TIMEOUT -#else -#define SENSE_TIMEOUT (10*HZ) -#endif - -#define START_UNIT_TIMEOUT (30*HZ) +#define SENSE_TIMEOUT (10*HZ) +#define START_UNIT_TIMEOUT (30*HZ) /* * These should *probably* be handled by the host itself. * Since it is allowed to sleep, it probably should. */ -#define BUS_RESET_SETTLE_TIME 10*HZ -#define HOST_RESET_SETTLE_TIME 10*HZ +#define BUS_RESET_SETTLE_TIME (10*HZ) +#define HOST_RESET_SETTLE_TIME (10*HZ) /* called with shost->host_lock held */ void scsi_eh_wakeup(struct Scsi_Host *shost) @@ -1026,7 +1021,8 @@ spin_unlock_irqrestore(scmd->device->host->host_lock, flags); if (rtn == SUCCESS) { - scsi_sleep(BUS_RESET_SETTLE_TIME); + if (!scmd->device->host->hostt->skip_settle_delay) + scsi_sleep(BUS_RESET_SETTLE_TIME); spin_lock_irqsave(scmd->device->host->host_lock, flags); scsi_report_bus_reset(scmd->device->host, scmd->device->channel); spin_unlock_irqrestore(scmd->device->host->host_lock, flags); @@ -1057,7 +1053,8 @@ spin_unlock_irqrestore(scmd->device->host->host_lock, flags); if (rtn == SUCCESS) { - scsi_sleep(HOST_RESET_SETTLE_TIME); + if (!scmd->device->host->hostt->skip_settle_delay) + scsi_sleep(HOST_RESET_SETTLE_TIME); spin_lock_irqsave(scmd->device->host->host_lock, flags); scsi_report_bus_reset(scmd->device->host, scmd->device->channel); spin_unlock_irqrestore(scmd->device->host->host_lock, flags); diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c --- a/drivers/scsi/scsi_ioctl.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/scsi_ioctl.c 2004-06-26 17:09:20 -07:00 @@ -20,7 +20,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include "scsi_logging.h" @@ -446,20 +446,4 @@ return sdev->host->hostt->ioctl(sdev, cmd, arg); } return -EINVAL; -} - -/* - * Just like scsi_ioctl, only callable from kernel space with no - * fs segment fiddling. - */ - -int kernel_scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg) -{ - mm_segment_t oldfs; - int tmp; - oldfs = get_fs(); - set_fs(get_ds()); - tmp = scsi_ioctl(sdev, cmd, arg); - set_fs(oldfs); - return tmp; } diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- a/drivers/scsi/scsi_lib.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/scsi_lib.c 2004-06-26 17:09:18 -07:00 @@ -255,7 +255,6 @@ sreq->sr_request->rq_status = RQ_SCSI_BUSY; scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done, timeout, retries); - generic_unplug_device(sreq->sr_device->request_queue); wait_for_completion(&wait); sreq->sr_request->waiting = NULL; if (sreq->sr_request->rq_status != RQ_SCSI_DONE) diff -Nru a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c --- a/drivers/scsi/scsi_module.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/scsi_module.c 2004-06-26 17:09:16 -07:00 @@ -12,7 +12,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include static int __init init_this_scsi_driver(void) diff -Nru a/drivers/scsi/scsi_pc98.c b/drivers/scsi/scsi_pc98.c --- a/drivers/scsi/scsi_pc98.c 2004-06-26 17:09:15 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2003 Osamu Tomita - * - * PC9801 BIOS geometry handling. - */ - -#include -#include -#include -#include -#include -#include - -#include "scsi.h" -#include "hosts.h" - - -static int pc98_first_bios_param(struct scsi_device *sdev, int *ip) -{ - const u8 *p = (&__PC9800SCA(u8, PC9800SCA_SCSI_PARAMS) + sdev->id * 4); - - ip[0] = p[1]; /* # of heads */ - ip[1] = p[0]; /* # of sectors/track */ - ip[2] = *(u16 *)&p[2] & 0x0fff; /* # of cylinders */ - if (p[3] & (1 << 6)) { /* #-of-cylinders is 16-bit */ - ip[2] |= (ip[0] & 0xf0) << 8; - ip[0] &= 0x0f; - } - - return 0; -} - -int pc98_bios_param(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int *ip) -{ - struct Scsi_Host *first_real = first_real_host(); - - /* - * XXX - * XXX This needs to become a sysfs attribute that's set - * XXX by code that knows which host is the first one. - * XXX - * XXX Currently we support only one host on with a - * XXX PC98ish HBA. - * XXX - */ - if (1 || sdev->host == first_real && sdev->id < 7 && - __PC9800SCA_TEST_BIT(PC9800SCA_DISK_EQUIPS, sdev->id)) - return pc98_first_bios_param(sdev, ip); - - /* Assume PC-9801-92 compatible parameters for HAs without BIOS. */ - ip[0] = 8; - ip[1] = 32; - ip[2] = capacity / (8 * 32); - if (ip[2] > 65535) { /* if capacity >= 8GB */ - /* Recent on-board adapters seem to use this parameter. */ - ip[1] = 128; - ip[2] = capacity / (8 * 128); - if (ip[2] > 65535) { /* if capacity >= 32GB */ - /* Clip the number of cylinders. Currently - this is the limit that we deal with. */ - ip[2] = 65535; - } - } - - return 0; -} - -EXPORT_SYMBOL(pc98_bios_param); diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/scsi_scan.c 2004-06-26 17:09:20 -07:00 @@ -45,6 +45,11 @@ " SCSI scanning, some SCSI devices might not be configured\n" /* + * Default timeout + */ +#define SCSI_TIMEOUT (2*HZ) + +/* * Prefix values for the SCSI id's (stored in driverfs name field) */ #define SCSI_UID_SER_NUM 'S' diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c --- a/drivers/scsi/scsi_syms.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/scsi_syms.c 2004-06-26 17:09:18 -07:00 @@ -46,15 +46,14 @@ EXPORT_SYMBOL(scsi_partsize); EXPORT_SYMBOL(scsi_bios_ptable); EXPORT_SYMBOL(scsi_ioctl); -EXPORT_SYMBOL(print_command); -EXPORT_SYMBOL(print_sense); -EXPORT_SYMBOL(print_req_sense); -EXPORT_SYMBOL(print_msg); -EXPORT_SYMBOL(print_status); +EXPORT_SYMBOL(scsi_print_command); +EXPORT_SYMBOL(__scsi_print_command); +EXPORT_SYMBOL(scsi_print_sense); +EXPORT_SYMBOL(scsi_print_req_sense); +EXPORT_SYMBOL(scsi_print_msg); +EXPORT_SYMBOL(scsi_print_status); EXPORT_SYMBOL(scsi_sense_key_string); EXPORT_SYMBOL(scsi_extd_sense_format); -EXPORT_SYMBOL(kernel_scsi_ioctl); -EXPORT_SYMBOL(print_Scsi_Cmnd); EXPORT_SYMBOL(scsi_block_when_processing_errors); EXPORT_SYMBOL(scsi_ioctl_send_command); EXPORT_SYMBOL(scsi_set_medium_removal); diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c --- a/drivers/scsi/scsi_sysfs.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/scsi_sysfs.c 2004-06-26 17:09:16 -07:00 @@ -99,7 +99,7 @@ */ #define shost_rd_attr2(name, field, format_string) \ shost_show_function(name, field, format_string) \ -static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); #define shost_rd_attr(field, format_string) \ shost_rd_attr2(field, field, format_string) @@ -228,8 +228,8 @@ * read only field. */ #define sdev_rd_attr(field, format_string) \ - sdev_show_function(field, format_string) \ -static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL) + sdev_show_function(field, format_string) \ +static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL); /* @@ -247,7 +247,7 @@ snscanf (buf, 20, format_string, &sdev->field); \ return count; \ } \ -static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field) +static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field); /* Currently we don't export bit fields, but we might in future, * so leave this code in */ @@ -272,7 +272,7 @@ } \ return ret; \ } \ -static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field) +static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field); /* * scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1", @@ -320,7 +320,7 @@ sdev->timeout = timeout * HZ; return count; } -static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout) +static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout); static ssize_t store_rescan_field (struct device *dev, const char *buf, size_t count) @@ -328,7 +328,7 @@ scsi_rescan_device(dev); return count; } -static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field) +static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field); static ssize_t sdev_store_delete(struct device *dev, const char *buf, size_t count) diff -Nru a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c --- a/drivers/scsi/scsi_transport_spi.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/scsi_transport_spi.c 2004-06-26 17:09:18 -07:00 @@ -152,7 +152,7 @@ spi_transport_store_function(field, format_string) \ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ show_spi_transport_##field, \ - store_spi_transport_##field) + store_spi_transport_##field); /* The Parallel SCSI Tranport Attributes: */ spi_transport_rd_attr(offset, "%d\n"); @@ -173,7 +173,7 @@ spi_dv_device(sdev); return count; } -static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate) +static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate); /* Translate the period into ns according to the current spec * for SDTR/PPR messages */ @@ -390,10 +390,11 @@ { struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt); struct scsi_device *sdev = sreq->sr_device; - int period, prevperiod = 0; + int period = 0, prevperiod = 0; for (;;) { + int newperiod; if (compare_fn(sreq, buffer, ptr, DV_LOOPS)) /* Successful DV */ break; @@ -401,7 +402,8 @@ /* OK, retrain, fallback */ if (i->f->get_period) i->f->get_period(sdev); - period = spi_period(sdev); + newperiod = spi_period(sdev); + period = newperiod > period ? newperiod : period; if (period < 0x0d) period++; else diff -Nru a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c --- a/drivers/scsi/scsicam.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/scsicam.c 2004-06-26 17:09:18 -07:00 @@ -19,7 +19,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include static int setsize(unsigned long capacity, unsigned int *cyls, unsigned int *hds, diff -Nru a/drivers/scsi/scsiiom.c b/drivers/scsi/scsiiom.c --- a/drivers/scsi/scsiiom.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/scsiiom.c 2004-06-26 17:09:15 -07:00 @@ -12,7 +12,7 @@ pDCB->TagMask &= ~(1 << pSRB->TagNumber); /* free tag mask */ pSRB->TagNumber = 255; } -}; +} static UCHAR @@ -75,7 +75,7 @@ printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->TargetID, pDCB->TargetLUN); return 1; //goto no_tag; - }; + } DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG); pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no; DC390_write8 (ScsiFifo, tag_no); @@ -86,7 +86,7 @@ { // no_tag: DEBUG1(printk (KERN_DEBUG "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed?"":"o"), pSRB->pcmd->pid, pSRB)); - }; + } pSRB->SRBState = SRB_START_; @@ -104,7 +104,7 @@ //pSRB->SRBState = SRB_MSGOUT_; pSRB->SRBState |= DO_SYNC_NEGO; cmd = SEL_W_ATN_STOP; - }; + } /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */ if (cmd != SEL_W_ATN_STOP) @@ -125,7 +125,7 @@ ptr = (PUCHAR) pSRB->pcmd->cmnd; for (i=0; ipcmd->cmd_len; i++) DC390_write8 (ScsiFifo, *(ptr++)); - }; + } } DEBUG0(if (pACB->pActiveDCB) \ printk (KERN_WARNING "DC390: ActiveDCB != 0\n")); @@ -141,7 +141,7 @@ //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); pACB->SelLost++; return 1; - }; + } DC390_write8 (ScsiCmd, cmd); pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB; pACB->Connected = 1; @@ -176,7 +176,7 @@ { printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate); return dstate; - }; + } if (dstate & DMA_XFER_DONE) { UINT residual, xferCnt; int ctr = 6000000; @@ -253,7 +253,7 @@ { DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n")); return IRQ_NONE; - }; + } #else //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT); //dstatus = DC390_read8 (DMA_Status); @@ -313,7 +313,7 @@ { printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n"); goto unlock; - }; + } pSRB = pDCB->pActiveSRB; if( pDCB->DCBFlag & ABORT_DEV_ ) dc390_EnableMsgOut_Abort (pACB, pSRB); @@ -549,7 +549,7 @@ DC390_write8 (CtrlReg3, pDCB->CtrlR3); DC390_write8 (CtrlReg4, pDCB->CtrlR4); dc390_SetXferRate (pACB, pDCB); -}; +} #ifdef DC390_DEBUG0 @@ -561,7 +561,7 @@ for (i = 1; i < len; i++) printk (" %02x", MsgBuf[i]); printk ("\n"); -}; +} #endif #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD) @@ -671,11 +671,11 @@ { printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2); pSRB->MsgInBuf[3] = pDCB->NegoPeriod; - }; + } memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5); pSRB->MsgCnt = 5; DC390_ENABLE_MSGOUT; - }; + } pSRB->SRBState &= ~DO_SYNC_NEGO; pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE; @@ -713,7 +713,7 @@ } dc390_reprog (pACB, pDCB); -}; +} /* handle RESTORE_PTR */ @@ -761,7 +761,7 @@ } pSRB->TotalXferredLen = pSRB->Saved_Ptr; -}; +} /* According to the docs, the AM53C974 reads the message and @@ -789,7 +789,7 @@ /* read and eval received messages */ -void +static void dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) { PDCB pDCB = pACB->pActiveDCB; @@ -832,7 +832,7 @@ dc390_MsgIn_set_async (pACB, pSRB); else dc390_MsgIn_set_sync (pACB, pSRB); - }; + } // nothing has to be done case COMMAND_COMPLETE: break; @@ -948,7 +948,7 @@ dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION); } -void +static void dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) { PDCB pDCB; @@ -989,7 +989,7 @@ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); } -void +static void dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) { UCHAR bval, i, cnt; @@ -1097,7 +1097,7 @@ } -void +static void dc390_Disconnect( PACB pACB ) { PDCB pDCB; @@ -1179,7 +1179,7 @@ } -void +static void dc390_Reselect( PACB pACB ) { PDCB pDCB; @@ -1276,7 +1276,7 @@ DCBDEBUG(printk (KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",\ pDCB->TargetID, pDCB->TargetLUN, (int)pDCB, pDCB->GoingSRBCnt)); return; - }; + } pACB->DCBmap[pDCB->TargetID] &= ~(1 << pDCB->TargetLUN); // The first one @@ -1302,8 +1302,7 @@ if (pDCB == pACB->pDCBRunRobin) pACB->pDCBRunRobin = pDCB->pNextDCB; kfree (pDCB); pACB->DCBCnt--; - /* pACB->DeviceCnt--; */ -}; +} static UCHAR __inline__ @@ -1314,7 +1313,7 @@ if (memcmp (name, dc390_baddevname1[i], 28) == 0) return 1; return 0; -}; +} static void @@ -1336,7 +1335,7 @@ else pDCB->MaxCommand = 1; } -}; +} static void @@ -1346,13 +1345,13 @@ pDCB->DevType = bval1; /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */ dc390_disc_tagq_set (pDCB, ptr); -}; +} -void +static void dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB ) { - UCHAR bval, status, i, DCB_removed; + UCHAR bval, status, i; PSCSICMD pcmd; PSCSI_INQDATA ptr; PSGL ptr2; @@ -1362,11 +1361,10 @@ /* KG: Moved pci_unmap here */ dc390_pci_unmap(pSRB); - DCB_removed = 0; status = pSRB->TargetStatus; ptr = (PSCSI_INQDATA) (pcmd->request_buffer); if( pcmd->use_sg ) - ptr = (PSCSI_INQDATA) sg_dma_address((PSGL) ptr); + ptr = (PSCSI_INQDATA) (page_address(((PSGL) ptr)->page) + ((PSGL) ptr)->offset); DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\ pSRB, pcmd->pid)); @@ -1564,55 +1562,22 @@ pcmd->sense_buffer[2], pcmd->sense_buffer[3]); else printk ("\n"); #endif - if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) || - ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 && - (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR ) - { - /* device not present: remove */ - //dc390_Going_remove (pDCB, pSRB); - dc390_remove_dev (pACB, pDCB); DCB_removed = 1; - - if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && - ((pcmd->device->lun == 0) || (pcmd->device->lun == pACB->pScsiHost->max_lun - 1)) ) - pACB->scan_devices = 0; - } - else - { - /* device present: add */ - if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && - (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) ) - pACB->scan_devices = END_SCAN ; - /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */ - } } } - - //if( pSRB->pcmd->cmnd[0] == INQUIRY && - // (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) ) + if( pcmd->cmnd[0] == INQUIRY && (pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) ) { - if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed) - { - //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun); - /* device not present: remove */ - //dc390_Going_remove (pDCB, pSRB); - dc390_remove_dev (pACB, pDCB); DCB_removed = 1; - } - else + if ((ptr->DevType & SCSI_DEVTYPE) != TYPE_NODEV) { /* device found: add */ dc390_add_dev (pACB, pDCB, ptr); - if (pACB->scan_devices) pACB->DeviceCnt++; } - if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && - (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) ) - pACB->scan_devices = 0; - }; + } pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen; - if (!DCB_removed) dc390_Going_remove (pDCB, pSRB); + dc390_Going_remove (pDCB, pSRB); /* Add to free list */ dc390_Free_insert (pACB, pSRB); @@ -1625,7 +1590,7 @@ /* Remove all SRBs from Going list and inform midlevel */ -void +static void dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd ) { PDCB pDCB, pdcb; @@ -1760,4 +1725,3 @@ if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) ) DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); } - diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c --- a/drivers/scsi/sd.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/sd.c 2004-06-26 17:09:19 -07:00 @@ -52,7 +52,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include @@ -763,11 +763,11 @@ good_bytes = 0; break; - case RECOVERED_ERROR: + case RECOVERED_ERROR: /* an error occurred, but it recovered */ + case NO_SENSE: /* LLDD got sense data */ /* - * An error occurred, but it recovered. Inform the - * user, but make sure that it's not treated as a - * hard error. + * Inform the user, but make sure that it's not treated + * as a hard error. */ print_sense("sd", SCpnt); SCpnt->result = 0; diff -Nru a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c --- a/drivers/scsi/seagate.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/seagate.c 2004-06-26 17:09:17 -07:00 @@ -103,7 +103,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "seagate.h" #include diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c --- a/drivers/scsi/sg.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/sg.c 2004-06-26 17:09:17 -07:00 @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -51,7 +50,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include #include @@ -60,7 +59,7 @@ #ifdef CONFIG_SCSI_PROC_FS #include -static char *sg_version_date = "20040513"; +static char *sg_version_date = "20040516"; static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -73,7 +72,7 @@ #define SG_ALLOW_DIO_DEF 0 #define SG_ALLOW_DIO_CODE /* compile out by commenting this define */ -#define SG_MAX_DEVS 8192 +#define SG_MAX_DEVS 32768 /* * Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d) @@ -718,7 +717,6 @@ (void *) SRpnt->sr_buffer, hp->dxfer_len, sg_cmd_done, timeout, SG_DEFAULT_RETRIES); /* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */ - generic_unplug_device(q); return 0; } @@ -1331,9 +1329,11 @@ void *old_sg_dev_arr = NULL; int k, error; - sdp = vmalloc(sizeof(Sg_device)); - if (!sdp) + sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL); + if (!sdp) { + printk(KERN_WARNING "kmalloc Sg_device failure\n"); return -ENOMEM; + } write_lock_irqsave(&sg_dev_arr_lock, iflags); if (unlikely(sg_nr_dev >= sg_dev_max)) { /* try to resize */ @@ -1341,7 +1341,7 @@ int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP; write_unlock_irqrestore(&sg_dev_arr_lock, iflags); - tmp_da = vmalloc(tmp_dev_max * sizeof(Sg_device *)); + tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL); if (unlikely(!tmp_da)) goto expand_failed; @@ -1375,12 +1375,12 @@ out: if (error < 0) - vfree(sdp); - vfree(old_sg_dev_arr); + kfree(sdp); + kfree(old_sg_dev_arr); return error; expand_failed: - printk(KERN_ERR "sg_alloc: device array cannot be resized\n"); + printk(KERN_WARNING "sg_alloc: device array cannot be resized\n"); error = -ENOMEM; goto out; @@ -1404,20 +1404,26 @@ int error, k; disk = alloc_disk(1); - if (!disk) + if (!disk) { + printk(KERN_WARNING "alloc_disk failed\n"); return -ENOMEM; + } disk->major = SCSI_GENERIC_MAJOR; error = -ENOMEM; cdev = cdev_alloc(); - if (!cdev) + if (!cdev) { + printk(KERN_WARNING "cdev_alloc failed\n"); goto out; + } cdev->owner = THIS_MODULE; cdev->ops = &sg_fops; error = sg_alloc(disk, scsidp); - if (error < 0) + if (error < 0) { + printk(KERN_WARNING "sg_alloc failed\n"); goto out; + } k = error; sdp = sg_dev_arr[k]; @@ -1525,7 +1531,7 @@ put_disk(sdp->disk); sdp->disk = NULL; if (NULL == sdp->headfp) - vfree((char *) sdp); + kfree((char *) sdp); } if (delay) @@ -1590,7 +1596,7 @@ unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), SG_MAX_DEVS); if (sg_dev_arr != NULL) { - vfree((char *) sg_dev_arr); + kfree((char *) sg_dev_arr); sg_dev_arr = NULL; } sg_dev_max = 0; @@ -2492,7 +2498,7 @@ } if (k < maxd) sg_dev_arr[k] = NULL; - vfree((char *) sdp); + kfree((char *) sdp); res = 1; } write_unlock_irqrestore(&sg_dev_arr_lock, iflags); diff -Nru a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c --- a/drivers/scsi/sgiwd93.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/sgiwd93.c 2004-06-26 17:09:20 -07:00 @@ -31,7 +31,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "wd33c93.h" #include "sgiwd93.h" diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c --- a/drivers/scsi/sim710.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/sim710.c 2004-06-26 17:09:20 -07:00 @@ -35,9 +35,8 @@ #include #include #include +#include -#include "scsi.h" -#include "hosts.h" #include "53c700.h" @@ -86,7 +85,7 @@ } __setup("sim710=", param_setup); -static Scsi_Host_Template sim710_driver_template = { +static struct scsi_host_template sim710_driver_template = { .name = "LSI (Symbios) 710 MCA/EISA", .proc_name = "sim710", .this_id = 7, diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c --- a/drivers/scsi/sr.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/sr.c 2004-06-26 17:09:21 -07:00 @@ -47,7 +47,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include /* For the door lock/unlock commands */ @@ -754,12 +754,11 @@ static void get_capabilities(struct scsi_cd *cd) { unsigned char *buffer; - int rc, n, mrw_write = 0, mrw = 1,ram_write=0; struct scsi_mode_data data; struct scsi_request *SRpnt; unsigned char cmd[MAX_COMMAND_SIZE]; unsigned int the_result; - int retries; + int retries, rc, n; static char *loadmech[] = { @@ -830,19 +829,6 @@ printk("%s: scsi-1 drive\n", cd->cdi.name); return; } - - if (cdrom_is_mrw(&cd->cdi, &mrw_write)) { - mrw = 0; - cd->cdi.mask |= CDC_MRW; - cd->cdi.mask |= CDC_MRW_W; - } - if (!mrw_write) - cd->cdi.mask |= CDC_MRW_W; - - if (cdrom_is_random_writable(&cd->cdi, &ram_write)) - cd->cdi.mask |= CDC_RAM; - if (!ram_write) - cd->cdi.mask |= CDC_RAM; n = data.header_length + data.block_descriptor_length; cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176; diff -Nru a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c --- a/drivers/scsi/sr_ioctl.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/sr_ioctl.c 2004-06-26 17:09:19 -07:00 @@ -11,7 +11,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include "sr.h" @@ -330,6 +330,9 @@ struct packet_command cgc; int result; unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); + + if (!buffer) + return -ENOMEM; memset(&cgc, 0, sizeof(struct packet_command)); cgc.timeout = IOCTL_TIMEOUT; diff -Nru a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c --- a/drivers/scsi/sr_vendor.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/sr_vendor.c 2004-06-26 17:09:17 -07:00 @@ -41,7 +41,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c --- a/drivers/scsi/st.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/st.c 2004-06-26 17:09:19 -07:00 @@ -58,7 +58,7 @@ #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c --- a/drivers/scsi/sun3_scsi.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/scsi/sun3_scsi.c 2004-06-26 17:09:15 -07:00 @@ -75,7 +75,7 @@ #define REAL_DMA #include "scsi.h" -#include "hosts.h" +#include #include "sun3_scsi.h" #include "NCR5380.h" diff -Nru a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c --- a/drivers/scsi/sun3_scsi_vme.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/sun3_scsi_vme.c 2004-06-26 17:09:21 -07:00 @@ -41,7 +41,7 @@ #define REAL_DMA #include "scsi.h" -#include "hosts.h" +#include #include "sun3_scsi.h" #include "NCR5380.h" diff -Nru a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c --- a/drivers/scsi/sun3x_esp.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/sun3x_esp.c 2004-06-26 17:09:19 -07:00 @@ -16,7 +16,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "NCR53C9x.h" #include diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c --- a/drivers/scsi/sym53c416.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/scsi/sym53c416.c 2004-06-26 17:09:16 -07:00 @@ -43,7 +43,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include "sym53c416.h" #define VERSION_STRING "Version 1.0.0-ac" @@ -622,12 +622,13 @@ int ints[2]; ints[0] = 1; - for(; *base; base++) - { - if(!check_region(*base, IO_RANGE) && sym53c416_test(*base)) - { - ints[1] = *base; - sym53c416_setup(NULL, ints); + for(; *base; base++) { + if (request_region(*base, IO_RANGE, ID)) { + if (sym53c416_test(*base)) { + ints[1] = *base; + sym53c416_setup(NULL, ints); + } + release_region(*base, IO_RANGE); } } } @@ -702,44 +703,42 @@ sym53c416_probe(); /* Now we register and set up each host adapter found... */ - for(count = 0, i = 0; i < host_index; i++) - { - if(!sym53c416_test(hosts[i].base)) + for(count = 0, i = 0; i < host_index; i++) { + if (!request_region(hosts[i].base, IO_RANGE, ID)) + continue; + if (!sym53c416_test(hosts[i].base)) { printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base); - else - { - if(hosts[i].irq == 0) - /* We don't have an irq yet, so we should probe for one */ - if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0) - printk(KERN_WARNING "IRQ autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base); - if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE)) - { - shpnt = scsi_register(tpnt, 0); - if(shpnt==NULL) - continue; - spin_lock_irqsave(&sym53c416_lock, flags); - /* Request for specified IRQ */ - if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt)) - { - spin_unlock_irqrestore(&sym53c416_lock, flags); - printk(KERN_ERR "sym53c416: Unable to assign IRQ %d\n", hosts[i].irq); - scsi_unregister(shpnt); - } - else - { - /* Inform the kernel of our IO range */ - request_region(hosts[i].base, IO_RANGE, ID); - shpnt->unique_id = hosts[i].base; - shpnt->io_port = hosts[i].base; - shpnt->n_io_port = IO_RANGE; - shpnt->irq = hosts[i].irq; - shpnt->this_id = hosts[i].scsi_id; - sym53c416_init(hosts[i].base, hosts[i].scsi_id); - count++; - spin_unlock_irqrestore(&sym53c416_lock, flags); - } - } + goto fail_release_region; } + + /* We don't have an irq yet, so we should probe for one */ + if (!hosts[i].irq) + hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id); + if (!hosts[i].irq) + goto fail_release_region; + + shpnt = scsi_register(tpnt, 0); + if (!shpnt) + goto fail_release_region; + /* Request for specified IRQ */ + if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt)) + goto fail_free_host; + + spin_lock_irqsave(&sym53c416_lock, flags); + shpnt->unique_id = hosts[i].base; + shpnt->io_port = hosts[i].base; + shpnt->n_io_port = IO_RANGE; + shpnt->irq = hosts[i].irq; + shpnt->this_id = hosts[i].scsi_id; + sym53c416_init(hosts[i].base, hosts[i].scsi_id); + count++; + spin_unlock_irqrestore(&sym53c416_lock, flags); + continue; + + fail_free_host: + scsi_unregister(shpnt); + fail_release_region: + release_region(hosts[i].base, IO_RANGE); } return count; } diff -Nru a/drivers/scsi/t128.c b/drivers/scsi/t128.c --- a/drivers/scsi/t128.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/t128.c 2004-06-26 17:09:20 -07:00 @@ -118,7 +118,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "t128.h" #define AUTOPROBE_IRQ #include "NCR5380.h" diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c --- a/drivers/scsi/tmscsim.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/tmscsim.c 2004-06-26 17:09:21 -07:00 @@ -172,6 +172,11 @@ * 2.1b1 04/01/31 GL (applied 05.04) Remove internal * * command-queuing. * * 2.1b2 04/02/01 CH (applied 05.04) Fix error-handling * + * 2.1c 04/05/23 GL Update to use the new pci_driver API, * + * some scsi EH updates, more cleanup. * + * 2.1d 04/05/27 GL Moved setting of scan_devices to * + * slave_alloc/_configure/_destroy, as * + * suggested by CH. * ***********************************************************************/ /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */ @@ -239,7 +244,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include #include @@ -267,7 +272,6 @@ #include #include -#if defined(MODULE) static struct pci_device_id tmscsim_pci_tbl[] = { { .vendor = PCI_VENDOR_ID_AMD, @@ -278,8 +282,7 @@ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl); -#endif - + #define USE_SPINLOCKS 1 #define DC390_IFLAGS unsigned long iflags @@ -342,6 +345,8 @@ static int DC390_release(struct Scsi_Host *host); static int dc390_shutdown (struct Scsi_Host *host); +static int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start, + off_t offset, int length, int inout); static PACB dc390_pACB_start= NULL; static PACB dc390_pACB_current = NULL; @@ -351,16 +356,14 @@ /* Startup values, to be overriden on the commandline */ static int tmscsim[] = {-2, -2, -2, -2, -2, -2}; +static int tmscsim_paramnum = ARRAY_SIZE(tmscsim); -#if defined(MODULE) -MODULE_PARM(tmscsim, "1-6i"); +module_param_array(tmscsim, int, tmscsim_paramnum, 0); MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)"); MODULE_AUTHOR("C.L. Huang / Kurt Garloff"); MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters"); MODULE_LICENSE("GPL"); - MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); -#endif static PVOID dc390_phase0[]={ dc390_DataOut_0, @@ -913,6 +916,14 @@ } } +static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length) +{ + memset(sg, 0, sizeof(struct scatterlist)); + sg->page = virt_to_page(addr); + sg->length = length; + sg->offset = (unsigned long)addr & ~PAGE_MASK; + return sg; +} /* Create pci mapping */ static int dc390_pci_map (PSRB pSRB) @@ -921,40 +932,43 @@ Scsi_Cmnd *pcmd = pSRB->pcmd; struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev; dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp)); + /* Map sense buffer */ if (pSRB->SRBFlag & AUTO_REQSENSE) { - sg_dma_address(&pSRB->Segmentx) = cmdp->saved_dma_handle = - pci_map_page(pdev, virt_to_page(pcmd->sense_buffer), - (unsigned long)pcmd->sense_buffer & ~PAGE_MASK, sizeof(pcmd->sense_buffer), - DMA_FROM_DEVICE); - sg_dma_len(&pSRB->Segmentx) = sizeof(pcmd->sense_buffer); - pSRB->SGcount = 1; - pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; + pSRB->pSegmentList = dc390_sg_build_single(&pSRB->Segmentx, pcmd->sense_buffer, sizeof(pcmd->sense_buffer)); + pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, 1, + DMA_FROM_DEVICE); + cmdp->saved_dma_handle = sg_dma_address(pSRB->pSegmentList); + + /* TODO: error handling */ + if (pSRB->SGcount != 1) + error = 1; DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle)); - /* Make SG list */ + /* Map SG list */ } else if (pcmd->use_sg) { - pSRB->pSegmentList = (PSGL) pcmd->request_buffer; - pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, - pcmd->use_sg, - scsi_to_pci_dma_dir(pcmd->sc_data_direction)); + pSRB->pSegmentList = (PSGL) pcmd->request_buffer; + pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, pcmd->use_sg, + scsi_to_pci_dma_dir(pcmd->sc_data_direction)); /* TODO: error handling */ if (!pSRB->SGcount) error = 1; - DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n", __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg)); + DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\ + __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg)); /* Map single segment */ } else if (pcmd->request_buffer && pcmd->request_bufflen) { - sg_dma_address(&pSRB->Segmentx) = cmdp->saved_dma_handle = - pci_map_page(pdev, virt_to_page(pcmd->request_buffer), - (unsigned long)pcmd->request_buffer & ~PAGE_MASK, - pcmd->request_bufflen, scsi_to_pci_dma_dir(pcmd->sc_data_direction)); + pSRB->pSegmentList = dc390_sg_build_single(&pSRB->Segmentx, pcmd->request_buffer, pcmd->request_bufflen); + pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, 1, + scsi_to_pci_dma_dir(pcmd->sc_data_direction)); + cmdp->saved_dma_handle = sg_dma_address(pSRB->pSegmentList); + /* TODO: error handling */ - sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen; - pSRB->SGcount = 1; - pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; + if (pSRB->SGcount != 1) + error = 1; DEBUG1(printk("%s(): Mapped request buffer %p at %x\n", __FUNCTION__, pcmd->request_buffer, cmdp->saved_dma_handle)); /* No mapping !? */ } else pSRB->SGcount = 0; + return error; } @@ -963,21 +977,16 @@ { Scsi_Cmnd* pcmd = pSRB->pcmd; struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev; - dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp)); + DEBUG1(dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp))); if (pSRB->SRBFlag) { - pci_unmap_page(pdev, cmdp->saved_dma_handle, - sizeof(pcmd->sense_buffer), DMA_FROM_DEVICE); + pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE); DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle)); } else if (pcmd->use_sg) { - pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, - scsi_to_pci_dma_dir(pcmd->sc_data_direction)); + pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, scsi_to_pci_dma_dir(pcmd->sc_data_direction)); DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", __FUNCTION__, pcmd->request_buffer, pcmd->use_sg)); } else if (pcmd->request_buffer && pcmd->request_bufflen) { - pci_unmap_page(pdev, - cmdp->saved_dma_handle, - pcmd->request_bufflen, - scsi_to_pci_dma_dir(pcmd->sc_data_direction)); + pci_unmap_sg(pdev, &pSRB->Segmentx, 1, scsi_to_pci_dma_dir(pcmd->sc_data_direction)); DEBUG1(printk("%s(): Unmapped request buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle)); } } @@ -1031,15 +1040,15 @@ * 2.0.x: always return 0 * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x * TO BE DONE: - * new model: return 0 if successful - * return 1 if command cannot be queued (queue full) + * new model: return 0 if successful, or must not be re-queued + * return 1 if command cannot be queued (queue full) * command will be inserted in midlevel queue then ... * ***********************************************************************/ static int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { - PDCB pDCB; + PDCB pDCB = (PDCB) cmd->device->hostdata; PSRB pSRB; PACB pACB = (PACB) cmd->device->host->hostdata; @@ -1050,42 +1059,19 @@ /* TODO: Change the policy: Always accept TEST_UNIT_READY or INQUIRY * commands and alloc a DCB for the device if not yet there. DCB will * be removed in dc390_SRBdone if SEL_TIMEOUT */ - - if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) ) - pACB->scan_devices = 0; - - else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) ) - pACB->scan_devices = 0; - - if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) && - !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) ) - { - pACB->scan_devices = 1; - - dc390_initDCB( pACB, &pDCB, cmd->device->id, cmd->device->lun ); - if (!pDCB) - { - printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n", - cmd->device->id, cmd->device->lun); - goto fail; - } - - } - else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) ) - { + if (!(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun))) { printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n", cmd->device->id, cmd->device->lun); goto fail; } - else - { - pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun); - if (!pDCB) - { /* should never happen */ - printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n", - cmd->device->id, cmd->device->lun); - goto fail; - } + + /* Should it be: BUG_ON(!pDCB); ? */ + + if (!pDCB) + { /* should never happen */ + printk (KERN_ERR "DC390: no DCB found, target %02x lun %02x\n", + cmd->device->id, cmd->device->lun); + goto fail; } pACB->Cmds++; @@ -1304,7 +1290,7 @@ static int DC390_abort (Scsi_Cmnd *cmd) { - PDCB pDCB; + PDCB pDCB = (PDCB) cmd->device->hostdata; PSRB pSRB, psrb; UINT count, i; int status; @@ -1314,7 +1300,6 @@ printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n", cmd->pid, cmd->device->id, cmd->device->lun); - pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun); if( !pDCB ) goto NOT_RUN; /* Added 98/07/02 KG */ @@ -1561,15 +1546,16 @@ { PEEprom prom; UCHAR index; - PDCB pDCB, pDCB2; + PDCB pDCB, pDCB2 = 0; pDCB = kmalloc (sizeof(DC390_DCB), GFP_ATOMIC); DCBDEBUG(printk (KERN_INFO "DC390: alloc mem for DCB (ID %i, LUN %i): %p\n", \ id, lun, pDCB)); - + *ppDCB = pDCB; - if (!pDCB) return; - pDCB2 = 0; + if (!pDCB) + return; + if( pACB->DCBCnt == 0 ) { pACB->pLinkDCB = pDCB; @@ -1745,8 +1731,6 @@ pACB->SRBCount = MAX_SRB_CNT; pACB->AdapterIndex = index; pACB->status = 0; - psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID]; - pACB->DeviceCnt = 0; pACB->DCBCnt = 0; pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM]; pACB->ACBFlag = 0; @@ -1856,7 +1840,7 @@ * * Inputs : host - pointer to this host adapter's structure * io_port - IO ports mapped to this adapter - * Irq - IRQ assigned to this adpater + * irq - IRQ assigned to this adpater * struct pci_dev - PCI access handle * index - Adapter index * @@ -1865,10 +1849,8 @@ * Note: written in capitals, because the locking is only done here, * not in DC390_detect, called from outside ***********************************************************************/ - -static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, struct pci_dev *pdev, UCHAR index) +static int __init dc390_init (PSH psh, unsigned long io_port, u8 irq, struct pci_dev *pdev, UCHAR index) { - PSH psh; PACB pACB; if (dc390_CheckEEpromCheckSum (PDEV, index)) @@ -1890,25 +1872,16 @@ dc390_check_for_safe_settings (); dc390_EEprom_Override (index); } - - psh = scsi_register( psht, sizeof(DC390_ACB) ); - if( !psh ) return( -1 ); - - scsi_set_device(psh, &pdev->dev); pACB = (PACB) psh->hostdata; DEBUG0(printk(KERN_INFO "DC390: pSH = %8x, Index %02i\n", (UINT) psh, index)); - dc390_initACB( psh, io_port, Irq, index ); + dc390_initACB( psh, io_port, irq, index ); PDEVSET; - if( !dc390_initAdapter( psh, io_port, Irq, index ) ) + if( !dc390_initAdapter( psh, io_port, irq, index ) ) { - DEBUG0(printk("DC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\ - (UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array)); - DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\ - sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) )); return (0); } else @@ -1927,42 +1900,131 @@ PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)); } -int __init DC390_detect (Scsi_Host_Template *psht) +/** + * dc390_slave_alloc - Called by the scsi mid layer to tell us about a new + * scsi device that we need to deal with. + * + * @scsi_device: The new scsi device that we need to handle. + */ +static int dc390_slave_alloc(struct scsi_device *scsi_device) { - struct pci_dev *pdev = NULL; - UCHAR irq; - ULONG io_port; + PDCB pDCB; + PACB pACB = (PACB) scsi_device->host->hostdata; + dc390_initDCB(pACB, &pDCB, scsi_device->id, scsi_device->lun); + if (pDCB != NULL) { + scsi_device->hostdata = pDCB; + pACB->scan_devices = 1; + return 0; + } + return -ENOMEM; +} - dc390_pACB_start = NULL; +/** + * dc390_slave_destroy - Called by the scsi mid layer to tell us about a + * device that is going away. + * + * @scsi_device: The scsi device that we need to remove. + */ +static void dc390_slave_destroy(struct scsi_device *scsi_device) +{ + PACB pACB = (PACB) scsi_device->host->hostdata; + PDCB pDCB = (PDCB) scsi_device->hostdata; + pACB->scan_devices = 0; + if (pDCB != NULL) + dc390_remove_dev(pACB, pDCB); + else + printk(KERN_ERR"%s() called for non-existing device!\n", __FUNCTION__); +} - if ( PCI_PRESENT ) - while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974, pdev))) - { - if (pci_enable_device (pdev)) - continue; +static int dc390_slave_configure(struct scsi_device *scsi_device) +{ + PACB pACB = (PACB) scsi_device->host->hostdata; + pACB->scan_devices = 0; + return 0; +} - if (pci_set_dma_mask(pdev, 0xffffffff)) { - printk(KERN_ERR "DC390(%i): No suitable DMA available.\n", dc390_adapterCnt); - continue; - } - PCI_GET_IO_AND_IRQ; - DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq)); +static Scsi_Host_Template driver_template = { + .module = THIS_MODULE, + .proc_name = "tmscsim", + .proc_info = DC390_proc_info, + .name = DC390_BANNER " V" DC390_VERSION, + .slave_alloc = dc390_slave_alloc, + .slave_configure = dc390_slave_configure, + .slave_destroy = dc390_slave_destroy, + .queuecommand = DC390_queue_command, + .eh_abort_handler = DC390_abort, + .eh_bus_reset_handler = DC390_reset, + .bios_param = DC390_bios_param, + .can_queue = 42, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 16, + .use_clustering = DISABLE_CLUSTERING, +}; - if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt)) - { - pci_set_master(pdev); - dc390_set_pci_cfg (PDEV); - dc390_adapterCnt++; - } +static int __devinit dc390_init_one(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct Scsi_Host *scsi_host; + unsigned long io_port; + u8 irq; + PACB pACB; + int ret = -ENOMEM; + + if (pci_enable_device(dev)) + return -ENODEV; + + io_port = pci_resource_start(dev, 0); + irq = dev->irq; + + /* allocate scsi host information (includes out adapter) */ + scsi_host = scsi_host_alloc(&driver_template, sizeof(struct _ACB)); + if (!scsi_host) + goto nomem; + + pACB = (PACB) scsi_host->hostdata; + + if (dc390_init(scsi_host, io_port, irq, dev, dc390_adapterCnt)) { + ret = -EBUSY; + goto busy; } - else - printk (KERN_ERR "DC390: No PCI BIOS found!\n"); - - if (dc390_adapterCnt) - psht->proc_name = "tmscsim"; - printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt); - return( dc390_adapterCnt ); + pci_set_master(dev); + dc390_set_pci_cfg(dev); + dc390_adapterCnt++; + + /* get the scsi mid level to scan for new devices on the bus */ + if (scsi_add_host(scsi_host, &dev->dev)) { + ret = -ENODEV; + goto nodev; + } + pci_set_drvdata(dev, scsi_host); + scsi_scan_host(scsi_host); + + return 0; + +nodev: +busy: + scsi_host_put(scsi_host); +nomem: + pci_disable_device(dev); + return ret; +} + +/** + * dc390_remove_one - Called to remove a single instance of the adapter. + * + * @dev: The PCI device to remove. + */ +static void __devexit dc390_remove_one(struct pci_dev *dev) +{ + struct Scsi_Host *scsi_host = pci_get_drvdata(dev); + + scsi_remove_host(scsi_host); + DC390_release(scsi_host); + pci_disable_device(dev); + scsi_host_put(scsi_host); + pci_set_drvdata(dev, NULL); } /******************************************************************** @@ -2035,7 +2097,7 @@ SPRINTF(" Lost arbitrations %i, Sel. connected %i, Connected: %s\n", pACB->SelLost, pACB->SelConn, pACB->Connected? "Yes": "No"); - SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB->DeviceCnt, pACB->DCBCnt); + SPRINTF("Nr of DCBs: %i\n", pACB->DCBCnt); SPRINTF("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n", pACB->DCBmap[0], pACB->DCBmap[1], pACB->DCBmap[2], pACB->DCBmap[3], pACB->DCBmap[4], pACB->DCBmap[5], pACB->DCBmap[6], pACB->DCBmap[7]); @@ -2122,7 +2184,7 @@ static int dc390_shutdown (struct Scsi_Host *host) { UCHAR bval; - PACB pACB = (PACB)(host->hostdata); + PACB pACB = (PACB) host->hostdata; /* pACB->soft_reset(host); */ @@ -2142,7 +2204,7 @@ static void dc390_freeDCBs (struct Scsi_Host *host) { PDCB pDCB, nDCB; - PACB pACB = (PACB)(host->hostdata); + PACB pACB = (PACB) host->hostdata; pDCB = pACB->pLinkDCB; if (!pDCB) return; @@ -2161,7 +2223,7 @@ static int DC390_release (struct Scsi_Host *host) { DC390_IFLAGS; - PACB pACB = (PACB)(host->hostdata); + PACB pACB = (PACB) host->hostdata; DC390_LOCK_IO(host); @@ -2177,24 +2239,25 @@ release_region(host->io_port,host->n_io_port); dc390_freeDCBs (host); DC390_UNLOCK_IO(host); - scsi_unregister(host); return( 1 ); } -static Scsi_Host_Template driver_template = { - .proc_name = "tmscsim", - .proc_info = DC390_proc_info, - .name = DC390_BANNER " V" DC390_VERSION, - .detect = DC390_detect, - .release = DC390_release, - .queuecommand = DC390_queue_command, - .eh_abort_handler = DC390_abort, - .eh_bus_reset_handler = DC390_reset, - .bios_param = DC390_bios_param, - .can_queue = 42, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = 16, - .use_clustering = DISABLE_CLUSTERING, +static struct pci_driver dc390_driver = { + .name = "tmscsim", + .id_table = tmscsim_pci_tbl, + .probe = dc390_init_one, + .remove = __devexit_p(dc390_remove_one), }; -#include "scsi_module.c" + +static int __init dc390_module_init(void) +{ + return pci_module_init(&dc390_driver); +} + +static void __exit dc390_module_exit(void) +{ + pci_unregister_driver(&dc390_driver); +} + +module_init(dc390_module_init); +module_exit(dc390_module_exit); diff -Nru a/drivers/scsi/tmscsim.h b/drivers/scsi/tmscsim.h --- a/drivers/scsi/tmscsim.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/scsi/tmscsim.h 2004-06-26 17:09:20 -07:00 @@ -22,8 +22,6 @@ #define SEL_TIMEOUT 153 /* 250 ms selection timeout (@ 40 MHz) */ -#define END_SCAN 2 - #define pci_dma_lo32(a) (a & 0xffffffff) typedef u8 UCHAR; /* 8 bits */ @@ -196,10 +194,8 @@ UCHAR SRBCount; UCHAR AdapterIndex; /*; nth Adapter this driver */ -UCHAR DeviceCnt; UCHAR DCBCnt; -/* 0x10: */ UCHAR TagMaxNum; UCHAR ACBFlag; UCHAR Gmode2; @@ -213,13 +209,11 @@ PSRB pFreeSRB; PSRB pTmpSRB; -/* 0x2c: */ UCHAR msgin123[4]; UCHAR DCBmap[MAX_SCSI_ID]; UCHAR Connected; UCHAR pad; -/* 0x30: */ #if defined(USE_SPINLOCKS) && USE_SPINLOCKS > 1 && (defined(CONFIG_SMP) || DEBUG_SPINLOCKS > 0) spinlock_t lock; #endif @@ -230,20 +224,17 @@ UCHAR Ignore_IRQ; /* Not used */ PDEVDECL1; /* Pointer to PCI cfg. space */ -/* 0x40/0x3c: */ + ULONG Cmds; UINT SelLost; UINT SelConn; UINT CmdInQ; UINT CmdOutOfSRB; -/* 0x54/0x50: */ struct timer_list Waiting_Timer; -/* 0x68/0x64: */ + DC390_SRB TmpSRB; -/* 0xcc/0xc8: */ DC390_SRB SRB_array[MAX_SRB_CNT]; /* 50 SRBs */ -/* 0xfa4/0xfa0: */ }; typedef struct _ACB DC390_ACB, *PACB; diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c --- a/drivers/scsi/u14-34f.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/scsi/u14-34f.c 2004-06-26 17:09:17 -07:00 @@ -423,7 +423,7 @@ #include #include #include "scsi.h" -#include "hosts.h" +#include #include #include diff -Nru a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c --- a/drivers/scsi/ultrastor.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/scsi/ultrastor.c 2004-06-26 17:09:18 -07:00 @@ -145,7 +145,7 @@ #define ULTRASTOR_PRIVATE /* Get the private stuff from ultrastor.h */ #include "scsi.h" -#include "hosts.h" +#include #include "ultrastor.h" #define FALSE 0 diff -Nru a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c --- a/drivers/scsi/wd33c93.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/wd33c93.c 2004-06-26 17:09:19 -07:00 @@ -83,7 +83,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include "wd33c93.h" diff -Nru a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c --- a/drivers/scsi/wd7000.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/scsi/wd7000.c 2004-06-26 17:09:21 -07:00 @@ -184,7 +184,7 @@ #include #include "scsi.h" -#include "hosts.h" +#include #include @@ -1605,6 +1605,7 @@ return 0; } +#if 0 /* * I have absolutely NO idea how to do an abort with the WD7000... */ @@ -1619,7 +1620,7 @@ } return FAILED; } - +#endif /* * I also have no idea how to do a reset... diff -Nru a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c --- a/drivers/scsi/zalon.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/scsi/zalon.c 2004-06-26 17:09:19 -07:00 @@ -24,7 +24,7 @@ #include "../parisc/gsc.h" #include "scsi.h" -#include "hosts.h" +#include #include "ncr53c8xx.h" diff -Nru a/drivers/serial/8250_acpi.c b/drivers/serial/8250_acpi.c --- a/drivers/serial/8250_acpi.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/serial/8250_acpi.c 2004-06-26 17:09:21 -07:00 @@ -57,28 +57,18 @@ static acpi_status acpi_serial_ext_irq(struct serial_struct *req, struct acpi_resource_ext_irq *ext_irq) { - if (ext_irq->number_of_interrupts > 0) { -#ifdef CONFIG_IA64 - req->irq = acpi_register_irq(ext_irq->interrupts[0], - ext_irq->active_high_low, ext_irq->edge_level); -#else - req->irq = ext_irq->interrupts[0]; -#endif - } + if (ext_irq->number_of_interrupts > 0) + req->irq = acpi_register_gsi(ext_irq->interrupts[0], + ext_irq->edge_level, ext_irq->active_high_low); return AE_OK; } static acpi_status acpi_serial_irq(struct serial_struct *req, struct acpi_resource_irq *irq) { - if (irq->number_of_interrupts > 0) { -#ifdef CONFIG_IA64 - req->irq = acpi_register_irq(irq->interrupts[0], - irq->active_high_low, irq->edge_level); -#else - req->irq = irq->interrupts[0]; -#endif - } + if (irq->number_of_interrupts > 0) + req->irq = acpi_register_gsi(irq->interrupts[0], + irq->edge_level, irq->active_high_low); return AE_OK; } diff -Nru a/drivers/serial/8250_hcdp.c b/drivers/serial/8250_hcdp.c --- a/drivers/serial/8250_hcdp.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/serial/8250_hcdp.c 2004-06-26 17:09:20 -07:00 @@ -183,16 +183,12 @@ } if (HCDP_IRQ_SUPPORTED(hcdp_dev)) { -#ifdef CONFIG_IA64 if (HCDP_PCI_UART(hcdp_dev)) - port.irq = acpi_register_irq(gsi, - ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE); + port.irq = acpi_register_gsi(gsi, + ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); else - port.irq = acpi_register_irq(gsi, - ACPI_ACTIVE_HIGH, ACPI_EDGE_SENSITIVE); -#else - port.irq = gsi; -#endif + port.irq = acpi_register_gsi(gsi, + ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH); port.flags |= UPF_AUTO_IRQ; if (HCDP_PCI_UART(hcdp_dev)) diff -Nru a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c --- a/drivers/serial/8250_pnp.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/serial/8250_pnp.c 2004-06-26 17:09:15 -07:00 @@ -361,9 +361,6 @@ ((port->min == 0x2f8) || (port->min == 0x3f8) || (port->min == 0x2e8) || -#ifdef CONFIG_X86_PC9800 - (port->min == 0x8b0) || -#endif (port->min == 0x3e8))) return 1; } diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig --- a/drivers/serial/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/serial/Kconfig 2004-06-26 17:09:20 -07:00 @@ -518,19 +518,6 @@ depends on V850E_UART select SERIAL_CORE_CONSOLE -config SERIAL98 - tristate "PC-9800 8251-based primary serial port support" - depends on X86_PC9800 - select SERIAL_CORE - help - If you want to use standard primary serial ports on PC-9800, - say Y. Otherwise, say N. - -config SERIAL98_CONSOLE - bool "Support for console on PC-9800 standard serial port" - depends on SERIAL98=y - select SERIAL_CORE_CONSOLE - config SERIAL_SH_SCI tristate "SH SCI(F) serial port support" depends on SUPERH || H8300 @@ -615,6 +602,89 @@ If you would like to be able to use the z85c30 serial port on your PowerMac as the console, you can do so by answering Y to this option. + +config SERIAL_LH7A40X + tristate "Sharp LH7A40X embedded UART support" + depends on ARM && ARCH_LH7A40X + select SERIAL_CORE + help + This enables support for the three on-board UARTs of the + Sharp LH7A40X series CPUs. Choose Y or M. + +config SERIAL_LH7A40X_CONSOLE + bool "Support for connsole on Sharp LH7A40X serial port" + depends on SERIAL_LH7A40X=y + select SERIAL_CORE_CONSOLE + help + Say Y here if you wish to use one of the serial ports as the + system console--the system console is the device which + receives all kernel messages and warnings and which allows + logins in single user mode. + + Even if you say Y here, the currently visible framebuffer console + (/dev/tty0) will still be used as the default system console, but + you can alter that using a kernel command line, for example + "console=ttyAM1". + +config SERIAL_CPM + tristate "CPM2 SCC/SMC serial port support" + depends on CPM2 || 8xx + select SERIAL_CORE + help + This driver supports the SCC and SMC serial ports on Motorola + embedded PowerPC that contain a CPM2 (8xxx) or a CPM1 (8xx) + +config SERIAL_CPM_CONSOLE + bool "Support for console on CPM2 SCC/SMC serial port" + depends on SERIAL_CPM=y + select SERIAL_CORE_CONSOLE + help + Say Y here if you wish to use a SCC or SMC CPM UART as the system + console (the system console is the device which receives all kernel + messages and warnings and which allows logins in single user mode). + + Even if you say Y here, the currently visible framebuffer console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttyCPM0". (Try "man bootparam" or see the documentation of + your boot loader (lilo or loadlin) about how to pass options to the + kernel at boot time.) + +config SERIAL_CPM_SCC1 + bool "Support for SCC1 serial port" + depends on SERIAL_CPM=y + help + Select the is option to use SCC1 as a serial port + +config SERIAL_CPM_SCC2 + bool "Support for SCC2 serial port" + depends on SERIAL_CPM=y + help + Select the is option to use SCC2 as a serial port + +config SERIAL_CPM_SCC3 + bool "Support for SCC3 serial port" + depends on SERIAL_CPM=y + help + Select the is option to use SCC3 as a serial port + +config SERIAL_CPM_SCC4 + bool "Support for SCC4 serial port" + depends on SERIAL_CPM=y + help + Select the is option to use SCC4 as a serial port + +config SERIAL_CPM_SMC1 + bool "Support for SMC1 serial port" + depends on SERIAL_CPM=y + help + Select the is option to use SMC1 as a serial port + +config SERIAL_CPM_SMC2 + bool "Support for SMC2 serial port" + depends on SERIAL_CPM=y + help + Select the is option to use SMC2 as a serial port endmenu diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile --- a/drivers/serial/Makefile 2004-06-26 17:09:18 -07:00 +++ b/drivers/serial/Makefile 2004-06-26 17:09:18 -07:00 @@ -33,9 +33,10 @@ obj-$(CONFIG_SERIAL_68360) += 68360serial.o obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o obj-$(CONFIG_V850E_UART) += v850e_uart.o -obj-$(CONFIG_SERIAL98) += serial98.o obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o +obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o obj-$(CONFIG_SERIAL_DZ) += dz.o obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o obj-$(CONFIG_SERIAL_BAST_SIO) += bast_sio.o +obj-$(CONFIG_SERIAL_CPM) += cpm_uart/ diff -Nru a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c --- a/drivers/serial/amba-pl011.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/serial/amba-pl011.c 2004-06-26 17:09:21 -07:00 @@ -44,6 +44,7 @@ #include #include #include +#include #if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ @@ -68,6 +69,7 @@ */ struct uart_amba_port { struct uart_port port; + struct clk *clk; unsigned int im; /* interrupt mask */ unsigned int old_status; }; @@ -352,11 +354,20 @@ int retval; /* + * Try to enable the clock producer. + */ + retval = clk_enable(uap->clk); + if (retval) + goto out; + + uap->port.uartclk = clk_get_rate(uap->clk); + + /* * Allocate the IRQ */ retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); if (retval) - goto out; + goto clk_dis; writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, uap->port.membase + UART011_IFLS); @@ -391,6 +402,8 @@ return 0; + clk_dis: + clk_disable(uap->clk); out: return retval; } @@ -425,6 +438,11 @@ val = readw(uap->port.membase + UART011_LCRH); val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); writew(val, uap->port.membase + UART011_LCRH); + + /* + * Shut down the clock producer + */ + clk_disable(uap->clk); } static void @@ -594,38 +612,40 @@ #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE static inline void -pl011_console_write_char(struct uart_port *port, char ch) +pl011_console_write_char(struct uart_amba_port *uap, char ch) { unsigned int status; do { - status = readw(port->membase + UART01x_FR); + status = readw(uap->port.membase + UART01x_FR); } while (status & UART01x_FR_TXFF); - writew(ch, port->membase + UART01x_DR); + writew(ch, uap->port.membase + UART01x_DR); } static void pl011_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_port *port = &amba_ports[co->index]->port; + struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; int i; + clk_enable(uap->clk); + /* * First save the CR then disable the interrupts */ - old_cr = readw(port->membase + UART011_CR); + old_cr = readw(uap->port.membase + UART011_CR); new_cr = old_cr & ~UART011_CR_CTSEN; new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - writew(new_cr, port->membase + UART011_CR); + writew(new_cr, uap->port.membase + UART011_CR); /* * Now, do each character */ for (i = 0; i < count; i++) { - pl011_console_write_char(port, s[i]); + pl011_console_write_char(uap, s[i]); if (s[i] == '\n') - pl011_console_write_char(port, '\r'); + pl011_console_write_char(uap, '\r'); } /* @@ -633,19 +653,21 @@ * and restore the TCR */ do { - status = readw(port->membase + UART01x_FR); + status = readw(uap->port.membase + UART01x_FR); } while (status & UART01x_FR_BUSY); - writew(old_cr, port->membase + UART011_CR); + writew(old_cr, uap->port.membase + UART011_CR); + + clk_disable(uap->clk); } static void __init -pl011_console_get_options(struct uart_port *port, int *baud, +pl011_console_get_options(struct uart_amba_port *uap, int *baud, int *parity, int *bits) { - if (readw(port->membase + UART011_CR) & UART01x_CR_UARTEN) { + if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { unsigned int lcr_h, ibrd, fbrd; - lcr_h = readw(port->membase + UART011_LCRH); + lcr_h = readw(uap->port.membase + UART011_LCRH); *parity = 'n'; if (lcr_h & UART01x_LCRH_PEN) { @@ -660,10 +682,10 @@ else *bits = 8; - ibrd = readw(port->membase + UART011_IBRD); - fbrd = readw(port->membase + UART011_FBRD); + ibrd = readw(uap->port.membase + UART011_IBRD); + fbrd = readw(uap->port.membase + UART011_FBRD); - *baud = port->uartclk * 4 / (64 * ibrd + fbrd); + *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); } } @@ -685,10 +707,12 @@ co->index = 0; uap = amba_ports[co->index]; + uap->port.uartclk = clk_get_rate(uap->clk); + if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else - pl011_console_get_options(&uap->port, &baud, &parity, &bits); + pl011_console_get_options(uap, &baud, &parity, &bits); return uart_set_options(&uap->port, co, baud, parity, bits, flow); } @@ -747,16 +771,21 @@ } memset(uap, 0, sizeof(struct uart_amba_port)); + uap->clk = clk_get(&dev->dev, "UARTCLK"); + if (IS_ERR(uap->clk)) { + ret = PTR_ERR(uap->clk); + goto unmap; + } + + ret = clk_use(uap->clk); + if (ret) + goto putclk; + uap->port.dev = &dev->dev; uap->port.mapbase = dev->res.start; uap->port.membase = base; uap->port.iotype = UPIO_MEM; uap->port.irq = dev->irq[0]; -#if 0 /* FIXME */ - uap->port.uartclk = 14745600; -#else - uap->port.uartclk = 24000000; -#endif uap->port.fifosize = 16; uap->port.ops = &amba_pl011_pops; uap->port.flags = UPF_BOOT_AUTOCONF; @@ -769,6 +798,10 @@ if (ret) { amba_set_drvdata(dev, NULL); amba_ports[i] = NULL; + clk_unuse(uap->clk); + putclk: + clk_put(uap->clk); + unmap: iounmap(base); free: kfree(uap); @@ -791,6 +824,8 @@ amba_ports[i] = NULL; iounmap(uap->port.membase); + clk_unuse(uap->clk); + clk_put(uap->clk); kfree(uap); return 0; } diff -Nru a/drivers/serial/cpm_uart/Makefile b/drivers/serial/cpm_uart/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/cpm_uart/Makefile 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,11 @@ +# +# Makefile for the Motorola 8xx FEC ethernet controller +# + +obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o + +# Select the correct platform objects. +cpm_uart-objs-$(CONFIG_CPM2) += cpm_uart_cpm2.o +cpm_uart-objs-$(CONFIG_8xx) += cpm_uart_cpm1.o + +cpm_uart-objs := cpm_uart_core.o $(cpm_uart-objs-y) diff -Nru a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/cpm_uart/cpm_uart.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,92 @@ +/* + * linux/drivers/serial/cpm_uart.h + * + * Driver for CPM (SCC/SMC) serial ports + * + * Copyright (C) 2004 Freescale Semiconductor, Inc. + * + */ +#ifndef CPM_UART_H +#define CPM_UART_H + +#include + +#if defined(CONFIG_CPM2) +#include "cpm_uart_cpm2.h" +#elif defined(CONFIG_8xx) +#include "cpm_uart_cpm1.h" +#endif + +#ifndef CONFIG_SERIAL_8250 +#define SERIAL_CPM_MAJOR TTY_MAJOR +#define SERIAL_CPM_MINOR 64 +#else +#define SERIAL_CPM_MAJOR 204 +#define SERIAL_CPM_MINOR 42 +#endif + +#define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) +#define IS_DISCARDING(pinfo) (pinfo->flags & FLAG_DISCARDING) +#define FLAG_DISCARDING 0x00000004 /* when set, don't discard */ +#define FLAG_SMC 0x00000002 +#define FLAG_CONSOLE 0x00000001 + +#define UART_SMC1 0 +#define UART_SMC2 1 +#define UART_SCC1 2 +#define UART_SCC2 3 +#define UART_SCC3 4 +#define UART_SCC4 5 + +#define UART_NR 6 + +#define RX_NUM_FIFO 4 +#define RX_BUF_SIZE 32 +#define TX_NUM_FIFO 4 +#define TX_BUF_SIZE 32 + +struct uart_cpm_port { + struct uart_port port; + u16 rx_nrfifos; + u16 rx_fifosize; + u16 tx_nrfifos; + u16 tx_fifosize; + smc_t *smcp; + smc_uart_t *smcup; + scc_t *sccp; + scc_uart_t *sccup; + volatile cbd_t *rx_bd_base; + volatile cbd_t *rx_cur; + volatile cbd_t *tx_bd_base; + volatile cbd_t *tx_cur; + unsigned char *tx_buf; + unsigned char *rx_buf; + u32 flags; + void (*set_lineif)(struct uart_cpm_port *); + u8 brg; + uint dp_addr; + void *mem_addr; + dma_addr_t dma_addr; + /* helpers */ + int baud; + int bits; +}; + +extern int cpm_uart_port_map[UART_NR]; +extern int cpm_uart_nr; +extern struct uart_cpm_port cpm_uart_ports[UART_NR]; + +/* these are located in their respective files */ +void cpm_line_cr_cmd(int line, int cmd); +int cpm_uart_init_portdesc(void); +int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); +void cpm_uart_freebuf(struct uart_cpm_port *pinfo); + +void smc1_lineif(struct uart_cpm_port *pinfo); +void smc2_lineif(struct uart_cpm_port *pinfo); +void scc1_lineif(struct uart_cpm_port *pinfo); +void scc2_lineif(struct uart_cpm_port *pinfo); +void scc3_lineif(struct uart_cpm_port *pinfo); +void scc4_lineif(struct uart_cpm_port *pinfo); + +#endif /* CPM_UART_H */ diff -Nru a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/cpm_uart/cpm_uart_core.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,1177 @@ +/* + * linux/drivers/serial/cpm_uart.c + * + * Driver for CPM (SCC/SMC) serial ports; core driver + * + * Based on arch/ppc/cpm2_io/uart.c by Dan Malek + * Based on ppc8xx.c by Thomas Gleixner + * Based on drivers/serial/amba.c by Russell King + * + * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) + * Pantelis Antoniou (panto@intracom.gr) (CPM1) + * + * Copyright (C) 2004 Freescale Semiconductor, Inc. + * (C) 2004 Intracom, S.A. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include +#include + +#include "cpm_uart.h" + +/***********************************************************************/ + +/* Track which ports are configured as uarts */ +int cpm_uart_port_map[UART_NR]; +/* How many ports did we config as uarts */ +int cpm_uart_nr; + +/**************************************************************/ + +static int cpm_uart_tx_pump(struct uart_port *port); +static void cpm_uart_init_smc(struct uart_cpm_port *pinfo, int bits, u16 cval); +static void cpm_uart_init_scc(struct uart_cpm_port *pinfo, int sbits, u16 sval); + +/**************************************************************/ + +/* + * Check, if transmit buffers are processed +*/ +static unsigned int cpm_uart_tx_empty(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + volatile cbd_t *bdp = pinfo->tx_bd_base; + int ret = 0; + + while (1) { + if (bdp->cbd_sc & BD_SC_READY) + break; + + if (bdp->cbd_sc & BD_SC_WRAP) { + ret = TIOCSER_TEMT; + break; + } + bdp++; + } + + pr_debug("CPM uart[%d]:tx_empty: %d\n", port->line, ret); + + return ret; +} + +static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + /* Whee. Do nothing. */ +} + +static unsigned int cpm_uart_get_mctrl(struct uart_port *port) +{ + /* Whee. Do nothing. */ + return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; +} + +/* + * Stop transmitter + */ +static void cpm_uart_stop_tx(struct uart_port *port, unsigned int tty_stop) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + volatile smc_t *smcp = pinfo->smcp; + volatile scc_t *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:stop tx\n", port->line); + + if (IS_SMC(pinfo)) + smcp->smc_smcm &= ~SMCM_TX; + else + sccp->scc_sccm &= ~UART_SCCM_TX; +} + +/* + * Start transmitter + */ +static void cpm_uart_start_tx(struct uart_port *port, unsigned int tty_start) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + volatile smc_t *smcp = pinfo->smcp; + volatile scc_t *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:start tx\n", port->line); + + /* if in the middle of discarding return */ + if (IS_DISCARDING(pinfo)) + return; + + if (IS_SMC(pinfo)) { + if (smcp->smc_smcm & SMCM_TX) + return; + } else { + if (sccp->scc_sccm & UART_SCCM_TX) + return; + } + + if (cpm_uart_tx_pump(port) != 0) { + if (IS_SMC(pinfo)) + smcp->smc_smcm |= SMCM_TX; + else + sccp->scc_sccm |= UART_SCCM_TX; + } +} + +/* + * Stop receiver + */ +static void cpm_uart_stop_rx(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + volatile smc_t *smcp = pinfo->smcp; + volatile scc_t *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:stop rx\n", port->line); + + if (IS_SMC(pinfo)) + smcp->smc_smcm &= ~SMCM_RX; + else + sccp->scc_sccm &= ~UART_SCCM_RX; +} + +/* + * Enable Modem status interrupts + */ +static void cpm_uart_enable_ms(struct uart_port *port) +{ + pr_debug("CPM uart[%d]:enable ms\n", port->line); +} + +/* + * Generate a break. + */ +static void cpm_uart_break_ctl(struct uart_port *port, int break_state) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + + pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, + break_state); + + if (break_state) + cpm_line_cr_cmd(pinfo->port.line, CPM_CR_STOP_TX); + else + cpm_line_cr_cmd(pinfo->port.line, CPM_CR_RESTART_TX); +} + +/* + * Transmit characters, refill buffer descriptor, if possible + */ +static void cpm_uart_int_tx(struct uart_port *port, struct pt_regs *regs) +{ + pr_debug("CPM uart[%d]:TX INT\n", port->line); + + cpm_uart_tx_pump(port); +} + +/* + * Receive characters + */ +static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) +{ + int i; + unsigned char ch, *cp; + struct tty_struct *tty = port->info->tty; + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + volatile cbd_t *bdp; + u16 status; + unsigned int flg; + + pr_debug("CPM uart[%d]:RX INT\n", port->line); + + /* Just loop through the closed BDs and copy the characters into + * the buffer. + */ + bdp = pinfo->rx_cur; + for (;;) { + /* get status */ + status = bdp->cbd_sc; + /* If this one is empty, return happy */ + if (status & BD_SC_EMPTY) + break; + + /* get number of characters, and check spce in flip-buffer */ + i = bdp->cbd_datlen; + + /* If we have not enough room in tty flip buffer, then we try + * later, which will be the next rx-interrupt or a timeout + */ + if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { + tty->flip.work.func((void *)tty); + if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { + printk(KERN_WARNING "TTY_DONT_FLIP set\n"); + return; + } + } + + /* get pointer */ + cp = (unsigned char *)bus_to_virt(bdp->cbd_bufaddr); + + /* loop through the buffer */ + while (i-- > 0) { + ch = *cp++; + port->icount.rx++; + flg = TTY_NORMAL; + + if (status & + (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) + goto handle_error; + if (uart_handle_sysrq_char(port, ch, regs)) + continue; + + error_return: + *tty->flip.char_buf_ptr++ = ch; + *tty->flip.flag_buf_ptr++ = flg; + tty->flip.count++; + + } /* End while (i--) */ + + /* This BD is ready to be used again. Clear status. get next */ + bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); + bdp->cbd_sc |= BD_SC_EMPTY; + + if (bdp->cbd_sc & BD_SC_WRAP) + bdp = pinfo->rx_bd_base; + else + bdp++; + } /* End for (;;) */ + + /* Write back buffer pointer */ + pinfo->rx_cur = (volatile cbd_t *) bdp; + + /* activate BH processing */ + tty_flip_buffer_push(tty); + + return; + + /* Error processing */ + + handle_error: + /* Statistics */ + if (status & BD_SC_BR) + port->icount.brk++; + if (status & BD_SC_PR) + port->icount.parity++; + if (status & BD_SC_FR) + port->icount.frame++; + if (status & BD_SC_OV) + port->icount.overrun++; + + /* Mask out ignored conditions */ + status &= port->read_status_mask; + + /* Handle the remaining ones */ + if (status & BD_SC_BR) + flg = TTY_BREAK; + else if (status & BD_SC_PR) + flg = TTY_PARITY; + else if (status & BD_SC_FR) + flg = TTY_FRAME; + + /* overrun does not affect the current character ! */ + if (status & BD_SC_OV) { + ch = 0; + flg = TTY_OVERRUN; + /* We skip this buffer */ + /* CHECK: Is really nothing senseful there */ + /* ASSUMPTION: it contains nothing valid */ + i = 0; + } +#ifdef SUPPORT_SYSRQ + port->sysrq = 0; +#endif + goto error_return; +} + +/* + * Asynchron mode interrupt handler + */ +static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs) +{ + u8 events; + struct uart_port *port = (struct uart_port *)data; + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + volatile smc_t *smcp = pinfo->smcp; + volatile scc_t *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:IRQ\n", port->line); + + if (IS_SMC(pinfo)) { + events = smcp->smc_smce; + if (events & SMCM_BRKE) + uart_handle_break(port); + if (events & SMCM_RX) + cpm_uart_int_rx(port, regs); + if (events & SMCM_TX) + cpm_uart_int_tx(port, regs); + smcp->smc_smce = events; + } else { + events = sccp->scc_scce; + if (events & UART_SCCM_BRKE) + uart_handle_break(port); + if (events & UART_SCCM_RX) + cpm_uart_int_rx(port, regs); + if (events & UART_SCCM_TX) + cpm_uart_int_tx(port, regs); + sccp->scc_scce = events; + } + return (events) ? IRQ_HANDLED : IRQ_NONE; +} + +static int cpm_uart_startup(struct uart_port *port) +{ + int retval; + + pr_debug("CPM uart[%d]:startup\n", port->line); + + /* Install interrupt handler. */ + retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); + if (retval) + return retval; + + return 0; +} + +/* + * Shutdown the uart + */ +static void cpm_uart_shutdown(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + + pr_debug("CPM uart[%d]:shutdown\n", port->line); + + /* free interrupt handler */ + free_irq(port->irq, port); + + /* If the port is not the console, disable Rx and Tx. */ + if (!(pinfo->flags & FLAG_CONSOLE)) { + /* Stop uarts */ + if (IS_SMC(pinfo)) { + volatile smc_t *smcp = pinfo->smcp; + smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); + } else { + volatile scc_t *sccp = pinfo->sccp; + sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); + } + + /* Shut them really down and reinit buffer descriptors */ + cpm_line_cr_cmd(pinfo->port.line, CPM_CR_INIT_TRX); + } +} + +static void cpm_uart_set_termios(struct uart_port *port, + struct termios *termios, struct termios *old) +{ + int baud; + unsigned long flags; + u16 cval, scval; + int bits, sbits; + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + volatile cbd_t *bdp; + + pr_debug("CPM uart[%d]:set_termios\n", port->line); + + spin_lock_irqsave(&port->lock, flags); + /* disable uart interrupts */ + if (IS_SMC(pinfo)) + pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); + else + pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); + pinfo->flags |= FLAG_DISCARDING; + spin_unlock_irqrestore(&port->lock, flags); + + /* if previous configuration exists wait for tx to finish */ + if (pinfo->baud != 0 && pinfo->bits != 0) { + + /* point to the last txed bd */ + bdp = pinfo->tx_cur; + if (bdp == pinfo->tx_bd_base) + bdp = pinfo->tx_bd_base + pinfo->tx_nrfifos; + else + bdp--; + + /* wait for it to be transmitted */ + while ((bdp->cbd_sc & BD_SC_READY) != 0) + schedule(); + + /* and delay for the hw fifo to drain */ + udelay((3 * 1000000 * pinfo->bits) / pinfo->baud); + } + + spin_lock_irqsave(&port->lock, flags); + + /* Send the CPM an initialize command. */ + cpm_line_cr_cmd(pinfo->port.line, CPM_CR_STOP_TX); + + /* Stop uart */ + if (IS_SMC(pinfo)) + pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + else + pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + /* Send the CPM an initialize command. */ + cpm_line_cr_cmd(pinfo->port.line, CPM_CR_INIT_TRX); + + spin_unlock_irqrestore(&port->lock, flags); + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); + + /* Character length programmed into the mode register is the + * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, + * 1 or 2 stop bits, minus 1. + * The value 'bits' counts this for us. + */ + cval = 0; + scval = 0; + + /* byte size */ + switch (termios->c_cflag & CSIZE) { + case CS5: + bits = 5; + break; + case CS6: + bits = 6; + break; + case CS7: + bits = 7; + break; + case CS8: + bits = 8; + break; + /* Never happens, but GCC is too dumb to figure it out */ + default: + bits = 8; + break; + } + sbits = bits - 5; + + if (termios->c_cflag & CSTOPB) { + cval |= SMCMR_SL; /* Two stops */ + scval |= SCU_PSMR_SL; + bits++; + } + + if (termios->c_cflag & PARENB) { + cval |= SMCMR_PEN; + scval |= SCU_PSMR_PEN; + bits++; + if (!(termios->c_cflag & PARODD)) { + cval |= SMCMR_PM_EVEN; + scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); + } + } + + /* + * Set up parity check flag + */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); + if (termios->c_iflag & INPCK) + port->read_status_mask |= BD_SC_FR | BD_SC_PR; + if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) + port->read_status_mask |= BD_SC_BR; + + /* + * Characters to ignore + */ + port->ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; + if (termios->c_iflag & IGNBRK) { + port->ignore_status_mask |= BD_SC_BR; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= BD_SC_OV; + } + /* + * !!! ignore all characters if CREAD is not set + */ + if ((termios->c_cflag & CREAD) == 0) + port->read_status_mask &= ~BD_SC_EMPTY; + + spin_lock_irqsave(&port->lock, flags); + + cpm_set_brg(pinfo->brg - 1, baud); + + /* Start bit has not been added (so don't, because we would just + * subtract it later), and we need to add one for the number of + * stops bits (there is always at least one). + */ + bits++; + + /* re-init */ + if (IS_SMC(pinfo)) + cpm_uart_init_smc(pinfo, bits, cval); + else + cpm_uart_init_scc(pinfo, sbits, scval); + + pinfo->baud = baud; + pinfo->bits = bits; + + pinfo->flags &= ~FLAG_DISCARDING; + spin_unlock_irqrestore(&port->lock, flags); + +} + +static const char *cpm_uart_type(struct uart_port *port) +{ + pr_debug("CPM uart[%d]:uart_type\n", port->line); + + return port->type == PORT_CPM ? "CPM UART" : NULL; +} + +/* + * verify the new serial_struct (for TIOCSSERIAL). + */ +static int cpm_uart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + int ret = 0; + + pr_debug("CPM uart[%d]:verify_port\n", port->line); + + if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) + ret = -EINVAL; + if (ser->irq < 0 || ser->irq >= NR_IRQS) + ret = -EINVAL; + if (ser->baud_base < 9600) + ret = -EINVAL; + return ret; +} + +/* + * Transmit characters, refill buffer descriptor, if possible + */ +static int cpm_uart_tx_pump(struct uart_port *port) +{ + volatile cbd_t *bdp; + unsigned char *p; + int count; + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + struct circ_buf *xmit = &port->info->xmit; + + /* Handle xon/xoff */ + if (port->x_char) { + /* Pick next descriptor and fill from buffer */ + bdp = pinfo->tx_cur; + + p = bus_to_virt(bdp->cbd_bufaddr); + *p++ = xmit->buf[xmit->tail]; + bdp->cbd_datlen = 1; + bdp->cbd_sc |= BD_SC_READY; + /* Get next BD. */ + if (bdp->cbd_sc & BD_SC_WRAP) + bdp = pinfo->tx_bd_base; + else + bdp++; + pinfo->tx_cur = bdp; + + port->icount.tx++; + port->x_char = 0; + return 1; + } + + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + cpm_uart_stop_tx(port, 0); + return 0; + } + + /* Pick next descriptor and fill from buffer */ + bdp = pinfo->tx_cur; + + while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { + count = 0; + p = bus_to_virt(bdp->cbd_bufaddr); + while (count < pinfo->tx_fifosize) { + *p++ = xmit->buf[xmit->tail]; + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + count++; + if (xmit->head == xmit->tail) + break; + } + bdp->cbd_datlen = count; + bdp->cbd_sc |= BD_SC_READY; + /* Get next BD. */ + if (bdp->cbd_sc & BD_SC_WRAP) + bdp = pinfo->tx_bd_base; + else + bdp++; + } + pinfo->tx_cur = bdp; + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_empty(xmit)) { + cpm_uart_stop_tx(port, 0); + return 0; + } + + return 1; +} + +static void cpm_uart_init_scc(struct uart_cpm_port *pinfo, int bits, u16 scval) +{ + volatile scc_t *scp; + volatile scc_uart_t *sup; + u8 *mem_addr; + volatile cbd_t *bdp; + int i; + + pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); + + scp = pinfo->sccp; + sup = pinfo->sccup; + + /* Set the physical address of the host memory + * buffers in the buffer descriptors, and the + * virtual address for us to work with. + */ + pinfo->rx_cur = pinfo->rx_bd_base; + mem_addr = pinfo->mem_addr; + for (bdp = pinfo->rx_bd_base, i = 0; i < pinfo->rx_nrfifos; i++, bdp++) { + bdp->cbd_bufaddr = virt_to_bus(mem_addr); + bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT | (i < (pinfo->rx_nrfifos - 1) ? 0 : BD_SC_WRAP); + mem_addr += pinfo->rx_fifosize; + } + + /* Set the physical address of the host memory + * buffers in the buffer descriptors, and the + * virtual address for us to work with. + */ + mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); + pinfo->tx_cur = pinfo->tx_bd_base; + for (bdp = pinfo->tx_bd_base, i = 0; i < pinfo->tx_nrfifos; i++, bdp++) { + bdp->cbd_bufaddr = virt_to_bus(mem_addr); + bdp->cbd_sc = BD_SC_INTRPT | (i < (pinfo->tx_nrfifos - 1) ? 0 : BD_SC_WRAP); + mem_addr += pinfo->tx_fifosize; + bdp++; + } + + /* Store address */ + pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE; + pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE; + + /* Set up the uart parameters in the + * parameter ram. + */ + + cpm_set_scc_fcr(sup); + + sup->scc_genscc.scc_mrblr = pinfo->rx_fifosize; + sup->scc_maxidl = pinfo->rx_fifosize; + sup->scc_brkcr = 1; + sup->scc_parec = 0; + sup->scc_frmec = 0; + sup->scc_nosec = 0; + sup->scc_brkec = 0; + sup->scc_uaddr1 = 0; + sup->scc_uaddr2 = 0; + sup->scc_toseq = 0; + sup->scc_char1 = 0x8000; + sup->scc_char2 = 0x8000; + sup->scc_char3 = 0x8000; + sup->scc_char4 = 0x8000; + sup->scc_char5 = 0x8000; + sup->scc_char6 = 0x8000; + sup->scc_char7 = 0x8000; + sup->scc_char8 = 0x8000; + sup->scc_rccm = 0xc0ff; + + /* Send the CPM an initialize command. + */ + cpm_line_cr_cmd(pinfo->port.line, CPM_CR_INIT_TRX); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + scp->scc_gsmrh = 0; + scp->scc_gsmrl = + (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); + + /* Enable rx interrupts and clear all pending events. */ + scp->scc_sccm = UART_SCCM_RX; + scp->scc_scce = 0xffff; + scp->scc_dsr = 0x7e7e; + scp->scc_psmr = (bits << 12) | scval; + + scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); +} + +static void cpm_uart_init_smc(struct uart_cpm_port *pinfo, int bits, u16 cval) +{ + volatile smc_t *sp; + volatile smc_uart_t *up; + volatile u8 *mem_addr; + volatile cbd_t *bdp; + int i; + + pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); + + sp = pinfo->smcp; + up = pinfo->smcup; + + /* Set the physical address of the host memory + * buffers in the buffer descriptors, and the + * virtual address for us to work with. + */ + mem_addr = pinfo->mem_addr; + pinfo->rx_cur = pinfo->rx_bd_base; + for (bdp = pinfo->rx_bd_base, i = 0; i < pinfo->rx_nrfifos; i++, bdp++) { + bdp->cbd_bufaddr = virt_to_bus(mem_addr); + bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT | (i < (pinfo->rx_nrfifos - 1) ? 0 : BD_SC_WRAP); + mem_addr += pinfo->rx_fifosize; + } + + /* Set the physical address of the host memory + * buffers in the buffer descriptors, and the + * virtual address for us to work with. + */ + mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); + pinfo->tx_cur = pinfo->tx_bd_base; + for (bdp = pinfo->tx_bd_base, i = 0; i < pinfo->tx_nrfifos; i++, bdp++) { + bdp->cbd_bufaddr = virt_to_bus(mem_addr); + bdp->cbd_sc = BD_SC_INTRPT | (i < (pinfo->tx_nrfifos - 1) ? 0 : BD_SC_WRAP); + mem_addr += pinfo->tx_fifosize; + } + + /* Store address */ + pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE; + pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE; + + /* Set up the uart parameters in the + * parameter ram. + */ + cpm_set_smc_fcr(up); + + /* Using idle charater time requires some additional tuning. */ + up->smc_mrblr = pinfo->rx_fifosize; + up->smc_maxidl = pinfo->rx_fifosize; + up->smc_brkcr = 1; + + cpm_line_cr_cmd(pinfo->port.line, CPM_CR_INIT_TRX); + + /* Set UART mode, according to the parameters */ + sp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; + + /* Enable only rx interrupts clear all pending events. */ + sp->smc_smcm = SMCM_RX; + sp->smc_smce = 0xff; + + sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); +} + +/* + * Initialize port. This is called from early_console stuff + * so we have to be careful here ! + */ +static int cpm_uart_request_port(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + int ret; + + pr_debug("CPM uart[%d]:request port\n", port->line); + + if (pinfo->flags & FLAG_CONSOLE) + return 0; + + /* + * Setup any port IO, connect any baud rate generators, + * etc. This is expected to be handled by board + * dependant code + */ + if (pinfo->set_lineif) + pinfo->set_lineif(pinfo); + + ret = cpm_uart_allocbuf(pinfo, 0); + if (ret) + return ret; + + return 0; +} + +static void cpm_uart_release_port(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + + if (!(pinfo->flags & FLAG_CONSOLE)) + cpm_uart_freebuf(pinfo); +} + +/* + * Configure/autoconfigure the port. + */ +static void cpm_uart_config_port(struct uart_port *port, int flags) +{ + pr_debug("CPM uart[%d]:config_port\n", port->line); + + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_CPM; + cpm_uart_request_port(port); + } +} +static struct uart_ops cpm_uart_pops = { + .tx_empty = cpm_uart_tx_empty, + .set_mctrl = cpm_uart_set_mctrl, + .get_mctrl = cpm_uart_get_mctrl, + .stop_tx = cpm_uart_stop_tx, + .start_tx = cpm_uart_start_tx, + .stop_rx = cpm_uart_stop_rx, + .enable_ms = cpm_uart_enable_ms, + .break_ctl = cpm_uart_break_ctl, + .startup = cpm_uart_startup, + .shutdown = cpm_uart_shutdown, + .set_termios = cpm_uart_set_termios, + .type = cpm_uart_type, + .release_port = cpm_uart_release_port, + .request_port = cpm_uart_request_port, + .config_port = cpm_uart_config_port, + .verify_port = cpm_uart_verify_port, +}; + +struct uart_cpm_port cpm_uart_ports[UART_NR] = { + [UART_SMC1] = { + .port = { + .irq = SMC1_IRQ, + .ops = &cpm_uart_pops, + .iotype = SERIAL_IO_MEM, + .line = UART_SMC1, + }, + .flags = FLAG_SMC, + .tx_nrfifos = TX_NUM_FIFO, + .tx_fifosize = TX_BUF_SIZE, + .rx_nrfifos = RX_NUM_FIFO, + .rx_fifosize = RX_BUF_SIZE, + .set_lineif = smc1_lineif, + }, + [UART_SMC2] = { + .port = { + .irq = SMC2_IRQ, + .ops = &cpm_uart_pops, + .iotype = SERIAL_IO_MEM, + }, + .flags = FLAG_SMC, + .tx_nrfifos = TX_NUM_FIFO, + .tx_fifosize = TX_BUF_SIZE, + .rx_nrfifos = RX_NUM_FIFO, + .rx_fifosize = RX_BUF_SIZE, + .set_lineif = smc2_lineif, + }, + [UART_SCC1] = { + .port = { + .irq = SCC1_IRQ, + .ops = &cpm_uart_pops, + .iotype = SERIAL_IO_MEM, + .line = UART_SCC1, + }, + .tx_nrfifos = TX_NUM_FIFO, + .tx_fifosize = TX_BUF_SIZE, + .rx_nrfifos = RX_NUM_FIFO, + .rx_fifosize = RX_BUF_SIZE, + .set_lineif = scc1_lineif, + }, + [UART_SCC2] = { + .port = { + .irq = SCC2_IRQ, + .ops = &cpm_uart_pops, + .iotype = SERIAL_IO_MEM, + }, + .tx_nrfifos = TX_NUM_FIFO, + .tx_fifosize = TX_BUF_SIZE, + .rx_nrfifos = RX_NUM_FIFO, + .rx_fifosize = RX_BUF_SIZE, + .set_lineif = scc2_lineif, + }, + [UART_SCC3] = { + .port = { + .irq = SCC3_IRQ, + .ops = &cpm_uart_pops, + .iotype = SERIAL_IO_MEM, + }, + .tx_nrfifos = TX_NUM_FIFO, + .tx_fifosize = TX_BUF_SIZE, + .rx_nrfifos = RX_NUM_FIFO, + .rx_fifosize = RX_BUF_SIZE, + .set_lineif = scc3_lineif, + }, + [UART_SCC4] = { + .port = { + .irq = SCC4_IRQ, + .ops = &cpm_uart_pops, + .iotype = SERIAL_IO_MEM, + .line = UART_SCC4, + }, + .tx_nrfifos = TX_NUM_FIFO, + .tx_fifosize = TX_BUF_SIZE, + .rx_nrfifos = RX_NUM_FIFO, + .rx_fifosize = RX_BUF_SIZE, + .set_lineif = scc4_lineif, + }, +}; + +#ifdef CONFIG_SERIAL_CPM_CONSOLE +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * Note that this is called with interrupts already disabled + */ +static void cpm_uart_console_write(struct console *co, const char *s, + u_int count) +{ + struct uart_cpm_port *pinfo = + &cpm_uart_ports[cpm_uart_port_map[co->index]]; + unsigned int i; + volatile cbd_t *bdp, *bdbase; + volatile unsigned char *cp; + + if (IS_DISCARDING(pinfo)) + return; + + /* Get the address of the host memory buffer. + */ + bdp = pinfo->tx_cur; + bdbase = pinfo->tx_bd_base; + + /* + * Now, do each character. This is not as bad as it looks + * since this is a holding FIFO and not a transmitting FIFO. + * We could add the complexity of filling the entire transmit + * buffer, but we would just wait longer between accesses...... + */ + for (i = 0; i < count; i++, s++) { + /* Wait for transmitter fifo to empty. + * Ready indicates output is ready, and xmt is doing + * that, not that it is ready for us to send. + */ + while ((bdp->cbd_sc & BD_SC_READY) != 0) + ; + + /* Send the character out. + * If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) + cp = (unsigned char *) (bdp->cbd_bufaddr); + else + cp = bus_to_virt(bdp->cbd_bufaddr); + + *cp = *s; + + bdp->cbd_datlen = 1; + bdp->cbd_sc |= BD_SC_READY; + + if (bdp->cbd_sc & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + + /* if a LF, also do CR... */ + if (*s == 10) { + while ((bdp->cbd_sc & BD_SC_READY) != 0) + ; + + if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) + cp = (unsigned char *) (bdp->cbd_bufaddr); + else + cp = bus_to_virt(bdp->cbd_bufaddr); + + *cp = 13; + bdp->cbd_datlen = 1; + bdp->cbd_sc |= BD_SC_READY; + + if (bdp->cbd_sc & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + while ((bdp->cbd_sc & BD_SC_READY) != 0) + ; + + pinfo->tx_cur = (volatile cbd_t *) bdp; +} + +/* + * Setup console. Be careful is called early ! + */ +static int __init cpm_uart_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + struct uart_cpm_port *pinfo; + int baud = 38400; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + int ret; + + port = + (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; + pinfo = (struct uart_cpm_port *)port; + + pinfo->flags |= FLAG_CONSOLE; + + if (options) { + uart_parse_options(options, &baud, &parity, &bits, &flow); + } else { + bd_t *bd = (bd_t *) __res; + + if (bd->bi_baudrate) + baud = bd->bi_baudrate; + else + baud = 9600; + } + + /* + * Setup any port IO, connect any baud rate generators, + * etc. This is expected to be handled by board + * dependant code + */ + if (pinfo->set_lineif) + pinfo->set_lineif(pinfo); + + ret = cpm_uart_allocbuf(pinfo, 1); + if (ret) + return ret; + + uart_set_options(port, co, baud, parity, bits, flow); + + return 0; +} + +extern struct uart_driver cpm_reg; +static struct console cpm_scc_uart_console = { + .name "ttyCPM", + .write cpm_uart_console_write, + .device uart_console_device, + .setup cpm_uart_console_setup, + .flags CON_PRINTBUFFER, + .index -1, + .data = &cpm_reg, +}; + +int __init cpm_uart_console_init(void) +{ + int ret = cpm_uart_init_portdesc(); + + if (!ret) + register_console(&cpm_scc_uart_console); + return ret; +} + +console_initcall(cpm_uart_console_init); + +#define CPM_UART_CONSOLE &cpm_scc_uart_console +#else +#define CPM_UART_CONSOLE NULL +#endif + +static struct uart_driver cpm_reg = { + .owner = THIS_MODULE, + .driver_name = "ttyCPM", + .dev_name = "ttyCPM", + .major = SERIAL_CPM_MAJOR, + .minor = SERIAL_CPM_MINOR, + .cons = CPM_UART_CONSOLE, +}; + +static int __init cpm_uart_init(void) +{ + int ret, i; + + printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n"); + +#ifndef CONFIG_SERIAL_CPM_CONSOLE + ret = cpm_uart_init_portdesc(); + if (ret) + return ret; +#endif + + cpm_reg.nr = cpm_uart_nr; + ret = uart_register_driver(&cpm_reg); + + if (ret) + return ret; + + for (i = 0; i < cpm_uart_nr; i++) { + int con = cpm_uart_port_map[i]; + cpm_uart_ports[con].port.line = i; + cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; + uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); + } + + return ret; +} + +static void __exit cpm_uart_exit(void) +{ + int i; + + for (i = 0; i < cpm_uart_nr; i++) { + int con = cpm_uart_port_map[i]; + uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port); + } + + uart_unregister_driver(&cpm_reg); +} + +module_init(cpm_uart_init); +module_exit(cpm_uart_exit); + +MODULE_AUTHOR("Kumar Gala/Antoniou Pantelis"); +MODULE_DESCRIPTION("CPM SCC/SMC port driver $Revision: 0.01 $"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV(SERIAL_CPM_MAJOR, SERIAL_CPM_MINOR); diff -Nru a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,275 @@ +/* + * linux/drivers/serial/cpm_uart.c + * + * Driver for CPM (SCC/SMC) serial ports; CPM1 definitions + * + * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) + * Pantelis Antoniou (panto@intracom.gr) (CPM1) + * + * Copyright (C) 2004 Freescale Semiconductor, Inc. + * (C) 2004 Intracom, S.A. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "cpm_uart.h" + +/**************************************************************/ + +void cpm_line_cr_cmd(int line, int cmd) +{ + ushort val; + volatile cpm8xx_t *cp = cpmp; + + switch (line) { + case UART_SMC1: + val = mk_cr_cmd(CPM_CR_CH_SMC1, cmd) | CPM_CR_FLG; + break; + case UART_SMC2: + val = mk_cr_cmd(CPM_CR_CH_SMC2, cmd) | CPM_CR_FLG; + break; + case UART_SCC1: + val = mk_cr_cmd(CPM_CR_CH_SCC1, cmd) | CPM_CR_FLG; + break; + case UART_SCC2: + val = mk_cr_cmd(CPM_CR_CH_SCC2, cmd) | CPM_CR_FLG; + break; + case UART_SCC3: + val = mk_cr_cmd(CPM_CR_CH_SCC3, cmd) | CPM_CR_FLG; + break; + case UART_SCC4: + val = mk_cr_cmd(CPM_CR_CH_SCC4, cmd) | CPM_CR_FLG; + break; + default: + return; + + } + cp->cp_cpcr = val; + while (cp->cp_cpcr & CPM_CR_FLG) ; +} + +void smc1_lineif(struct uart_cpm_port *pinfo) +{ + volatile cpm8xx_t *cp = cpmp; + + cp->cp_pbpar |= 0x000000c0; + cp->cp_pbdir &= ~0x000000c0; + cp->cp_pbodr &= ~0x000000c0; + + pinfo->brg = 1; +} + +void smc2_lineif(struct uart_cpm_port *pinfo) +{ + /* XXX SMC2: insert port configuration here */ + pinfo->brg = 2; +} + +void scc1_lineif(struct uart_cpm_port *pinfo) +{ + /* XXX SCC1: insert port configuration here */ + pinfo->brg = 1; +} + +void scc2_lineif(struct uart_cpm_port *pinfo) +{ + /* XXX SCC2: insert port configuration here */ + pinfo->brg = 2; +} + +void scc3_lineif(struct uart_cpm_port *pinfo) +{ + /* XXX SCC3: insert port configuration here */ + pinfo->brg = 3; +} + +void scc4_lineif(struct uart_cpm_port *pinfo) +{ + /* XXX SCC4: insert port configuration here */ + pinfo->brg = 4; +} + +/* + * Allocate DP-Ram and memory buffers. We need to allocate a transmit and + * receive buffer descriptors from dual port ram, and a character + * buffer area from host mem. If we are allocating for the console we need + * to do it from bootmem + */ +int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) +{ + int dpmemsz, memsz; + u8 *dp_mem; + uint dp_addr; + u8 *mem_addr; + dma_addr_t dma_addr; + + pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); + + dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); + dp_mem = m8xx_cpm_dpalloc(dpmemsz); + if (dp_mem == NULL) { + printk(KERN_ERR + "cpm_uart_cpm1.c: could not allocate buffer descriptors\n"); + return -ENOMEM; + } + dp_addr = m8xx_cpm_dpram_offset(dp_mem); + + memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); + if (is_con) { + mem_addr = (u8 *) m8xx_cpm_hostalloc(memsz); + dma_addr = 0; + } else + mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, + GFP_KERNEL); + + if (mem_addr == NULL) { + m8xx_cpm_dpfree(dp_mem); + printk(KERN_ERR + "cpm_uart_cpm1.c: could not allocate coherent memory\n"); + return -ENOMEM; + } + + pinfo->dp_addr = dp_addr; + pinfo->mem_addr = mem_addr; + pinfo->dma_addr = dma_addr; + + pinfo->rx_buf = mem_addr; + pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos + * pinfo->rx_fifosize); + + pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; + pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; + + return 0; +} + +void cpm_uart_freebuf(struct uart_cpm_port *pinfo) +{ + dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos * + pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * + pinfo->tx_fifosize), pinfo->mem_addr, + pinfo->dma_addr); + + m8xx_cpm_dpfree(m8xx_cpm_dpram_addr(pinfo->dp_addr)); +} + +/* Setup any dynamic params in the uart desc */ +int cpm_uart_init_portdesc(void) +{ + pr_debug("CPM uart[-]:init portdesc\n"); + + cpm_uart_nr = 0; +#ifdef CONFIG_SERIAL_CPM_SMC1 + cpm_uart_ports[UART_SMC1].smcp = &cpmp->cp_smc[0]; + cpm_uart_ports[UART_SMC1].smcup = + (smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC1]; + cpm_uart_ports[UART_SMC1].port.mapbase = + (unsigned long)&cpmp->cp_smc[0]; + cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); + cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; +#endif + +#ifdef CONFIG_SERIAL_CPM_SMC2 + cpm_uart_ports[UART_SMC2].smcp = &cpmp->cp_smc[1]; + cpm_uart_ports[UART_SMC2].smcup = + (smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC2]; + cpm_uart_ports[UART_SMC2].port.mapbase = + (unsigned long)&cpmp->cp_smc[1]; + cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); + cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC1 + cpm_uart_ports[UART_SCC1].sccp = &cpmp->cp_scc[0]; + cpm_uart_ports[UART_SCC1].sccup = + (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC1]; + cpm_uart_ports[UART_SCC1].port.mapbase = + (unsigned long)&cpmp->cp_scc[0]; + cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC2 + cpm_uart_ports[UART_SCC2].sccp = &cpmp->cp_scc[1]; + cpm_uart_ports[UART_SCC2].sccup = + (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC2]; + cpm_uart_ports[UART_SCC2].port.mapbase = + (unsigned long)&cpmp->cp_scc[1]; + cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC3 + cpm_uart_ports[UART_SCC3].sccp = &cpmp->cp_scc[2]; + cpm_uart_ports[UART_SCC3].sccup = + (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC3]; + cpm_uart_ports[UART_SCC3].port.mapbase = + (unsigned long)&cpmp->cp_scc[2]; + cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC4 + cpm_uart_ports[UART_SCC4].sccp = &cpmp->cp_scc[3]; + cpm_uart_ports[UART_SCC4].sccup = + (scc_uart_t *) & cpmp->cp_dparam[PROFF_SCC4]; + cpm_uart_ports[UART_SCC4].port.mapbase = + (unsigned long)&cpmp->cp_scc[3]; + cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; +#endif + return 0; +} diff -Nru a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,45 @@ +/* + * linux/drivers/serial/cpm_uart_cpm1.h + * + * Driver for CPM (SCC/SMC) serial ports + * + * definitions for cpm1 + * + */ + +#ifndef CPM_UART_CPM1_H +#define CPM_UART_CPM1_H + +#include + +/* defines for IRQs */ +#define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1) +#define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2) +#define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1) +#define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2) +#define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3) +#define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4) + +/* the CPM address */ +#define CPM_ADDR IMAP_ADDR + +static inline void cpm_set_brg(int brg, int baud) +{ + m8xx_cpm_setbrg(brg, baud); +} + +static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup) +{ + sup->scc_genscc.scc_rfcr = SMC_EB; + sup->scc_genscc.scc_tfcr = SMC_EB; +} + +static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) +{ + up->smc_rfcr = SMC_EB; + up->smc_tfcr = SMC_EB; +} + +#define DPRAM_BASE ((unsigned char *)&cpmp->cp_dpmem[0]) + +#endif diff -Nru a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,328 @@ +/* + * linux/drivers/serial/cpm_uart_cpm2.c + * + * Driver for CPM (SCC/SMC) serial ports; CPM2 definitions + * + * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) + * Pantelis Antoniou (panto@intracom.gr) (CPM1) + * + * Copyright (C) 2004 Freescale Semiconductor, Inc. + * (C) 2004 Intracom, S.A. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "cpm_uart.h" + +/**************************************************************/ + +void cpm_line_cr_cmd(int line, int cmd) +{ + volatile cpm_cpm2_t *cp = cpmp; + ulong val; + + switch (line) { + case UART_SMC1: + val = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, + cmd) | CPM_CR_FLG; + break; + case UART_SMC2: + val = mk_cr_cmd(CPM_CR_SMC2_PAGE, CPM_CR_SMC2_SBLOCK, 0, + cmd) | CPM_CR_FLG; + break; + case UART_SCC1: + val = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, + cmd) | CPM_CR_FLG; + break; + case UART_SCC2: + val = mk_cr_cmd(CPM_CR_SCC2_PAGE, CPM_CR_SCC2_SBLOCK, 0, + cmd) | CPM_CR_FLG; + break; + case UART_SCC3: + val = mk_cr_cmd(CPM_CR_SCC3_PAGE, CPM_CR_SCC3_SBLOCK, 0, + cmd) | CPM_CR_FLG; + break; + case UART_SCC4: + val = mk_cr_cmd(CPM_CR_SCC4_PAGE, CPM_CR_SCC4_SBLOCK, 0, + cmd) | CPM_CR_FLG; + break; + default: + return; + + } + cp->cp_cpcr = val; + while (cp->cp_cpcr & CPM_CR_FLG) ; +} + +void smc1_lineif(struct uart_cpm_port *pinfo) +{ + volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + + /* SMC1 is only on port D */ + io->iop_ppard |= 0x00c00000; + io->iop_pdird |= 0x00400000; + io->iop_pdird &= ~0x00800000; + io->iop_psord &= ~0x00c00000; + + /* Wire BRG1 to SMC1 */ + cpm2_immr->im_cpmux.cmx_smr &= 0x0f; + pinfo->brg = 1; +} + +void smc2_lineif(struct uart_cpm_port *pinfo) +{ + volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + + /* SMC2 is only on port A */ + io->iop_ppara |= 0x00c00000; + io->iop_pdira |= 0x00400000; + io->iop_pdira &= ~0x00800000; + io->iop_psora &= ~0x00c00000; + + /* Wire BRG2 to SMC2 */ + cpm2_immr->im_cpmux.cmx_smr &= 0xf0; + pinfo->brg = 2; +} + +void scc1_lineif(struct uart_cpm_port *pinfo) +{ + volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + + /* Use Port D for SCC1 instead of other functions. */ + io->iop_ppard |= 0x00000003; + io->iop_psord &= ~0x00000001; /* Rx */ + io->iop_psord |= 0x00000002; /* Tx */ + io->iop_pdird &= ~0x00000001; /* Rx */ + io->iop_pdird |= 0x00000002; /* Tx */ + + /* Wire BRG1 to SCC1 */ + cpm2_immr->im_cpmux.cmx_scr &= ~0x00ffffff; + cpm2_immr->im_cpmux.cmx_scr |= 0x00000000; + pinfo->brg = 1; +} + +void scc2_lineif(struct uart_cpm_port *pinfo) +{ + volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + io->iop_pparb |= 0x008b0000; + io->iop_pdirb |= 0x00880000; + io->iop_psorb |= 0x00880000; + io->iop_pdirb &= ~0x00030000; + io->iop_psorb &= ~0x00030000; + cpm2_immr->im_cpmux.cmx_scr &= ~0xff00ffff; + cpm2_immr->im_cpmux.cmx_scr |= 0x00090000; + pinfo->brg = 2; +} + +void scc3_lineif(struct uart_cpm_port *pinfo) +{ + volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + io->iop_pparb |= 0x008b0000; + io->iop_pdirb |= 0x00880000; + io->iop_psorb |= 0x00880000; + io->iop_pdirb &= ~0x00030000; + io->iop_psorb &= ~0x00030000; + cpm2_immr->im_cpmux.cmx_scr &= ~0xffff00ff; + cpm2_immr->im_cpmux.cmx_scr |= 0x00001200; + pinfo->brg = 3; +} + +void scc4_lineif(struct uart_cpm_port *pinfo) +{ + volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + + io->iop_ppard |= 0x00000600; + io->iop_psord &= ~0x00000600; /* Tx/Rx */ + io->iop_pdird &= ~0x00000200; /* Rx */ + io->iop_pdird |= 0x00000400; /* Tx */ + + cpm2_immr->im_cpmux.cmx_scr &= ~0xffffff00; + cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b; + pinfo->brg = 4; +} + +/* + * Allocate DP-Ram and memory buffers. We need to allocate a transmit and + * receive buffer descriptors from dual port ram, and a character + * buffer area from host mem. If we are allocating for the console we need + * to do it from bootmem + */ +int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) +{ + int dpmemsz, memsz; + u8 *dp_mem; + uint dp_addr; + u8 *mem_addr; + dma_addr_t dma_addr = 0; + + pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); + + dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); + dp_mem = cpm2_dpalloc(dpmemsz, 8); + if (dp_mem == NULL) { + printk(KERN_ERR + "cpm_uart_cpm1.c: could not allocate buffer descriptors\n"); + return -ENOMEM; + } + + dp_addr = cpm2_dpram_offset(dp_mem); + + memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); + if (is_con) + mem_addr = alloc_bootmem(memsz); + else + mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, + GFP_KERNEL); + + if (mem_addr == NULL) { + cpm2_dpfree(dp_mem); + printk(KERN_ERR + "cpm_uart_cpm1.c: could not allocate coherent memory\n"); + return -ENOMEM; + } + + pinfo->dp_addr = dp_addr; + pinfo->mem_addr = mem_addr; + pinfo->dma_addr = dma_addr; + + pinfo->rx_buf = mem_addr; + pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos + * pinfo->rx_fifosize); + + pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; + pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; + + return 0; +} + +void cpm_uart_freebuf(struct uart_cpm_port *pinfo) +{ + dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos * + pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * + pinfo->tx_fifosize), pinfo->mem_addr, + pinfo->dma_addr); + + cpm2_dpfree(&pinfo->dp_addr); +} + +/* Setup any dynamic params in the uart desc */ +int cpm_uart_init_portdesc(void) +{ + pr_debug("CPM uart[-]:init portdesc\n"); + + cpm_uart_nr = 0; +#ifdef CONFIG_SERIAL_CPM_SMC1 + cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0]; + cpm_uart_ports[UART_SMC1].smcup = + (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1]; + cpm_uart_ports[UART_SMC1].port.mapbase = + (unsigned long)&cpm2_immr->im_smc[0]; + cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); + cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; +#endif + +#ifdef CONFIG_SERIAL_CPM_SMC2 + cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1]; + cpm_uart_ports[UART_SMC2].smcup = + (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2]; + cpm_uart_ports[UART_SMC2].port.mapbase = + (unsigned long)&cpm2_immr->im_smc[1]; + cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); + cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC1 + cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0]; + cpm_uart_ports[UART_SCC1].sccup = + (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1]; + cpm_uart_ports[UART_SCC1].port.mapbase = + (unsigned long)&cpm2_immr->im_scc[0]; + cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC2 + cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1]; + cpm_uart_ports[UART_SCC2].sccup = + (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2]; + cpm_uart_ports[UART_SCC2].port.mapbase = + (unsigned long)&cpm2_immr->im_scc[1]; + cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC3 + cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2]; + cpm_uart_ports[UART_SCC3].sccup = + (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3]; + cpm_uart_ports[UART_SCC3].port.mapbase = + (unsigned long)&cpm2_immr->im_scc[2]; + cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; +#endif + +#ifdef CONFIG_SERIAL_CPM_SCC4 + cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3]; + cpm_uart_ports[UART_SCC4].sccup = + (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4]; + cpm_uart_ports[UART_SCC4].port.mapbase = + (unsigned long)&cpm2_immr->im_scc[3]; + cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= + ~(UART_SCCM_TX | UART_SCCM_RX); + cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; +#endif + + return 0; +} diff -Nru a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,45 @@ +/* + * linux/drivers/serial/cpm_uart_cpm2.h + * + * Driver for CPM (SCC/SMC) serial ports + * + * definitions for cpm2 + * + */ + +#ifndef CPM_UART_CPM2_H +#define CPM_UART_CPM2_H + +#include + +/* defines for IRQs */ +#define SMC1_IRQ SIU_INT_SMC1 +#define SMC2_IRQ SIU_INT_SMC2 +#define SCC1_IRQ SIU_INT_SCC1 +#define SCC2_IRQ SIU_INT_SCC2 +#define SCC3_IRQ SIU_INT_SCC3 +#define SCC4_IRQ SIU_INT_SCC4 + +/* the CPM address */ +#define CPM_ADDR CPM_MAP_ADDR + +static inline void cpm_set_brg(int brg, int baud) +{ + cpm2_setbrg(brg, baud); +} + +static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup) +{ + sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; + sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; +} + +static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) +{ + up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; + up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; +} + +#define DPRAM_BASE ((unsigned char *)&cpm2_immr->im_dprambase[0]) + +#endif diff -Nru a/drivers/serial/pxa.c b/drivers/serial/pxa.c --- a/drivers/serial/pxa.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/serial/pxa.c 2004-06-26 17:09:20 -07:00 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -571,14 +572,9 @@ unsigned int oldstate) { struct uart_pxa_port *up = (struct uart_pxa_port *)port; - if (state) { - /* sleep */ - CKEN &= ~up->cken; - } else { - /* wake */ - CKEN |= up->cken; + pxa_set_cken(up->cken, !state); + if (!state) udelay(1); - } } static void serial_pxa_release_port(struct uart_port *port) @@ -809,26 +805,76 @@ .cons = PXA_CONSOLE, }; -static int __init serial_pxa_init(void) +static int serial_pxa_suspend(struct device *_dev, u32 state, u32 level) { - int i, ret; + struct uart_pxa_port *sport = dev_get_drvdata(_dev); - ret = uart_register_driver(&serial_pxa_reg); - if (ret) - return ret; + if (sport && level == SUSPEND_DISABLE) + uart_suspend_port(&serial_pxa_reg, &sport->port); + + return 0; +} + +static int serial_pxa_resume(struct device *_dev, u32 level) +{ + struct uart_pxa_port *sport = dev_get_drvdata(_dev); - for (i = 0; i < ARRAY_SIZE(serial_pxa_ports); i++) - uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[i].port); + if (sport && level == RESUME_ENABLE) + uart_resume_port(&serial_pxa_reg, &sport->port); + return 0; +} + +static int serial_pxa_probe(struct device *_dev) +{ + struct platform_device *dev = to_platform_device(_dev); + + serial_pxa_ports[dev->id].port.dev = _dev; + uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port); + dev_set_drvdata(_dev, &serial_pxa_ports[dev->id]); return 0; } -static void __exit serial_pxa_exit(void) +static int serial_pxa_remove(struct device *_dev) { - int i; + struct uart_pxa_port *sport = dev_get_drvdata(_dev); + + dev_set_drvdata(_dev, NULL); + + if (sport) + uart_remove_one_port(&serial_pxa_reg, &sport->port); + + return 0; +} + +static struct device_driver serial_pxa_driver = { + .name = "pxa2xx-uart", + .bus = &platform_bus_type, + .probe = serial_pxa_probe, + .remove = serial_pxa_remove, + + .suspend = serial_pxa_suspend, + .resume = serial_pxa_resume, +}; + +int __init serial_pxa_init(void) +{ + int ret; - for (i = 0; i < ARRAY_SIZE(serial_pxa_ports); i++) - uart_remove_one_port(&serial_pxa_reg, &serial_pxa_ports[i].port); + ret = uart_register_driver(&serial_pxa_reg); + if (ret != 0) + return ret; + + ret = driver_register(&serial_pxa_driver); + if (ret != 0) + uart_unregister_driver(&serial_pxa_reg); + + return ret; +} + +void __exit serial_pxa_exit(void) +{ + driver_unregister(&serial_pxa_driver); uart_unregister_driver(&serial_pxa_reg); } diff -Nru a/drivers/serial/serial98.c b/drivers/serial/serial98.c --- a/drivers/serial/serial98.c 2004-06-26 17:09:19 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,1120 +0,0 @@ -/* - * linux/drivers/serial/serial98.c - * - * Driver for NEC PC-9801/PC-9821 standard serial ports - * - * Based on drivers/serial/8250.c, by Russell King. - * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. - * - * Copyright (C) 2002 Osamu Tomita - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(CONFIG_SERIAL98_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include - -#define SERIAL98_NR 1 -#define SERIAL98_ISR_PASS_LIMIT 256 -#define SERIAL98_EXT 0x434 - -//#define RX_8251F 0x130 /* In: Receive buffer */ -//#define TX_8251F 0x130 /* Out: Transmit buffer */ -//#define LSR_8251F 0x132 /* In: Line Status Register */ -//#define MSR_8251F 0x134 /* In: Modem Status Register */ -#define IIR_8251F 0x136 /* In: Interrupt ID Register */ -#define FCR_8251F 0x138 /* I/O: FIFO Control Register */ -#define VFAST_8251F 0x13a /* I/O: VFAST mode Register */ - -#define CMD_8251F 0x32 /* Out: 8251 Command Resister */ -#define IER2_8251F 0x34 /* I/O: Interrupt Enable Register */ -#define IER1_8251F 0x35 /* I/O: Interrupt Enable Register */ -#define IER1_CTL 0x37 /* Out: Interrupt Enable Register */ -#define DIS_RXR_INT 0x00 /* disable RxRDY Interrupt */ -#define ENA_RXR_INT 0x01 /* enable RxRDY Interrupt */ -#define DIS_TXE_INT 0x02 /* disable TxEMPTY Interrupt */ -#define ENA_TXE_INT 0x03 /* enable TxEMPTY Interrupt */ -#define DIS_TXR_INT 0x04 /* disable TxRDY Interrupt */ -#define ENA_TXR_INT 0x05 /* enable TxRDY Interrupt */ - -#define CMD_RESET 0x40 /* Reset Command */ -#define CMD_RTS 0x20 /* Set RTS line */ -#define CMD_CLR_ERR 0x10 /* Clear error flag */ -#define CMD_BREAK 0x08 /* Send Break */ -#define CMD_RXE 0x04 /* Enable receive */ -#define CMD_DTR 0x02 /* Set DTR line */ -#define CMD_TXE 0x01 /* Enable send */ -#define CMD_DUMMY 0x00 /* Dummy Command */ - -#define VFAST_ENABLE 0x80 /* V.Fast mode Enable */ - -/* Interrupt masks */ -#define INTR_8251_TXRE 0x04 -#define INTR_8251_TXEE 0x02 -#define INTR_8251_RXRE 0x01 -/* I/O Port */ -//#define PORT_8251_DATA 0 -//#define PORT_8251_CMD 2 -//#define PORT_8251_MOD 2 -//#define PORT_8251_STS 2 -/* status read */ -#define STAT_8251_TXRDY 0x01 -#define STAT_8251_RXRDY 0x02 -#define STAT_8251_TXEMP 0x04 -#define STAT_8251_PER 0x08 -#define STAT_8251_OER 0x10 -#define STAT_8251_FER 0x20 -#define STAT_8251_BRK 0x40 -#define STAT_8251_DSR 0x80 -#if 1 -#define STAT_8251F_TXEMP 0x01 -#define STAT_8251F_TXRDY 0x02 -#define STAT_8251F_RXRDY 0x04 -#define STAT_8251F_DSR 0x08 -#define STAT_8251F_OER 0x10 -#define STAT_8251F_PER 0x20 -#define STAT_8251F_FER 0x40 -#define STAT_8251F_BRK 0x80 -#else -#define STAT_8251F_TXEMP 0x01 -#define STAT_8251F_TEMT 0x01 -#define STAT_8251F_TXRDY 0x02 -#define STAT_8251F_THRE 0x02 -#define STAT_8251F_RXRDY 0x04 -#define STAT_8251F_DSR 0x04 -#define STAT_8251F_PER 0x08 -#define STAT_8251F_OER 0x10 -#define STAT_8251F_FER 0x20 -#define STAT_8251F_BRK 0x40 -#endif - -/* - * We wrap our port structure around the generic uart_port. - */ -struct serial98_port { - struct uart_port port; - unsigned int type; - unsigned int ext; - unsigned int lsr_break_flag; - unsigned char cmd; - unsigned char mode; - unsigned char msr; - unsigned char ier; - unsigned char rxchk; - unsigned char txemp; - unsigned char txrdy; - unsigned char rxrdy; - unsigned char brk; - unsigned char fe; - unsigned char oe; - unsigned char pe; - unsigned char dr; -}; - -#ifdef CONFIG_SERIAL98_CONSOLE -static void -serial98_console_write(struct console *co, const char *s, unsigned int count); -static int __init serial98_console_setup(struct console *co, char *options); - -extern struct uart_driver serial98_reg; -static struct console serial98_console = { - .name = "ttyS", - .write = serial98_console_write, - .device = uart_console_device, - .setup = serial98_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &serial98_reg, -}; - -#define SERIAL98_CONSOLE &serial98_console -#else -#define SERIAL98_CONSOLE NULL -#endif - -static struct uart_driver serial98_reg = { - .owner = THIS_MODULE, - .driver_name = "serial98", - .dev_name = "ttyS", - .major = TTY_MAJOR, - .minor = 64, - .nr = SERIAL98_NR, - .cons = SERIAL98_CONSOLE, -}; - -static int serial98_clk; -static char type_str[48]; - -#define PORT98 ((struct serial98_port *)port) -#define PORT (PORT98->port) - -static void serial98_fifo_enable(struct uart_port *port, int enable) -{ - unsigned char fcr; - - if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) { - fcr = inb(FCR_8251F); - if (enable) - fcr |= UART_FCR_ENABLE_FIFO; - else - fcr &= ~UART_FCR_ENABLE_FIFO; - outb(fcr, FCR_8251F); - } - - if (!enable) - return; - - outb(0, 0x5f); /* wait */ - outb(0, 0x5f); - outb(0, 0x5f); - outb(0, 0x5f); -} - -static void serial98_cmd_out(struct uart_port *port, unsigned char cmd) -{ - serial98_fifo_enable(port, 0); - outb(cmd, CMD_8251F); - serial98_fifo_enable(port, 1); -} - -static void serial98_mode_set(struct uart_port *port) -{ - serial98_cmd_out(port, CMD_DUMMY); - serial98_cmd_out(port, CMD_DUMMY); - serial98_cmd_out(port, CMD_DUMMY); - serial98_cmd_out(port, CMD_RESET); - serial98_cmd_out(port, PORT98->mode); -} - -static unsigned char serial98_msr_in(struct uart_port *port) -{ - unsigned long flags; - unsigned int ms, st; - unsigned int tmp; - - spin_lock_irqsave(&PORT.lock, flags); - if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) { - PORT98->msr = inb(PORT.iobase + 4); - } else { - ms = inb(0x33); - st = inb(0x32); - tmp = 0; - if(!(ms & 0x20)) - tmp |= UART_MSR_DCD; - if(!(ms & 0x80)) { - tmp |= UART_MSR_RI; - PORT98->msr |= UART_MSR_RI; - } - if(!(ms & 0x40)) - tmp |= UART_MSR_CTS; - if(st & 0x80) - tmp |= UART_MSR_DSR; - PORT98->msr = ((PORT98->msr ^ tmp) >> 4) | tmp; - } - - spin_unlock_irqrestore(&PORT.lock, flags); - return PORT98->msr; -} - -static void serial98_stop_tx(struct uart_port *port, unsigned int tty_stop) -{ - unsigned int ier = inb(IER1_8251F); - - ier &= ~(INTR_8251_TXRE | INTR_8251_TXEE); - outb(ier, IER1_8251F); -} - -static void serial98_start_tx(struct uart_port *port, unsigned int tty_start) -{ - unsigned int ier = inb(IER1_8251F); - - ier |= INTR_8251_TXRE | INTR_8251_TXEE; - outb(ier, IER1_8251F); -} - -static void serial98_stop_rx(struct uart_port *port) -{ - PORT.read_status_mask &= ~PORT98->dr; - outb(DIS_RXR_INT, IER1_CTL); -} - -static void serial98_enable_ms(struct uart_port *port) -{ - outb(PORT98->ier | 0x80, IER2_8251F); -} - -static void serial98_rx_chars(struct uart_port *port, int *status, - struct pt_regs *regs) -{ - struct tty_struct *tty = PORT.info->tty; - unsigned char ch; - int max_count = 256; - - do { - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { - tty->flip.work.func((void *)tty); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - return; // if TTY_DONT_FLIP is set - } - ch = inb(PORT.iobase); - *tty->flip.char_buf_ptr = ch; - *tty->flip.flag_buf_ptr = TTY_NORMAL; - PORT.icount.rx++; - - if (unlikely(*status & (PORT98->brk | PORT98->pe | - PORT98->fe | PORT98->oe))) { - /* - * For statistics only - */ - if (*status & PORT98->brk) { - *status &= ~(PORT98->fe | PORT98->pe); - PORT.icount.brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ - if (uart_handle_break(&PORT)) - goto ignore_char; - } else if (*status & PORT98->pe) - PORT.icount.parity++; - else if (*status & PORT98->fe) - PORT.icount.frame++; - if (*status & PORT98->oe) - PORT.icount.overrun++; - - /* - * Mask off conditions which should be ingored. - */ - *status &= PORT.read_status_mask; - -#ifdef CONFIG_SERIAL98_CONSOLE - if (PORT.line == PORT.cons->index) { - /* Recover the break flag from console xmit */ - *status |= PORT98->lsr_break_flag; - PORT98->lsr_break_flag = 0; - } -#endif - if (*status & PORT98->brk) { - *tty->flip.flag_buf_ptr = TTY_BREAK; - } else if (*status & PORT98->pe) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (*status & PORT98->fe) - *tty->flip.flag_buf_ptr = TTY_FRAME; - } - if (uart_handle_sysrq_char(&PORT, ch, regs)) - goto ignore_char; - if ((*status & PORT.ignore_status_mask) == 0) { - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - } - if ((*status & PORT98->oe) && - tty->flip.count < TTY_FLIPBUF_SIZE) { - /* - * Overrun is special, since it's reported - * immediately, and doesn't affect the current - * character. - */ - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - } - ignore_char: - *status = inb(PORT.iobase + 2); - } while ((*status & PORT98->rxchk) && (max_count-- > 0)); - tty_flip_buffer_push(tty); -} - -static void serial98_tx_chars(struct uart_port *port) -{ - struct circ_buf *xmit = &PORT.info->xmit; - int count; - - if (PORT.x_char) { - outb(PORT.x_char, PORT.iobase); - PORT.icount.tx++; - PORT.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&PORT)) { - serial98_stop_tx(port, 0); - return; - } - - count = PORT.fifosize; - do { - outb(xmit->buf[xmit->tail], PORT.iobase); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - PORT.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&PORT); - - if (uart_circ_empty(xmit)) - serial98_stop_tx(&PORT, 0); -} - -static void serial98_modem_status(struct uart_port *port) -{ - int status; - - status = serial98_msr_in(port); - - if ((status & UART_MSR_ANY_DELTA) == 0) - return; - - if (status & UART_MSR_TERI) - PORT.icount.rng++; - if (status & UART_MSR_DDSR) - PORT.icount.dsr++; - if (status & UART_MSR_DDCD) - uart_handle_dcd_change(&PORT, status & UART_MSR_DCD); - if (status & UART_MSR_DCTS) - uart_handle_cts_change(&PORT, status & UART_MSR_CTS); - - wake_up_interruptible(&PORT.info->delta_msr_wait); -} - -static void serial98_int(int irq, void *port, struct pt_regs *regs) -{ - unsigned int status; - - spin_lock(&PORT.lock); - status = inb(PORT.iobase + 2); - if (status & PORT98->rxrdy) { - serial98_rx_chars(port, &status, regs); - } - serial98_modem_status(port); - if (status & PORT98->txrdy) { - serial98_tx_chars(port); - } - spin_unlock(&PORT.lock); -} - -static unsigned int serial98_tx_empty(struct uart_port *port) -{ - unsigned long flags; - unsigned int ret = 0; - - spin_lock_irqsave(&PORT.lock, flags); - if (inb(PORT.iobase + 2) & PORT98->txemp) - ret = TIOCSER_TEMT; - - spin_unlock_irqrestore(&PORT.lock, flags); - return ret; -} - -static unsigned int serial98_get_mctrl(struct uart_port *port) -{ - unsigned char status; - unsigned int ret = 0; - - status = serial98_msr_in(port); - if (status & UART_MSR_DCD) - ret |= TIOCM_CAR; - if (status & UART_MSR_RI) - ret |= TIOCM_RNG; - if (status & UART_MSR_DSR) - ret |= TIOCM_DSR; - if (status & UART_MSR_CTS) - ret |= TIOCM_CTS; - return ret; -} - -static void serial98_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - PORT98->cmd &= 0xdd; - if (mctrl & TIOCM_RTS) - PORT98->cmd |= CMD_RTS; - - if (mctrl & TIOCM_DTR) - PORT98->cmd |= CMD_DTR; - - serial98_cmd_out(port, PORT98->cmd); -} - -static void serial98_break_ctl(struct uart_port *port, int break_state) -{ - unsigned long flags; - - spin_lock_irqsave(&PORT.lock, flags); - if (break_state == -1) - PORT98->cmd |= CMD_BREAK; - else - PORT98->cmd &= ~CMD_BREAK; - - serial98_cmd_out(port, PORT98->cmd); - spin_unlock_irqrestore(&PORT.lock, flags); -} - -static int serial98_startup(struct uart_port *port) -{ - int retval; - - if (PORT.type == PORT_8251_PC98) { - /* Wake up UART */ - PORT98->mode = 0xfc; - serial98_mode_set(port); - outb(DIS_RXR_INT, IER1_CTL); - outb(DIS_TXE_INT, IER1_CTL); - outb(DIS_TXR_INT, IER1_CTL); - PORT98->mode = 0; - serial98_mode_set(port); - } - - /* - * Clear the FIFO buffers and disable them. - * (they will be reeanbled in set_termios()) - */ - if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) { - outb(UART_FCR_ENABLE_FIFO, FCR_8251F); - outb((UART_FCR_ENABLE_FIFO - | UART_FCR_CLEAR_RCVR - | UART_FCR_CLEAR_XMIT), FCR_8251F); - outb(0, FCR_8251F); - } - - /* Clear the interrupt registers. */ - inb(0x30); - inb(0x32); - if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) { - inb(PORT.iobase); - inb(PORT.iobase + 2); - inb(PORT.iobase + 4); - inb(PORT.iobase + 6); - } - - /* Allocate the IRQ */ - retval = request_irq(PORT.irq, serial98_int, 0, - serial98_reg.driver_name, port); - if (retval) - return retval; - - /* - * Now, initialize the UART - */ - PORT98->mode = 0x4e; - serial98_mode_set(port); - PORT98->cmd = 0x15; - serial98_cmd_out(port, PORT98->cmd); - PORT98->cmd = 0x05; - - /* - * Finally, enable interrupts - */ - outb(0x00, IER2_8251F); - outb(ENA_RXR_INT, IER1_CTL); - - /* - * And clear the interrupt registers again for luck. - */ - inb(0x30); - inb(0x32); - if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) { - inb(PORT.iobase); - inb(PORT.iobase + 2); - inb(PORT.iobase + 4); - inb(PORT.iobase + 6); - } - - return 0; -} - -static void serial98_shutdown(struct uart_port *port) -{ - unsigned long flags; - - /* - * disable all interrupts - */ - spin_lock_irqsave(&PORT.lock, flags); - if (PORT.type == PORT_VFAST_PC98) - outb(0, VFAST_8251F); /* V.FAST mode off */ - - /* disnable all modem status interrupt */ - outb(0x80, IER2_8251F); - - /* disnable TX/RX interrupt */ - outb(0x00, IER2_8251F); - outb(DIS_RXR_INT, IER1_CTL); - outb(DIS_TXE_INT, IER1_CTL); - outb(DIS_TXR_INT, IER1_CTL); - PORT98->ier = 0; - - spin_unlock_irqrestore(&PORT.lock, flags); - - /* - * Free the interrupt - */ - free_irq(PORT.irq, port); - - /* disable break condition and disable the port */ - serial98_mode_set(port); - - /* disable FIFO's */ - if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) { - outb((UART_FCR_ENABLE_FIFO - | UART_FCR_CLEAR_RCVR - | UART_FCR_CLEAR_XMIT), FCR_8251F); - outb(0, FCR_8251F); - } - - inb(PORT.iobase); -} - -static void -serial98_set_termios(struct uart_port *port, struct termios *termios, - struct termios *old) -{ - unsigned char stopbit, cval, fcr = 0, ier = 0; - unsigned long flags; - unsigned int baud, quot; - - stopbit = 0x80; - switch (termios->c_cflag & CSIZE) { - case CS5: - cval = 0x42; - stopbit = 0xc0; - break; - case CS6: - cval = 0x46; - break; - case CS7: - cval = 0x4a; - break; - default: - case CS8: - cval = 0x4e; - break; - } - - if (termios->c_cflag & CSTOPB) - cval ^= stopbit; - if (termios->c_cflag & PARENB) - cval |= 0x10; - if (!(termios->c_cflag & PARODD)) - cval |= 0x20; - - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - - if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) { - if ((PORT.uartclk / quot) < (2400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8; - } - - /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. - */ - spin_lock_irqsave(&PORT.lock, flags); - - /* - * Update the per-port timeout. - */ - uart_update_timeout(port, termios->c_cflag, baud); - - PORT.read_status_mask = PORT98->oe | PORT98->txemp | PORT98->dr; - if (termios->c_iflag & INPCK) - PORT.read_status_mask |= PORT98->fe | PORT98->pe; - - if (termios->c_iflag & (BRKINT | PARMRK)) - PORT.read_status_mask |= PORT98->brk; - /* - * Characters to ignore - */ - PORT.ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - PORT.ignore_status_mask |= PORT98->fe | PORT98->pe; - - if (termios->c_iflag & IGNBRK) { - PORT.ignore_status_mask |= PORT98->brk; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - PORT.ignore_status_mask |= PORT98->oe; - } - - /* - * ignore all characters if CREAD is not set - */ - if ((termios->c_cflag & CREAD) == 0) - PORT.ignore_status_mask |= PORT98->dr; - - /* - * CTS flow control flag and modem status interrupts - */ - if (PORT.flags & UPF_HARDPPS_CD) - ier |= 0x80; /* enable modem status interrupt */ - if (termios->c_cflag & CRTSCTS) { - ier |= 0x08; /* enable CTS interrupt */ - ier |= 0x80; /* enable modem status interrupt */ - } - if (!(termios->c_cflag & CLOCAL)) { - ier |= 0x20; /* enable CD interrupt */ - ier |= 0x80; /* enable modem status interrupt */ - } - PORT98->ier = ier; - - PORT98->mode = cval; - serial98_mode_set(port); - if (PORT.type == PORT_VFAST_PC98 && quot <= 48) { - quot /= 4; - if (quot < 1) - quot = 1; - outb(quot | VFAST_ENABLE, VFAST_8251F); - } else { - quot /= 3; - if (quot < 1) - quot = 1; - if (PORT.type == PORT_VFAST_PC98) - outb(0, VFAST_8251F); /* V.FAST mode off */ - outb(0xb6, 0x77); - outb(quot & 0xff, 0x75); /* LS of divisor */ - outb(quot >> 8, 0x75); /* MS of divisor */ - } - - if (fcr & UART_FCR_ENABLE_FIFO) { - outb(UART_FCR_ENABLE_FIFO, FCR_8251F); - outb(fcr, FCR_8251F); - } - - /* enable RX/TX */ - PORT98->cmd = 0x15; - serial98_cmd_out(port, PORT98->cmd); - PORT98->cmd = 0x05; - /* enable interrupts */ - outb(0x00, IER2_8251F); - outb(ENA_RXR_INT, IER1_CTL); - spin_unlock_irqrestore(&PORT.lock, flags); -} - -static const char *serial98_type(struct uart_port *port) -{ - char *p; - - switch (PORT.type) { - case PORT_8251_PC98: - p = "PC98 onboard legacy 8251"; - break; - case PORT_19K_PC98: - p = "PC98 onboard max 19200bps"; - break; - case PORT_FIFO_PC98: - p = "PC98 onboard with FIFO"; - break; - case PORT_VFAST_PC98: - p = "PC98 onboard V.FAST"; - break; - case PORT_PC9861: - p = "PC-9861K RS-232C ext. board"; - break; - case PORT_PC9801_101: - p = "PC-9801-101 RS-232C ext. board"; - break; - default: - return NULL; - } - - sprintf(type_str, "%s Clock %dMHz", p, serial98_clk); - return type_str; -} - -/* Release the region(s) being used by 'port' */ -static void serial98_release_port(struct uart_port *port) -{ - switch (PORT.type) { - case PORT_VFAST_PC98: - release_region(PORT.iobase + 0xa, 1); - case PORT_FIFO_PC98: - release_region(PORT.iobase + 8, 1); - release_region(PORT.iobase + 6, 1); - release_region(PORT.iobase + 4, 1); - release_region(PORT.iobase + 2, 1); - release_region(PORT.iobase, 1); - case PORT_19K_PC98: - release_region(SERIAL98_EXT, 1); - release_region(0x34, 1); - case PORT_8251_PC98: - release_region(0x32, 1); - release_region(0x30, 1); - } -} - -/* Request the region(s) being used by 'port' */ -#define REQ_REGION98(base) (request_region((base), 1, serial98_reg.driver_name)) -static int serial98_request_region(unsigned int type) -{ - if (!REQ_REGION98(0x30)) - return -EBUSY; - if (REQ_REGION98(0x32)) { - if (type == PORT_8251_PC98) - return 0; - if (REQ_REGION98(0x34)) { - if (REQ_REGION98(SERIAL98_EXT)) { - unsigned long base; - - if (type == PORT_19K_PC98) - return 0; - for (base = 0x130; base <= 0x138; base += 2) { - if (!REQ_REGION98(base)) { - base -= 2; - goto err; - } - } - if (type == PORT_FIFO_PC98) - return 0; - if (type == PORT_VFAST_PC98) { - if (REQ_REGION98(0x13a)) - return 0; - } - err: - while (base >= 0x130) { - release_region(base, 1); - base -= 2; - } - release_region(SERIAL98_EXT, 1); - } - release_region(0x34, 1); - } - release_region(0x32, 1); - } - release_region(0x30, 1); - return -EBUSY; -} - -static int serial98_request_port(struct uart_port *port) -{ - return serial98_request_region(PORT.type); -} - -/* - * Configure/autoconfigure the port. - */ -static void serial98_config_port(struct uart_port *port, int flags) -{ - if (flags & UART_CONFIG_TYPE) - PORT.type = PORT98->type; -} - -/* - * verify the new serial_struct (for TIOCSSERIAL). - */ -static int serial98_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - switch (ser->type) { - case PORT_VFAST_PC98: - case PORT_FIFO_PC98: - case PORT_19K_PC98: - case PORT_8251_PC98: - /* not implemented yet - case PORT_PC9861: - case PORT_PC9801_101: - */ - case PORT_UNKNOWN: - break; - default: - return -EINVAL; - } - if (ser->irq < 0 || ser->irq >= NR_IRQS) - return -EINVAL; - if (ser->baud_base < 9600) - return -EINVAL; - return 0; -} - -static struct uart_ops serial98_ops = { - .tx_empty = serial98_tx_empty, - .set_mctrl = serial98_set_mctrl, - .get_mctrl = serial98_get_mctrl, - .stop_tx = serial98_stop_tx, - .start_tx = serial98_start_tx, - .stop_rx = serial98_stop_rx, - .enable_ms = serial98_enable_ms, - .break_ctl = serial98_break_ctl, - .startup = serial98_startup, - .shutdown = serial98_shutdown, - .set_termios = serial98_set_termios, - .type = serial98_type, - .release_port = serial98_release_port, - .request_port = serial98_request_port, - .config_port = serial98_config_port, - .verify_port = serial98_verify_port, -}; - -static struct serial98_port serial98_ports[SERIAL98_NR] = { - { - .port = { - .iobase = 0x30, - .iotype = SERIAL_IO_PORT, - .irq = 4, - .fifosize = 1, - .ops = &serial98_ops, - .flags = ASYNC_BOOT_AUTOCONF, - .line = 0, - }, - .rxchk = STAT_8251_RXRDY, - .txemp = STAT_8251_TXEMP, - .txrdy = STAT_8251_TXRDY, - .rxrdy = STAT_8251_RXRDY, - .brk = STAT_8251_BRK, - .fe = STAT_8251_FER, - .oe = STAT_8251_OER, - .pe = STAT_8251_PER, - .dr = STAT_8251_DSR, - }, -}; - -#ifdef CONFIG_SERIAL98_CONSOLE - -#define BOTH_EMPTY (PORT98->txemp | PORT98->txrdy) - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct uart_port *port) -{ - unsigned int status, tmout = 10000; - - /* Wait up to 10ms for the character(s) to be sent. */ - do { - status = inb(PORT.iobase + 2); - - if (status & PORT98->brk) - PORT98->lsr_break_flag = PORT98->brk; - - if (--tmout == 0) - break; - udelay(1); - } while ((status & BOTH_EMPTY) != BOTH_EMPTY); - - /* Wait up to 1s for flow control if necessary */ - if (PORT.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (--tmout && - ((serial98_msr_in(port) & UART_MSR_CTS) == 0)) - udelay(1); - } -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void -serial98_console_write(struct console *co, const char *s, unsigned int count) -{ - struct uart_port *port = (struct uart_port *)&serial98_ports[co->index]; - unsigned int ier1, ier2; - int i; - - /* - * First save the UER then disable the interrupts - */ - ier1 = inb(IER1_8251F); - ier2 = inb(IER2_8251F); - /* disnable all modem status interrupt */ - outb(0x80, IER2_8251F); - - /* disnable TX/RX interrupt */ - outb(0x00, IER2_8251F); - outb(DIS_RXR_INT, IER1_CTL); - outb(DIS_TXE_INT, IER1_CTL); - outb(DIS_TXR_INT, IER1_CTL); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++, s++) { - wait_for_xmitr(port); - - /* - * Send the character out. - * If a LF, also do CR... - */ - outb(*s, PORT.iobase); - if (*s == 10) { - wait_for_xmitr(port); - outb(13, PORT.iobase); - } - } - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(port); - - /* restore TX/RX interrupt */ - outb(0x00, IER2_8251F); - if (ier1 & 0x01) - outb(ENA_RXR_INT, IER1_CTL); - if (ier1 & 0x02) - outb(ENA_TXE_INT, IER1_CTL); - if (ier1 & 0x04) - outb(ENA_TXR_INT, IER1_CTL); - - /* restore modem status interrupt */ - outb(ier2, IER2_8251F); -} - -static int __init serial98_console_setup(struct console *co, char *options) -{ - struct uart_port *port; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - /* - * Check whether an invalid uart number has been specified, and - * if so, search for the first available port that does have - * console support. - */ - if (co->index >= SERIAL98_NR) - co->index = 0; - port = &serial98_ports[co->index].port; - - /* - * Temporary fix. - */ - spin_lock_init(&port->lock); - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(port, co, baud, parity, bits, flow); -} - -void __init serial98_console_init(void) -{ - register_console(&serial98_console); -} - -#endif /* CONFIG_SERIAL98_CONSOLE */ - - -static int __init serial98_init(void) -{ - int ret; - unsigned char iir1, iir2; - - if (PC9800_8MHz_P()) { - serial98_clk = 8; - serial98_ports[0].port.uartclk = 374400 * 16; - } else { - serial98_clk = 5; - serial98_ports[0].port.uartclk = 460800 * 16; - } - - printk(KERN_INFO "serial98: PC-9801 standard serial port driver Version 0.1alpha\n"); - serial98_ports[0].type = PORT_8251_PC98; - /* Check FIFO exist */ - iir1 = inb(IIR_8251F); - iir2 = inb(IIR_8251F); - if ((iir1 & 0x40) != (iir2 & 0x40) && (iir1 & 0x20) == (iir2 & 0x20)) { - serial98_ports[0].port.iobase = 0x130; - serial98_ports[0].port.fifosize = 16; - serial98_ports[0].rxchk = STAT_8251F_DSR; - serial98_ports[0].txemp = STAT_8251F_TXEMP; - serial98_ports[0].txrdy = STAT_8251F_TXRDY; - serial98_ports[0].rxrdy = STAT_8251F_RXRDY; - serial98_ports[0].brk = STAT_8251F_BRK; - serial98_ports[0].fe = STAT_8251F_FER; - serial98_ports[0].oe = STAT_8251F_OER; - serial98_ports[0].pe = STAT_8251F_PER; - serial98_ports[0].dr = STAT_8251F_DSR; - - if (*(unsigned char*)__va(PC9821SCA_RSFLAGS) & 0x10) - serial98_ports[0].type = PORT_VFAST_PC98; - else { - outb(serial98_ports[0].ext | 0x40, SERIAL98_EXT); - serial98_ports[0].port.uartclk *= 4; - serial98_ports[0].type = PORT_FIFO_PC98; - } - } else if ((serial98_ports[0].ext = inb(SERIAL98_EXT)) != 0xff) { - outb(serial98_ports[0].ext | 0x40, SERIAL98_EXT); - if (inb(SERIAL98_EXT) == (serial98_ports[0].ext | 0x40)) { - serial98_ports[0].port.uartclk *= 4; - serial98_ports[0].type = PORT_19K_PC98; - } else { - serial98_ops.enable_ms = NULL; - outb(serial98_ports[0].ext, SERIAL98_EXT); - } - } - - if (serial98_request_region(serial98_ports[0].type)) - return -EBUSY; - - ret = uart_register_driver(&serial98_reg); - if (ret == 0) { - int i; - - for (i = 0; i < SERIAL98_NR; i++) { - uart_add_one_port(&serial98_reg, - (struct uart_port *)&serial98_ports[i]); - } - } - - return ret; -} - -static void __exit serial98_exit(void) -{ - int i; - - if (serial98_ports[0].type == PORT_19K_PC98 - || serial98_ports[0].type == PORT_FIFO_PC98) - outb(serial98_ports[0].ext, SERIAL98_EXT); - - for (i = 0; i < SERIAL98_NR; i++) { - uart_remove_one_port(&serial98_reg, - (struct uart_port *)&serial98_ports[i]); - } - - uart_unregister_driver(&serial98_reg); -} - -module_init(serial98_init); -module_exit(serial98_exit); - -MODULE_AUTHOR("Osamu Tomita "); -MODULE_DESCRIPTION("PC-9801 standard serial port driver Version 0.1alpha"); -MODULE_LICENSE("GPL"); diff -Nru a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/serial/serial_lh7a40x.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,708 @@ +/* drivers/serial/serial_lh7a40x.c + * + * Copyright (C) 2004 Coastal Environmental Systems + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */ + +/* Driver for Sharp LH7A40X embedded serial ports + * + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * Based on drivers/serial/amba.c, by Deep Blue Solutions Ltd. + * + * --- + * + * This driver supports the embedded UARTs of the Sharp LH7A40X series + * CPUs. While similar to the 16550 and other UART chips, there is + * nothing close to register compatibility. Moreover, some of the + * modem control lines are not available, either in the chip or they + * are lacking in the board-level implementation. + * + * - Use of SIRDIS + * For simplicity, we disable the IR functions of any UART whenever + * we enable it. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(CONFIG_SERIAL_LH7A40X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include + +#include + +#define DEV_MAJOR 204 +#define DEV_MINOR 16 +#define DEV_NR 3 + +#define ISR_LOOP_LIMIT 256 + +#define UR(p,o) _UR ((p)->membase, o) +#define _UR(b,o) (*((volatile unsigned int*)(((unsigned char*) b) + (o)))) +#define BIT_CLR(p,o,m) UR(p,o) = UR(p,o) & (~(unsigned int)m) +#define BIT_SET(p,o,m) UR(p,o) = UR(p,o) | ( (unsigned int)m) + +#define UART_REG_SIZE 32 + +#define UARTEN (0x01) /* UART enable */ +#define SIRDIS (0x02) /* Serial IR disable (UART1 only) */ + +#define RxEmpty (0x10) +#define TxEmpty (0x80) +#define TxFull (0x20) +#define nRxRdy RxEmpty +#define nTxRdy TxFull +#define TxBusy (0x08) + +#define RxBreak (0x0800) +#define RxOverrunError (0x0400) +#define RxParityError (0x0200) +#define RxFramingError (0x0100) +#define RxError (RxBreak | RxOverrunError | RxParityError | RxFramingError) + +#define DCD (0x04) +#define DSR (0x02) +#define CTS (0x01) + +#define RxInt (0x01) +#define TxInt (0x02) +#define ModemInt (0x04) +#define RxTimeoutInt (0x08) + +#define MSEOI (0x10) + +#define WLEN_8 (0x60) +#define WLEN_7 (0x40) +#define WLEN_6 (0x20) +#define WLEN_5 (0x00) +#define WLEN (0x60) /* Mask for all word-length bits */ +#define STP2 (0x08) +#define PEN (0x02) /* Parity Enable */ +#define EPS (0x04) /* Even Parity Set */ +#define FEN (0x10) /* FIFO Enable */ +#define BRK (0x01) /* Send Break */ + + +struct uart_port_lh7a40x { + struct uart_port port; + unsigned int statusPrev; /* Most recently read modem status */ +}; + +static void lh7a40xuart_stop_tx (struct uart_port* port, unsigned int tty_stop) +{ + BIT_CLR (port, UART_R_INTEN, TxInt); +} + +static void lh7a40xuart_start_tx (struct uart_port* port, + unsigned int tty_start) +{ + BIT_SET (port, UART_R_INTEN, TxInt); + + /* *** FIXME: do I need to check for startup of the + transmitter? The old driver did, but AMBA + doesn't . */ +} + +static void lh7a40xuart_stop_rx (struct uart_port* port) +{ + BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt); +} + +static void lh7a40xuart_enable_ms (struct uart_port* port) +{ + BIT_SET (port, UART_R_INTEN, ModemInt); +} + +static void +#ifdef SUPPORT_SYSRQ +lh7a40xuart_rx_chars (struct uart_port* port, struct pt_regs* regs) +#else +lh7a40xuart_rx_chars (struct uart_port* port) +#endif +{ + struct tty_struct* tty = port->info->tty; + int cbRxMax = 256; /* (Gross) limit on receive */ + unsigned int data; /* Received data and status */ + + while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty->flip.work.func((void*)tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + printk(KERN_WARNING "TTY_DONT_FLIP set\n"); + return; + } + } + + data = UR (port, UART_R_DATA); + + *tty->flip.char_buf_ptr = (unsigned char) data; + *tty->flip.flag_buf_ptr = TTY_NORMAL; + ++port->icount.rx; + + if (data & RxError) { /* Quick check, short-circuit */ + if (data & RxBreak) { + data &= ~(RxFramingError | RxParityError); + ++port->icount.brk; + if (uart_handle_break (port)) + continue; + } + else if (data & RxParityError) + ++port->icount.parity; + else if (data & RxFramingError) + ++port->icount.frame; + if (data & RxOverrunError) + ++port->icount.overrun; + + /* Mask by termios, leave Rx'd byte */ + data &= port->read_status_mask | 0xff; + + if (data & RxBreak) + *tty->flip.flag_buf_ptr = TTY_BREAK; + else if (data & RxParityError) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (data & RxFramingError) + *tty->flip.flag_buf_ptr = TTY_FRAME; + } + + if (uart_handle_sysrq_char (port, (unsigned char) data, regs)) + continue; + + if ((data & port->ignore_status_mask) == 0) { + ++tty->flip.flag_buf_ptr; + ++tty->flip.char_buf_ptr; + ++tty->flip.count; + } + if ((data & RxOverrunError) + && tty->flip.count < TTY_FLIPBUF_SIZE) { + /* + * Overrun is special, since it's reported + * immediately, and doesn't affect the current + * character + */ + *tty->flip.char_buf_ptr++ = 0; + *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; + ++tty->flip.count; + } + } + tty_flip_buffer_push (tty); + return; +} + +static void lh7a40xuart_tx_chars (struct uart_port* port) +{ + struct circ_buf* xmit = &port->info->xmit; + int cbTxMax = port->fifosize; + + if (port->x_char) { + UR (port, UART_R_DATA) = port->x_char; + ++port->icount.tx; + port->x_char = 0; + return; + } + if (uart_circ_empty (xmit) || uart_tx_stopped (port)) { + lh7a40xuart_stop_tx (port, 0); + return; + } + + /* Unlike the AMBA UART, the lh7a40x UART does not guarantee + that at least half of the FIFO is empty. Instead, we check + status for every character. Using the AMBA method causes + the transmitter to drop characters. */ + + do { + UR (port, UART_R_DATA) = xmit->buf[xmit->tail]; + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + ++port->icount.tx; + if (uart_circ_empty(xmit)) + break; + } while (!(UR (port, UART_R_STATUS) & nTxRdy) + && cbTxMax--); + + if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS) + uart_write_wakeup (port); + + if (uart_circ_empty (xmit)) + lh7a40xuart_stop_tx (port, 0); +} + +static void lh7a40xuart_modem_status (struct uart_port* port) +{ + unsigned int status = UR (port, UART_R_STATUS); + unsigned int delta + = status ^ ((struct uart_port_lh7a40x*) port)->statusPrev; + + BIT_SET (port, UART_R_RAWISR, MSEOI); /* Clear modem status intr */ + + if (!delta) /* Only happens if we missed 2 transitions */ + return; + + ((struct uart_port_lh7a40x*) port)->statusPrev = status; + + if (delta & DCD) + uart_handle_dcd_change (port, status & DCD); + + if (delta & DSR) + ++port->icount.dsr; + + if (delta & CTS) + uart_handle_cts_change (port, status & CTS); + + wake_up_interruptible (&port->info->delta_msr_wait); +} + +static irqreturn_t lh7a40xuart_int (int irq, void* dev_id, + struct pt_regs* regs) +{ + struct uart_port* port = dev_id; + unsigned int cLoopLimit = ISR_LOOP_LIMIT; + unsigned int isr = UR (port, UART_R_ISR); + + + do { + if (isr & (RxInt | RxTimeoutInt)) +#ifdef SUPPORT_SYSRQ + lh7a40xuart_rx_chars(port, regs); +#else + lh7a40xuart_rx_chars(port); +#endif + if (isr & ModemInt) + lh7a40xuart_modem_status (port); + if (isr & TxInt) + lh7a40xuart_tx_chars (port); + + if (--cLoopLimit == 0) + break; + + isr = UR (port, UART_R_ISR); + } while (isr & (RxInt | TxInt | RxTimeoutInt)); + + return IRQ_HANDLED; +} + +static unsigned int lh7a40xuart_tx_empty (struct uart_port* port) +{ + return (UR (port, UART_R_STATUS) & TxEmpty) ? TIOCSER_TEMT : 0; +} + +static unsigned int lh7a40xuart_get_mctrl (struct uart_port* port) +{ + unsigned int result = 0; + unsigned int status = UR (port, UART_R_STATUS); + + if (status & DCD) + result |= TIOCM_CAR; + if (status & DSR) + result |= TIOCM_DSR; + if (status & CTS) + result |= TIOCM_CTS; + + return result; +} + +static void lh7a40xuart_set_mctrl (struct uart_port* port, unsigned int mctrl) +{ + /* None of the ports supports DTR. UART1 supports RTS through GPIO. */ + /* Note, kernel appears to be setting DTR and RTS on console. */ + + /* *** FIXME: this deserves more work. There's some work in + tracing all of the IO pins. */ +#if 0 + if( port->mapbase == UART1_PHYS) { + gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS); + + if (mctrl & TIOCM_RTS) + gpio->pbdr &= ~GPIOB_UART1_RTS; + else + gpio->pbdr |= GPIOB_UART1_RTS; + } +#endif +} + +static void lh7a40xuart_break_ctl (struct uart_port* port, int break_state) +{ + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + if (break_state == -1) + BIT_SET (port, UART_R_FCON, BRK); /* Assert break */ + else + BIT_CLR (port, UART_R_FCON, BRK); /* Deassert break */ + spin_unlock_irqrestore(&port->lock, flags); +} + +static int lh7a40xuart_startup (struct uart_port* port) +{ + int retval; + + retval = request_irq (port->irq, lh7a40xuart_int, 0, + "serial_lh7a40x", port); + if (retval) + return retval; + + /* Initial modem control-line settings */ + ((struct uart_port_lh7a40x*) port)->statusPrev + = UR (port, UART_R_STATUS); + + /* There is presently no configuration option to enable IR. + Thus, we always disable it. */ + + BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); + BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt); + + return 0; +} + +static void lh7a40xuart_shutdown (struct uart_port* port) +{ + free_irq (port->irq, port); + BIT_CLR (port, UART_R_FCON, BRK | FEN); + BIT_CLR (port, UART_R_CON, UARTEN); +} + +static void lh7a40xuart_set_termios (struct uart_port* port, + struct termios* termios, + struct termios* old) +{ + unsigned int con; + unsigned int inten; + unsigned int fcon; + unsigned long flags; + unsigned int baud; + unsigned int quot; + + baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16); + quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */ + + switch (termios->c_cflag & CSIZE) { + case CS5: + fcon = WLEN_5; + break; + case CS6: + fcon = WLEN_6; + break; + case CS7: + fcon = WLEN_7; + break; + case CS8: + default: + fcon = WLEN_8; + break; + } + if (termios->c_cflag & CSTOPB) + fcon |= STP2; + if (termios->c_cflag & PARENB) { + fcon |= PEN; + if (!(termios->c_cflag & PARODD)) + fcon |= EPS; + } + if (port->fifosize > 1) + fcon |= FEN; + + spin_lock_irqsave (&port->lock, flags); + + uart_update_timeout (port, termios->c_cflag, baud); + + port->read_status_mask = RxOverrunError; + if (termios->c_iflag & INPCK) + port->read_status_mask |= RxFramingError | RxParityError; + if (termios->c_iflag & (BRKINT | PARMRK)) + port->read_status_mask |= RxBreak; + + /* Figure mask for status we ignore */ + port->ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= RxFramingError | RxParityError; + if (termios->c_iflag & IGNBRK) { + port->ignore_status_mask |= RxBreak; + /* Ignore overrun when ignorning parity */ + /* *** FIXME: is this in the right place? */ + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= RxOverrunError; + } + + /* Ignore all receive errors when receive disabled */ + if ((termios->c_cflag & CREAD) == 0) + port->ignore_status_mask |= RxError; + + con = UR (port, UART_R_CON); + inten = (UR (port, UART_R_INTEN) & ~ModemInt); + + if (UART_ENABLE_MS (port, termios->c_cflag)) + inten |= ModemInt; + + BIT_CLR (port, UART_R_CON, UARTEN); /* Disable UART */ + UR (port, UART_R_INTEN) = 0; /* Disable interrupts */ + UR (port, UART_R_BRCON) = quot - 1; /* Set baud rate divisor */ + UR (port, UART_R_FCON) = fcon; /* Set FIFO and frame ctrl */ + UR (port, UART_R_INTEN) = inten; /* Enable interrupts */ + UR (port, UART_R_CON) = con; /* Restore UART mode */ + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char* lh7a40xuart_type (struct uart_port* port) +{ + return port->type == PORT_LH7A40X ? "LH7A40X" : NULL; +} + +static void lh7a40xuart_release_port (struct uart_port* port) +{ + release_mem_region (port->mapbase, UART_REG_SIZE); +} + +static int lh7a40xuart_request_port (struct uart_port* port) +{ + return request_mem_region (port->mapbase, UART_REG_SIZE, + "serial_lh7a40x") != NULL + ? 0 : -EBUSY; +} + +static void lh7a40xuart_config_port (struct uart_port* port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_LH7A40X; + lh7a40xuart_request_port (port); + } +} + +static int lh7a40xuart_verify_port (struct uart_port* port, + struct serial_struct* ser) +{ + int ret = 0; + + if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) + ret = -EINVAL; + if (ser->irq < 0 || ser->irq >= NR_IRQS) + ret = -EINVAL; + if (ser->baud_base < 9600) /* *** FIXME: is this true? */ + ret = -EINVAL; + return ret; +} + +static struct uart_ops lh7a40x_uart_ops = { + .tx_empty = lh7a40xuart_tx_empty, + .set_mctrl = lh7a40xuart_set_mctrl, + .get_mctrl = lh7a40xuart_get_mctrl, + .stop_tx = lh7a40xuart_stop_tx, + .start_tx = lh7a40xuart_start_tx, + .stop_rx = lh7a40xuart_stop_rx, + .enable_ms = lh7a40xuart_enable_ms, + .break_ctl = lh7a40xuart_break_ctl, + .startup = lh7a40xuart_startup, + .shutdown = lh7a40xuart_shutdown, + .set_termios = lh7a40xuart_set_termios, + .type = lh7a40xuart_type, + .release_port = lh7a40xuart_release_port, + .request_port = lh7a40xuart_request_port, + .config_port = lh7a40xuart_config_port, + .verify_port = lh7a40xuart_verify_port, +}; + +static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { + { + .port = { + .membase = (void*) io_p2v (UART1_PHYS), + .mapbase = UART1_PHYS, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART1INTR, + .uartclk = 14745600/2, + .fifosize = 16, + .ops = &lh7a40x_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + }, + { + .port = { + .membase = (void*) io_p2v (UART2_PHYS), + .mapbase = UART2_PHYS, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART2INTR, + .uartclk = 14745600/2, + .fifosize = 16, + .ops = &lh7a40x_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + }, + { + .port = { + .membase = (void*) io_p2v (UART3_PHYS), + .mapbase = UART3_PHYS, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART3INTR, + .uartclk = 14745600/2, + .fifosize = 16, + .ops = &lh7a40x_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, + }, + }, +}; + +#ifndef CONFIG_SERIAL_LH7A40X_CONSOLE +# define LH7A40X_CONSOLE NULL +#else +# define LH7A40X_CONSOLE &lh7a40x_console + + +static void lh7a40xuart_console_write (struct console* co, + const char* s, + unsigned int count) +{ + struct uart_port* port = &lh7a40x_ports[co->index].port; + unsigned int con = UR (port, UART_R_CON); + unsigned int inten = UR (port, UART_R_INTEN); + + + UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */ + BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */ + + for (; count-- > 0; ++s) { + while (UR (port, UART_R_STATUS) & nTxRdy) + ; + UR (port, UART_R_DATA) = *s; + if (*s == '\n') { + while ((UR (port, UART_R_STATUS) & TxBusy)) + ; + UR (port, UART_R_DATA) = '\r'; + } + } + + /* Wait until all characters are sent */ + while (UR (port, UART_R_STATUS) & TxBusy) + ; + + /* Restore control and interrupt mask */ + UR (port, UART_R_CON) = con; + UR (port, UART_R_INTEN) = inten; +} + +static void __init lh7a40xuart_console_get_options (struct uart_port* port, + int* baud, + int* parity, + int* bits) +{ + if (UR (port, UART_R_CON) & UARTEN) { + unsigned int fcon = UR (port, UART_R_FCON); + unsigned int quot = UR (port, UART_R_BRCON) + 1; + + switch (fcon & (PEN | EPS)) { + default: *parity = 'n'; break; + case PEN: *parity = 'o'; break; + case PEN | EPS: *parity = 'e'; break; + } + + switch (fcon & WLEN) { + default: + case WLEN_8: *bits = 8; break; + case WLEN_7: *bits = 7; break; + case WLEN_6: *bits = 6; break; + case WLEN_5: *bits = 5; break; + } + + *baud = port->uartclk/(16*quot); + } +} + +static int __init lh7a40xuart_console_setup (struct console* co, char* options) +{ + struct uart_port* port; + int baud = 38400; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index >= DEV_NR) /* Bounds check on device number */ + co->index = 0; + port = &lh7a40x_ports[co->index].port; + + if (options) + uart_parse_options (options, &baud, &parity, &bits, &flow); + else + lh7a40xuart_console_get_options (port, &baud, &parity, &bits); + + return uart_set_options (port, co, baud, parity, bits, flow); +} + +extern struct uart_driver lh7a40x_reg; +static struct console lh7a40x_console = { + .name = "ttyAM", + .write = lh7a40xuart_console_write, + .device = uart_console_device, + .setup = lh7a40xuart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &lh7a40x_reg, +}; + +static int __init lh7a40xuart_console_init(void) +{ + register_console (&lh7a40x_console); + return 0; +} + +console_initcall (lh7a40xuart_console_init); + +#endif + +static struct uart_driver lh7a40x_reg = { + .owner = THIS_MODULE, + .driver_name = "ttyAM", + .dev_name = "ttyAM", + .major = DEV_MAJOR, + .minor = DEV_MINOR, + .nr = DEV_NR, + .cons = LH7A40X_CONSOLE, +}; + +static int __init lh7a40xuart_init(void) +{ + int ret; + + printk (KERN_INFO "serial: LH7A40X serial driver\n"); + + ret = uart_register_driver (&lh7a40x_reg); + + if (ret == 0) { + int i; + + for (i = 0; i < DEV_NR; i++) + uart_add_one_port (&lh7a40x_reg, + &lh7a40x_ports[i].port); + } + return ret; +} + +static void __exit lh7a40xuart_exit(void) +{ + int i; + + for (i = 0; i < DEV_NR; i++) + uart_remove_one_port (&lh7a40x_reg, &lh7a40x_ports[i].port); + + uart_unregister_driver (&lh7a40x_reg); +} + +module_init (lh7a40xuart_init); +module_exit (lh7a40xuart_exit); + +MODULE_AUTHOR ("Marc Singer"); +MODULE_DESCRIPTION ("Sharp LH7A40X serial port driver"); +MODULE_LICENSE ("GPL"); diff -Nru a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c --- a/drivers/serial/sh-sci.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/serial/sh-sci.c 2004-06-26 17:09:20 -07:00 @@ -90,12 +90,12 @@ #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) -static void handle_error(struct sci_port *port) +static void handle_error(struct uart_port *port) { /* Clear error flags */ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); } -static int get_char(struct sci_port *port) +static int get_char(struct uart_port *port) { unsigned long flags; unsigned short status; @@ -332,11 +332,11 @@ #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) #if defined(CONFIG_CPU_SH3) -/* For SH7707, SH7709, SH7709A, SH7729 */ +/* For SH7707, SH7709, SH7709A, SH7729, SH7300*/ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) { unsigned int fcr_val = 0; - +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) /* SH7300 doesn't use RTS/CTS */ { unsigned short data; @@ -360,6 +360,7 @@ /* Set /RTS2 (bit6) = 0 */ ctrl_outb(data&0xbf, SCPDR); } +#endif sci_out(port, SCFCR, fcr_val); } @@ -420,7 +421,7 @@ #if !defined(SCI_ONLY) if (port->type == PORT_SCIF) { - txroom = 16 - (sci_in(port, SCFDR)>>8); + txroom = SCIF_TXROOM_MAX - (sci_in(port, SCFDR)>>8); } else { txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0; } @@ -488,7 +489,7 @@ while (1) { #if !defined(SCI_ONLY) if (port->type == PORT_SCIF) { - count = sci_in(port, SCFDR)&0x001f; + count = sci_in(port, SCFDR)&SCIF_RFDC_MASK ; } else { count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0; } @@ -671,8 +672,7 @@ pr_debug("sci: BREAK detected\n"); } -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) || \ - defined(CONFIG_CPU_SUBTYPE_SH7760) +#if defined(SCIF_ORER) /* XXX: Handle SCIF overrun error */ if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { sci_out(port, SCLSR, 0); @@ -726,6 +726,19 @@ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); } } else { +#if defined(SCIF_ORER) + if((sci_in(port, SCLSR) & SCIF_ORER) != 0) { + struct tty_struct *tty = port->info->tty; + + sci_out(port, SCLSR, 0); + if(tty->flip.countflip.flag_buf_ptr++ = TTY_OVERRUN; + tty->flip.count++; + tty_flip_buffer_push(tty); + pr_debug("scif: overrun error\n"); + } + } +#endif sci_rx_interrupt(irq, ptr, regs); } @@ -748,6 +761,30 @@ return IRQ_HANDLED; } +static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs) +{ + unsigned short ssr_status, scr_status; + struct uart_port *port = ptr; + + ssr_status = sci_in(port,SCxSR); + scr_status = sci_in(port,SCSCR); + + /* Tx Interrupt */ + if ((ssr_status&0x0020) && (scr_status&0x0080)) + sci_tx_interrupt(irq, ptr, regs); + /* Rx Interrupt */ + if ((ssr_status&0x0002) && (scr_status&0x0040)) + sci_rx_interrupt(irq, ptr, regs); + /* Error Interrupt */ + if ((ssr_status&0x0080) && (scr_status&0x0400)) + sci_er_interrupt(irq, ptr, regs); + /* Break Interrupt */ + if ((ssr_status&0x0010) && (scr_status&0x0200)) + sci_br_interrupt(irq, ptr, regs); + + return IRQ_HANDLED; +} + #ifdef CONFIG_CPU_FREQ /* * Here we define a transistion notifier so that we can update all of our @@ -797,14 +834,26 @@ const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", "SCI Transmit Data Empty", "SCI Break" }; - for (i = 0; i < ARRAY_SIZE(handlers); i++) { - if (!port->irqs[i]) - continue; - if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT, - desc[i], port)) { + if (port->irqs[0] == port->irqs[1]) { + if (!port->irqs[0]) { + printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n"); + return -ENODEV; + } + if (request_irq(port->irqs[0], sci_mpxed_interrupt, SA_INTERRUPT, + "sci", port)) { printk(KERN_ERR "sci: Cannot allocate irq.\n"); return -ENODEV; } + } else { + for (i = 0; i < ARRAY_SIZE(handlers); i++) { + if (!port->irqs[i]) + continue; + if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT, + desc[i], port)) { + printk(KERN_ERR "sci: Cannot allocate irq.\n"); + return -ENODEV; + } + } } return 0; @@ -814,11 +863,18 @@ { int i; - for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { - if (!port->irqs[i]) - continue; + if (port->irqs[0] == port->irqs[1]) { + if (!port->irqs[0]) + printk("sci: sci_free_irq error\n"); + else + free_irq(port->irqs[0], port); + } else { + for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { + if (!port->irqs[i]) + continue; - free_irq(port->irqs[i], port); + free_irq(port->irqs[i], port); + } } } @@ -873,7 +929,7 @@ /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ local_irq_save(flags); ctrl = sci_in(port, SCSCR); - ctrl |= SCI_CTRL_FLAGS_RIE; + ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; sci_out(port, SCSCR, ctrl); local_irq_restore(flags); } @@ -886,7 +942,7 @@ /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ local_irq_save(flags); ctrl = sci_in(port, SCSCR); - ctrl &= ~SCI_CTRL_FLAGS_RIE; + ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); sci_out(port, SCSCR, ctrl); local_irq_restore(flags); } @@ -976,7 +1032,7 @@ case 38400: t = BPS_38400; break; case 57600: t = BPS_57600; break; case 115200: t = BPS_115200; break; - default: t = BPS_115200; break; + default: t = SCBRR_VALUE(baud); break; } if (t > 0) { @@ -1026,6 +1082,13 @@ struct sci_port *s = &sci_ports[port->line]; port->type = s->type; + +#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) + if (port->mapbase == 0) + port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); + + port->membase = (void *)port->mapbase; +#endif } static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) @@ -1119,6 +1182,36 @@ .irqs = SH3_IRDA_IRQS, .init_pins = sci_init_pins_irda, } +#elif defined(CONFIG_CPU_SUBTYPE_SH7300) + { + .port = { + .membase = (void *)0xA4430000, + .mapbase = 0xA4430000, + .iotype = SERIAL_IO_MEM, + .irq = 25, + .ops = &sci_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + .type = PORT_SCIF, + .irqs = SH7300_SCIF0_IRQS, + .init_pins = sci_init_pins_scif, + }, +#elif defined(CONFIG_SH_RTS7751R2D) + { + .port = { + .membase = (void *)0xffe80000, + .mapbase = 0xffe80000, + .iotype = SERIAL_IO_MEM, + .irq = 43, + .ops = &sci_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + .type = PORT_SCIF, + .irqs = SH4_SCIF_IRQS, + .init_pins = sci_init_pins_scif, + }, #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) { .port = { @@ -1220,6 +1313,19 @@ .irqs = SH4_SCIF_IRQS, .init_pins = sci_init_pins_scif, }, +#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) + { + .port = { + .iotype = SERIAL_IO_MEM, + .irq = 42, + .ops = &sci_uart_ops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + .type = PORT_SCIF, + .irqs = SH5_SCIF_IRQS, + .init_pins = sci_init_pins_scif, + }, #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) { .port = { @@ -1338,6 +1444,11 @@ port = &serial_console_port->port; port->type = serial_console_port->type; +#ifdef CONFIG_SUPERH64 + /* This is especially needed on sh64 to remap the SCIF */ + sci_config_port(port, 0); +#endif + /* * We need to set the initial uartclk here, since otherwise it will * only ever be setup at sci_init() time. @@ -1374,18 +1485,7 @@ static int __init sci_console_init(void) { -#ifdef CONFIG_SH_EARLY_PRINTK - extern void sh_console_unregister(void); - - /* - * Now that the real console is available, unregister the one we - * used while first booting. - */ - sh_console_unregister(); -#endif - register_console(&serial_console); - return 0; } @@ -1452,7 +1552,6 @@ static int __init kgdb_console_init(void) { register_console(&kgdb_console); - return 0; } diff -Nru a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h --- a/drivers/serial/sh-sci.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/serial/sh-sci.h 2004-06-26 17:09:16 -07:00 @@ -7,6 +7,7 @@ * Copyright (C) 2000 Greg Banks * Copyright (C) 2002, 2003 Paul Mundt * Modified to support multiple serial ports. Stuart Menefy (May 2000). + * Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003). * Modified to support H8/300 Series Yoshinori Sato (Feb 2004). */ #include @@ -36,12 +37,14 @@ #define SH7760_SCIF0_IRQS { 52, 53, 55, 54 } #define SH7760_SCIF1_IRQS { 72, 73, 75, 74 } #define SH7760_SCIF2_IRQS { 76, 77, 79, 78 } +#define SH7300_SCIF0_IRQS {80, 80, 80, 80 } #define H8300H_SCI_IRQS0 {52, 53, 54, 0 } #define H8300H_SCI_IRQS1 {56, 57, 58, 0 } #define H8300H_SCI_IRQS2 {60, 61, 62, 0 } #define H8S_SCI_IRQS0 {88, 89, 90, 0 } #define H8S_SCI_IRQS1 {92, 93, 94, 0 } #define H8S_SCI_IRQS2 {96, 97, 98, 0 } +#define SH5_SCIF_IRQS {39, 40, 42, 0 } #if defined(CONFIG_CPU_SUBTYPE_SH7708) # define SCI_NPORTS 1 @@ -54,6 +57,13 @@ # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */ # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCI_AND_SCIF +#elif defined(CONFIG_SH_RTS7751R2D) +# define SCI_NPORTS 1 +# define SCSPTR1 0xffe0001c /* 8 bit SCI */ +# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ +# define SCIF_ORER 0x0001 /* overrun error bit */ +# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) # define SCI_NPORTS 2 # define SCSPTR1 0xffe0001c /* 8 bit SCI */ @@ -68,9 +78,15 @@ # define SCSPTR0 0xfe600000 /* 16 bit SCIF */ # define SCSPTR1 0xfe610000 /* 16 bit SCIF */ # define SCSPTR2 0xfe620000 /* 16 bit SCIF */ -# define SCIF_ORDER 0x0001 /* overrun error bit */ +# define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH7300) +# define SCI_NPORTS 1 +# define SCPCR 0xA4050116 /* 16 bit SCIF */ +# define SCPDR 0xA4050136 /* 16 bit SCIF */ +# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ +# define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) # define SCI_NPORTS 2 # define SCSPTR1 0xffe00020 /* 16 bit SCIF */ @@ -78,6 +94,22 @@ # define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) +# include +# define SCIF_BASE_ADDR 0x01030000 +# define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR +# define SCIF_PTR2_OFFS 0x0000020 +# define SCIF_LSR2_OFFS 0x0000024 +# define SCI_NPORTS 1 +# define SCI_INIT { \ + { {}, PORT_SCIF, 0, \ + SH5_SCIF_IRQS, sci_init_pins_scif } \ +} +# define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */ +# define SCLSR2 ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */ +# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0, + TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) # define SCI_NPORTS 3 # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ @@ -97,7 +129,11 @@ #define SCI_CTRL_FLAGS_RIE 0x40 /* all */ #define SCI_CTRL_FLAGS_TE 0x20 /* all */ #define SCI_CTRL_FLAGS_RE 0x10 /* all */ -/* SCI_CTRL_FLAGS_REIE 0x08 * 7750 SCIF */ +#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) +#define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ +#else +#define SCI_CTRL_FLAGS_REIE 0 +#endif /* SCI_CTRL_FLAGS_MPIE 0x08 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ /* SCI_CTRL_FLAGS_TEIE 0x04 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ /* SCI_CTRL_FLAGS_CKE1 0x02 * all */ @@ -125,7 +161,16 @@ #define SCIF_RDF 0x0002 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */ #define SCIF_DR 0x0001 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */ +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCIF_ORER 0x0200 +#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) +#define SCIF_RFDC_MASK 0x007f +#define SCIF_TXROOM_MAX 64 +#else #define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK) +#define SCIF_RFDC_MASK 0x001f +#define SCIF_TXROOM_MAX 16 +#endif #if defined(SCI_ONLY) # define SCxSR_TEND(port) SCI_TEND @@ -145,14 +190,25 @@ # define SCxSR_ERRORS(port) SCIF_ERRORS # define SCxSR_RDxF(port) SCIF_RDF # define SCxSR_TDxE(port) SCIF_TDFE +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +# define SCxSR_ORER(port) SCIF_ORER +#else # define SCxSR_ORER(port) 0x0000 +#endif # define SCxSR_FER(port) SCIF_FER # define SCxSR_PER(port) SCIF_PER # define SCxSR_BRK(port) SCIF_BRK +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +# define SCxSR_RDxF_CLEAR(port) (sci_in(port,SCxSR)&0xfffc) +# define SCxSR_ERROR_CLEAR(port) (sci_in(port,SCxSR)&0xfd73) +# define SCxSR_TDxE_CLEAR(port) (sci_in(port,SCxSR)&0xffdf) +# define SCxSR_BREAK_CLEAR(port) (sci_in(port,SCxSR)&0xffe3) +#else # define SCxSR_RDxF_CLEAR(port) 0x00fc # define SCxSR_ERROR_CLEAR(port) 0x0073 # define SCxSR_TDxE_CLEAR(port) 0x00df # define SCxSR_BREAK_CLEAR(port) 0x00e3 +#endif #else # define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) # define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) @@ -171,6 +227,7 @@ /* SCFCR */ #define SCFCR_RFRST 0x0002 #define SCFCR_TFRST 0x0004 +#define SCFCR_TCRST 0x4000 #define SCFCR_MCE 0x0008 #define SCI_MAJOR 204 @@ -250,12 +307,17 @@ } #ifdef CONFIG_CPU_SH3 +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCIF_FNS(name, scif_offset, scif_size) \ + CPU_SCIF_FNS(name, scif_offset, scif_size) +#else #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ h8_sci_offset, h8_sci_size) \ CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size) #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size) +#endif #elif defined(__H8300H__) || defined(__H8300S__) #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ @@ -271,6 +333,19 @@ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +SCIF_FNS(SCSMR, 0x00, 16) +SCIF_FNS(SCBRR, 0x04, 8) +SCIF_FNS(SCSCR, 0x08, 16) +SCIF_FNS(SCTDSR, 0x0c, 8) +SCIF_FNS(SCFER, 0x10, 16) +SCIF_FNS(SCxSR, 0x14, 16) +SCIF_FNS(SCFCR, 0x18, 16) +SCIF_FNS(SCFDR, 0x1c, 16) +SCIF_FNS(SCxTDR, 0x20, 8) +SCIF_FNS(SCxRDR, 0x24, 8) +SCIF_FNS(SCLSR, 0x24, 16) +#else /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ /* name off sz off sz off sz off sz off sz*/ SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16, 0x00, 8) @@ -281,8 +356,9 @@ SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) +SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) SCIF_FNS(SCLSR, 0, 0, 0x24, 16) - +#endif #define sci_in(port, reg) sci_##reg##_in(port) #define sci_out(port, reg, value) sci_##reg##_out(port, value) @@ -369,6 +445,13 @@ if (port->mapbase == 0xfe620000) return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ } +#elif defined(CONFIG_CPU_SUBTYPE_SH7300) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xa4430000) + return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCIF0 */ + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) static inline int sci_rxd_in(struct uart_port *port) { @@ -378,6 +461,11 @@ return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ } +#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) +static inline int sci_rxd_in(struct uart_port *port) +{ + return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */ +} #elif defined(__H8300H__) || defined(__H8300S__) static inline int sci_rxd_in(struct uart_port *port) { @@ -420,7 +508,9 @@ #define PCLK (current_cpu_data.module_clock) -#if !defined(__H8300H__) && !defined(__H8300S__) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCBRR_VALUE(bps) ((PCLK+16*bps)/(16*bps)-1) +#elif !defined(__H8300H__) && !defined(__H8300S__) #define SCBRR_VALUE(bps) ((PCLK+16*bps)/(32*bps)-1) #else #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) diff -Nru a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c --- a/drivers/telephony/ixj.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/telephony/ixj.c 2004-06-26 17:09:15 -07:00 @@ -461,8 +461,8 @@ static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf); static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr); static int ixj_init_tone(IXJ *j, IXJ_TONE * ti); -static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp); -static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp); +static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp); +static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp); /* Serial Control Interface funtions */ static int SCI_Control(IXJ *j, int control); static int SCI_Prepare(IXJ *j); @@ -2855,7 +2855,7 @@ } } -static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos) +static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos) { unsigned long i = *ppos; IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode)); @@ -2910,7 +2910,7 @@ } } -static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length, +static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos) { int pre_retval; @@ -2935,7 +2935,7 @@ return read_retval; } -static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos) +static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos) { unsigned long i = *ppos; IXJ *j = file_p->private_data; @@ -2989,7 +2989,7 @@ return min(count, j->write_buffer_size); } -static ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos) +static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos) { int pre_retval; ssize_t write_retval = 0; @@ -5938,31 +5938,41 @@ ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */ } -static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp) +static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp) { - IXJ_CADENCE *lcp; + ixj_cadence *lcp; + IXJ_CADENCE_ELEMENT __user *cep; IXJ_CADENCE_ELEMENT *lcep; IXJ_TONE ti; + int err; - lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL); + lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL); if (lcp == NULL) return -ENOMEM; - if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT) ) - { - kfree(lcp); - return -EFAULT; - } + + err = -EFAULT; + if (copy_from_user(&lcp->elements_used, + &cp->elements_used, sizeof(int))) + goto out; + if (copy_from_user(&lcp->termination, + &cp->termination, sizeof(IXJ_CADENCE_TERM))) + goto out; + if (get_user(cep, &cp->ce)) + goto out; + + err = -EINVAL; + if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT)) + goto out; + + err = -ENOMEM; lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL); - if (lcep == NULL) { - kfree(lcp); - return -ENOMEM; - } - if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used)) - { - kfree(lcep); - kfree(lcp); - return -EFAULT; - } + if (!lcep) + goto out; + + err = -EFAULT; + if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used)) + goto out1; + if (j->cadence_t) { kfree(j->cadence_t->ce); kfree(j->cadence_t); @@ -5982,9 +5992,14 @@ } ixj_play_tone(j, lcp->ce[0].index); return 1; +out1: + kfree(lcep); +out: + kfree(lcp); + return err; } -static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp) +static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp) { IXJ_FILTER_CADENCE *lcp; lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL); @@ -5994,7 +6009,7 @@ } return -ENOMEM; } - if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE))) { + if (copy_from_user(lcp, cp, sizeof(IXJ_FILTER_CADENCE))) { if(ixjdebug & 0x0001) { printk(KERN_INFO "Could not copy cadence to kernel\n"); } @@ -6206,6 +6221,7 @@ IXJ_TONE ti; IXJ_FILTER jf; IXJ_FILTER_RAW jfr; + void __user *argp = (void __user *)arg; unsigned int raise, mant; unsigned int minor = iminor(inode); @@ -6251,7 +6267,7 @@ retval = j->serial; break; case IXJCTL_VERSION: - if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision))) + if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision))) retval = -EFAULT; break; case PHONE_RING_CADENCE: @@ -6259,7 +6275,7 @@ break; case IXJCTL_CIDCW: if(arg) { - if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) { + if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { retval = -EFAULT; break; } @@ -6274,7 +6290,7 @@ /* Fall through */ case PHONE_RING_START: if(arg) { - if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) { + if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { retval = -EFAULT; break; } @@ -6432,22 +6448,22 @@ samplerate = arg; break; case IXJCTL_DRYBUFFER_READ: - put_user(j->drybuffer, (unsigned long *) arg); + put_user(j->drybuffer, (unsigned long __user *) argp); break; case IXJCTL_DRYBUFFER_CLEAR: j->drybuffer = 0; break; case IXJCTL_FRAMES_READ: - put_user(j->framesread, (unsigned long *) arg); + put_user(j->framesread, (unsigned long __user *) argp); break; case IXJCTL_FRAMES_WRITTEN: - put_user(j->frameswritten, (unsigned long *) arg); + put_user(j->frameswritten, (unsigned long __user *) argp); break; case IXJCTL_READ_WAIT: - put_user(j->read_wait, (unsigned long *) arg); + put_user(j->read_wait, (unsigned long __user *) argp); break; case IXJCTL_WRITE_WAIT: - put_user(j->write_wait, (unsigned long *) arg); + put_user(j->write_wait, (unsigned long __user *) argp); break; case PHONE_MAXRINGS: j->maxrings = arg; @@ -6573,7 +6589,7 @@ 12, 10, 16, 9, 8, 48, 5, 40, 40, 80, 40, 40, 6 }; - if(copy_from_user(&pd, (void *)arg, sizeof(pd))) { + if(copy_from_user(&pd, argp, sizeof(pd))) { retval = -EFAULT; break; } @@ -6590,7 +6606,7 @@ default:val=proto_size[pd.type]*3;break; } pd.buf_min=pd.buf_max=pd.buf_opt=val; - if(copy_to_user((void *)arg, &pd, sizeof(pd))) + if(copy_to_user(argp, &pd, sizeof(pd))) retval = -EFAULT; break; } @@ -6644,7 +6660,7 @@ ixj_write_vmwi(j, arg); break; case IXJCTL_CID: - if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID))) + if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) retval = -EFAULT; j->ex.bits.caller_id = 0; break; @@ -6666,13 +6682,13 @@ break; case PHONE_CAPABILITIES_LIST: add_caps(j); - if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps)) + if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) retval = -EFAULT; break; case PHONE_CAPABILITIES_CHECK: { struct phone_capability cap; - if (copy_from_user(&cap, (char *) arg, sizeof(cap))) + if (copy_from_user(&cap, argp, sizeof(cap))) retval = -EFAULT; else { add_caps(j); @@ -6688,12 +6704,12 @@ j->ex.bits.pstn_ring = 0; break; case IXJCTL_SET_FILTER: - if (copy_from_user(&jf, (char *) arg, sizeof(jf))) + if (copy_from_user(&jf, argp, sizeof(jf))) retval = -EFAULT; retval = ixj_init_filter(j, &jf); break; case IXJCTL_SET_FILTER_RAW: - if (copy_from_user(&jfr, (char *) arg, sizeof(jfr))) + if (copy_from_user(&jfr, argp, sizeof(jfr))) retval = -EFAULT; else retval = ixj_init_filter_raw(j, &jfr); @@ -6705,19 +6721,19 @@ retval = j->filter_hist[arg]; break; case IXJCTL_INIT_TONE: - if (copy_from_user(&ti, (char *) arg, sizeof(ti))) + if (copy_from_user(&ti, argp, sizeof(ti))) retval = -EFAULT; else retval = ixj_init_tone(j, &ti); break; case IXJCTL_TONE_CADENCE: - retval = ixj_build_cadence(j, (IXJ_CADENCE *) arg); + retval = ixj_build_cadence(j, argp); break; case IXJCTL_FILTER_CADENCE: - retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg); + retval = ixj_build_filter_cadence(j, argp); break; case IXJCTL_SIGCTL: - if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF))) { + if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) { retval = -EFAULT; break; } diff -Nru a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h --- a/drivers/telephony/ixj.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/telephony/ixj.h 2004-06-26 17:09:21 -07:00 @@ -1167,6 +1167,12 @@ ******************************************************************************/ typedef struct { + int elements_used; + IXJ_CADENCE_TERM termination; + IXJ_CADENCE_ELEMENT *ce; +} ixj_cadence; + +typedef struct { struct phone_device p; struct timer_list timer; unsigned int board; @@ -1220,8 +1226,8 @@ char tone_index; char tone_state; char maxrings; - IXJ_CADENCE *cadence_t; - IXJ_CADENCE *cadence_r; + ixj_cadence *cadence_t; + ixj_cadence *cadence_r; int tone_cadence_state; IXJ_CADENCE_F cadence_f[6]; DTMF dtmf; diff -Nru a/drivers/usb/Kconfig b/drivers/usb/Kconfig --- a/drivers/usb/Kconfig 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/Kconfig 2004-06-26 17:09:16 -07:00 @@ -7,7 +7,7 @@ # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. config USB tristate "Support for Host-side USB" - depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610 + depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610 || ARCH_LH7A404 ---help--- Universal Serial Bus (USB) is a specification for a serial bus subsystem which offers higher speeds and more features than the diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c --- a/drivers/usb/class/audio.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/class/audio.c 2004-06-26 17:09:21 -07:00 @@ -212,9 +212,6 @@ #define dprintk(x) -#undef abs -extern int abs(int __x) __attribute_const__; /* Shut up warning */ - /* --------------------------------------------------------------------- */ /* @@ -398,17 +395,6 @@ /* --------------------------------------------------------------------- */ -/* prevent picking up a bogus abs macro */ -#undef abs -static inline int abs(int x) -{ - if (x < 0) - return -x; - return x; -} - -/* --------------------------------------------------------------------- */ - static inline unsigned ld2(unsigned int x) { unsigned r = 0; @@ -2008,6 +1994,7 @@ { struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data; int i, j, val; + int __user *user_arg = (int __user *)arg; if (!ms->state->usbdev) return -ENODEV; @@ -2034,7 +2021,7 @@ return 0; } if (cmd == OSS_GETVERSION) - return put_user(SOUND_VERSION, (int *)arg); + return put_user(SOUND_VERSION, user_arg); if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) return -EINVAL; if (_IOC_DIR(cmd) == _IOC_READ) { @@ -2043,27 +2030,27 @@ val = get_rec_src(ms); if (val < 0) return val; - return put_user(val, (int *)arg); + return put_user(val, user_arg); case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ for (val = i = 0; i < ms->numch; i++) val |= 1 << ms->ch[i].osschannel; - return put_user(val, (int *)arg); + return put_user(val, user_arg); case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ for (val = i = 0; i < ms->numch; i++) if (ms->ch[i].slctunitid) val |= 1 << ms->ch[i].osschannel; - return put_user(val, (int *)arg); + return put_user(val, user_arg); case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ for (val = i = 0; i < ms->numch; i++) if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) val |= 1 << ms->ch[i].osschannel; - return put_user(val, (int *)arg); + return put_user(val, user_arg); case SOUND_MIXER_CAPS: - return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg); + return put_user(SOUND_CAP_EXCL_INPUT, user_arg); default: i = _IOC_NR(cmd); @@ -2071,7 +2058,7 @@ return -EINVAL; for (j = 0; j < ms->numch; j++) { if (ms->ch[j].osschannel == i) { - return put_user(ms->ch[j].value, (int *)arg); + return put_user(ms->ch[j].value, user_arg); } } return -EINVAL; @@ -2082,7 +2069,7 @@ ms->modcnt++; switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; return set_rec_src(ms, val); @@ -2093,11 +2080,11 @@ for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++); if (j >= ms->numch) return -EINVAL; - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; if (wrmixer(ms, j, val)) return -EIO; - return put_user(ms->ch[j].value, (int *)arg); + return put_user(ms->ch[j].value, user_arg); } } @@ -2370,6 +2357,7 @@ { struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; struct usb_audio_state *s = as->state; + int __user *user_arg = (int __user *)arg; unsigned long flags; audio_buf_info abinfo; count_info cinfo; @@ -2387,7 +2375,7 @@ #endif switch (cmd) { case OSS_GETVERSION: - return put_user(SOUND_VERSION, (int *)arg); + return put_user(SOUND_VERSION, user_arg); case SNDCTL_DSP_SYNC: if (file->f_mode & FMODE_WRITE) @@ -2399,7 +2387,7 @@ case SNDCTL_DSP_GETCAPS: return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | - DSP_CAP_MMAP | DSP_CAP_BATCH, (int *)arg); + DSP_CAP_MMAP | DSP_CAP_BATCH, user_arg); case SNDCTL_DSP_RESET: if (file->f_mode & FMODE_WRITE) { @@ -2413,7 +2401,7 @@ return 0; case SNDCTL_DSP_SPEED: - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; if (val >= 0) { if (val < 4000) @@ -2423,10 +2411,12 @@ if (set_format(as, file->f_mode, AFMT_QUERY, val)) return -EIO; } - return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg); + return put_user((file->f_mode & FMODE_READ) ? + as->usbin.dma.srate : as->usbout.dma.srate, + user_arg); case SNDCTL_DSP_STEREO: - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; if (val) @@ -2438,7 +2428,7 @@ return 0; case SNDCTL_DSP_CHANNELS: - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; if (val != 0) { val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; @@ -2450,14 +2440,14 @@ return -EIO; } val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; - return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg); + return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg); case SNDCTL_DSP_GETFMTS: /* Returns a mask */ return put_user(AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE | - AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, (int *)arg); + AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, user_arg); case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; if (val != AFMT_QUERY) { if (hweight32(val) != 1) @@ -2471,7 +2461,7 @@ return -EIO; } val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; - return put_user(val2 & ~AFMT_STEREO, (int *)arg); + return put_user(val2 & ~AFMT_STEREO, user_arg); case SNDCTL_DSP_POST: return 0; @@ -2482,10 +2472,10 @@ val |= PCM_ENABLE_INPUT; if (file->f_mode & FMODE_WRITE && as->usbout.flags & FLG_RUNNING) val |= PCM_ENABLE_OUTPUT; - return put_user(val, (int *)arg); + return put_user(val, user_arg); case SNDCTL_DSP_SETTRIGGER: - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; if (file->f_mode & FMODE_READ) { if (val & PCM_ENABLE_INPUT) { @@ -2543,7 +2533,7 @@ spin_lock_irqsave(&as->lock, flags); val = as->usbout.dma.count; spin_unlock_irqrestore(&as->lock, flags); - return put_user(val, (int *)arg); + return put_user(val, user_arg); case SNDCTL_DSP_GETIPTR: if (!(file->f_mode & FMODE_READ)) @@ -2577,14 +2567,14 @@ if (file->f_mode & FMODE_WRITE) { if ((val = prog_dmabuf_out(as))) return val; - return put_user(as->usbout.dma.fragsize, (int *)arg); + return put_user(as->usbout.dma.fragsize, user_arg); } if ((val = prog_dmabuf_in(as))) return val; - return put_user(as->usbin.dma.fragsize, (int *)arg); + return put_user(as->usbin.dma.fragsize, user_arg); case SNDCTL_DSP_SETFRAGMENT: - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; if (file->f_mode & FMODE_READ) { as->usbin.dma.ossfragshift = val & 0xffff; @@ -2612,7 +2602,7 @@ if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) || (file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision)) return -EINVAL; - if (get_user(val, (int *)arg)) + if (get_user(val, user_arg)) return -EFAULT; if (val != 1 && val != 2 && val != 4) return -EINVAL; @@ -2623,15 +2613,17 @@ return 0; case SOUND_PCM_READ_RATE: - return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg); + return put_user((file->f_mode & FMODE_READ) ? + as->usbin.dma.srate : as->usbout.dma.srate, + user_arg); case SOUND_PCM_READ_CHANNELS: val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; - return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg); + return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg); case SOUND_PCM_READ_BITS: val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; - return put_user(AFMT_IS16BIT(val2) ? 16 : 8, (int *)arg); + return put_user(AFMT_IS16BIT(val2) ? 16 : 8, user_arg); case SOUND_PCM_WRITE_FILTER: case SNDCTL_DSP_SETSYNCRO: diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c --- a/drivers/usb/class/cdc-acm.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/class/cdc-acm.c 2004-06-26 17:09:19 -07:00 @@ -27,6 +27,7 @@ * v0.22 - probe only the control interface. if usbcore doesn't choose the * config we want, sysadmin changes bConfigurationValue in sysfs. * v0.23 - use softirq for rx processing, as needed by tty layer + * v0.24 - change probe method to evaluate CDC union descriptor */ /* @@ -60,6 +61,8 @@ #include #include +#include "cdc-acm.h" + /* * Version Information */ @@ -67,102 +70,12 @@ #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik" #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" -/* - * CMSPAR, some architectures can't have space and mark parity. - */ - -#ifndef CMSPAR -#define CMSPAR 0 -#endif - -/* - * Major and minor numbers. - */ - -#define ACM_TTY_MAJOR 166 -#define ACM_TTY_MINORS 32 - -/* - * Requests. - */ - -#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE) - -#define ACM_REQ_COMMAND 0x00 -#define ACM_REQ_RESPONSE 0x01 -#define ACM_REQ_SET_FEATURE 0x02 -#define ACM_REQ_GET_FEATURE 0x03 -#define ACM_REQ_CLEAR_FEATURE 0x04 - -#define ACM_REQ_SET_LINE 0x20 -#define ACM_REQ_GET_LINE 0x21 -#define ACM_REQ_SET_CONTROL 0x22 -#define ACM_REQ_SEND_BREAK 0x23 - -/* - * IRQs. - */ - -#define ACM_IRQ_NETWORK 0x00 -#define ACM_IRQ_LINE_STATE 0x20 - -/* - * Output control lines. - */ - -#define ACM_CTRL_DTR 0x01 -#define ACM_CTRL_RTS 0x02 - -/* - * Input control lines and line errors. - */ - -#define ACM_CTRL_DCD 0x01 -#define ACM_CTRL_DSR 0x02 -#define ACM_CTRL_BRK 0x04 -#define ACM_CTRL_RI 0x08 - -#define ACM_CTRL_FRAMING 0x10 -#define ACM_CTRL_PARITY 0x20 -#define ACM_CTRL_OVERRUN 0x40 - -/* - * Line speed and caracter encoding. - */ - -struct acm_line { - __u32 speed; - __u8 stopbits; - __u8 parity; - __u8 databits; -} __attribute__ ((packed)); - -/* - * Internal driver structures. - */ - -struct acm { - struct usb_device *dev; /* the corresponding usb device */ - struct usb_interface *control; /* control interface */ - struct usb_interface *data; /* data interface */ - struct tty_struct *tty; /* the corresponding tty */ - struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ - struct acm_line line; /* line coding (bits, stop, parity) */ - struct work_struct work; /* work queue entry for line discipline waking up */ - struct tasklet_struct bh; /* rx processing */ - unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ - unsigned int ctrlout; /* output control lines (DTR, RTS) */ - unsigned int writesize; /* max packet size for the output bulk endpoint */ - unsigned int used; /* someone has this acm's device open */ - unsigned int minor; /* acm minor number */ - unsigned char throttle; /* throttled by tty layer */ - unsigned char clocal; /* termios CLOCAL */ -}; - static struct usb_driver acm_driver; static struct tty_driver *acm_tty_driver; static struct acm *acm_table[ACM_TTY_MINORS]; +static DECLARE_MUTEX(open_sem); + #define ACM_READY(acm) (acm && acm->dev && acm->used) /* @@ -310,12 +223,14 @@ struct acm *acm = (struct acm *)urb->context; if (!ACM_READY(acm)) - return; + goto out; if (urb->status) dbg("nonzero write bulk status received: %d", urb->status); schedule_work(&acm->work); +out: + acm->ready_for_write = 1; } static void acm_softint(void *private) @@ -346,22 +261,23 @@ tty->driver_data = acm; acm->tty = tty; - lock_kernel(); + down(&open_sem); - if (acm->used++) { - unlock_kernel(); - return 0; + if (acm->used) { + goto done; } - unlock_kernel(); - acm->ctrlurb->dev = acm->dev; - if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) + if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { dbg("usb_submit_urb(ctrl irq) failed"); + goto bail_out; + } acm->readurb->dev = acm->dev; - if (usb_submit_urb(acm->readurb, GFP_KERNEL)) + if (usb_submit_urb(acm->readurb, GFP_KERNEL)) { dbg("usb_submit_urb(read bulk) failed"); + goto bail_out_and_unlink; + } acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS); @@ -369,7 +285,16 @@ otherwise it is scheduled, and with high data rates data can get lost. */ tty->low_latency = 1; +done: + acm->used++; + up(&open_sem); return 0; + +bail_out_and_unlink: + usb_unlink_urb(acm->ctrlurb); +bail_out: + up(&open_sem); + return -EIO; } static void acm_tty_close(struct tty_struct *tty, struct file *filp) @@ -379,6 +304,7 @@ if (!acm || !acm->used) return; + down(&open_sem); if (!--acm->used) { if (acm->dev) { acm_set_control(acm, acm->ctrlout = 0); @@ -394,6 +320,7 @@ kfree(acm); } } + up(&open_sem); } static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count) @@ -403,7 +330,7 @@ if (!ACM_READY(acm)) return -EINVAL; - if (acm->writeurb->status == -EINPROGRESS) + if (!acm->ready_for_write) return 0; if (!count) return 0; @@ -419,10 +346,11 @@ acm->writeurb->transfer_buffer_length = count; acm->writeurb->dev = acm->dev; - /* GFP_KERNEL probably works if from_user */ - stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC); + acm->ready_for_write = 0; + stat = usb_submit_urb(acm->writeurb, GFP_NOIO); if (stat < 0) { dbg("usb_submit_urb(write bulk) failed"); + acm->ready_for_write = 1; return stat; } @@ -434,7 +362,7 @@ struct acm *acm = tty->driver_data; if (!ACM_READY(acm)) return -EINVAL; - return acm->writeurb->status == -EINPROGRESS ? 0 : acm->writesize; + return !acm->ready_for_write ? 0 : acm->writesize; } static int acm_tty_chars_in_buffer(struct tty_struct *tty) @@ -442,7 +370,7 @@ struct acm *acm = tty->driver_data; if (!ACM_READY(acm)) return -EINVAL; - return acm->writeurb->status == -EINPROGRESS ? acm->writeurb->transfer_buffer_length : 0; + return !acm->ready_for_write ? acm->writeurb->transfer_buffer_length : 0; } static void acm_tty_throttle(struct tty_struct *tty) @@ -567,77 +495,102 @@ * USB probe and disconnect routines. */ -#define CHECK_XFERTYPE(descr, xfer_type) (((descr)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == xfer_type) - static int acm_probe (struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *dev; + struct union_desc *union_header = NULL; + char *buffer = intf->altsetting->extra; + int buflen = intf->altsetting->extralen; + struct usb_interface *control_interface; + struct usb_interface *data_interface; + struct usb_endpoint_descriptor *epctrl; + struct usb_endpoint_descriptor *epread; + struct usb_endpoint_descriptor *epwrite; + struct usb_device *usb_dev = interface_to_usbdev(intf); struct acm *acm; - struct usb_host_config *cfacm; - struct usb_interface *data = NULL; - struct usb_host_interface *ifcom, *ifdata = NULL; - struct usb_endpoint_descriptor *epctrl = NULL; - struct usb_endpoint_descriptor *epread = NULL; - struct usb_endpoint_descriptor *epwrite = NULL; - int readsize, ctrlsize, minor, j; - unsigned char *buf; - - dev = interface_to_usbdev (intf); - - cfacm = dev->actconfig; - - /* We know we're probe()d with the control interface. */ - ifcom = intf->cur_altsetting; - - /* ACM doesn't guarantee the data interface is - * adjacent to the control interface, or that if one - * is there it's not for call management ... so find - * it - */ - for (j = 0; j < cfacm->desc.bNumInterfaces; j++) { - ifdata = cfacm->interface[j]->cur_altsetting; - data = cfacm->interface[j]; - - if (ifdata->desc.bInterfaceClass == USB_CLASS_CDC_DATA - && ifdata->desc.bNumEndpoints == 2) { - - epctrl = &ifcom->endpoint[0].desc; - epread = &ifdata->endpoint[0].desc; - epwrite = &ifdata->endpoint[1].desc; - - if ((epctrl->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN - || !CHECK_XFERTYPE(epctrl, USB_ENDPOINT_XFER_INT) - || !CHECK_XFERTYPE(epread, USB_ENDPOINT_XFER_BULK) - || !CHECK_XFERTYPE(epwrite, USB_ENDPOINT_XFER_BULK) - || ((epread->bEndpointAddress & USB_DIR_IN) - ^ (epwrite->bEndpointAddress & USB_DIR_IN)) != USB_DIR_IN) { - /* not suitable */ - goto next_interface; - } - - if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) { - /* descriptors are swapped */ - epread = &ifdata->endpoint[1].desc; - epwrite = &ifdata->endpoint[0].desc; - } - dev_dbg(&intf->dev, "found data interface at %d\n", j); - break; - } else { -next_interface: - ifdata = NULL; - data = NULL; + int minor; + int ctrlsize,readsize; + char *buf; + + if (!buffer) { + err("Wierd descriptor references"); + return -EINVAL; + } + + while (buflen > 0) { + if (buffer [1] != USB_DT_CS_INTERFACE) { + err("skipping garbage"); + goto next_desc; } + + switch (buffer [2]) { + case CDC_UNION_TYPE: /* we've found it */ + if (union_header) { + err("More than one union descriptor, skipping ..."); + goto next_desc; + } + union_header = (struct union_desc *)buffer; + break; + default: + err("Ignoring extra header"); + break; + } +next_desc: + buflen -= buffer[0]; + buffer += buffer[0]; } - /* there's been a problem */ - if (!ifdata) { - dev_dbg(&intf->dev, "data interface not found\n"); + if (!union_header) { + dev_dbg(&intf->dev,"No union descriptor, giving up\n"); return -ENODEV; + } + control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); + data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0); + if (!control_interface || !data_interface) { + dev_dbg(&intf->dev,"no interfaces\n"); + return -ENODEV; + } + + if (usb_interface_claimed(data_interface)) { /* valid in this context */ + dev_dbg(&intf->dev,"The data interface isn't available\n"); + return -EBUSY; } + /*workaround for switched interfaces */ + if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { + if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { + struct usb_interface *t; + dev_dbg(&intf->dev,"Your device has switched interfaces.\n"); + + t = control_interface; + control_interface = data_interface; + data_interface = t; + } else { + return -EINVAL; + } + } + if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) + return -EINVAL; + + epctrl = &control_interface->cur_altsetting->endpoint[0].desc; + epread = &data_interface->cur_altsetting->endpoint[0].desc; + epwrite = &data_interface->cur_altsetting->endpoint[1].desc; + + + /* workaround for switched endpoints */ + if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) { + /* descriptors are swapped */ + struct usb_endpoint_descriptor *t; + dev_dbg(&intf->dev,"The data interface has switched endpoints\n"); + + t = epread; + epread = epwrite; + epwrite = t; + } + dbg("interfaces are valid"); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); + if (acm_table[minor]) { err("no more free acm devices"); return -ENODEV; @@ -647,20 +600,21 @@ dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n"); return -ENOMEM; } - memset(acm, 0, sizeof(struct acm)); ctrlsize = epctrl->wMaxPacketSize; readsize = epread->wMaxPacketSize; acm->writesize = epwrite->wMaxPacketSize; - acm->control = intf; - acm->data = data; + acm->control = control_interface; + acm->data = data_interface; acm->minor = minor; - acm->dev = dev; + acm->dev = usb_dev; acm->bh.func = acm_rx_tasklet; acm->bh.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint, acm); + acm->ready_for_write = 1; + if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) { dev_dbg(&intf->dev, "out of memory (buf kmalloc)\n"); @@ -693,29 +647,17 @@ return -ENOMEM; } - usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress), - buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); + usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), + buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); - usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress), - buf += ctrlsize, readsize, acm_read_bulk, acm); + usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress), + buf += ctrlsize, readsize, acm_read_bulk, acm); acm->readurb->transfer_flags |= URB_NO_FSBR; - usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress), - buf += readsize, acm->writesize, acm_write_bulk, acm); + usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), + buf += readsize, acm->writesize, acm_write_bulk, acm); acm->writeurb->transfer_flags |= URB_NO_FSBR; - if ( (j = usb_driver_claim_interface(&acm_driver, data, acm)) != 0) { - err("claim failed"); - usb_free_urb(acm->ctrlurb); - usb_free_urb(acm->readurb); - usb_free_urb(acm->writeurb); - kfree(acm); - kfree(buf); - return j; - } - - tty_register_device(acm_tty_driver, minor, &intf->dev); - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); acm_set_control(acm, acm->ctrlout); @@ -724,11 +666,14 @@ acm->line.databits = 8; acm_set_line(acm, &acm->line); + usb_driver_claim_interface(&acm_driver, data_interface, acm); + + tty_register_device(acm_tty_driver, minor, &intf->dev); + acm_table[minor] = acm; usb_set_intfdata (intf, acm); return 0; } -#undef CHECK_XFERTYPE static void acm_disconnect(struct usb_interface *intf) { @@ -745,6 +690,8 @@ usb_unlink_urb(acm->ctrlurb); usb_unlink_urb(acm->readurb); usb_unlink_urb(acm->writeurb); + + flush_scheduled_work(); /* wait for acm_softint */ kfree(acm->ctrlurb->transfer_buffer); diff -Nru a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/usb/class/cdc-acm.h 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,115 @@ +/* + * + * Includes for cdc-acm.c + * + * Mainly take from usbnet's cdc-ether part + * + */ + +/* + * CMSPAR, some architectures can't have space and mark parity. + */ + +#ifndef CMSPAR +#define CMSPAR 0 +#endif + +/* + * Major and minor numbers. + */ + +#define ACM_TTY_MAJOR 166 +#define ACM_TTY_MINORS 32 + +/* + * Requests. + */ + +#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE) + +#define ACM_REQ_COMMAND 0x00 +#define ACM_REQ_RESPONSE 0x01 +#define ACM_REQ_SET_FEATURE 0x02 +#define ACM_REQ_GET_FEATURE 0x03 +#define ACM_REQ_CLEAR_FEATURE 0x04 + +#define ACM_REQ_SET_LINE 0x20 +#define ACM_REQ_GET_LINE 0x21 +#define ACM_REQ_SET_CONTROL 0x22 +#define ACM_REQ_SEND_BREAK 0x23 + +/* + * IRQs. + */ + +#define ACM_IRQ_NETWORK 0x00 +#define ACM_IRQ_LINE_STATE 0x20 + +/* + * Output control lines. + */ + +#define ACM_CTRL_DTR 0x01 +#define ACM_CTRL_RTS 0x02 + +/* + * Input control lines and line errors. + */ + +#define ACM_CTRL_DCD 0x01 +#define ACM_CTRL_DSR 0x02 +#define ACM_CTRL_BRK 0x04 +#define ACM_CTRL_RI 0x08 + +#define ACM_CTRL_FRAMING 0x10 +#define ACM_CTRL_PARITY 0x20 +#define ACM_CTRL_OVERRUN 0x40 + +/* + * Line speed and caracter encoding. + */ + +struct acm_line { + __u32 speed; + __u8 stopbits; + __u8 parity; + __u8 databits; +} __attribute__ ((packed)); + +/* + * Internal driver structures. + */ + +struct acm { + struct usb_device *dev; /* the corresponding usb device */ + struct usb_interface *control; /* control interface */ + struct usb_interface *data; /* data interface */ + struct tty_struct *tty; /* the corresponding tty */ + struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ + struct acm_line line; /* line coding (bits, stop, parity) */ + struct work_struct work; /* work queue entry for line discipline waking up */ + struct tasklet_struct bh; /* rx processing */ + unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ + unsigned int ctrlout; /* output control lines (DTR, RTS) */ + unsigned int writesize; /* max packet size for the output bulk endpoint */ + unsigned int used; /* someone has this acm's device open */ + unsigned int minor; /* acm minor number */ + unsigned char throttle; /* throttled by tty layer */ + unsigned char clocal; /* termios CLOCAL */ + unsigned char ready_for_write; /* write urb can be used */ +}; + +/* "Union Functional Descriptor" from CDC spec 5.2.3.X */ +struct union_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u8 bMasterInterface0; + u8 bSlaveInterface0; + /* ... and there could be other slave interfaces */ +} __attribute__ ((packed)); + +#define CDC_UNION_TYPE 0x06 +#define CDC_DATA_INTERFACE_TYPE 0x0a + diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c --- a/drivers/usb/class/usblp.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/class/usblp.c 2004-06-26 17:09:16 -07:00 @@ -75,6 +75,7 @@ #define IOCNR_HP_SET_CHANNEL 4 #define IOCNR_GET_BUS_ADDRESS 5 #define IOCNR_GET_VID_PID 6 +#define IOCNR_SOFT_RESET 7 /* Get device_id string: */ #define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len) /* The following ioctls were added for http://hpoj.sourceforge.net: */ @@ -90,6 +91,8 @@ #define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len) /* Get two-int array: [0]=vendor ID, [1]=product ID: */ #define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len) +/* Perform class specific soft reset */ +#define LPIOC_SOFT_RESET _IOC(_IOC_NONE, 'P', IOCNR_SOFT_RESET, 0); /* * A DEVICE_ID string may include the printer's serial number. @@ -587,6 +590,13 @@ usblp->minor, twoints[0], twoints[1]); break; + case IOCNR_SOFT_RESET: + if (_IOC_DIR(cmd) != _IOC_NONE) { + retval = -EINVAL; + goto done; + } + retval = usblp_reset(usblp); + break; default: retval = -ENOTTY; } @@ -761,6 +771,7 @@ usblp->minor, usblp->readurb->status); usblp->readurb->dev = usblp->dev; usblp->readcount = 0; + usblp->rcomplete = 0; if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) dbg("error submitting urb"); count = -EIO; diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c --- a/drivers/usb/core/devices.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/core/devices.c 2004-06-26 17:09:21 -07:00 @@ -589,6 +589,8 @@ bus = list_entry(buslist, struct usb_bus, bus_list); /* recurse through all children of the root hub */ + if (!bus->root_hub) + continue; down(&bus->root_hub->serialize); ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0); up(&bus->root_hub->serialize); diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c --- a/drivers/usb/core/devio.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/core/devio.c 2004-06-26 17:09:18 -07:00 @@ -290,8 +290,11 @@ spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); - while ((as = async_getcompleted(ps))) + as = async_getcompleted(ps); + while (as) { free_async(as); + as = async_getcompleted(ps); + } } static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum) @@ -558,7 +561,7 @@ if (usbfs_snoop) { dev_info(&dev->dev, "control read: data "); for (j = 0; j < ctrl.wLength; ++j) - printk ("%02x ", (unsigned char)((char *)ctrl.data)[j]); + printk ("%02x ", (unsigned char)(tbuf)[j]); printk("\n"); } if (copy_to_user(ctrl.data, tbuf, ctrl.wLength)) { @@ -578,7 +581,7 @@ if (usbfs_snoop) { dev_info(&dev->dev, "control write: data: "); for (j = 0; j < ctrl.wLength; ++j) - printk ("%02x ", (unsigned char)((char *)ctrl.data)[j]); + printk ("%02x ", (unsigned char)(tbuf)[j]); printk("\n"); } i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, @@ -968,29 +971,27 @@ static int processcompl(struct async *as) { struct urb *urb = as->urb; + struct usbdevfs_urb __user *userurb = as->userurb; unsigned int i; if (as->userbuffer) if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) return -EFAULT; - if (put_user(urb->status, - &((struct usbdevfs_urb *)as->userurb)->status)) + if (put_user(urb->status, &userurb->status)) return -EFAULT; - if (put_user(urb->actual_length, - &((struct usbdevfs_urb *)as->userurb)->actual_length)) + if (put_user(urb->actual_length, &userurb->actual_length)) return -EFAULT; - if (put_user(urb->error_count, - &((struct usbdevfs_urb *)as->userurb)->error_count)) + if (put_user(urb->error_count, &userurb->error_count)) return -EFAULT; if (!(usb_pipeisoc(urb->pipe))) return 0; for (i = 0; i < urb->number_of_packets; i++) { if (put_user(urb->iso_frame_desc[i].actual_length, - &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length)) + &userurb->iso_frame_desc[i].actual_length)) return -EFAULT; if (put_user(urb->iso_frame_desc[i].status, - &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status)) + &userurb->iso_frame_desc[i].status)) return -EFAULT; } return 0; diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c --- a/drivers/usb/core/hcd-pci.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/core/hcd-pci.c 2004-06-26 17:09:18 -07:00 @@ -229,7 +229,6 @@ void usb_hcd_pci_remove (struct pci_dev *dev) { struct usb_hcd *hcd; - struct usb_device *hub; hcd = pci_get_drvdata(dev); if (!hcd) @@ -239,12 +238,11 @@ if (in_interrupt ()) BUG (); - hub = hcd->self.root_hub; if (HCD_IS_RUNNING (hcd->state)) hcd->state = USB_STATE_QUIESCING; dev_dbg (hcd->self.controller, "roothub graceful disconnect\n"); - usb_disconnect (&hub); + usb_disconnect (&hcd->self.root_hub); hcd->driver->stop (hcd); hcd_buffer_destroy (hcd); diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/core/hcd.c 2004-06-26 17:09:18 -07:00 @@ -764,8 +764,9 @@ * * The USB host controller calls this function to register the root hub * properly with the USB subsystem. It sets up the device properly in - * the device model tree, and then calls usb_new_device() to register the - * usb device. It also assigns the root hub's USB address (always 1). + * the device tree and stores the root_hub pointer in the bus structure, + * then calls usb_new_device() to register the usb device. It also + * assigns the root hub's USB address (always 1). */ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev) { @@ -777,7 +778,10 @@ memset (&usb_dev->bus->devmap.devicemap, 0, sizeof usb_dev->bus->devmap.devicemap); set_bit (devnum, usb_dev->bus->devmap.devicemap); - usb_dev->state = USB_STATE_ADDRESS; + usb_set_device_state(usb_dev, USB_STATE_ADDRESS); + + down (&usb_bus_list_lock); + usb_dev->bus->root_hub = usb_dev; usb_dev->epmaxpacketin[0] = usb_dev->epmaxpacketout[0] = 64; retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); @@ -787,14 +791,15 @@ return (retval < 0) ? retval : -EMSGSIZE; } - (void) usb_get_dev (usb_dev); down (&usb_dev->serialize); retval = usb_new_device (usb_dev); - if (retval) + up (&usb_dev->serialize); + if (retval) { + usb_dev->bus->root_hub = NULL; dev_err (parent_dev, "can't register root hub for %s, %d\n", usb_dev->dev.bus_id, retval); - up (&usb_dev->serialize); - usb_put_dev (usb_dev); + } + up (&usb_bus_list_lock); return retval; } EXPORT_SYMBOL (usb_register_root_hub); @@ -1574,11 +1579,13 @@ unsigned i; /* hc's root hub is removed later removed in hcd->stop() */ - hub->state = USB_STATE_NOTATTACHED; + down (&hub->serialize); + usb_set_device_state(hub, USB_STATE_NOTATTACHED); for (i = 0; i < hub->maxchild; i++) { if (hub->children [i]) usb_disconnect (&hub->children [i]); } + up (&hub->serialize); } /** diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/core/hcd.h 2004-06-26 17:09:17 -07:00 @@ -244,17 +244,10 @@ struct usb_bus *, unsigned port); extern int usb_new_device(struct usb_device *dev); extern void usb_disconnect(struct usb_device **); -extern void usb_choose_address(struct usb_device *dev); -extern void usb_release_address(struct usb_device *dev); -/* exported to hub driver ONLY to support usb_reset_device () */ extern int usb_get_configuration(struct usb_device *dev); extern void usb_destroy_configuration(struct usb_device *dev); -/* use these only before the device's address has been set */ -#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30)) -#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | USB_DIR_IN) - /*-------------------------------------------------------------------------*/ /* @@ -346,7 +339,8 @@ extern int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev); -static inline int hcd_register_root (struct usb_hcd *hcd) +static inline int hcd_register_root (struct usb_device *usb_dev, + struct usb_hcd *hcd) { /* hcd->driver->start() reported can_wakeup, probably with * assistance from board's boot firmware. @@ -356,8 +350,7 @@ dev_dbg (hcd->self.controller, "supports USB remote wakeup\n"); hcd->remote_wakeup = hcd->can_wakeup; - return usb_register_root_hub ( - hcd_to_bus (hcd)->root_hub, hcd->self.controller); + return usb_register_root_hub (usb_dev, hcd->self.controller); } /*-------------------------------------------------------------------------*/ diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/core/hub.c 2004-06-26 17:09:17 -07:00 @@ -9,6 +9,11 @@ */ #include +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif #include #include #include @@ -19,11 +24,6 @@ #include #include #include -#ifdef CONFIG_USB_DEBUG - #define DEBUG -#else - #undef DEBUG -#endif #include #include #include @@ -36,11 +36,13 @@ #include "hcd.h" #include "hub.h" +/* Protect all struct usb_device state members */ +static spinlock_t device_state_lock = SPIN_LOCK_UNLOCKED; + /* Wakes up khubd */ static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */ -static LIST_HEAD(hub_list); /* List of all hubs (for cleanup) */ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); static pid_t khubd_pid = 0; /* PID of khubd */ @@ -229,6 +231,8 @@ { struct usb_hub *hub = (struct usb_hub *)urb->context; int status; + int i; + unsigned long bits; spin_lock(&hub_event_lock); hub->urb_active = 0; @@ -253,6 +257,11 @@ /* let khubd handle things */ case 0: /* we got data: port status changed */ + bits = 0; + for (i = 0; i < urb->actual_length; ++i) + bits |= ((unsigned long) ((*hub->buffer)[i])) + << (i*8); + hub->event_bits[0] = bits; break; } @@ -260,7 +269,7 @@ /* Something happened, let khubd figure it out */ if (list_empty(&hub->event_list)) { - list_add(&hub->event_list, &hub_event_list); + list_add_tail(&hub->event_list, &hub_event_list); wake_up(&khubd_wait); } @@ -268,7 +277,7 @@ if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0 /* ENODEV means we raced disconnect() */ && status != -ENODEV) - dev_err (&hub->intf->dev, "resubmit --> %d\n", urb->status); + dev_err (&hub->intf->dev, "resubmit --> %d\n", status); if (status == 0) hub->urb_active = 1; done: @@ -632,7 +641,6 @@ { struct usb_hub *hub = usb_get_intfdata (intf); DECLARE_COMPLETION(urb_complete); - unsigned long flags; if (!hub) return; @@ -641,17 +649,13 @@ highspeed_hubs--; usb_set_intfdata (intf, NULL); - spin_lock_irqsave(&hub_event_lock, flags); + spin_lock_irq(&hub_event_lock); hub->urb_complete = &urb_complete; /* Delete it and then reset it */ list_del_init(&hub->event_list); - list_del_init(&hub->hub_list); - spin_unlock_irqrestore(&hub_event_lock, flags); - - down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */ - up(&hub->khubd_sem); + spin_unlock_irq(&hub_event_lock); /* assuming we used keventd, it must quiesce too */ if (hub->has_indicators) @@ -695,7 +699,6 @@ struct usb_device *hdev; struct usb_hub *hub; struct device *hub_dev; - unsigned long flags; desc = intf->cur_altsetting; hdev = interface_to_usbdev(intf); @@ -711,23 +714,19 @@ } /* Multiple endpoints? What kind of mutant ninja-hub is this? */ - if (desc->desc.bNumEndpoints != 1) { + if (desc->desc.bNumEndpoints != 1) goto descriptor_error; - } endpoint = &desc->endpoint[0].desc; /* Output endpoint? Curiouser and curiouser.. */ - if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) goto descriptor_error; - } /* If it's not an interrupt endpoint, we'd better punt! */ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - != USB_ENDPOINT_XFER_INT) { + != USB_ENDPOINT_XFER_INT) goto descriptor_error; - return -EIO; - } /* We found a hub */ dev_info (hub_dev, "USB hub found\n"); @@ -742,15 +741,8 @@ INIT_LIST_HEAD(&hub->event_list); hub->intf = intf; - init_MUTEX(&hub->khubd_sem); INIT_WORK(&hub->leds, led_work, hub); - /* Record the new hub's existence */ - spin_lock_irqsave(&hub_event_lock, flags); - INIT_LIST_HEAD(&hub->hub_list); - list_add(&hub->hub_list, &hub_list); - spin_unlock_irqrestore(&hub_event_lock, flags); - usb_set_intfdata (intf, hub); if (hdev->speed == USB_SPEED_HIGH) @@ -827,6 +819,7 @@ return 0; } +/* FIXME! This routine should be subsumed into hub_reset */ static void hub_start_disconnect(struct usb_device *hdev) { struct usb_device *parent = hdev->parent; @@ -845,6 +838,289 @@ dev_err(&hdev->dev, "cannot disconnect hub!\n"); } + +static void recursively_mark_NOTATTACHED(struct usb_device *udev) +{ + int i; + + for (i = 0; i < udev->maxchild; ++i) { + if (udev->children[i]) + recursively_mark_NOTATTACHED(udev->children[i]); + } + udev->state = USB_STATE_NOTATTACHED; +} + +/** + * usb_set_device_state - change a device's current state (usbcore-internal) + * @udev: pointer to device whose state should be changed + * @new_state: new state value to be stored + * + * udev->state is _not_ protected by the udev->serialize semaphore. This + * is so that devices can be marked as disconnected as soon as possible, + * without having to wait for the semaphore to be released. Instead, + * changes to the state must be protected by the device_state_lock spinlock. + * + * Once a device has been added to the device tree, all changes to its state + * should be made using this routine. The state should _not_ be set directly. + * + * If udev->state is already USB_STATE_NOTATTACHED then no change is made. + * Otherwise udev->state is set to new_state, and if new_state is + * USB_STATE_NOTATTACHED then all of udev's descendant's states are also set + * to USB_STATE_NOTATTACHED. + */ +void usb_set_device_state(struct usb_device *udev, + enum usb_device_state new_state) +{ + unsigned long flags; + + spin_lock_irqsave(&device_state_lock, flags); + if (udev->state == USB_STATE_NOTATTACHED) + ; /* do nothing */ + else if (new_state != USB_STATE_NOTATTACHED) + udev->state = new_state; + else + recursively_mark_NOTATTACHED(udev); + spin_unlock_irqrestore(&device_state_lock, flags); +} + + +static void choose_address(struct usb_device *udev) +{ + int devnum; + struct usb_bus *bus = udev->bus; + + /* If khubd ever becomes multithreaded, this will need a lock */ + + /* Try to allocate the next devnum beginning at bus->devnum_next. */ + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, + bus->devnum_next); + if (devnum >= 128) + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1); + + bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); + + if (devnum < 128) { + set_bit(devnum, bus->devmap.devicemap); + udev->devnum = devnum; + } +} + +static void release_address(struct usb_device *udev) +{ + if (udev->devnum > 0) { + clear_bit(udev->devnum, udev->bus->devmap.devicemap); + udev->devnum = -1; + } +} + +/** + * usb_disconnect - disconnect a device (usbcore-internal) + * @pdev: pointer to device being disconnected + * Context: !in_interrupt () + * + * Something got disconnected. Get rid of it, and all of its children. + * If *pdev is a normal device then the parent hub should be locked. + * If *pdev is a root hub then this routine will acquire the + * usb_bus_list_lock on behalf of the caller. + * + * Only hub drivers (including virtual root hub drivers for host + * controllers) should ever call this. + * + * This call is synchronous, and may not be used in an interrupt context. + */ +void usb_disconnect(struct usb_device **pdev) +{ + struct usb_device *udev = *pdev; + int i; + + if (!udev) { + pr_debug ("%s nodev\n", __FUNCTION__); + return; + } + + /* mark the device as inactive, so any further urb submissions for + * this device will fail. + */ + usb_set_device_state(udev, USB_STATE_NOTATTACHED); + + /* lock the bus list on behalf of HCDs unregistering their root hubs */ + if (!udev->parent) + down(&usb_bus_list_lock); + down(&udev->serialize); + + dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); + + /* Free up all the children before we remove this device */ + for (i = 0; i < USB_MAXCHILDREN; i++) { + if (udev->children[i]) + usb_disconnect(&udev->children[i]); + } + + /* deallocate hcd/hardware state ... nuking all pending urbs and + * cleaning up all state associated with the current configuration + */ + usb_disable_device(udev, 0); + + /* Free the device number, remove the /proc/bus/usb entry and + * the sysfs attributes, and delete the parent's children[] + * (or root_hub) pointer. + */ + dev_dbg (&udev->dev, "unregistering device\n"); + release_address(udev); + usbfs_remove_device(udev); + usb_remove_sysfs_dev_files(udev); + + /* Avoid races with recursively_mark_NOTATTACHED() */ + spin_lock_irq(&device_state_lock); + *pdev = NULL; + spin_unlock_irq(&device_state_lock); + + up(&udev->serialize); + if (!udev->parent) + up(&usb_bus_list_lock); + + device_unregister(&udev->dev); +} + +static int choose_configuration(struct usb_device *udev) +{ + int c, i; + + /* NOTE: this should interact with hub power budgeting */ + + c = udev->config[0].desc.bConfigurationValue; + if (udev->descriptor.bNumConfigurations != 1) { + for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { + struct usb_interface_descriptor *desc; + + /* heuristic: Linux is more likely to have class + * drivers, so avoid vendor-specific interfaces. + */ + desc = &udev->config[i].intf_cache[0] + ->altsetting->desc; + if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) + continue; + /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */ + if (desc->bInterfaceClass == USB_CLASS_COMM + && desc->bInterfaceSubClass == 2 + && desc->bInterfaceProtocol == 0xff) + continue; + c = udev->config[i].desc.bConfigurationValue; + break; + } + dev_info(&udev->dev, + "configuration #%d chosen from %d choices\n", + c, udev->descriptor.bNumConfigurations); + } + return c; +} + +#ifdef DEBUG +static void show_string(struct usb_device *udev, char *id, int index) +{ + char *buf; + + if (!index) + return; + if (!(buf = kmalloc(256, GFP_KERNEL))) + return; + if (usb_string(udev, index, buf, 256) > 0) + dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, buf); + kfree(buf); +} + +#else +static inline void show_string(struct usb_device *udev, char *id, int index) +{} +#endif + +/* + * usb_new_device - perform initial device setup (usbcore-internal) + * @udev: newly addressed device (in ADDRESS state) + * + * This is called with devices which have been enumerated, but not yet + * configured. The device descriptor is available, but not descriptors + * for any device configuration. The caller must have locked udev and + * either the parent hub (if udev is a normal device) or else the + * usb_bus_list_lock (if udev is a root hub). The parent's pointer to + * udev has already been installed, but udev is not yet visible through + * sysfs or other filesystem code. + * + * Returns 0 for success (device is configured and listed, with its + * interfaces, in sysfs); else a negative errno value. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Only the hub driver should ever call this; root hub registration + * uses it indirectly. + */ +int usb_new_device(struct usb_device *udev) +{ + int err; + int c; + + err = usb_get_configuration(udev); + if (err < 0) { + dev_err(&udev->dev, "can't read configurations, error %d\n", + err); + goto fail; + } + + /* Tell the world! */ + dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " + "SerialNumber=%d\n", + udev->descriptor.iManufacturer, + udev->descriptor.iProduct, + udev->descriptor.iSerialNumber); + + if (udev->descriptor.iProduct) + show_string(udev, "Product", + udev->descriptor.iProduct); + if (udev->descriptor.iManufacturer) + show_string(udev, "Manufacturer", + udev->descriptor.iManufacturer); + if (udev->descriptor.iSerialNumber) + show_string(udev, "SerialNumber", + udev->descriptor.iSerialNumber); + + /* put device-specific files into sysfs */ + err = device_add (&udev->dev); + if (err) { + dev_err(&udev->dev, "can't device_add, error %d\n", err); + goto fail; + } + usb_create_sysfs_dev_files (udev); + + /* choose and set the configuration. that registers the interfaces + * with the driver core, and lets usb device drivers bind to them. + */ + c = choose_configuration(udev); + if (c < 0) + dev_warn(&udev->dev, + "can't choose an initial configuration\n"); + else { + err = usb_set_configuration(udev, c); + if (err) { + dev_err(&udev->dev, "can't set config #%d, error %d\n", + c, err); + usb_remove_sysfs_dev_files(udev); + device_del(&udev->dev); + goto fail; + } + } + + /* USB device state == configured ... usable */ + + /* add a /proc/bus/usb entry */ + usbfs_add_device(udev); + return 0; + +fail: + usb_set_device_state(udev, USB_STATE_NOTATTACHED); + return err; +} + + static int hub_port_status(struct usb_device *hdev, int port, u16 *status, u16 *change) { @@ -934,16 +1210,20 @@ /* Reset the port */ for (i = 0; i < PORT_RESET_TRIES; i++) { - set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET); + status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET); + if (status) + dev_err(hub_dev, "cannot reset port %d (err = %d)\n", + port + 1, status); + else + status = hub_port_wait_reset(hdev, port, udev, delay); /* return on disconnect or reset */ - status = hub_port_wait_reset(hdev, port, udev, delay); if (status == -ENOTCONN || status == 0) { clear_port_feature(hdev, port + 1, USB_PORT_FEAT_C_RESET); - udev->state = status + usb_set_device_state(udev, status ? USB_STATE_NOTATTACHED - : USB_STATE_DEFAULT; + : USB_STATE_DEFAULT); return status; } @@ -964,6 +1244,9 @@ { int ret; + if (hdev->children[port]) + usb_set_device_state(hdev->children[port], + USB_STATE_NOTATTACHED); ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE); if (ret) dev_err(hubdev(hdev), "cannot disable port %d (err = %d)\n", @@ -975,57 +1258,62 @@ /* USB 2.0 spec, 7.1.7.3 / fig 7-29: * * Between connect detection and reset signaling there must be a delay - * of 100ms at least for debounce and power-settling. The corresponding + * of 100ms at least for debounce and power-settling. The corresponding * timer shall restart whenever the downstream port detects a disconnect. * - * Apparently there are some bluetooth and irda-dongles and a number - * of low-speed devices which require longer delays of about 200-400ms. + * Apparently there are some bluetooth and irda-dongles and a number of + * low-speed devices for which this debounce period may last over a second. * Not covered by the spec - but easy to deal with. * - * This implementation uses 400ms minimum debounce timeout and checks - * every 25ms for transient disconnects to restart the delay. + * This implementation uses a 1500ms total debounce timeout; if the + * connection isn't stable by then it returns -ETIMEDOUT. It checks + * every 25ms for transient disconnects. When the port status has been + * unchanged for 100ms it returns the port status. */ -#define HUB_DEBOUNCE_TIMEOUT 400 -#define HUB_DEBOUNCE_STEP 25 -#define HUB_DEBOUNCE_STABLE 4 +#define HUB_DEBOUNCE_TIMEOUT 1500 +#define HUB_DEBOUNCE_STEP 25 +#define HUB_DEBOUNCE_STABLE 100 static int hub_port_debounce(struct usb_device *hdev, int port) { int ret; - int delay_time, stable_count; + int total_time, stable_time = 0; u16 portchange, portstatus; - unsigned connection; - - connection = 0; - stable_count = 0; - for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; delay_time += HUB_DEBOUNCE_STEP) { - msleep(HUB_DEBOUNCE_STEP); + unsigned connection = 0xffff; + for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) { ret = hub_port_status(hdev, port, &portstatus, &portchange); if (ret < 0) return ret; - if ((portstatus & USB_PORT_STAT_CONNECTION) == connection) { - if (connection) { - if (++stable_count == HUB_DEBOUNCE_STABLE) - break; - } + if (!(portchange & USB_PORT_STAT_C_CONNECTION) && + (portstatus & USB_PORT_STAT_CONNECTION) == connection) { + stable_time += HUB_DEBOUNCE_STEP; + if (stable_time >= HUB_DEBOUNCE_STABLE) + break; } else { - stable_count = 0; + stable_time = 0; + connection = portstatus & USB_PORT_STAT_CONNECTION; } - connection = portstatus & USB_PORT_STAT_CONNECTION; - if ((portchange & USB_PORT_STAT_C_CONNECTION)) { - clear_port_feature(hdev, port+1, USB_PORT_FEAT_C_CONNECTION); + if (portchange & USB_PORT_STAT_C_CONNECTION) { + clear_port_feature(hdev, port+1, + USB_PORT_FEAT_C_CONNECTION); } + + if (total_time >= HUB_DEBOUNCE_TIMEOUT) + break; + msleep(HUB_DEBOUNCE_STEP); } dev_dbg (hubdev (hdev), - "debounce: port %d: delay %dms stable %d status 0x%x\n", - port + 1, delay_time, stable_count, portstatus); + "debounce: port %d: total %dms stable %dms status 0x%x\n", + port + 1, total_time, stable_time, portstatus); - return (portstatus & USB_PORT_STAT_CONNECTION) ? 0 : -ENOTCONN; + if (stable_time < HUB_DEBOUNCE_STABLE) + return -ETIMEDOUT; + return portstatus; } static int hub_set_address(struct usb_device *udev) @@ -1037,11 +1325,11 @@ if (udev->state != USB_STATE_DEFAULT && udev->state != USB_STATE_ADDRESS) return -EINVAL; - retval = usb_control_msg(udev, usb_snddefctrl(udev), + retval = usb_control_msg(udev, (PIPE_CONTROL << 30) /* Address 0 */, USB_REQ_SET_ADDRESS, 0, udev->devnum, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); if (retval == 0) - udev->state = USB_STATE_ADDRESS; + usb_set_device_state(udev, USB_STATE_ADDRESS); return retval; } @@ -1109,33 +1397,9 @@ udev->epmaxpacketin [0] = i; udev->epmaxpacketout[0] = i; - /* set the address */ - if (udev->devnum <= 0) { - usb_choose_address(udev); - if (udev->devnum <= 0) - goto fail; - - /* Set up TT records, if needed */ - if (hdev->tt) { - udev->tt = hdev->tt; - udev->ttport = hdev->ttport; - } else if (udev->speed != USB_SPEED_HIGH - && hdev->speed == USB_SPEED_HIGH) { - struct usb_hub *hub; - - hub = usb_get_intfdata (hdev->actconfig - ->interface[0]); - udev->tt = &hub->tt; - udev->ttport = port + 1; - } - - /* force the right log message (below) at low speed */ - oldspeed = USB_SPEED_UNKNOWN; - } - dev_info (&udev->dev, "%s %s speed USB device using address %d\n", - (oldspeed == USB_SPEED_UNKNOWN) ? "new" : "reset", + (udev->config) ? "reset" : "new", ({ char *speed; switch (udev->speed) { case USB_SPEED_LOW: speed = "low"; break; case USB_SPEED_FULL: speed = "full"; break; @@ -1143,6 +1407,19 @@ default: speed = "?"; break; }; speed;}), udev->devnum); + + /* Set up TT records, if needed */ + if (hdev->tt) { + udev->tt = hdev->tt; + udev->ttport = hdev->ttport; + } else if (udev->speed != USB_SPEED_HIGH + && hdev->speed == USB_SPEED_HIGH) { + struct usb_hub *hub; + + hub = usb_get_intfdata(hdev->actconfig->interface[0]); + udev->tt = &hub->tt; + udev->ttport = port + 1; + } /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way? * Because device hardware and firmware is sometimes buggy in @@ -1164,12 +1441,7 @@ dev_err(&udev->dev, "device not accepting address %d, error %d\n", udev->devnum, retval); - fail: - hub_port_disable(hdev, port); - usb_release_address(udev); - usb_put_dev(udev); - up(&usb_address0_sem); - return retval; + goto fail; } /* cope with hardware quirkiness: @@ -1192,7 +1464,8 @@ if (udev->speed == USB_SPEED_FULL && (udev->epmaxpacketin [0] != udev->descriptor.bMaxPacketSize0)) { - usb_disable_endpoint(udev, 0); + usb_disable_endpoint(udev, 0 + USB_DIR_IN); + usb_disable_endpoint(udev, 0 + USB_DIR_OUT); usb_endpoint_running(udev, 0, 1); usb_endpoint_running(udev, 0, 0); udev->epmaxpacketin [0] = udev->descriptor.bMaxPacketSize0; @@ -1208,11 +1481,11 @@ goto fail; } - /* now dev is visible to other tasks */ - hdev->children[port] = udev; + retval = 0; +fail: up(&usb_address0_sem); - return 0; + return retval; } static void @@ -1271,7 +1544,14 @@ } return remaining; } - + +/* Handle physical or logical connection change events. + * This routine is called when: + * a port connection-change occurs; + * a port enable-change occurs (often caused by EMI); + * usb_reset_device() encounters changed descriptors (as from + * a firmware download) + */ static void hub_port_connect_change(struct usb_hub *hub, int port, u16 portstatus, u16 portchange) { @@ -1282,9 +1562,6 @@ dev_dbg (hub_dev, "port %d, status %04x, change %04x, %s\n", port + 1, portstatus, portchange, portspeed (portstatus)); - - /* Clear the connection change status */ - clear_port_feature(hdev, port + 1, USB_PORT_FEAT_C_CONNECTION); if (hub->has_indicators) { set_port_led(hdev, port + 1, HUB_LED_AUTO); @@ -1295,6 +1572,17 @@ if (hdev->children[port]) usb_disconnect(&hdev->children[port]); + if (portchange & USB_PORT_STAT_C_CONNECTION) { + status = hub_port_debounce(hdev, port); + if (status < 0) { + dev_err (hub_dev, + "connect-debounce failed, port %d disabled\n", + port+1); + goto done; + } + portstatus = status; + } + /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { @@ -1308,13 +1596,6 @@ goto done; return; } - - if (hub_port_debounce(hdev, port)) { - dev_err (hub_dev, - "connect-debounce failed, port %d disabled\n", - port+1); - goto done; - } for (i = 0; i < SET_CONFIG_TRIES; i++) { struct usb_device *udev; @@ -1328,21 +1609,26 @@ "couldn't allocate port %d usb_device\n", port+1); goto done; } - udev->state = USB_STATE_POWERED; - + + usb_set_device_state(udev, USB_STATE_POWERED); + /* hub can tell if it's lowspeed already: D- pullup (not D+) */ if (portstatus & USB_PORT_STAT_LOW_SPEED) udev->speed = USB_SPEED_LOW; else udev->speed = USB_SPEED_UNKNOWN; + + /* set the address */ + choose_address(udev); + if (udev->devnum <= 0) { + status = -ENOTCONN; /* Don't retry */ + goto loop; + } - /* reset, set address, get descriptor, add to hub's children */ - down (&udev->serialize); + /* reset and get descriptor */ status = hub_port_init(hdev, udev, port); - if (status == -ENOTCONN) - break; if (status < 0) - continue; + goto loop; /* consecutive bus-powered hubs aren't reliable; they can * violate the voltage drop budget. if the new child has @@ -1358,7 +1644,7 @@ &devstat); if (status < 0) { dev_dbg(&udev->dev, "get status %d ?\n", status); - continue; + goto loop; } cpu_to_le16s(&devstat); if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { @@ -1370,10 +1656,8 @@ INDICATOR_AMBER_BLINK; schedule_work (&hub->leds); } - hdev->children[port] = NULL; - usb_put_dev(udev); - hub_port_disable(hdev, port); - return; + status = -ENOTCONN; /* Don't retry */ + goto loop; } } @@ -1383,13 +1667,37 @@ && highspeed_hubs != 0) check_highspeed (hub, udev, port); + /* Store the parent's children[] pointer. At this point + * udev becomes globally accessible, although presumably + * no one will look at it until hdev is unlocked. + */ + down (&udev->serialize); + status = 0; + + /* We mustn't add new devices if the parent hub has + * been disconnected; we would race with the + * recursively_mark_NOTATTACHED() routine. + */ + spin_lock_irq(&device_state_lock); + if (hdev->state == USB_STATE_NOTATTACHED) + status = -ENOTCONN; + else + hdev->children[port] = udev; + spin_unlock_irq(&device_state_lock); + /* Run it through the hoops (find a driver, etc) */ - status = usb_new_device(udev); - if (status != 0) { - hdev->children[port] = NULL; - continue; + if (!status) { + status = usb_new_device(udev); + if (status) { + spin_lock_irq(&device_state_lock); + hdev->children[port] = NULL; + spin_unlock_irq(&device_state_lock); + } } + up (&udev->serialize); + if (status) + goto loop; status = hub_power_remaining(hub, hdev); if (status) @@ -1398,6 +1706,15 @@ 2 * status); return; + +loop: + hub_port_disable(hdev, port); + usb_disable_endpoint(udev, 0 + USB_DIR_IN); + usb_disable_endpoint(udev, 0 + USB_DIR_OUT); + release_address(udev); + usb_put_dev(udev); + if (status == -ENOTCONN) + break; } done: @@ -1406,7 +1723,6 @@ static void hub_events(void) { - unsigned long flags; struct list_head *tmp; struct usb_device *hdev; struct usb_hub *hub; @@ -1416,6 +1732,7 @@ u16 portstatus; u16 portchange; int i, ret; + int connect_change; /* * We restart the list every time to avoid a deadlock with @@ -1424,24 +1741,32 @@ * Not the most efficient, but avoids deadlocks. */ while (1) { - spin_lock_irqsave(&hub_event_lock, flags); - if (list_empty(&hub_event_list)) + /* Grab the first entry at the beginning of the list */ + spin_lock_irq(&hub_event_lock); + if (list_empty(&hub_event_list)) { + spin_unlock_irq(&hub_event_lock); break; + } - /* Grab the next entry from the beginning of the list */ tmp = hub_event_list.next; + list_del_init(tmp); hub = list_entry(tmp, struct usb_hub, event_list); hdev = interface_to_usbdev(hub->intf); hub_dev = &hub->intf->dev; - list_del_init(tmp); - - if (unlikely(down_trylock(&hub->khubd_sem))) - BUG(); /* never blocks, we were on list */ + usb_get_dev(hdev); + spin_unlock_irq(&hub_event_lock); - spin_unlock_irqrestore(&hub_event_lock, flags); + /* Lock the device, then check to see if we were + * disconnected while waiting for the lock to succeed. */ + down(&hdev->serialize); + if (hdev->state != USB_STATE_CONFIGURED || + !hdev->actconfig || + hub != usb_get_intfdata( + hdev->actconfig->interface[0])) + goto loop; if (hub->error) { dev_dbg (hub_dev, "resetting for error %d\n", @@ -1450,27 +1775,35 @@ if (hub_reset(hub)) { dev_dbg (hub_dev, "can't reset; disconnecting\n"); - up(&hub->khubd_sem); hub_start_disconnect(hdev); - continue; + goto loop; } hub->nerrors = 0; hub->error = 0; } + /* deal with port status changes */ for (i = 0; i < hub->descriptor->bNbrPorts; i++) { + if (!test_and_clear_bit(i+1, hub->event_bits)) + continue; ret = hub_port_status(hdev, i, &portstatus, &portchange); - if (ret < 0) { + if (ret < 0) continue; - } + connect_change = 0; if (portchange & USB_PORT_STAT_C_CONNECTION) { - hub_port_connect_change(hub, i, portstatus, portchange); - } else if (portchange & USB_PORT_STAT_C_ENABLE) { - dev_dbg (hub_dev, - "port %d enable change, status %08x\n", - i + 1, portstatus); + clear_port_feature(hdev, + i + 1, USB_PORT_FEAT_C_CONNECTION); + connect_change = 1; + } + + if (portchange & USB_PORT_STAT_C_ENABLE) { + if (!connect_change) + dev_dbg (hub_dev, + "port %d enable change, " + "status %08x\n", + i + 1, portstatus); clear_port_feature(hdev, i + 1, USB_PORT_FEAT_C_ENABLE); @@ -1481,15 +1814,14 @@ * Works at least with mouse driver. */ if (!(portstatus & USB_PORT_STAT_ENABLE) - && (portstatus & USB_PORT_STAT_CONNECTION) - && (hdev->children[i])) { + && !connect_change + && hdev->children[i]) { dev_err (hub_dev, "port %i " "disabled by hub (EMI?), " "re-enabling...", i + 1); - hub_port_connect_change(hub, - i, portstatus, portchange); + connect_change = 1; } } @@ -1517,10 +1849,16 @@ clear_port_feature(hdev, i + 1, USB_PORT_FEAT_C_RESET); } + + if (connect_change) + hub_port_connect_change(hub, i, + portstatus, portchange); } /* end for i */ /* deal with hub status changes */ - if (hub_hub_status(hub, &hubstatus, &hubchange) < 0) + if (test_and_clear_bit(0, hub->event_bits) == 0) + ; /* do nothing */ + else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0) dev_err (hub_dev, "get_hub_status failed\n"); else { if (hubchange & HUB_CHANGE_LOCAL_POWER) { @@ -1534,10 +1872,12 @@ hub_power_on(hub); } } - up(&hub->khubd_sem); - } /* end while (1) */ - spin_unlock_irqrestore(&hub_event_lock, flags); +loop: + up(&hdev->serialize); + usb_put_dev(hdev); + + } /* end while (1) */ } static int hub_thread(void *__unused) @@ -1581,9 +1921,6 @@ .id_table = hub_id_table, }; -/* - * This should be a separate module. - */ int usb_hub_init(void) { pid_t pid; @@ -1726,7 +2063,7 @@ udev->actconfig->desc.bConfigurationValue, ret); goto re_enumerate; } - udev->state = USB_STATE_CONFIGURED; + usb_set_device_state(udev, USB_STATE_CONFIGURED); for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf = udev->actconfig->interface[i]; @@ -1752,7 +2089,7 @@ re_enumerate: /* FIXME make some task re-enumerate; don't just mark unusable */ - udev->state = USB_STATE_NOTATTACHED; + hub_port_disable(parent, port); return -ENODEV; } EXPORT_SYMBOL(__usb_reset_device); diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h --- a/drivers/usb/core/hub.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/core/hub.h 2004-06-26 17:09:15 -07:00 @@ -202,11 +202,13 @@ int error; /* last reported error */ int nerrors; /* track consecutive errors */ - struct list_head hub_list; /* all hubs */ struct list_head event_list; /* hubs w/data or errs ready */ + unsigned long event_bits[1]; /* status change bitmask */ +#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ +#error event_bits[] is too short! +#endif struct usb_hub_descriptor *descriptor; /* class descriptor */ - struct semaphore khubd_sem; struct usb_tt tt; /* Transaction Translator */ u8 power_budget; /* in 2mA units; or zero */ @@ -215,5 +217,16 @@ enum hub_led_mode indicator[USB_MAXCHILDREN]; struct work_struct leds; }; + +/* use this for low-powered root hubs */ +static inline void +hub_set_power_budget (struct usb_device *hubdev, unsigned mA) +{ + struct usb_hub *hub; + + hub = (struct usb_hub *) + usb_get_intfdata (hubdev->actconfig->interface[0]); + hub->power_budget = min(mA,(unsigned)500)/2; +} #endif /* __LINUX_HUB_H */ diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/core/message.c 2004-06-26 17:09:16 -07:00 @@ -566,22 +566,19 @@ */ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) { - int i = 5; + int i; int result; memset(buf,0,size); // Make sure we parse really received data - while (i--) { + for (i = 0; i < 3; ++i) { /* retry on length 0 or stall; some devices are flakey */ - if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, buf, size, - HZ * USB_CTRL_GET_TIMEOUT)) > 0 - || result != -EPIPE) + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (type << 8) + index, 0, buf, size, + HZ * USB_CTRL_GET_TIMEOUT); + if (!(result == 0 || result == -EPIPE)) break; - - dev_dbg (&dev->dev, "RETRY descriptor, result %d\n", result); - result = -ENOMSG; } return result; } @@ -830,6 +827,7 @@ interface = dev->actconfig->interface[i]; dev_dbg (&dev->dev, "unregistering interface %s\n", interface->dev.bus_id); + usb_remove_sysfs_intf_files(interface); device_del (&interface->dev); } @@ -842,7 +840,7 @@ } dev->actconfig = 0; if (dev->state == USB_STATE_CONFIGURED) - dev->state = USB_STATE_ADDRESS; + usb_set_device_state(dev, USB_STATE_ADDRESS); } } @@ -1047,7 +1045,7 @@ config->desc.bConfigurationValue, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); if (retval < 0) { - dev->state = USB_STATE_ADDRESS; + usb_set_device_state(dev, USB_STATE_ADDRESS); return retval; } @@ -1185,9 +1183,9 @@ dev->actconfig = cp; if (!cp) - dev->state = USB_STATE_ADDRESS; + usb_set_device_state(dev, USB_STATE_ADDRESS); else { - dev->state = USB_STATE_CONFIGURED; + usb_set_device_state(dev, USB_STATE_CONFIGURED); /* Initialize the new interface structures and the * hc/hcd/usbcore interface/endpoint state. @@ -1322,7 +1320,7 @@ */ err = usb_get_string(dev, dev->string_langid, index, tbuf, 2); - if (err == -EPIPE) { + if (err == -EPIPE || err == 0) { dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, 2); err = usb_get_string(dev, dev->string_langid, index, tbuf, 2); } @@ -1331,7 +1329,7 @@ len=tbuf[0]; err = usb_get_string(dev, dev->string_langid, index, tbuf, len); - if (err == -EPIPE) { + if (err == -EPIPE || err == 0) { dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, len); err = usb_get_string(dev, dev->string_langid, index, tbuf, len); } diff -Nru a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c --- a/drivers/usb/core/sysfs.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/core/sysfs.c 2004-06-26 17:09:16 -07:00 @@ -2,8 +2,8 @@ * drivers/usb/core/sysfs.c * * (C) Copyright 2002 David Brownell - * (C) Copyright 2002 Greg Kroah-Hartman - * (C) Copyright 2002 IBM Corp. + * (C) Copyright 2002,2004 Greg Kroah-Hartman + * (C) Copyright 2002,2004 IBM Corp. * * All of the sysfs file attributes for usb devices and interfaces. * @@ -162,29 +162,35 @@ usb_descriptor_attr (bDeviceProtocol, "%02x\n") usb_descriptor_attr (bNumConfigurations, "%d\n") +static struct attribute *dev_attrs[] = { + /* current configuration's attributes */ + &dev_attr_bNumInterfaces.attr, + &dev_attr_bConfigurationValue.attr, + &dev_attr_bmAttributes.attr, + &dev_attr_bMaxPower.attr, + /* device attributes */ + &dev_attr_idVendor.attr, + &dev_attr_idProduct.attr, + &dev_attr_bcdDevice.attr, + &dev_attr_bDeviceClass.attr, + &dev_attr_bDeviceSubClass.attr, + &dev_attr_bDeviceProtocol.attr, + &dev_attr_bNumConfigurations.attr, + &dev_attr_speed.attr, + &dev_attr_devnum.attr, + &dev_attr_version.attr, + &dev_attr_maxchild.attr, + NULL, +}; +static struct attribute_group dev_attr_grp = { + .attrs = dev_attrs, +}; void usb_create_sysfs_dev_files (struct usb_device *udev) { struct device *dev = &udev->dev; - /* current configuration's attributes */ - device_create_file (dev, &dev_attr_bNumInterfaces); - device_create_file (dev, &dev_attr_bConfigurationValue); - device_create_file (dev, &dev_attr_bmAttributes); - device_create_file (dev, &dev_attr_bMaxPower); - - /* device attributes */ - device_create_file (dev, &dev_attr_idVendor); - device_create_file (dev, &dev_attr_idProduct); - device_create_file (dev, &dev_attr_bcdDevice); - device_create_file (dev, &dev_attr_bDeviceClass); - device_create_file (dev, &dev_attr_bDeviceSubClass); - device_create_file (dev, &dev_attr_bDeviceProtocol); - device_create_file (dev, &dev_attr_bNumConfigurations); - - /* speed varies depending on how you connect the device */ - device_create_file (dev, &dev_attr_speed); - // FIXME iff there are other speed configs, show how many + sysfs_create_group(&dev->kobj, &dev_attr_grp); if (udev->descriptor.iManufacturer) device_create_file (dev, &dev_attr_manufacturer); @@ -192,10 +198,20 @@ device_create_file (dev, &dev_attr_product); if (udev->descriptor.iSerialNumber) device_create_file (dev, &dev_attr_serial); +} + +void usb_remove_sysfs_dev_files (struct usb_device *udev) +{ + struct device *dev = &udev->dev; - device_create_file (dev, &dev_attr_devnum); - device_create_file (dev, &dev_attr_version); - device_create_file (dev, &dev_attr_maxchild); + sysfs_remove_group(&dev->kobj, &dev_attr_grp); + + if (udev->descriptor.iManufacturer) + device_remove_file(dev, &dev_attr_manufacturer); + if (udev->descriptor.iProduct) + device_remove_file(dev, &dev_attr_product); + if (udev->descriptor.iSerialNumber) + device_remove_file(dev, &dev_attr_serial); } /* Interface fields */ @@ -217,13 +233,26 @@ usb_intf_attr (bInterfaceProtocol, "%02x\n") usb_intf_attr (iInterface, "%02x\n") +static struct attribute *intf_attrs[] = { + &dev_attr_bInterfaceNumber.attr, + &dev_attr_bAlternateSetting.attr, + &dev_attr_bNumEndpoints.attr, + &dev_attr_bInterfaceClass.attr, + &dev_attr_bInterfaceSubClass.attr, + &dev_attr_bInterfaceProtocol.attr, + &dev_attr_iInterface.attr, + NULL, +}; +static struct attribute_group intf_attr_grp = { + .attrs = intf_attrs, +}; + void usb_create_sysfs_intf_files (struct usb_interface *intf) { - device_create_file (&intf->dev, &dev_attr_bInterfaceNumber); - device_create_file (&intf->dev, &dev_attr_bAlternateSetting); - device_create_file (&intf->dev, &dev_attr_bNumEndpoints); - device_create_file (&intf->dev, &dev_attr_bInterfaceClass); - device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass); - device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol); - device_create_file (&intf->dev, &dev_attr_iInterface); + sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); +} + +void usb_remove_sysfs_intf_files (struct usb_interface *intf) +{ + sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); } diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/core/usb.c 2004-06-26 17:09:18 -07:00 @@ -883,6 +883,8 @@ buslist != &usb_bus_list; buslist = buslist->next) { bus = container_of(buslist, struct usb_bus, bus_list); + if (!bus->root_hub) + continue; dev = match_device(bus->root_hub, vendor_id, product_id); if (dev) goto exit; @@ -942,235 +944,6 @@ size -= header->bLength; } return -1; -} - -/** - * usb_disconnect - disconnect a device (usbcore-internal) - * @pdev: pointer to device being disconnected - * Context: !in_interrupt () - * - * Something got disconnected. Get rid of it, and all of its children. - * - * Only hub drivers (including virtual root hub drivers for host - * controllers) should ever call this. - * - * This call is synchronous, and may not be used in an interrupt context. - */ -void usb_disconnect(struct usb_device **pdev) -{ - struct usb_device *dev = *pdev; - struct usb_bus *bus; - struct usb_operations *ops; - int i; - - might_sleep (); - - if (!dev) { - pr_debug ("%s nodev\n", __FUNCTION__); - return; - } - bus = dev->bus; - if (!bus) { - pr_debug ("%s nobus\n", __FUNCTION__); - return; - } - ops = bus->op; - - *pdev = NULL; - - /* mark the device as inactive, so any further urb submissions for - * this device will fail. - */ - dev->state = USB_STATE_NOTATTACHED; - down(&dev->serialize); - - dev_info (&dev->dev, "USB disconnect, address %d\n", dev->devnum); - - /* Free up all the children before we remove this device */ - for (i = 0; i < USB_MAXCHILDREN; i++) { - struct usb_device **child = dev->children + i; - if (*child) - usb_disconnect(child); - } - - /* deallocate hcd/hardware state ... nuking all pending urbs and - * cleaning up all state associated with the current configuration - */ - usb_disable_device(dev, 0); - - /* Free the device number and remove the /proc/bus/usb entry */ - dev_dbg (&dev->dev, "unregistering device\n"); - usb_release_address(dev); - usbfs_remove_device(dev); - up(&dev->serialize); - device_unregister(&dev->dev); -} - -/** - * usb_choose_address - pick device address (usbcore-internal) - * @dev: newly detected device (in DEFAULT state) - * - * Picks a device address. It's up to the hub (or root hub) driver - * to handle and manage enumeration, starting from the DEFAULT state. - * Only hub drivers (but not virtual root hub drivers for host - * controllers) should ever call this. - */ -void usb_choose_address(struct usb_device *dev) -{ - int devnum; - // FIXME needs locking for SMP!! - /* why? this is called only from the hub thread, - * which hopefully doesn't run on multiple CPU's simultaneously 8-) - */ - - /* Try to allocate the next devnum beginning at bus->devnum_next. */ - devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, dev->bus->devnum_next); - if (devnum >= 128) - devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1); - - dev->bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); - - if (devnum < 128) { - set_bit(devnum, dev->bus->devmap.devicemap); - dev->devnum = devnum; - } -} - -/** - * usb_release_address - deallocate device address (usbcore-internal) - * @dev: newly removed device - * - * Removes and deallocates the address assigned to a device. - * Only hub drivers (but not virtual root hub drivers for host - * controllers) should ever call this. - */ -void usb_release_address(struct usb_device *dev) -{ - if (dev->devnum > 0) { - clear_bit(dev->devnum, dev->bus->devmap.devicemap); - dev->devnum = -1; - } -} - - -static inline void usb_show_string(struct usb_device *dev, char *id, int index) -{ - char *buf; - - if (!index) - return; - if (!(buf = kmalloc(256, GFP_KERNEL))) - return; - if (usb_string(dev, index, buf, 256) > 0) - dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf); - kfree(buf); -} - -static int usb_choose_configuration(struct usb_device *dev) -{ - int c, i; - - c = dev->config[0].desc.bConfigurationValue; - if (dev->descriptor.bNumConfigurations != 1) { - for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { - struct usb_interface_descriptor *desc; - - /* heuristic: Linux is more likely to have class - * drivers, so avoid vendor-specific interfaces. - */ - desc = &dev->config[i].intf_cache[0] - ->altsetting->desc; - if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) - continue; - /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */ - if (desc->bInterfaceClass == USB_CLASS_COMM - && desc->bInterfaceSubClass == 2 - && desc->bInterfaceProtocol == 0xff) - continue; - c = dev->config[i].desc.bConfigurationValue; - break; - } - dev_info(&dev->dev, - "configuration #%d chosen from %d choices\n", - c, dev->descriptor.bNumConfigurations); - } - return c; -} - -/* - * usb_new_device - perform initial device setup (usbcore-internal) - * @dev: newly addressed device (in ADDRESS state) - * - * This is called with devices which have been enumerated, but not yet - * configured. The device descriptor is available, but not descriptors - * for any device configuration. The caller owns dev->serialize, and - * the device is not visible through sysfs or other filesystem code. - * - * Returns 0 for success (device is configured and listed, with its - * interfaces, in sysfs); else a negative errno value. On error, one - * reference count to the device has been dropped. - * - * This call is synchronous, and may not be used in an interrupt context. - * - * Only the hub driver should ever call this; root hub registration - * uses it only indirectly. - */ -int usb_new_device(struct usb_device *dev) -{ - int err; - int c; - - err = usb_get_configuration(dev); - if (err < 0) { - dev_err(&dev->dev, "can't read configurations, error %d\n", - err); - goto fail; - } - - /* Tell the world! */ - dev_dbg(&dev->dev, "new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", - dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber); - -#ifdef DEBUG - if (dev->descriptor.iProduct) - usb_show_string(dev, "Product", dev->descriptor.iProduct); - if (dev->descriptor.iManufacturer) - usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer); - if (dev->descriptor.iSerialNumber) - usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); -#endif - - /* put device-specific files into sysfs */ - err = device_add (&dev->dev); - if (err) { - dev_err(&dev->dev, "can't device_add, error %d\n", err); - goto fail; - } - usb_create_sysfs_dev_files (dev); - - /* choose and set the configuration. that registers the interfaces - * with the driver core, and lets usb device drivers bind to them. - * NOTE: should interact with hub power budgeting. - */ - c = usb_choose_configuration(dev); - err = usb_set_configuration(dev, c); - if (err) { - dev_err(&dev->dev, "can't set config #%d, error %d\n", c, err); - device_del(&dev->dev); - goto fail; - } - - /* USB device state == configured ... usable */ - - /* add a /proc/bus/usb entry */ - usbfs_add_device(dev); - - return 0; -fail: - dev->state = USB_STATE_NOTATTACHED; - usb_release_address(dev); - usb_put_dev(dev); - return err; } /** diff -Nru a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h --- a/drivers/usb/core/usb.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/core/usb.h 2004-06-26 17:09:16 -07:00 @@ -1,7 +1,9 @@ /* Functions local to drivers/usb/core/ */ extern void usb_create_sysfs_dev_files (struct usb_device *dev); +extern void usb_remove_sysfs_dev_files (struct usb_device *dev); extern void usb_create_sysfs_intf_files (struct usb_interface *intf); +extern void usb_remove_sysfs_intf_files (struct usb_interface *intf); extern int usb_probe_interface (struct device *dev); extern int usb_unbind_interface (struct device *dev); @@ -18,6 +20,9 @@ extern int usb_get_device_descriptor(struct usb_device *dev, unsigned int size); extern int usb_set_configuration(struct usb_device *dev, int configuration); + +extern void usb_set_device_state(struct usb_device *udev, + enum usb_device_state new_state); /* for labeling diagnostics */ extern const char *usbcore_name; diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c --- a/drivers/usb/gadget/dummy_hcd.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/gadget/dummy_hcd.c 2004-06-26 17:09:15 -07:00 @@ -825,8 +825,7 @@ dum = container_of (hcd, struct dummy, hcd); spin_lock_irqsave (&dum->lock, flags); - if (!dum->hdev) - dum->hdev = urb->dev->hcpriv; + dum->hdev = urb->dev->hcpriv; urb->hcpriv = dum; if (usb_pipetype (urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ @@ -994,10 +993,17 @@ return limit; } +#define is_active(dum) ((dum->port_status & \ + (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \ + USB_PORT_STAT_SUSPEND)) \ + == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) + static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) { int i; + if (!is_active (dum)) + return NULL; if ((address & ~USB_DIR_IN) == 0) return &dum->ep [0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { @@ -1011,6 +1017,8 @@ return NULL; } +#undef is_active + #define Dev_Request (USB_TYPE_STANDARD | USB_RECIP_DEVICE) #define Dev_InRequest (Dev_Request | USB_DIR_IN) #define Intf_Request (USB_TYPE_STANDARD | USB_RECIP_INTERFACE) @@ -1152,11 +1160,6 @@ case USB_REQ_SET_ADDRESS: if (setup.bRequestType != Dev_Request) break; - if (dum->address != 0) { - maybe_set_status (urb, -ETIMEDOUT); - urb->actual_length = 0; - goto return_urb; - } dum->address = setup.wValue; maybe_set_status (urb, 0); dev_dbg (hardware, "set_address = %d\n", @@ -1404,9 +1407,8 @@ break; case USB_PORT_FEAT_POWER: dum->port_status = 0; - dum->address = 0; - dum->hdev = 0; dum->resuming = 0; + stop_activity(dum, dum->driver); break; default: dum->port_status &= ~(1 << wValue); @@ -1657,7 +1659,7 @@ INIT_LIST_HEAD (&hcd->dev_list); usb_register_bus (bus); - bus->root_hub = root = usb_alloc_dev (0, bus, 0); + root = usb_alloc_dev (0, bus, 0); if (!root) { retval = -ENOMEM; clean1: @@ -1671,13 +1673,15 @@ root->speed = USB_SPEED_HIGH; /* ...then configured, so khubd sees us. */ - if ((retval = hcd_register_root (&dum->hcd)) != 0) { - bus->root_hub = 0; + if ((retval = hcd_register_root (root, &dum->hcd)) != 0) { usb_put_dev (root); clean2: dum->hcd.state = USB_STATE_QUIESCING; goto clean1; } + + /* only show a low-power port: just 8mA */ + hub_set_power_budget (root, 8); dum->started = 1; diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c --- a/drivers/usb/gadget/ether.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/gadget/ether.c 2004-06-26 17:09:21 -07:00 @@ -118,6 +118,7 @@ unsigned zlp:1; unsigned cdc:1; unsigned rndis:1; + unsigned suspended:1; u16 cdc_filter; unsigned long todo; #define WORK_RX_MEMORY 0 @@ -1345,24 +1346,23 @@ static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req) { - struct eth_dev *dev = ep->driver_data; - if (req->status || req->actual != req->length) DEBUG (dev, "rndis response complete --> %d, %d/%d\n", req->status, req->actual, req->length); /* done sending after CDC_GET_ENCAPSULATED_RESPONSE */ - rndis_free_response (dev->rndis_config, req->buf); } static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req) { struct eth_dev *dev = ep->driver_data; + int status; /* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */ spin_lock(&dev->lock); - if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf)) - ERROR(dev, "%s: rndis parse error\n", __FUNCTION__ ); + status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf); + if (status < 0) + ERROR(dev, "%s: rndis parse error %d\n", __FUNCTION__, status); spin_unlock(&dev->lock); } @@ -1580,6 +1580,7 @@ if (buf) { memcpy (req->buf, buf, value); req->complete = rndis_response_complete; + rndis_free_response(dev->rndis_config, buf); } /* else stalls ... spec says to avoid that */ } @@ -2064,6 +2065,16 @@ } } +static void rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req) +{ + if (req->status || req->actual != req->length) + DEBUG (dev, "rndis control ack complete --> %d, %d/%d\n", + req->status, req->actual, req->length); + + usb_ep_free_buffer(ep, req->buf, req->dma, 8); + usb_ep_free_request(ep, req); +} + static int rndis_control_ack (struct net_device *net) { struct eth_dev *dev = (struct eth_dev *) net->priv; @@ -2095,7 +2106,7 @@ * CDC_NOTIFY_RESPONSE_AVAILABLE should work too */ resp->length = 8; - resp->complete = rndis_response_complete; + resp->complete = rndis_control_ack_complete; *((u32 *) resp->buf) = __constant_cpu_to_le32 (1); *((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0); @@ -2103,7 +2114,7 @@ length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC); if (length < 0) { resp->status = 0; - rndis_response_complete (dev->status_ep, resp); + rndis_control_ack_complete (dev->status_ep, resp); } return 0; @@ -2302,17 +2313,6 @@ UTS_SYSNAME " " UTS_RELEASE "/%s", gadget->name); - /* CDC subset ... recognized by Linux since 2.4.10, but Windows - * drivers aren't widely available. - */ - if (!cdc) { - device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; - device_desc.idVendor = - __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); - device_desc.idProduct = - __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM); - } - /* If there's an RNDIS configuration, that's what Windows wants to * be using ... so use these product IDs here and in the "linux.inf" * needed to install MSFT drivers. Current Linux kernels will use @@ -2326,6 +2326,16 @@ __constant_cpu_to_le16(RNDIS_PRODUCT_NUM); snprintf (product_desc, sizeof product_desc, "RNDIS/%s", driver_desc); + + /* CDC subset ... recognized by Linux since 2.4.10, but Windows + * drivers aren't widely available. + */ + } else if (!cdc) { + device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; + device_desc.idVendor = + __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); + device_desc.idProduct = + __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM); } /* support optional vendor/distro customization */ @@ -2554,6 +2564,26 @@ /*-------------------------------------------------------------------------*/ +static void +eth_suspend (struct usb_gadget *gadget) +{ + struct eth_dev *dev = get_gadget_data (gadget); + + DEBUG (dev, "suspend\n"); + dev->suspended = 1; +} + +static void +eth_resume (struct usb_gadget *gadget) +{ + struct eth_dev *dev = get_gadget_data (gadget); + + DEBUG (dev, "resume\n"); + dev->suspended = 0; +} + +/*-------------------------------------------------------------------------*/ + static struct usb_gadget_driver eth_driver = { #ifdef CONFIG_USB_GADGET_DUALSPEED .speed = USB_SPEED_HIGH, @@ -2566,6 +2596,9 @@ .setup = eth_setup, .disconnect = eth_disconnect, + + .suspend = eth_suspend, + .resume = eth_resume, .driver = { .name = (char *) shortname, diff -Nru a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c --- a/drivers/usb/gadget/file_storage.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/gadget/file_storage.c 2004-06-26 17:09:20 -07:00 @@ -2501,7 +2501,7 @@ /* Store and send the Bulk-only CSW */ csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); csw->Tag = fsg->tag; - csw->Residue = fsg->residue; + csw->Residue = cpu_to_le32(fsg->residue); csw->Status = status; bh->inreq->length = USB_BULK_CS_WRAP_LEN; @@ -2947,7 +2947,7 @@ fsg->data_dir = DATA_DIR_TO_HOST; else fsg->data_dir = DATA_DIR_FROM_HOST; - fsg->data_size = cbw->DataTransferLength; + fsg->data_size = le32_to_cpu(cbw->DataTransferLength); if (fsg->data_size == 0) fsg->data_dir = DATA_DIR_NONE; fsg->lun = cbw->Lun; @@ -3834,6 +3834,7 @@ } /* Find all the endpoints we will use */ + usb_ep_autoconfig_reset(gadget); ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc); if (!ep) goto autoconf_fail; diff -Nru a/drivers/usb/gadget/ndis.h b/drivers/usb/gadget/ndis.h --- a/drivers/usb/gadget/ndis.h 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/gadget/ndis.h 2004-06-26 17:09:19 -07:00 @@ -26,10 +26,40 @@ #define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A #define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B +enum NDIS_DEVICE_POWER_STATE { + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, + NdisDeviceStateD1, + NdisDeviceStateD2, + NdisDeviceStateD3, + NdisDeviceStateMaximum +}; + +struct NDIS_PM_WAKE_UP_CAPABILITIES { + enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; + enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; + enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; +}; + /* NDIS_PNP_CAPABILITIES.Flags constants */ #define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 #define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 #define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 + +struct NDIS_PNP_CAPABILITIES { + u32 Flags; + struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; +}; + +struct NDIS_PM_PACKET_PATTERN { + u32 Priority; + u32 Reserved; + u32 MaskSize; + u32 PatternOffset; + u32 PatternSize; + u32 PatternFlags; +}; + /* Required Object IDs (OIDs) */ #define OID_GEN_SUPPORTED_LIST 0x00010101 diff -Nru a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c --- a/drivers/usb/gadget/net2280.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/gadget/net2280.c 2004-06-26 17:09:15 -07:00 @@ -1902,6 +1902,8 @@ , &dev->usb->stdrsp); writel ( (1 << USB_ROOT_PORT_WAKEUP_ENABLE) | (1 << SELF_POWERED_USB_DEVICE) + /* erratum 0102 workaround */ + | ((dev->chiprev == 0100) ? 0 : 1) << SUSPEND_IMMEDIATELY | (1 << REMOTE_WAKEUP_SUPPORT) | (1 << USB_DETECT_ENABLE) | (1 << SELF_POWERED_STATUS) @@ -1917,6 +1919,7 @@ | (1 << PCI_RETRY_ABORT_INTERRUPT_ENABLE) | (1 << VBUS_INTERRUPT_ENABLE) | (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE) + | (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) , &dev->regs->pciirqenb1); /* don't leave any writes posted */ @@ -2513,19 +2516,24 @@ return; } - /* NOTE: we don't actually suspend the hardware; that starts to - * interact with PCI power management, and needs something like a - * controller->suspend() call to clear SUSPEND_REQUEST_INTERRUPT. - * we shouldn't see resume interrupts. - * for rev 0100, this also avoids erratum 0102. + /* NOTE: chip stays in PCI D0 state for now, but it could + * enter D1 to save more power */ tmp = (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT); if (stat & tmp) { - if (dev->driver->suspend) - dev->driver->suspend (&dev->gadget); + writel (tmp, &dev->regs->irqstat1); + if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) { + if (dev->driver->suspend) + dev->driver->suspend (&dev->gadget); + /* we use SUSPEND_IMMEDIATELY */ + stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT); + } else { + if (dev->driver->resume) + dev->driver->resume (&dev->gadget); + /* at high speed, note erratum 0133 */ + } stat &= ~tmp; } - stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT); /* clear any other status/irqs */ if (stat) @@ -2533,6 +2541,7 @@ /* some status we can just ignore */ stat &= ~((1 << CONTROL_STATUS_INTERRUPT) + | (1 << SUSPEND_REQUEST_INTERRUPT) | (1 << RESUME_INTERRUPT) | (1 << SOF_INTERRUPT)); if (!stat) diff -Nru a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c --- a/drivers/usb/gadget/pxa2xx_udc.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/gadget/pxa2xx_udc.c 2004-06-26 17:09:19 -07:00 @@ -1406,7 +1406,7 @@ #ifdef CONFIG_ARCH_PXA /* Disable clock for USB device */ - CKEN &= ~CKEN11_USB; + pxa_set_cken(CKEN11_USB, 0); #endif ep0_idle (dev); @@ -1452,7 +1452,7 @@ #ifdef CONFIG_ARCH_PXA /* Enable clock for USB device */ - CKEN |= CKEN11_USB; + pxa_set_cken(CKEN11_USB, 1); #endif /* try to clear these bits before we enable the udc */ diff -Nru a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c --- a/drivers/usb/gadget/rndis.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/gadget/rndis.c 2004-06-26 17:09:15 -07:00 @@ -18,6 +18,9 @@ * * 03/25/2004 Kai-Uwe Bloem * Fixed rndis_rm_hdr length bug. + * + * Copyright (C) 2004 by David Brownell + * updates to merge with Linux 2.6, better match RNDIS spec */ #include @@ -35,28 +38,34 @@ #include #include + +#undef RNDIS_PM +#undef VERBOSE + #include "rndis.h" /* The driver for your USB chip needs to support ep0 OUT to work with - * RNDIS, plus the same three descriptors as CDC Ethernet. + * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional). * * Windows hosts need an INF file like Documentation/usb/linux.inf + * and will be happier if you provide the host_addr module parameter. */ -#ifndef __LITTLE_ENDIAN -#warning this code is missing all cpu_to_leXX() calls ... -#endif - #if 0 -#define DEBUG if (rndis_debug) printk +#define DEBUG(str,args...) do { \ + if (rndis_debug) \ + printk(KERN_DEBUG str , ## args ); \ + } while (0) static int rndis_debug = 0; module_param (rndis_debug, bool, 0); MODULE_PARM_DESC (rndis_debug, "enable debugging"); #else -#define DEBUG(str,args...) do{}while(0) + +#define rndis_debug 0 +#define DEBUG(str,args...) do{}while(0) #endif #define RNDIS_MAX_CONFIGS 1 @@ -79,16 +88,14 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length); -/* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include - * - power management (OID_PNP_CAPABILITIES, ...) - * - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...) - */ /* NDIS Functions */ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) { int retval = -ENOTSUPP; u32 length = 0; + u32 *tmp; + int i, count; rndis_query_cmplt_type *resp; if (!r) return -ENOMEM; @@ -97,11 +104,17 @@ if (!resp) return -ENOMEM; switch (OID) { + + /* general oids (table 4-1) */ + /* mandatory */ case OID_GEN_SUPPORTED_LIST: DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__); length = sizeof (oid_supported_list); - memcpy ((u8 *) resp + 24, oid_supported_list, length); + count = length / sizeof (u32); + tmp = (u32 *) ((u8 *)resp + 24); + for (i = 0; i < count; i++) + tmp[i] = cpu_to_le32 (oid_supported_list[i]); retval = 0; break; @@ -115,7 +128,7 @@ * reddite ergo quae sunt Caesaris Caesari * et quae sunt Dei Deo! */ - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; @@ -123,7 +136,8 @@ case OID_GEN_MEDIA_SUPPORTED: DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].medium); retval = 0; break; @@ -132,24 +146,21 @@ DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); length = 4; /* one medium, one transport... (maybe you do it better) */ - *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].medium); retval = 0; break; - case OID_GEN_MAXIMUM_LOOKAHEAD: - DEBUG("%s: OID_GEN_MAXIMUM_LOOKAHEAD\n", __FUNCTION__); - break; - /* mandatory */ case OID_GEN_MAXIMUM_FRAME_SIZE: DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); if (rndis_per_dev_params [configNr].dev) { length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr] - .dev->mtu; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].dev->mtu); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -160,30 +171,20 @@ length = 4; if (rndis_per_dev_params [configNr].media_state == NDIS_MEDIA_STATE_DISCONNECTED) - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); else - *((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].speed); retval = 0; break; - - case OID_GEN_TRANSMIT_BUFFER_SPACE: - DEBUG("%s: OID_GEN_TRANSMIT_BUFFER_SPACE\n", __FUNCTION__); - length = 4; - *((u32 *) resp + 6) = 0; - retval = 0; - break; - - case OID_GEN_RECEIVE_BUFFER_SPACE: - DEBUG("%s: OID_GEN_RECEIVE_BUFFER_SPACE\n", __FUNCTION__); - break; - + /* mandatory */ case OID_GEN_TRANSMIT_BLOCK_SIZE: DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__); if (rndis_per_dev_params [configNr].dev) { length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr] - .dev->mtu; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].dev->mtu); retval = 0; } break; @@ -193,8 +194,8 @@ DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); if (rndis_per_dev_params [configNr].dev) { length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr] - .dev->mtu; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].dev->mtu); retval = 0; } break; @@ -203,7 +204,8 @@ case OID_GEN_VENDOR_ID: DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr].vendorID; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].vendorID); retval = 0; break; @@ -216,129 +218,92 @@ retval = 0; break; + case OID_GEN_VENDOR_DRIVER_VERSION: + DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__); + length = 4; + /* Created as LE */ + *((u32 *) resp + 6) = rndis_driver_version; + retval = 0; + break; + /* mandatory */ case OID_GEN_CURRENT_PACKET_FILTER: DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params[configNr].filter; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params[configNr].filter); retval = 0; break; - - case OID_GEN_CURRENT_LOOKAHEAD: - DEBUG("%s: OID_GEN_CURRENT_LOOKAHEAD\n", __FUNCTION__); - break; - - case OID_GEN_DRIVER_VERSION: - DEBUG("%s: OID_GEN_DRIVER_VERSION\n", __FUNCTION__); - break; - + /* mandatory */ case OID_GEN_MAXIMUM_TOTAL_SIZE: DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = RNDIS_MAX_TOTAL_SIZE; - retval = 0; - break; - - case OID_GEN_PROTOCOL_OPTIONS: - DEBUG("%s: OID_GEN_PROTOCOL_OPTIONS\n", __FUNCTION__); - break; - - case OID_GEN_MAC_OPTIONS: - DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__); - length = 4; - *((u32 *) resp + 6) = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | - NDIS_MAC_OPTION_FULL_DUPLEX; + *((u32 *) resp + 6) = __constant_cpu_to_le32( + RNDIS_MAX_TOTAL_SIZE); retval = 0; break; - + /* mandatory */ case OID_GEN_MEDIA_CONNECT_STATUS: DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr] - .media_state; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .media_state); retval = 0; break; - - case OID_GEN_MAXIMUM_SEND_PACKETS: - DEBUG("%s: OID_GEN_MAXIMUM_SEND_PACKETS\n", __FUNCTION__); - break; - - /* mandatory */ - case OID_GEN_VENDOR_DRIVER_VERSION: - DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__); - length = 4; - *((u32 *) resp + 6) = rndis_driver_version; - retval = 0; - break; - - case OID_GEN_SUPPORTED_GUIDS: - DEBUG("%s: OID_GEN_SUPPORTED_GUIDS\n", __FUNCTION__); - break; - - case OID_GEN_NETWORK_LAYER_ADDRESSES: - DEBUG("%s: OID_GEN_NETWORK_LAYER_ADDRESSES\n", __FUNCTION__); - break; - - case OID_GEN_TRANSPORT_HEADER_OFFSET: - DEBUG("%s: OID_GEN_TRANSPORT_HEADER_OFFSET\n", __FUNCTION__); - break; - - case OID_GEN_MACHINE_NAME: - DEBUG("%s: OID_GEN_MACHINE_NAME\n", __FUNCTION__); - break; - - case OID_GEN_RNDIS_CONFIG_PARAMETER: - DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__); + + case OID_GEN_PHYSICAL_MEDIUM: + DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; - - case OID_GEN_VLAN_ID: - DEBUG("%s: OID_GEN_VLAN_ID\n", __FUNCTION__); - break; - - case OID_GEN_MEDIA_CAPABILITIES: - DEBUG("%s: OID_GEN_MEDIA_CAPABILITIES\n", __FUNCTION__); - break; - - case OID_GEN_PHYSICAL_MEDIUM: - DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__); + + /* The RNDIS specification is incomplete/wrong. Some versions + * of MS-Windows expect OIDs that aren't specified there. Other + * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! + */ + case OID_GEN_MAC_OPTIONS: /* from WinME */ + DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32( + NDIS_MAC_OPTION_RECEIVE_SERIALIZED + | NDIS_MAC_OPTION_FULL_DUPLEX); retval = 0; break; - + + /* statistics OIDs (table 4-2) */ + /* mandatory */ case OID_GEN_XMIT_OK: DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr] - .stats->tx_packets - + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].stats->tx_packets - rndis_per_dev_params [configNr].stats->tx_errors - - rndis_per_dev_params [configNr].stats->tx_dropped; + rndis_per_dev_params [configNr].stats->tx_dropped); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; - + /* mandatory */ case OID_GEN_RCV_OK: DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->rx_packets - + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr].stats->rx_packets - rndis_per_dev_params [configNr].stats->rx_errors - - rndis_per_dev_params [configNr].stats->rx_dropped; + rndis_per_dev_params [configNr].stats->rx_dropped); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -348,11 +313,12 @@ DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->tx_errors; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->tx_errors); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -361,11 +327,12 @@ case OID_GEN_RCV_ERROR: DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->rx_errors; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->rx_errors); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -374,15 +341,17 @@ case OID_GEN_RCV_NO_BUFFER: DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->rx_dropped; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->rx_dropped); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; - + +#ifdef RNDIS_OPTIONAL_STATS case OID_GEN_DIRECTED_BYTES_XMIT: DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); /* @@ -392,14 +361,17 @@ */ if (rndis_per_dev_params [configNr].stats) { length = 4; - *((u32 *) resp + 6) = (rndis_per_dev_params [configNr]. - stats->tx_packets - - rndis_per_dev_params [configNr].stats->tx_errors - - rndis_per_dev_params [configNr].stats->tx_dropped) - *123; + *((u32 *) resp + 6) = cpu_to_le32 ( + (rndis_per_dev_params [configNr] + .stats->tx_packets - + rndis_per_dev_params [configNr] + .stats->tx_errors - + rndis_per_dev_params [configNr] + .stats->tx_dropped) + * 123); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -409,14 +381,17 @@ /* dito */ if (rndis_per_dev_params [configNr].stats) { length = 4; - *((u32 *) resp + 6) = (rndis_per_dev_params [configNr]. - stats->tx_packets - - rndis_per_dev_params [configNr].stats->tx_errors - - rndis_per_dev_params [configNr].stats->tx_dropped) - /123; + *((u32 *) resp + 6) = cpu_to_le32 ( + (rndis_per_dev_params [configNr] + .stats->tx_packets - + rndis_per_dev_params [configNr] + .stats->tx_errors - + rndis_per_dev_params [configNr] + .stats->tx_dropped) + / 123); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -424,11 +399,12 @@ case OID_GEN_MULTICAST_BYTES_XMIT: DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->multicast*1234; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->multicast*1234); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -436,11 +412,12 @@ case OID_GEN_MULTICAST_FRAMES_XMIT: DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->multicast; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->multicast); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -448,11 +425,12 @@ case OID_GEN_BROADCAST_BYTES_XMIT: DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->tx_packets/42*255; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->tx_packets/42*255); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -460,35 +438,37 @@ case OID_GEN_BROADCAST_FRAMES_XMIT: DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->tx_packets/42; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->tx_packets/42); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; case OID_GEN_DIRECTED_BYTES_RCV: DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; case OID_GEN_DIRECTED_FRAMES_RCV: DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; case OID_GEN_MULTICAST_BYTES_RCV: DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->multicast*1111; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->multicast * 1111); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -496,11 +476,12 @@ case OID_GEN_MULTICAST_FRAMES_RCV: DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->multicast; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->multicast); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -508,11 +489,12 @@ case OID_GEN_BROADCAST_BYTES_RCV: DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->rx_packets/42*255; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->rx_packets/42*255); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -520,11 +502,12 @@ case OID_GEN_BROADCAST_FRAMES_RCV: DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->rx_packets/42; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->rx_packets/42); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -532,61 +515,25 @@ case OID_GEN_RCV_CRC_ERROR: DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { - *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. - stats->rx_crc_errors; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->rx_crc_errors); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; case OID_GEN_TRANSMIT_QUEUE_LENGTH: DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; - - case OID_GEN_GET_TIME_CAPS: - DEBUG("%s: OID_GEN_GET_TIME_CAPS\n", __FUNCTION__); - break; - - case OID_GEN_GET_NETCARD_TIME: - DEBUG("%s: OID_GEN_GET_NETCARD_TIME\n", __FUNCTION__); - break; - - case OID_GEN_NETCARD_LOAD: - DEBUG("%s: OID_GEN_NETCARD_LOAD\n", __FUNCTION__); - break; - - case OID_GEN_DEVICE_PROFILE: - DEBUG("%s: OID_GEN_DEVICE_PROFILE\n", __FUNCTION__); - break; - - case OID_GEN_INIT_TIME_MS: - DEBUG("%s: OID_GEN_INIT_TIME_MS\n", __FUNCTION__); - break; - - case OID_GEN_RESET_COUNTS: - DEBUG("%s: OID_GEN_RESET_COUNTS\n", __FUNCTION__); - break; - - case OID_GEN_MEDIA_SENSE_COUNTS: - DEBUG("%s: OID_GEN_MEDIA_SENSE_COUNTS\n", __FUNCTION__); - break; - - case OID_GEN_FRIENDLY_NAME: - DEBUG("%s: OID_GEN_FRIENDLY_NAME\n", __FUNCTION__); - break; - - case OID_GEN_MINIPORT_INFO: - DEBUG("%s: OID_GEN_MINIPORT_INFO\n", __FUNCTION__); - break; - - case OID_GEN_RESET_VERIFY_PARAMETERS: - DEBUG("%s: OID_GEN_RESET_VERIFY_PARAMETERS\n", __FUNCTION__); - break; - +#endif /* RNDIS_OPTIONAL_STATS */ + + /* ieee802.3 OIDs (table 4-3) */ + /* mandatory */ case OID_802_3_PERMANENT_ADDRESS: DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); @@ -597,7 +544,7 @@ length); retval = 0; } else { - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; @@ -619,7 +566,7 @@ DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); length = 4; /* Multicast base address only */ - *((u32 *) resp + 6) = 0xE0000000; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0xE0000000); retval = 0; break; @@ -628,22 +575,25 @@ DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); length = 4; /* Multicast base address only */ - *((u32 *) resp + 6) = 1; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (1); retval = 0; break; case OID_802_3_MAC_OPTIONS: DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); break; - + + /* ieee802.3 statistics OIDs (table 4-4) */ + /* mandatory */ case OID_802_3_RCV_ERROR_ALIGNMENT: DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { length = 4; - *((u32 *) resp + 6) = rndis_per_dev_params [configNr] - .stats->rx_frame_errors; + *((u32 *) resp + 6) = cpu_to_le32 ( + rndis_per_dev_params [configNr] + .stats->rx_frame_errors); retval = 0; } break; @@ -652,7 +602,7 @@ case OID_802_3_XMIT_ONE_COLLISION: DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; @@ -660,10 +610,11 @@ case OID_802_3_XMIT_MORE_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); length = 4; - *((u32 *) resp + 6) = 0; + *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; +#ifdef RNDIS_OPTIONAL_STATS case OID_802_3_XMIT_DEFERRED: DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); /* TODO */ @@ -698,14 +649,46 @@ DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); /* TODO */ break; - - default: printk (KERN_ERR "%s: unknown OID 0x%08X\n", +#endif /* RNDIS_OPTIONAL_STATS */ + +#ifdef RNDIS_PM + /* power management OIDs (table 4-5) */ + case OID_PNP_CAPABILITIES: + DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__); + + /* just PM, and remote wakeup on link status change + * (not magic packet or pattern match) + */ + length = sizeof (struct NDIS_PNP_CAPABILITIES); + memset (resp, 0, length); + { + struct NDIS_PNP_CAPABILITIES *caps = (void *) resp; + + caps->Flags = NDIS_DEVICE_WAKE_UP_ENABLE; + caps->WakeUpCapabilities.MinLinkChangeWakeUp + = NdisDeviceStateD3; + + /* FIXME then use usb_gadget_wakeup(), and + * set USB_CONFIG_ATT_WAKEUP in config desc + */ + } + retval = 0; + break; + case OID_PNP_QUERY_POWER: + DEBUG("%s: OID_PNP_QUERY_POWER\n", __FUNCTION__); + /* sure, handle any power state that maps to USB suspend */ + retval = 0; + break; +#endif + + default: + printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", __FUNCTION__, OID); } - resp->InformationBufferOffset = 16; - resp->InformationBufferLength = length; - resp->MessageLength = 24 + length; + resp->InformationBufferOffset = __constant_cpu_to_le32 (16); + resp->InformationBufferLength = cpu_to_le32 (length); + resp->MessageLength = cpu_to_le32 (24 + length); r->length = 24 + length; return retval; } @@ -715,9 +698,7 @@ { rndis_set_cmplt_type *resp; int i, retval = -ENOTSUPP; - struct rndis_config_parameter *param; struct rndis_params *params; - u8 *cp; if (!r) return -ENOMEM; @@ -725,20 +706,37 @@ if (!resp) return -ENOMEM; - cp = (u8 *)resp; + DEBUG("set OID %08x value, len %d:\n", OID, buf_len); + for (i = 0; i < buf_len; i += 16) { + DEBUG ("%03d: " + " %02x %02x %02x %02x" + " %02x %02x %02x %02x" + " %02x %02x %02x %02x" + " %02x %02x %02x %02x" + "\n", + i, + buf[i], buf [i+1], + buf[i+2], buf[i+3], + buf[i+4], buf [i+5], + buf[i+6], buf[i+7], + buf[i+8], buf [i+9], + buf[i+10], buf[i+11], + buf[i+12], buf [i+13], + buf[i+14], buf[i+15]); + } switch (OID) { case OID_GEN_CURRENT_PACKET_FILTER: params = &rndis_per_dev_params [configNr]; retval = 0; - /* FIXME use this NDIS_PACKET_TYPE_* bitflags to + /* FIXME use these NDIS_PACKET_TYPE_* bitflags to * filter packets in hard_start_xmit() * NDIS_PACKET_TYPE_x == CDC_PACKET_TYPE_x for x in: * PROMISCUOUS, DIRECTED, * MULTICAST, ALL_MULTICAST, BROADCAST */ - params->filter = *(u32 *)buf; + params->filter = cpu_to_le32p((u32 *)buf); DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", __FUNCTION__, params->filter); @@ -763,23 +761,40 @@ DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); retval = 0; break; - +#if 0 case OID_GEN_RNDIS_CONFIG_PARAMETER: - DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__); + { + struct rndis_config_parameter *param; param = (struct rndis_config_parameter *) buf; - if (param) { - for (i = 0; i < param->ParameterNameLength; i++) { - DEBUG ("%c", - *(buf + param->ParameterNameOffset + i)); - } - DEBUG ("\n"); + DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n", + __FUNCTION__, + min(cpu_to_le32(param->ParameterNameLength),80), + buf + param->ParameterNameOffset); + retval = 0; } - + break; +#endif + +#ifdef RNDIS_PM + case OID_PNP_SET_POWER: + DEBUG ("OID_PNP_SET_POWER\n"); + /* sure, handle any power state that maps to USB suspend */ retval = 0; break; - - default: printk (KERN_ERR "%s: unknown OID 0x%08X\n", - __FUNCTION__, OID); + + case OID_PNP_ENABLE_WAKE_UP: + /* always-connected ... */ + DEBUG ("OID_PNP_ENABLE_WAKE_UP\n"); + retval = 0; + break; + + // no PM resume patterns supported (specified where?) + // so OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN always fails +#endif + + default: + printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", + __FUNCTION__, OID, buf_len); } return retval; @@ -804,22 +819,24 @@ if (!resp) return -ENOMEM; - resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT; - resp->MessageLength = 52; - resp->RequestID = buf->RequestID; - resp->Status = RNDIS_STATUS_SUCCESS; - resp->MajorVersion = RNDIS_MAJOR_VERSION; - resp->MinorVersion = RNDIS_MINOR_VERSION; - resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS; - resp->Medium = RNDIS_MEDIUM_802_3; - resp->MaxPacketsPerTransfer = 1; - resp->MaxTransferSize = rndis_per_dev_params [configNr].dev->mtu + resp->MessageType = __constant_cpu_to_le32 ( + REMOTE_NDIS_INITIALIZE_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (52); + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); + resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION); + resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION); + resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS); + resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3); + resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1); + resp->MaxTransferSize = cpu_to_le32 ( + rndis_per_dev_params [configNr].dev->mtu + sizeof (struct ethhdr) + sizeof (struct rndis_packet_msg_type) - + 22; - resp->PacketAlignmentFactor = 0; - resp->AFListOffset = 0; - resp->AFListSize = 0; + + 22); + resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0); + resp->AFListOffset = __constant_cpu_to_le32 (0); + resp->AFListSize = __constant_cpu_to_le32 (0); if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( @@ -833,7 +850,7 @@ rndis_query_cmplt_type *resp; rndis_resp_t *r; - DEBUG("%s: OID = %08X\n", __FUNCTION__, buf->OID); + // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; /* @@ -847,17 +864,18 @@ if (!resp) return -ENOMEM; - resp->MessageType = REMOTE_NDIS_QUERY_CMPLT; - resp->MessageLength = 24; - resp->RequestID = buf->RequestID; + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (24); + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - if (gen_ndis_query_resp (configNr, buf->OID, r)) { + if (gen_ndis_query_resp (configNr, cpu_to_le32 (buf->OID), r)) { /* OID not supported */ - resp->Status = RNDIS_STATUS_NOT_SUPPORTED; - resp->InformationBufferLength = 0; - resp->InformationBufferOffset = 0; + resp->Status = __constant_cpu_to_le32 ( + RNDIS_STATUS_NOT_SUPPORTED); + resp->InformationBufferLength = __constant_cpu_to_le32 (0); + resp->InformationBufferOffset = __constant_cpu_to_le32 (0); } else - resp->Status = RNDIS_STATUS_SUCCESS; + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( @@ -867,38 +885,42 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) { + u32 BufLength, BufOffset; rndis_set_cmplt_type *resp; rndis_resp_t *r; - int i; r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_set_cmplt_type *) r->buf; if (!resp) return -ENOMEM; - - DEBUG("%s: Length: %d\n", __FUNCTION__, buf->InformationBufferLength); - DEBUG("%s: Offset: %d\n", __FUNCTION__, buf->InformationBufferOffset); + + BufLength = cpu_to_le32 (buf->InformationBufferLength); + BufOffset = cpu_to_le32 (buf->InformationBufferOffset); + +#ifdef VERBOSE + DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength); + DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset); DEBUG("%s: InfoBuffer: ", __FUNCTION__); - for (i = 0; i < buf->InformationBufferLength; i++) { - DEBUG ("%02x ", *(((u8 *) buf) + i + 12 + - buf->InformationBufferOffset)); + for (i = 0; i < BufLength; i++) { + DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); } DEBUG ("\n"); +#endif - resp->MessageType = REMOTE_NDIS_SET_CMPLT; - resp->MessageLength = 16; - resp->RequestID = buf->RequestID; - if (gen_ndis_set_resp (configNr, buf->OID, - ((u8 *) buf) + 28, - buf->InformationBufferLength, r)) - resp->Status = RNDIS_STATUS_NOT_SUPPORTED; - else resp->Status = RNDIS_STATUS_SUCCESS; + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (16); + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ + if (gen_ndis_set_resp (configNr, cpu_to_le32 (buf->OID), + ((u8 *) buf) + 8 + BufOffset, BufLength, r)) + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); + else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); if (rndis_per_dev_params [configNr].ack) - rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev); + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); return 0; } @@ -914,10 +936,11 @@ resp = (rndis_reset_cmplt_type *) r->buf; if (!resp) return -ENOMEM; - resp->MessageType = REMOTE_NDIS_RESET_CMPLT; - resp->MessageLength = 16; - resp->Status = RNDIS_STATUS_SUCCESS; - resp->AddressingReset = 1; /* resent information */ + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (16); + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); + /* resent information */ + resp->AddressingReset = __constant_cpu_to_le32 (1); if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( @@ -938,10 +961,11 @@ resp = (rndis_keepalive_cmplt_type *) r->buf; if (!resp) return -ENOMEM; - resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT; - resp->MessageLength = 16; - resp->RequestID = buf->RequestID; - resp->Status = RNDIS_STATUS_SUCCESS; + resp->MessageType = __constant_cpu_to_le32 ( + REMOTE_NDIS_KEEPALIVE_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (16); + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( @@ -969,11 +993,12 @@ resp = (rndis_indicate_status_msg_type *) r->buf; if (!resp) return -ENOMEM; - resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG; - resp->MessageLength = 20; - resp->Status = status; - resp->StatusBufferLength = 0; - resp->StatusBufferOffset = 0; + resp->MessageType = __constant_cpu_to_le32 ( + REMOTE_NDIS_INDICATE_STATUS_MSG); + resp->MessageLength = __constant_cpu_to_le32 (20); + resp->Status = cpu_to_le32 (status); + resp->StatusBufferLength = __constant_cpu_to_le32 (0); + resp->StatusBufferOffset = __constant_cpu_to_le32 (0); if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( @@ -1014,8 +1039,8 @@ return -ENOMEM; tmp = (u32 *) buf; - MsgType = *tmp; - MsgLength = *(tmp + 1); + MsgType = cpu_to_le32p(tmp++); + MsgLength = cpu_to_le32p(tmp++); if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP; @@ -1025,14 +1050,14 @@ switch (MsgType) { case REMOTE_NDIS_INITIALIZE_MSG: - DEBUG(KERN_INFO "%s: REMOTE_NDIS_INITIALIZE_MSG\n", + DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __FUNCTION__ ); params->state = RNDIS_INITIALIZED; return rndis_init_response (configNr, (rndis_init_msg_type *) buf); case REMOTE_NDIS_HALT_MSG: - DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n", + DEBUG("%s: REMOTE_NDIS_HALT_MSG\n", __FUNCTION__ ); params->state = RNDIS_UNINITIALIZED; if (params->dev) { @@ -1042,34 +1067,57 @@ return 0; case REMOTE_NDIS_QUERY_MSG: - DEBUG(KERN_INFO "%s: REMOTE_NDIS_QUERY_MSG\n", - __FUNCTION__ ); return rndis_query_response (configNr, (rndis_query_msg_type *) buf); case REMOTE_NDIS_SET_MSG: - DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n", - __FUNCTION__ ); return rndis_set_response (configNr, (rndis_set_msg_type *) buf); case REMOTE_NDIS_RESET_MSG: - DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n", + DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", __FUNCTION__ ); return rndis_reset_response (configNr, (rndis_reset_msg_type *) buf); case REMOTE_NDIS_KEEPALIVE_MSG: /* For USB: host does this every 5 seconds */ - DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n", +#ifdef VERBOSE + DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __FUNCTION__ ); +#endif return rndis_keepalive_response (configNr, (rndis_keepalive_msg_type *) buf); default: - printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n", - __FUNCTION__ , MsgType); + /* At least Windows XP emits some undefined RNDIS messages. + * In one case those messages seemed to relate to the host + * suspending itself. + */ + printk (KERN_WARNING + "%s: unknown RNDIS message 0x%08X len %d\n", + __FUNCTION__ , MsgType, MsgLength); + { + unsigned i; + for (i = 0; i < MsgLength; i += 16) { + DEBUG ("%03d: " + " %02x %02x %02x %02x" + " %02x %02x %02x %02x" + " %02x %02x %02x %02x" + " %02x %02x %02x %02x" + "\n", + i, + buf[i], buf [i+1], + buf[i+2], buf[i+3], + buf[i+4], buf [i+5], + buf[i+6], buf[i+7], + buf[i+8], buf [i+9], + buf[i+10], buf[i+11], + buf[i+12], buf [i+13], + buf[i+14], buf[i+15]); + } + } break; } @@ -1079,13 +1127,12 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *)) { u8 i; - DEBUG("%s: ", __FUNCTION__ ); for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { if (!rndis_per_dev_params [i].used) { rndis_per_dev_params [i].used = 1; rndis_per_dev_params [i].ack = rndis_control_ack; - DEBUG("configNr = %d\n", i); + DEBUG("%s: configNr = %d\n", __FUNCTION__, i); return i; } } @@ -1145,10 +1192,10 @@ if (!skb) return; skb_push (skb, sizeof (struct rndis_packet_msg_type)); memset (skb->data, 0, sizeof (struct rndis_packet_msg_type)); - *((u32 *) skb->data) = 1; - *((u32 *) skb->data + 1) = skb->len; - *((u32 *) skb->data + 2) = 36; - *((u32 *) skb->data + 3) = skb->len - 44; + *((u32 *) skb->data) = __constant_cpu_to_le32 (1); + *((u32 *) skb->data + 1) = cpu_to_le32(skb->len); + *((u32 *) skb->data + 2) = __constant_cpu_to_le32 (36); + *((u32 *) skb->data + 3) = cpu_to_le32(skb->len - 44); return; } @@ -1208,14 +1255,16 @@ int rndis_rm_hdr (u8 *buf, u32 *length) { - u32 i, messageLen, dataOffset; + u32 i, messageLen, dataOffset, *tmp; + tmp = (u32 *) buf; + if (!buf || !length) return -1; - if (*((u32 *) buf) != 1) return -1; + if (cpu_to_le32p(tmp++) != 1) return -1; - messageLen = *((u32 *) buf + 1); - - dataOffset = *((u32 *) buf + 2) + 8; + messageLen = cpu_to_le32p(tmp++); + dataOffset = cpu_to_le32p(tmp++) + 8; + if (messageLen < dataOffset || messageLen > *length) return -1; for (i = dataOffset; i < messageLen; i++) diff -Nru a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h --- a/drivers/usb/gadget/rndis.h 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/gadget/rndis.h 2004-06-26 17:09:16 -07:00 @@ -59,10 +59,18 @@ #define RNDIS_MEDIUM_802_3 0x00000000U +/* from drivers/net/sk98lin/h/skgepnmi.h */ +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 + + /* supported OIDs */ static const u32 oid_supported_list [] = { - /* mandatory general */ /* the general stuff */ OID_GEN_SUPPORTED_LIST, OID_GEN_HARDWARE_STATUS, @@ -70,7 +78,6 @@ OID_GEN_MEDIA_IN_USE, OID_GEN_MAXIMUM_FRAME_SIZE, OID_GEN_LINK_SPEED, - OID_GEN_TRANSMIT_BUFFER_SPACE, OID_GEN_TRANSMIT_BLOCK_SIZE, OID_GEN_RECEIVE_BLOCK_SIZE, OID_GEN_VENDOR_ID, @@ -78,10 +85,11 @@ OID_GEN_VENDOR_DRIVER_VERSION, OID_GEN_CURRENT_PACKET_FILTER, OID_GEN_MAXIMUM_TOTAL_SIZE, - OID_GEN_MAC_OPTIONS, OID_GEN_MEDIA_CONNECT_STATUS, OID_GEN_PHYSICAL_MEDIUM, +#if 0 OID_GEN_RNDIS_CONFIG_PARAMETER, +#endif /* the statistical stuff */ OID_GEN_XMIT_OK, @@ -89,6 +97,7 @@ OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR, OID_GEN_RCV_NO_BUFFER, +#ifdef RNDIS_OPTIONAL_STATS OID_GEN_DIRECTED_BYTES_XMIT, OID_GEN_DIRECTED_FRAMES_XMIT, OID_GEN_MULTICAST_BYTES_XMIT, @@ -103,6 +112,7 @@ OID_GEN_BROADCAST_FRAMES_RCV, OID_GEN_RCV_CRC_ERROR, OID_GEN_TRANSMIT_QUEUE_LENGTH, +#endif /* RNDIS_OPTIONAL_STATS */ /* mandatory 802.3 */ /* the general stuff */ @@ -115,7 +125,30 @@ /* the statistical stuff */ OID_802_3_RCV_ERROR_ALIGNMENT, OID_802_3_XMIT_ONE_COLLISION, - OID_802_3_XMIT_MORE_COLLISIONS + OID_802_3_XMIT_MORE_COLLISIONS, +#ifdef RNDIS_OPTIONAL_STATS + OID_802_3_XMIT_DEFERRED, + OID_802_3_XMIT_MAX_COLLISIONS, + OID_802_3_RCV_OVERRUN, + OID_802_3_XMIT_UNDERRUN, + OID_802_3_XMIT_HEARTBEAT_FAILURE, + OID_802_3_XMIT_TIMES_CRS_LOST, + OID_802_3_XMIT_LATE_COLLISIONS, +#endif /* RNDIS_OPTIONAL_STATS */ + +#ifdef RNDIS_PM + /* PM and wakeup are mandatory for USB: */ + + /* power management */ + OID_PNP_CAPABILITIES, + OID_PNP_QUERY_POWER, + OID_PNP_SET_POWER, + + /* wake up host */ + OID_PNP_ENABLE_WAKE_UP, + OID_PNP_ADD_WAKE_UP_PATTERN, + OID_PNP_REMOVE_WAKE_UP_PATTERN, +#endif }; diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/host/ehci-hcd.c 2004-06-26 17:09:19 -07:00 @@ -290,16 +290,17 @@ { if (cap & (1 << 16)) { int msec = 500; + struct pci_dev *pdev = to_pci_dev(ehci->hcd.self.controller); /* request handoff to OS */ - cap &= 1 << 24; - pci_write_config_dword (to_pci_dev(ehci->hcd.self.controller), where, cap); + cap |= 1 << 24; + pci_write_config_dword(pdev, where, cap); /* and wait a while for it to happen */ do { msleep(10); msec -= 10; - pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller), where, &cap); + pci_read_config_dword(pdev, where, &cap); } while ((cap & (1 << 16)) && msec); if (cap & (1 << 16)) { ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n", @@ -520,7 +521,7 @@ /* wire up the root hub */ bus = hcd_to_bus (hcd); - bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0); + udev = usb_alloc_dev (NULL, bus, 0); if (!udev) { done2: ehci_mem_cleanup (ehci); @@ -553,11 +554,10 @@ * and device drivers may start it running. */ udev->speed = USB_SPEED_HIGH; - if (hcd_register_root (hcd) != 0) { + if (hcd_register_root (udev, hcd) != 0) { if (hcd->state == USB_STATE_RUNNING) ehci_ready (ehci); ehci_reset (ehci); - bus->root_hub = 0; usb_put_dev (udev); retval = -ENODEV; goto done2; diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c --- a/drivers/usb/host/ehci-sched.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/host/ehci-sched.c 2004-06-26 17:09:17 -07:00 @@ -483,7 +483,7 @@ qh->start = frame; /* reset S-frame and (maybe) C-frame masks */ - qh->hw_info2 &= ~0xffff; + qh->hw_info2 &= ~__constant_cpu_to_le32(0xffff); qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask; } else dbg ("reused previous qh %p schedule", qh); diff -Nru a/drivers/usb/host/hc_sl811_rh.c b/drivers/usb/host/hc_sl811_rh.c --- a/drivers/usb/host/hc_sl811_rh.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/host/hc_sl811_rh.c 2004-06-26 17:09:19 -07:00 @@ -557,18 +557,24 @@ static int rh_connect_rh (hci_t * hci) { struct usb_device *usb_dev; + int retval; hci->rh.devnum = 0; usb_dev = usb_alloc_dev (NULL, hci->bus, 0); if (!usb_dev) return -ENOMEM; - hci->bus->root_hub = usb_dev; usb_dev->devnum = 1; usb_dev->bus->devnum_next = usb_dev->devnum + 1; set_bit (usb_dev->devnum, usb_dev->bus->devmap.devicemap); - if (usb_new_device (usb_dev) != 0) { + down (&usb_bus_list_lock); + hci->bus->root_hub = usb_dev; + retval = usb_new_device (usb_dev); + if (retval != 0) + hci->bus->root_hub = NULL; + up (&usb_bus_list_lock); + if (retval != 0) { usb_put_dev (usb_dev); return -ENODEV; } diff -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c --- a/drivers/usb/host/ohci-dbg.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/host/ohci-dbg.c 2004-06-26 17:09:20 -07:00 @@ -134,13 +134,13 @@ struct ohci_regs *regs = controller->regs; u32 temp; - temp = readl (®s->revision) & 0xff; + temp = ohci_readl (®s->revision) & 0xff; ohci_dbg_sw (controller, next, size, "OHCI %d.%d, %s legacy support registers\n", 0x03 & (temp >> 4), (temp & 0x0f), (temp & 0x10) ? "with" : "NO"); - temp = readl (®s->control); + temp = ohci_readl (®s->control); ohci_dbg_sw (controller, next, size, "control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n", temp, @@ -155,7 +155,7 @@ temp & OHCI_CTRL_CBSR ); - temp = readl (®s->cmdstatus); + temp = ohci_readl (®s->cmdstatus); ohci_dbg_sw (controller, next, size, "cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp, (temp & OHCI_SOC) >> 16, @@ -166,26 +166,26 @@ ); ohci_dump_intr_mask (controller, "intrstatus", - readl (®s->intrstatus), next, size); + ohci_readl (®s->intrstatus), next, size); ohci_dump_intr_mask (controller, "intrenable", - readl (®s->intrenable), next, size); + ohci_readl (®s->intrenable), next, size); // intrdisable always same as intrenable maybe_print_eds (controller, "ed_periodcurrent", - readl (®s->ed_periodcurrent), next, size); + ohci_readl (®s->ed_periodcurrent), next, size); maybe_print_eds (controller, "ed_controlhead", - readl (®s->ed_controlhead), next, size); + ohci_readl (®s->ed_controlhead), next, size); maybe_print_eds (controller, "ed_controlcurrent", - readl (®s->ed_controlcurrent), next, size); + ohci_readl (®s->ed_controlcurrent), next, size); maybe_print_eds (controller, "ed_bulkhead", - readl (®s->ed_bulkhead), next, size); + ohci_readl (®s->ed_bulkhead), next, size); maybe_print_eds (controller, "ed_bulkcurrent", - readl (®s->ed_bulkcurrent), next, size); + ohci_readl (®s->ed_bulkcurrent), next, size); maybe_print_eds (controller, "donehead", - readl (®s->donehead), next, size); + ohci_readl (®s->donehead), next, size); } #define dbg_port_sw(hc,num,value,next,size) \ @@ -637,7 +637,7 @@ "hcca frame 0x%04x\n", OHCI_FRAME_NO(ohci->hcca)); /* other registers mostly affect frame timings */ - rdata = readl (®s->fminterval); + rdata = ohci_readl (®s->fminterval); temp = scnprintf (next, size, "fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n", rdata, (rdata >> 31) ? " FIT" : "", @@ -645,20 +645,20 @@ size -= temp; next += temp; - rdata = readl (®s->fmremaining); + rdata = ohci_readl (®s->fmremaining); temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n", rdata, (rdata >> 31) ? " FRT" : "", rdata & 0x3fff); size -= temp; next += temp; - rdata = readl (®s->periodicstart); + rdata = ohci_readl (®s->periodicstart); temp = scnprintf (next, size, "periodicstart 0x%04x\n", rdata & 0x3fff); size -= temp; next += temp; - rdata = readl (®s->lsthresh); + rdata = ohci_readl (®s->lsthresh); temp = scnprintf (next, size, "lsthresh 0x%04x\n", rdata & 0x3fff); size -= temp; diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/host/ohci-hcd.c 2004-06-26 17:09:15 -07:00 @@ -17,6 +17,7 @@ * * History: * + * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer) * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net) * 2003/02/24 show registers in sysfs (Kevin Brosius) * @@ -393,7 +394,7 @@ /* boot firmware should have set this up (5.1.1.3.1) */ if (!ohci->fminterval) { - temp = readl (&ohci->regs->fminterval); + temp = ohci_readl (&ohci->regs->fminterval); if (temp & 0x3fff0000) ohci->fminterval = temp; else @@ -405,7 +406,7 @@ * On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ #ifndef __hppa__ - if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { + if (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) { ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n"); /* this timeout is arbitrary. we make it long, so systems @@ -416,7 +417,7 @@ writel (OHCI_INTR_OC, &ohci->regs->intrenable); writel (OHCI_OCR, &ohci->regs->cmdstatus); - while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { + while (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) { msleep (10); if (--temp == 0) { ohci_err (ohci, "USB HC TakeOver failed!\n"); @@ -430,13 +431,13 @@ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); ohci_dbg (ohci, "reset, control = 0x%x\n", - readl (&ohci->regs->control)); + ohci_readl (&ohci->regs->control)); /* Reset USB (needed by some controllers); RemoteWakeupConnected * saved if boot firmware (BIOS/SMM/...) told us it's connected * (for OHCI integrated on mainboard, it normally is) */ - ohci->hc_control = readl (&ohci->regs->control); + ohci->hc_control = ohci_readl (&ohci->regs->control); ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */ if (ohci->hc_control) ohci->hcd.can_wakeup = 1; @@ -450,13 +451,13 @@ &ohci->regs->roothub.portstatus [temp]); } // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); msleep (50); /* HC Reset requires max 10 us delay */ writel (OHCI_HCR, &ohci->regs->cmdstatus); temp = 30; /* ... allow extra time */ - while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { + while ((ohci_readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { if (--temp == 0) { ohci_err (ohci, "USB HC reset timed out!\n"); return -1; @@ -473,7 +474,7 @@ */ writel (ohci->hc_control, &ohci->regs->control); // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); return 0; } @@ -505,8 +506,8 @@ /* some OHCI implementations are finicky about how they init. * bogus values here mean not even enumeration could work. */ - if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0 - || !readl (&ohci->regs->periodicstart)) { + if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0 + || !ohci_readl (&ohci->regs->periodicstart)) { ohci_err (ohci, "init err\n"); return -EOVERFLOW; } @@ -548,7 +549,7 @@ writel (RH_HS_LPSC, &ohci->regs->roothub.status); writel (power_switching ? RH_B_PPCM : 0, &ohci->regs->roothub.b); // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); // POTPGT delay is bits 24-31, in 2 ms units. mdelay ((roothub_a (ohci) >> 23) & 0x1fe); @@ -560,7 +561,7 @@ } /* connect the virtual root hub */ - bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0); + udev = usb_alloc_dev (NULL, bus, 0); ohci->hcd.state = USB_STATE_RUNNING; if (!udev) { disable (ohci); @@ -570,9 +571,8 @@ } udev->speed = USB_SPEED_FULL; - if (hcd_register_root (&ohci->hcd) != 0) { + if (hcd_register_root (udev, &ohci->hcd) != 0) { usb_put_dev (udev); - bus->root_hub = NULL; disable (ohci); ohci->hc_control &= ~OHCI_CTRL_HCFS; writel (ohci->hc_control, &ohci->regs->control); @@ -592,19 +592,20 @@ struct ohci_regs *regs = ohci->regs; int ints; - /* we can eliminate a (slow) readl() if _only_ WDH caused this irq */ + /* we can eliminate a (slow) ohci_readl() + if _only_ WDH caused this irq */ if ((ohci->hcca->done_head != 0) && ! (le32_to_cpup (&ohci->hcca->done_head) & 0x01)) { ints = OHCI_INTR_WDH; /* cardbus/... hardware gone before remove() */ - } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) { + } else if ((ints = ohci_readl (®s->intrstatus)) == ~(u32)0) { disable (ohci); ohci_dbg (ohci, "device removed!\n"); return IRQ_HANDLED; /* interrupt for some other device? */ - } else if ((ints &= readl (®s->intrenable)) == 0) { + } else if ((ints &= ohci_readl (®s->intrenable)) == 0) { return IRQ_NONE; } @@ -650,7 +651,7 @@ writel (ints, ®s->intrstatus); writel (OHCI_INTR_MIE, ®s->intrenable); // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); } return IRQ_HANDLED; @@ -798,6 +799,14 @@ #include "ohci-omap.c" #endif -#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111) || defined(CONFIG_ARCH_OMAP)) +#ifdef CONFIG_ARCH_LH7A404 +#include "ohci-lh7a404.c" +#endif + +#if !(defined(CONFIG_PCI) \ + || defined(CONFIG_SA1111) \ + || defined(CONFIG_ARCH_OMAP) \ + || defined (CONFIG_ARCH_LH7A404) \ + ) #error "missing bus glue for ohci-hcd" #endif diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c --- a/drivers/usb/host/ohci-hub.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/host/ohci-hub.c 2004-06-26 17:09:16 -07:00 @@ -20,20 +20,20 @@ * till some bits (mostly reserved) are clear; ok for all revs. */ #define read_roothub(hc, register, mask) ({ \ - u32 temp = readl (&hc->regs->roothub.register); \ + u32 temp = ohci_readl (&hc->regs->roothub.register); \ if (temp == -1) \ disable (hc); \ else if (hc->flags & OHCI_QUIRK_AMD756) \ while (temp & mask) \ - temp = readl (&hc->regs->roothub.register); \ + temp = ohci_readl (&hc->regs->roothub.register); \ temp; }) static u32 roothub_a (struct ohci_hcd *hc) { return read_roothub (hc, a, 0xfc0fe000); } static inline u32 roothub_b (struct ohci_hcd *hc) - { return readl (&hc->regs->roothub.b); } + { return ohci_readl (&hc->regs->roothub.b); } static inline u32 roothub_status (struct ohci_hcd *hc) - { return readl (&hc->regs->roothub.status); } + { return ohci_readl (&hc->regs->roothub.status); } static u32 roothub_portstatus (struct ohci_hcd *hc, int i) { return read_roothub (hc, portstatus [i], 0xffe0fce0); } @@ -83,14 +83,14 @@ spin_lock_irq (&ohci->lock); - ohci->hc_control = readl (&ohci->regs->control); + ohci->hc_control = ohci_readl (&ohci->regs->control); switch (ohci->hc_control & OHCI_CTRL_HCFS) { case OHCI_USB_RESUME: ohci_dbg (ohci, "resume/suspend?\n"); ohci->hc_control &= ~OHCI_CTRL_HCFS; ohci->hc_control |= OHCI_USB_RESET; writel (ohci->hc_control, &ohci->regs->control); - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); /* FALL THROUGH */ case OHCI_USB_RESET: status = -EBUSY; @@ -109,7 +109,7 @@ ohci->hc_control &= ~OHCI_SCHED_ENABLES; writel (ohci->hc_control, &ohci->regs->control); - ohci->hc_control = readl (&ohci->regs->control); + ohci->hc_control = ohci_readl (&ohci->regs->control); writel (OHCI_INTR_SF, &ohci->regs->intrstatus); /* sched disables take effect on the next frame, @@ -120,7 +120,7 @@ while (limit > 0) { udelay (250); limit =- 250; - if (readl (&ohci->regs->intrstatus) & OHCI_INTR_SF) + if (ohci_readl (&ohci->regs->intrstatus) & OHCI_INTR_SF) break; } dl_done_list (ohci, 0); @@ -128,7 +128,7 @@ } dl_done_list (ohci, 0); finish_unlinks (ohci, OHCI_FRAME_NO(ohci->hcca), 0); - writel (readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus); + writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus); /* maybe resume can wake root hub */ if (ohci->hcd.remote_wakeup) @@ -140,7 +140,7 @@ ohci->hc_control &= ~OHCI_CTRL_HCFS; ohci->hc_control |= OHCI_USB_SUSPEND; writel (ohci->hc_control, &ohci->regs->control); - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); /* no resumes until devices finish suspending */ ohci->next_statechange = jiffies + msecs_to_jiffies (5); @@ -179,13 +179,13 @@ return -EAGAIN; spin_lock_irq (&ohci->lock); - ohci->hc_control = readl (&ohci->regs->control); + ohci->hc_control = ohci_readl (&ohci->regs->control); switch (ohci->hc_control & OHCI_CTRL_HCFS) { case OHCI_USB_SUSPEND: ohci->hc_control &= ~(OHCI_CTRL_HCFS|OHCI_SCHED_ENABLES); ohci->hc_control |= OHCI_USB_RESUME; writel (ohci->hc_control, &ohci->regs->control); - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); ohci_dbg (ohci, "resume root hub\n"); break; case OHCI_USB_RESUME: @@ -210,7 +210,7 @@ temp = roothub_a (ohci) & RH_A_NDP; enables = 0; while (temp--) { - u32 stat = readl (&ohci->regs->roothub.portstatus [temp]); + u32 stat = ohci_readl (&ohci->regs->roothub.portstatus [temp]); /* force global, not selective, resume */ if (!(stat & RH_PS_PSS)) @@ -222,7 +222,7 @@ ohci->hcd.state = USB_STATE_RESUMING; mdelay (20 /* usb 11.5.1.10 */ + 15); - temp = readl (&ohci->regs->control); + temp = ohci_readl (&ohci->regs->control); temp &= OHCI_CTRL_HCFS; if (temp != OHCI_USB_RESUME) { ohci_err (ohci, "controller won't resume\n"); @@ -243,11 +243,11 @@ writel (OHCI_INTR_INIT, &ohci->regs->intrenable); if (ohci->ed_rm_list) writel (OHCI_INTR_SF, &ohci->regs->intrenable); - writel (readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus); + writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus); /* Then re-enable operations */ writel (OHCI_USB_OPER, &ohci->regs->control); - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); msleep (3); temp = OHCI_CONTROL_INIT | OHCI_USB_OPER; @@ -255,7 +255,7 @@ temp |= OHCI_CTRL_RWC; ohci->hc_control = temp; writel (temp, &ohci->regs->control); - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); /* TRSMRCY */ msleep (10); @@ -290,7 +290,7 @@ writel (ohci->hc_control, &ohci->regs->control); if (temp) writel (status, &ohci->regs->cmdstatus); - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); } ohci->hcd.state = USB_STATE_RUNNING; @@ -332,7 +332,7 @@ if (!HCD_IS_RUNNING(ohci->hcd.state)) return -ESHUTDOWN; ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n", - ports, readl (&ohci->regs->roothub.a) & RH_A_NDP); + ports, ohci_readl (&ohci->regs->roothub.a) & RH_A_NDP); /* retry later; "should not happen" */ return 0; } @@ -496,7 +496,7 @@ goto error; } writel (temp, &ohci->regs->roothub.portstatus [wIndex]); - // readl (&ohci->regs->roothub.portstatus [wIndex]); + // ohci_readl (&ohci->regs->roothub.portstatus [wIndex]); break; case GetHubDescriptor: ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf); @@ -541,7 +541,7 @@ &ohci->regs->roothub.portstatus [wIndex]); break; case USB_PORT_FEAT_RESET: - temp = readl (&ohci->regs->roothub.portstatus [wIndex]); + temp = ohci_readl (&ohci->regs->roothub.portstatus [wIndex]); if (temp & RH_PS_CCS) writel (RH_PS_PRS, &ohci->regs->roothub.portstatus [wIndex]); diff -Nru a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/usb/host/ohci-lh7a404.c 2004-06-26 17:09:21 -07:00 @@ -0,0 +1,385 @@ +/* + * OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * (C) Copyright 2002 Hewlett-Packard Company + * + * Bus Glue for Sharp LH7A404 + * + * Written by Christopher Hoover + * Based on fragments of previous driver by Rusell King et al. + * + * Modified for LH7A404 from ohci-sa1111.c + * by Durgesh Pattamatta + * + * This file is licenced under the GPL. + */ + +#include +#include +#include + + +extern int usb_disabled(void); + +/*-------------------------------------------------------------------------*/ + +static void lh7a404_start_hc(struct platform_device *dev) +{ + printk(KERN_DEBUG __FILE__ + ": starting LH7A404 OHCI USB Controller\n"); + + /* + * Now, carefully enable the USB clock, and take + * the USB host controller out of reset. + */ + CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */ + udelay(1000); + USBH_CMDSTATUS = OHCI_HCR; + + printk(KERN_DEBUG __FILE__ + ": Clock to USB host has been enabled \n"); +} + +static void lh7a404_stop_hc(struct platform_device *dev) +{ + printk(KERN_DEBUG __FILE__ + ": stopping LH7A404 OHCI USB Controller\n"); + + CSC_PWRCNT &= ~CSC_PWRCNT_USBH_EN; /* Disable clock */ +} + + +/*-------------------------------------------------------------------------*/ + + +static irqreturn_t usb_hcd_lh7a404_hcim_irq (int irq, void *__hcd, + struct pt_regs * r) +{ + struct usb_hcd *hcd = __hcd; + + return usb_hcd_irq(irq, hcd, r); +} + +/*-------------------------------------------------------------------------*/ + +void usb_hcd_lh7a404_remove (struct usb_hcd *, struct platform_device *); + +/* configure so an HC device and id are always provided */ +/* always called with process context; sleeping is OK */ + + +/** + * usb_hcd_lh7a404_probe - initialize LH7A404-based HCDs + * Context: !in_interrupt() + * + * Allocates basic resources for this USB host controller, and + * then invokes the start() method for the HCD associated with it + * through the hotplug entry's driver_data. + * + */ +int usb_hcd_lh7a404_probe (const struct hc_driver *driver, + struct usb_hcd **hcd_out, + struct platform_device *dev) +{ + int retval; + struct usb_hcd *hcd = 0; + + unsigned int *addr = NULL; + + if (!request_mem_region(dev->resource[0].start, + dev->resource[0].end + - dev->resource[0].start + 1, hcd_name)) { + pr_debug("request_mem_region failed"); + return -EBUSY; + } + + + lh7a404_start_hc(dev); + + addr = ioremap(dev->resource[0].start, + dev->resource[0].end + - dev->resource[0].start + 1); + if (!addr) { + pr_debug("ioremap failed"); + retval = -ENOMEM; + goto err1; + } + + + hcd = driver->hcd_alloc (); + if (hcd == NULL){ + pr_debug ("hcd_alloc failed"); + retval = -ENOMEM; + goto err1; + } + + if(dev->resource[1].flags != IORESOURCE_IRQ){ + pr_debug ("resource[1] is not IORESOURCE_IRQ"); + retval = -ENOMEM; + goto err1; + } + + hcd->driver = (struct hc_driver *) driver; + hcd->description = driver->description; + hcd->irq = dev->resource[1].start; + hcd->regs = addr; + hcd->self.controller = &dev->dev; + + retval = hcd_buffer_create (hcd); + if (retval != 0) { + pr_debug ("pool alloc fail"); + goto err1; + } + + retval = request_irq (hcd->irq, usb_hcd_lh7a404_hcim_irq, SA_INTERRUPT, + hcd->description, hcd); + if (retval != 0) { + pr_debug("request_irq failed"); + retval = -EBUSY; + goto err2; + } + + pr_debug ("%s (LH7A404) at 0x%p, irq %d", + hcd->description, hcd->regs, hcd->irq); + + usb_bus_init (&hcd->self); + hcd->self.op = &usb_hcd_operations; + hcd->self.hcpriv = (void *) hcd; + hcd->self.bus_name = "lh7a404"; + hcd->product_desc = "LH7A404 OHCI"; + + INIT_LIST_HEAD (&hcd->dev_list); + + usb_register_bus (&hcd->self); + + if ((retval = driver->start (hcd)) < 0) + { + usb_hcd_lh7a404_remove(hcd, dev); + return retval; + } + + *hcd_out = hcd; + return 0; + + err2: + hcd_buffer_destroy (hcd); + if (hcd) + driver->hcd_free(hcd); + err1: + lh7a404_stop_hc(dev); + release_mem_region(dev->resource[0].start, + dev->resource[0].end + - dev->resource[0].start + 1); + return retval; +} + + +/* may be called without controller electrically present */ +/* may be called with controller, bus, and devices active */ + +/** + * usb_hcd_lh7a404_remove - shutdown processing for LH7A404-based HCDs + * @dev: USB Host Controller being removed + * Context: !in_interrupt() + * + * Reverses the effect of usb_hcd_lh7a404_probe(), first invoking + * the HCD's stop() method. It is always called from a thread + * context, normally "rmmod", "apmd", or something similar. + * + */ +void usb_hcd_lh7a404_remove (struct usb_hcd *hcd, struct platform_device *dev) +{ + void *base; + + pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state); + + if (in_interrupt ()) + BUG (); + + hcd->state = USB_STATE_QUIESCING; + + pr_debug ("%s: roothub graceful disconnect", hcd->self.bus_name); + usb_disconnect (&hcd->self.root_hub); + + hcd->driver->stop (hcd); + hcd->state = USB_STATE_HALT; + + free_irq (hcd->irq, hcd); + hcd_buffer_destroy (hcd); + + usb_deregister_bus (&hcd->self); + + base = hcd->regs; + hcd->driver->hcd_free (hcd); + + lh7a404_stop_hc(dev); + release_mem_region(dev->resource[0].start, + dev->resource[0].end + - dev->resource[0].start + 1); +} + +/*-------------------------------------------------------------------------*/ + +static int __devinit +ohci_lh7a404_start (struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + int ret; + + ohci_dbg (ohci, "ohci_lh7a404_start, ohci:%p", ohci); + + ohci->hcca = dma_alloc_coherent (hcd->self.controller, + sizeof *ohci->hcca, &ohci->hcca_dma, 0); + if (!ohci->hcca) + return -ENOMEM; + + ohci_dbg (ohci, "ohci_lh7a404_start, ohci->hcca:%p", + ohci->hcca); + + memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); + + if ((ret = ohci_mem_init (ohci)) < 0) { + ohci_stop (hcd); + return ret; + } + ohci->regs = hcd->regs; + + if (hc_reset (ohci) < 0) { + ohci_stop (hcd); + return -ENODEV; + } + + if (hc_start (ohci) < 0) { + err ("can't start %s", ohci->hcd.self.bus_name); + ohci_stop (hcd); + return -EBUSY; + } + create_debug_files (ohci); + +#ifdef DEBUG + ohci_dump (ohci, 1); +#endif /*DEBUG*/ + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static const struct hc_driver ohci_lh7a404_hc_driver = { + .description = hcd_name, + + /* + * generic hardware linkage + */ + .irq = ohci_irq, + .flags = HCD_USB11, + + /* + * basic lifecycle operations + */ + .start = ohci_lh7a404_start, +#ifdef CONFIG_PM + /* suspend: ohci_lh7a404_suspend, -- tbd */ + /* resume: ohci_lh7a404_resume, -- tbd */ +#endif /*CONFIG_PM*/ + .stop = ohci_stop, + + /* + * memory lifecycle (except per-request) + */ + .hcd_alloc = ohci_hcd_alloc, + .hcd_free = ohci_hcd_free, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ohci_urb_enqueue, + .urb_dequeue = ohci_urb_dequeue, + .endpoint_disable = ohci_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = ohci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ohci_hub_status_data, + .hub_control = ohci_hub_control, +}; + +/*-------------------------------------------------------------------------*/ + +static int ohci_hcd_lh7a404_drv_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct usb_hcd *hcd = NULL; + int ret; + + pr_debug ("In ohci_hcd_lh7a404_drv_probe"); + + if (usb_disabled()) + return -ENODEV; + + ret = usb_hcd_lh7a404_probe(&ohci_lh7a404_hc_driver, &hcd, pdev); + + if (ret == 0) + dev_set_drvdata(dev, hcd); + + return ret; +} + +static int ohci_hcd_lh7a404_drv_remove(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct usb_hcd *hcd = dev_get_drvdata(dev); + + usb_hcd_lh7a404_remove(hcd, pdev); + dev_set_drvdata(dev, NULL); + return 0; +} + /*TBD*/ +/*static int ohci_hcd_lh7a404_drv_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct usb_hcd *hcd = dev_get_drvdata(dev); + + return 0; +} +static int ohci_hcd_lh7a404_drv_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct usb_hcd *hcd = dev_get_drvdata(dev); + + + return 0; +} +*/ + +static struct device_driver ohci_hcd_lh7a404_driver = { + .name = "lh7a404-ohci", + .bus = &platform_bus_type, + .probe = ohci_hcd_lh7a404_drv_probe, + .remove = ohci_hcd_lh7a404_drv_remove, + /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ + /*.resume = ohci_hcd_lh7a404_drv_resume, */ +}; + +static int __init ohci_hcd_lh7a404_init (void) +{ + pr_debug (DRIVER_INFO " (LH7A404)"); + pr_debug ("block sizes: ed %d td %d\n", + sizeof (struct ed), sizeof (struct td)); + + return driver_register(&ohci_hcd_lh7a404_driver); +} + +static void __exit ohci_hcd_lh7a404_cleanup (void) +{ + driver_unregister(&ohci_hcd_lh7a404_driver); +} + +module_init (ohci_hcd_lh7a404_init); +module_exit (ohci_hcd_lh7a404_cleanup); diff -Nru a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c --- a/drivers/usb/host/ohci-omap.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/host/ohci-omap.c 2004-06-26 17:09:19 -07:00 @@ -454,7 +454,6 @@ */ void usb_hcd_omap_remove (struct usb_hcd *hcd, struct omap_dev *dev) { - struct usb_device *hub; void *base; info ("remove: %s, state %x", hcd->self.bus_name, hcd->state); @@ -462,11 +461,10 @@ if (in_interrupt ()) BUG (); - hub = hcd->self.root_hub; hcd->state = USB_STATE_QUIESCING; dbg ("%s: roothub graceful disconnect", hcd->self.bus_name); - usb_disconnect (&hub); + usb_disconnect (&hcd->self.root_hub); hcd->driver->stop (hcd); hcd_buffer_destroy (hcd); diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/host/ohci-q.c 2004-06-26 17:09:20 -07:00 @@ -321,7 +321,7 @@ if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_CLE; writel (ohci->hc_control, &ohci->regs->control); - // a readl() later syncs CLE with the HC + // a ohci_readl() later syncs CLE with the HC } else writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead); @@ -345,7 +345,7 @@ if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_BLE; writel (ohci->hc_control, &ohci->regs->control); - // a readl() later syncs BLE with the HC + // a ohci_readl() later syncs BLE with the HC } else writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead); @@ -481,7 +481,7 @@ writel (OHCI_INTR_SF, &ohci->regs->intrstatus); writel (OHCI_INTR_SF, &ohci->regs->intrenable); // flush those writes, and get latest HCCA contents - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); /* SF interrupt might get delayed; record the frame counter value that * indicates when the HC isn't looking at it, so concurrent unlinks diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c --- a/drivers/usb/host/ohci-sa1111.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/host/ohci-sa1111.c 2004-06-26 17:09:18 -07:00 @@ -237,7 +237,6 @@ */ void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev) { - struct usb_device *hub; void *base; info ("remove: %s, state %x", hcd->self.bus_name, hcd->state); @@ -245,11 +244,10 @@ if (in_interrupt ()) BUG (); - hub = hcd->self.root_hub; hcd->state = USB_STATE_QUIESCING; dbg ("%s: roothub graceful disconnect", hcd->self.bus_name); - usb_disconnect (&hub); + usb_disconnect (&hcd->self.root_hub); hcd->driver->stop (hcd); hcd->state = USB_STATE_HALT; diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h --- a/drivers/usb/host/ohci.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/host/ohci.h 2004-06-26 17:09:21 -07:00 @@ -429,3 +429,22 @@ # define ohci_vdbg(ohci, fmt, args...) do { } while (0) #endif +#ifdef CONFIG_ARCH_LH7A404 + /* Marc Singer: at the time this code was written, the LH7A404 + * had a problem reading the USB host registers. This + * implementation of the ohci_readl function performs the read + * twice as a work-around. + */ +static inline unsigned int ohci_readl (void* regs) +{ + *(volatile unsigned int*) regs; + return *(volatile unsigned int*) regs; +} +#else + /* Standard version of ohci_readl uses standard, platform + * specific implementation. */ +static inline unsigned int ohci_readl (void* regs) +{ + return readl (regs); +} +#endif diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/host/uhci-hcd.c 2004-06-26 17:09:20 -07:00 @@ -103,8 +103,8 @@ static void hc_state_transitions(struct uhci_hcd *uhci); /* If a transfer is still active after this much time, turn off FSBR */ -#define IDLE_TIMEOUT (HZ / 20) /* 50 ms */ -#define FSBR_DELAY (HZ / 20) /* 50 ms */ +#define IDLE_TIMEOUT msecs_to_jiffies(50) +#define FSBR_DELAY msecs_to_jiffies(50) /* When we timeout an idle transfer for FSBR, we'll switch it over to */ /* depth first traversal. We'll do it in groups of this number of TD's */ @@ -1611,6 +1611,7 @@ struct uhci_hcd *uhci = hcd_to_uhci(hcd); struct list_head list, *tmp, *head; unsigned long flags; + int called_uhci_finish_completion = 0; INIT_LIST_HEAD(&list); @@ -1619,6 +1620,7 @@ uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) { uhci_remove_pending_urbps(uhci); uhci_finish_completion(hcd, NULL); + called_uhci_finish_completion = 1; } head = &uhci->urb_list; @@ -1646,6 +1648,10 @@ } spin_unlock_irqrestore(&uhci->schedule_lock, flags); + /* Wake up anyone waiting for an URB to complete */ + if (called_uhci_finish_completion) + wake_up_all(&uhci->waitqh); + head = &list; tmp = head->next; while (tmp != head) { @@ -1676,7 +1682,7 @@ init_timer(&uhci->stall_timer); uhci->stall_timer.function = stall_callback; uhci->stall_timer.data = (unsigned long)hcd; - uhci->stall_timer.expires = jiffies + (HZ / 10); + uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100); add_timer(&uhci->stall_timer); return 0; @@ -1831,16 +1837,20 @@ { unsigned int io_addr = uhci->io_addr; + /* Turn off PIRQ, SMI, and all interrupts. This also turns off + * the BIOS's USB Legacy Support. + */ + pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); + outw(0, uhci->io_addr + USBINTR); + /* Global reset for 50ms */ uhci->state = UHCI_RESET; outw(USBCMD_GRESET, io_addr + USBCMD); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((HZ*50+999) / 1000); + msleep(50); outw(0, io_addr + USBCMD); /* Another 10ms delay */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((HZ*10+999) / 1000); + msleep(10); uhci->resume_detect = 0; } @@ -1865,7 +1875,7 @@ /* Global resume for >= 20ms */ outw(USBCMD_FGR | USBCMD_EGSM, io_addr + USBCMD); uhci->state = UHCI_RESUMING_1; - uhci->state_end = jiffies + (20*HZ+999) / 1000; + uhci->state_end = jiffies + msecs_to_jiffies(20); break; case UHCI_RESUMING_1: /* End global resume */ @@ -1990,7 +2000,9 @@ } } - /* Turn on all interrupts */ + /* Turn on PIRQ and all interrupts */ + pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, + USBLEGSUP_DEFAULT); outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, io_addr + USBINTR); @@ -2054,15 +2066,10 @@ uhci->io_addr = (unsigned long) hcd->regs; - /* Turn off all interrupts */ - outw(0, uhci->io_addr + USBINTR); - - /* Maybe kick BIOS off this hardware. Then reset, so we won't get + /* Kick BIOS off this hardware and reset, so we won't get * interrupts from any previous setup. */ reset_hc(uhci); - pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, - USBLEGSUP_DEFAULT); return 0; } @@ -2178,7 +2185,7 @@ uhci->rh_numports = port; - hcd->self.root_hub = udev = usb_alloc_dev(NULL, &hcd->self, 0); + udev = usb_alloc_dev(NULL, &hcd->self, 0); if (!udev) { dev_err(uhci_dev(uhci), "unable to allocate root hub\n"); goto err_alloc_root_hub; @@ -2260,7 +2267,7 @@ udev->speed = USB_SPEED_FULL; - if (usb_register_root_hub(udev, uhci_dev(uhci)) != 0) { + if (hcd_register_root(udev, &uhci->hcd) != 0) { dev_err(uhci_dev(uhci), "unable to start root hub\n"); retval = -ENOMEM; goto err_start_root_hub; @@ -2288,7 +2295,6 @@ err_alloc_term_td: usb_put_dev(udev); - hcd->self.root_hub = NULL; err_alloc_root_hub: dma_pool_destroy(uhci->qh_pool); @@ -2369,14 +2375,18 @@ /* * Some systems don't maintain the UHCI register values * during a PM suspend/resume cycle, so reinitialize - * the Frame Number, the Framelist Base Address, and the - * Interrupt Enable registers. + * the Frame Number, Framelist Base Address, Interrupt + * Enable, and Legacy Support registers. */ + pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, + 0); outw(uhci->saved_framenumber, uhci->io_addr + USBFRNUM); outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD); outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, uhci->io_addr + USBINTR); uhci->resume_detect = 1; + pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, + USBLEGSUP_DEFAULT); } else { reset_hc(uhci); start_hc(uhci); diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c --- a/drivers/usb/image/mdc800.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/image/mdc800.c 2004-06-26 17:09:18 -07:00 @@ -667,10 +667,10 @@ /* * The Device read callback Function */ -static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, loff_t *pos) +static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t len, loff_t *pos) { size_t left=len, sts=len; /* single transfer size */ - char* ptr=buf; + char __user *ptr = buf; long timeout; DECLARE_WAITQUEUE(wait, current); @@ -767,7 +767,7 @@ * After this the driver initiates the request for the answer or * just waits until the camera becomes ready. */ -static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos) +static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos) { size_t i=0; DECLARE_WAITQUEUE(wait, current); diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig --- a/drivers/usb/input/Kconfig 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/input/Kconfig 2004-06-26 17:09:19 -07:00 @@ -219,14 +219,16 @@ module will be called xpad. config USB_ATI_REMOTE - tristate "ATI USB RF remote control" + tristate "ATI / X10 USB RF remote control" depends on USB && INPUT ---help--- - Say Y here if you want to use one of ATI's USB remote controls. - These are RF remotes with USB receivers. They come with many of ATI's - All-In-Wonder video cards. This driver provides mouse pointer, left - and right mouse buttons, and maps all the other remote buttons to - keypress events. + Say Y here if you want to use an ATI or X10 "Lola" USB remote control. + These are RF remotes with USB receivers. + The ATI remote comes with many of ATI's All-In-Wonder video cards. + The X10 "Lola" remote is available at: + http://www.x10.com/products/lola_sg1.htm + This driver provides mouse pointer, left and right mouse buttons, + and maps all the other remote buttons to keypress events. To compile this driver as a module, choose M here: the module will be called ati_remote. diff -Nru a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c --- a/drivers/usb/input/ati_remote.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/input/ati_remote.c 2004-06-26 17:09:19 -07:00 @@ -16,6 +16,12 @@ * * Feb 2004: Torrey Hoffman * Version 2.2.0 + * Jun 2004: Torrey Hoffman + * Version 2.2.1 + * Added key repeat support contributed by: + * Vincent Vanackere + * Added support for the "Lola" remote contributed by: + * Seth Cohn * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -41,6 +47,11 @@ * "All-In-Wonder" video card packages. The receiver self-identifies as a * "USB Receiver" with manufacturer "X10 Wireless Technology Inc". * + * The "Lola" remote is available from X10. See: + * http://www.x10.com/products/lola_sg1.htm + * The Lola is similar to the ATI remote but has no mouse support, and slightly + * different keys. + * * It is possible to use multiple receivers and remotes on multiple computers * simultaneously by configuring them to use specific channels. * @@ -90,8 +101,9 @@ #define ATI_REMOTE_VENDOR_ID 0x0bc7 #define ATI_REMOTE_PRODUCT_ID 0x004 +#define LOLA_REMOTE_PRODUCT_ID 0x002 -#define DRIVER_VERSION "2.2.0" +#define DRIVER_VERSION "2.2.1" #define DRIVER_AUTHOR "Torrey Hoffman " #define DRIVER_DESC "ATI/X10 RF USB Remote Control" @@ -113,6 +125,7 @@ static struct usb_device_id ati_remote_table[] = { { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, + { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, {} /* Terminating entry */ }; @@ -134,10 +147,13 @@ /* Duplicate event filtering time. * Sequential, identical KIND_FILTERED inputs with less than - * FILTER_TIME jiffies between them are dropped. - * (HZ >> 4) == 1/16th of a second and works well for me. + * FILTER_TIME jiffies between them are considered as repeat + * events. The hardware generates 5 events for the first keypress + * and we have to take this into account for an accurate repeat + * behaviour. + * (HZ / 20) == 50 ms and works well for me. */ -#define FILTER_TIME (HZ >> 4) +#define FILTER_TIME (HZ / 20) static DECLARE_MUTEX(disconnect_sem); @@ -161,6 +177,7 @@ unsigned char old_data[2]; /* Detect duplicate events */ unsigned long old_jiffies; unsigned long acc_jiffies; /* handle acceleration */ + unsigned int repeat_count; char name[NAME_BUFSIZE]; char phys[NAME_BUFSIZE]; @@ -256,6 +273,12 @@ {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */ {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */ {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */ + {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */ + {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */ + {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */ + {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */ + {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */ + {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */ {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} }; @@ -483,9 +506,20 @@ if ((ati_remote->old_data[0] == data[1]) && (ati_remote->old_data[1] == data[2]) && ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) { - ati_remote->old_jiffies = jiffies; + ati_remote->repeat_count++; + } + else { + ati_remote->repeat_count = 0; + } + + ati_remote->old_data[0] = data[1]; + ati_remote->old_data[1] = data[2]; + ati_remote->old_jiffies = jiffies; + + if ((ati_remote->repeat_count > 0) + && (ati_remote->repeat_count < 5)) return; - } + input_regs(dev, regs); input_event(dev, ati_remote_tbl[index].type, @@ -494,9 +528,6 @@ ati_remote_tbl[index].code, 0); input_sync(dev); - ati_remote->old_data[0] = data[1]; - ati_remote->old_data[1] = data[2]; - ati_remote->old_jiffies = jiffies; return; } @@ -697,9 +728,9 @@ /* See if the offered device matches what we can accept */ if ((udev->descriptor.idVendor != ATI_REMOTE_VENDOR_ID) || - (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID)) { + ( (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID) && + (udev->descriptor.idProduct != LOLA_REMOTE_PRODUCT_ID) )) return -ENODEV; - } /* Allocate and clear an ati_remote struct */ if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL))) @@ -856,4 +887,3 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); - diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/input/hid-core.c 2004-06-26 17:09:18 -07:00 @@ -1324,12 +1324,14 @@ } err = 0; - while ((ret = hid_wait_io(hid))) { + ret = hid_wait_io(hid); + while (ret) { err |= ret; if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) usb_unlink_urb(hid->urbctrl); if (test_bit(HID_OUT_RUNNING, &hid->iofl)) usb_unlink_urb(hid->urbout); + ret = hid_wait_io(hid); } if (err) diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c --- a/drivers/usb/input/hiddev.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/input/hiddev.c 2004-06-26 17:09:17 -07:00 @@ -295,7 +295,7 @@ /* * "write" file op */ -static ssize_t hiddev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos) +static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) { return -EINVAL; } @@ -303,7 +303,7 @@ /* * "read" file op */ -static ssize_t hiddev_read(struct file * file, char * buffer, size_t count, loff_t *ppos) +static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) { DECLARE_WAITQUEUE(wait, current); struct hiddev_list *list = file->private_data; @@ -406,6 +406,7 @@ struct hiddev_devinfo dinfo; struct hid_report *report; struct hid_field *field; + void __user *user_arg = (void __user *)arg; int i; if (!hiddev->exist) @@ -414,7 +415,7 @@ switch (cmd) { case HIDIOCGVERSION: - return put_user(HID_VERSION, (int *) arg); + return put_user(HID_VERSION, (int __user *)arg); case HIDIOCAPPLICATION: if (arg < 0 || arg >= hid->maxapplication) @@ -439,13 +440,13 @@ dinfo.product = dev->descriptor.idProduct; dinfo.version = dev->descriptor.bcdDevice; dinfo.num_applications = hid->maxapplication; - if (copy_to_user((void *) arg, &dinfo, sizeof(dinfo))) + if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) return -EFAULT; return 0; case HIDIOCGFLAG: - if (put_user(list->flags, (int *) arg)) + if (put_user(list->flags, (int __user *)arg)) return -EFAULT; return 0; @@ -453,7 +454,7 @@ case HIDIOCSFLAG: { int newflags; - if (get_user(newflags, (int *) arg)) + if (get_user(newflags, (int __user *)arg)) return -EFAULT; if ((newflags & ~HIDDEV_FLAGS) != 0 || @@ -471,7 +472,7 @@ int idx, len; char *buf; - if (get_user(idx, (int *) arg)) + if (get_user(idx, (int __user *)arg)) return -EFAULT; if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL) @@ -482,7 +483,7 @@ return -EINVAL; } - if (copy_to_user((void *) (arg+sizeof(int)), buf, len+1)) { + if (copy_to_user(user_arg+sizeof(int), buf, len+1)) { kfree(buf); return -EFAULT; } @@ -498,7 +499,7 @@ return 0; case HIDIOCGREPORT: - if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo))) + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) return -EFAULT; if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT) @@ -513,7 +514,7 @@ return 0; case HIDIOCSREPORT: - if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo))) + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) return -EFAULT; if (rinfo.report_type == HID_REPORT_TYPE_INPUT) @@ -527,7 +528,7 @@ return 0; case HIDIOCGREPORTINFO: - if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo))) + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) return -EFAULT; if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) @@ -535,13 +536,13 @@ rinfo.num_fields = report->maxfield; - if (copy_to_user((void *) arg, &rinfo, sizeof(rinfo))) + if (copy_to_user(user_arg, &rinfo, sizeof(rinfo))) return -EFAULT; return 0; case HIDIOCGFIELDINFO: - if (copy_from_user(&finfo, (void *) arg, sizeof(finfo))) + if (copy_from_user(&finfo, user_arg, sizeof(finfo))) return -EFAULT; rinfo.report_type = finfo.report_type; rinfo.report_id = finfo.report_id; @@ -568,7 +569,7 @@ finfo.unit_exponent = field->unit_exponent; finfo.unit = field->unit; - if (copy_to_user((void *) arg, &finfo, sizeof(finfo))) + if (copy_to_user(user_arg, &finfo, sizeof(finfo))) return -EFAULT; return 0; @@ -578,7 +579,7 @@ if (!uref_multi) return -ENOMEM; uref = &uref_multi->uref; - if (copy_from_user(uref, (void *) arg, sizeof(*uref))) + if (copy_from_user(uref, user_arg, sizeof(*uref))) goto fault; rinfo.report_type = uref->report_type; @@ -595,7 +596,7 @@ uref->usage_code = field->usage[uref->usage_index].hid; - if (copy_to_user((void *) arg, uref, sizeof(*uref))) + if (copy_to_user(user_arg, uref, sizeof(*uref))) goto fault; kfree(uref_multi); @@ -611,11 +612,11 @@ return -ENOMEM; uref = &uref_multi->uref; if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { - if (copy_from_user(uref_multi, (void *) arg, + if (copy_from_user(uref_multi, user_arg, sizeof(*uref_multi))) goto fault; } else { - if (copy_from_user(uref, (void *) arg, sizeof(*uref))) + if (copy_from_user(uref, user_arg, sizeof(*uref))) goto fault; } @@ -652,7 +653,7 @@ switch (cmd) { case HIDIOCGUSAGE: uref->value = field->value[uref->usage_index]; - if (copy_to_user((void *) arg, uref, sizeof(*uref))) + if (copy_to_user(user_arg, uref, sizeof(*uref))) goto fault; goto goodreturn; @@ -667,7 +668,7 @@ for (i = 0; i < uref_multi->num_values; i++) uref_multi->values[i] = field->value[uref->usage_index + i]; - if (copy_to_user((void *) arg, uref_multi, + if (copy_to_user(user_arg, uref_multi, sizeof(*uref_multi))) goto fault; goto goodreturn; @@ -689,7 +690,7 @@ return -EINVAL; case HIDIOCGCOLLECTIONINFO: - if (copy_from_user(&cinfo, (void *) arg, sizeof(cinfo))) + if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) return -EFAULT; if (cinfo.index >= hid->maxcollection) @@ -699,7 +700,7 @@ cinfo.usage = hid->collection[cinfo.index].usage; cinfo.level = hid->collection[cinfo.index].level; - if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo))) + if (copy_to_user(user_arg, &cinfo, sizeof(cinfo))) return -EFAULT; return 0; @@ -715,7 +716,7 @@ len = strlen(hid->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - return copy_to_user((char *) arg, hid->name, len) ? + return copy_to_user(user_arg, hid->name, len) ? -EFAULT : len; } @@ -726,7 +727,7 @@ len = strlen(hid->phys) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - return copy_to_user((char *) arg, hid->phys, len) ? + return copy_to_user(user_arg, hid->phys, len) ? -EFAULT : len; } } diff -Nru a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig --- a/drivers/usb/media/Kconfig 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/media/Kconfig 2004-06-26 17:09:15 -07:00 @@ -108,7 +108,7 @@ config USB_PWC tristate "USB Philips Cameras" - depends on USB && VIDEO_DEV + depends on USB && VIDEO_DEV && CONFIG_BROKEN ---help--- Say Y or M here if you want to use one of these Philips & OEM webcams: diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c --- a/drivers/usb/media/dabusb.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/media/dabusb.c 2004-06-26 17:09:18 -07:00 @@ -476,7 +476,7 @@ return 0; } -static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t * ppos) +static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos) { pdabusb_t s = (pdabusb_t) file->private_data; unsigned long flags; @@ -670,7 +670,7 @@ break; } - if (copy_from_user (pbulk, (void *) arg, sizeof (bulk_transfer_t))) { + if (copy_from_user (pbulk, (void __user *) arg, sizeof (bulk_transfer_t))) { ret = -EFAULT; kfree (pbulk); break; @@ -678,18 +678,18 @@ ret=dabusb_bulk (s, pbulk); if(ret==0) - if (copy_to_user((void *)arg, pbulk, + if (copy_to_user((void __user *)arg, pbulk, sizeof(bulk_transfer_t))) ret = -EFAULT; kfree (pbulk); break; case IOCTL_DAB_OVERRUNS: - ret = put_user (s->overruns, (unsigned int *) arg); + ret = put_user (s->overruns, (unsigned int __user *) arg); break; case IOCTL_DAB_VERSION: - ret = put_user (version, (unsigned int *) arg); + ret = put_user (version, (unsigned int __user *) arg); break; default: diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c --- a/drivers/usb/media/ov511.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/media/ov511.c 2004-06-26 17:09:17 -07:00 @@ -4593,7 +4593,7 @@ } static ssize_t -ov51x_v4l1_read(struct file *file, char *buf, size_t cnt, loff_t *ppos) +ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos) { struct video_device *vdev = file->private_data; int noblock = file->f_flags&O_NONBLOCK; diff -Nru a/drivers/usb/media/ov511.h b/drivers/usb/media/ov511.h --- a/drivers/usb/media/ov511.h 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/media/ov511.h 2004-06-26 17:09:17 -07:00 @@ -11,7 +11,7 @@ #ifdef OV511_DEBUG #define PDEBUG(level, fmt, args...) \ if (debug >= (level)) info("[%s:%d] " fmt, \ - __PRETTY_FUNCTION__, __LINE__ , ## args) + __FUNCTION__, __LINE__ , ## args) #else #define PDEBUG(level, fmt, args...) do {} while(0) #endif diff -Nru a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c --- a/drivers/usb/media/pwc-if.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/media/pwc-if.c 2004-06-26 17:09:19 -07:00 @@ -129,7 +129,7 @@ static int pwc_video_open(struct inode *inode, struct file *file); static int pwc_video_close(struct inode *inode, struct file *file); -static ssize_t pwc_video_read(struct file *file, char *buf, +static ssize_t pwc_video_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); static unsigned int pwc_video_poll(struct file *file, poll_table *wait); static int pwc_video_ioctl(struct inode *inode, struct file *file, @@ -1132,7 +1132,7 @@ device is tricky anyhow. */ -static ssize_t pwc_video_read(struct file *file, char *buf, +static ssize_t pwc_video_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct video_device *vdev = file->private_data; diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c --- a/drivers/usb/media/se401.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/media/se401.c 2004-06-26 17:09:17 -07:00 @@ -1121,7 +1121,7 @@ return video_usercopy(inode, file, cmd, arg, se401_do_ioctl); } -static ssize_t se401_read(struct file *file, char *buf, +static ssize_t se401_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int realcount=count, ret=0; diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c --- a/drivers/usb/media/stv680.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/media/stv680.c 2004-06-26 17:09:19 -07:00 @@ -1309,7 +1309,7 @@ return 0; } -static ssize_t stv680_read (struct file *file, char *buf, +static ssize_t stv680_read (struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct video_device *dev = file->private_data; diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c --- a/drivers/usb/media/usbvideo.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/media/usbvideo.c 2004-06-26 17:09:21 -07:00 @@ -46,7 +46,7 @@ unsigned int cmd, unsigned long arg); static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma); static int usbvideo_v4l_open(struct inode *inode, struct file *file); -static ssize_t usbvideo_v4l_read(struct file *file, char *buf, +static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); static int usbvideo_v4l_close(struct inode *inode, struct file *file); @@ -1587,7 +1587,7 @@ * 20-Oct-2000 Created. * 01-Nov-2000 Added mutex (uvd->lock). */ -static ssize_t usbvideo_v4l_read(struct file *file, char *buf, +static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct uvd *uvd = file->private_data; diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c --- a/drivers/usb/media/vicam.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/media/vicam.c 2004-06-26 17:09:17 -07:00 @@ -523,9 +523,9 @@ } static int -vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long ul_arg) +vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg) { - void *arg = (void *)ul_arg; + void __user *user_arg = (void __user *)arg; struct vicam_camera *cam = file->private_data; int retval = 0; @@ -549,7 +549,7 @@ b.minwidth = 320; /* VIDEOSIZE_48_48 */ b.minheight = 240; - if (copy_to_user(arg, &b, sizeof (b))) + if (copy_to_user(user_arg, &b, sizeof(b))) retval = -EFAULT; break; @@ -560,7 +560,7 @@ struct video_channel v; DBG("VIDIOCGCHAN\n"); - if (copy_from_user(&v, arg, sizeof (v))) { + if (copy_from_user(&v, user_arg, sizeof(v))) { retval = -EFAULT; break; } @@ -576,7 +576,7 @@ v.type = VIDEO_TYPE_CAMERA; v.norm = 0; - if (copy_to_user(arg, &v, sizeof (v))) + if (copy_to_user(user_arg, &v, sizeof(v))) retval = -EFAULT; break; } @@ -585,7 +585,7 @@ { int v; - if (copy_from_user(&v, arg, sizeof (v))) + if (copy_from_user(&v, user_arg, sizeof(v))) retval = -EFAULT; DBG("VIDIOCSCHAN %d\n", v); @@ -604,8 +604,7 @@ vp.brightness = cam->gain << 8; vp.depth = 24; vp.palette = VIDEO_PALETTE_RGB24; - if (copy_to_user - (arg, &vp, sizeof (struct video_picture))) + if (copy_to_user(user_arg, &vp, sizeof (struct video_picture))) retval = -EFAULT; break; } @@ -614,7 +613,7 @@ { struct video_picture vp; - if (copy_from_user(&vp, arg, sizeof(vp))) { + if (copy_from_user(&vp, user_arg, sizeof(vp))) { retval = -EFAULT; break; } @@ -646,8 +645,7 @@ DBG("VIDIOCGWIN\n"); - if (copy_to_user - ((void *) arg, (void *) &vw, sizeof (vw))) + if (copy_to_user(user_arg, (void *)&vw, sizeof(vw))) retval = -EFAULT; // I'm not sure what the deal with a capture window is, it is very poorly described @@ -660,7 +658,7 @@ struct video_window vw; - if (copy_from_user(&vw, arg, sizeof(vw))) { + if (copy_from_user(&vw, user_arg, sizeof(vw))) { retval = -EFAULT; break; } @@ -687,8 +685,7 @@ for (i = 0; i < VICAM_FRAMES; i++) vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i; - if (copy_to_user - ((void *) arg, (void *) &vm, sizeof (vm))) + if (copy_to_user(user_arg, (void *)&vm, sizeof(vm))) retval = -EFAULT; break; @@ -699,8 +696,7 @@ struct video_mmap vm; // int video_size; - if (copy_from_user - ((void *) &vm, (void *) arg, sizeof (vm))) { + if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) { retval = -EFAULT; break; } @@ -723,7 +719,7 @@ { int frame; - if (copy_from_user((void *) &frame, arg, sizeof (int))) { + if (copy_from_user((void *)&frame, user_arg, sizeof(int))) { retval = -EFAULT; break; } @@ -1003,7 +999,7 @@ } static ssize_t -vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos ) +vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos ) { struct vicam_camera *cam = file->private_data; diff -Nru a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c --- a/drivers/usb/media/w9968cf.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/media/w9968cf.c 2004-06-26 17:09:19 -07:00 @@ -388,7 +388,7 @@ static struct file_operations w9968cf_fops; static int w9968cf_open(struct inode*, struct file*); static int w9968cf_release(struct inode*, struct file*); -static ssize_t w9968cf_read(struct file*, char*, size_t, loff_t*); +static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*); static int w9968cf_mmap(struct file*, struct vm_area_struct*); static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long); static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, void*); @@ -444,8 +444,8 @@ /* High-level CMOS sensor control functions */ static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val); static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val); -static inline int w9968cf_sensor_cmd(struct w9968cf_device*, - unsigned int cmd, void *arg); +static int w9968cf_sensor_cmd(struct w9968cf_device*, + unsigned int cmd, void *arg); static int w9968cf_sensor_init(struct w9968cf_device*); static int w9968cf_sensor_update_settings(struct w9968cf_device*); static int w9968cf_sensor_get_picture(struct w9968cf_device*); @@ -461,7 +461,7 @@ static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture); static int w9968cf_set_window(struct w9968cf_device*, struct video_window); static inline u16 w9968cf_valid_palette(u16 palette); -static inline u16 w9968cf_valid_depth(u16 palette); +static u16 w9968cf_valid_depth(u16 palette); static inline u8 w9968cf_need_decompression(u16 palette); static int w9968cf_postprocess_frame(struct w9968cf_device*, struct w9968cf_frame_t*); @@ -1959,7 +1959,7 @@ Return the depth corresponding to the given palette. Palette _must_ be supported ! --------------------------------------------------------------------------*/ -static inline u16 w9968cf_valid_depth(u16 palette) +static u16 w9968cf_valid_depth(u16 palette) { u8 i=0; while (w9968cf_formatlist[i].palette != palette) @@ -2178,7 +2178,7 @@ } -static inline int +static int w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg) { struct i2c_client* c = cam->sensor_client; @@ -2770,7 +2770,7 @@ static ssize_t -w9968cf_read(struct file* filp, char* buf, size_t count, loff_t* f_pos) +w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) { struct w9968cf_device* cam; struct w9968cf_frame_t* fr; @@ -2915,6 +2915,7 @@ unsigned int cmd, void* arg) { struct w9968cf_device* cam; + void __user *user_arg = (void __user *)arg; const char* v4l1_ioctls[] = { "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF", @@ -2948,7 +2949,7 @@ cap.maxheight = (cam->upscaling && w9968cf_vppmod_present) ? W9968CF_MAX_HEIGHT : cam->maxheight; - if (copy_to_user(arg, &cap, sizeof(cap))) + if (copy_to_user(user_arg, &cap, sizeof(cap))) return -EFAULT; DBG(5, "VIDIOCGCAP successfully called.") @@ -2958,7 +2959,7 @@ case VIDIOCGCHAN: /* get video channel informations */ { struct video_channel chan; - if (copy_from_user(&chan, arg, sizeof(chan))) + if (copy_from_user(&chan, user_arg, sizeof(chan))) return -EFAULT; if (chan.channel != 0) @@ -2970,7 +2971,7 @@ chan.type = VIDEO_TYPE_CAMERA; chan.norm = VIDEO_MODE_AUTO; - if (copy_to_user(arg, &chan, sizeof(chan))) + if (copy_to_user(user_arg, &chan, sizeof(chan))) return -EFAULT; DBG(5, "VIDIOCGCHAN successfully called.") @@ -2981,7 +2982,7 @@ { struct video_channel chan; - if (copy_from_user(&chan, arg, sizeof(chan))) + if (copy_from_user(&chan, user_arg, sizeof(chan))) return -EFAULT; if (chan.channel != 0) @@ -2996,7 +2997,7 @@ if (w9968cf_sensor_get_picture(cam)) return -EIO; - if (copy_to_user(arg, &cam->picture, sizeof(cam->picture))) + if (copy_to_user(user_arg, &cam->picture, sizeof(cam->picture))) return -EFAULT; DBG(5, "VIDIOCGPICT successfully called.") @@ -3008,7 +3009,7 @@ struct video_picture pict; int err = 0; - if (copy_from_user(&pict, arg, sizeof(pict))) + if (copy_from_user(&pict, user_arg, sizeof(pict))) return -EFAULT; if ( (cam->force_palette || !w9968cf_vppmod_present) @@ -3087,7 +3088,7 @@ struct video_window win; int err = 0; - if (copy_from_user(&win, arg, sizeof(win))) + if (copy_from_user(&win, user_arg, sizeof(win))) return -EFAULT; DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%d, " @@ -3141,7 +3142,7 @@ case VIDIOCGWIN: /* get current window properties */ { - if (copy_to_user(arg,&cam->window,sizeof(struct video_window))) + if (copy_to_user(user_arg, &cam->window, sizeof(struct video_window))) return -EFAULT; DBG(5, "VIDIOCGWIN successfully called.") @@ -3159,7 +3160,7 @@ mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer - (unsigned long)cam->frame[0].buffer; - if (copy_to_user(arg, &mbuf, sizeof(mbuf))) + if (copy_to_user(user_arg, &mbuf, sizeof(mbuf))) return -EFAULT; DBG(5, "VIDIOCGMBUF successfully called.") @@ -3172,7 +3173,7 @@ struct w9968cf_frame_t* fr; int err = 0; - if (copy_from_user(&mmap, arg, sizeof(mmap))) + if (copy_from_user(&mmap, user_arg, sizeof(mmap))) return -EFAULT; DBG(6, "VIDIOCMCAPTURE called: frame #%d, format=%s, %dx%d", @@ -3295,7 +3296,7 @@ struct w9968cf_frame_t* fr; int err = 0; - if (copy_from_user(&f_num, arg, sizeof(f_num))) + if (copy_from_user(&f_num, user_arg, sizeof(f_num))) return -EFAULT; if (f_num >= cam->nbuffers) { @@ -3348,7 +3349,7 @@ .teletext = VIDEO_NO_UNIT, }; - if (copy_to_user(arg, &unit, sizeof(unit))) + if (copy_to_user(user_arg, &unit, sizeof(unit))) return -EFAULT; DBG(5, "VIDIOCGUNIT successfully called.") @@ -3360,7 +3361,7 @@ case VIDIOCGFBUF: { - if (clear_user(arg, sizeof(struct video_buffer))) + if (clear_user(user_arg, sizeof(struct video_buffer))) return -EFAULT; DBG(5, "VIDIOCGFBUF successfully called.") @@ -3370,7 +3371,7 @@ case VIDIOCGTUNER: { struct video_tuner tuner; - if (copy_from_user(&tuner, arg, sizeof(tuner))) + if (copy_from_user(&tuner, user_arg, sizeof(tuner))) return -EFAULT; if (tuner.tuner != 0) @@ -3383,7 +3384,7 @@ tuner.mode = VIDEO_MODE_AUTO; tuner.signal = 0xffff; - if (copy_to_user(arg, &tuner, sizeof(tuner))) + if (copy_to_user(user_arg, &tuner, sizeof(tuner))) return -EFAULT; DBG(5, "VIDIOCGTUNER successfully called.") @@ -3393,7 +3394,7 @@ case VIDIOCSTUNER: { struct video_tuner tuner; - if (copy_from_user(&tuner, arg, sizeof(tuner))) + if (copy_from_user(&tuner, user_arg, sizeof(tuner))) return -EFAULT; if (tuner.tuner != 0) diff -Nru a/drivers/usb/media/w9968cf.h b/drivers/usb/media/w9968cf.h --- a/drivers/usb/media/w9968cf.h 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/media/w9968cf.h 2004-06-26 17:09:15 -07:00 @@ -293,7 +293,7 @@ warn(fmt, ## args); \ else if ((level) >= 5) \ info("[%s:%d] " fmt, \ - __PRETTY_FUNCTION__, __LINE__ , ## args); \ + __FUNCTION__, __LINE__ , ## args); \ } \ } #else diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c --- a/drivers/usb/misc/auerswald.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/misc/auerswald.c 2004-06-26 17:09:17 -07:00 @@ -1452,6 +1452,8 @@ audevinfo_t devinfo; pauerswald_t cp = NULL; unsigned int u; + unsigned int __user *user_arg = (unsigned int __user *)arg; + dbg ("ioctl"); /* get the mutexes */ @@ -1483,14 +1485,14 @@ u = ccp->auerdev && (ccp->scontext.id != AUH_UNASSIGNED) && !list_empty (&cp->bufctl.free_buff_list); - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* return != 0 if connected to a service channel */ case IOCTL_AU_CONNECT: dbg ("IOCTL_AU_CONNECT"); u = (ccp->scontext.id != AUH_UNASSIGNED); - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* return != 0 if Receive Data available */ @@ -1511,14 +1513,14 @@ u = 1; } } - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* return the max. buffer length for the device */ case IOCTL_AU_BUFLEN: dbg ("IOCTL_AU_BUFLEN"); u = cp->maxControlLength; - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* requesting a service channel */ @@ -1527,7 +1529,7 @@ /* requesting a service means: release the previous one first */ auerswald_removeservice (cp, &ccp->scontext); /* get the channel number */ - ret = get_user (u, (unsigned int *) arg); + ret = get_user (u, user_arg); if (ret) { break; } @@ -1564,7 +1566,7 @@ case IOCTL_AU_SLEN: dbg ("IOCTL_AU_SLEN"); u = AUSI_DLEN; - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; default: diff -Nru a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c --- a/drivers/usb/misc/legousbtower.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/misc/legousbtower.c 2004-06-26 17:09:17 -07:00 @@ -236,8 +236,8 @@ /* local function prototypes */ -static ssize_t tower_read (struct file *file, char *buffer, size_t count, loff_t *ppos); -static ssize_t tower_write (struct file *file, const char *buffer, size_t count, loff_t *ppos); +static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos); +static ssize_t tower_write (struct file *file, const char __user *buffer, size_t count, loff_t *ppos); static inline void tower_delete (struct lego_usb_tower *dev); static int tower_open (struct inode *inode, struct file *file); static int tower_release (struct inode *inode, struct file *file); @@ -560,7 +560,7 @@ /** * tower_read */ -static ssize_t tower_read (struct file *file, char *buffer, size_t count, loff_t *ppos) +static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct lego_usb_tower *dev; size_t bytes_to_read; @@ -651,7 +651,7 @@ /** * tower_write */ -static ssize_t tower_write (struct file *file, const char *buffer, size_t count, loff_t *ppos) +static ssize_t tower_write (struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct lego_usb_tower *dev; size_t bytes_to_write; diff -Nru a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c --- a/drivers/usb/misc/phidgetservo.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/misc/phidgetservo.c 2004-06-26 17:09:19 -07:00 @@ -17,6 +17,10 @@ * * CAUTION: Generally you should use 0 < degrees < 180 as anything else * is probably beyond the range of your servo and may damage it. + * + * Jun 16, 2004: Sean Young + * - cleanups + * - was using memory after kfree() */ #include @@ -33,19 +37,36 @@ #define DRIVER_AUTHOR "Sean Young " #define DRIVER_DESC "USB PhidgetServo Driver" -#define VENDOR_ID_GLAB 0x06c2 -#define DEVICE_ID_4MOTOR_SERVO_30 0x0038 -#define DEVICE_ID_1MOTOR_SERVO_30 0x0039 - -#define VENDOR_ID_WISEGROUP 0x0925 -#define DEVICE_ID_1MOTOR_SERVO_20 0x8101 -#define DEVICE_ID_4MOTOR_SERVO_20 0x8104 +#define VENDOR_ID_GLAB 0x06c2 +#define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD 0x0038 +#define DEVICE_ID_GLAB_PHIDGETSERVO_UNI 0x0039 + +#define VENDOR_ID_WISEGROUP 0x0925 +#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD 0x8101 +#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI 0x8104 + +#define SERVO_VERSION_30 0x01 +#define SERVO_COUNT_QUAD 0x02 static struct usb_device_id id_table[] = { - {USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_4MOTOR_SERVO_30)}, - {USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_1MOTOR_SERVO_30)}, - {USB_DEVICE(VENDOR_ID_WISEGROUP, DEVICE_ID_4MOTOR_SERVO_20)}, - {USB_DEVICE(VENDOR_ID_WISEGROUP, DEVICE_ID_1MOTOR_SERVO_20)}, + { + USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD), + .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD + }, + { + USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI), + .driver_info = SERVO_VERSION_30 + }, + { + USB_DEVICE(VENDOR_ID_WISEGROUP, + VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD), + .driver_info = SERVO_COUNT_QUAD + }, + { + USB_DEVICE(VENDOR_ID_WISEGROUP, + VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI), + .driver_info = 0 + }, {} }; @@ -53,14 +74,13 @@ struct phidget_servo { struct usb_device *udev; - int version; - int quad_servo; + ulong type; int pulse[4]; int degrees[4]; int minutes[4]; }; -static void +static int change_position_v30(struct phidget_servo *servo, int servo_no, int degrees, int minutes) { @@ -71,7 +91,7 @@ if (!buffer) { dev_err(&servo->udev->dev, "%s - out of memory\n", __FUNCTION__); - return; + return -ENOMEM; } /* @@ -124,12 +144,13 @@ retval = usb_control_msg(servo->udev, usb_sndctrlpipe(servo->udev, 0), 0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2 * HZ); - if (retval != 6) - dev_err(&servo->udev->dev, "retval = %d\n", retval); + kfree(buffer); + + return retval; } -static void +static int change_position_v20(struct phidget_servo *servo, int servo_no, int degrees, int minutes) { @@ -140,7 +161,7 @@ if (!buffer) { dev_err(&servo->udev->dev, "%s - out of memory\n", __FUNCTION__); - return; + return -ENOMEM; } /* @@ -171,16 +192,17 @@ retval = usb_control_msg(servo->udev, usb_sndctrlpipe(servo->udev, 0), 0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2 * HZ); - if (retval != 2) - dev_err(&servo->udev->dev, "retval = %d\n", retval); + kfree(buffer); + + return retval; } #define show_set(value) \ static ssize_t set_servo##value (struct device *dev, \ const char *buf, size_t count) \ { \ - int degrees, minutes; \ + int degrees, minutes, retval; \ struct usb_interface *intf = to_usb_interface (dev); \ struct phidget_servo *servo = usb_get_intfdata (intf); \ \ @@ -195,12 +217,14 @@ return -EINVAL; \ } \ \ - if (servo->version >= 3) \ - change_position_v30 (servo, value, degrees, minutes); \ + if (servo->type & SERVO_VERSION_30) \ + retval = change_position_v30 (servo, value, degrees, \ + minutes); \ else \ - change_position_v20 (servo, value, degrees, minutes); \ + retval = change_position_v20 (servo, value, degrees, \ + minutes); \ \ - return count; \ + return retval < 0 ? retval : count; \ } \ \ static ssize_t show_servo##value (struct device *dev, char *buf) \ @@ -223,7 +247,7 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); - struct phidget_servo *dev = NULL; + struct phidget_servo *dev; dev = kmalloc(sizeof (struct phidget_servo), GFP_KERNEL); if (dev == NULL) { @@ -233,37 +257,21 @@ memset(dev, 0x00, sizeof (*dev)); dev->udev = usb_get_dev(udev); - switch (udev->descriptor.idVendor) { - case VENDOR_ID_WISEGROUP: - dev->version = 2; - break; - case VENDOR_ID_GLAB: - dev->version = 3; - break; - } - switch (udev->descriptor.idProduct) { - case DEVICE_ID_4MOTOR_SERVO_20: - case DEVICE_ID_4MOTOR_SERVO_30: - dev->quad_servo = 1; - break; - case DEVICE_ID_1MOTOR_SERVO_20: - case DEVICE_ID_1MOTOR_SERVO_30: - dev->quad_servo = 0; - break; - } - + dev->type = id->driver_info; usb_set_intfdata(interface, dev); device_create_file(&interface->dev, &dev_attr_servo0); - if (dev->quad_servo) { + if (dev->type & SERVO_COUNT_QUAD) { device_create_file(&interface->dev, &dev_attr_servo1); device_create_file(&interface->dev, &dev_attr_servo2); device_create_file(&interface->dev, &dev_attr_servo3); } dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n", - dev->quad_servo ? 4 : 1, dev->version); - if (dev->version == 2) + dev->type & SERVO_COUNT_QUAD ? 4 : 1, + dev->type & SERVO_VERSION_30 ? 3 : 2); + + if(!(dev->type & SERVO_VERSION_30)) dev_info(&interface->dev, "WARNING: v2.0 not tested! Please report if it works.\n"); @@ -279,7 +287,7 @@ usb_set_intfdata(interface, NULL); device_remove_file(&interface->dev, &dev_attr_servo0); - if (dev->quad_servo) { + if (dev->type & SERVO_COUNT_QUAD) { device_remove_file(&interface->dev, &dev_attr_servo1); device_remove_file(&interface->dev, &dev_attr_servo2); device_remove_file(&interface->dev, &dev_attr_servo3); @@ -287,10 +295,11 @@ usb_put_dev(dev->udev); - kfree(dev); - dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n", - dev->quad_servo ? 4 : 1, dev->version); + dev->type & SERVO_COUNT_QUAD ? 4 : 1, + dev->type & SERVO_VERSION_30 ? 3 : 2); + + kfree(dev); } static struct usb_driver servo_driver = { @@ -304,7 +313,7 @@ static int __init phidget_servo_init(void) { - int retval = 0; + int retval; retval = usb_register(&servo_driver); if (retval) diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c --- a/drivers/usb/misc/usbtest.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/misc/usbtest.c 2004-06-26 17:09:20 -07:00 @@ -459,8 +459,8 @@ * or remote wakeup (which needs human interaction). */ -static int realworld = 1; -MODULE_PARM (realworld, "i"); +static unsigned realworld = 1; +module_param (realworld, uint, 0); MODULE_PARM_DESC (realworld, "clear to demand stricter ch9 compliance"); static int get_altsetting (struct usbtest_dev *dev) @@ -1808,17 +1808,17 @@ /*-------------------------------------------------------------------------*/ -static int force_interrupt = 0; -MODULE_PARM (force_interrupt, "i"); +static unsigned force_interrupt = 0; +module_param (force_interrupt, uint, 0); MODULE_PARM_DESC (force_interrupt, "0 = test default; else interrupt"); #ifdef GENERIC -static int vendor; -MODULE_PARM (vendor, "h"); +static unsigned short vendor; +module_param(vendor, ushort, 0); MODULE_PARM_DESC (vendor, "vendor code (from usb-if)"); -static int product; -MODULE_PARM (product, "h"); +static unsigned short product; +module_param(product, ushort, 0); MODULE_PARM_DESC (product, "product code (from vendor)"); #endif diff -Nru a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h --- a/drivers/usb/net/pegasus.h 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/net/pegasus.h 2004-06-26 17:09:21 -07:00 @@ -121,6 +121,7 @@ #define VENDOR_ADMTEK 0x07a6 #define VENDOR_AEILAB 0x3334 #define VENDOR_ALLIEDTEL 0x07c9 +#define VENDOR_ATEN 0x0557 #define VENDOR_BELKIN 0x050d #define VENDOR_BILLIONTON 0x08dd #define VENDOR_COMPAQ 0x049f @@ -149,6 +150,8 @@ #else /* PEGASUS_DEV */ PEGASUS_DEV( "3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601, + DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c, DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) diff -Nru a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c --- a/drivers/usb/net/rtl8150.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/net/rtl8150.c 2004-06-26 17:09:18 -07:00 @@ -398,6 +398,21 @@ usb_unlink_urb(dev->ctrl_urb); } +static inline struct sk_buff *pull_skb(rtl8150_t *dev) +{ + struct sk_buff *skb; + int i; + + for (i = 0; i < RX_SKB_POOL_SIZE; i++) { + if (dev->rx_skb_pool[i]) { + skb = dev->rx_skb_pool[i]; + dev->rx_skb_pool[i] = NULL; + return skb; + } + } + return NULL; +} + static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) { rtl8150_t *dev; @@ -601,21 +616,6 @@ for (i = 0; i < RX_SKB_POOL_SIZE; i++) if (dev->rx_skb_pool[i]) dev_kfree_skb(dev->rx_skb_pool[i]); -} - -static inline struct sk_buff *pull_skb(rtl8150_t *dev) -{ - struct sk_buff *skb; - int i; - - for (i = 0; i < RX_SKB_POOL_SIZE; i++) { - if (dev->rx_skb_pool[i]) { - skb = dev->rx_skb_pool[i]; - dev->rx_skb_pool[i] = NULL; - return skb; - } - } - return NULL; } static int enable_net_traffic(rtl8150_t * dev) diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c --- a/drivers/usb/net/usbnet.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/net/usbnet.c 2004-06-26 17:09:18 -07:00 @@ -104,6 +104,8 @@ * disconnect; other cleanups. (db) Flush net1080 fifos * after several sequential framing errors. (Johannes Erdfelt) * 22-aug-2003 AX8817X support (Dave Hollis). + * 14-jun-2004 Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan + * (Neil Bortnak) * *-------------------------------------------------------------------------*/ @@ -1157,6 +1159,7 @@ status = get_ethernet_addr (dev, info->ether); if (status < 0) { + usb_set_intfdata(info->data, NULL); usb_driver_release_interface (&usbnet_driver, info->data); return status; } @@ -3203,6 +3206,10 @@ }, { // ATEN UC210T USB_DEVICE (0x0557, 0x2009), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // Buffalo LUA-U2-KTX + USB_DEVICE (0x0411, 0x003d), .driver_info = (unsigned long) &ax8817x_info, }, #endif diff -Nru a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c --- a/drivers/usb/serial/bus.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/serial/bus.c 2004-06-26 17:09:21 -07:00 @@ -78,8 +78,8 @@ minor = port->number; tty_register_device (usb_serial_tty_driver, minor, dev); dev_info(&port->serial->dev->dev, - "%s converter now attached to ttyUSB%d (or usb/tts/%d for devfs)\n", - driver->name, minor, minor); + "%s converter now attached to ttyUSB%d\n", + driver->name, minor); exit: return retval; diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/serial/ftdi_sio.c 2004-06-26 17:09:20 -07:00 @@ -1022,7 +1022,7 @@ } -static int get_serial_info(struct usb_serial_port * port, struct serial_struct * retinfo) +static int get_serial_info(struct usb_serial_port * port, struct serial_struct __user * retinfo) { struct ftdi_private *priv = usb_get_serial_port_data(port); struct serial_struct tmp; @@ -1039,7 +1039,7 @@ } /* get_serial_info */ -static int set_serial_info(struct usb_serial_port * port, struct serial_struct * newinfo) +static int set_serial_info(struct usb_serial_port * port, struct serial_struct __user * newinfo) { /* set_serial_info */ struct ftdi_private *priv = usb_get_serial_port_data(port); struct serial_struct new_serial; @@ -1504,6 +1504,7 @@ if (status) { err("%s - failed submitting write urb, error %d", __FUNCTION__, status); count = status; + kfree (buffer); } /* we are done with this urb, so let the host driver @@ -2042,7 +2043,7 @@ case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */ dbg("%s TIOCMBIS", __FUNCTION__); - if (get_user(mask, (unsigned long *) arg)) + if (get_user(mask, (unsigned long __user *) arg)) return -EFAULT; if (mask & TIOCM_DTR){ if ((ret = set_dtr(port, HIGH)) < 0) { @@ -2061,7 +2062,7 @@ case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */ dbg("%s TIOCMBIC", __FUNCTION__); - if (get_user(mask, (unsigned long *) arg)) + if (get_user(mask, (unsigned long __user *) arg)) return -EFAULT; if (mask & TIOCM_DTR){ if ((ret = set_dtr(port, LOW)) < 0){ @@ -2088,10 +2089,10 @@ */ case TIOCGSERIAL: /* gets serial port data */ - return get_serial_info(port, (struct serial_struct *) arg); + return get_serial_info(port, (struct serial_struct __user *) arg); case TIOCSSERIAL: /* sets serial port data */ - return set_serial_info(port, (struct serial_struct *) arg); + return set_serial_info(port, (struct serial_struct __user *) arg); /* * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c --- a/drivers/usb/serial/io_edgeport.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/serial/io_edgeport.c 2004-06-26 17:09:15 -07:00 @@ -1705,7 +1705,7 @@ * transmit holding register is empty. This functionality * allows an RS485 driver to be written in user space. *****************************************************************************/ -static int get_lsr_info(struct edgeport_port *edge_port, unsigned int *value) +static int get_lsr_info(struct edgeport_port *edge_port, unsigned int __user *value) { unsigned int result = 0; @@ -1720,7 +1720,7 @@ return 0; } -static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int *value) +static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int __user *value) { unsigned int result = 0; struct tty_struct *tty = edge_port->port->tty; @@ -1790,7 +1790,7 @@ return result; } -static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct * retinfo) +static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct __user *retinfo) { struct serial_struct tmp; @@ -1812,7 +1812,6 @@ // tmp.hub6 = state->hub6; // tmp.io_type = state->io_type; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) return -EFAULT; return 0; @@ -1838,17 +1837,17 @@ // return number of bytes available case TIOCINQ: dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number); - return get_number_bytes_avail(edge_port, (unsigned int *) arg); + return get_number_bytes_avail(edge_port, (unsigned int __user *) arg); break; case TIOCSERGETLSR: dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); - return get_lsr_info(edge_port, (unsigned int *) arg); + return get_lsr_info(edge_port, (unsigned int __user *) arg); return 0; case TIOCGSERIAL: dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); - return get_serial_info(edge_port, (struct serial_struct *) arg); + return get_serial_info(edge_port, (struct serial_struct __user *) arg); case TIOCSSERIAL: dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); @@ -1893,7 +1892,7 @@ icount.buf_overrun = cnow.buf_overrun; dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, icount.rx, icount.tx ); - if (copy_to_user((void *)arg, &icount, sizeof(icount))) + if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) return -EFAULT; return 0; } diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c --- a/drivers/usb/serial/io_ti.c 2004-06-26 17:09:21 -07:00 +++ b/drivers/usb/serial/io_ti.c 2004-06-26 17:09:21 -07:00 @@ -2428,7 +2428,7 @@ return result; } -static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct * retinfo) +static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct __user *retinfo) { struct serial_struct tmp; @@ -2477,7 +2477,7 @@ case TIOCGSERIAL: dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number); - return get_serial_info(edge_port, (struct serial_struct *) arg); + return get_serial_info(edge_port, (struct serial_struct __user *) arg); break; case TIOCSSERIAL: @@ -2510,7 +2510,7 @@ case TIOCGICOUNT: dbg ("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, edge_port->icount.rx, edge_port->icount.tx); - if (copy_to_user((void *)arg, &edge_port->icount, sizeof(edge_port->icount))) + if (copy_to_user((void __user *)arg, &edge_port->icount, sizeof(edge_port->icount))) return -EFAULT; return 0; } diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c --- a/drivers/usb/serial/kl5kusb105.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/serial/kl5kusb105.c 2004-06-26 17:09:18 -07:00 @@ -926,6 +926,7 @@ unsigned int cmd, unsigned long arg) { struct klsi_105_private *priv = usb_get_serial_port_data(port); + void __user *user_arg = (void __user *)arg; dbg("%scmd=0x%x", __FUNCTION__, cmd); @@ -948,13 +949,12 @@ dbg("%s - TCGETS data faked/incomplete", __FUNCTION__); - retval = verify_area(VERIFY_WRITE, (void *)arg, + retval = verify_area(VERIFY_WRITE, user_arg, sizeof(struct termios)); - if (retval) - return(retval); + return retval; - if (kernel_termios_to_user_termios((struct termios *)arg, + if (kernel_termios_to_user_termios((struct termios __user *)arg, &priv->termios)) return -EFAULT; return(0); @@ -965,14 +965,13 @@ dbg("%s - TCSETS not handled", __FUNCTION__); - retval = verify_area(VERIFY_READ, (void *)arg, + retval = verify_area(VERIFY_READ, user_arg, sizeof(struct termios)); - if (retval) - return(retval); + return retval; if (user_termios_to_kernel_termios(&priv->termios, - (struct termios *)arg)) + (struct termios __user *)arg)) return -EFAULT; klsi_105_set_termios(port, &priv->termios); return(0); diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c --- a/drivers/usb/serial/kobil_sct.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/serial/kobil_sct.c 2004-06-26 17:09:20 -07:00 @@ -643,6 +643,7 @@ unsigned char *transfer_buffer; int transfer_buffer_length = 8; char *settings; + void __user *user_arg = (void __user *)arg; priv = usb_get_serial_port_data(port); if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { @@ -652,12 +653,12 @@ switch (cmd) { case TCGETS: // 0x5401 - result = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct termios)); + result = verify_area(VERIFY_WRITE, user_arg, sizeof(struct termios)); if (result) { dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number); return(result); } - if (kernel_termios_to_user_termios((struct termios *)arg, + if (kernel_termios_to_user_termios((struct termios __user *)arg, &priv->internal_termios)) return -EFAULT; return 0; @@ -667,13 +668,13 @@ dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number); return -ENOTTY; } - result = verify_area(VERIFY_READ, (void *)arg, sizeof(struct termios)); + result = verify_area(VERIFY_READ, user_arg, sizeof(struct termios)); if (result) { dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number); return result; } if (user_termios_to_kernel_termios(&priv->internal_termios, - (struct termios *)arg)) + (struct termios __user *)arg)) return -EFAULT; settings = (unsigned char *) kmalloc(50, GFP_KERNEL); diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/serial/visor.c 2004-06-26 17:09:17 -07:00 @@ -247,6 +247,8 @@ .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { }, /* optional parameter entry */ { } /* Terminating entry */ }; @@ -290,6 +292,7 @@ { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) }, { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) }, + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) }, { }, /* optional parameter entry */ { } /* Terminating entry */ }; @@ -515,6 +518,7 @@ dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __FUNCTION__, status); count = status; + kfree (buffer); } else { bytes_out += count; } @@ -795,7 +799,7 @@ dev_err(dev, "%s - error %d getting connection info\n", __FUNCTION__, retval); else - usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer); + usb_serial_debug_data (__FILE__, __FUNCTION__, retval, transfer_buffer); kfree (transfer_buffer); return 0; @@ -881,18 +885,19 @@ /* Only do this endpoint hack for the Handspring devices with * interrupt in endpoints, which for now are the Treo devices. */ - if ((serial->dev->descriptor.idVendor != HANDSPRING_VENDOR_ID) || + if (!((serial->dev->descriptor.idVendor == HANDSPRING_VENDOR_ID) || + (serial->dev->descriptor.idVendor == KYOCERA_VENDOR_ID)) || (serial->num_interrupt_in == 0)) return 0; dbg("%s", __FUNCTION__); /* - * It appears that Treos want to use the 1st interrupt endpoint to - * communicate with the 2nd bulk out endpoint, so let's swap the 1st - * and 2nd bulk in and interrupt endpoints. Note that swapping the - * bulk out endpoints would break lots of apps that want to communicate - * on the second port. + * It appears that Treos and Kyoceras want to use the + * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, + * so let's swap the 1st and 2nd bulk in and interrupt endpoints. + * Note that swapping the bulk out endpoints would break lots of + * apps that want to communicate on the second port. */ #define COPY_PORT(dest, src) \ dest->read_urb = src->read_urb; \ diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h --- a/drivers/usb/serial/visor.h 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/serial/visor.h 2004-06-26 17:09:20 -07:00 @@ -55,6 +55,9 @@ #define ACEECA_VENDOR_ID 0x4766 #define ACEECA_MEZ1000_ID 0x0001 +#define KYOCERA_VENDOR_ID 0x0C88 +#define KYOCERA_7135_ID 0x0021 + /**************************************************************************** * Handspring Visor Vendor specific request codes (bRequest values) * A big thank you to Handspring for providing the following information. diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c --- a/drivers/usb/serial/whiteheat.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/serial/whiteheat.c 2004-06-26 17:09:17 -07:00 @@ -835,6 +835,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) { struct serial_struct serstruct; + void __user *user_arg = (void __user *)arg; dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); @@ -851,13 +852,13 @@ serstruct.close_delay = CLOSING_DELAY; serstruct.closing_wait = CLOSING_DELAY; - if (copy_to_user((void *)arg, &serstruct, sizeof(serstruct))) + if (copy_to_user(user_arg, &serstruct, sizeof(serstruct))) return -EFAULT; break; case TIOCSSERIAL: - if (copy_from_user(&serstruct, (void *)arg, sizeof(serstruct))) + if (copy_from_user(&serstruct, user_arg, sizeof(serstruct))) return -EFAULT; /* diff -Nru a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig --- a/drivers/usb/storage/Kconfig 2004-06-26 17:09:20 -07:00 +++ b/drivers/usb/storage/Kconfig 2004-06-26 17:09:20 -07:00 @@ -23,6 +23,28 @@ Say Y here in order to have the USB Mass Storage code generate verbose debugging messages. +config USB_STORAGE_RW_DETECT + bool "USB Mass Storage Write-Protected Media Detection (EXPERIMENTAL)" + depends on USB_STORAGE && EXPERIMENTAL + help + Say Y here in order to have the USB Mass Storage code indicate to + the SCSI layer that using MODE SENSE(6) and MODE SENSE(10) to + determine if the media is write-protected is a good thing to do. + + Many devices have historically had trouble with these commands, + hence the default 2.6.x behavior has been to suppress their use. + 2.4.x used these commands with (at best) mixed results, often + crashing the firmware of the device. However, the SCSI layer now + issues these commands in a manner more consistent with other + "popular" OSes, in an attempt to improve compatibility. + + Saying Y here allows these commands to be sent to a USB device. + If you find a device this doesn't work for, switch to N and let + us know at usb-storage@lists.one-eyed-alien.net + + If you say N here, the kernel will assume that all disk-like USB + devices are write-enabled. + config USB_STORAGE_DATAFAB bool "Datafab Compact Flash Reader support (EXPERIMENTAL)" depends on USB_STORAGE && EXPERIMENTAL diff -Nru a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c --- a/drivers/usb/storage/jumpshot.c 2004-06-26 17:09:15 -07:00 +++ b/drivers/usb/storage/jumpshot.c 2004-06-26 17:09:15 -07:00 @@ -471,7 +471,7 @@ // build the reply // - ((u32 *) ptr)[0] = cpu_to_be32(info->sectors); + ((u32 *) ptr)[0] = cpu_to_be32(info->sectors - 1); ((u32 *) ptr)[1] = cpu_to_be32(info->ssize); usb_stor_set_xfer_buf(ptr, 8, srb); diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c --- a/drivers/usb/storage/scsiglue.c 2004-06-26 17:09:18 -07:00 +++ b/drivers/usb/storage/scsiglue.c 2004-06-26 17:09:18 -07:00 @@ -48,13 +48,13 @@ #include "usb.h" #include "debug.h" #include "transport.h" +#include "protocol.h" #include #include #include #include - /*********************************************************************** * Host functions ***********************************************************************/ @@ -68,10 +68,13 @@ { /* * Set default bflags. These can be overridden for individual - * models and vendors via the scsi devinfo mechanism. + * models and vendors via the scsi devinfo mechanism. The only + * flag we need is to force 36-byte INQUIRYs; we don't use any + * of the extra data and many devices choke if asked for more or + * less than 36 bytes. */ - sdev->sdev_bflags = (BLIST_MS_SKIP_PAGE_08 | BLIST_MS_SKIP_PAGE_3F | - BLIST_USE_10_BYTE_MS); + sdev->sdev_bflags = BLIST_INQUIRY_36; + return 0; } @@ -95,11 +98,48 @@ * reduce the maximum transfer size to 64 KB = 128 sectors. */ #define USB_VENDOR_ID_GENESYS 0x05e3 // Needs a standard location + if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS && - us->pusb_dev->speed == USB_SPEED_HIGH) + us->pusb_dev->speed == USB_SPEED_HIGH && + sdev->request_queue->max_sectors > 128) blk_queue_max_sectors(sdev->request_queue, 128); - /* this is to satisify the compiler, tho I don't think the + /* We can't put these settings in slave_alloc() because that gets + * called before the device type is known. Consequently these + * settings can't be overridden via the scsi devinfo mechanism. */ + if (sdev->type == TYPE_DISK) { + + /* Disk-type devices use MODE SENSE(6) if the protocol + * (SubClass) is Transparent SCSI, otherwise they use + * MODE SENSE(10). */ + if (us->subclass != US_SC_SCSI) + sdev->use_10_for_ms = 1; + + /* Many disks only accept MODE SENSE transfer lengths of + * 192 bytes (that's what Windows uses). */ + sdev->use_192_bytes_for_3f = 1; + + /* A number of devices have problems with MODE SENSE for + * page x08, so we will skip it. */ + sdev->skip_ms_page_8 = 1; + +#ifndef CONFIG_USB_STORAGE_RW_DETECT + /* Some devices may not like MODE SENSE with page=0x3f. + * Now that we're using 192-byte transfers this may no + * longer be a problem. So this will be a configuration + * option. */ + sdev->skip_ms_page_3f = 1; +#endif + + } else { + + /* Non-disk-type devices don't need to blacklist any pages + * or to force 192-byte transfer lengths for MODE SENSE. + * But they do need to use MODE SENSE(10). */ + sdev->use_10_for_ms = 1; + } + + /* this is to satisfy the compiler, tho I don't think the * return code is ever checked anywhere. */ return 0; } @@ -408,6 +448,9 @@ /* emulated HBA */ .emulated = TRUE, + + /* we do our own delay after a device or bus reset */ + .skip_settle_delay = 1, /* sysfs device attributes */ .sdev_attrs = sysfs_device_attr_list, diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/usb/storage/transport.c 2004-06-26 17:09:17 -07:00 @@ -908,26 +908,29 @@ USB_RECIP_INTERFACE, 0, us->ifnum, us->iobuf, 1, HZ); + US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", + result, us->iobuf[0]); + + /* if we have a successful request, return the result */ + if (result == 1) + return us->iobuf[0]; + /* * Some devices (i.e. Iomega Zip100) need this -- apparently * the bulk pipes get STALLed when the GetMaxLUN request is * processed. This is, in theory, harmless to all other devices * (regardless of if they stall or not). */ - if (result < 0) { + if (result == -EPIPE) { usb_stor_clear_halt(us, us->recv_bulk_pipe); usb_stor_clear_halt(us, us->send_bulk_pipe); + /* return the default -- no LUNs */ + return 0; } - US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", - result, us->iobuf[0]); - - /* if we have a successful request, return the result */ - if (result == 1) - return us->iobuf[0]; - - /* return the default -- no LUNs */ - return 0; + /* An answer or a STALL are the only valid responses. If we get + * something else, return an indication of error */ + return -1; } int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) @@ -1110,10 +1113,11 @@ goto Done; } - /* long wait for reset, so unlock to allow disconnects */ - up(&us->dev_semaphore); - msleep(6000); - down(&us->dev_semaphore); + /* Give the device some time to recover from the reset, + * but don't delay disconnect processing. */ + wait_event_interruptible_timeout(us->dev_reset_wait, + test_bit(US_FLIDX_DISCONNECTING, &us->flags), + HZ*6); if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { US_DEBUGP("Reset interrupted by disconnect\n"); goto Done; diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/storage/unusual_devs.h 2004-06-26 17:09:19 -07:00 @@ -207,7 +207,7 @@ UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0205, "Shuttle", "eUSB MMC Adapter", - US_SC_SCSI, US_PR_CB, NULL, + US_SC_SCSI, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN), UNUSUAL_DEV( 0x04e6, 0x0007, 0x0100, 0x0200, @@ -359,13 +359,19 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, "Fujifilm", "Digital Camera EX-20 DSC", - US_SC_8070, US_PR_CBI, NULL, 0 ), + US_SC_8070, US_PR_DEVICE, NULL, 0 ), UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200, "LaCie", "USB Hard Disk", US_SC_RBC, US_PR_CB, NULL, 0 ), +/* Submitted by Jol Bourquard */ +UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110, + "In-System", + "PyroGate External CD-ROM Enclosure (FCD-523)", + US_SC_SCSI, US_PR_BULK, NULL, 0 ), + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110, "In-System", @@ -396,8 +402,8 @@ UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, "Lexar", "Jumpshot USB CF Reader", - US_SC_DEVICE, US_PR_JUMPSHOT, NULL, - US_FL_MODE_XLATE ), + US_SC_SCSI, US_PR_JUMPSHOT, NULL, + US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE ), #endif /* Reported by Blake Matheny */ @@ -628,19 +634,13 @@ * - Some cameras with idProduct=0x1001 and bcdDevice=0x1000 have * bInterfaceProtocol=0x00 (US_PR_CBI) while others have 0x01 (US_PR_CB). * So don't remove the US_PR_CB override! + * - Cameras with bcdDevice=0x9009 require the US_SC_8070 override. */ -UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009, +UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, "Casio", "QV DigitalCamera", - US_SC_DEVICE, US_PR_CB, NULL, + US_SC_8070, US_PR_CB, NULL, US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), - -/* Later Casio cameras apparently tell the truth */ -UNUSUAL_DEV( 0x07cf, 0x1001, 0x9010, 0x9999, - "Casio", - "QV DigitalCamera", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_INQUIRY ), /* Submitted by Hartmut Wahl */ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c --- a/drivers/usb/storage/usb.c 2004-06-26 17:09:16 -07:00 +++ b/drivers/usb/storage/usb.c 2004-06-26 17:09:16 -07:00 @@ -266,6 +266,7 @@ static int usb_stor_control_thread(void * __us) { struct us_data *us = (struct us_data *)__us; + struct Scsi_Host *host = us->host; lock_kernel(); @@ -283,19 +284,21 @@ complete(&(us->notify)); for(;;) { - struct Scsi_Host *host; US_DEBUGP("*** thread sleeping.\n"); if(down_interruptible(&us->sema)) break; US_DEBUGP("*** thread awakened.\n"); + /* lock the device pointers */ + down(&(us->dev_semaphore)); + /* if us->srb is NULL, we are being asked to exit */ if (us->srb == NULL) { US_DEBUGP("-- exit command received\n"); + up(&(us->dev_semaphore)); break; } - host = us->srb->device->host; /* lock access to the state */ scsi_lock(host); @@ -306,23 +309,20 @@ goto SkipForAbort; } - /* set the state and release the lock */ - us->sm_state = US_STATE_RUNNING; - scsi_unlock(host); - - /* lock the device pointers */ - down(&(us->dev_semaphore)); - /* don't do anything if we are disconnecting */ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { US_DEBUGP("No command during disconnect\n"); - us->srb->result = DID_BAD_TARGET << 16; + goto SkipForDisconnect; } + /* set the state and release the lock */ + us->sm_state = US_STATE_RUNNING; + scsi_unlock(host); + /* reject the command if the direction indicator * is UNKNOWN */ - else if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) { + if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) { US_DEBUGP("UNKNOWN data direction\n"); us->srb->result = DID_ERROR << 16; } @@ -362,9 +362,6 @@ us->proto_handler(us->srb, us); } - /* unlock the device pointers */ - up(&(us->dev_semaphore)); - /* lock access to the state */ scsi_lock(host); @@ -374,7 +371,7 @@ us->srb->result); us->srb->scsi_done(us->srb); } else { - SkipForAbort: +SkipForAbort: US_DEBUGP("scsi command aborted\n"); } @@ -387,9 +384,13 @@ complete(&(us->notify)); /* empty the queue, reset the state, and release the lock */ +SkipForDisconnect: us->srb = NULL; us->sm_state = US_STATE_IDLE; scsi_unlock(host); + + /* unlock the device pointers */ + up(&(us->dev_semaphore)); } /* for (;;) */ /* notify the exit routine that we're actually exiting now @@ -423,10 +424,8 @@ us->pusb_intf = intf; us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; - /* Store our private data in the interface and increment the - * device's reference count */ + /* Store our private data in the interface */ usb_set_intfdata(intf, us); - usb_get_dev(us->pusb_dev); /* Allocate the device-related DMA-mapped buffers */ us->cr = usb_buffer_alloc(us->pusb_dev, sizeof(*us->cr), @@ -754,8 +753,14 @@ down(&us->dev_semaphore); /* For bulk-only devices, determine the max LUN value */ - if (us->protocol == US_PR_BULK) - us->max_lun = usb_stor_Bulk_max_lun(us); + if (us->protocol == US_PR_BULK) { + p = usb_stor_Bulk_max_lun(us); + if (p < 0) { + up(&us->dev_semaphore); + return p; + } + us->max_lun = p; + } /* Just before we start our control thread, initialize * the device if it needs initialization */ @@ -764,19 +769,6 @@ up(&us->dev_semaphore); - /* Start up our control thread */ - us->sm_state = US_STATE_IDLE; - p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); - if (p < 0) { - printk(KERN_WARNING USB_STORAGE - "Unable to start control thread\n"); - return p; - } - us->pid = p; - - /* Wait for the thread to start */ - wait_for_completion(&(us->notify)); - /* * Since this is a new device, we need to register a SCSI * host definition with the higher SCSI layers. @@ -784,69 +776,61 @@ us->host = scsi_host_alloc(&usb_stor_host_template, sizeof(us)); if (!us->host) { printk(KERN_WARNING USB_STORAGE - "Unable to register the scsi host\n"); + "Unable to allocate the scsi host\n"); return -EBUSY; } /* Set the hostdata to prepare for scanning */ us->host->hostdata[0] = (unsigned long) us; - return 0; -} - -/* Dissociate from the USB device */ -static void dissociate_dev(struct us_data *us) -{ - US_DEBUGP("-- %s\n", __FUNCTION__); - down(&us->dev_semaphore); - - /* Free the device-related DMA-mapped buffers */ - if (us->cr) { - usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, - us->cr_dma); - us->cr = NULL; - } - if (us->iobuf) { - usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf, - us->iobuf_dma); - us->iobuf = NULL; + /* Start up our control thread */ + us->sm_state = US_STATE_IDLE; + p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); + if (p < 0) { + printk(KERN_WARNING USB_STORAGE + "Unable to start control thread\n"); + return p; } + us->pid = p; - /* Remove our private data from the interface and decrement the - * device's reference count */ - usb_set_intfdata(us->pusb_intf, NULL); - usb_put_dev(us->pusb_dev); + /* Wait for the thread to start */ + wait_for_completion(&(us->notify)); - us->pusb_dev = NULL; - us->pusb_intf = NULL; - up(&us->dev_semaphore); + return 0; } -/* Release all our static and dynamic resources */ +/* Release all our dynamic resources */ void usb_stor_release_resources(struct us_data *us) { - /* - * The host must already have been removed - * and dissociate_dev() must have been called. - */ - - /* Finish the SCSI host removal sequence */ - if (us->host) { - us->host->hostdata[0] = 0; - scsi_host_put(us->host); - } + US_DEBUGP("-- %s\n", __FUNCTION__); - /* Kill the control thread - * - * Enqueue the command, wake up the thread, and wait for - * notification that it has exited. + /* Kill the control thread. The SCSI host must already have been + * removed so it won't try to queue any more commands. */ if (us->pid) { + + /* Wait for the thread to be idle */ + down(&us->dev_semaphore); US_DEBUGP("-- sending exit command to thread\n"); BUG_ON(us->sm_state != US_STATE_IDLE); + + /* If the SCSI midlayer queued a final command just before + * scsi_remove_host() was called, us->srb might not be + * NULL. We can overwrite it safely, because the midlayer + * will not wait for the command to finish. Also the + * control thread will already have been awakened. + * That's okay, an extra up() on us->sema won't hurt. + * + * Enqueue the command, wake up the thread, and wait for + * notification that it has exited. + */ + scsi_lock(us->host); us->srb = NULL; - up(&(us->sema)); - wait_for_completion(&(us->notify)); + scsi_unlock(us->host); + up(&us->dev_semaphore); + + up(&us->sema); + wait_for_completion(&us->notify); } /* Call the destructor routine, if it exists */ @@ -855,15 +839,36 @@ us->extra_destructor(us->extra); } + /* Finish the host removal sequence */ + if (us->host) + scsi_host_put(us->host); + /* Free the extra data and the URB */ if (us->extra) kfree(us->extra); if (us->current_urb) usb_free_urb(us->current_urb); +} + +/* Dissociate from the USB device */ +static void dissociate_dev(struct us_data *us) +{ + US_DEBUGP("-- %s\n", __FUNCTION__); + + /* Free the device-related DMA-mapped buffers */ + if (us->cr) + usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, + us->cr_dma); + if (us->iobuf) + usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf, + us->iobuf_dma); + + /* Remove our private data from the interface */ + usb_set_intfdata(us->pusb_intf, NULL); + /* Free the structure itself */ kfree(us); - US_DEBUGP("-- %s finished\n", __FUNCTION__); } /* Probe to see if we can drive a newly-connected USB device */ @@ -889,6 +894,7 @@ init_MUTEX(&(us->dev_semaphore)); init_MUTEX_LOCKED(&(us->sema)); init_completion(&(us->notify)); + init_waitqueue_head(&us->dev_reset_wait); /* Associate the us_data structure with the USB device */ result = associate_dev(us, intf); @@ -959,8 +965,8 @@ /* We come here if there are any problems */ BadDevice: US_DEBUGP("storage_probe() failed\n"); - dissociate_dev(us); usb_stor_release_resources(us); + dissociate_dev(us); return result; } @@ -971,20 +977,20 @@ US_DEBUGP("storage_disconnect() called\n"); - /* Prevent new USB transfers and stop the current command */ + /* Prevent new USB transfers, stop the current command, and + * interrupt a device-reset delay */ set_bit(US_FLIDX_DISCONNECTING, &us->flags); usb_stor_stop_transport(us); + wake_up(&us->dev_reset_wait); - /* Dissociate from the USB device */ - dissociate_dev(us); - + /* Wait for the current command to finish, then remove the host */ + down(&us->dev_semaphore); + up(&us->dev_semaphore); scsi_remove_host(us->host); - /* TODO: somehow, wait for the device to - * be 'idle' (tasklet completion) */ - - /* Release all our other resources */ + /* Wait for everything to become idle and release all our resources */ usb_stor_release_resources(us); + dissociate_dev(us); } /*********************************************************************** @@ -1017,47 +1023,6 @@ */ US_DEBUGP("-- calling usb_deregister()\n"); usb_deregister(&usb_storage_driver) ; - -#if 0 - /* While there are still virtual hosts, unregister them - * Note that it's important to do this completely before removing - * the structures because of possible races with the /proc - * interface - */ - for (next = us_list; next; next = next->next) { - US_DEBUGP("-- calling scsi_unregister_host()\n"); - scsi_unregister_host(&usb_stor_host_template); - } - - /* While there are still structures, free them. Note that we are - * now race-free, since these structures can no longer be accessed - * from either the SCSI command layer or the /proc interface - */ - while (us_list) { - /* keep track of where the next one is */ - next = us_list->next; - - /* If there's extra data in the us_data structure then - * free that first */ - if (us_list->extra) { - /* call the destructor routine, if it exists */ - if (us_list->extra_destructor) { - US_DEBUGP("-- calling extra_destructor()\n"); - us_list->extra_destructor(us_list->extra); - } - - /* destroy the extra data */ - US_DEBUGP("-- freeing the data structure\n"); - kfree(us_list->extra); - } - - /* free the structure itself */ - kfree (us_list); - - /* advance the list pointer */ - us_list = next; - } -#endif } module_init(usb_stor_init); diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h --- a/drivers/usb/storage/usb.h 2004-06-26 17:09:19 -07:00 +++ b/drivers/usb/storage/usb.h 2004-06-26 17:09:19 -07:00 @@ -158,9 +158,10 @@ dma_addr_t cr_dma; /* buffer DMA addresses */ dma_addr_t iobuf_dma; - /* mutual exclusion structures */ + /* mutual exclusion and synchronization structures */ struct semaphore sema; /* to sleep thread on */ - struct completion notify; /* thread begin/end */ + struct completion notify; /* thread begin/end */ + wait_queue_head_t dev_reset_wait; /* wait during reset */ /* subdriver information */ void *extra; /* Any extra data */ diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig --- a/drivers/video/Kconfig 2004-06-26 17:09:15 -07:00 +++ b/drivers/video/Kconfig 2004-06-26 17:09:15 -07:00 @@ -40,7 +40,7 @@ config FB_CIRRUS tristate "Cirrus Logic support" - depends on FB && (AMIGA || PCI) && BROKEN + depends on FB && (AMIGA || PCI) ---help--- This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. @@ -424,6 +424,8 @@ config FB_RIVA tristate "nVidia Riva support" depends on FB && PCI + select I2C_ALGOBIT if FB_RIVA_I2C + select I2C if FB_RIVA_I2C help This driver supports graphics boards with the nVidia Riva/Geforce chips. @@ -431,6 +433,18 @@ To compile this driver as a module, choose M here: the module will be called rivafb. + +config FB_RIVA_I2C + bool "Enable DDC Support" + depends on FB_RIVA + help + This enables I2C support for nVidia Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. config FB_I810 tristate "Intel 810/815 support (EXPERIMENTAL)" diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile --- a/drivers/video/Makefile 2004-06-26 17:09:15 -07:00 +++ b/drivers/video/Makefile 2004-06-26 17:09:15 -07:00 @@ -39,7 +39,7 @@ obj-$(CONFIG_FB_OF) += offb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_IMSTT) += imsttfb.o cfbimgblt.o obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o -obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o +obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_TRIDENT) += tridentfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_S3TRIO) += S3triofb.o obj-$(CONFIG_FB_TGA) += tgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o diff -Nru a/drivers/video/acornfb.c b/drivers/video/acornfb.c --- a/drivers/video/acornfb.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/video/acornfb.c 2004-06-26 17:09:20 -07:00 @@ -1246,6 +1246,8 @@ /* * This enables the unused memory to be freed on older Acorn machines. + * We are freeing memory on behalf of the architecture initialisation + * code here. */ static inline void free_unused_pages(unsigned int virtual_start, unsigned int virtual_end) @@ -1268,7 +1270,7 @@ */ page = virt_to_page(virtual_start); ClearPageReserved(page); - atomic_set(&page->count, 1); + set_page_count(page, 1); free_page(virtual_start); virtual_start += PAGE_SIZE; diff -Nru a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c --- a/drivers/video/aty/radeon_accel.c 2004-06-26 17:09:19 -07:00 +++ b/drivers/video/aty/radeon_accel.c 2004-06-26 17:09:19 -07:00 @@ -38,8 +38,8 @@ return; } - vxres = info->var.xres; - vyres = info->var.yres; + vxres = info->var.xres_virtual; + vyres = info->var.yres_virtual; memcpy(&modded, region, sizeof(struct fb_fillrect)); @@ -104,8 +104,8 @@ return; } - vxres = info->var.xres; - vyres = info->var.yres; + vxres = info->var.xres_virtual; + vyres = info->var.yres_virtual; if(!modded.width || !modded.height || modded.sx >= vxres || modded.sy >= vyres || diff -Nru a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c --- a/drivers/video/aty/radeon_base.c 2004-06-26 17:09:17 -07:00 +++ b/drivers/video/aty/radeon_base.c 2004-06-26 17:09:17 -07:00 @@ -858,6 +858,7 @@ if (rinfo->asleep) return 0; + radeon_fifo_wait(2); OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7); return 0; @@ -882,11 +883,12 @@ if (!rinfo->is_mobility) return -EINVAL; - rc = get_user(value, (__u32*)arg); + rc = get_user(value, (__u32 __user *)arg); if (rc) return rc; + radeon_fifo_wait(2); if (value & 0x01) { tmp = INREG(LVDS_GEN_CNTL); @@ -926,7 +928,7 @@ if (CRTC_CRT_ON & tmp) value |= 0x02; - return put_user(value, (__u32*)arg); + return put_user(value, (__u32 __user *)arg); default: return -EINVAL; } @@ -963,6 +965,7 @@ break; } + radeon_fifo_wait(1); switch (rinfo->mon1_type) { case MT_LCD: OUTREG(LVDS_GEN_CNTL, val2); @@ -1021,6 +1024,7 @@ if (!rinfo->asleep) { u32 dac_cntl2, vclk_cntl = 0; + radeon_fifo_wait(9); if (rinfo->is_mobility) { vclk_cntl = INPLL(VCLK_ECP_CNTL); OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); @@ -1112,6 +1116,8 @@ { int i; + radeon_fifo_wait(20); + /* Workaround from XFree */ if (rinfo->is_mobility) { /* A temporal workaround for the occational blanking on certain laptop panels. @@ -1198,6 +1204,8 @@ { struct radeonfb_info *rinfo = (struct radeonfb_info *)data; + radeon_fifo_wait(3); + OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); if (rinfo->pending_pixclks_cntl) { OUTPLL(PIXCLKS_CNTL, rinfo->pending_pixclks_cntl); @@ -1222,6 +1230,7 @@ radeon_screen_blank(rinfo, VESA_POWERDOWN); + radeon_fifo_wait(31); for (i=0; i<10; i++) OUTREG(common_regs[i].reg, common_regs[i].val); @@ -1249,6 +1258,7 @@ radeon_write_pll_regs(rinfo, mode); if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { + radeon_fifo_wait(10); OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); @@ -1288,6 +1298,7 @@ radeon_screen_blank(rinfo, VESA_NO_BLANKING); + radeon_fifo_wait(2); OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); return; @@ -1696,7 +1707,7 @@ -static ssize_t radeonfb_read(struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t radeonfb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; struct inode *inode = file->f_dentry->d_inode; @@ -1723,7 +1734,7 @@ return count; } -static ssize_t radeonfb_write(struct file *file, const char *buf, size_t count, +static ssize_t radeonfb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; @@ -1864,6 +1875,7 @@ del_timer_sync(&rinfo->lvds_timer); lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON); + radeon_fifo_wait(3); if (on && (level > BACKLIGHT_OFF)) { lvds_gen_cntl |= LVDS_DIGON; if (!(lvds_gen_cntl & LVDS_ON)) { @@ -2136,6 +2148,7 @@ u32 tom = INREG(NB_TOM); tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); + radeon_fifo_wait(6); OUTREG(MC_FB_LOCATION, tom); OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); @@ -2255,9 +2268,17 @@ /* * Map the BIOS ROM if any and retreive PLL parameters from - * either BIOS or Open Firmware + * the BIOS. We skip that on mobility chips as the real panel + * values we need aren't in the ROM but in the BIOS image in + * memory. This is definitely not the best meacnism though, + * we really need the arch code to tell us which is the "primary" + * video adapter to use the memory image (or better, the arch + * should provide us a copy of the BIOS image to shield us from + * archs who would store that elsewhere and/or could initialize + * more than one adapter during boot). */ - radeon_map_ROM(rinfo, pdev); + if (!rinfo->is_mobility) + radeon_map_ROM(rinfo, pdev); /* * On x86, the primary display on laptop may have it's BIOS @@ -2269,6 +2290,12 @@ if (rinfo->bios_seg == NULL) radeon_find_mem_vbios(rinfo); #endif /* __i386__ */ + + /* If both above failed, try the BIOS ROM again for mobility + * chips + */ + if (rinfo->bios_seg == NULL && rinfo->is_mobility) + radeon_map_ROM(rinfo, pdev); /* Get informations about the board's PLL */ radeon_get_pllinfo(rinfo); diff -Nru a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c --- a/drivers/video/cirrusfb.c 2004-06-26 17:09:20 -07:00 +++ b/drivers/video/cirrusfb.c 2004-06-26 17:09:20 -07:00 @@ -1,10 +1,13 @@ /* - * drivers/video/clgenfb.c - driver for Cirrus Logic chipsets + * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets * * Copyright 1999-2001 Jeff Garzik * * Contributors (thanks, all!) * + * David Eger: + * Overhaul for Linux 2.6 + * * Jeff Rugen: * Major contributions; Motorola PowerStack (PPC and PCI) support, * GD54xx, 1280x1024 mode support, change MCLK based on VCLK. @@ -15,9 +18,9 @@ * Lars Hecking: * Amiga updates and testing. * - * Original clgenfb author: Frank Neumann + * Original cirrusfb author: Frank Neumann * - * Based on retz3fb.c and clgen.c: + * Based on retz3fb.c and cirrusfb.c: * Copyright (C) 1997 Jes Sorensen * Copyright (C) 1996 Frank Neumann * @@ -31,7 +34,7 @@ * */ -#define CLGEN_VERSION "1.9.9.1" +#define CIRRUSFB_VERSION "2.0-pre2" #include #include @@ -63,15 +66,8 @@ #define isPReP 0 #endif -#include