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

📄 util.c

📁 can4linux-3.5.3.gz can4 linux
💻 C
字号:
/* * can4linux -- LINUX CAN device driver source * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * *  * derived from the the LDDK can4linux version *     (c) 1996,1997 Claus Schroeter (clausi@chemie.fu-berlin.de) * *------------------------------------------------------------------ * $Header: /z2/cvsroot/products/0530/software/can4linux/src/util.c,v 1.10 2008/11/23 12:05:30 oe Exp $ * *-------------------------------------------------------------------------- * * * */#include <linux/sched.h> #include <linux/proc_fs.h>#include <linux/pci.h>#include <linux/spinlock.h>#include "defs.h"/* * Refuse to compile under versions older than 1.99.4 */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)#  error "This module needs Linux 2.4 or newer"#endif/* each CAN channel has one wait_queue for read and one for write */wait_queue_head_t CanWait[MAX_CHANNELS][CAN_MAX_OPEN];wait_queue_head_t CanOutWait[MAX_CHANNELS];spinlock_t write_splock[MAX_CHANNELS];/* Flag for the ISR, which read queue is in use */int CanWaitFlag[MAX_CHANNELS][CAN_MAX_OPEN] = {{0}};/* for each CAN channel allocate a TX and RX FIFO */msg_fifo_t   Tx_Buf[MAX_CHANNELS] = {{0}};msg_fifo_t   Rx_Buf[MAX_CHANNELS][CAN_MAX_OPEN] = {{{0}}};#ifdef CAN_USE_FILTER    msg_filter_t Rx_Filter[MAX_CHANNELS] = {{0}}; #endif/* used to store always the last frame sent on this channel */canmsg_t     last_Tx_object[MAX_CHANNELS];void __iomem *can_base[MAX_CHANNELS] = {0};	/* ioremapped adresses */unsigned int can_range[MAX_CHANNELS] = {0};	/* ioremapped adresses *//* flag indicating that selfreception of frames is allowed */int selfreception[MAX_CHANNELS][CAN_MAX_OPEN] = {{0}};int use_timestamp[MAX_CHANNELS] = {0};	/* flag indicating that timestamp 				       value should assigned to rx messages */int wakeup[MAX_CHANNELS] = {0};		/* flag indicating that sleeping				    processes are waken up in case of events *//*initialize RX Fifo*/int Can_RxFifoInit(int minor, int fifo){    DBGin();    /* printk("Can_RxFifoInit minor %d, fifo %d\n", minor, fifo); */	Rx_Buf[minor][fifo].head   = 0;	Rx_Buf[minor][fifo].tail   = 0;	Rx_Buf[minor][fifo].status = 0;	Rx_Buf[minor][fifo].active = 0;	init_waitqueue_head(&CanWait[minor][fifo]);	CanWaitFlag[minor][fifo] = 1;    DBGout();    return 0;}/*initialize  TX Fifo*/int Can_TxFifoInit(int minor){int i;    DBGin();        Tx_Buf[minor].head   = 0;        Tx_Buf[minor].tail   = 0;        Tx_Buf[minor].status = 0;        Tx_Buf[minor].active = 0;        for(i = 0; i < MAX_BUFSIZE; i++) {	   Tx_Buf[minor].free[i]  = BUF_EMPTY;        }	init_waitqueue_head(&CanOutWait[minor]);    DBGout();    return 0;}#ifdef CAN_USE_FILTERint Can_FilterInit(int minor){int i;    DBGin();       Rx_Filter[minor].use      = 0;       Rx_Filter[minor].signo[0] = 0;       Rx_Filter[minor].signo[1] = 0;       Rx_Filter[minor].signo[2] = 0;       for(i=0;i<MAX_ID_NUMBER;i++)		  Rx_Filter[minor].filter[i].rtr_response = NULL;    DBGout();    return 0;}int Can_FilterCleanup(int minor){int i;    DBGin();    for(i=0;i<MAX_ID_NUMBER;i++) {	    if( Rx_Filter[minor].filter[i].rtr_response != NULL )		       kfree( Rx_Filter[minor].filter[i].rtr_response);	    Rx_Filter[minor].filter[i].rtr_response = NULL;    }    DBGout();    return 0;}int Can_FilterOnOff(int minor, unsigned on) {    DBGin();       Rx_Filter[minor].use = (on!=0);    DBGout();    return 0;}int Can_FilterMessage(int minor, unsigned message, unsigned enable) {    DBGin();       Rx_Filter[minor].filter[message].enable = (enable!=0);    DBGout();    return 0;}int Can_FilterTimestamp(int minor, unsigned message, unsigned stamp) {    DBGin();       Rx_Filter[minor].filter[message].timestamp = (stamp!=0);    DBGout();    return 0;}int Can_FilterSignal(int minor, unsigned id, unsigned signal) {    DBGin();       if( signal <= 3 )       Rx_Filter[minor].filter[id].signal = signal;    DBGout();    return 0;}int Can_FilterSigNo(int minor, unsigned signo, unsigned signal ) {    DBGin();       if( signal < 3 )       Rx_Filter[minor].signo[signal] = signo;    DBGout();    return 0;}#endif#ifdef CAN_RTR_CONFIGint Can_ConfigRTR( int minor, unsigned message, canmsg_t *Tx ){canmsg_t *tmp;    DBGin();    if( (tmp = kmalloc ( sizeof(canmsg_t), GFP_ATOMIC )) == NULL ){	    DBGprint(DBG_BRANCH,("memory problem"));	    DBGout(); return -1;    }    Rx_Filter[minor].filter[message].rtr_response = tmp;    memcpy( Rx_Filter[minor].filter[message].rtr_response , Tx, sizeof(canmsg_t));	    DBGout(); return 1;    return 0;}int Can_UnConfigRTR( int minor, unsigned message ){canmsg_t *tmp;    DBGin();    if( Rx_Filter[minor].filter[message].rtr_response != NULL ) {	    kfree(Rx_Filter[minor].filter[message].rtr_response);	    Rx_Filter[minor].filter[message].rtr_response = NULL;    }	    DBGout(); return 1;    return 0;}#endif#ifdef DEBUG/* dump_CAN or CAN_dump() which is better ?? */#if CAN4LINUX_PCI#else#endif#include <asm/io.h>#if 1/* simply dump a memory area bytewise for n*16 addresses *//* * adress - start address  * n      - number of 16 byte rows,  * offset - print every n-th byte */void dump_CAN(unsigned long adress, int n, int offset){int i, j;    printk("     CAN at Adress 0x%lx\n", adress);    for(i = 0; i < n; i++) {	printk("     ");	for(j = 0; j < 16; j++) {	    /* printk("%02x ", *ptr++); */	    printk("%02x ", readb((void __iomem *)adress));	    adress += offset;	}	printk("\n");    }}#endif#ifdef CPC_PCI # define REG_OFFSET 4#else# define REG_OFFSET 1#endif/***   Dump the CAN controllers register contents,*   identified by the device minor number to stdout**   Base[minor] should contain the virtual adress*/void can_dump(int minor){int i, j;int index = 0;	for(i = 0; i < 2; i++) {	    printk("0x%04x: ", (unsigned int)Base[minor] + (i * 16));	    for(j = 0; j < 16; j++) {		printk("%02x ",#ifdef  CAN_PORT_IO		inb((int) (Base[minor] + index)) );#else		readb((void __iomem *) (can_base[minor] + index)) );#endif		/* slow_down_io(); */		index += REG_OFFSET;	    }	    printk("\n");	}}#endif#ifdef CAN4LINUX_PCI#if 0/* reset both can controllers on the EMS-W黱sche CPC-PCI Board *//* writing to the control range at BAR1 of the PCI board */void reset_CPC_PCI(unsigned long address){unsigned long ptr = (unsigned long)ioremap(address, 32);    DBGin();    writeb(0x01, (void __iomem *)ptr);}/* check memory region if there is a CAN controller*  assume the controller was resetted before testing **  The check for an avaliable controller is difficult !*  After an Hardware Reset (or power on) the Conroller *  is in the so-called 'BasicCAN' mode.*     we can check for: *         adress  name      value*	    0x00  mode       0x21*           0x02  status     0xc0*           0x03  interrupt  0xe0* Once loaded thr driver switches into 'PeliCAN' mode and things are getting* difficult, because we now have only a 'soft reset' with not so  unique* values. The have to be masked before comparing.*         adress  name       mask   value*	    0x00  mode               *           0x01  command    0xffcan_base[minor]     0x00*           0x02  status     0x37    0x34*           0x03  interrupt  0xfb    0x00**/int controller_available(unsigned long address, int offset){unsigned long ptr = (unsigned long)ioremap(address, 32 * offset);    DBGin();    /* printk("controller_available %ld\n", address); */    /* printk("0x%0x, ", readb(ptr + (2 * offset)) ); */    /* printk("0x%0x\n", readb(ptr + (3 * offset)) ); */    if ( 0x21 == readb((void __iomem *)ptr))  {	/* compare rest values of status and interrupt register */	if(   0x0c == readb((void __iomem *)ptr + (2 * offset))	   && 0xe0 == readb((void __iomem *)ptr + (3 * offset)) ) {	    return 1;	} else {	    return 0;	}    } else {	/* may be called after a 'soft reset' in 'PeliCAN' mode */	/*   value     address                     mask    */	if(   0x00 ==  readb((void __iomem *)ptr + (1 * offset))	   && 0x34 == (readb((void __iomem *)ptr + (2 * offset))    & 0x37)	   && 0x00 == (readb((void __iomem *)ptr + (3 * offset))    & 0xfb)	  ) {	return 1;    } else {	return 0;    }    }}#endif#endif/*----------------------------------------------------------------------------*//*----------------------------------------------------------------------------*//*----------------------------------------------------------------------------*/

⌨️ 快捷键说明

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