public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] Question about interrupt trigger mode.
@ 2007-09-28 10:06 ariga masahiro
  2007-10-01  5:01 ` [ECOS] Not working lan91cxx_sc drv ariga masahiro
  0 siblings, 1 reply; 8+ messages in thread
From: ariga masahiro @ 2007-09-28 10:06 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss

Hi,

My target uses SMSC LAN91C111 chip,CPU is SH7709S.
As ethernet interrupt,uses IRQ3 line.
I build "net" template,eCos source is updated by CVS checkout.

Please help me next 2 questions.
(1)
When IRQ3 aserted,enter into ISR routine,so far so good.
But although IRQ3 line continually hold assert-state(LOW),
and never chang to OFF(HIGH)state,ISR is repeatedly entered.

My question is,if interrupt trigger mode is setted edge trigger mode,
ISR routine is only entered once,isn't it ?

I assume trigger mode is setted by next routine.
packages\kernel\current\src\intr\intr.cxx     HAL_INTERRUPT_CONFIGURE( 
vector, level, up );
or Cyg_Interrupt::configure_interrupt routine.

I checked source but never found using HAL_INTERRUPT_CONFIGURE or 
Cyg_Interrupt::configure_interrupt.
Is it only setted by default ?

I like to quarantee it is working egde trigger mode.
Could I know by cheching global area ?
How should I do to be confirmed that ?

(2)
After  IRQ3 was aserted,does eCos's SMSC LAN91C111 driver delete factors
causing IRQ3 toward LAN chip ?
If it does,and it is possible,please let me know where it is done ?
Or is it user's responsibility to do in ISR ?

Please enlighten me.

Masahiro Ariga


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ECOS] Not working lan91cxx_sc drv
  2007-09-28 10:06 [ECOS] Question about interrupt trigger mode ariga masahiro
@ 2007-10-01  5:01 ` ariga masahiro
  2007-10-02  1:18   ` ariga masahiro
  0 siblings, 1 reply; 8+ messages in thread
From: ariga masahiro @ 2007-10-01  5:01 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss

Hi,

I am the same person who posted "Question about interrupt trigger 
mode",dated 9/28/2007
but since then I am encountered the most serious problem so I change title 
and post this
most-urgent,most-ernest and most-desperate mail.

As I said,
My target uses SMSC LAN91C111 chip,CPU is SH7709S.
As ethernet interrupt,uses IRQ3 line.
I build "net" template,eCos source is updated by CVS checkout.

As I inserted LAN91C111's mask routine in the ISR,
I succeeded to entered into DSR.
(This interrupt was caused not by eCos-proper code, but by my tampered
routine.I will later explain.)
But although RCV-INT is assserted,delivering-packet routine never called,
so I entered repetedly ISR and DSR.
Then I discovered LAN91C111 driver's receive routine was never called.

Please forgive me long mail,but I try to
inform you as correctly as possible.
First I relate current problem,and later describe what I have tampered with.

I register SMSC interrupt ruoitne
in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
like this,
#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
    // Initialize environment, setup interrupt handler
    cyg_drv_interrupt_create(cpd->interrupt,
                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
                             (cyg_addrword_t)sc, //  Data item passed to 
interrupt handler
                             (cyg_ISR_t *)lan91cxx_isr,
                             (cyg_DSR_t *)eth_drv_dsr, // The logical driver 
DSR
                             &lan91cxx_interrupt_handle,
                             &lan91cxx_interrupt);
    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
    cyg_drv_interrupt_acknowledge(cpd->interrupt);
    cyg_drv_interrupt_unmask(cpd->interrupt);

And register LAN91C111 driver in my target's 
\packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
I think this is important so I put on all content.
#include <pkgconf/system.h>
#include <pkgconf/devs_eth_sh_inserter.h>
#include <cyg/hal/hal_intr.h>

// MAC address is stored as a Redboot config option
#ifdef CYGPKG_REDBOOT
#include <pkgconf/redboot.h>
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <redboot.h>
#include <flash_config.h>

#define LAN91CXX_IS_LAN91C111

RedBoot_config_option("Network hardware address [MAC]",
                      inserter_esa,
                      ALWAYS_ENABLED, true,
                      CONFIG_ESA, 0
    );
#endif
#endif

// ESA address fetch function
static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
{
    // Fetch hardware address from RedBoot config
#if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
#if defined(CYGPKG_REDBOOT) && \
    defined(CYGSEM_REDBOOT_FLASH_CONFIG)
    flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
#else
#error "No RedBoot flash configuration to store ESA"
#endif
#else
    unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
    memcpy(cpd->enaddr, static_esa, 6);
#endif
}

static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
    config_enaddr : inserter_get_ESA,
#ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
    enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
    hardwired_esa : true,
#else
    hardwired_esa : false,
#endif

#if 0
   base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
   attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
   interrupt : SA1110_IRQ_GPIO_ETH
#else
   base : (unsigned short *) 0xa8000000,
   interrupt : 9,
#endif
};

ETH_DRV_SC(lan91cxx_sc,
           &lan91cxx_eth0_priv_data,          // Driver specific data
           CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
           lan91cxx_start,
           lan91cxx_stop,
           lan91cxx_control,
           lan91cxx_can_send,
           lan91cxx_send,
           lan91cxx_recv,
           lan91cxx_deliver,
           lan91cxx_poll,
           lan91cxx_int_vector
);

NETDEVTAB_ENTRY(lan91cxx_netdev,
                "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
                smsc_lan91cxx_init,
                &lan91cxx_sc);

//EOF devs_eth_inserter.inl

I found ETH_DRV_SC definition as below.
\packages\io\eth\current\include\eth_drv.h
#define 
ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) 
\
static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags); 
\
static void stop(struct eth_drv_sc *sc); \
static int  control(struct eth_drv_sc *sc, unsigned long key, void *data, 
int data_length); \
static int  can_send(struct eth_drv_sc *sc); \
static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
sg_len, int total, unsigned long key); \
static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
sg_len); \
static void deliver(struct eth_drv_sc *sc); \
static void poll(struct eth_drv_sc *sc); \
static int  int_vector(struct eth_drv_sc *sc); \
static struct eth_hwr_funs sc##_funs = {        \
    start,                                      \
    stop,                                       \
    control,                                    \
    can_send,                                   \
    send,                                       \
    recv,                                       \
    deliver,                                    \
    poll,                                       \
    int_vector,                                 \
    &eth_drv_funs,                              \
    (struct eth_drv_funs *)0 };                 \
struct eth_drv_sc sc = {&sc##_funs, priv, name};

I assume this is developed like below,
#define 
ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) 
\
static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned char 
*enaddr, int flags); \
static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
static int  lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned long 
key, void *data, int data_length); \
static int  lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct eth_drv_sg 
*sg_list, int sg_len, int total, unsigned long key); \
static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct eth_drv_sg 
*sg_list, int sg_len); \
static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
static int  lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
static struct eth_hwr_funs lan91cxx_sc_funs = {        \
    lan91cxx_start,                                      \
    lan91cxx_stop,                                       \
    lan91cxx_control,                                    \
    lan91cxx_can_send,                                   \
    lan91cxx_send,                                       \
    lan91cxx_recv,                                       \
    lan91cxx_deliver,                                    \
    lan91cxx_poll,                                       \
    lan91cxx_int_vector,                                 \
    &eth_drv_funs,                              \
    (struct eth_drv_funs *)0 };                 \
struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, 
&lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};

I assume lan91cxx_recv must be called to operate on packets,
but it was never called.

I traced DSR routine
DSR is this
\packages\io\eth\current\src\net\eth_drv.c
void
eth_drv_dsr(cyg_vector_t vector,
            cyg_ucount32 count,
            cyg_addrword_t data)
{
    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;

#ifdef CYGDBG_USE_ASSERTS
    // then check that this really is a "sc"
    {
        cyg_netdevtab_entry_t *t;
        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
            if ( ((struct eth_drv_sc *)t->device_instance) == sc )
                break; // found it
        CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to find sc 
in NETDEVTAB" );
    }
#endif // Checking code

    sc->state |= ETH_DRV_NEEDS_DELIVERY;

    ecos_synch_eth_drv_dsr(); // [request] run delivery function for this 
dev
}

And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
void ecos_synch_eth_drv_dsr(void)
{
    cyg_flag_setbits( &alarm_flag, 2 );
}

And in \packages\kernel\current\src\common\kapi.cxx
void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
{
    ((Cyg_Flag *)flag)->setbits( value );
}

And in \packages\kernel\current\src\sync\flag.cxx
void
Cyg_Flag::setbits( Cyg_FlagValue arg )
{
    CYG_REPORT_FUNCTION();
    CYG_ASSERTCLASS( this, "Bad this pointer");

    // Prevent preemption
    Cyg_Scheduler::lock();

    // OR in the argument to get a new flag value.
    value |= arg;

    // anyone waiting?
    if ( !(queue.empty()) ) {
        FlagWaitInfo   *p;
        Cyg_Thread     *thread;
        Cyg_ThreadQueue holding;

        do {
            thread = queue.dequeue();
            p = (FlagWaitInfo *)(thread->get_wait_info());

            CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
                        "Both masks set" );
            CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );

            if ( ((p->allmask != 0) && (p->allmask & value) == p->allmask) 
||
                 ((p->anymask & value) != 0 ) ) {
                // success!  awaken the thread
                thread->set_wake_reason( Cyg_Thread::DONE );
                thread->wake();
                // return the successful value to it
                p->value_out = value;
                // do we clear the value; is this the end?
                if ( p->do_clear ) {
                    // we can break here but need to preserve ordering
                    value = 0;
                    // so let it cycle the whole queue regardless
                }
            }
            else {
                // preserve the entry on the holding queue
                holding.enqueue( thread );
            }
        } while ( !(queue.empty()) );

        // Now re-queue the unaffected threads back into the flag queue
        while ( !(holding.empty()) ) {
            queue.enqueue( holding.dequeue() );
        }
    }
    // Unlock scheduler and allow other threads to run
    Cyg_Scheduler::unlock();
    CYG_REPORT_RETURN();
}

Truely,I cannot fathom this coding and
I would appreciate if you kindly teach me how lan91cxx_recv is to be called.

Now I describe what I have tampered with in detail,please forgive me lengthy 
details.
The beginning of the matter is when I ran eCos as it is,I couldn't make 
LAN91C111 into LINK State,
LINK LED didn't light.So I inserted my own routine in order to operate 
LAN91C111 into LINK State in top of
\packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function like 
below.
eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
{
    // this is my tampered coding
    cyg_netdevtab_entry_t *t;

    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
#ifdef CYGPKG_NET_FREEBSD_STACK
    int unit;
    char *np, *xp;
#endif

    // this is my tampered coding
    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
        log(LOG_INIT, "Init device '%s'\n", t->name);
        if (smsc_91c111_init(t)) {             // this is my concocted 
routine
            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
        } else {
            // What to do if device init fails?
            t->status = 0;  // Device not [currently] available
        }
    }

and in order making LAN91C111 into LINK State it was necessary to use 
interrupt so I enabled LAN91C111 interrupt in my concocted routine.
Above-mentioned interrupt was caused by my tampered code.At LINK-established 
time interrupt happened.

On second thought, I realized my tampering was wrong.
So I quitted my tampering routine, I returned to eCos original source and 
checked why couldn't make LINK LED lighed.
I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC routines).

Below is RedBoot output messages log.
I breaked lan91cxx_start() but never entered it.
I made DEBUG_FUNCTION() available.
-- RedBoot output messages log
My Flash ID is 4:22f9:0:19
eth_drv_init:enaddr=0x8c0005c4
Ethernet eth0: MAC address 00:40:31:08:01:00
IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
Default server: 172.16.1.1

RedBoot(tm) bootstrap and debug environment [ROM]
Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007

Platform: inserter (SH 7709S)
Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited

RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
== Executing boot script in 3.000 seconds - enter ^C to abort
RedBoot> fis load -b 0x8c010000 nc_slave
RedBoot> channel 1
RedBoot> go 0x8c010000
Network stack using 69632 bytes for misc space
                    69632 bytes for mbufs
                    139264 bytes for mbuf clusters
[cyg_net_init] Init: mbinit(0x00000000)
[cyg_net_init] Init: cyg_net_init_devs(0x00000000)
Init device 'lan91cxx_eth0'
smsc_lan91cxx_init
LAN91CXX - supposed BankReg @ a800000e = 3302
LAN91CXX - type: 9, rev: 1
LAN91CXX - status: 0069
LAN91CXX - static ESA: 00:40:31:08:01:00
[cyg_net_init] Init: loopattach(0x00000000)
[cyg_net_init] Init: ifinit(0x00000000)
[cyg_net_init] Init: domaininit(0x00000000)
[cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
New domain internet at 0x00000000
[cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
New domain route at 0x00000000
[cyg_net_init] Init: call_route_init(0x00000000)
[cyg_net_init] Done
Start Network Characterization - SLAVE
No load = 58470
Set background load = 20%
Set background load = 0%
High Load[20] = 37131 => 37%
Set background load = 20%
Set background load = 0%
Load[10] = 47736 => 19%
Set background load = 20%
Set background load = 0%
Final load[10] = 47853 => 19%
Start test for eth0
-- end of RedBoot output messages log

All matters considered,I deduce that ETH_DRV_SC-table-reference-functions 
are not working.
I cannot understand where and how they are called.
Please teach me how to correctly call these functions.

Particularly I am curious to know eCos's system contrivance for calling drv 
routines
and if you know anything(e.g. web site,etc.) to guide me, please enlighten 
me.
I am "a drowning man catching at a straw".

I admit my knowledge is below than ecos level,
but my company's expecting in applying eCos into products.
And I trust eCos, so please do not let me down
and I eanestly beseech your kind advice.

Masahiro Ariga


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ECOS] Not working lan91cxx_sc drv
  2007-10-01  5:01 ` [ECOS] Not working lan91cxx_sc drv ariga masahiro
