diff options
Diffstat (limited to 'drivers/usb/serial/ir-usb.c')
-rw-r--r-- | drivers/usb/serial/ir-usb.c | 154 |
1 files changed, 67 insertions, 87 deletions
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 9d847f69291c..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; |
@@ -392,12 +397,14 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int | |||
392 | static void ir_write_bulk_callback (struct urb *urb) | 397 | static void ir_write_bulk_callback (struct urb *urb) |
393 | { | 398 | { |
394 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 399 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
400 | int status = urb->status; | ||
395 | 401 | ||
396 | dbg("%s - port %d", __FUNCTION__, port->number); | 402 | dbg("%s - port %d", __FUNCTION__, port->number); |
397 | 403 | ||
398 | port->write_urb_busy = 0; | 404 | port->write_urb_busy = 0; |
399 | if (urb->status) { | 405 | if (status) { |
400 | dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); | 406 | dbg("%s - nonzero write bulk status received: %d", |
407 | __FUNCTION__, status); | ||
401 | return; | 408 | return; |
402 | } | 409 | } |
403 | 410 | ||
@@ -417,6 +424,7 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
417 | struct tty_struct *tty; | 424 | struct tty_struct *tty; |
418 | unsigned char *data = urb->transfer_buffer; | 425 | unsigned char *data = urb->transfer_buffer; |
419 | int result; | 426 | int result; |
427 | int status = urb->status; | ||
420 | 428 | ||
421 | dbg("%s - port %d", __FUNCTION__, port->number); | 429 | dbg("%s - port %d", __FUNCTION__, port->number); |
422 | 430 | ||
@@ -425,8 +433,7 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
425 | return; | 433 | return; |
426 | } | 434 | } |
427 | 435 | ||
428 | switch (urb->status) { | 436 | switch (status) { |
429 | |||
430 | case 0: /* Successful */ | 437 | case 0: /* Successful */ |
431 | 438 | ||
432 | /* | 439 | /* |
@@ -444,22 +451,12 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
444 | urb->actual_length, | 451 | urb->actual_length, |
445 | data); | 452 | data); |
446 | 453 | ||
447 | /* | ||
448 | * Bypass flip-buffers, and feed the ldisc directly | ||
449 | * due to our potentially large buffer size. Since we | ||
450 | * used to set low_latency, this is exactly what the | ||
451 | * tty layer did anyway :) | ||
452 | */ | ||
453 | tty = port->tty; | 454 | tty = port->tty; |
454 | 455 | ||
455 | /* | 456 | if (tty_buffer_request_room(tty, urb->actual_length - 1)) { |
456 | * FIXME: must not do this in IRQ context | 457 | tty_insert_flip_string(tty, data+1, urb->actual_length - 1); |
457 | */ | 458 | tty_flip_buffer_push(tty); |
458 | tty->ldisc.receive_buf( | 459 | } |
459 | tty, | ||
460 | data+1, | ||
461 | NULL, | ||
462 | urb->actual_length-1); | ||
463 | 460 | ||
464 | /* | 461 | /* |
465 | * No break here. | 462 | * No break here. |
@@ -490,7 +487,7 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
490 | default: | 487 | default: |
491 | dbg("%s - nonzero read bulk status received: %d", | 488 | dbg("%s - nonzero read bulk status received: %d", |
492 | __FUNCTION__, | 489 | __FUNCTION__, |
493 | urb->status); | 490 | status); |
494 | break ; | 491 | break ; |
495 | 492 | ||
496 | } | 493 | } |
@@ -501,8 +498,9 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
501 | 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) |
502 | { | 499 | { |
503 | unsigned char *transfer_buffer; | 500 | unsigned char *transfer_buffer; |
504 | unsigned int cflag; | ||
505 | int result; | 501 | int result; |
502 | speed_t baud; | ||
503 | int ir_baud; | ||
506 | 504 | ||
507 | dbg("%s - port %d", __FUNCTION__, port->number); | 505 | dbg("%s - port %d", __FUNCTION__, port->number); |
508 | 506 | ||
@@ -511,77 +509,59 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t | |||
511 | return; | 509 | return; |
512 | } | 510 | } |
513 | 511 | ||
514 | cflag = port->tty->termios->c_cflag; | 512 | baud = tty_get_baud_rate(port->tty); |
515 | /* check that they really want us to change something */ | 513 | |
516 | if (old_termios) { | 514 | /* |
517 | if ((cflag == old_termios->c_cflag) && | 515 | * FIXME, we should compare the baud request against the |
518 | (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 |
519 | dbg("%s - nothing to change...", __FUNCTION__); | 517 | * startup function. |
520 | return; | 518 | */ |
521 | } | 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 */ | ||
522 | } | 536 | } |
523 | 537 | ||
524 | /* All we can change is the baud rate */ | 538 | if (xbof == -1) |
525 | if (cflag & CBAUD) { | 539 | ir_xbof = ir_xbof_change(ir_add_bof); |
526 | 540 | else | |
527 | dbg ("%s - asking for baud %d", | 541 | ir_xbof = ir_xbof_change(xbof) ; |
528 | __FUNCTION__, | ||
529 | tty_get_baud_rate(port->tty)); | ||
530 | |||
531 | /* | ||
532 | * FIXME, we should compare the baud request against the | ||
533 | * capability stated in the IR header that we got in the | ||
534 | * startup function. | ||
535 | */ | ||
536 | switch (cflag & CBAUD) { | ||
537 | case B2400: ir_baud = SPEED_2400; break; | ||
538 | default: | ||
539 | case B9600: ir_baud = SPEED_9600; break; | ||
540 | case B19200: ir_baud = SPEED_19200; break; | ||
541 | case B38400: ir_baud = SPEED_38400; break; | ||
542 | case B57600: ir_baud = SPEED_57600; break; | ||
543 | case B115200: ir_baud = SPEED_115200; break; | ||
544 | case B576000: ir_baud = SPEED_576000; break; | ||
545 | case B1152000: ir_baud = SPEED_1152000; break; | ||
546 | #ifdef B4000000 | ||
547 | case B4000000: ir_baud = SPEED_4000000; break; | ||
548 | #endif | ||
549 | } | ||
550 | 542 | ||
551 | if (xbof == -1) { | 543 | /* FIXME need to check to see if our write urb is busy right |
552 | ir_xbof = ir_xbof_change(ir_add_bof); | 544 | * now, or use a urb pool. |
553 | } else { | 545 | * |
554 | ir_xbof = ir_xbof_change(xbof) ; | 546 | * send the baud change out on an "empty" data packet |
555 | } | 547 | */ |
548 | transfer_buffer = port->write_urb->transfer_buffer; | ||
549 | *transfer_buffer = ir_xbof | ir_baud; | ||
556 | 550 | ||
557 | /* Notify the tty driver that the termios have changed. */ | 551 | usb_fill_bulk_urb ( |
558 | port->tty->ldisc.set_termios(port->tty, NULL); | 552 | port->write_urb, |
559 | 553 | port->serial->dev, | |
560 | /* FIXME need to check to see if our write urb is busy right | 554 | usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), |
561 | * now, or use a urb pool. | 555 | port->write_urb->transfer_buffer, |
562 | * | 556 | 1, |
563 | * send the baud change out on an "empty" data packet | 557 | ir_write_bulk_callback, |
564 | */ | 558 | port); |
565 | transfer_buffer = port->write_urb->transfer_buffer; | 559 | |
566 | *transfer_buffer = ir_xbof | ir_baud; | 560 | port->write_urb->transfer_flags = URB_ZERO_PACKET; |
567 | 561 | ||
568 | usb_fill_bulk_urb ( | 562 | result = usb_submit_urb (port->write_urb, GFP_KERNEL); |
569 | port->write_urb, | 563 | if (result) |
570 | port->serial->dev, | 564 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); |
571 | usb_sndbulkpipe(port->serial->dev, | ||
572 | port->bulk_out_endpointAddress), | ||
573 | port->write_urb->transfer_buffer, | ||
574 | 1, | ||
575 | ir_write_bulk_callback, | ||
576 | port); | ||
577 | |||
578 | port->write_urb->transfer_flags = URB_ZERO_PACKET; | ||
579 | |||
580 | result = usb_submit_urb (port->write_urb, GFP_KERNEL); | ||
581 | if (result) | ||
582 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); | ||
583 | } | ||
584 | return; | ||
585 | } | 565 | } |
586 | 566 | ||
587 | 567 | ||