Changeset a8595605 in rtems


Ignore:
Timestamp:
Mar 6, 2017, 12:08:04 PM (3 years ago)
Author:
Martin Aberg <maberg@…>
Branches:
5, master
Children:
21b3319f
Parents:
c609ccea
git-author:
Martin Aberg <maberg@…> (03/06/17 12:08:04)
git-committer:
Daniel Hellstrom <daniel@…> (05/02/17 10:34:48)
Message:

leon, occan: Converted disable/enable to SMP locks

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/can/occan.c

    rc609ccea ra8595605  
    99 */
    1010
     11#include <rtems.h>
    1112#include <rtems/libio.h>
    1213#include <stdlib.h>
     
    7071        #define DBG(fmt, vargs...)
    7172#endif
     73
     74/* Spin locks mapped via rtems_interrupt_lock_* API: */
     75#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     76#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     77#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     78#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     79#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     80#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     81#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     82#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    7283
    7384/* fifo interface */
     
    204215        struct drvmgr_dev *dev;
    205216        char devName[32];
     217        SPIN_DECLARE(devlock);
    206218
    207219        /* hardware shortcuts */
     
    11661178}
    11671179
    1168 static rtems_device_driver occan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg){
     1180static rtems_device_driver occan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     1181{
    11691182        occan_priv *can;
    11701183        struct drvmgr_dev *dev;
     
    11801193
    11811194        /* already opened? */
    1182         rtems_semaphore_obtain(can->devsem,RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     1195        rtems_semaphore_obtain(can->devsem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    11831196        if ( can->open ){
    11841197                rtems_semaphore_release(can->devsem);
     
    11871200        can->open = 1;
    11881201        rtems_semaphore_release(can->devsem);
     1202
     1203        SPIN_INIT(&can->devlock, can->devName);
    11891204
    11901205        /* allocate fifos */
     
    12541269}
    12551270
    1256 static rtems_device_driver occan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg){
     1271static rtems_device_driver occan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     1272{
    12571273        occan_priv *can;
    12581274        struct drvmgr_dev *dev;
    12591275        rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t *) arg;
    12601276        CANMsg *dstmsg, *srcmsg;
    1261         rtems_interrupt_level oldLevel;
     1277        SPIN_IRQFLAGS(oldLevel);
    12621278        int left;
    12631279
     
    12891305
    12901306                /* turn off interrupts */
    1291                 rtems_interrupt_disable(oldLevel);
     1307                SPIN_LOCK_IRQ(&can->devlock, oldLevel);
    12921308
    12931309                /* A bus off interrupt may have occured after checking can->started */
    12941310                if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
    1295                         rtems_interrupt_enable(oldLevel);
     1311                        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
    12961312                        DBG("OCCAN: read is cancelled due to a BUS OFF error\n\r");
    12971313                        rw_args->bytes_moved = rw_args->count-left;
     
    13081324                        if ( !can->rxblk || (left != rw_args->count) ){
    13091325                                /* turn on interrupts again */
    1310                                 rtems_interrupt_enable(oldLevel);
     1326                                SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
    13111327                                break;
    13121328                        }
    13131329
    13141330                        /* turn on interrupts again */
    1315                         rtems_interrupt_enable(oldLevel);
     1331                        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
    13161332
    13171333                        DBG("OCCAN: Waiting for RX int\n\r");
     
    13401356
    13411357                /* turn on interrupts again */
    1342                 rtems_interrupt_enable(oldLevel);
     1358                SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
    13431359
    13441360                /* increase pointers */
     
    13561372}
    13571373
    1358 static rtems_device_driver occan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg){
     1374static rtems_device_driver occan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     1375{
    13591376        occan_priv *can;
    13601377        struct drvmgr_dev *dev;
    13611378        rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t *) arg;
    13621379        CANMsg *msg,*fifo_msg;
    1363         rtems_interrupt_level oldLevel;
     1380        SPIN_IRQFLAGS(oldLevel);
    13641381        int left;
    13651382
     
    13901407
    13911408        /* turn off interrupts */
    1392         rtems_interrupt_disable(oldLevel);
     1409        SPIN_LOCK_IRQ(&can->devlock, oldLevel);
    13931410
    13941411        /* A bus off interrupt may have occured after checking can->started */
    13951412        if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
    1396                 rtems_interrupt_enable(oldLevel);
     1413                SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
    13971414                rw_args->bytes_moved = 0;
    13981415                return RTEMS_IO_ERROR; /* EIO */
     
    14461463                                CHECK_IF_FIFO_EMPTY ==> SEND DIRECT VIA HW;
    14471464                        */
    1448                         rtems_interrupt_enable(oldLevel);
     1465                        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
    14491466
    14501467                        DBG("OCCAN: Waiting for tx int\n\r");
     
    14601477                        }
    14611478
    1462                         rtems_interrupt_disable(oldLevel);
     1479                        SPIN_LOCK_IRQ(&can->devlock, oldLevel);
    14631480
    14641481                        if ( occan_fifo_empty(can->txfifo) ){
     
    14971514        }
    14981515
    1499         rtems_interrupt_enable(oldLevel);
     1516        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
    15001517
    15011518        rw_args->bytes_moved = rw_args->count-left;
     
    15071524}
    15081525
    1509 static rtems_device_driver occan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg){
     1526static rtems_device_driver occan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     1527{
    15101528        int ret;
    15111529        occan_speed_regs timing;
     
    17051723        unsigned char tmp, errcode, arbcode;
    17061724        int tx_error_cnt,rx_error_cnt;
     1725        SPIN_ISR_IRQFLAGS(irqflags);
    17071726
    17081727        if ( !can->started )
    17091728                return; /* Spurious Interrupt, do nothing */
    17101729
     1730        SPIN_LOCK(&can->devlock, irqflags);
    17111731        while (1) {
    17121732
     
    19431963                }
    19441964        }
     1965        SPIN_UNLOCK(&can->devlock, irqflags);
    19451966
    19461967        /* signal Binary semaphore, messages available! */
Note: See TracChangeset for help on using the changeset viewer.