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