Unable to open() a resource manager from my driver

I wrote a custom device driver (a PRODUCER_UP) which needs to open() another
device ( I call this device /dev/phy) and invoke devctl() on /dev/phy in
order to send packets over the physical layer. The driver receives an error
when it tries to open /dev/phy (which is written as a resource manager and
supports devctl() ). The error it receives on open() is 3 which says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client is able
to open() the device. I can also see the device name when i type “ls /dev”

While searching on google for similar type issues, I saw a post by someone
who wrote a custom “ethernet like” driver under QNX that used serial ports
below it to transmit/receive data. This post included the code for the
driver and it invoked several open() calls to the serial port drivers from
within his device driver. So I am a bit puzzled. What is it that I am
doing wrong here?

  • Murtaza

My guess is you didn’t specify _RESMGR_FLAG_SELF to resmgr_attach() ?

-seanb

Murtaza <murti@yahoo.com> wrote:

I wrote a custom device driver (a PRODUCER_UP) which needs to open() another
device ( I call this device /dev/phy) and invoke devctl() on /dev/phy in
order to send packets over the physical layer. The driver receives an error
when it tries to open /dev/phy (which is written as a resource manager and
supports devctl() ). The error it receives on open() is 3 which says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client is able
to open() the device. I can also see the device name when i type “ls /dev”

While searching on google for similar type issues, I saw a post by someone
who wrote a custom “ethernet like” driver under QNX that used serial ports
below it to transmit/receive data. This post included the code for the
driver and it invoked several open() calls to the serial port drivers from
within his device driver. So I am a bit puzzled. What is it that I am
doing wrong here?

  • Murtaza

I added this flag in the resmgr_attach() of the /dev/phy code but I still
get the same problem. I am doing the open() after I register the producer
with io-net. I have also tried moving the open() call to other places i.e.:
before the device registration and immediately after the Init is called but
no luck.

  • Murtaza

“Sean Boudreau” <seanb@node25.ott.qnx.com> wrote in message
news:b2h2b7$59s$1@nntp.qnx.com

My guess is you didn’t specify _RESMGR_FLAG_SELF to resmgr_attach() ?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to open()
another
device ( I call this device /dev/phy) and invoke devctl() on /dev/phy in
order to send packets over the physical layer. The driver receives an
error
when it tries to open /dev/phy (which is written as a resource manager
and
supports devctl() ). The error it receives on open() is 3 which says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client is
able
to open() the device. I can also see the device name when i type “ls
/dev”

While searching on google for similar type issues, I saw a post by
someone
who wrote a custom “ethernet like” driver under QNX that used serial
ports
below it to transmit/receive data. This post included the code for the
driver and it invoked several open() calls to the serial port drivers
from
within his device driver. So I am a bit puzzled. What is it that I am
doing wrong here?

  • Murtaza

Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
can indicate the manager went away unexpectedly. Are there any
core files in /var/dumps?

A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
force a stat().

-seanb

Murtaza <murti@yahoo.com> wrote:

I added this flag in the resmgr_attach() of the /dev/phy code but I still
get the same problem. I am doing the open() after I register the producer
with io-net. I have also tried moving the open() call to other places i.e.:
before the device registration and immediately after the Init is called but
no luck.

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2h2b7$59s$> 1@nntp.qnx.com> …

My guess is you didn’t specify _RESMGR_FLAG_SELF to resmgr_attach() ?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to open()
another
device ( I call this device /dev/phy) and invoke devctl() on /dev/phy in
order to send packets over the physical layer. The driver receives an
error
when it tries to open /dev/phy (which is written as a resource manager
and
supports devctl() ). The error it receives on open() is 3 which says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client is
able
to open() the device. I can also see the device name when i type “ls
/dev”

While searching on google for similar type issues, I saw a post by
someone
who wrote a custom “ethernet like” driver under QNX that used serial
ports
below it to transmit/receive data. This post included the code for the
driver and it invoked several open() calls to the serial port drivers
from
within his device driver. So I am a bit puzzled. What is it that I am
doing wrong here?

  • Murtaza

/dev/phy is a seperate application written as a resource manager and runs
itself as a seperate process. Its not a shared object mounted within the
io-net framework. I can open() /dev/phy using a test client I wrote for it
but trying to open() it from the network driver fails. I’ve also tried
“ls -l” on /dev and I can see the device name. Its listed as follows:

nrw-rw-rw- 1 root 1 0 Jan 01 00:09 phy#

I dont know the significance of “#” next to the name.

Thanks

  • Murtaza

“Sean Boudreau” <seanb@node25.ott.qnx.com> wrote in message
news:b2j0kp$dp2$1@nntp.qnx.com

Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
can indicate the manager went away unexpectedly. Are there any
core files in /var/dumps?

A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
force a stat().

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I added this flag in the resmgr_attach() of the /dev/phy code but I
still
get the same problem. I am doing the open() after I register the
producer
with io-net. I have also tried moving the open() call to other places
i.e.:
before the device registration and immediately after the Init is called
but
no luck.

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2h2b7$59s$> 1@nntp.qnx.com> …

My guess is you didn’t specify _RESMGR_FLAG_SELF to resmgr_attach() ?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to open()
another
device ( I call this device /dev/phy) and invoke devctl() on /dev/phy
in
order to send packets over the physical layer. The driver receives
an
error
when it tries to open /dev/phy (which is written as a resource
manager
and
supports devctl() ). The error it receives on open() is 3 which says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client is
able
to open() the device. I can also see the device name when i type “ls
/dev”

While searching on google for similar type issues, I saw a post by
someone
who wrote a custom “ethernet like” driver under QNX that used serial
ports
below it to transmit/receive data. This post included the code for
the
driver and it invoked several open() calls to the serial port drivers
from
within his device driver. So I am a bit puzzled. What is it that I
am
doing wrong here?

  • Murtaza

    \

Dunno then, but I suspect the /dev/phy manager. Did you check /var/dumps?
Do other opens succeed? The stack can open /dev/slog, /dev/random for
example and they work…

-seanb

Murtaza <murti@yahoo.com> wrote:

/dev/phy is a seperate application written as a resource manager and runs
itself as a seperate process. Its not a shared object mounted within the
io-net framework. I can open() /dev/phy using a test client I wrote for it
but trying to open() it from the network driver fails. I’ve also tried
“ls -l” on /dev and I can see the device name. Its listed as follows:

nrw-rw-rw- 1 root 1 0 Jan 01 00:09 phy#

I dont know the significance of “#” next to the name.

Thanks

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2j0kp$dp2$> 1@nntp.qnx.com> …
Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
can indicate the manager went away unexpectedly. Are there any
core files in /var/dumps?

A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
force a stat().

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I added this flag in the resmgr_attach() of the /dev/phy code but I
still
get the same problem. I am doing the open() after I register the
producer
with io-net. I have also tried moving the open() call to other places
i.e.:
before the device registration and immediately after the Init is called
but
no luck.

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2h2b7$59s$> 1@nntp.qnx.com> …

My guess is you didn’t specify _RESMGR_FLAG_SELF to resmgr_attach() ?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to open()
another
device ( I call this device /dev/phy) and invoke devctl() on /dev/phy
in
order to send packets over the physical layer. The driver receives
an
error
when it tries to open /dev/phy (which is written as a resource
manager
and
supports devctl() ). The error it receives on open() is 3 which says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client is
able
to open() the device. I can also see the device name when i type “ls
/dev”

While searching on google for similar type issues, I saw a post by
someone
who wrote a custom “ethernet like” driver under QNX that used serial
ports
below it to transmit/receive data. This post included the code for
the
driver and it invoked several open() calls to the serial port drivers
from
within his device driver. So I am a bit puzzled. What is it that I
am
doing wrong here?

  • Murtaza

    \

Murtaza <murti@yahoo.com> wrote:

/dev/phy is a seperate application written as a resource manager and runs
itself as a seperate process. Its not a shared object mounted within the
io-net framework. I can open() /dev/phy using a test client I wrote for it
but trying to open() it from the network driver fails. I’ve also tried
“ls -l” on /dev and I can see the device name. Its listed as follows:

I know nothing about the ddk network stuff; but what is the errno
from the open()? Have you tried opening other things, like “/tmp/spud”
for write? Does that work?

nrw-rw-rw- 1 root 1 0 Jan 01 00:09 phy#

I dont know the significance of “#” next to the name.

It means “named special device”, as indicated by the “n” in the mode…

Cheers,
-RK

Thanks

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2j0kp$dp2$> 1@nntp.qnx.com> …
Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
can indicate the manager went away unexpectedly. Are there any
core files in /var/dumps?

A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
force a stat().

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I added this flag in the resmgr_attach() of the /dev/phy code but I
still
get the same problem. I am doing the open() after I register the
producer
with io-net. I have also tried moving the open() call to other places
i.e.:
before the device registration and immediately after the Init is called
but
no luck.

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2h2b7$59s$> 1@nntp.qnx.com> …

My guess is you didn’t specify _RESMGR_FLAG_SELF to resmgr_attach() ?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to open()
another
device ( I call this device /dev/phy) and invoke devctl() on /dev/phy
in
order to send packets over the physical layer. The driver receives
an
error
when it tries to open /dev/phy (which is written as a resource
manager
and
supports devctl() ). The error it receives on open() is 3 which says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client is
able
to open() the device. I can also see the device name when i type “ls
/dev”

While searching on google for similar type issues, I saw a post by
someone
who wrote a custom “ethernet like” driver under QNX that used serial
ports
below it to transmit/receive data. This post included the code for
the
driver and it invoked several open() calls to the serial port drivers
from
within his device driver. So I am a bit puzzled. What is it that I
am
doing wrong here?

  • Murtaza


    \


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

I tried to open() all kinds of devices but they all fail. I even tried
/dev/null and it fails too. The errno I get is ESRCH (errno #3 which means
no such process). At first I was loading another io-net process for this
driver so I decided to use mount instead but that doesn’t help either.

Sean, the resource manager code for /dev/phy is a cut-and-paste of the
single threaded device resource example from
http://www.qnx.com/developer/docs/qnx_6.1_docs/neutrino/prog/resmgr.html.
The only thing I added was my own custom devctl and I added the flag
_RESMGR_FLAG_SELF to resmgr_attach() per your recommendation.

  • Murtaza

“Robert Krten” <nospam84@parse.com> wrote in message
news:b2j3rh$hgi$1@inn.qnx.com

Murtaza <> murti@yahoo.com> > wrote:
/dev/phy is a seperate application written as a resource manager and
runs
itself as a seperate process. Its not a shared object mounted within
the
io-net framework. I can open() /dev/phy using a test client I wrote for
it
but trying to open() it from the network driver fails. I’ve also tried
“ls -l” on /dev and I can see the device name. Its listed as follows:

I know nothing about the ddk network stuff; but what is the errno
from the open()? Have you tried opening other things, like “/tmp/spud”
for write? Does that work?

nrw-rw-rw- 1 root 1 0 Jan 01 00:09 phy#

I dont know the significance of “#” next to the name.

It means “named special device”, as indicated by the “n” in the mode…

Cheers,
-RK

Thanks

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2j0kp$dp2$> 1@nntp.qnx.com> …
Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
can indicate the manager went away unexpectedly. Are there any
core files in /var/dumps?

A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
force a stat().

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I added this flag in the resmgr_attach() of the /dev/phy code but I
still
get the same problem. I am doing the open() after I register the
producer
with io-net. I have also tried moving the open() call to other
places
i.e.:
before the device registration and immediately after the Init is
called
but
no luck.

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2h2b7$59s$> 1@nntp.qnx.com> …

My guess is you didn’t specify _RESMGR_FLAG_SELF to resmgr_attach()
?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to
open()
another
device ( I call this device /dev/phy) and invoke devctl() on
/dev/phy
in
order to send packets over the physical layer. The driver
receives
an
error
when it tries to open /dev/phy (which is written as a resource
manager
and
supports devctl() ). The error it receives on open() is 3 which
says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the client
is
able
to open() the device. I can also see the device name when i type
“ls
/dev”

While searching on google for similar type issues, I saw a post by
someone
who wrote a custom “ethernet like” driver under QNX that used
serial
ports
below it to transmit/receive data. This post included the code
for
the
driver and it invoked several open() calls to the serial port
drivers
from
within his device driver. So I am a bit puzzled. What is it that
I
am
doing wrong here?

  • Murtaza









    Robert Krten, PARSE Software Devices +1 613 599 8316.
    Realtime Systems Architecture, Books, Video-based and Instructor-led
    Training and Consulting at > www.parse.com> .
    Email my initials at parse dot com.

Could you post your working code and your failing (resmgr) code?

dB

“Murtaza” <murti@yahoo.com> wrote in message
news:b2jre9$d69$1@inn.qnx.com

I tried to open() all kinds of devices but they all fail. I even tried
/dev/null and it fails too. The errno I get is ESRCH (errno #3 which
means
no such process). At first I was loading another io-net process for this
driver so I decided to use mount instead but that doesn’t help either.

Sean, the resource manager code for /dev/phy is a cut-and-paste of the
single threaded device resource example from
http://www.qnx.com/developer/docs/qnx_6.1_docs/neutrino/prog/resmgr.html> .
The only thing I added was my own custom devctl and I added the flag
_RESMGR_FLAG_SELF to resmgr_attach() per your recommendation.

  • Murtaza

“Robert Krten” <> nospam84@parse.com> > wrote in message
news:b2j3rh$hgi$> 1@inn.qnx.com> …
Murtaza <> murti@yahoo.com> > wrote:
/dev/phy is a seperate application written as a resource manager and
runs
itself as a seperate process. Its not a shared object mounted within
the
io-net framework. I can open() /dev/phy using a test client I wrote
for
it
but trying to open() it from the network driver fails. I’ve also
tried
“ls -l” on /dev and I can see the device name. Its listed as follows:

I know nothing about the ddk network stuff; but what is the errno
from the open()? Have you tried opening other things, like “/tmp/spud”
for write? Does that work?

nrw-rw-rw- 1 root 1 0 Jan 01 00:09 phy#

I dont know the significance of “#” next to the name.

It means “named special device”, as indicated by the “n” in the mode…

Cheers,
-RK

