Subversion Repositories Kolibri OS

Rev

Rev 5056 | Rev 6082 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2007 Jens Axboe <jens.axboe@oracle.com>
  3.  *
  4.  * Scatterlist handling helpers.
  5.  *
  6.  * This source code is licensed under the GNU General Public License,
  7.  * Version 2. See the file COPYING for more details.
  8.  */
  9. #include <linux/export.h>
  10. #include <linux/slab.h>
  11. #include <linux/scatterlist.h>
  12.  
  13. /**
  14.  * sg_next - return the next scatterlist entry in a list
  15.  * @sg:         The current sg entry
  16.  *
  17.  * Description:
  18.  *   Usually the next entry will be @sg@ + 1, but if this sg element is part
  19.  *   of a chained scatterlist, it could jump to the start of a new
  20.  *   scatterlist array.
  21.  *
  22.  **/
  23. struct scatterlist *sg_next(struct scatterlist *sg)
  24. {
  25. #ifdef CONFIG_DEBUG_SG
  26.         BUG_ON(sg->sg_magic != SG_MAGIC);
  27. #endif
  28.     if (sg_is_last(sg))
  29.         return NULL;
  30.  
  31.     sg++;
  32.     if (unlikely(sg_is_chain(sg)))
  33.             sg = sg_chain_ptr(sg);
  34.  
  35.     return sg;
  36. }
  37. EXPORT_SYMBOL(sg_next);
  38.  
  39. /**
  40.  * sg_nents - return total count of entries in scatterlist
  41.  * @sg:         The scatterlist
  42.  *
  43.  * Description:
  44.  * Allows to know how many entries are in sg, taking into acount
  45.  * chaining as well
  46.  *
  47.  **/
  48. int sg_nents(struct scatterlist *sg)
  49. {
  50.         int nents;
  51.         for (nents = 0; sg; sg = sg_next(sg))
  52.                 nents++;
  53.         return nents;
  54. }
  55. EXPORT_SYMBOL(sg_nents);
  56.  
  57.  
  58. /**
  59.  * sg_last - return the last scatterlist entry in a list
  60.  * @sgl:        First entry in the scatterlist
  61.  * @nents:      Number of entries in the scatterlist
  62.  *
  63.  * Description:
  64.  *   Should only be used casually, it (currently) scans the entire list
  65.  *   to get the last entry.
  66.  *
  67.  *   Note that the @sgl@ pointer passed in need not be the first one,
  68.  *   the important bit is that @nents@ denotes the number of entries that
  69.  *   exist from @sgl@.
  70.  *
  71.  **/
  72. struct scatterlist *sg_last(struct scatterlist *sgl, unsigned int nents)
  73. {
  74. #ifndef CONFIG_ARCH_HAS_SG_CHAIN
  75.         struct scatterlist *ret = &sgl[nents - 1];
  76. #else
  77.         struct scatterlist *sg, *ret = NULL;
  78.         unsigned int i;
  79.  
  80.         for_each_sg(sgl, sg, nents, i)
  81.                 ret = sg;
  82.  
  83. #endif
  84. #ifdef CONFIG_DEBUG_SG
  85.         BUG_ON(sgl[0].sg_magic != SG_MAGIC);
  86.         BUG_ON(!sg_is_last(ret));
  87. #endif
  88.         return ret;
  89. }
  90. EXPORT_SYMBOL(sg_last);
  91.  
  92. /**
  93.  * sg_init_table - Initialize SG table
  94.  * @sgl:           The SG table
  95.  * @nents:         Number of entries in table
  96.  *
  97.  * Notes:
  98.  *   If this is part of a chained sg table, sg_mark_end() should be
  99.  *   used only on the last table part.
  100.  *
  101.  **/
  102. void sg_init_table(struct scatterlist *sgl, unsigned int nents)
  103. {
  104.     memset(sgl, 0, sizeof(*sgl) * nents);
  105. #ifdef CONFIG_DEBUG_SG
  106.     {
  107.             unsigned int i;
  108.             for (i = 0; i < nents; i++)
  109.                     sgl[i].sg_magic = SG_MAGIC;
  110.     }
  111. #endif
  112.     sg_mark_end(&sgl[nents - 1]);
  113. }
  114. EXPORT_SYMBOL(sg_init_table);
  115.  
  116. /**
  117.  * sg_init_one - Initialize a single entry sg list
  118.  * @sg:          SG entry
  119.  * @buf:         Virtual address for IO
  120.  * @buflen:      IO length
  121.  *
  122.  **/
  123. //void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen)
  124. //{
  125. //   sg_init_table(sg, 1);
  126. //   sg_set_buf(sg, buf, buflen);
  127. //}
  128. EXPORT_SYMBOL(sg_init_one);
  129.  
  130. /*
  131.  * The default behaviour of sg_alloc_table() is to use these kmalloc/kfree
  132.  * helpers.
  133.  */
  134. static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask)
  135. {
  136.         return kmalloc(nents * sizeof(struct scatterlist), gfp_mask);
  137. }
  138.  
  139. static void sg_kfree(struct scatterlist *sg, unsigned int nents)
  140. {
  141.         kfree(sg);
  142. }
  143.  
  144. /**
  145.  * __sg_free_table - Free a previously mapped sg table
  146.  * @table:      The sg table header to use
  147.  * @max_ents:   The maximum number of entries per single scatterlist
  148.  * @skip_first_chunk: don't free the (preallocated) first scatterlist chunk
  149.  * @free_fn:    Free function
  150.  *
  151.  *  Description:
  152.  *    Free an sg table previously allocated and setup with
  153.  *    __sg_alloc_table().  The @max_ents value must be identical to
  154.  *    that previously used with __sg_alloc_table().
  155.  *
  156.  **/
  157. void __sg_free_table(struct sg_table *table, unsigned int max_ents,
  158.                      bool skip_first_chunk, sg_free_fn *free_fn)
  159. {
  160.     struct scatterlist *sgl, *next;
  161.  
  162.     if (unlikely(!table->sgl))
  163.             return;
  164.  
  165.     sgl = table->sgl;
  166.     while (table->orig_nents) {
  167.         unsigned int alloc_size = table->orig_nents;
  168.         unsigned int sg_size;
  169.  
  170.         /*
  171.          * If we have more than max_ents segments left,
  172.          * then assign 'next' to the sg table after the current one.
  173.          * sg_size is then one less than alloc size, since the last
  174.          * element is the chain pointer.
  175.          */
  176.         if (alloc_size > max_ents) {
  177.                 next = sg_chain_ptr(&sgl[max_ents - 1]);
  178.                 alloc_size = max_ents;
  179.                 sg_size = alloc_size - 1;
  180.         } else {
  181.                 sg_size = alloc_size;
  182.                 next = NULL;
  183.         }
  184.  
  185.         table->orig_nents -= sg_size;
  186.                 if (skip_first_chunk)
  187.                         skip_first_chunk = false;
  188.                 else
  189.                         free_fn(sgl, alloc_size);
  190.         sgl = next;
  191.     }
  192.  
  193.     table->sgl = NULL;
  194. }
  195. EXPORT_SYMBOL(__sg_free_table);
  196.  
  197. /**
  198.  * sg_free_table - Free a previously allocated sg table
  199.  * @table:      The mapped sg table header
  200.  *
  201.  **/
  202. void sg_free_table(struct sg_table *table)
  203. {
  204.         __sg_free_table(table, SG_MAX_SINGLE_ALLOC, false, sg_kfree);
  205. }
  206. EXPORT_SYMBOL(sg_free_table);
  207.  
  208. /**
  209.  * __sg_alloc_table - Allocate and initialize an sg table with given allocator
  210.  * @table:      The sg table header to use
  211.  * @nents:      Number of entries in sg list
  212.  * @max_ents:   The maximum number of entries the allocator returns per call
  213.  * @gfp_mask:   GFP allocation mask
  214.  * @alloc_fn:   Allocator to use
  215.  *
  216.  * Description:
  217.  *   This function returns a @table @nents long. The allocator is
  218.  *   defined to return scatterlist chunks of maximum size @max_ents.
  219.  *   Thus if @nents is bigger than @max_ents, the scatterlists will be
  220.  *   chained in units of @max_ents.
  221.  *
  222.  * Notes:
  223.  *   If this function returns non-0 (eg failure), the caller must call
  224.  *   __sg_free_table() to cleanup any leftover allocations.
  225.  *
  226.  **/
  227. int __sg_alloc_table(struct sg_table *table, unsigned int nents,
  228.                      unsigned int max_ents, struct scatterlist *first_chunk,
  229.                      gfp_t gfp_mask, sg_alloc_fn *alloc_fn)
  230. {
  231.     struct scatterlist *sg, *prv;
  232.     unsigned int left;
  233.  
  234.         memset(table, 0, sizeof(*table));
  235.  
  236.         if (nents == 0)
  237.                 return -EINVAL;
  238. #ifndef CONFIG_ARCH_HAS_SG_CHAIN
  239.         if (WARN_ON_ONCE(nents > max_ents))
  240.                 return -EINVAL;
  241. #endif
  242.  
  243.     left = nents;
  244.     prv = NULL;
  245.     do {
  246.         unsigned int sg_size, alloc_size = left;
  247.  
  248.         if (alloc_size > max_ents) {
  249.                 alloc_size = max_ents;
  250.                 sg_size = alloc_size - 1;
  251.         } else
  252.                 sg_size = alloc_size;
  253.  
  254.         left -= sg_size;
  255.  
  256.                 if (first_chunk) {
  257.                         sg = first_chunk;
  258.                         first_chunk = NULL;
  259.                 } else {
  260.                         sg = alloc_fn(alloc_size, gfp_mask);
  261.                 }
  262.         if (unlikely(!sg)) {
  263.                 /*
  264.                  * Adjust entry count to reflect that the last
  265.                  * entry of the previous table won't be used for
  266.                  * linkage.  Without this, sg_kfree() may get
  267.                  * confused.
  268.                  */
  269.                 if (prv)
  270.                         table->nents = ++table->orig_nents;
  271.  
  272.                         return -ENOMEM;
  273.         }
  274.  
  275.         sg_init_table(sg, alloc_size);
  276.         table->nents = table->orig_nents += sg_size;
  277.  
  278.         /*
  279.          * If this is the first mapping, assign the sg table header.
  280.          * If this is not the first mapping, chain previous part.
  281.          */
  282.         if (prv)
  283.                 sg_chain(prv, max_ents, sg);
  284.         else
  285.                 table->sgl = sg;
  286.  
  287.         /*
  288.          * If no more entries after this one, mark the end
  289.          */
  290.         if (!left)
  291.                 sg_mark_end(&sg[sg_size - 1]);
  292.  
  293.         prv = sg;
  294.     } while (left);
  295.  
  296.     return 0;
  297. }
  298. EXPORT_SYMBOL(__sg_alloc_table);
  299.  
  300. /**
  301.  * sg_alloc_table - Allocate and initialize an sg table
  302.  * @table:      The sg table header to use
  303.  * @nents:      Number of entries in sg list
  304.  * @gfp_mask:   GFP allocation mask
  305.  *
  306.  *  Description:
  307.  *    Allocate and initialize an sg table. If @nents@ is larger than
  308.  *    SG_MAX_SINGLE_ALLOC a chained sg table will be setup.
  309.  *
  310.  **/
  311. int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
  312. {
  313.         int ret;
  314.  
  315.         ret = __sg_alloc_table(table, nents, SG_MAX_SINGLE_ALLOC,
  316.                                NULL, gfp_mask, sg_kmalloc);
  317.         if (unlikely(ret))
  318.                 __sg_free_table(table, SG_MAX_SINGLE_ALLOC, false, sg_kfree);
  319.  
  320.         return ret;
  321. }
  322. EXPORT_SYMBOL(sg_alloc_table);
  323.  
  324.  
  325.  
  326.  
  327. void __sg_page_iter_start(struct sg_page_iter *piter,
  328.               struct scatterlist *sglist, unsigned int nents,
  329.               unsigned long pgoffset)
  330. {
  331.     piter->__pg_advance = 0;
  332.     piter->__nents = nents;
  333.  
  334.     piter->sg = sglist;
  335.     piter->sg_pgoffset = pgoffset;
  336. }
  337. EXPORT_SYMBOL(__sg_page_iter_start);
  338.  
  339. static int sg_page_count(struct scatterlist *sg)
  340. {
  341.     return PAGE_ALIGN(sg->offset + sg->length) >> PAGE_SHIFT;
  342. }
  343.  
  344. bool __sg_page_iter_next(struct sg_page_iter *piter)
  345. {
  346.     if (!piter->__nents || !piter->sg)
  347.         return false;
  348.  
  349.     piter->sg_pgoffset += piter->__pg_advance;
  350.     piter->__pg_advance = 1;
  351.  
  352.     while (piter->sg_pgoffset >= sg_page_count(piter->sg)) {
  353.         piter->sg_pgoffset -= sg_page_count(piter->sg);
  354.         piter->sg = sg_next(piter->sg);
  355.         if (!--piter->__nents || !piter->sg)
  356.             return false;
  357.     }
  358.  
  359.     return true;
  360. }
  361. EXPORT_SYMBOL(__sg_page_iter_next);
  362.  
  363.  
  364.  
  365.