aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrajesh.shah@intel.com <rajesh.shah@intel.com>2005-10-13 15:05:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 18:37:00 -0400
commit424600f9706b20a8a33ad928d3d0326bd88679bc (patch)
tree364509b512ff4f522b38329df582553a9c8fb6ff
parent7e88ed199689f333668b62348051202706b6a74a (diff)
[PATCH] shpchp: reduce dependence on ACPI
Reduce the SHPC hotplug driver's dependence on ACPI. We don't walk the acpi namespace anymore to build a list of bridges and devices. The remaining interaction with ACPI is to run the _OSHP method to transition control of hotplug hardware from system BIOS to the shpc hotplug driver, and to run the _HPP method to get hotplug device parameters like cache line size, latency timer and SERR/PERR enable from BIOS. Note that one of the side effects of this patch is that shpchp does not enable the hot-added device or its DMA bus mastering automatically now. It expects the device driver to do that. This may break some drivers and we will have to fix them as they are reported. Signed-off-by: Rajesh Shah <rajesh.shah@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/hotplug/shpchp.h12
-rw-r--r--drivers/pci/hotplug/shpchp_core.c13
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c1
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c2
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c52
-rw-r--r--drivers/pci/hotplug/shpchprm.h43
-rw-r--r--drivers/pci/hotplug/shpchprm_acpi.c794
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.c97
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.c108
9 files changed, 138 insertions, 984 deletions
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index deea56c73cf2..1b345ae81ddb 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -122,6 +122,13 @@ struct controller {
122 u16 vendor_id; 122 u16 vendor_id;
123}; 123};
124 124
125struct hotplug_params {
126 u8 cache_line_size;
127 u8 latency_timer;
128 u8 enable_serr;
129 u8 enable_perr;
130};
131
125/* Define AMD SHPC ID */ 132/* Define AMD SHPC ID */
126#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 133#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
127 134
@@ -192,6 +199,11 @@ extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ct
192extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot); 199extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot);
193extern int shpchp_configure_device(struct slot *p_slot); 200extern int shpchp_configure_device(struct slot *p_slot);
194extern int shpchp_unconfigure_device(struct pci_func* func); 201extern int shpchp_unconfigure_device(struct pci_func* func);
202extern void get_hp_hw_control_from_firmware(struct pci_dev *dev);
203extern void get_hp_params_from_firmware(struct pci_dev *dev,
204 struct hotplug_params *hpp);
205extern int shpchprm_get_physical_slot_number(struct controller *ctrl,
206 u32 *sun, u8 busnum, u8 devnum);
195 207
196 208
197/* Global variables */ 209/* Global variables */
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 8f5da504df34..e3c0c17295da 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -39,7 +39,6 @@
39#include <linux/init.h> 39#include <linux/init.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include "shpchp.h" 41#include "shpchp.h"
42#include "shpchprm.h"
43 42
44/* Global variables */ 43/* Global variables */
45int shpchp_debug; 44int shpchp_debug;
@@ -566,16 +565,12 @@ static int __init shpcd_init(void)
566 if (retval) 565 if (retval)
567 goto error_hpc_init; 566 goto error_hpc_init;
568 567
569 retval = shpchprm_init(PCI); 568 retval = pci_register_driver(&shpc_driver);
570 if (!retval) { 569 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
571 retval = pci_register_driver(&shpc_driver); 570 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
572 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
573 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
574 }
575 571
576error_hpc_init: 572error_hpc_init:
577 if (retval) { 573 if (retval) {
578 shpchprm_cleanup();
579 shpchp_event_stop_thread(); 574 shpchp_event_stop_thread();
580 } 575 }
581 return retval; 576 return retval;
@@ -586,8 +581,6 @@ static void __exit shpcd_cleanup(void)
586 dbg("unload_shpchpd()\n"); 581 dbg("unload_shpchpd()\n");
587 unload_shpchpd(); 582 unload_shpchpd();
588 583
589 shpchprm_cleanup();
590
591 dbg("pci_unregister_driver\n"); 584 dbg("pci_unregister_driver\n");
592 pci_unregister_driver(&shpc_driver); 585 pci_unregister_driver(&shpc_driver);
593 586
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index aa507e453e49..23dd61c4c66c 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -40,7 +40,6 @@
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include "../pci.h" 41#include "../pci.h"
42#include "shpchp.h" 42#include "shpchp.h"
43#include "shpchprm.h"
44 43
45static void interrupt_event_handler(struct controller *ctrl); 44static void interrupt_event_handler(struct controller *ctrl);
46 45
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 8d98410bf1c0..d55a9a7f8d2b 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -1566,8 +1566,8 @@ int shpc_init(struct controller * ctrl,
1566 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); 1566 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
1567 goto abort_free_ctlr; 1567 goto abort_free_ctlr;
1568 } 1568 }
1569 /* Execute OSHP method here */
1570 } 1569 }
1570 get_hp_hw_control_from_firmware(pdev);
1571 dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__); 1571 dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__);
1572 1572
1573 /* Add this HPC instance into the HPC list */ 1573 /* Add this HPC instance into the HPC list */
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 89e404805777..6209972313f3 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -38,6 +38,55 @@
38#include "../pci.h" 38#include "../pci.h"
39#include "shpchp.h" 39#include "shpchp.h"
40 40
41void program_fw_provided_values(struct pci_dev *dev)
42{
43 u16 pci_cmd, pci_bctl;
44 struct pci_dev *cdev;
45 struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */
46
47 /* Program hpp values for this device */
48 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
49 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
50 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
51 return;
52
53 get_hp_params_from_firmware(dev, &hpp);
54
55 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size);
56 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
57 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
58 if (hpp.enable_serr)
59 pci_cmd |= PCI_COMMAND_SERR;
60 else
61 pci_cmd &= ~PCI_COMMAND_SERR;
62 if (hpp.enable_perr)
63 pci_cmd |= PCI_COMMAND_PARITY;
64 else
65 pci_cmd &= ~PCI_COMMAND_PARITY;
66 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
67
68 /* Program bridge control value and child devices */
69 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
70 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
71 hpp.latency_timer);
72 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
73 if (hpp.enable_serr)
74 pci_bctl |= PCI_BRIDGE_CTL_SERR;
75 else
76 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
77 if (hpp.enable_perr)
78 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
79 else
80 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
81 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
82 if (dev->subordinate) {
83 list_for_each_entry(cdev, &dev->subordinate->devices,
84 bus_list)
85 program_fw_provided_values(cdev);
86 }
87 }
88}
89
41int shpchp_configure_device(struct slot *p_slot) 90int shpchp_configure_device(struct slot *p_slot)
42{ 91{
43 struct pci_dev *dev; 92 struct pci_dev *dev;
@@ -90,8 +139,7 @@ int shpchp_configure_device(struct slot *p_slot)
90 child->subordinate = pci_do_scan_bus(child); 139 child->subordinate = pci_do_scan_bus(child);
91 pci_bus_size_bridges(child); 140 pci_bus_size_bridges(child);
92 } 141 }
93 /* TBD: program firmware provided _HPP values */ 142 program_fw_provided_values(dev);
94 /* program_fw_provided_values(dev); */
95 } 143 }
96 144
97 pci_bus_assign_resources(parent); 145 pci_bus_assign_resources(parent);
diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h
deleted file mode 100644
index df474b27d6e8..000000000000
--- a/drivers/pci/hotplug/shpchprm.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_H_
31#define _SHPCHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
34#include "shpchprm_legacy.h"
35#endif
36
37int shpchprm_init(enum php_ctlr_type ct);
38void shpchprm_cleanup(void);
39int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
40void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
41int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum);
42
43#endif /* _SHPCHPRM_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
index 3d2f9c5269c7..3be518c7d47a 100644
--- a/drivers/pci/hotplug/shpchprm_acpi.c
+++ b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -38,62 +38,11 @@
38#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
39#include <acpi/actypes.h> 39#include <acpi/actypes.h>
40#include "shpchp.h" 40#include "shpchp.h"
41#include "shpchprm.h"
42
43#define PCI_MAX_BUS 0x100
44#define ACPI_STA_DEVICE_PRESENT 0x01
45 41
46#define METHOD_NAME__SUN "_SUN" 42#define METHOD_NAME__SUN "_SUN"
47#define METHOD_NAME__HPP "_HPP" 43#define METHOD_NAME__HPP "_HPP"
48#define METHOD_NAME_OSHP "OSHP" 44#define METHOD_NAME_OSHP "OSHP"
49 45
50#define PHP_RES_BUS 0xA0
51#define PHP_RES_IO 0xA1
52#define PHP_RES_MEM 0xA2
53#define PHP_RES_PMEM 0xA3
54
55#define BRIDGE_TYPE_P2P 0x00
56#define BRIDGE_TYPE_HOST 0x01
57
58/* this should go to drivers/acpi/include/ */
59struct acpi__hpp {
60 u8 cache_line_size;
61 u8 latency_timer;
62 u8 enable_serr;
63 u8 enable_perr;
64};
65
66struct acpi_php_slot {
67 struct acpi_php_slot *next;
68 struct acpi_bridge *bridge;
69 acpi_handle handle;
70 int seg;
71 int bus;
72 int dev;
73 int fun;
74 u32 sun;
75 void *slot_ops; /* _STA, _EJx, etc */
76 struct slot *slot;
77}; /* per func */
78
79struct acpi_bridge {
80 struct acpi_bridge *parent;
81 struct acpi_bridge *next;
82 struct acpi_bridge *child;
83 acpi_handle handle;
84 int seg;
85 int pbus; /* pdev->bus->number */
86 int pdevice; /* PCI_SLOT(pdev->devfn) */
87 int pfunction; /* PCI_DEVFN(pdev->devfn) */
88 int bus; /* pdev->subordinate->number */
89 struct acpi__hpp *_hpp;
90 struct acpi_php_slot *slots;
91 int scanned;
92 int type;
93};
94
95static struct acpi_bridge *acpi_bridges_head;
96
97static u8 * acpi_path_name( acpi_handle handle) 46static u8 * acpi_path_name( acpi_handle handle)
98{ 47{
99 acpi_status status; 48 acpi_status status;
@@ -109,82 +58,43 @@ static u8 * acpi_path_name( acpi_handle handle)
109 return path_name; 58 return path_name;
110} 59}
111 60
112static void acpi_get__hpp ( struct acpi_bridge *ab); 61static acpi_status
113static void acpi_run_oshp ( struct acpi_bridge *ab); 62acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
114
115static int acpi_add_slot_to_php_slots(
116 struct acpi_bridge *ab,
117 int bus_num,
118 acpi_handle handle,
119 u32 adr,
120 u32 sun
121 )
122{
123 struct acpi_php_slot *aps;
124 static long samesun = -1;
125
126 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
127 if (!aps) {
128 err ("acpi_shpchprm: alloc for aps fail\n");
129 return -1;
130 }
131 memset(aps, 0, sizeof(struct acpi_php_slot));
132
133 aps->handle = handle;
134 aps->bus = bus_num;
135 aps->dev = (adr >> 16) & 0xffff;
136 aps->fun = adr & 0xffff;
137 aps->sun = sun;
138
139 aps->next = ab->slots; /* cling to the bridge */
140 aps->bridge = ab;
141 ab->slots = aps;
142
143 ab->scanned += 1;
144 if (!ab->_hpp)
145 acpi_get__hpp(ab);
146
147 acpi_run_oshp(ab);
148
149 if (sun != samesun) {
150 info("acpi_shpchprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", aps->sun, ab->seg,
151 aps->bus, aps->dev, aps->fun);
152 samesun = sun;
153 }
154 return 0;
155}
156
157static void acpi_get__hpp ( struct acpi_bridge *ab)
158{ 63{
159 acpi_status status; 64 acpi_status status;
160 u8 nui[4]; 65 u8 nui[4];
161 struct acpi_buffer ret_buf = { 0, NULL}; 66 struct acpi_buffer ret_buf = { 0, NULL};
162 union acpi_object *ext_obj, *package; 67 union acpi_object *ext_obj, *package;
163 u8 *path_name = acpi_path_name(ab->handle); 68 u8 *path_name = acpi_path_name(handle);
164 int i, len = 0; 69 int i, len = 0;
165 70
166 /* get _hpp */ 71 /* get _hpp */
167 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 72 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
168 switch (status) { 73 switch (status) {
169 case AE_BUFFER_OVERFLOW: 74 case AE_BUFFER_OVERFLOW:
170 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 75 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
171 if (!ret_buf.pointer) { 76 if (!ret_buf.pointer) {
172 err ("acpi_shpchprm:%s alloc for _HPP fail\n", path_name); 77 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
173 return; 78 path_name);
79 return AE_NO_MEMORY;
174 } 80 }
175 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 81 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
82 NULL, &ret_buf);
176 if (ACPI_SUCCESS(status)) 83 if (ACPI_SUCCESS(status))
177 break; 84 break;
178 default: 85 default:
179 if (ACPI_FAILURE(status)) { 86 if (ACPI_FAILURE(status)) {
180 err("acpi_shpchprm:%s _HPP fail=0x%x\n", path_name, status); 87 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
181 return; 88 path_name, status);
89 return status;
182 } 90 }
183 } 91 }
184 92
185 ext_obj = (union acpi_object *) ret_buf.pointer; 93 ext_obj = (union acpi_object *) ret_buf.pointer;
186 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 94 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
187 err ("acpi_shpchprm:%s _HPP obj not a package\n", path_name); 95 err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
96 path_name);
97 status = AE_ERROR;
188 goto free_and_return; 98 goto free_and_return;
189 } 99 }
190 100
@@ -197,553 +107,41 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
197 nui[i] = (u8)ext_obj->integer.value; 107 nui[i] = (u8)ext_obj->integer.value;
198 break; 108 break;
199 default: 109 default:
200 err ("acpi_shpchprm:%s _HPP obj type incorrect\n", path_name); 110 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
111 path_name);
112 status = AE_ERROR;
201 goto free_and_return; 113 goto free_and_return;
202 } 114 }
203 } 115 }
204 116
205 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); 117 hpp->cache_line_size = nui[0];
206 if (!ab->_hpp) { 118 hpp->latency_timer = nui[1];
207 err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name); 119 hpp->enable_serr = nui[2];
208 goto free_and_return; 120 hpp->enable_perr = nui[3];
209 }
210 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
211
212 ab->_hpp->cache_line_size = nui[0];
213 ab->_hpp->latency_timer = nui[1];
214 ab->_hpp->enable_serr = nui[2];
215 ab->_hpp->enable_perr = nui[3];
216 121
217 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size); 122 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
218 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer); 123 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
219 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr); 124 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
220 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr); 125 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
221 126
222free_and_return: 127free_and_return:
223 kfree(ret_buf.pointer); 128 kfree(ret_buf.pointer);
129 return status;
224} 130}
225 131
226static void acpi_run_oshp ( struct acpi_bridge *ab) 132static void acpi_run_oshp(acpi_handle handle)
227{
228 acpi_status status;
229 u8 *path_name = acpi_path_name(ab->handle);
230
231 /* run OSHP */
232 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
233 if (ACPI_FAILURE(status)) {
234 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
235 } else
236 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
237 return;
238}
239
240/* find acpi_bridge downword from ab. */
241static struct acpi_bridge *
242find_acpi_bridge_by_bus(
243 struct acpi_bridge *ab,
244 int seg,
245 int bus /* pdev->subordinate->number */
246 )
247{
248 struct acpi_bridge *lab = NULL;
249
250 if (!ab)
251 return NULL;
252
253 if ((ab->bus == bus) && (ab->seg == seg))
254 return ab;
255
256 if (ab->child)
257 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
258
259 if (!lab)
260 if (ab->next)
261 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
262
263 return lab;
264}
265
266/*
267 * Build a device tree of ACPI PCI Bridges
268 */
269static void shpchprm_acpi_register_a_bridge (
270 struct acpi_bridge **head,
271 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
272 struct acpi_bridge *cab /* child bridge to add */
273 )
274{
275 struct acpi_bridge *lpab;
276 struct acpi_bridge *lcab;
277
278 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
279 if (!lpab) {
280 if (!(pab->type & BRIDGE_TYPE_HOST))
281 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
282 pab->next = *head;
283 *head = pab;
284 lpab = pab;
285 }
286
287 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
288 return;
289
290 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
291 if (lcab) {
292 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
293 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
294 return;
295 } else
296 lcab = cab;
297
298 lcab->parent = lpab;
299 lcab->next = lpab->child;
300 lpab->child = lcab;
301}
302
303static acpi_status shpchprm_acpi_build_php_slots_callback(
304 acpi_handle handle,
305 u32 Level,
306 void *context,
307 void **retval
308 )
309{ 133{
310 ulong bus_num;
311 ulong seg_num;
312 ulong sun, adr;
313 ulong padr = 0;
314 acpi_handle phandle = NULL;
315 struct acpi_bridge *pab = (struct acpi_bridge *)context;
316 struct acpi_bridge *lab;
317 acpi_status status; 134 acpi_status status;
318 u8 *path_name = acpi_path_name(handle); 135 u8 *path_name = acpi_path_name(handle);
319 136
320 /* get _SUN */ 137 /* run OSHP */
321 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun); 138 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
322 switch(status) {
323 case AE_NOT_FOUND:
324 return AE_OK;
325 default:
326 if (ACPI_FAILURE(status)) {
327 err("acpi_shpchprm:%s _SUN fail=0x%x\n", path_name, status);
328 return status;
329 }
330 }
331
332 /* get _ADR. _ADR must exist if _SUN exists */
333 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
334 if (ACPI_FAILURE(status)) {
335 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
336 return status;
337 }
338
339 dbg("acpi_shpchprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
340
341 status = acpi_get_parent(handle, &phandle);
342 if (ACPI_FAILURE(status)) { 139 if (ACPI_FAILURE(status)) {
343 err("acpi_shpchprm:%s get_parent fail=0x%x\n", path_name, status); 140 err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
344 return (status); 141 status);
345 }
346
347 bus_num = pab->bus;
348 seg_num = pab->seg;
349
350 if (pab->bus == bus_num) {
351 lab = pab;
352 } else { 142 } else {
353 dbg("WARN: pab is not parent\n"); 143 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
354 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
355 if (!lab) {
356 dbg("acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
357 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
358 if (!lab) {
359 err("acpi_shpchprm: alloc for ab fail\n");
360 return AE_NO_MEMORY;
361 }
362 memset(lab, 0, sizeof(struct acpi_bridge));
363
364 lab->handle = phandle;
365 lab->pbus = pab->bus;
366 lab->pdevice = (int)(padr >> 16) & 0xffff;
367 lab->pfunction = (int)(padr & 0xffff);
368 lab->bus = (int)bus_num;
369 lab->scanned = 0;
370 lab->type = BRIDGE_TYPE_P2P;
371
372 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
373 } else
374 dbg("acpi_shpchprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
375 }
376
377 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
378 return (status);
379}
380
381static int shpchprm_acpi_build_php_slots(
382 struct acpi_bridge *ab,
383 u32 depth
384 )
385{
386 acpi_status status;
387 u8 *path_name = acpi_path_name(ab->handle);
388
389 /* Walk down this pci bridge to get _SUNs if any behind P2P */
390 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
391 ab->handle,
392 depth,
393 shpchprm_acpi_build_php_slots_callback,
394 ab,
395 NULL );
396 if (ACPI_FAILURE(status)) {
397 dbg("acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
398 return -1;
399 }
400
401 return 0;
402}
403
404static void build_a_bridge(
405 struct acpi_bridge *pab,
406 struct acpi_bridge *ab
407 )
408{
409 u8 *path_name = acpi_path_name(ab->handle);
410
411 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
412
413 switch (ab->type) {
414 case BRIDGE_TYPE_HOST:
415 dbg("acpi_shpchprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
416 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
417 break;
418 case BRIDGE_TYPE_P2P:
419 dbg("acpi_shpchprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
420 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
421 break;
422 };
423
424 /* build any immediate PHP slots under this pci bridge */
425 shpchprm_acpi_build_php_slots(ab, 1);
426}
427
428static struct acpi_bridge * add_p2p_bridge(
429 acpi_handle handle,
430 struct acpi_bridge *pab, /* parent */
431 ulong adr
432 )
433{
434 struct acpi_bridge *ab;
435 struct pci_dev *pdev;
436 ulong devnum, funcnum;
437 u8 *path_name = acpi_path_name(handle);
438
439 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
440 if (!ab) {
441 err("acpi_shpchprm: alloc for ab fail\n");
442 return NULL;
443 }
444 memset(ab, 0, sizeof(struct acpi_bridge));
445
446 devnum = (adr >> 16) & 0xffff;
447 funcnum = adr & 0xffff;
448
449 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
450 if (!pdev || !pdev->subordinate) {
451 err("acpi_shpchprm:%s is not a P2P Bridge\n", path_name);
452 kfree(ab);
453 return NULL;
454 }
455
456 ab->handle = handle;
457 ab->seg = pab->seg;
458 ab->pbus = pab->bus; /* or pdev->bus->number */
459 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
460 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
461 ab->bus = pdev->subordinate->number;
462 ab->scanned = 0;
463 ab->type = BRIDGE_TYPE_P2P;
464
465 dbg("acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
466 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
467 pab->bus, (u32)devnum, (u32)funcnum, path_name);
468
469 build_a_bridge(pab, ab);
470
471 return ab;
472}
473
474static acpi_status scan_p2p_bridge(
475 acpi_handle handle,
476 u32 Level,
477 void *context,
478 void **retval
479 )
480{
481 struct acpi_bridge *pab = (struct acpi_bridge *)context;
482 struct acpi_bridge *ab;
483 acpi_status status;
484 ulong adr = 0;
485 u8 *path_name = acpi_path_name(handle);
486 ulong devnum, funcnum;
487 struct pci_dev *pdev;
488
489 /* get device, function */
490 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
491 if (ACPI_FAILURE(status)) {
492 if (status != AE_NOT_FOUND)
493 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
494 return AE_OK;
495 } 144 }
496
497 devnum = (adr >> 16) & 0xffff;
498 funcnum = adr & 0xffff;
499
500 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
501 if (!pdev)
502 return AE_OK;
503 if (!pdev->subordinate)
504 return AE_OK;
505
506 ab = add_p2p_bridge(handle, pab, adr);
507 if (ab) {
508 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
509 handle,
510 (u32)1,
511 scan_p2p_bridge,
512 ab,
513 NULL);
514 if (ACPI_FAILURE(status))
515 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
516 }
517
518 return AE_OK;
519}
520
521static struct acpi_bridge * add_host_bridge(
522 acpi_handle handle,
523 ulong segnum,
524 ulong busnum
525 )
526{
527 ulong adr = 0;
528 acpi_status status;
529 struct acpi_bridge *ab;
530 u8 *path_name = acpi_path_name(handle);
531
532 /* get device, function: host br adr is always 0000 though. */
533 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
534 if (ACPI_FAILURE(status)) {
535 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
536 return NULL;
537 }
538 dbg("acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, (u32)busnum,
539 (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
540
541 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
542 if (!ab) {
543 err("acpi_shpchprm: alloc for ab fail\n");
544 return NULL;
545 }
546 memset(ab, 0, sizeof(struct acpi_bridge));
547
548 ab->handle = handle;
549 ab->seg = (int)segnum;
550 ab->bus = ab->pbus = (int)busnum;
551 ab->pdevice = (int)(adr >> 16) & 0xffff;
552 ab->pfunction = (int)(adr & 0xffff);
553 ab->scanned = 0;
554 ab->type = BRIDGE_TYPE_HOST;
555
556 build_a_bridge(ab, ab);
557
558 return ab;
559}
560
561static acpi_status acpi_scan_from_root_pci_callback (
562 acpi_handle handle,
563 u32 Level,
564 void *context,
565 void **retval
566 )
567{
568 ulong segnum = 0;
569 ulong busnum = 0;
570 acpi_status status;
571 struct acpi_bridge *ab;
572 u8 *path_name = acpi_path_name(handle);
573
574 /* get bus number of this pci root bridge */
575 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
576 if (ACPI_FAILURE(status)) {
577 if (status != AE_NOT_FOUND) {
578 err("acpi_shpchprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
579 return status;
580 }
581 segnum = 0;
582 }
583
584 /* get bus number of this pci root bridge */
585 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
586 if (ACPI_FAILURE(status)) {
587 err("acpi_shpchprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
588 return (status);
589 }
590
591 ab = add_host_bridge(handle, segnum, busnum);
592 if (ab) {
593 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
594 handle,
595 1,
596 scan_p2p_bridge,
597 ab,
598 NULL);
599 if (ACPI_FAILURE(status))
600 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
601 }
602
603 return AE_OK;
604}
605
606static int shpchprm_acpi_scan_pci (void)
607{
608 acpi_status status;
609
610 /*
611 * TBD: traverse LDM device tree with the help of
612 * unified ACPI augmented for php device population.
613 */
614 status = acpi_get_devices ( PCI_ROOT_HID_STRING,
615 acpi_scan_from_root_pci_callback,
616 NULL,
617 NULL );
618 if (ACPI_FAILURE(status)) {
619 err("acpi_shpchprm:get_device PCI ROOT HID fail=0x%x\n", status);
620 return -1;
621 }
622
623 return 0;
624}
625
626int shpchprm_init(enum php_ctlr_type ctlr_type)
627{
628 int rc;
629
630 if (ctlr_type != PCI)
631 return -ENODEV;
632
633 dbg("shpchprm ACPI init <enter>\n");
634 acpi_bridges_head = NULL;
635
636 /* construct PCI bus:device tree of acpi_handles */
637 rc = shpchprm_acpi_scan_pci();
638 if (rc)
639 return rc;
640
641 dbg("shpchprm ACPI init %s\n", (rc)?"fail":"success");
642 return rc;
643}
644
645static void free_a_slot(struct acpi_php_slot *aps)
646{
647 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
648
649 kfree(aps);
650}
651
652static void free_a_bridge( struct acpi_bridge *ab)
653{
654 struct acpi_php_slot *aps, *next;
655
656 switch (ab->type) {
657 case BRIDGE_TYPE_HOST:
658 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
659 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
660 break;
661 case BRIDGE_TYPE_P2P:
662 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
663 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
664 break;
665 };
666
667 /* free slots first */
668 for (aps = ab->slots; aps; aps = next) {
669 next = aps->next;
670 free_a_slot(aps);
671 }
672
673 kfree(ab);
674}
675
676static void shpchprm_free_bridges ( struct acpi_bridge *ab)
677{
678 if (!ab)
679 return;
680
681 if (ab->child)
682 shpchprm_free_bridges (ab->child);
683
684 if (ab->next)
685 shpchprm_free_bridges (ab->next);
686
687 free_a_bridge(ab);
688}
689
690void shpchprm_cleanup(void)
691{
692 shpchprm_free_bridges (acpi_bridges_head);
693}
694
695static int get_number_of_slots (
696 struct acpi_bridge *ab,
697 int selfonly
698 )
699{
700 struct acpi_php_slot *aps;
701 int prev_slot = -1;
702 int slot_num = 0;
703
704 for ( aps = ab->slots; aps; aps = aps->next)
705 if (aps->dev != prev_slot) {
706 prev_slot = aps->dev;
707 slot_num++;
708 }
709
710 if (ab->child)
711 slot_num += get_number_of_slots (ab->child, 0);
712
713 if (selfonly)
714 return slot_num;
715
716 if (ab->next)
717 slot_num += get_number_of_slots (ab->next, 0);
718
719 return slot_num;
720}
721
722static struct acpi_php_slot * get_acpi_slot (
723 struct acpi_bridge *ab,
724 u32 sun
725 )
726{
727 struct acpi_php_slot *aps = NULL;
728
729 for ( aps = ab->slots; aps; aps = aps->next)
730 if (aps->sun == sun)
731 return aps;
732
733 if (!aps && ab->child) {
734 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
735 if (aps)
736 return aps;
737 }
738
739 if (!aps && ab->next) {
740 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
741 if (aps)
742 return aps;
743 }
744
745 return aps;
746
747} 145}
748 146
749int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 147int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
@@ -755,108 +153,40 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
755 return 0; 153 return 0;
756} 154}
757 155
758int shpchprm_set_hpp( 156void get_hp_hw_control_from_firmware(struct pci_dev *dev)
759 struct controller *ctrl,
760 struct pci_func *func,
761 u8 card_type
762 )
763{ 157{
764 struct acpi_bridge *ab; 158 /*
765 struct pci_bus lpci_bus, *pci_bus; 159 * OSHP is an optional ACPI firmware control method. If present,
766 int rc = 0; 160 * we need to run it to inform BIOS that we will control SHPC
767 unsigned int devfn; 161 * hardware from now on.
768 u8 cls= 0x08; /* default cache line size */ 162 */
769 u8 lt = 0x40; /* default latency timer */ 163 acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
770 u8 ep = 0; 164 if (!handle)
771 u8 es = 0; 165 return;
772 166 acpi_run_oshp(handle);
773 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
774 pci_bus = &lpci_bus;
775 pci_bus->number = func->bus;
776 devfn = PCI_DEVFN(func->device, func->function);
777
778 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
779
780 if (ab) {
781 if (ab->_hpp) {
782 lt = (u8)ab->_hpp->latency_timer;
783 cls = (u8)ab->_hpp->cache_line_size;
784 ep = (u8)ab->_hpp->enable_perr;
785 es = (u8)ab->_hpp->enable_serr;
786 } else
787 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
788 } else
789 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
790
791
792 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
793 /* set subordinate Latency Timer */
794 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
795 }
796
797 /* set base Latency Timer */
798 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
799 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
800
801 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
802 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
803
804 return rc;
805} 167}
806 168
807void shpchprm_enable_card( 169void get_hp_params_from_firmware(struct pci_dev *dev,
808 struct controller *ctrl, 170 struct hotplug_params *hpp)
809 struct pci_func *func,
810 u8 card_type)
811{ 171{
812 u16 command, cmd, bcommand, bcmd; 172 acpi_status status = AE_NOT_FOUND;
813 struct pci_bus lpci_bus, *pci_bus; 173 struct pci_dev *pdev = dev;
814 struct acpi_bridge *ab;
815 unsigned int devfn;
816 int rc;
817
818 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
819 pci_bus = &lpci_bus;
820 pci_bus->number = func->bus;
821 devfn = PCI_DEVFN(func->device, func->function);
822
823 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
824
825 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
826 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
827 }
828
829 cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
830 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
831 bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
832 174
833 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); 175 /*
834 if (ab) { 176 * _HPP settings apply to all child buses, until another _HPP is
835 if (ab->_hpp) { 177 * encountered. If we don't find an _HPP for the input pci dev,
836 if (ab->_hpp->enable_perr) { 178 * look for it in the parent device scope since that would apply to
837 command |= PCI_COMMAND_PARITY; 179 * this pci dev. If we don't find any _HPP, use hardcoded defaults
838 bcommand |= PCI_BRIDGE_CTL_PARITY; 180 */
839 } else { 181 while (pdev && (ACPI_FAILURE(status))) {
840 command &= ~PCI_COMMAND_PARITY; 182 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
841 bcommand &= ~PCI_BRIDGE_CTL_PARITY; 183 if (!handle)
842 } 184 break;
843 if (ab->_hpp->enable_serr) { 185 status = acpi_run_hpp(handle, hpp);
844 command |= PCI_COMMAND_SERR; 186 if (!(pdev->bus->parent))
845 bcommand |= PCI_BRIDGE_CTL_SERR; 187 break;
846 } else { 188 /* Check if a parent object supports _HPP */
847 command &= ~PCI_COMMAND_SERR; 189 pdev = pdev->bus->parent->self;
848 bcommand &= ~PCI_BRIDGE_CTL_SERR;
849 }
850 } else
851 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
852 } else
853 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
854
855 if (command != cmd) {
856 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
857 }
858 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
859 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
860 } 190 }
861} 191}
862 192
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
index 6c27debe9522..cfc6092e2afd 100644
--- a/drivers/pci/hotplug/shpchprm_legacy.c
+++ b/drivers/pci/hotplug/shpchprm_legacy.c
@@ -37,10 +37,6 @@
37#include "shpchp.h" 37#include "shpchp.h"
38#include "shpchprm.h" 38#include "shpchprm.h"
39 39
40void shpchprm_cleanup(void)
41{
42}
43
44int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 40int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
45{ 41{
46 int offset = devnum - ctrl->slot_device_offset; 42 int offset = devnum - ctrl->slot_device_offset;
@@ -49,97 +45,14 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
49 return 0; 45 return 0;
50} 46}
51 47
52int shpchprm_set_hpp( 48void get_hp_params_from_firmware(struct pci_dev *dev,
53 struct controller *ctrl, 49 struct hotplug_params *hpp)
54 struct pci_func *func,
55 u8 card_type)
56{ 50{
57 u32 rc; 51 return;
58 u8 temp_byte;
59 struct pci_bus lpci_bus, *pci_bus;
60 unsigned int devfn;
61 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
62 pci_bus = &lpci_bus;
63 pci_bus->number = func->bus;
64 devfn = PCI_DEVFN(func->device, func->function);
65
66 temp_byte = 0x40; /* hard coded value for LT */
67 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
68 /* set subordinate Latency Timer */
69 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
70 if (rc) {
71 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
72 func->device, func->function);
73 return rc;
74 }
75 }
76
77 /* set base Latency Timer */
78 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
79 if (rc) {
80 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
81 return rc;
82 }
83
84 /* set Cache Line size */
85 temp_byte = 0x08; /* hard coded value for CLS */
86 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
87 if (rc) {
88 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
89 }
90
91 /* set enable_perr */
92 /* set enable_serr */
93
94 return rc;
95} 52}
96 53
97void shpchprm_enable_card( 54void get_hp_hw_control_from_firmware(struct pci_dev *dev)
98 struct controller *ctrl,
99 struct pci_func *func,
100 u8 card_type)
101{ 55{
102 u16 command, bcommand; 56 return;
103 struct pci_bus lpci_bus, *pci_bus;
104 unsigned int devfn;
105 int rc;
106
107 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
108 pci_bus = &lpci_bus;
109 pci_bus->number = func->bus;
110 devfn = PCI_DEVFN(func->device, func->function);
111
112 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
113 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
114 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
115 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
116 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
117
118 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
119 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
120 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
121 | PCI_BRIDGE_CTL_NO_ISA;
122 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
123 }
124}
125
126static int legacy_shpchprm_init_pci(void)
127{
128 return 0;
129} 57}
130 58
131int shpchprm_init(enum php_ctlr_type ctrl_type)
132{
133 int retval;
134
135 switch (ctrl_type) {
136 case PCI:
137 retval = legacy_shpchprm_init_pci();
138 break;
139 default:
140 retval = -ENODEV;
141 break;
142 }
143
144 return retval;
145}
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
index 9d4ccae5f78e..f36c188c23eb 100644
--- a/drivers/pci/hotplug/shpchprm_nonacpi.c
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -37,11 +37,6 @@
37#include "shpchp.h" 37#include "shpchp.h"
38#include "shpchprm.h" 38#include "shpchprm.h"
39 39
40void shpchprm_cleanup(void)
41{
42 return;
43}
44
45int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 40int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
46{ 41{
47 int offset = devnum - ctrl->slot_device_offset; 42 int offset = devnum - ctrl->slot_device_offset;
@@ -51,106 +46,13 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
51 return 0; 46 return 0;
52} 47}
53 48
54int shpchprm_set_hpp( 49void get_hp_params_from_firmware(struct pci_dev *dev,
55 struct controller *ctrl, 50 struct hotplug_params *hpp)
56 struct pci_func *func,
57 u8 card_type)
58{
59 u32 rc;
60 u8 temp_byte;
61 struct pci_bus lpci_bus, *pci_bus;
62 unsigned int devfn;
63 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
64 pci_bus = &lpci_bus;
65 pci_bus->number = func->bus;
66 devfn = PCI_DEVFN(func->device, func->function);
67
68 temp_byte = 0x40; /* hard coded value for LT */
69 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
70 /* set subordinate Latency Timer */
71 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
72
73 if (rc) {
74 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
75 func->device, func->function);
76 return rc;
77 }
78 }
79
80 /* set base Latency Timer */
81 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
82
83 if (rc) {
84 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
85 return rc;
86 }
87
88 /* set Cache Line size */
89 temp_byte = 0x08; /* hard coded value for CLS */
90
91 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
92
93 if (rc) {
94 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
95 }
96
97 /* set enable_perr */
98 /* set enable_serr */
99
100 return rc;
101}
102
103void shpchprm_enable_card(
104 struct controller *ctrl,
105 struct pci_func *func,
106 u8 card_type)
107{ 51{
108 u16 command, bcommand; 52 return;
109 struct pci_bus lpci_bus, *pci_bus;
110 unsigned int devfn;
111 int rc;
112
113 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
114 pci_bus = &lpci_bus;
115 pci_bus->number = func->bus;
116 devfn = PCI_DEVFN(func->device, func->function);
117
118 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
119
120 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
121 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
122 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
123
124 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
125
126 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
127
128 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
129
130 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
131 | PCI_BRIDGE_CTL_NO_ISA;
132
133 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
134 }
135}
136
137static int legacy_shpchprm_init_pci(void)
138{
139 return 0;
140} 53}
141 54
142int shpchprm_init(enum php_ctlr_type ctrl_type) 55void get_hp_hw_control_from_firmware(struct pci_dev *dev)
143{ 56{
144 int retval; 57 return;
145
146 switch (ctrl_type) {
147 case PCI:
148 retval = legacy_shpchprm_init_pci();
149 break;
150 default:
151 retval = -ENODEV;
152 break;
153 }
154
155 return retval;
156} 58}