Przeglądaj źródła

Merge from Linus' tree.

Paul Mackerras 19 lat temu
rodzic
commit
e5baa396af
100 zmienionych plików z 776 dodań i 435 usunięć
  1. 1 1
      Documentation/DocBook/kernel-hacking.tmpl
  2. 73 0
      Documentation/device-mapper/snapshot.txt
  3. 2 2
      Documentation/sparse.txt
  4. 31 43
      Documentation/usb/URB.txt
  5. 18 2
      MAINTAINERS
  6. 1 1
      Makefile
  7. 6 3
      README
  8. 4 0
      arch/alpha/kernel/process.c
  9. 23 18
      arch/alpha/kernel/sys_dp264.c
  10. 1 1
      arch/arm/boot/compressed/ofw-shark.c
  11. 1 1
      arch/arm/kernel/entry-armv.S
  12. 3 3
      arch/arm/kernel/io.c
  13. 1 1
      arch/arm/kernel/semaphore.c
  14. 3 0
      arch/arm/kernel/traps.c
  15. 4 4
      arch/arm/kernel/vmlinux.lds.S
  16. 6 0
      arch/arm/mach-ixp4xx/ixdp425-setup.c
  17. 2 1
      arch/arm/mach-s3c2410/mach-anubis.c
  18. 2 1
      arch/arm/mach-s3c2410/mach-bast.c
  19. 4 3
      arch/arm/mach-s3c2410/mach-h1940.c
  20. 3 3
      arch/arm/mach-s3c2410/mach-n30.c
  21. 1 1
      arch/arm/mach-s3c2410/mach-nexcoder.c
  22. 1 1
      arch/arm/mach-s3c2410/mach-otom.c
  23. 3 2
      arch/arm/mach-s3c2410/mach-rx3715.c
  24. 3 2
      arch/arm/mach-s3c2410/mach-smdk2410.c
  25. 3 2
      arch/arm/mach-s3c2410/mach-smdk2440.c
  26. 2 1
      arch/arm/mach-s3c2410/mach-vr1000.c
  27. 3 0
      arch/arm/mach-sa1100/generic.h
  28. 11 1
      arch/arm/mm/fault.c
  29. 1 1
      arch/arm/mm/proc-arm1020.S
  30. 1 1
      arch/arm/mm/proc-arm1020e.S
  31. 1 1
      arch/arm/mm/proc-arm1022.S
  32. 1 1
      arch/arm/mm/proc-arm1026.S
  33. 1 1
      arch/arm/mm/proc-arm6_7.S
  34. 1 1
      arch/arm/mm/proc-arm720.S
  35. 1 1
      arch/arm/mm/proc-arm920.S
  36. 1 1
      arch/arm/mm/proc-arm922.S
  37. 1 1
      arch/arm/mm/proc-arm925.S
  38. 1 1
      arch/arm/mm/proc-arm926.S
  39. 1 1
      arch/arm/mm/proc-sa110.S
  40. 1 1
      arch/arm/mm/proc-sa1100.S
  41. 1 1
      arch/arm/mm/proc-v6.S
  42. 1 1
      arch/arm/mm/proc-xscale.S
  43. 23 6
      arch/ia64/hp/sim/simscsi.c
  44. 85 11
      arch/ia64/kernel/mca_asm.S
  45. 15 6
      arch/ia64/kernel/mca_drv.c
  46. 1 2
      arch/ppc/kernel/Makefile
  47. 5 1
      arch/ppc/kernel/perfmon.c
  48. 6 4
      arch/ppc/platforms/pmac_setup.c
  49. 4 2
      arch/ppc/syslib/of_device.c
  50. 4 4
      arch/ppc/syslib/ppc85xx_setup.c
  51. 1 1
      arch/ppc64/Makefile
  52. 5 2
      arch/ppc64/kernel/of_device.c
  53. 95 86
      arch/ppc64/kernel/pSeries_iommu.c
  54. 6 3
      arch/ppc64/kernel/pci.c
  55. 13 5
      arch/ppc64/kernel/pmac_setup.c
  56. 2 2
      arch/ppc64/kernel/pmac_time.c
  57. 2 1
      arch/ppc64/kernel/prom_init.c
  58. 1 0
      arch/ppc64/kernel/ptrace.c
  59. 2 3
      arch/ppc64/mm/hash_native.c
  60. 5 2
      arch/ppc64/mm/hugetlbpage.c
  61. 19 20
      arch/sparc64/kernel/entry.S
  62. 4 3
      arch/sparc64/kernel/ptrace.c
  63. 1 1
      arch/sparc64/kernel/una_asm.S
  64. 57 7
      arch/sparc64/kernel/unaligned.c
  65. 5 1
      arch/um/Makefile
  66. 43 17
      arch/um/drivers/chan_kern.c
  67. 1 1
      arch/um/drivers/mconsole_user.c
  68. 3 1
      arch/um/include/common-offsets.h
  69. 3 1
      arch/um/include/user.h
  70. 2 1
      arch/um/kernel/process_kern.c
  71. 1 1
      arch/um/kernel/sigio_user.c
  72. 0 6
      arch/um/kernel/skas/include/uaccess-skas.h
  73. 6 6
      arch/um/kernel/tlb.c
  74. 17 1
      arch/um/kernel/trap_kern.c
  75. 0 6
      arch/um/kernel/tt/include/uaccess-tt.h
  76. 2 1
      arch/um/kernel/tt/process_kern.c
  77. 9 2
      arch/um/kernel/tt/uaccess_user.c
  78. 23 18
      arch/um/kernel/umid.c
  79. 6 0
      arch/um/kernel/user_util.c
  80. 1 0
      arch/um/os-Linux/aio.c
  81. 2 1
      arch/um/os-Linux/elf_aux.c
  82. 1 0
      arch/um/os-Linux/process.c
  83. 1 0
      arch/um/sys-i386/ldt.c
  84. 1 1
      arch/x86_64/Kconfig
  85. 2 2
      arch/xtensa/kernel/pci.c
  86. 1 1
      arch/xtensa/kernel/platform.c
  87. 1 1
      arch/xtensa/kernel/process.c
  88. 1 1
      arch/xtensa/kernel/setup.c
  89. 1 1
      arch/xtensa/kernel/signal.c
  90. 1 1
      arch/xtensa/kernel/time.c
  91. 1 1
      arch/xtensa/mm/init.c
  92. 2 1
      drivers/acorn/char/pcf8583.c
  93. 13 0
      drivers/base/class.c
  94. 3 0
      drivers/base/dd.c
  95. 1 4
      drivers/block/cciss.c
  96. 0 38
      drivers/block/ll_rw_blk.c
  97. 29 26
      drivers/block/ub.c
  98. 0 1
      drivers/char/hpet.c
  99. 3 3
      drivers/char/ipmi/ipmi_msghandler.c
  100. 4 5
      drivers/hwmon/Kconfig

+ 1 - 1
Documentation/DocBook/kernel-hacking.tmpl

@@ -1105,7 +1105,7 @@ static struct block_device_operations opt_fops = {
     </listitem>
     </listitem>
     <listitem>
     <listitem>
      <para>
      <para>
-      Function names as strings (__func__).
+      Function names as strings (__FUNCTION__).
      </para>
      </para>
     </listitem>
     </listitem>
     <listitem>
     <listitem>

+ 73 - 0
Documentation/device-mapper/snapshot.txt

@@ -0,0 +1,73 @@
+Device-mapper snapshot support
+==============================
+
+Device-mapper allows you, without massive data copying:
+
+*) To create snapshots of any block device i.e. mountable, saved states of
+the block device which are also writable without interfering with the
+original content;
+*) To create device "forks", i.e. multiple different versions of the
+same data stream.
+
+
+In both cases, dm copies only the chunks of data that get changed and
+uses a separate copy-on-write (COW) block device for storage.
+
+
+There are two dm targets available: snapshot and snapshot-origin.
+
+*) snapshot-origin <origin>
+
+which will normally have one or more snapshots based on it.
+You must create the snapshot-origin device before you can create snapshots.
+Reads will be mapped directly to the backing device. For each write, the
+original data will be saved in the <COW device> of each snapshot to keep
+its visible content unchanged, at least until the <COW device> fills up.
+
+
+*) snapshot <origin> <COW device> <persistent?> <chunksize>
+
+A snapshot is created of the <origin> block device. Changed chunks of
+<chunksize> sectors will be stored on the <COW device>.  Writes will
+only go to the <COW device>.  Reads will come from the <COW device> or
+from <origin> for unchanged data.  <COW device> will often be
+smaller than the origin and if it fills up the snapshot will become
+useless and be disabled, returning errors.  So it is important to monitor
+the amount of free space and expand the <COW device> before it fills up.
+
+<persistent?> is P (Persistent) or N (Not persistent - will not survive
+after reboot).
+
+
+How this is used by LVM2
+========================
+When you create the first LVM2 snapshot of a volume, four dm devices are used:
+
+1) a device containing the original mapping table of the source volume;
+2) a device used as the <COW device>;
+3) a "snapshot" device, combining #1 and #2, which is the visible snapshot
+   volume;
+4) the "original" volume (which uses the device number used by the original
+   source volume), whose table is replaced by a "snapshot-origin" mapping
+   from device #1.
+
+A fixed naming scheme is used, so with the following commands:
+
+lvcreate -L 1G -n base volumeGroup
+lvcreate -L 100M --snapshot -n snap volumeGroup/base
+
+we'll have this situation (with volumes in above order):
+
+# dmsetup table|grep volumeGroup
+
+volumeGroup-base-real: 0 2097152 linear 8:19 384
+volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
+volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
+volumeGroup-base: 0 2097152 snapshot-origin 254:11
+
+# ls -lL /dev/mapper/volumeGroup-*
+brw-------  1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
+brw-------  1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
+brw-------  1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
+brw-------  1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
+

+ 2 - 2
Documentation/sparse.txt

@@ -51,9 +51,9 @@ or you don't get any checking at all.
 Where to get sparse
 Where to get sparse
 ~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~
 
 
-With BK, you can just get it from
+With git, you can just get it from
 
 
-        bk://sparse.bkbits.net/sparse
+        rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git
 
 
 and DaveJ has tar-balls at
 and DaveJ has tar-balls at
 
 

+ 31 - 43
Documentation/usb/URB.txt

@@ -1,5 +1,6 @@
 Revised: 2000-Dec-05.
 Revised: 2000-Dec-05.
 Again:   2002-Jul-06
 Again:   2002-Jul-06
+Again:   2005-Sep-19
 
 
     NOTE:
     NOTE:
 
 
@@ -18,8 +19,8 @@ called USB Request Block, or URB for short.
   and deliver the data and status back. 
   and deliver the data and status back. 
 
 
 - Execution of an URB is inherently an asynchronous operation, i.e. the 
 - Execution of an URB is inherently an asynchronous operation, i.e. the 
-  usb_submit_urb(urb) call returns immediately after it has successfully queued 
-  the requested action. 
+  usb_submit_urb(urb) call returns immediately after it has successfully
+  queued the requested action.
 
 
 - Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time. 
 - Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time. 
 
 
@@ -94,8 +95,9 @@ To free an URB, use
 
 
 	void usb_free_urb(struct urb *urb)
 	void usb_free_urb(struct urb *urb)
 
 
-You may not free an urb that you've submitted, but which hasn't yet been
-returned to you in a completion callback.
+You may free an urb that you've submitted, but which hasn't yet been
+returned to you in a completion callback.  It will automatically be
+deallocated when it is no longer in use.
 
 
 
 
 1.4. What has to be filled in?
 1.4. What has to be filled in?
@@ -145,30 +147,36 @@ to get seamless ISO streaming.
 
 
 1.6. How to cancel an already running URB?
 1.6. How to cancel an already running URB?
 
 
-For an URB which you've submitted, but which hasn't been returned to
-your driver by the host controller, call
+There are two ways to cancel an URB you've submitted but which hasn't
+been returned to your driver yet.  For an asynchronous cancel, call
 
 
 	int usb_unlink_urb(struct urb *urb)
 	int usb_unlink_urb(struct urb *urb)
 
 
 It removes the urb from the internal list and frees all allocated
 It removes the urb from the internal list and frees all allocated
-HW descriptors. The status is changed to reflect unlinking. After 
-usb_unlink_urb() returns with that status code, you can free the URB
-with usb_free_urb().
+HW descriptors. The status is changed to reflect unlinking.  Note
+that the URB will not normally have finished when usb_unlink_urb()
+returns; you must still wait for the completion handler to be called.
 
 
-There is also an asynchronous unlink mode.  To use this, set the
-the URB_ASYNC_UNLINK flag in urb->transfer flags before calling
-usb_unlink_urb().  When using async unlinking, the URB will not
-normally be unlinked when usb_unlink_urb() returns.  Instead, wait
-for the completion handler to be called.
+To cancel an URB synchronously, call
+
+	void usb_kill_urb(struct urb *urb)
+
+It does everything usb_unlink_urb does, and in addition it waits
+until after the URB has been returned and the completion handler
+has finished.  It also marks the URB as temporarily unusable, so
+that if the completion handler or anyone else tries to resubmit it
+they will get a -EPERM error.  Thus you can be sure that when
+usb_kill_urb() returns, the URB is totally idle.
 
 
 
 
 1.7. What about the completion handler?
 1.7. What about the completion handler?
 
 
 The handler is of the following type:
 The handler is of the following type:
 
 
-	typedef void (*usb_complete_t)(struct urb *);
+	typedef void (*usb_complete_t)(struct urb *, struct pt_regs *)
 
 
-i.e. it gets just the URB that caused the completion call.
+I.e., it gets the URB that caused the completion call, plus the
+register values at the time of the corresponding interrupt (if any).
 In the completion handler, you should have a look at urb->status to
 In the completion handler, you should have a look at urb->status to
 detect any USB errors. Since the context parameter is included in the URB,
 detect any USB errors. Since the context parameter is included in the URB,
 you can pass information to the completion handler. 
 you can pass information to the completion handler. 
@@ -176,17 +184,11 @@ you can pass information to the completion handler.
 Note that even when an error (or unlink) is reported, data may have been
 Note that even when an error (or unlink) is reported, data may have been
 transferred.  That's because USB transfers are packetized; it might take
 transferred.  That's because USB transfers are packetized; it might take
 sixteen packets to transfer your 1KByte buffer, and ten of them might
 sixteen packets to transfer your 1KByte buffer, and ten of them might
-have transferred succesfully before the completion is called.
+have transferred succesfully before the completion was called.
 
 
 
 
 NOTE:  ***** WARNING *****
 NOTE:  ***** WARNING *****
-Don't use urb->dev field in your completion handler; it's cleared
-as part of giving urbs back to drivers.  (Addressing an issue with
-ownership of periodic URBs, which was otherwise ambiguous.) Instead,
-use urb->context to hold all the data your driver needs.
-
-NOTE:  ***** WARNING *****
-Also, NEVER SLEEP IN A COMPLETION HANDLER.  These are normally called
+NEVER SLEEP IN A COMPLETION HANDLER.  These are normally called
 during hardware interrupt processing.  If you can, defer substantial
 during hardware interrupt processing.  If you can, defer substantial
 work to a tasklet (bottom half) to keep system latencies low.  You'll
 work to a tasklet (bottom half) to keep system latencies low.  You'll
 probably need to use spinlocks to protect data structures you manipulate
 probably need to use spinlocks to protect data structures you manipulate
@@ -229,24 +231,10 @@ ISO data with some other event stream.
 Interrupt transfers, like isochronous transfers, are periodic, and happen
 Interrupt transfers, like isochronous transfers, are periodic, and happen
 in intervals that are powers of two (1, 2, 4 etc) units.  Units are frames
 in intervals that are powers of two (1, 2, 4 etc) units.  Units are frames
 for full and low speed devices, and microframes for high speed ones.
 for full and low speed devices, and microframes for high speed ones.
-
-Currently, after you submit one interrupt URB, that urb is owned by the
-host controller driver until you cancel it with usb_unlink_urb().  You
-may unlink interrupt urbs in their completion handlers, if you need to.
-
-After a transfer completion is called, the URB is automagically resubmitted.
-THIS BEHAVIOR IS EXPECTED TO BE REMOVED!!
-
-Interrupt transfers may only send (or receive) the "maxpacket" value for
-the given interrupt endpoint; if you need more data, you will need to
-copy that data out of (or into) another buffer.  Similarly, you can't
-queue interrupt transfers.
-THESE RESTRICTIONS ARE EXPECTED TO BE REMOVED!!
-
-Note that this automagic resubmission model does make it awkward to use
-interrupt OUT transfers.  The portable solution involves unlinking those
-OUT urbs after the data is transferred, and perhaps submitting a final
-URB for a short packet.
-
 The usb_submit_urb() call modifies urb->interval to the implemented interval
 The usb_submit_urb() call modifies urb->interval to the implemented interval
 value that is less than or equal to the requested interval value.
 value that is less than or equal to the requested interval value.
+
+In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically
+restarted when they complete.  They end when the completion handler is
+called, just like other URBs.  If you want an interrupt URB to be restarted,
+your completion handler must resubmit it.

+ 18 - 2
MAINTAINERS

@@ -1063,8 +1063,6 @@ M:	wli@holomorphy.com
 S:	Maintained
 S:	Maintained
 
 
 I2C SUBSYSTEM
 I2C SUBSYSTEM
-P:	Greg Kroah-Hartman
-M:	greg@kroah.com
 P:	Jean Delvare
 P:	Jean Delvare
 M:	khali@linux-fr.org
 M:	khali@linux-fr.org
 L:	lm-sensors@lm-sensors.org
 L:	lm-sensors@lm-sensors.org
