diff options
author | wollman <wollman@FreeBSD.org> | 1994-10-17 23:26:10 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1994-10-17 23:26:10 +0000 |
commit | 8f8aac0e4e1336af9c997acc4598309c12e5532d (patch) | |
tree | f35adf0851636ef6631861b56e1ea142284c0ca6 /usr.sbin/lsdev | |
download | FreeBSD-src-8f8aac0e4e1336af9c997acc4598309c12e5532d.zip FreeBSD-src-8f8aac0e4e1336af9c997acc4598309c12e5532d.tar.gz |
lsdev(8), a user-land utility to query the device configuration database
managed by kern_devconf.c. A useful feature is that the following
script generates almost well-formed config-file lines for all ISA devices
in the system:
lsdev -t isa | awk '{ print "device $0" }'
lsdev -t disk | awk '{ print "disk $0" }'
Diffstat (limited to 'usr.sbin/lsdev')
-rw-r--r-- | usr.sbin/lsdev/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/lsdev/i386.c | 183 | ||||
-rw-r--r-- | usr.sbin/lsdev/lsdev.8 | 61 | ||||
-rw-r--r-- | usr.sbin/lsdev/lsdev.c | 155 | ||||
-rw-r--r-- | usr.sbin/lsdev/lsdev.h | 16 |
5 files changed, 423 insertions, 0 deletions
diff --git a/usr.sbin/lsdev/Makefile b/usr.sbin/lsdev/Makefile new file mode 100644 index 0000000..061a86f --- /dev/null +++ b/usr.sbin/lsdev/Makefile @@ -0,0 +1,8 @@ +# $Id$ + +PROG= lsdev +MAN8= lsdev.8 +SRCS= lsdev.c ${MACHINE}.c +CFLAGS+= -I${.CURDIR}/../../sys + +.include <bsd.prog.mk> diff --git a/usr.sbin/lsdev/i386.c b/usr.sbin/lsdev/i386.c new file mode 100644 index 0000000..513284d --- /dev/null +++ b/usr.sbin/lsdev/i386.c @@ -0,0 +1,183 @@ +#include "lsdev.h" +#include <stdio.h> +#include <string.h> + +static void print_isa(struct devconf *); +static void print_eisa(struct devconf *); +static void print_pci(struct devconf *); +static void print_scsi(struct devconf *); +static void print_disk(struct devconf *); + +void +print(struct devconf *dc) +{ + if(vflag) + printf("%d: ", dc->dc_number); + + switch(dc->dc_devtype) { + case MDDT_CPU: + printf("CPU on %s", dc->dc_parent); + break; + case MDDT_ISA: + if(dc->dc_datalen >= ISA_EXTERNALLEN) { + print_isa(dc); + } else { +printit: + printf("%s%d on %s", + dc->dc_name, dc->dc_unit, dc->dc_parent); + } + break; + case MDDT_EISA: + if(dc->dc_datalen >= EISA_EXTERNALLEN) { + print_eisa(dc); + } else { + goto printit; + } + break; + case MDDT_PCI: + if(dc->dc_datalen >= PCI_EXTERNALLEN) { + print_pci(dc); + } else { + goto printit; + } + break; + case MDDT_SCSI: + if(dc->dc_datalen >= SCSI_EXTERNALLEN) { + print_scsi(dc); + } else { + goto printit; + } + break; + case MDDT_DISK: + if(dc->dc_datalen >= DISK_EXTERNALLEN) { + print_disk(dc); + } else { + goto printit; + } + break; + + default: + if(dc->dc_devtype >= NDEVTYPES) { + printf("%s%d (#%d) on %s", + dc->dc_name, dc->dc_unit, dc->dc_devtype, + dc->dc_parent); + } else { + printf("%s%d (%s) on %s", + dc->dc_name, dc->dc_unit, + devtypes[dc->dc_devtype], dc->dc_parent); + } + break; + } + fputc('\n', stdout); +} + +static void +print_isa(struct devconf *dc) +{ + struct isa_device *id = (struct isa_device *)dc->dc_data; + + printf("%s%d on %s", dc->dc_name, dc->dc_unit, dc->dc_parent); + + if(vflag) { + printf(" (id %d)", id->id_id); + } + + if(id->id_iobase) { + if(id->id_iobase < 0) { + printf(" port ?"); + } else { + printf(" port 0x%x", id->id_iobase); + } + } + + if(id->id_irq) { + int bit = ffs(id->id_irq) - 1; + + if(id->id_irq & ~(1 << bit)) { + printf(" irq ?"); + } else { + printf(" irq %d", bit); + } + } + + if(id->id_drq) { + if(id->id_drq < 0) { + printf(" drq ?"); + } else { + printf(" drq %d", id->id_drq); + } + } + + if(id->id_maddr) { + if((unsigned long)id->id_maddr == ~0UL) { + printf(" iomem ?"); + } else { + printf(" iomem 0x%lx", (unsigned long)id->id_maddr); + } + } + + if(id->id_msize) { + if(id->id_msize < 0) { + printf(" iosiz ?", id->id_msize); + } else { + printf(" iosiz %d", id->id_msize); + } + } + + if(id->id_flags) { + printf(" flags 0x%x", id->id_flags); + } +} + +static void +print_eisa(struct devconf *dc) +{ + int *slotp = (int *)&dc->dc_data[ISA_EXTERNALLEN]; + print_isa(dc); + if(vflag) { + printf(" (slot %d)", *slotp); + } +} + +static void +print_pci(struct devconf *dc) +{ + struct pci_device *pd = (struct pci_device *)dc->dc_data; + + /* + * Unfortunately, the `pci_device' struct is completely + * useless. We will have to develop a unique structure + * for this task eventually, unless the existing one can + * be made to serve. + */ + + printf("%s%d on %s", dc->dc_name, dc->dc_unit, dc->dc_parent); +} + +static void +print_scsi(struct devconf *dc) +{ + struct scsi_link *sl = (struct scsi_link *)dc->dc_data; + + printf("%s%d on SCSI bus %d:%d:%d", + dc->dc_name, dc->dc_unit, sl->scsibus, sl->target, + sl->lun); + if(vflag) { + if(sl->flags & SDEV_MEDIA_LOADED) + printf(" (ready)"); + if(sl->flags & SDEV_OPEN) + printf(" (open)"); + if(sl->flags & SDEV_BOUNCE) + printf(" (bounce)"); + } +} + +static void +print_disk(struct devconf *dc) +{ + int *slavep = (int *)dc->dc_data; + + printf("%s%d on %s drive %d", + dc->dc_name, dc->dc_unit, dc->dc_parent, *slavep); +} + diff --git a/usr.sbin/lsdev/lsdev.8 b/usr.sbin/lsdev/lsdev.8 new file mode 100644 index 0000000..bafbddf --- /dev/null +++ b/usr.sbin/lsdev/lsdev.8 @@ -0,0 +1,61 @@ +.\" $Id: lsvfs.1,v 1.1 1994/09/22 01:25:56 wollman Exp $ +.\" Garrett A. Wollman, October 1994 +.\" This file is in the public domain. +.\" +.Dd October 17, 1994 +.Dt LSDEV 1 +.Os +.Sh NAME +.Nm lsdev +.Nd list configured devices +.Sh SYNOPSIS +.Nm lsdev +.Op Fl t Ar type +.Op Fl v +.Op Ar class Ns Op unit +.Sh DESCRIPTION +The +.Nm lsdev +utility lists devices configured in the current system, in a +machine-dependent manner. The +.Fl t +flag can be used to restrict the listing to a specific +.Ar type +of device; +the types available vary from machine to machine. (Specifying an +invalid type will cause a list of valid types to be printed.) The +.Fl v +flag requests more verbose output. The optional +.Ar class +argument requests information on a particular class of devices (e.g., +.Dq Li wdc +or +.No Do Li ie Dc Ns ). +If no +.Ar unit +is specified, all units of the specified class will be listed. +.Pp +The +.Xr sysctl 3 +mechanism is used to retrieve information from the kernel about which +devices are configured. +.Sh FILES +.Bl -tag -width <machine/devconf.h> +.It Aq sys/devconf.h +defines the structure examined by +.Nm +.It Aq machine/devconf.h +defines the machine-dependent parts of the structure, including the +supported device type names +.El +.Sh SEE ALSO +.\" .Xr chdev 8 +.Xr sysctl 3 +.Sh BUGS +Not all devices have the proper support implmented yet. +.Sh HISTORY +An +.Nm +comand appeared in +.Tn FreeBSD +2.0. diff --git a/usr.sbin/lsdev/lsdev.c b/usr.sbin/lsdev/lsdev.c new file mode 100644 index 0000000..168d76f --- /dev/null +++ b/usr.sbin/lsdev/lsdev.c @@ -0,0 +1,155 @@ +#include "lsdev.h" +#include <stdio.h> +#include <stdlib.h> +#include <err.h> +#include <ctype.h> +#include <string.h> + +const char *const devtypes[] = DEVTYPENAMES; +int vflag = 0; +const char *whoami; + +static void usage(void); +static void badtype(const char *); +static void badname(const char *); + +int +main(int argc, char **argv) +{ + struct devconf *dc = 0; + size_t size, osize; + int ndevs, i; + int mib[8]; + int c; + int showonlytype = -1; + int showonlydev = 0; + char showonlydevclass[MAXDEVNAME]; + int showonlydevunit = -1; + + whoami = argv[0]; + + while((c = getopt(argc, argv, "t:v")) != EOF) { + switch(c) { + case 't': + showonlytype = findtype(optarg); + if(showonlytype < 0) + badtype(optarg); + break; + case 'v': + vflag++; + break; + default: + usage(); + break; + } + } + + if(argc - optind > 1) { + usage(); + } + + if(argv[optind]) { + char *s = &argv[optind][strlen(argv[optind])]; + + if(s - argv[optind] > MAXDEVNAME) + badname(argv[optind]); + s--; /* step over null */ + while(s > argv[optind] && isdigit(*s)) + s--; + s++; + if(*s) { + showonlydevunit = atoi(s); + *s = '\0'; + } else { + showonlydevunit = -1; + } + + strcpy(showonlydevclass, argv[optind]); + showonlydev = 1; + } + + mib[0] = CTL_HW; + mib[1] = HW_DEVCONF; + mib[2] = DEVCONF_NUMBER; + + size = sizeof ndevs; + if(sysctl(mib, 3, &ndevs, &size, 0, 0) < 0) { + err(1, "sysctl(hw.devconf.number)"); + } + osize = 0; + + for(i = 1; i <= ndevs; i++) { + mib[2] = i; + if(sysctl(mib, 3, 0, &size, 0, 0) < 0) { + /* + * Probably a deleted device; just go on to the next + * one. + */ + continue; + } + if(size > osize) { + dc = realloc(dc, size); + if(!dc) { + err(2, "realloc(%lu)", (unsigned long)size); + } + } + if(sysctl(mib, 3, dc, &size, 0, 0) < 0) { + err(1, "sysctl(hw.devconf.%d)", i); + } + if(!showonlydev && showonlytype < 0) { + print(dc); + } else if(showonlydev) { + if(!strcmp(showonlydevclass, dc->dc_name) + && (showonlydevunit < 0 || + showonlydevunit == dc->dc_unit)) + print(dc); + } else if(showonlytype == dc->dc_devtype) { + print(dc); + } + osize = size; + } + return 0; +} + +static void +usage(void) +{ + fprintf(stderr, + "usage:\n" + "\t%s [-t type] [-v] [name]\n", + whoami); + exit(-1); +} + +int +findtype(const char *name) +{ + int i; + for(i = 0; devtypes[i]; i++) { + if(!strcmp(name, devtypes[i])) + return i; + } + return -1; +} + +static void +badtype(const char *name) +{ + int i; + + fprintf(stderr, + "%s: invalid device type `%s'\n", whoami, name); + fprintf(stderr, + "%s: valid types are: ", whoami); + for(i = 0; devtypes[i]; i++) { + fprintf(stderr, "%s`%s'", i ? ", " : "", devtypes[i]); + } + fputs(".\n", stderr); + exit(-1); +} + +static void +badname(const char *name) +{ + errx(3, "invalid device name `%s'", name); +} diff --git a/usr.sbin/lsdev/lsdev.h b/usr.sbin/lsdev/lsdev.h new file mode 100644 index 0000000..1ea3910 --- /dev/null +++ b/usr.sbin/lsdev/lsdev.h @@ -0,0 +1,16 @@ +/* + * Declarations for lsdev(8). + */ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/time.h> +#include <sys/proc.h> +#include <vm/vm.h> +#include <sys/sysctl.h> +#include <sys/devconf.h> + +extern const char *const devtypes[]; /* device type array */ +extern void print(struct devconf *); /* machine-specific print routine */ +extern int vflag; + +extern int findtype(const char *); /* get device type by name */ |