forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kerne…
…l/git/jbarnes/pci-2.6 * 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: PCI: label: remove #include of ACPI header to avoid warnings PCI: label: Fix compilation error when CONFIG_ACPI is unset PCI: pre-allocate additional resources to devices only after successful allocation of essential resources. PCI: introduce reset_resource() PCI: data structure agnostic free list function PCI: refactor io size calculation code PCI: do not create quirk I/O regions below PCIBIOS_MIN_IO for ICH PCI hotplug: acpiphp: set current_state to D0 in register_slot PCI: Export ACPI _DSM provided firmware instance number and string name to sysfs PCI: add more checking to ICH region quirks PCI: aer-inject: Override PCIe AER Mask Registers PCI: fix tlan build when CONFIG_PCI is not enabled PCI: remove quirk for pre-production systems PCI: Avoid potential NULL pointer dereference in pci_scan_bridge PCI/lpc: irq and pci_ids patch for Intel DH89xxCC DeviceIDs PCI: sysfs: Fix failure path for addition of "vpd" attribute
- Loading branch information
Showing
14 changed files
with
614 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -145,9 +145,11 @@ Date: July 2010 | |
Contact: Narendra K <[email protected]>, [email protected] | ||
Description: | ||
Reading this attribute will provide the firmware | ||
given name(SMBIOS type 41 string) of the PCI device. | ||
The attribute will be created only if the firmware | ||
has given a name to the PCI device. | ||
given name (SMBIOS type 41 string or ACPI _DSM string) of | ||
the PCI device. The attribute will be created only | ||
if the firmware has given a name to the PCI device. | ||
ACPI _DSM string name will be given priority if the | ||
system firmware provides SMBIOS type 41 string also. | ||
Users: | ||
Userspace applications interested in knowing the | ||
firmware assigned name of the PCI device. | ||
|
@@ -157,12 +159,27 @@ Date: July 2010 | |
Contact: Narendra K <[email protected]>, [email protected] | ||
Description: | ||
Reading this attribute will provide the firmware | ||
given instance(SMBIOS type 41 device type instance) | ||
of the PCI device. The attribute will be created | ||
only if the firmware has given a device type instance | ||
to the PCI device. | ||
given instance (SMBIOS type 41 device type instance) of the | ||
PCI device. The attribute will be created only if the firmware | ||
has given an instance number to the PCI device. | ||
Users: | ||
Userspace applications interested in knowing the | ||
firmware assigned device type instance of the PCI | ||
device that can help in understanding the firmware | ||
intended order of the PCI device. | ||
|
||
What: /sys/bus/pci/devices/.../acpi_index | ||
Date: July 2010 | ||
Contact: Narendra K <[email protected]>, [email protected] | ||
Description: | ||
Reading this attribute will provide the firmware | ||
given instance (ACPI _DSM instance number) of the PCI device. | ||
The attribute will be created only if the firmware has given | ||
an instance number to the PCI device. ACPI _DSM instance number | ||
will be given priority if the system firmware provides SMBIOS | ||
type 41 device type instance also. | ||
Users: | ||
Userspace applications interested in knowing the | ||
firmware assigned instance number of the PCI | ||
device that can help in understanding the firmware | ||
intended order of the PCI device. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -87,3 +87,5 @@ config PCI_IOAPIC | |
depends on ACPI | ||
depends on HOTPLUG | ||
default y | ||
|
||
select NLS if (DMI || ACPI) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,13 @@ | |
* by Narendra K <[email protected]>, | ||
* Jordan Hargrave <[email protected]> | ||
* | ||
* PCI Firmware Specification Revision 3.1 section 4.6.7 (DSM for Naming a | ||
* PCI or PCI Express Device Under Operating Systems) defines an instance | ||
* number and string name. This code retrieves them and exports them to sysfs. | ||
* If the system firmware does not provide the ACPI _DSM (Device Specific | ||
* Method), then the SMBIOS type 41 instance number and string is exported to | ||
* sysfs. | ||
* | ||
* SMBIOS defines type 41 for onboard pci devices. This code retrieves | ||
* the instance number and string from the type 41 record and exports | ||
* it to sysfs. | ||
|
@@ -19,8 +26,29 @@ | |
#include <linux/pci_ids.h> | ||
#include <linux/module.h> | ||
#include <linux/device.h> | ||
#include <linux/nls.h> | ||
#include <linux/acpi.h> | ||
#include <linux/pci-acpi.h> | ||
#include <acpi/acpi_bus.h> | ||
#include "pci.h" | ||
|
||
#define DEVICE_LABEL_DSM 0x07 | ||
|
||
#ifndef CONFIG_DMI | ||
|
||
static inline int | ||
pci_create_smbiosname_file(struct pci_dev *pdev) | ||
{ | ||
return -1; | ||
} | ||
|
||
static inline void | ||
pci_remove_smbiosname_file(struct pci_dev *pdev) | ||
{ | ||
} | ||
|
||
#else | ||
|
||
enum smbios_attr_enum { | ||
SMBIOS_ATTR_NONE = 0, | ||
SMBIOS_ATTR_LABEL_SHOW, | ||
|
@@ -120,9 +148,7 @@ static struct attribute_group smbios_attr_group = { | |
static int | ||
pci_create_smbiosname_file(struct pci_dev *pdev) | ||
{ | ||
if (!sysfs_create_group(&pdev->dev.kobj, &smbios_attr_group)) | ||
return 0; | ||
return -ENODEV; | ||
return sysfs_create_group(&pdev->dev.kobj, &smbios_attr_group); | ||
} | ||
|
||
static void | ||
|
@@ -131,13 +157,227 @@ pci_remove_smbiosname_file(struct pci_dev *pdev) | |
sysfs_remove_group(&pdev->dev.kobj, &smbios_attr_group); | ||
} | ||
|
||
#endif | ||
|
||
#ifndef CONFIG_ACPI | ||
|
||
static inline int | ||
pci_create_acpi_index_label_files(struct pci_dev *pdev) | ||
{ | ||
return -1; | ||
} | ||
|
||
static inline int | ||
pci_remove_acpi_index_label_files(struct pci_dev *pdev) | ||
{ | ||
return -1; | ||
} | ||
|
||
static inline bool | ||
device_has_dsm(struct device *dev) | ||
{ | ||
return false; | ||
} | ||
|
||
#else | ||
|
||
static const char device_label_dsm_uuid[] = { | ||
0xD0, 0x37, 0xC9, 0xE5, 0x53, 0x35, 0x7A, 0x4D, | ||
0x91, 0x17, 0xEA, 0x4D, 0x19, 0xC3, 0x43, 0x4D | ||
}; | ||
|
||
enum acpi_attr_enum { | ||
ACPI_ATTR_NONE = 0, | ||
ACPI_ATTR_LABEL_SHOW, | ||
ACPI_ATTR_INDEX_SHOW, | ||
}; | ||
|
||
static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) | ||
{ | ||
int len; | ||
len = utf16s_to_utf8s((const wchar_t *)obj-> | ||
package.elements[1].string.pointer, | ||
obj->package.elements[1].string.length, | ||
UTF16_LITTLE_ENDIAN, | ||
buf, PAGE_SIZE); | ||
buf[len] = '\n'; | ||
} | ||
|
||
static int | ||
dsm_get_label(acpi_handle handle, int func, | ||
struct acpi_buffer *output, | ||
char *buf, enum acpi_attr_enum attribute) | ||
{ | ||
struct acpi_object_list input; | ||
union acpi_object params[4]; | ||
union acpi_object *obj; | ||
int len = 0; | ||
|
||
int err; | ||
|
||
input.count = 4; | ||
input.pointer = params; | ||
params[0].type = ACPI_TYPE_BUFFER; | ||
params[0].buffer.length = sizeof(device_label_dsm_uuid); | ||
params[0].buffer.pointer = (char *)device_label_dsm_uuid; | ||
params[1].type = ACPI_TYPE_INTEGER; | ||
params[1].integer.value = 0x02; | ||
params[2].type = ACPI_TYPE_INTEGER; | ||
params[2].integer.value = func; | ||
params[3].type = ACPI_TYPE_PACKAGE; | ||
params[3].package.count = 0; | ||
params[3].package.elements = NULL; | ||
|
||
err = acpi_evaluate_object(handle, "_DSM", &input, output); | ||
if (err) | ||
return -1; | ||
|
||
obj = (union acpi_object *)output->pointer; | ||
|
||
switch (obj->type) { | ||
case ACPI_TYPE_PACKAGE: | ||
if (obj->package.count != 2) | ||
break; | ||
len = obj->package.elements[0].integer.value; | ||
if (buf) { | ||
if (attribute == ACPI_ATTR_INDEX_SHOW) | ||
scnprintf(buf, PAGE_SIZE, "%llu\n", | ||
obj->package.elements[0].integer.value); | ||
else if (attribute == ACPI_ATTR_LABEL_SHOW) | ||
dsm_label_utf16s_to_utf8s(obj, buf); | ||
kfree(output->pointer); | ||
return strlen(buf); | ||
} | ||
kfree(output->pointer); | ||
return len; | ||
break; | ||
default: | ||
kfree(output->pointer); | ||
} | ||
return -1; | ||
} | ||
|
||
static bool | ||
device_has_dsm(struct device *dev) | ||
{ | ||
acpi_handle handle; | ||
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
|
||
handle = DEVICE_ACPI_HANDLE(dev); | ||
|
||
if (!handle) | ||
return FALSE; | ||
|
||
if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL, | ||
ACPI_ATTR_NONE) > 0) | ||
return TRUE; | ||
|
||
return FALSE; | ||
} | ||
|
||
static mode_t | ||
acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n) | ||
{ | ||
struct device *dev; | ||
|
||
dev = container_of(kobj, struct device, kobj); | ||
|
||
if (device_has_dsm(dev)) | ||
return S_IRUGO; | ||
|
||
return 0; | ||
} | ||
|
||
static ssize_t | ||
acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
{ | ||
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
acpi_handle handle; | ||
int length; | ||
|
||
handle = DEVICE_ACPI_HANDLE(dev); | ||
|
||
if (!handle) | ||
return -1; | ||
|
||
length = dsm_get_label(handle, DEVICE_LABEL_DSM, | ||
&output, buf, ACPI_ATTR_LABEL_SHOW); | ||
|
||
if (length < 1) | ||
return -1; | ||
|
||
return length; | ||
} | ||
|
||
static ssize_t | ||
acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
{ | ||
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
acpi_handle handle; | ||
int length; | ||
|
||
handle = DEVICE_ACPI_HANDLE(dev); | ||
|
||
if (!handle) | ||
return -1; | ||
|
||
length = dsm_get_label(handle, DEVICE_LABEL_DSM, | ||
&output, buf, ACPI_ATTR_INDEX_SHOW); | ||
|
||
if (length < 0) | ||
return -1; | ||
|
||
return length; | ||
|
||
} | ||
|
||
static struct device_attribute acpi_attr_label = { | ||
.attr = {.name = "label", .mode = 0444}, | ||
.show = acpilabel_show, | ||
}; | ||
|
||
static struct device_attribute acpi_attr_index = { | ||
.attr = {.name = "acpi_index", .mode = 0444}, | ||
.show = acpiindex_show, | ||
}; | ||
|
||
static struct attribute *acpi_attributes[] = { | ||
&acpi_attr_label.attr, | ||
&acpi_attr_index.attr, | ||
NULL, | ||
}; | ||
|
||
static struct attribute_group acpi_attr_group = { | ||
.attrs = acpi_attributes, | ||
.is_visible = acpi_index_string_exist, | ||
}; | ||
|
||
static int | ||
pci_create_acpi_index_label_files(struct pci_dev *pdev) | ||
{ | ||
return sysfs_create_group(&pdev->dev.kobj, &acpi_attr_group); | ||
} | ||
|
||
static int | ||
pci_remove_acpi_index_label_files(struct pci_dev *pdev) | ||
{ | ||
sysfs_remove_group(&pdev->dev.kobj, &acpi_attr_group); | ||
return 0; | ||
} | ||
#endif | ||
|
||
void pci_create_firmware_label_files(struct pci_dev *pdev) | ||
{ | ||
if (!pci_create_smbiosname_file(pdev)) | ||
; | ||
if (device_has_dsm(&pdev->dev)) | ||
pci_create_acpi_index_label_files(pdev); | ||
else | ||
pci_create_smbiosname_file(pdev); | ||
} | ||
|
||
void pci_remove_firmware_label_files(struct pci_dev *pdev) | ||
{ | ||
pci_remove_smbiosname_file(pdev); | ||
if (device_has_dsm(&pdev->dev)) | ||
pci_remove_acpi_index_label_files(pdev); | ||
else | ||
pci_remove_smbiosname_file(pdev); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.