lkml.org 
[lkml]   [1997]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: Compaq PCI probs


    Found a small bug in last patch for 2.1.26 :-(
    ... sorry for that ... my fault.

    It's missing the inlined save_flags/restore_flags.

    With `#include <asm/system.h>' it should work :-)

    Hope this will the working one.

    Werner
    --------------------------- 2.1.2x --------------------------------------
    diff -urN linux-clean/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
    --- linux-clean/arch/i386/kernel/bios32.c Mon Dec 23 18:25:31 1996
    +++ linux/arch/i386/kernel/bios32.c Thu Feb 13 00:16:49 1997
    @@ -49,6 +49,9 @@
    * Dec 7, 1996 : Added support for direct configuration access of boards
    * with Intel compatible access schemes (tsbogend@alpha.franken.de)
    *
    + * Feb 3, 1997 : Set internal functions to static, save/restore flags
    + * avoid dead locks reading broken PCI BIOS, werner@suse.de
    + *
    */

    #include <linux/config.h>
    @@ -59,6 +62,7 @@

    #include <asm/page.h>
    #include <asm/segment.h>
    +#include <asm/system.h>
    #include <asm/io.h>

    #define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
    @@ -137,7 +141,7 @@
    /*
    * pointer to selected PCI access function table
    */
    -struct pci_access *access_pci = NULL;
    +static struct pci_access *access_pci = NULL;



    @@ -151,7 +155,9 @@
    unsigned long address; /* %ebx */
    unsigned long length; /* %ecx */
    unsigned long entry; /* %edx */
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%edi)"
    : "=a" (return_code),
    "=b" (address),
    @@ -160,6 +166,7 @@
    : "0" (service),
    "1" (0),
    "D" (&bios32_indirect));
    + restore_flags(flags);

    switch (return_code) {
    case 0:
    @@ -187,11 +194,13 @@
    unsigned char present_status;
    unsigned char major_revision;
    unsigned char minor_revision;
    + unsigned long flags;
    int pack;

    if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
    pci_indirect.address = pcibios_entry | PAGE_OFFSET;

    + save_flags(flags);
    __asm__("lcall (%%edi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -202,6 +211,7 @@
    : "1" (PCIBIOS_PCI_BIOS_PRESENT),
    "D" (&pci_indirect)
    : "bx", "cx");
    + restore_flags(flags);

    present_status = (pack >> 16) & 0xff;
    major_revision = (pack >> 8) & 0xff;
    @@ -227,12 +237,14 @@
    }


    -int pci_bios_find_class (unsigned int class_code, unsigned short index,
    +static int pci_bios_find_class (unsigned int class_code, unsigned short index,
    unsigned char *bus, unsigned char *device_fn)
    {
    unsigned long bx;
    unsigned long ret;
    + unsigned long flags;

    + save_flags(flags);
    __asm__ ("lcall (%%edi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -243,18 +255,21 @@
    "c" (class_code),
    "S" ((int) index),
    "D" (&pci_indirect));
    + restore_flags(flags);
    *bus = (bx >> 8) & 0xff;
    *device_fn = bx & 0xff;
    return (int) (ret & 0xff00) >> 8;
    }


    -int pci_bios_find_device (unsigned short vendor, unsigned short device_id,
    +static int pci_bios_find_device (unsigned short vendor, unsigned short device_id,
    unsigned short index, unsigned char *bus, unsigned char *device_fn)
    {
    unsigned short bx;
    unsigned short ret;
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%edi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -266,17 +281,20 @@
    "d" (vendor),
    "S" ((int) index),
    "D" (&pci_indirect));
    + restore_flags(flags);
    *bus = (bx >> 8) & 0xff;
    *device_fn = bx & 0xff;
    return (int) (ret & 0xff00) >> 8;
    }

    -int pci_bios_read_config_byte(unsigned char bus,
    +static int pci_bios_read_config_byte(unsigned char bus,
    unsigned char device_fn, unsigned char where, unsigned char *value)
    {
    unsigned long ret;
    unsigned long bx = (bus << 8) | device_fn;
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%esi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -287,15 +305,18 @@
    "b" (bx),
    "D" ((long) where),
    "S" (&pci_indirect));
    + restore_flags(flags);
    return (int) (ret & 0xff00) >> 8;
    }

    -int pci_bios_read_config_word (unsigned char bus,
    +static int pci_bios_read_config_word (unsigned char bus,
    unsigned char device_fn, unsigned char where, unsigned short *value)
    {
    unsigned long ret;
    unsigned long bx = (bus << 8) | device_fn;
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%esi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -306,15 +327,18 @@
    "b" (bx),
    "D" ((long) where),
    "S" (&pci_indirect));
    + restore_flags(flags);
    return (int) (ret & 0xff00) >> 8;
    }

    -int pci_bios_read_config_dword (unsigned char bus,
    +static int pci_bios_read_config_dword (unsigned char bus,
    unsigned char device_fn, unsigned char where, unsigned int *value)
    {
    unsigned long ret;
    unsigned long bx = (bus << 8) | device_fn;
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%esi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -325,15 +349,18 @@
    "b" (bx),
    "D" ((long) where),
    "S" (&pci_indirect));
    + restore_flags(flags);
    return (int) (ret & 0xff00) >> 8;
    }

    -int pci_bios_write_config_byte (unsigned char bus,
    +static int pci_bios_write_config_byte (unsigned char bus,
    unsigned char device_fn, unsigned char where, unsigned char value)
    {
    unsigned long ret;
    unsigned long bx = (bus << 8) | device_fn;
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%esi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -344,15 +371,18 @@
    "b" (bx),
    "D" ((long) where),
    "S" (&pci_indirect));
    + restore_flags(flags);
    return (int) (ret & 0xff00) >> 8;
    }

    -int pci_bios_write_config_word (unsigned char bus,
    +static int pci_bios_write_config_word (unsigned char bus,
    unsigned char device_fn, unsigned char where, unsigned short value)
    {
    unsigned long ret;
    unsigned long bx = (bus << 8) | device_fn;
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%esi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -363,15 +393,18 @@
    "b" (bx),
    "D" ((long) where),
    "S" (&pci_indirect));
    + restore_flags(flags);
    return (int) (ret & 0xff00) >> 8;
    }

    -int pci_bios_write_config_dword (unsigned char bus,
    +static int pci_bios_write_config_dword (unsigned char bus,
    unsigned char device_fn, unsigned char where, unsigned int value)
    {
    unsigned long ret;
    unsigned long bx = (bus << 8) | device_fn;
    + unsigned long flags;

    + save_flags(flags);
    __asm__("lcall (%%esi)\n\t"
    "jc 1f\n\t"
    "xor %%ah, %%ah\n"
    @@ -382,13 +415,14 @@
    "b" (bx),
    "D" ((long) where),
    "S" (&pci_indirect));
    + restore_flags(flags);
    return (int) (ret & 0xff00) >> 8;
    }

    /*
    * function table for BIOS32 access
    */
    -struct pci_access pci_bios_access = {
    +static struct pci_access pci_bios_access = {
    pci_bios_find_device,
    pci_bios_find_class,
    pci_bios_read_config_byte,
    @@ -405,23 +439,27 @@
    * Given the vendor and device ids, find the n'th instance of that device
    * in the system.
    */
    -int pci_direct_find_device (unsigned short vendor, unsigned short device_id,
    +static int pci_direct_find_device (unsigned short vendor, unsigned short device_id,
    unsigned short index, unsigned char *bus,
    unsigned char *devfn)
    {
    unsigned int curr = 0;
    struct pci_dev *dev;
    + unsigned long flags;

    + save_flags(flags);
    for (dev = pci_devices; dev; dev = dev->next) {
    if (dev->vendor == vendor && dev->device == device_id) {
    if (curr == index) {
    *devfn = dev->devfn;
    *bus = dev->bus->number;
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }
    ++curr;
    }
    }
    + restore_flags(flags);
    return PCIBIOS_DEVICE_NOT_FOUND;
    }

    @@ -430,22 +468,26 @@
    * Given the class, find the n'th instance of that device
    * in the system.
    */
    -int pci_direct_find_class (unsigned int class_code, unsigned short index,
    +static int pci_direct_find_class (unsigned int class_code, unsigned short index,
    unsigned char *bus, unsigned char *devfn)
    {
    unsigned int curr = 0;
    struct pci_dev *dev;
    + unsigned long flags;

    + save_flags(flags);
    for (dev = pci_devices; dev; dev = dev->next) {
    if (dev->class == class_code) {
    if (curr == index) {
    *devfn = dev->devfn;
    *bus = dev->bus->number;
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }
    ++curr;
    }
    }
    + restore_flags(flags);
    return PCIBIOS_DEVICE_NOT_FOUND;
    }

    @@ -454,9 +496,12 @@
    */
    #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))

    -int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn,
    +static int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned char *value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
    switch (where & 3) {
    case 0: *value = inb(0xCFC);
    @@ -468,49 +513,70 @@
    case 3: *value = inb(0xCFF);
    break;
    }
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf1_read_config_word (unsigned char bus,
    +static int pci_conf1_read_config_word (unsigned char bus,
    unsigned char device_fn, unsigned char where, unsigned short *value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
    if (where & 2)
    *value = inw(0xCFE);
    else
    *value = inw(0xCFC);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn,
    +static int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned int *value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
    *value = inl(0xCFC);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn,
    +static int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned char value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
    outb(value, 0xCFC);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn,
    +static int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned short value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
    outw(value, 0xCFC);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn,
    +static int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned int value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
    outl(value, 0xCFC);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    @@ -519,7 +585,7 @@
    /*
    * functiontable for type 1
    */
    -struct pci_access pci_direct_conf1 = {
    +static struct pci_access pci_direct_conf1 = {
    pci_direct_find_device,
    pci_direct_find_class,
    pci_conf1_read_config_byte,
    @@ -536,69 +602,93 @@
    #define IOADDR(devfn, where) ((0xC000 | ((devfn & 0x78) << 5)) + where)
    #define FUNC(devfn) (((devfn & 7) << 1) | 0xf0)

    -int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn,
    +static int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned char *value)
    {
    + unsigned long flags;
    +
    if (device_fn & 0x80)
    return PCIBIOS_DEVICE_NOT_FOUND;
    + save_flags(flags);
    outb (FUNC(device_fn), 0xCF8);
    outb (bus, 0xCFA);
    *value = inb(IOADDR(device_fn,where));
    outb (0, 0xCF8);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn,
    +static int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned short *value)
    {
    + unsigned long flags;
    +
    if (device_fn & 0x80)
    return PCIBIOS_DEVICE_NOT_FOUND;
    + save_flags(flags);
    outb (FUNC(device_fn), 0xCF8);
    outb (bus, 0xCFA);
    *value = inw(IOADDR(device_fn,where));
    - outb (0, 0xCF8);
    + outb (0, 0xCF8);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn,
    +static int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned int *value)
    {
    + unsigned long flags;
    +
    if (device_fn & 0x80)
    return PCIBIOS_DEVICE_NOT_FOUND;
    + save_flags(flags);
    outb (FUNC(device_fn), 0xCF8);
    outb (bus, 0xCFA);
    *value = inl (IOADDR(device_fn,where));
    outb (0, 0xCF8);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn,
    +static int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned char value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outb (FUNC(device_fn), 0xCF8);
    outb (bus, 0xCFA);
    outb (value, IOADDR(device_fn,where));
    outb (0, 0xCF8);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn,
    +static int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned short value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outb (FUNC(device_fn), 0xCF8);
    outb (bus, 0xCFA);
    outw (value, IOADDR(device_fn,where));
    outb (0, 0xCF8);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    -int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn,
    +static int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn,
    unsigned char where, unsigned int value)
    {
    + unsigned long flags;
    +
    + save_flags(flags);
    outb (FUNC(device_fn), 0xCF8);
    outb (bus, 0xCFA);
    outl (value, IOADDR(device_fn,where));
    outb (0, 0xCF8);
    + restore_flags(flags);
    return PCIBIOS_SUCCESSFUL;
    }

    @@ -608,7 +698,7 @@
    /*
    * functiontable for type 2
    */
    -struct pci_access pci_direct_conf2 = {
    +static struct pci_access pci_direct_conf2 = {
    pci_direct_find_device,
    pci_direct_find_class,
    pci_conf2_read_config_byte,
    @@ -620,9 +710,12 @@
    };


    -struct pci_access *check_direct_pci(void)
    +static struct pci_access *check_direct_pci(void)
    {
    unsigned int tmp;
    + unsigned long flags;
    +
    + save_flags(flags);

    /*
    * check if configuration type 1 works
    @@ -632,6 +725,7 @@
    outl (0x80000000, 0xCF8);
    if (inl (0xCF8) == 0x80000000) {
    outl (tmp, 0xCF8);
    + restore_flags(flags);
    printk("pcibios_init: Using configuration type 1\n");
    return &pci_direct_conf1;
    }
    @@ -644,9 +738,11 @@
    outb (0x00, 0xCF8);
    outb (0x00, 0xCFA);
    if (inb (0xCF8) == 0x00 && inb (0xCFC) == 0x00) {
    + restore_flags(flags);
    printk("pcibios_init: Using configuration type 2\n");
    return &pci_direct_conf2;
    }
    + restore_flags(flags);
    printk("pcibios_init: Not supported chipset for direct PCI access !\n");
    return NULL;
    }
    --------------------------- 2.1.2x --------------------------------------
    \
     
     \ /
      Last update: 2005-03-22 13:38    [W:0.050 / U:60.972 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site