@@ -1404,6 +1402,18 @@ L:	linux-kernel@vger.kernel.org
 L:	fastboot@osdl.org
 L:	fastboot@osdl.org
 S:	Maintained
 S:	Maintained
 
 
+KPROBES
+P:	Prasanna S Panchamukhi
+M:	prasanna@in.ibm.com
+P:	Ananth N Mavinakayanahalli
+M:	ananth@in.ibm.com
+P:	Anil S Keshavamurthy
+M:	anil.s.keshavamurthy@intel.com
+P:	David S. Miller
+M:	davem@davemloft.net
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 LANMEDIA WAN CARD DRIVER
 LANMEDIA WAN CARD DRIVER
 P:	Andrew Stanley-Jones
 P:	Andrew Stanley-Jones
 M:	asj@lanmedia.com
 M:	asj@lanmedia.com
@@ -2266,6 +2276,12 @@ M:	kristen.c.accardi@intel.com
 L:	pcihpd-discuss@lists.sourceforge.net
 L:	pcihpd-discuss@lists.sourceforge.net
 S:	Maintained
 S:	Maintained
 
 
+SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
+P:	Stephen Hemminger
+M:	shemminger@osdl.org
+L:	netdev@vger.kernel.org
+S:	Maintained
+
 SPARC (sparc32):
 SPARC (sparc32):
 P:	William L. Irwin
 P:	William L. Irwin
 M:	wli@holomorphy.com
 M:	wli@holomorphy.com

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 14
 SUBLEVEL = 14
-EXTRAVERSION =-rc1
+EXTRAVERSION =-rc2
 NAME=Affluent Albatross
 NAME=Affluent Albatross
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*

+ 6 - 3
README

@@ -149,6 +149,9 @@ CONFIGURING the kernel:
 	"make gconfig"     X windows (Gtk) based configuration tool.
 	"make gconfig"     X windows (Gtk) based configuration tool.
 	"make oldconfig"   Default all questions based on the contents of
 	"make oldconfig"   Default all questions based on the contents of
 			   your existing ./.config file.
 			   your existing ./.config file.
+	"make silentoldconfig"
+			   Like above, but avoids cluttering the screen
+			   with questions already answered.
    
    
 	NOTES on "make config":
 	NOTES on "make config":
 	- having unnecessary drivers will make the kernel bigger, and can
 	- having unnecessary drivers will make the kernel bigger, and can
@@ -169,9 +172,6 @@ CONFIGURING the kernel:
 	  should probably answer 'n' to the questions for
 	  should probably answer 'n' to the questions for
           "development", "experimental", or "debugging" features.
           "development", "experimental", or "debugging" features.
 
 
- - Check the top Makefile for further site-dependent configuration
-   (default SVGA mode etc). 
-
 COMPILING the kernel:
 COMPILING the kernel:
 
 
  - Make sure you have gcc 2.95.3 available.
  - Make sure you have gcc 2.95.3 available.
@@ -199,6 +199,9 @@ COMPILING the kernel:
    are installing a new kernel with the same version number as your
    are installing a new kernel with the same version number as your
    working kernel, make a backup of your modules directory before you
    working kernel, make a backup of your modules directory before you
    do a "make modules_install".
    do a "make modules_install".
+   Alternatively, before compiling, use the kernel config option
+   "LOCALVERSION" to append a unique suffix to the regular kernel version.
+   LOCALVERSION can be set in the "General Setup" menu.
 
 
  - In order to boot your new kernel, you'll need to copy the kernel
  - In order to boot your new kernel, you'll need to copy the kernel
    image (e.g. .../linux/arch/i386/boot/bzImage after compilation)
    image (e.g. .../linux/arch/i386/boot/bzImage after compilation)

+ 4 - 0
arch/alpha/kernel/process.c

@@ -127,6 +127,10 @@ common_shutdown_1(void *generic_ptr)
 	/* If booted from SRM, reset some of the original environment. */
 	/* If booted from SRM, reset some of the original environment. */
 	if (alpha_using_srm) {
 	if (alpha_using_srm) {
 #ifdef CONFIG_DUMMY_CONSOLE
 #ifdef CONFIG_DUMMY_CONSOLE
+		/* If we've gotten here after SysRq-b, leave interrupt
+		   context before taking over the console. */
+		if (in_interrupt())
+			irq_exit();
 		/* This has the effect of resetting the VGA video origin.  */
 		/* This has the effect of resetting the VGA video origin.  */
 		take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
 		take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
 #endif
 #endif

+ 23 - 18
arch/alpha/kernel/sys_dp264.c

@@ -394,6 +394,22 @@ clipper_init_irq(void)
  *  10	 64 bit PCI option slot 3 (not bus 0)
  *  10	 64 bit PCI option slot 3 (not bus 0)
  */
  */
 
 
+static int __init
+isa_irq_fixup(struct pci_dev *dev, int irq)
+{
+	u8 irq8;
+
+	if (irq > 0)
+		return irq;
+
+	/* This interrupt is routed via ISA bridge, so we'll
+	   just have to trust whatever value the console might
+	   have assigned.  */
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
+
+	return irq8 & 0xf;
+}
+
 static int __init
 static int __init
 dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
 {
@@ -407,25 +423,13 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 		{ 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0}  /* IdSel 10 slot 3 */
 		{ 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0}  /* IdSel 10 slot 3 */
 	};
 	};
 	const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
 	const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
-
 	struct pci_controller *hose = dev->sysdata;
 	struct pci_controller *hose = dev->sysdata;
 	int irq = COMMON_TABLE_LOOKUP;
 	int irq = COMMON_TABLE_LOOKUP;
 
 
-	if (irq > 0) {
+	if (irq > 0)
 		irq += 16 * hose->index;
 		irq += 16 * hose->index;
-	} else {
-		/* ??? The Contaq IDE controller on the ISA bridge uses
-		   "legacy" interrupts 14 and 15.  I don't know if anything
-		   can wind up at the same slot+pin on hose1, so we'll
-		   just have to trust whatever value the console might
-		   have assigned.  */
-
-		u8 irq8;
-		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
-		irq = irq8;
-	}
 
 
-	return irq;
+	return isa_irq_fixup(dev, irq);
 }
 }
 
 
 static int __init
 static int __init
@@ -453,7 +457,8 @@ monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 		{    24,    24,    25,    26,    27}  /* IdSel 15 slot 5 PCI2*/
 		{    24,    24,    25,    26,    27}  /* IdSel 15 slot 5 PCI2*/
 	};
 	};
 	const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
 	const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
-	return COMMON_TABLE_LOOKUP;
+
+	return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
 }
 }
 
 
 static u8 __init
 static u8 __init
@@ -507,7 +512,8 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 		{    47,    47,    46,    45,    44}, /* IdSel 17 slot 3 */
 		{    47,    47,    46,    45,    44}, /* IdSel 17 slot 3 */
 	};
 	};
 	const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
 	const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
-	return COMMON_TABLE_LOOKUP;
+
+	return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
 }
 }
 
 
 static int __init
 static int __init
@@ -524,14 +530,13 @@ clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 		{    -1,    -1,    -1,    -1,    -1}  /* IdSel 7 ISA Bridge */
 		{    -1,    -1,    -1,    -1,    -1}  /* IdSel 7 ISA Bridge */
 	};
 	};
 	const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
 	const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
-
 	struct pci_controller *hose = dev->sysdata;
 	struct pci_controller *hose = dev->sysdata;
 	int irq = COMMON_TABLE_LOOKUP;
 	int irq = COMMON_TABLE_LOOKUP;
 
 
 	if (irq > 0)
 	if (irq > 0)
 		irq += 16 * hose->index;
 		irq += 16 * hose->index;
 
 
-	return irq;
+	return isa_irq_fixup(dev, irq);
 }
 }
 
 
 static void __init
 static void __init

+ 1 - 1
arch/arm/boot/compressed/ofw-shark.c

@@ -256,5 +256,5 @@ asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
 	temp[11]='\0';
 	temp[11]='\0';
 	mem_len = OF_getproplen(o,phandle, temp);
 	mem_len = OF_getproplen(o,phandle, temp);
 	OF_getprop(o,phandle, temp, buffer, mem_len);
 	OF_getprop(o,phandle, temp, buffer, mem_len);
-	(unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
+	* ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2];
 }
 }

+ 1 - 1
arch/arm/kernel/entry-armv.S

@@ -537,7 +537,7 @@ ENTRY(__switch_to)
 #ifdef CONFIG_CPU_MPCORE
 #ifdef CONFIG_CPU_MPCORE
 	clrex
 	clrex
 #else
 #else
-	strex	r3, r4, [ip]			@ Clear exclusive monitor
+	strex	r5, r4, [ip]			@ Clear exclusive monitor
 #endif
 #endif
 #endif
 #endif
 #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
 #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)

+ 3 - 3
arch/arm/kernel/io.c

@@ -7,7 +7,7 @@
  * Copy data from IO memory space to "real" memory space.
  * Copy data from IO memory space to "real" memory space.
  * This needs to be optimized.
  * This needs to be optimized.
  */
  */
-void _memcpy_fromio(void *to, void __iomem *from, size_t count)
+void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
 {
 {
 	unsigned char *t = to;
 	unsigned char *t = to;
 	while (count) {
 	while (count) {
@@ -22,7 +22,7 @@ void _memcpy_fromio(void *to, void __iomem *from, size_t count)
  * Copy data from "real" memory space to IO memory space.
  * Copy data from "real" memory space to IO memory space.
  * This needs to be optimized.
  * This needs to be optimized.
  */
  */
-void _memcpy_toio(void __iomem *to, const void *from, size_t count)
+void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
 {
 {
 	const unsigned char *f = from;
 	const unsigned char *f = from;
 	while (count) {
 	while (count) {
@@ -37,7 +37,7 @@ void _memcpy_toio(void __iomem *to, const void *from, size_t count)
  * "memset" on IO memory space.
  * "memset" on IO memory space.
  * This needs to be optimized.
  * This needs to be optimized.
  */
  */
-void _memset_io(void __iomem *dst, int c, size_t count)
+void _memset_io(volatile void __iomem *dst, int c, size_t count)
 {
 {
 	while (count) {
 	while (count) {
 		count--;
 		count--;

+ 1 - 1
arch/arm/kernel/semaphore.c

@@ -178,7 +178,7 @@ int __down_trylock(struct semaphore * sem)
  * registers (r0 to r3 and lr), but not ip, as we use it as a return
  * registers (r0 to r3 and lr), but not ip, as we use it as a return
  * value in some cases..
  * value in some cases..
  */
  */
-asm("	.section .sched.text,\"ax\"		\n\
+asm("	.section .sched.text,\"ax\",%progbits	\n\
 	.align	5				\n\
 	.align	5				\n\
 	.globl	__down_failed			\n\
 	.globl	__down_failed			\n\
 __down_failed:					\n\
 __down_failed:					\n\

+ 3 - 0
arch/arm/kernel/traps.c

@@ -624,6 +624,9 @@ void __attribute__((noreturn)) __bug(const char *file, int line, void *data)
 		printk(" - extra data = %p", data);
 		printk(" - extra data = %p", data);
 	printk("\n");
 	printk("\n");
 	*(int *)0 = 0;
 	*(int *)0 = 0;
+
+	/* Avoid "noreturn function does return" */
+	for (;;);
 }
 }
 EXPORT_SYMBOL(__bug);
 EXPORT_SYMBOL(__bug);
 
 

+ 4 - 4
arch/arm/kernel/vmlinux.lds.S

@@ -23,20 +23,20 @@ SECTIONS
 			*(.init.text)
 			*(.init.text)
 			_einittext = .;
 			_einittext = .;
 		__proc_info_begin = .;
 		__proc_info_begin = .;
-			*(.proc.info)
+			*(.proc.info.init)
 		__proc_info_end = .;
 		__proc_info_end = .;
 		__arch_info_begin = .;
 		__arch_info_begin = .;
-			*(.arch.info)
+			*(.arch.info.init)
 		__arch_info_end = .;
 		__arch_info_end = .;
 		__tagtable_begin = .;
 		__tagtable_begin = .;
-			*(.taglist)
+			*(.taglist.init)
 		__tagtable_end = .;
 		__tagtable_end = .;
 		. = ALIGN(16);
 		. = ALIGN(16);
 		__setup_start = .;
 		__setup_start = .;
 			*(.init.setup)
 			*(.init.setup)
 		__setup_end = .;
 		__setup_end = .;
 		__early_begin = .;
 		__early_begin = .;
-			*(__early_param)
+			*(.early_param.init)
 		__early_end = .;
 		__early_end = .;
 		__initcall_start = .;
 		__initcall_start = .;
 			*(.initcall1.init)
 			*(.initcall1.init)

+ 6 - 0
arch/arm/mach-ixp4xx/ixdp425-setup.c

@@ -123,6 +123,7 @@ static void __init ixdp425_init(void)
 	platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
 	platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
 }
 }
 
 
+#ifdef CONFIG_ARCH_IXDP465
 MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
 MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
 	/* Maintainer: MontaVista Software, Inc. */
 	/* Maintainer: MontaVista Software, Inc. */
 	.phys_ram	= PHYS_OFFSET,
 	.phys_ram	= PHYS_OFFSET,
@@ -134,7 +135,9 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
 	.boot_params	= 0x0100,
 	.boot_params	= 0x0100,
 	.init_machine	= ixdp425_init,
 	.init_machine	= ixdp425_init,
 MACHINE_END
 MACHINE_END
+#endif
 
 
+#ifdef CONFIG_MACH_IXDP465
 MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
 MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
 	/* Maintainer: MontaVista Software, Inc. */
 	/* Maintainer: MontaVista Software, Inc. */
 	.phys_ram	= PHYS_OFFSET,
 	.phys_ram	= PHYS_OFFSET,
@@ -146,7 +149,9 @@ MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
 	.boot_params	= 0x0100,
 	.boot_params	= 0x0100,
 	.init_machine	= ixdp425_init,
 	.init_machine	= ixdp425_init,
 MACHINE_END
 MACHINE_END
+#endif
 
 
+#ifdef CONFIG_ARCH_PRPMC1100
 MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
 MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
 	/* Maintainer: MontaVista Software, Inc. */
 	/* Maintainer: MontaVista Software, Inc. */
 	.phys_ram	= PHYS_OFFSET,
 	.phys_ram	= PHYS_OFFSET,
@@ -158,6 +163,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
 	.boot_params	= 0x0100,
 	.boot_params	= 0x0100,
 	.init_machine	= ixdp425_init,
 	.init_machine	= ixdp425_init,
 MACHINE_END
 MACHINE_END
+#endif
 
 
 /*
 /*
  * Avila is functionally equivalent to IXDP425 except that it adds
  * Avila is functionally equivalent to IXDP425 except that it adds

+ 2 - 1
arch/arm/mach-s3c2410/mach-anubis.c

@@ -12,6 +12,7 @@
  *
  *
  * Modifications:
  * Modifications:
  *	02-May-2005 BJD  Copied from mach-bast.c
  *	02-May-2005 BJD  Copied from mach-bast.c
+ *	20-Sep-2005 BJD  Added static to non-exported items
 */
 */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -232,7 +233,7 @@ static struct s3c24xx_board anubis_board __initdata = {
 	.clocks_count  = ARRAY_SIZE(anubis_clocks)
 	.clocks_count  = ARRAY_SIZE(anubis_clocks)
 };
 };
 
 
-void __init anubis_map_io(void)
+static void __init anubis_map_io(void)
 {
 {
 	/* initialise the clocks */
 	/* initialise the clocks */
 
 

+ 2 - 1
arch/arm/mach-s3c2410/mach-bast.c

@@ -31,6 +31,7 @@
  *     17-Jul-2005 BJD  Changed to platform device for SuperIO 16550s
  *     17-Jul-2005 BJD  Changed to platform device for SuperIO 16550s
  *     25-Jul-2005 BJD  Removed ASIX static mappings
  *     25-Jul-2005 BJD  Removed ASIX static mappings
  *     27-Jul-2005 BJD  Ensure maximum frequency of i2c bus
  *     27-Jul-2005 BJD  Ensure maximum frequency of i2c bus
+ *     20-Sep-2005 BJD  Added static to non-exported items
 */
 */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -428,7 +429,7 @@ static struct s3c24xx_board bast_board __initdata = {
 	.clocks_count  = ARRAY_SIZE(bast_clocks)
 	.clocks_count  = ARRAY_SIZE(bast_clocks)
 };
 };
 
 
-void __init bast_map_io(void)
+static void __init bast_map_io(void)
 {
 {
 	/* initialise the clocks */
 	/* initialise the clocks */
 
 

+ 4 - 3
arch/arm/mach-s3c2410/mach-h1940.c

@@ -24,6 +24,7 @@
  *     10-Jan-2005 BJD  Removed include of s3c2410.h
  *     10-Jan-2005 BJD  Removed include of s3c2410.h
  *     14-Jan-2005 BJD  Added clock init
  *     14-Jan-2005 BJD  Added clock init
  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
+ *     20-Sep-2005 BJD  Added static to non-exported items
 */
 */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -147,7 +148,7 @@ static struct s3c24xx_board h1940_board __initdata = {
 	.devices_count = ARRAY_SIZE(h1940_devices)
 	.devices_count = ARRAY_SIZE(h1940_devices)
 };
 };
 
 
-void __init h1940_map_io(void)
+static void __init h1940_map_io(void)
 {
 {
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
@@ -155,13 +156,13 @@ void __init h1940_map_io(void)
 	s3c24xx_set_board(&h1940_board);
 	s3c24xx_set_board(&h1940_board);
 }
 }
 
 
-void __init h1940_init_irq(void)
+static void __init h1940_init_irq(void)
 {
 {
 	s3c24xx_init_irq();
 	s3c24xx_init_irq();
 
 
 }
 }
 
 
-void __init h1940_init(void)
+static void __init h1940_init(void)
 {
 {
 	set_s3c2410fb_info(&h1940_lcdcfg);
 	set_s3c2410fb_info(&h1940_lcdcfg);
 }
 }

+ 3 - 3
arch/arm/mach-s3c2410/mach-n30.c

@@ -97,7 +97,7 @@ static struct s3c24xx_board n30_board __initdata = {
 	.devices_count = ARRAY_SIZE(n30_devices)
 	.devices_count = ARRAY_SIZE(n30_devices)
 };
 };
 
 
-void __init n30_map_io(void)
+static void __init n30_map_io(void)
 {
 {
 	s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
 	s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
@@ -105,14 +105,14 @@ void __init n30_map_io(void)
 	s3c24xx_set_board(&n30_board);
 	s3c24xx_set_board(&n30_board);
 }
 }
 
 
-void __init n30_init_irq(void)
+static void __init n30_init_irq(void)
 {
 {
 	s3c24xx_init_irq();
 	s3c24xx_init_irq();
 }
 }
 
 
 /* GPB3 is the line that controls the pull-up for the USB D+ line */
 /* GPB3 is the line that controls the pull-up for the USB D+ line */
 
 
-void __init n30_init(void)
+static void __init n30_init(void)
 {
 {
 	s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
 	s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
 
 

+ 1 - 1
arch/arm/mach-s3c2410/mach-nexcoder.c

@@ -136,7 +136,7 @@ static void __init nexcoder_sensorboard_init(void)
 	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN
 	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN
 }
 }
 
 
-void __init nexcoder_map_io(void)
+static void __init nexcoder_map_io(void)
 {
 {
 	s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
 	s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);

+ 1 - 1
arch/arm/mach-s3c2410/mach-otom.c

@@ -105,7 +105,7 @@ static struct s3c24xx_board otom11_board __initdata = {
 };
 };
 
 
 
 
-void __init otom11_map_io(void)
+static void __init otom11_map_io(void)
 {
 {
 	s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
 	s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);

+ 3 - 2
arch/arm/mach-s3c2410/mach-rx3715.c

@@ -16,6 +16,7 @@
  *	14-Jan-2005 BJD  Added new clock init
  *	14-Jan-2005 BJD  Added new clock init
  *	10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
  *	10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
  *	14-Mar-2005 BJD  Fixed __iomem warnings
  *	14-Mar-2005 BJD  Fixed __iomem warnings
+ *	20-Sep-2005 BJD  Added static to non-exported items
 */
 */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -108,7 +109,7 @@ static struct s3c24xx_board rx3715_board __initdata = {
 	.devices_count = ARRAY_SIZE(rx3715_devices)
 	.devices_count = ARRAY_SIZE(rx3715_devices)
 };
 };
 
 
-void __init rx3715_map_io(void)
+static void __init rx3715_map_io(void)
 {
 {
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
 	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_clocks(16934000);
@@ -116,7 +117,7 @@ void __init rx3715_map_io(void)
 	s3c24xx_set_board(&rx3715_board);
 	s3c24xx_set_board(&rx3715_board);
 }
 }
 
 
-void __init rx3715_init_irq(void)
+static void __init rx3715_init_irq(void)
 {
 {
 	s3c24xx_init_irq();
 	s3c24xx_init_irq();
 }
 }

+ 3 - 2
arch/arm/mach-s3c2410/mach-smdk2410.c

@@ -28,6 +28,7 @@
  * Ben Dooks <ben@simtec.co.uk>
  * Ben Dooks <ben@simtec.co.uk>
  *
  *
  * 10-Mar-2005 LCVR  Changed S3C2410_VA to S3C24XX_VA
  * 10-Mar-2005 LCVR  Changed S3C2410_VA to S3C24XX_VA
+ * 20-Sep-2005 BJD  Added static to non-exported items
  *
  *
  ***********************************************************************/
  ***********************************************************************/
 
 
@@ -97,7 +98,7 @@ static struct s3c24xx_board smdk2410_board __initdata = {
 	.devices_count = ARRAY_SIZE(smdk2410_devices)
 	.devices_count = ARRAY_SIZE(smdk2410_devices)
 };
 };
 
 
-void __init smdk2410_map_io(void)
+static void __init smdk2410_map_io(void)
 {
 {
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
@@ -105,7 +106,7 @@ void __init smdk2410_map_io(void)
 	s3c24xx_set_board(&smdk2410_board);
 	s3c24xx_set_board(&smdk2410_board);
 }
 }
 
 
-void __init smdk2410_init_irq(void)
+static void __init smdk2410_init_irq(void)
 {
 {
 	s3c24xx_init_irq();
 	s3c24xx_init_irq();
 }
 }

+ 3 - 2
arch/arm/mach-s3c2410/mach-smdk2440.c

@@ -18,6 +18,7 @@
  *	22-Feb-2005 BJD   Updated for 2.6.11-rc5 relesa
  *	22-Feb-2005 BJD   Updated for 2.6.11-rc5 relesa
  *	10-Mar-2005 LCVR  Replaced S3C2410_VA by S3C24XX_VA
  *	10-Mar-2005 LCVR  Replaced S3C2410_VA by S3C24XX_VA
  *	14-Mar-2005 BJD	  void __iomem fixes
  *	14-Mar-2005 BJD	  void __iomem fixes
+ *	20-Sep-2005 BJD   Added static to non-exported items
 */
 */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -98,7 +99,7 @@ static struct s3c24xx_board smdk2440_board __initdata = {
 	.devices_count = ARRAY_SIZE(smdk2440_devices)
 	.devices_count = ARRAY_SIZE(smdk2440_devices)
 };
 };
 
 
-void __init smdk2440_map_io(void)
+static void __init smdk2440_map_io(void)
 {
 {
 	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
 	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
 	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_clocks(16934400);
@@ -106,7 +107,7 @@ void __init smdk2440_map_io(void)
 	s3c24xx_set_board(&smdk2440_board);
 	s3c24xx_set_board(&smdk2440_board);
 }
 }
 
 
-void __init smdk2440_machine_init(void)
+static void __init smdk2440_machine_init(void)
 {
 {
 	/* Configure the LEDs (even if we have no LED support)*/
 	/* Configure the LEDs (even if we have no LED support)*/
 
 

+ 2 - 1
arch/arm/mach-s3c2410/mach-vr1000.c

@@ -28,6 +28,7 @@
  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
  *     14-Mar-2006 BJD  void __iomem fixes
  *     14-Mar-2006 BJD  void __iomem fixes
  *     22-Jun-2006 BJD  Added DM9000 platform information
  *     22-Jun-2006 BJD  Added DM9000 platform information
+ *     20-Sep-2005 BJD  Added static to non-exported items
 */
 */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -347,7 +348,7 @@ static void vr1000_power_off(void)
 	s3c2410_gpio_setpin(S3C2410_GPB9, 1);
 	s3c2410_gpio_setpin(S3C2410_GPB9, 1);
 }
 }
 
 
-void __init vr1000_map_io(void)
+static void __init vr1000_map_io(void)
 {
 {
 	/* initialise clock sources */
 	/* initialise clock sources */
 
 

+ 3 - 0
arch/arm/mach-sa1100/generic.h

@@ -39,3 +39,6 @@ extern void sa11x0_set_ssp_data(struct sa11x0_ssp_plat_ops *ops);
 
 
 struct irda_platform_data;
 struct irda_platform_data;
 void sa11x0_set_irda_data(struct irda_platform_data *irda);
 void sa11x0_set_irda_data(struct irda_platform_data *irda);
+
+struct mcp_plat_data;
+void sa11x0_set_mcp_data(struct mcp_plat_data *data);

+ 11 - 1
arch/arm/mm/fault.c

@@ -233,7 +233,17 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	if (in_interrupt() || !mm)
 	if (in_interrupt() || !mm)
 		goto no_context;
 		goto no_context;
 
 
-	down_read(&mm->mmap_sem);
+	/*
+	 * As per x86, we may deadlock here.  However, since the kernel only
+	 * validly references user space from well defined areas of the code,
+	 * we can bug out early if this is from code which shouldn't.
+	 */
+	if (!down_read_trylock(&mm->mmap_sem)) {
+		if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
+			goto no_context;
+		down_read(&mm->mmap_sem);
+	}
+
 	fault = __do_page_fault(mm, addr, fsr, tsk);
 	fault = __do_page_fault(mm, addr, fsr, tsk);
 	up_read(&mm->mmap_sem);
 	up_read(&mm->mmap_sem);
 
 

+ 1 - 1
arch/arm/mm/proc-arm1020.S

@@ -509,7 +509,7 @@ cpu_arm1020_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm1020_proc_info,#object
 	.type	__arm1020_proc_info,#object
 __arm1020_proc_info:
 __arm1020_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm1020e.S

@@ -491,7 +491,7 @@ cpu_arm1020e_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm1020e_proc_info,#object
 	.type	__arm1020e_proc_info,#object
 __arm1020e_proc_info:
 __arm1020e_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm1022.S

@@ -473,7 +473,7 @@ cpu_arm1022_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm1022_proc_info,#object
 	.type	__arm1022_proc_info,#object
 __arm1022_proc_info:
 __arm1022_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm1026.S

@@ -469,7 +469,7 @@ cpu_arm1026_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm1026_proc_info,#object
 	.type	__arm1026_proc_info,#object
 __arm1026_proc_info:
 __arm1026_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm6_7.S

@@ -332,7 +332,7 @@ cpu_arm710_name:
 
 
 		.align
 		.align
 
 
-		.section ".proc.info", #alloc, #execinstr
+		.section ".proc.info.init", #alloc, #execinstr
 
 
 		.type	__arm6_proc_info, #object
 		.type	__arm6_proc_info, #object
 __arm6_proc_info:
 __arm6_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm720.S

@@ -222,7 +222,7 @@ cpu_arm720_name:
  * See linux/include/asm-arm/procinfo.h for a definition of this structure.
  * See linux/include/asm-arm/procinfo.h for a definition of this structure.
  */
  */
 	
 	
-		.section ".proc.info", #alloc, #execinstr
+		.section ".proc.info.init", #alloc, #execinstr
 
 
 		.type	__arm710_proc_info, #object
 		.type	__arm710_proc_info, #object
 __arm710_proc_info:
 __arm710_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm920.S

@@ -452,7 +452,7 @@ cpu_arm920_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm920_proc_info,#object
 	.type	__arm920_proc_info,#object
 __arm920_proc_info:
 __arm920_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm922.S

@@ -456,7 +456,7 @@ cpu_arm922_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm922_proc_info,#object
 	.type	__arm922_proc_info,#object
 __arm922_proc_info:
 __arm922_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm925.S

@@ -521,7 +521,7 @@ cpu_arm925_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm925_proc_info,#object
 	.type	__arm925_proc_info,#object
 __arm925_proc_info:
 __arm925_proc_info:

+ 1 - 1
arch/arm/mm/proc-arm926.S

@@ -471,7 +471,7 @@ cpu_arm926_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__arm926_proc_info,#object
 	.type	__arm926_proc_info,#object
 __arm926_proc_info:
 __arm926_proc_info:

+ 1 - 1
arch/arm/mm/proc-sa110.S

@@ -249,7 +249,7 @@ cpu_sa110_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__sa110_proc_info,#object
 	.type	__sa110_proc_info,#object
 __sa110_proc_info:
 __sa110_proc_info:

+ 1 - 1
arch/arm/mm/proc-sa1100.S

@@ -280,7 +280,7 @@ cpu_sa1110_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__sa1100_proc_info,#object
 	.type	__sa1100_proc_info,#object
 __sa1100_proc_info:
 __sa1100_proc_info:

+ 1 - 1
arch/arm/mm/proc-v6.S

@@ -240,7 +240,7 @@ cpu_elf_name:
 	.size	cpu_elf_name, . - cpu_elf_name
 	.size	cpu_elf_name, . - cpu_elf_name
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	/*
 	/*
 	 * Match any ARMv6 processor core.
 	 * Match any ARMv6 processor core.

+ 1 - 1
arch/arm/mm/proc-xscale.S

@@ -578,7 +578,7 @@ cpu_pxa270_name:
 
 
 	.align
 	.align
 
 
-	.section ".proc.info", #alloc, #execinstr
+	.section ".proc.info.init", #alloc, #execinstr
 
 
 	.type	__80200_proc_info,#object
 	.type	__80200_proc_info,#object
 __80200_proc_info:
 __80200_proc_info:

+ 23 - 6
arch/ia64/hp/sim/simscsi.c

@@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
 		simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
 		simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
 }
 }
 
 
+static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
+{
+
+	int scatterlen = sc->use_sg;
+	struct scatterlist *slp;
+
+	if (scatterlen == 0)
+		memcpy(sc->request_buffer, buf, len);
+	else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) {
+		unsigned thislen = min(len, slp->length);
+
+		memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+		slp++;
+		len -= thislen;
+	}
+}
+
 static int
 static int
 simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
 {
@@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 	char fname[MAX_ROOT_LEN+16];
 	char fname[MAX_ROOT_LEN+16];
 	size_t disk_size;
 	size_t disk_size;
 	char *buf;
 	char *buf;
+	char localbuf[36];
 #if DEBUG_SIMSCSI
 #if DEBUG_SIMSCSI
 	register long sp asm ("sp");
 	register long sp asm ("sp");
 
 
@@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 				/* disk doesn't exist... */
 				/* disk doesn't exist... */
 				break;
 				break;
 			}
 			}
-			buf = sc->request_buffer;
+			buf = localbuf;
 			buf[0] = 0;	/* magnetic disk */
 			buf[0] = 0;	/* magnetic disk */
 			buf[1] = 0;	/* not a removable medium */
 			buf[1] = 0;	/* not a removable medium */
 			buf[2] = 2;	/* SCSI-2 compliant device */
 			buf[2] = 2;	/* SCSI-2 compliant device */
@@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 			buf[6] = 0;	/* reserved */
 			buf[6] = 0;	/* reserved */
 			buf[7] = 0;	/* various flags */
 			buf[7] = 0;	/* various flags */
 			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
 			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
+			simscsi_fillresult(sc, buf, 36);
 			sc->result = GOOD;
 			sc->result = GOOD;
 			break;
 			break;
 
 
@@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 			simscsi_readwrite10(sc, SSC_WRITE);
 			simscsi_readwrite10(sc, SSC_WRITE);
 			break;
 			break;
 
 
-
 		      case READ_CAPACITY:
 		      case READ_CAPACITY:
 			if (desc[target_id] < 0 || sc->request_bufflen < 8) {
 			if (desc[target_id] < 0 || sc->request_bufflen < 8) {
 				break;
 				break;
 			}
 			}
-			buf = sc->request_buffer;
-
+			buf = localbuf;
 			disk_size = simscsi_get_disk_size(desc[target_id]);
 			disk_size = simscsi_get_disk_size(desc[target_id]);
 
 
-			/* pretend to be a 1GB disk (partition table contains real stuff): */
 			buf[0] = (disk_size >> 24) & 0xff;
 			buf[0] = (disk_size >> 24) & 0xff;
 			buf[1] = (disk_size >> 16) & 0xff;
 			buf[1] = (disk_size >> 16) & 0xff;
 			buf[2] = (disk_size >>  8) & 0xff;
 			buf[2] = (disk_size >>  8) & 0xff;
@@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 			buf[5] = 0;
 			buf[5] = 0;
 			buf[6] = 2;
 			buf[6] = 2;
 			buf[7] = 0;
 			buf[7] = 0;
+			simscsi_fillresult(sc, buf, 8);
 			sc->result = GOOD;
 			sc->result = GOOD;
 			break;
 			break;
 
 
 		      case MODE_SENSE:
 		      case MODE_SENSE:
 		      case MODE_SENSE_10:
 		      case MODE_SENSE_10:
 			/* sd.c uses this to determine whether disk does write-caching. */
 			/* sd.c uses this to determine whether disk does write-caching. */
-			memset(sc->request_buffer, 0, 128);
+			simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen);
 			sc->result = GOOD;
 			sc->result = GOOD;
 			break;
 			break;
 
 

+ 85 - 11
arch/ia64/kernel/mca_asm.S

@@ -489,24 +489,27 @@ ia64_state_save:
 	;;
 	;;
 	st8 [temp1]=r17,16	// pal_min_state
 	st8 [temp1]=r17,16	// pal_min_state
 	st8 [temp2]=r6,16	// prev_IA64_KR_CURRENT
 	st8 [temp2]=r6,16	// prev_IA64_KR_CURRENT
+	mov r6=IA64_KR(CURRENT_STACK)
+	;;
+	st8 [temp1]=r6,16	// prev_IA64_KR_CURRENT_STACK
+	st8 [temp2]=r0,16	// prev_task, starts off as NULL
 	mov r6=cr.ifa
 	mov r6=cr.ifa
 	;;
 	;;
-	st8 [temp1]=r0,16	// prev_task, starts off as NULL
-	st8 [temp2]=r12,16	// cr.isr
+	st8 [temp1]=r12,16	// cr.isr
+	st8 [temp2]=r6,16	// cr.ifa
 	mov r12=cr.itir
 	mov r12=cr.itir
 	;;
 	;;
-	st8 [temp1]=r6,16	// cr.ifa
-	st8 [temp2]=r12,16	// cr.itir
+	st8 [temp1]=r12,16	// cr.itir
+	st8 [temp2]=r11,16	// cr.iipa
 	mov r12=cr.iim
 	mov r12=cr.iim
 	;;
 	;;
-	st8 [temp1]=r11,16	// cr.iipa
-	st8 [temp2]=r12,16	// cr.iim
-	mov r6=cr.iha
+	st8 [temp1]=r12,16	// cr.iim
 (p1)	mov r12=IA64_MCA_COLD_BOOT
 (p1)	mov r12=IA64_MCA_COLD_BOOT
 (p2)	mov r12=IA64_INIT_WARM_BOOT
 (p2)	mov r12=IA64_INIT_WARM_BOOT
+	mov r6=cr.iha
 	;;
 	;;
-	st8 [temp1]=r6,16	// cr.iha
-	st8 [temp2]=r12		// os_status, default is cold boot
+	st8 [temp2]=r6,16	// cr.iha
+	st8 [temp1]=r12		// os_status, default is cold boot
 	mov r6=IA64_MCA_SAME_CONTEXT
 	mov r6=IA64_MCA_SAME_CONTEXT
 	;;
 	;;
 	st8 [temp1]=r6		// context, default is same context
 	st8 [temp1]=r6		// context, default is same context
@@ -823,9 +826,12 @@ ia64_state_restore:
 	ld8 r12=[temp1],16	// sal_ra
 	ld8 r12=[temp1],16	// sal_ra
 	ld8 r9=[temp2],16	// sal_gp
 	ld8 r9=[temp2],16	// sal_gp
 	;;
 	;;
-	ld8 r22=[temp1],24	// pal_min_state, virtual.  skip prev_task
+	ld8 r22=[temp1],16	// pal_min_state, virtual
 	ld8 r21=[temp2],16	// prev_IA64_KR_CURRENT
 	ld8 r21=[temp2],16	// prev_IA64_KR_CURRENT
 	;;
 	;;
+	ld8 r16=[temp1],16	// prev_IA64_KR_CURRENT_STACK
+	ld8 r20=[temp2],16	// prev_task
+	;;
 	ld8 temp3=[temp1],16	// cr.isr
 	ld8 temp3=[temp1],16	// cr.isr
 	ld8 temp4=[temp2],16	// cr.ifa
 	ld8 temp4=[temp2],16	// cr.ifa
 	;;
 	;;
@@ -846,6 +852,45 @@ ia64_state_restore:
 	ld8 r8=[temp1]		// os_status
 	ld8 r8=[temp1]		// os_status
 	ld8 r10=[temp2]		// context
 	ld8 r10=[temp2]		// context
 
 
+	/* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to.  To
+	 * avoid any dependencies on the algorithm in ia64_switch_to(), just
+	 * purge any existing CURRENT_STACK mapping and insert the new one.
+	 *
+	 * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains
+	 * prev_IA64_KR_CURRENT, these values may have been changed by the C
+	 * code.  Do not use r8, r9, r10, r22, they contain values ready for
+	 * the return to SAL.
+	 */
+
+	mov r15=IA64_KR(CURRENT_STACK)		// physical granule mapped by IA64_TR_CURRENT_STACK
+	;;
+	shl r15=r15,IA64_GRANULE_SHIFT
+	;;
+	dep r15=-1,r15,61,3			// virtual granule
+	mov r18=IA64_GRANULE_SHIFT<<2		// for cr.itir.ps
+	;;
+	ptr.d r15,r18
+	;;
+	srlz.d
+
+	extr.u r19=r21,61,3			// r21 = prev_IA64_KR_CURRENT
+	shl r20=r16,IA64_GRANULE_SHIFT		// r16 = prev_IA64_KR_CURRENT_STACK
+	movl r21=PAGE_KERNEL			// page properties
+	;;
+	mov IA64_KR(CURRENT_STACK)=r16
+	cmp.ne p6,p0=RGN_KERNEL,r19		// new stack is in the kernel region?
+	or r21=r20,r21				// construct PA | page properties
+(p6)	br.spnt 1f				// the dreaded cpu 0 idle task in region 5:(
+	;;
+	mov cr.itir=r18
+	mov cr.ifa=r21
+	mov r20=IA64_TR_CURRENT_STACK
+	;;
+	itr.d dtr[r20]=r21
+	;;
+	srlz.d
+1:
+
 	br.sptk b0
 	br.sptk b0
 
 
 //EndStub//////////////////////////////////////////////////////////////////////
 //EndStub//////////////////////////////////////////////////////////////////////
@@ -982,6 +1027,7 @@ ia64_set_kernel_registers:
 	add temp4=temp4, temp1	// &struct ia64_sal_os_state.os_gp
 	add temp4=temp4, temp1	// &struct ia64_sal_os_state.os_gp
 	add r12=temp1, temp3	// kernel stack pointer on MCA/INIT stack
 	add r12=temp1, temp3	// kernel stack pointer on MCA/INIT stack
 	add r13=temp1, r3	// set current to start of MCA/INIT stack
 	add r13=temp1, r3	// set current to start of MCA/INIT stack
+	add r20=temp1, r3	// physical start of MCA/INIT stack
 	;;
 	;;
 	ld8 r1=[temp4]		// OS GP from SAL OS state
 	ld8 r1=[temp4]		// OS GP from SAL OS state
 	;;
 	;;
@@ -991,7 +1037,35 @@ ia64_set_kernel_registers:
 	;;
 	;;
 	mov IA64_KR(CURRENT)=r13
 	mov IA64_KR(CURRENT)=r13
 
 
-	// FIXME: do I need to wire IA64_KR_CURRENT_STACK and IA64_TR_CURRENT_STACK?
+	/* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack.  To avoid
+	 * any dependencies on the algorithm in ia64_switch_to(), just purge
+	 * any existing CURRENT_STACK mapping and insert the new one.
+	 */
+
+	mov r16=IA64_KR(CURRENT_STACK)		// physical granule mapped by IA64_TR_CURRENT_STACK
+	;;
+	shl r16=r16,IA64_GRANULE_SHIFT
+	;;
+	dep r16=-1,r16,61,3			// virtual granule
+	mov r18=IA64_GRANULE_SHIFT<<2		// for cr.itir.ps
+	;;
+	ptr.d r16,r18
+	;;
+	srlz.d
+
+	shr.u r16=r20,IA64_GRANULE_SHIFT	// r20 = physical start of MCA/INIT stack
+	movl r21=PAGE_KERNEL			// page properties
+	;;
+	mov IA64_KR(CURRENT_STACK)=r16
+	or r21=r20,r21				// construct PA | page properties
+	;;
+	mov cr.itir=r18
+	mov cr.ifa=r13
+	mov r20=IA64_TR_CURRENT_STACK
+	;;
+	itr.d dtr[r20]=r21
+	;;
+	srlz.d
 
 
 	br.sptk b0
 	br.sptk b0
 
 

+ 15 - 6
arch/ia64/kernel/mca_drv.c

@@ -56,8 +56,9 @@ static struct page *page_isolate[MAX_PAGE_ISOLATE];
 static int num_page_isolate = 0;
 static int num_page_isolate = 0;
 
 
 typedef enum {
 typedef enum {
-	ISOLATE_NG = 0,
-	ISOLATE_OK = 1
+	ISOLATE_NG,
+	ISOLATE_OK,
+	ISOLATE_NONE
 } isolate_status_t;
 } isolate_status_t;
 
 
 /*
 /*
@@ -74,7 +75,7 @@ static struct {
  * @paddr:	poisoned memory location
  * @paddr:	poisoned memory location
  *
  *
  * Return value:
  * Return value:
- *	ISOLATE_OK / ISOLATE_NG
+ *	one of isolate_status_t, ISOLATE_OK/NG/NONE.
  */
  */
 
 
 static isolate_status_t
 static isolate_status_t
@@ -85,7 +86,10 @@ mca_page_isolate(unsigned long paddr)
 
 
 	/* whether physical address is valid or not */
 	/* whether physical address is valid or not */
 	if (!ia64_phys_addr_valid(paddr))
 	if (!ia64_phys_addr_valid(paddr))
-		return ISOLATE_NG;
+		return ISOLATE_NONE;
+
+	if (!pfn_valid(paddr))
+		return ISOLATE_NONE;
 
 
 	/* convert physical address to physical page number */
 	/* convert physical address to physical page number */
 	p = pfn_to_page(paddr>>PAGE_SHIFT);
 	p = pfn_to_page(paddr>>PAGE_SHIFT);
@@ -122,10 +126,15 @@ mca_handler_bh(unsigned long paddr)
 		current->pid, current->comm);
 		current->pid, current->comm);
 
 
 	spin_lock(&mca_bh_lock);
 	spin_lock(&mca_bh_lock);
-	if (mca_page_isolate(paddr) == ISOLATE_OK) {
+	switch (mca_page_isolate(paddr)) {
+	case ISOLATE_OK:
 		printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr);
 		printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr);
-	} else {
+		break;
+	case ISOLATE_NG:
 		printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr);
 		printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr);
+		break;
+	default:
+		break;
 	}
 	}
 	spin_unlock(&mca_bh_lock);
 	spin_unlock(&mca_bh_lock);
 
 

+ 1 - 2
arch/ppc/kernel/Makefile

@@ -15,9 +15,8 @@ extra-y				+= vmlinux.lds
 obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
 obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
 					process.o signal.o ptrace.o align.o \
 					process.o signal.o ptrace.o align.o \
 					semaphore.o syscalls.o setup.o \
 					semaphore.o syscalls.o setup.o \
-					cputable.o ppc_htab.o
+					cputable.o ppc_htab.o perfmon.o
 obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
 obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
-obj-$(CONFIG_E500)		+= perfmon.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o
 obj-$(CONFIG_POWER4)		+= cpu_setup_power4.o
 obj-$(CONFIG_POWER4)		+= cpu_setup_power4.o
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o

+ 5 - 1
arch/ppc/kernel/perfmon.c

@@ -45,7 +45,7 @@ static void dummy_perf(struct pt_regs *regs)
 	mtpmr(PMRN_PMGC0, pmgc0);
 	mtpmr(PMRN_PMGC0, pmgc0);
 }
 }
 
 
-#else
+#elif CONFIG_6xx
 /* Ensure exceptions are disabled */
 /* Ensure exceptions are disabled */
 
 
 static void dummy_perf(struct pt_regs *regs)
 static void dummy_perf(struct pt_regs *regs)
@@ -55,6 +55,10 @@ static void dummy_perf(struct pt_regs *regs)
 	mmcr0 &= ~MMCR0_PMXE;
 	mmcr0 &= ~MMCR0_PMXE;
 	mtspr(SPRN_MMCR0, mmcr0);
 	mtspr(SPRN_MMCR0, mmcr0);
 }
 }
+#else
+static void dummy_perf(struct pt_regs *regs)
+{
+}
 #endif
 #endif
 
 
 void (*perf_irq)(struct pt_regs *) = dummy_perf;
 void (*perf_irq)(struct pt_regs *) = dummy_perf;

+ 6 - 4
arch/ppc/platforms/pmac_setup.c

@@ -719,7 +719,8 @@ pmac_declare_of_platform_devices(void)
 	if (np) {
 	if (np) {
 		for (np = np->child; np != NULL; np = np->sibling)
 		for (np = np->child; np != NULL; np = np->sibling)
 			if (strncmp(np->name, "i2c", 3) == 0) {
 			if (strncmp(np->name, "i2c", 3) == 0) {
-				of_platform_device_create(np, "uni-n-i2c");
+				of_platform_device_create(np, "uni-n-i2c",
+							  NULL);
 				break;
 				break;
 			}
 			}
 	}
 	}
@@ -727,17 +728,18 @@ pmac_declare_of_platform_devices(void)
 	if (np) {
 	if (np) {
 		for (np = np->child; np != NULL; np = np->sibling)
 		for (np = np->child; np != NULL; np = np->sibling)
 			if (strncmp(np->name, "i2c", 3) == 0) {
 			if (strncmp(np->name, "i2c", 3) == 0) {
-				of_platform_device_create(np, "u3-i2c");
+				of_platform_device_create(np, "u3-i2c",
+							  NULL);
 				break;
 				break;
 			}
 			}
 	}
 	}
 
 
 	np = find_devices("valkyrie");
 	np = find_devices("valkyrie");
 	if (np)
 	if (np)
-		of_platform_device_create(np, "valkyrie");
+		of_platform_device_create(np, "valkyrie", NULL);
 	np = find_devices("platinum");
 	np = find_devices("platinum");
 	if (np)
 	if (np)
-		of_platform_device_create(np, "platinum");
+		of_platform_device_create(np, "platinum", NULL);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 2
arch/ppc/syslib/of_device.c

@@ -234,7 +234,9 @@ void of_device_unregister(struct of_device *ofdev)
 	device_unregister(&ofdev->dev);
 	device_unregister(&ofdev->dev);
 }
 }
 
 
-struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id)
+struct of_device* of_platform_device_create(struct device_node *np,
+					    const char *bus_id,
+					    struct device *parent)
 {
 {
 	struct of_device *dev;
 	struct of_device *dev;
 	u32 *reg;
 	u32 *reg;
@@ -247,7 +249,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
 	dev->node = of_node_get(np);
 	dev->node = of_node_get(np);
 	dev->dma_mask = 0xffffffffUL;
 	dev->dma_mask = 0xffffffffUL;
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_mask = &dev->dma_mask;
-	dev->dev.parent = NULL;
+	dev->dev.parent = parent;
 	dev->dev.bus = &of_platform_bus_type;
 	dev->dev.bus = &of_platform_bus_type;
 	dev->dev.release = of_release_dev;
 	dev->dev.release = of_release_dev;
 
 

+ 4 - 4
arch/ppc/syslib/ppc85xx_setup.c

@@ -184,8 +184,8 @@ mpc85xx_setup_pci1(struct pci_controller *hose)
 	pci->powar1 = 0x80044000 |
 	pci->powar1 = 0x80044000 |
 	   (__ilog2(MPC85XX_PCI1_UPPER_MEM - MPC85XX_PCI1_LOWER_MEM + 1) - 1);
 	   (__ilog2(MPC85XX_PCI1_UPPER_MEM - MPC85XX_PCI1_LOWER_MEM + 1) - 1);
 
 
-	/* Setup outboud IO windows @ MPC85XX_PCI1_IO_BASE */
-	pci->potar2 = 0x00000000;
+	/* Setup outbound IO windows @ MPC85XX_PCI1_IO_BASE */
+	pci->potar2 = (MPC85XX_PCI1_LOWER_IO >> 12) & 0x000fffff;
 	pci->potear2 = 0x00000000;
 	pci->potear2 = 0x00000000;
 	pci->powbar2 = (MPC85XX_PCI1_IO_BASE >> 12) & 0x000fffff;
 	pci->powbar2 = (MPC85XX_PCI1_IO_BASE >> 12) & 0x000fffff;
 	/* Enable, IO R/W */
 	/* Enable, IO R/W */
@@ -235,8 +235,8 @@ mpc85xx_setup_pci2(struct pci_controller *hose)
 	pci->powar1 = 0x80044000 |
 	pci->powar1 = 0x80044000 |
 	   (__ilog2(MPC85XX_PCI2_UPPER_MEM - MPC85XX_PCI2_LOWER_MEM + 1) - 1);
 	   (__ilog2(MPC85XX_PCI2_UPPER_MEM - MPC85XX_PCI2_LOWER_MEM + 1) - 1);
 
 
-	/* Setup outboud IO windows @ MPC85XX_PCI2_IO_BASE */
-	pci->potar2 = 0x00000000;
+	/* Setup outbound IO windows @ MPC85XX_PCI2_IO_BASE */
+	pci->potar2 = (MPC85XX_PCI2_LOWER_IO >> 12) & 0x000fffff;;
 	pci->potear2 = 0x00000000;
 	pci->potear2 = 0x00000000;
 	pci->powbar2 = (MPC85XX_PCI2_IO_BASE >> 12) & 0x000fffff;
 	pci->powbar2 = (MPC85XX_PCI2_IO_BASE >> 12) & 0x000fffff;
 	/* Enable, IO R/W */
 	/* Enable, IO R/W */

+ 1 - 1
arch/ppc64/Makefile

@@ -107,7 +107,7 @@ install: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
 
 
 defaultimage-$(CONFIG_PPC_PSERIES) := zImage
 defaultimage-$(CONFIG_PPC_PSERIES) := zImage
-defaultimage-$(CONFIG_PPC_PMAC) := vmlinux
+defaultimage-$(CONFIG_PPC_PMAC) := zImage.vmode
 defaultimage-$(CONFIG_PPC_MAPLE) := zImage
 defaultimage-$(CONFIG_PPC_MAPLE) := zImage
 defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
 defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
 KBUILD_IMAGE := $(defaultimage-y)
 KBUILD_IMAGE := $(defaultimage-y)

+ 5 - 2
arch/ppc64/kernel/of_device.c

@@ -233,7 +233,9 @@ void of_device_unregister(struct of_device *ofdev)
 	device_unregister(&ofdev->dev);
 	device_unregister(&ofdev->dev);
 }
 }
 
 
-struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id)
+struct of_device* of_platform_device_create(struct device_node *np,
+					    const char *bus_id,
+					    struct device *parent)
 {
 {
 	struct of_device *dev;
 	struct of_device *dev;
 
 
@@ -245,7 +247,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
 	dev->node = np;
 	dev->node = np;
 	dev->dma_mask = 0xffffffffUL;
 	dev->dma_mask = 0xffffffffUL;
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_mask = &dev->dma_mask;
-	dev->dev.parent = NULL;
+	dev->dev.parent = parent;
 	dev->dev.bus = &of_platform_bus_type;
 	dev->dev.bus = &of_platform_bus_type;
 	dev->dev.release = of_release_dev;
 	dev->dev.release = of_release_dev;
 
 
@@ -259,6 +261,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
 	return dev;
 	return dev;
 }
 }
 
 
+
 EXPORT_SYMBOL(of_match_device);
 EXPORT_SYMBOL(of_match_device);
 EXPORT_SYMBOL(of_platform_bus_type);
 EXPORT_SYMBOL(of_platform_bus_type);
 EXPORT_SYMBOL(of_register_driver);
 EXPORT_SYMBOL(of_register_driver);

+ 95 - 86
arch/ppc64/kernel/pSeries_iommu.c

@@ -281,8 +281,10 @@ static void iommu_table_setparms(struct pci_controller *phb,
 	tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
 	tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
 	
 	
 	/* Test if we are going over 2GB of DMA space */
 	/* Test if we are going over 2GB of DMA space */
-	if (phb->dma_window_base_cur + phb->dma_window_size > (1L << 31))
+	if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
+		udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
 		panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
 		panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
+	}
 	
 	
 	phb->dma_window_base_cur += phb->dma_window_size;
 	phb->dma_window_base_cur += phb->dma_window_size;
 
 
@@ -326,92 +328,85 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
 
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 {
 {
-	struct device_node *dn, *pdn;
-	struct pci_dn *pci;
+	struct device_node *dn;
 	struct iommu_table *tbl;
 	struct iommu_table *tbl;
+	struct device_node *isa_dn, *isa_dn_orig;
+	struct device_node *tmp;
+	struct pci_dn *pci;
+	int children;
 
 
 	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
 	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
 
 
-	/* For each (root) bus, we carve up the available DMA space in 256MB
-	 * pieces. Since each piece is used by one (sub) bus/device, that would
-	 * give a maximum of 7 devices per PHB. In most cases, this is plenty.
-	 *
-	 * The exception is on Python PHBs (pre-POWER4). Here we don't have EADS
-	 * bridges below the PHB to allocate the sectioned tables to, so instead
-	 * we allocate a 1GB table at the PHB level.
+	dn = pci_bus_to_OF_node(bus);
+	pci = PCI_DN(dn);
+
+	if (bus->self) {
+		/* This is not a root bus, any setup will be done for the
+		 * device-side of the bridge in iommu_dev_setup_pSeries().
+		 */
+		return;
+	}
+
+	/* Check if the ISA bus on the system is under
+	 * this PHB.
 	 */
 	 */
+	isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");
 
 
-	dn = pci_bus_to_OF_node(bus);
-	pci = dn->data;
-
-	if (!bus->self) {
-		/* Root bus */
-		if (is_python(dn)) {
-			unsigned int *iohole;
-
-			DBG("Python root bus %s\n", bus->name);
-
-			iohole = (unsigned int *)get_property(dn, "io-hole", 0);
-
-			if (iohole) {
-				/* On first bus we need to leave room for the
-				 * ISA address space. Just skip the first 256MB
-				 * alltogether. This leaves 768MB for the window.
-				 */
-				DBG("PHB has io-hole, reserving 256MB\n");
-				pci->phb->dma_window_size = 3 << 28;
-				pci->phb->dma_window_base_cur = 1 << 28;
-			} else {
-				/* 1GB window by default */
-				pci->phb->dma_window_size = 1 << 30;
-				pci->phb->dma_window_base_cur = 0;
-			}
-
-			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
-
-			iommu_table_setparms(pci->phb, dn, tbl);
-			pci->iommu_table = iommu_init_table(tbl);
-		} else {
-			/* Do a 128MB table at root. This is used for the IDE
-			 * controller on some SMP-mode POWER4 machines. It
-			 * doesn't hurt to allocate it on other machines
-			 * -- it'll just be unused since new tables are
-			 * allocated on the EADS level.
-			 *
-			 * Allocate at offset 128MB to avoid having to deal
-			 * with ISA holes; 128MB table for IDE is plenty.
-			 */
-			pci->phb->dma_window_size = 1 << 27;
-			pci->phb->dma_window_base_cur = 1 << 27;
-
-			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
-
-			iommu_table_setparms(pci->phb, dn, tbl);
-			pci->iommu_table = iommu_init_table(tbl);
-
-			/* All child buses have 256MB tables */
-			pci->phb->dma_window_size = 1 << 28;
-		}
-	} else {
-		pdn = pci_bus_to_OF_node(bus->parent);
+	while (isa_dn && isa_dn != dn)
+		isa_dn = isa_dn->parent;
+
+	if (isa_dn_orig)
+		of_node_put(isa_dn_orig);
 
 
-		if (!bus->parent->self && !is_python(pdn)) {
-			struct iommu_table *tbl;
-			/* First child and not python means this is the EADS
-			 * level. Allocate new table for this slot with 256MB
-			 * window.
-			 */
+	/* Count number of direct PCI children of the PHB.
+	 * All PCI device nodes have class-code property, so it's
+	 * an easy way to find them.
+	 */
+	for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
+		if (get_property(tmp, "class-code", NULL))
+			children++;
 
 
-			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+	DBG("Children: %d\n", children);
 
 
-			iommu_table_setparms(pci->phb, dn, tbl);
+	/* Calculate amount of DMA window per slot. Each window must be
+	 * a power of two (due to pci_alloc_consistent requirements).
+	 *
+	 * Keep 256MB aside for PHBs with ISA.
+	 */
 
 
-			pci->iommu_table = iommu_init_table(tbl);
-		} else {
-			/* Lower than first child or under python, use parent table */
-			pci->iommu_table = PCI_DN(pdn)->iommu_table;
-		}
+	if (!isa_dn) {
+		/* No ISA/IDE - just set window size and return */
+		pci->phb->dma_window_size = 0x80000000ul; /* To be divided */
+
+		while (pci->phb->dma_window_size * children > 0x80000000ul)
+			pci->phb->dma_window_size >>= 1;
+		DBG("No ISA/IDE, window size is 0x%lx\n",
+			pci->phb->dma_window_size);
+		pci->phb->dma_window_base_cur = 0;
+
+		return;
 	}
 	}
+
+	/* If we have ISA, then we probably have an IDE
+	 * controller too. Allocate a 128MB table but
+	 * skip the first 128MB to avoid stepping on ISA
+	 * space.
+	 */
+	pci->phb->dma_window_size = 0x8000000ul;
+	pci->phb->dma_window_base_cur = 0x8000000ul;
+
+	tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+	iommu_table_setparms(pci->phb, dn, tbl);
+	pci->iommu_table = iommu_init_table(tbl);
+
+	/* Divide the rest (1.75GB) among the children */
+	pci->phb->dma_window_size = 0x80000000ul;
+	while (pci->phb->dma_window_size * children > 0x70000000ul)
+		pci->phb->dma_window_size >>= 1;
+
+	DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
+
 }
 }
 
 
 
 
@@ -462,21 +457,36 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
 static void iommu_dev_setup_pSeries(struct pci_dev *dev)
 static void iommu_dev_setup_pSeries(struct pci_dev *dev)
 {
 {
 	struct device_node *dn, *mydn;
 	struct device_node *dn, *mydn;
+	struct iommu_table *tbl;
+
+	DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));
 
 
-	DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name);
-	/* Now copy the iommu_table ptr from the bus device down to the
-	 * pci device_node.  This means get_iommu_table() won't need to search
-	 * up the device tree to find it.
-	 */
 	mydn = dn = pci_device_to_OF_node(dev);
 	mydn = dn = pci_device_to_OF_node(dev);
 
 
+	/* If we're the direct child of a root bus, then we need to allocate
+	 * an iommu table ourselves. The bus setup code should have setup
+	 * the window sizes already.
+	 */
+	if (!dev->bus->self) {
+		DBG(" --> first child, no bridge. Allocating iommu table.\n");
+		tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+		iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
+		PCI_DN(mydn)->iommu_table = iommu_init_table(tbl);
+
+		return;
+	}
+
+	/* If this device is further down the bus tree, search upwards until
+	 * an already allocated iommu table is found and use that.
+	 */
+
 	while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
 	while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
 		dn = dn->parent;
 		dn = dn->parent;
 
 
 	if (dn && dn->data) {
 	if (dn && dn->data) {
 		PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
 		PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
 	} else {
 	} else {
-		DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name);
+		DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
 	}
 	}
 }
 }
 
 
@@ -510,7 +520,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
 	int *dma_window = NULL;
 	int *dma_window = NULL;
 	struct pci_dn *pci;
 	struct pci_dn *pci;
 
 
-	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name);
+	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
 
 
 	/* dev setup for LPAR is a little tricky, since the device tree might
 	/* dev setup for LPAR is a little tricky, since the device tree might
 	 * contain the dma-window properties per-device and not neccesarily
 	 * contain the dma-window properties per-device and not neccesarily
@@ -532,9 +542,8 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
 	 * slots on POWER4 machines.
 	 * slots on POWER4 machines.
 	 */
 	 */
 	if (dma_window == NULL || pdn->parent == NULL) {
 	if (dma_window == NULL || pdn->parent == NULL) {
-		/* Fall back to regular (non-LPAR) dev setup */
-		DBG("No dma window for device, falling back to regular setup\n");
-		iommu_dev_setup_pSeries(dev);
+		DBG("No dma window for device, linking to parent\n");
+		PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;
 		return;
 		return;
 	} else {
 	} else {
 		DBG("Found DMA window, allocating table\n");
 		DBG("Found DMA window, allocating table\n");

+ 6 - 3
arch/ppc64/kernel/pci.c

@@ -246,11 +246,14 @@ static unsigned int pci_parse_of_flags(u32 addr0)
 	unsigned int flags = 0;
 	unsigned int flags = 0;
 
 
 	if (addr0 & 0x02000000) {
 	if (addr0 & 0x02000000) {
-		flags |= IORESOURCE_MEM;
+		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
+		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
+		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
 		if (addr0 & 0x40000000)
 		if (addr0 & 0x40000000)
-			flags |= IORESOURCE_PREFETCH;
+			flags |= IORESOURCE_PREFETCH
+				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
 	} else if (addr0 & 0x01000000)
 	} else if (addr0 & 0x01000000)
-		flags |= IORESOURCE_IO;
+		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
 	return flags;
 	return flags;
 }
 }
 
 

+ 13 - 5
arch/ppc64/kernel/pmac_setup.c

