Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] acpiphp: fix acpi_path_name

I encountered the problem that the insmod of the acpiphp
fails because of the mis-freeing of the memory.

I tested this patch on my tiger4 box.

Signed-off-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

MUNEDA Takahiro and committed by
Greg Kroah-Hartman
b2e6e3ba dc6712d1

+27 -43
+19 -35
drivers/pci/hotplug/acpi_pcihp.c
··· 37 37 #define METHOD_NAME__HPP "_HPP" 38 38 #define METHOD_NAME_OSHP "OSHP" 39 39 40 - /* acpi_path_name 41 - * 42 - * @handle - the acpi_handle of the object who's name you want. 43 - * 44 - * Caller must free buffer. 45 - */ 46 - u8 * acpi_path_name(acpi_handle handle) 47 - { 48 - acpi_status status; 49 - struct acpi_buffer ret_buf = {ACPI_ALLOCATE_BUFFER, NULL}; 50 - union acpi_object *obj; 51 - 52 - status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf); 53 - if (ACPI_FAILURE(status)) { 54 - return NULL; 55 - } 56 - obj = ret_buf.pointer; 57 - return obj->string.pointer; 58 - } 59 - EXPORT_SYMBOL_GPL(acpi_path_name); 60 - 61 - 62 40 63 41 static acpi_status 64 42 acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) ··· 44 66 acpi_status status; 45 67 u8 nui[4]; 46 68 struct acpi_buffer ret_buf = { 0, NULL}; 69 + struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 47 70 union acpi_object *ext_obj, *package; 48 - u8 *path_name = acpi_path_name(handle); 49 71 int i, len = 0; 72 + 73 + acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 50 74 51 75 /* get _hpp */ 52 76 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); ··· 57 77 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 58 78 if (!ret_buf.pointer) { 59 79 printk(KERN_ERR "%s:%s alloc for _HPP fail\n", 60 - __FUNCTION__, path_name); 61 - acpi_os_free(path_name); 80 + __FUNCTION__, (char *)string.pointer); 81 + acpi_os_free(string.pointer); 62 82 return AE_NO_MEMORY; 63 83 } 64 84 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, ··· 68 88 default: 69 89 if (ACPI_FAILURE(status)) { 70 90 pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__, 71 - path_name, status); 72 - acpi_os_free(path_name); 91 + (char *)string.pointer, status); 92 + acpi_os_free(string.pointer); 73 93 return status; 74 94 } 75 95 } ··· 77 97 ext_obj = (union acpi_object *) ret_buf.pointer; 78 98 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 79 99 printk(KERN_ERR "%s:%s _HPP obj not a package\n", __FUNCTION__, 80 - path_name); 100 + (char *)string.pointer); 81 101 status = AE_ERROR; 82 102 goto free_and_return; 83 103 } ··· 92 112 break; 93 113 default: 94 114 printk(KERN_ERR "%s:%s _HPP obj type incorrect\n", 95 - __FUNCTION__, path_name); 115 + __FUNCTION__, (char *)string.pointer); 96 116 status = AE_ERROR; 97 117 goto free_and_return; 98 118 } ··· 109 129 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); 110 130 111 131 free_and_return: 112 - acpi_os_free(path_name); 113 - kfree(ret_buf.pointer); 132 + acpi_os_free(string.pointer); 133 + acpi_os_free(ret_buf.pointer); 114 134 return status; 115 135 } 116 136 ··· 123 143 acpi_status acpi_run_oshp(acpi_handle handle) 124 144 { 125 145 acpi_status status; 126 - u8 *path_name = acpi_path_name(handle); 146 + struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 147 + 148 + acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 127 149 128 150 /* run OSHP */ 129 151 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); 130 152 if (ACPI_FAILURE(status)) 131 153 printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__, 132 - path_name, status); 154 + (char *)string.pointer, status); 133 155 else 134 - pr_debug("%s:%s OSHP passes\n", __FUNCTION__, path_name); 135 - acpi_os_free(path_name); 156 + pr_debug("%s:%s OSHP passes\n", __FUNCTION__, 157 + (char *)string.pointer); 158 + 159 + acpi_os_free(string.pointer); 136 160 return status; 137 161 } 138 162 EXPORT_SYMBOL_GPL(acpi_run_oshp);
-1
drivers/pci/hotplug/pci_hotplug.h
··· 190 190 extern acpi_status acpi_run_oshp(acpi_handle handle); 191 191 extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, 192 192 struct hotplug_params *hpp); 193 - extern u8 * acpi_path_name(acpi_handle handle); 194 193 int acpi_root_bridge(acpi_handle handle); 195 194 #endif 196 195 #endif
+8 -7
drivers/pci/hotplug/pciehp_hpc.c
··· 1246 1246 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); 1247 1247 struct pci_dev *pdev = dev; 1248 1248 struct pci_bus *parent; 1249 - u8 *path_name = NULL; 1249 + struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 1250 1250 1251 1251 /* 1252 1252 * Per PCI firmware specification, we should run the ACPI _OSC ··· 1278 1278 } 1279 1279 1280 1280 while (handle) { 1281 - path_name = acpi_path_name(handle); 1282 - dbg("Trying to get hotplug control for %s \n", path_name); 1281 + acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 1282 + dbg("Trying to get hotplug control for %s \n", 1283 + (char *)string.pointer); 1283 1284 status = pci_osc_control_set(handle, 1284 1285 OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); 1285 1286 if (status == AE_NOT_FOUND) 1286 1287 status = acpi_run_oshp(handle); 1287 1288 if (ACPI_SUCCESS(status)) { 1288 1289 dbg("Gained control for hotplug HW for pci %s (%s)\n", 1289 - pci_name(dev), path_name); 1290 - acpi_os_free(path_name); 1290 + pci_name(dev), (char *)string.pointer); 1291 + acpi_os_free(string.pointer); 1291 1292 return 0; 1292 1293 } 1293 1294 if (acpi_root_bridge(handle)) ··· 1301 1300 1302 1301 err("Cannot get control of hotplug hardware for pci %s\n", 1303 1302 pci_name(dev)); 1304 - if (path_name) 1305 - acpi_os_free(path_name); 1303 + 1304 + acpi_os_free(string.pointer); 1306 1305 return -1; 1307 1306 } 1308 1307 #endif