lkml.org 
[lkml]   [2015]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.10 11/22] hpsa: refine the pci enable/disable handling
    Date
    3.10-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Tomas Henzl <thenzl@redhat.com>

    commit 132aa220b45d60e9b20def1e9d8be9422eed9616 upstream.

    When a second(kdump) kernel starts and the hard reset method is used
    the driver calls pci_disable_device without previously enabling it,
    so the kernel shows a warning -
    [ 16.876248] WARNING: at drivers/pci/pci.c:1431 pci_disable_device+0x84/0x90()
    [ 16.882686] Device hpsa
    disabling already-disabled device
    ...
    This patch fixes it, in addition to this I tried to balance also some other pairs
    of enable/disable device in the driver.
    Unfortunately I wasn't able to verify the functionality for the case of a sw reset,
    because of a lack of proper hw.

    Signed-off-by: Tomas Henzl <thenzl@redhat.com>
    Reviewed-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/scsi/hpsa.c | 42 ++++++++++++++++++++++++++++--------------
    1 file changed, 28 insertions(+), 14 deletions(-)

    --- a/drivers/scsi/hpsa.c
    +++ b/drivers/scsi/hpsa.c
    @@ -3898,10 +3898,6 @@ static int hpsa_kdump_hard_reset_control

    /* Save the PCI command register */
    pci_read_config_word(pdev, 4, &command_register);
    - /* Turn the board off. This is so that later pci_restore_state()
    - * won't turn the board on before the rest of config space is ready.
    - */
    - pci_disable_device(pdev);
    pci_save_state(pdev);

    /* find the first memory BAR, so we can find the cfg table */
    @@ -3949,11 +3945,6 @@ static int hpsa_kdump_hard_reset_control
    goto unmap_cfgtable;

    pci_restore_state(pdev);
    - rc = pci_enable_device(pdev);
    - if (rc) {
    - dev_warn(&pdev->dev, "failed to enable device.\n");
    - goto unmap_cfgtable;
    - }
    pci_write_config_word(pdev, 4, command_register);

    /* Some devices (notably the HP Smart Array 5i Controller)
    @@ -4448,6 +4439,23 @@ static int hpsa_init_reset_devices(struc
    if (!reset_devices)
    return 0;

    + /* kdump kernel is loading, we don't know in which state is
    + * the pci interface. The dev->enable_cnt is equal zero
    + * so we call enable+disable, wait a while and switch it on.
    + */
    + rc = pci_enable_device(pdev);
    + if (rc) {
    + dev_warn(&pdev->dev, "Failed to enable PCI device\n");
    + return -ENODEV;
    + }
    + pci_disable_device(pdev);
    + msleep(260); /* a randomly chosen number */
    + rc = pci_enable_device(pdev);
    + if (rc) {
    + dev_warn(&pdev->dev, "failed to enable device.\n");
    + return -ENODEV;
    + }
    +
    /* Reset the controller with a PCI power-cycle or via doorbell */
    rc = hpsa_kdump_hard_reset_controller(pdev);

    @@ -4456,10 +4464,11 @@ static int hpsa_init_reset_devices(struc
    * "performant mode". Or, it might be 640x, which can't reset
    * due to concerns about shared bbwc between 6402/6404 pair.
    */
    - if (rc == -ENOTSUPP)
    - return rc; /* just try to do the kdump anyhow. */
    - if (rc)
    - return -ENODEV;
    + if (rc) {
    + if (rc != -ENOTSUPP) /* just try to do the kdump anyhow. */
    + rc = -ENODEV;
    + goto out_disable;
    + }

    /* Now try to get the controller to respond to a no-op */
    dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n");
    @@ -4470,7 +4479,11 @@ static int hpsa_init_reset_devices(struc
    dev_warn(&pdev->dev, "no-op failed%s\n",
    (i < 11 ? "; re-trying" : ""));
    }
    - return 0;
    +
    +out_disable:
    +
    + pci_disable_device(pdev);
    + return rc;
    }

    static int hpsa_allocate_cmd_pool(struct ctlr_info *h)
    @@ -4613,6 +4626,7 @@ static void hpsa_undo_allocations_after_
    iounmap(h->transtable);
    if (h->cfgtable)
    iounmap(h->cfgtable);
    + pci_disable_device(h->pdev);
    pci_release_regions(h->pdev);
    kfree(h);
    }



    \
     
     \ /
      Last update: 2015-07-01 21:01    [W:3.627 / U:0.804 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site