qnx6 resource manager tto issue

I am working on a resource manger that makes use of the io-char library for
qnx6 and have an interesting problem.

My resource manger creates virtual serial ports that actually communicate
with our Blue Heat/Net Ethernet to serial hardware via TCP/IP and this is
all working very well, but there is a behaviour that I am hoping someone can
shed some light on.

In my driver tto sends to an open tcp/ip socket. In some cases the serial
port can get flow controlled and data will back up to my send and cause it
to fail with an EAGAIN errno. In this case if I am running flow control I
mark the dev flags PAGED appropriately and return from my tto routine. This
appears to work fine. Later on I get another call to my tto and I can try
again. I cannot clear the PAGED flag because I have no real way of knowing
when the send will work without doing a send.

The issue is when I am running more than one of my virtual serial ports and
one of them gets flow controlled. My other serial port’s tto routines never
get called. It keeps trying my flow controlled tto over and over. Seeing
as all of the threads are running at the same priority, I don’t know why
this is happening.

Does anyone have any thoughts?

I forgot to mention that flags does have the LOSES_TX_INTR bit set on all
ports.

“Allan Smith” <aes@connecttech.com> wrote in message
news:d7nhmd$k17$1@inn.qnx.com

I am working on a resource manger that makes use of the io-char library for
qnx6 and have an interesting problem.

My resource manger creates virtual serial ports that actually communicate
with our Blue Heat/Net Ethernet to serial hardware via TCP/IP and this is
all working very well, but there is a behaviour that I am hoping someone
can shed some light on.

In my driver tto sends to an open tcp/ip socket. In some cases the serial
port can get flow controlled and data will back up to my send and cause it
to fail with an EAGAIN errno. In this case if I am running flow control I
mark the dev flags PAGED appropriately and return from my tto routine.
This appears to work fine. Later on I get another call to my tto and I
can try again. I cannot clear the PAGED flag because I have no real way
of knowing when the send will work without doing a send.

The issue is when I am running more than one of my virtual serial ports
and one of them gets flow controlled. My other serial port’s tto routines
never get called. It keeps trying my flow controlled tto over and over.
Seeing as all of the threads are running at the same priority, I don’t
know why this is happening.

Does anyone have any thoughts?

Hi Allan,

I’ve developed very similar driver for our Lava Ether-Serial Link (ESL)
controllers. Since it was more than a year ago, I think I’ve forgotten
some details. But I can’t recall any problem similar to yours.

Here are some thoughts, maybe they could be useful for you:

I commented out input flow control in io-char library, files io_read.c
and tti.c, because our ESL takes care of flow control by itself. Though
it was QNX 6.1 version and I don’t know if it was changed in later
releases of QNX. Keeping flow control in io-char library is a hassle for
writing drivers for Ethernet-to-serial converters as well as for 16C650-
16C950 kinds of UART with automatic flow control enabled. But I don’t
think this is an issue you’re experiencing problem with right now.

Architecturally my driver was different. I didn’t work with socket
whithin tto routine. Actually I eliminated any calls from io-char
callbacks which theoretically could block. Instead, my tto just set flag
in device structure and appropriate transport handling thread was
therefore informed there is some data to be sent. If device was in flow
stopped state (actually Lava ESL sends back to driver event
notifications, so in my case it was asynchronously to data sending
process), I also set appropriate PAGED flag in TTY structure. The state
of flags in one TTY structure never affected the state or operations of
a different port. Do you send a pulse? Here is my code snippet:

status=tti(&dev->tty, event?TTI_OHW_CONT:TTI_OHW_STOP);
if(status){
if(!atomic_set_value(&dev->tty.flags, EVENT_QUEUE)){
dev_lock(&ttyctrl);
ttyctrl.even_queue[ttyctrl.num_events++]=&dev->tty;
dev_unlock(&ttyctrl);
MsgSendPulse(ttyctrl.event.sigev_coid,
ttyctrl.event.sigev_priority,
ttyctrl.event.sigev_code, 0);
}
}

And last, but not least, check your init routine, it might be just wrong
initialization of pointers.

Eduard.

In article <d7nq41$pvc$1@inn.qnx.com>, aes@connecttech.com says…

I forgot to mention that flags does have the LOSES_TX_INTR bit set on all
ports.

“Allan Smith” <> aes@connecttech.com> > wrote in message
news:d7nhmd$k17$> 1@inn.qnx.com> …
I am working on a resource manger that makes use of the io-char library for
qnx6 and have an interesting problem.

My resource manger creates virtual serial ports that actually communicate
with our Blue Heat/Net Ethernet to serial hardware via TCP/IP and this is
all working very well, but there is a behaviour that I am hoping someone
can shed some light on.

In my driver tto sends to an open tcp/ip socket. In some cases the serial
port can get flow controlled and data will back up to my send and cause it
to fail with an EAGAIN errno. In this case if I am running flow control I
mark the dev flags PAGED appropriately and return from my tto routine.
This appears to work fine. Later on I get another call to my tto and I
can try again. I cannot clear the PAGED flag because I have no real way
of knowing when the send will work without doing a send.

The issue is when I am running more than one of my virtual serial ports
and one of them gets flow controlled. My other serial port’s tto routines
never get called. It keeps trying my flow controlled tto over and over.
Seeing as all of the threads are running at the same priority, I don’t
know why this is happening.

Does anyone have any thoughts?

\

Hi Eduard,

Thanks for the tips. I have given up on doing it the way I was doing it and
went to a similar threading scheme as you suggested.

Al
“ed1k” <ed1k@fake.address> wrote in message
news:MPG.1d0d25ec992b9d009896c1@inn.qnx.com

Hi Allan,

I’ve developed very similar driver for our Lava Ether-Serial Link (ESL)
controllers. Since it was more than a year ago, I think I’ve forgotten
some details. But I can’t recall any problem similar to yours.

Here are some thoughts, maybe they could be useful for you:

I commented out input flow control in io-char library, files io_read.c
and tti.c, because our ESL takes care of flow control by itself. Though
it was QNX 6.1 version and I don’t know if it was changed in later
releases of QNX. Keeping flow control in io-char library is a hassle for
writing drivers for Ethernet-to-serial converters as well as for 16C650-
16C950 kinds of UART with automatic flow control enabled. But I don’t
think this is an issue you’re experiencing problem with right now.

Architecturally my driver was different. I didn’t work with socket
whithin tto routine. Actually I eliminated any calls from io-char
callbacks which theoretically could block. Instead, my tto just set flag
in device structure and appropriate transport handling thread was
therefore informed there is some data to be sent. If device was in flow
stopped state (actually Lava ESL sends back to driver event
notifications, so in my case it was asynchronously to data sending
process), I also set appropriate PAGED flag in TTY structure. The state
of flags in one TTY structure never affected the state or operations of
a different port. Do you send a pulse? Here is my code snippet:

status=tti(&dev->tty, event?TTI_OHW_CONT:TTI_OHW_STOP);
if(status){
if(!atomic_set_value(&dev->tty.flags, EVENT_QUEUE)){
dev_lock(&ttyctrl);
ttyctrl.even_queue[ttyctrl.num_events++]=&dev->tty;
dev_unlock(&ttyctrl);
MsgSendPulse(ttyctrl.event.sigev_coid,
ttyctrl.event.sigev_priority,
ttyctrl.event.sigev_code, 0);
}
}

And last, but not least, check your init routine, it might be just wrong
initialization of pointers.

Eduard.