Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

  1. //****************************************************************************
  2. // Copyright (C) 2000-2006  ARW Elektronik Germany
  3. //
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. //
  19. // This product is not authorized for use as critical component in
  20. // life support systems without the express written approval of
  21. // ARW Elektronik Germany.
  22. //  
  23. // Please announce changes and hints to ARW Elektronik
  24. //
  25. // Maintainer(s): Klaus Hitschler (klaus.hitschler@gmx.de)
  26. //
  27. //****************************************************************************
  28.  
  29. //****************************************************************************
  30. //
  31. // askpci.c - a hardware independent tool to get
  32. //            information about searched pci-hardware
  33. //
  34. // $Log: askpci.c,v $
  35. // Revision 1.7  2006/06/04 12:20:46  klaus
  36. // release_20060604; Version 3.2; pci_{en|dis}able_device() added
  37. //
  38. // Revision 1.6  2004/08/13 19:23:26  klaus
  39. // conversion to kernel-version 2.6, released version 3.0
  40. //
  41. // Revision 1.5  2002/10/18 21:56:28  klaus
  42. // completed functional features, untested
  43. //
  44. // Revision 1.4  2002/10/18 21:56:28  klaus
  45. // completed functional features, untested
  46. //
  47. // Revision 1.3  2002/10/10 18:57:46  klaus
  48. // source beautyfied
  49. //
  50. //****************************************************************************
  51.  
  52. /*--- INCLUDES -------------------------------------------------------------*/
  53. #include "common.h"  /* must be the first include */
  54.  
  55. #include <linux/pci.h>
  56. #include <asm/types.h>
  57. #include "askpci.h"
  58.  
  59. /*--- DEFINES ---------------------------------------------------------------*/
  60.  
  61.  
  62. /*--- FUNCTIONS -------------------------------------------------------------*/
  63. void DeletePCIConfig(DRIVER_OBJ *drv)
  64. {
  65.     PCIConfig *dev = NULL;
  66.  
  67.     while (!list_empty(&drv->pciList))     // cycle through the list of pci devices and remove them
  68.     {
  69.         dev = (PCIConfig *)drv->pciList.prev; // empty in reverse order
  70.        
  71.         #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
  72.         if (dev->pciDev)
  73.                       pci_disable_device(dev->pciDev);
  74.         #endif         
  75.  
  76.         list_del(&dev->list);
  77.         kfree(dev);
  78.     }
  79. }
  80.  
  81. int GetPCIConfig(DRIVER_OBJ *drv, u16 device_id, u16 vendor_id, u16 subsys_id, u16 subven_id)
  82. {
  83.     int result     = 0;
  84.     PCIConfig *dev = NULL;
  85.     int i          = 0;
  86.  
  87.     // search pci devices
  88.     PRINTK(KERN_DEBUG "%s : GetPCIConfig(0x%04x, 0x%04x, 0x%04x, 0x%04x)\n", DEVICE_NAME, device_id, vendor_id, subsys_id, subven_id);
  89.  
  90. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  91.         if (CONFIG_PCI)
  92. #else
  93.         if (pci_present())
  94. #endif
  95.     {
  96.         struct pci_dev *pciDev;
  97.  
  98.         struct pci_dev *from = NULL;
  99.         do
  100.         {
  101. // https://groups.google.com/forum/?fromgroups=#!topic/fa.linux.kernel/aMXNYIFrOP8
  102. //            pciDev = pci_find_device((unsigned int)vendor_id, (unsigned int)device_id, from);
  103.             pciDev = pci_get_device((unsigned int)vendor_id, (unsigned int)device_id, from);
  104.  
  105.             if (pciDev != NULL)
  106.             {
  107.                 u16 wSubSysID;
  108.                 u16 wSubVenID;
  109.  
  110.                 // a PCI device with PCAN_PCI_VENDOR_ID and PCAN_PCI_DEVICE_ID was found
  111.                 from = pciDev;
  112.                
  113.                 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
  114.                 if (pci_enable_device(pciDev))
  115.                   continue;  
  116.                 #endif
  117.  
  118.                 // get the PCI Subsystem-ID
  119.                 result = pci_read_config_word(pciDev, PCI_SUBSYSTEM_ID, &wSubSysID);
  120.                 if (result)
  121.                 {
  122.                     result = -ENXIO;
  123.                     goto fail;
  124.                 }
  125.  
  126.                 // get the PCI Subvendor-ID
  127.                 result = pci_read_config_word(pciDev, PCI_SUBSYSTEM_VENDOR_ID, &wSubVenID);
  128.                 if (result)
  129.                 {
  130.                     result = -ENXIO;
  131.                     goto fail;
  132.                 }
  133.  
  134.                 // get next if the subsys and subvendor ids do not match
  135.                 if ((wSubVenID != subven_id) || (wSubSysID != subsys_id))
  136.                     continue;
  137.  
  138.                 // create space for PCIConfig descriptor
  139.                 if ((dev = (PCIConfig *)kmalloc(sizeof(PCIConfig), GFP_KERNEL)) == NULL)
  140.                 {
  141.                     result = -ENOMEM;
  142.                     goto fail;
  143.                 }
  144.  
  145.                 // put data into pci device
  146.                 dev->pciDev = pciDev;  
  147.  
  148.                 list_add_tail(&dev->list, &drv->pciList);  // add this device to the list of unchecked devices
  149.                 dev->index++;
  150.                 i++;
  151.             }
  152.         } while (pciDev != NULL);
  153.  
  154.         result = 0;
  155.     }
  156.     else
  157.     {
  158.         printk(KERN_ERR "%s: No pcibios present!\n", DEVICE_NAME);  
  159.         result = -ENXIO;
  160.     }
  161.  
  162.     fail:
  163.     if (result)
  164.         DeletePCIConfig(drv);
  165.  
  166.     PRINTK(KERN_DEBUG "%s : %d devices found (%d).\n", DEVICE_NAME, i, result);
  167.  
  168.     return result;  
  169. }
  170.  
  171.  
  172. /* ------------------------------------------------------------------------- */
  173. /* ------------------------------------------------------------------------- */
  174.  
  175.