# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.546   -> 1.547  
#	drivers/usb/net/usbnet.c	1.22    -> 1.23   
#	drivers/usb/net/cdc-ether.c	1.11    -> 1.12   
#	drivers/usb/host/usb-ohci.c	1.33    -> 1.34   
#	drivers/usb/storage/usb.c	1.19    -> 1.20   
#	 include/linux/usb.h	1.32    -> 1.33   
#	drivers/usb/host/usb-uhci.c	1.33    -> 1.34   
#	drivers/usb/media/usbvideo.c	1.18    -> 1.19   
#	drivers/usb/core/usb.c	1.53    -> 1.54   
#	drivers/usb/core/hcd.c	1.16    -> 1.17   
#	drivers/usb/host/uhci.c	1.42    -> 1.43   
#	drivers/usb/net/pegasus.c	1.26    -> 1.27   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/05/13	greg@kroah.com	1.547
# [PATCH] USB device reference counting api cleanup changes
# 
# This patch replaces the awkwardly named usb_inc_dev_use() and
# usb_dec_dev_use() with usb_get_dev() and usb_put_dev() to match the
# naming convention of the rest of the kernel's reference counted
# structures.  It also does away with the special case of usb_free_dev(),
# and has usb_put_dev() be the same thing (through a #define, just like
# usb_free_urb() works.)
# 
# Now when the last person calls usb_put_dev() or usb_free_dev() the
# structure is cleaned up.  This allows the different host controller
# drivers to implement their logic differently if they want to (as they
# do), and everyone can be happy and stop arguing about the "proper" way
# to write their host controller drivers :)
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/core/hcd.c	Mon May 13 15:53:46 2002
@@ -1320,7 +1320,7 @@
 	list_del_init (&urb->urb_list);
 	dev = urb->dev;
 	urb->dev = NULL;
-	usb_dec_dev_use (dev);
+	usb_put_dev (dev);
 	spin_unlock_irqrestore (&hcd_data_lock, flags);
 }
 
@@ -1516,7 +1516,7 @@
 
 	spin_lock_irqsave (&hcd_data_lock, flags);
 	if (HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_QUIESCING) {
-		usb_inc_dev_use (urb->dev);
+		usb_get_dev (urb->dev);
 		list_add (&urb->urb_list, &dev->urb_list);
 		status = 0;
 	} else {
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/core/usb.c	Mon May 13 15:53:46 2002
@@ -969,21 +969,47 @@
 }
 
 /**
- * usb_free_dev - free a usb device structure (usbcore-internal)
+ * usb_get_dev - increments the reference count of the device
+ * @dev: the device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for USB interfaces should normally record such references in
+ * their probe() methods, when they bind to an interface, and release
+ * them by calling usb_put_dev(), in their disconnect() methods.
+ *
+ * A pointer to the device with the incremented reference counter is returned.
+ */
+struct usb_device *usb_get_dev (struct usb_device *dev)
+{
+	if (dev) {
+		atomic_inc (&dev->refcnt);
+		return dev;
+	}
+	return NULL;
+}
+
+/**
+ * usb_free_dev - free a usb device structure when all users of it are finished.
  * @dev: device that's been disconnected
  * Context: !in_interrupt ()
  *
+ * Must be called when a user of a device is finished with it.  When the last
+ * user of the device calls this function, the memory of the device is freed.
+ *
  * Used by hub and virtual root hub drivers.  The device is completely
  * gone, everything is cleaned up, so it's time to get rid of these last
  * records of this device.
  */
 void usb_free_dev(struct usb_device *dev)
 {
-	if (dev->bus->op->deallocate)
-		dev->bus->op->deallocate(dev);
-	usb_destroy_configuration (dev);
-	usb_bus_put (dev->bus);
-	kfree (dev);
+	if (atomic_dec_and_test(&dev->refcnt)) {
+		if (dev->bus->op->deallocate)
+			dev->bus->op->deallocate(dev);
+		usb_destroy_configuration (dev);
+		usb_bus_put (dev->bus);
+		kfree (dev);
+	}
 }
 
 /**
@@ -1039,7 +1065,7 @@
 }
 
 /**
- * usb_get_urb - incrementes the reference count of the urb
+ * usb_get_urb - increments the reference count of the urb
  * @urb: pointer to the urb to modify
  *
  * This must be  called whenever a urb is transfered from a device driver to a
@@ -1928,7 +1954,7 @@
 
 	/* Decrement the reference count, it'll auto free everything when */
 	/* it hits 0 which could very well be now */
