This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Ethernet interrupt structure / flow
- From: Chuck McManis <ecos at mcmanis dot com>
- To: ECOS Discussion Group <ecos-discuss at sources dot redhat dot com>
- Date: Tue, 14 Feb 2006 23:14:55 -0800
- Subject: [ECOS] Ethernet interrupt structure / flow
Why does it have to be so complicated?
I understand the part about ISR's and DSR's. (And I agree it should be
serviced in FIFO order and I agree it should be a HAL configuration option)
But in this ethernet driver we have:
> static cyg_uint32
> vt8235_isr(cyg_vector_t vector, cyg_addrword_t data)
> {
> struct vt8235_priv_data *cpd = (struct vt8235_priv_data *)data;
>
> cyg_drv_interrupt_mask(cpd->interrupt);
> cyg_drv_interrupt_acknowledge(cpd->interrupt);
> return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
> }
Ok, I get this, disable the interrupt quickly, mark it as "handled" and
schedule the DSR to run. Pretty straight forward. But in the DSR the Rhine
driver had:
> /*
> * this services interrupts from the device after they have been
> * scheduled above. in the case of Polled mode we will call this
> * function manually to get our data
> */
> static void
> vt8235_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
> {
> struct vt8235_priv_data* cpd = (struct vt8235_priv_data *)data;
> struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry
*)(cpd->ndp);
> struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
>
> // but here, it must be a *sc:
> eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
> }
This get's called as the DSR, which turns around and calls, eth_drv_dsr
which schedules a thread to get deliveries? Why the extra level of
indirection? Couldn't the deliver function run in the context of generic
"collector of deliveries" thread that is annotated by the call to the isr
routine?
> // The deliver function (ex-DSR) handles the ethernet [logical] processing
> static void
> vt8235_deliver(struct eth_drv_sc *sc)
> {
> struct vt8235_priv_data *cpd = (struct vt8235_priv_data
*)sc->driver_private
;
>
>
> // Service the interrupt:
> vt8235_poll(sc);
> // Allow interrupts to happen again
> cyg_drv_interrupt_unmask(cpd->interrupt);
> }
And a double indirection again to deliver, to poll, then back to deliver
then back to the delivery thread. Any idea how much latency this is adding?
Final question for this email. I know that redboot only uses the poll
function for networking being an inherently simple monitor model. Is it
possible to allow it to use the interrupt version or is that simply not an
option at this time? I ask because it would seem to make the code cleaner
if it just assumed the interrupt infrastructure for networking was useful.
--Chuck
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss