1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <thread.h>
6 #include <9p.h>
7 #include "flashfs.h"
8
9 static char* file;
10 static int fd;
11 static uchar *ones;
12
13 static int isdev;
14
15 struct {
16 int dfd; /* data */
17 int cfd; /* control */
18 } flash;
19
20 void
initdata(char * f,int)21 initdata(char *f, int)
22 {
23 char err[ERRMAX];
24 char buf[1024], *fld[8];
25 int n;
26 Dir *d;
27
28 isdev = 1;
29 flash.dfd = open(f, ORDWR);
30 if(flash.dfd < 0){
31 errstr(err, sizeof err);
32 if((flash.dfd = create(f, ORDWR, 0666)) >= 0){
33 fprint(2, "warning: created plain file %s\n", buf);
34 goto Plain;
35 }
36 errstr(err, sizeof err); /* restore open error */
37 sysfatal("opening %s: %r", f);
38 }
39 if(snprint(buf, sizeof buf, "%sctl", f) != strlen(f)+3)
40 sysfatal("path too long: %s", f);
41 flash.cfd = open(buf, ORDWR);
42 if(flash.cfd < 0){
43 fprint(2, "warning: cannot open %s (%r); assuming plain file\n", buf);
44 Plain:
45 isdev = 0;
46 if(sectsize == 0)
47 sectsize = 512;
48 if(nsects == 0){
49 if((d = dirstat(f)) == nil)
50 sysfatal("stat %s: %r", f);
51 nsects = d->length / sectsize;
52 free(d);
53 }
54 ones = emalloc9p(sectsize);
55 memset(ones, ~0, sectsize);
56 }else{
57 n = read(flash.cfd, buf, sizeof(buf)-1);
58 if(n <= 0)
59 sysfatal("reading %sctl: %r", f);
60 buf[n] = 0;
61 n = tokenize(buf, fld, nelem(fld));
62 if(n < 7)
63 sysfatal("bad flash geometry");
64 nsects = atoi(fld[5]);
65 sectsize = atoi(fld[6]);
66 if(nsects < 8)
67 sysfatal("unreasonable value for nsects: %lud", nsects);
68 if(sectsize < 512)
69 sysfatal("unreasonable value for sectsize: %lud", sectsize);
70 }
71 }
72
73 void
clearsect(int sect)74 clearsect(int sect)
75 {
76 if(isdev==0){
77 if(pwrite(flash.dfd, ones, sectsize, sect*sectsize) != sectsize)
78 sysfatal("couldn't erase sector %d: %r", sect);
79 }else{
80 if(fprint(flash.cfd, "erase %lud", sect * sectsize) < 0)
81 sysfatal("couldn't erase sector %d: %r", sect);
82 }
83 }
84
85 void
readdata(int sect,void * buff,ulong count,ulong off)86 readdata(int sect, void *buff, ulong count, ulong off)
87 {
88 long n;
89 ulong m;
90
91 m = sect * sectsize + off;
92 n = pread(flash.dfd, buff, count, m);
93 if(n < 0)
94 sysfatal("error reading at %lux: %r", m);
95 if(n != count)
96 sysfatal("short read at %lux, %ld instead of %lud", m, n, count);
97 }
98
99 int
writedata(int err,int sect,void * buff,ulong count,ulong off)100 writedata(int err, int sect, void *buff, ulong count, ulong off)
101 {
102 long n;
103 ulong m;
104
105 m = sect*sectsize + off;
106 n = pwrite(flash.dfd, buff, count, m);
107 if(n < 0){
108 if(err)
109 return 0;
110 sysfatal("error writing at %lux: %r", m);
111 }
112 if(n != count){
113 if(err)
114 return 0;
115 sysfatal("short write at %lud, %ld instead of %lud", m, n, count);
116 }
117 return 1;
118 }
119