diff options
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 179 |
1 files changed, 140 insertions, 39 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 683304d60615..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,7 +82,8 @@ 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 */ |
@@ -94,6 +95,7 @@ struct ftdi_private { | |||
94 | unsigned long tx_bytes; | 95 | unsigned long tx_bytes; |
95 | unsigned long tx_outstanding_bytes; | 96 | unsigned long tx_outstanding_bytes; |
96 | unsigned long tx_outstanding_urbs; | 97 | unsigned long tx_outstanding_urbs; |
98 | unsigned short max_packet_size; | ||
97 | }; | 99 | }; |
98 | 100 | ||
99 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 101 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -164,6 +166,7 @@ static struct usb_device_id id_table_combined [] = { | |||
164 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, | 166 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, |
165 | { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, | 167 | { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, |
166 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, | 168 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, |
169 | { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, | ||
167 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, | 170 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, |
168 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, | 171 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, |
169 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, | 172 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, |
@@ -673,6 +676,7 @@ static struct usb_device_id id_table_combined [] = { | |||
673 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 676 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
674 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 677 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
675 | .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) }, | ||
676 | { }, /* Optional parameter entry */ | 680 | { }, /* Optional parameter entry */ |
677 | { } /* Terminating entry */ | 681 | { } /* Terminating entry */ |
678 | }; | 682 | }; |
@@ -693,12 +697,13 @@ static const char *ftdi_chip_name[] = { | |||
693 | [FT232BM] = "FT232BM", | 697 | [FT232BM] = "FT232BM", |
694 | [FT2232C] = "FT2232C", | 698 | [FT2232C] = "FT2232C", |
695 | [FT232RL] = "FT232RL", | 699 | [FT232RL] = "FT232RL", |
700 | [FT2232H] = "FT2232H", | ||
701 | [FT4232H] = "FT4232H" | ||
696 | }; | 702 | }; |
697 | 703 | ||
698 | 704 | ||
699 | /* Constants for read urb and write urb */ | 705 | /* Constants for read urb and write urb */ |
700 | #define BUFSZ 512 | 706 | #define BUFSZ 512 |
701 | #define PKTSZ 64 | ||
702 | 707 | ||
703 | /* rx_flags */ | 708 | /* rx_flags */ |
704 | #define THROTTLED 0x01 | 709 | #define THROTTLED 0x01 |
@@ -715,7 +720,6 @@ static const char *ftdi_chip_name[] = { | |||
715 | /* function prototypes for a FTDI serial converter */ | 720 | /* function prototypes for a FTDI serial converter */ |
716 | static int ftdi_sio_probe(struct usb_serial *serial, | 721 | static int ftdi_sio_probe(struct usb_serial *serial, |
717 | const struct usb_device_id *id); | 722 | const struct usb_device_id *id); |
718 | static void ftdi_shutdown(struct usb_serial *serial); | ||
719 | static int ftdi_sio_port_probe(struct usb_serial_port *port); | 723 | static int ftdi_sio_port_probe(struct usb_serial_port *port); |
720 | static int ftdi_sio_port_remove(struct usb_serial_port *port); | 724 | static int ftdi_sio_port_remove(struct usb_serial_port *port); |
721 | static int ftdi_open(struct tty_struct *tty, | 725 | static int ftdi_open(struct tty_struct *tty, |
@@ -744,6 +748,8 @@ static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); | |||
744 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); | 748 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); |
745 | 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); |
746 | 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); | ||
747 | 753 | ||
748 | static struct usb_serial_driver ftdi_sio_device = { | 754 | static struct usb_serial_driver ftdi_sio_device = { |
749 | .driver = { | 755 | .driver = { |
@@ -772,7 +778,6 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
772 | .ioctl = ftdi_ioctl, | 778 | .ioctl = ftdi_ioctl, |
773 | .set_termios = ftdi_set_termios, | 779 | .set_termios = ftdi_set_termios, |
774 | .break_ctl = ftdi_break_ctl, | 780 | .break_ctl = ftdi_break_ctl, |
775 | .shutdown = ftdi_shutdown, | ||
776 | }; | 781 | }; |
777 | 782 | ||
778 | 783 | ||
@@ -838,6 +843,36 @@ static __u32 ftdi_232bm_baud_to_divisor(int baud) | |||
838 | return ftdi_232bm_baud_base_to_divisor(baud, 48000000); | 843 | return ftdi_232bm_baud_base_to_divisor(baud, 48000000); |
839 | } | 844 | } |
840 | 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 | |||
841 | #define set_mctrl(port, set) update_mctrl((port), (set), 0) | 876 | #define set_mctrl(port, set) update_mctrl((port), (set), 0) |
842 | #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) | 877 | #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) |
843 | 878 | ||
@@ -996,6 +1031,19 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
996 | baud = 9600; | 1031 | baud = 9600; |
997 | } | 1032 | } |
998 | 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; | ||
999 | } /* priv->chip_type */ | 1047 | } /* priv->chip_type */ |
1000 | 1048 | ||
1001 | if (div_okay) { | 1049 | if (div_okay) { |
@@ -1196,14 +1244,29 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1196 | if (interfaces > 1) { | 1244 | if (interfaces > 1) { |
1197 | int inter; | 1245 | int inter; |
1198 | 1246 | ||
1199 | /* Multiple interfaces. Assume FT2232C. */ | 1247 | /* Multiple interfaces.*/ |
1200 | 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 | |||
1201 | /* Determine interface code. */ | 1259 | /* Determine interface code. */ |
1202 | inter = serial->interface->altsetting->desc.bInterfaceNumber; | 1260 | inter = serial->interface->altsetting->desc.bInterfaceNumber; |
1203 | if (inter == 0) | 1261 | if (inter == 0) { |
1204 | priv->interface = PIT_SIOA; | 1262 | priv->interface = INTERFACE_A; |
1205 | else | 1263 | } else if (inter == 1) { |
1206 | 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 | } | ||
1207 | /* BM-type devices have a bug where bcdDevice gets set | 1270 | /* BM-type devices have a bug where bcdDevice gets set |
1208 | * to 0x200 when iSerialNumber is 0. */ | 1271 | * to 0x200 when iSerialNumber is 0. */ |
1209 | if (version < 0x500) { | 1272 | if (version < 0x500) { |
@@ -1231,6 +1294,45 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1231 | } | 1294 | } |
1232 | 1295 | ||
1233 | 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 | |||
1234 | /* | 1336 | /* |
1235 | * *************************************************************************** | 1337 | * *************************************************************************** |
1236 | * Sysfs Attribute | 1338 | * Sysfs Attribute |
@@ -1314,7 +1416,9 @@ static int create_sysfs_attrs(struct usb_serial_port *port) | |||
1314 | if ((!retval) && | 1416 | if ((!retval) && |
1315 | (priv->chip_type == FT232BM || | 1417 | (priv->chip_type == FT232BM || |
1316 | priv->chip_type == FT2232C || | 1418 | priv->chip_type == FT2232C || |
1317 | priv->chip_type == FT232RL)) { | 1419 | priv->chip_type == FT232RL || |
1420 | priv->chip_type == FT2232H || | ||
1421 | priv->chip_type == FT4232H)) { | ||
1318 | retval = device_create_file(&port->dev, | 1422 | retval = device_create_file(&port->dev, |
1319 | &dev_attr_latency_timer); | 1423 | &dev_attr_latency_timer); |
1320 | } | 1424 | } |
@@ -1333,7 +1437,9 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) | |||
1333 | device_remove_file(&port->dev, &dev_attr_event_char); | 1437 | device_remove_file(&port->dev, &dev_attr_event_char); |
1334 | if (priv->chip_type == FT232BM || | 1438 | if (priv->chip_type == FT232BM || |
1335 | priv->chip_type == FT2232C || | 1439 | priv->chip_type == FT2232C || |
1336 | priv->chip_type == FT232RL) { | 1440 | priv->chip_type == FT232RL || |
1441 | priv->chip_type == FT2232H || | ||
1442 | priv->chip_type == FT4232H) { | ||
1337 | device_remove_file(&port->dev, &dev_attr_latency_timer); | 1443 | device_remove_file(&port->dev, &dev_attr_latency_timer); |
1338 | } | 1444 | } |
1339 | } | 1445 | } |
@@ -1416,6 +1522,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1416 | usb_set_serial_port_data(port, priv); | 1522 | usb_set_serial_port_data(port, priv); |
1417 | 1523 | ||
1418 | ftdi_determine_type(port); | 1524 | ftdi_determine_type(port); |
1525 | ftdi_set_max_packet_size(port); | ||
1419 | read_latency_timer(port); | 1526 | read_latency_timer(port); |
1420 | create_sysfs_attrs(port); | 1527 | create_sysfs_attrs(port); |
1421 | return 0; | 1528 | return 0; |
@@ -1485,18 +1592,6 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) | |||
1485 | return 0; | 1592 | return 0; |
1486 | } | 1593 | } |
1487 | 1594 | ||
1488 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | ||
1489 | * it is called when the usb device is disconnected | ||
1490 | * | ||
1491 | * usbserial:usb_serial_disconnect | ||
1492 | * calls __serial_close for each open of the port | ||
1493 | * shutdown is called then (ie ftdi_shutdown) | ||
1494 | */ | ||
1495 | static void ftdi_shutdown(struct usb_serial *serial) | ||
1496 | { | ||
1497 | dbg("%s", __func__); | ||
1498 | } | ||
1499 | |||
1500 | static void ftdi_sio_priv_release(struct kref *k) | 1595 | static void ftdi_sio_priv_release(struct kref *k) |
1501 | { | 1596 | { |
1502 | struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); | 1597 | struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); |
@@ -1671,8 +1766,8 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1671 | if (data_offset > 0) { | 1766 | if (data_offset > 0) { |
1672 | /* Original sio needs control bytes too... */ | 1767 | /* Original sio needs control bytes too... */ |
1673 | transfer_size += (data_offset * | 1768 | transfer_size += (data_offset * |
1674 | ((count + (PKTSZ - 1 - data_offset)) / | 1769 | ((count + (priv->max_packet_size - 1 - data_offset)) / |
1675 | (PKTSZ - data_offset))); | 1770 | (priv->max_packet_size - data_offset))); |
1676 | } | 1771 | } |
1677 | 1772 | ||
1678 | buffer = kmalloc(transfer_size, GFP_ATOMIC); | 1773 | buffer = kmalloc(transfer_size, GFP_ATOMIC); |
@@ -1694,7 +1789,7 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1694 | if (data_offset > 0) { | 1789 | if (data_offset > 0) { |
1695 | /* Original sio requires control byte at start of | 1790 | /* Original sio requires control byte at start of |
1696 | each packet. */ | 1791 | each packet. */ |
1697 | int user_pktsz = PKTSZ - data_offset; | 1792 | int user_pktsz = priv->max_packet_size - data_offset; |
1698 | int todo = count; | 1793 | int todo = count; |
1699 | unsigned char *first_byte = buffer; | 1794 | unsigned char *first_byte = buffer; |
1700 | const unsigned char *current_position = buf; | 1795 | const unsigned char *current_position = buf; |
@@ -1775,11 +1870,6 @@ static void ftdi_write_bulk_callback(struct urb *urb) | |||
1775 | 1870 | ||
1776 | dbg("%s - port %d", __func__, port->number); | 1871 | dbg("%s - port %d", __func__, port->number); |
1777 | 1872 | ||
1778 | if (status) { | ||
1779 | dbg("nonzero write bulk status received: %d", status); | ||
1780 | return; | ||
1781 | } | ||
1782 | |||
1783 | priv = usb_get_serial_port_data(port); | 1873 | priv = usb_get_serial_port_data(port); |
1784 | if (!priv) { | 1874 | if (!priv) { |
1785 | dbg("%s - bad port private data pointer - exiting", __func__); | 1875 | dbg("%s - bad port private data pointer - exiting", __func__); |
@@ -1790,13 +1880,18 @@ static void ftdi_write_bulk_callback(struct urb *urb) | |||
1790 | data_offset = priv->write_offset; | 1880 | data_offset = priv->write_offset; |
1791 | if (data_offset > 0) { | 1881 | if (data_offset > 0) { |
1792 | /* Subtract the control bytes */ | 1882 | /* Subtract the control bytes */ |
1793 | countback -= (data_offset * DIV_ROUND_UP(countback, PKTSZ)); | 1883 | countback -= (data_offset * DIV_ROUND_UP(countback, priv->max_packet_size)); |
1794 | } | 1884 | } |
1795 | spin_lock_irqsave(&priv->tx_lock, flags); | 1885 | spin_lock_irqsave(&priv->tx_lock, flags); |
1796 | --priv->tx_outstanding_urbs; | 1886 | --priv->tx_outstanding_urbs; |
1797 | priv->tx_outstanding_bytes -= countback; | 1887 | priv->tx_outstanding_bytes -= countback; |
1798 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1888 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1799 | 1889 | ||
1890 | if (status) { | ||
1891 | dbg("nonzero write bulk status received: %d", status); | ||
1892 | return; | ||
1893 | } | ||
1894 | |||
1800 | usb_serial_port_softint(port); | 1895 | usb_serial_port_softint(port); |
1801 | } /* ftdi_write_bulk_callback */ | 1896 | } /* ftdi_write_bulk_callback */ |
1802 | 1897 | ||
@@ -1892,7 +1987,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) | |||
1892 | 1987 | ||
1893 | /* count data bytes, but not status bytes */ | 1988 | /* count data bytes, but not status bytes */ |
1894 | countread = urb->actual_length; | 1989 | countread = urb->actual_length; |
1895 | countread -= 2 * DIV_ROUND_UP(countread, PKTSZ); | 1990 | countread -= 2 * DIV_ROUND_UP(countread, priv->max_packet_size); |
1896 | spin_lock_irqsave(&priv->rx_lock, flags); | 1991 | spin_lock_irqsave(&priv->rx_lock, flags); |
1897 | priv->rx_bytes += countread; | 1992 | priv->rx_bytes += countread; |
1898 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1993 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
@@ -1965,7 +2060,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1965 | 2060 | ||
1966 | need_flip = 0; | 2061 | need_flip = 0; |
1967 | for (packet_offset = priv->rx_processed; | 2062 | for (packet_offset = priv->rx_processed; |
1968 | packet_offset < urb->actual_length; packet_offset += PKTSZ) { | 2063 | packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) { |
1969 | int length; | 2064 | int length; |
1970 | 2065 | ||
1971 | /* Compare new line status to the old one, signal if different/ | 2066 | /* Compare new line status to the old one, signal if different/ |
@@ -1980,7 +2075,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
1980 | priv->prev_status = new_status; | 2075 | priv->prev_status = new_status; |
1981 | } | 2076 | } |
1982 | 2077 | ||
1983 | 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; |
1984 | if (length < 0) { | 2079 | if (length < 0) { |
1985 | dev_err(&port->dev, "%s - bad packet length: %d\n", | 2080 | dev_err(&port->dev, "%s - bad packet length: %d\n", |
1986 | __func__, length+2); | 2081 | __func__, length+2); |
@@ -2011,6 +2106,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
2011 | if (data[packet_offset+1] & FTDI_RS_BI) { | 2106 | if (data[packet_offset+1] & FTDI_RS_BI) { |
2012 | error_flag = TTY_BREAK; | 2107 | error_flag = TTY_BREAK; |
2013 | dbg("BREAK received"); | 2108 | dbg("BREAK received"); |
2109 | usb_serial_handle_break(port); | ||
2014 | } | 2110 | } |
2015 | if (data[packet_offset+1] & FTDI_RS_PE) { | 2111 | if (data[packet_offset+1] & FTDI_RS_PE) { |
2016 | error_flag = TTY_PARITY; | 2112 | error_flag = TTY_PARITY; |
@@ -2025,8 +2121,11 @@ static void ftdi_process_read(struct work_struct *work) | |||
2025 | /* Note that the error flag is duplicated for | 2121 | /* Note that the error flag is duplicated for |
2026 | every character received since we don't know | 2122 | every character received since we don't know |
2027 | which character it applied to */ | 2123 | which character it applied to */ |
2028 | tty_insert_flip_char(tty, | 2124 | if (!usb_serial_handle_sysrq_char(port, |
2029 | 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); | ||
2030 | } | 2129 | } |
2031 | need_flip = 1; | 2130 | need_flip = 1; |
2032 | } | 2131 | } |
@@ -2332,6 +2431,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2332 | case FT232BM: | 2431 | case FT232BM: |
2333 | case FT2232C: | 2432 | case FT2232C: |
2334 | case FT232RL: | 2433 | case FT232RL: |
2434 | case FT2232H: | ||
2435 | case FT4232H: | ||
2335 | /* 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 |
2336 | 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 |
2337 | point */ | 2438 | point */ |