Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  scatterlist.h   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SCATTERLIST_H
#define SCATTERLIST_H
#include <linux/kernel.h>
#include <linux/bug.h>

struct scatterlist {
 unsigned long page_link;
 unsigned int offset;
 unsigned int length;
 dma_addr_t dma_address;
};

/* Scatterlist helpers, stolen from linux/scatterlist.h */
#define sg_is_chain(sg)  ((sg)->page_link & 0x01)
#define sg_is_last(sg)  ((sg)->page_link & 0x02)
#define sg_chain_ptr(sg) \
 ((struct scatterlist *) ((sg)->page_link & ~0x03))

/**
 * sg_assign_page - Assign a given page to an SG entry
 * @sg:     SG entry
 * @page:     The page
 *
 * Description:
 *   Assign page to sg entry. Also see sg_set_page(), the most commonly used
 *   variant.
 *
 **/

static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
{
 unsigned long page_link = sg->page_link & 0x3;

 /*
 * In order for the low bit stealing approach to work, pages
 * must be aligned at a 32-bit boundary as a minimum.
 */

 BUG_ON((unsigned long) page & 0x03);
#ifdef CONFIG_DEBUG_SG
 BUG_ON(sg_is_chain(sg));
#endif
 sg->page_link = page_link | (unsigned long) page;
}

/**
 * sg_set_page - Set sg entry to point at given page
 * @sg:  SG entry
 * @page:  The page
 * @len:  Length of data
 * @offset:  Offset into page
 *
 * Description:
 *   Use this function to set an sg entry pointing at a page, never assign
 *   the page directly. We encode sg table information in the lower bits
 *   of the page pointer. See sg_page() for looking up the page belonging
 *   to an sg entry.
 *
 **/

static inline void sg_set_page(struct scatterlist *sg, struct page *page,
          unsigned int len, unsigned int offset)
{
 sg_assign_page(sg, page);
 sg->offset = offset;
 sg->length = len;
}

static inline struct page *sg_page(struct scatterlist *sg)
{
#ifdef CONFIG_DEBUG_SG
 BUG_ON(sg_is_chain(sg));
#endif
 return (struct page *)((sg)->page_link & ~0x3);
}

/*
 * Loop over each sg element, following the pointer to a new list if necessary
 */

#define for_each_sg(sglist, sg, nr, __i) \
 for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))

/**
 * sg_chain - Chain two sglists together
 * @prv: First scatterlist
 * @prv_nents: Number of entries in prv
 * @sgl: Second scatterlist
 *
 * Description:
 *   Links @prv@ and @sgl@ together, to form a longer scatterlist.
 *
 **/

static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
       struct scatterlist *sgl)
{
 /*
 * offset and length are unused for chain entry.  Clear them.
 */

 prv[prv_nents - 1].offset = 0;
 prv[prv_nents - 1].length = 0;

 /*
 * Set lowest bit to indicate a link pointer, and make sure to clear
 * the termination bit if it happens to be set.
 */

 prv[prv_nents - 1].page_link = ((unsigned long) sgl | 0x01) & ~0x02;
}

/**
 * sg_mark_end - Mark the end of the scatterlist
 * @sg:  SG entryScatterlist
 *
 * Description:
 *   Marks the passed in sg entry as the termination point for the sg
 *   table. A call to sg_next() on this entry will return NULL.
 *
 **/

static inline void sg_mark_end(struct scatterlist *sg)
{
 /*
 * Set termination bit, clear potential chain bit
 */

 sg->page_link |= 0x02;
 sg->page_link &= ~0x01;
}

/**
 * sg_unmark_end - Undo setting the end of the scatterlist
 * @sg:  SG entryScatterlist
 *
 * Description:
 *   Removes the termination marker from the given entry of the scatterlist.
 *
 **/

static inline void sg_unmark_end(struct scatterlist *sg)
{
 sg->page_link &= ~0x02;
}

static inline struct scatterlist *sg_next(struct scatterlist *sg)
{
 if (sg_is_last(sg))
  return NULL;

 sg++;
 if (unlikely(sg_is_chain(sg)))
  sg = sg_chain_ptr(sg);

 return sg;
}

static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
{
 memset(sgl, 0, sizeof(*sgl) * nents);
 sg_mark_end(&sgl[nents - 1]);
}

static inline dma_addr_t sg_phys(struct scatterlist *sg)
{
 return page_to_phys(sg_page(sg)) + sg->offset;
}

static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
         unsigned int buflen)
{
 sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
}

static inline void sg_init_one(struct scatterlist *sg,
          const void *buf, unsigned int buflen)
{
 sg_init_table(sg, 1);
 sg_set_buf(sg, buf, buflen);
}
#endif /* SCATTERLIST_H */

Messung V0.5
C=93 H=96 G=94

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge