Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: drivers/usb/class/cdc-acm.c

Issue 6820034: USB: cdc-acm: fix possible deadlock with multiple openers (Closed)
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * cdc-acm.c 2 * cdc-acm.c
3 * 3 *
4 * Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de> 4 * Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de>
5 * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> 5 * Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
6 * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> 6 * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com>
7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> 7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
8 * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> 8 * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name>
9 * Copyright (c) 2005 David Kubicek <dave@awk.cz> 9 * Copyright (c) 2005 David Kubicek <dave@awk.cz>
10 * 10 *
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 { 549 {
550 struct acm *acm; 550 struct acm *acm;
551 int rv = -ENODEV; 551 int rv = -ENODEV;
552 int i; 552 int i;
553 dbg("Entering acm_tty_open."); 553 dbg("Entering acm_tty_open.");
554 554
555 mutex_lock(&open_mutex); 555 mutex_lock(&open_mutex);
556 556
557 acm = acm_table[tty->index]; 557 acm = acm_table[tty->index];
558 if (!acm || !acm->dev) 558 if (!acm || !acm->dev)
559 » » goto err_out; 559 » » goto out;
560 else 560 else
561 rv = 0; 561 rv = 0;
562 562
563 set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); 563 set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
564 564
565 tty->driver_data = acm; 565 tty->driver_data = acm;
566 tty_port_tty_set(&acm->port, tty); 566 tty_port_tty_set(&acm->port, tty);
567 567
568 if (usb_autopm_get_interface(acm->control) < 0) 568 if (usb_autopm_get_interface(acm->control) < 0)
569 goto early_bail; 569 goto early_bail;
570 else 570 else
571 acm->control->needs_remote_wakeup = 1; 571 acm->control->needs_remote_wakeup = 1;
572 572
573 mutex_lock(&acm->mutex); 573 mutex_lock(&acm->mutex);
574 if (acm->port.count++) { 574 if (acm->port.count++) {
575 mutex_unlock(&acm->mutex);
575 usb_autopm_put_interface(acm->control); 576 usb_autopm_put_interface(acm->control);
576 » » goto done; 577 » » goto out;
577 } 578 }
578 579
579 acm->ctrlurb->dev = acm->dev; 580 acm->ctrlurb->dev = acm->dev;
580 if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { 581 if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
581 dbg("usb_submit_urb(ctrl irq) failed"); 582 dbg("usb_submit_urb(ctrl irq) failed");
582 goto bail_out; 583 goto bail_out;
583 } 584 }
584 585
585 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && 586 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
586 (acm->ctrl_caps & USB_CDC_CAP_LINE)) 587 (acm->ctrl_caps & USB_CDC_CAP_LINE))
587 goto full_bailout; 588 goto full_bailout;
588 589
589 usb_autopm_put_interface(acm->control); 590 usb_autopm_put_interface(acm->control);
590 591
591 INIT_LIST_HEAD(&acm->spare_read_urbs); 592 INIT_LIST_HEAD(&acm->spare_read_urbs);
592 INIT_LIST_HEAD(&acm->spare_read_bufs); 593 INIT_LIST_HEAD(&acm->spare_read_bufs);
593 INIT_LIST_HEAD(&acm->filled_read_bufs); 594 INIT_LIST_HEAD(&acm->filled_read_bufs);
594 595
595 for (i = 0; i < acm->rx_buflimit; i++) 596 for (i = 0; i < acm->rx_buflimit; i++)
596 list_add(&(acm->ru[i].list), &acm->spare_read_urbs); 597 list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
597 for (i = 0; i < acm->rx_buflimit; i++) 598 for (i = 0; i < acm->rx_buflimit; i++)
598 list_add(&(acm->rb[i].list), &acm->spare_read_bufs); 599 list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
599 600
600 acm->throttle = 0; 601 acm->throttle = 0;
601 602
602 set_bit(ASYNCB_INITIALIZED, &acm->port.flags); 603 set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
603 rv = tty_port_block_til_ready(&acm->port, tty, filp); 604 rv = tty_port_block_til_ready(&acm->port, tty, filp);
604 tasklet_schedule(&acm->urb_task); 605 tasklet_schedule(&acm->urb_task);
605 done: 606
606 mutex_unlock(&acm->mutex); 607 mutex_unlock(&acm->mutex);
607 err_out: 608 out:
608 mutex_unlock(&open_mutex); 609 mutex_unlock(&open_mutex);
609 return rv; 610 return rv;
610 611
611 full_bailout: 612 full_bailout:
612 usb_kill_urb(acm->ctrlurb); 613 usb_kill_urb(acm->ctrlurb);
613 bail_out: 614 bail_out:
614 usb_autopm_put_interface(acm->control);
615 acm->port.count--; 615 acm->port.count--;
616 mutex_unlock(&acm->mutex); 616 mutex_unlock(&acm->mutex);
617 usb_autopm_put_interface(acm->control);
617 early_bail: 618 early_bail:
618 mutex_unlock(&open_mutex); 619 mutex_unlock(&open_mutex);
619 tty_port_tty_set(&acm->port, NULL); 620 tty_port_tty_set(&acm->port, NULL);
620 return -EIO; 621 return -EIO;
621 } 622 }
622 623
623 static void acm_tty_unregister(struct acm *acm) 624 static void acm_tty_unregister(struct acm *acm)
624 { 625 {
625 int i, nr; 626 int i, nr;
626 627
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 put_tty_driver(acm_tty_driver); 1712 put_tty_driver(acm_tty_driver);
1712 } 1713 }
1713 1714
1714 module_init(acm_init); 1715 module_init(acm_init);
1715 module_exit(acm_exit); 1716 module_exit(acm_exit);
1716 1717
1717 MODULE_AUTHOR(DRIVER_AUTHOR); 1718 MODULE_AUTHOR(DRIVER_AUTHOR);
1718 MODULE_DESCRIPTION(DRIVER_DESC); 1719 MODULE_DESCRIPTION(DRIVER_DESC);
1719 MODULE_LICENSE("GPL"); 1720 MODULE_LICENSE("GPL");
1720 MODULE_ALIAS_CHARDEV_MAJOR(ACM_TTY_MAJOR); 1721 MODULE_ALIAS_CHARDEV_MAJOR(ACM_TTY_MAJOR);
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698