1/*
2 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6#include "pci_openfirmware.h"
7
8#include <stdlib.h>
9#include <string.h>
10
11#include <KernelExport.h>
12
13#include <platform/openfirmware/devices.h>
14#include <platform/openfirmware/openfirmware.h>
15#include <platform/openfirmware/pci.h>
16
17#include "pci_openfirmware_priv.h"
18
19
20typedef status_t (*probeFunction)(int, const StringArrayPropertyValue&);
21
22static const probeFunction sProbeFunctions[] = {
23	ppc_openfirmware_probe_uninorth,
24	ppc_openfirmware_probe_grackle,
25	NULL,
26};
27
28
29status_t
30ppc_openfirmware_pci_controller_init(void)
31{
32	char path[256];
33	int cookie = 0;
34	while (of_get_next_device(&cookie, 0, "pci", path, sizeof(path))
35			== B_OK) {
36dprintf("ppc_openfirmware_pci_controller_init(): pci device node: %s\n", path);
37		// get the device node and the "compatible" property
38		int deviceNode = of_finddevice(path);
39		StringArrayPropertyValue compatible;
40		status_t error = openfirmware_get_property(deviceNode, "compatible",
41			compatible);
42		if (error != B_OK) {
43			dprintf("ppc_openfirmware_pci_controller_init: Failed to get "
44				"\"compatible\" property for pci device: %s\n", path);
45			continue;
46		}
47
48		// probe
49		for (int i = 0; sProbeFunctions[i]; i++) {
50			error = sProbeFunctions[i](deviceNode, compatible);
51			if (error == B_OK)
52				break;
53		}
54	}
55
56	return B_OK;
57}
58
59
60// #pragma mark - support functions
61
62
63char *
64StringArrayPropertyValue::NextElement(int &cookie) const
65{
66	if (cookie >= length)
67		return NULL;
68
69	char *result = value + cookie;
70	cookie += strnlen(result, length - cookie) + 1;
71	return result;
72}
73
74
75bool
76StringArrayPropertyValue::ContainsElement(const char *value) const
77{
78	int cookie = 0;
79	while (char *checkValue = NextElement(cookie)) {
80		if (strcmp(checkValue, value) == 0)
81			return true;
82	}
83
84	return false;
85}
86
87
88status_t
89openfirmware_get_property(int package, const char *propertyName,
90	PropertyValue &value)
91{
92	value.length = of_getproplen(package, propertyName);
93	if (value.length < 0)
94		return B_ENTRY_NOT_FOUND;
95
96	value.value = (char*)malloc(value.length);
97	if (!value.value)
98		return B_NO_MEMORY;
99
100	if (of_getprop(package, propertyName, value.value, value.length)
101		== OF_FAILED) {
102		return B_ERROR;
103	}
104
105	return B_OK;
106}
107
108