aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/oti6858.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/oti6858.c')
-rw-r--r--drivers/usb/serial/oti6858.c254
1 files changed, 29 insertions, 225 deletions
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index deeacdea05db..e199b0f4f99c 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -51,12 +51,13 @@
51#include <linux/usb.h> 51#include <linux/usb.h>
52#include <linux/usb/serial.h> 52#include <linux/usb/serial.h>
53#include <linux/uaccess.h> 53#include <linux/uaccess.h>
54#include <linux/kfifo.h>
54#include "oti6858.h" 55#include "oti6858.h"
55 56
56#define OTI6858_DESCRIPTION \ 57#define OTI6858_DESCRIPTION \
57 "Ours Technology Inc. OTi-6858 USB to serial adapter driver" 58 "Ours Technology Inc. OTi-6858 USB to serial adapter driver"
58#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>" 59#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
59#define OTI6858_VERSION "0.1" 60#define OTI6858_VERSION "0.2"
60 61
61static const struct usb_device_id id_table[] = { 62static const struct usb_device_id id_table[] = {
62 { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) }, 63 { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
@@ -75,18 +76,6 @@ static struct usb_driver oti6858_driver = {
75 76
76static int debug; 77static int debug;
77 78
78
79/* buffering code, copied from pl2303 driver */
80#define PL2303_BUF_SIZE 1024
81#define PL2303_TMP_BUF_SIZE 1024
82
83struct oti6858_buf {
84 unsigned int buf_size;
85 char *buf_buf;
86 char *buf_get;
87 char *buf_put;
88};
89
90/* requests */ 79/* requests */
91#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00) 80#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
92#define OTI6858_REQ_T_GET_STATUS 0x01 81#define OTI6858_REQ_T_GET_STATUS 0x01
@@ -161,18 +150,6 @@ static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
161static int oti6858_startup(struct usb_serial *serial); 150static int oti6858_startup(struct usb_serial *serial);
162static void oti6858_release(struct usb_serial *serial); 151static void oti6858_release(struct usb_serial *serial);
163 152
164/* functions operating on buffers */
165static struct oti6858_buf *oti6858_buf_alloc(unsigned int size);
166static void oti6858_buf_free(struct oti6858_buf *pb);
167static void oti6858_buf_clear(struct oti6858_buf *pb);
168static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb);
169static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb);
170static unsigned int oti6858_buf_put(struct oti6858_buf *pb, const char *buf,
171 unsigned int count);
172static unsigned int oti6858_buf_get(struct oti6858_buf *pb, char *buf,
173 unsigned int count);
174
175
176/* device info */ 153/* device info */
177static struct usb_serial_driver oti6858_device = { 154static struct usb_serial_driver oti6858_device = {
178 .driver = { 155 .driver = {
@@ -201,7 +178,6 @@ static struct usb_serial_driver oti6858_device = {
201struct oti6858_private { 178struct oti6858_private {
202 spinlock_t lock; 179 spinlock_t lock;
203 180
204 struct oti6858_buf *buf;
205 struct oti6858_control_pkt status; 181 struct oti6858_control_pkt status;
206 182
207 struct { 183 struct {
@@ -295,7 +271,7 @@ static void setup_line(struct work_struct *work)
295 } 271 }
296} 272}
297 273
298void send_data(struct work_struct *work) 274static void send_data(struct work_struct *work)
299{ 275{
300 struct oti6858_private *priv = container_of(work, 276 struct oti6858_private *priv = container_of(work,
301 struct oti6858_private, delayed_write_work.work); 277 struct oti6858_private, delayed_write_work.work);
@@ -314,9 +290,12 @@ void send_data(struct work_struct *work)
314 return; 290 return;
315 } 291 }
316 priv->flags.write_urb_in_use = 1; 292 priv->flags.write_urb_in_use = 1;
317
318 count = oti6858_buf_data_avail(priv->buf);
319 spin_unlock_irqrestore(&priv->lock, flags); 293 spin_unlock_irqrestore(&priv->lock, flags);
294
295 spin_lock_irqsave(&port->lock, flags);
296 count = kfifo_len(&port->write_fifo);
297 spin_unlock_irqrestore(&port->lock, flags);
298
320 if (count > port->bulk_out_size) 299 if (count > port->bulk_out_size)
321 count = port->bulk_out_size; 300 count = port->bulk_out_size;
322 301
@@ -350,10 +329,9 @@ void send_data(struct work_struct *work)
350 return; 329 return;
351 } 330 }
352 331
353 spin_lock_irqsave(&priv->lock, flags); 332 count = kfifo_out_locked(&port->write_fifo,
354 oti6858_buf_get(priv->buf, port->write_urb->transfer_buffer, count); 333 port->write_urb->transfer_buffer,
355 spin_unlock_irqrestore(&priv->lock, flags); 334 count, &port->lock);
356
357 port->write_urb->transfer_buffer_length = count; 335 port->write_urb->transfer_buffer_length = count;
358 port->write_urb->dev = port->serial->dev; 336 port->write_urb->dev = port->serial->dev;
359 result = usb_submit_urb(port->write_urb, GFP_NOIO); 337 result = usb_submit_urb(port->write_urb, GFP_NOIO);
@@ -376,11 +354,6 @@ static int oti6858_startup(struct usb_serial *serial)
376 priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); 354 priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL);
377 if (!priv) 355 if (!priv)
378 break; 356 break;
379 priv->buf = oti6858_buf_alloc(PL2303_BUF_SIZE);
380 if (priv->buf == NULL) {
381 kfree(priv);
382 break;
383 }
384 357
385 spin_lock_init(&priv->lock); 358 spin_lock_init(&priv->lock);
386 init_waitqueue_head(&priv->intr_wait); 359 init_waitqueue_head(&priv->intr_wait);
@@ -397,7 +370,6 @@ static int oti6858_startup(struct usb_serial *serial)
397 370
398 for (--i; i >= 0; --i) { 371 for (--i; i >= 0; --i) {
399 priv = usb_get_serial_port_data(serial->port[i]); 372 priv = usb_get_serial_port_data(serial->port[i]);
400 oti6858_buf_free(priv->buf);
401 kfree(priv); 373 kfree(priv);
402 usb_set_serial_port_data(serial->port[i], NULL); 374 usb_set_serial_port_data(serial->port[i], NULL);
403 } 375 }
@@ -407,17 +379,12 @@ static int oti6858_startup(struct usb_serial *serial)
407static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, 379static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
408 const unsigned char *buf, int count) 380 const unsigned char *buf, int count)
409{ 381{
410 struct oti6858_private *priv = usb_get_serial_port_data(port);
411 unsigned long flags;
412
413 dbg("%s(port = %d, count = %d)", __func__, port->number, count); 382 dbg("%s(port = %d, count = %d)", __func__, port->number, count);
414 383
415 if (!count) 384 if (!count)
416 return count; 385 return count;
417 386
418 spin_lock_irqsave(&priv->lock, flags); 387 count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
419 count = oti6858_buf_put(priv->buf, buf, count);
420 spin_unlock_irqrestore(&priv->lock, flags);
421 388
422 return count; 389 return count;
423} 390}
@@ -425,15 +392,14 @@ static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
425static int oti6858_write_room(struct tty_struct *tty) 392static int oti6858_write_room(struct tty_struct *tty)
426{ 393{
427 struct usb_serial_port *port = tty->driver_data; 394 struct usb_serial_port *port = tty->driver_data;
428 struct oti6858_private *priv = usb_get_serial_port_data(port);
429 int room = 0; 395 int room = 0;
430 unsigned long flags; 396 unsigned long flags;
431 397
432 dbg("%s(port = %d)", __func__, port->number); 398 dbg("%s(port = %d)", __func__, port->number);
433 399
434 spin_lock_irqsave(&priv->lock, flags); 400 spin_lock_irqsave(&port->lock, flags);
435 room = oti6858_buf_space_avail(priv->buf); 401 room = kfifo_avail(&port->write_fifo);
436 spin_unlock_irqrestore(&priv->lock, flags); 402 spin_unlock_irqrestore(&port->lock, flags);
437 403
438 return room; 404 return room;
439} 405}
@@ -441,15 +407,14 @@ static int oti6858_write_room(struct tty_struct *tty)
441static int oti6858_chars_in_buffer(struct tty_struct *tty) 407static int oti6858_chars_in_buffer(struct tty_struct *tty)
442{ 408{
443 struct usb_serial_port *port = tty->driver_data; 409 struct usb_serial_port *port = tty->driver_data;
444 struct oti6858_private *priv = usb_get_serial_port_data(port);
445 int chars = 0; 410 int chars = 0;
446 unsigned long flags; 411 unsigned long flags;
447 412
448 dbg("%s(port = %d)", __func__, port->number); 413 dbg("%s(port = %d)", __func__, port->number);
449 414
450 spin_lock_irqsave(&priv->lock, flags); 415 spin_lock_irqsave(&port->lock, flags);
451 chars = oti6858_buf_data_avail(priv->buf); 416 chars = kfifo_len(&port->write_fifo);
452 spin_unlock_irqrestore(&priv->lock, flags); 417 spin_unlock_irqrestore(&port->lock, flags);
453 418
454 return chars; 419 return chars;
455} 420}
@@ -640,10 +605,10 @@ static void oti6858_close(struct usb_serial_port *port)
640 605
641 dbg("%s(port = %d)", __func__, port->number); 606 dbg("%s(port = %d)", __func__, port->number);
642 607
643 spin_lock_irqsave(&priv->lock, flags); 608 spin_lock_irqsave(&port->lock, flags);
644 /* clear out any remaining data in the buffer */ 609 /* clear out any remaining data in the buffer */
645 oti6858_buf_clear(priv->buf); 610 kfifo_reset_out(&port->write_fifo);
646 spin_unlock_irqrestore(&priv->lock, flags); 611 spin_unlock_irqrestore(&port->lock, flags);
647 612
648 dbg("%s(): after buf_clear()", __func__); 613 dbg("%s(): after buf_clear()", __func__);
649 614
@@ -785,18 +750,12 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
785 750
786static void oti6858_release(struct usb_serial *serial) 751static void oti6858_release(struct usb_serial *serial)
787{ 752{
788 struct oti6858_private *priv;
789 int i; 753 int i;
790 754
791 dbg("%s()", __func__); 755 dbg("%s()", __func__);
792 756
793 for (i = 0; i < serial->num_ports; ++i) { 757 for (i = 0; i < serial->num_ports; ++i)
794 priv = usb_get_serial_port_data(serial->port[i]); 758 kfree(usb_get_serial_port_data(serial->port[i]));
795 if (priv) {
796 oti6858_buf_free(priv->buf);
797 kfree(priv);
798 }
799 }
800} 759}
801 760
802static void oti6858_read_int_callback(struct urb *urb) 761static void oti6858_read_int_callback(struct urb *urb)
@@ -889,10 +848,14 @@ static void oti6858_read_int_callback(struct urb *urb)
889 } 848 }
890 } else if (!transient) { 849 } else if (!transient) {
891 unsigned long flags; 850 unsigned long flags;
851 int count;
852
853 spin_lock_irqsave(&port->lock, flags);
854 count = kfifo_len(&port->write_fifo);
855 spin_unlock_irqrestore(&port->lock, flags);
892 856
893 spin_lock_irqsave(&priv->lock, flags); 857 spin_lock_irqsave(&priv->lock, flags);
894 if (priv->flags.write_urb_in_use == 0 858 if (priv->flags.write_urb_in_use == 0 && count != 0) {
895 && oti6858_buf_data_avail(priv->buf) != 0) {
896 schedule_delayed_work(&priv->delayed_write_work, 0); 859 schedule_delayed_work(&priv->delayed_write_work, 0);
897 resubmit = 0; 860 resubmit = 0;
898 } 861 }
@@ -1014,165 +977,6 @@ static void oti6858_write_bulk_callback(struct urb *urb)
1014 } 977 }
1015} 978}
1016 979
1017
1018/*
1019 * oti6858_buf_alloc
1020 *
1021 * Allocate a circular buffer and all associated memory.
1022 */
1023static struct oti6858_buf *oti6858_buf_alloc(unsigned int size)
1024{
1025 struct oti6858_buf *pb;
1026
1027 if (size == 0)
1028 return NULL;
1029
1030 pb = kmalloc(sizeof(struct oti6858_buf), GFP_KERNEL);
1031 if (pb == NULL)
1032 return NULL;
1033
1034 pb->buf_buf = kmalloc(size, GFP_KERNEL);
1035 if (pb->buf_buf == NULL) {
1036 kfree(pb);
1037 return NULL;
1038 }
1039
1040 pb->buf_size = size;
1041 pb->buf_get = pb->buf_put = pb->buf_buf;
1042
1043 return pb;
1044}
1045
1046/*
1047 * oti6858_buf_free
1048 *
1049 * Free the buffer and all associated memory.
1050 */
1051static void oti6858_buf_free(struct oti6858_buf *pb)
1052{
1053 if (pb) {
1054 kfree(pb->buf_buf);
1055 kfree(pb);
1056 }
1057}
1058
1059/*
1060 * oti6858_buf_clear
1061 *
1062 * Clear out all data in the circular buffer.
1063 */
1064static void oti6858_buf_clear(struct oti6858_buf *pb)
1065{
1066 if (pb != NULL) {
1067 /* equivalent to a get of all data available */
1068 pb->buf_get = pb->buf_put;
1069 }
1070}
1071
1072/*
1073 * oti6858_buf_data_avail
1074 *
1075 * Return the number of bytes of data available in the circular
1076 * buffer.
1077 */
1078static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb)
1079{
1080 if (pb == NULL)
1081 return 0;
1082 return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
1083}
1084
1085/*
1086 * oti6858_buf_space_avail
1087 *
1088 * Return the number of bytes of space available in the circular
1089 * buffer.
1090 */
1091static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb)
1092{
1093 if (pb == NULL)
1094 return 0;
1095 return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
1096}
1097
1098/*
1099 * oti6858_buf_put
1100 *
1101 * Copy data data from a user buffer and put it into the circular buffer.
1102 * Restrict to the amount of space available.
1103 *
1104 * Return the number of bytes copied.
1105 */
1106static unsigned int oti6858_buf_put(struct oti6858_buf *pb, const char *buf,
1107 unsigned int count)
1108{
1109 unsigned int len;
1110
1111 if (pb == NULL)
1112 return 0;
1113
1114 len = oti6858_buf_space_avail(pb);
1115 if (count > len)
1116 count = len;
1117
1118 if (count == 0)
1119 return 0;
1120
1121 len = pb->buf_buf + pb->buf_size - pb->buf_put;
1122 if (count > len) {
1123 memcpy(pb->buf_put, buf, len);
1124 memcpy(pb->buf_buf, buf+len, count - len);
1125 pb->buf_put = pb->buf_buf + count - len;
1126 } else {
1127 memcpy(pb->buf_put, buf, count);
1128 if (count < len)
1129 pb->buf_put += count;
1130 else /* count == len */
1131 pb->buf_put = pb->buf_buf;
1132 }
1133
1134 return count;
1135}
1136
1137/*
1138 * oti6858_buf_get
1139 *
1140 * Get data from the circular buffer and copy to the given buffer.
1141 * Restrict to the amount of data available.
1142 *
1143 * Return the number of bytes copied.
1144 */
1145static unsigned int oti6858_buf_get(struct oti6858_buf *pb, char *buf,
1146 unsigned int count)
1147{
1148 unsigned int len;
1149
1150 if (pb == NULL)
1151 return 0;
1152
1153 len = oti6858_buf_data_avail(pb);
1154 if (count > len)
1155 count = len;
1156
1157 if (count == 0)
1158 return 0;
1159
1160 len = pb->buf_buf + pb->buf_size - pb->buf_get;
1161 if (count > len) {
1162 memcpy(buf, pb->buf_get, len);
1163 memcpy(buf+len, pb->buf_buf, count - len);
1164 pb->buf_get = pb->buf_buf + count - len;
1165 } else {
1166 memcpy(buf, pb->buf_get, count);
1167 if (count < len)
1168 pb->buf_get += count;
1169 else /* count == len */
1170 pb->buf_get = pb->buf_buf;
1171 }
1172
1173 return count;
1174}
1175
1176/* module description and (de)initialization */ 980/* module description and (de)initialization */
1177 981
1178static int __init oti6858_init(void) 982static int __init oti6858_init(void)