X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpci%2Fhotplug%2Fpciehprm_acpi.c;h=424e7ac61746622196f50a79ff8d460624bb71d3;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=b127575ec98516029298fbc817acc7421f6d6fde;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c index b127575ec..424e7ac61 100644 --- a/drivers/pci/hotplug/pciehprm_acpi.c +++ b/drivers/pci/hotplug/pciehprm_acpi.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_IA64 @@ -50,6 +51,14 @@ #define METHOD_NAME__HPP "_HPP" #define METHOD_NAME_OSHP "OSHP" +/* Status code for running acpi method to gain native control */ +#define NC_NOT_RUN 0 +#define OSC_NOT_EXIST 1 +#define OSC_RUN_FAILED 2 +#define OSHP_NOT_EXIST 3 +#define OSHP_RUN_FAILED 4 +#define NC_RUN_SUCCESS 5 + #define PHP_RES_BUS 0xA0 #define PHP_RES_IO 0xA1 #define PHP_RES_MEM 0xA2 @@ -125,7 +134,9 @@ static u8 * acpi_path_name( acpi_handle handle) } static void acpi_get__hpp ( struct acpi_bridge *ab); -static void acpi_run_oshp ( struct acpi_bridge *ab); +static int acpi_run_oshp ( struct acpi_bridge *ab); +static int osc_run_status = NC_NOT_RUN; +static int oshp_run_status = NC_NOT_RUN; static int acpi_add_slot_to_php_slots( struct acpi_bridge *ab, @@ -158,8 +169,9 @@ static int acpi_add_slot_to_php_slots( ab->scanned += 1; if (!ab->_hpp) acpi_get__hpp(ab); - - acpi_run_oshp(ab); + + if (osc_run_status == OSC_NOT_EXIST) + oshp_run_status = acpi_run_oshp(ab); if (sun != samesun) { info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", @@ -238,7 +250,7 @@ free_and_return: kfree(ret_buf.pointer); } -static void acpi_run_oshp ( struct acpi_bridge *ab) +static int acpi_run_oshp ( struct acpi_bridge *ab) { acpi_status status; u8 *path_name = acpi_path_name(ab->handle); @@ -248,9 +260,13 @@ static void acpi_run_oshp ( struct acpi_bridge *ab) status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, &ret_buf); if (ACPI_FAILURE(status)) { err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status); - } else + oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED; + } else { + oshp_run_status = NC_RUN_SUCCESS; dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status); - return; + dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status); + } + return oshp_run_status; } static acpi_status acpi_evaluate_crs( @@ -1056,6 +1072,16 @@ static struct acpi_bridge * add_host_bridge( kfree(ab); return NULL; } + + status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); + if (ACPI_FAILURE(status)) { + err("%s: status %x\n", __FUNCTION__, status); + osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED; + } else { + osc_run_status = NC_RUN_SUCCESS; + } + dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status); + build_a_bridge(ab, ab); return ab; @@ -1141,6 +1167,11 @@ int pciehprm_init(enum php_ctlr_type ctlr_type) if (rc) return rc; + if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) { + err("Fails to gain control of native hot-plug\n"); + rc = -ENODEV; + } + dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success"); return rc; }