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; }
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 */ }
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); } }