2 * Creation Date: <2003/12/03 22:10:45 samuel>
3 * Time-stamp: <2004/01/07 19:17:45 samuel>
9 * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
18 #include "libopenbios/bindings.h"
19 #include "libopenbios/load.h"
20 #include "libc/diskio.h"
21 #include "libc/vsprintf.h"
24 //#define DEBUG_DISK_LABEL
26 #ifdef DEBUG_DISK_LABEL
27 #define DPRINTF(fmt, args...) \
28 do { printk("DISK-LABEL - %s: " fmt, __func__ , ##args); } while (0)
30 #define DPRINTF(fmt, args...) do { } while (0)
38 ucell offs_hi, offs_lo;
39 ucell size_hi, size_lo;
41 int type; /* partition type or -1 */
44 phandle_t filesystem_ph;
47 DECLARE_NODE( dlabel, 0, sizeof(dlabel_info_t), "/packages/disk-label" );
52 dlabel_close( __attribute__((unused))dlabel_info_t *di )
58 dlabel_open( dlabel_info_t *di )
66 path = my_args_copy();
68 DPRINTF("dlabel-open '%s'\n", path );
72 /* Find parent methods */
73 di->filesystem_ph = 0;
74 di->parent_seek_xt = find_parent_method("seek");
75 di->parent_tell_xt = find_parent_method("tell");
76 di->parent_read_xt = find_parent_method("read");
78 /* If arguments have been passed, determine the partition/filesystem type */
79 if (path && strlen(path)) {
81 /* Read first block from parent device */
83 call_package(di->parent_seek_xt, my_parent());
86 PUSH(pointer2cell(block0));
88 call_package(di->parent_read_xt, my_parent());
90 if (status != sizeof(block0))
93 /* Find partition handler */
94 PUSH( pointer2cell(block0) );
95 selfword("find-part-handler");
98 /* We found a suitable partition handler, so interpose it */
99 DPRINTF("Partition found on disk - scheduling interpose with ph " FMT_ucellx "\n", ph);
107 /* unknown (or missing) partition map,
111 DPRINTF("Unknown or missing partition map; trying whole disk\n");
113 /* Probe for filesystem from start of device */
115 PUSH_ih( my_self() );
116 selfword("find-filesystem");
119 /* If we have been asked to open a particular file, interpose the filesystem package with the passed filename as an argument */
120 di->filesystem_ph = ph;
122 DPRINTF("Located filesystem with ph " FMT_ucellx "\n", ph);
123 DPRINTF("path: %s length: %d\n", path, strlen(path));
125 if (path && strlen(path)) {
126 DPRINTF("INTERPOSE!\n");
132 } else if (path && strcmp(path, "%BOOT") != 0) {
139 /* No arguments were passed, so we just use the parent raw device directly */
153 /* ( addr len -- actual ) */
155 dlabel_read( dlabel_info_t *di )
157 /* Call back up to parent */
158 call_package(di->parent_read_xt, my_parent());
161 /* ( pos.d -- status ) */
163 dlabel_seek( dlabel_info_t *di )
165 /* Call back up to parent */
166 call_package(di->parent_seek_xt, my_parent());
169 /* ( -- filepos.d ) */
171 dlabel_tell( dlabel_info_t *di )
173 /* Call back up to parent */
174 call_package(di->parent_tell_xt, my_parent());
177 /* ( addr len -- actual ) */
179 dlabel_write( __attribute__((unused)) dlabel_info_t *di )
185 /* ( addr -- size ) */
187 dlabel_load( __attribute__((unused)) dlabel_info_t *di )
189 /* Try the load method of the part package */
192 /* If we have a partition handle, invoke the load word on it */
194 xt = find_ih_method("load", di->part_ih);
196 forth_printf("load currently not implemented for ihandle " FMT_ucellx "\n", di->part_ih);
201 DPRINTF("calling load on ihandle " FMT_ucellx "\n", di->part_ih);
203 call_package(xt, di->part_ih);
205 /* Otherwise attempt load directly on the raw disk */
206 DPRINTF("calling load on raw disk ihandle " FMT_ucellx "\n", my_self());
212 /* ( pathstr len -- ) */
214 dlabel_dir( dlabel_info_t *di )
216 if ( di->filesystem_ph ) {
219 PUSH( di->filesystem_ph );
220 fword("find-method");
224 forth_printf("disk-label: Unable to determine filesystem\n");
230 NODE_METHODS( dlabel ) = {
231 { "open", dlabel_open },
232 { "close", dlabel_close },
233 { "load", dlabel_load },
234 { "read", dlabel_read },
235 { "write", dlabel_write },
236 { "seek", dlabel_seek },
237 { "tell", dlabel_tell },
238 { "dir", dlabel_dir },
242 disklabel_init( void )
244 REGISTER_NODE( dlabel );