summaryrefslogtreecommitdiff
path: root/libdde_linux26/lib/src/drivers/pci
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2011-05-08 23:11:02 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2011-05-08 23:11:02 +0200
commitcded208c7ea6d107dcbfdb2e2d4622daf41c2886 (patch)
treea04a03736b0a928c2954382f924aadb105ee39cc /libdde_linux26/lib/src/drivers/pci
parentfc82e00ca1e174cb961dea6ad37622e9b26cd899 (diff)
remove .svn directories
Diffstat (limited to 'libdde_linux26/lib/src/drivers/pci')
-rw-r--r--libdde_linux26/lib/src/drivers/pci/.svn/all-wcprops23
-rw-r--r--libdde_linux26/lib/src/drivers/pci/.svn/entries130
-rw-r--r--libdde_linux26/lib/src/drivers/pci/.svn/format1
-rw-r--r--libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci-driver.c.svn-base1008
-rw-r--r--libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci.c.svn-base2480
-rw-r--r--libdde_linux26/lib/src/drivers/pci/.svn/text-base/probe.c.svn-base1232
6 files changed, 0 insertions, 4874 deletions
diff --git a/libdde_linux26/lib/src/drivers/pci/.svn/all-wcprops b/libdde_linux26/lib/src/drivers/pci/.svn/all-wcprops
deleted file mode 100644
index 579ef35f..00000000
--- a/libdde_linux26/lib/src/drivers/pci/.svn/all-wcprops
+++ /dev/null
@@ -1,23 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 70
-/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/drivers/pci
-END
-pci-driver.c
-K 25
-svn:wc:ra_dav:version-url
-V 83
-/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/drivers/pci/pci-driver.c
-END
-probe.c
-K 25
-svn:wc:ra_dav:version-url
-V 78
-/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/drivers/pci/probe.c
-END
-pci.c
-K 25
-svn:wc:ra_dav:version-url
-V 76
-/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/drivers/pci/pci.c
-END
diff --git a/libdde_linux26/lib/src/drivers/pci/.svn/entries b/libdde_linux26/lib/src/drivers/pci/.svn/entries
deleted file mode 100644
index ba911e04..00000000
--- a/libdde_linux26/lib/src/drivers/pci/.svn/entries
+++ /dev/null
@@ -1,130 +0,0 @@
-9
-
-dir
-465
-http://svn.tudos.org/repos/tudos/trunk/l4/pkg/dde/linux26/lib/src/drivers/pci
-http://svn.tudos.org/repos/tudos
-
-
-
-2009-05-20T14:32:55.606606Z
-455
-l4check
-
-
-svn:special svn:externals svn:needs-lock
-
-
-
-
-
-
-
-
-
-
-
-a704ac0b-3a55-4d43-a2a9-7be6f07c34fb
-
-pci-driver.c
-file
-
-
-
-
-2009-11-15T17:17:13.000000Z
-928cd4ba1afdac7f2758391207734dff
-2009-05-20T14:32:55.606606Z
-455
-l4check
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-23851
-
-probe.c
-file
-
-
-
-
-2009-11-15T17:17:13.000000Z
-30ba0348e208a49904d1117852afe55f
-2009-05-20T14:32:55.606606Z
-455
-l4check
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-32125
-
-pci.c
-file
-
-
-
-
-2009-11-15T17:17:13.000000Z
-b8e363a840fc04948d1e7f74a8de59fa
-2009-05-20T14:32:55.606606Z
-455
-l4check
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-65407
-
diff --git a/libdde_linux26/lib/src/drivers/pci/.svn/format b/libdde_linux26/lib/src/drivers/pci/.svn/format
deleted file mode 100644
index ec635144..00000000
--- a/libdde_linux26/lib/src/drivers/pci/.svn/format
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci-driver.c.svn-base b/libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci-driver.c.svn-base
deleted file mode 100644
index 199ec8a7..00000000
--- a/libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci-driver.c.svn-base
+++ /dev/null
@@ -1,1008 +0,0 @@
-/*
- * drivers/pci/pci-driver.c
- *
- * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com>
- * (C) Copyright 2007 Novell Inc.
- *
- * Released under the GPL v2 only.
- *
- */
-
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/mempolicy.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/cpu.h>
-#include "pci.h"
-
-#ifdef DDE_LINUX
-#include "local.h"
-#endif /* DDE_LINUX */
-
-/*
- * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
- */
-
-struct pci_dynid {
- struct list_head node;
- struct pci_device_id id;
-};
-
-#ifdef CONFIG_HOTPLUG
-
-/**
- * store_new_id - add a new PCI device ID to this driver and re-probe devices
- * @driver: target device driver
- * @buf: buffer for scanning device ID data
- * @count: input size
- *
- * Adds a new dynamic pci device ID to this driver,
- * and causes the driver to probe for all devices again.
- */
-static ssize_t
-store_new_id(struct device_driver *driver, const char *buf, size_t count)
-{
- struct pci_dynid *dynid;
- struct pci_driver *pdrv = to_pci_driver(driver);
- const struct pci_device_id *ids = pdrv->id_table;
- __u32 vendor, device, subvendor=PCI_ANY_ID,
- subdevice=PCI_ANY_ID, class=0, class_mask=0;
- unsigned long driver_data=0;
- int fields=0;
- int retval=0;
-
- fields = sscanf(buf, "%x %x %x %x %x %x %lx",
- &vendor, &device, &subvendor, &subdevice,
- &class, &class_mask, &driver_data);
- if (fields < 2)
- return -EINVAL;
-
- /* Only accept driver_data values that match an existing id_table
- entry */
- if (ids) {
- retval = -EINVAL;
- while (ids->vendor || ids->subvendor || ids->class_mask) {
- if (driver_data == ids->driver_data) {
- retval = 0;
- break;
- }
- ids++;
- }
- if (retval) /* No match */
- return retval;
- }
-
- dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
- if (!dynid)
- return -ENOMEM;
-
- dynid->id.vendor = vendor;
- dynid->id.device = device;
- dynid->id.subvendor = subvendor;
- dynid->id.subdevice = subdevice;
- dynid->id.class = class;
- dynid->id.class_mask = class_mask;
- dynid->id.driver_data = driver_data;
-
- spin_lock(&pdrv->dynids.lock);
- list_add_tail(&dynid->node, &pdrv->dynids.list);
- spin_unlock(&pdrv->dynids.lock);
-
- if (get_driver(&pdrv->driver)) {
- retval = driver_attach(&pdrv->driver);
- put_driver(&pdrv->driver);
- }
-
- if (retval)
- return retval;
- return count;
-}
-static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
-
-static void
-pci_free_dynids(struct pci_driver *drv)
-{
- struct pci_dynid *dynid, *n;
-
- spin_lock(&drv->dynids.lock);
- list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
- list_del(&dynid->node);
- kfree(dynid);
- }
- spin_unlock(&drv->dynids.lock);
-}
-
-static int
-pci_create_newid_file(struct pci_driver *drv)
-{
- int error = 0;
- if (drv->probe != NULL)
- error = driver_create_file(&drv->driver, &driver_attr_new_id);
- return error;
-}
-
-static void pci_remove_newid_file(struct pci_driver *drv)
-{
- driver_remove_file(&drv->driver, &driver_attr_new_id);
-}
-#else /* !CONFIG_HOTPLUG */
-static inline void pci_free_dynids(struct pci_driver *drv) {}
-static inline int pci_create_newid_file(struct pci_driver *drv)
-{
- return 0;
-}
-static inline void pci_remove_newid_file(struct pci_driver *drv) {}
-#endif
-
-/**
- * pci_match_id - See if a pci device matches a given pci_id table
- * @ids: array of PCI device id structures to search in
- * @dev: the PCI device structure to match against.
- *
- * Used by a driver to check whether a PCI device present in the
- * system is in its list of supported devices. Returns the matching
- * pci_device_id structure or %NULL if there is no match.
- *
- * Deprecated, don't use this as it will not catch any dynamic ids
- * that a driver might want to check for.
- */
-const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
- struct pci_dev *dev)
-{
- if (ids) {
- while (ids->vendor || ids->subvendor || ids->class_mask) {
- if (pci_match_one_device(ids, dev))
- return ids;
- ids++;
- }
- }
- return NULL;
-}
-
-/**
- * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure
- * @drv: the PCI driver to match against
- * @dev: the PCI device structure to match against
- *
- * Used by a driver to check whether a PCI device present in the
- * system is in its list of supported devices. Returns the matching
- * pci_device_id structure or %NULL if there is no match.
- */
-static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
- struct pci_dev *dev)
-{
- struct pci_dynid *dynid;
-
- /* Look at the dynamic ids first, before the static ones */
- spin_lock(&drv->dynids.lock);
- list_for_each_entry(dynid, &drv->dynids.list, node) {
- if (pci_match_one_device(&dynid->id, dev)) {
- spin_unlock(&drv->dynids.lock);
- return &dynid->id;
- }
- }
- spin_unlock(&drv->dynids.lock);
-
- return pci_match_id(drv->id_table, dev);
-}
-
-struct drv_dev_and_id {
- struct pci_driver *drv;
- struct pci_dev *dev;
- const struct pci_device_id *id;
-};
-
-static long local_pci_probe(void *_ddi)
-{
- struct drv_dev_and_id *ddi = _ddi;
-
- return ddi->drv->probe(ddi->dev, ddi->id);
-}
-
-static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- int error, node;
- struct drv_dev_and_id ddi = { drv, dev, id };
-
- /* Execute driver initialization on node where the device's
- bus is attached to. This way the driver likely allocates
- its local memory on the right node without any need to
- change it. */
- node = dev_to_node(&dev->dev);
- if (node >= 0) {
- int cpu;
- node_to_cpumask_ptr(nodecpumask, node);
-
- get_online_cpus();
- cpu = cpumask_any_and(nodecpumask, cpu_online_mask);
- if (cpu < nr_cpu_ids)
- error = work_on_cpu(cpu, local_pci_probe, &ddi);
- else
- error = local_pci_probe(&ddi);
- put_online_cpus();
- } else
- error = local_pci_probe(&ddi);
- return error;
-}
-
-/**
- * __pci_device_probe()
- * @drv: driver to call to check if it wants the PCI device
- * @pci_dev: PCI device being probed
- *
- * returns 0 on success, else error.
- * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
- */
-static int
-__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
- const struct pci_device_id *id;
- int error = 0;
-
- if (!pci_dev->driver && drv->probe) {
- error = -ENODEV;
-
- id = pci_match_device(drv, pci_dev);
- if (id)
- error = pci_call_probe(drv, pci_dev, id);
- if (error >= 0) {
- pci_dev->driver = drv;
- error = 0;
- }
- }
- return error;
-}
-
-static int pci_device_probe(struct device * dev)
-{
- int error = 0;
- struct pci_driver *drv;
- struct pci_dev *pci_dev;
-
- drv = to_pci_driver(dev->driver);
- pci_dev = to_pci_dev(dev);
- pci_dev_get(pci_dev);
- error = __pci_device_probe(drv, pci_dev);
- if (error)
- pci_dev_put(pci_dev);
-
- return error;
-}
-
-static int pci_device_remove(struct device * dev)
-{
- struct pci_dev * pci_dev = to_pci_dev(dev);
- struct pci_driver * drv = pci_dev->driver;
-
- if (drv) {
- if (drv->remove)
- drv->remove(pci_dev);
- pci_dev->driver = NULL;
- }
-
- /*
- * If the device is still on, set the power state as "unknown",
- * since it might change by the next time we load the driver.
- */
- if (pci_dev->current_state == PCI_D0)
- pci_dev->current_state = PCI_UNKNOWN;
-
- /*
- * We would love to complain here if pci_dev->is_enabled is set, that
- * the driver should have called pci_disable_device(), but the
- * unfortunate fact is there are too many odd BIOS and bridge setups
- * that don't like drivers doing that all of the time.
- * Oh well, we can dream of sane hardware when we sleep, no matter how
- * horrible the crap we have to deal with is when we are awake...
- */
-
- pci_dev_put(pci_dev);
- return 0;
-}
-
-static void pci_device_shutdown(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
-
- if (drv && drv->shutdown)
- drv->shutdown(pci_dev);
- pci_msi_shutdown(pci_dev);
- pci_msix_shutdown(pci_dev);
-}
-
-#ifdef CONFIG_PM_SLEEP
-
-/*
- * Default "suspend" method for devices that have no driver provided suspend,
- * or not even a driver at all (second part).
- */
-static void pci_pm_set_unknown_state(struct pci_dev *pci_dev)
-{
- /*
- * mark its power state as "unknown", since we don't know if
- * e.g. the BIOS will change its device state when we suspend.
- */
- if (pci_dev->current_state == PCI_D0)
- pci_dev->current_state = PCI_UNKNOWN;
-}
-
-/*
- * Default "resume" method for devices that have no driver provided resume,
- * or not even a driver at all (second part).
- */
-static int pci_pm_reenable_device(struct pci_dev *pci_dev)
-{
- int retval;
-
- /* if the device was enabled before suspend, reenable */
- retval = pci_reenable_device(pci_dev);
- /*
- * if the device was busmaster before the suspend, make it busmaster
- * again
- */
- if (pci_dev->is_busmaster)
- pci_set_master(pci_dev);
-
- return retval;
-}
-
-static int pci_legacy_suspend(struct device *dev, pm_message_t state)
-{
-#ifndef DDE_LINUX
- struct pci_dev * pci_dev = to_pci_dev(dev);
- struct pci_driver * drv = pci_dev->driver;
- int i = 0;
-
- if (drv && drv->suspend) {
- pci_power_t prev = pci_dev->current_state;
-
- pci_dev->state_saved = false;
-
- i = drv->suspend(pci_dev, state);
- suspend_report_result(drv->suspend, i);
- if (i)
- return i;
-
- if (pci_dev->state_saved)
- goto Fixup;
-
- if (pci_dev->current_state != PCI_D0
- && pci_dev->current_state != PCI_UNKNOWN) {
- WARN_ONCE(pci_dev->current_state != prev,
- "PCI PM: Device state not saved by %pF\n",
- drv->suspend);
- goto Fixup;
- }
- }
-
- pci_save_state(pci_dev);
- /*
- * This is for compatibility with existing code with legacy PM support.
- */
- pci_pm_set_unknown_state(pci_dev);
-
- Fixup:
- pci_fixup_device(pci_fixup_suspend, pci_dev);
-
- return i;
-#else
- WARN_UNIMPL;
- return 0;
-#endif /* DDE_LINUX */
-}
-
-static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
-{
-#ifndef DDE_LINUX
- struct pci_dev * pci_dev = to_pci_dev(dev);
- struct pci_driver * drv = pci_dev->driver;
- int i = 0;
-
- if (drv && drv->suspend_late) {
- i = drv->suspend_late(pci_dev, state);
- suspend_report_result(drv->suspend_late, i);
- }
- return i;
-#else
- WARN_UNIMPL;
- return 0;
-#endif
-}
-
-static int pci_legacy_resume_early(struct device *dev)
-{
- struct pci_dev * pci_dev = to_pci_dev(dev);
- struct pci_driver * drv = pci_dev->driver;
-
- return drv && drv->resume_early ?
- drv->resume_early(pci_dev) : 0;
-}
-
-static int pci_legacy_resume(struct device *dev)
-{
- struct pci_dev * pci_dev = to_pci_dev(dev);
- struct pci_driver * drv = pci_dev->driver;
-
- pci_fixup_device(pci_fixup_resume, pci_dev);
-
- return drv && drv->resume ?
- drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
-}
-
-/* Auxiliary functions used by the new power management framework */
-
-static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
-{
- pci_restore_standard_config(pci_dev);
- pci_dev->state_saved = false;
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
-}
-
-static void pci_pm_default_resume(struct pci_dev *pci_dev)
-{
- pci_fixup_device(pci_fixup_resume, pci_dev);
-
- if (!pci_is_bridge(pci_dev))
- pci_enable_wake(pci_dev, PCI_D0, false);
-}
-
-static void pci_pm_default_suspend(struct pci_dev *pci_dev)
-{
- /* Disable non-bridge devices without PM support */
- if (!pci_is_bridge(pci_dev))
- pci_disable_enabled_device(pci_dev);
- pci_save_state(pci_dev);
-}
-
-static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
-{
- struct pci_driver *drv = pci_dev->driver;
- bool ret = drv && (drv->suspend || drv->suspend_late || drv->resume
- || drv->resume_early);
-
- /*
- * Legacy PM support is used by default, so warn if the new framework is
- * supported as well. Drivers are supposed to support either the
- * former, or the latter, but not both at the same time.
- */
- WARN_ON(ret && drv->driver.pm);
-
- return ret;
-}
-
-/* New power management framework */
-
-static int pci_pm_prepare(struct device *dev)
-{
- struct device_driver *drv = dev->driver;
- int error = 0;
-
- if (drv && drv->pm && drv->pm->prepare)
- error = drv->pm->prepare(dev);
-
- return error;
-}
-
-static void pci_pm_complete(struct device *dev)
-{
- struct device_driver *drv = dev->driver;
-
- if (drv && drv->pm && drv->pm->complete)
- drv->pm->complete(dev);
-}
-
-#ifdef CONFIG_SUSPEND
-
-static int pci_pm_suspend(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_suspend(dev, PMSG_SUSPEND);
-
- if (!pm) {
- pci_pm_default_suspend(pci_dev);
- goto Fixup;
- }
-
- pci_dev->state_saved = false;
-
- if (pm->suspend) {
- pci_power_t prev = pci_dev->current_state;
- int error;
-
- error = pm->suspend(dev);
- suspend_report_result(pm->suspend, error);
- if (error)
- return error;
-
- if (pci_dev->state_saved)
- goto Fixup;
-
- if (pci_dev->current_state != PCI_D0
- && pci_dev->current_state != PCI_UNKNOWN) {
- WARN_ONCE(pci_dev->current_state != prev,
- "PCI PM: State of device not saved by %pF\n",
- pm->suspend);
- goto Fixup;
- }
- }
-
- if (!pci_dev->state_saved) {
- pci_save_state(pci_dev);
- if (!pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
- }
-
- Fixup:
- pci_fixup_device(pci_fixup_suspend, pci_dev);
-
- return 0;
-}
-
-static int pci_pm_suspend_noirq(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
-
- if (drv && drv->pm && drv->pm->suspend_noirq) {
- error = drv->pm->suspend_noirq(dev);
- suspend_report_result(drv->pm->suspend_noirq, error);
- }
-
- if (!error)
- pci_pm_set_unknown_state(pci_dev);
-
- return error;
-}
-
-static int pci_pm_resume_noirq(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
-
- pci_pm_default_resume_noirq(pci_dev);
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_resume_early(dev);
-
- if (drv && drv->pm && drv->pm->resume_noirq)
- error = drv->pm->resume_noirq(dev);
-
- return error;
-}
-
-static int pci_pm_resume(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int error = 0;
-
- /*
- * This is necessary for the suspend error path in which resume is
- * called without restoring the standard config registers of the device.
- */
- if (pci_dev->state_saved)
- pci_restore_standard_config(pci_dev);
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_resume(dev);
-
- pci_pm_default_resume(pci_dev);
-
- if (pm) {
- if (pm->resume)
- error = pm->resume(dev);
- } else {
- pci_pm_reenable_device(pci_dev);
- }
-
- return 0;
-}
-
-#else /* !CONFIG_SUSPEND */
-
-#define pci_pm_suspend NULL
-#define pci_pm_suspend_noirq NULL
-#define pci_pm_resume NULL
-#define pci_pm_resume_noirq NULL
-
-#endif /* !CONFIG_SUSPEND */
-
-#ifdef CONFIG_HIBERNATION
-
-static int pci_pm_freeze(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_suspend(dev, PMSG_FREEZE);
-
- if (!pm) {
- pci_pm_default_suspend(pci_dev);
- return 0;
- }
-
- pci_dev->state_saved = false;
-
- if (pm->freeze) {
- int error;
-
- error = pm->freeze(dev);
- suspend_report_result(pm->freeze, error);
- if (error)
- return error;
- }
-
- if (!pci_dev->state_saved)
- pci_save_state(pci_dev);
-
- return 0;
-}
-
-static int pci_pm_freeze_noirq(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_suspend_late(dev, PMSG_FREEZE);
-
- if (drv && drv->pm && drv->pm->freeze_noirq) {
- error = drv->pm->freeze_noirq(dev);
- suspend_report_result(drv->pm->freeze_noirq, error);
- }
-
- if (!error)
- pci_pm_set_unknown_state(pci_dev);
-
- return error;
-}
-
-static int pci_pm_thaw_noirq(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_resume_early(dev);
-
- pci_update_current_state(pci_dev, PCI_D0);
-
- if (drv && drv->pm && drv->pm->thaw_noirq)
- error = drv->pm->thaw_noirq(dev);
-
- return error;
-}
-
-static int pci_pm_thaw(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int error = 0;
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_resume(dev);
-
- if (pm) {
- if (pm->thaw)
- error = pm->thaw(dev);
- } else {
- pci_pm_reenable_device(pci_dev);
- }
-
- return error;
-}
-
-static int pci_pm_poweroff(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int error = 0;
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_suspend(dev, PMSG_HIBERNATE);
-
- if (!pm) {
- pci_pm_default_suspend(pci_dev);
- goto Fixup;
- }
-
- pci_dev->state_saved = false;
-
- if (pm->poweroff) {
- error = pm->poweroff(dev);
- suspend_report_result(pm->poweroff, error);
- }
-
- if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
-
- Fixup:
- pci_fixup_device(pci_fixup_suspend, pci_dev);
-
- return error;
-}
-
-static int pci_pm_poweroff_noirq(struct device *dev)
-{
- struct device_driver *drv = dev->driver;
- int error = 0;
-
- if (pci_has_legacy_pm_support(to_pci_dev(dev)))
- return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
-
- if (drv && drv->pm && drv->pm->poweroff_noirq) {
- error = drv->pm->poweroff_noirq(dev);
- suspend_report_result(drv->pm->poweroff_noirq, error);
- }
-
- return error;
-}
-
-static int pci_pm_restore_noirq(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
-
- pci_pm_default_resume_noirq(pci_dev);
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_resume_early(dev);
-
- if (drv && drv->pm && drv->pm->restore_noirq)
- error = drv->pm->restore_noirq(dev);
-
- return error;
-}
-
-static int pci_pm_restore(struct device *dev)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int error = 0;
-
- /*
- * This is necessary for the hibernation error path in which restore is
- * called without restoring the standard config registers of the device.
- */
- if (pci_dev->state_saved)
- pci_restore_standard_config(pci_dev);
-
- if (pci_has_legacy_pm_support(pci_dev))
- return pci_legacy_resume(dev);
-
- pci_pm_default_resume(pci_dev);
-
- if (pm) {
- if (pm->restore)
- error = pm->restore(dev);
- } else {
- pci_pm_reenable_device(pci_dev);
- }
-
- return error;
-}
-
-#else /* !CONFIG_HIBERNATION */
-
-#define pci_pm_freeze NULL
-#define pci_pm_freeze_noirq NULL
-#define pci_pm_thaw NULL
-#define pci_pm_thaw_noirq NULL
-#define pci_pm_poweroff NULL
-#define pci_pm_poweroff_noirq NULL
-#define pci_pm_restore NULL
-#define pci_pm_restore_noirq NULL
-
-#endif /* !CONFIG_HIBERNATION */
-
-struct dev_pm_ops pci_dev_pm_ops = {
- .prepare = pci_pm_prepare,
- .complete = pci_pm_complete,
- .suspend = pci_pm_suspend,
- .resume = pci_pm_resume,
- .freeze = pci_pm_freeze,
- .thaw = pci_pm_thaw,
- .poweroff = pci_pm_poweroff,
- .restore = pci_pm_restore,
- .suspend_noirq = pci_pm_suspend_noirq,
- .resume_noirq = pci_pm_resume_noirq,
- .freeze_noirq = pci_pm_freeze_noirq,
- .thaw_noirq = pci_pm_thaw_noirq,
- .poweroff_noirq = pci_pm_poweroff_noirq,
- .restore_noirq = pci_pm_restore_noirq,
-};
-
-#define PCI_PM_OPS_PTR (&pci_dev_pm_ops)
-
-#else /* !CONFIG_PM_SLEEP */
-
-#define PCI_PM_OPS_PTR NULL
-
-#endif /* !CONFIG_PM_SLEEP */
-
-/**
- * __pci_register_driver - register a new pci driver
- * @drv: the driver structure to register
- * @owner: owner module of drv
- * @mod_name: module name string
- *
- * Adds the driver structure to the list of registered drivers.
- * Returns a negative value on error, otherwise 0.
- * If no error occurred, the driver remains registered even if
- * no device was claimed during registration.
- */
-int __pci_register_driver(struct pci_driver *drv, struct module *owner,
- const char *mod_name)
-{
- int error;
-
- /* initialize common driver fields */
- drv->driver.name = drv->name;
- drv->driver.bus = &pci_bus_type;
- drv->driver.owner = owner;
- drv->driver.mod_name = mod_name;
-
- spin_lock_init(&drv->dynids.lock);
- INIT_LIST_HEAD(&drv->dynids.list);
-
- /* register with core */
- error = driver_register(&drv->driver);
- if (error)
- return error;
-
- error = pci_create_newid_file(drv);
- if (error)
- driver_unregister(&drv->driver);
-
- return error;
-}
-
-/**
- * pci_unregister_driver - unregister a pci driver
- * @drv: the driver structure to unregister
- *
- * Deletes the driver structure from the list of registered PCI drivers,
- * gives it a chance to clean up by calling its remove() function for
- * each device it was responsible for, and marks those devices as
- * driverless.
- */
-
-void
-pci_unregister_driver(struct pci_driver *drv)
-{
- pci_remove_newid_file(drv);
- driver_unregister(&drv->driver);
- pci_free_dynids(drv);
-}
-
-static struct pci_driver pci_compat_driver = {
- .name = "compat"
-};
-
-/**
- * pci_dev_driver - get the pci_driver of a device
- * @dev: the device to query
- *
- * Returns the appropriate pci_driver structure or %NULL if there is no
- * registered driver for the device.
- */
-struct pci_driver *
-pci_dev_driver(const struct pci_dev *dev)
-{
- if (dev->driver)
- return dev->driver;
- else {
- int i;
- for(i=0; i<=PCI_ROM_RESOURCE; i++)
- if (dev->resource[i].flags & IORESOURCE_BUSY)
- return &pci_compat_driver;
- }
- return NULL;
-}
-
-/**
- * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
- * @dev: the PCI device structure to match against
- * @drv: the device driver to search for matching PCI device id structures
- *
- * Used by a driver to check whether a PCI device present in the
- * system is in its list of supported devices. Returns the matching
- * pci_device_id structure or %NULL if there is no match.
- */
-static int pci_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *pci_drv = to_pci_driver(drv);
- const struct pci_device_id *found_id;
-
- found_id = pci_match_device(pci_drv, pci_dev);
- if (found_id)
- return 1;
-
- return 0;
-}
-
-/**
- * pci_dev_get - increments the reference count of the pci device structure
- * @dev: the device being referenced
- *
- * Each live reference to a device should be refcounted.
- *
- * Drivers for PCI devices should normally record such references in
- * their probe() methods, when they bind to a device, and release
- * them by calling pci_dev_put(), in their disconnect() methods.
- *
- * A pointer to the device with the incremented reference counter is returned.
- */
-struct pci_dev *pci_dev_get(struct pci_dev *dev)
-{
- if (dev)
- get_device(&dev->dev);
- return dev;
-}
-
-/**
- * pci_dev_put - release a use of the pci device structure
- * @dev: device that's been disconnected
- *
- * Must be called when a user of a device is finished with it. When the last
- * user of the device calls this function, the memory of the device is freed.
- */
-void pci_dev_put(struct pci_dev *dev)
-{
- if (dev)
- put_device(&dev->dev);
-}
-
-#ifndef CONFIG_HOTPLUG
-int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return -ENODEV;
-}
-#endif
-
-struct bus_type pci_bus_type = {
- .name = "pci",
- .match = pci_bus_match,
- .uevent = pci_uevent,
- .probe = pci_device_probe,
- .remove = pci_device_remove,
- .shutdown = pci_device_shutdown,
-#ifndef DDE_LINUX
- .dev_attrs = pci_dev_attrs,
-#endif
- .pm = PCI_PM_OPS_PTR,
-};
-
-static int __init pci_driver_init(void)
-{
- return bus_register(&pci_bus_type);
-}
-
-postcore_initcall(pci_driver_init);
-
-EXPORT_SYMBOL(pci_match_id);
-EXPORT_SYMBOL(__pci_register_driver);
-EXPORT_SYMBOL(pci_unregister_driver);
-EXPORT_SYMBOL(pci_dev_driver);
-EXPORT_SYMBOL(pci_bus_type);
-EXPORT_SYMBOL(pci_dev_get);
-EXPORT_SYMBOL(pci_dev_put);
diff --git a/libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci.c.svn-base b/libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci.c.svn-base
deleted file mode 100644
index f67bf734..00000000
--- a/libdde_linux26/lib/src/drivers/pci/.svn/text-base/pci.c.svn-base
+++ /dev/null
@@ -1,2480 +0,0 @@
-/*
- * PCI Bus Services, see include/linux/pci.h for further explanation.
- *
- * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
- * David Mosberger-Tang
- *
- * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz>
- */
-
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/log2.h>
-#include <linux/pci-aspm.h>
-#include <linux/pm_wakeup.h>
-#include <linux/interrupt.h>
-#include <asm/dma.h> /* isa_dma_bridge_buggy */
-#include "pci.h"
-
-#ifdef DDE_LINUX
-#include "local.h"
-#endif
-
-unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
-
-#ifdef CONFIG_PCI_DOMAINS
-int pci_domains_supported = 1;
-#endif
-
-#define DEFAULT_CARDBUS_IO_SIZE (256)
-#define DEFAULT_CARDBUS_MEM_SIZE (64*1024*1024)
-/* pci=cbmemsize=nnM,cbiosize=nn can override this */
-unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
-unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
-
-/**
- * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
- * @bus: pointer to PCI bus structure to search
- *
- * Given a PCI bus, returns the highest PCI bus number present in the set
- * including the given PCI bus and its list of child PCI buses.
- */
-unsigned char pci_bus_max_busnr(struct pci_bus* bus)
-{
- struct list_head *tmp;
- unsigned char max, n;
-
- max = bus->subordinate;
- list_for_each(tmp, &bus->children) {
- n = pci_bus_max_busnr(pci_bus_b(tmp));
- if(n > max)
- max = n;
- }
- return max;
-}
-EXPORT_SYMBOL_GPL(pci_bus_max_busnr);
-
-#ifdef CONFIG_HAS_IOMEM
-void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
-{
- /*
- * Make sure the BAR is actually a memory resource, not an IO resource
- */
- if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
- WARN_ON(1);
- return NULL;
- }
- return ioremap_nocache(pci_resource_start(pdev, bar),
- pci_resource_len(pdev, bar));
-}
-EXPORT_SYMBOL_GPL(pci_ioremap_bar);
-#endif
-
-#if 0
-/**
- * pci_max_busnr - returns maximum PCI bus number
- *
- * Returns the highest PCI bus number present in the system global list of
- * PCI buses.
- */
-unsigned char __devinit
-pci_max_busnr(void)
-{
- struct pci_bus *bus = NULL;
- unsigned char max, n;
-
- max = 0;
- while ((bus = pci_find_next_bus(bus)) != NULL) {
- n = pci_bus_max_busnr(bus);
- if(n > max)
- max = n;
- }
- return max;
-}
-
-#endif /* 0 */
-
-#define PCI_FIND_CAP_TTL 48
-
-static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
- u8 pos, int cap, int *ttl)
-{
- u8 id;
-
- while ((*ttl)--) {
- pci_bus_read_config_byte(bus, devfn, pos, &pos);
- if (pos < 0x40)
- break;
- pos &= ~3;
- pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
- &id);
- if (id == 0xff)
- break;
- if (id == cap)
- return pos;
- pos += PCI_CAP_LIST_NEXT;
- }
- return 0;
-}
-
-static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
- u8 pos, int cap)
-{
- int ttl = PCI_FIND_CAP_TTL;
-
- return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
-}
-
-int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
-{
- return __pci_find_next_cap(dev->bus, dev->devfn,
- pos + PCI_CAP_LIST_NEXT, cap);
-}
-EXPORT_SYMBOL_GPL(pci_find_next_capability);
-
-static int __pci_bus_find_cap_start(struct pci_bus *bus,
- unsigned int devfn, u8 hdr_type)
-{
- u16 status;
-
- pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
- if (!(status & PCI_STATUS_CAP_LIST))
- return 0;
-
- switch (hdr_type) {
- case PCI_HEADER_TYPE_NORMAL:
- case PCI_HEADER_TYPE_BRIDGE:
- return PCI_CAPABILITY_LIST;
- case PCI_HEADER_TYPE_CARDBUS:
- return PCI_CB_CAPABILITY_LIST;
- default:
- return 0;
- }
-
- return 0;
-}
-
-/**
- * pci_find_capability - query for devices' capabilities
- * @dev: PCI device to query
- * @cap: capability code
- *
- * Tell if a device supports a given PCI capability.
- * Returns the address of the requested capability structure within the
- * device's PCI configuration space or 0 in case the device does not
- * support it. Possible values for @cap:
- *
- * %PCI_CAP_ID_PM Power Management
- * %PCI_CAP_ID_AGP Accelerated Graphics Port
- * %PCI_CAP_ID_VPD Vital Product Data
- * %PCI_CAP_ID_SLOTID Slot Identification
- * %PCI_CAP_ID_MSI Message Signalled Interrupts
- * %PCI_CAP_ID_CHSWP CompactPCI HotSwap
- * %PCI_CAP_ID_PCIX PCI-X
- * %PCI_CAP_ID_EXP PCI Express
- */
-int pci_find_capability(struct pci_dev *dev, int cap)
-{
- int pos;
-
- pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
- if (pos)
- pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
-
- return pos;
-}
-
-/**
- * pci_bus_find_capability - query for devices' capabilities
- * @bus: the PCI bus to query
- * @devfn: PCI device to query
- * @cap: capability code
- *
- * Like pci_find_capability() but works for pci devices that do not have a
- * pci_dev structure set up yet.
- *
- * Returns the address of the requested capability structure within the
- * device's PCI configuration space or 0 in case the device does not
- * support it.
- */
-int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
-{
- int pos;
- u8 hdr_type;
-
- pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-
- pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
- if (pos)
- pos = __pci_find_next_cap(bus, devfn, pos, cap);
-
- return pos;
-}
-
-/**
- * pci_find_ext_capability - Find an extended capability
- * @dev: PCI device to query
- * @cap: capability code
- *
- * Returns the address of the requested extended capability structure
- * within the device's PCI configuration space or 0 if the device does
- * not support it. Possible values for @cap:
- *
- * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
- * %PCI_EXT_CAP_ID_VC Virtual Channel
- * %PCI_EXT_CAP_ID_DSN Device Serial Number
- * %PCI_EXT_CAP_ID_PWR Power Budgeting
- */
-int pci_find_ext_capability(struct pci_dev *dev, int cap)
-{
- u32 header;
- int ttl;
- int pos = PCI_CFG_SPACE_SIZE;
-
- /* minimum 8 bytes per capability */
- ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
-
- if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
- return 0;
-
- if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
- return 0;
-
- /*
- * If we have no capabilities, this is indicated by cap ID,
- * cap version and next pointer all being 0.
- */
- if (header == 0)
- return 0;
-
- while (ttl-- > 0) {
- if (PCI_EXT_CAP_ID(header) == cap)
- return pos;
-
- pos = PCI_EXT_CAP_NEXT(header);
- if (pos < PCI_CFG_SPACE_SIZE)
- break;
-
- if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
- break;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(pci_find_ext_capability);
-
-static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
-{
- int rc, ttl = PCI_FIND_CAP_TTL;
- u8 cap, mask;
-
- if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST)
- mask = HT_3BIT_CAP_MASK;
- else
- mask = HT_5BIT_CAP_MASK;
-
- pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
- PCI_CAP_ID_HT, &ttl);
- while (pos) {
- rc = pci_read_config_byte(dev, pos + 3, &cap);
- if (rc != PCIBIOS_SUCCESSFUL)
- return 0;
-
- if ((cap & mask) == ht_cap)
- return pos;
-
- pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn,
- pos + PCI_CAP_LIST_NEXT,
- PCI_CAP_ID_HT, &ttl);
- }
-
- return 0;
-}
-/**
- * pci_find_next_ht_capability - query a device's Hypertransport capabilities
- * @dev: PCI device to query
- * @pos: Position from which to continue searching
- * @ht_cap: Hypertransport capability code
- *
- * To be used in conjunction with pci_find_ht_capability() to search for
- * all capabilities matching @ht_cap. @pos should always be a value returned
- * from pci_find_ht_capability().
- *
- * NB. To be 100% safe against broken PCI devices, the caller should take
- * steps to avoid an infinite loop.
- */
-int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap)
-{
- return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap);
-}
-EXPORT_SYMBOL_GPL(pci_find_next_ht_capability);
-
-/**
- * pci_find_ht_capability - query a device's Hypertransport capabilities
- * @dev: PCI device to query
- * @ht_cap: Hypertransport capability code
- *
- * Tell if a device supports a given Hypertransport capability.
- * Returns an address within the device's PCI configuration space
- * or 0 in case the device does not support the request capability.
- * The address points to the PCI capability, of type PCI_CAP_ID_HT,
- * which has a Hypertransport capability matching @ht_cap.
- */
-int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
-{
- int pos;
-
- pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
- if (pos)
- pos = __pci_find_next_ht_cap(dev, pos, ht_cap);
-
- return pos;
-}
-EXPORT_SYMBOL_GPL(pci_find_ht_capability);
-
-/**
- * pci_find_parent_resource - return resource region of parent bus of given region
- * @dev: PCI device structure contains resources to be searched
- * @res: child resource record for which parent is sought
- *
- * For given resource region of given device, return the resource
- * region of parent bus the given region is contained in or where
- * it should be allocated from.
- */
-struct resource *
-pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
-{
- const struct pci_bus *bus = dev->bus;
- int i;
- struct resource *best = NULL;
-
- for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *r = bus->resource[i];
- if (!r)
- continue;
- if (res->start && !(res->start >= r->start && res->end <= r->end))
- continue; /* Not contained */
- if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
- continue; /* Wrong type */
- if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
- return r; /* Exact match */
- if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH))
- best = r; /* Approximating prefetchable by non-prefetchable */
- }
- return best;
-}
-
-/**
- * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
- * @dev: PCI device to have its BARs restored
- *
- * Restore the BAR values for a given device, so as to make it
- * accessible by its driver.
- */
-static void
-pci_restore_bars(struct pci_dev *dev)
-{
- int i;
-
- for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
- pci_update_resource(dev, i);
-}
-
-static struct pci_platform_pm_ops *pci_platform_pm;
-
-int pci_set_platform_pm(struct pci_platform_pm_ops *ops)
-{
- if (!ops->is_manageable || !ops->set_state || !ops->choose_state
- || !ops->sleep_wake || !ops->can_wakeup)
- return -EINVAL;
- pci_platform_pm = ops;
- return 0;
-}
-
-static inline bool platform_pci_power_manageable(struct pci_dev *dev)
-{
- return pci_platform_pm ? pci_platform_pm->is_manageable(dev) : false;
-}
-
-static inline int platform_pci_set_power_state(struct pci_dev *dev,
- pci_power_t t)
-{
- return pci_platform_pm ? pci_platform_pm->set_state(dev, t) : -ENOSYS;
-}
-
-static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
-{
- return pci_platform_pm ?
- pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
-}
-
-static inline bool platform_pci_can_wakeup(struct pci_dev *dev)
-{
- return pci_platform_pm ? pci_platform_pm->can_wakeup(dev) : false;
-}
-
-static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
-{
- return pci_platform_pm ?
- pci_platform_pm->sleep_wake(dev, enable) : -ENODEV;
-}
-
-/**
- * pci_raw_set_power_state - Use PCI PM registers to set the power state of
- * given PCI device
- * @dev: PCI device to handle.
- * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
- * @wait: If 'true', wait for the device to change its power state
- *
- * RETURN VALUE:
- * -EINVAL if the requested state is invalid.
- * -EIO if device does not support PCI PM or its PM capabilities register has a
- * wrong version, or device doesn't support the requested state.
- * 0 if device already is in the requested state.
- * 0 if device's power state has been successfully changed.
- */
-static int
-pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
-{
- u16 pmcsr;
- bool need_restore = false;
-
- if (!dev->pm_cap)
- return -EIO;
-
- if (state < PCI_D0 || state > PCI_D3hot)
- return -EINVAL;
-
- /* Validate current state:
- * Can enter D0 from any state, but if we can only go deeper
- * to sleep if we're already in a low power state
- */
- if (dev->current_state == state) {
- /* we're already there */
- return 0;
- } else if (state != PCI_D0 && dev->current_state <= PCI_D3cold
- && dev->current_state > state) {
- dev_err(&dev->dev, "invalid power transition "
- "(from state %d to %d)\n", dev->current_state, state);
- return -EINVAL;
- }
-
- /* check if this device supports the desired state */
- if ((state == PCI_D1 && !dev->d1_support)
- || (state == PCI_D2 && !dev->d2_support))
- return -EIO;
-
- pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
-
- /* If we're (effectively) in D3, force entire word to 0.
- * This doesn't affect PME_Status, disables PME_En, and
- * sets PowerState to 0.
- */
- switch (dev->current_state) {
- case PCI_D0:
- case PCI_D1:
- case PCI_D2:
- pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
- pmcsr |= state;
- break;
- case PCI_UNKNOWN: /* Boot-up */
- if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
- && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) {
- need_restore = true;
- wait = true;
- }
- /* Fall-through: force to D0 */
- default:
- pmcsr = 0;
- break;
- }
-
- /* enter specified state */
- pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
-
- if (!wait)
- return 0;
-
- /* Mandatory power management transition delays */
- /* see PCI PM 1.1 5.6.1 table 18 */
- if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
- msleep(pci_pm_d3_delay);
- else if (state == PCI_D2 || dev->current_state == PCI_D2)
- udelay(PCI_PM_D2_DELAY);
-
- dev->current_state = state;
-
- /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
- * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
- * from D3hot to D0 _may_ perform an internal reset, thereby
- * going to "D0 Uninitialized" rather than "D0 Initialized".
- * For example, at least some versions of the 3c905B and the
- * 3c556B exhibit this behaviour.
- *
- * At least some laptop BIOSen (e.g. the Thinkpad T21) leave
- * devices in a D3hot state at boot. Consequently, we need to
- * restore at least the BARs so that the device will be
- * accessible to its driver.
- */
- if (need_restore)
- pci_restore_bars(dev);
-
- if (wait && dev->bus->self)
- pcie_aspm_pm_state_change(dev->bus->self);
-
- return 0;
-}
-
-/**
- * pci_update_current_state - Read PCI power state of given device from its
- * PCI PM registers and cache it
- * @dev: PCI device to handle.
- * @state: State to cache in case the device doesn't have the PM capability
- */
-void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
-{
- if (dev->pm_cap) {
- u16 pmcsr;
-
- pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
- dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
- } else {
- dev->current_state = state;
- }
-}
-
-/**
- * pci_set_power_state - Set the power state of a PCI device
- * @dev: PCI device to handle.
- * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
- *
- * Transition a device to a new power state, using the platform formware and/or
- * the device's PCI PM registers.
- *
- * RETURN VALUE:
- * -EINVAL if the requested state is invalid.
- * -EIO if device does not support PCI PM or its PM capabilities register has a
- * wrong version, or device doesn't support the requested state.
- * 0 if device already is in the requested state.
- * 0 if device's power state has been successfully changed.
- */
-int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
-{
- int error;
-
- /* bound the state we're entering */
- if (state > PCI_D3hot)
- state = PCI_D3hot;
- else if (state < PCI_D0)
- state = PCI_D0;
- else if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
- /*
- * If the device or the parent bridge do not support PCI PM,
- * ignore the request if we're doing anything other than putting
- * it into D0 (which would only happen on boot).
- */
- return 0;
-
- if (state == PCI_D0 && platform_pci_power_manageable(dev)) {
- /*
- * Allow the platform to change the state, for example via ACPI
- * _PR0, _PS0 and some such, but do not trust it.
- */
- int ret = platform_pci_set_power_state(dev, PCI_D0);
- if (!ret)
- pci_update_current_state(dev, PCI_D0);
- }
- /* This device is quirked not to be put into D3, so
- don't put it in D3 */
- if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
- return 0;
-
- error = pci_raw_set_power_state(dev, state, true);
-
- if (state > PCI_D0 && platform_pci_power_manageable(dev)) {
- /* Allow the platform to finalize the transition */
- int ret = platform_pci_set_power_state(dev, state);
- if (!ret) {
- pci_update_current_state(dev, state);
- error = 0;
- }
- }
-
- return error;
-}
-
-/**
- * pci_choose_state - Choose the power state of a PCI device
- * @dev: PCI device to be suspended
- * @state: target sleep state for the whole system. This is the value
- * that is passed to suspend() function.
- *
- * Returns PCI power state suitable for given device and given system
- * message.
- */
-
-pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
-{
- pci_power_t ret;
-
- if (!pci_find_capability(dev, PCI_CAP_ID_PM))
- return PCI_D0;
-
- ret = platform_pci_choose_state(dev);
- if (ret != PCI_POWER_ERROR)
- return ret;
-
- switch (state.event) {
- case PM_EVENT_ON:
- return PCI_D0;
- case PM_EVENT_FREEZE:
- case PM_EVENT_PRETHAW:
- /* REVISIT both freeze and pre-thaw "should" use D0 */
- case PM_EVENT_SUSPEND:
- case PM_EVENT_HIBERNATE:
- return PCI_D3hot;
- default:
- dev_info(&dev->dev, "unrecognized suspend event %d\n",
- state.event);
- BUG();
- }
- return PCI_D0;
-}
-
-EXPORT_SYMBOL(pci_choose_state);
-
-static int pci_save_pcie_state(struct pci_dev *dev)
-{
- int pos, i = 0;
- struct pci_cap_saved_state *save_state;
- u16 *cap;
-
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (pos <= 0)
- return 0;
-
- save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
- if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
- return -ENOMEM;
- }
- cap = (u16 *)&save_state->data[0];
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
- pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
- pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
- pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
-
- return 0;
-}
-
-static void pci_restore_pcie_state(struct pci_dev *dev)
-{
- int i = 0, pos;
- struct pci_cap_saved_state *save_state;
- u16 *cap;
-
- save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!save_state || pos <= 0)
- return;
- cap = (u16 *)&save_state->data[0];
-
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
- pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
- pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
- pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
-}
-
-
-static int pci_save_pcix_state(struct pci_dev *dev)
-{
- int pos;
- struct pci_cap_saved_state *save_state;
-
- pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (pos <= 0)
- return 0;
-
- save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
- if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
- return -ENOMEM;
- }
-
- pci_read_config_word(dev, pos + PCI_X_CMD, (u16 *)save_state->data);
-
- return 0;
-}
-
-static void pci_restore_pcix_state(struct pci_dev *dev)
-{
- int i = 0, pos;
- struct pci_cap_saved_state *save_state;
- u16 *cap;
-
- save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
- pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!save_state || pos <= 0)
- return;
- cap = (u16 *)&save_state->data[0];
-
- pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]);
-}
-
-
-/**
- * pci_save_state - save the PCI configuration space of a device before suspending
- * @dev: - PCI device that we're dealing with
- */
-int
-pci_save_state(struct pci_dev *dev)
-{
- int i;
- /* XXX: 100% dword access ok here? */
- for (i = 0; i < 16; i++)
- pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
- dev->state_saved = true;
- if ((i = pci_save_pcie_state(dev)) != 0)
- return i;
- if ((i = pci_save_pcix_state(dev)) != 0)
- return i;
- return 0;
-}
-
-/**
- * pci_restore_state - Restore the saved state of a PCI device
- * @dev: - PCI device that we're dealing with
- */
-int
-pci_restore_state(struct pci_dev *dev)
-{
- int i;
- u32 val;
-
- /* PCI Express register must be restored first */
- pci_restore_pcie_state(dev);
-
- /*
- * The Base Address register should be programmed before the command
- * register(s)
- */
- for (i = 15; i >= 0; i--) {
- pci_read_config_dword(dev, i * 4, &val);
- if (val != dev->saved_config_space[i]) {
- dev_printk(KERN_DEBUG, &dev->dev, "restoring config "
- "space at offset %#x (was %#x, writing %#x)\n",
- i, val, (int)dev->saved_config_space[i]);
- pci_write_config_dword(dev,i * 4,
- dev->saved_config_space[i]);
- }
- }
- pci_restore_pcix_state(dev);
- pci_restore_msi_state(dev);
-
- return 0;
-}
-
-static int do_pci_enable_device(struct pci_dev *dev, int bars)
-{
- int err;
-
- err = pci_set_power_state(dev, PCI_D0);
- if (err < 0 && err != -EIO)
- return err;
- err = pcibios_enable_device(dev, bars);
- if (err < 0)
- return err;
- pci_fixup_device(pci_fixup_enable, dev);
-
- return 0;
-}
-
-/**
- * pci_reenable_device - Resume abandoned device
- * @dev: PCI device to be resumed
- *
- * Note this function is a backend of pci_default_resume and is not supposed
- * to be called by normal code, write proper resume handler and use it instead.
- */
-int pci_reenable_device(struct pci_dev *dev)
-{
- if (atomic_read(&dev->enable_cnt))
- return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
- return 0;
-}
-
-static int __pci_enable_device_flags(struct pci_dev *dev,
- resource_size_t flags)
-{
- int err;
- int i, bars = 0;
-
- if (atomic_add_return(1, &dev->enable_cnt) > 1)
- return 0; /* already enabled */
-
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
- if (dev->resource[i].flags & flags)
- bars |= (1 << i);
-
- err = do_pci_enable_device(dev, bars);
- if (err < 0)
- atomic_dec(&dev->enable_cnt);
- return err;
-}
-
-/**
- * pci_enable_device_io - Initialize a device for use with IO space
- * @dev: PCI device to be initialized
- *
- * Initialize device before it's used by a driver. Ask low-level code
- * to enable I/O resources. Wake up the device if it was suspended.
- * Beware, this function can fail.
- */
-int pci_enable_device_io(struct pci_dev *dev)
-{
- return __pci_enable_device_flags(dev, IORESOURCE_IO);
-}
-
-/**
- * pci_enable_device_mem - Initialize a device for use with Memory space
- * @dev: PCI device to be initialized
- *
- * Initialize device before it's used by a driver. Ask low-level code
- * to enable Memory resources. Wake up the device if it was suspended.
- * Beware, this function can fail.
- */
-int pci_enable_device_mem(struct pci_dev *dev)
-{
- return __pci_enable_device_flags(dev, IORESOURCE_MEM);
-}
-
-/** pci_enable_device() is implemented by the DDE. */
-#ifndef DDE_LINUX
-/**
- * pci_enable_device - Initialize device before it's used by a driver.
- * @dev: PCI device to be initialized
- *
- * Initialize device before it's used by a driver. Ask low-level code
- * to enable I/O and memory. Wake up the device if it was suspended.
- * Beware, this function can fail.
- *
- * Note we don't actually enable the device many times if we call
- * this function repeatedly (we just increment the count).
- */
-int pci_enable_device(struct pci_dev *dev)
-{
- return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO);
-}
-#endif
-
-/*
- * Managed PCI resources. This manages device on/off, intx/msi/msix
- * on/off and BAR regions. pci_dev itself records msi/msix status, so
- * there's no need to track it separately. pci_devres is initialized
- * when a device is enabled using managed PCI device enable interface.
- */
-struct pci_devres {
- unsigned int enabled:1;
- unsigned int pinned:1;
- unsigned int orig_intx:1;
- unsigned int restore_intx:1;
- u32 region_mask;
-};
-
-static void pcim_release(struct device *gendev, void *res)
-{
- struct pci_dev *dev = container_of(gendev, struct pci_dev, dev);
- struct pci_devres *this = res;
- int i;
-
- if (dev->msi_enabled)
- pci_disable_msi(dev);
- if (dev->msix_enabled)
- pci_disable_msix(dev);
-
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
- if (this->region_mask & (1 << i))
- pci_release_region(dev, i);
-
- if (this->restore_intx)
- pci_intx(dev, this->orig_intx);
-
- if (this->enabled && !this->pinned)
- pci_disable_device(dev);
-}
-
-static struct pci_devres * get_pci_dr(struct pci_dev *pdev)
-{
- struct pci_devres *dr, *new_dr;
-
- dr = devres_find(&pdev->dev, pcim_release, NULL, NULL);
- if (dr)
- return dr;
-
- new_dr = devres_alloc(pcim_release, sizeof(*new_dr), GFP_KERNEL);
- if (!new_dr)
- return NULL;
- return devres_get(&pdev->dev, new_dr, NULL, NULL);
-}
-
-static struct pci_devres * find_pci_dr(struct pci_dev *pdev)
-{
- if (pci_is_managed(pdev))
- return devres_find(&pdev->dev, pcim_release, NULL, NULL);
- return NULL;
-}
-
-/**
- * pcim_enable_device - Managed pci_enable_device()
- * @pdev: PCI device to be initialized
- *
- * Managed pci_enable_device().
- */
-int pcim_enable_device(struct pci_dev *pdev)
-{
- struct pci_devres *dr;
- int rc;
-
- dr = get_pci_dr(pdev);
- if (unlikely(!dr))
- return -ENOMEM;
- if (dr->enabled)
- return 0;
-
- rc = pci_enable_device(pdev);
- if (!rc) {
- pdev->is_managed = 1;
- dr->enabled = 1;
- }
- return rc;
-}
-
-/**
- * pcim_pin_device - Pin managed PCI device
- * @pdev: PCI device to pin
- *
- * Pin managed PCI device @pdev. Pinned device won't be disabled on
- * driver detach. @pdev must have been enabled with
- * pcim_enable_device().
- */
-void pcim_pin_device(struct pci_dev *pdev)
-{
- struct pci_devres *dr;
-
- dr = find_pci_dr(pdev);
- WARN_ON(!dr || !dr->enabled);
- if (dr)
- dr->pinned = 1;
-}
-
-#ifndef DDE_LINUX
-/**
- * pcibios_disable_device - disable arch specific PCI resources for device dev
- * @dev: the PCI device to disable
- *
- * Disables architecture specific PCI resources for the device. This
- * is the default implementation. Architecture implementations can
- * override this.
- */
-void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {}
-
-static void do_pci_disable_device(struct pci_dev *dev)
-{
- u16 pci_command;
-
- pci_read_config_word(dev, PCI_COMMAND, &pci_command);
- if (pci_command & PCI_COMMAND_MASTER) {
- pci_command &= ~PCI_COMMAND_MASTER;
- pci_write_config_word(dev, PCI_COMMAND, pci_command);
- }
-
- pcibios_disable_device(dev);
-}
-
-/**
- * pci_disable_enabled_device - Disable device without updating enable_cnt
- * @dev: PCI device to disable
- *
- * NOTE: This function is a backend of PCI power management routines and is
- * not supposed to be called drivers.
- */
-void pci_disable_enabled_device(struct pci_dev *dev)
-{
- if (atomic_read(&dev->enable_cnt))
- do_pci_disable_device(dev);
-}
-
-/**
- * pci_disable_device - Disable PCI device after use
- * @dev: PCI device to be disabled
- *
- * Signal to the system that the PCI device is not in use by the system
- * anymore. This only involves disabling PCI bus-mastering, if active.
- *
- * Note we don't actually disable the device until all callers of
- * pci_device_enable() have called pci_device_disable().
- */
-void
-pci_disable_device(struct pci_dev *dev)
-{
- struct pci_devres *dr;
-
- dr = find_pci_dr(dev);
- if (dr)
- dr->enabled = 0;
-
- if (atomic_sub_return(1, &dev->enable_cnt) != 0)
- return;
-
- do_pci_disable_device(dev);
-
- dev->is_busmaster = 0;
-}
-
-/**
- * pcibios_set_pcie_reset_state - set reset state for device dev
- * @dev: the PCI-E device reset
- * @state: Reset state to enter into
- *
- *
- * Sets the PCI-E reset state for the device. This is the default
- * implementation. Architecture implementations can override this.
- */
-int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev,
- enum pcie_reset_state state)
-{
- return -EINVAL;
-}
-#endif
-
-/**
- * pci_set_pcie_reset_state - set reset state for device dev
- * @dev: the PCI-E device reset
- * @state: Reset state to enter into
- *
- *
- * Sets the PCI reset state for the device.
- */
-int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
-{
- return pcibios_set_pcie_reset_state(dev, state);
-}
-
-/**
- * pci_pme_capable - check the capability of PCI device to generate PME#
- * @dev: PCI device to handle.
- * @state: PCI state from which device will issue PME#.
- */
-bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
-{
- if (!dev->pm_cap)
- return false;
-
- return !!(dev->pme_support & (1 << state));
-}
-
-/**
- * pci_pme_active - enable or disable PCI device's PME# function
- * @dev: PCI device to handle.
- * @enable: 'true' to enable PME# generation; 'false' to disable it.
- *
- * The caller must verify that the device is capable of generating PME# before
- * calling this function with @enable equal to 'true'.
- */
-void pci_pme_active(struct pci_dev *dev, bool enable)
-{
- u16 pmcsr;
-
- if (!dev->pm_cap)
- return;
-
- pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
- /* Clear PME_Status by writing 1 to it and enable PME# */
- pmcsr |= PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_PME_ENABLE;
- if (!enable)
- pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
-
- pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
-
- dev_printk(KERN_INFO, &dev->dev, "PME# %s\n",
- enable ? "enabled" : "disabled");
-}
-
-/**
- * pci_enable_wake - enable PCI device as wakeup event source
- * @dev: PCI device affected
- * @state: PCI state from which device will issue wakeup events
- * @enable: True to enable event generation; false to disable
- *
- * This enables the device as a wakeup event source, or disables it.
- * When such events involves platform-specific hooks, those hooks are
- * called automatically by this routine.
- *
- * Devices with legacy power management (no standard PCI PM capabilities)
- * always require such platform hooks.
- *
- * RETURN VALUE:
- * 0 is returned on success
- * -EINVAL is returned if device is not supposed to wake up the system
- * Error code depending on the platform is returned if both the platform and
- * the native mechanism fail to enable the generation of wake-up events
- */
-int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
-{
- int error = 0;
- bool pme_done = false;
-
- if (enable && !device_may_wakeup(&dev->dev))
- return -EINVAL;
-
- /*
- * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don
- * Anderson we should be doing PME# wake enable followed by ACPI wake
- * enable. To disable wake-up we call the platform first, for symmetry.
- */
-
- if (!enable && platform_pci_can_wakeup(dev))
- error = platform_pci_sleep_wake(dev, false);
-
- if (!enable || pci_pme_capable(dev, state)) {
- pci_pme_active(dev, enable);
- pme_done = true;
- }
-
- if (enable && platform_pci_can_wakeup(dev))
- error = platform_pci_sleep_wake(dev, true);
-
- return pme_done ? 0 : error;
-}
-
-/**
- * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
- * @dev: PCI device to prepare
- * @enable: True to enable wake-up event generation; false to disable
- *
- * Many drivers want the device to wake up the system from D3_hot or D3_cold
- * and this function allows them to set that up cleanly - pci_enable_wake()
- * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI
- * ordering constraints.
- *
- * This function only returns error code if the device is not capable of
- * generating PME# from both D3_hot and D3_cold, and the platform is unable to
- * enable wake-up power for it.
- */
-int pci_wake_from_d3(struct pci_dev *dev, bool enable)
-{
- return pci_pme_capable(dev, PCI_D3cold) ?
- pci_enable_wake(dev, PCI_D3cold, enable) :
- pci_enable_wake(dev, PCI_D3hot, enable);
-}
-
-/**
- * pci_target_state - find an appropriate low power state for a given PCI dev
- * @dev: PCI device
- *
- * Use underlying platform code to find a supported low power state for @dev.
- * If the platform can't manage @dev, return the deepest state from which it
- * can generate wake events, based on any available PME info.
- */
-pci_power_t pci_target_state(struct pci_dev *dev)
-{
- pci_power_t target_state = PCI_D3hot;
-
- if (platform_pci_power_manageable(dev)) {
- /*
- * Call the platform to choose the target state of the device
- * and enable wake-up from this state if supported.
- */
- pci_power_t state = platform_pci_choose_state(dev);
-
- switch (state) {
- case PCI_POWER_ERROR:
- case PCI_UNKNOWN:
- break;
- case PCI_D1:
- case PCI_D2:
- if (pci_no_d1d2(dev))
- break;
- default:
- target_state = state;
- }
- } else if (device_may_wakeup(&dev->dev)) {
- /*
- * Find the deepest state from which the device can generate
- * wake-up events, make it the target state and enable device
- * to generate PME#.
- */
- if (!dev->pm_cap)
- return PCI_POWER_ERROR;
-
- if (dev->pme_support) {
- while (target_state
- && !(dev->pme_support & (1 << target_state)))
- target_state--;
- }
- }
-
- return target_state;
-}
-
-/**
- * pci_prepare_to_sleep - prepare PCI device for system-wide transition into a sleep state
- * @dev: Device to handle.
- *
- * Choose the power state appropriate for the device depending on whether
- * it can wake up the system and/or is power manageable by the platform
- * (PCI_D3hot is the default) and put the device into that state.
- */
-int pci_prepare_to_sleep(struct pci_dev *dev)
-{
- pci_power_t target_state = pci_target_state(dev);
- int error;
-
- if (target_state == PCI_POWER_ERROR)
- return -EIO;
-
- pci_enable_wake(dev, target_state, true);
-
- error = pci_set_power_state(dev, target_state);
-
- if (error)
- pci_enable_wake(dev, target_state, false);
-
- return error;
-}
-
-/**
- * pci_back_from_sleep - turn PCI device on during system-wide transition into working state
- * @dev: Device to handle.
- *
- * Disable device's sytem wake-up capability and put it into D0.
- */
-int pci_back_from_sleep(struct pci_dev *dev)
-{
- pci_enable_wake(dev, PCI_D0, false);
- return pci_set_power_state(dev, PCI_D0);
-}
-
-/**
- * pci_pm_init - Initialize PM functions of given PCI device
- * @dev: PCI device to handle.
- */
-void pci_pm_init(struct pci_dev *dev)
-{
- int pm;
- u16 pmc;
-
- dev->pm_cap = 0;
-
- /* find PCI PM capability in list */
- pm = pci_find_capability(dev, PCI_CAP_ID_PM);
- if (!pm)
- return;
- /* Check device's ability to generate PME# */
- pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc);
-
- if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
- dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
- pmc & PCI_PM_CAP_VER_MASK);
- return;
- }
-
- dev->pm_cap = pm;
-
- dev->d1_support = false;
- dev->d2_support = false;
- if (!pci_no_d1d2(dev)) {
- if (pmc & PCI_PM_CAP_D1)
- dev->d1_support = true;
- if (pmc & PCI_PM_CAP_D2)
- dev->d2_support = true;
-
- if (dev->d1_support || dev->d2_support)
- dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n",
- dev->d1_support ? " D1" : "",
- dev->d2_support ? " D2" : "");
- }
-
- pmc &= PCI_PM_CAP_PME_MASK;
- if (pmc) {
- dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n",
- (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
- (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
- (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
- (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
- (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
- dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
- /*
- * Make device's PM flags reflect the wake-up capability, but
- * let the user space enable it to wake up the system as needed.
- */
- device_set_wakeup_capable(&dev->dev, true);
- device_set_wakeup_enable(&dev->dev, false);
- /* Disable the PME# generation functionality */
- pci_pme_active(dev, false);
- } else {
- dev->pme_support = 0;
- }
-}
-
-/**
- * platform_pci_wakeup_init - init platform wakeup if present
- * @dev: PCI device
- *
- * Some devices don't have PCI PM caps but can still generate wakeup
- * events through platform methods (like ACPI events). If @dev supports
- * platform wakeup events, set the device flag to indicate as much. This
- * may be redundant if the device also supports PCI PM caps, but double
- * initialization should be safe in that case.
- */
-void platform_pci_wakeup_init(struct pci_dev *dev)
-{
- if (!platform_pci_can_wakeup(dev))
- return;
-
- device_set_wakeup_capable(&dev->dev, true);
- device_set_wakeup_enable(&dev->dev, false);
- platform_pci_sleep_wake(dev, false);
-}
-
-
-/**
- * pci_add_save_buffer - allocate buffer for saving given capability registers
- * @dev: the PCI device
- * @cap: the capability to allocate the buffer for
- * @size: requested size of the buffer
- */
-static int pci_add_cap_save_buffer(
- struct pci_dev *dev, char cap, unsigned int size)
-{
- int pos;
- struct pci_cap_saved_state *save_state;
-
- pos = pci_find_capability(dev, cap);
- if (pos <= 0)
- return 0;
-
- save_state = kzalloc(sizeof(*save_state) + size, GFP_KERNEL);
- if (!save_state)
- return -ENOMEM;
-
- save_state->cap_nr = cap;
- pci_add_saved_cap(dev, save_state);
-
- return 0;
-}
-
-/**
- * pci_allocate_cap_save_buffers - allocate buffers for saving capabilities
- * @dev: the PCI device
- */
-void pci_allocate_cap_save_buffers(struct pci_dev *dev)
-{
- int error;
-
- error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP, 4 * sizeof(u16));
- if (error)
- dev_err(&dev->dev,
- "unable to preallocate PCI Express save buffer\n");
-
- error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_PCIX, sizeof(u16));
- if (error)
- dev_err(&dev->dev,
- "unable to preallocate PCI-X save buffer\n");
-}
-
-/**
- * pci_restore_standard_config - restore standard config registers of PCI device
- * @dev: PCI device to handle
- *
- * This function assumes that the device's configuration space is accessible.
- * If the device needs to be powered up, the function will wait for it to
- * change the state.
- */
-int pci_restore_standard_config(struct pci_dev *dev)
-{
- pci_power_t prev_state;
- int error;
-
- pci_update_current_state(dev, PCI_D0);
-
- prev_state = dev->current_state;
- if (prev_state == PCI_D0)
- goto Restore;
-
- error = pci_raw_set_power_state(dev, PCI_D0, false);
- if (error)
- return error;
-
- /*
- * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
- * we've made this assumption forever and it appears to be universally
- * satisfied.
- */
- switch(prev_state) {
- case PCI_D3cold:
- case PCI_D3hot:
- mdelay(pci_pm_d3_delay);
- break;
- case PCI_D2:
- udelay(PCI_PM_D2_DELAY);
- break;
- }
-
- pci_update_current_state(dev, PCI_D0);
-
- Restore:
- return dev->state_saved ? pci_restore_state(dev) : 0;
-}
-
-/**
- * pci_enable_ari - enable ARI forwarding if hardware support it
- * @dev: the PCI device
- */
-void pci_enable_ari(struct pci_dev *dev)
-{
- int pos;
- u32 cap;
- u16 ctrl;
- struct pci_dev *bridge;
-
- if (!dev->is_pcie || dev->devfn)
- return;
-
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
- if (!pos)
- return;
-
- bridge = dev->bus->self;
- if (!bridge || !bridge->is_pcie)
- return;
-
- pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
- if (!pos)
- return;
-
- pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
- if (!(cap & PCI_EXP_DEVCAP2_ARI))
- return;
-
- pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl |= PCI_EXP_DEVCTL2_ARI;
- pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl);
-
- bridge->ari_enabled = 1;
-}
-
-/**
- * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
- * @dev: the PCI device
- * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD)
- *
- * Perform INTx swizzling for a device behind one level of bridge. This is
- * required by section 9.1 of the PCI-to-PCI bridge specification for devices
- * behind bridges on add-in cards.
- */
-u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin)
-{
- return (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
-}
-
-int
-pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
-{
- u8 pin;
-
- pin = dev->pin;
- if (!pin)
- return -1;
-
- while (dev->bus->self) {
- pin = pci_swizzle_interrupt_pin(dev, pin);
- dev = dev->bus->self;
- }
- *bridge = dev;
- return pin;
-}
-
-/**
- * pci_common_swizzle - swizzle INTx all the way to root bridge
- * @dev: the PCI device
- * @pinp: pointer to the INTx pin value (1=INTA, 2=INTB, 3=INTD, 4=INTD)
- *
- * Perform INTx swizzling for a device. This traverses through all PCI-to-PCI
- * bridges all the way up to a PCI root bus.
- */
-u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp)
-{
- u8 pin = *pinp;
-
- while (dev->bus->self) {
- pin = pci_swizzle_interrupt_pin(dev, pin);
- dev = dev->bus->self;
- }
- *pinp = pin;
- return PCI_SLOT(dev->devfn);
-}
-
-/**
- * pci_release_region - Release a PCI bar
- * @pdev: PCI device whose resources were previously reserved by pci_request_region
- * @bar: BAR to release
- *
- * Releases the PCI I/O and memory resources previously reserved by a
- * successful call to pci_request_region. Call this function only
- * after all use of the PCI regions has ceased.
- */
-void pci_release_region(struct pci_dev *pdev, int bar)
-{
- struct pci_devres *dr;
-
- if (pci_resource_len(pdev, bar) == 0)
- return;
- if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
- release_region(pci_resource_start(pdev, bar),
- pci_resource_len(pdev, bar));
- else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
- release_mem_region(pci_resource_start(pdev, bar),
- pci_resource_len(pdev, bar));
-
- dr = find_pci_dr(pdev);
- if (dr)
- dr->region_mask &= ~(1 << bar);
-}
-
-/**
- * __pci_request_region - Reserved PCI I/O and memory resource
- * @pdev: PCI device whose resources are to be reserved
- * @bar: BAR to be reserved
- * @res_name: Name to be associated with resource.
- * @exclusive: whether the region access is exclusive or not
- *
- * Mark the PCI region associated with PCI device @pdev BR @bar as
- * being reserved by owner @res_name. Do not access any
- * address inside the PCI regions unless this call returns
- * successfully.
- *
- * If @exclusive is set, then the region is marked so that userspace
- * is explicitly not allowed to map the resource via /dev/mem or
- * sysfs MMIO access.
- *
- * Returns 0 on success, or %EBUSY on error. A warning
- * message is also printed on failure.
- */
-static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_name,
- int exclusive)
-{
- struct pci_devres *dr;
-
- if (pci_resource_len(pdev, bar) == 0)
- return 0;
-
- if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
- if (!request_region(pci_resource_start(pdev, bar),
- pci_resource_len(pdev, bar), res_name))
- goto err_out;
- }
- else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
- if (!__request_mem_region(pci_resource_start(pdev, bar),
- pci_resource_len(pdev, bar), res_name,
- exclusive))
- goto err_out;
- }
-
- dr = find_pci_dr(pdev);
- if (dr)
- dr->region_mask |= 1 << bar;
-
- return 0;
-
-err_out:
- dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n",
- bar,
- pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
- &pdev->resource[bar]);
- return -EBUSY;
-}
-
-/**
- * pci_request_region - Reserve PCI I/O and memory resource
- * @pdev: PCI device whose resources are to be reserved
- * @bar: BAR to be reserved
- * @res_name: Name to be associated with resource
- *
- * Mark the PCI region associated with PCI device @pdev BAR @bar as
- * being reserved by owner @res_name. Do not access any
- * address inside the PCI regions unless this call returns
- * successfully.
- *
- * Returns 0 on success, or %EBUSY on error. A warning
- * message is also printed on failure.
- */
-int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
-{
- return __pci_request_region(pdev, bar, res_name, 0);
-}
-
-/**
- * pci_request_region_exclusive - Reserved PCI I/O and memory resource
- * @pdev: PCI device whose resources are to be reserved
- * @bar: BAR to be reserved
- * @res_name: Name to be associated with resource.
- *
- * Mark the PCI region associated with PCI device @pdev BR @bar as
- * being reserved by owner @res_name. Do not access any
- * address inside the PCI regions unless this call returns
- * successfully.
- *
- * Returns 0 on success, or %EBUSY on error. A warning
- * message is also printed on failure.
- *
- * The key difference that _exclusive makes it that userspace is
- * explicitly not allowed to map the resource via /dev/mem or
- * sysfs.
- */
-int pci_request_region_exclusive(struct pci_dev *pdev, int bar, const char *res_name)
-{
- return __pci_request_region(pdev, bar, res_name, IORESOURCE_EXCLUSIVE);
-}
-/**
- * pci_release_selected_regions - Release selected PCI I/O and memory resources
- * @pdev: PCI device whose resources were previously reserved
- * @bars: Bitmask of BARs to be released
- *
- * Release selected PCI I/O and memory resources previously reserved.
- * Call this function only after all use of the PCI regions has ceased.
- */
-void pci_release_selected_regions(struct pci_dev *pdev, int bars)
-{
- int i;
-
- for (i = 0; i < 6; i++)
- if (bars & (1 << i))
- pci_release_region(pdev, i);
-}
-
-int __pci_request_selected_regions(struct pci_dev *pdev, int bars,
- const char *res_name, int excl)
-{
- int i;
-
- for (i = 0; i < 6; i++)
- if (bars & (1 << i))
- if (__pci_request_region(pdev, i, res_name, excl))
- goto err_out;
- return 0;
-
-err_out:
- while(--i >= 0)
- if (bars & (1 << i))
- pci_release_region(pdev, i);
-
- return -EBUSY;
-}
-
-
-/**
- * pci_request_selected_regions - Reserve selected PCI I/O and memory resources
- * @pdev: PCI device whose resources are to be reserved
- * @bars: Bitmask of BARs to be requested
- * @res_name: Name to be associated with resource
- */
-int pci_request_selected_regions(struct pci_dev *pdev, int bars,
- const char *res_name)
-{
- return __pci_request_selected_regions(pdev, bars, res_name, 0);
-}
-
-int pci_request_selected_regions_exclusive(struct pci_dev *pdev,
- int bars, const char *res_name)
-{
- return __pci_request_selected_regions(pdev, bars, res_name,
- IORESOURCE_EXCLUSIVE);
-}
-
-/**
- * pci_release_regions - Release reserved PCI I/O and memory resources
- * @pdev: PCI device whose resources were previously reserved by pci_request_regions
- *
- * Releases all PCI I/O and memory resources previously reserved by a
- * successful call to pci_request_regions. Call this function only
- * after all use of the PCI regions has ceased.
- */
-
-void pci_release_regions(struct pci_dev *pdev)
-{
- pci_release_selected_regions(pdev, (1 << 6) - 1);
-}
-
-/**
- * pci_request_regions - Reserved PCI I/O and memory resources
- * @pdev: PCI device whose resources are to be reserved
- * @res_name: Name to be associated with resource.
- *
- * Mark all PCI regions associated with PCI device @pdev as
- * being reserved by owner @res_name. Do not access any
- * address inside the PCI regions unless this call returns
- * successfully.
- *
- * Returns 0 on success, or %EBUSY on error. A warning
- * message is also printed on failure.
- */
-int pci_request_regions(struct pci_dev *pdev, const char *res_name)
-{
- return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name);
-}
-
-#ifndef DDE_LINUX
-/**
- * pci_request_regions_exclusive - Reserved PCI I/O and memory resources
- * @pdev: PCI device whose resources are to be reserved
- * @res_name: Name to be associated with resource.
- *
- * Mark all PCI regions associated with PCI device @pdev as
- * being reserved by owner @res_name. Do not access any
- * address inside the PCI regions unless this call returns
- * successfully.
- *
- * pci_request_regions_exclusive() will mark the region so that
- * /dev/mem and the sysfs MMIO access will not be allowed.
- *
- * Returns 0 on success, or %EBUSY on error. A warning
- * message is also printed on failure.
- */
-int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
-{
- return pci_request_selected_regions_exclusive(pdev,
- ((1 << 6) - 1), res_name);
-}
-
-static void __pci_set_master(struct pci_dev *dev, bool enable)
-{
- u16 old_cmd, cmd;
-
- pci_read_config_word(dev, PCI_COMMAND, &old_cmd);
- if (enable)
- cmd = old_cmd | PCI_COMMAND_MASTER;
- else
- cmd = old_cmd & ~PCI_COMMAND_MASTER;
- if (cmd != old_cmd) {
- dev_dbg(&dev->dev, "%s bus mastering\n",
- enable ? "enabling" : "disabling");
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- dev->is_busmaster = enable;
-}
-
-/**
- * pci_set_master - enables bus-mastering for device dev
- * @dev: the PCI device to enable
- *
- * Enables bus-mastering on the device and calls pcibios_set_master()
- * to do the needed arch specific settings.
- */
-void pci_set_master(struct pci_dev *dev)
-{
- __pci_set_master(dev, true);
- pcibios_set_master(dev);
-}
-
-/**
- * pci_clear_master - disables bus-mastering for device dev
- * @dev: the PCI device to disable
- */
-void pci_clear_master(struct pci_dev *dev)
-{
- __pci_set_master(dev, false);
-}
-#endif /* DDE_LINUX */
-
-#ifdef PCI_DISABLE_MWI
-int pci_set_mwi(struct pci_dev *dev)
-{
- return 0;
-}
-
-int pci_try_set_mwi(struct pci_dev *dev)
-{
- return 0;
-}
-
-void pci_clear_mwi(struct pci_dev *dev)
-{
-}
-
-#else
-
-#ifndef PCI_CACHE_LINE_BYTES
-#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES
-#endif
-
-/* This can be overridden by arch code. */
-/* Don't forget this is measured in 32-bit words, not bytes */
-u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4;
-
-/**
- * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
- * @dev: the PCI device for which MWI is to be enabled
- *
- * Helper function for pci_set_mwi.
- * Originally copied from drivers/net/acenic.c.
- * Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>.
- *
- * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
- */
-static int
-pci_set_cacheline_size(struct pci_dev *dev)
-{
- u8 cacheline_size;
-
- if (!pci_cache_line_size)
- return -EINVAL; /* The system doesn't support MWI. */
-
- /* Validate current setting: the PCI_CACHE_LINE_SIZE must be
- equal to or multiple of the right value. */
- pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
- if (cacheline_size >= pci_cache_line_size &&
- (cacheline_size % pci_cache_line_size) == 0)
- return 0;
-
- /* Write the correct value. */
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
- /* Read it back. */
- pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
- if (cacheline_size == pci_cache_line_size)
- return 0;
-
- dev_printk(KERN_DEBUG, &dev->dev, "cache line size of %d is not "
- "supported\n", pci_cache_line_size << 2);
-
- return -EINVAL;
-}
-
-/**
- * pci_set_mwi - enables memory-write-invalidate PCI transaction
- * @dev: the PCI device for which MWI is enabled
- *
- * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
- *
- * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
- */
-int
-pci_set_mwi(struct pci_dev *dev)
-{
- int rc;
- u16 cmd;
-
- rc = pci_set_cacheline_size(dev);
- if (rc)
- return rc;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- if (! (cmd & PCI_COMMAND_INVALIDATE)) {
- dev_dbg(&dev->dev, "enabling Mem-Wr-Inval\n");
- cmd |= PCI_COMMAND_INVALIDATE;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
-
- return 0;
-}
-
-/**
- * pci_try_set_mwi - enables memory-write-invalidate PCI transaction
- * @dev: the PCI device for which MWI is enabled
- *
- * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
- * Callers are not required to check the return value.
- *
- * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
- */
-int pci_try_set_mwi(struct pci_dev *dev)
-{
- int rc = pci_set_mwi(dev);
- return rc;
-}
-
-/**
- * pci_clear_mwi - disables Memory-Write-Invalidate for device dev
- * @dev: the PCI device to disable
- *
- * Disables PCI Memory-Write-Invalidate transaction on the device
- */
-void
-pci_clear_mwi(struct pci_dev *dev)
-{
- u16 cmd;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- if (cmd & PCI_COMMAND_INVALIDATE) {
- cmd &= ~PCI_COMMAND_INVALIDATE;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
-}
-#endif /* ! PCI_DISABLE_MWI */
-
-/**
- * pci_intx - enables/disables PCI INTx for device dev
- * @pdev: the PCI device to operate on
- * @enable: boolean: whether to enable or disable PCI INTx
- *
- * Enables/disables PCI INTx for device dev
- */
-void
-pci_intx(struct pci_dev *pdev, int enable)
-{
- u16 pci_command, new;
-
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-
- if (enable) {
- new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
- } else {
- new = pci_command | PCI_COMMAND_INTX_DISABLE;
- }
-
- if (new != pci_command) {
- struct pci_devres *dr;
-
- pci_write_config_word(pdev, PCI_COMMAND, new);
-
- dr = find_pci_dr(pdev);
- if (dr && !dr->restore_intx) {
- dr->restore_intx = 1;
- dr->orig_intx = !enable;
- }
- }
-}
-
-/**
- * pci_msi_off - disables any msi or msix capabilities
- * @dev: the PCI device to operate on
- *
- * If you want to use msi see pci_enable_msi and friends.
- * This is a lower level primitive that allows us to disable
- * msi operation at the device level.
- */
-void pci_msi_off(struct pci_dev *dev)
-{
- int pos;
- u16 control;
-
- pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
- if (pos) {
- pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
- control &= ~PCI_MSI_FLAGS_ENABLE;
- pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
- }
- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
- if (pos) {
- pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
- control &= ~PCI_MSIX_FLAGS_ENABLE;
- pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
- }
-}
-
-#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
-/*
- * These can be overridden by arch-specific implementations
- */
-int
-pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (!pci_dma_supported(dev, mask))
- return -EIO;
-
- dev->dma_mask = mask;
-
- return 0;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (!pci_dma_supported(dev, mask))
- return -EIO;
-
- dev->dev.coherent_dma_mask = mask;
-
- return 0;
-}
-#endif
-
-#ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE
-int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
-{
- return dma_set_max_seg_size(&dev->dev, size);
-}
-EXPORT_SYMBOL(pci_set_dma_max_seg_size);
-#endif
-
-#ifndef HAVE_ARCH_PCI_SET_DMA_SEGMENT_BOUNDARY
-int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
-{
- return dma_set_seg_boundary(&dev->dev, mask);
-}
-EXPORT_SYMBOL(pci_set_dma_seg_boundary);
-#endif
-
-static int __pcie_flr(struct pci_dev *dev, int probe)
-{
- u16 status;
- u32 cap;
- int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-
- if (!exppos)
- return -ENOTTY;
- pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
- if (!(cap & PCI_EXP_DEVCAP_FLR))
- return -ENOTTY;
-
- if (probe)
- return 0;
-
- pci_block_user_cfg_access(dev);
-
- /* Wait for Transaction Pending bit clean */
- msleep(100);
- pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND) {
- dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
- "sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND)
- dev_info(&dev->dev, "Still busy after 1s; "
- "proceeding with reset anyway\n");
- }
-
- pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_BCR_FLR);
- mdelay(100);
-
- pci_unblock_user_cfg_access(dev);
- return 0;
-}
-
-static int __pci_af_flr(struct pci_dev *dev, int probe)
-{
- int cappos = pci_find_capability(dev, PCI_CAP_ID_AF);
- u8 status;
- u8 cap;
-
- if (!cappos)
- return -ENOTTY;
- pci_read_config_byte(dev, cappos + PCI_AF_CAP, &cap);
- if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
- return -ENOTTY;
-
- if (probe)
- return 0;
-
- pci_block_user_cfg_access(dev);
-
- /* Wait for Transaction Pending bit clean */
- msleep(100);
- pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP) {
- dev_info(&dev->dev, "Busy after 100ms while trying to"
- " reset; sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_byte(dev,
- cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP)
- dev_info(&dev->dev, "Still busy after 1s; "
- "proceeding with reset anyway\n");
- }
- pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
- mdelay(100);
-
- pci_unblock_user_cfg_access(dev);
- return 0;
-}
-
-static int __pci_reset_function(struct pci_dev *pdev, int probe)
-{
- int res;
-
- res = __pcie_flr(pdev, probe);
- if (res != -ENOTTY)
- return res;
-
- res = __pci_af_flr(pdev, probe);
- if (res != -ENOTTY)
- return res;
-
- return res;
-}
-
-/**
- * pci_execute_reset_function() - Reset a PCI device function
- * @dev: Device function to reset
- *
- * Some devices allow an individual function to be reset without affecting
- * other functions in the same device. The PCI device must be responsive
- * to PCI config space in order to use this function.
- *
- * The device function is presumed to be unused when this function is called.
- * Resetting the device will make the contents of PCI configuration space
- * random, so any caller of this must be prepared to reinitialise the
- * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
- * etc.
- *
- * Returns 0 if the device function was successfully reset or -ENOTTY if the
- * device doesn't support resetting a single function.
- */
-int pci_execute_reset_function(struct pci_dev *dev)
-{
- return __pci_reset_function(dev, 0);
-}
-EXPORT_SYMBOL_GPL(pci_execute_reset_function);
-
-/**
- * pci_reset_function() - quiesce and reset a PCI device function
- * @dev: Device function to reset
- *
- * Some devices allow an individual function to be reset without affecting
- * other functions in the same device. The PCI device must be responsive
- * to PCI config space in order to use this function.
- *
- * This function does not just reset the PCI portion of a device, but
- * clears all the state associated with the device. This function differs
- * from pci_execute_reset_function in that it saves and restores device state
- * over the reset.
- *
- * Returns 0 if the device function was successfully reset or -ENOTTY if the
- * device doesn't support resetting a single function.
- */
-int pci_reset_function(struct pci_dev *dev)
-{
- int r = __pci_reset_function(dev, 1);
-
- if (r < 0)
- return r;
-
- if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0)
- disable_irq(dev->irq);
- pci_save_state(dev);
-
- pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
-
- r = pci_execute_reset_function(dev);
-
- pci_restore_state(dev);
- if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0)
- enable_irq(dev->irq);
-
- return r;
-}
-EXPORT_SYMBOL_GPL(pci_reset_function);
-
-/**
- * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
- * @dev: PCI device to query
- *
- * Returns mmrbc: maximum designed memory read count in bytes
- * or appropriate error value.
- */
-int pcix_get_max_mmrbc(struct pci_dev *dev)
-{
- int err, cap;
- u32 stat;
-
- cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!cap)
- return -EINVAL;
-
- err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
- if (err)
- return -EINVAL;
-
- return (stat & PCI_X_STATUS_MAX_READ) >> 12;
-}
-EXPORT_SYMBOL(pcix_get_max_mmrbc);
-
-/**
- * pcix_get_mmrbc - get PCI-X maximum memory read byte count
- * @dev: PCI device to query
- *
- * Returns mmrbc: maximum memory read count in bytes
- * or appropriate error value.
- */
-int pcix_get_mmrbc(struct pci_dev *dev)
-{
- int ret, cap;
- u32 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);
- if (!ret)
- ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
-
- return ret;
-}
-EXPORT_SYMBOL(pcix_get_mmrbc);
-
-/**
- * pcix_set_mmrbc - set PCI-X maximum memory read byte count
- * @dev: PCI device to query
- * @mmrbc: maximum memory read count in bytes
- * valid values are 512, 1024, 2048, 4096
- *
- * If possible sets maximum memory read byte count, some bridges have erratas
- * that prevent this.
- */
-int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
-{
- int cap, err = -EINVAL;
- u32 stat, cmd, v, o;
-
- if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc))
- goto out;
-
- v = ffs(mmrbc) - 10;
-
- cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!cap)
- goto out;
-
- err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
- if (err)
- goto out;
-
- if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
- return -E2BIG;
-
- err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
- if (err)
- goto out;
-
- o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
- if (o != v) {
- if (v > o && dev->bus &&
- (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC))
- return -EIO;
-
- cmd &= ~PCI_X_CMD_MAX_READ;
- cmd |= v << 2;
- err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
- }
-out:
- return err;
-}
-EXPORT_SYMBOL(pcix_set_mmrbc);
-
-/**
- * pcie_get_readrq - get PCI Express read request size
- * @dev: PCI device to query
- *
- * Returns maximum memory read request in bytes
- * or appropriate error value.
- */
-int pcie_get_readrq(struct pci_dev *dev)
-{
- int ret, cap;
- u16 ctl;
-
- cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!cap)
- return -EINVAL;
-
- ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (!ret)
- ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
-
- return ret;
-}
-EXPORT_SYMBOL(pcie_get_readrq);
-
-/**
- * pcie_set_readrq - set PCI Express maximum memory read request
- * @dev: PCI device to query
- * @rq: maximum memory read count in bytes
- * valid values are 128, 256, 512, 1024, 2048, 4096
- *
- * If possible sets maximum read byte count
- */
-int pcie_set_readrq(struct pci_dev *dev, int rq)
-{
- int cap, err = -EINVAL;
- u16 ctl, v;
-
- if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
- goto out;
-
- v = (ffs(rq) - 8) << 12;
-
- cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!cap)
- goto out;
-
- err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (err)
- goto out;
-
- if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) {
- ctl &= ~PCI_EXP_DEVCTL_READRQ;
- ctl |= v;
- err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl);
- }
-
-out:
- return err;
-}
-EXPORT_SYMBOL(pcie_set_readrq);
-
-/**
- * pci_select_bars - Make BAR mask from the type of resource
- * @dev: the PCI device for which BAR mask is made
- * @flags: resource type mask to be selected
- *
- * This helper routine makes bar mask from the type of resource.
- */
-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;
-}
-
-/**
- * pci_resource_bar - get position of the BAR associated with a resource
- * @dev: the PCI device
- * @resno: the resource number
- * @type: the BAR type to be filled in
- *
- * Returns BAR position in config space, or 0 if the BAR is invalid.
- */
-int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
-{
- if (resno < PCI_ROM_RESOURCE) {
- *type = pci_bar_unknown;
- return PCI_BASE_ADDRESS_0 + 4 * resno;
- } else if (resno == PCI_ROM_RESOURCE) {
- *type = pci_bar_mem32;
- return dev->rom_base_reg;
- }
-
- dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno);
- return 0;
-}
-
-static void __devinit pci_no_domains(void)
-{
-#ifdef CONFIG_PCI_DOMAINS
- pci_domains_supported = 0;
-#endif
-}
-
-/**
- * pci_ext_cfg_enabled - can we access extended PCI config space?
- * @dev: The PCI device of the root bridge.
- *
- * Returns 1 if we can access PCI extended config space (offsets
- * greater than 0xff). This is the default implementation. Architecture
- * implementations can override this.
- */
-int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev)
-{
- return 1;
-}
-
-#ifndef DDE_LINUX
-static
-#endif
-int __devinit pci_init(void)
-{
- struct pci_dev *dev = NULL;
-
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- pci_fixup_device(pci_fixup_final, dev);
- }
-
- return 0;
-}
-
-static int __init pci_setup(char *str)
-{
-#ifndef DDE_LINUX
- while (str) {
- char *k = strchr(str, ',');
- if (k)
- *k++ = 0;
- if (*str && (str = pcibios_setup(str)) && *str) {
- if (!strcmp(str, "nomsi")) {
- pci_no_msi();
- } else if (!strcmp(str, "noaer")) {
- pci_no_aer();
- } else if (!strcmp(str, "nodomains")) {
- pci_no_domains();
- } else if (!strncmp(str, "cbiosize=", 9)) {
- pci_cardbus_io_size = memparse(str + 9, &str);
- } else if (!strncmp(str, "cbmemsize=", 10)) {
- pci_cardbus_mem_size = memparse(str + 10, &str);
- } else {
- printk(KERN_ERR "PCI: Unknown option `%s'\n",
- str);
- }
- }
- str = k;
- }
-#endif
- return 0;
-}
-early_param("pci", pci_setup);
-
-device_initcall(pci_init);
-
-EXPORT_SYMBOL(pci_reenable_device);
-EXPORT_SYMBOL(pci_enable_device_io);
-EXPORT_SYMBOL(pci_enable_device_mem);
-EXPORT_SYMBOL(pci_enable_device);
-EXPORT_SYMBOL(pcim_enable_device);
-EXPORT_SYMBOL(pcim_pin_device);
-EXPORT_SYMBOL(pci_disable_device);
-EXPORT_SYMBOL(pci_find_capability);
-EXPORT_SYMBOL(pci_bus_find_capability);
-EXPORT_SYMBOL(pci_release_regions);
-EXPORT_SYMBOL(pci_request_regions);
-EXPORT_SYMBOL(pci_request_regions_exclusive);
-EXPORT_SYMBOL(pci_release_region);
-EXPORT_SYMBOL(pci_request_region);
-EXPORT_SYMBOL(pci_request_region_exclusive);
-EXPORT_SYMBOL(pci_release_selected_regions);
-EXPORT_SYMBOL(pci_request_selected_regions);
-EXPORT_SYMBOL(pci_request_selected_regions_exclusive);
-EXPORT_SYMBOL(pci_set_master);
-EXPORT_SYMBOL(pci_clear_master);
-EXPORT_SYMBOL(pci_set_mwi);
-EXPORT_SYMBOL(pci_try_set_mwi);
-EXPORT_SYMBOL(pci_clear_mwi);
-EXPORT_SYMBOL_GPL(pci_intx);
-EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_set_consistent_dma_mask);
-EXPORT_SYMBOL(pci_assign_resource);
-EXPORT_SYMBOL(pci_find_parent_resource);
-EXPORT_SYMBOL(pci_select_bars);
-
-EXPORT_SYMBOL(pci_set_power_state);
-EXPORT_SYMBOL(pci_save_state);
-EXPORT_SYMBOL(pci_restore_state);
-EXPORT_SYMBOL(pci_pme_capable);
-EXPORT_SYMBOL(pci_pme_active);
-EXPORT_SYMBOL(pci_enable_wake);
-EXPORT_SYMBOL(pci_wake_from_d3);
-EXPORT_SYMBOL(pci_target_state);
-EXPORT_SYMBOL(pci_prepare_to_sleep);
-EXPORT_SYMBOL(pci_back_from_sleep);
-EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state);
-
diff --git a/libdde_linux26/lib/src/drivers/pci/.svn/text-base/probe.c.svn-base b/libdde_linux26/lib/src/drivers/pci/.svn/text-base/probe.c.svn-base
deleted file mode 100644
index 32da5108..00000000
--- a/libdde_linux26/lib/src/drivers/pci/.svn/text-base/probe.c.svn-base
+++ /dev/null
@@ -1,1232 +0,0 @@
-/*
- * probe.c - PCI detection and setup code
- */
-
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/cpumask.h>
-#include <linux/pci-aspm.h>
-#include "pci.h"
-
-#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
-#define CARDBUS_RESERVE_BUSNR 3
-
-/* Ugh. Need to stop exporting this to modules. */
-LIST_HEAD(pci_root_buses);
-EXPORT_SYMBOL(pci_root_buses);
-
-#ifdef DDE_LINUX
-#include "local.h"
-#endif
-
-static int find_anything(struct device *dev, void *data)
-{
- return 1;
-}
-
-/*
- * Some device drivers need know if pci is initiated.
- * Basically, we think pci is not initiated when there
- * is no device to be found on the pci_bus_type.
- */
-int no_pci_devices(void)
-{
- struct device *dev;
- int no_devices;
-
- dev = bus_find_device(&pci_bus_type, NULL, NULL, find_anything);
- no_devices = (dev == NULL);
- put_device(dev);
- return no_devices;
-}
-EXPORT_SYMBOL(no_pci_devices);
-
-/*
- * PCI Bus Class Devices
- */
-static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
- int type,
- struct device_attribute *attr,
- char *buf)
-{
- int ret;
- const struct cpumask *cpumask;
-
- cpumask = cpumask_of_pcibus(to_pci_bus(dev));
- ret = type?
- cpulist_scnprintf(buf, PAGE_SIZE-2, cpumask) :
- cpumask_scnprintf(buf, PAGE_SIZE-2, cpumask);
- buf[ret++] = '\n';
- buf[ret] = '\0';
- return ret;
-}
-
-static ssize_t inline pci_bus_show_cpumaskaffinity(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
-}
-
-static ssize_t inline pci_bus_show_cpulistaffinity(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return pci_bus_show_cpuaffinity(dev, 1, attr, buf);
-}
-
-DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpumaskaffinity, NULL);
-DEVICE_ATTR(cpulistaffinity, S_IRUGO, pci_bus_show_cpulistaffinity, NULL);
-
-/*
- * PCI Bus Class
- */
-static void release_pcibus_dev(struct device *dev)
-{
- struct pci_bus *pci_bus = to_pci_bus(dev);
-
- if (pci_bus->bridge)
- put_device(pci_bus->bridge);
- kfree(pci_bus);
-}
-
-static struct class pcibus_class = {
- .name = "pci_bus",
- .dev_release = &release_pcibus_dev,
-};
-
-static int __init pcibus_class_init(void)
-{
- return class_register(&pcibus_class);
-}
-postcore_initcall(pcibus_class_init);
-
-/*
- * Translate the low bits of the PCI base
- * to the resource type
- */
-static inline unsigned int pci_calc_resource_flags(unsigned int flags)
-{
- if (flags & PCI_BASE_ADDRESS_SPACE_IO)
- return IORESOURCE_IO;
-
- if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
- return IORESOURCE_MEM | IORESOURCE_PREFETCH;
-
- return IORESOURCE_MEM;
-}
-
-static u64 pci_size(u64 base, u64 maxbase, u64 mask)
-{
- u64 size = mask & maxbase; /* Find the significant bits */
- if (!size)
- return 0;
-
- /* Get the lowest of them to find the decode size, and
- from that the extent. */
- size = (size & ~(size-1)) - 1;
-
- /* base == maxbase can be valid only if the BAR has
- already been programmed with all 1s. */
- if (base == maxbase && ((base | size) & mask) != mask)
- return 0;
-
- return size;
-}
-
-static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
-{
- if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
- res->flags = bar & ~PCI_BASE_ADDRESS_IO_MASK;
- return pci_bar_io;
- }
-
- res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
-
- if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
- return pci_bar_mem64;
- return pci_bar_mem32;
-}
-
-/**
- * pci_read_base - read a PCI BAR
- * @dev: the PCI device
- * @type: type of the BAR
- * @res: resource buffer to be filled in
- * @pos: BAR position in the config space
- *
- * Returns 1 if the BAR is 64-bit, or 0 if 32-bit.
- */
-int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
- struct resource *res, unsigned int pos)
-{
- u32 l, sz, mask;
-
- mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0;
-
- res->name = pci_name(dev);
-
- pci_read_config_dword(dev, pos, &l);
- pci_write_config_dword(dev, pos, mask);
- pci_read_config_dword(dev, pos, &sz);
- pci_write_config_dword(dev, pos, l);
-
- /*
- * All bits set in sz means the device isn't working properly.
- * If the BAR isn't implemented, all bits must be 0. If it's a
- * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
- * 1 must be clear.
- */
- if (!sz || sz == 0xffffffff)
- goto fail;
-
- /*
- * I don't know how l can have all bits set. Copied from old code.
- * Maybe it fixes a bug on some ancient platform.
- */
- if (l == 0xffffffff)
- l = 0;
-
- if (type == pci_bar_unknown) {
- type = decode_bar(res, l);
- res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
- if (type == pci_bar_io) {
- l &= PCI_BASE_ADDRESS_IO_MASK;
- mask = PCI_BASE_ADDRESS_IO_MASK & 0xffff;
- } else {
- l &= PCI_BASE_ADDRESS_MEM_MASK;
- mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
- }
- } else {
- res->flags |= (l & IORESOURCE_ROM_ENABLE);
- l &= PCI_ROM_ADDRESS_MASK;
- mask = (u32)PCI_ROM_ADDRESS_MASK;
- }
-
- if (type == pci_bar_mem64) {
- u64 l64 = l;
- u64 sz64 = sz;
- u64 mask64 = mask | (u64)~0 << 32;
-
- pci_read_config_dword(dev, pos + 4, &l);
- pci_write_config_dword(dev, pos + 4, ~0);
- pci_read_config_dword(dev, pos + 4, &sz);
- pci_write_config_dword(dev, pos + 4, l);
-
- l64 |= ((u64)l << 32);
- sz64 |= ((u64)sz << 32);
-
- sz64 = pci_size(l64, sz64, mask64);
-
- if (!sz64)
- goto fail;
-
- if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) {
- dev_err(&dev->dev, "can't handle 64-bit BAR\n");
- goto fail;
- } else if ((sizeof(resource_size_t) < 8) && l) {
- /* Address above 32-bit boundary; disable the BAR */
- pci_write_config_dword(dev, pos, 0);
- pci_write_config_dword(dev, pos + 4, 0);
- res->start = 0;
- res->end = sz64;
- } else {
- res->start = l64;
- res->end = l64 + sz64;
- dev_printk(KERN_DEBUG, &dev->dev,
- "reg %x 64bit mmio: %pR\n", pos, res);
- }
- } else {
- sz = pci_size(l, sz, mask);
-
- if (!sz)
- goto fail;
-
- res->start = l;
- res->end = l + sz;
-
- dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos,
- (res->flags & IORESOURCE_IO) ? "io port" : "32bit mmio",
- res);
- }
-
- out:
- return (type == pci_bar_mem64) ? 1 : 0;
- fail:
- res->flags = 0;
- goto out;
-}
-
-static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
-{
- unsigned int pos, reg;
-
- for (pos = 0; pos < howmany; pos++) {
- struct resource *res = &dev->resource[pos];
- reg = PCI_BASE_ADDRESS_0 + (pos << 2);
- pos += __pci_read_base(dev, pci_bar_unknown, res, reg);
- }
-
- if (rom) {
- struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
- dev->rom_base_reg = rom;
- res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
- IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
- IORESOURCE_SIZEALIGN;
- __pci_read_base(dev, pci_bar_mem32, res, rom);
- }
-}
-
-void __devinit pci_read_bridge_bases(struct pci_bus *child)
-{
- struct pci_dev *dev = child->self;
- u8 io_base_lo, io_limit_lo;
- u16 mem_base_lo, mem_limit_lo;
- unsigned long base, limit;
- struct resource *res;
- int i;
-
- if (!dev) /* It's a host bus, nothing to read */
- return;
-
- if (dev->transparent) {
- dev_info(&dev->dev, "transparent bridge\n");
- for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
- child->resource[i] = child->parent->resource[i - 3];
- }
-
- res = child->resource[0];
- pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
- pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
- base = (io_base_lo & PCI_IO_RANGE_MASK) << 8;
- limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8;
-
- if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
- u16 io_base_hi, io_limit_hi;
- pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi);
- pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi);
- base |= (io_base_hi << 16);
- limit |= (io_limit_hi << 16);
- }
-
- if (base <= limit) {
- res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
- if (!res->start)
- res->start = base;
- if (!res->end)
- res->end = limit + 0xfff;
- dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res);
- }
-
- res = child->resource[1];
- pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
- pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
- base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
- limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
- if (base <= limit) {
- res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
- res->start = base;
- res->end = limit + 0xfffff;
- dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n",
- res);
- }
-
- res = child->resource[2];
- pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
- pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
- base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
- limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
-
- if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
- u32 mem_base_hi, mem_limit_hi;
- pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi);
- pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi);
-
- /*
- * Some bridges set the base > limit by default, and some
- * (broken) BIOSes do not initialize them. If we find
- * this, just assume they are not being used.
- */
- if (mem_base_hi <= mem_limit_hi) {
-#if BITS_PER_LONG == 64
- base |= ((long) mem_base_hi) << 32;
- limit |= ((long) mem_limit_hi) << 32;
-#else
- if (mem_base_hi || mem_limit_hi) {
- dev_err(&dev->dev, "can't handle 64-bit "
- "address space for bridge\n");
- return;
- }
-#endif
- }
- }
- if (base <= limit) {
- res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
- res->start = base;
- res->end = limit + 0xfffff;
- dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
- (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
- res);
- }
-}
-
-static struct pci_bus * pci_alloc_bus(void)
-{
- struct pci_bus *b;
-
- b = kzalloc(sizeof(*b), GFP_KERNEL);
- if (b) {
- INIT_LIST_HEAD(&b->node);
- INIT_LIST_HEAD(&b->children);
- INIT_LIST_HEAD(&b->devices);
- INIT_LIST_HEAD(&b->slots);
- }
- return b;
-}
-
-static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
- struct pci_dev *bridge, int busnr)
-{
- struct pci_bus *child;
- int i;
-
- /*
- * Allocate a new bus, and inherit stuff from the parent..
- */
- child = pci_alloc_bus();
- if (!child)
- return NULL;
-
- child->parent = parent;
- child->ops = parent->ops;
- child->sysdata = parent->sysdata;
- child->bus_flags = parent->bus_flags;
-
- /* initialize some portions of the bus device, but don't register it
- * now as the parent is not properly set up yet. This device will get
- * registered later in pci_bus_add_devices()
- */
- child->dev.class = &pcibus_class;
- dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
-
- /*
- * Set up the primary, secondary and subordinate
- * bus numbers.
- */
- child->number = child->secondary = busnr;
- child->primary = parent->secondary;
- child->subordinate = 0xff;
-
- if (!bridge)
- return child;
-
- child->self = bridge;
- child->bridge = get_device(&bridge->dev);
-
- /* Set up default resource pointers and names.. */
- for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
- child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
- child->resource[i]->name = child->name;
- }
- bridge->subordinate = child;
-
- return child;
-}
-
-struct pci_bus *__ref pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr)
-{
- struct pci_bus *child;
-
- child = pci_alloc_child_bus(parent, dev, busnr);
- if (child) {
- down_write(&pci_bus_sem);
- list_add_tail(&child->node, &parent->children);
- up_write(&pci_bus_sem);
- }
- return child;
-}
-
-static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
-{
- struct pci_bus *parent = child->parent;
-
-#ifndef DDE_LINUX
- /* Attempts to fix that up are really dangerous unless
- we're going to re-assign all bus numbers. */
- if (!pcibios_assign_all_busses())
- return;
-#endif
-
- while (parent->parent && parent->subordinate < max) {
- parent->subordinate = max;
- pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
- parent = parent->parent;
- }
-}
-
-/*
- * If it's a bridge, configure it and scan the bus behind it.
- * For CardBus bridges, we don't scan behind as the devices will
- * be handled by the bridge driver itself.
- *
- * We need to process bridges in two passes -- first we scan those
- * already configured by the BIOS and after we are done with all of
- * them, we proceed to assigning numbers to the remaining buses in
- * order to avoid overlaps between old and new bus numbers.
- */
-int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
-{
- struct pci_bus *child;
- int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
- u32 buses, i, j = 0;
- u16 bctl;
- int broken = 0;
-
- pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
-
- dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n",
- buses & 0xffffff, pass);
-
- /* Check if setup is sensible at all */
- if (!pass &&
- ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) {
- dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
- broken = 1;
- }
-
- /* Disable MasterAbortMode during probing to avoid reporting
- of bus errors (in some architectures) */
- pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl);
- pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
- bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
-
- if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) {
- unsigned int cmax, busnr;
- /*
- * Bus already configured by firmware, process it in the first
- * pass and just note the configuration.
- */
- if (pass)
- goto out;
- busnr = (buses >> 8) & 0xFF;
-
- /*
- * If we already got to this bus through a different bridge,
- * ignore it. This can happen with the i450NX chipset.
- */
- if (pci_find_bus(pci_domain_nr(bus), busnr)) {
- dev_info(&dev->dev, "bus %04x:%02x already known\n",
- pci_domain_nr(bus), busnr);
- goto out;
- }
-
- child = pci_add_new_bus(bus, dev, busnr);
- if (!child)
- goto out;
- child->primary = buses & 0xFF;
- child->subordinate = (buses >> 16) & 0xFF;
- child->bridge_ctl = bctl;
-
- cmax = pci_scan_child_bus(child);
- if (cmax > max)
- max = cmax;
- if (child->subordinate > max)
- max = child->subordinate;
- } else {
-#ifndef DDE_LINUX
- /*
- * We need to assign a number to this bus which we always
- * do in the second pass.
- */
- if (!pass) {
- if (pcibios_assign_all_busses() || broken)
- /* Temporarily disable forwarding of the
- configuration cycles on all bridges in
- this bus segment to avoid possible
- conflicts in the second pass between two
- bridges programmed with overlapping
- bus ranges. */
- pci_write_config_dword(dev, PCI_PRIMARY_BUS,
- buses & ~0xffffff);
- goto out;
- }
-#endif /* DDE_LINUX */
-
- /* Clear errors */
- pci_write_config_word(dev, PCI_STATUS, 0xffff);
-
- /* Prevent assigning a bus number that already exists.
- * This can happen when a bridge is hot-plugged */
- if (pci_find_bus(pci_domain_nr(bus), max+1))
- goto out;
- child = pci_add_new_bus(bus, dev, ++max);
- buses = (buses & 0xff000000)
- | ((unsigned int)(child->primary) << 0)
- | ((unsigned int)(child->secondary) << 8)
- | ((unsigned int)(child->subordinate) << 16);
-
- /*
- * yenta.c forces a secondary latency timer of 176.
- * Copy that behaviour here.
- */
- if (is_cardbus) {
- buses &= ~0xff000000;
- buses |= CARDBUS_LATENCY_TIMER << 24;
- }
-
- /*
- * We need to blast all three values with a single write.
- */
- pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
-
- if (!is_cardbus) {
- child->bridge_ctl = bctl;
- /*
- * Adjust subordinate busnr in parent buses.
- * We do this before scanning for children because
- * some devices may not be detected if the bios
- * was lazy.
- */
- pci_fixup_parent_subordinate_busnr(child, max);
- /* Now we can scan all subordinate buses... */
- max = pci_scan_child_bus(child);
- /*
- * now fix it up again since we have found
- * the real value of max.
- */
- pci_fixup_parent_subordinate_busnr(child, max);
- } else {
- /*
- * For CardBus bridges, we leave 4 bus numbers
- * as cards with a PCI-to-PCI bridge can be
- * inserted later.
- */
- for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) {
- struct pci_bus *parent = bus;
- if (pci_find_bus(pci_domain_nr(bus),
- max+i+1))
- break;
- while (parent->parent) {
- if ((!pcibios_assign_all_busses()) &&
- (parent->subordinate > max) &&
- (parent->subordinate <= max+i)) {
- j = 1;
- }
- parent = parent->parent;
- }
- if (j) {
- /*
- * Often, there are two cardbus bridges
- * -- try to leave one valid bus number
- * for each one.
- */
- i /= 2;
- break;
- }
- }
- max += i;
- pci_fixup_parent_subordinate_busnr(child, max);
- }
- /*
- * Set the subordinate bus number to its real value.
- */
- child->subordinate = max;
- pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
- }
-
- sprintf(child->name,
- (is_cardbus ? "PCI CardBus %04x:%02x" : "PCI Bus %04x:%02x"),
- pci_domain_nr(bus), child->number);
-
- /* Has only triggered on CardBus, fixup is in yenta_socket */
- while (bus->parent) {
- if ((child->subordinate > bus->subordinate) ||
- (child->number > bus->subordinate) ||
- (child->number < bus->number) ||
- (child->subordinate < bus->number)) {
- pr_debug("PCI: Bus #%02x (-#%02x) is %s "
- "hidden behind%s bridge #%02x (-#%02x)\n",
- child->number, child->subordinate,
- (bus->number > child->subordinate &&
- bus->subordinate < child->number) ?
- "wholly" : "partially",
- bus->self->transparent ? " transparent" : "",
- bus->number, bus->subordinate);
- }
- bus = bus->parent;
- }
-
-out:
- pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl);
-
- return max;
-}
-
-/*
- * Read interrupt line and base address registers.
- * The architecture-dependent code can tweak these, of course.
- */
-static void pci_read_irq(struct pci_dev *dev)
-{
- unsigned char irq;
-
- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
- dev->pin = irq;
- if (irq)
- pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
- dev->irq = irq;
-}
-
-#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
-
-/**
- * pci_setup_device - fill in class and map information of a device
- * @dev: the device structure to fill
- *
- * Initialize the device structure with information about the device's
- * vendor,class,memory and IO-space addresses,IRQ lines etc.
- * Called at initialisation of the PCI subsystem and by CardBus services.
- * Returns 0 on success and -1 if unknown type of device (not normal, bridge
- * or CardBus).
- */
-static int pci_setup_device(struct pci_dev * dev)
-{
- u32 class;
-
- dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
- dev->bus->number, PCI_SLOT(dev->devfn),
- PCI_FUNC(dev->devfn));
-
- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
- dev->revision = class & 0xff;
- class >>= 8; /* upper 3 bytes */
- dev->class = class;
- class >>= 8;
-
- dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n",
- dev->vendor, dev->device, class, dev->hdr_type);
-
- /* "Unknown power state" */
- dev->current_state = PCI_UNKNOWN;
-
- /* Early fixups, before probing the BARs */
- pci_fixup_device(pci_fixup_early, dev);
- class = dev->class >> 8;
-
- switch (dev->hdr_type) { /* header type */
- case PCI_HEADER_TYPE_NORMAL: /* standard header */
- if (class == PCI_CLASS_BRIDGE_PCI)
- goto bad;
- pci_read_irq(dev);
- pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
- pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
- pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
-
- /*
- * Do the ugly legacy mode stuff here rather than broken chip
- * quirk code. Legacy mode ATA controllers have fixed
- * addresses. These are not always echoed in BAR0-3, and
- * BAR0-3 in a few cases contain junk!
- */
- if (class == PCI_CLASS_STORAGE_IDE) {
- u8 progif;
- pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
- if ((progif & 1) == 0) {
- dev->resource[0].start = 0x1F0;
- dev->resource[0].end = 0x1F7;
- dev->resource[0].flags = LEGACY_IO_RESOURCE;
- dev->resource[1].start = 0x3F6;
- dev->resource[1].end = 0x3F6;
- dev->resource[1].flags = LEGACY_IO_RESOURCE;
- }
- if ((progif & 4) == 0) {
- dev->resource[2].start = 0x170;
- dev->resource[2].end = 0x177;
- dev->resource[2].flags = LEGACY_IO_RESOURCE;
- dev->resource[3].start = 0x376;
- dev->resource[3].end = 0x376;
- dev->resource[3].flags = LEGACY_IO_RESOURCE;
- }
- }
- break;
-
- case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
- if (class != PCI_CLASS_BRIDGE_PCI)
- goto bad;
- /* The PCI-to-PCI bridge spec requires that subtractive
- decoding (i.e. transparent) bridge must have programming
- interface code of 0x01. */
- pci_read_irq(dev);
- dev->transparent = ((dev->class & 0xff) == 1);
- pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
- break;
-
- case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
- if (class != PCI_CLASS_BRIDGE_CARDBUS)
- goto bad;
- pci_read_irq(dev);
- pci_read_bases(dev, 1, 0);
- pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
- pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
- break;
-
- default: /* unknown header */
- dev_err(&dev->dev, "unknown header type %02x, "
- "ignoring device\n", dev->hdr_type);
- return -1;
-
- bad:
- dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
- "type %02x)\n", class, dev->hdr_type);
- dev->class = PCI_CLASS_NOT_DEFINED;
- }
-
- /* We found a fine healthy device, go go go... */
- return 0;
-}
-
-static void pci_release_capabilities(struct pci_dev *dev)
-{
- pci_vpd_release(dev);
-}
-
-/**
- * pci_release_dev - free a pci device structure when all users of it are finished.
- * @dev: device that's been disconnected
- *
- * Will be called only by the device core when all users of this pci device are
- * done.
- */
-static void pci_release_dev(struct device *dev)
-{
- struct pci_dev *pci_dev;
-
- pci_dev = to_pci_dev(dev);
- pci_release_capabilities(pci_dev);
- kfree(pci_dev);
-}
-
-static void set_pcie_port_type(struct pci_dev *pdev)
-{
- int pos;
- u16 reg16;
-
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (!pos)
- return;
- pdev->is_pcie = 1;
- pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
- pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
-}
-
-/**
- * pci_cfg_space_size - get the configuration space size of the PCI device.
- * @dev: PCI device
- *
- * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
- * have 4096 bytes. Even if the device is capable, that doesn't mean we can
- * access it. Maybe we don't have a way to generate extended config space
- * accesses, or the device is behind a reverse Express bridge. So we try
- * reading the dword at 0x100 which must either be 0 or a valid extended
- * capability header.
- */
-int pci_cfg_space_size_ext(struct pci_dev *dev)
-{
- u32 status;
- int pos = PCI_CFG_SPACE_SIZE;
-
- if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
- goto fail;
- if (status == 0xffffffff)
- goto fail;
-
- return PCI_CFG_SPACE_EXP_SIZE;
-
- fail:
- return PCI_CFG_SPACE_SIZE;
-}
-
-int pci_cfg_space_size(struct pci_dev *dev)
-{
- int pos;
- u32 status;
-
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!pos) {
- pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!pos)
- goto fail;
-
- pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
- if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)))
- goto fail;
- }
-
- return pci_cfg_space_size_ext(dev);
-
- fail:
- return PCI_CFG_SPACE_SIZE;
-}
-
-static void pci_release_bus_bridge_dev(struct device *dev)
-{
- kfree(dev);
-}
-
-struct pci_dev *alloc_pci_dev(void)
-{
- struct pci_dev *dev;
-
- dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
- if (!dev)
- return NULL;
-
- INIT_LIST_HEAD(&dev->bus_list);
-
- return dev;
-}
-EXPORT_SYMBOL(alloc_pci_dev);
-
-/*
- * Read the config data for a PCI device, sanity-check it
- * and fill in the dev structure...
- */
-static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
-{
- struct pci_dev *dev;
- struct pci_slot *slot;
- u32 l;
- u8 hdr_type;
- int delay = 1;
-
- if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
- return NULL;
-
- /* some broken boards return 0 or ~0 if a slot is empty: */
- if (l == 0xffffffff || l == 0x00000000 ||
- l == 0x0000ffff || l == 0xffff0000)
- return NULL;
-
- /* Configuration request Retry Status */
- while (l == 0xffff0001) {
- msleep(delay);
- delay *= 2;
- if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
- return NULL;
- /* Card hasn't responded in 60 seconds? Must be stuck. */
- if (delay > 60 * 1000) {
- printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not "
- "responding\n", pci_domain_nr(bus),
- bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn));
- return NULL;
- }
- }
-
- if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
- return NULL;
-
- dev = alloc_pci_dev();
- if (!dev)
- return NULL;
-
- dev->bus = bus;
- dev->sysdata = bus->sysdata;
- dev->dev.parent = bus->bridge;
- dev->dev.bus = &pci_bus_type;
- dev->devfn = devfn;
- dev->hdr_type = hdr_type & 0x7f;
- dev->multifunction = !!(hdr_type & 0x80);
- dev->vendor = l & 0xffff;
- dev->device = (l >> 16) & 0xffff;
- dev->cfg_size = pci_cfg_space_size(dev);
- dev->error_state = pci_channel_io_normal;
- set_pcie_port_type(dev);
-
- list_for_each_entry(slot, &bus->slots, list)
- if (PCI_SLOT(devfn) == slot->number)
- dev->slot = slot;
-
- /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
- set this higher, assuming the system even supports it. */
- dev->dma_mask = 0xffffffff;
- if (pci_setup_device(dev) < 0) {
- kfree(dev);
- return NULL;
- }
-
- return dev;
-}
-
-static void pci_init_capabilities(struct pci_dev *dev)
-{
- /* MSI/MSI-X list */
- pci_msi_init_pci_dev(dev);
-
- /* Buffers for saving PCIe and PCI-X capabilities */
- pci_allocate_cap_save_buffers(dev);
-
- /* Power Management */
- pci_pm_init(dev);
- platform_pci_wakeup_init(dev);
-
- /* Vital Product Data */
- pci_vpd_pci22_init(dev);
-
- /* Alternative Routing-ID Forwarding */
- pci_enable_ari(dev);
-}
-
-void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
-{
- device_initialize(&dev->dev);
- dev->dev.release = pci_release_dev;
- pci_dev_get(dev);
-
- dev->dev.dma_mask = &dev->dma_mask;
- dev->dev.dma_parms = &dev->dma_parms;
- dev->dev.coherent_dma_mask = 0xffffffffull;
-
- pci_set_dma_max_seg_size(dev, 65536);
- pci_set_dma_seg_boundary(dev, 0xffffffff);
-
- /* Fix up broken headers */
- pci_fixup_device(pci_fixup_header, dev);
-
- /* Initialize various capabilities */
- pci_init_capabilities(dev);
-
- /*
- * Add the device to our list of discovered devices
- * and the bus list for fixup functions, etc.
- */
- down_write(&pci_bus_sem);
- list_add_tail(&dev->bus_list, &bus->devices);
- up_write(&pci_bus_sem);
-}
-
-struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
-{
- struct pci_dev *dev;
-
- dev = pci_scan_device(bus, devfn);
- if (!dev)
- return NULL;
-
- pci_device_add(dev, bus);
-
- return dev;
-}
-EXPORT_SYMBOL(pci_scan_single_device);
-
-/**
- * pci_scan_slot - scan a PCI slot on a bus for devices.
- * @bus: PCI bus to scan
- * @devfn: slot number to scan (must have zero function.)
- *
- * Scan a PCI slot on the specified PCI bus for devices, adding
- * discovered devices to the @bus->devices list. New devices
- * will not have is_added set.
- */
-int pci_scan_slot(struct pci_bus *bus, int devfn)
-{
- int func, nr = 0;
- int scan_all_fns;
-
- scan_all_fns = pcibios_scan_all_fns(bus, devfn);
-
- for (func = 0; func < 8; func++, devfn++) {
- struct pci_dev *dev;
-
- dev = pci_scan_single_device(bus, devfn);
- if (dev) {
- nr++;
-
- /*
- * If this is a single function device,
- * don't scan past the first function.
- */
- if (!dev->multifunction) {
- if (func > 0) {
- dev->multifunction = 1;
- } else {
- break;
- }
- }
- } else {
- if (func == 0 && !scan_all_fns)
- break;
- }
- }
-
- /* only one slot has pcie device */
- if (bus->self && nr)
- pcie_aspm_init_link_state(bus->self);
-
- return nr;
-}
-
-unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
-{
- unsigned int devfn, pass, max = bus->secondary;
- struct pci_dev *dev;
-
- pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
-
- /* Go find them, Rover! */
- for (devfn = 0; devfn < 0x100; devfn += 8)
- pci_scan_slot(bus, devfn);
-
-#ifndef DDE_LINUX
- /*
- * After performing arch-dependent fixup of the bus, look behind
- * all PCI-to-PCI bridges on this bus.
- */
- pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
- pcibios_fixup_bus(bus);
- for (pass=0; pass < 2; pass++)
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
- dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
- max = pci_scan_bridge(bus, dev, max, pass);
- }
-#endif
-
- /*
- * We've scanned the bus and so we know all about what's on
- * the other side of any bridges that may be on this bus plus
- * any devices.
- *
- * Return how far we've got finding sub-buses.
- */
- pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n",
- pci_domain_nr(bus), bus->number, max);
- return max;
-}
-
-void __attribute__((weak)) set_pci_bus_resources_arch_default(struct pci_bus *b)
-{
-}
-
-struct pci_bus * pci_create_bus(struct device *parent,
- int bus, struct pci_ops *ops, void *sysdata)
-{
- int error;
- struct pci_bus *b;
- struct device *dev;
-
- b = pci_alloc_bus();
- if (!b)
- return NULL;
-
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev){
- kfree(b);
- return NULL;
- }
-
- b->sysdata = sysdata;
- b->ops = ops;
-
- if (pci_find_bus(pci_domain_nr(b), bus)) {
- /* If we already got to this bus through a different bridge, ignore it */
- pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
- goto err_out;
- }
-
- down_write(&pci_bus_sem);
- list_add_tail(&b->node, &pci_root_buses);
- up_write(&pci_bus_sem);
-
- memset(dev, 0, sizeof(*dev));
- dev->parent = parent;
- dev->release = pci_release_bus_bridge_dev;
- dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus);
- error = device_register(dev);
- if (error)
- goto dev_reg_err;
- b->bridge = get_device(dev);
-
- if (!parent)
- set_dev_node(b->bridge, pcibus_to_node(b));
-
- b->dev.class = &pcibus_class;
- b->dev.parent = b->bridge;
- dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);
- error = device_register(&b->dev);
- if (error)
- goto class_dev_reg_err;
- error = device_create_file(&b->dev, &dev_attr_cpuaffinity);
- if (error)
- goto dev_create_file_err;
-
- /* Create legacy_io and legacy_mem files for this bus */
- pci_create_legacy_files(b);
-
- b->number = b->secondary = bus;
- b->resource[0] = &ioport_resource;
- b->resource[1] = &iomem_resource;
-
- set_pci_bus_resources_arch_default(b);
-
- return b;
-
-dev_create_file_err:
- device_unregister(&b->dev);
-class_dev_reg_err:
- device_unregister(dev);
-dev_reg_err:
- down_write(&pci_bus_sem);
- list_del(&b->node);
- up_write(&pci_bus_sem);
-err_out:
- kfree(dev);
- kfree(b);
- return NULL;
-}
-
-struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
- int bus, struct pci_ops *ops, void *sysdata)
-{
- struct pci_bus *b;
-
- b = pci_create_bus(parent, bus, ops, sysdata);
- if (b)
- b->subordinate = pci_scan_child_bus(b);
- return b;
-}
-EXPORT_SYMBOL(pci_scan_bus_parented);
-
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pci_add_new_bus);
-EXPORT_SYMBOL(pci_scan_slot);
-EXPORT_SYMBOL(pci_scan_bridge);
-EXPORT_SYMBOL_GPL(pci_scan_child_bus);
-#endif
-
-static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b)
-{
- const struct pci_dev *a = to_pci_dev(d_a);
- const struct pci_dev *b = to_pci_dev(d_b);
-
- if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1;
- else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1;
-
- if (a->bus->number < b->bus->number) return -1;
- else if (a->bus->number > b->bus->number) return 1;
-
- if (a->devfn < b->devfn) return -1;
- else if (a->devfn > b->devfn) return 1;
-
- return 0;
-}
-
-void __init pci_sort_breadthfirst(void)
-{
- bus_sort_breadthfirst(&pci_bus_type, &pci_sort_bf_cmp);
-}