--- zzzz-none-000/linux-3.10.107/drivers/s390/char/sclp_rw.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/s390/char/sclp_rw.c 2021-02-04 17:41:59.000000000 +0000 @@ -33,7 +33,7 @@ /* Event type structure for write message and write priority message */ static struct sclp_register sclp_rw_event = { - .send_mask = EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK, + .send_mask = EVTYP_MSG_MASK, .pm_event_fn = sclp_rw_pm_event, }; @@ -47,9 +47,9 @@ sclp_make_buffer(void *page, unsigned short columns, unsigned short htab) { struct sclp_buffer *buffer; - struct write_sccb *sccb; + struct sccb_header *sccb; - sccb = (struct write_sccb *) page; + sccb = (struct sccb_header *) page; /* * We keep the struct sclp_buffer structure at the end * of the sccb page. @@ -57,24 +57,16 @@ buffer = ((struct sclp_buffer *) ((addr_t) sccb + PAGE_SIZE)) - 1; buffer->sccb = sccb; buffer->retry_count = 0; - buffer->mto_number = 0; - buffer->mto_char_sum = 0; + buffer->messages = 0; + buffer->char_sum = 0; buffer->current_line = NULL; buffer->current_length = 0; buffer->columns = columns; buffer->htab = htab; /* initialize sccb */ - memset(sccb, 0, sizeof(struct write_sccb)); - sccb->header.length = sizeof(struct write_sccb); - sccb->msg_buf.header.length = sizeof(struct msg_buf); - sccb->msg_buf.header.type = EVTYP_MSG; - sccb->msg_buf.mdb.header.length = sizeof(struct mdb); - sccb->msg_buf.mdb.header.type = 1; - sccb->msg_buf.mdb.header.tag = 0xD4C4C240; /* ebcdic "MDB " */ - sccb->msg_buf.mdb.header.revision_code = 1; - sccb->msg_buf.mdb.go.length = sizeof(struct go); - sccb->msg_buf.mdb.go.type = 1; + memset(sccb, 0, sizeof(struct sccb_header)); + sccb->length = sizeof(struct sccb_header); return buffer; } @@ -90,37 +82,49 @@ } /* - * Initialize a new Message Text Object (MTO) at the end of the provided buffer - * with enough room for max_len characters. Return 0 on success. + * Initialize a new message the end of the provided buffer with + * enough room for max_len characters. Return 0 on success. */ static int sclp_initialize_mto(struct sclp_buffer *buffer, int max_len) { - struct write_sccb *sccb; + struct sccb_header *sccb; + struct msg_buf *msg; + struct mdb *mdb; + struct go *go; struct mto *mto; - int mto_size; + int msg_size; - /* max size of new Message Text Object including message text */ - mto_size = sizeof(struct mto) + max_len; + /* max size of new message including message text */ + msg_size = sizeof(struct msg_buf) + max_len; /* check if current buffer sccb can contain the mto */ sccb = buffer->sccb; - if ((MAX_SCCB_ROOM - sccb->header.length) < mto_size) + if ((MAX_SCCB_ROOM - sccb->length) < msg_size) return -ENOMEM; - /* find address of new message text object */ - mto = (struct mto *)(((addr_t) sccb) + sccb->header.length); + msg = (struct msg_buf *)((addr_t) sccb + sccb->length); + memset(msg, 0, sizeof(struct msg_buf)); + msg->header.length = sizeof(struct msg_buf); + msg->header.type = EVTYP_MSG; + + mdb = &msg->mdb; + mdb->header.length = sizeof(struct mdb); + mdb->header.type = 1; + mdb->header.tag = 0xD4C4C240; /* ebcdic "MDB " */ + mdb->header.revision_code = 1; + + go = &mdb->go; + go->length = sizeof(struct go); + go->type = 1; - /* - * fill the new Message-Text Object, - * starting behind the former last byte of the SCCB - */ - memset(mto, 0, sizeof(struct mto)); + mto = &mdb->mto; mto->length = sizeof(struct mto); mto->type = 4; /* message text object */ mto->line_type_flags = LNTPFLGS_ENDTEXT; /* end text */ /* set pointer to first byte after struct mto. */ + buffer->current_msg = msg; buffer->current_line = (char *) (mto + 1); buffer->current_length = 0; @@ -128,45 +132,37 @@ } /* - * Finalize MTO initialized by sclp_initialize_mto(), updating the sizes of - * MTO, enclosing MDB, event buffer and SCCB. + * Finalize message initialized by sclp_initialize_mto(), + * updating the sizes of MTO, enclosing MDB, event buffer and SCCB. */ static void sclp_finalize_mto(struct sclp_buffer *buffer) { - struct write_sccb *sccb; - struct mto *mto; - int str_len, mto_size; - - str_len = buffer->current_length; - buffer->current_line = NULL; - buffer->current_length = 0; - - /* real size of new Message Text Object including message text */ - mto_size = sizeof(struct mto) + str_len; - - /* find address of new message text object */ - sccb = buffer->sccb; - mto = (struct mto *)(((addr_t) sccb) + sccb->header.length); - - /* set size of message text object */ - mto->length = mto_size; + struct sccb_header *sccb; + struct msg_buf *msg; /* * update values of sizes * (SCCB, Event(Message) Buffer, Message Data Block) */ - sccb->header.length += mto_size; - sccb->msg_buf.header.length += mto_size; - sccb->msg_buf.mdb.header.length += mto_size; + sccb = buffer->sccb; + msg = buffer->current_msg; + msg->header.length += buffer->current_length; + msg->mdb.header.length += buffer->current_length; + msg->mdb.mto.length += buffer->current_length; + sccb->length += msg->header.length; /* * count number of buffered messages (= number of Message Text * Objects) and number of buffered characters * for the SCCB currently used for buffering and at all */ - buffer->mto_number++; - buffer->mto_char_sum += str_len; + buffer->messages++; + buffer->char_sum += buffer->current_length; + + buffer->current_line = NULL; + buffer->current_length = 0; + buffer->current_msg = NULL; } /* @@ -218,7 +214,13 @@ break; case '\a': /* bell, one for several times */ /* set SCLP sound alarm bit in General Object */ - buffer->sccb->msg_buf.mdb.go.general_msg_flags |= + if (buffer->current_line == NULL) { + rc = sclp_initialize_mto(buffer, + buffer->columns); + if (rc) + return i_msg; + } + buffer->current_msg->mdb.go.general_msg_flags |= GNRLMSGFLGS_SNDALRM; break; case '\t': /* horizontal tabulator */ @@ -309,11 +311,13 @@ int sclp_buffer_space(struct sclp_buffer *buffer) { + struct sccb_header *sccb; int count; - count = MAX_SCCB_ROOM - buffer->sccb->header.length; + sccb = buffer->sccb; + count = MAX_SCCB_ROOM - sccb->length; if (buffer->current_line != NULL) - count -= sizeof(struct mto) + buffer->current_length; + count -= sizeof(struct msg_buf) + buffer->current_length; return count; } @@ -325,7 +329,7 @@ { int count; - count = buffer->mto_char_sum; + count = buffer->char_sum; if (buffer->current_line != NULL) count += buffer->current_length; return count; @@ -378,7 +382,7 @@ { int rc; struct sclp_buffer *buffer; - struct write_sccb *sccb; + struct sccb_header *sccb; buffer = (struct sclp_buffer *) data; sccb = buffer->sccb; @@ -389,7 +393,7 @@ return; } /* check SCLP response code and choose suitable action */ - switch (sccb->header.response_code) { + switch (sccb->response_code) { case 0x0020 : /* Normal completion, buffer processed, message(s) sent */ rc = 0; @@ -403,7 +407,7 @@ /* remove processed buffers and requeue rest */ if (sclp_remove_processed((struct sccb_header *) sccb) > 0) { /* not all buffers were processed */ - sccb->header.response_code = 0x0000; + sccb->response_code = 0x0000; buffer->request.status = SCLP_REQ_FILLED; rc = sclp_add_request(request); if (rc == 0) @@ -419,14 +423,14 @@ break; } /* retry request */ - sccb->header.response_code = 0x0000; + sccb->response_code = 0x0000; buffer->request.status = SCLP_REQ_FILLED; rc = sclp_add_request(request); if (rc == 0) return; break; default: - if (sccb->header.response_code == 0x71f0) + if (sccb->response_code == 0x71f0) rc = -ENOMEM; else rc = -EINVAL; @@ -445,30 +449,19 @@ sclp_emit_buffer(struct sclp_buffer *buffer, void (*callback)(struct sclp_buffer *, int)) { - struct write_sccb *sccb; - /* add current line if there is one */ if (buffer->current_line != NULL) sclp_finalize_mto(buffer); /* Are there messages in the output buffer ? */ - if (buffer->mto_number == 0) + if (buffer->messages == 0) return -EIO; - sccb = buffer->sccb; - if (sclp_rw_event.sclp_receive_mask & EVTYP_MSG_MASK) - /* Use normal write message */ - sccb->msg_buf.header.type = EVTYP_MSG; - else if (sclp_rw_event.sclp_receive_mask & EVTYP_PMSGCMD_MASK) - /* Use write priority message */ - sccb->msg_buf.header.type = EVTYP_PMSGCMD; - else - return -EOPNOTSUPP; buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA; buffer->request.status = SCLP_REQ_FILLED; buffer->request.callback = sclp_writedata_callback; buffer->request.callback_data = buffer; - buffer->request.sccb = sccb; + buffer->request.sccb = buffer->sccb; buffer->callback = callback; return sclp_add_request(&buffer->request); }