diff --git a/usr.sbin/pccard/pccardd/cardd.h b/usr.sbin/pccard/pccardd/cardd.h index a0de46813e2a..41d68679cc54 100644 --- a/usr.sbin/pccard/pccardd/cardd.h +++ b/usr.sbin/pccard/pccardd/cardd.h @@ -139,6 +139,7 @@ EXTERN struct allocblk *pool_mem; /* Memory in the pool */ EXTERN int pool_irq[16]; /* IRQ allocations */ EXTERN struct driver *drivers; /* List of drivers */ EXTERN struct card *cards; +EXTERN struct card *last_card; EXTERN bitstr_t *mem_avail; EXTERN bitstr_t *io_avail; EXTERN int pccard_init_sleep; /* Time to sleep on init */ @@ -173,6 +174,7 @@ void readfile(char *); #define BIT2MEM(x) (((x)*MEMUNIT)+MEMSTART) #define MAXINCLUDES 10 +#define MAXERRORS 10 /* * Config index types diff --git a/usr.sbin/pccard/pccardd/file.c b/usr.sbin/pccard/pccardd/file.c index fcd65b7173d0..5e29ddd5a422 100644 --- a/usr.sbin/pccard/pccardd/file.c +++ b/usr.sbin/pccard/pccardd/file.c @@ -37,7 +37,12 @@ static const char rcsid[] = static FILE *in; static int includes = 0; -static FILE *files[MAXINCLUDES] = {NULL, }; +static struct { + FILE *filep; + char *filename; + int lineno; +} configfiles[MAXINCLUDES] = {{NULL, NULL, 0}, }; + static int pushc, pusht; static int lineno; static char *filename; @@ -114,12 +119,15 @@ readfile(char *name) die("readfile"); } for (i = 0; i < MAXINCLUDES; i++) { - if (files[i]) { - fclose(files[i]); - files[i] = NULL; + if (configfiles[i].filep) { + fclose(configfiles[i].filep); + configfiles[i].filep = NULL; } } - files[includes = 0] = in; + includes = 0; + configfiles[includes].filep = in; + filename = configfiles[includes].filename = name; + parsefile(); for (cp = cards; cp; cp = cp->next) { if (cp->config == 0) @@ -132,50 +140,54 @@ static void parsefile(void) { int i; - int irq_init = 0; - int io_init = 0; - struct allocblk *bp; + int errors = 0; + struct allocblk *bp, *next; char *incl; pushc = 0; lineno = 1; - for (i = 0; i < 16 ; i++) - if (pool_irq[i]) { - irq_init = 1; - break; - } for (;;) switch (keyword(next_tok())) { case KWD_EOF: /* EOF */ return; case KWD_IO: - /* reserved I/O blocks */ - while ((bp = ioblk_tok(0)) != 0) { - if (!io_init) { - if (bp->size == 0 || bp->addr == 0) { - free(bp); - continue; - } - bit_nset(io_avail, bp->addr, - bp->addr + bp->size - 1); - bp->next = pool_ioblks; - pool_ioblks = bp; - } + /* override reserved I/O blocks */ + bit_nclear(io_avail, 0, IOPORTS-1); + for (bp = pool_ioblks; bp; bp = next) { + next = bp->next; + free(bp); + } + pool_ioblks = NULL; + + while ((bp = ioblk_tok(0)) != 0) { + if (bp->size == 0 || bp->addr == 0) { + free(bp); + continue; + } + bit_nset(io_avail, bp->addr, + bp->addr + bp->size - 1); + bp->next = pool_ioblks; + pool_ioblks = bp; } - io_init = 1; pusht = 1; break; case KWD_IRQ: - /* reserved irqs */ + /* override reserved irqs */ + bzero(pool_irq, sizeof(pool_irq)); while ((i = irq_tok(0)) > 0) - if (!irq_init) - pool_irq[i] = 1; - irq_init = 1; + pool_irq[i] = 1; pusht = 1; break; case KWD_MEMORY: - /* reserved memory blocks. */ + /* override reserved memory blocks. */ + bit_nclear(mem_avail, 0, MEMBLKS-1); + for (bp = pool_mem; bp; bp = next) { + next = bp->next; + free(bp); + } + pool_mem = NULL; + while ((bp = memblk_tok(0)) != 0) { if (bp->size == 0 || bp->addr == 0) { free(bp); @@ -204,6 +216,10 @@ parsefile(void) default: error("syntax error"); pusht = 0; + if (errors++ >= MAXERRORS) { + error("too many errors, giving up"); + return; + } break; } } @@ -228,8 +244,13 @@ parse_card(void) cp->manuf = man; cp->version = vers; cp->reset_time = 50; - cp->next = cards; - cards = cp; + cp->next = 0; + if (!last_card) { + cards = last_card = cp; + } else { + last_card->next = cp; + last_card = cp; + } for (;;) { switch (keyword(next_tok())) { case KWD_CONFIG: @@ -367,6 +388,11 @@ ioblk_tok(int force) struct allocblk *io; int i, j; + /* ignore the keyword to allow separete blocks in multiple lines */ + if (keyword(next_tok()) != KWD_IO) { + pusht = 1; + } + if ((i = num_tok()) >= 0) { if (strcmp("-", next_tok()) || (j = num_tok()) < 0 || j < i) { error("I/O block format error"); @@ -399,6 +425,11 @@ memblk_tok(int force) struct allocblk *mem; int i, j; + /* ignore the keyword to allow separete blocks in multiple lines */ + if (keyword(next_tok()) != KWD_MEMORY) { + pusht = 1; + } + if ((i = num_tok()) >= 0) { if ((j = num_tok()) < 0) error("illegal memory block"); @@ -431,6 +462,11 @@ irq_tok(int force) { int i; + /* ignore the keyword to allow separete blocks in multiple lines */ + if (keyword(next_tok()) != KWD_IRQ) { + pusht = 1; + } + if (strcmp("?", next_tok()) == 0 && force) return (0); pusht = 1; @@ -731,8 +767,11 @@ _next_tok(void) case EOF: if (includes) { fclose(in); + /* go back to previous config file */ includes--; - in = files[includes]; + in = configfiles[includes].filep; + filename = configfiles[includes].filename; + lineno = configfiles[includes].lineno; return _next_tok(); /* recursive */ } if (p != buf) { @@ -773,17 +812,53 @@ getline(void) * Include configuration file */ static void -file_include(char *filename) +file_include(char *incl) { - FILE *fp; + int i, included; + FILE *fp; - includes++; + /* check nesting overflow */ if (includes >= MAXINCLUDES) { - error("include nesting overflow"); + if (debug_level >= 1) { + logmsg("%s: include nesting overflow " + "at line %d, near %s\n", filename, lineno, incl); + } + free(incl); + goto out; } - if (!(fp = fopen(filename, "r"))) { - error("can't open include file"); - includes--; + + /* check recursive inclusion */ + for (i = 0, included = 0; i <= includes; i++) { + if (strcmp(incl, configfiles[i].filename) == 0) { + included = 1; + break; + } } - in = files[includes] = fp; + if (included == 1) { + if (debug_level >= 1) { + logmsg("%s: can't include the same file twice " + "at line %d, near %s\n", filename, lineno, incl); + } + free(incl); + goto out; + } + + if (!(fp = fopen(incl, "r"))) { + if (debug_level >= 1) { + logmsg("%s: can't open include file " + "at line %d, near %s\n", filename, lineno, incl); + } + free(incl); + goto out; + } + + /* save line number of the current config file */ + configfiles[includes].lineno = lineno; + + /* now we start parsing new config file */ + includes++; + in = configfiles[includes].filep = fp; + filename = configfiles[includes].filename = incl; +out: + return; } diff --git a/usr.sbin/pccard/pccardd/pccard.conf.5 b/usr.sbin/pccard/pccardd/pccard.conf.5 index 999f18e89acb..1aaf4c613b2c 100644 --- a/usr.sbin/pccard/pccardd/pccard.conf.5 +++ b/usr.sbin/pccard/pccardd/pccard.conf.5 @@ -54,6 +54,17 @@ and The latter two may appear in any order, and may be interspersed as desired. .Pp +The +.Pa /etc/pccard.conf +file is included from the file +.Pa /etc/defaults/pccard.conf , +which contains the default resource pool settings and +pccard identifiers database. +The user specific configuration can be specified in +.Pa /etc/rc.conf +when the user wishes to override these defaults and/or +add additional entries. +.Pp Each PC-CARD card contains configuration tuples that provide the manufacturer and card version; these are used to identify the card specification in the configuration @@ -213,11 +224,14 @@ card "XYZZY" "FAX/1.0" .Ed .Sh FILES -.Bl -tag -width /etc/pccard.conf -compact -.It Pa /etc/pccard.conf +.Bl -tag -width /etc/defaults/pccard.conf -compact +.It Pa /etc/defaults/pccard.conf The .Xr pccardd 8 -configuration file. +default configuration file. +.It Pa /etc/pccard.conf +The +user configuration file. .El .Sh SEE ALSO .Xr pccardd 8 diff --git a/usr.sbin/pccard/pccardd/pccardd.8 b/usr.sbin/pccard/pccardd/pccardd.8 index 60132557aa40..28a731915238 100644 --- a/usr.sbin/pccard/pccardd/pccardd.8 +++ b/usr.sbin/pccard/pccardd/pccardd.8 @@ -46,7 +46,10 @@ and removal of PC-CARD cards. When started, .Nm will read the configuration file (default name -.Pa /etc/pccard.conf ) +.Pa /etc/defaults/pccard.conf +which includes +.Pa /etc/pccard.conf +as the user configuration file) and scans the available PC-CARD slots for cards. .Nm Pccardd then waits for @@ -130,11 +133,13 @@ of it. Delays running as a daemon until after the cards have been probed and attached. .It Fl i Ar IRQ Configures an available IRQ. It overrides the "irq" line in +.Pa /etc/defaults/pccard.conf +and .Pa /etc/pccard.conf . .It Fl f Ar configfile Specifies a different configuration file to be used in placed of the default file -.Pa /etc/pccard.conf . +.Pa /etc/defaults/pccard.conf . The file format is detailed in .Xr pccard.conf 5 , and lists the PC-CARD cards recognized by @@ -143,7 +148,8 @@ and the kernel drivers and devices that are used to interface to the card. .Pp .Sh FILES -.Bl -tag -width /etc/pccard.conf -compact +.Bl -tag -width /etc/defaults/pccard.conf -compact +.It Pa /etc/defaults/pccard.conf .It Pa /etc/pccard.conf .El .Sh SEE ALSO diff --git a/usr.sbin/pccard/pccardd/pccardd.c b/usr.sbin/pccard/pccardd/pccardd.c index 6a61bb9f8b89..1e905377f735 100644 --- a/usr.sbin/pccard/pccardd/pccardd.c +++ b/usr.sbin/pccard/pccardd/pccardd.c @@ -37,7 +37,7 @@ static const char rcsid[] = #define EXTERN #include "cardd.h" -char *config_file = "/etc/pccard.conf"; +char *config_file = "/etc/defaults/pccard.conf"; /* * mainline code for cardd @@ -53,6 +53,7 @@ main(int argc, char *argv[]) debug_level = 0; pccard_init_sleep = 5000000; + cards = last_card = 0; while ((count = getopt(argc, argv, ":dvf:i:z")) != -1) { switch (count) { case 'd':