summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2021-06-09 22:59:13 +0200
committerVasily Gorbik <gor@linux.ibm.com>2021-06-18 16:41:22 +0200
commit0a9d947fbe3e89e44758e1b8bf0098e98b3ccd78 (patch)
tree368c0a5d137dccc5b21de4a18d57e0195d513a48 /arch
parent25130c1a9e99c7b10af6d542d62808476a0dff24 (diff)
downloadlinux-0a9d947fbe3e89e44758e1b8bf0098e98b3ccd78.tar.gz
s390/cpcmd: use register pair instead of register asm
Remove register asm usage from diag8_noresponse() since it wasn't
needed at all. There is no requirement for even/odd register pairs for
diag 0x8.

For diag_response() use register pairs to fulfill the rx+1 and ry+1
requirements as required if a response buffer is specified. Also
change the inline asm to return the condition code of the diagnose
instruction and do the conditional handling of response length
calculation in C.

Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kernel/cpcmd.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index 2da027359798..54efc279f54e 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -26,33 +26,35 @@ 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(
-		"	diag	%1,%0,0x8\n"
-		: "+d" (reg3) : "d" (reg2) : "cc");
-	return reg3;
+		"	diag	%[rx],%[ry],0x8\n"
+		: [ry] "+&d" (cmdlen)
+		: [rx] "d" ((addr_t) cpcmd_buf)
+		: "cc");
+	return cmdlen;
 }
 
 static int diag8_response(int cmdlen, char *response, int *rlen)
 {
-	unsigned long _cmdlen = cmdlen | 0x40000000L;
-	unsigned long _rlen = *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;
-	register unsigned long reg5 asm ("5") = _rlen;
+	union register_pair rx, ry;
+	int cc;
 
+	rx.even = (addr_t) cpcmd_buf;
+	rx.odd	= (addr_t) response;
+	ry.even = cmdlen | 0x40000000L;
+	ry.odd	= *rlen;
 	asm volatile(
-		"	diag	%2,%0,0x8\n"
-		"	brc	8,1f\n"
-		"	agr	%1,%4\n"
-		"1:\n"
-		: "+d" (reg4), "+d" (reg5)
-		: "d" (reg2), "d" (reg3), "d" (*rlen) : "cc");
-	*rlen = reg5;
-	return reg4;
+		"	diag	%[rx],%[ry],0x8\n"
+		"	ipm	%[cc]\n"
+		"	srl	%[cc],28\n"
+		: [cc] "=&d" (cc), [ry] "+&d" (ry.pair)
+		: [rx] "d" (rx.pair)
+		: "cc");
+	if (cc)
+		*rlen += ry.odd;
+	else
+		*rlen = ry.odd;
+	return ry.even;
 }
 
 /*