This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]