Thanks

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2j0kp$dp2$> 1@nntp.qnx.com> …
Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
can indicate the manager went away unexpectedly. Are there any
core files in /var/dumps?

A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
force a stat().

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I added this flag in the resmgr_attach() of the /dev/phy code but I
still
get the same problem. I am doing the open() after I register the
producer
with io-net. I have also tried moving the open() call to other
places
i.e.:
before the device registration and immediately after the Init is
called
but
no luck.

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2h2b7$59s$> 1@nntp.qnx.com> …

My guess is you didn’t specify _RESMGR_FLAG_SELF to
resmgr_attach()
?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to
open()
another
device ( I call this device /dev/phy) and invoke devctl() on
/dev/phy
in
order to send packets over the physical layer. The driver
receives
an
error
when it tries to open /dev/phy (which is written as a resource
manager
and
supports devctl() ). The error it receives on open() is 3 which
says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the
client
is
able
to open() the device. I can also see the device name when i
type
“ls
/dev”

While searching on google for similar type issues, I saw a post
by
someone
who wrote a custom “ethernet like” driver under QNX that used
serial
ports
below it to transmit/receive data. This post included the code
for
the
driver and it invoked several open() calls to the serial port
drivers
from
within his device driver. So I am a bit puzzled. What is it
that
I
am
doing wrong here?

  • Murtaza









    Robert Krten, PARSE Software Devices +1 613 599 8316.
    Realtime Systems Architecture, Books, Video-based and Instructor-led
    Training and Consulting at > www.parse.com> .
    Email my initials at parse dot com.

And the open() call.

-seanb

David Bacon <dbacon@qnx.com> wrote:

Could you post your working code and your failing (resmgr) code?

dB

“Murtaza” <> murti@yahoo.com> > wrote in message
news:b2jre9$d69$> 1@inn.qnx.com> …
I tried to open() all kinds of devices but they all fail. I even tried
/dev/null and it fails too. The errno I get is ESRCH (errno #3 which
means
no such process). At first I was loading another io-net process for this
driver so I decided to use mount instead but that doesn’t help either.

Sean, the resource manager code for /dev/phy is a cut-and-paste of the
single threaded device resource example from
http://www.qnx.com/developer/docs/qnx_6.1_docs/neutrino/prog/resmgr.html> .
The only thing I added was my own custom devctl and I added the flag
_RESMGR_FLAG_SELF to resmgr_attach() per your recommendation.

  • Murtaza

“Robert Krten” <> nospam84@parse.com> > wrote in message
news:b2j3rh$hgi$> 1@inn.qnx.com> …
Murtaza <> murti@yahoo.com> > wrote:
/dev/phy is a seperate application written as a resource manager and
runs
itself as a seperate process. Its not a shared object mounted within
the
io-net framework. I can open() /dev/phy using a test client I wrote
for
it
but trying to open() it from the network driver fails. I’ve also
tried
“ls -l” on /dev and I can see the device name. Its listed as follows:

I know nothing about the ddk network stuff; but what is the errno
from the open()? Have you tried opening other things, like “/tmp/spud”
for write? Does that work?

nrw-rw-rw- 1 root 1 0 Jan 01 00:09 phy#

I dont know the significance of “#” next to the name.

It means “named special device”, as indicated by the “n” in the mode…

Cheers,
-RK

Thanks

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2j0kp$dp2$> 1@nntp.qnx.com> …
Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
can indicate the manager went away unexpectedly. Are there any
core files in /var/dumps?

A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
force a stat().

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I added this flag in the resmgr_attach() of the /dev/phy code but I
still
get the same problem. I am doing the open() after I register the
producer
with io-net. I have also tried moving the open() call to other
places
i.e.:
before the device registration and immediately after the Init is
called
but
no luck.

  • Murtaza

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:b2h2b7$59s$> 1@nntp.qnx.com> …

My guess is you didn’t specify _RESMGR_FLAG_SELF to
resmgr_attach()
?

-seanb

Murtaza <> murti@yahoo.com> > wrote:
I wrote a custom device driver (a PRODUCER_UP) which needs to
open()
another
device ( I call this device /dev/phy) and invoke devctl() on
/dev/phy
in
order to send packets over the physical layer. The driver
receives
an
error
when it tries to open /dev/phy (which is written as a resource
manager
and
supports devctl() ). The error it receives on open() is 3 which
says
/dev/phy does not exist.

At the same time, I run my test client for /dev/phy and the
client
is
able
to open() the device. I can also see the device name when i
type
“ls
/dev”

While searching on google for similar type issues, I saw a post
by
someone
who wrote a custom “ethernet like” driver under QNX that used
serial
ports
below it to transmit/receive data. This post included the code
for
the
driver and it invoked several open() calls to the serial port
drivers
from
within his device driver. So I am a bit puzzled. What is it
that
I
am
doing wrong here?

  • Murtaza









    Robert Krten, PARSE Software Devices +1 613 599 8316.
    Realtime Systems Architecture, Books, Video-based and Instructor-led
    Training and Consulting at > www.parse.com> .
    Email my initials at parse dot com.

Below are two pieces of code 1) code for /dev/phy, 2) code for “phytest”, a
test client for /dev/phy that succesfully works

  • /dev/phy is a dummy physical layer emulator that simply provides a
    loopback facility. It will receive packets from the client via devctl(),
    store them internally and send a pulse to the client, and hand the packet
    back to the client when the client issues a receive request. Its purely
    written for testing purpose. Eventually something more “concrete” will
    replace its place.

  • phytest simply open() /dev/phy, sends a packet to it, waits for a pulse,
    and receives the packet back

/* phy

  • Description:
  • A dummy physical layer that provides loopback facility for our driver

*/

#include <sys/iofunc.h>
#include <sys/dispatch.h>

#include “common.h”

#define QUEUE_SIZE 25
#define VACANT 0
#define OCCUPIED 1


typedef struct TAG_DATA
{
char buf[PACKET_SIZE];
int bufSize;
int status;

} PACKET_QUEUE;

// Globals
static PACKET_QUEUE pktQueue[QUEUE_SIZE];
struct EVENT_STRUCT Event;

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

int Devctl(resmgr_context_t *ctp, io_devctl_t *msg, RESMGR_OCB_T *ocb);

int HandleIOMessage(void *UsrOcb,int UsrRxChannel, int MsgCode, void
*MsgData,
int *MsgSize, int *RetStatus);

int main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id, ret;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr, “%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

// Initialize packet queue
memset((char *) &pktQueue, 0, sizeof(pktQueue));

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

io_funcs.devctl = Devctl; // For handling _IO_DEVCTL, sent by devctl()

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

/* attach our device name /
id = resmgr_attach(dpp, /
dispatch handle /
&resmgr_attr, /
resource manager attrs /
“/dev/phy”, /
device name /
_FTYPE_ANY, /
open type /
_RESMGR_FLAG_SELF, /
flags
/
&connect_funcs, /
connect routines /
&io_funcs, /
I/O routines /
&attr); /
handle */
if(id == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1)
{
if((ctp = dispatch_block(ctp)) == NULL)
{
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}

dispatch_handler(ctp);
}

return SUCCESS;
}

