2 * Copyright (c) 1995 Andrew McRae. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 static const char rcsid[] =
29 "$FreeBSD: src/usr.sbin/pccard/pccardd/pccardd.c,v 1.6.2.6 2001/08/02 18:51:38 imp Exp $";
38 #include <sys/socket.h>
44 char *config_file = "/etc/defaults/pccard.conf";
45 static char *pid_file = "/var/run/pccardd.pid";
48 * pathname of UNIX-domain socket
50 static char *socket_name = "/var/tmp/.pccardd";
51 static char *sock = 0;
52 static int server_sock;
54 /* SIGHUP signal handler */
58 bitstr_t bit_decl(io_inuse, IOPORTS);
59 bitstr_t bit_decl(mem_inuse, MEMBLKS);
62 struct sockaddr_un sun;
64 bit_nclear(io_inuse, 0, IOPORTS-1);
65 bit_nclear(mem_inuse, 0, MEMBLKS-1);
66 bzero(irq_inuse, sizeof(irq_inuse));
68 /* compare the initial and current state of resource pool */
69 for (i = 0; i < IOPORTS; i++) {
70 if (bit_test(io_init, i) == 1 && bit_test(io_avail, i) == 0) {
71 if (debug_level >= 1) {
72 logmsg("io 0x%x seems to be in use\n", i);
77 for (i = 0; i < MEMBLKS; i++) {
78 if (bit_test(mem_init, i) == 1 && bit_test(mem_avail, i) == 0) {
79 if (debug_level >= 1) {
80 logmsg("mem 0x%x seems to be in use\n", i);
82 bit_set(mem_inuse, i);
85 for (i = 0; i < 16; i++) {
86 if (irq_init[i] == 1 && pool_irq[i] == 0) {
87 if (debug_level >= 1) {
88 logmsg("irq %d seems to be in use\n", i);
94 readfile(config_file);
96 /* reflect used resources to managed resource pool */
97 for (i = 0; i < IOPORTS; i++) {
98 if (bit_test(io_inuse, i) == 1) {
99 bit_clear(io_avail, i);
102 for (i = 0; i < MEMBLKS; i++) {
103 if (bit_test(mem_inuse, i) == 1) {
104 bit_clear(mem_avail, i);
107 for (i = 0; i < 16; i++) {
108 if (irq_inuse[i] == 1) {
113 if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
114 die("socket failed");
115 bzero(&sun, sizeof(sun));
116 sun.sun_family = AF_UNIX;
120 strcpy(sun.sun_path, socket_name);
121 slen = SUN_LEN(&sun);
122 (void)unlink(socket_name);
123 if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0)
125 chown(socket_name, 0, 5); /* XXX - root.operator */
126 chmod(socket_name, 0660);
127 set_socket(server_sock);
130 /* SIGTERM/SIGINT signal handler */
134 logmsg("pccardd terminated: signal %d received", sig);
135 (void)unlink(pid_file);
142 FILE *fp = fopen(pid_file, "w");
145 fprintf(fp, "%d\n", getpid());
152 * mainline code for cardd
155 main(int argc, char *argv[])
158 int count, dodebug = 0;
161 int irq_specified = 0;
163 struct sockaddr_un sun;
164 #define COM_OPTS ":Idvf:s:i:z"
166 bzero(irq_arg, sizeof(irq_arg));
169 pccard_init_sleep = 5000000;
170 cards = last_card = 0;
171 while ((count = getopt(argc, argv, COM_OPTS)) != -1) {
185 config_file = optarg;
188 /* configure available irq */
189 if (sscanf(optarg, "%d", &i) != 1) {
190 fprintf(stderr, "%s: -i number\n", argv[0]);
203 die("no config file argument");
206 die("illegal option");
213 io_avail = bit_alloc(IOPORTS); /* Only supports ISA ports */
214 io_init = bit_alloc(IOPORTS);
216 /* Mem allocation done in MEMUNIT units. */
217 mem_avail = bit_alloc(MEMBLKS);
218 mem_init = bit_alloc(MEMBLKS);
219 readfile(config_file);
221 bcopy(irq_arg, pool_irq, sizeof(irq_arg));
222 bcopy(irq_arg, irq_init, sizeof(irq_arg));
227 if (!dodebug && !delay)
232 die("no PC-CARD slots");
236 logmsg("pccardd started", NULL);
239 if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
240 die("socket failed");
241 bzero(&sun, sizeof(sun));
242 sun.sun_family = AF_UNIX;
246 strcpy(sun.sun_path, socket_name);
247 slen = SUN_LEN(&sun);
248 (void)unlink(socket_name);
249 if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0)
251 chown(socket_name, 0, 5); /* XXX - root.operator */
252 chmod(socket_name, 0660);
253 set_socket(server_sock);
255 (void)signal(SIGINT, dodebug ? term : SIG_IGN);
256 (void)signal(SIGTERM, term);
257 (void)signal(SIGHUP, (void (*)(int))restart);
263 for (sp = slots; sp; sp = sp->next)
264 FD_SET(sp->fd, &emask);
265 FD_SET(server_sock, &rmask);
266 count = select(32, &rmask, 0, &emask, 0);
272 for (sp = slots; sp; sp = sp->next)
273 if (FD_ISSET(sp->fd, &emask))
275 if (FD_ISSET(server_sock, &rmask))