[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