xref: /linux/drivers/s390/char/raw3270.c (revision 2624f124b3b5d550ab2fbef7ee3bc0e1fed09722)
1 /*
2  *  drivers/s390/char/raw3270.c
3  *    IBM/3270 Driver - core functions.
4  *
5  *  Author(s):
6  *    Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7  *    Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8  *	-- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
9  */
10 
11 #include <linux/config.h>
12 #include <linux/bootmem.h>
13 #include <linux/module.h>
14 #include <linux/err.h>
15 #include <linux/init.h>
16 #include <linux/interrupt.h>
17 #include <linux/list.h>
18 #include <linux/slab.h>
19 #include <linux/types.h>
20 #include <linux/wait.h>
21 
22 #include <asm/ccwdev.h>
23 #include <asm/cio.h>
24 #include <asm/ebcdic.h>
25 
26 #include "raw3270.h"
27 
28 /* The main 3270 data structure. */
29 struct raw3270 {
30 	struct list_head list;
31 	struct ccw_device *cdev;
32 	int minor;
33 
34 	short model, rows, cols;
35 	unsigned long flags;
36 
37 	struct list_head req_queue;	/* Request queue. */
38 	struct list_head view_list;	/* List of available views. */
39 	struct raw3270_view *view;	/* Active view. */
40 
41 	struct timer_list timer;	/* Device timer. */
42 
43 	unsigned char *ascebc;		/* ascii -> ebcdic table */
44 };
45 
46 /* raw3270->flags */
47 #define RAW3270_FLAGS_14BITADDR	0	/* 14-bit buffer addresses */
48 #define RAW3270_FLAGS_BUSY	1	/* Device busy, leave it alone */
49 #define RAW3270_FLAGS_ATTN	2	/* Device sent an ATTN interrupt */
50 #define RAW3270_FLAGS_READY	4	/* Device is useable by views */
51 #define RAW3270_FLAGS_CONSOLE	8	/* Device is the console. */
52 
53 /* Semaphore to protect global data of raw3270 (devices, views, etc). */
54 static DECLARE_MUTEX(raw3270_sem);
55 
56 /* List of 3270 devices. */
57 static struct list_head raw3270_devices = LIST_HEAD_INIT(raw3270_devices);
58 
59 /*
60  * Flag to indicate if the driver has been registered. Some operations
61  * like waiting for the end of i/o need to be done differently as long
62  * as the kernel is still starting up (console support).
63  */
64 static int raw3270_registered;
65 
66 /* Module parameters */
67 static int tubxcorrect = 0;
68 module_param(tubxcorrect, bool, 0);
69 
70 /*
71  * Wait queue for device init/delete, view delete.
72  */
73 DECLARE_WAIT_QUEUE_HEAD(raw3270_wait_queue);
74 
75 /*
76  * Encode array for 12 bit 3270 addresses.
77  */
78 unsigned char raw3270_ebcgraf[64] =	{
79 	0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
80 	0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
81 	0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
82 	0xd8, 0xd9, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
83 	0x60, 0x61, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
84 	0xe8, 0xe9, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
85 	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
86 	0xf8, 0xf9, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
87 };
88 
89 void
90 raw3270_buffer_address(struct raw3270 *rp, char *cp, unsigned short addr)
91 {
92 	if (test_bit(RAW3270_FLAGS_14BITADDR, &rp->flags)) {
93 		cp[0] = (addr >> 8) & 0x3f;
94 		cp[1] = addr & 0xff;
95 	} else {
96 		cp[0] = raw3270_ebcgraf[(addr >> 6) & 0x3f];
97 		cp[1] = raw3270_ebcgraf[addr & 0x3f];
98 	}
99 }
100 
101 /*
102  * Allocate a new 3270 ccw request
103  */
104 struct raw3270_request *
105 raw3270_request_alloc(size_t size)
106 {
107 	struct raw3270_request *rq;
108 
109 	/* Allocate request structure */
110 	rq = kmalloc(sizeof(struct raw3270_request), GFP_KERNEL | GFP_DMA);
111 	if (!rq)
112 		return ERR_PTR(-ENOMEM);
113 	memset(rq, 0, sizeof(struct raw3270_request));
114 
115 	/* alloc output buffer. */
116 	if (size > 0) {
117 		rq->buffer = kmalloc(size, GFP_KERNEL | GFP_DMA);
118 		if (!rq->buffer) {
119 			kfree(rq);
120 			return ERR_PTR(-ENOMEM);
121 		}
122 	}
123 	rq->size = size;
124 	INIT_LIST_HEAD(&rq->list);
125 
126 	/*
127 	 * Setup ccw.
128 	 */
129 	rq->ccw.cda = __pa(rq->buffer);
130 	rq->ccw.flags = CCW_FLAG_SLI;
131 
132 	return rq;
133 }
134 
135 #ifdef CONFIG_TN3270_CONSOLE
136 /*
137  * Allocate a new 3270 ccw request from bootmem. Only works very
138  * early in the boot process. Only con3270.c should be using this.
139  */
140 struct raw3270_request *
141 raw3270_request_alloc_bootmem(size_t size)
142 {
143 	struct raw3270_request *rq;
144 
145 	rq = alloc_bootmem_low(sizeof(struct raw3270));
146 	if (!rq)
147 		return ERR_PTR(-ENOMEM);
148 	memset(rq, 0, sizeof(struct raw3270_request));
149 
150 	/* alloc output buffer. */
151 	if (size > 0) {
152 		rq->buffer = alloc_bootmem_low(size);
153 		if (!rq->buffer) {
154 			free_bootmem((unsigned long) rq,
155 				     sizeof(struct raw3270));
156 			return ERR_PTR(-ENOMEM);
157 		}
158 	}
159 	rq->size = size;
160 	INIT_LIST_HEAD(&rq->list);
161 
162 	/*
163 	 * Setup ccw.
164 	 */
165 	rq->ccw.cda = __pa(rq->buffer);
166 	rq->ccw.flags = CCW_FLAG_SLI;
167 
168 	return rq;
169 }
170 #endif
171 
172 /*
173  * Free 3270 ccw request
174  */
175 void
176 raw3270_request_free (struct raw3270_request *rq)
177 {
178 	if (rq->buffer)
179 		kfree(rq->buffer);
180 	kfree(rq);
181 }
182 
183 /*
184  * Reset request to initial state.
185  */
186 void
187 raw3270_request_reset(struct raw3270_request *rq)
188 {
189 	BUG_ON(!list_empty(&rq->list));
190 	rq->ccw.cmd_code = 0;
191 	rq->ccw.count = 0;
192 	rq->ccw.cda = __pa(rq->buffer);
193 	rq->ccw.flags = CCW_FLAG_SLI;
194 	rq->rescnt = 0;
195 	rq->rc = 0;
196 }
197 
198 /*
199  * Set command code to ccw of a request.
200  */
201 void
202 raw3270_request_set_cmd(struct raw3270_request *rq, u8 cmd)
203 {
204 	rq->ccw.cmd_code = cmd;
205 }
206 
207 /*
208  * Add data fragment to output buffer.
209  */
210 int
211 raw3270_request_add_data(struct raw3270_request *rq, void *data, size_t size)
212 {
213 	if (size + rq->ccw.count > rq->size)
214 		return -E2BIG;
215 	memcpy(rq->buffer + rq->ccw.count, data, size);
216 	rq->ccw.count += size;
217 	return 0;
218 }
219 
220 /*
221  * Set address/length pair to ccw of a request.
222  */
223 void
224 raw3270_request_set_data(struct raw3270_request *rq, void *data, size_t size)
225 {
226 	rq->ccw.cda = __pa(data);
227 	rq->ccw.count = size;
228 }
229 
230 /*
231  * Set idal buffer to ccw of a request.
232  */
233 void
234 raw3270_request_set_idal(struct raw3270_request *rq, struct idal_buffer *ib)
235 {
236 	rq->ccw.cda = __pa(ib->data);
237 	rq->ccw.count = ib->size;
238 	rq->ccw.flags |= CCW_FLAG_IDA;
239 }
240 
241 /*
242  * Stop running ccw.
243  */
244 static int
245 raw3270_halt_io_nolock(struct raw3270 *rp, struct raw3270_request *rq)
246 {
247 	int retries;
248 	int rc;
249 
250 	if (raw3270_request_final(rq))
251 		return 0;
252 	/* Check if interrupt has already been processed */
253 	for (retries = 0; retries < 5; retries++) {
254 		if (retries < 2)
255 			rc = ccw_device_halt(rp->cdev, (long) rq);
256 		else
257 			rc = ccw_device_clear(rp->cdev, (long) rq);
258 		if (rc == 0)
259 			break;		/* termination successful */
260 	}
261 	return rc;
262 }
263 
264 static int
265 raw3270_halt_io(struct raw3270 *rp, struct raw3270_request *rq)
266 {
267 	unsigned long flags;
268 	int rc;
269 
270 	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
271 	rc = raw3270_halt_io_nolock(rp, rq);
272 	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
273 	return rc;
274 }
275 
276 /*
277  * Add the request to the request queue, try to start it if the
278  * 3270 device is idle. Return without waiting for end of i/o.
279  */
280 static int
281 __raw3270_start(struct raw3270 *rp, struct raw3270_view *view,
282 		struct raw3270_request *rq)
283 {
284 	rq->view = view;
285 	raw3270_get_view(view);
286 	if (list_empty(&rp->req_queue) &&
287 	    !test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
288 		/* No other requests are on the queue. Start this one. */
289 		rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
290 					       (unsigned long) rq, 0, 0);
291 		if (rq->rc) {
292 			raw3270_put_view(view);
293 			return rq->rc;
294 		}
295 	}
296 	list_add_tail(&rq->list, &rp->req_queue);
297 	return 0;
298 }
299 
300 int
301 raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
302 {
303 	unsigned long flags;
304 	struct raw3270 *rp;
305 	int rc;
306 
307 	spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
308 	rp = view->dev;
309 	if (!rp || rp->view != view)
310 		rc = -EACCES;
311 	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
312 		rc = -ENODEV;
313 	else
314 		rc =  __raw3270_start(rp, view, rq);
315 	spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags);
316 	return rc;
317 }
318 
319 int
320 raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
321 {
322 	struct raw3270 *rp;
323 
324 	rp = view->dev;
325 	rq->view = view;
326 	raw3270_get_view(view);
327 	list_add_tail(&rq->list, &rp->req_queue);
328 	return 0;
329 }
330 
331 /*
332  * 3270 interrupt routine, called from the ccw_device layer
333  */
334 static void
335 raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
336 {
337 	struct raw3270 *rp;
338 	struct raw3270_view *view;
339 	struct raw3270_request *rq;
340 	int rc;
341 
342 	rp = (struct raw3270 *) cdev->dev.driver_data;
343 	if (!rp)
344 		return;
345 	rq = (struct raw3270_request *) intparm;
346 	view = rq ? rq->view : rp->view;
347 
348 	if (IS_ERR(irb))
349 		rc = RAW3270_IO_RETRY;
350 	else if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
351 		rq->rc = -EIO;
352 		rc = RAW3270_IO_DONE;
353 	} else if (irb->scsw.dstat ==  (DEV_STAT_CHN_END | DEV_STAT_DEV_END |
354 					DEV_STAT_UNIT_EXCEP)) {
355 		/* Handle CE-DE-UE and subsequent UDE */
356 		set_bit(RAW3270_FLAGS_BUSY, &rp->flags);
357 		rc = RAW3270_IO_BUSY;
358 	} else if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
359 		/* Wait for UDE if busy flag is set. */
360 		if (irb->scsw.dstat & DEV_STAT_DEV_END) {
361 			clear_bit(RAW3270_FLAGS_BUSY, &rp->flags);
362 			/* Got it, now retry. */
363 			rc = RAW3270_IO_RETRY;
364 		} else
365 			rc = RAW3270_IO_BUSY;
366 	} else if (view)
367 		rc = view->fn->intv(view, rq, irb);
368 	else
369 		rc = RAW3270_IO_DONE;
370 
371 	switch (rc) {
372 	case RAW3270_IO_DONE:
373 		break;
374 	case RAW3270_IO_BUSY:
375 		/*
376 		 * Intervention required by the operator. We have to wait
377 		 * for unsolicited device end.
378 		 */
379 		return;
380 	case RAW3270_IO_RETRY:
381 		if (!rq)
382 			break;
383 		rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
384 					  (unsigned long) rq, 0, 0);
385 		if (rq->rc == 0)
386 			return;	/* Sucessfully restarted. */
387 		break;
388 	case RAW3270_IO_STOP:
389 		if (!rq)
390 			break;
391 		raw3270_halt_io_nolock(rp, rq);
392 		rq->rc = -EIO;
393 		break;
394 	default:
395 		BUG();
396 	}
397 	if (rq) {
398 		BUG_ON(list_empty(&rq->list));
399 		/* The request completed, remove from queue and do callback. */
400 		list_del_init(&rq->list);
401 		if (rq->callback)
402 			rq->callback(rq, rq->callback_data);
403 		/* Do put_device for get_device in raw3270_start. */
404 		raw3270_put_view(view);
405 	}
406 	/*
407 	 * Try to start each request on request queue until one is
408 	 * started successful.
409 	 */
410 	while (!list_empty(&rp->req_queue)) {
411 		rq = list_entry(rp->req_queue.next,struct raw3270_request,list);
412 		rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
413 					  (unsigned long) rq, 0, 0);
414 		if (rq->rc == 0)
415 			break;
416 		/* Start failed. Remove request and do callback. */
417 		list_del_init(&rq->list);
418 		if (rq->callback)
419 			rq->callback(rq, rq->callback_data);
420 		/* Do put_device for get_device in raw3270_start. */
421 		raw3270_put_view(view);
422 	}
423 }
424 
425 /*
426  * Size sensing.
427  */
428 
429 struct raw3270_ua {	/* Query Reply structure for Usable Area */
430 	struct {	/* Usable Area Query Reply Base */
431 		short l;	/* Length of this structured field */
432 		char  sfid;	/* 0x81 if Query Reply */
433 		char  qcode;	/* 0x81 if Usable Area */
434 		char  flags0;
435 		char  flags1;
436 		short w;	/* Width of usable area */
437 		short h;	/* Heigth of usavle area */
438 		char  units;	/* 0x00:in; 0x01:mm */
439 		int   xr;
440 		int   yr;
441 		char  aw;
442 		char  ah;
443 		short buffsz;	/* Character buffer size, bytes */
444 		char  xmin;
445 		char  ymin;
446 		char  xmax;
447 		char  ymax;
448 	} __attribute__ ((packed)) uab;
449 	struct {	/* Alternate Usable Area Self-Defining Parameter */
450 		char  l;	/* Length of this Self-Defining Parm */
451 		char  sdpid;	/* 0x02 if Alternate Usable Area */
452 		char  res;
453 		char  auaid;	/* 0x01 is Id for the A U A */
454 		short wauai;	/* Width of AUAi */
455 		short hauai;	/* Height of AUAi */
456 		char  auaunits;	/* 0x00:in, 0x01:mm */
457 		int   auaxr;
458 		int   auayr;
459 		char  awauai;
460 		char  ahauai;
461 	} __attribute__ ((packed)) aua;
462 } __attribute__ ((packed));
463 
464 static unsigned char raw3270_init_data[256];
465 static struct raw3270_request raw3270_init_request;
466 static struct diag210 raw3270_init_diag210;
467 static DECLARE_MUTEX(raw3270_init_sem);
468 
469 static int
470 raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
471 		 struct irb *irb)
472 {
473 	/*
474 	 * Unit-Check Processing:
475 	 * Expect Command Reject or Intervention Required.
476 	 */
477 	if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {
478 		/* Request finished abnormally. */
479 		if (irb->ecw[0] & SNS0_INTERVENTION_REQ) {
480 			set_bit(RAW3270_FLAGS_BUSY, &view->dev->flags);
481 			return RAW3270_IO_BUSY;
482 		}
483 	}
484 	if (rq) {
485 		if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {
486 			if (irb->ecw[0] & SNS0_CMD_REJECT)
487 				rq->rc = -EOPNOTSUPP;
488 			else
489 				rq->rc = -EIO;
490 		} else
491 			/* Request finished normally. Copy residual count. */
492 			rq->rescnt = irb->scsw.count;
493 	}
494 	if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
495 		set_bit(RAW3270_FLAGS_ATTN, &view->dev->flags);
496 		wake_up(&raw3270_wait_queue);
497 	}
498 	return RAW3270_IO_DONE;
499 }
500 
501 static struct raw3270_fn raw3270_init_fn = {
502 	.intv = raw3270_init_irq
503 };
504 
505 static struct raw3270_view raw3270_init_view = {
506 	.fn = &raw3270_init_fn
507 };
508 
509 /*
510  * raw3270_wait/raw3270_wait_interruptible/__raw3270_wakeup
511  * Wait for end of request. The request must have been started
512  * with raw3270_start, rc = 0. The device lock may NOT have been
513  * released between calling raw3270_start and raw3270_wait.
514  */
515 static void
516 raw3270_wake_init(struct raw3270_request *rq, void *data)
517 {
518 	wake_up((wait_queue_head_t *) data);
519 }
520 
521 /*
522  * Special wait function that can cope with console initialization.
523  */
524 static int
525 raw3270_start_init(struct raw3270 *rp, struct raw3270_view *view,
526 		   struct raw3270_request *rq)
527 {
528 	unsigned long flags;
529 	wait_queue_head_t wq;
530 	int rc;
531 
532 #ifdef CONFIG_TN3270_CONSOLE
533 	if (raw3270_registered == 0) {
534 		spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
535 		rq->callback = 0;
536 		rc = __raw3270_start(rp, view, rq);
537 		if (rc == 0)
538 			while (!raw3270_request_final(rq)) {
539 				wait_cons_dev();
540 				barrier();
541 			}
542 		spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags);
543 		return rq->rc;
544 	}
545 #endif
546 	init_waitqueue_head(&wq);
547 	rq->callback = raw3270_wake_init;
548 	rq->callback_data = &wq;
549 	spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
550 	rc = __raw3270_start(rp, view, rq);
551 	spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags);
552 	if (rc)
553 		return rc;
554 	/* Now wait for the completion. */
555 	rc = wait_event_interruptible(wq, raw3270_request_final(rq));
556 	if (rc == -ERESTARTSYS) {	/* Interrupted by a signal. */
557 		raw3270_halt_io(view->dev, rq);
558 		/* No wait for the halt to complete. */
559 		wait_event(wq, raw3270_request_final(rq));
560 		return -ERESTARTSYS;
561 	}
562 	return rq->rc;
563 }
564 
565 static int
566 __raw3270_size_device_vm(struct raw3270 *rp)
567 {
568 	int rc, model;
569 
570 	raw3270_init_diag210.vrdcdvno =
571 		_ccw_device_get_device_number(rp->cdev);
572 	raw3270_init_diag210.vrdclen = sizeof(struct diag210);
573 	rc = diag210(&raw3270_init_diag210);
574 	if (rc)
575 		return rc;
576 	model = raw3270_init_diag210.vrdccrmd;
577 	switch (model) {
578 	case 2:
579 		rp->model = model;
580 		rp->rows = 24;
581 		rp->cols = 80;
582 		break;
583 	case 3:
584 		rp->model = model;
585 		rp->rows = 32;
586 		rp->cols = 80;
587 		break;
588 	case 4:
589 		rp->model = model;
590 		rp->rows = 43;
591 		rp->cols = 80;
592 		break;
593 	case 5:
594 		rp->model = model;
595 		rp->rows = 27;
596 		rp->cols = 132;
597 		break;
598 	default:
599 		printk(KERN_WARNING "vrdccrmd is 0x%.8x\n", model);
600 		rc = -EOPNOTSUPP;
601 		break;
602 	}
603 	return rc;
604 }
605 
606 static int
607 __raw3270_size_device(struct raw3270 *rp)
608 {
609 	static const unsigned char wbuf[] =
610 		{ 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 };
611 	struct raw3270_ua *uap;
612 	unsigned short count;
613 	int rc;
614 
615 	/*
616 	 * To determine the size of the 3270 device we need to do:
617 	 * 1) send a 'read partition' data stream to the device
618 	 * 2) wait for the attn interrupt that preceeds the query reply
619 	 * 3) do a read modified to get the query reply
620 	 * To make things worse we have to cope with intervention
621 	 * required (3270 device switched to 'stand-by') and command
622 	 * rejects (old devices that can't do 'read partition').
623 	 */
624 	memset(&raw3270_init_request, 0, sizeof(raw3270_init_request));
625 	memset(raw3270_init_data, 0, sizeof(raw3270_init_data));
626 	/* Store 'read partition' data stream to raw3270_init_data */
627 	memcpy(raw3270_init_data, wbuf, sizeof(wbuf));
628 	INIT_LIST_HEAD(&raw3270_init_request.list);
629 	raw3270_init_request.ccw.cmd_code = TC_WRITESF;
630 	raw3270_init_request.ccw.flags = CCW_FLAG_SLI;
631 	raw3270_init_request.ccw.count = sizeof(wbuf);
632 	raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data);
633 
634 	rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request);
635 	if (rc)
636 		/* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */
637 		return rc;
638 
639 	/* Wait for attention interrupt. */
640 #ifdef CONFIG_TN3270_CONSOLE
641 	if (raw3270_registered == 0) {
642 		unsigned long flags;
643 
644 		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
645 		while (!test_and_clear_bit(RAW3270_FLAGS_ATTN, &rp->flags))
646 			wait_cons_dev();
647 		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
648 	} else
649 #endif
650 		rc = wait_event_interruptible(raw3270_wait_queue,
651 			test_and_clear_bit(RAW3270_FLAGS_ATTN, &rp->flags));
652 	if (rc)
653 		return rc;
654 
655 	/*
656 	 * The device accepted the 'read partition' command. Now
657 	 * set up a read ccw and issue it.
658 	 */
659 	raw3270_init_request.ccw.cmd_code = TC_READMOD;
660 	raw3270_init_request.ccw.flags = CCW_FLAG_SLI;
661 	raw3270_init_request.ccw.count = sizeof(raw3270_init_data);
662 	raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data);
663 	rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request);
664 	if (rc)
665 		return rc;
666 	/* Got a Query Reply */
667 	count = sizeof(raw3270_init_data) - raw3270_init_request.rescnt;
668 	uap = (struct raw3270_ua *) (raw3270_init_data + 1);
669 	/* Paranoia check. */
670 	if (raw3270_init_data[0] != 0x88 || uap->uab.qcode != 0x81)
671 		return -EOPNOTSUPP;
672 	/* Copy rows/columns of default Usable Area */
673 	rp->rows = uap->uab.h;
674 	rp->cols = uap->uab.w;
675 	/* Check for 14 bit addressing */
676 	if ((uap->uab.flags0 & 0x0d) == 0x01)
677 		set_bit(RAW3270_FLAGS_14BITADDR, &rp->flags);
678 	/* Check for Alternate Usable Area */
679 	if (uap->uab.l == sizeof(struct raw3270_ua) &&
680 	    uap->aua.sdpid == 0x02) {
681 		rp->rows = uap->aua.hauai;
682 		rp->cols = uap->aua.wauai;
683 	}
684 	return 0;
685 }
686 
687 static int
688 raw3270_size_device(struct raw3270 *rp)
689 {
690 	int rc;
691 
692 	down(&raw3270_init_sem);
693 	rp->view = &raw3270_init_view;
694 	raw3270_init_view.dev = rp;
695 	if (MACHINE_IS_VM)
696 		rc = __raw3270_size_device_vm(rp);
697 	else
698 		rc = __raw3270_size_device(rp);
699 	raw3270_init_view.dev = 0;
700 	rp->view = 0;
701 	up(&raw3270_init_sem);
702 	if (rc == 0) {	/* Found something. */
703 		/* Try to find a model. */
704 		rp->model = 0;
705 		if (rp->rows == 24 && rp->cols == 80)
706 			rp->model = 2;
707 		if (rp->rows == 32 && rp->cols == 80)
708 			rp->model = 3;
709 		if (rp->rows == 43 && rp->cols == 80)
710 			rp->model = 4;
711 		if (rp->rows == 27 && rp->cols == 132)
712 			rp->model = 5;
713 	} else {
714 		/* Couldn't detect size. Use default model 2. */
715 		rp->model = 2;
716 		rp->rows = 24;
717 		rp->cols = 80;
718 		return 0;
719 	}
720 	return rc;
721 }
722 
723 static int
724 raw3270_reset_device(struct raw3270 *rp)
725 {
726 	int rc;
727 
728 	down(&raw3270_init_sem);
729 	memset(&raw3270_init_request, 0, sizeof(raw3270_init_request));
730 	memset(raw3270_init_data, 0, sizeof(raw3270_init_data));
731 	/* Store reset data stream to raw3270_init_data/raw3270_init_request */
732 	raw3270_init_data[0] = TW_KR;
733 	INIT_LIST_HEAD(&raw3270_init_request.list);
734 	raw3270_init_request.ccw.cmd_code = TC_EWRITEA;
735 	raw3270_init_request.ccw.flags = CCW_FLAG_SLI;
736 	raw3270_init_request.ccw.count = 1;
737 	raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data);
738 	rp->view = &raw3270_init_view;
739 	raw3270_init_view.dev = rp;
740 	rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request);
741 	raw3270_init_view.dev = 0;
742 	rp->view = 0;
743 	up(&raw3270_init_sem);
744 	return rc;
745 }
746 
747 /*
748  * Setup new 3270 device.
749  */
750 static int
751 raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
752 {
753 	struct list_head *l;
754 	struct raw3270 *tmp;
755 	int minor;
756 
757 	memset(rp, 0, sizeof(struct raw3270));
758 	/* Copy ebcdic -> ascii translation table. */
759 	memcpy(ascebc, _ascebc, 256);
760 	if (tubxcorrect) {
761 		/* correct brackets and circumflex */
762 		ascebc['['] = 0xad;
763 		ascebc[']'] = 0xbd;
764 		ascebc['^'] = 0xb0;
765 	}
766 	rp->ascebc = ascebc;
767 
768 	/* Set defaults. */
769 	rp->rows = 24;
770 	rp->cols = 80;
771 
772 	INIT_LIST_HEAD(&rp->req_queue);
773 	INIT_LIST_HEAD(&rp->view_list);
774 
775 	/*
776 	 * Add device to list and find the smallest unused minor
777 	 * number for it.
778 	 */
779 	down(&raw3270_sem);
780 	/* Keep the list sorted. */
781 	minor = 0;
782 	rp->minor = -1;
783 	list_for_each(l, &raw3270_devices) {
784 		tmp = list_entry(l, struct raw3270, list);
785 		if (tmp->minor > minor) {
786 			rp->minor = minor;
787 			__list_add(&rp->list, l->prev, l);
788 			break;
789 		}
790 		minor++;
791 	}
792 	if (rp->minor == -1 && minor < RAW3270_MAXDEVS) {
793 		rp->minor = minor;
794 		list_add_tail(&rp->list, &raw3270_devices);
795 	}
796 	up(&raw3270_sem);
797 	/* No free minor number? Then give up. */
798 	if (rp->minor == -1)
799 		return -EUSERS;
800 	rp->cdev = cdev;
801 	cdev->dev.driver_data = rp;
802 	cdev->handler = raw3270_irq;
803 	return 0;
804 }
805 
806 #ifdef CONFIG_TN3270_CONSOLE
807 /*
808  * Setup 3270 device configured as console.
809  */
810 struct raw3270 *
811 raw3270_setup_console(struct ccw_device *cdev)
812 {
813 	struct raw3270 *rp;
814 	char *ascebc;
815 	int rc;
816 
817 	rp = (struct raw3270 *) alloc_bootmem(sizeof(struct raw3270));
818 	ascebc = (char *) alloc_bootmem(256);
819 	rc = raw3270_setup_device(cdev, rp, ascebc);
820 	if (rc)
821 		return ERR_PTR(rc);
822 	set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags);
823 	rc = raw3270_reset_device(rp);
824 	if (rc)
825 		return ERR_PTR(rc);
826 	rc = raw3270_size_device(rp);
827 	if (rc)
828 		return ERR_PTR(rc);
829 	rc = raw3270_reset_device(rp);
830 	if (rc)
831 		return ERR_PTR(rc);
832 	set_bit(RAW3270_FLAGS_READY, &rp->flags);
833 	return rp;
834 }
835 
836 void
837 raw3270_wait_cons_dev(struct raw3270 *rp)
838 {
839 	unsigned long flags;
840 
841 	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
842 	wait_cons_dev();
843 	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
844 }
845 
846 #endif
847 
848 /*
849  * Create a 3270 device structure.
850  */
851 static struct raw3270 *
852 raw3270_create_device(struct ccw_device *cdev)
853 {
854 	struct raw3270 *rp;
855 	char *ascebc;
856 	int rc;
857 
858 	rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL);
859 	if (!rp)
860 		return ERR_PTR(-ENOMEM);
861 	ascebc = kmalloc(256, GFP_KERNEL);
862 	if (!ascebc) {
863 		kfree(rp);
864 		return ERR_PTR(-ENOMEM);
865 	}
866 	rc = raw3270_setup_device(cdev, rp, ascebc);
867 	if (rc) {
868 		kfree(rp->ascebc);
869 		kfree(rp);
870 		rp = ERR_PTR(rc);
871 	}
872 	/* Get reference to ccw_device structure. */
873 	get_device(&cdev->dev);
874 	return rp;
875 }
876 
877 /*
878  * Activate a view.
879  */
880 int
881 raw3270_activate_view(struct raw3270_view *view)
882 {
883 	struct raw3270 *rp;
884 	struct raw3270_view *oldview, *nv;
885 	unsigned long flags;
886 	int rc;
887 
888 	rp = view->dev;
889 	if (!rp)
890 		return -ENODEV;
891 	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
892 	if (rp->view == view)
893 		rc = 0;
894 	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
895 		rc = -ENODEV;
896 	else {
897 		oldview = 0;
898 		if (rp->view) {
899 			oldview = rp->view;
900 			oldview->fn->deactivate(oldview);
901 		}
902 		rp->view = view;
903 		rc = view->fn->activate(view);
904 		if (rc) {
905 			/* Didn't work. Try to reactivate the old view. */
906 			rp->view = oldview;
907 			if (!oldview || oldview->fn->activate(oldview) != 0) {
908 				/* Didn't work as well. Try any other view. */
909 				list_for_each_entry(nv, &rp->view_list, list)
910 					if (nv != view && nv != oldview) {
911 						rp->view = nv;
912 						if (nv->fn->activate(nv) == 0)
913 							break;
914 						rp->view = 0;
915 					}
916 			}
917 		}
918 	}
919 	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
920 	return rc;
921 }
922 
923 /*
924  * Deactivate current view.
925  */
926 void
927 raw3270_deactivate_view(struct raw3270_view *view)
928 {
929 	unsigned long flags;
930 	struct raw3270 *rp;
931 
932 	rp = view->dev;
933 	if (!rp)
934 		return;
935 	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
936 	if (rp->view == view) {
937 		view->fn->deactivate(view);
938 		rp->view = 0;
939 		/* Move deactivated view to end of list. */
940 		list_del_init(&view->list);
941 		list_add_tail(&view->list, &rp->view_list);
942 		/* Try to activate another view. */
943 		if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
944 			list_for_each_entry(view, &rp->view_list, list)
945 				if (view->fn->activate(view) == 0) {
946 					rp->view = view;
947 					break;
948 				}
949 		}
950 	}
951 	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
952 }
953 
954 /*
955  * Add view to device with minor "minor".
956  */
957 int
958 raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
959 {
960 	unsigned long flags;
961 	struct raw3270 *rp;
962 	int rc;
963 
964 	down(&raw3270_sem);
965 	rc = -ENODEV;
966 	list_for_each_entry(rp, &raw3270_devices, list) {
967 		if (rp->minor != minor)
968 			continue;
969 		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
970 		if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
971 			atomic_set(&view->ref_count, 2);
972 			view->dev = rp;
973 			view->fn = fn;
974 			view->model = rp->model;
975 			view->rows = rp->rows;
976 			view->cols = rp->cols;
977 			view->ascebc = rp->ascebc;
978 			spin_lock_init(&view->lock);
979 			list_add_tail(&view->list, &rp->view_list);
980 			rc = 0;
981 		}
982 		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
983 		break;
984 	}
985 	up(&raw3270_sem);
986 	return rc;
987 }
988 
989 /*
990  * Find specific view of device with minor "minor".
991  */
992 struct raw3270_view *
993 raw3270_find_view(struct raw3270_fn *fn, int minor)
994 {
995 	struct raw3270 *rp;
996 	struct raw3270_view *view, *tmp;
997 	unsigned long flags;
998 
999 	down(&raw3270_sem);
1000 	view = ERR_PTR(-ENODEV);
1001 	list_for_each_entry(rp, &raw3270_devices, list) {
1002 		if (rp->minor != minor)
1003 			continue;
1004 		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1005 		if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
1006 			view = ERR_PTR(-ENOENT);
1007 			list_for_each_entry(tmp, &rp->view_list, list) {
1008 				if (tmp->fn == fn) {
1009 					raw3270_get_view(tmp);
1010 					view = tmp;
1011 					break;
1012 				}
1013 			}
1014 		}
1015 		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1016 		break;
1017 	}
1018 	up(&raw3270_sem);
1019 	return view;
1020 }
1021 
1022 /*
1023  * Remove view from device and free view structure via call to view->fn->free.
1024  */
1025 void
1026 raw3270_del_view(struct raw3270_view *view)
1027 {
1028 	unsigned long flags;
1029 	struct raw3270 *rp;
1030 	struct raw3270_view *nv;
1031 
1032 	rp = view->dev;
1033 	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1034 	if (rp->view == view) {
1035 		view->fn->deactivate(view);
1036 		rp->view = 0;
1037 	}
1038 	list_del_init(&view->list);
1039 	if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
1040 		/* Try to activate another view. */
1041 		list_for_each_entry(nv, &rp->view_list, list) {
1042 			if (nv->fn->activate(view) == 0) {
1043 				rp->view = nv;
1044 				break;
1045 			}
1046 		}
1047 	}
1048 	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1049 	/* Wait for reference counter to drop to zero. */
1050 	atomic_dec(&view->ref_count);
1051 	wait_event(raw3270_wait_queue, atomic_read(&view->ref_count) == 0);
1052 	if (view->fn->free)
1053 		view->fn->free(view);
1054 }
1055 
1056 /*
1057  * Remove a 3270 device structure.
1058  */
1059 static void
1060 raw3270_delete_device(struct raw3270 *rp)
1061 {
1062 	struct ccw_device *cdev;
1063 
1064 	/* Remove from device chain. */
1065 	down(&raw3270_sem);
1066 	list_del_init(&rp->list);
1067 	up(&raw3270_sem);
1068 
1069 	/* Disconnect from ccw_device. */
1070 	cdev = rp->cdev;
1071 	rp->cdev = 0;
1072 	cdev->dev.driver_data = 0;
1073 	cdev->handler = 0;
1074 
1075 	/* Put ccw_device structure. */
1076 	put_device(&cdev->dev);
1077 
1078 	/* Now free raw3270 structure. */
1079 	kfree(rp->ascebc);
1080 	kfree(rp);
1081 }
1082 
1083 static int
1084 raw3270_probe (struct ccw_device *cdev)
1085 {
1086 	return 0;
1087 }
1088 
1089 /*
1090  * Additional attributes for a 3270 device
1091  */
1092 static ssize_t
1093 raw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf)
1094 {
1095 	return snprintf(buf, PAGE_SIZE, "%i\n",
1096 			((struct raw3270 *) dev->driver_data)->model);
1097 }
1098 static DEVICE_ATTR(model, 0444, raw3270_model_show, 0);
1099 
1100 static ssize_t
1101 raw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf)
1102 {
1103 	return snprintf(buf, PAGE_SIZE, "%i\n",
1104 			((struct raw3270 *) dev->driver_data)->rows);
1105 }
1106 static DEVICE_ATTR(rows, 0444, raw3270_rows_show, 0);
1107 
1108 static ssize_t
1109 raw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf)
1110 {
1111 	return snprintf(buf, PAGE_SIZE, "%i\n",
1112 			((struct raw3270 *) dev->driver_data)->cols);
1113 }
1114 static DEVICE_ATTR(columns, 0444, raw3270_columns_show, 0);
1115 
1116 static struct attribute * raw3270_attrs[] = {
1117 	&dev_attr_model.attr,
1118 	&dev_attr_rows.attr,
1119 	&dev_attr_columns.attr,
1120 	NULL,
1121 };
1122 
1123 static struct attribute_group raw3270_attr_group = {
1124 	.attrs = raw3270_attrs,
1125 };
1126 
1127 static void
1128 raw3270_create_attributes(struct raw3270 *rp)
1129 {
1130 	//FIXME: check return code
1131 	sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
1132 }
1133 
1134 /*
1135  * Notifier for device addition/removal
1136  */
1137 struct raw3270_notifier {
1138 	struct list_head list;
1139 	void (*notifier)(int, int);
1140 };
1141 
1142 static struct list_head raw3270_notifier = LIST_HEAD_INIT(raw3270_notifier);
1143 
1144 int raw3270_register_notifier(void (*notifier)(int, int))
1145 {
1146 	struct raw3270_notifier *np;
1147 	struct raw3270 *rp;
1148 
1149 	np = kmalloc(sizeof(struct raw3270_notifier), GFP_KERNEL);
1150 	if (!np)
1151 		return -ENOMEM;
1152 	np->notifier = notifier;
1153 	down(&raw3270_sem);
1154 	list_add_tail(&np->list, &raw3270_notifier);
1155 	list_for_each_entry(rp, &raw3270_devices, list) {
1156 		get_device(&rp->cdev->dev);
1157 		notifier(rp->minor, 1);
1158 	}
1159 	up(&raw3270_sem);
1160 	return 0;
1161 }
1162 
1163 void raw3270_unregister_notifier(void (*notifier)(int, int))
1164 {
1165 	struct raw3270_notifier *np;
1166 
1167 	down(&raw3270_sem);
1168 	list_for_each_entry(np, &raw3270_notifier, list)
1169 		if (np->notifier == notifier) {
1170 			list_del(&np->list);
1171 			kfree(np);
1172 			break;
1173 		}
1174 	up(&raw3270_sem);
1175 }
1176 
1177 /*
1178  * Set 3270 device online.
1179  */
1180 static int
1181 raw3270_set_online (struct ccw_device *cdev)
1182 {
1183 	struct raw3270 *rp;
1184 	struct raw3270_notifier *np;
1185 	int rc;
1186 
1187 	rp = raw3270_create_device(cdev);
1188 	if (IS_ERR(rp))
1189 		return PTR_ERR(rp);
1190 	rc = raw3270_reset_device(rp);
1191 	if (rc)
1192 		return rc;
1193 	rc = raw3270_size_device(rp);
1194 	if (rc)
1195 		return rc;
1196 	rc = raw3270_reset_device(rp);
1197 	if (rc)
1198 		return rc;
1199 	raw3270_create_attributes(rp);
1200 	set_bit(RAW3270_FLAGS_READY, &rp->flags);
1201 	down(&raw3270_sem);
1202 	list_for_each_entry(np, &raw3270_notifier, list)
1203 		np->notifier(rp->minor, 1);
1204 	up(&raw3270_sem);
1205 	return 0;
1206 }
1207 
1208 /*
1209  * Remove 3270 device structure.
1210  */
1211 static void
1212 raw3270_remove (struct ccw_device *cdev)
1213 {
1214 	unsigned long flags;
1215 	struct raw3270 *rp;
1216 	struct raw3270_view *v;
1217 	struct raw3270_notifier *np;
1218 
1219 	rp = cdev->dev.driver_data;
1220 	clear_bit(RAW3270_FLAGS_READY, &rp->flags);
1221 
1222 	sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
1223 
1224 	/* Deactivate current view and remove all views. */
1225 	spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1226 	if (rp->view) {
1227 		rp->view->fn->deactivate(rp->view);
1228 		rp->view = 0;
1229 	}
1230 	while (!list_empty(&rp->view_list)) {
1231 		v = list_entry(rp->view_list.next, struct raw3270_view, list);
1232 		if (v->fn->release)
1233 			v->fn->release(v);
1234 		spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1235 		raw3270_del_view(v);
1236 		spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1237 	}
1238 	spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1239 
1240 	down(&raw3270_sem);
1241 	list_for_each_entry(np, &raw3270_notifier, list)
1242 		np->notifier(rp->minor, 0);
1243 	up(&raw3270_sem);
1244 
1245 	/* Reset 3270 device. */
1246 	raw3270_reset_device(rp);
1247 	/* And finally remove it. */
1248 	raw3270_delete_device(rp);
1249 }
1250 
1251 /*
1252  * Set 3270 device offline.
1253  */
1254 static int
1255 raw3270_set_offline (struct ccw_device *cdev)
1256 {
1257 	struct raw3270 *rp;
1258 
1259 	rp = cdev->dev.driver_data;
1260 	if (test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags))
1261 		return -EBUSY;
1262 	raw3270_remove(cdev);
1263 	return 0;
1264 }
1265 
1266 static struct ccw_device_id raw3270_id[] = {
1267 	{ CCW_DEVICE(0x3270, 0) },
1268 	{ CCW_DEVICE(0x3271, 0) },
1269 	{ CCW_DEVICE(0x3272, 0) },
1270 	{ CCW_DEVICE(0x3273, 0) },
1271 	{ CCW_DEVICE(0x3274, 0) },
1272 	{ CCW_DEVICE(0x3275, 0) },
1273 	{ CCW_DEVICE(0x3276, 0) },
1274 	{ CCW_DEVICE(0x3277, 0) },
1275 	{ CCW_DEVICE(0x3278, 0) },
1276 	{ CCW_DEVICE(0x3279, 0) },
1277 	{ CCW_DEVICE(0x3174, 0) },
1278 	{ /* end of list */ },
1279 };
1280 
1281 static struct ccw_driver raw3270_ccw_driver = {
1282 	.name		= "3270",
1283 	.owner		= THIS_MODULE,
1284 	.ids		= raw3270_id,
1285 	.probe		= &raw3270_probe,
1286 	.remove		= &raw3270_remove,
1287 	.set_online	= &raw3270_set_online,
1288 	.set_offline	= &raw3270_set_offline,
1289 };
1290 
1291 static int
1292 raw3270_init(void)
1293 {
1294 	struct raw3270 *rp;
1295 	int rc;
1296 
1297 	if (raw3270_registered)
1298 		return 0;
1299 	raw3270_registered = 1;
1300 	rc = ccw_driver_register(&raw3270_ccw_driver);
1301 	if (rc == 0) {
1302 		/* Create attributes for early (= console) device. */
1303 		down(&raw3270_sem);
1304 		list_for_each_entry(rp, &raw3270_devices, list) {
1305 			get_device(&rp->cdev->dev);
1306 			raw3270_create_attributes(rp);
1307 		}
1308 		up(&raw3270_sem);
1309 	}
1310 	return rc;
1311 }
1312 
1313 static void
1314 raw3270_exit(void)
1315 {
1316 	ccw_driver_unregister(&raw3270_ccw_driver);
1317 }
1318 
1319 MODULE_LICENSE("GPL");
1320 
1321 module_init(raw3270_init);
1322 module_exit(raw3270_exit);
1323 
1324 EXPORT_SYMBOL(raw3270_request_alloc);
1325 EXPORT_SYMBOL(raw3270_request_free);
1326 EXPORT_SYMBOL(raw3270_request_reset);
1327 EXPORT_SYMBOL(raw3270_request_set_cmd);
1328 EXPORT_SYMBOL(raw3270_request_add_data);
1329 EXPORT_SYMBOL(raw3270_request_set_data);
1330 EXPORT_SYMBOL(raw3270_request_set_idal);
1331 EXPORT_SYMBOL(raw3270_buffer_address);
1332 EXPORT_SYMBOL(raw3270_add_view);
1333 EXPORT_SYMBOL(raw3270_del_view);
1334 EXPORT_SYMBOL(raw3270_find_view);
1335 EXPORT_SYMBOL(raw3270_activate_view);
1336 EXPORT_SYMBOL(raw3270_deactivate_view);
1337 EXPORT_SYMBOL(raw3270_start);
1338 EXPORT_SYMBOL(raw3270_start_irq);
1339 EXPORT_SYMBOL(raw3270_register_notifier);
1340 EXPORT_SYMBOL(raw3270_unregister_notifier);
1341 EXPORT_SYMBOL(raw3270_wait_queue);
1342