]> err.no Git - linux-2.6/blob - drivers/pci/hotplug/acpi_pcihp.c
x86: work around MTRR mask setting, v2
[linux-2.6] / drivers / pci / hotplug / acpi_pcihp.c
1 /*
2  * Common ACPI functions for hot plug platforms
3  *
4  * Copyright (C) 2006 Intel Corporation
5  *
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16  * NON INFRINGEMENT.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * Send feedback to <kristen.c.accardi@intel.com>
24  *
25  */
26
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/kernel.h>
30 #include <linux/types.h>
31 #include <linux/pci.h>
32 #include <linux/pci_hotplug.h>
33 #include <linux/pci-acpi.h>
34 #include <acpi/acpi.h>
35 #include <acpi/acpi_bus.h>
36 #include <acpi/actypes.h>
37
38 #define MY_NAME "acpi_pcihp"
39
40 #define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __func__ , ## arg); } while (0)
41 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
42 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
43 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
44
45 #define METHOD_NAME__SUN        "_SUN"
46 #define METHOD_NAME__HPP        "_HPP"
47 #define METHOD_NAME_OSHP        "OSHP"
48
49 static int debug_acpi;
50
51 static acpi_status
52 decode_type0_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
53 {
54         int i;
55         union acpi_object *fields = record->package.elements;
56         u32 revision = fields[1].integer.value;
57
58         switch (revision) {
59         case 1:
60                 if (record->package.count != 6)
61                         return AE_ERROR;
62                 for (i = 2; i < 6; i++)
63                         if (fields[i].type != ACPI_TYPE_INTEGER)
64                                 return AE_ERROR;
65                 hpx->t0 = &hpx->type0_data;
66                 hpx->t0->revision        = revision;
67                 hpx->t0->cache_line_size = fields[2].integer.value;
68                 hpx->t0->latency_timer   = fields[3].integer.value;
69                 hpx->t0->enable_serr     = fields[4].integer.value;
70                 hpx->t0->enable_perr     = fields[5].integer.value;
71                 break;
72         default:
73                 printk(KERN_WARNING
74                        "%s: Type 0 Revision %d record not supported\n",
75                        __func__, revision);
76                 return AE_ERROR;
77         }
78         return AE_OK;
79 }
80
81 static acpi_status
82 decode_type1_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
83 {
84         int i;
85         union acpi_object *fields = record->package.elements;
86         u32 revision = fields[1].integer.value;
87
88         switch (revision) {
89         case 1:
90                 if (record->package.count != 5)
91                         return AE_ERROR;
92                 for (i = 2; i < 5; i++)
93                         if (fields[i].type != ACPI_TYPE_INTEGER)
94                                 return AE_ERROR;
95                 hpx->t1 = &hpx->type1_data;
96                 hpx->t1->revision      = revision;
97                 hpx->t1->max_mem_read  = fields[2].integer.value;
98                 hpx->t1->avg_max_split = fields[3].integer.value;
99                 hpx->t1->tot_max_split = fields[4].integer.value;
100                 break;
101         default:
102                 printk(KERN_WARNING
103                        "%s: Type 1 Revision %d record not supported\n",
104                        __func__, revision);
105                 return AE_ERROR;
106         }
107         return AE_OK;
108 }
109
110 static acpi_status
111 decode_type2_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
112 {
113         int i;
114         union acpi_object *fields = record->package.elements;
115         u32 revision = fields[1].integer.value;
116
117         switch (revision) {
118         case 1:
119                 if (record->package.count != 18)
120                         return AE_ERROR;
121                 for (i = 2; i < 18; i++)
122                         if (fields[i].type != ACPI_TYPE_INTEGER)
123                                 return AE_ERROR;
124                 hpx->t2 = &hpx->type2_data;
125                 hpx->t2->revision      = revision;
126                 hpx->t2->unc_err_mask_and      = fields[2].integer.value;
127                 hpx->t2->unc_err_mask_or       = fields[3].integer.value;
128                 hpx->t2->unc_err_sever_and     = fields[4].integer.value;
129                 hpx->t2->unc_err_sever_or      = fields[5].integer.value;
130                 hpx->t2->cor_err_mask_and      = fields[6].integer.value;
131                 hpx->t2->cor_err_mask_or       = fields[7].integer.value;
132                 hpx->t2->adv_err_cap_and       = fields[8].integer.value;
133                 hpx->t2->adv_err_cap_or        = fields[9].integer.value;
134                 hpx->t2->pci_exp_devctl_and    = fields[10].integer.value;
135                 hpx->t2->pci_exp_devctl_or     = fields[11].integer.value;
136                 hpx->t2->pci_exp_lnkctl_and    = fields[12].integer.value;
137                 hpx->t2->pci_exp_lnkctl_or     = fields[13].integer.value;
138                 hpx->t2->sec_unc_err_sever_and = fields[14].integer.value;
139                 hpx->t2->sec_unc_err_sever_or  = fields[15].integer.value;
140                 hpx->t2->sec_unc_err_mask_and  = fields[16].integer.value;
141                 hpx->t2->sec_unc_err_mask_or   = fields[17].integer.value;
142                 break;
143         default:
144                 printk(KERN_WARNING
145                        "%s: Type 2 Revision %d record not supported\n",
146                        __func__, revision);
147                 return AE_ERROR;
148         }
149         return AE_OK;
150 }
151
152 static acpi_status
153 acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx)
154 {
155         acpi_status status;
156         struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
157         union acpi_object *package, *record, *fields;
158         u32 type;
159         int i;
160
161         /* Clear the return buffer with zeros */
162         memset(hpx, 0, sizeof(struct hotplug_params));
163
164         status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer);
165         if (ACPI_FAILURE(status))
166                 return status;
167
168         package = (union acpi_object *)buffer.pointer;
169         if (package->type != ACPI_TYPE_PACKAGE) {
170                 status = AE_ERROR;
171                 goto exit;
172         }
173
174         for (i = 0; i < package->package.count; i++) {
175                 record = &package->package.elements[i];
176                 if (record->type != ACPI_TYPE_PACKAGE) {
177                         status = AE_ERROR;
178                         goto exit;
179                 }
180
181                 fields = record->package.elements;
182                 if (fields[0].type != ACPI_TYPE_INTEGER ||
183                     fields[1].type != ACPI_TYPE_INTEGER) {
184                         status = AE_ERROR;
185                         goto exit;
186                 }
187
188                 type = fields[0].integer.value;
189                 switch (type) {
190                 case 0:
191                         status = decode_type0_hpx_record(record, hpx);
192                         if (ACPI_FAILURE(status))
193                                 goto exit;
194                         break;
195                 case 1:
196                         status = decode_type1_hpx_record(record, hpx);
197                         if (ACPI_FAILURE(status))
198                                 goto exit;
199                         break;
200                 case 2:
201                         status = decode_type2_hpx_record(record, hpx);
202                         if (ACPI_FAILURE(status))
203                                 goto exit;
204                         break;
205                 default:
206                         printk(KERN_ERR "%s: Type %d record not supported\n",
207                                __func__, type);
208                         status = AE_ERROR;
209                         goto exit;
210                 }
211         }
212  exit:
213         kfree(buffer.pointer);
214         return status;
215 }
216
217 static acpi_status
218 acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
219 {
220         acpi_status             status;
221         u8                      nui[4];
222         struct acpi_buffer      ret_buf = { 0, NULL};
223         struct acpi_buffer      string = { ACPI_ALLOCATE_BUFFER, NULL };
224         union acpi_object       *ext_obj, *package;
225         int                     i, len = 0;
226
227         acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
228
229         /* Clear the return buffer with zeros */
230         memset(hpp, 0, sizeof(struct hotplug_params));
231
232         /* get _hpp */
233         status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
234         switch (status) {
235         case AE_BUFFER_OVERFLOW:
236                 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
237                 if (!ret_buf.pointer) {
238                         printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
239                                 __func__, (char *)string.pointer);
240                         kfree(string.pointer);
241                         return AE_NO_MEMORY;
242                 }
243                 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
244                                 NULL, &ret_buf);
245                 if (ACPI_SUCCESS(status))
246                         break;
247         default:
248                 if (ACPI_FAILURE(status)) {
249                         pr_debug("%s:%s _HPP fail=0x%x\n", __func__,
250                                 (char *)string.pointer, status);
251                         kfree(string.pointer);
252                         return status;
253                 }
254         }
255
256         ext_obj = (union acpi_object *) ret_buf.pointer;
257         if (ext_obj->type != ACPI_TYPE_PACKAGE) {
258                 printk(KERN_ERR "%s:%s _HPP obj not a package\n", __func__,
259                                 (char *)string.pointer);
260                 status = AE_ERROR;
261                 goto free_and_return;
262         }
263
264         len = ext_obj->package.count;
265         package = (union acpi_object *) ret_buf.pointer;
266         for ( i = 0; (i < len) || (i < 4); i++) {
267                 ext_obj = (union acpi_object *) &package->package.elements[i];
268                 switch (ext_obj->type) {
269                 case ACPI_TYPE_INTEGER:
270                         nui[i] = (u8)ext_obj->integer.value;
271                         break;
272                 default:
273                         printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
274                                 __func__, (char *)string.pointer);
275                         status = AE_ERROR;
276                         goto free_and_return;
277                 }
278         }
279
280         hpp->t0 = &hpp->type0_data;
281         hpp->t0->cache_line_size = nui[0];
282         hpp->t0->latency_timer = nui[1];
283         hpp->t0->enable_serr = nui[2];
284         hpp->t0->enable_perr = nui[3];
285
286         pr_debug("  _HPP: cache_line_size=0x%x\n", hpp->t0->cache_line_size);
287         pr_debug("  _HPP: latency timer  =0x%x\n", hpp->t0->latency_timer);
288         pr_debug("  _HPP: enable SERR    =0x%x\n", hpp->t0->enable_serr);
289         pr_debug("  _HPP: enable PERR    =0x%x\n", hpp->t0->enable_perr);
290
291 free_and_return:
292         kfree(string.pointer);
293         kfree(ret_buf.pointer);
294         return status;
295 }
296
297
298
299 /* acpi_run_oshp - get control of hotplug from the firmware
300  *
301  * @handle - the handle of the hotplug controller.
302  */
303 static acpi_status acpi_run_oshp(acpi_handle handle)
304 {
305         acpi_status             status;
306         struct acpi_buffer      string = { ACPI_ALLOCATE_BUFFER, NULL };
307
308         acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
309
310         /* run OSHP */
311         status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
312         if (ACPI_FAILURE(status))
313                 if (status != AE_NOT_FOUND)
314                         printk(KERN_ERR "%s:%s OSHP fails=0x%x\n",
315                                __func__, (char *)string.pointer, status);
316                 else
317                         dbg("%s:%s OSHP not found\n",
318                             __func__, (char *)string.pointer);
319         else
320                 pr_debug("%s:%s OSHP passes\n", __func__,
321                         (char *)string.pointer);
322
323         kfree(string.pointer);
324         return status;
325 }
326
327 /* acpi_get_hp_params_from_firmware
328  *
329  * @bus - the pci_bus of the bus on which the device is newly added
330  * @hpp - allocated by the caller
331  */
332 acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
333                 struct hotplug_params *hpp)
334 {
335         acpi_status status = AE_NOT_FOUND;
336         acpi_handle handle, phandle;
337         struct pci_bus *pbus = bus;
338         struct pci_dev *pdev;
339
340         do {
341                 pdev = pbus->self;
342                 if (!pdev) {
343                         handle = acpi_get_pci_rootbridge_handle(
344                                 pci_domain_nr(pbus), pbus->number);
345                         break;
346                 }
347                 handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
348                 pbus = pbus->parent;
349         } while (!handle);
350
351         /*
352          * _HPP settings apply to all child buses, until another _HPP is
353          * encountered. If we don't find an _HPP for the input pci dev,
354          * look for it in the parent device scope since that would apply to
355          * this pci dev. If we don't find any _HPP, use hardcoded defaults
356          */
357         while (handle) {
358                 status = acpi_run_hpx(handle, hpp);
359                 if (ACPI_SUCCESS(status))
360                         break;
361                 status = acpi_run_hpp(handle, hpp);
362                 if (ACPI_SUCCESS(status))
363                         break;
364                 if (acpi_root_bridge(handle))
365                         break;
366                 status = acpi_get_parent(handle, &phandle);
367                 if (ACPI_FAILURE(status))
368                         break;
369                 handle = phandle;
370         }
371         return status;
372 }
373 EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
374
375 /**
376  * acpi_get_hp_hw_control_from_firmware
377  * @dev: the pci_dev of the bridge that has a hotplug controller
378  * @flags: requested control bits for _OSC
379  *
380  * Attempt to take hotplug control from firmware.
381  */
382 int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
383 {
384         acpi_status status;
385         acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
386         struct pci_dev *pdev = dev;
387         struct pci_bus *parent;
388         struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
389
390         flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
391                   OSC_SHPC_NATIVE_HP_CONTROL |
392                   OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
393         if (!flags) {
394                 err("Invalid flags %u specified!\n", flags);
395                 return -EINVAL;
396         }
397
398         /*
399          * Per PCI firmware specification, we should run the ACPI _OSC
400          * method to get control of hotplug hardware before using it. If
401          * an _OSC is missing, we look for an OSHP to do the same thing.
402          * To handle different BIOS behavior, we look for _OSC and OSHP
403          * within the scope of the hotplug controller and its parents,
404          * upto the host bridge under which this controller exists.
405          */
406         while (!handle) {
407                 /*
408                  * This hotplug controller was not listed in the ACPI name
409                  * space at all. Try to get acpi handle of parent pci bus.
410                  */
411                 if (!pdev || !pdev->bus->parent)
412                         break;
413                 parent = pdev->bus->parent;
414                 dbg("Could not find %s in acpi namespace, trying parent\n",
415                     pci_name(pdev));
416                 if (!parent->self)
417                         /* Parent must be a host bridge */
418                         handle = acpi_get_pci_rootbridge_handle(
419                                         pci_domain_nr(parent),
420                                         parent->number);
421                 else
422                         handle = DEVICE_ACPI_HANDLE(&(parent->self->dev));
423                 pdev = parent->self;
424         }
425
426         while (handle) {
427                 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
428                 dbg("Trying to get hotplug control for %s \n",
429                     (char *)string.pointer);
430                 status = pci_osc_control_set(handle, flags);
431                 if (status == AE_NOT_FOUND)
432                         status = acpi_run_oshp(handle);
433                 if (ACPI_SUCCESS(status)) {
434                         dbg("Gained control for hotplug HW for pci %s (%s)\n",
435                             pci_name(dev), (char *)string.pointer);
436                         kfree(string.pointer);
437                         return 0;
438                 }
439                 if (acpi_root_bridge(handle))
440                         break;
441                 chandle = handle;
442                 status = acpi_get_parent(chandle, &handle);
443                 if (ACPI_FAILURE(status))
444                         break;
445         }
446
447         dbg("Cannot get control of hotplug hardware for pci %s\n",
448             pci_name(dev));
449
450         kfree(string.pointer);
451         return -ENODEV;
452 }
453 EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware);
454
455 /* acpi_root_bridge - check to see if this acpi object is a root bridge
456  *
457  * @handle - the acpi object in question.
458  */
459 int acpi_root_bridge(acpi_handle handle)
460 {
461         acpi_status status;
462         struct acpi_device_info *info;
463         struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
464         int i;
465
466         status = acpi_get_object_info(handle, &buffer);
467         if (ACPI_SUCCESS(status)) {
468                 info = buffer.pointer;
469                 if ((info->valid & ACPI_VALID_HID) &&
470                         !strcmp(PCI_ROOT_HID_STRING,
471                                         info->hardware_id.value)) {
472                         kfree(buffer.pointer);
473                         return 1;
474                 }
475                 if (info->valid & ACPI_VALID_CID) {
476                         for (i=0; i < info->compatibility_id.count; i++) {
477                                 if (!strcmp(PCI_ROOT_HID_STRING,
478                                         info->compatibility_id.id[i].value)) {
479                                         kfree(buffer.pointer);
480                                         return 1;
481                                 }
482                         }
483                 }
484                 kfree(buffer.pointer);
485         }
486         return 0;
487 }
488 EXPORT_SYMBOL_GPL(acpi_root_bridge);
489
490 module_param(debug_acpi, bool, 0644);
491 MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not");