aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-07 22:23:21 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-07 22:23:21 -0500
commitc96e2c92072d3e78954c961f53d8c7352f7abbd7 (patch)
treed844f26f926ff40e98e9eae0e11fd71acad81df4 /drivers/usb/serial/usb-serial.c
parentf2aca47dc3c2d0c2d5dbd972558557e74232bbce (diff)
parent64358164f5bfe5e11d4040c1eb674c29e1436ce5 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (70 commits) USB: remove duplicate device id from zc0301 USB: remove duplicate device id from usb_storage USB: remove duplicate device id from keyspan USB: remove duplicate device id from ftdi_sio USB: remove duplicate device id from visor USB: a bit more coding style cleanup usbcore: trivial whitespace fixes usb-storage: use first bulk endpoints, not last EHCI: fix interrupt-driven remote wakeup USB: switch ehci-hcd to new polling scheme USB: autosuspend for usb printer driver USB Input: Added kernel module to support all GTCO CalComp USB InterWrite School products USB: Sierra Wireless auto set D0 USB: usb ethernet gadget recognizes HUSB2DEV USB: list atmel husb2_udc gadget controller USB: gadgetfs AIO tweaks USB: gadgetfs behaves better on userspace init bug USB: gadgetfs race fix USB: gadgetfs simplifications USB: gadgetfs cleanups ...
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c102
1 files changed, 81 insertions, 21 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 716f6806cc89..6bf22a28adb8 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -59,14 +59,19 @@ static struct usb_driver usb_serial_driver = {
59 59
60static int debug; 60static int debug;
61static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ 61static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
62static spinlock_t table_lock;
62static LIST_HEAD(usb_serial_driver_list); 63static LIST_HEAD(usb_serial_driver_list);
63 64
64struct usb_serial *usb_serial_get_by_index(unsigned index) 65struct usb_serial *usb_serial_get_by_index(unsigned index)
65{ 66{
66 struct usb_serial *serial = serial_table[index]; 67 struct usb_serial *serial;
68
69 spin_lock(&table_lock);
70 serial = serial_table[index];
67 71
68 if (serial) 72 if (serial)
69 kref_get(&serial->kref); 73 kref_get(&serial->kref);
74 spin_unlock(&table_lock);
70 return serial; 75 return serial;
71} 76}
72 77
@@ -78,6 +83,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po
78 dbg("%s %d", __FUNCTION__, num_ports); 83 dbg("%s %d", __FUNCTION__, num_ports);
79 84
80 *minor = 0; 85 *minor = 0;
86 spin_lock(&table_lock);
81 for (i = 0; i < SERIAL_TTY_MINORS; ++i) { 87 for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
82 if (serial_table[i]) 88 if (serial_table[i])
83 continue; 89 continue;
@@ -96,8 +102,10 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po
96 dbg("%s - minor base = %d", __FUNCTION__, *minor); 102 dbg("%s - minor base = %d", __FUNCTION__, *minor);
97 for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) 103 for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
98 serial_table[i] = serial; 104 serial_table[i] = serial;
105 spin_unlock(&table_lock);
99 return serial; 106 return serial;
100 } 107 }
108 spin_unlock(&table_lock);
101 return NULL; 109 return NULL;
102} 110}
103 111
@@ -110,9 +118,11 @@ static void return_serial(struct usb_serial *serial)
110 if (serial == NULL) 118 if (serial == NULL)
111 return; 119 return;
112 120
121 spin_lock(&table_lock);
113 for (i = 0; i < serial->num_ports; ++i) { 122 for (i = 0; i < serial->num_ports; ++i) {
114 serial_table[serial->minor + i] = NULL; 123 serial_table[serial->minor + i] = NULL;
115 } 124 }
125 spin_unlock(&table_lock);
116} 126}
117 127
118static void destroy_serial(struct kref *kref) 128static void destroy_serial(struct kref *kref)
@@ -271,7 +281,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
271static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) 281static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
272{ 282{
273 struct usb_serial_port *port = tty->driver_data; 283 struct usb_serial_port *port = tty->driver_data;
274 int retval = -EINVAL; 284 int retval = -ENODEV;
275 285
276 if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) 286 if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED)
277 goto exit; 287 goto exit;
@@ -279,6 +289,7 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int
279 dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); 289 dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
280 290
281 if (!port->open_count) { 291 if (!port->open_count) {
292 retval = -EINVAL;
282 dbg("%s - port not opened", __FUNCTION__); 293 dbg("%s - port not opened", __FUNCTION__);
283 goto exit; 294 goto exit;
284 } 295 }
@@ -559,15 +570,20 @@ static void port_release(struct device *dev)
559 port_free(port); 570 port_free(port);
560} 571}
561 572
562static void port_free(struct usb_serial_port *port) 573static void kill_traffic(struct usb_serial_port *port)
563{ 574{
564 usb_kill_urb(port->read_urb); 575 usb_kill_urb(port->read_urb);
565 usb_free_urb(port->read_urb);
566 usb_kill_urb(port->write_urb); 576 usb_kill_urb(port->write_urb);
567 usb_free_urb(port->write_urb);
568 usb_kill_urb(port->interrupt_in_urb); 577 usb_kill_urb(port->interrupt_in_urb);
569 usb_free_urb(port->interrupt_in_urb);
570 usb_kill_urb(port->interrupt_out_urb); 578 usb_kill_urb(port->interrupt_out_urb);
579}
580
581static void port_free(struct usb_serial_port *port)
582{
583 kill_traffic(port);
584 usb_free_urb(port->read_urb);
585 usb_free_urb(port->write_urb);
586 usb_free_urb(port->interrupt_in_urb);
571 usb_free_urb(port->interrupt_out_urb); 587 usb_free_urb(port->interrupt_out_urb);
572 kfree(port->bulk_in_buffer); 588 kfree(port->bulk_in_buffer);
573 kfree(port->bulk_out_buffer); 589 kfree(port->bulk_out_buffer);
@@ -596,6 +612,39 @@ static struct usb_serial * create_serial (struct usb_device *dev,
596 return serial; 612 return serial;
597} 613}
598 614
615static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
616 struct usb_serial_driver *drv)
617{
618 struct usb_dynid *dynid;
619
620 spin_lock(&drv->dynids.lock);
621 list_for_each_entry(dynid, &drv->dynids.list, node) {
622 if (usb_match_one_id(intf, &dynid->id)) {
623 spin_unlock(&drv->dynids.lock);
624 return &dynid->id;
625 }
626 }
627 spin_unlock(&drv->dynids.lock);
628 return NULL;
629}
630
631static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
632 struct usb_interface *intf)
633{
634 const struct usb_device_id *id;
635
636 id = usb_match_id(intf, drv->id_table);
637 if (id) {
638 dbg("static descriptor matches");
639 goto exit;
640 }
641 id = match_dynamic_id(intf, drv);
642 if (id)
643 dbg("dynamic descriptor matches");
644exit:
645 return id;
646}
647
599static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) 648static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
600{ 649{
601 struct list_head *p; 650 struct list_head *p;
@@ -605,11 +654,9 @@ static struct usb_serial_driver *search_serial_device(struct usb_interface *ifac
605 /* Check if the usb id matches a known device */ 654 /* Check if the usb id matches a known device */
606 list_for_each(p, &usb_serial_driver_list) { 655 list_for_each(p, &usb_serial_driver_list) {
607 t = list_entry(p, struct usb_serial_driver, driver_list); 656 t = list_entry(p, struct usb_serial_driver, driver_list);
608 id = usb_match_id(iface, t->id_table); 657 id = get_iface_id(t, iface);
609 if (id != NULL) { 658 if (id)
610 dbg("descriptor matches");
611 return t; 659 return t;
612 }
613 } 660 }
614 661
615 return NULL; 662 return NULL;
@@ -639,14 +686,17 @@ int usb_serial_probe(struct usb_interface *interface,
639 int num_ports = 0; 686 int num_ports = 0;
640 int max_endpoints; 687 int max_endpoints;
641 688
689 lock_kernel(); /* guard against unloading a serial driver module */
642 type = search_serial_device(interface); 690 type = search_serial_device(interface);
643 if (!type) { 691 if (!type) {
692 unlock_kernel();
644 dbg("none matched"); 693 dbg("none matched");
645 return -ENODEV; 694 return -ENODEV;
646 } 695 }
647 696
648 serial = create_serial (dev, interface, type); 697 serial = create_serial (dev, interface, type);
649 if (!serial) { 698 if (!serial) {
699 unlock_kernel();
650 dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); 700 dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__);
651 return -ENOMEM; 701 return -ENOMEM;
652 } 702 }
@@ -656,16 +706,18 @@ int usb_serial_probe(struct usb_interface *interface,
656 const struct usb_device_id *id; 706 const struct usb_device_id *id;
657 707
658 if (!try_module_get(type->driver.owner)) { 708 if (!try_module_get(type->driver.owner)) {
709 unlock_kernel();
659 dev_err(&interface->dev, "module get failed, exiting\n"); 710 dev_err(&interface->dev, "module get failed, exiting\n");
660 kfree (serial); 711 kfree (serial);
661 return -EIO; 712 return -EIO;
662 } 713 }
663 714
664 id = usb_match_id(interface, type->id_table); 715 id = get_iface_id(type, interface);
665 retval = type->probe(serial, id); 716 retval = type->probe(serial, id);
666 module_put(type->driver.owner); 717 module_put(type->driver.owner);
667 718
668 if (retval) { 719 if (retval) {
720 unlock_kernel();
669 dbg ("sub driver rejected device"); 721 dbg ("sub driver rejected device");
670 kfree (serial); 722 kfree (serial);
671 return retval; 723 return retval;
@@ -735,6 +787,7 @@ int usb_serial_probe(struct usb_interface *interface,
735 * properly during a later invocation of usb_serial_probe 787 * properly during a later invocation of usb_serial_probe
736 */ 788 */
737 if (num_bulk_in == 0 || num_bulk_out == 0) { 789 if (num_bulk_in == 0 || num_bulk_out == 0) {
790 unlock_kernel();
738 dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); 791 dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
739 kfree (serial); 792 kfree (serial);
740 return -ENODEV; 793 return -ENODEV;
@@ -750,6 +803,7 @@ int usb_serial_probe(struct usb_interface *interface,
750 if (type == &usb_serial_generic_device) { 803 if (type == &usb_serial_generic_device) {
751 num_ports = num_bulk_out; 804 num_ports = num_bulk_out;
752 if (num_ports == 0) { 805 if (num_ports == 0) {
806 unlock_kernel();
753 dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); 807 dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n");
754 kfree (serial); 808 kfree (serial);
755 return -EIO; 809 return -EIO;
@@ -760,6 +814,7 @@ int usb_serial_probe(struct usb_interface *interface,
760 /* if this device type has a calc_num_ports function, call it */ 814 /* if this device type has a calc_num_ports function, call it */
761 if (type->calc_num_ports) { 815 if (type->calc_num_ports) {
762 if (!try_module_get(type->driver.owner)) { 816 if (!try_module_get(type->driver.owner)) {
817 unlock_kernel();
763 dev_err(&interface->dev, "module get failed, exiting\n"); 818 dev_err(&interface->dev, "module get failed, exiting\n");
764 kfree (serial); 819 kfree (serial);
765 return -EIO; 820 return -EIO;
@@ -771,12 +826,6 @@ int usb_serial_probe(struct usb_interface *interface,
771 num_ports = type->num_ports; 826 num_ports = type->num_ports;
772 } 827 }
773 828
774 if (get_free_serial (serial, num_ports, &minor) == NULL) {
775 dev_err(&interface->dev, "No more free serial devices\n");
776 kfree (serial);
777 return -ENOMEM;
778 }
779
780 serial->minor = minor; 829 serial->minor = minor;
781 serial->num_ports = num_ports; 830 serial->num_ports = num_ports;
782 serial->num_bulk_in = num_bulk_in; 831 serial->num_bulk_in = num_bulk_in;
@@ -791,6 +840,8 @@ int usb_serial_probe(struct usb_interface *interface,
791 max_endpoints = max(max_endpoints, num_interrupt_out); 840 max_endpoints = max(max_endpoints, num_interrupt_out);
792 max_endpoints = max(max_endpoints, (int)serial->num_ports); 841 max_endpoints = max(max_endpoints, (int)serial->num_ports);
793 serial->num_port_pointers = max_endpoints; 842 serial->num_port_pointers = max_endpoints;
843 unlock_kernel();
844
794 dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); 845 dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints);
795 for (i = 0; i < max_endpoints; ++i) { 846 for (i = 0; i < max_endpoints; ++i) {
796 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); 847 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
@@ -925,6 +976,11 @@ int usb_serial_probe(struct usb_interface *interface,
925 } 976 }
926 } 977 }
927 978
979 if (get_free_serial (serial, num_ports, &minor) == NULL) {
980 dev_err(&interface->dev, "No more free serial devices\n");
981 goto probe_error;
982 }
983
928 /* register all of the individual ports with the driver core */ 984 /* register all of the individual ports with the driver core */
929 for (i = 0; i < num_ports; ++i) { 985 for (i = 0; i < num_ports; ++i) {
930 port = serial->port[i]; 986 port = serial->port[i];
@@ -1002,8 +1058,11 @@ void usb_serial_disconnect(struct usb_interface *interface)
1002 if (serial) { 1058 if (serial) {
1003 for (i = 0; i < serial->num_ports; ++i) { 1059 for (i = 0; i < serial->num_ports; ++i) {
1004 port = serial->port[i]; 1060 port = serial->port[i];
1005 if (port && port->tty) 1061 if (port) {
1006 tty_hangup(port->tty); 1062 if (port->tty)
1063 tty_hangup(port->tty);
1064 kill_traffic(port);
1065 }
1007 } 1066 }
1008 /* let the last holder of this object 1067 /* let the last holder of this object
1009 * cause it to be cleaned up */ 1068 * cause it to be cleaned up */
@@ -1040,6 +1099,7 @@ static int __init usb_serial_init(void)
1040 return -ENOMEM; 1099 return -ENOMEM;
1041 1100
1042 /* Initialize our global data */ 1101 /* Initialize our global data */
1102 spin_lock_init(&table_lock);
1043 for (i = 0; i < SERIAL_TTY_MINORS; ++i) { 1103 for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
1044 serial_table[i] = NULL; 1104 serial_table[i] = NULL;
1045 } 1105 }
@@ -1138,7 +1198,7 @@ static void fixup_generic(struct usb_serial_driver *device)
1138 set_to_generic_if_null(device, shutdown); 1198 set_to_generic_if_null(device, shutdown);
1139} 1199}
1140 1200
1141int usb_serial_register(struct usb_serial_driver *driver) 1201int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */
1142{ 1202{
1143 int retval; 1203 int retval;
1144 1204
@@ -1162,7 +1222,7 @@ int usb_serial_register(struct usb_serial_driver *driver)
1162} 1222}
1163 1223
1164 1224
1165void usb_serial_deregister(struct usb_serial_driver *device) 1225void usb_serial_deregister(struct usb_serial_driver *device) /* must be called with BKL held */
1166{ 1226{
1167 info("USB Serial deregistering driver %s", device->description); 1227 info("USB Serial deregistering driver %s", device->description);
1168 list_del(&device->driver_list); 1228 list_del(&device->driver_list);