aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci/slot.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/slot.c')
-rw-r--r--drivers/pci/slot.c98
1 files changed, 66 insertions, 32 deletions
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index eddb0748b0e..396c200b9dd 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -6,6 +6,8 @@
*/
#include <linux/kobject.h>
+#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/pci.h>
#include <linux/err.h>
#include "pci.h"
@@ -29,7 +31,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj,
return attribute->store ? attribute->store(slot, buf, len) : -EIO;
}
-static struct sysfs_ops pci_slot_sysfs_ops = {
+static const struct sysfs_ops pci_slot_sysfs_ops = {
.show = pci_slot_attr_show,
.store = pci_slot_attr_store,
};
@@ -47,6 +49,55 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
slot->number);
}
+/* these strings match up with the values in pci_bus_speed */
+static const char *pci_bus_speed_strings[] = {
+ "33 MHz PCI", /* 0x00 */
+ "66 MHz PCI", /* 0x01 */
+ "66 MHz PCI-X", /* 0x02 */
+ "100 MHz PCI-X", /* 0x03 */
+ "133 MHz PCI-X", /* 0x04 */
+ NULL, /* 0x05 */
+ NULL, /* 0x06 */
+ NULL, /* 0x07 */
+ NULL, /* 0x08 */
+ "66 MHz PCI-X 266", /* 0x09 */
+ "100 MHz PCI-X 266", /* 0x0a */
+ "133 MHz PCI-X 266", /* 0x0b */
+ "Unknown AGP", /* 0x0c */
+ "1x AGP", /* 0x0d */
+ "2x AGP", /* 0x0e */
+ "4x AGP", /* 0x0f */
+ "8x AGP", /* 0x10 */
+ "66 MHz PCI-X 533", /* 0x11 */
+ "100 MHz PCI-X 533", /* 0x12 */
+ "133 MHz PCI-X 533", /* 0x13 */
+ "2.5 GT/s PCIe", /* 0x14 */
+ "5.0 GT/s PCIe", /* 0x15 */
+ "8.0 GT/s PCIe", /* 0x16 */
+};
+
+static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf)
+{
+ const char *speed_string;
+
+ if (speed < ARRAY_SIZE(pci_bus_speed_strings))
+ speed_string = pci_bus_speed_strings[speed];
+ else
+ speed_string = "Unknown";
+
+ return sprintf(buf, "%s\n", speed_string);
+}
+
+static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf)
+{
+ return bus_speed_read(slot->bus->max_bus_speed, buf);
+}
+
+static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
+{
+ return bus_speed_read(slot->bus->cur_bus_speed, buf);
+}
+
static void pci_slot_release(struct kobject *kobj)
{
struct pci_dev *dev;
@@ -65,10 +116,16 @@ static void pci_slot_release(struct kobject *kobj)
}
static struct pci_slot_attribute pci_slot_attr_address =
- __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL);
+ __ATTR(address, S_IRUGO, address_read_file, NULL);
+static struct pci_slot_attribute pci_slot_attr_max_speed =
+ __ATTR(max_bus_speed, S_IRUGO, max_speed_read_file, NULL);
+static struct pci_slot_attribute pci_slot_attr_cur_speed =
+ __ATTR(cur_bus_speed, S_IRUGO, cur_speed_read_file, NULL);
static struct attribute *pci_slot_default_attrs[] = {
&pci_slot_attr_address.attr,
+ &pci_slot_attr_max_speed.attr,
+ &pci_slot_attr_cur_speed.attr,
NULL,
};
@@ -263,32 +320,6 @@ err:
EXPORT_SYMBOL_GPL(pci_create_slot);
/**
- * pci_renumber_slot - update %struct pci_slot -> number
- * @slot: &struct pci_slot to update
- * @slot_nr: new number for slot
- *
- * The primary purpose of this interface is to allow callers who earlier
- * created a placeholder slot in pci_create_slot() by passing a -1 as
- * slot_nr, to update their %struct pci_slot with the correct @slot_nr.
- */
-void pci_renumber_slot(struct pci_slot *slot, int slot_nr)
-{
- struct pci_slot *tmp;
-
- down_write(&pci_bus_sem);
-
- list_for_each_entry(tmp, &slot->bus->slots, list) {
- WARN_ON(tmp->number == slot_nr);
- goto out;
- }
-
- slot->number = slot_nr;
-out:
- up_write(&pci_bus_sem);
-}
-EXPORT_SYMBOL_GPL(pci_renumber_slot);
-
-/**
* pci_destroy_slot - decrement refcount for physical PCI slot
* @slot: struct pci_slot to decrement
*
@@ -311,7 +342,7 @@ EXPORT_SYMBOL_GPL(pci_destroy_slot);
#include <linux/pci_hotplug.h>
/**
* pci_hp_create_link - create symbolic link to the hotplug driver module.
- * @slot: struct pci_slot
+ * @pci_slot: struct pci_slot
*
* Helper function for pci_hotplug_core.c to create symbolic link to
* the hotplug driver module.
@@ -320,21 +351,24 @@ void pci_hp_create_module_link(struct pci_slot *pci_slot)
{
struct hotplug_slot *slot = pci_slot->hotplug;
struct kobject *kobj = NULL;
- int no_warn;
+ int ret;
if (!slot || !slot->ops)
return;
kobj = kset_find_obj(module_kset, slot->ops->mod_name);
if (!kobj)
return;
- no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module");
+ ret = sysfs_create_link(&pci_slot->kobj, kobj, "module");
+ if (ret)
+ dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n",
+ ret);
kobject_put(kobj);
}
EXPORT_SYMBOL_GPL(pci_hp_create_module_link);
/**
* pci_hp_remove_link - remove symbolic link to the hotplug driver module.
- * @slot: struct pci_slot
+ * @pci_slot: struct pci_slot
*
* Helper function for pci_hotplug_core.c to remove symbolic link to
* the hotplug driver module.