Пример #1
0
/*
 *  UART Interrupt Handler
 */
static void
uarttxintr(Ureg*, void* arg)
{
	Uart *p = arg;			
	intrclear(UARTTXbit(p->port), 0);
	p->inters++;
	p->winters++;
	uartxmit(p);
}
Пример #2
0
static void
uartrxintr(Ureg*, void* arg)
{
	Uart *p = arg;			
	intrclear(UARTRXbit(p->port), 0);
	p->inters++;
	p->rinters++;
	uartrecv(p);
}
Пример #3
0
Файл: clock.c Проект: 8l/inferno
static void
clockintr(Ureg*, void*)
{
	Clock0link *lp;

	m->ticks++;

	checkalarms();

	if(canlock(&clock0lock)){
		for(lp = clock0link; lp; lp = lp->link)
			if (lp->clock)
				lp->clock();
		unlock(&clock0lock);
	}
	intrclear(TIMERbit(0), 0);
}
Пример #4
0
static void
interrupt(Ureg*, void *arg)
{
	ulong irq, irqe, handled;
	Ether *ether = arg;
	Ctlr *ctlr = ether->ctlr;
	Gbereg *reg = ctlr->reg;

	handled = 0;
	irq = reg->irq;
	irqe = reg->irqe;
	reg->irqe = 0;				/* extinguish intr causes */
	reg->irq = 0;				/* extinguish intr causes */
	ethercheck(ether);

	if(irq & (Irx | Irxbufferq(Qno))) {
		/*
		 * letting a kproc process the input takes far less real time
		 * than doing it all at interrupt level.
		 */
		ctlr->haveinput = 1;
		wakeup(&ctlr->rrendez);
		irq &= ~(Irx | Irxbufferq(Qno));
		handled++;
	} else
		rxkick(ctlr);

	if(irq & Itxendq(Qno)) {		/* transmit ring empty? */
		reg->irqmask  &= ~Itxendq(Qno);	/* prevent more interrupts */
		reg->irqemask &= ~(IEtxerrq(Qno) | IEtxunderrun);
		transmit(ether);
		irq &= ~Itxendq(Qno);
		handled++;
	}

	if(irqe & IEsum) {
		/*
		 * IElinkchg appears to only be set when unplugging.
		 * autonegotiation is likely not done yet, so linkup not valid,
		 * thus we note the link change here, and check for
		 * that and autonegotiation done below.
		 */
		if(irqe & IEphystschg) {
			ether->link = (reg->ps0 & PS0linkup) != 0;
			ether->linkchg = 1;
		}
		if(irqe & IEtxerrq(Qno))
			ether->oerrs++;
		if(irqe & IErxoverrun)
			ether->overflows++;
		if(irqe & IEtxunderrun)
			ctlr->txunderrun++;
		if(irqe & (IEphystschg | IEtxerrq(Qno) | IErxoverrun |
		    IEtxunderrun))
			handled++;
	}
	if (irq & Isum) {
		if (irq & Irxerr) {  /* nil desc. ptr. or desc. owned by cpu */
			ether->buffs++;		/* approx. error */

			/* if the input ring is full, drain it */
			ctlr->haveinput = 1;
			wakeup(&ctlr->rrendez);
		}
		if(irq & (Irxerr | Irxerrq(Qno)))
			handled++;
		irq  &= ~(Irxerr | Irxerrq(Qno));
	}

	if(ether->linkchg && (reg->ps1 & PS1an_done)) {
		handled++;
		ether->link = (reg->ps0 & PS0linkup) != 0;
		ether->linkchg = 0;
	}
	ctlr->newintrs++;

	if (!handled) {
		irq  &= ~Isum;
		irqe &= ~IEtxbufferq(Qno);
		if (irq == 0 && irqe == 0) {
			/* seems to be triggered by continuous output */
			// iprint("ether1116: spurious interrupt\n");
		} else
			iprint("ether1116: interrupt cause unknown; "
				"irq %#lux irqe %#lux\n", irq, irqe);
	}
	intrclear(Irqlo, ether->irq);
}