Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / pccard / pccardd / pccardd.c
1 /*
2  * Copyright (c) 1995 Andrew McRae.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
14  *
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.
25  *
26  * $FreeBSD: src/usr.sbin/pccard/pccardd/pccardd.c,v 1.6.2.6 2001/08/02 18:51:38 imp Exp $
27  * $DragonFly: src/usr.sbin/pccard/pccardd/Attic/pccardd.c,v 1.2 2003/06/17 04:29:59 dillon Exp $
28  */
29
30 #include <signal.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <sys/stat.h>
39 #define EXTERN
40 #include "cardd.h"
41
42 char   *config_file = "/etc/defaults/pccard.conf";
43 static char *pid_file = "/var/run/pccardd.pid";
44
45 /*
46  * pathname of UNIX-domain socket
47  */
48 static char     *socket_name = "/var/tmp/.pccardd";
49 static char     *sock = 0;
50 static int      server_sock;
51
52 /* SIGHUP signal handler */
53 static void
54 restart(void)
55 {
56         bitstr_t bit_decl(io_inuse, IOPORTS);
57         bitstr_t bit_decl(mem_inuse, MEMBLKS);
58         int     irq_inuse[16];
59         int     i;
60         struct sockaddr_un sun;
61
62         bit_nclear(io_inuse, 0, IOPORTS-1);
63         bit_nclear(mem_inuse, 0, MEMBLKS-1);
64         bzero(irq_inuse, sizeof(irq_inuse));
65
66         /* compare the initial and current state of resource pool */
67         for (i = 0; i < IOPORTS; i++) {
68                 if (bit_test(io_init, i) == 1 && bit_test(io_avail, i) == 0) {
69                         if (debug_level >= 1) {
70                                 logmsg("io 0x%x seems to be in use\n", i);
71                         }
72                         bit_set(io_inuse, i);
73                 }
74         }
75         for (i = 0; i < MEMBLKS; i++) {
76                 if (bit_test(mem_init, i) == 1 && bit_test(mem_avail, i) == 0) {
77                         if (debug_level >= 1) {
78                                 logmsg("mem 0x%x seems to be in use\n", i);
79                         }
80                         bit_set(mem_inuse, i);
81                 }
82         }
83         for (i = 0; i < 16; i++) {
84                 if (irq_init[i] == 1 && pool_irq[i] == 0) {
85                         if (debug_level >= 1) {
86                                 logmsg("irq %d seems to be in use\n", i);
87                         }
88                         irq_inuse[i] = 1;
89                 }
90         }
91
92         readfile(config_file);
93
94         /* reflect used resources to managed resource pool */
95         for (i = 0; i < IOPORTS; i++) {
96                 if (bit_test(io_inuse, i) == 1) {
97                         bit_clear(io_avail, i);
98                 }
99         }
100         for (i = 0; i < MEMBLKS; i++) {
101                 if (bit_test(mem_inuse, i) == 1) {
102                         bit_clear(mem_avail, i);
103                 }
104         }
105         for (i = 0; i < 16; i++) {
106                 if (irq_inuse[i] == 1) {
107                         pool_irq[i] = 0;
108                 }
109         }
110         close(server_sock);
111         if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
112                 die("socket failed");
113         bzero(&sun, sizeof(sun));
114         sun.sun_family = AF_UNIX;
115         if (sock) {
116                 socket_name = sock;
117         }
118         strcpy(sun.sun_path, socket_name);
119         slen = SUN_LEN(&sun);
120         (void)unlink(socket_name);
121         if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0)
122                 die("bind failed");
123         chown(socket_name, 0, 5);       /* XXX - root.operator */
124         chmod(socket_name, 0660);
125         set_socket(server_sock);
126 }
127
128 /* SIGTERM/SIGINT signal handler */
129 static void
130 term(int sig)
131 {
132         logmsg("pccardd terminated: signal %d received", sig);
133         (void)unlink(pid_file);
134         exit(0);
135 }
136
137 static void
138 write_pid()
139 {
140         FILE *fp = fopen(pid_file, "w");
141
142         if (fp) {
143                 fprintf(fp, "%d\n", getpid());
144                 fclose(fp);
145         }
146 }
147
148 int doverbose = 0;
149 /*
150  *      mainline code for cardd
151  */
152 int
153 main(int argc, char *argv[])
154 {
155         struct slot *sp;
156         int count, dodebug = 0;
157         int delay = 0;
158         int irq_arg[16];
159         int irq_specified = 0;
160         int i;
161         struct sockaddr_un sun;
162 #define COM_OPTS        ":Idvf:s:i:z"
163
164         bzero(irq_arg, sizeof(irq_arg));
165         use_kern_irq = 1;
166         debug_level = 0;
167         pccard_init_sleep = 5000000;
168         cards = last_card = 0;
169         while ((count = getopt(argc, argv, COM_OPTS)) != -1) {
170                 switch (count) {
171                 case 'I':
172                         use_kern_irq = 0;
173                         break;
174                 case 'd':
175                         setbuf(stdout, 0);
176                         setbuf(stderr, 0);
177                         dodebug = 1;
178                         break;
179                 case 'v':
180                         doverbose = 1;
181                         break;
182                 case 'f':
183                         config_file = optarg;
184                         break;
185                 case 'i':
186                         /* configure available irq */
187                         if (sscanf(optarg, "%d", &i) != 1) {
188                                 fprintf(stderr, "%s: -i number\n", argv[0]);
189                                 exit(1);
190                         }
191                         irq_arg[i] = 1;
192                         irq_specified = 1;
193                         break;
194                 case 's':
195                         sock = optarg;
196                         break;
197                 case 'z':
198                         delay = 1;
199                         break;
200                 case ':':
201                         die("no config file argument");
202                         break;
203                 case '?':
204                         die("illegal option");
205                         break;
206                 }
207         }
208 #ifdef  DEBUG
209         dodebug = 1;
210 #endif
211         io_avail = bit_alloc(IOPORTS);  /* Only supports ISA ports */
212         io_init  = bit_alloc(IOPORTS);
213
214         /* Mem allocation done in MEMUNIT units. */
215         mem_avail = bit_alloc(MEMBLKS);
216         mem_init  = bit_alloc(MEMBLKS);
217         readfile(config_file);
218         if (irq_specified) {
219                 bcopy(irq_arg, pool_irq, sizeof(irq_arg));
220                 bcopy(irq_arg, irq_init, sizeof(irq_arg));
221         }
222         if (doverbose)
223                 dump_config_file();
224         log_setup();
225         if (!dodebug && !delay)
226                 if (daemon(0, 0))
227                         die("fork failed");
228         slots = readslots();
229         if (slots == 0)
230                 die("no PC-CARD slots");
231         if (delay)
232                 if (daemon(0, 0))
233                         die("fork failed");
234         logmsg("pccardd started", NULL);
235         write_pid();
236
237         if ((server_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
238                 die("socket failed");
239         bzero(&sun, sizeof(sun));
240         sun.sun_family = AF_UNIX;
241         if (sock) {
242                 socket_name = sock;
243         }
244         strcpy(sun.sun_path, socket_name);
245         slen = SUN_LEN(&sun);
246         (void)unlink(socket_name);
247         if (bind(server_sock, (struct sockaddr *) & sun, slen) < 0)
248                 die("bind failed");
249         chown(socket_name, 0, 5);       /* XXX - root.operator */
250         chmod(socket_name, 0660);
251         set_socket(server_sock);
252
253         (void)signal(SIGINT, dodebug ? term : SIG_IGN);
254         (void)signal(SIGTERM, term);
255         (void)signal(SIGHUP, (void (*)(int))restart);
256
257         for (;;) {
258                 fd_set  rmask, emask;
259                 FD_ZERO(&emask);
260                 FD_ZERO(&rmask);
261                 for (sp = slots; sp; sp = sp->next)
262                         FD_SET(sp->fd, &emask);
263                 FD_SET(server_sock, &rmask);
264                 count = select(32, &rmask, 0, &emask, 0);
265                 if (count == -1) {
266                         logerr("select");
267                         continue;
268                 }
269                 if (count) {
270                         for (sp = slots; sp; sp = sp->next)
271                                 if (FD_ISSET(sp->fd, &emask))
272                                         slot_change(sp);
273                         if (FD_ISSET(server_sock, &rmask))
274                                 process_client();
275                 }
276         }
277 }