@ 2007-10-02  1:18   ` ariga masahiro
  2007-10-02  4:46     ` ariga masahiro
  0 siblings, 1 reply; 8+ messages in thread
From: ariga masahiro @ 2007-10-02  1:18 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss

Hi,

I am in a complete predicament.
You are the only hope.
Please give me any hints whatsoever.

I realized I should check Configuration conflicts.

When building "net" template,appeares 2 Resolve Conflicts windows.
I donnot know how much level auto-amendment system guarantees,
but I relied auto-amendment completely.

All-items tracking down is impossible because I consumed time enough.
If any one hits you as most suspecting,please let me know.

[First Resolve Conflicts window]
Resolve conflicts
CYGPKG_DEVS_FLASH_SH_inserter       Requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
CYGPKG_HAL_SH_SH77X9_inserter        Requires CYGHWR_HAL_SH_IRQ_USE_IRQLVL
CYGPRI_HAL_SH_SH77X9_VARIANT_7709S  Requires CYGPRI_HAL_SH_SH77X9_SUPERIO

Proposed Solutions:
CYGPRI_HAL_SH_SH77X9_SUPERIO           Enabled
CYGHWR_HAL_SH_IRQ_USE_IRQLVL        Enabled
CYGHWR_DEVS_FLASH_AMD_AM29LV160     Enabled

[Second Resolve Conflicts window]
CYGPKG_POSIX_CLOCKS                   Requires 
CYGBLD_ISO_STRUCTTIMEVAL_HEADER == "<cyg/posix/sys/time.h>"
CYGPKG_FILEIO_FNMATCH               Requires CYGBLD_ISO_FNMATCH_HEADER == 
"<cyg/fileio/fnmatch.h>"

Proposed Solutions:
CYGBLD_ISO_FNMATCH_HEADER                 Enabled,<cyg/fileio/fnmatch.h>
CYGBLD_ISO_STRUCTTIMEVAL_HEADER     Enabled,<cyg/posix/sys/time.h>

Please help me.

Mashiro Ariga