-	usb_dec_dev_use(dev);
+	usb_put_dev(dev);
 }
 
 /**
@@ -2760,6 +2786,7 @@
 
 EXPORT_SYMBOL(usb_alloc_dev);
 EXPORT_SYMBOL(usb_free_dev);
+EXPORT_SYMBOL(usb_get_dev);
 EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
 
 EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum);
diff -Nru a/drivers/usb/host/uhci.c b/drivers/usb/host/uhci.c
--- a/drivers/usb/host/uhci.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/host/uhci.c	Mon May 13 15:53:46 2002
@@ -165,7 +165,7 @@
 	INIT_LIST_HEAD(&td->list);
 	INIT_LIST_HEAD(&td->fl_list);
 
-	usb_inc_dev_use(dev);
+	usb_get_dev(dev);
 
 	return td;
 }
@@ -317,7 +317,7 @@
 		dbg("td is still in URB list!");
 
 	if (td->dev)
-		usb_dec_dev_use(td->dev);
+		usb_put_dev(td->dev);
 
 	pci_pool_free(uhci->td_pool, td, td->dma_handle);
 }
@@ -342,7 +342,7 @@
 	INIT_LIST_HEAD(&qh->list);
 	INIT_LIST_HEAD(&qh->remove_list);
 
-	usb_inc_dev_use(dev);
+	usb_get_dev(dev);
 
 	return qh;
 }
@@ -355,7 +355,7 @@
 		dbg("qh still in remove_list!");
 
 	if (qh->dev)
-		usb_dec_dev_use(qh->dev);
+		usb_put_dev(qh->dev);
 
 	pci_pool_free(uhci->qh_pool, qh, qh->dma_handle);
 }
@@ -1492,7 +1492,7 @@
 	uhci = (struct uhci *)urb->dev->bus->hcpriv;
 
 	INIT_LIST_HEAD(&urb->urb_list);
-	usb_inc_dev_use(urb->dev);
+	usb_get_dev(urb->dev);
 
 	spin_lock_irqsave(&uhci->urb_list_lock, flags);
 	spin_lock(&urb->lock);
@@ -1503,7 +1503,7 @@
 		/* Since we can have problems on the out path */
 		spin_unlock(&urb->lock);
 		spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
-		usb_dec_dev_use(urb->dev);
+		usb_put_dev(urb->dev);
 		usb_put_urb(urb);
 
 		return ret;
@@ -2376,7 +2376,7 @@
 		} else {
 			/* We decrement the usage count after we're done */
 			/*  with everything */
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			usb_put_urb(urb);
 		}
 	}
diff -Nru a/drivers/usb/host/usb-ohci.c b/drivers/usb/host/usb-ohci.c
--- a/drivers/usb/host/usb-ohci.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/host/usb-ohci.c	Mon May 13 15:53:46 2002
@@ -210,7 +210,7 @@
 		}
 
 		urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv);
-		usb_dec_dev_use (urb->dev);
+		usb_put_dev (urb->dev);
 		urb->dev = NULL;
 		usb_put_urb (urb);
 	}
@@ -563,7 +563,7 @@
 	/* increment the reference count of the urb, as we now also control it */
 	urb = usb_get_urb (urb);
 
-	usb_inc_dev_use (urb->dev);
+	usb_get_dev (urb->dev);
 	ohci = (ohci_t *) urb->dev->bus->hcpriv;
 	
 #ifdef DEBUG
@@ -577,14 +577,14 @@
 	/* when controller's hung, permit only roothub cleanup attempts
 	 * such as powering down ports */
 	if (ohci->disabled) {
-		usb_dec_dev_use (urb->dev);	
+		usb_put_dev (urb->dev);	
 		usb_put_urb (urb);
 		return -ESHUTDOWN;
 	}
 
 	/* every endpoint has a ed, locate and fill it */
 	if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) {
-		usb_dec_dev_use (urb->dev);	
+		usb_put_dev (urb->dev);	
 		usb_put_urb (urb);
 		return -ENOMEM;
 	}
@@ -606,7 +606,7 @@
 		case PIPE_ISOCHRONOUS: /* number of packets from URB */
 			size = urb->number_of_packets;
 			if (size <= 0) {
-				usb_dec_dev_use (urb->dev);	
+				usb_put_dev (urb->dev);	
 				usb_put_urb (urb);
 				return -EINVAL;
 			}
@@ -627,7 +627,7 @@
 	/* allocate the private part of the URB */
 	urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags);
 	if (!urb_priv) {
-		usb_dec_dev_use (urb->dev);	
+		usb_put_dev (urb->dev);	
 		usb_put_urb (urb);
 		return -ENOMEM;
 	}
@@ -645,7 +645,7 @@
 			urb_priv->length = i;
 			urb_free_priv (ohci, urb_priv);
 			spin_unlock_irqrestore (&usb_ed_lock, flags);
-			usb_dec_dev_use (urb->dev);	
+			usb_put_dev (urb->dev);	
 			usb_put_urb (urb);
 			return -ENOMEM;
 		}
@@ -654,7 +654,7 @@
 	if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
 		urb_free_priv (ohci, urb_priv);
 		spin_unlock_irqrestore (&usb_ed_lock, flags);
-		usb_dec_dev_use (urb->dev);	
+		usb_put_dev (urb->dev);	
 		usb_put_urb (urb);
 		return -EINVAL;
 	}
@@ -677,7 +677,7 @@
 			if (bustime < 0) {
 				urb_free_priv (ohci, urb_priv);
 				spin_unlock_irqrestore (&usb_ed_lock, flags);
-				usb_dec_dev_use (urb->dev);	
+				usb_put_dev (urb->dev);	
 				usb_put_urb (urb);
 				return bustime;
 			}
@@ -802,7 +802,7 @@
 					return -ETIMEDOUT;
 				}
 			} else {
-				/* usb_dec_dev_use done in dl_del_list() */
+				/* usb_put_dev done in dl_del_list() */
 				urb->status = -EINPROGRESS;
 				spin_unlock_irqrestore (&usb_ed_lock, flags);
 				return -EINPROGRESS;
@@ -2109,7 +2109,7 @@
 #endif
 
 	urb->hcpriv = NULL;
-	usb_dec_dev_use (usb_dev);
+	usb_put_dev (usb_dev);
 	urb->dev = NULL;
 	if (urb->complete)
 	    	urb->complete (urb);
@@ -2129,7 +2129,7 @@
 		ohci->rh.urb = NULL;
 
 		urb->hcpriv = NULL;
-		usb_dec_dev_use(urb->dev);
+		usb_put_dev (urb->dev);
 		urb->dev = NULL;
 		if (urb->transfer_flags & USB_ASYNC_UNLINK) {
 			urb->status = -ECONNRESET;
diff -Nru a/drivers/usb/host/usb-uhci.c b/drivers/usb/host/usb-uhci.c
--- a/drivers/usb/host/usb-uhci.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/host/usb-uhci.c	Mon May 13 15:53:46 2002
@@ -1217,7 +1217,7 @@
 			urb->dev = NULL;
 			urb->complete ((struct urb *) urb);
 		}
-		usb_dec_dev_use (usb_dev);
+		usb_put_dev (usb_dev);
 		usb_put_urb (urb);
 	}
 	else
@@ -1301,7 +1301,7 @@
 	
 			uhci_urb_dma_unmap(s, urb, urb_priv);
 
-			usb_dec_dev_use (dev);
+			usb_put_dev (dev);
 #ifdef DEBUG_SLAB
 			kmem_cache_free (urb_priv_kmem, urb_priv);
 #else
@@ -1655,7 +1655,7 @@
 	/* increment the reference count of the urb, as we now also control it */
 	urb = usb_get_urb (urb);
 
-	usb_inc_dev_use (urb->dev);
+	usb_get_dev (urb->dev);
 
 	spin_lock_irqsave (&s->urb_list_lock, flags);
 