int Devctl(resmgr_context_t *ctp, io_devctl_t *msg, RESMGR_OCB_T *ocb)
{

void *Data = NULL;
int nbytes, ret_status, ret;
struct sigaction action;

if ((ret = iofunc_devctl_default(ctp, msg, ocb)) != _RESMGR_DEFAULT)
{
return(ret);
}

(void *) Data = _DEVCTL_DATA(msg->i);

ret = HandleIOMessage(ocb, ctp->rcvid, msg->i.dcmd, Data, &nbytes, &ret_
status);

if (ret != SUCCESS)
{
return(ret);
}

memset(&msg->o, 0, sizeof(msg->o));
msg->o.ret_val = ret_status;
msg->o.nbytes = nbytes;

return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + nbytes));

}

int HandleIOMessage(void *UsrOcb,int UsrRxChannel, int MsgCode, void
*MsgData,
int *MsgSize, int *RetStatus)
{
int i, ret = SUCCESS, placeHolderFound, packetFound;
DEVCTL_MESSAGE *Msg = NULL;
DEVCTL_PULSE_MESSAGE *PulseCode = NULL;
char reply_buf[100];
iov_t send, reply;
int PACKET_RECEIVE_CMD = PHY_PACKET_RECEIVE;

*RetStatus = SUCCESS;

switch (MsgCode)
{
case DEVCTL_PULSE_CODE:
{

PulseCode = ( DEVCTL_PULSE_MESSAGE *) MsgData;

Event.Channel = UsrRxChannel;
Event.Connection = PulseCode->connectionId;

*MsgSize = 0;
}
break;

case DEVCTL_PACKET_TRANSMIT:
{
Msg = ( DEVCTL_MESSAGE *) MsgData;
placeHolderFound = 0;

for (i=0;i<QUEUE_SIZE;i++)
{
if (pktQueue_.status == VACANT)
{

placeHolderFound = 1;

memset((char ) &pktQueue.buf, 0,
(sizeof(char)PACKET_SIZE));

memcpy((char ) &pktQueue.buf, (char ) Msg->buf,
(sizeof(char)PACKET_SIZE));

pktQueue.bufSize = Msg->bufSize;

pktQueue.status = OCCUPIED;
printf(“Phy: Event->Channel = %x Event->Connection =
%x\n”, Event.Channel, Event.Connection);
if( (fddDeliverEvent (Event.Channel, Event.Connection,
PHY_PACKET_RECEIVE, 0)) != SUCCESS)
{
printf(“Failed to deliver event to client\n”);
}

break;
}
}

MsgSize = 0;

if (placeHolderFound == 0)
{
ret = PHY_QUEUE_FULL;
}
}
break;

case DEVCTL_PACKET_RECEIVE:
{
Msg = ( DEVCTL_MESSAGE ) MsgData;

packetFound = 0;

for (i=0;i<QUEUE_SIZE;i++)
{
if (pktQueue.status == OCCUPIED)
{

packetFound = 1;

memset((char ) Msg->buf, 0,
(sizeof(char)PACKET_SIZE));

memcpy( (char ) Msg->buf, (char ) &pktQueue.buf,
pktQueue.bufSize);

Msg->bufSize = pktQueue.bufSize;

pktQueue.status = VACANT;

MsgSize = sizeof(pktQueue[i].buf) +
sizeof(pktQueue[i].bufSize);

break;
}
}

if(packetFound == 0)
{
ret= PHY_QUEUE_EMPTY;
MsgSize = 0;
}

}

break;

default:
{
ret=PHY_INVALID_COMMAND;
MsgSize = 0;
}
break;
}

return ret;

} // end HandleIOMessage

/
************ End of /dev/phy
**********************************/

// Code for a test client that works with /dev/phy

/
phytest

  • Description:
  • Program to test phy.c (The physical layer emulation)

*/

#include “common.h”

char data[] = “This is a test packet!”;

FDD_EVENT Event = {0};

void main()
{
int dh, ret, dev_ret;
DEVCTL_MESSAGE packet;
DEVCTL_PULSE_MESSAGE Pulse;

if ((dh = open("/dev/phy", O_RDWR)) == -1)
{
printf(“Can’t open the device\n”);
return;
}

// Create and connect a channel for notifications

if ((fddCreateEvent(&Event)) != SUCCESS)
{
printf(“Unable to create and attach a channel\n”);
return;
}

printf(“Event->Channel = %x Event->Connection = %x\n”, Event->Channel,

Event->Connection);

Pulse.connectionId = Event->Connection;

ret = devctl(dh, DEVCTL_PULSE_CODE, &Pulse, sizeof(Pulse), &dev_ret);

if(ret != SUCCESS)
{
printf(“Can’t send channel Id. Ret code = %x\n”, ret);
return;
}

memset((char ) &packet, 0, sizeof(packet));
memcpy((char
) &packet.buf, (char *) &data, sizeof(data));

packet.bufSize = sizeof(data);

printf(“Packet Before: %s\n”, packet.buf);

// Send a packet to the phy layer
ret = devctl(dh, DEVCTL_PACKET_TRANSMIT, &packet, sizeof(packet),
&dev_ret);

if(ret != SUCCESS)
{
printf(“Can’t send packet. Ret code = %x\n”, ret);
return;
}


// Lets wait for our pulse
printf(“Waiting for pulse…\n”);
ret = fddWaitOnEvent(Event, 0, FDD_TIMEOUT_INFINITE);

printf(“Got pulse: code = %x\n”, Event->EventCode);

if(Event->EventCode == PHY_PACKET_RECEIVE)
{

memset((char *) &packet, 0, sizeof(packet));

// Receive a packet back from the phy layer
ret = devctl(dh, DEVCTL_PACKET_RECEIVE, &packet, sizeof(packet),
&dev_ret);

if(dev_ret != SUCCESS)
{
printf(“Can’t receive the packet\n”);
return;
}

printf(“Got Packet!. Packet Size = %d. Packet says-> %s\n”,
packet.bufSize,

packet.buf);
fflush(stdout);
}

fddDestroyEvent(Event);

close(dh);
}


“Sean Boudreau” <seanb@node25.ott.qnx.com> wrote in message
news:b2l4e4$q1v$1@nntp.qnx.com…_

_And the open() call.

-seanb

David Bacon <> dbacon@qnx.com> > wrote:
Could you post your working code and your failing (resmgr) code?

dB

“Murtaza” <> murti@yahoo.com> > wrote in message
news:b2jre9$d69$> 1@inn.qnx.com> …
I tried to open() all kinds of devices but they all fail. I even tried
/dev/null and it fails too. The errno I get is ESRCH (errno #3 which
means
no such process). At first I was loading another io-net process for
this
driver so I decided to use mount instead but that doesn’t help either.

Sean, the resource manager code for /dev/phy is a cut-and-paste of the
single threaded device resource example from

