Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/hardware/eicon/di.c
15115 views
1
2
/*
3
*
4
Copyright (c) Eicon Networks, 2002.
5
*
6
This source file is supplied for the use with
7
Eicon Networks range of DIVA Server Adapters.
8
*
9
Eicon File Revision : 2.1
10
*
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation; either version 2, or (at your option)
14
any later version.
15
*
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
See the GNU General Public License for more details.
20
*
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software
23
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
*
25
*/
26
#include "platform.h"
27
#include "pc.h"
28
#include "pr_pc.h"
29
#include "di_defs.h"
30
#include "di.h"
31
#if !defined USE_EXTENDED_DEBUGS
32
#include "dimaint.h"
33
#else
34
#define dprintf
35
#endif
36
#include "io.h"
37
#include "dfifo.h"
38
#define PR_RAM ((struct pr_ram *)0)
39
#define RAM ((struct dual *)0)
40
/*------------------------------------------------------------------*/
41
/* local function prototypes */
42
/*------------------------------------------------------------------*/
43
void pr_out(ADAPTER * a);
44
byte pr_dpc(ADAPTER * a);
45
static byte pr_ready(ADAPTER * a);
46
static byte isdn_rc(ADAPTER *, byte, byte, byte, word, dword, dword);
47
static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word);
48
/* -----------------------------------------------------------------
49
Functions used for the extended XDI Debug
50
macros
51
global convergence counter (used by all adapters)
52
Look by the implementation part of the functions
53
about the parameters.
54
If you change the dubugging parameters, then you should update
55
the aididbg.doc in the IDI doc's.
56
----------------------------------------------------------------- */
57
#if defined(XDI_USE_XLOG)
58
#define XDI_A_NR(_x_) ((byte)(((ISDN_ADAPTER *)(_x_->io))->ANum))
59
static void xdi_xlog (byte *msg, word code, int length);
60
static byte xdi_xlog_sec = 0;
61
#else
62
#define XDI_A_NR(_x_) ((byte)0)
63
#endif
64
static void xdi_xlog_rc_event (byte Adapter,
65
byte Id, byte Ch, byte Rc, byte cb, byte type);
66
static void xdi_xlog_request (byte Adapter, byte Id,
67
byte Ch, byte Req, byte type);
68
static void xdi_xlog_ind (byte Adapter,
69
byte Id,
70
byte Ch,
71
byte Ind,
72
byte rnr_valid,
73
byte rnr,
74
byte type);
75
/*------------------------------------------------------------------*/
76
/* output function */
77
/*------------------------------------------------------------------*/
78
void pr_out(ADAPTER * a)
79
{
80
byte e_no;
81
ENTITY * this = NULL;
82
BUFFERS *X;
83
word length;
84
word i;
85
word clength;
86
REQ * ReqOut;
87
byte more;
88
byte ReadyCount;
89
byte ReqCount;
90
byte Id;
91
dtrc(dprintf("pr_out"));
92
/* while a request is pending ... */
93
e_no = look_req(a);
94
if(!e_no)
95
{
96
dtrc(dprintf("no_req"));
97
return;
98
}
99
ReadyCount = pr_ready(a);
100
if(!ReadyCount)
101
{
102
dtrc(dprintf("not_ready"));
103
return;
104
}
105
ReqCount = 0;
106
while(e_no && ReadyCount) {
107
next_req(a);
108
this = entity_ptr(a, e_no);
109
#ifdef USE_EXTENDED_DEBUGS
110
if ( !this )
111
{
112
DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
113
xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
114
e_no = look_req(a) ;
115
ReadyCount-- ;
116
continue ;
117
}
118
{
119
DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
120
}
121
#else
122
dbug(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
123
#endif
124
/* get address of next available request buffer */
125
ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)];
126
#if defined(DIVA_ISTREAM)
127
if (!(a->tx_stream[this->Id] &&
128
this->Req == N_DATA)) {
129
#endif
130
/* now copy the data from the current data buffer into the */
131
/* adapters request buffer */
132
length = 0;
133
i = this->XCurrent;
134
X = PTR_X(a,this);
135
while(i<this->XNum && length<270) {
136
clength = min((word)(270-length),(word)(X[i].PLength-this->XOffset));
137
a->ram_out_buffer(a,
138
&ReqOut->XBuffer.P[length],
139
PTR_P(a,this,&X[i].P[this->XOffset]),
140
clength);
141
length +=clength;
142
this->XOffset +=clength;
143
if(this->XOffset==X[i].PLength) {
144
this->XCurrent = (byte)++i;
145
this->XOffset = 0;
146
}
147
}
148
#if defined(DIVA_ISTREAM)
149
} else { /* Use CMA extension in order to transfer data to the card */
150
i = this->XCurrent;
151
X = PTR_X(a,this);
152
while (i < this->XNum) {
153
diva_istream_write (a,
154
this->Id,
155
PTR_P(a,this,&X[i].P[0]),
156
X[i].PLength,
157
((i+1) == this->XNum),
158
0, 0);
159
this->XCurrent = (byte)++i;
160
}
161
length = 0;
162
}
163
#endif
164
a->ram_outw(a, &ReqOut->XBuffer.length, length);
165
a->ram_out(a, &ReqOut->ReqId, this->Id);
166
a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
167
/* if it's a specific request (no ASSIGN) ... */
168
if(this->Id &0x1f) {
169
/* if buffers are left in the list of data buffers do */
170
/* do chaining (LL_MDATA, N_MDATA) */
171
this->More++;
172
if(i<this->XNum && this->MInd) {
173
xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->MInd,
174
a->IdTypeTable[this->No]);
175
a->ram_out(a, &ReqOut->Req, this->MInd);
176
more = true;
177
}
178
else {
179
xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->Req,
180
a->IdTypeTable[this->No]);
181
this->More |=XMOREF;
182
a->ram_out(a, &ReqOut->Req, this->Req);
183
more = false;
184
if (a->FlowControlIdTable[this->ReqCh] == this->Id)
185
a->FlowControlSkipTable[this->ReqCh] = true;
186
/*
187
Note that remove request was sent to the card
188
*/
189
if (this->Req == REMOVE) {
190
a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING;
191
}
192
}
193
/* if we did chaining, this entity is put back into the */
194
/* request queue */
195
if(more) {
196
req_queue(a,this->No);
197
}
198
}
199
/* else it's a ASSIGN */
200
else {
201
/* save the request code used for buffer chaining */
202
this->MInd = 0;
203
if (this->Id==BLLC_ID) this->MInd = LL_MDATA;
204
if (this->Id==NL_ID ||
205
this->Id==TASK_ID ||
206
this->Id==MAN_ID
207
) this->MInd = N_MDATA;
208
/* send the ASSIGN */
209
a->IdTypeTable[this->No] = this->Id;
210
xdi_xlog_request (XDI_A_NR(a),this->Id,this->ReqCh,this->Req, this->Id);
211
this->More |=XMOREF;
212
a->ram_out(a, &ReqOut->Req, this->Req);
213
/* save the reference of the ASSIGN */
214
assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference));
215
}
216
a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next));
217
ReadyCount--;
218
ReqCount++;
219
e_no = look_req(a);
220
}
221
/* send the filled request buffers to the ISDN adapter */
222
a->ram_out(a, &PR_RAM->ReqInput,
223
(byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount));
224
/* if it is a 'unreturncoded' UREMOVE request, remove the */
225
/* Id from our table after sending the request */
226
if(this && (this->Req==UREMOVE) && this->Id) {
227
Id = this->Id;
228
e_no = a->IdTable[Id];
229
free_entity(a, e_no);
230
for (i = 0; i < 256; i++)
231
{
232
if (a->FlowControlIdTable[i] == Id)
233
a->FlowControlIdTable[i] = 0;
234
}
235
a->IdTable[Id] = 0;
236
this->Id = 0;
237
}
238
}
239
static byte pr_ready(ADAPTER * a)
240
{
241
byte ReadyCount;
242
ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) -
243
a->ram_in(a, &PR_RAM->ReqInput));
244
if(!ReadyCount) {
245
if(!a->ReadyInt) {
246
a->ram_inc(a, &PR_RAM->ReadyInt);
247
a->ReadyInt++;
248
}
249
}
250
return ReadyCount;
251
}
252
/*------------------------------------------------------------------*/
253
/* isdn interrupt handler */
254
/*------------------------------------------------------------------*/
255
byte pr_dpc(ADAPTER * a)
256
{
257
byte Count;
258
RC * RcIn;
259
IND * IndIn;
260
byte c;
261
byte RNRId;
262
byte Rc;
263
byte Ind;
264
/* if return codes are available ... */
265
if((Count = a->ram_in(a, &PR_RAM->RcOutput)) != 0) {
266
dtrc(dprintf("#Rc=%x",Count));
267
/* get the buffer address of the first return code */
268
RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)];
269
/* for all return codes do ... */
270
while(Count--) {
271
if((Rc=a->ram_in(a, &RcIn->Rc)) != 0) {
272
dword tmp[2];
273
/*
274
Get extended information, associated with return code
275
*/
276
a->ram_in_buffer(a,
277
&RcIn->Reserved2[0],
278
(byte*)&tmp[0],
279
8);
280
/* call return code handler, if it is not our return code */
281
/* the handler returns 2 */
282
/* for all return codes we process, we clear the Rc field */
283
isdn_rc(a,
284
Rc,
285
a->ram_in(a, &RcIn->RcId),
286
a->ram_in(a, &RcIn->RcCh),
287
a->ram_inw(a, &RcIn->Reference),
288
tmp[0], /* type of extended information */
289
tmp[1]); /* extended information */
290
a->ram_out(a, &RcIn->Rc, 0);
291
}
292
/* get buffer address of next return code */
293
RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)];
294
}
295
/* clear all return codes (no chaining!) */
296
a->ram_out(a, &PR_RAM->RcOutput ,0);
297
/* call output function */
298
pr_out(a);
299
}
300
/* clear RNR flag */
301
RNRId = 0;
302
/* if indications are available ... */
303
if((Count = a->ram_in(a, &PR_RAM->IndOutput)) != 0) {
304
dtrc(dprintf("#Ind=%x",Count));
305
/* get the buffer address of the first indication */
306
IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)];
307
/* for all indications do ... */
308
while(Count--) {
309
/* if the application marks an indication as RNR, all */
310
/* indications from the same Id delivered in this interrupt */
311
/* are marked RNR */
312
if(RNRId && RNRId==a->ram_in(a, &IndIn->IndId)) {
313
a->ram_out(a, &IndIn->Ind, 0);
314
a->ram_out(a, &IndIn->RNR, true);
315
}
316
else {
317
Ind = a->ram_in(a, &IndIn->Ind);
318
if(Ind) {
319
RNRId = 0;
320
/* call indication handler, a return value of 2 means chain */
321
/* a return value of 1 means RNR */
322
/* for all indications we process, we clear the Ind field */
323
c = isdn_ind(a,
324
Ind,
325
a->ram_in(a, &IndIn->IndId),
326
a->ram_in(a, &IndIn->IndCh),
327
&IndIn->RBuffer,
328
a->ram_in(a, &IndIn->MInd),
329
a->ram_inw(a, &IndIn->MLength));
330
if(c==1) {
331
dtrc(dprintf("RNR"));
332
a->ram_out(a, &IndIn->Ind, 0);
333
RNRId = a->ram_in(a, &IndIn->IndId);
334
a->ram_out(a, &IndIn->RNR, true);
335
}
336
}
337
}
338
/* get buffer address of next indication */
339
IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)];
340
}
341
a->ram_out(a, &PR_RAM->IndOutput, 0);
342
}
343
return false;
344
}
345
byte scom_test_int(ADAPTER * a)
346
{
347
return a->ram_in(a,(void *)0x3fe);
348
}
349
void scom_clear_int(ADAPTER * a)
350
{
351
a->ram_out(a,(void *)0x3fe,0);
352
}
353
/*------------------------------------------------------------------*/
354
/* return code handler */
355
/*------------------------------------------------------------------*/
356
static byte isdn_rc(ADAPTER *a,
357
byte Rc,
358
byte Id,
359
byte Ch,
360
word Ref,
361
dword extended_info_type,
362
dword extended_info)
363
{
364
ENTITY * this;
365
byte e_no;
366
word i;
367
int cancel_rc;
368
#ifdef USE_EXTENDED_DEBUGS
369
{
370
DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
371
}
372
#else
373
dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
374
#endif
375
/* check for ready interrupt */
376
if(Rc==READY_INT) {
377
xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, 0);
378
if(a->ReadyInt) {
379
a->ReadyInt--;
380
return 0;
381
}
382
return 2;
383
}
384
/* if we know this Id ... */
385
e_no = a->IdTable[Id];
386
if(e_no) {
387
this = entity_ptr(a,e_no);
388
xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, a->IdTypeTable[this->No]);
389
this->RcCh = Ch;
390
/* if it is a return code to a REMOVE request, remove the */
391
/* Id from our table */
392
if ((a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_REMOVE_PENDING) &&
393
(Rc==OK)) {
394
if (a->IdTypeTable[e_no] == NL_ID) {
395
if (a->RcExtensionSupported &&
396
(extended_info_type != DIVA_RC_TYPE_REMOVE_COMPLETE)) {
397
dtrc(dprintf("XDI: N-REMOVE, A(%02x) Id:%02x, ignore RC=OK",
398
XDI_A_NR(a),Id));
399
return (0);
400
}
401
if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE)
402
a->RcExtensionSupported = true;
403
}
404
a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING;
405
a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING;
406
free_entity(a, e_no);
407
for (i = 0; i < 256; i++)
408
{
409
if (a->FlowControlIdTable[i] == Id)
410
a->FlowControlIdTable[i] = 0;
411
}
412
a->IdTable[Id] = 0;
413
this->Id = 0;
414
/* ---------------------------------------------------------------
415
If we send N_DISC or N_DISK_ACK after we have received OK_FC
416
then the card will respond with OK_FC and later with RC==OK.
417
If we send N_REMOVE in this state we will receive only RC==OK
418
This will create the state in that the XDI is waiting for the
419
additional RC and does not delivery the RC to the client. This
420
code corrects the counter of outstanding RC's in this case.
421
--------------------------------------------------------------- */
422
if ((this->More & XMOREC) > 1) {
423
this->More &= ~XMOREC;
424
this->More |= 1;
425
dtrc(dprintf("XDI: correct MORE on REMOVE A(%02x) Id:%02x",
426
XDI_A_NR(a),Id));
427
}
428
}
429
if (Rc==OK_FC) {
430
a->FlowControlIdTable[Ch] = Id;
431
a->FlowControlSkipTable[Ch] = false;
432
this->Rc = Rc;
433
this->More &= ~(XBUSY | XMOREC);
434
this->complete=0xff;
435
xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
436
CALLBACK(a, this);
437
return 0;
438
}
439
/*
440
New protocol code sends return codes that comes from release
441
of flow control condition marked with DIVA_RC_TYPE_OK_FC extended
442
information element type.
443
If like return code arrives then application is able to process
444
all return codes self and XDI should not cances return codes.
445
This return code does not decrement XMOREC partial return code
446
counter due to fact that it was no request for this return code,
447
also XMOREC was not incremented.
448
*/
449
if (extended_info_type == DIVA_RC_TYPE_OK_FC) {
450
a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_NO_RC_CANCELLING;
451
this->Rc = Rc;
452
this->complete=0xff;
453
xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
454
DBG_TRC(("XDI OK_FC A(%02x) Id:%02x Ch:%02x Rc:%02x",
455
XDI_A_NR(a), Id, Ch, Rc))
456
CALLBACK(a, this);
457
return 0;
458
}
459
cancel_rc = !(a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_NO_RC_CANCELLING);
460
if (cancel_rc && (a->FlowControlIdTable[Ch] == Id))
461
{
462
a->FlowControlIdTable[Ch] = 0;
463
if ((Rc != OK) || !a->FlowControlSkipTable[Ch])
464
{
465
this->Rc = Rc;
466
if (Ch == this->ReqCh)
467
{
468
this->More &=~(XBUSY | XMOREC);
469
this->complete=0xff;
470
}
471
xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
472
CALLBACK(a, this);
473
}
474
return 0;
475
}
476
if (this->More &XMOREC)
477
this->More--;
478
/* call the application callback function */
479
if (((!cancel_rc) || (this->More & XMOREF)) && !(this->More & XMOREC)) {
480
this->Rc = Rc;
481
this->More &=~XBUSY;
482
this->complete=0xff;
483
xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
484
CALLBACK(a, this);
485
}
486
return 0;
487
}
488
/* if it's an ASSIGN return code check if it's a return */
489
/* code to an ASSIGN request from us */
490
if((Rc &0xf0)==ASSIGN_RC) {
491
e_no = get_assign(a, Ref);
492
if(e_no) {
493
this = entity_ptr(a,e_no);
494
this->Id = Id;
495
xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 2, a->IdTypeTable[this->No]);
496
/* call the application callback function */
497
this->Rc = Rc;
498
this->More &=~XBUSY;
499
this->complete=0xff;
500
#if defined(DIVA_ISTREAM) /* { */
501
if ((Rc == ASSIGN_OK) && a->ram_offset &&
502
(a->IdTypeTable[this->No] == NL_ID) &&
503
((extended_info_type == DIVA_RC_TYPE_RX_DMA) ||
504
(extended_info_type == DIVA_RC_TYPE_CMA_PTR)) &&
505
extended_info) {
506
dword offset = (*(a->ram_offset)) (a);
507
dword tmp[2];
508
extended_info -= offset;
509
#ifdef PLATFORM_GT_32BIT
510
a->ram_in_dw(a, (void*)ULongToPtr(extended_info), (dword*)&tmp[0], 2);
511
#else
512
a->ram_in_dw(a, (void*)extended_info, (dword*)&tmp[0], 2);
513
#endif
514
a->tx_stream[Id] = tmp[0];
515
a->rx_stream[Id] = tmp[1];
516
if (extended_info_type == DIVA_RC_TYPE_RX_DMA) {
517
DBG_TRC(("Id=0x%x RxDMA=%08x:%08x",
518
Id, a->tx_stream[Id], a->rx_stream[Id]))
519
a->misc_flags_table[this->No] |= DIVA_MISC_FLAGS_RX_DMA;
520
} else {
521
DBG_TRC(("Id=0x%x CMA=%08x:%08x",
522
Id, a->tx_stream[Id], a->rx_stream[Id]))
523
a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
524
a->rx_pos[Id] = 0;
525
a->rx_stream[Id] -= offset;
526
}
527
a->tx_pos[Id] = 0;
528
a->tx_stream[Id] -= offset;
529
} else {
530
a->tx_stream[Id] = 0;
531
a->rx_stream[Id] = 0;
532
a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
533
}
534
#endif /* } */
535
CALLBACK(a, this);
536
if(Rc==ASSIGN_OK) {
537
a->IdTable[Id] = e_no;
538
}
539
else
540
{
541
free_entity(a, e_no);
542
for (i = 0; i < 256; i++)
543
{
544
if (a->FlowControlIdTable[i] == Id)
545
a->FlowControlIdTable[i] = 0;
546
}
547
a->IdTable[Id] = 0;
548
this->Id = 0;
549
}
550
return 1;
551
}
552
}
553
return 2;
554
}
555
/*------------------------------------------------------------------*/
556
/* indication handler */
557
/*------------------------------------------------------------------*/
558
static byte isdn_ind(ADAPTER *a,
559
byte Ind,
560
byte Id,
561
byte Ch,
562
PBUFFER *RBuffer,
563
byte MInd,
564
word MLength)
565
{
566
ENTITY * this;
567
word clength;
568
word offset;
569
BUFFERS *R;
570
byte* cma = NULL;
571
#ifdef USE_EXTENDED_DEBUGS
572
{
573
DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
574
}
575
#else
576
dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch));
577
#endif
578
if(a->IdTable[Id]) {
579
this = entity_ptr(a,a->IdTable[Id]);
580
this->IndCh = Ch;
581
xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
582
0/* rnr_valid */, 0 /* rnr */, a->IdTypeTable[this->No]);
583
/* if the Receive More flag is not yet set, this is the */
584
/* first buffer of the packet */
585
if(this->RCurrent==0xff) {
586
/* check for receive buffer chaining */
587
if(Ind==this->MInd) {
588
this->complete = 0;
589
this->Ind = MInd;
590
}
591
else {
592
this->complete = 1;
593
this->Ind = Ind;
594
}
595
/* call the application callback function for the receive */
596
/* look ahead */
597
this->RLength = MLength;
598
#if defined(DIVA_ISTREAM)
599
if ((a->rx_stream[this->Id] ||
600
(a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA)) &&
601
((Ind == N_DATA) ||
602
(a->protocol_capabilities & PROTCAP_CMA_ALLPR))) {
603
PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io ;
604
if (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA) {
605
#if defined(DIVA_IDI_RX_DMA)
606
dword d;
607
diva_get_dma_map_entry (\
608
(struct _diva_dma_map_entry*)IoAdapter->dma_map,
609
(int)a->rx_stream[this->Id], (void**)&cma, &d);
610
#else
611
cma = &a->stream_buffer[0];
612
cma[0] = cma[1] = cma[2] = cma[3] = 0;
613
#endif
614
this->RLength = MLength = (word)*(dword*)cma;
615
cma += 4;
616
} else {
617
int final = 0;
618
cma = &a->stream_buffer[0];
619
this->RLength = MLength = (word)diva_istream_read (a,
620
Id,
621
cma,
622
sizeof(a->stream_buffer),
623
&final, NULL, NULL);
624
}
625
IoAdapter->RBuffer.length = min(MLength, (word)270);
626
if (IoAdapter->RBuffer.length != MLength) {
627
this->complete = 0;
628
} else {
629
this->complete = 1;
630
}
631
memcpy (IoAdapter->RBuffer.P, cma, IoAdapter->RBuffer.length) ;
632
this->RBuffer = (DBUFFER *)&IoAdapter->RBuffer ;
633
}
634
#endif
635
if (!cma) {
636
a->ram_look_ahead(a, RBuffer, this);
637
}
638
this->RNum = 0;
639
CALLBACK(a, this);
640
/* map entity ptr, selector could be re-mapped by call to */
641
/* IDI from within callback */
642
this = entity_ptr(a,a->IdTable[Id]);
643
xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
644
1/* rnr_valid */, this->RNR/* rnr */, a->IdTypeTable[this->No]);
645
/* check for RNR */
646
if(this->RNR==1) {
647
this->RNR = 0;
648
return 1;
649
}
650
/* if no buffers are provided by the application, the */
651
/* application want to copy the data itself including */
652
/* N_MDATA/LL_MDATA chaining */
653
if(!this->RNR && !this->RNum) {
654
xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
655
2/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
656
return 0;
657
}
658
/* if there is no RNR, set the More flag */
659
this->RCurrent = 0;
660
this->ROffset = 0;
661
}
662
if(this->RNR==2) {
663
if(Ind!=this->MInd) {
664
this->RCurrent = 0xff;
665
this->RNR = 0;
666
}
667
return 0;
668
}
669
/* if we have received buffers from the application, copy */
670
/* the data into these buffers */
671
offset = 0;
672
R = PTR_R(a,this);
673
do {
674
if(this->ROffset==R[this->RCurrent].PLength) {
675
this->ROffset = 0;
676
this->RCurrent++;
677
}
678
if (cma) {
679
clength = min(MLength, (word)(R[this->RCurrent].PLength-this->ROffset));
680
} else {
681
clength = min(a->ram_inw(a, &RBuffer->length)-offset,
682
R[this->RCurrent].PLength-this->ROffset);
683
}
684
if(R[this->RCurrent].P) {
685
if (cma) {
686
memcpy (PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]),
687
&cma[offset],
688
clength);
689
} else {
690
a->ram_in_buffer(a,
691
&RBuffer->P[offset],
692
PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]),
693
clength);
694
}
695
}
696
offset +=clength;
697
this->ROffset +=clength;
698
if (cma) {
699
if (offset >= MLength) {
700
break;
701
}
702
continue;
703
}
704
} while(offset<(a->ram_inw(a, &RBuffer->length)));
705
/* if it's the last buffer of the packet, call the */
706
/* application callback function for the receive complete */
707
/* call */
708
if(Ind!=this->MInd) {
709
R[this->RCurrent].PLength = this->ROffset;
710
if(this->ROffset) this->RCurrent++;
711
this->RNum = this->RCurrent;
712
this->RCurrent = 0xff;
713
this->Ind = Ind;
714
this->complete = 2;
715
xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
716
3/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
717
CALLBACK(a, this);
718
}
719
return 0;
720
}
721
return 2;
722
}
723
#if defined(XDI_USE_XLOG)
724
/* -----------------------------------------------------------
725
This function works in the same way as xlog on the
726
active board
727
----------------------------------------------------------- */
728
static void xdi_xlog (byte *msg, word code, int length) {
729
xdi_dbg_xlog ("\x00\x02", msg, code, length);
730
}
731
#endif
732
/* -----------------------------------------------------------
733
This function writes the information about the Return Code
734
processing in the trace buffer. Trace ID is 221.
735
INPUT:
736
Adapter - system unicue adapter number (0 ... 255)
737
Id - Id of the entity that had sent this return code
738
Ch - Channel of the entity that had sent this return code
739
Rc - return code value
740
cb: (0...2)
741
switch (cb) {
742
case 0: printf ("DELIVERY"); break;
743
case 1: printf ("CALLBACK"); break;
744
case 2: printf ("ASSIGN"); break;
745
}
746
DELIVERY - have entered isdn_rc with this RC
747
CALLBACK - about to make callback to the application
748
for this RC
749
ASSIGN - about to make callback for RC that is result
750
of ASSIGN request. It is no DELIVERY message
751
before of this message
752
type - the Id that was sent by the ASSIGN of this entity.
753
This should be global Id like NL_ID, DSIG_ID, MAN_ID.
754
An unknown Id will cause "?-" in the front of the request.
755
In this case the log.c is to be extended.
756
----------------------------------------------------------- */
757
static void xdi_xlog_rc_event (byte Adapter,
758
byte Id, byte Ch, byte Rc, byte cb, byte type) {
759
#if defined(XDI_USE_XLOG)
760
word LogInfo[4];
761
PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
762
PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
763
PUT_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
764
PUT_WORD(&LogInfo[3], cb);
765
xdi_xlog ((byte*)&LogInfo[0], 221, sizeof(LogInfo));
766
#endif
767
}
768
/* ------------------------------------------------------------------------
769
This function writes the information about the request processing
770
in the trace buffer. Trace ID is 220.
771
INPUT:
772
Adapter - system unicue adapter number (0 ... 255)
773
Id - Id of the entity that had sent this request
774
Ch - Channel of the entity that had sent this request
775
Req - Code of the request
776
type - the Id that was sent by the ASSIGN of this entity.
777
This should be global Id like NL_ID, DSIG_ID, MAN_ID.
778
An unknown Id will cause "?-" in the front of the request.
779
In this case the log.c is to be extended.
780
------------------------------------------------------------------------ */
781
static void xdi_xlog_request (byte Adapter, byte Id,
782
byte Ch, byte Req, byte type) {
783
#if defined(XDI_USE_XLOG)
784
word LogInfo[3];
785
PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
786
PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
787
PUT_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
788
xdi_xlog ((byte*)&LogInfo[0], 220, sizeof(LogInfo));
789
#endif
790
}
791
/* ------------------------------------------------------------------------
792
This function writes the information about the indication processing
793
in the trace buffer. Trace ID is 222.
794
INPUT:
795
Adapter - system unicue adapter number (0 ... 255)
796
Id - Id of the entity that had sent this indication
797
Ch - Channel of the entity that had sent this indication
798
Ind - Code of the indication
799
rnr_valid: (0 .. 3) supported
800
switch (rnr_valid) {
801
case 0: printf ("DELIVERY"); break;
802
case 1: printf ("RNR=%d", rnr);
803
case 2: printf ("RNum=0");
804
case 3: printf ("COMPLETE");
805
}
806
DELIVERY - indication entered isdn_rc function
807
RNR=... - application had returned RNR=... after the
808
look ahead callback
809
RNum=0 - application had not returned any buffer to copy
810
this indication and will copy it self
811
COMPLETE - XDI had copied the data to the buffers provided
812
bu the application and is about to issue the
813
final callback
814
rnr: Look case 1 of the rnr_valid
815
type: the Id that was sent by the ASSIGN of this entity. This should
816
be global Id like NL_ID, DSIG_ID, MAN_ID. An unknown Id will
817
cause "?-" in the front of the request. In this case the
818
log.c is to be extended.
819
------------------------------------------------------------------------ */
820
static void xdi_xlog_ind (byte Adapter,
821
byte Id,
822
byte Ch,
823
byte Ind,
824
byte rnr_valid,
825
byte rnr,
826
byte type) {
827
#if defined(XDI_USE_XLOG)
828
word LogInfo[4];
829
PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
830
PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
831
PUT_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
832
PUT_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
833
xdi_xlog ((byte*)&LogInfo[0], 222, sizeof(LogInfo));
834
#endif
835
}
836
837