File: /usr/src/linux/drivers/s390/char/tubio.h
1 /*
2 * IBM/3270 Driver -- Copyright (C) 2000 UTS Global LLC
3 *
4 * tubio.h -- All-Purpose header file
5 *
6 *
7 *
8 *
9 *
10 * Author: Richard Hitt
11 */
12 #include <linux/config.h>
13
14 #include <linux/module.h>
15 #include <linux/version.h>
16
17 #include <linux/major.h>
18 #ifndef IBM_TTY3270_MAJOR
19 # define IBM_TTY3270_MAJOR 212
20 #endif /* IBM_TTY3270_MAJOR */
21 #ifndef IBM_FS3270_MAJOR
22 # define IBM_FS3270_MAJOR 213
23 #endif /* IBM_FS3270_MAJOR */
24
25
26 #include <linux/slab.h>
27 #include <asm/irq.h>
28 #include <asm/io.h>
29 #include <linux/console.h>
30 #include <linux/interrupt.h>
31 #include <asm/ebcdic.h>
32 #include <asm/uaccess.h>
33 #include <linux/proc_fs.h>
34 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
35 #include <linux/devfs_fs_kernel.h>
36 #endif
37
38 #define TUB(x) (('3'<<8)|(x))
39 #define TUBICMD TUB(3)
40 #define TUBOCMD TUB(4)
41 #define TUBGETI TUB(7)
42 #define TUBGETO TUB(8)
43 #define TUBSETMOD TUB(12)
44 #define TUBGETMOD TUB(13)
45 #define TIOPOLL TUB(32)
46 #define TIOPOKE TUB(33)
47 #define TIONPOKE TUB(34)
48 #define TIOTNORM TUB(35)
49
50 /* Local Channel Commands */
51 #define TC_WRITE 0x01
52 #define TC_EWRITE 0x05
53 #define TC_READMOD 0x06
54 #define TC_EWRITEA 0x0d
55 #define TC_WRITESF 0x11
56
57 /* Buffer Control Orders */
58 #define TO_SF 0x1d
59 #define TO_SBA 0x11
60 #define TO_IC 0x13
61 #define TO_PT 0x05
62 #define TO_RA 0x3c
63 #define TO_SFE 0x29
64 #define TO_EUA 0x12
65 #define TO_MF 0x2c
66 #define TO_SA 0x28
67
68 /* Field Attribute Bytes */
69 #define TF_INPUT 0x40 /* Visible input */
70 #define TF_INPUTN 0x4c /* Invisible input */
71 #define TF_INMDT 0xc1 /* Visible, Set-MDT */
72 #define TF_LOG 0x60
73 #define TF_STAT 0x60
74
75 /* Character Attribute Bytes */
76 #define TAT_RESET 0x00
77 #define TAT_FIELD 0xc0
78 #define TAT_EXTHI 0x41
79 #define TAT_COLOR 0x42
80 #define TAT_CHARS 0x43
81 #define TAT_TRANS 0x46
82
83 /* Reset value */
84 #define TAR_RESET 0x00
85
86 /* Color values */
87 #define TAC_BLUE 0xf1
88 #define TAC_RED 0xf2
89 #define TAC_PINK 0xf3
90 #define TAC_GREEN 0xf4
91 #define TAC_TURQ 0xf5
92 #define TAC_YELLOW 0xf6
93 #define TAC_WHITE 0xf7
94 #define TAC_DEFAULT 0x00
95
96 /* Write Control Characters */
97 #define TW_NONE 0x40 /* No particular action */
98 #define TW_KR 0xc2 /* Keyboard restore */
99 #define TW_PLUSALARM 0x04 /* Add this bit for alarm */
100
101 /* Attention-ID (AID) Characters */
102 #define TA_CLEAR 0x6d
103 #define TA_PA2 0x6e
104 #define TA_ENTER 0x7d
105 /* more to come */
106
107 #define MIN(a, b) ((a) < (b)? (a): (b))
108
109 #define TUB_BUFADR(adr, cpp) \
110 tty3270_tub_bufadr(tubp, adr, cpp)
111
112 #define TUB_EBCASC(addr, nr) codepage_convert(tub_ebcasc, addr, nr)
113 #define TUB_ASCEBC(addr, nr) codepage_convert(tub_ascebc, addr, nr)
114
115 /*
116 *
117 * General global values for the tube driver
118 *
119 */
120 enum tubmode {
121 TBM_LN, /* Line mode */
122 TBM_FS, /* Fullscreen mode */
123 TBM_FSLN /* Line mode shelled out of fullscreen */
124 };
125 enum tubstat { /* normal-mode status */
126 TBS_RUNNING, /* none of the following */
127 TBS_MORE, /* timed "MORE..." in status */
128 TBS_HOLD /* untimed "HOLDING" in status */
129 };
130 enum tubcmd { /* normal-mode actions to do */
131 TBC_CONOPEN, /* Erase-write the console */
132 TBC_OPEN, /* Open the tty screen */
133 TBC_UPDATE, /* Add lines to the log, clear cmdline */
134 TBC_UPDLOG, /* Add lines to log */
135 TBC_KRUPDLOG, /* Add lines to log, reset kbd */
136 TBC_CLEAR, /* Build screen from scratch */
137 TBC_CLRUPDLOG, /* Do log & status, not cmdline */
138 TBC_UPDSTAT, /* Do status update only */
139 TBC_CLRINPUT, /* Clear input area only */
140 TBC_UPDINPUT /* Update input area only */
141 };
142 enum tubwhat { /* echo what= proc actions */
143 TW_BOGUS, /* Nothing at all */
144 TW_CONFIG /* Output configuration info */
145 };
146
147
148
149
150
151 #define TUBMAXMINS 256
152 #define TUB_DEV MKDEV(IBM_FS3270_MAJ, 0) /* Generic /dev/3270/tub */
153 #define _GEOM_ROWS 24
154 #define _GEOM_COLS 80
155 #define GEOM_ROWS (tubp->geom_rows)
156 #define GEOM_COLS (tubp->geom_cols)
157 #define GEOM_MAXROWS 127
158 #define GEOM_MAXCOLS 132
159 #define GEOM_INPLEN (GEOM_COLS * 2 - 20)
160 #define GEOM_MAXINPLEN (GEOM_MAXCOLS * 2 - 20)
161 #define GEOM_INPUT (GEOM_COLS * (GEOM_ROWS - 2) - 1) /* input atr posn */
162 #define GEOM_STAT (GEOM_INPUT + 1 + GEOM_INPLEN)
163 #define GEOM_LOG (GEOM_COLS * GEOM_ROWS - 1) /* log atr posn */
164 #define TS_RUNNING "Linux Running "
165 #define TS_MORE "Linux More... "
166 #define DEFAULT_SCROLLTIME 5
167 #define TS_HOLD "Linux Holding "
168 /* data length used by tty3270_set_status_area: SBA (3), SF (2), data */
169 #define TS_LENGTH (sizeof TS_RUNNING + 3 + 2)
170
171 typedef struct {
172 int aid; /* What-to-do flags */
173 char *string; /* Optional input string */
174 } aid_t;
175 #define AIDENTRY(ch, tubp) (&((tubp)->tty_aid[(ch) & 0x3f]))
176
177 /* For TUBGETMOD and TUBSETMOD. Should include. */
178 typedef struct tubiocb {
179 short model;
180 short line_cnt;
181 short col_cnt;
182 short pf_cnt;
183 short re_cnt;
184 short map;
185 } tubiocb_t;
186
187 /* Flags that go in int aid, above */
188 #define TA_CLEARKEY 0x01 /* Key does hardware CLEAR */
189 #define TA_SHORTREAD 0x02 /* Key does hardware shortread */
190 /* If both are off, key does hardware Read Modified. */
191 #define TA_DOENTER 0x04 /* Treat key like ENTER */
192 #define TA_DOSTRING 0x08 /* Use string and ENTER */
193 #define TA_DOSTRINGD 0x10 /* Display string & set MDT */
194 #define TA_CLEARLOG 0x20 /* Make key cause clear of log */
195
196 /*
197 * Tube driver buffer control block
198 */
199 typedef struct bcb_s {
200 char *bc_buf; /* Pointer to buffer */
201 int bc_len; /* Length of buffer */
202 int bc_cnt; /* Count of bytes buffered */
203 int bc_wr; /* Posn to write next byte into */
204 int bc_rd; /* Posn to read next byte from */
205 } bcb_t;
206
207 typedef struct tub_s {
208 int minor;
209 int irq;
210 int irqrc;
211 int devno;
212 int geom_rows;
213 int geom_cols;
214 tubiocb_t tubiocb;
215 int lnopen;
216 int fsopen;
217 int icmd;
218 int ocmd;
219 devstat_t devstat;
220 ccw1_t rccw;
221 ccw1_t wccw;
222 void *wbuf;
223 int cswl;
224 void (*intv)(struct tub_s *, devstat_t *);
225 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
226 struct wait_queue *waitq;
227 #else
228 wait_queue_head_t waitq;
229 #endif
230 int dstat;
231 sense_t sense;
232 enum tubmode mode;
233 enum tubstat stat;
234 enum tubcmd cmd;
235 int flags; /* See below for values */
236 struct tq_struct tqueue;
237
238 /* Stuff for fs-driver support */
239 pid_t fs_pid; /* Pid if TBM_FS */
240
241
242 /* Stuff for tty-driver support */
243 struct tty_struct *tty;
244 char tty_input[GEOM_MAXINPLEN]; /* tty input area */
245 int tty_inattr; /* input-area field attribute */
246 #define TTY_OUTPUT_SIZE 1024
247 bcb_t tty_bcb; /* Output buffer control info */
248 int tty_oucol; /* Kludge */
249 int tty_nextlogx; /* next screen-log position */
250 int tty_scrolltime; /* scrollforward wait time, sec */
251 struct timer_list tty_stimer; /* timer for scrolltime */
252 aid_t tty_aid[64]; /* Aid descriptors */
253 int tty_aidinit; /* Boolean */
254 int tty_showaidx; /* Last aid x to set_aid */
255 int tty_14bitadr; /* 14-bit bufadrs okay */
256 #define MAX_TTY_ESCA 24 /* Set-Attribute-Order array */
257 char tty_esca[MAX_TTY_ESCA]; /* SA array */
258 int tty_escx; /* Current index within it */
259
260 /* For command recall --- */
261 char *(*tty_rclbufs)[]; /* Array of ptrs to recall bufs */
262 int tty_rclk; /* Size of array tty_rclbufs */
263 int tty_rclp; /* Index for most-recent cmd */
264 int tty_rclb; /* Index for backscrolling */
265
266 /* Work area to contain the hardware write stream */
267 char (*ttyscreen)[]; /* ptr to data stream area */
268 int ttyscreenl; /* its length */
269 ccw1_t ttyccw;
270 } tub_t;
271
272 /* values for flags: */
273 #define TUB_WORKING 0x0001
274 #define TUB_BHPENDING 0x0002
275 #define TUB_RDPENDING 0x0004
276 #define TUB_ALARM 0x0008
277 #define TUB_SCROLLTIMING 0x0010
278 #define TUB_ATTN 0x0020
279 #define TUB_IACTIVE 0x0040
280 #define TUB_SIZED 0x0080
281 #define TUB_EXPECT_DE 0x0100
282 #define TUB_UNSOL_DE 0x0200
283 #define TUB_OPEN_STET 0x0400 /* No screen clear on open */
284 #define TUB_UE_BUSY 0x0800
285 #define TUB_INPUT_HACK 0x1000 /* Early init of command line */
286
287 #ifdef CONFIG_TN3270_CONSOLE
288 /*
289 * Extra stuff for 3270 console support
290 */
291 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
292 #define S390_CONSOLE_DEV MKDEV(TTY_MAJOR, 64)
293 #else
294 #define S390_CONSOLE_DEV MKDEV(TTYAUX_MAJOR, 1)
295 #endif
296 extern int tub3270_con_devno;
297 extern char (*tub3270_con_output)[];
298 extern int tub3270_con_outputl;
299 extern int tub3270_con_ouwr;
300 extern int tub3270_con_oucount;
301 extern int tub3270_con_irq;
302 extern tub_t *tub3270_con_tubp;
303 extern struct tty_driver tty3270_con_driver;
304 #endif /* CONFIG_TN3270_CONSOLE */
305
306 extern int tubnummins;
307 extern tub_t *(*tubminors)[TUBMAXMINS];
308 extern tub_t *(*(*tubirqs)[256])[256];
309 extern unsigned char tub_ascebc[256];
310 extern unsigned char tub_ebcasc[256];
311 extern unsigned char tub_ebcgraf[64];
312 extern int tubdebug;
313 extern int fs3270_major;
314 extern int tty3270_major;
315 extern int tty3270_proc_misc;
316 extern enum tubwhat tty3270_proc_what;
317 extern struct tty_driver tty3270_driver;
318 #ifdef CONFIG_DEVFS_FS
319 extern devfs_handle_t fs3270_devfs_dir;
320 extern void fs3270_devfs_register(tub_t *);
321 extern void fs3270_devfs_unregister(tub_t *);
322 #endif
323
324 #ifndef spin_trylock_irqsave
325 #define spin_trylock_irqsave(lock, flags) \
326 ({ \
327 int success; \
328 __save_flags(flags); \
329 __cli(); \
330 success = spin_trylock(lock); \
331 if (success == 0) \
332 __restore_flags(flags); \
333 success; \
334 })
335 #endif /* if not spin_trylock_irqsave */
336
337 #ifndef s390irq_spin_trylock_irqsave
338 #define s390irq_spin_trylock_irqsave(irq, flags) \
339 spin_trylock_irqsave(&(ioinfo[irq]->irq_lock), flags)
340 #endif /* if not s390irq_spin_trylock_irqsave */
341
342 #define TUBLOCK(irq, flags) \
343 s390irq_spin_lock_irqsave(irq, flags)
344
345 #define TUBTRYLOCK(irq, flags) \
346 s390irq_spin_trylock_irqsave(irq, flags)
347
348 #define TUBUNLOCK(irq, flags) \
349 s390irq_spin_unlock_irqrestore(irq, flags)
350
351 /*
352 * Find tub_t * given fullscreen device's irq (subchannel number)
353 */
354 extern tub_t *tubfindbyirq(int);
355 #define IRQ2TUB(irq) tubfindbyirq(irq)
356 /*
357 * Find tub_t * given fullscreen device's inode pointer
358 * This algorithm takes into account /dev/3270/tub.
359 */
360 extern inline tub_t *INODE2TUB(struct inode *ip)
361 {
362 unsigned int minor = MINOR(ip->i_rdev);
363 tub_t *tubp = NULL;
364 if (minor == 0 && current->tty != NULL) {
365 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
366 #ifdef CONFIG_TN3270_CONSOLE
367 if (tub3270_con_tubp != NULL &&
368 current->tty->device == S390_CONSOLE_DEV)
369 minor = tub3270_con_tubp->minor;
370 else
371 #endif
372 #endif
373 if (MAJOR(current->tty->device) == IBM_TTY3270_MAJOR)
374 minor = MINOR(current->tty->device);
375 }
376 if (minor <= tubnummins && minor > 0)
377 tubp = (*tubminors)[minor];
378 return tubp;
379 }
380
381 /*
382 * Find tub_t * given non-fullscreen (tty) device's tty_struct pointer
383 */
384 extern inline tub_t *TTY2TUB(struct tty_struct *tty)
385 {
386 unsigned int minor = MINOR(tty->device);
387 tub_t *tubp = NULL;
388
389 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
390 #ifdef CONFIG_TN3270_CONSOLE
391 if (tty->device == S390_CONSOLE_DEV)
392 tubp = tub3270_con_tubp;
393 else
394 #endif
395 #endif
396 if (minor <= tubnummins && minor > 0)
397 tubp = (*tubminors)[minor];
398 return tubp;
399 }
400
401 extern void tub_inc_use_count(void);
402 extern void tub_dec_use_count(void);
403 extern int tub3270_movedata(bcb_t *, bcb_t *, int);
404 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
405 extern int tubmakemin(int, dev_info_t *);
406 #else
407 extern int tubmakemin(int, s390_dev_info_t *);
408 #endif
409 extern int tub3270_con_copy(tub_t *);
410 extern int tty3270_rcl_init(tub_t *);
411 extern int tty3270_rcl_set(tub_t *, char *, int);
412 extern void tty3270_rcl_fini(tub_t *);
413 extern int tty3270_rcl_get(tub_t *, char *, int, int);
414 extern void tty3270_rcl_put(tub_t *, char *, int);
415 extern void tty3270_rcl_sync(tub_t *);
416 extern void tty3270_rcl_purge(tub_t *);
417 extern int tty3270_rcl_resize(tub_t *, int);
418 extern int tty3270_size(tub_t *, long *);
419 extern int tty3270_aid_init(tub_t *);
420 extern void tty3270_aid_fini(tub_t *);
421 extern void tty3270_aid_reinit(tub_t *);
422 extern int tty3270_aid_get(tub_t *, int, int *, char **);
423 extern int tty3270_aid_set(tub_t *, char *, int);
424 extern int tty3270_build(tub_t *);
425 extern void tty3270_scl_settimer(tub_t *);
426 extern void tty3270_scl_resettimer(tub_t *);
427 extern int tty3270_scl_set(tub_t *, char *, int);
428 extern int tty3270_scl_init(tub_t *tubp);
429 extern void tty3270_scl_fini(tub_t *tubp);
430