diff options
author | Heinz Graalfs <graalfs@linux.vnet.ibm.com> | 2012-06-11 10:06:59 -0400 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2012-06-13 19:53:45 -0400 |
commit | cd1834591fe9564720ac4b0193bf1c790fe89f0d (patch) | |
tree | d705284edf49d5054f6558db3c1f827179984bc4 | |
parent | 61bde82caee95426bf1ad53fefc8dc691b8ba37c (diff) |
KVM: s390: Perform early event mask processing during boot
For processing under KVM it is required to detect
the actual SCLP console type in order to set it as
preferred console.
Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Acked-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | arch/s390/include/asm/sclp.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 12 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 10 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 10 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 38 | ||||
-rw-r--r-- | drivers/s390/kvm/kvm_virtio.c | 3 |
6 files changed, 61 insertions, 14 deletions
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index bf238c55740b..173f07aaeb2b 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h | |||
@@ -55,5 +55,7 @@ int sclp_chp_configure(struct chp_id chpid); | |||
55 | int sclp_chp_deconfigure(struct chp_id chpid); | 55 | int sclp_chp_deconfigure(struct chp_id chpid); |
56 | int sclp_chp_read_info(struct sclp_chp_info *info); | 56 | int sclp_chp_read_info(struct sclp_chp_info *info); |
57 | void sclp_get_ipl_info(struct sclp_ipl_info *info); | 57 | void sclp_get_ipl_info(struct sclp_ipl_info *info); |
58 | bool sclp_has_linemode(void); | ||
59 | bool sclp_has_vt220(void); | ||
58 | 60 | ||
59 | #endif /* _ASM_S390_SCLP_H */ | 61 | #endif /* _ASM_S390_SCLP_H */ |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 489d1d8d96b0..e86bca6f975c 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <asm/kvm_virtio.h> | 63 | #include <asm/kvm_virtio.h> |
64 | #include <asm/diag.h> | 64 | #include <asm/diag.h> |
65 | #include <asm/os_info.h> | 65 | #include <asm/os_info.h> |
66 | #include <asm/sclp.h> | ||
66 | #include "entry.h" | 67 | #include "entry.h" |
67 | 68 | ||
68 | long psw_kernel_bits = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY | | 69 | long psw_kernel_bits = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY | |
@@ -138,9 +139,14 @@ __setup("condev=", condev_setup); | |||
138 | 139 | ||
139 | static void __init set_preferred_console(void) | 140 | static void __init set_preferred_console(void) |
140 | { | 141 | { |
141 | if (MACHINE_IS_KVM) | 142 | if (MACHINE_IS_KVM) { |
142 | add_preferred_console("hvc", 0, NULL); | 143 | if (sclp_has_vt220()) |
143 | else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) | 144 | add_preferred_console("ttyS", 1, NULL); |
145 | else if (sclp_has_linemode()) | ||
146 | add_preferred_console("ttyS", 0, NULL); | ||
147 | else | ||
148 | add_preferred_console("hvc", 0, NULL); | ||
149 | } else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) | ||
144 | add_preferred_console("ttyS", 0, NULL); | 150 | add_preferred_console("ttyS", 0, NULL); |
145 | else if (CONSOLE_IS_3270) | 151 | else if (CONSOLE_IS_3270) |
146 | add_preferred_console("tty3270", 0, NULL); | 152 | add_preferred_console("tty3270", 0, NULL); |
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 | ||
655 | EXPORT_SYMBOL(sclp_remove_processed); | 655 | EXPORT_SYMBOL(sclp_remove_processed); |
656 | 656 | ||
657 | struct 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. */ |
668 | static inline void | 658 | static 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 | ||
91 | struct 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 | |||
91 | extern u64 sclp_facilities; | 101 | extern 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 | ||
51 | static struct init_sccb __initdata early_event_mask_sccb __aligned(PAGE_SIZE); | ||
51 | static struct read_info_sccb __initdata early_read_info_sccb; | 52 | static struct read_info_sccb __initdata early_read_info_sccb; |
52 | static int __initdata early_read_info_sccb_valid; | 53 | static 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 | ||
108 | static 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 | |||
107 | void __init sclp_facilities_detect(void) | 121 | void __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 | |||
140 | bool __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 | |||
151 | bool __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 | ||
124 | unsigned long long sclp_get_rnmax(void) | 162 | unsigned 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 | ||
469 | static int __init s390_virtio_console_init(void) | 470 | static 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 | } |