!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/isdn/eicon/   drwxr-xr-x
Free 318.31 GB of 458.09 GB (69.49%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     idi.c (19.36 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * Core driver for Diva Server cards
 * Implements the IDI interface
 *
 * Copyright (C) Eicon Technology Corporation, 2000.
 *
 * Eicon File Revision :    1.8  
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include "idi.h"
#include "adapter.h"
#include "pc.h"
#include "pr_pc.h"
#include "sys.h"
#include "uxio.h"

/* IDI request functions */

static void    request(card_t *card, ENTITY *e);

static void req_0(ENTITY *e)    { request(&DivasCards[ 0], e); }
static void req_1(ENTITY *e)    { request(&DivasCards[ 1], e); }
static void req_2(ENTITY *e)    { request(&DivasCards[ 2], e); }
static void req_3(ENTITY *e)    { request(&DivasCards[ 3], e); }
static void req_4(ENTITY *e)    { request(&DivasCards[ 4], e); }
static void req_5(ENTITY *e)    { request(&DivasCards[ 5], e); }
static void req_6(ENTITY *e)    { request(&DivasCards[ 6], e); }
static void req_7(ENTITY *e)    { request(&DivasCards[ 7], e); }
static void req_8(ENTITY *e)    { request(&DivasCards[ 8], e); }
static void req_9(ENTITY *e)    { request(&DivasCards[ 9], e); }
static void req_10(ENTITY *e)    { request(&DivasCards[10], e); }
static void req_11(ENTITY *e)    { request(&DivasCards[11], e); }
static void req_12(ENTITY *e)    { request(&DivasCards[12], e); }
static void req_13(ENTITY *e)    { request(&DivasCards[13], e); }
static void req_14(ENTITY *e)    { request(&DivasCards[14], e); }
static void req_15(ENTITY *e)    { request(&DivasCards[15], e); }

IDI_CALL DivasIdiRequest[16] =
{
    &req_0,        &req_1,        &req_2,        &req_3,
    &req_4,        &req_5,        &req_6,        &req_7,
    &req_8,        &req_9,        &req_10,    &req_11,
    &req_12,    &req_13,    &req_14,    &req_15
};

#define PR_RAM  ((struct pr_ram *)0)
#define RAM ((struct dual *)0)

/*------------------------------------------------------------------*/
/* local function prototypes                                        */
/*------------------------------------------------------------------*/

static byte isdn_rc(ADAPTER *, byte, byte, byte, word);
static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word);

/*
 * IDI related functions
 */

static
ENTITY    *entity_ptr(ADAPTER *a, byte e_no)
{
    card_t    *card;

    card = a->io;

    return card->e_tbl[e_no].e;
}

static
void    CALLBACK(ADAPTER *a, ENTITY *e)
{
    card_t    *card = a->io;

    if (card->log_types & DIVAS_LOG_IDI)
    {
        DivasLogIdi(card, e, FALSE);
    }

    (*e->callback)(e);
}

static
void    *PTR_P(ADAPTER *a, ENTITY *e, void *P)
{
    return(P);
}

static
void    *PTR_R(ADAPTER *a, ENTITY *e)
{
    return((void*)e->R);
}

static
void    *PTR_X(ADAPTER *a, ENTITY *e)
{
    return((void*)e->X);
}

static
void    free_entity(ADAPTER *a, byte e_no) 
{
    card_t    *card;
    int        ipl;

    card = a->io;

    ipl = UxCardLock(card->hw);

    card->e_tbl[e_no].e = NULL;
    card->e_count--;

    UxCardUnlock(card->hw, ipl);

    return;
}

static
void    assign_queue(ADAPTER * a, byte e_no, word ref)
{
    card_t    *card;
    int        ipl;

    card = a->io;

    ipl = UxCardLock(card->hw);

    card->e_tbl[e_no].assign_ref = ref;
    card->e_tbl[e_no].next = card->assign;
    card->assign = e_no;

    UxCardUnlock(card->hw, ipl);

    return;
}

static
byte    get_assign(ADAPTER *a, word ref)
{
    card_t    *card;
    byte    e_no;
    int        ipl;

    card = a->io;

    ipl = UxCardLock(card->hw);

    e_no = (byte)card->assign;
    while (e_no)
    {
        if (card->e_tbl[e_no].assign_ref == ref)
        {
            break;
        }
        e_no = card->e_tbl[e_no].next;
    }

    UxCardUnlock(card->hw, ipl);

    return e_no;
}

static
void    req_queue(ADAPTER * a, byte e_no)
{
    card_t    *card;
    int        ipl;

    card = a->io;

    ipl = UxCardLock(card->hw);

    card->e_tbl[e_no].next = 0;

    if (card->e_head)
    {
        card->e_tbl[card->e_tail].next = e_no;
        card->e_tail = e_no;
    }
    else
    {
        card->e_head = e_no;
        card->e_tail = e_no;
    }

    UxCardUnlock(card->hw, ipl);

    return;
}

static
byte    look_req(ADAPTER * a)
{
    card_t    *card;

    card = a->io;

    return(card->e_head);
}

static
void    next_req(ADAPTER * a)
{
    card_t    *card;
    int        ipl;


    card = a->io;

    ipl = UxCardLock(card->hw);

    card->e_head = card->e_tbl[card->e_head].next;
    if (!card->e_head)
    {
        card->e_tail = 0;
    }

    UxCardUnlock(card->hw, ipl);

    return;
}


/*
 * IDI request function for active cards
 */
static
void    request(card_t *card, ENTITY *e)
{
    word    *special_req;
    int        i;
    int        ipl;


    if (card->log_types & DIVAS_LOG_IDI)
    {
        DivasLogIdi(card, e, TRUE);
    }

    if (!e->Req)
    {
        special_req = (word *) e;

        switch (*special_req)
        {
        case REQ_REMOVE:
            return;

        case REQ_NAME:
            for (i=0; i < DIM(card->cfg.name); i++)
            {
                ((struct get_name_s *) e)->name[i] = card->cfg.name[i];
            }
            return;

        case REQ_SERIAL:
        case REQ_XLOG:
            DPRINTF(("IDI: attempted REQ_SERIAL or REQ_XLOG"));
            return;

        default:
            return;
        }
    }

    ipl = UxCardLock(card->hw);

       if (!(e->Id & 0x1f))
    {
        DPRINTF(("IDI: ASSIGN req"));

        for (i = 1; i < card->e_max; i++)
        {
            if (!card->e_tbl[i].e)
            {
                break;
            }
        }

        if (i == card->e_max)
        {
            DPRINTF(("IDI: request all ids in use (IDI req ignored)"));
            UxCardUnlock(card->hw, ipl);
            e->Rc = OUT_OF_RESOURCES;
            return;
        }

        card->e_tbl[i].e = e;
        card->e_count++;

        e->No = (byte) i;
        e->More = 0;
        e->RCurrent = 0xff;
    }
    else
    {
        i = e->No;
    }
    
    if (e->More & XBUSY)
    {
        DPRINTF(("IDI: request - entity is busy"));
        UxCardUnlock(card->hw, ipl);
        return;
    }

    e->More |= XBUSY;
    e->More &= ~ XMOREF;
    e->XCurrent = 0;
    e->XOffset = 0;

    card->e_tbl[i].next = 0;

    if(card->e_head)
    {
        card->e_tbl[card->e_tail].next = i;
        card->e_tail = i;
    }
    else
    {
        card->e_head = i;
        card->e_tail = i;
    }

    UxCardUnlock(card->hw, ipl);

    DivasScheduleRequestDpc();

    return;
}

static byte pr_ready(ADAPTER * a)
{
  byte ReadyCount;

  ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) -
                      a->ram_in(a, &PR_RAM->ReqInput));

  if(!ReadyCount) {
    if(!a->ReadyInt) {
      a->ram_inc(a, &PR_RAM->ReadyInt);
      a->ReadyInt++;
    }
  }
  return ReadyCount;
}

