aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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)
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
189static inline struct gds_vector *
190sclp_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
200static inline struct gds_subvector *
201sclp_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
411static void 411static void sclp_get_input(struct gds_subvector *sv)
412sclp_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
427static inline struct gds_vector *
428find_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
438static inline struct gds_subvector * 428static inline void sclp_eval_selfdeftextmsg(struct gds_subvector *sv)
439find_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
451static inline void 438static inline void sclp_eval_textcmd(struct gds_vector *v)
452sclp_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
468static inline void 443 end = (void *) v + v->length;
469sclp_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
486static inline void 451static inline void sclp_eval_cpmsu(struct gds_vector *v)
487sclp_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
503static inline void 462static inline void sclp_eval_mdsmu(struct gds_vector *v)
504sclp_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
513static void 469static void sclp_tty_receiver(struct evbuf_header *evbuf)
514sclp_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
525static void 479static void