コード例 #1
0
ファイル: ethInterrupt.c プロジェクト: BridgeNY/purdue
/*------------------------------------------------------------------------
 * ethInterrupt - decode and handle interrupt from an Ethernet device
 *------------------------------------------------------------------------
 */
interrupt ethInterrupt(void)
{
	struct	ether	*ethptr;	/* ptr to control block		*/
	struct	ag71xx	*nicptr;	/* ptr to device CSRs 		*/
	uint32	status;
	uint32	mask;

	/* Initialize structure pointers */

	ethptr = &ethertab[0];		/* default physical Ethernet	*/
	if (!ethptr) {
		return;
	}
	nicptr = ethptr->csr;
	if (!nicptr) {
		return;
	}

	/* Obtain status bits from device */

	mask = nicptr->interruptMask;
	status = nicptr->interruptStatus & mask;

	/* Record status in ether struct */

	ethptr->interruptStatus = status;

	if (status == 0) {
		return;
	}

	sched_cntl(DEFER_START);

	if (status & IRQ_TX_PKTSENT) {	/* handle transmitter interrupt	*/
		ethptr->txirq++;
		txPackets(ethptr, nicptr);
	}

	if (status & IRQ_RX_PKTRECV) {	/* handle receiver interrupt	*/
		ethptr->rxirq++;
		rxPackets(ethptr, nicptr);
	}

	/* Handle errors (transmit or receive overflow) */

	if (status & IRQ_RX_OVERFLOW) {
		/* Clear interrupt and restart processing */
		nicptr->rxStatus = RX_STAT_OVERFLOW;
		nicptr->rxControl = RX_CTRL_RXE;
		ethptr->errors++;
	}

	if ((status & IRQ_TX_UNDERFLOW) ||
		(status & IRQ_TX_BUSERR) || (status & IRQ_RX_BUSERR)) {
		panic("Catastrophic Ethernet error");
	}
	sched_cntl(DEFER_STOP);
	return;
}
コード例 #2
0
ファイル: e1000Interrupt.c プロジェクト: eerpini/Xinu-RPL
/*------------------------------------------------------------------------
 * e1000Interrupt - decode and handle interrupt from an E1000 device
 *------------------------------------------------------------------------
 */
interrupt e1000Interrupt(void)
{
	uint32	status;
	struct  dentry  *devptr;        /* address of device control blk*/
	struct 	ether 	*ethptr;	/* ptr to control block		*/

	/* Initialize structure pointers */

	devptr = (struct dentry *) &devtab[ETHER0];
	
	/* Obtain a pointer to the tty control block */

	ethptr = &ethertab[devptr->dvminor];

	/* Invoke the device-specific interrupt handler */

	/* Disable device interrupt */

	e1000IrqDisable(ethptr);

	/* Obtain status bits from device */

	status = e1000_io_readl(ethptr->iobase, E1000_ICR);

	/* Not our interrupt */

	if (status == 0) {
		e1000IrqEnable(ethptr);
		return;
	}

	sched_cntl(DEFER_START);

	if (status & E1000_ICR_LSC) {
	}

	if (status & E1000_ICR_RXT0) {
		ethptr->rxIrq++;
		e1000_rxPackets(ethptr);
	}

	if (status & E1000_ICR_TXDW) {
		ethptr->txIrq++;
		e1000_txPackets(ethptr);
	}

	/* Enable device interrupt */

	e1000IrqEnable(ethptr);
	
	sched_cntl(DEFER_STOP);

	return;
}
コード例 #3
0
ファイル: udp.c プロジェクト: eerpini/Xinu-RPL
/*------------------------------------------------------------------------
 * udp_release - release a previously-registered UDP slot
 *------------------------------------------------------------------------
 */
