aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/sierra.c228
1 files changed, 144 insertions, 84 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 222a6230276b..88ec7bfd9d35 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -26,12 +26,10 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/usb.h> 27#include <linux/usb.h>
28#include <linux/usb/serial.h> 28#include <linux/usb/serial.h>
29#include <linux/usb/ch9.h>
30 29
31#define SWIMS_USB_REQUEST_SetPower 0x00 30#define SWIMS_USB_REQUEST_SetPower 0x00
32#define SWIMS_USB_REQUEST_SetNmea 0x07 31#define SWIMS_USB_REQUEST_SetNmea 0x07
33 32
34/* per port private data */
35#define N_IN_URB 4 33#define N_IN_URB 4
36#define N_OUT_URB 4 34#define N_OUT_URB 4
37#define IN_BUFLEN 4096 35#define IN_BUFLEN 4096
@@ -229,7 +227,6 @@ struct sierra_port_private {
229 227
230 /* Input endpoints and buffers for this port */ 228 /* Input endpoints and buffers for this port */
231 struct urb *in_urbs[N_IN_URB]; 229 struct urb *in_urbs[N_IN_URB];
232 char *in_buffer[N_IN_URB];
233 230
234 /* Settings for the port */ 231 /* Settings for the port */
235 int rts_state; /* Handshaking pins (outputs) */ 232 int rts_state; /* Handshaking pins (outputs) */
@@ -334,6 +331,17 @@ static int sierra_tiocmset(struct tty_struct *tty, struct file *file,
334 return sierra_send_setup(port); 331 return sierra_send_setup(port);
335} 332}
336 333
334static void sierra_release_urb(struct urb *urb)
335{
336 struct usb_serial_port *port;
337 if (urb) {
338 port = urb->context;
339 dev_dbg(&port->dev, "%s: %p\n", __func__, urb);
340 kfree(urb->transfer_buffer);
341 usb_free_urb(urb);
342 }
343}
344
337static void sierra_outdat_callback(struct urb *urb) 345static void sierra_outdat_callback(struct urb *urb)
338{ 346{
339 struct usb_serial_port *port = urb->context; 347 struct usb_serial_port *port = urb->context;
@@ -458,7 +466,7 @@ static void sierra_indat_callback(struct urb *urb)
458 " received", __func__); 466 " received", __func__);
459 467
460 /* Resubmit urb so we continue receiving */ 468 /* Resubmit urb so we continue receiving */
461 if (port->port.count && status != -ESHUTDOWN) { 469 if (port->port.count && status != -ESHUTDOWN && status != -EPERM) {
462 err = usb_submit_urb(urb, GFP_ATOMIC); 470 err = usb_submit_urb(urb, GFP_ATOMIC);
463 if (err) 471 if (err)
464 dev_err(&port->dev, "resubmit read urb failed." 472 dev_err(&port->dev, "resubmit read urb failed."
@@ -550,100 +558,184 @@ static int sierra_write_room(struct tty_struct *tty)
550 return 2048; 558 return 2048;
551} 559}
552 560
553static int sierra_open(struct tty_struct *tty, 561static void sierra_stop_rx_urbs(struct usb_serial_port *port)
554 struct usb_serial_port *port, struct file *filp)
555{ 562{
556 struct sierra_port_private *portdata;
557 struct usb_serial *serial = port->serial;
558 int i; 563 int i;
559 struct urb *urb; 564 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
560 int result;
561 565
562 portdata = usb_get_serial_port_data(port); 566 for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++)
567 usb_kill_urb(portdata->in_urbs[i]);
563 568
564 dev_dbg(&port->dev, "%s", __func__); 569 usb_kill_urb(port->interrupt_in_urb);
570}
565 571
566 /* Set some sane defaults */ 572static int sierra_submit_rx_urbs(struct usb_serial_port *port, gfp_t mem_flags)
567 portdata->rts_state = 1; 573{
568 portdata->dtr_state = 1; 574 int ok_cnt;
575 int err = -EINVAL;
576 int i;
577 struct urb *urb;
578 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
569 579
570 /* Reset low level data toggle and start reading from endpoints */ 580 ok_cnt = 0;
571 for (i = 0; i < N_IN_URB; i++) { 581 for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
572 urb = portdata->in_urbs[i]; 582 urb = portdata->in_urbs[i];
573 if (!urb) 583 if (!urb)
574 continue; 584 continue;
575 if (urb->dev != serial->dev) { 585 err = usb_submit_urb(urb, mem_flags);
576 dev_dbg(&port->dev, "%s: dev %p != %p", 586 if (err) {
577 __func__, urb->dev, serial->dev); 587 dev_err(&port->dev, "%s: submit urb failed: %d\n",
578 continue; 588 __func__, err);
589 } else {
590 ok_cnt++;
579 } 591 }
592 }
580 593
581 /* 594 if (ok_cnt && port->interrupt_in_urb) {
582 * make sure endpoint data toggle is synchronized with the 595 err = usb_submit_urb(port->interrupt_in_urb, mem_flags);
583 * device 596 if (err) {
584 */ 597 dev_err(&port->dev, "%s: submit intr urb failed: %d\n",
585 usb_clear_halt(urb->dev, urb->pipe); 598 __func__, err);
586
587 result = usb_submit_urb(urb, GFP_KERNEL);
588 if (result) {
589 dev_err(&port->dev, "submit urb %d failed (%d) %d\n",
590 i, result, urb->transfer_buffer_length);
591 } 599 }
592 } 600 }
593 601
594 sierra_send_setup(port); 602 if (ok_cnt > 0) /* at least one rx urb submitted */
603 return 0;
604 else
605 return err;
606}
607
608static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
609 int dir, void *ctx, int len,
610 gfp_t mem_flags,
611 usb_complete_t callback)
612{
613 struct urb *urb;
614 u8 *buf;
615
616 if (endpoint == -1)
617 return NULL;
595 618
596 /* start up the interrupt endpoint if we have one */ 619 urb = usb_alloc_urb(0, mem_flags);
597 if (port->interrupt_in_urb) { 620 if (urb == NULL) {
598 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 621 dev_dbg(&serial->dev->dev, "%s: alloc for endpoint %d failed\n",
599 if (result) 622 __func__, endpoint);
600 dev_err(&port->dev, "submit irq_in urb failed %d\n", 623 return NULL;
601 result);
602 } 624 }
603 return 0; 625
626 buf = kmalloc(len, mem_flags);
627 if (buf) {
628 /* Fill URB using supplied data */
629 usb_fill_bulk_urb(urb, serial->dev,
630 usb_sndbulkpipe(serial->dev, endpoint) | dir,
631 buf, len, callback, ctx);
632
633 /* debug */
634 dev_dbg(&serial->dev->dev, "%s %c u : %p d:%p\n", __func__,
635 dir == USB_DIR_IN ? 'i' : 'o', urb, buf);
636 } else {
637 dev_dbg(&serial->dev->dev, "%s %c u:%p d:%p\n", __func__,
638 dir == USB_DIR_IN ? 'i' : 'o', urb, buf);
639
640 sierra_release_urb(urb);
641 urb = NULL;
642 }
643
644 return urb;
604} 645}
605 646
606static void sierra_dtr_rts(struct usb_serial_port *port, int on) 647static void sierra_close(struct usb_serial_port *port)
607{ 648{
649 int i;
608 struct usb_serial *serial = port->serial; 650 struct usb_serial *serial = port->serial;
609 struct sierra_port_private *portdata; 651 struct sierra_port_private *portdata;
610 652
653 dev_dbg(&port->dev, "%s\n", __func__);
611 portdata = usb_get_serial_port_data(port); 654 portdata = usb_get_serial_port_data(port);
612 portdata->rts_state = on; 655
613 portdata->dtr_state = on; 656 portdata->rts_state = 0;
657 portdata->dtr_state = 0;
614 658
615 if (serial->dev) { 659 if (serial->dev) {
616 mutex_lock(&serial->disc_mutex); 660 mutex_lock(&serial->disc_mutex);
617 if (!serial->disconnected) 661 if (!serial->disconnected)
618 sierra_send_setup(port); 662 sierra_send_setup(port);
619 mutex_unlock(&serial->disc_mutex); 663 mutex_unlock(&serial->disc_mutex);
664
665 /* Stop reading urbs */
666 sierra_stop_rx_urbs(port);
667 /* .. and release them */
668 for (i = 0; i < N_IN_URB; i++) {
669 sierra_release_urb(portdata->in_urbs[i]);
670 portdata->in_urbs[i] = NULL;
671 }
620 } 672 }
621} 673}
622 674
623static void sierra_close(struct usb_serial_port *port) 675static int sierra_open(struct tty_struct *tty,
676 struct usb_serial_port *port, struct file *filp)
624{ 677{
678 struct sierra_port_private *portdata;
679 struct usb_serial *serial = port->serial;
625 int i; 680 int i;
681 int err;
682 int endpoint;
683 struct urb *urb;
684
685 portdata = usb_get_serial_port_data(port);
686
687 dev_dbg(&port->dev, "%s", __func__);
688
689 /* Set some sane defaults */
690 portdata->rts_state = 1;
691 portdata->dtr_state = 1;
692
693
694 endpoint = port->bulk_in_endpointAddress;
695 for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
696 urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port,
697 IN_BUFLEN, GFP_KERNEL,
698 sierra_indat_callback);
699 portdata->in_urbs[i] = urb;
700 }
701 /* clear halt condition */
702 usb_clear_halt(serial->dev,
703 usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN);
704
705 err = sierra_submit_rx_urbs(port, GFP_KERNEL);
706 if (err) {
707 /* get rid of everything as in close */
708 sierra_close(port);
709 return err;
710 }
711 sierra_send_setup(port);
712
713 return 0;
714}
715
716
717static void sierra_dtr_rts(struct usb_serial_port *port, int on)
718{
626 struct usb_serial *serial = port->serial; 719 struct usb_serial *serial = port->serial;
627 struct sierra_port_private *portdata; 720 struct sierra_port_private *portdata;
628 721
629 dev_dbg(&port->dev, "%s", __func__);
630 portdata = usb_get_serial_port_data(port); 722 portdata = usb_get_serial_port_data(port);
723 portdata->rts_state = on;
724 portdata->dtr_state = on;
631 725
632 if (serial->dev) { 726 if (serial->dev) {
633 /* Stop reading/writing urbs */ 727 mutex_lock(&serial->disc_mutex);
634 for (i = 0; i < N_IN_URB; i++) 728 if (!serial->disconnected)
635 usb_kill_urb(portdata->in_urbs[i]); 729 sierra_send_setup(port);
730 mutex_unlock(&serial->disc_mutex);
636 } 731 }
637 usb_kill_urb(port->interrupt_in_urb);
638} 732}
639 733
640static int sierra_startup(struct usb_serial *serial) 734static int sierra_startup(struct usb_serial *serial)
641{ 735{
642 struct usb_serial_port *port; 736 struct usb_serial_port *port;
643 struct sierra_port_private *portdata; 737 struct sierra_port_private *portdata;
644 struct urb *urb;
645 int i; 738 int i;
646 int j;
647 739
648 dev_dbg(&serial->dev->dev, "%s", __func__); 740 dev_dbg(&serial->dev->dev, "%s", __func__);
649 741
@@ -665,34 +757,8 @@ static int sierra_startup(struct usb_serial *serial)
665 return -ENOMEM; 757 return -ENOMEM;
666 } 758 }
667 spin_lock_init(&portdata->lock); 759 spin_lock_init(&portdata->lock);
668 for (j = 0; j < N_IN_URB; j++) { 760 /* Set the port private data pointer */
669 portdata->in_buffer[j] = kmalloc(IN_BUFLEN, GFP_KERNEL);
670 if (!portdata->in_buffer[j]) {
671 for (--j; j >= 0; j--)
672 kfree(portdata->in_buffer[j]);
673 kfree(portdata);
674 return -ENOMEM;
675 }
676 }
677
678 usb_set_serial_port_data(port, portdata); 761 usb_set_serial_port_data(port, portdata);
679
680 /* initialize the in urbs */
681 for (j = 0; j < N_IN_URB; ++j) {
682 urb = usb_alloc_urb(0, GFP_KERNEL);
683 if (urb == NULL) {
684 dev_dbg(&port->dev, "%s: alloc for in "
685 "port failed.", __func__);
686 continue;
687 }
688 /* Fill URB using supplied data. */
689 usb_fill_bulk_urb(urb, serial->dev,
690 usb_rcvbulkpipe(serial->dev,
691 port->bulk_in_endpointAddress),
692 portdata->in_buffer[j], IN_BUFLEN,
693 sierra_indat_callback, port);
694 portdata->in_urbs[j] = urb;
695 }
696 } 762 }
697 763
698 return 0; 764 return 0;
@@ -700,7 +766,7 @@ static int sierra_startup(struct usb_serial *serial)
700 766
701static void sierra_shutdown(struct usb_serial *serial) 767static void sierra_shutdown(struct usb_serial *serial)
702{ 768{
703 int i, j; 769 int i;
704 struct usb_serial_port *port; 770 struct usb_serial_port *port;
705 struct sierra_port_private *portdata; 771 struct sierra_port_private *portdata;
706 772
@@ -713,12 +779,6 @@ static void sierra_shutdown(struct usb_serial *serial)
713 portdata = usb_get_serial_port_data(port); 779 portdata = usb_get_serial_port_data(port);
714 if (!portdata) 780 if (!portdata)
715 continue; 781 continue;
716
717 for (j = 0; j < N_IN_URB; j++) {
718 usb_kill_urb(portdata->in_urbs[j]);
719 usb_free_urb(portdata->in_urbs[j]);
720 kfree(portdata->in_buffer[j]);
721 }
722 kfree(portdata); 782 kfree(portdata);
723 usb_set_serial_port_data(port, NULL); 783 usb_set_serial_port_data(port, NULL);
724 } 784 }