summaryrefslogtreecommitdiffstats
path: root/perl-install/c
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/c')
-rw-r--r--perl-install/c/smp.c201
-rw-r--r--perl-install/c/stuff.xs.pl61
2 files changed, 213 insertions, 49 deletions
diff --git a/perl-install/c/smp.c b/perl-install/c/smp.c
index 2438418bb..9cc75978d 100644
--- a/perl-install/c/smp.c
+++ b/perl-install/c/smp.c
@@ -64,30 +64,132 @@ int sparcDetectSMP(void)
}
#endif /* __sparc__ */
-/* just a placeholder for now - don't have an SMP machine
- need something in place to build - s.benedict */
-
#ifdef __powerpc__
+/* minifind.c -- simple find library
+ *
+ * Copyright (c) 2002 Terra Soft Solutions, Inc.
+ * Written by Dan Burcaw <dburcaw@terrasoftsolutions.com>
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * library public license.
+ *
+ * You should have received a copy of the GNU Library Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+struct pathNode
+{
+ char *path;
+ struct pathNode *next;
+};
+
+struct findNode
+{
+ struct pathNode *result;
+ struct pathNode *exclude;
+};
+
+// insert a node at head of linked-list
+static void insert_node(struct pathNode *n, char *path)
+{
+ struct pathNode *new = (struct pathNode *) malloc(sizeof(struct pathNode));
+ new->path = path;
+ new->next = n->next;
+ n->next = new;
+}
+
+// return input strip less last character
+static char *stripLastChar(char *in)
+{
+ char *out = malloc(sizeof(char)*strlen(in));
+ snprintf(out, strlen(in) - 1, "%s", in);
+ return out;
+}
+
+// do the work
+static char *minifind(char *dir, char *search, struct findNode *list)
+{
+ char *d = NULL;
+ int n;
+ struct dirent **namelist;
+ struct stat buf;
+
+ if (dir[strlen(dir)-1] == '/')
+ dir = stripLastChar(dir);
+
+ // check is there is an exact filematch to dir
+ // when search is not specified
+ if (search == NULL)
+ {
+ if (lstat(dir, &buf) == 0)
+ insert_node(list->result, dir);
+ return 0;
+ }
+
+ n = scandir(dir, &namelist, 0, alphasort);
+ if (n >= 0)
+ {
+ while (n--)
+ {
+ d = malloc(sizeof(char) * (strlen(dir) \
+ + strlen(namelist[n]->d_name)+1));
+ sprintf(d, "%s/%s", dir, namelist[n]->d_name);
+ if (strstr(namelist[n]->d_name, search))
+ insert_node(list->result, d);
+
+ if ((lstat(d, &buf) == 0) && S_ISDIR(buf.st_mode))
+ {
+ if (strcmp(namelist[n]->d_name, ".") &&
+ strcmp(namelist[n]->d_name, ".."))
+ d = minifind(d, search, list);
+ }
+ free(namelist[n]);
+ }
+ free(namelist);
+ return d;
+ }
+ return 0;
+}
+
int ppcDetectSMP(void)
{
- int issmp = 0;
+ int issmp = -1;
FILE *f;
-
- f = fopen("/proc/cpuinfo", "r");
- if (f) {
- char buff[1024];
+ struct findNode *list = (struct findNode *) malloc(sizeof(struct findNode));
+ struct pathNode *n;
- while (fgets (buff, 1024, f) != NULL) {
- if (!strncmp (buff, "ncpus active\t: ", 15)) {
- if (strtoul (buff + 15, NULL, 0) > 1)
- issmp = 1;
- break;
+ list->result = (struct pathNode *) malloc(sizeof(struct pathNode));
+ list->result->path = NULL;
+ list->result->next = list->result;
+
+ minifind("/proc/device-tree/cpus", "device_type", list);
+
+ for (n = list->result->next; n != list->result; n = n->next)
+ {
+ f = fopen(n->path, "r");
+ if (f) {
+ char buff[1024];
+ while (fgets (buff, 1024, f) != NULL) {
+ if (!strncmp (buff, "cpu", 3))
+ {
+ issmp++;
+ break;
+ }
+ }
+ fclose(f);
}
}
- fclose(f);
- } else
- return -1;
-
+
return issmp;
}
#endif /* __powerpc__ */
@@ -152,6 +254,11 @@ typedef unsigned int vm_offset_t;
#include <machine/types.h>
#endif
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef vm_offset_t addr_t;
+
/* EBDA is @ 40:0e in real-mode terms */
#define EBDA_POINTER 0x040e /* location of EBDA pointer */
@@ -172,43 +279,43 @@ typedef unsigned int vm_offset_t;
/* MP Floating Pointer Structure */
typedef struct MPFPS {
char signature[ 4 ];
- void* pap;
- u_char length;
- u_char spec_rev;
- u_char checksum;
- u_char mpfb1;
- u_char mpfb2;
- u_char mpfb3;
- u_char mpfb4;
- u_char mpfb5;
+ addr_t pap;
+ u8 length;
+ u8 spec_rev;
+ u8 checksum;
+ u8 mpfb1;
+ u8 mpfb2;
+ u8 mpfb3;
+ u8 mpfb4;
+ u8 mpfb5;
} mpfps_t;
/* MP Configuration Table Header */
typedef struct MPCTH {
char signature[ 4 ];
- u_short base_table_length;
- u_char spec_rev;
- u_char checksum;
- u_char oem_id[ 8 ];
- u_char product_id[ 12 ];
- void* oem_table_pointer;
- u_short oem_table_size;
- u_short entry_count;
- void* apic_address;
- u_short extended_table_length;
- u_char extended_table_checksum;
- u_char reserved;
+ u16 base_table_length;
+ u8 spec_rev;
+ u8 checksum;
+ u8 oem_id[ 8 ];
+ u8 product_id[ 12 ];
+ addr_t oem_table_pointer;
+ u16 oem_table_size;
+ u16 entry_count;
+ addr_t apic_address;
+ u16 extended_table_length;
+ u8 extended_table_checksum;
+ u8 reserved;
} mpcth_t;
typedef struct PROCENTRY {
- u_char type;
- u_char apicID;
- u_char apicVersion;
- u_char cpuFlags;
- u_long cpuSignature;
- u_long featureFlags;
- u_long reserved1;
- u_long reserved2;
+ u8 type;
+ u8 apicID;
+ u8 apicVersion;
+ u8 cpuFlags;
+ u32 cpuSignature;
+ u32 featureFlags;
+ u32 reserved1;
+ u32 reserved2;
} ProcEntry;
#define PROCENTRY_FLAG_EN 0x01
@@ -274,7 +381,7 @@ static int intelDetectSMP_mptable(void)
mpcth_t cth;
int count, i;
- paddr = (vm_offset_t) mpfps.pap;
+ paddr = mpfps.pap;
seekEntry( paddr );
readEntry( &cth, sizeof( cth ) );
/* if we don't have any entries, the kernel sure
diff --git a/perl-install/c/stuff.xs.pl b/perl-install/c/stuff.xs.pl
index 26e6ce413..07249d66b 100644
--- a/perl-install/c/stuff.xs.pl
+++ b/perl-install/c/stuff.xs.pl
@@ -23,6 +23,8 @@ print '
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/mount.h>
+#undef __USE_MISC
+#include <linux/wireless.h>
#include <linux/keyboard.h>
#include <linux/kd.h>
#include <linux/hdreg.h>
@@ -398,13 +400,68 @@ hasNetDevice(device)
int s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1) { RETVAL = 0; return; }
- strcpy(req.ifr_name, device);
+ strncpy(req.ifr_name, device, IFNAMSIZ);
RETVAL = ioctl(s, SIOCGIFFLAGS, &req) == 0;
close(s);
OUTPUT:
RETVAL
+
+int
+isNetDeviceWirelessAware(device)
+ char * device
+ CODE:
+ struct iwreq ifr;
+
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, device, IFNAMSIZ);
+ RETVAL = ioctl(s, SIOCGIWNAME, &ifr) != -1;
+ close(s);
+ OUTPUT:
+ RETVAL
+
+
+void
+get_netdevices()
+ PPCODE:
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ int i;
+ int numreqs = 10;
+
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+
+ ifc.ifc_buf = NULL;
+ for (;;) {
+ ifc.ifc_len = sizeof(struct ifreq) * numreqs;
+ ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
+
+ if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
+ perror("SIOCGIFCONF");
+ return;
+ }
+ if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
+ /* assume it overflowed and try again */
+ numreqs += 10;
+ continue;
+ }
+ break;
+ }
+ if (ifc.ifc_len) {
+ ifr = ifc.ifc_req;
+ EXTEND(sp, ifc.ifc_len);
+ for (i=0; i < ifc.ifc_len; i+= sizeof(struct ifreq)) {
+ PUSHs(sv_2mortal(newSVpv(ifr->ifr_name, 0)));
+ ifr++;
+ }
+ }
+
+ close(s);
+
+
char*
getNetDriver(char* device)
ALIAS:
@@ -415,7 +472,7 @@ getNetDriver(char* device)
int s = socket(AF_INET, SOCK_DGRAM, 0);
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)-1);
+ strncpy(ifr.ifr_name, device, IFNAMSIZ);
drvinfo.cmd = ETHTOOL_GDRVINFO;
ifr.ifr_data = (caddr_t) &drvinfo;