📄 open.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 + -