]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/host/ehci-mem.c
Merge branch 'linus' into x86/timers
[linux-2.6-omap-h63xx.git] / drivers / usb / host / ehci-mem.c
index 766061e0260a5e96d6258149bc6f7f8a31f71ee9..0431397836f65e859f1a2b1829f418fa3697f65d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2001 by David Brownell
- * 
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  * Free Software Foundation; either version 2 of the License, or (at your
@@ -25,9 +25,9 @@
  *     - data used only by the HCD ... kmalloc is fine
  *     - async and periodic schedules, shared by HC and HCD ... these
  *       need to use dma_pool or dma_alloc_coherent
- *     - driver buffers, read/written by HC ... single shot DMA mapped 
+ *     - driver buffers, read/written by HC ... single shot DMA mapped
  *
- * There's also PCI "register" data, which is memory mapped.
+ * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
  * No memory seen by this driver is pageable.
  */
 
 
 /* Allocate the key transfer structures from the previously allocated pool */
 
-static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
+static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
+                                 dma_addr_t dma)
 {
        memset (qtd, 0, sizeof *qtd);
        qtd->qtd_dma = dma;
        qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
-       qtd->hw_next = EHCI_LIST_END;
-       qtd->hw_alt_next = EHCI_LIST_END;
+       qtd->hw_next = EHCI_LIST_END(ehci);
+       qtd->hw_alt_next = EHCI_LIST_END(ehci);
        INIT_LIST_HEAD (&qtd->qtd_list);
 }
 
@@ -52,7 +53,7 @@ static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
 
        qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
        if (qtd != NULL) {
-               ehci_qtd_init (qtd, dma);
+               ehci_qtd_init(ehci, qtd, dma);
        }
        return qtd;
 }
@@ -63,9 +64,8 @@ static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
 }
 
 
-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 +89,7 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
                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,18 +108,20 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
 /* 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);
 }
 
 /*-------------------------------------------------------------------------*/
 
-/* The queue heads and transfer descriptors are managed from pools tied 
+/* The queue heads and transfer descriptors are managed from pools tied
  * to each of the "per device" structures.
  * This is the initialisation and cleanup code.
  */
@@ -165,7 +167,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
        int i;
 
        /* QTDs for control/bulk/intr transfers */
-       ehci->qtd_pool = dma_pool_create ("ehci_qtd", 
+       ehci->qtd_pool = dma_pool_create ("ehci_qtd",
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_qtd),
                        32 /* byte alignment (for hw parts) */,
@@ -175,7 +177,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
        }
 
        /* QHs for control/bulk/intr transfers */
-       ehci->qh_pool = dma_pool_create ("ehci_qh", 
+       ehci->qh_pool = dma_pool_create ("ehci_qh",
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_qh),
                        32 /* byte alignment (for hw parts) */,
@@ -189,7 +191,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
        }
 
        /* ITD for high speed ISO transfers */
-       ehci->itd_pool = dma_pool_create ("ehci_itd", 
+       ehci->itd_pool = dma_pool_create ("ehci_itd",
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_itd),
                        32 /* byte alignment (for hw parts) */,
@@ -199,7 +201,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
        }
 
        /* SITD for full/low speed split ISO transfers */
-       ehci->sitd_pool = dma_pool_create ("ehci_sitd", 
+       ehci->sitd_pool = dma_pool_create ("ehci_sitd",
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_sitd),
                        32 /* byte alignment (for hw parts) */,
@@ -217,7 +219,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
                goto fail;
        }
        for (i = 0; i < ehci->periodic_size; i++)
-               ehci->periodic [i] = EHCI_LIST_END;
+               ehci->periodic [i] = EHCI_LIST_END(ehci);
 
        /* software shadow of hardware table */
        ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags);