Commit a1a5d792 authored by Kay Sievers's avatar Kay Sievers Committed by Greg Kroah-Hartman

[PATCH] usblp: usb_buffer_free() not called

Here is the blind flight :-)
===
drivers/usb/class/usblp.c
usblp->dev was set to NULL to indicate a device disconnect but we need
this value for usb_buffer_free() when device is still opened and cleanup
is delayed until usblp_release().
We have a usblp->present now for preventing device read, write, open and ioctl.
parent 1db72c60
...@@ -146,6 +146,7 @@ struct usblp { ...@@ -146,6 +146,7 @@ struct usblp {
int rcomplete; /* reading is completed */ int rcomplete; /* reading is completed */
unsigned int quirks; /* quirks flags */ unsigned int quirks; /* quirks flags */
unsigned char used; /* True if open */ unsigned char used; /* True if open */
unsigned char present; /* True if not disconnected */
unsigned char bidir; /* interface is bidirectional */ unsigned char bidir; /* interface is bidirectional */
unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */
/* first 2 bytes are (big-endian) length */ /* first 2 bytes are (big-endian) length */
...@@ -157,6 +158,7 @@ static void usblp_dump(struct usblp *usblp) { ...@@ -157,6 +158,7 @@ static void usblp_dump(struct usblp *usblp) {
dbg("usblp=0x%p", usblp); dbg("usblp=0x%p", usblp);
dbg("dev=0x%p", usblp->dev); dbg("dev=0x%p", usblp->dev);
dbg("present=%d", usblp->present);
dbg("buf=0x%p", usblp->buf); dbg("buf=0x%p", usblp->buf);
dbg("readcount=%d", usblp->readcount); dbg("readcount=%d", usblp->readcount);
dbg("ifnum=%d", usblp->ifnum); dbg("ifnum=%d", usblp->ifnum);
...@@ -253,7 +255,7 @@ static void usblp_bulk_read(struct urb *urb, struct pt_regs *regs) ...@@ -253,7 +255,7 @@ static void usblp_bulk_read(struct urb *urb, struct pt_regs *regs)
{ {
struct usblp *usblp = urb->context; struct usblp *usblp = urb->context;
if (!usblp || !usblp->dev || !usblp->used) if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
return; return;
if (unlikely(urb->status)) if (unlikely(urb->status))
...@@ -267,7 +269,7 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs) ...@@ -267,7 +269,7 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs)
{ {
struct usblp *usblp = urb->context; struct usblp *usblp = urb->context;
if (!usblp || !usblp->dev || !usblp->used) if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
return; return;
if (unlikely(urb->status)) if (unlikely(urb->status))
...@@ -332,7 +334,7 @@ static int usblp_open(struct inode *inode, struct file *file) ...@@ -332,7 +334,7 @@ static int usblp_open(struct inode *inode, struct file *file)
goto out; goto out;
} }
usblp = usb_get_intfdata (intf); usblp = usb_get_intfdata (intf);
if (!usblp || !usblp->dev) if (!usblp || !usblp->dev || !usblp->present)
goto out; goto out;
retval = -EBUSY; retval = -EBUSY;
...@@ -404,7 +406,7 @@ static int usblp_release(struct inode *inode, struct file *file) ...@@ -404,7 +406,7 @@ static int usblp_release(struct inode *inode, struct file *file)
down (&usblp->sem); down (&usblp->sem);
lock_kernel(); lock_kernel();
usblp->used = 0; usblp->used = 0;
if (usblp->dev) { if (usblp->present) {
usblp_unlink_urbs(usblp); usblp_unlink_urbs(usblp);
up(&usblp->sem); up(&usblp->sem);
} else /* finish cleanup from disconnect */ } else /* finish cleanup from disconnect */
...@@ -432,7 +434,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -432,7 +434,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
int retval = 0; int retval = 0;
down (&usblp->sem); down (&usblp->sem);
if (!usblp->dev) { if (!usblp->present) {
retval = -ENODEV; retval = -ENODEV;
goto done; goto done;
} }
...@@ -630,7 +632,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t ...@@ -630,7 +632,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
} }
down (&usblp->sem); down (&usblp->sem);
if (!usblp->dev) { if (!usblp->present) {
up (&usblp->sem); up (&usblp->sem);
return -ENODEV; return -ENODEV;
} }
...@@ -691,7 +693,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, ...@@ -691,7 +693,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
return -EINVAL; return -EINVAL;
down (&usblp->sem); down (&usblp->sem);
if (!usblp->dev) { if (!usblp->present) {
count = -ENODEV; count = -ENODEV;
goto done; goto done;
} }
...@@ -726,7 +728,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, ...@@ -726,7 +728,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
remove_wait_queue(&usblp->wait, &wait); remove_wait_queue(&usblp->wait, &wait);
} }
if (!usblp->dev) { if (!usblp->present) {
count = -ENODEV; count = -ENODEV;
goto done; goto done;
} }
...@@ -916,6 +918,8 @@ static int usblp_probe(struct usb_interface *intf, ...@@ -916,6 +918,8 @@ static int usblp_probe(struct usb_interface *intf,
usb_set_intfdata (intf, usblp); usb_set_intfdata (intf, usblp);
usblp->present = 1;
return 0; return 0;
abort_minor: abort_minor:
...@@ -1115,14 +1119,14 @@ static void usblp_disconnect(struct usb_interface *intf) ...@@ -1115,14 +1119,14 @@ static void usblp_disconnect(struct usb_interface *intf)
down (&usblp->sem); down (&usblp->sem);
lock_kernel(); lock_kernel();
usblp->dev = NULL; usblp->present = 0;
usb_set_intfdata (intf, NULL); usb_set_intfdata (intf, NULL);
usblp_unlink_urbs(usblp); usblp_unlink_urbs(usblp);
if (!usblp->used) if (!usblp->used)
usblp_cleanup (usblp); usblp_cleanup (usblp);
else /* cleanup later, on close */ else /* cleanup later, on release */
up (&usblp->sem); up (&usblp->sem);
unlock_kernel(); unlock_kernel();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment