Initial import from FreeBSD RELENG_4:
[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  *
34  *      last edit-date: [Sat Aug 11 18:06:38 2001]
35  *
36  *---------------------------------------------------------------------------*/
37
38 #include "i4bctl.h"
39
40 #if NI4BCTL > 1
41 #error "only 1 (one) i4bctl device allowed!"
42 #endif
43
44 #if NI4BCTL > 0
45
46 #include <sys/param.h>
47
48 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
49 #include <sys/ioccom.h>
50 #else
51 #include <sys/ioctl.h>
52 #endif
53
54 #include <sys/kernel.h>
55 #include <sys/systm.h>
56 #include <sys/conf.h>
57 #include <sys/socket.h>
58 #include <net/if.h>
59
60 #ifdef __FreeBSD__
61
62 #if defined(__FreeBSD__) && __FreeBSD__ == 3
63 #include "opt_devfs.h"
64 #endif
65
66 #ifdef DEVFS
67 #include <sys/devfsext.h>
68 #endif
69
70 #endif /* __FreeBSD__ */
71
72 #ifdef __FreeBSD__
73 #include <machine/i4b_debug.h>
74 #include <machine/i4b_ioctl.h>
75 #elif defined(__bsdi__)
76 #include <i4b/i4b_debug.h>
77 #include <i4b/i4b_ioctl.h>
78 #else
79 #include <machine/bus.h>
80 #include <sys/device.h>
81 #include <i4b/i4b_debug.h>
82 #include <i4b/i4b_ioctl.h>
83 #endif
84
85 #include <i4b/include/i4b_global.h>
86 #include <i4b/include/i4b_l3l4.h>
87
88 #include <i4b/layer2/i4b_l2.h>
89
90 static int openflag = 0;
91
92 #if 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(__FreeBSD__) && __FreeBSD__ >= 4
107 static struct cdevsw i4bctl_cdevsw = {
108         /* open */      i4bctlopen,
109         /* close */     i4bctlclose,
110         /* read */      noread,
111         /* write */     nowrite,
112         /* ioctl */     i4bctlioctl,
113         /* poll */      POLLFIELD,
114         /* mmap */      nommap,
115         /* strategy */  nostrategy,
116         /* name */      "i4bctl",
117         /* maj */       CDEV_MAJOR,
118         /* dump */      nodump,
119         /* psize */     nopsize,
120         /* flags */     0,
121         /* bmaj */      -1
122 };
123 #else
124 static struct cdevsw i4bctl_cdevsw = 
125         { i4bctlopen,   i4bctlclose,    noread,         nowrite,
126           i4bctlioctl,  nostop,         nullreset,      nodevtotty,
127           POLLFIELD,    nommap,         NULL,   "i4bctl", NULL, -1 };
128 #endif
129
130 static void i4bctlattach(void *);
131 PSEUDO_SET(i4bctlattach, i4b_i4bctldrv);
132
133 #define PDEVSTATIC      static
134 #endif /* __FreeBSD__ */
135
136 #if defined(__FreeBSD__) && __FreeBSD__ == 3
137 #ifdef DEVFS
138 static void *devfs_token;
139 #endif
140 #endif
141
142 #ifndef __FreeBSD__
143 #define PDEVSTATIC      /* */
144 void i4bctlattach __P((void));
145 int i4bctlopen __P((dev_t dev, int flag, int fmt, struct proc *p));
146 int i4bctlclose __P((dev_t dev, int flag, int fmt, struct proc *p));
147 #ifdef __bsdi__
148 int i4bctlioctl __P((dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p));
149 #else
150 int i4bctlioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p));
151 #endif
152 #endif  /* !FreeBSD */
153
154 #if BSD > 199306 && defined(__FreeBSD__)
155 /*---------------------------------------------------------------------------*
156  *      initialization at kernel load time
157  *---------------------------------------------------------------------------*/
158 static void
159 i4bctlinit(void *unused)
160 {
161 #if defined(__FreeBSD__) && __FreeBSD__ >= 4
162         cdevsw_add(&i4bctl_cdevsw);
163 #else
164         dev_t dev = makedev(CDEV_MAJOR, 0);
165         cdevsw_add(&dev, &i4bctl_cdevsw, NULL);
166 #endif
167 }
168
169 SYSINIT(i4bctldev, SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, &i4bctlinit, NULL);
170
171 #endif /* BSD > 199306 && defined(__FreeBSD__) */
172
173 #ifdef __bsdi__
174 int i4bctlmatch(struct device *parent, struct cfdata *cf, void *aux);
175 void dummy_i4bctlattach(struct device*, struct device *, void *);
176
177 #define CDEV_MAJOR 64
178
179 static struct cfdriver i4bctlcd =
180         { NULL, "i4bctl", i4bctlmatch, dummy_i4bctlattach, DV_DULL,
181           sizeof(struct cfdriver) };
182 struct devsw i4bctlsw = 
183         { &i4bctlcd,
184           i4bctlopen,   i4bctlclose,    noread,         nowrite,
185           i4bctlioctl,  seltrue,        nommap,         nostrat,
186           nodump,       nopsize,        0,              nostop
187 };
188
189 int
190 i4bctlmatch(struct device *parent, struct cfdata *cf, void *aux)
191 {
192         printf("i4bctlmatch: aux=0x%x\n", aux);
193         return 1;
194 }
195 void
196 dummy_i4bctlattach(struct device *parent, struct device *self, void *aux)
197 {
198         printf("dummy_i4bctlattach: aux=0x%x\n", aux);
199 }
200 #endif /* __bsdi__ */
201 /*---------------------------------------------------------------------------*
202  *      interface attach routine
203  *---------------------------------------------------------------------------*/
204 PDEVSTATIC void
205 #ifdef __FreeBSD__
206 i4bctlattach(void *dummy)
207 #else
208 i4bctlattach()
209 #endif
210 {
211 #ifndef HACK_NO_PSEUDO_ATTACH_MSG
212         printf("i4bctl: ISDN system control port attached\n");
213 #endif
214
215 #if defined(__FreeBSD__)
216 #if __FreeBSD__ == 3
217
218 #ifdef DEVFS
219         devfs_token = devfs_add_devswf(&i4bctl_cdevsw, 0, DV_CHR,
220                                        UID_ROOT, GID_WHEEL, 0600,
221                                        "i4bctl");
222 #endif
223
224 #else
225         make_dev(&i4bctl_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "i4bctl");
226 #endif
227 #endif
228 }
229
230 /*---------------------------------------------------------------------------*
231  *      i4bctlopen - device driver open routine
232  *---------------------------------------------------------------------------*/
233 PDEVSTATIC int
234 i4bctlopen(dev_t dev, int flag, int fmt, struct proc *p)
235 {
236         if(minor(dev))
237                 return (ENXIO);
238
239         if(openflag)
240                 return (EBUSY);
241         
242         openflag = 1;
243         
244         return (0);
245 }
246
247 /*---------------------------------------------------------------------------*
248  *      i4bctlclose - device driver close routine
249  *---------------------------------------------------------------------------*/
250 PDEVSTATIC int
251 i4bctlclose(dev_t dev, int flag, int fmt, struct proc *p)
252 {
253         openflag = 0;
254         return (0);
255 }
256
257 /*---------------------------------------------------------------------------*
258  *      i4bctlioctl - device driver ioctl routine
259  *---------------------------------------------------------------------------*/
260 PDEVSTATIC int
261 #if defined (__FreeBSD_version) && __FreeBSD_version >= 300003
262 i4bctlioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
263 #elif defined(__bsdi__)
264 i4bctlioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
265 #else
266 i4bctlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
267 #endif
268 {
269 #if DO_I4B_DEBUG
270         ctl_debug_t *cdbg;      
271         int error = 0;
272 #endif
273         
274 #if !DO_I4B_DEBUG
275        return(ENODEV);
276 #else
277         if(minor(dev))
278                 return(ENODEV);
279
280         switch(cmd)
281         {
282                 case I4B_CTL_GET_DEBUG:
283                         cdbg = (ctl_debug_t *)data;
284                         cdbg->l1 = i4b_l1_debug;
285                         cdbg->l2 = i4b_l2_debug;
286                         cdbg->l3 = i4b_l3_debug;
287                         cdbg->l4 = i4b_l4_debug;
288                         break;
289                 
290                 case I4B_CTL_SET_DEBUG:
291                         cdbg = (ctl_debug_t *)data;
292                         i4b_l1_debug = cdbg->l1;
293                         i4b_l2_debug = cdbg->l2;
294                         i4b_l3_debug = cdbg->l3;
295                         i4b_l4_debug = cdbg->l4;
296                         break;
297
298                 case I4B_CTL_GET_CHIPSTAT:
299                 {
300                         struct chipstat *cst;
301                         cst = (struct chipstat *)data;
302                         (*ctrl_desc[cst->driver_unit].N_MGMT_COMMAND)(cst->driver_unit, CMR_GCST, cst);
303                         break;
304                 }
305
306                 case I4B_CTL_CLR_CHIPSTAT:
307                 {
308                         struct chipstat *cst;
309                         cst = (struct chipstat *)data;
310                         (*ctrl_desc[cst->driver_unit].N_MGMT_COMMAND)(cst->driver_unit, CMR_CCST, cst);
311                         break;
312                 }
313
314                 case I4B_CTL_GET_LAPDSTAT:
315                 {
316                         l2stat_t *l2s;
317                         l2_softc_t *sc;
318                         l2s = (l2stat_t *)data;
319
320                         if( l2s->unit < 0 || l2s->unit > MAXL1UNITS)
321                         {
322                                 error = EINVAL;
323                                 break;
324                         }
325                           
326                         sc = &l2_softc[l2s->unit];
327
328                         bcopy(&sc->stat, &l2s->lapdstat, sizeof(lapdstat_t));
329                         break;
330                 }
331
332                 case I4B_CTL_CLR_LAPDSTAT:
333                 {
334                         int *up;
335                         l2_softc_t *sc;
336                         up = (int *)data;
337
338                         if( *up < 0 || *up > MAXL1UNITS)
339                         {
340                                 error = EINVAL;
341                                 break;
342                         }
343                           
344                         sc = &l2_softc[*up];
345
346                         bzero(&sc->stat, sizeof(lapdstat_t));
347                         break;
348                 }
349
350                 default:
351                         error = ENOTTY;
352                         break;
353         }
354         return(error);
355 #endif DO_I4B_DEBUG
356 }
357
358 #if defined(__FreeBSD__) && defined(OS_USES_POLL)
359
360 /*---------------------------------------------------------------------------*
361  *      i4bctlpoll - device driver poll routine
362  *---------------------------------------------------------------------------*/
363 static int
364 i4bctlpoll (dev_t dev, int events, struct proc *p)
365 {
366         return (ENODEV);
367 }
368
369 #endif
370
371 #endif /* NI4BCTL > 0 */