diff options
| author | Johan Hovold <jhovold@gmail.com> | 2010-05-18 18:01:35 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:50 -0400 |
| commit | 074ef65aacdf4eb5a0af191e85ded8c995047e9d (patch) | |
| tree | 2111a4b4d8e2d431576e2043140bf45df80b701b /drivers/usb | |
| parent | e421fe97adf96a2b1f9d89140ec3e184f0cb7d7c (diff) | |
USB: ti_usb: use kfifo to implement write buffering
Kill custom fifo implementation.
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')
| -rw-r--r-- | drivers/usb/serial/ti_usb_3410_5052.c | 179 |
1 files changed, 14 insertions, 165 deletions
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index e1bfda33f5b9..90979a1f5311 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
| 31 | #include <linux/ioctl.h> | 31 | #include <linux/ioctl.h> |
| 32 | #include <linux/serial.h> | 32 | #include <linux/serial.h> |
| 33 | #include <linux/circ_buf.h> | 33 | #include <linux/kfifo.h> |
| 34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 35 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
| 36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
| @@ -40,7 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | /* Defines */ | 41 | /* Defines */ |
| 42 | 42 | ||
| 43 | #define TI_DRIVER_VERSION "v0.9" | 43 | #define TI_DRIVER_VERSION "v0.10" |
| 44 | #define TI_DRIVER_AUTHOR "Al Borchers <alborchers@steinerpoint.com>" | 44 | #define TI_DRIVER_AUTHOR "Al Borchers <alborchers@steinerpoint.com>" |
| 45 | #define TI_DRIVER_DESC "TI USB 3410/5052 Serial Driver" | 45 | #define TI_DRIVER_DESC "TI USB 3410/5052 Serial Driver" |
| 46 | 46 | ||
| @@ -82,7 +82,7 @@ struct ti_port { | |||
| 82 | spinlock_t tp_lock; | 82 | spinlock_t tp_lock; |
| 83 | int tp_read_urb_state; | 83 | int tp_read_urb_state; |
| 84 | int tp_write_urb_in_use; | 84 | int tp_write_urb_in_use; |
| 85 | struct circ_buf *tp_write_buf; | 85 | struct kfifo write_fifo; |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | struct ti_device { | 88 | struct ti_device { |
| @@ -144,15 +144,6 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr, | |||
| 144 | 144 | ||
| 145 | static int ti_download_firmware(struct ti_device *tdev); | 145 | static int ti_download_firmware(struct ti_device *tdev); |
| 146 | 146 | ||
| 147 | /* circular buffer */ | ||
| 148 | static struct circ_buf *ti_buf_alloc(void); | ||
| 149 | static void ti_buf_free(struct circ_buf *cb); | ||
| 150 | static void ti_buf_clear(struct circ_buf *cb); | ||
| 151 | static int ti_buf_data_avail(struct circ_buf *cb); | ||
| 152 | static int ti_buf_space_avail(struct circ_buf *cb); | ||
| 153 | static int ti_buf_put(struct circ_buf *cb, const char *buf, int count); | ||
| 154 | static int ti_buf_get(struct circ_buf *cb, char *buf, int count); | ||
| 155 | |||
| 156 | 147 | ||
| 157 | /* Data */ | 148 | /* Data */ |
| 158 | 149 | ||
| @@ -450,8 +441,8 @@ static int ti_startup(struct usb_serial *serial) | |||
| 450 | tport->tp_closing_wait = closing_wait; | 441 | tport->tp_closing_wait = closing_wait; |
| 451 | init_waitqueue_head(&tport->tp_msr_wait); | 442 | init_waitqueue_head(&tport->tp_msr_wait); |
| 452 | init_waitqueue_head(&tport->tp_write_wait); | 443 | init_waitqueue_head(&tport->tp_write_wait); |
| 453 | tport->tp_write_buf = ti_buf_alloc(); | 444 | if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, |
| 454 | if (tport->tp_write_buf == NULL) { | 445 | GFP_KERNEL)) { |
| 455 | dev_err(&dev->dev, "%s - out of memory\n", __func__); | 446 | dev_err(&dev->dev, "%s - out of memory\n", __func__); |
| 456 | kfree(tport); | 447 | kfree(tport); |
| 457 | status = -ENOMEM; | 448 | status = -ENOMEM; |
| @@ -468,7 +459,7 @@ static int ti_startup(struct usb_serial *serial) | |||
| 468 | free_tports: | 459 | free_tports: |
| 469 | for (--i; i >= 0; --i) { | 460 | for (--i; i >= 0; --i) { |
| 470 | tport = usb_get_serial_port_data(serial->port[i]); | 461 | tport = usb_get_serial_port_data(serial->port[i]); |
| 471 | ti_buf_free(tport->tp_write_buf); | 462 | kfifo_free(&tport->write_fifo); |
| 472 | kfree(tport); | 463 | kfree(tport); |
| 473 | usb_set_serial_port_data(serial->port[i], NULL); | 464 | usb_set_serial_port_data(serial->port[i], NULL); |
| 474 | } | 465 | } |
| @@ -490,7 +481,7 @@ static void ti_release(struct usb_serial *serial) | |||
| 490 | for (i = 0; i < serial->num_ports; ++i) { | 481 | for (i = 0; i < serial->num_ports; ++i) { |
| 491 | tport = usb_get_serial_port_data(serial->port[i]); | 482 | tport = usb_get_serial_port_data(serial->port[i]); |
| 492 | if (tport) { | 483 | if (tport) { |
| 493 | ti_buf_free(tport->tp_write_buf); | 484 | kfifo_free(&tport->write_fifo); |
| 494 | kfree(tport); | 485 | kfree(tport); |
| 495 | } | 486 | } |
| 496 | } | 487 | } |
| @@ -701,7 +692,6 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 701 | const unsigned char *data, int count) | 692 | const unsigned char *data, int count) |
| 702 | { | 693 | { |
| 703 | struct ti_port *tport = usb_get_serial_port_data(port); | 694 | struct ti_port *tport = usb_get_serial_port_data(port); |
| 704 | unsigned long flags; | ||
| 705 | 695 | ||
| 706 | dbg("%s - port %d", __func__, port->number); | 696 | dbg("%s - port %d", __func__, port->number); |
| 707 | 697 | ||
| @@ -713,10 +703,8 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 713 | if (tport == NULL || !tport->tp_is_open) | 703 | if (tport == NULL || !tport->tp_is_open) |
| 714 | return -ENODEV; | 704 | return -ENODEV; |
| 715 | 705 | ||
| 716 | spin_lock_irqsave(&tport->tp_lock, flags); | 706 | count = kfifo_in_locked(&tport->write_fifo, data, count, |
| 717 | count = ti_buf_put(tport->tp_write_buf, data, count); | 707 | &tport->tp_lock); |
| 718 | spin_unlock_irqrestore(&tport->tp_lock, flags); | ||
| 719 | |||
| 720 | ti_send(tport); | 708 | ti_send(tport); |
| 721 | 709 | ||
| 722 | return count; | 710 | return count; |
| @@ -736,7 +724,7 @@ static int ti_write_room(struct tty_struct *tty) | |||
| 736 | return 0; | 724 | return 0; |
| 737 | 725 | ||
| 738 | spin_lock_irqsave(&tport->tp_lock, flags); | 726 | spin_lock_irqsave(&tport->tp_lock, flags); |
| 739 | room = ti_buf_space_avail(tport->tp_write_buf); | 727 | room = kfifo_avail(&tport->write_fifo); |
| 740 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 728 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
| 741 | 729 | ||
| 742 | dbg("%s - returns %d", __func__, room); | 730 | dbg("%s - returns %d", __func__, room); |
| @@ -757,7 +745,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty) | |||
| 757 | return 0; | 745 | return 0; |
| 758 | 746 | ||
| 759 | spin_lock_irqsave(&tport->tp_lock, flags); | 747 | spin_lock_irqsave(&tport->tp_lock, flags); |
| 760 | chars = ti_buf_data_avail(tport->tp_write_buf); | 748 | chars = kfifo_len(&tport->write_fifo); |
| 761 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 749 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
| 762 | 750 | ||
| 763 | dbg("%s - returns %d", __func__, chars); | 751 | dbg("%s - returns %d", __func__, chars); |
| @@ -1309,7 +1297,7 @@ static void ti_send(struct ti_port *tport) | |||
| 1309 | if (tport->tp_write_urb_in_use) | 1297 | if (tport->tp_write_urb_in_use) |
| 1310 | goto unlock; | 1298 | goto unlock; |
| 1311 | 1299 | ||
| 1312 | count = ti_buf_get(tport->tp_write_buf, | 1300 | count = kfifo_out(&tport->write_fifo, |
| 1313 | port->write_urb->transfer_buffer, | 1301 | port->write_urb->transfer_buffer, |
| 1314 | port->bulk_out_size); | 1302 | port->bulk_out_size); |
| 1315 | 1303 | ||
| @@ -1504,7 +1492,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
| 1504 | add_wait_queue(&tport->tp_write_wait, &wait); | 1492 | add_wait_queue(&tport->tp_write_wait, &wait); |
| 1505 | for (;;) { | 1493 | for (;;) { |
| 1506 | set_current_state(TASK_INTERRUPTIBLE); | 1494 | set_current_state(TASK_INTERRUPTIBLE); |
| 1507 | if (ti_buf_data_avail(tport->tp_write_buf) == 0 | 1495 | if (kfifo_len(&tport->write_fifo) == 0 |
| 1508 | || timeout == 0 || signal_pending(current) | 1496 | || timeout == 0 || signal_pending(current) |
| 1509 | || tdev->td_urb_error | 1497 | || tdev->td_urb_error |
| 1510 | || port->serial->disconnected) /* disconnect */ | 1498 | || port->serial->disconnected) /* disconnect */ |
| @@ -1518,7 +1506,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
| 1518 | 1506 | ||
| 1519 | /* flush any remaining data in the buffer */ | 1507 | /* flush any remaining data in the buffer */ |
| 1520 | if (flush) | 1508 | if (flush) |
| 1521 | ti_buf_clear(tport->tp_write_buf); | 1509 | kfifo_reset_out(&tport->write_fifo); |
| 1522 | 1510 | ||
| 1523 | spin_unlock_irq(&tport->tp_lock); | 1511 | spin_unlock_irq(&tport->tp_lock); |
| 1524 | 1512 | ||
| @@ -1761,142 +1749,3 @@ static int ti_download_firmware(struct ti_device *tdev) | |||
| 1761 | 1749 | ||
| 1762 | return 0; | 1750 | return 0; |
| 1763 | } | 1751 | } |
| 1764 | |||
| 1765 | |||
| 1766 | /* Circular Buffer Functions */ | ||
| 1767 | |||
| 1768 | /* | ||
| 1769 | * ti_buf_alloc | ||
| 1770 | * | ||
| 1771 | * Allocate a circular buffer and all associated memory. | ||
| 1772 | */ | ||
| 1773 | |||
| 1774 | static struct circ_buf *ti_buf_alloc(void) | ||
| 1775 | { | ||
| 1776 | struct circ_buf *cb; | ||
| 1777 | |||
| 1778 | cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL); | ||
| 1779 | if (cb == NULL) | ||
| 1780 | return NULL; | ||
| 1781 | |||
| 1782 | cb->buf = kmalloc(TI_WRITE_BUF_SIZE, GFP_KERNEL); | ||
| 1783 | if (cb->buf == NULL) { | ||
| 1784 | kfree(cb); | ||
| 1785 | return NULL; | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | ti_buf_clear(cb); | ||
| 1789 | |||
| 1790 | return cb; | ||
| 1791 | } | ||
| 1792 | |||
| 1793 | |||
| 1794 | /* | ||
| 1795 | * ti_buf_free | ||
| 1796 | * | ||
| 1797 | * Free the buffer and all associated memory. | ||
| 1798 | */ | ||
| 1799 | |||
| 1800 | static void ti_buf_free(struct circ_buf *cb) | ||
| 1801 | { | ||
| 1802 | kfree(cb->buf); | ||
| 1803 | kfree(cb); | ||
| 1804 | } | ||
| 1805 | |||
| 1806 | |||
| 1807 | /* | ||
| 1808 | * ti_buf_clear | ||
| 1809 | * | ||
| 1810 | * Clear out all data in the circular buffer. | ||
| 1811 | */ | ||
| 1812 | |||
| 1813 | static void ti_buf_clear(struct circ_buf *cb) | ||
| 1814 | { | ||
| 1815 | cb->head = cb->tail = 0; | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | |||
| 1819 | /* | ||
| 1820 | * ti_buf_data_avail | ||
| 1821 | * | ||
| 1822 | * Return the number of bytes of data available in the circular | ||
| 1823 | * buffer. | ||
| 1824 | */ | ||
| 1825 | |||
| 1826 | static int ti_buf_data_avail(struct circ_buf *cb) | ||
| 1827 | { | ||
| 1828 | return CIRC_CNT(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
| 1829 | } | ||
| 1830 | |||
| 1831 | |||
| 1832 | /* | ||
| 1833 | * ti_buf_space_avail | ||
| 1834 | * | ||
| 1835 | * Return the number of bytes of space available in the circular | ||
| 1836 | * buffer. | ||
| 1837 | */ | ||
| 1838 | |||
| 1839 | static int ti_buf_space_avail(struct circ_buf *cb) | ||
| 1840 | { | ||
| 1841 | return CIRC_SPACE(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
| 1842 | } | ||
| 1843 | |||
| 1844 | |||
| 1845 | /* | ||
| 1846 | * ti_buf_put | ||
| 1847 | * | ||
| 1848 | * Copy data data from a user buffer and put it into the circular buffer. | ||
| 1849 | * Restrict to the amount of space available. | ||
| 1850 | * | ||
| 1851 | * Return the number of bytes copied. | ||
| 1852 | */ | ||
| 1853 | |||
| 1854 | static int ti_buf_put(struct circ_buf *cb, const char *buf, int count) | ||
| 1855 | { | ||
| 1856 | int c, ret = 0; | ||
| 1857 | |||
| 1858 | while (1) { | ||
| 1859 | c = CIRC_SPACE_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
| 1860 | if (count < c) | ||
| 1861 | c = count; | ||
| 1862 | if (c <= 0) | ||
| 1863 | break; | ||
| 1864 | memcpy(cb->buf + cb->head, buf, c); | ||
| 1865 | cb->head = (cb->head + c) & (TI_WRITE_BUF_SIZE-1); | ||
| 1866 | buf += c; | ||
| 1867 | count -= c; | ||
| 1868 | ret += c; | ||
| 1869 | } | ||
| 1870 | |||
| 1871 | return ret; | ||
| 1872 | } | ||
| 1873 | |||
| 1874 | |||
| 1875 | /* | ||
| 1876 | * ti_buf_get | ||
| 1877 | * | ||
| 1878 | * Get data from the circular buffer and copy to the given buffer. | ||
| 1879 | * Restrict to the amount of data available. | ||
| 1880 | * | ||
| 1881 | * Return the number of bytes copied. | ||
| 1882 | */ | ||
| 1883 | |||
| 1884 | static int ti_buf_get(struct circ_buf *cb, char *buf, int count) | ||
| 1885 | { | ||
| 1886 | int c, ret = 0; | ||
| 1887 | |||
| 1888 | while (1) { | ||
| 1889 | c = CIRC_CNT_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
| 1890 | if (count < c) | ||
| 1891 | c = count; | ||
| 1892 | if (c <= 0) | ||
| 1893 | break; | ||
| 1894 | memcpy(buf, cb->buf + cb->tail, c); | ||
| 1895 | cb->tail = (cb->tail + c) & (TI_WRITE_BUF_SIZE-1); | ||
| 1896 | buf += c; | ||
| 1897 | count -= c; | ||
| 1898 | ret += c; | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | return ret; | ||
| 1902 | } | ||