status	udp_release (
	 uid32	slot			/* table slot to release	*/
	)
{
	intmask	mask;			/* saved interrupt mask		*/
	struct	udpentry *udptr;	/* pointer to udptab entry	*/
	struct	netpacket *pkt;		/* ptr to packet being read	*/

	/* Insure only one process can access the UDP table at a time */

	mask = disable();

	/* Verify that the slot is valid */

	if ( (slot < 0) || (slot >= UDP_SLOTS) ) {
		restore(mask);
		return SYSERR;
	}

	/* Get pointer to table entry */

	udptr = &udptab[slot];

	/* Verify that the slot has been registered and is valid */

	if (udptr->udstate == UDP_FREE) {
		restore(mask);
		return SYSERR;
	}

	sched_cntl(DEFER_START);
	while (udptr->udcount > 0) {
		pkt = udptr->udqueue[udptr->udhead++];
		if (udptr->udhead >= UDP_QSIZ) {
			udptr->udhead = 0;
		}
		freebuf((char *)pkt);
		udptr->udcount--;
	}
	udptr->udstate = UDP_FREE;
	sched_cntl(DEFER_STOP);
	restore(mask);
	return OK;
}
コード例 #4
0
ファイル: udp.c プロジェクト: eerpini/Xinu-RPL
/*------------------------------------------------------------------------
 * udp_release - release a previously-registered remote IP, remote
 *			port, and local port (exact match required)
 *------------------------------------------------------------------------
 */
status	udp_release (
    uint32	remip,			/* remote IP address or zero	*/
    uint16	remport,		/* remote UDP protocol port	*/
    uint16	locport			/* local UDP protocol port	*/
)
{
    int32	i;			/* index into udptab		*/
    struct	udpentry *udptr;	/* pointer to udptab entry	*/
    struct	eth_packet *pkt;		/* ptr to packet being read	*/

    for (i=0; i<UDP_SLOTS; i++) {
        udptr = &udptab[i];
        if (udptr->udstate != UDP_USED) {
            continue;
        }
        if ((remport == udptr->udremport) &&
                (locport == udptr->udlocport) &&
                (remip   == udptr->udremip  ) ) {

            /* Entry in table matches */

            sched_cntl(DEFER_START);
            while (udptr->udcount > 0) {
                pkt = udptr->udqueue[udptr->udhead++];
                if (udptr->udhead >= UDP_SLOTS) {
                    udptr->udhead = 0;
                }
                freebuf((char *)pkt);
                udptr->udcount--;
            }
            udptr->udstate = UDP_FREE;
            sched_cntl(DEFER_STOP);
            return OK;
        }
    }
    return SYSERR;
}
コード例 #5
0
ファイル: e100_intr.c プロジェクト: jhngzhu/OS-Driver
void 	e100_txPackets(struct	ether *ethptr)		/* ptr to control block		*/						 
{
	struct	e100_tx_desc *descptr;/* ptr to ring descriptor 	*/
	uint32 	head; 			/* pos to reclaim descriptor	*/
	char 	*pktptr; 		/* ptr used during packet copy  */
	int 	numdesc; 		/* num. of descriptor reclaimed	*/

	//kprintf("SCB Status = %2x\r\n", inb(ethptr->iobase + E100_STATUS));
	//kprintf("Enter e100_txPackets\r\n");
	for (numdesc = 0; numdesc < E100_BLK_PER_INT; numdesc++) {
		head = ethptr->txHead;
		descptr = (struct e100_tx_desc *)ethptr->txRing + head;
		
		//kprintf("In e100_intr, descptr = %d\r\n", (int32)descptr);
		//kprintf("descptr->status = %x\r\n", descptr->status);
		if (!(descptr->status & cb_complete)) {
			//kprintf("Before, break, descptr->status = %x\r\n", descptr->status);			
			break;
		}
		//kprintf("descptr->status = %4x\r\n",descptr->status);
		/* Clear the write-back descriptor and buffer */
		
		//descptr->status |= cb_complete;
		descptr->command = 0;
		//descptr->link = 0;
		descptr->u.tcb.tbd_array = 0;
		descptr->u.tcb.tcb_byte_count = 0;
		descptr->u.tcb.threshold = 0;
		descptr->u.tcb.tbd_num = 0;
		pktptr = descptr->u.tcb.data;
		memset(pktptr, '\0', ETH_BUF_SIZE);
		
		ethptr->txHead 
		= (ethptr->txHead + 1) % ethptr->txRingSize;	
		if (ethptr->txHead == ethptr->txTail ) {
			break;
		}
	}
	
	//signaln(ethptr->osem, numdesc);
	
	return;
}

/*------------------------------------------------------------------------
 * e100_intr - decode and handle interrupt from an E100 device
 *------------------------------------------------------------------------
 */

