diff options
author | Jeremy Katz <katzj@redhat.com> | 2003-02-21 00:20:40 +0000 |
---|---|---|
committer | Jeremy Katz <katzj@redhat.com> | 2003-02-21 00:20:40 +0000 |
commit | 44d46f319dd770a135af9aee9fc6775749f0deaa (patch) | |
tree | 389b8870f5036c25e26542c183058ca1b56b5c49 /loader2 | |
parent | a010e915a4fe505b36e63392ddcacbfe7c0db4cd (diff) | |
download | anaconda-44d46f319dd770a135af9aee9fc6775749f0deaa.tar.gz anaconda-44d46f319dd770a135af9aee9fc6775749f0deaa.tar.xz anaconda-44d46f319dd770a135af9aee9fc6775749f0deaa.zip |
silly test program for pcmcia stuff that's basically ripped straight out
of pcmcia.c with some code wrapped around it for things like loading modules.
would be even better to get to where I can just compile pcmcia.c and get this
but I don't want to lose this before I get around to doing that
Diffstat (limited to 'loader2')
-rw-r--r-- | loader2/pcmciatest.c | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/loader2/pcmciatest.c b/loader2/pcmciatest.c new file mode 100644 index 000000000..cd0389914 --- /dev/null +++ b/loader2/pcmciatest.c @@ -0,0 +1,333 @@ +#include <errno.h> +#include <fcntl.h> +#include <kudzu/kudzu.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <unistd.h> + +#define LOADER_OK 0 +#define LOADER_BACK 1 +#define LOADER_ERROR -1 + +void logMessage(const char * s, ...) { + va_list args; + + va_start(args, s); + + fprintf(stdout, "* "); + vfprintf(stdout, s, args); + fprintf(stdout, "\n"); + fflush(stdout); + + va_end(args); + return; +} + +char * sdupprintf(const char *format, ...) { + char *buf = NULL; + char c; + va_list ap1, ap2; + size_t size = 0; + + va_start(ap1, format); + va_copy(ap2, ap1); + + /* XXX requires C99 vsnprintf behavior */ + size = vsnprintf(&c, 1, format, ap1) + 1; + if (size == -1) { + printf("ERROR: vsnprintf behavior is not C99\n"); + abort(); + } + + va_end(ap1); + + buf = malloc(size); + if (buf == NULL) + return NULL; + vsnprintf(buf, size, format, ap2); + va_end (ap2); + + return buf; +} + + + +void mlLoadModuleSet(char * origModNames) { + char * start, * next, * end; + char ** initialList; + int child, i, status; + + start = alloca(strlen(origModNames) + 1); + + printf("mods are %s", origModNames); + next = start; + i = 1; + while (*next) { + if (*next == ':') i++; + next++; + } + initialList = alloca(sizeof(*initialList) * (i + 1)); + + i = 0; + while (start) { + next = end = strchr(start, ':'); + if (next) { + *end = '\0'; + next++; + } + + initialList[i++] = start; + start = next; + } + + initialList[i] = NULL; + for (i = 0; initialList[i]; i++) { + logMessage("inserting %s", initialList[i]); + /* if (child = fork()) { + execl("/sbin/modprobe", "/sbin/modprobe", initialList[i], NULL); + exit(0); + } + + waitpid(child, &status, 0);*/ + logMessage("inserted %s", initialList[i]); + } +} + + +char * getPcicController() { + struct device ** devices; + static int probed = 0; + static char * pcic = NULL; + + if (!probed) { + probed = 1; + + devices = probeDevices(CLASS_SOCKET, BUS_PCI, PROBE_ALL); + if (devices) { + logMessage("found cardbus pci adapter"); + pcic = "yenta_socket"; + } else { + devices = probeDevices(CLASS_SOCKET, BUS_MISC, PROBE_ALL); + if (devices && strcmp (devices[0]->driver, "ignore") && + strcmp(devices[0]->driver, "unknown") && + strcmp(devices[0]->driver, "disabled")) { + logMessage("found pcmcia adapter"); + pcic = strdup(devices[0]->driver); + } + } + + if (!pcic) { + logMessage("no pcic controller found"); + } + return pcic; + } else { + return pcic; + } +} + +int initializePcmciaController() { + char * pcic = NULL; + char * mods; + int i; + + pcic = getPcicController(); + if (!pcic) + return 0; + + mods = sdupprintf("pcmcia_core:%s:ds", pcic); + mlLoadModuleSet(mods); + + return 0; +} + + + +/* code from notting to activate pcmcia devices. all kinds of wackiness */ +static int pcmcia_major = 0; + +static int lookup_dev(char *name) { + FILE *f; + int n; + char s[32], t[32]; + + f = fopen("/proc/devices", "r"); + if (f == NULL) + return -errno; + while (fgets(s, 32, f) != NULL) { + if (sscanf(s, "%d %s", &n, t) == 2) + if (strcmp(name, t) == 0) + break; + } + fclose(f); + if (strcmp(name, t) == 0) + return n; + else + return -ENODEV; +} + +static int open_sock(int sock) { + int fd; + char fn[64]; + dev_t dev = (pcmcia_major<<8) + sock; + + snprintf(fn, 64, "/tmp/pcmciadev-%d", getpid()); + if (mknod(fn, (S_IFCHR|0600), dev) == 0) { + fd = open(fn, O_RDONLY); + unlink(fn); + if (fd >= 0) + return fd; + } + return -1; +} + +/* return whether or not we have pcmcia loaded */ +int has_pcmcia(void) { + if (pcmcia_major > 0) + return pcmcia_major; + pcmcia_major = lookup_dev("pcmcia"); + return pcmcia_major; +} + +struct bind_info_t { + char dev_info[32]; + unsigned char function; + /* Not really a void *. Some convuluted structure that appears + * to be NULL in cardmgr. */ + void *instance; + char name[32]; + unsigned short major; + unsigned short minor; + void *next; +}; + + +#define DS_BIND_REQUEST _IOWR('d', 60, struct bind_info_t) +int activate_pcmcia_device(struct pcmciaDevice *pdev) { + int fd; + struct bind_info_t * bind; + + if (has_pcmcia() <= 0) { + logMessage("pcmcia not loaded, can't activate module"); + return -1; + } + + fd = open_sock(pdev->slot); + if (fd < 0) { + logMessage("unable to open slot"); + return -1; + } + + bind = calloc(1, sizeof(struct bind_info_t *)); + strcpy(bind->dev_info,pdev->driver); + bind->function = pdev->function; + if (ioctl(fd, DS_BIND_REQUEST, bind) == -1) { + logMessage("failed to activate pcmcia device"); + return LOADER_ERROR; + } + return LOADER_OK; +} + +void startPcmciaDevices() { + struct device ** devices; + int i; + + /* no pcmcia, don't try to start the devices */ + if (has_pcmcia() <= 0) + return; + + devices = probeDevices(CLASS_UNSPEC, BUS_PCMCIA, PROBE_ALL); + if (!devices) { + logMessage("no devices to activate\n"); + return; + } + + for (i = 0; devices[i]; i++) { + if (devices[i]->bus != BUS_PCMCIA) + continue; + if (!(strcmp (devices[i]->driver, "ignore") && + strcmp (devices[i]->driver, "unknown") && + strcmp (devices[i]->driver, "disabled"))) + continue; + + logMessage("going to activate device using %s", devices[i]->driver); + activate_pcmcia_device((struct pcmciaDevice *)devices[i]); + } +} + +static int detectHardware(char *** modules) { + struct device ** devices, ** device; + char ** modList; + int numMods; + char *driver; + + logMessage("probing buses"); + + devices = probeDevices(CLASS_UNSPEC, + BUS_PCI | BUS_SBUS | + ((has_pcmcia() >= 0) ? BUS_PCMCIA : 0), + PROBE_ALL); + + logMessage("finished bus probing"); + + if (devices == NULL) { + *modules = NULL; + return LOADER_OK; + } + + numMods = 0; + for (device = devices; *device; device++) numMods++; + + if (!numMods) { + *modules = NULL; + return LOADER_OK; + } + + modList = malloc(sizeof(*modList) * (numMods + 1)); + numMods = 0; + + for (device = devices; *device; device++) { + driver = (*device)->driver; + if (strcmp (driver, "ignore") && strcmp (driver, "unknown") + && strcmp (driver, "disabled")) { + modList[numMods++] = strdup(driver); + } + + freeDevice (*device); + } + + modList[numMods] = NULL; + *modules = modList; + + free(devices); + + return LOADER_OK; +} + + +int main(int argc, char ** argv) { + char ** modList; + char modules[1024]; + int i; + + logMessage("initializing pcmcia controller"); + initializePcmciaController(); + + detectHardware(&modList); + + if (modList) { + *modules = '\0'; + + for (i = 0; modList[i]; i++) { + if (i) strcat(modules, ":"); + strcat(modules, modList[i]); + } + + mlLoadModuleSet(modules); + + startPcmciaDevices(); + } +} |