aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cypress_m8.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
-rw-r--r--drivers/usb/serial/cypress_m8.c242
1 files changed, 18 insertions, 224 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index e23c77925e7a..f5d06746cc3b 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -64,6 +64,7 @@
64#include <linux/usb.h> 64#include <linux/usb.h>
65#include <linux/usb/serial.h> 65#include <linux/usb/serial.h>
66#include <linux/serial.h> 66#include <linux/serial.h>
67#include <linux/kfifo.h>
67#include <linux/delay.h> 68#include <linux/delay.h>
68#include <linux/uaccess.h> 69#include <linux/uaccess.h>
69#include <asm/unaligned.h> 70#include <asm/unaligned.h>
@@ -79,13 +80,12 @@ static int unstable_bauds;
79/* 80/*
80 * Version Information 81 * Version Information
81 */ 82 */
82#define DRIVER_VERSION "v1.09" 83#define DRIVER_VERSION "v1.10"
83#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>" 84#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
84#define DRIVER_DESC "Cypress USB to Serial Driver" 85#define DRIVER_DESC "Cypress USB to Serial Driver"
85 86
86/* write buffer size defines */ 87/* write buffer size defines */
87#define CYPRESS_BUF_SIZE 1024 88#define CYPRESS_BUF_SIZE 1024
88#define CYPRESS_CLOSING_WAIT (30*HZ)
89 89
90static const struct usb_device_id id_table_earthmate[] = { 90static const struct usb_device_id id_table_earthmate[] = {
91 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, 91 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
@@ -135,7 +135,7 @@ struct cypress_private {
135 int bytes_out; /* used for statistics */ 135 int bytes_out; /* used for statistics */
136 int cmd_count; /* used for statistics */ 136 int cmd_count; /* used for statistics */
137 int cmd_ctrl; /* always set this to 1 before issuing a command */ 137 int cmd_ctrl; /* always set this to 1 before issuing a command */
138 struct cypress_buf *buf; /* write buffer */ 138 struct kfifo write_fifo; /* write fifo */
139 int write_urb_in_use; /* write urb in use indicator */ 139 int write_urb_in_use; /* write urb in use indicator */
140 int write_urb_interval; /* interval to use for write urb */ 140 int write_urb_interval; /* interval to use for write urb */
141 int read_urb_interval; /* interval to use for read urb */ 141 int read_urb_interval; /* interval to use for read urb */
@@ -157,14 +157,6 @@ struct cypress_private {
157 struct ktermios tmp_termios; /* stores the old termios settings */ 157 struct ktermios tmp_termios; /* stores the old termios settings */
158}; 158};
159 159
160/* write buffer structure */
161struct cypress_buf {
162 unsigned int buf_size;
163 char *buf_buf;
164 char *buf_get;
165 char *buf_put;
166};
167
168/* function prototypes for the Cypress USB to serial device */ 160/* function prototypes for the Cypress USB to serial device */
169static int cypress_earthmate_startup(struct usb_serial *serial); 161static int cypress_earthmate_startup(struct usb_serial *serial);
170static int cypress_hidcom_startup(struct usb_serial *serial); 162static int cypress_hidcom_startup(struct usb_serial *serial);
@@ -190,17 +182,6 @@ static void cypress_unthrottle(struct tty_struct *tty);
190static void cypress_set_dead(struct usb_serial_port *port); 182static void cypress_set_dead(struct usb_serial_port *port);
191static void cypress_read_int_callback(struct urb *urb); 183static void cypress_read_int_callback(struct urb *urb);
192static void cypress_write_int_callback(struct urb *urb); 184static void cypress_write_int_callback(struct urb *urb);
193/* write buffer functions */
194static struct cypress_buf *cypress_buf_alloc(unsigned int size);
195static void cypress_buf_free(struct cypress_buf *cb);
196static void cypress_buf_clear(struct cypress_buf *cb);
197static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
198static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
199static unsigned int cypress_buf_put(struct cypress_buf *cb,
200 const char *buf, unsigned int count);
201static unsigned int cypress_buf_get(struct cypress_buf *cb,
202 char *buf, unsigned int count);
203
204 185
205static struct usb_serial_driver cypress_earthmate_device = { 186static struct usb_serial_driver cypress_earthmate_device = {
206 .driver = { 187 .driver = {
@@ -503,8 +484,7 @@ static int generic_startup(struct usb_serial *serial)
503 484
504 priv->comm_is_ok = !0; 485 priv->comm_is_ok = !0;
505 spin_lock_init(&priv->lock); 486 spin_lock_init(&priv->lock);
506 priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE); 487 if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) {
507 if (priv->buf == NULL) {
508 kfree(priv); 488 kfree(priv);
509 return -ENOMEM; 489 return -ENOMEM;
510 } 490 }
@@ -627,7 +607,7 @@ static void cypress_release(struct usb_serial *serial)
627 priv = usb_get_serial_port_data(serial->port[0]); 607 priv = usb_get_serial_port_data(serial->port[0]);
628 608
629 if (priv) { 609 if (priv) {
630 cypress_buf_free(priv->buf); 610 kfifo_free(&priv->write_fifo);
631 kfree(priv); 611 kfree(priv);
632 } 612 }
633} 613}
@@ -704,6 +684,7 @@ static void cypress_dtr_rts(struct usb_serial_port *port, int on)
704static void cypress_close(struct usb_serial_port *port) 684static void cypress_close(struct usb_serial_port *port)
705{ 685{
706 struct cypress_private *priv = usb_get_serial_port_data(port); 686 struct cypress_private *priv = usb_get_serial_port_data(port);
687 unsigned long flags;
707 688
708 dbg("%s - port %d", __func__, port->number); 689 dbg("%s - port %d", __func__, port->number);
709 690
@@ -713,12 +694,14 @@ static void cypress_close(struct usb_serial_port *port)
713 mutex_unlock(&port->serial->disc_mutex); 694 mutex_unlock(&port->serial->disc_mutex);
714 return; 695 return;
715 } 696 }
716 cypress_buf_clear(priv->buf); 697 spin_lock_irqsave(&priv->lock, flags);
698 kfifo_reset_out(&priv->write_fifo);
699 spin_unlock_irqrestore(&priv->lock, flags);
700
717 dbg("%s - stopping urbs", __func__); 701 dbg("%s - stopping urbs", __func__);
718 usb_kill_urb(port->interrupt_in_urb); 702 usb_kill_urb(port->interrupt_in_urb);
719 usb_kill_urb(port->interrupt_out_urb); 703 usb_kill_urb(port->interrupt_out_urb);
720 704
721
722 if (stats) 705 if (stats)
723 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", 706 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
724 priv->bytes_in, priv->bytes_out, priv->cmd_count); 707 priv->bytes_in, priv->bytes_out, priv->cmd_count);
@@ -730,7 +713,6 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
730 const unsigned char *buf, int count) 713 const unsigned char *buf, int count)
731{ 714{
732 struct cypress_private *priv = usb_get_serial_port_data(port); 715 struct cypress_private *priv = usb_get_serial_port_data(port);
733 unsigned long flags;
734 716
735 dbg("%s - port %d, %d bytes", __func__, port->number, count); 717 dbg("%s - port %d, %d bytes", __func__, port->number, count);
736 718
@@ -745,9 +727,7 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
745 if (!count) 727 if (!count)
746 return count; 728 return count;
747 729
748 spin_lock_irqsave(&priv->lock, flags); 730 count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock);
749 count = cypress_buf_put(priv->buf, buf, count);
750 spin_unlock_irqrestore(&priv->lock, flags);
751 731
752finish: 732finish:
753 cypress_send(port); 733 cypress_send(port);
@@ -807,9 +787,10 @@ static void cypress_send(struct usb_serial_port *port)
807 } else 787 } else
808 spin_unlock_irqrestore(&priv->lock, flags); 788 spin_unlock_irqrestore(&priv->lock, flags);
809 789
810 count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset], 790 count = kfifo_out_locked(&priv->write_fifo,
811 port->interrupt_out_size-offset); 791 &port->interrupt_out_buffer[offset],
812 792 port->interrupt_out_size - offset,
793 &priv->lock);
813 if (count == 0) 794 if (count == 0)
814 return; 795 return;
815 796
@@ -875,7 +856,7 @@ static int cypress_write_room(struct tty_struct *tty)
875 dbg("%s - port %d", __func__, port->number); 856 dbg("%s - port %d", __func__, port->number);
876 857
877 spin_lock_irqsave(&priv->lock, flags); 858 spin_lock_irqsave(&priv->lock, flags);
878 room = cypress_buf_space_avail(priv->buf); 859 room = kfifo_avail(&priv->write_fifo);
879 spin_unlock_irqrestore(&priv->lock, flags); 860 spin_unlock_irqrestore(&priv->lock, flags);
880 861
881 dbg("%s - returns %d", __func__, room); 862 dbg("%s - returns %d", __func__, room);
@@ -1143,7 +1124,7 @@ static int cypress_chars_in_buffer(struct tty_struct *tty)
1143 dbg("%s - port %d", __func__, port->number); 1124 dbg("%s - port %d", __func__, port->number);
1144 1125
1145 spin_lock_irqsave(&priv->lock, flags); 1126 spin_lock_irqsave(&priv->lock, flags);
1146 chars = cypress_buf_data_avail(priv->buf); 1127 chars = kfifo_len(&priv->write_fifo);
1147 spin_unlock_irqrestore(&priv->lock, flags); 1128 spin_unlock_irqrestore(&priv->lock, flags);
1148 1129
1149 dbg("%s - returns %d", __func__, chars); 1130 dbg("%s - returns %d", __func__, chars);
@@ -1309,7 +1290,7 @@ static void cypress_read_int_callback(struct urb *urb)
1309 /* process read if there is data other than line status */ 1290 /* process read if there is data other than line status */
1310 if (tty && bytes > i) { 1291 if (tty && bytes > i) {
1311 tty_insert_flip_string_fixed_flag(tty, data + i, 1292 tty_insert_flip_string_fixed_flag(tty, data + i,
1312 bytes - i, tty_flag); 1293 tty_flag, bytes - i);
1313 tty_flip_buffer_push(tty); 1294 tty_flip_buffer_push(tty);
1314 } 1295 }
1315 1296
@@ -1397,193 +1378,6 @@ static void cypress_write_int_callback(struct urb *urb)
1397 1378
1398 1379
1399/***************************************************************************** 1380/*****************************************************************************
1400 * Write buffer functions - buffering code from pl2303 used
1401 *****************************************************************************/
1402
1403/*
1404 * cypress_buf_alloc
1405 *
1406 * Allocate a circular buffer and all associated memory.
1407 */
1408
1409static struct cypress_buf *cypress_buf_alloc(unsigned int size)
1410{
1411
1412 struct cypress_buf *cb;
1413
1414
1415 if (size == 0)
1416 return NULL;
1417
1418 cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
1419 if (cb == NULL)
1420 return NULL;
1421
1422 cb->buf_buf = kmalloc(size, GFP_KERNEL);
1423 if (cb->buf_buf == NULL) {
1424 kfree(cb);
1425 return NULL;
1426 }
1427
1428 cb->buf_size = size;
1429 cb->buf_get = cb->buf_put = cb->buf_buf;
1430
1431 return cb;
1432
1433}
1434
1435
1436/*
1437 * cypress_buf_free
1438 *
1439 * Free the buffer and all associated memory.
1440 */
1441
1442static void cypress_buf_free(struct cypress_buf *cb)
1443{
1444 if (cb) {
1445 kfree(cb->buf_buf);
1446 kfree(cb);
1447 }
1448}
1449
1450
1451/*
1452 * cypress_buf_clear
1453 *
1454 * Clear out all data in the circular buffer.
1455 */
1456
1457static void cypress_buf_clear(struct cypress_buf *cb)
1458{
1459 if (cb != NULL)
1460 cb->buf_get = cb->buf_put;
1461 /* equivalent to a get of all data available */
1462}
1463
1464
1465/*
1466 * cypress_buf_data_avail
1467 *
1468 * Return the number of bytes of data available in the circular
1469 * buffer.
1470 */
1471
1472static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
1473{
1474 if (cb != NULL)
1475 return (cb->buf_size + cb->buf_put - cb->buf_get)
1476 % cb->buf_size;
1477 else
1478 return 0;
1479}
1480
1481
1482/*
1483 * cypress_buf_space_avail
1484 *
1485 * Return the number of bytes of space available in the circular
1486 * buffer.
1487 */
1488
1489static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
1490{
1491 if (cb != NULL)
1492 return (cb->buf_size + cb->buf_get - cb->buf_put - 1)
1493 % cb->buf_size;
1494 else
1495 return 0;
1496}
1497
1498
1499/*
1500 * cypress_buf_put
1501 *
1502 * Copy data data from a user buffer and put it into the circular buffer.
1503 * Restrict to the amount of space available.
1504 *
1505 * Return the number of bytes copied.
1506 */
1507
1508static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf,
1509 unsigned int count)
1510{
1511
1512 unsigned int len;
1513
1514
1515 if (cb == NULL)
1516 return 0;
1517
1518 len = cypress_buf_space_avail(cb);
1519 if (count > len)
1520 count = len;
1521
1522 if (count == 0)
1523 return 0;
1524
1525 len = cb->buf_buf + cb->buf_size - cb->buf_put;
1526 if (count > len) {
1527 memcpy(cb->buf_put, buf, len);
1528 memcpy(cb->buf_buf, buf+len, count - len);
1529 cb->buf_put = cb->buf_buf + count - len;
1530 } else {
1531 memcpy(cb->buf_put, buf, count);
1532 if (count < len)
1533 cb->buf_put += count;
1534 else /* count == len */
1535 cb->buf_put = cb->buf_buf;
1536 }
1537
1538 return count;
1539
1540}
1541
1542
1543/*
1544 * cypress_buf_get
1545 *
1546 * Get data from the circular buffer and copy to the given buffer.
1547 * Restrict to the amount of data available.
1548 *
1549 * Return the number of bytes copied.
1550 */
1551
1552static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
1553 unsigned int count)
1554{
1555
1556 unsigned int len;
1557
1558
1559 if (cb == NULL)
1560 return 0;
1561
1562 len = cypress_buf_data_avail(cb);
1563 if (count > len)
1564 count = len;
1565
1566 if (count == 0)
1567 return 0;
1568
1569 len = cb->buf_buf + cb->buf_size - cb->buf_get;
1570 if (count > len) {
1571 memcpy(buf, cb->buf_get, len);
1572 memcpy(buf+len, cb->buf_buf, count - len);
1573 cb->buf_get = cb->buf_buf + count - len;
1574 } else {
1575 memcpy(buf, cb->buf_get, count);
1576 if (count < len)
1577 cb->buf_get += count;
1578 else /* count == len */
1579 cb->buf_get = cb->buf_buf;
1580 }
1581
1582 return count;
1583
1584}
1585
1586/*****************************************************************************
1587 * Module functions 1381 * Module functions
1588 *****************************************************************************/ 1382 *****************************************************************************/
1589 1383