@@ -434,15 +434,23 @@ static int pmac_check_legacy_ioport(unsigned int baseport)
 
 
 static int __init pmac_declare_of_platform_devices(void)
 static int __init pmac_declare_of_platform_devices(void)
 {
 {
-	struct device_node *np;
+	struct device_node *np, *npp;
 
 
-	np = find_devices("u3");
-	if (np) {
-		for (np = np->child; np != NULL; np = np->sibling)
+	npp = of_find_node_by_name(NULL, "u3");
+	if (npp) {
+		for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
 			if (strncmp(np->name, "i2c", 3) == 0) {
 			if (strncmp(np->name, "i2c", 3) == 0) {
-				of_platform_device_create(np, "u3-i2c");
+				of_platform_device_create(np, "u3-i2c", NULL);
+				of_node_put(np);
 				break;
 				break;
 			}
 			}
+		}
+		of_node_put(npp);
+	}
+        npp = of_find_node_by_type(NULL, "smu");
+        if (npp) {
+		of_platform_device_create(npp, "smu", NULL);
+		of_node_put(npp);
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 2 - 2
arch/ppc64/kernel/pmac_time.c

@@ -84,7 +84,7 @@ void pmac_get_rtc_time(struct rtc_time *tm)
 
 
 #ifdef CONFIG_PMAC_SMU
 #ifdef CONFIG_PMAC_SMU
 	case SYS_CTRLER_SMU:
 	case SYS_CTRLER_SMU:
-		smu_get_rtc_time(tm);
+		smu_get_rtc_time(tm, 1);
 		break;
 		break;
 #endif /* CONFIG_PMAC_SMU */
 #endif /* CONFIG_PMAC_SMU */
 	default:
 	default:
@@ -128,7 +128,7 @@ int pmac_set_rtc_time(struct rtc_time *tm)
 
 
 #ifdef CONFIG_PMAC_SMU
 #ifdef CONFIG_PMAC_SMU
 	case SYS_CTRLER_SMU:
 	case SYS_CTRLER_SMU:
-		return smu_set_rtc_time(tm);
+		return smu_set_rtc_time(tm, 1);
 #endif /* CONFIG_PMAC_SMU */
 #endif /* CONFIG_PMAC_SMU */
 	default:
 	default:
 		return -ENODEV;
 		return -ENODEV;

+ 2 - 1
arch/ppc64/kernel/prom_init.c

@@ -1711,6 +1711,7 @@ static void __init flatten_device_tree(void)
 	unsigned long offset = reloc_offset();
 	unsigned long offset = reloc_offset();
 	unsigned long mem_start, mem_end, room;
 	unsigned long mem_start, mem_end, room;
 	struct boot_param_header *hdr;
 	struct boot_param_header *hdr;
+	struct prom_t *_prom = PTRRELOC(&prom);
 	char *namep;
 	char *namep;
 	u64 *rsvmap;
 	u64 *rsvmap;
 
 
@@ -1765,6 +1766,7 @@ static void __init flatten_device_tree(void)
 	RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
 	RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
 
 
 	/* Finish header */
 	/* Finish header */
+	hdr->boot_cpuid_phys = _prom->cpu;
 	hdr->magic = OF_DT_HEADER;
 	hdr->magic = OF_DT_HEADER;
 	hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
 	hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
 	hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
 	hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
@@ -1854,7 +1856,6 @@ static void __init prom_find_boot_cpu(void)
 
 
 	cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
 	cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
 
 
-	prom_setprop(cpu_pkg, "linux,boot-cpu", NULL, 0);
 	prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
 	prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
 	_prom->cpu = getprop_rval;
 	_prom->cpu = getprop_rval;
 
 

+ 1 - 0
arch/ppc64/kernel/ptrace.c

@@ -219,6 +219,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
 
 
 	case PTRACE_SET_DEBUGREG:
 	case PTRACE_SET_DEBUGREG:
 		ret = ptrace_set_debugreg(child, addr, data);
 		ret = ptrace_set_debugreg(child, addr, data);
+		break;
 
 
 	case PTRACE_DETACH:
 	case PTRACE_DETACH:
 		ret = ptrace_detach(child, data);
 		ret = ptrace_detach(child, data);

+ 2 - 3
arch/ppc64/mm/hash_native.c

@@ -342,15 +342,14 @@ static void native_flush_hash_range(unsigned long number, int local)
 	hpte_t *hptep;
 	hpte_t *hptep;
 	unsigned long hpte_v;
 	unsigned long hpte_v;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
-
-	/* XXX fix for large ptes */
-	unsigned long large = 0;
+	unsigned long large;
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
 	j = 0;
 	j = 0;
 	for (i = 0; i < number; i++) {
 	for (i = 0; i < number; i++) {
 		va = batch->vaddr[j];
 		va = batch->vaddr[j];
+		large = pte_huge(batch->pte[i]);
 		if (large)
 		if (large)
 			vpn = va >> HPAGE_SHIFT;
 			vpn = va >> HPAGE_SHIFT;
 		else
 		else

+ 5 - 2
arch/ppc64/mm/hugetlbpage.c

@@ -710,10 +710,13 @@ repeat:
 			hpte_group = ((~hash & htab_hash_mask) *
 			hpte_group = ((~hash & htab_hash_mask) *
 				      HPTES_PER_GROUP) & ~0x7UL; 
 				      HPTES_PER_GROUP) & ~0x7UL; 
 			slot = ppc_md.hpte_insert(hpte_group, va, prpn,
 			slot = ppc_md.hpte_insert(hpte_group, va, prpn,
-						  HPTE_V_LARGE, rflags);
+						  HPTE_V_LARGE |
+						  HPTE_V_SECONDARY,
+						  rflags);
 			if (slot == -1) {
 			if (slot == -1) {
 				if (mftb() & 0x1)
 				if (mftb() & 0x1)
-					hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+					hpte_group = ((hash & htab_hash_mask) *
+						      HPTES_PER_GROUP)&~0x7UL;
 
 
 				ppc_md.hpte_remove(hpte_group);
 				ppc_md.hpte_remove(hpte_group);
 				goto repeat;
 				goto repeat;

+ 19 - 20
arch/sparc64/kernel/entry.S

@@ -42,19 +42,15 @@
  * executing (see inherit_locked_prom_mappings() rant).
  * executing (see inherit_locked_prom_mappings() rant).
  */
  */
 sparc64_vpte_nucleus:
 sparc64_vpte_nucleus:
-	/* Load 0xf0000000, which is LOW_OBP_ADDRESS.  */
-	mov		0xf, %g5
-	sllx		%g5, 28, %g5
-
-	/* Is addr >= LOW_OBP_ADDRESS?  */
+	/* Note that kvmap below has verified that the address is
+	 * in the range MODULES_VADDR --> VMALLOC_END already.  So
+	 * here we need only check if it is an OBP address or not.
+	 */
+	sethi		%hi(LOW_OBP_ADDRESS), %g5
 	cmp		%g4, %g5
 	cmp		%g4, %g5
 	blu,pn		%xcc, sparc64_vpte_patchme1
 	blu,pn		%xcc, sparc64_vpte_patchme1
 	 mov		0x1, %g5
 	 mov		0x1, %g5
-
-	/* Load 0x100000000, which is HI_OBP_ADDRESS.  */
 	sllx		%g5, 32, %g5
 	sllx		%g5, 32, %g5
-
-	/* Is addr < HI_OBP_ADDRESS?  */
 	cmp		%g4, %g5
 	cmp		%g4, %g5
 	blu,pn		%xcc, obp_iaddr_patch
 	blu,pn		%xcc, obp_iaddr_patch
 	 nop
 	 nop
@@ -156,26 +152,29 @@ obp_daddr_patch:
  * rather, use information saved during inherit_prom_mappings() using 8k
  * rather, use information saved during inherit_prom_mappings() using 8k
  * pagesize.
  * pagesize.
  */
  */
+	.align		32
 kvmap:
 kvmap:
-	/* Load 0xf0000000, which is LOW_OBP_ADDRESS.  */
-	mov		0xf, %g5
-	sllx		%g5, 28, %g5
+	sethi		%hi(MODULES_VADDR), %g5
+	cmp		%g4, %g5
+	blu,pn		%xcc, longpath
+	 mov		(VMALLOC_END >> 24), %g5
+	sllx		%g5, 24, %g5
+	cmp		%g4, %g5
+	bgeu,pn		%xcc, longpath
+	 nop
 
 
-	/* Is addr >= LOW_OBP_ADDRESS?  */
+kvmap_check_obp:
+	sethi		%hi(LOW_OBP_ADDRESS), %g5
 	cmp		%g4, %g5
 	cmp		%g4, %g5
-	blu,pn		%xcc, vmalloc_addr
+	blu,pn		%xcc, kvmap_vmalloc_addr
 	 mov		0x1, %g5
 	 mov		0x1, %g5
-
-	/* Load 0x100000000, which is HI_OBP_ADDRESS.  */
 	sllx		%g5, 32, %g5
 	sllx		%g5, 32, %g5
-
-	/* Is addr < HI_OBP_ADDRESS?  */
 	cmp		%g4, %g5
 	cmp		%g4, %g5
 	blu,pn		%xcc, obp_daddr_patch
 	blu,pn		%xcc, obp_daddr_patch
 	 nop
 	 nop
 
 
-vmalloc_addr:
-	/* If we get here, a vmalloc addr accessed, load kernel VPTE.  */
+kvmap_vmalloc_addr:
+	/* If we get here, a vmalloc addr was accessed, load kernel VPTE.  */
 	ldxa		[%g3 + %g6] ASI_N, %g5
 	ldxa		[%g3 + %g6] ASI_N, %g5
 	brgez,pn	%g5, longpath
 	brgez,pn	%g5, longpath
 	 nop
 	 nop

+ 4 - 3
arch/sparc64/kernel/ptrace.c

@@ -30,6 +30,7 @@
 #include <asm/psrcompat.h>
 #include <asm/psrcompat.h>
 #include <asm/visasm.h>
 #include <asm/visasm.h>
 #include <asm/spitfire.h>
 #include <asm/spitfire.h>
+#include <asm/page.h>
 
 
 /* Returning from ptrace is a bit tricky because the syscall return
 /* Returning from ptrace is a bit tricky because the syscall return
  * low level code assumes any value returned which is negative and
  * low level code assumes any value returned which is negative and
@@ -128,20 +129,20 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
 	 * is mapped to in the user's address space, we can skip the
 	 * is mapped to in the user's address space, we can skip the
 	 * D-cache flush.
 	 * D-cache flush.
 	 */
 	 */
-	if ((uaddr ^ kaddr) & (1UL << 13)) {
+	if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
 		unsigned long start = __pa(kaddr);
 		unsigned long start = __pa(kaddr);
 		unsigned long end = start + len;
 		unsigned long end = start + len;
 
 
 		if (tlb_type == spitfire) {
 		if (tlb_type == spitfire) {
 			for (; start < end; start += 32)
 			for (; start < end; start += 32)
-				spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
+				spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
 		} else {
 		} else {
 			for (; start < end; start += 32)
 			for (; start < end; start += 32)
 				__asm__ __volatile__(
 				__asm__ __volatile__(
 					"stxa %%g0, [%0] %1\n\t"
 					"stxa %%g0, [%0] %1\n\t"
 					"membar #Sync"
 					"membar #Sync"
 					: /* no outputs */
 					: /* no outputs */
-					: "r" (va),
+					: "r" (start),
 					"i" (ASI_DCACHE_INVALIDATE));
 					"i" (ASI_DCACHE_INVALIDATE));
 		}
 		}
 	}
 	}

+ 1 - 1
arch/sparc64/kernel/una_asm.S

@@ -17,7 +17,7 @@ kernel_unaligned_trap_fault:
 __do_int_store:
 __do_int_store:
 	rd	%asi, %o4
 	rd	%asi, %o4
 	wr	%o3, 0, %asi
 	wr	%o3, 0, %asi
-	ldx	[%o2], %g3
+	mov	%o2, %g3
 	cmp	%o1, 2
 	cmp	%o1, 2
 	be,pn	%icc, 2f
 	be,pn	%icc, 2f
 	 cmp	%o1, 4
 	 cmp	%o1, 4

+ 57 - 7
arch/sparc64/kernel/unaligned.c

@@ -184,13 +184,14 @@ extern void do_int_load(unsigned long *dest_reg, int size,
 			unsigned long *saddr, int is_signed, int asi);
 			unsigned long *saddr, int is_signed, int asi);
 	
 	
 extern void __do_int_store(unsigned long *dst_addr, int size,
 extern void __do_int_store(unsigned long *dst_addr, int size,
-			   unsigned long *src_val, int asi);
+			   unsigned long src_val, int asi);
 
 
 static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
 static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
-				struct pt_regs *regs, int asi)
+				struct pt_regs *regs, int asi, int orig_asi)
 {
 {
 	unsigned long zero = 0;
 	unsigned long zero = 0;
-	unsigned long *src_val = &zero;
+	unsigned long *src_val_p = &zero;
+	unsigned long src_val;
 
 
 	if (size == 16) {
 	if (size == 16) {
 		size = 8;
 		size = 8;
@@ -198,7 +199,25 @@ static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
 		        (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
 		        (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
 			(unsigned)fetch_reg(reg_num + 1, regs);
 			(unsigned)fetch_reg(reg_num + 1, regs);
 	} else if (reg_num) {
 	} else if (reg_num) {
-		src_val = fetch_reg_addr(reg_num, regs);
+		src_val_p = fetch_reg_addr(reg_num, regs);
+	}
+	src_val = *src_val_p;
+	if (unlikely(asi != orig_asi)) {
+		switch (size) {
+		case 2:
+			src_val = swab16(src_val);
+			break;
+		case 4:
+			src_val = swab32(src_val);
+			break;
+		case 8:
+			src_val = swab64(src_val);
+			break;
+		case 16:
+		default:
+			BUG();
+			break;
+		};
 	}
 	}
 	__do_int_store(dst_addr, size, src_val, asi);
 	__do_int_store(dst_addr, size, src_val, asi);
 }
 }
@@ -276,6 +295,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
 		kernel_mna_trap_fault();
 		kernel_mna_trap_fault();
 	} else {
 	} else {
 		unsigned long addr;
 		unsigned long addr;
+		int orig_asi, asi;
 
 
 		addr = compute_effective_address(regs, insn,
 		addr = compute_effective_address(regs, insn,
 						 ((insn >> 25) & 0x1f));
 						 ((insn >> 25) & 0x1f));
@@ -285,18 +305,48 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
 		       regs->tpc, dirstrings[dir], addr, size,
 		       regs->tpc, dirstrings[dir], addr, size,
 		       regs->u_regs[UREG_RETPC]);
 		       regs->u_regs[UREG_RETPC]);
 #endif
 #endif
+		orig_asi = asi = decode_asi(insn, regs);
+		switch (asi) {
+		case ASI_NL:
+		case ASI_AIUPL:
+		case ASI_AIUSL:
+		case ASI_PL:
+		case ASI_SL:
+		case ASI_PNFL:
+		case ASI_SNFL:
+			asi &= ~0x08;
+			break;
+		};
 		switch (dir) {
 		switch (dir) {
 		case load:
 		case load:
 			do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
 			do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
 				    size, (unsigned long *) addr,
 				    size, (unsigned long *) addr,
-				    decode_signedness(insn),
-				    decode_asi(insn, regs));
+				    decode_signedness(insn), asi);
+			if (unlikely(asi != orig_asi)) {
+				unsigned long val_in = *(unsigned long *) addr;
+				switch (size) {
+				case 2:
+					val_in = swab16(val_in);
+					break;
+				case 4:
+					val_in = swab32(val_in);
+					break;
+				case 8:
+					val_in = swab64(val_in);
+					break;
+				case 16:
+				default:
+					BUG();
+					break;
+				};
+				*(unsigned long *) addr = val_in;
+			}
 			break;
 			break;
 
 
 		case store:
 		case store:
 			do_int_store(((insn>>25)&0x1f), size,
 			do_int_store(((insn>>25)&0x1f), size,
 				     (unsigned long *) addr, regs,
 				     (unsigned long *) addr, regs,
-				     decode_asi(insn, regs));
+				     asi, orig_asi);
 			break;
 			break;
 
 
 		default:
 		default:

+ 5 - 1
arch/um/Makefile

@@ -53,9 +53,13 @@ SYS_DIR		:= $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
 
 # -Dvmap=kernel_vmap affects everything, and prevents anything from
 # -Dvmap=kernel_vmap affects everything, and prevents anything from
 # referencing the libpcap.o symbol so named.
 # referencing the libpcap.o symbol so named.
+#
+# Same things for in6addr_loopback - found in libc.
 
 
 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
-	$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap
+	$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
+	-Din6addr_loopback=kernel_in6addr_loopback
+
 AFLAGS += $(ARCH_INCLUDE)
 AFLAGS += $(ARCH_INCLUDE)
 
 
 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))

+ 43 - 17
arch/um/drivers/chan_kern.c

@@ -19,18 +19,44 @@
 #include "line.h"
 #include "line.h"
 #include "os.h"
 #include "os.h"
 
 
-#ifdef CONFIG_NOCONFIG_CHAN
+/* XXX: could well be moved to somewhere else, if needed. */
+static int my_printf(const char * fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+static int my_printf(const char * fmt, ...)
+{
+	/* Yes, can be called on atomic context.*/
+	char *buf = kmalloc(4096, GFP_ATOMIC);
+	va_list args;
+	int r;
+
+	if (!buf) {
+		/* We print directly fmt.
+		 * Yes, yes, yes, feel free to complain. */
+		r = strlen(fmt);
+	} else {
+		va_start(args, fmt);
+		r = vsprintf(buf, fmt, args);
+		va_end(args);
+		fmt = buf;
+	}
 
 
-/* The printk's here are wrong because we are complaining that there is no
- * output device, but printk is printing to that output device.  The user will
- * never see the error.  printf would be better, except it can't run on a
- * kernel stack because it will overflow it.
- * Use printk for now since that will avoid crashing.
- */
+	if (r)
+		r = os_write_file(1, fmt, r);
+	return r;
+
+}
+
+#ifdef CONFIG_NOCONFIG_CHAN
+/* Despite its name, there's no added trailing newline. */
+static int my_puts(const char * buf)
+{
+	return os_write_file(1, buf, strlen(buf));
+}
 
 
 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 {
 {
-	printk(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(NULL);
 	return(NULL);
 }
 }
@@ -38,27 +64,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 static int not_configged_open(int input, int output, int primary, void *data,
 static int not_configged_open(int input, int output, int primary, void *data,
 			      char **dev_out)
 			      char **dev_out)
 {
 {
-	printk(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-ENODEV);
 	return(-ENODEV);
 }
 }
 
 
 static void not_configged_close(int fd, void *data)
 static void not_configged_close(int fd, void *data)
 {
 {
-	printk(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 }
 }
 
 
 static int not_configged_read(int fd, char *c_out, void *data)
 static int not_configged_read(int fd, char *c_out, void *data)
 {
 {
-	printk(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-EIO);
 	return(-EIO);
 }
 }
 
 
 static int not_configged_write(int fd, const char *buf, int len, void *data)
 static int not_configged_write(int fd, const char *buf, int len, void *data)
 {
 {
-	printk(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-EIO);
 	return(-EIO);
 }
 }
@@ -66,7 +92,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
 static int not_configged_console_write(int fd, const char *buf, int len,
 static int not_configged_console_write(int fd, const char *buf, int len,
 				       void *data)
 				       void *data)
 {
 {
-	printk(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-EIO);
 	return(-EIO);
 }
 }
@@ -74,14 +100,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
 static int not_configged_window_size(int fd, void *data, unsigned short *rows,
 static int not_configged_window_size(int fd, void *data, unsigned short *rows,
 				     unsigned short *cols)
 				     unsigned short *cols)
 {
 {
-	printk(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-ENODEV);
 	return(-ENODEV);
 }
 }
 
 
 static void not_configged_free(void *data)
 static void not_configged_free(void *data)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 }
 }
 
 
@@ -457,7 +483,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
 		}
 		}
 	}
 	}
 	if(ops == NULL){
 	if(ops == NULL){
-		printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", 
+		my_printf("parse_chan couldn't parse \"%s\"\n",
 		       str);
 		       str);
 		return(NULL);
 		return(NULL);
 	}
 	}
@@ -465,7 +491,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
 	data = (*ops->init)(str, device, opts);
 	data = (*ops->init)(str, device, opts);
 	if(data == NULL) return(NULL);
 	if(data == NULL) return(NULL);
 
 
