Commit b8435635 authored by Claudio Imbrenda's avatar Claudio Imbrenda Committed by Martin Schwidefsky

s390/sclp: generic event mask accessors

Switch the layout of the event masks to be a generic buffer, and
implement accessors to retrieve the values of the masks.

This will be needed in the next patches, where we will eventually switch
the mask size to 64 bits.
Reviewed-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarClaudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 0ee5f8dc
...@@ -618,9 +618,12 @@ struct sclp_statechangebuf { ...@@ -618,9 +618,12 @@ struct sclp_statechangebuf {
u16 _zeros : 12; u16 _zeros : 12;
u16 mask_length; u16 mask_length;
u64 sclp_active_facility_mask; u64 sclp_active_facility_mask;
sccb_mask_t sclp_receive_mask; u8 masks[2 * 1021 + 4]; /* variable length */
sccb_mask_t sclp_send_mask; /*
u32 read_data_function_mask; * u8 sclp_receive_mask[mask_length];
* u8 sclp_send_mask[mask_length];
* u32 read_data_function_mask;
*/
} __attribute__((packed)); } __attribute__((packed));
...@@ -631,14 +634,14 @@ sclp_state_change_cb(struct evbuf_header *evbuf) ...@@ -631,14 +634,14 @@ sclp_state_change_cb(struct evbuf_header *evbuf)
unsigned long flags; unsigned long flags;
struct sclp_statechangebuf *scbuf; struct sclp_statechangebuf *scbuf;
BUILD_BUG_ON(sizeof(struct sclp_statechangebuf) > PAGE_SIZE);
scbuf = (struct sclp_statechangebuf *) evbuf; scbuf = (struct sclp_statechangebuf *) evbuf;
if (scbuf->mask_length != sizeof(sccb_mask_t))
return;
spin_lock_irqsave(&sclp_lock, flags); spin_lock_irqsave(&sclp_lock, flags);
if (scbuf->validity_sclp_receive_mask) if (scbuf->validity_sclp_receive_mask)
sclp_receive_mask = scbuf->sclp_receive_mask; sclp_receive_mask = sccb_get_recv_mask(scbuf);
if (scbuf->validity_sclp_send_mask) if (scbuf->validity_sclp_send_mask)
sclp_send_mask = scbuf->sclp_send_mask; sclp_send_mask = sccb_get_send_mask(scbuf);
spin_unlock_irqrestore(&sclp_lock, flags); spin_unlock_irqrestore(&sclp_lock, flags);
if (scbuf->validity_sclp_active_facility_mask) if (scbuf->validity_sclp_active_facility_mask)
sclp.facilities = scbuf->sclp_active_facility_mask; sclp.facilities = scbuf->sclp_active_facility_mask;
...@@ -763,10 +766,10 @@ __sclp_make_init_req(sccb_mask_t receive_mask, sccb_mask_t send_mask) ...@@ -763,10 +766,10 @@ __sclp_make_init_req(sccb_mask_t receive_mask, sccb_mask_t send_mask)
sclp_init_req.sccb = sccb; sclp_init_req.sccb = sccb;
sccb->header.length = sizeof(*sccb); sccb->header.length = sizeof(*sccb);
sccb->mask_length = sizeof(sccb_mask_t); sccb->mask_length = sizeof(sccb_mask_t);
sccb->receive_mask = receive_mask; sccb_set_recv_mask(sccb, receive_mask);
sccb->send_mask = send_mask; sccb_set_send_mask(sccb, send_mask);
sccb->sclp_receive_mask = 0; sccb_set_sclp_recv_mask(sccb, 0);
sccb->sclp_send_mask = 0; sccb_set_sclp_send_mask(sccb, 0);
} }
/* Start init mask request. If calculate is non-zero, calculate the mask as /* Start init mask request. If calculate is non-zero, calculate the mask as
...@@ -822,8 +825,8 @@ sclp_init_mask(int calculate) ...@@ -822,8 +825,8 @@ sclp_init_mask(int calculate)
sccb->header.response_code == 0x20) { sccb->header.response_code == 0x20) {
/* Successful request */ /* Successful request */
if (calculate) { if (calculate) {
sclp_receive_mask = sccb->sclp_receive_mask; sclp_receive_mask = sccb_get_sclp_recv_mask(sccb);
sclp_send_mask = sccb->sclp_send_mask; sclp_send_mask = sccb_get_sclp_send_mask(sccb);
} else { } else {
sclp_receive_mask = 0; sclp_receive_mask = 0;
sclp_send_mask = 0; sclp_send_mask = 0;
......
...@@ -100,12 +100,51 @@ struct init_sccb { ...@@ -100,12 +100,51 @@ struct init_sccb {
struct sccb_header header; struct sccb_header header;
u16 _reserved; u16 _reserved;
u16 mask_length; u16 mask_length;
sccb_mask_t receive_mask; u8 masks[4 * 1021]; /* variable length */
sccb_mask_t send_mask; /*
sccb_mask_t sclp_receive_mask; * u8 receive_mask[mask_length];
sccb_mask_t sclp_send_mask; * u8 send_mask[mask_length];
* u8 sclp_receive_mask[mask_length];
* u8 sclp_send_mask[mask_length];
*/
} __attribute__((packed)); } __attribute__((packed));
static inline sccb_mask_t sccb_get_mask(u8 *masks, size_t len, int i)
{
sccb_mask_t res = 0;
memcpy(&res, masks + i * len, min(sizeof(res), len));
return res;
}
static inline void sccb_set_mask(u8 *masks, size_t len, int i, sccb_mask_t val)
{
memset(masks + i * len, 0, len);
memcpy(masks + i * len, &val, min(sizeof(val), len));
}
#define sccb_get_generic_mask(sccb, i) \
({ \
__typeof__(sccb) __sccb = sccb; \
\
sccb_get_mask(__sccb->masks, __sccb->mask_length, i); \
})
#define sccb_get_recv_mask(sccb) sccb_get_generic_mask(sccb, 0)
#define sccb_get_send_mask(sccb) sccb_get_generic_mask(sccb, 1)
#define sccb_get_sclp_recv_mask(sccb) sccb_get_generic_mask(sccb, 2)
#define sccb_get_sclp_send_mask(sccb) sccb_get_generic_mask(sccb, 3)
#define sccb_set_generic_mask(sccb, i, val) \
({ \
__typeof__(sccb) __sccb = sccb; \
\
sccb_set_mask(__sccb->masks, __sccb->mask_length, i, val); \
})
#define sccb_set_recv_mask(sccb, val) sccb_set_generic_mask(sccb, 0, val)
#define sccb_set_send_mask(sccb, val) sccb_set_generic_mask(sccb, 1, val)
#define sccb_set_sclp_recv_mask(sccb, val) sccb_set_generic_mask(sccb, 2, val)
#define sccb_set_sclp_send_mask(sccb, val) sccb_set_generic_mask(sccb, 3, val)
struct read_cpu_info_sccb { struct read_cpu_info_sccb {
struct sccb_header header; struct sccb_header header;
u16 nr_configured; u16 nr_configured;
...@@ -229,6 +268,7 @@ extern char sclp_early_sccb[PAGE_SIZE]; ...@@ -229,6 +268,7 @@ extern char sclp_early_sccb[PAGE_SIZE];
void sclp_early_wait_irq(void); void sclp_early_wait_irq(void);
int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb); int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb); unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb);
unsigned int sclp_early_con_check_vt220(struct init_sccb *sccb);
int sclp_early_set_event_mask(struct init_sccb *sccb, int sclp_early_set_event_mask(struct init_sccb *sccb,
sccb_mask_t receive_mask, sccb_mask_t receive_mask,
sccb_mask_t send_mask); sccb_mask_t send_mask);
......
...@@ -249,7 +249,7 @@ static void __init sclp_early_console_detect(struct init_sccb *sccb) ...@@ -249,7 +249,7 @@ static void __init sclp_early_console_detect(struct init_sccb *sccb)
if (sccb->header.response_code != 0x20) if (sccb->header.response_code != 0x20)
return; return;
if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK) if (sclp_early_con_check_vt220(sccb))
sclp.has_vt220 = 1; sclp.has_vt220 = 1;
if (sclp_early_con_check_linemode(sccb)) if (sclp_early_con_check_linemode(sccb))
......
...@@ -148,8 +148,8 @@ int sclp_early_set_event_mask(struct init_sccb *sccb, ...@@ -148,8 +148,8 @@ int sclp_early_set_event_mask(struct init_sccb *sccb,
memset(sccb, 0, sizeof(*sccb)); memset(sccb, 0, sizeof(*sccb));
sccb->header.length = sizeof(*sccb); sccb->header.length = sizeof(*sccb);
sccb->mask_length = sizeof(sccb_mask_t); sccb->mask_length = sizeof(sccb_mask_t);
sccb->receive_mask = receive_mask; sccb_set_recv_mask(sccb, receive_mask);
sccb->send_mask = send_mask; sccb_set_send_mask(sccb, send_mask);
if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_MASK, sccb)) if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_MASK, sccb))
return -EIO; return -EIO;
if (sccb->header.response_code != 0x20) if (sccb->header.response_code != 0x20)
...@@ -159,19 +159,28 @@ int sclp_early_set_event_mask(struct init_sccb *sccb, ...@@ -159,19 +159,28 @@ int sclp_early_set_event_mask(struct init_sccb *sccb,
unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb) unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb)
{ {
if (!(sccb->sclp_send_mask & EVTYP_OPCMD_MASK)) if (!(sccb_get_sclp_send_mask(sccb) & EVTYP_OPCMD_MASK))
return 0; return 0;
if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK))) if (!(sccb_get_sclp_recv_mask(sccb) & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
return 0; return 0;
return 1; return 1;
} }
unsigned int sclp_early_con_check_vt220(struct init_sccb *sccb)
{
if (sccb_get_sclp_send_mask(sccb) & EVTYP_VT220MSG_MASK)
return 1;
return 0;
}
static int sclp_early_setup(int disable, int *have_linemode, int *have_vt220) static int sclp_early_setup(int disable, int *have_linemode, int *have_vt220)
{ {
unsigned long receive_mask, send_mask; unsigned long receive_mask, send_mask;
struct init_sccb *sccb; struct init_sccb *sccb;
int rc; int rc;
BUILD_BUG_ON(sizeof(struct init_sccb) > PAGE_SIZE);
*have_linemode = *have_vt220 = 0; *have_linemode = *have_vt220 = 0;
sccb = (struct init_sccb *) &sclp_early_sccb; sccb = (struct init_sccb *) &sclp_early_sccb;
receive_mask = disable ? 0 : EVTYP_OPCMD_MASK; receive_mask = disable ? 0 : EVTYP_OPCMD_MASK;
...@@ -180,7 +189,7 @@ static int sclp_early_setup(int disable, int *have_linemode, int *have_vt220) ...@@ -180,7 +189,7 @@ static int sclp_early_setup(int disable, int *have_linemode, int *have_vt220)
if (rc) if (rc)
return rc; return rc;
*have_linemode = sclp_early_con_check_linemode(sccb); *have_linemode = sclp_early_con_check_linemode(sccb);
*have_vt220 = sccb->send_mask & EVTYP_VT220MSG_MASK; *have_vt220 = !!(sccb_get_send_mask(sccb) & EVTYP_VT220MSG_MASK);
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment