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 ]
  1 /*
  2  * BIOS32 and PCI BIOS handling.
  3  */
  4 
  5 #include <linux/pci.h>
  6 #include <linux/init.h>
  7 #include <linux/module.h>
  8 #include <linux/uaccess.h>
  9 #include "pci.h"
 10 #include "pci-functions.h"
 11 
 12 
 13 /* BIOS32 signature: "_32_" */
 14 #define BIOS32_SIGNATURE        (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
 15 
 16 /* PCI signature: "PCI " */
 17 #define PCI_SIGNATURE           (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
 18 
 19 /* PCI service signature: "$PCI" */
 20 #define PCI_SERVICE             (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
 21 
 22 /* PCI BIOS hardware mechanism flags */
 23 #define PCIBIOS_HW_TYPE1                0x01
 24 #define PCIBIOS_HW_TYPE2                0x02
 25 #define PCIBIOS_HW_TYPE1_SPEC           0x10
 26 #define PCIBIOS_HW_TYPE2_SPEC           0x20
 27 
 28 /*
 29  * This is the standard structure used to identify the entry point
 30  * to the BIOS32 Service Directory, as documented in
 31  *      Standard BIOS 32-bit Service Directory Proposal
 32  *      Revision 0.4 May 24, 1993
 33  *      Phoenix Technologies Ltd.
 34  *      Norwood, MA
 35  * and the PCI BIOS specification.
 36  */
 37 
 38 union bios32 {
 39         struct {
 40                 unsigned long signature;        /* _32_ */
 41                 unsigned long entry;            /* 32 bit physical address */
 42                 unsigned char revision;         /* Revision level, 0 */
 43                 unsigned char length;           /* Length in paragraphs should be 01 */
 44                 unsigned char checksum;         /* All bytes must add up to zero */
 45                 unsigned char reserved[5];      /* Must be zero */
 46         } fields;
 47         char chars[16];
 48 };
 49 
 50 /*
 51  * Physical address of the service directory.  I don't know if we're
 52  * allowed to have more than one of these or not, so just in case
 53  * we'll make pcibios_present() take a memory start parameter and store
 54  * the array there.
 55  */
 56 
 57 static struct {
 58         unsigned long address;
 59         unsigned short segment;
 60 } bios32_indirect = { 0, __KERNEL_CS };
 61 
 62 /*
 63  * Returns the entry point for the given service, NULL on error
 64  */
 65 
 66 static unsigned long bios32_service(unsigned long service)
 67 {
 68         unsigned char return_code;      /* %al */
 69         unsigned long address;          /* %ebx */
 70         unsigned long length;           /* %ecx */
 71         unsigned long entry;            /* %edx */
 72         unsigned long flags;
 73 
 74         local_irq_save(flags);
 75         __asm__("lcall *(%%edi); cld"
 76                 : "=a" (return_code),
 77                   "=b" (address),
 78                   "=c" (length),
 79                   "=d" (entry)
 80                 : "" (service),
 81                   "1" (0),
 82                   "D" (&bios32_indirect));
 83         local_irq_restore(flags);
 84 
 85         switch (return_code) {
 86                 case 0:
 87                         return address + entry;
 88                 case 0x80:      /* Not present */
 89                         printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
 90                         return 0;
 91                 default: /* Shouldn't happen */
 92                         printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
 93                                 service, return_code);
 94                         return 0;
 95         }
 96 }
 97 
 98 static struct {
 99         unsigned long address;
100         unsigned short segment;
101 } pci_indirect = { 0, __KERNEL_CS };
102 
103 static int pci_bios_present;
104 
105 static int __devinit check_pcibios(void)
106 {
107         u32 signature, eax, ebx, ecx;
108         u8 status, major_ver, minor_ver, hw_mech;
109         unsigned long flags, pcibios_entry;
110 
111         if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
112                 pci_indirect.address = pcibios_entry + PAGE_OFFSET;
113 
114                 local_irq_save(flags);
115                 __asm__(
116                         "lcall *(%%edi); cld\n\t"
117                         "jc 1f\n\t"
118                         "xor %%ah, %%ah\n"
119                         "1:"
120                         : "=d" (signature),
121                           "=a" (eax),
122                           "=b" (ebx),
123                           "=c" (ecx)
124                         : "1" (PCIBIOS_PCI_BIOS_PRESENT),
125                           "D" (&pci_indirect)
126                         : "memory");
127                 local_irq_restore(flags);
128 
129                 status = (eax >> 8) & 0xff;
130                 hw_mech = eax & 0xff;
131                 major_ver = (ebx >> 8) & 0xff;
132                 minor_ver = ebx & 0xff;
133                 if (pcibios_last_bus < 0)
134                         pcibios_last_bus = ecx & 0xff;
135                 DBG("PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
136                         status, hw_mech, major_ver, minor_ver, pcibios_last_bus);
137                 if (status || signature != PCI_SIGNATURE) {
138                         printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found\n",
139                                 status, signature);
140                         return 0;
141                 }
142                 printk(KERN_INFO "PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
143                         major_ver, minor_ver, pcibios_entry, pcibios_last_bus);
144 #ifdef CONFIG_PCI_DIRECT
145                 if (!(hw_mech & PCIBIOS_HW_TYPE1))
146                         pci_probe &= ~PCI_PROBE_CONF1;
147                 if (!(hw_mech & PCIBIOS_HW_TYPE2))
148                         pci_probe &= ~PCI_PROBE_CONF2;
149 #endif
150                 return 1;
151         }
152         return 0;
153 }
154 
155 static int __devinit pci_bios_find_device (unsigned short vendor, unsigned short device_id,
156                                         unsigned short index, unsigned char *bus, unsigned char *device_fn)
157 {
158         unsigned short bx;
159         unsigned short ret;
160 
161         __asm__("lcall *(%%edi); cld\n\t"
162                 "jc 1f\n\t"
163                 "xor %%ah, %%ah\n"
164                 "1:"
165                 : "=b" (bx),
166                   "=a" (ret)
167                 : "1" (PCIBIOS_FIND_PCI_DEVICE),
168                   "c" (device_id),
169                   "d" (vendor),
170                   "S" ((int) index),
171                   "D" (&pci_indirect));
172         *bus = (bx >> 8) & 0xff;
173         *device_fn = bx & 0xff;
174         return (int) (ret & 0xff00) >> 8;
175 }
176 
177 static int pci_bios_read(unsigned int seg, unsigned int bus,
178                          unsigned int devfn, int reg, int len, u32 *value)
179 {
180         unsigned long result = 0;
181         unsigned long flags;
182         unsigned long bx = (bus << 8) | devfn;
183 
184         if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
185                 return -EINVAL;
186 
187         spin_lock_irqsave(&pci_config_lock, flags);
188 
189         switch (len) {
190         case 1:
191                 __asm__("lcall *(%%esi); cld\n\t"
192                         "jc 1f\n\t"
193                         "xor %%ah, %%ah\n"
194                         "1:"
195                         : "=c" (*value),
196                           "=a" (result)
197                         : "1" (PCIBIOS_READ_CONFIG_BYTE),
198                           "b" (bx),
199                           "D" ((long)reg),
200                           "S" (&pci_indirect));
201                 /*
202                  * Zero-extend the result beyond 8 bits, do not trust the
203                  * BIOS having done it:
204                  */
205                 *value &= 0xff;
206                 break;
207         case 2:
208                 __asm__("lcall *(%%esi); cld\n\t"
209                         "jc 1f\n\t"
210                         "xor %%ah, %%ah\n"
211                         "1:"
212                         : "=c" (*value),
213                           "=a" (result)
214                         : "1" (PCIBIOS_READ_CONFIG_WORD),
215                           "b" (bx),
216                           "D" ((long)reg),
217                           "S" (&pci_indirect));
218                 /*
219                  * Zero-extend the result beyond 16 bits, do not trust the
220                  * BIOS having done it:
221                  */
222                 *value &= 0xffff;
223                 break;
224         case 4:
225                 __asm__("lcall *(%%esi); cld\n\t"
226                         "jc 1f\n\t"
227                         "xor %%ah, %%ah\n"
228                         "1:"
229                         : "=c" (*value),
230                           "=a" (result)
231                         : "1" (PCIBIOS_READ_CONFIG_DWORD),
232                           "b" (bx),
233                           "D" ((long)reg),
234                           "S" (&pci_indirect));
235                 break;
236         }
237 
238         spin_unlock_irqrestore(&pci_config_lock, flags);
239 
240         return (int)((result & 0xff00) >> 8);
241 }
242 
243 static int pci_bios_write(unsigned int seg, unsigned int bus,
244                           unsigned int devfn, int reg, int len, u32 value)
245 {
246         unsigned long result = 0;
247         unsigned long flags;
248         unsigned long bx = (bus << 8) | devfn;
249 
250         if ((bus > 255) || (devfn > 255) || (reg > 255)) 
251                 return -EINVAL;
252 
253         spin_lock_irqsave(&pci_config_lock, flags);
254 
255         switch (len) {
256         case 1:
257                 __asm__("lcall *(%%esi); cld\n\t"
258                         "jc 1f\n\t"
259                         "xor %%ah, %%ah\n"
260                         "1:"
261                         : "=a" (result)
262                         : "" (PCIBIOS_WRITE_CONFIG_BYTE),
263                           "c" (value),
264                           "b" (bx),
265                           "D" ((long)reg),
266                           "S" (&pci_indirect));
267                 break;
268         case 2:
269                 __asm__("lcall *(%%esi); cld\n\t"
270                         "jc 1f\n\t"
271                         "xor %%ah, %%ah\n"
272                         "1:"
273                         : "=a" (result)
274                         : "" (PCIBIOS_WRITE_CONFIG_WORD),
275                           "c" (value),
276                           "b" (bx),
277                           "D" ((long)reg),
278                           "S" (&pci_indirect));
279                 break;
280         case 4:
281                 __asm__("lcall *(%%esi); cld\n\t"
282                         "jc 1f\n\t"
283                         "xor %%ah, %%ah\n"
284                         "1:"
285                         : "=a" (result)
286                         : "" (PCIBIOS_WRITE_CONFIG_DWORD),
287                           "c" (value),
288                           "b" (bx),
289                           "D" ((long)reg),
290                           "S" (&pci_indirect));
291                 break;
292         }
293 
294         spin_unlock_irqrestore(&pci_config_lock, flags);
295 
296         return (int)((result & 0xff00) >> 8);
297 }
298 
299 
300 /*
301  * Function table for BIOS32 access
302  */
303 
304 static struct pci_raw_ops pci_bios_access = {
305         .read =         pci_bios_read,
306         .write =        pci_bios_write
307 };
308 
309 /*
310  * Try to find PCI BIOS.
311  */
312 
313 static struct pci_raw_ops * __devinit pci_find_bios(void)
314 {
315         union bios32 *check;
316         unsigned char sum;
317         int i, length;
318 
319         /*
320          * Follow the standard procedure for locating the BIOS32 Service
321          * directory by scanning the permissible address range from
322          * 0xe0000 through 0xfffff for a valid BIOS32 structure.
323          */
324 
325         for (check = (union bios32 *) __va(0xe0000);
326              check <= (union bios32 *) __va(0xffff0);
327              ++check) {
328                 long sig;
329                 if (probe_kernel_address(&check->fields.signature, sig))
330                         continue;
331 
332                 if (check->fields.signature != BIOS32_SIGNATURE)
333                         continue;
334                 length = check->fields.length * 16;
335                 if (!length)
336                         continue;
337                 sum = 0;
338                 for (i = 0; i < length ; ++i)
339                         sum += check->chars[i];
340                 if (sum != 0)
341                         continue;
342                 if (check->fields.revision != 0) {
343                         printk("PCI: unsupported BIOS32 revision %d at 0x%p\n",
344                                 check->fields.revision, check);
345                         continue;
346                 }
347                 DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check);
348                 if (check->fields.entry >= 0x100000) {
349                         printk("PCI: BIOS32 entry (0x%p) in high memory, "
350                                         "cannot use.\n", check);
351                         return NULL;
352                 } else {
353                         unsigned long bios32_entry = check->fields.entry;
354                         DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n",
355                                         bios32_entry);
356                         bios32_indirect.address = bios32_entry + PAGE_OFFSET;
357                         if (check_pcibios())
358                                 return &pci_bios_access;
359                 }
360                 break;  /* Hopefully more than one BIOS32 cannot happen... */
361         }
362 
363         return NULL;
364 }
365 
366 /*
367  * Sort the device list according to PCI BIOS. Nasty hack, but since some
368  * fool forgot to define the `correct' device order in the PCI BIOS specs
369  * and we want to be (possibly bug-to-bug ;-]) compatible with older kernels
370  * which used BIOS ordering, we are bound to do this...
371  */
372 
373 void __devinit pcibios_sort(void)
374 {
375         LIST_HEAD(sorted_devices);
376         struct list_head *ln;
377         struct pci_dev *dev, *d;
378         int idx, found;
379         unsigned char bus, devfn;
380 
381         DBG("PCI: Sorting device list...\n");
382         while (!list_empty(&pci_devices)) {
383                 ln = pci_devices.next;
384                 dev = pci_dev_g(ln);
385                 idx = found = 0;
386                 while (pci_bios_find_device(dev->vendor, dev->device, idx, &bus, &devfn) == PCIBIOS_SUCCESSFUL) {
387                         idx++;
388                         list_for_each(ln, &pci_devices) {
389                                 d = pci_dev_g(ln);
390                                 if (d->bus->number == bus && d->devfn == devfn) {
391                                         list_move_tail(&d->global_list, &sorted_devices);
392                                         if (d == dev)
393                                                 found = 1;
394                                         break;
395                                 }
396                         }
397                         if (ln == &pci_devices) {
398                                 printk(KERN_WARNING "PCI: BIOS reporting unknown device %02x:%02x\n", bus, devfn);
399                                 /*
400                                  * We must not continue scanning as several buggy BIOSes
401                                  * return garbage after the last device. Grr.
402                                  */
403                                 break;
404                         }
405                 }
406                 if (!found) {
407                         printk(KERN_WARNING "PCI: Device %s not found by BIOS\n",
408                                 pci_name(dev));
409                         list_move_tail(&dev->global_list, &sorted_devices);
410                 }
411         }
412         list_splice(&sorted_devices, &pci_devices);
413 }
414 
415 /*
416  *  BIOS Functions for IRQ Routing
417  */
418 
419 struct irq_routing_options {
420         u16 size;
421         struct irq_info *table;
422         u16 segment;
423 } __attribute__((packed));
424 
425 struct irq_routing_table * pcibios_get_irq_routing_table(void)
426 {
427         struct irq_routing_options opt;
428         struct irq_routing_table *rt = NULL;
429         int ret, map;
430         unsigned long page;
431 
432         if (!pci_bios_present)
433                 return NULL;
434         page = __get_free_page(GFP_KERNEL);
435         if (!page)
436                 return NULL;
437         opt.table = (struct irq_info *) page;
438         opt.size = PAGE_SIZE;
439         opt.segment = __KERNEL_DS;
440 
441         DBG("PCI: Fetching IRQ routing table... ");
442         __asm__("push %%es\n\t"
443                 "push %%ds\n\t"
444                 "pop  %%es\n\t"
445                 "lcall *(%%esi); cld\n\t"
446                 "pop %%es\n\t"
447                 "jc 1f\n\t"
448                 "xor %%ah, %%ah\n"
449                 "1:"
450                 : "=a" (ret),
451                   "=b" (map),
452                   "=m" (opt)
453                 : "" (PCIBIOS_GET_ROUTING_OPTIONS),
454                   "1" (0),
455                   "D" ((long) &opt),
456                   "S" (&pci_indirect),
457                   "m" (opt)
458                 : "memory");
459         DBG("OK  ret=%d, size=%d, map=%x\n", ret, opt.size, map);
460         if (ret & 0xff00)
461                 printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff);
462         else if (opt.size) {
463                 rt = kmalloc(sizeof(struct irq_routing_table) + opt.size, GFP_KERNEL);
464                 if (rt) {
465                         memset(rt, 0, sizeof(struct irq_routing_table));
466                         rt->size = opt.size + sizeof(struct irq_routing_table);
467                         rt->exclusive_irqs = map;
468                         memcpy(rt->slots, (void *) page, opt.size);
469                         printk(KERN_INFO "PCI: Using BIOS Interrupt Routing Table\n");
470                 }
471         }
472         free_page(page);
473         return rt;
474 }
475 EXPORT_SYMBOL(pcibios_get_irq_routing_table);
476 
477 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
478 {
479         int ret;
480 
481         __asm__("lcall *(%%esi); cld\n\t"
482                 "jc 1f\n\t"
483                 "xor %%ah, %%ah\n"
484                 "1:"
485                 : "=a" (ret)
486                 : "" (PCIBIOS_SET_PCI_HW_INT),
487                   "b" ((dev->bus->number << 8) | dev->devfn),
488                   "c" ((irq << 8) | (pin + 10)),
489                   "S" (&pci_indirect));
490         return !(ret & 0xff00);
491 }
492 EXPORT_SYMBOL(pcibios_set_irq_routing);
493 
494 void __init pci_pcbios_init(void)
495 {
496         if ((pci_probe & PCI_PROBE_BIOS) 
497                 && ((raw_pci_ops = pci_find_bios()))) {
498                 pci_probe |= PCI_BIOS_SORT;
499                 pci_bios_present = 1;
500         }
501 }
502 
503 
  This page was automatically generated by the LXR engine.