summaryrefslogtreecommitdiffstats
path: root/loader2/pcmcia.c
diff options
context:
space:
mode:
authorJeremy Katz <katzj@redhat.com>2003-01-07 00:10:30 +0000
committerJeremy Katz <katzj@redhat.com>2003-01-07 00:10:30 +0000
commit2cddec56cf4bdac62a88136952b7fe6f1ceb23d8 (patch)
tree2fea20ddb95384ee6c6b559bd641dfe440b89e0f /loader2/pcmcia.c
parent7b03f1babae8b4924b741e06f5d57951a4b94683 (diff)
downloadanaconda-2cddec56cf4bdac62a88136952b7fe6f1ceb23d8.tar.gz
anaconda-2cddec56cf4bdac62a88136952b7fe6f1ceb23d8.tar.xz
anaconda-2cddec56cf4bdac62a88136952b7fe6f1ceb23d8.zip
non-cardbus pcmcia support. it looks like it basically works
Diffstat (limited to 'loader2/pcmcia.c')
-rw-r--r--loader2/pcmcia.c129
1 files changed, 126 insertions, 3 deletions
diff --git a/loader2/pcmcia.c b/loader2/pcmcia.c
index 69e87e040..d4efcbbb4 100644
--- a/loader2/pcmcia.c
+++ b/loader2/pcmcia.c
@@ -16,9 +16,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <errno.h>
+#include <fcntl.h>
#include <kudzu/kudzu.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
#include "loader.h"
#include "loadermisc.h"
@@ -32,15 +36,21 @@ char * getPcicController() {
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);
+ }
}
- /* JKFIXME: need to probe for non-cardbus adapters */
-
if (!pcic) {
logMessage("no pcic controller found");
}
@@ -77,3 +87,116 @@ int cardbusControllerInitialize(moduleList modLoaded, moduleDeps modDeps,
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(moduleList modLoaded, int flags) {
+ 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)
+ 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;
+ if (!mlModuleInList(devices[i]->driver, modLoaded))
+ continue;
+
+ activate_pcmcia_device((struct pcmciaDevice *)devices[i]);
+ }
+}