Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=a004fb0c33539ae90f25573505be6a116a76e639
Commit:     a004fb0c33539ae90f25573505be6a116a76e639
Parent:     e39394b84156bc0822785e379977fe75a5662aad
Author:     Heiko Carstens <[EMAIL PROTECTED]>
AuthorDate: Fri Oct 12 16:11:46 2007 +0200
Committer:  Martin Schwidefsky <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 16:13:09 2007 +0200

    [S390] cpcmd: fix inline assembly usage.
    
    After assigning values to specific registers memset was called. This
    may clobber the contents of the used registers.
    To solve this extract the two used inline assemblies into small
    functions that don't call any functions.
    
    Signed-off-by: Heiko Carstens <[EMAIL PROTECTED]>
    Signed-off-by: Martin Schwidefsky <[EMAIL PROTECTED]>
---
 arch/s390/kernel/cpcmd.c |  100 +++++++++++++++++++++++++---------------------
 1 files changed, 55 insertions(+), 45 deletions(-)

diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index 6c89f30..d8c1131 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/cpcmd.c
  *
  *  S390 version
- *    Copyright (C) 1999,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright IBM Corp. 1999,2007
  *    Author(s): Martin Schwidefsky ([EMAIL PROTECTED]),
  *               Christian Borntraeger ([EMAIL PROTECTED]),
  */
@@ -21,6 +21,49 @@
 static DEFINE_SPINLOCK(cpcmd_lock);
 static char cpcmd_buf[241];
 
+static int diag8_noresponse(int cmdlen)
+{
+       register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
+       register unsigned long reg3 asm ("3") = cmdlen;
+
+       asm volatile(
+#ifndef CONFIG_64BIT
+               "       diag    %1,%0,0x8\n"
+#else /* CONFIG_64BIT */
+               "       sam31\n"
+               "       diag    %1,%0,0x8\n"
+               "       sam64\n"
+#endif /* CONFIG_64BIT */
+               : "+d" (reg3) : "d" (reg2) : "cc");
+       return reg3;
+}
+
+static int diag8_response(int cmdlen, char *response, int *rlen)
+{
+       register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
+       register unsigned long reg3 asm ("3") = (addr_t) response;
+       register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
+       register unsigned long reg5 asm ("5") = *rlen;
+
+       asm volatile(
+#ifndef CONFIG_64BIT
+               "       diag    %2,%0,0x8\n"
+               "       brc     8,1f\n"
+               "       ar      %1,%4\n"
+#else /* CONFIG_64BIT */
+               "       sam31\n"
+               "       diag    %2,%0,0x8\n"
+               "       sam64\n"
+               "       brc     8,1f\n"
+               "       agr     %1,%4\n"
+#endif /* CONFIG_64BIT */
+               "1:\n"
+               : "+d" (reg4), "+d" (reg5)
+               : "d" (reg2), "d" (reg3), "d" (*rlen) : "cc");
+       *rlen = reg5;
+       return reg4;
+}
+
 /*
  * __cpcmd has some restrictions over cpcmd
  *  - the response buffer must reside below 2GB (if any)
@@ -28,59 +71,27 @@ static char cpcmd_buf[241];
  */
 int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
-       unsigned cmdlen;
-       int return_code, return_len;
+       int cmdlen;
+       int rc;
+       int response_len;
 
        cmdlen = strlen(cmd);
        BUG_ON(cmdlen > 240);
        memcpy(cpcmd_buf, cmd, cmdlen);
        ASCEBC(cpcmd_buf, cmdlen);
 
-       if (response != NULL && rlen > 0) {
-               register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
-               register unsigned long reg3 asm ("3") = (addr_t) response;
-               register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
-               register unsigned long reg5 asm ("5") = rlen;
-
+       if (response) {
                memset(response, 0, rlen);
-               asm volatile(
-#ifndef CONFIG_64BIT
-                       "       diag    %2,%0,0x8\n"
-                       "       brc     8,1f\n"
-                       "       ar      %1,%4\n"
-#else /* CONFIG_64BIT */
-                       "       sam31\n"
-                       "       diag    %2,%0,0x8\n"
-                       "       sam64\n"
-                       "       brc     8,1f\n"
-                       "       agr     %1,%4\n"
-#endif /* CONFIG_64BIT */
-                       "1:\n"
-                       : "+d" (reg4), "+d" (reg5)
-                       : "d" (reg2), "d" (reg3), "d" (rlen) : "cc");
-               return_code = (int) reg4;
-               return_len = (int) reg5;
-                EBCASC(response, rlen);
+               response_len = rlen;
+               rc = diag8_response(cmdlen, response, &rlen);
+               EBCASC(response, response_len);
         } else {
-               register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
-               register unsigned long reg3 asm ("3") = cmdlen;
-               return_len = 0;
-               asm volatile(
-#ifndef CONFIG_64BIT
-                       "       diag    %1,%0,0x8\n"
-#else /* CONFIG_64BIT */
-                       "       sam31\n"
-                       "       diag    %1,%0,0x8\n"
-                       "       sam64\n"
-#endif /* CONFIG_64BIT */
-                       : "+d" (reg3) : "d" (reg2) : "cc");
-               return_code = (int) reg3;
+               rc = diag8_noresponse(cmdlen);
         }
-       if (response_code != NULL)
-               *response_code = return_code;
-       return return_len;
+       if (response_code)
+               *response_code = rc;
+       return rlen;
 }
-
 EXPORT_SYMBOL(__cpcmd);
 
 int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
@@ -109,5 +120,4 @@ int cpcmd(const char *cmd, char *response, int rlen, int 
*response_code)
        }
        return len;
 }
-
 EXPORT_SYMBOL(cpcmd);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to