Fix a minor compile-time errors when INVARIANTS is not defined.
[dragonfly.git] / sys / net / i4b / driver / i4b_trace.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1997, 2001 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 * i4btrc - device driver for trace data read device
28 * ---------------------------------------------------
29 *
30 * last edit-date: [Sat Aug 11 18:07:15 2001]
31 *
32 * $FreeBSD: src/sys/i4b/driver/i4b_trace.c,v 1.9.2.3 2001/08/12 16:22:48 hm Exp $
33 * $DragonFly: src/sys/net/i4b/driver/i4b_trace.c,v 1.3 2003/07/19 21:14:37 dillon Exp $
34 *
35 * NOTE: the code assumes that SPLI4B >= splimp !
36 *
37 *---------------------------------------------------------------------------*/
38
39#include "i4btrc.h"
40
41#if NI4BTRC > 0
42
43#include <sys/param.h>
44#include <sys/systm.h>
45
46#if defined(__FreeBSD__) && __FreeBSD__ >= 3
47#include <sys/ioccom.h>
48#else
49#include <sys/ioctl.h>
50#endif
51
52#include <sys/conf.h>
53#include <sys/uio.h>
54#include <sys/kernel.h>
55#include <sys/mbuf.h>
56#include <sys/socket.h>
57#include <net/if.h>
58#include <sys/tty.h>
59
60#ifdef __FreeBSD__
61
62#ifdef DEVFS
63#include <sys/devfsext.h>
64#endif
65
66#include <machine/i4b_trace.h>
67#include <machine/i4b_ioctl.h>
68
69#else
70
71#include <i4b/i4b_trace.h>
72#include <i4b/i4b_ioctl.h>
73
74#endif
75
76#include <i4b/include/i4b_mbuf.h>
77#include <i4b/include/i4b_global.h>
78#include <i4b/include/i4b_l3l4.h>
79
80#ifndef __FreeBSD__
81#define memcpy(d,s,l) bcopy(s,d,l)
82#endif
83
84static struct ifqueue trace_queue[NI4BTRC];
85static int device_state[NI4BTRC];
86#define ST_IDLE 0x00
87#define ST_ISOPEN 0x01
88#define ST_WAITDATA 0x02
89
90#if defined(__FreeBSD__) && __FreeBSD__ == 3
91#ifdef DEVFS
92static void *devfs_token[NI4BTRC];
93#endif
94#endif
95
96static int analyzemode = 0;
97static int rxunit = -1;
98static int txunit = -1;
99static int outunit = -1;
100
101#ifndef __FreeBSD__
102
103#define PDEVSTATIC /* - not static - */
104void i4btrcattach __P((void));
105int i4btrcopen __P((dev_t dev, int flag, int fmt, struct proc *p));
106int i4btrcclose __P((dev_t dev, int flag, int fmt, struct proc *p));
107int i4btrcread __P((dev_t dev, struct uio * uio, int ioflag));
108
109#ifdef __bsdi__
110int i4btrcioctl __P((dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p));
111#else
112int i4btrcioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p));
113#endif
114
115#endif
116
117#if BSD > 199306 && defined(__FreeBSD__)
118#define PDEVSTATIC static
119static d_open_t i4btrcopen;
120static d_close_t i4btrcclose;
121static d_read_t i4btrcread;
122static d_ioctl_t i4btrcioctl;
123
124#ifdef OS_USES_POLL
125static d_poll_t i4btrcpoll;
126#define POLLFIELD i4btrcpoll
127#else
128#define POLLFIELD noselect
129#endif
130
131#define CDEV_MAJOR 59
132
133static struct cdevsw i4btrc_cdevsw = {
134 /* open */ i4btrcopen,
135 /* close */ i4btrcclose,
136 /* read */ i4btrcread,
137 /* write */ nowrite,
138 /* ioctl */ i4btrcioctl,
139 /* poll */ POLLFIELD,
140 /* mmap */ nommap,
141 /* strategy */ nostrategy,
142 /* name */ "i4btrc",
143 /* maj */ CDEV_MAJOR,
144 /* dump */ nodump,
145 /* psize */ nopsize,
146 /* flags */ 0,
147 /* bmaj */ -1
148};
149
150/*---------------------------------------------------------------------------*
151 * interface init routine
152 *---------------------------------------------------------------------------*/
153static
154void i4btrcinit(void *unused)
155{
156 cdevsw_add(&i4btrc_cdevsw);
157}
158
159SYSINIT(i4btrcdev, SI_SUB_DRIVERS,
160 SI_ORDER_MIDDLE+CDEV_MAJOR, &i4btrcinit, NULL);
161
162static void i4btrcattach(void *);
163PSEUDO_SET(i4btrcattach, i4b_trace);
164
165#endif /* BSD > 199306 && defined(__FreeBSD__) */
166
167#ifdef __bsdi__
168#include <sys/device.h>
169int i4btrcmatch(struct device *parent, struct cfdata *cf, void *aux);
170void dummy_i4btrcattach(struct device*, struct device *, void *);
171
172#define CDEV_MAJOR 60
173
174static struct cfdriver i4btrccd =
175 { NULL, "i4btrc", i4btrcmatch, dummy_i4btrcattach, DV_DULL,
176 sizeof(struct cfdriver) };
177struct devsw i4btrcsw =
178 { &i4btrccd,
179 i4btrcopen, i4btrcclose, i4btrcread, nowrite,
180 i4btrcioctl, seltrue, nommap, nostrat,
181 nodump, nopsize, 0, nostop
182};
183
184int
185i4btrcmatch(struct device *parent, struct cfdata *cf, void *aux)
186{
187 printf("i4btrcmatch: aux=0x%x\n", aux);
188 return 1;
189}
190void
191dummy_i4btrcattach(struct device *parent, struct device *self, void *aux)
192{
193 printf("dummy_i4btrcattach: aux=0x%x\n", aux);
194}
195#endif /* __bsdi__ */
196
197int get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf);
198
199/*---------------------------------------------------------------------------*
200 * interface attach routine
201 *---------------------------------------------------------------------------*/
202PDEVSTATIC void
203#ifdef __FreeBSD__
204i4btrcattach(void *dummy)
205#else
206i4btrcattach()
207#endif
208{
209 int i;
210
211 printf("i4btrc: %d ISDN trace device(s) attached\n", NI4BTRC);
212
213 for(i=0; i < NI4BTRC; i++)
214 {
215
216#if defined(__FreeBSD__)
217 make_dev(&i4btrc_cdevsw, i,
218 UID_ROOT, GID_WHEEL, 0600, "i4btrc%d", i);
219#endif
220 trace_queue[i].ifq_maxlen = IFQ_MAXLEN;
221
222#if __FreeBSD__ > 4
223 mtx_init(&trace_queue[i].ifq_mtx, "i4b_trace", MTX_DEF);
224#endif
225 device_state[i] = ST_IDLE;
226 }
227}
228
229/*---------------------------------------------------------------------------*
230 * get_trace_data_from_l1()
231 * ------------------------
232 * is called from layer 1, adds timestamp to trace data and puts
233 * it into a queue, from which it can be read from the i4btrc
234 * device. The unit number in the trace header selects the minor
235 * device's queue the data is put into.
236 *---------------------------------------------------------------------------*/
237int
238get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf)
239{
240 struct mbuf *m;
241 int x;
242 int unit;
243 int trunc = 0;
244 int totlen = len + sizeof(i4b_trace_hdr_t);
245
246 /*
247 * for telephony (or better non-HDLC HSCX mode) we get
248 * (MCLBYTE + sizeof(i4b_trace_hdr_t)) length packets
249 * to put into the queue to userland. because of this
250 * we detect this situation, strip the length to MCLBYTES
251 * max size, and infor the userland program of this fact
252 * by putting the no of truncated bytes into hdr->trunc.
253 */
254
255 if(totlen > MCLBYTES)
256 {
257 trunc = 1;
258 hdr->trunc = totlen - MCLBYTES;
259 totlen = MCLBYTES;
260 }
261 else
262 {
263 hdr->trunc = 0;
264 }
265
266 /* set length of trace record */
267
268 hdr->length = totlen;
269
270 /* check valid unit no */
271
272 if((unit = hdr->unit) > NI4BTRC)
273 {
274 printf("i4b_trace: get_trace_data_from_l1 - unit > NI4BTRC!\n");
275 return(0);
276 }
277
278 /* get mbuf */
279
280 if(!(m = i4b_Bgetmbuf(totlen)))
281 {
282 printf("i4b_trace: get_trace_data_from_l1 - i4b_getmbuf() failed!\n");
283 return(0);
284 }
285
286 /* check if we are in analyzemode */
287
288 if(analyzemode && (unit == rxunit || unit == txunit))
289 {
290 if(unit == rxunit)
291 hdr->dir = FROM_NT;
292 else
293 hdr->dir = FROM_TE;
294 unit = outunit;
295 }
296
297 IF_LOCK(&trace_queue[unit]);
298 if(_IF_QFULL(&trace_queue[unit]))
299 {
300 struct mbuf *m1;
301
302 x = SPLI4B();
303 _IF_DEQUEUE(&trace_queue[unit], m1);
304 splx(x);
305
306 i4b_Bfreembuf(m1);
307 }
308
309 /* copy trace header */
310 memcpy(m->m_data, hdr, sizeof(i4b_trace_hdr_t));
311
312 /* copy trace data */
313 if(trunc)
314 memcpy(&m->m_data[sizeof(i4b_trace_hdr_t)], buf, totlen-sizeof(i4b_trace_hdr_t));
315 else
316 memcpy(&m->m_data[sizeof(i4b_trace_hdr_t)], buf, len);
317
318 x = SPLI4B();
319
320 _IF_ENQUEUE(&trace_queue[unit], m);
321 IF_UNLOCK(&trace_queue[unit]);
322
323 if(device_state[unit] & ST_WAITDATA)
324 {
325 device_state[unit] &= ~ST_WAITDATA;
326 wakeup((caddr_t) &trace_queue[unit]);
327 }
328
329 splx(x);
330
331 return(1);
332}
333
334/*---------------------------------------------------------------------------*
335 * open trace device
336 *---------------------------------------------------------------------------*/
337PDEVSTATIC int
338i4btrcopen(dev_t dev, int flag, int fmt, struct proc *p)
339{
340 int x;
341 int unit = minor(dev);
342
343 if(unit >= NI4BTRC)
344 return(ENXIO);
345
346 if(device_state[unit] & ST_ISOPEN)
347 return(EBUSY);
348
349 if(analyzemode && (unit == outunit || unit == rxunit || unit == txunit))
350 return(EBUSY);
351
352 x = SPLI4B();
353
354 device_state[unit] = ST_ISOPEN;
355
356 splx(x);
357
358 return(0);
359}
360
361/*---------------------------------------------------------------------------*
362 * close trace device
363 *---------------------------------------------------------------------------*/
364PDEVSTATIC int
365i4btrcclose(dev_t dev, int flag, int fmt, struct proc *p)
366{
367 int unit = minor(dev);
368 int i, x;
369 int cno = -1;
370
371 for(i=0; i < nctrl; i++)
372 {
373 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
374 (ctrl_desc[i].unit == unit))
375 {
376 cno = i;
377 break;
378 }
379 }
380
381 if(analyzemode && (unit == outunit))
382 {
383 analyzemode = 0;
384 outunit = -1;
385
386 if(cno >= 0)
387 {
388 (*ctrl_desc[cno].N_MGMT_COMMAND)(rxunit, CMR_SETTRACE, TRACE_OFF);
389 (*ctrl_desc[cno].N_MGMT_COMMAND)(txunit, CMR_SETTRACE, TRACE_OFF);
390 }
391 rxunit = -1;
392 txunit = -1;
393 }
394
395 if(cno >= 0)
396 {
397 (*ctrl_desc[cno].N_MGMT_COMMAND)(ctrl_desc[cno].unit, CMR_SETTRACE, TRACE_OFF);
398 }
399
400 x = SPLI4B();
401 device_state[unit] = ST_IDLE;
402 splx(x);
403
404 return(0);
405}
406
407/*---------------------------------------------------------------------------*
408 * read from trace device
409 *---------------------------------------------------------------------------*/
410PDEVSTATIC int
411i4btrcread(dev_t dev, struct uio * uio, int ioflag)
412{
413 struct mbuf *m;
414 int x;
415 int error = 0;
416 int unit = minor(dev);
417
418 if(!(device_state[unit] & ST_ISOPEN))
419 return(EIO);
420
421 x = SPLI4B();
422
423 IF_LOCK(&trace_queue[unit]);
424 while(IF_QEMPTY(&trace_queue[unit]) && (device_state[unit] & ST_ISOPEN))
425 {
426 device_state[unit] |= ST_WAITDATA;
427
428#if defined (__FreeBSD__) && __FreeBSD__ > 4
429 if((error = msleep((caddr_t) &trace_queue[unit],
430 &trace_queue[unit].ifq_mtx,
431 TTIPRI | PCATCH,
432 "bitrc", 0 )) != 0)
433#else
434 if((error = tsleep((caddr_t) &trace_queue[unit],
435 PCATCH, "bitrc", 0 )) != 0)
436#endif
437 {
438 device_state[unit] &= ~ST_WAITDATA;
439 IF_UNLOCK(&trace_queue[unit]);
440 splx(x);
441 return(error);
442 }
443 }
444
445 _IF_DEQUEUE(&trace_queue[unit], m);
446 IF_UNLOCK(&trace_queue[unit]);
447
448 if(m && m->m_len)
449 error = uiomove(m->m_data, m->m_len, uio);
450 else
451 error = EIO;
452
453 if(m)
454 i4b_Bfreembuf(m);
455
456 splx(x);
457
458 return(error);
459}
460
461#if defined(__FreeBSD__) && defined(OS_USES_POLL)
462/*---------------------------------------------------------------------------*
463 * poll device
464 *---------------------------------------------------------------------------*/
465PDEVSTATIC int
466i4btrcpoll(dev_t dev, int events, struct proc *p)
467{
468 return(ENODEV);
469}
470#endif
471
472/*---------------------------------------------------------------------------*
473 * device driver ioctl routine
474 *---------------------------------------------------------------------------*/
475PDEVSTATIC int
476#if defined (__FreeBSD_version) && __FreeBSD_version >= 300003
477i4btrcioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
478#elif defined(__bsdi__)
479i4btrcioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
480#else
481i4btrcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
482#endif
483{
484 int error = 0;
485 int unit = minor(dev);
486 i4b_trace_setupa_t *tsa;
487 int i;
488 int cno = -1;
489
490 /* find the first passive controller matching our unit no */
491
492 for(i=0; i < nctrl; i++)
493 {
494 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
495 (ctrl_desc[i].unit == unit))
496 {
497 cno = i;
498 break;
499 }
500 }
501
502 switch(cmd)
503 {
504 case I4B_TRC_SET:
505 if(cno < 0)
506 return ENOTTY;
507 (*ctrl_desc[cno].N_MGMT_COMMAND)(ctrl_desc[cno].unit, CMR_SETTRACE, (void *)*(unsigned int *)data);
508 break;
509
510 case I4B_TRC_SETA:
511 tsa = (i4b_trace_setupa_t *)data;
512
513 if(tsa->rxunit >= 0 && tsa->rxunit < NI4BTRC)
514 rxunit = tsa->rxunit;
515 else
516 error = EINVAL;
517
518 if(tsa->txunit >= 0 && tsa->txunit < NI4BTRC)
519 txunit = tsa->txunit;
520 else
521 error = EINVAL;
522
523 if(error)
524 {
525 outunit = -1;
526 rxunit = -1;
527 txunit = -1;
528 }
529 else
530 {
531 if(cno < 0)
532 return ENOTTY;
533
534 outunit = unit;
535 analyzemode = 1;
536 (*ctrl_desc[cno].N_MGMT_COMMAND)(rxunit, CMR_SETTRACE, (int *)(tsa->rxflags & (TRACE_I | TRACE_D_RX | TRACE_B_RX)));
537 (*ctrl_desc[cno].N_MGMT_COMMAND)(txunit, CMR_SETTRACE, (int *)(tsa->txflags & (TRACE_I | TRACE_D_RX | TRACE_B_RX)));
538 }
539 break;
540
541 case I4B_TRC_RESETA:
542 analyzemode = 0;
543 outunit = -1;
544 rxunit = -1;
545 txunit = -1;
546 break;
547
548 default:
549 error = ENOTTY;
550 break;
551 }
552 return(error);
553}
554
555#endif /* NI4BTRC > 0 */