aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/stallion.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:40:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commitd18a750fe9fa3b6cab882d51f99bba25bb0a006e (patch)
tree391ccab5a5847782ae48dde60a661486f434ae35 /drivers/char/stallion.c
parentd450b5a0196b6442cf3f29fc611d9c8daa56b559 (diff)
stallion: Use krefs
Use tty_port_init and krefs in the stallion drivers to protect us from devices going away underneath us. As with the other drives some rearranging is done to pass the tty structure down properly on the user side. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/stallion.c')
-rw-r--r--drivers/char/stallion.c105
1 files changed, 64 insertions, 41 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 19db1eb87c26..81b3234127db 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -405,9 +405,9 @@ static unsigned int stl_baudrates[] = {
405 405
406static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); 406static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
407static int stl_brdinit(struct stlbrd *brdp); 407static int stl_brdinit(struct stlbrd *brdp);
408static int stl_getportstats(struct stlport *portp, comstats_t __user *cp); 408static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp);
409static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); 409static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp);
410static int stl_waitcarrier(struct stlport *portp, struct file *filp); 410static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, struct file *filp);
411 411
412/* 412/*
413 * CD1400 uart specific handling functions. 413 * CD1400 uart specific handling functions.
@@ -612,8 +612,9 @@ static struct class *stallion_class;
612static void stl_cd_change(struct stlport *portp) 612static void stl_cd_change(struct stlport *portp)
613{ 613{
614 unsigned int oldsigs = portp->sigs; 614 unsigned int oldsigs = portp->sigs;
615 struct tty_struct *tty = tty_port_tty_get(&portp->port);
615 616
616 if (!portp->port.tty) 617 if (!tty)
617 return; 618 return;
618 619
619 portp->sigs = stl_getsignals(portp); 620 portp->sigs = stl_getsignals(portp);
@@ -623,7 +624,8 @@ static void stl_cd_change(struct stlport *portp)
623 624
624 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) 625 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
625 if (portp->port.flags & ASYNC_CHECK_CD) 626 if (portp->port.flags & ASYNC_CHECK_CD)
626 tty_hangup(portp->port.tty); 627 tty_hangup(tty);
628 tty_kref_put(tty);
627} 629}
628 630
629/* 631/*
@@ -734,7 +736,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
734 * On the first open of the device setup the port hardware, and 736 * On the first open of the device setup the port hardware, and
735 * initialize the per port data structure. 737 * initialize the per port data structure.
736 */ 738 */
737 portp->port.tty = tty; 739 tty_port_tty_set(&portp->port, tty);
738 tty->driver_data = portp; 740 tty->driver_data = portp;
739 portp->port.count++; 741 portp->port.count++;
740 742
@@ -774,7 +776,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
774 * then also we might have to wait for carrier. 776 * then also we might have to wait for carrier.
775 */ 777 */
776 if (!(filp->f_flags & O_NONBLOCK)) 778 if (!(filp->f_flags & O_NONBLOCK))
777 if ((rc = stl_waitcarrier(portp, filp)) != 0) 779 if ((rc = stl_waitcarrier(tty, portp, filp)) != 0)
778 return rc; 780 return rc;
779 781
780 portp->port.flags |= ASYNC_NORMAL_ACTIVE; 782 portp->port.flags |= ASYNC_NORMAL_ACTIVE;
@@ -789,7 +791,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
789 * maybe because if we are clocal then we don't need to wait... 791 * maybe because if we are clocal then we don't need to wait...
790 */ 792 */
791 793
792static int stl_waitcarrier(struct stlport *portp, struct file *filp) 794static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp,
795 struct file *filp)
793{ 796{
794 unsigned long flags; 797 unsigned long flags;
795 int rc, doclocal; 798 int rc, doclocal;
@@ -801,7 +804,7 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
801 804
802 spin_lock_irqsave(&stallion_lock, flags); 805 spin_lock_irqsave(&stallion_lock, flags);
803 806
804 if (portp->port.tty->termios->c_cflag & CLOCAL) 807 if (tty->termios->c_cflag & CLOCAL)
805 doclocal++; 808 doclocal++;
806 809
807 portp->openwaitcnt++; 810 portp->openwaitcnt++;
@@ -949,7 +952,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
949 tty_ldisc_flush(tty); 952 tty_ldisc_flush(tty);
950 953
951 tty->closing = 0; 954 tty->closing = 0;
952 portp->port.tty = NULL; 955 tty_port_tty_set(&portp->port, NULL);
953 956
954 if (portp->openwaitcnt) { 957 if (portp->openwaitcnt) {
955 if (portp->close_delay) 958 if (portp->close_delay)
@@ -1183,8 +1186,9 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
1183 * just quietly ignore any requests to change irq, etc. 1186 * just quietly ignore any requests to change irq, etc.
1184 */ 1187 */
1185 1188
1186static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) 1189static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp)
1187{ 1190{
1191 struct stlport * portp = tty->driver_data;
1188 struct serial_struct sio; 1192 struct serial_struct sio;
1189 1193
1190 pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); 1194 pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp);
@@ -1205,7 +1209,7 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp)
1205 portp->close_delay = sio.close_delay; 1209 portp->close_delay = sio.close_delay;
1206 portp->closing_wait = sio.closing_wait; 1210 portp->closing_wait = sio.closing_wait;
1207 portp->custom_divisor = sio.custom_divisor; 1211 portp->custom_divisor = sio.custom_divisor;
1208 stl_setport(portp, portp->port.tty->termios); 1212 stl_setport(portp, tty->termios);
1209 return 0; 1213 return 0;
1210} 1214}
1211 1215
@@ -1282,10 +1286,10 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
1282 rc = stl_getserial(portp, argp); 1286 rc = stl_getserial(portp, argp);
1283 break; 1287 break;
1284 case TIOCSSERIAL: 1288 case TIOCSSERIAL:
1285 rc = stl_setserial(portp, argp); 1289 rc = stl_setserial(tty, argp);
1286 break; 1290 break;
1287 case COM_GETPORTSTATS: 1291 case COM_GETPORTSTATS:
1288 rc = stl_getportstats(portp, argp); 1292 rc = stl_getportstats(tty, portp, argp);
1289 break; 1293 break;
1290 case COM_CLRPORTSTATS: 1294 case COM_CLRPORTSTATS:
1291 rc = stl_clrportstats(portp, argp); 1295 rc = stl_clrportstats(portp, argp);
@@ -1452,7 +1456,7 @@ static void stl_hangup(struct tty_struct *tty)
1452 portp->tx.head = NULL; 1456 portp->tx.head = NULL;
1453 portp->tx.tail = NULL; 1457 portp->tx.tail = NULL;
1454 } 1458 }
1455 portp->port.tty = NULL; 1459 tty_port_tty_set(&portp->port, NULL);
1456 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1460 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1457 portp->port.count = 0; 1461 portp->port.count = 0;
1458 wake_up_interruptible(&portp->port.open_wait); 1462 wake_up_interruptible(&portp->port.open_wait);
@@ -1805,7 +1809,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp)
1805 "(size=%Zd)\n", sizeof(struct stlport)); 1809 "(size=%Zd)\n", sizeof(struct stlport));
1806 break; 1810 break;
1807 } 1811 }
1808 1812 tty_port_init(&portp->port);
1809 portp->magic = STL_PORTMAGIC; 1813 portp->magic = STL_PORTMAGIC;
1810 portp->portnr = i; 1814 portp->portnr = i;
1811 portp->brdnr = panelp->brdnr; 1815 portp->brdnr = panelp->brdnr;
@@ -1832,6 +1836,7 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
1832 struct stlpanel *panelp; 1836 struct stlpanel *panelp;
1833 struct stlport *portp; 1837 struct stlport *portp;
1834 unsigned int j, k; 1838 unsigned int j, k;
1839 struct tty_struct *tty;
1835 1840
1836 for (j = 0; j < STL_MAXPANELS; j++) { 1841 for (j = 0; j < STL_MAXPANELS; j++) {
1837 panelp = brdp->panels[j]; 1842 panelp = brdp->panels[j];
@@ -1841,8 +1846,11 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
1841 portp = panelp->ports[k]; 1846 portp = panelp->ports[k];
1842 if (portp == NULL) 1847 if (portp == NULL)
1843 continue; 1848 continue;
1844 if (portp->port.tty != NULL) 1849 tty = tty_port_tty_get(&portp->port);
1845 stl_hangup(portp->port.tty); 1850 if (tty != NULL) {
1851 stl_hangup(tty);
1852 tty_kref_put(tty);
1853 }
1846 kfree(portp->tx.buf); 1854 kfree(portp->tx.buf);
1847 kfree(portp); 1855 kfree(portp);
1848 } 1856 }
@@ -2498,7 +2506,7 @@ static struct stlport *stl_getport(int brdnr, int panelnr, int portnr)
2498 * what port to get stats for (used through board control device). 2506 * what port to get stats for (used through board control device).
2499 */ 2507 */
2500 2508
2501static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) 2509static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp)
2502{ 2510{
2503 comstats_t stl_comstats; 2511 comstats_t stl_comstats;
2504 unsigned char *head, *tail; 2512 unsigned char *head, *tail;
@@ -2525,18 +2533,17 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
2525 portp->stats.rxbuffered = 0; 2533 portp->stats.rxbuffered = 0;
2526 2534
2527 spin_lock_irqsave(&stallion_lock, flags); 2535 spin_lock_irqsave(&stallion_lock, flags);
2528 if (portp->port.tty != NULL) 2536 if (tty != NULL && portp->port.tty == tty) {
2529 if (portp->port.tty->driver_data == portp) { 2537 portp->stats.ttystate = tty->flags;
2530 portp->stats.ttystate = portp->port.tty->flags; 2538 /* No longer available as a statistic */
2531 /* No longer available as a statistic */ 2539 portp->stats.rxbuffered = 1; /*tty->flip.count; */
2532 portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */ 2540 if (tty->termios != NULL) {
2533 if (portp->port.tty->termios != NULL) { 2541 portp->stats.cflags = tty->termios->c_cflag;
2534 portp->stats.cflags = portp->port.tty->termios->c_cflag; 2542 portp->stats.iflags = tty->termios->c_iflag;
2535 portp->stats.iflags = portp->port.tty->termios->c_iflag; 2543 portp->stats.oflags = tty->termios->c_oflag;
2536 portp->stats.oflags = portp->port.tty->termios->c_oflag; 2544 portp->stats.lflags = tty->termios->c_lflag;
2537 portp->stats.lflags = portp->port.tty->termios->c_lflag;
2538 }
2539 } 2545 }
2546 }
2540 spin_unlock_irqrestore(&stallion_lock, flags); 2547 spin_unlock_irqrestore(&stallion_lock, flags);
2541 2548
2542 head = portp->tx.head; 2549 head = portp->tx.head;
@@ -2640,7 +2647,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns
2640 2647
2641 switch (cmd) { 2648 switch (cmd) {
2642 case COM_GETPORTSTATS: 2649 case COM_GETPORTSTATS:
2643 rc = stl_getportstats(NULL, argp); 2650 rc = stl_getportstats(NULL, NULL, argp);
2644 break; 2651 break;
2645 case COM_CLRPORTSTATS: 2652 case COM_CLRPORTSTATS:
2646 rc = stl_clrportstats(NULL, argp); 2653 rc = stl_clrportstats(NULL, argp);
@@ -3243,7 +3250,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)
3243 3250
3244 if (portp == NULL) 3251 if (portp == NULL)
3245 return; 3252 return;
3246 tty = portp->port.tty; 3253 tty = tty_port_tty_get(&portp->port);
3247 if (tty == NULL) 3254 if (tty == NULL)
3248 return; 3255 return;
3249 3256
@@ -3288,6 +3295,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)
3288 3295
3289 BRDDISABLE(portp->brdnr); 3296 BRDDISABLE(portp->brdnr);
3290 spin_unlock_irqrestore(&brd_lock, flags); 3297 spin_unlock_irqrestore(&brd_lock, flags);
3298 tty_kref_put(tty);
3291} 3299}
3292 3300
3293/*****************************************************************************/ 3301/*****************************************************************************/
@@ -3305,7 +3313,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)
3305 3313
3306 if (portp == NULL) 3314 if (portp == NULL)
3307 return; 3315 return;
3308 tty = portp->port.tty; 3316 tty = tty_port_tty_get(&portp->port);
3309 if (tty == NULL) 3317 if (tty == NULL)
3310 return; 3318 return;
3311 3319
@@ -3325,6 +3333,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)
3325 } 3333 }
3326 BRDDISABLE(portp->brdnr); 3334 BRDDISABLE(portp->brdnr);
3327 spin_unlock_irqrestore(&brd_lock, flags); 3335 spin_unlock_irqrestore(&brd_lock, flags);
3336 tty_kref_put(tty);
3328} 3337}
3329 3338
3330/*****************************************************************************/ 3339/*****************************************************************************/
@@ -3478,6 +3487,7 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
3478 int len, stlen; 3487 int len, stlen;
3479 char *head, *tail; 3488 char *head, *tail;
3480 unsigned char ioack, srer; 3489 unsigned char ioack, srer;
3490 struct tty_struct *tty;
3481 3491
3482 pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); 3492 pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr);
3483 3493
@@ -3504,8 +3514,11 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
3504 if ((len == 0) || ((len < STL_TXBUFLOW) && 3514 if ((len == 0) || ((len < STL_TXBUFLOW) &&
3505 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { 3515 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
3506 set_bit(ASYI_TXLOW, &portp->istate); 3516 set_bit(ASYI_TXLOW, &portp->istate);
3507 if (portp->port.tty) 3517 tty = tty_port_tty_get(&portp->port);
3508 tty_wakeup(portp->port.tty); 3518 if (tty) {
3519 tty_wakeup(tty);
3520 tty_kref_put(tty);
3521 }
3509 } 3522 }
3510 3523
3511 if (len == 0) { 3524 if (len == 0) {
@@ -3569,7 +3582,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
3569 return; 3582 return;
3570 } 3583 }
3571 portp = panelp->ports[(ioack >> 3)]; 3584 portp = panelp->ports[(ioack >> 3)];
3572 tty = portp->port.tty; 3585 tty = tty_port_tty_get(&portp->port);
3573 3586
3574 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { 3587 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
3575 outb((RDCR + portp->uartaddr), ioaddr); 3588 outb((RDCR + portp->uartaddr), ioaddr);
@@ -3633,10 +3646,12 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
3633 } 3646 }
3634 } else { 3647 } else {
3635 printk("STALLION: bad RX interrupt ack value=%x\n", ioack); 3648 printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
3649 tty_kref_put(tty);
3636 return; 3650 return;
3637 } 3651 }
3638 3652
3639stl_rxalldone: 3653stl_rxalldone:
3654 tty_kref_put(tty);
3640 outb((EOSRR + portp->uartaddr), ioaddr); 3655 outb((EOSRR + portp->uartaddr), ioaddr);
3641 outb(0, (ioaddr + EREG_DATA)); 3656 outb(0, (ioaddr + EREG_DATA));
3642} 3657}
@@ -4175,7 +4190,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)
4175 4190
4176 if (portp == NULL) 4191 if (portp == NULL)
4177 return; 4192 return;
4178 tty = portp->port.tty; 4193 tty = tty_port_tty_get(&portp->port);
4179 if (tty == NULL) 4194 if (tty == NULL)
4180 return; 4195 return;
4181 4196
@@ -4226,6 +4241,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)
4226 4241
4227 BRDDISABLE(portp->brdnr); 4242 BRDDISABLE(portp->brdnr);
4228 spin_unlock_irqrestore(&brd_lock, flags); 4243 spin_unlock_irqrestore(&brd_lock, flags);
4244 tty_kref_put(tty);
4229} 4245}
4230 4246
4231/*****************************************************************************/ 4247/*****************************************************************************/
@@ -4244,7 +4260,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)
4244 4260
4245 if (portp == NULL) 4261 if (portp == NULL)
4246 return; 4262 return;
4247 tty = portp->port.tty; 4263 tty = tty_port_tty_get(&portp->port);
4248 if (tty == NULL) 4264 if (tty == NULL)
4249 return; 4265 return;
4250 4266
@@ -4269,6 +4285,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)
4269 } 4285 }
4270 BRDDISABLE(portp->brdnr); 4286 BRDDISABLE(portp->brdnr);
4271 spin_unlock_irqrestore(&brd_lock, flags); 4287 spin_unlock_irqrestore(&brd_lock, flags);
4288 tty_kref_put(tty);
4272} 4289}
4273 4290
4274/*****************************************************************************/ 4291/*****************************************************************************/
@@ -4408,6 +4425,7 @@ static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase)
4408 4425
4409static void stl_sc26198txisr(struct stlport *portp) 4426static void stl_sc26198txisr(struct stlport *portp)
4410{ 4427{
4428 struct tty_struct *tty;
4411 unsigned int ioaddr; 4429 unsigned int ioaddr;
4412 unsigned char mr0; 4430 unsigned char mr0;
4413 int len, stlen; 4431 int len, stlen;
@@ -4422,8 +4440,11 @@ static void stl_sc26198txisr(struct stlport *portp)
4422 if ((len == 0) || ((len < STL_TXBUFLOW) && 4440 if ((len == 0) || ((len < STL_TXBUFLOW) &&
4423 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { 4441 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
4424 set_bit(ASYI_TXLOW, &portp->istate); 4442 set_bit(ASYI_TXLOW, &portp->istate);
4425 if (portp->port.tty) 4443 tty = tty_port_tty_get(&portp->port);
4426 tty_wakeup(portp->port.tty); 4444 if (tty) {
4445 tty_wakeup(tty);
4446 tty_kref_put(tty);
4447 }
4427 } 4448 }
4428 4449
4429 if (len == 0) { 4450 if (len == 0) {
@@ -4476,7 +4497,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
4476 4497
4477 pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); 4498 pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);
4478 4499
4479 tty = portp->port.tty; 4500 tty = tty_port_tty_get(&portp->port);
4480 ioaddr = portp->ioaddr; 4501 ioaddr = portp->ioaddr;
4481 outb(GIBCR, (ioaddr + XP_ADDR)); 4502 outb(GIBCR, (ioaddr + XP_ADDR));
4482 len = inb(ioaddr + XP_DATA) + 1; 4503 len = inb(ioaddr + XP_DATA) + 1;
@@ -4515,6 +4536,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
4515 stl_sc26198txunflow(portp, tty); 4536 stl_sc26198txunflow(portp, tty);
4516 } 4537 }
4517 } 4538 }
4539 tty_kref_put(tty);
4518} 4540}
4519 4541
4520/*****************************************************************************/ 4542/*****************************************************************************/
@@ -4528,7 +4550,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
4528 struct tty_struct *tty; 4550 struct tty_struct *tty;
4529 unsigned int ioaddr; 4551 unsigned int ioaddr;
4530 4552
4531 tty = portp->port.tty; 4553 tty = tty_port_tty_get(&portp->port);
4532 ioaddr = portp->ioaddr; 4554 ioaddr = portp->ioaddr;
4533 4555
4534 if (status & SR_RXPARITY) 4556 if (status & SR_RXPARITY)
@@ -4566,6 +4588,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
4566 if (status == 0) 4588 if (status == 0)
4567 portp->stats.rxtotal++; 4589 portp->stats.rxtotal++;
4568 } 4590 }
4591 tty_kref_put(tty);
4569} 4592}
4570 4593
4571/*****************************************************************************/ 4594/*****************************************************************************/