📄 pcan_main.c
字号:
//****************************************************************************// 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 + -