diff options
Diffstat (limited to 'drivers/misc/sgi-gru/grukservices.c')
-rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 150 |
1 files changed, 135 insertions, 15 deletions
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index 9dff33cb72e3..7d7952b27e03 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c | |||
@@ -846,13 +846,14 @@ EXPORT_SYMBOL_GPL(gru_copy_gpa); | |||
846 | /* ------------------- KERNEL QUICKTESTS RUN AT STARTUP ----------------*/ | 846 | /* ------------------- KERNEL QUICKTESTS RUN AT STARTUP ----------------*/ |
847 | /* Temp - will delete after we gain confidence in the GRU */ | 847 | /* Temp - will delete after we gain confidence in the GRU */ |
848 | 848 | ||
849 | int quicktest(void) | 849 | static int quicktest0(unsigned long arg) |
850 | { | 850 | { |
851 | unsigned long word0; | 851 | unsigned long word0; |
852 | unsigned long word1; | 852 | unsigned long word1; |
853 | void *cb; | 853 | void *cb; |
854 | void *dsr; | 854 | void *dsr; |
855 | unsigned long *p; | 855 | unsigned long *p; |
856 | int ret = -EIO; | ||
856 | 857 | ||
857 | if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr)) | 858 | if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr)) |
858 | return MQE_BUG_NO_RESOURCES; | 859 | return MQE_BUG_NO_RESOURCES; |
@@ -861,26 +862,148 @@ int quicktest(void) | |||
861 | word1 = 0; | 862 | word1 = 0; |
862 | 863 | ||
863 | gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); | 864 | gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); |
864 | if (gru_wait(cb) != CBS_IDLE) | 865 | if (gru_wait(cb) != CBS_IDLE) { |
865 | BUG(); | 866 | printk(KERN_DEBUG "GRU quicktest0: CBR failure 1\n"); |
867 | goto done; | ||
868 | } | ||
866 | 869 | ||
867 | if (*p != MAGIC) | 870 | if (*p != MAGIC) { |
868 | BUG(); | 871 | printk(KERN_DEBUG "GRU: quicktest0 bad magic 0x%lx\n", *p); |
872 | goto done; | ||
873 | } | ||
869 | gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); | 874 | gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); |
870 | if (gru_wait(cb) != CBS_IDLE) | 875 | if (gru_wait(cb) != CBS_IDLE) { |
871 | BUG(); | 876 | printk(KERN_DEBUG "GRU quicktest0: CBR failure 2\n"); |
872 | gru_free_cpu_resources(cb, dsr); | 877 | goto done; |
878 | } | ||
873 | 879 | ||
874 | if (word0 != word1 || word1 != MAGIC) { | 880 | if (word0 != word1 || word1 != MAGIC) { |
875 | printk | 881 | printk(KERN_DEBUG |
876 | ("GRU quicktest err: found 0x%lx, expected 0x%lx\n", | 882 | "GRU quicktest0 err: found 0x%lx, expected 0x%lx\n", |
877 | word1, MAGIC); | 883 | word1, MAGIC); |
878 | BUG(); /* ZZZ should not be fatal */ | 884 | goto done; |
879 | } | 885 | } |
886 | ret = 0; | ||
880 | 887 | ||
881 | return 0; | 888 | done: |
889 | gru_free_cpu_resources(cb, dsr); | ||
890 | return ret; | ||
882 | } | 891 | } |
883 | 892 | ||
893 | #define ALIGNUP(p, q) ((void *)(((unsigned long)(p) + (q) - 1) & ~(q - 1))) | ||
894 | |||
895 | static int quicktest1(unsigned long arg) | ||
896 | { | ||
897 | struct gru_message_queue_desc mqd; | ||
898 | void *p, *mq; | ||
899 | unsigned long *dw; | ||
900 | int i, ret = -EIO; | ||
901 | char mes[GRU_CACHE_LINE_BYTES], *m; | ||
902 | |||
903 | /* Need 1K cacheline aligned that does not cross page boundary */ | ||
904 | p = kmalloc(4096, 0); | ||
905 | mq = ALIGNUP(p, 1024); | ||
906 | memset(mes, 0xee, sizeof(mes)); | ||
907 | dw = mq; | ||
908 | |||
909 | gru_create_message_queue(&mqd, mq, 8 * GRU_CACHE_LINE_BYTES, 0, 0, 0); | ||
910 | for (i = 0; i < 6; i++) { | ||
911 | mes[8] = i; | ||
912 | do { | ||
913 | ret = gru_send_message_gpa(&mqd, mes, sizeof(mes)); | ||
914 | } while (ret == MQE_CONGESTION); | ||
915 | if (ret) | ||
916 | break; | ||
917 | } | ||
918 | if (ret != MQE_QUEUE_FULL || i != 4) | ||
919 | goto done; | ||
920 | |||
921 | for (i = 0; i < 6; i++) { | ||
922 | m = gru_get_next_message(&mqd); | ||
923 | if (!m || m[8] != i) | ||
924 | break; | ||
925 | gru_free_message(&mqd, m); | ||
926 | } | ||
927 | ret = (i == 4) ? 0 : -EIO; | ||
928 | |||
929 | done: | ||
930 | kfree(p); | ||
931 | return ret; | ||
932 | } | ||
933 | |||
934 | static int quicktest2(unsigned long arg) | ||
935 | { | ||
936 | static DECLARE_COMPLETION(cmp); | ||
937 | unsigned long han; | ||
938 | int blade_id = 0; | ||
939 | int numcb = 4; | ||
940 | int ret = 0; | ||
941 | unsigned long *buf; | ||
942 | void *cb0, *cb; | ||
943 | int i, k, istatus, bytes; | ||
944 | |||
945 | bytes = numcb * 4 * 8; | ||
946 | buf = kmalloc(bytes, GFP_KERNEL); | ||
947 | if (!buf) | ||
948 | return -ENOMEM; | ||
949 | |||
950 | ret = -EBUSY; | ||
951 | han = gru_reserve_async_resources(blade_id, numcb, 0, &cmp); | ||
952 | if (!han) | ||
953 | goto done; | ||
954 | |||
955 | gru_lock_async_resource(han, &cb0, NULL); | ||
956 | memset(buf, 0xee, bytes); | ||
957 | for (i = 0; i < numcb; i++) | ||
958 | gru_vset(cb0 + i * GRU_HANDLE_STRIDE, uv_gpa(&buf[i * 4]), 0, | ||
959 | XTYPE_DW, 4, 1, IMA_INTERRUPT); | ||
960 | |||
961 | ret = 0; | ||
962 | for (k = 0; k < numcb; k++) { | ||
963 | gru_wait_async_cbr(han); | ||
964 | for (i = 0; i < numcb; i++) { | ||
965 | cb = cb0 + i * GRU_HANDLE_STRIDE; | ||
966 | istatus = gru_check_status(cb); | ||
967 | if (istatus == CBS_ACTIVE) | ||
968 | continue; | ||
969 | if (istatus == CBS_EXCEPTION) | ||
970 | ret = -EFAULT; | ||
971 | else if (buf[i] || buf[i + 1] || buf[i + 2] || | ||
972 | buf[i + 3]) | ||
973 | ret = -EIO; | ||
974 | } | ||
975 | } | ||
976 | BUG_ON(cmp.done); | ||
977 | |||
978 | gru_unlock_async_resource(han); | ||
979 | gru_release_async_resources(han); | ||
980 | done: | ||
981 | kfree(buf); | ||
982 | return ret; | ||
983 | } | ||
984 | |||
985 | /* | ||
986 | * Debugging only. User hook for various kernel tests | ||
987 | * of driver & gru. | ||
988 | */ | ||
989 | int gru_ktest(unsigned long arg) | ||
990 | { | ||
991 | int ret = -EINVAL; | ||
992 | |||
993 | switch (arg & 0xff) { | ||
994 | case 0: | ||
995 | ret = quicktest0(arg); | ||
996 | break; | ||
997 | case 1: | ||
998 | ret = quicktest1(arg); | ||
999 | break; | ||
1000 | case 2: | ||
1001 | ret = quicktest2(arg); | ||
1002 | break; | ||
1003 | } | ||
1004 | return ret; | ||
1005 | |||
1006 | } | ||
884 | 1007 | ||
885 | int gru_kservices_init(struct gru_state *gru) | 1008 | int gru_kservices_init(struct gru_state *gru) |
886 | { | 1009 | { |
@@ -891,9 +1014,6 @@ int gru_kservices_init(struct gru_state *gru) | |||
891 | return 0; | 1014 | return 0; |
892 | 1015 | ||
893 | init_rwsem(&bs->bs_kgts_sema); | 1016 | init_rwsem(&bs->bs_kgts_sema); |
894 | |||
895 | if (gru_options & GRU_QUICKLOOK) | ||
896 | quicktest(); | ||
897 | return 0; | 1017 | return 0; |
898 | } | 1018 | } |
899 | 1019 | ||