diff options
author | Francois Pons <fpons@mandriva.com> | 2000-06-23 13:45:16 +0000 |
---|---|---|
committer | Francois Pons <fpons@mandriva.com> | 2000-06-23 13:45:16 +0000 |
commit | 13c1505ba44c0d57a4d5bdb6ce62267a34f9b510 (patch) | |
tree | 2740d85139f57bb07ba00a16316cc63a9b1b6bfc | |
parent | c8d8767aa3dfeb049fd662080ac8cf2a7075ca56 (diff) | |
download | drakx-13c1505ba44c0d57a4d5bdb6ce62267a34f9b510.tar drakx-13c1505ba44c0d57a4d5bdb6ce62267a34f9b510.tar.gz drakx-13c1505ba44c0d57a4d5bdb6ce62267a34f9b510.tar.bz2 drakx-13c1505ba44c0d57a4d5bdb6ce62267a34f9b510.tar.xz drakx-13c1505ba44c0d57a4d5bdb6ce62267a34f9b510.zip |
*** empty log message ***
-rw-r--r-- | perl-install/c/silo.c | 817 |
1 files changed, 817 insertions, 0 deletions
diff --git a/perl-install/c/silo.c b/perl-install/c/silo.c new file mode 100644 index 000000000..2fd621f4e --- /dev/null +++ b/perl-install/c/silo.c @@ -0,0 +1,817 @@ +/* silo.c: Conversions between SCSI and IDE disk names + * and OpenPROM fully qualified paths. + * + * Modified for DrakX light integration. + * Copyright (C) 1999, 2000 Jakub Jelinek <jakub@redhat.com> + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef __sparc__ + +#define _GNU_SOURCE +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <asm/openpromio.h> +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/utsname.h> + +#ifndef OPROMSETCUR +#define OPROMSETCUR 0x20004FF0 +#define OPROMPCI2NODE 0x20004FF1 +#define OPROMPATH2NODE 0x20004FF2 +#endif + +static int hasaliases; +static char *promdev = "/dev/openprom"; +static int promfd; +static char sd_targets[10] = "31204567"; +static int p1275 = 0; +static int prom_root_node, prom_current_node; +static int promvers; +static void (*prom_walk_callback)(int node); +static char prom_path[1024]; +#define MAX_PROP 128 +#define MAX_VAL (4096-128-4) +static char buf[4096]; +static char regstr[40]; +#define DECL_OP(size) struct openpromio *op = (struct openpromio *)buf; op->oprom_size = (size) + +static int +prom_setcur(int node) { + DECL_OP(sizeof(int)); + + if (node == -1) return 0; + *(int *)op->oprom_array = node; + if (ioctl (promfd, OPROMSETCUR, op) < 0) + return 0; + prom_current_node = *(int *)op->oprom_array; + return *(int *)op->oprom_array; +} + +static int +prom_getsibling(int node) { + DECL_OP(sizeof(int)); + + if (node == -1) return 0; + *(int *)op->oprom_array = node; + if (ioctl (promfd, OPROMNEXT, op) < 0) + return 0; + prom_current_node = *(int *)op->oprom_array; + return *(int *)op->oprom_array; +} + +static int +prom_getchild(int node) { + DECL_OP(sizeof(int)); + + if (!node || node == -1) return 0; + *(int *)op->oprom_array = node; + if (ioctl (promfd, OPROMCHILD, op) < 0) + return 0; + prom_current_node = *(int *)op->oprom_array; + return *(int *)op->oprom_array; +} + +static char * +prom_getproperty(char *prop, int *lenp) { + DECL_OP(MAX_VAL); + + strcpy (op->oprom_array, prop); + if (ioctl (promfd, OPROMGETPROP, op) < 0) + return 0; + if (lenp) *lenp = op->oprom_size; + return op->oprom_array; +} + +static char * +prom_getopt(char *var, int *lenp) { + DECL_OP(MAX_VAL); + + strcpy (op->oprom_array, var); + if (ioctl (promfd, OPROMGETOPT, op) < 0) + return 0; + if (lenp) *lenp = op->oprom_size; + return op->oprom_array; +} + +static void +prom_setopt(char *var, char *value) { + DECL_OP(MAX_VAL); + + strcpy (op->oprom_array, var); + strcpy (op->oprom_array + strlen (var) + 1, value); + ioctl (promfd, OPROMSETOPT, op); +} + +static int +prom_getbool(char *prop) { + DECL_OP(0); + + *(int *)op->oprom_array = 0; + for (;;) { + op->oprom_size = MAX_PROP; + if (ioctl(promfd, OPROMNXTPROP, op) < 0) + return 0; + if (!op->oprom_size) + return 0; + if (!strcmp (op->oprom_array, prop)) + return 1; + } +} + +static int +prom_pci2node(int bus, int devfn) { + DECL_OP(2*sizeof(int)); + + ((int *)op->oprom_array)[0] = bus; + ((int *)op->oprom_array)[1] = devfn; + if (ioctl (promfd, OPROMPCI2NODE, op) < 0) + return 0; + prom_current_node = *(int *)op->oprom_array; + return *(int *)op->oprom_array; +} + +static int +prom_path2node(char *path) { + DECL_OP(MAX_VAL); + + strcpy (op->oprom_array, path); + if (ioctl (promfd, OPROMPATH2NODE, op) < 0) + return 0; + prom_current_node = *(int *)op->oprom_array; + return *(int *)op->oprom_array; +} + +#define PW_TYPE_SBUS 1 +#define PW_TYPE_PCI 2 +#define PW_TYPE_EBUS 3 + +static void +prom_walk(char *path, int parent, int node, int type) { + int nextnode; + int len, ntype = type; + char *prop; + + prop = prom_getproperty("name", &len); + if (prop && len > 0) { + if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type) + ntype = PW_TYPE_SBUS; + else if (!strcmp(prop, "ebus") && type == PW_TYPE_PCI) + ntype = PW_TYPE_EBUS; + else if (!strcmp(prop, "pci") && !type) + ntype = PW_TYPE_PCI; + } + *path = '/'; + strcpy (path + 1, prop); + prop = prom_getproperty("reg", &len); + if (prop && len >= 4) { + unsigned int *reg = (unsigned int *)prop; + int cnt = 0; + if (!p1275 || (type == PW_TYPE_SBUS)) + sprintf (regstr, "@%x,%x", reg[0], reg[1]); + else if (type == PW_TYPE_PCI) { + if ((reg[0] >> 8) & 7) + sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7); + else + sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f); + } else if (len == 4) + sprintf (regstr, "@%x", reg[0]); + else { + unsigned int regs[2]; + + /* Things get more complicated on UPA. If upa-portid exists, + then address is @upa-portid,second-int-in-reg, otherwise + it is @first-int-in-reg/16,second-int-in-reg (well, probably + upa-portid always exists, but just to be safe). */ + memcpy (regs, reg, sizeof(regs)); + prop = prom_getproperty("upa-portid", &len); + if (prop && len == 4) { + reg = (unsigned int *)prop; + sprintf (regstr, "@%x,%x", reg[0], regs[1]); + } else + sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]); + } + for (nextnode = prom_getchild(parent); nextnode; nextnode = prom_getsibling(nextnode)) { + prop = prom_getproperty("name", &len); + if (prop && len > 0 && !strcmp (path + 1, prop)) + cnt++; + } + if (cnt > 1) + strcat (path, regstr); + } + + prom_walk_callback(node); + + nextnode = prom_getchild(node); + if (nextnode) + prom_walk(strchr (path, 0), node, nextnode, ntype); + nextnode = prom_getsibling(node); + if (nextnode) + prom_walk(path, parent, nextnode, type); +} + +static int +prom_init(int mode) { + struct utsname u; + + promfd = open(promdev, mode); + if (promfd == -1) + return -1; + prom_root_node = prom_getsibling(0); + if (!prom_root_node) + return -1; + + if (!uname (&u) && !strcmp (u.machine, "sparc64")) + p1275 = 1; + return 0; +} + +#define SDSK_TYPE_IDE 1 +#define SDSK_TYPE_SD 2 +#define SDSK_TYPE_PLN 3 +#define SDSK_TYPE_FC 4 + +static struct sdsk_disk { + unsigned int prom_node; + unsigned int type, host, hi, mid, lo; + unsigned char *prom_name; +} *hd = NULL, *sd = NULL; +static int hdlen, sdlen; + +static void +scan_walk_callback(int node) { + int nextnode; + char *prop; + int len, disk; + static int v0ctrl = 0; + + for (disk = 0; disk < hdlen + sdlen; disk++) { + if (hd[disk].prom_node == node) { + switch (hd[disk].type) { + case SDSK_TYPE_IDE: + for (nextnode = prom_getchild(node); nextnode; nextnode = prom_getsibling(nextnode)) { + prop = prom_getproperty("name", &len); + if (prop && len > 0 && (!strcmp (prop, "ata") || !strcmp (prop, "disk"))) + break; + } + if (!nextnode) + continue; + if (prop[0] == 'a') + sprintf (prop, "/ata@%x,0/cmdk@%x,0", hd[disk].hi, hd[disk].lo); + else + sprintf (prop, "/disk@%x,0", hd[disk].hi * 2 + hd[disk].lo); + break; + case SDSK_TYPE_SD: + for (nextnode = prom_getchild(node); nextnode; nextnode = prom_getsibling(nextnode)) { + prop = prom_getproperty("compatible", &len); + if (prop && len > 0 && !strcmp (prop, "sd")) + break; + prop = prom_getproperty("name", &len); + if (prop && len > 0 && (!strcmp (prop, "sd") || !strcmp (prop, "disk"))) + break; + } + if (!nextnode || hd[disk].hi) + continue; + if (promvers) { + char name[1024]; + prop = prom_getproperty("name", &len); + if (prop && len > 0) + strcpy (name, prop); + else + strcpy (name, "sd"); + if (!prop) + prop = ((struct openpromio *)buf)->oprom_array; + sprintf (prop, "/%s@%x,%x", name, hd[disk].mid, hd[disk].lo); + } else { + int i; + for (i = 0; sd_targets[i]; i++) + if (sd_targets[i] == '0' + hd[disk].mid) + break; + if (!sd_targets[i]) + i = hd[disk].mid; + sprintf (prop, "sd(%d,%d,", v0ctrl, i); + } + break; + case SDSK_TYPE_PLN: + prop = ((struct openpromio *)buf)->oprom_array; + sprintf (prop, "/SUNW,pln@%x,%x/SUNW,ssd@%x,%x", + hd[disk].lo & 0xf0000000, hd[disk].lo & 0xffffff, + hd[disk].hi, hd[disk].mid); + break; + case SDSK_TYPE_FC: + prop = ((struct openpromio *)buf)->oprom_array; + sprintf (prop, "/sf@0,0/ssd@w%08x%08x,%x", hd[disk].hi, hd[disk].mid, hd[disk].lo); + break; + default: + continue; + } + hd[disk].prom_name = malloc (strlen (prom_path) + strlen(prop) + 3); + if (!hd[disk].prom_name) + continue; + if (promvers) + strcpy (hd[disk].prom_name, prom_path); + else + hd[disk].prom_name[0] = '\0'; + strcat (hd[disk].prom_name, prop); + } + } + v0ctrl++; +} + +static int +scan_ide(void) { + DIR * dir; + char path[80]; + char buffer[512]; + int fd, i, disk; + struct dirent * ent; + int pci_bus, pci_devfn; + + if (access("/proc/ide", R_OK)) return 0; + + if (!(dir = opendir("/proc/ide"))) { + return 1; + } + + while ((ent = readdir(dir))) { + if (ent->d_name[0] == 'h' && ent->d_name[1] == 'd' && + ent->d_name[2] >= 'a' && ent->d_name[2] <= 'z' && + ent->d_name[3] == '\0') { + disk = ent->d_name[2] - 'a'; + if (disk >= hdlen) { + hd = (struct sdsk_disk *)realloc(hd, ((disk&~3)+4)*sizeof(struct sdsk_disk)); + memset (hd + hdlen, 0, ((disk&~3)+4-hdlen)*sizeof(struct sdsk_disk)); + hdlen = (disk&~3)+4; + } + for (i = (disk & ~3); i <= (disk | 3); i++) { + if (hd[i].type) + break; + } + if (i > (disk | 3)) { + sprintf(path, "/proc/ide/%s", ent->d_name); + if (readlink(path, buffer, 512) < 5) + continue; + if (strncmp(buffer, "ide", 3) || + !isdigit(buffer[3]) || + buffer[4] != '/') + continue; + buffer[4] = 0; + sprintf(path, "/proc/ide/%s/config", buffer); + if ((fd = open(path, O_RDONLY)) < 0) + continue; + i = read(fd, buffer, 50); + close(fd); + if (i < 50) continue; + if (sscanf (buffer, "pci bus %x device %x ", + &pci_bus, &pci_devfn) != 2) + continue; + hd[disk].prom_node = prom_pci2node (pci_bus, pci_devfn); + } else + hd[disk].prom_node = hd[i].prom_node; + hd[disk].type = SDSK_TYPE_IDE; + hd[disk].hi = (disk & 2) >> 1; + hd[disk].lo = (disk & 1); + } + } + + closedir(dir); + + return 0; +} + +static int +scan_scsi(void) { + FILE *f; + DIR * dir, *dirhba; + struct dirent * ent, *enthba; + struct stat st; + char * p, * q; + char buf[512]; + char path[128]; + int disk = 0; + int host, channel, id, lun; + int prom_node, pci_bus, pci_devfn; + + if (access("/proc/scsi/scsi", R_OK)) { + return 0; + } + + f = fopen("/proc/scsi/scsi", "r"); + if (f == NULL) return 1; + + if (fgets(buf, sizeof(buf), f) == NULL) { + fclose(f); + return 1; + } + if (!strcmp(buf, "Attached devices: none\n")) { + fclose(f); + return 0; + } + + while (fgets(buf, sizeof(buf), f) != NULL) { + if (sscanf(buf, "Host: scsi%d Channel: %d Id: %d Lun: %d\n", + &host, &channel, &id, &lun) != 4) + break; + if (fgets(buf, sizeof(buf), f) == NULL) + break; + if (strncmp(buf, " Vendor:", 9)) + break; + if (fgets(buf, sizeof(buf), f) == NULL) + break; + if (strncmp(buf, " Type: ", 10)) + break; + if (!strncmp(buf+10, "Direct-Access", 13)) { + if (disk >= sdlen) { + hd = (struct sdsk_disk *) + realloc(hd, (hdlen+(disk&~3)+4)*sizeof(struct sdsk_disk)); + sd = hd + hdlen; + memset (sd + sdlen, 0, + ((disk&~3)+4-sdlen)*sizeof(struct sdsk_disk)); + sdlen = (disk&~3)+4; + } + sd[disk].type = SDSK_TYPE_SD; + sd[disk].host = host; + sd[disk].hi = channel; + sd[disk].mid = id; + sd[disk].lo = lun; + disk++; + } + } + fclose (f); + + if (!(dir = opendir("/proc/scsi"))) { + if (!hdlen && hd) { + free(hd); + hd = NULL; + } + sd = NULL; + sdlen = 0; + return 1; + } + + while ((ent = readdir(dir))) { + if (!strcmp (ent->d_name, "scsi") || ent->d_name[0] == '.') + continue; + sprintf (path, "/proc/scsi/%s", ent->d_name); + if (stat (path, &st) < 0 || !S_ISDIR (st.st_mode)) + continue; + if (!(dirhba = opendir(path))) + continue; + + while ((enthba = readdir(dirhba))) { + if (enthba->d_name[0] == '.') + continue; + host = atoi(enthba->d_name); + sprintf (path, "/proc/scsi/%s/%s", ent->d_name, enthba->d_name); + f = fopen (path, "r"); + if (f == NULL) continue; + + if (!strcmp (ent->d_name, "esp") || + !strcmp (ent->d_name, "qlogicpti") || + !strcmp (ent->d_name, "fcal")) + p = "PROM node"; + else if (!strcmp (ent->d_name, "pluto")) + p = "serial "; + else + p = "PCI bus"; + while (fgets (buf, sizeof(buf), f) != NULL) { + q = strstr (buf, p); + if (q == NULL) continue; + prom_node = 0; + switch (p[1]) { + case 'R': + if (sscanf (q, "PROM node %x", &prom_node) == 1) + q = NULL; + break; + case 'e': + if (sscanf (q, "serial 000000%x %*dx%*d on soc%*d port %x PROM node %x", + &id, &lun, &prom_node) == 3 && + lun >= 10 && lun <= 11) { + q = NULL; + } + break; + case 'C': + if (sscanf (q, "PCI bus %x device %x", &pci_bus, &pci_devfn) == 2) { + q = NULL; + prom_node = prom_pci2node (pci_bus, pci_devfn); + } + break; + } + if (q == NULL) { + for (disk = 0; disk < sdlen; disk++) + if (sd[disk].host == host && sd[disk].type) { + sd[disk].prom_node = prom_node; + if (p[1] == 'e') { + sd[disk].type = SDSK_TYPE_PLN; + sd[disk].lo = (lun << 28) | id; + } else if (!strcmp (ent->d_name, "fcal")) + sd[disk].type = SDSK_TYPE_FC; + } + } + } + if (!strcmp (ent->d_name, "fcal")) { + while (fgets (buf, sizeof(buf), f) != NULL) { + unsigned long long ll; + if (sscanf (buf, " [AL-PA: %*x, Id: %d, Port WWN: %Lx, Node WWN: ", &id, &ll) == 2) { + for (disk = 0; disk < sdlen; disk++) + if (sd[disk].host == host && sd[disk].mid == id) { + sd[disk].hi = ll >> 32; + sd[disk].mid = ll; + } + } + } + } + fclose(f); + } + closedir(dirhba); + } + closedir(dir); + return 0; +} + +static int get_prom_ver(void) +{ + FILE *f = fopen ("/proc/cpuinfo","r"); + int ver = 0; + char buffer[1024]; + char *p; + + if (f) { + while (fgets (buffer, 1024, f)) { + if (!strncmp (buffer, "promlib", 7)) { + p = strstr (buffer, "Version "); + if (p) { + p += 8; + if (*p == '0' || (*p >= '2' && *p <= '3')) { + ver = *p - '0'; + } + } + break; + } + } + fclose(f); + } + if (!ver) { + int len; + p = prom_getopt("sd-targets", &len); + if (p && len > 0 && len <= 8) + strcpy(sd_targets, p); + } + return ver; +} + +static void check_aliases(void) { + int nextnode, len; + char *prop; + hasaliases = 0; + for (nextnode = prom_getchild(prom_root_node); nextnode; nextnode = prom_getsibling(nextnode)) { + prop = prom_getproperty("name", &len); + if (prop && len > 0 && !strcmp (prop, "aliases")) + hasaliases = 1; + } +} + +char *prom_root_name = NULL; + +static void get_root_name(void) { + int len; + char *prop; + + prom_getsibling(0); + prop = prom_getproperty("name", &len); + if (prop && len > 0) + prom_root_name = strdup(prop); +} + +int init_sbusdisk(void) { + if (prom_init(O_RDONLY)) + return -1; + promvers = get_prom_ver(); + check_aliases(); + get_root_name(); + scan_ide(); + scan_scsi(); + prom_walk_callback = scan_walk_callback; + prom_walk(prom_path, prom_root_node, prom_getchild (prom_root_node), 0); + close(promfd); + return 0; +} + +void set_prom_vars(char *linuxAlias, char *bootDevice) { + int len; + int aliasDone = 0; + if (prom_init(O_RDWR)) + return; + if (linuxAlias && hasaliases) { + char *use_nvramrc; + char nvramrc[2048]; + char *p, *q, *r, *s; + int enabled = -1; + int count; + + use_nvramrc = prom_getopt ("use-nvramrc?", &len); + if (len > 0) { + if (!strcasecmp (use_nvramrc, "false")) + enabled = 0; + else if (!strcasecmp (use_nvramrc, "true")) + enabled = 1; + } + if (enabled != -1) { + p = prom_getopt ("nvramrc", &len); + if (p) { + memcpy (nvramrc, p, len); + nvramrc [len] = 0; + q = nvramrc; + for (;;) { + /* If there is already `devalias linux /some/ugly/prom/path' + make sure we fully understand that and remove it. */ + if (!strncmp (q, "devalias", 8) && (q[8] == ' ' || q[8] == '\t')) { + for (r = q + 9; *r == ' ' || *r == '\t'; r++); + if (!strncmp (r, "linux", 5)) { + for (s = r + 5; *s && *s != ' ' && *s != '\t'; s++); + if (!*s) break; + if (s == r + 5 || + (r[5] == '#' && r[6] >= '0' && r[6] <= '9' && + (s == r + 7 || + (r[7] >= '0' && r[7] <= '9' && s == r + 8)))) { + for (r = s + 1; *r == ' ' || *r == '\t'; r++); + for (; *r && *r != ' ' && *r != '\t' && *r != '\n'; r++); + for (; *r == ' ' || *r == '\t'; r++); + if (*r == '\n') { + r++; + memmove (q, r, strlen(r) + 1); + continue; + } + } + } + } + q = strchr (q, '\n'); + if (!q) break; + q++; + } + len = strlen (nvramrc); + if (len && nvramrc [len-1] != '\n') + nvramrc [len++] = '\n'; + p = nvramrc + len; + p = stpcpy (p, "devalias linux "); + r = linuxAlias; + q = strchr (r, ';'); + count = 1; + while (q) { + memcpy (p, r, q - r); + p += q - r; + sprintf (p, "\ndevalias linux#%d ", count++); + p = strchr (p, 0); + r = q + 1; + q = strchr (r, ';'); + } + p = stpcpy (p, r); + *p++ = '\n'; + *p = 0; + prom_setopt ("nvramrc", nvramrc); + if (!enabled) + prom_setopt ("use-nvramrc?", "true"); + aliasDone = 1; + } + } + } + if (bootDevice) { + char *p; + if (aliasDone) + bootDevice = "linux"; + p = prom_getopt ("boot-device", &len); + if (p) { + prom_setopt ("boot-device", bootDevice); + prom_setopt ("boot-file", ""); + } else { + p = prom_getopt ("boot-from", &len); + if (p) + prom_setopt ("boot-from", bootDevice); + } + } + close(promfd); +} + +#ifdef STANDALONE_SILO + +int main(void) { + int i; + + init_sbusdisk(); + set_prom_vars ("/sbus@1f,0/espdma/esp/sd@1,0:c;/sbus@1f,0/espdma/esp/sd@1,0:g;/sbus@1f,0/espdma/esp/sd@1,0:h", "linux"); + printf ("prom root name `%s'\n", prom_root_name); + for (i = 0; i < hdlen; i++) { + if (hd[i].type) + printf ("hd%c %x %d %d %d\n", i + 'a', hd[i].prom_node, + hd[i].hi, hd[i].mid, hd[i].lo); + if (hd[i].prom_name) printf ("%s\n", hd[i].prom_name); + } + for (i = 0; i < sdlen; i++) { + if (sd[i].type) { + if (i < 26) + printf ("sd%c %x %d %d %d\n", i + 'a', sd[i].prom_node, + sd[i].hi, sd[i].mid, sd[i].lo); + else + printf ("sd%c%c %x %d %d %d\n", (i / 26) + 'a' - 1, (i % 26) + 'a', sd[i].prom_node, + sd[i].hi, sd[i].mid, sd[i].lo); + } + if (sd[i].prom_name) printf ("%s\n", sd[i].prom_name); + } + exit(0); +} + +#else + +void +initSilo () +{ + return init_sbusdisk(); +} + +char * +disk2PromPath (unsigned char *disk) +{ + static unsigned char prompath[1024]; + int diskno = -1, part; + + if (disk[0] == 'h' && disk[1] == 'd' && disk[2] >= 'a' && disk[2] <= 'z') { + diskno = disk[2] - 'a'; + disk += 3; + } else if (disk[0] == 's' && disk[1] == 'd' && disk[2] >= 'a' && disk[2] <= 'z') { + if (disk[3] >= 'a' && disk[3] <= 'z') { + diskno = (disk[2] - 'a' + 1) * 26 + (disk[3] - 'a'); + disk += 4; + } else { + diskno = disk[2] - 'a'; + disk += 3; + } + if (diskno >= 128) + diskno = -1; + else + diskno += hdlen; + } + if (diskno == -1) + part = -1; + else if (!disk[0]) + part = 3; + else { + part = atoi (disk); + if (part <= 0 || part > 8) part = -1; + } + if (diskno < 0 || part == -1 || + diskno >= hdlen + sdlen || !hd[diskno].prom_name) { + return NULL; + } + if (!promvers) + sprintf (prompath, "%s%d)", hd[diskno].prom_name, part ? part - 1 : 2); + else { + if (part) + sprintf (prompath, "%s:%c", hd[diskno].prom_name, part + 'a' - 1); + else + strcpy (prompath, hd[diskno].prom_name); + } + return prompath; +} + +int +hasAliases (void) +{ + return hasaliases; +} + +char * +promRootName (void) +{ + return prom_root_name ? prom_root_name : ""; +} + +void +setPromVars (char *linuxAlias, char *bootDevice) +{ + if (linuxAlias && !*linuxAlias) linuxAlias = NULL; + if (bootDevice && !*bootDevice) bootDevice = NULL; + set_prom_vars (linuxAlias, bootDevice); +} + +#endif + +#else +void initSilo() {} +char *disk2PromPath(unsigned char *disk) { return 0; /* NULL */ } +int hasAliases(void) { return 0; } +char *promRootName(void) { return 0; /* NULL */ } +void setPromVars(char *linuxAlias, char *bootDevice) {} +#endif /* __sparc__ */ |