Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 185340
b: refs/heads/master
c: 554f769
h: refs/heads/master
v: v3
  • Loading branch information
Oliver Neukum authored and Greg Kroah-Hartman committed Mar 2, 2010
1 parent c7dce58 commit 9c43f70
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 20 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: 08add0c780b9f5c35de49d83abb7a4e14a9cd457
refs/heads/master: 554f76962d3a6eb5110415f1591aca83f96a84ae
28 changes: 9 additions & 19 deletions trunk/drivers/usb/core/devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ static const char *format_endpt =
*/

static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq);
/* guarded by usbfs_mutex */
static unsigned int conndiscevcnt;

/* this struct stores the poll state for <mountpoint>/devices pollers */
Expand Down Expand Up @@ -156,7 +157,9 @@ static const struct class_info clas_info[] =

void usbfs_conn_disc_event(void)
{
mutex_lock(&usbfs_mutex);
conndiscevcnt++;
mutex_unlock(&usbfs_mutex);
wake_up(&deviceconndiscwq);
}

Expand Down Expand Up @@ -629,42 +632,29 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
static unsigned int usb_device_poll(struct file *file,
struct poll_table_struct *wait)
{
struct usb_device_status *st = file->private_data;
struct usb_device_status *st;
unsigned int mask = 0;

lock_kernel();
mutex_lock(&usbfs_mutex);
st = file->private_data;
if (!st) {
st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);

/* we may have dropped BKL -
* need to check for having lost the race */
if (file->private_data) {
kfree(st);
st = file->private_data;
goto lost_race;
}
/* we haven't lost - check for allocation failure now */
if (!st) {
unlock_kernel();
mutex_unlock(&usbfs_mutex);
return POLLIN;
}

/*
* need to prevent the module from being unloaded, since
* proc_unregister does not call the release method and
* we would have a memory leak
*/
st->lastev = conndiscevcnt;
file->private_data = st;
mask = POLLIN;
}
lost_race:

if (file->f_mode & FMODE_READ)
poll_wait(file, &deviceconndiscwq, wait);
if (st->lastev != conndiscevcnt)
mask |= POLLIN;
st->lastev = conndiscevcnt;
unlock_kernel();
mutex_unlock(&usbfs_mutex);
return mask;
}

Expand Down

0 comments on commit 9c43f70

Please sign in to comment.