File: /usr/src/linux/drivers/s390/char/tubttyaid.c

1     /*
2      *  IBM/3270 Driver -- Copyright (C) 2000 UTS Global LLC
3      *
4      *  tubttyaid.c -- Linemode Attention-ID functionality
5      *
6      *
7      *
8      *
9      *
10      *  Author:  Richard Hitt
11      */
12     #include "tubio.h"
13     
14     #define PA1_STR "^C"
15     #define PF3_STR "^D"
16     #define PF9_STR "\033j"
17     #define PF10_STR "\033k"
18     #define PF11_STR "\033j"
19     /* other AID-key default strings */
20     
21     aid_t aidtab[64] = {
22     /* 00         */	{ 0, 0 },
23     /* C1 = PF13  */	{ TA_DOSTRING, 0 },
24     /* C2 = PF14  */	{ TA_DOSTRING, 0 },
25     /* C3 = PF15  */	{ TA_DOSTRING, 0 },
26     /* C4 = PF16  */	{ TA_DOSTRING, 0 },
27     /* C5 = PF17  */	{ TA_DOSTRING, 0 },
28     /* C6 = PF18  */	{ TA_DOSTRING, 0 },
29     /* C7 = PF19  */	{ TA_DOSTRING, 0 },
30     /* C8 = PF20  */	{ TA_DOSTRING, 0 },
31     /* C9 = PF21  */	{ TA_DOSTRING, 0 },
32     /* 4A = PF22  */	{ TA_DOSTRING, 0 },
33     /* 4B = PF23  */	{ TA_DOSTRING, 0 },
34     /* 4C = PF24  */	{ TA_DOSTRING, 0 },
35     /* 0D         */	{ 0, 0 },
36     /* 0E         */	{ 0, 0 },
37     /* 0F         */	{ 0, 0 },
38     /* 10         */	{ 0, 0 },
39     /* 11         */	{ 0, 0 },
40     /* 12         */	{ 0, 0 },
41     /* 13         */	{ 0, 0 },
42     /* 14         */	{ 0, 0 },
43     /* 15         */	{ 0, 0 },
44     /* 16         */	{ 0, 0 },
45     /* 17         */	{ 0, 0 },
46     /* 18         */	{ 0, 0 },
47     /* 19         */	{ 0, 0 },
48     /* 1A         */	{ 0, 0 },
49     /* 1B         */	{ 0, 0 },
50     /* 1C         */	{ 0, 0 },
51     /* 1D         */	{ 0, 0 },
52     /* 1E         */	{ 0, 0 },
53     /* 1F         */	{ 0, 0 },
54     /* 60 = NoAID */	{ 0, 0 },
55     /* 21         */	{ 0, 0 },
56     /* 22         */	{ 0, 0 },
57     /* 23         */	{ 0, 0 },
58     /* 24         */	{ 0, 0 },
59     /* 25         */	{ 0, 0 },
60     /* E6 = OpRdr */	{ 0, 0 },
61     /* E7 = MSRdr */	{ 0, 0 },
62     /* E8 = NoAID */	{ 0, 0 },
63     /* 29         */	{ 0, 0 },
64     /* 2A         */	{ 0, 0 },
65     /* 6B =  PA3  */        { TA_SHORTREAD, 0 },
66     /* 6C =  PA1  */        { TA_SHORTREAD | TA_DOSTRING, PA1_STR },
67     /* 6D = CLEAR */        { TA_SHORTREAD | TA_CLEARKEY, 0 },
68     /* 6E =  PA2  */        { TA_SHORTREAD | TA_CLEARLOG, 0 },
69     /* 2F         */	{ 0, 0 },
70     /* F0 = TstRq */        { 0, 0 },
71     /* F1 =  PF1  */	{ TA_DOSTRING, 0 },
72     /* F2 =  PF2  */	{ TA_DOSTRING, 0 },
73     /* F3 =  PF3  */        { TA_DOSTRING, PF3_STR },
74     /* F4 =  PF4  */	{ TA_DOSTRING, 0 },
75     /* F5 =  PF5  */	{ TA_DOSTRING, 0 },
76     /* F6 =  PF6  */	{ TA_DOSTRING, 0 },
77     /* F7 =  PF7  */	{ TA_DOSTRING, 0 },
78     /* F8 =  PF8  */	{ TA_DOSTRING, 0 },
79     /* F9 =  PF9  */        { TA_DOSTRING, PF9_STR },
80     /* 7A = PF10  */        { TA_DOSTRING, PF10_STR },
81     /* 7B = PF11  */        { TA_DOSTRING, PF11_STR },
82     /* 7C = PF12  */	{ TA_DOSTRING, 0 },
83     /* 7D = ENTER */        { TA_DOENTER, 0 },
84     /* 7E = Pen   */        { 0, 0 },
85     /* 3F         */	{ 0, 0 },
86     };
87     
88     int
89     tty3270_aid_init(tub_t *tubp)
90     {
91     	memcpy(tubp->tty_aid, aidtab, sizeof aidtab);
92     	tubp->tty_aidinit = 1;
93     	return 0;
94     }
95     
96     void
97     tty3270_aid_fini(tub_t *tubp)
98     {
99     	int i;
100     	char *sp;
101     
102     	if (tubp->tty_aidinit == 0)
103     		return;
104     	for (i = 0; i < 64; i++) {
105     		if ((sp = tubp->tty_aid[i].string) == NULL)
106     			continue;
107     		if (sp == aidtab[i].string)
108     			continue;
109     		kfree(sp);
110     	}
111     	tubp->tty_aidinit = 0;
112     }
113     
114     void
115     tty3270_aid_reinit(tub_t *tubp)
116     {
117     	tty3270_aid_fini(tubp);
118     	tty3270_aid_init(tubp);
119     }
120     
121     int
122     tty3270_aid_get(tub_t *tubp, int aid, int *aidflags, char **aidstring)
123     {
124     	aid_t *ap;
125     
126     	ap = AIDENTRY(aid, tubp);
127     	*aidflags = ap->aid;
128     	*aidstring = ap->string;
129     	return 0;
130     }
131     
132     /*
133      * tty3270_aid_set() -- write_proc extension
134      * Parse written string as an AID name.  Return 0 if it's not.
135      * Otherwise absorb the string and return count or -error.
136      */
137     int
138     tty3270_aid_set(tub_t *tubp, char *buf, int count)
139     {
140     	char name[8];
141     	char *sp;
142     	int aidn, aidx;
143     	aid_t *ap;
144     	int len;
145     	char *pfp;
146     
147     	if (tubp->tty_aidinit == 0)
148     		return 0;
149     	if (count < 3)          /* If AID-key name too short */
150     		return 0;
151     	name[0] = buf[0] < 0x60? buf[0]: (buf[0] & 0x5f);
152     	name[1] = buf[1] < 0x60? buf[1]: (buf[1] & 0x5f);
153     	if (name[0] == 'P' && name[1] == 'F') {
154     		aidn = simple_strtoul(buf+2, &sp, 10);
155     		if (aidn < 1 || aidn > 24)
156     			return 0;
157     		aidx = aidn > 12? aidn - 12: aidn + 0x30;
158     		ap = &tubp->tty_aid[aidx];
159     	} else if (name[0] == 'P' && name[1] == 'A') {
160     		aidn = simple_strtoul(buf+2, &sp, 10);
161     		if (aidn < 1 || aidn > 3)
162     			return 0;
163     		switch(aidn) {
164     		case 1:  aidx = 0x2c; break;
165     		case 2:  aidx = 0x2e; break;
166     		case 3:  aidx = 0x2b; break;
167     		default:  aidx = 0; break;
168     		}
169     		ap = &tubp->tty_aid[aidx];
170     	} else {
171     		return 0;
172     	}
173     
174     	if (*sp == '\0') {
175     		tubp->tty_showaidx = ap - tubp->tty_aid;
176     		return count;
177     	} else if (*sp == '=') {
178     		len = strlen(++sp);
179     		if (len == 0) {
180     			if (ap->string != NULL &&
181     			    ap->string != aidtab[aidx].string)
182     				kfree(ap->string);
183     			ap->string = aidtab[aidx].string;
184     			ap->aid = aidtab[aidx].aid;
185     			return count;
186     		}
187     		if ((pfp = kmalloc(len + 1, GFP_KERNEL)) == NULL)
188     			return -ENOMEM;
189     		if (ap->string != NULL &&
190     		    ap->string != aidtab[aidx].string)
191     			kfree(ap->string);
192     		if (sp[len - 1] == '\n') {
193     			ap->aid = TA_DOSTRING;
194     			sp[len - 1] = '\0';
195     			len--;
196     		} else {
197     			ap->aid = TA_DOSTRINGD;
198     		}
199     		memcpy(pfp, sp, len + 1);
200     		ap->string = pfp;
201     		return count;
202     	} else {
203     		return -EINVAL;
204     	}
205     }
206