Merge branch 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6
[cascardo/linux.git] / drivers / s390 / char / fs3270.c
1 /*
2  * IBM/3270 Driver - fullscreen driver.
3  *
4  * Author(s):
5  *   Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
6  *   Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com>
7  *     Copyright IBM Corp. 2003, 2009
8  */
9
10 #include <linux/bootmem.h>
11 #include <linux/console.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/list.h>
15 #include <linux/types.h>
16 #include <linux/smp_lock.h>
17
18 #include <asm/compat.h>
19 #include <asm/ccwdev.h>
20 #include <asm/cio.h>
21 #include <asm/ebcdic.h>
22 #include <asm/idals.h>
23
24 #include "raw3270.h"
25 #include "ctrlchar.h"
26
27 static struct raw3270_fn fs3270_fn;
28
29 struct fs3270 {
30         struct raw3270_view view;
31         struct pid *fs_pid;             /* Pid of controlling program. */
32         int read_command;               /* ccw command to use for reads. */
33         int write_command;              /* ccw command to use for writes. */
34         int attention;                  /* Got attention. */
35         int active;                     /* Fullscreen view is active. */
36         struct raw3270_request *init;   /* single init request. */
37         wait_queue_head_t wait;         /* Init & attention wait queue. */
38         struct idal_buffer *rdbuf;      /* full-screen-deactivate buffer */
39         size_t rdbuf_size;              /* size of data returned by RDBUF */
40 };
41
42 static DEFINE_MUTEX(fs3270_mutex);
43
44 static void
45 fs3270_wake_up(struct raw3270_request *rq, void *data)
46 {
47         wake_up((wait_queue_head_t *) data);
48 }
49
50 static inline int
51 fs3270_working(struct fs3270 *fp)
52 {
53         /*
54          * The fullscreen view is in working order if the view
55          * has been activated AND the initial request is finished.
56          */
57         return fp->active && raw3270_request_final(fp->init);
58 }
59
60 static int
61 fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq)
62 {
63         struct fs3270 *fp;
64         int rc;
65
66         fp = (struct fs3270 *) view;
67         rq->callback = fs3270_wake_up;
68         rq->callback_data = &fp->wait;
69
70         do {
71                 if (!fs3270_working(fp)) {
72                         /* Fullscreen view isn't ready yet. */
73                         rc = wait_event_interruptible(fp->wait,
74                                                       fs3270_working(fp));
75                         if (rc != 0)
76                                 break;
77                 }
78                 rc = raw3270_start(view, rq);
79                 if (rc == 0) {
80                         /* Started successfully. Now wait for completion. */
81                         wait_event(fp->wait, raw3270_request_final(rq));
82                 }
83         } while (rc == -EACCES);
84         return rc;
85 }
86
87 /*
88  * Switch to the fullscreen view.
89  */
90 static void
91 fs3270_reset_callback(struct raw3270_request *rq, void *data)
92 {
93         struct fs3270 *fp;
94
95         fp = (struct fs3270 *) rq->view;
96         raw3270_request_reset(rq);
97         wake_up(&fp->wait);
98 }
99
100 static void
101 fs3270_restore_callback(struct raw3270_request *rq, void *data)
102 {
103         struct fs3270 *fp;
104
105         fp = (struct fs3270 *) rq->view;
106         if (rq->rc != 0 || rq->rescnt != 0) {
107                 if (fp->fs_pid)
108                         kill_pid(fp->fs_pid, SIGHUP, 1);
109         }
110         fp->rdbuf_size = 0;
111         raw3270_request_reset(rq);
112         wake_up(&fp->wait);
113 }
114
115 static int
116 fs3270_activate(struct raw3270_view *view)
117 {
118         struct fs3270 *fp;
119         char *cp;
120         int rc;
121
122         fp = (struct fs3270 *) view;
123
124         /* If an old init command is still running just return. */
125         if (!raw3270_request_final(fp->init))
126                 return 0;
127
128         if (fp->rdbuf_size == 0) {
129                 /* No saved buffer. Just clear the screen. */
130                 raw3270_request_set_cmd(fp->init, TC_EWRITEA);
131                 fp->init->callback = fs3270_reset_callback;
132         } else {
133                 /* Restore fullscreen buffer saved by fs3270_deactivate. */
134                 raw3270_request_set_cmd(fp->init, TC_EWRITEA);
135                 raw3270_request_set_idal(fp->init, fp->rdbuf);
136                 fp->init->ccw.count = fp->rdbuf_size;
137                 cp = fp->rdbuf->data[0];
138                 cp[0] = TW_KR;
139                 cp[1] = TO_SBA;
140                 cp[2] = cp[6];
141                 cp[3] = cp[7];
142                 cp[4] = TO_IC;
143                 cp[5] = TO_SBA;
144                 cp[6] = 0x40;
145                 cp[7] = 0x40;
146                 fp->init->rescnt = 0;
147                 fp->init->callback = fs3270_restore_callback;
148         }
149         rc = fp->init->rc = raw3270_start_locked(view, fp->init);
150         if (rc)
151                 fp->init->callback(fp->init, NULL);
152         else
153                 fp->active = 1;
154         return rc;
155 }
156
157 /*
158  * Shutdown fullscreen view.
159  */
160 static void
161 fs3270_save_callback(struct raw3270_request *rq, void *data)
162 {
163         struct fs3270 *fp;
164
165         fp = (struct fs3270 *) rq->view;
166
167         /* Correct idal buffer element 0 address. */
168         fp->rdbuf->data[0] -= 5;
169         fp->rdbuf->size += 5;
170
171         /*
172          * If the rdbuf command failed or the idal buffer is
173          * to small for the amount of data returned by the
174          * rdbuf command, then we have no choice but to send
175          * a SIGHUP to the application.
176          */
177         if (rq->rc != 0 || rq->rescnt == 0) {
178                 if (fp->fs_pid)
179                         kill_pid(fp->fs_pid, SIGHUP, 1);
180                 fp->rdbuf_size = 0;
181         } else
182                 fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
183         raw3270_request_reset(rq);
184         wake_up(&fp->wait);
185 }
186
187 static void
188 fs3270_deactivate(struct raw3270_view *view)
189 {
190         struct fs3270 *fp;
191
192         fp = (struct fs3270 *) view;
193         fp->active = 0;
194
195         /* If an old init command is still running just return. */
196         if (!raw3270_request_final(fp->init))
197                 return;
198
199         /* Prepare read-buffer request. */
200         raw3270_request_set_cmd(fp->init, TC_RDBUF);
201         /*
202          * Hackish: skip first 5 bytes of the idal buffer to make
203          * room for the TW_KR/TO_SBA/<address>/<address>/TO_IC sequence
204          * in the activation command.
205          */
206         fp->rdbuf->data[0] += 5;
207         fp->rdbuf->size -= 5;
208         raw3270_request_set_idal(fp->init, fp->rdbuf);
209         fp->init->rescnt = 0;
210         fp->init->callback = fs3270_save_callback;
211
212         /* Start I/O to read in the 3270 buffer. */
213         fp->init->rc = raw3270_start_locked(view, fp->init);
214         if (fp->init->rc)
215                 fp->init->callback(fp->init, NULL);
216 }
217
218 static int
219 fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
220 {
221         /* Handle ATTN. Set indication and wake waiters for attention. */
222         if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
223                 fp->attention = 1;
224                 wake_up(&fp->wait);
225         }
226
227         if (rq) {
228                 if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
229                         rq->rc = -EIO;
230                 else
231                         /* Normal end. Copy residual count. */
232                         rq->rescnt = irb->scsw.cmd.count;
233         }
234         return RAW3270_IO_DONE;
235 }
236
237 /*
238  * Process reads from fullscreen 3270.
239  */
240 static ssize_t
241 fs3270_read(struct file *filp, char __user *data, size_t count, loff_t *off)
242 {
243         struct fs3270 *fp;
244         struct raw3270_request *rq;
245         struct idal_buffer *ib;
246         ssize_t rc;
247         
248         if (count == 0 || count > 65535)
249                 return -EINVAL;
250         fp = filp->private_data;
251         if (!fp)
252                 return -ENODEV;
253         ib = idal_buffer_alloc(count, 0);
254         if (IS_ERR(ib))
255                 return -ENOMEM;
256         rq = raw3270_request_alloc(0);
257         if (!IS_ERR(rq)) {
258                 if (fp->read_command == 0 && fp->write_command != 0)
259                         fp->read_command = 6;
260                 raw3270_request_set_cmd(rq, fp->read_command ? : 2);
261                 raw3270_request_set_idal(rq, ib);
262                 rc = wait_event_interruptible(fp->wait, fp->attention);
263                 fp->attention = 0;
264                 if (rc == 0) {
265                         rc = fs3270_do_io(&fp->view, rq);
266                         if (rc == 0) {
267                                 count -= rq->rescnt;
268                                 if (idal_buffer_to_user(ib, data, count) != 0)
269                                         rc = -EFAULT;
270                                 else
271                                         rc = count;
272
273                         }
274                 }
275                 raw3270_request_free(rq);
276         } else
277                 rc = PTR_ERR(rq);
278         idal_buffer_free(ib);
279         return rc;
280 }
281
282 /*
283  * Process writes to fullscreen 3270.
284  */
285 static ssize_t
286 fs3270_write(struct file *filp, const char __user *data, size_t count, loff_t *off)
287 {
288         struct fs3270 *fp;
289         struct raw3270_request *rq;
290         struct idal_buffer *ib;
291         int write_command;
292         ssize_t rc;
293
294         fp = filp->private_data;
295         if (!fp)
296                 return -ENODEV;
297         ib = idal_buffer_alloc(count, 0);
298         if (IS_ERR(ib))
299                 return -ENOMEM;
300         rq = raw3270_request_alloc(0);
301         if (!IS_ERR(rq)) {
302                 if (idal_buffer_from_user(ib, data, count) == 0) {
303                         write_command = fp->write_command ? : 1;
304                         if (write_command == 5)
305                                 write_command = 13;
306                         raw3270_request_set_cmd(rq, write_command);
307                         raw3270_request_set_idal(rq, ib);
308                         rc = fs3270_do_io(&fp->view, rq);
309                         if (rc == 0)
310                                 rc = count - rq->rescnt;
311                 } else
312                         rc = -EFAULT;
313                 raw3270_request_free(rq);
314         } else
315                 rc = PTR_ERR(rq);
316         idal_buffer_free(ib);
317         return rc;
318 }
319
320 /*
321  * process ioctl commands for the tube driver
322  */
323 static long
324 fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
325 {
326         char __user *argp;
327         struct fs3270 *fp;
328         struct raw3270_iocb iocb;
329         int rc;
330
331         fp = filp->private_data;
332         if (!fp)
333                 return -ENODEV;
334         if (is_compat_task())
335                 argp = compat_ptr(arg);
336         else
337                 argp = (char __user *)arg;
338         rc = 0;
339         mutex_lock(&fs3270_mutex);
340         switch (cmd) {
341         case TUBICMD:
342                 fp->read_command = arg;
343                 break;
344         case TUBOCMD:
345                 fp->write_command = arg;
346                 break;
347         case TUBGETI:
348                 rc = put_user(fp->read_command, argp);
349                 break;
350         case TUBGETO:
351                 rc = put_user(fp->write_command, argp);
352                 break;
353         case TUBGETMOD:
354                 iocb.model = fp->view.model;
355                 iocb.line_cnt = fp->view.rows;
356                 iocb.col_cnt = fp->view.cols;
357                 iocb.pf_cnt = 24;
358                 iocb.re_cnt = 20;
359                 iocb.map = 0;
360                 if (copy_to_user(argp, &iocb, sizeof(struct raw3270_iocb)))
361                         rc = -EFAULT;
362                 break;
363         }
364         mutex_unlock(&fs3270_mutex);
365         return rc;
366 }
367
368 /*
369  * Allocate fs3270 structure.
370  */
371 static struct fs3270 *
372 fs3270_alloc_view(void)
373 {
374         struct fs3270 *fp;
375
376         fp = kzalloc(sizeof(struct fs3270),GFP_KERNEL);
377         if (!fp)
378                 return ERR_PTR(-ENOMEM);
379         fp->init = raw3270_request_alloc(0);
380         if (IS_ERR(fp->init)) {
381                 kfree(fp);
382                 return ERR_PTR(-ENOMEM);
383         }
384         return fp;
385 }
386
387 /*
388  * Free fs3270 structure.
389  */
390 static void
391 fs3270_free_view(struct raw3270_view *view)
392 {
393         struct fs3270 *fp;
394
395         fp = (struct fs3270 *) view;
396         if (fp->rdbuf)
397                 idal_buffer_free(fp->rdbuf);
398         raw3270_request_free(((struct fs3270 *) view)->init);
399         kfree(view);
400 }
401
402 /*
403  * Unlink fs3270 data structure from filp.
404  */
405 static void
406 fs3270_release(struct raw3270_view *view)
407 {
408         struct fs3270 *fp;
409
410         fp = (struct fs3270 *) view;
411         if (fp->fs_pid)
412                 kill_pid(fp->fs_pid, SIGHUP, 1);
413 }
414
415 /* View to a 3270 device. Can be console, tty or fullscreen. */
416 static struct raw3270_fn fs3270_fn = {
417         .activate = fs3270_activate,
418         .deactivate = fs3270_deactivate,
419         .intv = (void *) fs3270_irq,
420         .release = fs3270_release,
421         .free = fs3270_free_view
422 };
423
424 /*
425  * This routine is called whenever a 3270 fullscreen device is opened.
426  */
427 static int
428 fs3270_open(struct inode *inode, struct file *filp)
429 {
430         struct fs3270 *fp;
431         struct idal_buffer *ib;
432         int minor, rc = 0;
433
434         if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR)
435                 return -ENODEV;
436         minor = iminor(filp->f_path.dentry->d_inode);
437         /* Check for minor 0 multiplexer. */
438         if (minor == 0) {
439                 struct tty_struct *tty = get_current_tty();
440                 if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
441                         tty_kref_put(tty);
442                         return -ENODEV;
443                 }
444                 minor = tty->index + RAW3270_FIRSTMINOR;
445                 tty_kref_put(tty);
446         }
447         mutex_lock(&fs3270_mutex);
448         /* Check if some other program is already using fullscreen mode. */
449         fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
450         if (!IS_ERR(fp)) {
451                 raw3270_put_view(&fp->view);
452                 rc = -EBUSY;
453                 goto out;
454         }
455         /* Allocate fullscreen view structure. */
456         fp = fs3270_alloc_view();
457         if (IS_ERR(fp)) {
458                 rc = PTR_ERR(fp);
459                 goto out;
460         }
461
462         init_waitqueue_head(&fp->wait);
463         fp->fs_pid = get_pid(task_pid(current));
464         rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
465         if (rc) {
466                 fs3270_free_view(&fp->view);
467                 goto out;
468         }
469
470         /* Allocate idal-buffer. */
471         ib = idal_buffer_alloc(2*fp->view.rows*fp->view.cols + 5, 0);
472         if (IS_ERR(ib)) {
473                 raw3270_put_view(&fp->view);
474                 raw3270_del_view(&fp->view);
475                 rc = PTR_ERR(ib);
476                 goto out;
477         }
478         fp->rdbuf = ib;
479
480         rc = raw3270_activate_view(&fp->view);
481         if (rc) {
482                 raw3270_put_view(&fp->view);
483                 raw3270_del_view(&fp->view);
484                 goto out;
485         }
486         filp->private_data = fp;
487 out:
488         mutex_unlock(&fs3270_mutex);
489         return rc;
490 }
491
492 /*
493  * This routine is called when the 3270 tty is closed. We wait
494  * for the remaining request to be completed. Then we clean up.
495  */
496 static int
497 fs3270_close(struct inode *inode, struct file *filp)
498 {
499         struct fs3270 *fp;
500
501         fp = filp->private_data;
502         filp->private_data = NULL;
503         if (fp) {
504                 put_pid(fp->fs_pid);
505                 fp->fs_pid = NULL;
506                 raw3270_reset(&fp->view);
507                 raw3270_put_view(&fp->view);
508                 raw3270_del_view(&fp->view);
509         }
510         return 0;
511 }
512
513 static const struct file_operations fs3270_fops = {
514         .owner           = THIS_MODULE,         /* owner */
515         .read            = fs3270_read,         /* read */
516         .write           = fs3270_write,        /* write */
517         .unlocked_ioctl  = fs3270_ioctl,        /* ioctl */
518         .compat_ioctl    = fs3270_ioctl,        /* ioctl */
519         .open            = fs3270_open,         /* open */
520         .release         = fs3270_close,        /* release */
521 };
522
523 /*
524  * 3270 fullscreen driver initialization.
525  */
526 static int __init
527 fs3270_init(void)
528 {
529         int rc;
530
531         rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops);
532         if (rc)
533                 return rc;
534         return 0;
535 }
536
537 static void __exit
538 fs3270_exit(void)
539 {
540         unregister_chrdev(IBM_FS3270_MAJOR, "fs3270");
541 }
542
543 MODULE_LICENSE("GPL");
544 MODULE_ALIAS_CHARDEV_MAJOR(IBM_FS3270_MAJOR);
545
546 module_init(fs3270_init);
547 module_exit(fs3270_exit);