Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}