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