diff options
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 256 |
1 files changed, 141 insertions, 115 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ebcc6d0e2e91..1d7c4fac02e8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -33,23 +33,24 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/smp_lock.h> | ||
37 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
38 | #include <linux/tty_driver.h> | 37 | #include <linux/tty_driver.h> |
39 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
40 | #include <linux/module.h> | 39 | #include <linux/module.h> |
41 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/mutex.h> | ||
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
43 | #include <linux/usb.h> | 43 | #include <linux/usb.h> |
44 | #include <linux/serial.h> | 44 | #include <linux/serial.h> |
45 | #include <linux/usb/serial.h> | 45 | #include <linux/usb/serial.h> |
46 | #include "ftdi_sio.h" | 46 | #include "ftdi_sio.h" |
47 | #include "ftdi_sio_ids.h" | ||
47 | 48 | ||
48 | /* | 49 | /* |
49 | * Version Information | 50 | * Version Information |
50 | */ | 51 | */ |
51 | #define DRIVER_VERSION "v1.5.0" | 52 | #define DRIVER_VERSION "v1.5.0" |
52 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" | 53 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr" |
53 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" | 54 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" |
54 | 55 | ||
55 | static int debug; | 56 | static int debug; |
@@ -87,10 +88,10 @@ struct ftdi_private { | |||
87 | 88 | ||
88 | unsigned int latency; /* latency setting in use */ | 89 | unsigned int latency; /* latency setting in use */ |
89 | spinlock_t tx_lock; /* spinlock for transmit state */ | 90 | spinlock_t tx_lock; /* spinlock for transmit state */ |
90 | unsigned long tx_bytes; | ||
91 | unsigned long tx_outstanding_bytes; | 91 | unsigned long tx_outstanding_bytes; |
92 | unsigned long tx_outstanding_urbs; | 92 | unsigned long tx_outstanding_urbs; |
93 | unsigned short max_packet_size; | 93 | unsigned short max_packet_size; |
94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ | ||
94 | }; | 95 | }; |
95 | 96 | ||
96 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -144,10 +145,15 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { | |||
144 | 145 | ||
145 | 146 | ||
146 | 147 | ||
148 | /* | ||
149 | * Device ID not listed? Test via module params product/vendor or | ||
150 | * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! | ||
151 | */ | ||
147 | static struct usb_device_id id_table_combined [] = { | 152 | static struct usb_device_id id_table_combined [] = { |
148 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | 153 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, |
149 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 154 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
150 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, | 155 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, |
156 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, | ||
151 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, | 157 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, |
152 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, | 158 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, |
153 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, | 159 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, |
@@ -551,9 +557,16 @@ static struct usb_device_id id_table_combined [] = { | |||
551 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, | 557 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, |
552 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, | 558 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, |
553 | /* | 559 | /* |
554 | * Due to many user requests for multiple ELV devices we enable | 560 | * ELV devices: |
555 | * them by default. | ||
556 | */ | 561 | */ |
562 | { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, | ||
563 | { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, | ||
564 | { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, | ||
565 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS550_PID) }, | ||
566 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EC3000_PID) }, | ||
567 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS888_PID) }, | ||
568 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TWS550_PID) }, | ||
569 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FEM_PID) }, | ||
557 | { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, | 570 | { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, |
558 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, | 571 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, |
559 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, | 572 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, |
@@ -570,11 +583,17 @@ static struct usb_device_id id_table_combined [] = { | |||
570 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, | 583 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, |
571 | { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, | 584 | { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, |
572 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, | 585 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, |
586 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UTP8_PID) }, | ||
573 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, | 587 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, |
588 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS444PC_PID) }, | ||
574 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, | 589 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, |
575 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, | 590 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, |
576 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, | 591 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, |
577 | { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) }, | 592 | { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) }, |
593 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UMS100_PID) }, | ||
594 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) }, | ||
595 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) }, | ||
596 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) }, | ||
578 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, | 597 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, |
579 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, | 598 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, |
580 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, | 599 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, |
@@ -595,9 +614,24 @@ static struct usb_device_id id_table_combined [] = { | |||
595 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, | 614 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, |
596 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, | 615 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, |
597 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, | 616 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, |
617 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | ||
598 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, | 618 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, |
599 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 619 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
600 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, | 620 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, |
621 | { USB_DEVICE(BANDB_VID, BANDB_USOPTL4_PID) }, | ||
622 | { USB_DEVICE(BANDB_VID, BANDB_USPTL4_PID) }, | ||
623 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_2_PID) }, | ||
624 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_PID) }, | ||
625 | { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR2_PID) }, | ||
626 | { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR_PID) }, | ||
627 | { USB_DEVICE(BANDB_VID, BANDB_485USB9F_2W_PID) }, | ||
628 | { USB_DEVICE(BANDB_VID, BANDB_485USB9F_4W_PID) }, | ||
629 | { USB_DEVICE(BANDB_VID, BANDB_232USB9M_PID) }, | ||
630 | { USB_DEVICE(BANDB_VID, BANDB_485USBTB_2W_PID) }, | ||
631 | { USB_DEVICE(BANDB_VID, BANDB_485USBTB_4W_PID) }, | ||
632 | { USB_DEVICE(BANDB_VID, BANDB_TTL5USB9M_PID) }, | ||
633 | { USB_DEVICE(BANDB_VID, BANDB_TTL3USB9M_PID) }, | ||
634 | { USB_DEVICE(BANDB_VID, BANDB_ZZ_PROG1_USB_PID) }, | ||
601 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, | 635 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, |
602 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, | 636 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, |
603 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, | 637 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, |
@@ -624,6 +658,7 @@ static struct usb_device_id id_table_combined [] = { | |||
624 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 658 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
625 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, | 659 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, |
626 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, | 660 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, |
661 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | ||
627 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 662 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
628 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 663 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
629 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, | 664 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, |
@@ -682,6 +717,7 @@ static struct usb_device_id id_table_combined [] = { | |||
682 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | 717 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, |
683 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, | 718 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, |
684 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, | 719 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, |
720 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) }, | ||
685 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, | 721 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, |
686 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, | 722 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, |
687 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, | 723 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, |
@@ -703,6 +739,10 @@ static struct usb_device_id id_table_combined [] = { | |||
703 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 739 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
704 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, | 740 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, |
705 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, | 741 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, |
742 | { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, | ||
743 | { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, | ||
744 | { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, | ||
745 | { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, | ||
706 | { }, /* Optional parameter entry */ | 746 | { }, /* Optional parameter entry */ |
707 | { } /* Terminating entry */ | 747 | { } /* Terminating entry */ |
708 | }; | 748 | }; |
@@ -778,7 +818,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
778 | .name = "ftdi_sio", | 818 | .name = "ftdi_sio", |
779 | }, | 819 | }, |
780 | .description = "FTDI USB Serial Device", | 820 | .description = "FTDI USB Serial Device", |
781 | .usb_driver = &ftdi_driver , | 821 | .usb_driver = &ftdi_driver, |
782 | .id_table = id_table_combined, | 822 | .id_table = id_table_combined, |
783 | .num_ports = 1, | 823 | .num_ports = 1, |
784 | .probe = ftdi_sio_probe, | 824 | .probe = ftdi_sio_probe, |
@@ -794,8 +834,8 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
794 | .chars_in_buffer = ftdi_chars_in_buffer, | 834 | .chars_in_buffer = ftdi_chars_in_buffer, |
795 | .read_bulk_callback = ftdi_read_bulk_callback, | 835 | .read_bulk_callback = ftdi_read_bulk_callback, |
796 | .write_bulk_callback = ftdi_write_bulk_callback, | 836 | .write_bulk_callback = ftdi_write_bulk_callback, |
797 | .tiocmget = ftdi_tiocmget, | 837 | .tiocmget = ftdi_tiocmget, |
798 | .tiocmset = ftdi_tiocmset, | 838 | .tiocmset = ftdi_tiocmset, |
799 | .ioctl = ftdi_ioctl, | 839 | .ioctl = ftdi_ioctl, |
800 | .set_termios = ftdi_set_termios, | 840 | .set_termios = ftdi_set_termios, |
801 | .break_ctl = ftdi_break_ctl, | 841 | .break_ctl = ftdi_break_ctl, |
@@ -901,7 +941,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
901 | unsigned int clear) | 941 | unsigned int clear) |
902 | { | 942 | { |
903 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 943 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
904 | char *buf; | ||
905 | unsigned urb_value; | 944 | unsigned urb_value; |
906 | int rv; | 945 | int rv; |
907 | 946 | ||
@@ -910,10 +949,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
910 | return 0; /* no change */ | 949 | return 0; /* no change */ |
911 | } | 950 | } |
912 | 951 | ||
913 | buf = kmalloc(1, GFP_NOIO); | ||
914 | if (!buf) | ||
915 | return -ENOMEM; | ||
916 | |||
917 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | 952 | clear &= ~set; /* 'set' takes precedence over 'clear' */ |
918 | urb_value = 0; | 953 | urb_value = 0; |
919 | if (clear & TIOCM_DTR) | 954 | if (clear & TIOCM_DTR) |
@@ -929,9 +964,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
929 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, | 964 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, |
930 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | 965 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, |
931 | urb_value, priv->interface, | 966 | urb_value, priv->interface, |
932 | buf, 0, WDR_TIMEOUT); | 967 | NULL, 0, WDR_TIMEOUT); |
933 | |||
934 | kfree(buf); | ||
935 | if (rv < 0) { | 968 | if (rv < 0) { |
936 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", | 969 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", |
937 | __func__, | 970 | __func__, |
@@ -1090,16 +1123,11 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
1090 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | 1123 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) |
1091 | { | 1124 | { |
1092 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1125 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1093 | char *buf; | ||
1094 | __u16 urb_value; | 1126 | __u16 urb_value; |
1095 | __u16 urb_index; | 1127 | __u16 urb_index; |
1096 | __u32 urb_index_value; | 1128 | __u32 urb_index_value; |
1097 | int rv; | 1129 | int rv; |
1098 | 1130 | ||
1099 | buf = kmalloc(1, GFP_NOIO); | ||
1100 | if (!buf) | ||
1101 | return -ENOMEM; | ||
1102 | |||
1103 | urb_index_value = get_ftdi_divisor(tty, port); | 1131 | urb_index_value = get_ftdi_divisor(tty, port); |
1104 | urb_value = (__u16)urb_index_value; | 1132 | urb_value = (__u16)urb_index_value; |
1105 | urb_index = (__u16)(urb_index_value >> 16); | 1133 | urb_index = (__u16)(urb_index_value >> 16); |
@@ -1112,9 +1140,7 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | |||
1112 | FTDI_SIO_SET_BAUDRATE_REQUEST, | 1140 | FTDI_SIO_SET_BAUDRATE_REQUEST, |
1113 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, | 1141 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, |
1114 | urb_value, urb_index, | 1142 | urb_value, urb_index, |
1115 | buf, 0, WDR_SHORT_TIMEOUT); | 1143 | NULL, 0, WDR_SHORT_TIMEOUT); |
1116 | |||
1117 | kfree(buf); | ||
1118 | return rv; | 1144 | return rv; |
1119 | } | 1145 | } |
1120 | 1146 | ||
@@ -1122,8 +1148,7 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1122 | { | 1148 | { |
1123 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1149 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1124 | struct usb_device *udev = port->serial->dev; | 1150 | struct usb_device *udev = port->serial->dev; |
1125 | char buf[1]; | 1151 | int rv; |
1126 | int rv = 0; | ||
1127 | int l = priv->latency; | 1152 | int l = priv->latency; |
1128 | 1153 | ||
1129 | if (priv->flags & ASYNC_LOW_LATENCY) | 1154 | if (priv->flags & ASYNC_LOW_LATENCY) |
@@ -1136,8 +1161,7 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1136 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1161 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1137 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1162 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1138 | l, priv->interface, | 1163 | l, priv->interface, |
1139 | buf, 0, WDR_TIMEOUT); | 1164 | NULL, 0, WDR_TIMEOUT); |
1140 | |||
1141 | if (rv < 0) | 1165 | if (rv < 0) |
1142 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); | 1166 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); |
1143 | return rv; | 1167 | return rv; |
@@ -1147,24 +1171,29 @@ static int read_latency_timer(struct usb_serial_port *port) | |||
1147 | { | 1171 | { |
1148 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1172 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1149 | struct usb_device *udev = port->serial->dev; | 1173 | struct usb_device *udev = port->serial->dev; |
1150 | unsigned short latency = 0; | 1174 | unsigned char *buf; |
1151 | int rv = 0; | 1175 | int rv; |
1152 | |||
1153 | 1176 | ||
1154 | dbg("%s", __func__); | 1177 | dbg("%s", __func__); |
1155 | 1178 | ||
1179 | buf = kmalloc(1, GFP_KERNEL); | ||
1180 | if (!buf) | ||
1181 | return -ENOMEM; | ||
1182 | |||
1156 | rv = usb_control_msg(udev, | 1183 | rv = usb_control_msg(udev, |
1157 | usb_rcvctrlpipe(udev, 0), | 1184 | usb_rcvctrlpipe(udev, 0), |
1158 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | 1185 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, |
1159 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | 1186 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, |
1160 | 0, priv->interface, | 1187 | 0, priv->interface, |
1161 | (char *) &latency, 1, WDR_TIMEOUT); | 1188 | buf, 1, WDR_TIMEOUT); |
1162 | 1189 | if (rv < 0) | |
1163 | if (rv < 0) { | ||
1164 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); | 1190 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); |
1165 | return -EIO; | 1191 | else |
1166 | } | 1192 | priv->latency = buf[0]; |
1167 | return latency; | 1193 | |
1194 | kfree(buf); | ||
1195 | |||
1196 | return rv; | ||
1168 | } | 1197 | } |
1169 | 1198 | ||
1170 | static int get_serial_info(struct usb_serial_port *port, | 1199 | static int get_serial_info(struct usb_serial_port *port, |
@@ -1195,7 +1224,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1195 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | 1224 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) |
1196 | return -EFAULT; | 1225 | return -EFAULT; |
1197 | 1226 | ||
1198 | lock_kernel(); | 1227 | mutex_lock(&priv->cfg_lock); |
1199 | old_priv = *priv; | 1228 | old_priv = *priv; |
1200 | 1229 | ||
1201 | /* Do error checking and permission checking */ | 1230 | /* Do error checking and permission checking */ |
@@ -1203,7 +1232,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1203 | if (!capable(CAP_SYS_ADMIN)) { | 1232 | if (!capable(CAP_SYS_ADMIN)) { |
1204 | if (((new_serial.flags & ~ASYNC_USR_MASK) != | 1233 | if (((new_serial.flags & ~ASYNC_USR_MASK) != |
1205 | (priv->flags & ~ASYNC_USR_MASK))) { | 1234 | (priv->flags & ~ASYNC_USR_MASK))) { |
1206 | unlock_kernel(); | 1235 | mutex_unlock(&priv->cfg_lock); |
1207 | return -EPERM; | 1236 | return -EPERM; |
1208 | } | 1237 | } |
1209 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | | 1238 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | |
@@ -1214,7 +1243,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1214 | 1243 | ||
1215 | if ((new_serial.baud_base != priv->baud_base) && | 1244 | if ((new_serial.baud_base != priv->baud_base) && |
1216 | (new_serial.baud_base < 9600)) { | 1245 | (new_serial.baud_base < 9600)) { |
1217 | unlock_kernel(); | 1246 | mutex_unlock(&priv->cfg_lock); |
1218 | return -EINVAL; | 1247 | return -EINVAL; |
1219 | } | 1248 | } |
1220 | 1249 | ||
@@ -1244,11 +1273,11 @@ check_and_exit: | |||
1244 | (priv->flags & ASYNC_SPD_MASK)) || | 1273 | (priv->flags & ASYNC_SPD_MASK)) || |
1245 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && | 1274 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && |
1246 | (old_priv.custom_divisor != priv->custom_divisor))) { | 1275 | (old_priv.custom_divisor != priv->custom_divisor))) { |
1247 | unlock_kernel(); | ||
1248 | change_speed(tty, port); | 1276 | change_speed(tty, port); |
1277 | mutex_unlock(&priv->cfg_lock); | ||
1249 | } | 1278 | } |
1250 | else | 1279 | else |
1251 | unlock_kernel(); | 1280 | mutex_unlock(&priv->cfg_lock); |
1252 | return 0; | 1281 | return 0; |
1253 | 1282 | ||
1254 | } /* set_serial_info */ | 1283 | } /* set_serial_info */ |
@@ -1304,20 +1333,20 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1304 | __func__); | 1333 | __func__); |
1305 | } | 1334 | } |
1306 | } else if (version < 0x200) { | 1335 | } else if (version < 0x200) { |
1307 | /* Old device. Assume its the original SIO. */ | 1336 | /* Old device. Assume it's the original SIO. */ |
1308 | priv->chip_type = SIO; | 1337 | priv->chip_type = SIO; |
1309 | priv->baud_base = 12000000 / 16; | 1338 | priv->baud_base = 12000000 / 16; |
1310 | priv->write_offset = 1; | 1339 | priv->write_offset = 1; |
1311 | } else if (version < 0x400) { | 1340 | } else if (version < 0x400) { |
1312 | /* Assume its an FT8U232AM (or FT8U245AM) */ | 1341 | /* Assume it's an FT8U232AM (or FT8U245AM) */ |
1313 | /* (It might be a BM because of the iSerialNumber bug, | 1342 | /* (It might be a BM because of the iSerialNumber bug, |
1314 | * but it will still work as an AM device.) */ | 1343 | * but it will still work as an AM device.) */ |
1315 | priv->chip_type = FT8U232AM; | 1344 | priv->chip_type = FT8U232AM; |
1316 | } else if (version < 0x600) { | 1345 | } else if (version < 0x600) { |
1317 | /* Assume its an FT232BM (or FT245BM) */ | 1346 | /* Assume it's an FT232BM (or FT245BM) */ |
1318 | priv->chip_type = FT232BM; | 1347 | priv->chip_type = FT232BM; |
1319 | } else { | 1348 | } else { |
1320 | /* Assume its an FT232R */ | 1349 | /* Assume it's an FT232R */ |
1321 | priv->chip_type = FT232RL; | 1350 | priv->chip_type = FT232RL; |
1322 | } | 1351 | } |
1323 | dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); | 1352 | dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); |
@@ -1337,7 +1366,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) | |||
1337 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; | 1366 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; |
1338 | 1367 | ||
1339 | unsigned num_endpoints; | 1368 | unsigned num_endpoints; |
1340 | int i = 0; | 1369 | int i; |
1341 | 1370 | ||
1342 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | 1371 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; |
1343 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | 1372 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); |
@@ -1389,7 +1418,7 @@ static ssize_t store_latency_timer(struct device *dev, | |||
1389 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1418 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1390 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1419 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1391 | int v = simple_strtoul(valbuf, NULL, 10); | 1420 | int v = simple_strtoul(valbuf, NULL, 10); |
1392 | int rv = 0; | 1421 | int rv; |
1393 | 1422 | ||
1394 | priv->latency = v; | 1423 | priv->latency = v; |
1395 | rv = write_latency_timer(port); | 1424 | rv = write_latency_timer(port); |
@@ -1406,9 +1435,8 @@ static ssize_t store_event_char(struct device *dev, | |||
1406 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1435 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1407 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1436 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1408 | struct usb_device *udev = port->serial->dev; | 1437 | struct usb_device *udev = port->serial->dev; |
1409 | char buf[1]; | ||
1410 | int v = simple_strtoul(valbuf, NULL, 10); | 1438 | int v = simple_strtoul(valbuf, NULL, 10); |
1411 | int rv = 0; | 1439 | int rv; |
1412 | 1440 | ||
1413 | dbg("%s: setting event char = %i", __func__, v); | 1441 | dbg("%s: setting event char = %i", __func__, v); |
1414 | 1442 | ||
@@ -1417,8 +1445,7 @@ static ssize_t store_event_char(struct device *dev, | |||
1417 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, | 1445 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, |
1418 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, | 1446 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, |
1419 | v, priv->interface, | 1447 | v, priv->interface, |
1420 | buf, 0, WDR_TIMEOUT); | 1448 | NULL, 0, WDR_TIMEOUT); |
1421 | |||
1422 | if (rv < 0) { | 1449 | if (rv < 0) { |
1423 | dbg("Unable to write event character: %i", rv); | 1450 | dbg("Unable to write event character: %i", rv); |
1424 | return -EIO; | 1451 | return -EIO; |
@@ -1517,9 +1544,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1517 | 1544 | ||
1518 | kref_init(&priv->kref); | 1545 | kref_init(&priv->kref); |
1519 | spin_lock_init(&priv->tx_lock); | 1546 | spin_lock_init(&priv->tx_lock); |
1547 | mutex_init(&priv->cfg_lock); | ||
1520 | init_waitqueue_head(&priv->delta_msr_wait); | 1548 | init_waitqueue_head(&priv->delta_msr_wait); |
1521 | /* This will push the characters through immediately rather | 1549 | |
1522 | than queue a task to deliver them */ | ||
1523 | priv->flags = ASYNC_LOW_LATENCY; | 1550 | priv->flags = ASYNC_LOW_LATENCY; |
1524 | 1551 | ||
1525 | if (quirk && quirk->port_probe) | 1552 | if (quirk && quirk->port_probe) |
@@ -1551,7 +1578,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1551 | 1578 | ||
1552 | ftdi_determine_type(port); | 1579 | ftdi_determine_type(port); |
1553 | ftdi_set_max_packet_size(port); | 1580 | ftdi_set_max_packet_size(port); |
1554 | read_latency_timer(port); | 1581 | if (read_latency_timer(port) < 0) |
1582 | priv->latency = 16; | ||
1555 | create_sysfs_attrs(port); | 1583 | create_sysfs_attrs(port); |
1556 | return 0; | 1584 | return 0; |
1557 | } | 1585 | } |
@@ -1596,8 +1624,6 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1596 | { | 1624 | { |
1597 | struct usb_device *udev = serial->dev; | 1625 | struct usb_device *udev = serial->dev; |
1598 | int latency = ndi_latency_timer; | 1626 | int latency = ndi_latency_timer; |
1599 | int rv = 0; | ||
1600 | char buf[1]; | ||
1601 | 1627 | ||
1602 | if (latency == 0) | 1628 | if (latency == 0) |
1603 | latency = 1; | 1629 | latency = 1; |
@@ -1607,10 +1633,11 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1607 | dbg("%s setting NDI device latency to %d", __func__, latency); | 1633 | dbg("%s setting NDI device latency to %d", __func__, latency); |
1608 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); | 1634 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); |
1609 | 1635 | ||
1610 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 1636 | /* FIXME: errors are not returned */ |
1637 | usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
1611 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1638 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1612 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1639 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1613 | latency, 0, buf, 0, WDR_TIMEOUT); | 1640 | latency, 0, NULL, 0, WDR_TIMEOUT); |
1614 | return 0; | 1641 | return 0; |
1615 | } | 1642 | } |
1616 | 1643 | ||
@@ -1686,7 +1713,7 @@ static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | |||
1686 | urb->transfer_buffer_length, | 1713 | urb->transfer_buffer_length, |
1687 | ftdi_read_bulk_callback, port); | 1714 | ftdi_read_bulk_callback, port); |
1688 | result = usb_submit_urb(urb, mem_flags); | 1715 | result = usb_submit_urb(urb, mem_flags); |
1689 | if (result) | 1716 | if (result && result != -EPERM) |
1690 | dev_err(&port->dev, | 1717 | dev_err(&port->dev, |
1691 | "%s - failed submitting read urb, error %d\n", | 1718 | "%s - failed submitting read urb, error %d\n", |
1692 | __func__, result); | 1719 | __func__, result); |
@@ -1698,16 +1725,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1698 | struct usb_device *dev = port->serial->dev; | 1725 | struct usb_device *dev = port->serial->dev; |
1699 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1726 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1700 | unsigned long flags; | 1727 | unsigned long flags; |
1701 | 1728 | int result; | |
1702 | int result = 0; | ||
1703 | char buf[1]; /* Needed for the usb_control_msg I think */ | ||
1704 | 1729 | ||
1705 | dbg("%s", __func__); | 1730 | dbg("%s", __func__); |
1706 | 1731 | ||
1707 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1708 | priv->tx_bytes = 0; | ||
1709 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1710 | |||
1711 | write_latency_timer(port); | 1732 | write_latency_timer(port); |
1712 | 1733 | ||
1713 | /* No error checking for this (will get errors later anyway) */ | 1734 | /* No error checking for this (will get errors later anyway) */ |
@@ -1715,7 +1736,7 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1715 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1736 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1716 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, | 1737 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, |
1717 | FTDI_SIO_RESET_SIO, | 1738 | FTDI_SIO_RESET_SIO, |
1718 | priv->interface, buf, 0, WDR_TIMEOUT); | 1739 | priv->interface, NULL, 0, WDR_TIMEOUT); |
1719 | 1740 | ||
1720 | /* Termios defaults are set by usb_serial_init. We don't change | 1741 | /* Termios defaults are set by usb_serial_init. We don't change |
1721 | port->tty->termios - this would lose speed settings, etc. | 1742 | port->tty->termios - this would lose speed settings, etc. |
@@ -1743,7 +1764,6 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1743 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | 1764 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) |
1744 | { | 1765 | { |
1745 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1766 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1746 | char buf[1]; | ||
1747 | 1767 | ||
1748 | mutex_lock(&port->serial->disc_mutex); | 1768 | mutex_lock(&port->serial->disc_mutex); |
1749 | if (!port->serial->disconnected) { | 1769 | if (!port->serial->disconnected) { |
@@ -1752,7 +1772,7 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | |||
1752 | usb_sndctrlpipe(port->serial->dev, 0), | 1772 | usb_sndctrlpipe(port->serial->dev, 0), |
1753 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1773 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1754 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1774 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1755 | 0, priv->interface, buf, 0, | 1775 | 0, priv->interface, NULL, 0, |
1756 | WDR_TIMEOUT) < 0) { | 1776 | WDR_TIMEOUT) < 0) { |
1757 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 1777 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
1758 | } | 1778 | } |
@@ -1813,7 +1833,7 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1813 | spin_lock_irqsave(&priv->tx_lock, flags); | 1833 | spin_lock_irqsave(&priv->tx_lock, flags); |
1814 | if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { | 1834 | if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { |
1815 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1835 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1816 | dbg("%s - write limit hit\n", __func__); | 1836 | dbg("%s - write limit hit", __func__); |
1817 | return 0; | 1837 | return 0; |
1818 | } | 1838 | } |
1819 | priv->tx_outstanding_urbs++; | 1839 | priv->tx_outstanding_urbs++; |
@@ -1893,7 +1913,6 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1893 | } else { | 1913 | } else { |
1894 | spin_lock_irqsave(&priv->tx_lock, flags); | 1914 | spin_lock_irqsave(&priv->tx_lock, flags); |
1895 | priv->tx_outstanding_bytes += count; | 1915 | priv->tx_outstanding_bytes += count; |
1896 | priv->tx_bytes += count; | ||
1897 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1916 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1898 | } | 1917 | } |
1899 | 1918 | ||
@@ -2120,8 +2139,7 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2120 | { | 2139 | { |
2121 | struct usb_serial_port *port = tty->driver_data; | 2140 | struct usb_serial_port *port = tty->driver_data; |
2122 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2141 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2123 | __u16 urb_value = 0; | 2142 | __u16 urb_value; |
2124 | char buf[1]; | ||
2125 | 2143 | ||
2126 | /* break_state = -1 to turn on break, and 0 to turn off break */ | 2144 | /* break_state = -1 to turn on break, and 0 to turn off break */ |
2127 | /* see drivers/char/tty_io.c to see it used */ | 2145 | /* see drivers/char/tty_io.c to see it used */ |
@@ -2137,7 +2155,7 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2137 | FTDI_SIO_SET_DATA_REQUEST, | 2155 | FTDI_SIO_SET_DATA_REQUEST, |
2138 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2156 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2139 | urb_value , priv->interface, | 2157 | urb_value , priv->interface, |
2140 | buf, 0, WDR_TIMEOUT) < 0) { | 2158 | NULL, 0, WDR_TIMEOUT) < 0) { |
2141 | dev_err(&port->dev, "%s FAILED to enable/disable break state " | 2159 | dev_err(&port->dev, "%s FAILED to enable/disable break state " |
2142 | "(state was %d)\n", __func__, break_state); | 2160 | "(state was %d)\n", __func__, break_state); |
2143 | } | 2161 | } |
@@ -2161,7 +2179,6 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2161 | struct ktermios *termios = tty->termios; | 2179 | struct ktermios *termios = tty->termios; |
2162 | unsigned int cflag = termios->c_cflag; | 2180 | unsigned int cflag = termios->c_cflag; |
2163 | __u16 urb_value; /* will hold the new flags */ | 2181 | __u16 urb_value; /* will hold the new flags */ |
2164 | char buf[1]; /* Perhaps I should dynamically alloc this? */ | ||
2165 | 2182 | ||
2166 | /* Added for xon/xoff support */ | 2183 | /* Added for xon/xoff support */ |
2167 | unsigned int iflag = termios->c_iflag; | 2184 | unsigned int iflag = termios->c_iflag; |
@@ -2195,23 +2212,27 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2195 | 2212 | ||
2196 | /* Set number of data bits, parity, stop bits */ | 2213 | /* Set number of data bits, parity, stop bits */ |
2197 | 2214 | ||
2198 | termios->c_cflag &= ~CMSPAR; | ||
2199 | |||
2200 | urb_value = 0; | 2215 | urb_value = 0; |
2201 | urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : | 2216 | urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : |
2202 | FTDI_SIO_SET_DATA_STOP_BITS_1); | 2217 | FTDI_SIO_SET_DATA_STOP_BITS_1); |
2203 | urb_value |= (cflag & PARENB ? | 2218 | if (cflag & PARENB) { |
2204 | (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : | 2219 | if (cflag & CMSPAR) |
2205 | FTDI_SIO_SET_DATA_PARITY_EVEN) : | 2220 | urb_value |= cflag & PARODD ? |
2206 | FTDI_SIO_SET_DATA_PARITY_NONE); | 2221 | FTDI_SIO_SET_DATA_PARITY_MARK : |
2222 | FTDI_SIO_SET_DATA_PARITY_SPACE; | ||
2223 | else | ||
2224 | urb_value |= cflag & PARODD ? | ||
2225 | FTDI_SIO_SET_DATA_PARITY_ODD : | ||
2226 | FTDI_SIO_SET_DATA_PARITY_EVEN; | ||
2227 | } else { | ||
2228 | urb_value |= FTDI_SIO_SET_DATA_PARITY_NONE; | ||
2229 | } | ||
2207 | if (cflag & CSIZE) { | 2230 | if (cflag & CSIZE) { |
2208 | switch (cflag & CSIZE) { | 2231 | switch (cflag & CSIZE) { |
2209 | case CS5: urb_value |= 5; dbg("Setting CS5"); break; | ||
2210 | case CS6: urb_value |= 6; dbg("Setting CS6"); break; | ||
2211 | case CS7: urb_value |= 7; dbg("Setting CS7"); break; | 2232 | case CS7: urb_value |= 7; dbg("Setting CS7"); break; |
2212 | case CS8: urb_value |= 8; dbg("Setting CS8"); break; | 2233 | case CS8: urb_value |= 8; dbg("Setting CS8"); break; |
2213 | default: | 2234 | default: |
2214 | dev_err(&port->dev, "CSIZE was set but not CS5-CS8\n"); | 2235 | dev_err(&port->dev, "CSIZE was set but not CS7-CS8\n"); |
2215 | } | 2236 | } |
2216 | } | 2237 | } |
2217 | 2238 | ||
@@ -2223,7 +2244,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2223 | FTDI_SIO_SET_DATA_REQUEST, | 2244 | FTDI_SIO_SET_DATA_REQUEST, |
2224 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2245 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2225 | urb_value , priv->interface, | 2246 | urb_value , priv->interface, |
2226 | buf, 0, WDR_SHORT_TIMEOUT) < 0) { | 2247 | NULL, 0, WDR_SHORT_TIMEOUT) < 0) { |
2227 | dev_err(&port->dev, "%s FAILED to set " | 2248 | dev_err(&port->dev, "%s FAILED to set " |
2228 | "databits/stopbits/parity\n", __func__); | 2249 | "databits/stopbits/parity\n", __func__); |
2229 | } | 2250 | } |
@@ -2235,7 +2256,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2235 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2256 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2236 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2257 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2237 | 0, priv->interface, | 2258 | 0, priv->interface, |
2238 | buf, 0, WDR_TIMEOUT) < 0) { | 2259 | NULL, 0, WDR_TIMEOUT) < 0) { |
2239 | dev_err(&port->dev, | 2260 | dev_err(&port->dev, |
2240 | "%s error from disable flowcontrol urb\n", | 2261 | "%s error from disable flowcontrol urb\n", |
2241 | __func__); | 2262 | __func__); |
@@ -2244,9 +2265,11 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2244 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 2265 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
2245 | } else { | 2266 | } else { |
2246 | /* set the baudrate determined before */ | 2267 | /* set the baudrate determined before */ |
2268 | mutex_lock(&priv->cfg_lock); | ||
2247 | if (change_speed(tty, port)) | 2269 | if (change_speed(tty, port)) |
2248 | dev_err(&port->dev, "%s urb failed to set baudrate\n", | 2270 | dev_err(&port->dev, "%s urb failed to set baudrate\n", |
2249 | __func__); | 2271 | __func__); |
2272 | mutex_unlock(&priv->cfg_lock); | ||
2250 | /* Ensure RTS and DTR are raised when baudrate changed from 0 */ | 2273 | /* Ensure RTS and DTR are raised when baudrate changed from 0 */ |
2251 | if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) | 2274 | if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) |
2252 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 2275 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
@@ -2261,7 +2284,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2261 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2284 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2262 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2285 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2263 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), | 2286 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), |
2264 | buf, 0, WDR_TIMEOUT) < 0) { | 2287 | NULL, 0, WDR_TIMEOUT) < 0) { |
2265 | dev_err(&port->dev, | 2288 | dev_err(&port->dev, |
2266 | "urb failed to set to rts/cts flow control\n"); | 2289 | "urb failed to set to rts/cts flow control\n"); |
2267 | } | 2290 | } |
@@ -2293,7 +2316,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2293 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2316 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2294 | urb_value , (FTDI_SIO_XON_XOFF_HS | 2317 | urb_value , (FTDI_SIO_XON_XOFF_HS |
2295 | | priv->interface), | 2318 | | priv->interface), |
2296 | buf, 0, WDR_TIMEOUT) < 0) { | 2319 | NULL, 0, WDR_TIMEOUT) < 0) { |
2297 | dev_err(&port->dev, "urb failed to set to " | 2320 | dev_err(&port->dev, "urb failed to set to " |
2298 | "xon/xoff flow control\n"); | 2321 | "xon/xoff flow control\n"); |
2299 | } | 2322 | } |
@@ -2307,7 +2330,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2307 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2330 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2308 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2331 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2309 | 0, priv->interface, | 2332 | 0, priv->interface, |
2310 | buf, 0, WDR_TIMEOUT) < 0) { | 2333 | NULL, 0, WDR_TIMEOUT) < 0) { |
2311 | dev_err(&port->dev, | 2334 | dev_err(&port->dev, |
2312 | "urb failed to clear flow control\n"); | 2335 | "urb failed to clear flow control\n"); |
2313 | } | 2336 | } |
@@ -2321,21 +2344,22 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2321 | { | 2344 | { |
2322 | struct usb_serial_port *port = tty->driver_data; | 2345 | struct usb_serial_port *port = tty->driver_data; |
2323 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2346 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2324 | unsigned char buf[2]; | 2347 | unsigned char *buf; |
2348 | int len; | ||
2325 | int ret; | 2349 | int ret; |
2326 | 2350 | ||
2327 | dbg("%s TIOCMGET", __func__); | 2351 | dbg("%s TIOCMGET", __func__); |
2352 | |||
2353 | buf = kmalloc(2, GFP_KERNEL); | ||
2354 | if (!buf) | ||
2355 | return -ENOMEM; | ||
2356 | /* | ||
2357 | * The 8U232AM returns a two byte value (the SIO a 1 byte value) in | ||
2358 | * the same format as the data returned from the in point. | ||
2359 | */ | ||
2328 | switch (priv->chip_type) { | 2360 | switch (priv->chip_type) { |
2329 | case SIO: | 2361 | case SIO: |
2330 | /* Request the status from the device */ | 2362 | len = 1; |
2331 | ret = usb_control_msg(port->serial->dev, | ||
2332 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2333 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2334 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2335 | 0, 0, | ||
2336 | buf, 1, WDR_TIMEOUT); | ||
2337 | if (ret < 0) | ||
2338 | return ret; | ||
2339 | break; | 2363 | break; |
2340 | case FT8U232AM: | 2364 | case FT8U232AM: |
2341 | case FT232BM: | 2365 | case FT232BM: |
@@ -2343,27 +2367,30 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2343 | case FT232RL: | 2367 | case FT232RL: |
2344 | case FT2232H: | 2368 | case FT2232H: |
2345 | case FT4232H: | 2369 | case FT4232H: |
2346 | /* the 8U232AM returns a two byte value (the sio is a 1 byte | 2370 | len = 2; |
2347 | value) - in the same format as the data returned from the in | ||
2348 | point */ | ||
2349 | ret = usb_control_msg(port->serial->dev, | ||
2350 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2351 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2352 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2353 | 0, priv->interface, | ||
2354 | buf, 2, WDR_TIMEOUT); | ||
2355 | if (ret < 0) | ||
2356 | return ret; | ||
2357 | break; | 2371 | break; |
2358 | default: | 2372 | default: |
2359 | return -EFAULT; | 2373 | ret = -EFAULT; |
2374 | goto out; | ||
2360 | } | 2375 | } |
2361 | 2376 | ||
2362 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | 2377 | ret = usb_control_msg(port->serial->dev, |
2378 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2379 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2380 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2381 | 0, priv->interface, | ||
2382 | buf, len, WDR_TIMEOUT); | ||
2383 | if (ret < 0) | ||
2384 | goto out; | ||
2385 | |||
2386 | ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | ||
2363 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | | 2387 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | |
2364 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | | 2388 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | |
2365 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | | 2389 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | |
2366 | priv->last_dtr_rts; | 2390 | priv->last_dtr_rts; |
2391 | out: | ||
2392 | kfree(buf); | ||
2393 | return ret; | ||
2367 | } | 2394 | } |
2368 | 2395 | ||
2369 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, | 2396 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, |
@@ -2468,8 +2495,7 @@ void ftdi_unthrottle(struct tty_struct *tty) | |||
2468 | port->throttled = port->throttle_req = 0; | 2495 | port->throttled = port->throttle_req = 0; |
2469 | spin_unlock_irqrestore(&port->lock, flags); | 2496 | spin_unlock_irqrestore(&port->lock, flags); |
2470 | 2497 | ||
2471 | /* Resubmit urb if throttled and open. */ | 2498 | if (was_throttled) |
2472 | if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | ||
2473 | ftdi_submit_read_urb(port, GFP_KERNEL); | 2499 | ftdi_submit_read_urb(port, GFP_KERNEL); |
2474 | } | 2500 | } |
2475 | 2501 | ||