summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pccard
diff options
context:
space:
mode:
authoriwasaki <iwasaki@FreeBSD.org>2000-04-08 05:19:44 +0000
committeriwasaki <iwasaki@FreeBSD.org>2000-04-08 05:19:44 +0000
commit6927b5bc642dff72a604d0dd729706a8ea68232d (patch)
treeea0c8e18b101f2d1d34697a764eb64378e58aaf8 /usr.sbin/pccard
parent89ff8e1b55fe7a4a26573ebd73bcd7bc3aa93b67 (diff)
downloadFreeBSD-src-6927b5bc642dff72a604d0dd729706a8ea68232d.zip
FreeBSD-src-6927b5bc642dff72a604d0dd729706a8ea68232d.tar.gz
Add restart capability by SIGHUP. On restart, working configuration
(resource and card configuration being used) is to be maintained for consistency. Part of resource pool re-initialization would be rewrite later using on Warner-san's hints driver API :-) Reviewed by: nate, imp and -nomads ML in Japan. Obtained from: http://www.freebsd.org/~iwasaki/pccard/pccardd-signal.diff Commited at: BSD HANAMI Party 2000 in Japan
Diffstat (limited to 'usr.sbin/pccard')
-rw-r--r--usr.sbin/pccard/pccardd/cardd.h3
-rw-r--r--usr.sbin/pccard/pccardd/file.c160
-rw-r--r--usr.sbin/pccard/pccardd/pccardd.89
-rw-r--r--usr.sbin/pccard/pccardd/pccardd.c89
4 files changed, 255 insertions, 6 deletions
diff --git a/usr.sbin/pccard/pccardd/cardd.h b/usr.sbin/pccard/pccardd/cardd.h
index a180ca6..36d712d 100644
--- a/usr.sbin/pccard/pccardd/cardd.h
+++ b/usr.sbin/pccard/pccardd/cardd.h
@@ -139,11 +139,14 @@ struct slot {
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;
diff --git a/usr.sbin/pccard/pccardd/file.c b/usr.sbin/pccard/pccardd/file.c
index 098d2c4..2d15704 100644
--- a/usr.sbin/pccard/pccardd/file.c
+++ b/usr.sbin/pccard/pccardd/file.c
@@ -115,6 +115,41 @@ static void file_include(char *);
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 @@ static void parse_card(int);
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;
+
+ /* 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;
+ }
+ }
- in = fopen(name, "r");
- if (in == 0) {
- logerr(name);
- die("readfile");
+ /*
+ * 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 @@ readfile(char *name)
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
diff --git a/usr.sbin/pccard/pccardd/pccardd.8 b/usr.sbin/pccard/pccardd/pccardd.8
index 28a7319..9214a04 100644
--- a/usr.sbin/pccard/pccardd/pccardd.8
+++ b/usr.sbin/pccard/pccardd/pccardd.8
@@ -119,6 +119,10 @@ parameters.
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 @@ interface to the card.
.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 ,
diff --git a/usr.sbin/pccard/pccardd/pccardd.c b/usr.sbin/pccard/pccardd/pccardd.c
index 1e90537..d476513 100644
--- a/usr.sbin/pccard/pccardd/pccardd.c
+++ b/usr.sbin/pccard/pccardd/pccardd.c
@@ -29,6 +29,7 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -38,6 +39,86 @@ static const char rcsid[] =
#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 @@ main(int argc, char *argv[])
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 @@ main(int argc, char *argv[])
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);
OpenPOWER on IntegriCloud