Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6

Conflicts:

	drivers/pci/dmar.c
This commit is contained in:
David Woodhouse 2008-10-21 19:42:20 +01:00
commit b876d08f81
471 changed files with 13281 additions and 10999 deletions

View file

@ -151,6 +151,13 @@ void pci_bus_add_devices(struct pci_bus *bus)
if (retval)
dev_err(&dev->dev, "Error creating cpuaffinity"
" file, continuing...\n");
retval = device_create_file(&child_bus->dev,
&dev_attr_cpulistaffinity);
if (retval)
dev_err(&dev->dev,
"Error creating cpulistaffinity"
" file, continuing...\n");
}
}
}

View file

@ -211,7 +211,7 @@ static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru)
include_all = 1;
}
if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) {
if (ret) {
list_del(&dmaru->list);
kfree(dmaru);
}
@ -289,6 +289,24 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
}
}
/**
* dmar_table_detect - checks to see if the platform supports DMAR devices
*/
static int __init dmar_table_detect(void)
{
acpi_status status = AE_OK;
/* if we could find DMAR table, then there are DMAR devices */
status = acpi_get_table(ACPI_SIG_DMAR, 0,
(struct acpi_table_header **)&dmar_tbl);
if (ACPI_SUCCESS(status) && !dmar_tbl) {
printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
status = AE_NOT_FOUND;
}
return (ACPI_SUCCESS(status) ? 1 : 0);
}
/**
* parse_dmar_table - parses the DMA reporting table
@ -300,6 +318,12 @@ parse_dmar_table(void)
struct acpi_dmar_header *entry_header;
int ret = 0;
/*
* Do it again, earlier dmar_tbl mapping could be mapped with
* fixed map.
*/
dmar_table_detect();
dmar = (struct acpi_table_dmar *)dmar_tbl;
if (!dmar)
return -ENODEV;
@ -373,10 +397,10 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
int __init dmar_dev_scope_init(void)
{
struct dmar_drhd_unit *drhd;
struct dmar_drhd_unit *drhd, *drhd_n;
int ret = -ENODEV;
for_each_drhd_unit(drhd) {
list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) {
ret = dmar_parse_dev(drhd);
if (ret)
return ret;
@ -384,8 +408,8 @@ int __init dmar_dev_scope_init(void)
#ifdef CONFIG_DMAR
{
struct dmar_rmrr_unit *rmrr;
for_each_rmrr_units(rmrr) {
struct dmar_rmrr_unit *rmrr, *rmrr_n;
list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) {
ret = rmrr_parse_dev(rmrr);
if (ret)
return ret;
@ -430,30 +454,11 @@ int __init dmar_table_init(void)
return 0;
}
/**
* early_dmar_detect - checks to see if the platform supports DMAR devices
*/
int __init early_dmar_detect(void)
{
acpi_status status = AE_OK;
/* if we could find DMAR table, then there are DMAR devices */
status = acpi_get_table(ACPI_SIG_DMAR, 0,
(struct acpi_table_header **)&dmar_tbl);
if (ACPI_SUCCESS(status) && !dmar_tbl) {
printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
status = AE_NOT_FOUND;
}
return (ACPI_SUCCESS(status) ? 1 : 0);
}
void __init detect_intel_iommu(void)
{
int ret;
ret = early_dmar_detect();
ret = dmar_table_detect();
{
#ifdef CONFIG_INTR_REMAP
@ -470,13 +475,13 @@ void __init detect_intel_iommu(void)
"Queued invalidation will be enabled to support "
"x2apic and Intr-remapping.\n");
#endif
#ifdef CONFIG_DMAR
if (ret && !no_iommu && !iommu_detected && !swiotlb &&
!dmar_disabled)
iommu_detected = 1;
#endif
}
dmar_tbl = NULL;
}

View file

@ -123,10 +123,8 @@ static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
static void __init print_bus_info (void)
{
struct bus_info *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &bus_info_head) {
ptr = list_entry (ptr1, struct bus_info, bus_info_list);
list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
debug ("%s - slot_min = %x\n", __func__, ptr->slot_min);
debug ("%s - slot_max = %x\n", __func__, ptr->slot_max);
debug ("%s - slot_count = %x\n", __func__, ptr->slot_count);
@ -146,10 +144,8 @@ static void __init print_bus_info (void)
static void print_lo_info (void)
{
struct rio_detail *ptr;
struct list_head *ptr1;
debug ("print_lo_info ----\n");
list_for_each (ptr1, &rio_lo_head) {
ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) {
debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
@ -163,10 +159,8 @@ static void print_lo_info (void)
static void print_vg_info (void)
{
struct rio_detail *ptr;
struct list_head *ptr1;
debug ("%s ---\n", __func__);
list_for_each (ptr1, &rio_vg_head) {
ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
list_for_each_entry(ptr, &rio_vg_head, rio_detail_list) {
debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
@ -180,10 +174,8 @@ static void print_vg_info (void)
static void __init print_ebda_pci_rsrc (void)
{
struct ebda_pci_rsrc *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) {
debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
__func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
}
@ -192,10 +184,8 @@ static void __init print_ebda_pci_rsrc (void)
static void __init print_ibm_slot (void)
{
struct slot *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &ibmphp_slot_head) {
ptr = list_entry (ptr1, struct slot, ibm_slot_list);
list_for_each_entry(ptr, &ibmphp_slot_head, ibm_slot_list) {
debug ("%s - slot_number: %x\n", __func__, ptr->number);
}
}
@ -203,10 +193,8 @@ static void __init print_ibm_slot (void)
static void __init print_opt_vg (void)
{
struct opt_rio *ptr;
struct list_head *ptr1;
debug ("%s ---\n", __func__);
list_for_each (ptr1, &opt_vg_head) {
ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
debug ("%s - rio_type %x\n", __func__, ptr->rio_type);
debug ("%s - chassis_num: %x\n", __func__, ptr->chassis_num);
debug ("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num);
@ -217,13 +205,9 @@ static void __init print_opt_vg (void)
static void __init print_ebda_hpc (void)
{
struct controller *hpc_ptr;
struct list_head *ptr1;
u16 index;
list_for_each (ptr1, &ebda_hpc_head) {
hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list);
list_for_each_entry(hpc_ptr, &ebda_hpc_head, ebda_hpc_list) {
for (index = 0; index < hpc_ptr->slot_count; index++) {
debug ("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num);
debug ("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num);
@ -460,9 +444,7 @@ static int __init ebda_rio_table (void)
static struct opt_rio *search_opt_vg (u8 chassis_num)
{
struct opt_rio *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &opt_vg_head) {
ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
if (ptr->chassis_num == chassis_num)
return ptr;
}
@ -473,10 +455,8 @@ static int __init combine_wpg_for_chassis (void)
{
struct opt_rio *opt_rio_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
struct list_head *list_head_ptr = NULL;
list_for_each (list_head_ptr, &rio_vg_head) {
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) {
opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
if (!opt_rio_ptr) {
opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL);
@ -497,14 +477,12 @@ static int __init combine_wpg_for_chassis (void)
}
/*
* reorgnizing linked list of expansion box
* reorganizing linked list of expansion box
*/
static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
{
struct opt_rio_lo *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &opt_lo_head) {
ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) {
if (ptr->chassis_num == chassis_num)
return ptr;
}
@ -515,10 +493,8 @@ static int combine_wpg_for_expansion (void)
{
struct opt_rio_lo *opt_rio_lo_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
struct list_head *list_head_ptr = NULL;
list_for_each (list_head_ptr, &rio_lo_head) {
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) {
opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
if (!opt_rio_lo_ptr) {
opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL);
@ -550,20 +526,17 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
{
struct opt_rio *opt_vg_ptr = NULL;
struct opt_rio_lo *opt_lo_ptr = NULL;
struct list_head *ptr = NULL;
int rc = 0;
if (!var) {
list_for_each (ptr, &opt_vg_head) {
opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {
rc = -ENODEV;
break;
}
}
} else {
list_for_each (ptr, &opt_lo_head) {
opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
rc = -ENODEV;
break;
@ -576,10 +549,8 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
static struct opt_rio_lo * find_rxe_num (u8 slot_num)
{
struct opt_rio_lo *opt_lo_ptr;
struct list_head *ptr;
list_for_each (ptr, &opt_lo_head) {
opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
//check to see if this slot_num belongs to expansion box
if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))
return opt_lo_ptr;
@ -590,10 +561,8 @@ static struct opt_rio_lo * find_rxe_num (u8 slot_num)
static struct opt_rio * find_chassis_num (u8 slot_num)
{
struct opt_rio *opt_vg_ptr;
struct list_head *ptr;
list_for_each (ptr, &opt_vg_head) {
opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
//check to see if this slot_num belongs to chassis
if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))
return opt_vg_ptr;
@ -607,11 +576,9 @@ static struct opt_rio * find_chassis_num (u8 slot_num)
static u8 calculate_first_slot (u8 slot_num)
{
u8 first_slot = 1;
struct list_head * list;
struct slot * slot_cur;
list_for_each (list, &ibmphp_slot_head) {
slot_cur = list_entry (list, struct slot, ibm_slot_list);
list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
if (slot_cur->ctrl) {
if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))
first_slot = slot_cur->ctrl->ending_slot_num;
@ -767,7 +734,6 @@ static int __init ebda_rsrc_controller (void)
struct bus_info *bus_info_ptr1, *bus_info_ptr2;
int rc;
struct slot *tmp_slot;
struct list_head *list;
addr = hpc_list_ptr->phys_addr;
for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
@ -997,9 +963,7 @@ static int __init ebda_rsrc_controller (void)
} /* each hpc */
list_for_each (list, &ibmphp_slot_head) {
tmp_slot = list_entry (list, struct slot, ibm_slot_list);
list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) {
snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
pci_hp_register(tmp_slot->hotplug_slot,
pci_find_bus(0, tmp_slot->bus), tmp_slot->device);
@ -1101,10 +1065,8 @@ u16 ibmphp_get_total_controllers (void)
struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
{
struct slot *slot;
struct list_head *list;
list_for_each (list, &ibmphp_slot_head) {
slot = list_entry (list, struct slot, ibm_slot_list);
list_for_each_entry(slot, &ibmphp_slot_head, ibm_slot_list) {
if (slot->number == physical_num)
return slot;
}
@ -1120,10 +1082,8 @@ struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
struct bus_info *ibmphp_find_same_bus_num (u32 num)
{
struct bus_info *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &bus_info_head) {
ptr = list_entry (ptr1, struct bus_info, bus_info_list);
list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
if (ptr->busno == num)
return ptr;
}
@ -1136,10 +1096,8 @@ struct bus_info *ibmphp_find_same_bus_num (u32 num)
int ibmphp_get_bus_index (u8 num)
{
struct bus_info *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &bus_info_head) {
ptr = list_entry (ptr1, struct bus_info, bus_info_list);
list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
if (ptr->busno == num)
return ptr->index;
}
@ -1212,11 +1170,9 @@ static struct pci_driver ibmphp_driver = {
int ibmphp_register_pci (void)
{
struct controller *ctrl;
struct list_head *tmp;
int rc = 0;
list_for_each (tmp, &ebda_hpc_head) {
ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
if (ctrl->ctlr_type == 1) {
rc = pci_register_driver(&ibmphp_driver);
break;
@ -1227,12 +1183,10 @@ int ibmphp_register_pci (void)
static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
{
struct controller *ctrl;
struct list_head *tmp;
debug ("inside ibmphp_probe\n");
list_for_each (tmp, &ebda_hpc_head) {
ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
if (ctrl->ctlr_type == 1) {
if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
ctrl->ctrl_dev = dev;

View file

@ -102,13 +102,13 @@ static int get_##name (struct hotplug_slot *slot, type *value) \
{ \
struct hotplug_slot_ops *ops = slot->ops; \
int retval = 0; \
if (try_module_get(ops->owner)) { \
if (ops->get_##name) \
retval = ops->get_##name(slot, value); \
else \
*value = slot->info->name; \
module_put(ops->owner); \
} \
if (!try_module_get(ops->owner)) \
return -ENODEV; \
if (ops->get_##name) \
retval = ops->get_##name(slot, value); \
else \
*value = slot->info->name; \
module_put(ops->owner); \
return retval; \
}

View file

@ -57,6 +57,19 @@ extern struct workqueue_struct *pciehp_wq;
#define warn(format, arg...) \
printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (pciehp_debug) \
dev_printk(, &ctrl->pcie->device, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
dev_err(&ctrl->pcie->device, format, ## arg)
#define ctrl_info(ctrl, format, arg...) \
dev_info(&ctrl->pcie->device, format, ## arg)
#define ctrl_warn(ctrl, format, arg...) \
dev_warn(&ctrl->pcie->device, format, ## arg)
#define SLOT_NAME_SIZE 10
struct slot {
u8 bus;
@ -87,6 +100,7 @@ struct controller {
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev;
struct pcie_device *pcie; /* PCI Express port service */
struct list_head slot_list;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
@ -170,7 +184,7 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
return slot;
}
err("%s: slot (device=0x%x) not found\n", __func__, device);
ctrl_err(ctrl, "%s: slot (device=0x%x) not found\n", __func__, device);
return NULL;
}

View file

@ -144,9 +144,10 @@ set_lock_exit:
* sysfs interface which allows the user to toggle the Electro Mechanical
* Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock
*/
static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf,
size_t count)
static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot,
const char *buf, size_t count)
{
struct slot *slot = hotplug_slot->private;
unsigned long llock;
u8 lock;
int retval = 0;
@ -157,10 +158,11 @@ static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf,
switch (lock) {
case 0:
case 1:
retval = set_lock_status(slot, lock);
retval = set_lock_status(hotplug_slot, lock);
break;
default:
err ("%d is an invalid lock value\n", lock);
ctrl_err(slot->ctrl, "%d is an invalid lock value\n",
lock);
retval = -EINVAL;
}
if (retval)
@ -180,7 +182,10 @@ static struct hotplug_slot_attribute hotplug_slot_attr_lock = {
*/
static void release_slot(struct hotplug_slot *hotplug_slot)
{
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
struct slot *slot = hotplug_slot->private;
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
kfree(hotplug_slot->info);
kfree(hotplug_slot);
@ -215,9 +220,9 @@ static int init_slots(struct controller *ctrl)
get_adapter_status(hotplug_slot, &info->adapter_status);
slot->hotplug_slot = hotplug_slot;
dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
"slot_device_offset=%x\n", slot->bus, slot->device,
slot->hp_slot, slot->number, ctrl->slot_device_offset);
ctrl_dbg(ctrl, "Registering bus=%x dev=%x hp_slot=%x sun=%x "
"slot_device_offset=%x\n", slot->bus, slot->device,
slot->hp_slot, slot->number, ctrl->slot_device_offset);
duplicate_name:
retval = pci_hp_register(hotplug_slot,
ctrl->pci_dev->subordinate,
@ -233,9 +238,11 @@ duplicate_name:
if (len < SLOT_NAME_SIZE)
goto duplicate_name;
else
err("duplicate slot name overflow\n");
ctrl_err(ctrl, "duplicate slot name "
"overflow\n");
}
err("pci_hp_register failed with error %d\n", retval);
ctrl_err(ctrl, "pci_hp_register failed with error %d\n",
retval);
goto error_info;
}
/* create additional sysfs entries */
@ -244,7 +251,8 @@ duplicate_name:
&hotplug_slot_attr_lock.attr);
if (retval) {
pci_hp_deregister(hotplug_slot);
err("cannot create additional sysfs entries\n");
ctrl_err(ctrl, "cannot create additional sysfs "
"entries\n");
goto error_info;
}
}
@ -278,7 +286,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
{
struct slot *slot = hotplug_slot->private;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
hotplug_slot->info->attention_status = status;
@ -293,7 +302,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
{
struct slot *slot = hotplug_slot->private;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
return pciehp_sysfs_enable_slot(slot);
}
@ -303,7 +313,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
{
struct slot *slot = hotplug_slot->private;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
return pciehp_sysfs_disable_slot(slot);
}
@ -313,7 +324,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
retval = slot->hpc_ops->get_power_status(slot, value);
if (retval < 0)
@ -327,7 +339,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
retval = slot->hpc_ops->get_attention_status(slot, value);
if (retval < 0)
@ -341,7 +354,8 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
retval = slot->hpc_ops->get_latch_status(slot, value);
if (retval < 0)
@ -355,7 +369,8 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
retval = slot->hpc_ops->get_adapter_status(slot, value);
if (retval < 0)
@ -370,7 +385,8 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
struct slot *slot = hotplug_slot->private;
int retval;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
retval = slot->hpc_ops->get_max_bus_speed(slot, value);
if (retval < 0)
@ -384,7 +400,8 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
struct slot *slot = hotplug_slot->private;
int retval;
dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
__func__, hotplug_slot->name);
retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
if (retval < 0)
@ -402,14 +419,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
struct pci_dev *pdev = dev->port;
if (pciehp_force)
dbg("Bypassing BIOS check for pciehp use on %s\n",
pci_name(pdev));
dev_info(&dev->device,
"Bypassing BIOS check for pciehp use on %s\n",
pci_name(pdev));
else if (pciehp_get_hp_hw_control_from_firmware(pdev))
goto err_out_none;
ctrl = pcie_init(dev);
if (!ctrl) {
dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
dev_err(&dev->device, "controller initialization failed\n");
goto err_out_none;
}
set_service_data(dev, ctrl);
@ -418,11 +436,10 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
rc = init_slots(ctrl);
if (rc) {
if (rc == -EBUSY)
warn("%s: slot already registered by another "
"hotplug driver\n", PCIE_MODULE_NAME);
ctrl_warn(ctrl, "slot already registered by another "
"hotplug driver\n");
else
err("%s: slot initialization failed\n",
PCIE_MODULE_NAME);
ctrl_err(ctrl, "slot initialization failed\n");
goto err_out_release_ctlr;
}
@ -461,13 +478,13 @@ static void pciehp_remove (struct pcie_device *dev)
#ifdef CONFIG_PM
static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
{
printk("%s ENTRY\n", __func__);
dev_info(&dev->device, "%s ENTRY\n", __func__);
return 0;
}
static int pciehp_resume (struct pcie_device *dev)
{
printk("%s ENTRY\n", __func__);
dev_info(&dev->device, "%s ENTRY\n", __func__);
if (pciehp_force) {
struct controller *ctrl = get_service_data(dev);
struct slot *t_slot;
@ -497,10 +514,9 @@ static struct pcie_port_service_id port_pci_ids[] = { {
.driver_data = 0,
}, { /* end: all zeroes */ }
};
static const char device_name[] = "hpdriver";
static struct pcie_port_service_driver hpdriver_portdrv = {
.name = (char *)device_name,
.name = PCIE_MODULE_NAME,
.id_table = &port_pci_ids[0],
.probe = pciehp_probe,

View file

@ -58,14 +58,15 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
u8 pciehp_handle_attention_button(struct slot *p_slot)
{
u32 event_type;
struct controller *ctrl = p_slot->ctrl;
/* Attention Button Change */
dbg("pciehp: Attention button interrupt received.\n");
ctrl_dbg(ctrl, "Attention button interrupt received.\n");
/*
* Button pressed - See if need to TAKE ACTION!!!
*/
info("Button pressed on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Button pressed on Slot(%s)\n", p_slot->name);
event_type = INT_BUTTON_PRESS;
queue_interrupt_event(p_slot, event_type);
@ -77,22 +78,23 @@ u8 pciehp_handle_switch_change(struct slot *p_slot)
{
u8 getstatus;
u32 event_type;
struct controller *ctrl = p_slot->ctrl;
/* Switch Change */
dbg("pciehp: Switch interrupt received.\n");
ctrl_dbg(ctrl, "Switch interrupt received.\n");
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (getstatus) {
/*
* Switch opened
*/
info("Latch open on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Latch open on Slot(%s)\n", p_slot->name);
event_type = INT_SWITCH_OPEN;
} else {
/*
* Switch closed
*/
info("Latch close on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Latch close on Slot(%s)\n", p_slot->name);
event_type = INT_SWITCH_CLOSE;
}
@ -105,9 +107,10 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
{
u32 event_type;
u8 presence_save;
struct controller *ctrl = p_slot->ctrl;
/* Presence Change */
dbg("pciehp: Presence/Notify input change.\n");
ctrl_dbg(ctrl, "Presence/Notify input change.\n");
/* Switch is open, assume a presence change
* Save the presence state
@ -117,13 +120,13 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
/*
* Card Present
*/
info("Card present on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Card present on Slot(%s)\n", p_slot->name);
event_type = INT_PRESENCE_ON;
} else {
/*
* Not Present
*/
info("Card not present on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Card not present on Slot(%s)\n", p_slot->name);
event_type = INT_PRESENCE_OFF;
}
@ -135,23 +138,25 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
u8 pciehp_handle_power_fault(struct slot *p_slot)
{
u32 event_type;
struct controller *ctrl = p_slot->ctrl;
/* power fault */
dbg("pciehp: Power fault interrupt received.\n");
ctrl_dbg(ctrl, "Power fault interrupt received.\n");
if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
/*
* power fault Cleared
*/
info("Power fault cleared on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n",
p_slot->name);
event_type = INT_POWER_FAULT_CLEAR;
} else {
/*
* power fault
*/
info("Power fault on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Power fault on Slot(%s)\n", p_slot->name);
event_type = INT_POWER_FAULT;
info("power fault bit %x set\n", 0);
ctrl_info(ctrl, "power fault bit %x set\n", 0);
}
queue_interrupt_event(p_slot, event_type);
@ -168,8 +173,9 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
/* turn off slot, turn on Amber LED, turn off Green LED if supported*/
if (POWER_CTRL(ctrl)) {
if (pslot->hpc_ops->power_off_slot(pslot)) {
err("%s: Issue of Slot Power Off command failed\n",
__func__);
ctrl_err(ctrl,
"%s: Issue of Slot Power Off command failed\n",
__func__);
return;
}
}
@ -186,8 +192,8 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
if (ATTN_LED(ctrl)) {
if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
err("%s: Issue of Set Attention Led command failed\n",
__func__);
ctrl_err(ctrl, "%s: Issue of Set Attention "
"Led command failed\n", __func__);
return;
}
}
@ -205,9 +211,9 @@ static int board_added(struct slot *p_slot)
int retval = 0;
struct controller *ctrl = p_slot->ctrl;
dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
__func__, p_slot->device,
ctrl->slot_device_offset, p_slot->hp_slot);
ctrl_dbg(ctrl, "%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
__func__, p_slot->device, ctrl->slot_device_offset,
p_slot->hp_slot);
if (POWER_CTRL(ctrl)) {
/* Power on slot */
@ -225,22 +231,22 @@ static int board_added(struct slot *p_slot)
/* Check link training status */
retval = p_slot->hpc_ops->check_lnk_status(ctrl);
if (retval) {
err("%s: Failed to check link status\n", __func__);
ctrl_err(ctrl, "%s: Failed to check link status\n", __func__);
set_slot_off(ctrl, p_slot);
return retval;
}
/* Check for a power fault */
if (p_slot->hpc_ops->query_power_fault(p_slot)) {
dbg("%s: power fault detected\n", __func__);
ctrl_dbg(ctrl, "%s: power fault detected\n", __func__);
retval = POWER_FAILURE;
goto err_exit;
}
retval = pciehp_configure_device(p_slot);
if (retval) {
err("Cannot add device 0x%x:%x\n", p_slot->bus,
p_slot->device);
ctrl_err(ctrl, "Cannot add device 0x%x:%x\n",
p_slot->bus, p_slot->device);
goto err_exit;
}
@ -272,14 +278,14 @@ static int remove_board(struct slot *p_slot)
if (retval)
return retval;
dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
ctrl_dbg(ctrl, "In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
if (POWER_CTRL(ctrl)) {
/* power off slot */
retval = p_slot->hpc_ops->power_off_slot(p_slot);
if (retval) {
err("%s: Issue of Slot Disable command failed\n",
__func__);
ctrl_err(ctrl, "%s: Issue of Slot Disable command "
"failed\n", __func__);
return retval;
}
}
@ -320,8 +326,8 @@ static void pciehp_power_thread(struct work_struct *work)
switch (p_slot->state) {
case POWEROFF_STATE:
mutex_unlock(&p_slot->lock);
dbg("%s: disabling bus:device(%x:%x)\n",
__func__, p_slot->bus, p_slot->device);
ctrl_dbg(p_slot->ctrl, "%s: disabling bus:device(%x:%x)\n",
__func__, p_slot->bus, p_slot->device);
pciehp_disable_slot(p_slot);
mutex_lock(&p_slot->lock);
p_slot->state = STATIC_STATE;
@ -349,7 +355,8 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
err("%s: Cannot allocate memory\n", __func__);
ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
__func__);
return;
}
info->p_slot = p_slot;
@ -403,12 +410,14 @@ static void handle_button_press_event(struct slot *p_slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) {
p_slot->state = BLINKINGOFF_STATE;
info("PCI slot #%s - powering off due to button "
"press.\n", p_slot->name);
ctrl_info(ctrl,
"PCI slot #%s - powering off due to button "
"press.\n", p_slot->name);
} else {
p_slot->state = BLINKINGON_STATE;
info("PCI slot #%s - powering on due to button "
"press.\n", p_slot->name);
ctrl_info(ctrl,
"PCI slot #%s - powering on due to button "
"press.\n", p_slot->name);
}
/* blink green LED and turn off amber */
if (PWR_LED(ctrl))
@ -425,8 +434,8 @@ static void handle_button_press_event(struct slot *p_slot)
* press the attention again before the 5 sec. limit
* expires to cancel hot-add or hot-remove
*/
info("Button cancel on Slot(%s)\n", p_slot->name);
dbg("%s: button cancel\n", __func__);
ctrl_info(ctrl, "Button cancel on Slot(%s)\n", p_slot->name);
ctrl_dbg(ctrl, "%s: button cancel\n", __func__);
cancel_delayed_work(&p_slot->work);
if (p_slot->state == BLINKINGOFF_STATE) {
if (PWR_LED(ctrl))
@ -437,8 +446,8 @@ static void handle_button_press_event(struct slot *p_slot)
}
if (ATTN_LED(ctrl))
p_slot->hpc_ops->set_attention_status(p_slot, 0);
info("PCI slot #%s - action canceled due to button press\n",
p_slot->name);
ctrl_info(ctrl, "PCI slot #%s - action canceled "
"due to button press\n", p_slot->name);
p_slot->state = STATIC_STATE;
break;
case POWEROFF_STATE:
@ -448,11 +457,11 @@ static void handle_button_press_event(struct slot *p_slot)
* this means that the previous attention button action
* to hot-add or hot-remove is undergoing
*/
info("Button ignore on Slot(%s)\n", p_slot->name);
ctrl_info(ctrl, "Button ignore on Slot(%s)\n", p_slot->name);
update_slot_info(p_slot);
break;
default:
warn("Not a valid state\n");
ctrl_warn(ctrl, "Not a valid state\n");
break;
}
}
@ -467,7 +476,8 @@ static void handle_surprise_event(struct slot *p_slot)
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
err("%s: Cannot allocate memory\n", __func__);
ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
__func__);
return;
}
info->p_slot = p_slot;
@ -505,7 +515,7 @@ static void interrupt_event_handler(struct work_struct *work)
case INT_PRESENCE_OFF:
if (!HP_SUPR_RM(ctrl))
break;
dbg("Surprise Removal\n");
ctrl_dbg(ctrl, "Surprise Removal\n");
update_slot_info(p_slot);
handle_surprise_event(p_slot);
break;
@ -522,22 +532,23 @@ int pciehp_enable_slot(struct slot *p_slot)
{
u8 getstatus = 0;
int rc;
struct controller *ctrl = p_slot->ctrl;
/* Check to see if (latch closed, card present, power off) */
mutex_lock(&p_slot->ctrl->crit_sect);
rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (rc || !getstatus) {
info("%s: no adapter on slot(%s)\n", __func__,
p_slot->name);
ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
__func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
if (MRL_SENS(p_slot->ctrl)) {
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) {
info("%s: latch open on slot(%s)\n", __func__,
p_slot->name);
ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
__func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
@ -546,8 +557,8 @@ int pciehp_enable_slot(struct slot *p_slot)
if (POWER_CTRL(p_slot->ctrl)) {
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || getstatus) {
info("%s: already enabled on slot(%s)\n", __func__,
p_slot->name);
ctrl_info(ctrl, "%s: already enabled on slot(%s)\n",
__func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -EINVAL;
}
@ -571,6 +582,7 @@ int pciehp_disable_slot(struct slot *p_slot)
{
u8 getstatus = 0;
int ret = 0;
struct controller *ctrl = p_slot->ctrl;
if (!p_slot->ctrl)
return 1;
@ -581,8 +593,8 @@ int pciehp_disable_slot(struct slot *p_slot)
if (!HP_SUPR_RM(p_slot->ctrl)) {
ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (ret || !getstatus) {
info("%s: no adapter on slot(%s)\n", __func__,
p_slot->name);
ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
__func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
@ -591,8 +603,8 @@ int pciehp_disable_slot(struct slot *p_slot)
if (MRL_SENS(p_slot->ctrl)) {
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (ret || getstatus) {
info("%s: latch open on slot(%s)\n", __func__,
p_slot->name);
ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
__func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
@ -601,8 +613,8 @@ int pciehp_disable_slot(struct slot *p_slot)
if (POWER_CTRL(p_slot->ctrl)) {
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (ret || !getstatus) {
info("%s: already disabled slot(%s)\n", __func__,
p_slot->name);
ctrl_info(ctrl, "%s: already disabled slot(%s)\n",
__func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -EINVAL;
}
@ -618,6 +630,7 @@ int pciehp_disable_slot(struct slot *p_slot)
int pciehp_sysfs_enable_slot(struct slot *p_slot)
{
int retval = -ENODEV;
struct controller *ctrl = p_slot->ctrl;
mutex_lock(&p_slot->lock);
switch (p_slot->state) {
@ -631,15 +644,15 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
p_slot->state = STATIC_STATE;
break;
case POWERON_STATE:
info("Slot %s is already in powering on state\n",
p_slot->name);
ctrl_info(ctrl, "Slot %s is already in powering on state\n",
p_slot->name);
break;
case BLINKINGOFF_STATE:
case POWEROFF_STATE:
info("Already enabled on slot %s\n", p_slot->name);
ctrl_info(ctrl, "Already enabled on slot %s\n", p_slot->name);
break;
default:
err("Not a valid state on slot %s\n", p_slot->name);
ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name);
break;
}
mutex_unlock(&p_slot->lock);
@ -650,6 +663,7 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
int pciehp_sysfs_disable_slot(struct slot *p_slot)
{
int retval = -ENODEV;
struct controller *ctrl = p_slot->ctrl;
mutex_lock(&p_slot->lock);
switch (p_slot->state) {
@ -663,15 +677,15 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
p_slot->state = STATIC_STATE;
break;
case POWEROFF_STATE:
info("Slot %s is already in powering off state\n",
p_slot->name);
ctrl_info(ctrl, "Slot %s is already in powering off state\n",
p_slot->name);
break;
case BLINKINGON_STATE:
case POWERON_STATE:
info("Already disabled on slot %s\n", p_slot->name);
ctrl_info(ctrl, "Already disabled on slot %s\n", p_slot->name);
break;
default:
err("Not a valid state on slot %s\n", p_slot->name);
ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name);
break;
}
mutex_unlock(&p_slot->lock);

View file

@ -223,7 +223,7 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)
static inline int pciehp_request_irq(struct controller *ctrl)
{
int retval, irq = ctrl->pci_dev->irq;
int retval, irq = ctrl->pcie->irq;
/* Install interrupt polling timer. Start with 10 sec delay */
if (pciehp_poll_mode) {
@ -235,7 +235,8 @@ static inline int pciehp_request_irq(struct controller *ctrl)
/* Installs the interrupt handler */
retval = request_irq(irq, pcie_isr, IRQF_SHARED, MY_NAME, ctrl);
if (retval)
err("Cannot get irq %d for the hotplug controller\n", irq);
ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n",
irq);
return retval;
}
@ -244,7 +245,7 @@ static inline void pciehp_free_irq(struct controller *ctrl)
if (pciehp_poll_mode)
del_timer_sync(&ctrl->poll_timer);
else
free_irq(ctrl->pci_dev->irq, ctrl);
free_irq(ctrl->pcie->irq, ctrl);
}
static int pcie_poll_cmd(struct controller *ctrl)
@ -282,7 +283,7 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll)
else
rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout);
if (!rc)
dbg("Command not completed in 1000 msec\n");
ctrl_dbg(ctrl, "Command not completed in 1000 msec\n");
}
/**
@ -301,7 +302,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
err("%s: Cannot read SLOTSTATUS register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
__func__);
goto out;
}
@ -312,26 +314,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
* proceed forward to issue the next command according
* to spec. Just print out the error message.
*/
dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
__func__);
ctrl_dbg(ctrl,
"%s: CMD_COMPLETED not clear after 1 sec.\n",
__func__);
} else if (!NO_CMD_CMPL(ctrl)) {
/*
* This controller semms to notify of command completed
* event even though it supports none of power
* controller, attention led, power led and EMI.
*/
dbg("%s: Unexpected CMD_COMPLETED. Need to wait for "
"command completed event.\n", __func__);
ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Need to "
"wait for command completed event.\n",
__func__);
ctrl->no_cmd_complete = 0;
} else {
dbg("%s: Unexpected CMD_COMPLETED. Maybe the "
"controller is broken.\n", __func__);
ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Maybe "
"the controller is broken.\n", __func__);
}
}
retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
if (retval) {
err("%s: Cannot read SLOTCTRL register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
goto out;
}
@ -341,7 +345,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
smp_mb();
retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl);
if (retval)
err("%s: Cannot write to SLOTCTRL register\n", __func__);
ctrl_err(ctrl, "%s: Cannot write to SLOTCTRL register\n",
__func__);
/*
* Wait for command completion.
@ -370,14 +375,15 @@ static int hpc_check_lnk_status(struct controller *ctrl)
retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
if (retval) {
err("%s: Cannot read LNKSTATUS register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
__func__);
return retval;
}
dbg("%s: lnk_status = %x\n", __func__, lnk_status);
ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) ||
!(lnk_status & NEG_LINK_WD)) {
err("%s : Link Training Error occurs \n", __func__);
ctrl_err(ctrl, "%s : Link Training Error occurs \n", __func__);
retval = -1;
return retval;
}
@ -394,12 +400,12 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
if (retval) {
err("%s: Cannot read SLOTCTRL register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
return retval;
}
dbg("%s: SLOTCTRL %x, value read %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
@ -433,11 +439,11 @@ static int hpc_get_power_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
if (retval) {
err("%s: Cannot read SLOTCTRL register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
return retval;
}
dbg("%s: SLOTCTRL %x value read %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
@ -464,7 +470,8 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
err("%s: Cannot read SLOTSTATUS register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
__func__);
return retval;
}
@ -482,7 +489,8 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
err("%s: Cannot read SLOTSTATUS register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
__func__);
return retval;
}
card_state = (u8)((slot_status & PRSN_STATE) >> 6);
@ -500,7 +508,7 @@ static int hpc_query_power_fault(struct slot *slot)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
err("%s: Cannot check for power fault\n", __func__);
ctrl_err(ctrl, "%s: Cannot check for power fault\n", __func__);
return retval;
}
pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
@ -516,7 +524,7 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
err("%s : Cannot check EMI status\n", __func__);
ctrl_err(ctrl, "%s : Cannot check EMI status\n", __func__);
return retval;
}
*status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT;
@ -560,8 +568,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
return -1;
}
rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
dbg("%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
return rc;
}
@ -575,8 +583,8 @@ static void hpc_set_green_led_on(struct slot *slot)
slot_cmd = 0x0100;
cmd_mask = PWR_LED_CTRL;
pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
dbg("%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
}
static void hpc_set_green_led_off(struct slot *slot)
@ -588,8 +596,8 @@ static void hpc_set_green_led_off(struct slot *slot)
slot_cmd = 0x0300;
cmd_mask = PWR_LED_CTRL;
pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
dbg("%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
}
static void hpc_set_green_led_blink(struct slot *slot)
@ -601,8 +609,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
slot_cmd = 0x0200;
cmd_mask = PWR_LED_CTRL;
pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
dbg("%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
}
static int hpc_power_on_slot(struct slot * slot)
@ -613,20 +621,22 @@ static int hpc_power_on_slot(struct slot * slot)
u16 slot_status;
int retval = 0;
dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
/* Clear sticky power-fault bit from previous power failures */
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
err("%s: Cannot read SLOTSTATUS register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
__func__);
return retval;
}
slot_status &= PWR_FAULT_DETECTED;
if (slot_status) {
retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status);
if (retval) {
err("%s: Cannot write to SLOTSTATUS register\n",
__func__);
ctrl_err(ctrl,
"%s: Cannot write to SLOTSTATUS register\n",
__func__);
return retval;
}
}
@ -644,11 +654,12 @@ static int hpc_power_on_slot(struct slot * slot)
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
if (retval) {
err("%s: Write %x command failed!\n", __func__, slot_cmd);
ctrl_err(ctrl, "%s: Write %x command failed!\n",
__func__, slot_cmd);
return -1;
}
dbg("%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
return retval;
}
@ -694,7 +705,7 @@ static int hpc_power_off_slot(struct slot * slot)
int retval = 0;
int changed;
dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
/*
* Set Bad DLLP Mask bit in Correctable Error Mask
@ -722,12 +733,12 @@ static int hpc_power_off_slot(struct slot * slot)
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
if (retval) {
err("%s: Write command failed!\n", __func__);
ctrl_err(ctrl, "%s: Write command failed!\n", __func__);
retval = -1;
goto out;
}
dbg("%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
out:
if (changed)
pcie_unmask_bad_dllp(ctrl);
@ -749,7 +760,8 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
intr_loc = 0;
do {
if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) {
err("%s: Cannot read SLOTSTATUS\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n",
__func__);
return IRQ_NONE;
}
@ -760,12 +772,13 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
if (!intr_loc)
return IRQ_NONE;
if (detected && pciehp_writew(ctrl, SLOTSTATUS, detected)) {
err("%s: Cannot write to SLOTSTATUS\n", __func__);
ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
__func__);
return IRQ_NONE;
}
} while (detected);
dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc);
/* Check Command Complete Interrupt Pending */
if (intr_loc & CMD_COMPLETED) {
@ -807,7 +820,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
if (retval) {
err("%s: Cannot read LNKCAP register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
return retval;
}
@ -821,7 +834,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
}
*value = lnk_speed;
dbg("Max link speed = %d\n", lnk_speed);
ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed);
return retval;
}
@ -836,7 +849,7 @@ static int hpc_get_max_lnk_width(struct slot *slot,
retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
if (retval) {
err("%s: Cannot read LNKCAP register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
return retval;
}
@ -871,7 +884,7 @@ static int hpc_get_max_lnk_width(struct slot *slot,
}
*value = lnk_wdth;
dbg("Max link width = %d\n", lnk_wdth);
ctrl_dbg(ctrl, "Max link width = %d\n", lnk_wdth);
return retval;
}
@ -885,7 +898,8 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
if (retval) {
err("%s: Cannot read LNKSTATUS register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
__func__);
return retval;
}
@ -899,7 +913,7 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
}
*value = lnk_speed;
dbg("Current link speed = %d\n", lnk_speed);
ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed);
return retval;
}
@ -914,7 +928,8 @@ static int hpc_get_cur_lnk_width(struct slot *slot,
retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
if (retval) {
err("%s: Cannot read LNKSTATUS register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
__func__);
return retval;
}
@ -949,7 +964,7 @@ static int hpc_get_cur_lnk_width(struct slot *slot,
}
*value = lnk_wdth;
dbg("Current link width = %d\n", lnk_wdth);
ctrl_dbg(ctrl, "Current link width = %d\n", lnk_wdth);
return retval;
}
@ -998,7 +1013,8 @@ int pcie_enable_notification(struct controller *ctrl)
PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE;
if (pcie_write_cmd(ctrl, cmd, mask)) {
err("%s: Cannot enable software notification\n", __func__);
ctrl_err(ctrl, "%s: Cannot enable software notification\n",
__func__);
return -1;
}
return 0;
@ -1010,7 +1026,8 @@ static void pcie_disable_notification(struct controller *ctrl)
mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE |
PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE;
if (pcie_write_cmd(ctrl, 0, mask))
warn("%s: Cannot disable software notification\n", __func__);
ctrl_warn(ctrl, "%s: Cannot disable software notification\n",
__func__);
}
static int pcie_init_notification(struct controller *ctrl)
@ -1071,34 +1088,45 @@ static inline void dbg_ctrl(struct controller *ctrl)
if (!pciehp_debug)
return;
dbg("Hotplug Controller:\n");
dbg(" Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", pci_name(pdev), pdev->irq);
dbg(" Vendor ID : 0x%04x\n", pdev->vendor);
dbg(" Device ID : 0x%04x\n", pdev->device);
dbg(" Subsystem ID : 0x%04x\n", pdev->subsystem_device);
dbg(" Subsystem Vendor ID : 0x%04x\n", pdev->subsystem_vendor);
dbg(" PCIe Cap offset : 0x%02x\n", ctrl->cap_base);
ctrl_info(ctrl, "Hotplug Controller:\n");
ctrl_info(ctrl, " Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n",
pci_name(pdev), pdev->irq);
ctrl_info(ctrl, " Vendor ID : 0x%04x\n", pdev->vendor);
ctrl_info(ctrl, " Device ID : 0x%04x\n", pdev->device);
ctrl_info(ctrl, " Subsystem ID : 0x%04x\n",
pdev->subsystem_device);
ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n",
pdev->subsystem_vendor);
ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base);
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
if (!pci_resource_len(pdev, i))
continue;
dbg(" PCI resource [%d] : 0x%llx@0x%llx\n", i,
(unsigned long long)pci_resource_len(pdev, i),
(unsigned long long)pci_resource_start(pdev, i));
ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n",
i, (unsigned long long)pci_resource_len(pdev, i),
(unsigned long long)pci_resource_start(pdev, i));
}
dbg("Slot Capabilities : 0x%08x\n", ctrl->slot_cap);
dbg(" Physical Slot Number : %d\n", ctrl->first_slot);
dbg(" Attention Button : %3s\n", ATTN_BUTTN(ctrl) ? "yes" : "no");
dbg(" Power Controller : %3s\n", POWER_CTRL(ctrl) ? "yes" : "no");
dbg(" MRL Sensor : %3s\n", MRL_SENS(ctrl) ? "yes" : "no");
dbg(" Attention Indicator : %3s\n", ATTN_LED(ctrl) ? "yes" : "no");
dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no");
dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no");
dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no");
dbg(" Command Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes");
ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap);
ctrl_info(ctrl, " Physical Slot Number : %d\n", ctrl->first_slot);
ctrl_info(ctrl, " Attention Button : %3s\n",
ATTN_BUTTN(ctrl) ? "yes" : "no");
ctrl_info(ctrl, " Power Controller : %3s\n",
POWER_CTRL(ctrl) ? "yes" : "no");
ctrl_info(ctrl, " MRL Sensor : %3s\n",
MRL_SENS(ctrl) ? "yes" : "no");
ctrl_info(ctrl, " Attention Indicator : %3s\n",
ATTN_LED(ctrl) ? "yes" : "no");
ctrl_info(ctrl, " Power Indicator : %3s\n",
PWR_LED(ctrl) ? "yes" : "no");
ctrl_info(ctrl, " Hot-Plug Surprise : %3s\n",
HP_SUPR_RM(ctrl) ? "yes" : "no");
ctrl_info(ctrl, " EMI Present : %3s\n",
EMI(ctrl) ? "yes" : "no");
ctrl_info(ctrl, " Command Completed : %3s\n",
NO_CMD_CMPL(ctrl) ? "no" : "yes");
pciehp_readw(ctrl, SLOTSTATUS, &reg16);
dbg("Slot Status : 0x%04x\n", reg16);
ctrl_info(ctrl, "Slot Status : 0x%04x\n", reg16);
pciehp_readw(ctrl, SLOTCTRL, &reg16);
dbg("Slot Control : 0x%04x\n", reg16);
ctrl_info(ctrl, "Slot Control : 0x%04x\n", reg16);
}
struct controller *pcie_init(struct pcie_device *dev)
@ -1109,19 +1137,21 @@ struct controller *pcie_init(struct pcie_device *dev)
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __func__);
dev_err(&dev->device, "%s : out of memory\n", __func__);
goto abort;
}
INIT_LIST_HEAD(&ctrl->slot_list);
ctrl->pcie = dev;
ctrl->pci_dev = pdev;
ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (!ctrl->cap_base) {
err("%s: Cannot find PCI Express capability\n", __func__);
ctrl_err(ctrl, "%s: Cannot find PCI Express capability\n",
__func__);
goto abort;
}
if (pciehp_readl(ctrl, SLOTCAP, &slot_cap)) {
err("%s: Cannot read SLOTCAP register\n", __func__);
ctrl_err(ctrl, "%s: Cannot read SLOTCAP register\n", __func__);
goto abort;
}
@ -1161,9 +1191,9 @@ struct controller *pcie_init(struct pcie_device *dev)
goto abort_ctrl;
}
info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device);
ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
pdev->vendor, pdev->device, pdev->subsystem_vendor,
pdev->subsystem_device);
if (pcie_init_slot(ctrl))
goto abort_ctrl;

View file

@ -198,18 +198,20 @@ int pciehp_configure_device(struct slot *p_slot)
struct pci_dev *dev;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
int num, fn;
struct controller *ctrl = p_slot->ctrl;
dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
if (dev) {
err("Device %s already exists at %x:%x, cannot hot-add\n",
pci_name(dev), p_slot->bus, p_slot->device);
ctrl_err(ctrl,
"Device %s already exists at %x:%x, cannot hot-add\n",
pci_name(dev), p_slot->bus, p_slot->device);
pci_dev_put(dev);
return -EINVAL;
}
num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
if (num == 0) {
err("No new device found\n");
ctrl_err(ctrl, "No new device found\n");
return -ENODEV;
}
@ -218,8 +220,8 @@ int pciehp_configure_device(struct slot *p_slot)
if (!dev)
continue;
if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
err("Cannot hot-add display device %s\n",
pci_name(dev));
ctrl_err(ctrl, "Cannot hot-add display device %s\n",
pci_name(dev));
pci_dev_put(dev);
continue;
}
@ -244,9 +246,10 @@ int pciehp_unconfigure_device(struct slot *p_slot)
u8 presence = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
u16 command;
struct controller *ctrl = p_slot->ctrl;
dbg("%s: bus/dev = %x/%x\n", __func__, p_slot->bus,
p_slot->device);
ctrl_dbg(ctrl, "%s: bus/dev = %x/%x\n", __func__,
p_slot->bus, p_slot->device);
ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence);
if (ret)
presence = 0;
@ -257,16 +260,17 @@ int pciehp_unconfigure_device(struct slot *p_slot)
if (!temp)
continue;
if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
err("Cannot remove display device %s\n",
pci_name(temp));
ctrl_err(ctrl, "Cannot remove display device %s\n",
pci_name(temp));
pci_dev_put(temp);
continue;
}
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
if (bctl & PCI_BRIDGE_CTL_VGA) {
err("Cannot remove display device %s\n",
pci_name(temp));
ctrl_err(ctrl,
"Cannot remove display device %s\n",
pci_name(temp));
pci_dev_put(temp);
continue;
}

View file

@ -46,10 +46,10 @@
#define PRESENT 1 /* Card in slot */
#define MY_NAME "rpaphp"
extern int debug;
extern int rpaphp_debug;
#define dbg(format, arg...) \
do { \
if (debug) \
if (rpaphp_debug) \
printk(KERN_DEBUG "%s: " format, \
MY_NAME , ## arg); \
} while (0)

View file

@ -37,7 +37,7 @@
/* and pci_do_scan_bus */
#include "rpaphp.h"
int debug;
int rpaphp_debug;
LIST_HEAD(rpaphp_slot_head);
#define DRIVER_VERSION "0.1"
@ -50,7 +50,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
module_param(debug, bool, 0644);
module_param_named(debug, rpaphp_debug, bool, 0644);
/**
* set_attention_status - set attention LED

View file

@ -123,7 +123,7 @@ int rpaphp_enable_slot(struct slot *slot)
slot->state = CONFIGURED;
}
if (debug) {
if (rpaphp_debug) {
struct pci_dev *dev;
dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name);
list_for_each_entry (dev, &bus->devices, bus_list)

View file

@ -126,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
cfg->msg.address_hi = 0xffffffff;
irq = create_irq();
if (irq < 0) {
if (irq <= 0) {
kfree(cfg);
return -EBUSY;
}

View file

@ -1,3 +1,4 @@
#include <linux/interrupt.h>
#include <linux/dmar.h>
#include <linux/spinlock.h>
#include <linux/jiffies.h>
@ -11,41 +12,64 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
static int ir_ioapic_num;
int intr_remapping_enabled;
static struct {
struct irq_2_iommu {
struct intel_iommu *iommu;
u16 irte_index;
u16 sub_handle;
u8 irte_mask;
} irq_2_iommu[NR_IRQS];
};
static struct irq_2_iommu irq_2_iommuX[NR_IRQS];
static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
{
return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL;
}
static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
{
return irq_2_iommu(irq);
}
static DEFINE_SPINLOCK(irq_2_ir_lock);
static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq)
{
struct irq_2_iommu *irq_iommu;
irq_iommu = irq_2_iommu(irq);
if (!irq_iommu)
return NULL;
if (!irq_iommu->iommu)
return NULL;
return irq_iommu;
}
int irq_remapped(int irq)
{
if (irq > NR_IRQS)
return 0;
if (!irq_2_iommu[irq].iommu)
return 0;
return 1;
return valid_irq_2_iommu(irq) != NULL;
}
int get_irte(int irq, struct irte *entry)
{
int index;
struct irq_2_iommu *irq_iommu;
if (!entry || irq > NR_IRQS)
if (!entry)
return -1;
spin_lock(&irq_2_ir_lock);
if (!irq_2_iommu[irq].iommu) {
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
*entry = *(irq_2_iommu[irq].iommu->ir_table->base + index);
index = irq_iommu->irte_index + irq_iommu->sub_handle;
*entry = *(irq_iommu->iommu->ir_table->base + index);
spin_unlock(&irq_2_ir_lock);
return 0;
@ -54,6 +78,7 @@ int get_irte(int irq, struct irte *entry)
int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
{
struct ir_table *table = iommu->ir_table;
struct irq_2_iommu *irq_iommu;
u16 index, start_index;
unsigned int mask = 0;
int i;
@ -61,6 +86,10 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
if (!count)
return -1;
/* protect irq_2_iommu_alloc later */
if (irq >= nr_irqs)
return -1;
/*
* start the IRTE search from index 0.
*/
@ -100,10 +129,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
for (i = index; i < index + count; i++)
table->base[i].present = 1;
irq_2_iommu[irq].iommu = iommu;
irq_2_iommu[irq].irte_index = index;
irq_2_iommu[irq].sub_handle = 0;
irq_2_iommu[irq].irte_mask = mask;
irq_iommu = irq_2_iommu_alloc(irq);
irq_iommu->iommu = iommu;
irq_iommu->irte_index = index;
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = mask;
spin_unlock(&irq_2_ir_lock);
@ -124,31 +154,33 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
int map_irq_to_irte_handle(int irq, u16 *sub_handle)
{
int index;
struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
*sub_handle = irq_2_iommu[irq].sub_handle;
index = irq_2_iommu[irq].irte_index;
*sub_handle = irq_iommu->sub_handle;
index = irq_iommu->irte_index;
spin_unlock(&irq_2_ir_lock);
return index;
}
int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
{
spin_lock(&irq_2_ir_lock);
if (irq >= NR_IRQS || irq_2_iommu[irq].iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
struct irq_2_iommu *irq_iommu;
irq_2_iommu[irq].iommu = iommu;
irq_2_iommu[irq].irte_index = index;
irq_2_iommu[irq].sub_handle = subhandle;
irq_2_iommu[irq].irte_mask = 0;
spin_lock(&irq_2_ir_lock);
irq_iommu = irq_2_iommu_alloc(irq);
irq_iommu->iommu = iommu;
irq_iommu->irte_index = index;
irq_iommu->sub_handle = subhandle;
irq_iommu->irte_mask = 0;
spin_unlock(&irq_2_ir_lock);
@ -157,16 +189,19 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
{
struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
irq_2_iommu[irq].iommu = NULL;
irq_2_iommu[irq].irte_index = 0;
irq_2_iommu[irq].sub_handle = 0;
irq_2_iommu[irq].irte_mask = 0;
irq_iommu->iommu = NULL;
irq_iommu->irte_index = 0;
irq_iommu->sub_handle = 0;
irq_2_iommu(irq)->irte_mask = 0;
spin_unlock(&irq_2_ir_lock);
@ -178,16 +213,18 @@ int modify_irte(int irq, struct irte *irte_modified)
int index;
struct irte *irte;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
iommu = irq_2_iommu[irq].iommu;
iommu = irq_iommu->iommu;
index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
index = irq_iommu->irte_index + irq_iommu->sub_handle;
irte = &iommu->ir_table->base[index];
set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
@ -203,18 +240,20 @@ int flush_irte(int irq)
{
int index;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
iommu = irq_2_iommu[irq].iommu;
iommu = irq_iommu->iommu;
index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
index = irq_iommu->irte_index + irq_iommu->sub_handle;
qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask);
qi_flush_iec(iommu, index, irq_iommu->irte_mask);
spin_unlock(&irq_2_ir_lock);
return 0;
@ -246,28 +285,30 @@ int free_irte(int irq)
int index, i;
struct irte *irte;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
iommu = irq_2_iommu[irq].iommu;
iommu = irq_iommu->iommu;
index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
index = irq_iommu->irte_index + irq_iommu->sub_handle;
irte = &iommu->ir_table->base[index];
if (!irq_2_iommu[irq].sub_handle) {
for (i = 0; i < (1 << irq_2_iommu[irq].irte_mask); i++)
if (!irq_iommu->sub_handle) {
for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
set_64bit((unsigned long *)irte, 0);
qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask);
qi_flush_iec(iommu, index, irq_iommu->irte_mask);
}
irq_2_iommu[irq].iommu = NULL;
irq_2_iommu[irq].irte_index = 0;
irq_2_iommu[irq].sub_handle = 0;
irq_2_iommu[irq].irte_mask = 0;
irq_iommu->iommu = NULL;
irq_iommu->irte_index = 0;
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = 0;
spin_unlock(&irq_2_ir_lock);

View file

@ -378,23 +378,21 @@ static int msi_capability_init(struct pci_dev *dev)
entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
if (is_mask_bit_support(control)) {
if (entry->msi_attrib.maskbit) {
entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
is_64bit_address(control));
entry->msi_attrib.is_64);
}
entry->dev = dev;
if (entry->msi_attrib.maskbit) {
unsigned int maskbits, temp;
/* All MSIs are unmasked by default, Mask them all */
pci_read_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)),
msi_mask_bits_reg(pos, entry->msi_attrib.is_64),
&maskbits);
temp = (1 << multi_msi_capable(control));
temp = ((temp - 1) & ~temp);
maskbits |= temp;
pci_write_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)),
maskbits);
pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits);
entry->msi_attrib.maskbits_mask = temp;
}
list_add_tail(&entry->list, &dev->msi_list);

View file

@ -43,18 +43,32 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
{
struct pci_dynid *dynid;
struct pci_driver *pdrv = to_pci_driver(driver);
const struct pci_device_id *ids = pdrv->id_table;
__u32 vendor, device, subvendor=PCI_ANY_ID,
subdevice=PCI_ANY_ID, class=0, class_mask=0;
unsigned long driver_data=0;
int fields=0;
int retval = 0;
int retval;
fields = sscanf(buf, "%x %x %x %x %x %x %lux",
fields = sscanf(buf, "%x %x %x %x %x %x %lx",
&vendor, &device, &subvendor, &subdevice,
&class, &class_mask, &driver_data);
if (fields < 2)
return -EINVAL;
/* Only accept driver_data values that match an existing id_table
entry */
retval = -EINVAL;
while (ids->vendor || ids->subvendor || ids->class_mask) {
if (driver_data == ids->driver_data) {
retval = 0;
break;
}
ids++;
}
if (retval) /* No match */
return retval;
dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
if (!dynid)
return -ENOMEM;
@ -65,8 +79,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
dynid->id.subdevice = subdevice;
dynid->id.class = class;
dynid->id.class_mask = class_mask;
dynid->id.driver_data = pdrv->dynids.use_driver_data ?
driver_data : 0UL;
dynid->id.driver_data = driver_data;
spin_lock(&pdrv->dynids.lock);
list_add_tail(&dynid->node, &pdrv->dynids.list);

View file

@ -423,7 +423,7 @@ pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr,
* Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
* callback routine (pci_legacy_read).
*/
ssize_t
static ssize_t
pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
@ -448,7 +448,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
* Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
* callback routine (pci_legacy_write).
*/
ssize_t
static ssize_t
pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
@ -468,11 +468,11 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
* @attr: struct bin_attribute for this file
* @vma: struct vm_area_struct passed to mmap
*
* Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
* Uses an arch specific callback, pci_mmap_legacy_mem_page_range, to mmap
* legacy memory space (first meg of bus space) into application virtual
* memory space.
*/
int
static int
pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma)
{
@ -480,7 +480,90 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
struct device,
kobj));
return pci_mmap_legacy_page_range(bus, vma);
return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem);
}
/**
* pci_mmap_legacy_io - map legacy PCI IO into user memory space
* @kobj: kobject corresponding to device to be mapped
* @attr: struct bin_attribute for this file
* @vma: struct vm_area_struct passed to mmap
*
* Uses an arch specific callback, pci_mmap_legacy_io_page_range, to mmap
* legacy IO space (first meg of bus space) into application virtual
* memory space. Returns -ENOSYS if the operation isn't supported
*/
static int
pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma)
{
struct pci_bus *bus = to_pci_bus(container_of(kobj,
struct device,
kobj));
return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
}
/**
* pci_create_legacy_files - create legacy I/O port and memory files
* @b: bus to create files under
*
* Some platforms allow access to legacy I/O port and ISA memory space on
* a per-bus basis. This routine creates the files and ties them into
* their associated read, write and mmap files from pci-sysfs.c
*
* On error unwind, but don't propogate the error to the caller
* as it is ok to set up the PCI bus without these files.
*/
void pci_create_legacy_files(struct pci_bus *b)
{
int error;
b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
GFP_ATOMIC);
if (!b->legacy_io)
goto kzalloc_err;
b->legacy_io->attr.name = "legacy_io";
b->legacy_io->size = 0xffff;
b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_io->read = pci_read_legacy_io;
b->legacy_io->write = pci_write_legacy_io;
b->legacy_io->mmap = pci_mmap_legacy_io;
error = device_create_bin_file(&b->dev, b->legacy_io);
if (error)
goto legacy_io_err;
/* Allocated above after the legacy_io struct */
b->legacy_mem = b->legacy_io + 1;
b->legacy_mem->attr.name = "legacy_mem";
b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_mem->mmap = pci_mmap_legacy_mem;
error = device_create_bin_file(&b->dev, b->legacy_mem);
if (error)
goto legacy_mem_err;
return;
legacy_mem_err:
device_remove_bin_file(&b->dev, b->legacy_io);
legacy_io_err:
kfree(b->legacy_io);
b->legacy_io = NULL;
kzalloc_err:
printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
"and ISA memory resources to sysfs\n");
return;
}
void pci_remove_legacy_files(struct pci_bus *b)
{
if (b->legacy_io) {
device_remove_bin_file(&b->dev, b->legacy_io);
device_remove_bin_file(&b->dev, b->legacy_mem);
kfree(b->legacy_io); /* both are allocated here */
}
}
#endif /* HAVE_PCI_LEGACY */
@ -715,7 +798,7 @@ static struct bin_attribute pci_config_attr = {
.name = "config",
.mode = S_IRUGO | S_IWUSR,
},
.size = 256,
.size = PCI_CFG_SPACE_SIZE,
.read = pci_read_config,
.write = pci_write_config,
};
@ -725,7 +808,7 @@ static struct bin_attribute pcie_config_attr = {
.name = "config",
.mode = S_IRUGO | S_IWUSR,
},
.size = 4096,
.size = PCI_CFG_SPACE_EXP_SIZE,
.read = pci_read_config,
.write = pci_write_config,
};
@ -735,86 +818,103 @@ int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev)
return 0;
}
static int pci_create_capabilities_sysfs(struct pci_dev *dev)
{
int retval;
struct bin_attribute *attr;
/* If the device has VPD, try to expose it in sysfs. */
if (dev->vpd) {
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
if (!attr)
return -ENOMEM;
attr->size = dev->vpd->len;
attr->attr.name = "vpd";
attr->attr.mode = S_IRUSR | S_IWUSR;
attr->read = pci_read_vpd;
attr->write = pci_write_vpd;
retval = sysfs_create_bin_file(&dev->dev.kobj, attr);
if (retval) {
kfree(dev->vpd->attr);
return retval;
}
dev->vpd->attr = attr;
}
/* Active State Power Management */
pcie_aspm_create_sysfs_dev_files(dev);
return 0;
}
int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
struct bin_attribute *attr = NULL;
int retval;
int rom_size = 0;
struct bin_attribute *attr;
if (!sysfs_initialized)
return -EACCES;
if (pdev->cfg_size < 4096)
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
if (retval)
goto err;
/* If the device has VPD, try to expose it in sysfs. */
if (pdev->vpd) {
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
if (attr) {
pdev->vpd->attr = attr;
attr->size = pdev->vpd->len;
attr->attr.name = "vpd";
attr->attr.mode = S_IRUSR | S_IWUSR;
attr->read = pci_read_vpd;
attr->write = pci_write_vpd;
retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
if (retval)
goto err_vpd;
} else {
retval = -ENOMEM;
goto err_config_file;
}
}
retval = pci_create_resource_files(pdev);
if (retval)
goto err_vpd_file;
goto err_config_file;
if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
rom_size = 0x20000;
/* If the device has a ROM, try to expose it in sysfs. */
if (pci_resource_len(pdev, PCI_ROM_RESOURCE) ||
(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) {
if (rom_size) {
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
if (attr) {
pdev->rom_attr = attr;
attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
attr->attr.name = "rom";
attr->attr.mode = S_IRUSR;
attr->read = pci_read_rom;
attr->write = pci_write_rom;
retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
if (retval)
goto err_rom;
} else {
if (!attr) {
retval = -ENOMEM;
goto err_resource_files;
}
attr->size = rom_size;
attr->attr.name = "rom";
attr->attr.mode = S_IRUSR;
attr->read = pci_read_rom;
attr->write = pci_write_rom;
retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
if (retval) {
kfree(attr);
goto err_resource_files;
}
pdev->rom_attr = attr;
}
/* add platform-specific attributes */
if (pcibios_add_platform_entries(pdev))
retval = pcibios_add_platform_entries(pdev);
if (retval)
goto err_rom_file;
pcie_aspm_create_sysfs_dev_files(pdev);
/* add sysfs entries for various capabilities */
retval = pci_create_capabilities_sysfs(pdev);
if (retval)
goto err_rom_file;
return 0;
err_rom_file:
if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
if (rom_size) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
err_rom:
kfree(pdev->rom_attr);
kfree(pdev->rom_attr);
pdev->rom_attr = NULL;
}
err_resource_files:
pci_remove_resource_files(pdev);
err_vpd_file:
if (pdev->vpd) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
err_vpd:
kfree(pdev->vpd->attr);
}
err_config_file:
if (pdev->cfg_size < 4096)
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
@ -822,6 +922,16 @@ err:
return retval;
}
static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
{
if (dev->vpd && dev->vpd->attr) {
sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
kfree(dev->vpd->attr);
}
pcie_aspm_remove_sysfs_dev_files(dev);
}
/**
* pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
* @pdev: device whose entries we should free
@ -830,27 +940,28 @@ err:
*/
void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
{
int rom_size = 0;
if (!sysfs_initialized)
return;
pcie_aspm_remove_sysfs_dev_files(pdev);
pci_remove_capabilities_sysfs(pdev);
if (pdev->vpd) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
kfree(pdev->vpd->attr);
}
if (pdev->cfg_size < 4096)
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
pci_remove_resource_files(pdev);
if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
if (pdev->rom_attr) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
kfree(pdev->rom_attr);
}
if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
rom_size = 0x20000;
if (rom_size && pdev->rom_attr) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
kfree(pdev->rom_attr);
}
}

