Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 289655
b: refs/heads/master
c: b0c1386
h: refs/heads/master
i:
  289653: eaa807e
  289651: 2906942
  289647: 7298887
v: v3
  • Loading branch information
Bjørn Mork authored and Greg Kroah-Hartman committed Mar 8, 2012
1 parent ce19901 commit 7ac3a97
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0dffb4862a5f109dc9b72e3a4e0ecc85a87ce397
refs/heads/master: b0c13860808a528cd580fdca61aef9f73352a331
60 changes: 48 additions & 12 deletions trunk/drivers/usb/class/cdc-wdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
#define WDM_DEFAULT_BUFSIZE 256

static DEFINE_MUTEX(wdm_mutex);
static DEFINE_SPINLOCK(wdm_device_list_lock);
static LIST_HEAD(wdm_device_list);

/* --- method tables --- */

Expand Down Expand Up @@ -112,10 +114,39 @@ struct wdm_device {
struct work_struct rxwork;
int werr;
int rerr;

struct list_head device_list;
};

static struct usb_driver wdm_driver;

/* return intfdata if we own the interface, else look up intf in the list */
static struct wdm_device *wdm_find_device(struct usb_interface *intf)
{
struct wdm_device *desc = NULL;

spin_lock(&wdm_device_list_lock);
list_for_each_entry(desc, &wdm_device_list, device_list)
if (desc->intf == intf)
break;
spin_unlock(&wdm_device_list_lock);

return desc;
}

static struct wdm_device *wdm_find_device_by_minor(int minor)
{
struct wdm_device *desc = NULL;

spin_lock(&wdm_device_list_lock);
list_for_each_entry(desc, &wdm_device_list, device_list)
if (desc->intf->minor == minor)
break;
spin_unlock(&wdm_device_list_lock);

return desc;
}

/* --- callbacks --- */
static void wdm_out_callback(struct urb *urb)
{
Expand Down Expand Up @@ -275,6 +306,9 @@ static void free_urbs(struct wdm_device *desc)

static void cleanup(struct wdm_device *desc)
{
spin_lock(&wdm_device_list_lock);
list_del(&desc->device_list);
spin_unlock(&wdm_device_list_lock);
kfree(desc->sbuf);
kfree(desc->inbuf);
kfree(desc->orq);
Expand Down Expand Up @@ -532,11 +566,11 @@ static int wdm_open(struct inode *inode, struct file *file)
struct wdm_device *desc;

mutex_lock(&wdm_mutex);
intf = usb_find_interface(&wdm_driver, minor);
if (!intf)
desc = wdm_find_device_by_minor(minor);
if (!desc)
goto out;

desc = usb_get_intfdata(intf);
intf = desc->intf;
if (test_bit(WDM_DISCONNECTING, &desc->flags))
goto out;
file->private_data = desc;
Expand Down Expand Up @@ -639,6 +673,7 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
if (!desc)
goto out;
INIT_LIST_HEAD(&desc->device_list);
mutex_init(&desc->rlock);
mutex_init(&desc->wlock);
spin_lock_init(&desc->iuspin);
Expand Down Expand Up @@ -715,16 +750,17 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
desc
);

usb_set_intfdata(intf, desc);
spin_lock(&wdm_device_list_lock);
list_add(&desc->device_list, &wdm_device_list);
spin_unlock(&wdm_device_list_lock);

rv = usb_register_dev(intf, &wdm_class);
if (rv < 0)
goto err2;
goto err;
else
dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev));
out:
return rv;
err2:
usb_set_intfdata(intf, NULL);
err:
cleanup(desc);
return rv;
Expand Down Expand Up @@ -785,8 +821,8 @@ static void wdm_disconnect(struct usb_interface *intf)
unsigned long flags;

usb_deregister_dev(intf, &wdm_class);
desc = wdm_find_device(intf);
mutex_lock(&wdm_mutex);
desc = usb_get_intfdata(intf);

/* the spinlock makes sure no new urbs are generated in the callbacks */
spin_lock_irqsave(&desc->iuspin, flags);
Expand All @@ -810,7 +846,7 @@ static void wdm_disconnect(struct usb_interface *intf)
#ifdef CONFIG_PM
static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
{
struct wdm_device *desc = usb_get_intfdata(intf);
struct wdm_device *desc = wdm_find_device(intf);
int rv = 0;

dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
Expand Down Expand Up @@ -860,7 +896,7 @@ static int recover_from_urb_loss(struct wdm_device *desc)
#ifdef CONFIG_PM
static int wdm_resume(struct usb_interface *intf)
{
struct wdm_device *desc = usb_get_intfdata(intf);
struct wdm_device *desc = wdm_find_device(intf);
int rv;

dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
Expand All @@ -874,7 +910,7 @@ static int wdm_resume(struct usb_interface *intf)

static int wdm_pre_reset(struct usb_interface *intf)
{
struct wdm_device *desc = usb_get_intfdata(intf);
struct wdm_device *desc = wdm_find_device(intf);

/*
* we notify everybody using poll of
Expand All @@ -898,7 +934,7 @@ static int wdm_pre_reset(struct usb_interface *intf)

static int wdm_post_reset(struct usb_interface *intf)
{
struct wdm_device *desc = usb_get_intfdata(intf);
struct wdm_device *desc = wdm_find_device(intf);
int rv;

clear_bit(WDM_RESETTING, &desc->flags);
Expand Down

0 comments on commit 7ac3a97

Please sign in to comment.