Index: sys/pccard/cardinfo.h diff -u sys/pccard/cardinfo.h.orig sys/pccard/cardinfo.h --- sys/pccard/cardinfo.h.orig Fri Jul 21 00:28:44 2000 +++ sys/pccard/cardinfo.h Sun Jul 23 03:31:57 2000 @@ -58,7 +58,7 @@ /* * Slot states for PIOCGSTATE */ -enum cardstate { noslot, empty, suspend, filled }; +enum cardstate { noslot, empty, suspend, filled, inactive }; /* * Descriptor structure for memory map. Index: sys/pccard/pccard.c diff -u sys/pccard/pccard.c.orig sys/pccard/pccard.c --- sys/pccard/pccard.c.orig Tue May 23 12:56:58 2000 +++ sys/pccard/pccard.c Mon Jul 24 03:38:17 2000 @@ -318,7 +318,7 @@ * The slot and devices are disabled, but the * data structures are not unlinked. */ - if (slt->state == filled) { + if (slt->state == filled || slt->state == inactive) { slt->state = empty; disable_slot_to(slt); } @@ -597,11 +597,14 @@ if (!pwval) { if (slt->state != filled) return EINVAL; + pccard_event(slt, card_removed); + slt->state = inactive; } else { - if (slt->state != empty) + if (slt->state != empty && slt->state != inactive) return EINVAL; + slt->state = empty; + pccard_event(slt, card_inserted); } - pccard_event(slt, pwval == 0 ? card_removed : card_inserted); break; case PIOCSBEEP: if (pccard_beep_select(*(int *)data)) { Index: usr.sbin/pccard/pccardd/Makefile diff -u usr.sbin/pccard/pccardd/Makefile.orig usr.sbin/pccard/pccardd/Makefile --- usr.sbin/pccard/pccardd/Makefile.orig Fri Feb 27 17:19:23 1998 +++ usr.sbin/pccard/pccardd/Makefile Sat Jul 22 05:02:03 2000 @@ -1,12 +1,12 @@ # Makefile for pccardd PROG= pccardd -SRCS= pccardd.c cardd.c file.c util.c readcis.c printcis.c +SRCS= pccardd.c cardd.c file.c util.c readcis.c printcis.c server.c MAN8= pccardd.8 MAN5= pccard.conf.5 DPADD= ${LIBUTIL} LDADD= -lutil -CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../pccardc +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../pccardc -DSERVER .include .PATH: ${.CURDIR}/../pccardc Index: usr.sbin/pccard/pccardd/cardd.c diff -u usr.sbin/pccard/pccardd/cardd.c.orig usr.sbin/pccard/pccardd/cardd.c --- usr.sbin/pccard/pccardd/cardd.c.orig Tue Jul 18 13:59:39 2000 +++ usr.sbin/pccard/pccardd/cardd.c Mon Jul 24 03:26:43 2000 @@ -49,6 +49,8 @@ static void read_ether(struct slot *); static void read_ether_attr2(struct slot *sp); +struct slot *slots; + /* * Dump configuration file data. */ @@ -105,7 +107,7 @@ { char name[128]; int i, fd; - struct slot *slots, *sp; + struct slot *sp; slots = NULL; for (i = 0; i < MAXSLOT; i++) { @@ -158,6 +160,7 @@ } switch (state.state) { case empty: + case inactive: case noslot: /* Debounce potentially incorrectly reported removals */ if (state.laststate == filled || state.laststate == suspend) @@ -173,6 +176,10 @@ /* ignored */ break; } +#ifdef SERVER + sp->state = state.state; + stat_changed(sp); +#endif /* SERVER */ } /* Index: usr.sbin/pccard/pccardd/cardd.h diff -u usr.sbin/pccard/pccardd/cardd.h.orig usr.sbin/pccard/pccardd/cardd.h --- usr.sbin/pccard/pccardd/cardd.h.orig Tue Jul 18 13:59:39 2000 +++ usr.sbin/pccard/pccardd/cardd.h Sat Jul 22 05:02:03 2000 @@ -139,6 +139,11 @@ #define AFLAGS (IO_ASSIGNED | MEM_ASSIGNED | IRQ_ASSIGNED) #define CFLAGS (EADDR_CONFIGED | WL_CONFIGED) +#ifdef SERVER +EXTERN struct slot *slots, *current_slot; +EXTERN int slen; +#endif + 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 */ Index: usr.sbin/pccard/pccardd/pccardd.c diff -u usr.sbin/pccard/pccardd/pccardd.c.orig usr.sbin/pccard/pccardd/pccardd.c --- usr.sbin/pccard/pccardd/pccardd.c.orig Thu Jun 29 17:23:26 2000 +++ usr.sbin/pccard/pccardd/pccardd.c Sat Jul 22 05:05:15 2000 @@ -35,12 +35,25 @@ #include #include #include +#ifdef SERVER +#include +#include +#endif #define EXTERN #include "cardd.h" char *config_file = "/etc/defaults/pccard.conf"; static char *pid_file = "/var/run/pccardd.pid"; +#ifdef SERVER +/* + * pathname of UNIX-domain socket + */ +static char *socket_name = "/var/tmp/.pccardd"; +static char *sock = 0; +static int server_sock; +#endif + /* SIGHUP signal handler */ static void restart(void) @@ -49,6 +62,9 @@ bitstr_t bit_decl(mem_inuse, MEMBLKS); int irq_inuse[16]; int i; +#ifdef SERVER + struct sockaddr_un sun; +#endif bit_nclear(io_inuse, 0, IOPORTS-1); bit_nclear(mem_inuse, 0, MEMBLKS-1); @@ -98,6 +114,24 @@ pool_irq[i] = 0; } } +#ifdef SERVER + close(server_sock); + if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0) + die("socket failed"); + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_UNIX; + if (sock) { + socket_name = sock; + } + strcpy(sun.sun_path, socket_name); + slen = SUN_LEN(&sun); + (void)unlink(socket_name); + if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0) + die("bind failed"); + chown(socket_name, 0, 5); /* XXX - root.operator */ + chmod(socket_name, 0660); + set_socket(server_sock); +#endif /* SERVER */ } /* SIGTERM/SIGINT signal handler */ @@ -127,18 +161,24 @@ int main(int argc, char *argv[]) { - struct slot *slots, *sp; + struct slot *sp; int count, dodebug = 0; int delay = 0; int irq_arg[16]; int irq_specified = 0; int i; +#ifdef SERVER + struct sockaddr_un sun; +#define COM_OPTS ":dvf:s:i:z" +#else +#define COM_OPTS ":dvf:i:z" +#endif bzero(irq_arg, sizeof(irq_arg)); debug_level = 0; pccard_init_sleep = 5000000; cards = last_card = 0; - while ((count = getopt(argc, argv, ":dvf:i:z")) != -1) { + while ((count = getopt(argc, argv, COM_OPTS)) != -1) { switch (count) { case 'd': setbuf(stdout, 0); @@ -160,6 +200,11 @@ irq_arg[i] = 1; irq_specified = 1; break; +#ifdef SERVER + case 's': + sock = optarg; + break; +#endif /* SERVER */ case 'z': delay = 1; break; @@ -200,23 +245,54 @@ logmsg("pccardd started", NULL); write_pid(); +#ifdef SERVER + if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0) + die("socket failed"); + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_UNIX; + if (sock) { + socket_name = sock; + } + strcpy(sun.sun_path, socket_name); + slen = SUN_LEN(&sun); + (void)unlink(socket_name); + if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0) + die("bind failed"); + chown(socket_name, 0, 5); /* XXX - root.operator */ + chmod(socket_name, 0660); + set_socket(server_sock); +#endif /* SERVER */ + (void)signal(SIGINT, dodebug ? term : SIG_IGN); (void)signal(SIGTERM, term); (void)signal(SIGHUP, (void (*)(int))restart); for (;;) { - fd_set mask; - FD_ZERO(&mask); + fd_set rmask, emask; + FD_ZERO(&emask); +#ifdef SERVER + FD_ZERO(&rmask); +#endif /* SERVER */ for (sp = slots; sp; sp = sp->next) - FD_SET(sp->fd, &mask); - count = select(32, 0, 0, &mask, 0); + FD_SET(sp->fd, &emask); +#ifdef SERVER + FD_SET(server_sock, &rmask); + count = select(32, &rmask, 0, &emask, 0); +#else /* SERVER */ + count = select(32, 0, 0, &emask, 0); +#endif /* SERVER */ if (count == -1) { logerr("select"); continue; } - if (count) + if (count) { for (sp = slots; sp; sp = sp->next) - if (FD_ISSET(sp->fd, &mask)) + if (FD_ISSET(sp->fd, &emask)) slot_change(sp); +#ifdef SERVER + if (FD_ISSET(server_sock, &rmask)) + process_client(); +#endif /* SERVER */ + } } } Index: usr.sbin/pccard/pccardd/server.c diff -u usr.sbin/pccard/pccardd/server.c.orig usr.sbin/pccard/pccardd/server.c --- usr.sbin/pccard/pccardd/server.c.orig Sat Jul 22 05:02:03 2000 +++ usr.sbin/pccard/pccardd/server.c Mon Jul 24 03:41:09 2000 @@ -0,0 +1,182 @@ +/* + * pccardd UNIX-domain socket interface + * Copyright (C) 1996 by Tatsumi Hosokawa + * + * $Id: server.c,v 1.3 1999/02/07 08:02:44 kuriyama Exp $ + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cardd.h" + +static void +cardnum(char *buf) +{ + int i = 0; + struct slot *sp; + + + for (sp = slots; sp; sp = sp->next) + i++; + if (i > MAXSLOT) + i = MAXSLOT; + sprintf(buf, "%2d", i); +} + +static struct slot * +find_slot(int slot) +{ + struct slot *sp; + + /* Search the list until we find the slot or get to the end */ + for (sp = slots; sp && sp->slot != slot; sp = sp->next) + continue; + + return ( sp ); +} + +static void +cardname(char *buf, int slot) +{ + struct slot *sp; + char *manuf, *vers, *drv, *stat; + + /* Look for the slot */ + if ( (sp = find_slot(slot)) == NULL) + return; + + /* Fill in the information in the buff */ + if (sp->cis) { + + manuf = sp->cis->manuf; + vers = sp->cis->vers; + if (sp->config && sp->config->driver && + sp->config->driver->name) + drv = sp->config->driver->name; + else + drv = ""; + } else + manuf = vers = drv = ""; + + switch (sp->state) { + case empty: + stat = "0"; + break; + case filled: + stat = "1"; + break; + case inactive: + stat = "2"; + break; + default: + stat = "9"; + } + sprintf(buf, "%d~%s~%s~%s~%s", slot, manuf, vers, drv, stat); +} + +static void +cardpwr(int slot, int pwon) +{ + struct slot *sp; + + /* Look for the slot */ + if ( (sp = find_slot(slot)) == NULL) + return; + + if (ioctl(sp->fd, PIOCSVIR, &pwon) < 0) + logerr("invaild arguments for cardpwr"); +} + +static int sock = 0; +static int slen = 0; +static struct sockaddr_un sun; + +void +set_socket(int s) +{ + sock = s; +} + +void +stat_changed(struct slot *sp) +{ + int len; + char buf[512]; + + if (!slen) + return; + + cardname(buf, sp->slot); + len = strlen(buf); + if (sendto(sock, buf, len, 0, (struct sockaddr *) & sun, slen) != len) { + logerr("sendto failed"); + slen = 0; + } +} + +void +process_client(void) +{ + char buf[512], obuf[512]; + int len; + int snum; + + if (!sock) + return; + slen = sizeof(sun); + len = recvfrom(sock, buf, sizeof(buf), + 0, (struct sockaddr *)&sun, &slen); + if (len < 0) + logerr("recvfrom failed"); + buf[len] = '\0'; + obuf[0] = '\0'; + switch (buf[0]) { /* Protocol implementation */ + case 'S': /* How many slots? */ + cardnum(obuf); + break; + case 'N': /* Card name request */ + sscanf(buf + 1, "%d", &snum); + if (snum >= 0 && snum <= MAXSLOT) + cardname(obuf, snum); + else + logerr("Illegal slot requests for N command"); + break; + case 'P': /* Virtual insertion request */ + sscanf(buf + 1, "%d", &snum); + if (snum >= 0 && snum <= MAXSLOT) { + logmsg("slot %d: spring has come", snum); + cardpwr(snum, 1); + } else + logerr("Illegal slot requests for P command"); + break; + case 'Q': /* Virtual removal request */ + sscanf(buf + 1, "%d", &snum); + if (snum >= 0 && snum <= MAXSLOT) { + logmsg("slot %d: hibernation", snum); + cardpwr(snum, 0); + } else + logerr("Illegal slot requests for Q command"); + break; + default: + logerr("Unknown control message from socket"); + break; + } + len = strlen(obuf); + if (len) { + if (sendto(sock, obuf, len, 0, (struct sockaddr *)&sun, slen) + != len) { + logerr("sendto failed"); + slen = 0; + } + } else if (sendto(sock, 0, 0, 0, (struct sockaddr *)&sun, slen) + != len) { + logerr("sendto failed"); + slen = 0; + } +}