http://www.qnx.com/developer/docs/qnx_6.1_docs/neutrino/prog/resmgr.html> .
The only thing I added was my own custom devctl and I added the flag
_RESMGR_FLAG_SELF to resmgr_attach() per your recommendation.
\

  • Murtaza

    “Robert Krten” <> nospam84@parse.com> > wrote in message
    news:b2j3rh$hgi$> 1@inn.qnx.com> …
    Murtaza <> murti@yahoo.com> > wrote:
    /dev/phy is a seperate application written as a resource manager
    and
    runs
    itself as a seperate process. Its not a shared object mounted
    within
    the
    io-net framework. I can open() /dev/phy using a test client I
    wrote
    for
    it
    but trying to open() it from the network driver fails. I’ve also
    tried
    “ls -l” on /dev and I can see the device name. Its listed as
    follows:

    I know nothing about the ddk network stuff; but what is the errno
    from the open()? Have you tried opening other things, like
    “/tmp/spud”
    for write? Does that work?

    nrw-rw-rw- 1 root 1 0 Jan 01 00:09 phy#

    I dont know the significance of “#” next to the name.

    It means “named special device”, as indicated by the “n” in the
    mode…

    Cheers,
    -RK

    Thanks
    \
  • Murtaza

    “Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
    news:b2j0kp$dp2$> 1@nntp.qnx.com> …
    Is the /dev/phy manager outside of io-net? errno 3 is ESRCH which
    can indicate the manager went away unexpectedly. Are there any
    core files in /var/dumps?

    A straight ‘ls’ won’t actually query the manager. Try ‘ls -l’ to
    force a stat().

    -seanb

    Murtaza <> murti@yahoo.com> > wrote:
    I added this flag in the resmgr_attach() of the /dev/phy code
    but I
    still
    get the same problem. I am doing the open() after I register
    the
    producer
    with io-net. I have also tried moving the open() call to other
    places
    i.e.:
    before the device registration and immediately after the Init is
    called
    but
    no luck.
    \
  • Murtaza

    “Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
    news:b2h2b7$59s$> 1@nntp.qnx.com> …

    My guess is you didn’t specify _RESMGR_FLAG_SELF to
    resmgr_attach()
    ?

    -seanb

    Murtaza <> murti@yahoo.com> > wrote:
    I wrote a custom device driver (a PRODUCER_UP) which needs to
    open()
    another
    device ( I call this device /dev/phy) and invoke devctl() on
    /dev/phy
    in
    order to send packets over the physical layer. The driver
    receives
    an
    error
    when it tries to open /dev/phy (which is written as a
    resource
    manager
    and
    supports devctl() ). The error it receives on open() is 3
    which
    says
    /dev/phy does not exist.

    At the same time, I run my test client for /dev/phy and the
    client
    is
    able
    to open() the device. I can also see the device name when i
    type
    “ls
    /dev”

    While searching on google for similar type issues, I saw a
    post
    by
    someone
    who wrote a custom “ethernet like” driver under QNX that used
    serial
    ports
    below it to transmit/receive data. This post included the
    code
    for
    the
    driver and it invoked several open() calls to the serial port
    drivers
    from
    within his device driver. So I am a bit puzzled. What is it
    that
    I
    am
    doing wrong here?
    \
  • Murtaza









    Robert Krten, PARSE Software Devices +1 613 599 8316.
    Realtime Systems Architecture, Books, Video-based and Instructor-led
    Training and Consulting at > www.parse.com> .
    Email my initials at parse dot com._

Below is the code for my custom device driver “bdd” where the open() call to
/dev/phy fails with errno 3.

bdd registers both an UP producer and a converter. Its a custom driver of
type “bd”. The call to open() /dev/phy takes place in the
bdd_RegisterDevice() routine. I call the open() to /dev/phy after I spawn a
receive thread for the device and register the device with io-net.

I very much appreciate your help in looking over this. Thanks!

  • Murtaza

/*

  • bdd
  • Description: A custom network device driver of type “bd” that
    sends/receives IP
  • packets via another device driver.
  • This code registers both the UP Producer and a pass-thru Converter

*/

// io-net functions used in the code.
#define ionetRxPackets ext->ion->tx_up_start
#define ionetRegister ext->ion->reg
#define ionetDeregister ext->ion->dereg
#define ionetAlloc ext->ion->alloc
#define ionetFree ext->ion->free
#define ionetAllocNpkt ext->ion->alloc_up_npkt
#define ionetMphys ext->ion->mphys
#define ionetTxComplete ext->ion->tx_done
#define ionetDevctl ext->ion->devctl

// Drvr entry
io_net_dll_entry_t io_net_dll_entry = {
2,
bdd_Init,
NULL
};

// Functions associated with our UP producer
io_net_registrant_funcs_t bddFuncs = {
_IO_NET_REG_NFUNCS,
NULL,
bdd_Transmit,
bdd_ReceiveComplete,
bdd_Shutdown1,
bdd_Shutdown2,
bdd_Advertise,
bdd_Devctl,
bdd_FlushTxQueue,
NULL,
};

// UP Producer register entry
io_net_registrant_t bddEntry = {
_REG_PRODUCER_UP,
“devn-bdd.so”,
“bd”,
NULL,
NULL,
&bddFuncs,
0
};

// Functions associated with our ip-bd converter
// Notice: I am using some of UP producer functions here
// so the IP stack can transmit packets directly to the UP producer
// and bypass the converter

io_net_registrant_funcs_t bdcFuncs = {
_IO_NET_REG_NFUNCS, // nfuncs,
bdc_RxUp,
bdd_Transmit,
bdd_ReceiveComplete,
bdc_Shutdown1,
bdc_Shutdown2,
NULL,
NULL,
NULL,
NULL,
};

// Converter register entry
io_net_registrant_t bdcEntry = {
_REG_CONVERTOR,
“devn-bdd.so”,
“ip”,
“bd”,
NULL,
&bdcFuncs,
0,
};

/*

  • bdd_Init() – Our DLL entry point.

*/

int bdd_Init(void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char
*options)
{
int ret;

dpp = dpp;

if ((ret = bdd_Detect(dll_hdl, ion, options)) != SUCCESS)
{
errno = ret;
return FAILURE;
}

return SUCCESS;
}

/*

  • bdd_Detect – Detect device interfaces and register them with io-net

*/

int bdd_Detect( void *dll_hdl, io_net_self_t *ion, char *options )
{
int iface, totalInterfaces = 1; //hardcoded to 1 for testing
Nic_t *nic = NULL, *conv_nic = NULL;
BDD_EXT *ext = NULL;
int reg_convhdl;
uint16_t lan;

// Some prints for debugging
fprintf(stderr, “bdd: Detect\n”);

// Parse command line args
//TODO: Code missing

// First and foremost, create a device
//and register our custom converter with io-net

fflush(stdout);

if ((conv_nic = nic_create_dev(sizeof (BDD_EXT))) == NULL)
{
return ENODEV;
}

ext = (BDD_EXT *)(conv_nic->ext);

memset((char *) ext, 0, sizeof(BDD_EXT));

ext->ion = ion;
ext->dll_hdl = dll_hdl;
ext->verbose = 1; // temp verbose

bdcEntry.func_hdl = (void *) conv_nic;

if ((ion->reg(dll_hdl, &bdcEntry, &ext->reg_convhdl, &ext->cell, &lan))
!= SUCCESS)
{

fprintf(stderr, “bdd: Unable to register the converter with
io-net\n”);
return FAILURE;
}

conv_nic->lan = lan;

reg_convhdl = ext->reg_convhdl;

for (iface = 0;iface < totalBackhaulInterfaces; iface++)
{
// For each interface, do the following…

// Create a device structure and initialize it
if ((nic = nic_create_dev(sizeof (BDD_EXT))) == NULL)
{

return ENODEV;
}

ext = (BDD_EXT *)(nic->ext);

memset((char *) ext, 0, sizeof(BDD_EXT));

ext->ion = ion;
ext->dll_hdl = dll_hdl;
ext->reg_convhdl = reg_convhdl;
ext->verbose = 1; // temp verbose

// Register device to io-net and spawn an event thread

if ((bdd_RegisterDevice(nic, ion, dll_hdl)) != SUCCESS)
{
return FAILURE;
}

// Advertise the device
bdd_Advertise(ext->reg_hdl, nic);
}

return SUCCESS;
}

