lkml.org 
[lkml]   [2006]   [Mar]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2.6.16-mm1 1/4] PCI legacy I/O port free driver (take 6) - Changes to generic PCI code
    This patch adds the following changes into generic PCI code especially
    for PCI legacy free drivers.

    - Moved the following two things from pci_enable_device() into
    pci_enable_device_bars(). By this change, we can use
    pci_enable_device_bars() to enable only the specific regions.

    o Call pci_fixup_device() on the device
    o Set dev->is_enabled

    - Added new field 'bars_enabled' into struct pci_device to
    remember which BARs already enabled. This new field is
    initialized at pci_enable_device_bars() time and cleared
    at pci_disable_device() time.

    - Changed pci_request_regions()/pci_release_regions() to
    request/release only the regions which have already been
    enabled.

    - Added helper routine pci_select_bars() which makes proper mask
    of BARs from the specified resource type. This would be very
    helpful for users of pci_enable_device_bars().

    Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>

    ---
    drivers/pci/pci-driver.c | 3 ++-
    drivers/pci/pci.c | 30 +++++++++++++++++++++++-------
    include/linux/pci.h | 12 ++++++++++++
    3 files changed, 37 insertions(+), 8 deletions(-)

    Index: linux-2.6.16-mm1/drivers/pci/pci-driver.c
    ===================================================================
    --- linux-2.6.16-mm1.orig/drivers/pci/pci-driver.c 2006-03-23 20:04:06.000000000 +0900
    +++ linux-2.6.16-mm1/drivers/pci/pci-driver.c 2006-03-23 20:04:11.000000000 +0900
    @@ -293,7 +293,8 @@
    pci_restore_state(pci_dev);
    /* if the device was enabled before suspend, reenable */
    if (pci_dev->is_enabled)
    - retval = pci_enable_device(pci_dev);
    + retval = pci_enable_device_bars(pci_dev,
    + pci_dev->bars_enabled);
    /* if the device was busmaster before the suspend, make it busmaster again */
    if (pci_dev->is_busmaster)
    pci_set_master(pci_dev);
    Index: linux-2.6.16-mm1/drivers/pci/pci.c
    ===================================================================
    --- linux-2.6.16-mm1.orig/drivers/pci/pci.c 2006-03-23 20:04:06.000000000 +0900
    +++ linux-2.6.16-mm1/drivers/pci/pci.c 2006-03-23 20:04:11.000000000 +0900
    @@ -493,6 +493,9 @@
    err = pcibios_enable_device(dev, bars);
    if (err < 0)
    return err;
    + pci_fixup_device(pci_fixup_enable, dev);
    + dev->is_enabled = 1;
    + dev->bars_enabled = bars;
    return 0;
    }

    @@ -510,8 +513,6 @@
    int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
    if (err)
    return err;
    - pci_fixup_device(pci_fixup_enable, dev);
    - dev->is_enabled = 1;
    return 0;
    }

    @@ -546,6 +547,7 @@

    pcibios_disable_device(dev);
    dev->is_enabled = 0;
    + dev->bars_enabled = 0;
    }

    /**
    @@ -628,6 +630,12 @@
    {
    if (pci_resource_len(pdev, bar) == 0)
    return;
    + if (!(pdev->bars_enabled & (1 << bar))) {
    + dev_warn(&pdev->dev,
    + "Trying to release region #%d that is not enabled\n",
    + bar + 1);
    + return;
    + }
    if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
    release_region(pci_resource_start(pdev, bar),
    pci_resource_len(pdev, bar));
    @@ -654,7 +662,12 @@
    {
    if (pci_resource_len(pdev, bar) == 0)
    return 0;
    -
    + if (!(pdev->bars_enabled & (1 << bar))) {
    + dev_warn(&pdev->dev,
    + "Trying to request region #%d that is not enabled\n",
    + bar + 1);
    + goto err_out;
    + }
    if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
    if (!request_region(pci_resource_start(pdev, bar),
    pci_resource_len(pdev, bar), res_name))
    @@ -692,7 +705,8 @@
    int i;

    for (i = 0; i < 6; i++)
    - pci_release_region(pdev, i);
    + if (pdev->bars_enabled & (1 << i))
    + pci_release_region(pdev, i);
    }

    /**
    @@ -713,13 +727,15 @@
    int i;

    for (i = 0; i < 6; i++)
    - if(pci_request_region(pdev, i, res_name))
    - goto err_out;
    + if (pdev->bars_enabled & (1 << i))
    + if(pci_request_region(pdev, i, res_name))
    + goto err_out;
    return 0;

    err_out:
    while(--i >= 0)
    - pci_release_region(pdev, i);
    + if (pdev->bars_enabled & (1 << i))
    + pci_release_region(pdev, i);

    return -EBUSY;
    }
    Index: linux-2.6.16-mm1/include/linux/pci.h
    ===================================================================
    --- linux-2.6.16-mm1.orig/include/linux/pci.h 2006-03-23 20:04:06.000000000 +0900
    +++ linux-2.6.16-mm1/include/linux/pci.h 2006-03-23 20:04:11.000000000 +0900
    @@ -169,6 +169,7 @@
    struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
    int rom_attr_enabled; /* has display of the rom attribute been enabled? */
    struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
    + int bars_enabled; /* BARs enabled */
    };

    #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
    @@ -732,6 +733,17 @@
    }
    #endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */

    +/*
    + * This helper routine makes bar mask from the type of resource.
    + */
    +static inline int pci_select_bars(struct pci_dev *dev, unsigned long flags)
    +{
    + int i, bars = 0;
    + for (i = 0; i < PCI_NUM_RESOURCES; i++)
    + if (pci_resource_flags(dev, i) & flags)
    + bars |= (1 << i);
    + return bars;
    +}

    /*
    * The world is not perfect and supplies us with broken PCI devices.
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-03-24 06:41    [W:0.031 / U:0.156 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site