|
3 | 3 | * BIOS32 and PCI BIOS handling. |
4 | 4 | */ |
5 | 5 |
|
| 6 | +#include <linux/bits.h> |
| 7 | +#include <linux/bitfield.h> |
6 | 8 | #include <linux/pci.h> |
7 | 9 | #include <linux/init.h> |
8 | 10 | #include <linux/slab.h> |
|
29 | 31 | #define PCIBIOS_HW_TYPE1_SPEC 0x10 |
30 | 32 | #define PCIBIOS_HW_TYPE2_SPEC 0x20 |
31 | 33 |
|
| 34 | +/* |
| 35 | + * Returned in EAX: |
| 36 | + * - AH: return code |
| 37 | + */ |
| 38 | +#define PCIBIOS_RETURN_CODE GENMASK(15, 8) |
| 39 | + |
32 | 40 | int pcibios_enabled; |
33 | 41 |
|
| 42 | +static u8 pcibios_get_return_code(u32 eax) |
| 43 | +{ |
| 44 | + return FIELD_GET(PCIBIOS_RETURN_CODE, eax); |
| 45 | +} |
| 46 | + |
34 | 47 | /* According to the BIOS specification at: |
35 | 48 | * http://members.datafast.net.au/dft0802/specs/bios21.pdf, we could |
36 | 49 | * restrict the x zone to some pages and make it ro. But this may be |
@@ -154,7 +167,7 @@ static int __init check_pcibios(void) |
154 | 167 | : "memory"); |
155 | 168 | local_irq_restore(flags); |
156 | 169 |
|
157 | | - status = (eax >> 8) & 0xff; |
| 170 | + status = pcibios_get_return_code(eax); |
158 | 171 | hw_mech = eax & 0xff; |
159 | 172 | major_ver = (ebx >> 8) & 0xff; |
160 | 173 | minor_ver = ebx & 0xff; |
@@ -227,7 +240,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, |
227 | 240 |
|
228 | 241 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
229 | 242 |
|
230 | | - return (int)((result & 0xff00) >> 8); |
| 243 | + return pcibios_get_return_code(result); |
231 | 244 | } |
232 | 245 |
|
233 | 246 | static int pci_bios_write(unsigned int seg, unsigned int bus, |
@@ -269,7 +282,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, |
269 | 282 |
|
270 | 283 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
271 | 284 |
|
272 | | - return (int)((result & 0xff00) >> 8); |
| 285 | + return pcibios_get_return_code(result); |
273 | 286 | } |
274 | 287 |
|
275 | 288 |
|
@@ -385,9 +398,10 @@ struct irq_routing_table * pcibios_get_irq_routing_table(void) |
385 | 398 | "m" (opt) |
386 | 399 | : "memory"); |
387 | 400 | DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map); |
388 | | - if (ret & 0xff00) |
389 | | - printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff); |
390 | | - else if (opt.size) { |
| 401 | + ret = pcibios_get_return_code(ret); |
| 402 | + if (ret) { |
| 403 | + printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", ret); |
| 404 | + } else if (opt.size) { |
391 | 405 | rt = kmalloc(sizeof(struct irq_routing_table) + opt.size, GFP_KERNEL); |
392 | 406 | if (rt) { |
393 | 407 | memset(rt, 0, sizeof(struct irq_routing_table)); |
@@ -415,7 +429,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq) |
415 | 429 | "b" ((dev->bus->number << 8) | dev->devfn), |
416 | 430 | "c" ((irq << 8) | (pin + 10)), |
417 | 431 | "S" (&pci_indirect)); |
418 | | - return !(ret & 0xff00); |
| 432 | + return pcibios_get_return_code(ret) == PCIBIOS_SUCCESSFUL; |
419 | 433 | } |
420 | 434 | EXPORT_SYMBOL(pcibios_set_irq_routing); |
421 | 435 |
|
|
0 commit comments