-- my previous mail.
> As I said,
> My target uses SMSC LAN91C111 chip,CPU is SH7709S.
> As ethernet interrupt,uses IRQ3 line.
> I build "net" template,eCos source is updated by CVS checkout.
>
> As I inserted LAN91C111's mask routine in the ISR,
> I succeeded to entered into DSR.
> (This interrupt was caused not by eCos-proper code, but by my tampered
> routine.I will later explain.)
> But although RCV-INT is assserted,delivering-packet routine never called,
> so I entered repetedly ISR and DSR.
> Then I discovered LAN91C111 driver's receive routine was never called.
>
> Please forgive me long mail,but I try to
> inform you as correctly as possible.
> First I relate current problem,and later describe what I have tampered 
> with.
>
> I register SMSC interrupt ruoitne
> in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
> smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
> like this,
> #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>    // Initialize environment, setup interrupt handler
>    cyg_drv_interrupt_create(cpd->interrupt,
>                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
>                             (cyg_addrword_t)sc, //  Data item passed to 
> interrupt handler
>                             (cyg_ISR_t *)lan91cxx_isr,
>                             (cyg_DSR_t *)eth_drv_dsr, // The logical 
> driver DSR
>                             &lan91cxx_interrupt_handle,
>                             &lan91cxx_interrupt);
>    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
> #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>    cyg_drv_interrupt_acknowledge(cpd->interrupt);
>    cyg_drv_interrupt_unmask(cpd->interrupt);
>
> And register LAN91C111 driver in my target's 
> \packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
> I think this is important so I put on all content.
> #include <pkgconf/system.h>
> #include <pkgconf/devs_eth_sh_inserter.h>
> #include <cyg/hal/hal_intr.h>
>
> // MAC address is stored as a Redboot config option
> #ifdef CYGPKG_REDBOOT
> #include <pkgconf/redboot.h>
> #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
> #include <redboot.h>
> #include <flash_config.h>
>
> #define LAN91CXX_IS_LAN91C111
>
> RedBoot_config_option("Network hardware address [MAC]",
>                      inserter_esa,
>                      ALWAYS_ENABLED, true,
>                      CONFIG_ESA, 0
>    );
> #endif
> #endif
>
> // ESA address fetch function
> static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
> {
>    // Fetch hardware address from RedBoot config
> #if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
> #if defined(CYGPKG_REDBOOT) && \
>    defined(CYGSEM_REDBOOT_FLASH_CONFIG)
>    flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
> #else
> #error "No RedBoot flash configuration to store ESA"
> #endif
> #else
>    unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
>    memcpy(cpd->enaddr, static_esa, 6);
> #endif
> }
>
> static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
>    config_enaddr : inserter_get_ESA,
> #ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>    enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
>    hardwired_esa : true,
> #else
>    hardwired_esa : false,
> #endif
>
> #if 0
>   base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
>   attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
>   interrupt : SA1110_IRQ_GPIO_ETH
> #else
>   base : (unsigned short *) 0xa8000000,
>   interrupt : 9,
> #endif
> };
>
> ETH_DRV_SC(lan91cxx_sc,
>           &lan91cxx_eth0_priv_data,          // Driver specific data
>           CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
>           lan91cxx_start,
>           lan91cxx_stop,
>           lan91cxx_control,
>           lan91cxx_can_send,
>           lan91cxx_send,
>           lan91cxx_recv,
>           lan91cxx_deliver,
>           lan91cxx_poll,
>           lan91cxx_int_vector
> );
>
> NETDEVTAB_ENTRY(lan91cxx_netdev,
>                "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
>                smsc_lan91cxx_init,
>                &lan91cxx_sc);
>
> //EOF devs_eth_inserter.inl
>
> I found ETH_DRV_SC definition as below.
> \packages\io\eth\current\include\eth_drv.h
> #define 
> ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) 
> \
> static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int 
> flags); \
> static void stop(struct eth_drv_sc *sc); \
> static int  control(struct eth_drv_sc *sc, unsigned long key, void *data, 
> int data_length); \
> static int  can_send(struct eth_drv_sc *sc); \
> static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
> sg_len, int total, unsigned long key); \
> static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
> sg_len); \
> static void deliver(struct eth_drv_sc *sc); \
> static void poll(struct eth_drv_sc *sc); \
> static int  int_vector(struct eth_drv_sc *sc); \
> static struct eth_hwr_funs sc##_funs = {        \
>    start,                                      \
>    stop,                                       \
>    control,                                    \
>    can_send,                                   \
>    send,                                       \
>    recv,                                       \
>    deliver,                                    \
>    poll,                                       \
>    int_vector,                                 \
>    &eth_drv_funs,                              \
>    (struct eth_drv_funs *)0 };                 \
> struct eth_drv_sc sc = {&sc##_funs, priv, name};
>
> I assume this is developed like below,
> #define 
> ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) 
> \
> static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned char 
> *enaddr, int flags); \
> static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
> static int  lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned long 
> key, void *data, int data_length); \
> static int  lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
> static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct 
> eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
> static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct 
> eth_drv_sg *sg_list, int sg_len); \
> static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
> static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
> static int  lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
> static struct eth_hwr_funs lan91cxx_sc_funs = {        \
>    lan91cxx_start,                                      \
>    lan91cxx_stop,                                       \
>    lan91cxx_control,                                    \
>    lan91cxx_can_send,                                   \
>    lan91cxx_send,                                       \
>    lan91cxx_recv,                                       \
>    lan91cxx_deliver,                                    \
>    lan91cxx_poll,                                       \
>    lan91cxx_int_vector,                                 \
>    &eth_drv_funs,                              \
>    (struct eth_drv_funs *)0 };                 \
> struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, 
> &lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};
>
> I assume lan91cxx_recv must be called to operate on packets,
> but it was never called.
>
> I traced DSR routine
> DSR is this
> \packages\io\eth\current\src\net\eth_drv.c
> void
> eth_drv_dsr(cyg_vector_t vector,
>            cyg_ucount32 count,
>            cyg_addrword_t data)
> {
>    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
>
> #ifdef CYGDBG_USE_ASSERTS
>    // then check that this really is a "sc"
>    {
>        cyg_netdevtab_entry_t *t;
>        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
>            if ( ((struct eth_drv_sc *)t->device_instance) == sc )
>                break; // found it
>        CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to find 
> sc in NETDEVTAB" );
>    }
> #endif // Checking code
>
>    sc->state |= ETH_DRV_NEEDS_DELIVERY;
>
>    ecos_synch_eth_drv_dsr(); // [request] run delivery function for this 
> dev
> }
>
> And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
> void ecos_synch_eth_drv_dsr(void)
> {
>    cyg_flag_setbits( &alarm_flag, 2 );
> }
>
> And in \packages\kernel\current\src\common\kapi.cxx
> void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
> {
>    ((Cyg_Flag *)flag)->setbits( value );
> }
>
> And in \packages\kernel\current\src\sync\flag.cxx
> void
> Cyg_Flag::setbits( Cyg_FlagValue arg )
> {
>    CYG_REPORT_FUNCTION();
>    CYG_ASSERTCLASS( this, "Bad this pointer");
>
>    // Prevent preemption
>    Cyg_Scheduler::lock();
>
>    // OR in the argument to get a new flag value.
>    value |= arg;
>
>    // anyone waiting?
>    if ( !(queue.empty()) ) {
>        FlagWaitInfo   *p;
>        Cyg_Thread     *thread;
>        Cyg_ThreadQueue holding;
>
>        do {
>            thread = queue.dequeue();
>            p = (FlagWaitInfo *)(thread->get_wait_info());
>
>            CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
>                        "Both masks set" );
>            CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );
>
>            if ( ((p->allmask != 0) && (p->allmask & value) == p->allmask) 
> ||
>                 ((p->anymask & value) != 0 ) ) {
>                // success!  awaken the thread
>                thread->set_wake_reason( Cyg_Thread::DONE );
>                thread->wake();
>                // return the successful value to it
>                p->value_out = value;
>                // do we clear the value; is this the end?
>                if ( p->do_clear ) {
>                    // we can break here but need to preserve ordering
>                    value = 0;
>                    // so let it cycle the whole queue regardless
>                }
>            }
>            else {
>                // preserve the entry on the holding queue
>                holding.enqueue( thread );
>            }
>        } while ( !(queue.empty()) );
>
>        // Now re-queue the unaffected threads back into the flag queue
>        while ( !(holding.empty()) ) {
>            queue.enqueue( holding.dequeue() );
>        }
>    }
>    // Unlock scheduler and allow other threads to run
>    Cyg_Scheduler::unlock();
>    CYG_REPORT_RETURN();
> }
>
> Truely,I cannot fathom this coding and
> I would appreciate if you kindly teach me how lan91cxx_recv is to be 
> called.
>
> Now I describe what I have tampered with in detail,please forgive me 
> lengthy details.
> The beginning of the matter is when I ran eCos as it is,I couldn't make 
> LAN91C111 into LINK State,
> LINK LED didn't light.So I inserted my own routine in order to operate 
> LAN91C111 into LINK State in top of
> \packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function like 
> below.
> eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
> {
>    // this is my tampered coding
>    cyg_netdevtab_entry_t *t;
>
>    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
> #ifdef CYGPKG_NET_FREEBSD_STACK
>    int unit;
>    char *np, *xp;
> #endif
>
>    // this is my tampered coding
>    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
>        log(LOG_INIT, "Init device '%s'\n", t->name);
>        if (smsc_91c111_init(t)) {             // this is my concocted 
> routine
>            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
>        } else {
>            // What to do if device init fails?
>            t->status = 0;  // Device not [currently] available
>        }
>    }
>
> and in order making LAN91C111 into LINK State it was necessary to use 
> interrupt so I enabled LAN91C111 interrupt in my concocted routine.
> Above-mentioned interrupt was caused by my tampered code.At 
> LINK-established time interrupt happened.
>
> On second thought, I realized my tampering was wrong.
> So I quitted my tampering routine, I returned to eCos original source and 
> checked why couldn't make LINK LED lighed.
> I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC routines).
>
> Below is RedBoot output messages log.
> I breaked lan91cxx_start() but never entered it.
> I made DEBUG_FUNCTION() available.
> -- RedBoot output messages log
> My Flash ID is 4:22f9:0:19
> eth_drv_init:enaddr=0x8c0005c4
> Ethernet eth0: MAC address 00:40:31:08:01:00
> IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
> Default server: 172.16.1.1
>
> RedBoot(tm) bootstrap and debug environment [ROM]
> Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007
>
> Platform: inserter (SH 7709S)
> Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
> Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited
>
> RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
> FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
> == Executing boot script in 3.000 seconds - enter ^C to abort
> RedBoot> fis load -b 0x8c010000 nc_slave
> RedBoot> channel 1
> RedBoot> go 0x8c010000
> Network stack using 69632 bytes for misc space
>                    69632 bytes for mbufs
>                    139264 bytes for mbuf clusters
> [cyg_net_init] Init: mbinit(0x00000000)
> [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
> Init device 'lan91cxx_eth0'
> smsc_lan91cxx_init
> LAN91CXX - supposed BankReg @ a800000e = 3302
> LAN91CXX - type: 9, rev: 1
> LAN91CXX - status: 0069
> LAN91CXX - static ESA: 00:40:31:08:01:00
> [cyg_net_init] Init: loopattach(0x00000000)
> [cyg_net_init] Init: ifinit(0x00000000)
> [cyg_net_init] Init: domaininit(0x00000000)
> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
> New domain internet at 0x00000000
> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
> New domain route at 0x00000000
> [cyg_net_init] Init: call_route_init(0x00000000)
> [cyg_net_init] Done
> Start Network Characterization - SLAVE
> No load = 58470
> Set background load = 20%
> Set background load = 0%
> High Load[20] = 37131 => 37%
> Set background load = 20%
> Set background load = 0%
> Load[10] = 47736 => 19%
> Set background load = 20%
> Set background load = 0%
> Final load[10] = 47853 => 19%
> Start test for eth0
> -- end of RedBoot output messages log
>
> All matters considered,I deduce that ETH_DRV_SC-table-reference-functions 
> are not working.
> I cannot understand where and how they are called.
> Please teach me how to correctly call these functions.
>


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ECOS] Not working lan91cxx_sc drv
  2007-10-02  1:18   ` ariga masahiro
@ 2007-10-02  4:46     ` ariga masahiro
  2007-10-02  5:27       ` ariga masahiro
  0 siblings, 1 reply; 8+ messages in thread
From: ariga masahiro @ 2007-10-02  4:46 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss

Hi,

In order to work ETH_DRV_SC-table-reference-functions,
should I add anything in CDL ?

If there is,
I would appreciate if you show me sample CDL.

Please help me.

Masahiro Ariga

-- my previous mail
> I realized I should check Configuration conflicts.
>
> When building "net" template,appeares 2 Resolve Conflicts windows.
> I donnot know how much level auto-amendment system guarantees,
> but I relied auto-amendment completely.
>
> All-items tracking down is impossible because I consumed time enough.
> If any one hits you as most suspecting,please let me know.
>
> [First Resolve Conflicts window]
> Resolve conflicts
> CYGPKG_DEVS_FLASH_SH_inserter       Requires 
> CYGHWR_DEVS_FLASH_AMD_AM29LV160
> CYGPKG_HAL_SH_SH77X9_inserter        Requires CYGHWR_HAL_SH_IRQ_USE_IRQLVL
> CYGPRI_HAL_SH_SH77X9_VARIANT_7709S  Requires CYGPRI_HAL_SH_SH77X9_SUPERIO
>
> Proposed Solutions:
> CYGPRI_HAL_SH_SH77X9_SUPERIO           Enabled
> CYGHWR_HAL_SH_IRQ_USE_IRQLVL        Enabled
> CYGHWR_DEVS_FLASH_AMD_AM29LV160     Enabled
>
> [Second Resolve Conflicts window]
> CYGPKG_POSIX_CLOCKS                   Requires 
> CYGBLD_ISO_STRUCTTIMEVAL_HEADER == "<cyg/posix/sys/time.h>"
> CYGPKG_FILEIO_FNMATCH               Requires CYGBLD_ISO_FNMATCH_HEADER == 
> "<cyg/fileio/fnmatch.h>"
>
> Proposed Solutions:
> CYGBLD_ISO_FNMATCH_HEADER                 Enabled,<cyg/fileio/fnmatch.h>
> CYGBLD_ISO_STRUCTTIMEVAL_HEADER     Enabled,<cyg/posix/sys/time.h>
>
> Please help me.
>
> Mashiro Ariga
>
> -- my previous mail.
>> As I said,
>> My target uses SMSC LAN91C111 chip,CPU is SH7709S.
>> As ethernet interrupt,uses IRQ3 line.
>> I build "net" template,eCos source is updated by CVS checkout.
>>
>> As I inserted LAN91C111's mask routine in the ISR,
>> I succeeded to entered into DSR.
>> (This interrupt was caused not by eCos-proper code, but by my tampered
>> routine.I will later explain.)
>> But although RCV-INT is assserted,delivering-packet routine never called,
>> so I entered repetedly ISR and DSR.
>> Then I discovered LAN91C111 driver's receive routine was never called.
>>
>> Please forgive me long mail,but I try to
>> inform you as correctly as possible.
>> First I relate current problem,and later describe what I have tampered 
>> with.
>>
>> I register SMSC interrupt ruoitne
>> in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
>> smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
>> like this,
>> #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>    // Initialize environment, setup interrupt handler
>>    cyg_drv_interrupt_create(cpd->interrupt,
>>                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
>>                             (cyg_addrword_t)sc, //  Data item passed to 
>> interrupt handler
>>                             (cyg_ISR_t *)lan91cxx_isr,
>>                             (cyg_DSR_t *)eth_drv_dsr, // The logical 
>> driver DSR
>>                             &lan91cxx_interrupt_handle,
>>                             &lan91cxx_interrupt);
>>    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
>> #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>    cyg_drv_interrupt_acknowledge(cpd->interrupt);
>>    cyg_drv_interrupt_unmask(cpd->interrupt);
>>
>> And register LAN91C111 driver in my target's 
>> \packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
>> I think this is important so I put on all content.
>> #include <pkgconf/system.h>
>> #include <pkgconf/devs_eth_sh_inserter.h>
>> #include <cyg/hal/hal_intr.h>
>>
>> // MAC address is stored as a Redboot config option
>> #ifdef CYGPKG_REDBOOT
>> #include <pkgconf/redboot.h>
>> #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
>> #include <redboot.h>
>> #include <flash_config.h>
>>
>> #define LAN91CXX_IS_LAN91C111
>>
>> RedBoot_config_option("Network hardware address [MAC]",
>>                      inserter_esa,
>>                      ALWAYS_ENABLED, true,
>>                      CONFIG_ESA, 0
>>    );
>> #endif
>> #endif
>>
>> // ESA address fetch function
>> static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
>> {
>>    // Fetch hardware address from RedBoot config
>> #if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
>> #if defined(CYGPKG_REDBOOT) && \
>>    defined(CYGSEM_REDBOOT_FLASH_CONFIG)
>>    flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
>> #else
>> #error "No RedBoot flash configuration to store ESA"
>> #endif
>> #else
>>    unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
>>    memcpy(cpd->enaddr, static_esa, 6);
>> #endif
>> }
>>
>> static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
>>    config_enaddr : inserter_get_ESA,
>> #ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>>    enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
>>    hardwired_esa : true,
>> #else
>>    hardwired_esa : false,
>> #endif
>>
>> #if 0
>>   base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
>>   attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
>>   interrupt : SA1110_IRQ_GPIO_ETH
>> #else
>>   base : (unsigned short *) 0xa8000000,
>>   interrupt : 9,
>> #endif
>> };
>>
>> ETH_DRV_SC(lan91cxx_sc,
>>           &lan91cxx_eth0_priv_data,          // Driver specific data
>>           CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
>>           lan91cxx_start,
>>           lan91cxx_stop,
>>           lan91cxx_control,
>>           lan91cxx_can_send,
>>           lan91cxx_send,
>>           lan91cxx_recv,
>>           lan91cxx_deliver,
>>           lan91cxx_poll,
>>           lan91cxx_int_vector
>> );
>>
>> NETDEVTAB_ENTRY(lan91cxx_netdev,
>>                "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
>>                smsc_lan91cxx_init,
>>                &lan91cxx_sc);
>>
>> //EOF devs_eth_inserter.inl
>>
>> I found ETH_DRV_SC definition as below.
>> \packages\io\eth\current\include\eth_drv.h
>> #define 
>> ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) 
>> \
>> static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int 
>> flags); \
>> static void stop(struct eth_drv_sc *sc); \
>> static int  control(struct eth_drv_sc *sc, unsigned long key, void *data, 
>> int data_length); \
>> static int  can_send(struct eth_drv_sc *sc); \
>> static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
>> sg_len, int total, unsigned long key); \
>> static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
>> sg_len); \
>> static void deliver(struct eth_drv_sc *sc); \
>> static void poll(struct eth_drv_sc *sc); \
>> static int  int_vector(struct eth_drv_sc *sc); \
>> static struct eth_hwr_funs sc##_funs = {        \
>>    start,                                      \
>>    stop,                                       \
>>    control,                                    \
>>    can_send,                                   \
>>    send,                                       \
>>    recv,                                       \
>>    deliver,                                    \
>>    poll,                                       \
>>    int_vector,                                 \
>>    &eth_drv_funs,                              \
>>    (struct eth_drv_funs *)0 };                 \
>> struct eth_drv_sc sc = {&sc##_funs, priv, name};
>>
>> I assume this is developed like below,
>> #define 
>> ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) 
>> \
>> static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned char 
>> *enaddr, int flags); \
>> static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
>> static int  lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned 
>> long key, void *data, int data_length); \
>> static int  lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
>> static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct 
>> eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
>> static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct 
>> eth_drv_sg *sg_list, int sg_len); \
>> static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
>> static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
>> static int  lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
>> static struct eth_hwr_funs lan91cxx_sc_funs = {        \
>>    lan91cxx_start,                                      \
>>    lan91cxx_stop,                                       \
>>    lan91cxx_control,                                    \
>>    lan91cxx_can_send,                                   \
>>    lan91cxx_send,                                       \
>>    lan91cxx_recv,                                       \
>>    lan91cxx_deliver,                                    \
>>    lan91cxx_poll,                                       \
>>    lan91cxx_int_vector,                                 \
>>    &eth_drv_funs,                              \
>>    (struct eth_drv_funs *)0 };                 \
>> struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, 
>> &lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};
>>
>> I assume lan91cxx_recv must be called to operate on packets,
>> but it was never called.
>>
>> I traced DSR routine
>> DSR is this
>> \packages\io\eth\current\src\net\eth_drv.c
>> void
>> eth_drv_dsr(cyg_vector_t vector,
>>            cyg_ucount32 count,
>>            cyg_addrword_t data)
>> {
>>    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
>>
>> #ifdef CYGDBG_USE_ASSERTS
>>    // then check that this really is a "sc"
>>    {
>>        cyg_netdevtab_entry_t *t;
>>        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
>>            if ( ((struct eth_drv_sc *)t->device_instance) == sc )
>>                break; // found it
>>        CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to find 
>> sc in NETDEVTAB" );
>>    }
>> #endif // Checking code
>>
>>    sc->state |= ETH_DRV_NEEDS_DELIVERY;
>>
>>    ecos_synch_eth_drv_dsr(); // [request] run delivery function for this 
>> dev
>> }
>>
>> And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
>> void ecos_synch_eth_drv_dsr(void)
>> {
>>    cyg_flag_setbits( &alarm_flag, 2 );
>> }
>>
>> And in \packages\kernel\current\src\common\kapi.cxx
>> void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
>> {
>>    ((Cyg_Flag *)flag)->setbits( value );
>> }
>>
>> And in \packages\kernel\current\src\sync\flag.cxx
>> void
>> Cyg_Flag::setbits( Cyg_FlagValue arg )
>> {
>>    CYG_REPORT_FUNCTION();
>>    CYG_ASSERTCLASS( this, "Bad this pointer");
>>
>>    // Prevent preemption
>>    Cyg_Scheduler::lock();
>>
>>    // OR in the argument to get a new flag value.
>>    value |= arg;
>>
>>    // anyone waiting?
>>    if ( !(queue.empty()) ) {
>>        FlagWaitInfo   *p;
>>        Cyg_Thread     *thread;
>>        Cyg_ThreadQueue holding;
>>
>>        do {
>>            thread = queue.dequeue();
>>            p = (FlagWaitInfo *)(thread->get_wait_info());
>>
>>            CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
>>                        "Both masks set" );
>>            CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );
>>
>>            if ( ((p->allmask != 0) && (p->allmask & value) == p->allmask) 
>> ||
>>                 ((p->anymask & value) != 0 ) ) {
>>                // success!  awaken the thread
>>                thread->set_wake_reason( Cyg_Thread::DONE );
>>                thread->wake();
>>                // return the successful value to it
>>                p->value_out = value;
>>                // do we clear the value; is this the end?
>>                if ( p->do_clear ) {
>>                    // we can break here but need to preserve ordering
>>                    value = 0;
>>                    // so let it cycle the whole queue regardless
>>                }
>>            }
>>            else {
>>                // preserve the entry on the holding queue
>>                holding.enqueue( thread );
>>            }
>>        } while ( !(queue.empty()) );
>>
>>        // Now re-queue the unaffected threads back into the flag queue
>>        while ( !(holding.empty()) ) {
>>            queue.enqueue( holding.dequeue() );
>>        }
>>    }
>>    // Unlock scheduler and allow other threads to run
>>    Cyg_Scheduler::unlock();
>>    CYG_REPORT_RETURN();
>> }
>>
>> Truely,I cannot fathom this coding and
>> I would appreciate if you kindly teach me how lan91cxx_recv is to be 
>> called.
>>
>> Now I describe what I have tampered with in detail,please forgive me 
>> lengthy details.
>> The beginning of the matter is when I ran eCos as it is,I couldn't make 
>> LAN91C111 into LINK State,
>> LINK LED didn't light.So I inserted my own routine in order to operate 
>> LAN91C111 into LINK State in top of
>> \packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function like 
>> below.
>> eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
>> {
>>    // this is my tampered coding
>>    cyg_netdevtab_entry_t *t;
>>
>>    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
>> #ifdef CYGPKG_NET_FREEBSD_STACK
>>    int unit;
>>    char *np, *xp;
>> #endif
>>
>>    // this is my tampered coding
>>    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
>>        log(LOG_INIT, "Init device '%s'\n", t->name);
>>        if (smsc_91c111_init(t)) {             // this is my concocted 
>> routine
>>            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
>>        } else {
>>            // What to do if device init fails?
>>            t->status = 0;  // Device not [currently] available
>>        }
>>    }
>>
>> and in order making LAN91C111 into LINK State it was necessary to use 
>> interrupt so I enabled LAN91C111 interrupt in my concocted routine.
>> Above-mentioned interrupt was caused by my tampered code.At 
>> LINK-established time interrupt happened.
>>
>> On second thought, I realized my tampering was wrong.
>> So I quitted my tampering routine, I returned to eCos original source and 
>> checked why couldn't make LINK LED lighed.
>> I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC routines).
>>
>> Below is RedBoot output messages log.
>> I breaked lan91cxx_start() but never entered it.
>> I made DEBUG_FUNCTION() available.
>> -- RedBoot output messages log
>> My Flash ID is 4:22f9:0:19
>> eth_drv_init:enaddr=0x8c0005c4
>> Ethernet eth0: MAC address 00:40:31:08:01:00
>> IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
>> Default server: 172.16.1.1
>>
>> RedBoot(tm) bootstrap and debug environment [ROM]
>> Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007
>>
>> Platform: inserter (SH 7709S)
>> Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
>> Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited
>>
>> RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
>> FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
>> == Executing boot script in 3.000 seconds - enter ^C to abort
>> RedBoot> fis load -b 0x8c010000 nc_slave
>> RedBoot> channel 1
>> RedBoot> go 0x8c010000
>> Network stack using 69632 bytes for misc space
>>                    69632 bytes for mbufs
>>                    139264 bytes for mbuf clusters
>> [cyg_net_init] Init: mbinit(0x00000000)
>> [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
>> Init device 'lan91cxx_eth0'
>> smsc_lan91cxx_init
>> LAN91CXX - supposed BankReg @ a800000e = 3302
>> LAN91CXX - type: 9, rev: 1
>> LAN91CXX - status: 0069
>> LAN91CXX - static ESA: 00:40:31:08:01:00
>> [cyg_net_init] Init: loopattach(0x00000000)
>> [cyg_net_init] Init: ifinit(0x00000000)
>> [cyg_net_init] Init: domaininit(0x00000000)
>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
>> New domain internet at 0x00000000
>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
>> New domain route at 0x00000000
>> [cyg_net_init] Init: call_route_init(0x00000000)
>> [cyg_net_init] Done
>> Start Network Characterization - SLAVE
>> No load = 58470
>> Set background load = 20%
>> Set background load = 0%
>> High Load[20] = 37131 => 37%
>> Set background load = 20%
>> Set background load = 0%
>> Load[10] = 47736 => 19%
>> Set background load = 20%
>> Set background load = 0%
>> Final load[10] = 47853 => 19%
>> Start test for eth0
>> -- end of RedBoot output messages log
>>
>> All matters considered,I deduce that ETH_DRV_SC-table-reference-functions 
>> are not working.
>> I cannot understand where and how they are called.
>> Please teach me how to correctly call these functions.
>>
>
>
> -- 
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>
> 


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ECOS] Not working lan91cxx_sc drv
  2007-10-02  4:46     ` ariga masahiro
