ChangeSet 1.1372.2.1, 2003/07/09 17:39:41-07:00, lkml001@vrfy.org

[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.


 drivers/usb/class/usblp.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)


diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c	Thu Jul 10 16:01:48 2003
+++ b/drivers/usb/class/usblp.c	Thu Jul 10 16:01:48 2003
@@ -146,6 +146,7 @@
 	int			rcomplete;		/* reading is completed */
 	unsigned int		quirks;			/* quirks flags */
 	unsigned char		used;			/* True if open */
+	unsigned char		present;		/* True if not disconnected */
 	unsigned char		bidir;			/* interface is bidirectional */
 	unsigned char		*device_id_string;	/* IEEE 1284 DEVICE ID string (ptr) */
 							/* first 2 bytes are (big-endian) length */
@@ -157,6 +158,7 @@
 
 	dbg("usblp=0x%p", usblp);
 	dbg("dev=0x%p", usblp->dev);
+	dbg("present=%d", usblp->present);
 	dbg("buf=0x%p", usblp->buf);
 	dbg("readcount=%d", usblp->readcount);
 	dbg("ifnum=%d", usblp->ifnum);
@@ -253,7 +255,7 @@
 {
 	struct usblp *usblp = urb->context;
 
-	if (!usblp || !usblp->dev || !usblp->used)
+	if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
 		return;
 
 	if (unlikely(urb->status))
@@ -267,7 +269,7 @@
 {
 	struct usblp *usblp = urb->context;
 
-	if (!usblp || !usblp->dev || !usblp->used)
+	if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
 		return;
 
 	if (unlikely(urb->status))
@@ -332,7 +334,7 @@
 		goto out;
 	}
 	usblp = usb_get_intfdata (intf);
-	if (!usblp || !usblp->dev)
+	if (!usblp || !usblp->dev || !usblp->present)
 		goto out;
 
 	retval = -EBUSY;
@@ -404,7 +406,7 @@
 	down (&usblp->sem);
 	lock_kernel();
 	usblp->used = 0;
-	if (usblp->dev) {
+	if (usblp->present) {
 		usblp_unlink_urbs(usblp);
 		up(&usblp->sem);
 	} else 		/* finish cleanup from disconnect */
@@ -432,7 +434,7 @@
 	int retval = 0;
 
 	down (&usblp->sem);
-	if (!usblp->dev) {
+	if (!usblp->present) {
 		retval = -ENODEV;
 		goto done;
 	}
@@ -630,7 +632,7 @@
 		}
 
 		down (&usblp->sem);
-		if (!usblp->dev) {
+		if (!usblp->present) {
 			up (&usblp->sem);
 			return -ENODEV;
 		}
@@ -691,7 +693,7 @@
 		return -EINVAL;
 
 	down (&usblp->sem);
-	if (!usblp->dev) {
+	if (!usblp->present) {
 		count = -ENODEV;
 		goto done;
 	}
@@ -726,7 +728,7 @@
 		remove_wait_queue(&usblp->wait, &wait);
 	}
 
-	if (!usblp->dev) {
+	if (!usblp->present) {
 		count = -ENODEV;
 		goto done;
 	}
@@ -916,6 +918,8 @@
 
 	usb_set_intfdata (intf, usblp);
 
+	usblp->present = 1;
+
 	return 0;
 
 abort_minor:
@@ -1115,14 +1119,14 @@
 
 	down (&usblp->sem);
 	lock_kernel();
-	usblp->dev = NULL;
+	usblp->present = 0;
 	usb_set_intfdata (intf, NULL);
 
 	usblp_unlink_urbs(usblp);
 
 	if (!usblp->used)
 		usblp_cleanup (usblp);
-	else 	/* cleanup later, on close */
+	else 	/* cleanup later, on release */
 		up (&usblp->sem);
 	unlock_kernel();
 }
