mct_u232.c (7af75af2424c3a866041e7981d91f01f93235533) | mct_u232.c (60b33c133ca0b7c0b6072c87234b63fee6e80558) |
---|---|
1/* 2 * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver 3 * 4 * Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 64 unchanged lines hidden (view full) --- 73#include <linux/tty_driver.h> 74#include <linux/tty_flip.h> 75#include <linux/module.h> 76#include <linux/spinlock.h> 77#include <linux/uaccess.h> 78#include <asm/unaligned.h> 79#include <linux/usb.h> 80#include <linux/usb/serial.h> | 1/* 2 * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver 3 * 4 * Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 64 unchanged lines hidden (view full) --- 73#include <linux/tty_driver.h> 74#include <linux/tty_flip.h> 75#include <linux/module.h> 76#include <linux/spinlock.h> 77#include <linux/uaccess.h> 78#include <asm/unaligned.h> 79#include <linux/usb.h> 80#include <linux/usb/serial.h> |
81#include <linux/serial.h> 82#include <linux/ioctl.h> | |
83#include "mct_u232.h" 84 85/* 86 * Version Information 87 */ 88#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */ 89#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>" 90#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" --- 7 unchanged lines hidden (view full) --- 98static void mct_u232_release(struct usb_serial *serial); 99static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); 100static void mct_u232_close(struct usb_serial_port *port); 101static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); 102static void mct_u232_read_int_callback(struct urb *urb); 103static void mct_u232_set_termios(struct tty_struct *tty, 104 struct usb_serial_port *port, struct ktermios *old); 105static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); | 81#include "mct_u232.h" 82 83/* 84 * Version Information 85 */ 86#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */ 87#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>" 88#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" --- 7 unchanged lines hidden (view full) --- 96static void mct_u232_release(struct usb_serial *serial); 97static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); 98static void mct_u232_close(struct usb_serial_port *port); 99static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); 100static void mct_u232_read_int_callback(struct urb *urb); 101static void mct_u232_set_termios(struct tty_struct *tty, 102 struct usb_serial_port *port, struct ktermios *old); 103static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); |
106static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file); | 104static int mct_u232_tiocmget(struct tty_struct *tty); |
107static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, 108 unsigned int set, unsigned int clear); | 105static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, 106 unsigned int set, unsigned int clear); |
109static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, 110 unsigned int cmd, unsigned long arg); 111static int mct_u232_get_icount(struct tty_struct *tty, 112 struct serial_icounter_struct *icount); | |
113static void mct_u232_throttle(struct tty_struct *tty); 114static void mct_u232_unthrottle(struct tty_struct *tty); 115 116 117/* 118 * All of the device info needed for the MCT USB-RS232 converter. 119 */ 120static const struct usb_device_id id_table_combined[] = { --- 30 unchanged lines hidden (view full) --- 151 .unthrottle = mct_u232_unthrottle, 152 .read_int_callback = mct_u232_read_int_callback, 153 .set_termios = mct_u232_set_termios, 154 .break_ctl = mct_u232_break_ctl, 155 .tiocmget = mct_u232_tiocmget, 156 .tiocmset = mct_u232_tiocmset, 157 .attach = mct_u232_startup, 158 .release = mct_u232_release, | 107static void mct_u232_throttle(struct tty_struct *tty); 108static void mct_u232_unthrottle(struct tty_struct *tty); 109 110 111/* 112 * All of the device info needed for the MCT USB-RS232 converter. 113 */ 114static const struct usb_device_id id_table_combined[] = { --- 30 unchanged lines hidden (view full) --- 145 .unthrottle = mct_u232_unthrottle, 146 .read_int_callback = mct_u232_read_int_callback, 147 .set_termios = mct_u232_set_termios, 148 .break_ctl = mct_u232_break_ctl, 149 .tiocmget = mct_u232_tiocmget, 150 .tiocmset = mct_u232_tiocmset, 151 .attach = mct_u232_startup, 152 .release = mct_u232_release, |
159 .ioctl = mct_u232_ioctl, 160 .get_icount = mct_u232_get_icount, | |
161}; 162 | 153}; 154 |
155 |
|
163struct mct_u232_private { 164 spinlock_t lock; 165 unsigned int control_state; /* Modem Line Setting (TIOCM) */ 166 unsigned char last_lcr; /* Line Control Register */ 167 unsigned char last_lsr; /* Line Status Register */ 168 unsigned char last_msr; /* Modem Status Register */ 169 unsigned int rx_flags; /* Throttling flags */ | 156struct mct_u232_private { 157 spinlock_t lock; 158 unsigned int control_state; /* Modem Line Setting (TIOCM) */ 159 unsigned char last_lcr; /* Line Control Register */ 160 unsigned char last_lsr; /* Line Status Register */ 161 unsigned char last_msr; /* Modem Status Register */ 162 unsigned int rx_flags; /* Throttling flags */ |
170 struct async_icount icount; 171 wait_queue_head_t msr_wait; /* for handling sleeping while waiting 172 for msr change to happen */ | |
173}; 174 175#define THROTTLED 0x01 176 177/* 178 * Handle vendor specific USB requests 179 */ 180 --- 210 unchanged lines hidden (view full) --- 391 } else { 392 *msr = buf[0]; 393 } 394 dbg("get_modem_stat: 0x%x", *msr); 395 kfree(buf); 396 return rc; 397} /* mct_u232_get_modem_stat */ 398 | 163}; 164 165#define THROTTLED 0x01 166 167/* 168 * Handle vendor specific USB requests 169 */ 170 --- 210 unchanged lines hidden (view full) --- 381 } else { 382 *msr = buf[0]; 383 } 384 dbg("get_modem_stat: 0x%x", *msr); 385 kfree(buf); 386 return rc; 387} /* mct_u232_get_modem_stat */ 388 |
399static void mct_u232_msr_to_icount(struct async_icount *icount, 400 unsigned char msr) 401{ 402 /* Translate Control Line states */ 403 if (msr & MCT_U232_MSR_DDSR) 404 icount->dsr++; 405 if (msr & MCT_U232_MSR_DCTS) 406 icount->cts++; 407 if (msr & MCT_U232_MSR_DRI) 408 icount->rng++; 409 if (msr & MCT_U232_MSR_DCD) 410 icount->dcd++; 411} /* mct_u232_msr_to_icount */ 412 | |
413static void mct_u232_msr_to_state(unsigned int *control_state, 414 unsigned char msr) 415{ 416 /* Translate Control Line states */ 417 if (msr & MCT_U232_MSR_DSR) 418 *control_state |= TIOCM_DSR; 419 else 420 *control_state &= ~TIOCM_DSR; --- 20 unchanged lines hidden (view full) --- 441{ 442 struct mct_u232_private *priv; 443 struct usb_serial_port *port, *rport; 444 445 priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); 446 if (!priv) 447 return -ENOMEM; 448 spin_lock_init(&priv->lock); | 389static void mct_u232_msr_to_state(unsigned int *control_state, 390 unsigned char msr) 391{ 392 /* Translate Control Line states */ 393 if (msr & MCT_U232_MSR_DSR) 394 *control_state |= TIOCM_DSR; 395 else 396 *control_state &= ~TIOCM_DSR; --- 20 unchanged lines hidden (view full) --- 417{ 418 struct mct_u232_private *priv; 419 struct usb_serial_port *port, *rport; 420 421 priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); 422 if (!priv) 423 return -ENOMEM; 424 spin_lock_init(&priv->lock); |
449 init_waitqueue_head(&priv->msr_wait); | |
450 usb_set_serial_port_data(serial->port[0], priv); 451 452 init_waitqueue_head(&serial->port[0]->write_wait); 453 454 /* Puh, that's dirty */ 455 port = serial->port[0]; 456 rport = serial->port[1]; 457 /* No unlinking, it wasn't submitted yet. */ --- 183 unchanged lines hidden (view full) --- 641 * signal changes and errors). data[0] holds MSR, data[1] holds LSR. 642 */ 643 spin_lock_irqsave(&priv->lock, flags); 644 priv->last_msr = data[MCT_U232_MSR_INDEX]; 645 646 /* Record Control Line states */ 647 mct_u232_msr_to_state(&priv->control_state, priv->last_msr); 648 | 425 usb_set_serial_port_data(serial->port[0], priv); 426 427 init_waitqueue_head(&serial->port[0]->write_wait); 428 429 /* Puh, that's dirty */ 430 port = serial->port[0]; 431 rport = serial->port[1]; 432 /* No unlinking, it wasn't submitted yet. */ --- 183 unchanged lines hidden (view full) --- 616 * signal changes and errors). data[0] holds MSR, data[1] holds LSR. 617 */ 618 spin_lock_irqsave(&priv->lock, flags); 619 priv->last_msr = data[MCT_U232_MSR_INDEX]; 620 621 /* Record Control Line states */ 622 mct_u232_msr_to_state(&priv->control_state, priv->last_msr); 623 |
649 mct_u232_msr_to_icount(&priv->icount, priv->last_msr); 650 | |
651#if 0 652 /* Not yet handled. See belkin_sa.c for further information */ 653 /* Now to report any errors */ 654 priv->last_lsr = data[MCT_U232_LSR_INDEX]; 655 /* 656 * fill in the flip buffer here, but I do not know the relation 657 * to the current/next receive buffer or characters. I need 658 * to look in to this before committing any code. --- 10 unchanged lines hidden (view full) --- 669 if (priv->last_lsr & MCT_U232_LSR_FE) { 670 } 671 /* Break Indicator */ 672 if (priv->last_lsr & MCT_U232_LSR_BI) { 673 } 674 tty_kref_put(tty); 675 } 676#endif | 624#if 0 625 /* Not yet handled. See belkin_sa.c for further information */ 626 /* Now to report any errors */ 627 priv->last_lsr = data[MCT_U232_LSR_INDEX]; 628 /* 629 * fill in the flip buffer here, but I do not know the relation 630 * to the current/next receive buffer or characters. I need 631 * to look in to this before committing any code. --- 10 unchanged lines hidden (view full) --- 642 if (priv->last_lsr & MCT_U232_LSR_FE) { 643 } 644 /* Break Indicator */ 645 if (priv->last_lsr & MCT_U232_LSR_BI) { 646 } 647 tty_kref_put(tty); 648 } 649#endif |
677 wake_up_interruptible(&priv->msr_wait); | |
678 spin_unlock_irqrestore(&priv->lock, flags); 679exit: 680 retval = usb_submit_urb(urb, GFP_ATOMIC); 681 if (retval) 682 dev_err(&port->dev, 683 "%s - usb_submit_urb failed with result %d\n", 684 __func__, retval); 685} /* mct_u232_read_int_callback */ --- 99 unchanged lines hidden (view full) --- 785 if (break_state) 786 lcr |= MCT_U232_SET_BREAK; 787 spin_unlock_irqrestore(&priv->lock, flags); 788 789 mct_u232_set_line_ctrl(serial, lcr); 790} /* mct_u232_break_ctl */ 791 792 | 650 spin_unlock_irqrestore(&priv->lock, flags); 651exit: 652 retval = usb_submit_urb(urb, GFP_ATOMIC); 653 if (retval) 654 dev_err(&port->dev, 655 "%s - usb_submit_urb failed with result %d\n", 656 __func__, retval); 657} /* mct_u232_read_int_callback */ --- 99 unchanged lines hidden (view full) --- 757 if (break_state) 758 lcr |= MCT_U232_SET_BREAK; 759 spin_unlock_irqrestore(&priv->lock, flags); 760 761 mct_u232_set_line_ctrl(serial, lcr); 762} /* mct_u232_break_ctl */ 763 764 |
793static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file) | 765static int mct_u232_tiocmget(struct tty_struct *tty) |
794{ 795 struct usb_serial_port *port = tty->driver_data; 796 struct mct_u232_private *priv = usb_get_serial_port_data(port); 797 unsigned int control_state; 798 unsigned long flags; 799 800 dbg("%s", __func__); 801 --- 47 unchanged lines hidden (view full) --- 849 control_state = priv->control_state; 850 spin_unlock_irq(&priv->lock); 851 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 852 } else { 853 spin_unlock_irq(&priv->lock); 854 } 855} 856 | 766{ 767 struct usb_serial_port *port = tty->driver_data; 768 struct mct_u232_private *priv = usb_get_serial_port_data(port); 769 unsigned int control_state; 770 unsigned long flags; 771 772 dbg("%s", __func__); 773 --- 47 unchanged lines hidden (view full) --- 821 control_state = priv->control_state; 822 spin_unlock_irq(&priv->lock); 823 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 824 } else { 825 spin_unlock_irq(&priv->lock); 826 } 827} 828 |
829 |
|
857static void mct_u232_unthrottle(struct tty_struct *tty) 858{ 859 struct usb_serial_port *port = tty->driver_data; 860 struct mct_u232_private *priv = usb_get_serial_port_data(port); 861 unsigned int control_state; 862 863 dbg("%s - port %d", __func__, port->number); 864 --- 4 unchanged lines hidden (view full) --- 869 control_state = priv->control_state; 870 spin_unlock_irq(&priv->lock); 871 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 872 } else { 873 spin_unlock_irq(&priv->lock); 874 } 875} 876 | 830static void mct_u232_unthrottle(struct tty_struct *tty) 831{ 832 struct usb_serial_port *port = tty->driver_data; 833 struct mct_u232_private *priv = usb_get_serial_port_data(port); 834 unsigned int control_state; 835 836 dbg("%s - port %d", __func__, port->number); 837 --- 4 unchanged lines hidden (view full) --- 842 control_state = priv->control_state; 843 spin_unlock_irq(&priv->lock); 844 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 845 } else { 846 spin_unlock_irq(&priv->lock); 847 } 848} 849 |
877static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, 878 unsigned int cmd, unsigned long arg) 879{ 880 DEFINE_WAIT(wait); 881 struct usb_serial_port *port = tty->driver_data; 882 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); 883 struct async_icount cnow, cprev; 884 unsigned long flags; 885 886 dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); 887 888 switch (cmd) { 889 890 case TIOCMIWAIT: 891 892 dbg("%s (%d) TIOCMIWAIT", __func__, port->number); 893 894 spin_lock_irqsave(&mct_u232_port->lock, flags); 895 cprev = mct_u232_port->icount; 896 spin_unlock_irqrestore(&mct_u232_port->lock, flags); 897 for ( ; ; ) { 898 prepare_to_wait(&mct_u232_port->msr_wait, 899 &wait, TASK_INTERRUPTIBLE); 900 schedule(); 901 finish_wait(&mct_u232_port->msr_wait, &wait); 902 /* see if a signal did it */ 903 if (signal_pending(current)) 904 return -ERESTARTSYS; 905 spin_lock_irqsave(&mct_u232_port->lock, flags); 906 cnow = mct_u232_port->icount; 907 spin_unlock_irqrestore(&mct_u232_port->lock, flags); 908 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 909 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) 910 return -EIO; /* no change => error */ 911 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 912 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 913 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || 914 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { 915 return 0; 916 } 917 cprev = cnow; 918 } 919 920 } 921 return -ENOIOCTLCMD; 922} 923 924static int mct_u232_get_icount(struct tty_struct *tty, 925 struct serial_icounter_struct *icount) 926{ 927 struct usb_serial_port *port = tty->driver_data; 928 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); 929 struct async_icount *ic = &mct_u232_port->icount; 930 unsigned long flags; 931 932 spin_lock_irqsave(&mct_u232_port->lock, flags); 933 934 icount->cts = ic->cts; 935 icount->dsr = ic->dsr; 936 icount->rng = ic->rng; 937 icount->dcd = ic->dcd; 938 icount->rx = ic->rx; 939 icount->tx = ic->tx; 940 icount->frame = ic->frame; 941 icount->overrun = ic->overrun; 942 icount->parity = ic->parity; 943 icount->brk = ic->brk; 944 icount->buf_overrun = ic->buf_overrun; 945 946 spin_unlock_irqrestore(&mct_u232_port->lock, flags); 947 948 dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", 949 __func__, port->number, icount->rx, icount->tx); 950 return 0; 951} 952 | |
953static int __init mct_u232_init(void) 954{ 955 int retval; 956 retval = usb_serial_register(&mct_u232_device); 957 if (retval) 958 goto failed_usb_serial_register; 959 retval = usb_register(&mct_u232_driver); 960 if (retval) --- 26 unchanged lines hidden --- | 850static int __init mct_u232_init(void) 851{ 852 int retval; 853 retval = usb_serial_register(&mct_u232_device); 854 if (retval) 855 goto failed_usb_serial_register; 856 retval = usb_register(&mct_u232_driver); 857 if (retval) --- 26 unchanged lines hidden --- |