@ 2007-10-02  5:27       ` ariga masahiro
  2007-10-02  7:08         ` ariga masahiro
  0 siblings, 1 reply; 8+ messages in thread
From: ariga masahiro @ 2007-10-02  5:27 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss

Hi,

I put on my target's eth_drivers CDL file.
inserter_eth_drivers.cdl
In order to work ETH_DRV_SC-table-reference-functions,
if anything missing,please teach me.

cdl_package CYGPKG_DEVS_ETH_SH_INSERTER {

    display       "Inserter SMC91C96 ethernet driver"

    parent        CYGPKG_IO_ETH_DRIVERS
    active_if   CYGPKG_IO_ETH_DRIVERS
    active_if   CYGPKG_HAL_SH_SH77X9_inserter

    # chip wired in PCMCIA, 16-bit mode, no EEPROM
    implements    CYGHWR_NET_DRIVERS
    implements    CYGHWR_NET_DRIVER_ETH0
    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA

    requires      CYGPKG_DEVS_ETH_SMSC_LAN91CXX
    description   "Ethernet driver for Inserter boards."

    include_dir   cyg/io
    compile       if_inserter.c

    define_proc {
        puts $::cdl_system_header "/***** ethernet driver proc output start 
*****/"
        puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL 
<cyg/io/devs_eth_inserter.inl>"
        puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG 
<pkgconf/devs_eth_sh_inserter.h>"
        puts $::cdl_system_header "/*****  ethernet driver proc output end 
*****/"
    }

    # Arguably this should do in the generic package
    # but then there is a logic loop so you can never enable it.

    cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
        display   "SMSC LAN91CXX driver required"
    }

    cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_NAME {
        display       "Device name for the ethernet driver"
        flavor        data
        default_value {"\"eth0\""}
        description   "
            This option sets the name of the ethernet device for the
            ethernet port."
    }

    cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_ESA {
        display       "The ethernet station address (MAC)"
        flavor        data
        default_value {"{0x00, 0x40, 0x31, 0x08, 0x01, 0x00}"}
        description   "A static ethernet station address.
            Caution: Booting two systems with the same MAC on the same
            network, will cause severe conflicts."
        active_if     !CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
    }

    cdl_option CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA {
        display "Use the RedBoot ESA (MAC address)"
        default_value 0
        flavor        bool
        description   "
            Use the ESA that is stored as a RedBoot variable instead of
            a static ESA."
    }

}
# EOF inserter_eth_drivers.cdl

Mashiro Ariga

