diff options
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 61 |
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 | ||
43 | static 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 */ |
45 | static struct usb_driver usb_serial_driver = { | 46 | static 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 | |||
561 | static 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); |