|
|
@@ -1,289 +0,0 @@
|
|
1
|
|
-#include <etherboot.h>
|
|
2
|
|
-#include <disk.h>
|
|
3
|
|
-
|
|
4
|
|
-#warning "disk.c is currently broken"
|
|
5
|
|
-#if 0
|
|
6
|
|
-
|
|
7
|
|
-#undef disk_disable
|
|
8
|
|
-
|
|
9
|
|
-static int dummy(void *unused __unused)
|
|
10
|
|
-{
|
|
11
|
|
- return (0);
|
|
12
|
|
-}
|
|
13
|
|
-
|
|
14
|
|
-static unsigned char disk_buffer[DISK_BUFFER_SIZE];
|
|
15
|
|
-struct disk disk =
|
|
16
|
|
-{
|
|
17
|
|
- {
|
|
18
|
|
- 0, /* dev.disable */
|
|
19
|
|
- {
|
|
20
|
|
- 0,
|
|
21
|
|
- 0,
|
|
22
|
|
- PCI_BUS_TYPE,
|
|
23
|
|
- }, /* dev.devid */
|
|
24
|
|
- 0, /* index */
|
|
25
|
|
- 0, /* type */
|
|
26
|
|
- PROBE_FIRST, /* how_probe */
|
|
27
|
|
- PROBE_NONE, /* to_probe */
|
|
28
|
|
- 0, /* failsafe */
|
|
29
|
|
- 0, /* type_index */
|
|
30
|
|
- {}, /* state */
|
|
31
|
|
- },
|
|
32
|
|
- (int (*)(struct disk *, sector_t ))dummy, /* read */
|
|
33
|
|
- 0 - 1, /* drive */
|
|
34
|
|
- 0, /* hw_sector_size */
|
|
35
|
|
- 0, /* sectors_per_read */
|
|
36
|
|
- 0, /* bytes */
|
|
37
|
|
- 0, /* sectors */
|
|
38
|
|
- 0, /* sector */
|
|
39
|
|
- disk_buffer, /* buffer */
|
|
40
|
|
- 0, /* priv */
|
|
41
|
|
-
|
|
42
|
|
- 0, /* disk_offset */
|
|
43
|
|
- 0, /* direction */
|
|
44
|
|
-};
|
|
45
|
|
-
|
|
46
|
|
-
|
|
47
|
|
-static int disk_read(
|
|
48
|
|
- struct disk *disk, unsigned char *buffer, sector_t sector)
|
|
49
|
|
-{
|
|
50
|
|
- int result;
|
|
51
|
|
- sector_t base_sector;
|
|
52
|
|
-
|
|
53
|
|
- /* Note: I do not handle disk wrap around here! */
|
|
54
|
|
-
|
|
55
|
|
- /* Compute the start of the track cache */
|
|
56
|
|
- base_sector = sector;
|
|
57
|
|
- /* Support sectors_per_read > 1 only on small disks */
|
|
58
|
|
- if ((sizeof(sector_t) > sizeof(unsigned long)) &&
|
|
59
|
|
- (disk->sectors_per_read > 1)) {
|
|
60
|
|
- unsigned long offset;
|
|
61
|
|
- offset = ((unsigned long)sector) % disk->sectors_per_read;
|
|
62
|
|
- base_sector -= offset;
|
|
63
|
|
- }
|
|
64
|
|
-
|
|
65
|
|
- /* See if I need to update the track cache */
|
|
66
|
|
- if ((sector < disk->sector) ||
|
|
67
|
|
- sector >= disk->sector + (disk->bytes >> 9)) {
|
|
68
|
|
- twiddle();
|
|
69
|
|
- result = disk->read(disk, base_sector);
|
|
70
|
|
- if (result < 0)
|
|
71
|
|
- return result;
|
|
72
|
|
- }
|
|
73
|
|
- /* Service the request from the track cache */
|
|
74
|
|
- memcpy(buffer, disk->buffer + ((sector - base_sector)<<9), SECTOR_SIZE);
|
|
75
|
|
- return 0;
|
|
76
|
|
-}
|
|
77
|
|
-
|
|
78
|
|
-static int disk_read_sectors(
|
|
79
|
|
- struct disk *disk,
|
|
80
|
|
- unsigned char *buffer,
|
|
81
|
|
- sector_t base_sector, unsigned int sectors)
|
|
82
|
|
-{
|
|
83
|
|
- sector_t sector = 0;
|
|
84
|
|
- unsigned long offset;
|
|
85
|
|
- int result = 0;
|
|
86
|
|
-
|
|
87
|
|
- for(offset = 0; offset < sectors; offset++) {
|
|
88
|
|
- sector = base_sector + offset;
|
|
89
|
|
- if (sector >= disk->sectors) {
|
|
90
|
|
- sector -= disk->sectors;
|
|
91
|
|
- }
|
|
92
|
|
- result = disk_read(disk, buffer + (offset << 9), sector);
|
|
93
|
|
- if (result < 0)
|
|
94
|
|
- break;
|
|
95
|
|
- }
|
|
96
|
|
- if (result < 0) {
|
|
97
|
|
- printf("disk read error at 0x%lx\n", sector);
|
|
98
|
|
- }
|
|
99
|
|
- return result;
|
|
100
|
|
-}
|
|
101
|
|
-
|
|
102
|
|
-static os_download_t probe_buffer(unsigned char *buffer, unsigned int len,
|
|
103
|
|
- int increment, unsigned int offset, unsigned int *roffset)
|
|
104
|
|
-{
|
|
105
|
|
- os_download_t os_download;
|
|
106
|
|
- unsigned int end;
|
|
107
|
|
- end = 0;
|
|
108
|
|
- os_download = 0;
|
|
109
|
|
- if (increment > 0) {
|
|
110
|
|
- end = len - SECTOR_SIZE;
|
|
111
|
|
- }
|
|
112
|
|
- do {
|
|
113
|
|
- offset += increment;
|
|
114
|
|
- os_download = probe_image(buffer + offset, len - offset);
|
|
115
|
|
- } while(!os_download && (offset != end));
|
|
116
|
|
- *roffset = offset;
|
|
117
|
|
- return os_download;
|
|
118
|
|
-}
|
|
119
|
|
-
|
|
120
|
|
-static int load_image(
|
|
121
|
|
- struct disk *disk,
|
|
122
|
|
- unsigned char *buffer, unsigned int buf_sectors,
|
|
123
|
|
- sector_t block, unsigned int offset,
|
|
124
|
|
- os_download_t os_download)
|
|
125
|
|
-{
|
|
126
|
|
- sector_t skip_sectors;
|
|
127
|
|
-
|
|
128
|
|
- skip_sectors = 0;
|
|
129
|
|
- while(1) {
|
|
130
|
|
- skip_sectors = os_download(buffer + offset,
|
|
131
|
|
- (buf_sectors << 9) - offset, 0);
|
|
132
|
|
-
|
|
133
|
|
- block += skip_sectors + buf_sectors;
|
|
134
|
|
- if (block >= disk->sectors) {
|
|
135
|
|
- block -= disk->sectors;
|
|
136
|
|
- }
|
|
137
|
|
-
|
|
138
|
|
- offset = 0;
|
|
139
|
|
- buf_sectors = 1;
|
|
140
|
|
- if (disk_read_sectors(disk, buffer, block, 1) < 0) {
|
|
141
|
|
- return 0;
|
|
142
|
|
- }
|
|
143
|
|
- }
|
|
144
|
|
- return -1;
|
|
145
|
|
-}
|
|
146
|
|
-
|
|
147
|
|
-int disk_probe(struct dev *dev)
|
|
148
|
|
-{
|
|
149
|
|
- struct disk *disk = (struct disk *)dev;
|
|
150
|
|
- if (dev->how_probe == PROBE_NEXT) {
|
|
151
|
|
- disk->drive += 1;
|
|
152
|
|
- }
|
|
153
|
|
- return probe(dev);
|
|
154
|
|
-}
|
|
155
|
|
-
|
|
156
|
|
-
|
|
157
|
|
-int disk_load_configuration(struct dev *dev)
|
|
158
|
|
-{
|
|
159
|
|
- /* Start with the very simplest possible disk configuration */
|
|
160
|
|
- struct disk *disk = (struct disk *)dev;
|
|
161
|
|
- disk->direction = (dev->failsafe)?-1:1;
|
|
162
|
|
- disk->disk_offset = 0;
|
|
163
|
|
- return 0;
|
|
164
|
|
-}
|
|
165
|
|
-
|
|
166
|
|
-int disk_load(struct dev *dev)
|
|
167
|
|
-{
|
|
168
|
|
- struct disk *disk = (struct disk *)dev;
|
|
169
|
|
- /* 16K == 8K in either direction from the start of the disk */
|
|
170
|
|
- static unsigned char buffer[32*SECTOR_SIZE];
|
|
171
|
|
- os_download_t os_download;
|
|
172
|
|
- unsigned int offset;
|
|
173
|
|
- unsigned int len;
|
|
174
|
|
- unsigned int buf_sectors;
|
|
175
|
|
- volatile sector_t block;
|
|
176
|
|
- volatile int inc, increment;
|
|
177
|
|
- int i;
|
|
178
|
|
- int result;
|
|
179
|
|
- jmp_buf real_restart;
|
|
180
|
|
-
|
|
181
|
|
-
|
|
182
|
|
- printf("Searching for image...\n");
|
|
183
|
|
- result = 0;
|
|
184
|
|
- /* Only check for 16byte aligned images */
|
|
185
|
|
- increment = (disk->direction < 0)?-16:16;
|
|
186
|
|
- /* Load a buffer, and see if it contains the start of an image
|
|
187
|
|
- * we can boot from disk.
|
|
188
|
|
- */
|
|
189
|
|
- len = sizeof(buffer);
|
|
190
|
|
- buf_sectors = sizeof(buffer) / SECTOR_SIZE;
|
|
191
|
|
- inc = increment;
|
|
192
|
|
- block = (disk->disk_offset) >> 9;
|
|
193
|
|
- if (buf_sectors/2 > block) {
|
|
194
|
|
- block = (disk->sectors - (buf_sectors/2)) + block;
|
|
195
|
|
- }
|
|
196
|
|
- /* let probe buffer assume offset always needs to be incremented */
|
|
197
|
|
- offset = (len/2 + ((disk->disk_offset) & 0x1ff)) - inc;
|
|
198
|
|
-
|
|
199
|
|
- /* Catch longjmp so if this image fails to load, I start looking
|
|
200
|
|
- * for the next image where I left off looking for this image.
|
|
201
|
|
- */
|
|
202
|
|
- memcpy(&real_restart, &restart_etherboot, sizeof(jmp_buf));
|
|
203
|
|
- i = setjmp(restart_etherboot);
|
|
204
|
|
- if ((i != 0) && (i != -2)) {
|
|
205
|
|
- memcpy(&restart_etherboot, &real_restart, sizeof(jmp_buf));
|
|
206
|
|
- longjmp(restart_etherboot, i);
|
|
207
|
|
- }
|
|
208
|
|
- /* Read the canidate sectors into the buffer */
|
|
209
|
|
- if (disk_read_sectors(disk, buffer, block, buf_sectors) < 0) {
|
|
210
|
|
- result = -1;
|
|
211
|
|
- goto out;
|
|
212
|
|
- }
|
|
213
|
|
- if (inc == increment) {
|
|
214
|
|
- os_download = probe_buffer(buffer, len, inc, offset, &offset);
|
|
215
|
|
- if (os_download)
|
|
216
|
|
- goto load_image;
|
|
217
|
|
- inc = -inc;
|
|
218
|
|
- }
|
|
219
|
|
- os_download = probe_buffer(buffer, len, inc, offset, &offset);
|
|
220
|
|
- if (!os_download) {
|
|
221
|
|
- result = -1;
|
|
222
|
|
- goto out;
|
|
223
|
|
- }
|
|
224
|
|
- load_image:
|
|
225
|
|
- printf("Loading image...\n");
|
|
226
|
|
- result = load_image(disk, buffer, buf_sectors, block, offset, os_download);
|
|
227
|
|
- out:
|
|
228
|
|
- memcpy(&restart_etherboot, &real_restart, sizeof(jmp_buf));
|
|
229
|
|
- return result;
|
|
230
|
|
-}
|
|
231
|
|
-
|
|
232
|
|
-int url_file(const char *name,
|
|
233
|
|
- int (*fnc)(unsigned char *, unsigned int, unsigned int, int) __unused)
|
|
234
|
|
-{
|
|
235
|
|
- unsigned int drive;
|
|
236
|
|
- unsigned long disk_offset;
|
|
237
|
|
- int direction;
|
|
238
|
|
- int type;
|
|
239
|
|
-
|
|
240
|
|
- disk_offset = 0;
|
|
241
|
|
- direction = 1;
|
|
242
|
|
- if (memcmp(name, "disk", 4) == 0) {
|
|
243
|
|
- type = DISK_DRIVER;
|
|
244
|
|
- name += 4;
|
|
245
|
|
- }
|
|
246
|
|
- else if (memcmp(name, "floppy", 6) == 0) {
|
|
247
|
|
- type = FLOPPY_DRIVER;
|
|
248
|
|
- name += 6;
|
|
249
|
|
- }
|
|
250
|
|
- else {
|
|
251
|
|
- printf("Unknown device type\n");
|
|
252
|
|
- return 0;
|
|
253
|
|
- }
|
|
254
|
|
- drive = strtoul(name, &name, 10);
|
|
255
|
|
- if ((name[0] == '+') || (name[0] == '-')) {
|
|
256
|
|
- direction = (name[0] == '-')? -1 : 1;
|
|
257
|
|
- name++;
|
|
258
|
|
- disk_offset = strtoul(name, &name, 10);
|
|
259
|
|
- }
|
|
260
|
|
- if (name[0]) {
|
|
261
|
|
- printf("Junk '%s' at end of disk url\n", name);
|
|
262
|
|
- return 0;
|
|
263
|
|
- }
|
|
264
|
|
- memset(&disk, 0, sizeof(disk));
|
|
265
|
|
- disk.buffer = disk_buffer;
|
|
266
|
|
- disk.drive = 0;
|
|
267
|
|
- disk.dev.how_probe = PROBE_FIRST;
|
|
268
|
|
- disk.dev.type = type;
|
|
269
|
|
- do {
|
|
270
|
|
- disk_disable();
|
|
271
|
|
- disk.dev.how_probe = disk_probe(&disk.dev);
|
|
272
|
|
- if (disk.dev.how_probe == PROBE_FAILED) {
|
|
273
|
|
- printf("Not that many drives\n");
|
|
274
|
|
- return 0;
|
|
275
|
|
- }
|
|
276
|
|
- } while(disk.drive < drive);
|
|
277
|
|
- disk.direction = direction;
|
|
278
|
|
- disk.disk_offset = disk_offset;
|
|
279
|
|
-
|
|
280
|
|
- return disk_load(&disk.dev);
|
|
281
|
|
-}
|
|
282
|
|
-
|
|
283
|
|
-void disk_disable(void)
|
|
284
|
|
-{
|
|
285
|
|
- disable(&disk.dev);
|
|
286
|
|
-}
|
|
287
|
|
-
|
|
288
|
|
-
|
|
289
|
|
-#endif
|