diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/char/sclp.h | 22 | ||||
-rw-r--r-- | drivers/s390/char/sclp_tty.c | 122 |
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) | |||
186 | (MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr); | 186 | (MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr); |
187 | } | 187 | } |
188 | 188 | ||
189 | static inline struct gds_vector * | ||
190 | sclp_find_gds_vector(void *start, void *end, u16 id) | ||
191 | { | ||
192 | struct gds_vector *v; | ||
193 | |||
194 | for (v = start; (void *) v < end; v = (void *) v + v->length) | ||
195 | if (v->gds_id == id) | ||
196 | return v; | ||
197 | return NULL; | ||
198 | } | ||
199 | |||
200 | static inline struct gds_subvector * | ||
201 | sclp_find_gds_subvector(void *start, void *end, u8 key) | ||
202 | { | ||
203 | struct gds_subvector *sv; | ||
204 | |||
205 | for (sv = start; (void *) sv < end; sv = (void *) sv + sv->length) | ||
206 | if (sv->key == key) | ||
207 | return sv; | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
189 | #endif /* __SCLP_H__ */ | 211 | #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) | |||
408 | return op - buf; | 408 | return op - buf; |
409 | } | 409 | } |
410 | 410 | ||
411 | static void | 411 | static void sclp_get_input(struct gds_subvector *sv) |
412 | sclp_get_input(unsigned char *start, unsigned char *end) | ||
413 | { | 412 | { |
413 | unsigned char *str; | ||
414 | int count; | 414 | int count; |
415 | 415 | ||
416 | count = end - start; | 416 | str = (unsigned char *) (sv + 1); |
417 | count = sv->length - sizeof(*sv); | ||
417 | if (sclp_tty_tolower) | 418 | if (sclp_tty_tolower) |
418 | EBC_TOLOWER(start, count); | 419 | EBC_TOLOWER(str, count); |
419 | count = sclp_switch_cases(start, count); | 420 | count = sclp_switch_cases(str, count); |
420 | /* convert EBCDIC to ASCII (modify original input in SCCB) */ | 421 | /* convert EBCDIC to ASCII (modify original input in SCCB) */ |
421 | sclp_ebcasc_str(start, count); | 422 | sclp_ebcasc_str(str, count); |
422 | 423 | ||
423 | /* transfer input to high level driver */ | 424 | /* transfer input to high level driver */ |
424 | sclp_tty_input(start, count); | 425 | sclp_tty_input(str, count); |
425 | } | ||
426 | |||
427 | static inline struct gds_vector * | ||
428 | find_gds_vector(struct gds_vector *start, struct gds_vector *end, u16 id) | ||
429 | { | ||
430 | struct gds_vector *vec; | ||
431 | |||
432 | for (vec = start; vec < end; vec = (void *) vec + vec->length) | ||
433 | if (vec->gds_id == id) | ||
434 | return vec; | ||
435 | return NULL; | ||
436 | } | 426 | } |
437 | 427 | ||
438 | static inline struct gds_subvector * | 428 | static inline void sclp_eval_selfdeftextmsg(struct gds_subvector *sv) |
439 | find_gds_subvector(struct gds_subvector *start, | ||
440 | struct gds_subvector *end, u8 key) | ||
441 | { | 429 | { |
442 | struct gds_subvector *subvec; | 430 | void *end; |
443 | 431 | ||
444 | for (subvec = start; subvec < end; | 432 | end = (void *) sv + sv->length; |
445 | subvec = (void *) subvec + subvec->length) | 433 | for (sv = sv + 1; (void *) sv < end; sv = (void *) sv + sv->length) |
446 | if (subvec->key == key) | 434 | if (sv->key == 0x30) |
447 | return subvec; | 435 | sclp_get_input(sv); |
448 | return NULL; | ||
449 | } | 436 | } |
450 | 437 | ||
451 | static inline void | 438 | static inline void sclp_eval_textcmd(struct gds_vector *v) |
452 | sclp_eval_selfdeftextmsg(struct gds_subvector *start, | ||
453 | struct gds_subvector *end) | ||
454 | { | 439 | { |
455 | struct gds_subvector *subvec; | 440 | struct gds_subvector *sv; |
456 | 441 | void *end; | |
457 | subvec = start; | ||
458 | while (subvec < end) { | ||
459 | subvec = find_gds_subvector(subvec, end, 0x30); | ||
460 | if (!subvec) | ||
461 | break; | ||
462 | sclp_get_input((unsigned char *)(subvec + 1), | ||
463 | (unsigned char *) subvec + subvec->length); | ||
464 | subvec = (void *) subvec + subvec->length; | ||
465 | } | ||
466 | } | ||
467 | 442 | ||
468 | static inline void | 443 | end = (void *) v + v->length; |
469 | sclp_eval_textcmd(struct gds_subvector *start, | 444 | for (sv = (struct gds_subvector *) (v + 1); |
470 | struct gds_subvector *end) | 445 | (void *) sv < end; sv = (void *) sv + sv->length) |
471 | { | 446 | if (sv->key == GDS_KEY_SELFDEFTEXTMSG) |
472 | struct gds_subvector *subvec; | 447 | sclp_eval_selfdeftextmsg(sv); |
473 | 448 | ||
474 | subvec = start; | ||
475 | while (subvec < end) { | ||
476 | subvec = find_gds_subvector(subvec, end, | ||
477 | GDS_KEY_SELFDEFTEXTMSG); | ||
478 | if (!subvec) | ||
479 | break; | ||
480 | sclp_eval_selfdeftextmsg((struct gds_subvector *)(subvec + 1), | ||
481 | (void *)subvec + subvec->length); | ||
482 | subvec = (void *) subvec + subvec->length; | ||
483 | } | ||
484 | } | 449 | } |
485 | 450 | ||
486 | static inline void | 451 | static inline void sclp_eval_cpmsu(struct gds_vector *v) |
487 | sclp_eval_cpmsu(struct gds_vector *start, struct gds_vector *end) | ||
488 | { | 452 | { |
489 | struct gds_vector *vec; | 453 | void *end; |
490 | 454 | ||
491 | vec = start; | 455 | end = (void *) v + v->length; |
492 | while (vec < end) { | 456 | for (v = v + 1; (void *) v < end; v = (void *) v + v->length) |
493 | vec = find_gds_vector(vec, end, GDS_ID_TEXTCMD); | 457 | if (v->gds_id == GDS_ID_TEXTCMD) |
494 | if (!vec) | 458 | sclp_eval_textcmd(v); |
495 | break; | ||
496 | sclp_eval_textcmd((struct gds_subvector *)(vec + 1), | ||
497 | (void *) vec + vec->length); | ||
498 | vec = (void *) vec + vec->length; | ||
499 | } | ||
500 | } | 459 | } |
501 | 460 | ||
502 | 461 | ||
503 | static inline void | 462 | static inline void sclp_eval_mdsmu(struct gds_vector *v) |
504 | sclp_eval_mdsmu(struct gds_vector *start, void *end) | ||
505 | { | 463 | { |
506 | struct gds_vector *vec; | 464 | v = sclp_find_gds_vector(v + 1, (void *) v + v->length, GDS_ID_CPMSU); |
507 | 465 | if (v) | |
508 | vec = find_gds_vector(start, end, GDS_ID_CPMSU); | 466 | sclp_eval_cpmsu(v); |
509 | if (vec) | ||
510 | sclp_eval_cpmsu(vec + 1, (void *) vec + vec->length); | ||
511 | } | 467 | } |
512 | 468 | ||
513 | static void | 469 | static void sclp_tty_receiver(struct evbuf_header *evbuf) |
514 | sclp_tty_receiver(struct evbuf_header *evbuf) | ||
515 | { | 470 | { |
516 | struct gds_vector *start, *end, *vec; | 471 | struct gds_vector *v; |
517 | 472 | ||
518 | start = (struct gds_vector *)(evbuf + 1); | 473 | v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length, |
519 | end = (void *) evbuf + evbuf->length; | 474 | GDS_ID_MDSMU); |
520 | vec = find_gds_vector(start, end, GDS_ID_MDSMU); | 475 | if (v) |
521 | if (vec) | 476 | sclp_eval_mdsmu(v); |
522 | sclp_eval_mdsmu(vec + 1, (void *) vec + vec->length); | ||
523 | } | 477 | } |
524 | 478 | ||
525 | static void | 479 | static void |