1
/* prom - prom handling routines via /dev/openprom
3
Copyright (C) 1996 Jakub Jelinek
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
23
#include <sys/ioctl.h>
25
# include <asm/openpromio.h>
26
#elif defined (__sun__)
27
# include <sys/types.h>
28
# include <sys/stat.h>
29
# include <sys/openpromio.h>
32
# error "Unknown system"
36
static struct openpromio *oi;
37
static char buffer[2048 + sizeof (oi->oprom_size)];
38
static int prom_root_node = 0;
40
static int current_node;
41
static int previous_node;
43
static int parent_node;
45
#define SETSIZE oi->oprom_size = 2048;
49
if ((fd = open ("/dev/openprom", O_RDONLY)) < 0 &&
50
(fd = open ("/dev/misc/openprom", O_RDONLY)) < 0)
52
oi = (struct openpromio *)buffer;
54
*(int *)(oi->oprom_array) = 0;
55
if (ioctl (fd, OPROMNEXT, (void *)oi) >= 0) {
56
prom_root_node = *(int *)(oi->oprom_array);
57
current_node = prom_root_node;
66
int prom_set_root_node (void)
69
*(int *)(oi->oprom_array) = 0;
70
if (ioctl (fd, OPROMNEXT, (void *)oi) >= 0) {
71
current_node = prom_root_node;
80
int prom_search_siblings (char *name)
82
int node = current_node;
86
strcpy (oi->oprom_array, "name");
87
if (ioctl (fd, OPROMGETPROP, (void *)oi) < 0)
89
if (!oi->oprom_size) return -1;
90
if (!strcmp (oi->oprom_array, name))
93
*(int *)(oi->oprom_array) = node;
94
if (ioctl (fd, OPROMNEXT, (void *)oi) < 0 || !(*(int *)(oi->oprom_array)))
96
if (!(*(int *)(oi->oprom_array)) || !oi->oprom_size) return -1;
97
node = *(int *)(oi->oprom_array);
98
previous_node = current_node;
104
int prom_next_sibling (void)
107
*(int *)(oi->oprom_array) = current_node;
108
if (ioctl (fd, OPROMNEXT, (void *)oi) < 0 || !(*(int *)(oi->oprom_array)))
110
if (!(*(int *)(oi->oprom_array)) || !oi->oprom_size) return -1;
111
previous_node = current_node;
112
current_node = *(int *)(oi->oprom_array);
117
int prom_getchild (void)
120
*(int *)(oi->oprom_array) = current_node;
121
if (ioctl (fd, OPROMCHILD, (void *)oi) >= 0) {
122
if (!(*(int *)(oi->oprom_array)) || !oi->oprom_size) return -1;
123
parent_node = current_node;
124
current_node = *(int *)(oi->oprom_array);
126
previous_node = parent_node;
132
char *prom_getstring (char *name)
135
strcpy (oi->oprom_array, name);
136
if (ioctl (fd, OPROMGETPROP, (void *)oi) >= 0) {
137
if (!oi->oprom_size) return 0;
138
return oi->oprom_array;
143
char *prom_getopt (char *name)
146
strcpy (oi->oprom_array, name);
147
if (ioctl (fd, OPROMGETOPT, (void *)oi) >= 0) {
148
if (!oi->oprom_size) return 0;
149
return oi->oprom_array;
155
int prom_getversion()
161
if (ioctl (fd, OPROMGETVERSION, (void *)oi) >= 0) {
162
p = strchr (oi->oprom_array, '.');
163
if (p && p > oi->oprom_array && p[-1] >= '0' && p[-1] <= '9' &&
164
(p == oi->oprom_array + 1 || p[-2] < '0' || p[-2] > '9')) {
172
printf ("Please report version string '%s' to jj@sunsite.mff.cuni.cz\n", oi->oprom_array);
174
/* Let's try brute force :)) */
176
if (prom_set_root_node () < 0) return -1;
178
if ((p = prom_getstring ("compatability")) != 0)
180
else if ((p = prom_getstring ("compatible")) != 0)
182
if (*arch && (!strcmp (arch, "sun4m") || !strcmp (arch, "sun4d") || !strcmp (arch, "sun4e")))
185
p = prom_getopt ("boot-from");
186
if (p && (!strncmp (p, "sd(", 3) ||
187
!strncmp (p, "le(", 3) ||
188
!strncmp (p, "ie(", 3) ||
189
!strncmp (p, "fd(", 3) ||
190
!strncmp (p, "xd(", 3)))
193
if (prom_getchild () < 0) return -1;
194
if (prom_search_siblings ("aliases") != -1) {
195
p = prom_getstring ("disk");
196
if (!p) p = prom_getstring ("net");
197
if (!p) p = prom_getstring ("disk0");
198
if (p && *p == '/') {
199
if (!strncmp (p + 1, "iommu@", 6) || !strncmp (p + 1, "iommu/", 6) ||
200
!strncmp (p + 1, "sbus@", 5) || !strncmp (p + 1, "sbus/", 5) ||
201
!strncmp (p + 1, "espdma@", 7) || !strncmp (p + 1, "espdma/", 7) ||
202
!strncmp (p + 1, "esp@", 4) || !strncmp (p + 1, "esp/", 4) ||
203
!strncmp (p + 1, "io-unit@", 8) || !strncmp (p + 1, "io-unit/", 8))