aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c108
1 files changed, 94 insertions, 14 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 8a74b19f1283..b458aedc5fb6 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -257,7 +257,7 @@
257#include <asm/uaccess.h> 257#include <asm/uaccess.h>
258#include <linux/usb.h> 258#include <linux/usb.h>
259#include <linux/serial.h> 259#include <linux/serial.h>
260#include "usb-serial.h" 260#include <linux/usb/serial.h>
261#include "ftdi_sio.h" 261#include "ftdi_sio.h"
262 262
263/* 263/*
@@ -313,6 +313,7 @@ static struct usb_device_id id_table_combined [] = {
313 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, 313 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
314 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, 314 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
315 { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, 315 { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
316 { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
316 { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, 317 { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
317 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, 318 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
318 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, 319 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
@@ -500,6 +501,8 @@ static struct usb_device_id id_table_combined [] = {
500 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, 501 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) },
501 { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, 502 { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
502 { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) }, 503 { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
504 { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
505 { USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) },
503 { }, /* Optional parameter entry */ 506 { }, /* Optional parameter entry */
504 { } /* Terminating entry */ 507 { } /* Terminating entry */
505}; 508};
@@ -548,11 +551,17 @@ struct ftdi_private {
548 spinlock_t rx_lock; /* spinlock for receive state */ 551 spinlock_t rx_lock; /* spinlock for receive state */
549 struct work_struct rx_work; 552 struct work_struct rx_work;
550 int rx_processed; 553 int rx_processed;
554 unsigned long rx_bytes;
551 555
552 __u16 interface; /* FT2232C port interface (0 for FT232/245) */ 556 __u16 interface; /* FT2232C port interface (0 for FT232/245) */
553 557
554 int force_baud; /* if non-zero, force the baud rate to this value */ 558 int force_baud; /* if non-zero, force the baud rate to this value */
555 int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ 559 int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
560
561 spinlock_t tx_lock; /* spinlock for transmit state */
562 unsigned long tx_bytes;
563 unsigned long tx_outstanding_bytes;
564 unsigned long tx_outstanding_urbs;
556}; 565};
557 566
558/* Used for TIOCMIWAIT */ 567/* Used for TIOCMIWAIT */
@@ -626,6 +635,9 @@ static struct usb_serial_driver ftdi_sio_device = {
626#define HIGH 1 635#define HIGH 1
627#define LOW 0 636#define LOW 0
628 637
638/* number of outstanding urbs to prevent userspace DoS from happening */
639#define URB_UPPER_LIMIT 42
640
629/* 641/*
630 * *************************************************************************** 642 * ***************************************************************************
631 * Utlity functions 643 * Utlity functions
@@ -1156,6 +1168,7 @@ static int ftdi_sio_attach (struct usb_serial *serial)
1156 } 1168 }
1157 1169
1158 spin_lock_init(&priv->rx_lock); 1170 spin_lock_init(&priv->rx_lock);
1171 spin_lock_init(&priv->tx_lock);
1159 init_waitqueue_head(&priv->delta_msr_wait); 1172 init_waitqueue_head(&priv->delta_msr_wait);
1160 /* This will push the characters through immediately rather 1173 /* This will push the characters through immediately rather
1161 than queue a task to deliver them */ 1174 than queue a task to deliver them */
@@ -1270,6 +1283,13 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
1270 1283
1271 dbg("%s", __FUNCTION__); 1284 dbg("%s", __FUNCTION__);
1272 1285
1286 spin_lock_irqsave(&priv->tx_lock, flags);
1287 priv->tx_bytes = 0;
1288 spin_unlock_irqrestore(&priv->tx_lock, flags);
1289 spin_lock_irqsave(&priv->rx_lock, flags);
1290 priv->rx_bytes = 0;
1291 spin_unlock_irqrestore(&priv->rx_lock, flags);
1292
1273 if (port->tty) 1293 if (port->tty)
1274 port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1294 port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1275 1295
@@ -1372,6 +1392,7 @@ static int ftdi_write (struct usb_serial_port *port,
1372 int data_offset ; /* will be 1 for the SIO and 0 otherwise */ 1392 int data_offset ; /* will be 1 for the SIO and 0 otherwise */
1373 int status; 1393 int status;
1374 int transfer_size; 1394 int transfer_size;
1395 unsigned long flags;
1375 1396
1376 dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count); 1397 dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);
1377 1398
@@ -1379,6 +1400,13 @@ static int ftdi_write (struct usb_serial_port *port,
1379 dbg("write request of 0 bytes"); 1400 dbg("write request of 0 bytes");
1380 return 0; 1401 return 0;
1381 } 1402 }
1403 spin_lock_irqsave(&priv->tx_lock, flags);
1404 if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) {
1405 spin_unlock_irqrestore(&priv->tx_lock, flags);
1406 dbg("%s - write limit hit\n", __FUNCTION__);
1407 return 0;
1408 }
1409 spin_unlock_irqrestore(&priv->tx_lock, flags);
1382 1410
1383 data_offset = priv->write_offset; 1411 data_offset = priv->write_offset;
1384 dbg("data_offset set to %d",data_offset); 1412 dbg("data_offset set to %d",data_offset);
@@ -1445,6 +1473,12 @@ static int ftdi_write (struct usb_serial_port *port,
1445 err("%s - failed submitting write urb, error %d", __FUNCTION__, status); 1473 err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
1446 count = status; 1474 count = status;
1447 kfree (buffer); 1475 kfree (buffer);
1476 } else {
1477 spin_lock_irqsave(&priv->tx_lock, flags);
1478 ++priv->tx_outstanding_urbs;
1479 priv->tx_outstanding_bytes += count;
1480 priv->tx_bytes += count;
1481 spin_unlock_irqrestore(&priv->tx_lock, flags);
1448 } 1482 }
1449 1483
1450 /* we are done with this urb, so let the host driver 1484 /* we are done with this urb, so let the host driver
@@ -1460,7 +1494,11 @@ static int ftdi_write (struct usb_serial_port *port,
1460 1494
1461static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs) 1495static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
1462{ 1496{
1497 unsigned long flags;
1463 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1498 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1499 struct ftdi_private *priv;
1500 int data_offset; /* will be 1 for the SIO and 0 otherwise */
1501 unsigned long countback;
1464 1502
1465 /* free up the transfer buffer, as usb_free_urb() does not do this */ 1503 /* free up the transfer buffer, as usb_free_urb() does not do this */
1466 kfree (urb->transfer_buffer); 1504 kfree (urb->transfer_buffer);
@@ -1472,34 +1510,67 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
1472 return; 1510 return;
1473 } 1511 }
1474 1512
1513 priv = usb_get_serial_port_data(port);
1514 if (!priv) {
1515 dbg("%s - bad port private data pointer - exiting", __FUNCTION__);
1516 return;
1517 }
1518 /* account for transferred data */
1519 countback = urb->actual_length;
1520 data_offset = priv->write_offset;
1521 if (data_offset > 0) {
1522 /* Subtract the control bytes */
1523 countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ));
1524 }
1525 spin_lock_irqsave(&priv->tx_lock, flags);
1526 --priv->tx_outstanding_urbs;
1527 priv->tx_outstanding_bytes -= countback;
1528 spin_unlock_irqrestore(&priv->tx_lock, flags);
1529
1475 usb_serial_port_softint(port); 1530 usb_serial_port_softint(port);
1476} /* ftdi_write_bulk_callback */ 1531} /* ftdi_write_bulk_callback */
1477 1532
1478 1533
1479static int ftdi_write_room( struct usb_serial_port *port ) 1534static int ftdi_write_room( struct usb_serial_port *port )
1480{ 1535{
1536 struct ftdi_private *priv = usb_get_serial_port_data(port);
1537 int room;
1538 unsigned long flags;
1539
1481 dbg("%s - port %d", __FUNCTION__, port->number); 1540 dbg("%s - port %d", __FUNCTION__, port->number);
1482 1541
1483 /* 1542 spin_lock_irqsave(&priv->tx_lock, flags);
1484 * We really can take anything the user throws at us 1543 if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) {
1485 * but let's pick a nice big number to tell the tty 1544 /*
1486 * layer that we have lots of free space 1545 * We really can take anything the user throws at us
1487 */ 1546 * but let's pick a nice big number to tell the tty
1488 return 2048; 1547 * layer that we have lots of free space
1548 */
1549 room = 2048;
1550 } else {
1551 room = 0;
1552 }
1553 spin_unlock_irqrestore(&priv->tx_lock, flags);
1554 return room;
1489} /* ftdi_write_room */ 1555} /* ftdi_write_room */
1490 1556
1491 1557
1492static int ftdi_chars_in_buffer (struct usb_serial_port *port) 1558static int ftdi_chars_in_buffer (struct usb_serial_port *port)
1493{ /* ftdi_chars_in_buffer */ 1559{ /* ftdi_chars_in_buffer */
1560 struct ftdi_private *priv = usb_get_serial_port_data(port);
1561 int buffered;
1562 unsigned long flags;
1563
1494 dbg("%s - port %d", __FUNCTION__, port->number); 1564 dbg("%s - port %d", __FUNCTION__, port->number);
1495 1565
1496 /* 1566 spin_lock_irqsave(&priv->tx_lock, flags);
1497 * We can't really account for how much data we 1567 buffered = (int)priv->tx_outstanding_bytes;
1498 * have sent out, but hasn't made it through to the 1568 spin_unlock_irqrestore(&priv->tx_lock, flags);
1499 * device, so just tell the tty layer that everything 1569 if (buffered < 0) {
1500 * is flushed. 1570 err("%s outstanding tx bytes is negative!", __FUNCTION__);
1501 */ 1571 buffered = 0;
1502 return 0; 1572 }
1573 return buffered;
1503} /* ftdi_chars_in_buffer */ 1574} /* ftdi_chars_in_buffer */
1504 1575
1505 1576
@@ -1509,6 +1580,8 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
1509 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1580 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1510 struct tty_struct *tty; 1581 struct tty_struct *tty;
1511 struct ftdi_private *priv; 1582 struct ftdi_private *priv;
1583 unsigned long countread;
1584 unsigned long flags;
1512 1585
1513 if (urb->number_of_packets > 0) { 1586 if (urb->number_of_packets > 0) {
1514 err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__, 1587 err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,
@@ -1543,6 +1616,13 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
1543 return; 1616 return;
1544 } 1617 }
1545 1618
1619 /* count data bytes, but not status bytes */
1620 countread = urb->actual_length;
1621 countread -= 2 * ((countread + (PKTSZ - 1)) / PKTSZ);
1622 spin_lock_irqsave(&priv->rx_lock, flags);
1623 priv->rx_bytes += countread;
1624 spin_unlock_irqrestore(&priv->rx_lock, flags);
1625
1546 ftdi_process_read(port); 1626 ftdi_process_read(port);
1547 1627
1548} /* ftdi_read_bulk_callback */ 1628} /* ftdi_read_bulk_callback */