View file

@ -213,10 +213,13 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
int pci_find_ext_capability(struct pci_dev *dev, int cap)
{
u32 header;
int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
int pos = 0x100;
int ttl;
int pos = PCI_CFG_SPACE_SIZE;
if (dev->cfg_size <= 256)
/* minimum 8 bytes per capability */
ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
return 0;
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
@ -234,7 +237,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
return pos;
pos = PCI_EXT_CAP_NEXT(header);
if (pos < 0x100)
if (pos < PCI_CFG_SPACE_SIZE)
break;
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
@ -1126,6 +1129,27 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
return pme_done ? 0 : error;
}
/**
* pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
* @dev: PCI device to prepare
* @enable: True to enable wake-up event generation; false to disable
*
* Many drivers want the device to wake up the system from D3_hot or D3_cold
* and this function allows them to set that up cleanly - pci_enable_wake()
* should not be called twice in a row to enable wake-up due to PCI PM vs ACPI
* ordering constraints.
*
* This function only returns error code if the device is not capable of
* generating PME# from both D3_hot and D3_cold, and the platform is unable to
* enable wake-up power for it.
*/
int pci_wake_from_d3(struct pci_dev *dev, bool enable)
{
return pci_pme_capable(dev, PCI_D3cold) ?
pci_enable_wake(dev, PCI_D3cold, enable) :
pci_enable_wake(dev, PCI_D3hot, enable);
}
/**
* pci_target_state - find an appropriate low power state for a given PCI dev
* @dev: PCI device
@ -1242,25 +1266,25 @@ void pci_pm_init(struct pci_dev *dev)
dev->d1_support = false;
dev->d2_support = false;
if (!pci_no_d1d2(dev)) {
if (pmc & PCI_PM_CAP_D1) {
dev_printk(KERN_DEBUG, &dev->dev, "supports D1\n");
if (pmc & PCI_PM_CAP_D1)
dev->d1_support = true;
}
if (pmc & PCI_PM_CAP_D2) {
dev_printk(KERN_DEBUG, &dev->dev, "supports D2\n");
if (pmc & PCI_PM_CAP_D2)
dev->d2_support = true;
}
if (dev->d1_support || dev->d2_support)
dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n",
dev->d1_support ? " D1" : "",
dev->d2_support ? " D2" : "");
}
pmc &= PCI_PM_CAP_PME_MASK;
if (pmc) {
dev_printk(KERN_INFO, &dev->dev,
"PME# supported from%s%s%s%s%s\n",
(pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
(pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
(pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
(pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
(pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n",
(pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
(pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
(pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
(pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
(pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
/*
* Make device's PM flags reflect the wake-up capability, but
@ -1275,6 +1299,38 @@ void pci_pm_init(struct pci_dev *dev)
}
}
/**
* pci_enable_ari - enable ARI forwarding if hardware support it
* @dev: the PCI device
*/
void pci_enable_ari(struct pci_dev *dev)
{
int pos;
u32 cap;
u16 ctrl;
if (!dev->is_pcie)
return;
if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
return;
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return;
pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_DEVCAP2_ARI))
return;
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
ctrl |= PCI_EXP_DEVCTL2_ARI;
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
dev->ari_enabled = 1;
}
int
pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
{
@ -1942,6 +1998,7 @@ EXPORT_SYMBOL(pci_restore_state);
EXPORT_SYMBOL(pci_pme_capable);
EXPORT_SYMBOL(pci_pme_active);
EXPORT_SYMBOL(pci_enable_wake);
EXPORT_SYMBOL(pci_wake_from_d3);
EXPORT_SYMBOL(pci_target_state);
EXPORT_SYMBOL(pci_prepare_to_sleep);
EXPORT_SYMBOL(pci_back_from_sleep);

View file

@ -1,3 +1,9 @@
#ifndef DRIVERS_PCI_H
#define DRIVERS_PCI_H
#define PCI_CFG_SPACE_SIZE 256
#define PCI_CFG_SPACE_EXP_SIZE 4096
/* Functions internal to the PCI core code */
extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
@ -76,7 +82,13 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
/* Functions for PCI Hotplug drivers to use */
extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
#ifdef HAVE_PCI_LEGACY
extern void pci_create_legacy_files(struct pci_bus *bus);
extern void pci_remove_legacy_files(struct pci_bus *bus);
#else
static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
#endif
/* Lock for read/write access to pci device and bus lists */
extern struct rw_semaphore pci_bus_sem;
@ -109,6 +121,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[];
extern struct device_attribute dev_attr_cpuaffinity;
extern struct device_attribute dev_attr_cpulistaffinity;
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
@ -144,3 +157,16 @@ struct pci_slot_attribute {
};
#define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr)
extern void pci_enable_ari(struct pci_dev *dev);
/**
* pci_ari_enabled - query ARI forwarding status
* @dev: the PCI device
*
* Returns 1 if ARI forwarding is enabled, or 0 if not enabled;
*/
static inline int pci_ari_enabled(struct pci_dev *dev)
{
return dev->ari_enabled;
}
#endif /* DRIVERS_PCI_H */

View file

@ -105,7 +105,7 @@ static irqreturn_t aer_irq(int irq, void *context)
unsigned long flags;
int pos;
pos = pci_find_aer_capability(pdev->port);
pos = pci_find_ext_capability(pdev->port, PCI_EXT_CAP_ID_ERR);
/*
* Must lock access to Root Error Status Reg, Root Error ID Reg,
* and Root error producer/consumer index
@ -252,7 +252,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
u32 status;
int pos;
pos = pci_find_aer_capability(dev);
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
/* Disable Root's interrupt in response to error messages */
pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0);
@ -316,7 +316,7 @@ static void aer_error_resume(struct pci_dev *dev)
pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16);
/* Clean AER Root Error Status */
pos = pci_find_aer_capability(dev);
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
if (dev->error_state == pci_channel_io_normal)

View file

@ -28,41 +28,15 @@
static int forceload;
module_param(forceload, bool, 0);
#define PCI_CFG_SPACE_SIZE (0x100)
int pci_find_aer_capability(struct pci_dev *dev)
{
int pos;
u32 reg32 = 0;
/* Check if it's a pci-express device */
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return 0;
/* Check if it supports pci-express AER */
pos = PCI_CFG_SPACE_SIZE;
while (pos) {
if (pci_read_config_dword(dev, pos, &reg32))
return 0;
/* some broken boards return ~0 */
if (reg32 == 0xffffffff)
return 0;
if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR)
break;
pos = reg32 >> 20;
}
return pos;
}
int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
u16 reg16 = 0;
int pos;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return -EIO;
@ -102,7 +76,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
int pos;
u32 status, mask;
pos = pci_find_aer_capability(dev);
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
@ -123,7 +97,7 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
int pos;
u32 status;
pos = pci_find_aer_capability(dev);
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
@ -502,7 +476,7 @@ static void handle_error_source(struct pcie_device * aerdev,
* Correctable error does not need software intevention.
* No need to go through error recovery process.
*/
pos = pci_find_aer_capability(dev);
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (pos)
pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
info.status);
@ -542,7 +516,7 @@ void aer_enable_rootport(struct aer_rpc *rpc)
reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
aer_pos = pci_find_aer_capability(pdev);
aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Clear error status */
pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
@ -579,7 +553,7 @@ static void disable_root_aer(struct aer_rpc *rpc)
u32 reg32;
int pos;
pos = pci_find_aer_capability(pdev);
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Disable Root's interrupt in response to error messages */
pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
@ -618,7 +592,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
{
int pos;
pos = pci_find_aer_capability(dev);
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
/* The device might not support AER */
if (!pos)
@ -755,7 +729,6 @@ int aer_init(struct pcie_device *dev)
return AER_SUCCESS;
}
EXPORT_SYMBOL_GPL(pci_find_aer_capability);
EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);

View file

@ -528,9 +528,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP,
&reg32);
if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
printk("Pre-1.1 PCIe device detected, "
"disable ASPM for %s. It can be enabled forcedly"
" with 'pcie_aspm=force'\n", pci_name(pdev));
dev_printk(KERN_INFO, &child_dev->dev, "disabling ASPM"
" on pre-1.1 PCIe device. You can enable it"
" with 'pcie_aspm=force'\n");
return -EINVAL;
}
}

View file

@ -25,7 +25,6 @@
#define PCIE_CAPABILITIES_REG 0x2
#define PCIE_SLOT_CAPABILITIES_REG 0x14
#define PCIE_PORT_DEVICE_MAXSERVICES 4
#define PCI_CFG_SPACE_SIZE 256
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)

View file

@ -195,24 +195,11 @@ static int get_port_device_capability(struct pci_dev *dev)
/* PME Capable - root port capability */
if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
services |= PCIE_PORT_SERVICE_PME;
pos = PCI_CFG_SPACE_SIZE;
while (pos) {
pci_read_config_dword(dev, pos, &reg32);
switch (reg32 & 0xffff) {
case PCI_EXT_CAP_ID_ERR:
services |= PCIE_PORT_SERVICE_AER;
pos = reg32 >> 20;
break;
case PCI_EXT_CAP_ID_VC:
services |= PCIE_PORT_SERVICE_VC;
pos = reg32 >> 20;
break;
default:
pos = 0;
break;
}
}
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
services |= PCIE_PORT_SERVICE_AER;
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
services |= PCIE_PORT_SERVICE_VC;
return services;
}

