UIO-用户空间驱动的新发展
作者 佚名技术
来源 Linux系统
浏览
发布时间 2012-05-13
ce向内核注册了设备.
/* * UIO Hilscher CIF card driver */ #include <linux/device.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/uio_driver.h> #include <asm/io.h> #ifndef PCI_DEVICE_ID_PLX_9030 #define PCI_DEVICE_ID_PLX_9030 0x9030 #endif #define PLX9030_INTCSR 0x4C #define INTSCR_INT1_ENABLE 0x01 #define INTSCR_INT1_STATUS 0x04 #define INT1_ENABLED_AND_ACTIVE (INTSCR_INT1_ENABLE | INTSCR_INT1_STATUS) #define PCI_SUBVENDOR_ID_PEP 0x1518 #define CIF_SUBDEVICE_PROFIBUS 0x430 #define CIF_SUBDEVICE_DEVICENET 0x432 static irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info) { void __iomem *plx_intscr = dev_info->mem[0].internal_addr PLX9030_INTCSR; if ((ioread8(plx_intscr) & INT1_ENABLED_AND_ACTIVE) != INT1_ENABLED_AND_ACTIVE) return IRQ_NONE; /* Disable interrupt */ iowrite8(ioread8(plx_intscr) & ~INTSCR_INT1_ENABLE, plx_intscr); return IRQ_HANDLED; } static int __devinit hilscher_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct uio_info *info; info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); if (!info) return -ENOMEM; if (pci_enable_device(dev)) goto out_free; if (pci_request_regions(dev, "hilscher"))
goto out_disable; info->mem[0].addr = pci_resource_start(dev, 0); if (!info->mem[0].addr) goto out_release; info->mem[0].internal_addr = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0)); if (!info->mem[0].internal_addr) goto out_release; info->mem[0].size = pci_resource_len(dev, 0); info->mem[0].memtype = UIO_MEM_PHYS; info->mem[1].addr = pci_resource_start(dev, 2); info->mem[1].size = pci_resource_len(dev, 2); info->mem[1].memtype = UIO_MEM_PHYS; switch (id->subdevice) { case CIF_SUBDEVICE_PROFIBUS: info->name = "CIF_Profibus"; break; case CIF_SUBDEVICE_DEVICENET: info->name = "CIF_Devicenet"; break; default: info->name = "CIF_???"; } info->version = "0.0.1"; info->irq = dev->irq; info->irq_flags = IRQF_DISABLED | IRQF_SHARED; info->handler = hilscher_handler; if (uio_register_device(&dev->dev, info)) goto out_unmap; pci_set_drvdata(dev, info); return 0; out_unmap: iounmap(info->mem[0].internal_addr); out_release: pci_release_regions(dev); out_disable: pci_disable_device(dev); out_free: kfree (info); return -ENODEV; } static void hilscher_pci_remove(struct pci_dev *dev) { struct uio_info *info = pci_get_drvdata(dev); uio_unregister_device(info); pci_release_regions(dev); pci_disable_device(dev); pci_set_drvdata(dev, NULL); iounmap(info->mem[0].internal_addr); kfree (info); } static struct pci_device_id hilscher_pci_ids[] = { { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9030, .subvendor = PCI_SUBVENDOR_ID_PEP, .subdevice = CIF_SUBDEVICE_PROFIBUS,
}, { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9030, .subvendor = PCI_SUBVENDOR_ID_PEP, .subdevice = C |
||
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |
你可能对下面的文章感兴趣
上一篇: linux 共享问题下一篇: linux下samba服务器的配置
关于UIO-用户空间驱动的新发展的所有评论