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