/*
*

  • bdd_Advertise – Advertise device to io-net and upper layers

*/

int bdd_Advertise(int reg_hdl, void *func_hdl)
{
npkt_t *npkt = NULL;
net_buf_t *nb = NULL;
net_iov_t *iov = NULL;
Nic_t *nic = NULL;
BDD_EXT *ext = NULL;
io_net_msg_dl_advert_t *ap = NULL;

nic = (Nic_t *) func_hdl;

ext = (BDD_EXT *) nic->ext;

if (ext->verbose > 1)
{
fprintf(stderr, “bdd: advertise to io-net\n”);
}

nic->mtu = MAX_PACKET_SIZE;

if ((npkt = ionetAllocNpkt(sizeof(*nb) + sizeof *iov,
(void **)&nb)) == NULL)
{
return(ENOMEM);
}

if ((ap = ionetAlloc(sizeof(*ap), 0)) == NULL)
{
ionetFree(npkt);
return(ENOMEM);
}


TAILQ_INSERT_HEAD(&npkt->buffers, nb, ptrs);

iov = (net_iov_t *)(nb + 1);

nb->niov = 1;
nb->net_iov = iov;
iov->iov_base = ap;
iov->iov_len = sizeof *ap;

memset(ap, 0x00, sizeof *ap);
ap->type = _IO_NET_MSG_DL_ADVERT;

// Our interface does not support broadcast or multicast
ap->iflags = (IFF_SIMPLEX | IFF_POINTOPOINT | IFF_RUNNING);

ap->mtu_min = 0;
ap->mtu_max = nic->mtu;
ap->mtu_preferred = nic->mtu;
strcpy(ap->up_type, “bd”);
itoa(nic->lan, ap->up_type + 2, 10);

strcpy(ap->dl.sdl_data, ap->up_type);

ap->dl.sdl_len = sizeof(struct sockaddr_dl);
ap->dl.sdl_family = AF_LINK;
ap->dl.sdl_index = nic->lan;
ap->dl.sdl_type = IFT_OTHER;

// We dont have an ethernet address. Lets put something here for now
ap->dl.sdl_nlen = strlen(ap->dl.sdl_data); /* not null terminated */
ap->dl.sdl_alen = 6;

memcpy(ap->dl.sdl_data + ap->dl.sdl_nlen, “\x1\x2\x3\x4\x5\x6”, 6);

npkt->org_data = ap;
npkt->flags |= _NPKT_MSG;
npkt->iface = 0;
npkt->framelen = sizeof *ap;

//atomic_add(&ext->rxActive, 1);

// we are using ion->tx_up_start to deliver this advertise packet up

if (ionetRxPackets(ext->reg_hdl, npkt, 0, 0, ext->cell, nic->lan, 0,
nic) == SUCCESS)
{
fprintf(stdout, “Advertise: Done with RxPackets\n”);
fflush(stdout);

ionetTxComplete(ext->reg_hdl, npkt);
}

return(EOK);
}

/* bdd_RegisterDevice
*

  • Create a pulse channel for communication with physical layer
  • Spawn an event thread to receive pulses and fetch packet from the
    physical layer
  • Register the device with ionet
  • and obtain a handle to /dev/phy

*/

int bdd_RegisterDevice(Nic_t *nic, io_net_self_t *ion, void *dll_hdl)
{
BDD_EXT *ext = (BDD_EXT *) nic->ext;
pthread_attr_t pattr;
pthread_mutexattr_t mattr;
struct sched_param param;
uint16_t lan;
DEVCTL_PULSE_MESSAGE Pulse;
int dev_ret;

fprintf(stdout, “bdd_RegisterDevice\n”);
fflush(stdout);

if (ext->verbose > 1 )
{
fprintf(stderr, “bdd: RegisterDeviceInstance\n”);
}

// Create an Event Channel to receive pulses from /dev/phy
// This code simply calls CreateChannel() and AttachChannel() and fills
up the
// Event structure with channel ID and connection IDs.

if ((fddCreateEvent(&ext->Event)) != SUCCESS)
{
fprintf(stderr, “bdd: Unable to create and attach a pulse channel
for events\n”);
return ENODEV;
}

// Setup a Mutex for this thread to use

pthread_mutexattr_init(&mattr);

mattr.flags = PTHREAD_RECURSIVE_ENABLE;

if (pthread_mutex_init(&ext->mutex, NULL) == FAILURE)
{
fprintf(stderr,“bdd: RegisterDeviceInstance: phtread_mutex_init
failed\n”);
return ENODEV;
}

// Setup thread attributes
pthread_attr_init(&pattr);
pthread_attr_setschedpolicy(&pattr, SCHED_RR);
param.sched_priority = 21;
pthread_attr_setschedparam(&pattr, &param);
pthread_attr_setinheritsched(&pattr, PTHREAD_EXPLICIT_SCHED);

// create the event handler thread

if (pthread_create(&ext->threadId, &pattr,(void *)bdd_EventHandler, nic)
!= SUCCESS)
{
slogf( _SLOG_SETCODE(_SLOGC_NETWORK,0), _SLOG_ERROR,
“bdd: Unable to create driver thread”);

pthread_mutex_destroy(&ext->mutex);

return ENODEV;
}

bddEntry.func_hdl = (void *) nic;

// Register the device with io-net
if (ionetRegister(dll_hdl, &bddEntry, &ext->reg_hdl, &ext->cell, &lan)
!= SUCCESS)
{
slogf( _SLOG_SETCODE(_SLOGC_NETWORK,0), _SLOG_ERROR,
“bdd: Unable to register with io-net”);

pthread_kill(ext->threadId, SIGKILL);
pthread_mutex_destroy(&ext->mutex);

return ENODEV;
}

nic->lan = lan;

if (!ext->maxPackets)
{
ext->maxPackets = MAX_PACKETS;
}


ionetDevctl( ext->reg_hdl, DCMD_IO_NET_MAX_QUEUE, &ext->maxPackets,
sizeof(ext->maxPackets), NULL );


// Get a handle to /dev/phy, our physical layer emulator

/******* This is where the open() fails ************/

if ( (ext->phy_hdl = open("/dev/phy", O_RDWR)) != SUCCESS)
{
fprintf(stderr, “bdd: Can’t open the Phy device. ret = %x Errno =
%x\n”, ext->phy_hdl, errno);
return ext->phy_hdl;
}

// Pass the Channel’s ConnectionID to /dev/phy so he can use it to send
us pulses

Pulse.connectionId = ext->Event->Connection;

if ( (devctl(ext->phy_hdl, DEVCTL_PULSE_CODE, &Pulse, sizeof(Pulse),
&dev_ret)) != SUCCESS)
{
fprintf(stderr, “bdd: Can’t send connectionId to /dev/phy\n”);
return ENODEV;
}

return SUCCESS;

} // end RegisterDeviceInstance

