diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2017-05-11 12:54:46 +0200 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2017-05-14 12:32:00 +0200 |
commit | 818f10bc6c82990c5f0a33200d34de86b344e688 (patch) | |
tree | dfa037931b6ad03f400ac718dd4f416489d4cf93 /c/src/lib/libbsp/sparc/shared/tmtc/grtc.c | |
parent | leon, gr1553bm: SMP support by using spin-locks (diff) | |
download | rtems-818f10bc6c82990c5f0a33200d34de86b344e688.tar.bz2 |
leon, grtc: updated overrun condition handling
The following functions now reports to the user that an overrun has
occured by returning errno EIO:
* grtc_read, on overrun and no more data in the DMA buffer
* ioctl(GRTC_IOC_RECV), on overrun and no more frames in the DMA buffer
* ioctl(GRTC_IOC_ISSTARTED), EIO is returned on overrun
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/tmtc/grtc.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/tmtc/grtc.c b/c/src/lib/libbsp/sparc/shared/tmtc/grtc.c index e2661c8ce4..3cceb60c86 100644 --- a/c/src/lib/libbsp/sparc/shared/tmtc/grtc.c +++ b/c/src/lib/libbsp/sparc/shared/tmtc/grtc.c @@ -523,7 +523,7 @@ static int __inline__ grtc_hw_data_avail(unsigned int rrp, unsigned rwp, unsigne return rwp+(bufsize-rrp); } -/* Reads as much as possiböe but not more than 'max' bytes from the TC receive buffer. +/* Reads as much as possible but not more than 'max' bytes from the TC receive buffer. * Number of bytes put into 'buf' is returned. */ static int grtc_hw_read_try(struct grtc_priv *pDev, char *buf, int max) @@ -599,7 +599,7 @@ static int grtc_hw_read_try(struct grtc_priv *pDev, char *buf, int max) return count; } -/* Reads as much as possiböe but not more than 'max' bytes from the TC receive buffer. +/* Reads as much as possible but not more than 'max' bytes from the TC receive buffer. * Number of bytes put into 'buf' is returned. */ static int grtc_data_avail(struct grtc_priv *pDev) @@ -659,6 +659,12 @@ static int grtc_start(struct grtc_priv *pDev) return RTEMS_IO_ERROR; } + /* make sure the RX semaphore is in the correct state when starting. + * In case of a previous overrun condition it could be in incorrect + * state (where rtems_semaphore_flush was used). + */ + rtems_semaphore_obtain(pDev->sem_rx, RTEMS_NO_WAIT, 0); + /* Set operating modes */ tmp = 0; if ( pDev->config.psr_enable ) @@ -814,6 +820,7 @@ static rtems_device_driver grtc_open( pDev->ready.cnt = 0; pDev->running = 0; + pDev->overrun_condition = 0; memset(&pDev->config,0,sizeof(pDev->config)); @@ -841,7 +848,7 @@ static rtems_device_driver grtc_close(rtems_device_major_number major, rtems_dev grtc_stop(pDev); pDev->running = 0; } - + /* Reset core */ grtc_hw_reset(pDev); @@ -910,16 +917,22 @@ read_from_buffer: /* Non-blocking mode and no data read. */ return RTEMS_TIMEOUT; } - + /* Tell caller how much was read. */ - + DBG("READ returning %d bytes, left: %d\n",rw_args->count-left,left); - + rw_args->bytes_moved = rw_args->count - left; - if ( rw_args->bytes_moved == 0 ){ + if ( rw_args->bytes_moved == 0 ) { + if ( pDev->overrun_condition ) { + /* signal to the user that overrun has happend when + * no more data can be read out. + */ + return RTEMS_IO_ERROR; + } return RTEMS_TIMEOUT; } - + return RTEMS_SUCCESSFUL; } @@ -1569,6 +1582,8 @@ static rtems_device_driver grtc_ioctl(rtems_device_major_number major, rtems_dev case GRTC_IOC_ISSTARTED: if ( !pDev->running ) { return RTEMS_RESOURCE_IN_USE; + } else if ( pDev->overrun_condition ) { + return RTEMS_IO_ERROR; } break; @@ -1850,13 +1865,20 @@ static rtems_device_driver grtc_ioctl(rtems_device_major_number major, rtems_dev frmlist->head = pDev->ready.head; frmlist->tail = pDev->ready.tail; frmlist->cnt = pDev->ready.cnt; - + /* Empty list */ pDev->ready.head = NULL; pDev->ready.tail = NULL; pDev->ready.cnt = 0; + + if ((frmlist->cnt == 0) && pDev->overrun_condition) { + /* signal to the user that overrun has happend when + * no more data can be read out. + */ + return RTEMS_IO_ERROR; + } break; - + case GRTC_IOC_GET_CLCW_ADR: if ( !data ) { return RTEMS_INVALID_NAME; @@ -1878,7 +1900,7 @@ static void grtc_interrupt(void *arg) /* Clear interrupt by reading it */ status = READ_REG(®s->pisr); - + /* Spurious Interrupt? */ if ( !pDev->running ) return; |