summaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-05-23 10:24:42 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-05-23 10:24:31 +0200
commit30c2df51173ea4e4755ad52be7f2914f01e32404 (patch)
treeee228c2f42902b484fb1d58f36cc955a1d0edcd6 /drivers/s390
parentfca894edd7566f5c548598c8fad7f329278c23b4 (diff)
downloadlinux-30c2df51173ea4e4755ad52be7f2914f01e32404.tar.gz
linux-30c2df51173ea4e4755ad52be7f2914f01e32404.tar.bz2
linux-30c2df51173ea4e4755ad52be7f2914f01e32404.zip
[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: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/sclp.h22
-rw-r--r--drivers/s390/char/sclp_tty.c122
2 files changed, 60 insertions, 84 deletions
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 6bb5a6bdfab5..bc23b05bfe7d 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -186,4 +186,26 @@ sclp_ascebc_str(unsigned char *str, int 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__ */
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 8258d590505f..a879c139926a 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -408,118 +408,72 @@ static int sclp_switch_cases(unsigned char *buf, int count)
return op - buf;
}
-static void
-sclp_get_input(unsigned char *start, unsigned char *end)
+static void sclp_get_input(struct gds_subvector *sv)
{
+ unsigned char *str;
int count;
- count = end - start;
+ str = (unsigned char *) (sv + 1);
+ count = sv->length - sizeof(*sv);
if (sclp_tty_tolower)
- EBC_TOLOWER(start, count);
- count = sclp_switch_cases(start, count);
+ EBC_TOLOWER(str, count);
+ count = sclp_switch_cases(str, count);
/* 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 */
- sclp_tty_input(start, 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;
+ sclp_tty_input(str, count);
}
-static inline struct gds_subvector *
-find_gds_subvector(struct gds_subvector *start,
- struct gds_subvector *end, u8 key)
+static inline void sclp_eval_selfdeftextmsg(struct gds_subvector *sv)
{
- struct gds_subvector *subvec;
+ void *end;
- for (subvec = start; subvec < end;
- subvec = (void *) subvec + subvec->length)
- if (subvec->key == key)
- return subvec;
- return NULL;
+ end = (void *) sv + sv->length;
+ for (sv = sv + 1; (void *) sv < end; sv = (void *) sv + sv->length)
+ if (sv->key == 0x30)
+ sclp_get_input(sv);
}
-static inline void
-sclp_eval_selfdeftextmsg(struct gds_subvector *start,
- struct gds_subvector *end)
+static inline void sclp_eval_textcmd(struct gds_vector *v)
{
- struct gds_subvector *subvec;
-
- 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;
- }
-}
+ struct gds_subvector *sv;
+ void *end;
-static inline void
-sclp_eval_textcmd(struct gds_subvector *start,
- struct gds_subvector *end)
-{
- struct gds_subvector *subvec;
+ end = (void *) v + v->length;
+ for (sv = (struct gds_subvector *) (v + 1);
+ (void *) sv < end; sv = (void *) sv + sv->length)
+ if (sv->key == GDS_KEY_SELFDEFTEXTMSG)
+ 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
-sclp_eval_cpmsu(struct gds_vector *start, struct gds_vector *end)
+static inline void sclp_eval_cpmsu(struct gds_vector *v)
{
- struct gds_vector *vec;
+ void *end;
- vec = start;
- while (vec < end) {
- vec = find_gds_vector(vec, end, GDS_ID_TEXTCMD);
- if (!vec)
- break;
- sclp_eval_textcmd((struct gds_subvector *)(vec + 1),
- (void *) vec + vec->length);
- vec = (void *) vec + vec->length;
- }
+ end = (void *) v + v->length;
+ for (v = v + 1; (void *) v < end; v = (void *) v + v->length)
+ if (v->gds_id == GDS_ID_TEXTCMD)
+ sclp_eval_textcmd(v);
}
-static inline void
-sclp_eval_mdsmu(struct gds_vector *start, void *end)
+static inline void sclp_eval_mdsmu(struct gds_vector *v)
{
- struct gds_vector *vec;
-
- vec = find_gds_vector(start, end, GDS_ID_CPMSU);
- if (vec)
- sclp_eval_cpmsu(vec + 1, (void *) vec + vec->length);
+ v = sclp_find_gds_vector(v + 1, (void *) v + v->length, GDS_ID_CPMSU);
+ if (v)
+ sclp_eval_cpmsu(v);
}
-static void
-sclp_tty_receiver(struct evbuf_header *evbuf)
+static void sclp_tty_receiver(struct evbuf_header *evbuf)
{
- struct gds_vector *start, *end, *vec;
+ struct gds_vector *v;
- start = (struct gds_vector *)(evbuf + 1);
- end = (void *) evbuf + evbuf->length;
- vec = find_gds_vector(start, end, GDS_ID_MDSMU);
- if (vec)
- sclp_eval_mdsmu(vec + 1, (void *) vec + vec->length);
+ v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length,
+ GDS_ID_MDSMU);
+ if (v)
+ sclp_eval_mdsmu(v);
}
static void