static byte isdn_ind(ADAPTER * a, byte Ind, byte Id, byte Ch, PBUFFER * RBuffer, byte MInd, word MLength) { ENTITY * this; word clength; word offset; BUFFERS *R; #ifdef USE_EXTENDED_DEBUGS { ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ; DPRINTF(("IDI: <A%d Id=0x%x Ind=0x%x", io->ANum, Id, Ind)) } #else DPRINTF(("IDI: <IND(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch)); #endif if(a->IdTable[Id]) { this = entity_ptr(a,a->IdTable[Id]); this->IndCh = Ch; /* if the Receive More flag is not yet set, this is the */ /* first buffer of the packet */ if(this->RCurrent==0xff) { /* check for receive buffer chaining */ if(Ind==this->MInd) { this->complete = 0; this->Ind = MInd; } else { this->complete = 1; this->Ind = Ind; } /* call the application callback function for the receive */ /* look ahead */ this->RLength = MLength; a->ram_look_ahead(a, RBuffer, this); this->RNum = 0; CALLBACK(a, this); /* map entity ptr, selector could be re-mapped by call to */ /* IDI from within callback */ this = entity_ptr(a,a->IdTable[Id]); /* check for RNR */ if(this->RNR==1) { this->RNR = 0; return 1; } /* if no buffers are provided by the application, the */ /* application want to copy the data itself including */ /* N_MDATA/LL_MDATA chaining */ if(!this->RNR && !this->RNum) { return 0; } /* if there is no RNR, set the More flag */ this->RCurrent = 0; this->ROffset = 0; } if(this->RNR==2) { if(Ind!=this->MInd) { this->RCurrent = 0xff; this->RNR = 0; } return 0; } /* if we have received buffers from the application, copy */ /* the data into these buffers */ offset = 0; R = PTR_R(a,this); do { if(this->ROffset==R[this->RCurrent].PLength) { this->ROffset = 0; this->RCurrent++; } clength = a->ram_inw(a, &RBuffer->length)-offset; if (clength > R[this->RCurrent].PLength-this->ROffset) clength = R[this->RCurrent].PLength-this->ROffset; if(R[this->RCurrent].P) { a->ram_in_buffer(a, &RBuffer->P[offset], PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]), clength); } offset +=clength; this->ROffset +=clength; } while(offset<(a->ram_inw(a, &RBuffer->length))); /* if it's the last buffer of the packet, call the */ /* application callback function for the receive complete */ /* call */ if(Ind!=this->MInd) { R[this->RCurrent].PLength = this->ROffset; if(this->ROffset) this->RCurrent++; this->RNum = this->RCurrent; this->RCurrent = 0xff; this->Ind = Ind; this->complete = 2; CALLBACK(a, this); } return 0; } return 2; }
/*------------------------------------------------------------------*/ void pr_out(ADAPTER *a) { byte e_no; ENTITY *this = NULL; BUFFERS *X; word length; word i; word clength; REQ *ReqOut; byte more; byte ReadyCount; byte ReqCount; byte Id; dtrc(dprintf("pr_out")); /* while a request is pending ... */ e_no = look_req(a); if (!e_no) { dtrc(dprintf("no_req")); return; } ReadyCount = pr_ready(a); if (!ReadyCount) { dtrc(dprintf("not_ready")); return; } ReqCount = 0; while (e_no && ReadyCount) { next_req(a); this = entity_ptr(a, e_no); #ifdef USE_EXTENDED_DEBUGS if (!this) { DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore", xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum)) e_no = look_req(a); ReadyCount--; continue; } { DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req)) } #else dbug(dprintf("out:Req=%x,Id=%x,Ch=%x", this->Req, this->Id, this->ReqCh)); #endif /* get address of next available request buffer */ ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)]; #if defined(DIVA_ISTREAM) if (!(a->tx_stream[this->Id] && this->Req == N_DATA)) { #endif /* now copy the data from the current data buffer into the */ /* adapters request buffer */ length = 0; i = this->XCurrent; X = PTR_X(a, this); while (i < this->XNum && length < 270) { clength = min((word)(270 - length), (word)(X[i].PLength-this->XOffset)); a->ram_out_buffer(a, &ReqOut->XBuffer.P[length], PTR_P(a, this, &X[i].P[this->XOffset]), clength); length += clength; this->XOffset += clength; if (this->XOffset == X[i].PLength) { this->XCurrent = (byte)++i; this->XOffset = 0; } } #if defined(DIVA_ISTREAM) } else { /* Use CMA extension in order to transfer data to the card */ i = this->XCurrent; X = PTR_X(a, this); while (i < this->XNum) { diva_istream_write(a, this->Id, PTR_P(a, this, &X[i].P[0]), X[i].PLength, ((i + 1) == this->XNum), 0, 0); this->XCurrent = (byte)++i; } length = 0; } #endif a->ram_outw(a, &ReqOut->XBuffer.length, length); a->ram_out(a, &ReqOut->ReqId, this->Id); a->ram_out(a, &ReqOut->ReqCh, this->ReqCh); /* if it's a specific request (no ASSIGN) ... */ if (this->Id & 0x1f) { /* if buffers are left in the list of data buffers do */ /* do chaining (LL_MDATA, N_MDATA) */ this->More++; if (i < this->XNum && this->MInd) { xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->MInd, a->IdTypeTable[this->No]); a->ram_out(a, &ReqOut->Req, this->MInd); more = true; } else { xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req, a->IdTypeTable[this->No]); this->More |= XMOREF; a->ram_out(a, &ReqOut->Req, this->Req); more = false; if (a->FlowControlIdTable[this->ReqCh] == this->Id) a->FlowControlSkipTable[this->ReqCh] = true; /* Note that remove request was sent to the card */ if (this->Req == REMOVE) { a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING; } } /* if we did chaining, this entity is put back into the */ /* request queue */ if (more) { req_queue(a, this->No); } } /* else it's a ASSIGN */ else { /* save the request code used for buffer chaining */ this->MInd = 0; if (this->Id == BLLC_ID) this->MInd = LL_MDATA; if (this->Id == NL_ID || this->Id == TASK_ID || this->Id == MAN_ID ) this->MInd = N_MDATA; /* send the ASSIGN */ a->IdTypeTable[this->No] = this->Id; xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req, this->Id); this->More |= XMOREF; a->ram_out(a, &ReqOut->Req, this->Req); /* save the reference of the ASSIGN */ assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference)); } a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next)); ReadyCount--; ReqCount++; e_no = look_req(a); } /* send the filled request buffers to the ISDN adapter */ a->ram_out(a, &PR_RAM->ReqInput, (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount)); /* if it is a 'unreturncoded' UREMOVE request, remove the */ /* Id from our table after sending the request */ if (this && (this->Req == UREMOVE) && this->Id) { Id = this->Id; e_no = a->IdTable[Id]; free_entity(a, e_no); for (i = 0; i < 256; i++) { if (a->FlowControlIdTable[i] == Id) a->FlowControlIdTable[i] = 0; } a->IdTable[Id] = 0; this->Id = 0; } }
void DivasOut(ADAPTER * a) { byte e_no; ENTITY * this = NULL; BUFFERS *X; word length; word i; word clength; REQ * ReqOut; byte more; byte ReadyCount; byte ReqCount; byte Id; /* while a request is pending ... */ e_no = look_req(a); if(!e_no) { return; } ReadyCount = pr_ready(a); if(!ReadyCount) { DPRINTF(("IDI: card not ready for next request")); return; } ReqCount = 0; while(e_no && ReadyCount) { next_req(a); this = entity_ptr(a, e_no); #ifdef USE_EXTENDED_DEBUGS if ( !this ) { ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ; DBG_FTL(("!A%d ==> NULL entity ptr - try to ignore", (int)io->ANum)) e_no = look_req(a) ; ReadyCount-- ; continue ; } { ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ; DPRINTF(("IDI: >A%d Id=0x%x Req=0x%x", io->ANum, this->Id, this->Req)) } #else DPRINTF(("IDI: >REQ=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh)); #endif /* get address of next available request buffer */ ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)]; /* now copy the data from the current data buffer into the */ /* adapters request buffer */ length = 0; i = this->XCurrent; X = PTR_X(a,this); while(i<this->XNum && length<270) { clength = (word)(270-length); if (clength > X[i].PLength-this->XOffset) clength = X[i].PLength-this->XOffset; a->ram_out_buffer(a, &ReqOut->XBuffer.P[length], PTR_P(a,this,&X[i].P[this->XOffset]), clength); length +=clength; this->XOffset +=clength; if(this->XOffset==X[i].PLength) { this->XCurrent = (byte)++i; this->XOffset = 0; } } a->ram_outw(a, &ReqOut->XBuffer.length, length); a->ram_out(a, &ReqOut->ReqId, this->Id); a->ram_out(a, &ReqOut->ReqCh, this->ReqCh); /* if its a specific request (no ASSIGN) ... */ if(this->Id &0x1f) { /* if buffers are left in the list of data buffers do */ /* do chaining (LL_MDATA, N_MDATA) */ this->More++; if(i<this->XNum && this->MInd) { a->ram_out(a, &ReqOut->Req, this->MInd); more = TRUE; } else { this->More |=XMOREF; a->ram_out(a, &ReqOut->Req, this->Req); more = FALSE; } /* if we did chaining, this entity is put back into the */ /* request queue */ if(more) { req_queue(a,this->No); } } /* else it's a ASSIGN */ else { /* save the request code used for buffer chaining */ this->MInd = 0; if (this->Id==BLLC_ID) this->MInd = LL_MDATA; if (this->Id==NL_ID || this->Id==TASK_ID || this->Id==MAN_ID ) this->MInd = N_MDATA; /* send the ASSIGN */ this->More |=XMOREF; a->ram_out(a, &ReqOut->Req, this->Req); /* save the reference of the ASSIGN */ assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference)); } a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next)); ReadyCount--; ReqCount++; e_no = look_req(a); } /* send the filled request buffers to the ISDN adapter */ a->ram_out(a, &PR_RAM->ReqInput, (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount)); /* if it is a 'unreturncoded' UREMOVE request, remove the */ /* Id from our table after sending the request */ if(this->Req==UREMOVE && this->Id) { Id = this->Id; e_no = a->IdTable[Id]; free_entity(a, e_no); a->IdTable[Id] = 0; this->Id = 0; } }