changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/aux/wacom.c

changeset 4350: 1f9d7811d546
parent: 9409bb0e03b2
author: cinap_lenrek@felloff.net
date: Mon, 16 Mar 2015 05:46:08 +0100
permissions: -rw-r--r--
description: kernel: get rid of auxpage() and preserve cache index bits in Page.va in mount cache

the mount cache uses Page.va to store cached range offset and
limit, but mips kernel uses cache index bits from Page.va to
maintain page coloring. Page.va was not initialized by auxpage().

this change removes auxpage() which was primarily used only
by the mount cache and use newpage() with cache file offset
page as va so we will get a page of the right color.

mount cache keeps the index bits intact by only using the top
and buttom PGSHIFT bits of Page.va for the range offset/limit.
1 #include <u.h>
2 #include <libc.h>
3 #include <fcall.h>
4 #include <thread.h>
5 #include <9p.h>
6 
7 typedef struct Tablet Tablet;
8 typedef struct Message Message;
9 typedef struct QItem QItem;
10 typedef struct Queue Queue;
11 typedef struct Reader Reader;
12 
13 
14 enum { MAX = 1000 };
15 
16 struct Tablet {
17  int ser;
18  int xmax, ymax, pmax, version;
19  int sx, sy;
20 };
21 
22 struct Message {
23  Ref;
24  int b, x, y, p;
25  char *msg;
26 };
27 
28 Tablet*
29 newtablet(char* dev)
30 {
31  int serctl;
32  char* ctl;
33  Tablet* t;
34 
35  ctl = smprint("%sctl", dev);
36  t = calloc(sizeof(Tablet), 1);
37  t->ser = open(dev, ORDWR);
38  if(t->ser < 0) {
39  free(t);
40  return 0;
41  }
42  serctl = open(ctl, OWRITE);
43  free(ctl);
44  if(serctl < 0) {
45  free(t);
46  close(t->ser);
47  return 0;
48  }
49  if(fprint(serctl, "b19200\n") < 0) {
50  free(t);
51  close(t->ser);
52  close(serctl);
53  return 0;
54  }
55  close(serctl);
56  return t;
57 }
58 
59 int
60 query(Tablet* t)
61 {
62  uchar buf[11];
63 
64  if(write(t->ser, "&0*", 3) < 3) return -1;
65  do {
66  if(read(t->ser, buf, 1) < 1) return -1;
67  } while(buf[0] != 0xC0);
68  if(readn(t->ser, buf+1, 10) < 10) return -1;
69  t->xmax = (buf[1] << 9) | (buf[2] << 2) | ((buf[6] >> 5) & 3);
70  t->ymax = (buf[3] << 9) | (buf[4] << 2) | ((buf[6] >> 3) & 3);
71  t->pmax = buf[5] | (buf[6] & 7);
72  t->version = (buf[9] << 7) | buf[10];
73  if(write(t->ser, "1", 1) < 1) return -1;
74  return 0;
75 }
76 
77 int
78 screensize(Tablet* t)
79 {
80  int fd;
81  char buf[189], buf2[12], *p;
82 
83  fd = open("/dev/draw/new", OREAD);
84  if(fd < 0) return -1;
85  read(fd, buf, 189);
86  memcpy(buf2, buf + 72, 11);
87  buf2[11] = 0;
88  for(p = buf2; *p == ' '; p++);
89  t->sx = atoi(p);
90  memcpy(buf2, buf + 84, 11);
91  for(p = buf2; *p == ' '; p++);
92  t->sy = atoi(p);
93  if(t->sx == 0 || t->sy == 0) {
94  close(fd);
95  werrstr("invalid resolution read from /dev/draw/new");
96  return -1;
97  }
98 
99  close(fd);
100  return 0;
101 }
102 
103 int
104 findheader(Tablet* t)
105 {
106  uchar c;
107 
108  do {
109  if(read(t->ser, &c, 1) < 1) return -1;
110  } while((c & 0x80) == 0);
111  return c;
112 }
113 
114 Message*
115 readpacket(Tablet* t)
116 {
117  uchar buf[9];
118  int head;
119  Message *m;
120 
121  head = findheader(t);
122  if(head < 0) return 0;
123  if(readn(t->ser, buf, 9) < 9) return 0;
124 
125  m = calloc(sizeof(Message), 1);
126  incref(m);
127 
128  m->b = head & 7;
129  m->x = (buf[0] << 9) | (buf[1] << 2) | ((buf[5] >> 5) & 3);
130  m->y = (buf[2] << 9) | (buf[3] << 2) | ((buf[5] >> 3) & 3);
131  m->p = ((buf[5] & 7) << 7) | buf[4];
132 
133  m->p *= MAX;
134  m->p /= t->pmax;
135  m->x *= t->sx;
136  m->x /= t->xmax;
137  m->y *= t->sy;
138  m->y /= t->ymax;
139 
140  m->msg = smprint("m %d %d %d %d\n", m->x, m->y, m->b, m->p);
141  return m;
142 }
143 
144 void
145 msgdecref(Message *m)
146 {
147  if(decref(m) == 0) {
148  free(m->msg);
149  free(m);
150  }
151 }
152 
153 struct QItem {
154  Message *m;
155  QItem *next;
156 };
157 
158 struct Queue {
159  Lock;
160  QItem *first, *last;
161 };
162 
163 void
164 qput(Queue* q, Message* m)
165 {
166  QItem *i;
167 
168  lock(q);
169  i = malloc(sizeof(QItem));
170  i->m = m;
171  i->next = 0;
172  if(q->last == nil) {
173  q->last = q->first = i;
174  } else {
175  q->last->next = i;
176  q->last = i;
177  }
178  unlock(q);
179 }
180 
181 Message*
182 qget(Queue* q)
183 {
184  QItem *i;
185  Message *m;
186 
187  if(q->first == nil) return nil;
188  lock(q);
189  i = q->first;
190  if(q->first == q->last) {
191  q->first = q->last = nil;
192  } else {
193  q->first = i->next;
194  }
195  m = i->m;
196  free(i);
197  unlock(q);
198  return m;
199 }
200 
201 void
202 freequeue(Queue *q)
203 {
204  Message *m;
205 
206  while(m = qget(q))
207  msgdecref(m);
208  free(q);
209 }
210 
211 struct Reader {
212  Queue *e;
213  Reader *prev, *next;
214  Req* req;
215 };
216 
217 Lock readers;
218 Reader *rfirst, *rlast;
219 
220 void
221 reply(Req *req, Message *m)
222 {
223  req->ofcall.count = strlen(m->msg);
224  if(req->ofcall.count > req->ifcall.count)
225  req->ofcall.count = req->ifcall.count;
226  memmove(req->ofcall.data, m->msg, req->ofcall.count);
227  respond(req, nil);
228 }
229 
230 void
231 sendout(Message *m)
232 {
233  Reader *r;
234 
235  lock(&readers);
236  for(r = rfirst; r; r = r->next) {
237  if(r->req) {
238  reply(r->req, m);
239  r->req = nil;
240  } else {
241  incref(m);
242  qput(r->e, m);
243  }
244  }
245  unlock(&readers);
246 }
247 
248 void
249 tabletopen(Req *req)
250 {
251  Reader *r;
252 
253  lock(&readers);
254  r = calloc(sizeof(Reader), 1);
255  r->e = calloc(sizeof(Queue), 1);
256  if(rlast) rlast->next = r;
257  r->prev = rlast;
258  rlast = r;
259  if(rfirst == nil) rfirst = r;
260  unlock(&readers);
261  req->fid->aux = r;
262  respond(req, nil);
263 }
264 
265 void
266 tabletdestroyfid(Fid *fid)
267 {
268  Reader *r;
269 
270  r = fid->aux;
271  if(r == nil) return;
272  lock(&readers);
273  if(r->prev) r->prev->next = r->next;
274  if(r->next) r->next->prev = r->prev;
275  if(r == rfirst) rfirst = r->next;
276  if(r == rlast) rlast = r->prev;
277  freequeue(r->e);
278  free(r);
279  unlock(&readers);
280 }
281 
282 void
283 tabletdestroyreq(Req *req)
284 {
285  Reader *r;
286 
287  if(req->fid == nil) return;
288  r = req->fid->aux;
289  if(r == nil) return;
290  if(req == r->req) {
291  r->req = nil;
292  }
293 }
294 
295 void
296 tabletread(Req* req)
297 {
298  Reader *r;
299  Message *m;
300 
301  r = req->fid->aux;
302  if(m = qget(r->e)) {
303  reply(req, m);
304  msgdecref(m);
305  } else {
306  if(r->req) {
307  respond(req, "no concurrent reads, please");
308  } else {
309  r->req = req;
310  }
311  }
312 }
313 
314 Srv tabletsrv = {
315  .open = tabletopen,
316  .read = tabletread,
317  .destroyfid = tabletdestroyfid,
318  .destroyreq = tabletdestroyreq,
319 };
320 
321 File *tfile;
322 
323 void
324 main()
325 {
326  Tablet *t;
327  Message *m;
328  int fd[2];
329 
330  pipe(fd);
331  tabletsrv.infd = tabletsrv.outfd = fd[0];
332  tabletsrv.srvfd = fd[1];
333  tabletsrv.tree = alloctree(getuser(), getuser(), 0555, 0);
334  tfile = createfile(tabletsrv.tree->root, "tablet", getuser(), 0400, 0);
335  if(rfork(RFPROC | RFMEM | RFNOWAIT | RFNOTEG) > 0) exits(nil);
336  if(rfork(RFPROC | RFMEM) == 0) {
337  srv(&tabletsrv);
338  exits(nil);
339  }
340  mount(fd[1], -1, "/dev", MAFTER, "");
341 
342  t = newtablet("/dev/eia2");
343  if(!t) sysfatal("%r");
344  if(screensize(t) < 0) sysfatal("%r");
345  if(query(t) < 0) sysfatal("%r");
346  while(1) {
347  m = readpacket(t);
348  if(!m) sysfatal("%r");
349  sendout(m);
350  msgdecref(m);
351  }
352 }