aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/stallion.c
diff options
context:
space:
mode:
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/*****************************************************************************/