aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2012-03-06 11:29:21 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-08 16:06:48 -0500
commitb0c13860808a528cd580fdca61aef9f73352a331 (patch)
tree8b2bc79cf10452c499741a5bb1a0a7c22ab4df94 /drivers/usb/class
parent0dffb4862a5f109dc9b72e3a4e0ecc85a87ce397 (diff)
usb: cdc-wdm: adding list lookup indirection
Register all interfaces handled by this driver in a list, getting rid of the dependency on usb_set_intfdata. This allows further generalization and simplification of the probe/create functions. This is needed to decouple wdm_open from the driver owning the interface, and it also allows us to share all the code in wdm_create with drivers unable to do usb_set_intfdata. Signed-off-by: Bjørn Mork <bjorn@mork.no> Acked-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/class')
-rw-r--r--drivers/usb/class/cdc-wdm.c60
1 files changed, 48 insertions, 12 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 451793036d37..46827373ecf9 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -78,6 +78,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
78#define WDM_DEFAULT_BUFSIZE 256 78#define WDM_DEFAULT_BUFSIZE 256
79 79
80static DEFINE_MUTEX(wdm_mutex); 80static DEFINE_MUTEX(wdm_mutex);
81static DEFINE_SPINLOCK(wdm_device_list_lock);
82static LIST_HEAD(wdm_device_list);
81 83
82/* --- method tables --- */ 84/* --- method tables --- */
83 85
@@ -112,10 +114,39 @@ struct wdm_device {
112 struct work_struct rxwork; 114 struct work_struct rxwork;
113 int werr; 115 int werr;
114 int rerr; 116 int rerr;
117
118 struct list_head device_list;
115}; 119};
116 120
117static struct usb_driver wdm_driver; 121static struct usb_driver wdm_driver;
118 122
123/* return intfdata if we own the interface, else look up intf in the list */
124static struct wdm_device *wdm_find_device(struct usb_interface *intf)
125{
126 struct wdm_device *desc = NULL;
127
128 spin_lock(&wdm_device_list_lock);
129 list_for_each_entry(desc, &wdm_device_list, device_list)
130 if (desc->intf == intf)
131 break;
132 spin_unlock(&wdm_device_list_lock);
133
134 return desc;
135}
136
137static struct wdm_device *wdm_find_device_by_minor(int minor)
138{
139 struct wdm_device *desc = NULL;
140
141 spin_lock(&wdm_device_list_lock);
142 list_for_each_entry(desc, &wdm_device_list, device_list)
143 if (desc->intf->minor == minor)
144 break;
145 spin_unlock(&wdm_device_list_lock);
146
147 return desc;
148}
149
119/* --- callbacks --- */ 150/* --- callbacks --- */
120static void wdm_out_callback(struct urb *urb) 151static void wdm_out_callback(struct urb *urb)
121{ 152{
@@ -275,6 +306,9 @@ static void free_urbs(struct wdm_device *desc)
275 306
276static void cleanup(struct wdm_device *desc) 307static void cleanup(struct wdm_device *desc)
277{ 308{
309 spin_lock(&wdm_device_list_lock);
310 list_del(&desc->device_list);
311 spin_unlock(&wdm_device_list_lock);
278 kfree(desc->sbuf); 312 kfree(desc->sbuf);
279 kfree(desc->inbuf); 313 kfree(desc->inbuf);
280 kfree(desc->orq); 314 kfree(desc->orq);
@@ -532,11 +566,11 @@ static int wdm_open(struct inode *inode, struct file *file)
532 struct wdm_device *desc; 566 struct wdm_device *desc;
533 567
534 mutex_lock(&wdm_mutex); 568 mutex_lock(&wdm_mutex);
535 intf = usb_find_interface(&wdm_driver, minor); 569 desc = wdm_find_device_by_minor(minor);
536 if (!intf) 570 if (!desc)
537 goto out; 571 goto out;
538 572
539 desc = usb_get_intfdata(intf); 573 intf = desc->intf;
540 if (test_bit(WDM_DISCONNECTING, &desc->flags)) 574 if (test_bit(WDM_DISCONNECTING, &desc->flags))
541 goto out; 575 goto out;
542 file->private_data = desc; 576 file->private_data = desc;
@@ -639,6 +673,7 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
639 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); 673 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
640 if (!desc) 674 if (!desc)
641 goto out; 675 goto out;
676 INIT_LIST_HEAD(&desc->device_list);
642 mutex_init(&desc->rlock); 677 mutex_init(&desc->rlock);
643 mutex_init(&desc->wlock); 678 mutex_init(&desc->wlock);
644 spin_lock_init(&desc->iuspin); 679 spin_lock_init(&desc->iuspin);
@@ -715,16 +750,17 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
715 desc 750 desc
716 ); 751 );
717 752
718 usb_set_intfdata(intf, desc); 753 spin_lock(&wdm_device_list_lock);
754 list_add(&desc->device_list, &wdm_device_list);
755 spin_unlock(&wdm_device_list_lock);
756
719 rv = usb_register_dev(intf, &wdm_class); 757 rv = usb_register_dev(intf, &wdm_class);
720 if (rv < 0) 758 if (rv < 0)
721 goto err2; 759 goto err;
722 else 760 else
723 dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev)); 761 dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev));
724out: 762out:
725 return rv; 763 return rv;
726err2:
727 usb_set_intfdata(intf, NULL);
728err: 764err:
729 cleanup(desc); 765 cleanup(desc);
730 return rv; 766 return rv;
@@ -785,8 +821,8 @@ static void wdm_disconnect(struct usb_interface *intf)
785 unsigned long flags; 821 unsigned long flags;
786 822
787 usb_deregister_dev(intf, &wdm_class); 823 usb_deregister_dev(intf, &wdm_class);
824 desc = wdm_find_device(intf);
788 mutex_lock(&wdm_mutex); 825 mutex_lock(&wdm_mutex);
789 desc = usb_get_intfdata(intf);
790 826
791 /* the spinlock makes sure no new urbs are generated in the callbacks */ 827 /* the spinlock makes sure no new urbs are generated in the callbacks */
792 spin_lock_irqsave(&desc->iuspin, flags); 828 spin_lock_irqsave(&desc->iuspin, flags);
@@ -810,7 +846,7 @@ static void wdm_disconnect(struct usb_interface *intf)
810#ifdef CONFIG_PM 846#ifdef CONFIG_PM
811static int wdm_suspend(struct usb_interface *intf, pm_message_t message) 847static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
812{ 848{
813 struct wdm_device *desc = usb_get_intfdata(intf); 849 struct wdm_device *desc = wdm_find_device(intf);
814 int rv = 0; 850 int rv = 0;
815 851
816 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); 852 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
@@ -860,7 +896,7 @@ static int recover_from_urb_loss(struct wdm_device *desc)
860#ifdef CONFIG_PM 896#ifdef CONFIG_PM
861static int wdm_resume(struct usb_interface *intf) 897static int wdm_resume(struct usb_interface *intf)
862{ 898{
863 struct wdm_device *desc = usb_get_intfdata(intf); 899 struct wdm_device *desc = wdm_find_device(intf);
864 int rv; 900 int rv;
865 901
866 dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); 902 dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
@@ -874,7 +910,7 @@ static int wdm_resume(struct usb_interface *intf)
874 910
875static int wdm_pre_reset(struct usb_interface *intf) 911static int wdm_pre_reset(struct usb_interface *intf)
876{ 912{
877 struct wdm_device *desc = usb_get_intfdata(intf); 913 struct wdm_device *desc = wdm_find_device(intf);
878 914
879 /* 915 /*
880 * we notify everybody using poll of 916 * we notify everybody using poll of
@@ -898,7 +934,7 @@ static int wdm_pre_reset(struct usb_interface *intf)
898 934
899static int wdm_post_reset(struct usb_interface *intf) 935static int wdm_post_reset(struct usb_interface *intf)
900{ 936{
901 struct wdm_device *desc = usb_get_intfdata(intf); 937 struct wdm_device *desc = wdm_find_device(intf);
902 int rv; 938 int rv;
903 939
904 clear_bit(WDM_RESETTING, &desc->flags); 940 clear_bit(WDM_RESETTING, &desc->flags);