aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:48:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:41 -0500
commit3969ffba71d39ced700d09d9cfde83174396299e (patch)
tree8cbb5528f31ed4ca44eb0fd7ecdd45db8d5acef4 /drivers/char
parentd1c815e549ff40f9e9db65654855118e6bdff6a4 (diff)
tty: refcount the epca driver
Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/epca.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index e07d7925c300..7a697055e4f6 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -175,7 +175,7 @@ static unsigned termios2digi_h(struct channel *ch, unsigned);
175static unsigned termios2digi_i(struct channel *ch, unsigned); 175static unsigned termios2digi_i(struct channel *ch, unsigned);
176static unsigned termios2digi_c(struct channel *ch, unsigned); 176static unsigned termios2digi_c(struct channel *ch, unsigned);
177static void epcaparam(struct tty_struct *, struct channel *); 177static void epcaparam(struct tty_struct *, struct channel *);
178static void receive_data(struct channel *); 178static void receive_data(struct channel *, struct tty_struct *tty);
179static int pc_ioctl(struct tty_struct *, struct file *, 179static int pc_ioctl(struct tty_struct *, struct file *,
180 unsigned int, unsigned long); 180 unsigned int, unsigned long);
181static int info_ioctl(struct tty_struct *, struct file *, 181static int info_ioctl(struct tty_struct *, struct file *,
@@ -473,7 +473,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
473 spin_lock_irqsave(&port->lock, flags); 473 spin_lock_irqsave(&port->lock, flags);
474 tty->closing = 0; 474 tty->closing = 0;
475 ch->event = 0; 475 ch->event = 0;
476 port->tty = NULL; 476 tty_port_tty_set(port, NULL);
477 spin_unlock_irqrestore(&port->lock, flags); 477 spin_unlock_irqrestore(&port->lock, flags);
478 478
479 if (port->blocked_open) { 479 if (port->blocked_open) {
@@ -1029,8 +1029,11 @@ static void __exit epca_module_exit(void)
1029 } 1029 }
1030 ch = card_ptr[crd]; 1030 ch = card_ptr[crd];
1031 for (count = 0; count < bd->numports; count++, ch++) { 1031 for (count = 0; count < bd->numports; count++, ch++) {
1032 if (ch && ch->port.tty) 1032 struct tty_struct *tty = tty_port_tty_get(&ch->port);
1033 tty_hangup(ch->port.tty); 1033 if (tty) {
1034 tty_hangup(tty);
1035 tty_kref_put(tty);
1036 }
1034 } 1037 }
1035 } 1038 }
1036 pci_unregister_driver(&epca_driver); 1039 pci_unregister_driver(&epca_driver);
@@ -1441,7 +1444,7 @@ static void post_fep_init(unsigned int crd)
1441 ch->boardnum = crd; 1444 ch->boardnum = crd;
1442 ch->channelnum = i; 1445 ch->channelnum = i;
1443 ch->magic = EPCA_MAGIC; 1446 ch->magic = EPCA_MAGIC;
1444 ch->port.tty = NULL; 1447 tty_port_tty_set(&ch->port, NULL);
1445 1448
1446 if (shrinkmem) { 1449 if (shrinkmem) {
1447 fepcmd(ch, SETBUFFER, 32, 0, 0, 0); 1450 fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
@@ -1635,8 +1638,9 @@ static void doevent(int crd)
1635 if (bc == NULL) 1638 if (bc == NULL)
1636 goto next; 1639 goto next;
1637 1640
1641 tty = tty_port_tty_get(&ch->port);
1638 if (event & DATA_IND) { /* Begin DATA_IND */ 1642 if (event & DATA_IND) { /* Begin DATA_IND */
1639 receive_data(ch); 1643 receive_data(ch, tty);
1640 assertgwinon(ch); 1644 assertgwinon(ch);
1641 } /* End DATA_IND */ 1645 } /* End DATA_IND */
1642 /* else *//* Fix for DCD transition missed bug */ 1646 /* else *//* Fix for DCD transition missed bug */
@@ -1651,7 +1655,6 @@ static void doevent(int crd)
1651 pc_sched_event(ch, EPCA_EVENT_HANGUP); 1655 pc_sched_event(ch, EPCA_EVENT_HANGUP);
1652 } 1656 }
1653 } 1657 }
1654 tty = ch->port.tty;
1655 if (tty) { 1658 if (tty) {
1656 if (event & BREAK_IND) { 1659 if (event & BREAK_IND) {
1657 /* A break has been indicated */ 1660 /* A break has been indicated */
@@ -1671,6 +1674,7 @@ static void doevent(int crd)
1671 tty_wakeup(tty); 1674 tty_wakeup(tty);
1672 } 1675 }
1673 } 1676 }
1677 tty_kref_put(tty);
1674 } 1678 }
1675next: 1679next:
1676 globalwinon(ch); 1680 globalwinon(ch);
@@ -1965,11 +1969,10 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
1965} 1969}
1966 1970
1967/* Caller holds lock */ 1971/* Caller holds lock */
1968static void receive_data(struct channel *ch) 1972static void receive_data(struct channel *ch, struct tty_struct *tty)
1969{ 1973{
1970 unchar *rptr; 1974 unchar *rptr;
1971 struct ktermios *ts = NULL; 1975 struct ktermios *ts = NULL;
1972 struct tty_struct *tty;
1973 struct board_chan __iomem *bc; 1976 struct board_chan __iomem *bc;
1974 int dataToRead, wrapgap, bytesAvailable; 1977 int dataToRead, wrapgap, bytesAvailable;
1975 unsigned int tail, head; 1978 unsigned int tail, head;
@@ -1982,7 +1985,6 @@ static void receive_data(struct channel *ch)
1982 globalwinon(ch); 1985 globalwinon(ch);
1983 if (ch->statusflags & RXSTOPPED) 1986 if (ch->statusflags & RXSTOPPED)
1984 return; 1987 return;
1985 tty = ch->port.tty;
1986 if (tty) 1988 if (tty)
1987 ts = tty->termios; 1989 ts = tty->termios;
1988 bc = ch->brdchan; 1990 bc = ch->brdchan;
@@ -2042,7 +2044,7 @@ static void receive_data(struct channel *ch)
2042 globalwinon(ch); 2044 globalwinon(ch);
2043 writew(tail, &bc->rout); 2045 writew(tail, &bc->rout);
2044 /* Must be called with global data */ 2046 /* Must be called with global data */
2045 tty_schedule_flip(ch->port.tty); 2047 tty_schedule_flip(tty);
2046} 2048}
2047 2049
2048static int info_ioctl(struct tty_struct *tty, struct file *file, 2050static int info_ioctl(struct tty_struct *tty, struct file *file,
@@ -2365,7 +2367,7 @@ static void do_softint(struct work_struct *work)
2365 struct channel *ch = container_of(work, struct channel, tqueue); 2367 struct channel *ch = container_of(work, struct channel, tqueue);
2366 /* Called in response to a modem change event */ 2368 /* Called in response to a modem change event */
2367 if (ch && ch->magic == EPCA_MAGIC) { 2369 if (ch && ch->magic == EPCA_MAGIC) {
2368 struct tty_struct *tty = ch->port.tty; 2370 struct tty_struct *tty = tty_port_tty_get(&ch->port);;
2369 2371
2370 if (tty && tty->driver_data) { 2372 if (tty && tty->driver_data) {
2371 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { 2373 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
@@ -2374,6 +2376,7 @@ static void do_softint(struct work_struct *work)
2374 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; 2376 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2375 } 2377 }
2376 } 2378 }
2379 tty_kref_put(tty);
2377 } 2380 }
2378} 2381}
2379 2382