Commit 7e298750 authored by Steve French's avatar Steve French
parents b1a45695 49a43876
...@@ -7,7 +7,6 @@ that support it. For example, a given bus might look like this: ...@@ -7,7 +7,6 @@ that support it. For example, a given bus might look like this:
|-- 0000:17:00.0 |-- 0000:17:00.0
| |-- class | |-- class
| |-- config | |-- config
| |-- detach_state
| |-- device | |-- device
| |-- irq | |-- irq
| |-- local_cpus | |-- local_cpus
...@@ -19,7 +18,7 @@ that support it. For example, a given bus might look like this: ...@@ -19,7 +18,7 @@ that support it. For example, a given bus might look like this:
| |-- subsystem_device | |-- subsystem_device
| |-- subsystem_vendor | |-- subsystem_vendor
| `-- vendor | `-- vendor
`-- detach_state `-- ...
The topmost element describes the PCI domain and bus number. In this case, 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). 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. ...@@ -31,7 +30,6 @@ files, each with their own function.
---- -------- ---- --------
class PCI class (ascii, ro) class PCI class (ascii, ro)
config PCI config space (binary, rw) config PCI config space (binary, rw)
detach_state connection status (bool, rw)
device PCI device (ascii, ro) device PCI device (ascii, ro)
irq IRQ number (ascii, ro) irq IRQ number (ascii, ro)
local_cpus nearby CPU mask (cpumask, ro) local_cpus nearby CPU mask (cpumask, ro)
......
...@@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event ...@@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
#READY_AFTER_RESUME #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 pm_message_t meaning
......
...@@ -348,7 +348,7 @@ looks like the following: ...@@ -348,7 +348,7 @@ looks like the following:
Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
. current_vty devspec name partner_vtys . current_vty devspec name partner_vtys
.. detach_state index partner_clcs vterm_state .. index partner_clcs vterm_state
Each entry is provided, by default with a "name" attribute. Reading the Each entry is provided, by default with a "name" attribute. Reading the
"name" attribute will reveal the device type as shown in the following "name" attribute will reveal the device type as shown in the following
......
# Makefile for the Linux device tree # 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 \ driver.o class.o class_simple.o platform.o \
cpu.o firmware.o init.o map.o dmapool.o \ cpu.o firmware.o init.o map.o dmapool.o \
attribute_container.o transport_class.o attribute_container.o transport_class.o
......
...@@ -390,7 +390,6 @@ void device_release_driver(struct device * dev) ...@@ -390,7 +390,6 @@ void device_release_driver(struct device * dev)
sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
sysfs_remove_link(&dev->kobj, "driver"); sysfs_remove_link(&dev->kobj, "driver");
list_del_init(&dev->driver_list); list_del_init(&dev->driver_list);
device_detach_shutdown(dev);
if (drv->remove) if (drv->remove)
drv->remove(dev); drv->remove(dev);
dev->driver = NULL; dev->driver = NULL;
......
...@@ -31,8 +31,6 @@ int (*platform_notify_remove)(struct device * dev) = 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(obj) container_of(obj, struct device, kobj)
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
extern struct attribute * dev_default_attrs[];
static ssize_t static ssize_t
dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{ {
...@@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj) ...@@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj)
static struct kobj_type ktype_device = { static struct kobj_type ktype_device = {
.release = device_release, .release = device_release,
.sysfs_ops = &dev_sysfs_ops, .sysfs_ops = &dev_sysfs_ops,
.default_attrs = dev_default_attrs,
}; };
......
/*
* 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,
};
enum {
DEVICE_PM_ON,
DEVICE_PM1,
DEVICE_PM2,
DEVICE_PM3,
DEVICE_PM_OFF,
};
/* /*
* shutdown.c * shutdown.c
*/ */
extern int device_detach_shutdown(struct device *);
extern void device_shutdown(void); extern void device_shutdown(void);
......
...@@ -22,8 +22,17 @@ extern int sysdev_resume(void); ...@@ -22,8 +22,17 @@ extern int sysdev_resume(void);
int resume_device(struct device * dev) 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 dev->bus->resume(dev);
}
return 0; return 0;
} }
......
...@@ -19,20 +19,6 @@ ...@@ -19,20 +19,6 @@
extern struct subsystem devices_subsys; 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 * 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 * down last and resume them first. That way, we don't do anything stupid like
...@@ -52,13 +38,12 @@ void device_shutdown(void) ...@@ -52,13 +38,12 @@ void device_shutdown(void)
struct device * dev; struct device * dev;
down_write(&devices_subsys.rwsem); down_write(&devices_subsys.rwsem);
list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) { list_for_each_entry_reverse(dev, &devices_subsys.kset.list,
pr_debug("shutting down %s: ", dev->bus_id); kobj.entry) {
if (dev->driver && dev->driver->shutdown) { if (dev->driver && dev->driver->shutdown) {
pr_debug("Ok\n"); dev_dbg(dev, "shutdown\n");
dev->driver->shutdown(dev); dev->driver->shutdown(dev);
} else }
pr_debug("Ignored.\n");
} }
up_write(&devices_subsys.rwsem); up_write(&devices_subsys.rwsem);
......
...@@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state) ...@@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state)
{ {
int error = 0; 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; 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); error = dev->bus->suspend(dev, state);
}
return error; return error;
} }
......
...@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp, ...@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
{ {
struct block_device *bdev = filp->private_data; 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) static void bind_device(struct raw_config_request *rq)
......
...@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp, ...@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
if ((buffer_size - length <= 0) || (i >= num_envp)) if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM; return -ENOMEM;
envp[i] = NULL; envp[i++] = scratch;
length += scnprintf (scratch, buffer_size - length,
return 0; "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
} pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device,
static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent) (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
{ (u8)(pdev->class));
struct list_head *ln; if ((buffer_size - length <= 0) || (i >= num_envp))
struct pci_dev *dev; return -ENOMEM;
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;
}
/** envp[i] = NULL;
* 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; 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 @@ ...@@ -31,7 +31,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/pci.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_INS 0x0080
#define HS_CSR_EXT 0x0040 #define HS_CSR_EXT 0x0040
#define HS_CSR_PI 0x0030 #define HS_CSR_PI 0x0030
......
...@@ -33,11 +33,11 @@ ...@@ -33,11 +33,11 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <asm/atomic.h>
#include <linux/delay.h> #include <linux/delay.h>
#include "pci_hotplug.h" #include "pci_hotplug.h"
#include "cpci_hotplug.h" #include "cpci_hotplug.h"
#define DRIVER_VERSION "0.2"
#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
#define DRIVER_DESC "CompactPCI Hot Plug Core" #define DRIVER_DESC "CompactPCI Hot Plug Core"
...@@ -54,9 +54,10 @@ ...@@ -54,9 +54,10 @@
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
/* local variables */ /* local variables */
static spinlock_t list_lock; static DECLARE_RWSEM(list_rwsem);
static LIST_HEAD(slot_list); static LIST_HEAD(slot_list);
static int slots; static int slots;
static atomic_t extracting;
int cpci_debug; int cpci_debug;
static struct cpci_hp_controller *controller; static struct cpci_hp_controller *controller;
static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ 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); ...@@ -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 set_attention_status(struct hotplug_slot *slot, u8 value);
static int get_power_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_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 = { static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = { ...@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
.set_attention_status = set_attention_status, .set_attention_status = set_attention_status,
.get_power_status = get_power_status, .get_power_status = get_power_status,
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_adapter_status = get_adapter_status,
.get_latch_status = get_latch_status,
}; };
static int static int
...@@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot) ...@@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot)
warn("failure to update adapter file"); warn("failure to update adapter file");
} }
if(slot->extracting) {
slot->extracting = 0; slot->extracting = 0;
atomic_dec(&extracting);
}
return retval; return retval;
} }
...@@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) ...@@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
return cpci_set_attention_status(hotplug_slot->private, 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) static void release_slot(struct hotplug_slot *hotplug_slot)
{ {
struct slot *slot = hotplug_slot->private; struct slot *slot = hotplug_slot->private;
...@@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) ...@@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
} }
/* Add slot to our internal list */ /* Add slot to our internal list */
spin_lock(&list_lock); down_write(&list_rwsem);
list_add(&slot->slot_list, &slot_list); list_add(&slot->slot_list, &slot_list);
slots++; slots++;
spin_unlock(&list_lock); up_write(&list_rwsem);
} }
return 0; return 0;
error_name: error_name:
...@@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus) ...@@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
struct list_head *next; struct list_head *next;
int status; int status;
spin_lock(&list_lock); down_write(&list_rwsem);
if(!slots) { if(!slots) {
spin_unlock(&list_lock); up_write(&list_rwsem);
return -1; return -1;
} }
list_for_each_safe(tmp, next, &slot_list) { list_for_each_safe(tmp, next, &slot_list) {
...@@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus) ...@@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
slots--; slots--;
} }
} }
spin_unlock(&list_lock); up_write(&list_rwsem);
return 0; return 0;
} }
...@@ -347,7 +368,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) ...@@ -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 * initialization, the system driver shall clear the
* INS bits of the cold-inserted devices. * INS bits of the cold-inserted devices.
*/ */
...@@ -359,9 +380,9 @@ init_slots(void) ...@@ -359,9 +380,9 @@ init_slots(void)
struct pci_dev* dev; struct pci_dev* dev;
dbg("%s - enter", __FUNCTION__); dbg("%s - enter", __FUNCTION__);
spin_lock(&list_lock); down_read(&list_rwsem);
if(!slots) { if(!slots) {
spin_unlock(&list_lock); up_read(&list_rwsem);
return -1; return -1;
} }
list_for_each(tmp, &slot_list) { list_for_each(tmp, &slot_list) {
...@@ -386,7 +407,7 @@ init_slots(void) ...@@ -386,7 +407,7 @@ init_slots(void)
} }
} }
} }
spin_unlock(&list_lock); up_read(&list_rwsem);
dbg("%s - exit", __FUNCTION__); dbg("%s - exit", __FUNCTION__);
return 0; return 0;
} }
...@@ -398,10 +419,11 @@ check_slots(void) ...@@ -398,10 +419,11 @@ check_slots(void)
struct list_head *tmp; struct list_head *tmp;
int extracted; int extracted;
int inserted; int inserted;
u16 hs_csr;
spin_lock(&list_lock); down_read(&list_rwsem);
if(!slots) { if(!slots) {
spin_unlock(&list_lock); up_read(&list_rwsem);
err("no slots registered, shutting down"); err("no slots registered, shutting down");
return -1; return -1;
} }
...@@ -411,8 +433,6 @@ check_slots(void) ...@@ -411,8 +433,6 @@ check_slots(void)
dbg("%s - looking at slot %s", dbg("%s - looking at slot %s",
__FUNCTION__, slot->hotplug_slot->name); __FUNCTION__, slot->hotplug_slot->name);
if(cpci_check_and_clear_ins(slot)) { if(cpci_check_and_clear_ins(slot)) {
u16 hs_csr;
/* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
if(slot->dev) { if(slot->dev) {
warn("slot %s already inserted", slot->hotplug_slot->name); warn("slot %s already inserted", slot->hotplug_slot->name);
...@@ -462,8 +482,6 @@ check_slots(void) ...@@ -462,8 +482,6 @@ check_slots(void)
inserted++; inserted++;
} else if(cpci_check_ext(slot)) { } else if(cpci_check_ext(slot)) {
u16 hs_csr;
/* Process extraction request */ /* Process extraction request */
dbg("%s - slot %s extracted", dbg("%s - slot %s extracted",
__FUNCTION__, slot->hotplug_slot->name); __FUNCTION__, slot->hotplug_slot->name);
...@@ -476,20 +494,40 @@ check_slots(void) ...@@ -476,20 +494,40 @@ check_slots(void)
if(!slot->extracting) { if(!slot->extracting) {
if(update_latch_status(slot->hotplug_slot, 0)) { if(update_latch_status(slot->hotplug_slot, 0)) {
warn("failure to update latch file"); warn("failure to update latch file");
} }
atomic_inc(&extracting);
slot->extracting = 1; slot->extracting = 1;
} }
extracted++; 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) { if(inserted || extracted) {
return extracted; return extracted;
} }
else { else if(!atomic_read(&extracting)) {
err("cannot find ENUM# source, shutting down"); err("cannot find ENUM# source, shutting down");
return -1; return -1;
} }
return 0;
} }
/* This is the interrupt mode worker thread body */ /* This is the interrupt mode worker thread body */
...@@ -497,8 +535,6 @@ static int ...@@ -497,8 +535,6 @@ static int
event_thread(void *data) event_thread(void *data)
{ {
int rc; int rc;
struct slot *slot;
struct list_head *tmp;
lock_kernel(); lock_kernel();
daemonize("cpci_hp_eventd"); daemonize("cpci_hp_eventd");
...@@ -512,39 +548,22 @@ event_thread(void *data) ...@@ -512,39 +548,22 @@ event_thread(void *data)
thread_finished); thread_finished);
if(thread_finished || signal_pending(current)) if(thread_finished || signal_pending(current))
break; break;
while(controller->ops->query_enum()) { do {
rc = check_slots(); rc = check_slots();
if (rc > 0) if (rc > 0) {
/* Give userspace a chance to handle extraction */ /* Give userspace a chance to handle extraction */
msleep(500); msleep(500);
else if (rc < 0) { } else if (rc < 0) {
dbg("%s - error checking slots", __FUNCTION__); dbg("%s - error checking slots", __FUNCTION__);
thread_finished = 1; thread_finished = 1;
break; break;
} }
} } while(atomic_read(&extracting) != 0);
/* 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;
}
}
/* Re-enable ENUM# interrupt */ /* Re-enable ENUM# interrupt */
dbg("%s - re-enabling irq", __FUNCTION__); dbg("%s - re-enabling irq", __FUNCTION__);
controller->ops->enable_irq(); controller->ops->enable_irq();
} }
dbg("%s - event thread signals exit", __FUNCTION__); dbg("%s - event thread signals exit", __FUNCTION__);
up(&thread_exit); up(&thread_exit);
return 0; return 0;
...@@ -555,8 +574,6 @@ static int ...@@ -555,8 +574,6 @@ static int
poll_thread(void *data) poll_thread(void *data)
{ {
int rc; int rc;
struct slot *slot;
struct list_head *tmp;
lock_kernel(); lock_kernel();
daemonize("cpci_hp_polld"); daemonize("cpci_hp_polld");
...@@ -565,35 +582,19 @@ poll_thread(void *data) ...@@ -565,35 +582,19 @@ poll_thread(void *data)
while(1) { while(1) {
if(thread_finished || signal_pending(current)) if(thread_finished || signal_pending(current))
break; break;
if(controller->ops->query_enum()) {
while(controller->ops->query_enum()) { do {
rc = check_slots(); rc = check_slots();
if(rc > 0) if(rc > 0) {
/* Give userspace a chance to handle extraction */ /* Give userspace a chance to handle extraction */
msleep(500); msleep(500);
else if (rc < 0) { } else if(rc < 0) {
dbg("%s - error checking slots", __FUNCTION__); dbg("%s - error checking slots", __FUNCTION__);
thread_finished = 1; thread_finished = 1;
break; break;
} }
} while(atomic_read(&extracting) != 0);
} }
/* 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;
}
}
msleep(100); msleep(100);
} }
dbg("poll thread signals exit"); dbg("poll thread signals exit");
...@@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) ...@@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
int status = 0; int status = 0;
if(controller) { if(controller) {
if(atomic_read(&extracting) != 0) {
return -EBUSY;
}
if(!thread_finished) { if(!thread_finished) {
cpci_stop_thread(); cpci_stop_thread();
} }
...@@ -691,12 +695,12 @@ cpci_hp_start(void) ...@@ -691,12 +695,12 @@ cpci_hp_start(void)
return -ENODEV; return -ENODEV;
} }
spin_lock(&list_lock); down_read(&list_rwsem);
if(!slots) { if(list_empty(&slot_list)) {
spin_unlock(&list_lock); up_read(&list_rwsem);
return -ENODEV; return -ENODEV;
} }
spin_unlock(&list_lock); up_read(&list_rwsem);
if(first) { if(first) {
status = init_slots(); status = init_slots();
...@@ -727,7 +731,9 @@ cpci_hp_stop(void) ...@@ -727,7 +731,9 @@ cpci_hp_stop(void)
if(!controller) { if(!controller) {
return -ENODEV; return -ENODEV;
} }
if(atomic_read(&extracting) != 0) {
return -EBUSY;
}
if(controller->irq) { if(controller->irq) {
/* Stop enum interrupt processing */ /* Stop enum interrupt processing */
dbg("%s - disabling irq", __FUNCTION__); dbg("%s - disabling irq", __FUNCTION__);
...@@ -747,7 +753,7 @@ cleanup_slots(void) ...@@ -747,7 +753,7 @@ cleanup_slots(void)
* Unregister all of our slots with the pci_hotplug subsystem, * Unregister all of our slots with the pci_hotplug subsystem,
* and free up all memory that we had allocated. * and free up all memory that we had allocated.
*/ */
spin_lock(&list_lock); down_write(&list_rwsem);
if(!slots) { if(!slots) {
goto null_cleanup; goto null_cleanup;
} }
...@@ -761,17 +767,14 @@ cleanup_slots(void) ...@@ -761,17 +767,14 @@ cleanup_slots(void)
kfree(slot); kfree(slot);
} }
null_cleanup: null_cleanup:
spin_unlock(&list_lock); up_write(&list_rwsem);
return; return;
} }
int __init int __init
cpci_hotplug_init(int debug) cpci_hotplug_init(int debug)
{ {
spin_lock_init(&list_lock);
cpci_debug = debug; cpci_debug = debug;
info(DRIVER_DESC " version: " DRIVER_VERSION);
return 0; return 0;
} }
......
...@@ -32,11 +32,7 @@ ...@@ -32,11 +32,7 @@
#include "pci_hotplug.h" #include "pci_hotplug.h"
#include "cpci_hotplug.h" #include "cpci_hotplug.h"
#if !defined(MODULE)
#define MY_NAME "cpci_hotplug" #define MY_NAME "cpci_hotplug"
#else
#define MY_NAME THIS_MODULE->name
#endif
extern int cpci_debug; extern int cpci_debug;
...@@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot) ...@@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot)
return hs_csr; 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 cpci_check_and_clear_ins(struct slot* slot)
{ {
int hs_cap; int hs_cap;
...@@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot) ...@@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot)
return -ENODEV; return -ENODEV;
} }
if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
/* Set LOO */
hs_csr |= HS_CSR_LOO; hs_csr |= HS_CSR_LOO;
if(pci_bus_write_config_word(slot->bus, if(pci_bus_write_config_word(slot->bus,
slot->devfn, slot->devfn,
...@@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot) ...@@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot)
return -ENODEV; return -ENODEV;
} }
if(hs_csr & HS_CSR_LOO) { if(hs_csr & HS_CSR_LOO) {
/* Clear LOO */
hs_csr &= ~HS_CSR_LOO; hs_csr &= ~HS_CSR_LOO;
if(pci_bus_write_config_word(slot->bus, if(pci_bus_write_config_word(slot->bus,
slot->devfn, slot->devfn,
...@@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot) ...@@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot)
* Device configuration functions * 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;
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_bus *bus;
struct pci_dev *dev = wrapped_dev->dev;
struct pci_bus *bus = wrapped_bus->bus;
struct slot* slot;
dbg("%s - enter", __FUNCTION__); pci_enable_device(dev);
/*
* 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 */
if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
rc = cpci_configure_bridge(bus, dev); bus = dev->subordinate;
if(rc) list_for_each_entry(dev, &bus->devices, bus_list) {
return rc; cpci_enable_device(dev);
}
/* 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);
} }
} }
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 cpci_configure_slot(struct slot* slot)
{ {
int rc = 0; unsigned char busnr;
struct pci_bus *child;
dbg("%s - enter", __FUNCTION__); dbg("%s - enter", __FUNCTION__);
...@@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot) ...@@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot)
slot->dev = pci_find_slot(slot->bus->number, slot->devfn); slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
if(slot->dev == NULL) { if(slot->dev == NULL) {
err("Could not find PCI device for slot %02x", slot->number); err("Could not find PCI device for slot %02x", slot->number);
return 0; return 1;
} }
} }
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++) { if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
dev = pci_find_slot(slot->bus->number, pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr);
PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i)); child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr);
if(!dev) pci_do_scan_bus(child);
continue; pci_bus_size_bridges(child);
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);
}
} }
dbg("%s - exit, rc = %d", __FUNCTION__, rc); pci_bus_assign_resources(slot->dev->bus);
return rc;
cpci_enable_device(slot->dev);
dbg("%s - exit", __FUNCTION__);
return 0;
} }
int cpci_unconfigure_slot(struct slot* slot) int cpci_unconfigure_slot(struct slot* slot)
{ {
int rc = 0;
int i; int i;
struct pci_dev_wrapped wrapped_dev;
struct pci_bus_wrapped wrapped_bus;
struct pci_dev *dev; struct pci_dev *dev;
dbg("%s - enter", __FUNCTION__); dbg("%s - enter", __FUNCTION__);
if(!slot->dev) { if(!slot->dev) {
err("No device for slot %02x\n", slot->number); err("No device for slot %02x\n", slot->number);
return -ENODEV; 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++) { for (i = 0; i < 8; i++) {
dev = pci_find_slot(slot->bus->number, dev = pci_find_slot(slot->bus->number,
PCI_DEVFN(PCI_SLOT(slot->devfn), i)); PCI_DEVFN(PCI_SLOT(slot->devfn), i));
if(dev) { if(dev) {
wrapped_dev.dev = dev; pci_remove_bus_device(dev);
wrapped_bus.bus = dev->bus; slot->dev = NULL;
if(i) }
wrapped_dev.data = NULL; }
else dbg("%s - exit", __FUNCTION__);
wrapped_dev.data = (void*) slot; return 0;
dbg("%s - unconfigure phase 2", __FUNCTION__);
rc = pci_visit_dev(&unconfigure_functions_phase2,
&wrapped_dev,
&wrapped_bus);
if(rc)
break;
}
}
dbg("%s - exit, rc = %d", __FUNCTION__, rc);
return rc;
} }
...@@ -130,6 +130,7 @@ struct controller { ...@@ -130,6 +130,7 @@ struct controller {
u8 slot_bus; /* Bus where the slots handled by this controller sit */ u8 slot_bus; /* Bus where the slots handled by this controller sit */
u8 ctrlcap; u8 ctrlcap;
u16 vendor_id; u16 vendor_id;
u8 cap_base;
}; };
struct irq_mapping { struct irq_mapping {
......
...@@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev) ...@@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev)
static struct pcie_port_service_id port_pci_ids[] = { { static struct pcie_port_service_id port_pci_ids[] = { {
.vendor = PCI_ANY_ID, .vendor = PCI_ANY_ID,
.device = PCI_ANY_ID, .device = PCI_ANY_ID,
.port_type = PCIE_RC_PORT, .port_type = PCIE_ANY_PORT,
.service_type = PCIE_PORT_SERVICE_HP, .service_type = PCIE_PORT_SERVICE_HP,
.driver_data = 0, .driver_data = 0,
}, { /* end: all zeroes */ } }, { /* end: all zeroes */ }
......
...@@ -109,20 +109,20 @@ enum ctrl_offsets { ...@@ -109,20 +109,20 @@ enum ctrl_offsets {
}; };
static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */
#define PCIE_CAP_ID ( pcie_cap_base + PCIECAPID ) #define PCIE_CAP_ID(cb) ( cb + PCIECAPID )
#define NXT_CAP_PTR ( pcie_cap_base + NXTCAPPTR ) #define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR )
#define CAP_REG ( pcie_cap_base + CAPREG ) #define CAP_REG(cb) ( cb + CAPREG )
#define DEV_CAP ( pcie_cap_base + DEVCAP ) #define DEV_CAP(cb) ( cb + DEVCAP )
#define DEV_CTRL ( pcie_cap_base + DEVCTRL ) #define DEV_CTRL(cb) ( cb + DEVCTRL )
#define DEV_STATUS ( pcie_cap_base + DEVSTATUS ) #define DEV_STATUS(cb) ( cb + DEVSTATUS )
#define LNK_CAP ( pcie_cap_base + LNKCAP ) #define LNK_CAP(cb) ( cb + LNKCAP )
#define LNK_CTRL ( pcie_cap_base + LNKCTRL ) #define LNK_CTRL(cb) ( cb + LNKCTRL )
#define LNK_STATUS ( pcie_cap_base + LNKSTATUS ) #define LNK_STATUS(cb) ( cb + LNKSTATUS )
#define SLOT_CAP ( pcie_cap_base + SLOTCAP ) #define SLOT_CAP(cb) ( cb + SLOTCAP )
#define SLOT_CTRL ( pcie_cap_base + SLOTCTRL ) #define SLOT_CTRL(cb) ( cb + SLOTCTRL )
#define SLOT_STATUS ( pcie_cap_base + SLOTSTATUS ) #define SLOT_STATUS(cb) ( cb + SLOTSTATUS )
#define ROOT_CTRL ( pcie_cap_base + ROOTCTRL ) #define ROOT_CTRL(cb) ( cb + ROOTCTRL )
#define ROOT_STATUS ( pcie_cap_base + ROOTSTATUS ) #define ROOT_STATUS(cb) ( cb + ROOTSTATUS )
#define hp_register_read_word(pdev, reg , value) \ #define hp_register_read_word(pdev, reg , value) \
pci_read_config_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) ...@@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return retval; return retval;
...@@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) ...@@ -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); 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) { if (retval) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
...@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl) ...@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); 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) ...@@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; 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; atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
...@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) ...@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; 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; pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
...@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) ...@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 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) ...@@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
...@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot) ...@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 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) ...@@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
err("%s: Invalid HPC slot number!\n", __FUNCTION__); err("%s: Invalid HPC slot number!\n", __FUNCTION__);
return -1; 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 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) ...@@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
slot_cmd = slot_cmd | HP_INTR_ENABLE; slot_cmd = slot_cmd | HP_INTR_ENABLE;
pcie_write_cmd(slot, slot_cmd); 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; return rc;
} }
...@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot) ...@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot)
return ; 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 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) ...@@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot)
pcie_write_cmd(slot, slot_cmd); 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; return;
} }
...@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot) ...@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot)
return ; 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 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) ...@@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot)
if (!pciehp_poll_mode) if (!pciehp_poll_mode)
slot_cmd = slot_cmd | HP_INTR_ENABLE; slot_cmd = slot_cmd | HP_INTR_ENABLE;
pcie_write_cmd(slot, slot_cmd); 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; return;
} }
...@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot) ...@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
return ; 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 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) ...@@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
slot_cmd = slot_cmd | HP_INTR_ENABLE; slot_cmd = slot_cmd | HP_INTR_ENABLE;
pcie_write_cmd(slot, slot_cmd); 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; return;
} }
...@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl, ...@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl,
*first_device_num = 0; *first_device_num = 0;
*num_ctlr_slots = 1; *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) { if (rc) {
err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
...@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; 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_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
...@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot)
err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
return -1; 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 DBG_LEAVE_ROUTINE
...@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot) ...@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot)
err("%s: Invalid HPC slot number!\n", __FUNCTION__); err("%s: Invalid HPC slot number!\n", __FUNCTION__);
return -1; 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) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; 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_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
...@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot) ...@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot)
err("%s: Write command failed!\n", __FUNCTION__); err("%s: Write command failed!\n", __FUNCTION__);
return -1; 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 DBG_LEAVE_ROUTINE
...@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
return IRQ_NONE; 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) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -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); dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
/* Mask Hot-plug Interrupt Enable */ /* Mask Hot-plug Interrupt Enable */
if (!pciehp_poll_mode) { 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -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); 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; 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) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); 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) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -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 */ /* Clear command complete interrupt caused by this write */
temp_word = 0x1f; 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) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* Clear all events after serving them */ /* Clear all events after serving them */
temp_word = 0x1F; 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) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
/* Unmask Hot-plug Interrupt Enable */ /* Unmask Hot-plug Interrupt Enable */
if (!pciehp_poll_mode) { 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -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); 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; 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) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); 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) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -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 */ /* Clear command complete interrupt caused by this write */
temp_word = 0x1F; 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) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) ...@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
return -1; 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) { if (retval) {
err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); 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 ...@@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value
return -1; 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) { if (retval) {
err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); 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) ...@@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
return -1; 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) { if (retval) {
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); 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 ...@@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value
return -1; 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) { if (retval) {
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
...@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl, ...@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl,
goto abort_free_ctlr; 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); 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) { if (rc) {
err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
goto abort_free_ctlr; 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__); dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
goto abort_free_ctlr; 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) { if (rc) {
err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
goto abort_free_ctlr; 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)) { if (!(slot_cap & HP_CAP)) {
dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
/* For debugging purpose */ /* 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) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; 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) { if (first) {
spin_lock_init(&hpc_event_lock); spin_lock_init(&hpc_event_lock);
...@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl, ...@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl,
php_ctlr->num_slots = 1; php_ctlr->num_slots = 1;
/* Mask Hot-plug Interrupt Enable */ /* 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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; 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; 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) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word); 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) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; 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 */ 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) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; 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 */ if (pciehp_poll_mode) {/* Install interrupt polling code */
/* Install and start the interrupt polling timer */ /* Install and start the interrupt polling timer */
...@@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl, ...@@ -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) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; 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); dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
intr_enable = intr_enable | PRSN_DETECT_ENABLE; intr_enable = intr_enable | PRSN_DETECT_ENABLE;
...@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl, ...@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl,
dbg("%s: temp_word %x\n", __FUNCTION__, temp_word); dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
/* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ /* 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) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word); 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) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, 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 */ 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) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; 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 */ /* Add this HPC instance into the HPC list */
spin_lock(&list_lock); spin_lock(&list_lock);
......
...@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { ...@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
*/ */
static void release_slot(struct hotplug_slot *hotplug_slot) 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); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......
...@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot)
func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
if (!func) { if (!func) {
dbg("%s: Error! slot NULL\n", __FUNCTION__); dbg("%s: Error! slot NULL\n", __FUNCTION__);
return 1; return -ENODEV;
} }
/* Check to see if (latch closed, card present, power off) */ /* Check to see if (latch closed, card present, power off) */
...@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot)
if (rc || !getstatus) { if (rc || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) { if (rc || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || getstatus) { if (rc || getstatus) {
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
...@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot)
func = shpchp_slot_create(p_slot->bus); func = shpchp_slot_create(p_slot->bus);
if (func == NULL) if (func == NULL)
return 1; return -ENOMEM;
func->bus = p_slot->bus; func->bus = p_slot->bus;
func->device = p_slot->device; func->device = p_slot->device;
...@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot)
/* Setup slot structure with entry for empty slot */ /* Setup slot structure with entry for empty slot */
func = shpchp_slot_create(p_slot->bus); func = shpchp_slot_create(p_slot->bus);
if (func == NULL) if (func == NULL)
return (1); /* Out of memory */ return -ENOMEM; /* Out of memory */
func->bus = p_slot->bus; func->bus = p_slot->bus;
func->device = p_slot->device; func->device = p_slot->device;
...@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot)
struct pci_func *func; struct pci_func *func;
if (!p_slot->ctrl) if (!p_slot->ctrl)
return 1; return -ENODEV;
pci_bus = p_slot->ctrl->pci_dev->subordinate; pci_bus = p_slot->ctrl->pci_dev->subordinate;
...@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot)
if (ret || !getstatus) { if (ret || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (ret || getstatus) { if (ret || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (ret || !getstatus) { if (ret || !getstatus) {
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
...@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot)
/* Check the Class Code */ /* Check the Class Code */
rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (rc) if (rc)
return rc; return -ENODEV;
if (class_code == PCI_BASE_CLASS_DISPLAY) { if (class_code == PCI_BASE_CLASS_DISPLAY) {
/* Display/Video adapter (not supported) */ /* Display/Video adapter (not supported) */
...@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot)
/* See if it's a bridge */ /* See if it's a bridge */
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return -ENODEV;
/* If it's a bridge, check the VGA Enable bit */ /* If it's a bridge, check the VGA Enable bit */
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
if (rc) if (rc)
return rc; return -ENODEV;
/* If the VGA Enable bit is set, remove isn't supported */ /* If the VGA Enable bit is set, remove isn't supported */
if (BCR & PCI_BRIDGE_CTL_VGA) { if (BCR & PCI_BRIDGE_CTL_VGA) {
...@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot)
if ((func != NULL) && !rc) { if ((func != NULL) && !rc) {
rc = remove_board(func, p_slot->ctrl); rc = remove_board(func, p_slot->ctrl);
} else if (!rc) } else if (!rc)
rc = 1; rc = -ENODEV;
if (p_slot) if (p_slot)
update_slot_info(p_slot); update_slot_info(p_slot);
return(rc); return rc;
} }
......
...@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf) ...@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf)
return (str - 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[] = { struct device_attribute pci_dev_attrs[] = {
__ATTR_RO(resource), __ATTR_RO(resource),
__ATTR_RO(vendor), __ATTR_RO(vendor),
...@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = { ...@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = {
__ATTR_RO(class), __ATTR_RO(class),
__ATTR_RO(irq), __ATTR_RO(irq),
__ATTR_RO(local_cpus), __ATTR_RO(local_cpus),
__ATTR_RO(modalias),
__ATTR_NULL, __ATTR_NULL,
}; };
......
...@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void); ...@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void);
extern unsigned char pci_bus_max_busnr(struct pci_bus *bus); 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); 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); extern void pci_remove_legacy_files(struct pci_bus *bus);
/* Lock for read/write access to pci device and bus lists */ /* 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) ...@@ -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->vendor != pciedev->id.vendor) ||
(driver->id_table->device != PCI_ANY_ID && (driver->id_table->device != PCI_ANY_ID &&
driver->id_table->device != pciedev->id.device) || 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 ) driver->id_table->service_type != pciedev->id.service_type )
return 0; return 0;
......
...@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function, ...@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function,
int errno) int errno)
{ {
char nbuf[16]; 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", printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
sb->s_id, function, errstr); sb->s_id, function, errstr);
......
...@@ -273,9 +273,6 @@ struct device { ...@@ -273,9 +273,6 @@ struct device {
BIOS data relevant to device) */ BIOS data relevant to device) */
struct dev_pm_info power; 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 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as alloc_coherent mappings as
......
...@@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state) ...@@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state)
goto Unlock; 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))) if ((error = suspend_prepare(state)))
goto Unlock; goto Unlock;
pr_debug("PM: Entering state.\n"); pr_debug("PM: Entering %s sleep\n", pm_states[state]);
error = suspend_enter(state); error = suspend_enter(state);
pr_debug("PM: Finishing up.\n"); pr_debug("PM: Finishing wakeup.\n");
suspend_finish(state); suspend_finish(state);
Unlock: Unlock:
up(&pm_sem); up(&pm_sem);
......
...@@ -1244,7 +1244,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ...@@ -1244,7 +1244,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
addr = mm->free_area_cache; addr = mm->free_area_cache;
/* make sure it can fit in the remaining address space */ /* make sure it can fit in the remaining address space */
if (addr >= len) { if (addr > len) {
vma = find_vma(mm, addr-len); vma = find_vma(mm, addr-len);
if (!vma || addr <= vma->vm_start) if (!vma || addr <= vma->vm_start)
/* remember the address as a hint for next time */ /* 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, ...@@ -1266,7 +1266,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
/* try just below the current vma->vm_start */ /* try just below the current vma->vm_start */
addr = vma->vm_start-len; addr = vma->vm_start-len;
} while (len <= vma->vm_start); } while (len < vma->vm_start);
/* /*
* A failed mmap() very likely causes application failure, * A failed mmap() very likely causes application failure,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment