Hi,
trying to get rid of the old pcmcia-ioctl-interface in the kernel, I modified
discover to use sysfs for that. Please find the patch attached. It modifies
configure.ac, so autoreconf has to be used to generate the new configure.
Is this interesting? I hope so, it seems discover is the last more prominent
user of that old interface...
Regards,
Wolfram
---
Finally get rid of these messages that discover uses the outdated pcmcia-ioctl
interface. For that, the sysfs-code was copied from PCI and adapted. That means
the ioctl-method is still there as a fallback.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
configure.ac | 3 +
sysdeps/linux/pcmcia.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 148 insertions(+), 2 deletions(-)
Index: configure.ac
===================================================================
--- configure.ac.orig
+++ configure.ac
@@ -218,6 +218,7 @@ linux*)
PATH_PROC_PCI="/proc/bus/pci/devices"
PATH_PROC_PCI_DIR=`dirname $PATH_PROC_PCI`
PATH_SYS_PCI="/sys/bus/pci/devices"
+ PATH_SYS_PCMCIA="/sys/bus/pcmcia/devices"
PATH_PROC_SCSI="/proc/scsi/scsi"
PATH_PROC_USB="/proc/bus/usb/devices"
AC_DEFINE_UNQUOTED(PATH_PROC_IDE, "$PATH_PROC_IDE",
@@ -228,6 +229,8 @@ linux*)
[Define path to /proc/bus/pci.])
AC_DEFINE_UNQUOTED(PATH_SYS_PCI, "$PATH_SYS_PCI",
[Define path to /sys/bus/pci/devices.])
+ AC_DEFINE_UNQUOTED(PATH_SYS_PCMCIA, "$PATH_SYS_PCMCIA",
+ [Define path to /sys/bus/pcmcia/devices.])
AC_DEFINE_UNQUOTED(PATH_PROC_SCSI, "$PATH_PROC_SCSI",
[Define path to /proc/scsi/scsi.])
AC_DEFINE_UNQUOTED(PATH_PROC_USB, "$PATH_PROC_USB",
Index: sysdeps/linux/pcmcia.c
===================================================================
--- sysdeps/linux/pcmcia.c.orig
+++ sysdeps/linux/pcmcia.c
@@ -72,6 +72,8 @@
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
+#include <string.h>
+#include <dirent.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
@@ -79,13 +81,18 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
-
+#include <discover/sysdep.h>
#include <discover/device.h>
#include <discover/utils.h>
/* XXX: There's no reason for this to be global. */
static int major = 0;
+static int cmpstringp(const void *p1, const void *p2)
+{
+ return strcmp(* (char * const *) p1, * (char * const *) p2);
+}
+
static int lookup_dev(char *name){
FILE *f;
int n;
@@ -153,7 +160,7 @@ _discover_sysdep_init(discover_sysdep_da
}
discover_sysdep_data_t *
-_discover_get_pcmcia_raw(void)
+_discover_get_pcmcia_raw_ioctl(void)
{
int fd, ns;
ds_ioctl_arg_t arg;
@@ -198,6 +205,142 @@ _discover_get_pcmcia_raw(void)
return head;
}
+discover_sysdep_data_t *
+_discover_get_pcmcia_raw_sys(void)
+{
+ discover_sysdep_data_t *head = NULL, *node, *last = NULL;
+ FILE *f;
+ DIR *pcmciaDir;
+ struct dirent *pcmcia_device_entry;
+ unsigned int len;
+ char *device_dir, *vendor, *model, *p;
+ char **device_dir_list = NULL;
+ size_t device_dir_list_len, device_dir_index;
+ char path[256];
+ int ret;
+
+ /* Open the directory containing all the PCMCIA device dirs. */
+ pcmciaDir = opendir(PATH_SYS_PCMCIA);
+ if (pcmciaDir == NULL)
+ return _discover_get_pcmcia_raw_ioctl();
+
+ /*
+ * The order of links in PATH_SYS_PCMCIA is not sorted. Since
+ * module load order can affect things like device naming,
+ * we should collect the device directory names and sort them.
+ */
+
+ for (pcmcia_device_entry = readdir(pcmciaDir); pcmcia_device_entry;
+ pcmcia_device_entry = readdir(pcmciaDir)) {
+ device_dir = strdup(pcmcia_device_entry->d_name);
+ if (device_dir == NULL)
+ continue;
+ if (device_dir[0] == '.') {
+ free(device_dir);
+ continue;
+ }
+
+ if (device_dir_list == NULL) {
+ device_dir_list = (char **)malloc(sizeof(char *));
+ device_dir_list_len = 1;
+ } else {
+ device_dir_list =
+ (char **)realloc(device_dir_list,
+ sizeof(char *) * ++device_dir_list_len);
+ }
+
+ if (device_dir_list != NULL) {
+ device_dir_list[device_dir_list_len - 1] = device_dir;
+ } else {
+ free(device_dir);
+ }
+ }
+
+ closedir(pcmciaDir);
+
+ if (device_dir_list == NULL)
+ return _discover_get_pcmcia_raw_ioctl();
+
+ /* Do a sort. */
+ qsort(device_dir_list, device_dir_list_len, sizeof(char *), cmpstringp);
+
+ /* Loop through the PCMCIA device dirs. */
+ vendor = model = NULL;
+ for (device_dir_index = 0; device_dir_index < device_dir_list_len;
+ device_dir_index++) {
+ device_dir = device_dir_list[device_dir_index];
+ if (device_dir == NULL)
+ continue;
+
+ /* Clean up from tne last loop, if necessary. */
+ if (vendor) {
+ free(vendor);
+ vendor = NULL;
+ }
+ if (model) {
+ free(model);
+ model = NULL;
+ }
+
+ snprintf(path, 256, "%s/%s/manf_id", PATH_SYS_PCMCIA, device_dir);
+ printf("%s\n", path);
+ f = fopen(path, "r");
+ if (!f) continue;
+ ret = getline(&vendor, &len, f);
+ fclose(f);
+ if (ret < 0) continue;
+ vendor[6] = '\0';
+ for (p = vendor; *(p + 2) != '\0'; p++) *p = *(p + 2);
+ *p = '\0';
+
+ snprintf(path, 256, "%s/%s/card_id", PATH_SYS_PCMCIA, device_dir);
+ f = fopen(path, "r");
+ if (!f) continue;
+ ret = getline(&model, &len, f);
+ fclose(f);
+ if (ret < 0) continue;
+ model[6] = '\0';
+ for (p = model; *(p + 2) != '\0'; p++) *p = *(p + 2);
+ *p = '\0';
+
+ /* Create a new sysdep node and populate it. */
+ node = _discover_sysdep_data_new();
+ if (!node) continue;
+ _discover_sysdep_init(node);
+
+ node->vendor = vendor;
+ node->model = model;
+
+ vendor = model = NULL;
+
+ /* Stick the new node in the list. */
+ if (head == NULL) {
+ head = node;
+ last = head;
+ } else {
+ last->next = node;
+ last = node;
+ }
+
+ /* Clean up the directory list memory as we go. */
+ free(device_dir);
+ }
+
+ free(device_dir_list);
+ return head;
+}
+
+
+discover_sysdep_data_t *
+_discover_get_pcmcia_raw(void)
+{
+ if (!access(PATH_SYS_PCMCIA, R_OK))
+ return _discover_get_pcmcia_raw_sys();
+ else
+ return _discover_get_pcmcia_raw_ioctl();
+}
+
+
/*
* Local variables:
* c-file-style: "progeny"
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Attachment:
signature.asc
Description: Digital signature