diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2017-01-24 15:58:52 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-02-08 14:13:19 +0100 |
commit | d5ab7a34f9bbad54f89b812e6b0d2d898f9433db (patch) | |
tree | 3aa685926bc40dc71fb3482b7766705ca451fa3a /drivers/s390/char/sclp.h | |
parent | s390/sclp: disable early sclp code as soon as the base sclp driver is active (diff) | |
download | linux-d5ab7a34f9bbad54f89b812e6b0d2d898f9433db.tar.xz linux-d5ab7a34f9bbad54f89b812e6b0d2d898f9433db.zip |
s390/sclp: make early sclp code readable
This patch
- unifies the old sclp early code and the sclp early printk code, so
they can use common functions
- makes sure all sclp early functions and variables have the same
"sclp_early" prefix
- converts the sclp early printk code into readable code by using
existing data structures instead of hard coded magic arrays
- splits the early sclp code into two files: sclp_early.c and
sclp_early_core.c. The core file contains everything that is
required by the kernel decompressor and may not call functions not
contained within the core file. Otherwise the result would be a
link error.
- changes interrupt handling to be completely synchronous. The old
early sclp code had a small window which allowed to receive several
interrupts instead of exactly the single expected interrupt. This
did hide a subtle potential bug, which is fixed with this large
rework.
- contains a couple of small cleanups.
Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/sclp.h')
-rw-r--r-- | drivers/s390/char/sclp.h | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index 0c1fa376df9e..78d5f542d979 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -204,7 +204,6 @@ void sclp_unregister(struct sclp_register *reg); int sclp_remove_processed(struct sccb_header *sccb); int sclp_deactivate(void); int sclp_reactivate(void); -int sclp_service_call(sclp_cmdw_t command, void *sccb); int sclp_sync_request(sclp_cmdw_t command, void *sccb); int sclp_sync_request_timeout(sclp_cmdw_t command, void *sccb, int timeout); @@ -222,8 +221,41 @@ extern int sclp_console_pages; extern int sclp_console_drop; extern unsigned long sclp_console_full; +extern char sclp_early_sccb[PAGE_SIZE]; + +void sclp_early_wait_irq(void); +int sclp_early_cmd_sync(sclp_cmdw_t cmd, void *sccb); +int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb); +unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb); +int sclp_early_set_event_mask(struct init_sccb *sccb, + unsigned long receive_mask, + unsigned long send_mask); + /* useful inlines */ +/* Perform service call. Return 0 on success, non-zero otherwise. */ +static inline int sclp_service_call(sclp_cmdw_t command, void *sccb) +{ + int cc = 4; /* Initialize for program check handling */ + + asm volatile( + "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" ((unsigned long)sccb) + : "cc", "memory"); + if (cc == 4) + return -EINVAL; + if (cc == 3) + return -EIO; + if (cc == 2) + return -EBUSY; + return 0; +} + /* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */ /* translate single character from ASCII to EBCDIC */ static inline unsigned char |