⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 open.c

📁 HMS30C7202下的CAN驱动
💻 C
字号:
/** open.c * * Written by Sebastian Stolzenberg email:stolzi@sebastian-stolzenberg.de * Version 1.0  04 Feb 2003 */#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#include <linux/module.h>#include "../include/candrv.h"#include "../include/hms30c7202_can.h"#include "../include/c_can.h"#include "../include/irq.h"////////////////////////////////////////////////////////////////////////////////* * can_open * * Open function called by user through device file. * It activates one message object of the C_CAN chip and configures it to * to receive messages with id=0 (can be changed through ioctl). */int can_open( struct inode *inode, struct file *filp ){        int i,j;        struct msgobj_t *pmsgobj = NULL;#ifdef CAN_DEBUG        u32 intCntrVAddr = 0;#endif        /* Find the related msg object for this minor */        for ( i = 0; i<pghw->cnt_tot_chips; i++ ) {                for ( j = 0; j<pghw->pchip[ i ]->obj_cnt; j++ ) {                        if ( pghw->pchip[ i ]->pmsgobj[ j ]->minor ==                                MINOR( filp->f_dentry->d_inode->i_rdev )) {                                /* We have a match */                                if ( NULL != ( pmsgobj = pghw->pchip[ i ]->pmsgobj[ j ] ))                                        filp->private_data = pmsgobj;                                break;                        }                }        }        /* Check that we have a valid pointer to           the message object info structure */        if ( NULL == pmsgobj ) {                CANMSG("There is no hardware support for the device file with minor nr.: %d",                       MINOR( filp->f_dentry->d_inode->i_rdev ) );                return -ENODEV;        }        /* Check to see if the message object already has been opened. */        if ( pmsgobj->flags & CHANNEL_OPENED ) {                CANMSG("Sorry, only single open per device file.");                return -EBUSY;        }        DEBUGMSG("Opening device with minor %d", pmsgobj->minor);        DEBUGMSG("Object Number %d of its chip", pmsgobj->object);        /* *** We need to claim hardware to open the device ***         *         * Request I/O for the chip if it hasn't been done before */        if ( pmsgobj->hostchip->active_obj_cnt < 1 ) {                DEBUGMSG("Configuring the Hostchip of this message object");                if ( pmsgobj->hostchip->request_io( pmsgobj->hostchip ))                        return -ENODEV;                pmsgobj->hostchip->active_obj_cnt++;                /* Reset chip */                if ( pmsgobj->hostchip->reset( pmsgobj->hostchip )) {                        pmsgobj->hostchip->release_io( pmsgobj->hostchip );                        pmsgobj->hostchip->active_obj_cnt--;                        return -ENODEV;                }                /* Initialize statistics block */                pmsgobj->hostchip->stat.cntRxPkt = 0;                pmsgobj->hostchip->stat.cntRxData = 0;                pmsgobj->hostchip->stat.cntTxPkt = 0;                pmsgobj->hostchip->stat.cntTxData = 0;                pmsgobj->hostchip->stat.cntWarnings = 0;                pmsgobj->hostchip->stat.cntErrPassive = 0;                pmsgobj->hostchip->stat.cntBusOff = 0;                pmsgobj->hostchip->stat.cntMsgLst = 0;                pmsgobj->hostchip->stat.cntRxFifoOvr = 0;                pmsgobj->hostchip->stat.cntTxFifoOvr = 0;                pmsgobj->hostchip->stat.cntStuffErr = 0;                pmsgobj->hostchip->stat.cntFormErr = 0;                pmsgobj->hostchip->stat.cntAckErr = 0;                pmsgobj->hostchip->stat.cntBit0Err = 0;                pmsgobj->hostchip->stat.cntBit1Err = 0;                pmsgobj->hostchip->stat.cntCrcErr = 0;                DEBUGMSG("Initializing Spinlocks");                /* Initialize read & write fifo spinlock's */                spin_lock_init( &pmsgobj->hostchip->spwlock );                spin_lock_init( &pmsgobj->hostchip->sprlock );                spin_lock_init( &pmsgobj->hostchip->if1lock );                spin_lock_init( &pmsgobj->hostchip->if2lock );                /* Configure the device */                if ( pmsgobj->hostchip->flags & CHANNEL_CONFIGURED )                        DEBUGMSG("Device is already configured.");                else {                        if ( pmsgobj->hostchip->chip_config( pmsgobj->hostchip )) {                                CANMSG("Error configuring chip.");                                /* Release I/O */                                pmsgobj->hostchip->release_io( pmsgobj->hostchip );                                pmsgobj->hostchip->flags &= ~CHANNEL_OPENED;                                pmsgobj->hostchip->active_obj_cnt--;                                return -ENODEV;                        } else {                                DEBUGMSG("Chip configured");                                pmsgobj->hostchip->flags |= CHANNEL_CONFIGURED;                        }                }                /* End of chip configuration */                /* configure interrupts if chip is not run in time trig mode */                if ( ! pmsgobj->hostchip->time_triggered ) {#ifdef CAN_DEBUG                        if ( !( intCntrVAddr = (u32)ioremap( 0x80024000, 0xCD ))) {                                DEBUGMSG("Failed to map Interrupt IO-memory");                                return -ENODEV;                        } else                                DEBUGMSG( "Mapped Interrupt Controller IO-memory: 0x%lx - 0x%lx to 0x%lx",                                        (unsigned long)0X80024000,                                        (unsigned long)0X800240CC,                                        (unsigned long)intCntrVAddr);                        DEBUGMSG("Interrupt Enable Register : 0x%.4lx",(long)readl(intCntrVAddr));#endif                        /* Request irq's */                        DEBUGMSG("Call request_irq(%d,...)",pmsgobj->hostchip->irq);                        if ( request_irq( pmsgobj->hostchip->irq,                                        pmsgobj->hostchip->irq_handler,                                        SA_SHIRQ,                                        DEVICE_NAME,                                        pmsgobj->hostchip )) {                                pmsgobj->hostchip->release_io( pmsgobj->hostchip );                                pmsgobj->hostchip->active_obj_cnt--;                                return -ENODEV;                        }#ifdef CAN_DEBUG                        DEBUGMSG("Interrupt Enable Register : 0x%.4lx",(long)readl(intCntrVAddr));                        iounmap( (void*)intCntrVAddr);                        DEBUGMSG( "Unmapped Interrupt Controller IO-memory: 0x%lx",                                (unsigned long)intCntrVAddr);#endif                        DEBUGMSG("IRQ handler configured. %lx %x",                                (unsigned long)pmsgobj->hostchip, pmsgobj->hostchip->irq );                } else {                        /* start time triggered mode */                        start_time_trig(pmsgobj->hostchip);                }                pmsgobj->hostchip->flags |= CHANNEL_OPENED;        } else {                pmsgobj->hostchip->active_obj_cnt++;        }        DEBUGMSG("Initializing FIFO");        /* Allocate memory for fifo structure */        pmsgobj->fifo=(struct canfifo_t *)kmalloc(sizeof(struct canfifo_t),GFP_KERNEL);        if (pmsgobj->fifo == NULL)                return -ENOMEM;        else                if (add_mem_to_list(pmsgobj->fifo))                        return -ENOMEM;        /* Allocate output buffer memory for the opened device */        pmsgobj->fifo->ptxbuf = (char *)kmalloc( MAX_BUF_LENGTH * sizeof(struct canmsg_t),                                                GFP_KERNEL);        if ( pmsgobj->fifo->ptxbuf == NULL )                return -ENOMEM;        else                if ( add_mem_to_list( pmsgobj->fifo->ptxbuf ) )                        return -ENOMEM;        /* Allocate input buffer memory for the opened device */        pmsgobj->fifo->prxbuf = (char *)kmalloc( MAX_BUF_LENGTH *                                sizeof( struct canmsg_t ), GFP_KERNEL );        if ( pmsgobj->fifo->prxbuf == NULL )                return -ENOMEM;        else                if ( add_mem_to_list( pmsgobj->fifo->prxbuf ) )                        return -ENOMEM;        pmsgobj->flags |= CHANNEL_OPENED;        /* In- and output buffer initialization */        pmsgobj->fifo->txrp = pmsgobj->fifo->ptxbuf;        pmsgobj->fifo->txwp = pmsgobj->fifo->ptxbuf;        pmsgobj->fifo->txsize = MAX_BUF_LENGTH * sizeof( struct canmsg_t );        pmsgobj->fifo->rxrp = pmsgobj->fifo->prxbuf;        pmsgobj->fifo->rxwp = pmsgobj->fifo->prxbuf;        pmsgobj->fifo->rxsize = MAX_BUF_LENGTH * sizeof( struct canmsg_t );        init_waitqueue_head( &pmsgobj->fifo->readq );        init_waitqueue_head( &pmsgobj->fifo->writeq );        /* reset progress bits */        pmsgobj->fifo->flags &= ~ ( RX_IN_PROGRESS | TX_IN_PROGRESS );        /* allow overwriting of read buffer per default */        pmsgobj->fifo->flags |= RD_BUFF_OVRWRT;        pmsgobj->fifo->head = pmsgobj->fifo->tail = 0; //TEMP!!        if ( pmsgobj->hostchip->pre_read_config( pmsgobj, 0 ) < 0 )                CANMSG("Error initializing chip for receiving");        MOD_INC_USE_COUNT;        return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -