diff options
| -rw-r--r-- | drivers/usb/serial/quatech2.c | 121 |
1 files changed, 51 insertions, 70 deletions
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 5adb7428fbb1..8d0c4a0b6a7b 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
| @@ -143,12 +143,12 @@ static void qt2_read_bulk_callback(struct urb *urb); | |||
| 143 | 143 | ||
| 144 | static void qt2_release(struct usb_serial *serial) | 144 | static void qt2_release(struct usb_serial *serial) |
| 145 | { | 145 | { |
| 146 | int i; | 146 | struct qt2_serial_private *serial_priv; |
| 147 | 147 | ||
| 148 | kfree(usb_get_serial_data(serial)); | 148 | serial_priv = usb_get_serial_data(serial); |
| 149 | 149 | ||
| 150 | for (i = 0; i < serial->num_ports; i++) | 150 | usb_free_urb(serial_priv->read_urb); |
| 151 | kfree(usb_get_serial_port_data(serial->port[i])); | 151 | kfree(serial_priv); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | static inline int calc_baud_divisor(int baudrate) | 154 | static inline int calc_baud_divisor(int baudrate) |
| @@ -464,21 +464,9 @@ static void qt2_close(struct usb_serial_port *port) | |||
| 464 | static void qt2_disconnect(struct usb_serial *serial) | 464 | static void qt2_disconnect(struct usb_serial *serial) |
| 465 | { | 465 | { |
| 466 | struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); | 466 | struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); |
| 467 | struct qt2_port_private *port_priv; | ||
| 468 | int i; | ||
| 469 | 467 | ||
| 470 | if (serial_priv->read_urb->status == -EINPROGRESS) | 468 | if (serial_priv->read_urb->status == -EINPROGRESS) |
| 471 | usb_kill_urb(serial_priv->read_urb); | 469 | usb_kill_urb(serial_priv->read_urb); |
| 472 | |||
| 473 | usb_free_urb(serial_priv->read_urb); | ||
| 474 | |||
| 475 | for (i = 0; i < serial->num_ports; i++) { | ||
| 476 | port_priv = usb_get_serial_port_data(serial->port[i]); | ||
| 477 | |||
| 478 | if (port_priv->write_urb->status == -EINPROGRESS) | ||
| 479 | usb_kill_urb(port_priv->write_urb); | ||
| 480 | usb_free_urb(port_priv->write_urb); | ||
| 481 | } | ||
| 482 | } | 470 | } |
| 483 | 471 | ||
| 484 | static int get_serial_info(struct usb_serial_port *port, | 472 | static int get_serial_info(struct usb_serial_port *port, |
| @@ -773,11 +761,9 @@ static void qt2_read_bulk_callback(struct urb *urb) | |||
| 773 | 761 | ||
| 774 | static int qt2_setup_urbs(struct usb_serial *serial) | 762 | static int qt2_setup_urbs(struct usb_serial *serial) |
| 775 | { | 763 | { |
| 776 | struct usb_serial_port *port; | ||
| 777 | struct usb_serial_port *port0; | 764 | struct usb_serial_port *port0; |
| 778 | struct qt2_serial_private *serial_priv; | 765 | struct qt2_serial_private *serial_priv; |
| 779 | struct qt2_port_private *port_priv; | 766 | int status; |
| 780 | int pcount, status; | ||
| 781 | 767 | ||
| 782 | port0 = serial->port[0]; | 768 | port0 = serial->port[0]; |
| 783 | 769 | ||
| @@ -795,30 +781,6 @@ static int qt2_setup_urbs(struct usb_serial *serial) | |||
| 795 | sizeof(serial_priv->read_buffer), | 781 | sizeof(serial_priv->read_buffer), |
| 796 | qt2_read_bulk_callback, serial); | 782 | qt2_read_bulk_callback, serial); |
| 797 | 783 | ||
| 798 | /* setup write_urb for each port */ | ||
| 799 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
| 800 | |||
| 801 | port = serial->port[pcount]; | ||
| 802 | port_priv = usb_get_serial_port_data(port); | ||
| 803 | |||
| 804 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 805 | if (!port_priv->write_urb) { | ||
| 806 | dev_err(&serial->dev->dev, | ||
| 807 | "failed to alloc write_urb for port %i\n", | ||
| 808 | pcount); | ||
| 809 | return -ENOMEM; | ||
| 810 | } | ||
| 811 | |||
| 812 | usb_fill_bulk_urb(port_priv->write_urb, | ||
| 813 | serial->dev, | ||
| 814 | usb_sndbulkpipe(serial->dev, | ||
| 815 | port0-> | ||
| 816 | bulk_out_endpointAddress), | ||
| 817 | port_priv->write_buffer, | ||
| 818 | sizeof(port_priv->write_buffer), | ||
| 819 | qt2_write_bulk_callback, port); | ||
| 820 | } | ||
| 821 | |||
| 822 | status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); | 784 | status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); |
| 823 | if (status != 0) { | 785 | if (status != 0) { |
| 824 | dev_err(&serial->dev->dev, | 786 | dev_err(&serial->dev->dev, |
| @@ -828,14 +790,12 @@ static int qt2_setup_urbs(struct usb_serial *serial) | |||
| 828 | } | 790 | } |
| 829 | 791 | ||
| 830 | return 0; | 792 | return 0; |
| 831 | |||
| 832 | } | 793 | } |
| 833 | 794 | ||
| 834 | static int qt2_attach(struct usb_serial *serial) | 795 | static int qt2_attach(struct usb_serial *serial) |
| 835 | { | 796 | { |
| 836 | struct qt2_serial_private *serial_priv; | 797 | struct qt2_serial_private *serial_priv; |
| 837 | struct qt2_port_private *port_priv; | 798 | int status; |
| 838 | int status, pcount; | ||
| 839 | 799 | ||
| 840 | /* power on unit */ | 800 | /* power on unit */ |
| 841 | status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 801 | status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
| @@ -855,26 +815,6 @@ static int qt2_attach(struct usb_serial *serial) | |||
| 855 | 815 | ||
| 856 | usb_set_serial_data(serial, serial_priv); | 816 | usb_set_serial_data(serial, serial_priv); |
| 857 | 817 | ||
| 858 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
| 859 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | ||
| 860 | if (!port_priv) { | ||
| 861 | dev_err(&serial->dev->dev, | ||
| 862 | "%s- kmalloc(%Zd) failed.\n", __func__, | ||
| 863 | sizeof(*port_priv)); | ||
| 864 | pcount--; | ||
| 865 | status = -ENOMEM; | ||
| 866 | goto attach_failed; | ||
| 867 | } | ||
| 868 | |||
| 869 | spin_lock_init(&port_priv->lock); | ||
| 870 | spin_lock_init(&port_priv->urb_lock); | ||
| 871 | init_waitqueue_head(&port_priv->delta_msr_wait); | ||
| 872 | |||
| 873 | port_priv->port = serial->port[pcount]; | ||
| 874 | |||
| 875 | usb_set_serial_port_data(serial->port[pcount], port_priv); | ||
| 876 | } | ||
| 877 | |||
| 878 | status = qt2_setup_urbs(serial); | 818 | status = qt2_setup_urbs(serial); |
| 879 | if (status != 0) | 819 | if (status != 0) |
| 880 | goto attach_failed; | 820 | goto attach_failed; |
| @@ -882,14 +822,53 @@ static int qt2_attach(struct usb_serial *serial) | |||
| 882 | return 0; | 822 | return 0; |
| 883 | 823 | ||
| 884 | attach_failed: | 824 | attach_failed: |
| 885 | for (/* empty */; pcount >= 0; pcount--) { | ||
| 886 | port_priv = usb_get_serial_port_data(serial->port[pcount]); | ||
| 887 | kfree(port_priv); | ||
| 888 | } | ||
| 889 | kfree(serial_priv); | 825 | kfree(serial_priv); |
| 890 | return status; | 826 | return status; |
| 891 | } | 827 | } |
| 892 | 828 | ||
| 829 | static int qt2_port_probe(struct usb_serial_port *port) | ||
| 830 | { | ||
| 831 | struct usb_serial *serial = port->serial; | ||
| 832 | struct qt2_port_private *port_priv; | ||
| 833 | u8 bEndpointAddress; | ||
| 834 | |||
| 835 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | ||
| 836 | if (!port_priv) | ||
| 837 | return -ENOMEM; | ||
| 838 | |||
| 839 | spin_lock_init(&port_priv->lock); | ||
| 840 | spin_lock_init(&port_priv->urb_lock); | ||
| 841 | init_waitqueue_head(&port_priv->delta_msr_wait); | ||
| 842 | port_priv->port = port; | ||
| 843 | |||
| 844 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 845 | if (!port_priv->write_urb) { | ||
| 846 | kfree(port_priv); | ||
| 847 | return -ENOMEM; | ||
| 848 | } | ||
| 849 | bEndpointAddress = serial->port[0]->bulk_out_endpointAddress; | ||
| 850 | usb_fill_bulk_urb(port_priv->write_urb, serial->dev, | ||
| 851 | usb_sndbulkpipe(serial->dev, bEndpointAddress), | ||
| 852 | port_priv->write_buffer, | ||
| 853 | sizeof(port_priv->write_buffer), | ||
| 854 | qt2_write_bulk_callback, port); | ||
| 855 | |||
| 856 | usb_set_serial_port_data(port, port_priv); | ||
| 857 | |||
| 858 | return 0; | ||
| 859 | } | ||
| 860 | |||
| 861 | static int qt2_port_remove(struct usb_serial_port *port) | ||
| 862 | { | ||
| 863 | struct qt2_port_private *port_priv; | ||
| 864 | |||
| 865 | port_priv = usb_get_serial_port_data(port); | ||
| 866 | usb_free_urb(port_priv->write_urb); | ||
| 867 | kfree(port_priv); | ||
| 868 | |||
| 869 | return 0; | ||
| 870 | } | ||
| 871 | |||
| 893 | static int qt2_tiocmget(struct tty_struct *tty) | 872 | static int qt2_tiocmget(struct tty_struct *tty) |
| 894 | { | 873 | { |
| 895 | struct usb_serial_port *port = tty->driver_data; | 874 | struct usb_serial_port *port = tty->driver_data; |
| @@ -1128,6 +1107,8 @@ static struct usb_serial_driver qt2_device = { | |||
| 1128 | .attach = qt2_attach, | 1107 | .attach = qt2_attach, |
| 1129 | .release = qt2_release, | 1108 | .release = qt2_release, |
| 1130 | .disconnect = qt2_disconnect, | 1109 | .disconnect = qt2_disconnect, |
| 1110 | .port_probe = qt2_port_probe, | ||
| 1111 | .port_remove = qt2_port_remove, | ||
| 1131 | .dtr_rts = qt2_dtr_rts, | 1112 | .dtr_rts = qt2_dtr_rts, |
| 1132 | .break_ctl = qt2_break_ctl, | 1113 | .break_ctl = qt2_break_ctl, |
| 1133 | .tiocmget = qt2_tiocmget, | 1114 | .tiocmget = qt2_tiocmget, |
