aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390/char/sclp.c
diff options
context:
space:
mode:
authorGravatar Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> 2018-01-23 16:50:43 +0100
committerGravatar Martin Schwidefsky <schwidefsky@de.ibm.com> 2018-02-22 15:31:24 +0100
commit0b0d1173d8aef75e821c0cceedb0e8178834ec1b (patch)
treeeceecae57a15d49a22440434cc3aeb0ed0e97831 /drivers/s390/char/sclp.c
parents390/sclp: generic event mask accessors (diff)
downloadlinux-0b0d1173d8aef75e821c0cceedb0e8178834ec1b.tar.gz
linux-0b0d1173d8aef75e821c0cceedb0e8178834ec1b.tar.bz2
linux-0b0d1173d8aef75e821c0cceedb0e8178834ec1b.zip
s390/sclp: 32 bit event mask compatibility mode
Qemu before version 2.11 does not implement the architecture correctly, and does not allow for a mask size of size different than 4. This patch introduces a compatibility mode for such systems, forcing the mask sizes to 4. Since the mask size is currently still 4 anyway, this patch should have no impact whatsoever by itself, but it will be needed when the mask size is increased to 64 bits in the next patch. Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Claudio Imbrenda <imbrenda@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.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 59e3219ce5c9..e9aa71cdfc44 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -765,7 +765,10 @@ __sclp_make_init_req(sccb_mask_t receive_mask, sccb_mask_t send_mask)
sclp_init_req.callback_data = NULL;
sclp_init_req.sccb = sccb;
sccb->header.length = sizeof(*sccb);
- sccb->mask_length = sizeof(sccb_mask_t);
+ if (sclp_mask_compat_mode)
+ sccb->mask_length = SCLP_MASK_SIZE_COMPAT;
+ else
+ sccb->mask_length = sizeof(sccb_mask_t);
sccb_set_recv_mask(sccb, receive_mask);
sccb_set_send_mask(sccb, send_mask);
sccb_set_sclp_recv_mask(sccb, 0);
@@ -977,12 +980,18 @@ sclp_check_interface(void)
irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
spin_lock_irqsave(&sclp_lock, flags);
del_timer(&sclp_request_timer);
- if (sclp_init_req.status == SCLP_REQ_DONE &&
- sccb->header.response_code == 0x20) {
- rc = 0;
- break;
- } else
- rc = -EBUSY;
+ rc = -EBUSY;
+ if (sclp_init_req.status == SCLP_REQ_DONE) {
+ if (sccb->header.response_code == 0x20) {
+ rc = 0;
+ break;
+ } else if (sccb->header.response_code == 0x74f0) {
+ if (!sclp_mask_compat_mode) {
+ sclp_mask_compat_mode = true;
+ retry = 0;
+ }
+ }
+ }
}
unregister_external_irq(EXT_IRQ_SERVICE_SIG, sclp_check_handler);
spin_unlock_irqrestore(&sclp_lock, flags);