aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/pl2303.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r--drivers/usb/serial/pl2303.c432
1 files changed, 35 insertions, 397 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 73d5f346d3e0..6b6001822279 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -40,16 +40,6 @@ static int debug;
40 40
41#define PL2303_CLOSING_WAIT (30*HZ) 41#define PL2303_CLOSING_WAIT (30*HZ)
42 42
43#define PL2303_BUF_SIZE 1024
44#define PL2303_TMP_BUF_SIZE 1024
45
46struct pl2303_buf {
47 unsigned int buf_size;
48 char *buf_buf;
49 char *buf_get;
50 char *buf_put;
51};
52
53static const struct usb_device_id id_table[] = { 43static const struct usb_device_id id_table[] = {
54 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) }, 44 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
55 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) }, 45 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
@@ -59,6 +49,7 @@ static const struct usb_device_id id_table[] = {
59 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) }, 49 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
60 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) }, 50 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
61 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, 51 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
52 { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
62 { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, 53 { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
63 { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, 54 { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
64 { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, 55 { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
@@ -97,6 +88,7 @@ static const struct usb_device_id id_table[] = {
97 { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, 88 { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
98 { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, 89 { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
99 { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, 90 { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
91 { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
100 { } /* Terminating entry */ 92 { } /* Terminating entry */
101}; 93};
102 94
@@ -155,173 +147,12 @@ enum pl2303_type {
155 147
156struct pl2303_private { 148struct pl2303_private {
157 spinlock_t lock; 149 spinlock_t lock;
158 struct pl2303_buf *buf;
159 int write_urb_in_use;
160 wait_queue_head_t delta_msr_wait; 150 wait_queue_head_t delta_msr_wait;
161 u8 line_control; 151 u8 line_control;
162 u8 line_status; 152 u8 line_status;
163 enum pl2303_type type; 153 enum pl2303_type type;
164}; 154};
165 155
166/*
167 * pl2303_buf_alloc
168 *
169 * Allocate a circular buffer and all associated memory.
170 */
171static struct pl2303_buf *pl2303_buf_alloc(unsigned int size)
172{
173 struct pl2303_buf *pb;
174
175 if (size == 0)
176 return NULL;
177
178 pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL);
179 if (pb == NULL)
180 return NULL;
181
182 pb->buf_buf = kmalloc(size, GFP_KERNEL);
183 if (pb->buf_buf == NULL) {
184 kfree(pb);
185 return NULL;
186 }
187
188 pb->buf_size = size;
189 pb->buf_get = pb->buf_put = pb->buf_buf;
190
191 return pb;
192}
193
194/*
195 * pl2303_buf_free
196 *
197 * Free the buffer and all associated memory.
198 */
199static void pl2303_buf_free(struct pl2303_buf *pb)
200{
201 if (pb) {
202 kfree(pb->buf_buf);
203 kfree(pb);
204 }
205}
206
207/*
208 * pl2303_buf_clear
209 *
210 * Clear out all data in the circular buffer.
211 */
212static void pl2303_buf_clear(struct pl2303_buf *pb)
213{
214 if (pb != NULL)
215 pb->buf_get = pb->buf_put;
216 /* equivalent to a get of all data available */
217}
218
219/*
220 * pl2303_buf_data_avail
221 *
222 * Return the number of bytes of data available in the circular
223 * buffer.
224 */
225static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb)
226{
227 if (pb == NULL)
228 return 0;
229
230 return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
231}
232
233/*
234 * pl2303_buf_space_avail
235 *
236 * Return the number of bytes of space available in the circular
237 * buffer.
238 */
239static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb)
240{
241 if (pb == NULL)
242 return 0;
243
244 return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
245}
246
247/*
248 * pl2303_buf_put
249 *
250 * Copy data data from a user buffer and put it into the circular buffer.
251 * Restrict to the amount of space available.
252 *
253 * Return the number of bytes copied.
254 */
255static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf,
256 unsigned int count)
257{
258 unsigned int len;
259
260 if (pb == NULL)
261 return 0;
262
263 len = pl2303_buf_space_avail(pb);
264 if (count > len)
265 count = len;
266
267 if (count == 0)
268 return 0;
269
270 len = pb->buf_buf + pb->buf_size - pb->buf_put;
271 if (count > len) {
272 memcpy(pb->buf_put, buf, len);
273 memcpy(pb->buf_buf, buf+len, count - len);
274 pb->buf_put = pb->buf_buf + count - len;
275 } else {
276 memcpy(pb->buf_put, buf, count);
277 if (count < len)
278 pb->buf_put += count;
279 else /* count == len */
280 pb->buf_put = pb->buf_buf;
281 }
282
283 return count;
284}
285
286/*
287 * pl2303_buf_get
288 *
289 * Get data from the circular buffer and copy to the given buffer.
290 * Restrict to the amount of data available.
291 *
292 * Return the number of bytes copied.
293 */
294static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf,
295 unsigned int count)
296{
297 unsigned int len;
298
299 if (pb == NULL)
300 return 0;
301
302 len = pl2303_buf_data_avail(pb);
303 if (count > len)
304 count = len;
305
306 if (count == 0)
307 return 0;
308
309 len = pb->buf_buf + pb->buf_size - pb->buf_get;
310 if (count > len) {
311 memcpy(buf, pb->buf_get, len);
312 memcpy(buf+len, pb->buf_buf, count - len);
313 pb->buf_get = pb->buf_buf + count - len;
314 } else {
315 memcpy(buf, pb->buf_get, count);
316 if (count < len)
317 pb->buf_get += count;
318 else /* count == len */
319 pb->buf_get = pb->buf_buf;
320 }
321
322 return count;
323}
324
325static int pl2303_vendor_read(__u16 value, __u16 index, 156static int pl2303_vendor_read(__u16 value, __u16 index,
326 struct usb_serial *serial, unsigned char *buf) 157 struct usb_serial *serial, unsigned char *buf)
327{ 158{
@@ -370,11 +201,6 @@ static int pl2303_startup(struct usb_serial *serial)
370 if (!priv) 201 if (!priv)
371 goto cleanup; 202 goto cleanup;
372 spin_lock_init(&priv->lock); 203 spin_lock_init(&priv->lock);
373 priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE);
374 if (priv->buf == NULL) {
375 kfree(priv);
376 goto cleanup;
377 }
378 init_waitqueue_head(&priv->delta_msr_wait); 204 init_waitqueue_head(&priv->delta_msr_wait);
379 priv->type = type; 205 priv->type = type;
380 usb_set_serial_port_data(serial->port[i], priv); 206 usb_set_serial_port_data(serial->port[i], priv);
@@ -402,7 +228,6 @@ cleanup:
402 kfree(buf); 228 kfree(buf);
403 for (--i; i >= 0; --i) { 229 for (--i; i >= 0; --i) {
404 priv = usb_get_serial_port_data(serial->port[i]); 230 priv = usb_get_serial_port_data(serial->port[i]);
405 pl2303_buf_free(priv->buf);
406 kfree(priv); 231 kfree(priv);
407 usb_set_serial_port_data(serial->port[i], NULL); 232 usb_set_serial_port_data(serial->port[i], NULL);
408 } 233 }
@@ -420,102 +245,6 @@ static int set_control_lines(struct usb_device *dev, u8 value)
420 return retval; 245 return retval;
421} 246}
422 247
423static void pl2303_send(struct usb_serial_port *port)
424{
425 int count, result;
426 struct pl2303_private *priv = usb_get_serial_port_data(port);
427 unsigned long flags;
428
429 dbg("%s - port %d", __func__, port->number);
430
431 spin_lock_irqsave(&priv->lock, flags);
432
433 if (priv->write_urb_in_use) {
434 spin_unlock_irqrestore(&priv->lock, flags);
435 return;
436 }
437
438 count = pl2303_buf_get(priv->buf, port->write_urb->transfer_buffer,
439 port->bulk_out_size);
440
441 if (count == 0) {
442 spin_unlock_irqrestore(&priv->lock, flags);
443 return;
444 }
445
446 priv->write_urb_in_use = 1;
447
448 spin_unlock_irqrestore(&priv->lock, flags);
449
450 usb_serial_debug_data(debug, &port->dev, __func__, count,
451 port->write_urb->transfer_buffer);
452
453 port->write_urb->transfer_buffer_length = count;
454 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
455 if (result) {
456 dev_err(&port->dev, "%s - failed submitting write urb,"
457 " error %d\n", __func__, result);
458 priv->write_urb_in_use = 0;
459 /* TODO: reschedule pl2303_send */
460 }
461
462 usb_serial_port_softint(port);
463}
464
465static int pl2303_write(struct tty_struct *tty, struct usb_serial_port *port,
466 const unsigned char *buf, int count)
467{
468 struct pl2303_private *priv = usb_get_serial_port_data(port);
469 unsigned long flags;
470
471 dbg("%s - port %d, %d bytes", __func__, port->number, count);
472
473 if (!count)
474 return count;
475
476 spin_lock_irqsave(&priv->lock, flags);
477 count = pl2303_buf_put(priv->buf, buf, count);
478 spin_unlock_irqrestore(&priv->lock, flags);
479
480 pl2303_send(port);
481
482 return count;
483}
484
485static int pl2303_write_room(struct tty_struct *tty)
486{
487 struct usb_serial_port *port = tty->driver_data;
488 struct pl2303_private *priv = usb_get_serial_port_data(port);
489 int room = 0;
490 unsigned long flags;
491
492 dbg("%s - port %d", __func__, port->number);
493
494 spin_lock_irqsave(&priv->lock, flags);
495 room = pl2303_buf_space_avail(priv->buf);
496 spin_unlock_irqrestore(&priv->lock, flags);
497
498 dbg("%s - returns %d", __func__, room);
499 return room;
500}
501
502static int pl2303_chars_in_buffer(struct tty_struct *tty)
503{
504 struct usb_serial_port *port = tty->driver_data;
505 struct pl2303_private *priv = usb_get_serial_port_data(port);
506 int chars = 0;
507 unsigned long flags;
508
509 dbg("%s - port %d", __func__, port->number);
510
511 spin_lock_irqsave(&priv->lock, flags);
512 chars = pl2303_buf_data_avail(priv->buf);
513 spin_unlock_irqrestore(&priv->lock, flags);
514
515 dbg("%s - returns %d", __func__, chars);
516 return chars;
517}
518
519static void pl2303_set_termios(struct tty_struct *tty, 248static void pl2303_set_termios(struct tty_struct *tty,
520 struct usb_serial_port *port, struct ktermios *old_termios) 249 struct usb_serial_port *port, struct ktermios *old_termios)
521{ 250{
@@ -727,22 +456,10 @@ static void pl2303_dtr_rts(struct usb_serial_port *port, int on)
727 456
728static void pl2303_close(struct usb_serial_port *port) 457static void pl2303_close(struct usb_serial_port *port)
729{ 458{
730 struct pl2303_private *priv = usb_get_serial_port_data(port);
731 unsigned long flags;
732
733 dbg("%s - port %d", __func__, port->number); 459 dbg("%s - port %d", __func__, port->number);
734 460
735 spin_lock_irqsave(&priv->lock, flags); 461 usb_serial_generic_close(port);
736 /* clear out any remaining data in the buffer */
737 pl2303_buf_clear(priv->buf);
738 spin_unlock_irqrestore(&priv->lock, flags);
739
740 /* shutdown our urbs */
741 dbg("%s - shutting down urbs", __func__);
742 usb_kill_urb(port->write_urb);
743 usb_kill_urb(port->read_urb);
744 usb_kill_urb(port->interrupt_in_urb); 462 usb_kill_urb(port->interrupt_in_urb);
745
746} 463}
747 464
748static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) 465static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
@@ -768,10 +485,8 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
768 pl2303_set_termios(tty, port, &tmp_termios); 485 pl2303_set_termios(tty, port, &tmp_termios);
769 486
770 dbg("%s - submitting read urb", __func__); 487 dbg("%s - submitting read urb", __func__);
771 result = usb_submit_urb(port->read_urb, GFP_KERNEL); 488 result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL);
772 if (result) { 489 if (result) {
773 dev_err(&port->dev, "%s - failed submitting read urb,"
774 " error %d\n", __func__, result);
775 pl2303_close(port); 490 pl2303_close(port);
776 return -EPROTO; 491 return -EPROTO;
777 } 492 }
@@ -951,10 +666,7 @@ static void pl2303_release(struct usb_serial *serial)
951 666
952 for (i = 0; i < serial->num_ports; ++i) { 667 for (i = 0; i < serial->num_ports; ++i) {
953 priv = usb_get_serial_port_data(serial->port[i]); 668 priv = usb_get_serial_port_data(serial->port[i]);
954 if (priv) { 669 kfree(priv);
955 pl2303_buf_free(priv->buf);
956 kfree(priv);
957 }
958 } 670 }
959} 671}
960 672
@@ -1035,13 +747,31 @@ exit:
1035 __func__, retval); 747 __func__, retval);
1036} 748}
1037 749
1038static void pl2303_push_data(struct tty_struct *tty, 750static void pl2303_process_read_urb(struct urb *urb)
1039 struct usb_serial_port *port, struct urb *urb,
1040 u8 line_status)
1041{ 751{
752 struct usb_serial_port *port = urb->context;
753 struct pl2303_private *priv = usb_get_serial_port_data(port);
754 struct tty_struct *tty;
1042 unsigned char *data = urb->transfer_buffer; 755 unsigned char *data = urb->transfer_buffer;
1043 /* get tty_flag from status */
1044 char tty_flag = TTY_NORMAL; 756 char tty_flag = TTY_NORMAL;
757 unsigned long flags;
758 u8 line_status;
759 int i;
760
761 /* update line status */
762 spin_lock_irqsave(&priv->lock, flags);
763 line_status = priv->line_status;
764 priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
765 spin_unlock_irqrestore(&priv->lock, flags);
766 wake_up_interruptible(&priv->delta_msr_wait);
767
768 if (!urb->actual_length)
769 return;
770
771 tty = tty_port_tty_get(&port->port);
772 if (!tty)
773 return;
774
1045 /* break takes precedence over parity, */ 775 /* break takes precedence over parity, */
1046 /* which takes precedence over framing errors */ 776 /* which takes precedence over framing errors */
1047 if (line_status & UART_BREAK_ERROR) 777 if (line_status & UART_BREAK_ERROR)
@@ -1056,107 +786,17 @@ static void pl2303_push_data(struct tty_struct *tty,
1056 if (line_status & UART_OVERRUN_ERROR) 786 if (line_status & UART_OVERRUN_ERROR)
1057 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 787 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1058 788
1059 if (tty_flag == TTY_NORMAL && !(port->console && port->sysrq)) 789 if (port->port.console && port->sysrq) {
1060 tty_insert_flip_string(tty, data, urb->actual_length);
1061 else {
1062 int i;
1063 for (i = 0; i < urb->actual_length; ++i) 790 for (i = 0; i < urb->actual_length; ++i)
1064 if (!usb_serial_handle_sysrq_char(tty, port, data[i])) 791 if (!usb_serial_handle_sysrq_char(tty, port, data[i]))
1065 tty_insert_flip_char(tty, data[i], tty_flag); 792 tty_insert_flip_char(tty, data[i], tty_flag);
793 } else {
794 tty_insert_flip_string_fixed_flag(tty, data, tty_flag,
795 urb->actual_length);
1066 } 796 }
1067 tty_flip_buffer_push(tty);
1068}
1069
1070static void pl2303_read_bulk_callback(struct urb *urb)
1071{
1072 struct usb_serial_port *port = urb->context;
1073 struct pl2303_private *priv = usb_get_serial_port_data(port);
1074 struct tty_struct *tty;
1075 unsigned long flags;
1076 int result;
1077 int status = urb->status;
1078 u8 line_status;
1079
1080 dbg("%s - port %d", __func__, port->number);
1081
1082 if (status) {
1083 dbg("%s - urb status = %d", __func__, status);
1084 if (status == -EPROTO) {
1085 /* PL2303 mysteriously fails with -EPROTO reschedule
1086 * the read */
1087 dbg("%s - caught -EPROTO, resubmitting the urb",
1088 __func__);
1089 result = usb_submit_urb(urb, GFP_ATOMIC);
1090 if (result)
1091 dev_err(&urb->dev->dev, "%s - failed"
1092 " resubmitting read urb, error %d\n",
1093 __func__, result);
1094 return;
1095 }
1096 dbg("%s - unable to handle the error, exiting.", __func__);
1097 return;
1098 }
1099
1100 usb_serial_debug_data(debug, &port->dev, __func__,
1101 urb->actual_length, urb->transfer_buffer);
1102
1103 spin_lock_irqsave(&priv->lock, flags);
1104 line_status = priv->line_status;
1105 priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
1106 spin_unlock_irqrestore(&priv->lock, flags);
1107 wake_up_interruptible(&priv->delta_msr_wait);
1108 797
1109 tty = tty_port_tty_get(&port->port); 798 tty_flip_buffer_push(tty);
1110 if (tty && urb->actual_length) {
1111 pl2303_push_data(tty, port, urb, line_status);
1112 }
1113 tty_kref_put(tty); 799 tty_kref_put(tty);
1114 /* Schedule the next read _if_ we are still open */
1115 result = usb_submit_urb(urb, GFP_ATOMIC);
1116 if (result && result != -EPERM)
1117 dev_err(&urb->dev->dev, "%s - failed resubmitting"
1118 " read urb, error %d\n", __func__, result);
1119}
1120
1121static void pl2303_write_bulk_callback(struct urb *urb)
1122{
1123 struct usb_serial_port *port = urb->context;
1124 struct pl2303_private *priv = usb_get_serial_port_data(port);
1125 int result;
1126 int status = urb->status;
1127
1128 dbg("%s - port %d", __func__, port->number);
1129
1130 switch (status) {
1131 case 0:
1132 /* success */
1133 break;
1134 case -ECONNRESET:
1135 case -ENOENT:
1136 case -ESHUTDOWN:
1137 /* this urb is terminated, clean up */
1138 dbg("%s - urb shutting down with status: %d", __func__,
1139 status);
1140 priv->write_urb_in_use = 0;
1141 return;
1142 default:
1143 /* error in the urb, so we have to resubmit it */
1144 dbg("%s - Overflow in write", __func__);
1145 dbg("%s - nonzero write bulk status received: %d", __func__,
1146 status);
1147 port->write_urb->transfer_buffer_length = 1;
1148 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
1149 if (result)
1150 dev_err(&urb->dev->dev, "%s - failed resubmitting write"
1151 " urb, error %d\n", __func__, result);
1152 else
1153 return;
1154 }
1155
1156 priv->write_urb_in_use = 0;
1157
1158 /* send any buffered data */
1159 pl2303_send(port);
1160} 800}
1161 801
1162/* All of the device info needed for the PL2303 SIO serial converter */ 802/* All of the device info needed for the PL2303 SIO serial converter */
@@ -1168,21 +808,19 @@ static struct usb_serial_driver pl2303_device = {
1168 .id_table = id_table, 808 .id_table = id_table,
1169 .usb_driver = &pl2303_driver, 809 .usb_driver = &pl2303_driver,
1170 .num_ports = 1, 810 .num_ports = 1,
811 .bulk_in_size = 256,
812 .bulk_out_size = 256,
1171 .open = pl2303_open, 813 .open = pl2303_open,
1172 .close = pl2303_close, 814 .close = pl2303_close,
1173 .dtr_rts = pl2303_dtr_rts, 815 .dtr_rts = pl2303_dtr_rts,
1174 .carrier_raised = pl2303_carrier_raised, 816 .carrier_raised = pl2303_carrier_raised,
1175 .write = pl2303_write,
1176 .ioctl = pl2303_ioctl, 817 .ioctl = pl2303_ioctl,
1177 .break_ctl = pl2303_break_ctl, 818 .break_ctl = pl2303_break_ctl,
1178 .set_termios = pl2303_set_termios, 819 .set_termios = pl2303_set_termios,
1179 .tiocmget = pl2303_tiocmget, 820 .tiocmget = pl2303_tiocmget,
1180 .tiocmset = pl2303_tiocmset, 821 .tiocmset = pl2303_tiocmset,
1181 .read_bulk_callback = pl2303_read_bulk_callback, 822 .process_read_urb = pl2303_process_read_urb,
1182 .read_int_callback = pl2303_read_int_callback, 823 .read_int_callback = pl2303_read_int_callback,
1183 .write_bulk_callback = pl2303_write_bulk_callback,
1184 .write_room = pl2303_write_room,
1185 .chars_in_buffer = pl2303_chars_in_buffer,
1186 .attach = pl2303_startup, 824 .attach = pl2303_startup,
1187 .release = pl2303_release, 825 .release = pl2303_release,
1188}; 826};