| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) { | 
| Amol Lad | e2de257 | 2006-12-08 02:39:32 -0800 | [diff] [blame] | 136 | clength = min((word)(270-length),(word)(X[i].PLength-this->XOffset)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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); | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 176 | more = true; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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); | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 183 | more = false; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 184 | if (a->FlowControlIdTable[this->ReqCh] == this->Id) | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 185 | a->FlowControlSkipTable[this->ReqCh] = true; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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), | 
| Joe Perches | c66ed65 | 2008-02-03 17:16:28 +0200 | [diff] [blame] | 288 | tmp[0],  /* type of extended information */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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); | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 314 | a->ram_out(a, &IndIn->RNR, true); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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); | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 334 | a->ram_out(a, &IndIn->RNR, true); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | } | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 343 | return false; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | /*------------------------------------------------------------------*/ | 
| Hannes Eder | 4ee59d5 | 2008-12-16 01:17:33 -0800 | [diff] [blame] | 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) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 402 | a->RcExtensionSupported = true; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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; | 
| Richard Knutsson | 986c4bb | 2007-02-12 00:53:24 -0800 | [diff] [blame] | 431 | a->FlowControlSkipTable[Ch] = false; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | /*------------------------------------------------------------------*/ | 
| Hannes Eder | 4ee59d5 | 2008-12-16 01:17:33 -0800 | [diff] [blame] | 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) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | } | 
| Amol Lad | e2de257 | 2006-12-08 02:39:32 -0800 | [diff] [blame] | 625 | IoAdapter->RBuffer.length = min(MLength, (word)270); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) { | 
| Amol Lad | e2de257 | 2006-12-08 02:39:32 -0800 | [diff] [blame] | 679 | clength = min(MLength, (word)(R[this->RCurrent].PLength-this->ROffset)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 680 | } else { | 
| Amol Lad | e2de257 | 2006-12-08 02:39:32 -0800 | [diff] [blame] | 681 | clength = min(a->ram_inw(a, &RBuffer->length)-offset, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | 
| André Goddard Rosa | af901ca | 2009-11-14 13:09:05 -0200 | [diff] [blame] | 809 | RNum=0   - application had not returned any buffer to copy | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | } |