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