2 * file.c - Filesystem related interfaces
4 * Copyright (C) 2001, 2002 Ethan Benson
8 * Copyright (C) 2001 Colin Walters
10 * Copyright (C) 1999 Benjamin Herrenschmidt
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include "partition.h"
39 extern char bootdevice[1024];
41 /* This function follows the device path in the devtree and separates
42 the device name, partition number, and other datas (mostly file name)
43 the string passed in parameters is changed since 0 are put in place
44 of some separators to terminate the various strings.
46 when a default device is supplied imagepath will be assumed to be a
47 plain filename unless it contains a : otherwise if defaultdev is
48 NULL imagepath will be assumed to be a device path.
50 returns 1 on success 0 on failure.
53 - /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:4
54 - /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:4,/boot/vmlinux
56 - enet:10.0.0.1,/tftpboot/vmlinux
57 - enet:,/tftpboot/vmlinux
60 Supported only if defdevice == NULL
62 - any other device path lacking a :
64 - hd:2,\\:tbxi <- no filename will be detected due to the extra :
65 - enet:192.168.2.1,bootme,c-iaddr,g-iaddr,subnet-mask,bootp-retries,tftp-retries */
68 parse_device_path(char *imagepath, char *defdevice, int defpart,
69 char *deffile, struct boot_fspec_t *result)
81 else if (!(ipath = strdup(imagepath)))
85 defdev = strdup(defdevice);
88 if (!strstr(defdev, "ethernet") && !strstr(defdev, "enet")) {
89 if ((ptr = strrchr(defdev, ':')) != NULL)
90 *ptr = 0; /* remove trailing : from defdevice if necessary */
96 /* if there is no : then there is no filename or partition. must
97 use strrchr() since enet:,10.0.0.1,file is legal */
99 if (strchr(ipath, ':') != NULL) {
100 if ((ptr = strrchr(ipath, ',')) != NULL) {
101 char *colon = strrchr(ipath, ':');
102 /* If a ':' occurs *after* a ',', then we assume that there is
104 if (!colon || colon < ptr) {
105 result->file = strdup(ptr+1);
106 /* Trim the filename off */
112 if (strstr(ipath, "ethernet") || strstr(ipath, "enet"))
113 if ((ptr = strstr(ipath, "bootp")) != NULL) { /* `n' key booting boots enet:bootp */
115 result->dev = strdup(ipath);
117 result->dev = strdup(ipath);
118 else if ((ptr = strchr(ipath, ':')) != NULL) {
120 result->dev = strdup(ipath);
122 result->part = simple_strtol(ptr+1, NULL, 10);
123 } else if (!defdev) {
124 result->dev = strdup(ipath);
125 } else if (strlen(ipath)) {
126 result->file = strdup(ipath);
132 if (!result->dev && defdev)
133 result->dev = strdup(defdev);
135 if (result->part < 0)
136 result->part = defpart;
139 result->file = strdup(deffile);
149 file_block_open( struct boot_file_t* file,
150 const char* dev_name,
151 const char* file_name,
154 struct partition_t* parts;
155 struct partition_t* p;
156 struct partition_t* found;
158 parts = partitions_lookup(dev_name);
163 prom_printf("partitions:\n");
165 prom_printf("no partitions found.\n");
167 for (p = parts; p && !found; p=p->next) {
168 DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
169 p->part_number, p->part_start, p->part_size );
170 if (partition == -1) {
171 file->fs = fs_open( file, dev_name, p, file_name );
172 if (file->fs == NULL || fserrorno != FILE_ERR_OK)
175 partition = p->part_number;
179 if ((partition >= 0) && (partition == p->part_number))
183 prom_printf(" (match)\n");
187 /* Note: we don't skip when found is NULL since we can, in some
188 * cases, let OF figure out a default partition.
190 DEBUG_F( "Using OF defaults.. (found = %p)\n", found );
191 file->fs = fs_open( file, dev_name, found, file_name );
195 partitions_free(parts);
201 file_net_open( struct boot_file_t* file,
202 const char* dev_name,
203 const char* file_name)
205 file->fs = fs_of_netboot;
206 return fs_of_netboot->open(file, dev_name, NULL, file_name);
210 default_read( struct boot_file_t* file,
214 prom_printf("WARNING ! default_read called !\n");
219 default_seek( struct boot_file_t* file,
222 prom_printf("WARNING ! default_seek called !\n");
227 default_close( struct boot_file_t* file)
229 prom_printf("WARNING ! default_close called !\n");
233 static struct fs_t fs_default =
243 int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file)
247 memset(file, 0, sizeof(struct boot_file_t*));
248 file->fs = &fs_default;
250 DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n",
251 spec->dev, spec->file, spec->part);
253 result = prom_get_devtype(spec->dev);
255 file->device_kind = result;
259 switch(file->device_kind) {
260 case FILE_DEVICE_BLOCK:
261 DEBUG_F("device is a block device\n");
262 return file_block_open(file, spec->dev, spec->file, spec->part);
263 case FILE_DEVICE_NET:
264 DEBUG_F("device is a network device\n");
265 return file_net_open(file, spec->dev, spec->file);
272 * c-file-style: "k&r"