Lines Matching +full:on +full:- +full:the +full:- +full:go
1 // SPDX-License-Identifier: GPL-2.0
3 * driver: reading from and writing to system console on S/390 via SCLP
23 * The room for the SCCB (only for writing) is not equal to a pages size
24 * (as it is specified as the maximum size in the SCLP documentation)
25 * because of the additional data structure described above.
27 #define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer))
36 * a pointer to a struct sclp_buffer structure that is located at the
37 * end of the input page. This reduces the buffer space by a few
48 * We keep the struct sclp_buffer structure at the end in sclp_make_buffer()
49 * of the sccb page. in sclp_make_buffer()
51 buffer = ((struct sclp_buffer *) ((addr_t) sccb + PAGE_SIZE)) - 1; in sclp_make_buffer()
52 buffer->sccb = sccb; in sclp_make_buffer()
53 buffer->retry_count = 0; in sclp_make_buffer()
54 buffer->messages = 0; in sclp_make_buffer()
55 buffer->char_sum = 0; in sclp_make_buffer()
56 buffer->current_line = NULL; in sclp_make_buffer()
57 buffer->current_length = 0; in sclp_make_buffer()
58 buffer->columns = columns; in sclp_make_buffer()
59 buffer->htab = htab; in sclp_make_buffer()
63 sccb->length = sizeof(struct sccb_header); in sclp_make_buffer()
69 * Return a pointer to the original page that has been used to create
70 * the buffer.
75 return buffer->sccb; in sclp_unmake_buffer()
79 * Initialize a new message the end of the provided buffer with
80 * enough room for max_len characters. Return 0 on success.
88 struct go *go; in sclp_initialize_mto() local
95 /* check if current buffer sccb can contain the mto */ in sclp_initialize_mto()
96 sccb = buffer->sccb; in sclp_initialize_mto()
97 if ((MAX_SCCB_ROOM - sccb->length) < msg_size) in sclp_initialize_mto()
98 return -ENOMEM; in sclp_initialize_mto()
100 msg = (struct msg_buf *)((addr_t) sccb + sccb->length); in sclp_initialize_mto()
102 msg->header.length = sizeof(struct msg_buf); in sclp_initialize_mto()
103 msg->header.type = EVTYP_MSG; in sclp_initialize_mto()
105 mdb = &msg->mdb; in sclp_initialize_mto()
106 mdb->header.length = sizeof(struct mdb); in sclp_initialize_mto()
107 mdb->header.type = 1; in sclp_initialize_mto()
108 mdb->header.tag = 0xD4C4C240; /* ebcdic "MDB " */ in sclp_initialize_mto()
109 mdb->header.revision_code = 1; in sclp_initialize_mto()
111 go = &mdb->go; in sclp_initialize_mto()
112 go->length = sizeof(struct go); in sclp_initialize_mto()
113 go->type = 1; in sclp_initialize_mto()
115 mto = &mdb->mto; in sclp_initialize_mto()
116 mto->length = sizeof(struct mto); in sclp_initialize_mto()
117 mto->type = 4; /* message text object */ in sclp_initialize_mto()
118 mto->line_type_flags = LNTPFLGS_ENDTEXT; /* end text */ in sclp_initialize_mto()
121 buffer->current_msg = msg; in sclp_initialize_mto()
122 buffer->current_line = (char *) (mto + 1); in sclp_initialize_mto()
123 buffer->current_length = 0; in sclp_initialize_mto()
130 * updating the sizes of MTO, enclosing MDB, event buffer and SCCB.
142 sccb = buffer->sccb; in sclp_finalize_mto()
143 msg = buffer->current_msg; in sclp_finalize_mto()
144 msg->header.length += buffer->current_length; in sclp_finalize_mto()
145 msg->mdb.header.length += buffer->current_length; in sclp_finalize_mto()
146 msg->mdb.mto.length += buffer->current_length; in sclp_finalize_mto()
147 sccb->length += msg->header.length; in sclp_finalize_mto()
152 * for the SCCB currently used for buffering and at all in sclp_finalize_mto()
154 buffer->messages++; in sclp_finalize_mto()
155 buffer->char_sum += buffer->current_length; in sclp_finalize_mto()
157 buffer->current_line = NULL; in sclp_finalize_mto()
158 buffer->current_length = 0; in sclp_finalize_mto()
159 buffer->current_msg = NULL; in sclp_finalize_mto()
164 * returns number of characters written to the output sccb
165 * ("processed" means that is not guaranteed that the character have already
166 * been sent to the SCLP but that it will be done at least next time the SCLP
180 * these characters on the native machine and only partial support in sclp_write()
181 * under VM (Why does VM interpret \n but the native machine doesn't ?) in sclp_write()
183 * Depending on i/o-control setting the message is always written in sclp_write()
184 * immediately or we wait for a final new line maybe coming with the in sclp_write()
191 * previous output that have already been accepted by the SCLP. in sclp_write()
195 * previous \t and decreases the current position by one column. in sclp_write()
202 if (buffer->current_line == NULL) { in sclp_write()
211 if (buffer->current_line == NULL) { in sclp_write()
213 buffer->columns); in sclp_write()
217 buffer->current_msg->mdb.go.general_msg_flags |= in sclp_write()
222 if (buffer->current_line == NULL) { in sclp_write()
224 buffer->columns); in sclp_write()
228 /* "go to (next htab-boundary + 1, same line)" */ in sclp_write()
230 if (buffer->current_length >= buffer->columns) in sclp_write()
233 *buffer->current_line++ = 0x40; in sclp_write()
234 buffer->current_length++; in sclp_write()
235 } while (buffer->current_length % buffer->htab); in sclp_write()
239 /* "go to (actual column, actual line + 1)" */ in sclp_write()
241 if (buffer->current_line != NULL) { in sclp_write()
242 spaces = buffer->current_length; in sclp_write()
245 buffer->columns); in sclp_write()
248 memset(buffer->current_line, 0x40, spaces); in sclp_write()
249 buffer->current_line += spaces; in sclp_write()
250 buffer->current_length = spaces; in sclp_write()
252 /* one an empty line this is the same as \n */ in sclp_write()
254 buffer->columns); in sclp_write()
261 /* "go to (actual column - 1, actual line)" */ in sclp_write()
264 if (buffer->current_line != NULL && in sclp_write()
265 buffer->current_length > 0) { in sclp_write()
266 buffer->current_length--; in sclp_write()
267 buffer->current_line--; in sclp_write()
272 if (buffer->current_line != NULL) in sclp_write()
274 /* skip the rest of the message including the 0 byte */ in sclp_write()
275 i_msg = count - 1; in sclp_write()
282 if (buffer->current_line == NULL) { in sclp_write()
284 buffer->columns); in sclp_write()
288 *buffer->current_line++ = sclp_ascebc(msg[i_msg]); in sclp_write()
289 buffer->current_length++; in sclp_write()
293 if (buffer->current_line != NULL && in sclp_write()
294 buffer->current_length >= buffer->columns) in sclp_write()
303 * Return the number of free bytes in the sccb
311 sccb = buffer->sccb; in sclp_buffer_space()
312 count = MAX_SCCB_ROOM - sccb->length; in sclp_buffer_space()
313 if (buffer->current_line != NULL) in sclp_buffer_space()
314 count -= sizeof(struct msg_buf) + buffer->current_length; in sclp_buffer_space()
326 count = buffer->char_sum; in sclp_chars_in_buffer()
327 if (buffer->current_line != NULL) in sclp_chars_in_buffer()
328 count += buffer->current_length; in sclp_chars_in_buffer()
353 * second half of Write Event Data-function that has to be done after
364 sccb = buffer->sccb; in sclp_writedata_callback()
366 if (request->status == SCLP_REQ_FAILED) { in sclp_writedata_callback()
367 if (buffer->callback != NULL) in sclp_writedata_callback()
368 buffer->callback(buffer, -EIO); in sclp_writedata_callback()
372 switch (sccb->response_code) { in sclp_writedata_callback()
379 if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) { in sclp_writedata_callback()
380 rc = -EIO; in sclp_writedata_callback()
386 sccb->response_code = 0x0000; in sclp_writedata_callback()
387 buffer->request.status = SCLP_REQ_FILLED; in sclp_writedata_callback()
397 if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) { in sclp_writedata_callback()
398 rc = -EIO; in sclp_writedata_callback()
402 sccb->response_code = 0x0000; in sclp_writedata_callback()
403 buffer->request.status = SCLP_REQ_FILLED; in sclp_writedata_callback()
409 if (sccb->response_code == 0x71f0) in sclp_writedata_callback()
410 rc = -ENOMEM; in sclp_writedata_callback()
412 rc = -EINVAL; in sclp_writedata_callback()
415 if (buffer->callback != NULL) in sclp_writedata_callback()
416 buffer->callback(buffer, rc); in sclp_writedata_callback()
420 * Setup the request structure in the struct sclp_buffer to do SCLP Write
421 * Event Data and pass the request to the core SCLP loop. Return zero on
422 * success, non-zero otherwise.
429 if (buffer->current_line != NULL) in sclp_emit_buffer()
432 /* Are there messages in the output buffer ? */ in sclp_emit_buffer()
433 if (buffer->messages == 0) in sclp_emit_buffer()
434 return -EIO; in sclp_emit_buffer()
436 buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA; in sclp_emit_buffer()
437 buffer->request.status = SCLP_REQ_FILLED; in sclp_emit_buffer()
438 buffer->request.callback = sclp_writedata_callback; in sclp_emit_buffer()
439 buffer->request.callback_data = buffer; in sclp_emit_buffer()
440 buffer->request.sccb = buffer->sccb; in sclp_emit_buffer()
441 buffer->callback = callback; in sclp_emit_buffer()
442 return sclp_add_request(&buffer->request); in sclp_emit_buffer()