Browse Source

Merge branch 'master' into upstream

Jeff Garzik 19 years ago
parent
commit
23930fa1ce
100 changed files with 4133 additions and 1181 deletions
  1. 7 0
      CREDITS
  2. 2 0
      Documentation/00-INDEX
  3. 22 14
      Documentation/crypto/api-intro.txt
  4. 0 2
      Documentation/kernel-parameters.txt
  5. 10 0
      Documentation/netlabel/00-INDEX
  6. 48 0
      Documentation/netlabel/cipso_ipv4.txt
  7. 791 0
      Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt
  8. 46 0
      Documentation/netlabel/introduction.txt
  9. 47 0
      Documentation/netlabel/lsm_interface.txt
  10. 38 0
      Documentation/networking/ip-sysctl.txt
  11. 14 0
      Documentation/networking/secid.txt
  12. 56 0
      Documentation/scsi/ChangeLog.arcmsr
  13. 30 23
      Documentation/scsi/aacraid.txt
  14. 574 0
      Documentation/scsi/arcmsr_spec.txt
  15. 484 0
      Documentation/scsi/libsas.txt
  16. 39 5
      Documentation/sound/alsa/ALSA-Configuration.txt
  17. 2 3
      Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
  18. 27 2
      MAINTAINERS
  19. 3 2
      Makefile
  20. 1 4
      arch/frv/Makefile
  21. 2 1
      arch/frv/boot/Makefile
  22. 3 0
      arch/i386/crypto/Makefile
  23. 2 1
      arch/i386/crypto/aes.c
  24. 335 0
      arch/i386/crypto/twofish-i586-asm.S
  25. 97 0
      arch/i386/crypto/twofish.c
  26. 38 1
      arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
  27. 123 63
      arch/i386/kernel/cpu/cpufreq/longhaul.c
  28. 38 10
      arch/i386/kernel/cpu/cpufreq/longhaul.h
  29. 41 1
      arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
  30. 32 0
      arch/i386/kernel/setup.c
  31. 0 5
      arch/i386/pci/common.c
  32. 10 24
      arch/i386/pci/mmconfig.c
  33. 1 2
      arch/i386/pci/pci.h
  34. 13 1
      arch/powerpc/Kconfig
  35. 16 0
      arch/powerpc/Kconfig.debug
  36. 6 1
      arch/powerpc/boot/Makefile
  37. 8 8
      arch/powerpc/boot/dts/mpc8349emds.dts
  38. 46 0
      arch/powerpc/boot/flatdevtree.h
  39. 129 121
      arch/powerpc/boot/main.c
  40. 131 13
      arch/powerpc/boot/of.c
  41. 100 0
      arch/powerpc/boot/ops.h
  42. 0 41
      arch/powerpc/boot/prom.h
  43. 2 2
      arch/powerpc/boot/stdio.c
  44. 8 0
      arch/powerpc/boot/stdio.h
  45. 23 0
      arch/powerpc/boot/types.h
  46. 1 1
      arch/powerpc/configs/maple_defconfig
  47. 2 2
      arch/powerpc/kernel/Makefile
  48. 16 1
      arch/powerpc/kernel/asm-offsets.c
  49. 12 12
      arch/powerpc/kernel/btext.c
  50. 26 77
      arch/powerpc/kernel/cpu_setup_ppc970.S
  51. 21 0
      arch/powerpc/kernel/cputable.c
  52. 1 1
      arch/powerpc/kernel/crash_dump.c
  53. 28 37
      arch/powerpc/kernel/dma_64.c
  54. 8 0
      arch/powerpc/kernel/entry_64.S
  55. 34 20
      arch/powerpc/kernel/head_64.S
  56. 3 3
      arch/powerpc/kernel/ibmebus.c
  57. 131 0
      arch/powerpc/kernel/io.c
  58. 5 0
      arch/powerpc/kernel/irq.c
  59. 18 17
      arch/powerpc/kernel/legacy_serial.c
  60. 19 11
      arch/powerpc/kernel/lparcfg.c
  61. 4 6
      arch/powerpc/kernel/machine_kexec_64.c
  62. 0 159
      arch/powerpc/kernel/misc.S
  63. 0 24
      arch/powerpc/kernel/of_device.c
  64. 14 1
      arch/powerpc/kernel/paca.c
  65. 21 18
      arch/powerpc/kernel/pci_32.c
  66. 16 51
      arch/powerpc/kernel/pci_64.c
  67. 7 6
      arch/powerpc/kernel/pci_dn.c
  68. 2 17
      arch/powerpc/kernel/ppc_ksyms.c
  69. 14 30
      arch/powerpc/kernel/prom.c
  70. 8 2
      arch/powerpc/kernel/prom_init.c
  71. 47 43
      arch/powerpc/kernel/prom_parse.c
  72. 13 12
      arch/powerpc/kernel/rtas-proc.c
  73. 28 19
      arch/powerpc/kernel/rtas.c
  74. 13 15
      arch/powerpc/kernel/rtas_pci.c
  75. 18 14
      arch/powerpc/kernel/setup-common.c
  76. 11 12
      arch/powerpc/kernel/setup_64.c
  77. 4 5
      arch/powerpc/kernel/sysfs.c
  78. 3 5
      arch/powerpc/kernel/time.c
  79. 25 0
      arch/powerpc/kernel/traps.c
  80. 8 8
      arch/powerpc/kernel/vio.c
  81. 0 1
      arch/powerpc/lib/Makefile
  82. 0 116
      arch/powerpc/lib/e2a.c
  83. 13 14
      arch/powerpc/lib/locks.c
  84. 14 17
      arch/powerpc/mm/numa.c
  85. 33 4
      arch/powerpc/mm/slb.c
  86. 1 0
      arch/powerpc/mm/tlb_64.c
  87. 2 2
      arch/powerpc/platforms/83xx/mpc834x_itx.c
  88. 2 2
      arch/powerpc/platforms/83xx/mpc834x_sys.c
  89. 2 2
      arch/powerpc/platforms/83xx/pci.c
  90. 2 2
      arch/powerpc/platforms/85xx/mpc85xx_ads.c
  91. 2 2
      arch/powerpc/platforms/85xx/mpc85xx_cds.c
  92. 2 2
      arch/powerpc/platforms/85xx/pci.c
  93. 2 2
      arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
  94. 2 2
      arch/powerpc/platforms/86xx/pci.c
  95. 1 0
      arch/powerpc/platforms/Makefile
  96. 3 5
      arch/powerpc/platforms/cell/cbe_regs.c
  97. 12 13
      arch/powerpc/platforms/cell/interrupt.c
  98. 12 10
      arch/powerpc/platforms/cell/iommu.c
  99. 0 4
      arch/powerpc/platforms/cell/setup.c
  100. 2 2
      arch/powerpc/platforms/cell/smp.c

+ 7 - 0
CREDITS

@@ -2384,6 +2384,13 @@ N: Thomas Molina
 E: tmolina@cablespeed.com
 E: tmolina@cablespeed.com
 D: bug fixes, documentation, minor hackery
 D: bug fixes, documentation, minor hackery
 
 
+N: Paul Moore
+E: paul.moore@hp.com
+D: NetLabel author
+S: Hewlett-Packard
+S: 110 Spit Brook Road
+S: Nashua, NH 03062
+
 N: James Morris
 N: James Morris
 E: jmorris@namei.org
 E: jmorris@namei.org
 W: http://namei.org/
 W: http://namei.org/

+ 2 - 0
Documentation/00-INDEX

@@ -184,6 +184,8 @@ mtrr.txt
 	- how to use PPro Memory Type Range Registers to increase performance.
 	- how to use PPro Memory Type Range Registers to increase performance.
 nbd.txt
 nbd.txt
 	- info on a TCP implementation of a network block device.
 	- info on a TCP implementation of a network block device.
+netlabel/
+	- directory with information on the NetLabel subsystem.
 networking/
 networking/
 	- directory with info on various aspects of networking with Linux.
 	- directory with info on various aspects of networking with Linux.
 nfsroot.txt
 nfsroot.txt

+ 22 - 14
Documentation/crypto/api-intro.txt

@@ -19,15 +19,14 @@ At the lowest level are algorithms, which register dynamically with the
 API.
 API.
 
 
 'Transforms' are user-instantiated objects, which maintain state, handle all
 'Transforms' are user-instantiated objects, which maintain state, handle all
-of the implementation logic (e.g. manipulating page vectors), provide an 
-abstraction to the underlying algorithms, and handle common logical 
-operations (e.g. cipher modes, HMAC for digests).  However, at the user 
+of the implementation logic (e.g. manipulating page vectors) and provide an 
+abstraction to the underlying algorithms.  However, at the user 
 level they are very simple.
 level they are very simple.
 
 
 Conceptually, the API layering looks like this:
 Conceptually, the API layering looks like this:
 
 
   [transform api]  (user interface)
   [transform api]  (user interface)
-  [transform ops]  (per-type logic glue e.g. cipher.c, digest.c)
+  [transform ops]  (per-type logic glue e.g. cipher.c, compress.c)
   [algorithm api]  (for registering algorithms)
   [algorithm api]  (for registering algorithms)
   
   
 The idea is to make the user interface and algorithm registration API
 The idea is to make the user interface and algorithm registration API
@@ -44,22 +43,27 @@ under development.
 Here's an example of how to use the API:
 Here's an example of how to use the API:
 
 
 	#include <linux/crypto.h>
 	#include <linux/crypto.h>
+	#include <linux/err.h>
+	#include <linux/scatterlist.h>
 	
 	
 	struct scatterlist sg[2];
 	struct scatterlist sg[2];
 	char result[128];
 	char result[128];
-	struct crypto_tfm *tfm;
+	struct crypto_hash *tfm;
+	struct hash_desc desc;
 	
 	
-	tfm = crypto_alloc_tfm("md5", 0);
-	if (tfm == NULL)
+	tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(tfm))
 		fail();
 		fail();
 		
 		
 	/* ... set up the scatterlists ... */
 	/* ... set up the scatterlists ... */
+
+	desc.tfm = tfm;
+	desc.flags = 0;
 	
 	
-	crypto_digest_init(tfm);
-	crypto_digest_update(tfm, &sg, 2);
-	crypto_digest_final(tfm, result);
+	if (crypto_hash_digest(&desc, &sg, 2, result))
+		fail();
 	
 	
-	crypto_free_tfm(tfm);
+	crypto_free_hash(tfm);
 
 
     
     
 Many real examples are available in the regression test module (tcrypt.c).
 Many real examples are available in the regression test module (tcrypt.c).
@@ -126,7 +130,7 @@ might already be working on.
 BUGS
 BUGS
 
 
 Send bug reports to:
 Send bug reports to:
-James Morris <jmorris@redhat.com>
+Herbert Xu <herbert@gondor.apana.org.au>
 Cc: David S. Miller <davem@redhat.com>
 Cc: David S. Miller <davem@redhat.com>
 
 
 
 
@@ -134,13 +138,14 @@ FURTHER INFORMATION
 
 
 For further patches and various updates, including the current TODO
 For further patches and various updates, including the current TODO
 list, see:
 list, see:
-http://samba.org/~jamesm/crypto/
+http://gondor.apana.org.au/~herbert/crypto/
 
 
 
 
 AUTHORS
 AUTHORS
 
 
 James Morris
 James Morris
 David S. Miller
 David S. Miller
+Herbert Xu
 
 
 
 
 CREDITS
 CREDITS
@@ -238,8 +243,11 @@ Anubis algorithm contributors:
 Tiger algorithm contributors:
 Tiger algorithm contributors:
   Aaron Grothe
   Aaron Grothe
 
 
+VIA PadLock contributors:
+  Michal Ludvig
+
 Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
 Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
 
 
 Please send any credits updates or corrections to:
 Please send any credits updates or corrections to:
-James Morris <jmorris@redhat.com>
+Herbert Xu <herbert@gondor.apana.org.au>
 
 

+ 0 - 2
Documentation/kernel-parameters.txt

@@ -1189,8 +1189,6 @@ running once the system is up.
 				Mechanism 2.
 				Mechanism 2.
 		nommconf	[IA-32,X86_64] Disable use of MMCONFIG for PCI
 		nommconf	[IA-32,X86_64] Disable use of MMCONFIG for PCI
 				Configuration
 				Configuration
-		mmconf		[IA-32,X86_64] Force MMCONFIG. This is useful
-				to override the builtin blacklist.
 		nomsi		[MSI] If the PCI_MSI kernel config parameter is
 		nomsi		[MSI] If the PCI_MSI kernel config parameter is
 				enabled, this kernel boot option can be used to
 				enabled, this kernel boot option can be used to
 				disable the use of MSI interrupts system-wide.
 				disable the use of MSI interrupts system-wide.

+ 10 - 0
Documentation/netlabel/00-INDEX

@@ -0,0 +1,10 @@
+00-INDEX
+	- this file.
+cipso_ipv4.txt
+	- documentation on the IPv4 CIPSO protocol engine.
+draft-ietf-cipso-ipsecurity-01.txt
+	- IETF draft of the CIPSO protocol, dated 16 July 1992.
+introduction.txt
+	- NetLabel introduction, READ THIS FIRST.
+lsm_interface.txt
+	- documentation on the NetLabel kernel security module API.

+ 48 - 0
Documentation/netlabel/cipso_ipv4.txt

@@ -0,0 +1,48 @@
+NetLabel CIPSO/IPv4 Protocol Engine
+==============================================================================
+Paul Moore, paul.moore@hp.com
+
+May 17, 2006
+
+ * Overview
+
+The NetLabel CIPSO/IPv4 protocol engine is based on the IETF Commercial IP
+Security Option (CIPSO) draft from July 16, 1992.  A copy of this draft can be
+found in this directory, consult '00-INDEX' for the filename.  While the IETF
+draft never made it to an RFC standard it has become a de-facto standard for
+labeled networking and is used in many trusted operating systems.
+
+ * Outbound Packet Processing
+
+The CIPSO/IPv4 protocol engine applies the CIPSO IP option to packets by
+adding the CIPSO label to the socket.  This causes all packets leaving the
+system through the socket to have the CIPSO IP option applied.  The socket's
+CIPSO label can be changed at any point in time, however, it is recommended
+that it is set upon the socket's creation.  The LSM can set the socket's CIPSO
+label by using the NetLabel security module API; if the NetLabel "domain" is
+configured to use CIPSO for packet labeling then a CIPSO IP option will be
+generated and attached to the socket.
+
+ * Inbound Packet Processing
+
+The CIPSO/IPv4 protocol engine validates every CIPSO IP option it finds at the
+IP layer without any special handling required by the LSM.  However, in order
+to decode and translate the CIPSO label on the packet the LSM must use the
+NetLabel security module API to extract the security attributes of the packet.
+This is typically done at the socket layer using the 'socket_sock_rcv_skb()'
+LSM hook.
+
+ * Label Translation
+
+The CIPSO/IPv4 protocol engine contains a mechanism to translate CIPSO security
+attributes such as sensitivity level and category to values which are
+appropriate for the host.  These mappings are defined as part of a CIPSO
+Domain Of Interpretation (DOI) definition and are configured through the
+NetLabel user space communication layer.  Each DOI definition can have a
+different security attribute mapping table.
+
+ * Label Translation Cache
+
+The NetLabel system provides a framework for caching security attribute
+mappings from the network labels to the corresponding LSM identifiers.  The
+CIPSO/IPv4 protocol engine supports this caching mechanism.

+ 791 - 0
Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt

@@ -0,0 +1,791 @@
+IETF CIPSO Working Group
+16 July, 1992
+
+
+
+                 COMMERCIAL IP SECURITY OPTION (CIPSO 2.2)
+
+
+
+1.    Status
+
+This Internet Draft provides the high level specification for a Commercial
+IP Security Option (CIPSO).  This draft reflects the version as approved by
+the CIPSO IETF Working Group.  Distribution of this memo is unlimited.
+
+This document is an Internet Draft.  Internet Drafts are working documents
+of the Internet Engineering Task Force (IETF), its Areas, and its Working
+Groups. Note that other groups may also distribute working documents as
+Internet Drafts.
+
+Internet Drafts are draft documents valid for a maximum of six months.
+Internet Drafts may be updated, replaced, or obsoleted by other documents
+at any time.  It is not appropriate to use Internet Drafts as reference
+material or to cite them other than as a "working draft" or "work in
+progress."
+
+Please check the I-D abstract listing contained in each Internet Draft
+directory to learn the current status of this or any other Internet Draft.
+
+
+
+
+2.    Background
+
+Currently the Internet Protocol includes two security options.  One of
+these options is the DoD Basic Security Option (BSO) (Type 130) which allows
+IP datagrams to be labeled with security classifications.  This option
+provides sixteen security classifications and a variable number of handling
+restrictions.  To handle additional security information, such as security
+categories or compartments, another security option (Type 133) exists and
+is referred to as the DoD Extended Security Option (ESO).  The values for
+the fixed fields within these two options are administered by the Defense
+Information Systems Agency (DISA).
+
+Computer vendors are now building commercial operating systems with
+mandatory access controls and multi-level security.  These systems are
+no longer built specifically for a particular group in the defense or
+intelligence communities.  They are generally available commercial systems
+for use in a variety of government and civil sector environments.
+
+The small number of ESO format codes can not support all the possible
+applications of a commercial security option.  The BSO and ESO were
+designed to only support the United States DoD.  CIPSO has been designed
+to support multiple security policies.  This Internet Draft provides the
+format and procedures required to support a Mandatory Access Control
+security policy.  Support for additional security policies shall be
+defined in future RFCs.
+
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 1]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+
+3.    CIPSO Format
+
+Option type: 134 (Class 0, Number 6, Copy on Fragmentation)
+Option length: Variable
+
+This option permits security related information to be passed between
+systems within a single Domain of Interpretation (DOI).  A DOI is a
+collection of systems which agree on the meaning of particular values
+in the security option.  An authority that has been assigned a DOI
+identifier will define a mapping between appropriate CIPSO field values
+and their human readable equivalent.  This authority will distribute that
+mapping to hosts within the authority's domain.  These mappings may be
+sensitive, therefore a DOI authority is not required to make these
+mappings available to anyone other than the systems that are included in
+the DOI.
+
+This option MUST be copied on fragmentation.  This option appears at most
+once in a datagram.  All multi-octet fields in the option are defined to be
+transmitted in network byte order.  The format of this option is as follows:
+
++----------+----------+------//------+-----------//---------+
+| 10000110 | LLLLLLLL | DDDDDDDDDDDD | TTTTTTTTTTTTTTTTTTTT |
++----------+----------+------//------+-----------//---------+
+
+  TYPE=134    OPTION    DOMAIN OF               TAGS
+              LENGTH    INTERPRETATION
+
+
+                Figure 1. CIPSO Format
+
+
+3.1    Type
+
+This field is 1 octet in length.  Its value is 134.
+
+
+3.2    Length
+
+This field is 1 octet in length.  It is the total length of the option
+including the type and length fields.  With the current IP header length
+restriction of 40 octets the value of this field MUST not exceed 40.
+
+
+3.3    Domain of Interpretation Identifier
+
+This field is an unsigned 32 bit integer.  The value 0 is reserved and MUST
+not appear as the DOI identifier in any CIPSO option.  Implementations
+should assume that the DOI identifier field is not aligned on any particular
+byte boundary.
+
+To conserve space in the protocol, security levels and categories are
+represented by numbers rather than their ASCII equivalent.  This requires
+a mapping table within CIPSO hosts to map these numbers to their
+corresponding ASCII representations.  Non-related groups of systems may
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 2]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+have their own unique mappings.  For example, one group of systems may
+use the number 5 to represent Unclassified while another group may use the
+number 1 to represent that same security level.  The DOI identifier is used
+to identify which mapping was used for the values within the option.
+
+
+3.4    Tag Types
+
+A common format for passing security related information is necessary
+for interoperability.  CIPSO uses sets of "tags" to contain the security
+information relevant to the data in the IP packet.  Each tag begins with
+a tag type identifier followed by the length of the tag and ends with the
+actual security information to be passed.  All multi-octet fields in a tag
+are defined to be transmitted in network byte order.  Like the DOI
+identifier field in the CIPSO header, implementations should assume that
+all tags, as well as fields within a tag, are not aligned on any particular
+octet boundary.   The tag types defined in this document contain alignment
+bytes to assist alignment of some information, however alignment can not
+be guaranteed if CIPSO is not the first IP option.
+
+CIPSO tag types 0 through 127 are reserved for defining standard tag
+formats.  Their definitions will be published in RFCs.  Tag types whose
+identifiers are greater than 127 are defined by the DOI authority and may
+only be meaningful in certain Domains of Interpretation.  For these tag
+types, implementations will require the DOI identifier as well as the tag
+number to determine the security policy and the format associated with the
+tag.  Use of tag types above 127 are restricted to closed networks where
+interoperability with other networks will not be an issue.  Implementations
+that support a tag type greater than 127 MUST support at least one DOI that
+requires only tag types 1 to 127.
+
+Tag type 0 is reserved. Tag types 1, 2, and 5 are defined in this
+Internet Draft.  Types 3 and 4 are reserved for work in progress.
+The standard format for all current and future CIPSO tags is shown below:
+
++----------+----------+--------//--------+
+| TTTTTTTT | LLLLLLLL | IIIIIIIIIIIIIIII |
++----------+----------+--------//--------+
+    TAG       TAG         TAG
+    TYPE      LENGTH      INFORMATION
+
+    Figure 2:  Standard Tag Format
+
+In the three tag types described in this document, the length and count
+restrictions are based on the current IP limitation of 40 octets for all
+IP options.  If the IP header is later expanded, then the length and count
+restrictions specified in this document may increase to use the full area
+provided for IP options.
+
+
+3.4.1    Tag Type Classes
+
+Tag classes consist of tag types that have common processing requirements
+and support the same security policy.  The three tags defined in this
+Internet Draft belong to the Mandatory Access Control (MAC) Sensitivity
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 3]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+class and support the MAC Sensitivity security policy.
+
+
+3.4.2    Tag Type 1
+
+This is referred to as the "bit-mapped" tag type.  Tag type 1 is included
+in the MAC Sensitivity tag type class.  The format of this tag type is as
+follows:
+
++----------+----------+----------+----------+--------//---------+
+| 00000001 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCC |
++----------+----------+----------+----------+--------//---------+
+
+    TAG       TAG      ALIGNMENT  SENSITIVITY    BIT MAP OF
+    TYPE      LENGTH   OCTET      LEVEL          CATEGORIES
+
+            Figure 3. Tag Type 1 Format
+
+
+3.4.2.1    Tag Type
+
+This field is 1 octet in length and has a value of 1.
+
+
+3.4.2.2    Tag Length
+
+This field is 1 octet in length.  It is the total length of the tag type
+including the type and length fields.  With the current IP header length
+restriction of 40 bytes the value within this field is between 4 and 34.
+
+
+3.4.2.3    Alignment Octet
+
+This field is 1 octet in length and always has the value of 0.  Its purpose
+is to align the category bitmap field on an even octet boundary.  This will
+speed many implementations including router implementations.
+
+
+3.4.2.4    Sensitivity Level
+
+This field is 1 octet in length.  Its value is from 0 to 255.  The values
+are ordered with 0 being the minimum value and 255 representing the maximum
+value.
+
+
+3.4.2.5    Bit Map of Categories
+
+The length of this field is variable and ranges from 0 to 30 octets.  This
+provides representation of categories 0 to 239.  The ordering of the bits
+is left to right or MSB to LSB.  For example category 0 is represented by
+the most significant bit of the first byte and category 15 is represented
+by the least significant bit of the second byte.  Figure 4 graphically
+shows this ordering.  Bit N is binary 1 if category N is part of the label
+for the datagram, and bit N is binary 0 if category N is not part of the
+label.  Except for the optimized tag 1 format described in the next section,
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 4]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+minimal encoding SHOULD be used resulting in no trailing zero octets in the
+category bitmap.
+
+        octet 0  octet 1  octet 2  octet 3  octet 4  octet 5
+        XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX . . .
+bit     01234567 89111111 11112222 22222233 33333333 44444444
+number             012345 67890123 45678901 23456789 01234567
+
+            Figure 4. Ordering of Bits in Tag 1 Bit Map
+
+
+3.4.2.6    Optimized Tag 1 Format
+
+Routers work most efficiently when processing fixed length fields.  To
+support these routers there is an optimized form of tag type 1.  The format
+does not change.  The only change is to the category bitmap which is set to
+a constant length of 10 octets.  Trailing octets required to fill out the 10
+octets are zero filled.  Ten octets, allowing for 80 categories, was chosen
+because it makes the total length of the CIPSO option 20 octets.  If CIPSO
+is the only option then the option will be full word aligned and additional
+filler octets will not be required.
+
+
+3.4.3    Tag Type 2
+
+This is referred to as the "enumerated" tag type.  It is used to describe
+large but sparsely populated sets of categories.  Tag type 2 is in the MAC
+Sensitivity tag type class.  The format of this tag type is as follows:
+
++----------+----------+----------+----------+-------------//-------------+
+| 00000010 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCCCCCCCCCCC |
++----------+----------+----------+----------+-------------//-------------+
+
+    TAG       TAG      ALIGNMENT  SENSITIVITY         ENUMERATED
+    TYPE      LENGTH   OCTET      LEVEL               CATEGORIES
+
+                Figure 5. Tag Type 2 Format
+
+
+3.4.3.1     Tag Type
+
+This field is one octet in length and has a value of 2.
+
+
+3.4.3.2    Tag Length
+
+This field is 1 octet in length. It is the total length of the tag type
+including the type and length fields.  With the current IP header length
+restriction of 40 bytes the value within this field is between 4 and 34.
+
+
+3.4.3.3    Alignment Octet
+
+This field is 1 octet in length and always has the value of 0.  Its purpose
+is to align the category field on an even octet boundary.  This will
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 5]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+speed many implementations including router implementations.
+
+
+3.4.3.4    Sensitivity Level
+
+This field is 1 octet in length. Its value is from 0 to 255.  The values
+are ordered with 0 being the minimum value and 255 representing the
+maximum value.
+
+
+3.4.3.5    Enumerated Categories
+
+In this tag, categories are represented by their actual value rather than
+by their position within a bit field.  The length of each category is 2
+octets.  Up to 15 categories may be represented by this tag.  Valid values
+for categories are 0 to 65534.  Category 65535 is not a valid category
+value.  The categories MUST be listed in ascending order within the tag.
+
+
+3.4.4    Tag Type 5
+
+This is referred to as the "range" tag type.  It is used to represent
+labels where all categories in a range, or set of ranges, are included
+in the sensitivity label.  Tag type 5 is in the MAC Sensitivity tag type
+class.  The format of this tag type is as follows:
+
++----------+----------+----------+----------+------------//-------------+
+| 00000101 | LLLLLLLL | 00000000 | LLLLLLLL |  Top/Bottom | Top/Bottom  |
++----------+----------+----------+----------+------------//-------------+
+
+    TAG       TAG      ALIGNMENT  SENSITIVITY        CATEGORY RANGES
+    TYPE      LENGTH   OCTET      LEVEL
+
+                     Figure 6. Tag Type 5 Format
+
+
+3.4.4.1     Tag Type
+
+This field is one octet in length and has a value of 5.
+
+
+3.4.4.2    Tag Length
+
+This field is 1 octet in length. It is the total length of the tag type
+including the type and length fields.  With the current IP header length
+restriction of 40 bytes the value within this field is between 4 and 34.
+
+
+3.4.4.3    Alignment Octet
+
+This field is 1 octet in length and always has the value of 0.  Its purpose
+is to align the category range field on an even octet boundary.  This will
+speed many implementations including router implementations.
+
+
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 6]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+3.4.4.4    Sensitivity Level
+
+This field is 1 octet in length. Its value is from 0 to 255.  The values
+are ordered with 0 being the minimum value and 255 representing the maximum
+value.
+
+
+3.4.4.5    Category Ranges
+
+A category range is a 4 octet field comprised of the 2 octet index of the
+highest numbered category followed by the 2 octet index of the lowest
+numbered category.  These range endpoints are inclusive within the range of
+categories.  All categories within a range are included in the sensitivity
+label.  This tag may contain a maximum of 7 category pairs.  The bottom
+category endpoint for the last pair in the tag MAY be omitted and SHOULD be
+assumed to be 0.  The ranges MUST be non-overlapping and be listed in
+descending order.  Valid values for categories are 0 to 65534.  Category
+65535 is not a valid category value.
+
+
+3.4.5     Minimum Requirements
+
+A CIPSO implementation MUST be capable of generating at least tag type 1 in
+the non-optimized form.  In addition, a CIPSO implementation MUST be able
+to receive any valid tag type 1 even those using the optimized tag type 1
+format.
+
+
+4.    Configuration Parameters
+
+The configuration parameters defined below are required for all CIPSO hosts,
+gateways, and routers that support multiple sensitivity labels.  A CIPSO
+host is defined to be the origination or destination system for an IP
+datagram.  A CIPSO gateway provides IP routing services between two or more
+IP networks and may be required to perform label translations between
+networks.  A CIPSO gateway may be an enhanced CIPSO host or it may just
+provide gateway services with no end system CIPSO capabilities.  A CIPSO
+router is a dedicated IP router that routes IP datagrams between two or more
+IP networks.
+
+An implementation of CIPSO on a host MUST have the capability to reject a
+datagram for reasons that the information contained can not be adequately
+protected by the receiving host or if acceptance may result in violation of
+the host or network security policy.  In addition, a CIPSO gateway or router
+MUST be able to reject datagrams going to networks that can not provide
+adequate protection or may violate the network's security policy.  To
+provide this capability the following minimal set of configuration
+parameters are required for CIPSO implementations:
+
+HOST_LABEL_MAX - This parameter contains the maximum sensitivity label that
+a CIPSO host is authorized to handle.  All datagrams that have a label
+greater than this maximum MUST be rejected by the CIPSO host.  This
+parameter does not apply to CIPSO gateways or routers.  This parameter need
+not be defined explicitly as it can be implicitly derived from the
+PORT_LABEL_MAX parameters for the associated interfaces.
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 7]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+
+HOST_LABEL_MIN - This parameter contains the minimum sensitivity label that
+a CIPSO host is authorized to handle.  All datagrams that have a label less
+than this minimum MUST be rejected by the CIPSO host.  This parameter does
+not apply to CIPSO gateways or routers.  This parameter need not be defined
+explicitly as it can be implicitly derived from the PORT_LABEL_MIN
+parameters for the associated interfaces.
+
+PORT_LABEL_MAX - This parameter contains the maximum sensitivity label for
+all datagrams that may exit a particular network interface port.  All
+outgoing datagrams that have a label greater than this maximum MUST be
+rejected by the CIPSO system.  The label within this parameter MUST be
+less than or equal to the label within the HOST_LABEL_MAX parameter.  This
+parameter does not apply to CIPSO hosts that support only one network port.
+
+PORT_LABEL_MIN - This parameter contains the minimum sensitivity label for
+all datagrams that may exit a particular network interface port.  All
+outgoing datagrams that have a label less than this minimum MUST be
+rejected by the CIPSO system.  The label within this parameter MUST be
+greater than or equal to the label within the HOST_LABEL_MIN parameter.
+This parameter does not apply to CIPSO hosts that support only one network
+port.
+
+PORT_DOI - This parameter is used to assign a DOI identifier value to a
+particular network interface port.  All CIPSO labels within datagrams
+going out this port MUST use the specified DOI identifier.  All CIPSO
+hosts and gateways MUST support either this parameter, the NET_DOI
+parameter, or the HOST_DOI parameter.
+
+NET_DOI - This parameter is used to assign a DOI identifier value to a
+particular IP network address.  All CIPSO labels within datagrams destined
+for the particular IP network MUST use the specified DOI identifier.  All
+CIPSO hosts and gateways MUST support either this parameter, the PORT_DOI
+parameter, or the HOST_DOI parameter.
+
+HOST_DOI - This parameter is used to assign a DOI identifier value to a
+particular IP host address.  All CIPSO labels within datagrams destined for
+the particular IP host will use the specified DOI identifier.  All CIPSO
+hosts and gateways MUST support either this parameter, the PORT_DOI
+parameter, or the NET_DOI parameter.
+
+This list represents the minimal set of configuration parameters required
+to be compliant.  Implementors are encouraged to add to this list to
+provide enhanced functionality and control.  For example, many security
+policies may require both incoming and outgoing datagrams be checked against
+the port and host label ranges.
+
+
+4.1    Port Range Parameters
+
+The labels represented by the PORT_LABEL_MAX and PORT_LABEL_MIN parameters
+MAY be in CIPSO or local format.  Some CIPSO systems, such as routers, may
+want to have the range parameters expressed in CIPSO format so that incoming
+labels do not have to be converted to a local format before being compared
+against the range.  If multiple DOIs are supported by one of these CIPSO
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 8]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+systems then multiple port range parameters would be needed, one set for
+each DOI supported on a particular port.
+
+The port range will usually represent the total set of labels that may
+exist on the logical network accessed through the corresponding network
+interface.  It may, however, represent a subset of these labels that are
+allowed to enter the CIPSO system.
+
+
+4.2    Single Label CIPSO Hosts
+
+CIPSO implementations that support only one label are not required to
+support the parameters described above.  These limited implementations are
+only required to support a NET_LABEL parameter.  This parameter contains
+the CIPSO label that may be inserted in datagrams that exit the host.  In
+addition, the host MUST reject any incoming datagram that has a label which
+is not equivalent to the NET_LABEL parameter.
+
+
+5.    Handling Procedures
+
+This section describes the processing requirements for incoming and
+outgoing IP datagrams.  Just providing the correct CIPSO label format
+is not enough.  Assumptions will be made by one system on how a
+receiving system will handle the CIPSO label.  Wrong assumptions may
+lead to non-interoperability or even a security incident.  The
+requirements described below represent the minimal set needed for
+interoperability and that provide users some level of confidence.
+Many other requirements could be added to increase user confidence,
+however at the risk of restricting creativity and limiting vendor
+participation.
+
+
+5.1    Input Procedures
+
+All datagrams received through a network port MUST have a security label
+associated with them, either contained in the datagram or assigned to the
+receiving port.  Without this label the host, gateway, or router will not
+have the information it needs to make security decisions.  This security
+label will be obtained from the CIPSO if the option is present in the
+datagram.  See section 4.1.2 for handling procedures for unlabeled
+datagrams.  This label will be compared against the PORT (if appropriate)
+and HOST configuration parameters defined in section 3.
+
+If any field within the CIPSO option, such as the DOI identifier, is not
+recognized the IP datagram is discarded and an ICMP "parameter problem"
+(type 12) is generated and returned.  The ICMP code field is set to "bad
+parameter" (code 0) and the pointer is set to the start of the CIPSO field
+that is unrecognized.
+
+If the contents of the CIPSO are valid but the security label is
+outside of the configured host or port label range, the datagram is
+discarded and an ICMP "destination unreachable" (type 3) is generated
+and returned.  The code field of the ICMP is set to "communication with
+destination network administratively prohibited" (code 9) or to
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 9]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+"communication with destination host administratively prohibited"
+(code 10).  The value of the code field used is dependent upon whether
+the originator of the ICMP message is acting as a CIPSO host or a CIPSO
+gateway.  The recipient of the ICMP message MUST be able to handle either
+value.  The same procedure is performed if a CIPSO can not be added to an
+IP packet because it is too large to fit in the IP options area.
+
+If the error is triggered by receipt of an ICMP message, the message
+is discarded and no response is permitted (consistent with general ICMP
+processing rules).
+
+
+5.1.1    Unrecognized tag types
+
+The default condition for any CIPSO implementation is that an
+unrecognized tag type MUST be treated as a "parameter problem" and
+handled as described in section 4.1.  A CIPSO implementation MAY allow
+the system administrator to identify tag types that may safely be
+ignored.  This capability is an allowable enhancement, not a
+requirement.
+
+
+5.1.2    Unlabeled Packets
+
+A network port may be configured to not require a CIPSO label for all
+incoming  datagrams.  For this configuration a CIPSO label must be
+assigned to that network port and associated with all unlabeled IP
+datagrams.  This capability might be used for single level networks or
+networks that have CIPSO and non-CIPSO hosts and the non-CIPSO hosts
+all operate at the same label.
+
+If a CIPSO option is required and none is found, the datagram is
+discarded and an ICMP "parameter problem" (type 12) is generated and
+returned to the originator of the datagram.  The code field of the ICMP
+is set to "option missing" (code 1) and the ICMP pointer is set to 134
+(the value of the option type for the missing CIPSO option).
+
+
+5.2    Output Procedures
+
+A CIPSO option MUST appear only once in a datagram.  Only one tag type
+from the MAC Sensitivity class MAY be included in a CIPSO option.  Given
+the current set of defined tag types, this means that CIPSO labels at
+first will contain only one tag.
+
+All datagrams leaving a CIPSO system MUST meet the following condition:
+
+        PORT_LABEL_MIN <= CIPSO label <= PORT_LABEL_MAX
+
+If this condition is not satisfied the datagram MUST be discarded.
+If the CIPSO system only supports one port, the HOST_LABEL_MIN and the
+HOST_LABEL_MAX parameters MAY be substituted for the PORT parameters in
+the above condition.
+
+The DOI identifier to be used for all outgoing datagrams is configured by
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 10]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+the administrator.  If port level DOI identifier assignment is used, then
+the PORT_DOI configuration parameter MUST contain the DOI identifier to
+use.  If network level DOI assignment is used, then the NET_DOI parameter
+MUST contain the DOI identifier to use.  And if host level DOI assignment
+is employed, then the HOST_DOI parameter MUST contain the DOI identifier
+to use.  A CIPSO implementation need only support one level of DOI
+assignment.
+
+
+5.3    DOI Processing Requirements
+
+A CIPSO implementation MUST support at least one DOI and SHOULD support
+multiple DOIs.  System and network administrators are cautioned to
+ensure that at least one DOI is common within an IP network to allow for
+broadcasting of IP datagrams.
+
+CIPSO gateways MUST be capable of translating a CIPSO option from one
+DOI to another when forwarding datagrams between networks.  For
+efficiency purposes this capability is only a desired feature for CIPSO
+routers.
+
+
+5.4    Label of ICMP Messages
+
+The CIPSO label to be used on all outgoing ICMP messages MUST be equivalent
+to the label of the datagram that caused the ICMP message.  If the ICMP was
+generated due to a problem associated with the original CIPSO label then the
+following responses are allowed:
+
+  a.  Use the CIPSO label of the original IP datagram
+  b.  Drop the original datagram with no return message generated
+
+In most cases these options will have the same effect.  If you can not
+interpret the label or if it is outside the label range of your host or
+interface then an ICMP message with the same label will probably not be
+able to exit the system.
+
+
+6.    Assignment of DOI Identifier Numbers                                   =
+
+Requests for assignment of a DOI identifier number should be addressed to
+the Internet Assigned Numbers Authority (IANA).
+
+
+7.    Acknowledgements
+
+Much of the material in this RFC is based on (and copied from) work
+done by Gary Winiger of Sun Microsystems and published as Commercial
+IP Security Option at the INTEROP 89, Commercial IPSO Workshop.
+
+
+8.    Author's Address
+
+To submit mail for distribution to members of the IETF CIPSO Working
+Group, send mail to: cipso@wdl1.wdl.loral.com.
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 11]
+
+
+
+CIPSO INTERNET DRAFT                                         16 July, 1992
+
+
+
+
+To be added to or deleted from this distribution, send mail to:
+cipso-request@wdl1.wdl.loral.com.
+
+
+9.    References
+
+RFC 1038, "Draft Revised IP Security Option", M. St. Johns, IETF, January
+1988.
+
+RFC 1108, "U.S. Department of Defense Security Options
+for the Internet Protocol", Stephen Kent, IAB, 1 March, 1991.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Internet Draft, Expires 15 Jan 93                                 [PAGE 12]
+
+
+

+ 46 - 0
Documentation/netlabel/introduction.txt

@@ -0,0 +1,46 @@
+NetLabel Introduction
+==============================================================================
+Paul Moore, paul.moore@hp.com
+
+August 2, 2006
+
+ * Overview
+
+NetLabel is a mechanism which can be used by kernel security modules to attach
+security attributes to outgoing network packets generated from user space
+applications and read security attributes from incoming network packets.  It
+is composed of three main components, the protocol engines, the communication
+layer, and the kernel security module API.
+
+ * Protocol Engines
+
+The protocol engines are responsible for both applying and retrieving the
+network packet's security attributes.  If any translation between the network
+security attributes and those on the host are required then the protocol
+engine will handle those tasks as well.  Other kernel subsystems should
+refrain from calling the protocol engines directly, instead they should use
+the NetLabel kernel security module API described below.
+
+Detailed information about each NetLabel protocol engine can be found in this
+directory, consult '00-INDEX' for filenames.
+
+ * Communication Layer
+
+The communication layer exists to allow NetLabel configuration and monitoring
+from user space.  The NetLabel communication layer uses a message based
+protocol built on top of the Generic NETLINK transport mechanism.  The exact
+formatting of these NetLabel messages as well as the Generic NETLINK family
+names can be found in the the 'net/netlabel/' directory as comments in the
+header files as well as in 'include/net/netlabel.h'.
+
+ * Security Module API
+
+The purpose of the NetLabel security module API is to provide a protocol
+independent interface to the underlying NetLabel protocol engines.  In addition
+to protocol independence, the security module API is designed to be completely
+LSM independent which should allow multiple LSMs to leverage the same code
+base.
+
+Detailed information about the NetLabel security module API can be found in the
+'include/net/netlabel.h' header file as well as the 'lsm_interface.txt' file
+found in this directory.

+ 47 - 0
Documentation/netlabel/lsm_interface.txt

@@ -0,0 +1,47 @@
+NetLabel Linux Security Module Interface
+==============================================================================
+Paul Moore, paul.moore@hp.com
+
+May 17, 2006
+
+ * Overview
+
+NetLabel is a mechanism which can set and retrieve security attributes from
+network packets.  It is intended to be used by LSM developers who want to make
+use of a common code base for several different packet labeling protocols.
+The NetLabel security module API is defined in 'include/net/netlabel.h' but a
+brief overview is given below.
+
+ * NetLabel Security Attributes
+
+Since NetLabel supports multiple different packet labeling protocols and LSMs
+it uses the concept of security attributes to refer to the packet's security
+labels.  The NetLabel security attributes are defined by the
+'netlbl_lsm_secattr' structure in the NetLabel header file.  Internally the
+NetLabel subsystem converts the security attributes to and from the correct
+low-level packet label depending on the NetLabel build time and run time
+configuration.  It is up to the LSM developer to translate the NetLabel
+security attributes into whatever security identifiers are in use for their
+particular LSM.
+
+ * NetLabel LSM Protocol Operations
+
+These are the functions which allow the LSM developer to manipulate the labels
+on outgoing packets as well as read the labels on incoming packets.  Functions
+exist to operate both on sockets as well as the sk_buffs directly.  These high
+level functions are translated into low level protocol operations based on how
+the administrator has configured the NetLabel subsystem.
+
+ * NetLabel Label Mapping Cache Operations
+
+Depending on the exact configuration, translation between the network packet
+label and the internal LSM security identifier can be time consuming.  The
+NetLabel label mapping cache is a caching mechanism which can be used to
+sidestep much of this overhead once a mapping has been established.  Once the
+LSM has received a packet, used NetLabel to decode it's security attributes,
+and translated the security attributes into a LSM internal identifier the LSM
+can use the NetLabel caching functions to associate the LSM internal
+identifier with the network packet's label.  This means that in the future
+when a incoming packet matches a cached value not only are the internal
+NetLabel translation mechanisms bypassed but the LSM translation mechanisms are
+bypassed as well which should result in a significant reduction in overhead.

+ 38 - 0
Documentation/networking/ip-sysctl.txt

@@ -375,6 +375,41 @@ tcp_slow_start_after_idle - BOOLEAN
 	be timed out after an idle period.
 	be timed out after an idle period.
 	Default: 1
 	Default: 1
 
 
+CIPSOv4 Variables:
+
+cipso_cache_enable - BOOLEAN
+	If set, enable additions to and lookups from the CIPSO label mapping
+	cache.  If unset, additions are ignored and lookups always result in a
+	miss.  However, regardless of the setting the cache is still
+	invalidated when required when means you can safely toggle this on and
+	off and the cache will always be "safe".
+	Default: 1
+
+cipso_cache_bucket_size - INTEGER
+	The CIPSO label cache consists of a fixed size hash table with each
+	hash bucket containing a number of cache entries.  This variable limits
+	the number of entries in each hash bucket; the larger the value the
+	more CIPSO label mappings that can be cached.  When the number of
+	entries in a given hash bucket reaches this limit adding new entries
+	causes the oldest entry in the bucket to be removed to make room.
+	Default: 10
+
+cipso_rbm_optfmt - BOOLEAN
+	Enable the "Optimized Tag 1 Format" as defined in section 3.4.2.6 of
+	the CIPSO draft specification (see Documentation/netlabel for details).
+	This means that when set the CIPSO tag will be padded with empty
+	categories in order to make the packet data 32-bit aligned.
+	Default: 0
+
+cipso_rbm_structvalid - BOOLEAN
+	If set, do a very strict check of the CIPSO option when
+	ip_options_compile() is called.  If unset, relax the checks done during
+	ip_options_compile().  Either way is "safe" as errors are caught else
+	where in the CIPSO processing code but setting this to 0 (False) should
+	result in less work (i.e. it should be faster) but could cause problems
+	with other implementations that require strict checking.
+	Default: 0
+
 IP Variables:
 IP Variables:
 
 
 ip_local_port_range - 2 INTEGERS
 ip_local_port_range - 2 INTEGERS
@@ -730,6 +765,9 @@ conf/all/forwarding - BOOLEAN
 
 
 	This referred to as global forwarding.
 	This referred to as global forwarding.
 
 
+proxy_ndp - BOOLEAN
+	Do proxy ndp.
+
 conf/interface/*:
 conf/interface/*:
 	Change special settings per interface.
 	Change special settings per interface.
 
 

+ 14 - 0
Documentation/networking/secid.txt

@@ -0,0 +1,14 @@
+flowi structure:
+
+The secid member in the flow structure is used in LSMs (e.g. SELinux) to indicate
+the label of the flow. This label of the flow is currently used in selecting
+matching labeled xfrm(s).
+
+If this is an outbound flow, the label is derived from the socket, if any, or
+the incoming packet this flow is being generated as a response to (e.g. tcp
+resets, timewait ack, etc.). It is also conceivable that the label could be
+derived from other sources such as process context, device, etc., in special
+cases, as may be appropriate.
+
+If this is an inbound flow, the label is derived from the IPSec security
+associations, if any, used by the packet.

+ 56 - 0
Documentation/scsi/ChangeLog.arcmsr

@@ -0,0 +1,56 @@
+**************************************************************************
+** History
+**
+**   REV#         DATE             NAME         DESCRIPTION
+** 1.00.00.00    3/31/2004       Erich Chen     First release
+** 1.10.00.04    7/28/2004       Erich Chen     modify for ioctl
+** 1.10.00.06    8/28/2004       Erich Chen     modify for 2.6.x
+** 1.10.00.08    9/28/2004       Erich Chen     modify for x86_64
+** 1.10.00.10   10/10/2004       Erich Chen     bug fix for SMP & ioctl
+** 1.20.00.00   11/29/2004       Erich Chen     bug fix with arcmsr_bus_reset when PHY error
+** 1.20.00.02   12/09/2004       Erich Chen     bug fix with over 2T bytes RAID Volume
+** 1.20.00.04    1/09/2005       Erich Chen     fits for Debian linux kernel version 2.2.xx
+** 1.20.00.05    2/20/2005       Erich Chen     cleanly as look like a Linux driver at 2.6.x
+**                                              thanks for peoples kindness comment
+**						Kornel Wieliczek
+**						Christoph Hellwig
+**						Adrian Bunk
+**						Andrew Morton
+**						Christoph Hellwig
+**						James Bottomley
+**						Arjan van de Ven
+** 1.20.00.06    3/12/2005       Erich Chen     fix with arcmsr_pci_unmap_dma "unsigned long" cast,
+**						modify PCCB POOL allocated by "dma_alloc_coherent"
+**						(Kornel Wieliczek's comment)
+** 1.20.00.07    3/23/2005       Erich Chen     bug fix with arcmsr_scsi_host_template_init
+**						occur segmentation fault,
+**						if RAID adapter does not on PCI slot
+**						and modprobe/rmmod this driver twice.
+**						bug fix enormous stack usage (Adrian Bunk's comment)
+** 1.20.00.08    6/23/2005       Erich Chen     bug fix with abort command,
+**						in case of heavy loading when sata cable
+**						working on low quality connection
+** 1.20.00.09    9/12/2005       Erich Chen     bug fix with abort command handling, firmware version check
+**						and firmware update notify for hardware bug fix
+** 1.20.00.10    9/23/2005       Erich Chen     enhance sysfs function for change driver's max tag Q number.
+**						add DMA_64BIT_MASK for backward compatible with all 2.6.x
+**						add some useful message for abort command
+**						add ioctl code 'ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE'
+**						customer can send this command for sync raid volume data
+** 1.20.00.11    9/29/2005       Erich Chen     by comment of Arjan van de Ven fix incorrect msleep redefine
+**						cast off sizeof(dma_addr_t) condition for 64bit pci_set_dma_mask
+** 1.20.00.12    9/30/2005       Erich Chen     bug fix with 64bit platform's ccbs using if over 4G system memory
+**						change 64bit pci_set_consistent_dma_mask into 32bit
+**						increcct adapter count if adapter initialize fail.
+**						miss edit at arcmsr_build_ccb....
+**						psge += sizeof(struct _SG64ENTRY *) =>
+**						psge += sizeof(struct _SG64ENTRY)
+**						64 bits sg entry would be incorrectly calculated
+**						thanks Kornel Wieliczek give me kindly notify
+**						and detail description
+** 1.20.00.13   11/15/2005       Erich Chen     scheduling pending ccb with FIFO
+**						change the architecture of arcmsr command queue list
+**						for linux standard list
+**						enable usage of pci message signal interrupt
+**						follow Randy.Danlup kindness suggestion cleanup this code
+**************************************************************************

+ 30 - 23
Documentation/scsi/aacraid.txt

@@ -11,38 +11,43 @@ the original).
 Supported Cards/Chipsets
 Supported Cards/Chipsets
 -------------------------
 -------------------------
 	PCI ID (pci.ids)	OEM	Product
 	PCI ID (pci.ids)	OEM	Product
-	9005:0285:9005:028a	Adaptec	2020ZCR (Skyhawk)
-	9005:0285:9005:028e	Adaptec	2020SA (Skyhawk)
-	9005:0285:9005:028b	Adaptec 2025ZCR (Terminator)
-	9005:0285:9005:028f	Adaptec 2025SA (Terminator)
-	9005:0285:9005:0286	Adaptec	2120S (Crusader)
-	9005:0286:9005:028d	Adaptec	2130S (Lancer)
+	9005:0283:9005:0283	Adaptec	Catapult (3210S with arc firmware)
+	9005:0284:9005:0284	Adaptec	Tomcat (3410S with arc firmware)
 	9005:0285:9005:0285	Adaptec	2200S (Vulcan)
 	9005:0285:9005:0285	Adaptec	2200S (Vulcan)
+	9005:0285:9005:0286	Adaptec	2120S (Crusader)
 	9005:0285:9005:0287	Adaptec	2200S (Vulcan-2m)
 	9005:0285:9005:0287	Adaptec	2200S (Vulcan-2m)
+	9005:0285:9005:0288	Adaptec	3230S (Harrier)
+	9005:0285:9005:0289	Adaptec	3240S (Tornado)
+	9005:0285:9005:028a	Adaptec	2020ZCR (Skyhawk)
+	9005:0285:9005:028b	Adaptec 2025ZCR (Terminator)
 	9005:0286:9005:028c	Adaptec	2230S (Lancer)
 	9005:0286:9005:028c	Adaptec	2230S (Lancer)
 	9005:0286:9005:028c	Adaptec	2230SLP (Lancer)
 	9005:0286:9005:028c	Adaptec	2230SLP (Lancer)
-	9005:0285:9005:0296	Adaptec	2240S (SabreExpress)
+	9005:0286:9005:028d	Adaptec	2130S (Lancer)
+	9005:0285:9005:028e	Adaptec	2020SA (Skyhawk)
+	9005:0285:9005:028f	Adaptec 2025SA (Terminator)
 	9005:0285:9005:0290	Adaptec	2410SA (Jaguar)
 	9005:0285:9005:0290	Adaptec	2410SA (Jaguar)
-	9005:0285:9005:0293	Adaptec 21610SA (Corsair-16)
 	9005:0285:103c:3227	Adaptec 2610SA (Bearcat HP release)
 	9005:0285:103c:3227	Adaptec 2610SA (Bearcat HP release)
+	9005:0285:9005:0293	Adaptec 21610SA (Corsair-16)
+	9005:0285:9005:0296	Adaptec	2240S (SabreExpress)
 	9005:0285:9005:0292	Adaptec	2810SA (Corsair-8)
 	9005:0285:9005:0292	Adaptec	2810SA (Corsair-8)
 	9005:0285:9005:0294	Adaptec	Prowler
 	9005:0285:9005:0294	Adaptec	Prowler
-	9005:0286:9005:029d	Adaptec	2420SA (Intruder HP release)
-	9005:0286:9005:029c	Adaptec	2620SA (Intruder)
-	9005:0286:9005:029b	Adaptec	2820SA (Intruder)
-	9005:0286:9005:02a7	Adaptec	2830SA (Skyray)
-	9005:0286:9005:02a8	Adaptec	2430SA (Skyray)
-	9005:0285:9005:0288	Adaptec	3230S (Harrier)
-	9005:0285:9005:0289	Adaptec	3240S (Tornado)
-	9005:0285:9005:0298	Adaptec	4000SAS (BlackBird)
 	9005:0285:9005:0297	Adaptec	4005SAS (AvonPark)
 	9005:0285:9005:0297	Adaptec	4005SAS (AvonPark)
+	9005:0285:9005:0298	Adaptec	4000SAS (BlackBird)
 	9005:0285:9005:0299	Adaptec	4800SAS (Marauder-X)
 	9005:0285:9005:0299	Adaptec	4800SAS (Marauder-X)
 	9005:0285:9005:029a	Adaptec	4805SAS (Marauder-E)
 	9005:0285:9005:029a	Adaptec	4805SAS (Marauder-E)
+	9005:0286:9005:029b	Adaptec	2820SA (Intruder)
+	9005:0286:9005:029c	Adaptec	2620SA (Intruder)
+	9005:0286:9005:029d	Adaptec	2420SA (Intruder HP release)
 	9005:0286:9005:02a2	Adaptec	3800SAS (Hurricane44)
 	9005:0286:9005:02a2	Adaptec	3800SAS (Hurricane44)
+	9005:0286:9005:02a7	Adaptec	3805SAS (Hurricane80)
+	9005:0286:9005:02a8	Adaptec	3400SAS (Hurricane40)
+	9005:0286:9005:02ac	Adaptec	1800SAS (Typhoon44)
+	9005:0286:9005:02b3	Adaptec	2400SAS (Hurricane40lm)
+	9005:0285:9005:02b5	Adaptec ASR5800 (Voodoo44)
+	9005:0285:9005:02b6	Adaptec ASR5805 (Voodoo80)
+	9005:0285:9005:02b7	Adaptec ASR5808 (Voodoo08)
 	1011:0046:9005:0364	Adaptec	5400S (Mustang)
 	1011:0046:9005:0364	Adaptec	5400S (Mustang)
 	1011:0046:9005:0365	Adaptec	5400S (Mustang)
 	1011:0046:9005:0365	Adaptec	5400S (Mustang)
-	9005:0283:9005:0283	Adaptec	Catapult (3210S with arc firmware)
-	9005:0284:9005:0284	Adaptec	Tomcat (3410S with arc firmware)
 	9005:0287:9005:0800	Adaptec	Themisto (Jupiter)
 	9005:0287:9005:0800	Adaptec	Themisto (Jupiter)
 	9005:0200:9005:0200	Adaptec	Themisto (Jupiter)
 	9005:0200:9005:0200	Adaptec	Themisto (Jupiter)
 	9005:0286:9005:0800	Adaptec	Callisto (Jupiter)
 	9005:0286:9005:0800	Adaptec	Callisto (Jupiter)
@@ -64,18 +69,20 @@ Supported Cards/Chipsets
 	9005:0285:9005:0290	IBM	ServeRAID 7t (Jaguar)
 	9005:0285:9005:0290	IBM	ServeRAID 7t (Jaguar)
 	9005:0285:1014:02F2	IBM	ServeRAID 8i (AvonPark)
 	9005:0285:1014:02F2	IBM	ServeRAID 8i (AvonPark)
 	9005:0285:1014:0312	IBM	ServeRAID 8i (AvonParkLite)
 	9005:0285:1014:0312	IBM	ServeRAID 8i (AvonParkLite)
-	9005:0286:1014:9580	IBM	ServeRAID 8k/8k-l8 (Aurora)
 	9005:0286:1014:9540	IBM	ServeRAID 8k/8k-l4 (AuroraLite)
 	9005:0286:1014:9540	IBM	ServeRAID 8k/8k-l4 (AuroraLite)
-	9005:0286:9005:029f	ICP	ICP9014R0 (Lancer)
+	9005:0286:1014:9580	IBM	ServeRAID 8k/8k-l8 (Aurora)
+	9005:0286:1014:034d	IBM	ServeRAID 8s (Hurricane)
 	9005:0286:9005:029e	ICP	ICP9024R0 (Lancer)
 	9005:0286:9005:029e	ICP	ICP9024R0 (Lancer)
+	9005:0286:9005:029f	ICP	ICP9014R0 (Lancer)
 	9005:0286:9005:02a0	ICP	ICP9047MA (Lancer)
 	9005:0286:9005:02a0	ICP	ICP9047MA (Lancer)
 	9005:0286:9005:02a1	ICP	ICP9087MA (Lancer)
 	9005:0286:9005:02a1	ICP	ICP9087MA (Lancer)
+	9005:0286:9005:02a3	ICP	ICP5445AU (Hurricane44)
 	9005:0286:9005:02a4	ICP	ICP9085LI (Marauder-X)
 	9005:0286:9005:02a4	ICP	ICP9085LI (Marauder-X)
 	9005:0286:9005:02a5	ICP	ICP5085BR (Marauder-E)
 	9005:0286:9005:02a5	ICP	ICP5085BR (Marauder-E)
-	9005:0286:9005:02a3	ICP	ICP5445AU (Hurricane44)
 	9005:0286:9005:02a6	ICP	ICP9067MA (Intruder-6)
 	9005:0286:9005:02a6	ICP	ICP9067MA (Intruder-6)
-	9005:0286:9005:02a9	ICP	ICP5087AU (Skyray)
-	9005:0286:9005:02aa	ICP	ICP5047AU (Skyray)
+	9005:0286:9005:02a9	ICP	ICP5085AU (Hurricane80)
+	9005:0286:9005:02aa	ICP	ICP5045AU (Hurricane40)
+	9005:0286:9005:02b4	ICP	ICP5045AL (Hurricane40lm)
 
 
 People
 People
 -------------------------
 -------------------------

+ 574 - 0
Documentation/scsi/arcmsr_spec.txt

@@ -0,0 +1,574 @@
+*******************************************************************************
+**                            ARECA FIRMWARE SPEC
+*******************************************************************************
+**	Usage of IOP331 adapter
+**	(All In/Out is in IOP331's view)
+**	1. Message 0 --> InitThread message and retrun code
+**	2. Doorbell is used for RS-232 emulation
+**		inDoorBell :    bit0 -- data in ready
+**			(DRIVER DATA WRITE OK)
+**				bit1 -- data out has been read
+**			(DRIVER DATA READ OK)
+**		outDooeBell:    bit0 -- data out ready
+**			(IOP331 DATA WRITE OK)
+**				bit1 -- data in has been read
+**			(IOP331 DATA READ OK)
+**	3. Index Memory Usage
+**	offset 0xf00 : for RS232 out (request buffer)
+**	offset 0xe00 : for RS232 in  (scratch buffer)
+**	offset 0xa00 : for inbound message code message_rwbuffer
+**			(driver send to IOP331)
+**	offset 0xa00 : for outbound message code message_rwbuffer
+**			(IOP331 send to driver)
+**	4. RS-232 emulation
+**		Currently 128 byte buffer is used
+**			1st uint32_t : Data length (1--124)
+**			Byte 4--127  : Max 124 bytes of data
+**	5. PostQ
+**	All SCSI Command must be sent through postQ:
+**	(inbound queue port)	Request frame must be 32 bytes aligned
+**	#bit27--bit31 => flag for post ccb
+**	#bit0--bit26  => real address (bit27--bit31) of post arcmsr_cdb
+**		bit31 :
+**			0 : 256 bytes frame
+**			1 : 512 bytes frame
+**		bit30 :
+**			0 : normal request
+**			1 : BIOS request
+**		bit29 : reserved
+**		bit28 : reserved
+**		bit27 : reserved
+**  ---------------------------------------------------------------------------
+**	(outbount queue port)	Request reply
+**	#bit27--bit31
+**		=> flag for reply
+**	#bit0--bit26
+**		=> real address (bit27--bit31) of reply arcmsr_cdb
+**			bit31 : must be 0 (for this type of reply)
+**			bit30 : reserved for BIOS handshake
+**			bit29 : reserved
+**			bit28 :
+**			0 : no error, ignore AdapStatus/DevStatus/SenseData
+**			1 : Error, error code in AdapStatus/DevStatus/SenseData
+**			bit27 : reserved
+**	6. BIOS request
+**		All BIOS request is the same with request from PostQ
+**		Except :
+**			Request frame is sent from configuration space
+**		offset: 0x78 : Request Frame (bit30 == 1)
+**		offset: 0x18 : writeonly to generate
+**					IRQ to IOP331
+**		Completion of request:
+**			(bit30 == 0, bit28==err flag)
+**	7. Definition of SGL entry (structure)
+**	8. Message1 Out - Diag Status Code (????)
+**	9. Message0 message code :
+**		0x00 : NOP
+**		0x01 : Get Config
+**		->offset 0xa00 :for outbound message code message_rwbuffer
+**		(IOP331 send to driver)
+**		Signature             0x87974060(4)
+**		Request len           0x00000200(4)
+**		numbers of queue      0x00000100(4)
+**		SDRAM Size            0x00000100(4)-->256 MB
+**		IDE Channels          0x00000008(4)
+**		vendor                40 bytes char
+**		model                  8 bytes char
+**		FirmVer               16 bytes char
+**		Device Map            16 bytes char
+**		FirmwareVersion DWORD <== Added for checking of
+**						new firmware capability
+**		0x02 : Set Config
+**		->offset 0xa00 :for inbound message code message_rwbuffer
+**		(driver send to IOP331)
+**		Signature             0x87974063(4)
+**		UPPER32 of Request Frame  (4)-->Driver Only
+**		0x03 : Reset (Abort all queued Command)
+**		0x04 : Stop Background Activity
+**		0x05 : Flush Cache
+**		0x06 : Start Background Activity
+**			(re-start if background is halted)
+**		0x07 : Check If Host Command Pending
+**			(Novell May Need This Function)
+**		0x08 : Set controller time
+**		->offset 0xa00 : for inbound message code message_rwbuffer
+**		(driver to IOP331)
+**		byte 0 : 0xaa <-- signature
+**		byte 1 : 0x55 <-- signature
+**		byte 2 : year (04)
+**		byte 3 : month (1..12)
+**		byte 4 : date (1..31)
+**		byte 5 : hour (0..23)
+**		byte 6 : minute (0..59)
+**		byte 7 : second (0..59)
+*******************************************************************************
+*******************************************************************************
+**      	RS-232 Interface for Areca Raid Controller
+**      The low level command interface is exclusive with VT100 terminal
+**  --------------------------------------------------------------------
+**      1. Sequence of command execution
+**  --------------------------------------------------------------------
+**    	(A) Header : 3 bytes sequence (0x5E, 0x01, 0x61)
+**    	(B) Command block : variable length of data including length,
+**    		command code, data and checksum byte
+**    	(C) Return data : variable length of data
+**  --------------------------------------------------------------------
+**    2. Command block
+**  --------------------------------------------------------------------
+**    	(A) 1st byte : command block length (low byte)
+**    	(B) 2nd byte : command block length (high byte)
+**                note ..command block length shouldn't > 2040 bytes,
+**    		length excludes these two bytes
+**    	(C) 3rd byte : command code
+**    	(D) 4th and following bytes : variable length data bytes
+**    		depends on command code
+**    	(E) last byte : checksum byte (sum of 1st byte until last data byte)
+**  --------------------------------------------------------------------
+**    3. Command code and associated data
+**  --------------------------------------------------------------------
+**    	The following are command code defined in raid controller Command
+**    	code 0x10--0x1? are used for system level management,
+**    	no password checking is needed and should be implemented in separate
+**    	well controlled utility and not for end user access.
+**    	Command code 0x20--0x?? always check the password,
+**    	password must be entered to enable these command.
+**    	enum
+**    	{
+**    		GUI_SET_SERIAL=0x10,
+**    		GUI_SET_VENDOR,
+**    		GUI_SET_MODEL,
+**    		GUI_IDENTIFY,
+**    		GUI_CHECK_PASSWORD,
+**    		GUI_LOGOUT,
+**    		GUI_HTTP,
+**    		GUI_SET_ETHERNET_ADDR,
+**    		GUI_SET_LOGO,
+**    		GUI_POLL_EVENT,
+**    		GUI_GET_EVENT,
+**    		GUI_GET_HW_MONITOR,
+**    		//    GUI_QUICK_CREATE=0x20, (function removed)
+**    		GUI_GET_INFO_R=0x20,
+**    		GUI_GET_INFO_V,
+**    		GUI_GET_INFO_P,
+**    		GUI_GET_INFO_S,
+**    		GUI_CLEAR_EVENT,
+**    		GUI_MUTE_BEEPER=0x30,
+**    		GUI_BEEPER_SETTING,
+**    		GUI_SET_PASSWORD,
+**    		GUI_HOST_INTERFACE_MODE,
+**    		GUI_REBUILD_PRIORITY,
+**    		GUI_MAX_ATA_MODE,
+**    		GUI_RESET_CONTROLLER,
+**    		GUI_COM_PORT_SETTING,
+**    		GUI_NO_OPERATION,
+**    		GUI_DHCP_IP,
+**    		GUI_CREATE_PASS_THROUGH=0x40,
+**    		GUI_MODIFY_PASS_THROUGH,
+**    		GUI_DELETE_PASS_THROUGH,
+**    		GUI_IDENTIFY_DEVICE,
+**    		GUI_CREATE_RAIDSET=0x50,
+**    		GUI_DELETE_RAIDSET,
+**    		GUI_EXPAND_RAIDSET,
+**    		GUI_ACTIVATE_RAIDSET,
+**    		GUI_CREATE_HOT_SPARE,
+**    		GUI_DELETE_HOT_SPARE,
+**    		GUI_CREATE_VOLUME=0x60,
+**    		GUI_MODIFY_VOLUME,
+**    		GUI_DELETE_VOLUME,
+**    		GUI_START_CHECK_VOLUME,
+**    		GUI_STOP_CHECK_VOLUME
+**    	};
+**    Command description :
+**    	GUI_SET_SERIAL : Set the controller serial#
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x10
+**    		byte 3          : password length (should be 0x0f)
+**    		byte 4-0x13     : should be "ArEcATecHnoLogY"
+**    		byte 0x14--0x23 : Serial number string (must be 16 bytes)
+**      GUI_SET_VENDOR : Set vendor string for the controller
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x11
+**    		byte 3          : password length (should be 0x08)
+**    		byte 4-0x13     : should be "ArEcAvAr"
+**    		byte 0x14--0x3B : vendor string (must be 40 bytes)
+**      GUI_SET_MODEL : Set the model name of the controller
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x12
+**    		byte 3          : password length (should be 0x08)
+**    		byte 4-0x13     : should be "ArEcAvAr"
+**    		byte 0x14--0x1B : model string (must be 8 bytes)
+**      GUI_IDENTIFY : Identify device
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x13
+**    		                  return "Areca RAID Subsystem "
+**      GUI_CHECK_PASSWORD : Verify password
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x14
+**    		byte 3          : password length
+**    		byte 4-0x??     : user password to be checked
+**      GUI_LOGOUT : Logout GUI (force password checking on next command)
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x15
+**      GUI_HTTP : HTTP interface (reserved for Http proxy service)(0x16)
+**
+**      GUI_SET_ETHERNET_ADDR : Set the ethernet MAC address
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x17
+**    		byte 3          : password length (should be 0x08)
+**    		byte 4-0x13     : should be "ArEcAvAr"
+**    		byte 0x14--0x19 : Ethernet MAC address (must be 6 bytes)
+**      GUI_SET_LOGO : Set logo in HTTP
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x18
+**    		byte 3          : Page# (0/1/2/3) (0xff --> clear OEM logo)
+**    		byte 4/5/6/7    : 0x55/0xaa/0xa5/0x5a
+**    		byte 8          : TITLE.JPG data (each page must be 2000 bytes)
+**    		                  note page0 1st 2 byte must be
+**    					actual length of the JPG file
+**      GUI_POLL_EVENT : Poll If Event Log Changed
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x19
+**      GUI_GET_EVENT : Read Event
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x1a
+**    		byte 3          : Event Page (0:1st page/1/2/3:last page)
+**      GUI_GET_HW_MONITOR : Get HW monitor data
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x1b
+**    		byte 3 			: # of FANs(example 2)
+**    		byte 4 			: # of Voltage sensor(example 3)
+**    		byte 5 			: # of temperature sensor(example 2)
+**    		byte 6 			: # of power
+**    		byte 7/8        : Fan#0 (RPM)
+**    		byte 9/10       : Fan#1
+**    		byte 11/12 		: Voltage#0 original value in *1000
+**    		byte 13/14 		: Voltage#0 value
+**    		byte 15/16 		: Voltage#1 org
+**    		byte 17/18 		: Voltage#1
+**    		byte 19/20 		: Voltage#2 org
+**    		byte 21/22 		: Voltage#2
+**    		byte 23 		: Temp#0
+**    		byte 24 		: Temp#1
+**    		byte 25 		: Power indicator (bit0 : power#0,
+**    						 bit1 : power#1)
+**    		byte 26 		: UPS indicator
+**      GUI_QUICK_CREATE : Quick create raid/volume set
+**    	    byte 0,1        : length
+**    	    byte 2          : command code 0x20
+**    	    byte 3/4/5/6    : raw capacity
+**    	    byte 7 			: raid level
+**    	    byte 8 			: stripe size
+**    	    byte 9 			: spare
+**    	    byte 10/11/12/13: device mask (the devices to create raid/volume)
+**    		This function is removed, application like
+**    		to implement quick create function
+**    	need to use GUI_CREATE_RAIDSET and GUI_CREATE_VOLUMESET function.
+**      GUI_GET_INFO_R : Get Raid Set Information
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x20
+**    		byte 3          : raidset#
+**    	typedef struct sGUI_RAIDSET
+**    	{
+**    		BYTE grsRaidSetName[16];
+**    		DWORD grsCapacity;
+**    		DWORD grsCapacityX;
+**    		DWORD grsFailMask;
+**    		BYTE grsDevArray[32];
+**    		BYTE grsMemberDevices;
+**    		BYTE grsNewMemberDevices;
+**    		BYTE grsRaidState;
+**    		BYTE grsVolumes;
+**    		BYTE grsVolumeList[16];
+**    		BYTE grsRes1;
+**    		BYTE grsRes2;
+**    		BYTE grsRes3;
+**    		BYTE grsFreeSegments;
+**    		DWORD grsRawStripes[8];
+**    		DWORD grsRes4;
+**    		DWORD grsRes5; //     Total to 128 bytes
+**    		DWORD grsRes6; //     Total to 128 bytes
+**    	} sGUI_RAIDSET, *pGUI_RAIDSET;
+**      GUI_GET_INFO_V : Get Volume Set Information
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x21
+**    		byte 3          : volumeset#
+**    	typedef struct sGUI_VOLUMESET
+**    	{
+**    		BYTE gvsVolumeName[16]; //     16
+**    		DWORD gvsCapacity;
+**    		DWORD gvsCapacityX;
+**    		DWORD gvsFailMask;
+**    		DWORD gvsStripeSize;
+**    		DWORD gvsNewFailMask;
+**    		DWORD gvsNewStripeSize;
+**    		DWORD gvsVolumeStatus;
+**    		DWORD gvsProgress; //     32
+**    		sSCSI_ATTR gvsScsi;
+**    		BYTE gvsMemberDisks;
+**    		BYTE gvsRaidLevel; //     8
+**    		BYTE gvsNewMemberDisks;
+**    		BYTE gvsNewRaidLevel;
+**    		BYTE gvsRaidSetNumber;
+**    		BYTE gvsRes0; //     4
+**    		BYTE gvsRes1[4]; //     64 bytes
+**    	} sGUI_VOLUMESET, *pGUI_VOLUMESET;
+**      GUI_GET_INFO_P : Get Physical Drive Information
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x22
+**    		byte 3          : drive # (from 0 to max-channels - 1)
+**    	typedef struct sGUI_PHY_DRV
+**    	{
+**    		BYTE gpdModelName[40];
+**    		BYTE gpdSerialNumber[20];
+**    		BYTE gpdFirmRev[8];
+**    		DWORD gpdCapacity;
+**    		DWORD gpdCapacityX; //     Reserved for expansion
+**    		BYTE gpdDeviceState;
+**    		BYTE gpdPioMode;
+**    		BYTE gpdCurrentUdmaMode;
+**    		BYTE gpdUdmaMode;
+**    		BYTE gpdDriveSelect;
+**    		BYTE gpdRaidNumber; //     0xff if not belongs to a raid set
+**    		sSCSI_ATTR gpdScsi;
+**    		BYTE gpdReserved[40]; //     Total to 128 bytes
+**    	} sGUI_PHY_DRV, *pGUI_PHY_DRV;
+**    	GUI_GET_INFO_S : Get System Information
+**      	byte 0,1        : length
+**      	byte 2          : command code 0x23
+**    	typedef struct sCOM_ATTR
+**    	{
+**    		BYTE comBaudRate;
+**    		BYTE comDataBits;
+**    		BYTE comStopBits;
+**    		BYTE comParity;
+**    		BYTE comFlowControl;
+**    	} sCOM_ATTR, *pCOM_ATTR;
+**    	typedef struct sSYSTEM_INFO
+**    	{
+**    		BYTE gsiVendorName[40];
+**    		BYTE gsiSerialNumber[16];
+**    		BYTE gsiFirmVersion[16];
+**    		BYTE gsiBootVersion[16];
+**    		BYTE gsiMbVersion[16];
+**    		BYTE gsiModelName[8];
+**    		BYTE gsiLocalIp[4];
+**    		BYTE gsiCurrentIp[4];
+**    		DWORD gsiTimeTick;
+**    		DWORD gsiCpuSpeed;
+**    		DWORD gsiICache;
+**    		DWORD gsiDCache;
+**    		DWORD gsiScache;
+**    		DWORD gsiMemorySize;
+**    		DWORD gsiMemorySpeed;
+**    		DWORD gsiEvents;
+**    		BYTE gsiMacAddress[6];
+**    		BYTE gsiDhcp;
+**    		BYTE gsiBeeper;
+**    		BYTE gsiChannelUsage;
+**    		BYTE gsiMaxAtaMode;
+**    		BYTE gsiSdramEcc; //     1:if ECC enabled
+**    		BYTE gsiRebuildPriority;
+**    		sCOM_ATTR gsiComA; //     5 bytes
+**    		sCOM_ATTR gsiComB; //     5 bytes
+**    		BYTE gsiIdeChannels;
+**    		BYTE gsiScsiHostChannels;
+**    		BYTE gsiIdeHostChannels;
+**    		BYTE gsiMaxVolumeSet;
+**    		BYTE gsiMaxRaidSet;
+**    		BYTE gsiEtherPort; //     1:if ether net port supported
+**    		BYTE gsiRaid6Engine; //     1:Raid6 engine supported
+**    		BYTE gsiRes[75];
+**    	} sSYSTEM_INFO, *pSYSTEM_INFO;
+**    	GUI_CLEAR_EVENT : Clear System Event
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x24
+**      GUI_MUTE_BEEPER : Mute current beeper
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x30
+**      GUI_BEEPER_SETTING : Disable beeper
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x31
+**    		byte 3          : 0->disable, 1->enable
+**      GUI_SET_PASSWORD : Change password
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x32
+**    		byte 3 			: pass word length ( must <= 15 )
+**    		byte 4 			: password (must be alpha-numerical)
+**    	GUI_HOST_INTERFACE_MODE : Set host interface mode
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x33
+**    		byte 3 			: 0->Independent, 1->cluster
+**      GUI_REBUILD_PRIORITY : Set rebuild priority
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x34
+**    		byte 3 			: 0/1/2/3 (low->high)
+**      GUI_MAX_ATA_MODE : Set maximum ATA mode to be used
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x35
+**    		byte 3 			: 0/1/2/3 (133/100/66/33)
+**      GUI_RESET_CONTROLLER : Reset Controller
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x36
+**                            *Response with VT100 screen (discard it)
+**      GUI_COM_PORT_SETTING : COM port setting
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x37
+**    		byte 3 			: 0->COMA (term port),
+**    					  1->COMB (debug port)
+**    		byte 4 			: 0/1/2/3/4/5/6/7
+**    			(1200/2400/4800/9600/19200/38400/57600/115200)
+**    		byte 5 			: data bit
+**    					(0:7 bit, 1:8 bit : must be 8 bit)
+**    		byte 6 			: stop bit (0:1, 1:2 stop bits)
+**    		byte 7 			: parity (0:none, 1:off, 2:even)
+**    		byte 8 			: flow control
+**    			(0:none, 1:xon/xoff, 2:hardware => must use none)
+**      GUI_NO_OPERATION : No operation
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x38
+**      GUI_DHCP_IP : Set DHCP option and local IP address
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x39
+**    		byte 3          : 0:dhcp disabled, 1:dhcp enabled
+**    		byte 4/5/6/7    : IP address
+**      GUI_CREATE_PASS_THROUGH : Create pass through disk
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x40
+**    		byte 3 			: device #
+**    		byte 4 			: scsi channel (0/1)
+**    		byte 5 			: scsi id (0-->15)
+**    		byte 6 			: scsi lun (0-->7)
+**    		byte 7 			: tagged queue (1 : enabled)
+**    		byte 8 			: cache mode (1 : enabled)
+**    		byte 9 			: max speed (0/1/2/3/4,
+**    			async/20/40/80/160 for scsi)
+**    			(0/1/2/3/4, 33/66/100/133/150 for ide  )
+**      GUI_MODIFY_PASS_THROUGH : Modify pass through disk
+**    		byte 0,1        : length
+**    		byte 2 			: command code 0x41
+**    		byte 3 			: device #
+**    		byte 4 			: scsi channel (0/1)
+**    		byte 5 			: scsi id (0-->15)
+**    		byte 6 			: scsi lun (0-->7)
+**    		byte 7 			: tagged queue (1 : enabled)
+**    		byte 8 			: cache mode (1 : enabled)
+**    		byte 9 			: max speed (0/1/2/3/4,
+**    					async/20/40/80/160 for scsi)
+**    			(0/1/2/3/4, 33/66/100/133/150 for ide  )
+**      GUI_DELETE_PASS_THROUGH : Delete pass through disk
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x42
+**    		byte 3          : device# to be deleted
+**      GUI_IDENTIFY_DEVICE : Identify Device
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x43
+**    		byte 3          : Flash Method
+**    				(0:flash selected, 1:flash not selected)
+**    		byte 4/5/6/7    : IDE device mask to be flashed
+**                           note .... no response data available
+**    	GUI_CREATE_RAIDSET : Create Raid Set
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x50
+**    		byte 3/4/5/6    : device mask
+**    		byte 7-22       : raidset name (if byte 7 == 0:use default)
+**      GUI_DELETE_RAIDSET : Delete Raid Set
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x51
+**    		byte 3          : raidset#
+**    	GUI_EXPAND_RAIDSET : Expand Raid Set
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x52
+**    		byte 3          : raidset#
+**    		byte 4/5/6/7    : device mask for expansion
+**    		byte 8/9/10     : (8:0 no change, 1 change, 0xff:terminate,
+**    				9:new raid level,
+**    				10:new stripe size
+**    				0/1/2/3/4/5->4/8/16/32/64/128K )
+**    		byte 11/12/13   : repeat for each volume in the raidset
+**      GUI_ACTIVATE_RAIDSET : Activate incomplete raid set
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x53
+**    		byte 3          : raidset#
+**      GUI_CREATE_HOT_SPARE : Create hot spare disk
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x54
+**    		byte 3/4/5/6    : device mask for hot spare creation
+**    	GUI_DELETE_HOT_SPARE : Delete hot spare disk
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x55
+**    		byte 3/4/5/6    : device mask for hot spare deletion
+**    	GUI_CREATE_VOLUME : Create volume set
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x60
+**    		byte 3          : raidset#
+**    		byte 4-19       : volume set name
+**    				(if byte4 == 0, use default)
+**    		byte 20-27      : volume capacity (blocks)
+**    		byte 28 		: raid level
+**    		byte 29 		: stripe size
+**    				(0/1/2/3/4/5->4/8/16/32/64/128K)
+**    		byte 30 		: channel
+**    		byte 31 		: ID
+**    		byte 32 		: LUN
+**    		byte 33 		: 1 enable tag
+**    		byte 34 		: 1 enable cache
+**    		byte 35 		: speed
+**    		(0/1/2/3/4->async/20/40/80/160 for scsi)
+**    		(0/1/2/3/4->33/66/100/133/150 for IDE  )
+**    		byte 36 		: 1 to select quick init
+**
+**    	GUI_MODIFY_VOLUME : Modify volume Set
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x61
+**    		byte 3          : volumeset#
+**    		byte 4-19       : new volume set name
+**    		(if byte4 == 0, not change)
+**    		byte 20-27      : new volume capacity (reserved)
+**    		byte 28 		: new raid level
+**    		byte 29 		: new stripe size
+**    		(0/1/2/3/4/5->4/8/16/32/64/128K)
+**    		byte 30 		: new channel
+**    		byte 31 		: new ID
+**    		byte 32 		: new LUN
+**    		byte 33 		: 1 enable tag
+**    		byte 34 		: 1 enable cache
+**    		byte 35 		: speed
+**    		(0/1/2/3/4->async/20/40/80/160 for scsi)
+**    		(0/1/2/3/4->33/66/100/133/150 for IDE  )
+**    	GUI_DELETE_VOLUME : Delete volume set
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x62
+**    		byte 3          : volumeset#
+**    	GUI_START_CHECK_VOLUME : Start volume consistency check
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x63
+**    		byte 3          : volumeset#
+**    	GUI_STOP_CHECK_VOLUME : Stop volume consistency check
+**    		byte 0,1        : length
+**    		byte 2          : command code 0x64
+** ---------------------------------------------------------------------
+**    4. Returned data
+** ---------------------------------------------------------------------
+**    	(A) Header          : 3 bytes sequence (0x5E, 0x01, 0x61)
+**    	(B) Length          : 2 bytes
+**    			(low byte 1st, excludes length and checksum byte)
+**    	(C) status or data  :
+**           <1> If length == 1 ==> 1 byte status code
+**    		#define GUI_OK                    0x41
+**    		#define GUI_RAIDSET_NOT_NORMAL    0x42
+**    		#define GUI_VOLUMESET_NOT_NORMAL  0x43
+**    		#define GUI_NO_RAIDSET            0x44
+**    		#define GUI_NO_VOLUMESET          0x45
+**    		#define GUI_NO_PHYSICAL_DRIVE     0x46
+**    		#define GUI_PARAMETER_ERROR       0x47
+**    		#define GUI_UNSUPPORTED_COMMAND   0x48
+**    		#define GUI_DISK_CONFIG_CHANGED   0x49
+**    		#define GUI_INVALID_PASSWORD      0x4a
+**    		#define GUI_NO_DISK_SPACE         0x4b
+**    		#define GUI_CHECKSUM_ERROR        0x4c
+**    		#define GUI_PASSWORD_REQUIRED     0x4d
+**           <2> If length > 1 ==>
+**    		data block returned from controller
+**    		and the contents depends on the command code
+**    	(E) Checksum        : checksum of length and status or data byte
+**************************************************************************

+ 484 - 0
Documentation/scsi/libsas.txt

@@ -0,0 +1,484 @@
+SAS Layer
+---------
+
+The SAS Layer is a management infrastructure which manages
+SAS LLDDs.  It sits between SCSI Core and SAS LLDDs.  The
+layout is as follows: while SCSI Core is concerned with
+SAM/SPC issues, and a SAS LLDD+sequencer is concerned with
+phy/OOB/link management, the SAS layer is concerned with:
+
+      * SAS Phy/Port/HA event management (LLDD generates,
+        SAS Layer processes),
+      * SAS Port management (creation/destruction),
+      * SAS Domain discovery and revalidation,
+      * SAS Domain device management,
+      * SCSI Host registration/unregistration,
+      * Device registration with SCSI Core (SAS) or libata
+        (SATA), and
+      * Expander management and exporting expander control
+        to user space.
+
+A SAS LLDD is a PCI device driver.  It is concerned with
+phy/OOB management, and vendor specific tasks and generates
+events to the SAS layer.
+
+The SAS Layer does most SAS tasks as outlined in the SAS 1.1
+spec.
+
+The sas_ha_struct describes the SAS LLDD to the SAS layer.
+Most of it is used by the SAS Layer but a few fields need to
+be initialized by the LLDDs.
+
+After initializing your hardware, from the probe() function
+you call sas_register_ha(). It will register your LLDD with
+the SCSI subsystem, creating a SCSI host and it will
+register your SAS driver with the sysfs SAS tree it creates.
+It will then return.  Then you enable your phys to actually
+start OOB (at which point your driver will start calling the
+notify_* event callbacks).
+
+Structure descriptions:
+
+struct sas_phy --------------------
+Normally this is statically embedded to your driver's
+phy structure:
+	struct my_phy {
+	       blah;
+	       struct sas_phy sas_phy;
+	       bleh;
+	};
+And then all the phys are an array of my_phy in your HA
+struct (shown below).
+
+Then as you go along and initialize your phys you also
+initialize the sas_phy struct, along with your own
+phy structure.
+
+In general, the phys are managed by the LLDD and the ports
+are managed by the SAS layer.  So the phys are initialized
+and updated by the LLDD and the ports are initialized and
+updated by the SAS layer.
+
+There is a scheme where the LLDD can RW certain fields,
+and the SAS layer can only read such ones, and vice versa.
+The idea is to avoid unnecessary locking.
+
+enabled -- must be set (0/1)
+id -- must be set [0,MAX_PHYS)
+class, proto, type, role, oob_mode, linkrate -- must be set
+oob_mode --  you set this when OOB has finished and then notify
+the SAS Layer.
+
+sas_addr -- this normally points to an array holding the sas
+address of the phy, possibly somewhere in your my_phy
+struct.
+
+attached_sas_addr -- set this when you (LLDD) receive an
+IDENTIFY frame or a FIS frame, _before_ notifying the SAS
+layer.  The idea is that sometimes the LLDD may want to fake
+or provide a different SAS address on that phy/port and this
+allows it to do this.  At best you should copy the sas
+address from the IDENTIFY frame or maybe generate a SAS
+address for SATA directly attached devices.  The Discover
+process may later change this.
+
+frame_rcvd -- this is where you copy the IDENTIFY/FIS frame
+when you get it; you lock, copy, set frame_rcvd_size and
+unlock the lock, and then call the event.  It is a pointer
+since there's no way to know your hw frame size _exactly_,
+so you define the actual array in your phy struct and let
+this pointer point to it.  You copy the frame from your
+DMAable memory to that area holding the lock.
+
+sas_prim -- this is where primitives go when they're
+received.  See sas.h. Grab the lock, set the primitive,
+release the lock, notify.
+
+port -- this points to the sas_port if the phy belongs
+to a port -- the LLDD only reads this. It points to the
+sas_port this phy is part of.  Set by the SAS Layer.
+
+ha -- may be set; the SAS layer sets it anyway.
+
+lldd_phy -- you should set this to point to your phy so you
+can find your way around faster when the SAS layer calls one
+of your callbacks and passes you a phy.  If the sas_phy is
+embedded you can also use container_of -- whatever you
+prefer.
+
+
+struct sas_port --------------------
+The LLDD doesn't set any fields of this struct -- it only
+reads them.  They should be self explanatory.
+
+phy_mask is 32 bit, this should be enough for now, as I
+haven't heard of a HA having more than 8 phys.
+
+lldd_port -- I haven't found use for that -- maybe other
+LLDD who wish to have internal port representation can make
+use of this.
+
+
+struct sas_ha_struct --------------------
+It normally is statically declared in your own LLDD
+structure describing your adapter:
+struct my_sas_ha {
+       blah;
+       struct sas_ha_struct sas_ha;
+       struct my_phy phys[MAX_PHYS];
+       struct sas_port sas_ports[MAX_PHYS]; /* (1) */
+       bleh;
+};
+
+(1) If your LLDD doesn't have its own port representation.
+
+What needs to be initialized (sample function given below).
+
+pcidev
+sas_addr -- since the SAS layer doesn't want to mess with
+	 memory allocation, etc, this points to statically
+	 allocated array somewhere (say in your host adapter
+	 structure) and holds the SAS address of the host
+	 adapter as given by you or the manufacturer, etc.
+sas_port
+sas_phy -- an array of pointers to structures. (see
+	note above on sas_addr).
+	These must be set.  See more notes below.
+num_phys -- the number of phys present in the sas_phy array,
+	 and the number of ports present in the sas_port
+	 array.  There can be a maximum num_phys ports (one per
+	 port) so we drop the num_ports, and only use
+	 num_phys.
+
+The event interface:
+
+	/* LLDD calls these to notify the class of an event. */
+	void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
+	void (*notify_port_event)(struct sas_phy *, enum port_event);
+	void (*notify_phy_event)(struct sas_phy *, enum phy_event);
+
+When sas_register_ha() returns, those are set and can be
+called by the LLDD to notify the SAS layer of such events
+the SAS layer.
+
+The port notification:
+
+	/* The class calls these to notify the LLDD of an event. */
+	void (*lldd_port_formed)(struct sas_phy *);
+	void (*lldd_port_deformed)(struct sas_phy *);
+
+If the LLDD wants notification when a port has been formed
+or deformed it sets those to a function satisfying the type.
+
+A SAS LLDD should also implement at least one of the Task
+Management Functions (TMFs) described in SAM:
+
+	/* Task Management Functions. Must be called from process context. */
+	int (*lldd_abort_task)(struct sas_task *);
+	int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
+	int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
+	int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
+	int (*lldd_I_T_nexus_reset)(struct domain_device *);
+	int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
+	int (*lldd_query_task)(struct sas_task *);
+
+For more information please read SAM from T10.org.
+
+Port and Adapter management:
+
+	/* Port and Adapter management */
+	int (*lldd_clear_nexus_port)(struct sas_port *);
+	int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
+
+A SAS LLDD should implement at least one of those.
+
+Phy management:
+
+	/* Phy management */
+	int (*lldd_control_phy)(struct sas_phy *, enum phy_func);
+
+lldd_ha -- set this to point to your HA struct. You can also
+use container_of if you embedded it as shown above.
+
+A sample initialization and registration function
+can look like this (called last thing from probe())
+*but* before you enable the phys to do OOB:
+
+static int register_sas_ha(struct my_sas_ha *my_ha)
+{
+	int i;
+	static struct sas_phy   *sas_phys[MAX_PHYS];
+	static struct sas_port  *sas_ports[MAX_PHYS];
+
+	my_ha->sas_ha.sas_addr = &my_ha->sas_addr[0];
+
+	for (i = 0; i < MAX_PHYS; i++) {
+		sas_phys[i] = &my_ha->phys[i].sas_phy;
+		sas_ports[i] = &my_ha->sas_ports[i];
+	}
+
+	my_ha->sas_ha.sas_phy  = sas_phys;
+	my_ha->sas_ha.sas_port = sas_ports;
+	my_ha->sas_ha.num_phys = MAX_PHYS;
+
+	my_ha->sas_ha.lldd_port_formed = my_port_formed;
+
+	my_ha->sas_ha.lldd_dev_found = my_dev_found;
+	my_ha->sas_ha.lldd_dev_gone = my_dev_gone;
+
+	my_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num; (1)
+
+	my_ha->sas_ha.lldd_queue_size = ha_can_queue;
+	my_ha->sas_ha.lldd_execute_task = my_execute_task;
+
+	my_ha->sas_ha.lldd_abort_task     = my_abort_task;
+	my_ha->sas_ha.lldd_abort_task_set = my_abort_task_set;
+	my_ha->sas_ha.lldd_clear_aca      = my_clear_aca;
+	my_ha->sas_ha.lldd_clear_task_set = my_clear_task_set;
+	my_ha->sas_ha.lldd_I_T_nexus_reset= NULL; (2)
+	my_ha->sas_ha.lldd_lu_reset       = my_lu_reset;
+	my_ha->sas_ha.lldd_query_task     = my_query_task;
+
+	my_ha->sas_ha.lldd_clear_nexus_port = my_clear_nexus_port;
+	my_ha->sas_ha.lldd_clear_nexus_ha = my_clear_nexus_ha;
+
+	my_ha->sas_ha.lldd_control_phy = my_control_phy;
+
+	return sas_register_ha(&my_ha->sas_ha);
+}
+
+(1) This is normally a LLDD parameter, something of the
+lines of a task collector.  What it tells the SAS Layer is
+whether the SAS layer should run in Direct Mode (default:
+value 0 or 1) or Task Collector Mode (value greater than 1).
+
+In Direct Mode, the SAS Layer calls Execute Task as soon as
+it has a command to send to the SDS, _and_ this is a single
+command, i.e. not linked.
+
+Some hardware (e.g. aic94xx) has the capability to DMA more
+than one task at a time (interrupt) from host memory.  Task
+Collector Mode is an optional feature for HAs which support
+this in their hardware.  (Again, it is completely optional
+even if your hardware supports it.)
+
+In Task Collector Mode, the SAS Layer would do _natural_
+coalescing of tasks and at the appropriate moment it would
+call your driver to DMA more than one task in a single HA
+interrupt. DMBS may want to use this by insmod/modprobe
+setting the lldd_max_execute_num to something greater than
+1.
+
+(2) SAS 1.1 does not define I_T Nexus Reset TMF.
+
+Events
+------
+
+Events are _the only way_ a SAS LLDD notifies the SAS layer
+of anything.  There is no other method or way a LLDD to tell
+the SAS layer of anything happening internally or in the SAS
+domain.
+
+Phy events:
+	PHYE_LOSS_OF_SIGNAL, (C)
+	PHYE_OOB_DONE,
+	PHYE_OOB_ERROR,      (C)
+	PHYE_SPINUP_HOLD.
+
+Port events, passed on a _phy_:
+	PORTE_BYTES_DMAED,      (M)
+	PORTE_BROADCAST_RCVD,   (E)
+	PORTE_LINK_RESET_ERR,   (C)
+	PORTE_TIMER_EVENT,      (C)
+	PORTE_HARD_RESET.
+
+Host Adapter event:
+	HAE_RESET
+
+A SAS LLDD should be able to generate
+	- at least one event from group C (choice),
+	- events marked M (mandatory) are mandatory (only one),
+	- events marked E (expander) if it wants the SAS layer
+	  to handle domain revalidation (only one such).
+	- Unmarked events are optional.
+
+Meaning:
+
+HAE_RESET -- when your HA got internal error and was reset.
+
+PORTE_BYTES_DMAED -- on receiving an IDENTIFY/FIS frame
+PORTE_BROADCAST_RCVD -- on receiving a primitive
+PORTE_LINK_RESET_ERR -- timer expired, loss of signal, loss
+of DWS, etc. (*)
+PORTE_TIMER_EVENT -- DWS reset timeout timer expired (*)
+PORTE_HARD_RESET -- Hard Reset primitive received.
+
+PHYE_LOSS_OF_SIGNAL -- the device is gone (*)
+PHYE_OOB_DONE -- OOB went fine and oob_mode is valid
+PHYE_OOB_ERROR -- Error while doing OOB, the device probably
+got disconnected. (*)
+PHYE_SPINUP_HOLD -- SATA is present, COMWAKE not sent.
+
+(*) should set/clear the appropriate fields in the phy,
+    or alternatively call the inlined sas_phy_disconnected()
+    which is just a helper, from their tasklet.
+
+The Execute Command SCSI RPC:
+
+	int (*lldd_execute_task)(struct sas_task *, int num,
+				 unsigned long gfp_flags);
+
+Used to queue a task to the SAS LLDD.  @task is the tasks to
+be executed.  @num should be the number of tasks being
+queued at this function call (they are linked listed via
+task::list), @gfp_mask should be the gfp_mask defining the
+context of the caller.
+
+This function should implement the Execute Command SCSI RPC,
+or if you're sending a SCSI Task as linked commands, you
+should also use this function.
+
+That is, when lldd_execute_task() is called, the command(s)
+go out on the transport *immediately*.  There is *no*
+queuing of any sort and at any level in a SAS LLDD.
+
+The use of task::list is two-fold, one for linked commands,
+the other discussed below.
+
+It is possible to queue up more than one task at a time, by
+initializing the list element of struct sas_task, and
+passing the number of tasks enlisted in this manner in num.
+
+Returns: -SAS_QUEUE_FULL, -ENOMEM, nothing was queued;
+	 0, the task(s) were queued.
+
+If you want to pass num > 1, then either
+A) you're the only caller of this function and keep track
+   of what you've queued to the LLDD, or
+B) you know what you're doing and have a strategy of
+   retrying.
+
+As opposed to queuing one task at a time (function call),
+batch queuing of tasks, by having num > 1, greatly
+simplifies LLDD code, sequencer code, and _hardware design_,
+and has some performance advantages in certain situations
+(DBMS).
+
+The LLDD advertises if it can take more than one command at
+a time at lldd_execute_task(), by setting the
+lldd_max_execute_num parameter (controlled by "collector"
+module parameter in aic94xx SAS LLDD).
+
+You should leave this to the default 1, unless you know what
+you're doing.
+
+This is a function of the LLDD, to which the SAS layer can
+cater to.
+
+int lldd_queue_size
+	The host adapter's queue size.  This is the maximum
+number of commands the lldd can have pending to domain
+devices on behalf of all upper layers submitting through
+lldd_execute_task().
+
+You really want to set this to something (much) larger than
+1.
+
+This _really_ has absolutely nothing to do with queuing.
+There is no queuing in SAS LLDDs.
+
+struct sas_task {
+	dev -- the device this task is destined to
+	list -- must be initialized (INIT_LIST_HEAD)
+	task_proto -- _one_ of enum sas_proto
+	scatter -- pointer to scatter gather list array
+	num_scatter -- number of elements in scatter
+	total_xfer_len -- total number of bytes expected to be transfered
+	data_dir -- PCI_DMA_...
+	task_done -- callback when the task has finished execution
+};
+
+When an external entity, entity other than the LLDD or the
+SAS Layer, wants to work with a struct domain_device, it
+_must_ call kobject_get() when getting a handle on the
+device and kobject_put() when it is done with the device.
+
+This does two things:
+     A) implements proper kfree() for the device;
+     B) increments/decrements the kref for all players:
+     domain_device
+	all domain_device's ... (if past an expander)
+	    port
+		host adapter
+		     pci device
+			 and up the ladder, etc.
+
+DISCOVERY
+---------
+
+The sysfs tree has the following purposes:
+    a) It shows you the physical layout of the SAS domain at
+       the current time, i.e. how the domain looks in the
+       physical world right now.
+    b) Shows some device parameters _at_discovery_time_.
+
+This is a link to the tree(1) program, very useful in
+viewing the SAS domain:
+ftp://mama.indstate.edu/linux/tree/
+I expect user space applications to actually create a
+graphical interface of this.
+
+That is, the sysfs domain tree doesn't show or keep state if
+you e.g., change the meaning of the READY LED MEANING
+setting, but it does show you the current connection status
+of the domain device.
+
+Keeping internal device state changes is responsibility of
+upper layers (Command set drivers) and user space.
+
+When a device or devices are unplugged from the domain, this
+is reflected in the sysfs tree immediately, and the device(s)
+removed from the system.
+
+The structure domain_device describes any device in the SAS
+domain.  It is completely managed by the SAS layer.  A task
+points to a domain device, this is how the SAS LLDD knows
+where to send the task(s) to.  A SAS LLDD only reads the
+contents of the domain_device structure, but it never creates
+or destroys one.
+
+Expander management from User Space
+-----------------------------------
+
+In each expander directory in sysfs, there is a file called
+"smp_portal".  It is a binary sysfs attribute file, which
+implements an SMP portal (Note: this is *NOT* an SMP port),
+to which user space applications can send SMP requests and
+receive SMP responses.
+
+Functionality is deceptively simple:
+
+1. Build the SMP frame you want to send. The format and layout
+   is described in the SAS spec.  Leave the CRC field equal 0.
+open(2)
+2. Open the expander's SMP portal sysfs file in RW mode.
+write(2)
+3. Write the frame you built in 1.
+read(2)
+4. Read the amount of data you expect to receive for the frame you built.
+   If you receive different amount of data you expected to receive,
+   then there was some kind of error.
+close(2)
+All this process is shown in detail in the function do_smp_func()
+and its callers, in the file "expander_conf.c".
+
+The kernel functionality is implemented in the file
+"sas_expander.c".
+
+The program "expander_conf.c" implements this. It takes one
+argument, the sysfs file name of the SMP portal to the
+expander, and gives expander information, including routing
+tables.
+
+The SMP portal gives you complete control of the expander,
+so please be careful.

+ 39 - 5
Documentation/sound/alsa/ALSA-Configuration.txt

@@ -758,6 +758,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
     position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
     single_cmd  - Use single immediate commands to communicate with
     single_cmd  - Use single immediate commands to communicate with
 		codecs (for debugging only)
 		codecs (for debugging only)
+    disable_msi - Disable Message Signaled Interrupt (MSI)
 
 
     This module supports one card and autoprobe.
     This module supports one card and autoprobe.
 
 
@@ -778,11 +779,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	  6stack-digout	6-jack with a SPDIF out
 	  6stack-digout	6-jack with a SPDIF out
 	  w810		3-jack
 	  w810		3-jack
 	  z71v		3-jack (HP shared SPDIF)
 	  z71v		3-jack (HP shared SPDIF)
-	  asus		3-jack
+	  asus		3-jack (ASUS Mobo)
+	  asus-w1v	ASUS W1V
+	  asus-dig	ASUS with SPDIF out
+	  asus-dig2	ASUS with SPDIF out (using GPIO2)
 	  uniwill	3-jack
 	  uniwill	3-jack
 	  F1734		2-jack
 	  F1734		2-jack
 	  lg		LG laptop (m1 express dual)
 	  lg		LG laptop (m1 express dual)
-	  lg-lw		LG LW20 laptop
+	  lg-lw		LG LW20/LW25 laptop
+	  tcl		TCL S700
+	  clevo		Clevo laptops (m520G, m665n)
 	  test		for testing/debugging purpose, almost all controls can be
 	  test		for testing/debugging purpose, almost all controls can be
 			adjusted.  Appearing only when compiled with
 			adjusted.  Appearing only when compiled with
 			$CONFIG_SND_DEBUG=y
 			$CONFIG_SND_DEBUG=y
@@ -790,6 +796,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
 	ALC260
 	ALC260
 	  hp		HP machines
 	  hp		HP machines
+	  hp-3013	HP machines (3013-variant)
 	  fujitsu	Fujitsu S7020
 	  fujitsu	Fujitsu S7020
 	  acer		Acer TravelMate
 	  acer		Acer TravelMate
 	  basic		fixed pin assignment (old default model)
 	  basic		fixed pin assignment (old default model)
@@ -797,24 +804,32 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
 	ALC262
 	ALC262
 	  fujitsu	Fujitsu Laptop
 	  fujitsu	Fujitsu Laptop
+	  hp-bpc	HP xw4400/6400/8400/9400 laptops
+	  benq		Benq ED8
 	  basic		fixed pin assignment w/o SPDIF
 	  basic		fixed pin assignment w/o SPDIF
 	  auto		auto-config reading BIOS (default)
 	  auto		auto-config reading BIOS (default)
 
 
 	ALC882/885
 	ALC882/885
 	  3stack-dig	3-jack with SPDIF I/O
 	  3stack-dig	3-jack with SPDIF I/O
 	  6stck-dig	6-jack digital with SPDIF I/O
 	  6stck-dig	6-jack digital with SPDIF I/O
+	  arima		Arima W820Di1
 	  auto		auto-config reading BIOS (default)
 	  auto		auto-config reading BIOS (default)
 
 
 	ALC883/888
 	ALC883/888
 	  3stack-dig	3-jack with SPDIF I/O
 	  3stack-dig	3-jack with SPDIF I/O
 	  6stack-dig	6-jack digital with SPDIF I/O
 	  6stack-dig	6-jack digital with SPDIF I/O
-	  6stack-dig-demo  6-stack digital for Intel demo board
+	  3stack-6ch    3-jack 6-channel
+	  3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
+	  6stack-dig-demo  6-jack digital for Intel demo board
+	  acer		Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
 	  auto		auto-config reading BIOS (default)
 	  auto		auto-config reading BIOS (default)
 
 
 	ALC861/660
 	ALC861/660
 	  3stack	3-jack
 	  3stack	3-jack
 	  3stack-dig	3-jack with SPDIF I/O
 	  3stack-dig	3-jack with SPDIF I/O
 	  6stack-dig	6-jack with SPDIF I/O
 	  6stack-dig	6-jack with SPDIF I/O
+	  3stack-660	3-jack (for ALC660)
+	  uniwill-m31	Uniwill M31 laptop
 	  auto		auto-config reading BIOS (default)
 	  auto		auto-config reading BIOS (default)
 
 
 	CMI9880
 	CMI9880
@@ -843,10 +858,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	  3stack-dig	ditto with SPDIF
 	  3stack-dig	ditto with SPDIF
 	  laptop	3-jack with hp-jack automute
 	  laptop	3-jack with hp-jack automute
 	  laptop-dig	ditto with SPDIF
 	  laptop-dig	ditto with SPDIF
-	  auto		auto-confgi reading BIOS (default)
+	  auto		auto-config reading BIOS (default)
+
+	STAC9200/9205/9220/9221/9254
+	  ref		Reference board
+	  3stack	D945 3stack
+	  5stack	D945 5stack + SPDIF
 
 
-	STAC7661(?)
+	STAC9227/9228/9229/927x
+	  ref		Reference board
+	  3stack	D965 3stack
+	  5stack	D965 5stack + SPDIF
+
+	STAC9872
 	  vaio		Setup for VAIO FE550G/SZ110
 	  vaio		Setup for VAIO FE550G/SZ110
+	  vaio-ar Setup for VAIO AR
 
 
     If the default configuration doesn't work and one of the above
     If the default configuration doesn't work and one of the above
     matches with your device, report it together with the PCI
     matches with your device, report it together with the PCI
@@ -1213,6 +1239,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     
     
     Module supports only 1 card.  This module has no enable option.
     Module supports only 1 card.  This module has no enable option.
 
 
+  Module snd-mts64
+  ----------------
+
+    Module for Ego Systems (ESI) Miditerminal 4140
+
+    This module supports multiple devices.
+    Requires parport (CONFIG_PARPORT).
+
   Module snd-nm256
   Module snd-nm256
   ----------------
   ----------------
 
 

+ 2 - 3
Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl

@@ -1054,9 +1054,8 @@
 
 
       <para>
       <para>
       For a device which allows hotplugging, you can use
       For a device which allows hotplugging, you can use
-      <function>snd_card_free_in_thread</function>.  This one will
-      postpone the destruction and wait in a kernel-thread until all
-      devices are closed.
+      <function>snd_card_free_when_closed</function>.  This one will
+      postpone the destruction until all devices are closed.
       </para>
       </para>
 
 
     </section>
     </section>

+ 27 - 2
MAINTAINERS

@@ -298,6 +298,14 @@ L:	info-linux@geode.amd.com
 W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
 W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
 S:	Supported
 S:	Supported
 
 
+AMSO1100 RNIC DRIVER
+P:	Tom Tucker
+M:	tom@opengridcomputing.com
+P:	Steve Wise
+M:	swise@opengridcomputing.com
+L:	openib-general@openib.org
+S:	Maintained
+
 AOA (Apple Onboard Audio) ALSA DRIVER
 AOA (Apple Onboard Audio) ALSA DRIVER
 P:	Johannes Berg
 P:	Johannes Berg
 M:	johannes@sipsolutions.net
 M:	johannes@sipsolutions.net
@@ -991,6 +999,14 @@ EFS FILESYSTEM
 W:	http://aeschi.ch.eu.org/efs/
 W:	http://aeschi.ch.eu.org/efs/
 S:	Orphan
 S:	Orphan
 
 
+EHCA (IBM GX bus InfiniBand adapter) DRIVER:
+P:	Hoang-Nam Nguyen
+M:	hnguyen@de.ibm.com
+P:	Christoph Raisch
+M:	raisch@de.ibm.com
+L:	openib-general@openib.org
+S:	Supported
+
 EMU10K1 SOUND DRIVER
 EMU10K1 SOUND DRIVER
 P:	James Courtier-Dutton
 P:	James Courtier-Dutton
 M:	James@superbug.demon.co.uk
 M:	James@superbug.demon.co.uk
@@ -1783,6 +1799,13 @@ W:     http://www.penguinppc.org/
 L:     linuxppc-embedded@ozlabs.org
 L:     linuxppc-embedded@ozlabs.org
 S:     Maintained
 S:     Maintained
 
 
+LINUX FOR POWERPC PA SEMI PWRFICIENT
+P:	Olof Johansson
+M:	olof@lixom.net
+W:	http://www.pasemi.com/
+L:	linuxppc-dev@ozlabs.org
+S:	Supported
+
 LLC (802.2)
 LLC (802.2)
 P:	Arnaldo Carvalho de Melo
 P:	Arnaldo Carvalho de Melo
 M:	acme@conectiva.com.br
 M:	acme@conectiva.com.br
@@ -2445,6 +2468,8 @@ S:      Maintained
 S390
 S390
 P:	Martin Schwidefsky
 P:	Martin Schwidefsky
 M:	schwidefsky@de.ibm.com
 M:	schwidefsky@de.ibm.com
+P:	Heiko Carstens
+M:	heiko.carstens@de.ibm.com
 M:	linux390@de.ibm.com
 M:	linux390@de.ibm.com
 L:	linux-390@vm.marist.edu
 L:	linux-390@vm.marist.edu
 W:	http://www.ibm.com/developerworks/linux/linux390/
 W:	http://www.ibm.com/developerworks/linux/linux390/
@@ -2459,8 +2484,8 @@ W:	http://www.ibm.com/developerworks/linux/linux390/
 S:	Supported
 S:	Supported
 
 
 S390 ZFCP DRIVER
 S390 ZFCP DRIVER
-P:	Andreas Herrmann
-M:	aherrman@de.ibm.com
+P:	Swen Schillig
+M:	swen@vnet.ibm.com
 M:	linux390@de.ibm.com
 M:	linux390@de.ibm.com
 L:	linux-390@vm.marist.edu
 L:	linux-390@vm.marist.edu
 W:	http://www.ibm.com/developerworks/linux/linux390/
 W:	http://www.ibm.com/developerworks/linux/linux390/

+ 3 - 2
Makefile

@@ -1,8 +1,8 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 18
 SUBLEVEL = 18
-EXTRAVERSION = -rc7
-NAME=Crazed Snow-Weasel
+EXTRAVERSION =
+NAME=Avast! A bilge rat!
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
 # To see a list of typical targets execute "make help"
@@ -1082,6 +1082,7 @@ help:
 	@echo  'Static analysers'
 	@echo  'Static analysers'
 	@echo  '  checkstack      - Generate a list of stack hogs'
 	@echo  '  checkstack      - Generate a list of stack hogs'
 	@echo  '  namespacecheck  - Name space analysis on compiled kernel'
 	@echo  '  namespacecheck  - Name space analysis on compiled kernel'
+	@echo  '  headers_check   - Sanity check on exported headers'
 	@echo  ''
 	@echo  ''
 	@echo  'Kernel packaging:'
 	@echo  'Kernel packaging:'
 	@$(MAKE) $(build)=$(package-dir) help
 	@$(MAKE) $(build)=$(package-dir) help

+ 1 - 4
arch/frv/Makefile

@@ -108,11 +108,8 @@ Image: vmlinux
 bootstrap:
 bootstrap:
 	$(Q)$(MAKEBOOT) bootstrap
 	$(Q)$(MAKEBOOT) bootstrap
 
 
-archmrproper:
-	$(Q)$(MAKE) $(build)=arch/frv/boot mrproper
-
 archclean:
 archclean:
-	$(Q)$(MAKE) $(build)=arch/frv/boot clean
+	$(Q)$(MAKE) $(clean)=arch/frv/boot
 
 
 archdep: scripts/mkdep symlinks
 archdep: scripts/mkdep symlinks
 	$(Q)$(MAKE) $(build)=arch/frv/boot dep
 	$(Q)$(MAKE) $(build)=arch/frv/boot dep

+ 2 - 1
arch/frv/boot/Makefile

@@ -8,6 +8,8 @@
 # Copyright (C) 1995-2000 Russell King
 # Copyright (C) 1995-2000 Russell King
 #
 #
 
 
+targets := Image zImage bootpImage
+
 SYSTEM	=$(TOPDIR)/$(LINUX)
 SYSTEM	=$(TOPDIR)/$(LINUX)
 
 
 ZTEXTADDR	 = 0x02080000
 ZTEXTADDR	 = 0x02080000
@@ -66,7 +68,6 @@ zinstall: $(CONFIGURE) zImage
 # miscellany
 # miscellany
 #
 #
 mrproper clean:
 mrproper clean:
-	$(RM) Image zImage bootpImage
 #	@$(MAKE) -C compressed clean
 #	@$(MAKE) -C compressed clean
 #	@$(MAKE) -C bootp clean
 #	@$(MAKE) -C bootp clean
 
 

+ 3 - 0
arch/i386/crypto/Makefile

@@ -5,5 +5,8 @@
 # 
 # 
 
 
 obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
 obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
+obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
 
 
 aes-i586-y := aes-i586-asm.o aes.o
 aes-i586-y := aes-i586-asm.o aes.o
+twofish-i586-y := twofish-i586-asm.o twofish.o
+

+ 2 - 1
arch/i386/crypto/aes.c

@@ -379,12 +379,13 @@ static void gen_tabs(void)
 }
 }
 
 
 static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
 static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
-		       unsigned int key_len, u32 *flags)
+		       unsigned int key_len)
 {
 {
 	int i;
 	int i;
 	u32 ss[8];
 	u32 ss[8];
 	struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
 	struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
 	const __le32 *key = (const __le32 *)in_key;
 	const __le32 *key = (const __le32 *)in_key;
+	u32 *flags = &tfm->crt_flags;
 
 
 	/* encryption schedule */
 	/* encryption schedule */
 	
 	

+ 335 - 0
arch/i386/crypto/twofish-i586-asm.S

@@ -0,0 +1,335 @@
+/***************************************************************************
+*   Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de>        *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+*   This program is distributed in the hope that it will be useful,       *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+*   GNU General Public License for more details.                          *
+*                                                                         *
+*   You should have received a copy of the GNU General Public License     *
+*   along with this program; if not, write to the                         *
+*   Free Software Foundation, Inc.,                                       *
+*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+***************************************************************************/
+
+.file "twofish-i586-asm.S"
+.text
+
+#include <asm/asm-offsets.h>
+
+/* return adress at 0 */
+
+#define in_blk    12  /* input byte array address parameter*/
+#define out_blk   8  /* output byte array address parameter*/
+#define tfm       4  /* Twofish context structure */
+
+#define a_offset	0
+#define b_offset	4
+#define c_offset	8
+#define d_offset	12
+
+/* Structure of the crypto context struct*/
+
+#define s0	0	/* S0 Array 256 Words each */
+#define s1	1024	/* S1 Array */
+#define s2	2048	/* S2 Array */
+#define s3	3072	/* S3 Array */
+#define w	4096	/* 8 whitening keys (word) */
+#define k	4128	/* key 1-32 ( word ) */
+
+/* define a few register aliases to allow macro substitution */
+
+#define R0D    %eax
+#define R0B    %al
+#define R0H    %ah
+
+#define R1D    %ebx
+#define R1B    %bl
+#define R1H    %bh
+
+#define R2D    %ecx
+#define R2B    %cl
+#define R2H    %ch
+
+#define R3D    %edx
+#define R3B    %dl
+#define R3H    %dh
+
+
+/* performs input whitening */
+#define input_whitening(src,context,offset)\
+	xor	w+offset(context),	src;
+
+/* performs input whitening */
+#define output_whitening(src,context,offset)\
+	xor	w+16+offset(context),	src;
+
+/*
+ * a input register containing a (rotated 16)
+ * b input register containing b
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ */
+#define encrypt_round(a,b,c,d,round)\
+	push	d ## D;\
+	movzx	b ## B,		%edi;\
+	mov	s1(%ebp,%edi,4),d ## D;\
+	movzx	a ## B,		%edi;\
+	mov	s2(%ebp,%edi,4),%esi;\
+	movzx	b ## H,		%edi;\
+	ror	$16,		b ## D;\
+	xor	s2(%ebp,%edi,4),d ## D;\
+	movzx	a ## H,		%edi;\
+	ror	$16,		a ## D;\
+	xor	s3(%ebp,%edi,4),%esi;\
+	movzx	b ## B,		%edi;\
+	xor	s3(%ebp,%edi,4),d ## D;\
+	movzx	a ## B,		%edi;\
+	xor	(%ebp,%edi,4),	%esi;\
+	movzx	b ## H,		%edi;\
+	ror	$15,		b ## D;\
+	xor	(%ebp,%edi,4),	d ## D;\
+	movzx	a ## H,		%edi;\
+	xor	s1(%ebp,%edi,4),%esi;\
+	pop	%edi;\
+	add	d ## D,		%esi;\
+	add	%esi,		d ## D;\
+	add	k+round(%ebp),	%esi;\
+	xor	%esi,		c ## D;\
+	rol	$15,		c ## D;\
+	add	k+4+round(%ebp),d ## D;\
+	xor	%edi,		d ## D;
+
+/*
+ * a input register containing a (rotated 16)
+ * b input register containing b
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ * last round has different rotations for the output preparation
+ */
+#define encrypt_last_round(a,b,c,d,round)\
+	push	d ## D;\
+	movzx	b ## B,		%edi;\
+	mov	s1(%ebp,%edi,4),d ## D;\
+	movzx	a ## B,		%edi;\
+	mov	s2(%ebp,%edi,4),%esi;\
+	movzx	b ## H,		%edi;\
+	ror	$16,		b ## D;\
+	xor	s2(%ebp,%edi,4),d ## D;\
+	movzx	a ## H,		%edi;\
+	ror	$16,		a ## D;\
+	xor	s3(%ebp,%edi,4),%esi;\
+	movzx	b ## B,		%edi;\
+	xor	s3(%ebp,%edi,4),d ## D;\
+	movzx	a ## B,		%edi;\
+	xor	(%ebp,%edi,4),	%esi;\
+	movzx	b ## H,		%edi;\
+	ror	$16,		b ## D;\
+	xor	(%ebp,%edi,4),	d ## D;\
+	movzx	a ## H,		%edi;\
+	xor	s1(%ebp,%edi,4),%esi;\
+	pop	%edi;\
+	add	d ## D,		%esi;\
+	add	%esi,		d ## D;\
+	add	k+round(%ebp),	%esi;\
+	xor	%esi,		c ## D;\
+	ror	$1,		c ## D;\
+	add	k+4+round(%ebp),d ## D;\
+	xor	%edi,		d ## D;
+
+/*
+ * a input register containing a
+ * b input register containing b (rotated 16)
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ */
+#define decrypt_round(a,b,c,d,round)\
+	push	c ## D;\
+	movzx	a ## B,		%edi;\
+	mov	(%ebp,%edi,4),	c ## D;\
+	movzx	b ## B,		%edi;\
+	mov	s3(%ebp,%edi,4),%esi;\
+	movzx	a ## H,		%edi;\
+	ror	$16,		a ## D;\
+	xor	s1(%ebp,%edi,4),c ## D;\
+	movzx	b ## H,		%edi;\
+	ror	$16,		b ## D;\
+	xor	(%ebp,%edi,4),	%esi;\
+	movzx	a ## B,		%edi;\
+	xor	s2(%ebp,%edi,4),c ## D;\
+	movzx	b ## B,		%edi;\
+	xor	s1(%ebp,%edi,4),%esi;\
+	movzx	a ## H,		%edi;\
+	ror	$15,		a ## D;\
+	xor	s3(%ebp,%edi,4),c ## D;\
+	movzx	b ## H,		%edi;\
+	xor	s2(%ebp,%edi,4),%esi;\
+	pop	%edi;\
+	add	%esi,		c ## D;\
+	add	c ## D,		%esi;\
+	add	k+round(%ebp),	c ## D;\
+	xor	%edi,		c ## D;\
+	add	k+4+round(%ebp),%esi;\
+	xor	%esi,		d ## D;\
+	rol	$15,		d ## D;
+
+/*
+ * a input register containing a
+ * b input register containing b (rotated 16)
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ * last round has different rotations for the output preparation
+ */
+#define decrypt_last_round(a,b,c,d,round)\
+	push	c ## D;\
+	movzx	a ## B,		%edi;\
+	mov	(%ebp,%edi,4),	c ## D;\
+	movzx	b ## B,		%edi;\
+	mov	s3(%ebp,%edi,4),%esi;\
+	movzx	a ## H,		%edi;\
+	ror	$16,		a ## D;\
+	xor	s1(%ebp,%edi,4),c ## D;\
+	movzx	b ## H,		%edi;\
+	ror	$16,		b ## D;\
+	xor	(%ebp,%edi,4),	%esi;\
+	movzx	a ## B,		%edi;\
+	xor	s2(%ebp,%edi,4),c ## D;\
+	movzx	b ## B,		%edi;\
+	xor	s1(%ebp,%edi,4),%esi;\
+	movzx	a ## H,		%edi;\
+	ror	$16,		a ## D;\
+	xor	s3(%ebp,%edi,4),c ## D;\
+	movzx	b ## H,		%edi;\
+	xor	s2(%ebp,%edi,4),%esi;\
+	pop	%edi;\
+	add	%esi,		c ## D;\
+	add	c ## D,		%esi;\
+	add	k+round(%ebp),	c ## D;\
+	xor	%edi,		c ## D;\
+	add	k+4+round(%ebp),%esi;\
+	xor	%esi,		d ## D;\
+	ror	$1,		d ## D;
+
+.align 4
+.global twofish_enc_blk
+.global twofish_dec_blk
+
+twofish_enc_blk:
+	push	%ebp			/* save registers according to calling convention*/
+	push    %ebx
+	push    %esi
+	push    %edi
+
+	mov	tfm + 16(%esp),	%ebp	/* abuse the base pointer: set new base bointer to the crypto tfm */
+	add	$crypto_tfm_ctx_offset, %ebp	/* ctx adress */
+	mov     in_blk+16(%esp),%edi	/* input adress in edi */
+
+	mov	(%edi),		%eax
+	mov	b_offset(%edi),	%ebx
+	mov	c_offset(%edi),	%ecx
+	mov	d_offset(%edi),	%edx
+	input_whitening(%eax,%ebp,a_offset)
+	ror	$16,	%eax
+	input_whitening(%ebx,%ebp,b_offset)
+	input_whitening(%ecx,%ebp,c_offset)
+	input_whitening(%edx,%ebp,d_offset)
+	rol	$1,	%edx
+
+	encrypt_round(R0,R1,R2,R3,0);
+	encrypt_round(R2,R3,R0,R1,8);
+	encrypt_round(R0,R1,R2,R3,2*8);
+	encrypt_round(R2,R3,R0,R1,3*8);
+	encrypt_round(R0,R1,R2,R3,4*8);
+	encrypt_round(R2,R3,R0,R1,5*8);
+	encrypt_round(R0,R1,R2,R3,6*8);
+	encrypt_round(R2,R3,R0,R1,7*8);
+	encrypt_round(R0,R1,R2,R3,8*8);
+	encrypt_round(R2,R3,R0,R1,9*8);
+	encrypt_round(R0,R1,R2,R3,10*8);
+	encrypt_round(R2,R3,R0,R1,11*8);
+	encrypt_round(R0,R1,R2,R3,12*8);
+	encrypt_round(R2,R3,R0,R1,13*8);
+	encrypt_round(R0,R1,R2,R3,14*8);
+	encrypt_last_round(R2,R3,R0,R1,15*8);
+
+	output_whitening(%eax,%ebp,c_offset)
+	output_whitening(%ebx,%ebp,d_offset)
+	output_whitening(%ecx,%ebp,a_offset)
+	output_whitening(%edx,%ebp,b_offset)
+	mov	out_blk+16(%esp),%edi;
+	mov	%eax,		c_offset(%edi)
+	mov	%ebx,		d_offset(%edi)
+	mov	%ecx,		(%edi)
+	mov	%edx,		b_offset(%edi)
+
+	pop	%edi
+	pop	%esi
+	pop	%ebx
+	pop	%ebp
+	mov	$1,	%eax
+	ret
+
+twofish_dec_blk:
+	push	%ebp			/* save registers according to calling convention*/
+	push    %ebx
+	push    %esi
+	push    %edi
+
+
+	mov	tfm + 16(%esp),	%ebp	/* abuse the base pointer: set new base bointer to the crypto tfm */
+	add	$crypto_tfm_ctx_offset, %ebp	/* ctx adress */
+	mov     in_blk+16(%esp),%edi	/* input adress in edi */
+
+	mov	(%edi),		%eax
+	mov	b_offset(%edi),	%ebx
+	mov	c_offset(%edi),	%ecx
+	mov	d_offset(%edi),	%edx
+	output_whitening(%eax,%ebp,a_offset)
+	output_whitening(%ebx,%ebp,b_offset)
+	ror	$16,	%ebx
+	output_whitening(%ecx,%ebp,c_offset)
+	output_whitening(%edx,%ebp,d_offset)
+	rol	$1,	%ecx
+
+	decrypt_round(R0,R1,R2,R3,15*8);
+	decrypt_round(R2,R3,R0,R1,14*8);
+	decrypt_round(R0,R1,R2,R3,13*8);
+	decrypt_round(R2,R3,R0,R1,12*8);
+	decrypt_round(R0,R1,R2,R3,11*8);
+	decrypt_round(R2,R3,R0,R1,10*8);
+	decrypt_round(R0,R1,R2,R3,9*8);
+	decrypt_round(R2,R3,R0,R1,8*8);
+	decrypt_round(R0,R1,R2,R3,7*8);
+	decrypt_round(R2,R3,R0,R1,6*8);
+	decrypt_round(R0,R1,R2,R3,5*8);
+	decrypt_round(R2,R3,R0,R1,4*8);
+	decrypt_round(R0,R1,R2,R3,3*8);
+	decrypt_round(R2,R3,R0,R1,2*8);
+	decrypt_round(R0,R1,R2,R3,1*8);
+	decrypt_last_round(R2,R3,R0,R1,0);
+
+	input_whitening(%eax,%ebp,c_offset)
+	input_whitening(%ebx,%ebp,d_offset)
+	input_whitening(%ecx,%ebp,a_offset)
+	input_whitening(%edx,%ebp,b_offset)
+	mov	out_blk+16(%esp),%edi;
+	mov	%eax,		c_offset(%edi)
+	mov	%ebx,		d_offset(%edi)
+	mov	%ecx,		(%edi)
+	mov	%edx,		b_offset(%edi)
+
+	pop	%edi
+	pop	%esi
+	pop	%ebx
+	pop	%ebp
+	mov	$1,	%eax
+	ret

+ 97 - 0
arch/i386/crypto/twofish.c

@@ -0,0 +1,97 @@
+/*
+ *  Glue Code for optimized 586 assembler version of TWOFISH
+ *
+ * Originally Twofish for GPG
+ * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
+ * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus put it in the public domain. The subsequent authors
+ * have put this under the GNU General Public License.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ * USA
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ */
+
+#include <crypto/twofish.h>
+#include <linux/crypto.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+
+asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+
+static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+	twofish_enc_blk(tfm, dst, src);
+}
+
+static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+	twofish_dec_blk(tfm, dst, src);
+}
+
+static struct crypto_alg alg = {
+	.cra_name		=	"twofish",
+	.cra_driver_name	=	"twofish-i586",
+	.cra_priority		=	200,
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	TF_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct twofish_ctx),
+	.cra_alignmask		=	3,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(alg.cra_list),
+	.cra_u			=	{
+		.cipher = {
+			.cia_min_keysize	=	TF_MIN_KEY_SIZE,
+			.cia_max_keysize	=	TF_MAX_KEY_SIZE,
+			.cia_setkey		=	twofish_setkey,
+			.cia_encrypt		=	twofish_encrypt,
+			.cia_decrypt		=	twofish_decrypt
+		}
+	}
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized");
+MODULE_ALIAS("twofish");

+ 38 - 1
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c

@@ -32,6 +32,7 @@
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
 #include <linux/compiler.h>
 #include <linux/compiler.h>
 #include <linux/sched.h>	/* current */
 #include <linux/sched.h>	/* current */
+#include <linux/dmi.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
@@ -387,6 +388,33 @@ static int acpi_cpufreq_early_init_acpi(void)
 	return acpi_processor_preregister_performance(acpi_perf_data);
 	return acpi_processor_preregister_performance(acpi_perf_data);
 }
 }
 
 
+/*
+ * Some BIOSes do SW_ANY coordination internally, either set it up in hw
+ * or do it in BIOS firmware and won't inform about it to OS. If not
+ * detected, this has a side effect of making CPU run at a different speed
+ * than OS intended it to run at. Detect it and handle it cleanly.
+ */
+static int bios_with_sw_any_bug;
+
+static int __init sw_any_bug_found(struct dmi_system_id *d)
+{
+	bios_with_sw_any_bug = 1;
+	return 0;
+}
+
+static struct dmi_system_id __initdata sw_any_bug_dmi_table[] = {
+	{
+		.callback = sw_any_bug_found,
+		.ident = "Supermicro Server X6DLP",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+			DMI_MATCH(DMI_BIOS_VERSION, "080010"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
+		},
+	},
+	{ }
+};
+
 static int
 static int
 acpi_cpufreq_cpu_init (
 acpi_cpufreq_cpu_init (
 	struct cpufreq_policy   *policy)
 	struct cpufreq_policy   *policy)
@@ -422,8 +450,17 @@ acpi_cpufreq_cpu_init (
 	 * coordination is required.
 	 * coordination is required.
 	 */
 	 */
 	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
 	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
-	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
 		policy->cpus = perf->shared_cpu_map;
 		policy->cpus = perf->shared_cpu_map;
+	}
+
+#ifdef CONFIG_SMP
+	dmi_check_system(sw_any_bug_dmi_table);
+	if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
+		policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+		policy->cpus = cpu_core_map[cpu];
+	}
+#endif
 
 
 	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
 	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
 		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
 		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;

+ 123 - 63
arch/i386/kernel/cpu/cpufreq/longhaul.c

@@ -27,6 +27,7 @@
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/cpufreq.h>
+#include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/string.h>
 
 
@@ -52,18 +53,26 @@
 #define	CPU_NEHEMIAH	5
 #define	CPU_NEHEMIAH	5
 
 
 static int cpu_model;
 static int cpu_model;
-static unsigned int numscales=16, numvscales;
+static unsigned int numscales=16;
 static unsigned int fsb;
 static unsigned int fsb;
-static int minvid, maxvid;
+
+static struct mV_pos *vrm_mV_table;
+static unsigned char *mV_vrm_table;
+struct f_msr {
+	unsigned char vrm;
+};
+static struct f_msr f_msr_table[32];
+
+static unsigned int highest_speed, lowest_speed; /* kHz */
 static unsigned int minmult, maxmult;
 static unsigned int minmult, maxmult;
 static int can_scale_voltage;
 static int can_scale_voltage;
-static int vrmrev;
 static struct acpi_processor *pr = NULL;
 static struct acpi_processor *pr = NULL;
 static struct acpi_processor_cx *cx = NULL;
 static struct acpi_processor_cx *cx = NULL;
+static int port22_en;
 
 
 /* Module parameters */
 /* Module parameters */
-static int dont_scale_voltage;
-
+static int scale_voltage;
+static int ignore_latency;
 
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
 
 
@@ -71,7 +80,6 @@ static int dont_scale_voltage;
 /* Clock ratios multiplied by 10 */
 /* Clock ratios multiplied by 10 */
 static int clock_ratio[32];
 static int clock_ratio[32];
 static int eblcr_table[32];
 static int eblcr_table[32];
-static int voltage_table[32];
 static unsigned int highest_speed, lowest_speed; /* kHz */
 static unsigned int highest_speed, lowest_speed; /* kHz */
 static int longhaul_version;
 static int longhaul_version;
 static struct cpufreq_frequency_table *longhaul_table;
 static struct cpufreq_frequency_table *longhaul_table;
@@ -124,10 +132,9 @@ static int longhaul_get_cpu_mult(void)
 
 
 /* For processor with BCR2 MSR */
 /* For processor with BCR2 MSR */
 
 
-static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
+static void do_longhaul1(unsigned int clock_ratio_index)
 {
 {
 	union msr_bcr2 bcr2;
 	union msr_bcr2 bcr2;
-	u32 t;
 
 
 	rdmsrl(MSR_VIA_BCR2, bcr2.val);
 	rdmsrl(MSR_VIA_BCR2, bcr2.val);
 	/* Enable software clock multiplier */
 	/* Enable software clock multiplier */
@@ -136,13 +143,11 @@ static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
 
 
 	/* Sync to timer tick */
 	/* Sync to timer tick */
 	safe_halt();
 	safe_halt();
-	ACPI_FLUSH_CPU_CACHE();
 	/* Change frequency on next halt or sleep */
 	/* Change frequency on next halt or sleep */
 	wrmsrl(MSR_VIA_BCR2, bcr2.val);
 	wrmsrl(MSR_VIA_BCR2, bcr2.val);
-	/* Invoke C3 */
-	inb(cx_address);
-	/* Dummy op - must do something useless after P_LVL3 read */
-	t = inl(acpi_fadt.xpm_tmr_blk.address);
+	/* Invoke transition */
+	ACPI_FLUSH_CPU_CACHE();
+	halt();
 
 
 	/* Disable software clock multiplier */
 	/* Disable software clock multiplier */
 	local_irq_disable();
 	local_irq_disable();
@@ -164,11 +169,16 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
 	longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
 	longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
 	longhaul.bits.EnableSoftBusRatio = 1;
 	longhaul.bits.EnableSoftBusRatio = 1;
 
 
+	if (can_scale_voltage) {
+		longhaul.bits.SoftVID = f_msr_table[clock_ratio_index].vrm;
+		longhaul.bits.EnableSoftVID = 1;
+	}
+
 	/* Sync to timer tick */
 	/* Sync to timer tick */
 	safe_halt();
 	safe_halt();
-	ACPI_FLUSH_CPU_CACHE();
 	/* Change frequency on next halt or sleep */
 	/* Change frequency on next halt or sleep */
 	wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 	wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+	ACPI_FLUSH_CPU_CACHE();
 	/* Invoke C3 */
 	/* Invoke C3 */
 	inb(cx_address);
 	inb(cx_address);
 	/* Dummy op - must do something useless after P_LVL3 read */
 	/* Dummy op - must do something useless after P_LVL3 read */
@@ -227,10 +237,13 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
 	outb(0xFF,0xA1);	/* Overkill */
 	outb(0xFF,0xA1);	/* Overkill */
 	outb(0xFE,0x21);	/* TMR0 only */
 	outb(0xFE,0x21);	/* TMR0 only */
 
 
-	/* Disable bus master arbitration */
-	if (pr->flags.bm_check) {
+	if (pr->flags.bm_control) {
+ 		/* Disable bus master arbitration */
 		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
 		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
 				  ACPI_MTX_DO_NOT_LOCK);
 				  ACPI_MTX_DO_NOT_LOCK);
+	} else if (port22_en) {
+		/* Disable AGP and PCI arbiters */
+		outb(3, 0x22);
 	}
 	}
 
 
 	switch (longhaul_version) {
 	switch (longhaul_version) {
@@ -244,7 +257,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
 	 */
 	 */
 	case TYPE_LONGHAUL_V1:
 	case TYPE_LONGHAUL_V1:
 	case TYPE_LONGHAUL_V2:
 	case TYPE_LONGHAUL_V2:
-		do_longhaul1(cx->address, clock_ratio_index);
+		do_longhaul1(clock_ratio_index);
 		break;
 		break;
 
 
 	/*
 	/*
@@ -259,14 +272,20 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
 	 * to work in practice.
 	 * to work in practice.
 	 */
 	 */
 	case TYPE_POWERSAVER:
 	case TYPE_POWERSAVER:
+		/* Don't allow wakeup */
+		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0,
+				  ACPI_MTX_DO_NOT_LOCK);
 		do_powersaver(cx->address, clock_ratio_index);
 		do_powersaver(cx->address, clock_ratio_index);
 		break;
 		break;
 	}
 	}
 
 
-	/* Enable bus master arbitration */
-	if (pr->flags.bm_check) {
+	if (pr->flags.bm_control) {
+		/* Enable bus master arbitration */
 		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
 		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
 				  ACPI_MTX_DO_NOT_LOCK);
 				  ACPI_MTX_DO_NOT_LOCK);
+	} else if (port22_en) {
+		/* Enable arbiters */
+		outb(0, 0x22);
 	}
 	}
 
 
 	outb(pic2_mask,0xA1);	/* restore mask */
 	outb(pic2_mask,0xA1);	/* restore mask */
@@ -446,53 +465,57 @@ static int __init longhaul_get_ranges(void)
 static void __init longhaul_setup_voltagescaling(void)
 static void __init longhaul_setup_voltagescaling(void)
 {
 {
 	union msr_longhaul longhaul;
 	union msr_longhaul longhaul;
+	struct mV_pos minvid, maxvid;
+	unsigned int j, speed, pos, kHz_step, numvscales;
 
 
-	rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-
-	if (!(longhaul.bits.RevisionID & 1))
+	rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+	if (!(longhaul.bits.RevisionID & 1)) {
+		printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
 		return;
 		return;
+	}
+
+	if (!longhaul.bits.VRMRev) {
+		printk (KERN_INFO PFX "VRM 8.5\n");
+		vrm_mV_table = &vrm85_mV[0];
+		mV_vrm_table = &mV_vrm85[0];
+	} else {
+		printk (KERN_INFO PFX "Mobile VRM\n");
+		vrm_mV_table = &mobilevrm_mV[0];
+		mV_vrm_table = &mV_mobilevrm[0];
+	}
 
 
-	minvid = longhaul.bits.MinimumVID;
-	maxvid = longhaul.bits.MaximumVID;
-	vrmrev = longhaul.bits.VRMRev;
+	minvid = vrm_mV_table[longhaul.bits.MinimumVID];
+	maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
+	numvscales = maxvid.pos - minvid.pos + 1;
+	kHz_step = (highest_speed - lowest_speed) / numvscales;
 
 
-	if (minvid == 0 || maxvid == 0) {
+	if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
 		printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
 		printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
 					"Voltage scaling disabled.\n",
 					"Voltage scaling disabled.\n",
-					minvid/1000, minvid%1000, maxvid/1000, maxvid%1000);
+					minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000);
 		return;
 		return;
 	}
 	}
 
 
-	if (minvid == maxvid) {
+	if (minvid.mV == maxvid.mV) {
 		printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
 		printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
 				"both %d.%03d. Voltage scaling disabled\n",
 				"both %d.%03d. Voltage scaling disabled\n",
-				maxvid/1000, maxvid%1000);
+				maxvid.mV/1000, maxvid.mV%1000);
 		return;
 		return;
 	}
 	}
 
 
-	if (vrmrev==0) {
-		dprintk ("VRM 8.5\n");
-		memcpy (voltage_table, vrm85scales, sizeof(voltage_table));
-		numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25;
-	} else {
-		dprintk ("Mobile VRM\n");
-		memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table));
-		numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5;
+	printk(KERN_INFO PFX "Max VID=%d.%03d  Min VID=%d.%03d, %d possible voltage scales\n",
+		maxvid.mV/1000, maxvid.mV%1000,
+		minvid.mV/1000, minvid.mV%1000,
+		numvscales);
+	
+	j = 0;
+	while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
+		speed = longhaul_table[j].frequency;
+		pos = (speed - lowest_speed) / kHz_step + minvid.pos;
+		f_msr_table[longhaul_table[j].index].vrm = mV_vrm_table[pos];
+		j++;
 	}
 	}
 
 
-	/* Current voltage isn't readable at first, so we need to
-	   set it to a known value. The spec says to use maxvid */
-	longhaul.bits.RevisionKey = longhaul.bits.RevisionID;	/* FIXME: This is bad. */
-	longhaul.bits.EnableSoftVID = 1;
-	longhaul.bits.SoftVID = maxvid;
-	wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-
-	minvid = voltage_table[minvid];
-	maxvid = voltage_table[maxvid];
-
-	dprintk ("Min VID=%d.%03d Max VID=%d.%03d, %d possible voltage scales\n",
-		maxvid/1000, maxvid%1000, minvid/1000, minvid%1000, numvscales);
-
 	can_scale_voltage = 1;
 	can_scale_voltage = 1;
 }
 }
 
 
@@ -540,21 +563,33 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
 	return 1;
 	return 1;
 }
 }
 
 
+/* VIA don't support PM2 reg, but have something similar */
+static int enable_arbiter_disable(void)
+{
+	struct pci_dev *dev;
+	u8 pci_cmd;
+
+	/* Find PLE133 host bridge */
+	dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL);
+	if (dev != NULL) {
+		/* Enable access to port 0x22 */
+		pci_read_config_byte(dev, 0x78, &pci_cmd);
+		if ( !(pci_cmd & 1<<7) ) {
+			pci_cmd |= 1<<7;
+			pci_write_config_byte(dev, 0x78, pci_cmd);
+		}
+		return 1;
+	}
+	return 0;
+}
+
 static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 {
 {
 	struct cpuinfo_x86 *c = cpu_data;
 	struct cpuinfo_x86 *c = cpu_data;
 	char *cpuname=NULL;
 	char *cpuname=NULL;
 	int ret;
 	int ret;
 
 
-	/* Check ACPI support for C3 state */
-	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
-			 &longhaul_walk_callback, NULL, (void *)&pr);
-	if (pr == NULL) goto err_acpi;
-
-	cx = &pr->power.states[ACPI_STATE_C3];
-	if (cx->address == 0 || cx->latency > 1000) goto err_acpi;
-
-	/* Now check what we have on this motherboard */
+	/* Check what we have on this motherboard */
 	switch (c->x86_model) {
 	switch (c->x86_model) {
 	case 6:
 	case 6:
 		cpu_model = CPU_SAMUEL;
 		cpu_model = CPU_SAMUEL;
@@ -636,12 +671,36 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 		break;
 		break;
 	};
 	};
 
 
+	/* Find ACPI data for processor */
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+			    &longhaul_walk_callback, NULL, (void *)&pr);
+	if (pr == NULL)
+		goto err_acpi;
+
+	if (longhaul_version == TYPE_POWERSAVER) {
+		/* Check ACPI support for C3 state */
+		cx = &pr->power.states[ACPI_STATE_C3];
+		if (cx->address == 0 ||
+		   (cx->latency > 1000 && ignore_latency == 0) )
+			goto err_acpi;
+
+	} else {
+		/* Check ACPI support for bus master arbiter disable */
+		if (!pr->flags.bm_control) {
+			if (!enable_arbiter_disable()) {
+				printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n");
+				return -ENODEV;
+			} else
+				port22_en = 1;
+		}
+	}
+
 	ret = longhaul_get_ranges();
 	ret = longhaul_get_ranges();
 	if (ret != 0)
 	if (ret != 0)
 		return ret;
 		return ret;
 
 
 	if ((longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) &&
 	if ((longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) &&
-		 (dont_scale_voltage==0))
+		 (scale_voltage != 0))
 		longhaul_setup_voltagescaling();
 		longhaul_setup_voltagescaling();
 
 
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
@@ -729,8 +788,10 @@ static void __exit longhaul_exit(void)
 	kfree(longhaul_table);
 	kfree(longhaul_table);
 }
 }
 
 
-module_param (dont_scale_voltage, int, 0644);
-MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor");
+module_param (scale_voltage, int, 0644);
+MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
+module_param(ignore_latency, int, 0644);
+MODULE_PARM_DESC(ignore_latency, "Skip ACPI C3 latency test");
 
 
 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
 MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
@@ -738,4 +799,3 @@ MODULE_LICENSE ("GPL");
 
 
 late_initcall(longhaul_init);
 late_initcall(longhaul_init);
 module_exit(longhaul_exit);
 module_exit(longhaul_exit);
-

+ 38 - 10
arch/i386/kernel/cpu/cpufreq/longhaul.h

@@ -450,17 +450,45 @@ static int __initdata nehemiah_c_eblcr[32] = {
  * Voltage scales. Div/Mod by 1000 to get actual voltage.
  * Voltage scales. Div/Mod by 1000 to get actual voltage.
  * Which scale to use depends on the VRM type in use.
  * Which scale to use depends on the VRM type in use.
  */
  */
-static int __initdata vrm85scales[32] = {
-	1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700,
-	1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300,
-	1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725,
-	1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325,
+
+struct mV_pos {
+	unsigned short mV;
+	unsigned short pos;
+};
+
+static struct mV_pos __initdata vrm85_mV[32] = {
+	{1250, 8},	{1200, 6},	{1150, 4},	{1100, 2},
+	{1050, 0},	{1800, 30},	{1750, 28},	{1700, 26},
+	{1650, 24},	{1600, 22},	{1550, 20},	{1500, 18},
+	{1450, 16},	{1400, 14},	{1350, 12},	{1300, 10},
+	{1275, 9},	{1225, 7},	{1175, 5},	{1125, 3},
+	{1075, 1},	{1825, 31},	{1775, 29},	{1725, 27},
+	{1675, 25},	{1625, 23},	{1575, 21},	{1525, 19},
+	{1475, 17},	{1425, 15},	{1375, 13},	{1325, 11}
+};
+
+static unsigned char __initdata mV_vrm85[32] = {
+	0x04,	0x14,	0x03,	0x13,	0x02,	0x12,	0x01,	0x11,
+	0x00,	0x10,	0x0f,	0x1f,	0x0e,	0x1e,	0x0d,	0x1d,
+	0x0c,	0x1c,	0x0b,	0x1b,	0x0a,	0x1a,	0x09,	0x19,
+	0x08,	0x18,	0x07,	0x17,	0x06,	0x16,	0x05,	0x15
+};
+
+static struct mV_pos __initdata mobilevrm_mV[32] = {
+	{1750, 31},	{1700, 30},	{1650, 29},	{1600, 28},
+	{1550, 27},	{1500, 26},	{1450, 25},	{1400, 24},
+	{1350, 23},	{1300, 22},	{1250, 21},	{1200, 20},
+	{1150, 19},	{1100, 18},	{1050, 17},	{1000, 16},
+	{975, 15},	{950, 14},	{925, 13},	{900, 12},
+	{875, 11},	{850, 10},	{825, 9},	{800, 8},
+	{775, 7},	{750, 6},	{725, 5},	{700, 4},
+	{675, 3},	{650, 2},	{625, 1},	{600, 0}
 };
 };
 
 
-static int __initdata mobilevrmscales[32] = {
-	2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
-	1600, 1550, 1500, 1450, 1500, 1350, 1300, -1,
-	1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
-	1075, 1050, 1025, 1000, 975, 950, 925, -1,
+static unsigned char __initdata mV_mobilevrm[32] = {
+	0x1f,	0x1e,	0x1d,	0x1c,	0x1b,	0x1a,	0x19,	0x18,
+	0x17,	0x16,	0x15,	0x14,	0x13,	0x12,	0x11,	0x10,
+	0x0f,	0x0e,	0x0d,	0x0c,	0x0b,	0x0a,	0x09,	0x08,
+	0x07,	0x06,	0x05,	0x04,	0x03,	0x02,	0x01,	0x00
 };
 };
 
 

+ 41 - 1
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c

@@ -23,6 +23,7 @@
 
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
 #include <linux/acpi.h>
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <acpi/processor.h>
 #include <acpi/processor.h>
 #endif
 #endif
 
 
@@ -377,6 +378,35 @@ static int centrino_cpu_early_init_acpi(void)
 	return 0;
 	return 0;
 }
 }
 
 
+
+/*
+ * Some BIOSes do SW_ANY coordination internally, either set it up in hw
+ * or do it in BIOS firmware and won't inform about it to OS. If not
+ * detected, this has a side effect of making CPU run at a different speed
+ * than OS intended it to run at. Detect it and handle it cleanly.
+ */
+static int bios_with_sw_any_bug;
+static int __init sw_any_bug_found(struct dmi_system_id *d)
+{
+	bios_with_sw_any_bug = 1;
+	return 0;
+}
+
+
+static struct dmi_system_id sw_any_bug_dmi_table[] = {
+	{
+		.callback = sw_any_bug_found,
+		.ident = "Supermicro Server X6DLP",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+			DMI_MATCH(DMI_BIOS_VERSION, "080010"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
+		},
+	},
+	{ }
+};
+
+
 /*
 /*
  * centrino_cpu_init_acpi - register with ACPI P-States library
  * centrino_cpu_init_acpi - register with ACPI P-States library
  *
  *
@@ -398,14 +428,24 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
 		dprintk(PFX "obtaining ACPI data failed\n");
 		dprintk(PFX "obtaining ACPI data failed\n");
 		return -EIO;
 		return -EIO;
 	}
 	}
+
 	policy->shared_type = p->shared_type;
 	policy->shared_type = p->shared_type;
 	/*
 	/*
 	 * Will let policy->cpus know about dependency only when software 
 	 * Will let policy->cpus know about dependency only when software 
 	 * coordination is required.
 	 * coordination is required.
 	 */
 	 */
 	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
 	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
-	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
 		policy->cpus = p->shared_cpu_map;
 		policy->cpus = p->shared_cpu_map;
+	}
+
+#ifdef CONFIG_SMP
+	dmi_check_system(sw_any_bug_dmi_table);
+	if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
+		policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+		policy->cpus = cpu_core_map[cpu];
+	}
+#endif
 
 
 	/* verify the acpi_data */
 	/* verify the acpi_data */
 	if (p->state_count <= 1) {
 	if (p->state_count <= 1) {

+ 32 - 0
arch/i386/kernel/setup.c

@@ -956,6 +956,38 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
 	return 0;
 	return 0;
 }
 }
 
 
+ /*
+  * This function checks if the entire range <start,end> is mapped with type.
+  *
+  * Note: this function only works correct if the e820 table is sorted and
+  * not-overlapping, which is the case
+  */
+int __init
+e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
+{
+	u64 start = s;
+	u64 end = e;
+	int i;
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		if (type && ei->type != type)
+			continue;
+		/* is the region (part) in overlap with the current region ?*/
+		if (ei->addr >= end || ei->addr + ei->size <= start)
+			continue;
+		/* if the region is at the beginning of <start,end> we move
+		 * start to the end of the region since it's ok until there
+		 */
+		if (ei->addr <= start)
+			start = ei->addr + ei->size;
+		/* if start is now at or beyond end, we're done, full
+		 * coverage */
+		if (start >= end)
+			return 1; /* we're done */
+	}
+	return 0;
+}
+
 /*
 /*
  * Find the highest page frame number we have available
  * Find the highest page frame number we have available
  */
  */

+ 0 - 5
arch/i386/pci/common.c

@@ -237,11 +237,6 @@ char * __devinit  pcibios_setup(char *str)
 		pci_probe &= ~PCI_PROBE_MMCONF;
 		pci_probe &= ~PCI_PROBE_MMCONF;
 		return NULL;
 		return NULL;
 	}
 	}
-	/* override DMI blacklist */
-	else if (!strcmp(str, "mmconf")) {
-		pci_probe |= PCI_PROBE_MMCONF_FORCE;
-		return NULL;
-	}
 #endif
 #endif
 	else if (!strcmp(str, "noacpi")) {
 	else if (!strcmp(str, "noacpi")) {
 		acpi_noirq_set();
 		acpi_noirq_set();

+ 10 - 24
arch/i386/pci/mmconfig.c

@@ -12,7 +12,6 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>
-#include <linux/dmi.h>
 #include <asm/e820.h>
 #include <asm/e820.h>
 #include "pci.h"
 #include "pci.h"
 
 
@@ -188,31 +187,9 @@ static __init void unreachable_devices(void)
 	}
 	}
 }
 }
 
 
-static int disable_mcfg(struct dmi_system_id *d)
-{
-	printk("PCI: %s detected. Disabling MCFG.\n", d->ident);
-	pci_probe &= ~PCI_PROBE_MMCONF;
-	return 0;
-}
-
-static struct dmi_system_id __initdata dmi_bad_mcfg[] = {
-	/* Has broken MCFG table that makes the system hang when used */
-        {
-         .callback = disable_mcfg,
-         .ident = "Intel D3C5105 SDV",
-         .matches = {
-                     DMI_MATCH(DMI_BIOS_VENDOR, "Intel"),
-                     DMI_MATCH(DMI_BOARD_NAME, "D26928"),
-                     },
-         },
-         {}
-};
-
 void __init pci_mmcfg_init(void)
 void __init pci_mmcfg_init(void)
 {
 {
-	dmi_check_system(dmi_bad_mcfg);
-
-	if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0)
+	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		return;
 		return;
 
 
 	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
 	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
@@ -221,6 +198,15 @@ void __init pci_mmcfg_init(void)
 	    (pci_mmcfg_config[0].base_address == 0))
 	    (pci_mmcfg_config[0].base_address == 0))
 		return;
 		return;
 
 
+	if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
+			pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
+			E820_RESERVED)) {
+		printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
+				pci_mmcfg_config[0].base_address);
+		printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
+		return;
+	}
+
 	printk(KERN_INFO "PCI: Using MMCONFIG\n");
 	printk(KERN_INFO "PCI: Using MMCONFIG\n");
 	raw_pci_ops = &pci_mmcfg;
 	raw_pci_ops = &pci_mmcfg;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;

+ 1 - 2
arch/i386/pci/pci.h

@@ -16,8 +16,7 @@
 #define PCI_PROBE_CONF1		0x0002
 #define PCI_PROBE_CONF1		0x0002
 #define PCI_PROBE_CONF2		0x0004
 #define PCI_PROBE_CONF2		0x0004
 #define PCI_PROBE_MMCONF	0x0008
 #define PCI_PROBE_MMCONF	0x0008
-#define PCI_PROBE_MMCONF_FORCE	0x0010
-#define PCI_PROBE_MASK		0x00ff
+#define PCI_PROBE_MASK		0x000f
 
 
 #define PCI_NO_SORT		0x0100
 #define PCI_NO_SORT		0x0100
 #define PCI_BIOS_SORT		0x0200
 #define PCI_BIOS_SORT		0x0200

+ 13 - 1
arch/powerpc/Kconfig

@@ -417,6 +417,17 @@ config PPC_MAPLE
           This option enables support for the Maple 970FX Evaluation Board.
           This option enables support for the Maple 970FX Evaluation Board.
 	  For more informations, refer to <http://www.970eval.com>
 	  For more informations, refer to <http://www.970eval.com>
 
 
+config PPC_PASEMI
+	depends on PPC_MULTIPLATFORM && PPC64
+	bool "PA Semi SoC-based platforms"
+	default n
+	select MPIC
+	select PPC_UDBG_16550
+	select GENERIC_TBSYNC
+	help
+	  This option enables support for PA Semi's PWRficient line
+	  of SoC processors, including PA6T-1682M
+
 config PPC_CELL
 config PPC_CELL
 	bool
 	bool
 	default n
 	default n
@@ -436,7 +447,8 @@ config PPC_IBM_CELL_BLADE
 	select UDBG_RTAS_CONSOLE
 	select UDBG_RTAS_CONSOLE
 
 
 config UDBG_RTAS_CONSOLE
 config UDBG_RTAS_CONSOLE
-	bool
+	bool "RTAS based debug console"
+	depends on PPC_RTAS
 	default n
 	default n
 
 
 config XICS
 config XICS

+ 16 - 0
arch/powerpc/Kconfig.debug

@@ -18,6 +18,20 @@ config DEBUG_STACK_USAGE
 
 
 	  This option will slow down process creation somewhat.
 	  This option will slow down process creation somewhat.
 
 
+config HCALL_STATS
+	bool "Hypervisor call instrumentation"
+	depends on PPC_PSERIES && DEBUG_FS
+	help
+	  Adds code to keep track of the number of hypervisor calls made and
+	  the amount of time spent in hypervisor callsr.  Wall time spent in
+	  each call is always calculated, and if available CPU cycles spent
+	  are also calculated.  A directory named hcall_inst is added at the
+	  root of the debugfs filesystem.  Within the hcall_inst directory
+	  are files that contain CPU specific call statistics.
+
+	  This option will add a small amount of overhead to all hypervisor
+	  calls.
+
 config DEBUGGER
 config DEBUGGER
 	bool "Enable debugger hooks"
 	bool "Enable debugger hooks"
 	depends on DEBUG_KERNEL
 	depends on DEBUG_KERNEL
@@ -74,6 +88,8 @@ config XMON
 	  very early during boot. 'xmon=on' will just enable the xmon
 	  very early during boot. 'xmon=on' will just enable the xmon
 	  debugger hooks.  'xmon=off' will disable the debugger hooks
 	  debugger hooks.  'xmon=off' will disable the debugger hooks
 	  if CONFIG_XMON_DEFAULT is set.
 	  if CONFIG_XMON_DEFAULT is set.
+	  xmon will print a backtrace on the very first invocation.
+	  'xmon=nobt' will disable this autobacktrace.
 
 
 config XMON_DEFAULT
 config XMON_DEFAULT
 	bool "Enable xmon by default"
 	bool "Enable xmon by default"

+ 6 - 1
arch/powerpc/boot/Makefile

@@ -36,11 +36,16 @@ zliblinuxheader := zlib.h zconf.h zutil.h
 $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
 $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
 #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
 #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
 
 
-src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
+src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
+src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
 src-boot += $(zlib)
 src-boot += $(zlib)
 src-boot := $(addprefix $(obj)/, $(src-boot))
 src-boot := $(addprefix $(obj)/, $(src-boot))
 obj-boot := $(addsuffix .o, $(basename $(src-boot)))
 obj-boot := $(addsuffix .o, $(basename $(src-boot)))
 
 
+ifeq ($(call cc-option-yn, -fstack-protector),y)
+BOOTCFLAGS	+= -fno-stack-protector
+endif
+
 BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj)
 BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj)
 
 
 quiet_cmd_copy_zlib = COPY    $@
 quiet_cmd_copy_zlib = COPY    $@

+ 8 - 8
arch/powerpc/boot/dts/mpc8349emds.dts

@@ -214,10 +214,10 @@
 					 b800 0 0 4 700 15 8
 					 b800 0 0 4 700 15 8
 
 
 					/* IDSEL 0x18 */
 					/* IDSEL 0x18 */
-					 b000 0 0 1 700 15 8
-					 b000 0 0 2 700 16 8
-					 b000 0 0 3 700 17 8
-					 b000 0 0 4 700 14 8>;
+					 c000 0 0 1 700 15 8
+					 c000 0 0 2 700 16 8
+					 c000 0 0 3 700 17 8
+					 c000 0 0 4 700 14 8>;
 			interrupt-parent = <700>;
 			interrupt-parent = <700>;
 			interrupts = <42 8>;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
@@ -274,10 +274,10 @@
 					 b800 0 0 4 700 15 8
 					 b800 0 0 4 700 15 8
 
 
 					/* IDSEL 0x18 */
 					/* IDSEL 0x18 */
-					 b000 0 0 1 700 15 8
-					 b000 0 0 2 700 16 8
-					 b000 0 0 3 700 17 8
-					 b000 0 0 4 700 14 8>;
+					 c000 0 0 1 700 15 8
+					 c000 0 0 2 700 16 8
+					 c000 0 0 3 700 17 8
+					 c000 0 0 4 700 14 8>;
 			interrupt-parent = <700>;
 			interrupt-parent = <700>;
 			interrupts = <42 8>;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;

+ 46 - 0
arch/powerpc/boot/flatdevtree.h

@@ -0,0 +1,46 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef FLATDEVTREE_H
+#define FLATDEVTREE_H
+
+#include "types.h"
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER            0xd00dfeed      /* marker */
+#define OF_DT_BEGIN_NODE        0x1     /* Start of node, full name */
+#define OF_DT_END_NODE          0x2     /* End node */
+#define OF_DT_PROP              0x3     /* Property: name off, size, content */
+#define OF_DT_NOP               0x4     /* nop */
+#define OF_DT_END               0x9
+
+#define OF_DT_VERSION           0x10
+
+struct boot_param_header {
+	u32 magic;              /* magic word OF_DT_HEADER */
+	u32 totalsize;          /* total size of DT block */
+	u32 off_dt_struct;      /* offset to structure */
+	u32 off_dt_strings;     /* offset to strings */
+	u32 off_mem_rsvmap;     /* offset to memory reserve map */
+	u32 version;            /* format version */
+	u32 last_comp_version;  /* last compatible version */
+	/* version 2 fields below */
+	u32 boot_cpuid_phys;    /* Physical CPU id we're booting on */
+	/* version 3 fields below */
+	u32 dt_strings_size;    /* size of the DT strings block */
+};
+
+#endif /* FLATDEVTREE_H */

+ 129 - 121
arch/powerpc/boot/main.c

@@ -14,17 +14,12 @@
 #include "page.h"
 #include "page.h"
 #include "string.h"
 #include "string.h"
 #include "stdio.h"
 #include "stdio.h"
-#include "prom.h"
 #include "zlib.h"
 #include "zlib.h"
+#include "ops.h"
+#include "flatdevtree.h"
 
 
 extern void flush_cache(void *, unsigned long);
 extern void flush_cache(void *, unsigned long);
 
 
-
-/* Value picked to match that used by yaboot */
-#define PROG_START	0x01400000	/* only used on 64-bit systems */
-#define RAM_END		(512<<20)	/* Fixme: use OF */
-#define	ONE_MB		0x100000
-
 extern char _start[];
 extern char _start[];
 extern char __bss_start[];
 extern char __bss_start[];
 extern char _end[];
 extern char _end[];
@@ -33,14 +28,6 @@ extern char _vmlinux_end[];
 extern char _initrd_start[];
 extern char _initrd_start[];
 extern char _initrd_end[];
 extern char _initrd_end[];
 
 
-/* A buffer that may be edited by tools operating on a zImage binary so as to
- * edit the command line passed to vmlinux (by setting /chosen/bootargs).
- * The buffer is put in it's own section so that tools may locate it easier.
- */
-static char builtin_cmdline[512]
-	__attribute__((section("__builtin_cmdline")));
-
-
 struct addr_range {
 struct addr_range {
 	unsigned long addr;
 	unsigned long addr;
 	unsigned long size;
 	unsigned long size;
@@ -51,21 +38,16 @@ static struct addr_range vmlinuz;
 static struct addr_range initrd;
 static struct addr_range initrd;
 
 
 static unsigned long elfoffset;
 static unsigned long elfoffset;
+static int is_64bit;
 
 
-static char scratch[46912];	/* scratch space for gunzip, from zlib_inflate_workspacesize() */
+/* scratch space for gunzip; 46912 is from zlib_inflate_workspacesize() */
+static char scratch[46912];
 static char elfheader[256];
 static char elfheader[256];
 
 
-
-typedef void (*kernel_entry_t)( unsigned long,
-                                unsigned long,
-                                void *,
-				void *);
-
+typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
 
 
 #undef DEBUG
 #undef DEBUG
 
 
-static unsigned long claim_base;
-
 #define HEAD_CRC	2
 #define HEAD_CRC	2
 #define EXTRA_FIELD	4
 #define EXTRA_FIELD	4
 #define ORIG_NAME	8
 #define ORIG_NAME	8
@@ -123,24 +105,6 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
 	zlib_inflateEnd(&s);
 	zlib_inflateEnd(&s);
 }
 }
 
 
-static unsigned long try_claim(unsigned long size)
-{
-	unsigned long addr = 0;
-
-	for(; claim_base < RAM_END; claim_base += ONE_MB) {
-#ifdef DEBUG
-		printf("    trying: 0x%08lx\n\r", claim_base);
-#endif
-		addr = (unsigned long)claim(claim_base, size, 0);
-		if ((void *)addr != (void *)-1)
-			break;
-	}
-	if (addr == 0)
-		return 0;
-	claim_base = PAGE_ALIGN(claim_base + size);
-	return addr;
-}
-
 static int is_elf64(void *hdr)
 static int is_elf64(void *hdr)
 {
 {
 	Elf64_Ehdr *elf64 = hdr;
 	Elf64_Ehdr *elf64 = hdr;
@@ -169,16 +133,7 @@ static int is_elf64(void *hdr)
 	vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
 	vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
 	vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
 	vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
 
 
-#if defined(PROG_START)
-	/*
-	 * Maintain a "magic" minimum address. This keeps some older
-	 * firmware platforms running.
-	 */
-
-	if (claim_base < PROG_START)
-		claim_base = PROG_START;
-#endif
-
+	is_64bit = 1;
 	return 1;
 	return 1;
 }
 }
 
 
@@ -212,47 +167,9 @@ static int is_elf32(void *hdr)
 	return 1;
 	return 1;
 }
 }
 
 
-void export_cmdline(void* chosen_handle)
-{
-        int len;
-        char cmdline[2] = { 0, 0 };
-
-	if (builtin_cmdline[0] == 0)
-		return;
-
-        len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline));
-        if (len > 0 && cmdline[0] != 0)
-		return;
-
-	setprop(chosen_handle, "bootargs", builtin_cmdline,
-		strlen(builtin_cmdline) + 1);
-}
-
-
-void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
+static void prep_kernel(unsigned long *a1, unsigned long *a2)
 {
 {
 	int len;
 	int len;
-	kernel_entry_t kernel_entry;
-
-	memset(__bss_start, 0, _end - __bss_start);
-
-	prom = (int (*)(void *)) promptr;
-	chosen_handle = finddevice("/chosen");
-	if (chosen_handle == (void *) -1)
-		exit();
-	if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
-		exit();
-
-	printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
-
-	/*
-	 * The first available claim_base must be above the end of the
-	 * the loaded kernel wrapper file (_start to _end includes the
-	 * initrd image if it is present) and rounded up to a nice
-	 * 1 MB boundary for good measure.
-	 */
-
-	claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
 
 
 	vmlinuz.addr = (unsigned long)_vmlinux_start;
 	vmlinuz.addr = (unsigned long)_vmlinux_start;
 	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
 	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -263,43 +180,51 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
 		gunzip(elfheader, sizeof(elfheader),
 		gunzip(elfheader, sizeof(elfheader),
 				(unsigned char *)vmlinuz.addr, &len);
 				(unsigned char *)vmlinuz.addr, &len);
 	} else
 	} else
-		memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
+		memcpy(elfheader, (const void *)vmlinuz.addr,
+		       sizeof(elfheader));
 
 
 	if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
 	if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
 		printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
 		printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
 		exit();
 		exit();
 	}
 	}
+	if (platform_ops.image_hdr)
+		platform_ops.image_hdr(elfheader);
 
 
-	/* We need to claim the memsize plus the file offset since gzip
+	/* We need to alloc the memsize plus the file offset since gzip
 	 * will expand the header (file offset), then the kernel, then
 	 * will expand the header (file offset), then the kernel, then
 	 * possible rubbish we don't care about. But the kernel bss must
 	 * possible rubbish we don't care about. But the kernel bss must
 	 * be claimed (it will be zero'd by the kernel itself)
 	 * be claimed (it will be zero'd by the kernel itself)
 	 */
 	 */
 	printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
 	printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
-	vmlinux.addr = try_claim(vmlinux.memsize);
+	vmlinux.addr = (unsigned long)malloc(vmlinux.memsize);
 	if (vmlinux.addr == 0) {
 	if (vmlinux.addr == 0) {
 		printf("Can't allocate memory for kernel image !\n\r");
 		printf("Can't allocate memory for kernel image !\n\r");
 		exit();
 		exit();
 	}
 	}
 
 
 	/*
 	/*
-	 * Now we try to claim memory for the initrd (and copy it there)
+	 * Now we try to alloc memory for the initrd (and copy it there)
 	 */
 	 */
 	initrd.size = (unsigned long)(_initrd_end - _initrd_start);
 	initrd.size = (unsigned long)(_initrd_end - _initrd_start);
 	initrd.memsize = initrd.size;
 	initrd.memsize = initrd.size;
 	if ( initrd.size > 0 ) {
 	if ( initrd.size > 0 ) {
-		printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size);
-		initrd.addr = try_claim(initrd.size);
+		printf("Allocating 0x%lx bytes for initrd ...\n\r",
+		       initrd.size);
+		initrd.addr = (unsigned long)malloc((u32)initrd.size);
 		if (initrd.addr == 0) {
 		if (initrd.addr == 0) {
-			printf("Can't allocate memory for initial ramdisk !\n\r");
+			printf("Can't allocate memory for initial "
+					"ramdisk !\n\r");
 			exit();
 			exit();
 		}
 		}
-		a1 = initrd.addr;
-		a2 = initrd.size;
-		printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r",
-		       initrd.addr, (unsigned long)_initrd_start, initrd.size);
-		memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
-		printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr));
+		*a1 = initrd.addr;
+		*a2 = initrd.size;
+		printf("initial ramdisk moving 0x%lx <- 0x%lx "
+			"(0x%lx bytes)\n\r", initrd.addr,
+			(unsigned long)_initrd_start, initrd.size);
+		memmove((void *)initrd.addr, (void *)_initrd_start,
+			initrd.size);
+		printf("initrd head: 0x%lx\n\r",
+				*((unsigned long *)initrd.addr));
 	}
 	}
 
 
 	/* Eventually gunzip the kernel */
 	/* Eventually gunzip the kernel */
@@ -311,11 +236,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
 			(unsigned char *)vmlinuz.addr, &len);
 			(unsigned char *)vmlinuz.addr, &len);
 		printf("done 0x%lx bytes\n\r", len);
 		printf("done 0x%lx bytes\n\r", len);
 	} else {
 	} else {
-		memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
+		memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,
+			vmlinuz.size);
 	}
 	}
 
 
-	export_cmdline(chosen_handle);
-
 	/* Skip over the ELF header */
 	/* Skip over the ELF header */
 #ifdef DEBUG
 #ifdef DEBUG
 	printf("... skipping 0x%lx bytes of ELF header\n\r",
 	printf("... skipping 0x%lx bytes of ELF header\n\r",
@@ -324,23 +248,107 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
 	vmlinux.addr += elfoffset;
 	vmlinux.addr += elfoffset;
 
 
 	flush_cache((void *)vmlinux.addr, vmlinux.size);
 	flush_cache((void *)vmlinux.addr, vmlinux.size);
+}
 
 
-	kernel_entry = (kernel_entry_t)vmlinux.addr;
-#ifdef DEBUG
-	printf( "kernel:\n\r"
-		"        entry addr = 0x%lx\n\r"
-		"        a1         = 0x%lx,\n\r"
-		"        a2         = 0x%lx,\n\r"
-		"        prom       = 0x%lx,\n\r"
-		"        bi_recs    = 0x%lx,\n\r",
-		(unsigned long)kernel_entry, a1, a2,
-		(unsigned long)prom, NULL);
-#endif
+void __attribute__ ((weak)) ft_init(void *dt_blob)
+{
+}
 
 
-	kernel_entry(a1, a2, prom, NULL);
+/* A buffer that may be edited by tools operating on a zImage binary so as to
+ * edit the command line passed to vmlinux (by setting /chosen/bootargs).
+ * The buffer is put in it's own section so that tools may locate it easier.
+ */
+static char builtin_cmdline[COMMAND_LINE_SIZE]
+	__attribute__((__section__("__builtin_cmdline")));
 
 
-	printf("Error: Linux kernel returned to zImage bootloader!\n\r");
+static void get_cmdline(char *buf, int size)
+{
+	void *devp;
+	int len = strlen(builtin_cmdline);
 
 
-	exit();
+	buf[0] = '\0';
+
+	if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */
+		len = min(len, size-1);
+		strncpy(buf, builtin_cmdline, len);
+		buf[len] = '\0';
+	}
+	else if ((devp = finddevice("/chosen")))
+		getprop(devp, "bootargs", buf, size);
+}
+
+static void set_cmdline(char *buf)
+{
+	void *devp;
+
+	if ((devp = finddevice("/chosen")))
+		setprop(devp, "bootargs", buf, strlen(buf) + 1);
 }
 }
 
 
+/* Section where ft can be tacked on after zImage is built */
+union blobspace {
+	struct boot_param_header hdr;
+	char space[8*1024];
+} dt_blob __attribute__((__section__("__builtin_ft")));
+
+struct platform_ops platform_ops;
+struct dt_ops dt_ops;
+struct console_ops console_ops;
+
+void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
+{
+	int have_dt = 0;
+	kernel_entry_t kentry;
+	char cmdline[COMMAND_LINE_SIZE];
+
+	memset(__bss_start, 0, _end - __bss_start);
+	memset(&platform_ops, 0, sizeof(platform_ops));
+	memset(&dt_ops, 0, sizeof(dt_ops));
+	memset(&console_ops, 0, sizeof(console_ops));
+
+	/* Override the dt_ops and device tree if there was an flat dev
+	 * tree attached to the zImage.
+	 */
+	if (dt_blob.hdr.magic == OF_DT_HEADER) {
+		have_dt = 1;
+		ft_init(&dt_blob);
+	}
+
+	if (platform_init(promptr))
+		exit();
+	if (console_ops.open && (console_ops.open() < 0))
+		exit();
+	if (platform_ops.fixups)
+		platform_ops.fixups();
+
+	printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
+	       _start, sp);
+
+	prep_kernel(&a1, &a2);
+
+	/* If cmdline came from zimage wrapper or if we can edit the one
+	 * in the dt, print it out and edit it, if possible.
+	 */
+	if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) {
+		get_cmdline(cmdline, COMMAND_LINE_SIZE);
+		printf("\n\rLinux/PowerPC load: %s", cmdline);
+		if (console_ops.edit_cmdline)
+			console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
+		printf("\n\r");
+		set_cmdline(cmdline);
+	}
+
+	if (console_ops.close)
+		console_ops.close();
+
+	kentry = (kernel_entry_t) vmlinux.addr;
+	if (have_dt)
+		kentry(dt_ops.ft_addr(), 0, NULL);
+	else
+		/* XXX initrd addr/size should be passed in properties */
+		kentry(a1, a2, promptr);
+
+	/* console closed so printf below may not work */
+	printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
+	exit();
+}

+ 131 - 13
arch/powerpc/boot/prom.c → arch/powerpc/boot/of.c

@@ -8,15 +8,29 @@
  */
  */
 #include <stdarg.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stddef.h>
+#include "types.h"
+#include "elf.h"
 #include "string.h"
 #include "string.h"
 #include "stdio.h"
 #include "stdio.h"
-#include "prom.h"
+#include "page.h"
+#include "ops.h"
 
 
-int (*prom)(void *);
-phandle chosen_handle;
-ihandle stdout;
+typedef void *ihandle;
+typedef void *phandle;
 
 
-int call_prom(const char *service, int nargs, int nret, ...)
+extern char _end[];
+
+/* Value picked to match that used by yaboot */
+#define PROG_START	0x01400000	/* only used on 64-bit systems */
+#define RAM_END		(512<<20)	/* Fixme: use OF */
+#define	ONE_MB		0x100000
+
+int (*prom) (void *);
+
+
+static unsigned long claim_base;
+
+static int call_prom(const char *service, int nargs, int nret, ...)
 {
 {
 	int i;
 	int i;
 	struct prom_args {
 	struct prom_args {
@@ -45,7 +59,7 @@ int call_prom(const char *service, int nargs, int nret, ...)
 	return (nret > 0)? args.args[nargs]: 0;
 	return (nret > 0)? args.args[nargs]: 0;
 }
 }
 
 
-int call_prom_ret(const char *service, int nargs, int nret,
+static int call_prom_ret(const char *service, int nargs, int nret,
 		  unsigned int *rets, ...)
 		  unsigned int *rets, ...)
 {
 {
 	int i;
 	int i;
@@ -79,11 +93,6 @@ int call_prom_ret(const char *service, int nargs, int nret,
 	return (nret > 0)? args.args[nargs]: 0;
 	return (nret > 0)? args.args[nargs]: 0;
 }
 }
 
 
-int write(void *handle, void *ptr, int nb)
-{
-	return call_prom("write", 3, 1, handle, ptr, nb);
-}
-
 /*
 /*
  * Older OF's require that when claiming a specific range of addresses,
  * Older OF's require that when claiming a specific range of addresses,
  * we claim the physical space in the /memory node and the virtual
  * we claim the physical space in the /memory node and the virtual
@@ -142,7 +151,7 @@ static int check_of_version(void)
 	return 1;
 	return 1;
 }
 }
 
 
-void *claim(unsigned long virt, unsigned long size, unsigned long align)
+static void *claim(unsigned long virt, unsigned long size, unsigned long align)
 {
 {
 	int ret;
 	int ret;
 	unsigned int result;
 	unsigned int result;
@@ -151,7 +160,7 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
 		need_map = check_of_version();
 		need_map = check_of_version();
 	if (align || !need_map)
 	if (align || !need_map)
 		return (void *) call_prom("claim", 3, 1, virt, size, align);
 		return (void *) call_prom("claim", 3, 1, virt, size, align);
-	
+
 	ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
 	ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
 			    align, size, virt);
 			    align, size, virt);
 	if (ret != 0 || result == -1)
 	if (ret != 0 || result == -1)
@@ -163,3 +172,112 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
 			0x12, size, virt, virt);
 			0x12, size, virt, virt);
 	return (void *) virt;
 	return (void *) virt;
 }
 }
+
+static void *of_try_claim(u32 size)
+{
+	unsigned long addr = 0;
+	static u8 first_time = 1;
+
+	if (first_time) {
+		claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+		first_time = 0;
+	}
+
+	for(; claim_base < RAM_END; claim_base += ONE_MB) {
+#ifdef DEBUG
+		printf("    trying: 0x%08lx\n\r", claim_base);
+#endif
+		addr = (unsigned long)claim(claim_base, size, 0);
+		if ((void *)addr != (void *)-1)
+			break;
+	}
+	if (addr == 0)
+		return NULL;
+	claim_base = PAGE_ALIGN(claim_base + size);
+	return (void *)addr;
+}
+
+static void of_image_hdr(const void *hdr)
+{
+	const Elf64_Ehdr *elf64 = hdr;
+
+	if (elf64->e_ident[EI_CLASS] == ELFCLASS64) {
+		/*
+		 * Maintain a "magic" minimum address. This keeps some older
+		 * firmware platforms running.
+		 */
+		if (claim_base < PROG_START)
+			claim_base = PROG_START;
+	}
+}
+
+static void of_exit(void)
+{
+	call_prom("exit", 0, 0);
+}
+
+/*
+ * OF device tree routines
+ */
+static void *of_finddevice(const char *name)
+{
+	return (phandle) call_prom("finddevice", 1, 1, name);
+}
+
+static int of_getprop(const void *phandle, const char *name, void *buf,
+		const int buflen)
+{
+	return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
+}
+
+static int of_setprop(const void *phandle, const char *name, const void *buf,
+		const int buflen)
+{
+	return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
+}
+
+/*
+ * OF console routines
+ */
+static void *of_stdout_handle;
+
+static int of_console_open(void)
+{
+	void *devp;
+
+	if (((devp = finddevice("/chosen")) != NULL)
+			&& (getprop(devp, "stdout", &of_stdout_handle,
+				sizeof(of_stdout_handle))
+				== sizeof(of_stdout_handle)))
+		return 0;
+
+	return -1;
+}
+
+static void of_console_write(char *buf, int len)
+{
+	call_prom("write", 3, 1, of_stdout_handle, buf, len);
+}
+
+int platform_init(void *promptr)
+{
+	platform_ops.fixups = NULL;
+	platform_ops.image_hdr = of_image_hdr;
+	platform_ops.malloc = of_try_claim;
+	platform_ops.free = NULL;
+	platform_ops.exit = of_exit;
+
+	dt_ops.finddevice = of_finddevice;
+	dt_ops.getprop = of_getprop;
+	dt_ops.setprop = of_setprop;
+	dt_ops.translate_addr = NULL;
+
+	console_ops.open = of_console_open;
+	console_ops.write = of_console_write;
+	console_ops.edit_cmdline = NULL;
+	console_ops.close = NULL;
+	console_ops.data = NULL;
+
+	prom = (int (*)(void *))promptr;
+	return 0;
+}

+ 100 - 0
arch/powerpc/boot/ops.h

@@ -0,0 +1,100 @@
+/*
+ * Global definition of all the bootwrapper operations.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2006 (c) MontaVista Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef _PPC_BOOT_OPS_H_
+#define _PPC_BOOT_OPS_H_
+
+#include "types.h"
+
+#define	COMMAND_LINE_SIZE	512
+#define	MAX_PATH_LEN		256
+#define	MAX_PROP_LEN		256 /* What should this be? */
+
+/* Platform specific operations */
+struct platform_ops {
+	void	(*fixups)(void);
+	void	(*image_hdr)(const void *);
+	void *	(*malloc)(u32 size);
+	void	(*free)(void *ptr, u32 size);
+	void	(*exit)(void);
+};
+extern struct platform_ops platform_ops;
+
+/* Device Tree operations */
+struct dt_ops {
+	void *	(*finddevice)(const char *name);
+	int	(*getprop)(const void *node, const char *name, void *buf,
+			const int buflen);
+	int	(*setprop)(const void *node, const char *name,
+			const void *buf, const int buflen);
+	u64	(*translate_addr)(const char *path, const u32 *in_addr,
+			const u32 addr_len);
+	unsigned long (*ft_addr)(void);
+};
+extern struct dt_ops dt_ops;
+
+/* Console operations */
+struct console_ops {
+	int	(*open)(void);
+	void	(*write)(char *buf, int len);
+	void	(*edit_cmdline)(char *buf, int len);
+	void	(*close)(void);
+	void	*data;
+};
+extern struct console_ops console_ops;
+
+/* Serial console operations */
+struct serial_console_data {
+	int		(*open)(void);
+	void		(*putc)(unsigned char c);
+	unsigned char	(*getc)(void);
+	u8		(*tstc)(void);
+	void		(*close)(void);
+};
+
+extern int platform_init(void *promptr);
+extern void simple_alloc_init(void);
+extern void ft_init(void *dt_blob);
+extern int serial_console_init(void);
+
+static inline void *finddevice(const char *name)
+{
+	return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
+}
+
+static inline int getprop(void *devp, const char *name, void *buf, int buflen)
+{
+	return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
+}
+
+static inline int setprop(void *devp, const char *name, void *buf, int buflen)
+{
+	return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
+}
+
+static inline void *malloc(u32 size)
+{
+	return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
+}
+
+static inline void free(void *ptr, u32 size)
+{
+	if (platform_ops.free)
+		platform_ops.free(ptr, size);
+}
+
+static inline void exit(void)
+{
+	if (platform_ops.exit)
+		platform_ops.exit();
+	for(;;);
+}
+
+#endif /* _PPC_BOOT_OPS_H_ */

+ 0 - 41
arch/powerpc/boot/prom.h

@@ -1,41 +0,0 @@
-#ifndef _PPC_BOOT_PROM_H_
-#define _PPC_BOOT_PROM_H_
-
-typedef void *phandle;
-typedef void *ihandle;
-
-extern int (*prom) (void *);
-extern phandle chosen_handle;
-extern ihandle stdout;
-
-int	call_prom(const char *service, int nargs, int nret, ...);
-int	call_prom_ret(const char *service, int nargs, int nret,
-		      unsigned int *rets, ...);
-
-extern int write(void *handle, void *ptr, int nb);
-extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
-
-static inline void exit(void)
-{
-	call_prom("exit", 0, 0);
-}
-
-static inline phandle finddevice(const char *name)
-{
-	return (phandle) call_prom("finddevice", 1, 1, name);
-}
-
-static inline int getprop(void *phandle, const char *name,
-			  void *buf, int buflen)
-{
-	return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
-}
-
-
-static inline int setprop(void *phandle, const char *name,
-			  void *buf, int buflen)
-{
-	return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
-}
-
-#endif				/* _PPC_BOOT_PROM_H_ */

+ 2 - 2
arch/powerpc/boot/stdio.c

@@ -10,7 +10,7 @@
 #include <stddef.h>
 #include <stddef.h>
 #include "string.h"
 #include "string.h"
 #include "stdio.h"
 #include "stdio.h"
-#include "prom.h"
+#include "ops.h"
 
 
 size_t strnlen(const char * s, size_t count)
 size_t strnlen(const char * s, size_t count)
 {
 {
@@ -320,6 +320,6 @@ printf(const char *fmt, ...)
 	va_start(args, fmt);
 	va_start(args, fmt);
 	n = vsprintf(sprint_buf, fmt, args);
 	n = vsprintf(sprint_buf, fmt, args);
 	va_end(args);
 	va_end(args);
-	write(stdout, sprint_buf, n);
+	console_ops.write(sprint_buf, n);
 	return n;
 	return n;
 }
 }

+ 8 - 0
arch/powerpc/boot/stdio.h

@@ -1,8 +1,16 @@
 #ifndef _PPC_BOOT_STDIO_H_
 #ifndef _PPC_BOOT_STDIO_H_
 #define _PPC_BOOT_STDIO_H_
 #define _PPC_BOOT_STDIO_H_
 
 
+#include <stdarg.h>
+
+#define	ENOMEM		12	/* Out of Memory */
+#define	EINVAL		22	/* Invalid argument */
+#define ENOSPC		28	/* No space left on device */
+
 extern int printf(const char *fmt, ...);
 extern int printf(const char *fmt, ...);
 
 
+#define fprintf(fmt, args...)	printf(args)
+
 extern int sprintf(char *buf, const char *fmt, ...);
 extern int sprintf(char *buf, const char *fmt, ...);
 
 
 extern int vsprintf(char *buf, const char *fmt, va_list args);
 extern int vsprintf(char *buf, const char *fmt, va_list args);

+ 23 - 0
arch/powerpc/boot/types.h

@@ -0,0 +1,23 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+typedef unsigned char		u8;
+typedef unsigned short		u16;
+typedef unsigned int		u32;
+typedef unsigned long long	u64;
+
+#define min(x,y) ({ \
+	typeof(x) _x = (x);	\
+	typeof(y) _y = (y);	\
+	(void) (&_x == &_y);	\
+	_x < _y ? _x : _y; })
+
+#define max(x,y) ({ \
+	typeof(x) _x = (x);	\
+	typeof(y) _y = (y);	\
+	(void) (&_x == &_y);	\
+	_x > _y ? _x : _y; })
+
+#endif /* _TYPES_H_ */

+ 1 - 1
arch/powerpc/configs/maple_defconfig

@@ -496,7 +496,7 @@ CONFIG_E1000=y
 # CONFIG_SKY2 is not set
 # CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
+CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_MV643XX_ETH is not set
 # CONFIG_MV643XX_ETH is not set
 
 

+ 2 - 2
arch/powerpc/kernel/Makefile

@@ -16,7 +16,7 @@ obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
 obj-y				+= vdso32/
 obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 				   signal_64.o ptrace32.o \
 				   signal_64.o ptrace32.o \
-				   paca.o cpu_setup_power4.o \
+				   paca.o cpu_setup_ppc970.o \
 				   firmware.o sysfs.o
 				   firmware.o sysfs.o
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
@@ -51,7 +51,7 @@ extra-$(CONFIG_8xx)		:= head_8xx.o
 extra-y				+= vmlinux.lds
 extra-y				+= vmlinux.lds
 
 
 obj-y				+= time.o prom.o traps.o setup-common.o \
 obj-y				+= time.o prom.o traps.o setup-common.o \
-				   udbg.o misc.o
+				   udbg.o misc.o io.o
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o
 obj-$(CONFIG_PPC64)		+= misc_64.o dma_64.o iommu.o
 obj-$(CONFIG_PPC64)		+= misc_64.o dma_64.o iommu.o
 obj-$(CONFIG_PPC_MULTIPLATFORM)	+= prom_init.o
 obj-$(CONFIG_PPC_MULTIPLATFORM)	+= prom_init.o

+ 16 - 1
arch/powerpc/kernel/asm-offsets.c

@@ -40,9 +40,10 @@
 #ifdef CONFIG_PPC64
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #include <asm/paca.h>
 #include <asm/lppaca.h>
 #include <asm/lppaca.h>
-#include <asm/iseries/hv_lp_event.h>
 #include <asm/cache.h>
 #include <asm/cache.h>
 #include <asm/compat.h>
 #include <asm/compat.h>
+#include <asm/mmu.h>
+#include <asm/hvcall.h>
 #endif
 #endif
 
 
 #define DEFINE(sym, val) \
 #define DEFINE(sym, val) \
@@ -136,11 +137,18 @@ int main(void)
 	DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
 	DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
 	DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
 	DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
 	DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
 	DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
+	DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
+	DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
 
 
+	DEFINE(SLBSHADOW_STACKVSID,
+	       offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid));
+	DEFINE(SLBSHADOW_STACKESID,
+	       offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid));
 	DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
 	DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
 	DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
 	DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
 	DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
 	DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
 	DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
 	DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
+	DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
 #endif /* CONFIG_PPC64 */
 #endif /* CONFIG_PPC64 */
 
 
 	/* RTAS */
 	/* RTAS */
@@ -159,6 +167,12 @@ int main(void)
 	/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
 	/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
 	DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
 	DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
 	DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
 	DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
+
+	/* hcall statistics */
+	DEFINE(HCALL_STAT_SIZE, sizeof(struct hcall_stats));
+	DEFINE(HCALL_STAT_CALLS, offsetof(struct hcall_stats, num_calls));
+	DEFINE(HCALL_STAT_TB, offsetof(struct hcall_stats, tb_total));
+	DEFINE(HCALL_STAT_PURR, offsetof(struct hcall_stats, purr_total));
 #endif /* CONFIG_PPC64 */
 #endif /* CONFIG_PPC64 */
 	DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
 	DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
 	DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
 	DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
@@ -240,6 +254,7 @@ int main(void)
 	DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
 	DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
 	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
 	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
 	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
 	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+	DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
 
 
 #ifndef CONFIG_PPC64
 #ifndef CONFIG_PPC64
 	DEFINE(pbe_address, offsetof(struct pbe, address));
 	DEFINE(pbe_address, offsetof(struct pbe, address));

+ 12 - 12
arch/powerpc/kernel/btext.c

@@ -158,35 +158,35 @@ int btext_initialize(struct device_node *np)
 {
 {
 	unsigned int width, height, depth, pitch;
 	unsigned int width, height, depth, pitch;
 	unsigned long address = 0;
 	unsigned long address = 0;
-	u32 *prop;
+	const u32 *prop;
 
 
-	prop = (u32 *)get_property(np, "linux,bootx-width", NULL);
+	prop = get_property(np, "linux,bootx-width", NULL);
 	if (prop == NULL)
 	if (prop == NULL)
-		prop = (u32 *)get_property(np, "width", NULL);
+		prop = get_property(np, "width", NULL);
 	if (prop == NULL)
 	if (prop == NULL)
 		return -EINVAL;
 		return -EINVAL;
 	width = *prop;
 	width = *prop;
-	prop = (u32 *)get_property(np, "linux,bootx-height", NULL);
+	prop = get_property(np, "linux,bootx-height", NULL);
 	if (prop == NULL)
 	if (prop == NULL)
-		prop = (u32 *)get_property(np, "height", NULL);
+		prop = get_property(np, "height", NULL);
 	if (prop == NULL)
 	if (prop == NULL)
 		return -EINVAL;
 		return -EINVAL;
 	height = *prop;
 	height = *prop;
-	prop = (u32 *)get_property(np, "linux,bootx-depth", NULL);
+	prop = get_property(np, "linux,bootx-depth", NULL);
 	if (prop == NULL)
 	if (prop == NULL)
-		prop = (u32 *)get_property(np, "depth", NULL);
+		prop = get_property(np, "depth", NULL);
 	if (prop == NULL)
 	if (prop == NULL)
 		return -EINVAL;
 		return -EINVAL;
 	depth = *prop;
 	depth = *prop;
 	pitch = width * ((depth + 7) / 8);
 	pitch = width * ((depth + 7) / 8);
-	prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL);
+	prop = get_property(np, "linux,bootx-linebytes", NULL);
 	if (prop == NULL)
 	if (prop == NULL)
-		prop = (u32 *)get_property(np, "linebytes", NULL);
+		prop = get_property(np, "linebytes", NULL);
 	if (prop)
 	if (prop)
 		pitch = *prop;
 		pitch = *prop;
 	if (pitch == 1)
 	if (pitch == 1)
 		pitch = 0x1000;
 		pitch = 0x1000;
-	prop = (u32 *)get_property(np, "address", NULL);
+	prop = get_property(np, "address", NULL);
 	if (prop)
 	if (prop)
 		address = *prop;
 		address = *prop;
 
 
@@ -214,11 +214,11 @@ int btext_initialize(struct device_node *np)
 
 
 int __init btext_find_display(int allow_nonstdout)
 int __init btext_find_display(int allow_nonstdout)
 {
 {
-	char *name;
+	const char *name;
 	struct device_node *np = NULL; 
 	struct device_node *np = NULL; 
 	int rc = -ENODEV;
 	int rc = -ENODEV;
 
 
-	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+	name = get_property(of_chosen, "linux,stdout-path", NULL);
 	if (name != NULL) {
 	if (name != NULL) {
 		np = of_find_node_by_path(name);
 		np = of_find_node_by_path(name);
 		if (np != NULL) {
 		if (np != NULL) {

+ 26 - 77
arch/powerpc/kernel/cpu_setup_power4.S → arch/powerpc/kernel/cpu_setup_ppc970.S

@@ -16,27 +16,12 @@
 #include <asm/asm-offsets.h>
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 #include <asm/cache.h>
 
 
-_GLOBAL(__970_cpu_preinit)
-	/*
-	 * Do nothing if not running in HV mode
-	 */
+_GLOBAL(__cpu_preinit_ppc970)
+	/* Do nothing if not running in HV mode */
 	mfmsr	r0
 	mfmsr	r0
 	rldicl.	r0,r0,4,63
 	rldicl.	r0,r0,4,63
 	beqlr
 	beqlr
 
 
-	/*
-	 * Deal only with PPC970 and PPC970FX.
-	 */
-	mfspr	r0,SPRN_PVR
-	srwi	r0,r0,16
-	cmpwi	r0,0x39
-	beq	1f
-	cmpwi	r0,0x3c
-	beq	1f
-	cmpwi	r0,0x44
-	bnelr
-1:
-
 	/* Make sure HID4:rm_ci is off before MMU is turned off, that large
 	/* Make sure HID4:rm_ci is off before MMU is turned off, that large
 	 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
 	 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
 	 * HID5:DCBZ32_ill
 	 * HID5:DCBZ32_ill
@@ -72,23 +57,6 @@ _GLOBAL(__970_cpu_preinit)
 	isync
 	isync
 	blr
 	blr
 
 
-_GLOBAL(__setup_cpu_ppc970)
-	mfspr	r0,SPRN_HID0
-	li	r11,5			/* clear DOZE and SLEEP */
-	rldimi	r0,r11,52,8		/* set NAP and DPM */
-	li	r11,0
-	rldimi	r0,r11,32,31		/* clear EN_ATTN */
-	mtspr	SPRN_HID0,r0
-	mfspr	r0,SPRN_HID0
-	mfspr	r0,SPRN_HID0
-	mfspr	r0,SPRN_HID0
-	mfspr	r0,SPRN_HID0
-	mfspr	r0,SPRN_HID0
-	mfspr	r0,SPRN_HID0
-	sync
-	isync
-	blr
-
 /* Definitions for the table use to save CPU states */
 /* Definitions for the table use to save CPU states */
 #define CS_HID0		0
 #define CS_HID0		0
 #define CS_HID1		8
 #define CS_HID1		8
@@ -103,33 +71,30 @@ cpu_state_storage:
 	.balign	L1_CACHE_BYTES,0
 	.balign	L1_CACHE_BYTES,0
 	.text
 	.text
 
 
-/* Called in normal context to backup CPU 0 state. This
- * does not include cache settings. This function is also
- * called for machine sleep. This does not include the MMU
- * setup, BATs, etc... but rather the "special" registers
- * like HID0, HID1, HID4, etc...
- */
-_GLOBAL(__save_cpu_setup)
-	/* Some CR fields are volatile, we back it up all */
-	mfcr	r7
-
-	/* Get storage ptr */
-	LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
 
 
-	/* We only deal with 970 for now */
-	mfspr	r0,SPRN_PVR
-	srwi	r0,r0,16
-	cmpwi	r0,0x39
-	beq	1f
-	cmpwi	r0,0x3c
-	beq	1f
-	cmpwi	r0,0x44
-	bne	2f
-
-1:	/* skip if not running in HV mode */
+_GLOBAL(__setup_cpu_ppc970)
+	/* Do nothing if not running in HV mode */
 	mfmsr	r0
 	mfmsr	r0
 	rldicl.	r0,r0,4,63
 	rldicl.	r0,r0,4,63
-	beq	2f
+	beqlr
+
+	mfspr	r0,SPRN_HID0
+	li	r11,5			/* clear DOZE and SLEEP */
+	rldimi	r0,r11,52,8		/* set NAP and DPM */
+	li	r11,0
+	rldimi	r0,r11,32,31		/* clear EN_ATTN */
+	mtspr	SPRN_HID0,r0
+	mfspr	r0,SPRN_HID0
+	mfspr	r0,SPRN_HID0
+	mfspr	r0,SPRN_HID0
+	mfspr	r0,SPRN_HID0
+	mfspr	r0,SPRN_HID0
+	mfspr	r0,SPRN_HID0
+	sync
+	isync
+
+	/* Save away cpu state */
+	LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
 
 
 	/* Save HID0,1,4 and 5 */
 	/* Save HID0,1,4 and 5 */
 	mfspr	r3,SPRN_HID0
 	mfspr	r3,SPRN_HID0
@@ -141,35 +106,19 @@ _GLOBAL(__save_cpu_setup)
 	mfspr	r3,SPRN_HID5
 	mfspr	r3,SPRN_HID5
 	std	r3,CS_HID5(r5)
 	std	r3,CS_HID5(r5)
 
 
-2:
-	mtcr	r7
 	blr
 	blr
 
 
 /* Called with no MMU context (typically MSR:IR/DR off) to
 /* Called with no MMU context (typically MSR:IR/DR off) to
  * restore CPU state as backed up by the previous
  * restore CPU state as backed up by the previous
  * function. This does not include cache setting
  * function. This does not include cache setting
  */
  */
-_GLOBAL(__restore_cpu_setup)
-	/* Get storage ptr (FIXME when using anton reloc as we
-	 * are running with translation disabled here
-	 */
-	LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
-
-	/* We only deal with 970 for now */
-	mfspr	r0,SPRN_PVR
-	srwi	r0,r0,16
-	cmpwi	r0,0x39
-	beq	1f
-	cmpwi	r0,0x3c
-	beq	1f
-	cmpwi	r0,0x44
-	bnelr
-
-1:	/* skip if not running in HV mode */
+_GLOBAL(__restore_cpu_ppc970)
+	/* Do nothing if not running in HV mode */
 	mfmsr	r0
 	mfmsr	r0
 	rldicl.	r0,r0,4,63
 	rldicl.	r0,r0,4,63
 	beqlr
 	beqlr
 
 
+	LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
 	/* Before accessing memory, we make sure rm_ci is clear */
 	/* Before accessing memory, we make sure rm_ci is clear */
 	li	r0,0
 	li	r0,0
 	mfspr	r3,SPRN_HID4
 	mfspr	r3,SPRN_HID4

+ 21 - 0
arch/powerpc/kernel/cputable.c

@@ -39,7 +39,10 @@ extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
 #endif /* CONFIG_PPC32 */
 #endif /* CONFIG_PPC32 */
+#ifdef CONFIG_PPC64
 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
+extern void __restore_cpu_ppc970(void);
+#endif /* CONFIG_PPC64 */
 
 
 /* This table only contains "desktop" CPUs, it need to be filled with embedded
 /* This table only contains "desktop" CPUs, it need to be filled with embedded
  * ones as well...
  * ones as well...
@@ -55,6 +58,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
 #define COMMON_USER_POWER6	(COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
 #define COMMON_USER_POWER6	(COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
 				 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
 				 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
 				 PPC_FEATURE_TRUE_LE)
 				 PPC_FEATURE_TRUE_LE)
+#define COMMON_USER_PA6T	(COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
+				 PPC_FEATURE_TRUE_LE | \
+				 PPC_FEATURE_HAS_ALTIVEC_COMP)
 #define COMMON_USER_BOOKE	(PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
 #define COMMON_USER_BOOKE	(PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
 				 PPC_FEATURE_BOOKE)
 				 PPC_FEATURE_BOOKE)
 
 
@@ -184,6 +190,7 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_ppc970,
 		.cpu_setup		= __setup_cpu_ppc970,
+		.cpu_restore		= __restore_cpu_ppc970,
 		.oprofile_cpu_type	= "ppc64/970",
 		.oprofile_cpu_type	= "ppc64/970",
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.platform		= "ppc970",
 		.platform		= "ppc970",
@@ -199,6 +206,7 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_ppc970,
 		.cpu_setup		= __setup_cpu_ppc970,
+		.cpu_restore		= __restore_cpu_ppc970,
 		.oprofile_cpu_type	= "ppc64/970",
 		.oprofile_cpu_type	= "ppc64/970",
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.platform		= "ppc970",
 		.platform		= "ppc970",
@@ -214,6 +222,7 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_ppc970,
 		.cpu_setup		= __setup_cpu_ppc970,
+		.cpu_restore		= __restore_cpu_ppc970,
 		.oprofile_cpu_type	= "ppc64/970",
 		.oprofile_cpu_type	= "ppc64/970",
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.platform		= "ppc970",
 		.platform		= "ppc970",
@@ -280,6 +289,17 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.platform		= "ppc-cell-be",
 		.platform		= "ppc-cell-be",
 	},
 	},
+	{	/* PA Semi PA6T */
+		.pvr_mask		= 0x7fff0000,
+		.pvr_value		= 0x00900000,
+		.cpu_name		= "PA6T",
+		.cpu_features		= CPU_FTRS_PA6T,
+		.cpu_user_features	= COMMON_USER_PA6T,
+		.icache_bsize		= 64,
+		.dcache_bsize		= 64,
+		.num_pmcs		= 6,
+		.platform		= "pa6t",
+	},
 	{	/* default match */
 	{	/* default match */
 		.pvr_mask		= 0x00000000,
 		.pvr_mask		= 0x00000000,
 		.pvr_value		= 0x00000000,
 		.pvr_value		= 0x00000000,
@@ -929,6 +949,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	},
 	{	/* 405EP */
 	{	/* 405EP */
 		.pvr_mask		= 0xffff0000,
 		.pvr_mask		= 0xffff0000,

+ 1 - 1
arch/powerpc/kernel/crash_dump.c

@@ -80,7 +80,7 @@ static int __init parse_savemaxmem(char *p)
 }
 }
 __setup("savemaxmem=", parse_savemaxmem);
 __setup("savemaxmem=", parse_savemaxmem);
 
 
-/*
+/**
  * copy_oldmem_page - copy one page from "oldmem"
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
  * @pfn: page frame number to be copied
  * @buf: target memory address for the copy; this can be in kernel address
  * @buf: target memory address for the copy; this can be in kernel address

+ 28 - 37
arch/powerpc/kernel/dma_64.c

@@ -35,10 +35,9 @@ int dma_supported(struct device *dev, u64 mask)
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		return dma_ops->dma_supported(dev, mask);
-	BUG();
-	return 0;
+	BUG_ON(!dma_ops);
+
+	return dma_ops->dma_supported(dev, mask);
 }
 }
 EXPORT_SYMBOL(dma_supported);
 EXPORT_SYMBOL(dma_supported);
 
 
@@ -66,10 +65,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
-	BUG();
-	return NULL;
+	BUG_ON(!dma_ops);
+
+	return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
 }
 }
 EXPORT_SYMBOL(dma_alloc_coherent);
 EXPORT_SYMBOL(dma_alloc_coherent);
 
 
@@ -78,10 +76,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
-	else
-		BUG();
+	BUG_ON(!dma_ops);
+
+	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
 }
 }
 EXPORT_SYMBOL(dma_free_coherent);
 EXPORT_SYMBOL(dma_free_coherent);
 
 
@@ -90,10 +87,9 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		return dma_ops->map_single(dev, cpu_addr, size, direction);
-	BUG();
-	return (dma_addr_t)0;
+	BUG_ON(!dma_ops);
+
+	return dma_ops->map_single(dev, cpu_addr, size, direction);
 }
 }
 EXPORT_SYMBOL(dma_map_single);
 EXPORT_SYMBOL(dma_map_single);
 
 
@@ -102,10 +98,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		dma_ops->unmap_single(dev, dma_addr, size, direction);
-	else
-		BUG();
+	BUG_ON(!dma_ops);
+
+	dma_ops->unmap_single(dev, dma_addr, size, direction);
 }
 }
 EXPORT_SYMBOL(dma_unmap_single);
 EXPORT_SYMBOL(dma_unmap_single);
 
 
@@ -115,11 +110,10 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		return dma_ops->map_single(dev,
-				(page_address(page) + offset), size, direction);
-	BUG();
-	return (dma_addr_t)0;
+	BUG_ON(!dma_ops);
+
+	return dma_ops->map_single(dev, page_address(page) + offset, size,
+			direction);
 }
 }
 EXPORT_SYMBOL(dma_map_page);
 EXPORT_SYMBOL(dma_map_page);
 
 
@@ -128,10 +122,9 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		dma_ops->unmap_single(dev, dma_address, size, direction);
-	else
-		BUG();
+	BUG_ON(!dma_ops);
+
+	dma_ops->unmap_single(dev, dma_address, size, direction);
 }
 }
 EXPORT_SYMBOL(dma_unmap_page);
 EXPORT_SYMBOL(dma_unmap_page);
 
 
@@ -140,10 +133,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		return dma_ops->map_sg(dev, sg, nents, direction);
-	BUG();
-	return 0;
+	BUG_ON(!dma_ops);
+
+	return dma_ops->map_sg(dev, sg, nents, direction);
 }
 }
 EXPORT_SYMBOL(dma_map_sg);
 EXPORT_SYMBOL(dma_map_sg);
 
 
@@ -152,9 +144,8 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
 {
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
 
-	if (dma_ops)
-		dma_ops->unmap_sg(dev, sg, nhwentries, direction);
-	else
-		BUG();
+	BUG_ON(!dma_ops);
+
+	dma_ops->unmap_sg(dev, sg, nhwentries, direction);
 }
 }
 EXPORT_SYMBOL(dma_unmap_sg);
 EXPORT_SYMBOL(dma_unmap_sg);

+ 8 - 0
arch/powerpc/kernel/entry_64.S

@@ -375,6 +375,14 @@ BEGIN_FTR_SECTION
 	ld	r7,KSP_VSID(r4)	/* Get new stack's VSID */
 	ld	r7,KSP_VSID(r4)	/* Get new stack's VSID */
 	oris	r0,r6,(SLB_ESID_V)@h
 	oris	r0,r6,(SLB_ESID_V)@h
 	ori	r0,r0,(SLB_NUM_BOLTED-1)@l
 	ori	r0,r0,(SLB_NUM_BOLTED-1)@l
+
+	/* Update the last bolted SLB */
+	ld	r9,PACA_SLBSHADOWPTR(r13)
+	li	r12,0
+	std	r12,SLBSHADOW_STACKESID(r9) /* Clear ESID */
+	std	r7,SLBSHADOW_STACKVSID(r9)  /* Save VSID */
+	std	r0,SLBSHADOW_STACKESID(r9)  /* Save ESID */
+
 	slbie	r6
 	slbie	r6
 	slbie	r6		/* Workaround POWER5 < DD2.1 issue */
 	slbie	r6		/* Workaround POWER5 < DD2.1 issue */
 	slbmte	r7,r0
 	slbmte	r7,r0

+ 34 - 20
arch/powerpc/kernel/head_64.S

@@ -132,7 +132,7 @@ _GLOBAL(__secondary_hold)
 	bne	100b
 	bne	100b
 
 
 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
-	LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init)
+	LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init)
 	mtctr	r4
 	mtctr	r4
 	mr	r3,r24
 	mr	r3,r24
 	bctr
 	bctr
@@ -1484,19 +1484,17 @@ fwnmi_data_area:
         . = 0x8000
         . = 0x8000
 
 
 /*
 /*
- * On pSeries, secondary processors spin in the following code.
+ * On pSeries and most other platforms, secondary processors spin
+ * in the following code.
  * At entry, r3 = this processor's number (physical cpu id)
  * At entry, r3 = this processor's number (physical cpu id)
  */
  */
-_GLOBAL(pSeries_secondary_smp_init)
+_GLOBAL(generic_secondary_smp_init)
 	mr	r24,r3
 	mr	r24,r3
 	
 	
 	/* turn on 64-bit mode */
 	/* turn on 64-bit mode */
 	bl	.enable_64b_mode
 	bl	.enable_64b_mode
 	isync
 	isync
 
 
-	/* Copy some CPU settings from CPU 0 */
-	bl	.__restore_cpu_setup
-
 	/* Set up a paca value for this processor. Since we have the
 	/* Set up a paca value for this processor. Since we have the
 	 * physical cpu id in r24, we need to search the pacas to find
 	 * physical cpu id in r24, we need to search the pacas to find
 	 * which logical id maps to our physical one.
 	 * which logical id maps to our physical one.
@@ -1522,15 +1520,28 @@ _GLOBAL(pSeries_secondary_smp_init)
 					/* start.			 */
 					/* start.			 */
 	sync
 	sync
 
 
-	/* Create a temp kernel stack for use before relocation is on.	*/
+#ifndef CONFIG_SMP
+	b	3b			/* Never go on non-SMP		 */
+#else
+	cmpwi	0,r23,0
+	beq	3b			/* Loop until told to go	 */
+
+	/* See if we need to call a cpu state restore handler */
+	LOAD_REG_IMMEDIATE(r23, cur_cpu_spec)
+	ld	r23,0(r23)
+	ld	r23,CPU_SPEC_RESTORE(r23)
+	cmpdi	0,r23,0
+	beq	4f
+	ld	r23,0(r23)
+	mtctr	r23
+	bctrl
+
+4:	/* Create a temp kernel stack for use before relocation is on.	*/
 	ld	r1,PACAEMERGSP(r13)
 	ld	r1,PACAEMERGSP(r13)
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
 
-	cmpwi	0,r23,0
-#ifdef CONFIG_SMP
-	bne	.__secondary_start
+	b	.__secondary_start
 #endif
 #endif
-	b 	3b			/* Loop until told to go	 */
 
 
 #ifdef CONFIG_PPC_ISERIES
 #ifdef CONFIG_PPC_ISERIES
 _STATIC(__start_initialization_iSeries)
 _STATIC(__start_initialization_iSeries)
@@ -1611,7 +1622,16 @@ _GLOBAL(__start_initialization_multiplatform)
 	bl	.enable_64b_mode
 	bl	.enable_64b_mode
 
 
 	/* Setup some critical 970 SPRs before switching MMU off */
 	/* Setup some critical 970 SPRs before switching MMU off */
-	bl	.__970_cpu_preinit
+	mfspr	r0,SPRN_PVR
+	srwi	r0,r0,16
+	cmpwi	r0,0x39		/* 970 */
+	beq	1f
+	cmpwi	r0,0x3c		/* 970FX */
+	beq	1f
+	cmpwi	r0,0x44		/* 970MP */
+	bne	2f
+1:	bl	.__cpu_preinit_ppc970
+2:
 
 
 	/* Switch off MMU if not already */
 	/* Switch off MMU if not already */
 	LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
 	LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
@@ -1728,7 +1748,7 @@ _STATIC(__after_prom_start)
 _GLOBAL(copy_and_flush)
 _GLOBAL(copy_and_flush)
 	addi	r5,r5,-8
 	addi	r5,r5,-8
 	addi	r6,r6,-8
 	addi	r6,r6,-8
-4:	li	r0,16			/* Use the least common		*/
+4:	li	r0,8			/* Use the smallest common	*/
 					/* denominator cache line	*/
 					/* denominator cache line	*/
 					/* size.  This results in	*/
 					/* size.  This results in	*/
 					/* extra cache line flushes	*/
 					/* extra cache line flushes	*/
@@ -1782,7 +1802,7 @@ _GLOBAL(pmac_secondary_start)
 	isync
 	isync
 
 
 	/* Copy some CPU settings from CPU 0 */
 	/* Copy some CPU settings from CPU 0 */
-	bl	.__restore_cpu_setup
+	bl	.__restore_cpu_ppc970
 
 
 	/* pSeries do that early though I don't think we really need it */
 	/* pSeries do that early though I don't think we really need it */
 	mfmsr	r3
 	mfmsr	r3
@@ -1932,12 +1952,6 @@ _STATIC(start_here_multiplatform)
 	mr	r5,r26
 	mr	r5,r26
 	bl	.identify_cpu
 	bl	.identify_cpu
 
 
-	/* Save some low level config HIDs of CPU0 to be copied to
-	 * other CPUs later on, or used for suspend/resume
-	 */
-	bl	.__save_cpu_setup
-	sync
-
 	/* Do very early kernel initializations, including initial hash table,
 	/* Do very early kernel initializations, including initial hash table,
 	 * stab and slb setup before we turn on relocation.	*/
 	 * stab and slb setup before we turn on relocation.	*/
 
 

+ 3 - 3
arch/powerpc/kernel/ibmebus.c

@@ -167,7 +167,7 @@ static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name,
 		   NULL);
 		   NULL);
 
 
 static struct ibmebus_dev* __devinit ibmebus_register_device_common(
 static struct ibmebus_dev* __devinit ibmebus_register_device_common(
-	struct ibmebus_dev *dev, char *name)
+	struct ibmebus_dev *dev, const char *name)
 {
 {
 	int err = 0;
 	int err = 0;
 
 
@@ -194,10 +194,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node(
 	struct device_node *dn)
 	struct device_node *dn)
 {
 {
 	struct ibmebus_dev *dev;
 	struct ibmebus_dev *dev;
-	char *loc_code;
+	const char *loc_code;
 	int length;
 	int length;
 
 
-	loc_code = (char *)get_property(dn, "ibm,loc-code", NULL);
+	loc_code = get_property(dn, "ibm,loc-code", NULL);
 	if (!loc_code) {
 	if (!loc_code) {
                 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
                 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
 		       __FUNCTION__, dn->name ? dn->name : "<unknown>");
 		       __FUNCTION__, dn->name ? dn->name : "<unknown>");

+ 131 - 0
arch/powerpc/kernel/io.c

@@ -0,0 +1,131 @@
+/*
+ * I/O string operations
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *    Copyright (C) 2006 IBM Corporation
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
+ *
+ * Rewritten in C by Stephen Rothwell.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/firmware.h>
+#include <asm/bug.h>
+
+void _insb(volatile u8 __iomem *port, void *buf, long count)
+{
+	u8 *tbuf = buf;
+	u8 tmp;
+
+	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+	if (unlikely(count <= 0))
+		return;
+	asm volatile("sync");
+	do {
+		tmp = *port;
+		asm volatile("eieio");
+		*tbuf++ = tmp;
+	} while (--count != 0);
+	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
+}
+EXPORT_SYMBOL(_insb);
+
+void _outsb(volatile u8 __iomem *port, const void *buf, long count)
+{
+	const u8 *tbuf = buf;
+
+	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+	if (unlikely(count <= 0))
+		return;
+	asm volatile("sync");
+	do {
+		*port = *tbuf++;
+	} while (--count != 0);
+	asm volatile("sync");
+}
+EXPORT_SYMBOL(_outsb);
+
+void _insw_ns(volatile u16 __iomem *port, void *buf, long count)
+{
+	u16 *tbuf = buf;
+	u16 tmp;
+
+	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+	if (unlikely(count <= 0))
+		return;
+	asm volatile("sync");
+	do {
+		tmp = *port;
+		asm volatile("eieio");
+		*tbuf++ = tmp;
+	} while (--count != 0);
+	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
+}
+EXPORT_SYMBOL(_insw_ns);
+
+void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
+{
+	const u16 *tbuf = buf;
+
+	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+	if (unlikely(count <= 0))
+		return;
+	asm volatile("sync");
+	do {
+		*port = *tbuf++;
+	} while (--count != 0);
+	asm volatile("sync");
+}
+EXPORT_SYMBOL(_outsw_ns);
+
+void _insl_ns(volatile u32 __iomem *port, void *buf, long count)
+{
+	u32 *tbuf = buf;
+	u32 tmp;
+
+	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+	if (unlikely(count <= 0))
+		return;
+	asm volatile("sync");
+	do {
+		tmp = *port;
+		asm volatile("eieio");
+		*tbuf++ = tmp;
+	} while (--count != 0);
+	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
+}
+EXPORT_SYMBOL(_insl_ns);
+
+void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
+{
+	const u32 *tbuf = buf;
+
+	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+	if (unlikely(count <= 0))
+		return;
+	asm volatile("sync");
+	do {
+		*port = *tbuf++;
+	} while (--count != 0);
+	asm volatile("sync");
+}
+EXPORT_SYMBOL(_outsl_ns);

+ 5 - 0
arch/powerpc/kernel/irq.c

@@ -52,6 +52,7 @@
 #include <linux/radix-tree.h>
 #include <linux/radix-tree.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
+#include <linux/pci.h>
 
 
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/system.h>
@@ -875,12 +876,14 @@ int pci_enable_msi(struct pci_dev * pdev)
 	else
 	else
 		return -1;
 		return -1;
 }
 }
+EXPORT_SYMBOL(pci_enable_msi);
 
 
 void pci_disable_msi(struct pci_dev * pdev)
 void pci_disable_msi(struct pci_dev * pdev)
 {
 {
 	if (ppc_md.disable_msi)
 	if (ppc_md.disable_msi)
 		ppc_md.disable_msi(pdev);
 		ppc_md.disable_msi(pdev);
 }
 }
+EXPORT_SYMBOL(pci_disable_msi);
 
 
 void pci_scan_msi_device(struct pci_dev *dev) {}
 void pci_scan_msi_device(struct pci_dev *dev) {}
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
@@ -888,6 +891,8 @@ void pci_disable_msix(struct pci_dev *dev) {}
 void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
 void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
 void disable_msi_mode(struct pci_dev *dev, int pos, int type) {}
 void disable_msi_mode(struct pci_dev *dev, int pos, int type) {}
 void pci_no_msi(void) {}
 void pci_no_msi(void) {}
+EXPORT_SYMBOL(pci_enable_msix);
+EXPORT_SYMBOL(pci_disable_msix);
 
 
 #endif
 #endif
 
 

+ 18 - 17
arch/powerpc/kernel/legacy_serial.c

@@ -39,16 +39,17 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 				  phys_addr_t taddr, unsigned long irq,
 				  phys_addr_t taddr, unsigned long irq,
 				  upf_t flags, int irq_check_parent)
 				  upf_t flags, int irq_check_parent)
 {
 {
-	u32 *clk, *spd, clock = BASE_BAUD * 16;
+	const u32 *clk, *spd;
+	u32 clock = BASE_BAUD * 16;
 	int index;
 	int index;
 
 
 	/* get clock freq. if present */
 	/* get clock freq. if present */
-	clk = (u32 *)get_property(np, "clock-frequency", NULL);
+	clk = get_property(np, "clock-frequency", NULL);
 	if (clk && *clk)
 	if (clk && *clk)
 		clock = *clk;
 		clock = *clk;
 
 
 	/* get default speed if present */
 	/* get default speed if present */
-	spd = (u32 *)get_property(np, "current-speed", NULL);
+	spd = get_property(np, "current-speed", NULL);
 
 
 	/* If we have a location index, then try to use it */
 	/* If we have a location index, then try to use it */
 	if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
 	if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
@@ -113,7 +114,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
 				      struct device_node *soc_dev)
 				      struct device_node *soc_dev)
 {
 {
 	u64 addr;
 	u64 addr;
-	u32 *addrp;
+	const u32 *addrp;
 	upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
 	upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
 	struct device_node *tsi = of_get_parent(np);
 	struct device_node *tsi = of_get_parent(np);
 
 
@@ -144,15 +145,15 @@ static int __init add_legacy_soc_port(struct device_node *np,
 static int __init add_legacy_isa_port(struct device_node *np,
 static int __init add_legacy_isa_port(struct device_node *np,
 				      struct device_node *isa_brg)
 				      struct device_node *isa_brg)
 {
 {
-	u32 *reg;
-	char *typep;
+	const u32 *reg;
+	const char *typep;
 	int index = -1;
 	int index = -1;
 	u64 taddr;
 	u64 taddr;
 
 
 	DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
 	DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
 
 
 	/* Get the ISA port number */
 	/* Get the ISA port number */
-	reg = (u32 *)get_property(np, "reg", NULL);
+	reg = get_property(np, "reg", NULL);
 	if (reg == NULL)
 	if (reg == NULL)
 		return -1;
 		return -1;
 
 
@@ -163,7 +164,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
 	/* Now look for an "ibm,aix-loc" property that gives us ordering
 	/* Now look for an "ibm,aix-loc" property that gives us ordering
 	 * if any...
 	 * if any...
 	 */
 	 */
-	typep = (char *)get_property(np, "ibm,aix-loc", NULL);
+	typep = get_property(np, "ibm,aix-loc", NULL);
 
 
 	/* If we have a location index, then use it */
 	/* If we have a location index, then use it */
 	if (typep && *typep == 'S')
 	if (typep && *typep == 'S')
@@ -188,7 +189,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
 				      struct device_node *pci_dev)
 				      struct device_node *pci_dev)
 {
 {
 	u64 addr, base;
 	u64 addr, base;
-	u32 *addrp;
+	const u32 *addrp;
 	unsigned int flags;
 	unsigned int flags;
 	int iotype, index = -1, lindex = 0;
 	int iotype, index = -1, lindex = 0;
 
 
@@ -227,7 +228,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
 	 * we get to their "reg" property
 	 * we get to their "reg" property
 	 */
 	 */
 	if (np != pci_dev) {
 	if (np != pci_dev) {
-		u32 *reg = (u32 *)get_property(np, "reg", NULL);
+		const u32 *reg = get_property(np, "reg", NULL);
 		if (reg && (*reg < 4))
 		if (reg && (*reg < 4))
 			index = lindex = *reg;
 			index = lindex = *reg;
 	}
 	}
@@ -285,13 +286,13 @@ static void __init setup_legacy_serial_console(int console)
 void __init find_legacy_serial_ports(void)
 void __init find_legacy_serial_ports(void)
 {
 {
 	struct device_node *np, *stdout = NULL;
 	struct device_node *np, *stdout = NULL;
-	char *path;
+	const char *path;
 	int index;
 	int index;
 
 
 	DBG(" -> find_legacy_serial_port()\n");
 	DBG(" -> find_legacy_serial_port()\n");
 
 
 	/* Now find out if one of these is out firmware console */
 	/* Now find out if one of these is out firmware console */
-	path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+	path = get_property(of_chosen, "linux,stdout-path", NULL);
 	if (path != NULL) {
 	if (path != NULL) {
 		stdout = of_find_node_by_path(path);
 		stdout = of_find_node_by_path(path);
 		if (stdout)
 		if (stdout)
@@ -491,8 +492,8 @@ static int __init check_legacy_serial_console(void)
 {
 {
 	struct device_node *prom_stdout = NULL;
 	struct device_node *prom_stdout = NULL;
 	int speed = 0, offset = 0;
 	int speed = 0, offset = 0;
-	char *name;
-	u32 *spd;
+	const char *name;
+	const u32 *spd;
 
 
 	DBG(" -> check_legacy_serial_console()\n");
 	DBG(" -> check_legacy_serial_console()\n");
 
 
@@ -513,7 +514,7 @@ static int __init check_legacy_serial_console(void)
 	}
 	}
 	/* We are getting a weird phandle from OF ... */
 	/* We are getting a weird phandle from OF ... */
 	/* ... So use the full path instead */
 	/* ... So use the full path instead */
-	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+	name = get_property(of_chosen, "linux,stdout-path", NULL);
 	if (name == NULL) {
 	if (name == NULL) {
 		DBG(" no linux,stdout-path !\n");
 		DBG(" no linux,stdout-path !\n");
 		return -ENODEV;
 		return -ENODEV;
@@ -525,12 +526,12 @@ static int __init check_legacy_serial_console(void)
 	}
 	}
 	DBG("stdout is %s\n", prom_stdout->full_name);
 	DBG("stdout is %s\n", prom_stdout->full_name);
 
 
-	name = (char *)get_property(prom_stdout, "name", NULL);
+	name = get_property(prom_stdout, "name", NULL);
 	if (!name) {
 	if (!name) {
 		DBG(" stdout package has no name !\n");
 		DBG(" stdout package has no name !\n");
 		goto not_found;
 		goto not_found;
 	}
 	}
-	spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
+	spd = get_property(prom_stdout, "current-speed", NULL);
 	if (spd)
 	if (spd)
 		speed = *spd;
 		speed = *spd;
 
 

+ 19 - 11
arch/powerpc/kernel/lparcfg.c

@@ -32,7 +32,6 @@
 #include <asm/rtas.h>
 #include <asm/rtas.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/time.h>
-#include <asm/iseries/it_exp_vpd_panel.h>
 #include <asm/prom.h>
 #include <asm/prom.h>
 #include <asm/vdso_datapage.h>
 #include <asm/vdso_datapage.h>
 
 
@@ -183,8 +182,14 @@ static unsigned int h_get_ppp(unsigned long *entitled,
 			      unsigned long *resource)
 			      unsigned long *resource)
 {
 {
 	unsigned long rc;
 	unsigned long rc;
-	rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated,
-			      aggregation, resource);
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall(H_GET_PPP, retbuf);
+
+	*entitled = retbuf[0];
+	*unallocated = retbuf[1];
+	*aggregation = retbuf[2];
+	*resource = retbuf[3];
 
 
 	log_plpar_hcall_return(rc, "H_GET_PPP");
 	log_plpar_hcall_return(rc, "H_GET_PPP");
 
 
@@ -194,8 +199,12 @@ static unsigned int h_get_ppp(unsigned long *entitled,
 static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
 static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
 {
 {
 	unsigned long rc;
 	unsigned long rc;
-	unsigned long dummy;
-	rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy);
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall(H_PIC, retbuf);
+
+	*pool_idle_time = retbuf[0];
+	*num_procs = retbuf[1];
 
 
 	if (rc != H_AUTHORITY)
 	if (rc != H_AUTHORITY)
 		log_plpar_hcall_return(rc, "H_PIC");
 		log_plpar_hcall_return(rc, "H_PIC");
@@ -310,12 +319,11 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
 	int partition_potential_processors;
 	int partition_potential_processors;
 	int partition_active_processors;
 	int partition_active_processors;
 	struct device_node *rtas_node;
 	struct device_node *rtas_node;
-	int *lrdrp = NULL;
+	const int *lrdrp = NULL;
 
 
 	rtas_node = find_path_device("/rtas");
 	rtas_node = find_path_device("/rtas");
 	if (rtas_node)
 	if (rtas_node)
-		lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity",
-		                            NULL);
+		lrdrp = get_property(rtas_node, "ibm,lrdr-capacity", NULL);
 
 
 	if (lrdrp == NULL) {
 	if (lrdrp == NULL) {
 		partition_potential_processors = vdso_data->processorCount;
 		partition_potential_processors = vdso_data->processorCount;
@@ -520,7 +528,8 @@ static int lparcfg_data(struct seq_file *m, void *v)
 	const char *model = "";
 	const char *model = "";
 	const char *system_id = "";
 	const char *system_id = "";
 	const char *tmp;
 	const char *tmp;
-	unsigned int *lp_index_ptr, lp_index = 0;
+	const unsigned int *lp_index_ptr;
+	unsigned int lp_index = 0;
 
 
 	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
 	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
 
 
@@ -540,8 +549,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
 			if (firmware_has_feature(FW_FEATURE_ISERIES))
 			if (firmware_has_feature(FW_FEATURE_ISERIES))
 				system_id += 4;
 				system_id += 4;
 		}
 		}
-		lp_index_ptr = (unsigned int *)
-			get_property(rootdn, "ibm,partition-no", NULL);
+		lp_index_ptr = get_property(rootdn, "ibm,partition-no", NULL);
 		if (lp_index_ptr)
 		if (lp_index_ptr)
 			lp_index = *lp_index_ptr;
 			lp_index = *lp_index_ptr;
 	}
 	}

+ 4 - 6
arch/powerpc/kernel/machine_kexec_64.c

@@ -31,8 +31,8 @@ int default_machine_kexec_prepare(struct kimage *image)
 	unsigned long begin, end;	/* limits of segment */
 	unsigned long begin, end;	/* limits of segment */
 	unsigned long low, high;	/* limits of blocked memory range */
 	unsigned long low, high;	/* limits of blocked memory range */
 	struct device_node *node;
 	struct device_node *node;
-	unsigned long *basep;
-	unsigned int *sizep;
+	const unsigned long *basep;
+	const unsigned int *sizep;
 
 
 	if (!ppc_md.hpte_clear_all)
 	if (!ppc_md.hpte_clear_all)
 		return -ENOENT;
 		return -ENOENT;
@@ -72,10 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image)
 	/* We also should not overwrite the tce tables */
 	/* We also should not overwrite the tce tables */
 	for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
 	for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
 			node = of_find_node_by_type(node, "pci")) {
 			node = of_find_node_by_type(node, "pci")) {
-		basep = (unsigned long *)get_property(node, "linux,tce-base",
-							NULL);
-		sizep = (unsigned int *)get_property(node, "linux,tce-size",
-							NULL);
+		basep = get_property(node, "linux,tce-base", NULL);
+		sizep = get_property(node, "linux,tce-size", NULL);
 		if (basep == NULL || sizep == NULL)
 		if (basep == NULL || sizep == NULL)
 			continue;
 			continue;
 
 

+ 0 - 159
arch/powerpc/kernel/misc.S

@@ -43,162 +43,3 @@ _GLOBAL(add_reloc_offset)
 	add	r3,r3,r5
 	add	r3,r3,r5
 	mtlr	r0
 	mtlr	r0
 	blr
 	blr
-
-/*
- * I/O string operations
- *
- * insb(port, buf, len)
- * outsb(port, buf, len)
- * insw(port, buf, len)
- * outsw(port, buf, len)
- * insl(port, buf, len)
- * outsl(port, buf, len)
- * insw_ns(port, buf, len)
- * outsw_ns(port, buf, len)
- * insl_ns(port, buf, len)
- * outsl_ns(port, buf, len)
- *
- * The *_ns versions don't do byte-swapping.
- */
-_GLOBAL(_insb)
-	sync
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,1
-	blelr-
-00:	lbz	r5,0(r3)
-	eieio
-	stbu	r5,1(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-_GLOBAL(_outsb)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,1
-	blelr-
-	sync
-00:	lbzu	r5,1(r4)
-	stb	r5,0(r3)
-	bdnz	00b
-	sync
-	blr
-
-_GLOBAL(_insw)
-	sync
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-00:	lhbrx	r5,0,r3
-	eieio
-	sthu	r5,2(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-_GLOBAL(_outsw)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-	sync
-00:	lhzu	r5,2(r4)
-	sthbrx	r5,0,r3
-	bdnz	00b
-	sync
-	blr
-
-_GLOBAL(_insl)
-	sync
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-00:	lwbrx	r5,0,r3
-	eieio
-	stwu	r5,4(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-_GLOBAL(_outsl)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-	sync
-00:	lwzu	r5,4(r4)
-	stwbrx	r5,0,r3
-	bdnz	00b
-	sync
-	blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_insw)
-#endif
-_GLOBAL(_insw_ns)
-	sync
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-00:	lhz	r5,0(r3)
-	eieio
-	sthu	r5,2(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_outsw)
-#endif
-_GLOBAL(_outsw_ns)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-	sync
-00:	lhzu	r5,2(r4)
-	sth	r5,0(r3)
-	bdnz	00b
-	sync
-	blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_insl)
-#endif
-_GLOBAL(_insl_ns)
-	sync
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-00:	lwz	r5,0(r3)
-	eieio
-	stwu	r5,4(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_outsl)
-#endif
-_GLOBAL(_outsl_ns)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-	sync
-00:	lwzu	r5,4(r4)
-	stw	r5,0(r3)
-	bdnz	00b
-	sync
-	blr
-

+ 0 - 24
arch/powerpc/kernel/of_device.c

@@ -189,27 +189,9 @@ void of_release_dev(struct device *dev)
 int of_device_register(struct of_device *ofdev)
 int of_device_register(struct of_device *ofdev)
 {
 {
 	int rc;
 	int rc;
-	struct of_device **odprop;
 
 
 	BUG_ON(ofdev->node == NULL);
 	BUG_ON(ofdev->node == NULL);
 
 
-	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
-	if (!odprop) {
-		struct property *new_prop;
-	
-		new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
-			GFP_KERNEL);
-		if (new_prop == NULL)
-			return -ENOMEM;
-		new_prop->name = "linux,device";
-		new_prop->length = sizeof(sizeof(struct of_device *));
-		new_prop->value = (unsigned char *)&new_prop[1];
-		odprop = (struct of_device **)new_prop->value;
-		*odprop = NULL;
-		prom_add_property(ofdev->node, new_prop);
-	}
-	*odprop = ofdev;
-
 	rc = device_register(&ofdev->dev);
 	rc = device_register(&ofdev->dev);
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
@@ -221,14 +203,8 @@ int of_device_register(struct of_device *ofdev)
 
 
 void of_device_unregister(struct of_device *ofdev)
 void of_device_unregister(struct of_device *ofdev)
 {
 {
-	struct of_device **odprop;
-
 	device_remove_file(&ofdev->dev, &dev_attr_devspec);
 	device_remove_file(&ofdev->dev, &dev_attr_devspec);
 
 
-	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
-	if (odprop)
-		*odprop = NULL;
-
 	device_unregister(&ofdev->dev);
 	device_unregister(&ofdev->dev);
 }
 }
 
 

+ 14 - 1
arch/powerpc/kernel/paca.c

@@ -17,6 +17,7 @@
 #include <asm/lppaca.h>
 #include <asm/lppaca.h>
 #include <asm/iseries/it_lp_reg_save.h>
 #include <asm/iseries/it_lp_reg_save.h>
 #include <asm/paca.h>
 #include <asm/paca.h>
+#include <asm/mmu.h>
 
 
 
 
 /* This symbol is provided by the linker - let it fill in the paca
 /* This symbol is provided by the linker - let it fill in the paca
@@ -45,6 +46,17 @@ struct lppaca lppaca[] = {
 	},
 	},
 };
 };
 
 
+/*
+ * 3 persistent SLBs are registered here.  The buffer will be zero
+ * initially, hence will all be invaild until we actually write them.
+ */
+struct slb_shadow slb_shadow[] __cacheline_aligned = {
+	[0 ... (NR_CPUS-1)] = {
+		.persistent = SLB_NUM_BOLTED,
+		.buffer_length = sizeof(struct slb_shadow),
+	},
+};
+
 /* The Paca is an array with one entry per processor.  Each contains an
 /* The Paca is an array with one entry per processor.  Each contains an
  * lppaca, which contains the information shared between the
  * lppaca, which contains the information shared between the
  * hypervisor and Linux.
  * hypervisor and Linux.
@@ -59,7 +71,8 @@ struct lppaca lppaca[] = {
 	.lock_token = 0x8000,						    \
 	.lock_token = 0x8000,						    \
 	.paca_index = (number),		/* Paca Index */		    \
 	.paca_index = (number),		/* Paca Index */		    \
 	.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL,		    \
 	.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL,		    \
-	.hw_cpu_id = 0xffff,
+	.hw_cpu_id = 0xffff,						    \
+	.slb_shadow_ptr = &slb_shadow[number],
 
 
 #ifdef CONFIG_PPC_ISERIES
 #ifdef CONFIG_PPC_ISERIES
 #define PACA_INIT_ISERIES(number)					    \
 #define PACA_INIT_ISERIES(number)					    \

+ 21 - 18
arch/powerpc/kernel/pci_32.c

@@ -633,12 +633,12 @@ pcibios_alloc_controller(void)
 static void
 static void
 make_one_node_map(struct device_node* node, u8 pci_bus)
 make_one_node_map(struct device_node* node, u8 pci_bus)
 {
 {
-	int *bus_range;
+	const int *bus_range;
 	int len;
 	int len;
 
 
 	if (pci_bus >= pci_bus_count)
 	if (pci_bus >= pci_bus_count)
 		return;
 		return;
-	bus_range = (int *) get_property(node, "bus-range", &len);
+	bus_range = get_property(node, "bus-range", &len);
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 		printk(KERN_WARNING "Can't get bus-range for %s, "
 		printk(KERN_WARNING "Can't get bus-range for %s, "
 		       "assuming it starts at 0\n", node->full_name);
 		       "assuming it starts at 0\n", node->full_name);
@@ -648,13 +648,13 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
 
 
 	for (node=node->child; node != 0;node = node->sibling) {
 	for (node=node->child; node != 0;node = node->sibling) {
 		struct pci_dev* dev;
 		struct pci_dev* dev;
-		unsigned int *class_code, *reg;
+		const unsigned int *class_code, *reg;
 	
 	
-		class_code = (unsigned int *) get_property(node, "class-code", NULL);
+		class_code = get_property(node, "class-code", NULL);
 		if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
 		if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
 			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
 			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
 			continue;
 			continue;
-		reg = (unsigned int *)get_property(node, "reg", NULL);
+		reg = get_property(node, "reg", NULL);
 		if (!reg)
 		if (!reg)
 			continue;
 			continue;
 		dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
 		dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
@@ -669,7 +669,7 @@ pcibios_make_OF_bus_map(void)
 {
 {
 	int i;
 	int i;
 	struct pci_controller* hose;
 	struct pci_controller* hose;
-	u8* of_prop_map;
+	struct property *map_prop;
 
 
 	pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
 	pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
 	if (!pci_to_OF_bus_map) {
 	if (!pci_to_OF_bus_map) {
@@ -691,9 +691,12 @@ pcibios_make_OF_bus_map(void)
 			continue;
 			continue;
 		make_one_node_map(node, hose->first_busno);
 		make_one_node_map(node, hose->first_busno);
 	}
 	}
-	of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL);
-	if (of_prop_map)
-		memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);
+	map_prop = of_find_property(find_path_device("/"),
+			"pci-OF-bus-map", NULL);
+	if (map_prop) {
+		BUG_ON(pci_bus_count > map_prop->length);
+		memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count);
+	}
 #ifdef DEBUG
 #ifdef DEBUG
 	printk("PCI->OF bus map:\n");
 	printk("PCI->OF bus map:\n");
 	for (i=0; i<pci_bus_count; i++) {
 	for (i=0; i<pci_bus_count; i++) {
@@ -712,7 +715,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
 	struct device_node* sub_node;
 	struct device_node* sub_node;
 
 
 	for (; node != 0;node = node->sibling) {
 	for (; node != 0;node = node->sibling) {
-		unsigned int *class_code;
+		const unsigned int *class_code;
 	
 	
 		if (filter(node, data))
 		if (filter(node, data))
 			return node;
 			return node;
@@ -722,7 +725,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
 		 * a fake root for all functions of a multi-function device,
 		 * a fake root for all functions of a multi-function device,
 		 * we go down them as well.
 		 * we go down them as well.
 		 */
 		 */
-		class_code = (unsigned int *) get_property(node, "class-code", NULL);
+		class_code = get_property(node, "class-code", NULL);
 		if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
 		if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
 			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
 			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
 			strcmp(node->name, "multifunc-device"))
 			strcmp(node->name, "multifunc-device"))
@@ -737,10 +740,10 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
 static int
 static int
 scan_OF_pci_childs_iterator(struct device_node* node, void* data)
 scan_OF_pci_childs_iterator(struct device_node* node, void* data)
 {
 {
-	unsigned int *reg;
+	const unsigned int *reg;
 	u8* fdata = (u8*)data;
 	u8* fdata = (u8*)data;
 	
 	
-	reg = (unsigned int *) get_property(node, "reg", NULL);
+	reg = get_property(node, "reg", NULL);
 	if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
 	if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
 		&& ((reg[0] >> 16) & 0xff) == fdata[0])
 		&& ((reg[0] >> 16) & 0xff) == fdata[0])
 		return 1;
 		return 1;
@@ -841,7 +844,7 @@ find_OF_pci_device_filter(struct device_node* node, void* data)
 int
 int
 pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
 pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
 {
 {
-	unsigned int *reg;
+	const unsigned int *reg;
 	struct pci_controller* hose;
 	struct pci_controller* hose;
 	struct pci_dev* dev = NULL;
 	struct pci_dev* dev = NULL;
 	
 	
@@ -854,7 +857,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
 	if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
 	if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
 			find_OF_pci_device_filter, (void *)node))
 			find_OF_pci_device_filter, (void *)node))
 		return -ENODEV;
 		return -ENODEV;
-	reg = (unsigned int *) get_property(node, "reg", NULL);
+	reg = get_property(node, "reg", NULL);
 	if (!reg)
 	if (!reg)
 		return -ENODEV;
 		return -ENODEV;
 	*bus = (reg[0] >> 16) & 0xff;
 	*bus = (reg[0] >> 16) & 0xff;
@@ -885,8 +888,8 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			   struct device_node *dev, int primary)
 			   struct device_node *dev, int primary)
 {
 {
 	static unsigned int static_lc_ranges[256] __initdata;
 	static unsigned int static_lc_ranges[256] __initdata;
-	unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
-	unsigned int size;
+	const unsigned int *dt_ranges;
+	unsigned int *lc_ranges, *ranges, *prev, size;
 	int rlen = 0, orig_rlen;
 	int rlen = 0, orig_rlen;
 	int memno = 0;
 	int memno = 0;
 	struct resource *res;
 	struct resource *res;
@@ -897,7 +900,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
 	 * that can have more than 3 ranges, fortunately using contiguous
 	 * that can have more than 3 ranges, fortunately using contiguous
 	 * addresses -- BenH
 	 * addresses -- BenH
 	 */
 	 */
-	dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+	dt_ranges = get_property(dev, "ranges", &rlen);
 	if (!dt_ranges)
 	if (!dt_ranges)
 		return;
 		return;
 	/* Sanity check, though hopefully that never happens */
 	/* Sanity check, though hopefully that never happens */

+ 16 - 51
arch/powerpc/kernel/pci_64.c

@@ -185,34 +185,6 @@ static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
 	spin_unlock(&hose_spinlock);
 	spin_unlock(&hose_spinlock);
 }
 }
 
 
-static void add_linux_pci_domain(struct device_node *dev,
-				 struct pci_controller *phb)
-{
-	struct property *of_prop;
-	unsigned int size;
-
-	of_prop = (struct property *)
-		get_property(dev, "linux,pci-domain", &size);
-	if (of_prop != NULL)
-		return;
-	WARN_ON(of_prop && size < sizeof(int));
-	if (of_prop && size < sizeof(int))
-		of_prop = NULL;
-	size = sizeof(struct property) + sizeof(int);
-	if (of_prop == NULL) {
-		if (mem_init_done)
-			of_prop = kmalloc(size, GFP_KERNEL);
-		else
-			of_prop = alloc_bootmem(size);
-	}
-	memset(of_prop, 0, sizeof(struct property));
-	of_prop->name = "linux,pci-domain";
-	of_prop->length = sizeof(int);
-	of_prop->value = (unsigned char *)&of_prop[1];
-	*((int *)of_prop->value) = phb->global_number;
-	prom_add_property(dev, of_prop);
-}
-
 struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
 struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
 {
 {
 	struct pci_controller *phb;
 	struct pci_controller *phb;
@@ -226,22 +198,13 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
 	pci_setup_pci_controller(phb);
 	pci_setup_pci_controller(phb);
 	phb->arch_data = dev;
 	phb->arch_data = dev;
 	phb->is_dynamic = mem_init_done;
 	phb->is_dynamic = mem_init_done;
-	if (dev) {
+	if (dev)
 		PHB_SET_NODE(phb, of_node_to_nid(dev));
 		PHB_SET_NODE(phb, of_node_to_nid(dev));
-		add_linux_pci_domain(dev, phb);
-	}
 	return phb;
 	return phb;
 }
 }
 
 
 void pcibios_free_controller(struct pci_controller *phb)
 void pcibios_free_controller(struct pci_controller *phb)
 {
 {
-	if (phb->arch_data) {
-		struct device_node *np = phb->arch_data;
-		int *domain = (int *)get_property(np,
-						  "linux,pci-domain", NULL);
-		if (domain)
-			*domain = -1;
-	}
 	if (phb->is_dynamic)
 	if (phb->is_dynamic)
 		kfree(phb);
 		kfree(phb);
 }
 }
@@ -283,10 +246,10 @@ static void __init pcibios_claim_of_setup(void)
 #ifdef CONFIG_PPC_MULTIPLATFORM
 #ifdef CONFIG_PPC_MULTIPLATFORM
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
 {
 {
-	u32 *prop;
+	const u32 *prop;
 	int len;
 	int len;
 
 
-	prop = (u32 *) get_property(np, name, &len);
+	prop = get_property(np, name, &len);
 	if (prop && len >= 4)
 	if (prop && len >= 4)
 		return *prop;
 		return *prop;
 	return def;
 	return def;
@@ -315,10 +278,11 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
 	u64 base, size;
 	u64 base, size;
 	unsigned int flags;
 	unsigned int flags;
 	struct resource *res;
 	struct resource *res;
-	u32 *addrs, i;
+	const u32 *addrs;
+	u32 i;
 	int proplen;
 	int proplen;
 
 
-	addrs = (u32 *) get_property(node, "assigned-addresses", &proplen);
+	addrs = get_property(node, "assigned-addresses", &proplen);
 	if (!addrs)
 	if (!addrs)
 		return;
 		return;
 	DBG("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
 	DBG("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
@@ -418,7 +382,7 @@ void __devinit of_scan_bus(struct device_node *node,
 				  struct pci_bus *bus)
 				  struct pci_bus *bus)
 {
 {
 	struct device_node *child = NULL;
 	struct device_node *child = NULL;
-	u32 *reg;
+	const u32 *reg;
 	int reglen, devfn;
 	int reglen, devfn;
 	struct pci_dev *dev;
 	struct pci_dev *dev;
 
 
@@ -426,7 +390,7 @@ void __devinit of_scan_bus(struct device_node *node,
 
 
 	while ((child = of_get_next_child(node, child)) != NULL) {
 	while ((child = of_get_next_child(node, child)) != NULL) {
 		DBG("  * %s\n", child->full_name);
 		DBG("  * %s\n", child->full_name);
-		reg = (u32 *) get_property(child, "reg", &reglen);
+		reg = get_property(child, "reg", &reglen);
 		if (reg == NULL || reglen < 20)
 		if (reg == NULL || reglen < 20)
 			continue;
 			continue;
 		devfn = (reg[0] >> 8) & 0xff;
 		devfn = (reg[0] >> 8) & 0xff;
@@ -450,7 +414,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
 			 	struct pci_dev *dev)
 			 	struct pci_dev *dev)
 {
 {
 	struct pci_bus *bus;
 	struct pci_bus *bus;
-	u32 *busrange, *ranges;
+	const u32 *busrange, *ranges;
 	int len, i, mode;
 	int len, i, mode;
 	struct resource *res;
 	struct resource *res;
 	unsigned int flags;
 	unsigned int flags;
@@ -459,13 +423,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
 	DBG("of_scan_pci_bridge(%s)\n", node->full_name);
 	DBG("of_scan_pci_bridge(%s)\n", node->full_name);
 
 
 	/* parse bus-range property */
 	/* parse bus-range property */
-	busrange = (u32 *) get_property(node, "bus-range", &len);
+	busrange = get_property(node, "bus-range", &len);
 	if (busrange == NULL || len != 8) {
 	if (busrange == NULL || len != 8) {
 		printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
 		printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
 		       node->full_name);
 		       node->full_name);
 		return;
 		return;
 	}
 	}
-	ranges = (u32 *) get_property(node, "ranges", &len);
+	ranges = get_property(node, "ranges", &len);
 	if (ranges == NULL) {
 	if (ranges == NULL) {
 		printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
 		printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
 		       node->full_name);
 		       node->full_name);
@@ -929,13 +893,13 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
 		unsigned int size;
 		unsigned int size;
 	};
 	};
 
 
-	struct isa_range *range;
+	const struct isa_range *range;
 	unsigned long pci_addr;
 	unsigned long pci_addr;
 	unsigned int isa_addr;
 	unsigned int isa_addr;
 	unsigned int size;
 	unsigned int size;
 	int rlen = 0;
 	int rlen = 0;
 
 
-	range = (struct isa_range *) get_property(isa_node, "ranges", &rlen);
+	range = get_property(isa_node, "ranges", &rlen);
 	if (range == NULL || (rlen < sizeof(struct isa_range))) {
 	if (range == NULL || (rlen < sizeof(struct isa_range))) {
 		printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
 		printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
 		       "mapping 64k\n");
 		       "mapping 64k\n");
@@ -976,7 +940,8 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
 void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
 void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
 					    struct device_node *dev, int prim)
 					    struct device_node *dev, int prim)
 {
 {
-	unsigned int *ranges, pci_space;
+	const unsigned int *ranges;
+	unsigned int pci_space;
 	unsigned long size;
 	unsigned long size;
 	int rlen = 0;
 	int rlen = 0;
 	int memno = 0;
 	int memno = 0;
@@ -994,7 +959,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
 	 *			(size depending on dev->n_addr_cells)
 	 *			(size depending on dev->n_addr_cells)
 	 *   cells 4+5 or 5+6:	the size of the range
 	 *   cells 4+5 or 5+6:	the size of the range
 	 */
 	 */
-	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+	ranges = get_property(dev, "ranges", &rlen);
 	if (ranges == NULL)
 	if (ranges == NULL)
 		return;
 		return;
 	hose->io_base_phys = 0;
 	hose->io_base_phys = 0;

+ 7 - 6
arch/powerpc/kernel/pci_dn.c

@@ -40,8 +40,8 @@
 static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 {
 {
 	struct pci_controller *phb = data;
 	struct pci_controller *phb = data;
-	int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
-	u32 *regs;
+	const int *type = get_property(dn, "ibm,pci-config-space-type", NULL);
+	const u32 *regs;
 	struct pci_dn *pdn;
 	struct pci_dn *pdn;
 
 
 	if (mem_init_done)
 	if (mem_init_done)
@@ -54,14 +54,14 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 	dn->data = pdn;
 	dn->data = pdn;
 	pdn->node = dn;
 	pdn->node = dn;
 	pdn->phb = phb;
 	pdn->phb = phb;
-	regs = (u32 *)get_property(dn, "reg", NULL);
+	regs = get_property(dn, "reg", NULL);
 	if (regs) {
 	if (regs) {
 		/* First register entry is addr (00BBSS00)  */
 		/* First register entry is addr (00BBSS00)  */
 		pdn->busno = (regs[0] >> 16) & 0xff;
 		pdn->busno = (regs[0] >> 16) & 0xff;
 		pdn->devfn = (regs[0] >> 8) & 0xff;
 		pdn->devfn = (regs[0] >> 8) & 0xff;
 	}
 	}
 	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
 	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		u32 *busp = (u32 *)get_property(dn, "linux,subbus", NULL);
+		const u32 *busp = get_property(dn, "linux,subbus", NULL);
 		if (busp)
 		if (busp)
 			pdn->bussubno = *busp;
 			pdn->bussubno = *busp;
 	}
 	}
@@ -96,10 +96,11 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
 
 
 	/* We started with a phb, iterate all childs */
 	/* We started with a phb, iterate all childs */
 	for (dn = start->child; dn; dn = nextdn) {
 	for (dn = start->child; dn; dn = nextdn) {
-		u32 *classp, class;
+		const u32 *classp;
+		u32 class;
 
 
 		nextdn = NULL;
 		nextdn = NULL;
-		classp = (u32 *)get_property(dn, "class-code", NULL);
+		classp = get_property(dn, "class-code", NULL);
 		class = classp ? *classp : 0;
 		class = classp ? *classp : 0;
 
 
 		if (pre && ((ret = pre(dn, data)) != NULL))
 		if (pre && ((ret = pre(dn, data)) != NULL))

+ 2 - 17
arch/powerpc/kernel/ppc_ksyms.c

@@ -91,25 +91,10 @@ EXPORT_SYMBOL(__copy_tofrom_user);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(__strnlen_user);
-
-#ifndef  __powerpc64__
-EXPORT_SYMBOL(__ide_mm_insl);
-EXPORT_SYMBOL(__ide_mm_outsw);
-EXPORT_SYMBOL(__ide_mm_insw);
-EXPORT_SYMBOL(__ide_mm_outsl);
+#ifdef CONFIG_PPC64
+EXPORT_SYMBOL(copy_4K_page);
 #endif
 #endif
 
 
-EXPORT_SYMBOL(_insb);
-EXPORT_SYMBOL(_outsb);
-EXPORT_SYMBOL(_insw);
-EXPORT_SYMBOL(_outsw);
-EXPORT_SYMBOL(_insl);
-EXPORT_SYMBOL(_outsl);
-EXPORT_SYMBOL(_insw_ns);
-EXPORT_SYMBOL(_outsw_ns);
-EXPORT_SYMBOL(_insl_ns);
-EXPORT_SYMBOL(_outsl_ns);
-
 #if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
 #if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
 EXPORT_SYMBOL(ppc_ide_md);
 EXPORT_SYMBOL(ppc_ide_md);
 #endif
 #endif

+ 14 - 30
arch/powerpc/kernel/prom.c

@@ -757,24 +757,9 @@ static int __init early_init_dt_scan_root(unsigned long node,
 static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
 static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
 {
 {
 	cell_t *p = *cellp;
 	cell_t *p = *cellp;
-	unsigned long r;
 
 
-	/* Ignore more than 2 cells */
-	while (s > sizeof(unsigned long) / 4) {
-		p++;
-		s--;
-	}
-	r = *p++;
-#ifdef CONFIG_PPC64
-	if (s > 1) {
-		r <<= 32;
-		r |= *(p++);
-		s--;
-	}
-#endif
-
-	*cellp = p;
-	return r;
+	*cellp = p + s;
+	return of_read_ulong(p, s);
 }
 }
 
 
 
 
@@ -942,11 +927,11 @@ void __init early_init_devtree(void *params)
 int
 int
 prom_n_addr_cells(struct device_node* np)
 prom_n_addr_cells(struct device_node* np)
 {
 {
-	int* ip;
+	const int *ip;
 	do {
 	do {
 		if (np->parent)
 		if (np->parent)
 			np = np->parent;
 			np = np->parent;
-		ip = (int *) get_property(np, "#address-cells", NULL);
+		ip = get_property(np, "#address-cells", NULL);
 		if (ip != NULL)
 		if (ip != NULL)
 			return *ip;
 			return *ip;
 	} while (np->parent);
 	} while (np->parent);
@@ -958,11 +943,11 @@ EXPORT_SYMBOL(prom_n_addr_cells);
 int
 int
 prom_n_size_cells(struct device_node* np)
 prom_n_size_cells(struct device_node* np)
 {
 {
-	int* ip;
+	const int* ip;
 	do {
 	do {
 		if (np->parent)
 		if (np->parent)
 			np = np->parent;
 			np = np->parent;
-		ip = (int *) get_property(np, "#size-cells", NULL);
+		ip = get_property(np, "#size-cells", NULL);
 		if (ip != NULL)
 		if (ip != NULL)
 			return *ip;
 			return *ip;
 	} while (np->parent);
 	} while (np->parent);
@@ -1034,7 +1019,7 @@ int device_is_compatible(struct device_node *device, const char *compat)
 	const char* cp;
 	const char* cp;
 	int cplen, l;
 	int cplen, l;
 
 
-	cp = (char *) get_property(device, "compatible", &cplen);
+	cp = get_property(device, "compatible", &cplen);
 	if (cp == NULL)
 	if (cp == NULL)
 		return 0;
 		return 0;
 	while (cplen > 0) {
 	while (cplen > 0) {
@@ -1449,7 +1434,7 @@ static int of_finish_dynamic_node(struct device_node *node)
 {
 {
 	struct device_node *parent = of_get_parent(node);
 	struct device_node *parent = of_get_parent(node);
 	int err = 0;
 	int err = 0;
-	phandle *ibm_phandle;
+	const phandle *ibm_phandle;
 
 
 	node->name = get_property(node, "name", NULL);
 	node->name = get_property(node, "name", NULL);
 	node->type = get_property(node, "device_type", NULL);
 	node->type = get_property(node, "device_type", NULL);
@@ -1466,8 +1451,7 @@ static int of_finish_dynamic_node(struct device_node *node)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	/* fix up new node's linux_phandle field */
 	/* fix up new node's linux_phandle field */
-	if ((ibm_phandle = (unsigned int *)get_property(node,
-							"ibm,phandle", NULL)))
+	if ((ibm_phandle = get_property(node, "ibm,phandle", NULL)))
 		node->linux_phandle = *ibm_phandle;
 		node->linux_phandle = *ibm_phandle;
 
 
 out:
 out:
@@ -1528,7 +1512,7 @@ struct property *of_find_property(struct device_node *np, const char *name,
  * Find a property with a given name for a given node
  * Find a property with a given name for a given node
  * and return the value.
  * and return the value.
  */
  */
-void *get_property(struct device_node *np, const char *name, int *lenp)
+const void *get_property(struct device_node *np, const char *name, int *lenp)
 {
 {
 	struct property *pp = of_find_property(np,name,lenp);
 	struct property *pp = of_find_property(np,name,lenp);
 	return pp ? pp->value : NULL;
 	return pp ? pp->value : NULL;
@@ -1658,16 +1642,16 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
 	hardid = get_hard_smp_processor_id(cpu);
 	hardid = get_hard_smp_processor_id(cpu);
 
 
 	for_each_node_by_type(np, "cpu") {
 	for_each_node_by_type(np, "cpu") {
-		u32 *intserv;
+		const u32 *intserv;
 		unsigned int plen, t;
 		unsigned int plen, t;
 
 
 		/* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
 		/* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
 		 * fallback to "reg" property and assume no threads
 		 * fallback to "reg" property and assume no threads
 		 */
 		 */
-		intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s",
-					      &plen);
+		intserv = get_property(np, "ibm,ppc-interrupt-server#s",
+				&plen);
 		if (intserv == NULL) {
 		if (intserv == NULL) {
-			u32 *reg = (u32 *)get_property(np, "reg", NULL);
+			const u32 *reg = get_property(np, "reg", NULL);
 			if (reg == NULL)
 			if (reg == NULL)
 				continue;
 				continue;
 			if (*reg == hardid) {
 			if (*reg == hardid) {

+ 8 - 2
arch/powerpc/kernel/prom_init.c

@@ -2033,16 +2033,22 @@ static void __init fixup_device_tree_maple(void)
 #endif
 #endif
 
 
 #ifdef CONFIG_PPC_CHRP
 #ifdef CONFIG_PPC_CHRP
-/* Pegasos lacks the "ranges" property in the isa node */
+/* Pegasos and BriQ lacks the "ranges" property in the isa node */
 static void __init fixup_device_tree_chrp(void)
 static void __init fixup_device_tree_chrp(void)
 {
 {
 	phandle isa;
 	phandle isa;
 	u32 isa_ranges[6];
 	u32 isa_ranges[6];
+	u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
 	char *name;
 	char *name;
 	int rc;
 	int rc;
 
 
 	name = "/pci@80000000/isa@c";
 	name = "/pci@80000000/isa@c";
 	isa = call_prom("finddevice", 1, 1, ADDR(name));
 	isa = call_prom("finddevice", 1, 1, ADDR(name));
+	if (!PHANDLE_VALID(isa)) {
+		name = "/pci@ff500000/isa@6";
+		isa = call_prom("finddevice", 1, 1, ADDR(name));
+		rloc = 0x01003000; /* IO space; PCI device = 6 */
+	}
 	if (!PHANDLE_VALID(isa))
 	if (!PHANDLE_VALID(isa))
 		return;
 		return;
 
 
@@ -2054,7 +2060,7 @@ static void __init fixup_device_tree_chrp(void)
 
 
 	isa_ranges[0] = 0x1;
 	isa_ranges[0] = 0x1;
 	isa_ranges[1] = 0x0;
 	isa_ranges[1] = 0x0;
-	isa_ranges[2] = 0x01006000;
+	isa_ranges[2] = rloc;
 	isa_ranges[3] = 0x0;
 	isa_ranges[3] = 0x0;
 	isa_ranges[4] = 0x0;
 	isa_ranges[4] = 0x0;
 	isa_ranges[5] = 0x00010000;
 	isa_ranges[5] = 0x00010000;

+ 47 - 43
arch/powerpc/kernel/prom_parse.c

@@ -27,7 +27,7 @@
 
 
 /* Debug utility */
 /* Debug utility */
 #ifdef DEBUG
 #ifdef DEBUG
-static void of_dump_addr(const char *s, u32 *addr, int na)
+static void of_dump_addr(const char *s, const u32 *addr, int na)
 {
 {
 	printk("%s", s);
 	printk("%s", s);
 	while(na--)
 	while(na--)
@@ -35,7 +35,7 @@ static void of_dump_addr(const char *s, u32 *addr, int na)
 	printk("\n");
 	printk("\n");
 }
 }
 #else
 #else
-static void of_dump_addr(const char *s, u32 *addr, int na) { }
+static void of_dump_addr(const char *s, const u32 *addr, int na) { }
 #endif
 #endif
 
 
 
 
@@ -46,9 +46,10 @@ struct of_bus {
 	int		(*match)(struct device_node *parent);
 	int		(*match)(struct device_node *parent);
 	void		(*count_cells)(struct device_node *child,
 	void		(*count_cells)(struct device_node *child,
 				       int *addrc, int *sizec);
 				       int *addrc, int *sizec);
-	u64		(*map)(u32 *addr, u32 *range, int na, int ns, int pna);
+	u64		(*map)(u32 *addr, const u32 *range,
+				int na, int ns, int pna);
 	int		(*translate)(u32 *addr, u64 offset, int na);
 	int		(*translate)(u32 *addr, u64 offset, int na);
-	unsigned int	(*get_flags)(u32 *addr);
+	unsigned int	(*get_flags)(const u32 *addr);
 };
 };
 
 
 
 
@@ -65,7 +66,8 @@ static void of_bus_default_count_cells(struct device_node *dev,
 		*sizec = prom_n_size_cells(dev);
 		*sizec = prom_n_size_cells(dev);
 }
 }
 
 
-static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
+static u64 of_bus_default_map(u32 *addr, const u32 *range,
+		int na, int ns, int pna)
 {
 {
 	u64 cp, s, da;
 	u64 cp, s, da;
 
 
@@ -93,7 +95,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
 	return 0;
 	return 0;
 }
 }
 
 
-static unsigned int of_bus_default_get_flags(u32 *addr)
+static unsigned int of_bus_default_get_flags(const u32 *addr)
 {
 {
 	return IORESOURCE_MEM;
 	return IORESOURCE_MEM;
 }
 }
@@ -118,7 +120,7 @@ static void of_bus_pci_count_cells(struct device_node *np,
 		*sizec = 2;
 		*sizec = 2;
 }
 }
 
 
-static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
+static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
 {
 {
 	u64 cp, s, da;
 	u64 cp, s, da;
 
 
@@ -143,7 +145,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
 }
 
 
-static unsigned int of_bus_pci_get_flags(u32 *addr)
+static unsigned int of_bus_pci_get_flags(const u32 *addr)
 {
 {
 	unsigned int flags = 0;
 	unsigned int flags = 0;
 	u32 w = addr[0];
 	u32 w = addr[0];
@@ -178,7 +180,7 @@ static void of_bus_isa_count_cells(struct device_node *child,
 		*sizec = 1;
 		*sizec = 1;
 }
 }
 
 
-static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
+static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
 {
 {
 	u64 cp, s, da;
 	u64 cp, s, da;
 
 
@@ -203,7 +205,7 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
 }
 
 
-static unsigned int of_bus_isa_get_flags(u32 *addr)
+static unsigned int of_bus_isa_get_flags(const u32 *addr)
 {
 {
 	unsigned int flags = 0;
 	unsigned int flags = 0;
 	u32 w = addr[0];
 	u32 w = addr[0];
@@ -268,7 +270,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
 			    struct of_bus *pbus, u32 *addr,
 			    struct of_bus *pbus, u32 *addr,
 			    int na, int ns, int pna)
 			    int na, int ns, int pna)
 {
 {
-	u32 *ranges;
+	const u32 *ranges;
 	unsigned int rlen;
 	unsigned int rlen;
 	int rone;
 	int rone;
 	u64 offset = OF_BAD_ADDR;
 	u64 offset = OF_BAD_ADDR;
@@ -285,7 +287,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
 	 * to translate addresses that aren't supposed to be translated in
 	 * to translate addresses that aren't supposed to be translated in
 	 * the first place. --BenH.
 	 * the first place. --BenH.
 	 */
 	 */
-	ranges = (u32 *)get_property(parent, "ranges", &rlen);
+	ranges = get_property(parent, "ranges", &rlen);
 	if (ranges == NULL || rlen == 0) {
 	if (ranges == NULL || rlen == 0) {
 		offset = of_read_number(addr, na);
 		offset = of_read_number(addr, na);
 		memset(addr, 0, pna * 4);
 		memset(addr, 0, pna * 4);
@@ -328,7 +330,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
  * that can be mapped to a cpu physical address). This is not really specified
  * that can be mapped to a cpu physical address). This is not really specified
  * that way, but this is traditionally the way IBM at least do things
  * that way, but this is traditionally the way IBM at least do things
  */
  */
-u64 of_translate_address(struct device_node *dev, u32 *in_addr)
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
 {
 {
 	struct device_node *parent = NULL;
 	struct device_node *parent = NULL;
 	struct of_bus *bus, *pbus;
 	struct of_bus *bus, *pbus;
@@ -405,10 +407,10 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr)
 }
 }
 EXPORT_SYMBOL(of_translate_address);
 EXPORT_SYMBOL(of_translate_address);
 
 
-u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
 		    unsigned int *flags)
 		    unsigned int *flags)
 {
 {
-	u32 *prop;
+	const u32 *prop;
 	unsigned int psize;
 	unsigned int psize;
 	struct device_node *parent;
 	struct device_node *parent;
 	struct of_bus *bus;
 	struct of_bus *bus;
@@ -425,7 +427,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
 		return NULL;
 		return NULL;
 
 
 	/* Get "reg" or "assigned-addresses" property */
 	/* Get "reg" or "assigned-addresses" property */
-	prop = (u32 *)get_property(dev, bus->addresses, &psize);
+	prop = get_property(dev, bus->addresses, &psize);
 	if (prop == NULL)
 	if (prop == NULL)
 		return NULL;
 		return NULL;
 	psize /= 4;
 	psize /= 4;
@@ -443,10 +445,10 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
 }
 }
 EXPORT_SYMBOL(of_get_address);
 EXPORT_SYMBOL(of_get_address);
 
 
-u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
 			unsigned int *flags)
 			unsigned int *flags)
 {
 {
-	u32 *prop;
+	const u32 *prop;
 	unsigned int psize;
 	unsigned int psize;
 	struct device_node *parent;
 	struct device_node *parent;
 	struct of_bus *bus;
 	struct of_bus *bus;
@@ -467,7 +469,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
 		return NULL;
 		return NULL;
 
 
 	/* Get "reg" or "assigned-addresses" property */
 	/* Get "reg" or "assigned-addresses" property */
-	prop = (u32 *)get_property(dev, bus->addresses, &psize);
+	prop = get_property(dev, bus->addresses, &psize);
 	if (prop == NULL)
 	if (prop == NULL)
 		return NULL;
 		return NULL;
 	psize /= 4;
 	psize /= 4;
@@ -485,7 +487,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
 }
 }
 EXPORT_SYMBOL(of_get_pci_address);
 EXPORT_SYMBOL(of_get_pci_address);
 
 
-static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
 				    u64 size, unsigned int flags,
 				    u64 size, unsigned int flags,
 				    struct resource *r)
 				    struct resource *r)
 {
 {
@@ -516,7 +518,7 @@ static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
 int of_address_to_resource(struct device_node *dev, int index,
 int of_address_to_resource(struct device_node *dev, int index,
 			   struct resource *r)
 			   struct resource *r)
 {
 {
-	u32		*addrp;
+	const u32	*addrp;
 	u64		size;
 	u64		size;
 	unsigned int	flags;
 	unsigned int	flags;
 
 
@@ -530,7 +532,7 @@ EXPORT_SYMBOL_GPL(of_address_to_resource);
 int of_pci_address_to_resource(struct device_node *dev, int bar,
 int of_pci_address_to_resource(struct device_node *dev, int bar,
 			       struct resource *r)
 			       struct resource *r)
 {
 {
-	u32		*addrp;
+	const u32	*addrp;
 	u64		size;
 	u64		size;
 	unsigned int	flags;
 	unsigned int	flags;
 
 
@@ -541,13 +543,14 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
 }
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
 
 
-void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
 {
 {
-	u32 *dma_window, cells;
-	unsigned char *prop;
+	const u32 *dma_window;
+	u32 cells;
+	const unsigned char *prop;
 
 
-	dma_window = (u32 *)dma_window_prop;
+	dma_window = dma_window_prop;
 
 
 	/* busno is always one cell */
 	/* busno is always one cell */
 	*busno = *(dma_window++);
 	*busno = *(dma_window++);
@@ -576,13 +579,13 @@ static struct device_node *of_irq_dflt_pic;
 static struct device_node *of_irq_find_parent(struct device_node *child)
 static struct device_node *of_irq_find_parent(struct device_node *child)
 {
 {
 	struct device_node *p;
 	struct device_node *p;
-	phandle *parp;
+	const phandle *parp;
 
 
 	if (!of_node_get(child))
 	if (!of_node_get(child))
 		return NULL;
 		return NULL;
 
 
 	do {
 	do {
-		parp = (phandle *)get_property(child, "interrupt-parent", NULL);
+		parp = get_property(child, "interrupt-parent", NULL);
 		if (parp == NULL)
 		if (parp == NULL)
 			p = of_get_parent(child);
 			p = of_get_parent(child);
 		else {
 		else {
@@ -639,11 +642,11 @@ void of_irq_map_init(unsigned int flags)
 
 
 }
 }
 
 
-int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
-		   u32 *addr, struct of_irq *out_irq)
+int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
+		const u32 *addr, struct of_irq *out_irq)
 {
 {
 	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
 	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
-	u32 *tmp, *imap, *imask;
+	const u32 *tmp, *imap, *imask;
 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
 	int imaplen, match, i;
 	int imaplen, match, i;
 
 
@@ -657,7 +660,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
 	 * is none, we are nice and just walk up the tree
 	 * is none, we are nice and just walk up the tree
 	 */
 	 */
 	do {
 	do {
-		tmp = (u32 *)get_property(ipar, "#interrupt-cells", NULL);
+		tmp = get_property(ipar, "#interrupt-cells", NULL);
 		if (tmp != NULL) {
 		if (tmp != NULL) {
 			intsize = *tmp;
 			intsize = *tmp;
 			break;
 			break;
@@ -681,7 +684,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
 	 */
 	 */
 	old = of_node_get(ipar);
 	old = of_node_get(ipar);
 	do {
 	do {
-		tmp = (u32 *)get_property(old, "#address-cells", NULL);
+		tmp = get_property(old, "#address-cells", NULL);
 		tnode = of_get_parent(old);
 		tnode = of_get_parent(old);
 		of_node_put(old);
 		of_node_put(old);
 		old = tnode;
 		old = tnode;
@@ -708,7 +711,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
 		}
 		}
 
 
 		/* Now look for an interrupt-map */
 		/* Now look for an interrupt-map */
-		imap = (u32 *)get_property(ipar, "interrupt-map", &imaplen);
+		imap = get_property(ipar, "interrupt-map", &imaplen);
 		/* No interrupt map, check for an interrupt parent */
 		/* No interrupt map, check for an interrupt parent */
 		if (imap == NULL) {
 		if (imap == NULL) {
 			DBG(" -> no map, getting parent\n");
 			DBG(" -> no map, getting parent\n");
@@ -718,7 +721,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
 		imaplen /= sizeof(u32);
 		imaplen /= sizeof(u32);
 
 
 		/* Look for a mask */
 		/* Look for a mask */
-		imask = (u32 *)get_property(ipar, "interrupt-map-mask", NULL);
+		imask = get_property(ipar, "interrupt-map-mask", NULL);
 
 
 		/* If we were passed no "reg" property and we attempt to parse
 		/* If we were passed no "reg" property and we attempt to parse
 		 * an interrupt-map, then #address-cells must be 0.
 		 * an interrupt-map, then #address-cells must be 0.
@@ -765,14 +768,14 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
 			/* Get #interrupt-cells and #address-cells of new
 			/* Get #interrupt-cells and #address-cells of new
 			 * parent
 			 * parent
 			 */
 			 */
-			tmp = (u32 *)get_property(newpar, "#interrupt-cells",
+			tmp = get_property(newpar, "#interrupt-cells",
 						  NULL);
 						  NULL);
 			if (tmp == NULL) {
 			if (tmp == NULL) {
 				DBG(" -> parent lacks #interrupt-cells !\n");
 				DBG(" -> parent lacks #interrupt-cells !\n");
 				goto fail;
 				goto fail;
 			}
 			}
 			newintsize = *tmp;
 			newintsize = *tmp;
-			tmp = (u32 *)get_property(newpar, "#address-cells",
+			tmp = get_property(newpar, "#address-cells",
 						  NULL);
 						  NULL);
 			newaddrsize = (tmp == NULL) ? 0 : *tmp;
 			newaddrsize = (tmp == NULL) ? 0 : *tmp;
 
 
@@ -818,14 +821,14 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
 static int of_irq_map_oldworld(struct device_node *device, int index,
 static int of_irq_map_oldworld(struct device_node *device, int index,
 			       struct of_irq *out_irq)
 			       struct of_irq *out_irq)
 {
 {
-	u32 *ints;
+	const u32 *ints;
 	int intlen;
 	int intlen;
 
 
 	/*
 	/*
 	 * Old machines just have a list of interrupt numbers
 	 * Old machines just have a list of interrupt numbers
 	 * and no interrupt-controller nodes.
 	 * and no interrupt-controller nodes.
 	 */
 	 */
-	ints = (u32 *) get_property(device, "AAPL,interrupts", &intlen);
+	ints = get_property(device, "AAPL,interrupts", &intlen);
 	if (ints == NULL)
 	if (ints == NULL)
 		return -EINVAL;
 		return -EINVAL;
 	intlen /= sizeof(u32);
 	intlen /= sizeof(u32);
@@ -850,7 +853,8 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
 int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
 int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
 {
 {
 	struct device_node *p;
 	struct device_node *p;
-	u32 *intspec, *tmp, intsize, intlen, *addr;
+	const u32 *intspec, *tmp, *addr;
+	u32 intsize, intlen;
 	int res;
 	int res;
 
 
 	DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
 	DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
@@ -860,13 +864,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
 		return of_irq_map_oldworld(device, index, out_irq);
 		return of_irq_map_oldworld(device, index, out_irq);
 
 
 	/* Get the interrupts property */
 	/* Get the interrupts property */
-	intspec = (u32 *)get_property(device, "interrupts", &intlen);
+	intspec = get_property(device, "interrupts", &intlen);
 	if (intspec == NULL)
 	if (intspec == NULL)
 		return -EINVAL;
 		return -EINVAL;
 	intlen /= sizeof(u32);
 	intlen /= sizeof(u32);
 
 
 	/* Get the reg property (if any) */
 	/* Get the reg property (if any) */
-	addr = (u32 *)get_property(device, "reg", NULL);
+	addr = get_property(device, "reg", NULL);
 
 
 	/* Look for the interrupt parent. */
 	/* Look for the interrupt parent. */
 	p = of_irq_find_parent(device);
 	p = of_irq_find_parent(device);
@@ -874,7 +878,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
 		return -EINVAL;
 		return -EINVAL;
 
 
 	/* Get size of interrupt specifier */
 	/* Get size of interrupt specifier */
-	tmp = (u32 *)get_property(p, "#interrupt-cells", NULL);
+	tmp = get_property(p, "#interrupt-cells", NULL);
 	if (tmp == NULL) {
 	if (tmp == NULL) {
 		of_node_put(p);
 		of_node_put(p);
 		return -EINVAL;
 		return -EINVAL;

+ 13 - 12
arch/powerpc/kernel/rtas-proc.c

@@ -246,12 +246,12 @@ struct file_operations ppc_rtas_rmo_buf_ops = {
 
 
 static int ppc_rtas_find_all_sensors(void);
 static int ppc_rtas_find_all_sensors(void);
 static void ppc_rtas_process_sensor(struct seq_file *m,
 static void ppc_rtas_process_sensor(struct seq_file *m,
-	struct individual_sensor *s, int state, int error, char *loc);
+	struct individual_sensor *s, int state, int error, const char *loc);
 static char *ppc_rtas_process_error(int error);
 static char *ppc_rtas_process_error(int error);
 static void get_location_code(struct seq_file *m,
 static void get_location_code(struct seq_file *m,
-	struct individual_sensor *s, char *loc);
-static void check_location_string(struct seq_file *m, char *c);
-static void check_location(struct seq_file *m, char *c);
+	struct individual_sensor *s, const char *loc);
+static void check_location_string(struct seq_file *m, const char *c);
+static void check_location(struct seq_file *m, const char *c);
 
 
 static int __init proc_rtas_init(void)
 static int __init proc_rtas_init(void)
 {
 {
@@ -446,11 +446,11 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
 	for (i=0; i<sensors.quant; i++) {
 	for (i=0; i<sensors.quant; i++) {
 		struct individual_sensor *p = &sensors.sensor[i];
 		struct individual_sensor *p = &sensors.sensor[i];
 		char rstr[64];
 		char rstr[64];
-		char *loc;
+		const char *loc;
 		int llen, offs;
 		int llen, offs;
 
 
 		sprintf (rstr, SENSOR_PREFIX"%04d", p->token);
 		sprintf (rstr, SENSOR_PREFIX"%04d", p->token);
-		loc = (char *) get_property(rtas_node, rstr, &llen);
+		loc = get_property(rtas_node, rstr, &llen);
 
 
 		/* A sensor may have multiple instances */
 		/* A sensor may have multiple instances */
 		for (j = 0, offs = 0; j <= p->quant; j++) {
 		for (j = 0, offs = 0; j <= p->quant; j++) {
@@ -474,10 +474,10 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
 
 
 static int ppc_rtas_find_all_sensors(void)
 static int ppc_rtas_find_all_sensors(void)
 {
 {
-	unsigned int *utmp;
+	const unsigned int *utmp;
 	int len, i;
 	int len, i;
 
 
-	utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);
+	utmp = get_property(rtas_node, "rtas-sensors", &len);
 	if (utmp == NULL) {
 	if (utmp == NULL) {
 		printk (KERN_ERR "error: could not get rtas-sensors\n");
 		printk (KERN_ERR "error: could not get rtas-sensors\n");
 		return 1;
 		return 1;
@@ -530,7 +530,7 @@ static char *ppc_rtas_process_error(int error)
  */
  */
 
 
 static void ppc_rtas_process_sensor(struct seq_file *m,
 static void ppc_rtas_process_sensor(struct seq_file *m,
-	struct individual_sensor *s, int state, int error, char *loc)
+	struct individual_sensor *s, int state, int error, const char *loc)
 {
 {
 	/* Defined return vales */
 	/* Defined return vales */
 	const char * key_switch[]        = { "Off\t", "Normal\t", "Secure\t", 
 	const char * key_switch[]        = { "Off\t", "Normal\t", "Secure\t", 
@@ -682,7 +682,7 @@ static void ppc_rtas_process_sensor(struct seq_file *m,
 
 
 /* ****************************************************************** */
 /* ****************************************************************** */
 
 
-static void check_location(struct seq_file *m, char *c)
+static void check_location(struct seq_file *m, const char *c)
 {
 {
 	switch (c[0]) {
 	switch (c[0]) {
 		case LOC_PLANAR:
 		case LOC_PLANAR:
@@ -719,7 +719,7 @@ static void check_location(struct seq_file *m, char *c)
  * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
  * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
  * the '.' may be an abbrevation
  * the '.' may be an abbrevation
  */
  */
-static void check_location_string(struct seq_file *m, char *c)
+static void check_location_string(struct seq_file *m, const char *c)
 {
 {
 	while (*c) {
 	while (*c) {
 		if (isalpha(*c) || *c == '.')
 		if (isalpha(*c) || *c == '.')
@@ -733,7 +733,8 @@ static void check_location_string(struct seq_file *m, char *c)
 
 
 /* ****************************************************************** */
 /* ****************************************************************** */
 
 
-static void get_location_code(struct seq_file *m, struct individual_sensor *s, char *loc)
+static void get_location_code(struct seq_file *m, struct individual_sensor *s,
+		const char *loc)
 {
 {
 	if (!loc || !*loc) {
 	if (!loc || !*loc) {
 		seq_printf(m, "---");/* does not have a location */
 		seq_printf(m, "---");/* does not have a location */

+ 28 - 19
arch/powerpc/kernel/rtas.c

@@ -177,10 +177,12 @@ void __init udbg_init_rtas_console(void)
 void rtas_progress(char *s, unsigned short hex)
 void rtas_progress(char *s, unsigned short hex)
 {
 {
 	struct device_node *root;
 	struct device_node *root;
-	int width, *p;
+	int width;
+	const int *p;
 	char *os;
 	char *os;
 	static int display_character, set_indicator;
 	static int display_character, set_indicator;
-	static int display_width, display_lines, *row_width, form_feed;
+	static int display_width, display_lines, form_feed;
+	const static int *row_width;
 	static DEFINE_SPINLOCK(progress_lock);
 	static DEFINE_SPINLOCK(progress_lock);
 	static int current_line;
 	static int current_line;
 	static int pending_newline = 0;  /* did last write end with unprinted newline? */
 	static int pending_newline = 0;  /* did last write end with unprinted newline? */
@@ -191,16 +193,16 @@ void rtas_progress(char *s, unsigned short hex)
 	if (display_width == 0) {
 	if (display_width == 0) {
 		display_width = 0x10;
 		display_width = 0x10;
 		if ((root = find_path_device("/rtas"))) {
 		if ((root = find_path_device("/rtas"))) {
-			if ((p = (unsigned int *)get_property(root,
+			if ((p = get_property(root,
 					"ibm,display-line-length", NULL)))
 					"ibm,display-line-length", NULL)))
 				display_width = *p;
 				display_width = *p;
-			if ((p = (unsigned int *)get_property(root,
+			if ((p = get_property(root,
 					"ibm,form-feed", NULL)))
 					"ibm,form-feed", NULL)))
 				form_feed = *p;
 				form_feed = *p;
-			if ((p = (unsigned int *)get_property(root,
+			if ((p = get_property(root,
 					"ibm,display-number-of-lines", NULL)))
 					"ibm,display-number-of-lines", NULL)))
 				display_lines = *p;
 				display_lines = *p;
-			row_width = (unsigned int *)get_property(root,
+			row_width = get_property(root,
 					"ibm,display-truncation-length", NULL);
 					"ibm,display-truncation-length", NULL);
 		}
 		}
 		display_character = rtas_token("display-character");
 		display_character = rtas_token("display-character");
@@ -293,10 +295,10 @@ EXPORT_SYMBOL(rtas_progress);		/* needed by rtas_flash module */
 
 
 int rtas_token(const char *service)
 int rtas_token(const char *service)
 {
 {
-	int *tokp;
+	const int *tokp;
 	if (rtas.dev == NULL)
 	if (rtas.dev == NULL)
 		return RTAS_UNKNOWN_SERVICE;
 		return RTAS_UNKNOWN_SERVICE;
-	tokp = (int *) get_property(rtas.dev, service, NULL);
+	tokp = get_property(rtas.dev, service, NULL);
 	return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
 	return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
 }
 }
 EXPORT_SYMBOL(rtas_token);
 EXPORT_SYMBOL(rtas_token);
@@ -626,6 +628,9 @@ void rtas_os_term(char *str)
 {
 {
 	int status;
 	int status;
 
 
+	if (panic_timeout)
+		return;
+
 	if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
 	if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
 		return;
 		return;
 
 
@@ -687,15 +692,14 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
 	int i;
 	int i;
 	long state;
 	long state;
 	long rc;
 	long rc;
-	unsigned long dummy;
-
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 	struct rtas_suspend_me_data data;
 	struct rtas_suspend_me_data data;
 
 
 	/* Make sure the state is valid */
 	/* Make sure the state is valid */
-	rc = plpar_hcall(H_VASI_STATE,
-			 ((u64)args->args[0] << 32) | args->args[1],
-			 0, 0, 0,
-			 &state, &dummy, &dummy);
+	rc = plpar_hcall(H_VASI_STATE, retbuf,
+			 ((u64)args->args[0] << 32) | args->args[1]);
+
+	state = retbuf[0];
 
 
 	if (rc) {
 	if (rc) {
 		printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
 		printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
@@ -845,15 +849,15 @@ void __init rtas_initialize(void)
 	 */
 	 */
 	rtas.dev = of_find_node_by_name(NULL, "rtas");
 	rtas.dev = of_find_node_by_name(NULL, "rtas");
 	if (rtas.dev) {
 	if (rtas.dev) {
-		u32 *basep, *entryp;
-		u32 *sizep;
+		const u32 *basep, *entryp, *sizep;
 
 
-		basep = (u32 *)get_property(rtas.dev, "linux,rtas-base", NULL);
-		sizep = (u32 *)get_property(rtas.dev, "rtas-size", NULL);
+		basep = get_property(rtas.dev, "linux,rtas-base", NULL);
+		sizep = get_property(rtas.dev, "rtas-size", NULL);
 		if (basep != NULL && sizep != NULL) {
 		if (basep != NULL && sizep != NULL) {
 			rtas.base = *basep;
 			rtas.base = *basep;
 			rtas.size = *sizep;
 			rtas.size = *sizep;
-			entryp = (u32 *)get_property(rtas.dev, "linux,rtas-entry", NULL);
+			entryp = get_property(rtas.dev,
+					"linux,rtas-entry", NULL);
 			if (entryp == NULL) /* Ugh */
 			if (entryp == NULL) /* Ugh */
 				rtas.entry = rtas.base;
 				rtas.entry = rtas.base;
 			else
 			else
@@ -909,6 +913,11 @@ int __init early_init_dt_scan_rtas(unsigned long node,
 	basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
 	basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
 	if (basep)
 	if (basep)
 		rtas_getchar_token = *basep;
 		rtas_getchar_token = *basep;
+
+	if (rtas_putchar_token != RTAS_UNKNOWN_SERVICE &&
+	    rtas_getchar_token != RTAS_UNKNOWN_SERVICE)
+		udbg_init_rtas_console();
+
 #endif
 #endif
 
 
 	/* break now */
 	/* break now */

+ 13 - 15
arch/powerpc/kernel/rtas_pci.c

@@ -57,7 +57,7 @@ static inline int config_access_valid(struct pci_dn *dn, int where)
 
 
 static int of_device_available(struct device_node * dn)
 static int of_device_available(struct device_node * dn)
 {
 {
-        char * status;
+        const char *status;
 
 
         status = get_property(dn, "status", NULL);
         status = get_property(dn, "status", NULL);
 
 
@@ -81,8 +81,7 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
 	if (!config_access_valid(pdn, where))
 	if (!config_access_valid(pdn, where))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 
-	addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
-		(pdn->devfn << 8) | (where & 0xff);
+	addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
 	buid = pdn->phb->buid;
 	buid = pdn->phb->buid;
 	if (buid) {
 	if (buid) {
 		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
 		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
@@ -134,8 +133,7 @@ int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
 	if (!config_access_valid(pdn, where))
 	if (!config_access_valid(pdn, where))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 
-	addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
-		(pdn->devfn << 8) | (where & 0xff);
+	addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
 	buid = pdn->phb->buid;
 	buid = pdn->phb->buid;
 	if (buid) {
 	if (buid) {
 		ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
 		ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
@@ -178,7 +176,7 @@ struct pci_ops rtas_pci_ops = {
 
 
 int is_python(struct device_node *dev)
 int is_python(struct device_node *dev)
 {
 {
-	char *model = (char *)get_property(dev, "model", NULL);
+	const char *model = get_property(dev, "model", NULL);
 
 
 	if (model && strstr(model, "Python"))
 	if (model && strstr(model, "Python"))
 		return 1;
 		return 1;
@@ -234,7 +232,7 @@ void __init init_pci_config_tokens (void)
 unsigned long __devinit get_phb_buid (struct device_node *phb)
 unsigned long __devinit get_phb_buid (struct device_node *phb)
 {
 {
 	int addr_cells;
 	int addr_cells;
-	unsigned int *buid_vals;
+	const unsigned int *buid_vals;
 	unsigned int len;
 	unsigned int len;
 	unsigned long buid;
 	unsigned long buid;
 
 
@@ -247,7 +245,7 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
 	if (phb->parent->parent)
 	if (phb->parent->parent)
 		return 0;
 		return 0;
 
 
-	buid_vals = (unsigned int *) get_property(phb, "reg", &len);
+	buid_vals = get_property(phb, "reg", &len);
 	if (buid_vals == NULL)
 	if (buid_vals == NULL)
 		return 0;
 		return 0;
 
 
@@ -264,10 +262,10 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
 static int phb_set_bus_ranges(struct device_node *dev,
 static int phb_set_bus_ranges(struct device_node *dev,
 			      struct pci_controller *phb)
 			      struct pci_controller *phb)
 {
 {
-	int *bus_range;
+	const int *bus_range;
 	unsigned int len;
 	unsigned int len;
 
 
-	bus_range = (int *) get_property(dev, "bus-range", &len);
+	bus_range = get_property(dev, "bus-range", &len);
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 		return 1;
 		return 1;
  	}
  	}
@@ -325,15 +323,15 @@ unsigned long __init find_and_init_phbs(void)
 	 * in chosen.
 	 * in chosen.
 	 */
 	 */
 	if (of_chosen) {
 	if (of_chosen) {
-		int *prop;
+		const int *prop;
 
 
-		prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
-					   NULL);
+		prop = get_property(of_chosen,
+				"linux,pci-probe-only", NULL);
 		if (prop)
 		if (prop)
 			pci_probe_only = *prop;
 			pci_probe_only = *prop;
 
 
-		prop = (int *)get_property(of_chosen,
-					   "linux,pci-assign-all-buses", NULL);
+		prop = get_property(of_chosen,
+				"linux,pci-assign-all-buses", NULL);
 		if (prop)
 		if (prop)
 			pci_assign_all_buses = *prop;
 			pci_assign_all_buses = *prop;
 	}
 	}

+ 18 - 14
arch/powerpc/kernel/setup-common.c

@@ -304,19 +304,21 @@ struct seq_operations cpuinfo_op = {
 void __init check_for_initrd(void)
 void __init check_for_initrd(void)
 {
 {
 #ifdef CONFIG_BLK_DEV_INITRD
 #ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long *prop;
+	const unsigned int *prop;
+	int len;
 
 
 	DBG(" -> check_for_initrd()\n");
 	DBG(" -> check_for_initrd()\n");
 
 
 	if (of_chosen) {
 	if (of_chosen) {
-		prop = (unsigned long *)get_property(of_chosen,
-				"linux,initrd-start", NULL);
+		prop = get_property(of_chosen, "linux,initrd-start", &len);
 		if (prop != NULL) {
 		if (prop != NULL) {
-			initrd_start = (unsigned long)__va(*prop);
-			prop = (unsigned long *)get_property(of_chosen,
-					"linux,initrd-end", NULL);
+			initrd_start = (unsigned long)
+				__va(of_read_ulong(prop, len / 4));
+			prop = get_property(of_chosen,
+					"linux,initrd-end", &len);
 			if (prop != NULL) {
 			if (prop != NULL) {
-				initrd_end = (unsigned long)__va(*prop);
+				initrd_end = (unsigned long)
+					__va(of_read_ulong(prop, len / 4));
 				initrd_below_start_ok = 1;
 				initrd_below_start_ok = 1;
 			} else
 			} else
 				initrd_start = 0;
 				initrd_start = 0;
@@ -366,15 +368,14 @@ void __init smp_setup_cpu_maps(void)
 	int cpu = 0;
 	int cpu = 0;
 
 
 	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
 	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
-		int *intserv;
+		const int *intserv;
 		int j, len = sizeof(u32), nthreads = 1;
 		int j, len = sizeof(u32), nthreads = 1;
 
 
-		intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s",
-					      &len);
+		intserv = get_property(dn, "ibm,ppc-interrupt-server#s", &len);
 		if (intserv)
 		if (intserv)
 			nthreads = len / sizeof(int);
 			nthreads = len / sizeof(int);
 		else {
 		else {
-			intserv = (int *) get_property(dn, "reg", NULL);
+			intserv = get_property(dn, "reg", NULL);
 			if (!intserv)
 			if (!intserv)
 				intserv = &cpu;	/* assume logical == phys */
 				intserv = &cpu;	/* assume logical == phys */
 		}
 		}
@@ -395,13 +396,12 @@ void __init smp_setup_cpu_maps(void)
 	if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
 	if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
 	    (dn = of_find_node_by_path("/rtas"))) {
 	    (dn = of_find_node_by_path("/rtas"))) {
 		int num_addr_cell, num_size_cell, maxcpus;
 		int num_addr_cell, num_size_cell, maxcpus;
-		unsigned int *ireg;
+		const unsigned int *ireg;
 
 
 		num_addr_cell = prom_n_addr_cells(dn);
 		num_addr_cell = prom_n_addr_cells(dn);
 		num_size_cell = prom_n_size_cells(dn);
 		num_size_cell = prom_n_size_cells(dn);
 
 
-		ireg = (unsigned int *)
-			get_property(dn, "ibm,lrdr-capacity", NULL);
+		ireg = get_property(dn, "ibm,lrdr-capacity", NULL);
 
 
 		if (!ireg)
 		if (!ireg)
 			goto out;
 			goto out;
@@ -444,6 +444,8 @@ void __init smp_setup_cpu_maps(void)
 
 
 int __initdata do_early_xmon;
 int __initdata do_early_xmon;
 #ifdef CONFIG_XMON
 #ifdef CONFIG_XMON
+extern int xmon_no_auto_backtrace;
+
 static int __init early_xmon(char *p)
 static int __init early_xmon(char *p)
 {
 {
 	/* ensure xmon is enabled */
 	/* ensure xmon is enabled */
@@ -452,6 +454,8 @@ static int __init early_xmon(char *p)
 			xmon_init(1);
 			xmon_init(1);
 		if (strncmp(p, "off", 3) == 0)
 		if (strncmp(p, "off", 3) == 0)
 			xmon_init(0);
 			xmon_init(0);
+		if (strncmp(p, "nobt", 4) == 0)
+			xmon_no_auto_backtrace = 1;
 		if (strncmp(p, "early", 5) != 0)
 		if (strncmp(p, "early", 5) != 0)
 			return 0;
 			return 0;
 	}
 	}

+ 11 - 12
arch/powerpc/kernel/setup_64.c

@@ -56,7 +56,6 @@
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/mmu.h>
 #include <asm/lmb.h>
 #include <asm/lmb.h>
-#include <asm/iseries/it_lp_naca.h>
 #include <asm/firmware.h>
 #include <asm/firmware.h>
 #include <asm/xmon.h>
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 #include <asm/udbg.h>
@@ -79,10 +78,10 @@ u64 ppc64_pft_size;
  * before we've read this from the device tree.
  * before we've read this from the device tree.
  */
  */
 struct ppc64_caches ppc64_caches = {
 struct ppc64_caches ppc64_caches = {
-	.dline_size = 0x80,
-	.log_dline_size = 7,
-	.iline_size = 0x80,
-	.log_iline_size = 7
+	.dline_size = 0x40,
+	.log_dline_size = 6,
+	.iline_size = 0x40,
+	.log_iline_size = 6
 };
 };
 EXPORT_SYMBOL_GPL(ppc64_caches);
 EXPORT_SYMBOL_GPL(ppc64_caches);
 
 
@@ -107,7 +106,7 @@ static int smt_enabled_cmdline;
 static void check_smt_enabled(void)
 static void check_smt_enabled(void)
 {
 {
 	struct device_node *dn;
 	struct device_node *dn;
-	char *smt_option;
+	const char *smt_option;
 
 
 	/* Allow the command line to overrule the OF option */
 	/* Allow the command line to overrule the OF option */
 	if (smt_enabled_cmdline)
 	if (smt_enabled_cmdline)
@@ -116,7 +115,7 @@ static void check_smt_enabled(void)
 	dn = of_find_node_by_path("/options");
 	dn = of_find_node_by_path("/options");
 
 
 	if (dn) {
 	if (dn) {
-		smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL);
+		smt_option = get_property(dn, "ibm,smt-enabled", NULL);
 
 
                 if (smt_option) {
                 if (smt_option) {
 			if (!strcmp(smt_option, "on"))
 			if (!strcmp(smt_option, "on"))
@@ -293,7 +292,7 @@ static void __init initialize_cache_info(void)
 		 */
 		 */
 
 
 		if ( num_cpus == 1 ) {
 		if ( num_cpus == 1 ) {
-			u32 *sizep, *lsizep;
+			const u32 *sizep, *lsizep;
 			u32 size, lsize;
 			u32 size, lsize;
 			const char *dc, *ic;
 			const char *dc, *ic;
 
 
@@ -308,10 +307,10 @@ static void __init initialize_cache_info(void)
 
 
 			size = 0;
 			size = 0;
 			lsize = cur_cpu_spec->dcache_bsize;
 			lsize = cur_cpu_spec->dcache_bsize;
-			sizep = (u32 *)get_property(np, "d-cache-size", NULL);
+			sizep = get_property(np, "d-cache-size", NULL);
 			if (sizep != NULL)
 			if (sizep != NULL)
 				size = *sizep;
 				size = *sizep;
-			lsizep = (u32 *) get_property(np, dc, NULL);
+			lsizep = get_property(np, dc, NULL);
 			if (lsizep != NULL)
 			if (lsizep != NULL)
 				lsize = *lsizep;
 				lsize = *lsizep;
 			if (sizep == 0 || lsizep == 0)
 			if (sizep == 0 || lsizep == 0)
@@ -325,10 +324,10 @@ static void __init initialize_cache_info(void)
 
 
 			size = 0;
 			size = 0;
 			lsize = cur_cpu_spec->icache_bsize;
 			lsize = cur_cpu_spec->icache_bsize;
-			sizep = (u32 *)get_property(np, "i-cache-size", NULL);
+			sizep = get_property(np, "i-cache-size", NULL);
 			if (sizep != NULL)
 			if (sizep != NULL)
 				size = *sizep;
 				size = *sizep;
-			lsizep = (u32 *)get_property(np, ic, NULL);
+			lsizep = get_property(np, ic, NULL);
 			if (lsizep != NULL)
 			if (lsizep != NULL)
 				lsize = *lsizep;
 				lsize = *lsizep;
 			if (sizep == 0 || lsizep == 0)
 			if (sizep == 0 || lsizep == 0)

+ 4 - 5
arch/powerpc/kernel/sysfs.c

@@ -60,7 +60,7 @@ static int smt_snooze_cmdline;
 static int __init smt_setup(void)
 static int __init smt_setup(void)
 {
 {
 	struct device_node *options;
 	struct device_node *options;
-	unsigned int *val;
+	const unsigned int *val;
 	unsigned int cpu;
 	unsigned int cpu;
 
 
 	if (!cpu_has_feature(CPU_FTR_SMT))
 	if (!cpu_has_feature(CPU_FTR_SMT))
@@ -70,8 +70,7 @@ static int __init smt_setup(void)
 	if (!options)
 	if (!options)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay",
-					   NULL);
+	val = get_property(options, "ibm,smt-snooze-delay", NULL);
 	if (!smt_snooze_cmdline && val) {
 	if (!smt_snooze_cmdline && val) {
 		for_each_possible_cpu(cpu)
 		for_each_possible_cpu(cpu)
 			per_cpu(smt_snooze_delay, cpu) = *val;
 			per_cpu(smt_snooze_delay, cpu) = *val;
@@ -231,7 +230,7 @@ static void register_cpu_online(unsigned int cpu)
 	if (cur_cpu_spec->num_pmcs >= 8)
 	if (cur_cpu_spec->num_pmcs >= 8)
 		sysdev_create_file(s, &attr_pmc8);
 		sysdev_create_file(s, &attr_pmc8);
 
 
-	if (cpu_has_feature(CPU_FTR_SMT))
+	if (cpu_has_feature(CPU_FTR_PURR))
 		sysdev_create_file(s, &attr_purr);
 		sysdev_create_file(s, &attr_purr);
 }
 }
 
 
@@ -273,7 +272,7 @@ static void unregister_cpu_online(unsigned int cpu)
 	if (cur_cpu_spec->num_pmcs >= 8)
 	if (cur_cpu_spec->num_pmcs >= 8)
 		sysdev_remove_file(s, &attr_pmc8);
 		sysdev_remove_file(s, &attr_pmc8);
 
 
-	if (cpu_has_feature(CPU_FTR_SMT))
+	if (cpu_has_feature(CPU_FTR_PURR))
 		sysdev_remove_file(s, &attr_purr);
 		sysdev_remove_file(s, &attr_purr);
 }
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 #endif /* CONFIG_HOTPLUG_CPU */

+ 3 - 5
arch/powerpc/kernel/time.c

@@ -860,19 +860,17 @@ EXPORT_SYMBOL(do_settimeofday);
 static int __init get_freq(char *name, int cells, unsigned long *val)
 static int __init get_freq(char *name, int cells, unsigned long *val)
 {
 {
 	struct device_node *cpu;
 	struct device_node *cpu;
-	unsigned int *fp;
+	const unsigned int *fp;
 	int found = 0;
 	int found = 0;
 
 
 	/* The cpu node should have timebase and clock frequency properties */
 	/* The cpu node should have timebase and clock frequency properties */
 	cpu = of_find_node_by_type(NULL, "cpu");
 	cpu = of_find_node_by_type(NULL, "cpu");
 
 
 	if (cpu) {
 	if (cpu) {
-		fp = (unsigned int *)get_property(cpu, name, NULL);
+		fp = get_property(cpu, name, NULL);
 		if (fp) {
 		if (fp) {
 			found = 1;
 			found = 1;
-			*val = 0;
-			while (cells--)
-				*val = (*val << 32) | *fp++;
+			*val = of_read_ulong(fp, cells);
 		}
 		}
 
 
 		of_node_put(cpu);
 		of_node_put(cpu);

+ 25 - 0
arch/powerpc/kernel/traps.c

@@ -598,6 +598,9 @@ static void parse_fpe(struct pt_regs *regs)
 #define INST_STSWI		0x7c0005aa
 #define INST_STSWI		0x7c0005aa
 #define INST_STSWX		0x7c00052a
 #define INST_STSWX		0x7c00052a
 
 
+#define INST_POPCNTB		0x7c0000f4
+#define INST_POPCNTB_MASK	0xfc0007fe
+
 static int emulate_string_inst(struct pt_regs *regs, u32 instword)
 static int emulate_string_inst(struct pt_regs *regs, u32 instword)
 {
 {
 	u8 rT = (instword >> 21) & 0x1f;
 	u8 rT = (instword >> 21) & 0x1f;
@@ -666,6 +669,23 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
 	return 0;
 	return 0;
 }
 }
 
 
+static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
+{
+	u32 ra,rs;
+	unsigned long tmp;
+
+	ra = (instword >> 16) & 0x1f;
+	rs = (instword >> 21) & 0x1f;
+
+	tmp = regs->gpr[rs];
+	tmp = tmp - ((tmp >> 1) & 0x5555555555555555ULL);
+	tmp = (tmp & 0x3333333333333333ULL) + ((tmp >> 2) & 0x3333333333333333ULL);
+	tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
+	regs->gpr[ra] = tmp;
+
+	return 0;
+}
+
 static int emulate_instruction(struct pt_regs *regs)
 static int emulate_instruction(struct pt_regs *regs)
 {
 {
 	u32 instword;
 	u32 instword;
@@ -703,6 +723,11 @@ static int emulate_instruction(struct pt_regs *regs)
 	if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
 	if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
 		return emulate_string_inst(regs, instword);
 		return emulate_string_inst(regs, instword);
 
 
+	/* Emulate the popcntb (Population Count Bytes) instruction. */
+	if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
+		return emulate_popcntb_inst(regs, instword);
+	}
+
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 

+ 8 - 8
arch/powerpc/kernel/vio.c

@@ -77,7 +77,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
 	} else
 	} else
 #endif
 #endif
 	{
 	{
-		unsigned char *dma_window;
+		const unsigned char *dma_window;
 		struct iommu_table *tbl;
 		struct iommu_table *tbl;
 		unsigned long offset, size;
 		unsigned long offset, size;
 
 
@@ -217,7 +217,7 @@ static void __devinit vio_dev_release(struct device *dev)
 struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
 struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
 {
 {
 	struct vio_dev *viodev;
 	struct vio_dev *viodev;
-	unsigned int *unit_address;
+	const unsigned int *unit_address;
 
 
 	/* we need the 'device_type' property, in order to match with drivers */
 	/* we need the 'device_type' property, in order to match with drivers */
 	if (of_node->type == NULL) {
 	if (of_node->type == NULL) {
@@ -227,7 +227,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
 		return NULL;
 		return NULL;
 	}
 	}
 
 
-	unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
+	unit_address = get_property(of_node, "reg", NULL);
 	if (unit_address == NULL) {
 	if (unit_address == NULL) {
 		printk(KERN_WARNING "%s: node %s missing 'reg'\n",
 		printk(KERN_WARNING "%s: node %s missing 'reg'\n",
 				__FUNCTION__,
 				__FUNCTION__,
@@ -249,7 +249,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
 	viodev->type = of_node->type;
 	viodev->type = of_node->type;
 	viodev->unit_address = *unit_address;
 	viodev->unit_address = *unit_address;
 	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
 	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		unit_address = (unsigned int *)get_property(of_node,
+		unit_address = get_property(of_node,
 				"linux,unit_address", NULL);
 				"linux,unit_address", NULL);
 		if (unit_address != NULL)
 		if (unit_address != NULL)
 			viodev->unit_address = *unit_address;
 			viodev->unit_address = *unit_address;
@@ -423,7 +423,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
 {
 {
 	const struct vio_dev *vio_dev = to_vio_dev(dev);
 	const struct vio_dev *vio_dev = to_vio_dev(dev);
 	struct device_node *dn = dev->platform_data;
 	struct device_node *dn = dev->platform_data;
-	char *cp;
+	const char *cp;
 	int length;
 	int length;
 
 
 	if (!num_envp)
 	if (!num_envp)
@@ -431,7 +431,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
 
 
 	if (!dn)
 	if (!dn)
 		return -ENODEV;
 		return -ENODEV;
-	cp = (char *)get_property(dn, "compatible", &length);
+	cp = get_property(dn, "compatible", &length);
 	if (!cp)
 	if (!cp)
 		return -ENODEV;
 		return -ENODEV;
 
 
@@ -493,11 +493,11 @@ static struct vio_dev *vio_find_name(const char *kobj_name)
  */
  */
 struct vio_dev *vio_find_node(struct device_node *vnode)
 struct vio_dev *vio_find_node(struct device_node *vnode)
 {
 {
-	uint32_t *unit_address;
+	const uint32_t *unit_address;
 	char kobj_name[BUS_ID_SIZE];
 	char kobj_name[BUS_ID_SIZE];
 
 
 	/* construct the kobject name from the device node */
 	/* construct the kobject name from the device node */
-	unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
+	unit_address = get_property(vnode, "reg", NULL);
 	if (!unit_address)
 	if (!unit_address)
 		return NULL;
 		return NULL;
 	snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
 	snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);

+ 0 - 1
arch/powerpc/lib/Makefile

@@ -14,7 +14,6 @@ endif
 obj-$(CONFIG_PPC64)	+= checksum_64.o copypage_64.o copyuser_64.o \
 obj-$(CONFIG_PPC64)	+= checksum_64.o copypage_64.o copyuser_64.o \
 			   memcpy_64.o usercopy_64.o mem_64.o string.o \
 			   memcpy_64.o usercopy_64.o mem_64.o string.o \
 			   strcase.o
 			   strcase.o
-obj-$(CONFIG_PPC_ISERIES) += e2a.o
 obj-$(CONFIG_XMON)	+= sstep.o
 obj-$(CONFIG_XMON)	+= sstep.o
 
 
 ifeq ($(CONFIG_PPC64),y)
 ifeq ($(CONFIG_PPC64),y)

+ 0 - 116
arch/powerpc/lib/e2a.c

@@ -1,116 +0,0 @@
-/*
- *  EBCDIC to ASCII conversion
- *
- * This function moved here from arch/powerpc/platforms/iseries/viopath.c 
- *
- * (C) Copyright 2000-2004 IBM Corporation
- *
- * This program is free software;  you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) anyu later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/module.h>
-
-unsigned char e2a(unsigned char x)
-{
-	switch (x) {
-	case 0xF0:
-		return '0';
-	case 0xF1:
-		return '1';
-	case 0xF2:
-		return '2';
-	case 0xF3:
-		return '3';
-	case 0xF4:
-		return '4';
-	case 0xF5:
-		return '5';
-	case 0xF6:
-		return '6';
-	case 0xF7:
-		return '7';
-	case 0xF8:
-		return '8';
-	case 0xF9:
-		return '9';
-	case 0xC1:
-		return 'A';
-	case 0xC2:
-		return 'B';
-	case 0xC3:
-		return 'C';
-	case 0xC4:
-		return 'D';
-	case 0xC5:
-		return 'E';
-	case 0xC6:
-		return 'F';
-	case 0xC7:
-		return 'G';
-	case 0xC8:
-		return 'H';
-	case 0xC9:
-		return 'I';
-	case 0xD1:
-		return 'J';
-	case 0xD2:
-		return 'K';
-	case 0xD3:
-		return 'L';
-	case 0xD4:
-		return 'M';
-	case 0xD5:
-		return 'N';
-	case 0xD6:
-		return 'O';
-	case 0xD7:
-		return 'P';
-	case 0xD8:
-		return 'Q';
-	case 0xD9:
-		return 'R';
-	case 0xE2:
-		return 'S';
-	case 0xE3:
-		return 'T';
-	case 0xE4:
-		return 'U';
-	case 0xE5:
-		return 'V';
-	case 0xE6:
-		return 'W';
-	case 0xE7:
-		return 'X';
-	case 0xE8:
-		return 'Y';
-	case 0xE9:
-		return 'Z';
-	}
-	return ' ';
-}
-EXPORT_SYMBOL(e2a);
-
-unsigned char* strne2a(unsigned char *dest, const unsigned char *src, size_t n)
-{
-	int i;
-
-	n = strnlen(src, n);
-
-	for (i = 0; i < n; i++)
-		dest[i] = e2a(src[i]);
-
-	return dest;
-}

+ 13 - 14
arch/powerpc/lib/locks.c

@@ -23,6 +23,7 @@
 #include <asm/hvcall.h>
 #include <asm/hvcall.h>
 #include <asm/iseries/hv_call.h>
 #include <asm/iseries/hv_call.h>
 #include <asm/smp.h>
 #include <asm/smp.h>
+#include <asm/firmware.h>
 
 
 void __spin_yield(raw_spinlock_t *lock)
 void __spin_yield(raw_spinlock_t *lock)
 {
 {
@@ -39,13 +40,12 @@ void __spin_yield(raw_spinlock_t *lock)
 	rmb();
 	rmb();
 	if (lock->slock != lock_value)
 	if (lock->slock != lock_value)
 		return;		/* something has changed */
 		return;		/* something has changed */
-#ifdef CONFIG_PPC_ISERIES
-	HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
-		((u64)holder_cpu << 32) | yield_count);
-#else
-	plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
-			   yield_count);
-#endif
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
+			((u64)holder_cpu << 32) | yield_count);
+	else
+		plpar_hcall_norets(H_CONFER,
+			get_hard_smp_processor_id(holder_cpu), yield_count);
 }
 }
 
 
 /*
 /*
@@ -69,13 +69,12 @@ void __rw_yield(raw_rwlock_t *rw)
 	rmb();
 	rmb();
 	if (rw->lock != lock_value)
 	if (rw->lock != lock_value)
 		return;		/* something has changed */
 		return;		/* something has changed */
-#ifdef CONFIG_PPC_ISERIES
-	HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
-		((u64)holder_cpu << 32) | yield_count);
-#else
-	plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
-			   yield_count);
-#endif
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
+			((u64)holder_cpu << 32) | yield_count);
+	else
+		plpar_hcall_norets(H_CONFER,
+			get_hard_smp_processor_id(holder_cpu), yield_count);
 }
 }
 #endif
 #endif
 
 

+ 14 - 17
arch/powerpc/mm/numa.c

@@ -159,12 +159,12 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
 {
 {
 	unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
 	unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
 	struct device_node *cpu_node = NULL;
 	struct device_node *cpu_node = NULL;
-	unsigned int *interrupt_server, *reg;
+	const unsigned int *interrupt_server, *reg;
 	int len;
 	int len;
 
 
 	while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
 	while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
 		/* Try interrupt server first */
 		/* Try interrupt server first */
-		interrupt_server = (unsigned int *)get_property(cpu_node,
+		interrupt_server = get_property(cpu_node,
 					"ibm,ppc-interrupt-server#s", &len);
 					"ibm,ppc-interrupt-server#s", &len);
 
 
 		len = len / sizeof(u32);
 		len = len / sizeof(u32);
@@ -175,8 +175,7 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
 					return cpu_node;
 					return cpu_node;
 			}
 			}
 		} else {
 		} else {
-			reg = (unsigned int *)get_property(cpu_node,
-							   "reg", &len);
+			reg = get_property(cpu_node, "reg", &len);
 			if (reg && (len > 0) && (reg[0] == hw_cpuid))
 			if (reg && (len > 0) && (reg[0] == hw_cpuid))
 				return cpu_node;
 				return cpu_node;
 		}
 		}
@@ -186,9 +185,9 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
 }
 }
 
 
 /* must hold reference to node during call */
 /* must hold reference to node during call */
-static int *of_get_associativity(struct device_node *dev)
+static const int *of_get_associativity(struct device_node *dev)
 {
 {
-	return (unsigned int *)get_property(dev, "ibm,associativity", NULL);
+	return get_property(dev, "ibm,associativity", NULL);
 }
 }
 
 
 /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
 /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
@@ -197,7 +196,7 @@ static int *of_get_associativity(struct device_node *dev)
 static int of_node_to_nid_single(struct device_node *device)
 static int of_node_to_nid_single(struct device_node *device)
 {
 {
 	int nid = -1;
 	int nid = -1;
-	unsigned int *tmp;
+	const unsigned int *tmp;
 
 
 	if (min_common_depth == -1)
 	if (min_common_depth == -1)
 		goto out;
 		goto out;
@@ -255,7 +254,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
 static int __init find_min_common_depth(void)
 static int __init find_min_common_depth(void)
 {
 {
 	int depth;
 	int depth;
-	unsigned int *ref_points;
+	const unsigned int *ref_points;
 	struct device_node *rtas_root;
 	struct device_node *rtas_root;
 	unsigned int len;
 	unsigned int len;
 
 
@@ -270,7 +269,7 @@ static int __init find_min_common_depth(void)
 	 * configuration (should be all 0's) and the second is for a normal
 	 * configuration (should be all 0's) and the second is for a normal
 	 * NUMA configuration.
 	 * NUMA configuration.
 	 */
 	 */
-	ref_points = (unsigned int *)get_property(rtas_root,
+	ref_points = get_property(rtas_root,
 			"ibm,associativity-reference-points", &len);
 			"ibm,associativity-reference-points", &len);
 
 
 	if ((len >= 1) && ref_points) {
 	if ((len >= 1) && ref_points) {
@@ -297,7 +296,7 @@ static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
 	of_node_put(memory);
 	of_node_put(memory);
 }
 }
 
 
-static unsigned long __devinit read_n_cells(int n, unsigned int **buf)
+static unsigned long __devinit read_n_cells(int n, const unsigned int **buf)
 {
 {
 	unsigned long result = 0;
 	unsigned long result = 0;
 
 
@@ -435,15 +434,13 @@ static int __init parse_numa_properties(void)
 		unsigned long size;
 		unsigned long size;
 		int nid;
 		int nid;
 		int ranges;
 		int ranges;
-		unsigned int *memcell_buf;
+		const unsigned int *memcell_buf;
 		unsigned int len;
 		unsigned int len;
 
 
-		memcell_buf = (unsigned int *)get_property(memory,
+		memcell_buf = get_property(memory,
 			"linux,usable-memory", &len);
 			"linux,usable-memory", &len);
 		if (!memcell_buf || len <= 0)
 		if (!memcell_buf || len <= 0)
-			memcell_buf =
-				(unsigned int *)get_property(memory, "reg",
-					&len);
+			memcell_buf = get_property(memory, "reg", &len);
 		if (!memcell_buf || len <= 0)
 		if (!memcell_buf || len <= 0)
 			continue;
 			continue;
 
 
@@ -787,10 +784,10 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
 	while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
 	while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
 		unsigned long start, size;
 		unsigned long start, size;
 		int ranges;
 		int ranges;
-		unsigned int *memcell_buf;
+		const unsigned int *memcell_buf;
 		unsigned int len;
 		unsigned int len;
 
 
-		memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
+		memcell_buf = get_property(memory, "reg", &len);
 		if (!memcell_buf || len <= 0)
 		if (!memcell_buf || len <= 0)
 			continue;
 			continue;
 
 

+ 33 - 4
arch/powerpc/mm/slb.c

@@ -22,6 +22,8 @@
 #include <asm/paca.h>
 #include <asm/paca.h>
 #include <asm/cputable.h>
 #include <asm/cputable.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
+#include <asm/smp.h>
+#include <linux/compiler.h>
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
 #define DBG(fmt...) udbg_printf(fmt)
@@ -50,9 +52,32 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
 	return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
 	return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
 }
 }
 
 
-static inline void create_slbe(unsigned long ea, unsigned long flags,
-			       unsigned long entry)
+static inline void slb_shadow_update(unsigned long esid, unsigned long vsid,
+				     unsigned long entry)
 {
 {
+	/*
+	 * Clear the ESID first so the entry is not valid while we are
+	 * updating it.
+	 */
+	get_slb_shadow()->save_area[entry].esid = 0;
+	barrier();
+	get_slb_shadow()->save_area[entry].vsid = vsid;
+	barrier();
+	get_slb_shadow()->save_area[entry].esid = esid;
+
+}
+
+static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
+					unsigned long entry)
+{
+	/*
+	 * Updating the shadow buffer before writing the SLB ensures
+	 * we don't get a stale entry here if we get preempted by PHYP
+	 * between these two statements.
+	 */
+	slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags),
+			  entry);
+
 	asm volatile("slbmte  %0,%1" :
 	asm volatile("slbmte  %0,%1" :
 		     : "r" (mk_vsid_data(ea, flags)),
 		     : "r" (mk_vsid_data(ea, flags)),
 		       "r" (mk_esid_data(ea, entry))
 		       "r" (mk_esid_data(ea, entry))
@@ -77,6 +102,10 @@ void slb_flush_and_rebolt(void)
 	if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
 	if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
 		ksp_esid_data &= ~SLB_ESID_V;
 		ksp_esid_data &= ~SLB_ESID_V;
 
 
+	/* Only third entry (stack) may change here so only resave that */
+	slb_shadow_update(ksp_esid_data,
+			  mk_vsid_data(ksp_esid_data, lflags), 2);
+
 	/* We need to do this all in asm, so we're sure we don't touch
 	/* We need to do this all in asm, so we're sure we don't touch
 	 * the stack between the slbia and rebolting it. */
 	 * the stack between the slbia and rebolting it. */
 	asm volatile("isync\n"
 	asm volatile("isync\n"
@@ -209,9 +238,9 @@ void slb_initialize(void)
 	asm volatile("isync":::"memory");
 	asm volatile("isync":::"memory");
 	asm volatile("slbmte  %0,%0"::"r" (0) : "memory");
 	asm volatile("slbmte  %0,%0"::"r" (0) : "memory");
 	asm volatile("isync; slbia; isync":::"memory");
 	asm volatile("isync; slbia; isync":::"memory");
-	create_slbe(PAGE_OFFSET, lflags, 0);
+	create_shadowed_slbe(PAGE_OFFSET, lflags, 0);
 
 
-	create_slbe(VMALLOC_START, vflags, 1);
+	create_shadowed_slbe(VMALLOC_START, vflags, 1);
 
 
 	/* We don't bolt the stack for the time being - we're in boot,
 	/* We don't bolt the stack for the time being - we're in boot,
 	 * so the stack is in the bolted segment.  By the time it goes
 	 * so the stack is in the bolted segment.  By the time it goes

+ 1 - 0
arch/powerpc/mm/tlb_64.c

@@ -146,6 +146,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
 		psize = mmu_huge_psize;
 		psize = mmu_huge_psize;
 #else
 #else
 		BUG();
 		BUG();
+		psize = pte_pagesize_index(pte); /* shutup gcc */
 #endif
 #endif
 	} else
 	} else
 		psize = pte_pagesize_index(pte);
 		psize = pte_pagesize_index(pte);

+ 2 - 2
arch/powerpc/platforms/83xx/mpc834x_itx.c

@@ -60,8 +60,8 @@ static void __init mpc834x_itx_setup_arch(void)
 
 
 	np = of_find_node_by_type(NULL, "cpu");
 	np = of_find_node_by_type(NULL, "cpu");
 	if (np != 0) {
 	if (np != 0) {
-		unsigned int *fp =
-		    (int *)get_property(np, "clock-frequency", NULL);
+		const unsigned int *fp =
+			get_property(np, "clock-frequency", NULL);
 		if (fp != 0)
 		if (fp != 0)
 			loops_per_jiffy = *fp / HZ;
 			loops_per_jiffy = *fp / HZ;
 		else
 		else

+ 2 - 2
arch/powerpc/platforms/83xx/mpc834x_sys.c

@@ -57,8 +57,8 @@ static void __init mpc834x_sys_setup_arch(void)
 
 
 	np = of_find_node_by_type(NULL, "cpu");
 	np = of_find_node_by_type(NULL, "cpu");
 	if (np != 0) {
 	if (np != 0) {
-		unsigned int *fp =
-		    (int *)get_property(np, "clock-frequency", NULL);
+		const unsigned int *fp =
+			get_property(np, "clock-frequency", NULL);
 		if (fp != 0)
 		if (fp != 0)
 			loops_per_jiffy = *fp / HZ;
 			loops_per_jiffy = *fp / HZ;
 		else
 		else

+ 2 - 2
arch/powerpc/platforms/83xx/pci.c

@@ -59,7 +59,7 @@ int __init add_bridge(struct device_node *dev)
 	int len;
 	int len;
 	struct pci_controller *hose;
 	struct pci_controller *hose;
 	struct resource rsrc;
 	struct resource rsrc;
-	int *bus_range;
+	const int *bus_range;
 	int primary = 1, has_address = 0;
 	int primary = 1, has_address = 0;
 	phys_addr_t immr = get_immrbase();
 	phys_addr_t immr = get_immrbase();
 
 
@@ -69,7 +69,7 @@ int __init add_bridge(struct device_node *dev)
 	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
 	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
 
 
 	/* Get bus range if any */
 	/* Get bus range if any */
-	bus_range = (int *)get_property(dev, "bus-range", &len);
+	bus_range = get_property(dev, "bus-range", &len);
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 		       " bus 0\n", dev->full_name);
 		       " bus 0\n", dev->full_name);

+ 2 - 2
arch/powerpc/platforms/85xx/mpc85xx_ads.c

@@ -121,9 +121,9 @@ static void __init mpc85xx_ads_setup_arch(void)
 
 
 	cpu = of_find_node_by_type(NULL, "cpu");
 	cpu = of_find_node_by_type(NULL, "cpu");
 	if (cpu != 0) {
 	if (cpu != 0) {
-		unsigned int *fp;
+		const unsigned int *fp;
 
 
-		fp = (int *)get_property(cpu, "clock-frequency", NULL);
+		fp = get_property(cpu, "clock-frequency", NULL);
 		if (fp != 0)
 		if (fp != 0)
 			loops_per_jiffy = *fp / HZ;
 			loops_per_jiffy = *fp / HZ;
 		else
 		else

+ 2 - 2
arch/powerpc/platforms/85xx/mpc85xx_cds.c

@@ -241,9 +241,9 @@ mpc85xx_cds_setup_arch(void)
 
 
 	cpu = of_find_node_by_type(NULL, "cpu");
 	cpu = of_find_node_by_type(NULL, "cpu");
 	if (cpu != 0) {
 	if (cpu != 0) {
-		unsigned int *fp;
+		const unsigned int *fp;
 
 
-		fp = (int *)get_property(cpu, "clock-frequency", NULL);
+		fp = get_property(cpu, "clock-frequency", NULL);
 		if (fp != 0)
 		if (fp != 0)
 			loops_per_jiffy = *fp / HZ;
 			loops_per_jiffy = *fp / HZ;
 		else
 		else

+ 2 - 2
arch/powerpc/platforms/85xx/pci.c

@@ -41,7 +41,7 @@ int __init add_bridge(struct device_node *dev)
 	int len;
 	int len;
 	struct pci_controller *hose;
 	struct pci_controller *hose;
 	struct resource rsrc;
 	struct resource rsrc;
-	int *bus_range;
+	const int *bus_range;
 	int primary = 1, has_address = 0;
 	int primary = 1, has_address = 0;
 	phys_addr_t immr = get_immrbase();
 	phys_addr_t immr = get_immrbase();
 
 
@@ -51,7 +51,7 @@ int __init add_bridge(struct device_node *dev)
 	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
 	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
 
 
 	/* Get bus range if any */
 	/* Get bus range if any */
-	bus_range = (int *) get_property(dev, "bus-range", &len);
+	bus_range = get_property(dev, "bus-range", &len);
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 		       " bus 0\n", dev->full_name);
 		       " bus 0\n", dev->full_name);

+ 2 - 2
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c

@@ -347,9 +347,9 @@ mpc86xx_hpcn_setup_arch(void)
 
 
 	np = of_find_node_by_type(NULL, "cpu");
 	np = of_find_node_by_type(NULL, "cpu");
 	if (np != 0) {
 	if (np != 0) {
-		unsigned int *fp;
+		const unsigned int *fp;
 
 
-		fp = (int *)get_property(np, "clock-frequency", NULL);
+		fp = get_property(np, "clock-frequency", NULL);
 		if (fp != 0)
 		if (fp != 0)
 			loops_per_jiffy = *fp / HZ;
 			loops_per_jiffy = *fp / HZ;
 		else
 		else

+ 2 - 2
arch/powerpc/platforms/86xx/pci.c

@@ -153,7 +153,7 @@ int __init add_bridge(struct device_node *dev)
 	int len;
 	int len;
 	struct pci_controller *hose;
 	struct pci_controller *hose;
 	struct resource rsrc;
 	struct resource rsrc;
-	int *bus_range;
+	const int *bus_range;
 	int has_address = 0;
 	int has_address = 0;
 	int primary = 0;
 	int primary = 0;
 
 
@@ -163,7 +163,7 @@ int __init add_bridge(struct device_node *dev)
 	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
 	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
 
 
 	/* Get bus range if any */
 	/* Get bus range if any */
-	bus_range = (int *) get_property(dev, "bus-range", &len);
+	bus_range = get_property(dev, "bus-range", &len);
 	if (bus_range == NULL || len < 2 * sizeof(int))
 	if (bus_range == NULL || len < 2 * sizeof(int))
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 		       " bus 0\n", dev->full_name);
 		       " bus 0\n", dev->full_name);

+ 1 - 0
arch/powerpc/platforms/Makefile

@@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx)		+= 86xx/
 obj-$(CONFIG_PPC_PSERIES)	+= pseries/
 obj-$(CONFIG_PPC_PSERIES)	+= pseries/
 obj-$(CONFIG_PPC_ISERIES)	+= iseries/
 obj-$(CONFIG_PPC_ISERIES)	+= iseries/
 obj-$(CONFIG_PPC_MAPLE)		+= maple/
 obj-$(CONFIG_PPC_MAPLE)		+= maple/
+obj-$(CONFIG_PPC_PASEMI)		+= pasemi/
 obj-$(CONFIG_PPC_CELL)		+= cell/
 obj-$(CONFIG_PPC_CELL)		+= cell/
 obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/
 obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/

+ 3 - 5
arch/powerpc/platforms/cell/cbe_regs.c

@@ -97,7 +97,7 @@ void __init cbe_regs_init(void)
 		struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
 		struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
 
 
 		/* That hack must die die die ! */
 		/* That hack must die die die ! */
-		struct address_prop {
+		const struct address_prop {
 			unsigned long address;
 			unsigned long address;
 			unsigned int len;
 			unsigned int len;
 		} __attribute__((packed)) *prop;
 		} __attribute__((packed)) *prop;
@@ -114,13 +114,11 @@ void __init cbe_regs_init(void)
 			if (cbe_thread_map[i].cpu_node == cpu)
 			if (cbe_thread_map[i].cpu_node == cpu)
 				cbe_thread_map[i].regs = map;
 				cbe_thread_map[i].regs = map;
 
 
-		prop = (struct address_prop *)get_property(cpu, "pervasive",
-							   NULL);
+		prop = get_property(cpu, "pervasive", NULL);
 		if (prop != NULL)
 		if (prop != NULL)
 			map->pmd_regs = ioremap(prop->address, prop->len);
 			map->pmd_regs = ioremap(prop->address, prop->len);
 
 
-		prop = (struct address_prop *)get_property(cpu, "iic",
-							   NULL);
+		prop = get_property(cpu, "iic", NULL);
 		if (prop != NULL)
 		if (prop != NULL)
 			map->iic_regs = ioremap(prop->address, prop->len);
 			map->iic_regs = ioremap(prop->address, prop->len);
 	}
 	}

+ 12 - 13
arch/powerpc/platforms/cell/interrupt.c

@@ -89,17 +89,17 @@ static struct irq_chip iic_chip = {
 /* Get an IRQ number from the pending state register of the IIC */
 /* Get an IRQ number from the pending state register of the IIC */
 static unsigned int iic_get_irq(struct pt_regs *regs)
 static unsigned int iic_get_irq(struct pt_regs *regs)
 {
 {
-  	struct cbe_iic_pending_bits pending;
- 	struct iic *iic;
-
- 	iic = &__get_cpu_var(iic);
- 	*(unsigned long *) &pending =
- 		in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
- 	iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
- 	BUG_ON(iic->eoi_ptr > 15);
+	struct cbe_iic_pending_bits pending;
+	struct iic *iic;
+
+	iic = &__get_cpu_var(iic);
+	*(unsigned long *) &pending =
+		in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
+	iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
+	BUG_ON(iic->eoi_ptr > 15);
 	if (pending.flags & CBE_IIC_IRQ_VALID)
 	if (pending.flags & CBE_IIC_IRQ_VALID)
 		return irq_linear_revmap(iic->host,
 		return irq_linear_revmap(iic->host,
- 					 iic_pending_to_hwnum(pending));
+					 iic_pending_to_hwnum(pending));
 	return NO_IRQ;
 	return NO_IRQ;
 }
 }
 
 
@@ -250,16 +250,15 @@ static int __init setup_iic(void)
 	struct resource r0, r1;
 	struct resource r0, r1;
 	struct irq_host *host;
 	struct irq_host *host;
 	int found = 0;
 	int found = 0;
- 	u32 *np;
+	const u32 *np;
 
 
 	for (dn = NULL;
 	for (dn = NULL;
 	     (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
 	     (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
 		if (!device_is_compatible(dn,
 		if (!device_is_compatible(dn,
 				     "IBM,CBEA-Internal-Interrupt-Controller"))
 				     "IBM,CBEA-Internal-Interrupt-Controller"))
 			continue;
 			continue;
- 		np = (u32 *)get_property(dn, "ibm,interrupt-server-ranges",
-					 NULL);
- 		if (np == NULL) {
+		np = get_property(dn, "ibm,interrupt-server-ranges", NULL);
+		if (np == NULL) {
 			printk(KERN_WARNING "IIC: CPU association not found\n");
 			printk(KERN_WARNING "IIC: CPU association not found\n");
 			of_node_put(dn);
 			of_node_put(dn);
 			return -ENODEV;
 			return -ENODEV;

+ 12 - 10
arch/powerpc/platforms/cell/iommu.c

@@ -308,15 +308,16 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
 
 
 static void iommu_devnode_setup(struct device_node *d)
 static void iommu_devnode_setup(struct device_node *d)
 {
 {
-	unsigned int *ioid;
-	unsigned long *dma_window, map_start, map_size, token;
+	const unsigned int *ioid;
+	unsigned long map_start, map_size, token;
+	const unsigned long *dma_window;
 	struct cell_iommu *iommu;
 	struct cell_iommu *iommu;
 
 
-	ioid = (unsigned int *)get_property(d, "ioid", NULL);
+	ioid = get_property(d, "ioid", NULL);
 	if (!ioid)
 	if (!ioid)
 		pr_debug("No ioid entry found !\n");
 		pr_debug("No ioid entry found !\n");
 
 
-	dma_window = (unsigned long *)get_property(d, "ibm,dma-window", NULL);
+	dma_window = get_property(d, "ibm,dma-window", NULL);
 	if (!dma_window)
 	if (!dma_window)
 		pr_debug("No ibm,dma-window entry found !\n");
 		pr_debug("No ibm,dma-window entry found !\n");
 
 
@@ -371,8 +372,9 @@ static int cell_map_iommu_hardcoded(int num_nodes)
 
 
 static int cell_map_iommu(void)
 static int cell_map_iommu(void)
 {
 {
-	unsigned int num_nodes = 0, *node_id;
-	unsigned long *base, *mmio_base;
+	unsigned int num_nodes = 0;
+	const unsigned int *node_id;
+	const unsigned long *base, *mmio_base;
 	struct device_node *dn;
 	struct device_node *dn;
 	struct cell_iommu *iommu = NULL;
 	struct cell_iommu *iommu = NULL;
 
 
@@ -381,7 +383,7 @@ static int cell_map_iommu(void)
 	for(dn = of_find_node_by_type(NULL, "cpu");
 	for(dn = of_find_node_by_type(NULL, "cpu");
 	    dn;
 	    dn;
 	    dn = of_find_node_by_type(dn, "cpu")) {
 	    dn = of_find_node_by_type(dn, "cpu")) {
-		node_id = (unsigned int *)get_property(dn, "node-id", NULL);
+		node_id = get_property(dn, "node-id", NULL);
 
 
 		if (num_nodes < *node_id)
 		if (num_nodes < *node_id)
 			num_nodes = *node_id;
 			num_nodes = *node_id;
@@ -396,9 +398,9 @@ static int cell_map_iommu(void)
 	    dn;
 	    dn;
 	    dn = of_find_node_by_type(dn, "cpu")) {
 	    dn = of_find_node_by_type(dn, "cpu")) {
 
 
-		node_id = (unsigned int *)get_property(dn, "node-id", NULL);
-		base = (unsigned long *)get_property(dn, "ioc-cache", NULL);
-		mmio_base = (unsigned long *)get_property(dn, "ioc-translation", NULL);
+		node_id = get_property(dn, "node-id", NULL);
+		base = get_property(dn, "ioc-cache", NULL);
+		mmio_base = get_property(dn, "ioc-translation", NULL);
 
 
 		if (!base || !mmio_base || !node_id)
 		if (!base || !mmio_base || !node_id)
 			return cell_map_iommu_hardcoded(num_nodes);
 			return cell_map_iommu_hardcoded(num_nodes);

+ 0 - 4
arch/powerpc/platforms/cell/setup.c

@@ -150,10 +150,6 @@ static int __init cell_probe(void)
 	    !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
 	    !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
 		return 0;
 		return 0;
 
 
-#ifdef CONFIG_UDBG_RTAS_CONSOLE
-	udbg_init_rtas_console();
-#endif
-
 	hpte_init_native();
 	hpte_init_native();
 
 
 	return 1;
 	return 1;

+ 2 - 2
arch/powerpc/platforms/cell/smp.c

@@ -57,7 +57,7 @@
  */
  */
 static cpumask_t of_spin_map;
 static cpumask_t of_spin_map;
 
 
-extern void pSeries_secondary_smp_init(unsigned long);
+extern void generic_secondary_smp_init(unsigned long);
 
 
 /**
 /**
  * smp_startup_cpu() - start the given cpu
  * smp_startup_cpu() - start the given cpu
@@ -74,7 +74,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
 {
 {
 	int status;
 	int status;
 	unsigned long start_here = __pa((u32)*((unsigned long *)
 	unsigned long start_here = __pa((u32)*((unsigned long *)
-					       pSeries_secondary_smp_init));
+					       generic_secondary_smp_init));
 	unsigned int pcpu;
 	unsigned int pcpu;
 	int start_cpu;
 	int start_cpu;
 
 

Some files were not shown because too many files changed in this diff