Subversion Repositories Kolibri OS

Rev

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