Please add the following bug fixes to 2.6.36-stable

The first is a rather obvious HZ bug on Leon sparc 32-bit.

The rest of the patches deal with a regression involving firmware
calls.  For certain kinds of calls, in particular firmware console
writes, we can't pass in a buffer addressed above 4GB, so we
use a bounce buffer to deal with this limitation.

Thanks.
>From b203e3cc8ab98a0e6a0d1bef65dbabc0d2ebad0e Mon Sep 17 00:00:00 2001
From: Daniel Hellstrom <[email protected]>
Date: Fri, 29 Oct 2010 13:25:24 -0700
Subject: [PATCH 01/10] SPARC/LEON: removed constant timer initialization as if 
HZ=100, now it reflects the value of HZ

[ Upstream commit b690c425fe07c725e7f1f7d40303588416cba67f ]

Signed-off-by: Daniel Hellstrom <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/leon_kernel.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 6a7b4db..dcefd22 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
        if (leon3_gptimer_regs && leon3_irqctrl_regs) {
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
-                                     (((1000000 / 100) - 1)));
+                                     (((1000000 / HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
 
 #ifdef CONFIG_SMP
@@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
                }
 
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, 
(((1000000/100) - 1)));
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, 
(((1000000/HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
 # endif
 
-- 
1.7.3.4


>From bc389c4be6cfaf636103b4e4dfdeabb6e8adbe32 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 16 Nov 2010 12:08:23 -0800
Subject: [PATCH 02/10] sparc64: Delete prom_puts() unused.

[ Upstream commit ce05a94efaf71d562eeefd30d6bbc2ab42b06bac ]

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/prom/console_64.c |   16 ----------------
 1 files changed, 0 insertions(+), 16 deletions(-)

diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index 10322dc..de67fc7 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -81,19 +81,3 @@ prom_putchar(char c)
 {
        prom_nbputchar(c);
 }
-
-void
-prom_puts(const char *s, int len)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "write";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) s;
-       args[5] = len;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-}
-- 
1.7.3.4


>From 4948cb473bbe934273498daec57176dddf188c65 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 16 Nov 2010 12:11:15 -0800
Subject: [PATCH 03/10] sparc: Remove prom_pathtoinode()

[ Upstream commit 17d70d6df0c4ea7a203b444001572a91ad9c2bef ]

Unused.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/oplib_32.h |    1 -
 arch/sparc/include/asm/oplib_64.h |    1 -
 arch/sparc/prom/tree_32.c         |   15 ---------------
 arch/sparc/prom/tree_64.c         |   18 ------------------
 4 files changed, 0 insertions(+), 35 deletions(-)

diff --git a/arch/sparc/include/asm/oplib_32.h 
b/arch/sparc/include/asm/oplib_32.h
index 33e31ce..72bc43c 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -238,7 +238,6 @@ extern int prom_node_has_property(int node, char *property);
 extern int prom_setprop(int node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern int prom_pathtoinode(char *path);
 extern int prom_inst2pkg(int);
 
 /* Dorking with Bus ranges... */
diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index 3e0b2d6..061c6a3 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -278,7 +278,6 @@ extern int prom_finddevice(const char *name);
 extern int prom_setprop(int node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern int prom_pathtoinode(const char *path);
 extern int prom_inst2pkg(int);
 extern int prom_service_exists(const char *service_name);
 extern void prom_sun4v_guest_soft_state(void);
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c
index b21592f..71e7f08 100644
--- a/arch/sparc/prom/tree_32.c
+++ b/arch/sparc/prom/tree_32.c
@@ -341,18 +341,3 @@ int prom_inst2pkg(int inst)
        if (node == -1) return 0;
        return node;
 }
-
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-int prom_pathtoinode(char *path)
-{
-       int node, inst;
-       
-       inst = prom_devopen (path);
-       if (inst == -1) return 0;
-       node = prom_inst2pkg (inst);
-       prom_devclose (inst);
-       if (node == -1) return 0;
-       return node;
-}
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 9d3f913..8327b1b 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -374,24 +374,6 @@ inline int prom_inst2pkg(int inst)
        return node;
 }
 
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-int
-prom_pathtoinode(const char *path)
-{
-       int node, inst;
-
-       inst = prom_devopen (path);
-       if (inst == 0)
-               return 0;
-       node = prom_inst2pkg(inst);
-       prom_devclose(inst);
-       if (node == -1)
-               return 0;
-       return node;
-}
-
 int prom_ihandle2path(int handle, char *buffer, int bufsize)
 {
        unsigned long args[7];
-- 
1.7.3.4


>From 731e466bd3f80a9601e848fe0262e65c9ef0b377 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 16 Nov 2010 12:23:20 -0800
Subject: [PATCH 04/10] sparc: Kill prom devops_{32,64}.c

[ Upstream commit b148246912bea92bde2a0cba125ca94f1f776b12 ]

Completely unused.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/oplib_32.h |   19 --------
 arch/sparc/include/asm/oplib_64.h |   21 ---------
 arch/sparc/prom/Makefile          |    1 -
 arch/sparc/prom/devops_32.c       |   87 -------------------------------------
 arch/sparc/prom/devops_64.c       |   67 ----------------------------
 5 files changed, 0 insertions(+), 195 deletions(-)
 delete mode 100644 arch/sparc/prom/devops_32.c
 delete mode 100644 arch/sparc/prom/devops_64.c

diff --git a/arch/sparc/include/asm/oplib_32.h 
b/arch/sparc/include/asm/oplib_32.h
index 72bc43c..66df2b1 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -60,25 +60,6 @@ extern char *prom_getbootargs(void);
 extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, 
unsigned int num_bytes);
 extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
 
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index 061c6a3..e7a53a3 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack);
 /* Boot argument acquisition, returns the boot command line string. */
 extern char *prom_getbootargs(void);
 
-/* Device utilities. */
-
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(const char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile
index 1b8c073..816c0fa 100644
--- a/arch/sparc/prom/Makefile
+++ b/arch/sparc/prom/Makefile
@@ -6,7 +6,6 @@ ccflags := -Werror
 
 lib-y                 := bootstr_$(BITS).o
 lib-$(CONFIG_SPARC32) += devmap.o
-lib-y                 += devops_$(BITS).o
 lib-y                 += init_$(BITS).o
 lib-$(CONFIG_SPARC32) += memory.o
 lib-y                 += misc_$(BITS).o
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c
deleted file mode 100644
index 9c5d468..0000000
--- a/arch/sparc/prom/devops_32.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-extern void restore_current(void);
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns -1 on failure.
- */
-int
-prom_devopen(char *dstr)
-{
-       int handle;
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
-               if(handle == 0) handle = -1;
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr);
-               break;
-       default:
-               handle = -1;
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-
-       return handle;
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_devclose))(dhandle);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_close))(dhandle);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-}
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c
deleted file mode 100644
index a017119..0000000
--- a/arch/sparc/prom/devops_64.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- * Copyright (C) 1996,1997 Jakub Jelinek ([email protected])
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns 0 on failure.
- */
-int
-prom_devopen(const char *dstr)
-{
-       unsigned long args[5];
-
-       args[0] = (unsigned long) "open";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) dstr;
-       args[4] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       return (int) args[4];
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long args[4];
-
-       args[0] = (unsigned long) "close";
-       args[1] = 1;
-       args[2] = 0;
-       args[3] = (unsigned int) dhandle;
-
-       p1275_cmd_direct(args);
-
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "seek";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) dhandle;
-       args[4] = seekhi;
-       args[5] = seeklo;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-}
-- 
1.7.3.4


