diff options
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r-- | drivers/usb/serial/option.c | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d101025a4c63..e4be2d442b1e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -28,7 +28,7 @@ | |||
28 | device features. | 28 | device features. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #define DRIVER_VERSION "v0.7.1" | 31 | #define DRIVER_VERSION "v0.7.2" |
32 | #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" | 32 | #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" |
33 | #define DRIVER_DESC "USB Driver for GSM modems" | 33 | #define DRIVER_DESC "USB Driver for GSM modems" |
34 | 34 | ||
@@ -325,9 +325,6 @@ static struct usb_serial_driver option_1port_device = { | |||
325 | .description = "GSM modem (1-port)", | 325 | .description = "GSM modem (1-port)", |
326 | .usb_driver = &option_driver, | 326 | .usb_driver = &option_driver, |
327 | .id_table = option_ids, | 327 | .id_table = option_ids, |
328 | .num_interrupt_in = NUM_DONT_CARE, | ||
329 | .num_bulk_in = NUM_DONT_CARE, | ||
330 | .num_bulk_out = NUM_DONT_CARE, | ||
331 | .num_ports = 1, | 328 | .num_ports = 1, |
332 | .open = option_open, | 329 | .open = option_open, |
333 | .close = option_close, | 330 | .close = option_close, |
@@ -411,24 +408,24 @@ module_exit(option_exit); | |||
411 | 408 | ||
412 | static void option_rx_throttle(struct usb_serial_port *port) | 409 | static void option_rx_throttle(struct usb_serial_port *port) |
413 | { | 410 | { |
414 | dbg("%s", __FUNCTION__); | 411 | dbg("%s", __func__); |
415 | } | 412 | } |
416 | 413 | ||
417 | static void option_rx_unthrottle(struct usb_serial_port *port) | 414 | static void option_rx_unthrottle(struct usb_serial_port *port) |
418 | { | 415 | { |
419 | dbg("%s", __FUNCTION__); | 416 | dbg("%s", __func__); |
420 | } | 417 | } |
421 | 418 | ||
422 | static void option_break_ctl(struct usb_serial_port *port, int break_state) | 419 | static void option_break_ctl(struct usb_serial_port *port, int break_state) |
423 | { | 420 | { |
424 | /* Unfortunately, I don't know how to send a break */ | 421 | /* Unfortunately, I don't know how to send a break */ |
425 | dbg("%s", __FUNCTION__); | 422 | dbg("%s", __func__); |
426 | } | 423 | } |
427 | 424 | ||
428 | static void option_set_termios(struct usb_serial_port *port, | 425 | static void option_set_termios(struct usb_serial_port *port, |
429 | struct ktermios *old_termios) | 426 | struct ktermios *old_termios) |
430 | { | 427 | { |
431 | dbg("%s", __FUNCTION__); | 428 | dbg("%s", __func__); |
432 | /* Doesn't support option setting */ | 429 | /* Doesn't support option setting */ |
433 | tty_termios_copy_hw(port->tty->termios, old_termios); | 430 | tty_termios_copy_hw(port->tty->termios, old_termios); |
434 | option_send_setup(port); | 431 | option_send_setup(port); |
@@ -458,6 +455,7 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file, | |||
458 | 455 | ||
459 | portdata = usb_get_serial_port_data(port); | 456 | portdata = usb_get_serial_port_data(port); |
460 | 457 | ||
458 | /* FIXME: what locks portdata fields ? */ | ||
461 | if (set & TIOCM_RTS) | 459 | if (set & TIOCM_RTS) |
462 | portdata->rts_state = 1; | 460 | portdata->rts_state = 1; |
463 | if (set & TIOCM_DTR) | 461 | if (set & TIOCM_DTR) |
@@ -488,7 +486,7 @@ static int option_write(struct usb_serial_port *port, | |||
488 | 486 | ||
489 | portdata = usb_get_serial_port_data(port); | 487 | portdata = usb_get_serial_port_data(port); |
490 | 488 | ||
491 | dbg("%s: write (%d chars)", __FUNCTION__, count); | 489 | dbg("%s: write (%d chars)", __func__, count); |
492 | 490 | ||
493 | i = 0; | 491 | i = 0; |
494 | left = count; | 492 | left = count; |
@@ -509,7 +507,7 @@ static int option_write(struct usb_serial_port *port, | |||
509 | dbg("usb_write %p failed (err=%d)", | 507 | dbg("usb_write %p failed (err=%d)", |
510 | this_urb, this_urb->status); | 508 | this_urb, this_urb->status); |
511 | 509 | ||
512 | dbg("%s: endpoint %d buf %d", __FUNCTION__, | 510 | dbg("%s: endpoint %d buf %d", __func__, |
513 | usb_pipeendpoint(this_urb->pipe), i); | 511 | usb_pipeendpoint(this_urb->pipe), i); |
514 | 512 | ||
515 | /* send the data */ | 513 | /* send the data */ |
@@ -531,7 +529,7 @@ static int option_write(struct usb_serial_port *port, | |||
531 | } | 529 | } |
532 | 530 | ||
533 | count -= left; | 531 | count -= left; |
534 | dbg("%s: wrote (did %d)", __FUNCTION__, count); | 532 | dbg("%s: wrote (did %d)", __func__, count); |
535 | return count; | 533 | return count; |
536 | } | 534 | } |
537 | 535 | ||
@@ -544,14 +542,14 @@ static void option_indat_callback(struct urb *urb) | |||
544 | unsigned char *data = urb->transfer_buffer; | 542 | unsigned char *data = urb->transfer_buffer; |
545 | int status = urb->status; | 543 | int status = urb->status; |
546 | 544 | ||
547 | dbg("%s: %p", __FUNCTION__, urb); | 545 | dbg("%s: %p", __func__, urb); |
548 | 546 | ||
549 | endpoint = usb_pipeendpoint(urb->pipe); | 547 | endpoint = usb_pipeendpoint(urb->pipe); |
550 | port = (struct usb_serial_port *) urb->context; | 548 | port = urb->context; |
551 | 549 | ||
552 | if (status) { | 550 | if (status) { |
553 | dbg("%s: nonzero status: %d on endpoint %02x.", | 551 | dbg("%s: nonzero status: %d on endpoint %02x.", |
554 | __FUNCTION__, status, endpoint); | 552 | __func__, status, endpoint); |
555 | } else { | 553 | } else { |
556 | tty = port->tty; | 554 | tty = port->tty; |
557 | if (urb->actual_length) { | 555 | if (urb->actual_length) { |
@@ -559,7 +557,7 @@ static void option_indat_callback(struct urb *urb) | |||
559 | tty_insert_flip_string(tty, data, urb->actual_length); | 557 | tty_insert_flip_string(tty, data, urb->actual_length); |
560 | tty_flip_buffer_push(tty); | 558 | tty_flip_buffer_push(tty); |
561 | } else { | 559 | } else { |
562 | dbg("%s: empty read urb received", __FUNCTION__); | 560 | dbg("%s: empty read urb received", __func__); |
563 | } | 561 | } |
564 | 562 | ||
565 | /* Resubmit urb so we continue receiving */ | 563 | /* Resubmit urb so we continue receiving */ |
@@ -567,7 +565,7 @@ static void option_indat_callback(struct urb *urb) | |||
567 | err = usb_submit_urb(urb, GFP_ATOMIC); | 565 | err = usb_submit_urb(urb, GFP_ATOMIC); |
568 | if (err) | 566 | if (err) |
569 | printk(KERN_ERR "%s: resubmit read urb failed. " | 567 | printk(KERN_ERR "%s: resubmit read urb failed. " |
570 | "(%d)", __FUNCTION__, err); | 568 | "(%d)", __func__, err); |
571 | } | 569 | } |
572 | } | 570 | } |
573 | return; | 571 | return; |
@@ -579,9 +577,9 @@ static void option_outdat_callback(struct urb *urb) | |||
579 | struct option_port_private *portdata; | 577 | struct option_port_private *portdata; |
580 | int i; | 578 | int i; |
581 | 579 | ||
582 | dbg("%s", __FUNCTION__); | 580 | dbg("%s", __func__); |
583 | 581 | ||
584 | port = (struct usb_serial_port *) urb->context; | 582 | port = urb->context; |
585 | 583 | ||
586 | usb_serial_port_softint(port); | 584 | usb_serial_port_softint(port); |
587 | 585 | ||
@@ -599,19 +597,19 @@ static void option_instat_callback(struct urb *urb) | |||
599 | { | 597 | { |
600 | int err; | 598 | int err; |
601 | int status = urb->status; | 599 | int status = urb->status; |
602 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; | 600 | struct usb_serial_port *port = urb->context; |
603 | struct option_port_private *portdata = usb_get_serial_port_data(port); | 601 | struct option_port_private *portdata = usb_get_serial_port_data(port); |
604 | struct usb_serial *serial = port->serial; | 602 | struct usb_serial *serial = port->serial; |
605 | 603 | ||
606 | dbg("%s", __FUNCTION__); | 604 | dbg("%s", __func__); |
607 | dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); | 605 | dbg("%s: urb %p port %p has data %p", __func__,urb,port,portdata); |
608 | 606 | ||
609 | if (status == 0) { | 607 | if (status == 0) { |
610 | struct usb_ctrlrequest *req_pkt = | 608 | struct usb_ctrlrequest *req_pkt = |
611 | (struct usb_ctrlrequest *)urb->transfer_buffer; | 609 | (struct usb_ctrlrequest *)urb->transfer_buffer; |
612 | 610 | ||
613 | if (!req_pkt) { | 611 | if (!req_pkt) { |
614 | dbg("%s: NULL req_pkt\n", __FUNCTION__); | 612 | dbg("%s: NULL req_pkt\n", __func__); |
615 | return; | 613 | return; |
616 | } | 614 | } |
617 | if ((req_pkt->bRequestType == 0xA1) && | 615 | if ((req_pkt->bRequestType == 0xA1) && |
@@ -621,7 +619,7 @@ static void option_instat_callback(struct urb *urb) | |||
621 | urb->transfer_buffer + | 619 | urb->transfer_buffer + |
622 | sizeof(struct usb_ctrlrequest)); | 620 | sizeof(struct usb_ctrlrequest)); |
623 | 621 | ||
624 | dbg("%s: signal x%x", __FUNCTION__, signals); | 622 | dbg("%s: signal x%x", __func__, signals); |
625 | 623 | ||
626 | old_dcd_state = portdata->dcd_state; | 624 | old_dcd_state = portdata->dcd_state; |
627 | portdata->cts_state = 1; | 625 | portdata->cts_state = 1; |
@@ -633,11 +631,11 @@ static void option_instat_callback(struct urb *urb) | |||
633 | old_dcd_state && !portdata->dcd_state) | 631 | old_dcd_state && !portdata->dcd_state) |
634 | tty_hangup(port->tty); | 632 | tty_hangup(port->tty); |
635 | } else { | 633 | } else { |
636 | dbg("%s: type %x req %x", __FUNCTION__, | 634 | dbg("%s: type %x req %x", __func__, |
637 | req_pkt->bRequestType,req_pkt->bRequest); | 635 | req_pkt->bRequestType,req_pkt->bRequest); |
638 | } | 636 | } |
639 | } else | 637 | } else |
640 | dbg("%s: error %d", __FUNCTION__, status); | 638 | dbg("%s: error %d", __func__, status); |
641 | 639 | ||
642 | /* Resubmit urb so we continue receiving IRQ data */ | 640 | /* Resubmit urb so we continue receiving IRQ data */ |
643 | if (status != -ESHUTDOWN) { | 641 | if (status != -ESHUTDOWN) { |
@@ -645,7 +643,7 @@ static void option_instat_callback(struct urb *urb) | |||
645 | err = usb_submit_urb(urb, GFP_ATOMIC); | 643 | err = usb_submit_urb(urb, GFP_ATOMIC); |
646 | if (err) | 644 | if (err) |
647 | dbg("%s: resubmit intr urb failed. (%d)", | 645 | dbg("%s: resubmit intr urb failed. (%d)", |
648 | __FUNCTION__, err); | 646 | __func__, err); |
649 | } | 647 | } |
650 | } | 648 | } |
651 | 649 | ||
@@ -658,13 +656,14 @@ static int option_write_room(struct usb_serial_port *port) | |||
658 | 656 | ||
659 | portdata = usb_get_serial_port_data(port); | 657 | portdata = usb_get_serial_port_data(port); |
660 | 658 | ||
659 | |||
661 | for (i=0; i < N_OUT_URB; i++) { | 660 | for (i=0; i < N_OUT_URB; i++) { |
662 | this_urb = portdata->out_urbs[i]; | 661 | this_urb = portdata->out_urbs[i]; |
663 | if (this_urb && !test_bit(i, &portdata->out_busy)) | 662 | if (this_urb && !test_bit(i, &portdata->out_busy)) |
664 | data_len += OUT_BUFLEN; | 663 | data_len += OUT_BUFLEN; |
665 | } | 664 | } |
666 | 665 | ||
667 | dbg("%s: %d", __FUNCTION__, data_len); | 666 | dbg("%s: %d", __func__, data_len); |
668 | return data_len; | 667 | return data_len; |
669 | } | 668 | } |
670 | 669 | ||
@@ -679,10 +678,12 @@ static int option_chars_in_buffer(struct usb_serial_port *port) | |||
679 | 678 | ||
680 | for (i=0; i < N_OUT_URB; i++) { | 679 | for (i=0; i < N_OUT_URB; i++) { |
681 | this_urb = portdata->out_urbs[i]; | 680 | this_urb = portdata->out_urbs[i]; |
681 | /* FIXME: This locking is insufficient as this_urb may | ||
682 | go unused during the test */ | ||
682 | if (this_urb && test_bit(i, &portdata->out_busy)) | 683 | if (this_urb && test_bit(i, &portdata->out_busy)) |
683 | data_len += this_urb->transfer_buffer_length; | 684 | data_len += this_urb->transfer_buffer_length; |
684 | } | 685 | } |
685 | dbg("%s: %d", __FUNCTION__, data_len); | 686 | dbg("%s: %d", __func__, data_len); |
686 | return data_len; | 687 | return data_len; |
687 | } | 688 | } |
688 | 689 | ||
@@ -695,7 +696,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp) | |||
695 | 696 | ||
696 | portdata = usb_get_serial_port_data(port); | 697 | portdata = usb_get_serial_port_data(port); |
697 | 698 | ||
698 | dbg("%s", __FUNCTION__); | 699 | dbg("%s", __func__); |
699 | 700 | ||
700 | /* Set some sane defaults */ | 701 | /* Set some sane defaults */ |
701 | portdata->rts_state = 1; | 702 | portdata->rts_state = 1; |
@@ -707,7 +708,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp) | |||
707 | if (! urb) | 708 | if (! urb) |
708 | continue; | 709 | continue; |
709 | if (urb->dev != serial->dev) { | 710 | if (urb->dev != serial->dev) { |
710 | dbg("%s: dev %p != %p", __FUNCTION__, | 711 | dbg("%s: dev %p != %p", __func__, |
711 | urb->dev, serial->dev); | 712 | urb->dev, serial->dev); |
712 | continue; | 713 | continue; |
713 | } | 714 | } |
@@ -721,7 +722,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp) | |||
721 | err = usb_submit_urb(urb, GFP_KERNEL); | 722 | err = usb_submit_urb(urb, GFP_KERNEL); |
722 | if (err) { | 723 | if (err) { |
723 | dbg("%s: submit urb %d failed (%d) %d", | 724 | dbg("%s: submit urb %d failed (%d) %d", |
724 | __FUNCTION__, i, err, | 725 | __func__, i, err, |
725 | urb->transfer_buffer_length); | 726 | urb->transfer_buffer_length); |
726 | } | 727 | } |
727 | } | 728 | } |
@@ -749,7 +750,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp) | |||
749 | struct usb_serial *serial = port->serial; | 750 | struct usb_serial *serial = port->serial; |
750 | struct option_port_private *portdata; | 751 | struct option_port_private *portdata; |
751 | 752 | ||
752 | dbg("%s", __FUNCTION__); | 753 | dbg("%s", __func__); |
753 | portdata = usb_get_serial_port_data(port); | 754 | portdata = usb_get_serial_port_data(port); |
754 | 755 | ||
755 | portdata->rts_state = 0; | 756 | portdata->rts_state = 0; |
@@ -782,7 +783,7 @@ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, | |||
782 | 783 | ||
783 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | 784 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ |
784 | if (urb == NULL) { | 785 | if (urb == NULL) { |
785 | dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); | 786 | dbg("%s: alloc for endpoint %d failed.", __func__, endpoint); |
786 | return NULL; | 787 | return NULL; |
787 | } | 788 | } |
788 | 789 | ||
@@ -801,7 +802,7 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
801 | struct usb_serial_port *port; | 802 | struct usb_serial_port *port; |
802 | struct option_port_private *portdata; | 803 | struct option_port_private *portdata; |
803 | 804 | ||
804 | dbg("%s", __FUNCTION__); | 805 | dbg("%s", __func__); |
805 | 806 | ||
806 | for (i = 0; i < serial->num_ports; i++) { | 807 | for (i = 0; i < serial->num_ports; i++) { |
807 | port = serial->port[i]; | 808 | port = serial->port[i]; |
@@ -823,15 +824,18 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
823 | } | 824 | } |
824 | } | 825 | } |
825 | 826 | ||
827 | |||
828 | /** send RTS/DTR state to the port. | ||
829 | * | ||
830 | * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN | ||
831 | * CDC. | ||
832 | */ | ||
826 | static int option_send_setup(struct usb_serial_port *port) | 833 | static int option_send_setup(struct usb_serial_port *port) |
827 | { | 834 | { |
828 | struct usb_serial *serial = port->serial; | 835 | struct usb_serial *serial = port->serial; |
829 | struct option_port_private *portdata; | 836 | struct option_port_private *portdata; |
830 | 837 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | |
831 | dbg("%s", __FUNCTION__); | 838 | dbg("%s", __func__); |
832 | |||
833 | if (port->number != 0) | ||
834 | return 0; | ||
835 | 839 | ||
836 | portdata = usb_get_serial_port_data(port); | 840 | portdata = usb_get_serial_port_data(port); |
837 | 841 | ||
@@ -844,7 +848,7 @@ static int option_send_setup(struct usb_serial_port *port) | |||
844 | 848 | ||
845 | return usb_control_msg(serial->dev, | 849 | return usb_control_msg(serial->dev, |
846 | usb_rcvctrlpipe(serial->dev, 0), | 850 | usb_rcvctrlpipe(serial->dev, 0), |
847 | 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); | 851 | 0x22,0x21,val,ifNum,NULL,0,USB_CTRL_SET_TIMEOUT); |
848 | } | 852 | } |
849 | 853 | ||
850 | return 0; | 854 | return 0; |
@@ -857,7 +861,7 @@ static int option_startup(struct usb_serial *serial) | |||
857 | struct option_port_private *portdata; | 861 | struct option_port_private *portdata; |
858 | u8 *buffer; | 862 | u8 *buffer; |
859 | 863 | ||
860 | dbg("%s", __FUNCTION__); | 864 | dbg("%s", __func__); |
861 | 865 | ||
862 | /* Now setup per port private data */ | 866 | /* Now setup per port private data */ |
863 | for (i = 0; i < serial->num_ports; i++) { | 867 | for (i = 0; i < serial->num_ports; i++) { |
@@ -865,7 +869,7 @@ static int option_startup(struct usb_serial *serial) | |||
865 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | 869 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
866 | if (!portdata) { | 870 | if (!portdata) { |
867 | dbg("%s: kmalloc for option_port_private (%d) failed!.", | 871 | dbg("%s: kmalloc for option_port_private (%d) failed!.", |
868 | __FUNCTION__, i); | 872 | __func__, i); |
869 | return (1); | 873 | return (1); |
870 | } | 874 | } |
871 | 875 | ||
@@ -890,7 +894,7 @@ static int option_startup(struct usb_serial *serial) | |||
890 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 894 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
891 | if (err) | 895 | if (err) |
892 | dbg("%s: submit irq_in urb failed %d", | 896 | dbg("%s: submit irq_in urb failed %d", |
893 | __FUNCTION__, err); | 897 | __func__, err); |
894 | } | 898 | } |
895 | 899 | ||
896 | option_setup_urbs(serial); | 900 | option_setup_urbs(serial); |
@@ -914,7 +918,7 @@ static void option_shutdown(struct usb_serial *serial) | |||
914 | struct usb_serial_port *port; | 918 | struct usb_serial_port *port; |
915 | struct option_port_private *portdata; | 919 | struct option_port_private *portdata; |
916 | 920 | ||
917 | dbg("%s", __FUNCTION__); | 921 | dbg("%s", __func__); |
918 | 922 | ||
919 | /* Stop reading/writing urbs */ | 923 | /* Stop reading/writing urbs */ |
920 | for (i = 0; i < serial->num_ports; ++i) { | 924 | for (i = 0; i < serial->num_ports; ++i) { |