]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i4b/layer1/i4b_l1.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / sys / i4b / layer1 / i4b_l1.c
1 /*
2  * Copyright (c) 1997, 1999 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_l1.c - isdn4bsd layer 1 handler
28  *      -----------------------------------
29  *
30  *      $Id: i4b_l1.c,v 1.2 1999/12/13 21:25:26 hm Exp $ 
31  *
32  * $FreeBSD$
33  *
34  *      last edit-date: [Mon Dec 13 22:01:55 1999]
35  *
36  *---------------------------------------------------------------------------*/
37
38 #include "isic.h"
39
40 #if NISIC > 0
41
42 #include <sys/param.h>
43 #include <sys/ioccom.h>
44 #include <sys/kernel.h>
45 #include <sys/systm.h>
46 #include <sys/mbuf.h>
47 #include <sys/socket.h>
48
49 #include <machine/stdarg.h>
50 #include <machine/clock.h>
51
52 #include <net/if.h>
53
54 #include <machine/i4b_debug.h>
55 #include <machine/i4b_ioctl.h>
56 #include <machine/i4b_trace.h>
57
58 #include <i4b/layer1/i4b_l1.h>
59 #include <i4b/layer1/i4b_isac.h>
60 #include <i4b/layer1/i4b_hscx.h>
61
62 #include <i4b/include/i4b_l1l2.h>
63 #include <i4b/include/i4b_mbuf.h>
64 #include <i4b/include/i4b_global.h>
65
66 unsigned int i4b_l1_debug = L1_DEBUG_DEFAULT;
67
68 static int ph_data_req(int, struct mbuf *, int);
69 static int ph_activate_req(int);
70
71 /* from i4btrc driver i4b_trace.c */
72 extern int get_trace_data_from_l1(int unit, int what, int len, char *buf);
73
74 /* from layer 2 */
75 extern int i4b_ph_data_ind(int unit, struct mbuf *m);
76 extern int i4b_ph_activate_ind(int unit);
77 extern int i4b_ph_deactivate_ind(int unit);
78 extern int i4b_mph_attach_ind(int unit);
79 extern int i4b_mph_status_ind(int, int, int);
80
81 /* layer 1 lme */
82 static int i4b_mph_command_req(int, int, int);
83
84 /* jump table */
85 struct i4b_l1l2_func i4b_l1l2_func = {
86
87         /* Layer 1 --> Layer 2 */
88         
89         (int (*)(int, struct mbuf *))           i4b_ph_data_ind,
90         (int (*)(int))                          i4b_ph_activate_ind,
91         (int (*)(int))                          i4b_ph_deactivate_ind,
92
93         /* Layer 2 --> Layer 1 */
94
95         (int (*)(int, struct mbuf *, int))      ph_data_req,
96         (int (*)(int))                          ph_activate_req,
97
98         /* Layer 1 --> upstream, ISDN trace data */
99
100         (int (*)(i4b_trace_hdr_t *, int, u_char *))     get_trace_data_from_l1,
101
102         /* Driver control and status information */
103
104         (int (*)(int, int, int))                i4b_mph_status_ind,
105         (int (*)(int, int, int))                i4b_mph_command_req,
106 };
107  
108 /*---------------------------------------------------------------------------*
109  *
110  *      L2 -> L1: PH-DATA-REQUEST
111  *      =========================
112  *
113  *      parms:
114  *              unit            physical interface unit number
115  *              m               mbuf containing L2 frame to be sent out
116  *              freeflag        MBUF_FREE: free mbuf here after having sent
117  *                                              it out
118  *                              MBUF_DONTFREE: mbuf is freed by Layer 2
119  *      returns:
120  *              ==0     fail, nothing sent out
121  *              !=0     ok, frame sent out
122  *
123  *---------------------------------------------------------------------------*/
124 static int
125 ph_data_req(int unit, struct mbuf *m, int freeflag)
126 {
127         u_char cmd;
128         int s;
129         struct l1_softc *sc = &l1_sc[unit];
130
131 #ifdef NOTDEF
132         DBGL1(L1_PRIM, "PH-DATA-REQ", ("unit %d, freeflag=%d\n", unit, freeflag));
133 #endif
134
135         if(m == NULL)                   /* failsafe */
136                 return (0);
137
138         s = SPLI4B();
139
140         if(sc->sc_I430state == ST_F3)   /* layer 1 not running ? */
141         {
142                 DBGL1(L1_I_ERR, "ph_data_req", ("still in state F3!\n"));
143                 ph_activate_req(unit);
144         }
145
146         if(sc->sc_state & ISAC_TX_ACTIVE)
147         {
148                 if(sc->sc_obuf2 == NULL)
149                 {
150                         sc->sc_obuf2 = m;               /* save mbuf ptr */
151
152                         if(freeflag)
153                                 sc->sc_freeflag2 = 1;   /* IRQ must mfree */
154                         else
155                                 sc->sc_freeflag2 = 0;   /* IRQ must not mfree */
156
157                         DBGL1(L1_I_MSG, "ph_data_req", ("using 2nd ISAC TX buffer, state = %s\n", isic_printstate(sc)));
158
159                         if(sc->sc_trace & TRACE_D_TX)
160                         {
161                                 i4b_trace_hdr_t hdr;
162                                 hdr.unit = unit;
163                                 hdr.type = TRC_CH_D;
164                                 hdr.dir = FROM_TE;
165                                 hdr.count = ++sc->sc_trace_dcount;
166                                 MICROTIME(hdr.time);
167                                 MPH_Trace_Ind(&hdr, m->m_len, m->m_data);
168                         }
169                         splx(s);
170                         return(1);
171                 }
172
173                 DBGL1(L1_I_ERR, "ph_data_req", ("No Space in TX FIFO, state = %s\n", isic_printstate(sc)));
174         
175                 if(freeflag == MBUF_FREE)
176                         i4b_Dfreembuf(m);                       
177         
178                 splx(s);
179                 return (0);
180         }
181
182         if(sc->sc_trace & TRACE_D_TX)
183         {
184                 i4b_trace_hdr_t hdr;
185                 hdr.unit = unit;
186                 hdr.type = TRC_CH_D;
187                 hdr.dir = FROM_TE;
188                 hdr.count = ++sc->sc_trace_dcount;
189                 MICROTIME(hdr.time);
190                 MPH_Trace_Ind(&hdr, m->m_len, m->m_data);
191         }
192         
193         sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */
194
195         DBGL1(L1_I_MSG, "ph_data_req", ("ISAC_TX_ACTIVE set\n"));
196
197         sc->sc_freeflag = 0;            /* IRQ must NOT mfree */
198         
199         ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */
200
201         if(m->m_len > ISAC_FIFO_LEN)    /* message > 32 bytes ? */
202         {
203                 sc->sc_obuf = m;        /* save mbuf ptr */
204                 sc->sc_op = m->m_data + ISAC_FIFO_LEN;  /* ptr for irq hdl */
205                 sc->sc_ol = m->m_len - ISAC_FIFO_LEN;   /* length for irq hdl */
206
207                 if(freeflag)
208                         sc->sc_freeflag = 1;    /* IRQ must mfree */
209                 
210                 cmd = ISAC_CMDR_XTF;
211         }
212         else
213         {
214                 sc->sc_obuf = NULL;
215                 sc->sc_op = NULL;
216                 sc->sc_ol = 0;
217
218                 if(freeflag)
219                         i4b_Dfreembuf(m);
220
221                 cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
222         }
223
224         ISAC_WRITE(I_CMDR, cmd);
225         ISACCMDRWRDELAY();
226
227         splx(s);
228         
229         return(1);
230 }
231
232 /*---------------------------------------------------------------------------*
233  *
234  *      L2 -> L1: PH-ACTIVATE-REQUEST
235  *      =============================
236  *
237  *      parms:
238  *              unit    physical interface unit number
239  *
240  *      returns:
241  *              ==0     
242  *              !=0     
243  *
244  *---------------------------------------------------------------------------*/
245 static int
246 ph_activate_req(int unit)
247 {
248         struct l1_softc *sc = &l1_sc[unit];
249         DBGL1(L1_PRIM, "PH-ACTIVATE-REQ", ("unit %d\n", unit));
250         isic_next_state(sc, EV_PHAR);
251         return(0);
252 }
253
254 /*---------------------------------------------------------------------------*
255  *      command from the upper layers
256  *---------------------------------------------------------------------------*/
257 static int
258 i4b_mph_command_req(int unit, int command, int parm)
259 {
260         struct l1_softc *sc = &l1_sc[unit];
261
262         switch(command)
263         {
264                 case CMR_DOPEN:         /* daemon running */
265                         DBGL1(L1_PRIM, "MPH-COMMAND-REQ", ("unit %d, command = CMR_DOPEN\n", unit));
266                         sc->sc_enabled = 1;                     
267                         break;
268                         
269                 case CMR_DCLOSE:        /* daemon not running */
270                         DBGL1(L1_PRIM, "MPH-COMMAND-REQ", ("unit %d, command = CMR_DCLOSE\n", unit));
271                         sc->sc_enabled = 0;
272                         break;
273
274                 default:
275                         DBGL1(L1_ERROR, "i4b_mph_command_req", ("ERROR, unknown command = %d, unit = %d, parm = %d\n", command, unit, parm));
276                         break;
277         }
278
279         return(0);
280 }
281
282 #endif /* NISIC > 0 */