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 ((ptr = strrchr(ipath, ',')) != NULL) {
87 char *colon = strrchr(ipath, ':');
88 /* If a ':' occurs *after* a ',', then we assume that there is
90 if (!colon || colon < ptr) {
91 result->file = strdup(ptr+1);
92 /* Trim the filename off */
97 if (strstr(ipath, "ethernet") || strstr(ipath, "enet"))
98 if ((ptr = strstr(ipath, "bootp")) != NULL) { /* `n' key booting boots enet:bootp */
100 result->dev = strdup(ipath);
102 result->dev = strdup(ipath);
103 else if ((ptr = strchr(ipath, ':')) != NULL) {
105 result->dev = strdup(ipath);
107 result->part = simple_strtol(ptr+1, NULL, 10);
108 } else if (!defdev) {
109 result->dev = strdup(ipath);
110 } else if (strlen(ipath)) {
111 result->file = strdup(ipath);
116 if (!result->dev && defdev)
117 result->dev = strdup(defdev);
119 if (result->part < 0)
120 result->part = defpart;
123 result->file = strdup(deffile);
133 file_block_open( struct boot_file_t* file,
134 const char* dev_name,
135 const char* file_name,
138 struct partition_t* parts;
139 struct partition_t* p;
140 struct partition_t* found;
142 parts = partitions_lookup(dev_name);
147 prom_printf("partitions:\n");
149 prom_printf("no partitions found.\n");
151 for (p = parts; p && !found; p=p->next) {
152 DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
153 p->part_number, p->part_start, p->part_size );
154 if (partition == -1) {
155 file->fs = fs_open( file, dev_name, p, file_name );
156 if (file->fs != NULL)
159 if ((partition >= 0) && (partition == p->part_number))
163 prom_printf(" (match)\n");
167 /* Note: we don't skip when found is NULL since we can, in some
168 * cases, let OF figure out a default partition.
170 DEBUG_F( "Using OF defaults.. (found = %p)\n", found );
171 file->fs = fs_open( file, dev_name, found, file_name );
175 partitions_free(parts);
181 file_net_open( struct boot_file_t* file,
182 const char* dev_name,
183 const char* file_name)
185 file->fs = fs_of_netboot;
186 return fs_of_netboot->open(file, dev_name, NULL, file_name);
190 default_read( struct boot_file_t* file,
194 prom_printf("WARNING ! default_read called !\n");
199 default_seek( struct boot_file_t* file,
202 prom_printf("WARNING ! default_seek called !\n");
207 default_close( struct boot_file_t* file)
209 prom_printf("WARNING ! default_close called !\n");
213 static struct fs_t fs_default =
223 int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file)
227 memset(file, 0, sizeof(struct boot_file_t*));
228 file->fs = &fs_default;
230 DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n",
231 spec->dev, spec->file, spec->part);
233 result = prom_get_devtype(spec->dev);
235 file->device_kind = result;
239 switch(file->device_kind) {
240 case FILE_DEVICE_BLOCK:
241 DEBUG_F("device is a block device\n");
242 return file_block_open(file, spec->dev, spec->file, spec->part);
243 case FILE_DEVICE_NET:
244 DEBUG_F("device is a network device\n");
245 return file_net_open(file, spec->dev, spec->file);
252 * c-file-style: "k&r"