>From b3596383d350eeb552954eee4aaeee64efcdc443 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 16 Nov 2010 12:24:16 -0800
Subject: [PATCH 05/10] sparc64: Unexport prom_service_exists().

[ Upstream commit f7b5f55ac1623dfde24ef5319ad77c1746645f3f ]

Only used by functions in misc_64.c so make it private
to that file.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/oplib_64.h |    1 -
 arch/sparc/prom/misc_64.c         |    2 +-
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index e7a53a3..1c81a27 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -258,7 +258,6 @@ extern int prom_setprop(int node, const char *prop_name, 
char *prop_value,
                        int value_size);
 
 extern int prom_inst2pkg(int);
-extern int prom_service_exists(const char *service_name);
 extern void prom_sun4v_guest_soft_state(void);
 
 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index 6cb1581..4a89893 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -18,7 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldc.h>
 
-int prom_service_exists(const char *service_name)
+static int prom_service_exists(const char *service_name)
 {
        unsigned long args[5];
 
-- 
1.7.3.4


>From 1bcb53777cfdf5f1148e5aab9a4742789b4c52a4 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 16 Nov 2010 12:50:19 -0800
Subject: [PATCH 06/10] sparc64: Delete prom_setcallback().

[ Upstream commit c540ee70e49b573535c7ddfd0e9a0fc9d549c8b7 ]

Unused.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/oplib_64.h |    8 --------
 arch/sparc/prom/misc_64.c         |   14 --------------
 2 files changed, 0 insertions(+), 22 deletions(-)

diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index 1c81a27..7ab973d 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -88,14 +88,6 @@ extern void prom_halt(void) __attribute__ ((noreturn));
 /* Halt and power-off the machine. */
 extern void prom_halt_power_off(void) __attribute__ ((noreturn));
 
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- */
-typedef int (*callback_func_t)(long *cmd);
-extern void prom_setcallback(callback_func_t func_ptr);
-
 /* Acquire the IDPROM of the root node in the prom device tree.  This
  * gets passed a buffer where you would like it stuffed.  The return value
  * is the format type of this idprom or 0xff on error.
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index 4a89893..2fdcebf 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -150,20 +150,6 @@ void prom_halt_power_off(void)
        prom_halt();
 }
 
-/* Set prom sync handler to call function 'funcp'. */
-void prom_setcallback(callback_func_t funcp)
-{
-       unsigned long args[5];
-       if (!funcp)
-               return;
-       args[0] = (unsigned long) "set-callback";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) funcp;
-       args[4] = (unsigned long) -1;
-       p1275_cmd_direct(args);
-}
-
 /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
  * format type.  'num_bytes' is the number of bytes that your idbuf
  * has space for.  Returns 0xff on error.
-- 
1.7.3.4


>From d775633c84060f48f0136a69d15249a806ad407e Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Wed, 17 Nov 2010 10:22:56 -0800
Subject: [PATCH 07/10] sparc: Do not export prom_nb{get,put}char().

[ Upstream commit 91921fef7c658b12de53376b312d071d757f7770 ]

Never used outside of console_{32,64}.c

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/oplib_32.h |    6 ------
 arch/sparc/include/asm/oplib_64.h |    6 ------
 arch/sparc/prom/console_32.c      |    6 ++----
 arch/sparc/prom/console_64.c      |    6 ++----
 4 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/arch/sparc/include/asm/oplib_32.h 
b/arch/sparc/include/asm/oplib_32.h
index 66df2b1..ca51a66 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -104,12 +104,6 @@ extern int prom_getprev(void);
 
 /* Character operations to/from the console.... */
 
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
 /* Blocking get character from console. */
 extern char prom_getchar(void);
 
diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index 7ab973d..0d614e3 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -96,12 +96,6 @@ extern unsigned char prom_get_idprom(char *idp_buffer, int 
idpbuf_size);
 
 /* Character operations to/from the console.... */
 
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
 /* Blocking get character from console. */
 extern char prom_getchar(void);
 
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c
index 5340264..2ce5acb 100644
--- a/arch/sparc/prom/console_32.c
+++ b/arch/sparc/prom/console_32.c
@@ -19,8 +19,7 @@ extern void restore_current(void);
 /* Non blocking get character from console input device, returns -1
  * if no input was taken.  This can be used for polling.
  */
