diff options
Diffstat (limited to 'perl-install/c')
-rw-r--r-- | perl-install/c/Makefile.PL | 2 | ||||
-rw-r--r-- | perl-install/c/sbus.c | 123 | ||||
-rw-r--r-- | perl-install/c/stuff.xs.pm | 45 |
3 files changed, 169 insertions, 1 deletions
diff --git a/perl-install/c/Makefile.PL b/perl-install/c/Makefile.PL index 4e76dea67..e406f1fe4 100644 --- a/perl-install/c/Makefile.PL +++ b/perl-install/c/Makefile.PL @@ -10,7 +10,7 @@ WriteMakefile( 'NAME' => 'stuff', 'OPTIMIZE' => '-Os', 'MAKEFILE' => 'Makefile_c', - 'OBJECT' => 'stuff.o smp.o md5.o md5_crypt.o', + 'OBJECT' => 'stuff.o smp.o md5.o md5_crypt.o sbus.o', 'VERSION_FROM' => 'stuff.pm', # finds $VERSION 'LIBS' => [$libs], # e.g., '-lm' 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' diff --git a/perl-install/c/sbus.c b/perl-install/c/sbus.c new file mode 100644 index 000000000..1fed1f886 --- /dev/null +++ b/perl-install/c/sbus.c @@ -0,0 +1,123 @@ +/* This file is inspired from source code of kudzu from Red Hat, Inc. + * It has been modified to keep only "what is needed" in C, the prom_walk + * has been rewritten in perl for convenience :-) + * + * Copyright notice from original version. + * sbus.c: Probe for Sun SBUS and UPA framebuffers using OpenPROM, + * SBUS SCSI and Ethernet cards and SBUS or EBUS audio chips. + * + * Copyright (C) 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz) + * (C) 1999 Red Hat, Inc. + * + * 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__ + +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <asm/openpromio.h> + +static char *promdev = "/dev/openprom"; +static int promfd = -1; +static int prom_current_node; +#define MAX_PROP 128 +#define MAX_VAL (4096-128-4) +static char buf[4096]; +#define DECL_OP(size) struct openpromio *op = (struct openpromio *)buf; op->oprom_size = (size) + +int prom_open() +{ + int prom_root_node; + + if (promfd == -1) { + promfd = open(promdev, O_RDONLY); + if (promfd == -1) + return 0; + } + prom_root_node = prom_getsibling(0); + if (!prom_root_node) { + close(promfd); + promfd = -1; + return 0; + } + return prom_root_node; +} + +void prom_close() +{ + if (promfd != -1) { + close(promfd); + promfd = -1; + } +} + +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; +} + +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; +} + +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; +} + +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; + } +} + +#else +int prom_open() { return 0; } +void prom_close() {} +int prom_getsibling(int node) { return 0; } +int prom_getchild(int node) { return 0; } +char *prom_getproperty(char *prop, int *lenp) { return NULL; } +int prom_getbool(char *prop) { return 0; } +#endif /* __sparc__ */ diff --git a/perl-install/c/stuff.xs.pm b/perl-install/c/stuff.xs.pm index 77c779c83..034996d21 100644 --- a/perl-install/c/stuff.xs.pm +++ b/perl-install/c/stuff.xs.pm @@ -311,6 +311,51 @@ del_loop(device) OUTPUT: RETVAL +int +prom_open() + +void +prom_close() + +int +prom_getsibling(node) + int node + +int +prom_getchild(node) + int node + +void +prom_getproperty(key) + char *key + PPCODE: + int lenp = 0; + char *value = NULL; + value = prom_getproperty(key, &lenp); + EXTEND(sp, 1); + if (value != NULL) { + PUSHs(sv_2mortal(newSVpv(value, 0))); + } else { + PUSHs(&PL_sv_undef); + } + +int +prom_getbool(key) + char *key + +void +prom_getint(key) + char *key + PPCODE: + int lenp = 0; + char *value = NULL; + value = prom_getproperty(key, &lenp); + EXTEND(sp, 1); + if (value != NULL && lenp == sizeof(int)) { + PUSHs(sv_2mortal(newSViv(*(int *)value))); + } else { + PUSHs(&PL_sv_undef); + } '; $ENV{C_RPM} and print ' |