summaryrefslogtreecommitdiff
path: root/drivers/s390/char/sclp.c
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2013-06-06 11:52:08 +0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 23:10:13 +0400
commitd475f942b1dd6a897dac3ad4ed98d6994b275378 (patch)
tree43f599275ef7ac5350ea25f8f1eeb2690d6dc4e4 /drivers/s390/char/sclp.c
parente9a8f32a98a6099b009ea7da4f299bb5427db126 (diff)
downloadlinux-d475f942b1dd6a897dac3ad4ed98d6994b275378.tar.xz
s390/sclp: Add SCLP character device driver
Add a character misc device "sclp_ctl" that allows to run SCCBs from user space using the SCLP_CTL_SCCB ioctl. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/sclp.c')
-rw-r--r--drivers/s390/char/sclp.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index a77febeead1f..97319d692b04 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -148,14 +148,19 @@ static int sclp_init(void);
int
sclp_service_call(sclp_cmdw_t command, void *sccb)
{
- int cc;
+ int cc = 4; /* Initialize for program check handling */
asm volatile(
- " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
- " ipm %0\n"
- " srl %0,28"
- : "=&d" (cc) : "d" (command), "a" (__pa(sccb))
+ "0: .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
+ "1: ipm %0\n"
+ " srl %0,28\n"
+ "2:\n"
+ EX_TABLE(0b, 2b)
+ EX_TABLE(1b, 2b)
+ : "+&d" (cc) : "d" (command), "a" (__pa(sccb))
: "cc", "memory");
+ if (cc == 4)
+ return -EINVAL;
if (cc == 3)
return -EIO;
if (cc == 2)