Auto-detect whether to use hw assisted crc32c

Little point in separating the two. If the hardware assisted
crypto is available, always use it.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c
index 5040efe..8a6e6dc 100644
--- a/crc/crc32c-intel.c
+++ b/crc/crc32c-intel.c
@@ -18,6 +18,8 @@
  * Volume 2A: Instruction Set Reference, A-M
  */
 
+int crc32c_intel_available = 0;
+
 #ifdef ARCH_HAVE_SSE4_2
 
 #if BITS_PER_LONG == 64
@@ -28,6 +30,8 @@
 #define SCALE_F 4
 #endif
 
+static int crc32c_probed;
+
 static uint32_t crc32c_intel_le_hw_byte(uint32_t crc, unsigned char const *data,
 					unsigned long length)
 {
@@ -90,14 +94,17 @@
 		: "eax", "ebx", "ecx", "edx");
 }
 
-int crc32c_intel_works(void)
+void crc32c_intel_probe(void)
 {
-	unsigned int eax, ebx, ecx, edx;
+	if (!crc32c_probed) {
+		unsigned int eax, ebx, ecx, edx;
 
-	eax = 1;
+		eax = 1;
 
-	do_cpuid(&eax, &ebx, &ecx, &edx);
-	return (ecx & (1 << 20)) != 0;
+		do_cpuid(&eax, &ebx, &ecx, &edx);
+		crc32c_intel_available = (ecx & (1 << 20)) != 0;
+		crc32c_probed = 1;
+	}
 }
 
 #endif /* ARCH_HAVE_SSE */
diff --git a/crc/crc32c.c b/crc/crc32c.c
index 8bbea68..b830b9f 100644
--- a/crc/crc32c.c
+++ b/crc/crc32c.c
@@ -113,7 +113,7 @@
  * crc using table.
  */
 
-uint32_t crc32c(unsigned char const *data, unsigned long length)
+uint32_t crc32c_sw(unsigned char const *data, unsigned long length)
 {
 	uint32_t crc = ~0;
 
diff --git a/crc/crc32c.h b/crc/crc32c.h
index 596fd6c..46c1063 100644
--- a/crc/crc32c.h
+++ b/crc/crc32c.h
@@ -20,17 +20,25 @@
 
 #include "../arch/arch.h"
 
-extern uint32_t crc32c(unsigned char const *, unsigned long);
+extern uint32_t crc32c_sw(unsigned char const *, unsigned long);
+extern int crc32c_intel_available;
 
 #ifdef ARCH_HAVE_SSE4_2
 extern uint32_t crc32c_intel(unsigned char const *, unsigned long);
-extern int crc32c_intel_works(void);
+extern void crc32c_intel_probe(void);
 #else
-#define crc32c_intel crc32c
-static inline int crc32c_intel_works(void)
+#define crc32c_intel crc32c_sw
+static inline void crc32c_intel_probe(void)
 {
-	return 0;
 }
 #endif
 
+static inline uint32_t crc32c(unsigned char const *buf, unsigned long len)
+{
+	if (crc32c_intel_available)
+		return crc32c_intel(buf, len);
+
+	return crc32c_sw(buf, len);
+}
+
 #endif
diff --git a/options.c b/options.c
index bd8141a..d777efc 100644
--- a/options.c
+++ b/options.c
@@ -245,12 +245,9 @@
 {
 	struct thread_data *td = data;
 
-	if (td->o.verify != VERIFY_CRC32C_INTEL)
-		return 0;
-
-	if (!crc32c_intel_works()) {
-		log_info("fio: System does not support hw accelerated crc32c. Falling back to sw crc32c.\n");
-		td->o.verify = VERIFY_CRC32C;
+	if (td->o.verify == VERIFY_CRC32C_INTEL ||
+	    td->o.verify == VERIFY_CRC32C) {
+		crc32c_intel_probe();
 	}
 
 	return 0;
@@ -1482,12 +1479,12 @@
 			    .help = "Use crc32 checksums for verification",
 			  },
 			  { .ival = "crc32c-intel",
-			    .oval = VERIFY_CRC32C_INTEL,
-			    .help = "Use hw crc32c checksums for verification",
+			    .oval = VERIFY_CRC32C,
+			    .help = "Use crc32c checksums for verification (hw assisted, if available)",
 			  },
 			  { .ival = "crc32c",
 			    .oval = VERIFY_CRC32C,
-			    .help = "Use crc32c checksums for verification",
+			    .help = "Use crc32c checksums for verification (hw assisted, if available)",
 			  },
 			  { .ival = "crc16",
 			    .oval = VERIFY_CRC16,
diff --git a/verify.c b/verify.c
index 8bf14ae..d6abb98 100644
--- a/verify.c
+++ b/verify.c
@@ -551,10 +551,7 @@
 
 	dprint(FD_VERIFY, "crc32c verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-	if (hdr->verify_type == VERIFY_CRC32C_INTEL)
-		c = crc32c_intel(p, hdr->len - hdr_size(hdr));
-	else
-		c = crc32c(p, hdr->len - hdr_size(hdr));
+	c = crc32c(p, hdr->len - hdr_size(hdr));
 
 	if (c == vh->crc32)
 		return 0;
@@ -833,10 +830,7 @@
 {
 	struct vhdr_crc32 *vh = hdr_priv(hdr);
 
-	if (hdr->verify_type == VERIFY_CRC32C_INTEL)
-		vh->crc32 = crc32c_intel(p, len);
-	else
-		vh->crc32 = crc32c(p, len);
+	vh->crc32 = crc32c(p, len);
 }
 
 static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)