-- my prev mail
> In order to work ETH_DRV_SC-table-reference-functions,
> should I add anything in CDL ?
>
> If there is,
> I would appreciate if you show me sample CDL.
>
> Please help me.
>
> Masahiro Ariga
>
> -- my previous mail
>> I realized I should check Configuration conflicts.
>>
>> When building "net" template,appeares 2 Resolve Conflicts windows.
>> I donnot know how much level auto-amendment system guarantees,
>> but I relied auto-amendment completely.
>>
>> All-items tracking down is impossible because I consumed time enough.
>> If any one hits you as most suspecting,please let me know.
>>
>> [First Resolve Conflicts window]
>> Resolve conflicts
>> CYGPKG_DEVS_FLASH_SH_inserter       Requires 
>> CYGHWR_DEVS_FLASH_AMD_AM29LV160
>> CYGPKG_HAL_SH_SH77X9_inserter        Requires 
>> CYGHWR_HAL_SH_IRQ_USE_IRQLVL
>> CYGPRI_HAL_SH_SH77X9_VARIANT_7709S  Requires CYGPRI_HAL_SH_SH77X9_SUPERIO
>>
>> Proposed Solutions:
>> CYGPRI_HAL_SH_SH77X9_SUPERIO           Enabled
>> CYGHWR_HAL_SH_IRQ_USE_IRQLVL        Enabled
>> CYGHWR_DEVS_FLASH_AMD_AM29LV160     Enabled
>>
>> [Second Resolve Conflicts window]
>> CYGPKG_POSIX_CLOCKS                   Requires 
>> CYGBLD_ISO_STRUCTTIMEVAL_HEADER == "<cyg/posix/sys/time.h>"
>> CYGPKG_FILEIO_FNMATCH               Requires CYGBLD_ISO_FNMATCH_HEADER == 
>> "<cyg/fileio/fnmatch.h>"
>>
>> Proposed Solutions:
>> CYGBLD_ISO_FNMATCH_HEADER                 Enabled,<cyg/fileio/fnmatch.h>
>> CYGBLD_ISO_STRUCTTIMEVAL_HEADER     Enabled,<cyg/posix/sys/time.h>
>>
>> Please help me.
>>
>> Mashiro Ariga
>>
>> -- my previous mail.
>>> As I said,
>>> My target uses SMSC LAN91C111 chip,CPU is SH7709S.
>>> As ethernet interrupt,uses IRQ3 line.
>>> I build "net" template,eCos source is updated by CVS checkout.
>>>
>>> As I inserted LAN91C111's mask routine in the ISR,
>>> I succeeded to entered into DSR.
>>> (This interrupt was caused not by eCos-proper code, but by my tampered
>>> routine.I will later explain.)
>>> But although RCV-INT is assserted,delivering-packet routine never 
>>> called,
>>> so I entered repetedly ISR and DSR.
>>> Then I discovered LAN91C111 driver's receive routine was never called.
>>>
>>> Please forgive me long mail,but I try to
>>> inform you as correctly as possible.
>>> First I relate current problem,and later describe what I have tampered 
>>> with.
>>>
>>> I register SMSC interrupt ruoitne
>>> in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
>>> smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
>>> like this,
>>> #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>>    // Initialize environment, setup interrupt handler
>>>    cyg_drv_interrupt_create(cpd->interrupt,
>>>                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
>>>                             (cyg_addrword_t)sc, //  Data item passed to 
>>> interrupt handler
>>>                             (cyg_ISR_t *)lan91cxx_isr,
>>>                             (cyg_DSR_t *)eth_drv_dsr, // The logical 
>>> driver DSR
>>>                             &lan91cxx_interrupt_handle,
>>>                             &lan91cxx_interrupt);
>>>    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
>>> #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>>    cyg_drv_interrupt_acknowledge(cpd->interrupt);
>>>    cyg_drv_interrupt_unmask(cpd->interrupt);
>>>
>>> And register LAN91C111 driver in my target's 
>>> \packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
>>> I think this is important so I put on all content.
>>> #include <pkgconf/system.h>
>>> #include <pkgconf/devs_eth_sh_inserter.h>
>>> #include <cyg/hal/hal_intr.h>
>>>
>>> // MAC address is stored as a Redboot config option
>>> #ifdef CYGPKG_REDBOOT
>>> #include <pkgconf/redboot.h>
>>> #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
>>> #include <redboot.h>
>>> #include <flash_config.h>
>>>
>>> #define LAN91CXX_IS_LAN91C111
>>>
>>> RedBoot_config_option("Network hardware address [MAC]",
>>>                      inserter_esa,
>>>                      ALWAYS_ENABLED, true,
>>>                      CONFIG_ESA, 0
>>>    );
>>> #endif
>>> #endif
>>>
>>> // ESA address fetch function
>>> static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
>>> {
>>>    // Fetch hardware address from RedBoot config
>>> #if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
>>> #if defined(CYGPKG_REDBOOT) && \
>>>    defined(CYGSEM_REDBOOT_FLASH_CONFIG)
>>>    flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
>>> #else
>>> #error "No RedBoot flash configuration to store ESA"
>>> #endif
>>> #else
>>>    unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
>>>    memcpy(cpd->enaddr, static_esa, 6);
>>> #endif
>>> }
>>>
>>> static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
>>>    config_enaddr : inserter_get_ESA,
>>> #ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>>>    enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
>>>    hardwired_esa : true,
>>> #else
>>>    hardwired_esa : false,
>>> #endif
>>>
>>> #if 0
>>>   base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
>>>   attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
>>>   interrupt : SA1110_IRQ_GPIO_ETH
>>> #else
>>>   base : (unsigned short *) 0xa8000000,
>>>   interrupt : 9,
>>> #endif
>>> };
>>>
>>> ETH_DRV_SC(lan91cxx_sc,
>>>           &lan91cxx_eth0_priv_data,          // Driver specific data
>>>           CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
>>>           lan91cxx_start,
>>>           lan91cxx_stop,
>>>           lan91cxx_control,
>>>           lan91cxx_can_send,
>>>           lan91cxx_send,
>>>           lan91cxx_recv,
>>>           lan91cxx_deliver,
>>>           lan91cxx_poll,
>>>           lan91cxx_int_vector
>>> );
>>>
>>> NETDEVTAB_ENTRY(lan91cxx_netdev,
>>>                "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
>>>                smsc_lan91cxx_init,
>>>                &lan91cxx_sc);
>>>
>>> //EOF devs_eth_inserter.inl
>>>
>>> I found ETH_DRV_SC definition as below.
>>> \packages\io\eth\current\include\eth_drv.h
>>> #define 
>>> ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) 
>>> \
>>> static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int 
>>> flags); \
>>> static void stop(struct eth_drv_sc *sc); \
>>> static int  control(struct eth_drv_sc *sc, unsigned long key, void 
>>> *data, int data_length); \
>>> static int  can_send(struct eth_drv_sc *sc); \
>>> static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
>>> sg_len, int total, unsigned long key); \
>>> static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
>>> sg_len); \
>>> static void deliver(struct eth_drv_sc *sc); \
>>> static void poll(struct eth_drv_sc *sc); \
>>> static int  int_vector(struct eth_drv_sc *sc); \
>>> static struct eth_hwr_funs sc##_funs = {        \
>>>    start,                                      \
>>>    stop,                                       \
>>>    control,                                    \
>>>    can_send,                                   \
>>>    send,                                       \
>>>    recv,                                       \
>>>    deliver,                                    \
>>>    poll,                                       \
>>>    int_vector,                                 \
>>>    &eth_drv_funs,                              \
>>>    (struct eth_drv_funs *)0 };                 \
>>> struct eth_drv_sc sc = {&sc##_funs, priv, name};
>>>
>>> I assume this is developed like below,
>>> #define 
>>> ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) 
>>> \
>>> static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned char 
>>> *enaddr, int flags); \
>>> static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
>>> static int  lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned 
>>> long key, void *data, int data_length); \
>>> static int  lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
>>> static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct 
>>> eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
>>> static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct 
>>> eth_drv_sg *sg_list, int sg_len); \
>>> static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
>>> static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
>>> static int  lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
>>> static struct eth_hwr_funs lan91cxx_sc_funs = {        \
>>>    lan91cxx_start,                                      \
>>>    lan91cxx_stop,                                       \
>>>    lan91cxx_control,                                    \
>>>    lan91cxx_can_send,                                   \
>>>    lan91cxx_send,                                       \
>>>    lan91cxx_recv,                                       \
>>>    lan91cxx_deliver,                                    \
>>>    lan91cxx_poll,                                       \
>>>    lan91cxx_int_vector,                                 \
>>>    &eth_drv_funs,                              \
>>>    (struct eth_drv_funs *)0 };                 \
>>> struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, 
>>> &lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};
>>>
>>> I assume lan91cxx_recv must be called to operate on packets,
>>> but it was never called.
>>>
>>> I traced DSR routine
>>> DSR is this
>>> \packages\io\eth\current\src\net\eth_drv.c
>>> void
>>> eth_drv_dsr(cyg_vector_t vector,
>>>            cyg_ucount32 count,
>>>            cyg_addrword_t data)
>>> {
>>>    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
>>>
>>> #ifdef CYGDBG_USE_ASSERTS
>>>    // then check that this really is a "sc"
>>>    {
>>>        cyg_netdevtab_entry_t *t;
>>>        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
>>>            if ( ((struct eth_drv_sc *)t->device_instance) == sc )
>>>                break; // found it
>>>        CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to find 
>>> sc in NETDEVTAB" );
>>>    }
>>> #endif // Checking code
>>>
>>>    sc->state |= ETH_DRV_NEEDS_DELIVERY;
>>>
>>>    ecos_synch_eth_drv_dsr(); // [request] run delivery function for this 
>>> dev
>>> }
>>>
>>> And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
>>> void ecos_synch_eth_drv_dsr(void)
>>> {
>>>    cyg_flag_setbits( &alarm_flag, 2 );
>>> }
>>>
>>> And in \packages\kernel\current\src\common\kapi.cxx
>>> void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
>>> {
>>>    ((Cyg_Flag *)flag)->setbits( value );
>>> }
>>>
>>> And in \packages\kernel\current\src\sync\flag.cxx
>>> void
>>> Cyg_Flag::setbits( Cyg_FlagValue arg )
>>> {
>>>    CYG_REPORT_FUNCTION();
>>>    CYG_ASSERTCLASS( this, "Bad this pointer");
>>>
>>>    // Prevent preemption
>>>    Cyg_Scheduler::lock();
>>>
>>>    // OR in the argument to get a new flag value.
>>>    value |= arg;
>>>
>>>    // anyone waiting?
>>>    if ( !(queue.empty()) ) {
>>>        FlagWaitInfo   *p;
>>>        Cyg_Thread     *thread;
>>>        Cyg_ThreadQueue holding;
>>>
>>>        do {
>>>            thread = queue.dequeue();
>>>            p = (FlagWaitInfo *)(thread->get_wait_info());
>>>
>>>            CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
>>>                        "Both masks set" );
>>>            CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );
>>>
>>>            if ( ((p->allmask != 0) && (p->allmask & value) == 
>>> p->allmask) ||
>>>                 ((p->anymask & value) != 0 ) ) {
>>>                // success!  awaken the thread
>>>                thread->set_wake_reason( Cyg_Thread::DONE );
>>>                thread->wake();
>>>                // return the successful value to it
>>>                p->value_out = value;
>>>                // do we clear the value; is this the end?
>>>                if ( p->do_clear ) {
>>>                    // we can break here but need to preserve ordering
>>>                    value = 0;
>>>                    // so let it cycle the whole queue regardless
>>>                }
>>>            }
>>>            else {
>>>                // preserve the entry on the holding queue
>>>                holding.enqueue( thread );
>>>            }
>>>        } while ( !(queue.empty()) );
>>>
>>>        // Now re-queue the unaffected threads back into the flag queue
>>>        while ( !(holding.empty()) ) {
>>>            queue.enqueue( holding.dequeue() );
>>>        }
>>>    }
>>>    // Unlock scheduler and allow other threads to run
>>>    Cyg_Scheduler::unlock();
>>>    CYG_REPORT_RETURN();
>>> }
>>>
>>> Truely,I cannot fathom this coding and
>>> I would appreciate if you kindly teach me how lan91cxx_recv is to be 
>>> called.
>>>
>>> Now I describe what I have tampered with in detail,please forgive me 
>>> lengthy details.
>>> The beginning of the matter is when I ran eCos as it is,I couldn't make 
>>> LAN91C111 into LINK State,
>>> LINK LED didn't light.So I inserted my own routine in order to operate 
>>> LAN91C111 into LINK State in top of
>>> \packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function like 
>>> below.
>>> eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
>>> {
>>>    // this is my tampered coding
>>>    cyg_netdevtab_entry_t *t;
>>>
>>>    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
>>> #ifdef CYGPKG_NET_FREEBSD_STACK
>>>    int unit;
>>>    char *np, *xp;
>>> #endif
>>>
>>>    // this is my tampered coding
>>>    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
>>>        log(LOG_INIT, "Init device '%s'\n", t->name);
>>>        if (smsc_91c111_init(t)) {             // this is my concocted 
>>> routine
>>>            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
>>>        } else {
>>>            // What to do if device init fails?
>>>            t->status = 0;  // Device not [currently] available
>>>        }
>>>    }
>>>
>>> and in order making LAN91C111 into LINK State it was necessary to use 
>>> interrupt so I enabled LAN91C111 interrupt in my concocted routine.
>>> Above-mentioned interrupt was caused by my tampered code.At 
>>> LINK-established time interrupt happened.
>>>
>>> On second thought, I realized my tampering was wrong.
>>> So I quitted my tampering routine, I returned to eCos original source 
>>> and checked why couldn't make LINK LED lighed.
>>> I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC 
>>> routines).
>>>
>>> Below is RedBoot output messages log.
>>> I breaked lan91cxx_start() but never entered it.
>>> I made DEBUG_FUNCTION() available.
>>> -- RedBoot output messages log
>>> My Flash ID is 4:22f9:0:19
>>> eth_drv_init:enaddr=0x8c0005c4
>>> Ethernet eth0: MAC address 00:40:31:08:01:00
>>> IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
>>> Default server: 172.16.1.1
>>>
>>> RedBoot(tm) bootstrap and debug environment [ROM]
>>> Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007
>>>
>>> Platform: inserter (SH 7709S)
>>> Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
>>> Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited
>>>
>>> RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
>>> FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
>>> == Executing boot script in 3.000 seconds - enter ^C to abort
>>> RedBoot> fis load -b 0x8c010000 nc_slave
>>> RedBoot> channel 1
>>> RedBoot> go 0x8c010000
>>> Network stack using 69632 bytes for misc space
>>>                    69632 bytes for mbufs
>>>                    139264 bytes for mbuf clusters
>>> [cyg_net_init] Init: mbinit(0x00000000)
>>> [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
>>> Init device 'lan91cxx_eth0'
>>> smsc_lan91cxx_init
>>> LAN91CXX - supposed BankReg @ a800000e = 3302
>>> LAN91CXX - type: 9, rev: 1
>>> LAN91CXX - status: 0069
>>> LAN91CXX - static ESA: 00:40:31:08:01:00
>>> [cyg_net_init] Init: loopattach(0x00000000)
>>> [cyg_net_init] Init: ifinit(0x00000000)
>>> [cyg_net_init] Init: domaininit(0x00000000)
>>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
>>> New domain internet at 0x00000000
>>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
>>> New domain route at 0x00000000
>>> [cyg_net_init] Init: call_route_init(0x00000000)
>>> [cyg_net_init] Done
>>> Start Network Characterization - SLAVE
>>> No load = 58470
>>> Set background load = 20%
>>> Set background load = 0%
>>> High Load[20] = 37131 => 37%
>>> Set background load = 20%
>>> Set background load = 0%
>>> Load[10] = 47736 => 19%
>>> Set background load = 20%
>>> Set background load = 0%
>>> Final load[10] = 47853 => 19%
>>> Start test for eth0
>>> -- end of RedBoot output messages log
>>>
>>> All matters considered,I deduce that 
>>> ETH_DRV_SC-table-reference-functions are not working.
>>> I cannot understand where and how they are called.
>>> Please teach me how to correctly call these functions.
>>>
>>
>>
>> -- 
>> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
>> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>>
>>
>
>
> -- 
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>
> 


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ECOS] Not working lan91cxx_sc drv
  2007-10-02  5:27       ` ariga masahiro
@ 2007-10-02  7:08         ` ariga masahiro
  2007-10-02 10:45           ` ariga masahiro
  2007-10-11  9:01           ` [ECOS] Not enter VSR routine when lan91cxx_start executed ariga masahiro
  0 siblings, 2 replies; 8+ messages in thread
From: ariga masahiro @ 2007-10-02  7:08 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss

Hi,

Forgive me rushing mails,
but I am in desperate.

I am convinced if I only could call lan91cxx_start in ETH_DRV_SC-table
then  it begin to work ethernet drv.

Please teach me where I should set  break_point to trace lan91cxx_start.
Or any hints to tracking lan91cxx_start ?

Please help me.

Masahiro Ariga