/* bdd_AssemblePacket
*

  • Defrag packet received from the IP stack into a linear area

*/

int bdd_AssemblePacket( Nic_t *nic, npkt_t *npkt, char *packet, int
*packetSize )
{
char *dst;
net_iov_t *iov;
net_buf_t *buf;
int totalLen;
int i, len;

BDD_EXT *ext;

ext = (BDD_EXT *)nic->ext;

fprintf(stdout, “bdd_AssemblePacket\n”);
fflush(stdout);

// Do some basic checks on the packet size

for ( totalLen = 0, buf = TAILQ_FIRST(&npkt->buffers); buf != NULL;
buf = TAILQ_NEXT( buf, ptrs ) )
{
for ( i = 0, iov = buf->net_iov; i < buf->niov; i++, iov++ )
{
totalLen += iov->iov_len;
}
}

if ( totalLen > MAX_PACKET_SIZE )
{
return FAILURE;
}

*packetSize = npkt->framelen;

// Initialize pointer for copying the entire packet
dst = packet;

// Copy the fragments into a linear area
for ( len = 0, buf = TAILQ_FIRST( &npkt->buffers ); buf != NULL;
buf = TAILQ_NEXT( buf, ptrs ) )
{
for ( i = 0, iov = buf->net_iov; i < buf->niov; i++, iov++ )
{
memcpy( dst, iov->iov_base, iov->iov_len );
dst += iov->iov_len;
len += iov->iov_len;
}
}


return SUCCESS;
}

/*

  • bdd_Transmit
  • Transmit packets via our physical layer
    */

int bdd_Transmit( npkt_t *npkt, void *hdl )
{
Nic_t *nic;
BDD_EXT *ext;
DEVCTL_MESSAGE packet;
int dev_ret;

nic = (Nic_t *) hdl;
ext = (BDD_EXT *)nic->ext;

//if link is down then return error
fprintf(stdout, “bdd_Transmit\n”);
fflush(stdout);

if ( ext->linkFail == 1 )
{
errno = ENOLINK;
npkt->flags |= _NPKT_NOT_TXED;
pthread_mutex_unlock( &ext->mutex );
ionetTxComplete( ext->reg_hdl, npkt );
pthread_mutex_lock( &ext->mutex );
return(TX_DOWN_FAILED);
}

memset((char *) &packet, 0, sizeof(packet));

// Defrag the packet and assemble the data into a linear packet

if ((bdd_AssemblePacket(nic, npkt, (char*) &packet.buf,
&packet.bufSize)) != SUCCESS)
{
errno = ENOMEM;
npkt->flags |= _NPKT_NOT_TXED;
ionetTxComplete( ext->reg_hdl, npkt );
return(TX_DOWN_FAILED);
} else
{
// Send the packet to the bottom layer (/dev/phy) using devctl
if ( (devctl(ext->phy_hdl, DEVCTL_PACKET_TRANSMIT, &packet,
sizeof(packet), &dev_ret)) != SUCCESS)
{
npkt->flags |= _NPKT_NOT_TXED;
ionetTxComplete( ext->reg_hdl, npkt );
fprintf(stderr, “bdd: Can’t send packet to /dev/phy \n”);

return(TX_DOWN_FAILED);
}

// Give back the packet to io-net
pthread_mutex_unlock( &ext->mutex );
ionetTxComplete( ext->reg_hdl, npkt );
pthread_mutex_lock( &ext->mutex );

// Collect stats
ext->stats.txBytes += packet.bufSize;
ext->stats.txPackets++;

return(TX_DOWN_OK);
}

}

/*
*

  • bdd_EventHandler
  • This is our EventHandler,
  • it will handle all incoming pulses and invoke approprite functions

*/

void *bdd_EventHandler(void *data)
{
Nic_t *nic = (Nic_t *)(data);
BDD_EXT *ext;
//iov_t iov;
int ret;

ext = (BDD_EXT *)(nic->ext);

while (1)
{
// fddWaitOnEvent calls MessageReceivePulse and waits for a pulse
// from /dev/phy

ret = fddWaitOnEvent(ext->Event, 0, FDD_TIMEOUT_INFINITE);

if (ret != SUCCESS)
{
if ( errno == ESRCH )
{
pthread_exit( NULL );
}
continue;
}

pthread_mutex_lock(&ext->mutex);

switch (ext->Event->EventCode)
{
case DEVCTL_PACKET_RECEIVE:
bdd_Receive(nic);
break;

}
pthread_mutex_unlock(&ext->mutex);
}
return(NULL);

}

/*

  • bdd_Receive
  • Receive packet from the physical layer and pass it up

*/

void bdd_Receive(Nic_t *nic)
{

BDD_EXT *ext = NULL;
npkt_t *npkt = NULL;
net_buf_t *nb;
net_iov_t *ni = NULL;
int dev_ret;
DEVCTL_MESSAGE packet;

ext = (BDD_EXT *)(nic->ext);
fprintf(stdout, “bdd: Bdd_receive\n”);
fflush(stdout);

// Allocate packet
if ((npkt = ionetAllocNpkt(sizeof(*nb) + sizeof *ni + MAX_PACKET_SIZE,
(void **)&nb)) == NULL)
{
return;
}

// Receive packet data from /dev/phy using devctl

memset((char *) &packet, 0, sizeof(packet));

if ( (devctl(ext->phy_hdl, DEVCTL_PACKET_RECEIVE, &packet,
sizeof(packet), &dev_ret)) != SUCCESS)
{
fprintf(stderr, “bdd: Can’t receive packet from /dev/phy \n”);

bdd_ReceiveComplete(npkt, nic, NULL);
return;
}

// Copy packet to the iov for up delivery
// ni->iov_base is the starting point for a buffer copy

memcpy((char *) ni->iov_base, (char *) &packet.buf, packet.bufSize);

// Fill in the packet structure
npkt->tot_iov = 1;

ni = (net_iov_t *)(nb + 1);

nb->niov = 1;
nb->net_iov = ni;

ni->iov_base = ni + 1;
ni->iov_len = packet.bufSize; // Actual packet size in bytes
npkt->iface = 0;
npkt->flags = _NPKT_UP;
npkt->req_complete = 0;
npkt->ref_cnt = 1;
npkt->framelen = packet.bufSize;

// Collect stats
ext->stats.rxBytes += packet.bufSize;
ext->stats.rxPackets++;

// Send the packet up
pthread_mutex_unlock( &ext->mutex );

if ((ionetRxPackets(ext->reg_convhdl, npkt, 0, 0, ext->cell, nic->lan,
0, nic)) != NULL)
{
bdd_ReceiveComplete(npkt, nic, NULL);
}

pthread_mutex_lock( &ext->mutex );

return;
}

/*

  • bdd_ReceiveComplete
  • our tx_done()

*/

