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

📄 pcan_main.c

📁 CAN 驱动编程
💻 C
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************// Copyright (C) 2001,2002,2003  PEAK System-Technik GmbH//// linux@peak-system.com// www.peak-system.com//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.//// Maintainer(s): Klaus Hitschler (klaus.hitschler@gmx.de)//****************************************************************************//****************************************************************************//// pcan_main.c - the starting point of the driver, //               init and cleanup and proc interface//// $Log: pcan_main.c,v $// Revision 1.50  2003/03/02 12:18:33  klaus// Release_20030302_?//// Revision 1.49  2003/03/02 12:18:33  klaus// Release_20030302_?//// Revision 1.48  2003/03/02 10:45:52  klaus// resolved conflict while merging USB thread//// Revision 1.46.2.26  2003/02/25 20:22:42  klaus// Release_20030225_?//// Revision 1.47  2003/01/17 20:38:13  klaus// wrong re-update of pcan_main.c, try to repair//// Revision 1.46  2002/12/01 17:51:09  klaus// minor improvement of code//// Revision 1.46.2.25  2003/02/16 19:55:52  klaus// USB Integration, first non public release//// Revision 1.46.2.24  2003/02/16 16:36:16  klaus// pcan_usb_kernel.c returned to main modules//// Revision 1.46.2.23  2003/02/09 10:29:20  klaus// code cleanup, Release_20030208_x//// Revision 1.46.2.22  2003/02/08 17:32:43  klaus// modified to use pcan_usb_kernel as prorietary module//// Revision 1.46.2.21  2003/01/29 20:34:20  klaus// release_20030129_a and release_20030129_u released//// Revision 1.46.2.20  2003/01/29 20:34:20  klaus// release_20030129_a and release_20030129_u released//// Revision 1.46.2.19  2003/01/28 23:28:26  klaus// reorderd pcan_usb.c and pcan_usb_kernel.c, tidied up//// Revision 1.46.2.18  2003/01/26 22:35:39  klaus// it's not allowed to invoke 2 waits for bulk transfer at the same pipe at the same time////****************************************************************************//****************************************************************************// INCLUDES#include <src/pcan_common.h>     // must always be the 1st include#include <linux/config.h>#include <linux/kernel.h>   // DPRINTK()#include <linux/slab.h>     // kmalloc()#include <linux/fs.h>       // everything...#include <linux/errno.h>    // error codes#include <linux/types.h>    // size_t#include <linux/proc_fs.h>  // proc #include <linux/fcntl.h>    // O_ACCMODE#include <linux/pci.h>      // all about pci#include <linux/capability.h> // all about restrictions#include <linux/param.h>    // because of HZ#include <asm/system.h>     // cli(), *_flags#include <asm/uaccess.h>    // copy_...#include <asm/timex.h>      // get_mtime()#include <pcan.h>#include <src/pcan_main.h>#include <src/pcan_pci.h>#include <src/pcan_isa.h>#include <src/pcan_dongle.h>#ifdef USB_SUPPORT#include <src/pcan_usb.h>#endif#include <src/pcan_fops.h>#include <src/pcan_fifo.h>#include <src/pcan_sja1000.h>//****************************************************************************// DEFINES//----------------------------------------------------------------------------// set here the current release of the driver 'Release_date_nr' synchronoes// with CVS until we have managed that CVS does it itself#ifdef USB_SUPPORT#define CURRENT_RELEASE "*Name: Release_20030202_u *"  // $name:  $#else#define CURRENT_RELEASE "*Name: Release_20030302_a *"  // $name:  $#endif#define DEFAULT_BTR0BTR1    CAN_BAUD_500K  // defaults to 500 kbit/sec #define DEFAULT_EXTENDED    1              // catch all frames#define DEFAULT_LISTENONLY  0  //****************************************************************************// GLOBALS// filled by module initialisationchar *type[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};u16  io[8]    = {0, 0, 0, 0, 0, 0, 0, 0};u8   irq[8]   = {0, 0, 0, 0, 0, 0, 0, 0};// the global driver objectstruct driverobj pcan_drv;//****************************************************************************// LOCALS//****************************************************************************// CODE  //****************************************************************************// debug utilityvoid buffer_dump(u8 *pucBuffer, u16 wLineCount){  #ifdef DEBUG  int i, j;  for (i = 0; i < wLineCount; i++)  {    printk(KERN_DEBUG "%s: %04x ", DEVICE_NAME, i * 16);    for (j = 0; j < 8; j++)      printk(" %02x", *pucBuffer++);    printk(" ");    for (j = 0; j < 8; j++)      printk(" %02x", *pucBuffer++);    printk("\n");  }  #endif}//----------------------------------------------------------------------------// request time in msec, may be it becomes more sophisticated in futureu32 get_mtime(void){  return jiffies * (1000 / HZ);}//----------------------------------------------------------------------------// is called when 'cat /proc/pcan' invokedstatic int pcan_read_procmem(char *page, char **start, off_t offset, int count, int *eof, void *data){  struct pcandev *dev;  struct list_head *ptr;  int    len = 0;    DPRINTK(KERN_DEBUG "%s: pcan_read_procmem()\n", DEVICE_NAME);  len += sprintf(page + len, "\n");  len += sprintf(page + len, "*--------- PEAK-Systems CAN interfaces (www.peak-system.com) ----------\n");  len += sprintf(page + len, "*-------------------  %s  --------------------\n", pcan_drv.szVersionString);  len += sprintf(page + len, "*------------------ %d interfaces @ major %03d found --------------------\n",                      pcan_drv.wDeviceCount, pcan_drv.nMajor);  len += sprintf(page + len, "*n typ ---base--- ir ---read--- ---write-- ---irqs--- ---error-- status\n");    // loop trough my devices  for (ptr = pcan_drv.devices.next; ptr != &pcan_drv.devices; ptr = ptr->next)  {    u32 dwPort = 0;    u16 wIrq   = 0;        dev = (struct pcandev *)ptr;      switch (dev->wType)    {      case HW_ISA_SJA:        dwPort = dev->port.isa.dwPort;        wIrq   = dev->port.isa.wIrq;        break;      case HW_DONGLE_SJA:      case HW_DONGLE_SJA_EPP:        dwPort = dev->port.dng.dwPort;        wIrq   = dev->port.dng.wIrq;        break;      case HW_PCI:        dwPort = dev->port.pci.dwPort;        wIrq   = dev->port.pci.wIrq;        break;      case HW_USB:        #ifdef USB_SUPPORT        // get serial number of device        if (!dev->ucPhysicallyInstalled)        {          dev->port.usb.dwSerialNumber   = 0x00dead00;  // it is dead          dev->port.usb.ucHardcodedDevNr = 0;        }        else        {          if (pcan_usb_getSerialNumber(dev))          dev->port.usb.dwSerialNumber = 0;        }        dwPort = dev->port.usb.dwSerialNumber;        wIrq   = dev->port.usb.ucHardcodedDevNr;        #endif        break;    }          len += sprintf(page + len, "%2d %3s 0x%08x %2d 0x%08x 0x%08x 0x%08x 0x%08x 0x%04x\n",                         dev->nMinor, dev->type, dwPort, wIrq,  			                           dev->readFifo.dwTotal, dev->writeFifo.dwTotal, dev->dwInterruptCounter, 						                           dev->dwErrorCounter, dev->wCANStatus);   }    len += sprintf(page + len, "\n");    *eof = 1;  return len;}//----------------------------------------------------------------------------// is called when the device is removed 'rmmod pcan'void cleanup_module(void){  struct pcandev *dev;    DPRINTK(KERN_DEBUG "%s: cleanup_module()\n", DEVICE_NAME);  switch (pcan_drv.wInitStep)  {    case 3: remove_proc_entry(DEVICE_NAME, NULL);    case 2: unregister_chrdev(pcan_drv.nMajor, DEVICE_NAME);    case 1:     case 0:             #ifdef USB_SUPPORT            pcan_usb_deinit();            #endif            while (!list_empty(&pcan_drv.devices)) // cycle through the list of devices and remove them            {              dev = (struct pcandev *)pcan_drv.devices.prev; // empty in reverse order              dev->cleanup(dev);              list_del(&dev->list);	            		          // free all device allocted memory               kfree(dev);            }        	          pcan_drv.wInitStep = 0;	}	  printk(KERN_INFO "%s: removed.\n", DEVICE_NAME);}//----------------------------------------------------------------------------// init some equal parts of devvoid pcan_soft_init(struct pcandev *dev, char *szType, u16 wType){  dev->wType            = wType;  dev->type             = szType; 	        dev->nOpenPaths       = 0;  dev->nLastError       = 0;  dev->dwErrorCounter   = 0;  dev->dwInterruptCounter = 0;  dev->wCANStatus       = 0;  dev->pdwInitTime      = &pcan_drv.dwInitTime;  dev->bExtended        = 1;   // accept all frames  dev->wBTR0BTR1        = DEFAULT_BTR0BTR1;  dev->ucCANMsgType     = DEFAULT_EXTENDED;  dev->ucListenOnly     = DEFAULT_LISTENONLY;  // set default access functions - only USB overrides  dev->device_open      = sja1000_open;  dev->device_release   = sja1000_release;  dev->device_write     = sja1000_write;  dev->ucPhysicallyInstalled = 0;  // assume the device is not installed  atomic_set(&dev->DataSendReady, 1);  // init fifos  pcan_fifo_init(&dev->readFifo,   &dev->rMsg[0], &dev->rMsg[READ_MESSAGE_COUNT - 1],  READ_MESSAGE_COUNT,  sizeof(TPCANRdMsg));  pcan_fifo_init(&dev->writeFifo,  &dev->wMsg[0], &dev->wMsg[WRITE_MESSAGE_COUNT - 1], WRITE_MESSAGE_COUNT, sizeof(TPCANMsg) );}

⌨️ 快捷键说明

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