#define SLOT_POWEREDON (0x00000001)
#define SLOT_ENABLED (0x00000002)
-#define SLOT_MULTIFUNCTION (x000000004)
+#define SLOT_MULTIFUNCTION (0x00000004)
/* function flags */
#define FUNC_HAS_PS2 (0x00000040)
#define FUNC_HAS_PS3 (0x00000080)
-#define FUNC_EXISTS (0x10000000) /* to make sure we call _EJ0 only for existing funcs */
-
/* function prototypes */
/* acpiphp_glue.c */
extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot);
extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
+extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
/* acpiphp_pci.c */
extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
*
*/
-#include <linux/config.h>
-#include <linux/kernel.h>
+#include <linux/init.h>
#include <linux/module.h>
+
+#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
-#include <linux/init.h>
#include "pci_hotplug.h"
#include "acpiphp.h"
static int hardware_test (struct hotplug_slot *slot, u32 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_address (struct hotplug_slot *slot, u32 *value);
static int get_latch_status (struct hotplug_slot *slot, u8 *value);
static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
.get_attention_status = get_attention_status,
.get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_status,
+ .get_address = get_address,
.get_max_bus_speed = get_max_bus_speed,
.get_cur_bus_speed = get_cur_bus_speed,
};
}
+/**
+ * get_address - get pci address of a slot
+ * @hotplug_slot: slot to get status
+ * @busdev: pointer to struct pci_busdev (seg, bus, dev)
+ *
+ */
+static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
+{
+ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ int retval = 0;
+
+ if (slot == NULL)
+ return -ENODEV;
+
+ dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+ *value = acpiphp_get_address(slot->acpi_slot);
+
+ return retval;
+}
+
+
/* return dummy value because ACPI doesn't provide any method... */
static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{
*
*/
-#include <linux/config.h>
-#include <linux/kernel.h>
+#include <linux/init.h>
#include <linux/module.h>
+
+#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/smp_lock.h>
-#include <linux/init.h>
#include <asm/semaphore.h>
#include "../pci.h"
struct list_head *l;
int retval = 0;
- /* is this already enabled? */
+ /* if already enabled, just skip */
if (slot->flags & SLOT_POWEREDON)
goto err_exit;
int retval = 0;
- /* is this already enabled? */
+ /* if already disabled, just skip */
if ((slot->flags & SLOT_POWEREDON) == 0)
goto err_exit;
list_for_each (l, &slot->funcs) {
func = list_entry(l, struct acpiphp_func, sibling);
- if (func->flags & (FUNC_HAS_PS3 | FUNC_EXISTS)) {
+ if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
if (ACPI_FAILURE(status)) {
warn("%s: _PS3 failed\n", __FUNCTION__);
func = list_entry(l, struct acpiphp_func, sibling);
/* We don't want to call _EJ0 on non-existing functions. */
- if (func->flags & (FUNC_HAS_EJ0 | FUNC_EXISTS)) {
+ if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
/* _EJ0 method take one argument */
arg_list.count = 1;
arg_list.pointer = &arg;
retval = -1;
goto err_exit;
}
- func->flags &= (~FUNC_EXISTS);
}
}
retval = acpiphp_configure_function(func);
if (retval)
goto err_exit;
-
- func->flags |= FUNC_EXISTS;
}
slot->flags |= SLOT_ENABLED;
return (sta == 0) ? 0 : 1;
}
+
+
+/*
+ * pci address (seg/bus/dev)
+ */
+u32 acpiphp_get_address (struct acpiphp_slot *slot)
+{
+ u32 address;
+
+ address = ((slot->bridge->seg) << 16) |
+ ((slot->bridge->bus) << 8) |
+ slot->device;
+
+ return address;
+}
*
*/
-#include <linux/config.h>
-#include <linux/kernel.h>
+#include <linux/init.h>
#include <linux/module.h>
+
+#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/init.h>
#include <linux/acpi.h>
#include "../pci.h"
#include "pci_hotplug.h"
*
*/
-#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
-#include <linux/init.h>
#include <linux/string.h>
#include <linux/mm.h>
* @get_adapter_status: Called to get see if an adapter is present in the slot or not.
* If this field is NULL, the value passed in the struct hotplug_slot_info
* will be used when this value is requested by a user.
+ * @get_address: Called to get pci address of a slot.
+ * If this field is NULL, the value passed in the struct hotplug_slot_info
+ * will be used when this value is requested by a user.
* @get_max_bus_speed: Called to get the max bus speed for a slot.
* If this field is NULL, the value passed in the struct hotplug_slot_info
* will be used when this value is requested by a user.
int (*get_attention_status) (struct hotplug_slot *slot, u8 *value);
int (*get_latch_status) (struct hotplug_slot *slot, u8 *value);
int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value);
+ int (*get_address) (struct hotplug_slot *slot, u32 *value);
int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
};
* @attention_status: if the attention light is enabled or not (1/0)
* @latch_status: if the latch (if any) is open or closed (1/0)
* @adapter_present: if there is a pci board present in the slot or not (1/0)
+ * @address: (domain << 16 | bus << 8 | dev)
*
* Used to notify the hotplug pci core of the status of a specific slot.
*/
u8 attention_status;
u8 latch_status;
u8 adapter_status;
+ u32 address;
enum pci_bus_speed max_bus_speed;
enum pci_bus_speed cur_bus_speed;
};
GET_STATUS(attention_status, u8)
GET_STATUS(latch_status, u8)
GET_STATUS(adapter_status, u8)
+GET_STATUS(address, u32)
GET_STATUS(max_bus_speed, enum pci_bus_speed)
GET_STATUS(cur_bus_speed, enum pci_bus_speed)
.show = presence_read_file,
};
+static ssize_t address_read_file (struct hotplug_slot *slot, char *buf)
+{
+ int retval;
+ u32 address;
+
+ retval = get_address (slot, &address);
+ if (retval)
+ goto exit;
+ retval = sprintf (buf, "%04x:%02x:%02x\n",
+ (address >> 16) & 0xffff,
+ (address >> 8) & 0xff,
+ address & 0xff);
+
+exit:
+ return retval;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_address = {
+ .attr = {.name = "address", .mode = S_IFREG | S_IRUGO},
+ .show = address_read_file,
+};
+
static char *unknown_speed = "Unknown bus speed";
static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
return -ENOENT;
}
+static int has_address_file (struct hotplug_slot *slot)
+{
+ if ((!slot) || (!slot->ops))
+ return -ENODEV;
+ if (slot->ops->get_address)
+ return 0;
+ return -ENOENT;
+}
+
static int has_max_bus_speed_file (struct hotplug_slot *slot)
{
if ((!slot) || (!slot->ops))
if (has_adapter_file(slot) == 0)
sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+ if (has_address_file(slot) == 0)
+ sysfs_create_file(&slot->kobj, &hotplug_slot_attr_address.attr);
+
if (has_max_bus_speed_file(slot) == 0)
sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
if (has_adapter_file(slot) == 0)
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+ if (has_address_file(slot) == 0)
+ sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_address.attr);
+
if (has_max_bus_speed_file(slot) == 0)
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
(slot->info->adapter_status != info->adapter_status))
sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+ if ((has_address_file(slot) == 0) &&
+ (slot->info->address != info->address))
+ sysfs_update_file(&slot->kobj, &hotplug_slot_attr_address.attr);
+
if ((has_max_bus_speed_file(slot) == 0) &&
(slot->info->max_bus_speed != info->max_bus_speed))
sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);