From: "H. Peter Anvin" This patch fixes a signedness bug with RAID6 for Altivec, and makes the Altivec code testable in userspace. Signed-off-by: H. Peter Anvin Signed-off-by: Andrew Morton --- drivers/md/raid6.h | 4 ++++ drivers/md/raid6algos.c | 1 + drivers/md/raid6altivec.uc | 18 +++++++++++++----- drivers/md/raid6test/Makefile | 27 ++++++++++++++++++++++----- 4 files changed, 40 insertions(+), 10 deletions(-) diff -puN drivers/md/raid6algos.c~raid6-altivec-fix drivers/md/raid6algos.c --- devel/drivers/md/raid6algos.c~raid6-altivec-fix 2005-09-14 20:12:53.000000000 -0700 +++ devel-akpm/drivers/md/raid6algos.c 2005-09-14 20:12:53.000000000 -0700 @@ -19,6 +19,7 @@ #include "raid6.h" #ifndef __KERNEL__ #include +#include #endif struct raid6_calls raid6_call; diff -puN drivers/md/raid6altivec.uc~raid6-altivec-fix drivers/md/raid6altivec.uc --- devel/drivers/md/raid6altivec.uc~raid6-altivec-fix 2005-09-14 20:12:53.000000000 -0700 +++ devel-akpm/drivers/md/raid6altivec.uc 2005-09-14 20:12:53.000000000 -0700 @@ -27,16 +27,20 @@ #ifdef CONFIG_ALTIVEC #include -#include -#include +#ifdef __KERNEL__ +# include +# include +#endif /* - * This is the C data type to use + * This is the C data type to use. We use a vector of + * signed char so vec_cmpgt() will generate the right + * instruction. */ -typedef vector unsigned char unative_t; +typedef vector signed char unative_t; -#define NBYTES(x) ((vector unsigned char) {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}) +#define NBYTES(x) ((vector signed char) {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}) #define NSIZE sizeof(unative_t) /* @@ -108,7 +112,11 @@ int raid6_have_altivec(void); int raid6_have_altivec(void) { /* This assumes either all CPUs have Altivec or none does */ +# ifdef __KERNEL__ return cpu_has_feature(CPU_FTR_ALTIVEC); +# else + return 1; +# endif } #endif diff -puN drivers/md/raid6.h~raid6-altivec-fix drivers/md/raid6.h --- devel/drivers/md/raid6.h~raid6-altivec-fix 2005-09-14 20:12:53.000000000 -0700 +++ devel-akpm/drivers/md/raid6.h 2005-09-14 20:12:53.000000000 -0700 @@ -69,9 +69,13 @@ extern const char raid6_empty_zero_page[ #define __init #define __exit #define __attribute_const__ __attribute__((const)) +#define noinline __attribute__((noinline)) #define preempt_enable() #define preempt_disable() +#define cpu_has_feature(x) 1 +#define enable_kernel_altivec() +#define disable_kernel_altivec() #endif /* __KERNEL__ */ diff -puN drivers/md/raid6test/Makefile~raid6-altivec-fix drivers/md/raid6test/Makefile --- devel/drivers/md/raid6test/Makefile~raid6-altivec-fix 2005-09-14 20:12:53.000000000 -0700 +++ devel-akpm/drivers/md/raid6test/Makefile 2005-09-14 20:12:53.000000000 -0700 @@ -8,6 +8,8 @@ OPTFLAGS = -O2 # Adjust as desired CFLAGS = -I.. -g $(OPTFLAGS) LD = ld PERL = perl +AR = ar +RANLIB = ranlib .c.o: $(CC) $(CFLAGS) -c -o $@ $< @@ -18,18 +20,33 @@ PERL = perl %.uc: ../%.uc cp -f $< $@ -all: raid6.o raid6test +all: raid6.a raid6test -raid6.o: raid6int1.o raid6int2.o raid6int4.o raid6int8.o raid6int16.o \ +raid6.a: raid6int1.o raid6int2.o raid6int4.o raid6int8.o raid6int16.o \ raid6int32.o \ raid6mmx.o raid6sse1.o raid6sse2.o \ + raid6altivec1.o raid6altivec2.o raid6altivec4.o raid6altivec8.o \ raid6recov.o raid6algos.o \ raid6tables.o - $(LD) -r -o $@ $^ + rm -f $@ + $(AR) cq $@ $^ + $(RANLIB) $@ -raid6test: raid6.o test.c +raid6test: test.c raid6.a $(CC) $(CFLAGS) -o raid6test $^ +raid6altivec1.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 1 < raid6altivec.uc > $@ + +raid6altivec2.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 2 < raid6altivec.uc > $@ + +raid6altivec4.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 4 < raid6altivec.uc > $@ + +raid6altivec8.c: raid6altivec.uc ../unroll.pl + $(PERL) ../unroll.pl 8 < raid6altivec.uc > $@ + raid6int1.c: raid6int.uc ../unroll.pl $(PERL) ../unroll.pl 1 < raid6int.uc > $@ @@ -52,7 +69,7 @@ raid6tables.c: mktables ./mktables > raid6tables.c clean: - rm -f *.o mktables mktables.c raid6int.uc raid6*.c raid6test + rm -f *.o *.a mktables mktables.c raid6int.uc raid6*.c raid6test spotless: clean rm -f *~ _