Merge branch 'master' of git://oak/home/sfr/kernels/iseries/work
[sfrench/cifs-2.6.git] / arch / s390 / kernel / cpcmd.c
index d47fecb42cc5f24d5e2aeda18424fb60f37ffb25..1eae74e72f9525f91a11f56a012f815582157500 100644 (file)
@@ -25,11 +25,8 @@ static char cpcmd_buf[241];
  */
 int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
-       const int mask = 0x40000000L;
-       unsigned long flags;
-       int return_code;
-       int return_len;
-       int cmdlen;
+       unsigned long flags, cmdlen;
+       int return_code, return_len;
 
        spin_lock_irqsave(&cpcmd_lock, flags);
        cmdlen = strlen(cmd);
@@ -38,64 +35,44 @@ int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
        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;
+
                memset(response, 0, rlen);
-#ifndef CONFIG_ARCH_S390X
-               asm volatile (  "lra    2,0(%2)\n"
-                               "lr     4,%3\n"
-                               "o      4,%6\n"
-                               "lra    3,0(%4)\n"
-                               "lr     5,%5\n"
-                               "diag   2,4,0x8\n"
-                               "brc    8, 1f\n"
-                               "ar     5, %5\n"
-                               "1: \n"
-                               "lr     %0,4\n"
-                               "lr     %1,5\n"
-                               : "=d" (return_code), "=d" (return_len)
-                               : "a" (cpcmd_buf), "d" (cmdlen),
-                               "a" (response), "d" (rlen), "m" (mask)
-                               : "cc", "2", "3", "4", "5" );
-#else /* CONFIG_ARCH_S390X */
-                asm volatile ( "lrag   2,0(%2)\n"
-                               "lgr    4,%3\n"
-                               "o      4,%6\n"
-                               "lrag   3,0(%4)\n"
-                               "lgr    5,%5\n"
-                               "sam31\n"
-                               "diag   2,4,0x8\n"
-                               "sam64\n"
-                               "brc    8, 1f\n"
-                               "agr    5, %5\n"
-                               "1: \n"
-                               "lgr    %0,4\n"
-                               "lgr    %1,5\n"
-                               : "=d" (return_code), "=d" (return_len)
-                               : "a" (cpcmd_buf), "d" (cmdlen),
-                               "a" (response), "d" (rlen), "m" (mask)
-                               : "cc", "2", "3", "4", "5" );
-#endif /* CONFIG_ARCH_S390X */
+               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);
         } else {
+               register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
+               register unsigned long reg3 asm ("3") = cmdlen;
                return_len = 0;
-#ifndef CONFIG_ARCH_S390X
-                asm volatile ( "lra    2,0(%1)\n"
-                               "lr     3,%2\n"
-                               "diag   2,3,0x8\n"
-                               "lr     %0,3\n"
-                               : "=d" (return_code)
-                               : "a" (cpcmd_buf), "d" (cmdlen)
-                               : "2", "3"  );
-#else /* CONFIG_ARCH_S390X */
-                asm volatile ( "lrag   2,0(%1)\n"
-                               "lgr    3,%2\n"
-                               "sam31\n"
-                               "diag   2,3,0x8\n"
-                               "sam64\n"
-                               "lgr    %0,3\n"
-                               : "=d" (return_code)
-                               : "a" (cpcmd_buf), "d" (cmdlen)
-                               : "2", "3" );
-#endif /* CONFIG_ARCH_S390X */
+               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;
         }
        spin_unlock_irqrestore(&cpcmd_lock, flags);
        if (response_code != NULL)
@@ -105,7 +82,7 @@ int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 
 EXPORT_SYMBOL(__cpcmd);
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
        char *lowbuf;
@@ -129,4 +106,4 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 }
 
 EXPORT_SYMBOL(cpcmd);
-#endif         /* CONFIG_ARCH_S390X */
+#endif         /* CONFIG_64BIT */