diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:07:53 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:07:53 +0000 |
commit | 4fbe7358c7747a9165f776eb19addbb9baf7def2 (patch) | |
tree | bc7076b4f6d10c2cc2942539bb666e50f0b66954 /libdde_linux26/contrib/drivers/pci | |
parent | 21adb5284111190057db245cfc2b54091920c373 (diff) |
rename libdde_linux26 into libdde-linux26 to make dpkg-source happy
Diffstat (limited to 'libdde_linux26/contrib/drivers/pci')
-rw-r--r-- | libdde_linux26/contrib/drivers/pci/access.c | 410 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/pci/bus.c | 241 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/pci/hotplug-pci.c | 20 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/pci/pci.h | 198 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/pci/search.c | 419 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/pci/setup-bus.c | 581 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/pci/setup-res.c | 292 |
7 files changed, 0 insertions, 2161 deletions
diff --git a/libdde_linux26/contrib/drivers/pci/access.c b/libdde_linux26/contrib/drivers/pci/access.c deleted file mode 100644 index 9d05aea2..00000000 --- a/libdde_linux26/contrib/drivers/pci/access.c +++ /dev/null @@ -1,410 +0,0 @@ -#include <linux/delay.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/ioport.h> -#include <linux/wait.h> - -#include "pci.h" -#include <ddekit/timer.h> - -/* - * This interrupt-safe spinlock protects all accesses to PCI - * configuration space. - */ - -static DEFINE_SPINLOCK(pci_lock); - -/* - * Wrappers for all PCI configuration access functions. They just check - * alignment, do locking and call the low-level functions pointed to - * by pci_dev->ops. - */ - -#define PCI_byte_BAD 0 -#define PCI_word_BAD (pos & 1) -#define PCI_dword_BAD (pos & 3) - -#define PCI_OP_READ(size,type,len) \ -int pci_bus_read_config_##size \ - (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \ -{ \ - int res; \ - unsigned long flags; \ - u32 data = 0; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irqsave(&pci_lock, flags); \ - res = bus->ops->read(bus, devfn, pos, len, &data); \ - *value = (type)data; \ - spin_unlock_irqrestore(&pci_lock, flags); \ - return res; \ -} - -#define PCI_OP_WRITE(size,type,len) \ -int pci_bus_write_config_##size \ - (struct pci_bus *bus, unsigned int devfn, int pos, type value) \ -{ \ - int res; \ - unsigned long flags; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irqsave(&pci_lock, flags); \ - res = bus->ops->write(bus, devfn, pos, len, value); \ - spin_unlock_irqrestore(&pci_lock, flags); \ - return res; \ -} - -PCI_OP_READ(byte, u8, 1) -PCI_OP_READ(word, u16, 2) -PCI_OP_READ(dword, u32, 4) -PCI_OP_WRITE(byte, u8, 1) -PCI_OP_WRITE(word, u16, 2) -PCI_OP_WRITE(dword, u32, 4) - -EXPORT_SYMBOL(pci_bus_read_config_byte); -EXPORT_SYMBOL(pci_bus_read_config_word); -EXPORT_SYMBOL(pci_bus_read_config_dword); -EXPORT_SYMBOL(pci_bus_write_config_byte); -EXPORT_SYMBOL(pci_bus_write_config_word); -EXPORT_SYMBOL(pci_bus_write_config_dword); - - -/** - * pci_read_vpd - Read one entry from Vital Product Data - * @dev: pci device struct - * @pos: offset in vpd space - * @count: number of bytes to read - * @buf: pointer to where to store result - * - */ -ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf) -{ - if (!dev->vpd || !dev->vpd->ops) - return -ENODEV; - return dev->vpd->ops->read(dev, pos, count, buf); -} -EXPORT_SYMBOL(pci_read_vpd); - -/** - * pci_write_vpd - Write entry to Vital Product Data - * @dev: pci device struct - * @pos: offset in vpd space - * @count: number of bytes to read - * @val: value to write - * - */ -ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf) -{ - if (!dev->vpd || !dev->vpd->ops) - return -ENODEV; - return dev->vpd->ops->write(dev, pos, count, buf); -} -EXPORT_SYMBOL(pci_write_vpd); - -/* - * The following routines are to prevent the user from accessing PCI config - * space when it's unsafe to do so. Some devices require this during BIST and - * we're required to prevent it during D-state transitions. - * - * We have a bit per device to indicate it's blocked and a global wait queue - * for callers to sleep on until devices are unblocked. - */ -static DECLARE_WAIT_QUEUE_HEAD(pci_ucfg_wait); - -static noinline void pci_wait_ucfg(struct pci_dev *dev) -{ - DECLARE_WAITQUEUE(wait, current); - - __add_wait_queue(&pci_ucfg_wait, &wait); - do { - set_current_state(TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&pci_lock); - schedule(); - spin_lock_irq(&pci_lock); - } while (dev->block_ucfg_access); - __remove_wait_queue(&pci_ucfg_wait, &wait); -} - -#define PCI_USER_READ_CONFIG(size,type) \ -int pci_user_read_config_##size \ - (struct pci_dev *dev, int pos, type *val) \ -{ \ - int ret = 0; \ - u32 data = -1; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ - if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ - ret = dev->bus->ops->read(dev->bus, dev->devfn, \ - pos, sizeof(type), &data); \ - spin_unlock_irq(&pci_lock); \ - *val = (type)data; \ - return ret; \ -} - -#define PCI_USER_WRITE_CONFIG(size,type) \ -int pci_user_write_config_##size \ - (struct pci_dev *dev, int pos, type val) \ -{ \ - int ret = -EIO; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ - if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ - ret = dev->bus->ops->write(dev->bus, dev->devfn, \ - pos, sizeof(type), val); \ - spin_unlock_irq(&pci_lock); \ - return ret; \ -} - -PCI_USER_READ_CONFIG(byte, u8) -PCI_USER_READ_CONFIG(word, u16) -PCI_USER_READ_CONFIG(dword, u32) -PCI_USER_WRITE_CONFIG(byte, u8) -PCI_USER_WRITE_CONFIG(word, u16) -PCI_USER_WRITE_CONFIG(dword, u32) - -/* VPD access through PCI 2.2+ VPD capability */ - -#define PCI_VPD_PCI22_SIZE (PCI_VPD_ADDR_MASK + 1) - -struct pci_vpd_pci22 { - struct pci_vpd base; - struct mutex lock; - u16 flag; - bool busy; - u8 cap; -}; - -/* - * Wait for last operation to complete. - * This code has to spin since there is no other notification from the PCI - * hardware. Since the VPD is often implemented by serial attachment to an - * EEPROM, it may take many milliseconds to complete. - */ -static int pci_vpd_pci22_wait(struct pci_dev *dev) -{ - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); - unsigned long timeout = jiffies + HZ/20 + 2; - u16 status; - int ret; - - if (!vpd->busy) - return 0; - - for (;;) { - ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, - &status); - if (ret) - return ret; - - if ((status & PCI_VPD_ADDR_F) == vpd->flag) { - vpd->busy = false; - return 0; - } - - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - if (fatal_signal_pending(current)) - return -EINTR; - if (!cond_resched()) - udelay(10); - } -} - -static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count, - void *arg) -{ - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); - int ret; - loff_t end = pos + count; - u8 *buf = arg; - - if (pos < 0 || pos > vpd->base.len || end > vpd->base.len) - return -EINVAL; - - if (mutex_lock_killable(&vpd->lock)) - return -EINTR; - - ret = pci_vpd_pci22_wait(dev); - if (ret < 0) - goto out; - - while (pos < end) { - u32 val; - unsigned int i, skip; - - ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, - pos & ~3); - if (ret < 0) - break; - vpd->busy = true; - vpd->flag = PCI_VPD_ADDR_F; - ret = pci_vpd_pci22_wait(dev); - if (ret < 0) - break; - - ret = pci_user_read_config_dword(dev, vpd->cap + PCI_VPD_DATA, &val); - if (ret < 0) - break; - - skip = pos & 3; - for (i = 0; i < sizeof(u32); i++) { - if (i >= skip) { - *buf++ = val; - if (++pos == end) - break; - } - val >>= 8; - } - } -out: - mutex_unlock(&vpd->lock); - return ret ? ret : count; -} - -static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count, - const void *arg) -{ - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); - const u8 *buf = arg; - loff_t end = pos + count; - int ret = 0; - - if (pos < 0 || (pos & 3) || (count & 3) || end > vpd->base.len) - return -EINVAL; - - if (mutex_lock_killable(&vpd->lock)) - return -EINTR; - - ret = pci_vpd_pci22_wait(dev); - if (ret < 0) - goto out; - - while (pos < end) { - u32 val; - - val = *buf++; - val |= *buf++ << 8; - val |= *buf++ << 16; - val |= *buf++ << 24; - - ret = pci_user_write_config_dword(dev, vpd->cap + PCI_VPD_DATA, val); - if (ret < 0) - break; - ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, - pos | PCI_VPD_ADDR_F); - if (ret < 0) - break; - - vpd->busy = true; - vpd->flag = 0; - ret = pci_vpd_pci22_wait(dev); - - pos += sizeof(u32); - } -out: - mutex_unlock(&vpd->lock); - return ret ? ret : count; -} - -static void pci_vpd_pci22_release(struct pci_dev *dev) -{ - kfree(container_of(dev->vpd, struct pci_vpd_pci22, base)); -} - -static const struct pci_vpd_ops pci_vpd_pci22_ops = { - .read = pci_vpd_pci22_read, - .write = pci_vpd_pci22_write, - .release = pci_vpd_pci22_release, -}; - -int pci_vpd_pci22_init(struct pci_dev *dev) -{ - struct pci_vpd_pci22 *vpd; - u8 cap; - - cap = pci_find_capability(dev, PCI_CAP_ID_VPD); - if (!cap) - return -ENODEV; - vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); - if (!vpd) - return -ENOMEM; - - vpd->base.len = PCI_VPD_PCI22_SIZE; - vpd->base.ops = &pci_vpd_pci22_ops; - mutex_init(&vpd->lock); - vpd->cap = cap; - vpd->busy = false; - dev->vpd = &vpd->base; - return 0; -} - -/** - * pci_vpd_truncate - Set available Vital Product Data size - * @dev: pci device struct - * @size: available memory in bytes - * - * Adjust size of available VPD area. - */ -int pci_vpd_truncate(struct pci_dev *dev, size_t size) -{ - if (!dev->vpd) - return -EINVAL; - - /* limited by the access method */ - if (size > dev->vpd->len) - return -EINVAL; - - dev->vpd->len = size; - dev->vpd->attr->size = size; - - return 0; -} -EXPORT_SYMBOL(pci_vpd_truncate); - -/** - * pci_block_user_cfg_access - Block userspace PCI config reads/writes - * @dev: pci device struct - * - * When user access is blocked, any reads or writes to config space will - * sleep until access is unblocked again. We don't allow nesting of - * block/unblock calls. - */ -void pci_block_user_cfg_access(struct pci_dev *dev) -{ - unsigned long flags; - int was_blocked; - - spin_lock_irqsave(&pci_lock, flags); - was_blocked = dev->block_ucfg_access; - dev->block_ucfg_access = 1; - spin_unlock_irqrestore(&pci_lock, flags); - - /* If we BUG() inside the pci_lock, we're guaranteed to hose - * the machine */ - BUG_ON(was_blocked); -} -EXPORT_SYMBOL_GPL(pci_block_user_cfg_access); - -/** - * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes - * @dev: pci device struct - * - * This function allows userspace PCI config accesses to resume. - */ -void pci_unblock_user_cfg_access(struct pci_dev *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&pci_lock, flags); - - /* This indicates a problem in the caller, but we don't need - * to kill them, unlike a double-block above. */ - WARN_ON(!dev->block_ucfg_access); - - dev->block_ucfg_access = 0; - wake_up_all(&pci_ucfg_wait); - spin_unlock_irqrestore(&pci_lock, flags); -} -EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); diff --git a/libdde_linux26/contrib/drivers/pci/bus.c b/libdde_linux26/contrib/drivers/pci/bus.c deleted file mode 100644 index 52b54f05..00000000 --- a/libdde_linux26/contrib/drivers/pci/bus.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * drivers/pci/bus.c - * - * From setup-res.c, by: - * Dave Rusling (david.rusling@reo.mts.dec.com) - * David Mosberger (davidm@cs.arizona.edu) - * David Miller (davem@redhat.com) - * Ivan Kokshaysky (ink@jurassic.park.msu.ru) - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/proc_fs.h> -#include <linux/init.h> - -#include "pci.h" - -/** - * pci_bus_alloc_resource - allocate a resource from a parent bus - * @bus: PCI bus - * @res: resource to allocate - * @size: size of resource to allocate - * @align: alignment of resource to allocate - * @min: minimum /proc/iomem address to allocate - * @type_mask: IORESOURCE_* type flags - * @alignf: resource alignment function - * @alignf_data: data argument for resource alignment function - * - * Given the PCI bus a device resides on, the size, minimum address, - * alignment and type, try to find an acceptable resource allocation - * for a specific device resource. - */ -int -pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, - resource_size_t size, resource_size_t align, - resource_size_t min, unsigned int type_mask, - void (*alignf)(void *, struct resource *, resource_size_t, - resource_size_t), - void *alignf_data) -{ - int i, ret = -ENOMEM; - - type_mask |= IORESOURCE_IO | IORESOURCE_MEM; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *r = bus->resource[i]; - if (!r) - continue; - - /* type_mask must match */ - if ((res->flags ^ r->flags) & type_mask) - continue; - - /* We cannot allocate a non-prefetching resource - from a pre-fetching area */ - if ((r->flags & IORESOURCE_PREFETCH) && - !(res->flags & IORESOURCE_PREFETCH)) - continue; - - /* Ok, try it out.. */ - ret = allocate_resource(r, res, size, - r->start ? : min, - -1, align, - alignf, alignf_data); - if (ret == 0) - break; - } - return ret; -} - -/** - * pci_bus_add_device - add a single device - * @dev: device to add - * - * This adds a single pci device to the global - * device list and adds sysfs and procfs entries - */ -int pci_bus_add_device(struct pci_dev *dev) -{ - int retval; - retval = device_add(&dev->dev); - if (retval) - return retval; - - dev->is_added = 1; - pci_proc_attach_device(dev); - pci_create_sysfs_dev_files(dev); - return 0; -} - -/** - * pci_bus_add_child - add a child bus - * @bus: bus to add - * - * This adds sysfs entries for a single bus - */ -int pci_bus_add_child(struct pci_bus *bus) -{ - int retval; - - if (bus->bridge) - bus->dev.parent = bus->bridge; - - retval = device_register(&bus->dev); - if (retval) - return retval; - - bus->is_added = 1; - - retval = device_create_file(&bus->dev, &dev_attr_cpuaffinity); - if (retval) - return retval; - - retval = device_create_file(&bus->dev, &dev_attr_cpulistaffinity); - - /* Create legacy_io and legacy_mem files for this bus */ - pci_create_legacy_files(bus); - - return retval; -} - -/** - * pci_bus_add_devices - insert newly discovered PCI devices - * @bus: bus to check for new devices - * - * Add newly discovered PCI devices (which are on the bus->devices - * list) to the global PCI device list, add the sysfs and procfs - * entries. Where a bridge is found, add the discovered bus to - * the parents list of child buses, and recurse (breadth-first - * to be compatible with 2.4) - * - * Call hotplug for each new devices. - */ -void pci_bus_add_devices(struct pci_bus *bus) -{ - struct pci_dev *dev; - struct pci_bus *child; - int retval; - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* Skip already-added devices */ - if (dev->is_added) - continue; - retval = pci_bus_add_device(dev); - if (retval) - dev_err(&dev->dev, "Error adding device, continuing\n"); - } - - list_for_each_entry(dev, &bus->devices, bus_list) { - BUG_ON(!dev->is_added); - - child = dev->subordinate; - /* - * If there is an unattached subordinate bus, attach - * it and then scan for unattached PCI devices. - */ - if (!child) - continue; - if (list_empty(&child->node)) { - down_write(&pci_bus_sem); - list_add_tail(&child->node, &dev->bus->children); - up_write(&pci_bus_sem); - } - pci_bus_add_devices(child); - - /* - * register the bus with sysfs as the parent is now - * properly registered. - */ - if (child->is_added) - continue; - retval = pci_bus_add_child(child); - if (retval) - dev_err(&dev->dev, "Error adding bus, continuing\n"); - } -} - -void pci_enable_bridges(struct pci_bus *bus) -{ - struct pci_dev *dev; - int retval; - - list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->subordinate) { - retval = pci_enable_device(dev); - pci_set_master(dev); - pci_enable_bridges(dev->subordinate); - } - } -} - -/** pci_walk_bus - walk devices on/under bus, calling callback. - * @top bus whose devices should be walked - * @cb callback to be called for each device found - * @userdata arbitrary pointer to be passed to callback. - * - * Walk the given bus, including any bridged devices - * on buses under this bus. Call the provided callback - * on each device found. - */ -void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), - void *userdata) -{ - struct pci_dev *dev; - struct pci_bus *bus; - struct list_head *next; - - bus = top; - down_read(&pci_bus_sem); - next = top->devices.next; - for (;;) { - if (next == &bus->devices) { - /* end of this bus, go up or finish */ - if (bus == top) - break; - next = bus->self->bus_list.next; - bus = bus->self->bus; - continue; - } - dev = list_entry(next, struct pci_dev, bus_list); - if (dev->subordinate) { - /* this is a pci-pci bridge, do its devices next */ - next = dev->subordinate->devices.next; - bus = dev->subordinate; - } else - next = dev->bus_list.next; - - /* Run device routines with the device locked */ - down(&dev->dev.sem); - cb(dev, userdata); - up(&dev->dev.sem); - } - up_read(&pci_bus_sem); -} - -EXPORT_SYMBOL(pci_bus_alloc_resource); -EXPORT_SYMBOL_GPL(pci_bus_add_device); -EXPORT_SYMBOL(pci_bus_add_devices); -EXPORT_SYMBOL(pci_enable_bridges); diff --git a/libdde_linux26/contrib/drivers/pci/hotplug-pci.c b/libdde_linux26/contrib/drivers/pci/hotplug-pci.c deleted file mode 100644 index 4d4a6447..00000000 --- a/libdde_linux26/contrib/drivers/pci/hotplug-pci.c +++ /dev/null @@ -1,20 +0,0 @@ -/* Core PCI functionality used only by PCI hotplug */ - -#include <linux/pci.h> -#include "pci.h" - - -unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) -{ - unsigned int max; - - max = pci_scan_child_bus(bus); - - /* - * Make the discovered devices available. - */ - pci_bus_add_devices(bus); - - return max; -} -EXPORT_SYMBOL(pci_do_scan_bus); diff --git a/libdde_linux26/contrib/drivers/pci/pci.h b/libdde_linux26/contrib/drivers/pci/pci.h deleted file mode 100644 index 07c0aa52..00000000 --- a/libdde_linux26/contrib/drivers/pci/pci.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef DRIVERS_PCI_H -#define DRIVERS_PCI_H - -#define PCI_CFG_SPACE_SIZE 256 -#define PCI_CFG_SPACE_EXP_SIZE 4096 - -/* Functions internal to the PCI core code */ - -extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); -extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); -extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); -extern void pci_cleanup_rom(struct pci_dev *dev); -#ifdef HAVE_PCI_MMAP -extern int pci_mmap_fits(struct pci_dev *pdev, int resno, - struct vm_area_struct *vma); -#endif - -/** - * struct pci_platform_pm_ops - Firmware PM callbacks - * - * @is_manageable: returns 'true' if given device is power manageable by the - * platform firmware - * - * @set_state: invokes the platform firmware to set the device's power state - * - * @choose_state: returns PCI power state of given device preferred by the - * platform; to be used during system-wide transitions from a - * sleeping state to the working state and vice versa - * - * @can_wakeup: returns 'true' if given device is capable of waking up the - * system from a sleeping state - * - * @sleep_wake: enables/disables the system wake up capability of given device - * - * If given platform is generally capable of power managing PCI devices, all of - * these callbacks are mandatory. - */ -struct pci_platform_pm_ops { - bool (*is_manageable)(struct pci_dev *dev); - int (*set_state)(struct pci_dev *dev, pci_power_t state); - pci_power_t (*choose_state)(struct pci_dev *dev); - bool (*can_wakeup)(struct pci_dev *dev); - int (*sleep_wake)(struct pci_dev *dev, bool enable); -}; - -extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); -extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); -extern void pci_disable_enabled_device(struct pci_dev *dev); -extern void pci_pm_init(struct pci_dev *dev); -extern void platform_pci_wakeup_init(struct pci_dev *dev); -extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); -extern int pci_restore_standard_config(struct pci_dev *dev); - -static inline bool pci_is_bridge(struct pci_dev *pci_dev) -{ - return !!(pci_dev->subordinate); -} - -extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); -extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); -extern int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val); -extern int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val); -extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); -extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); - -struct pci_vpd_ops { - ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); - ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); - void (*release)(struct pci_dev *dev); -}; - -struct pci_vpd { - unsigned int len; - const struct pci_vpd_ops *ops; - struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ -}; - -extern int pci_vpd_pci22_init(struct pci_dev *dev); -static inline void pci_vpd_release(struct pci_dev *dev) -{ - if (dev->vpd) - dev->vpd->ops->release(dev); -} - -/* PCI /proc functions */ -#ifdef CONFIG_PROC_FS -extern int pci_proc_attach_device(struct pci_dev *dev); -extern int pci_proc_detach_device(struct pci_dev *dev); -extern int pci_proc_detach_bus(struct pci_bus *bus); -#else -static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } -static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } -static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } -#endif - -/* Functions for PCI Hotplug drivers to use */ -extern unsigned int pci_do_scan_bus(struct pci_bus *bus); - -#ifdef HAVE_PCI_LEGACY -extern void pci_create_legacy_files(struct pci_bus *bus); -extern void pci_remove_legacy_files(struct pci_bus *bus); -#else -static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } -static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } -#endif - -/* Lock for read/write access to pci device and bus lists */ -extern struct rw_semaphore pci_bus_sem; - -extern unsigned int pci_pm_d3_delay; - -#ifdef CONFIG_PCI_MSI -void pci_no_msi(void); -extern void pci_msi_init_pci_dev(struct pci_dev *dev); -#else -static inline void pci_no_msi(void) { } -static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } -#endif - -#ifdef CONFIG_PCIEAER -void pci_no_aer(void); -#else -static inline void pci_no_aer(void) { } -#endif - -static inline int pci_no_d1d2(struct pci_dev *dev) -{ - unsigned int parent_dstates = 0; - - if (dev->bus->self) - parent_dstates = dev->bus->self->no_d1d2; - return (dev->no_d1d2 || parent_dstates); - -} -extern int pcie_mch_quirk; -extern struct device_attribute pci_dev_attrs[]; -extern struct device_attribute dev_attr_cpuaffinity; -extern struct device_attribute dev_attr_cpulistaffinity; - -/** - * pci_match_one_device - Tell if a PCI device structure has a matching - * PCI device id structure - * @id: single PCI device id structure to match - * @dev: the PCI device structure to match against - * - * Returns the matching pci_device_id structure or %NULL if there is no match. - */ -static inline const struct pci_device_id * -pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev) -{ - if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) && - (id->device == PCI_ANY_ID || id->device == dev->device) && - (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) && - (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) && - !((id->class ^ dev->class) & id->class_mask)) - return id; - return NULL; -} - -struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev); - -/* PCI slot sysfs helper code */ -#define to_pci_slot(s) container_of(s, struct pci_slot, kobj) - -extern struct kset *pci_slots_kset; - -struct pci_slot_attribute { - struct attribute attr; - ssize_t (*show)(struct pci_slot *, char *); - ssize_t (*store)(struct pci_slot *, const char *, size_t); -}; -#define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) - -enum pci_bar_type { - pci_bar_unknown, /* Standard PCI BAR probe */ - pci_bar_io, /* An io port BAR */ - pci_bar_mem32, /* A 32-bit memory BAR */ - pci_bar_mem64, /* A 64-bit memory BAR */ -}; - -extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, - struct resource *res, unsigned int reg); -extern int pci_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type); -extern int pci_bus_add_child(struct pci_bus *bus); -extern void pci_enable_ari(struct pci_dev *dev); -/** - * pci_ari_enabled - query ARI forwarding status - * @bus: the PCI bus - * - * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; - */ -static inline int pci_ari_enabled(struct pci_bus *bus) -{ - return bus->self && bus->self->ari_enabled; -} - -#endif /* DRIVERS_PCI_H */ diff --git a/libdde_linux26/contrib/drivers/pci/search.c b/libdde_linux26/contrib/drivers/pci/search.c deleted file mode 100644 index 5af8bd53..00000000 --- a/libdde_linux26/contrib/drivers/pci/search.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * PCI searching functions. - * - * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter, - * David Mosberger-Tang - * Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz> - * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com> - */ - -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include "pci.h" - -DECLARE_RWSEM(pci_bus_sem); -/* - * find the upstream PCIE-to-PCI bridge of a PCI device - * if the device is PCIE, return NULL - * if the device isn't connected to a PCIE bridge (that is its parent is a - * legacy PCI bridge and the bridge is directly connected to bus 0), return its - * parent - */ -struct pci_dev * -pci_find_upstream_pcie_bridge(struct pci_dev *pdev) -{ - struct pci_dev *tmp = NULL; - - if (pdev->is_pcie) - return NULL; - while (1) { - if (!pdev->bus->self) - break; - pdev = pdev->bus->self; - /* a p2p bridge */ - if (!pdev->is_pcie) { - tmp = pdev; - continue; - } - /* PCI device should connect to a PCIE bridge */ - if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { - /* Busted hardware? */ - WARN_ON_ONCE(1); - return NULL; - } - return pdev; - } - - return tmp; -} - -static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) -{ - struct pci_bus* child; - struct list_head *tmp; - - if(bus->number == busnr) - return bus; - - list_for_each(tmp, &bus->children) { - child = pci_do_find_bus(pci_bus_b(tmp), busnr); - if(child) - return child; - } - return NULL; -} - -/** - * pci_find_bus - locate PCI bus from a given domain and bus number - * @domain: number of PCI domain to search - * @busnr: number of desired PCI bus - * - * Given a PCI bus number and domain number, the desired PCI bus is located - * in the global list of PCI buses. If the bus is found, a pointer to its - * data structure is returned. If no bus is found, %NULL is returned. - */ -struct pci_bus * pci_find_bus(int domain, int busnr) -{ - struct pci_bus *bus = NULL; - struct pci_bus *tmp_bus; - - while ((bus = pci_find_next_bus(bus)) != NULL) { - if (pci_domain_nr(bus) != domain) - continue; - tmp_bus = pci_do_find_bus(bus, busnr); - if (tmp_bus) - return tmp_bus; - } - return NULL; -} - -/** - * pci_find_next_bus - begin or continue searching for a PCI bus - * @from: Previous PCI bus found, or %NULL for new search. - * - * Iterates through the list of known PCI busses. A new search is - * initiated by passing %NULL as the @from argument. Otherwise if - * @from is not %NULL, searches continue from next device on the - * global list. - */ -struct pci_bus * -pci_find_next_bus(const struct pci_bus *from) -{ - struct list_head *n; - struct pci_bus *b = NULL; - - WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); - n = from ? from->node.next : pci_root_buses.next; - if (n != &pci_root_buses) - b = pci_bus_b(n); - up_read(&pci_bus_sem); - return b; -} - -#ifdef CONFIG_PCI_LEGACY -/** - * pci_find_slot - locate PCI device from a given PCI slot - * @bus: number of PCI bus on which desired PCI device resides - * @devfn: encodes number of PCI slot in which the desired PCI - * device resides and the logical device number within that slot - * in case of multi-function devices. - * - * Given a PCI bus and slot/function number, the desired PCI device - * is located in system global list of PCI devices. If the device - * is found, a pointer to its data structure is returned. If no - * device is found, %NULL is returned. - * - * NOTE: Do not use this function any more; use pci_get_slot() instead, as - * the PCI device returned by this function can disappear at any moment in - * time. - */ -struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (dev->bus->number == bus && dev->devfn == devfn) { - pci_dev_put(dev); - return dev; - } - } - return NULL; -} -EXPORT_SYMBOL(pci_find_slot); - -/** - * pci_find_device - begin or continue searching for a PCI device by vendor/device id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching @vendor and @device, a pointer to its device structure is - * returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device - * on the global list. - * - * NOTE: Do not use this function any more; use pci_get_device() instead, as - * the PCI device returned by this function can disappear at any moment in - * time. - */ -struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, - struct pci_dev *from) -{ - struct pci_dev *pdev; - - pci_dev_get(from); - pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); - pci_dev_put(pdev); - return pdev; -} -EXPORT_SYMBOL(pci_find_device); -#endif /* CONFIG_PCI_LEGACY */ - -/** - * pci_get_slot - locate PCI device for a given PCI slot - * @bus: PCI bus on which desired PCI device resides - * @devfn: encodes number of PCI slot in which the desired PCI - * device resides and the logical device number within that slot - * in case of multi-function devices. - * - * Given a PCI bus and slot/function number, the desired PCI device - * is located in the list of PCI devices. - * If the device is found, its reference count is increased and this - * function returns a pointer to its data structure. The caller must - * decrement the reference count by calling pci_dev_put(). - * If no device is found, %NULL is returned. - */ -struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) -{ - struct list_head *tmp; - struct pci_dev *dev; - - WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); - - list_for_each(tmp, &bus->devices) { - dev = pci_dev_b(tmp); - if (dev->devfn == devfn) - goto out; - } - - dev = NULL; - out: - pci_dev_get(dev); - up_read(&pci_bus_sem); - return dev; -} - -/** - * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot - * @bus: number of PCI bus on which desired PCI device resides - * @devfn: encodes number of PCI slot in which the desired PCI - * device resides and the logical device number within that slot - * in case of multi-function devices. - * - * Note: the bus/slot search is limited to PCI domain (segment) 0. - * - * Given a PCI bus and slot/function number, the desired PCI device - * is located in system global list of PCI devices. If the device - * is found, a pointer to its data structure is returned. If no - * device is found, %NULL is returned. The returned device has its - * reference count bumped by one. - */ - -struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (pci_domain_nr(dev->bus) == 0 && - (dev->bus->number == bus && dev->devfn == devfn)) - return dev; - } - return NULL; -} - -static int match_pci_dev_by_id(struct device *dev, void *data) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct pci_device_id *id = data; - - if (pci_match_one_device(id, pdev)) - return 1; - return 0; -} - -/* - * pci_get_dev_by_id - begin or continue searching for a PCI device by id - * @id: pointer to struct pci_device_id to match for the device - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching id a pointer to its device structure is returned, and the - * reference count to the device is incremented. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. Otherwise - * if @from is not %NULL, searches continue from next device on the global - * list. The reference count for @from is always decremented if it is not - * %NULL. - * - * This is an internal function for use by the other search functions in - * this file. - */ -static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, - struct pci_dev *from) -{ - struct device *dev; - struct device *dev_start = NULL; - struct pci_dev *pdev = NULL; - - WARN_ON(in_interrupt()); - if (from) - dev_start = &from->dev; - dev = bus_find_device(&pci_bus_type, dev_start, (void *)id, - match_pci_dev_by_id); - if (dev) - pdev = to_pci_dev(dev); - if (from) - pci_dev_put(from); - return pdev; -} - -/** - * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its - * device structure is returned, and the reference count to the device is - * incremented. Otherwise, %NULL is returned. A new search is initiated by - * passing %NULL as the @from argument. Otherwise if @from is not %NULL, - * searches continue from next device on the global list. - * The reference count for @from is always decremented if it is not %NULL. - */ -struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, - unsigned int ss_vendor, unsigned int ss_device, - struct pci_dev *from) -{ - struct pci_dev *pdev; - struct pci_device_id *id; - - /* - * pci_find_subsys() can be called on the ide_setup() path, - * super-early in boot. But the down_read() will enable local - * interrupts, which can cause some machines to crash. So here we - * detect and flag that situation and bail out early. - */ - if (unlikely(no_pci_devices())) - return NULL; - - id = kzalloc(sizeof(*id), GFP_KERNEL); - if (!id) - return NULL; - id->vendor = vendor; - id->device = device; - id->subvendor = ss_vendor; - id->subdevice = ss_device; - - pdev = pci_get_dev_by_id(id, from); - kfree(id); - - return pdev; -} - -/** - * pci_get_device - begin or continue searching for a PCI device by vendor/device id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @vendor and @device, the reference count to the - * device is incremented and a pointer to its device structure is returned. - * Otherwise, %NULL is returned. A new search is initiated by passing %NULL - * as the @from argument. Otherwise if @from is not %NULL, searches continue - * from next device on the global list. The reference count for @from is - * always decremented if it is not %NULL. - */ -struct pci_dev * -pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) -{ - return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); -} - -/** - * pci_get_class - begin or continue searching for a PCI device by class - * @class: search for a PCI device with this class designation - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @class, the reference count to the device is - * incremented and a pointer to its device structure is returned. - * Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device - * on the global list. The reference count for @from is always decremented - * if it is not %NULL. - */ -struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) -{ - struct pci_dev *dev; - struct pci_device_id *id; - - id = kzalloc(sizeof(*id), GFP_KERNEL); - if (!id) - return NULL; - id->vendor = id->device = id->subvendor = id->subdevice = PCI_ANY_ID; - id->class_mask = PCI_ANY_ID; - id->class = class; - - dev = pci_get_dev_by_id(id, from); - kfree(id); - return dev; -} - -/** - * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. - * @ids: A pointer to a null terminated list of struct pci_device_id structures - * that describe the type of PCI device the caller is trying to find. - * - * Obvious fact: You do not have a reference to any device that might be found - * by this function, so if that device is removed from the system right after - * this function is finished, the value will be stale. Use this function to - * find devices that are usually built into a system, or for a general hint as - * to if another device happens to be present at this specific moment in time. - */ -int pci_dev_present(const struct pci_device_id *ids) -{ - struct pci_dev *found = NULL; - - WARN_ON(in_interrupt()); - while (ids->vendor || ids->subvendor || ids->class_mask) { - found = pci_get_dev_by_id(ids, NULL); - if (found) - goto exit; - ids++; - } -exit: - if (found) - return 1; - return 0; -} -EXPORT_SYMBOL(pci_dev_present); - -/* For boot time work */ -EXPORT_SYMBOL(pci_find_bus); -EXPORT_SYMBOL(pci_find_next_bus); -/* For everyone */ -EXPORT_SYMBOL(pci_get_device); -EXPORT_SYMBOL(pci_get_subsys); -EXPORT_SYMBOL(pci_get_slot); -EXPORT_SYMBOL(pci_get_bus_and_slot); -EXPORT_SYMBOL(pci_get_class); diff --git a/libdde_linux26/contrib/drivers/pci/setup-bus.c b/libdde_linux26/contrib/drivers/pci/setup-bus.c deleted file mode 100644 index 70460894..00000000 --- a/libdde_linux26/contrib/drivers/pci/setup-bus.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * drivers/pci/setup-bus.c - * - * Extruded from code written by - * Dave Rusling (david.rusling@reo.mts.dec.com) - * David Mosberger (davidm@cs.arizona.edu) - * David Miller (davem@redhat.com) - * - * Support routines for initializing a PCI subsystem. - */ - -/* - * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru> - * PCI-PCI bridges cleanup, sorted resource allocation. - * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru> - * Converted to allocation in 3 passes, which gives - * tighter packing. Prefetchable range support. - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/cache.h> -#include <linux/slab.h> - - -static void pbus_assign_resources_sorted(struct pci_bus *bus) -{ - struct pci_dev *dev; - struct resource *res; - struct resource_list head, *list, *tmp; - int idx; - - head.next = NULL; - list_for_each_entry(dev, &bus->devices, bus_list) { - u16 class = dev->class >> 8; - - /* Don't touch classless devices or host bridges or ioapics. */ - if (class == PCI_CLASS_NOT_DEFINED || - class == PCI_CLASS_BRIDGE_HOST) - continue; - - /* Don't touch ioapic devices already enabled by firmware */ - if (class == PCI_CLASS_SYSTEM_PIC) { - u16 command; - pci_read_config_word(dev, PCI_COMMAND, &command); - if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) - continue; - } - - pdev_sort_resources(dev, &head); - } - - for (list = head.next; list;) { - res = list->res; - idx = res - &list->dev->resource[0]; - if (pci_assign_resource(list->dev, idx)) { - /* FIXME: get rid of this */ - res->start = 0; - res->end = 0; - res->flags = 0; - } - tmp = list; - list = list->next; - kfree(tmp); - } -} - -void pci_setup_cardbus(struct pci_bus *bus) -{ - struct pci_dev *bridge = bus->self; - struct pci_bus_region region; - - dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); - if (bus->resource[0]->flags & IORESOURCE_IO) { - /* - * The IO resource is allocated a range twice as large as it - * would normally need. This allows us to set both IO regs. - */ - dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, - region.start); - pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, - region.end); - } - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); - if (bus->resource[1]->flags & IORESOURCE_IO) { - dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, - region.start); - pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, - region.end); - } - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); - if (bus->resource[2]->flags & IORESOURCE_MEM) { - dev_info(&bridge->dev, " PREFETCH window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, - region.start); - pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, - region.end); - } - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); - if (bus->resource[3]->flags & IORESOURCE_MEM) { - dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, - region.start); - pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, - region.end); - } -} -EXPORT_SYMBOL(pci_setup_cardbus); - -/* Initialize bridges with base/limit values we have collected. - PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998) - requires that if there is no I/O ports or memory behind the - bridge, corresponding range must be turned off by writing base - value greater than limit to the bridge's base/limit registers. - - Note: care must be taken when updating I/O base/limit registers - of bridges which support 32-bit I/O. This update requires two - config space writes, so it's quite possible that an I/O window of - the bridge will have some undesirable address (e.g. 0) after the - first write. Ditto 64-bit prefetchable MMIO. */ -static void pci_setup_bridge(struct pci_bus *bus) -{ - struct pci_dev *bridge = bus->self; - struct pci_bus_region region; - u32 l, bu, lu, io_upper16; - - dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); - - /* Set up the top and bottom of the PCI I/O segment for this bus. */ - pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); - if (bus->resource[0]->flags & IORESOURCE_IO) { - pci_read_config_dword(bridge, PCI_IO_BASE, &l); - l &= 0xffff0000; - l |= (region.start >> 8) & 0x00f0; - l |= region.end & 0xf000; - /* Set up upper 16 bits of I/O base/limit. */ - io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); - dev_info(&bridge->dev, " IO window: %#04lx-%#04lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - } - else { - /* Clear upper 16 bits of I/O base/limit. */ - io_upper16 = 0; - l = 0x00f0; - dev_info(&bridge->dev, " IO window: disabled\n"); - } - /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ - pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); - /* Update lower 16 bits of I/O base/limit. */ - pci_write_config_dword(bridge, PCI_IO_BASE, l); - /* Update upper 16 bits of I/O base/limit. */ - pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); - - /* Set up the top and bottom of the PCI Memory segment - for this bus. */ - pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); - if (bus->resource[1]->flags & IORESOURCE_MEM) { - l = (region.start >> 16) & 0xfff0; - l |= region.end & 0xfff00000; - dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - } - else { - l = 0x0000fff0; - dev_info(&bridge->dev, " MEM window: disabled\n"); - } - pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); - - /* Clear out the upper 32 bits of PREF limit. - If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily - disables PREF range, which is ok. */ - pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); - - /* Set up PREF base/limit. */ - bu = lu = 0; - pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); - if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { - l = (region.start >> 16) & 0xfff0; - l |= region.end & 0xfff00000; - bu = upper_32_bits(region.start); - lu = upper_32_bits(region.end); - dev_info(&bridge->dev, " PREFETCH window: %#016llx-%#016llx\n", - (unsigned long long)region.start, - (unsigned long long)region.end); - } - else { - l = 0x0000fff0; - dev_info(&bridge->dev, " PREFETCH window: disabled\n"); - } - pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); - - /* Set the upper 32 bits of PREF base & limit. */ - pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); - pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); - - pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); -} - -/* Check whether the bridge supports optional I/O and - prefetchable memory ranges. If not, the respective - base/limit registers must be read-only and read as 0. */ -static void pci_bridge_check_ranges(struct pci_bus *bus) -{ - u16 io; - u32 pmem; - struct pci_dev *bridge = bus->self; - struct resource *b_res; - - b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; - b_res[1].flags |= IORESOURCE_MEM; - - pci_read_config_word(bridge, PCI_IO_BASE, &io); - if (!io) { - pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); - pci_read_config_word(bridge, PCI_IO_BASE, &io); - pci_write_config_word(bridge, PCI_IO_BASE, 0x0); - } - if (io) - b_res[0].flags |= IORESOURCE_IO; - /* DECchip 21050 pass 2 errata: the bridge may miss an address - disconnect boundary by one PCI data phase. - Workaround: do not use prefetching on this device. */ - if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001) - return; - pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); - if (!pmem) { - pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, - 0xfff0fff0); - pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); - pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); - } - if (pmem) - b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; -} - -/* Helper function for sizing routines: find first available - bus resource of a given type. Note: we intentionally skip - the bus resources which have already been assigned (that is, - have non-NULL parent resource). */ -static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type) -{ - int i; - struct resource *r; - unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | - IORESOURCE_PREFETCH; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - r = bus->resource[i]; - if (r == &ioport_resource || r == &iomem_resource) - continue; - if (r && (r->flags & type_mask) == type && !r->parent) - return r; - } - return NULL; -} - -/* Sizing the IO windows of the PCI-PCI bridge is trivial, - since these windows have 4K granularity and the IO ranges - of non-bridge PCI devices are limited to 256 bytes. - We must be careful with the ISA aliasing though. */ -static void pbus_size_io(struct pci_bus *bus) -{ - struct pci_dev *dev; - struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); - unsigned long size = 0, size1 = 0; - - if (!b_res) - return; - - list_for_each_entry(dev, &bus->devices, bus_list) { - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - unsigned long r_size; - - if (r->parent || !(r->flags & IORESOURCE_IO)) - continue; - r_size = resource_size(r); - - if (r_size < 0x400) - /* Might be re-aligned for ISA */ - size += r_size; - else - size1 += r_size; - } - } -/* To be fixed in 2.5: we should have sort of HAVE_ISA - flag in the struct pci_bus. */ -#if defined(CONFIG_ISA) || defined(CONFIG_EISA) - size = (size & 0xff) + ((size & ~0xffUL) << 2); -#endif - size = ALIGN(size + size1, 4096); - if (!size) { - b_res->flags = 0; - return; - } - /* Alignment of the IO window is always 4K */ - b_res->start = 4096; - b_res->end = b_res->start + size - 1; - b_res->flags |= IORESOURCE_STARTALIGN; -} - -/* Calculate the size of the bus and minimal alignment which - guarantees that all child resources fit in this size. */ -static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) -{ - struct pci_dev *dev; - resource_size_t min_align, align, size; - resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ - int order, max_order; - struct resource *b_res = find_free_bus_resource(bus, type); - - if (!b_res) - return 0; - - memset(aligns, 0, sizeof(aligns)); - max_order = 0; - size = 0; - - list_for_each_entry(dev, &bus->devices, bus_list) { - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - resource_size_t r_size; - - if (r->parent || (r->flags & mask) != type) - continue; - r_size = resource_size(r); - /* For bridges size != alignment */ - align = resource_alignment(r); - order = __ffs(align) - 20; - if (order > 11) { - dev_warn(&dev->dev, "BAR %d bad alignment %llx: " - "%pR\n", i, (unsigned long long)align, r); - r->flags = 0; - continue; - } - size += r_size; - if (order < 0) - order = 0; - /* Exclude ranges with size > align from - calculation of the alignment. */ - if (r_size == align) - aligns[order] += align; - if (order > max_order) - max_order = order; - } - } - - align = 0; - min_align = 0; - for (order = 0; order <= max_order; order++) { - resource_size_t align1 = 1; - - align1 <<= (order + 20); - - if (!align) - min_align = align1; - else if (ALIGN(align + min_align, min_align) < align1) - min_align = align1 >> 1; - align += aligns[order]; - } - size = ALIGN(size, min_align); - if (!size) { - b_res->flags = 0; - return 1; - } - b_res->start = min_align; - b_res->end = size + min_align - 1; - b_res->flags |= IORESOURCE_STARTALIGN; - return 1; -} - -static void pci_bus_size_cardbus(struct pci_bus *bus) -{ - struct pci_dev *bridge = bus->self; - struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; - u16 ctrl; - - /* - * Reserve some resources for CardBus. We reserve - * a fixed amount of bus space for CardBus bridges. - */ - b_res[0].start = 0; - b_res[0].end = pci_cardbus_io_size - 1; - b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; - - b_res[1].start = 0; - b_res[1].end = pci_cardbus_io_size - 1; - b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; - - /* - * Check whether prefetchable memory is supported - * by this bridge. - */ - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) { - ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; - pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - } - - /* - * If we have prefetchable memory support, allocate - * two regions. Otherwise, allocate one region of - * twice the size. - */ - if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { - b_res[2].start = 0; - b_res[2].end = pci_cardbus_mem_size - 1; - b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; - - b_res[3].start = 0; - b_res[3].end = pci_cardbus_mem_size - 1; - b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; - } else { - b_res[3].start = 0; - b_res[3].end = pci_cardbus_mem_size * 2 - 1; - b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; - } -} - -void __ref pci_bus_size_bridges(struct pci_bus *bus) -{ - struct pci_dev *dev; - unsigned long mask, prefmask; - - list_for_each_entry(dev, &bus->devices, bus_list) { - struct pci_bus *b = dev->subordinate; - if (!b) - continue; - - switch (dev->class >> 8) { - case PCI_CLASS_BRIDGE_CARDBUS: - pci_bus_size_cardbus(b); - break; - - case PCI_CLASS_BRIDGE_PCI: - default: - pci_bus_size_bridges(b); - break; - } - } - - /* The root bus? */ - if (!bus->self) - return; - - switch (bus->self->class >> 8) { - case PCI_CLASS_BRIDGE_CARDBUS: - /* don't size cardbuses yet. */ - break; - - case PCI_CLASS_BRIDGE_PCI: - pci_bridge_check_ranges(bus); - default: - pbus_size_io(bus); - /* If the bridge supports prefetchable range, size it - separately. If it doesn't, or its prefetchable window - has already been allocated by arch code, try - non-prefetchable range for both types of PCI memory - resources. */ - mask = IORESOURCE_MEM; - prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; - if (pbus_size_mem(bus, prefmask, prefmask)) - mask = prefmask; /* Success, size non-prefetch only. */ - pbus_size_mem(bus, mask, IORESOURCE_MEM); - break; - } -} -EXPORT_SYMBOL(pci_bus_size_bridges); - -void __ref pci_bus_assign_resources(struct pci_bus *bus) -{ - struct pci_bus *b; - struct pci_dev *dev; - - pbus_assign_resources_sorted(bus); - - list_for_each_entry(dev, &bus->devices, bus_list) { - b = dev->subordinate; - if (!b) - continue; - - pci_bus_assign_resources(b); - - switch (dev->class >> 8) { - case PCI_CLASS_BRIDGE_PCI: - pci_setup_bridge(b); - break; - - case PCI_CLASS_BRIDGE_CARDBUS: - pci_setup_cardbus(b); - break; - - default: - dev_info(&dev->dev, "not setting up bridge for bus " - "%04x:%02x\n", pci_domain_nr(b), b->number); - break; - } - } -} -EXPORT_SYMBOL(pci_bus_assign_resources); - -static void pci_bus_dump_res(struct pci_bus *bus) -{ - int i; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *res = bus->resource[i]; - if (!res) - continue; - - dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i, - (res->flags & IORESOURCE_IO) ? "io: " : "mem:", res); - } -} - -static void pci_bus_dump_resources(struct pci_bus *bus) -{ - struct pci_bus *b; - struct pci_dev *dev; - - - pci_bus_dump_res(bus); - - list_for_each_entry(dev, &bus->devices, bus_list) { - b = dev->subordinate; - if (!b) - continue; - - pci_bus_dump_resources(b); - } -} - -void __init -pci_assign_unassigned_resources(void) -{ - struct pci_bus *bus; - - /* Depth first, calculate sizes and alignments of all - subordinate buses. */ - list_for_each_entry(bus, &pci_root_buses, node) { - pci_bus_size_bridges(bus); - } - /* Depth last, allocate resources and update the hardware. */ - list_for_each_entry(bus, &pci_root_buses, node) { - pci_bus_assign_resources(bus); - pci_enable_bridges(bus); - } - - /* dump the resource on buses */ - list_for_each_entry(bus, &pci_root_buses, node) { - pci_bus_dump_resources(bus); - } -} diff --git a/libdde_linux26/contrib/drivers/pci/setup-res.c b/libdde_linux26/contrib/drivers/pci/setup-res.c deleted file mode 100644 index 32e8d88a..00000000 --- a/libdde_linux26/contrib/drivers/pci/setup-res.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * drivers/pci/setup-res.c - * - * Extruded from code written by - * Dave Rusling (david.rusling@reo.mts.dec.com) - * David Mosberger (davidm@cs.arizona.edu) - * David Miller (davem@redhat.com) - * - * Support routines for initializing a PCI subsystem. - */ - -/* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */ - -/* - * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru> - * Resource sorting - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/cache.h> -#include <linux/slab.h> -#include "pci.h" - - -void pci_update_resource(struct pci_dev *dev, int resno) -{ - struct pci_bus_region region; - u32 new, check, mask; - int reg; - enum pci_bar_type type; - struct resource *res = dev->resource + resno; - - /* - * Ignore resources for unimplemented BARs and unused resource slots - * for 64 bit BARs. - */ - if (!res->flags) - return; - - /* - * Ignore non-moveable resources. This might be legacy resources for - * which no functional BAR register exists or another important - * system resource we shouldn't move around. - */ - if (res->flags & IORESOURCE_PCI_FIXED) - return; - - pcibios_resource_to_bus(dev, ®ion, res); - - dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " - "flags %#lx\n", resno, res, - (unsigned long long)region.start, - (unsigned long long)region.end, - (unsigned long)res->flags); - - new = region.start | (res->flags & PCI_REGION_FLAG_MASK); - if (res->flags & IORESOURCE_IO) - mask = (u32)PCI_BASE_ADDRESS_IO_MASK; - else - mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; - - reg = pci_resource_bar(dev, resno, &type); - if (!reg) - return; - if (type != pci_bar_unknown) { - if (!(res->flags & IORESOURCE_ROM_ENABLE)) - return; - new |= PCI_ROM_ADDRESS_ENABLE; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - - if ((new ^ check) & mask) { - dev_err(&dev->dev, "BAR %d: error updating (%#08x != %#08x)\n", - resno, new, check); - } - - if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == - (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) { - new = region.start >> 16 >> 16; - pci_write_config_dword(dev, reg + 4, new); - pci_read_config_dword(dev, reg + 4, &check); - if (check != new) { - dev_err(&dev->dev, "BAR %d: error updating " - "(high %#08x != %#08x)\n", resno, new, check); - } - } - res->flags &= ~IORESOURCE_UNSET; - dev_dbg(&dev->dev, "BAR %d: moved to bus [%#llx-%#llx] flags %#lx\n", - resno, (unsigned long long)region.start, - (unsigned long long)region.end, res->flags); -} - -int pci_claim_resource(struct pci_dev *dev, int resource) -{ - struct resource *res = &dev->resource[resource]; - struct resource *root = NULL; - char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; - int err; - - root = pcibios_select_root(dev, res); - - err = -EINVAL; - if (root != NULL) - err = insert_resource(root, res); - - if (err) { - dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", - resource, - root ? "address space collision on" : - "no parent found for", - dtype, res); - } - - return err; -} - -int pci_assign_resource(struct pci_dev *dev, int resno) -{ - struct pci_bus *bus = dev->bus; - struct resource *res = dev->resource + resno; - resource_size_t size, min, align; - int ret; - - size = resource_size(res); - min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; - - align = resource_alignment(res); - if (!align) { - dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " - "alignment) %pR flags %#lx\n", - resno, res, res->flags); - return -EINVAL; - } - - /* First, try exact prefetching match.. */ - ret = pci_bus_alloc_resource(bus, res, size, align, min, - IORESOURCE_PREFETCH, - pcibios_align_resource, dev); - - if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) { - /* - * That failed. - * - * But a prefetching area can handle a non-prefetching - * window (it will just not perform as well). - */ - ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, - pcibios_align_resource, dev); - } - - if (ret) { - dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", - resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); - } else { - res->flags &= ~IORESOURCE_STARTALIGN; - if (resno < PCI_BRIDGE_RESOURCES) - pci_update_resource(dev, resno); - } - - return ret; -} - -#if 0 -int pci_assign_resource_fixed(struct pci_dev *dev, int resno) -{ - struct pci_bus *bus = dev->bus; - struct resource *res = dev->resource + resno; - unsigned int type_mask; - int i, ret = -EBUSY; - - type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *r = bus->resource[i]; - if (!r) - continue; - - /* type_mask must match */ - if ((res->flags ^ r->flags) & type_mask) - continue; - - ret = request_resource(r, res); - - if (ret == 0) - break; - } - - if (ret) { - dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", - resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); - } else if (resno < PCI_BRIDGE_RESOURCES) { - pci_update_resource(dev, resno); - } - - return ret; -} -EXPORT_SYMBOL_GPL(pci_assign_resource_fixed); -#endif - -/* Sort resources by alignment */ -void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) -{ - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r; - struct resource_list *list, *tmp; - resource_size_t r_align; - - r = &dev->resource[i]; - - if (r->flags & IORESOURCE_PCI_FIXED) - continue; - - if (!(r->flags) || r->parent) - continue; - - r_align = resource_alignment(r); - if (!r_align) { - dev_warn(&dev->dev, "BAR %d: bogus alignment " - "%pR flags %#lx\n", - i, r, r->flags); - continue; - } - for (list = head; ; list = list->next) { - resource_size_t align = 0; - struct resource_list *ln = list->next; - - if (ln) - align = resource_alignment(ln->res); - - if (r_align > align) { - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - if (!tmp) - panic("pdev_sort_resources(): " - "kmalloc() failed!\n"); - tmp->next = ln; - tmp->res = r; - tmp->dev = dev; - list->next = tmp; - break; - } - } - } -} - -int pci_enable_resources(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int i; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (!(mask & (1 << i))) - continue; - - r = &dev->resource[i]; - - if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) - continue; - if ((i == PCI_ROM_RESOURCE) && - (!(r->flags & IORESOURCE_ROM_ENABLE))) - continue; - - if (!r->parent) { - dev_err(&dev->dev, "device not available because of " - "BAR %d %pR collisions\n", i, r); - return -EINVAL; - } - - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - - if (cmd != old_cmd) { - dev_info(&dev->dev, "enabling device (%04x -> %04x)\n", - old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} |