3 Copyright (C) 1999 Benjamin Herrenschmidt
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "partition.h"
31 extern char bootdevice[1024];
33 /* This function follows the device path in the devtree and separates
34 the device name, partition number, and other datas (mostly file name)
35 the string passed in parameters is changed since 0 are put in place
36 of some separators to terminate the various strings.
38 when a default device is supplied imagepath will be assumed to be a
39 plain filename unless it contains a : otherwise if defaultdev is
40 NULL imagepath will be assumed to be a device path.
42 returns 1 on success 0 on failure.
45 - /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:4
46 - /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:4,/boot/vmlinux
48 - enet:10.0.0.1,/tftpboot/vmlinux
49 - enet:,/tftpboot/vmlinux
52 Supported only if defdevice == NULL
54 - any other device path lacking a :
56 - hd:2,\\:tbxi <- no filename will be detected due to the extra :
57 - enet:192.168.2.1,bootme,c-iaddr,g-iaddr,subnet-mask,bootp-retries,tftp-retries */
60 parse_device_path(char *imagepath, char *defdevice, int defpart,
61 char *deffile, struct boot_fspec_t *result)
74 ipath = strdup(imagepath);
77 defdev = strdup(defdevice);
80 if (!strstr(defdev, "ethernet") && !strstr(defdev, "enet")) {
81 if ((ptr = strrchr(defdev, ':')) != NULL)
82 *ptr = 0; /* remove trailing : from defdevice if necessary */
86 /* if there is no : then there is no filename or partition. must
87 use strrchr() since enet:,10.0.0.1,file is legal */
89 if (strchr(ipath, ':') != NULL) {
90 if ((ptr = strrchr(ipath, ',')) != NULL) {
91 char *colon = strrchr(ipath, ':');
92 /* If a ':' occurs *after* a ',', then we assume that there is
94 if (!colon || colon < ptr) {
95 result->file = strdup(ptr+1);
96 /* Trim the filename off */
102 if (strstr(ipath, "ethernet") || strstr(ipath, "enet"))
103 if ((ptr = strstr(ipath, "bootp")) != NULL) { /* `n' key booting boots enet:bootp */
105 result->dev = strdup(ipath);
107 result->dev = strdup(ipath);
108 else if ((ptr = strchr(ipath, ':')) != NULL) {
110 result->dev = strdup(ipath);
112 result->part = simple_strtol(ptr+1, NULL, 10);
113 } else if (!defdev) {
114 result->dev = strdup(ipath);
115 } else if (strlen(ipath)) {
116 result->file = strdup(ipath);
121 if (!result->dev && defdev)
122 result->dev = strdup(defdev);
124 if (result->part < 0)
125 result->part = defpart;
128 result->file = strdup(deffile);
138 file_block_open( struct boot_file_t* file,
139 const char* dev_name,
140 const char* file_name,
143 struct partition_t* parts;
144 struct partition_t* p;
145 struct partition_t* found;
147 parts = partitions_lookup(dev_name);
152 prom_printf("partitions:\n");
154 prom_printf("no partitions found.\n");
156 for (p = parts; p && !found; p=p->next) {
157 DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
158 p->part_number, p->part_start, p->part_size );
159 if (partition == -1) {
160 file->fs = fs_open( file, dev_name, p, file_name );
161 if (file->fs != NULL)
164 if ((partition >= 0) && (partition == p->part_number))
168 prom_printf(" (match)\n");
172 /* Note: we don't skip when found is NULL since we can, in some
173 * cases, let OF figure out a default partition.
175 DEBUG_F( "Using OF defaults.. (found = %p)\n", found );
176 file->fs = fs_open( file, dev_name, found, file_name );
180 partitions_free(parts);
186 file_net_open( struct boot_file_t* file,
187 const char* dev_name,
188 const char* file_name)
190 file->fs = fs_of_netboot;
191 return fs_of_netboot->open(file, dev_name, NULL, file_name);
195 default_read( struct boot_file_t* file,
199 prom_printf("WARNING ! default_read called !\n");
204 default_seek( struct boot_file_t* file,
207 prom_printf("WARNING ! default_seek called !\n");
212 default_close( struct boot_file_t* file)
214 prom_printf("WARNING ! default_close called !\n");
218 static struct fs_t fs_default =
228 int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file)
232 memset(file, 0, sizeof(struct boot_file_t*));
233 file->fs = &fs_default;
235 DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n",
236 spec->dev, spec->file, spec->part);
238 result = prom_get_devtype(spec->dev);
240 file->device_kind = result;
244 switch(file->device_kind) {
245 case FILE_DEVICE_BLOCK:
246 DEBUG_F("device is a block device\n");
247 return file_block_open(file, spec->dev, spec->file, spec->part);
248 case FILE_DEVICE_NET:
249 DEBUG_F("device is a network device\n");
250 return file_net_open(file, spec->dev, spec->file);
257 * c-file-style: "k&r"