//------------------------------------------------------------------- // nicstatus.c // // This module creates a pseudo-file in the '/proc' directory // that lets a user display the current value in the 'STATUS' // register of our Intel 82573L Network Interface controller. // // to compile: $ mmake nicstatus // to install: $ /sbin/insmod nicstatus.ko // to execute: $ cat /proc/nicstatus // and remove: $ /sbin/rmmod nicstatus // // NOTE: Written and tested with Linux kernel version 2.6.26. // // programmer: ALLAN CRUSE // written on: 23 APR 2009 //------------------------------------------------------------------- #include // for init_module() #include // for create_proc_read_entry() #include // for pci_get_device() #define VENDOR_ID 0x8086 // Intel Corporation #define DEVICE_ID 0x109A // 82573L controller char modname[] = "nicstatus"; struct pci_dev *devp = NULL; unsigned int iobase; const char *duplex[] = { "half", "full" }; const char *state[] = { "DOWN", "UP" }; const char *speed[] = { "10Mbps", "100Mbps", "1000Mbps", "?" }; int my_proc( char *buf, char **start, off_t off, int count, int *eof, void *data ) { int status, len; // declare local variables // obtain the NIC's 'status' outl( 0x0008, iobase+0 ); // specify register to access status = inl( iobase+4 ); // input the register's value // create the pseudo-file's contents len = sprintf( buf, "\n E1000_STATUS=%08X ", status ); len += sprintf( buf+len, " speed=%s,", speed[ (status >> 6)&3 ] ); len += sprintf( buf+len, " %s-duplex,", duplex[ (status >> 0)&1 ] ); len += sprintf( buf+len, " nic is %s ", state[ (status >> 1)&1 ] ); len += sprintf( buf+len, "\n\n" ); // set End-Of-File flag, and return the pseudo-file's length *eof = 1; return len; } static int __init nicstatus_init( void ) { // append a confirmation-message to the system log printk( "<1>\nInstalling \'%s\' module\n", modname ); // detect the device's presence devp = pci_get_device( VENDOR_ID, DEVICE_ID, devp ); if ( !devp ) return -ENODEV; // get the device's I/O-port base-address iobase = pci_resource_start( devp, 2 ); // create our pseudo-file in the '/proc' subdirectory create_proc_read_entry( modname, 0, NULL, my_proc, NULL ); return 0; //SUCCESS } static void __exit nicstatus_exit(void ) { // detete our pseudo-file remove_proc_entry( modname, NULL ); // append a confirmation-message to the system log printk( "<1>Removing \'%s\' module\n", modname ); } module_init( nicstatus_init ); module_exit( nicstatus_exit ); MODULE_LICENSE("GPL");