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