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

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
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -618,9 +618,12 @@ struct sclp_statechangebuf {
	u16		_zeros : 12;
	u16		mask_length;
	u64		sclp_active_facility_mask;
	sccb_mask_t	sclp_receive_mask;
	sccb_mask_t	sclp_send_mask;
	u32		read_data_function_mask;
	u8		masks[2 * 1021 + 4];	/* variable length */
	/*
	 * u8		sclp_receive_mask[mask_length];
	 * u8		sclp_send_mask[mask_length];
	 * u32		read_data_function_mask;
	 */
} __attribute__((packed));


@@ -631,14 +634,14 @@ sclp_state_change_cb(struct evbuf_header *evbuf)
	unsigned long flags;
	struct sclp_statechangebuf *scbuf;

	BUILD_BUG_ON(sizeof(struct sclp_statechangebuf) > PAGE_SIZE);

	scbuf = (struct sclp_statechangebuf *) evbuf;
	if (scbuf->mask_length != sizeof(sccb_mask_t))
		return;
	spin_lock_irqsave(&sclp_lock, flags);
	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)
		sclp_send_mask = scbuf->sclp_send_mask;
		sclp_send_mask = sccb_get_send_mask(scbuf);
	spin_unlock_irqrestore(&sclp_lock, flags);
	if (scbuf->validity_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)
	sclp_init_req.sccb = sccb;
	sccb->header.length = sizeof(*sccb);
	sccb->mask_length = sizeof(sccb_mask_t);
	sccb->receive_mask = receive_mask;
	sccb->send_mask = send_mask;
	sccb->sclp_receive_mask = 0;
	sccb->sclp_send_mask = 0;
	sccb_set_recv_mask(sccb, receive_mask);
	sccb_set_send_mask(sccb, send_mask);
	sccb_set_sclp_recv_mask(sccb, 0);
	sccb_set_sclp_send_mask(sccb, 0);
}

/* Start init mask request. If calculate is non-zero, calculate the mask as
@@ -822,8 +825,8 @@ sclp_init_mask(int calculate)
		    sccb->header.response_code == 0x20) {
			/* Successful request */
			if (calculate) {
				sclp_receive_mask = sccb->sclp_receive_mask;
				sclp_send_mask = sccb->sclp_send_mask;
				sclp_receive_mask = sccb_get_sclp_recv_mask(sccb);
				sclp_send_mask = sccb_get_sclp_send_mask(sccb);
			} else {
				sclp_receive_mask = 0;
				sclp_send_mask = 0;
+44 −4
Original line number Diff line number Diff line
@@ -100,12 +100,51 @@ struct init_sccb {
	struct sccb_header header;
	u16 _reserved;
	u16 mask_length;
	sccb_mask_t receive_mask;
	sccb_mask_t send_mask;
	sccb_mask_t sclp_receive_mask;
	sccb_mask_t sclp_send_mask;
	u8 masks[4 * 1021];	/* variable length */
	/*
	 * u8 receive_mask[mask_length];
	 * u8 send_mask[mask_length];
	 * u8 sclp_receive_mask[mask_length];
	 * u8 sclp_send_mask[mask_length];
	 */
} __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	sccb_header header;
	u16	nr_configured;
@@ -229,6 +268,7 @@ extern char sclp_early_sccb[PAGE_SIZE];
void sclp_early_wait_irq(void);
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_vt220(struct init_sccb *sccb);
int sclp_early_set_event_mask(struct init_sccb *sccb,
			      sccb_mask_t receive_mask,
			      sccb_mask_t send_mask);
+1 −1
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ static void __init sclp_early_console_detect(struct init_sccb *sccb)
	if (sccb->header.response_code != 0x20)
		return;

	if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
	if (sclp_early_con_check_vt220(sccb))
		sclp.has_vt220 = 1;

	if (sclp_early_con_check_linemode(sccb))
+14 −5
Original line number Diff line number Diff line
@@ -148,8 +148,8 @@ int sclp_early_set_event_mask(struct init_sccb *sccb,
	memset(sccb, 0, sizeof(*sccb));
	sccb->header.length = sizeof(*sccb);
	sccb->mask_length = sizeof(sccb_mask_t);
	sccb->receive_mask = receive_mask;
	sccb->send_mask = send_mask;
	sccb_set_recv_mask(sccb, receive_mask);
	sccb_set_send_mask(sccb, send_mask);
	if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_MASK, sccb))
		return -EIO;
	if (sccb->header.response_code != 0x20)
@@ -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)
{
	if (!(sccb->sclp_send_mask & EVTYP_OPCMD_MASK))
	if (!(sccb_get_sclp_send_mask(sccb) & EVTYP_OPCMD_MASK))
		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 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)
{
	unsigned long receive_mask, send_mask;
	struct init_sccb *sccb;
	int rc;

	BUILD_BUG_ON(sizeof(struct init_sccb) > PAGE_SIZE);

	*have_linemode = *have_vt220 = 0;
	sccb = (struct init_sccb *) &sclp_early_sccb;
	receive_mask = disable ? 0 : EVTYP_OPCMD_MASK;
@@ -180,7 +189,7 @@ static int sclp_early_setup(int disable, int *have_linemode, int *have_vt220)
	if (rc)
		return rc;
	*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;
}