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