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