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 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 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 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 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