summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormananth <mananth>2003-10-15 12:28:43 +0000
committermananth <mananth>2003-10-15 12:28:43 +0000
commitff6875c900cfc39181a3798ce72957158faf93f5 (patch)
tree940be88cd1c0dd30d8ac0f7eebf676e47d1ae226
parent2ce335030ece164a7e0b3f124b30e373586f6372 (diff)
downloadsysfsutils-ff6875c900cfc39181a3798ce72957158faf93f5.tar.gz
1. PCI name decodes
2. Test routines (get_*)
-rw-r--r--CREDITS3
-rw-r--r--ChangeLog5
-rw-r--r--cmd/Makefile.am4
-rw-r--r--cmd/Makefile.in12
-rw-r--r--cmd/lsbus.c69
-rw-r--r--cmd/names.c340
-rw-r--r--cmd/names.h23
-rw-r--r--cmd/systool.c70
-rw-r--r--test/get_dev_bus.c35
-rw-r--r--test/get_dev_class.c38
-rw-r--r--test/get_device.c52
-rw-r--r--test/get_drv.c52
-rw-r--r--test/get_list.c42
-rw-r--r--test/write_attr.c63
-rw-r--r--test/write_attr_2.c27
15 files changed, 804 insertions, 31 deletions
diff --git a/CREDITS b/CREDITS
index 161d0d4..ba2438c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -11,3 +11,6 @@ have made contributions:
- Added dlist_for_each* functionality.
o Guo Min <min.guo@intel.com>:
- Supplied sysfs_write_attribute patch
+ o Martin Mares <mj@ucw.cz>
+ - Author of pciutils. Reused the pci name decoding
+ from Martin's library.
diff --git a/ChangeLog b/ChangeLog
index 0e3a509..8e9dce3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
+10/01/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
+ * Added number of utility routines in "test" directory
+ * Adapted PCI name decode support from Martin Mares'
+ pciutils
+
09/30/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
* Modified routines to find device/driver on a bus
* Made some miscellaneous changes to use #defines
diff --git a/cmd/Makefile.am b/cmd/Makefile.am
index 1297002..4bcc334 100644
--- a/cmd/Makefile.am
+++ b/cmd/Makefile.am
@@ -1,6 +1,6 @@
bin_PROGRAMS = systool lsbus
-systool_SOURCES = systool.c
-lsbus_SOURCES = lsbus.c
+systool_SOURCES = systool.c names.c
+lsbus_SOURCES = lsbus.c names.c
INCLUDES = -I../include
LDADD = ../lib/libsysfs.a
diff --git a/cmd/Makefile.in b/cmd/Makefile.in
index 170efa5..b263562 100644
--- a/cmd/Makefile.in
+++ b/cmd/Makefile.in
@@ -76,8 +76,8 @@ am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
bin_PROGRAMS = systool lsbus
-systool_SOURCES = systool.c
-lsbus_SOURCES = lsbus.c
+systool_SOURCES = systool.c names.c
+lsbus_SOURCES = lsbus.c names.c
INCLUDES = -I../include
LDADD = ../lib/libsysfs.a
subdir = cmd
@@ -87,12 +87,12 @@ CONFIG_CLEAN_FILES =
bin_PROGRAMS = systool$(EXEEXT) lsbus$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
-am_lsbus_OBJECTS = lsbus.$(OBJEXT)
+am_lsbus_OBJECTS = lsbus.$(OBJEXT) names.$(OBJEXT)
lsbus_OBJECTS = $(am_lsbus_OBJECTS)
lsbus_LDADD = $(LDADD)
lsbus_DEPENDENCIES = ../lib/libsysfs.a
lsbus_LDFLAGS =
-am_systool_OBJECTS = systool.$(OBJEXT)
+am_systool_OBJECTS = systool.$(OBJEXT) names.$(OBJEXT)
systool_OBJECTS = $(am_systool_OBJECTS)
systool_LDADD = $(LDADD)
systool_DEPENDENCIES = ../lib/libsysfs.a
@@ -105,7 +105,8 @@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/lsbus.Po ./$(DEPDIR)/systool.Po
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/lsbus.Po ./$(DEPDIR)/names.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/systool.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
@@ -162,6 +163,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsbus.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/systool.Po@am__quote@
distclean-depend:
diff --git a/cmd/lsbus.c b/cmd/lsbus.c
index 9b9a709..1be88b7 100644
--- a/cmd/lsbus.c
+++ b/cmd/lsbus.c
@@ -31,11 +31,14 @@
#include <ctype.h>
#include "libsysfs.h"
+#include "names.h"
/* Command Options */
static int show_options = 0; /* bitmask of show options */
-static unsigned char *attr_to_show = NULL; /* print value for this attribute*/
-static unsigned char *bus_device = NULL; /* print only this bus device */
+static unsigned char *attr_to_show = NULL; /* print value for this attribute*/
+static unsigned char *bus_device = NULL; /* print only this bus device */
+struct pci_access *pacc = NULL;
+unsigned char *bus_to_print = NULL;
#define SHOW_ATTRIBUTES 0x01 /* show attributes command option */
#define SHOW_ATTRIBUTE_VALUE 0x02 /* show an attribute value option */
@@ -58,6 +61,19 @@ static unsigned char *binary_files[] = {
static int binfiles = 2;
+static unsigned int get_pciconfig_word(int offset, char *buf)
+{
+ unsigned short val = (unsigned char)buf[offset] |
+ ((unsigned char)buf[offset+1] << 8);
+ return val;
+}
+
+static unsigned char get_pciconfig_byte(int offset, char *buf)
+{
+ return((unsigned char)buf[offset]);
+}
+
+
/**
* usage: prints utility usage.
*/
@@ -125,7 +141,6 @@ void print_attribute_value(struct sysfs_attribute *attr)
(unsigned char)attr->value[i]);
}
fprintf(stdout, "\n");
-
} else if (attr->value != NULL && strlen(attr->value) > 0) {
remove_end_newline(attr->value);
fprintf(stdout, "\t: %s\n", attr->value);
@@ -184,16 +199,34 @@ void print_device_attributes(struct dlist *attributes)
void print_device(struct sysfs_device *device)
{
struct dlist *attributes = NULL;
+ unsigned int vendor_id, device_id, subsystem_vendor, subsystem_device;
+ unsigned char buf[128], *value = NULL;
if (device != NULL) {
- fprintf (stdout, " %s\n", device->bus_id);
- if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES))
- attributes = sysfs_get_device_attributes(device);
- if (attributes != NULL)
- print_device_attributes(attributes);
+ fprintf (stdout, " %s: ", device->bus_id);
+ attributes = sysfs_get_device_attributes(device);
+ if (attributes != NULL) {
+ if (!(strcmp(bus_to_print, "pci"))) {
+ value = sysfs_get_value_from_attributes
+ (attributes, "config");
+ if (value != NULL) {
+ vendor_id = get_pciconfig_word
+ (PCI_VENDOR_ID, value);
+ device_id = get_pciconfig_word
+ (PCI_DEVICE_ID, value);
+ fprintf(stdout, "%s\n",
+ pci_lookup_name(pacc, buf, 128,
+ PCI_LOOKUP_VENDOR |
+ PCI_LOOKUP_DEVICE,
+ vendor_id, device_id, 0, 0));
+ }
+ }
+ if (show_options & (SHOW_ATTRIBUTES |
+ SHOW_ATTRIBUTE_VALUE | SHOW_ALL_ATTRIB_VALUES))
+ print_device_attributes(attributes);
+ }
if (isalnum(device->driver_name[0]))
- fprintf (stdout, "\tDriver: %s\n",
+ fprintf (stdout, "\tDriver: %s\n\n",
device->driver_name);
}
}
@@ -324,11 +357,13 @@ int print_sysfs_buses(void)
/* MAIN */
int main(int argc, char *argv[])
{
- unsigned char *bus_to_print = NULL;
+ //unsigned char *bus_to_print = NULL;
int retval = 0;
int opt;
extern int optind;
extern char *optarg;
+ /*pci ids*/
+ char *pci_id_file = "/usr/local/share/pci.ids";
while((opt = getopt(argc, argv, cmd_options)) != EOF) {
switch(opt) {
@@ -406,10 +441,18 @@ int main(int argc, char *argv[])
if (!(show_options & (SHOW_DEVICES | SHOW_DRIVERS)))
show_options |= SHOW_DEVICES;
- if (bus_to_print != NULL)
+ if (bus_to_print != NULL) {
+ if (!(strcmp(bus_to_print, "pci"))) {
+ pacc = (struct pci_access *)calloc(1, sizeof(struct pci_access));
+ pacc->pci_id_file_name = pci_id_file;
+ pacc->numeric_ids = 0;
+ }
retval = print_sysfs_bus(bus_to_print);
- else
+ } else
retval = print_sysfs_buses();
+ if (bus_to_print != NULL)
+ if (!(strcmp(bus_to_print, "pci")))
+ pci_free_name_list(pacc);
exit(retval);
}
diff --git a/cmd/names.c b/cmd/names.c
new file mode 100644
index 0000000..e77fc4e
--- /dev/null
+++ b/cmd/names.c
@@ -0,0 +1,340 @@
+/*
+ * $Id: names.c,v 1.1.2.1 2003/10/15 12:28:44 mananth Exp $
+ *
+ * The PCI Library -- ID to Name Translation
+ *
+ * Copyright (c) 1997--2002 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include "names.h"
+
+struct nl_entry {
+ struct nl_entry *next;
+ unsigned short id1, id2, id3, id4;
+ int cat;
+ char *name;
+};
+
+#define NL_VENDOR 0
+#define NL_DEVICE 1
+#define NL_SUBSYSTEM 2
+#define NL_CLASS 3
+#define NL_SUBCLASS 4
+#define NL_PROGIF 5
+
+#define HASH_SIZE 1024
+
+static inline unsigned int nl_calc_hash(int cat, int id1, int id2, int id3, int id4)
+{
+ unsigned int h;
+
+ h = id1 ^ id2 ^ id3 ^ id4 ^ (cat << 5);
+ h += (h >> 6);
+ return h & (HASH_SIZE-1);
+}
+
+static struct nl_entry *nl_lookup(struct pci_access *a, int num, int cat, int id1, int id2, int id3, int id4)
+{
+ unsigned int h;
+ struct nl_entry *n;
+
+ if (num)
+ return NULL;
+ h = nl_calc_hash(cat, id1, id2, id3, id4);
+ n = a->nl_hash[h];
+ while (n && (n->id1 != id1 || n->id2 != id2 || n->id3 != id3 || n->id4 != id4 || n->cat != cat))
+ n = n->next;
+
+ return n;
+}
+
+static int nl_add(struct pci_access *a, int cat, int id1, int id2, int id3, int id4, char *text)
+{
+ unsigned int h = nl_calc_hash(cat, id1, id2, id3, id4);
+ struct nl_entry *n = a->nl_hash[h];
+
+ while (n && (n->id1 != id1 || n->id2 != id2 || n->id3 != id3 || n->id4 != id4 || n->cat != cat))
+ n = n->next;
+ if (n)
+ return 1;
+ n = malloc(sizeof(struct nl_entry));
+ bzero(n, sizeof(struct nl_entry));
+ n->id1 = id1;
+ n->id2 = id2;
+ n->id3 = id3;
+ n->id4 = id4;
+ n->cat = cat;
+ n->name = text;
+ n->next = a->nl_hash[h];
+ a->nl_hash[h] = n;
+ return 0;
+}
+
+static void
+err_name_list(struct pci_access *a, char *msg)
+{
+ fprintf(stderr, "%s: %s: %s\n", a->pci_id_file_name, msg, strerror(errno));
+}
+
+static void
+parse_name_list(struct pci_access *a)
+{
+ char *p = a->nl_list;
+ char *q, *r;
+ int lino = 0;
+ unsigned int id1=0, id2=0, id3=0, id4=0;
+ int cat = -1;
+
+ while (*p)
+ {
+ lino++;
+ q = p;
+ while (*p && *p != '\n')
+ p++;
+ if (*p == '\n')
+ *p++ = 0;
+ if (!*q || *q == '#')
+ continue;
+ r = p;
+ while (r > q && r[-1] == ' ')
+ *--r = 0;
+ r = q;
+ while (*q == '\t')
+ q++;
+ if (q == r)
+ {
+ if (q[0] == 'C' && q[1] == ' ')
+ {
+ if (strlen(q+2) < 3 ||
+ q[4] != ' ' ||
+ sscanf(q+2, "%x", &id1) != 1)
+ goto parserr;
+ cat = NL_CLASS;
+ }
+ else
+ {
+ if (strlen(q) < 5 ||
+ q[4] != ' ' ||
+ sscanf(q, "%x", &id1) != 1)
+ goto parserr;
+ cat = NL_VENDOR;
+ }
+ id2 = id3 = id4 = 0;
+ q += 4;
+ }
+ else if (q == r+1)
+ switch (cat)
+ {
+ case NL_VENDOR:
+ case NL_DEVICE:
+ case NL_SUBSYSTEM:
+ if (sscanf(q, "%x", &id2) != 1 || q[4] != ' ')
+ goto parserr;
+ q += 5;
+ cat = NL_DEVICE;
+ id3 = id4 = 0;
+ break;
+ case NL_CLASS:
+ case NL_SUBCLASS:
+ case NL_PROGIF:
+ if (sscanf(q, "%x", &id2) != 1 || q[2] != ' ')
+ goto parserr;
+ q += 3;
+ cat = NL_SUBCLASS;
+ id3 = id4 = 0;
+ break;
+ default:
+ goto parserr;
+ }
+ else if (q == r+2)
+ switch (cat)
+ {
+ case NL_DEVICE:
+ case NL_SUBSYSTEM:
+ if (sscanf(q, "%x%x", &id3, &id4) != 2 || q[9] != ' ')
+ goto parserr;
+ q += 10;
+ cat = NL_SUBSYSTEM;
+ break;
+ case NL_CLASS:
+ case NL_SUBCLASS:
+ case NL_PROGIF:
+ if (sscanf(q, "%x", &id3) != 1 || q[2] != ' ')
+ goto parserr;
+ q += 3;
+ cat = NL_PROGIF;
+ id4 = 0;
+ break;
+ default:
+ goto parserr;
+ }
+ else
+ goto parserr;
+ while (*q == ' ')
+ q++;
+ if (!*q)
+ goto parserr;
+ if (nl_add(a, cat, id1, id2, id3, id4, q))
+ fprintf(stderr, "%s, line %d: duplicate entry", a->pci_id_file_name, lino);
+ }
+ return;
+
+parserr:
+ fprintf(stderr, "%s, line %d: parse error", a->pci_id_file_name, lino);
+}
+
+static void
+load_name_list(struct pci_access *a)
+{
+ int fd;
+ struct stat st;
+
+ fd = open(a->pci_id_file_name, O_RDONLY);
+ if (fd < 0)
+ {
+ a->numeric_ids = 1;
+ return;
+ }
+ if (fstat(fd, &st) < 0)
+ err_name_list(a, "stat");
+ a->nl_list = malloc(st.st_size + 1);
+ if (read(fd, a->nl_list, st.st_size) != st.st_size)
+ err_name_list(a, "read");
+ a->nl_list[st.st_size] = 0;
+ a->nl_hash = malloc(sizeof(struct nl_entry *) * HASH_SIZE);
+ bzero(a->nl_hash, sizeof(struct nl_entry *) * HASH_SIZE);
+ parse_name_list(a);
+ close(fd);
+}
+
+void
+pci_free_name_list(struct pci_access *a)
+{
+ free(a->nl_list);
+ a->nl_list = NULL;
+ free(a->nl_hash);
+ a->nl_hash = NULL;
+}
+
+char *
+pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, unsigned int arg1, unsigned int arg2, unsigned int arg3, unsigned int arg4)
+{
+ int num = a->numeric_ids;
+ int res;
+ struct nl_entry *n;
+
+ if (flags & PCI_LOOKUP_NUMERIC)
+ {
+ flags &= PCI_LOOKUP_NUMERIC;
+ num = 1;
+ }
+ if (!a->nl_hash && !num)
+ {
+ load_name_list(a);
+ num = a->numeric_ids;
+ }
+ switch (flags)
+ {
+ case PCI_LOOKUP_VENDOR:
+ if (n = nl_lookup(a, num, NL_VENDOR, arg1, 0, 0, 0))
+ return n->name;
+ else
+ res = snprintf(buf, size, "%04x", arg1);
+ break;
+ case PCI_LOOKUP_DEVICE:
+ if (n = nl_lookup(a, num, NL_DEVICE, arg1, arg2, 0, 0))
+ return n->name;
+ else
+ res = snprintf(buf, size, "%04x", arg2);
+ break;
+ case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE:
+ if (!num)
+ {
+ struct nl_entry *e, *e2;
+ e = nl_lookup(a, 0, NL_VENDOR, arg1, 0, 0, 0);
+ e2 = nl_lookup(a, 0, NL_DEVICE, arg1, arg2, 0, 0);
+ if (!e)
+ res = snprintf(buf, size, "Unknown device %04x:%04x", arg1, arg2);
+ else if (!e2)
+ res = snprintf(buf, size, "%s: Unknown device %04x", e->name, arg2);
+ else
+ res = snprintf(buf, size, "%s %s", e->name, e2->name);
+ }
+ else
+ res = snprintf(buf, size, "%04x:%04x", arg1, arg2);
+ break;
+ case PCI_LOOKUP_VENDOR | PCI_LOOKUP_SUBSYSTEM:
+ if (n = nl_lookup(a, num, NL_VENDOR, arg3, 0, 0, 0))
+ return n->name;
+ else
+ res = snprintf(buf, size, "%04x", arg2);
+ break;
+ case PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM:
+ if (n = nl_lookup(a, num, NL_SUBSYSTEM, arg1, arg2, arg3, arg4))
+ return n->name;
+ else if (arg1 == arg3 && arg2 == arg4 && (n = nl_lookup(a, num, NL_DEVICE, arg1, arg2, 0, 0)))
+ return n->name;
+ else
+ res = snprintf(buf, size, "%04x", arg4);
+ break;
+ case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM:
+ if (!num)
+ {
+ struct nl_entry *e, *e2;
+ e = nl_lookup(a, 0, NL_VENDOR, arg3, 0, 0, 0);
+ e2 = nl_lookup(a, 0, NL_SUBSYSTEM, arg1, arg2, arg3, arg4);
+ if (!e2 && arg1 == arg3 && arg2 == arg4)
+ /* Cheat for vendors blindly setting subsystem ID same as device ID */
+ e2 = nl_lookup(a, 0, NL_DEVICE, arg1, arg2, 0, 0);
+ if (!e)
+ res = snprintf(buf, size, "Unknown device %04x:%04x", arg3, arg4);
+ else if (!e2)
+ res = snprintf(buf, size, "%s: Unknown device %04x", e->name, arg4);
+ else
+ res = snprintf(buf, size, "%s %s", e->name, e2->name);
+ }
+ else
+ res = snprintf(buf, size, "%04x:%04x", arg3, arg4);
+ break;
+ case PCI_LOOKUP_CLASS:
+ if (n = nl_lookup(a, num, NL_SUBCLASS, arg1 >> 8, arg1 & 0xff, 0, 0))
+ return n->name;
+ else if (n = nl_lookup(a, num, NL_CLASS, arg1, 0, 0, 0))
+ res = snprintf(buf, size, "%s [%04x]", n->name, arg1);
+ else
+ res = snprintf(buf, size, "Class %04x", arg1);
+ break;
+ case PCI_LOOKUP_PROGIF:
+ if (n = nl_lookup(a, num, NL_PROGIF, arg1 >> 8, arg1 & 0xff, arg2, 0))
+ return n->name;
+ if (arg1 == 0x0101)
+ {
+ /* IDE controllers have complex prog-if semantics */
+ if (arg2 & 0x70)
+ return NULL;
+ res = snprintf(buf, size, "%s%s%s%s%s",
+ (arg2 & 0x80) ? "Master " : "",
+ (arg2 & 0x08) ? "SecP " : "",
+ (arg2 & 0x04) ? "SecO " : "",
+ (arg2 & 0x02) ? "PriP " : "",
+ (arg2 & 0x01) ? "PriO " : "");
+ if (res)
+ buf[--res] = 0;
+ break;
+ }
+ return NULL;
+ default:
+ return "<pci_lookup_name: invalid request>";
+ }
+ return (res == size) ? "<too-large>" : buf;
+}
diff --git a/cmd/names.h b/cmd/names.h
new file mode 100644
index 0000000..6b4243b
--- /dev/null
+++ b/cmd/names.h
@@ -0,0 +1,23 @@
+/* names.h */
+
+#ifndef _NAMES_H_
+#define _NAMES_H_
+
+#define PCI_LOOKUP_VENDOR 1
+#define PCI_LOOKUP_DEVICE 2
+#define PCI_LOOKUP_CLASS 4
+#define PCI_LOOKUP_SUBSYSTEM 8
+#define PCI_LOOKUP_PROGIF 16
+#define PCI_LOOKUP_NUMERIC 0x10000
+
+#define PCI_VENDOR_ID 0x00
+#define PCI_DEVICE_ID 0x02
+
+struct pci_access {
+ int numeric_ids;
+ char *pci_id_file_name;
+ char *nl_list;
+ struct nl_entry **nl_hash;
+};
+
+#endif /* _NAMES_H_ */
diff --git a/cmd/systool.c b/cmd/systool.c
index 6ebbe3a..fabf14e 100644
--- a/cmd/systool.c
+++ b/cmd/systool.c
@@ -31,11 +31,14 @@
#include <ctype.h>
#include "libsysfs.h"
+#include "names.h"
/* Command Options */
static int show_options = 0; /* bitmask of show options */
static unsigned char *attribute_to_show = NULL; /* show value for this attribute */
static unsigned char *device_to_show = NULL; /* show only this bus device */
+struct pci_access *pacc = NULL;
+unsigned char *show_bus = NULL;
#define SHOW_ATTRIBUTES 0x01 /* show attributes command option */
#define SHOW_ATTRIBUTE_VALUE 0x02 /* show an attribute value option */
@@ -58,6 +61,19 @@ static unsigned char *binary_files[] = {
static int binfiles = 2;
+static unsigned int get_pciconfig_word(int offset, char *buf)
+{
+ unsigned short val = (unsigned char)buf[offset] |
+ ((unsigned char)buf[offset+1] << 8);
+ return val;
+}
+
+static unsigned char get_pciconfig_byte(int offset, char *buf)
+{
+ return((unsigned char)buf[offset]);
+}
+
+
/**
* usage: prints utility usage.
*/
@@ -227,20 +243,41 @@ void show_attributes(struct dlist *attributes, int level)
void show_device(struct sysfs_device *device, int level)
{
struct dlist *attributes = NULL;
+ unsigned int vendor_id, device_id, subsystem_vendor, subsystem_device;
+ unsigned char buf[128], *value = NULL;
+
if (device != NULL) {
indent(level);
- fprintf (stdout, "%s\n", device->bus_id);
- if (device->children != NULL)
- show_device_children(device->children, (level+4));
- if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE
- | SHOW_ALL_ATTRIB_VALUES)) {
- attributes = sysfs_get_device_attributes(device);
- if (attributes != NULL)
+ fprintf (stdout, "%s: ", device->bus_id);
+ attributes = sysfs_get_device_attributes(device);
+ if (attributes != NULL) {
+ if (!(strcmp(show_bus, "pci"))) {
+ value = sysfs_get_value_from_attributes
+ (attributes, "config");
+ if (value != NULL) {
+ vendor_id = get_pciconfig_word
+ (PCI_VENDOR_ID, value);
+ device_id = get_pciconfig_word
+ (PCI_DEVICE_ID, value);
+ fprintf(stdout, "%s\n",
+ pci_lookup_name(pacc, buf, 128,
+ PCI_LOOKUP_VENDOR |
+ PCI_LOOKUP_DEVICE,
+ vendor_id, device_id,
+ 0, 0));
+ }
+ }
+ if (show_options & (SHOW_ATTRIBUTES |
+ SHOW_ATTRIBUTE_VALUE |
+ SHOW_ALL_ATTRIB_VALUES)) {
show_attributes(attributes, (level+4));
+ }
}
+ if (device->children != NULL)
+ show_device_children(device->children, (level+4));
if (isalnum(device->driver_name[0])) {
- indent(level+4);
+ indent(level+6);
fprintf (stdout, "Driver: %s\n",
device->driver_name);
}
@@ -626,7 +663,7 @@ int show_default_info(void)
/* MAIN */
int main(int argc, char *argv[])
{
- unsigned char *show_bus = NULL;
+/* unsigned char *show_bus = NULL;*/
unsigned char *show_class = NULL;
unsigned char *show_root = NULL;
unsigned char *show_block = NULL;
@@ -634,7 +671,8 @@ int main(int argc, char *argv[])
int opt;
extern int optind;
extern char *optarg;
-
+ char *pci_id_file = "/usr/local/share/pci.ids";
+
while((opt = getopt(argc, argv, cmd_options)) != EOF) {
switch(opt) {
case 'a':
@@ -716,8 +754,15 @@ int main(int argc, char *argv[])
if (!(show_options & (SHOW_DEVICES | SHOW_DRIVERS)))
show_options |= SHOW_DEVICES;
- if (show_bus != NULL)
+ if (show_bus != NULL) {
+ if (!(strcmp(show_bus, "pci"))) {
+ pacc = (struct pci_access *)
+ calloc(1, sizeof(struct pci_access));
+ pacc->pci_id_file_name = pci_id_file;
+ pacc->numeric_ids = 0;
+ }
retval = show_sysfs_bus(show_bus);
+ }
if (show_class != NULL)
retval = show_sysfs_class(show_class);
if (show_root != NULL)
@@ -729,5 +774,8 @@ int main(int argc, char *argv[])
show_root == NULL && show_block == NULL)
retval = show_default_info();
+ if (show_bus != NULL)
+ if (!(strcmp(show_bus, "pci")))
+ pci_free_name_list(pacc);
exit(retval);
}
diff --git a/test/get_dev_bus.c b/test/get_dev_bus.c
new file mode 100644
index 0000000..bdfecda
--- /dev/null
+++ b/test/get_dev_bus.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <mntent.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "libsysfs.h"
+
+int main(int argc, char *argv[])
+{
+ char *busname = NULL;
+ int rc;
+
+ if (argc != 2) {
+ fprintf(stdout, "Need 2 argx\n");
+ return 1;
+ }
+
+ busname = (char *)calloc(1, SYSFS_NAME_LEN);
+ rc = sysfs_find_device_bus_name(argv[1], busname, SYSFS_NAME_LEN);
+ if (rc == -1) {
+ fprintf(stdout, "Device %s not found\n", argv[1]);
+ free(busname);
+ return 1;
+ }
+ fprintf(stdout, "Device %s is on bus %s\n", argv[1], busname);
+ free(busname);
+ return 0;
+}
+
diff --git a/test/get_dev_class.c b/test/get_dev_class.c
new file mode 100644
index 0000000..32efabf
--- /dev/null
+++ b/test/get_dev_class.c
@@ -0,0 +1,38 @@
+/* Gets class of the supplied device */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <mntent.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "libsysfs.h"
+
+int main(int argc, char *argv[])
+{
+ char *classname = NULL;
+ int rc;
+
+ if (argc != 2) {
+ fprintf(stdout, "Need 2 argx\n");
+ return 1;
+ }
+
+ classname = (char *)calloc(1, SYSFS_NAME_LEN);
+ rc = sysfs_find_device_class_name(argv[1], classname, SYSFS_NAME_LEN);
+ if (rc == -1) {
+ fprintf(stdout, "Device %s not found\n", argv[1]);
+ free(classname);
+ return 1;
+ }
+ fprintf(stdout, "Device %s is a member of class %s\n",
+ argv[1], classname);
+ free(classname);
+ return 0;
+}
+
diff --git a/test/get_device.c b/test/get_device.c
new file mode 100644
index 0000000..46ba7ff
--- /dev/null
+++ b/test/get_device.c
@@ -0,0 +1,52 @@
+/* Gets details of the supplied device */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <mntent.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "libsysfs.h"
+
+int main(int argc, char *argv[])
+{
+ char *bus = NULL;
+ struct sysfs_driver *driver = NULL;
+ struct sysfs_device *device = NULL;
+ struct sysfs_attribute *attr = NULL;
+
+ if (argc != 2) {
+ fprintf(stdout, "Need 2 args\n");
+ return 1;
+ }
+
+ bus = (char *)calloc(1, SYSFS_NAME_LEN);
+ if ((sysfs_find_device_bus(argv[1], bus, SYSFS_NAME_LEN)) < 0) {
+ fprintf(stdout, "Device %s not found\n", argv[1]);
+ free (bus);
+ return 1;
+ }
+ fprintf(stdout, "Device %s is a member of bus %s\n",
+ argv[1], bus);
+ device = sysfs_open_device_by_id(argv[1], bus, SYSFS_NAME_LEN);
+ if (device == NULL) {
+ fprintf(stdout, "Device %s not found\n", argv[1]);
+ free(bus);
+ return 1;
+ }
+ dlist_for_each_data(device->directory->attributes, attr,
+ struct sysfs_attribute) {
+ fprintf(stdout, "\t%s : %s", attr->name, attr->value);
+ }
+ fprintf(stdout, "\n");
+
+ sysfs_close_device(device);
+ free(bus);
+ return 0;
+}
+
diff --git a/test/get_drv.c b/test/get_drv.c
new file mode 100644
index 0000000..3040818
--- /dev/null
+++ b/test/get_drv.c
@@ -0,0 +1,52 @@
+/* Gets details of the supplied driver */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <mntent.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "libsysfs.h"
+
+int main(int argc, char *argv[])
+{
+ char *bus = NULL;
+ struct sysfs_driver *driver = NULL;
+ struct sysfs_device *device = NULL;
+
+ if (argc != 2) {
+ fprintf(stdout, "Need 2 args\n");
+ return 1;
+ }
+
+ bus = (char *)calloc(1, SYSFS_NAME_LEN);
+ if ((sysfs_find_driver_bus(argv[1], bus, SYSFS_NAME_LEN)) < 0) {
+ fprintf(stdout, "Driver %s not found\n", argv[1]);
+ free(bus);
+ return 1;
+ }
+ fprintf(stdout, "Driver %s is a member of bus %s\n",
+ argv[1], bus);
+ driver = sysfs_open_driver_by_name(argv[1], bus, SYSFS_NAME_LEN);
+ if (driver == NULL) {
+ fprintf(stdout, "Device %s not found\n", argv[1]);
+ free(bus);
+ return 1;
+ }
+ if (driver->devices != NULL) {
+ fprintf(stdout, "%s is used by:\n", argv[1]);
+ dlist_for_each_data(driver->devices, device, struct sysfs_device)
+ fprintf(stdout, "\t\t%s\n", device->bus_id);
+ } else
+ fprintf(stdout, "%s is presently not used by any device\n", argv[1]);
+
+ sysfs_close_drv(driver);
+ free(bus);
+ return 0;
+}
+
diff --git a/test/get_list.c b/test/get_list.c
new file mode 100644
index 0000000..36d3ec5
--- /dev/null
+++ b/test/get_list.c
@@ -0,0 +1,42 @@
+/* gets list of devices on a given bus */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <mntent.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "libsysfs.h"
+
+int main(int argc, char *argv[])
+{
+ struct dlist *name = NULL;
+ unsigned char path[SYSFS_PATH_MAX];
+ unsigned char *cur = NULL;
+
+ if (argc != 2) {
+ fprintf(stdout, "Require 2 args: bus\n");
+ return 1;
+ }
+
+ memset(path, 0, SYSFS_PATH_MAX);
+ strcpy(path, "/bus/");
+ strcpy(path, argv[1]);
+ strcat(path, "/devices");
+
+
+ name = sysfs_open_subsystem_list(path);
+ dlist_for_each_data(name, cur, char) {
+ fprintf(stdout, "\t%s", cur);
+ }
+
+ sysfs_close_list(name);
+
+ return 0;
+}
+
diff --git a/test/write_attr.c b/test/write_attr.c
new file mode 100644
index 0000000..ab9e6b6
--- /dev/null
+++ b/test/write_attr.c
@@ -0,0 +1,63 @@
+/* write attribute support for the given device */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <mntent.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "libsysfs.h"
+
+int main(int argc, char *argv[])
+{
+ char *bus = NULL;
+ struct sysfs_device *device = NULL;
+ struct sysfs_attribute *attribute = NULL;
+
+ /*
+ * need args: device, attribute and value to be changed to
+ * eg: ./fn_name <device> <attribute> <val to change to>
+ */
+ if (argc != 4) {
+ fprintf(stdout, "Need 4 args\n");
+ return 1;
+ }
+
+ bus = (char *)calloc(1, SYSFS_NAME_LEN);
+ device = sysfs_open_device_by_name(argv[1], bus, SYSFS_NAME_LEN);
+ if (device == NULL) {
+ fprintf(stdout, "Device %s not found\n", argv[1]);
+ free(bus);
+ return 1;
+ }
+ fprintf(stdout, "Device %s is a member of bus %s\n",
+ argv[1], bus);
+ fprintf(stdout, "\t\t%s\n", device->bus_id);
+
+ attribute = sysfs_get_device_attr(device, argv[2]);
+ if (attribute == NULL) {
+ fprintf(stdout, "Attribute %s not defined for device %s\n",
+ argv[2], argv[1]);
+ sysfs_close_device(device);
+ free(bus);
+ return 1;
+ }
+
+ if ((sysfs_write_attribute_value(attribute->path, argv[2])) < 0) {
+ fprintf(stdout, "Write attribute failed\n");
+ sysfs_close_device(device);
+ free(bus);
+ return 1;
+ }
+
+ fprintf(stdout, "Write succeeded\n");
+ sysfs_close_device(device);
+ free(bus);
+ return 0;
+}
+
diff --git a/test/write_attr_2.c b/test/write_attr_2.c
new file mode 100644
index 0000000..6c895c2
--- /dev/null
+++ b/test/write_attr_2.c
@@ -0,0 +1,27 @@
+/* write attribute support for the given device */
+
+#include <stdio.h>
+
+#include "libsysfs.h"
+
+int main(int argc, char *argv[])
+{
+ /*
+ * need args: device, attribute and value to be changed to
+ * eg: ./fn_name <device> <attribut> <val to change to>
+ */
+ if (argc != 4) {
+ fprintf(stdout, "Need 4 args\n");
+ return 1;
+ }
+/* if ((sysfs_change_attribute_value(argv[1], argv[2], argv[3])) < 0) {*/
+ if ((sysfs_write_device_attr(argv[1], argv[2], argv[3])) < 0) {
+/* if ((sysfs_write_classdev_attr(argv[1], argv[2], argv[3])) < 0) {*/
+/* if ((sysfs_write_driver_attr(argv[1], argv[2], argv[3])) < 0) {*/
+ fprintf(stdout, "Write attribute error\n");
+ return 1;
+ }
+ fprintf(stdout, "Write succeeded\n");
+ return 0;
+}
+