aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index a30135c7cfe6..0222d92842b8 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -16,7 +16,6 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/config.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/errno.h> 20#include <linux/errno.h>
22#include <linux/init.h> 21#include <linux/init.h>
@@ -32,7 +31,7 @@
32#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
33#include <asm/uaccess.h> 32#include <asm/uaccess.h>
34#include <linux/usb.h> 33#include <linux/usb.h>
35#include "usb-serial.h" 34#include <linux/usb/serial.h>
36#include "pl2303.h" 35#include "pl2303.h"
37 36
38/* 37/*
@@ -41,6 +40,8 @@
41#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" 40#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
42#define DRIVER_DESC "USB Serial Driver core" 41#define DRIVER_DESC "USB Serial Driver core"
43 42
43static void port_free(struct usb_serial_port *port);
44
44/* Driver structure we register with the USB core */ 45/* Driver structure we register with the USB core */
45static struct usb_driver usb_serial_driver = { 46static struct usb_driver usb_serial_driver = {
46 .name = "usbserial", 47 .name = "usbserial",
@@ -147,23 +148,10 @@ static void destroy_serial(struct kref *kref)
147 port = serial->port[i]; 148 port = serial->port[i];
148 if (!port) 149 if (!port)
149 continue; 150 continue;
150 usb_kill_urb(port->read_urb); 151 port_free(port);
151 usb_free_urb(port->read_urb);
152 usb_kill_urb(port->write_urb);
153 usb_free_urb(port->write_urb);
154 usb_kill_urb(port->interrupt_in_urb);
155 usb_free_urb(port->interrupt_in_urb);
156 usb_kill_urb(port->interrupt_out_urb);
157 usb_free_urb(port->interrupt_out_urb);
158 kfree(port->bulk_in_buffer);
159 kfree(port->bulk_out_buffer);
160 kfree(port->interrupt_in_buffer);
161 kfree(port->interrupt_out_buffer);
162 } 152 }
163 } 153 }
164 154
165 flush_scheduled_work(); /* port->work */
166
167 usb_put_dev(serial->dev); 155 usb_put_dev(serial->dev);
168 156
169 /* free up any memory that we allocated */ 157 /* free up any memory that we allocated */
@@ -476,8 +464,10 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
476 length += sprintf (page+length, " path:%s", tmp); 464 length += sprintf (page+length, " path:%s", tmp);
477 465
478 length += sprintf (page+length, "\n"); 466 length += sprintf (page+length, "\n");
479 if ((length + begin) > (off + count)) 467 if ((length + begin) > (off + count)) {
468 usb_serial_put(serial);
480 goto done; 469 goto done;
470 }
481 if ((length + begin) < off) { 471 if ((length + begin) < off) {
482 begin += length; 472 begin += length;
483 length = 0; 473 length = 0;
@@ -565,6 +555,11 @@ static void port_release(struct device *dev)
565 struct usb_serial_port *port = to_usb_serial_port(dev); 555 struct usb_serial_port *port = to_usb_serial_port(dev);
566 556
567 dbg ("%s - %s", __FUNCTION__, dev->bus_id); 557 dbg ("%s - %s", __FUNCTION__, dev->bus_id);
558 port_free(port);
559}
560
561static void port_free(struct usb_serial_port *port)
562{
568 usb_kill_urb(port->read_urb); 563 usb_kill_urb(port->read_urb);
569 usb_free_urb(port->read_urb); 564 usb_free_urb(port->read_urb);
570 usb_kill_urb(port->write_urb); 565 usb_kill_urb(port->write_urb);
@@ -577,6 +572,7 @@ static void port_release(struct device *dev)
577 kfree(port->bulk_out_buffer); 572 kfree(port->bulk_out_buffer);
578 kfree(port->interrupt_in_buffer); 573 kfree(port->interrupt_in_buffer);
579 kfree(port->interrupt_out_buffer); 574 kfree(port->interrupt_out_buffer);
575 flush_scheduled_work(); /* port->work */
580 kfree(port); 576 kfree(port);
581} 577}
582 578
@@ -680,33 +676,29 @@ int usb_serial_probe(struct usb_interface *interface,
680 iface_desc = interface->cur_altsetting; 676 iface_desc = interface->cur_altsetting;
681 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 677 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
682 endpoint = &iface_desc->endpoint[i].desc; 678 endpoint = &iface_desc->endpoint[i].desc;
683 679
684 if ((endpoint->bEndpointAddress & 0x80) && 680 if (usb_endpoint_is_bulk_in(endpoint)) {
685 ((endpoint->bmAttributes & 3) == 0x02)) {
686 /* we found a bulk in endpoint */ 681 /* we found a bulk in endpoint */
687 dbg("found bulk in on endpoint %d", i); 682 dbg("found bulk in on endpoint %d", i);
688 bulk_in_endpoint[num_bulk_in] = endpoint; 683 bulk_in_endpoint[num_bulk_in] = endpoint;
689 ++num_bulk_in; 684 ++num_bulk_in;
690 } 685 }
691 686
692 if (((endpoint->bEndpointAddress & 0x80) == 0x00) && 687 if (usb_endpoint_is_bulk_out(endpoint)) {
693 ((endpoint->bmAttributes & 3) == 0x02)) {
694 /* we found a bulk out endpoint */ 688 /* we found a bulk out endpoint */
695 dbg("found bulk out on endpoint %d", i); 689 dbg("found bulk out on endpoint %d", i);
696 bulk_out_endpoint[num_bulk_out] = endpoint; 690 bulk_out_endpoint[num_bulk_out] = endpoint;
697 ++num_bulk_out; 691 ++num_bulk_out;
698 } 692 }
699 693
700 if ((endpoint->bEndpointAddress & 0x80) && 694 if (usb_endpoint_is_int_in(endpoint)) {
701 ((endpoint->bmAttributes & 3) == 0x03)) {
702 /* we found a interrupt in endpoint */ 695 /* we found a interrupt in endpoint */
703 dbg("found interrupt in on endpoint %d", i); 696 dbg("found interrupt in on endpoint %d", i);
704 interrupt_in_endpoint[num_interrupt_in] = endpoint; 697 interrupt_in_endpoint[num_interrupt_in] = endpoint;
705 ++num_interrupt_in; 698 ++num_interrupt_in;
706 } 699 }
707 700
708 if (((endpoint->bEndpointAddress & 0x80) == 0x00) && 701 if (usb_endpoint_is_int_out(endpoint)) {
709 ((endpoint->bmAttributes & 3) == 0x03)) {
710 /* we found an interrupt out endpoint */ 702 /* we found an interrupt out endpoint */
711 dbg("found interrupt out on endpoint %d", i); 703 dbg("found interrupt out on endpoint %d", i);
712 interrupt_out_endpoint[num_interrupt_out] = endpoint; 704 interrupt_out_endpoint[num_interrupt_out] = endpoint;
@@ -720,14 +712,15 @@ int usb_serial_probe(struct usb_interface *interface,
720 if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) && 712 if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
721 (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) || 713 (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
722 ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) && 714 ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
723 (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID))) { 715 (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) ||
716 ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) &&
717 (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID))) {
724 if (interface != dev->actconfig->interface[0]) { 718 if (interface != dev->actconfig->interface[0]) {
725 /* check out the endpoints of the other interface*/ 719 /* check out the endpoints of the other interface*/
726 iface_desc = dev->actconfig->interface[0]->cur_altsetting; 720 iface_desc = dev->actconfig->interface[0]->cur_altsetting;
727 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 721 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
728 endpoint = &iface_desc->endpoint[i].desc; 722 endpoint = &iface_desc->endpoint[i].desc;
729 if ((endpoint->bEndpointAddress & 0x80) && 723 if (usb_endpoint_is_int_in(endpoint)) {
730 ((endpoint->bmAttributes & 3) == 0x03)) {
731 /* we found a interrupt in endpoint */ 724 /* we found a interrupt in endpoint */
732 dbg("found interrupt in for Prolific device on separate interface"); 725 dbg("found interrupt in for Prolific device on separate interface");
733 interrupt_in_endpoint[num_interrupt_in] = endpoint; 726 interrupt_in_endpoint[num_interrupt_in] = endpoint;
@@ -941,7 +934,10 @@ int usb_serial_probe(struct usb_interface *interface,
941 934
942 snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number); 935 snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number);
943 dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id); 936 dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id);
944 device_register (&port->dev); 937 retval = device_register(&port->dev);
938 if (retval)
939 dev_err(&port->dev, "Error registering port device, "
940 "continuing\n");
945 } 941 }
946 942
947 usb_serial_console_init (debug, minor); 943 usb_serial_console_init (debug, minor);
@@ -1059,13 +1055,12 @@ static int __init usb_serial_init(void)
1059 1055
1060 usb_serial_tty_driver->owner = THIS_MODULE; 1056 usb_serial_tty_driver->owner = THIS_MODULE;
1061 usb_serial_tty_driver->driver_name = "usbserial"; 1057 usb_serial_tty_driver->driver_name = "usbserial";
1062 usb_serial_tty_driver->devfs_name = "usb/tts/";
1063 usb_serial_tty_driver->name = "ttyUSB"; 1058 usb_serial_tty_driver->name = "ttyUSB";
1064 usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; 1059 usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;
1065 usb_serial_tty_driver->minor_start = 0; 1060 usb_serial_tty_driver->minor_start = 0;
1066 usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; 1061 usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1067 usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; 1062 usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
1068 usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; 1063 usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
1069 usb_serial_tty_driver->init_termios = tty_std_termios; 1064 usb_serial_tty_driver->init_termios = tty_std_termios;
1070 usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1065 usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1071 tty_set_operations(usb_serial_tty_driver, &serial_ops); 1066 tty_set_operations(usb_serial_tty_driver, &serial_ops);