Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/arch/x86/pci/direct.c (Version 2.6.25.8) and /linux/arch/i386/pci/direct.c (Version 2.6.11.8)


  1 /*                                                  1 /*
  2  * direct.c - Low-level direct PCI config spac      2  * direct.c - Low-level direct PCI config space access
  3  */                                                 3  */
  4                                                     4 
  5 #include <linux/pci.h>                              5 #include <linux/pci.h>
  6 #include <linux/init.h>                             6 #include <linux/init.h>
  7 #include <linux/dmi.h>                         << 
  8 #include "pci.h"                                    7 #include "pci.h"
  9                                                     8 
 10 /*                                                  9 /*
 11  * Functions for accessing PCI configuration s     10  * Functions for accessing PCI configuration space with type 1 accesses
 12  */                                                11  */
 13                                                    12 
 14 #define PCI_CONF1_ADDRESS(bus, devfn, reg) \       13 #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
 15         (0x80000000 | (bus << 16) | (devfn <<      14         (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
 16                                                    15 
 17 static int pci_conf1_read(unsigned int seg, un !!  16 static int pci_conf1_read (int seg, int bus, int devfn, int reg, int len, u32 *value)
 18                           unsigned int devfn,  << 
 19 {                                                  17 {
 20         unsigned long flags;                       18         unsigned long flags;
 21                                                    19 
 22         if ((bus > 255) || (devfn > 255) || (r !!  20         if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
 23                 *value = -1;                   << 
 24                 return -EINVAL;                    21                 return -EINVAL;
 25         }                                      << 
 26                                                    22 
 27         spin_lock_irqsave(&pci_config_lock, fl     23         spin_lock_irqsave(&pci_config_lock, flags);
 28                                                    24 
 29         outl(PCI_CONF1_ADDRESS(bus, devfn, reg     25         outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
 30                                                    26 
 31         switch (len) {                             27         switch (len) {
 32         case 1:                                    28         case 1:
 33                 *value = inb(0xCFC + (reg & 3)     29                 *value = inb(0xCFC + (reg & 3));
 34                 break;                             30                 break;
 35         case 2:                                    31         case 2:
 36                 *value = inw(0xCFC + (reg & 2)     32                 *value = inw(0xCFC + (reg & 2));
 37                 break;                             33                 break;
 38         case 4:                                    34         case 4:
 39                 *value = inl(0xCFC);               35                 *value = inl(0xCFC);
 40                 break;                             36                 break;
 41         }                                          37         }
 42                                                    38 
 43         spin_unlock_irqrestore(&pci_config_loc     39         spin_unlock_irqrestore(&pci_config_lock, flags);
 44                                                    40 
 45         return 0;                                  41         return 0;
 46 }                                                  42 }
 47                                                    43 
 48 static int pci_conf1_write(unsigned int seg, u !!  44 static int pci_conf1_write (int seg, int bus, int devfn, int reg, int len, u32 value)
 49                            unsigned int devfn, << 
 50 {                                                  45 {
 51         unsigned long flags;                       46         unsigned long flags;
 52                                                    47 
 53         if ((bus > 255) || (devfn > 255) || (r     48         if ((bus > 255) || (devfn > 255) || (reg > 255)) 
 54                 return -EINVAL;                    49                 return -EINVAL;
 55                                                    50 
 56         spin_lock_irqsave(&pci_config_lock, fl     51         spin_lock_irqsave(&pci_config_lock, flags);
 57                                                    52 
 58         outl(PCI_CONF1_ADDRESS(bus, devfn, reg     53         outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
 59                                                    54 
 60         switch (len) {                             55         switch (len) {
 61         case 1:                                    56         case 1:
 62                 outb((u8)value, 0xCFC + (reg &     57                 outb((u8)value, 0xCFC + (reg & 3));
 63                 break;                             58                 break;
 64         case 2:                                    59         case 2:
 65                 outw((u16)value, 0xCFC + (reg      60                 outw((u16)value, 0xCFC + (reg & 2));
 66                 break;                             61                 break;
 67         case 4:                                    62         case 4:
 68                 outl((u32)value, 0xCFC);           63                 outl((u32)value, 0xCFC);
 69                 break;                             64                 break;
 70         }                                          65         }
 71                                                    66 
 72         spin_unlock_irqrestore(&pci_config_loc     67         spin_unlock_irqrestore(&pci_config_lock, flags);
 73                                                    68 
 74         return 0;                                  69         return 0;
 75 }                                                  70 }
 76                                                    71 
 77 #undef PCI_CONF1_ADDRESS                           72 #undef PCI_CONF1_ADDRESS
 78                                                    73 
 79 struct pci_raw_ops pci_direct_conf1 = {            74 struct pci_raw_ops pci_direct_conf1 = {
 80         .read =         pci_conf1_read,            75         .read =         pci_conf1_read,
 81         .write =        pci_conf1_write,           76         .write =        pci_conf1_write,
 82 };                                                 77 };
 83                                                    78 
 84                                                    79 
 85 /*                                                 80 /*
 86  * Functions for accessing PCI configuration s     81  * Functions for accessing PCI configuration space with type 2 accesses
 87  */                                                82  */
 88                                                    83 
 89 #define PCI_CONF2_ADDRESS(dev, reg)     (u16)(     84 #define PCI_CONF2_ADDRESS(dev, reg)     (u16)(0xC000 | (dev << 8) | reg)
 90                                                    85 
 91 static int pci_conf2_read(unsigned int seg, un !!  86 static int pci_conf2_read(int seg, int bus, int devfn, int reg, int len, u32 *value)
 92                           unsigned int devfn,  << 
 93 {                                                  87 {
 94         unsigned long flags;                       88         unsigned long flags;
 95         int dev, fn;                               89         int dev, fn;
 96                                                    90 
 97         if ((bus > 255) || (devfn > 255) || (r !!  91         if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
 98                 *value = -1;                   << 
 99                 return -EINVAL;                    92                 return -EINVAL;
100         }                                      << 
101                                                    93 
102         dev = PCI_SLOT(devfn);                     94         dev = PCI_SLOT(devfn);
103         fn = PCI_FUNC(devfn);                      95         fn = PCI_FUNC(devfn);
104                                                    96 
105         if (dev & 0x10)                            97         if (dev & 0x10) 
106                 return PCIBIOS_DEVICE_NOT_FOUN     98                 return PCIBIOS_DEVICE_NOT_FOUND;
107                                                    99 
108         spin_lock_irqsave(&pci_config_lock, fl    100         spin_lock_irqsave(&pci_config_lock, flags);
109                                                   101 
110         outb((u8)(0xF0 | (fn << 1)), 0xCF8);      102         outb((u8)(0xF0 | (fn << 1)), 0xCF8);
111         outb((u8)bus, 0xCFA);                     103         outb((u8)bus, 0xCFA);
112                                                   104 
113         switch (len) {                            105         switch (len) {
114         case 1:                                   106         case 1:
115                 *value = inb(PCI_CONF2_ADDRESS    107                 *value = inb(PCI_CONF2_ADDRESS(dev, reg));
116                 break;                            108                 break;
117         case 2:                                   109         case 2:
118                 *value = inw(PCI_CONF2_ADDRESS    110                 *value = inw(PCI_CONF2_ADDRESS(dev, reg));
119                 break;                            111                 break;
120         case 4:                                   112         case 4:
121                 *value = inl(PCI_CONF2_ADDRESS    113                 *value = inl(PCI_CONF2_ADDRESS(dev, reg));
122                 break;                            114                 break;
123         }                                         115         }
124                                                   116 
125         outb(0, 0xCF8);                           117         outb(0, 0xCF8);
126                                                   118 
127         spin_unlock_irqrestore(&pci_config_loc    119         spin_unlock_irqrestore(&pci_config_lock, flags);
128                                                   120 
129         return 0;                                 121         return 0;
130 }                                                 122 }
131                                                   123 
132 static int pci_conf2_write(unsigned int seg, u !! 124 static int pci_conf2_write (int seg, int bus, int devfn, int reg, int len, u32 value)
133                            unsigned int devfn, << 
134 {                                                 125 {
135         unsigned long flags;                      126         unsigned long flags;
136         int dev, fn;                              127         int dev, fn;
137                                                   128 
138         if ((bus > 255) || (devfn > 255) || (r    129         if ((bus > 255) || (devfn > 255) || (reg > 255)) 
139                 return -EINVAL;                   130                 return -EINVAL;
140                                                   131 
141         dev = PCI_SLOT(devfn);                    132         dev = PCI_SLOT(devfn);
142         fn = PCI_FUNC(devfn);                     133         fn = PCI_FUNC(devfn);
143                                                   134 
144         if (dev & 0x10)                           135         if (dev & 0x10) 
145                 return PCIBIOS_DEVICE_NOT_FOUN    136                 return PCIBIOS_DEVICE_NOT_FOUND;
146                                                   137 
147         spin_lock_irqsave(&pci_config_lock, fl    138         spin_lock_irqsave(&pci_config_lock, flags);
148                                                   139 
149         outb((u8)(0xF0 | (fn << 1)), 0xCF8);      140         outb((u8)(0xF0 | (fn << 1)), 0xCF8);
150         outb((u8)bus, 0xCFA);                     141         outb((u8)bus, 0xCFA);
151                                                   142 
152         switch (len) {                            143         switch (len) {
153         case 1:                                   144         case 1:
154                 outb((u8)value, PCI_CONF2_ADDR    145                 outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
155                 break;                            146                 break;
156         case 2:                                   147         case 2:
157                 outw((u16)value, PCI_CONF2_ADD    148                 outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
158                 break;                            149                 break;
159         case 4:                                   150         case 4:
160                 outl((u32)value, PCI_CONF2_ADD    151                 outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
161                 break;                            152                 break;
162         }                                         153         }
163                                                   154 
164         outb(0, 0xCF8);                           155         outb(0, 0xCF8);    
165                                                   156 
166         spin_unlock_irqrestore(&pci_config_loc    157         spin_unlock_irqrestore(&pci_config_lock, flags);
167                                                   158 
168         return 0;                                 159         return 0;
169 }                                                 160 }
170                                                   161 
171 #undef PCI_CONF2_ADDRESS                          162 #undef PCI_CONF2_ADDRESS
172                                                   163 
173 static struct pci_raw_ops pci_direct_conf2 = {    164 static struct pci_raw_ops pci_direct_conf2 = {
174         .read =         pci_conf2_read,           165         .read =         pci_conf2_read,
175         .write =        pci_conf2_write,          166         .write =        pci_conf2_write,
176 };                                                167 };
177                                                   168 
178                                                   169 
179 /*                                                170 /*
180  * Before we decide to use direct hardware acc    171  * Before we decide to use direct hardware access mechanisms, we try to do some
181  * trivial checks to ensure it at least _seems    172  * trivial checks to ensure it at least _seems_ to be working -- we just test
182  * whether bus 00 contains a host bridge (this    173  * whether bus 00 contains a host bridge (this is similar to checking
183  * techniques used in XFree86, but ours should    174  * techniques used in XFree86, but ours should be more reliable since we
184  * attempt to make use of direct access hints     175  * attempt to make use of direct access hints provided by the PCI BIOS).
185  *                                                176  *
186  * This should be close to trivial, but it isn    177  * This should be close to trivial, but it isn't, because there are buggy
187  * chipsets (yes, you guessed it, by Intel and    178  * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
188  */                                               179  */
189 static int __init pci_sanity_check(struct pci_    180 static int __init pci_sanity_check(struct pci_raw_ops *o)
190 {                                                 181 {
191         u32 x = 0;                                182         u32 x = 0;
192         int devfn;                                183         int devfn;
193                                                   184 
194         if (pci_probe & PCI_NO_CHECKS)            185         if (pci_probe & PCI_NO_CHECKS)
195                 return 1;                         186                 return 1;
196         /* Assume Type 1 works for newer syste << 
197            This handles machines that don't ha << 
198         if (dmi_get_year(DMI_BIOS_DATE) >= 200 << 
199                 return 1;                      << 
200                                                   187 
201         for (devfn = 0; devfn < 0x100; devfn++    188         for (devfn = 0; devfn < 0x100; devfn++) {
202                 if (o->read(0, 0, devfn, PCI_C    189                 if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x))
203                         continue;                 190                         continue;
204                 if (x == PCI_CLASS_BRIDGE_HOST    191                 if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)
205                         return 1;                 192                         return 1;
206                                                   193 
207                 if (o->read(0, 0, devfn, PCI_V    194                 if (o->read(0, 0, devfn, PCI_VENDOR_ID, 2, &x))
208                         continue;                 195                         continue;
209                 if (x == PCI_VENDOR_ID_INTEL |    196                 if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)
210                         return 1;                 197                         return 1;
211         }                                         198         }
212                                                   199 
213         DBG(KERN_WARNING "PCI: Sanity check fa !! 200         DBG("PCI: Sanity check failed\n");
214         return 0;                                 201         return 0;
215 }                                                 202 }
216                                                   203 
217 static int __init pci_check_type1(void)           204 static int __init pci_check_type1(void)
218 {                                                 205 {
219         unsigned long flags;                      206         unsigned long flags;
220         unsigned int tmp;                         207         unsigned int tmp;
221         int works = 0;                            208         int works = 0;
222                                                   209 
223         spin_lock_irqsave(&pci_config_lock, fl !! 210         local_irq_save(flags);
224                                                   211 
225         outb(0x01, 0xCFB);                        212         outb(0x01, 0xCFB);
226         tmp = inl(0xCF8);                         213         tmp = inl(0xCF8);
227         outl(0x80000000, 0xCF8);                  214         outl(0x80000000, 0xCF8);
228                                                !! 215         if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) {
229         if (inl(0xCF8) == 0x80000000) {        !! 216                 works = 1;
230                 spin_unlock_irqrestore(&pci_co << 
231                                                << 
232                 if (pci_sanity_check(&pci_dire << 
233                         works = 1;             << 
234                                                << 
235                 spin_lock_irqsave(&pci_config_ << 
236         }                                         217         }
237         outl(tmp, 0xCF8);                         218         outl(tmp, 0xCF8);
238                                                !! 219         local_irq_restore(flags);
239         spin_unlock_irqrestore(&pci_config_loc << 
240                                                   220 
241         return works;                             221         return works;
242 }                                                 222 }
243                                                   223 
244 static int __init pci_check_type2(void)           224 static int __init pci_check_type2(void)
245 {                                                 225 {
246         unsigned long flags;                      226         unsigned long flags;
247         int works = 0;                            227         int works = 0;
248                                                   228 
249         spin_lock_irqsave(&pci_config_lock, fl !! 229         local_irq_save(flags);
250                                                   230 
251         outb(0x00, 0xCFB);                        231         outb(0x00, 0xCFB);
252         outb(0x00, 0xCF8);                        232         outb(0x00, 0xCF8);
253         outb(0x00, 0xCFA);                        233         outb(0x00, 0xCFA);
                                                   >> 234         if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 &&
                                                   >> 235             pci_sanity_check(&pci_direct_conf2)) {
                                                   >> 236                 works = 1;
                                                   >> 237         }
254                                                   238 
255         if (inb(0xCF8) == 0x00 && inb(0xCFA) = !! 239         local_irq_restore(flags);
256                 spin_unlock_irqrestore(&pci_co << 
257                                                << 
258                 if (pci_sanity_check(&pci_dire << 
259                         works = 1;             << 
260         } else                                 << 
261                 spin_unlock_irqrestore(&pci_co << 
262                                                   240 
263         return works;                             241         return works;
264 }                                                 242 }
265                                                   243 
266 void __init pci_direct_init(int type)          !! 244 static int __init pci_direct_init(void)
267 {                                              << 
268         if (type == 0)                         << 
269                 return;                        << 
270         printk(KERN_INFO "PCI: Using configura << 
271         if (type == 1)                         << 
272                 raw_pci_ops = &pci_direct_conf << 
273         else                                   << 
274                 raw_pci_ops = &pci_direct_conf << 
275 }                                              << 
276                                                << 
277 int __init pci_direct_probe(void)              << 
278 {                                                 245 {
279         struct resource *region, *region2;        246         struct resource *region, *region2;
280                                                   247 
281         if ((pci_probe & PCI_PROBE_CONF1) == 0    248         if ((pci_probe & PCI_PROBE_CONF1) == 0)
282                 goto type2;                       249                 goto type2;
283         region = request_region(0xCF8, 8, "PCI    250         region = request_region(0xCF8, 8, "PCI conf1");
284         if (!region)                              251         if (!region)
285                 goto type2;                       252                 goto type2;
286                                                   253 
287         if (pci_check_type1())                 !! 254         if (pci_check_type1()) {
288                 return 1;                      !! 255                 printk(KERN_INFO "PCI: Using configuration type 1\n");
                                                   >> 256                 raw_pci_ops = &pci_direct_conf1;
                                                   >> 257                 return 0;
                                                   >> 258         }
289         release_resource(region);                 259         release_resource(region);
290                                                   260 
291  type2:                                           261  type2:
292         if ((pci_probe & PCI_PROBE_CONF2) == 0    262         if ((pci_probe & PCI_PROBE_CONF2) == 0)
293                 return 0;                      !! 263                 goto out;
294         region = request_region(0xCF8, 4, "PCI    264         region = request_region(0xCF8, 4, "PCI conf2");
295         if (!region)                              265         if (!region)
296                 return 0;                      !! 266                 goto out;
297         region2 = request_region(0xC000, 0x100    267         region2 = request_region(0xC000, 0x1000, "PCI conf2");
298         if (!region2)                             268         if (!region2)
299                 goto fail2;                       269                 goto fail2;
300                                                   270 
301         if (pci_check_type2()) {                  271         if (pci_check_type2()) {
302                 printk(KERN_INFO "PCI: Using c    272                 printk(KERN_INFO "PCI: Using configuration type 2\n");
303                 raw_pci_ops = &pci_direct_conf    273                 raw_pci_ops = &pci_direct_conf2;
304                 return 2;                      !! 274                 return 0;
305         }                                         275         }
306                                                   276 
307         release_resource(region2);                277         release_resource(region2);
308  fail2:                                           278  fail2:
309         release_resource(region);                 279         release_resource(region);
                                                   >> 280 
                                                   >> 281  out:
310         return 0;                                 282         return 0;
311 }                                                 283 }
                                                   >> 284 
                                                   >> 285 arch_initcall(pci_direct_init);
312                                                   286 
  This page was automatically generated by the LXR engine.