1
2
3
4
5
6
7
8
9
10
11#include <linux/types.h>
12#include <linux/config.h>
13#include <linux/slab.h>
14#include <linux/ctype.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/fs.h>
19#include <linux/string.h>
20#include <linux/sched.h>
21#include <linux/smp_lock.h>
22#include <asm/sn/sgi.h>
23#include <asm/io.h>
24#include <asm/sn/iograph.h>
25#include <asm/sn/hwgfs.h>
26#include <asm/sn/invent.h>
27#include <asm/sn/hcl.h>
28#include <asm/sn/labelcl.h>
29#include <asm/sn/simulator.h>
30
31#define vertex_hdl_t hwgfs_handle_t
32
33vertex_hdl_t hwgraph_root;
34vertex_hdl_t linux_busnum;
35extern void pci_bus_cvlink_init(void);
36unsigned long hwgraph_debug_mask = 0;
37
38
39
40
41#define OPTION_NONE 0x00
42#define HCL_DEBUG_NONE 0x00000
43#define HCL_DEBUG_ALL 0x0ffff
44#if defined(CONFIG_HCL_DEBUG)
45static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
46#endif
47static unsigned int hcl_debug = HCL_DEBUG_NONE;
48#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
49static unsigned int boot_options = OPTION_NONE;
50#endif
51
52
53
54
55vertex_hdl_t hcl_handle;
56
57invplace_t invplace_none = {
58 GRAPH_VERTEX_NONE,
59 GRAPH_VERTEX_PLACE_NONE,
60 NULL
61};
62
63
64
65
66
67
68
69
70
71static int hcl_open(struct inode * inode, struct file * filp)
72{
73 if (hcl_debug) {
74 printk("HCL: hcl_open called.\n");
75 }
76
77 return(0);
78
79}
80
81static int hcl_close(struct inode * inode, struct file * filp)
82{
83
84 if (hcl_debug) {
85 printk("HCL: hcl_close called.\n");
86 }
87
88 return(0);
89
90}
91
92static int hcl_ioctl(struct inode * inode, struct file * file,
93 unsigned int cmd, unsigned long arg)
94{
95
96 if (hcl_debug) {
97 printk("HCL: hcl_ioctl called.\n");
98 }
99
100 switch (cmd) {
101 default:
102 if (hcl_debug) {
103 printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
104 }
105 }
106
107 return(0);
108
109}
110
111struct file_operations hcl_fops = {
112 (struct module *)0,
113 NULL,
114 NULL,
115 NULL,
116 NULL,
117 NULL,
118 hcl_ioctl,
119 NULL,
120 hcl_open,
121 NULL,
122 hcl_close,
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 NULL,
128};
129
130
131
132
133
134
135int __init init_hcl(void)
136{
137 extern void string_table_init(struct string_table *);
138 extern struct string_table label_string_table;
139 extern int init_ifconfig_net(void);
140 extern int init_ioconfig_bus(void);
141 extern int init_hwgfs_fs(void);
142 int rv = 0;
143
144 if (IS_RUNNING_ON_SIMULATOR()) {
145 extern u64 klgraph_addr[];
146 klgraph_addr[0] = 0xe000003000030000;
147 }
148
149 init_hwgfs_fs();
150
151
152
153
154 rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
155 if (rv)
156 panic("init_hcl: Failed to create hwgraph_root.\n");
157
158
159
160
161
162 hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
163 0, DEVFS_FL_AUTO_DEVNUM,
164 0, 0,
165 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
166 &hcl_fops, NULL);
167
168 if (hcl_handle == NULL) {
169 panic("HCL: Unable to create HCL Driver in init_hcl().\n");
170 return(0);
171 }
172
173
174
175
176
177 string_table_init(&label_string_table);
178
179
180
181
182 rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
183 if (linux_busnum == NULL) {
184 panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
185 return(0);
186 }
187
188 pci_bus_cvlink_init();
189
190
191
192
193
194 init_ifconfig_net();
195 init_ioconfig_bus();
196
197 return(0);
198
199}
200
201
202
203
204
205
206
207
208
209
210
211
212static int __init hcl_setup(char *str)
213{
214 while ( (*str != '\0') && !isspace (*str) )
215 {
216#ifdef CONFIG_HCL_DEBUG
217 if (strncmp (str, "all", 3) == 0) {
218 hcl_debug_init |= HCL_DEBUG_ALL;
219 str += 3;
220 } else
221 return 0;
222#endif
223 if (*str != ',') return 0;
224 ++str;
225 }
226
227 return 1;
228
229}
230
231__setup("hcl=", hcl_setup);
232
233
234int
235hwgraph_generate_path(
236 vertex_hdl_t de,
237 char *path,
238 int buflen)
239{
240 return (hwgfs_generate_path(de, path, buflen));
241}
242
243
244
245
246
247void
248hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
249{
250 labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
251}
252
253
254
255
256
257
258arbitrary_info_t
259hwgraph_fastinfo_get(vertex_hdl_t de)
260{
261 arbitrary_info_t fastinfo;
262 int rv;
263
264 if (!de) {
265 printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
266 return(-1);
267 }
268
269 rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
270 if (rv == 0)
271 return(fastinfo);
272
273 return(0);
274}
275
276
277
278
279
280
281
282int
283hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
284{
285 int rv;
286
287 if (!de)
288 return(-1);
289
290 rv = labelcl_info_connectpt_set(de, connect_de);
291
292 return(rv);
293}
294
295
296
297
298
299
300vertex_hdl_t
301hwgraph_connectpt_get(vertex_hdl_t de)
302{
303 int rv;
304 arbitrary_info_t info;
305 vertex_hdl_t connect;
306
307 rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
308 if (rv != 0) {
309 return(NULL);
310 }
311
312 connect = (vertex_hdl_t)info;
313 return(connect);
314
315}
316
317
318
319
320
321vertex_hdl_t
322hwgraph_mk_dir(vertex_hdl_t de, const char *name,
323 unsigned int namelen, void *info)
324{
325
326 int rv;
327 labelcl_info_t *labelcl_info = NULL;
328 vertex_hdl_t new_handle = NULL;
329 vertex_hdl_t parent = NULL;
330
331
332
333
334 labelcl_info = labelcl_info_create();
335 if (!labelcl_info)
336 return(NULL);
337
338
339
340
341 new_handle = hwgfs_mk_dir(de, name, (void *)labelcl_info);
342 if (!new_handle) {
343 labelcl_info_destroy(labelcl_info);
344 return(NULL);
345 }
346
347
348
349
350 parent = hwgfs_get_parent (new_handle);
351
352
353
354
355 rv = hwgraph_connectpt_set(new_handle, parent);
356 if (!rv) {
357
358
359
360 }
361
362
363
364
365
366
367 if (info)
368 hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
369
370 return(new_handle);
371
372}
373
374
375
376
377
378int
379hwgraph_path_add(vertex_hdl_t fromv,
380 char *path,
381 vertex_hdl_t *new_de)
382{
383
384 unsigned int namelen = strlen(path);
385 int rv;
386
387
388
389
390
391
392 if (fromv == NULL)
393 fromv = hwgraph_root;
394
395
396
397
398
399
400 rv = hwgraph_edge_get(fromv, path, new_de);
401 if (rv) {
402 *new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
403 if (new_de == NULL)
404 return(-1);
405 else
406 return(0);
407 }
408 else
409 return(0);
410
411}
412
413
414
415
416
417vertex_hdl_t
418hwgraph_register(vertex_hdl_t de, const char *name,
419 unsigned int namelen, unsigned int flags,
420 unsigned int major, unsigned int minor,
421 umode_t mode, uid_t uid, gid_t gid,
422 struct file_operations *fops,
423 void *info)
424{
425
426 vertex_hdl_t new_handle = NULL;
427
428
429
430
431 new_handle = hwgfs_register(de, name, flags, major,
432 minor, mode, fops, info);
433
434 return(new_handle);
435
436}
437
438
439
440
441
442int
443hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
444 unsigned int flags, const char *link, unsigned int linklen,
445 vertex_hdl_t *handle, void *info)
446{
447
448 void *labelcl_info = NULL;
449 int status = 0;
450 vertex_hdl_t new_handle = NULL;
451
452
453
454
455 labelcl_info = labelcl_info_create();
456 if (!labelcl_info)
457 return(-1);
458
459
460
461
462 status = hwgfs_mk_symlink(de, name, flags, link,
463 &new_handle, labelcl_info);
464 if ( (!new_handle) || (!status) ){
465 labelcl_info_destroy((labelcl_info_t *)labelcl_info);
466 return(-1);
467 }
468
469
470
471
472
473
474 if (info)
475 hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
476
477 *handle = new_handle;
478 return(0);
479
480}
481
482
483
484
485int
486hwgraph_vertex_destroy(vertex_hdl_t de)
487{
488
489 void *labelcl_info = NULL;
490
491 labelcl_info = hwgfs_get_info(de);
492 hwgfs_unregister(de);
493
494 if (labelcl_info)
495 labelcl_info_destroy((labelcl_info_t *)labelcl_info);
496
497 return(0);
498}
499
500int
501hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
502{
503
504 char *path, *link;
505 char *s1;
506 char *index;
507 vertex_hdl_t handle = NULL;
508 int rv;
509 int i, count;
510
511 path = kmalloc(1024, GFP_KERNEL);
512 memset((char *)path, 0x0, 1024);
513 link = kmalloc(1024, GFP_KERNEL);
514 memset((char *)link, 0x0, 1024);
515
516 i = hwgfs_generate_path (from, path, 1024);
517 s1 = (char *)path;
518 count = 0;
519 while (1) {
520 index = strstr (s1, "/");
521 if (index) {
522 count++;
523 s1 = ++index;
524 } else {
525 count++;
526 break;
527 }
528 }
529
530 for (i = 0; i < count; i++) {
531 strcat((char *)link,"../");
532 }
533
534 memset(path, 0x0, 1024);
535 i = hwgfs_generate_path (to, path, 1024);
536 strcat((char *)link, (char *)path);
537
538
539
540
541
542 rv = hwgfs_mk_symlink (from, (const char *)name,
543 DEVFS_FL_DEFAULT, link,
544 &handle, NULL);
545 kfree(path);
546 kfree(link);
547
548 return(rv);
549
550
551}
552
553
554int
555hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
556{
557
558 vertex_hdl_t target_handle = NULL;
559
560 if (name == NULL)
561 return(-1);
562
563 if (toptr == NULL)
564 return(-1);
565
566
567
568
569 if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
570 if (toptr) {
571 *toptr = from;
572 }
573 } else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
574
575
576
577
578
579
580
581 target_handle = hwgraph_connectpt_get(from);
582 if (target_handle) {
583
584
585
586 *toptr = target_handle;
587 return(0);
588 }
589 target_handle = hwgfs_get_parent(from);
590 *toptr = target_handle;
591
592 } else {
593 target_handle = hwgfs_find_handle (from, name, 0, 0,
594 0, 1);
595 }
596
597 if (target_handle == NULL)
598 return(-1);
599 else
600 *toptr = target_handle;
601
602 return(0);
603}
604
605
606
607
608
609
610int
611hwgraph_info_add_LBL( vertex_hdl_t de,
612 char *name,
613 arbitrary_info_t info)
614{
615 return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
616}
617
618
619
620
621
622int
623hwgraph_info_remove_LBL( vertex_hdl_t de,
624 char *name,
625 arbitrary_info_t *old_info)
626{
627 return(labelcl_info_remove_LBL(de, name, NULL, old_info));
628}
629
630
631
632
633
634
635int
636hwgraph_info_replace_LBL( vertex_hdl_t de,
637 char *name,
638 arbitrary_info_t info,
639 arbitrary_info_t *old_info)
640{
641 return(labelcl_info_replace_LBL(de, name,
642 INFO_DESC_PRIVATE, info,
643 NULL, old_info));
644}
645
646
647
648
649
650int
651hwgraph_info_get_LBL(vertex_hdl_t de,
652 char *name,
653 arbitrary_info_t *infop)
654{
655 return(labelcl_info_get_LBL(de, name, NULL, infop));
656}
657
658
659
660
661
662
663
664
665int
666hwgraph_info_get_exported_LBL(vertex_hdl_t de,
667 char *name,
668 int *export_info,
669 arbitrary_info_t *infop)
670{
671 int rc;
672 arb_info_desc_t info_desc;
673
674 rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
675 if (rc == 0)
676 *export_info = (int)info_desc;
677
678 return(rc);
679}
680
681
682
683
684
685
686
687
688
689int
690hwgraph_info_get_next_LBL(vertex_hdl_t de,
691 char *buf,
692 arbitrary_info_t *infop,
693 labelcl_info_place_t *place)
694{
695 return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
696}
697
698
699
700
701
702
703int
704hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
705{
706 arbitrary_info_t info;
707 int rc;
708
709 if (nbytes == 0)
710 nbytes = INFO_DESC_EXPORT;
711
712 if (nbytes < 0)
713 return(-1);
714
715 rc = labelcl_info_get_LBL(de, name, NULL, &info);
716 if (rc != 0)
717 return(rc);
718
719 rc = labelcl_info_replace_LBL(de, name,
720 nbytes, info, NULL, NULL);
721
722 return(rc);
723}
724
725
726
727
728
729
730int
731hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
732{
733 arbitrary_info_t info;
734 int rc;
735
736 rc = labelcl_info_get_LBL(de, name, NULL, &info);
737 if (rc != 0)
738 return(rc);
739
740 rc = labelcl_info_replace_LBL(de, name,
741 INFO_DESC_PRIVATE, info, NULL, NULL);
742
743 return(rc);
744}
745
746
747
748
749
750int
751hwgraph_path_lookup(vertex_hdl_t start_vertex_handle,
752 char *lookup_path,
753 vertex_hdl_t *vertex_handle_ptr,
754 char **remainder)
755{
756 *vertex_handle_ptr = hwgfs_find_handle(start_vertex_handle,
757 lookup_path,
758 0,
759 0,
760 0,
761 1);
762 if (*vertex_handle_ptr == NULL)
763 return(-1);
764 else
765 return(0);
766}
767
768
769
770
771
772graph_error_t
773hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
774{
775
776
777
778
779 *found = hwgfs_find_handle(de,
780 path,
781 0,
782 0,
783 0,
784 1);
785 if (*found == NULL)
786 return(GRAPH_NOT_FOUND);
787 else
788 return(GRAPH_SUCCESS);
789}
790
791
792
793
794
795vertex_hdl_t
796hwgraph_path_to_vertex(char *path)
797{
798 return(hwgfs_find_handle(NULL,
799 path,
800 0,
801 0,
802 0,
803 1));
804}
805
806
807
808
809
810
811
812
813int
814hwgraph_inventory_remove( vertex_hdl_t de,
815 int class,
816 int type,
817 major_t controller,
818 minor_t unit,
819 int state)
820{
821 return(0);
822}
823
824
825
826
827
828
829
830
831
832
833
834
835int
836hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
837{
838 char *locbuf;
839 int pos;
840
841 if (buflen < 1)
842 return(-1);
843
844 locbuf = kmalloc(buflen, GFP_KERNEL);
845
846 pos = hwgfs_generate_path(vhdl, locbuf, buflen);
847 if (pos < 0) {
848 kfree(locbuf);
849 return pos;
850 }
851
852 strcpy(buf, &locbuf[pos]);
853 kfree(locbuf);
854 return 0;
855}
856
857
858
859
860
861
862
863
864
865
866
867
868#define DEVNAME_UNKNOWN "UnknownDevice"
869
870char *
871vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
872{
873 if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
874 return(buf);
875 else
876 return(DEVNAME_UNKNOWN);
877}
878
879graph_error_t
880hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
881{
882 return(GRAPH_ILLEGAL_REQUEST);
883}
884
885graph_error_t
886hwgraph_vertex_unref(vertex_hdl_t vhdl)
887{
888 return(GRAPH_ILLEGAL_REQUEST);
889}
890
891void
892hwgraph_debug(char *file, char * function, int line, vertex_hdl_t vhdl1, vertex_hdl_t vhdl2, char *format, ...)
893{
894
895 int pos;
896 char *hwpath;
897 va_list ap;
898
899 if ( !hwgraph_debug_mask )
900 return;
901
902 hwpath = kmalloc(MAXDEVNAME, GFP_KERNEL);
903 if (!hwpath)
904 BUG();
905
906 printk("HWGRAPH_DEBUG %s %s %d : ", file, function, line);
907
908 if (vhdl1){
909 memset(hwpath, 0, MAXDEVNAME);
910 pos = hwgfs_generate_path(vhdl1, hwpath, MAXDEVNAME);
911 printk("vhdl1 = %s : ", &hwpath[pos]);
912 }
913
914 if (vhdl2){
915 memset(hwpath, 0, MAXDEVNAME);
916 pos = hwgfs_generate_path(vhdl2, hwpath, MAXDEVNAME);
917 printk("vhdl2 = %s :", &hwpath[pos]);
918 }
919
920 memset(hwpath, 0, MAXDEVNAME);
921 va_start(ap, format);
922 vsnprintf(hwpath, 500, format, ap);
923 va_end(ap);
924 hwpath[MAXDEVNAME -1] = (char)0;
925 printk(" %s", hwpath);
926 kfree(hwpath);
927}
928
929EXPORT_SYMBOL(hwgraph_mk_dir);
930EXPORT_SYMBOL(hwgraph_path_add);
931EXPORT_SYMBOL(hwgraph_register);
932EXPORT_SYMBOL(hwgraph_vertex_destroy);
933EXPORT_SYMBOL(hwgraph_fastinfo_get);
934EXPORT_SYMBOL(hwgraph_fastinfo_set);
935EXPORT_SYMBOL(hwgraph_connectpt_set);
936EXPORT_SYMBOL(hwgraph_connectpt_get);
937EXPORT_SYMBOL(hwgraph_info_add_LBL);
938EXPORT_SYMBOL(hwgraph_info_remove_LBL);
939EXPORT_SYMBOL(hwgraph_info_replace_LBL);
940EXPORT_SYMBOL(hwgraph_info_get_LBL);
941EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
942EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
943EXPORT_SYMBOL(hwgraph_info_export_LBL);
944EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
945EXPORT_SYMBOL(hwgraph_path_lookup);
946EXPORT_SYMBOL(hwgraph_traverse);
947EXPORT_SYMBOL(hwgraph_vertex_name_get);
948