1 #include "all.h"
2
3 #define FDEV(d) ((d)->fw.fw)
4
5 enum { DEBUG = 0 };
6
7 Devsize
fwormsize(Device * d)8 fwormsize(Device *d)
9 {
10 Devsize l;
11
12 l = devsize(FDEV(d));
13 l -= l/(BUFSIZE*8) + 1;
14 return l;
15 }
16
17 void
fwormream(Device * d)18 fwormream(Device *d)
19 {
20 Iobuf *p;
21 Device *fdev;
22 Off a, b;
23
24 print("fworm ream\n");
25 devinit(d);
26 fdev = FDEV(d);
27 a = fwormsize(d);
28 b = devsize(fdev);
29 print("\tfwsize = %lld\n", (Wideoff)a);
30 print("\tbwsize = %lld\n", (Wideoff)b-a);
31 for(; a < b; a++) {
32 p = getbuf(fdev, a, Bmod|Bres);
33 if(!p)
34 panic("fworm: init");
35 memset(p->iobuf, 0, RBUFSIZE);
36 settag(p, Tvirgo, a);
37 putbuf(p);
38 }
39 }
40
41 void
fworminit(Device * d)42 fworminit(Device *d)
43 {
44 print("fworm init\n");
45 devinit(FDEV(d));
46 }
47
48 int
fwormread(Device * d,Off b,void * c)49 fwormread(Device *d, Off b, void *c)
50 {
51 Iobuf *p;
52 Device *fdev;
53 Devsize l;
54
55 if(DEBUG)
56 print("fworm read %lld\n", (Wideoff)b);
57 fdev = FDEV(d);
58 l = devsize(fdev);
59 l -= l/(BUFSIZE*8) + 1;
60 if(b >= l)
61 panic("fworm: rbounds %lld", (Wideoff)b);
62 l += b/(BUFSIZE*8);
63
64 p = getbuf(fdev, l, Brd|Bres);
65 if(!p || checktag(p, Tvirgo, l))
66 panic("fworm: checktag %lld", (Wideoff)l);
67 l = b % (BUFSIZE*8);
68 if(!(p->iobuf[l/8] & (1<<(l%8)))) {
69 putbuf(p);
70 print("fworm: read %lld\n", (Wideoff)b);
71 return 1;
72 }
73 putbuf(p);
74 return devread(fdev, b, c);
75 }
76
77 int
fwormwrite(Device * d,Off b,void * c)78 fwormwrite(Device *d, Off b, void *c)
79 {
80 Iobuf *p;
81 Device *fdev;
82 Devsize l;
83
84 if(DEBUG)
85 print("fworm write %lld\n", (Wideoff)b);
86 fdev = FDEV(d);
87 l = devsize(fdev);
88 l -= l/(BUFSIZE*8) + 1;
89 if(b >= l)
90 panic("fworm: wbounds %lld", (Wideoff)b);
91 l += b/(BUFSIZE*8);
92
93 p = getbuf(fdev, l, Brd|Bmod|Bres);
94 if(!p || checktag(p, Tvirgo, l))
95 panic("fworm: checktag %lld", (Wideoff)l);
96 l = b % (BUFSIZE*8);
97 if((p->iobuf[l/8] & (1<<(l%8)))) {
98 putbuf(p);
99 print("fworm: write %lld\n", (Wideoff)b);
100 return 1;
101 }
102 p->iobuf[l/8] |= 1<<(l%8);
103 putbuf(p);
104 return devwrite(fdev, b, c);
105 }
106