It is also required to use semaphore release instead of flush when stopping
or on BUSOFF/AHBERR condition. Otherwise a task just about to wait
(taking the semaphore) could end up locked because the semaphore count is
still the same.
There was previously a scenario where the semaphore flush would not always make
semaphore obtain to return in case of BUSOFF, AHBERROR or grcan_stop. It has to
do with the rtems_semaphore_flush() not releasing the semaphore but just aborts
any _current_ waiter.
When bus-off condition is detected by the ISR, it sets the started flag to
STATE_BUSOFF. This is monitored by the user functions grcan_read() and
grcan_write() each time they want to enable DMA or update interrupt mask. If
they detect that ISR has detected bus-off then they will return either with an
error or with the number of CAN messages processed. Future calls to functions
which require STARTED mode will be rejected and grcan_isstarted() will return
0. The next call to grcan_stop() will do the transition from BUSOFF->STOPPED
and the device can then be started again with grcan_start().
Similar to a bus-off condition, the AHB error condition detected by the ISR
will trigger the same shut-down logic of the driver. The difference is that
the state entered is STATE_AHBERR and the routines will return a different
value to indicate AHB error state.
This commit also fixes an issue where ISR was not always unregistered on close.
User functions can cause these transitions:
STATE_STOPPED -> STATE_STARTED (grcan_start)
STATE_STARTED -> STATE_STOPPED (grcan_stop)
STATE_BUSOFF -> STATE_STOPPED (grcan_stop, grcan_close)
STATE_AHBERR -> STATE_STOPPED (grcan_stop, grcan_close)
ISR can cause these transition
STATE_STARTED -> STATE_BUSOFF (grcan_interrupt)
STATE_STARTED -> STATE_AHBERR (grcan_interrupt)
STATE_BUSOFF/AHBERR is entered from ISR on bus-off condition. At transition
the ISR disables DMA, masks all interrupts and flushes semaphores.
Other related updates:
* Statistics are updated from the ISR. Update is now spin-locked to ensure a
consistent user view.
* The debug output has been updated to include state changes.
* For read/write/flush, return error (-4) if driver aborted the operation
due to bus-off. Likewise if abourted due to AHB error -5 is returned.
* Collect bus-off statistics
Related to the new BUSOFF and AHBERR states the API has been updated to
reflect the current SW driver state. The isstarted() function has been
replaced with get_state().
This commit preserves all driver services, using a function based user
interface instead of the I/O interface.
The messages count parameter is now number of CAN messages instead of
number of bytes.
The EDCL and Duplex-Detection are now disabled during soft-reset
of the GRETH core.
The speed settings are preserved on boot and greth_stop() also,
this is required to keep EDCL operational when DD is set.
Enable the SMP configuration by default in case SMP is enabled. Add
configuration option CONFIGURE_DISABLE_SMP_CONFIGURATION to disable it
explicitly.
Add CONFIGURE_DISABLE_SMP_CONFIGURATION to all test which would fail
otherwise.
Update #3001.
Probing of separate interrupts was done by storing the GPTIMER_CFG_SI bit. But
it was never actually stored since it is bit 8 and the datatype is 8-bit. Now
store the AND result as boolean value instead.
This commit updates the OCCAN driver locking mechanism:
1. Convert interrupt disable/enable to interrupt locks.
2. Make sure interrupt service routines use proper locking to deal with threads
running in parallel.