Commit 30c2df51 authored by Martin Schwidefsky's avatar Martin Schwidefsky

[S390] sclp: event buffer dissection

Move gds vector/subvector find functions to the sclp header file.
Simplify event buffer dissection in sclp tty code.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent fca894ed
...@@ -186,4 +186,26 @@ sclp_ascebc_str(unsigned char *str, int nr) ...@@ -186,4 +186,26 @@ sclp_ascebc_str(unsigned char *str, int nr)
(MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr); (MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr);
} }
static inline struct gds_vector *
sclp_find_gds_vector(void *start, void *end, u16 id)
{
struct gds_vector *v;
for (v = start; (void *) v < end; v = (void *) v + v->length)
if (v->gds_id == id)
return v;
return NULL;
}
static inline struct gds_subvector *
sclp_find_gds_subvector(void *start, void *end, u8 key)
{
struct gds_subvector *sv;
for (sv = start; (void *) sv < end; sv = (void *) sv + sv->length)
if (sv->key == key)
return sv;
return NULL;
}
#endif /* __SCLP_H__ */ #endif /* __SCLP_H__ */
...@@ -408,118 +408,72 @@ static int sclp_switch_cases(unsigned char *buf, int count) ...@@ -408,118 +408,72 @@ static int sclp_switch_cases(unsigned char *buf, int count)
return op - buf; return op - buf;
} }
static void static void sclp_get_input(struct gds_subvector *sv)
sclp_get_input(unsigned char *start, unsigned char *end)
{ {
unsigned char *str;
int count; int count;
count = end - start; str = (unsigned char *) (sv + 1);
count = sv->length - sizeof(*sv);
if (sclp_tty_tolower) if (sclp_tty_tolower)
EBC_TOLOWER(start, count); EBC_TOLOWER(str, count);
count = sclp_switch_cases(start, count); count = sclp_switch_cases(str, count);
/* convert EBCDIC to ASCII (modify original input in SCCB) */ /* convert EBCDIC to ASCII (modify original input in SCCB) */
sclp_ebcasc_str(start, count); sclp_ebcasc_str(str, count);
/* transfer input to high level driver */ /* transfer input to high level driver */
sclp_tty_input(start, count); sclp_tty_input(str, count);
}
static inline struct gds_vector *
find_gds_vector(struct gds_vector *start, struct gds_vector *end, u16 id)
{
struct gds_vector *vec;
for (vec = start; vec < end; vec = (void *) vec + vec->length)
if (vec->gds_id == id)
return vec;
return NULL;
} }
static inline struct gds_subvector * static inline void sclp_eval_selfdeftextmsg(struct gds_subvector *sv)
find_gds_subvector(struct gds_subvector *start,
struct gds_subvector *end, u8 key)
{ {
struct gds_subvector *subvec; void *end;
for (subvec = start; subvec < end; end = (void *) sv + sv->length;
subvec = (void *) subvec + subvec->length) for (sv = sv + 1; (void *) sv < end; sv = (void *) sv + sv->length)
if (subvec->key == key) if (sv->key == 0x30)
return subvec; sclp_get_input(sv);
return NULL;
} }
static inline void static inline void sclp_eval_textcmd(struct gds_vector *v)
sclp_eval_selfdeftextmsg(struct gds_subvector *start,
struct gds_subvector *end)
{ {
struct gds_subvector *subvec; struct gds_subvector *sv;
void *end;
subvec = start;
while (subvec < end) {
subvec = find_gds_subvector(subvec, end, 0x30);
if (!subvec)
break;
sclp_get_input((unsigned char *)(subvec + 1),
(unsigned char *) subvec + subvec->length);
subvec = (void *) subvec + subvec->length;
}
}
static inline void end = (void *) v + v->length;
sclp_eval_textcmd(struct gds_subvector *start, for (sv = (struct gds_subvector *) (v + 1);
struct gds_subvector *end) (void *) sv < end; sv = (void *) sv + sv->length)
{ if (sv->key == GDS_KEY_SELFDEFTEXTMSG)
struct gds_subvector *subvec; sclp_eval_selfdeftextmsg(sv);
subvec = start;
while (subvec < end) {
subvec = find_gds_subvector(subvec, end,
GDS_KEY_SELFDEFTEXTMSG);
if (!subvec)
break;
sclp_eval_selfdeftextmsg((struct gds_subvector *)(subvec + 1),
(void *)subvec + subvec->length);
subvec = (void *) subvec + subvec->length;
}
} }
static inline void static inline void sclp_eval_cpmsu(struct gds_vector *v)
sclp_eval_cpmsu(struct gds_vector *start, struct gds_vector *end)
{ {
struct gds_vector *vec; void *end;
vec = start; end = (void *) v + v->length;
while (vec < end) { for (v = v + 1; (void *) v < end; v = (void *) v + v->length)
vec = find_gds_vector(vec, end, GDS_ID_TEXTCMD); if (v->gds_id == GDS_ID_TEXTCMD)
if (!vec) sclp_eval_textcmd(v);
break;
sclp_eval_textcmd((struct gds_subvector *)(vec + 1),
(void *) vec + vec->length);
vec = (void *) vec + vec->length;
}
} }
static inline void static inline void sclp_eval_mdsmu(struct gds_vector *v)
sclp_eval_mdsmu(struct gds_vector *start, void *end)
{ {
struct gds_vector *vec; v = sclp_find_gds_vector(v + 1, (void *) v + v->length, GDS_ID_CPMSU);
if (v)
vec = find_gds_vector(start, end, GDS_ID_CPMSU); sclp_eval_cpmsu(v);
if (vec)
sclp_eval_cpmsu(vec + 1, (void *) vec + vec->length);
} }
static void static void sclp_tty_receiver(struct evbuf_header *evbuf)
sclp_tty_receiver(struct evbuf_header *evbuf)
{ {
struct gds_vector *start, *end, *vec; struct gds_vector *v;
start = (struct gds_vector *)(evbuf + 1); v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length,
end = (void *) evbuf + evbuf->length; GDS_ID_MDSMU);
vec = find_gds_vector(start, end, GDS_ID_MDSMU); if (v)
if (vec) sclp_eval_mdsmu(v);
sclp_eval_mdsmu(vec + 1, (void *) vec + vec->length);
} }
static void static void
......
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