xref: /plan9/sys/src/cmd/aux/flashfs/devfs.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
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