📄 pcan_main.c
字号:
//----------------------------------------------------------------------------// 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, "%s\n", config); len += sprintf(page + len, "*--------------------- %d interfaces @ major %03d found -----------------------\n", pcan_drv.wDeviceCount, pcan_drv.nMajor); len += sprintf(page + len, "*n -type- ndev --base-- irq --btr- --read-- --write- --irqs-- -errors- 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; #ifdef NETDEV_SUPPORT struct net_device_stats *stats; /* rx/tx statistics can be found here */ #endif 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; } dwPort = dev->port.usb.dwSerialNumber; wIrq = dev->port.usb.ucHardcodedDevNr; #endif break; case HW_PCCARD: #ifdef PCCARD_SUPPORT dwPort = dev->port.pccard.dwPort; wIrq = dev->port.pccard.wIrq; #endif break; } #ifdef NETDEV_SUPPORT stats = dev->netdev->get_stats(dev->netdev); #endif len += sprintf(page + len, "%2d %6s %4s %08x %03d 0x%04x %08lx %08lx %08x %08x 0x%04x\n", dev->nMinor, dev->type, #ifdef NETDEV_SUPPORT dev->netdev->name, #else "-NA-", #endif dwPort, wIrq, dev->wBTR0BTR1, #ifdef NETDEV_SUPPORT stats->rx_packets, stats->tx_packets + dev->writeFifo.dwTotal, #else (unsigned long)dev->readFifo.dwTotal, (unsigned long)dev->writeFifo.dwTotal, #endif dev->dwInterruptCounter, dev->dwErrorCounter, dev->wCANStatus); } len += sprintf(page + len, "\n"); *eof = 1; return len;}void dev_unregister(void){#ifdef NETDEV_SUPPORT struct list_head *ptr; struct pcandev *pdev; // remove all netdevice registrations except those for USB-devices // which is done by pcan_usb_plugout(). for (ptr = pcan_drv.devices.next; ptr != &pcan_drv.devices; ptr = ptr->next) { pdev = (struct pcandev *)ptr; if (pdev->wType != HW_USB) pcan_netdev_unregister(pdev); }#endif}void remove_dev_list(void){ struct pcandev *dev; 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); }}//----------------------------------------------------------------------------// is called when the device is removed 'rmmod pcan'void cleanup_module(void){ DPRINTK(KERN_DEBUG "%s: cleanup_module()\n", DEVICE_NAME); switch (pcan_drv.wInitStep) { case 3: remove_proc_entry(DEVICE_NAME, NULL); case 2: DEV_UNREGISTER(); case 1: case 0: #ifdef USB_SUPPORT pcan_usb_deinit(); #endif #ifdef PCCARD_SUPPORT pcan_pccard_deinit(); #endif REMOVE_DEV_LIST(); 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->busStatus = CAN_ERROR_ACTIVE; dev->dwErrorCounter = 0; dev->dwInterruptCounter = 0; dev->wCANStatus = 0; dev->bExtended = 1; // accept all frames dev->wBTR0BTR1 = bitrate; dev->ucCANMsgType = DEFAULT_EXTENDED; dev->ucListenOnly = DEFAULT_LISTENONLY; memset(&dev->props, 0, sizeof(dev->props)); // set default access functions dev->device_open = NULL; dev->device_release = NULL; dev->device_write = NULL; #ifdef NETDEV_SUPPORT dev->netdevice_write = NULL; #endif dev->ucPhysicallyInstalled = 0; // assume the device is not installed dev->ucActivityState = ACTIVITY_NONE; 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) );}//----------------------------------------------------------------------------// create all declared Peak legacy devicesstatic int make_legacy_devices(void){ int result = 0; int i; DPRINTK(KERN_DEBUG "%s: make_legacy_devices()\n", DEVICE_NAME); for (i = 0; ((i < 8) && (type[i] != NULL)); i++) { #ifdef ISA_SUPPORT if (!strncmp(type[i], "isa", 4)) result = pcan_create_isa_devices(type[i], io[i], irq[i]); #endif #ifdef DONGLE_SUPPORT if (!strncmp(type[i], "sp", 4) || !strncmp(type[i], "epp", 4)) result = pcan_create_dongle_devices(type[i], io[i], irq[i]); #endif if (result) break; } #ifdef ISA_SUPPORT // create lists of devices with the same irqs ISA_SHARED_IRQ_LISTS(); #endif return result;}//----------------------------------------------------------------------------// is called when the device is installed 'insmod pcan.o' or 'insmod pcan.ko'int init_module(void){ int result = 0; memset(&pcan_drv, 0, sizeof(pcan_drv)); pcan_drv.wInitStep = 0; DO_GETTIMEOFDAY(pcan_drv.sInitTime); // store time for timestamp relation, increments in usec pcan_drv.szVersionString = CURRENT_RELEASE; // get the release name global pcan_drv.nMajor = PCAN_MAJOR; printk(KERN_INFO "%s: %s\n", DEVICE_NAME, pcan_drv.szVersionString); printk(KERN_INFO "%s: driver config%s\n", DEVICE_NAME, current_config); // Copy the centered string only one time and use sizeof() for // compiletime value calculation and optimisation. Also ensure // to have a valid current_config and that it fits into config[] if ((sizeof(current_config) > 3) && (sizeof(config) > sizeof(current_config))) strncpy(config + (sizeof(config)-sizeof(current_config))/2, current_config, sizeof(current_config)-1); INIT_LIST_HEAD(&pcan_drv.devices); pcan_drv.wDeviceCount = 0; #ifdef PCI_SUPPORT // search pci devices if ((result = pcan_search_and_create_pci_devices())) goto fail; #endif // create isa and dongle devices if ((result = make_legacy_devices())) goto fail; #ifdef USB_SUPPORT // register usb devices only if ((result = pcan_usb_register_devices())) goto fail; #endif #ifdef PCCARD_SUPPORT if ((result = pcan_pccard_register_devices())) goto fail; #endif #if !defined USB_SUPPORT && !defined PCCARD_SUPPORT // no device found, stop all if (!pcan_drv.wDeviceCount) goto fail; #endif pcan_drv.wInitStep = 1; result = DEV_REGISTER(); if (result < 0) goto fail; if (!pcan_drv.nMajor) pcan_drv.nMajor = result; pcan_drv.wInitStep = 2; // create the proc entry if (create_proc_read_entry(DEVICE_NAME, 0, NULL, pcan_read_procmem, NULL) == NULL) { result = -ENODEV; // maybe wrong if there is no proc filesystem configured goto fail; } pcan_drv.wInitStep = 3; printk(KERN_INFO "%s: major %d.\n", DEVICE_NAME, pcan_drv.nMajor); return 0; // succeed fail: cleanup_module(); return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -