diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-09-08 10:49:34 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2012-03-24 19:29:54 -0400 |
commit | bed5e39c56f3fe792e336cfa2670001d78f1d44c (patch) | |
tree | 3b1276d6c18de5a547657d7d86f3aa2f55fa2d1d /arch/um | |
parent | ee4850702bd6980c7baeb6a45142d55744a109a2 (diff) |
um: switch users of ->chan_list to ->chan_{in,out} (easy cases)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/drivers/chan.h | 16 | ||||
-rw-r--r-- | arch/um/drivers/chan_kern.c | 172 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 24 | ||||
-rw-r--r-- | arch/um/drivers/ssl.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/stdio_console.c | 2 |
5 files changed, 88 insertions, 128 deletions
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h index 8df0fd9024dc..5078ec701c61 100644 --- a/arch/um/drivers/chan.h +++ b/arch/um/drivers/chan.h | |||
@@ -27,24 +27,24 @@ struct chan { | |||
27 | void *data; | 27 | void *data; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | extern void chan_interrupt(struct list_head *chans, struct delayed_work *task, | 30 | extern void chan_interrupt(struct line *line, struct delayed_work *task, |
31 | struct tty_struct *tty, int irq); | 31 | struct tty_struct *tty, int irq); |
32 | extern int parse_chan_pair(char *str, struct line *line, int device, | 32 | extern int parse_chan_pair(char *str, struct line *line, int device, |
33 | const struct chan_opts *opts, char **error_out); | 33 | const struct chan_opts *opts, char **error_out); |
34 | extern int write_chan(struct list_head *chans, const char *buf, int len, | 34 | extern int write_chan(struct chan *chan, const char *buf, int len, |
35 | int write_irq); | 35 | int write_irq); |
36 | extern int console_write_chan(struct list_head *chans, const char *buf, | 36 | extern int console_write_chan(struct chan *chan, const char *buf, |
37 | int len); | 37 | int len); |
38 | extern int console_open_chan(struct line *line, struct console *co); | 38 | extern int console_open_chan(struct line *line, struct console *co); |
39 | extern void deactivate_chan(struct list_head *chans, int irq); | 39 | extern void deactivate_chan(struct chan *chan, int irq); |
40 | extern void reactivate_chan(struct list_head *chans, int irq); | 40 | extern void reactivate_chan(struct chan *chan, int irq); |
41 | extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); | 41 | extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty); |
42 | extern int enable_chan(struct line *line); | 42 | extern int enable_chan(struct line *line); |
43 | extern void close_chan(struct list_head *chans, int delay_free_irq); | 43 | extern void close_chan(struct list_head *chans, int delay_free_irq); |
44 | extern int chan_window_size(struct list_head *chans, | 44 | extern int chan_window_size(struct line *line, |
45 | unsigned short *rows_out, | 45 | unsigned short *rows_out, |
46 | unsigned short *cols_out); | 46 | unsigned short *cols_out); |
47 | extern int chan_config_string(struct list_head *chans, char *str, int size, | 47 | extern int chan_config_string(struct line *line, char *str, int size, |
48 | char **error_out); | 48 | char **error_out); |
49 | 49 | ||
50 | #endif | 50 | #endif |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 390920d63a24..73d7bc018ab2 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -140,18 +140,10 @@ static int open_chan(struct list_head *chans) | |||
140 | return err; | 140 | return err; |
141 | } | 141 | } |
142 | 142 | ||
143 | void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) | 143 | void chan_enable_winch(struct chan *chan, struct tty_struct *tty) |
144 | { | 144 | { |
145 | struct list_head *ele; | 145 | if (chan && chan->primary && chan->ops->winch) |
146 | struct chan *chan; | 146 | register_winch(chan->fd, tty); |
147 | |||
148 | list_for_each(ele, chans) { | ||
149 | chan = list_entry(ele, struct chan, list); | ||
150 | if (chan->primary && chan->output && chan->ops->winch) { | ||
151 | register_winch(chan->fd, tty); | ||
152 | return; | ||
153 | } | ||
154 | } | ||
155 | } | 147 | } |
156 | 148 | ||
157 | int enable_chan(struct line *line) | 149 | int enable_chan(struct line *line) |
@@ -258,72 +250,45 @@ void close_chan(struct list_head *chans, int delay_free_irq) | |||
258 | } | 250 | } |
259 | } | 251 | } |
260 | 252 | ||
261 | void deactivate_chan(struct list_head *chans, int irq) | 253 | void deactivate_chan(struct chan *chan, int irq) |
262 | { | 254 | { |
263 | struct list_head *ele; | 255 | if (chan && chan->enabled) |
264 | 256 | deactivate_fd(chan->fd, irq); | |
265 | struct chan *chan; | ||
266 | list_for_each(ele, chans) { | ||
267 | chan = list_entry(ele, struct chan, list); | ||
268 | |||
269 | if (chan->enabled && chan->input) | ||
270 | deactivate_fd(chan->fd, irq); | ||
271 | } | ||
272 | } | 257 | } |
273 | 258 | ||
274 | void reactivate_chan(struct list_head *chans, int irq) | 259 | void reactivate_chan(struct chan *chan, int irq) |
275 | { | 260 | { |
276 | struct list_head *ele; | 261 | if (chan && chan->enabled) |
277 | struct chan *chan; | 262 | reactivate_fd(chan->fd, irq); |
278 | |||
279 | list_for_each(ele, chans) { | ||
280 | chan = list_entry(ele, struct chan, list); | ||
281 | |||
282 | if (chan->enabled && chan->input) | ||
283 | reactivate_fd(chan->fd, irq); | ||
284 | } | ||
285 | } | 263 | } |
286 | 264 | ||
287 | int write_chan(struct list_head *chans, const char *buf, int len, | 265 | int write_chan(struct chan *chan, const char *buf, int len, |
288 | int write_irq) | 266 | int write_irq) |
289 | { | 267 | { |
290 | struct list_head *ele; | ||
291 | struct chan *chan = NULL; | ||
292 | int n, ret = 0; | 268 | int n, ret = 0; |
293 | 269 | ||
294 | if (len == 0) | 270 | if (len == 0 || !chan || !chan->ops->write) |
295 | return 0; | 271 | return 0; |
296 | 272 | ||
297 | list_for_each(ele, chans) { | 273 | n = chan->ops->write(chan->fd, buf, len, chan->data); |
298 | chan = list_entry(ele, struct chan, list); | 274 | if (chan->primary) { |
299 | if (!chan->output || (chan->ops->write == NULL)) | 275 | ret = n; |
300 | continue; | 276 | if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len))) |
301 | 277 | reactivate_fd(chan->fd, write_irq); | |
302 | n = chan->ops->write(chan->fd, buf, len, chan->data); | ||
303 | if (chan->primary) { | ||
304 | ret = n; | ||
305 | if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len))) | ||
306 | reactivate_fd(chan->fd, write_irq); | ||
307 | } | ||
308 | } | 278 | } |
309 | return ret; | 279 | return ret; |
310 | } | 280 | } |
311 | 281 | ||
312 | int console_write_chan(struct list_head *chans, const char *buf, int len) | 282 | int console_write_chan(struct chan *chan, const char *buf, int len) |
313 | { | 283 | { |
314 | struct list_head *ele; | ||
315 | struct chan *chan; | ||
316 | int n, ret = 0; | 284 | int n, ret = 0; |
317 | 285 | ||
318 | list_for_each(ele, chans) { | 286 | if (!chan || !chan->ops->console_write) |
319 | chan = list_entry(ele, struct chan, list); | 287 | return 0; |
320 | if (!chan->output || (chan->ops->console_write == NULL)) | ||
321 | continue; | ||
322 | 288 | ||
323 | n = chan->ops->console_write(chan->fd, buf, len); | 289 | n = chan->ops->console_write(chan->fd, buf, len); |
324 | if (chan->primary) | 290 | if (chan->primary) |
325 | ret = n; | 291 | ret = n; |
326 | } | ||
327 | return ret; | 292 | return ret; |
328 | } | 293 | } |
329 | 294 | ||
@@ -340,20 +305,24 @@ int console_open_chan(struct line *line, struct console *co) | |||
340 | return 0; | 305 | return 0; |
341 | } | 306 | } |
342 | 307 | ||
343 | int chan_window_size(struct list_head *chans, unsigned short *rows_out, | 308 | int chan_window_size(struct line *line, unsigned short *rows_out, |
344 | unsigned short *cols_out) | 309 | unsigned short *cols_out) |
345 | { | 310 | { |
346 | struct list_head *ele; | ||
347 | struct chan *chan; | 311 | struct chan *chan; |
348 | 312 | ||
349 | list_for_each(ele, chans) { | 313 | chan = line->chan_in; |
350 | chan = list_entry(ele, struct chan, list); | 314 | if (chan && chan->primary) { |
351 | if (chan->primary) { | 315 | if (chan->ops->window_size == NULL) |
352 | if (chan->ops->window_size == NULL) | 316 | return 0; |
353 | return 0; | 317 | return chan->ops->window_size(chan->fd, chan->data, |
354 | return chan->ops->window_size(chan->fd, chan->data, | 318 | rows_out, cols_out); |
355 | rows_out, cols_out); | 319 | } |
356 | } | 320 | chan = line->chan_out; |
321 | if (chan && chan->primary) { | ||
322 | if (chan->ops->window_size == NULL) | ||
323 | return 0; | ||
324 | return chan->ops->window_size(chan->fd, chan->data, | ||
325 | rows_out, cols_out); | ||
357 | } | 326 | } |
358 | return 0; | 327 | return 0; |
359 | } | 328 | } |
@@ -429,21 +398,15 @@ static int chan_pair_config_string(struct chan *in, struct chan *out, | |||
429 | return n; | 398 | return n; |
430 | } | 399 | } |
431 | 400 | ||
432 | int chan_config_string(struct list_head *chans, char *str, int size, | 401 | int chan_config_string(struct line *line, char *str, int size, |
433 | char **error_out) | 402 | char **error_out) |
434 | { | 403 | { |
435 | struct list_head *ele; | 404 | struct chan *in = line->chan_in, *out = line->chan_out; |
436 | struct chan *chan, *in = NULL, *out = NULL; | ||
437 | 405 | ||
438 | list_for_each(ele, chans) { | 406 | if (in && !in->primary) |
439 | chan = list_entry(ele, struct chan, list); | 407 | in = NULL; |
440 | if (!chan->primary) | 408 | if (out && !out->primary) |
441 | continue; | 409 | out = NULL; |
442 | if (chan->input) | ||
443 | in = chan; | ||
444 | if (chan->output) | ||
445 | out = chan; | ||
446 | } | ||
447 | 410 | ||
448 | return chan_pair_config_string(in, out, str, size, error_out); | 411 | return chan_pair_config_string(in, out, str, size, error_out); |
449 | } | 412 | } |
@@ -589,39 +552,36 @@ int parse_chan_pair(char *str, struct line *line, int device, | |||
589 | return 0; | 552 | return 0; |
590 | } | 553 | } |
591 | 554 | ||
592 | void chan_interrupt(struct list_head *chans, struct delayed_work *task, | 555 | void chan_interrupt(struct line *line, struct delayed_work *task, |
593 | struct tty_struct *tty, int irq) | 556 | struct tty_struct *tty, int irq) |
594 | { | 557 | { |
595 | struct list_head *ele, *next; | 558 | struct chan *chan = line->chan_in; |
596 | struct chan *chan; | ||
597 | int err; | 559 | int err; |
598 | char c; | 560 | char c; |
599 | 561 | ||
600 | list_for_each_safe(ele, next, chans) { | 562 | if (!chan || !chan->ops->read) |
601 | chan = list_entry(ele, struct chan, list); | 563 | goto out; |
602 | if (!chan->input || (chan->ops->read == NULL)) | 564 | |
603 | continue; | 565 | do { |
604 | do { | 566 | if (tty && !tty_buffer_request_room(tty, 1)) { |
605 | if (tty && !tty_buffer_request_room(tty, 1)) { | 567 | schedule_delayed_work(task, 1); |
606 | schedule_delayed_work(task, 1); | 568 | goto out; |
607 | goto out; | 569 | } |
608 | } | 570 | err = chan->ops->read(chan->fd, &c, chan->data); |
609 | err = chan->ops->read(chan->fd, &c, chan->data); | 571 | if (err > 0) |
610 | if (err > 0) | 572 | tty_receive_char(tty, c); |
611 | tty_receive_char(tty, c); | 573 | } while (err > 0); |
612 | } while (err > 0); | 574 | |
613 | 575 | if (err == 0) | |
614 | if (err == 0) | 576 | reactivate_fd(chan->fd, irq); |
615 | reactivate_fd(chan->fd, irq); | 577 | if (err == -EIO) { |
616 | if (err == -EIO) { | 578 | if (chan->primary) { |
617 | if (chan->primary) { | 579 | if (tty != NULL) |
618 | if (tty != NULL) | 580 | tty_hangup(tty); |
619 | tty_hangup(tty); | 581 | close_chan(&line->chan_list, 1); |
620 | close_chan(chans, 1); | 582 | return; |
621 | return; | ||
622 | } | ||
623 | else close_one_chan(chan, 1); | ||
624 | } | 583 | } |
584 | else close_one_chan(chan, 1); | ||
625 | } | 585 | } |
626 | out: | 586 | out: |
627 | if (tty) | 587 | if (tty) |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 9ffade87a8cf..c1aa89cefaec 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -21,7 +21,7 @@ static irqreturn_t line_interrupt(int irq, void *data) | |||
21 | struct line *line = chan->line; | 21 | struct line *line = chan->line; |
22 | 22 | ||
23 | if (line) | 23 | if (line) |
24 | chan_interrupt(&line->chan_list, &line->task, line->tty, irq); | 24 | chan_interrupt(line, &line->task, line->tty, irq); |
25 | return IRQ_HANDLED; | 25 | return IRQ_HANDLED; |
26 | } | 26 | } |
27 | 27 | ||
@@ -30,7 +30,7 @@ static void line_timer_cb(struct work_struct *work) | |||
30 | struct line *line = container_of(work, struct line, task.work); | 30 | struct line *line = container_of(work, struct line, task.work); |
31 | 31 | ||
32 | if (!line->throttled) | 32 | if (!line->throttled) |
33 | chan_interrupt(&line->chan_list, &line->task, line->tty, | 33 | chan_interrupt(line, &line->task, line->tty, |
34 | line->driver->read_irq); | 34 | line->driver->read_irq); |
35 | } | 35 | } |
36 | 36 | ||
@@ -145,7 +145,7 @@ static int flush_buffer(struct line *line) | |||
145 | /* line->buffer + LINE_BUFSIZE is the end of the buffer! */ | 145 | /* line->buffer + LINE_BUFSIZE is the end of the buffer! */ |
146 | count = line->buffer + LINE_BUFSIZE - line->head; | 146 | count = line->buffer + LINE_BUFSIZE - line->head; |
147 | 147 | ||
148 | n = write_chan(&line->chan_list, line->head, count, | 148 | n = write_chan(line->chan_out, line->head, count, |
149 | line->driver->write_irq); | 149 | line->driver->write_irq); |
150 | if (n < 0) | 150 | if (n < 0) |
151 | return n; | 151 | return n; |
@@ -162,7 +162,7 @@ static int flush_buffer(struct line *line) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | count = line->tail - line->head; | 164 | count = line->tail - line->head; |
165 | n = write_chan(&line->chan_list, line->head, count, | 165 | n = write_chan(line->chan_out, line->head, count, |
166 | line->driver->write_irq); | 166 | line->driver->write_irq); |
167 | 167 | ||
168 | if (n < 0) | 168 | if (n < 0) |
@@ -206,7 +206,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len) | |||
206 | if (line->head != line->tail) | 206 | if (line->head != line->tail) |
207 | ret = buffer_data(line, buf, len); | 207 | ret = buffer_data(line, buf, len); |
208 | else { | 208 | else { |
209 | n = write_chan(&line->chan_list, buf, len, | 209 | n = write_chan(line->chan_out, buf, len, |
210 | line->driver->write_irq); | 210 | line->driver->write_irq); |
211 | if (n < 0) { | 211 | if (n < 0) { |
212 | ret = n; | 212 | ret = n; |
@@ -318,7 +318,7 @@ void line_throttle(struct tty_struct *tty) | |||
318 | { | 318 | { |
319 | struct line *line = tty->driver_data; | 319 | struct line *line = tty->driver_data; |
320 | 320 | ||
321 | deactivate_chan(&line->chan_list, line->driver->read_irq); | 321 | deactivate_chan(line->chan_in, line->driver->read_irq); |
322 | line->throttled = 1; | 322 | line->throttled = 1; |
323 | } | 323 | } |
324 | 324 | ||
@@ -327,7 +327,7 @@ void line_unthrottle(struct tty_struct *tty) | |||
327 | struct line *line = tty->driver_data; | 327 | struct line *line = tty->driver_data; |
328 | 328 | ||
329 | line->throttled = 0; | 329 | line->throttled = 0; |
330 | chan_interrupt(&line->chan_list, &line->task, tty, | 330 | chan_interrupt(line, &line->task, tty, |
331 | line->driver->read_irq); | 331 | line->driver->read_irq); |
332 | 332 | ||
333 | /* | 333 | /* |
@@ -336,7 +336,7 @@ void line_unthrottle(struct tty_struct *tty) | |||
336 | * again and we shouldn't turn the interrupt back on. | 336 | * again and we shouldn't turn the interrupt back on. |
337 | */ | 337 | */ |
338 | if (!line->throttled) | 338 | if (!line->throttled) |
339 | reactivate_chan(&line->chan_list, line->driver->read_irq); | 339 | reactivate_chan(line->chan_in, line->driver->read_irq); |
340 | } | 340 | } |
341 | 341 | ||
342 | static irqreturn_t line_write_interrupt(int irq, void *data) | 342 | static irqreturn_t line_write_interrupt(int irq, void *data) |
@@ -428,11 +428,11 @@ int line_open(struct line *lines, struct tty_struct *tty) | |||
428 | INIT_DELAYED_WORK(&line->task, line_timer_cb); | 428 | INIT_DELAYED_WORK(&line->task, line_timer_cb); |
429 | 429 | ||
430 | if (!line->sigio) { | 430 | if (!line->sigio) { |
431 | chan_enable_winch(&line->chan_list, tty); | 431 | chan_enable_winch(line->chan_out, tty); |
432 | line->sigio = 1; | 432 | line->sigio = 1; |
433 | } | 433 | } |
434 | 434 | ||
435 | chan_window_size(&line->chan_list, &tty->winsize.ws_row, | 435 | chan_window_size(line, &tty->winsize.ws_row, |
436 | &tty->winsize.ws_col); | 436 | &tty->winsize.ws_col); |
437 | out_unlock: | 437 | out_unlock: |
438 | mutex_unlock(&line->count_lock); | 438 | mutex_unlock(&line->count_lock); |
@@ -624,7 +624,7 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, | |||
624 | CONFIG_CHUNK(str, size, n, "none", 1); | 624 | CONFIG_CHUNK(str, size, n, "none", 1); |
625 | else if (line->tty == NULL) | 625 | else if (line->tty == NULL) |
626 | CONFIG_CHUNK(str, size, n, line->init_str, 1); | 626 | CONFIG_CHUNK(str, size, n, line->init_str, 1); |
627 | else n = chan_config_string(&line->chan_list, str, size, error_out); | 627 | else n = chan_config_string(line, str, size, error_out); |
628 | mutex_unlock(&line->count_lock); | 628 | mutex_unlock(&line->count_lock); |
629 | 629 | ||
630 | return n; | 630 | return n; |
@@ -761,7 +761,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) | |||
761 | if (tty != NULL) { | 761 | if (tty != NULL) { |
762 | line = tty->driver_data; | 762 | line = tty->driver_data; |
763 | if (line != NULL) { | 763 | if (line != NULL) { |
764 | chan_window_size(&line->chan_list, &tty->winsize.ws_row, | 764 | chan_window_size(line, &tty->winsize.ws_row, |
765 | &tty->winsize.ws_col); | 765 | &tty->winsize.ws_col); |
766 | kill_pgrp(tty->pgrp, SIGWINCH, 1); | 766 | kill_pgrp(tty->pgrp, SIGWINCH, 1); |
767 | } | 767 | } |
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index d0b5ccf2379f..e09801a1327b 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -151,7 +151,7 @@ static void ssl_console_write(struct console *c, const char *string, | |||
151 | unsigned long flags; | 151 | unsigned long flags; |
152 | 152 | ||
153 | spin_lock_irqsave(&line->lock, flags); | 153 | spin_lock_irqsave(&line->lock, flags); |
154 | console_write_chan(&line->chan_list, string, len); | 154 | console_write_chan(line->chan_out, string, len); |
155 | spin_unlock_irqrestore(&line->lock, flags); | 155 | spin_unlock_irqrestore(&line->lock, flags); |
156 | } | 156 | } |
157 | 157 | ||
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index fe581209d629..7663541c372e 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -124,7 +124,7 @@ static void uml_console_write(struct console *console, const char *string, | |||
124 | unsigned long flags; | 124 | unsigned long flags; |
125 | 125 | ||
126 | spin_lock_irqsave(&line->lock, flags); | 126 | spin_lock_irqsave(&line->lock, flags); |
127 | console_write_chan(&line->chan_list, string, len); | 127 | console_write_chan(line->chan_out, string, len); |
128 | spin_unlock_irqrestore(&line->lock, flags); | 128 | spin_unlock_irqrestore(&line->lock, flags); |
129 | } | 129 | } |
130 | 130 | ||