Changeset ad203e58 in rtems


Ignore:
Timestamp:
Jan 24, 2017, 9:00:07 AM (3 years ago)
Author:
Martin Aberg <maberg@…>
Branches:
5, master
Children:
bc40b4d
Parents:
229c4249
git-author:
Martin Aberg <maberg@…> (01/24/17 09:00:07)
git-committer:
Daniel Hellstrom <daniel@…> (05/14/17 10:31:57)
Message:

leon, grcan: function based user interface

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.

Location:
c/src/lib/libbsp/sparc/shared
Files:
2 edited

Legend:

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

    r229c4249 rad203e58  
    1111
    1212#include <bsp.h>
    13 #include <rtems/libio.h>
    1413#include <stdlib.h>
    1514#include <stdio.h>
     
    2322#include <drvmgr/ambapp_bus.h>
    2423#include <ambapp.h>
     24
     25/* Maximum number of GRCAN devices supported by driver */
     26#define GRCAN_COUNT_MAX 8
    2527
    2628#define WRAP_AROUND_TX_MSGS 1
     
    138140};
    139141
    140 static rtems_device_driver grcan_initialize(rtems_device_major_number  major, rtems_device_minor_number  minor, void *arg);
    141 static rtems_device_driver grcan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
    142 static rtems_device_driver grcan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
    143 static rtems_device_driver grcan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
    144 static rtems_device_driver grcan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
    145 static rtems_device_driver grcan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
    146 
    147 #define GRCAN_DRIVER_TABLE_ENTRY { grcan_initialize, grcan_open, grcan_close, grcan_read, grcan_write, grcan_ioctl }
    148 
    149142static void __inline__ grcan_hw_reset(struct grcan_regs *regs);
    150143
     
    210203#endif
    211204
    212 
    213 static rtems_driver_address_table grcan_driver = GRCAN_DRIVER_TABLE_ENTRY;
    214 static int grcan_driver_io_registered = 0;
    215 static rtems_device_major_number grcan_driver_io_major = 0;
     205static int grcan_count = 0;
     206static struct grcan_priv *priv_tab[GRCAN_COUNT_MAX];
    216207
    217208/******************* Driver manager interface ***********************/
    218209
    219210/* Driver prototypes */
    220 int grcan_register_io(rtems_device_major_number *m);
    221211int grcan_device_init(struct grcan_priv *pDev);
    222212
     
    266256
    267257        DBG("GRCAN[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
     258        if (GRCAN_COUNT_MAX <= grcan_count)
     259                return DRVMGR_ENORES;
    268260        priv = dev->priv = malloc(sizeof(struct grcan_priv));
    269261        if ( !priv )
     
    281273        struct grcan_priv *priv;
    282274        char prefix[32];
    283         rtems_status_code status;
    284275
    285276        priv = dev->priv;
    286277
    287         /* Do initialization */
    288 
    289         if ( grcan_driver_io_registered == 0) {
    290                 /* Register the I/O driver only once for all cores */
    291                 if ( grcan_register_io(&grcan_driver_io_major) ) {
    292                         /* Failed to register I/O driver */
    293                         dev->priv = NULL;
    294                         return DRVMGR_FAIL;
    295                 }
    296 
    297                 grcan_driver_io_registered = 1;
    298         }
    299 
    300         /* I/O system registered and initialized
     278        /*
    301279         * Now we take care of device initialization.
    302280         */
     
    305283                return DRVMGR_FAIL;
    306284        }
     285
     286        priv_tab[grcan_count] = priv;
     287        grcan_count++;
    307288
    308289        /* Get Filesystem name prefix */
     
    320301        }
    321302
    322         /* Register Device */
    323         status = rtems_io_register_name(priv->devName, grcan_driver_io_major, dev->minor_drv);
    324         if (status != RTEMS_SUCCESSFUL) {
    325                 return DRVMGR_FAIL;
    326         }
    327 
    328303        return DRVMGR_OK;
    329 }
    330 
    331 /******************* Driver Implementation ***********************/
    332 
    333 int grcan_register_io(rtems_device_major_number *m)
    334 {
    335         rtems_status_code r;
    336 
    337         if ((r = rtems_io_register_driver(0, &grcan_driver, m)) == RTEMS_SUCCESSFUL) {
    338                 DBG("GRCAN driver successfully registered, major: %d\n", *m);
    339         } else {
    340                 switch(r) {
    341                 case RTEMS_TOO_MANY:
    342                         printk("GRCAN rtems_io_register_driver failed: RTEMS_TOO_MANY\n");
    343                         return -1;
    344                 case RTEMS_INVALID_NUMBER: 
    345                         printk("GRCAN rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");
    346                         return -1;
    347                 case RTEMS_RESOURCE_IN_USE:
    348                         printk("GRCAN rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");
    349                         return -1;
    350                 default:
    351                         printk("GRCAN rtems_io_register_driver failed\n");
    352                         return -1;
    353                 }
    354         }
    355         return 0;
    356304}
    357305
     
    429377}
    430378
    431 static rtems_device_driver grcan_start(struct grcan_priv *pDev)
     379static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
    432380{
    433381  /*
     
    504452}
    505453
    506 static void grcan_stop(struct grcan_priv *pDev)
     454static void grcan_hw_stop(struct grcan_priv *pDev)
    507455{
    508456  FUNCDBG();
     
    12111159}
    12121160
    1213 static rtems_device_driver grcan_initialize(
    1214   rtems_device_major_number major,
    1215   rtems_device_minor_number unused,
    1216   void *arg
    1217   )
    1218 {
    1219         return RTEMS_SUCCESSFUL;
    1220 }
    1221 
    1222 static rtems_device_driver grcan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     1161int grcan_dev_count(void)
     1162{
     1163        return grcan_count;
     1164}
     1165
     1166void *grcan_open(int dev_no)
    12231167{
    12241168        struct grcan_priv *pDev;
    1225         rtems_device_driver ret;
    1226         struct drvmgr_dev *dev;
     1169        void *ret;
    12271170        union drvmgr_key_value *value;
    12281171
    12291172        FUNCDBG();
    12301173
    1231         if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) {
    1232                 DBG("Wrong minor %d\n", minor);
    1233                 return RTEMS_INVALID_NAME;
    1234         }
    1235         pDev = (struct grcan_priv *)dev->priv;
     1174        if (grcan_count == 0 || (grcan_count <= dev_no)) {
     1175                return NULL;
     1176        }
     1177
     1178        pDev = priv_tab[dev_no];
    12361179
    12371180        /* Wait until we get semaphore */
    12381181        if (rtems_semaphore_obtain(pDev->dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
    12391182            != RTEMS_SUCCESSFUL) {
    1240                 return RTEMS_INTERNAL_ERROR;
     1183                return NULL;
    12411184        }
    12421185
    12431186        /* is device busy/taken? */
    12441187        if ( pDev->open ) {
    1245                 ret=RTEMS_RESOURCE_IN_USE;
     1188                ret = NULL;
    12461189                goto out;
    12471190        }
     
    12981241
    12991242        if ( grcan_alloc_buffers(pDev,1,1) ) {
    1300                 ret=RTEMS_NO_MEMORY;
     1243                ret = NULL;
    13011244                goto out;
    13021245        }
     
    13051248        memset(&pDev->stats,0,sizeof(struct grcan_stats));
    13061249
    1307         ret = RTEMS_SUCCESSFUL;
     1250        ret = pDev;
    13081251out:
    13091252        rtems_semaphore_release(pDev->dev_sem);
     
    13111254}
    13121255
    1313 static rtems_device_driver grcan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
    1314 {
    1315         struct grcan_priv *pDev;
    1316         struct drvmgr_dev *dev;
    1317 
    1318         FUNCDBG();
    1319 
    1320         if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) {
    1321                 return RTEMS_INVALID_NAME;
    1322         }
    1323         pDev = (struct grcan_priv *)dev->priv;
     1256int grcan_close(void *d)
     1257{
     1258        struct grcan_priv *pDev = d;
     1259
     1260        FUNCDBG();
    13241261
    13251262        if ( pDev->started )
    1326                 grcan_stop(pDev);
     1263                grcan_hw_stop(pDev);
    13271264
    13281265        grcan_hw_reset(pDev->regs);
     
    13331270        pDev->open = 0;
    13341271
    1335         return RTEMS_SUCCESSFUL;
    1336 }
    1337 
    1338 static rtems_device_driver grcan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
    1339 {
    1340         struct grcan_priv *pDev;
    1341         struct drvmgr_dev *dev;
    1342         rtems_libio_rw_args_t *rw_args; 
     1272        return 0;
     1273}
     1274
     1275int grcan_read(void *d, CANMsg *msg, size_t ucount)
     1276{
     1277        struct grcan_priv *pDev = d;
    13431278        CANMsg *dest;
    13441279        unsigned int count, left;
     
    13471282        FUNCDBG();
    13481283
    1349         if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) {
    1350                 return RTEMS_INVALID_NAME;
    1351         }
    1352         pDev = (struct grcan_priv *)dev->priv;
    1353 
    1354         rw_args = (rtems_libio_rw_args_t *) arg;
    1355         dest = (CANMsg *) rw_args->buffer;
    1356         req_cnt = rw_args->count / sizeof(CANMsg);
     1284        dest = msg;
     1285        req_cnt = ucount;
    13571286
    13581287        if ( (!dest) || (req_cnt<1) )
    1359                 return RTEMS_INVALID_NAME;
     1288                return -1;
    13601289
    13611290        if ( !pDev->started )
    1362                 return RTEMS_RESOURCE_IN_USE;
     1291                return -2;
    13631292
    13641293        /*FUNCDBG("grcan_read [%i,%i]: buf: 0x%x len: %i\n",major, minor, (unsigned int)rw_args->buffer,rw_args->count);*/
     
    13681297                if ( count > 0 ) {
    13691298                        /* Successfully received messages (at least one) */
    1370                         rw_args->bytes_moved = count * sizeof(CANMsg);
    1371                         return RTEMS_SUCCESSFUL;
     1299                        return count;
    13721300                }
    13731301
     
    13751303                if ( !pDev->rxblock ) {
    13761304                        /* non-blocking mode */
    1377                         rw_args->bytes_moved = 0;
    1378                         return RTEMS_TIMEOUT;
     1305                        return -3;
    13791306                }
    13801307        }
     
    14021329                 * thread.
    14031330                 */
    1404                 rw_args->bytes_moved = count * sizeof(CANMsg);
    1405                 return RTEMS_UNSATISFIED;
     1331                return count;
    14061332        }
    14071333
     
    14141340        }
    14151341        /* no need to unmask IRQ as IRQ Handler do that for us. */
    1416         rw_args->bytes_moved = count * sizeof(CANMsg);
    1417         return RTEMS_SUCCESSFUL;
    1418 }
    1419 
    1420 static rtems_device_driver grcan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
    1421 {
    1422         struct grcan_priv *pDev;
    1423         struct drvmgr_dev *dev;
    1424         rtems_libio_rw_args_t *rw_args;
     1342        return count;
     1343}
     1344
     1345int grcan_write(void *d, CANMsg *msg, size_t ucount)
     1346{
     1347        struct grcan_priv *pDev = d;
    14251348        CANMsg *source;
    14261349        unsigned int count, left;
     
    14291352        DBGC(DBG_TX,"\n");
    14301353
    1431         if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) {
    1432                 return RTEMS_INVALID_NAME;
    1433         }
    1434         pDev = (struct grcan_priv *)dev->priv;
    1435 
    14361354        if ( !pDev->started || pDev->config.silent || pDev->flushing )
    1437                 return RTEMS_RESOURCE_IN_USE;
    1438 
    1439         rw_args = (rtems_libio_rw_args_t *) arg;
    1440         req_cnt = rw_args->count / sizeof(CANMsg);
    1441         source = (CANMsg *) rw_args->buffer;
     1355                return -2;
     1356
     1357        req_cnt = ucount;
     1358        source = (CANMsg *) msg;
    14421359
    14431360        /* check proper length and buffer pointer */
    14441361        if (( req_cnt < 1) || (source == NULL) ){
    1445                 return RTEMS_INVALID_NAME;
     1362                return -1;
    14461363        }
    14471364
     
    14501367                if ( count > 0 ) {
    14511368                        /* Successfully transmitted chars (at least one char) */
    1452                         rw_args->bytes_moved = count * sizeof(CANMsg);
    1453                         return RTEMS_SUCCESSFUL;
     1369                        return count;
    14541370                }
    14551371
     
    14571373                if ( !pDev->txblock ) {
    14581374                        /* non-blocking mode */
    1459                         rw_args->bytes_moved = 0;
    1460                         return RTEMS_TIMEOUT;
     1375                        return -3;
    14611376                }
    14621377        }
     
    14891404                         * with error status.
    14901405                         */
    1491                         rw_args->bytes_moved = count * sizeof(CANMsg);
    1492                         return RTEMS_UNSATISFIED;
     1406                        return count;
    14931407                }
    14941408
     
    15101424        /* no need to unmask IRQ as IRQ Handler do that for us. */
    15111425
    1512         rw_args->bytes_moved = count * sizeof(CANMsg);
    1513         return RTEMS_SUCCESSFUL;
    1514 }
    1515 
    1516 static rtems_device_driver grcan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
    1517 {
    1518         struct grcan_priv *pDev;
    1519         struct drvmgr_dev *dev;
    1520         rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
    1521         unsigned int *data = ioarg->buffer;
     1426        return count;
     1427}
     1428
     1429int grcan_start(void *d)
     1430{
     1431        struct grcan_priv *pDev = d;
     1432        rtems_device_driver status;
     1433
     1434        FUNCDBG();
     1435
     1436        if ( pDev->started )
     1437                return -1;
     1438
     1439        if ( (status=grcan_hw_start(pDev)) != RTEMS_SUCCESSFUL ){
     1440                return -2;
     1441        }
     1442
     1443        /* Read and write are now open... */
     1444        pDev->started = 1;
     1445
     1446        /* Register interrupt routine and enable IRQ at IRQ ctrl */
     1447        drvmgr_interrupt_register(pDev->dev, 0, "grcan", grcan_interrupt, pDev);
     1448
     1449        return 0;
     1450}
     1451
     1452int grcan_stop(void *d)
     1453{
     1454        struct grcan_priv *pDev = d;
     1455
     1456        FUNCDBG();
     1457
     1458        if ( !pDev->started )
     1459                return -1;
     1460
     1461        /* Disable interrupts */
     1462        drvmgr_interrupt_unregister(pDev->dev, 0, grcan_interrupt, pDev);
     1463
     1464        grcan_hw_stop(pDev);
     1465        pDev->started = 0;
     1466
     1467        return 0;
     1468}
     1469
     1470int grcan_isstarted(void *d)
     1471{
     1472        struct grcan_priv *pDev = d;
     1473
     1474        FUNCDBG();
     1475
     1476        return pDev->started;
     1477}
     1478
     1479int grcan_flush(void *d)
     1480{
     1481        struct grcan_priv *pDev = d;
     1482        int tmp;
     1483
     1484        FUNCDBG();
     1485
     1486        if ( !pDev->started || pDev->flushing || pDev->config.silent )
     1487                return -1;
     1488
     1489        pDev->flushing = 1;
     1490        tmp = grcan_tx_flush(pDev);
     1491        pDev->flushing = 0;
     1492        if ( tmp ) {
     1493                /* The wait has been aborted, probably due to
     1494                 * the device driver has been closed by another
     1495                 * thread.
     1496                 */
     1497                return -1;
     1498        }
     1499
     1500        return 0;
     1501}
     1502
     1503int grcan_set_silent(void* d, int silent)
     1504{
     1505        struct grcan_priv *pDev = d;
     1506
     1507        FUNCDBG();
     1508
     1509        if ( pDev->started )
     1510                return -1;
     1511
     1512        pDev->config.silent = silent;
     1513        pDev->config_changed = 1;
     1514
     1515        return 0;
     1516}
     1517
     1518int grcan_set_abort(void* d, int abort)
     1519{
     1520        struct grcan_priv *pDev = d;
     1521
     1522        FUNCDBG();
     1523
     1524        if ( pDev->started )
     1525                return -1;
     1526
     1527        pDev->config.abort = abort;
     1528        /* This Configuration parameter doesn't need HurriCANe reset
     1529         * ==> no pDev->config_changed = 1;
     1530         */
     1531
     1532        return 0;
     1533}
     1534
     1535int grcan_set_selection(void *d, const struct grcan_selection *selection)
     1536{
     1537        struct grcan_priv *pDev = d;
     1538
     1539        FUNCDBG();
     1540
     1541        if ( pDev->started )
     1542                return -1;
     1543
     1544        if ( !selection )
     1545                return -2;
     1546
     1547        pDev->config.selection = *selection;
     1548        pDev->config_changed = 1;
     1549
     1550        return 0;
     1551}
     1552
     1553int grcan_set_rxblock(void *d, int block)
     1554{
     1555        struct grcan_priv *pDev = d;
     1556
     1557        FUNCDBG();
     1558
     1559        pDev->rxblock = block;
     1560
     1561        return 0;
     1562}
     1563
     1564int grcan_set_txblock(void *d, int block)
     1565{
     1566        struct grcan_priv *pDev = d;
     1567
     1568        FUNCDBG();
     1569
     1570        pDev->txblock = block;
     1571
     1572        return 0;
     1573}
     1574
     1575int grcan_set_txcomplete(void *d, int complete)
     1576{
     1577        struct grcan_priv *pDev = d;
     1578
     1579        FUNCDBG();
     1580
     1581        pDev->txcomplete = complete;
     1582
     1583        return 0;
     1584}
     1585
     1586int grcan_set_rxcomplete(void *d, int complete)
     1587{
     1588        struct grcan_priv *pDev = d;
     1589
     1590        FUNCDBG();
     1591
     1592        pDev->rxcomplete = complete;
     1593
     1594        return 0;
     1595}
     1596
     1597int grcan_get_stats(void *d, struct grcan_stats *stats)
     1598{
     1599        struct grcan_priv *pDev = d;
     1600
     1601        FUNCDBG();
     1602
     1603        if ( !stats )
     1604                return -1;
     1605
     1606        *stats = pDev->stats;
     1607
     1608        return 0;
     1609}
     1610
     1611int grcan_clr_stats(void *d)
     1612{
     1613        struct grcan_priv *pDev = d;
     1614        IRQ_GLOBAL_PREPARE(oldLevel);
     1615
     1616        FUNCDBG();
     1617
     1618        IRQ_GLOBAL_DISABLE(oldLevel);
     1619        memset(&pDev->stats,0,sizeof(struct grcan_stats));
     1620        IRQ_GLOBAL_ENABLE(oldLevel);
     1621
     1622        return 0;
     1623}
     1624
     1625int grcan_set_speed(void *d, unsigned int speed)
     1626{
     1627        struct grcan_priv *pDev = d;
    15221628        struct grcan_timing timing;
    1523         unsigned int speed;
    1524         struct grcan_selection *selection;
    1525         int tmp,ret;
    1526         rtems_device_driver status;
    1527         struct grcan_stats *stats;
    1528         struct grcan_filter *filter;
    1529         IRQ_GLOBAL_PREPARE(oldLevel);
    1530 
    1531         FUNCDBG();
    1532 
    1533         if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) {
    1534                 return RTEMS_INVALID_NAME;
    1535         }
    1536         pDev = (struct grcan_priv *)dev->priv;
    1537 
    1538         if (!ioarg)
    1539                 return RTEMS_INVALID_NAME;
    1540 
    1541         ioarg->ioctl_return = 0;
    1542         switch(ioarg->command) {
    1543                 case GRCAN_IOC_START:
    1544                 if ( pDev->started )
    1545                         return RTEMS_RESOURCE_IN_USE; /* EBUSY */
    1546 
    1547                 if ( (status=grcan_start(pDev)) != RTEMS_SUCCESSFUL ){
    1548                         return status;
    1549                 }
    1550                 /* Read and write are now open... */
    1551                 pDev->started = 1;
    1552 
    1553                 /* Register interrupt routine and enable IRQ at IRQ ctrl */
    1554                 drvmgr_interrupt_register(dev, 0, "grcan", grcan_interrupt, pDev);
    1555 
    1556                 break;
    1557 
    1558                 case GRCAN_IOC_STOP:
    1559                 if ( !pDev->started )
    1560                         return RTEMS_RESOURCE_IN_USE;
    1561 
    1562                 /* Disable interrupts */
    1563                 drvmgr_interrupt_unregister(dev, 0, grcan_interrupt, pDev);
    1564 
    1565                 grcan_stop(pDev);
    1566                 pDev->started = 0;
    1567                 break;
    1568 
    1569                 case GRCAN_IOC_ISSTARTED:
    1570                 if ( !pDev->started )
    1571                         return RTEMS_RESOURCE_IN_USE;
    1572                 break;
    1573 
    1574                 case GRCAN_IOC_FLUSH:
    1575                 if ( !pDev->started || pDev->flushing || pDev->config.silent )
    1576                         return RTEMS_RESOURCE_IN_USE;
    1577 
    1578                 pDev->flushing = 1;
    1579                 tmp = grcan_tx_flush(pDev);
    1580                 pDev->flushing = 0;
    1581                 if ( tmp ) {
    1582                         /* The wait has been aborted, probably due to
    1583                          * the device driver has been closed by another
    1584                          * thread.
    1585                          */
    1586                         return RTEMS_UNSATISFIED;
    1587                 }
    1588                 break;
    1589 
    1590 #if 0
    1591                 /* Set physical link */
    1592                 case GRCAN_IOC_SET_LINK:
    1593 #ifdef REDUNDANT_CHANNELS
    1594                 if ( pDev->started )
    1595                         return RTEMS_RESOURCE_IN_USE; /* EBUSY */
    1596 
    1597                 /* switch HW channel */
    1598                 pDev->channel = (unsigned int)ioargs->buffer;
    1599 #else
    1600                 return RTEMS_NOT_IMPLEMENTED;
    1601 #endif
    1602                 break;
    1603 #endif
    1604 
    1605                 case GRCAN_IOC_SET_SILENT:
    1606                 if ( pDev->started )
    1607                         return RTEMS_RESOURCE_IN_USE;
    1608                 pDev->config.silent = (int)ioarg->buffer;
    1609                 pDev->config_changed = 1;
    1610                 break;
    1611 
    1612                 case GRCAN_IOC_SET_ABORT:
    1613                 if ( pDev->started )
    1614                         return RTEMS_RESOURCE_IN_USE;
    1615                 pDev->config.abort = (int)ioarg->buffer;
    1616                 /* This Configuration parameter doesn't need HurriCANe reset
    1617                  * ==> no pDev->config_changed = 1;
    1618                  */
    1619                 break;
    1620 
    1621                 case GRCAN_IOC_SET_SELECTION:
    1622                 if ( pDev->started )
    1623                         return RTEMS_RESOURCE_IN_USE;
    1624 
    1625                 selection = (struct grcan_selection *)ioarg->buffer;
    1626                 if ( !selection )
    1627                         return RTEMS_INVALID_NAME;
    1628 
    1629                 pDev->config.selection = *selection;
    1630                 pDev->config_changed = 1;
    1631                 break;
    1632 
    1633                 case GRCAN_IOC_SET_RXBLOCK:
    1634                 pDev->rxblock = (int)ioarg->buffer;
    1635                 break;
    1636 
    1637                 case GRCAN_IOC_SET_TXBLOCK:
    1638                 pDev->txblock = (int)ioarg->buffer;
    1639                 break;
    1640 
    1641                 case GRCAN_IOC_SET_TXCOMPLETE:
    1642                 pDev->txcomplete = (int)ioarg->buffer;
    1643                 break;
    1644 
    1645                 case GRCAN_IOC_SET_RXCOMPLETE:
    1646                 pDev->rxcomplete = (int)ioarg->buffer;
    1647                 break;
    1648 
    1649                 case GRCAN_IOC_GET_STATS:
    1650                 stats = (struct grcan_stats *)ioarg->buffer;
    1651                 if ( !stats )
    1652                         return RTEMS_INVALID_NAME;
    1653                 *stats = pDev->stats;
    1654                 break;
    1655 
    1656                 case GRCAN_IOC_CLR_STATS:
    1657                 IRQ_GLOBAL_DISABLE(oldLevel);
    1658                 memset(&pDev->stats,0,sizeof(struct grcan_stats));
    1659                 IRQ_GLOBAL_ENABLE(oldLevel);
    1660                 break;
    1661 
    1662                 case GRCAN_IOC_SET_SPEED:
    1663                 /* cannot change speed during run mode */
    1664                 if ( pDev->started )
    1665                         return RTEMS_RESOURCE_IN_USE; /* EBUSY */
    1666 
    1667                 /* get speed rate from argument */
    1668                 speed = (unsigned int)ioarg->buffer;
    1669                 ret = grcan_calc_timing(speed, pDev->corefreq_hz, GRCAN_SAMPLING_POINT, &timing);
    1670                 if ( ret )
    1671                         return  RTEMS_INVALID_NAME; /* EINVAL */
    1672 
    1673                 /* save timing/speed */
    1674                 pDev->config.timing = timing;
    1675                 pDev->config_changed = 1;
    1676                 break;
    1677 
    1678                 case GRCAN_IOC_SET_BTRS:
    1679                 /* Set BTR registers manually
    1680                  * Read GRCAN/HurriCANe Manual.
    1681                  */
    1682                 if ( pDev->started )
    1683                         return RTEMS_RESOURCE_IN_USE; /* EBUSY */
    1684                 if ( !ioarg->buffer )
    1685                         return RTEMS_INVALID_NAME;
    1686 
    1687                 pDev->config.timing = *(struct grcan_timing *)ioarg->buffer;
    1688                 pDev->config_changed = 1;
    1689                 break;
    1690 
    1691                 case GRCAN_IOC_SET_AFILTER:
    1692                 filter = (struct grcan_filter *)ioarg->buffer;
    1693                 if ( !filter ){
    1694                         /* Disable filtering - let all messages pass */
    1695                         pDev->afilter.mask = 0x0;
    1696                         pDev->afilter.code = 0x0;
    1697                 }else{
    1698                         /* Save filter */
    1699                         pDev->afilter = *filter;
    1700                 }
    1701                 /* Set hardware acceptance filter */     
    1702                 grcan_hw_accept(pDev->regs,&pDev->afilter);
    1703                 break;
    1704 
    1705                 case GRCAN_IOC_SET_SFILTER:
    1706                 filter = (struct grcan_filter *)ioarg->buffer;
    1707                 if ( !filter ){
    1708                         /* disable TX/RX SYNC filtering */
    1709                         pDev->sfilter.mask = 0xffffffff;
    1710                         pDev->sfilter.mask = 0;
    1711 
    1712                          /* disable Sync interrupt */
    1713                         pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
    1714                 }else{
    1715                         /* Save filter */
    1716                         pDev->sfilter = *filter;
    1717 
    1718                         /* Enable Sync interrupt */
    1719                         pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
    1720                 }
    1721                 /* Set Sync RX/TX filter */
    1722                 grcan_hw_sync(pDev->regs,&pDev->sfilter);
    1723                 break;
    1724 
    1725                 case GRCAN_IOC_GET_STATUS:
    1726                 if ( !data )
    1727                         return RTEMS_INVALID_NAME;
    1728                 /* Read out the statsu register from the GRCAN core */
    1729                 data[0] = READ_REG(&pDev->regs->stat);
    1730                 break;
    1731 
    1732         default:
    1733                 return RTEMS_NOT_DEFINED;
    1734         }
    1735         return RTEMS_SUCCESSFUL;
     1629        int ret;
     1630
     1631        FUNCDBG();
     1632
     1633        /* cannot change speed during run mode */
     1634        if ( pDev->started )
     1635                return -1;
     1636
     1637        /* get speed rate from argument */
     1638        ret = grcan_calc_timing(speed, pDev->corefreq_hz, GRCAN_SAMPLING_POINT, &timing);
     1639        if ( ret )
     1640                return -2;
     1641
     1642        /* save timing/speed */
     1643        pDev->config.timing = timing;
     1644        pDev->config_changed = 1;
     1645
     1646        return 0;
     1647}
     1648
     1649int grcan_set_btrs(void *d, const struct grcan_timing *timing)
     1650{
     1651        struct grcan_priv *pDev = d;
     1652
     1653        FUNCDBG();
     1654
     1655        /* Set BTR registers manually
     1656         * Read GRCAN/HurriCANe Manual.
     1657         */
     1658        if ( pDev->started )
     1659                return -1;
     1660
     1661        if ( !timing )
     1662                return -2;
     1663
     1664        pDev->config.timing = *timing;
     1665        pDev->config_changed = 1;
     1666
     1667        return 0;
     1668}
     1669
     1670int grcan_set_afilter(void *d, const struct grcan_filter *filter)
     1671{
     1672        struct grcan_priv *pDev = d;
     1673
     1674        FUNCDBG();
     1675
     1676        if ( !filter ){
     1677                /* Disable filtering - let all messages pass */
     1678                pDev->afilter.mask = 0x0;
     1679                pDev->afilter.code = 0x0;
     1680        }else{
     1681                /* Save filter */
     1682                pDev->afilter = *filter;
     1683        }
     1684        /* Set hardware acceptance filter */
     1685        grcan_hw_accept(pDev->regs,&pDev->afilter);
     1686
     1687        return 0;
     1688}
     1689
     1690int grcan_set_sfilter(void *d, const struct grcan_filter *filter)
     1691{
     1692        struct grcan_priv *pDev = d;
     1693
     1694        FUNCDBG();
     1695
     1696        if ( !filter ){
     1697                /* disable TX/RX SYNC filtering */
     1698                pDev->sfilter.mask = 0xffffffff;
     1699                pDev->sfilter.mask = 0;
     1700
     1701                 /* disable Sync interrupt */
     1702                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
     1703        }else{
     1704                /* Save filter */
     1705                pDev->sfilter = *filter;
     1706
     1707                /* Enable Sync interrupt */
     1708                pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
     1709        }
     1710        /* Set Sync RX/TX filter */
     1711        grcan_hw_sync(pDev->regs,&pDev->sfilter);
     1712
     1713        return 0;
     1714}
     1715
     1716int grcan_get_status(void* d, unsigned int *data)
     1717{
     1718        struct grcan_priv *pDev = d;
     1719
     1720        FUNCDBG();
     1721
     1722        if ( !data )
     1723                return -1;
     1724
     1725        /* Read out the statsu register from the GRCAN core */
     1726        data[0] = READ_REG(&pDev->regs->stat);
     1727
     1728        return 0;
    17361729}
    17371730
     
    17641757                 */
    17651758                pDev->started = 0;
    1766                 grcan_stop(pDev); /* this mask all IRQ sources */
     1759                grcan_hw_stop(pDev); /* this mask all IRQ sources */
    17671760                status=0x1ffff; /* clear all interrupts */
    17681761                goto out;
  • c/src/lib/libbsp/sparc/shared/include/grcan.h

    r229c4249 rad203e58  
    157157#define GRCAN_STAT_TXERRCNT  0xff0000
    158158
    159 /* IOCTL Commands controlling operational
     159/*
     160 * Return number of GRCAN devices available to driver
     161 */
     162extern int grcan_dev_count(void);
     163
     164/*
     165 * Open a GRCAN device
     166 *
     167 * dev_no:      Device number to open
     168 * return:      Device handle to use with all other grcan_ API functions. The
     169 *              function returns NULL if device can not be opened.
     170 */
     171extern void *grcan_open(int dev_no);
     172
     173/*
     174 * Close a GRCAN device
     175 *
     176 * return: This function always returns 0 (success)
     177 */
     178extern int grcan_close(void *d);
     179
     180/*
     181 * Receive CAN messages
     182 *
     183 * Multiple CAN messages can be received in one call.
     184 *
     185 * d: Device handle
     186 * msg: Pointer to receive messages
     187 * count: Number of CAN messages to receive
     188 *
     189 * return:
     190 *   >=0:       Number of CAN messages received. This can be less than the
     191 *              count parameter.
     192 *   -1:        count parameter less than size of struct grcan_msg or NULL msg.
     193 *   -2:        Device not in started mode
     194 *   -3:        Timeout in non-blocking mode
     195 *   -4:        A blocking read was interrupted by a Bus-off error. Device has
     196 *              left started mode.
     197 */
     198extern int grcan_read(
     199        void *d,
     200        CANMsg *msg,
     201        size_t count
     202);
     203
     204/*
     205 * Transmit CAN messages
     206 *
     207 * Multiple CAN messages can be transmit in one call.
     208 *
     209 * d: Device handle
     210 * msg: Pointer to messages to transmit
     211 * count: Number of CAN messages to transmit
     212 *
     213 * return:
     214 *   >=0:       Number of CAN messages transmitted. This can be less than the
     215 *              count parameter.
     216 *   -1:        count parameter less than size of struct grcan_msg
     217 *   -2:        Device not in started mode
     218 *   -3:        Timeout in non-blocking mode
     219 *   -4:        Bus-off error. Device has left started mode
     220 */
     221extern int grcan_write(
     222        void *d,
     223        CANMsg *msg,
     224        size_t count
     225);
     226
     227/* The remaining functions return 0 on success and non-zero on failure. */
     228
     229/* Functions controlling operational
    160230 * mode
    161231 */
    162 #define GRCAN_IOC_START          1   /* Bring the link up after open or bus-off */
    163 #define GRCAN_IOC_STOP           2   /* stop to change baud rate/config or closing down */
    164 #define GRCAN_IOC_ISSTARTED      3   /* return RTEMS_SUCCESSFUL when started, othervise EBUSY */
    165 #define GRCAN_IOC_FLUSH          4   /* Waits until all TX messages has been sent */
    166 
    167 /* IOCTL Commands that require connection
     232/* Bring the link up after open or bus-off */
     233extern int grcan_start(void *d);
     234/* stop to change baud rate/config or closing down */
     235extern int grcan_stop(void *d);
     236/* return 1 when started, othervise 0 */
     237extern int grcan_isstarted(void *d);
     238/* Wait until all TX messages have been sent */
     239extern int grcan_flush(void *d);
     240
     241/* Functions that require connection
    168242 * to be stopped
    169243 */
    170 #define GRCAN_IOC_SET_SILENT     16  /* enable silent mode read only state */
    171 #define GRCAN_IOC_SET_ABORT      17  /* enable/disable stopping link on AHB Error */
    172 #define GRCAN_IOC_SET_SELECTION  18  /* Set Enable0,Enable1,Selection */
    173 #define GRCAN_IOC_SET_SPEED      19  /* Set baudrate by using driver's baud rate timing calculation routines */
    174 #define GRCAN_IOC_SET_BTRS       20  /* Set baudrate by specifying the timing registers manually */
    175 
    176 /* IOCTL Commands can be called whenever */
    177 #define GRCAN_IOC_SET_RXBLOCK    32  /* Enable/disable Blocking on reception (until at least one message has been received) */
    178 #define GRCAN_IOC_SET_TXBLOCK    33  /* Enable/disable Blocking on transmission (until at least one message has been transmitted) */
    179 #define GRCAN_IOC_SET_TXCOMPLETE 34  /* Enable/disable Blocking until all requested messages has been sent */
    180 #define GRCAN_IOC_SET_RXCOMPLETE 35  /* Enable/disable Blocking until all requested has been received */
    181 #define GRCAN_IOC_GET_STATS      36  /* Get Statistics */
    182 #define GRCAN_IOC_CLR_STATS      37  /* Clear Statistics */
    183 #define GRCAN_IOC_SET_AFILTER    38  /* Set Acceptance filters, provide pointer to "struct grcan_filter" or NULL to disable filtering (let all messages pass) */
    184 #define GRCAN_IOC_SET_SFILTER    40  /* Set Sync Messages RX/TX filters, NULL disables the IRQ completely */
    185 #define GRCAN_IOC_GET_STATUS     41  /* Get status register of GRCAN core */
    186 
     244/* enable silent mode read only state */
     245extern int grcan_set_silent(void *d, int silent);
     246/* enable/disable stopping link on AHB Error */
     247extern int grcan_set_abort(void *d, int abort);
     248/* Set Enable0,Enable1,Selection */
     249extern int grcan_set_selection(void *d, const struct grcan_selection *selection);
     250/* Set baudrate by using driver's baud rate timing calculation routines */
     251extern int grcan_set_speed(void *d, unsigned int hz);
     252/* Set baudrate by specifying the timing registers manually */
     253extern int grcan_set_btrs(void *d, const struct grcan_timing *timing);
     254
     255/* Functions can be called whenever */
     256/* Enable/disable Blocking on reception (until at least one message has been received) */
     257int grcan_set_rxblock(void* d, int block);
     258/* Enable/disable Blocking on transmission (until at least one message has been transmitted) */
     259int grcan_set_txblock(void* d, int block);
     260/* Enable/disable Blocking until all requested messages has been sent */
     261int grcan_set_txcomplete(void* d, int complete);
     262/* Enable/disable Blocking until all requested has been received */
     263int grcan_set_rxcomplete(void* d, int complete);
     264/* Get statistics */
     265extern int grcan_get_stats(void *d, struct grcan_stats *stats);
     266/* Clear statistics */
     267extern int grcan_clr_stats(void *d);
     268/* Set Acceptance filters, provide pointer to "struct grcan_filter" or NULL to disable filtering (let all messages pass) */
     269extern int grcan_set_afilter(void *d, const struct grcan_filter *filter);
     270/* Set Sync Messages RX/TX filters, NULL disables the IRQ completely */
     271extern int grcan_set_sfilter(void *d, const struct grcan_filter *filter);
     272/* Get status register of GRCAN core */
     273extern int grcan_get_status(void *d, unsigned int *status);
    187274
    188275void grcan_register_drv(void);
Note: See TracChangeset for help on using the changeset viewer.