Hi all,
I found a bug in rt_com-0.5.3.
To verify free space remaining in a buffer (input or output), the
indexes
head and tail are compared. But when the buffer is full (head == tail),
it is considered as empty. It cannot do the difference between a full
and
an empty buffer.
To solve that, I added a counter (used) in the rt_buf_struct structure,
which count the numbers of characters in the buffer.
Attach the diff file.
Denis
*** rt_com.c Wed Jun 13 13:30:38 2001
--- ../rt_com-0.5.3.ori/rt_com.c Fri May 5 19:37:13 2000
***************
*** 77,83 ****
* a standard rt_com you can set used=1. */
struct rt_com_struct rt_com_table[ RT_COM_CNT ] =
{
! { 0, RT_COM_BASE_BAUD, 0x3f8, 4, RT_COM_STD_COM_FLAG, rt_com0_isr, 0x02, 0x01 },
/* ttyS0 - COM1 */
{ 0, RT_COM_BASE_BAUD, 0x2f8, 3, RT_COM_STD_COM_FLAG, rt_com1_isr, 0, 0 } /*
ttyS1 - COM2 */
};
--- 77,83 ----
* a standard rt_com you can set used=1. */
struct rt_com_struct rt_com_table[ RT_COM_CNT ] =
{
! { 0, RT_COM_BASE_BAUD, 0x3f8, 4, RT_COM_STD_COM_FLAG, rt_com0_isr, 0, 0 }, /*
ttyS0 - COM1 */
{ 0, RT_COM_BASE_BAUD, 0x2f8, 3, RT_COM_STD_COM_FLAG, rt_com1_isr, 0, 0 } /*
ttyS1 - COM2 */
};
***************
*** 87,94 ****
/** Remaining free space of buffer
*
* @return amount of free space remaining in a buffer (input or output) */
! #define rt_com_buff_free( b ) \
! ( RT_COM_BUF_SIZ - (b)->used )
--- 87,94 ----
/** Remaining free space of buffer
*
* @return amount of free space remaining in a buffer (input or output) */
! #define rt_com_buff_free( head, tail ) \
! ( RT_COM_BUF_SIZ - ( ( head - tail ) & ( RT_COM_BUF_SIZ - 1 ) ) )
***************
*** 140,146 ****
struct rt_com_struct *p = &( rt_com_table[ com ] );
struct rt_buf_struct *b = &( p->obuf );
if( p->used > 0 )
! return( rt_com_buff_free( b ) );
}
return( -1 );
}
--- 140,146 ----
struct rt_com_struct *p = &( rt_com_table[ com ] );
struct rt_buf_struct *b = &( p->obuf );
if( p->used > 0 )
! return( rt_com_buff_free( b->head, b->tail ) );
}
return( -1 );
}
***************
*** 163,169 ****
if( p->used > 0 ) {
rt_com_irq_off( state );
b->tail = b->head;
- b->used = 0;
if( RT_COM_FIFO_TRIGGER > 0)
rt_com_enable_fifo(p->port, RT_COM_FIFO_TRIGGER, 0x02);
rt_com_irq_on( state );
--- 163,168 ----
***************
*** 197,203 ****
p->ier &= ~0x02;
outb ( p->ier, p->port+RT_COM_IER);
b->tail = b->head;
- b->used = 0;
if ( RT_COM_FIFO_TRIGGER > 0)
rt_com_enable_fifo( p->port, RT_COM_FIFO_TRIGGER, 0x04 );
rt_com_irq_on( state );
--- 196,201 ----
***************
*** 335,341 ****
b->buf[ b->head++ ] = *data++;
/* if( head == RT_COM_BUF_SIZ ), wrap head to the first buffer element
*/
b->head &= ( RT_COM_BUF_SIZ - 1 );
- b->used++;
}
p->ier |= 0x02;
outb( p->ier, p->port + RT_COM_IER );
--- 333,338 ----
***************
*** 365,379 ****
long state;
if( p->used > 0) {
rt_com_irq_off( state );
! while( ( b->used ) && ( --cnt >= 0 ) ) {
done++;
*ptr++ = b->buf[ b->tail++ ];
b->tail &= ( RT_COM_BUF_SIZ - 1 );
- b->used--;
}
rt_com_irq_on( state );
if( ( p->mode & 0x02 )
! && ( rt_com_buff_free( b ) > RT_COM_BUF_HI ) ) {
/* if hardware flow and enough free space on input buffer
then set RTS */
p->mcr |= 0x02;
--- 362,375 ----
long state;
if( p->used > 0) {
rt_com_irq_off( state );
! while( ( b->head != b->tail ) && ( --cnt >= 0 ) ) {
done++;
*ptr++ = b->buf[ b->tail++ ];
b->tail &= ( RT_COM_BUF_SIZ - 1 );
}
rt_com_irq_on( state );
if( ( p->mode & 0x02 )
! && ( rt_com_buff_free( b->head, b->tail ) > RT_COM_BUF_HI ) ) {
/* if hardware flow and enough free space on input buffer
then set RTS */
p->mcr |= 0x02;
***************
*** 397,406 ****
static inline int rt_com_irq_get( struct rt_com_struct *p, unsigned char *c )
{
struct rt_buf_struct *b = &( p->obuf );
! if( b->used ) {
*c = b->buf[ b->tail++ ];
b->tail &= ( RT_COM_BUF_SIZ - 1 );
- b->used--;
return( 1 );
}
return( 0 );
--- 393,401 ----
static inline int rt_com_irq_get( struct rt_com_struct *p, unsigned char *c )
{
struct rt_buf_struct *b = &( p->obuf );
! if( b->head != b->tail ) {
*c = b->buf[ b->tail++ ];
b->tail &= ( RT_COM_BUF_SIZ - 1 );
return( 1 );
}
return( 0 );
***************
*** 420,426 ****
struct rt_buf_struct *b = &( p->ibuf );
b->buf[ b->head++ ] = ch;
b->head &= ( RT_COM_BUF_SIZ - 1 );
- b->used++;
}
--- 415,420 ----
***************
*** 489,495 ****
};
/* controls on buffer full and RTS clear on hardware flow control */
! buff = rt_com_buff_free( b );
if (buff < RT_COM_BUF_FULL) p->error = RT_COM_BUFFER_FULL;
if( ( p->mode & 0x02 ) && ( buff < RT_COM_BUF_LOW ) ) {
p->mcr &= ~0x02;
--- 483,489 ----
};
/* controls on buffer full and RTS clear on hardware flow control */
! buff = rt_com_buff_free( b->head, b->tail );
if (buff < RT_COM_BUF_FULL) p->error = RT_COM_BUFFER_FULL;
if( ( p->mode & 0x02 ) && ( buff < RT_COM_BUF_LOW ) ) {
p->mcr &= ~0x02;
*** rt_comP.h Wed Jun 13 13:31:01 2001
--- ../rt_com-0.5.3.ori/rt_comP.h Wed May 3 01:14:11 2000
***************
*** 100,106 ****
struct rt_buf_struct{
int head;
int tail;
- int used;
char buf[ RT_COM_BUF_SIZ ];
};
--- 100,105 ----