View file

@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
pci_set_master(dev);
if (!dev->irq && dev->pin) {
dev_warn(&dev->dev, "device [%04x/%04x] has invalid IRQ; "
dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
"check vendor BIOS\n", dev->vendor, dev->device);
}
if (pcie_port_device_register(dev)) {

View file

@ -14,8 +14,6 @@
#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
#define CARDBUS_RESERVE_BUSNR 3
#define PCI_CFG_SPACE_SIZE 256
#define PCI_CFG_SPACE_EXP_SIZE 4096
/* Ugh. Need to stop exporting this to modules. */
LIST_HEAD(pci_root_buses);
@ -44,72 +42,6 @@ int no_pci_devices(void)
}
EXPORT_SYMBOL(no_pci_devices);
#ifdef HAVE_PCI_LEGACY
/**
* pci_create_legacy_files - create legacy I/O port and memory files
* @b: bus to create files under
*
* Some platforms allow access to legacy I/O port and ISA memory space on
* a per-bus basis. This routine creates the files and ties them into
* their associated read, write and mmap files from pci-sysfs.c
*
* On error unwind, but don't propogate the error to the caller
* as it is ok to set up the PCI bus without these files.
*/
static void pci_create_legacy_files(struct pci_bus *b)
{
int error;
b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
GFP_ATOMIC);
if (!b->legacy_io)
goto kzalloc_err;
b->legacy_io->attr.name = "legacy_io";
b->legacy_io->size = 0xffff;
b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_io->read = pci_read_legacy_io;
b->legacy_io->write = pci_write_legacy_io;
error = device_create_bin_file(&b->dev, b->legacy_io);
if (error)
goto legacy_io_err;
/* Allocated above after the legacy_io struct */
b->legacy_mem = b->legacy_io + 1;
b->legacy_mem->attr.name = "legacy_mem";
b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_mem->mmap = pci_mmap_legacy_mem;
error = device_create_bin_file(&b->dev, b->legacy_mem);
if (error)
goto legacy_mem_err;
return;
legacy_mem_err:
device_remove_bin_file(&b->dev, b->legacy_io);
legacy_io_err:
kfree(b->legacy_io);
b->legacy_io = NULL;
kzalloc_err:
printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
"and ISA memory resources to sysfs\n");
return;
}
void pci_remove_legacy_files(struct pci_bus *b)
{
if (b->legacy_io) {
device_remove_bin_file(&b->dev, b->legacy_io);
device_remove_bin_file(&b->dev, b->legacy_mem);
kfree(b->legacy_io); /* both are allocated here */
}
}
#else /* !HAVE_PCI_LEGACY */
static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
void pci_remove_legacy_files(struct pci_bus *bus) { return; }
#endif /* HAVE_PCI_LEGACY */
/*
* PCI Bus Class Devices
*/
@ -219,7 +151,7 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
return pci_bar_mem64;
return pci_bar_mem32;
}
@ -304,8 +236,8 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
} else {
res->start = l64;
res->end = l64 + sz64;
printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: %pR\n",
pci_name(dev), pos, res);
dev_printk(KERN_DEBUG, &dev->dev,
"reg %x 64bit mmio: %pR\n", pos, res);
}
} else {
sz = pci_size(l, sz, mask);
@ -315,10 +247,10 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
res->start = l;
res->end = l + sz;
printk(KERN_DEBUG "PCI: %s reg %x %s: %pR\n",
pci_name(dev), pos,
(res->flags & IORESOURCE_IO) ? "io port":"32bit mmio",
res);
dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos,
(res->flags & IORESOURCE_IO) ? "io port" : "32bit mmio",
res);
}
out:
@ -389,8 +321,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->start = base;
if (!res->end)
res->end = limit + 0xfff;
printk(KERN_DEBUG "PCI: bridge %s io port: %pR\n",
pci_name(dev), res);
dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res);
}
res = child->resource[1];
@ -402,8 +333,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
res->start = base;
res->end = limit + 0xfffff;
printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: %pR\n",
pci_name(dev), res);
dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n",
res);
}
res = child->resource[2];
@ -439,9 +370,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
res->start = base;
res->end = limit + 0xfffff;
printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: %pR\n",
pci_name(dev),
(res->flags & PCI_PREF_RANGE_TYPE_64) ? "64":"32", res);
dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
(res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
res);
}
}
@ -762,7 +693,7 @@ static int pci_setup_device(struct pci_dev * dev)
dev->class = class;
class >>= 8;
dev_dbg(&dev->dev, "found [%04x/%04x] class %06x header type %02x\n",
dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n",
dev->vendor, dev->device, class, dev->hdr_type);
/* "Unknown power state" */
@ -844,6 +775,11 @@ static int pci_setup_device(struct pci_dev * dev)
return 0;
}
static void pci_release_capabilities(struct pci_dev *dev)
{
pci_vpd_release(dev);
}
/**
* pci_release_dev - free a pci device structure when all users of it are finished.
* @dev: device that's been disconnected
@ -856,7 +792,7 @@ static void pci_release_dev(struct device *dev)
struct pci_dev *pci_dev;
pci_dev = to_pci_dev(dev);
pci_vpd_release(pci_dev);
pci_release_capabilities(pci_dev);
kfree(pci_dev);
}
@ -887,8 +823,9 @@ static void set_pcie_port_type(struct pci_dev *pdev)
int pci_cfg_space_size_ext(struct pci_dev *dev)
{
u32 status;
int pos = PCI_CFG_SPACE_SIZE;
if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
goto fail;
if (status == 0xffffffff)
goto fail;
@ -936,8 +873,6 @@ struct pci_dev *alloc_pci_dev(void)
INIT_LIST_HEAD(&dev->bus_list);
pci_msi_init_pci_dev(dev);
return dev;
}
EXPORT_SYMBOL(alloc_pci_dev);
@ -949,6 +884,7 @@ EXPORT_SYMBOL(alloc_pci_dev);
static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
struct pci_slot *slot;
u32 l;
u8 hdr_type;
int delay = 1;
@ -997,6 +933,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev);
list_for_each_entry(slot, &bus->slots, list)
if (PCI_SLOT(devfn) == slot->number)
dev->slot = slot;
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
set this higher, assuming the system even supports it. */
dev->dma_mask = 0xffffffff;
@ -1005,9 +945,22 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
return NULL;
}
return dev;
}
static void pci_init_capabilities(struct pci_dev *dev)
{
/* MSI/MSI-X list */
pci_msi_init_pci_dev(dev);
/* Power Management */
pci_pm_init(dev);
/* Vital Product Data */
pci_vpd_pci22_init(dev);
return dev;
/* Alternative Routing-ID Forwarding */
pci_enable_ari(dev);
}
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@ -1026,8 +979,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
/* Fix up broken headers */
pci_fixup_device(pci_fixup_header, dev);
/* Initialize power management of the device */
pci_pm_init(dev);
/* Initialize various capabilities */
pci_init_capabilities(dev);
/*
* Add the device to our list of discovered devices

View file

@ -24,6 +24,14 @@
#include <linux/kallsyms.h>
#include "pci.h"
int isa_dma_bridge_buggy;
EXPORT_SYMBOL(isa_dma_bridge_buggy);
int pci_pci_problems;
EXPORT_SYMBOL(pci_pci_problems);
int pcie_mch_quirk;
EXPORT_SYMBOL(pcie_mch_quirk);
#ifdef CONFIG_PCI_QUIRKS
/* The Mellanox Tavor device gives false positive parity errors
* Mark this device with a broken_parity_status, to allow
* PCI scanning code to "skip" this now blacklisted device.
@ -76,8 +84,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p
This appears to be BIOS not version dependent. So presumably there is a
chipset level fix */
int isa_dma_bridge_buggy;
EXPORT_SYMBOL(isa_dma_bridge_buggy);
static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
{
@ -98,9 +104,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_d
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs);
int pci_pci_problems;
EXPORT_SYMBOL(pci_pci_problems);
/*
* Chipsets where PCI->PCI transfers vanish or hang
*/
@ -1376,9 +1379,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic);
#endif
int pcie_mch_quirk;
EXPORT_SYMBOL(pcie_mch_quirk);
static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
{
pcie_mch_quirk = 1;
@ -1569,84 +1569,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
{
while (f < end) {
if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
(f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
#ifdef DEBUG
dev_dbg(&dev->dev, "calling %pF\n", f->hook);
#endif
f->hook(dev);
}
f++;
}
}
extern struct pci_fixup __start_pci_fixups_early[];
extern struct pci_fixup __end_pci_fixups_early[];
extern struct pci_fixup __start_pci_fixups_header[];
extern struct pci_fixup __end_pci_fixups_header[];
extern struct pci_fixup __start_pci_fixups_final[];
extern struct pci_fixup __end_pci_fixups_final[];
extern struct pci_fixup __start_pci_fixups_enable[];
extern struct pci_fixup __end_pci_fixups_enable[];
extern struct pci_fixup __start_pci_fixups_resume[];
extern struct pci_fixup __end_pci_fixups_resume[];
extern struct pci_fixup __start_pci_fixups_resume_early[];
extern struct pci_fixup __end_pci_fixups_resume_early[];
extern struct pci_fixup __start_pci_fixups_suspend[];
extern struct pci_fixup __end_pci_fixups_suspend[];
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
{
struct pci_fixup *start, *end;
switch(pass) {
case pci_fixup_early:
start = __start_pci_fixups_early;
end = __end_pci_fixups_early;
break;
case pci_fixup_header:
start = __start_pci_fixups_header;
end = __end_pci_fixups_header;
break;
case pci_fixup_final:
start = __start_pci_fixups_final;
end = __end_pci_fixups_final;
break;
case pci_fixup_enable:
start = __start_pci_fixups_enable;
end = __end_pci_fixups_enable;
break;
case pci_fixup_resume:
start = __start_pci_fixups_resume;
end = __end_pci_fixups_resume;
break;
case pci_fixup_resume_early:
start = __start_pci_fixups_resume_early;
end = __end_pci_fixups_resume_early;
break;
case pci_fixup_suspend:
start = __start_pci_fixups_suspend;
end = __end_pci_fixups_suspend;
break;
default:
/* stupid compiler warning, you would think with an enum... */
return;
}
pci_do_fixups(dev, start, end);
}
EXPORT_SYMBOL(pci_fixup_device);
/* Enable 1k I/O space granularity on the Intel P64H2 */
static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
{
@ -2020,3 +1942,82 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375,
quirk_msi_intx_disable_bug);
#endif /* CONFIG_PCI_MSI */
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
{
while (f < end) {
if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
(f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
dev_dbg(&dev->dev, "calling %pF\n", f->hook);
f->hook(dev);
}
f++;
}
}
extern struct pci_fixup __start_pci_fixups_early[];
extern struct pci_fixup __end_pci_fixups_early[];
extern struct pci_fixup __start_pci_fixups_header[];
extern struct pci_fixup __end_pci_fixups_header[];
extern struct pci_fixup __start_pci_fixups_final[];
extern struct pci_fixup __end_pci_fixups_final[];
extern struct pci_fixup __start_pci_fixups_enable[];
extern struct pci_fixup __end_pci_fixups_enable[];
extern struct pci_fixup __start_pci_fixups_resume[];
extern struct pci_fixup __end_pci_fixups_resume[];
extern struct pci_fixup __start_pci_fixups_resume_early[];
extern struct pci_fixup __end_pci_fixups_resume_early[];
extern struct pci_fixup __start_pci_fixups_suspend[];
extern struct pci_fixup __end_pci_fixups_suspend[];
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
{
struct pci_fixup *start, *end;
switch(pass) {
case pci_fixup_early:
start = __start_pci_fixups_early;
end = __end_pci_fixups_early;
break;
case pci_fixup_header:
start = __start_pci_fixups_header;
end = __end_pci_fixups_header;
break;
case pci_fixup_final:
start = __start_pci_fixups_final;
end = __end_pci_fixups_final;
break;
case pci_fixup_enable:
start = __start_pci_fixups_enable;
end = __end_pci_fixups_enable;
break;
case pci_fixup_resume:
start = __start_pci_fixups_resume;
end = __end_pci_fixups_resume;
break;
case pci_fixup_resume_early:
start = __start_pci_fixups_resume_early;
end = __end_pci_fixups_resume_early;
break;
case pci_fixup_suspend:
start = __start_pci_fixups_suspend;
end = __end_pci_fixups_suspend;
break;
default:
/* stupid compiler warning, you would think with an enum... */
return;
}
pci_do_fixups(dev, start, end);
}
#else
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
#endif
EXPORT_SYMBOL(pci_fixup_device);

View file

@ -73,6 +73,7 @@ void pci_remove_bus(struct pci_bus *pci_bus)
up_write(&pci_bus_sem);
pci_remove_legacy_files(pci_bus);
device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
device_unregister(&pci_bus->dev);
}
EXPORT_SYMBOL(pci_remove_bus);
@ -114,13 +115,9 @@ void pci_remove_behind_bridge(struct pci_dev *dev)
{
struct list_head *l, *n;
if (dev->subordinate) {
list_for_each_safe(l, n, &dev->subordinate->devices) {
struct pci_dev *dev = pci_dev_b(l);
pci_remove_bus_device(dev);
}
}
if (dev->subordinate)
list_for_each_safe(l, n, &dev->subordinate->devices)
pci_remove_bus_device(pci_dev_b(l));
}
static void pci_stop_bus_devices(struct pci_bus *bus)

