[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
--- /dev/null
+#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 */
--- /dev/null
+#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 */