Added headers and macros required by NVME target
authorVladimir Sokolovsky <vlad@mellanox.com>
Mon, 10 Sep 2018 22:30:15 +0000 (17:30 -0500)
committerVladimir Sokolovsky <vlad@mellanox.com>
Mon, 10 Sep 2018 22:51:46 +0000 (17:51 -0500)
Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
config/rdma.m4
include/linux/scatterlist.h [new file with mode: 0644]
include/linux/string.h [new file with mode: 0644]

index cf969ac..fdc0cdf 100644 (file)
@@ -8410,6 +8410,297 @@ AC_DEFUN([LINUX_CONFIG_COMPAT],
                        [dev_pm_qos_update_user_latency_tolerance is exported by the kernel])],
        [])
 
+       AC_MSG_CHECKING([if linux/bio.h bio_endio has 1 parameter])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/bio.h>
+       ],[
+               bio_endio(NULL);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_BIO_ENDIO_1_PARAM, 1,
+                       [linux/bio.h bio_endio has 1 parameter])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if bio.h bio_init has 3 parameters])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/bio.h>
+       ],[
+               bio_init(NULL, NULL, false);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_BIO_INIT_3_PARAMS, 1,
+                         [bio.h bio_init has 3 parameters])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if blkdev.h has __blkdev_issue_discard])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/blkdev.h>
+       ],[
+               __blkdev_issue_discard(NULL, 0, 0, 0, 0, NULL);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE___BLKDEV_ISSUE_DISCARD, 1,
+                       [__blkdev_issue_discard is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if blkdev.h has __blkdev_issue_zeroout])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/blkdev.h>
+       ],[
+               __blkdev_issue_zeroout(NULL, 0, 0, 0, NULL, 0);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_BLKDEV_ISSUE_ZEROOUT, 1,
+                       [__blkdev_issue_zeroout exist])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if blkdev.h has blk_poll])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/blkdev.h>
+       ],[
+               blk_poll(NULL, 0);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_BLK_POLL, 1,
+                       [blk_poll exist])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if linux/inet.h has inet_addr_is_any])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/inet.h>
+       ],[
+               inet_addr_is_any(NULL);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_INET_ADDR_IS_ANY, 1,
+                       [inet_addr_is_any is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if string.h has memchr_inv])
+       LB_LINUX_TRY_COMPILE([
+       #include <linux/string.h>
+       ],[
+               memchr_inv(NULL, 0, 0);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_MEMCHR_INV, 1,
+               [memchr_inv is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if string.h has memcpy_and_pad])
+       LB_LINUX_TRY_COMPILE([
+       #include <linux/string.h>
+       ],
+       [
+               memcpy_and_pad(NULL, 0, NULL, 0, ' ');
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_MEMCPY_AND_PAD, 1,
+               [memcpy_and_pad is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if string.h has memdup_user_nul])
+       LB_LINUX_TRY_COMPILE([
+       #include <linux/string.h>
+       ],[
+               memdup_user_nul(NULL, 0);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_MEMDUP_USER_NUL, 1,
+               [memdup_user_nul is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if blk_types.h has REQ_IDLE])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/blk_types.h>
+       ],[
+               int flags = REQ_IDLE;
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_REQ_IDLE, 1,
+                       [blk_types.h has REQ_IDLE])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if linux/scatterlist.h sg_alloc_table_chained has 3 parameters])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/scatterlist.h>
+       ],[
+               sg_alloc_table_chained(NULL, 0, NULL);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_SG_ALLOC_TABLE_CHAINED_3_PARAMS, 1,
+                       [sg_alloc_table_chained has 3 parameters])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if linux/scatterlist.h has sgl_alloc])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/scatterlist.h>
+       ],[
+               sgl_alloc(0, 0, NULL);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_SGL_ALLOC, 1,
+                       [sgl_alloc is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if linux/scatterlist.h has sgl_free])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/scatterlist.h>
+       ],[
+               sgl_free(NULL);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_SGL_FREE, 1,
+                       [sgl_free is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if linux/scatterlist.h has sg_zero_buffer])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/scatterlist.h>
+       ],[
+               sg_zero_buffer(NULL, 0, 0, 0);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_SG_ZERO_BUFFER, 1,
+                       [sg_zero_buffer is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if string.h has strnicmp])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/string.h>
+       ],[
+               char a[10] = "aaa";
+               char b[10] = "bbb";
+               strnicmp(a, b, sizeof(a));
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_STRNICMP, 1,
+                         [strnicmp is defined])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if struct bio has member bi_error])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/blk_types.h>
+       ],[
+               struct bio b = {
+                       .bi_error = 0,
+               };
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_STRUCT_BIO_BI_ERROR, 1,
+                       [struct bio has member bi_error])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if struct bio has member bi_iter])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/blk_types.h>
+       ],[
+               struct bio b = {
+                       .bi_iter = 0,
+               };
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_STRUCT_BIO_BI_ITER, 1,
+                       [struct bio has member bi_iter])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if struct bio has member bi_opf])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/blk_types.h>
+       ],[
+               struct bio b = {
+                       .bi_opf = 0,
+               };
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_STRUCT_BIO_BI_OPF, 1,
+                       [struct bio has member bi_opf])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
+       AC_MSG_CHECKING([if linux/bio.h submit_bio has 1 parameter])
+       LB_LINUX_TRY_COMPILE([
+               #include <linux/bio.h>
+               #include <linux/fs.h>
+       ],[
+               submit_bio(NULL);
+
+               return 0;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_SUBMIT_BIO_1_PARAM, 1,
+                       [linux/bio.h submit_bio has 1 parameter])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+
 ])
 #
 # COMPAT_CONFIG_HEADERS
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
new file mode 100644 (file)
index 0000000..46271a8
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef _COMPAT_LINUX_SCATTERLIST_H
+#define _COMPAT_LINUX_SCATTERLIST_H
+
+#include "../../compat/config.h"
+#include <linux/version.h>
+
+#include_next <linux/scatterlist.h>
+
+#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) || \
+       (defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 7 && RHEL_MINOR -0 >= 4)
+#ifndef HAVE_SG_ZERO_BUFFER
+/**
+ * sg_zero_buffer - Zero-out a part of a SG list
+ * @sgl:                The SG list
+ * @nents:              Number of SG entries
+ * @buflen:             The number of bytes to zero out
+ * @skip:               Number of bytes to skip before zeroing
+ *
+ * Returns the number of bytes zeroed.
+ **/
+static inline size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents,
+                      size_t buflen, off_t skip)
+{
+       unsigned int offset = 0;
+       struct sg_mapping_iter miter;
+       unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
+
+       sg_miter_start(&miter, sgl, nents, sg_flags);
+
+       if (!sg_miter_skip(&miter, skip))
+               return false;
+
+       while (offset < buflen && sg_miter_next(&miter)) {
+               unsigned int len;
+
+               len = min(miter.length, buflen - offset);
+               memset(miter.addr, 0, len);
+
+               offset += len;
+       }
+
+       sg_miter_stop(&miter);
+       return offset;
+}
+#endif /* HAVE_SG_ZERO_BUFFER */
+
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) */
+
+#if defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 7 && RHEL_MINOR -0 >= 2
+#if !defined(HAVE_SG_ALLOC_TABLE_CHAINED_4_PARAMS) && \
+    !defined(HAVE_SG_ALLOC_TABLE_CHAINED_3_PARAMS)
+
+#include <scsi/scsi.h>
+#include <linux/mempool.h>
+
+struct sg_pool {
+       size_t          size;
+       char            *name;
+       struct kmem_cache       *slab;
+       mempool_t       *pool;
+};
+
+#define SP(x) { .size = x, "sgpool-" __stringify(x) }
+#if (SCSI_MAX_SG_SEGMENTS < 32)
+#error SCSI_MAX_SG_SEGMENTS is too small (must be 32 or greater)
+#endif
+static struct sg_pool sg_pools[] = {
+       SP(8),
+       SP(16),
+#if (SCSI_MAX_SG_SEGMENTS > 32)
+       SP(32),
+#if (SCSI_MAX_SG_SEGMENTS > 64)
+       SP(64),
+#if (SCSI_MAX_SG_SEGMENTS > 128)
+       SP(128),
+#if (SCSI_MAX_SG_SEGMENTS > 256)
+#error SCSI_MAX_SG_SEGMENTS is too large (256 MAX)
+#endif
+#endif
+#endif
+#endif
+       SP(SCSI_MAX_SG_SEGMENTS)
+};
+#undef SP
+
+static inline unsigned int sg_pool_index(unsigned short nents)
+{
+       unsigned int index;
+
+       BUG_ON(nents > SCSI_MAX_SG_SEGMENTS);
+
+       if (nents <= 8)
+               index = 0;
+       else
+               index = get_count_order(nents) - 3;
+
+       return index;
+}
+
+static inline void sg_pool_free(struct scatterlist *sgl, unsigned int nents)
+{
+       struct sg_pool *sgp;
+
+       sgp = sg_pools + sg_pool_index(nents);
+       mempool_free(sgl, sgp->pool);
+}
+
+static inline struct scatterlist *sg_pool_alloc(unsigned int nents, gfp_t gfp_mask)
+{
+       struct sg_pool *sgp;
+
+       sgp = sg_pools + sg_pool_index(nents);
+       return mempool_alloc(sgp->pool, gfp_mask);
+}
+
+static inline void sg_free_table_chained(struct sg_table *table, bool first_chunk)
+{
+       if (first_chunk && table->orig_nents <= SCSI_MAX_SG_SEGMENTS)
+               return;
+       __sg_free_table(table, SCSI_MAX_SG_SEGMENTS, first_chunk, sg_pool_free);
+}
+
+static inline int sg_alloc_table_chained(struct sg_table *table, int nents,
+               struct scatterlist *first_chunk)
+{
+       int ret;
+
+       BUG_ON(!nents);
+
+       if (first_chunk) {
+               if (nents <= SCSI_MAX_SG_SEGMENTS) {
+                       table->nents = table->orig_nents = nents;
+                       sg_init_table(table->sgl, nents);
+                       return 0;
+               }
+       }
+
+       ret = __sg_alloc_table(table, nents, SCSI_MAX_SG_SEGMENTS,
+                              first_chunk, GFP_ATOMIC, sg_pool_alloc);
+       if (unlikely(ret))
+               sg_free_table_chained(table, (bool)first_chunk);
+       return ret;
+}
+#endif
+#endif /* defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 7 && RHEL_MINOR -0 >= 2 */
+
+#endif /* _COMPAT_LINUX_SCATTERLIST_H */
diff --git a/include/linux/string.h b/include/linux/string.h
new file mode 100644 (file)
index 0000000..5db1e33
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _COMPAT_LINUX_STRING_H
+#define _COMPAT_LINUX_STRING_H
+
+#include "../../compat/config.h"
+
+#include_next <linux/string.h>
+
+#ifndef HAVE_STRNICMP
+#ifndef __HAVE_ARCH_STRNICMP
+#define strnicmp strncasecmp
+#endif
+#endif /* HAVE_STRNICMP */
+
+#ifndef HAVE_MEMCHR_INV
+#define memchr_inv LINUX_BACKPORT(memchr_inv)
+void *memchr_inv(const void *start, int c, size_t bytes);
+#endif
+
+#ifndef HAVE_MEMDUP_USER_NUL
+#define memdup_user_nul LINUX_BACKPORT(memdup_user_nul)
+void *memdup_user_nul(const void __user *src, size_t len);
+#endif
+
+#ifndef HAVE_MEMCPY_AND_PAD
+/**
+ * memcpy_and_pad - Copy one buffer to another with padding
+ * @dest: Where to copy to
+ * @dest_len: The destination buffer size
+ * @src: Where to copy from
+ * @count: The number of bytes to copy
+ * @pad: Character to use for padding if space is left in destination.
+ */
+#define memcpy_and_pad LINUX_BACKPORT(memcpy_and_pad)
+static inline void memcpy_and_pad(void *dest, size_t dest_len,
+                                 const void *src, size_t count, int pad)
+{
+       if (dest_len > count) {
+               memcpy(dest, src, count);
+               memset(dest + count, pad,  dest_len - count);
+       } else
+               memcpy(dest, src, dest_len);
+}
+#endif
+
+#endif /* _COMPAT_LINUX_STRING_H */