aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-06-04 07:35:27 -0400
committerRichard Weinberger <richard@nod.at>2012-07-28 11:47:58 -0400
commit6fc58845ad189f8ceebd68a2ff524bfcd689a75e (patch)
tree7acc1ed13ec6427bf80f9ef3bf6eb4be0119663d /arch/um
parent060ed31dd9ede0726f8c88aff36c6cd8ec6d0fe8 (diff)
TTY: um/line, use tty from tty_port
This means switching to the tty refcounted model so that we will not race with interrupts. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Jeff Dike <jdike@addtoit.com> Cc: Richard Weinberger <richard@nod.at> Cc: user-mode-linux-devel@lists.sourceforge.net Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/drivers/chan_kern.c4
-rw-r--r--arch/um/drivers/line.c25
-rw-r--r--arch/um/drivers/line.h1
3 files changed, 21 insertions, 9 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 45e248c2f43c..87eebfe03c61 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -150,9 +150,11 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
150static void line_timer_cb(struct work_struct *work) 150static void line_timer_cb(struct work_struct *work)
151{ 151{
152 struct line *line = container_of(work, struct line, task.work); 152 struct line *line = container_of(work, struct line, task.work);
153 struct tty_struct *tty = tty_port_tty_get(&line->port);
153 154
154 if (!line->throttled) 155 if (!line->throttled)
155 chan_interrupt(line, line->tty, line->driver->read_irq); 156 chan_interrupt(line, tty, line->driver->read_irq);
157 tty_kref_put(tty);
156} 158}
157 159
158int enable_chan(struct line *line) 160int enable_chan(struct line *line)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 482a7bd4a64c..fb6e4ea09921 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data)
19{ 19{
20 struct chan *chan = data; 20 struct chan *chan = data;
21 struct line *line = chan->line; 21 struct line *line = chan->line;
22 struct tty_struct *tty = tty_port_tty_get(&line->port);
22 23
23 if (line) 24 if (line)
24 chan_interrupt(line, line->tty, irq); 25 chan_interrupt(line, tty, irq);
26 tty_kref_put(tty);
25 return IRQ_HANDLED; 27 return IRQ_HANDLED;
26} 28}
27 29
@@ -333,7 +335,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
333{ 335{
334 struct chan *chan = data; 336 struct chan *chan = data;
335 struct line *line = chan->line; 337 struct line *line = chan->line;
336 struct tty_struct *tty = line->tty; 338 struct tty_struct *tty;
337 int err; 339 int err;
338 340
339 /* 341 /*
@@ -352,10 +354,13 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
352 } 354 }
353 spin_unlock(&line->lock); 355 spin_unlock(&line->lock);
354 356
357 tty = tty_port_tty_get(&line->port);
355 if (tty == NULL) 358 if (tty == NULL)
356 return IRQ_NONE; 359 return IRQ_NONE;
357 360
358 tty_wakeup(tty); 361 tty_wakeup(tty);
362 tty_kref_put(tty);
363
359 return IRQ_HANDLED; 364 return IRQ_HANDLED;
360} 365}
361 366
@@ -409,7 +414,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
409 414
410 BUG_ON(tty->driver_data); 415 BUG_ON(tty->driver_data);
411 tty->driver_data = line; 416 tty->driver_data = line;
412 line->tty = tty; 417 tty_port_tty_set(&line->port, tty);
413 418
414 err = enable_chan(line); 419 err = enable_chan(line);
415 if (err) /* line_close() will be called by our caller */ 420 if (err) /* line_close() will be called by our caller */
@@ -449,7 +454,7 @@ void line_close(struct tty_struct *tty, struct file * filp)
449 if (--line->port.count) 454 if (--line->port.count)
450 goto out_unlock; 455 goto out_unlock;
451 456
452 line->tty = NULL; 457 tty_port_tty_set(&line->port, NULL);
453 tty->driver_data = NULL; 458 tty->driver_data = NULL;
454 459
455 if (line->sigio) { 460 if (line->sigio) {
@@ -610,9 +615,15 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
610 mutex_lock(&line->count_lock); 615 mutex_lock(&line->count_lock);
611 if (!line->valid) 616 if (!line->valid)
612 CONFIG_CHUNK(str, size, n, "none", 1); 617 CONFIG_CHUNK(str, size, n, "none", 1);
613 else if (line->tty == NULL) 618 else {
614 CONFIG_CHUNK(str, size, n, line->init_str, 1); 619 struct tty_struct *tty = tty_port_tty_get(&line->port);
615 else n = chan_config_string(line, str, size, error_out); 620 if (tty == NULL) {
621 CONFIG_CHUNK(str, size, n, line->init_str, 1);
622 } else {
623 n = chan_config_string(line, str, size, error_out);
624 tty_kref_put(tty);
625 }
626 }
616 mutex_unlock(&line->count_lock); 627 mutex_unlock(&line->count_lock);
617 628
618 return n; 629 return n;
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h
index 0e06a1f441d7..5b3d4fbdec18 100644
--- a/arch/um/drivers/line.h
+++ b/arch/um/drivers/line.h
@@ -33,7 +33,6 @@ struct line_driver {
33 33
34struct line { 34struct line {
35 struct tty_port port; 35 struct tty_port port;
36 struct tty_struct *tty;
37 struct mutex count_lock; 36 struct mutex count_lock;
38 int valid; 37 int valid;
39 38