-int
-prom_nbgetchar(void)
+static int prom_nbgetchar(void)
 {
        static char inc;
        int i = -1;
@@ -51,8 +50,7 @@ prom_nbgetchar(void)
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-int
-prom_nbputchar(char c)
+static int prom_nbputchar(char c)
 {
        static char outc;
        unsigned long flags;
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index de67fc7..33a8b27 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -18,8 +18,7 @@ extern int prom_stdin, prom_stdout;
 /* Non blocking get character from console input device, returns -1
  * if no input was taken.  This can be used for polling.
  */
-inline int
-prom_nbgetchar(void)
+static int prom_nbgetchar(void)
 {
        unsigned long args[7];
        char inc;
@@ -42,8 +41,7 @@ prom_nbgetchar(void)
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-inline int
-prom_nbputchar(char c)
+static int prom_nbputchar(char c)
 {
        unsigned long args[7];
        char outc;
-- 
1.7.3.4


>From 859fb9bffac2f3fb2e32766a2ce57f1789e33064 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 30 Nov 2010 14:33:29 -0800
Subject: [PATCH 08/10] sparc: Pass buffer pointer all the way down to 
prom_{get,put}char().

[ Upstream commit e62cac1fd035b4cde707285008499dbe71955a86 ]

This gets us closer to being able to eliminate the use
of dynamic and stack based buffers, so that we can adhere
to the "no buffer addresses above 4GB" rule for PROM calls.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/openprom.h |    2 +-
 arch/sparc/include/asm/oplib_32.h |    4 +-
 arch/sparc/include/asm/oplib_64.h |    4 +-
 arch/sparc/prom/console_32.c      |   50 ++++++++++++++++++------------------
 arch/sparc/prom/console_64.c      |   34 ++++++++++++------------
 arch/sparc/prom/printf.c          |   15 ++++++-----
 6 files changed, 55 insertions(+), 54 deletions(-)

diff --git a/arch/sparc/include/asm/openprom.h 
b/arch/sparc/include/asm/openprom.h
index 963e1a4..f61a501 100644
--- a/arch/sparc/include/asm/openprom.h
+++ b/arch/sparc/include/asm/openprom.h
@@ -37,7 +37,7 @@ struct linux_dev_v2_funcs {
        int (*v2_dev_open)(char *devpath);
        void (*v2_dev_close)(int d);
        int (*v2_dev_read)(int d, char *buf, int nbytes);
-       int (*v2_dev_write)(int d, char *buf, int nbytes);
+       int (*v2_dev_write)(int d, const char *buf, int nbytes);
        int (*v2_dev_seek)(int d, int hi, int lo);
 
        /* Never issued (multistage load support) */
diff --git a/arch/sparc/include/asm/oplib_32.h 
b/arch/sparc/include/asm/oplib_32.h
index ca51a66..4d708b7 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -105,10 +105,10 @@ extern int prom_getprev(void);
 /* Character operations to/from the console.... */
 
 /* Blocking get character from console. */
-extern char prom_getchar(void);
+extern void prom_getchar(char *buf);
 
 /* Blocking put character to console. */
-extern void prom_putchar(char character);
+extern void prom_putchar(const char *buf);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index 0d614e3..891a00b 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -97,10 +97,10 @@ extern unsigned char prom_get_idprom(char *idp_buffer, int 
idpbuf_size);
 /* Character operations to/from the console.... */
 
 /* Blocking get character from console. */
-extern char prom_getchar(void);
+extern void prom_getchar(char *buf);
 
 /* Blocking put character to console. */
-extern void prom_putchar(char character);
+extern void prom_putchar(const char *buf);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c
index 2ce5acb..69c16bb 100644
--- a/arch/sparc/prom/console_32.c
+++ b/arch/sparc/prom/console_32.c
@@ -19,27 +19,27 @@ extern void restore_current(void);
 /* Non blocking get character from console input device, returns -1
  * if no input was taken.  This can be used for polling.
  */
-static int prom_nbgetchar(void)
+static int prom_nbgetchar(char *buf)
 {
-       static char inc;
-       int i = -1;
        unsigned long flags;
+       int i = -1;
 
        spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
                i = (*(romvec->pv_nbgetchar))();
+               if (i != -1) {
+                       *buf = i;
+                       i = 0;
+               }
                break;
        case PROM_V2:
        case PROM_V3:
-               if( 
(*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 
0x1) == 1) {
-                       i = inc;
-               } else {
-                       i = -1;
-               }
+               if 
((*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin,
+                                                        buf, 0x1) == 1)
+                       i = 0;
                break;
        default:
-               i = -1;
                break;
        };
        restore_current();
@@ -50,27 +50,23 @@ static int prom_nbgetchar(void)
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-static int prom_nbputchar(char c)
+static int prom_nbputchar(const char *buf)
 {
-       static char outc;
        unsigned long flags;
        int i = -1;
 
        spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
-               i = (*(romvec->pv_nbputchar))(c);
+               i = (*(romvec->pv_nbputchar))(*buf);
                break;
        case PROM_V2:
        case PROM_V3:
-               outc = c;
-               if( 
(*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 
0x1) == 1)
+               if 
((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
+                                                         buf, 0x1) == 1)
                        i = 0;
-               else
-                       i = -1;
                break;
        default:
-               i = -1;
                break;
        };
        restore_current();
@@ -79,17 +75,21 @@ static int prom_nbputchar(char c)
 }
 
 /* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_getchar(char *buf)
 {
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
+       while (1) {
+               int err = prom_nbgetchar(buf);
+               if (!err)
+                       break;
+       }
 }
 
 /* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
+void prom_putchar(const char *buf)
 {
-       while(prom_nbputchar(c) == -1) ;
+       while (1) {
+               int err = prom_nbputchar(buf);
+               if (!err)
+                       break;
+       }
 }
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index 33a8b27..a9a5754 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -18,41 +18,37 @@ extern int prom_stdin, prom_stdout;
 /* Non blocking get character from console input device, returns -1
  * if no input was taken.  This can be used for polling.
  */
-static int prom_nbgetchar(void)
+static int prom_nbgetchar(char *buf)
 {
        unsigned long args[7];
-       char inc;
 
        args[0] = (unsigned long) "read";
        args[1] = 3;
        args[2] = 1;
        args[3] = (unsigned int) prom_stdin;
-       args[4] = (unsigned long) &inc;
+       args[4] = (unsigned long) buf;
        args[5] = 1;
        args[6] = (unsigned long) -1;
 
        p1275_cmd_direct(args);
 
        if (args[6] == 1)
-               return inc;
+               return 0;
        return -1;
 }
 
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-static int prom_nbputchar(char c)
+static int prom_nbputchar(const char *buf)
 {
        unsigned long args[7];
-       char outc;
-       
-       outc = c;
 
        args[0] = (unsigned long) "write";
        args[1] = 3;
        args[2] = 1;
        args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) &outc;
+       args[4] = (unsigned long) buf;
        args[5] = 1;
        args[6] = (unsigned long) -1;
 
@@ -65,17 +61,21 @@ static int prom_nbputchar(char c)
 }
 
 /* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_getchar(char *buf)
 {
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
+       while (1) {
+               int err = prom_nbgetchar(buf);
+               if (!err)
+                       break;
+       }
 }
 
 /* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
+void prom_putchar(const char *buf)
 {
-       prom_nbputchar(c);
+       while (1) {
+               int err = prom_nbputchar(buf);
+               if (!err)
+                       break;
+       }
 }
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c
index ca86926..2403197 100644
--- a/arch/sparc/prom/printf.c
+++ b/arch/sparc/prom/printf.c
@@ -23,13 +23,14 @@ static char ppbuf[1024];
 
 void notrace prom_write(const char *buf, unsigned int n)
 {
-       char ch;
-
-       while (n != 0) {
-               --n;
-               if ((ch = *buf++) == '\n')
-                       prom_putchar('\r');
-               prom_putchar(ch);
+       while (n-- != 0) {
+               char ch = *buf;
+               if (ch == '\n') {
+                       char tmp = '\r';
+                       prom_putchar(&tmp);
+               }
+               prom_putchar(buf);
+               buf++;
        }
 }
 
-- 
1.7.3.4


>From 771babb4c614ecc81ee901527fbbfe61d45d3570 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 30 Nov 2010 14:53:05 -0800
Subject: [PATCH 09/10] sparc: Delete prom_*getchar().

[ Upstream commit 12c7a35ee6a1c605e740733f2cbd5b5079f09f0f ]

Completely unused.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/oplib_32.h |    5 ----
 arch/sparc/include/asm/oplib_64.h |    5 ----
 arch/sparc/prom/console_32.c      |   41 -------------------------------------
 arch/sparc/prom/console_64.c      |   32 ----------------------------
 4 files changed, 0 insertions(+), 83 deletions(-)

diff --git a/arch/sparc/include/asm/oplib_32.h 
b/arch/sparc/include/asm/oplib_32.h
index 4d708b7..3a2d3a6 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -102,11 +102,6 @@ extern int prom_getrev(void);
 /* Get the prom firmware revision. */
 extern int prom_getprev(void);
 
-/* Character operations to/from the console.... */
-
-/* Blocking get character from console. */
-extern void prom_getchar(char *buf);
-
 /* Blocking put character to console. */
 extern void prom_putchar(const char *buf);
 
diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index 891a00b..3636136 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -94,11 +94,6 @@ extern void prom_halt_power_off(void) __attribute__ 
((noreturn));
  */
 extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
 
-/* Character operations to/from the console.... */
-
-/* Blocking get character from console. */
-extern void prom_getchar(char *buf);
-
 /* Blocking put character to console. */
 extern void prom_putchar(const char *buf);
 
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c
index 69c16bb..157019e 100644
--- a/arch/sparc/prom/console_32.c
+++ b/arch/sparc/prom/console_32.c
@@ -16,37 +16,6 @@
 
 extern void restore_current(void);
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-static int prom_nbgetchar(char *buf)
-{
-       unsigned long flags;
-       int i = -1;
-
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               i = (*(romvec->pv_nbgetchar))();
-               if (i != -1) {
-                       *buf = i;
-                       i = 0;
-               }
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               if 
((*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin,
-                                                        buf, 0x1) == 1)
-                       i = 0;
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return i; /* Ugh, we could spin forever on unsupported proms ;( */
-}
-
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
@@ -74,16 +43,6 @@ static int prom_nbputchar(const char *buf)
        return i; /* Ugh, we could spin forever on unsupported proms ;( */
 }
 
-/* Blocking version of get character routine above. */
-void prom_getchar(char *buf)
-{
-       while (1) {
-               int err = prom_nbgetchar(buf);
-               if (!err)
-                       break;
-       }
-}
-
 /* Blocking version of put character routine above. */
 void prom_putchar(const char *buf)
 {
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index a9a5754..0da88d1 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -15,28 +15,6 @@
 
 extern int prom_stdin, prom_stdout;
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-static int prom_nbgetchar(char *buf)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "read";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdin;
-       args[4] = (unsigned long) buf;
-       args[5] = 1;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       if (args[6] == 1)
-               return 0;
-       return -1;
-}
-
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
@@ -60,16 +38,6 @@ static int prom_nbputchar(const char *buf)
                return -1;
 }
 
-/* Blocking version of get character routine above. */
-void prom_getchar(char *buf)
-{
-       while (1) {
-               int err = prom_nbgetchar(buf);
-               if (!err)
-                       break;
-       }
-}
-
 /* Blocking version of put character routine above. */
 void prom_putchar(const char *buf)
 {
-- 
1.7.3.4


>From 699a02e295c0ee4826731598611556935e0f2457 Mon Sep 17 00:00:00 2001
From: David S. Miller <[email protected]>
Date: Tue, 30 Nov 2010 20:15:58 -0800
Subject: [PATCH 10/10] sparc: Write to prom console using indirect buffer.

[ Upstream commit 595a251c0740785fd3c0d2156d78578c7479811e ]

sparc64 systems have a restriction in that passing in buffer
addressses above 4GB to prom calls is not reliable.

We end up violating this when we do prom console writes, because we
use an on-stack buffer to translate '\n' into '\r\n'.

So instead, do this translation into an intermediate buffer, which is
in the kernel image and thus below 4GB, then pass that to the PROM
console write calls.

On the 32-bit side we don't have to deal with any of these issues, so
the new prom_console_write_buf() uses the existing prom_nbputchar()
implementation.  However we can now mark those routines static.

Since the 64-bit side completely uses new code we can delete the
putchar bits as they are now completely unused.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/include/asm/oplib_32.h |    4 ++--
 arch/sparc/include/asm/oplib_64.h |    4 ++--
 arch/sparc/prom/console_32.c      |   14 ++++++++------
 arch/sparc/prom/console_64.c      |   27 +++++++++++++--------------
 arch/sparc/prom/printf.c          |   32 +++++++++++++++++++++++++++-----
 5 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/arch/sparc/include/asm/oplib_32.h 
b/arch/sparc/include/asm/oplib_32.h
index 3a2d3a6..618a5bd 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -102,8 +102,8 @@ extern int prom_getrev(void);
 /* Get the prom firmware revision. */
 extern int prom_getprev(void);
 
-/* Blocking put character to console. */
-extern void prom_putchar(const char *buf);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
diff --git a/arch/sparc/include/asm/oplib_64.h 
b/arch/sparc/include/asm/oplib_64.h
index 3636136..209463d 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -94,8 +94,8 @@ extern void prom_halt_power_off(void) __attribute__ 
((noreturn));
  */
 extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
 
-/* Blocking put character to console. */
-extern void prom_putchar(const char *buf);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c
index 157019e..4886310 100644
--- a/arch/sparc/prom/console_32.c
+++ b/arch/sparc/prom/console_32.c
@@ -43,12 +43,14 @@ static int prom_nbputchar(const char *buf)
        return i; /* Ugh, we could spin forever on unsupported proms ;( */
 }
 
-/* Blocking version of put character routine above. */
-void prom_putchar(const char *buf)
+void prom_console_write_buf(const char *buf, int len)
 {
-       while (1) {
-               int err = prom_nbputchar(buf);
-               if (!err)
-                       break;
+       while (len) {
+               int n = prom_nbputchar(buf);
+               if (n)
+                       continue;
+               len--;
+               buf++;
        }
 }
+
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index 0da88d1..ed39e75 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -15,35 +15,34 @@
 
 extern int prom_stdin, prom_stdout;
 
-/* Non blocking put character to console device, returns -1 if
- * unsuccessful.
- */
-static int prom_nbputchar(const char *buf)
+static int __prom_console_write_buf(const char *buf, int len)
 {
        unsigned long args[7];
+       int ret;
 
        args[0] = (unsigned long) "write";
        args[1] = 3;
        args[2] = 1;
        args[3] = (unsigned int) prom_stdout;
        args[4] = (unsigned long) buf;
-       args[5] = 1;
+       args[5] = (unsigned int) len;
        args[6] = (unsigned long) -1;
 
        p1275_cmd_direct(args);
 
-       if (args[6] == 1)
-               return 0;
-       else
+       ret = (int) args[6];
+       if (ret < 0)
                return -1;
+       return ret;
 }
 
-/* Blocking version of put character routine above. */
-void prom_putchar(const char *buf)
+void prom_console_write_buf(const char *buf, int len)
 {
-       while (1) {
-               int err = prom_nbputchar(buf);
-               if (!err)
-                       break;
+       while (len) {
+               int n = __prom_console_write_buf(buf, len);
+               if (n < 0)
+                       continue;
+               len -= n;
+               buf += len;
        }
 }
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c
index 2403197..d9682f0 100644
--- a/arch/sparc/prom/printf.c
+++ b/arch/sparc/prom/printf.c
@@ -15,23 +15,45 @@
 
 #include <linux/kernel.h>
 #include <linux/compiler.h>
+#include <linux/spinlock.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 
+#define CONSOLE_WRITE_BUF_SIZE 1024
+
 static char ppbuf[1024];
+static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
+static DEFINE_RAW_SPINLOCK(console_write_lock);
 
 void notrace prom_write(const char *buf, unsigned int n)
 {
+       unsigned int dest_len;
+       unsigned long flags;
+       char *dest;
+
+       dest = console_write_buf;
+       raw_spin_lock_irqsave(&console_write_lock, flags);
+
+       dest_len = 0;
        while (n-- != 0) {
-               char ch = *buf;
+               char ch = *buf++;
                if (ch == '\n') {
-                       char tmp = '\r';
-                       prom_putchar(&tmp);
+                       *dest++ = '\r';
+                       dest_len++;
+               }
+               *dest++ = ch;
+               dest_len++;
+               if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
+                       prom_console_write_buf(console_write_buf, dest_len);
+                       dest = console_write_buf;
+                       dest_len = 0;
                }
-               prom_putchar(buf);
-               buf++;
        }
+       if (dest_len)
+               prom_console_write_buf(console_write_buf, dest_len);
+
+       raw_spin_unlock_irqrestore(&console_write_lock, flags);
 }
 
 void notrace prom_printf(const char *fmt, ...)
-- 
1.7.3.4

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to