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

📄 pcan_main.c

📁 CAN 驱动编程
💻 C
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------------------------------// search all pci based devices from peakstatic int search_and_create_pci_devices(void){  int result = 0;  struct pcandev *dev = NULL;    // search pci devices  DPRINTK(KERN_DEBUG "%s: search_and_create_pci_devices()\n", DEVICE_NAME);  if (pci_present())  {    struct pci_dev *pciDev;        struct pci_dev *from = NULL;    do    {      pciDev = pci_find_device((unsigned int)PCAN_PCI_VENDOR_ID, (unsigned int)PCAN_PCI_DEVICE_ID, from);            if (pciDev != NULL)      {        u16 wSubSysID;	        // a PCI device with PCAN_PCI_VENDOR_ID and PCAN_PCI_DEVICE_ID was found	      from = pciDev;	        	      // get the PCI Subsystem-ID	      result = pci_read_config_word(pciDev, 0x2E, &wSubSysID);	      if (result)	        goto fail;		    // configure the PCI chip, part 1		    result = pci_write_config_word(pciDev, 0x04, 2);		    if (result)		      goto fail;		      		    result = pci_write_config_word(pciDev, 0x44, 0);		    if (result)		      goto fail;		    wmb();		      	      // make the first device on board        if ((dev = (struct pcandev *)kmalloc(sizeof(struct pcandev), GFP_KERNEL)) == NULL)          goto fail;	  	      	      pcan_soft_init(dev, "pci", HW_PCI);	      	      #ifdef LINUX_24	      result = pcan_pci_init(dev, (u32)pciDev->resource[0].start, (u32)pciDev->resource[1].start, 	                                          (u16)pciDev->irq, (wSubSysID > 3) ? CHANNEL_MASTER : CHANNEL_SINGLE, NULL);			  #endif			  			  #ifdef LINUX_22	      result = pcan_pci_init(dev, (u32)pciDev->base_address[0], (u32)pciDev->base_address[1], 	                                          (u16)pciDev->irq, (wSubSysID > 3) ? CHANNEL_MASTER : CHANNEL_SINGLE, NULL);			  #endif			  		    if (!result)		      result = sja1000_probe(dev);        if (result)        {	        dev->cleanup(dev);          kfree(dev);	        goto fail;	      }	      else	      {          dev->ucPhysicallyInstalled = 1;          list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list	        pcan_drv.wDeviceCount++;	      }	        if (wSubSysID > 3)	      {	        struct pcandev *master_dev = dev;			        // make the second device on board          if ((dev = (struct pcandev *)kmalloc(sizeof(struct pcandev), GFP_KERNEL)) == NULL)            goto fail;	  	        pcan_soft_init(dev, "pci", HW_PCI);	      	        #ifdef LINUX_24	        result = pcan_pci_init(dev, (u32)pciDev->resource[0].start, (u32)pciDev->resource[1].start + 0x400, 		                                          (u16)pciDev->irq, CHANNEL_SLAVE, master_dev);					#endif										#ifdef LINUX_22	        result = pcan_pci_init(dev, (u32)pciDev->base_address[0], (u32)pciDev->base_address[1] + 0x400, 		                                          (u16)pciDev->irq, CHANNEL_SLAVE, master_dev);					#endif							      if (!result)		        result = sja1000_probe(dev);          if (result)          {	          dev->cleanup(dev);            kfree(dev);	          goto fail;	        }	        else	        {            dev->ucPhysicallyInstalled = 1;            list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list	          pcan_drv.wDeviceCount++;	        }	        }      }    } while (pciDev != NULL);  }      DPRINTK(KERN_DEBUG "%s: search_and_create_pci_devices() is OK\n", DEVICE_NAME);    fail:  return result;  }//----------------------------------------------------------------------------// create all declared isa devicesstatic int create_isa_devices(void){  int result = 0;  int i;  struct pcandev *dev = NULL;    // create isa devices  DPRINTK(KERN_DEBUG "%s: create_isa_devices()\n", DEVICE_NAME);  for (i = 0; ((i < 8) && (type[i] != NULL)); i++)  {    if (!strncmp(type[i], "isa", 4))    {      if ((dev = (struct pcandev *)kmalloc(sizeof(struct pcandev), GFP_KERNEL)) == NULL)        	goto fail;	      pcan_soft_init(dev, type[i], HW_ISA_SJA);      result = pcan_isa_init(dev, (u32)io[i], (u16)irq[i]);      if (!result)		result = sja1000_probe(dev);      if (result)        {	dev->cleanup(dev);        kfree(dev);	goto fail;	}      else	{        dev->ucPhysicallyInstalled = 1;        list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list	pcan_drv.wDeviceCount++;	}	          }  }    DPRINTK(KERN_DEBUG "%s: create_isa_devices() is OK\n", DEVICE_NAME);    fail:  return result;}//----------------------------------------------------------------------------// create all declared dongle devicesstatic int create_dongle_devices(void){  int result = 0;  int i;  struct pcandev *dev = NULL;    DPRINTK(KERN_DEBUG "%s: create_dongle_devices()\n", DEVICE_NAME);  for (i = 0; ((i < 8) && (type[i] != NULL)); i++)  {    if (!strncmp(type[i], "sp", 4) || !strncmp(type[i], "epp", 4))    {      if ((dev = (struct pcandev *)kmalloc(sizeof(struct pcandev), GFP_KERNEL)) == NULL)        goto fail;			  pcan_soft_init(dev, type[i], (!strncmp(type[i], "sp", 4)) ? HW_DONGLE_SJA : HW_DONGLE_SJA_EPP);		        result = pcan_dongle_init(dev, (u32)io[i], (u16)irq[i], type[i]);      if (result)      {	      dev->cleanup(dev);          kfree(dev);	      goto fail;	    }	    else	    {        list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list	      	      pcan_drv.wDeviceCount++;	    }	          }  }   DPRINTK(KERN_DEBUG "%s: create_dongle_devices() is OK\n", DEVICE_NAME);  fail:  return result; }#ifdef USB_SUPPORT//----------------------------------------------------------------------------// init for usb based devices from peakstatic int register_usb_devices(void){  int err;  DPRINTK(KERN_DEBUG "%s: register_usb_devices()\n", DEVICE_NAME);    if (!(err = pcan_usb_init()))  {    DPRINTK(KERN_DEBUG "%s: register_usb_devices() is OK\n", DEVICE_NAME);  }  return err;}#endif#ifdef LINUX_22//----------------------------------------------------------------------------// replacement for kernel 2.4.x function// original from sysdep.h  from the book// "Linux Device Drivers" by Alessandro Rubini and Jonathan Corbet, published by O'Reilly & Associates.static struct proc_dir_entry *create_proc_read_entry(const char *name, mode_t mode,                                         struct proc_dir_entry *base, read_proc_t *read_proc, void * data){  struct proc_dir_entry *res = create_proc_entry(name, mode, base);  if (res)   {    res->read_proc=read_proc;    res->data=data;  }  return res;}#endif//----------------------------------------------------------------------------// is called when the device is installed 'insmod pcan.o'int init_module(void){  int result = 0;    pcan_drv.wInitStep       = 0;     pcan_drv.dwInitTime      = get_mtime();     // store time for timestamp relation, increments in msec  pcan_drv.szVersionString = CURRENT_RELEASE; // get the release name global    printk(KERN_INFO "%s: %s\n", DEVICE_NAME, pcan_drv.szVersionString);  INIT_LIST_HEAD(&pcan_drv.devices);  pcan_drv.wDeviceCount = 0;    // search pci devices  if ((result = search_and_create_pci_devices()))    goto fail;    // create isa devices  if ((result = create_isa_devices()))    goto fail;      // create dongle devices  if ((result = create_dongle_devices()))    goto fail;  #ifdef USB_SUPPORT  // register usb devices only  if ((result = register_usb_devices()))    goto fail;  #else  // no device found, stop all  if (!pcan_drv.wDeviceCount)    goto fail;  #endif      pcan_drv.wInitStep = 1;    // register the driver by the OS  pcan_drv.nMajor  = PCAN_MAJOR;  if ((result = register_chrdev(pcan_drv.nMajor, DEVICE_NAME, &pcan_fops)) < 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;}// end

⌨️ 快捷键说明

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