diff options
author | Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> | 2018-01-23 18:50:43 +0300 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-02-22 17:31:24 +0300 |
commit | 0b0d1173d8aef75e821c0cceedb0e8178834ec1b (patch) | |
tree | eceecae57a15d49a22440434cc3aeb0ed0e97831 /drivers/s390/char/sclp.c | |
parent | b843563518c1e06521c446b9a043b7d352df02e0 (diff) | |
download | linux-0b0d1173d8aef75e821c0cceedb0e8178834ec1b.tar.xz |
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.c | 23 |
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); |