diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2007-06-22 09:44:54 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:34:37 -0400 |
commit | a6ea438b6d38689b7f876093bcba4505fe1995d1 (patch) | |
tree | 76c090a4c4c5de30184605e84019ecde5beaeac7 | |
parent | 9a8baec77205dfe14f98a4e291c830a311125a8b (diff) |
USB: serial: ir_usb: Clean up the worst of it, remove exciting 'crash on open' feature
- Drivers don't call ldisc termios methods. They certainly don't call
them the way this one does - remove wrong call
- The tty buffer code isn't designed to be abused from IRQ handlers and
the new buffering removes the need for the uglies involved - fix them
- Style
- Remove incorrect baud and change handling for termios changes
The driver now has some style, but not a lot - it goes insane if you have
two dongles for example as it continues to use global variables for per
dongle state. That bit isn't my problem.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/serial/ir-usb.c | 142 |
1 files changed, 60 insertions, 82 deletions
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 8cec5e520d95..5ab6a0c5ac52 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -21,6 +21,10 @@ | |||
21 | * | 21 | * |
22 | * See Documentation/usb/usb-serial.txt for more information on using this driver | 22 | * See Documentation/usb/usb-serial.txt for more information on using this driver |
23 | * | 23 | * |
24 | * 2007_Jun_21 Alan Cox <alan@redhat.com> | ||
25 | * Minimal cleanups for some of the driver problens and tty layer abuse. | ||
26 | * Still needs fixing to allow multiple dongles. | ||
27 | * | ||
24 | * 2002_Mar_07 greg kh | 28 | * 2002_Mar_07 greg kh |
25 | * moved some needed structures and #define values from the | 29 | * moved some needed structures and #define values from the |
26 | * net/irda/irda-usb.h file into our file, as we don't want to depend on | 30 | * net/irda/irda-usb.h file into our file, as we don't want to depend on |
@@ -109,6 +113,7 @@ static void ir_write_bulk_callback (struct urb *urb); | |||
109 | static void ir_read_bulk_callback (struct urb *urb); | 113 | static void ir_read_bulk_callback (struct urb *urb); |
110 | static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); | 114 | static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); |
111 | 115 | ||
116 | /* Not that this lot means you can only have one per system */ | ||
112 | static u8 ir_baud = 0; | 117 | static u8 ir_baud = 0; |
113 | static u8 ir_xbof = 0; | 118 | static u8 ir_xbof = 0; |
114 | static u8 ir_add_bof = 0; | 119 | static u8 ir_add_bof = 0; |
@@ -446,22 +451,12 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
446 | urb->actual_length, | 451 | urb->actual_length, |
447 | data); | 452 | data); |
448 | 453 | ||
449 | /* | ||
450 | * Bypass flip-buffers, and feed the ldisc directly | ||
451 | * due to our potentially large buffer size. Since we | ||
452 | * used to set low_latency, this is exactly what the | ||
453 | * tty layer did anyway :) | ||
454 | */ | ||
455 | tty = port->tty; | 454 | tty = port->tty; |
456 | 455 | ||
457 | /* | 456 | if (tty_buffer_request_room(tty, urb->actual_length - 1)) { |
458 | * FIXME: must not do this in IRQ context | 457 | tty_insert_flip_string(tty, data+1, urb->actual_length - 1); |
459 | */ | 458 | tty_flip_buffer_push(tty); |
460 | tty->ldisc.receive_buf( | 459 | } |
461 | tty, | ||
462 | data+1, | ||
463 | NULL, | ||
464 | urb->actual_length-1); | ||
465 | 460 | ||
466 | /* | 461 | /* |
467 | * No break here. | 462 | * No break here. |
@@ -503,8 +498,9 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
503 | static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) | 498 | static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
504 | { | 499 | { |
505 | unsigned char *transfer_buffer; | 500 | unsigned char *transfer_buffer; |
506 | unsigned int cflag; | ||
507 | int result; | 501 | int result; |
502 | speed_t baud; | ||
503 | int ir_baud; | ||
508 | 504 | ||
509 | dbg("%s - port %d", __FUNCTION__, port->number); | 505 | dbg("%s - port %d", __FUNCTION__, port->number); |
510 | 506 | ||
@@ -513,77 +509,59 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t | |||
513 | return; | 509 | return; |
514 | } | 510 | } |
515 | 511 | ||
516 | cflag = port->tty->termios->c_cflag; | 512 | baud = tty_get_baud_rate(port->tty); |
517 | /* check that they really want us to change something */ | 513 | |
518 | if (old_termios) { | 514 | /* |
519 | if ((cflag == old_termios->c_cflag) && | 515 | * FIXME, we should compare the baud request against the |
520 | (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { | 516 | * capability stated in the IR header that we got in the |
521 | dbg("%s - nothing to change...", __FUNCTION__); | 517 | * startup function. |
522 | return; | 518 | */ |
523 | } | 519 | |
520 | switch (baud) { | ||
521 | case 2400: ir_baud = SPEED_2400; break; | ||
522 | case 9600: ir_baud = SPEED_9600; break; | ||
523 | case 19200: ir_baud = SPEED_19200; break; | ||
524 | case 38400: ir_baud = SPEED_38400; break; | ||
525 | case 57600: ir_baud = SPEED_57600; break; | ||
526 | case 115200: ir_baud = SPEED_115200; break; | ||
527 | case 576000: ir_baud = SPEED_576000; break; | ||
528 | case 1152000: ir_baud = SPEED_1152000; break; | ||
529 | case 4000000: ir_baud = SPEED_4000000; break; | ||
530 | break; | ||
531 | default: | ||
532 | ir_baud = SPEED_9600; | ||
533 | baud = 9600; | ||
534 | /* And once the new tty stuff is all done we need to | ||
535 | call back to correct the baud bits */ | ||
524 | } | 536 | } |
525 | 537 | ||
526 | /* All we can change is the baud rate */ | 538 | if (xbof == -1) |
527 | if (cflag & CBAUD) { | 539 | ir_xbof = ir_xbof_change(ir_add_bof); |
528 | 540 | else | |
529 | dbg ("%s - asking for baud %d", | 541 | ir_xbof = ir_xbof_change(xbof) ; |
530 | __FUNCTION__, | ||
531 | tty_get_baud_rate(port->tty)); | ||
532 | |||
533 | /* | ||
534 | * FIXME, we should compare the baud request against the | ||
535 | * capability stated in the IR header that we got in the | ||
536 | * startup function. | ||
537 | */ | ||
538 | switch (cflag & CBAUD) { | ||
539 | case B2400: ir_baud = SPEED_2400; break; | ||
540 | default: | ||
541 | case B9600: ir_baud = SPEED_9600; break; | ||
542 | case B19200: ir_baud = SPEED_19200; break; | ||
543 | case B38400: ir_baud = SPEED_38400; break; | ||
544 | case B57600: ir_baud = SPEED_57600; break; | ||
545 | case B115200: ir_baud = SPEED_115200; break; | ||
546 | case B576000: ir_baud = SPEED_576000; break; | ||
547 | case B1152000: ir_baud = SPEED_1152000; break; | ||
548 | #ifdef B4000000 | ||
549 | case B4000000: ir_baud = SPEED_4000000; break; | ||
550 | #endif | ||
551 | } | ||
552 | 542 | ||
553 | if (xbof == -1) { | 543 | /* FIXME need to check to see if our write urb is busy right |
554 | ir_xbof = ir_xbof_change(ir_add_bof); | 544 | * now, or use a urb pool. |
555 | } else { | 545 | * |
556 | ir_xbof = ir_xbof_change(xbof) ; | 546 | * send the baud change out on an "empty" data packet |
557 | } | 547 | */ |
548 | transfer_buffer = port->write_urb->transfer_buffer; | ||
549 | *transfer_buffer = ir_xbof | ir_baud; | ||
558 | 550 | ||
559 | /* Notify the tty driver that the termios have changed. */ | 551 | usb_fill_bulk_urb ( |
560 | port->tty->ldisc.set_termios(port->tty, NULL); | 552 | port->write_urb, |
561 | 553 | port->serial->dev, | |
562 | /* FIXME need to check to see if our write urb is busy right | 554 | usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), |
563 | * now, or use a urb pool. | 555 | port->write_urb->transfer_buffer, |
564 | * | 556 | 1, |
565 | * send the baud change out on an "empty" data packet | 557 | ir_write_bulk_callback, |
566 | */ | 558 | port); |
567 | transfer_buffer = port->write_urb->transfer_buffer; | 559 | |
568 | *transfer_buffer = ir_xbof | ir_baud; | 560 | port->write_urb->transfer_flags = URB_ZERO_PACKET; |
569 | 561 | ||
570 | usb_fill_bulk_urb ( | 562 | result = usb_submit_urb (port->write_urb, GFP_KERNEL); |
571 | port->write_urb, | 563 | if (result) |
572 | port->serial->dev, | 564 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); |
573 | usb_sndbulkpipe(port->serial->dev, | ||
574 | port->bulk_out_endpointAddress), | ||
575 | port->write_urb->transfer_buffer, | ||
576 | 1, | ||
577 | ir_write_bulk_callback, | ||
578 | port); | ||
579 | |||
580 | port->write_urb->transfer_flags = URB_ZERO_PACKET; | ||
581 | |||
582 | result = usb_submit_urb (port->write_urb, GFP_KERNEL); | ||
583 | if (result) | ||
584 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); | ||
585 | } | ||
586 | return; | ||
587 | } | 565 | } |
588 | 566 | ||
589 | 567 | ||