Index: cardd.h =================================================================== RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/cardd.h,v retrieving revision 1.20 diff -u -r1.20 cardd.h --- cardd.h 2000/04/05 18:39:21 1.20 +++ cardd.h 2000/04/05 21:11:38 @@ -139,11 +139,14 @@ EXTERN struct allocblk *pool_ioblks; /* I/O blocks in the pool */ EXTERN struct allocblk *pool_mem; /* Memory in the pool */ EXTERN int pool_irq[16]; /* IRQ allocations */ +EXTERN int irq_init[16]; /* initial 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 *mem_init; EXTERN bitstr_t *io_avail; +EXTERN bitstr_t *io_init; EXTERN int pccard_init_sleep; /* Time to sleep on init */ EXTERN int debug_level; Index: file.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/file.c,v retrieving revision 1.26 diff -u -r1.26 file.c --- file.c 2000/04/05 18:39:21 1.26 +++ file.c 2000/04/07 16:53:22 @@ -115,6 +115,41 @@ static void addcmd(struct cmd **); static void parse_card(int); +static void +delete_card(struct card *cp) +{ + struct ether *etherp, *ether_next; + struct card_config *configp, *config_next; + struct cmd *cmdp, *cmd_next; + + /* free characters */ + if (cp->manuf[0] != NULL) + free(cp->manuf); + if (cp->version[0] != NULL) + free(cp->version); + + /* free structures */ + for (etherp = cp->ether; etherp; etherp = ether_next) { + ether_next = etherp->next; + free(etherp); + } + for (configp = cp->config; configp; configp = config_next) { + config_next = configp->next; + free(configp); + } + for (cmdp = cp->insert; cmdp; cmdp = cmd_next) { + cmd_next = cmdp->next; + free(cmdp->line); + free(cmdp); + } + for (cmdp = cp->remove; cmdp; cmdp = cmd_next) { + cmd_next = cmdp->next; + free(cmdp->line); + free(cmdp); + } + free(cp); +} + /* * Read a file and parse the pcmcia configuration data. * After parsing, verify the links. @@ -122,20 +157,82 @@ void readfile(char *name) { - int i; - struct card *cp; + int i, inuse; + struct card *cp, *card_next; + struct card *genericp, *tail_gp; + struct card_config *configp; - in = fopen(name, "r"); - if (in == 0) { - logerr(name); - die("readfile"); + /* delete all card configuration data before we proceed */ + genericp = 0; + cp = cards; + cards = last_card = 0; + while (cp) { + card_next = cp->next; + + /* check whether this card is in use */ + inuse = 0; + for (configp = cp->config; configp; configp = configp->next) { + if (configp->inuse) { + inuse = 1; + break; + } + } + + /* + * don't delete entry in use for consistency. + * leave normal entry in the cards list, + * insert generic entry into the list after re-loading config files. + */ + if (inuse == 1) { + cp->next = 0; /* unchain from the cards list */ + switch (cp->deftype) { + case DT_VERS: + /* don't delete this entry for consistency */ + if (debug_level >= 1) { + logmsg("Card \"%s\"(\"%s\") is in use, " + "can't change configuration\n", + cp->manuf, cp->version); + } + /* add this to the card list */ + if (!last_card) { + cards = last_card = cp; + } else { + last_card->next = cp; + last_card = cp; + } + break; + + case DT_FUNC: + /* generic entry must be inserted to the list later */ + if (debug_level >= 1) { + logmsg("Generic entry is in use, " + "can't change configuration\n"); + } + cp->next = genericp; + genericp = cp; + break; + } + } else { + delete_card(cp); + } + + cp = card_next; } + for (i = 0; i < MAXINCLUDES; i++) { if (configfiles[i].filep) { fclose(configfiles[i].filep); configfiles[i].filep = NULL; + if (i > 0) { + free(configfiles[i].filename); + } } } + in = fopen(name, "r"); + if (in == 0) { + logerr(name); + die("readfile"); + } includes = 0; configfiles[includes].filep = in; filename = configfiles[includes].filename = name; @@ -146,6 +243,57 @@ logmsg("warning: card %s(%s) has no valid configuration\n", cp->manuf, cp->version); } + + /* insert generic entries in use into the top of generic entries */ + if (genericp) { + /* search tail of generic entries in use */ + for (tail_gp = genericp; tail_gp->next; tail_gp = tail_gp->next) + ; + + /* + * if the top of cards list is generic entry, + * insert generic entries in use before it. + */ + if (cards && cards->deftype == DT_FUNC) { + tail_gp->next = cards; + cards = genericp; + goto generic_done; + } + + /* search top of generic entries */ + for (cp = cards; cp; cp = cp->next) { + if (cp->next && cp->next->deftype == DT_FUNC) { + break; + } + } + + /* + * if we have generic entry in the cards list, + * insert generic entries in use into there. + */ + if (cp) { + tail_gp->next = cp->next; + cp->next = genericp; + goto generic_done; + } + + /* + * otherwise we don't have generic entries in + * cards list, just add them to the list. + */ + if (!last_card) { + cards = genericp; + } else { + last_card->next = genericp; + last_card = tail_gp; + } +generic_done: + } + + /* save the initial state of resource pool */ + bcopy(io_avail, io_init, bitstr_size(IOPORTS)); + bcopy(mem_avail, mem_init, bitstr_size(MEMBLKS)); + bcopy(pool_irq, irq_init, sizeof(pool_irq)); } static void Index: pccardd.8 =================================================================== RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/pccardd.8,v retrieving revision 1.18 diff -u -r1.18 pccardd.8 --- pccardd.8 2000/03/30 16:01:37 1.18 +++ pccardd.8 2000/04/05 21:11:38 @@ -119,6 +119,10 @@ This will change significantly when loadable kernel modules are supported. .Pp +SIGHUP causes +.Nm +to reload the configuration files. +.Pp The start options understood by .Nm are: @@ -150,7 +154,12 @@ .Sh FILES .Bl -tag -width /etc/defaults/pccard.conf -compact .It Pa /etc/defaults/pccard.conf +default configuration file .It Pa /etc/pccard.conf +user configuration file +.It Pa /var/run/pccardd.pid +process id of of the currently running +.Nm .El .Sh SEE ALSO .Xr pccard.conf 5 , Index: pccardd.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/pccardd.c,v retrieving revision 1.7 diff -u -r1.7 pccardd.c --- pccardd.c 2000/03/30 16:01:37 1.7 +++ pccardd.c 2000/04/05 21:11:38 @@ -29,6 +29,7 @@ "$FreeBSD: src/usr.sbin/pccard/pccardd/pccardd.c,v 1.7 2000/03/30 16:01:37 iwasaki Exp $"; #endif /* not lint */ +#include #include #include #include @@ -38,7 +39,87 @@ #include "cardd.h" char *config_file = "/etc/defaults/pccard.conf"; +static char *pid_file = "/var/run/pccardd.pid"; +/* SIGHUP signal handler */ +static void +restart(void) +{ + bitstr_t bit_decl(io_inuse, IOPORTS); + bitstr_t bit_decl(mem_inuse, MEMBLKS); + int irq_inuse[16]; + int i; + + bit_nclear(io_inuse, 0, IOPORTS-1); + bit_nclear(mem_inuse, 0, MEMBLKS-1); + bzero(irq_inuse, sizeof(irq_inuse)); + + /* compare the initial and current state of resource pool */ + for (i = 0; i < IOPORTS; i++) { + if (bit_test(io_init, i) == 1 && bit_test(io_avail, i) == 0) { + if (debug_level >= 1) { + logmsg("io 0x%x seems to be in use\n", i); + } + bit_set(io_inuse, i); + } + } + for (i = 0; i < MEMBLKS; i++) { + if (bit_test(mem_init, i) == 1 && bit_test(mem_avail, i) == 0) { + if (debug_level >= 1) { + logmsg("mem 0x%x seems to be in use\n", i); + } + bit_set(mem_inuse, i); + } + } + for (i = 0; i < 16; i++) { + if (irq_init[i] == 1 && pool_irq[i] == 0) { + if (debug_level >= 1) { + logmsg("irq %d seems to be in use\n", i); + } + irq_inuse[i] = 1; + } + } + + readfile(config_file); + + /* reflect used resources to managed resource pool */ + for (i = 0; i < IOPORTS; i++) { + if (bit_test(io_inuse, i) == 1) { + bit_clear(io_avail, i); + } + } + for (i = 0; i < MEMBLKS; i++) { + if (bit_test(mem_inuse, i) == 1) { + bit_clear(mem_avail, i); + } + } + for (i = 0; i < 16; i++) { + if (irq_inuse[i] == 1) { + pool_irq[i] = 0; + } + } +} + +/* SIGTERM/SIGINT signal handler */ +static void +term(int sig) +{ + logmsg("pccardd terminated: signal %d received", sig); + (void)unlink(pid_file); + exit(0); +} + +static void +write_pid() +{ + FILE *fp = fopen(pid_file, "w"); + + if (fp) { + fprintf(fp, "%d\n", getpid()); + fclose(fp); + } +} + /* * mainline code for cardd */ @@ -90,9 +171,11 @@ dodebug = 1; #endif io_avail = bit_alloc(IOPORTS); /* Only supports ISA ports */ + io_init = bit_alloc(IOPORTS); /* Mem allocation done in MEMUNIT units. */ mem_avail = bit_alloc(MEMBLKS); + mem_init = bit_alloc(MEMBLKS); readfile(config_file); if (doverbose) dump_config_file(); @@ -107,6 +190,12 @@ if (daemon(0, 0)) die("fork failed"); logmsg("pccardd started", NULL); + write_pid(); + + (void)signal(SIGINT, dodebug ? term : SIG_IGN); + (void)signal(SIGTERM, term); + (void)signal(SIGHUP, (void (*)(int))restart); + for (;;) { fd_set mask; FD_ZERO(&mask);