//------------------------------------------------------------------- // msiset.c // // This module creates a pseudo-file named '/proc/msiset' which // shows the current values of the Pro1000 network controller's // Message Signaled Interrupt Capability Register Set read from // documented offsets in that device's PCI Configuration Space. // // NOTE: Written and tested with Linux kernel version 2.6.22.5. // // programmer: ALLAN CRUSE // written on: 13 MAY 2008 //------------------------------------------------------------------- #include // for init_module() #include // for create_proc_info_entry() #include // for pci_get_device() #define VENDOR_ID 0x8086 // Intel Corporation #define DEVICE_ID 0x109A // 82573L controller char modname[] = "msiset"; struct pci_dev *devp; char legend[] = "MSI Capability Register Set for Intel Pro1000 controller"; int my_get_info( char *buf, char **start, off_t off, int count ) { u16 msi_ctrl, msi_data; u32 msi_addr_lo, msi_addr_hi; int len = 0; pci_read_config_word( devp, 0xD2, &msi_ctrl ); pci_read_config_dword( devp, 0xD4, &msi_addr_lo ); pci_read_config_dword( devp, 0xD8, &msi_addr_hi ); pci_read_config_word( devp, 0xDC, &msi_data ); len += sprintf( buf+len, "\n %s\n\n", legend ); len += sprintf( buf+len, " msi_control=%04X ", msi_ctrl ); len += sprintf( buf+len, " msi_address=%08X%08X ", msi_addr_hi, msi_addr_lo ); len += sprintf( buf+len, " msi_data=%04X ", msi_data ); len += sprintf( buf+len, "\n\n" ); return len; } static int __init my_init( void ) { printk( "<1>\nInstalling \'%s\' module\n", modname ); devp = pci_get_device( VENDOR_ID, DEVICE_ID, NULL ); if ( !devp ) return -ENODEV; create_proc_info_entry( modname, 0, NULL, my_get_info ); return 0; //SUCCESS } static void __exit my_exit(void ) { remove_proc_entry( modname, NULL ); printk( "<1>Removing \'%s\' module\n", modname ); } module_init( my_init ); module_exit( my_exit ); MODULE_LICENSE("GPL");