void davicom_close(PIFACE pi) /*__fn__*/ { PDAVICOM_SOFTC softc; int i; if (pi->minor_number >= CFG_NUM_DAVICOM) { set_errno( ENUMDEVICE ); return; } softc = iface_to_davicom_softc(pi); if (!softc) { set_errno(ENUMDEVICE); return; } /* issue stop receive command */ WRITE_CR(DC_MODE_CR6, 0); /* stop interrupts */ WRITE_CR(DC_ISR_MASK_CR7, 0); /* free receive buffers */ for (i = 0; i < DC_RX_RING_SIZE; i++) { os_free_packet( softc->rx_dcus[i] ); } }
void timeout(void * vsc) { PDAVICOM_SOFTC softc = vsc; if (softc->OutOfBuffers) { int i; softc->OutOfBuffers = 0; for (i=0; i<DC_RX_RING_SIZE; i++) { PDESCRIPTOR pdesc = softc->rx_desc + i; if (pdesc->buffer == 0) { DCU msg; softc->rx_dcus[i] = msg = os_alloc_packet_input(CFG_MAX_PACKETSIZE+4, DRIVER_ALLOC); if (msg) { pdesc->buffer = (dword) DCUTODATA(msg); pdesc->status = OWN_BIT; #if DEBUG_DAVICOM DEBUG_ERROR("davicom_timeout: added new receive DCU", NOVAR, 0, 0); #endif } else { #if DEBUG_DAVICOM DEBUG_ERROR("davicom_timeout: out of DCUs", NOVAR, 0, 0); #endif } } } /* get receiver going again */ #if DEBUG_DAVICOM DEBUG_ERROR("davicom_timeout: restart receiver stalled at ", EBS_INT1, softc->this_rx, 0); #endif softc->this_rx = 0; WRITE_CR(DC_RX_BASE_ADDR_CR3, (dword)(softc->rx_desc)); WRITE_CR(DC_RX_START_CR2, 0xFFFFFFFF); } ebs_start_timer(&softc->timer); }
void mc6821_write(struct MC6821 *pia, uint16_t A, uint8_t D) { switch (A & 3) { default: case 0: WRITE_DR(pia->a, D); UPDATE_OUTPUT_A(pia->a); break; case 1: WRITE_CR(pia->a, D); break; case 2: WRITE_DR(pia->b, D); UPDATE_OUTPUT_B(pia->b); break; case 3: WRITE_CR(pia->b, D); break; } }
void davicom_interrupt(int minor_no) { dword status; PDAVICOM_SOFTC softc; PDESCRIPTOR pdesc; DCU msg; int pkt_len; softc = off_to_davicom_softc(minor_no); if (!softc) return; status = READ_CR(DC_STATUS_ISR_CR5); WRITE_CR(DC_STATUS_ISR_CR5, status); status &= DC_STATUS_MASK; /* keep only bits we are interested in */ if (status & DC_ISR_RX_DONE) while (1) { pdesc = softc->rx_desc + softc->this_rx; if (pdesc->buffer == 0) break; if (pdesc->status & OWN_BIT) break; if ((pdesc->status & (ES_BIT|PLE_BIT|AE_BIT)) == 0) /* no error */ { pkt_len = (pdesc->status >> 16) & 2047; msg = softc->rx_dcus[softc->this_rx]; /* set up length of packet; MUST be set to actual size */ /* not including crc etc even if allocated a larger */ /* packet above */ DCUTOPACKET(msg)->length = pkt_len; softc->stats.packets_in++; softc->stats.bytes_in += pkt_len; /* signal IP layer that a packet is on its exchange' */ /* send packet from ring buffer */ ks_invoke_input(softc->iface, msg); /* replace current DCU from ring buffer just passed to */ /* IP task with a new DCU */ softc->rx_dcus[softc->this_rx] = msg = os_alloc_packet_input(CFG_MAX_PACKETSIZE+4, DRIVER_ALLOC); if (msg) pdesc->buffer = (dword) DCUTODATA(msg); else { pdesc->buffer = 0; /* out of buffers */ DEBUG_ERROR("davicom_interrupt: out of DCUs", NOVAR, 0, 0); } } else /* error receive, discard */ {
RTIP_BOOLEAN davicom_open(PIFACE pi) { PDAVICOM_SOFTC softc; int i; unsigned short w; PFBYTE p; if (davicom_softc[pi->minor_number] == NULL) { p = ks_malloc(sizeof(*softc)+16-1-4, PACKET_POOL_MALLOC, DRV_MALLOC); /* make sure on 16 byte boundary first */ while (((dword)p) & 15) p++; davicom_softc[pi->minor_number] = (PDAVICOM_SOFTC) p; } softc = iface_to_davicom_softc(pi); if (!softc) { set_errno(ENUMDEVICE); return (FALSE); } tc_memset((PFBYTE)softc, 0, sizeof(*softc)); /* Set up the private data structure so that it points to the global interface */ /* structure. (address is needed later when returning packets) */ softc->iface = pi; pi->driver_stats.ether_stats = (PETHER_STATS)&(softc->stats); /* ************************************************************ */ #if (CFG_DAVICOM_PCI) /* read/write suitable values for the PCI configuration registers */ if (!davicom_pci_init(pi, softc)) { DEBUG_ERROR("davicom_open: PCI register configuration failed", NOVAR, 0, 0); set_errno(EPROBEFAIL); /* ??check for a PCI init failed error code?? */ return(FALSE); } #endif /* CFG_DAVICOM_PCI */ /* ************************************************************ */ /* reset the Davicom chip */ WRITE_CR(DC_SCR_CR0, DC_SCR_SW_RESET); /* wait at least 32 PCI clock cycles */ ks_sleep(2); /* ************************************************************ */ /* read local Ethernet address from EEPROM */ w = davicom_read_srom_word( softc, 10 ); /* was 20 */ pi->addr.my_hw_addr[0] = (unsigned char) w; pi->addr.my_hw_addr[1] = (unsigned char) (w >> 8); w = davicom_read_srom_word( softc, 11 ); /* was 22 */ pi->addr.my_hw_addr[2] = (unsigned char) w; pi->addr.my_hw_addr[3] = (unsigned char) (w >> 8); w = davicom_read_srom_word( softc, 12 ); /* was 24 */ pi->addr.my_hw_addr[4] = (unsigned char) w; pi->addr.my_hw_addr[5] = (unsigned char) (w >> 8); #if (DEBUG_DAVICOM) DEBUG_ERROR("ETHERNET ADDRESS: ", ETHERADDR, pi->addr.my_hw_addr, 0); #endif /* ************************************************************ */ /* create the Tx descriptors */ for (i=0; i < DC_TX_RING_SIZE; i++) softc->tx_desc[i].nxt_desc = (dword) (softc->tx_desc + ((i+1) & DC_TX_RING_MASK)); /* create the Rx descriptors */ for (i=0; i < DC_RX_RING_SIZE; i++) { softc->rx_dcus[i] = os_alloc_packet_input(CFG_MAX_PACKETSIZE+4, DRIVER_ALLOC); if (!softc->rx_dcus[i]) { DEBUG_ERROR("davicom_init: out of DCUs", NOVAR, 0, 0); return(set_errno(ENOPKTS)); } softc->rx_desc[i].buffer = (dword) DCUTODATA(softc->rx_dcus[i]); softc->rx_desc[i].ctrl_flags = (CFG_MAX_PACKETSIZE+4) | (1<<24); softc->rx_desc[i].nxt_desc = (dword) (softc->rx_desc + ((i+1) & DC_RX_RING_MASK)); softc->rx_desc[i].status = OWN_BIT; } /* write CR3 and CR4 to provide the starting address of each descriptor */ /* list */ WRITE_CR(DC_RX_BASE_ADDR_CR3, (dword)(softc->rx_desc)); WRITE_CR(DC_TX_BASE_ADDR_CR4, (dword)(softc->tx_desc)); /* ************************************************************ */ /* Write CR0 to set global host bus operation parameters */ WRITE_CR( DC_SCR_CR0, 0 ); /* ************************************************************ */ /* hook the interrupt based up PCI values read */ ks_hook_interrupt(softc->dav_irq, (PFVOID) pi, (RTIPINTFN_POINTER)davicom_interrupt, (RTIPINTFN_POINTER)davicom_pre_interrupt, pi->minor_number); /* ************************************************************ */ /* write CR7 to mask causes of unnecessary interrupt */ WRITE_CR(DC_ISR_MASK_CR7, /* normal */ DC_IMR_NISE | /* Normal interrupt enable */ DC_IMR_RXCIE | /* Receive complete interrupt */ /* DC_IMR_TXDUE | */ /* Transmit buffer unavailable enabled */ DC_IMR_TXCIE | /* Transmit complete interrupt enable */ /* abnormal */ DC_IMR_AISE | /* Abnormal interrupt enable */ DC_IMR_RXDUE | /* Receive buffer unavailable */ DC_IMR_TXFUE); /* Transmit fifo underrun enabled */ #define DC_STATUS_MASK (DC_ISR_RX_DONE | DC_ISR_TX_DONE | DC_ISR_ABNORMAL | DC_ISR_TX_UNDERRUN | DC_ISR_RX_NOBUF) #if (DEBUG_DAVICOM) DEBUG_ERROR("davicom_init: start rcv and xmit", NOVAR, 0, 0); #endif /* ************************************************************ * write CR6 to set global parameters and start both receive and transmit * processes; start receive * DC_MODE_TX_SC - start transmitter * DC_MODE_RX_RC - start receiver * DC_MODE_PAM - receive multicasts * DC_MODE_1_PKT */ WRITE_CR(DC_MODE_CR6, (1<<26) | DC_MODE_SFT_XMIT | /* wait with transmit until all data is in fifo (disable threshold) */ DC_MODE_1_PKT | /* only one packet in transmit fifo */ (3<<14) | /* max threshohld */ DC_MODE_TX_SC | /* start transmit */ /* DC_MODE_PAM | // receive multicasts */ DC_MODE_RX_RC | /* start receive */ 0); /* ************************************************************ */ softc->timer.func = timeout; /* routine to execute every second */ softc->timer.arg = softc; ebs_set_timer(&softc->timer, 1, TRUE); ebs_start_timer(&softc->timer); return(TRUE); }