aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rocket.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:48:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:41 -0500
commit47b01b3a5fc7239f3e8d5d5cadc88afbea24d0c3 (patch)
tree74faa32048c31c53efb2789bec407e1c40d06bdc /drivers/char/rocket.c
parent21bed701da009b4192d9e86b3596cf210ac7369c (diff)
tty: kref the rocket driver
We will need this kref fitted to make full use of the port operations. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/rocket.c')
-rw-r--r--drivers/char/rocket.c78
1 files changed, 41 insertions, 37 deletions
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index ca6fcdcca56e..b5e5e77c59de 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -436,15 +436,15 @@ static void rp_do_transmit(struct r_port *info)
436#endif 436#endif
437 if (!info) 437 if (!info)
438 return; 438 return;
439 if (!info->port.tty) { 439 tty = tty_port_tty_get(&info->port);
440 printk(KERN_WARNING "rp: WARNING %s called with " 440
441 "info->port.tty==NULL\n", __func__); 441 if (tty == NULL) {
442 printk(KERN_WARNING "rp: WARNING %s called with tty==NULL\n", __func__);
442 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 443 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
443 return; 444 return;
444 } 445 }
445 446
446 spin_lock_irqsave(&info->slock, flags); 447 spin_lock_irqsave(&info->slock, flags);
447 tty = info->port.tty;
448 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); 448 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
449 449
450 /* Loop sending data to FIFO until done or FIFO full */ 450 /* Loop sending data to FIFO until done or FIFO full */
@@ -478,6 +478,7 @@ static void rp_do_transmit(struct r_port *info)
478 } 478 }
479 479
480 spin_unlock_irqrestore(&info->slock, flags); 480 spin_unlock_irqrestore(&info->slock, flags);
481 tty_kref_put(tty);
481 482
482#ifdef ROCKET_DEBUG_INTR 483#ifdef ROCKET_DEBUG_INTR
483 printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head, 484 printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head,
@@ -504,13 +505,13 @@ static void rp_handle_port(struct r_port *info)
504 "info->flags & NOT_INIT\n"); 505 "info->flags & NOT_INIT\n");
505 return; 506 return;
506 } 507 }
507 if (!info->port.tty) { 508 tty = tty_port_tty_get(&info->port);
509 if (!tty) {
508 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " 510 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
509 "info->port.tty==NULL\n"); 511 "tty==NULL\n");
510 return; 512 return;
511 } 513 }
512 cp = &info->channel; 514 cp = &info->channel;
513 tty = info->port.tty;
514 515
515 IntMask = sGetChanIntID(cp) & info->intmask; 516 IntMask = sGetChanIntID(cp) & info->intmask;
516#ifdef ROCKET_DEBUG_INTR 517#ifdef ROCKET_DEBUG_INTR
@@ -542,6 +543,7 @@ static void rp_handle_port(struct r_port *info)
542 printk(KERN_INFO "DSR change...\n"); 543 printk(KERN_INFO "DSR change...\n");
543 } 544 }
544#endif 545#endif
546 tty_kref_put(tty);
545} 547}
546 548
547/* 549/*
@@ -710,7 +712,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
710 * Configures a rocketport port according to its termio settings. Called from 712 * Configures a rocketport port according to its termio settings. Called from
711 * user mode into the driver (exception handler). *info CD manipulation is spinlock protected. 713 * user mode into the driver (exception handler). *info CD manipulation is spinlock protected.
712 */ 714 */
713static void configure_r_port(struct r_port *info, 715static void configure_r_port(struct tty_struct *tty, struct r_port *info,
714 struct ktermios *old_termios) 716 struct ktermios *old_termios)
715{ 717{
716 unsigned cflag; 718 unsigned cflag;
@@ -718,7 +720,7 @@ static void configure_r_port(struct r_port *info,
718 unsigned rocketMode; 720 unsigned rocketMode;
719 int bits, baud, divisor; 721 int bits, baud, divisor;
720 CHANNEL_t *cp; 722 CHANNEL_t *cp;
721 struct ktermios *t = info->port.tty->termios; 723 struct ktermios *t = tty->termios;
722 724
723 cp = &info->channel; 725 cp = &info->channel;
724 cflag = t->c_cflag; 726 cflag = t->c_cflag;
@@ -751,7 +753,7 @@ static void configure_r_port(struct r_port *info,
751 } 753 }
752 754
753 /* baud rate */ 755 /* baud rate */
754 baud = tty_get_baud_rate(info->port.tty); 756 baud = tty_get_baud_rate(tty);
755 if (!baud) 757 if (!baud)
756 baud = 9600; 758 baud = 9600;
757 divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1; 759 divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
@@ -769,7 +771,7 @@ static void configure_r_port(struct r_port *info,
769 sSetBaud(cp, divisor); 771 sSetBaud(cp, divisor);
770 772
771 /* FIXME: Should really back compute a baud rate from the divisor */ 773 /* FIXME: Should really back compute a baud rate from the divisor */
772 tty_encode_baud_rate(info->port.tty, baud, baud); 774 tty_encode_baud_rate(tty, baud, baud);
773 775
774 if (cflag & CRTSCTS) { 776 if (cflag & CRTSCTS) {
775 info->intmask |= DELTA_CTS; 777 info->intmask |= DELTA_CTS;
@@ -794,15 +796,15 @@ static void configure_r_port(struct r_port *info,
794 * Handle software flow control in the board 796 * Handle software flow control in the board
795 */ 797 */
796#ifdef ROCKET_SOFT_FLOW 798#ifdef ROCKET_SOFT_FLOW
797 if (I_IXON(info->port.tty)) { 799 if (I_IXON(tty)) {
798 sEnTxSoftFlowCtl(cp); 800 sEnTxSoftFlowCtl(cp);
799 if (I_IXANY(info->port.tty)) { 801 if (I_IXANY(tty)) {
800 sEnIXANY(cp); 802 sEnIXANY(cp);
801 } else { 803 } else {
802 sDisIXANY(cp); 804 sDisIXANY(cp);
803 } 805 }
804 sSetTxXONChar(cp, START_CHAR(info->port.tty)); 806 sSetTxXONChar(cp, START_CHAR(tty));
805 sSetTxXOFFChar(cp, STOP_CHAR(info->port.tty)); 807 sSetTxXOFFChar(cp, STOP_CHAR(tty));
806 } else { 808 } else {
807 sDisTxSoftFlowCtl(cp); 809 sDisTxSoftFlowCtl(cp);
808 sDisIXANY(cp); 810 sDisIXANY(cp);
@@ -814,24 +816,24 @@ static void configure_r_port(struct r_port *info,
814 * Set up ignore/read mask words 816 * Set up ignore/read mask words
815 */ 817 */
816 info->read_status_mask = STMRCVROVRH | 0xFF; 818 info->read_status_mask = STMRCVROVRH | 0xFF;
817 if (I_INPCK(info->port.tty)) 819 if (I_INPCK(tty))
818 info->read_status_mask |= STMFRAMEH | STMPARITYH; 820 info->read_status_mask |= STMFRAMEH | STMPARITYH;
819 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) 821 if (I_BRKINT(tty) || I_PARMRK(tty))
820 info->read_status_mask |= STMBREAKH; 822 info->read_status_mask |= STMBREAKH;
821 823
822 /* 824 /*
823 * Characters to ignore 825 * Characters to ignore
824 */ 826 */
825 info->ignore_status_mask = 0; 827 info->ignore_status_mask = 0;
826 if (I_IGNPAR(info->port.tty)) 828 if (I_IGNPAR(tty))
827 info->ignore_status_mask |= STMFRAMEH | STMPARITYH; 829 info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
828 if (I_IGNBRK(info->port.tty)) { 830 if (I_IGNBRK(tty)) {
829 info->ignore_status_mask |= STMBREAKH; 831 info->ignore_status_mask |= STMBREAKH;
830 /* 832 /*
831 * If we're ignoring parity and break indicators, 833 * If we're ignoring parity and break indicators,
832 * ignore overruns too. (For real raw support). 834 * ignore overruns too. (For real raw support).
833 */ 835 */
834 if (I_IGNPAR(info->port.tty)) 836 if (I_IGNPAR(tty))
835 info->ignore_status_mask |= STMRCVROVRH; 837 info->ignore_status_mask |= STMRCVROVRH;
836 } 838 }
837 839
@@ -1015,7 +1017,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1015 info->xmit_buf = (unsigned char *) page; 1017 info->xmit_buf = (unsigned char *) page;
1016 1018
1017 tty->driver_data = info; 1019 tty->driver_data = info;
1018 info->port.tty = tty; 1020 tty_port_tty_set(&info->port, tty);
1019 1021
1020 if (info->port.count++ == 0) { 1022 if (info->port.count++ == 0) {
1021 atomic_inc(&rp_num_ports_open); 1023 atomic_inc(&rp_num_ports_open);
@@ -1062,15 +1064,15 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1062 * Set up the tty->alt_speed kludge 1064 * Set up the tty->alt_speed kludge
1063 */ 1065 */
1064 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) 1066 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1065 info->port.tty->alt_speed = 57600; 1067 tty->alt_speed = 57600;
1066 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) 1068 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1067 info->port.tty->alt_speed = 115200; 1069 tty->alt_speed = 115200;
1068 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) 1070 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1069 info->port.tty->alt_speed = 230400; 1071 tty->alt_speed = 230400;
1070 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) 1072 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1071 info->port.tty->alt_speed = 460800; 1073 tty->alt_speed = 460800;
1072 1074
1073 configure_r_port(info, NULL); 1075 configure_r_port(tty, info, NULL);
1074 if (tty->termios->c_cflag & CBAUD) { 1076 if (tty->termios->c_cflag & CBAUD) {
1075 sSetDTR(cp); 1077 sSetDTR(cp);
1076 sSetRTS(cp); 1078 sSetRTS(cp);
@@ -1227,7 +1229,7 @@ static void rp_set_termios(struct tty_struct *tty,
1227 /* Or CMSPAR */ 1229 /* Or CMSPAR */
1228 tty->termios->c_cflag &= ~CMSPAR; 1230 tty->termios->c_cflag &= ~CMSPAR;
1229 1231
1230 configure_r_port(info, old_termios); 1232 configure_r_port(tty, info, old_termios);
1231 1233
1232 cp = &info->channel; 1234 cp = &info->channel;
1233 1235
@@ -1352,7 +1354,8 @@ static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1352 return 0; 1354 return 0;
1353} 1355}
1354 1356
1355static int set_config(struct r_port *info, struct rocket_config __user *new_info) 1357static int set_config(struct tty_struct *tty, struct r_port *info,
1358 struct rocket_config __user *new_info)
1356{ 1359{
1357 struct rocket_config new_serial; 1360 struct rocket_config new_serial;
1358 1361
@@ -1364,7 +1367,7 @@ static int set_config(struct r_port *info, struct rocket_config __user *new_info
1364 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) 1367 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
1365 return -EPERM; 1368 return -EPERM;
1366 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); 1369 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
1367 configure_r_port(info, NULL); 1370 configure_r_port(tty, info, NULL);
1368 return 0; 1371 return 0;
1369 } 1372 }
1370 1373
@@ -1373,15 +1376,15 @@ static int set_config(struct r_port *info, struct rocket_config __user *new_info
1373 info->port.closing_wait = new_serial.closing_wait; 1376 info->port.closing_wait = new_serial.closing_wait;
1374 1377
1375 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) 1378 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1376 info->port.tty->alt_speed = 57600; 1379 tty->alt_speed = 57600;
1377 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) 1380 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1378 info->port.tty->alt_speed = 115200; 1381 tty->alt_speed = 115200;
1379 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) 1382 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1380 info->port.tty->alt_speed = 230400; 1383 tty->alt_speed = 230400;
1381 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) 1384 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1382 info->port.tty->alt_speed = 460800; 1385 tty->alt_speed = 460800;
1383 1386
1384 configure_r_port(info, NULL); 1387 configure_r_port(tty, info, NULL);
1385 return 0; 1388 return 0;
1386} 1389}
1387 1390
@@ -1466,7 +1469,7 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file,
1466 ret = get_config(info, argp); 1469 ret = get_config(info, argp);
1467 break; 1470 break;
1468 case RCKP_SET_CONFIG: 1471 case RCKP_SET_CONFIG:
1469 ret = set_config(info, argp); 1472 ret = set_config(tty, info, argp);
1470 break; 1473 break;
1471 case RCKP_GET_PORTS: 1474 case RCKP_GET_PORTS:
1472 ret = get_ports(info, argp); 1475 ret = get_ports(info, argp);
@@ -1658,7 +1661,7 @@ static void rp_hangup(struct tty_struct *tty)
1658 1661
1659 info->port.count = 0; 1662 info->port.count = 0;
1660 info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1663 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1661 info->port.tty = NULL; 1664 tty_port_tty_set(&info->port, NULL);
1662 1665
1663 cp = &info->channel; 1666 cp = &info->channel;
1664 sDisRxFIFO(cp); 1667 sDisRxFIFO(cp);
@@ -1778,7 +1781,8 @@ static int rp_write(struct tty_struct *tty,
1778 1781
1779 /* Write remaining data into the port's xmit_buf */ 1782 /* Write remaining data into the port's xmit_buf */
1780 while (1) { 1783 while (1) {
1781 if (!info->port.tty) /* Seemingly obligatory check... */ 1784 /* Hung up ? */
1785 if (!test_bit(ASYNC_NORMAL_ACTIVE, &info->port.flags))
1782 goto end; 1786 goto end;
1783 c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); 1787 c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
1784 c = min(c, XMIT_BUF_SIZE - info->xmit_head); 1788 c = min(c, XMIT_BUF_SIZE - info->xmit_head);