pcidata.c
上传用户:wudi5211
上传日期:2010-01-21
资源大小:607k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

C/C++

  1. /*
  2.  * pcidata.c --  a module that dumps the cfg registers through /proc
  3.  *
  4.  * $Id: pcidata.c,v 1.8 2001/03/16 21:04:49 rubini Exp $
  5.  *
  6.  * Copyright (C) 1997,2000   rubini@linux.it (Alessandro Rubini)
  7.  *
  8.  *   This program is free software; you can redistribute it and/or modify
  9.  *   it under the terms of the GNU General Public License as published by
  10.  *   the Free Software Foundation; either version 2 of the License, or
  11.  *   (at your option) any later version.
  12.  *
  13.  *   This program is distributed in the hope that it will be useful,
  14.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *   GNU General Public License for more details.
  17.  *
  18.  *   You should have received a copy of the GNU General Public License
  19.  *   along with this program; if not, write to the Free Software
  20.  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  21.  */
  22. #ifndef __KERNEL__
  23. #  define __KERNEL__
  24. #endif
  25. #ifndef MODULE
  26. #  define MODULE
  27. #endif
  28. #include <linux/config.h>
  29. #include <linux/module.h>
  30. #include <linux/sched.h>
  31. #include <linux/proc_fs.h>
  32. #include <linux/pci.h>
  33. #include "sysdep.h"
  34. /*
  35.  * This simple module offers in a /proc file the binary
  36.  * configuration data of available PCI devices.
  37.  * Each device has 256 bytes of cfg data: 16 devices
  38.  * can fit in a page (32 on the alpha).
  39.  * FIXME: page size is no longer an issue with 2.2/2.4
  40.  */
  41. int pcidata_read_proc(char *buf, char **start, off_t offset,
  42.                    int len, int *eof, void *data)
  43. {
  44.     int i, pos=0;
  45.     int bus, devfn;
  46.     if (!pcibios_present())
  47.         return sprintf(buf,"No PCI bios presentn");
  48.     /*
  49.      * This code is derived from "drivers/pci/pci.c". This means that
  50.      * the GPL applies to this source file and credit is due to the
  51.      * original authors (Drew Eckhardt, Frederic Potter, David
  52.      * Mosberger-Tang)
  53.      */
  54.     for (bus=0; !bus; bus++) { /* only bus 0 :-) */
  55.         for (devfn=0; devfn < 0x100 && pos < PAGE_SIZE/2; devfn++) {
  56.     struct pci_dev *dev = NULL;
  57.     dev = pci_find_slot(bus, devfn);
  58.     if (!dev) continue;
  59.             /* Ok, we've found a device, copy its cfg space to the buffer*/
  60.             for (i=0; i<256; i += sizeof(u32), pos += sizeof(u32))
  61.                 pci_read_config_dword(dev,i,(u32 *)(buf+pos));
  62.     pci_release_device(dev); /* 2.0 compatibility */
  63.         }
  64.     }
  65.     *eof=1;
  66.     return pos;
  67. }
  68. #ifdef USE_PROC_REGISTER
  69. static int pcidata_old_read_proc(char *buf, char **start, off_t offset,
  70.  int len, int unused)
  71. {
  72.     int eof;
  73.     return pcidata_read_proc(buf, start, offset, len, &eof, NULL);
  74. }
  75. struct proc_dir_entry pcimod_proc_entry = {
  76.         0,                 /* low_ino: the inode -- dynamic */
  77.         7, "pcidata",      /* len of name and name */
  78.         S_IFREG | S_IRUGO, /* mode */
  79.         1, 0, 0,           /* nlinks, owner, group */
  80.         0, NULL,           /* size - unused; operations -- use default */
  81.         &pcidata_old_read_proc,   /* function used to read data */
  82.         /* nothing more */
  83.     };
  84. #endif /* USE_PROC_REGISTER */
  85. int init_module(void)
  86. {
  87. #ifdef USE_PROC_REGISTER
  88.     proc_register_dynamic(&proc_root, &pcimod_proc_entry);
  89. #else
  90.     create_proc_read_entry("pcidata", 0, NULL, pcidata_read_proc, NULL);
  91. #endif
  92.     return 0;
  93. }
  94. void cleanup_module(void)
  95. {
  96. #ifdef USE_PROC_REGISTER
  97.     proc_unregister(&proc_root, pcimod_proc_entry.low_ino);
  98. #else
  99.     remove_proc_entry("pcidata", 0);
  100. #endif
  101.     return;
  102. }