LCOV - code coverage report
Current view: top level - drivers/usb/host - ehci-mem.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 108 108 100.0 %
Date: 2017-01-25 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2001 by David Brownell
       3             :  *
       4             :  * This program is free software; you can redistribute it and/or modify it
       5             :  * under the terms of the GNU General Public License as published by the
       6             :  * Free Software Foundation; either version 2 of the License, or (at your
       7             :  * option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful, but
      10             :  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      11             :  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      12             :  * for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program; if not, write to the Free Software Foundation,
      16             :  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      17             :  */
      18             : 
      19             : /* this file is part of ehci-hcd.c */
      20             : 
      21             : /*-------------------------------------------------------------------------*/
      22             : 
      23             : /*
      24             :  * There's basically three types of memory:
      25             :  *      - data used only by the HCD ... kmalloc is fine
      26             :  *      - async and periodic schedules, shared by HC and HCD ... these
      27             :  *        need to use dma_pool or dma_alloc_coherent
      28             :  *      - driver buffers, read/written by HC ... single shot DMA mapped
      29             :  *
      30             :  * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
      31             :  * No memory seen by this driver is pageable.
      32             :  */
      33             : 
      34             : /*-------------------------------------------------------------------------*/
      35             : 
      36             : /* Allocate the key transfer structures from the previously allocated pool */
      37             : 
      38             : static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
      39             :                                   dma_addr_t dma)
      40             : {
      41          17 :         memset (qtd, 0, sizeof *qtd);
      42          17 :         qtd->qtd_dma = dma;
      43          17 :         qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
      44          34 :         qtd->hw_next = EHCI_LIST_END(ehci);
      45          34 :         qtd->hw_alt_next = EHCI_LIST_END(ehci);
      46          34 :         INIT_LIST_HEAD (&qtd->qtd_list);
      47          17 : }
      48             : 
      49             : static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
      50             : {
      51          13 :         struct ehci_qtd         *qtd;
      52          13 :         dma_addr_t              dma;
      53          13 : 
      54          26 :         qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
      55          26 :         if (qtd != NULL) {
      56          26 :                 ehci_qtd_init(ehci, qtd, dma);
      57             :         }
      58          26 :         return qtd;
      59             : }
      60             : 
      61             : static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
      62             : {
      63         433 :         dma_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);
      64         433 : }
      65             : 
      66             : 
      67             : static void qh_destroy(struct ehci_qh *qh)
      68             : {
      69         610 :         struct ehci_hcd *ehci = qh->ehci;
      70         305 : 
      71             :         /* clean qtds first, and know this is not linked */
      72        1830 :         if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
      73             :                 ehci_dbg (ehci, "unused qh not empty!\n");
      74         610 :                 BUG ();
      75             :         }
      76         915 :         if (qh->dummy)
      77         610 :                 ehci_qtd_free (ehci, qh->dummy);
      78        1220 :         dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma);
      79         610 :         kfree(qh);
      80         610 : }
      81             : 
      82             : static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
      83             : {
      84           5 :         struct ehci_qh          *qh;
      85           5 :         dma_addr_t              dma;
      86           5 : 
      87          20 :         qh = kzalloc(sizeof *qh, GFP_ATOMIC);
      88          10 :         if (!qh)
      89           5 :                 goto done;
      90          10 :         qh->hw = (struct ehci_qh_hw *)
      91             :                 dma_pool_alloc(ehci->qh_pool, flags, &dma);
      92          15 :         if (!qh->hw)
      93           5 :                 goto fail;
      94          10 :         memset(qh->hw, 0, sizeof *qh->hw);
      95           5 :         qh->refcount = 1;
      96           5 :         qh->ehci = ehci;
      97           5 :         qh->qh_dma = dma;
      98             :         // INIT_LIST_HEAD (&qh->qh_list);
      99          10 :         INIT_LIST_HEAD (&qh->qtd_list);
     100             : 
     101             :         /* dummy td enables safe urb queuing */
     102          15 :         qh->dummy = ehci_qtd_alloc (ehci, flags);
     103          15 :         if (qh->dummy == NULL) {
     104             :                 ehci_dbg (ehci, "no dummy td\n");
     105           5 :                 goto fail1;
     106             :         }
     107             : done:
     108          10 :         return qh;
     109          10 : fail1:
     110          10 :         dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma);
     111             : fail:
     112          15 :         kfree(qh);
     113          10 :         return NULL;
     114             : }
     115             : 
     116             : /* to share a qh (cpu threads, or hc) */
     117             : static inline struct ehci_qh *qh_get (struct ehci_qh *qh)
     118             : {
     119         864 :         WARN_ON(!qh->refcount);
     120         192 :         qh->refcount++;
     121          96 :         return qh;
     122             : }
     123             : 
     124             : static inline void qh_put (struct ehci_qh *qh)
     125             : {
     126         915 :         if (!--qh->refcount)
     127         915 :                 qh_destroy(qh);
     128         610 : }
     129             : 
     130             : /*-------------------------------------------------------------------------*/
     131             : 
     132             : /* The queue heads and transfer descriptors are managed from pools tied
     133             :  * to each of the "per device" structures.
     134             :  * This is the initialisation and cleanup code.
     135             :  */
     136             : 
     137             : static void ehci_mem_cleanup (struct ehci_hcd *ehci)
     138             : {
     139          27 :         free_cached_lists(ehci);
     140          27 :         if (ehci->async)
     141          27 :                 qh_put (ehci->async);
     142          18 :         ehci->async = NULL;
     143             : 
     144             :         /* DMA consistent memory and pools */
     145          54 :         if (ehci->qtd_pool)
     146          18 :                 dma_pool_destroy (ehci->qtd_pool);
     147          18 :         ehci->qtd_pool = NULL;
     148             : 
     149          54 :         if (ehci->qh_pool) {
     150          18 :                 dma_pool_destroy (ehci->qh_pool);
     151          18 :                 ehci->qh_pool = NULL;
     152             :         }
     153             : 
     154          54 :         if (ehci->itd_pool)
     155          18 :                 dma_pool_destroy (ehci->itd_pool);
     156          18 :         ehci->itd_pool = NULL;
     157             : 
     158          54 :         if (ehci->sitd_pool)
     159          18 :                 dma_pool_destroy (ehci->sitd_pool);
     160          18 :         ehci->sitd_pool = NULL;
     161             : 
     162          54 :         if (ehci->periodic)
     163          72 :                 dma_free_coherent (ehci_to_hcd(ehci)->self.controller,
     164             :                         ehci->periodic_size * sizeof (u32),
     165             :                         ehci->periodic, ehci->periodic_dma);
     166          27 :         ehci->periodic = NULL;
     167             : 
     168             :         /* shadow periodic table */
     169          54 :         kfree(ehci->pshadow);
     170          27 :         ehci->pshadow = NULL;
     171          27 : }
     172             : 
     173             : /* remember to add cleanup code (above) if you add anything here */
     174             : static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
     175             : {
     176           1 :         int i;
     177           1 : 
     178           1 :         /* QTDs for control/bulk/intr transfers */
     179           4 :         ehci->qtd_pool = dma_pool_create ("ehci_qtd",
     180           1 :                         ehci_to_hcd(ehci)->self.controller,
     181           1 :                         sizeof (struct ehci_qtd),
     182           1 :                         32 /* byte alignment (for hw parts) */,
     183           1 :                         4096 /* can't cross 4K */);
     184           3 :         if (!ehci->qtd_pool) {
     185           1 :                 goto fail;
     186             :         }
     187             : 
     188             :         /* QHs for control/bulk/intr transfers */
     189           3 :         ehci->qh_pool = dma_pool_create ("ehci_qh",
     190             :                         ehci_to_hcd(ehci)->self.controller,
     191             :                         sizeof(struct ehci_qh_hw),
     192             :                         32 /* byte alignment (for hw parts) */,
     193             :                         4096 /* can't cross 4K */);
     194           3 :         if (!ehci->qh_pool) {
     195           1 :                 goto fail;
     196             :         }
     197           3 :         ehci->async = ehci_qh_alloc (ehci, flags);
     198           3 :         if (!ehci->async) {
     199           1 :                 goto fail;
     200             :         }
     201             : 
     202             :         /* ITD for high speed ISO transfers */
     203           3 :         ehci->itd_pool = dma_pool_create ("ehci_itd",
     204             :                         ehci_to_hcd(ehci)->self.controller,
     205             :                         sizeof (struct ehci_itd),
     206             :                         32 /* byte alignment (for hw parts) */,
     207             :                         4096 /* can't cross 4K */);
     208           3 :         if (!ehci->itd_pool) {
     209           1 :                 goto fail;
     210             :         }
     211             : 
     212             :         /* SITD for full/low speed split ISO transfers */
     213           3 :         ehci->sitd_pool = dma_pool_create ("ehci_sitd",
     214             :                         ehci_to_hcd(ehci)->self.controller,
     215             :                         sizeof (struct ehci_sitd),
     216             :                         32 /* byte alignment (for hw parts) */,
     217             :                         4096 /* can't cross 4K */);
     218           3 :         if (!ehci->sitd_pool) {
     219           1 :                 goto fail;
     220             :         }
     221             : 
     222             :         /* Hardware periodic table */
     223           7 :         ehci->periodic = (__le32 *)
     224             :                 dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
     225             :                         ehci->periodic_size * sizeof(__le32),
     226             :                         &ehci->periodic_dma, 0);
     227           3 :         if (ehci->periodic == NULL) {
     228           1 :                 goto fail;
     229             :         }
     230           5 :         for (i = 0; i < ehci->periodic_size; i++)
     231           3 :                 ehci->periodic [i] = EHCI_LIST_END(ehci);
     232           2 : 
     233             :         /* software shadow of hardware table */
     234           4 :         ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags);
     235           3 :         if (ehci->pshadow != NULL)
     236           1 :                 return 0;
     237             : 
     238             : fail:
     239             :         ehci_dbg (ehci, "couldn't init memory\n");
     240          29 :         ehci_mem_cleanup (ehci);
     241           1 :         return -ENOMEM;
     242             : }

Generated by: LCOV version 1.10