s390/sclp_early: Add function to detect sclp console capabilities
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Thu, 5 Dec 2013 18:28:39 +0000 (19:28 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 16 Dec 2013 13:37:49 +0000 (14:37 +0100)
Add SCLP console detect functions to encapsulate detection of SCLP console
capabilities, for example, VT220 support.  Reuse the sclp_send/receive masks
that were stored by the most recent sclp_set_event_mask() call to prevent
unnecessary SCLP calls.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/sclp.h
drivers/s390/char/sclp_early.c

index 2f390956c7c1c930722320956a54d1e65ada5673..220e171413f857210012d7a09f07dfb904c21a10 100644 (file)
@@ -52,8 +52,8 @@ int sclp_chp_configure(struct chp_id chpid);
 int sclp_chp_deconfigure(struct chp_id chpid);
 int sclp_chp_read_info(struct sclp_chp_info *info);
 void sclp_get_ipl_info(struct sclp_ipl_info *info);
-bool sclp_has_linemode(void);
-bool sclp_has_vt220(void);
+bool __init sclp_has_linemode(void);
+bool __init sclp_has_vt220(void);
 int sclp_pci_configure(u32 fid);
 int sclp_pci_deconfigure(u32 fid);
 int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode);
index 1af3555c096d3f27a6948d43d707443d6ccb9309..82f2c389b4d1f51e882de45cd5e0fadfa3405f3e 100644 (file)
@@ -36,6 +36,8 @@ struct read_info_sccb {
 } __packed __aligned(PAGE_SIZE);
 
 static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
+static unsigned int sclp_con_has_vt220 __initdata;
+static unsigned int sclp_con_has_linemode __initdata;
 static unsigned long sclp_hsa_size;
 static struct sclp_ipl_info sclp_ipl_info;
 
@@ -109,26 +111,12 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
 
 bool __init sclp_has_linemode(void)
 {
-       struct init_sccb *sccb = (void *) &sccb_early;
-
-       if (sccb->header.response_code != 0x20)
-               return 0;
-       if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
-               return 0;
-       if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
-               return 0;
-       return 1;
+       return !!sclp_con_has_linemode;
 }
 
 bool __init sclp_has_vt220(void)
 {
-       struct init_sccb *sccb = (void *) &sccb_early;
-
-       if (sccb->header.response_code != 0x20)
-               return 0;
-       if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
-               return 1;
-       return 0;
+       return !!sclp_con_has_vt220;
 }
 
 unsigned long long sclp_get_rnmax(void)
@@ -240,11 +228,37 @@ out:
        sclp_hsa_size = size;
 }
 
+static unsigned int __init sclp_con_check_linemode(struct init_sccb *sccb)
+{
+       if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
+               return 0;
+       if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
+               return 0;
+       return 1;
+}
+
+static void __init sclp_console_detect(struct init_sccb *sccb)
+{
+       if (sccb->header.response_code != 0x20)
+               return;
+
+       if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
+               sclp_con_has_vt220 = 1;
+
+       if (sclp_con_check_linemode(sccb))
+               sclp_con_has_linemode = 1;
+}
+
 void __init sclp_early_detect(void)
 {
        void *sccb = &sccb_early;
 
        sclp_facilities_detect(sccb);
        sclp_hsa_size_detect(sccb);
+
+       /* Turn off SCLP event notifications.  Also save remote masks in the
+        * sccb.  These are sufficient to detect sclp console capabilities.
+        */
        sclp_set_event_mask(sccb, 0, 0);
+       sclp_console_detect(sccb);
 }