/*------------------------------------------------------------------*/
/* output function                                                  */
/*------------------------------------------------------------------*/

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;
  }

}

/*------------------------------------------------------------------*/
/* isdn interrupt handler                                           */
/*------------------------------------------------------------------*/

byte DivasDpc(ADAPTER * a)
{
  byte Count;
  RC * RcIn;
  IND * IndIn;
  byte c;
  byte RNRId;
  byte Rc;
  byte Ind;

        /* if return codes are available ...                        */
  if((Count = a->ram_in(a, &PR_RAM->RcOutput))) {

    DPRINTF(("IDI: #Rc=%x",Count));

        /* get the buffer address of the first return code          */
    RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)];

        /* for all return codes do ...                              */
    while(Count--) {

      if((Rc=a->ram_in(a, &RcIn->Rc))) {

        /* call return code handler, if it is not our return code   */
        /* the handler returns 2                                    */
        /* for all return codes we process, we clear the Rc field   */
        isdn_rc(a,
                Rc,
                a->ram_in(a, &RcIn->RcId),
                a->ram_in(a, &RcIn->RcCh),
                a->ram_inw(a, &RcIn->Reference));

        a->ram_out(a, &RcIn->Rc, 0);
      }

        /* get buffer address of next return code                   */
      RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)];
    }

        /* clear all return codes (no chaining!)                    */
    a->ram_out(a, &PR_RAM->RcOutput ,0);

        /* call output function                                     */
    DivasOut(a);
  }

        /* clear RNR flag                                           */
  RNRId = 0;

        /* if indications are available ...                         */
  if((Count = a->ram_in(a, &PR_RAM->IndOutput))) {

    DPRINTF(("IDI: #Ind=%x",Count));

        /* get the buffer address of the first indication           */
    IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)];

        /* for all indications do ...                               */
    while(Count--) {

        /* if the application marks an indication as RNR, all       */
        /* indications from the same Id delivered in this interrupt */
        /* are marked RNR                                           */
      if(RNRId && RNRId==a->ram_in(a, &IndIn->IndId)) {
        a->ram_out(a, &IndIn->Ind, 0);
        a->ram_out(a, &IndIn->RNR, TRUE);
      }
      else {
        Ind = a->ram_in(a, &IndIn->Ind);
        if(Ind) {
          RNRId = 0;

        /* call indication handler, a return value of 2 means chain */
        /* a return value of 1 means RNR                            */
        /* for all indications we process, we clear the Ind field   */
          c = isdn_ind(a,
                       Ind,
                       a->ram_in(a, &IndIn->IndId),
                       a->ram_in(a, &IndIn->IndCh),
                       &IndIn->RBuffer,
                       a->ram_in(a, &IndIn->MInd),
                       a->ram_inw(a, &IndIn->MLength));

          if(c==1) {
            DPRINTF(("IDI: RNR"));
            a->ram_out(a, &IndIn->Ind, 0);
            RNRId = a->ram_in(a, &IndIn->IndId);
            a->ram_out(a, &IndIn->RNR, TRUE);
          }
        }
      }

        /* get buffer address of next indication                    */
      IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)];
    }

    a->ram_out(a, &PR_RAM->IndOutput, 0);
  }
  return FALSE;
}

byte DivasTestInt(ADAPTER * a)
{
  return a->ram_in(a,(void *)0x3fe);
}

void DivasClearInt(ADAPTER * a)
{
  a->ram_out(a,(void *)0x3fe,0); 
}

/*------------------------------------------------------------------*/
/* return code handler                                              */
/*------------------------------------------------------------------*/

static
byte isdn_rc(ADAPTER * a,
             byte Rc,
             byte Id,
             byte Ch,
             word Ref)
{
  ENTITY  * this;
  byte e_no;

#ifdef    USE_EXTENDED_DEBUGS
    {
        ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
        DPRINTF(("IDI: <A%d Id=0x%x Rc=0x%x", io->ANum, Id, Rc))
    }
#else
  DPRINTF(("IDI: <RC(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
#endif

        /* check for ready interrupt                                */
  if(Rc==READY_INT) {
    if(a->ReadyInt) {
      a->ReadyInt--;
      return 0;
    }
    return 2;
  }

        /* if we know this Id ...                                   */
  e_no = a->IdTable[Id];
  if(e_no) {

    this = entity_ptr(a,e_no);

    this->RcCh = Ch;

        /* if it is a return code to a REMOVE request, remove the   */
        /* Id from our table                                        */
    if(this->Req==REMOVE && Rc==OK) {
      free_entity(a, e_no);
      a->IdTable[Id] = 0;
      this->Id = 0;
/**************************************************************/
      if ((this->More & XMOREC) > 1) {
        this->More &= ~XMOREC;
    this->More |= 1;
    DPRINTF(("isdn_rc, Id=%x, correct More on REMOVE", Id));
      }
    }

    if (Rc==OK_FC) {
      this->Rc = Rc;
      this->More = (this->More & (~XBUSY | XMOREC)) | 1;
      this->complete = 0xFF;
      CALLBACK(a, this);
      return 0;
    }
    if(this->More &XMOREC)
      this->More--;

        /* call the application callback function                   */
    if(this->More &XMOREF && !(this->More &XMOREC)) {
      this->Rc = Rc;
      this->More &=~XBUSY;
      this->complete=0xff;
      CALLBACK(a, this);
    }
    return 0;
  }

        /* if it's an ASSIGN return code check if it's a return     */
        /* code to an ASSIGN request from us                        */
  if((Rc &0xf0)==ASSIGN_RC) {

    e_no = get_assign(a, Ref);

    if(e_no) {

      this = entity_ptr(a,e_no);

      this->Id = Id;

        /* call the application callback function                   */
      this->Rc = Rc;
      this->More &=~XBUSY;
      this->complete=0xff;
      CALLBACK(a, this);

      if(Rc==ASSIGN_OK) {
        a->IdTable[Id] = e_no;
      }
      else
      {
        free_entity(a, e_no);
        a->IdTable[Id] = 0;
        this->Id = 0;
      }
      return 1;
    }
  }
  return 2;
}

/*------------------------------------------------------------------*/
/* indication handler                                               */
/*------------------------------------------------------------------*/

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;
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0059 ]--