xref: /plan9/sys/src/cmd/aux/flashfs/devfs.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <auth.h>
49a747e4fSDavid du Colombier #include <fcall.h>
59a747e4fSDavid du Colombier #include <thread.h>
69a747e4fSDavid du Colombier #include <9p.h>
79a747e4fSDavid du Colombier #include "flashfs.h"
89a747e4fSDavid du Colombier 
99a747e4fSDavid du Colombier static	char*	file;
109a747e4fSDavid du Colombier static	int	fd;
119a747e4fSDavid du Colombier static	uchar	*ones;
129a747e4fSDavid du Colombier 
139a747e4fSDavid du Colombier static	int	isdev;
149a747e4fSDavid du Colombier 
159a747e4fSDavid du Colombier struct {
169a747e4fSDavid du Colombier 	int	dfd;	/* data */
179a747e4fSDavid du Colombier 	int	cfd;	/* control */
189a747e4fSDavid du Colombier } flash;
199a747e4fSDavid du Colombier 
209a747e4fSDavid du Colombier void
initdata(char * f,int)219a747e4fSDavid du Colombier initdata(char *f, int)
229a747e4fSDavid du Colombier {
239a747e4fSDavid du Colombier 	char err[ERRMAX];
249a747e4fSDavid du Colombier 	char buf[1024], *fld[8];
259a747e4fSDavid du Colombier 	int n;
269a747e4fSDavid du Colombier 	Dir *d;
279a747e4fSDavid du Colombier 
289a747e4fSDavid du Colombier 	isdev = 1;
299a747e4fSDavid du Colombier 	flash.dfd = open(f, ORDWR);
309a747e4fSDavid du Colombier 	if(flash.dfd < 0){
319a747e4fSDavid du Colombier 		errstr(err, sizeof err);
329a747e4fSDavid du Colombier 		if((flash.dfd = create(f, ORDWR, 0666)) >= 0){
339a747e4fSDavid du Colombier 			fprint(2, "warning: created plain file %s\n", buf);
349a747e4fSDavid du Colombier 			goto Plain;
359a747e4fSDavid du Colombier 		}
369a747e4fSDavid du Colombier 		errstr(err, sizeof err);	/* restore open error */
379a747e4fSDavid du Colombier 		sysfatal("opening %s: %r", f);
389a747e4fSDavid du Colombier 	}
399a747e4fSDavid du Colombier 	if(snprint(buf, sizeof buf, "%sctl", f) != strlen(f)+3)
409a747e4fSDavid du Colombier 		sysfatal("path too long: %s", f);
419a747e4fSDavid du Colombier 	flash.cfd = open(buf, ORDWR);
429a747e4fSDavid du Colombier 	if(flash.cfd < 0){
439a747e4fSDavid du Colombier 		fprint(2, "warning: cannot open %s (%r); assuming plain file\n", buf);
449a747e4fSDavid du Colombier 	Plain:
459a747e4fSDavid du Colombier 		isdev = 0;
469a747e4fSDavid du Colombier 		if(sectsize == 0)
479a747e4fSDavid du Colombier 			sectsize = 512;
489a747e4fSDavid du Colombier 		if(nsects == 0){
499a747e4fSDavid du Colombier 			if((d = dirstat(f)) == nil)
509a747e4fSDavid du Colombier 				sysfatal("stat %s: %r", f);
519a747e4fSDavid du Colombier 			nsects = d->length / sectsize;
529a747e4fSDavid du Colombier 			free(d);
539a747e4fSDavid du Colombier 		}
549a747e4fSDavid du Colombier 		ones = emalloc9p(sectsize);
559a747e4fSDavid du Colombier 		memset(ones, ~0, sectsize);
569a747e4fSDavid du Colombier 	}else{
579a747e4fSDavid du Colombier 		n = read(flash.cfd, buf, sizeof(buf)-1);
589a747e4fSDavid du Colombier 		if(n <= 0)
599a747e4fSDavid du Colombier 			sysfatal("reading %sctl: %r", f);
609a747e4fSDavid du Colombier 		buf[n] = 0;
619a747e4fSDavid du Colombier 		n = tokenize(buf, fld, nelem(fld));
629a747e4fSDavid du Colombier 		if(n < 7)
639a747e4fSDavid du Colombier 			sysfatal("bad flash geometry");
649a747e4fSDavid du Colombier 		nsects = atoi(fld[5]);
659a747e4fSDavid du Colombier 		sectsize = atoi(fld[6]);
669a747e4fSDavid du Colombier 		if(nsects < 8)
679a747e4fSDavid du Colombier 			sysfatal("unreasonable value for nsects: %lud", nsects);
689a747e4fSDavid du Colombier 		if(sectsize < 512)
699a747e4fSDavid du Colombier 			sysfatal("unreasonable value for sectsize: %lud", sectsize);
709a747e4fSDavid du Colombier 	}
719a747e4fSDavid du Colombier }
729a747e4fSDavid du Colombier 
739a747e4fSDavid du Colombier void
clearsect(int sect)749a747e4fSDavid du Colombier clearsect(int sect)
759a747e4fSDavid du Colombier {
769a747e4fSDavid du Colombier 	if(isdev==0){
779a747e4fSDavid du Colombier 		if(pwrite(flash.dfd, ones, sectsize, sect*sectsize) != sectsize)
789a747e4fSDavid du Colombier 			sysfatal("couldn't erase sector %d: %r", sect);
799a747e4fSDavid du Colombier 	}else{
809a747e4fSDavid du Colombier 		if(fprint(flash.cfd, "erase %lud", sect * sectsize) < 0)
819a747e4fSDavid du Colombier 			sysfatal("couldn't erase sector %d: %r", sect);
829a747e4fSDavid du Colombier 	}
839a747e4fSDavid du Colombier }
849a747e4fSDavid du Colombier 
859a747e4fSDavid du Colombier void
readdata(int sect,void * buff,ulong count,ulong off)869a747e4fSDavid du Colombier readdata(int sect, void *buff, ulong count, ulong off)
879a747e4fSDavid du Colombier {
889a747e4fSDavid du Colombier 	long n;
899a747e4fSDavid du Colombier 	ulong m;
909a747e4fSDavid du Colombier 
919a747e4fSDavid du Colombier 	m = sect * sectsize + off;
929a747e4fSDavid du Colombier 	n = pread(flash.dfd, buff, count, m);
939a747e4fSDavid du Colombier 	if(n < 0)
949a747e4fSDavid du Colombier 		sysfatal("error reading at %lux: %r", m);
959a747e4fSDavid du Colombier 	if(n != count)
96*14cc0f53SDavid du Colombier 		sysfatal("short read at %lux, %ld instead of %lud", m, n, count);
979a747e4fSDavid du Colombier }
989a747e4fSDavid du Colombier 
999a747e4fSDavid du Colombier int
writedata(int err,int sect,void * buff,ulong count,ulong off)1009a747e4fSDavid du Colombier writedata(int err, int sect, void *buff, ulong count, ulong off)
1019a747e4fSDavid du Colombier {
1029a747e4fSDavid du Colombier 	long n;
1039a747e4fSDavid du Colombier 	ulong m;
1049a747e4fSDavid du Colombier 
1059a747e4fSDavid du Colombier 	m = sect*sectsize + off;
1069a747e4fSDavid du Colombier 	n = pwrite(flash.dfd, buff, count, m);
1079a747e4fSDavid du Colombier 	if(n < 0){
1089a747e4fSDavid du Colombier 		if(err)
1099a747e4fSDavid du Colombier 			return 0;
1109a747e4fSDavid du Colombier 		sysfatal("error writing at %lux: %r", m);
1119a747e4fSDavid du Colombier 	}
1129a747e4fSDavid du Colombier 	if(n != count){
1139a747e4fSDavid du Colombier 		if(err)
1149a747e4fSDavid du Colombier 			return 0;
1159a747e4fSDavid du Colombier 		sysfatal("short write at %lud, %ld instead of %lud", m, n, count);
1169a747e4fSDavid du Colombier 	}
1179a747e4fSDavid du Colombier 	return 1;
1189a747e4fSDavid du Colombier }
119