-- my prev mai.
> Hi,
>
> I put on my target's eth_drivers CDL file.
> inserter_eth_drivers.cdl
> In order to work ETH_DRV_SC-table-reference-functions,
> if anything missing,please teach me.
>
> cdl_package CYGPKG_DEVS_ETH_SH_INSERTER {
>
>    display       "Inserter SMC91C96 ethernet driver"
>
>    parent        CYGPKG_IO_ETH_DRIVERS
>    active_if   CYGPKG_IO_ETH_DRIVERS
>    active_if   CYGPKG_HAL_SH_SH77X9_inserter
>
>    # chip wired in PCMCIA, 16-bit mode, no EEPROM
>    implements    CYGHWR_NET_DRIVERS
>    implements    CYGHWR_NET_DRIVER_ETH0
>    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
>    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
>    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
>
>    requires      CYGPKG_DEVS_ETH_SMSC_LAN91CXX
>    description   "Ethernet driver for Inserter boards."
>
>    include_dir   cyg/io
>    compile       if_inserter.c
>
>    define_proc {
>        puts $::cdl_system_header "/***** ethernet driver proc output start 
> *****/"
>        puts $::cdl_system_header "#define 
> CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_inserter.inl>"
>        puts $::cdl_system_header "#define 
> CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_sh_inserter.h>"
>        puts $::cdl_system_header "/*****  ethernet driver proc output end 
> *****/"
>    }
>
>    # Arguably this should do in the generic package
>    # but then there is a logic loop so you can never enable it.
>
>    cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
>        display   "SMSC LAN91CXX driver required"
>    }
>
>    cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_NAME {
>        display       "Device name for the ethernet driver"
>        flavor        data
>        default_value {"\"eth0\""}
>        description   "
>            This option sets the name of the ethernet device for the
>            ethernet port."
>    }
>
>    cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_ESA {
>        display       "The ethernet station address (MAC)"
>        flavor        data
>        default_value {"{0x00, 0x40, 0x31, 0x08, 0x01, 0x00}"}
>        description   "A static ethernet station address.
>            Caution: Booting two systems with the same MAC on the same
>            network, will cause severe conflicts."
>        active_if     !CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>    }
>
>    cdl_option CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA {
>        display "Use the RedBoot ESA (MAC address)"
>        default_value 0
>        flavor        bool
>        description   "
>            Use the ESA that is stored as a RedBoot variable instead of
>            a static ESA."
>    }
>
> }
> # EOF inserter_eth_drivers.cdl
>
> Mashiro Ariga
>
> -- my prev mail
>> In order to work ETH_DRV_SC-table-reference-functions,
>> should I add anything in CDL ?
>>
>> If there is,
>> I would appreciate if you show me sample CDL.
>>
>> Please help me.
>>
>> Masahiro Ariga
>>
>> -- my previous mail
>>> I realized I should check Configuration conflicts.
>>>
>>> When building "net" template,appeares 2 Resolve Conflicts windows.
>>> I donnot know how much level auto-amendment system guarantees,
>>> but I relied auto-amendment completely.
>>>
>>> All-items tracking down is impossible because I consumed time enough.
>>> If any one hits you as most suspecting,please let me know.
>>>
>>> [First Resolve Conflicts window]
>>> Resolve conflicts
>>> CYGPKG_DEVS_FLASH_SH_inserter       Requires 
>>> CYGHWR_DEVS_FLASH_AMD_AM29LV160
>>> CYGPKG_HAL_SH_SH77X9_inserter        Requires 
>>> CYGHWR_HAL_SH_IRQ_USE_IRQLVL
>>> CYGPRI_HAL_SH_SH77X9_VARIANT_7709S  Requires 
>>> CYGPRI_HAL_SH_SH77X9_SUPERIO
>>>
>>> Proposed Solutions:
>>> CYGPRI_HAL_SH_SH77X9_SUPERIO           Enabled
>>> CYGHWR_HAL_SH_IRQ_USE_IRQLVL        Enabled
>>> CYGHWR_DEVS_FLASH_AMD_AM29LV160     Enabled
>>>
>>> [Second Resolve Conflicts window]
>>> CYGPKG_POSIX_CLOCKS                   Requires 
>>> CYGBLD_ISO_STRUCTTIMEVAL_HEADER == "<cyg/posix/sys/time.h>"
>>> CYGPKG_FILEIO_FNMATCH               Requires CYGBLD_ISO_FNMATCH_HEADER 
>>> == "<cyg/fileio/fnmatch.h>"
>>>
>>> Proposed Solutions:
>>> CYGBLD_ISO_FNMATCH_HEADER                 Enabled,<cyg/fileio/fnmatch.h>
>>> CYGBLD_ISO_STRUCTTIMEVAL_HEADER     Enabled,<cyg/posix/sys/time.h>
>>>
>>> Please help me.
>>>
>>> Mashiro Ariga
>>>
>>> -- my previous mail.
>>>> As I said,
>>>> My target uses SMSC LAN91C111 chip,CPU is SH7709S.
>>>> As ethernet interrupt,uses IRQ3 line.
>>>> I build "net" template,eCos source is updated by CVS checkout.
>>>>
>>>> As I inserted LAN91C111's mask routine in the ISR,
>>>> I succeeded to entered into DSR.
>>>> (This interrupt was caused not by eCos-proper code, but by my tampered
>>>> routine.I will later explain.)
>>>> But although RCV-INT is assserted,delivering-packet routine never 
>>>> called,
>>>> so I entered repetedly ISR and DSR.
>>>> Then I discovered LAN91C111 driver's receive routine was never called.
>>>>
>>>> Please forgive me long mail,but I try to
>>>> inform you as correctly as possible.
>>>> First I relate current problem,and later describe what I have tampered 
>>>> with.
>>>>
>>>> I register SMSC interrupt ruoitne
>>>> in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
>>>> smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
>>>> like this,
>>>> #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>>>    // Initialize environment, setup interrupt handler
>>>>    cyg_drv_interrupt_create(cpd->interrupt,
>>>>                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
>>>>                             (cyg_addrword_t)sc, //  Data item passed to 
>>>> interrupt handler
>>>>                             (cyg_ISR_t *)lan91cxx_isr,
>>>>                             (cyg_DSR_t *)eth_drv_dsr, // The logical 
>>>> driver DSR
>>>>                             &lan91cxx_interrupt_handle,
>>>>                             &lan91cxx_interrupt);
>>>>    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
>>>> #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>>>    cyg_drv_interrupt_acknowledge(cpd->interrupt);
>>>>    cyg_drv_interrupt_unmask(cpd->interrupt);
>>>>
>>>> And register LAN91C111 driver in my target's 
>>>> \packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
>>>> I think this is important so I put on all content.
>>>> #include <pkgconf/system.h>
>>>> #include <pkgconf/devs_eth_sh_inserter.h>
>>>> #include <cyg/hal/hal_intr.h>
>>>>
>>>> // MAC address is stored as a Redboot config option
>>>> #ifdef CYGPKG_REDBOOT
>>>> #include <pkgconf/redboot.h>
>>>> #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
>>>> #include <redboot.h>
>>>> #include <flash_config.h>
>>>>
>>>> #define LAN91CXX_IS_LAN91C111
>>>>
>>>> RedBoot_config_option("Network hardware address [MAC]",
>>>>                      inserter_esa,
>>>>                      ALWAYS_ENABLED, true,
>>>>                      CONFIG_ESA, 0
>>>>    );
>>>> #endif
>>>> #endif
>>>>
>>>> // ESA address fetch function
>>>> static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
>>>> {
>>>>    // Fetch hardware address from RedBoot config
>>>> #if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
>>>> #if defined(CYGPKG_REDBOOT) && \
>>>>    defined(CYGSEM_REDBOOT_FLASH_CONFIG)
>>>>    flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
>>>> #else
>>>> #error "No RedBoot flash configuration to store ESA"
>>>> #endif
>>>> #else
>>>>    unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
>>>>    memcpy(cpd->enaddr, static_esa, 6);
>>>> #endif
>>>> }
>>>>
>>>> static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
>>>>    config_enaddr : inserter_get_ESA,
>>>> #ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>>>>    enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
>>>>    hardwired_esa : true,
>>>> #else
>>>>    hardwired_esa : false,
>>>> #endif
>>>>
>>>> #if 0
>>>>   base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
>>>>   attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
>>>>   interrupt : SA1110_IRQ_GPIO_ETH
>>>> #else
>>>>   base : (unsigned short *) 0xa8000000,
>>>>   interrupt : 9,
>>>> #endif
>>>> };
>>>>
>>>> ETH_DRV_SC(lan91cxx_sc,
>>>>           &lan91cxx_eth0_priv_data,          // Driver specific data
>>>>           CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
>>>>           lan91cxx_start,
>>>>           lan91cxx_stop,
>>>>           lan91cxx_control,
>>>>           lan91cxx_can_send,
>>>>           lan91cxx_send,
>>>>           lan91cxx_recv,
>>>>           lan91cxx_deliver,
>>>>           lan91cxx_poll,
>>>>           lan91cxx_int_vector
>>>> );
>>>>
>>>> NETDEVTAB_ENTRY(lan91cxx_netdev,
>>>>                "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
>>>>                smsc_lan91cxx_init,
>>>>                &lan91cxx_sc);
>>>>
>>>> //EOF devs_eth_inserter.inl
>>>>
>>>> I found ETH_DRV_SC definition as below.
>>>> \packages\io\eth\current\include\eth_drv.h
>>>> #define 
>>>> ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) 
>>>> \
>>>> static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int 
>>>> flags); \
>>>> static void stop(struct eth_drv_sc *sc); \
>>>> static int  control(struct eth_drv_sc *sc, unsigned long key, void 
>>>> *data, int data_length); \
>>>> static int  can_send(struct eth_drv_sc *sc); \
>>>> static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
>>>> sg_len, int total, unsigned long key); \
>>>> static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
>>>> sg_len); \
>>>> static void deliver(struct eth_drv_sc *sc); \
>>>> static void poll(struct eth_drv_sc *sc); \
>>>> static int  int_vector(struct eth_drv_sc *sc); \
>>>> static struct eth_hwr_funs sc##_funs = {        \
>>>>    start,                                      \
>>>>    stop,                                       \
>>>>    control,                                    \
>>>>    can_send,                                   \
>>>>    send,                                       \
>>>>    recv,                                       \
>>>>    deliver,                                    \
>>>>    poll,                                       \
>>>>    int_vector,                                 \
>>>>    &eth_drv_funs,                              \
>>>>    (struct eth_drv_funs *)0 };                 \
>>>> struct eth_drv_sc sc = {&sc##_funs, priv, name};
>>>>
>>>> I assume this is developed like below,
>>>> #define 
>>>> ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) 
>>>> \
>>>> static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned 
>>>> char *enaddr, int flags); \
>>>> static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
>>>> static int  lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned 
>>>> long key, void *data, int data_length); \
>>>> static int  lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
>>>> static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct 
>>>> eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
>>>> static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct 
>>>> eth_drv_sg *sg_list, int sg_len); \
>>>> static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
>>>> static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
>>>> static int  lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
>>>> static struct eth_hwr_funs lan91cxx_sc_funs = {        \
>>>>    lan91cxx_start,                                      \
>>>>    lan91cxx_stop,                                       \
>>>>    lan91cxx_control,                                    \
>>>>    lan91cxx_can_send,                                   \
>>>>    lan91cxx_send,                                       \
>>>>    lan91cxx_recv,                                       \
>>>>    lan91cxx_deliver,                                    \
>>>>    lan91cxx_poll,                                       \
>>>>    lan91cxx_int_vector,                                 \
>>>>    &eth_drv_funs,                              \
>>>>    (struct eth_drv_funs *)0 };                 \
>>>> struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, 
>>>> &lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};
>>>>
>>>> I assume lan91cxx_recv must be called to operate on packets,
>>>> but it was never called.
>>>>
>>>> I traced DSR routine
>>>> DSR is this
>>>> \packages\io\eth\current\src\net\eth_drv.c
>>>> void
>>>> eth_drv_dsr(cyg_vector_t vector,
>>>>            cyg_ucount32 count,
>>>>            cyg_addrword_t data)
>>>> {
>>>>    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
>>>>
>>>> #ifdef CYGDBG_USE_ASSERTS
>>>>    // then check that this really is a "sc"
>>>>    {
>>>>        cyg_netdevtab_entry_t *t;
>>>>        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
>>>>            if ( ((struct eth_drv_sc *)t->device_instance) == sc )
>>>>                break; // found it
>>>>        CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to 
>>>> find sc in NETDEVTAB" );
>>>>    }
>>>> #endif // Checking code
>>>>
>>>>    sc->state |= ETH_DRV_NEEDS_DELIVERY;
>>>>
>>>>    ecos_synch_eth_drv_dsr(); // [request] run delivery function for 
>>>> this dev
>>>> }
>>>>
>>>> And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
>>>> void ecos_synch_eth_drv_dsr(void)
>>>> {
>>>>    cyg_flag_setbits( &alarm_flag, 2 );
>>>> }
>>>>
>>>> And in \packages\kernel\current\src\common\kapi.cxx
>>>> void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) 
>>>> __THROW
>>>> {
>>>>    ((Cyg_Flag *)flag)->setbits( value );
>>>> }
>>>>
>>>> And in \packages\kernel\current\src\sync\flag.cxx
>>>> void
>>>> Cyg_Flag::setbits( Cyg_FlagValue arg )
>>>> {
>>>>    CYG_REPORT_FUNCTION();
>>>>    CYG_ASSERTCLASS( this, "Bad this pointer");
>>>>
>>>>    // Prevent preemption
>>>>    Cyg_Scheduler::lock();
>>>>
>>>>    // OR in the argument to get a new flag value.
>>>>    value |= arg;
>>>>
>>>>    // anyone waiting?
>>>>    if ( !(queue.empty()) ) {
>>>>        FlagWaitInfo   *p;
>>>>        Cyg_Thread     *thread;
>>>>        Cyg_ThreadQueue holding;
>>>>
>>>>        do {
>>>>            thread = queue.dequeue();
>>>>            p = (FlagWaitInfo *)(thread->get_wait_info());
>>>>
>>>>            CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
>>>>                        "Both masks set" );
>>>>            CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );
>>>>
>>>>            if ( ((p->allmask != 0) && (p->allmask & value) == 
>>>> p->allmask) ||
>>>>                 ((p->anymask & value) != 0 ) ) {
>>>>                // success!  awaken the thread
>>>>                thread->set_wake_reason( Cyg_Thread::DONE );
>>>>                thread->wake();
>>>>                // return the successful value to it
>>>>                p->value_out = value;
>>>>                // do we clear the value; is this the end?
>>>>                if ( p->do_clear ) {
>>>>                    // we can break here but need to preserve ordering
>>>>                    value = 0;
>>>>                    // so let it cycle the whole queue regardless
>>>>                }
>>>>            }
>>>>            else {
>>>>                // preserve the entry on the holding queue
>>>>                holding.enqueue( thread );
>>>>            }
>>>>        } while ( !(queue.empty()) );
>>>>
>>>>        // Now re-queue the unaffected threads back into the flag queue
>>>>        while ( !(holding.empty()) ) {
>>>>            queue.enqueue( holding.dequeue() );
>>>>        }
>>>>    }
>>>>    // Unlock scheduler and allow other threads to run
>>>>    Cyg_Scheduler::unlock();
>>>>    CYG_REPORT_RETURN();
>>>> }
>>>>
>>>> Truely,I cannot fathom this coding and
>>>> I would appreciate if you kindly teach me how lan91cxx_recv is to be 
>>>> called.
>>>>
>>>> Now I describe what I have tampered with in detail,please forgive me 
>>>> lengthy details.
>>>> The beginning of the matter is when I ran eCos as it is,I couldn't make 
>>>> LAN91C111 into LINK State,
>>>> LINK LED didn't light.So I inserted my own routine in order to operate 
>>>> LAN91C111 into LINK State in top of
>>>> \packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function like 
>>>> below.
>>>> eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
>>>> {
>>>>    // this is my tampered coding
>>>>    cyg_netdevtab_entry_t *t;
>>>>
>>>>    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
>>>> #ifdef CYGPKG_NET_FREEBSD_STACK
>>>>    int unit;
>>>>    char *np, *xp;
>>>> #endif
>>>>
>>>>    // this is my tampered coding
>>>>    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
>>>>        log(LOG_INIT, "Init device '%s'\n", t->name);
>>>>        if (smsc_91c111_init(t)) {             // this is my concocted 
>>>> routine
>>>>            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
>>>>        } else {
>>>>            // What to do if device init fails?
>>>>            t->status = 0;  // Device not [currently] available
>>>>        }
>>>>    }
>>>>
>>>> and in order making LAN91C111 into LINK State it was necessary to use 
>>>> interrupt so I enabled LAN91C111 interrupt in my concocted routine.
>>>> Above-mentioned interrupt was caused by my tampered code.At 
>>>> LINK-established time interrupt happened.
>>>>
>>>> On second thought, I realized my tampering was wrong.
>>>> So I quitted my tampering routine, I returned to eCos original source 
>>>> and checked why couldn't make LINK LED lighed.
>>>> I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC 
>>>> routines).
>>>>
>>>> Below is RedBoot output messages log.
>>>> I breaked lan91cxx_start() but never entered it.
>>>> I made DEBUG_FUNCTION() available.
>>>> -- RedBoot output messages log
>>>> My Flash ID is 4:22f9:0:19
>>>> eth_drv_init:enaddr=0x8c0005c4
>>>> Ethernet eth0: MAC address 00:40:31:08:01:00
>>>> IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
>>>> Default server: 172.16.1.1
>>>>
>>>> RedBoot(tm) bootstrap and debug environment [ROM]
>>>> Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007
>>>>
>>>> Platform: inserter (SH 7709S)
>>>> Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
>>>> Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited
>>>>
>>>> RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
>>>> FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
>>>> == Executing boot script in 3.000 seconds - enter ^C to abort
>>>> RedBoot> fis load -b 0x8c010000 nc_slave
>>>> RedBoot> channel 1
>>>> RedBoot> go 0x8c010000
>>>> Network stack using 69632 bytes for misc space
>>>>                    69632 bytes for mbufs
>>>>                    139264 bytes for mbuf clusters
>>>> [cyg_net_init] Init: mbinit(0x00000000)
>>>> [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
>>>> Init device 'lan91cxx_eth0'
>>>> smsc_lan91cxx_init
>>>> LAN91CXX - supposed BankReg @ a800000e = 3302
>>>> LAN91CXX - type: 9, rev: 1
>>>> LAN91CXX - status: 0069
>>>> LAN91CXX - static ESA: 00:40:31:08:01:00
>>>> [cyg_net_init] Init: loopattach(0x00000000)
>>>> [cyg_net_init] Init: ifinit(0x00000000)
>>>> [cyg_net_init] Init: domaininit(0x00000000)
>>>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
>>>> New domain internet at 0x00000000
>>>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
>>>> New domain route at 0x00000000
>>>> [cyg_net_init] Init: call_route_init(0x00000000)
>>>> [cyg_net_init] Done
>>>> Start Network Characterization - SLAVE
>>>> No load = 58470
>>>> Set background load = 20%
>>>> Set background load = 0%
>>>> High Load[20] = 37131 => 37%
>>>> Set background load = 20%
>>>> Set background load = 0%
>>>> Load[10] = 47736 => 19%
>>>> Set background load = 20%
>>>> Set background load = 0%
>>>> Final load[10] = 47853 => 19%
>>>> Start test for eth0
>>>> -- end of RedBoot output messages log
>>>>
>>>> All matters considered,I deduce that 
>>>> ETH_DRV_SC-table-reference-functions are not working.
>>>> I cannot understand where and how they are called.
>>>> Please teach me how to correctly call these functions.
>>>>
>>>
>>>
>>> -- 
>>> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
>>> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>>>
>>>
>>
>>
>> -- 
>> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
>> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>>
>>
>
>
> -- 
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>
> 


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ECOS] Not working lan91cxx_sc drv
  2007-10-02  7:08         ` ariga masahiro
@ 2007-10-02 10:45           ` ariga masahiro
  2007-10-11  9:01           ` [ECOS] Not enter VSR routine when lan91cxx_start executed ariga masahiro
  1 sibling, 0 replies; 8+ messages in thread
From: ariga masahiro @ 2007-10-02 10:45 UTC (permalink / raw)
  To: ecos-discuss

Hi,

I am sorry for bothering just one more time.
I think I found the cause of not working lan91cxx_sc drv.

I traced
eth_drv_init().
I executed next coding (number is line number),
       407: #ifdef CYGPKG_NET_FREEBSD_STACK
       408:     ether_ifattach(ifp, 0);
And
jumped to
if_ethersubr.c's
       726: ether_ifattach(ifp, bpf)

I traced to last part of the function.
       750:     if (ng_ether_attach_p != NULL)
       751:         (*ng_ether_attach_p)(ifp);
But ng_ether_attach_p == NULL,and  line751 was not executed.

I "grep"ed ng_ether_attach_p,and found it was setted by only next file.
packages\net\bsd_tcpip\current\include\sys\param.h(673): #define 
ng_ether_attach_p cyg_ng_ether_attach_p

I confirmed that I correctly included that file in building,and I used 
compile option -D_KERNEL -D__ECOS.

But my tracking stopped here and I cannot understand
why ng_ether_attach_p is become NULL.

I "grep"ed cyg_ng_ether_attach_p but found nothing.

Please teach me why ng_ether_attach_p becomes NULL.
Or is it a correct operation ?

I am very sorry for troubling you.
I hope this clears my problem.

Masahiro Ariga

> I am convinced if I only could call lan91cxx_start in ETH_DRV_SC-table
> then  it begin to work ethernet drv.
>
> Please teach me where I should set  break_point to trace lan91cxx_start.
> Or any hints to tracking lan91cxx_start ?
>

> -- my prev mai.
>> I put on my target's eth_drivers CDL file.
>> inserter_eth_drivers.cdl
>> In order to work ETH_DRV_SC-table-reference-functions,
>> if anything missing,please teach me.
>>
>> cdl_package CYGPKG_DEVS_ETH_SH_INSERTER {
>>
>>    display       "Inserter SMC91C96 ethernet driver"
>>
>>    parent        CYGPKG_IO_ETH_DRIVERS
>>    active_if   CYGPKG_IO_ETH_DRIVERS
>>    active_if   CYGPKG_HAL_SH_SH77X9_inserter
>>
>>    # chip wired in PCMCIA, 16-bit mode, no EEPROM
>>    implements    CYGHWR_NET_DRIVERS
>>    implements    CYGHWR_NET_DRIVER_ETH0
>>    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
>>    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
>>    implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
>>
>>    requires      CYGPKG_DEVS_ETH_SMSC_LAN91CXX
>>    description   "Ethernet driver for Inserter boards."
>>
>>    include_dir   cyg/io
>>    compile       if_inserter.c
>>
>>    define_proc {
>>        puts $::cdl_system_header "/***** ethernet driver proc output 
>> start *****/"
>>        puts $::cdl_system_header "#define 
>> CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_inserter.inl>"
>>        puts $::cdl_system_header "#define 
>> CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_sh_inserter.h>"
>>        puts $::cdl_system_header "/*****  ethernet driver proc output end 
>> *****/"
>>    }
>>
>>    # Arguably this should do in the generic package
>>    # but then there is a logic loop so you can never enable it.
>>
>>    cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
>>        display   "SMSC LAN91CXX driver required"
>>    }
>>
>>    cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_NAME {
>>        display       "Device name for the ethernet driver"
>>        flavor        data
>>        default_value {"\"eth0\""}
>>        description   "
>>            This option sets the name of the ethernet device for the
>>            ethernet port."
>>    }
>>
>>    cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_ESA {
>>        display       "The ethernet station address (MAC)"
>>        flavor        data
>>        default_value {"{0x00, 0x40, 0x31, 0x08, 0x01, 0x00}"}
>>        description   "A static ethernet station address.
>>            Caution: Booting two systems with the same MAC on the same
>>            network, will cause severe conflicts."
>>        active_if     !CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>>    }
>>
>>    cdl_option CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA {
>>        display "Use the RedBoot ESA (MAC address)"
>>        default_value 0
>>        flavor        bool
>>        description   "
>>            Use the ESA that is stored as a RedBoot variable instead of
>>            a static ESA."
>>    }
>>
>> }
>> # EOF inserter_eth_drivers.cdl
>>
>> Mashiro Ariga
>>
>> -- my prev mail
>>> In order to work ETH_DRV_SC-table-reference-functions,
>>> should I add anything in CDL ?
>>>
>>> If there is,
>>> I would appreciate if you show me sample CDL.
>>>
>>> Please help me.
>>>
>>> Masahiro Ariga
>>>
>>> -- my previous mail
>>>> I realized I should check Configuration conflicts.
>>>>
>>>> When building "net" template,appeares 2 Resolve Conflicts windows.
>>>> I donnot know how much level auto-amendment system guarantees,
>>>> but I relied auto-amendment completely.
>>>>
>>>> All-items tracking down is impossible because I consumed time enough.
>>>> If any one hits you as most suspecting,please let me know.
>>>>
>>>> [First Resolve Conflicts window]
>>>> Resolve conflicts
>>>> CYGPKG_DEVS_FLASH_SH_inserter       Requires 
>>>> CYGHWR_DEVS_FLASH_AMD_AM29LV160
>>>> CYGPKG_HAL_SH_SH77X9_inserter        Requires 
>>>> CYGHWR_HAL_SH_IRQ_USE_IRQLVL
>>>> CYGPRI_HAL_SH_SH77X9_VARIANT_7709S  Requires 
>>>> CYGPRI_HAL_SH_SH77X9_SUPERIO
>>>>
>>>> Proposed Solutions:
>>>> CYGPRI_HAL_SH_SH77X9_SUPERIO           Enabled
>>>> CYGHWR_HAL_SH_IRQ_USE_IRQLVL        Enabled
>>>> CYGHWR_DEVS_FLASH_AMD_AM29LV160     Enabled
>>>>
>>>> [Second Resolve Conflicts window]
>>>> CYGPKG_POSIX_CLOCKS                   Requires 
>>>> CYGBLD_ISO_STRUCTTIMEVAL_HEADER == "<cyg/posix/sys/time.h>"
>>>> CYGPKG_FILEIO_FNMATCH               Requires CYGBLD_ISO_FNMATCH_HEADER 
>>>> == "<cyg/fileio/fnmatch.h>"
>>>>
>>>> Proposed Solutions:
>>>> CYGBLD_ISO_FNMATCH_HEADER 
>>>> Enabled,<cyg/fileio/fnmatch.h>
>>>> CYGBLD_ISO_STRUCTTIMEVAL_HEADER     Enabled,<cyg/posix/sys/time.h>
>>>>
>>>> Please help me.
>>>>
>>>> Mashiro Ariga
>>>>
>>>> -- my previous mail.
>>>>> As I said,
>>>>> My target uses SMSC LAN91C111 chip,CPU is SH7709S.
>>>>> As ethernet interrupt,uses IRQ3 line.
>>>>> I build "net" template,eCos source is updated by CVS checkout.
>>>>>
>>>>> As I inserted LAN91C111's mask routine in the ISR,
>>>>> I succeeded to entered into DSR.
>>>>> (This interrupt was caused not by eCos-proper code, but by my tampered
>>>>> routine.I will later explain.)
>>>>> But although RCV-INT is assserted,delivering-packet routine never 
>>>>> called,
>>>>> so I entered repetedly ISR and DSR.
>>>>> Then I discovered LAN91C111 driver's receive routine was never called.
>>>>>
>>>>> Please forgive me long mail,but I try to
>>>>> inform you as correctly as possible.
>>>>> First I relate current problem,and later describe what I have tampered 
>>>>> with.
>>>>>
>>>>> I register SMSC interrupt ruoitne
>>>>> in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
>>>>> smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
>>>>> like this,
>>>>> #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>>>>    // Initialize environment, setup interrupt handler
>>>>>    cyg_drv_interrupt_create(cpd->interrupt,
>>>>>                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
>>>>>                             (cyg_addrword_t)sc, //  Data item passed 
>>>>> to interrupt handler
>>>>>                             (cyg_ISR_t *)lan91cxx_isr,
>>>>>                             (cyg_DSR_t *)eth_drv_dsr, // The logical 
>>>>> driver DSR
>>>>>                             &lan91cxx_interrupt_handle,
>>>>>                             &lan91cxx_interrupt);
>>>>>    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
>>>>> #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
>>>>>    cyg_drv_interrupt_acknowledge(cpd->interrupt);
>>>>>    cyg_drv_interrupt_unmask(cpd->interrupt);
>>>>>
>>>>> And register LAN91C111 driver in my target's 
>>>>> \packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
>>>>> I think this is important so I put on all content.
>>>>> #include <pkgconf/system.h>
>>>>> #include <pkgconf/devs_eth_sh_inserter.h>
>>>>> #include <cyg/hal/hal_intr.h>
>>>>>
>>>>> // MAC address is stored as a Redboot config option
>>>>> #ifdef CYGPKG_REDBOOT
>>>>> #include <pkgconf/redboot.h>
>>>>> #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
>>>>> #include <redboot.h>
>>>>> #include <flash_config.h>
>>>>>
>>>>> #define LAN91CXX_IS_LAN91C111
>>>>>
>>>>> RedBoot_config_option("Network hardware address [MAC]",
>>>>>                      inserter_esa,
>>>>>                      ALWAYS_ENABLED, true,
>>>>>                      CONFIG_ESA, 0
>>>>>    );
>>>>> #endif
>>>>> #endif
>>>>>
>>>>> // ESA address fetch function
>>>>> static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
>>>>> {
>>>>>    // Fetch hardware address from RedBoot config
>>>>> #if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
>>>>> #if defined(CYGPKG_REDBOOT) && \
>>>>>    defined(CYGSEM_REDBOOT_FLASH_CONFIG)
>>>>>    flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
>>>>> #else
>>>>> #error "No RedBoot flash configuration to store ESA"
>>>>> #endif
>>>>> #else
>>>>>    unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
>>>>>    memcpy(cpd->enaddr, static_esa, 6);
>>>>> #endif
>>>>> }
>>>>>
>>>>> static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
>>>>>    config_enaddr : inserter_get_ESA,
>>>>> #ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
>>>>>    enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
>>>>>    hardwired_esa : true,
>>>>> #else
>>>>>    hardwired_esa : false,
>>>>> #endif
>>>>>
>>>>> #if 0
>>>>>   base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
>>>>>   attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
>>>>>   interrupt : SA1110_IRQ_GPIO_ETH
>>>>> #else
>>>>>   base : (unsigned short *) 0xa8000000,
>>>>>   interrupt : 9,
>>>>> #endif
>>>>> };
>>>>>
>>>>> ETH_DRV_SC(lan91cxx_sc,
>>>>>           &lan91cxx_eth0_priv_data,          // Driver specific data
>>>>>           CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
>>>>>           lan91cxx_start,
>>>>>           lan91cxx_stop,
>>>>>           lan91cxx_control,
>>>>>           lan91cxx_can_send,
>>>>>           lan91cxx_send,
>>>>>           lan91cxx_recv,
>>>>>           lan91cxx_deliver,
>>>>>           lan91cxx_poll,
>>>>>           lan91cxx_int_vector
>>>>> );
>>>>>
>>>>> NETDEVTAB_ENTRY(lan91cxx_netdev,
>>>>>                "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
>>>>>                smsc_lan91cxx_init,
>>>>>                &lan91cxx_sc);
>>>>>
>>>>> //EOF devs_eth_inserter.inl
>>>>>
>>>>> I found ETH_DRV_SC definition as below.
>>>>> \packages\io\eth\current\include\eth_drv.h
>>>>> #define 
>>>>> ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) 
>>>>> \
>>>>> static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int 
>>>>> flags); \
>>>>> static void stop(struct eth_drv_sc *sc); \
>>>>> static int  control(struct eth_drv_sc *sc, unsigned long key, void 
>>>>> *data, int data_length); \
>>>>> static int  can_send(struct eth_drv_sc *sc); \
>>>>> static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, 
>>>>> int sg_len, int total, unsigned long key); \
>>>>> static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, 
>>>>> int sg_len); \
>>>>> static void deliver(struct eth_drv_sc *sc); \
>>>>> static void poll(struct eth_drv_sc *sc); \
>>>>> static int  int_vector(struct eth_drv_sc *sc); \
>>>>> static struct eth_hwr_funs sc##_funs = {        \
>>>>>    start,                                      \
>>>>>    stop,                                       \
>>>>>    control,                                    \
>>>>>    can_send,                                   \
>>>>>    send,                                       \
>>>>>    recv,                                       \
>>>>>    deliver,                                    \
>>>>>    poll,                                       \
>>>>>    int_vector,                                 \
>>>>>    &eth_drv_funs,                              \
>>>>>    (struct eth_drv_funs *)0 };                 \
>>>>> struct eth_drv_sc sc = {&sc##_funs, priv, name};
>>>>>
>>>>> I assume this is developed like below,
>>>>> #define 
>>>>> ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) 
>>>>> \
>>>>> static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned 
>>>>> char *enaddr, int flags); \
>>>>> static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
>>>>> static int  lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned 
>>>>> long key, void *data, int data_length); \
>>>>> static int  lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
>>>>> static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct 
>>>>> eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
>>>>> static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct 
>>>>> eth_drv_sg *sg_list, int sg_len); \
>>>>> static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
>>>>> static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
>>>>> static int  lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
>>>>> static struct eth_hwr_funs lan91cxx_sc_funs = {        \
>>>>>    lan91cxx_start,                                      \
>>>>>    lan91cxx_stop,                                       \
>>>>>    lan91cxx_control,                                    \
>>>>>    lan91cxx_can_send,                                   \
>>>>>    lan91cxx_send,                                       \
>>>>>    lan91cxx_recv,                                       \
>>>>>    lan91cxx_deliver,                                    \
>>>>>    lan91cxx_poll,                                       \
>>>>>    lan91cxx_int_vector,                                 \
>>>>>    &eth_drv_funs,                              \
>>>>>    (struct eth_drv_funs *)0 };                 \
>>>>> struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, 
>>>>> &lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};
>>>>>
>>>>> I assume lan91cxx_recv must be called to operate on packets,
>>>>> but it was never called.
>>>>>
>>>>> I traced DSR routine
>>>>> DSR is this
>>>>> \packages\io\eth\current\src\net\eth_drv.c
>>>>> void
>>>>> eth_drv_dsr(cyg_vector_t vector,
>>>>>            cyg_ucount32 count,
>>>>>            cyg_addrword_t data)
>>>>> {
>>>>>    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
>>>>>
>>>>> #ifdef CYGDBG_USE_ASSERTS
>>>>>    // then check that this really is a "sc"
>>>>>    {
>>>>>        cyg_netdevtab_entry_t *t;
>>>>>        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
>>>>>            if ( ((struct eth_drv_sc *)t->device_instance) == sc )
>>>>>                break; // found it
>>>>>        CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to 
>>>>> find sc in NETDEVTAB" );
>>>>>    }
>>>>> #endif // Checking code
>>>>>
>>>>>    sc->state |= ETH_DRV_NEEDS_DELIVERY;
>>>>>
>>>>>    ecos_synch_eth_drv_dsr(); // [request] run delivery function for 
>>>>> this dev
>>>>> }
>>>>>
>>>>> And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
>>>>> void ecos_synch_eth_drv_dsr(void)
>>>>> {
>>>>>    cyg_flag_setbits( &alarm_flag, 2 );
>>>>> }
>>>>>
>>>>> And in \packages\kernel\current\src\common\kapi.cxx
>>>>> void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) 
>>>>> __THROW
>>>>> {
>>>>>    ((Cyg_Flag *)flag)->setbits( value );
>>>>> }
>>>>>
>>>>> And in \packages\kernel\current\src\sync\flag.cxx
>>>>> void
>>>>> Cyg_Flag::setbits( Cyg_FlagValue arg )
>>>>> {
>>>>>    CYG_REPORT_FUNCTION();
>>>>>    CYG_ASSERTCLASS( this, "Bad this pointer");
>>>>>
>>>>>    // Prevent preemption
>>>>>    Cyg_Scheduler::lock();
>>>>>
>>>>>    // OR in the argument to get a new flag value.
>>>>>    value |= arg;
>>>>>
>>>>>    // anyone waiting?
>>>>>    if ( !(queue.empty()) ) {
>>>>>        FlagWaitInfo   *p;
>>>>>        Cyg_Thread     *thread;
>>>>>        Cyg_ThreadQueue holding;
>>>>>
>>>>>        do {
>>>>>            thread = queue.dequeue();
>>>>>            p = (FlagWaitInfo *)(thread->get_wait_info());
>>>>>
>>>>>            CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
>>>>>                        "Both masks set" );
>>>>>            CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );
>>>>>
>>>>>            if ( ((p->allmask != 0) && (p->allmask & value) == 
>>>>> p->allmask) ||
>>>>>                 ((p->anymask & value) != 0 ) ) {
>>>>>                // success!  awaken the thread
>>>>>                thread->set_wake_reason( Cyg_Thread::DONE );
>>>>>                thread->wake();
>>>>>                // return the successful value to it
>>>>>                p->value_out = value;
>>>>>                // do we clear the value; is this the end?
>>>>>                if ( p->do_clear ) {
>>>>>                    // we can break here but need to preserve ordering
>>>>>                    value = 0;
>>>>>                    // so let it cycle the whole queue regardless
>>>>>                }
>>>>>            }
>>>>>            else {
>>>>>                // preserve the entry on the holding queue
>>>>>                holding.enqueue( thread );
>>>>>            }
>>>>>        } while ( !(queue.empty()) );
>>>>>
>>>>>        // Now re-queue the unaffected threads back into the flag queue
>>>>>        while ( !(holding.empty()) ) {
>>>>>            queue.enqueue( holding.dequeue() );
>>>>>        }
>>>>>    }
>>>>>    // Unlock scheduler and allow other threads to run
>>>>>    Cyg_Scheduler::unlock();
>>>>>    CYG_REPORT_RETURN();
>>>>> }
>>>>>
>>>>> Truely,I cannot fathom this coding and
>>>>> I would appreciate if you kindly teach me how lan91cxx_recv is to be 
>>>>> called.
>>>>>
>>>>> Now I describe what I have tampered with in detail,please forgive me 
>>>>> lengthy details.
>>>>> The beginning of the matter is when I ran eCos as it is,I couldn't 
>>>>> make LAN91C111 into LINK State,
>>>>> LINK LED didn't light.So I inserted my own routine in order to operate 
>>>>> LAN91C111 into LINK State in top of
>>>>> \packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function 
>>>>> like below.
>>>>> eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
>>>>> {
>>>>>    // this is my tampered coding
>>>>>    cyg_netdevtab_entry_t *t;
>>>>>
>>>>>    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
>>>>> #ifdef CYGPKG_NET_FREEBSD_STACK
>>>>>    int unit;
>>>>>    char *np, *xp;
>>>>> #endif
>>>>>
>>>>>    // this is my tampered coding
>>>>>    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
>>>>>        log(LOG_INIT, "Init device '%s'\n", t->name);
>>>>>        if (smsc_91c111_init(t)) {             // this is my concocted 
>>>>> routine
>>>>>            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
>>>>>        } else {
>>>>>            // What to do if device init fails?
>>>>>            t->status = 0;  // Device not [currently] available
>>>>>        }
>>>>>    }
>>>>>
>>>>> and in order making LAN91C111 into LINK State it was necessary to use 
>>>>> interrupt so I enabled LAN91C111 interrupt in my concocted routine.
>>>>> Above-mentioned interrupt was caused by my tampered code.At 
>>>>> LINK-established time interrupt happened.
>>>>>
>>>>> On second thought, I realized my tampering was wrong.
>>>>> So I quitted my tampering routine, I returned to eCos original source 
>>>>> and checked why couldn't make LINK LED lighed.
>>>>> I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC 
>>>>> routines).
>>>>>
>>>>> Below is RedBoot output messages log.
>>>>> I breaked lan91cxx_start() but never entered it.
>>>>> I made DEBUG_FUNCTION() available.
>>>>> -- RedBoot output messages log
>>>>> My Flash ID is 4:22f9:0:19
>>>>> eth_drv_init:enaddr=0x8c0005c4
>>>>> Ethernet eth0: MAC address 00:40:31:08:01:00
>>>>> IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
>>>>> Default server: 172.16.1.1
>>>>>
>>>>> RedBoot(tm) bootstrap and debug environment [ROM]
>>>>> Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007
>>>>>
>>>>> Platform: inserter (SH 7709S)
>>>>> Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
>>>>> Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited
>>>>>
>>>>> RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
>>>>> FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
>>>>> == Executing boot script in 3.000 seconds - enter ^C to abort
>>>>> RedBoot> fis load -b 0x8c010000 nc_slave
>>>>> RedBoot> channel 1
>>>>> RedBoot> go 0x8c010000
>>>>> Network stack using 69632 bytes for misc space
>>>>>                    69632 bytes for mbufs
>>>>>                    139264 bytes for mbuf clusters
>>>>> [cyg_net_init] Init: mbinit(0x00000000)
>>>>> [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
>>>>> Init device 'lan91cxx_eth0'
>>>>> smsc_lan91cxx_init
>>>>> LAN91CXX - supposed BankReg @ a800000e = 3302
>>>>> LAN91CXX - type: 9, rev: 1
>>>>> LAN91CXX - status: 0069
>>>>> LAN91CXX - static ESA: 00:40:31:08:01:00
>>>>> [cyg_net_init] Init: loopattach(0x00000000)
>>>>> [cyg_net_init] Init: ifinit(0x00000000)
>>>>> [cyg_net_init] Init: domaininit(0x00000000)
>>>>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
>>>>> New domain internet at 0x00000000
>>>>> [cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
>>>>> New domain route at 0x00000000
>>>>> [cyg_net_init] Init: call_route_init(0x00000000)
>>>>> [cyg_net_init] Done
>>>>> Start Network Characterization - SLAVE
>>>>> No load = 58470
>>>>> Set background load = 20%
>>>>> Set background load = 0%
>>>>> High Load[20] = 37131 => 37%
>>>>> Set background load = 20%
>>>>> Set background load = 0%
>>>>> Load[10] = 47736 => 19%
>>>>> Set background load = 20%
>>>>> Set background load = 0%
>>>>> Final load[10] = 47853 => 19%
>>>>> Start test for eth0
>>>>> -- end of RedBoot output messages log
>>>>>
>>>>> All matters considered,I deduce that 
>>>>> ETH_DRV_SC-table-reference-functions are not working.
>>>>> I cannot understand where and how they are called.
>>>>> Please teach me how to correctly call these functions.
>>>>>
>>>>
>>>>
>>>> -- 
>>>> Before posting, please read the FAQ: 
>>>> http://ecos.sourceware.org/fom/ecos
>>>> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>>>>
>>>>
>>>
>>>
>>> -- 
>>> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
>>> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>>>
>>>
>>
>>
>> -- 
>> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
>> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>>
>>
>
>
> -- 
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>
> 


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [ECOS] Not enter VSR routine when lan91cxx_start executed
  2007-10-02  7:08         ` ariga masahiro
  2007-10-02 10:45           ` ariga masahiro
@ 2007-10-11  9:01           ` ariga masahiro
  1 sibling, 0 replies; 8+ messages in thread
From: ariga masahiro @ 2007-10-11  9:01 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss

Hello,

Since I enabled next option,
CYGHWR_NET_DRIVER_ETH0_ADDRS
lan91cxx driver began to work.

But when lan91cxx_start routine is ececuted,
although IRQ-3 line(=ethernet interrupt signal) is asserted,
it looks like not entering into cyg_hal_default_interrupt_vsr(SH VSR 
routine).
On the other hand Timer interrupts are entering into that routine.

Why this happens ?
Do I need to set any options ?

Please help me if you know the reason.

Masahiro Ariga




-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-10-11  9:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-28 10:06 [ECOS] Question about interrupt trigger mode ariga masahiro
2007-10-01  5:01 ` [ECOS] Not working lan91cxx_sc drv ariga masahiro
2007-10-02  1:18   ` ariga masahiro
2007-10-02  4:46     ` ariga masahiro
2007-10-02  5:27       ` ariga masahiro
2007-10-02  7:08         ` ariga masahiro
2007-10-02 10:45           ` ariga masahiro
2007-10-11  9:01           ` [ECOS] Not enter VSR routine when lan91cxx_start executed ariga masahiro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).