On Thu, Apr 26, 2007 at 11:30:03AM -0700, David Brownell wrote:
>
> Looks OK except it's missing a comment about why standard
> atomic refcount utilities (kref, atomic_t, etc) must not
> be used. (That's in addition to the patch comment.)
>
Dave,
The patch to remove atomic operations on the reference counter for EHCI
is attached. Thank you.
-Steve
Signed-off-by: Steven J. Hill <[EMAIL PROTECTED]>
diff -ur linux-2.6.21.1/drivers/usb/host/ehci.h linux-2.6.21.1-patched/drivers/usb/host/ehci.h
--- linux-2.6.21.1/drivers/usb/host/ehci.h 2007-05-08 09:22:05.000000000 -0500
+++ linux-2.6.21.1-patched/drivers/usb/host/ehci.h 2007-05-08 09:31:51.000000000 -0500
@@ -418,7 +418,14 @@
struct ehci_qh *reclaim; /* next to reclaim */
struct ehci_hcd *ehci;
- struct kref kref;
+
+ /*
+ * Do NOT use atomic operations for reference counting. On some CPUs
+ * (PPC7448 for example), atomic operations cannot be performed on
+ * memory that is cache-inhibited (i.e. being used for DMA). Currently
+ * spinlocks are sufficient to protect the counter.
+ */
+ u32 refcount;
unsigned stamp;
u8 qh_state;
diff -ur linux-2.6.21.1/drivers/usb/host/ehci-mem.c linux-2.6.21.1-patched/drivers/usb/host/ehci-mem.c
--- linux-2.6.21.1/drivers/usb/host/ehci-mem.c 2007-02-04 12:44:54.000000000 -0600
+++ linux-2.6.21.1-patched/drivers/usb/host/ehci-mem.c 2007-05-08 09:31:51.000000000 -0500
@@ -63,9 +63,8 @@
}
-static void qh_destroy (struct kref *kref)
+static void qh_destroy (struct ehci_qh *qh)
{
- struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref);
struct ehci_hcd *ehci = qh->ehci;
/* clean qtds first, and know this is not linked */
@@ -89,7 +88,7 @@
return qh;
memset (qh, 0, sizeof *qh);
- kref_init(&qh->kref);
+ qh->refcount = 1;
qh->ehci = ehci;
qh->qh_dma = dma;
// INIT_LIST_HEAD (&qh->qh_list);
@@ -108,13 +107,16 @@
/* to share a qh (cpu threads, or hc) */
static inline struct ehci_qh *qh_get (struct ehci_qh *qh)
{
- kref_get(&qh->kref);
+ WARN_ON(!qh->refcount);
+ qh->refcount++;
return qh;
}
static inline void qh_put (struct ehci_qh *qh)
{
- kref_put(&qh->kref, qh_destroy);
+ if(!(qh->refcount--)) {
+ qh_destroy(qh);
+ }
}
/*-------------------------------------------------------------------------*/
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel