Пример #1
0
AdpErrs DevSW_Close (DeviceDescr *device, const DevChanID type)
{
    DevSWState *ds = (DevSWState *)(device->SwitcherState);
    Packet *pk;

    if ((ds->ds_opendevchans & (1 << type)) == 0)
        return adp_device_not_open;

    ds->ds_opendevchans &= ~(1 << type);

    /*
     * if this is the last close for this channel, then inform the driver
     */
    if (ds->ds_opendevchans == 0)
        device->DeviceClose();

    /*
     * release all packets of the appropriate type
     */
    for (pk = Adp_removeFromQueue(&(ds->ds_readqueue[type]));
         pk != NULL;
         pk = Adp_removeFromQueue(&(ds->ds_readqueue[type])))
        DevSW_FreePacket(pk);

    /* Free memory */
    free ((char *) device->SwitcherState);
    device->SwitcherState = 0x0;

    /* that's all */
    return adp_ok;
}
Пример #2
0
AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
                   Packet **packet, bool block)
{
  int read_err;
  DevSWState *ds = device->SwitcherState;

    /*
     * To try to get information out of the device driver as
     * quickly as possible, we try and read more packets, even
     * if a completed packet is already available.
     */

    /*
     * have we got a packet currently pending?
     */
  if (ds->ds_nextreadpacket == NULL)
    /*
       * no - set things up
       */
    if (initialise_read(ds) < 0) {
      /*
       * we failed to initialise the next packet, but can
       * still return a packet that has already arrived.
       */
      *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]); 
      return adp_ok;
    }
  read_err = device->DeviceRead(&ds->ds_activeread, block);
  switch (read_err) {
  case 1:
    /*
     * driver has pulled in a complete packet, queue it up
     */
#ifdef RET_DEBUG
    printf("got a complete packet\n");
#endif
    
    if (angelDebugLogEnable)
      dumpPacket(angelDebugLogFile,"rx:",&ds->ds_activeread.dc_packet);

    enqueue_packet(ds);
    *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
    return adp_ok;
  case 0:
    /*
     * OK, return the head of the read queue for the given type
     */
    /*    enqueue_packet(ds); */
    *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
    return adp_ok;
  case -1:
#ifdef RET_DEBUG
    printf("got a bad packet\n");
#endif
    /* bad packet */
    *packet = NULL;
    return adp_bad_packet;
  default:
    panic("DevSW_Read: bad read status %d", read_err);
  }
  return 0; /* get rid of a potential compiler warning */
}
Пример #3
0
static void async_process_write( const AsyncMode mode,
                                 bool *const finished  )
{
    Packet *packet;

#ifdef DEBUG
    static unsigned int num_written = 0;
#endif

    /*
     * NOTE: here we rely in the fact that any packet in the writeQueueSend
     * section of the queue will need its sequence number setting up while
     * and packet in the writeQueueRoot section will have its sequence
     * numbers set up from when it was first sent so we can easily look
     * up the packet numbers when(if) we want to resend the packet.
     */

#ifdef DEBUG
    if (writeQueueSend!=NULL)
       printf("written 0x%x\n",num_written += writeQueueSend->pk_length);
#endif
    /*
     * give the switcher a chance to complete any partial writes
     */
    if (DevSW_FlushPendingWrite(deviceToUse) == adp_write_busy)
    {
        /* no point trying a new write */
        return;
    }

    /*
     * now see whether there is anything to write
     */
    packet = NULL;
    if (resending) {
        packet = resend_pkt;
#ifdef RET_DEBUG
        printf("resending hseq 0x%x oseq 0x%x\n",
               packet->pk_buffer[CF_HOME_SEQ_BYTE_POS],
               packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
#endif
    }
    else if (writeQueueSend != NULL) {
#ifdef RETRANS
        /* set up the sequence number on the packet */
        packet = writeQueueSend;
        HomeSeq++;
        (writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS])
            = OppoSeq;
        (writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS])
            = HomeSeq;
        (writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS])
            = CF_RELIABLE;
# ifdef RET_DEBUG
        printf("sending packet with hseq 0x%x oseq 0x%x\n",
               writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS],
               writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
# endif
#endif /* RETRANS */
    }

    if (packet != NULL) {
        AdpErrs dev_err;

#ifdef FAKE_BAD_LINE_TX
        fake_bad_line_tx();
#endif

        dev_err = DevSW_Write(deviceToUse, packet, DC_DBUG);
        if (dev_err == adp_ok) {
#ifdef RETRANS
            if (resending) {
                /* check to see if we've recovered yet */
                if ((packet->pk_next) == NULL){
# ifdef RET_DEBUG
                    printf("we have recovered\n");
# endif
                    resending = FALSE;
                }
                else {
                    resend_pkt = resend_pkt->pk_next;
                }
            }
            else {
                /*
                 * move the packet we just sent from the send queue to the root
                 */
                Packet *tmp_pkt, *tmp;

# ifdef FAKE_BAD_LINE_TX
                unfake_bad_line_tx();
# endif

                tmp_pkt = writeQueueSend;
                writeQueueSend = writeQueueSend->pk_next;
                tmp_pkt->pk_next = NULL;
                if (writeQueueRoot == NULL)
                   writeQueueRoot = tmp_pkt;
                else {
                    tmp = writeQueueRoot;
                    while (tmp->pk_next != NULL) {
                        tmp = tmp->pk_next;
                    }
                    tmp->pk_next = tmp_pkt;
                }
            }
#else  /* not RETRANS */
            /*
             * switcher has taken the write, so remove it from the
             * queue, and free its resources
             */
            DevSW_FreePacket(Adp_removeFromQueue(&writeQueueSend));
#endif /* if RETRANS ... else ... */

            if (mode == async_block_on_write)
               *finished = DevSW_WriteFinished(deviceToUse);

        } /* endif write ok */
    }
    else /* packet == NULL */
    {
        if (mode == async_block_on_write)
           *finished = DevSW_WriteFinished(deviceToUse);
    }
}