summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.cvsignore3
-rw-r--r--Makefile13
-rw-r--r--common.h10
-rwxr-xr-xgenerate_usbclass.pl35
-rw-r--r--ldetect.spec13
-rw-r--r--libldetect-private.h2
-rw-r--r--libldetect.h21
-rw-r--r--lspcidrake.c27
-rw-r--r--pci.c93
-rw-r--r--pciusb.c64
-rw-r--r--usb.c63
11 files changed, 256 insertions, 88 deletions
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000..f6b7b68
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,3 @@
+pciclass.c
+usbclass.c
+lspcidrake
diff --git a/Makefile b/Makefile
index bea2b13..c78f5d3 100644
--- a/Makefile
+++ b/Makefile
@@ -12,16 +12,21 @@ build: $(binaries) $(libraries)
lspcidrake: lspcidrake.c libldetect.a
-libldetect.a: pci.o pciclass.o
+libldetect.a: pciusb.o pci.o usb.o pciclass.o usbclass.o
ar rsc $@ $^
-pciclass.c: /usr/include/linux/pci.h generate_pciclass.pl
+pciclass.c: /usr/include/linux/pci.h /usr/include/linux/pci_ids.h
rm -f $@
- perl generate_pciclass.pl < $< > $@
+ perl generate_pciclass.pl $^ > $@
+ chmod a-w $@
+
+usbclass.c: /usr/share/usb.ids
+ rm -f $@
+ perl generate_usbclass.pl $^ > $@
chmod a-w $@
clean:
- rm -f *~ *.o pciclass.c $(binaries) $(libraries)
+ rm -f *~ *.o pciclass.c usbclass.c $(binaries) $(libraries)
install: build
install -d $(bindir) $(libdir) $(includedir)
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..10fa22b
--- /dev/null
+++ b/common.h
@@ -0,0 +1,10 @@
+#define psizeof(a) (sizeof(a) / sizeof(*(a)))
+
+static inline void *memdup(void *src, size_t size) {
+ void *r = malloc(size);
+ memcpy(r, src, size);
+ return r;
+}
+static inline void ifree(void *p) {
+ if (p) { free(p); p = NULL; }
+}
diff --git a/generate_usbclass.pl b/generate_usbclass.pl
new file mode 100755
index 0000000..a503e85
--- /dev/null
+++ b/generate_usbclass.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+print q(/* This auto-generated from <usb.h>, don't modify! */
+
+struct {
+ unsigned short id;
+ const char *name;
+} usbclasses[] = {
+);
+
+while (<>) {
+ chomp;
+ if (/^C\s+(\d+)\s+(.*)/) {
+ ($cat, $descr) = ($1, $2);
+ } elsif (/^\t\t(\d+)\s+(.*)/ && defined $cat) {
+ print qq( { 0x$cat$1, "$descr|$2" },\n);
+ } elsif (/^\S/) {
+ undef $cat;
+ }
+}
+
+print '
+};
+
+int nb_usbclasses = sizeof(usbclasses) / sizeof(*usbclasses);
+
+extern const char *usb_class2text(unsigned short class) {
+ int i;
+ for (i = 0; i < nb_usbclasses; i++)
+ if (usbclasses[i].id == class) return usbclasses[i].name;
+
+ return "";
+}
+
+';
diff --git a/ldetect.spec b/ldetect.spec
index dcbf728..b26d35c 100644
--- a/ldetect.spec
+++ b/ldetect.spec
@@ -1,6 +1,6 @@
%define name ldetect
-%define version 0.2.0
-%define release 2mdk
+%define version 0.2.3
+%define release 1mdk
Name: %{name}
Version: %{version}
@@ -47,6 +47,15 @@ rm -rf $RPM_BUILD_ROOT
%{_libdir}/*
%changelog
+* Sat Dec 16 2000 Pixel <pixel@mandrakesoft.com> 0.2.3-1mdk
+- now detect usb
+
+* Fri Dec 15 2000 Pixel <pixel@mandrakesoft.com> 0.2.2-1mdk
+- fix pciprobe for subids
+
+* Fri Dec 15 2000 Pixel <pixel@mandrakesoft.com> 0.2.1-1mdk
+- try with linux/pci_ids.h to generate pciclass.c (kernel 2.4)
+
* Fri Dec 15 2000 Pixel <pixel@mandrakesoft.com> 0.2.0-2mdk
- add requires ldetect-lst
diff --git a/libldetect-private.h b/libldetect-private.h
new file mode 100644
index 0000000..6a27497
--- /dev/null
+++ b/libldetect-private.h
@@ -0,0 +1,2 @@
+extern void pciusb_find_modules(struct pciusb_entries entries, const char *fpciusbtable);
+extern void pciusb_initialize(struct pciusb_entry *e);
diff --git a/libldetect.h b/libldetect.h
index a8d9053..5e43b1a 100644
--- a/libldetect.h
+++ b/libldetect.h
@@ -1,7 +1,7 @@
/******************************************************************************/
-/* pci ************************************************************************/
+/* pciusb *********************************************************************/
/******************************************************************************/
-struct pci_entry {
+struct pciusb_entry {
unsigned short vendor; /* PCI vendor id */
unsigned short device;
@@ -12,13 +12,22 @@ struct pci_entry {
char *module;
char *text;
};
-struct pci_entries {
- struct pci_entry *entries;
+struct pciusb_entries {
+ struct pciusb_entry *entries;
int nb;
};
+extern void pciusb_free(struct pciusb_entries entries);
-extern struct pci_entries pci_probe(int probe_type); /* probe_type is boolean */
-extern void pci_free(struct pci_entries entries);
+/******************************************************************************/
+/* pci ************************************************************************/
+/******************************************************************************/
+extern struct pciusb_entries pci_probe(int probe_type); /* probe_type is boolean */
extern const char *pci_class2text(unsigned short class);
+
+/******************************************************************************/
+/* usb ************************************************************************/
+/******************************************************************************/
+extern struct pciusb_entries usb_probe(void);
+extern const char *usb_class2text(unsigned short class);
diff --git a/lspcidrake.c b/lspcidrake.c
index faec021..cb3b2da 100644
--- a/lspcidrake.c
+++ b/lspcidrake.c
@@ -3,10 +3,10 @@
#include <string.h>
#include "libldetect.h"
-void pci_printit(struct pci_entries entries) {
+void pci_printit(struct pciusb_entries entries) {
int i;
for (i = 0; i < entries.nb; i++) {
- struct pci_entry e = entries.entries[i];
+ struct pciusb_entry e = entries.entries[i];
printf("%s:\t%s", e.module ? e.module : "unknown", e.text);
if (e.class) {
const char *class = pci_class2text(e.class);
@@ -16,9 +16,26 @@ void pci_printit(struct pci_entries entries) {
}
}
+void usb_printit(struct pciusb_entries entries) {
+ int i;
+ for (i = 0; i < entries.nb; i++) {
+ struct pciusb_entry e = entries.entries[i];
+ printf("%s:\t%s", e.module ? e.module : "unknown", e.text);
+ if (e.class) printf(" [%s]", usb_class2text(e.class));
+ printf("\n");
+ }
+}
+
int main(int argc, char **argv) {
- struct pci_entries entries = pci_probe(1);
- pci_printit(entries);
- pci_free(entries);
+ {
+ struct pciusb_entries entries = pci_probe(1);
+ pci_printit(entries);
+ pciusb_free(entries);
+ }
+ {
+ struct pciusb_entries entries = usb_probe();
+ usb_printit(entries);
+ pciusb_free(entries);
+ }
exit(0);
}
diff --git a/pci.c b/pci.c
index 6b44e67..e9bf606 100644
--- a/pci.c
+++ b/pci.c
@@ -2,102 +2,53 @@
#include <stdlib.h>
#include <string.h>
#include "libldetect.h"
+#include "libldetect-private.h"
+#include "common.h"
-#define psizeof(a) (sizeof(a) / sizeof(*(a)))
-
-void *memdup(void *src, size_t size) {
- void *r = malloc(size);
- memcpy(r, src, size);
- return r;
-}
-void ifree(void *p) {
- if (p) { free(p); p = NULL; }
-}
-
-static void pci_find_modules(struct pci_entries entries) {
- FILE *f;
- const char *fpcitable = "/usr/share/ldetect-lst/pcitable";
- char buf[2048];
- int line;
-
- if (!(f = fopen(fpcitable, "r"))) {
- fprintf(stderr, "Missing pcitable (should be %s)\n", fpcitable);
- exit(1);
- }
- for (line = 1; fgets(buf, sizeof(buf) - 1, f); line++) {
- unsigned short vendor, device, subvendor, subdevice;
- int offset, i;
- int nb = sscanf(buf, "0x%hx\t0x%hx\t0x%hx\t0x%hx\t%n", &vendor, &device, &subvendor, &subdevice, &offset);
- if (nb != 4) {
- nb = sscanf(buf, "0x%hx\t0x%hx\t%n", &vendor, &device, &offset);
- if (nb != 2 && buf[0] != '#') {
- fprintf(stderr, "%s %d: bad line\n", fpcitable, line);
- continue;
- }
- }
- for (i = 0; i < entries.nb; i++) {
- struct pci_entry *e = &entries.entries[i];
- if (vendor == e->vendor && device == e->device &&
- (nb != 4 || (subvendor == e->subvendor && subdevice == e->subdevice)) && !e->module) {
- char *p = buf + offset + 1;
- char *q = strchr(p, '\t');
- if (q) {
- q[-1] = 0;
- q[strlen(q)-1] = 0;
- e->module = strcmp(p, "unknown") ? strdup(p) : NULL;
- e->text = strdup(q+2);
- }
- }
- }
- }
+static void pci_find_modules(struct pciusb_entries entries) {
+ pciusb_find_modules(entries, "/usr/share/ldetect-lst/pcitable");
}
-extern struct pci_entries pci_probe(int probe_type) {
+extern struct pciusb_entries pci_probe(int probe_type) {
FILE *f;
char buf[512];
unsigned short devbusfn;
unsigned int id;
- struct pci_entry t[100];
- struct pci_entries r;
+ struct pciusb_entry t[100];
+ struct pciusb_entries r;
if (!(f = fopen("/proc/bus/pci/devices", "r"))) exit(1);
for (r.nb = 0; fgets(buf, sizeof(buf) - 1, f) && r.nb < psizeof(t); r.nb++) {
+ struct pciusb_entry e;
+ pciusb_initialize(&e);
+
sscanf(buf, "%hx %x", &devbusfn, &id);
- t[r.nb].vendor = id >> 16;
- t[r.nb].device = id & 0xffff;
- t[r.nb].module = NULL;
- t[r.nb].text = NULL;
+ e.vendor = id >> 16;
+ e.device = id & 0xffff;
{
char file[25];
FILE *f;
snprintf(file, sizeof(file), "/proc/bus/pci/%02x/%02x.%d", devbusfn >> 8, (devbusfn & 0xff) >> 3, (devbusfn & 0xff) & 0x7);
if (probe_type && (f = fopen(file, "r"))) {
if (fseek(f, 10, SEEK_SET) == 0)
- fread(&t[r.nb].class, 2, 1, f);
+ fread(&e.class, 2, 1, f);
if (fseek(f, 0x2c, SEEK_SET) == 0)
- fread(&t[r.nb].subvendor, 2, 1, f), fread(&t[r.nb].subdevice, 2, 1, f);
- } else {
- t[r.nb].subvendor = 0xffff;
- t[r.nb].subdevice = 0xffff;
- t[r.nb].class = 0;
+ fread(&e.subvendor, 2, 1, f), fread(&e.subdevice, 2, 1, f);
+
+ if ((e.subvendor == 0 && e.subdevice == 0) ||
+ (e.subvendor == e.vendor && e.subdevice == e.device)) {
+ e.subvendor = 0xffff;
+ e.subdevice = 0xffff;
+ }
}
}
+ t[r.nb] = e;
}
fclose(f);
- r.entries = memdup(t, sizeof(struct pci_entry) * r.nb);
+ r.entries = memdup(t, sizeof(struct pciusb_entry) * r.nb);
pci_find_modules(r);
return r;
}
-extern void pci_free(struct pci_entries entries) {
- int i;
- for (i = 0; i < entries.nb; i++) {
- struct pci_entry e = entries.entries[i];
- ifree(e.module);
- ifree(e.text);
- }
- ifree(entries.entries);
-}
-
diff --git a/pciusb.c b/pciusb.c
new file mode 100644
index 0000000..b5de8d8
--- /dev/null
+++ b/pciusb.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libldetect.h"
+#include "libldetect-private.h"
+#include "common.h"
+
+extern void pciusb_find_modules(struct pciusb_entries entries, const char *fpciusbtable) {
+ FILE *f;
+ char buf[2048];
+ int line;
+
+ if (!(f = fopen(fpciusbtable, "r"))) {
+ fprintf(stderr, "Missing pciusbtable (should be %s)\n", fpciusbtable);
+ exit(1);
+ }
+ for (line = 1; fgets(buf, sizeof(buf) - 1, f); line++) {
+ unsigned short vendor, device, subvendor, subdevice;
+ int offset, i;
+ int nb = sscanf(buf, "0x%hx\t0x%hx\t0x%hx\t0x%hx\t%n", &vendor, &device, &subvendor, &subdevice, &offset);
+ if (nb != 4) {
+ nb = sscanf(buf, "0x%hx\t0x%hx\t%n", &vendor, &device, &offset);
+ if (nb != 2 && buf[0] != '#') {
+ fprintf(stderr, "%s %d: bad line\n", fpciusbtable, line);
+ continue;
+ }
+ }
+ for (i = 0; i < entries.nb; i++) {
+ struct pciusb_entry *e = &entries.entries[i];
+ if (vendor == e->vendor && device == e->device &&
+ (nb != 4 || (subvendor == e->subvendor && subdevice == e->subdevice)) && !e->module) {
+ char *p = buf + offset + 1;
+ char *q = strchr(p, '\t');
+ if (q) {
+ q[-1] = 0;
+ q[strlen(q)-2] = 0;
+ e->module = strcmp(p, "unknown") ? strdup(p) : NULL;
+ e->text = strdup(q+2);
+ }
+ }
+ }
+ }
+}
+
+extern void pciusb_initialize(struct pciusb_entry *e) {
+ e->vendor = 0xffff;
+ e->device = 0xffff;
+ e->subvendor = 0xffff;
+ e->subdevice = 0xffff;
+ e->class = 0;
+ e->module = NULL;
+ e->text = NULL;
+}
+
+extern void pciusb_free(struct pciusb_entries entries) {
+ int i;
+ for (i = 0; i < entries.nb; i++) {
+ struct pciusb_entry e = entries.entries[i];
+ ifree(e.module);
+ ifree(e.text);
+ }
+ ifree(entries.entries);
+}
+
diff --git a/usb.c b/usb.c
new file mode 100644
index 0000000..fbb23a3
--- /dev/null
+++ b/usb.c
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libldetect.h"
+#include "libldetect-private.h"
+#include "common.h"
+
+static void usb_find_modules(struct pciusb_entries entries) {
+ pciusb_find_modules(entries, "/usr/share/ldetect-lst/usbtable");
+}
+
+extern struct pciusb_entries usb_probe(void) {
+ FILE *f;
+ char buf[512];
+ int line;
+ const char *file = "/proc/bus/usb/devices";
+ struct pciusb_entry t[100];
+ struct pciusb_entries r;
+ struct pciusb_entry *e = NULL;
+
+ if (!(f = fopen(file, "r"))) {
+ fprintf(stderr, "can't open %s\n", file);
+ exit(1);
+ }
+
+ for(r.nb = line = 0; fgets(buf, sizeof(buf) - 1, f) && r.nb < psizeof(t); line++) {
+ if (buf[0] == 'P') {
+ e = &t[r.nb++];
+ pciusb_initialize(e);
+
+ if (sscanf(buf, "P: Vendor=%hx ProdID=%hx", &e->vendor, &e->device) != 2) {
+ fprintf(stderr, "%s %d: unknown ``P'' line\n", file, line);
+ pciusb_initialize(e);
+ }
+ } else if (e && buf[0] == 'I' && e->class == 0) {
+ int class, prot = 0;
+ if (sscanf(buf, "I: If#=%*2d Alt=%*2d #EPs=%*2d Cls=%02x(%*5c) Sub=%*02x Prot=%02x", &class, &prot) == 2) {
+ /* we fake a class based on class and proto, subclass unneeded? */
+ e->class = class * 0x100 + prot;
+ } else {
+ fprintf(stderr, "%s %d: unknown ``I'' line\n", file, line);
+ }
+ } else if (e && buf[0] == 'S') {
+ int offset;
+ char dummy;
+ if (sscanf(buf, "S: Manufacturer=%n%c", &offset, &dummy) == 1) {
+ buf[strlen(buf) - 1] = '|'; /* replacing '\n' by '|' */
+ e->text = strdup(buf + offset);
+ } else if (sscanf(buf, "S: Product=%n%c", &offset, &dummy) == 1) {
+ if (!e->text) e->text = strdup("Unknown|");
+ buf[strlen(buf) - 1] = 0; /* removing '\n' */
+ e->text = realloc(e->text, strlen(e->text) + strlen(buf + offset) + 1);
+ strcat(e->text, buf + offset);
+ }
+ }
+ }
+ fclose(f);
+ r.entries = memdup(t, sizeof(struct pciusb_entry) * r.nb);
+
+ usb_find_modules(r);
+ return r;
+}
+