Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / sys / net / i4b / driver / i4b_ctl.c
1 /*
2  * Copyright (c) 1997, 2000 Hellmuth Michaelis. 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  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      i4b_ctl.c - i4b system control port driver
28  *      ------------------------------------------
29  *
30  *      $Id: i4b_ctl.c,v 1.37 2000/05/31 08:04:43 hm Exp $
31  *
32  * $FreeBSD: src/sys/i4b/driver/i4b_ctl.c,v 1.10.2.3 2001/08/12 16:22:48 hm Exp $
33  * $DragonFly: src/sys/net/i4b/driver/i4b_ctl.c,v 1.10 2004/07/02 15:43:10 joerg Exp $
34  *
35  *      last edit-date: [Sat Aug 11 18:06:38 2001]
36  *
37  *---------------------------------------------------------------------------*/
38
39 #include "use_i4bctl.h"
40
41 #if NI4BCTL > 1
42 #error "only 1 (one) i4bctl device allowed!"
43 #endif
44
45 #if NI4BCTL > 0
46
47 #include <sys/param.h>
48
49 #if defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD__ >= 3)
50 #include <sys/ioccom.h>
51 #else
52 #include <sys/ioctl.h>
53 #endif
54
55 #include <sys/kernel.h>
56 #include <sys/systm.h>
57 #include <sys/conf.h>
58 #include <sys/socket.h>
59 #include <net/if.h>
60
61 #if defined(__DragonFly__) || defined(__FreeBSD__)
62
63 #if defined(__FreeBSD__) && __FreeBSD__ == 3
64 #include "opt_devfs.h"
65 #endif
66
67 #ifdef DEVFS
68 #include <sys/devfsext.h>
69 #endif
70
71 #endif /* __FreeBSD__ */
72
73 #if defined(__DragonFly__) || defined(__FreeBSD__)
74 #include <net/i4b/include/machine/i4b_debug.h>
75 #include <net/i4b/include/machine/i4b_ioctl.h>
76 #elif defined(__bsdi__)
77 #include <i4b/i4b_debug.h>
78 #include <i4b/i4b_ioctl.h>
79 #else
80 #include <machine/bus.h>
81 #include <sys/device.h>
82 #include <i4b/i4b_debug.h>
83 #include <i4b/i4b_ioctl.h>
84 #endif
85
86 #include "../include/i4b_global.h"
87 #include "../include/i4b_l3l4.h"
88 #include "../layer2/i4b_l2.h"
89
90 static int openflag = 0;
91
92 #if defined(__DragonFly__) || (BSD > 199306 && defined(__FreeBSD__))
93 static  d_open_t        i4bctlopen;
94 static  d_close_t       i4bctlclose;
95 static  d_ioctl_t       i4bctlioctl;
96
97 #ifdef OS_USES_POLL
98 static d_poll_t         i4bctlpoll;
99 #define POLLFIELD       i4bctlpoll
100 #else
101 #define POLLFIELD       noselect
102 #endif
103
104 #define CDEV_MAJOR 55
105
106 #if defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD__ >= 4)
107 static struct cdevsw i4bctl_cdevsw = {
108         /* name */      "i4bctl",
109         /* maj */       CDEV_MAJOR,
110         /* flags */     0,
111         /* port */      NULL,
112         /* clone */     NULL,
113
114         /* open */      i4bctlopen,
115         /* close */     i4bctlclose,
116         /* read */      noread,
117         /* write */     nowrite,
118         /* ioctl */     i4bctlioctl,
119         /* poll */      POLLFIELD,
120         /* mmap */      nommap,
121         /* strategy */  nostrategy,
122         /* dump */      nodump,
123         /* psize */     nopsize
124 };
125 #else
126 static struct cdevsw i4bctl_cdevsw = 
127         { i4bctlopen,   i4bctlclose,    noread,         nowrite,
128           i4bctlioctl,  nostop,         nullreset,      nodevtotty,
129           POLLFIELD,    nommap,         NULL,   "i4bctl", NULL, -1 };
130 #endif
131
132 static void i4bctlattach(void *);
133 PSEUDO_SET(i4bctlattach, i4b_i4bctldrv);
134
135 #define PDEVSTATIC      static
136 #endif /* __FreeBSD__ */
137
138 #if defined(__FreeBSD__) && __FreeBSD__ == 3
139 #ifdef DEVFS
140 static void *devfs_token;
141 #endif
142 #endif
143
144 #if !defined(__DragonFly__) && !defined(__FreeBSD__)
145 #define PDEVSTATIC      /* */
146 void i4bctlattach (void);
147 int i4bctlopen (dev_t dev, int flag, int fmt, struct proc *p);
148 int i4bctlclose (dev_t dev, int flag, int fmt, struct proc *p);
149 #ifdef __bsdi__
150 int i4bctlioctl (dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p);
151 #else
152 int i4bctlioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p);
153 #endif
154 #endif  /* !FreeBSD */
155
156 #if defined(__DragonFly__) || (BSD > 199306 && defined(__FreeBSD__))
157 /*---------------------------------------------------------------------------*
158  *      initialization at kernel load time
159  *---------------------------------------------------------------------------*/
160 static void
161 i4bctlinit(void *unused)
162 {
163 #if defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD__ >= 4)
164         cdevsw_add(&i4bctl_cdevsw, 0, 0);
165 #else
166         dev_t dev = make_adhoc_dev(&i4bctl, 0);
167         cdevsw_add(&dev, &i4bctl_cdevsw, NULL);
168 #endif
169 }
170
171 SYSINIT(i4bctldev, SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, &i4bctlinit, NULL);
172
173 #endif /* BSD > 199306 && defined(__FreeBSD__) */
174
175 #ifdef __bsdi__
176 int i4bctlmatch(struct device *parent, struct cfdata *cf, void *aux);
177 void dummy_i4bctlattach(struct device*, struct device *, void *);
178
179 #define CDEV_MAJOR 64
180
181 static struct cfdriver i4bctlcd =
182         { NULL, "i4bctl", i4bctlmatch, dummy_i4bctlattach, DV_DULL,
183           sizeof(struct cfdriver) };
184 struct devsw i4bctlsw = 
185         { &i4bctlcd,
186           i4bctlopen,   i4bctlclose,    noread,         nowrite,
187           i4bctlioctl,  seltrue,        nommap,         nostrat,
188           nodump,       nopsize,        0,              nostop
189 };
190
191 int
192 i4bctlmatch(struct device *parent, struct cfdata *cf, void *aux)
193 {
194         printf("i4bctlmatch: aux=0x%x\n", aux);
195         return 1;
196 }
197 void
198 dummy_i4bctlattach(struct device *parent, struct device *self, void *aux)
199 {
200         printf("dummy_i4bctlattach: aux=0x%x\n", aux);
201 }
202 #endif /* __bsdi__ */
203 /*---------------------------------------------------------------------------*
204  *      interface attach routine
205  *---------------------------------------------------------------------------*/
206 PDEVSTATIC void
207 #if defined(__DragonFly__) || defined(__FreeBSD__)
208 i4bctlattach(void *dummy)
209 #else
210 i4bctlattach()
211 #endif
212 {
213 #ifndef HACK_NO_PSEUDO_ATTACH_MSG
214         printf("i4bctl: ISDN system control port attached\n");
215 #endif
216
217 #if defined(__FreeBSD__)
218 #if __FreeBSD__ == 3
219
220 #ifdef DEVFS
221         devfs_token = devfs_add_devswf(&i4bctl_cdevsw, 0, DV_CHR,
222                                        UID_ROOT, GID_WHEEL, 0600,
223                                        "i4bctl");
224 #endif
225
226 #else
227         make_dev(&i4bctl_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "i4bctl");
228 #endif
229 #endif
230 }
231
232 /*---------------------------------------------------------------------------*
233  *      i4bctlopen - device driver open routine
234  *---------------------------------------------------------------------------*/
235 PDEVSTATIC int
236 i4bctlopen(dev_t dev, int flag, int fmt, struct thread *td)
237 {
238         if(minor(dev))
239                 return (ENXIO);
240
241         if(openflag)
242                 return (EBUSY);
243         
244         openflag = 1;
245         
246         return (0);
247 }
248
249 /*---------------------------------------------------------------------------*
250  *      i4bctlclose - device driver close routine
251  *---------------------------------------------------------------------------*/
252 PDEVSTATIC int
253 i4bctlclose(dev_t dev, int flag, int fmt, struct thread *td)
254 {
255         openflag = 0;
256         return (0);
257 }
258
259 /*---------------------------------------------------------------------------*
260  *      i4bctlioctl - device driver ioctl routine
261  *---------------------------------------------------------------------------*/
262 PDEVSTATIC int
263 #if defined(__DragonFly__) || (defined (__FreeBSD_version) && __FreeBSD_version >= 300003)
264 i4bctlioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
265 #elif defined(__bsdi__)
266 i4bctlioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
267 #else
268 i4bctlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
269 #endif
270 {
271 #if DO_I4B_DEBUG
272         ctl_debug_t *cdbg;      
273         int error = 0;
274 #endif
275         
276 #if !DO_I4B_DEBUG
277        return(ENODEV);
278 #else
279         if(minor(dev))
280                 return(ENODEV);
281
282         switch(cmd)
283         {
284                 case I4B_CTL_GET_DEBUG:
285                         cdbg = (ctl_debug_t *)data;
286                         cdbg->l1 = i4b_l1_debug;
287                         cdbg->l2 = i4b_l2_debug;
288                         cdbg->l3 = i4b_l3_debug;
289                         cdbg->l4 = i4b_l4_debug;
290                         break;
291                 
292                 case I4B_CTL_SET_DEBUG:
293                         cdbg = (ctl_debug_t *)data;
294                         i4b_l1_debug = cdbg->l1;
295                         i4b_l2_debug = cdbg->l2;
296                         i4b_l3_debug = cdbg->l3;
297                         i4b_l4_debug = cdbg->l4;
298                         break;
299
300                 case I4B_CTL_GET_CHIPSTAT:
301                 {
302                         struct chipstat *cst;
303                         cst = (struct chipstat *)data;
304                         (*ctrl_desc[cst->driver_unit].N_MGMT_COMMAND)(cst->driver_unit, CMR_GCST, cst);
305                         break;
306                 }
307
308                 case I4B_CTL_CLR_CHIPSTAT:
309                 {
310                         struct chipstat *cst;
311                         cst = (struct chipstat *)data;
312                         (*ctrl_desc[cst->driver_unit].N_MGMT_COMMAND)(cst->driver_unit, CMR_CCST, cst);
313                         break;
314                 }
315
316                 case I4B_CTL_GET_LAPDSTAT:
317                 {
318                         l2stat_t *l2s;
319                         l2_softc_t *sc;
320                         l2s = (l2stat_t *)data;
321
322                         if( l2s->unit < 0 || l2s->unit > MAXL1UNITS)
323                         {
324                                 error = EINVAL;
325                                 break;
326                         }
327                           
328                         sc = &l2_softc[l2s->unit];
329
330                         bcopy(&sc->stat, &l2s->lapdstat, sizeof(lapdstat_t));
331                         break;
332                 }
333
334                 case I4B_CTL_CLR_LAPDSTAT:
335                 {
336                         int *up;
337                         l2_softc_t *sc;
338                         up = (int *)data;
339
340                         if( *up < 0 || *up > MAXL1UNITS)
341                         {
342                                 error = EINVAL;
343                                 break;
344                         }
345                           
346                         sc = &l2_softc[*up];
347
348                         bzero(&sc->stat, sizeof(lapdstat_t));
349                         break;
350                 }
351
352                 default:
353                         error = ENOTTY;
354                         break;
355         }
356         return(error);
357 #endif /* DO_I4B_DEBUG */
358 }
359
360 #if (defined(__DragonFly__) || defined(__FreeBSD__)) && defined(OS_USES_POLL)
361
362 /*---------------------------------------------------------------------------*
363  *      i4bctlpoll - device driver poll routine
364  *---------------------------------------------------------------------------*/
365 static int
366 i4bctlpoll (dev_t dev, int events, struct thread *td)
367 {
368         return (ENODEV);
369 }
370
371 #endif
372
373 #endif /* NI4BCTL > 0 */