2 * This file is part of the coreboot project.
4 * Copyright (C) 2003-2004 Linux Networx
5 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
6 * Copyright (C) 2003 Greg Watson <jarrah@users.sourceforge.net>
7 * Copyright (C) 2004 Li-Ta Lo <ollie@lanl.gov>
8 * Copyright (C) 2005-2006 Tyan
9 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
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; version 2 of the License.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include <console/console.h>
22 #include <device/device.h>
23 #include <device/path.h>
24 #include <device/pci.h>
25 #include <device/resource.h>
27 /** Linked list of ALL devices */
28 DEVTREE_CONST
struct device
* DEVTREE_CONST all_devices
= &dev_root
;
31 * Given a PCI bus and a devfn number, find the device structure.
33 * @param bus The bus number.
34 * @param devfn A device/function number.
35 * @return Pointer to the device structure (if found), 0 otherwise.
37 DEVTREE_CONST
struct device
*dev_find_slot(unsigned int bus
,
40 DEVTREE_CONST
struct device
*dev
, *result
;
43 for (dev
= all_devices
; dev
; dev
= dev
->next
) {
44 if ((dev
->path
.type
== DEVICE_PATH_PCI
) &&
45 (dev
->bus
->secondary
== bus
) &&
46 (dev
->path
.pci
.devfn
== devfn
)) {
55 * Given a Device Path Type, find the device structure.
57 * @param prev_match The previously matched device instance.
58 * @param path_type The Device Path Type.
59 * @return Pointer to the device structure (if found), 0 otherwise.
61 DEVTREE_CONST
struct device
*dev_find_path(
62 DEVTREE_CONST
struct device
*prev_match
,
63 enum device_path_type path_type
)
65 DEVTREE_CONST
struct device
*dev
, *result
= NULL
;
67 if (prev_match
== NULL
)
68 prev_match
= all_devices
;
70 prev_match
= prev_match
->next
;
72 for (dev
= prev_match
; dev
; dev
= dev
->next
) {
73 if (dev
->path
.type
== path_type
) {
82 * Given a device pointer, find the next PCI device.
84 * @param previous_dev A pointer to a PCI device structure.
85 * @return Pointer to the next device structure (if found), 0 otherwise.
87 DEVTREE_CONST
struct device
*dev_find_next_pci_device(
88 DEVTREE_CONST
struct device
*previous_dev
)
90 return dev_find_path(previous_dev
, DEVICE_PATH_PCI
);
93 static int path_eq(const struct device_path
*path1
,
94 const struct device_path
*path2
)
98 if (path1
->type
!= path2
->type
)
101 switch (path1
->type
) {
102 case DEVICE_PATH_NONE
:
104 case DEVICE_PATH_ROOT
:
107 case DEVICE_PATH_PCI
:
108 equal
= (path1
->pci
.devfn
== path2
->pci
.devfn
);
110 case DEVICE_PATH_PNP
:
111 equal
= (path1
->pnp
.port
== path2
->pnp
.port
) &&
112 (path1
->pnp
.device
== path2
->pnp
.device
);
114 case DEVICE_PATH_I2C
:
115 equal
= (path1
->i2c
.device
== path2
->i2c
.device
) &&
116 (path1
->i2c
.mode_10bit
== path2
->i2c
.mode_10bit
);
118 case DEVICE_PATH_APIC
:
119 equal
= (path1
->apic
.apic_id
== path2
->apic
.apic_id
);
121 case DEVICE_PATH_DOMAIN
:
122 equal
= (path1
->domain
.domain
== path2
->domain
.domain
);
124 case DEVICE_PATH_CPU_CLUSTER
:
125 equal
= (path1
->cpu_cluster
.cluster
126 == path2
->cpu_cluster
.cluster
);
128 case DEVICE_PATH_CPU
:
129 equal
= (path1
->cpu
.id
== path2
->cpu
.id
);
131 case DEVICE_PATH_CPU_BUS
:
132 equal
= (path1
->cpu_bus
.id
== path2
->cpu_bus
.id
);
134 case DEVICE_PATH_GENERIC
:
135 equal
= (path1
->generic
.id
== path2
->generic
.id
) &&
136 (path1
->generic
.subid
== path2
->generic
.subid
);
138 case DEVICE_PATH_SPI
:
139 equal
= (path1
->spi
.cs
== path2
->spi
.cs
);
141 case DEVICE_PATH_USB
:
142 equal
= (path1
->usb
.port_type
== path2
->usb
.port_type
) &&
143 (path1
->usb
.port_id
== path2
->usb
.port_id
);
145 case DEVICE_PATH_MMIO
:
146 equal
= (path1
->mmio
.addr
== path2
->mmio
.addr
);
149 printk(BIOS_ERR
, "Unknown device type: %d\n", path1
->type
);
157 * See if a device structure exists for path.
159 * @param parent The bus to find the device on.
160 * @param path The relative path from the bus to the appropriate device.
161 * @return Pointer to a device structure for the device on bus at path
162 * or 0/NULL if no device is found.
164 DEVTREE_CONST
struct device
*find_dev_path(
165 const struct bus
*parent
, const struct device_path
*path
)
167 DEVTREE_CONST
struct device
*child
;
168 for (child
= parent
->children
; child
; child
= child
->sibling
) {
169 if (path_eq(path
, &child
->path
))
176 * Given an SMBus bus and a device number, find the device structure.
178 * @param bus The bus number.
179 * @param addr A device number.
180 * @return Pointer to the device structure (if found), 0 otherwise.
182 DEVTREE_CONST
struct device
*dev_find_slot_on_smbus(unsigned int bus
,
185 DEVTREE_CONST
struct device
*dev
, *result
;
188 for (dev
= all_devices
; dev
; dev
= dev
->next
) {
189 if ((dev
->path
.type
== DEVICE_PATH_I2C
) &&
190 (dev
->bus
->secondary
== bus
) &&
191 (dev
->path
.i2c
.device
== addr
)) {
200 * Given a PnP port and a device number, find the device structure.
202 * @param port The I/O port.
203 * @param device Logical device number.
204 * @return Pointer to the device structure (if found), 0 otherwise.
206 DEVTREE_CONST
struct device
*dev_find_slot_pnp(u16 port
, u16 device
)
208 DEVTREE_CONST
struct device
*dev
;
210 for (dev
= all_devices
; dev
; dev
= dev
->next
) {
211 if ((dev
->path
.type
== DEVICE_PATH_PNP
) &&
212 (dev
->path
.pnp
.port
== port
) &&
213 (dev
->path
.pnp
.device
== device
)) {
221 * Given a device and previous match iterate through all the children.
223 * @param bus parent device's bus holding all the children
224 * @param prev_child previous child already traversed, if NULL start at
225 * children of parent bus.
226 * @return pointer to child or NULL when no more children
228 DEVTREE_CONST
struct device
*dev_bus_each_child(const struct bus
*parent
,
229 DEVTREE_CONST
struct device
*prev_child
)
231 DEVTREE_CONST
struct device
*dev
;
236 if (prev_child
== NULL
)
237 dev
= parent
->children
;
239 dev
= prev_child
->sibling
;