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>
This commit is contained in:
Heiko Carstens 2021-06-09 22:59:13 +02:00 committed by Vasily Gorbik
parent 25130c1a9e
commit 0a9d947fbe

View File

@ -26,33 +26,35 @@ static char cpcmd_buf[241];
static int diag8_noresponse(int cmdlen) 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( asm volatile(
" diag %1,%0,0x8\n" " diag %[rx],%[ry],0x8\n"
: "+d" (reg3) : "d" (reg2) : "cc"); : [ry] "+&d" (cmdlen)
return reg3; : [rx] "d" ((addr_t) cpcmd_buf)
: "cc");
return cmdlen;
} }
static int diag8_response(int cmdlen, char *response, int *rlen) static int diag8_response(int cmdlen, char *response, int *rlen)
{ {
unsigned long _cmdlen = cmdlen | 0x40000000L; union register_pair rx, ry;
unsigned long _rlen = *rlen; int cc;
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;
rx.even = (addr_t) cpcmd_buf;
rx.odd = (addr_t) response;
ry.even = cmdlen | 0x40000000L;
ry.odd = *rlen;
asm volatile( asm volatile(
" diag %2,%0,0x8\n" " diag %[rx],%[ry],0x8\n"
" brc 8,1f\n" " ipm %[cc]\n"
" agr %1,%4\n" " srl %[cc],28\n"
"1:\n" : [cc] "=&d" (cc), [ry] "+&d" (ry.pair)
: "+d" (reg4), "+d" (reg5) : [rx] "d" (rx.pair)
: "d" (reg2), "d" (reg3), "d" (*rlen) : "cc"); : "cc");
*rlen = reg5; if (cc)
return reg4; *rlen += ry.odd;
else
*rlen = ry.odd;
return ry.even;
} }
/* /*