@@ -1669,7 +1669,7 @@
 		    ((type == PIPE_BULK) &&
 		     (!(urb->transfer_flags & USB_QUEUE_BULK) || !(queued_urb->transfer_flags & USB_QUEUE_BULK)))) {
 			spin_unlock_irqrestore (&s->urb_list_lock, flags);
-			usb_dec_dev_use (urb->dev);
+			usb_put_dev (urb->dev);
 			usb_put_urb (urb);
 			err("ENXIO %08x, flags %x, urb %p, burb %p",urb->pipe,urb->transfer_flags,urb,queued_urb);
 			return -ENXIO;	// urb already queued
@@ -1682,7 +1682,7 @@
 	urb_priv = kmalloc (sizeof (urb_priv_t), mem_flags);
 #endif
 	if (!urb_priv) {
-		usb_dec_dev_use (urb->dev);
+		usb_put_dev (urb->dev);
 		spin_unlock_irqrestore (&s->urb_list_lock, flags);
 		usb_put_urb (urb);
 		return -ENOMEM;
@@ -1767,7 +1767,7 @@
 	
 	if (ret != 0) {
 		uhci_urb_dma_unmap(s, urb, urb_priv);
-		usb_dec_dev_use (urb->dev);
+		usb_put_dev (urb->dev);
 #ifdef DEBUG_SLAB
 		kmem_cache_free(urb_priv_kmem, urb_priv);
 #else
@@ -2737,7 +2737,7 @@
 				spin_lock(&s->urb_list_lock);
 			}
 			
-			usb_dec_dev_use (usb_dev);
+			usb_put_dev (usb_dev);
 			usb_put_urb (urb);
 		}
 	}
diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
--- a/drivers/usb/media/usbvideo.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/media/usbvideo.c	Mon May 13 15:53:46 2002
@@ -970,7 +970,7 @@
 	for (i=0; i < USBVIDEO_NUMSBUF; i++)
 		usb_free_urb(uvd->sbuf[i].urb);
 
-	usb_dec_dev_use(uvd->dev);
+	usb_put_dev(uvd->dev);
 	uvd->dev = NULL;    	    /* USB device is no more */
 
 	video_unregister_device(&uvd->vdev);
@@ -1176,7 +1176,7 @@
 	}
 #endif
 
-	usb_inc_dev_use(uvd->dev);
+	usb_get_dev(uvd->dev);
 	return 0;
 }
 
diff -Nru a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c
--- a/drivers/usb/net/cdc-ether.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/net/cdc-ether.c	Mon May 13 15:53:46 2002
@@ -1256,7 +1256,7 @@
 	                            ether_dev );
 
 	// Does this REALLY do anything???
-	usb_inc_dev_use( usb );
+	usb_get_dev( usb );
 
 	// TODO - last minute HACK
 	ether_dev->comm_ep_in = 5;
@@ -1298,7 +1298,7 @@
 	ether_dev->net = NULL;
 
 	// I ask again, does this do anything???
-	usb_dec_dev_use( usb );
+	usb_put_dev( usb );
 
 	// We are done with this interface
 	usb_driver_release_interface( &CDCEther_driver, 
diff -Nru a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
--- a/drivers/usb/net/pegasus.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/net/pegasus.c	Mon May 13 15:53:46 2002
@@ -981,7 +981,7 @@
 		return NULL;
 	}
 
-	usb_inc_dev_use(dev);
+	usb_get_dev(dev);
 	memset(pegasus, 0, sizeof(struct pegasus));
 	pegasus->dev_index = dev_index;
 	init_waitqueue_head(&pegasus->ctrl_wait);
@@ -1086,7 +1086,7 @@
 
 	pegasus->flags |= PEGASUS_UNPLUG;
 	unregister_netdev(pegasus->net);
-	usb_dec_dev_use(dev);
+	usb_put_dev(dev);
 	usb_unlink_urb(pegasus->intr_urb);
 	usb_unlink_urb(pegasus->tx_urb);
 	usb_unlink_urb(pegasus->rx_urb);
diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/net/usbnet.c	Mon May 13 15:53:46 2002
@@ -1951,7 +1951,7 @@
 	flush_scheduled_tasks ();
 
 	kfree (dev);
-	usb_dec_dev_use (udev);
+	usb_put_dev (udev);
 }
 
 
@@ -1997,7 +1997,7 @@
 	memset (dev, 0, sizeof *dev);
 
 	init_MUTEX_LOCKED (&dev->mutex);
-	usb_inc_dev_use (udev);
+	usb_get_dev (udev);
 	dev->udev = udev;
 	dev->driver_info = info;
 	dev->msg_level = msg_level;
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	Mon May 13 15:53:46 2002
+++ b/drivers/usb/storage/usb.c	Mon May 13 15:53:46 2002
@@ -676,7 +676,7 @@
 	}
 
 	/* At this point, we're committed to using the device */
-	usb_inc_dev_use(dev);
+	usb_get_dev(dev);
 
 	/* clear the GUID and fetch the strings */
 	GUID_CLEAR(guid);
@@ -735,14 +735,14 @@
 
 		/* allocate an IRQ callback if one is needed */
 		if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) {
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 		}
 
 		/* allocate the URB we're going to use */
 		ss->current_urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!ss->current_urb) {
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 		}
 
@@ -760,7 +760,7 @@
 		if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), 
 						    GFP_KERNEL)) == NULL) {
 			printk(KERN_WARNING USB_STORAGE "Out of memory\n");
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 		}
 		memset(ss, 0, sizeof(struct us_data));
@@ -769,7 +769,7 @@
 		ss->current_urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!ss->current_urb) {
 			kfree(ss);
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 		}
 
@@ -919,7 +919,7 @@
 			ss->transport_name = "Unknown";
 			kfree(ss->current_urb);
 			kfree(ss);
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 			break;
 		}
@@ -974,7 +974,7 @@
 			ss->protocol_name = "Unknown";
 			kfree(ss->current_urb);
 			kfree(ss);
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 			break;
 		}
@@ -984,7 +984,7 @@
 		if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) {
 			kfree(ss->current_urb);
 			kfree(ss);
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 		}
 
@@ -1020,7 +1020,7 @@
 			       "Unable to start control thread\n");
 			kfree(ss->current_urb);
 			kfree(ss);
-			usb_dec_dev_use(dev);
+			usb_put_dev(dev);
 			return NULL;
 		}
 
@@ -1087,7 +1087,7 @@
 	ss->current_urb = NULL;
 
 	/* mark the device as gone */
-	usb_dec_dev_use(ss->pusb_dev);
+	usb_put_dev(ss->pusb_dev);
 	ss->pusb_dev = NULL;
 	atomic_set(&ss->sm_state, US_STATE_DETACHED);
 
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Mon May 13 15:53:46 2002
+++ b/include/linux/usb.h	Mon May 13 15:53:46 2002
@@ -426,10 +426,10 @@
 	struct usb_device *children[USB_MAXCHILDREN];
 };
 
-/* usb_free_dev can be called anywhere from usb_dec_dev_use */
-extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
-	struct usb_bus *);
+extern struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *);
+extern struct usb_device *usb_get_dev(struct usb_device *dev);
 extern void usb_free_dev(struct usb_device *);
+#define usb_put_dev usb_free_dev
 
 /* for when layers above USB add new non-USB drivers */
 extern void usb_scan_devices(void);
@@ -439,34 +439,6 @@
 
 /* for drivers using iso endpoints */
 extern int usb_get_current_frame_number (struct usb_device *usb_dev);
-
-/**
- * usb_inc_dev_use - record another reference to a device
- * @dev: the device being referenced
- *
- * Each live reference to a device should be refcounted.
- *
- * Drivers for USB interfaces should normally record such references in
- * their probe() methods, when they bind to an interface, and release
- * them usb_dec_dev_use(), in their disconnect() methods.
- */
-static inline void usb_inc_dev_use (struct usb_device *dev)
-{
-	atomic_inc (&dev->refcnt);
-}
-
-/**
- * usb_dec_dev_use - drop a reference to a device
- * @dev: the device no longer being referenced
- *
- * Each live reference to a device should be refcounted.
- */
-static inline void usb_dec_dev_use (struct usb_device *dev)
-{
-	if (atomic_dec_and_test(&dev->refcnt))
-		usb_free_dev(dev);
-}
-
 
 /* used these for multi-interface device registration */
 extern int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int ifnum);
