2 * SCLP ASCII access driver
4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
6 * This work is licensed under the terms of the GNU GPL, version 2 or (at
7 * your option) any later version. See the COPYING file in the top-level
15 long write(int fd
, const void *str
, size_t len
);
17 static char _sccb
[PAGE_SIZE
] __attribute__((__aligned__(4096)));
19 const unsigned char ebc2asc
[256] =
20 /* 0123456789abcdef0123456789abcdef */
21 "................................" /* 1F */
22 "................................" /* 3F */
23 " ...........<(+|&.........!$*);." /* 5F first.chr.here.is.real.space */
24 "-/.........,%_>?.........`:#@'=\""/* 7F */
25 ".abcdefghi.......jklmnopqr......" /* 9F */
26 "..stuvwxyz......................" /* BF */
27 ".ABCDEFGHI.......JKLMNOPQR......" /* DF */
28 "..STUVWXYZ......0123456789......";/* FF */
30 /* Perform service call. Return 0 on success, non-zero otherwise. */
31 static int sclp_service_call(unsigned int command
, void *sccb
)
36 " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
39 : "=&d" (cc
) : "d" (command
), "a" (__pa(sccb
))
49 void sclp_set_write_mask(uint32_t receive_mask
, uint32_t send_mask
)
51 WriteEventMask
*sccb
= (void *)_sccb
;
53 sccb
->h
.length
= sizeof(WriteEventMask
);
54 sccb
->mask_length
= sizeof(unsigned int);
55 sccb
->cp_receive_mask
= receive_mask
;
56 sccb
->cp_send_mask
= send_mask
;
58 sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK
, sccb
);
63 sclp_set_write_mask(0, SCLP_EVENT_MASK_MSG_ASCII
);
66 long write(int fd
, const void *str
, size_t len
)
68 WriteEventData
*sccb
= (void *)_sccb
;
73 if (fd
!= 1 && fd
!= 2) {
77 for (i
= 0; i
< len
; i
++) {
78 if ((data_len
+ 1) >= SCCB_DATA_LEN
) {
79 /* We would overflow the sccb buffer, abort early */
85 /* Terminal emulators might need \r\n, so generate it */
86 sccb
->data
[data_len
++] = '\r';
89 sccb
->data
[data_len
++] = *p
;
93 sccb
->h
.length
= sizeof(WriteEventData
) + data_len
;
94 sccb
->h
.function_code
= SCLP_FC_NORMAL_WRITE
;
95 sccb
->ebh
.length
= sizeof(EventBufferHeader
) + data_len
;
96 sccb
->ebh
.type
= SCLP_EVENT_ASCII_CONSOLE_DATA
;
99 sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA
, sccb
);
104 void sclp_print(const char *str
)
106 write(1, str
, strlen(str
));
109 void sclp_get_loadparm_ascii(char *loadparm
)
112 ReadInfo
*sccb
= (void *)_sccb
;
114 memset((char *)_sccb
, 0, sizeof(ReadInfo
));
115 sccb
->h
.length
= SCCB_SIZE
;
116 if (!sclp_service_call(SCLP_CMDW_READ_SCP_INFO
, sccb
)) {
117 ebcdic_to_ascii((char *) sccb
->loadparm
, loadparm
, LOADPARM_LEN
);
121 int sclp_read(char *str
, size_t count
)
123 ReadEventData
*sccb
= (void *)_sccb
;
124 char *buf
= (char *)(&sccb
->ebh
) + 7;
126 /* If count exceeds max buffer size, then restrict it to the max size */
127 if (count
> SCCB_SIZE
- 8) {
128 count
= SCCB_SIZE
- 8;
131 sccb
->h
.length
= SCCB_SIZE
;
132 sccb
->h
.function_code
= SCLP_UNCONDITIONAL_READ
;
134 sclp_service_call(SCLP_CMD_READ_EVENT_DATA
, sccb
);
135 memcpy(str
, buf
, count
);
137 return sccb
->ebh
.length
- 7;