diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/char/stallion.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/char/stallion.c')
-rw-r--r-- | drivers/char/stallion.c | 132 |
1 files changed, 44 insertions, 88 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index db6dcfa35ba0..6049fd731924 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -407,7 +407,7 @@ static unsigned int stl_baudrates[] = { | |||
407 | * Declare all those functions in this driver! | 407 | * Declare all those functions in this driver! |
408 | */ | 408 | */ |
409 | 409 | ||
410 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 410 | static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); |
411 | static int stl_brdinit(struct stlbrd *brdp); | 411 | static int stl_brdinit(struct stlbrd *brdp); |
412 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); | 412 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); |
413 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); | 413 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); |
@@ -607,7 +607,7 @@ static unsigned int sc26198_baudtable[] = { | |||
607 | */ | 607 | */ |
608 | static const struct file_operations stl_fsiomem = { | 608 | static const struct file_operations stl_fsiomem = { |
609 | .owner = THIS_MODULE, | 609 | .owner = THIS_MODULE, |
610 | .ioctl = stl_memioctl, | 610 | .unlocked_ioctl = stl_memioctl, |
611 | }; | 611 | }; |
612 | 612 | ||
613 | static struct class *stallion_class; | 613 | static struct class *stallion_class; |
@@ -702,11 +702,28 @@ static struct stlbrd *stl_allocbrd(void) | |||
702 | 702 | ||
703 | /*****************************************************************************/ | 703 | /*****************************************************************************/ |
704 | 704 | ||
705 | static int stl_activate(struct tty_port *port, struct tty_struct *tty) | ||
706 | { | ||
707 | struct stlport *portp = container_of(port, struct stlport, port); | ||
708 | if (!portp->tx.buf) { | ||
709 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
710 | if (!portp->tx.buf) | ||
711 | return -ENOMEM; | ||
712 | portp->tx.head = portp->tx.buf; | ||
713 | portp->tx.tail = portp->tx.buf; | ||
714 | } | ||
715 | stl_setport(portp, tty->termios); | ||
716 | portp->sigs = stl_getsignals(portp); | ||
717 | stl_setsignals(portp, 1, 1); | ||
718 | stl_enablerxtx(portp, 1, 1); | ||
719 | stl_startrxtx(portp, 1, 0); | ||
720 | return 0; | ||
721 | } | ||
722 | |||
705 | static int stl_open(struct tty_struct *tty, struct file *filp) | 723 | static int stl_open(struct tty_struct *tty, struct file *filp) |
706 | { | 724 | { |
707 | struct stlport *portp; | 725 | struct stlport *portp; |
708 | struct stlbrd *brdp; | 726 | struct stlbrd *brdp; |
709 | struct tty_port *port; | ||
710 | unsigned int minordev, brdnr, panelnr; | 727 | unsigned int minordev, brdnr, panelnr; |
711 | int portnr; | 728 | int portnr; |
712 | 729 | ||
@@ -736,33 +753,10 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
736 | portp = brdp->panels[panelnr]->ports[portnr]; | 753 | portp = brdp->panels[panelnr]->ports[portnr]; |
737 | if (portp == NULL) | 754 | if (portp == NULL) |
738 | return -ENODEV; | 755 | return -ENODEV; |
739 | port = &portp->port; | ||
740 | 756 | ||
741 | /* | ||
742 | * On the first open of the device setup the port hardware, and | ||
743 | * initialize the per port data structure. | ||
744 | */ | ||
745 | tty_port_tty_set(port, tty); | ||
746 | tty->driver_data = portp; | 757 | tty->driver_data = portp; |
747 | port->count++; | 758 | return tty_port_open(&portp->port, tty, filp); |
748 | 759 | ||
749 | if ((port->flags & ASYNC_INITIALIZED) == 0) { | ||
750 | if (!portp->tx.buf) { | ||
751 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
752 | if (!portp->tx.buf) | ||
753 | return -ENOMEM; | ||
754 | portp->tx.head = portp->tx.buf; | ||
755 | portp->tx.tail = portp->tx.buf; | ||
756 | } | ||
757 | stl_setport(portp, tty->termios); | ||
758 | portp->sigs = stl_getsignals(portp); | ||
759 | stl_setsignals(portp, 1, 1); | ||
760 | stl_enablerxtx(portp, 1, 1); | ||
761 | stl_startrxtx(portp, 1, 0); | ||
762 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
763 | port->flags |= ASYNC_INITIALIZED; | ||
764 | } | ||
765 | return tty_port_block_til_ready(port, tty, filp); | ||
766 | } | 760 | } |
767 | 761 | ||
768 | /*****************************************************************************/ | 762 | /*****************************************************************************/ |
@@ -826,38 +820,12 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
826 | 820 | ||
827 | /*****************************************************************************/ | 821 | /*****************************************************************************/ |
828 | 822 | ||
829 | static void stl_close(struct tty_struct *tty, struct file *filp) | 823 | static void stl_shutdown(struct tty_port *port) |
830 | { | 824 | { |
831 | struct stlport *portp; | 825 | struct stlport *portp = container_of(port, struct stlport, port); |
832 | struct tty_port *port; | ||
833 | unsigned long flags; | ||
834 | |||
835 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | ||
836 | |||
837 | portp = tty->driver_data; | ||
838 | BUG_ON(portp == NULL); | ||
839 | |||
840 | port = &portp->port; | ||
841 | |||
842 | if (tty_port_close_start(port, tty, filp) == 0) | ||
843 | return; | ||
844 | /* | ||
845 | * May want to wait for any data to drain before closing. The BUSY | ||
846 | * flag keeps track of whether we are still sending or not - it is | ||
847 | * very accurate for the cd1400, not quite so for the sc26198. | ||
848 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | ||
849 | */ | ||
850 | stl_waituntilsent(tty, (HZ / 2)); | ||
851 | |||
852 | spin_lock_irqsave(&port->lock, flags); | ||
853 | portp->port.flags &= ~ASYNC_INITIALIZED; | ||
854 | spin_unlock_irqrestore(&port->lock, flags); | ||
855 | |||
856 | stl_disableintrs(portp); | 826 | stl_disableintrs(portp); |
857 | if (tty->termios->c_cflag & HUPCL) | ||
858 | stl_setsignals(portp, 0, 0); | ||
859 | stl_enablerxtx(portp, 0, 0); | 827 | stl_enablerxtx(portp, 0, 0); |
860 | stl_flushbuffer(tty); | 828 | stl_flush(portp); |
861 | portp->istate = 0; | 829 | portp->istate = 0; |
862 | if (portp->tx.buf != NULL) { | 830 | if (portp->tx.buf != NULL) { |
863 | kfree(portp->tx.buf); | 831 | kfree(portp->tx.buf); |
@@ -865,9 +833,17 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
865 | portp->tx.head = NULL; | 833 | portp->tx.head = NULL; |
866 | portp->tx.tail = NULL; | 834 | portp->tx.tail = NULL; |
867 | } | 835 | } |
836 | } | ||
837 | |||
838 | static void stl_close(struct tty_struct *tty, struct file *filp) | ||
839 | { | ||
840 | struct stlport*portp; | ||
841 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | ||
868 | 842 | ||
869 | tty_port_close_end(port, tty); | 843 | portp = tty->driver_data; |
870 | tty_port_tty_set(port, NULL); | 844 | if(portp == NULL) |
845 | return; | ||
846 | tty_port_close(&portp->port, tty, filp); | ||
871 | } | 847 | } |
872 | 848 | ||
873 | /*****************************************************************************/ | 849 | /*****************************************************************************/ |
@@ -1314,35 +1290,12 @@ static void stl_stop(struct tty_struct *tty) | |||
1314 | 1290 | ||
1315 | static void stl_hangup(struct tty_struct *tty) | 1291 | static void stl_hangup(struct tty_struct *tty) |
1316 | { | 1292 | { |
1317 | struct stlport *portp; | 1293 | struct stlport *portp = tty->driver_data; |
1318 | struct tty_port *port; | ||
1319 | unsigned long flags; | ||
1320 | |||
1321 | pr_debug("stl_hangup(tty=%p)\n", tty); | 1294 | pr_debug("stl_hangup(tty=%p)\n", tty); |
1322 | 1295 | ||
1323 | portp = tty->driver_data; | ||
1324 | if (portp == NULL) | 1296 | if (portp == NULL) |
1325 | return; | 1297 | return; |
1326 | port = &portp->port; | 1298 | tty_port_hangup(&portp->port); |
1327 | |||
1328 | spin_lock_irqsave(&port->lock, flags); | ||
1329 | port->flags &= ~ASYNC_INITIALIZED; | ||
1330 | spin_unlock_irqrestore(&port->lock, flags); | ||
1331 | |||
1332 | stl_disableintrs(portp); | ||
1333 | if (tty->termios->c_cflag & HUPCL) | ||
1334 | stl_setsignals(portp, 0, 0); | ||
1335 | stl_enablerxtx(portp, 0, 0); | ||
1336 | stl_flushbuffer(tty); | ||
1337 | portp->istate = 0; | ||
1338 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
1339 | if (portp->tx.buf != NULL) { | ||
1340 | kfree(portp->tx.buf); | ||
1341 | portp->tx.buf = NULL; | ||
1342 | portp->tx.head = NULL; | ||
1343 | portp->tx.tail = NULL; | ||
1344 | } | ||
1345 | tty_port_hangup(port); | ||
1346 | } | 1299 | } |
1347 | 1300 | ||
1348 | /*****************************************************************************/ | 1301 | /*****************************************************************************/ |
@@ -2486,18 +2439,19 @@ static int stl_getbrdstruct(struct stlbrd __user *arg) | |||
2486 | * collection. | 2439 | * collection. |
2487 | */ | 2440 | */ |
2488 | 2441 | ||
2489 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) | 2442 | static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) |
2490 | { | 2443 | { |
2491 | int brdnr, rc; | 2444 | int brdnr, rc; |
2492 | void __user *argp = (void __user *)arg; | 2445 | void __user *argp = (void __user *)arg; |
2493 | 2446 | ||
2494 | pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg); | 2447 | pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg); |
2495 | 2448 | ||
2496 | brdnr = iminor(ip); | 2449 | brdnr = iminor(fp->f_dentry->d_inode); |
2497 | if (brdnr >= STL_MAXBRDS) | 2450 | if (brdnr >= STL_MAXBRDS) |
2498 | return -ENODEV; | 2451 | return -ENODEV; |
2499 | rc = 0; | 2452 | rc = 0; |
2500 | 2453 | ||
2454 | lock_kernel(); | ||
2501 | switch (cmd) { | 2455 | switch (cmd) { |
2502 | case COM_GETPORTSTATS: | 2456 | case COM_GETPORTSTATS: |
2503 | rc = stl_getportstats(NULL, NULL, argp); | 2457 | rc = stl_getportstats(NULL, NULL, argp); |
@@ -2518,7 +2472,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns | |||
2518 | rc = -ENOIOCTLCMD; | 2472 | rc = -ENOIOCTLCMD; |
2519 | break; | 2473 | break; |
2520 | } | 2474 | } |
2521 | 2475 | unlock_kernel(); | |
2522 | return rc; | 2476 | return rc; |
2523 | } | 2477 | } |
2524 | 2478 | ||
@@ -2549,6 +2503,8 @@ static const struct tty_operations stl_ops = { | |||
2549 | static const struct tty_port_operations stl_port_ops = { | 2503 | static const struct tty_port_operations stl_port_ops = { |
2550 | .carrier_raised = stl_carrier_raised, | 2504 | .carrier_raised = stl_carrier_raised, |
2551 | .dtr_rts = stl_dtr_rts, | 2505 | .dtr_rts = stl_dtr_rts, |
2506 | .activate = stl_activate, | ||
2507 | .shutdown = stl_shutdown, | ||
2552 | }; | 2508 | }; |
2553 | 2509 | ||
2554 | /*****************************************************************************/ | 2510 | /*****************************************************************************/ |