-	chan = kmalloc(sizeof(*chan), GFP_KERNEL);
+	chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
 	if(chan == NULL) return(NULL);
 	if(chan == NULL) return(NULL);
 	*chan = ((struct chan) { .list	 	= LIST_HEAD_INIT(chan->list),
 	*chan = ((struct chan) { .list	 	= LIST_HEAD_INIT(chan->list),
 				 .primary	= 1,
 				 .primary	= 1,

+ 1 - 1
arch/um/drivers/mconsole_user.c

@@ -23,7 +23,7 @@ static struct mconsole_command commands[] = {
 	{ "reboot", mconsole_reboot, MCONSOLE_PROC },
 	{ "reboot", mconsole_reboot, MCONSOLE_PROC },
 	{ "config", mconsole_config, MCONSOLE_PROC },
 	{ "config", mconsole_config, MCONSOLE_PROC },
 	{ "remove", mconsole_remove, MCONSOLE_PROC },
 	{ "remove", mconsole_remove, MCONSOLE_PROC },
-	{ "sysrq", mconsole_sysrq, MCONSOLE_INTR },
+	{ "sysrq", mconsole_sysrq, MCONSOLE_PROC },
 	{ "help", mconsole_help, MCONSOLE_INTR },
 	{ "help", mconsole_help, MCONSOLE_INTR },
 	{ "cad", mconsole_cad, MCONSOLE_INTR },
 	{ "cad", mconsole_cad, MCONSOLE_INTR },
 	{ "stop", mconsole_stop, MCONSOLE_PROC },
 	{ "stop", mconsole_stop, MCONSOLE_PROC },

+ 3 - 1
arch/um/include/common-offsets.h

@@ -12,4 +12,6 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
 DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
 DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
 DEFINE_STR(UM_KERN_INFO, KERN_INFO);
 DEFINE_STR(UM_KERN_INFO, KERN_INFO);
 DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
 DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
-DEFINE(HOST_ELF_CLASS, ELF_CLASS);
+DEFINE(UM_ELF_CLASS, ELF_CLASS);
+DEFINE(UM_ELFCLASS32, ELFCLASS32);
+DEFINE(UM_ELFCLASS64, ELFCLASS64);

+ 3 - 1
arch/um/include/user.h

@@ -14,7 +14,9 @@ extern void *um_kmalloc_atomic(int size);
 extern void kfree(void *ptr);
 extern void kfree(void *ptr);
 extern int in_aton(char *str);
 extern int in_aton(char *str);
 extern int open_gdb_chan(void);
 extern int open_gdb_chan(void);
-extern int strlcpy(char *, const char *, int);
+/* These use size_t, however unsigned long is correct on both i386 and x86_64. */
+extern unsigned long strlcpy(char *, const char *, unsigned long);
+extern unsigned long strlcat(char *, const char *, unsigned long);
 extern void *um_vmalloc(int size);
 extern void *um_vmalloc(int size);
 extern void vfree(void *ptr);
 extern void vfree(void *ptr);
 
 

+ 2 - 1
arch/um/kernel/process_kern.c

@@ -82,7 +82,8 @@ unsigned long alloc_stack(int order, int atomic)
 	unsigned long page;
 	unsigned long page;
 	int flags = GFP_KERNEL;
 	int flags = GFP_KERNEL;
 
 
-	if(atomic) flags |= GFP_ATOMIC;
+	if (atomic)
+		flags = GFP_ATOMIC;
 	page = __get_free_pages(flags, order);
 	page = __get_free_pages(flags, order);
 	if(page == 0)
 	if(page == 0)
 		return(0);
 		return(0);

+ 1 - 1
arch/um/kernel/sigio_user.c

@@ -340,7 +340,7 @@ static int setup_initial_poll(int fd)
 {
 {
 	struct pollfd *p;
 	struct pollfd *p;
 
 
-	p = um_kmalloc(sizeof(struct pollfd));
+	p = um_kmalloc_atomic(sizeof(struct pollfd));
 	if(p == NULL){
 	if(p == NULL){
 		printk("setup_initial_poll : failed to allocate poll\n");
 		printk("setup_initial_poll : failed to allocate poll\n");
 		return(-1);
 		return(-1);

+ 0 - 6
arch/um/kernel/skas/include/uaccess-skas.h

@@ -18,12 +18,6 @@
 	  ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
 	  ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
 	  ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
 	  ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
 
 
-static inline int verify_area_skas(int type, const void __user * addr,
-                                   unsigned long size)
-{
-	return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
-}
-
 extern int copy_from_user_skas(void *to, const void __user *from, int n);
 extern int copy_from_user_skas(void *to, const void __user *from, int n);
 extern int copy_to_user_skas(void __user *to, const void *from, int n);
 extern int copy_to_user_skas(void __user *to, const void *from, int n);
 extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
 extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);

+ 6 - 6
arch/um/kernel/tlb.c

@@ -193,12 +193,12 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
                 r = pte_read(*npte);
                 r = pte_read(*npte);
                 w = pte_write(*npte);
                 w = pte_write(*npte);
                 x = pte_exec(*npte);
                 x = pte_exec(*npte);
-                if(!pte_dirty(*npte))
-                        w = 0;
-                if(!pte_young(*npte)){
-                        r = 0;
-                        w = 0;
-                }
+		if (!pte_young(*npte)) {
+			r = 0;
+			w = 0;
+		} else if (!pte_dirty(*npte)) {
+			w = 0;
+		}
                 if(force || pte_newpage(*npte)){
                 if(force || pte_newpage(*npte)){
                         if(pte_present(*npte))
                         if(pte_present(*npte))
 			  ret = add_mmap(addr,
 			  ret = add_mmap(addr,

+ 17 - 1
arch/um/kernel/trap_kern.c

@@ -18,6 +18,7 @@
 #include "asm/a.out.h"
 #include "asm/a.out.h"
 #include "asm/current.h"
 #include "asm/current.h"
 #include "asm/irq.h"
 #include "asm/irq.h"
+#include "sysdep/sigcontext.h"
 #include "user_util.h"
 #include "user_util.h"
 #include "kern_util.h"
 #include "kern_util.h"
 #include "kern.h"
 #include "kern.h"
@@ -39,6 +40,12 @@ int handle_page_fault(unsigned long address, unsigned long ip,
 	int err = -EFAULT;
 	int err = -EFAULT;
 
 
 	*code_out = SEGV_MAPERR;
 	*code_out = SEGV_MAPERR;
+
+	/* If the fault was during atomic operation, don't take the fault, just
+	 * fail. */
+	if (in_atomic())
+		goto out_nosemaphore;
+
 	down_read(&mm->mmap_sem);
 	down_read(&mm->mmap_sem);
 	vma = find_vma(mm, address);
 	vma = find_vma(mm, address);
 	if(!vma) 
 	if(!vma) 
@@ -89,6 +96,7 @@ survive:
 	flush_tlb_page(vma, address);
 	flush_tlb_page(vma, address);
 out:
 out:
 	up_read(&mm->mmap_sem);
 	up_read(&mm->mmap_sem);
+out_nosemaphore:
 	return(err);
 	return(err);
 
 
 /*
 /*
@@ -125,7 +133,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
         }
         }
 	else if(current->mm == NULL)
 	else if(current->mm == NULL)
 		panic("Segfault with no mm");
 		panic("Segfault with no mm");
-	err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+
+	if (SEGV_IS_FIXABLE(&fi))
+		err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+	else {
+		err = -EFAULT;
+		/* A thread accessed NULL, we get a fault, but CR2 is invalid.
+		 * This code is used in __do_copy_from_user() of TT mode. */
+		address = 0;
+	}
 
 
 	catcher = current->thread.fault_catcher;
 	catcher = current->thread.fault_catcher;
 	if(!err)
 	if(!err)

+ 0 - 6
arch/um/kernel/tt/include/uaccess-tt.h

@@ -33,12 +33,6 @@ extern unsigned long uml_physmem;
          (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
          (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
           (under_task_size(addr, size) || is_stack(addr, size))))
           (under_task_size(addr, size) || is_stack(addr, size))))
 
 
-static inline int verify_area_tt(int type, const void __user * addr,
-                                 unsigned long size)
-{
-	return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
-}
-
 extern unsigned long get_fault_addr(void);
 extern unsigned long get_fault_addr(void);
 
 
 extern int __do_copy_from_user(void *to, const void *from, int n,
 extern int __do_copy_from_user(void *to, const void *from, int n,

+ 2 - 1
arch/um/kernel/tt/process_kern.c

@@ -23,10 +23,11 @@
 #include "mem_user.h"
 #include "mem_user.h"
 #include "tlb.h"
 #include "tlb.h"
 #include "mode.h"
 #include "mode.h"
+#include "mode_kern.h"
 #include "init.h"
 #include "init.h"
 #include "tt.h"
 #include "tt.h"
 
 
-int switch_to_tt(void *prev, void *next, void *last)
+void switch_to_tt(void *prev, void *next)
 {
 {
 	struct task_struct *from, *to, *prev_sched;
 	struct task_struct *from, *to, *prev_sched;
 	unsigned long flags;
 	unsigned long flags;

+ 9 - 2
arch/um/kernel/tt/uaccess_user.c

@@ -22,8 +22,15 @@ int __do_copy_from_user(void *to, const void *from, int n,
 			       __do_copy, &faulted);
 			       __do_copy, &faulted);
 	TASK_REGS(get_current())->tt = save;
 	TASK_REGS(get_current())->tt = save;
 
 
-	if(!faulted) return(0);
-	else return(n - (fault - (unsigned long) from));
+	if(!faulted)
+		return 0;
+	else if (fault)
+		return n - (fault - (unsigned long) from);
+	else
+		/* In case of a general protection fault, we don't have the
+		 * fault address, so NULL is used instead. Pretend we didn't
+		 * copy anything. */
+		return n;
 }
 }
 
 
 static void __do_strncpy(void *dst, const void *src, int count)
 static void __do_strncpy(void *dst, const void *src, int count)

+ 23 - 18
arch/um/kernel/umid.c

@@ -31,6 +31,8 @@ static char *uml_dir = UML_DIR;
 /* Changed by set_umid */
 /* Changed by set_umid */
 static int umid_is_random = 1;
 static int umid_is_random = 1;
 static int umid_inited = 0;
 static int umid_inited = 0;
+/* Have we created the files? Should we remove them? */
+static int umid_owned = 0;
 
 
 static int make_umid(int (*printer)(const char *fmt, ...));
 static int make_umid(int (*printer)(const char *fmt, ...));
 
 
@@ -82,20 +84,21 @@ int __init umid_file_name(char *name, char *buf, int len)
 
 
 extern int tracing_pid;
 extern int tracing_pid;
 
 
-static int __init create_pid_file(void)
+static void __init create_pid_file(void)
 {
 {
 	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
 	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
 	char pid[sizeof("nnnnn\0")];
 	char pid[sizeof("nnnnn\0")];
 	int fd, n;
 	int fd, n;
 
 
-	if(umid_file_name("pid", file, sizeof(file))) return 0;
+	if(umid_file_name("pid", file, sizeof(file)))
+		return;
 
 
 	fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
 	fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
 			  0644);
 			  0644);
 	if(fd < 0){
 	if(fd < 0){
 		printf("Open of machine pid file \"%s\" failed: %s\n",
 		printf("Open of machine pid file \"%s\" failed: %s\n",
 		       file, strerror(-fd));
 		       file, strerror(-fd));
-		return 0;
+		return;
 	}
 	}
 
 
 	sprintf(pid, "%d\n", os_getpid());
 	sprintf(pid, "%d\n", os_getpid());
@@ -103,7 +106,6 @@ static int __init create_pid_file(void)
 	if(n != strlen(pid))
 	if(n != strlen(pid))
 		printf("Write of pid file failed - err = %d\n", -n);
 		printf("Write of pid file failed - err = %d\n", -n);
 	os_close_file(fd);
 	os_close_file(fd);
-	return 0;
 }
 }
 
 
 static int actually_do_remove(char *dir)
 static int actually_do_remove(char *dir)
@@ -147,7 +149,8 @@ static int actually_do_remove(char *dir)
 void remove_umid_dir(void)
 void remove_umid_dir(void)
 {
 {
 	char dir[strlen(uml_dir) + UMID_LEN + 1];
 	char dir[strlen(uml_dir) + UMID_LEN + 1];
-	if(!umid_inited) return;
+	if (!umid_owned)
+		return;
 
 
 	sprintf(dir, "%s%s", uml_dir, umid);
 	sprintf(dir, "%s%s", uml_dir, umid);
 	actually_do_remove(dir);
 	actually_do_remove(dir);
@@ -155,11 +158,12 @@ void remove_umid_dir(void)
 
 
 char *get_umid(int only_if_set)
 char *get_umid(int only_if_set)
 {
 {
-	if(only_if_set && umid_is_random) return(NULL);
-	return(umid);
+	if(only_if_set && umid_is_random)
+		return NULL;
+	return umid;
 }
 }
 
 
-int not_dead_yet(char *dir)
+static int not_dead_yet(char *dir)
 {
 {
 	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
 	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
 	char pid[sizeof("nnnnn\0")], *end;
 	char pid[sizeof("nnnnn\0")], *end;
@@ -193,7 +197,8 @@ int not_dead_yet(char *dir)
 		   (p == CHOOSE_MODE(tracing_pid, os_getpid())))
 		   (p == CHOOSE_MODE(tracing_pid, os_getpid())))
 			dead = 1;
 			dead = 1;
 	}
 	}
-	if(!dead) return(1);
+	if(!dead)
+		return(1);
 	return(actually_do_remove(dir));
 	return(actually_do_remove(dir));
 }
 }
 
 
@@ -232,16 +237,13 @@ static int __init make_uml_dir(void)
 		strlcpy(dir, home, sizeof(dir));
 		strlcpy(dir, home, sizeof(dir));
 		uml_dir++;
 		uml_dir++;
 	}
 	}
+	strlcat(dir, uml_dir, sizeof(dir));
 	len = strlen(dir);
 	len = strlen(dir);
-	strncat(dir, uml_dir, sizeof(dir) - len);
-	len = strlen(dir);
-	if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
-		dir[len] = '/';
-		dir[len + 1] = '\0';
-	}
+	if (len > 0 && dir[len - 1] != '/')
+		strlcat(dir, "/", sizeof(dir));
 
 
 	uml_dir = malloc(strlen(dir) + 1);
 	uml_dir = malloc(strlen(dir) + 1);
-	if(uml_dir == NULL){
+	if (uml_dir == NULL) {
 		printf("make_uml_dir : malloc failed, errno = %d\n", errno);
 		printf("make_uml_dir : malloc failed, errno = %d\n", errno);
 		exit(1);
 		exit(1);
 	}
 	}
@@ -286,6 +288,7 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
 		if(errno == EEXIST){
 		if(errno == EEXIST){
 			if(not_dead_yet(tmp)){
 			if(not_dead_yet(tmp)){
 				(*printer)("umid '%s' is in use\n", umid);
 				(*printer)("umid '%s' is in use\n", umid);
+				umid_owned = 0;
 				return(-1);
 				return(-1);
 			}
 			}
 			err = mkdir(tmp, 0777);
 			err = mkdir(tmp, 0777);
@@ -296,7 +299,8 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
 		return(-1);
 		return(-1);
 	}
 	}
 
 
-	return(0);
+	umid_owned = 1;
+	return 0;
 }
 }
 
 
 __uml_setup("uml_dir=", set_uml_dir,
 __uml_setup("uml_dir=", set_uml_dir,
@@ -309,7 +313,8 @@ static int __init make_umid_setup(void)
 	/* one function with the ordering we need ... */
 	/* one function with the ordering we need ... */
 	make_uml_dir();
 	make_uml_dir();
 	make_umid(printf);
 	make_umid(printf);
-	return create_pid_file();
+	create_pid_file();
+	return 0;
 }
 }
 __uml_postsetup(make_umid_setup);
 __uml_postsetup(make_umid_setup);
 
 

+ 6 - 0
arch/um/kernel/user_util.c

@@ -128,6 +128,12 @@ void setup_machinename(char *machine_out)
 	struct utsname host;
 	struct utsname host;
 
 
 	uname(&host);
 	uname(&host);
+#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
+	if (!strcmp(host.machine, "x86_64")) {
+		strcpy(machine_out, "i686");
+		return;
+	}
+#endif
 	strcpy(machine_out, host.machine);
 	strcpy(machine_out, host.machine);
 }
 }
 
 

+ 1 - 0
arch/um/os-Linux/aio.c

@@ -144,6 +144,7 @@ static int aio_thread(void *arg)
                                "errno = %d\n", errno);
                                "errno = %d\n", errno);
                 }
                 }
                 else {
                 else {
+			/* This is safe as we've just a pointer here. */
 			aio = (struct aio_context *) (long) event.data;
 			aio = (struct aio_context *) (long) event.data;
 			if(update_aio(aio, event.res)){
 			if(update_aio(aio, event.res)){
 				do_aio(ctx, aio);
 				do_aio(ctx, aio);

+ 2 - 1
arch/um/os-Linux/elf_aux.c

@@ -14,7 +14,8 @@
 #include "mem_user.h"
 #include "mem_user.h"
 #include <kernel-offsets.h>
 #include <kernel-offsets.h>
 
 
-#if HOST_ELF_CLASS == ELFCLASS32
+/* Use the one from the kernel - the host may miss it, if having old headers. */
+#if UM_ELF_CLASS == UM_ELFCLASS32
 typedef Elf32_auxv_t elf_auxv_t;
 typedef Elf32_auxv_t elf_auxv_t;
 #else
 #else
 typedef Elf64_auxv_t elf_auxv_t;
 typedef Elf64_auxv_t elf_auxv_t;

+ 1 - 0
arch/um/os-Linux/process.c

@@ -3,6 +3,7 @@
  * Licensed under the GPL
  * Licensed under the GPL
  */
  */
 
 
+#include <unistd.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <errno.h>
 #include <errno.h>
 #include <signal.h>
 #include <signal.h>

+ 1 - 0
arch/um/sys-i386/ldt.c

@@ -83,6 +83,7 @@ int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
 			goto out;
 			goto out;
 		}
 		}
 		p = buf;
 		p = buf;
+		break;
 	default:
 	default:
 		res = -ENOSYS;
 		res = -ENOSYS;
 		goto out;
 		goto out;

+ 1 - 1
arch/x86_64/Kconfig

@@ -308,7 +308,7 @@ config HPET_TIMER
 	  present.  The HPET provides a stable time base on SMP
 	  present.  The HPET provides a stable time base on SMP
 	  systems, unlike the TSC, but it is more expensive to access,
 	  systems, unlike the TSC, but it is more expensive to access,
 	  as it is off-chip.  You can find the HPET spec at
 	  as it is off-chip.  You can find the HPET spec at
-	  <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
+	  <http://www.intel.com/hardwaredesign/hpetspec.htm>.
 
 
 config X86_PM_TIMER
 config X86_PM_TIMER
 	bool "PM timer"
 	bool "PM timer"

+ 2 - 2
arch/xtensa/kernel/pci.c

@@ -402,8 +402,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 	__pci_mmap_set_flags(dev, vma, mmap_state);
 	__pci_mmap_set_flags(dev, vma, mmap_state);
 	__pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
 	__pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
 
 
-	ret = io_remap_page_range(vma, vma->vm_start, vma->vm_pgoff<<PAGE_SHIFT,
-			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+	ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			         vma->vm_end - vma->vm_start,vma->vm_page_prot);
 
 
 	return ret;
 	return ret;
 }
 }

+ 1 - 1
arch/xtensa/kernel/platform.c

@@ -39,7 +39,7 @@ _F(int,  pcibios_fixup, (void), { return 0; });
 _F(int, get_rtc_time, (time_t* t), { return 0; });
 _F(int, get_rtc_time, (time_t* t), { return 0; });
 _F(int, set_rtc_time, (time_t t), { return 0; });
 _F(int, set_rtc_time, (time_t t), { return 0; });
 
 
-#if CONFIG_XTENSA_CALIBRATE_CCOUNT
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 _F(void, calibrate_ccount, (void),
 _F(void, calibrate_ccount, (void),
 {
 {
   printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");
   printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");

+ 1 - 1
arch/xtensa/kernel/process.c

@@ -457,7 +457,7 @@ int
 dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
 dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
 {
 {
 /* see asm/coprocessor.h for this magic number 16 */
 /* see asm/coprocessor.h for this magic number 16 */
-#if TOTAL_CPEXTRA_SIZE > 16
+#if XTENSA_CP_EXTRA_SIZE > 16
 	do_save_fpregs (r, regs, task);
 	do_save_fpregs (r, regs, task);
 
 
 	/*  For now, bit 16 means some extra state may be present:  */
 	/*  For now, bit 16 means some extra state may be present:  */

+ 1 - 1
arch/xtensa/kernel/setup.c

@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p)
 # endif
 # endif
 #endif
 #endif
 
 
-#if CONFIG_PCI
+#ifdef CONFIG_PCI
 	platform_pcibios_init();
 	platform_pcibios_init();
 #endif
 #endif
 }
 }

+ 1 - 1
arch/xtensa/kernel/signal.c

@@ -182,7 +182,7 @@ restore_cpextra (struct _cpstate *buf)
 
 
 	struct task_struct *tsk = current;
 	struct task_struct *tsk = current;
 	release_all_cp(tsk);
 	release_all_cp(tsk);
-	return __copy_from_user(tsk->thread.cpextra, buf, TOTAL_CPEXTRA_SIZE);
+	return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE);
 #endif
 #endif
 	return 0;
 	return 0;
 }
 }

+ 1 - 1
arch/xtensa/kernel/time.c

@@ -68,7 +68,7 @@ void __init time_init(void)
 	 * speed for the CALIBRATE.
 	 * speed for the CALIBRATE.
 	 */
 	 */
 
 
-#if CONFIG_XTENSA_CALIBRATE_CCOUNT
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 	printk("Calibrating CPU frequency ");
 	printk("Calibrating CPU frequency ");
 	platform_calibrate_ccount();
 	platform_calibrate_ccount();
 	printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
 	printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),

+ 1 - 1
arch/xtensa/mm/init.c

@@ -239,7 +239,7 @@ void __init mem_init(void)
 	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
 	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
 	highmemsize = 0;
 	highmemsize = 0;
 
 
-#if CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM
 #error HIGHGMEM not implemented in init.c
 #error HIGHGMEM not implemented in init.c
 #endif
 #endif
 
 

+ 2 - 1
drivers/acorn/char/pcf8583.c

@@ -23,12 +23,13 @@ static struct i2c_driver pcf8583_driver;
 
 
 static unsigned short ignore[] = { I2C_CLIENT_END };
 static unsigned short ignore[] = { I2C_CLIENT_END };
 static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
 static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
