lkml.org 
[lkml]   [2010]   [Mar]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[089/156] PCI: fix access of PCI_X_CMD by pcix get and set mmrbc functions
    2.6.33-stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: Dean Nelson <dnelson@redhat.com>

    commit bdc2bda7c4dd253026cc1fce45fc939304749029 upstream.

    An e1000 driver on a system with a PCI-X bus was always being returned
    a value of 135 from both pcix_get_mmrbc() and pcix_set_mmrbc(). This
    value reflects an error return of PCIBIOS_BAD_REGISTER_NUMBER from
    pci_bus_read_config_dword(,, cap + PCI_X_CMD,).

    This is because for a dword, the following portion of the PCI_OP_READ()
    macro:

    if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;
    expands to:

    if (pos & 3) return PCIBIOS_BAD_REGISTER_NUMBER;
    And is always true for 'cap + PCI_X_CMD', which is 0xe4 + 2 = 0xe6. ('cap' is
    the result of calling pci_find_capability(, PCI_CAP_ID_PCIX).)

    The same problem exists for pci_bus_write_config_dword(,, cap + PCI_X_CMD,).
    In both cases, instead of calling _dword(), _word() should be called.

    Signed-off-by: Dean Nelson <dnelson@redhat.com>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/pci/pci.c | 11 ++++++-----
    1 file changed, 6 insertions(+), 5 deletions(-)
    --- a/drivers/pci/pci.c
    +++ b/drivers/pci/pci.c
    @@ -2446,13 +2446,13 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc);
    int pcix_get_mmrbc(struct pci_dev *dev)
    {
    int ret, cap;
    - u32 cmd;
    + u16 cmd;

    cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
    if (!cap)
    return -EINVAL;

    - ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
    + ret = pci_read_config_word(dev, cap + PCI_X_CMD, &cmd);
    if (!ret)
    ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);

    @@ -2472,7 +2472,8 @@ EXPORT_SYMBOL(pcix_get_mmrbc);
    int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
    {
    int cap, err = -EINVAL;
    - u32 stat, cmd, v, o;
    + u32 stat, v, o;
    + u16 cmd;

    if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc))
    goto out;
    @@ -2490,7 +2491,7 @@ int pcix_set_mmrbc(struct pci_dev *dev,
    if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
    return -E2BIG;

    - err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
    + err = pci_read_config_word(dev, cap + PCI_X_CMD, &cmd);
    if (err)
    goto out;

    @@ -2502,7 +2503,7 @@ int pcix_set_mmrbc(struct pci_dev *dev,

    cmd &= ~PCI_X_CMD_MAX_READ;
    cmd |= v << 2;
    - err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
    + err = pci_write_config_word(dev, cap + PCI_X_CMD, cmd);
    }
    out:
    return err;



    \
     
     \ /
      Last update: 2010-03-31 01:41    [from the cache]
    ©2003-2014 Jasper Spaans. hosted at Digital Ocean