Subversion Repositories f9daq

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
9 f9daq 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