devarch.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. #include "io.h"
  8. enum {
  9. Qdir = 0,
  10. Qbase,
  11. Qmax = 16,
  12. };
  13. typedef long Rdwrfn(Chan*, void*, long, vlong);
  14. static Rdwrfn *readfn[Qmax];
  15. static Rdwrfn *writefn[Qmax];
  16. static Dirtab archdir[Qmax] = {
  17. ".", { Qdir, 0, QTDIR }, 0, 0555,
  18. };
  19. Lock archwlock; /* the lock is only for changing archdir */
  20. int narchdir = Qbase;
  21. /*
  22. * Add a file to the #P listing. Once added, you can't delete it.
  23. * You can't add a file with the same name as one already there,
  24. * and you get a pointer to the Dirtab entry so you can do things
  25. * like change the Qid version. Changing the Qid path is disallowed.
  26. */
  27. Dirtab*
  28. addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
  29. {
  30. int i;
  31. Dirtab d;
  32. Dirtab *dp;
  33. memset(&d, 0, sizeof d);
  34. strcpy(d.name, name);
  35. d.perm = perm;
  36. lock(&archwlock);
  37. if(narchdir >= Qmax){
  38. unlock(&archwlock);
  39. return nil;
  40. }
  41. for(i=0; i<narchdir; i++)
  42. if(strcmp(archdir[i].name, name) == 0){
  43. unlock(&archwlock);
  44. return nil;
  45. }
  46. d.qid.path = narchdir;
  47. archdir[narchdir] = d;
  48. readfn[narchdir] = rdfn;
  49. writefn[narchdir] = wrfn;
  50. dp = &archdir[narchdir++];
  51. unlock(&archwlock);
  52. return dp;
  53. }
  54. static Chan*
  55. archattach(char* spec)
  56. {
  57. return devattach('P', spec);
  58. }
  59. Walkqid*
  60. archwalk(Chan* c, Chan *nc, char** name, int nname)
  61. {
  62. return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
  63. }
  64. static int
  65. archstat(Chan* c, uchar* dp, int n)
  66. {
  67. return devstat(c, dp, n, archdir, narchdir, devgen);
  68. }
  69. static Chan*
  70. archopen(Chan* c, int omode)
  71. {
  72. return devopen(c, omode, archdir, narchdir, devgen);
  73. }
  74. static void
  75. archclose(Chan*)
  76. {
  77. }
  78. static long
  79. archread(Chan *c, void *a, long n, vlong offset)
  80. {
  81. Rdwrfn *fn;
  82. switch((ulong)c->qid.path){
  83. case Qdir:
  84. return devdirread(c, a, n, archdir, narchdir, devgen);
  85. default:
  86. if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
  87. return fn(c, a, n, offset);
  88. error(Eperm);
  89. break;
  90. }
  91. return 0;
  92. }
  93. static long
  94. archwrite(Chan *c, void *a, long n, vlong offset)
  95. {
  96. Rdwrfn *fn;
  97. if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
  98. return fn(c, a, n, offset);
  99. error(Eperm);
  100. return 0;
  101. }
  102. void archinit(void);
  103. Dev archdevtab = {
  104. 'P',
  105. "arch",
  106. devreset,
  107. archinit,
  108. devshutdown,
  109. archattach,
  110. archwalk,
  111. archstat,
  112. archopen,
  113. devcreate,
  114. archclose,
  115. archread,
  116. devbread,
  117. archwrite,
  118. devbwrite,
  119. devremove,
  120. devwstat,
  121. };
  122. static long
  123. cputyperead(Chan*, void *a, long n, vlong offset)
  124. {
  125. char str[128];
  126. snprint(str, sizeof str, "ARM11 %d\n", m->cpumhz);
  127. return readstr(offset, a, n, str);
  128. }
  129. void
  130. archinit(void)
  131. {
  132. addarchfile("cputype", 0444, cputyperead, nil);
  133. }