Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
This commit is contained in:
commit
7e2987503d
|
@ -7,7 +7,6 @@ that support it. For example, a given bus might look like this:
|
|||
|-- 0000:17:00.0
|
||||
| |-- class
|
||||
| |-- config
|
||||
| |-- detach_state
|
||||
| |-- device
|
||||
| |-- irq
|
||||
| |-- local_cpus
|
||||
|
@ -19,7 +18,7 @@ that support it. For example, a given bus might look like this:
|
|||
| |-- subsystem_device
|
||||
| |-- subsystem_vendor
|
||||
| `-- vendor
|
||||
`-- detach_state
|
||||
`-- ...
|
||||
|
||||
The topmost element describes the PCI domain and bus number. In this case,
|
||||
the domain number is 0000 and the bus number is 17 (both values are in hex).
|
||||
|
@ -31,7 +30,6 @@ files, each with their own function.
|
|||
---- --------
|
||||
class PCI class (ascii, ro)
|
||||
config PCI config space (binary, rw)
|
||||
detach_state connection status (bool, rw)
|
||||
device PCI device (ascii, ro)
|
||||
irq IRQ number (ascii, ro)
|
||||
local_cpus nearby CPU mask (cpumask, ro)
|
||||
|
@ -85,4 +83,4 @@ useful return codes should be provided.
|
|||
|
||||
Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
|
||||
wishing to support legacy functionality should define it and provide
|
||||
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
|
||||
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
|
||||
|
|
|
@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
|
|||
#READY_AFTER_RESUME
|
||||
#
|
||||
|
||||
Driver Detach Power Management
|
||||
|
||||
The kernel now supports the ability to place a device in a low-power
|
||||
state when it is detached from its driver, which happens when its
|
||||
module is removed.
|
||||
|
||||
Each device contains a 'detach_state' file in its sysfs directory
|
||||
which can be used to control this state. Reading from this file
|
||||
displays what the current detach state is set to. This is 0 (On) by
|
||||
default. A user may write a positive integer value to this file in the
|
||||
range of 1-4 inclusive.
|
||||
|
||||
A value of 1-3 will indicate the device should be placed in that
|
||||
low-power state, which will cause ->suspend() to be called for that
|
||||
device. A value of 4 indicates that the device should be shutdown, so
|
||||
->shutdown() will be called for that device.
|
||||
|
||||
The driver is responsible for reinitializing the device when the
|
||||
module is re-inserted during it's ->probe() (or equivalent) method.
|
||||
The driver core will not call any extra functions when binding the
|
||||
device to the driver.
|
||||
|
||||
pm_message_t meaning
|
||||
|
||||
|
|
|
@ -347,8 +347,8 @@ address that is created by firmware. An example vty-server sysfs entry
|
|||
looks like the following:
|
||||
|
||||
Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
|
||||
. current_vty devspec name partner_vtys
|
||||
.. detach_state index partner_clcs vterm_state
|
||||
. current_vty devspec name partner_vtys
|
||||
.. index partner_clcs vterm_state
|
||||
|
||||
Each entry is provided, by default with a "name" attribute. Reading the
|
||||
"name" attribute will reveal the device type as shown in the following
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Makefile for the Linux device tree
|
||||
|
||||
obj-y := core.o sys.o interface.o bus.o \
|
||||
obj-y := core.o sys.o bus.o \
|
||||
driver.o class.o class_simple.o platform.o \
|
||||
cpu.o firmware.o init.o map.o dmapool.o \
|
||||
attribute_container.o transport_class.o
|
||||
|
|
|
@ -390,7 +390,6 @@ void device_release_driver(struct device * dev)
|
|||
sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
|
||||
sysfs_remove_link(&dev->kobj, "driver");
|
||||
list_del_init(&dev->driver_list);
|
||||
device_detach_shutdown(dev);
|
||||
if (drv->remove)
|
||||
drv->remove(dev);
|
||||
dev->driver = NULL;
|
||||
|
|
|
@ -31,8 +31,6 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
|
|||
#define to_dev(obj) container_of(obj, struct device, kobj)
|
||||
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
|
||||
|
||||
extern struct attribute * dev_default_attrs[];
|
||||
|
||||
static ssize_t
|
||||
dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
||||
{
|
||||
|
@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj)
|
|||
static struct kobj_type ktype_device = {
|
||||
.release = device_release,
|
||||
.sysfs_ops = &dev_sysfs_ops,
|
||||
.default_attrs = dev_default_attrs,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* drivers/base/interface.c - common driverfs interface that's exported to
|
||||
* the world for all devices.
|
||||
*
|
||||
* Copyright (c) 2002-3 Patrick Mochel
|
||||
* Copyright (c) 2002-3 Open Source Development Labs
|
||||
*
|
||||
* This file is released under the GPLv2
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
/**
|
||||
* detach_state - control the default power state for the device.
|
||||
*
|
||||
* This is the state the device enters when it's driver module is
|
||||
* unloaded. The value is an unsigned integer, in the range of 0-4.
|
||||
* '0' indicates 'On', so no action will be taken when the driver is
|
||||
* unloaded. This is the default behavior.
|
||||
* '4' indicates 'Off', meaning the driver core will call the driver's
|
||||
* shutdown method to quiesce the device.
|
||||
* 1-3 indicate a low-power state for the device to enter via the
|
||||
* driver's suspend method.
|
||||
*/
|
||||
|
||||
static ssize_t detach_show(struct device * dev, char * buf)
|
||||
{
|
||||
return sprintf(buf, "%u\n", dev->detach_state);
|
||||
}
|
||||
|
||||
static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
|
||||
{
|
||||
u32 state;
|
||||
state = simple_strtoul(buf, NULL, 10);
|
||||
if (state > 4)
|
||||
return -EINVAL;
|
||||
dev->detach_state = state;
|
||||
return n;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
|
||||
|
||||
|
||||
struct attribute * dev_default_attrs[] = {
|
||||
&dev_attr_detach_state.attr,
|
||||
NULL,
|
||||
};
|
|
@ -1,18 +1,7 @@
|
|||
|
||||
|
||||
enum {
|
||||
DEVICE_PM_ON,
|
||||
DEVICE_PM1,
|
||||
DEVICE_PM2,
|
||||
DEVICE_PM3,
|
||||
DEVICE_PM_OFF,
|
||||
};
|
||||
|
||||
/*
|
||||
* shutdown.c
|
||||
*/
|
||||
|
||||
extern int device_detach_shutdown(struct device *);
|
||||
extern void device_shutdown(void);
|
||||
|
||||
|
||||
|
|
|
@ -22,8 +22,17 @@ extern int sysdev_resume(void);
|
|||
|
||||
int resume_device(struct device * dev)
|
||||
{
|
||||
if (dev->bus && dev->bus->resume)
|
||||
if (dev->power.pm_parent
|
||||
&& dev->power.pm_parent->power.power_state) {
|
||||
dev_err(dev, "PM: resume from %d, parent %s still %d\n",
|
||||
dev->power.power_state,
|
||||
dev->power.pm_parent->bus_id,
|
||||
dev->power.pm_parent->power.power_state);
|
||||
}
|
||||
if (dev->bus && dev->bus->resume) {
|
||||
dev_dbg(dev,"resuming\n");
|
||||
return dev->bus->resume(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,20 +19,6 @@
|
|||
extern struct subsystem devices_subsys;
|
||||
|
||||
|
||||
int device_detach_shutdown(struct device * dev)
|
||||
{
|
||||
if (!dev->detach_state)
|
||||
return 0;
|
||||
|
||||
if (dev->detach_state == DEVICE_PM_OFF) {
|
||||
if (dev->driver && dev->driver->shutdown)
|
||||
dev->driver->shutdown(dev);
|
||||
return 0;
|
||||
}
|
||||
return dpm_runtime_suspend(dev, dev->detach_state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We handle system devices differently - we suspend and shut them
|
||||
* down last and resume them first. That way, we don't do anything stupid like
|
||||
|
@ -52,13 +38,12 @@ void device_shutdown(void)
|
|||
struct device * dev;
|
||||
|
||||
down_write(&devices_subsys.rwsem);
|
||||
list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) {
|
||||
pr_debug("shutting down %s: ", dev->bus_id);
|
||||
list_for_each_entry_reverse(dev, &devices_subsys.kset.list,
|
||||
kobj.entry) {
|
||||
if (dev->driver && dev->driver->shutdown) {
|
||||
pr_debug("Ok\n");
|
||||
dev_dbg(dev, "shutdown\n");
|
||||
dev->driver->shutdown(dev);
|
||||
} else
|
||||
pr_debug("Ignored.\n");
|
||||
}
|
||||
}
|
||||
up_write(&devices_subsys.rwsem);
|
||||
|
||||
|
|
|
@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state)
|
|||
{
|
||||
int error = 0;
|
||||
|
||||
dev_dbg(dev, "suspending\n");
|
||||
if (dev->power.power_state) {
|
||||
dev_dbg(dev, "PM: suspend %d-->%d\n",
|
||||
dev->power.power_state, state);
|
||||
}
|
||||
if (dev->power.pm_parent
|
||||
&& dev->power.pm_parent->power.power_state) {
|
||||
dev_err(dev,
|
||||
"PM: suspend %d->%d, parent %s already %d\n",
|
||||
dev->power.power_state, state,
|
||||
dev->power.pm_parent->bus_id,
|
||||
dev->power.pm_parent->power.power_state);
|
||||
}
|
||||
|
||||
dev->power.prev_state = dev->power.power_state;
|
||||
|
||||
if (dev->bus && dev->bus->suspend && !dev->power.power_state)
|
||||
if (dev->bus && dev->bus->suspend && !dev->power.power_state) {
|
||||
dev_dbg(dev, "suspending\n");
|
||||
error = dev->bus->suspend(dev, state);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
|
|||
{
|
||||
struct block_device *bdev = filp->private_data;
|
||||
|
||||
return blkdev_ioctl(bdev->bd_inode, filp, command, arg);
|
||||
return blkdev_ioctl(bdev->bd_inode, NULL, command, arg);
|
||||
}
|
||||
|
||||
static void bind_device(struct raw_config_request *rq)
|
||||
|
|
|
@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
|
|||
if ((buffer_size - length <= 0) || (i >= num_envp))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i++] = scratch;
|
||||
length += scnprintf (scratch, buffer_size - length,
|
||||
"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
|
||||
pdev->vendor, pdev->device,
|
||||
pdev->subsystem_vendor, pdev->subsystem_device,
|
||||
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
|
||||
(u8)(pdev->class));
|
||||
if ((buffer_size - length <= 0) || (i >= num_envp))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
|
||||
{
|
||||
struct list_head *ln;
|
||||
struct pci_dev *dev;
|
||||
struct pci_dev_wrapped wrapped_dev;
|
||||
int result = 0;
|
||||
|
||||
pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus),
|
||||
wrapped_bus->bus->number);
|
||||
|
||||
if (fn->pre_visit_pci_bus) {
|
||||
result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
ln = wrapped_bus->bus->devices.next;
|
||||
while (ln != &wrapped_bus->bus->devices) {
|
||||
dev = pci_dev_b(ln);
|
||||
ln = ln->next;
|
||||
|
||||
memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
|
||||
wrapped_dev.dev = dev;
|
||||
|
||||
result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (fn->post_visit_pci_bus)
|
||||
result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int pci_visit_bridge (struct pci_visit * fn,
|
||||
struct pci_dev_wrapped *wrapped_dev,
|
||||
struct pci_bus_wrapped *wrapped_parent)
|
||||
{
|
||||
struct pci_bus *bus;
|
||||
struct pci_bus_wrapped wrapped_bus;
|
||||
int result = 0;
|
||||
|
||||
pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev));
|
||||
|
||||
if (fn->visit_pci_dev) {
|
||||
result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
bus = wrapped_dev->dev->subordinate;
|
||||
if (bus) {
|
||||
memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
|
||||
wrapped_bus.bus = bus;
|
||||
|
||||
result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_visit_dev - scans the pci buses.
|
||||
* @fn: callback functions that are called while visiting
|
||||
* @wrapped_dev: the device to scan
|
||||
* @wrapped_parent: the bus where @wrapped_dev is connected to
|
||||
*
|
||||
* Every bus and every function is presented to a custom
|
||||
* function that can act upon it.
|
||||
*/
|
||||
int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
|
||||
struct pci_bus_wrapped *wrapped_parent)
|
||||
{
|
||||
struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
|
||||
int result = 0;
|
||||
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
if (fn->pre_visit_pci_dev) {
|
||||
result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (dev->class >> 8) {
|
||||
case PCI_CLASS_BRIDGE_PCI:
|
||||
result = pci_visit_bridge(fn, wrapped_dev,
|
||||
wrapped_parent);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
default:
|
||||
pr_debug("PCI: Scanning device %s\n", pci_name(dev));
|
||||
if (fn->visit_pci_dev) {
|
||||
result = fn->visit_pci_dev (wrapped_dev,
|
||||
wrapped_parent);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (fn->post_visit_pci_dev)
|
||||
result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_visit_dev);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
/* PICMG 2.12 R2.0 HS CSR bits: */
|
||||
/* PICMG 2.1 R2.0 HS CSR bits: */
|
||||
#define HS_CSR_INS 0x0080
|
||||
#define HS_CSR_EXT 0x0040
|
||||
#define HS_CSR_PI 0x0030
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/delay.h>
|
||||
#include "pci_hotplug.h"
|
||||
#include "cpci_hotplug.h"
|
||||
|
||||
#define DRIVER_VERSION "0.2"
|
||||
#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
|
||||
#define DRIVER_DESC "CompactPCI Hot Plug Core"
|
||||
|
||||
|
@ -54,9 +54,10 @@
|
|||
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
|
||||
|
||||
/* local variables */
|
||||
static spinlock_t list_lock;
|
||||
static DECLARE_RWSEM(list_rwsem);
|
||||
static LIST_HEAD(slot_list);
|
||||
static int slots;
|
||||
static atomic_t extracting;
|
||||
int cpci_debug;
|
||||
static struct cpci_hp_controller *controller;
|
||||
static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
|
||||
|
@ -68,6 +69,8 @@ static int disable_slot(struct hotplug_slot *slot);
|
|||
static int set_attention_status(struct hotplug_slot *slot, u8 value);
|
||||
static int get_power_status(struct hotplug_slot *slot, u8 * value);
|
||||
static int get_attention_status(struct hotplug_slot *slot, u8 * value);
|
||||
static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
|
||||
static int get_latch_status(struct hotplug_slot *slot, u8 * value);
|
||||
|
||||
static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
|
|||
.set_attention_status = set_attention_status,
|
||||
.get_power_status = get_power_status,
|
||||
.get_attention_status = get_attention_status,
|
||||
.get_adapter_status = get_adapter_status,
|
||||
.get_latch_status = get_latch_status,
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot)
|
|||
warn("failure to update adapter file");
|
||||
}
|
||||
|
||||
slot->extracting = 0;
|
||||
|
||||
if(slot->extracting) {
|
||||
slot->extracting = 0;
|
||||
atomic_dec(&extracting);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
|
|||
return cpci_set_attention_status(hotplug_slot->private, status);
|
||||
}
|
||||
|
||||
static int
|
||||
get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
|
||||
{
|
||||
*value = hotplug_slot->info->adapter_status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
|
||||
{
|
||||
*value = hotplug_slot->info->latch_status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void release_slot(struct hotplug_slot *hotplug_slot)
|
||||
{
|
||||
struct slot *slot = hotplug_slot->private;
|
||||
|
@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
|
|||
}
|
||||
|
||||
/* Add slot to our internal list */
|
||||
spin_lock(&list_lock);
|
||||
down_write(&list_rwsem);
|
||||
list_add(&slot->slot_list, &slot_list);
|
||||
slots++;
|
||||
spin_unlock(&list_lock);
|
||||
up_write(&list_rwsem);
|
||||
}
|
||||
return 0;
|
||||
error_name:
|
||||
|
@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
|
|||
struct list_head *next;
|
||||
int status;
|
||||
|
||||
spin_lock(&list_lock);
|
||||
down_write(&list_rwsem);
|
||||
if(!slots) {
|
||||
spin_unlock(&list_lock);
|
||||
up_write(&list_rwsem);
|
||||
return -1;
|
||||
}
|
||||
list_for_each_safe(tmp, next, &slot_list) {
|
||||
|
@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
|
|||
slots--;
|
||||
}
|
||||
}
|
||||
spin_unlock(&list_lock);
|
||||
up_write(&list_rwsem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -347,7 +368,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
|
|||
}
|
||||
|
||||
/*
|
||||
* According to PICMG 2.12 R2.0, section 6.3.2, upon
|
||||
* According to PICMG 2.1 R2.0, section 6.3.2, upon
|
||||
* initialization, the system driver shall clear the
|
||||
* INS bits of the cold-inserted devices.
|
||||
*/
|
||||
|
@ -359,9 +380,9 @@ init_slots(void)
|
|||
struct pci_dev* dev;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
spin_lock(&list_lock);
|
||||
down_read(&list_rwsem);
|
||||
if(!slots) {
|
||||
spin_unlock(&list_lock);
|
||||
up_read(&list_rwsem);
|
||||
return -1;
|
||||
}
|
||||
list_for_each(tmp, &slot_list) {
|
||||
|
@ -386,7 +407,7 @@ init_slots(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&list_lock);
|
||||
up_read(&list_rwsem);
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
@ -398,10 +419,11 @@ check_slots(void)
|
|||
struct list_head *tmp;
|
||||
int extracted;
|
||||
int inserted;
|
||||
u16 hs_csr;
|
||||
|
||||
spin_lock(&list_lock);
|
||||
down_read(&list_rwsem);
|
||||
if(!slots) {
|
||||
spin_unlock(&list_lock);
|
||||
up_read(&list_rwsem);
|
||||
err("no slots registered, shutting down");
|
||||
return -1;
|
||||
}
|
||||
|
@ -411,8 +433,6 @@ check_slots(void)
|
|||
dbg("%s - looking at slot %s",
|
||||
__FUNCTION__, slot->hotplug_slot->name);
|
||||
if(cpci_check_and_clear_ins(slot)) {
|
||||
u16 hs_csr;
|
||||
|
||||
/* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
|
||||
if(slot->dev) {
|
||||
warn("slot %s already inserted", slot->hotplug_slot->name);
|
||||
|
@ -462,8 +482,6 @@ check_slots(void)
|
|||
|
||||
inserted++;
|
||||
} else if(cpci_check_ext(slot)) {
|
||||
u16 hs_csr;
|
||||
|
||||
/* Process extraction request */
|
||||
dbg("%s - slot %s extracted",
|
||||
__FUNCTION__, slot->hotplug_slot->name);
|
||||
|
@ -476,20 +494,40 @@ check_slots(void)
|
|||
if(!slot->extracting) {
|
||||
if(update_latch_status(slot->hotplug_slot, 0)) {
|
||||
warn("failure to update latch file");
|
||||
|
||||
}
|
||||
atomic_inc(&extracting);
|
||||
slot->extracting = 1;
|
||||
}
|
||||
extracted++;
|
||||
} else if(slot->extracting) {
|
||||
hs_csr = cpci_get_hs_csr(slot);
|
||||
if(hs_csr == 0xffff) {
|
||||
/*
|
||||
* Hmmm, we're likely hosed at this point, should we
|
||||
* bother trying to tell the driver or not?
|
||||
*/
|
||||
err("card in slot %s was improperly removed",
|
||||
slot->hotplug_slot->name);
|
||||
if(update_adapter_status(slot->hotplug_slot, 0)) {
|
||||
warn("failure to update adapter file");
|
||||
}
|
||||
slot->extracting = 0;
|
||||
atomic_dec(&extracting);
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&list_lock);
|
||||
up_read(&list_rwsem);
|
||||
dbg("inserted=%d, extracted=%d, extracting=%d",
|
||||
inserted, extracted, atomic_read(&extracting));
|
||||
if(inserted || extracted) {
|
||||
return extracted;
|
||||
}
|
||||
else {
|
||||
else if(!atomic_read(&extracting)) {
|
||||
err("cannot find ENUM# source, shutting down");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is the interrupt mode worker thread body */
|
||||
|
@ -497,8 +535,6 @@ static int
|
|||
event_thread(void *data)
|
||||
{
|
||||
int rc;
|
||||
struct slot *slot;
|
||||
struct list_head *tmp;
|
||||
|
||||
lock_kernel();
|
||||
daemonize("cpci_hp_eventd");
|
||||
|
@ -512,39 +548,22 @@ event_thread(void *data)
|
|||
thread_finished);
|
||||
if(thread_finished || signal_pending(current))
|
||||
break;
|
||||
while(controller->ops->query_enum()) {
|
||||
do {
|
||||
rc = check_slots();
|
||||
if (rc > 0)
|
||||
if (rc > 0) {
|
||||
/* Give userspace a chance to handle extraction */
|
||||
msleep(500);
|
||||
else if (rc < 0) {
|
||||
} else if (rc < 0) {
|
||||
dbg("%s - error checking slots", __FUNCTION__);
|
||||
thread_finished = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Check for someone yanking out a board */
|
||||
list_for_each(tmp, &slot_list) {
|
||||
slot = list_entry(tmp, struct slot, slot_list);
|
||||
if(slot->extracting) {
|
||||
/*
|
||||
* Hmmm, we're likely hosed at this point, should we
|
||||
* bother trying to tell the driver or not?
|
||||
*/
|
||||
err("card in slot %s was improperly removed",
|
||||
slot->hotplug_slot->name);
|
||||
if(update_adapter_status(slot->hotplug_slot, 0)) {
|
||||
warn("failure to update adapter file");
|
||||
}
|
||||
slot->extracting = 0;
|
||||
}
|
||||
}
|
||||
} while(atomic_read(&extracting) != 0);
|
||||
|
||||
/* Re-enable ENUM# interrupt */
|
||||
dbg("%s - re-enabling irq", __FUNCTION__);
|
||||
controller->ops->enable_irq();
|
||||
}
|
||||
|
||||
dbg("%s - event thread signals exit", __FUNCTION__);
|
||||
up(&thread_exit);
|
||||
return 0;
|
||||
|
@ -555,8 +574,6 @@ static int
|
|||
poll_thread(void *data)
|
||||
{
|
||||
int rc;
|
||||
struct slot *slot;
|
||||
struct list_head *tmp;
|
||||
|
||||
lock_kernel();
|
||||
daemonize("cpci_hp_polld");
|
||||
|
@ -565,35 +582,19 @@ poll_thread(void *data)
|
|||
while(1) {
|
||||
if(thread_finished || signal_pending(current))
|
||||
break;
|
||||
|
||||
while(controller->ops->query_enum()) {
|
||||
rc = check_slots();
|
||||
if(rc > 0)
|
||||
/* Give userspace a chance to handle extraction */
|
||||
msleep(500);
|
||||
else if (rc < 0) {
|
||||
dbg("%s - error checking slots", __FUNCTION__);
|
||||
thread_finished = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Check for someone yanking out a board */
|
||||
list_for_each(tmp, &slot_list) {
|
||||
slot = list_entry(tmp, struct slot, slot_list);
|
||||
if(slot->extracting) {
|
||||
/*
|
||||
* Hmmm, we're likely hosed at this point, should we
|
||||
* bother trying to tell the driver or not?
|
||||
*/
|
||||
err("card in slot %s was improperly removed",
|
||||
slot->hotplug_slot->name);
|
||||
if(update_adapter_status(slot->hotplug_slot, 0)) {
|
||||
warn("failure to update adapter file");
|
||||
if(controller->ops->query_enum()) {
|
||||
do {
|
||||
rc = check_slots();
|
||||
if(rc > 0) {
|
||||
/* Give userspace a chance to handle extraction */
|
||||
msleep(500);
|
||||
} else if(rc < 0) {
|
||||
dbg("%s - error checking slots", __FUNCTION__);
|
||||
thread_finished = 1;
|
||||
break;
|
||||
}
|
||||
slot->extracting = 0;
|
||||
}
|
||||
} while(atomic_read(&extracting) != 0);
|
||||
}
|
||||
|
||||
msleep(100);
|
||||
}
|
||||
dbg("poll thread signals exit");
|
||||
|
@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
|
|||
int status = 0;
|
||||
|
||||
if(controller) {
|
||||
if(atomic_read(&extracting) != 0) {
|
||||
return -EBUSY;
|
||||
}
|
||||
if(!thread_finished) {
|
||||
cpci_stop_thread();
|
||||
}
|
||||
|
@ -691,12 +695,12 @@ cpci_hp_start(void)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock(&list_lock);
|
||||
if(!slots) {
|
||||
spin_unlock(&list_lock);
|
||||
down_read(&list_rwsem);
|
||||
if(list_empty(&slot_list)) {
|
||||
up_read(&list_rwsem);
|
||||
return -ENODEV;
|
||||
}
|
||||
spin_unlock(&list_lock);
|
||||
up_read(&list_rwsem);
|
||||
|
||||
if(first) {
|
||||
status = init_slots();
|
||||
|
@ -727,7 +731,9 @@ cpci_hp_stop(void)
|
|||
if(!controller) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if(atomic_read(&extracting) != 0) {
|
||||
return -EBUSY;
|
||||
}
|
||||
if(controller->irq) {
|
||||
/* Stop enum interrupt processing */
|
||||
dbg("%s - disabling irq", __FUNCTION__);
|
||||
|
@ -747,7 +753,7 @@ cleanup_slots(void)
|
|||
* Unregister all of our slots with the pci_hotplug subsystem,
|
||||
* and free up all memory that we had allocated.
|
||||
*/
|
||||
spin_lock(&list_lock);
|
||||
down_write(&list_rwsem);
|
||||
if(!slots) {
|
||||
goto null_cleanup;
|
||||
}
|
||||
|
@ -761,17 +767,14 @@ cleanup_slots(void)
|
|||
kfree(slot);
|
||||
}
|
||||
null_cleanup:
|
||||
spin_unlock(&list_lock);
|
||||
up_write(&list_rwsem);
|
||||
return;
|
||||
}
|
||||
|
||||
int __init
|
||||
cpci_hotplug_init(int debug)
|
||||
{
|
||||
spin_lock_init(&list_lock);
|
||||
cpci_debug = debug;
|
||||
|
||||
info(DRIVER_DESC " version: " DRIVER_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,7 @@
|
|||
#include "pci_hotplug.h"
|
||||
#include "cpci_hotplug.h"
|
||||
|
||||
#if !defined(MODULE)
|
||||
#define MY_NAME "cpci_hotplug"
|
||||
#else
|
||||
#define MY_NAME THIS_MODULE->name
|
||||
#endif
|
||||
|
||||
extern int cpci_debug;
|
||||
|
||||
|
@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot)
|
|||
return hs_csr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
|
||||
{
|
||||
int hs_cap;
|
||||
u16 new_hs_csr;
|
||||
|
||||
hs_cap = pci_bus_find_capability(slot->bus,
|
||||
slot->devfn,
|
||||
PCI_CAP_ID_CHSWP);
|
||||
if(!hs_cap) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
/* Write out the new value */
|
||||
if(pci_bus_write_config_word(slot->bus,
|
||||
slot->devfn,
|
||||
hs_cap + 2,
|
||||
hs_csr)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
/* Read back what we just wrote out */
|
||||
if(pci_bus_read_config_word(slot->bus,
|
||||
slot->devfn,
|
||||
hs_cap + 2,
|
||||
&new_hs_csr)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
return new_hs_csr;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cpci_check_and_clear_ins(struct slot* slot)
|
||||
{
|
||||
int hs_cap;
|
||||
|
@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot)
|
|||
return -ENODEV;
|
||||
}
|
||||
if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
|
||||
/* Set LOO */
|
||||
hs_csr |= HS_CSR_LOO;
|
||||
if(pci_bus_write_config_word(slot->bus,
|
||||
slot->devfn,
|
||||
|
@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot)
|
|||
return -ENODEV;
|
||||
}
|
||||
if(hs_csr & HS_CSR_LOO) {
|
||||
/* Clear LOO */
|
||||
hs_csr &= ~HS_CSR_LOO;
|
||||
if(pci_bus_write_config_word(slot->bus,
|
||||
slot->devfn,
|
||||
|
@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot)
|
|||
* Device configuration functions
|
||||
*/
|
||||
|
||||
static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
|
||||
static void cpci_enable_device(struct pci_dev *dev)
|
||||
{
|
||||
u8 irq_pin;
|
||||
int r;
|
||||
struct pci_bus *bus;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
|
||||
/* NOTE: device already setup from prior scan */
|
||||
|
||||
/* FIXME: How would we know if we need to enable the expansion ROM? */
|
||||
pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
|
||||
|
||||
/* Assign resources */
|
||||
dbg("assigning resources for %02x:%02x.%x",
|
||||
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
|
||||
for (r = 0; r < 6; r++) {
|
||||
struct resource *res = dev->resource + r;
|
||||
if(res->flags)
|
||||
pci_assign_resource(dev, r);
|
||||
}
|
||||
dbg("finished assigning resources for %02x:%02x.%x",
|
||||
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
|
||||
|
||||
/* Does this function have an interrupt at all? */
|
||||
dbg("checking for function interrupt");
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
|
||||
if(irq_pin) {
|
||||
dbg("function uses interrupt pin %d", irq_pin);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to explicitly set irq field to 0 so that it'll get assigned
|
||||
* by the pcibios platform dependent code called by pci_enable_device.
|
||||
*/
|
||||
dev->irq = 0;
|
||||
|
||||
dbg("enabling device");
|
||||
pci_enable_device(dev); /* XXX check return */
|
||||
dbg("now dev->irq = %d", dev->irq);
|
||||
if(irq_pin && dev->irq) {
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
}
|
||||
|
||||
/* Can't use pci_insert_device at the moment, do it manually for now */
|
||||
pci_proc_attach_device(dev);
|
||||
dbg("notifying drivers");
|
||||
//pci_announce_device_to_drivers(dev);
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
|
||||
{
|
||||
int rc;
|
||||
struct pci_bus* child;
|
||||
struct resource* r;
|
||||
u8 max, n;
|
||||
u16 command;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
|
||||
/* Do basic bridge initialization */
|
||||
rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
|
||||
if(rc) {
|
||||
printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
|
||||
}
|
||||
rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
|
||||
if(rc) {
|
||||
printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
|
||||
}
|
||||
rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
|
||||
if(rc) {
|
||||
printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set parent bridge's subordinate field so that configuration space
|
||||
* access will work in pci_scan_bridge and friends.
|
||||
*/
|
||||
max = pci_max_busnr();
|
||||
bus->subordinate = max + 1;
|
||||
pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
|
||||
|
||||
/* Scan behind bridge */
|
||||
n = pci_scan_bridge(bus, dev, max, 2);
|
||||
child = pci_find_bus(0, max + 1);
|
||||
if (!child)
|
||||
return -ENODEV;
|
||||
pci_proc_attach_bus(child);
|
||||
|
||||
/*
|
||||
* Update parent bridge's subordinate field if there were more bridges
|
||||
* behind the bridge that was scanned.
|
||||
*/
|
||||
if(n > max) {
|
||||
bus->subordinate = n;
|
||||
pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the bridge resources of the bridge to accommodate devices
|
||||
* behind it.
|
||||
*/
|
||||
pci_bus_size_bridges(child);
|
||||
pci_bus_assign_resources(child);
|
||||
|
||||
/* Enable resource mapping via command register */
|
||||
command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
|
||||
r = child->resource[0];
|
||||
if(r && r->start) {
|
||||
command |= PCI_COMMAND_IO;
|
||||
}
|
||||
r = child->resource[1];
|
||||
if(r && r->start) {
|
||||
command |= PCI_COMMAND_MEMORY;
|
||||
}
|
||||
r = child->resource[2];
|
||||
if(r && r->start) {
|
||||
command |= PCI_COMMAND_MEMORY;
|
||||
}
|
||||
rc = pci_write_config_word(dev, PCI_COMMAND, command);
|
||||
if(rc) {
|
||||
err("Error setting command register");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set bridge control register */
|
||||
command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
|
||||
rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
|
||||
if(rc) {
|
||||
err("Error setting bridge control register");
|
||||
return rc;
|
||||
}
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
|
||||
struct pci_bus_wrapped *wrapped_bus)
|
||||
{
|
||||
int rc;
|
||||
struct pci_dev *dev = wrapped_dev->dev;
|
||||
struct pci_bus *bus = wrapped_bus->bus;
|
||||
struct slot* slot;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
|
||||
/*
|
||||
* We need to fix up the hotplug representation with the Linux
|
||||
* representation.
|
||||
*/
|
||||
if(wrapped_dev->data) {
|
||||
slot = (struct slot*) wrapped_dev->data;
|
||||
slot->dev = dev;
|
||||
}
|
||||
|
||||
/* If it's a bridge, scan behind it for devices */
|
||||
pci_enable_device(dev);
|
||||
if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
rc = cpci_configure_bridge(bus, dev);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Actually configure device */
|
||||
if(dev) {
|
||||
rc = cpci_configure_dev(bus, dev);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
|
||||
struct pci_bus_wrapped *wrapped_bus)
|
||||
{
|
||||
struct pci_dev *dev = wrapped_dev->dev;
|
||||
struct slot* slot;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
if(!dev)
|
||||
return -ENODEV;
|
||||
|
||||
/* Remove the Linux representation */
|
||||
if(pci_remove_device_safe(dev)) {
|
||||
err("Could not remove device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now remove the hotplug representation.
|
||||
*/
|
||||
if(wrapped_dev->data) {
|
||||
slot = (struct slot*) wrapped_dev->data;
|
||||
slot->dev = NULL;
|
||||
} else {
|
||||
dbg("No hotplug representation for %02x:%02x.%x",
|
||||
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
|
||||
}
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
|
||||
struct pci_dev_wrapped *wrapped_dev)
|
||||
{
|
||||
struct pci_bus *bus = wrapped_bus->bus;
|
||||
struct pci_bus *parent = bus->self->bus;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
|
||||
/* The cleanup code for proc entries regarding buses should be in the kernel... */
|
||||
if(bus->procdir)
|
||||
dbg("detach_pci_bus %s", bus->procdir->name);
|
||||
pci_proc_detach_bus(bus);
|
||||
|
||||
/* The cleanup code should live in the kernel... */
|
||||
bus->self->subordinate = NULL;
|
||||
|
||||
/* unlink from parent bus */
|
||||
list_del(&bus->node);
|
||||
|
||||
/* Now, remove */
|
||||
if(bus)
|
||||
kfree(bus);
|
||||
|
||||
/* Update parent's subordinate field */
|
||||
if(parent) {
|
||||
u8 n = pci_bus_max_busnr(parent);
|
||||
if(n < parent->subordinate) {
|
||||
parent->subordinate = n;
|
||||
pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
|
||||
bus = dev->subordinate;
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
cpci_enable_device(dev);
|
||||
}
|
||||
}
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pci_visit configure_functions = {
|
||||
.visit_pci_dev = configure_visit_pci_dev,
|
||||
};
|
||||
|
||||
static struct pci_visit unconfigure_functions_phase2 = {
|
||||
.post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
|
||||
.post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
|
||||
};
|
||||
|
||||
|
||||
int cpci_configure_slot(struct slot* slot)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned char busnr;
|
||||
struct pci_bus *child;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
|
||||
|
@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot)
|
|||
slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
|
||||
if(slot->dev == NULL) {
|
||||
err("Could not find PCI device for slot %02x", slot->number);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
dbg("slot->dev = %p", slot->dev);
|
||||
if(slot->dev) {
|
||||
struct pci_dev *dev;
|
||||
struct pci_dev_wrapped wrapped_dev;
|
||||
struct pci_bus_wrapped wrapped_bus;
|
||||
int i;
|
||||
|
||||
memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
|
||||
memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
dev = pci_find_slot(slot->bus->number,
|
||||
PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
|
||||
if(!dev)
|
||||
continue;
|
||||
wrapped_dev.dev = dev;
|
||||
wrapped_bus.bus = slot->dev->bus;
|
||||
if(i)
|
||||
wrapped_dev.data = NULL;
|
||||
else
|
||||
wrapped_dev.data = (void*) slot;
|
||||
rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
dbg("%s - exit, rc = %d", __FUNCTION__, rc);
|
||||
return rc;
|
||||
if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr);
|
||||
child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr);
|
||||
pci_do_scan_bus(child);
|
||||
pci_bus_size_bridges(child);
|
||||
}
|
||||
|
||||
pci_bus_assign_resources(slot->dev->bus);
|
||||
|
||||
cpci_enable_device(slot->dev);
|
||||
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpci_unconfigure_slot(struct slot* slot)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
struct pci_dev_wrapped wrapped_dev;
|
||||
struct pci_bus_wrapped wrapped_bus;
|
||||
struct pci_dev *dev;
|
||||
|
||||
dbg("%s - enter", __FUNCTION__);
|
||||
|
||||
if(!slot->dev) {
|
||||
err("No device for slot %02x\n", slot->number);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
|
||||
memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
dev = pci_find_slot(slot->bus->number,
|
||||
PCI_DEVFN(PCI_SLOT(slot->devfn), i));
|
||||
if(dev) {
|
||||
wrapped_dev.dev = dev;
|
||||
wrapped_bus.bus = dev->bus;
|
||||
if(i)
|
||||
wrapped_dev.data = NULL;
|
||||
else
|
||||
wrapped_dev.data = (void*) slot;
|
||||
dbg("%s - unconfigure phase 2", __FUNCTION__);
|
||||
rc = pci_visit_dev(&unconfigure_functions_phase2,
|
||||
&wrapped_dev,
|
||||
&wrapped_bus);
|
||||
if(rc)
|
||||
break;
|
||||
pci_remove_bus_device(dev);
|
||||
slot->dev = NULL;
|
||||
}
|
||||
}
|
||||
dbg("%s - exit, rc = %d", __FUNCTION__, rc);
|
||||
return rc;
|
||||
dbg("%s - exit", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -130,6 +130,7 @@ struct controller {
|
|||
u8 slot_bus; /* Bus where the slots handled by this controller sit */
|
||||
u8 ctrlcap;
|
||||
u16 vendor_id;
|
||||
u8 cap_base;
|
||||
};
|
||||
|
||||
struct irq_mapping {
|
||||
|
|
|
@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev)
|
|||
static struct pcie_port_service_id port_pci_ids[] = { {
|
||||
.vendor = PCI_ANY_ID,
|
||||
.device = PCI_ANY_ID,
|
||||
.port_type = PCIE_RC_PORT,
|
||||
.port_type = PCIE_ANY_PORT,
|
||||
.service_type = PCIE_PORT_SERVICE_HP,
|
||||
.driver_data = 0,
|
||||
}, { /* end: all zeroes */ }
|
||||
|
|
|
@ -109,20 +109,20 @@ enum ctrl_offsets {
|
|||
};
|
||||
static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */
|
||||
|
||||
#define PCIE_CAP_ID ( pcie_cap_base + PCIECAPID )
|
||||
#define NXT_CAP_PTR ( pcie_cap_base + NXTCAPPTR )
|
||||
#define CAP_REG ( pcie_cap_base + CAPREG )
|
||||
#define DEV_CAP ( pcie_cap_base + DEVCAP )
|
||||
#define DEV_CTRL ( pcie_cap_base + DEVCTRL )
|
||||
#define DEV_STATUS ( pcie_cap_base + DEVSTATUS )
|
||||
#define LNK_CAP ( pcie_cap_base + LNKCAP )
|
||||
#define LNK_CTRL ( pcie_cap_base + LNKCTRL )
|
||||
#define LNK_STATUS ( pcie_cap_base + LNKSTATUS )
|
||||
#define SLOT_CAP ( pcie_cap_base + SLOTCAP )
|
||||
#define SLOT_CTRL ( pcie_cap_base + SLOTCTRL )
|
||||
#define SLOT_STATUS ( pcie_cap_base + SLOTSTATUS )
|
||||
#define ROOT_CTRL ( pcie_cap_base + ROOTCTRL )
|
||||
#define ROOT_STATUS ( pcie_cap_base + ROOTSTATUS )
|
||||
#define PCIE_CAP_ID(cb) ( cb + PCIECAPID )
|
||||
#define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR )
|
||||
#define CAP_REG(cb) ( cb + CAPREG )
|
||||
#define DEV_CAP(cb) ( cb + DEVCAP )
|
||||
#define DEV_CTRL(cb) ( cb + DEVCTRL )
|
||||
#define DEV_STATUS(cb) ( cb + DEVSTATUS )
|
||||
#define LNK_CAP(cb) ( cb + LNKCAP )
|
||||
#define LNK_CTRL(cb) ( cb + LNKCTRL )
|
||||
#define LNK_STATUS(cb) ( cb + LNKSTATUS )
|
||||
#define SLOT_CAP(cb) ( cb + SLOTCAP )
|
||||
#define SLOT_CTRL(cb) ( cb + SLOTCTRL )
|
||||
#define SLOT_STATUS(cb) ( cb + SLOTSTATUS )
|
||||
#define ROOT_CTRL(cb) ( cb + ROOTCTRL )
|
||||
#define ROOT_STATUS(cb) ( cb + ROOTSTATUS )
|
||||
|
||||
#define hp_register_read_word(pdev, reg , value) \
|
||||
pci_read_config_word(pdev, reg, &value)
|
||||
|
@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
return retval;
|
||||
|
@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
|
|||
}
|
||||
|
||||
dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
|
||||
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE);
|
||||
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
|
||||
if (retval) {
|
||||
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return retval;
|
||||
|
@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
|
||||
|
@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return retval;
|
||||
}
|
||||
|
||||
dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl);
|
||||
dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
|
||||
|
||||
|
@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return retval;
|
||||
}
|
||||
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
|
||||
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
|
||||
|
||||
|
@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
|
@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
|
@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
|
@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
|
|||
err("%s: Invalid HPC slot number!\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
|
@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
|
|||
slot_cmd = slot_cmd | HP_INTR_ENABLE;
|
||||
|
||||
pcie_write_cmd(slot, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot)
|
|||
return ;
|
||||
}
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
|
@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot)
|
|||
|
||||
pcie_write_cmd(slot, slot_cmd);
|
||||
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot)
|
|||
return ;
|
||||
}
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
|
@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot)
|
|||
if (!pciehp_poll_mode)
|
||||
slot_cmd = slot_cmd | HP_INTR_ENABLE;
|
||||
pcie_write_cmd(slot, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
|
|||
return ;
|
||||
}
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
|
@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
|
|||
slot_cmd = slot_cmd | HP_INTR_ENABLE;
|
||||
pcie_write_cmd(slot, slot_cmd);
|
||||
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl,
|
|||
*first_device_num = 0;
|
||||
*num_ctlr_slots = 1;
|
||||
|
||||
rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
|
||||
rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
|
||||
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
|
||||
|
@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return retval;
|
||||
}
|
||||
dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL,
|
||||
dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
|
||||
slot_ctrl);
|
||||
|
||||
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
|
||||
|
@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot)
|
|||
err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
|
||||
return -1;
|
||||
}
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
|
||||
|
||||
DBG_LEAVE_ROUTINE
|
||||
|
||||
|
@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot)
|
|||
err("%s: Invalid HPC slot number!\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return retval;
|
||||
}
|
||||
dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL,
|
||||
dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
|
||||
slot_ctrl);
|
||||
|
||||
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
|
||||
|
@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot)
|
|||
err("%s: Write command failed!\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
|
||||
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
|
||||
|
||||
DBG_LEAVE_ROUTINE
|
||||
|
||||
|
@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
|
|||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
|
@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
|
|||
dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
|
||||
/* Mask Hot-plug Interrupt Enable */
|
||||
if (!pciehp_poll_mode) {
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
|
@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
|
|||
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
|
||||
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
|
||||
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
|
@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
|
|||
|
||||
/* Clear command complete interrupt caused by this write */
|
||||
temp_word = 0x1f;
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
|
@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
|
|||
|
||||
/* Clear all events after serving them */
|
||||
temp_word = 0x1F;
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
/* Unmask Hot-plug Interrupt Enable */
|
||||
if (!pciehp_poll_mode) {
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
|
@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
|
|||
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
|
||||
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
|
||||
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
|
@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
|
|||
|
||||
/* Clear command complete interrupt caused by this write */
|
||||
temp_word = 0x1F;
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
return IRQ_NONE;
|
||||
|
@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
|
||||
retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
|
||||
|
@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
|
||||
retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
|
||||
|
@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
|
||||
|
@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value
|
|||
return -1;
|
||||
}
|
||||
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
|
||||
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
|
||||
|
||||
if (retval) {
|
||||
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
|
||||
|
@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl,
|
|||
goto abort_free_ctlr;
|
||||
}
|
||||
|
||||
pcie_cap_base = cap_base;
|
||||
ctrl->cap_base = cap_base;
|
||||
|
||||
dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
|
||||
|
||||
rc = hp_register_read_word(pdev, CAP_REG, cap_reg);
|
||||
rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg);
|
||||
dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg);
|
||||
|
||||
if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){
|
||||
if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040)
|
||||
&& ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
|
||||
dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
|
||||
rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
|
||||
rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap);
|
||||
dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap);
|
||||
|
||||
if (!(slot_cap & HP_CAP)) {
|
||||
dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
/* For debugging purpose */
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
|
||||
dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
|
||||
dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
|
||||
|
||||
if (first) {
|
||||
spin_lock_init(&hpc_event_lock);
|
||||
|
@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl,
|
|||
php_ctlr->num_slots = 1;
|
||||
|
||||
/* Mask Hot-plug Interrupt Enable */
|
||||
rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
|
||||
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
|
||||
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
|
||||
|
||||
rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
|
||||
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
|
||||
dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
|
||||
, slot_status);
|
||||
|
||||
temp_word = 0x1F; /* Clear all events */
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
|
||||
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
|
||||
|
||||
if (pciehp_poll_mode) {/* Install interrupt polling code */
|
||||
/* Install and start the interrupt polling timer */
|
||||
|
@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl,
|
|||
}
|
||||
}
|
||||
|
||||
rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
|
||||
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
|
||||
|
||||
intr_enable = intr_enable | PRSN_DETECT_ENABLE;
|
||||
|
@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl,
|
|||
dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
|
||||
|
||||
/* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
|
||||
rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
|
||||
rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
|
||||
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
if (rc) {
|
||||
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
|
||||
SLOT_STATUS, slot_status);
|
||||
SLOT_STATUS(ctrl->cap_base), slot_status);
|
||||
|
||||
temp_word = 0x1F; /* Clear all events */
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
|
||||
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
|
||||
if (rc) {
|
||||
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
|
||||
goto abort_free_ctlr;
|
||||
}
|
||||
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
|
||||
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
|
||||
|
||||
/* Add this HPC instance into the HPC list */
|
||||
spin_lock(&list_lock);
|
||||
|
|
|
@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
|
|||
*/
|
||||
static void release_slot(struct hotplug_slot *hotplug_slot)
|
||||
{
|
||||
struct slot *slot = (struct slot *)hotplug_slot->private;
|
||||
struct slot *slot = hotplug_slot->private;
|
||||
|
||||
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
|
||||
|
||||
|
|
|
@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot)
|
|||
func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
|
||||
if (!func) {
|
||||
dbg("%s: Error! slot NULL\n", __FUNCTION__);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Check to see if (latch closed, card present, power off) */
|
||||
|
@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot)
|
|||
if (rc || !getstatus) {
|
||||
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
|
||||
if (rc || getstatus) {
|
||||
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
|
||||
if (rc || getstatus) {
|
||||
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
|
||||
|
@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot)
|
|||
|
||||
func = shpchp_slot_create(p_slot->bus);
|
||||
if (func == NULL)
|
||||
return 1;
|
||||
return -ENOMEM;
|
||||
|
||||
func->bus = p_slot->bus;
|
||||
func->device = p_slot->device;
|
||||
|
@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot)
|
|||
/* Setup slot structure with entry for empty slot */
|
||||
func = shpchp_slot_create(p_slot->bus);
|
||||
if (func == NULL)
|
||||
return (1); /* Out of memory */
|
||||
return -ENOMEM; /* Out of memory */
|
||||
|
||||
func->bus = p_slot->bus;
|
||||
func->device = p_slot->device;
|
||||
|
@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot)
|
|||
struct pci_func *func;
|
||||
|
||||
if (!p_slot->ctrl)
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
|
||||
pci_bus = p_slot->ctrl->pci_dev->subordinate;
|
||||
|
||||
|
@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot)
|
|||
if (ret || !getstatus) {
|
||||
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
|
||||
if (ret || getstatus) {
|
||||
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
|
||||
if (ret || !getstatus) {
|
||||
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
up(&p_slot->ctrl->crit_sect);
|
||||
|
||||
|
@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot)
|
|||
/* Check the Class Code */
|
||||
rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
|
||||
if (rc)
|
||||
return rc;
|
||||
return -ENODEV;
|
||||
|
||||
if (class_code == PCI_BASE_CLASS_DISPLAY) {
|
||||
/* Display/Video adapter (not supported) */
|
||||
|
@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot)
|
|||
/* See if it's a bridge */
|
||||
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
|
||||
if (rc)
|
||||
return rc;
|
||||
return -ENODEV;
|
||||
|
||||
/* If it's a bridge, check the VGA Enable bit */
|
||||
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
|
||||
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
|
||||
if (rc)
|
||||
return rc;
|
||||
return -ENODEV;
|
||||
|
||||
/* If the VGA Enable bit is set, remove isn't supported */
|
||||
if (BCR & PCI_BRIDGE_CTL_VGA) {
|
||||
|
@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot)
|
|||
if ((func != NULL) && !rc) {
|
||||
rc = remove_board(func, p_slot->ctrl);
|
||||
} else if (!rc)
|
||||
rc = 1;
|
||||
rc = -ENODEV;
|
||||
|
||||
if (p_slot)
|
||||
update_slot_info(p_slot);
|
||||
|
||||
return(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf)
|
|||
return (str - buf);
|
||||
}
|
||||
|
||||
static ssize_t modalias_show(struct device *dev, char *buf)
|
||||
{
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
|
||||
return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
|
||||
pci_dev->vendor, pci_dev->device,
|
||||
pci_dev->subsystem_vendor, pci_dev->subsystem_device,
|
||||
(u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
|
||||
(u8)(pci_dev->class));
|
||||
}
|
||||
|
||||
struct device_attribute pci_dev_attrs[] = {
|
||||
__ATTR_RO(resource),
|
||||
__ATTR_RO(vendor),
|
||||
|
@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = {
|
|||
__ATTR_RO(class),
|
||||
__ATTR_RO(irq),
|
||||
__ATTR_RO(local_cpus),
|
||||
__ATTR_RO(modalias),
|
||||
__ATTR_NULL,
|
||||
};
|
||||
|
||||
|
|
|
@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void);
|
|||
extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
|
||||
extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
|
||||
|
||||
struct pci_dev_wrapped {
|
||||
struct pci_dev *dev;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct pci_bus_wrapped {
|
||||
struct pci_bus *bus;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct pci_visit {
|
||||
int (* pre_visit_pci_bus) (struct pci_bus_wrapped *,
|
||||
struct pci_dev_wrapped *);
|
||||
int (* post_visit_pci_bus) (struct pci_bus_wrapped *,
|
||||
struct pci_dev_wrapped *);
|
||||
|
||||
int (* pre_visit_pci_dev) (struct pci_dev_wrapped *,
|
||||
struct pci_bus_wrapped *);
|
||||
int (* visit_pci_dev) (struct pci_dev_wrapped *,
|
||||
struct pci_bus_wrapped *);
|
||||
int (* post_visit_pci_dev) (struct pci_dev_wrapped *,
|
||||
struct pci_bus_wrapped *);
|
||||
};
|
||||
|
||||
extern int pci_visit_dev(struct pci_visit *fn,
|
||||
struct pci_dev_wrapped *wrapped_dev,
|
||||
struct pci_bus_wrapped *wrapped_parent);
|
||||
extern void pci_remove_legacy_files(struct pci_bus *bus);
|
||||
|
||||
/* Lock for read/write access to pci device and bus lists */
|
||||
|
|
|
@ -39,7 +39,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
|
|||
driver->id_table->vendor != pciedev->id.vendor) ||
|
||||
(driver->id_table->device != PCI_ANY_ID &&
|
||||
driver->id_table->device != pciedev->id.device) ||
|
||||
driver->id_table->port_type != pciedev->id.port_type ||
|
||||
(driver->id_table->port_type != PCIE_ANY_PORT &&
|
||||
driver->id_table->port_type != pciedev->id.port_type) ||
|
||||
driver->id_table->service_type != pciedev->id.service_type )
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function,
|
|||
int errno)
|
||||
{
|
||||
char nbuf[16];
|
||||
const char *errstr = ext3_decode_error(sb, errno, nbuf);
|
||||
const char *errstr;
|
||||
|
||||
/* Special case: if the error is EROFS, and we're not already
|
||||
* inside a transaction, then there's really no point in logging
|
||||
* an error. */
|
||||
if (errno == -EROFS && journal_current_handle() == NULL &&
|
||||
(sb->s_flags & MS_RDONLY))
|
||||
return;
|
||||
|
||||
errstr = ext3_decode_error(sb, errno, nbuf);
|
||||
printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
|
||||
sb->s_id, function, errstr);
|
||||
|
||||
|
|
|
@ -273,9 +273,6 @@ struct device {
|
|||
BIOS data relevant to device) */
|
||||
struct dev_pm_info power;
|
||||
|
||||
u32 detach_state; /* State to enter when device is
|
||||
detached from its driver. */
|
||||
|
||||
u64 *dma_mask; /* dma mask (if dma'able device) */
|
||||
u64 coherent_dma_mask;/* Like dma_mask, but for
|
||||
alloc_coherent mappings as
|
||||
|
|
|
@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state)
|
|||
goto Unlock;
|
||||
}
|
||||
|
||||
pr_debug("PM: Preparing system for suspend\n");
|
||||
pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
|
||||
if ((error = suspend_prepare(state)))
|
||||
goto Unlock;
|
||||
|
||||
pr_debug("PM: Entering state.\n");
|
||||
pr_debug("PM: Entering %s sleep\n", pm_states[state]);
|
||||
error = suspend_enter(state);
|
||||
|
||||
pr_debug("PM: Finishing up.\n");
|
||||
pr_debug("PM: Finishing wakeup.\n");
|
||||
suspend_finish(state);
|
||||
Unlock:
|
||||
up(&pm_sem);
|
||||
|
|
|
@ -1244,7 +1244,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
addr = mm->free_area_cache;
|
||||
|
||||
/* make sure it can fit in the remaining address space */
|
||||
if (addr >= len) {
|
||||
if (addr > len) {
|
||||
vma = find_vma(mm, addr-len);
|
||||
if (!vma || addr <= vma->vm_start)
|
||||
/* remember the address as a hint for next time */
|
||||
|
@ -1266,7 +1266,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
|
||||
/* try just below the current vma->vm_start */
|
||||
addr = vma->vm_start-len;
|
||||
} while (len <= vma->vm_start);
|
||||
} while (len < vma->vm_start);
|
||||
|
||||
/*
|
||||
* A failed mmap() very likely causes application failure,
|
||||
|
|
Loading…
Reference in New Issue