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);
}
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 {
}
/**
- * 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);
+ }
}
/**
}
/**
- * 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
/* 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);
}
/**
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);
INIT_LIST_HEAD(&td->list);
INIT_LIST_HEAD(&td->fl_list);
- usb_inc_dev_use(dev);
+ usb_get_dev(dev);
return td;
}
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);
}
INIT_LIST_HEAD(&qh->list);
INIT_LIST_HEAD(&qh->remove_list);
- usb_inc_dev_use(dev);
+ usb_get_dev(dev);
return qh;
}
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);
}
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);
/* 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;
} 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);
}
}
}
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);
}
/* 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
/* 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;
}
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;
}
/* 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;
}
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;
}
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;
}
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;
}
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;
#endif
urb->hcpriv = NULL;
- usb_dec_dev_use (usb_dev);
+ usb_put_dev (usb_dev);
urb->dev = NULL;
if (urb->complete)
urb->complete (urb);
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;
urb->dev = NULL;
urb->complete ((struct urb *) urb);
}
- usb_dec_dev_use (usb_dev);
+ usb_put_dev (usb_dev);
usb_put_urb (urb);
}
else
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
/* 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);
((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
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;
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
spin_lock(&s->urb_list_lock);
}
- usb_dec_dev_use (usb_dev);
+ usb_put_dev (usb_dev);
usb_put_urb (urb);
}
}
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);
}
#endif
- usb_inc_dev_use(uvd->dev);
+ usb_get_dev(uvd->dev);
return 0;
}
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;
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,
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);
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);
flush_scheduled_tasks ();
kfree (dev);
- usb_dec_dev_use (udev);
+ usb_put_dev (udev);
}
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;
}
/* 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);
/* 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;
}
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));
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;
}
ss->transport_name = "Unknown";
kfree(ss->current_urb);
kfree(ss);
- usb_dec_dev_use(dev);
+ usb_put_dev(dev);
return NULL;
break;
}
ss->protocol_name = "Unknown";
kfree(ss->current_urb);
kfree(ss);
- usb_dec_dev_use(dev);
+ usb_put_dev(dev);
return NULL;
break;
}
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;
}
"Unable to start control thread\n");
kfree(ss->current_urb);
kfree(ss);
- usb_dec_dev_use(dev);
+ usb_put_dev(dev);
return NULL;
}
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);
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);
/* 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);
extern void usb_driver_claim_interface(struct usb_driver *driver,