Added support for linux-3.18
authorVladimir Sokolovsky <vlad@mellanox.com>
Mon, 27 Oct 2014 16:24:35 +0000 (18:24 +0200)
committerVladimir Sokolovsky <vlad@mellanox.com>
Tue, 28 Oct 2014 13:51:51 +0000 (15:51 +0200)
Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
compat/Makefile
compat/compat-3.11.c [new file with mode: 0644]
compat/compat-3.12.c [new file with mode: 0644]
compat/compat-3.16.c [new file with mode: 0644]
compat/compat-3.18.c [new file with mode: 0644]
include/linux/compat-2.6.h
include/linux/compat-3.13.h [new file with mode: 0644]
include/linux/compat-3.16.h [new file with mode: 0644]
include/linux/compat-3.17.h [new file with mode: 0644]

index b9b0930..f025580 100644 (file)
@@ -50,6 +50,10 @@ compat-$(CONFIG_COMPAT_KERNEL_3_5) += compat-3.5.o
 compat-$(CONFIG_COMPAT_KERNEL_3_6) += compat-3.6.o
 compat-$(CONFIG_COMPAT_KERNEL_3_7) += compat-3.7.o
 compat-$(CONFIG_COMPAT_KERNEL_3_9) += compat-3.9.o
+compat-$(CONFIG_COMPAT_KERNEL_3_11) += compat-3.11.o
+compat-$(CONFIG_COMPAT_KERNEL_3_12) += compat-3.12.o
+compat-$(CONFIG_COMPAT_KERNEL_3_16) += compat-3.16.o
+compat-$(CONFIG_COMPAT_KERNEL_3_18) += compat-3.18.o
 
 compat-$(CONFIG_COMPAT_CORDIC) += cordic.o
 compat-$(CONFIG_COMPAT_CRC8) += crc8.o
diff --git a/compat/compat-3.11.c b/compat/compat-3.11.c
new file mode 100644 (file)
index 0000000..f74a0f0
--- /dev/null
@@ -0,0 +1,428 @@
+#include <linux/export.h>
+#include <linux/scatterlist.h>
+#include <linux/highmem.h>
+
+
+#define sg_mapping_iter LINUX_BACKPORT(sg_mapping_iter)
+#define sg_page_iter LINUX_BACKPORT(sg_page_iter)
+#define __sg_page_iter_next LINUX_BACKPORT(__sg_page_iter_next)
+#define __sg_page_iter_start LINUX_BACKPORT(__sg_page_iter_start)
+#define sg_page_iter_page LINUX_BACKPORT(sg_page_iter_page)
+#define sg_page_iter_dma_address LINUX_BACKPORT(sg_page_iter_dma_address)
+
+#define sg_miter_start LINUX_BACKPORT(sg_miter_start)
+#define sg_miter_skip LINUX_BACKPORT(sg_miter_skip)
+#define sg_miter_next LINUX_BACKPORT(sg_miter_next)
+#define sg_miter_stop LINUX_BACKPORT(sg_miter_stop)
+
+/*
+ * sg page iterator
+ *
+ * Iterates over sg entries page-by-page.  On each successful iteration,
+ * you can call sg_page_iter_page(@piter) and sg_page_iter_dma_address(@piter)
+ * to get the current page and its dma address. @piter->sg will point to the
+ * sg holding this page and @piter->sg_pgoffset to the page's page offset
+ * within the sg. The iteration will stop either when a maximum number of sg
+ * entries was reached or a terminating sg (sg_last(sg) == true) was reached.
+ */
+struct sg_page_iter {
+       struct scatterlist      *sg;            /* sg holding the page */
+       unsigned int            sg_pgoffset;    /* page offset within the sg */
+
+       /* these are internal states, keep away */
+       unsigned int            __nents;        /* remaining sg entries */
+       int                     __pg_advance;   /* nr pages to advance at the
+                                                * next step */
+};
+
+
+/*
+ * Mapping sg iterator
+ *
+ * Iterates over sg entries mapping page-by-page.  On each successful
+ * iteration, @miter->page points to the mapped page and
+ * @miter->length bytes of data can be accessed at @miter->addr.  As
+ * long as an interation is enclosed between start and stop, the user
+ * is free to choose control structure and when to stop.
+ *
+ * @miter->consumed is set to @miter->length on each iteration.  It
+ * can be adjusted if the user can't consume all the bytes in one go.
+ * Also, a stopped iteration can be resumed by calling next on it.
+ * This is useful when iteration needs to release all resources and
+ * continue later (e.g. at the next interrupt).
+ */
+
+#define SG_MITER_ATOMIC                (1 << 0)        /* use kmap_atomic */
+#define SG_MITER_TO_SG         (1 << 1)        /* flush back to phys on unmap*/
+#define SG_MITER_FROM_SG       (1 << 2)        /* nop */
+
+struct sg_mapping_iter {
+       /* the following three fields can be accessed directly */
+       struct page             *page;          /* currently mapped page */
+       void                    *addr;          /* pointer to the mapped area */
+       size_t                  length;         /* length of the mapped area */
+       size_t                  consumed;       /* number of consumed bytes */
+       struct sg_page_iter     piter;          /* page iterator */
+
+       /* these are internal states, keep away */
+       unsigned int            __offset;       /* offset within page */
+       unsigned int            __remaining;    /* remaining bytes on page */
+       unsigned int            __flags;
+};
+
+void sg_miter_stop(struct sg_mapping_iter *miter);
+
+
+/**
+ * sg_page_iter_page - get the current page held by the page iterator
+ * @piter:     page iterator holding the page
+ */
+static inline struct page *sg_page_iter_page(struct sg_page_iter *piter)
+{
+       return nth_page(sg_page(piter->sg), piter->sg_pgoffset);
+}
+
+/**
+ * sg_page_iter_dma_address - get the dma address of the current page held by
+ * the page iterator.
+ * @piter:     page iterator holding the page
+ */
+static inline dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter)
+{
+       return sg_dma_address(piter->sg) + (piter->sg_pgoffset << PAGE_SHIFT);
+}
+
+void __sg_page_iter_start(struct sg_page_iter *piter,
+                         struct scatterlist *sglist, unsigned int nents,
+                         unsigned long pgoffset)
+{
+       piter->__pg_advance = 0;
+       piter->__nents = nents;
+
+       piter->sg = sglist;
+       piter->sg_pgoffset = pgoffset;
+}
+/* EXPORT_SYMBOL(__sg_page_iter_start); */
+
+static int sg_page_count(struct scatterlist *sg)
+{
+       return PAGE_ALIGN(sg->offset + sg->length) >> PAGE_SHIFT;
+}
+
+bool __sg_page_iter_next(struct sg_page_iter *piter)
+{
+       if (!piter->__nents || !piter->sg)
+               return false;
+
+       piter->sg_pgoffset += piter->__pg_advance;
+       piter->__pg_advance = 1;
+
+       while (piter->sg_pgoffset >= sg_page_count(piter->sg)) {
+               piter->sg_pgoffset -= sg_page_count(piter->sg);
+               piter->sg = sg_next(piter->sg);
+               if (!--piter->__nents || !piter->sg)
+                       return false;
+       }
+
+       return true;
+}
+/* EXPORT_SYMBOL(__sg_page_iter_next); */
+
+/**
+ * sg_miter_start - start mapping iteration over a sg list
+ * @miter: sg mapping iter to be started
+ * @sgl: sg list to iterate over
+ * @nents: number of sg entries
+ *
+ * Description:
+ *   Starts mapping iterator @miter.
+ *
+ * Context:
+ *   Don't care.
+ */
+void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
+                   unsigned int nents, unsigned int flags)
+{
+       memset(miter, 0, sizeof(struct sg_mapping_iter));
+
+       __sg_page_iter_start(&miter->piter, sgl, nents, 0);
+       WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG)));
+       miter->__flags = flags;
+}
+/* EXPORT_SYMBOL(sg_miter_start); */
+
+static bool sg_miter_get_next_page(struct sg_mapping_iter *miter)
+{
+       if (!miter->__remaining) {
+               struct scatterlist *sg;
+               unsigned long pgoffset;
+
+               if (!__sg_page_iter_next(&miter->piter))
+                       return false;
+
+               sg = miter->piter.sg;
+               pgoffset = miter->piter.sg_pgoffset;
+
+               miter->__offset = pgoffset ? 0 : sg->offset;
+               miter->__remaining = sg->offset + sg->length -
+                               (pgoffset << PAGE_SHIFT) - miter->__offset;
+               miter->__remaining = min_t(unsigned long, miter->__remaining,
+                                          PAGE_SIZE - miter->__offset);
+       }
+
+       return true;
+}
+
+/**
+ * sg_miter_skip - reposition mapping iterator
+ * @miter: sg mapping iter to be skipped
+ * @offset: number of bytes to plus the current location
+ *
+ * Description:
+ *   Sets the offset of @miter to its current location plus @offset bytes.
+ *   If mapping iterator @miter has been proceeded by sg_miter_next(), this
+ *   stops @miter.
+ *
+ * Context:
+ *   Don't care if @miter is stopped, or not proceeded yet.
+ *   Otherwise, preemption disabled if the SG_MITER_ATOMIC is set.
+ *
+ * Returns:
+ *   true if @miter contains the valid mapping.  false if end of sg
+ *   list is reached.
+ */
+bool sg_miter_skip(struct sg_mapping_iter *miter, off_t offset)
+{
+       sg_miter_stop(miter);
+
+       while (offset) {
+               off_t consumed;
+
+               if (!sg_miter_get_next_page(miter))
+                       return false;
+
+               consumed = min_t(off_t, offset, miter->__remaining);
+               miter->__offset += consumed;
+               miter->__remaining -= consumed;
+               offset -= consumed;
+       }
+
+       return true;
+}
+/* EXPORT_SYMBOL(sg_miter_skip); */
+
+/**
+ * sg_miter_next - proceed mapping iterator to the next mapping
+ * @miter: sg mapping iter to proceed
+ *
+ * Description:
+ *   Proceeds @miter to the next mapping.  @miter should have been started
+ *   using sg_miter_start().  On successful return, @miter->page,
+ *   @miter->addr and @miter->length point to the current mapping.
+ *
+ * Context:
+ *   Preemption disabled if SG_MITER_ATOMIC.  Preemption must stay disabled
+ *   till @miter is stopped.  May sleep if !SG_MITER_ATOMIC.
+ *
+ * Returns:
+ *   true if @miter contains the next mapping.  false if end of sg
+ *   list is reached.
+ */
+bool sg_miter_next(struct sg_mapping_iter *miter)
+{
+       sg_miter_stop(miter);
+
+       /*
+        * Get to the next page if necessary.
+        * __remaining, __offset is adjusted by sg_miter_stop
+        */
+       if (!sg_miter_get_next_page(miter))
+               return false;
+
+       miter->page = sg_page_iter_page(&miter->piter);
+       miter->consumed = miter->length = miter->__remaining;
+
+       if (miter->__flags & SG_MITER_ATOMIC)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
+               miter->addr = kmap_atomic(miter->page, 0) + miter->__offset;
+#else
+               miter->addr = kmap_atomic(miter->page) + miter->__offset;
+#endif
+       else
+               miter->addr = kmap(miter->page) + miter->__offset;
+
+       return true;
+}
+/* EXPORT_SYMBOL(sg_miter_next); */
+
+/**
+ * sg_miter_stop - stop mapping iteration
+ * @miter: sg mapping iter to be stopped
+ *
+ * Description:
+ *   Stops mapping iterator @miter.  @miter should have been started
+ *   started using sg_miter_start().  A stopped iteration can be
+ *   resumed by calling sg_miter_next() on it.  This is useful when
+ *   resources (kmap) need to be released during iteration.
+ *
+ * Context:
+ *   Preemption disabled if the SG_MITER_ATOMIC is set.  Don't care
+ *   otherwise.
+ */
+void sg_miter_stop(struct sg_mapping_iter *miter)
+{
+       WARN_ON(miter->consumed > miter->length);
+
+       /* drop resources from the last iteration */
+       if (miter->addr) {
+               miter->__offset += miter->consumed;
+               miter->__remaining -= miter->consumed;
+
+               if ((miter->__flags & SG_MITER_TO_SG) &&
+                   !PageSlab(miter->page))
+                       flush_kernel_dcache_page(miter->page);
+
+               if (miter->__flags & SG_MITER_ATOMIC) {
+                       WARN_ON_ONCE(preemptible());
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
+                       kunmap_atomic(miter->addr, 0);
+#else
+                       kunmap_atomic(miter->addr);
+#endif
+               } else
+                       kunmap(miter->page);
+
+               miter->page = NULL;
+               miter->addr = NULL;
+               miter->length = 0;
+               miter->consumed = 0;
+       }
+}
+/* EXPORT_SYMBOL(sg_miter_stop); */
+
+/**
+ * sg_copy_buffer - Copy data between a linear buffer and an SG list
+ * @sgl:                The SG list
+ * @nents:              Number of SG entries
+ * @buf:                Where to copy from
+ * @buflen:             The number of bytes to copy
+ * @skip:               Number of bytes to skip before copying
+ * @to_buffer:          transfer direction (true == from an sg list to a
+ *                      buffer, false == from a buffer to an sg list
+ *
+ * Returns the number of copied bytes.
+ *
+ **/
+static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
+                            void *buf, size_t buflen, off_t skip,
+                            bool to_buffer)
+{
+       unsigned int offset = 0;
+       struct sg_mapping_iter miter;
+       unsigned long flags;
+       unsigned int sg_flags = SG_MITER_ATOMIC;
+
+       if (to_buffer)
+               sg_flags |= SG_MITER_FROM_SG;
+       else
+               sg_flags |= SG_MITER_TO_SG;
+
+       sg_miter_start(&miter, sgl, nents, sg_flags);
+
+       if (!sg_miter_skip(&miter, skip))
+               return false;
+
+       local_irq_save(flags);
+
+       while (sg_miter_next(&miter) && offset < buflen) {
+               unsigned int len;
+
+               len = min(miter.length, buflen - offset);
+
+               if (to_buffer)
+                       memcpy(buf + offset, miter.addr, len);
+               else
+                       memcpy(miter.addr, buf + offset, len);
+
+               offset += len;
+       }
+
+       sg_miter_stop(&miter);
+
+       local_irq_restore(flags);
+       return offset;
+}
+
+/**
+ * sg_copy_from_buffer - Copy from a linear buffer to an SG list
+ * @sgl:                The SG list
+ * @nents:              Number of SG entries
+ * @buf:                Where to copy from
+ * @buflen:             The number of bytes to copy
+ *
+ * Returns the number of copied bytes.
+ *
+ **/
+#define sg_copy_from_buffer LINUX_BACKPORT(sg_copy_from_buffer)
+size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
+                          void *buf, size_t buflen)
+{
+       return sg_copy_buffer(sgl, nents, buf, buflen, 0, false);
+}
+EXPORT_SYMBOL(sg_copy_from_buffer);
+
+/**
+ * sg_copy_to_buffer - Copy from an SG list to a linear buffer
+ * @sgl:                The SG list
+ * @nents:              Number of SG entries
+ * @buf:                Where to copy to
+ * @buflen:             The number of bytes to copy
+ *
+ * Returns the number of copied bytes.
+ *
+ **/
+#define sg_copy_to_buffer LINUX_BACKPORT(sg_copy_to_buffer)
+size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
+                        void *buf, size_t buflen)
+{
+       return sg_copy_buffer(sgl, nents, buf, buflen, 0, true);
+}
+EXPORT_SYMBOL(sg_copy_to_buffer);
+
+/**
+ * sg_pcopy_from_buffer - Copy from a linear buffer to an SG list
+ * @sgl:                The SG list
+ * @nents:              Number of SG entries
+ * @buf:                Where to copy from
+ * @skip:               Number of bytes to skip before copying
+ * @buflen:             The number of bytes to copy
+ *
+ * Returns the number of copied bytes.
+ *
+ **/
+#define sg_pcopy_from_buffer LINUX_BACKPORT(sg_pcopy_from_buffer)
+size_t sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents,
+                           void *buf, size_t buflen, off_t skip)
+{
+       return sg_copy_buffer(sgl, nents, buf, buflen, skip, false);
+}
+EXPORT_SYMBOL(sg_pcopy_from_buffer);
+
+/**
+ * sg_pcopy_to_buffer - Copy from an SG list to a linear buffer
+ * @sgl:                The SG list
+ * @nents:              Number of SG entries
+ * @buf:                Where to copy to
+ * @skip:               Number of bytes to skip before copying
+ * @buflen:             The number of bytes to copy
+ *
+ * Returns the number of copied bytes.
+ *
+ **/
+#define sg_pcopy_to_buffer LINUX_BACKPORT(sg_pcopy_to_buffer)
+size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents,
+                         void *buf, size_t buflen, off_t skip)
+{
+       return sg_copy_buffer(sgl, nents, buf, buflen, skip, true);
+}
+EXPORT_SYMBOL(sg_pcopy_to_buffer);
diff --git a/compat/compat-3.12.c b/compat/compat-3.12.c
new file mode 100644 (file)
index 0000000..69c9ed4
--- /dev/null
@@ -0,0 +1,111 @@
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/export.h>
+#include <linux/pci.h>
+
+#define debugfs_create_atomic_t LINUX_BACKPORT(debugfs_create_atomic_t)
+
+static int debugfs_atomic_t_set(void *data, u64 val)
+{
+       atomic_set((atomic_t *)data, val);
+       return 0;
+}
+static int debugfs_atomic_t_get(void *data, u64 *val)
+{
+       *val = atomic_read((atomic_t *)data);
+       return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
+                       debugfs_atomic_t_set, "%lld\n");
+DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, "%lld\n");
+DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%lld\n");
+
+/**
+ * debugfs_create_atomic_t - create a debugfs file that is used to read and
+ * write an atomic_t value
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this parameter is %NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ *         from.
+ */
+struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
+                                struct dentry *parent, atomic_t *value)
+{
+       /* if there are no write bits set, make read only */
+       if (!(mode & S_IWUGO))
+               return debugfs_create_file(name, mode, parent, value,
+                                       &fops_atomic_t_ro);
+       /* if there are no read bits set, make write only */
+       if (!(mode & S_IRUGO))
+               return debugfs_create_file(name, mode, parent, value,
+                                       &fops_atomic_t_wo);
+
+       return debugfs_create_file(name, mode, parent, value, &fops_atomic_t);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_atomic_t);
+
+const unsigned char pcie_link_speed[] = {
+       PCI_SPEED_UNKNOWN,              /* 0 */
+       PCIE_SPEED_2_5GT,               /* 1 */
+       PCIE_SPEED_5_0GT,               /* 2 */
+       PCIE_SPEED_8_0GT,               /* 3 */
+       PCI_SPEED_UNKNOWN,              /* 4 */
+       PCI_SPEED_UNKNOWN,              /* 5 */
+       PCI_SPEED_UNKNOWN,              /* 6 */
+       PCI_SPEED_UNKNOWN,              /* 7 */
+       PCI_SPEED_UNKNOWN,              /* 8 */
+       PCI_SPEED_UNKNOWN,              /* 9 */
+       PCI_SPEED_UNKNOWN,              /* A */
+       PCI_SPEED_UNKNOWN,              /* B */
+       PCI_SPEED_UNKNOWN,              /* C */
+       PCI_SPEED_UNKNOWN,              /* D */
+       PCI_SPEED_UNKNOWN,              /* E */
+       PCI_SPEED_UNKNOWN               /* F */
+};
+
+/**
+ * pcie_get_minimum_link - determine minimum link settings of a PCI device
+ * @dev: PCI device to query
+ * @speed: storage for minimum speed
+ * @width: storage for minimum width
+ *
+ * This function will walk up the PCI device chain and determine the minimum
+ * link width and speed of the device.
+ */
+#define pcie_get_minimum_link LINUX_BACKPORT(pcie_get_minimum_link)
+int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
+                         enum pcie_link_width *width)
+{
+       int ret;
+
+       *speed = PCI_SPEED_UNKNOWN;
+       *width = PCIE_LNK_WIDTH_UNKNOWN;
+
+       while (dev) {
+               u16 lnksta;
+               enum pci_bus_speed next_speed;
+               enum pcie_link_width next_width;
+
+               ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
+               if (ret)
+                       return ret;
+
+               next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
+               next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
+                       PCI_EXP_LNKSTA_NLW_SHIFT;
+
+               if (next_speed < *speed)
+                       *speed = next_speed;
+
+               if (next_width < *width)
+                       *width = next_width;
+
+               dev = dev->bus->self;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(pcie_get_minimum_link);
diff --git a/compat/compat-3.16.c b/compat/compat-3.16.c
new file mode 100644 (file)
index 0000000..6c840f7
--- /dev/null
@@ -0,0 +1,69 @@
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/cpumask.h>
+#include <linux/export.h>
+#include <linux/bootmem.h>
+
+/**
+ * cpumask_set_cpu_local_first - set i'th cpu with local numa cpu's first
+ *
+ * @i: index number
+ * @numa_node: local numa_node
+ * @dstp: cpumask with the relevant cpu bit set according to the policy
+ *
+ * This function sets the cpumask according to a numa aware policy.
+ * cpumask could be used as an affinity hint for the IRQ related to a
+ * queue. When the policy is to spread queues across cores - local cores
+ * first.
+ *
+ * Returns 0 on success, -ENOMEM for no memory, and -EAGAIN when failed to set
+ * the cpu bit and need to re-call the function.
+ */
+int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp)
+{
+       cpumask_var_t mask;
+       int cpu;
+       int ret = 0;
+
+       if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
+               return -ENOMEM;
+
+       i %= num_online_cpus();
+
+       if (numa_node == -1 || !cpumask_of_node(numa_node)) {
+               /* Use all online cpu's for non numa aware system */
+               cpumask_copy(mask, cpu_online_mask);
+       } else {
+               int n;
+
+               cpumask_and(mask,
+                           cpumask_of_node(numa_node), cpu_online_mask);
+
+               n = cpumask_weight(mask);
+               if (i >= n) {
+                       i -= n;
+
+                       /* If index > number of local cpu's, mask out local
+                        * cpu's
+                        */
+                       cpumask_andnot(mask, cpu_online_mask, mask);
+               }
+       }
+
+       for_each_cpu(cpu, mask) {
+               if (--i < 0)
+                       goto out;
+       }
+
+       ret = -EAGAIN;
+
+out:
+       free_cpumask_var(mask);
+
+       if (!ret)
+               cpumask_set_cpu(cpu, dstp);
+
+       return ret;
+}
+EXPORT_SYMBOL(cpumask_set_cpu_local_first);
diff --git a/compat/compat-3.18.c b/compat/compat-3.18.c
new file mode 100644 (file)
index 0000000..4dced45
--- /dev/null
@@ -0,0 +1,5 @@
+#include <linux/kernel.h>
+#include <linux/crash_dump.h>
+
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+EXPORT_SYMBOL_GPL(elfcorehdr_addr);
index af5700e..dce64ef 100644 (file)
@@ -76,5 +76,8 @@ void backport_dependency_symbol(void);
 #include <linux/compat-3.10.h>
 #include <linux/compat-3.11.h>
 #include <linux/compat-3.12.h>
+#include <linux/compat-3.13.h>
+#include <linux/compat-3.16.h>
+#include <linux/compat-3.17.h>
 
 #endif /* LINUX_26_COMPAT_H */
diff --git a/include/linux/compat-3.13.h b/include/linux/compat-3.13.h
new file mode 100644 (file)
index 0000000..619b8f9
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef LINUX_3_13_COMPAT_H
+#define LINUX_3_13_COMPAT_H
+
+#include <linux/version.h>
+#include <linux/completion.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0))
+
+#ifndef CONFIG_COMPAT_IS_REINIT_COMPLETION
+#define CONFIG_COMPAT_IS_REINIT_COMPLETION
+
+static inline void reinit_completion(struct completion *x)
+{
+       x->done = 0;
+}
+
+#endif
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)) */
+
+#endif /* LINUX_3_13_COMPAT_H */
diff --git a/include/linux/compat-3.16.h b/include/linux/compat-3.16.h
new file mode 100644 (file)
index 0000000..ea150ac
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef LINUX_3_16_COMPAT_H
+#define LINUX_3_16_COMPAT_H
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
+
+#include <linux/cpumask.h>
+
+#if NR_CPUS == 1
+static inline int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp)
+{
+       set_bit(0, cpumask_bits(dstp));
+
+       return 0;
+}
+#else
+int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp);
+#endif
+
+#include <linux/ktime.h>
+
+static inline u64 ktime_get_ns(void)
+{
+       return ktime_to_ns(ktime_get());
+}
+
+#include <asm/barrier.h>
+
+#ifndef smp_mb__after_atomic
+#define smp_mb__after_atomic() smp_mb()
+#endif
+
+#ifndef smp_mb__before_atomic
+#define smp_mb__before_atomic()        smp_mb()
+#endif
+
+#define RPC_CWNDSHIFT          (8U)
+#define RPC_CWNDSCALE          (1U << RPC_CWNDSHIFT)
+#define RPC_INITCWND           RPC_CWNDSCALE
+#define RPC_MAXCWND(xprt)      ((xprt)->max_reqs << RPC_CWNDSHIFT)
+#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) */
+
+#endif /* LINUX_3_16_COMPAT_H */
diff --git a/include/linux/compat-3.17.h b/include/linux/compat-3.17.h
new file mode 100644 (file)
index 0000000..d2c054e
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef LINUX_3_17_COMPAT_H
+#define LINUX_3_17_COMPAT_H
+
+#include <linux/version.h>
+#include <linux/dcbnl.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0))
+
+#include <linux/netdevice.h>
+
+#ifdef alloc_netdev
+#undef alloc_netdev
+#define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \
+       alloc_netdev_mqs(sizeof_priv, name, setup, 1, 1)
+#endif
+
+#ifndef CONFIG_COMPAT_IS_QCN
+
+enum dcbnl_cndd_states {
+       DCB_CNDD_RESET = 0,
+       DCB_CNDD_EDGE,
+       DCB_CNDD_INTERIOR,
+       DCB_CNDD_INTERIOR_READY,
+};
+
+struct ieee_qcn {
+       __u8 rpg_enable[IEEE_8021QAZ_MAX_TCS];
+       __u32 rppp_max_rps[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_time_reset[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_byte_reset[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_threshold[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_max_rate[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_ai_rate[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_hai_rate[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_gd[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_min_dec_fac[IEEE_8021QAZ_MAX_TCS];
+       __u32 rpg_min_rate[IEEE_8021QAZ_MAX_TCS];
+       __u32 cndd_state_machine[IEEE_8021QAZ_MAX_TCS];
+};
+
+struct ieee_qcn_stats {
+       __u64 rppp_rp_centiseconds[IEEE_8021QAZ_MAX_TCS];
+       __u32 rppp_created_rps[IEEE_8021QAZ_MAX_TCS];
+       __u32 ignored_cnm[IEEE_8021QAZ_MAX_TCS];
+       __u32 estimated_total_rate[IEEE_8021QAZ_MAX_TCS];
+       __u32 cnms_handled_successfully[IEEE_8021QAZ_MAX_TCS];
+       __u32 min_total_limiters_rate[IEEE_8021QAZ_MAX_TCS];
+       __u32 max_total_limiters_rate[IEEE_8021QAZ_MAX_TCS];
+};
+
+#endif
+
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)) */
+
+#endif /* LINUX_3_17_COMPAT_H */