aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/oti6858.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2010-05-16 14:33:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:49 -0400
commite3c1803f8b33fb97005202fa3645501ebb946d93 (patch)
tree1e91d0181ab866413fccb9503f5949b0188048fe /drivers/usb/serial/oti6858.c
parent117fb8d086cfc6e51c729fe5533bb83cb55c150a (diff)
USB: oti6858: use kfifo to implement write buffering
Kill custom fifo implementation. Use private write fifo to minimise changes to lock handling. 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/serial/oti6858.c')
-rw-r--r--drivers/usb/serial/oti6858.c218
1 files changed, 17 insertions, 201 deletions
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 525d8523df95..a65be37bf129 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,17 +76,7 @@ static struct usb_driver oti6858_driver = {
75 76
76static int debug; 77static int debug;
77 78
78 79#define OTI6858_FIFO_SIZE 1024
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 80
90/* requests */ 81/* requests */
91#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00) 82#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
@@ -161,18 +152,6 @@ static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
161static int oti6858_startup(struct usb_serial *serial); 152static int oti6858_startup(struct usb_serial *serial);
162static void oti6858_release(struct usb_serial *serial); 153static void oti6858_release(struct usb_serial *serial);
163 154
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 */ 155/* device info */
177static struct usb_serial_driver oti6858_device = { 156static struct usb_serial_driver oti6858_device = {
178 .driver = { 157 .driver = {
@@ -201,7 +180,7 @@ static struct usb_serial_driver oti6858_device = {
201struct oti6858_private { 180struct oti6858_private {
202 spinlock_t lock; 181 spinlock_t lock;
203 182
204 struct oti6858_buf *buf; 183 struct kfifo write_fifo;
205 struct oti6858_control_pkt status; 184 struct oti6858_control_pkt status;
206 185
207 struct { 186 struct {
@@ -315,7 +294,7 @@ static void send_data(struct work_struct *work)
315 } 294 }
316 priv->flags.write_urb_in_use = 1; 295 priv->flags.write_urb_in_use = 1;
317 296
318 count = oti6858_buf_data_avail(priv->buf); 297 count = kfifo_len(&priv->write_fifo);
319 spin_unlock_irqrestore(&priv->lock, flags); 298 spin_unlock_irqrestore(&priv->lock, flags);
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;
@@ -350,10 +329,9 @@ static 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(&priv->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, &priv->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,8 +354,8 @@ 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); 357 if (kfifo_alloc(&priv->write_fifo, OTI6858_FIFO_SIZE,
380 if (priv->buf == NULL) { 358 GFP_KERNEL)) {
381 kfree(priv); 359 kfree(priv);
382 break; 360 break;
383 } 361 }
@@ -397,7 +375,7 @@ static int oti6858_startup(struct usb_serial *serial)
397 375
398 for (--i; i >= 0; --i) { 376 for (--i; i >= 0; --i) {
399 priv = usb_get_serial_port_data(serial->port[i]); 377 priv = usb_get_serial_port_data(serial->port[i]);
400 oti6858_buf_free(priv->buf); 378 kfifo_free(&priv->write_fifo);
401 kfree(priv); 379 kfree(priv);
402 usb_set_serial_port_data(serial->port[i], NULL); 380 usb_set_serial_port_data(serial->port[i], NULL);
403 } 381 }
@@ -408,16 +386,13 @@ static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
408 const unsigned char *buf, int count) 386 const unsigned char *buf, int count)
409{ 387{
410 struct oti6858_private *priv = usb_get_serial_port_data(port); 388 struct oti6858_private *priv = usb_get_serial_port_data(port);
411 unsigned long flags;
412 389
413 dbg("%s(port = %d, count = %d)", __func__, port->number, count); 390 dbg("%s(port = %d, count = %d)", __func__, port->number, count);
414 391
415 if (!count) 392 if (!count)
416 return count; 393 return count;
417 394
418 spin_lock_irqsave(&priv->lock, flags); 395 count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock);
419 count = oti6858_buf_put(priv->buf, buf, count);
420 spin_unlock_irqrestore(&priv->lock, flags);
421 396
422 return count; 397 return count;
423} 398}
@@ -432,7 +407,7 @@ static int oti6858_write_room(struct tty_struct *tty)
432 dbg("%s(port = %d)", __func__, port->number); 407 dbg("%s(port = %d)", __func__, port->number);
433 408
434 spin_lock_irqsave(&priv->lock, flags); 409 spin_lock_irqsave(&priv->lock, flags);
435 room = oti6858_buf_space_avail(priv->buf); 410 room = kfifo_avail(&priv->write_fifo);
436 spin_unlock_irqrestore(&priv->lock, flags); 411 spin_unlock_irqrestore(&priv->lock, flags);
437 412
438 return room; 413 return room;
@@ -448,7 +423,7 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty)
448 dbg("%s(port = %d)", __func__, port->number); 423 dbg("%s(port = %d)", __func__, port->number);
449 424
450 spin_lock_irqsave(&priv->lock, flags); 425 spin_lock_irqsave(&priv->lock, flags);
451 chars = oti6858_buf_data_avail(priv->buf); 426 chars = kfifo_len(&priv->write_fifo);
452 spin_unlock_irqrestore(&priv->lock, flags); 427 spin_unlock_irqrestore(&priv->lock, flags);
453 428
454 return chars; 429 return chars;
@@ -642,7 +617,7 @@ static void oti6858_close(struct usb_serial_port *port)
642 617
643 spin_lock_irqsave(&priv->lock, flags); 618 spin_lock_irqsave(&priv->lock, flags);
644 /* clear out any remaining data in the buffer */ 619 /* clear out any remaining data in the buffer */
645 oti6858_buf_clear(priv->buf); 620 kfifo_reset_out(&priv->write_fifo);
646 spin_unlock_irqrestore(&priv->lock, flags); 621 spin_unlock_irqrestore(&priv->lock, flags);
647 622
648 dbg("%s(): after buf_clear()", __func__); 623 dbg("%s(): after buf_clear()", __func__);
@@ -793,7 +768,7 @@ static void oti6858_release(struct usb_serial *serial)
793 for (i = 0; i < serial->num_ports; ++i) { 768 for (i = 0; i < serial->num_ports; ++i) {
794 priv = usb_get_serial_port_data(serial->port[i]); 769 priv = usb_get_serial_port_data(serial->port[i]);
795 if (priv) { 770 if (priv) {
796 oti6858_buf_free(priv->buf); 771 kfifo_free(&priv->write_fifo);
797 kfree(priv); 772 kfree(priv);
798 } 773 }
799 } 774 }
@@ -892,7 +867,7 @@ static void oti6858_read_int_callback(struct urb *urb)
892 867
893 spin_lock_irqsave(&priv->lock, flags); 868 spin_lock_irqsave(&priv->lock, flags);
894 if (priv->flags.write_urb_in_use == 0 869 if (priv->flags.write_urb_in_use == 0
895 && oti6858_buf_data_avail(priv->buf) != 0) { 870 && kfifo_len(&priv->write_fifo) != 0) {
896 schedule_delayed_work(&priv->delayed_write_work, 0); 871 schedule_delayed_work(&priv->delayed_write_work, 0);
897 resubmit = 0; 872 resubmit = 0;
898 } 873 }
@@ -1014,165 +989,6 @@ static void oti6858_write_bulk_callback(struct urb *urb)
1014 } 989 }
1015} 990}
1016 991
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 */ 992/* module description and (de)initialization */
1177 993
1178static int __init oti6858_init(void) 994static int __init oti6858_init(void)