4 #warning "disk.c is currently broken"
9 static int dummy(void *unused __unused
)
14 static unsigned char disk_buffer
[DISK_BUFFER_SIZE
];
26 PROBE_FIRST
, /* how_probe */
27 PROBE_NONE
, /* to_probe */
32 (int (*)(struct disk
*, sector_t
))dummy
, /* read */
34 0, /* hw_sector_size */
35 0, /* sectors_per_read */
39 disk_buffer
, /* buffer */
48 struct disk
*disk
, unsigned char *buffer
, sector_t sector
)
53 /* Note: I do not handle disk wrap around here! */
55 /* Compute the start of the track cache */
57 /* Support sectors_per_read > 1 only on small disks */
58 if ((sizeof(sector_t
) > sizeof(unsigned long)) &&
59 (disk
->sectors_per_read
> 1)) {
61 offset
= ((unsigned long)sector
) % disk
->sectors_per_read
;
62 base_sector
-= offset
;
65 /* See if I need to update the track cache */
66 if ((sector
< disk
->sector
) ||
67 sector
>= disk
->sector
+ (disk
->bytes
>> 9)) {
69 result
= disk
->read(disk
, base_sector
);
73 /* Service the request from the track cache */
74 memcpy(buffer
, disk
->buffer
+ ((sector
- base_sector
)<<9), SECTOR_SIZE
);
78 static int disk_read_sectors(
80 unsigned char *buffer
,
81 sector_t base_sector
, unsigned int sectors
)
87 for(offset
= 0; offset
< sectors
; offset
++) {
88 sector
= base_sector
+ offset
;
89 if (sector
>= disk
->sectors
) {
90 sector
-= disk
->sectors
;
92 result
= disk_read(disk
, buffer
+ (offset
<< 9), sector
);
97 printf("disk read error at 0x%lx\n", sector
);
102 static os_download_t
probe_buffer(unsigned char *buffer
, unsigned int len
,
103 int increment
, unsigned int offset
, unsigned int *roffset
)
105 os_download_t os_download
;
110 end
= len
- SECTOR_SIZE
;
114 os_download
= probe_image(buffer
+ offset
, len
- offset
);
115 } while(!os_download
&& (offset
!= end
));
120 static int load_image(
122 unsigned char *buffer
, unsigned int buf_sectors
,
123 sector_t block
, unsigned int offset
,
124 os_download_t os_download
)
126 sector_t skip_sectors
;
130 skip_sectors
= os_download(buffer
+ offset
,
131 (buf_sectors
<< 9) - offset
, 0);
133 block
+= skip_sectors
+ buf_sectors
;
134 if (block
>= disk
->sectors
) {
135 block
-= disk
->sectors
;
140 if (disk_read_sectors(disk
, buffer
, block
, 1) < 0) {
147 int disk_probe(struct dev
*dev
)
149 struct disk
*disk
= (struct disk
*)dev
;
150 if (dev
->how_probe
== PROBE_NEXT
) {
157 int disk_load_configuration(struct dev
*dev
)
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;
166 int disk_load(struct dev
*dev
)
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
;
174 unsigned int buf_sectors
;
175 volatile sector_t block
;
176 volatile int inc
, increment
;
179 jmp_buf real_restart
;
182 printf("Searching for image...\n");
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.
189 len
= sizeof(buffer
);
190 buf_sectors
= sizeof(buffer
) / SECTOR_SIZE
;
192 block
= (disk
->disk_offset
) >> 9;
193 if (buf_sectors
/2 > block
) {
194 block
= (disk
->sectors
- (buf_sectors
/2)) + block
;
196 /* let probe buffer assume offset always needs to be incremented */
197 offset
= (len
/2 + ((disk
->disk_offset
) & 0x1ff)) - inc
;
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.
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
);
208 /* Read the canidate sectors into the buffer */
209 if (disk_read_sectors(disk
, buffer
, block
, buf_sectors
) < 0) {
213 if (inc
== increment
) {
214 os_download
= probe_buffer(buffer
, len
, inc
, offset
, &offset
);
219 os_download
= probe_buffer(buffer
, len
, inc
, offset
, &offset
);
225 printf("Loading image...\n");
226 result
= load_image(disk
, buffer
, buf_sectors
, block
, offset
, os_download
);
228 memcpy(&restart_etherboot
, &real_restart
, sizeof(jmp_buf));
232 int url_file(const char *name
,
233 int (*fnc
)(unsigned char *, unsigned int, unsigned int, int) __unused
)
236 unsigned long disk_offset
;
242 if (memcmp(name
, "disk", 4) == 0) {
246 else if (memcmp(name
, "floppy", 6) == 0) {
247 type
= FLOPPY_DRIVER
;
251 printf("Unknown device type\n");
254 drive
= strtoul(name
, &name
, 10);
255 if ((name
[0] == '+') || (name
[0] == '-')) {
256 direction
= (name
[0] == '-')? -1 : 1;
258 disk_offset
= strtoul(name
, &name
, 10);
261 printf("Junk '%s' at end of disk url\n", name
);
264 memset(&disk
, 0, sizeof(disk
));
265 disk
.buffer
= disk_buffer
;
267 disk
.dev
.how_probe
= PROBE_FIRST
;
268 disk
.dev
.type
= type
;
271 disk
.dev
.how_probe
= disk_probe(&disk
.dev
);
272 if (disk
.dev
.how_probe
== PROBE_FAILED
) {
273 printf("Not that many drives\n");
276 } while(disk
.drive
< drive
);
277 disk
.direction
= direction
;
278 disk
.disk_offset
= disk_offset
;
280 return disk_load(&disk
.dev
);
283 void disk_disable(void)