summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2016-03-01 12:58:06 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-03-16 08:42:58 -0700
commitdc5a60756e536494af2fb4d044cd65a765eeddae (patch)
tree506615a8ed796879f82ce568ced7d2a6fcfa2cc1
parent5833fac3b88d39b39402309399e8b0aaa54e5f75 (diff)
downloadlinux-stable-dc5a60756e536494af2fb4d044cd65a765eeddae.tar.gz
linux-stable-dc5a60756e536494af2fb4d044cd65a765eeddae.tar.bz2
linux-stable-dc5a60756e536494af2fb4d044cd65a765eeddae.zip
s390/dasd: fix diag 0x250 inline assembly
commit ce0c12b633846a47e103842149a5bac2e5d261ec upstream. git commit 1ec2772e0c3c ("s390/diag: add a statistic for diagnose calls") added function calls to gather diagnose statistics. In case of the dasd diag driver the function call was added between a register asm statement which initialized register r2 and the inline assembly itself. The function call clobbers the contents of register r2 and therefore the diag 0x250 call behaves in a more or less random way. Fix this by extracting the function call into a separate function like we do everywhere else. Fixes: 1ec2772e0c3c ("s390/diag: add a statistic for diagnose calls") Reported-and-tested-by: Stefan Haberland <sth@linux.vnet.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/s390/block/dasd_diag.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index cb61f300f8b5..277b5c8c825c 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -67,7 +67,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
* and function code cmd.
* In case of an exception return 3. Otherwise return result of bitwise OR of
* resulting condition code and DIAG return code. */
-static inline int dia250(void *iob, int cmd)
+static inline int __dia250(void *iob, int cmd)
{
register unsigned long reg2 asm ("2") = (unsigned long) iob;
typedef union {
@@ -77,7 +77,6 @@ static inline int dia250(void *iob, int cmd)
int rc;
rc = 3;
- diag_stat_inc(DIAG_STAT_X250);
asm volatile(
" diag 2,%2,0x250\n"
"0: ipm %0\n"
@@ -91,6 +90,12 @@ static inline int dia250(void *iob, int cmd)
return rc;
}
+static inline int dia250(void *iob, int cmd)
+{
+ diag_stat_inc(DIAG_STAT_X250);
+ return __dia250(iob, cmd);
+}
+
/* Initialize block I/O to DIAG device using the specified blocksize and
* block offset. On success, return zero and set end_block to contain the
* number of blocks on the device minus the specified offset. Return non-zero