+static unsigned short *forces[] = { NULL };
 
 
 static struct i2c_client_address_data addr_data = {
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_addr,
 	.normal_i2c		= normal_addr,
 	.probe			= ignore,
 	.probe			= ignore,
 	.ignore			= ignore,
 	.ignore			= ignore,
-	.force			= ignore,
+	.forces			= forces,
 };
 };
 
 
 #define DAT(x) ((unsigned int)(x->dev.driver_data))
 #define DAT(x) ((unsigned int)(x->dev.driver_data))

+ 13 - 0
drivers/base/class.c

@@ -669,6 +669,7 @@ void class_device_destroy(struct class *cls, dev_t devt)
 int class_device_rename(struct class_device *class_dev, char *new_name)
 int class_device_rename(struct class_device *class_dev, char *new_name)
 {
 {
 	int error = 0;
 	int error = 0;
+	char *old_class_name = NULL, *new_class_name = NULL;
 
 
 	class_dev = class_device_get(class_dev);
 	class_dev = class_device_get(class_dev);
 	if (!class_dev)
 	if (!class_dev)
@@ -677,12 +678,24 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
 	pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
 	pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
 		 new_name);
 		 new_name);
 
 
+	if (class_dev->dev)
+		old_class_name = make_class_name(class_dev);
+
 	strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
 	strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
 
 
 	error = kobject_rename(&class_dev->kobj, new_name);
 	error = kobject_rename(&class_dev->kobj, new_name);
 
 
+	if (class_dev->dev) {
+		new_class_name = make_class_name(class_dev);
+		sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
+				  new_class_name);
+		sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
+	}
 	class_device_put(class_dev);
 	class_device_put(class_dev);
 
 
+	kfree(old_class_name);
+	kfree(new_class_name);
+
 	return error;
 	return error;
 }
 }
 
 

+ 3 - 0
drivers/base/dd.c

@@ -40,6 +40,9 @@
  */
  */
 void device_bind_driver(struct device * dev)
 void device_bind_driver(struct device * dev)
 {
 {
+	if (klist_node_attached(&dev->knode_driver))
+		return;
+
 	pr_debug("bound device '%s' to driver '%s'\n",
 	pr_debug("bound device '%s' to driver '%s'\n",
 		 dev->bus_id, dev->driver->name);
 		 dev->bus_id, dev->driver->name);
 	klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
 	klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);

+ 1 - 4
drivers/block/cciss.c

@@ -483,9 +483,6 @@ static int cciss_open(struct inode *inode, struct file *filep)
 	printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
 	printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
 #endif /* CCISS_DEBUG */ 
 #endif /* CCISS_DEBUG */ 
 
 
-	if (host->busy_initializing)
-		return -EBUSY;
-
 	if (host->busy_initializing || drv->busy_configuring)
 	if (host->busy_initializing || drv->busy_configuring)
 		return -EBUSY;
 		return -EBUSY;
 	/*
 	/*
@@ -2991,6 +2988,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
 	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
 
 
 	cciss_procinit(i);
 	cciss_procinit(i);
+	hba[i]->busy_initializing = 0;
 
 
 	for(j=0; j < NWD; j++) { /* mfm */
 	for(j=0; j < NWD; j++) { /* mfm */
 		drive_info_struct *drv = &(hba[i]->drv[j]);
 		drive_info_struct *drv = &(hba[i]->drv[j]);
@@ -3033,7 +3031,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 		add_disk(disk);
 		add_disk(disk);
 	}
 	}
 
 
-	hba[i]->busy_initializing = 0;
 	return(1);
 	return(1);
 
 
 clean4:
 clean4:

+ 0 - 38
drivers/block/ll_rw_blk.c

@@ -2373,44 +2373,6 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
 
 
 EXPORT_SYMBOL(blkdev_issue_flush);
 EXPORT_SYMBOL(blkdev_issue_flush);
 
 
-/**
- * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
- * @q:		device queue
- * @disk:	gendisk
- * @error_sector:	error offset
- *
- * Description:
- *    Devices understanding the SCSI command set, can use this function as
- *    a helper for issuing a cache flush. Note: driver is required to store
- *    the error offset (in case of error flushing) in ->sector of struct
- *    request.
- */
-int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
-			       sector_t *error_sector)
-{
-	struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
-	int ret;
-
-	rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
-	rq->sector = 0;
-	memset(rq->cmd, 0, sizeof(rq->cmd));
-	rq->cmd[0] = 0x35;
-	rq->cmd_len = 12;
-	rq->data = NULL;
-	rq->data_len = 0;
-	rq->timeout = 60 * HZ;
-
-	ret = blk_execute_rq(q, disk, rq, 0);
-
-	if (ret && error_sector)
-		*error_sector = rq->sector;
-
-	blk_put_request(rq);
-	return ret;
-}
-
-EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
-
 static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
 static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
 {
 {
 	int rw = rq_data_dir(rq);
 	int rw = rq_data_dir(rq);

+ 29 - 26
drivers/block/ub.c

@@ -172,7 +172,7 @@ struct bulk_cs_wrap {
  */
  */
 struct ub_dev;
 struct ub_dev;
 
 
-#define UB_MAX_REQ_SG	4
+#define UB_MAX_REQ_SG	9	/* cdrecord requires 32KB and maybe a header */
 #define UB_MAX_SECTORS 64
 #define UB_MAX_SECTORS 64
 
 
 /*
 /*
@@ -387,7 +387,7 @@ struct ub_dev {
 	struct bulk_cs_wrap work_bcs;
 	struct bulk_cs_wrap work_bcs;
 	struct usb_ctrlrequest work_cr;
 	struct usb_ctrlrequest work_cr;
 
 
-	int sg_stat[UB_MAX_REQ_SG+1];
+	int sg_stat[6];
 	struct ub_scsi_trace tr;
 	struct ub_scsi_trace tr;
 };
 };
 
 
@@ -525,12 +525,13 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
 	    "qlen %d qmax %d\n",
 	    "qlen %d qmax %d\n",
 	    sc->cmd_queue.qlen, sc->cmd_queue.qmax);
 	    sc->cmd_queue.qlen, sc->cmd_queue.qmax);
 	cnt += sprintf(page + cnt,
 	cnt += sprintf(page + cnt,
-	    "sg %d %d %d %d %d\n",
+	    "sg %d %d %d %d %d .. %d\n",
 	    sc->sg_stat[0],
 	    sc->sg_stat[0],
 	    sc->sg_stat[1],
 	    sc->sg_stat[1],
 	    sc->sg_stat[2],
 	    sc->sg_stat[2],
 	    sc->sg_stat[3],
 	    sc->sg_stat[3],
-	    sc->sg_stat[4]);
+	    sc->sg_stat[4],
+	    sc->sg_stat[5]);
 
 
 	list_for_each (p, &sc->luns) {
 	list_for_each (p, &sc->luns) {
 		lun = list_entry(p, struct ub_lun, link);
 		lun = list_entry(p, struct ub_lun, link);
@@ -835,7 +836,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
 		return -1;
 		return -1;
 	}
 	}
 	cmd->nsg = n_elem;
 	cmd->nsg = n_elem;
-	sc->sg_stat[n_elem]++;
+	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
 
 
 	/*
 	/*
 	 * build the command
 	 * build the command
@@ -891,7 +892,7 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
 		return -1;
 		return -1;
 	}
 	}
 	cmd->nsg = n_elem;
 	cmd->nsg = n_elem;
-	sc->sg_stat[n_elem]++;
+	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
 
 
 	memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
 	memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
 	cmd->cdb_len = rq->cmd_len;
 	cmd->cdb_len = rq->cmd_len;
@@ -1010,7 +1011,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	sc->last_pipe = sc->send_bulk_pipe;
 	sc->last_pipe = sc->send_bulk_pipe;
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe,
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe,
 	    bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc);
 	    bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc);
-	sc->work_urb.transfer_flags = 0;
 
 
 	/* Fill what we shouldn't be filling, because usb-storage did so. */
 	/* Fill what we shouldn't be filling, because usb-storage did so. */
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.actual_length = 0;
@@ -1019,7 +1019,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
 
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
 		/* XXX Clear stalls */
 		/* XXX Clear stalls */
-		printk("ub: cmd #%d start failed (%d)\n", cmd->tag, rc); /* P3 */
 		ub_complete(&sc->work_done);
 		ub_complete(&sc->work_done);
 		return rc;
 		return rc;
 	}
 	}
@@ -1190,11 +1189,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			return;
 			return;
 		}
 		}
 		if (urb->status != 0) {
 		if (urb->status != 0) {
-			printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */
 			goto Bad_End;
 			goto Bad_End;
 		}
 		}
 		if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
 		if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
-			printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */
 			/* XXX Must do reset here to unconfuse the device */
 			/* XXX Must do reset here to unconfuse the device */
 			goto Bad_End;
 			goto Bad_End;
 		}
 		}
@@ -1395,14 +1392,12 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
 	    page_address(sg->page) + sg->offset, sg->length,
 	    page_address(sg->page) + sg->offset, sg->length,
 	    ub_urb_complete, sc);
 	    ub_urb_complete, sc);
-	sc->work_urb.transfer_flags = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.status = 0;
 	sc->work_urb.status = 0;
 
 
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
 		/* XXX Clear stalls */
 		/* XXX Clear stalls */
-		printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
 		ub_complete(&sc->work_done);
 		ub_complete(&sc->work_done);
 		ub_state_done(sc, cmd, rc);
 		ub_state_done(sc, cmd, rc);
 		return;
 		return;
@@ -1442,7 +1437,6 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	sc->last_pipe = sc->recv_bulk_pipe;
 	sc->last_pipe = sc->recv_bulk_pipe;
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe,
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe,
 	    &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
 	    &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
-	sc->work_urb.transfer_flags = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.status = 0;
 	sc->work_urb.status = 0;
@@ -1563,7 +1557,6 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
 
 
 	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
 	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
 	    (unsigned char*) cr, NULL, 0, ub_urb_complete, sc);
 	    (unsigned char*) cr, NULL, 0, ub_urb_complete, sc);
-	sc->work_urb.transfer_flags = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.status = 0;
 	sc->work_urb.status = 0;
@@ -2000,17 +1993,16 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
 
 
 	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe,
 	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe,
 	    (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl);
 	    (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl);
-	sc->work_urb.transfer_flags = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.status = 0;
 	sc->work_urb.status = 0;
 
 
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
 		if (rc == -EPIPE) {
 		if (rc == -EPIPE) {
-			printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
+			printk("%s: Stall submitting GetMaxLUN, using 1 LUN\n",
 			     sc->name); /* P3 */
 			     sc->name); /* P3 */
 		} else {
 		} else {
-			printk(KERN_WARNING
+			printk(KERN_NOTICE
 			     "%s: Unable to submit GetMaxLUN (%d)\n",
 			     "%s: Unable to submit GetMaxLUN (%d)\n",
 			     sc->name, rc);
 			     sc->name, rc);
 		}
 		}
@@ -2028,6 +2020,18 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
 	del_timer_sync(&timer);
 	del_timer_sync(&timer);
 	usb_kill_urb(&sc->work_urb);
 	usb_kill_urb(&sc->work_urb);
 
 
+	if ((rc = sc->work_urb.status) < 0) {
+		if (rc == -EPIPE) {
+			printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
+			     sc->name); /* P3 */
+		} else {
+			printk(KERN_NOTICE
+			     "%s: Error at GetMaxLUN (%d)\n",
+			     sc->name, rc);
+		}
+		goto err_io;
+	}
+
 	if (sc->work_urb.actual_length != 1) {
 	if (sc->work_urb.actual_length != 1) {
 		printk("%s: GetMaxLUN returned %d bytes\n", sc->name,
 		printk("%s: GetMaxLUN returned %d bytes\n", sc->name,
 		    sc->work_urb.actual_length); /* P3 */
 		    sc->work_urb.actual_length); /* P3 */
@@ -2048,6 +2052,7 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
 	kfree(p);
 	kfree(p);
 	return nluns;
 	return nluns;
 
 
+err_io:
 err_submit:
 err_submit:
 	kfree(p);
 	kfree(p);
 err_alloc:
 err_alloc:
@@ -2080,7 +2085,6 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe)
 
 
 	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
 	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
 	    (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);
 	    (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);
-	sc->work_urb.transfer_flags = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.status = 0;
 	sc->work_urb.status = 0;
@@ -2213,8 +2217,10 @@ static int ub_probe(struct usb_interface *intf,
 	 * This is needed to clear toggles. It is a problem only if we do
 	 * This is needed to clear toggles. It is a problem only if we do
 	 * `rmmod ub && modprobe ub` without disconnects, but we like that.
 	 * `rmmod ub && modprobe ub` without disconnects, but we like that.
 	 */
 	 */
+#if 0 /* iPod Mini fails if we do this (big white iPod works) */
 	ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
 	ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
 	ub_probe_clear_stall(sc, sc->send_bulk_pipe);
 	ub_probe_clear_stall(sc, sc->send_bulk_pipe);
+#endif
 
 
 	/*
 	/*
 	 * The way this is used by the startup code is a little specific.
 	 * The way this is used by the startup code is a little specific.
@@ -2241,10 +2247,10 @@ static int ub_probe(struct usb_interface *intf,
 	for (i = 0; i < 3; i++) {
 	for (i = 0; i < 3; i++) {
 		if ((rc = ub_sync_getmaxlun(sc)) < 0) {
 		if ((rc = ub_sync_getmaxlun(sc)) < 0) {
 			/* 
 			/* 
-			 * Some devices (i.e. Iomega Zip100) need this --
-			 * apparently the bulk pipes get STALLed when the
-			 * GetMaxLUN request is processed.
-			 * XXX I have a ZIP-100, verify it does this.
+			 * This segment is taken from usb-storage. They say
+			 * that ZIP-100 needs this, but my own ZIP-100 works
+			 * fine without this.
+			 * Still, it does not seem to hurt anything.
 			 */
 			 */
 			if (rc == -EPIPE) {
 			if (rc == -EPIPE) {
 				ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
 				ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
@@ -2313,7 +2319,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
 	disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
 	disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
 	disk->fops = &ub_bd_fops;
 	disk->fops = &ub_bd_fops;
 	disk->private_data = lun;
 	disk->private_data = lun;
-	disk->driverfs_dev = &sc->intf->dev;	/* XXX Many to one ok? */
+	disk->driverfs_dev = &sc->intf->dev;
 
 
 	rc = -ENOMEM;
 	rc = -ENOMEM;
 	if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL)
 	if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL)
@@ -2466,9 +2472,6 @@ static int __init ub_init(void)
 {
 {
 	int rc;
 	int rc;
 
 
-	/* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n",
-			sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun));
-
 	if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
 	if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
 		goto err_regblkdev;
 		goto err_regblkdev;
 	devfs_mk_dir(DEVFS_NAME);
 	devfs_mk_dir(DEVFS_NAME);

+ 0 - 1
drivers/char/hpet.c

@@ -273,7 +273,6 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
 
 
 	vma->vm_flags |= VM_IO;
 	vma->vm_flags |= VM_IO;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	addr = __pa(addr);
 
 
 	if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
 	if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
 					PAGE_SIZE, vma->vm_page_prot)) {
 					PAGE_SIZE, vma->vm_page_prot)) {

+ 3 - 3
drivers/char/ipmi/ipmi_msghandler.c

@@ -2620,7 +2620,7 @@ void ipmi_smi_msg_received(ipmi_smi_t          intf,
 	spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
 	spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
 	if (!list_empty(&(intf->waiting_msgs))) {
 	if (!list_empty(&(intf->waiting_msgs))) {
 		list_add_tail(&(msg->link), &(intf->waiting_msgs));
 		list_add_tail(&(msg->link), &(intf->waiting_msgs));
-		spin_unlock(&(intf->waiting_msgs_lock));
+		spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
 		goto out_unlock;
 		goto out_unlock;
 	}
 	}
 	spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
 	spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
@@ -2629,9 +2629,9 @@ void ipmi_smi_msg_received(ipmi_smi_t          intf,
 	if (rv > 0) {
 	if (rv > 0) {
 		/* Could not handle the message now, just add it to a
 		/* Could not handle the message now, just add it to a
                    list to handle later. */
                    list to handle later. */
-		spin_lock(&(intf->waiting_msgs_lock));
+		spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
 		list_add_tail(&(msg->link), &(intf->waiting_msgs));
 		list_add_tail(&(msg->link), &(intf->waiting_msgs));
-		spin_unlock(&(intf->waiting_msgs_lock));
+		spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
 	} else if (rv == 0) {
 	} else if (rv == 0) {
 		ipmi_free_smi_msg(msg);
 		ipmi_free_smi_msg(msg);
 	}
 	}

+ 4 - 5
drivers/hwmon/Kconfig

@@ -418,12 +418,11 @@ config SENSORS_HDAPS
 	help
 	help
 	  This driver provides support for the IBM Hard Drive Active Protection
 	  This driver provides support for the IBM Hard Drive Active Protection
 	  System (hdaps), which provides an accelerometer and other misc. data.
 	  System (hdaps), which provides an accelerometer and other misc. data.
-	  Supported laptops include the IBM ThinkPad T41, T42, T43, and R51.
-	  The accelerometer data is readable via sysfs.
+	  ThinkPads starting with the R50, T41, and X40 are supported.  The
+	  accelerometer data is readable via sysfs.
 
 
-	  This driver also provides an input class device, allowing the
-	  laptop to act as a pinball machine-esque mouse.  This is off by
-	  default but enabled via sysfs or the module parameter "mousedev".
+	  This driver also provides an absolute input class device, allowing
+	  the laptop to act as a pinball machine-esque joystick.
 
 
 	  Say Y here if you have an applicable laptop and want to experience
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of hdaps.
 	  the awesome power of hdaps.

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików