summaryrefslogtreecommitdiff
path: root/crc
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2012-02-22 20:28:17 +0100
committerJens Axboe <axboe@kernel.dk>2012-02-22 20:28:17 +0100
commite3aaafc4e902a0f78b8ee4d4bc85f8edac6e09d2 (patch)
tree05a25267deb1da1058c2cf6ffd28195496e9f0ab /crc
parentf65d1c2663ac6007eac1a2063fe25b4275d013e4 (diff)
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>
Diffstat (limited to 'crc')
-rw-r--r--crc/crc32c-intel.c17
-rw-r--r--crc/crc32c.c2
-rw-r--r--crc/crc32c.h18
3 files changed, 26 insertions, 11 deletions
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 @@ static void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
: "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 @@ static const uint32_t crc32c_table[256] = {
* 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