diff options
| -rw-r--r-- | drivers/usb/serial/io_ti.c | 223 |
1 files changed, 13 insertions, 210 deletions
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 2e3d0acbc389..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> |
| @@ -83,14 +84,6 @@ struct product_info { | |||
| 83 | __u8 hardware_type; /* Type of hardware */ | 84 | __u8 hardware_type; /* Type of hardware */ |
| 84 | } __attribute__((packed)); | 85 | } __attribute__((packed)); |
| 85 | 86 | ||
| 86 | /* circular buffer */ | ||
| 87 | struct edge_buf { | ||
| 88 | unsigned int buf_size; | ||
| 89 | char *buf_buf; | ||
| 90 | char *buf_get; | ||
| 91 | char *buf_put; | ||
| 92 | }; | ||
| 93 | |||
| 94 | struct edgeport_port { | 87 | struct edgeport_port { |
| 95 | __u16 uart_base; | 88 | __u16 uart_base; |
| 96 | __u16 dma_address; | 89 | __u16 dma_address; |
| @@ -114,7 +107,7 @@ struct edgeport_port { | |||
| 114 | spinlock_t ep_lock; | 107 | spinlock_t ep_lock; |
| 115 | int ep_read_urb_state; | 108 | int ep_read_urb_state; |
| 116 | int ep_write_urb_in_use; | 109 | int ep_write_urb_in_use; |
| 117 | struct edge_buf *ep_out_buf; | 110 | struct kfifo write_fifo; |
| 118 | }; | 111 | }; |
| 119 | 112 | ||
| 120 | struct edgeport_serial { | 113 | struct edgeport_serial { |
| @@ -244,17 +237,6 @@ static void edge_send(struct tty_struct *tty); | |||
| 244 | static int edge_create_sysfs_attrs(struct usb_serial_port *port); | 237 | static int edge_create_sysfs_attrs(struct usb_serial_port *port); |
| 245 | static int edge_remove_sysfs_attrs(struct usb_serial_port *port); | 238 | static int edge_remove_sysfs_attrs(struct usb_serial_port *port); |
| 246 | 239 | ||
| 247 | /* circular buffer */ | ||
| 248 | static struct edge_buf *edge_buf_alloc(unsigned int size); | ||
| 249 | static void edge_buf_free(struct edge_buf *eb); | ||
| 250 | static void edge_buf_clear(struct edge_buf *eb); | ||
| 251 | static unsigned int edge_buf_data_avail(struct edge_buf *eb); | ||
| 252 | static unsigned int edge_buf_space_avail(struct edge_buf *eb); | ||
| 253 | static unsigned int edge_buf_put(struct edge_buf *eb, const char *buf, | ||
| 254 | unsigned int count); | ||
| 255 | static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, | ||
| 256 | unsigned int count); | ||
| 257 | |||
| 258 | 240 | ||
| 259 | static int ti_vread_sync(struct usb_device *dev, __u8 request, | 241 | static int ti_vread_sync(struct usb_device *dev, __u8 request, |
| 260 | __u16 value, __u16 index, u8 *data, int size) | 242 | __u16 value, __u16 index, u8 *data, int size) |
| @@ -585,7 +567,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
| 585 | add_wait_queue(&tty->write_wait, &wait); | 567 | add_wait_queue(&tty->write_wait, &wait); |
| 586 | for (;;) { | 568 | for (;;) { |
| 587 | set_current_state(TASK_INTERRUPTIBLE); | 569 | set_current_state(TASK_INTERRUPTIBLE); |
| 588 | if (edge_buf_data_avail(port->ep_out_buf) == 0 | 570 | if (kfifo_len(&port->write_fifo) == 0 |
| 589 | || timeout == 0 || signal_pending(current) | 571 | || timeout == 0 || signal_pending(current) |
| 590 | || !usb_get_intfdata(port->port->serial->interface)) | 572 | || !usb_get_intfdata(port->port->serial->interface)) |
| 591 | /* disconnect */ | 573 | /* disconnect */ |
| @@ -597,7 +579,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
| 597 | set_current_state(TASK_RUNNING); | 579 | set_current_state(TASK_RUNNING); |
| 598 | remove_wait_queue(&tty->write_wait, &wait); | 580 | remove_wait_queue(&tty->write_wait, &wait); |
| 599 | if (flush) | 581 | if (flush) |
| 600 | edge_buf_clear(port->ep_out_buf); | 582 | kfifo_reset_out(&port->write_fifo); |
| 601 | spin_unlock_irqrestore(&port->ep_lock, flags); | 583 | spin_unlock_irqrestore(&port->ep_lock, flags); |
| 602 | tty_kref_put(tty); | 584 | tty_kref_put(tty); |
| 603 | 585 | ||
| @@ -2084,7 +2066,6 @@ static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 2084 | const unsigned char *data, int count) | 2066 | const unsigned char *data, int count) |
| 2085 | { | 2067 | { |
| 2086 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 2068 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
| 2087 | unsigned long flags; | ||
| 2088 | 2069 | ||
| 2089 | dbg("%s - port %d", __func__, port->number); | 2070 | dbg("%s - port %d", __func__, port->number); |
| 2090 | 2071 | ||
| @@ -2098,10 +2079,8 @@ static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 2098 | if (edge_port->close_pending == 1) | 2079 | if (edge_port->close_pending == 1) |
| 2099 | return -ENODEV; | 2080 | return -ENODEV; |
| 2100 | 2081 | ||
| 2101 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2082 | count = kfifo_in_locked(&edge_port->write_fifo, data, count, |
| 2102 | count = edge_buf_put(edge_port->ep_out_buf, data, count); | 2083 | &edge_port->ep_lock); |
| 2103 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | ||
| 2104 | |||
| 2105 | edge_send(tty); | 2084 | edge_send(tty); |
| 2106 | 2085 | ||
| 2107 | return count; | 2086 | return count; |
| @@ -2124,7 +2103,7 @@ static void edge_send(struct tty_struct *tty) | |||
| 2124 | return; | 2103 | return; |
| 2125 | } | 2104 | } |
| 2126 | 2105 | ||
| 2127 | count = edge_buf_get(edge_port->ep_out_buf, | 2106 | count = kfifo_out(&edge_port->write_fifo, |
| 2128 | port->write_urb->transfer_buffer, | 2107 | port->write_urb->transfer_buffer, |
| 2129 | port->bulk_out_size); | 2108 | port->bulk_out_size); |
| 2130 | 2109 | ||
| @@ -2180,7 +2159,7 @@ static int edge_write_room(struct tty_struct *tty) | |||
| 2180 | return 0; | 2159 | return 0; |
| 2181 | 2160 | ||
| 2182 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2161 | spin_lock_irqsave(&edge_port->ep_lock, flags); |
| 2183 | room = edge_buf_space_avail(edge_port->ep_out_buf); | 2162 | room = kfifo_avail(&edge_port->write_fifo); |
| 2184 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | 2163 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); |
| 2185 | 2164 | ||
| 2186 | dbg("%s - returns %d", __func__, room); | 2165 | dbg("%s - returns %d", __func__, room); |
| @@ -2202,7 +2181,7 @@ static int edge_chars_in_buffer(struct tty_struct *tty) | |||
| 2202 | return 0; | 2181 | return 0; |
| 2203 | 2182 | ||
| 2204 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2183 | spin_lock_irqsave(&edge_port->ep_lock, flags); |
| 2205 | chars = edge_buf_data_avail(edge_port->ep_out_buf); | 2184 | chars = kfifo_len(&edge_port->write_fifo); |
| 2206 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | 2185 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); |
| 2207 | 2186 | ||
| 2208 | dbg("%s - returns %d", __func__, chars); | 2187 | dbg("%s - returns %d", __func__, chars); |
| @@ -2659,8 +2638,8 @@ static int edge_startup(struct usb_serial *serial) | |||
| 2659 | goto cleanup; | 2638 | goto cleanup; |
| 2660 | } | 2639 | } |
| 2661 | spin_lock_init(&edge_port->ep_lock); | 2640 | spin_lock_init(&edge_port->ep_lock); |
| 2662 | edge_port->ep_out_buf = edge_buf_alloc(EDGE_OUT_BUF_SIZE); | 2641 | if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, |
| 2663 | if (edge_port->ep_out_buf == NULL) { | 2642 | GFP_KERNEL)) { |
| 2664 | dev_err(&serial->dev->dev, "%s - Out of memory\n", | 2643 | dev_err(&serial->dev->dev, "%s - Out of memory\n", |
| 2665 | __func__); | 2644 | __func__); |
| 2666 | kfree(edge_port); | 2645 | kfree(edge_port); |
| @@ -2677,7 +2656,7 @@ static int edge_startup(struct usb_serial *serial) | |||
| 2677 | cleanup: | 2656 | cleanup: |
| 2678 | for (--i; i >= 0; --i) { | 2657 | for (--i; i >= 0; --i) { |
| 2679 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2658 | edge_port = usb_get_serial_port_data(serial->port[i]); |
| 2680 | edge_buf_free(edge_port->ep_out_buf); | 2659 | kfifo_free(&edge_port->write_fifo); |
| 2681 | kfree(edge_port); | 2660 | kfree(edge_port); |
| 2682 | usb_set_serial_port_data(serial->port[i], NULL); | 2661 | usb_set_serial_port_data(serial->port[i], NULL); |
| 2683 | } | 2662 | } |
| @@ -2708,7 +2687,7 @@ static void edge_release(struct usb_serial *serial) | |||
| 2708 | 2687 | ||
| 2709 | for (i = 0; i < serial->num_ports; ++i) { | 2688 | for (i = 0; i < serial->num_ports; ++i) { |
| 2710 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2689 | edge_port = usb_get_serial_port_data(serial->port[i]); |
| 2711 | edge_buf_free(edge_port->ep_out_buf); | 2690 | kfifo_free(&edge_port->write_fifo); |
| 2712 | kfree(edge_port); | 2691 | kfree(edge_port); |
| 2713 | } | 2692 | } |
| 2714 | kfree(usb_get_serial_data(serial)); | 2693 | kfree(usb_get_serial_data(serial)); |
| @@ -2758,182 +2737,6 @@ static int edge_remove_sysfs_attrs(struct usb_serial_port *port) | |||
| 2758 | } | 2737 | } |
| 2759 | 2738 | ||
| 2760 | 2739 | ||
| 2761 | /* Circular Buffer */ | ||
| 2762 | |||
| 2763 | /* | ||
| 2764 | * edge_buf_alloc | ||
| 2765 | * | ||
| 2766 | * Allocate a circular buffer and all associated memory. | ||
| 2767 | */ | ||
| 2768 | |||
| 2769 | static struct edge_buf *edge_buf_alloc(unsigned int size) | ||
| 2770 | { | ||
| 2771 | struct edge_buf *eb; | ||
| 2772 | |||
| 2773 | |||
| 2774 | if (size == 0) | ||
| 2775 | return NULL; | ||
| 2776 | |||
| 2777 | eb = kmalloc(sizeof(struct edge_buf), GFP_KERNEL); | ||
| 2778 | if (eb == NULL) | ||
| 2779 | return NULL; | ||
| 2780 | |||
| 2781 | eb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
| 2782 | if (eb->buf_buf == NULL) { | ||
| 2783 | kfree(eb); | ||
| 2784 | return NULL; | ||
| 2785 | } | ||
| 2786 | |||
| 2787 | eb->buf_size = size; | ||
| 2788 | eb->buf_get = eb->buf_put = eb->buf_buf; | ||
| 2789 | |||
| 2790 | return eb; | ||
| 2791 | } | ||
| 2792 | |||
| 2793 | |||
| 2794 | /* | ||
| 2795 | * edge_buf_free | ||
| 2796 | * | ||
| 2797 | * Free the buffer and all associated memory. | ||
| 2798 | */ | ||
| 2799 | |||
| 2800 | static void edge_buf_free(struct edge_buf *eb) | ||
| 2801 | { | ||
| 2802 | if (eb) { | ||
| 2803 | kfree(eb->buf_buf); | ||
| 2804 | kfree(eb); | ||
| 2805 | } | ||
| 2806 | } | ||
| 2807 | |||
| 2808 | |||
| 2809 | /* | ||
| 2810 | * edge_buf_clear | ||
| 2811 | * | ||
| 2812 | * Clear out all data in the circular buffer. | ||
| 2813 | */ | ||
| 2814 | |||
| 2815 | static void edge_buf_clear(struct edge_buf *eb) | ||
| 2816 | { | ||
| 2817 | if (eb != NULL) | ||
| 2818 | eb->buf_get = eb->buf_put; | ||
| 2819 | /* equivalent to a get of all data available */ | ||
| 2820 | } | ||
| 2821 | |||
| 2822 | |||
| 2823 | /* | ||
| 2824 | * edge_buf_data_avail | ||
| 2825 | * | ||
| 2826 | * Return the number of bytes of data available in the circular | ||
| 2827 | * buffer. | ||
| 2828 | */ | ||
| 2829 | |||
| 2830 | static unsigned int edge_buf_data_avail(struct edge_buf *eb) | ||
| 2831 | { | ||
| 2832 | if (eb == NULL) | ||
| 2833 | return 0; | ||
| 2834 | return ((eb->buf_size + eb->buf_put - eb->buf_get) % eb->buf_size); | ||
| 2835 | } | ||
| 2836 | |||
| 2837 | |||
| 2838 | /* | ||
| 2839 | * edge_buf_space_avail | ||
| 2840 | * | ||
| 2841 | * Return the number of bytes of space available in the circular | ||
| 2842 | * buffer. | ||
| 2843 | */ | ||
| 2844 | |||
| 2845 | static unsigned int edge_buf_space_avail(struct edge_buf *eb) | ||
| 2846 | { | ||
| 2847 | if (eb == NULL) | ||
| 2848 | return 0; | ||
| 2849 | return ((eb->buf_size + eb->buf_get - eb->buf_put - 1) % eb->buf_size); | ||
| 2850 | } | ||
| 2851 | |||
| 2852 | |||
| 2853 | /* | ||
| 2854 | * edge_buf_put | ||
| 2855 | * | ||
| 2856 | * Copy data data from a user buffer and put it into the circular buffer. | ||
| 2857 | * Restrict to the amount of space available. | ||
| 2858 | * | ||
| 2859 | * Return the number of bytes copied. | ||
| 2860 | */ | ||
| 2861 | |||
| 2862 | static unsigned int edge_buf_put(struct edge_buf *eb, const char *buf, | ||
| 2863 | unsigned int count) | ||
| 2864 | { | ||
| 2865 | unsigned int len; | ||
| 2866 | |||
| 2867 | |||
| 2868 | if (eb == NULL) | ||
| 2869 | return 0; | ||
| 2870 | |||
| 2871 | len = edge_buf_space_avail(eb); | ||
| 2872 | if (count > len) | ||
| 2873 | count = len; | ||
| 2874 | |||
| 2875 | if (count == 0) | ||
| 2876 | return 0; | ||
| 2877 | |||
| 2878 | len = eb->buf_buf + eb->buf_size - eb->buf_put; | ||
| 2879 | if (count > len) { | ||
| 2880 | memcpy(eb->buf_put, buf, len); | ||
| 2881 | memcpy(eb->buf_buf, buf+len, count - len); | ||
| 2882 | eb->buf_put = eb->buf_buf + count - len; | ||
| 2883 | } else { | ||
| 2884 | memcpy(eb->buf_put, buf, count); | ||
| 2885 | if (count < len) | ||
| 2886 | eb->buf_put += count; | ||
| 2887 | else /* count == len */ | ||
| 2888 | eb->buf_put = eb->buf_buf; | ||
| 2889 | } | ||
| 2890 | |||
| 2891 | return count; | ||
| 2892 | } | ||
| 2893 | |||
| 2894 | |||
| 2895 | /* | ||
| 2896 | * edge_buf_get | ||
| 2897 | * | ||
| 2898 | * Get data from the circular buffer and copy to the given buffer. | ||
| 2899 | * Restrict to the amount of data available. | ||
| 2900 | * | ||
| 2901 | * Return the number of bytes copied. | ||
| 2902 | */ | ||
| 2903 | |||
| 2904 | static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, | ||
| 2905 | unsigned int count) | ||
| 2906 | { | ||
| 2907 | unsigned int len; | ||
| 2908 | |||
| 2909 | |||
| 2910 | if (eb == NULL) | ||
| 2911 | return 0; | ||
| 2912 | |||
| 2913 | len = edge_buf_data_avail(eb); | ||
| 2914 | if (count > len) | ||
| 2915 | count = len; | ||
| 2916 | |||
| 2917 | if (count == 0) | ||
| 2918 | return 0; | ||
| 2919 | |||
| 2920 | len = eb->buf_buf + eb->buf_size - eb->buf_get; | ||
| 2921 | if (count > len) { | ||
| 2922 | memcpy(buf, eb->buf_get, len); | ||
| 2923 | memcpy(buf+len, eb->buf_buf, count - len); | ||
| 2924 | eb->buf_get = eb->buf_buf + count - len; | ||
| 2925 | } else { | ||
| 2926 | memcpy(buf, eb->buf_get, count); | ||
| 2927 | if (count < len) | ||
| 2928 | eb->buf_get += count; | ||
| 2929 | else /* count == len */ | ||
| 2930 | eb->buf_get = eb->buf_buf; | ||
| 2931 | } | ||
| 2932 | |||
| 2933 | return count; | ||
| 2934 | } | ||
| 2935 | |||
| 2936 | |||
| 2937 | static struct usb_serial_driver edgeport_1port_device = { | 2740 | static struct usb_serial_driver edgeport_1port_device = { |
| 2938 | .driver = { | 2741 | .driver = { |
| 2939 | .owner = THIS_MODULE, | 2742 | .owner = THIS_MODULE, |
