more changes on original files
[linux-2.4.git] / 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 }