Hi,

Here's a patch against 2.6.6-rc2 that replaces the use of atomic_t in
the ehci driver with a kref.  It builds for for me here, any objections
to me adding it to the main kernel tree?

thanks,

greg k-h


===== drivers/usb/host/ehci-hcd.c 1.113 vs edited =====
--- 1.113/drivers/usb/host/ehci-hcd.c   Thu Apr 22 02:04:21 2004
+++ edited/drivers/usb/host/ehci-hcd.c  Tue Apr 27 08:50:10 2004
@@ -965,7 +965,7 @@
                goto rescan;
        case QH_STATE_IDLE:             /* fully unlinked */
                if (list_empty (&qh->qtd_list)) {
-                       qh_put (ehci, qh);
+                       qh_put (qh);
                        break;
                }
                /* else FALL THROUGH */
===== drivers/usb/host/ehci-mem.c 1.29 vs edited =====
--- 1.29/drivers/usb/host/ehci-mem.c    Fri Feb 27 10:09:16 2004
+++ edited/drivers/usb/host/ehci-mem.c  Tue Apr 27 08:48:48 2004
@@ -87,6 +87,22 @@
 }
 
 
+static void qh_destroy (struct kref *kref)
+{
+       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 */
+       if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
+               ehci_dbg (ehci, "unused qh not empty!\n");
+               BUG ();
+       }
+       if (qh->dummy)
+               ehci_qtd_free (ehci, qh->dummy);
+       usb_put_dev (qh->dev);
+       dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+}
+
 static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
 {
        struct ehci_qh          *qh;
@@ -98,7 +114,8 @@
                return qh;
 
        memset (qh, 0, sizeof *qh);
-       atomic_set (&qh->refcount, 1);
+       kref_init(&qh->kref, qh_destroy);
+       qh->ehci = ehci;
        qh->qh_dma = dma;
        // INIT_LIST_HEAD (&qh->qh_list);
        INIT_LIST_HEAD (&qh->qtd_list);
@@ -116,23 +133,13 @@
 /* to share a qh (cpu threads, or hc) */
 static inline struct ehci_qh *qh_get (/* ehci, */ struct ehci_qh *qh)
 {
-       atomic_inc (&qh->refcount);
+       kref_get(&qh->kref);
        return qh;
 }
 
-static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
+static void qh_put (struct ehci_qh *qh)
 {
-       if (!atomic_dec_and_test (&qh->refcount))
-               return;
-       /* clean qtds first, and know this is not linked */
-       if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
-               ehci_dbg (ehci, "unused qh not empty!\n");
-               BUG ();
-       }
-       if (qh->dummy)
-               ehci_qtd_free (ehci, qh->dummy);
-       usb_put_dev (qh->dev);
-       dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+       kref_put(&qh->kref);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -145,7 +152,7 @@
 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
 {
        if (ehci->async)
-               qh_put (ehci, ehci->async);
+               qh_put (ehci->async);
        ehci->async = 0;
 
        /* DMA consistent memory and pools */
===== drivers/usb/host/ehci-q.c 1.92 vs edited =====
--- 1.92/drivers/usb/host/ehci-q.c      Thu Apr 15 09:22:34 2004
+++ edited/drivers/usb/host/ehci-q.c    Tue Apr 27 08:49:45 2004
@@ -193,7 +193,7 @@
                        /* ... update hc-wide periodic stats (for usbfs) */
                        hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--;
                }
-               qh_put (ehci, qh);
+               qh_put (qh);
        }
 
        spin_lock (&urb->lock);
@@ -708,7 +708,7 @@
        default:
                dbg ("bogus dev %p speed %d", urb->dev, urb->dev->speed);
 done:
-               qh_put (ehci, qh);
+               qh_put (qh);
                return 0;
        }
 
@@ -951,7 +951,7 @@
        // qh->hw_next = cpu_to_le32 (qh->qh_dma);
        qh->qh_state = QH_STATE_IDLE;
        qh->qh_next.qh = 0;
-       qh_put (ehci, qh);                      // refcount from reclaim 
+       qh_put (qh);                    // refcount from reclaim 
 
        /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */
        next = qh->reclaim;
@@ -965,7 +965,7 @@
                        && HCD_IS_RUNNING (ehci->hcd.state))
                qh_link_async (ehci, qh);
        else {
-               qh_put (ehci, qh);              // refcount from async list
+               qh_put (qh);            // refcount from async list
 
                /* it's not free to turn the async schedule on/off; leave it
                 * active but idle for a while once it empties.
@@ -1067,7 +1067,7 @@
                                qh = qh_get (qh);
                                qh->stamp = ehci->stamp;
                                temp = qh_completions (ehci, qh, regs);
-                               qh_put (ehci, qh);
+                               qh_put (qh);
                                if (temp != 0) {
                                        goto rescan;
                                }
===== drivers/usb/host/ehci-sched.c 1.57 vs edited =====
--- 1.57/drivers/usb/host/ehci-sched.c  Wed Mar 17 11:16:48 2004
+++ edited/drivers/usb/host/ehci-sched.c        Tue Apr 27 08:49:10 2004
@@ -312,7 +312,7 @@
 
        do {
                periodic_unlink (ehci, frame, qh);
-               qh_put (ehci, qh);
+               qh_put (qh);
                frame += qh->period;
        } while (frame < ehci->periodic_size);
 
@@ -355,7 +355,7 @@
 
        dbg ("descheduled qh %p, period = %d frame = %d count = %d, urbs = %d",
                qh, qh->period, frame,
-               atomic_read (&qh->refcount), ehci->periodic_sched);
+               atomic_read (&qh->kref.refcount), ehci->periodic_sched);
 }
 
 static int check_period (
@@ -1846,7 +1846,7 @@
                                modified = qh_completions (ehci, temp.qh, regs);
                                if (unlikely (list_empty (&temp.qh->qtd_list)))
                                        intr_deschedule (ehci, temp.qh, 0);
-                               qh_put (ehci, temp.qh);
+                               qh_put (temp.qh);
                                break;
                        case Q_TYPE_FSTN:
                                /* for "save place" FSTNs, look at QH entries
===== drivers/usb/host/ehci.h 1.50 vs edited =====
--- 1.50/drivers/usb/host/ehci.h        Thu Apr 15 09:22:34 2004
+++ edited/drivers/usb/host/ehci.h      Tue Apr 27 08:46:04 2004
@@ -366,7 +366,8 @@
        struct ehci_qtd         *dummy;
        struct ehci_qh          *reclaim;       /* next to reclaim */
 
-       atomic_t                refcount;
+       struct ehci_hcd         *ehci;
+       struct kref             kref;
        unsigned                stamp;
 
        u8                      qh_state;


-------------------------------------------------------
This SF.net email is sponsored by: The Robotic Monkeys at ThinkGeek
For a limited time only, get FREE Ground shipping on all orders of $35
or more. Hurry up and shop folks, this offer expires April 30th!
http://www.thinkgeek.com/freeshipping/?cpg=12297
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to