These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / s390 / char / sclp_rw.c
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
28 static 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 */
35 static 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  */
46 struct sclp_buffer *
47 sclp_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  */
78 void *
79 sclp_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  */
88 static int
89 sclp_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  */
138 static void
139 sclp_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  */
175 int
176 sclp_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  */
311 int
312 sclp_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  */
327 int
328 sclp_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  */
341 void
342 sclp_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
350 void
351 sclp_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  */
359 int
360 sclp_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  */
380 static void
381 sclp_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  */
448 int
449 sclp_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 }