1/*
2 * driver: reading from and writing to system console on S/390 via SCLP
3 *
4 * Copyright IBM Corp. 1999, 2009
5 *
6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
7 *	      Martin Schwidefsky <schwidefsky@de.ibm.com>
8 */
9
10#include <linux/kmod.h>
11#include <linux/types.h>
12#include <linux/err.h>
13#include <linux/string.h>
14#include <linux/spinlock.h>
15#include <linux/ctype.h>
16#include <asm/uaccess.h>
17
18#include "sclp.h"
19#include "sclp_rw.h"
20
21/*
22 * The room for the SCCB (only for writing) is not equal to a pages size
23 * (as it is specified as the maximum size in the SCLP documentation)
24 * because of the additional data structure described above.
25 */
26#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer))
27
28static void sclp_rw_pm_event(struct sclp_register *reg,
29			     enum sclp_pm_event sclp_pm_event)
30{
31	sclp_console_pm_event(sclp_pm_event);
32}
33
34/* Event type structure for write message and write priority message */
35static struct sclp_register sclp_rw_event = {
36	.send_mask = EVTYP_MSG_MASK,
37	.pm_event_fn = sclp_rw_pm_event,
38};
39
40/*
41 * Setup a sclp write buffer. Gets a page as input (4K) and returns
42 * a pointer to a struct sclp_buffer structure that is located at the
43 * end of the input page. This reduces the buffer space by a few
44 * bytes but simplifies things.
45 */
46struct sclp_buffer *
47sclp_make_buffer(void *page, unsigned short columns, unsigned short htab)
48{
49	struct sclp_buffer *buffer;
50	struct sccb_header *sccb;
51
52	sccb = (struct sccb_header *) page;
53	/*
54	 * We keep the struct sclp_buffer structure at the end
55	 * of the sccb page.
56	 */
57	buffer = ((struct sclp_buffer *) ((addr_t) sccb + PAGE_SIZE)) - 1;
58	buffer->sccb = sccb;
59	buffer->retry_count = 0;
60	buffer->messages = 0;
61	buffer->char_sum = 0;
62	buffer->current_line = NULL;
63	buffer->current_length = 0;
64	buffer->columns = columns;
65	buffer->htab = htab;
66
67	/* initialize sccb */
68	memset(sccb, 0, sizeof(struct sccb_header));
69	sccb->length = sizeof(struct sccb_header);
70
71	return buffer;
72}
73
74/*
75 * Return a pointer to the original page that has been used to create
76 * the buffer.
77 */
78void *
79sclp_unmake_buffer(struct sclp_buffer *buffer)
80{
81	return buffer->sccb;
82}
83
84/*
85 * Initialize a new message the end of the provided buffer with
86 * enough room for max_len characters. Return 0 on success.
87 */
88static int
89sclp_initialize_mto(struct sclp_buffer *buffer, int max_len)
90{
91	struct sccb_header *sccb;
92	struct msg_buf *msg;
93	struct mdb *mdb;
94	struct go *go;
95	struct mto *mto;
96	int msg_size;
97
98	/* max size of new message including message text  */
99	msg_size = sizeof(struct msg_buf) + max_len;
100
101	/* check if current buffer sccb can contain the mto */
102	sccb = buffer->sccb;
103	if ((MAX_SCCB_ROOM - sccb->length) < msg_size)
104		return -ENOMEM;
105
106	msg = (struct msg_buf *)((addr_t) sccb + sccb->length);
107	memset(msg, 0, sizeof(struct msg_buf));
108	msg->header.length = sizeof(struct msg_buf);
109	msg->header.type = EVTYP_MSG;
110
111	mdb = &msg->mdb;
112	mdb->header.length = sizeof(struct mdb);
113	mdb->header.type = 1;
114	mdb->header.tag = 0xD4C4C240;	/* ebcdic "MDB " */
115	mdb->header.revision_code = 1;
116
117	go = &mdb->go;
118	go->length = sizeof(struct go);
119	go->type = 1;
120
121	mto = &mdb->mto;
122	mto->length = sizeof(struct mto);
123	mto->type = 4;	/* message text object */
124	mto->line_type_flags = LNTPFLGS_ENDTEXT; /* end text */
125
126	/* set pointer to first byte after struct mto. */
127	buffer->current_msg = msg;
128	buffer->current_line = (char *) (mto + 1);
129	buffer->current_length = 0;
130
131	return 0;
132}
133
134/*
135 * Finalize message initialized by sclp_initialize_mto(),
136 * updating the sizes of MTO, enclosing MDB, event buffer and SCCB.
137 */
138static void
139sclp_finalize_mto(struct sclp_buffer *buffer)
140{
141	struct sccb_header *sccb;
142	struct msg_buf *msg;
143
144	/*
145	 * update values of sizes
146	 * (SCCB, Event(Message) Buffer, Message Data Block)
147	 */
148	sccb = buffer->sccb;
149	msg = buffer->current_msg;
150	msg->header.length += buffer->current_length;
151	msg->mdb.header.length += buffer->current_length;
152	msg->mdb.mto.length += buffer->current_length;
153	sccb->length += msg->header.length;
154
155	/*
156	 * count number of buffered messages (= number of Message Text
157	 * Objects) and number of buffered characters
158	 * for the SCCB currently used for buffering and at all
159	 */
160	buffer->messages++;
161	buffer->char_sum += buffer->current_length;
162
163	buffer->current_line = NULL;
164	buffer->current_length = 0;
165	buffer->current_msg = NULL;
166}
167
168/*
169 * processing of a message including escape characters,
170 * returns number of characters written to the output sccb
171 * ("processed" means that is not guaranteed that the character have already
172 *  been sent to the SCLP but that it will be done at least next time the SCLP
173 *  is not busy)
174 */
175int
176sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
177{
178	int spaces, i_msg;
179	int rc;
180
181	/*
182	 * parse msg for escape sequences (\t,\v ...) and put formated
183	 * msg into an mto (created by sclp_initialize_mto).
184	 *
185	 * We have to do this work ourselfs because there is no support for
186	 * these characters on the native machine and only partial support
187	 * under VM (Why does VM interpret \n but the native machine doesn't ?)
188	 *
189	 * Depending on i/o-control setting the message is always written
190	 * immediately or we wait for a final new line maybe coming with the
191	 * next message. Besides we avoid a buffer overrun by writing its
192	 * content.
193	 *
194	 * RESTRICTIONS:
195	 *
196	 * \r and \b work within one line because we are not able to modify
197	 * previous output that have already been accepted by the SCLP.
198	 *
199	 * \t combined with following \r is not correctly represented because
200	 * \t is expanded to some spaces but \r does not know about a
201	 * previous \t and decreases the current position by one column.
202	 * This is in order to a slim and quick implementation.
203	 */
204	for (i_msg = 0; i_msg < count; i_msg++) {
205		switch (msg[i_msg]) {
206		case '\n':	/* new line, line feed (ASCII)	*/
207			/* check if new mto needs to be created */
208			if (buffer->current_line == NULL) {
209				rc = sclp_initialize_mto(buffer, 0);
210				if (rc)
211					return i_msg;
212			}
213			sclp_finalize_mto(buffer);
214			break;
215		case '\a':	/* bell, one for several times	*/
216			/* set SCLP sound alarm bit in General Object */
217			if (buffer->current_line == NULL) {
218				rc = sclp_initialize_mto(buffer,
219							 buffer->columns);
220				if (rc)
221					return i_msg;
222			}
223			buffer->current_msg->mdb.go.general_msg_flags |=
224				GNRLMSGFLGS_SNDALRM;
225			break;
226		case '\t':	/* horizontal tabulator	 */
227			/* check if new mto needs to be created */
228			if (buffer->current_line == NULL) {
229				rc = sclp_initialize_mto(buffer,
230							 buffer->columns);
231				if (rc)
232					return i_msg;
233			}
234			/* "go to (next htab-boundary + 1, same line)" */
235			do {
236				if (buffer->current_length >= buffer->columns)
237					break;
238				/* ok, add a blank */
239				*buffer->current_line++ = 0x40;
240				buffer->current_length++;
241			} while (buffer->current_length % buffer->htab);
242			break;
243		case '\f':	/* form feed  */
244		case '\v':	/* vertical tabulator  */
245			/* "go to (actual column, actual line + 1)" */
246			/* = new line, leading spaces */
247			if (buffer->current_line != NULL) {
248				spaces = buffer->current_length;
249				sclp_finalize_mto(buffer);
250				rc = sclp_initialize_mto(buffer,
251							 buffer->columns);
252				if (rc)
253					return i_msg;
254				memset(buffer->current_line, 0x40, spaces);
255				buffer->current_line += spaces;
256				buffer->current_length = spaces;
257			} else {
258				/* one an empty line this is the same as \n */
259				rc = sclp_initialize_mto(buffer,
260							 buffer->columns);
261				if (rc)
262					return i_msg;
263				sclp_finalize_mto(buffer);
264			}
265			break;
266		case '\b':	/* backspace  */
267			/* "go to (actual column - 1, actual line)" */
268			/* decrement counter indicating position, */
269			/* do not remove last character */
270			if (buffer->current_line != NULL &&
271			    buffer->current_length > 0) {
272				buffer->current_length--;
273				buffer->current_line--;
274			}
275			break;
276		case 0x00:	/* end of string  */
277			/* transfer current line to SCCB */
278			if (buffer->current_line != NULL)
279				sclp_finalize_mto(buffer);
280			/* skip the rest of the message including the 0 byte */
281			i_msg = count - 1;
282			break;
283		default:	/* no escape character	*/
284			/* do not output unprintable characters */
285			if (!isprint(msg[i_msg]))
286				break;
287			/* check if new mto needs to be created */
288			if (buffer->current_line == NULL) {
289				rc = sclp_initialize_mto(buffer,
290							 buffer->columns);
291				if (rc)
292					return i_msg;
293			}
294			*buffer->current_line++ = sclp_ascebc(msg[i_msg]);
295			buffer->current_length++;
296			break;
297		}
298		/* check if current mto is full */
299		if (buffer->current_line != NULL &&
300		    buffer->current_length >= buffer->columns)
301			sclp_finalize_mto(buffer);
302	}
303
304	/* return number of processed characters */
305	return i_msg;
306}
307
308/*
309 * Return the number of free bytes in the sccb
310 */
311int
312sclp_buffer_space(struct sclp_buffer *buffer)
313{
314	struct sccb_header *sccb;
315	int count;
316
317	sccb = buffer->sccb;
318	count = MAX_SCCB_ROOM - sccb->length;
319	if (buffer->current_line != NULL)
320		count -= sizeof(struct msg_buf) + buffer->current_length;
321	return count;
322}
323
324/*
325 * Return number of characters in buffer
326 */
327int
328sclp_chars_in_buffer(struct sclp_buffer *buffer)
329{
330	int count;
331
332	count = buffer->char_sum;
333	if (buffer->current_line != NULL)
334		count += buffer->current_length;
335	return count;
336}
337
338/*
339 * sets or provides some values that influence the drivers behaviour
340 */
341void
342sclp_set_columns(struct sclp_buffer *buffer, unsigned short columns)
343{
344	buffer->columns = columns;
345	if (buffer->current_line != NULL &&
346	    buffer->current_length > buffer->columns)
347		sclp_finalize_mto(buffer);
348}
349
350void
351sclp_set_htab(struct sclp_buffer *buffer, unsigned short htab)
352{
353	buffer->htab = htab;
354}
355
356/*
357 * called by sclp_console_init and/or sclp_tty_init
358 */
359int
360sclp_rw_init(void)
361{
362	static int init_done = 0;
363	int rc;
364
365	if (init_done)
366		return 0;
367
368	rc = sclp_register(&sclp_rw_event);
369	if (rc == 0)
370		init_done = 1;
371	return rc;
372}
373
374#define SCLP_BUFFER_MAX_RETRY		1
375
376/*
377 * second half of Write Event Data-function that has to be done after
378 * interruption indicating completion of Service Call.
379 */
380static void
381sclp_writedata_callback(struct sclp_req *request, void *data)
382{
383	int rc;
384	struct sclp_buffer *buffer;
385	struct sccb_header *sccb;
386
387	buffer = (struct sclp_buffer *) data;
388	sccb = buffer->sccb;
389
390	if (request->status == SCLP_REQ_FAILED) {
391		if (buffer->callback != NULL)
392			buffer->callback(buffer, -EIO);
393		return;
394	}
395	/* check SCLP response code and choose suitable action	*/
396	switch (sccb->response_code) {
397	case 0x0020 :
398		/* Normal completion, buffer processed, message(s) sent */
399		rc = 0;
400		break;
401
402	case 0x0340: /* Contained SCLP equipment check */
403		if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
404			rc = -EIO;
405			break;
406		}
407		/* remove processed buffers and requeue rest */
408		if (sclp_remove_processed((struct sccb_header *) sccb) > 0) {
409			/* not all buffers were processed */
410			sccb->response_code = 0x0000;
411			buffer->request.status = SCLP_REQ_FILLED;
412			rc = sclp_add_request(request);
413			if (rc == 0)
414				return;
415		} else
416			rc = 0;
417		break;
418
419	case 0x0040: /* SCLP equipment check */
420	case 0x05f0: /* Target resource in improper state */
421		if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
422			rc = -EIO;
423			break;
424		}
425		/* retry request */
426		sccb->response_code = 0x0000;
427		buffer->request.status = SCLP_REQ_FILLED;
428		rc = sclp_add_request(request);
429		if (rc == 0)
430			return;
431		break;
432	default:
433		if (sccb->response_code == 0x71f0)
434			rc = -ENOMEM;
435		else
436			rc = -EINVAL;
437		break;
438	}
439	if (buffer->callback != NULL)
440		buffer->callback(buffer, rc);
441}
442
443/*
444 * Setup the request structure in the struct sclp_buffer to do SCLP Write
445 * Event Data and pass the request to the core SCLP loop. Return zero on
446 * success, non-zero otherwise.
447 */
448int
449sclp_emit_buffer(struct sclp_buffer *buffer,
450		 void (*callback)(struct sclp_buffer *, int))
451{
452	/* add current line if there is one */
453	if (buffer->current_line != NULL)
454		sclp_finalize_mto(buffer);
455
456	/* Are there messages in the output buffer ? */
457	if (buffer->messages == 0)
458		return -EIO;
459
460	buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA;
461	buffer->request.status = SCLP_REQ_FILLED;
462	buffer->request.callback = sclp_writedata_callback;
463	buffer->request.callback_data = buffer;
464	buffer->request.sccb = buffer->sccb;
465	buffer->callback = callback;
466	return sclp_add_request(&buffer->request);
467}
468