aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grukservices.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/sgi-gru/grukservices.c')
-rw-r--r--drivers/misc/sgi-gru/grukservices.c150
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
849int quicktest(void) 849static 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; 888done:
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
895static 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
929done:
930 kfree(p);
931 return ret;
932}
933
934static 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);
980done:
981 kfree(buf);
982 return ret;
983}
984
985/*
986 * Debugging only. User hook for various kernel tests
987 * of driver & gru.
988 */
989int 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
885int gru_kservices_init(struct gru_state *gru) 1008int 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