Annotation of qemu/roms/openbios/packages/disk-label.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *   Creation Date: <2003/12/03 22:10:45 samuel>
                      3:  *   Time-stamp: <2004/01/07 19:17:45 samuel>
                      4:  *
                      5:  *     <disk-label.c>
                      6:  *
                      7:  *     Partition support
                      8:  *
                      9:  *   Copyright (C) 2003, 2004 Samuel Rydh ([email protected])
                     10:  *
                     11:  *   This program is free software; you can redistribute it and/or
                     12:  *   modify it under the terms of the GNU General Public License
                     13:  *   version 2
                     14:  *
                     15:  */
                     16: 
                     17: #include "config.h"
                     18: #include "libopenbios/bindings.h"
                     19: #include "libopenbios/load.h"
                     20: #include "libc/diskio.h"
                     21: #include "libc/vsprintf.h"
                     22: #include "packages.h"
                     23: 
                     24: //#define DEBUG_DISK_LABEL
                     25: 
                     26: #ifdef DEBUG_DISK_LABEL
                     27: #define DPRINTF(fmt, args...) \
                     28: do { printk("DISK-LABEL - %s: " fmt, __func__ , ##args); } while (0)
                     29: #else
                     30: #define DPRINTF(fmt, args...) do { } while (0)
                     31: #endif
                     32: 
                     33: typedef struct {
                     34:        xt_t            parent_seek_xt;
                     35:        xt_t            parent_tell_xt;
                     36:        xt_t            parent_read_xt;
                     37: 
                     38:         ucell          offs_hi, offs_lo;
                     39:         ucell          size_hi, size_lo;
                     40:        int             block_size;
                     41:        int             type;           /* partition type or -1 */
                     42: 
                     43:        ihandle_t       part_ih;
                     44:        phandle_t       filesystem_ph;
                     45: } dlabel_info_t;
                     46: 
                     47: DECLARE_NODE( dlabel, 0, sizeof(dlabel_info_t), "/packages/disk-label" );
                     48: 
                     49: 
                     50: /* ( -- ) */
                     51: static void
                     52: dlabel_close( __attribute__((unused))dlabel_info_t *di )
                     53: {
                     54: }
                     55: 
                     56: /* ( -- success? ) */
                     57: static void
                     58: dlabel_open( dlabel_info_t *di )
                     59: {
                     60:        char *path;
                     61:        char block0[512];
                     62:        phandle_t ph;
                     63:        int success=0;
                     64:        cell status;
                     65: 
                     66:        path = my_args_copy();
                     67: 
                     68:        DPRINTF("dlabel-open '%s'\n", path );
                     69: 
                     70:        di->part_ih = 0;
                     71: 
                     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");       
                     77: 
                     78:        /* Read first block from parent device */
                     79:        DPUSH(0);
                     80:        call_package(di->parent_seek_xt, my_parent());
                     81:        POP();
                     82: 
                     83:        PUSH(pointer2cell(block0));
                     84:        PUSH(sizeof(block0));
                     85:        call_package(di->parent_read_xt, my_parent());
                     86:        status = POP();
                     87:        if (status != sizeof(block0))
                     88:                goto out;
                     89: 
                     90:        /* Find partition handler */
                     91:        PUSH( pointer2cell(block0) );
                     92:        selfword("find-part-handler");
                     93:        ph = POP_ph();
                     94:        if( ph ) {
                     95:                /* We found a suitable partition handler, so interpose it */
                     96:                DPRINTF("Partition found on disk - scheduling interpose with ph " FMT_ucellx "\n", ph);
                     97: 
                     98:                push_str(path);
                     99:                PUSH_ph(ph);
                    100:                fword("interpose");     
                    101: 
                    102:                success = 1;
                    103:        } else {
                    104:                /* unknown (or missing) partition map,
                    105:                 * try the whole disk
                    106:                 */
                    107: 
                    108:                DPRINTF("Unknown or missing partition map; trying whole disk\n");
                    109: 
                    110:                /* Probe for filesystem from start of device */
                    111:                DPUSH ( 0 );    
                    112:                PUSH_ih( my_self() );
                    113:                selfword("find-filesystem");
                    114:                ph = POP_ph();
                    115:                if( ph ) {
                    116:                        /* If we have been asked to open a particular file, interpose the filesystem package with the passed filename as an argument */
                    117:                        di->filesystem_ph = ph;
                    118: 
                    119:                        DPRINTF("Located filesystem with ph " FMT_ucellx "\n", ph);
                    120:                        DPRINTF("path: %s length: %d\n", path, strlen(path));
                    121: 
                    122:                         if (path && strlen(path)) {
                    123:                                DPRINTF("INTERPOSE!\n");
                    124: 
                    125:                                push_str( path );
                    126:                                PUSH_ph( ph );
                    127:                                fword("interpose");
                    128:                        }
                    129:                 } else if (path && strcmp(path, "%BOOT") != 0) {
                    130:                        goto out;
                    131:                }
                    132: 
                    133:                success = 1;
                    134:        }
                    135: 
                    136: out:
                    137:        if( path )
                    138:                free( path );
                    139:        if( !success ) {
                    140:                dlabel_close( di );
                    141:                RET(0);
                    142:        }
                    143:        PUSH(-1);
                    144: }
                    145: 
                    146: /* ( addr len -- actual ) */
                    147: static void
                    148: dlabel_read( dlabel_info_t *di )
                    149: {
                    150:        /* Call back up to parent */
                    151:        call_package(di->parent_read_xt, my_parent());
                    152: }
                    153: 
                    154: /* ( pos.d -- status ) */
                    155: static void
                    156: dlabel_seek( dlabel_info_t *di )
                    157: {
                    158:        /* Call back up to parent */
                    159:        call_package(di->parent_seek_xt, my_parent());
                    160: }
                    161: 
                    162: /* ( -- filepos.d ) */
                    163: static void
                    164: dlabel_tell( dlabel_info_t *di )
                    165: {
                    166:        /* Call back up to parent */
                    167:        call_package(di->parent_tell_xt, my_parent());
                    168: }
                    169: 
                    170: /* ( addr len -- actual ) */
                    171: static void
                    172: dlabel_write( __attribute__((unused)) dlabel_info_t *di )
                    173: {
                    174:        DDROP();
                    175:        PUSH( -1 );
                    176: }
                    177: 
                    178: /* ( addr -- size ) */
                    179: static void
                    180: dlabel_load( __attribute__((unused)) dlabel_info_t *di )
                    181: {
                    182:        /* Try the load method of the part package */
                    183: #ifdef DEBUG_DISK_LABEL
                    184:        char *buf;
                    185: #endif
                    186:        xt_t xt;
                    187: 
                    188: #ifdef DEBUG_DISK_LABEL
                    189:        buf = (char *)POP();
                    190: #else
                    191:         POP();
                    192: #endif
                    193: 
                    194:        DPRINTF("load invoked with address %p\n", buf);
                    195: 
                    196:        /* If we have a partition handle, invoke the load word on it */
                    197:        if (di->part_ih) {
                    198:                xt = find_ih_method("load", di->part_ih);
                    199:                if (!xt) {
                    200:                        forth_printf("load currently not implemented for ihandle " FMT_ucellx "\n", di->part_ih);
                    201:                        PUSH(0);
                    202:                        return;
                    203:                }
                    204:        
                    205:                DPRINTF("calling load on ihandle " FMT_ucellx "\n", di->part_ih);
                    206: 
                    207:                call_package(xt, di->part_ih);
                    208:        } else {
                    209:                /* Otherwise attempt load directly on the raw disk */
                    210:                DPRINTF("calling load on raw disk ihandle " FMT_ucellx "\n", my_self());
                    211: 
                    212:                load(my_self());
                    213:        }
                    214: }
                    215: 
                    216: /* ( pathstr len -- ) */
                    217: static void
                    218: dlabel_dir( dlabel_info_t *di )
                    219: {
                    220:        if ( di->filesystem_ph ) {
                    221:                PUSH( my_self() );
                    222:                push_str("dir");
                    223:                PUSH( di->filesystem_ph );
                    224:                fword("find-method");
                    225:                POP();
                    226:                fword("execute");
                    227:        } else {
                    228:                forth_printf("disk-label: Unable to determine filesystem\n");
                    229:                POP();
                    230:                POP();
                    231:        }
                    232: }
                    233: 
                    234: NODE_METHODS( dlabel ) = {
                    235:        { "open",       dlabel_open     },
                    236:        { "close",      dlabel_close    },
                    237:        { "load",       dlabel_load     },
                    238:        { "read",       dlabel_read     },
                    239:        { "write",      dlabel_write    },
                    240:        { "seek",       dlabel_seek     },
                    241:        { "tell",       dlabel_tell     },
                    242:        { "dir",        dlabel_dir      },
                    243: };
                    244: 
                    245: void
                    246: disklabel_init( void )
                    247: {
                    248:        REGISTER_NODE( dlabel );
                    249: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.