cgroup: superblock can't be released with active dentries
[firefly-linux-kernel-4.4.55.git] / arch / um / drivers / chan_kern.c
1 /*
2  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3  * Licensed under the GPL
4  */
5
6 #include <linux/slab.h>
7 #include <linux/tty.h>
8 #include <linux/tty_flip.h>
9 #include "chan.h"
10 #include "os.h"
11
12 #ifdef CONFIG_NOCONFIG_CHAN
13 static void *not_configged_init(char *str, int device,
14                                 const struct chan_opts *opts)
15 {
16         printk(KERN_ERR "Using a channel type which is configured out of "
17                "UML\n");
18         return NULL;
19 }
20
21 static int not_configged_open(int input, int output, int primary, void *data,
22                               char **dev_out)
23 {
24         printk(KERN_ERR "Using a channel type which is configured out of "
25                "UML\n");
26         return -ENODEV;
27 }
28
29 static void not_configged_close(int fd, void *data)
30 {
31         printk(KERN_ERR "Using a channel type which is configured out of "
32                "UML\n");
33 }
34
35 static int not_configged_read(int fd, char *c_out, void *data)
36 {
37         printk(KERN_ERR "Using a channel type which is configured out of "
38                "UML\n");
39         return -EIO;
40 }
41
42 static int not_configged_write(int fd, const char *buf, int len, void *data)
43 {
44         printk(KERN_ERR "Using a channel type which is configured out of "
45                "UML\n");
46         return -EIO;
47 }
48
49 static int not_configged_console_write(int fd, const char *buf, int len)
50 {
51         printk(KERN_ERR "Using a channel type which is configured out of "
52                "UML\n");
53         return -EIO;
54 }
55
56 static int not_configged_window_size(int fd, void *data, unsigned short *rows,
57                                      unsigned short *cols)
58 {
59         printk(KERN_ERR "Using a channel type which is configured out of "
60                "UML\n");
61         return -ENODEV;
62 }
63
64 static void not_configged_free(void *data)
65 {
66         printk(KERN_ERR "Using a channel type which is configured out of "
67                "UML\n");
68 }
69
70 static const struct chan_ops not_configged_ops = {
71         .init           = not_configged_init,
72         .open           = not_configged_open,
73         .close          = not_configged_close,
74         .read           = not_configged_read,
75         .write          = not_configged_write,
76         .console_write  = not_configged_console_write,
77         .window_size    = not_configged_window_size,
78         .free           = not_configged_free,
79         .winch          = 0,
80 };
81 #endif /* CONFIG_NOCONFIG_CHAN */
82
83 static void tty_receive_char(struct tty_struct *tty, char ch)
84 {
85         if (tty == NULL)
86                 return;
87
88         if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
89                 if (ch == STOP_CHAR(tty)) {
90                         stop_tty(tty);
91                         return;
92                 }
93                 else if (ch == START_CHAR(tty)) {
94                         start_tty(tty);
95                         return;
96                 }
97         }
98
99         tty_insert_flip_char(tty, ch, TTY_NORMAL);
100 }
101
102 static int open_one_chan(struct chan *chan)
103 {
104         int fd, err;
105
106         if (chan->opened)
107                 return 0;
108
109         if (chan->ops->open == NULL)
110                 fd = 0;
111         else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary,
112                                      chan->data, &chan->dev);
113         if (fd < 0)
114                 return fd;
115
116         err = os_set_fd_block(fd, 0);
117         if (err) {
118                 (*chan->ops->close)(fd, chan->data);
119                 return err;
120         }
121
122         chan->fd = fd;
123
124         chan->opened = 1;
125         return 0;
126 }
127
128 static int open_chan(struct list_head *chans)
129 {
130         struct list_head *ele;
131         struct chan *chan;
132         int ret, err = 0;
133
134         list_for_each(ele, chans) {
135                 chan = list_entry(ele, struct chan, list);
136                 ret = open_one_chan(chan);
137                 if (chan->primary)
138                         err = ret;
139         }
140         return err;
141 }
142
143 void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
144 {
145         if (chan && chan->primary && chan->ops->winch)
146                 register_winch(chan->fd, tty);
147 }
148
149 static void line_timer_cb(struct work_struct *work)
150 {
151         struct line *line = container_of(work, struct line, task.work);
152
153         if (!line->throttled)
154                 chan_interrupt(line, line->tty, line->driver->read_irq);
155 }
156
157 int enable_chan(struct line *line)
158 {
159         struct list_head *ele;
160         struct chan *chan;
161         int err;
162
163         INIT_DELAYED_WORK(&line->task, line_timer_cb);
164
165         list_for_each(ele, &line->chan_list) {
166                 chan = list_entry(ele, struct chan, list);
167                 err = open_one_chan(chan);
168                 if (err) {
169                         if (chan->primary)
170                                 goto out_close;
171
172                         continue;
173                 }
174
175                 if (chan->enabled)
176                         continue;
177                 err = line_setup_irq(chan->fd, chan->input, chan->output, line,
178                                      chan);
179                 if (err)
180                         goto out_close;
181
182                 chan->enabled = 1;
183         }
184
185         return 0;
186
187  out_close:
188         close_chan(line);
189         return err;
190 }
191
192 /* Items are added in IRQ context, when free_irq can't be called, and
193  * removed in process context, when it can.
194  * This handles interrupt sources which disappear, and which need to
195  * be permanently disabled.  This is discovered in IRQ context, but
196  * the freeing of the IRQ must be done later.
197  */
198 static DEFINE_SPINLOCK(irqs_to_free_lock);
199 static LIST_HEAD(irqs_to_free);
200
201 void free_irqs(void)
202 {
203         struct chan *chan;
204         LIST_HEAD(list);
205         struct list_head *ele;
206         unsigned long flags;
207
208         spin_lock_irqsave(&irqs_to_free_lock, flags);
209         list_splice_init(&irqs_to_free, &list);
210         spin_unlock_irqrestore(&irqs_to_free_lock, flags);
211
212         list_for_each(ele, &list) {
213                 chan = list_entry(ele, struct chan, free_list);
214
215                 if (chan->input && chan->enabled)
216                         free_irq(chan->line->driver->read_irq, chan);
217                 if (chan->output && chan->enabled)
218                         free_irq(chan->line->driver->write_irq, chan);
219                 chan->enabled = 0;
220         }
221 }
222
223 static void close_one_chan(struct chan *chan, int delay_free_irq)
224 {
225         unsigned long flags;
226
227         if (!chan->opened)
228                 return;
229
230         if (delay_free_irq) {
231                 spin_lock_irqsave(&irqs_to_free_lock, flags);
232                 list_add(&chan->free_list, &irqs_to_free);
233                 spin_unlock_irqrestore(&irqs_to_free_lock, flags);
234         }
235         else {
236                 if (chan->input && chan->enabled)
237                         free_irq(chan->line->driver->read_irq, chan);
238                 if (chan->output && chan->enabled)
239                         free_irq(chan->line->driver->write_irq, chan);
240                 chan->enabled = 0;
241         }
242         if (chan->ops->close != NULL)
243                 (*chan->ops->close)(chan->fd, chan->data);
244
245         chan->opened = 0;
246         chan->fd = -1;
247 }
248
249 void close_chan(struct line *line)
250 {
251         struct chan *chan;
252
253         /* Close in reverse order as open in case more than one of them
254          * refers to the same device and they save and restore that device's
255          * state.  Then, the first one opened will have the original state,
256          * so it must be the last closed.
257          */
258         list_for_each_entry_reverse(chan, &line->chan_list, list) {
259                 close_one_chan(chan, 0);
260         }
261 }
262
263 void deactivate_chan(struct chan *chan, int irq)
264 {
265         if (chan && chan->enabled)
266                 deactivate_fd(chan->fd, irq);
267 }
268
269 void reactivate_chan(struct chan *chan, int irq)
270 {
271         if (chan && chan->enabled)
272                 reactivate_fd(chan->fd, irq);
273 }
274
275 int write_chan(struct chan *chan, const char *buf, int len,
276                int write_irq)
277 {
278         int n, ret = 0;
279
280         if (len == 0 || !chan || !chan->ops->write)
281                 return 0;
282
283         n = chan->ops->write(chan->fd, buf, len, chan->data);
284         if (chan->primary) {
285                 ret = n;
286                 if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
287                         reactivate_fd(chan->fd, write_irq);
288         }
289         return ret;
290 }
291
292 int console_write_chan(struct chan *chan, const char *buf, int len)
293 {
294         int n, ret = 0;
295
296         if (!chan || !chan->ops->console_write)
297                 return 0;
298
299         n = chan->ops->console_write(chan->fd, buf, len);
300         if (chan->primary)
301                 ret = n;
302         return ret;
303 }
304
305 int console_open_chan(struct line *line, struct console *co)
306 {
307         int err;
308
309         err = open_chan(&line->chan_list);
310         if (err)
311                 return err;
312
313         printk(KERN_INFO "Console initialized on /dev/%s%d\n", co->name,
314                co->index);
315         return 0;
316 }
317
318 int chan_window_size(struct line *line, unsigned short *rows_out,
319                       unsigned short *cols_out)
320 {
321         struct chan *chan;
322
323         chan = line->chan_in;
324         if (chan && chan->primary) {
325                 if (chan->ops->window_size == NULL)
326                         return 0;
327                 return chan->ops->window_size(chan->fd, chan->data,
328                                               rows_out, cols_out);
329         }
330         chan = line->chan_out;
331         if (chan && chan->primary) {
332                 if (chan->ops->window_size == NULL)
333                         return 0;
334                 return chan->ops->window_size(chan->fd, chan->data,
335                                               rows_out, cols_out);
336         }
337         return 0;
338 }
339
340 static void free_one_chan(struct chan *chan)
341 {
342         list_del(&chan->list);
343
344         close_one_chan(chan, 0);
345
346         if (chan->ops->free != NULL)
347                 (*chan->ops->free)(chan->data);
348
349         if (chan->primary && chan->output)
350                 ignore_sigio_fd(chan->fd);
351         kfree(chan);
352 }
353
354 static void free_chan(struct list_head *chans)
355 {
356         struct list_head *ele, *next;
357         struct chan *chan;
358
359         list_for_each_safe(ele, next, chans) {
360                 chan = list_entry(ele, struct chan, list);
361                 free_one_chan(chan);
362         }
363 }
364
365 static int one_chan_config_string(struct chan *chan, char *str, int size,
366                                   char **error_out)
367 {
368         int n = 0;
369
370         if (chan == NULL) {
371                 CONFIG_CHUNK(str, size, n, "none", 1);
372                 return n;
373         }
374
375         CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
376
377         if (chan->dev == NULL) {
378                 CONFIG_CHUNK(str, size, n, "", 1);
379                 return n;
380         }
381
382         CONFIG_CHUNK(str, size, n, ":", 0);
383         CONFIG_CHUNK(str, size, n, chan->dev, 0);
384
385         return n;
386 }
387
388 static int chan_pair_config_string(struct chan *in, struct chan *out,
389                                    char *str, int size, char **error_out)
390 {
391         int n;
392
393         n = one_chan_config_string(in, str, size, error_out);
394         str += n;
395         size -= n;
396
397         if (in == out) {
398                 CONFIG_CHUNK(str, size, n, "", 1);
399                 return n;
400         }
401
402         CONFIG_CHUNK(str, size, n, ",", 1);
403         n = one_chan_config_string(out, str, size, error_out);
404         str += n;
405         size -= n;
406         CONFIG_CHUNK(str, size, n, "", 1);
407
408         return n;
409 }
410
411 int chan_config_string(struct line *line, char *str, int size,
412                        char **error_out)
413 {
414         struct chan *in = line->chan_in, *out = line->chan_out;
415
416         if (in && !in->primary)
417                 in = NULL;
418         if (out && !out->primary)
419                 out = NULL;
420
421         return chan_pair_config_string(in, out, str, size, error_out);
422 }
423
424 struct chan_type {
425         char *key;
426         const struct chan_ops *ops;
427 };
428
429 static const struct chan_type chan_table[] = {
430         { "fd", &fd_ops },
431
432 #ifdef CONFIG_NULL_CHAN
433         { "null", &null_ops },
434 #else
435         { "null", &not_configged_ops },
436 #endif
437
438 #ifdef CONFIG_PORT_CHAN
439         { "port", &port_ops },
440 #else
441         { "port", &not_configged_ops },
442 #endif
443
444 #ifdef CONFIG_PTY_CHAN
445         { "pty", &pty_ops },
446         { "pts", &pts_ops },
447 #else
448         { "pty", &not_configged_ops },
449         { "pts", &not_configged_ops },
450 #endif
451
452 #ifdef CONFIG_TTY_CHAN
453         { "tty", &tty_ops },
454 #else
455         { "tty", &not_configged_ops },
456 #endif
457
458 #ifdef CONFIG_XTERM_CHAN
459         { "xterm", &xterm_ops },
460 #else
461         { "xterm", &not_configged_ops },
462 #endif
463 };
464
465 static struct chan *parse_chan(struct line *line, char *str, int device,
466                                const struct chan_opts *opts, char **error_out)
467 {
468         const struct chan_type *entry;
469         const struct chan_ops *ops;
470         struct chan *chan;
471         void *data;
472         int i;
473
474         ops = NULL;
475         data = NULL;
476         for(i = 0; i < ARRAY_SIZE(chan_table); i++) {
477                 entry = &chan_table[i];
478                 if (!strncmp(str, entry->key, strlen(entry->key))) {
479                         ops = entry->ops;
480                         str += strlen(entry->key);
481                         break;
482                 }
483         }
484         if (ops == NULL) {
485                 *error_out = "No match for configured backends";
486                 return NULL;
487         }
488
489         data = (*ops->init)(str, device, opts);
490         if (data == NULL) {
491                 *error_out = "Configuration failed";
492                 return NULL;
493         }
494
495         chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
496         if (chan == NULL) {
497                 *error_out = "Memory allocation failed";
498                 return NULL;
499         }
500         *chan = ((struct chan) { .list          = LIST_HEAD_INIT(chan->list),
501                                  .free_list     =
502                                         LIST_HEAD_INIT(chan->free_list),
503                                  .line          = line,
504                                  .primary       = 1,
505                                  .input         = 0,
506                                  .output        = 0,
507                                  .opened        = 0,
508                                  .enabled       = 0,
509                                  .fd            = -1,
510                                  .ops           = ops,
511                                  .data          = data });
512         return chan;
513 }
514
515 int parse_chan_pair(char *str, struct line *line, int device,
516                     const struct chan_opts *opts, char **error_out)
517 {
518         struct list_head *chans = &line->chan_list;
519         struct chan *new;
520         char *in, *out;
521
522         if (!list_empty(chans)) {
523                 line->chan_in = line->chan_out = NULL;
524                 free_chan(chans);
525                 INIT_LIST_HEAD(chans);
526         }
527
528         if (!str)
529                 return 0;
530
531         out = strchr(str, ',');
532         if (out != NULL) {
533                 in = str;
534                 *out = '\0';
535                 out++;
536                 new = parse_chan(line, in, device, opts, error_out);
537                 if (new == NULL)
538                         return -1;
539
540                 new->input = 1;
541                 list_add(&new->list, chans);
542                 line->chan_in = new;
543
544                 new = parse_chan(line, out, device, opts, error_out);
545                 if (new == NULL)
546                         return -1;
547
548                 list_add(&new->list, chans);
549                 new->output = 1;
550                 line->chan_out = new;
551         }
552         else {
553                 new = parse_chan(line, str, device, opts, error_out);
554                 if (new == NULL)
555                         return -1;
556
557                 list_add(&new->list, chans);
558                 new->input = 1;
559                 new->output = 1;
560                 line->chan_in = line->chan_out = new;
561         }
562         return 0;
563 }
564
565 void chan_interrupt(struct line *line, struct tty_struct *tty, int irq)
566 {
567         struct chan *chan = line->chan_in;
568         int err;
569         char c;
570
571         if (!chan || !chan->ops->read)
572                 goto out;
573
574         do {
575                 if (tty && !tty_buffer_request_room(tty, 1)) {
576                         schedule_delayed_work(&line->task, 1);
577                         goto out;
578                 }
579                 err = chan->ops->read(chan->fd, &c, chan->data);
580                 if (err > 0)
581                         tty_receive_char(tty, c);
582         } while (err > 0);
583
584         if (err == 0)
585                 reactivate_fd(chan->fd, irq);
586         if (err == -EIO) {
587                 if (chan->primary) {
588                         if (tty != NULL)
589                                 tty_hangup(tty);
590                         if (line->chan_out != chan)
591                                 close_one_chan(line->chan_out, 1);
592                 }
593                 close_one_chan(chan, 1);
594                 if (chan->primary)
595                         return;
596         }
597  out:
598         if (tty)
599                 tty_flip_buffer_push(tty);
600 }