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 | |
| 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')
| -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 | ||