int bdd_ReceiveComplete ( npkt_t *npkt, void *hdl, void *func_hdl )
{
Nic_t *nic;
BDD_EXT *ext;
int ret;

nic = (Nic_t *)hdl;
ext = (BDD_EXT *)nic->ext;

fprintf(stdout, “bdd_ReceiveComplete\n”);
fflush(stdout);

pthread_mutex_lock(&ext->mutex);

// We will simply free up the packet we created.
ret = ionetFree(npkt);

pthread_mutex_unlock(&ext->mutex);

return ret;
}

/*
*

  • UP Producer shutdowns

*/

int bdd_Shutdown1( int reg_hdl, void *hdl )
{
Nic_t *nic = (Nic_t *)hdl;
BDD_EXT *ext = (BDD_EXT *)nic->ext;

if (ext->verbose > 1)
{

fprintf(stderr, “bdd: shutdown1 (hdl 0x%lx, nic 0x%lx)\n”,
(ulong_t)(hdl), (ulong_t)(nic));
}

// Destroy the event channel
fddDestroyEvent(ext->Event);

// Close the phy driver instance
close(ext->phy_hdl);

return SUCCESS;
}

int bdd_Shutdown2( int reg_hdl, void *hdl )
{
Nic_t *nic = (Nic_t *)hdl;
BDD_EXT *ext = (BDD_EXT *)nic->ext;

if (ext->verbose > 1)
{

fprintf(stderr, “bdd: shutdown2 (hdl 0x%lx, nic 0x%lx)\n”,
(ulong_t)(hdl), (ulong_t)(nic));
}

// Free up all the device resources

pthread_join(ext->threadId, NULL);

pthread_mutex_destroy(&ext->mutex);

free(nic->ext);
free(nic);

return SUCCESS;
}

int bdd_Devctl( void *hdl, int dcmd, void *data, size_t size, int *ret )
{
return SUCCESS;
}

int bdd_FlushTxQueue( int x, void *hdl )
{
return SUCCESS;
}

/* bdc_RxUp
*

  • Converter code to receive packets on the way up. Useful in handling
    advertise
  • packets

*/

int bdc_RxUp( npkt_t *npkt,
void *func_hdl,
int off,
int framlen_sub,
uint16_t cell,
uint16_t endpoint,
uint16_t iface )
{

Nic_t *nic = (Nic_t *)func_hdl;
BDD_EXT *ext = (BDD_EXT *)nic->ext;

fprintf( stdout, “bdc_RxUp\n” );
fflush(stdout);

(*ext->ion->tx_up)( ext->reg_convhdl, npkt, off, framlen_sub, cell,
endpoint, iface );

return EOK;
}

/*

  • Converter shutdowns

*/

int bdc_Shutdown1( int reg_hdl, void *hdl )
{
return SUCCESS;
}

int bdc_Shutdown2( int reg_hdl, void *hdl )
{
Nic_t *nic = (Nic_t *)hdl;
BDD_EXT *ext = (BDD_EXT *)nic->ext;

if (ext->verbose > 1)
{

fprintf(stderr, “bdc: shutdown2 (hdl 0x%lx, nic 0x%lx)\n”,
(ulong_t)(hdl), (ulong_t)(nic));
}

free(nic->ext);
free(nic);

return SUCCESS;
}

Murtaza <murti@yahoo.com> wrote:

Below is the code for my custom device driver “bdd” where the open() call to
/dev/phy fails with errno 3.

bdd registers both an UP producer and a converter. Its a custom driver of
type “bd”. The call to open() /dev/phy takes place in the
bdd_RegisterDevice() routine. I call the open() to /dev/phy after I spawn a
receive thread for the device and register the device with io-net.

I very much appreciate your help in looking over this. Thanks!

  • Murtaza

/******* This is where the open() fails ************/

if ( (ext->phy_hdl = open("/dev/phy", O_RDWR)) != SUCCESS)
{
fprintf(stderr, “bdd: Can’t open the Phy device. ret = %x Errno =
%x\n”, ext->phy_hdl, errno);
return ext->phy_hdl;
}

open() returns -1 on failure and >= 0 on success. You can’t
test for success against a constant.

if ( (ext->phy_hdl = open("/dev/phy", O_RDWR)) == -1)

-seanb

/******* This is where the open() fails ************/

if ( (ext->phy_hdl = open("/dev/phy", O_RDWR)) != SUCCESS)
{
fprintf(stderr, "bdd: Can’t open the Phy device. ret = %x Errno

%x\n", ext->phy_hdl, errno);
return ext->phy_hdl;
}

open() returns -1 on failure and >= 0 on success. You can’t
test for success against a constant.

if ( (ext->phy_hdl = open("/dev/phy", O_RDWR)) == -1)

Duh! :slight_smile:.

Thanks Sean!. I got pass the innitialization and I see the device bd0 and
the converter ip_bd under /dev/io-net but I can’t see it with ifconfig.
Ifconfig complaints there is no such device bd0. Any ideas ? I type
“mount -T io-net //devn-bdd.so” to load the module. I am
guessing its something dumb that I’ve done (Again! :slight_smile: or missed in the
code. Thanks

  • Murtaza

Murtaza <murti@yahoo.com> wrote:

/******* This is where the open() fails ************/

if ( (ext->phy_hdl = open("/dev/phy", O_RDWR)) != SUCCESS)
{
fprintf(stderr, "bdd: Can’t open the Phy device. ret = %x Errno

%x\n", ext->phy_hdl, errno);
return ext->phy_hdl;
}

open() returns -1 on failure and >= 0 on success. You can’t
test for success against a constant.

if ( (ext->phy_hdl = open("/dev/phy", O_RDWR)) == -1)

Duh! > :slight_smile:> .

Thanks Sean!. I got pass the innitialization and I see the device bd0 and
the converter ip_bd under /dev/io-net but I can’t see it with ifconfig.
Ifconfig complaints there is no such device bd0. Any ideas ? I type
“mount -T io-net //devn-bdd.so” to load the module. I am
guessing its something dumb that I’ve done (Again! > :slight_smile: > or missed in the
code. Thanks

The stack learns of your interface from your advertise packet so
something is wrong therein. Do you send one up? Does it get passed
on by your converter? Is it contained in one iov? Is the npkt->tot_iov
field set to 1?

-seanb

Thanks Sean!. I got pass the innitialization and I see the device bd0
and
the converter ip_bd under /dev/io-net but I can’t see it with ifconfig.
Ifconfig complaints there is no such device bd0. Any ideas ? I type
“mount -T io-net //devn-bdd.so” to load the module. I am
guessing its something dumb that I’ve done (Again! > :slight_smile: > or missed in the
code. Thanks


The stack learns of your interface from your advertise packet so
something is wrong therein. Do you send one up? Does it get passed
on by your converter? Is it contained in one iov? Is the npkt->tot_iov
field set to 1?

Got it fixed. Turned out to be the register handle that I was using in the
ion->tx_up_start(). It had to be the converter handle and not the producer
handle even though it is the producer who is originating the advetise
packet.

I had a dummy RxUp for my converter that simply called ion->tx_up but the
return code was always 0 which meant that no one above the converter picked
up the advertise message. However, when I use the converter handle in the
tx_up_start of the producer advetise function, the stack receives the
packet.

  • Murtaza