diff options
author | Johan Hovold <jhovold@gmail.com> | 2010-05-16 14:33:50 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:49 -0400 |
commit | 117fb8d086cfc6e51c729fe5533bb83cb55c150a (patch) | |
tree | 638ecc35e7181a482a425250729622cbe2f2016e /drivers/usb/serial/cypress_m8.c | |
parent | c4f4736fc4518b92d7071016c4e28fe4f4e13e82 (diff) |
USB: cypress_m8: use kfifo to implement write buffering
Kill custom fifo implementation.
Note that cypress_m8 has no port write fifo as it has no bulk-out
endpoint.
Compile-only tested.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
-rw-r--r-- | drivers/usb/serial/cypress_m8.c | 239 |
1 files changed, 17 insertions, 222 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index d96374865289..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,7 +80,7 @@ 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 | ||
@@ -134,7 +135,7 @@ struct cypress_private { | |||
134 | int bytes_out; /* used for statistics */ | 135 | int bytes_out; /* used for statistics */ |
135 | int cmd_count; /* used for statistics */ | 136 | int cmd_count; /* used for statistics */ |
136 | 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 */ |
137 | struct cypress_buf *buf; /* write buffer */ | 138 | struct kfifo write_fifo; /* write fifo */ |
138 | int write_urb_in_use; /* write urb in use indicator */ | 139 | int write_urb_in_use; /* write urb in use indicator */ |
139 | int write_urb_interval; /* interval to use for write urb */ | 140 | int write_urb_interval; /* interval to use for write urb */ |
140 | int read_urb_interval; /* interval to use for read urb */ | 141 | int read_urb_interval; /* interval to use for read urb */ |
@@ -156,14 +157,6 @@ struct cypress_private { | |||
156 | struct ktermios tmp_termios; /* stores the old termios settings */ | 157 | struct ktermios tmp_termios; /* stores the old termios settings */ |
157 | }; | 158 | }; |
158 | 159 | ||
159 | /* write buffer structure */ | ||
160 | struct cypress_buf { | ||
161 | unsigned int buf_size; | ||
162 | char *buf_buf; | ||
163 | char *buf_get; | ||
164 | char *buf_put; | ||
165 | }; | ||
166 | |||
167 | /* function prototypes for the Cypress USB to serial device */ | 160 | /* function prototypes for the Cypress USB to serial device */ |
168 | static int cypress_earthmate_startup(struct usb_serial *serial); | 161 | static int cypress_earthmate_startup(struct usb_serial *serial); |
169 | static int cypress_hidcom_startup(struct usb_serial *serial); | 162 | static int cypress_hidcom_startup(struct usb_serial *serial); |
@@ -189,17 +182,6 @@ static void cypress_unthrottle(struct tty_struct *tty); | |||
189 | static void cypress_set_dead(struct usb_serial_port *port); | 182 | static void cypress_set_dead(struct usb_serial_port *port); |
190 | static void cypress_read_int_callback(struct urb *urb); | 183 | static void cypress_read_int_callback(struct urb *urb); |
191 | static void cypress_write_int_callback(struct urb *urb); | 184 | static void cypress_write_int_callback(struct urb *urb); |
192 | /* write buffer functions */ | ||
193 | static struct cypress_buf *cypress_buf_alloc(unsigned int size); | ||
194 | static void cypress_buf_free(struct cypress_buf *cb); | ||
195 | static void cypress_buf_clear(struct cypress_buf *cb); | ||
196 | static unsigned int cypress_buf_data_avail(struct cypress_buf *cb); | ||
197 | static unsigned int cypress_buf_space_avail(struct cypress_buf *cb); | ||
198 | static unsigned int cypress_buf_put(struct cypress_buf *cb, | ||
199 | const char *buf, unsigned int count); | ||
200 | static unsigned int cypress_buf_get(struct cypress_buf *cb, | ||
201 | char *buf, unsigned int count); | ||
202 | |||
203 | 185 | ||
204 | static struct usb_serial_driver cypress_earthmate_device = { | 186 | static struct usb_serial_driver cypress_earthmate_device = { |
205 | .driver = { | 187 | .driver = { |
@@ -502,8 +484,7 @@ static int generic_startup(struct usb_serial *serial) | |||
502 | 484 | ||
503 | priv->comm_is_ok = !0; | 485 | priv->comm_is_ok = !0; |
504 | spin_lock_init(&priv->lock); | 486 | spin_lock_init(&priv->lock); |
505 | priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE); | 487 | if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) { |
506 | if (priv->buf == NULL) { | ||
507 | kfree(priv); | 488 | kfree(priv); |
508 | return -ENOMEM; | 489 | return -ENOMEM; |
509 | } | 490 | } |
@@ -626,7 +607,7 @@ static void cypress_release(struct usb_serial *serial) | |||
626 | priv = usb_get_serial_port_data(serial->port[0]); | 607 | priv = usb_get_serial_port_data(serial->port[0]); |
627 | 608 | ||
628 | if (priv) { | 609 | if (priv) { |
629 | cypress_buf_free(priv->buf); | 610 | kfifo_free(&priv->write_fifo); |
630 | kfree(priv); | 611 | kfree(priv); |
631 | } | 612 | } |
632 | } | 613 | } |
@@ -703,6 +684,7 @@ static void cypress_dtr_rts(struct usb_serial_port *port, int on) | |||
703 | static void cypress_close(struct usb_serial_port *port) | 684 | static void cypress_close(struct usb_serial_port *port) |
704 | { | 685 | { |
705 | 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; | ||
706 | 688 | ||
707 | dbg("%s - port %d", __func__, port->number); | 689 | dbg("%s - port %d", __func__, port->number); |
708 | 690 | ||
@@ -712,12 +694,14 @@ static void cypress_close(struct usb_serial_port *port) | |||
712 | mutex_unlock(&port->serial->disc_mutex); | 694 | mutex_unlock(&port->serial->disc_mutex); |
713 | return; | 695 | return; |
714 | } | 696 | } |
715 | 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 | |||
716 | dbg("%s - stopping urbs", __func__); | 701 | dbg("%s - stopping urbs", __func__); |
717 | usb_kill_urb(port->interrupt_in_urb); | 702 | usb_kill_urb(port->interrupt_in_urb); |
718 | usb_kill_urb(port->interrupt_out_urb); | 703 | usb_kill_urb(port->interrupt_out_urb); |
719 | 704 | ||
720 | |||
721 | if (stats) | 705 | if (stats) |
722 | 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", |
723 | priv->bytes_in, priv->bytes_out, priv->cmd_count); | 707 | priv->bytes_in, priv->bytes_out, priv->cmd_count); |
@@ -729,7 +713,6 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
729 | const unsigned char *buf, int count) | 713 | const unsigned char *buf, int count) |
730 | { | 714 | { |
731 | struct cypress_private *priv = usb_get_serial_port_data(port); | 715 | struct cypress_private *priv = usb_get_serial_port_data(port); |
732 | unsigned long flags; | ||
733 | 716 | ||
734 | dbg("%s - port %d, %d bytes", __func__, port->number, count); | 717 | dbg("%s - port %d, %d bytes", __func__, port->number, count); |
735 | 718 | ||
@@ -744,9 +727,7 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
744 | if (!count) | 727 | if (!count) |
745 | return count; | 728 | return count; |
746 | 729 | ||
747 | spin_lock_irqsave(&priv->lock, flags); | 730 | count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock); |
748 | count = cypress_buf_put(priv->buf, buf, count); | ||
749 | spin_unlock_irqrestore(&priv->lock, flags); | ||
750 | 731 | ||
751 | finish: | 732 | finish: |
752 | cypress_send(port); | 733 | cypress_send(port); |
@@ -806,9 +787,10 @@ static void cypress_send(struct usb_serial_port *port) | |||
806 | } else | 787 | } else |
807 | spin_unlock_irqrestore(&priv->lock, flags); | 788 | spin_unlock_irqrestore(&priv->lock, flags); |
808 | 789 | ||
809 | count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset], | 790 | count = kfifo_out_locked(&priv->write_fifo, |
810 | port->interrupt_out_size-offset); | 791 | &port->interrupt_out_buffer[offset], |
811 | 792 | port->interrupt_out_size - offset, | |
793 | &priv->lock); | ||
812 | if (count == 0) | 794 | if (count == 0) |
813 | return; | 795 | return; |
814 | 796 | ||
@@ -874,7 +856,7 @@ static int cypress_write_room(struct tty_struct *tty) | |||
874 | dbg("%s - port %d", __func__, port->number); | 856 | dbg("%s - port %d", __func__, port->number); |
875 | 857 | ||
876 | spin_lock_irqsave(&priv->lock, flags); | 858 | spin_lock_irqsave(&priv->lock, flags); |
877 | room = cypress_buf_space_avail(priv->buf); | 859 | room = kfifo_avail(&priv->write_fifo); |
878 | spin_unlock_irqrestore(&priv->lock, flags); | 860 | spin_unlock_irqrestore(&priv->lock, flags); |
879 | 861 | ||
880 | dbg("%s - returns %d", __func__, room); | 862 | dbg("%s - returns %d", __func__, room); |
@@ -1142,7 +1124,7 @@ static int cypress_chars_in_buffer(struct tty_struct *tty) | |||
1142 | dbg("%s - port %d", __func__, port->number); | 1124 | dbg("%s - port %d", __func__, port->number); |
1143 | 1125 | ||
1144 | spin_lock_irqsave(&priv->lock, flags); | 1126 | spin_lock_irqsave(&priv->lock, flags); |
1145 | chars = cypress_buf_data_avail(priv->buf); | 1127 | chars = kfifo_len(&priv->write_fifo); |
1146 | spin_unlock_irqrestore(&priv->lock, flags); | 1128 | spin_unlock_irqrestore(&priv->lock, flags); |
1147 | 1129 | ||
1148 | dbg("%s - returns %d", __func__, chars); | 1130 | dbg("%s - returns %d", __func__, chars); |
@@ -1396,193 +1378,6 @@ static void cypress_write_int_callback(struct urb *urb) | |||
1396 | 1378 | ||
1397 | 1379 | ||
1398 | /***************************************************************************** | 1380 | /***************************************************************************** |
1399 | * Write buffer functions - buffering code from pl2303 used | ||
1400 | *****************************************************************************/ | ||
1401 | |||
1402 | /* | ||
1403 | * cypress_buf_alloc | ||
1404 | * | ||
1405 | * Allocate a circular buffer and all associated memory. | ||
1406 | */ | ||
1407 | |||
1408 | static struct cypress_buf *cypress_buf_alloc(unsigned int size) | ||
1409 | { | ||
1410 | |||
1411 | struct cypress_buf *cb; | ||
1412 | |||
1413 | |||
1414 | if (size == 0) | ||
1415 | return NULL; | ||
1416 | |||
1417 | cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL); | ||
1418 | if (cb == NULL) | ||
1419 | return NULL; | ||
1420 | |||
1421 | cb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
1422 | if (cb->buf_buf == NULL) { | ||
1423 | kfree(cb); | ||
1424 | return NULL; | ||
1425 | } | ||
1426 | |||
1427 | cb->buf_size = size; | ||
1428 | cb->buf_get = cb->buf_put = cb->buf_buf; | ||
1429 | |||
1430 | return cb; | ||
1431 | |||
1432 | } | ||
1433 | |||
1434 | |||
1435 | /* | ||
1436 | * cypress_buf_free | ||
1437 | * | ||
1438 | * Free the buffer and all associated memory. | ||
1439 | */ | ||
1440 | |||
1441 | static void cypress_buf_free(struct cypress_buf *cb) | ||
1442 | { | ||
1443 | if (cb) { | ||
1444 | kfree(cb->buf_buf); | ||
1445 | kfree(cb); | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | |||
1450 | /* | ||
1451 | * cypress_buf_clear | ||
1452 | * | ||
1453 | * Clear out all data in the circular buffer. | ||
1454 | */ | ||
1455 | |||
1456 | static void cypress_buf_clear(struct cypress_buf *cb) | ||
1457 | { | ||
1458 | if (cb != NULL) | ||
1459 | cb->buf_get = cb->buf_put; | ||
1460 | /* equivalent to a get of all data available */ | ||
1461 | } | ||
1462 | |||
1463 | |||
1464 | /* | ||
1465 | * cypress_buf_data_avail | ||
1466 | * | ||
1467 | * Return the number of bytes of data available in the circular | ||
1468 | * buffer. | ||
1469 | */ | ||
1470 | |||
1471 | static unsigned int cypress_buf_data_avail(struct cypress_buf *cb) | ||
1472 | { | ||
1473 | if (cb != NULL) | ||
1474 | return (cb->buf_size + cb->buf_put - cb->buf_get) | ||
1475 | % cb->buf_size; | ||
1476 | else | ||
1477 | return 0; | ||
1478 | } | ||
1479 | |||
1480 | |||
1481 | /* | ||
1482 | * cypress_buf_space_avail | ||
1483 | * | ||
1484 | * Return the number of bytes of space available in the circular | ||
1485 | * buffer. | ||
1486 | */ | ||
1487 | |||
1488 | static unsigned int cypress_buf_space_avail(struct cypress_buf *cb) | ||
1489 | { | ||
1490 | if (cb != NULL) | ||
1491 | return (cb->buf_size + cb->buf_get - cb->buf_put - 1) | ||
1492 | % cb->buf_size; | ||
1493 | else | ||
1494 | return 0; | ||
1495 | } | ||
1496 | |||
1497 | |||
1498 | /* | ||
1499 | * cypress_buf_put | ||
1500 | * | ||
1501 | * Copy data data from a user buffer and put it into the circular buffer. | ||
1502 | * Restrict to the amount of space available. | ||
1503 | * | ||
1504 | * Return the number of bytes copied. | ||
1505 | */ | ||
1506 | |||
1507 | static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, | ||
1508 | unsigned int count) | ||
1509 | { | ||
1510 | |||
1511 | unsigned int len; | ||
1512 | |||
1513 | |||
1514 | if (cb == NULL) | ||
1515 | return 0; | ||
1516 | |||
1517 | len = cypress_buf_space_avail(cb); | ||
1518 | if (count > len) | ||
1519 | count = len; | ||
1520 | |||
1521 | if (count == 0) | ||
1522 | return 0; | ||
1523 | |||
1524 | len = cb->buf_buf + cb->buf_size - cb->buf_put; | ||
1525 | if (count > len) { | ||
1526 | memcpy(cb->buf_put, buf, len); | ||
1527 | memcpy(cb->buf_buf, buf+len, count - len); | ||
1528 | cb->buf_put = cb->buf_buf + count - len; | ||
1529 | } else { | ||
1530 | memcpy(cb->buf_put, buf, count); | ||
1531 | if (count < len) | ||
1532 | cb->buf_put += count; | ||
1533 | else /* count == len */ | ||
1534 | cb->buf_put = cb->buf_buf; | ||
1535 | } | ||
1536 | |||
1537 | return count; | ||
1538 | |||
1539 | } | ||
1540 | |||
1541 | |||
1542 | /* | ||
1543 | * cypress_buf_get | ||
1544 | * | ||
1545 | * Get data from the circular buffer and copy to the given buffer. | ||
1546 | * Restrict to the amount of data available. | ||
1547 | * | ||
1548 | * Return the number of bytes copied. | ||
1549 | */ | ||
1550 | |||
1551 | static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, | ||
1552 | unsigned int count) | ||
1553 | { | ||
1554 | |||
1555 | unsigned int len; | ||
1556 | |||
1557 | |||
1558 | if (cb == NULL) | ||
1559 | return 0; | ||
1560 | |||
1561 | len = cypress_buf_data_avail(cb); | ||
1562 | if (count > len) | ||
1563 | count = len; | ||
1564 | |||
1565 | if (count == 0) | ||
1566 | return 0; | ||
1567 | |||
1568 | len = cb->buf_buf + cb->buf_size - cb->buf_get; | ||
1569 | if (count > len) { | ||
1570 | memcpy(buf, cb->buf_get, len); | ||
1571 | memcpy(buf+len, cb->buf_buf, count - len); | ||
1572 | cb->buf_get = cb->buf_buf + count - len; | ||
1573 | } else { | ||
1574 | memcpy(buf, cb->buf_get, count); | ||
1575 | if (count < len) | ||
1576 | cb->buf_get += count; | ||
1577 | else /* count == len */ | ||
1578 | cb->buf_get = cb->buf_buf; | ||
1579 | } | ||
1580 | |||
1581 | return count; | ||
1582 | |||
1583 | } | ||
1584 | |||
1585 | /***************************************************************************** | ||
1586 | * Module functions | 1381 | * Module functions |
1587 | *****************************************************************************/ | 1382 | *****************************************************************************/ |
1588 | 1383 | ||