diff options
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r-- | drivers/usb/serial/pl2303.c | 432 |
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 | |||
46 | struct pl2303_buf { | ||
47 | unsigned int buf_size; | ||
48 | char *buf_buf; | ||
49 | char *buf_get; | ||
50 | char *buf_put; | ||
51 | }; | ||
52 | |||
53 | static const struct usb_device_id id_table[] = { | 43 | static 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 | ||
156 | struct pl2303_private { | 148 | struct 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 | */ | ||
171 | static 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 | */ | ||
199 | static 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 | */ | ||
212 | static 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 | */ | ||
225 | static 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 | */ | ||
239 | static 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 | */ | ||
255 | static 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 | */ | ||
294 | static 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 | |||
325 | static int pl2303_vendor_read(__u16 value, __u16 index, | 156 | static 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 | ||
423 | static 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 | |||
465 | static 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 | |||
485 | static 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 | |||
502 | static 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 | |||
519 | static void pl2303_set_termios(struct tty_struct *tty, | 248 | static 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 | ||
728 | static void pl2303_close(struct usb_serial_port *port) | 457 | static 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 | ||
748 | static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) | 465 | static 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 | ||
1038 | static void pl2303_push_data(struct tty_struct *tty, | 750 | static 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 | |||
1070 | static 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 | |||
1121 | static 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 | }; |