Commit 8c61259d authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

USB: switch struct urb to use a kref instead of it's own atomic_t

parent c1c737a2
...@@ -13,6 +13,14 @@ ...@@ -13,6 +13,14 @@
#include <linux/usb.h> #include <linux/usb.h>
#include "hcd.h" #include "hcd.h"
#define to_urb(d) container_of(d, struct urb, kref)
static void urb_destroy(struct kref *kref)
{
struct urb *urb = to_urb(kref);
kfree(urb);
}
/** /**
* usb_init_urb - initializes a urb so that it can be used by a USB driver * usb_init_urb - initializes a urb so that it can be used by a USB driver
* @urb: pointer to the urb to initialize * @urb: pointer to the urb to initialize
...@@ -31,7 +39,7 @@ void usb_init_urb(struct urb *urb) ...@@ -31,7 +39,7 @@ void usb_init_urb(struct urb *urb)
{ {
if (urb) { if (urb) {
memset(urb, 0, sizeof(*urb)); memset(urb, 0, sizeof(*urb));
urb->count = (atomic_t)ATOMIC_INIT(1); kref_init(&urb->kref, urb_destroy);
spin_lock_init(&urb->lock); spin_lock_init(&urb->lock);
} }
} }
...@@ -80,8 +88,7 @@ struct urb *usb_alloc_urb(int iso_packets, int mem_flags) ...@@ -80,8 +88,7 @@ struct urb *usb_alloc_urb(int iso_packets, int mem_flags)
void usb_free_urb(struct urb *urb) void usb_free_urb(struct urb *urb)
{ {
if (urb) if (urb)
if (atomic_dec_and_test(&urb->count)) kref_put(&urb->kref);
kfree(urb);
} }
/** /**
...@@ -96,11 +103,9 @@ void usb_free_urb(struct urb *urb) ...@@ -96,11 +103,9 @@ void usb_free_urb(struct urb *urb)
*/ */
struct urb * usb_get_urb(struct urb *urb) struct urb * usb_get_urb(struct urb *urb)
{ {
if (urb) { if (urb)
atomic_inc(&urb->count); kref_get(&urb->kref);
return urb; return urb;
} else
return NULL;
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/delay.h> /* for mdelay() */ #include <linux/delay.h> /* for mdelay() */
#include <linux/interrupt.h> /* for in_interrupt() */ #include <linux/interrupt.h> /* for in_interrupt() */
#include <linux/list.h> /* for struct list_head */ #include <linux/list.h> /* for struct list_head */
#include <linux/kref.h> /* for struct kref */
#include <linux/device.h> /* for struct device */ #include <linux/device.h> /* for struct device */
#include <linux/fs.h> /* for struct file_operations */ #include <linux/fs.h> /* for struct file_operations */
#include <linux/completion.h> /* for struct completion */ #include <linux/completion.h> /* for struct completion */
...@@ -731,8 +732,8 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -731,8 +732,8 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
struct urb struct urb
{ {
/* private, usb core and host controller only fields in the urb */ /* private, usb core and host controller only fields in the urb */
struct kref kref; /* reference count of the URB */
spinlock_t lock; /* lock for the URB */ spinlock_t lock; /* lock for the URB */
atomic_t count; /* reference count of the URB */
void *hcpriv; /* private data for host controller */ void *hcpriv; /* private data for host controller */
struct list_head urb_list; /* list pointer to all active urbs */ struct list_head urb_list; /* list pointer to all active urbs */
int bandwidth; /* bandwidth for INT/ISO request */ int bandwidth; /* bandwidth for INT/ISO request */
......
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