Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
/*
2
 * read-only sd driver for BIOS devices with partitions.
3
 * will probably only work with bootstrap kernels, as the normal kernel
4
 * deals directly with the clock and disk controllers, which seems
5
 * to confuse many BIOSes.
6
 *
7
 * devbios must be initialised first and no disks may be accessed
8
 * via non-BIOS means.
9
 */
10
 
11
#include	"u.h"
12
#include	"../port/lib.h"
13
#include	"mem.h"
14
#include	"dat.h"
15
#include	"fns.h"
16
#include	"io.h"
17
#include	"ureg.h"
18
#include	"pool.h"
19
#include	"../port/error.h"
20
#include	"../port/netif.h"
21
#include	"../port/sd.h"
22
#include	"dosfs.h"
23
#include	<disk.h>
24
 
25
long	biosread0(Bootfs *, void *, long);
26
vlong	biosseek(Bootfs *fs, vlong off);
27
 
28
extern SDifc sdbiosifc;
29
extern int biosndevs;
30
 
31
uchar *
32
putbeul(ulong ul, uchar *p)
33
{
34
	*p++ = ul >> 24;
35
	*p++ = ul >> 16;
36
	*p++ = ul >> 8;
37
	*p++ = ul;
38
	return p;
39
}
40
 
41
uchar *
42
putbeuvl(uvlong uvl, uchar *p)
43
{
44
	*p++ = uvl >> 56;
45
	*p++ = uvl >> 48;
46
	*p++ = uvl >> 40;
47
	*p++ = uvl >> 32;
48
	*p++ = uvl >> 24;
49
	*p++ = uvl >> 16;
50
	*p++ = uvl >> 8;
51
	*p++ = uvl;
52
	return p;
53
}
54
 
55
int
56
biosverify(SDunit* )
57
{
58
	if (!biosinited)
59
		return 0;
60
	return 1;
61
}
62
 
63
int
64
biosonline(SDunit* unit)
65
{
66
	uint subno = unit->subno;
67
 
68
	if (!biosinited)
69
		panic("sdbios: biosonline: sdbios not inited");
70
	if (unit == nil)
71
		return 0;
72
	unit->secsize = biossectsz(subno);
73
	if (unit->secsize <= 0) {
74
		print("sdbios: biosonline: implausible sector size on medium\n");
75
		return 0;
76
	}
77
	unit->sectors = biossize(subno);
78
	if (unit->sectors <= 0) {
79
		unit->sectors = 0;
80
		print("sdbios: biosonline: no sectors on medium\n");
81
		return 0;
82
	}
83
	return 1;
84
}
85
 
86
static int
87
biosrio(SDreq* r)
88
{
89
	int nb;
90
	long got;
91
	vlong off;
92
	uchar *p;
93
	Bootfs fs;			/* just for fs->dev, which is zero */
94
	SDunit *unit;
95
 
96
	if (!biosinited)
97
		return SDeio;
98
	unit = r->unit;
99
	/*
100
	 * Most SCSI commands can be passed unchanged except for
101
	 * the padding on the end. The few which require munging
102
	 * are not used internally. Mode select/sense(6) could be
103
	 * converted to the 10-byte form but it's not worth the
104
	 * effort. Read/write(6) are easy.
105
	 */
106
	r->rlen = 0;
107
	r->status = SDok;
108
	switch(r->cmd[0]){
109
	case ScmdRead:
110
	case ScmdExtread:
111
		if (r->cmd[0] == ScmdRead)
112
			panic("biosrio: ScmdRead read op");
113
		off = r->cmd[2]<<24 | r->cmd[3]<<16 | r->cmd[4]<<8 | r->cmd[5];
114
		nb =  r->cmd[7]<<8  | r->cmd[8];	/* often 4 */
115
		USED(nb);		/* is nb*unit->secsize == r->dlen? */
116
		memset(&fs, 0, sizeof fs);
117
		biosseek(&fs, off * unit->secsize);
118
		got = biosread0(&fs, r->data, r->dlen);
119
		if (got < 0)
120
			r->status = SDeio;
121
		else
122
			r->rlen = got;
123
		break;
124
	case ScmdWrite:
125
	case ScmdExtwrite:
126
		r->status = SDeio;	/* boot programs don't write */
127
		break;
128
 
129
		/*
130
		 * Read capacity returns the LBA of the last sector.
131
		 */
132
	case ScmdRcapacity:
133
		p = putbeul(r->unit->sectors - 1, r->data);
134
		r->data = putbeul(r->unit->secsize, p);
135
		return SDok;
136
	case ScmdRcapacity16:
137
		p = putbeuvl(r->unit->sectors - 1, r->data);
138
		r->data = putbeul(r->unit->secsize, p);
139
		return SDok;
140
	/* ignore others */
141
	}
142
	return r->status;
143
}
144
 
145
/* this is called between biosreset and biosinit */
146
static SDev*
147
biospnp(void)
148
{
149
	SDev *sdev;
150
 
151
	if (!biosinited)
152
		panic("sdbios: biospnp: bios devbios not yet inited");
153
	if((sdev = malloc(sizeof(SDev))) != nil) {
154
		sdev->ifc = &sdbiosifc;
155
		sdev->idno = 'B';
156
		sdev->nunit = biosndevs;
157
		iprint("sdbios: biospnp: %d unit(s) at sd%C0\n",
158
			sdev->nunit, sdev->idno);
159
	}
160
	return sdev;
161
}
162
 
163
SDifc sdbiosifc = {
164
	"bios",				/* name */
165
 
166
	biospnp,			/* pnp */
167
	nil,				/* legacy */
168
	nil,				/* enable */
169
	nil,				/* disable */
170
 
171
	biosverify,			/* verify */
172
	biosonline,			/* online */
173
	biosrio,			/* rio */
174
	nil,				/* rctl */
175
	nil,				/* wctl */
176
 
177
	scsibio,			/* bio */
178
	nil,				/* probe */
179
	nil,				/* clear */
180
	nil,				/* rtopctl */
181
	nil,				/* wtopctl */
182
};