1/*
2 *  pci_bind.c - ACPI PCI Device Binding ($Revision: 1.1.1.1 $)
3 *
4 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 *  This program is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or (at
12 *  your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful, but
15 *  WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *  General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License along
20 *  with this program; if not, write to the Free Software Foundation, Inc.,
21 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/types.h>
30#include <linux/proc_fs.h>
31#include <linux/spinlock.h>
32#include <linux/pm.h>
33#include <linux/pci.h>
34#include <linux/acpi.h>
35#include <acpi/acpi_bus.h>
36#include <acpi/acpi_drivers.h>
37
38#define _COMPONENT		ACPI_PCI_COMPONENT
39ACPI_MODULE_NAME("pci_bind");
40
41struct acpi_pci_data {
42	struct acpi_pci_id id;
43	struct pci_bus *bus;
44	struct pci_dev *dev;
45};
46
47static void acpi_pci_data_handler(acpi_handle handle, u32 function,
48				  void *context)
49{
50
51	/* TBD: Anything we need to do here? */
52
53	return;
54}
55
56/**
57 * acpi_get_pci_id
58 * ------------------
59 * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
60 * to resolve PCI information for ACPI-PCI devices defined in the namespace.
61 * This typically occurs when resolving PCI operation region information.
62 */
63acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id)
64{
65	int result = 0;
66	acpi_status status = AE_OK;
67	struct acpi_device *device = NULL;
68	struct acpi_pci_data *data = NULL;
69
70
71	if (!id)
72		return AE_BAD_PARAMETER;
73
74	result = acpi_bus_get_device(handle, &device);
75	if (result) {
76		printk(KERN_ERR PREFIX
77			    "Invalid ACPI Bus context for device %s\n",
78			    acpi_device_bid(device));
79		return AE_NOT_EXIST;
80	}
81
82	status = acpi_get_data(handle, acpi_pci_data_handler, (void **)&data);
83	if (ACPI_FAILURE(status) || !data) {
84		ACPI_EXCEPTION((AE_INFO, status,
85				"Invalid ACPI-PCI context for device %s",
86				acpi_device_bid(device)));
87		return status;
88	}
89
90	*id = data->id;
91
92	/*
93	   id->segment = data->id.segment;
94	   id->bus = data->id.bus;
95	   id->device = data->id.device;
96	   id->function = data->id.function;
97	 */
98
99	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
100			  "Device %s has PCI address %02x:%02x:%02x.%02x\n",
101			  acpi_device_bid(device), id->segment, id->bus,
102			  id->device, id->function));
103
104	return AE_OK;
105}
106
107EXPORT_SYMBOL(acpi_get_pci_id);
108
109int acpi_pci_bind(struct acpi_device *device)
110{
111	int result = 0;
112	acpi_status status = AE_OK;
113	struct acpi_pci_data *data = NULL;
114	struct acpi_pci_data *pdata = NULL;
115	char *pathname = NULL;
116	struct acpi_buffer buffer = { 0, NULL };
117	acpi_handle handle = NULL;
118	struct pci_dev *dev;
119	struct pci_bus *bus;
120
121
122	if (!device || !device->parent)
123		return -EINVAL;
124
125	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
126	if (!pathname)
127		return -ENOMEM;
128	buffer.length = ACPI_PATHNAME_MAX;
129	buffer.pointer = pathname;
130
131	data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
132	if (!data) {
133		kfree(pathname);
134		return -ENOMEM;
135	}
136
137	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
138	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
139			  pathname));
140
141	/*
142	 * Segment & Bus
143	 * -------------
144	 * These are obtained via the parent device's ACPI-PCI context.
145	 */
146	status = acpi_get_data(device->parent->handle, acpi_pci_data_handler,
147			       (void **)&pdata);
148	if (ACPI_FAILURE(status) || !pdata || !pdata->bus) {
149		ACPI_EXCEPTION((AE_INFO, status,
150				"Invalid ACPI-PCI context for parent device %s",
151				acpi_device_bid(device->parent)));
152		result = -ENODEV;
153		goto end;
154	}
155	data->id.segment = pdata->id.segment;
156	data->id.bus = pdata->bus->number;
157
158	/*
159	 * Device & Function
160	 * -----------------
161	 * These are simply obtained from the device's _ADR method.  Note
162	 * that a value of zero is valid.
163	 */
164	data->id.device = device->pnp.bus_address >> 16;
165	data->id.function = device->pnp.bus_address & 0xFFFF;
166
167	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n",
168			  data->id.segment, data->id.bus, data->id.device,
169			  data->id.function));
170
171	/*
172	 * TBD: Support slot devices (e.g. function=0xFFFF).
173	 */
174
175	/*
176	 * Locate PCI Device
177	 * -----------------
178	 * Locate matching device in PCI namespace.  If it doesn't exist
179	 * this typically means that the device isn't currently inserted
180	 * (e.g. docking station, port replicator, etc.).
181	 * We cannot simply search the global pci device list, since
182	 * PCI devices are added to the global pci list when the root
183	 * bridge start ops are run, which may not have happened yet.
184	 */
185	bus = pci_find_bus(data->id.segment, data->id.bus);
186	if (bus) {
187		list_for_each_entry(dev, &bus->devices, bus_list) {
188			if (dev->devfn == PCI_DEVFN(data->id.device,
189						    data->id.function)) {
190				data->dev = dev;
191				break;
192			}
193		}
194	}
195	if (!data->dev) {
196		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
197				  "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
198				  data->id.segment, data->id.bus,
199				  data->id.device, data->id.function));
200		result = -ENODEV;
201		goto end;
202	}
203	if (!data->dev->bus) {
204		printk(KERN_ERR PREFIX
205			    "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
206			    data->id.segment, data->id.bus,
207			    data->id.device, data->id.function);
208		result = -ENODEV;
209		goto end;
210	}
211
212	/*
213	 * PCI Bridge?
214	 * -----------
215	 * If so, set the 'bus' field and install the 'bind' function to
216	 * facilitate callbacks for all of its children.
217	 */
218	if (data->dev->subordinate) {
219		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
220				  "Device %02x:%02x:%02x.%02x is a PCI bridge\n",
221				  data->id.segment, data->id.bus,
222				  data->id.device, data->id.function));
223		data->bus = data->dev->subordinate;
224		device->ops.bind = acpi_pci_bind;
225		device->ops.unbind = acpi_pci_unbind;
226	}
227
228	/*
229	 * Attach ACPI-PCI Context
230	 * -----------------------
231	 * Thus binding the ACPI and PCI devices.
232	 */
233	status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
234	if (ACPI_FAILURE(status)) {
235		ACPI_EXCEPTION((AE_INFO, status,
236				"Unable to attach ACPI-PCI context to device %s",
237				acpi_device_bid(device)));
238		result = -ENODEV;
239		goto end;
240	}
241
242	/*
243	 * PCI Routing Table
244	 * -----------------
245	 * Evaluate and parse _PRT, if exists.  This code is independent of
246	 * PCI bridges (above) to allow parsing of _PRT objects within the
247	 * scope of non-bridge devices.  Note that _PRTs within the scope of
248	 * a PCI bridge assume the bridge's subordinate bus number.
249	 *
250	 * TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
251	 */
252	status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
253	if (ACPI_SUCCESS(status)) {
254		if (data->bus)	/* PCI-PCI bridge */
255			acpi_pci_irq_add_prt(device->handle, data->id.segment,
256					     data->bus->number);
257		else		/* non-bridge PCI device */
258			acpi_pci_irq_add_prt(device->handle, data->id.segment,
259					     data->id.bus);
260	}
261
262      end:
263	kfree(pathname);
264	if (result)
265		kfree(data);
266
267	return result;
268}
269
270int acpi_pci_unbind(struct acpi_device *device)
271{
272	int result = 0;
273	acpi_status status = AE_OK;
274	struct acpi_pci_data *data = NULL;
275	char *pathname = NULL;
276	struct acpi_buffer buffer = { 0, NULL };
277
278
279	if (!device || !device->parent)
280		return -EINVAL;
281
282	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
283	if (!pathname)
284		return -ENOMEM;
285
286	buffer.length = ACPI_PATHNAME_MAX;
287	buffer.pointer = pathname;
288	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
289	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
290			  pathname));
291	kfree(pathname);
292
293	status =
294	    acpi_get_data(device->handle, acpi_pci_data_handler,
295			  (void **)&data);
296	if (ACPI_FAILURE(status)) {
297		ACPI_EXCEPTION((AE_INFO, status,
298				"Unable to get data from device %s",
299				acpi_device_bid(device)));
300		result = -ENODEV;
301		goto end;
302	}
303
304	status = acpi_detach_data(device->handle, acpi_pci_data_handler);
305	if (ACPI_FAILURE(status)) {
306		ACPI_EXCEPTION((AE_INFO, status,
307				"Unable to detach data from device %s",
308				acpi_device_bid(device)));
309		result = -ENODEV;
310		goto end;
311	}
312	if (data->dev->subordinate) {
313		acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
314	}
315	kfree(data);
316
317      end:
318	return result;
319}
320
321int
322acpi_pci_bind_root(struct acpi_device *device,
323		   struct acpi_pci_id *id, struct pci_bus *bus)
324{
325	int result = 0;
326	acpi_status status = AE_OK;
327	struct acpi_pci_data *data = NULL;
328	char *pathname = NULL;
329	struct acpi_buffer buffer = { 0, NULL };
330
331	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
332	if (!pathname)
333		return -ENOMEM;
334
335	buffer.length = ACPI_PATHNAME_MAX;
336	buffer.pointer = pathname;
337
338	if (!device || !id || !bus) {
339		kfree(pathname);
340		return -EINVAL;
341	}
342
343	data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
344	if (!data) {
345		kfree(pathname);
346		return -ENOMEM;
347	}
348
349	data->id = *id;
350	data->bus = bus;
351	device->ops.bind = acpi_pci_bind;
352	device->ops.unbind = acpi_pci_unbind;
353
354	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
355
356	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
357			  "%02x:%02x\n", pathname, id->segment, id->bus));
358
359	status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
360	if (ACPI_FAILURE(status)) {
361		ACPI_EXCEPTION((AE_INFO, status,
362				"Unable to attach ACPI-PCI context to device %s",
363				pathname));
364		result = -ENODEV;
365		goto end;
366	}
367
368      end:
369	kfree(pathname);
370	if (result != 0)
371		kfree(data);
372
373	return result;
374}
375