diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:55:21 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:55:21 -0400 |
commit | bbb20089a3275a19e475dbc21320c3742e3ca423 (patch) | |
tree | 216fdc1cbef450ca688135c5b8969169482d9a48 /drivers/usb/serial/ftdi_sio.c | |
parent | 3e48e656903e9fd8bc805c6a2c4264d7808d315b (diff) | |
parent | 657a77fa7284d8ae28dfa48f1dc5d919bf5b2843 (diff) |
Merge branch 'dmaengine' into async-tx-next
Conflicts:
crypto/async_tx/async_xor.c
drivers/dma/ioat/dma_v2.h
drivers/dma/ioat/pci.c
drivers/md/raid5.c
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 328 |
1 files changed, 228 insertions, 100 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d9fcdaedf389..3dc3768ca71c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -47,7 +47,7 @@ | |||
47 | /* | 47 | /* |
48 | * Version Information | 48 | * Version Information |
49 | */ | 49 | */ |
50 | #define DRIVER_VERSION "v1.4.3" | 50 | #define DRIVER_VERSION "v1.5.0" |
51 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" | 51 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" |
52 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" | 52 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" |
53 | 53 | ||
@@ -82,17 +82,20 @@ struct ftdi_private { | |||
82 | int rx_processed; | 82 | int rx_processed; |
83 | unsigned long rx_bytes; | 83 | unsigned long rx_bytes; |
84 | 84 | ||
85 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ | 85 | __u16 interface; /* FT2232C, FT2232H or FT4232H port interface |
86 | (0 for FT232/245) */ | ||
86 | 87 | ||
87 | speed_t force_baud; /* if non-zero, force the baud rate to | 88 | speed_t force_baud; /* if non-zero, force the baud rate to |
88 | this value */ | 89 | this value */ |
89 | int force_rtscts; /* if non-zero, force RTS-CTS to always | 90 | int force_rtscts; /* if non-zero, force RTS-CTS to always |
90 | be enabled */ | 91 | be enabled */ |
91 | 92 | ||
93 | unsigned int latency; /* latency setting in use */ | ||
92 | spinlock_t tx_lock; /* spinlock for transmit state */ | 94 | spinlock_t tx_lock; /* spinlock for transmit state */ |
93 | unsigned long tx_bytes; | 95 | unsigned long tx_bytes; |
94 | unsigned long tx_outstanding_bytes; | 96 | unsigned long tx_outstanding_bytes; |
95 | unsigned long tx_outstanding_urbs; | 97 | unsigned long tx_outstanding_urbs; |
98 | unsigned short max_packet_size; | ||
96 | }; | 99 | }; |
97 | 100 | ||
98 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 101 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -163,6 +166,7 @@ static struct usb_device_id id_table_combined [] = { | |||
163 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, | 166 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, |
164 | { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, | 167 | { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, |
165 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, | 168 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, |
169 | { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, | ||
166 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, | 170 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, |
167 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, | 171 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, |
168 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, | 172 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, |
@@ -672,6 +676,7 @@ static struct usb_device_id id_table_combined [] = { | |||
672 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 676 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
673 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 677 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
674 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 678 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
679 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | ||
675 | { }, /* Optional parameter entry */ | 680 | { }, /* Optional parameter entry */ |
676 | { } /* Terminating entry */ | 681 | { } /* Terminating entry */ |
677 | }; | 682 | }; |
@@ -692,12 +697,13 @@ static const char *ftdi_chip_name[] = { | |||
692 | [FT232BM] = "FT232BM", | 697 | [FT232BM] = "FT232BM", |
693 | [FT2232C] = "FT2232C", | 698 | [FT2232C] = "FT2232C", |
694 | [FT232RL] = "FT232RL", | 699 | [FT232RL] = "FT232RL", |
700 | [FT2232H] = "FT2232H", | ||
701 | [FT4232H] = "FT4232H" | ||
695 | }; | 702 | }; |
696 | 703 | ||
697 | 704 | ||
698 | /* Constants for read urb and write urb */ | 705 | /* Constants for read urb and write urb */ |
699 | #define BUFSZ 512 | 706 | #define BUFSZ 512 |
700 | #define PKTSZ 64 | ||
701 | 707 | ||
702 | /* rx_flags */ | 708 | /* rx_flags */ |
703 | #define THROTTLED 0x01 | 709 | #define THROTTLED 0x01 |
@@ -714,13 +720,12 @@ static const char *ftdi_chip_name[] = { | |||
714 | /* function prototypes for a FTDI serial converter */ | 720 | /* function prototypes for a FTDI serial converter */ |
715 | static int ftdi_sio_probe(struct usb_serial *serial, | 721 | static int ftdi_sio_probe(struct usb_serial *serial, |
716 | const struct usb_device_id *id); | 722 | const struct usb_device_id *id); |
717 | static void ftdi_shutdown(struct usb_serial *serial); | ||
718 | static int ftdi_sio_port_probe(struct usb_serial_port *port); | 723 | static int ftdi_sio_port_probe(struct usb_serial_port *port); |
719 | static int ftdi_sio_port_remove(struct usb_serial_port *port); | 724 | static int ftdi_sio_port_remove(struct usb_serial_port *port); |
720 | static int ftdi_open(struct tty_struct *tty, | 725 | static int ftdi_open(struct tty_struct *tty, |
721 | struct usb_serial_port *port, struct file *filp); | 726 | struct usb_serial_port *port, struct file *filp); |
722 | static void ftdi_close(struct tty_struct *tty, | 727 | static void ftdi_close(struct usb_serial_port *port); |
723 | struct usb_serial_port *port, struct file *filp); | 728 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on); |
724 | static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | 729 | static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, |
725 | const unsigned char *buf, int count); | 730 | const unsigned char *buf, int count); |
726 | static int ftdi_write_room(struct tty_struct *tty); | 731 | static int ftdi_write_room(struct tty_struct *tty); |
@@ -743,6 +748,8 @@ static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); | |||
743 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); | 748 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); |
744 | static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); | 749 | static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); |
745 | static __u32 ftdi_232bm_baud_to_divisor(int baud); | 750 | static __u32 ftdi_232bm_baud_to_divisor(int baud); |
751 | static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base); | ||
752 | static __u32 ftdi_2232h_baud_to_divisor(int baud); | ||
746 | 753 | ||
747 | static struct usb_serial_driver ftdi_sio_device = { | 754 | static struct usb_serial_driver ftdi_sio_device = { |
748 | .driver = { | 755 | .driver = { |
@@ -758,6 +765,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
758 | .port_remove = ftdi_sio_port_remove, | 765 | .port_remove = ftdi_sio_port_remove, |
759 | .open = ftdi_open, | 766 | .open = ftdi_open, |
760 | .close = ftdi_close, | 767 | .close = ftdi_close, |
768 | .dtr_rts = ftdi_dtr_rts, | ||
761 | .throttle = ftdi_throttle, | 769 | .throttle = ftdi_throttle, |
762 | .unthrottle = ftdi_unthrottle, | 770 | .unthrottle = ftdi_unthrottle, |
763 | .write = ftdi_write, | 771 | .write = ftdi_write, |
@@ -770,7 +778,6 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
770 | .ioctl = ftdi_ioctl, | 778 | .ioctl = ftdi_ioctl, |
771 | .set_termios = ftdi_set_termios, | 779 | .set_termios = ftdi_set_termios, |
772 | .break_ctl = ftdi_break_ctl, | 780 | .break_ctl = ftdi_break_ctl, |
773 | .shutdown = ftdi_shutdown, | ||
774 | }; | 781 | }; |
775 | 782 | ||
776 | 783 | ||
@@ -836,6 +843,36 @@ static __u32 ftdi_232bm_baud_to_divisor(int baud) | |||
836 | return ftdi_232bm_baud_base_to_divisor(baud, 48000000); | 843 | return ftdi_232bm_baud_base_to_divisor(baud, 48000000); |
837 | } | 844 | } |
838 | 845 | ||
846 | static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base) | ||
847 | { | ||
848 | static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; | ||
849 | __u32 divisor; | ||
850 | int divisor3; | ||
851 | |||
852 | /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ | ||
853 | divisor3 = (base / 10 / baud) * 8; | ||
854 | |||
855 | divisor = divisor3 >> 3; | ||
856 | divisor |= (__u32)divfrac[divisor3 & 0x7] << 14; | ||
857 | /* Deal with special cases for highest baud rates. */ | ||
858 | if (divisor == 1) | ||
859 | divisor = 0; | ||
860 | else if (divisor == 0x4001) | ||
861 | divisor = 1; | ||
862 | /* | ||
863 | * Set this bit to turn off a divide by 2.5 on baud rate generator | ||
864 | * This enables baud rates up to 12Mbaud but cannot reach below 1200 | ||
865 | * baud with this bit set | ||
866 | */ | ||
867 | divisor |= 0x00020000; | ||
868 | return divisor; | ||
869 | } | ||
870 | |||
871 | static __u32 ftdi_2232h_baud_to_divisor(int baud) | ||
872 | { | ||
873 | return ftdi_2232h_baud_base_to_divisor(baud, 120000000); | ||
874 | } | ||
875 | |||
839 | #define set_mctrl(port, set) update_mctrl((port), (set), 0) | 876 | #define set_mctrl(port, set) update_mctrl((port), (set), 0) |
840 | #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) | 877 | #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) |
841 | 878 | ||
@@ -994,6 +1031,19 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
994 | baud = 9600; | 1031 | baud = 9600; |
995 | } | 1032 | } |
996 | break; | 1033 | break; |
1034 | case FT2232H: /* FT2232H chip */ | ||
1035 | case FT4232H: /* FT4232H chip */ | ||
1036 | if ((baud <= 12000000) & (baud >= 1200)) { | ||
1037 | div_value = ftdi_2232h_baud_to_divisor(baud); | ||
1038 | } else if (baud < 1200) { | ||
1039 | div_value = ftdi_232bm_baud_to_divisor(baud); | ||
1040 | } else { | ||
1041 | dbg("%s - Baud rate too high!", __func__); | ||
1042 | div_value = ftdi_232bm_baud_to_divisor(9600); | ||
1043 | div_okay = 0; | ||
1044 | baud = 9600; | ||
1045 | } | ||
1046 | break; | ||
997 | } /* priv->chip_type */ | 1047 | } /* priv->chip_type */ |
998 | 1048 | ||
999 | if (div_okay) { | 1049 | if (div_okay) { |
@@ -1037,7 +1087,54 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | |||
1037 | return rv; | 1087 | return rv; |
1038 | } | 1088 | } |
1039 | 1089 | ||
1090 | static int write_latency_timer(struct usb_serial_port *port) | ||
1091 | { | ||
1092 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1093 | struct usb_device *udev = port->serial->dev; | ||
1094 | char buf[1]; | ||
1095 | int rv = 0; | ||
1096 | int l = priv->latency; | ||
1097 | |||
1098 | if (priv->flags & ASYNC_LOW_LATENCY) | ||
1099 | l = 1; | ||
1100 | |||
1101 | dbg("%s: setting latency timer = %i", __func__, l); | ||
1102 | |||
1103 | rv = usb_control_msg(udev, | ||
1104 | usb_sndctrlpipe(udev, 0), | ||
1105 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
1106 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
1107 | l, priv->interface, | ||
1108 | buf, 0, WDR_TIMEOUT); | ||
1109 | |||
1110 | if (rv < 0) | ||
1111 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); | ||
1112 | return rv; | ||
1113 | } | ||
1114 | |||
1115 | static int read_latency_timer(struct usb_serial_port *port) | ||
1116 | { | ||
1117 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1118 | struct usb_device *udev = port->serial->dev; | ||
1119 | unsigned short latency = 0; | ||
1120 | int rv = 0; | ||
1121 | |||
1040 | 1122 | ||
1123 | dbg("%s", __func__); | ||
1124 | |||
1125 | rv = usb_control_msg(udev, | ||
1126 | usb_rcvctrlpipe(udev, 0), | ||
1127 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | ||
1128 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | ||
1129 | 0, priv->interface, | ||
1130 | (char *) &latency, 1, WDR_TIMEOUT); | ||
1131 | |||
1132 | if (rv < 0) { | ||
1133 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); | ||
1134 | return -EIO; | ||
1135 | } | ||
1136 | return latency; | ||
1137 | } | ||
1041 | 1138 | ||
1042 | static int get_serial_info(struct usb_serial_port *port, | 1139 | static int get_serial_info(struct usb_serial_port *port, |
1043 | struct serial_struct __user *retinfo) | 1140 | struct serial_struct __user *retinfo) |
@@ -1097,6 +1194,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1097 | priv->custom_divisor = new_serial.custom_divisor; | 1194 | priv->custom_divisor = new_serial.custom_divisor; |
1098 | 1195 | ||
1099 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1196 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1197 | write_latency_timer(port); | ||
1100 | 1198 | ||
1101 | check_and_exit: | 1199 | check_and_exit: |
1102 | if ((old_priv.flags & ASYNC_SPD_MASK) != | 1200 | if ((old_priv.flags & ASYNC_SPD_MASK) != |
@@ -1146,14 +1244,29 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1146 | if (interfaces > 1) { | 1244 | if (interfaces > 1) { |
1147 | int inter; | 1245 | int inter; |
1148 | 1246 | ||
1149 | /* Multiple interfaces. Assume FT2232C. */ | 1247 | /* Multiple interfaces.*/ |
1150 | priv->chip_type = FT2232C; | 1248 | if (version == 0x0800) { |
1249 | priv->chip_type = FT4232H; | ||
1250 | /* Hi-speed - baud clock runs at 120MHz */ | ||
1251 | priv->baud_base = 120000000 / 2; | ||
1252 | } else if (version == 0x0700) { | ||
1253 | priv->chip_type = FT2232H; | ||
1254 | /* Hi-speed - baud clock runs at 120MHz */ | ||
1255 | priv->baud_base = 120000000 / 2; | ||
1256 | } else | ||
1257 | priv->chip_type = FT2232C; | ||
1258 | |||
1151 | /* Determine interface code. */ | 1259 | /* Determine interface code. */ |
1152 | inter = serial->interface->altsetting->desc.bInterfaceNumber; | 1260 | inter = serial->interface->altsetting->desc.bInterfaceNumber; |
1153 | if (inter == 0) | 1261 | if (inter == 0) { |
1154 | priv->interface = PIT_SIOA; | 1262 | priv->interface = INTERFACE_A; |
1155 | else | 1263 | } else if (inter == 1) { |
1156 | priv->interface = PIT_SIOB; | 1264 | priv->interface = INTERFACE_B; |
1265 | } else if (inter == 2) { | ||
1266 | priv->interface = INTERFACE_C; | ||
1267 | } else if (inter == 3) { | ||
1268 | priv->interface = INTERFACE_D; | ||
1269 | } | ||
1157 | /* BM-type devices have a bug where bcdDevice gets set | 1270 | /* BM-type devices have a bug where bcdDevice gets set |
1158 | * to 0x200 when iSerialNumber is 0. */ | 1271 | * to 0x200 when iSerialNumber is 0. */ |
1159 | if (version < 0x500) { | 1272 | if (version < 0x500) { |
@@ -1181,6 +1294,45 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1181 | } | 1294 | } |
1182 | 1295 | ||
1183 | 1296 | ||
1297 | /* Determine the maximum packet size for the device. This depends on the chip | ||
1298 | * type and the USB host capabilities. The value should be obtained from the | ||
1299 | * device descriptor as the chip will use the appropriate values for the host.*/ | ||
1300 | static void ftdi_set_max_packet_size(struct usb_serial_port *port) | ||
1301 | { | ||
1302 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1303 | struct usb_serial *serial = port->serial; | ||
1304 | struct usb_device *udev = serial->dev; | ||
1305 | |||
1306 | struct usb_interface *interface = serial->interface; | ||
1307 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; | ||
1308 | |||
1309 | unsigned num_endpoints; | ||
1310 | int i = 0; | ||
1311 | |||
1312 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | ||
1313 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | ||
1314 | |||
1315 | /* NOTE: some customers have programmed FT232R/FT245R devices | ||
1316 | * with an endpoint size of 0 - not good. In this case, we | ||
1317 | * want to override the endpoint descriptor setting and use a | ||
1318 | * value of 64 for wMaxPacketSize */ | ||
1319 | for (i = 0; i < num_endpoints; i++) { | ||
1320 | dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1, | ||
1321 | interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize); | ||
1322 | ep_desc = &interface->cur_altsetting->endpoint[i].desc; | ||
1323 | if (ep_desc->wMaxPacketSize == 0) { | ||
1324 | ep_desc->wMaxPacketSize = cpu_to_le16(0x40); | ||
1325 | dev_info(&udev->dev, "Overriding wMaxPacketSize on endpoint %d\n", i); | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | /* set max packet size based on descriptor */ | ||
1330 | priv->max_packet_size = ep_desc->wMaxPacketSize; | ||
1331 | |||
1332 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | ||
1333 | } | ||
1334 | |||
1335 | |||
1184 | /* | 1336 | /* |
1185 | * *************************************************************************** | 1337 | * *************************************************************************** |
1186 | * Sysfs Attribute | 1338 | * Sysfs Attribute |
@@ -1192,27 +1344,13 @@ static ssize_t show_latency_timer(struct device *dev, | |||
1192 | { | 1344 | { |
1193 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1345 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1194 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1346 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1195 | struct usb_device *udev = port->serial->dev; | 1347 | if (priv->flags & ASYNC_LOW_LATENCY) |
1196 | unsigned short latency = 0; | 1348 | return sprintf(buf, "1\n"); |
1197 | int rv = 0; | 1349 | else |
1198 | 1350 | return sprintf(buf, "%i\n", priv->latency); | |
1199 | |||
1200 | dbg("%s", __func__); | ||
1201 | |||
1202 | rv = usb_control_msg(udev, | ||
1203 | usb_rcvctrlpipe(udev, 0), | ||
1204 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | ||
1205 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | ||
1206 | 0, priv->interface, | ||
1207 | (char *) &latency, 1, WDR_TIMEOUT); | ||
1208 | |||
1209 | if (rv < 0) { | ||
1210 | dev_err(dev, "Unable to read latency timer: %i\n", rv); | ||
1211 | return -EIO; | ||
1212 | } | ||
1213 | return sprintf(buf, "%i\n", latency); | ||
1214 | } | 1351 | } |
1215 | 1352 | ||
1353 | |||
1216 | /* Write a new value of the latency timer, in units of milliseconds. */ | 1354 | /* Write a new value of the latency timer, in units of milliseconds. */ |
1217 | static ssize_t store_latency_timer(struct device *dev, | 1355 | static ssize_t store_latency_timer(struct device *dev, |
1218 | struct device_attribute *attr, const char *valbuf, | 1356 | struct device_attribute *attr, const char *valbuf, |
@@ -1220,25 +1358,13 @@ static ssize_t store_latency_timer(struct device *dev, | |||
1220 | { | 1358 | { |
1221 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1359 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1222 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1360 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1223 | struct usb_device *udev = port->serial->dev; | ||
1224 | char buf[1]; | ||
1225 | int v = simple_strtoul(valbuf, NULL, 10); | 1361 | int v = simple_strtoul(valbuf, NULL, 10); |
1226 | int rv = 0; | 1362 | int rv = 0; |
1227 | 1363 | ||
1228 | dbg("%s: setting latency timer = %i", __func__, v); | 1364 | priv->latency = v; |
1229 | 1365 | rv = write_latency_timer(port); | |
1230 | rv = usb_control_msg(udev, | 1366 | if (rv < 0) |
1231 | usb_sndctrlpipe(udev, 0), | ||
1232 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
1233 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
1234 | v, priv->interface, | ||
1235 | buf, 0, WDR_TIMEOUT); | ||
1236 | |||
1237 | if (rv < 0) { | ||
1238 | dev_err(dev, "Unable to write latency timer: %i\n", rv); | ||
1239 | return -EIO; | 1367 | return -EIO; |
1240 | } | ||
1241 | |||
1242 | return count; | 1368 | return count; |
1243 | } | 1369 | } |
1244 | 1370 | ||
@@ -1290,7 +1416,9 @@ static int create_sysfs_attrs(struct usb_serial_port *port) | |||
1290 | if ((!retval) && | 1416 | if ((!retval) && |
1291 | (priv->chip_type == FT232BM || | 1417 | (priv->chip_type == FT232BM || |
1292 | priv->chip_type == FT2232C || | 1418 | priv->chip_type == FT2232C || |
1293 | priv->chip_type == FT232RL)) { | 1419 | priv->chip_type == FT232RL || |
1420 | priv->chip_type == FT2232H || | ||
1421 | priv->chip_type == FT4232H)) { | ||
1294 | retval = device_create_file(&port->dev, | 1422 | retval = device_create_file(&port->dev, |
1295 | &dev_attr_latency_timer); | 1423 | &dev_attr_latency_timer); |
1296 | } | 1424 | } |
@@ -1309,7 +1437,9 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) | |||
1309 | device_remove_file(&port->dev, &dev_attr_event_char); | 1437 | device_remove_file(&port->dev, &dev_attr_event_char); |
1310 | if (priv->chip_type == FT232BM || | 1438 | if (priv->chip_type == FT232BM || |
1311 | priv->chip_type == FT2232C || | 1439 | priv->chip_type == FT2232C || |
1312 | priv->chip_type == FT232RL) { | 1440 | priv->chip_type == FT232RL || |
1441 | priv->chip_type == FT2232H || | ||
1442 | priv->chip_type == FT4232H) { | ||
1313 | device_remove_file(&port->dev, &dev_attr_latency_timer); | 1443 | device_remove_file(&port->dev, &dev_attr_latency_timer); |
1314 | } | 1444 | } |
1315 | } | 1445 | } |
@@ -1392,6 +1522,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1392 | usb_set_serial_port_data(port, priv); | 1522 | usb_set_serial_port_data(port, priv); |
1393 | 1523 | ||
1394 | ftdi_determine_type(port); | 1524 | ftdi_determine_type(port); |
1525 | ftdi_set_max_packet_size(port); | ||
1526 | read_latency_timer(port); | ||
1395 | create_sysfs_attrs(port); | 1527 | create_sysfs_attrs(port); |
1396 | return 0; | 1528 | return 0; |
1397 | } | 1529 | } |
@@ -1460,18 +1592,6 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) | |||
1460 | return 0; | 1592 | return 0; |
1461 | } | 1593 | } |
1462 | 1594 | ||
1463 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | ||
1464 | * it is called when the usb device is disconnected | ||
1465 | * | ||
1466 | * usbserial:usb_serial_disconnect | ||
1467 | * calls __serial_close for each open of the port | ||
1468 | * shutdown is called then (ie ftdi_shutdown) | ||
1469 | */ | ||
1470 | static void ftdi_shutdown(struct usb_serial *serial) | ||
1471 | { | ||
1472 | dbg("%s", __func__); | ||
1473 | } | ||
1474 | |||
1475 | static void ftdi_sio_priv_release(struct kref *k) | 1595 | static void ftdi_sio_priv_release(struct kref *k) |
1476 | { | 1596 | { |
1477 | struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); | 1597 | struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); |
@@ -1514,6 +1634,8 @@ static int ftdi_open(struct tty_struct *tty, | |||
1514 | if (tty) | 1634 | if (tty) |
1515 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1635 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1516 | 1636 | ||
1637 | write_latency_timer(port); | ||
1638 | |||
1517 | /* No error checking for this (will get errors later anyway) */ | 1639 | /* No error checking for this (will get errors later anyway) */ |
1518 | /* See ftdi_sio.h for description of what is reset */ | 1640 | /* See ftdi_sio.h for description of what is reset */ |
1519 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1641 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
@@ -1529,11 +1651,6 @@ static int ftdi_open(struct tty_struct *tty, | |||
1529 | if (tty) | 1651 | if (tty) |
1530 | ftdi_set_termios(tty, port, tty->termios); | 1652 | ftdi_set_termios(tty, port, tty->termios); |
1531 | 1653 | ||
1532 | /* FIXME: Flow control might be enabled, so it should be checked - | ||
1533 | we have no control of defaults! */ | ||
1534 | /* Turn on RTS and DTR since we are not flow controlling by default */ | ||
1535 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1536 | |||
1537 | /* Not throttled */ | 1654 | /* Not throttled */ |
1538 | spin_lock_irqsave(&priv->rx_lock, flags); | 1655 | spin_lock_irqsave(&priv->rx_lock, flags); |
1539 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 1656 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); |
@@ -1558,6 +1675,30 @@ static int ftdi_open(struct tty_struct *tty, | |||
1558 | } /* ftdi_open */ | 1675 | } /* ftdi_open */ |
1559 | 1676 | ||
1560 | 1677 | ||
1678 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | ||
1679 | { | ||
1680 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1681 | char buf[1]; | ||
1682 | |||
1683 | mutex_lock(&port->serial->disc_mutex); | ||
1684 | if (!port->serial->disconnected) { | ||
1685 | /* Disable flow control */ | ||
1686 | if (!on && usb_control_msg(port->serial->dev, | ||
1687 | usb_sndctrlpipe(port->serial->dev, 0), | ||
1688 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | ||
1689 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | ||
1690 | 0, priv->interface, buf, 0, | ||
1691 | WDR_TIMEOUT) < 0) { | ||
1692 | dev_err(&port->dev, "error from flowcontrol urb\n"); | ||
1693 | } | ||
1694 | /* drop RTS and DTR */ | ||
1695 | if (on) | ||
1696 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1697 | else | ||
1698 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1699 | } | ||
1700 | mutex_unlock(&port->serial->disc_mutex); | ||
1701 | } | ||
1561 | 1702 | ||
1562 | /* | 1703 | /* |
1563 | * usbserial:__serial_close only calls ftdi_close if the point is open | 1704 | * usbserial:__serial_close only calls ftdi_close if the point is open |
@@ -1567,31 +1708,12 @@ static int ftdi_open(struct tty_struct *tty, | |||
1567 | * | 1708 | * |
1568 | */ | 1709 | */ |
1569 | 1710 | ||
1570 | static void ftdi_close(struct tty_struct *tty, | 1711 | static void ftdi_close(struct usb_serial_port *port) |
1571 | struct usb_serial_port *port, struct file *filp) | ||
1572 | { /* ftdi_close */ | 1712 | { /* ftdi_close */ |
1573 | unsigned int c_cflag = tty->termios->c_cflag; | ||
1574 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1713 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1575 | char buf[1]; | ||
1576 | 1714 | ||
1577 | dbg("%s", __func__); | 1715 | dbg("%s", __func__); |
1578 | 1716 | ||
1579 | mutex_lock(&port->serial->disc_mutex); | ||
1580 | if (c_cflag & HUPCL && !port->serial->disconnected) { | ||
1581 | /* Disable flow control */ | ||
1582 | if (usb_control_msg(port->serial->dev, | ||
1583 | usb_sndctrlpipe(port->serial->dev, 0), | ||
1584 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | ||
1585 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | ||
1586 | 0, priv->interface, buf, 0, | ||
1587 | WDR_TIMEOUT) < 0) { | ||
1588 | dev_err(&port->dev, "error from flowcontrol urb\n"); | ||
1589 | } | ||
1590 | |||
1591 | /* drop RTS and DTR */ | ||
1592 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1593 | } /* Note change no line if hupcl is off */ | ||
1594 | mutex_unlock(&port->serial->disc_mutex); | ||
1595 | 1717 | ||
1596 | /* cancel any scheduled reading */ | 1718 | /* cancel any scheduled reading */ |
1597 | cancel_delayed_work_sync(&priv->rx_work); | 1719 | cancel_delayed_work_sync(&priv->rx_work); |
@@ -1644,8 +1766,8 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1644 | if (data_offset > 0) { | 1766 | if (data_offset > 0) { |
1645 | /* Original sio needs control bytes too... */ | 1767 | /* Original sio needs control bytes too... */ |
1646 | transfer_size += (data_offset * | 1768 | transfer_size += (data_offset * |
1647 | ((count + (PKTSZ - 1 - data_offset)) / | 1769 | ((count + (priv->max_packet_size - 1 - data_offset)) / |
1648 | (PKTSZ - data_offset))); | 1770 | (priv->max_packet_size - data_offset))); |
1649 | } | 1771 | } |
1650 | 1772 | ||
1651 | buffer = kmalloc(transfer_size, GFP_ATOMIC); | 1773 | buffer = kmalloc(transfer_size, GFP_ATOMIC); |
@@ -1667,7 +1789,7 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1667 | if (data_offset > 0) { | 1789 | if (data_offset > 0) { |
1668 | /* Original sio requires control byte at start of | 1790 | /* Original sio requires control byte at start of |
1669 | each packet. */ | 1791 | each packet. */ |
1670 | int user_pktsz = PKTSZ - data_offset; | 1792 | int user_pktsz = priv->max_packet_size - data_offset; |
1671 | int todo = count; | 1793 | int todo = count; |
1672 | unsigned char *first_byte = buffer; | 1794 | unsigned char *first_byte = buffer; |
1673 | const unsigned char *current_position = buf; | 1795 | const unsigned char *current_position = buf; |
@@ -1748,11 +1870,6 @@ static void ftdi_write_bulk_callback(struct urb *urb) | |||
1748 | 1870 | ||
1749 | dbg("%s - port %d", __func__, port->number); | 1871 | dbg("%s - port %d", __func__, port->number); |
1750 | 1872 | ||
1751 | if (status) { | ||
1752 | dbg("nonzero write bulk status received: %d", status); | ||
1753 | return; | ||
1754 | } | ||
1755 | |||
1756 | priv = usb_get_serial_port_data(port); | 1873 | priv = usb_get_serial_port_data(port); |
1757 | if (!priv) { | 1874 | if (!priv) { |
1758 | dbg("%s - bad port private data pointer - exiting", __func__); | 1875 | dbg("%s - bad port private data pointer - exiting", __func__); |
@@ -1763,13 +1880,18 @@ static void ftdi_write_bulk_callback(struct urb *urb) | |||
1763 | data_offset = priv->write_offset; | 1880 | data_offset = priv->write_offset; |
1764 | if (data_offset > 0) { | 1881 | if (data_offset > 0) { |
1765 | /* Subtract the control bytes */ | 1882 | /* Subtract the control bytes */ |
1766 | countback -= (data_offset * DIV_ROUND_UP(countback, PKTSZ)); | 1883 | countback -= (data_offset * DIV_ROUND_UP(countback, priv->max_packet_size)); |
1767 | } | 1884 | } |
1768 | spin_lock_irqsave(&priv->tx_lock, flags); | 1885 | spin_lock_irqsave(&priv->tx_lock, flags); |
1769 | --priv->tx_outstanding_urbs; | 1886 | --priv->tx_outstanding_urbs; |
1770 | priv->tx_outstanding_bytes -= countback; | 1887 | priv->tx_outstanding_bytes -= countback; |
1771 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1888 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1772 | 1889 | ||
1890 | if (status) { | ||
1891 | dbg("nonzero write bulk status received: %d", status); | ||
1892 | return; | ||
1893 | } | ||
1894 | |||
1773 | usb_serial_port_softint(port); | 1895 | usb_serial_port_softint(port); |
1774 | } /* ftdi_write_bulk_callback */ | 1896 | } /* ftdi_write_bulk_callback */ |
1775 | 1897 | ||
@@ -1865,7 +1987,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) | |||
1865 | 1987 | ||
1866 | /* count data bytes, but not status bytes */ | 1988 | /* count data bytes, but not status bytes */ |
1867 | countread = urb->actual_length; | 1989 | countread = urb->actual_length; |
1868 | countread -= 2 * DIV_ROUND_UP(countread, PKTSZ); | 1990 | countread -= 2 * DIV_ROUND_UP(countread, priv->max_packet_size); |
1869 | spin_lock_irqsave(&priv->rx_lock, flags); | 1991 | spin_lock_irqsave(&priv->rx_lock, flags); |
1870 | priv->rx_bytes += countread; | 1992 | priv->rx_bytes += countread; |
1871 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1993 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
@@ -1938,7 +2060,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1938 | 2060 | ||
1939 | need_flip = 0; | 2061 | need_flip = 0; |
1940 | for (packet_offset = priv->rx_processed; | 2062 | for (packet_offset = priv->rx_processed; |
1941 | packet_offset < urb->actual_length; packet_offset += PKTSZ) { | 2063 | packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) { |
1942 | int length; | 2064 | int length; |
1943 | 2065 | ||
1944 | /* Compare new line status to the old one, signal if different/ | 2066 | /* Compare new line status to the old one, signal if different/ |
@@ -1953,7 +2075,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1953 | priv->prev_status = new_status; | 2075 | priv->prev_status = new_status; |
1954 | } | 2076 | } |
1955 | 2077 | ||
1956 | length = min_t(u32, PKTSZ, urb->actual_length-packet_offset)-2; | 2078 | length = min_t(u32, priv->max_packet_size, urb->actual_length-packet_offset)-2; |
1957 | if (length < 0) { | 2079 | if (length < 0) { |
1958 | dev_err(&port->dev, "%s - bad packet length: %d\n", | 2080 | dev_err(&port->dev, "%s - bad packet length: %d\n", |
1959 | __func__, length+2); | 2081 | __func__, length+2); |
@@ -1984,6 +2106,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1984 | if (data[packet_offset+1] & FTDI_RS_BI) { | 2106 | if (data[packet_offset+1] & FTDI_RS_BI) { |
1985 | error_flag = TTY_BREAK; | 2107 | error_flag = TTY_BREAK; |
1986 | dbg("BREAK received"); | 2108 | dbg("BREAK received"); |
2109 | usb_serial_handle_break(port); | ||
1987 | } | 2110 | } |
1988 | if (data[packet_offset+1] & FTDI_RS_PE) { | 2111 | if (data[packet_offset+1] & FTDI_RS_PE) { |
1989 | error_flag = TTY_PARITY; | 2112 | error_flag = TTY_PARITY; |
@@ -1998,8 +2121,11 @@ static void ftdi_process_read(struct work_struct *work) | |||
1998 | /* Note that the error flag is duplicated for | 2121 | /* Note that the error flag is duplicated for |
1999 | every character received since we don't know | 2122 | every character received since we don't know |
2000 | which character it applied to */ | 2123 | which character it applied to */ |
2001 | tty_insert_flip_char(tty, | 2124 | if (!usb_serial_handle_sysrq_char(port, |
2002 | data[packet_offset + i], error_flag); | 2125 | data[packet_offset + i])) |
2126 | tty_insert_flip_char(tty, | ||
2127 | data[packet_offset + i], | ||
2128 | error_flag); | ||
2003 | } | 2129 | } |
2004 | need_flip = 1; | 2130 | need_flip = 1; |
2005 | } | 2131 | } |
@@ -2305,6 +2431,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2305 | case FT232BM: | 2431 | case FT232BM: |
2306 | case FT2232C: | 2432 | case FT2232C: |
2307 | case FT232RL: | 2433 | case FT232RL: |
2434 | case FT2232H: | ||
2435 | case FT4232H: | ||
2308 | /* the 8U232AM returns a two byte value (the sio is a 1 byte | 2436 | /* the 8U232AM returns a two byte value (the sio is a 1 byte |
2309 | value) - in the same format as the data returned from the in | 2437 | value) - in the same format as the data returned from the in |
2310 | point */ | 2438 | point */ |