Statistics
| Branch: | Revision:

root / pc-bios / s390-ccw / sclp-ascii.c @ 0369b2eb

History | View | Annotate | Download (2 kB)

1
/*
2
 * SCLP ASCII access driver
3
 *
4
 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
5
 *
6
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
7
 * your option) any later version. See the COPYING file in the top-level
8
 * directory.
9
 */
10

    
11
#include "s390-ccw.h"
12
#include "sclp.h"
13

    
14
static char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096)));
15

    
16
/* Perform service call. Return 0 on success, non-zero otherwise. */
17
static int sclp_service_call(unsigned int command, void *sccb)
18
{
19
        int cc;
20

    
21
        asm volatile(
22
                "       .insn   rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
23
                "       ipm     %0\n"
24
                "       srl     %0,28"
25
                : "=&d" (cc) : "d" (command), "a" (__pa(sccb))
26
                : "cc", "memory");
27
        if (cc == 3)
28
                return -EIO;
29
        if (cc == 2)
30
                return -EBUSY;
31
        return 0;
32
}
33

    
34
static void sclp_set_write_mask(void)
35
{
36
    WriteEventMask *sccb = (void*)_sccb;
37

    
38
    sccb->h.length = sizeof(WriteEventMask);
39
    sccb->mask_length = sizeof(unsigned int);
40
    sccb->receive_mask = SCLP_EVENT_MASK_MSG_ASCII;
41
    sccb->cp_receive_mask = SCLP_EVENT_MASK_MSG_ASCII;
42
    sccb->send_mask = SCLP_EVENT_MASK_MSG_ASCII;
43
    sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII;
44

    
45
    sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK, sccb);
46
}
47

    
48
void sclp_setup(void)
49
{
50
    sclp_set_write_mask();
51
}
52

    
53
static int _strlen(const char *str)
54
{
55
    int i;
56
    for (i = 0; *str; i++)
57
        str++;
58
    return i;
59
}
60

    
61
static void _memcpy(char *dest, const char *src, int len)
62
{
63
    int i;
64
    for (i = 0; i < len; i++)
65
        dest[i] = src[i];
66
}
67

    
68
void sclp_print(const char *str)
69
{
70
    int len = _strlen(str);
71
    WriteEventData *sccb = (void*)_sccb;
72

    
73
    sccb->h.length = sizeof(WriteEventData) + len;
74
    sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
75
    sccb->ebh.length = sizeof(EventBufferHeader) + len;
76
    sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
77
    sccb->ebh.flags = 0;
78
    _memcpy(sccb->data, str, len);
79

    
80
    sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb);
81
}