diff options
Diffstat (limited to 'drivers/usb/serial/io_ti.c')
-rw-r--r-- | drivers/usb/serial/io_ti.c | 228 |
1 files changed, 13 insertions, 215 deletions
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index aa876f71f228..0fca2659206f 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
38 | #include <linux/serial.h> | 38 | #include <linux/serial.h> |
39 | #include <linux/kfifo.h> | ||
39 | #include <linux/ioctl.h> | 40 | #include <linux/ioctl.h> |
40 | #include <linux/firmware.h> | 41 | #include <linux/firmware.h> |
41 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
@@ -56,10 +57,6 @@ | |||
56 | #define EPROM_PAGE_SIZE 64 | 57 | #define EPROM_PAGE_SIZE 64 |
57 | 58 | ||
58 | 59 | ||
59 | struct edgeport_uart_buf_desc { | ||
60 | __u32 count; /* Number of bytes currently in buffer */ | ||
61 | }; | ||
62 | |||
63 | /* different hardware types */ | 60 | /* different hardware types */ |
64 | #define HARDWARE_TYPE_930 0 | 61 | #define HARDWARE_TYPE_930 0 |
65 | #define HARDWARE_TYPE_TIUMP 1 | 62 | #define HARDWARE_TYPE_TIUMP 1 |
@@ -87,14 +84,6 @@ struct product_info { | |||
87 | __u8 hardware_type; /* Type of hardware */ | 84 | __u8 hardware_type; /* Type of hardware */ |
88 | } __attribute__((packed)); | 85 | } __attribute__((packed)); |
89 | 86 | ||
90 | /* circular buffer */ | ||
91 | struct edge_buf { | ||
92 | unsigned int buf_size; | ||
93 | char *buf_buf; | ||
94 | char *buf_get; | ||
95 | char *buf_put; | ||
96 | }; | ||
97 | |||
98 | struct edgeport_port { | 87 | struct edgeport_port { |
99 | __u16 uart_base; | 88 | __u16 uart_base; |
100 | __u16 dma_address; | 89 | __u16 dma_address; |
@@ -108,7 +97,6 @@ struct edgeport_port { | |||
108 | int baud_rate; | 97 | int baud_rate; |
109 | int close_pending; | 98 | int close_pending; |
110 | int lsr_event; | 99 | int lsr_event; |
111 | struct edgeport_uart_buf_desc tx; | ||
112 | struct async_icount icount; | 100 | struct async_icount icount; |
113 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while | 101 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while |
114 | waiting for msr change to | 102 | waiting for msr change to |
@@ -119,7 +107,7 @@ struct edgeport_port { | |||
119 | spinlock_t ep_lock; | 107 | spinlock_t ep_lock; |
120 | int ep_read_urb_state; | 108 | int ep_read_urb_state; |
121 | int ep_write_urb_in_use; | 109 | int ep_write_urb_in_use; |
122 | struct edge_buf *ep_out_buf; | 110 | struct kfifo write_fifo; |
123 | }; | 111 | }; |
124 | 112 | ||
125 | struct edgeport_serial { | 113 | struct edgeport_serial { |
@@ -249,17 +237,6 @@ static void edge_send(struct tty_struct *tty); | |||
249 | static int edge_create_sysfs_attrs(struct usb_serial_port *port); | 237 | static int edge_create_sysfs_attrs(struct usb_serial_port *port); |
250 | static int edge_remove_sysfs_attrs(struct usb_serial_port *port); | 238 | static int edge_remove_sysfs_attrs(struct usb_serial_port *port); |
251 | 239 | ||
252 | /* circular buffer */ | ||
253 | static struct edge_buf *edge_buf_alloc(unsigned int size); | ||
254 | static void edge_buf_free(struct edge_buf *eb); | ||
255 | static void edge_buf_clear(struct edge_buf *eb); | ||
256 | static unsigned int edge_buf_data_avail(struct edge_buf *eb); | ||
257 | static unsigned int edge_buf_space_avail(struct edge_buf *eb); | ||
258 | static unsigned int edge_buf_put(struct edge_buf *eb, const char *buf, | ||
259 | unsigned int count); | ||
260 | static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, | ||
261 | unsigned int count); | ||
262 | |||
263 | 240 | ||
264 | static int ti_vread_sync(struct usb_device *dev, __u8 request, | 241 | static int ti_vread_sync(struct usb_device *dev, __u8 request, |
265 | __u16 value, __u16 index, u8 *data, int size) | 242 | __u16 value, __u16 index, u8 *data, int size) |
@@ -590,7 +567,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
590 | add_wait_queue(&tty->write_wait, &wait); | 567 | add_wait_queue(&tty->write_wait, &wait); |
591 | for (;;) { | 568 | for (;;) { |
592 | set_current_state(TASK_INTERRUPTIBLE); | 569 | set_current_state(TASK_INTERRUPTIBLE); |
593 | if (edge_buf_data_avail(port->ep_out_buf) == 0 | 570 | if (kfifo_len(&port->write_fifo) == 0 |
594 | || timeout == 0 || signal_pending(current) | 571 | || timeout == 0 || signal_pending(current) |
595 | || !usb_get_intfdata(port->port->serial->interface)) | 572 | || !usb_get_intfdata(port->port->serial->interface)) |
596 | /* disconnect */ | 573 | /* disconnect */ |
@@ -602,7 +579,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
602 | set_current_state(TASK_RUNNING); | 579 | set_current_state(TASK_RUNNING); |
603 | remove_wait_queue(&tty->write_wait, &wait); | 580 | remove_wait_queue(&tty->write_wait, &wait); |
604 | if (flush) | 581 | if (flush) |
605 | edge_buf_clear(port->ep_out_buf); | 582 | kfifo_reset_out(&port->write_fifo); |
606 | spin_unlock_irqrestore(&port->ep_lock, flags); | 583 | spin_unlock_irqrestore(&port->ep_lock, flags); |
607 | tty_kref_put(tty); | 584 | tty_kref_put(tty); |
608 | 585 | ||
@@ -2089,7 +2066,6 @@ static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
2089 | const unsigned char *data, int count) | 2066 | const unsigned char *data, int count) |
2090 | { | 2067 | { |
2091 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 2068 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
2092 | unsigned long flags; | ||
2093 | 2069 | ||
2094 | dbg("%s - port %d", __func__, port->number); | 2070 | dbg("%s - port %d", __func__, port->number); |
2095 | 2071 | ||
@@ -2103,10 +2079,8 @@ static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
2103 | if (edge_port->close_pending == 1) | 2079 | if (edge_port->close_pending == 1) |
2104 | return -ENODEV; | 2080 | return -ENODEV; |
2105 | 2081 | ||
2106 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2082 | count = kfifo_in_locked(&edge_port->write_fifo, data, count, |
2107 | count = edge_buf_put(edge_port->ep_out_buf, data, count); | 2083 | &edge_port->ep_lock); |
2108 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | ||
2109 | |||
2110 | edge_send(tty); | 2084 | edge_send(tty); |
2111 | 2085 | ||
2112 | return count; | 2086 | return count; |
@@ -2129,7 +2103,7 @@ static void edge_send(struct tty_struct *tty) | |||
2129 | return; | 2103 | return; |
2130 | } | 2104 | } |
2131 | 2105 | ||
2132 | count = edge_buf_get(edge_port->ep_out_buf, | 2106 | count = kfifo_out(&edge_port->write_fifo, |
2133 | port->write_urb->transfer_buffer, | 2107 | port->write_urb->transfer_buffer, |
2134 | port->bulk_out_size); | 2108 | port->bulk_out_size); |
2135 | 2109 | ||
@@ -2185,7 +2159,7 @@ static int edge_write_room(struct tty_struct *tty) | |||
2185 | return 0; | 2159 | return 0; |
2186 | 2160 | ||
2187 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2161 | spin_lock_irqsave(&edge_port->ep_lock, flags); |
2188 | room = edge_buf_space_avail(edge_port->ep_out_buf); | 2162 | room = kfifo_avail(&edge_port->write_fifo); |
2189 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | 2163 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); |
2190 | 2164 | ||
2191 | dbg("%s - returns %d", __func__, room); | 2165 | dbg("%s - returns %d", __func__, room); |
@@ -2207,7 +2181,7 @@ static int edge_chars_in_buffer(struct tty_struct *tty) | |||
2207 | return 0; | 2181 | return 0; |
2208 | 2182 | ||
2209 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2183 | spin_lock_irqsave(&edge_port->ep_lock, flags); |
2210 | chars = edge_buf_data_avail(edge_port->ep_out_buf); | 2184 | chars = kfifo_len(&edge_port->write_fifo); |
2211 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | 2185 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); |
2212 | 2186 | ||
2213 | dbg("%s - returns %d", __func__, chars); | 2187 | dbg("%s - returns %d", __func__, chars); |
@@ -2664,8 +2638,8 @@ static int edge_startup(struct usb_serial *serial) | |||
2664 | goto cleanup; | 2638 | goto cleanup; |
2665 | } | 2639 | } |
2666 | spin_lock_init(&edge_port->ep_lock); | 2640 | spin_lock_init(&edge_port->ep_lock); |
2667 | edge_port->ep_out_buf = edge_buf_alloc(EDGE_OUT_BUF_SIZE); | 2641 | if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, |
2668 | if (edge_port->ep_out_buf == NULL) { | 2642 | GFP_KERNEL)) { |
2669 | dev_err(&serial->dev->dev, "%s - Out of memory\n", | 2643 | dev_err(&serial->dev->dev, "%s - Out of memory\n", |
2670 | __func__); | 2644 | __func__); |
2671 | kfree(edge_port); | 2645 | kfree(edge_port); |
@@ -2682,7 +2656,7 @@ static int edge_startup(struct usb_serial *serial) | |||
2682 | cleanup: | 2656 | cleanup: |
2683 | for (--i; i >= 0; --i) { | 2657 | for (--i; i >= 0; --i) { |
2684 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2658 | edge_port = usb_get_serial_port_data(serial->port[i]); |
2685 | edge_buf_free(edge_port->ep_out_buf); | 2659 | kfifo_free(&edge_port->write_fifo); |
2686 | kfree(edge_port); | 2660 | kfree(edge_port); |
2687 | usb_set_serial_port_data(serial->port[i], NULL); | 2661 | usb_set_serial_port_data(serial->port[i], NULL); |
2688 | } | 2662 | } |
@@ -2713,7 +2687,7 @@ static void edge_release(struct usb_serial *serial) | |||
2713 | 2687 | ||
2714 | for (i = 0; i < serial->num_ports; ++i) { | 2688 | for (i = 0; i < serial->num_ports; ++i) { |
2715 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2689 | edge_port = usb_get_serial_port_data(serial->port[i]); |
2716 | edge_buf_free(edge_port->ep_out_buf); | 2690 | kfifo_free(&edge_port->write_fifo); |
2717 | kfree(edge_port); | 2691 | kfree(edge_port); |
2718 | } | 2692 | } |
2719 | kfree(usb_get_serial_data(serial)); | 2693 | kfree(usb_get_serial_data(serial)); |
@@ -2763,182 +2737,6 @@ static int edge_remove_sysfs_attrs(struct usb_serial_port *port) | |||
2763 | } | 2737 | } |
2764 | 2738 | ||
2765 | 2739 | ||
2766 | /* Circular Buffer */ | ||
2767 | |||
2768 | /* | ||
2769 | * edge_buf_alloc | ||
2770 | * | ||
2771 | * Allocate a circular buffer and all associated memory. | ||
2772 | */ | ||
2773 | |||
2774 | static struct edge_buf *edge_buf_alloc(unsigned int size) | ||
2775 | { | ||
2776 | struct edge_buf *eb; | ||
2777 | |||
2778 | |||
2779 | if (size == 0) | ||
2780 | return NULL; | ||
2781 | |||
2782 | eb = kmalloc(sizeof(struct edge_buf), GFP_KERNEL); | ||
2783 | if (eb == NULL) | ||
2784 | return NULL; | ||
2785 | |||
2786 | eb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
2787 | if (eb->buf_buf == NULL) { | ||
2788 | kfree(eb); | ||
2789 | return NULL; | ||
2790 | } | ||
2791 | |||
2792 | eb->buf_size = size; | ||
2793 | eb->buf_get = eb->buf_put = eb->buf_buf; | ||
2794 | |||
2795 | return eb; | ||
2796 | } | ||
2797 | |||
2798 | |||
2799 | /* | ||
2800 | * edge_buf_free | ||
2801 | * | ||
2802 | * Free the buffer and all associated memory. | ||
2803 | */ | ||
2804 | |||
2805 | static void edge_buf_free(struct edge_buf *eb) | ||
2806 | { | ||
2807 | if (eb) { | ||
2808 | kfree(eb->buf_buf); | ||
2809 | kfree(eb); | ||
2810 | } | ||
2811 | } | ||
2812 | |||
2813 | |||
2814 | /* | ||
2815 | * edge_buf_clear | ||
2816 | * | ||
2817 | * Clear out all data in the circular buffer. | ||
2818 | */ | ||
2819 | |||
2820 | static void edge_buf_clear(struct edge_buf *eb) | ||
2821 | { | ||
2822 | if (eb != NULL) | ||
2823 | eb->buf_get = eb->buf_put; | ||
2824 | /* equivalent to a get of all data available */ | ||
2825 | } | ||
2826 | |||
2827 | |||
2828 | /* | ||
2829 | * edge_buf_data_avail | ||
2830 | * | ||
2831 | * Return the number of bytes of data available in the circular | ||
2832 | * buffer. | ||
2833 | */ | ||
2834 | |||
2835 | static unsigned int edge_buf_data_avail(struct edge_buf *eb) | ||
2836 | { | ||
2837 | if (eb == NULL) | ||
2838 | return 0; | ||
2839 | return ((eb->buf_size + eb->buf_put - eb->buf_get) % eb->buf_size); | ||
2840 | } | ||
2841 | |||
2842 | |||
2843 | /* | ||
2844 | * edge_buf_space_avail | ||
2845 | * | ||
2846 | * Return the number of bytes of space available in the circular | ||
2847 | * buffer. | ||
2848 | */ | ||
2849 | |||
2850 | static unsigned int edge_buf_space_avail(struct edge_buf *eb) | ||
2851 | { | ||
2852 | if (eb == NULL) | ||
2853 | return 0; | ||
2854 | return ((eb->buf_size + eb->buf_get - eb->buf_put - 1) % eb->buf_size); | ||
2855 | } | ||
2856 | |||
2857 | |||
2858 | /* | ||
2859 | * edge_buf_put | ||
2860 | * | ||
2861 | * Copy data data from a user buffer and put it into the circular buffer. | ||
2862 | * Restrict to the amount of space available. | ||
2863 | * | ||
2864 | * Return the number of bytes copied. | ||
2865 | */ | ||
2866 | |||
2867 | static unsigned int edge_buf_put(struct edge_buf *eb, const char *buf, | ||
2868 | unsigned int count) | ||
2869 | { | ||
2870 | unsigned int len; | ||
2871 | |||
2872 | |||
2873 | if (eb == NULL) | ||
2874 | return 0; | ||
2875 | |||
2876 | len = edge_buf_space_avail(eb); | ||
2877 | if (count > len) | ||
2878 | count = len; | ||
2879 | |||
2880 | if (count == 0) | ||
2881 | return 0; | ||
2882 | |||
2883 | len = eb->buf_buf + eb->buf_size - eb->buf_put; | ||
2884 | if (count > len) { | ||
2885 | memcpy(eb->buf_put, buf, len); | ||
2886 | memcpy(eb->buf_buf, buf+len, count - len); | ||
2887 | eb->buf_put = eb->buf_buf + count - len; | ||
2888 | } else { | ||
2889 | memcpy(eb->buf_put, buf, count); | ||
2890 | if (count < len) | ||
2891 | eb->buf_put += count; | ||
2892 | else /* count == len */ | ||
2893 | eb->buf_put = eb->buf_buf; | ||
2894 | } | ||
2895 | |||
2896 | return count; | ||
2897 | } | ||
2898 | |||
2899 | |||
2900 | /* | ||
2901 | * edge_buf_get | ||
2902 | * | ||
2903 | * Get data from the circular buffer and copy to the given buffer. | ||
2904 | * Restrict to the amount of data available. | ||
2905 | * | ||
2906 | * Return the number of bytes copied. | ||
2907 | */ | ||
2908 | |||
2909 | static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, | ||
2910 | unsigned int count) | ||
2911 | { | ||
2912 | unsigned int len; | ||
2913 | |||
2914 | |||
2915 | if (eb == NULL) | ||
2916 | return 0; | ||
2917 | |||
2918 | len = edge_buf_data_avail(eb); | ||
2919 | if (count > len) | ||
2920 | count = len; | ||
2921 | |||
2922 | if (count == 0) | ||
2923 | return 0; | ||
2924 | |||
2925 | len = eb->buf_buf + eb->buf_size - eb->buf_get; | ||
2926 | if (count > len) { | ||
2927 | memcpy(buf, eb->buf_get, len); | ||
2928 | memcpy(buf+len, eb->buf_buf, count - len); | ||
2929 | eb->buf_get = eb->buf_buf + count - len; | ||
2930 | } else { | ||
2931 | memcpy(buf, eb->buf_get, count); | ||
2932 | if (count < len) | ||
2933 | eb->buf_get += count; | ||
2934 | else /* count == len */ | ||
2935 | eb->buf_get = eb->buf_buf; | ||
2936 | } | ||
2937 | |||
2938 | return count; | ||
2939 | } | ||
2940 | |||
2941 | |||
2942 | static struct usb_serial_driver edgeport_1port_device = { | 2740 | static struct usb_serial_driver edgeport_1port_device = { |
2943 | .driver = { | 2741 | .driver = { |
2944 | .owner = THIS_MODULE, | 2742 | .owner = THIS_MODULE, |