summaryrefslogtreecommitdiffstats
path: root/perl-install/c
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/c')
-rw-r--r--perl-install/c/Makefile.PL2
-rw-r--r--perl-install/c/sbus.c123
-rw-r--r--perl-install/c/stuff.xs.pm45
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 '