aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/char/sclp.c10
-rw-r--r--drivers/s390/char/sclp.h10
-rw-r--r--drivers/s390/char/sclp_cmd.c38
-rw-r--r--drivers/s390/kvm/kvm_virtio.c3
4 files changed, 50 insertions, 11 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 30f29a0020a1..3fcc000efc53 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -654,16 +654,6 @@ sclp_remove_processed(struct sccb_header *sccb)
654 654
655EXPORT_SYMBOL(sclp_remove_processed); 655EXPORT_SYMBOL(sclp_remove_processed);
656 656
657struct init_sccb {
658 struct sccb_header header;
659 u16 _reserved;
660 u16 mask_length;
661 sccb_mask_t receive_mask;
662 sccb_mask_t send_mask;
663 sccb_mask_t sclp_receive_mask;
664 sccb_mask_t sclp_send_mask;
665} __attribute__((packed));
666
667/* Prepare init mask request. Called while sclp_lock is locked. */ 657/* Prepare init mask request. Called while sclp_lock is locked. */
668static inline void 658static inline void
669__sclp_make_init_req(u32 receive_mask, u32 send_mask) 659__sclp_make_init_req(u32 receive_mask, u32 send_mask)
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 49a1bb52bc87..d7e97ae9ef6d 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -88,6 +88,16 @@ struct sccb_header {
88 u16 response_code; 88 u16 response_code;
89} __attribute__((packed)); 89} __attribute__((packed));
90 90
91struct init_sccb {
92 struct sccb_header header;
93 u16 _reserved;
94 u16 mask_length;
95 sccb_mask_t receive_mask;
96 sccb_mask_t send_mask;
97 sccb_mask_t sclp_receive_mask;
98 sccb_mask_t sclp_send_mask;
99} __attribute__((packed));
100
91extern u64 sclp_facilities; 101extern u64 sclp_facilities;
92#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) 102#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL)
93#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) 103#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 766cb7b19b40..71ea923c322d 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -48,6 +48,7 @@ struct read_info_sccb {
48 u8 _reserved5[4096 - 112]; /* 112-4095 */ 48 u8 _reserved5[4096 - 112]; /* 112-4095 */
49} __attribute__((packed, aligned(PAGE_SIZE))); 49} __attribute__((packed, aligned(PAGE_SIZE)));
50 50
51static struct init_sccb __initdata early_event_mask_sccb __aligned(PAGE_SIZE);
51static struct read_info_sccb __initdata early_read_info_sccb; 52static struct read_info_sccb __initdata early_read_info_sccb;
52static int __initdata early_read_info_sccb_valid; 53static int __initdata early_read_info_sccb_valid;
53 54
@@ -104,6 +105,19 @@ static void __init sclp_read_info_early(void)
104 } 105 }
105} 106}
106 107
108static void __init sclp_event_mask_early(void)
109{
110 struct init_sccb *sccb = &early_event_mask_sccb;
111 int rc;
112
113 do {
114 memset(sccb, 0, sizeof(*sccb));
115 sccb->header.length = sizeof(*sccb);
116 sccb->mask_length = sizeof(sccb_mask_t);
117 rc = sclp_cmd_sync_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb);
118 } while (rc == -EBUSY);
119}
120
107void __init sclp_facilities_detect(void) 121void __init sclp_facilities_detect(void)
108{ 122{
109 struct read_info_sccb *sccb; 123 struct read_info_sccb *sccb;
@@ -119,6 +133,30 @@ void __init sclp_facilities_detect(void)
119 rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; 133 rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
120 rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; 134 rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
121 rzm <<= 20; 135 rzm <<= 20;
136
137 sclp_event_mask_early();
138}
139
140bool __init sclp_has_linemode(void)
141{
142 struct init_sccb *sccb = &early_event_mask_sccb;
143
144 if (sccb->header.response_code != 0x20)
145 return 0;
146 if (sccb->sclp_send_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK))
147 return 1;
148 return 0;
149}
150
151bool __init sclp_has_vt220(void)
152{
153 struct init_sccb *sccb = &early_event_mask_sccb;
154
155 if (sccb->header.response_code != 0x20)
156 return 0;
157 if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
158 return 1;
159 return 0;
122} 160}
123 161
124unsigned long long sclp_get_rnmax(void) 162unsigned long long sclp_get_rnmax(void)
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index d74e9ae6dfb3..d3bdae49512f 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -25,6 +25,7 @@
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/kvm_para.h> 26#include <asm/kvm_para.h>
27#include <asm/kvm_virtio.h> 27#include <asm/kvm_virtio.h>
28#include <asm/sclp.h>
28#include <asm/setup.h> 29#include <asm/setup.h>
29#include <asm/irq.h> 30#include <asm/irq.h>
30 31
@@ -468,7 +469,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
468 469
469static int __init s390_virtio_console_init(void) 470static int __init s390_virtio_console_init(void)
470{ 471{
471 if (!MACHINE_IS_KVM) 472 if (sclp_has_vt220() || sclp_has_linemode())
472 return -ENODEV; 473 return -ENODEV;
473 return virtio_cons_early_init(early_put_chars); 474 return virtio_cons_early_init(early_put_chars);
474} 475}