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