治肾虚不含糖,专注内核性能优化二十年。 https://github.com/KnightKu
分类: LINUX
2013-01-22 17:07:24
写了一个模块想模拟一下pcie slot的外部按钮事件,想法是通过改pcie插槽的寄存器的状态,然后有pciehp的中断/轮询机制来触发 对应的处理流程,可是实验过程中没有出现预期的结果...,功力尚浅~~ #include#include #include #include #define PCI_EXP_SLTSTA_PDS 0x0040 /* Presence Detect State */ #define PCI_EXP_SLTSTA_PDC 0x0008 /* Presence Detect Changed */ #define PCI_EXP_SLTSTA 26 /* Slot Status */ #define PCI_EXP_SLTCTL_PCC 0x0400 /* Power Controller Control */ #define POWER_OFF PCI_EXP_SLTCTL_PCC #define PCI_EXP_SLTCTL 24 /* Slot Control */ static struct pci_dev *dev; static struct pci_bus *bus; static int domain = 0x0000; static int busnr = 0; module_param(domain, int, 0644); module_param(busnr, int, 0644); MODULE_LICENSE("GPL"); MODULE_AUTHOR("GuZheng cengku@gmail.com"); static int __init pcie_conf_init(void) { int retval = 0; u16 slot_ctrl; u16 slot_cmd; u16 cmd_mask; bus = pci_find_bus(domain, busnr); if (!bus) { printk("==can not get pci_bus==\\n"); return -1; } printk("Succeed get pci bus:%s\\n", bus->name); dev = bus->self; if (!dev) { printk("==can not get dev==\\n"); return -1; } retval = pcie_capability_read_word(dev, PCI_EXP_SLTCTL, &slot_ctrl); if (retval) { printk("%s can not read pcie register!\\n", __func__); return retval; } printk("Succeed read pcie slot register!\\n"); cmd_mask = PCI_EXP_SLTCTL_PCC; slot_cmd = POWER_OFF; slot_ctrl &= ~cmd_mask; slot_ctrl |= (cmd_mask & slot_cmd); retval = pcie_capability_write_word(dev, PCI_EXP_SLTCTL, slot_ctrl); if (retval) { printk("%s can not read pcie register!\\n", __func__); return retval; } printk("Succeed write pcie slot register!\\n"); return retval; } static void __exit pcie_conf_exit(void) { printk("exit module!\\n"); return; } module_init(pcie_conf_init); module_exit(pcie_conf_exit);