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.s...@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/ |
signature.asc
Description: Digital signature