interrupt e100_intr(
	struct 	ether *ethptr
	)
{
	uint8	stat_ack;
	
	/* kprintf("Enter interrupt handler!\r\n");
	kprintf("SCB Status = %2x\r\n", inb(ethptr->iobase + E100_STATUS)); */
	/* Disable device interrupt */
	e100_disable_irq(ethptr);
	
	/* Obtain stat_ack bits from device */
	stat_ack 	= inb(ethptr->iobase + E100_STAT_ACK);
	outb(ethptr->iobase + E100_STAT_ACK, stat_ack);

	/* kprintf("stat_ack = %x\r\n", stat_ack);
	kprintf("stat_ack_rx = %x\r\n", stat_ack_rx);
	kprintf("stat_ack_tx = %x\r\n", stat_ack_tx); */
	
	/* Not our interrupt */
	if (stat_ack == stat_ack_not_ours) {
		e100_enable_irq(ethptr);
		return;
	}
	
	sched_cntl(DEFER_START);
	
	if (stat_ack & stat_ack_rx) {
		ethptr->rxIrq++;
		e100_rxPackets(ethptr);
	}
	
	if (stat_ack & stat_ack_tx) {
		ethptr->txIrq++;
		e100_txPackets(ethptr);
	}
	
	/* struct e100_tx_desc *descptr1;
	struct e100_rx_desc *descptr2;

	descptr1 = (struct e100_tx_desc *)ethptr->txRing;
	kprintf("Tx block: descptr->status = %x\r\n", descptr1->status);
	kprintf("Tx block: descptr->command = %x\r\n", descptr1->command);
	//kprintf("Tx block: descptr->size = %x\r\n", descptr->size);
	kprintf("Tx block: descptr->link = %x\r\n", descptr1->link);
	
	kprintf("=======================================\r\n");
	descptr2 = (struct e100_rx_desc *)ethptr->rxRing;
	kprintf("Rx block: descptr->status = %x\r\n", descptr2->status);
	kprintf("Rx block: descptr->command = %x\r\n", descptr2->command);
	kprintf("Rx block: descptr->size = %x\r\n", descptr2->size);
	kprintf("Rx block: descptr->link = %x\r\n", descptr2->link);	 */	
	
	/* Enable device interrupt */
	
	e100_enable_irq(ethptr);
	
	sched_cntl(DEFER_STOP);

	return;
}
コード例 #6
0
ファイル: ttyInterrupt.c プロジェクト: disrvptor/xinu
/*------------------------------------------------------------------------
 *  ttyInterrupt - handle an interrupt for a tty (serial) device
 *------------------------------------------------------------------------
 */
void ttyInterrupt(void) {
	struct	dentry	*devptr;	/* address of device control blk*/
	struct	ttycblk	*typtr;		/* pointer to ttytab entry	*/	
	struct	uart_csreg *csrptr;	/* address of UART's CSR	*/
	byte	iir = 0;		/* interrupt identification	*/
	byte	lsr = 0;		/* line status			*/


	/* Get CSR address of the device (assume console for now) */

	devptr = (struct dentry *) &devtab[CONSOLE];
	csrptr = (struct uart_csreg *) devptr->dvcsr;

	/* Obtain a pointer to the tty control block */

	typtr = &ttytab[ devptr->dvminor ];

	/* Decode hardware interrupt request from UART device */

        /* Check interrupt identification register */
        iir = inb( (int)&csrptr->iir );
        if (iir & UART_IIR_IRQ) {
		return;
        }

	/* Decode the interrupt cause based upon the value extracted	*/
	/* from the UART interrupt identification register.  Clear	*/
	/* the interrupt source and perform the appropriate handling	*/
	/* to coordinate with the upper half of the driver		*/

        /* Decode the interrupt cause */

        iir &= UART_IIR_IDMASK;		/* mask off the interrupt ID */
        switch (iir) {

	    /* Receiver line status interrupt (error) */

	    case UART_IIR_RLSI:
		lsr = inb( (int)&csrptr->lsr );
		return;

	    /* Receiver data available or timed out */

	    case UART_IIR_RDA:
	    case UART_IIR_RTO:

		sched_cntl(DEFER_START);

		/* While chars avail. in UART buffer, call ttyInter_in	*/

		while ( (inb( (int)&csrptr->lsr) & UART_LSR_DR) != 0) {
			ttyInter_in(typtr, csrptr);
                }

		sched_cntl(DEFER_STOP);

		return;

            /* Transmitter output FIFO is empty (i.e., ready for more)	*/

	    case UART_IIR_THRE:
		/* Read from LSR to clear interrupt */
		lsr = inb( (int)&csrptr->lsr );
		ttyInter_out(typtr, csrptr);
		return;

	    /* Modem status change (simply ignore) */

	    case UART_IIR_MSC:
		return;
	    }
}