Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / libfs / raw.c
1 /*
2  * <raw.c>
3  *
4  * Open Hack'Ware BIOS raw file system management
5  * 
6  * Copyright (c) 2004-2005 Jocelyn Mayer
7  * 
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License V2
10  *   as published by the Free Software Foundation
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include "bios.h"
25 #include "../libpart/libpart.h"
26 #include "libfs.h"
27
28 /* Raw filesystem (ie no filesystem) */
29 static inode_t *fs_raw_get_inode (inode_t *parent, const unsigned char *name)
30 {
31     inode_t *new;
32     fs_t *fs;
33     int flags;
34
35     if (parent != NULL) {
36         return NULL;
37     }
38     /* Open root inode */
39     flags = INODE_TYPE_DIR;
40     fs = NULL;
41     new = malloc(sizeof(inode_t));
42     memset(new, 0, sizeof(inode_t));
43     new->flags = flags;
44     new->name = strdup(name);
45
46     return new;
47 }
48
49 static void fs_raw_put_inode (inode_t *inode)
50 {
51     free(inode);
52 }
53
54 static uint32_t fs_raw_map_bloc (unused inode_t *inode, uint32_t bloc)
55 {
56     if (inode != NULL
57         /* XXX: can't figure out why I did this... */
58         /* && inode == inode->fs->bootfile*/
59         )
60          bloc += inode->blocs[0].bloc;
61
62     return bloc;
63 }
64
65 static inode_t *fs_raw_get_special_inode (fs_t *fs, int type)
66 {
67     const unsigned char *name;
68     inode_t *new, *parent, **inp;
69     int flags;
70
71     new = NULL;
72     name = NULL;
73     parent = NULL;
74     inp = NULL;
75     flags = 0;
76     switch (type) {
77     case FILE_ROOT:
78         if (fs->root != NULL) {
79             new = fs->root;
80         } else {
81             flags = INODE_TYPE_DIR;
82             parent = NULL;
83             name = NULL;
84             inp = &fs->root;
85         }
86         break;
87     case FILE_BOOT:
88         if (fs->bootfile != NULL) {
89             dprintf("bootfile already exists\n");
90             new = fs->bootfile;
91         } else {
92             new = part_private_get(fs_part(fs));
93             if (fs->bootdir == NULL) {
94                 dprintf("Get boot directory\n");
95                 fs->bootdir = fs_raw_get_special_inode(fs, FILE_BOOTDIR);
96             }
97             parent = fs->bootdir;
98             if (new != NULL) {
99                 dprintf("Fix bootfile\n");
100                 new->parent = parent;
101                 new->fs = fs;
102             } else {
103                 dprintf("New bootfile\n");
104                 flags = INODE_TYPE_FILE | INODE_FLAG_EXEC | INODE_FLAG_BOOT;
105                 name = "ofwboot";
106                 inp = &fs->bootfile;
107             }
108         }
109         break;
110     case FILE_BOOTDIR:
111         if (fs->bootdir != NULL) {
112             new = fs->bootdir;
113         } else {
114             flags = INODE_TYPE_DIR;
115             parent = fs->root;
116             name = "boot";
117             inp = &fs->bootdir;
118         }
119         break;
120     default:
121         return NULL;
122     }
123     if (new == NULL) {
124         new = malloc(sizeof(inode_t));
125         memset(new, 0, sizeof(inode_t));
126         new->flags = flags;
127         new->parent = parent;
128         if (name != NULL)
129             new->name = strdup(name);
130         new->fs = fs;
131         *inp = new;
132     }
133     
134     return new;
135 }
136
137 static fs_ops_t fs_ops_raw = {
138     &fs_raw_get_inode,
139     &fs_raw_put_inode,
140     &fs_raw_map_bloc,
141     &fs_raw_get_special_inode,
142 };
143
144 int fs_raw_set_bootfile (part_t *part,
145                          uint32_t start_bloc, uint32_t start_offset,
146                          uint32_t size_bloc, uint32_t size_offset)
147 {
148     inode_t *new;
149
150     new = malloc(sizeof(inode_t));
151     if (new == NULL)
152         return -1;
153     DPRINTF("%s: pos %d %d size %d %d\n", __func__, start_bloc, start_offset,
154             size_bloc, size_offset);
155     memset(new, 0, sizeof(inode_t));
156     new->flags = INODE_TYPE_FILE | INODE_FLAG_EXEC | INODE_FLAG_BOOT;
157     new->name = "ofwboot";
158     new->blocs[0].bloc = start_bloc;
159     new->blocs[0].offset = start_offset;
160     new->size.bloc = size_bloc;
161     new->size.offset = size_offset;
162     new->nb_blocs = size_bloc;
163     part_private_set(part, new);
164
165     return 0;
166 }
167
168 int fs_raw_probe (part_t *part, uint32_t *size,
169                   fs_ops_t **fs_ops, unsigned char **name,
170                   unused void **private)
171 {
172     DPRINTF("%s: %p map_bloc %p\n", __func__, &fs_ops_raw, &fs_raw_map_bloc);
173     *fs_ops = &fs_ops_raw;
174     *name = "Raw FS";
175     *size = part_size(part);
176
177     return FS_TYPE_RAW;
178 }