[Prism54-devel] suggestion to shorten interrupt code path

Rainer Weikusat rainer.weikusat at sncag.com
Thu Apr 21 21:00:19 UTC 2005


I happen to have the mispleasure to get this driver
to actually work (for Indigo, AFAIK, and on ARM)[*], and I have
replaced the interrupt handler code today. Before I did this,
I used to have packet loss rates > 80% when flood pinging, and now
they have dropped to zero (I still do not really believe this :-).
The code I am using at present (2.4 only) looks basically like this:

void
islpci_interrupt(int irq, void *arg, struct pt_regs *regs)
{
	islpci_private *priv;
	u32 irqs, saved_irqs;

	priv = arg;
	spin_lock(&priv->slock);
	
	irqs = check_and_acknowledge_irqs(priv->device_base);
	if (!irqs) goto out;
		
	p_trace(("indigo: irqs 0x%08x, state %u\n", irqs, priv->state));
	saved_irqs = irqs;
	
	irqs &= ~INDIGO_FROM_IRQ_UPDATE;
	if (irqs != saved_irqs) {
		handle_update(priv);
		
		saved_irqs = irqs; /* could use MOVS on arm if gcc could */  
		if (!saved_irqs) goto out;
	}

	irqs &= ~INDIGO_FROM_IRQ_DID_WAKEUP;
	if (irqs != saved_irqs) {
		handle_wakeup(priv);
		
		saved_irqs = irqs;
		if (!saved_irqs) goto out;
	}

	irqs &= ~INDIGO_FROM_IRQ_INIT;
	if (irqs != saved_irqs) {
		handle_init(priv);
		
		saved_irqs = irqs;
		if (!saved_irqs) goto out;
	}

	irqs &= ~INDIGO_FROM_IRQ_WANT_SLEEP;
	if (irqs != saved_irqs) handle_sleep(priv);

 out:
	spin_unlock(&priv->slock);
}

- just in case someone is interested -

[*] for instance, I happen to know one cause of 'mgmt timeouts'
    (device bug, sometimes asserts update but doesn't send data
     => little endian frame length converted to little endian
     a 2nd time => kmalloc failure in mgt_receive)
     
   


More information about the Prism54-devel mailing list