diff options
-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 | } | ||