View file

@ -299,7 +299,7 @@ static void pbus_size_io(struct pci_bus *bus)
if (r->parent || !(r->flags & IORESOURCE_IO))
continue;
r_size = r->end - r->start + 1;
r_size = resource_size(r);
if (r_size < 0x400)
/* Might be re-aligned for ISA */
@ -350,7 +350,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
if (r->parent || (r->flags & mask) != type)
continue;
r_size = r->end - r->start + 1;
r_size = resource_size(r);
/* For bridges size != alignment */
align = resource_alignment(r);
order = __ffs(align) - 20;

View file

@ -129,7 +129,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
resource_size_t size, min, align;
int ret;
size = res->end - res->start + 1;
size = resource_size(res);
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
align = resource_alignment(res);

View file

@ -49,11 +49,16 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
static void pci_slot_release(struct kobject *kobj)
{
struct pci_dev *dev;
struct pci_slot *slot = to_pci_slot(kobj);
pr_debug("%s: releasing pci_slot on %x:%d\n", __func__,
slot->bus->number, slot->number);
list_for_each_entry(dev, &slot->bus->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot->number)
dev->slot = NULL;
list_del(&slot->list);
kfree(slot);
@ -108,6 +113,7 @@ static struct kobj_type pci_slot_ktype = {
struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
const char *name)
{
struct pci_dev *dev;
struct pci_slot *slot;
int err;
@ -150,6 +156,10 @@ placeholder:
INIT_LIST_HEAD(&slot->list);
list_add(&slot->list, &parent->slots);
list_for_each_entry(dev, &parent->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot_nr)
dev->slot = slot;
/* Don't care if debug printk has a -1 for slot_nr */
pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
__func__, pci_domain_nr(parent), parent->number, slot_nr);