diff options
author | Johan Hovold <jhovold@gmail.com> | 2010-05-18 18:01:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:50 -0400 |
commit | 60b3013cdaf3fa8a17243ca46b19db3cbe08d943 (patch) | |
tree | adcd171323c298313160cdbe7500a0c731df6c90 /drivers/usb | |
parent | ff8c195ff56d5d4226d4c1586e89b7b2e96c120a (diff) |
USB: kl5usb105: reimplement using generic framework
Kill custom read and write implementations (static per-port,
singleton(!) urb pool).
Also remove changelog header (can be retrieved through git).
Read processing and write-buffer handling tested using a cp210x device
in a loopback setup.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 380 |
1 files changed, 47 insertions, 333 deletions
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index ad168255cc04..cdbe8bf7f674 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * KLSI KL5KUSB105 chip RS232 converter driver | 2 | * KLSI KL5KUSB105 chip RS232 converter driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> | ||
4 | * Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de> | 5 | * Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de> |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -34,17 +35,6 @@ | |||
34 | * implement handshaking or decide that we do not support it | 35 | * implement handshaking or decide that we do not support it |
35 | */ | 36 | */ |
36 | 37 | ||
37 | /* History: | ||
38 | * 0.3a - implemented pools of write URBs | ||
39 | * 0.3 - alpha version for public testing | ||
40 | * 0.2 - TIOCMGET works, so autopilot(1) can be used! | ||
41 | * 0.1 - can be used to do pilot-xfer -p /dev/ttyUSB0 -l | ||
42 | * | ||
43 | * The driver skeleton is mainly based on mct_u232.c and various other | ||
44 | * pieces of code shamelessly copied from the drivers/usb/serial/ directory. | ||
45 | */ | ||
46 | |||
47 | |||
48 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
49 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
50 | #include <linux/init.h> | 40 | #include <linux/init.h> |
@@ -64,8 +54,8 @@ static int debug; | |||
64 | /* | 54 | /* |
65 | * Version Information | 55 | * Version Information |
66 | */ | 56 | */ |
67 | #define DRIVER_VERSION "v0.3a" | 57 | #define DRIVER_VERSION "v0.4" |
68 | #define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>" | 58 | #define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>, Johan Hovold <jhovold@gmail.com>" |
69 | #define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver" | 59 | #define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver" |
70 | 60 | ||
71 | 61 | ||
@@ -73,23 +63,17 @@ static int debug; | |||
73 | * Function prototypes | 63 | * Function prototypes |
74 | */ | 64 | */ |
75 | static int klsi_105_startup(struct usb_serial *serial); | 65 | static int klsi_105_startup(struct usb_serial *serial); |
76 | static void klsi_105_disconnect(struct usb_serial *serial); | ||
77 | static void klsi_105_release(struct usb_serial *serial); | 66 | static void klsi_105_release(struct usb_serial *serial); |
78 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); | 67 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); |
79 | static void klsi_105_close(struct usb_serial_port *port); | 68 | static void klsi_105_close(struct usb_serial_port *port); |
80 | static int klsi_105_write(struct tty_struct *tty, | ||
81 | struct usb_serial_port *port, const unsigned char *buf, int count); | ||
82 | static void klsi_105_write_bulk_callback(struct urb *urb); | ||
83 | static int klsi_105_chars_in_buffer(struct tty_struct *tty); | ||
84 | static int klsi_105_write_room(struct tty_struct *tty); | ||
85 | static void klsi_105_read_bulk_callback(struct urb *urb); | ||
86 | static void klsi_105_set_termios(struct tty_struct *tty, | 69 | static void klsi_105_set_termios(struct tty_struct *tty, |
87 | struct usb_serial_port *port, struct ktermios *old); | 70 | struct usb_serial_port *port, struct ktermios *old); |
88 | static void klsi_105_throttle(struct tty_struct *tty); | ||
89 | static void klsi_105_unthrottle(struct tty_struct *tty); | ||
90 | static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file); | 71 | static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file); |
91 | static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, | 72 | static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, |
92 | unsigned int set, unsigned int clear); | 73 | unsigned int set, unsigned int clear); |
74 | static void klsi_105_process_read_urb(struct urb *urb); | ||
75 | static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, | ||
76 | void *dest, size_t size); | ||
93 | 77 | ||
94 | /* | 78 | /* |
95 | * All of the device info needed for the KLSI converters. | 79 | * All of the device info needed for the KLSI converters. |
@@ -119,22 +103,19 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
119 | .usb_driver = &kl5kusb105d_driver, | 103 | .usb_driver = &kl5kusb105d_driver, |
120 | .id_table = id_table, | 104 | .id_table = id_table, |
121 | .num_ports = 1, | 105 | .num_ports = 1, |
106 | .bulk_out_size = 64, | ||
122 | .open = klsi_105_open, | 107 | .open = klsi_105_open, |
123 | .close = klsi_105_close, | 108 | .close = klsi_105_close, |
124 | .write = klsi_105_write, | ||
125 | .write_bulk_callback = klsi_105_write_bulk_callback, | ||
126 | .chars_in_buffer = klsi_105_chars_in_buffer, | ||
127 | .write_room = klsi_105_write_room, | ||
128 | .read_bulk_callback = klsi_105_read_bulk_callback, | ||
129 | .set_termios = klsi_105_set_termios, | 109 | .set_termios = klsi_105_set_termios, |
130 | /*.break_ctl = klsi_105_break_ctl,*/ | 110 | /*.break_ctl = klsi_105_break_ctl,*/ |
131 | .tiocmget = klsi_105_tiocmget, | 111 | .tiocmget = klsi_105_tiocmget, |
132 | .tiocmset = klsi_105_tiocmset, | 112 | .tiocmset = klsi_105_tiocmset, |
133 | .attach = klsi_105_startup, | 113 | .attach = klsi_105_startup, |
134 | .disconnect = klsi_105_disconnect, | ||
135 | .release = klsi_105_release, | 114 | .release = klsi_105_release, |
136 | .throttle = klsi_105_throttle, | 115 | .throttle = usb_serial_generic_throttle, |
137 | .unthrottle = klsi_105_unthrottle, | 116 | .unthrottle = usb_serial_generic_unthrottle, |
117 | .process_read_urb = klsi_105_process_read_urb, | ||
118 | .prepare_write_buffer = klsi_105_prepare_write_buffer, | ||
138 | }; | 119 | }; |
139 | 120 | ||
140 | struct klsi_105_port_settings { | 121 | struct klsi_105_port_settings { |
@@ -145,18 +126,11 @@ struct klsi_105_port_settings { | |||
145 | __u8 unknown2; | 126 | __u8 unknown2; |
146 | } __attribute__ ((packed)); | 127 | } __attribute__ ((packed)); |
147 | 128 | ||
148 | /* we implement a pool of NUM_URBS urbs per usb_serial */ | ||
149 | #define NUM_URBS 1 | ||
150 | #define URB_TRANSFER_BUFFER_SIZE 64 | ||
151 | struct klsi_105_private { | 129 | struct klsi_105_private { |
152 | struct klsi_105_port_settings cfg; | 130 | struct klsi_105_port_settings cfg; |
153 | struct ktermios termios; | 131 | struct ktermios termios; |
154 | unsigned long line_state; /* modem line settings */ | 132 | unsigned long line_state; /* modem line settings */ |
155 | /* write pool */ | ||
156 | struct urb *write_urb_pool[NUM_URBS]; | ||
157 | spinlock_t lock; | 133 | spinlock_t lock; |
158 | unsigned long bytes_in; | ||
159 | unsigned long bytes_out; | ||
160 | }; | 134 | }; |
161 | 135 | ||
162 | 136 | ||
@@ -259,7 +233,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, | |||
259 | static int klsi_105_startup(struct usb_serial *serial) | 233 | static int klsi_105_startup(struct usb_serial *serial) |
260 | { | 234 | { |
261 | struct klsi_105_private *priv; | 235 | struct klsi_105_private *priv; |
262 | int i, j; | 236 | int i; |
263 | 237 | ||
264 | /* check if we support the product id (see keyspan.c) | 238 | /* check if we support the product id (see keyspan.c) |
265 | * FIXME | 239 | * FIXME |
@@ -283,29 +257,9 @@ static int klsi_105_startup(struct usb_serial *serial) | |||
283 | 257 | ||
284 | priv->line_state = 0; | 258 | priv->line_state = 0; |
285 | 259 | ||
286 | priv->bytes_in = 0; | ||
287 | priv->bytes_out = 0; | ||
288 | usb_set_serial_port_data(serial->port[i], priv); | 260 | usb_set_serial_port_data(serial->port[i], priv); |
289 | 261 | ||
290 | spin_lock_init(&priv->lock); | 262 | spin_lock_init(&priv->lock); |
291 | for (j = 0; j < NUM_URBS; j++) { | ||
292 | struct urb *urb = usb_alloc_urb(0, GFP_KERNEL); | ||
293 | |||
294 | priv->write_urb_pool[j] = urb; | ||
295 | if (urb == NULL) { | ||
296 | dev_err(&serial->dev->dev, "No more urbs???\n"); | ||
297 | goto err_cleanup; | ||
298 | } | ||
299 | |||
300 | urb->transfer_buffer = | ||
301 | kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); | ||
302 | if (!urb->transfer_buffer) { | ||
303 | dev_err(&serial->dev->dev, | ||
304 | "%s - out of memory for urb buffers.\n", | ||
305 | __func__); | ||
306 | goto err_cleanup; | ||
307 | } | ||
308 | } | ||
309 | 263 | ||
310 | /* priv->termios is left uninitalized until port opening */ | 264 | /* priv->termios is left uninitalized until port opening */ |
311 | init_waitqueue_head(&serial->port[i]->write_wait); | 265 | init_waitqueue_head(&serial->port[i]->write_wait); |
@@ -316,56 +270,20 @@ static int klsi_105_startup(struct usb_serial *serial) | |||
316 | err_cleanup: | 270 | err_cleanup: |
317 | for (; i >= 0; i--) { | 271 | for (; i >= 0; i--) { |
318 | priv = usb_get_serial_port_data(serial->port[i]); | 272 | priv = usb_get_serial_port_data(serial->port[i]); |
319 | for (j = 0; j < NUM_URBS; j++) { | ||
320 | if (priv->write_urb_pool[j]) { | ||
321 | kfree(priv->write_urb_pool[j]->transfer_buffer); | ||
322 | usb_free_urb(priv->write_urb_pool[j]); | ||
323 | } | ||
324 | } | ||
325 | kfree(priv); | 273 | kfree(priv); |
326 | usb_set_serial_port_data(serial->port[i], NULL); | 274 | usb_set_serial_port_data(serial->port[i], NULL); |
327 | } | 275 | } |
328 | return -ENOMEM; | 276 | return -ENOMEM; |
329 | } | 277 | } |
330 | 278 | ||
331 | static void klsi_105_disconnect(struct usb_serial *serial) | ||
332 | { | ||
333 | int i; | ||
334 | |||
335 | dbg("%s", __func__); | ||
336 | |||
337 | /* stop reads and writes on all ports */ | ||
338 | for (i = 0; i < serial->num_ports; ++i) { | ||
339 | struct klsi_105_private *priv = | ||
340 | usb_get_serial_port_data(serial->port[i]); | ||
341 | |||
342 | if (priv) { | ||
343 | /* kill our write urb pool */ | ||
344 | int j; | ||
345 | struct urb **write_urbs = priv->write_urb_pool; | ||
346 | |||
347 | for (j = 0; j < NUM_URBS; j++) { | ||
348 | if (write_urbs[j]) { | ||
349 | usb_kill_urb(write_urbs[j]); | ||
350 | usb_free_urb(write_urbs[j]); | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | |||
357 | static void klsi_105_release(struct usb_serial *serial) | 279 | static void klsi_105_release(struct usb_serial *serial) |
358 | { | 280 | { |
359 | int i; | 281 | int i; |
360 | 282 | ||
361 | dbg("%s", __func__); | 283 | dbg("%s", __func__); |
362 | 284 | ||
363 | for (i = 0; i < serial->num_ports; ++i) { | 285 | for (i = 0; i < serial->num_ports; ++i) |
364 | struct klsi_105_private *priv = | 286 | kfree(usb_get_serial_port_data(serial->port[i])); |
365 | usb_get_serial_port_data(serial->port[i]); | ||
366 | |||
367 | kfree(priv); | ||
368 | } | ||
369 | } | 287 | } |
370 | 288 | ||
371 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | 289 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) |
@@ -416,18 +334,8 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
416 | spin_unlock_irqrestore(&priv->lock, flags); | 334 | spin_unlock_irqrestore(&priv->lock, flags); |
417 | 335 | ||
418 | /* READ_ON and urb submission */ | 336 | /* READ_ON and urb submission */ |
419 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 337 | rc = usb_serial_generic_open(tty, port); |
420 | usb_rcvbulkpipe(port->serial->dev, | ||
421 | port->bulk_in_endpointAddress), | ||
422 | port->read_urb->transfer_buffer, | ||
423 | port->read_urb->transfer_buffer_length, | ||
424 | klsi_105_read_bulk_callback, | ||
425 | port); | ||
426 | |||
427 | rc = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
428 | if (rc) { | 338 | if (rc) { |
429 | dev_err(&port->dev, "%s - failed submitting read urb, " | ||
430 | "error %d\n", __func__, rc); | ||
431 | retval = rc; | 339 | retval = rc; |
432 | goto exit; | 340 | goto exit; |
433 | } | 341 | } |
@@ -464,7 +372,6 @@ exit: | |||
464 | 372 | ||
465 | static void klsi_105_close(struct usb_serial_port *port) | 373 | static void klsi_105_close(struct usb_serial_port *port) |
466 | { | 374 | { |
467 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
468 | int rc; | 375 | int rc; |
469 | 376 | ||
470 | dbg("%s port %d", __func__, port->number); | 377 | dbg("%s port %d", __func__, port->number); |
@@ -487,232 +394,61 @@ static void klsi_105_close(struct usb_serial_port *port) | |||
487 | mutex_unlock(&port->serial->disc_mutex); | 394 | mutex_unlock(&port->serial->disc_mutex); |
488 | 395 | ||
489 | /* shutdown our bulk reads and writes */ | 396 | /* shutdown our bulk reads and writes */ |
490 | usb_kill_urb(port->write_urb); | 397 | usb_serial_generic_close(port); |
491 | usb_kill_urb(port->read_urb); | 398 | |
492 | /* unlink our write pool */ | ||
493 | /* FIXME */ | ||
494 | /* wgg - do I need this? I think so. */ | 399 | /* wgg - do I need this? I think so. */ |
495 | usb_kill_urb(port->interrupt_in_urb); | 400 | usb_kill_urb(port->interrupt_in_urb); |
496 | dev_info(&port->serial->dev->dev, | ||
497 | "port stats: %ld bytes in, %ld bytes out\n", | ||
498 | priv->bytes_in, priv->bytes_out); | ||
499 | } | 401 | } |
500 | 402 | ||
501 | /* We need to write a complete 64-byte data block and encode the | 403 | /* We need to write a complete 64-byte data block and encode the |
502 | * number actually sent in the first double-byte, LSB-order. That | 404 | * number actually sent in the first double-byte, LSB-order. That |
503 | * leaves at most 62 bytes of payload. | 405 | * leaves at most 62 bytes of payload. |
504 | */ | 406 | */ |
505 | #define KLSI_105_DATA_OFFSET 2 /* in the bulk urb data block */ | 407 | #define KLSI_HDR_LEN 2 |
506 | 408 | static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, | |
507 | static int klsi_105_write(struct tty_struct *tty, | 409 | void *dest, size_t size) |
508 | struct usb_serial_port *port, const unsigned char *buf, int count) | ||
509 | { | ||
510 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
511 | int result, size; | ||
512 | int bytes_sent = 0; | ||
513 | |||
514 | dbg("%s - port %d", __func__, port->number); | ||
515 | |||
516 | while (count > 0) { | ||
517 | /* try to find a free urb (write 0 bytes if none) */ | ||
518 | struct urb *urb = NULL; | ||
519 | unsigned long flags; | ||
520 | int i; | ||
521 | /* since the pool is per-port we might not need | ||
522 | the spin lock !? */ | ||
523 | spin_lock_irqsave(&priv->lock, flags); | ||
524 | for (i = 0; i < NUM_URBS; i++) { | ||
525 | if (priv->write_urb_pool[i]->status != -EINPROGRESS) { | ||
526 | urb = priv->write_urb_pool[i]; | ||
527 | dbg("%s - using pool URB %d", __func__, i); | ||
528 | break; | ||
529 | } | ||
530 | } | ||
531 | spin_unlock_irqrestore(&priv->lock, flags); | ||
532 | |||
533 | if (urb == NULL) { | ||
534 | dbg("%s - no more free urbs", __func__); | ||
535 | goto exit; | ||
536 | } | ||
537 | |||
538 | if (urb->transfer_buffer == NULL) { | ||
539 | urb->transfer_buffer = | ||
540 | kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); | ||
541 | if (urb->transfer_buffer == NULL) { | ||
542 | dev_err(&port->dev, | ||
543 | "%s - no more kernel memory...\n", | ||
544 | __func__); | ||
545 | goto exit; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | size = min(count, port->bulk_out_size - KLSI_105_DATA_OFFSET); | ||
550 | size = min(size, URB_TRANSFER_BUFFER_SIZE - | ||
551 | KLSI_105_DATA_OFFSET); | ||
552 | |||
553 | memcpy(urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size); | ||
554 | |||
555 | /* write payload size into transfer buffer */ | ||
556 | ((__u8 *)urb->transfer_buffer)[0] = (__u8) (size & 0xFF); | ||
557 | ((__u8 *)urb->transfer_buffer)[1] = (__u8) ((size & 0xFF00)>>8); | ||
558 | |||
559 | /* set up our urb */ | ||
560 | usb_fill_bulk_urb(urb, port->serial->dev, | ||
561 | usb_sndbulkpipe(port->serial->dev, | ||
562 | port->bulk_out_endpointAddress), | ||
563 | urb->transfer_buffer, | ||
564 | URB_TRANSFER_BUFFER_SIZE, | ||
565 | klsi_105_write_bulk_callback, | ||
566 | port); | ||
567 | |||
568 | /* send the data out the bulk port */ | ||
569 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
570 | if (result) { | ||
571 | dev_err(&port->dev, | ||
572 | "%s - failed submitting write urb, error %d\n", | ||
573 | __func__, result); | ||
574 | goto exit; | ||
575 | } | ||
576 | buf += size; | ||
577 | bytes_sent += size; | ||
578 | count -= size; | ||
579 | } | ||
580 | exit: | ||
581 | /* lockless, but it's for debug info only... */ | ||
582 | priv->bytes_out += bytes_sent; | ||
583 | |||
584 | return bytes_sent; /* that's how much we wrote */ | ||
585 | } | ||
586 | |||
587 | static void klsi_105_write_bulk_callback(struct urb *urb) | ||
588 | { | 410 | { |
589 | struct usb_serial_port *port = urb->context; | 411 | unsigned char *buf = dest; |
590 | int status = urb->status; | 412 | int count; |
591 | |||
592 | dbg("%s - port %d", __func__, port->number); | ||
593 | 413 | ||
594 | if (status) { | 414 | count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN, size, |
595 | dbg("%s - nonzero write bulk status received: %d", __func__, | 415 | &port->lock); |
596 | status); | 416 | put_unaligned_le16(count, buf); |
597 | return; | ||
598 | } | ||
599 | 417 | ||
600 | usb_serial_port_softint(port); | 418 | return count + KLSI_HDR_LEN; |
601 | } | 419 | } |
602 | 420 | ||
603 | /* return number of characters currently in the writing process */ | 421 | /* The data received is preceded by a length double-byte in LSB-first order. |
604 | static int klsi_105_chars_in_buffer(struct tty_struct *tty) | 422 | */ |
605 | { | 423 | static void klsi_105_process_read_urb(struct urb *urb) |
606 | struct usb_serial_port *port = tty->driver_data; | ||
607 | int chars = 0; | ||
608 | int i; | ||
609 | unsigned long flags; | ||
610 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
611 | |||
612 | spin_lock_irqsave(&priv->lock, flags); | ||
613 | |||
614 | for (i = 0; i < NUM_URBS; ++i) { | ||
615 | if (priv->write_urb_pool[i]->status == -EINPROGRESS) | ||
616 | chars += URB_TRANSFER_BUFFER_SIZE; | ||
617 | } | ||
618 | |||
619 | spin_unlock_irqrestore(&priv->lock, flags); | ||
620 | |||
621 | dbg("%s - returns %d", __func__, chars); | ||
622 | return chars; | ||
623 | } | ||
624 | |||
625 | static int klsi_105_write_room(struct tty_struct *tty) | ||
626 | { | ||
627 | struct usb_serial_port *port = tty->driver_data; | ||
628 | unsigned long flags; | ||
629 | int i; | ||
630 | int room = 0; | ||
631 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
632 | |||
633 | spin_lock_irqsave(&priv->lock, flags); | ||
634 | for (i = 0; i < NUM_URBS; ++i) { | ||
635 | if (priv->write_urb_pool[i]->status != -EINPROGRESS) | ||
636 | room += URB_TRANSFER_BUFFER_SIZE; | ||
637 | } | ||
638 | |||
639 | spin_unlock_irqrestore(&priv->lock, flags); | ||
640 | |||
641 | dbg("%s - returns %d", __func__, room); | ||
642 | return room; | ||
643 | } | ||
644 | |||
645 | static void klsi_105_read_bulk_callback(struct urb *urb) | ||
646 | { | 424 | { |
647 | struct usb_serial_port *port = urb->context; | 425 | struct usb_serial_port *port = urb->context; |
648 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
649 | struct tty_struct *tty; | ||
650 | unsigned char *data = urb->transfer_buffer; | 426 | unsigned char *data = urb->transfer_buffer; |
651 | int rc; | 427 | struct tty_struct *tty; |
652 | int status = urb->status; | 428 | unsigned len; |
653 | 429 | ||
654 | dbg("%s - port %d", __func__, port->number); | 430 | /* empty urbs seem to happen, we ignore them */ |
431 | if (!urb->actual_length) | ||
432 | return; | ||
655 | 433 | ||
656 | /* The urb might have been killed. */ | 434 | if (urb->actual_length <= KLSI_HDR_LEN) { |
657 | if (status) { | 435 | dbg("%s - malformed packet", __func__); |
658 | dbg("%s - nonzero read bulk status received: %d", __func__, | ||
659 | status); | ||
660 | return; | 436 | return; |
661 | } | 437 | } |
662 | 438 | ||
663 | /* The data received is again preceded by a length double-byte in LSB- | 439 | tty = tty_port_tty_get(&port->port); |
664 | * first order (see klsi_105_write() ) | 440 | if (!tty) |
665 | */ | 441 | return; |
666 | if (urb->actual_length == 0) { | ||
667 | /* empty urbs seem to happen, we ignore them */ | ||
668 | /* dbg("%s - emtpy URB", __func__); */ | ||
669 | ; | ||
670 | } else if (urb->actual_length <= 2) { | ||
671 | dbg("%s - size %d URB not understood", __func__, | ||
672 | urb->actual_length); | ||
673 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
674 | urb->actual_length, data); | ||
675 | } else { | ||
676 | int bytes_sent = ((__u8 *) data)[0] + | ||
677 | ((unsigned int) ((__u8 *) data)[1] << 8); | ||
678 | tty = tty_port_tty_get(&port->port); | ||
679 | /* we should immediately resubmit the URB, before attempting | ||
680 | * to pass the data on to the tty layer. But that needs locking | ||
681 | * against re-entry an then mixed-up data because of | ||
682 | * intermixed tty_flip_buffer_push()s | ||
683 | * FIXME | ||
684 | */ | ||
685 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
686 | urb->actual_length, data); | ||
687 | |||
688 | if (bytes_sent + 2 > urb->actual_length) { | ||
689 | dbg("%s - trying to read more data than available" | ||
690 | " (%d vs. %d)", __func__, | ||
691 | bytes_sent+2, urb->actual_length); | ||
692 | /* cap at implied limit */ | ||
693 | bytes_sent = urb->actual_length - 2; | ||
694 | } | ||
695 | |||
696 | tty_insert_flip_string(tty, data + 2, bytes_sent); | ||
697 | tty_flip_buffer_push(tty); | ||
698 | tty_kref_put(tty); | ||
699 | 442 | ||
700 | /* again lockless, but debug info only */ | 443 | len = get_unaligned_le16(data); |
701 | priv->bytes_in += bytes_sent; | 444 | if (len > urb->actual_length - KLSI_HDR_LEN) { |
445 | dbg("%s - packet length mismatch", __func__); | ||
446 | len = urb->actual_length - KLSI_HDR_LEN; | ||
702 | } | 447 | } |
703 | /* Continue trying to always read */ | 448 | |
704 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 449 | tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len); |
705 | usb_rcvbulkpipe(port->serial->dev, | 450 | tty_flip_buffer_push(tty); |
706 | port->bulk_in_endpointAddress), | 451 | tty_kref_put(tty); |
707 | port->read_urb->transfer_buffer, | ||
708 | port->read_urb->transfer_buffer_length, | ||
709 | klsi_105_read_bulk_callback, | ||
710 | port); | ||
711 | rc = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
712 | if (rc) | ||
713 | dev_err(&port->dev, | ||
714 | "%s - failed resubmitting read urb, error %d\n", | ||
715 | __func__, rc); | ||
716 | } | 452 | } |
717 | 453 | ||
718 | static void klsi_105_set_termios(struct tty_struct *tty, | 454 | static void klsi_105_set_termios(struct tty_struct *tty, |
@@ -954,28 +690,6 @@ static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, | |||
954 | return retval; | 690 | return retval; |
955 | } | 691 | } |
956 | 692 | ||
957 | static void klsi_105_throttle(struct tty_struct *tty) | ||
958 | { | ||
959 | struct usb_serial_port *port = tty->driver_data; | ||
960 | dbg("%s - port %d", __func__, port->number); | ||
961 | usb_kill_urb(port->read_urb); | ||
962 | } | ||
963 | |||
964 | static void klsi_105_unthrottle(struct tty_struct *tty) | ||
965 | { | ||
966 | struct usb_serial_port *port = tty->driver_data; | ||
967 | int result; | ||
968 | |||
969 | dbg("%s - port %d", __func__, port->number); | ||
970 | |||
971 | port->read_urb->dev = port->serial->dev; | ||
972 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
973 | if (result) | ||
974 | dev_err(&port->dev, | ||
975 | "%s - failed submitting read urb, error %d\n", | ||
976 | __func__, result); | ||
977 | } | ||
978 | |||
979 | 693 | ||
980 | static int __init klsi_105_init(void) | 694 | static int __init klsi_105_init(void) |
981 | { | 695 | { |