summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/s390/char/sclp_rw.c
diff options
context:
space:
mode:
authorJosé Pekkarinen <jose.pekkarinen@nokia.com>2016-04-11 10:41:07 +0300
committerJosé Pekkarinen <jose.pekkarinen@nokia.com>2016-04-13 08:17:18 +0300
commite09b41010ba33a20a87472ee821fa407a5b8da36 (patch)
treed10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/s390/char/sclp_rw.c
parentf93b97fd65072de626c074dbe099a1fff05ce060 (diff)
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page. During the rebasing, the following patch collided: Force tick interrupt and get rid of softirq magic(I70131fb85). Collisions have been removed because its logic was found on the source already. Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769 Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/s390/char/sclp_rw.c')
-rw-r--r--kernel/drivers/s390/char/sclp_rw.c136
1 files changed, 67 insertions, 69 deletions
diff --git a/kernel/drivers/s390/char/sclp_rw.c b/kernel/drivers/s390/char/sclp_rw.c
index 35a84af87..6010cd347 100644
--- a/kernel/drivers/s390/char/sclp_rw.c
+++ b/kernel/drivers/s390/char/sclp_rw.c
@@ -47,9 +47,9 @@ struct sclp_buffer *
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 @@ sclp_make_buffer(void *page, unsigned short columns, unsigned short htab)
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 @@ sclp_unmake_buffer(struct sclp_buffer *buffer)
}
/*
- * 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;
- /*
- * fill the new Message-Text Object,
- * starting behind the former last byte of the SCCB
- */
- memset(mto, 0, sizeof(struct mto));
+ 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;
+
+ 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 @@ sclp_initialize_mto(struct sclp_buffer *buffer, int max_len)
}
/*
- * 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 @@ sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
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 @@ sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
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 @@ sclp_chars_in_buffer(struct sclp_buffer *buffer)
{
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 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
{
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 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
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 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
/* 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 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
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,25 +449,19 @@ int
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;
- /* Use normal write message */
- sccb->msg_buf.header.type = EVTYP_MSG;
-
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);
}