Rev 1625 | Rev 1628 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1625 | Rev 1627 | ||
---|---|---|---|
Line 4... | Line 4... | ||
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | 6 | ||
Line 7... | Line 7... | ||
7 | #include "acpi.h" |
7 | #include "acpi.h" |
- | 8 | #include "acpi_bus.h" |
|
- | 9 | ||
- | 10 | #define PREFIX "ACPI: " |
|
Line 8... | Line 11... | ||
8 | 11 | ||
9 | #define ACPI_BUS_CLASS "system_bus" |
12 | #define ACPI_BUS_CLASS "system_bus" |
10 | #define ACPI_BUS_HID "KLBSYBUS" |
13 | #define ACPI_BUS_HID "KLBSYBUS" |
Line 11... | Line 14... | ||
11 | #define ACPI_BUS_DEVICE_NAME "System Bus" |
14 | #define ACPI_BUS_DEVICE_NAME "System Bus" |
Line 12... | Line 15... | ||
12 | 15 | ||
13 | 16 | ||
14 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
- | |
- | 17 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
|
Line 15... | Line 18... | ||
15 | 18 | ||
16 | static LIST_HEAD(acpi_device_list); |
19 | static LIST_HEAD(acpi_device_list); |
17 | static LIST_HEAD(acpi_bus_id_list); |
20 | static LIST_HEAD(acpi_bus_id_list); |
18 | DEFINE_MUTEX(acpi_device_lock); |
21 | |
Line 42... | Line 45... | ||
42 | ACPI_BUS_REMOVAL_SUPRISE, |
45 | ACPI_BUS_REMOVAL_SUPRISE, |
43 | ACPI_BUS_REMOVAL_TYPE_COUNT |
46 | ACPI_BUS_REMOVAL_TYPE_COUNT |
44 | }; |
47 | }; |
45 | 48 | ||
Line 46... | Line -... | ||
46 | enum acpi_bus_device_type { |
- | |
47 | ACPI_BUS_TYPE_DEVICE = 0, |
- | |
48 | ACPI_BUS_TYPE_POWER, |
- | |
49 | ACPI_BUS_TYPE_PROCESSOR, |
- | |
50 | ACPI_BUS_TYPE_THERMAL, |
- | |
51 | ACPI_BUS_TYPE_POWER_BUTTON, |
- | |
52 | ACPI_BUS_TYPE_SLEEP_BUTTON, |
- | |
53 | ACPI_BUS_DEVICE_TYPE_COUNT |
- | |
54 | }; |
- | |
55 | - | ||
56 | /* |
- | |
57 | * _HID definitions |
- | |
58 | * HIDs must conform to ACPI spec(6.1.4) |
- | |
59 | * KolibriOS specific HIDs do not apply to this and begin with KOS: |
- | |
60 | */ |
- | |
61 | - | ||
62 | #define ACPI_POWER_HID "KLBPOWER" |
- | |
63 | #define ACPI_PROCESSOR_OBJECT_HID "KLBCPU" |
- | |
64 | #define ACPI_SYSTEM_HID "KLBSYSTM" |
- | |
65 | #define ACPI_THERMAL_HID "KLBTHERM" |
- | |
66 | #define ACPI_BUTTON_HID_POWERF "KLBPWRBN" |
- | |
67 | #define ACPI_BUTTON_HID_SLEEPF "KLBSLPBN" |
- | |
68 | #define ACPI_VIDEO_HID "KLBVIDEO" |
- | |
69 | #define ACPI_BAY_HID "KLBIOBAY" |
- | |
70 | #define ACPI_DOCK_HID "KLBDOCK" |
- | |
71 | /* Quirk for broken IBM BIOSes */ |
- | |
72 | #define ACPI_SMBUS_IBM_HID "SMBUSIBM" |
- | |
73 | - | ||
74 | - | ||
75 | #define STRUCT_TO_INT(s) (*((int*)&s)) |
- | |
76 | - | ||
77 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ |
- | |
78 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) |
- | |
Line 79... | Line 49... | ||
79 | 49 | ||
80 | #define PCI_MAX_DEVICES 32 |
50 | #define PCI_MAX_DEVICES 32 |
Line 81... | Line 51... | ||
81 | #define PCI_MAX_PINS 4 |
51 | #define PCI_MAX_PINS 4 |
Line 94... | Line 64... | ||
94 | 64 | ||
Line 95... | Line 65... | ||
95 | #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01) |
65 | #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01) |
Line 96... | Line -... | ||
96 | - | ||
97 | - | ||
98 | struct acpi_bus_ops |
- | |
99 | { |
- | |
100 | u32_t acpi_op_add:1; |
- | |
101 | u32_t acpi_op_start:1; |
- | |
102 | }; |
- | |
103 | - | ||
104 | struct acpi_device_flags { |
- | |
105 | u32 dynamic_status:1; |
- | |
106 | u32 bus_address:1; |
- | |
107 | u32 removable:1; |
- | |
108 | u32 ejectable:1; |
- | |
109 | u32 lockable:1; |
- | |
110 | u32 suprise_removal_ok:1; |
- | |
111 | u32 power_manageable:1; |
- | |
112 | u32 performance_manageable:1; |
- | |
113 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ |
- | |
114 | u32 force_power_state:1; |
- | |
115 | u32 reserved:22; |
- | |
116 | }; |
66 | |
117 | - | ||
118 | struct acpi_device_status { |
- | |
119 | u32 present:1; |
- | |
120 | u32 enabled:1; |
- | |
121 | u32 show_in_ui:1; |
- | |
122 | u32 functional:1; |
- | |
123 | u32 battery_present:1; |
- | |
124 | u32 reserved:27; |
- | |
Line 125... | Line -... | ||
125 | }; |
- | |
126 | - | ||
127 | - | ||
128 | typedef char acpi_bus_id[8]; |
67 | |
129 | typedef unsigned long acpi_bus_address; |
- | |
130 | typedef char acpi_device_name[40]; |
- | |
131 | typedef char acpi_device_class[20]; |
68 | struct acpi_device *acpi_root; |
132 | - | ||
133 | struct acpi_hardware_id { |
- | |
Line 134... | Line 69... | ||
134 | struct list_head list; |
69 | |
135 | char *id; |
70 | extern struct resource iomem_resource; |
136 | }; |
- | |
137 | 71 | extern struct resource ioport_resource; |
|
138 | struct acpi_device_pnp |
72 | |
139 | { |
- | |
140 | acpi_bus_id bus_id; /* Object name */ |
- | |
141 | acpi_bus_address bus_address; /* _ADR */ |
- | |
142 | char *unique_id; /* _UID */ |
73 | enum pic_mode |
Line 143... | Line -... | ||
143 | struct list_head ids; /* _HID and _CIDs */ |
- | |
144 | acpi_device_name device_name; /* Driver-determined */ |
74 | { |
145 | acpi_device_class device_class; /* " */ |
75 | IO_PIC = 0, |
146 | }; |
76 | IO_APIC |
147 | - | ||
148 | - | ||
149 | struct acpi_device |
- | |
150 | { |
77 | }; |
151 | int device_type; |
- | |
152 | ACPI_HANDLE handle; /* no handle for fixed hardware */ |
- | |
153 | struct acpi_device *parent; |
- | |
154 | struct list_head children; |
- | |
155 | struct list_head node; |
- | |
156 | // struct list_head wakeup_list; |
- | |
157 | struct acpi_device_status status; |
- | |
158 | struct acpi_device_flags flags; |
- | |
159 | struct acpi_device_pnp pnp; |
- | |
160 | // struct acpi_device_power power; |
- | |
161 | // struct acpi_device_wakeup wakeup; |
78 | |
162 | // struct acpi_device_perf performance; |
- | |
163 | // struct acpi_device_dir dir; |
- | |
164 | // struct acpi_device_ops ops; |
- | |
165 | // struct acpi_driver *driver; |
- | |
166 | void *driver_data; |
- | |
167 | // struct device dev; |
- | |
Line -... | Line 79... | ||
- | 79 | static void set_pic_mode(enum pic_mode mode) |
|
- | 80 | { |
|
- | 81 | ACPI_OBJECT arg1; |
|
- | 82 | ACPI_OBJECT_LIST args; |
|
Line 168... | Line -... | ||
168 | struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ |
- | |
169 | // enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ |
83 | ACPI_STATUS as; |
170 | }; |
84 | |
171 | - | ||
172 | struct acpi_device *acpi_root; |
- | |
173 | - | ||
174 | - | ||
175 | static void |
85 | arg1.Type = ACPI_TYPE_INTEGER; |
176 | acpi_util_eval_error(ACPI_HANDLE h, ACPI_STRING p, ACPI_STATUS s) |
86 | arg1.Integer.Value = mode; |
177 | { |
87 | args.Count = 1; |
178 | #ifdef ACPI_DEBUG_OUTPUT |
88 | args.Pointer = &arg1; |
179 | char prefix[80] = {'\0'}; |
- | |
- | 89 | ||
180 | ACPI_BUFFER buffer = {sizeof(prefix), prefix}; |
90 | as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL); |
Line 181... | Line -... | ||
181 | AcpiGetName(h, ACPI_FULL_PATHNAME, &buffer); |
- | |
182 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n", |
91 | /* |
183 | (char *) prefix, p, AcpiFormatException(s))); |
- | |
184 | #else |
92 | * We can silently ignore failure as it may not be implemented, ACPI should |
185 | return; |
- | |
186 | #endif |
- | |
187 | } |
- | |
188 | - | ||
189 | ACPI_STATUS |
- | |
190 | acpi_evaluate_integer(ACPI_HANDLE handle, ACPI_STRING pathname, |
- | |
191 | ACPI_OBJECT_LIST *arguments, unsigned long long *data) |
- | |
192 | { |
- | |
193 | ACPI_STATUS status = AE_OK; |
93 | * provide us with correct information anyway |
194 | ACPI_OBJECT element; |
- | |
195 | ACPI_BUFFER buffer = { 0, NULL }; |
- | |
196 | - | ||
197 | if (!data) |
- | |
198 | return AE_BAD_PARAMETER; |
- | |
199 | - | ||
200 | buffer.Length = sizeof(ACPI_OBJECT); |
- | |
201 | buffer.Pointer = &element; |
- | |
202 | status = AcpiEvaluateObject(handle, pathname, arguments, &buffer); |
- | |
203 | if (ACPI_FAILURE(status)) { |
- | |
Line 204... | Line 94... | ||
204 | acpi_util_eval_error(handle, pathname, status); |
94 | */ |
Line 205... | Line 95... | ||
205 | return status; |
95 | if (ACPI_SUCCESS(as)) |
- | 96 | dbgprintf(PREFIX "machine set to %s mode\n", mode ? "APIC" : "PIC"); |
|
- | 97 | } |
|
- | 98 | ||
- | 99 | void print_device_tree(struct acpi_device *device) |
|
Line 206... | Line -... | ||
206 | } |
- | |
207 | - | ||
Line -... | Line 100... | ||
- | 100 | { |
|
208 | if (element.Type != ACPI_TYPE_INTEGER) { |
101 | struct acpi_device *child; |
209 | acpi_util_eval_error(handle, pathname, AE_BAD_DATA); |
102 | |
- | 103 | dbgprintf("%s\n", device->pnp.bus_id); |
|
- | 104 | ||
Line 210... | Line -... | ||
210 | return AE_BAD_DATA; |
- | |
211 | } |
- | |
212 | 105 | list_for_each_entry(child, &device->children, node) |
|
213 | *data = element.Integer.Value; |
106 | { |
- | 107 | print_device_tree(child); |
|
Line -... | Line 108... | ||
- | 108 | }; |
|
Line 214... | Line -... | ||
214 | - | ||
215 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); |
- | |
216 | 109 | }; |
|
Line -... | Line 110... | ||
- | 110 | ||
- | 111 | ||
217 | return AE_OK; |
112 | /* |
218 | } |
113 | int acpi_pci_bind_root(struct acpi_device *device) |
219 | 114 | { |
|
220 | void acpi_bus_data_handler(ACPI_HANDLE handle, void *context) |
115 | device->ops.bind = acpi_pci_bind; |
- | 116 | device->ops.unbind = acpi_pci_unbind; |
|
Line 221... | Line -... | ||
221 | { |
- | |
- | 117 | ||
Line 222... | Line -... | ||
222 | - | ||
223 | /* TBD */ |
118 | return 0; |
224 | - | ||
225 | return; |
- | |
226 | } |
- | |
227 | - | ||
228 | - | ||
229 | int acpi_bus_get_device(ACPI_HANDLE handle, struct acpi_device **device) |
- | |
Line -... | Line 119... | ||
- | 119 | } |
|
- | 120 | */ |
|
Line 230... | Line 121... | ||
230 | { |
121 | |
231 | ACPI_STATUS status = AE_OK; |
122 | static bool pci_use_crs = false; |
232 | 123 | ||
- | 124 | #define IORESOURCE_BUS 0x00001000 |
|
233 | if (!device) |
125 | |
Line -... | Line 126... | ||
- | 126 | struct acpi_pci_root { |
|
234 | { |
127 | struct list_head node; |
235 | return -EINVAL; |
128 | struct acpi_device * device; |
236 | }; |
- | |
237 | 129 | struct acpi_pci_id id; |
|
238 | /* TBD: Support fixed-feature devices */ |
- | |
Line 239... | Line 130... | ||
239 | 130 | struct pci_bus *bus; |
|
240 | status = AcpiGetData(handle, acpi_bus_data_handler, (void **)device); |
- | |
241 | if (ACPI_FAILURE(status) || !*device) { |
131 | u16 segment; |
242 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", |
132 | struct resource secondary; /* downstream bus range */ |
243 | handle)); |
133 | |
- | 134 | }; |
|
244 | return -ENODEV; |
135 | |
- | 136 | static LIST_HEAD(acpi_pci_roots); |
|
245 | } |
137 | |
246 | return 0; |
138 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" |
Line 247... | Line 139... | ||
247 | } |
139 | #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" |
248 | 140 | ||
249 | 141 | static ACPI_STATUS |
|
250 | ACPI_STATUS acpi_bus_get_status_handle(ACPI_HANDLE handle, |
142 | get_root_bridge_busnr_callback(ACPI_RESOURCE *resource, void *data) |
251 | unsigned long long *sta) |
- | |
Line -... | Line 143... | ||
- | 143 | { |
|
- | 144 | struct resource *res = data; |
|
252 | { |
145 | ACPI_RESOURCE_ADDRESS64 address; |
- | 146 | ||
253 | ACPI_STATUS status; |
147 | if (resource->Type != ACPI_RESOURCE_TYPE_ADDRESS16 && |
254 | - | ||
255 | status = acpi_evaluate_integer(handle, "_STA", NULL, sta); |
148 | resource->Type != ACPI_RESOURCE_TYPE_ADDRESS32 && |
256 | if (ACPI_SUCCESS(status)) |
- | |
257 | { |
- | |
258 | return AE_OK; |
- | |
259 | }; |
- | |
260 | - | ||
261 | if (status == AE_NOT_FOUND) |
- | |
262 | { |
- | |
263 | *sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | |
- | |
264 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; |
- | |
265 | return AE_OK; |
- | |
266 | } |
- | |
267 | return status; |
- | |
268 | } |
- | |
269 | - | ||
270 | - | ||
271 | - | ||
272 | static int acpi_bus_type_and_status(ACPI_HANDLE handle, int *type, |
- | |
273 | unsigned long long *sta) |
- | |
274 | { |
- | |
275 | ACPI_STATUS status; |
149 | resource->Type != ACPI_RESOURCE_TYPE_ADDRESS64) |
276 | ACPI_OBJECT_TYPE acpi_type; |
- | |
277 | - | ||
278 | status = AcpiGetType(handle, &acpi_type); |
- | |
279 | if (ACPI_FAILURE(status)) |
- | |
280 | { |
- | |
281 | return -ENODEV; |
- | |
282 | }; |
- | |
283 | - | ||
284 | switch (acpi_type) |
- | |
285 | { |
- | |
286 | case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */ |
- | |
287 | case ACPI_TYPE_DEVICE: |
150 | return AE_OK; |
288 | *type = ACPI_BUS_TYPE_DEVICE; |
- | |
289 | status = acpi_bus_get_status_handle(handle, sta); |
- | |
290 | if (ACPI_FAILURE(status)) |
151 | |
291 | { |
152 | AcpiResourceToAddress64(resource, &address); |
Line 292... | Line -... | ||
292 | return -ENODEV; |
- | |
293 | }; |
- | |
294 | break; |
- | |
295 | - | ||
296 | case ACPI_TYPE_PROCESSOR: |
- | |
297 | *type = ACPI_BUS_TYPE_PROCESSOR; |
- | |
298 | status = acpi_bus_get_status_handle(handle, sta); |
- | |
299 | if (ACPI_FAILURE(status)) |
- | |
300 | { |
- | |
301 | return -ENODEV; |
- | |
302 | }; |
- | |
303 | break; |
- | |
304 | case ACPI_TYPE_THERMAL: |
- | |
305 | *type = ACPI_BUS_TYPE_THERMAL; |
- | |
306 | *sta = ACPI_STA_DEFAULT; |
- | |
Line 307... | Line 153... | ||
307 | break; |
153 | if ((address.AddressLength > 0) && |
308 | case ACPI_TYPE_POWER: |
154 | (address.ResourceType == ACPI_BUS_NUMBER_RANGE)) { |
309 | *type = ACPI_BUS_TYPE_POWER; |
155 | res->start = address.Minimum; |
- | 156 | res->end = address.Minimum + address.AddressLength - 1; |
|
310 | *sta = ACPI_STA_DEFAULT; |
157 | } |
311 | break; |
158 | |
312 | default: |
159 | return AE_OK; |
- | 160 | } |
|
313 | return -ENODEV; |
161 | |
314 | } |
- | |
315 | - | ||
316 | return 0; |
- | |
317 | } |
- | |
318 | - | ||
319 | static struct acpi_device *acpi_bus_get_parent(ACPI_HANDLE handle) |
- | |
320 | { |
- | |
321 | ACPI_STATUS status; |
- | |
322 | struct acpi_device *device; |
- | |
323 | int ret; |
- | |
324 | - | ||
325 | /* |
- | |
326 | * Fixed hardware devices do not appear in the namespace and do not |
- | |
327 | * have handles, but we fabricate acpi_devices for them, so we have |
- | |
328 | * to deal with them specially. |
- | |
329 | */ |
- | |
330 | if (handle == NULL) |
- | |
331 | { |
- | |
332 | return acpi_root; |
- | |
Line 333... | Line -... | ||
333 | }; |
- | |
334 | - | ||
335 | do |
- | |
336 | { |
- | |
337 | status = AcpiGetParent(handle, &handle); |
- | |
338 | if (status == AE_NULL_ENTRY) |
- | |
339 | { |
- | |
340 | return NULL; |
- | |
341 | }; |
- | |
342 | if (ACPI_FAILURE(status)) |
- | |
Line 343... | Line -... | ||
343 | { |
- | |
344 | return acpi_root; |
- | |
345 | }; |
- | |
346 | - | ||
347 | ret = acpi_bus_get_device(handle, &device); |
162 | |
348 | if (ret == 0) |
- | |
349 | { |
- | |
350 | return device; |
- | |
351 | }; |
- | |
352 | } while (1); |
163 | |
353 | } |
- | |
354 | - | ||
355 | 164 | static ACPI_STATUS try_get_root_bridge_busnr(ACPI_HANDLE handle, |
|
- | 165 | struct resource *res) |
|
- | 166 | { |
|
- | 167 | ACPI_STATUS status; |
|
- | 168 | ||
- | 169 | res->start = -1; |
|
- | 170 | status = |
|
- | 171 | AcpiWalkResources(handle, METHOD_NAME__CRS, |
|
- | 172 | get_root_bridge_busnr_callback, res); |
|
- | 173 | if (ACPI_FAILURE(status)) |
|
- | 174 | return status; |
|
356 | static void acpi_device_get_busid(struct acpi_device *device) |
175 | if (res->start == -1) |
- | 176 | return AE_ERROR; |
|
- | 177 | return AE_OK; |
|
- | 178 | } |
|
- | 179 | ||
- | 180 | ||
- | 181 | struct pci_root_info |
|
357 | { |
182 | { |
- | 183 | struct acpi_device *bridge; |
|
- | 184 | char *name; |
|
- | 185 | unsigned int res_num; |
|
- | 186 | struct resource *res; |
|
- | 187 | struct pci_bus *bus; |
|
- | 188 | int busnum; |
|
- | 189 | }; |
|
- | 190 | ||
- | 191 | ||
358 | char bus_id[5] = { '?', 0 }; |
192 | static ACPI_STATUS |
- | 193 | resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr) |
|
- | 194 | { |
|
- | 195 | ACPI_STATUS status; |
|
- | 196 | struct acpi_resource_memory24 *memory24; |
|
- | 197 | struct acpi_resource_memory32 *memory32; |
|
- | 198 | struct acpi_resource_fixed_memory32 *fixed_memory32; |
|
- | 199 | ||
- | 200 | memset(addr, 0, sizeof(*addr)); |
|
359 | struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; |
201 | switch (resource->Type) { |
360 | int i = 0; |
202 | case ACPI_RESOURCE_TYPE_MEMORY24: |
361 | - | ||
362 | /* |
203 | memory24 = &resource->Data.Memory24; |
363 | * Bus ID |
204 | addr->ResourceType = ACPI_MEMORY_RANGE; |
- | 205 | addr->Minimum = memory24->Minimum; |
|
364 | * ------ |
206 | addr->AddressLength = memory24->AddressLength; |
Line -... | Line 207... | ||
- | 207 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
|
365 | * The device's Bus ID is simply the object name. |
208 | return AE_OK; |
366 | * TBD: Shouldn't this value be unique (within the ACPI namespace)? |
209 | case ACPI_RESOURCE_TYPE_MEMORY32: |
367 | */ |
- | |
368 | if (ACPI_IS_ROOT_DEVICE(device)) { |
210 | memory32 = &resource->Data.Memory32; |
369 | strcpy(device->pnp.bus_id, "ACPI"); |
- | |
370 | return; |
- | |
371 | } |
- | |
372 | 211 | addr->ResourceType = ACPI_MEMORY_RANGE; |
|
373 | switch (device->device_type) |
- | |
374 | { |
- | |
375 | case ACPI_BUS_TYPE_POWER_BUTTON: |
- | |
376 | strcpy(device->pnp.bus_id, "PWRF"); |
- | |
377 | break; |
212 | addr->Minimum = memory32->Minimum; |
378 | case ACPI_BUS_TYPE_SLEEP_BUTTON: |
- | |
Line 379... | Line -... | ||
379 | strcpy(device->pnp.bus_id, "SLPF"); |
- | |
380 | break; |
213 | addr->AddressLength = memory32->AddressLength; |
381 | default: |
214 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
382 | AcpiGetName(device->handle, ACPI_SINGLE_NAME, &buffer); |
215 | return AE_OK; |
383 | /* Clean up trailing underscores (if any) */ |
216 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
384 | for (i = 3; i > 1; i--) |
- | |
385 | { |
- | |
386 | if (bus_id[i] == '_') |
- | |
387 | bus_id[i] = '\0'; |
217 | fixed_memory32 = &resource->Data.FixedMemory32; |
Line 388... | Line -... | ||
388 | else |
- | |
389 | break; |
- | |
390 | } |
- | |
391 | strcpy(device->pnp.bus_id, bus_id); |
- | |
392 | break; |
- | |
393 | } |
- | |
394 | } |
- | |
395 | - | ||
396 | - | ||
397 | static int acpi_bus_get_flags(struct acpi_device *device) |
- | |
398 | { |
- | |
399 | ACPI_STATUS status = AE_OK; |
- | |
400 | ACPI_HANDLE temp = NULL; |
- | |
401 | - | ||
402 | /* Presence of _STA indicates 'dynamic_status' */ |
- | |
403 | status = AcpiGetHandle(device->handle, "_STA", &temp); |
- | |
404 | if (ACPI_SUCCESS(status)) |
- | |
405 | device->flags.dynamic_status = 1; |
- | |
406 | - | ||
407 | /* Presence of _RMV indicates 'removable' */ |
- | |
408 | status = AcpiGetHandle(device->handle, "_RMV", &temp); |
- | |
Line 409... | Line -... | ||
409 | if (ACPI_SUCCESS(status)) |
- | |
410 | device->flags.removable = 1; |
218 | addr->ResourceType = ACPI_MEMORY_RANGE; |
411 | 219 | addr->Minimum = fixed_memory32->Address; |
|
412 | /* Presence of _EJD|_EJ0 indicates 'ejectable' */ |
220 | addr->AddressLength = fixed_memory32->AddressLength; |
413 | status = AcpiGetHandle(device->handle, "_EJD", &temp); |
221 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
414 | if (ACPI_SUCCESS(status)) |
- | |
415 | device->flags.ejectable = 1; |
222 | return AE_OK; |
416 | else { |
223 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
417 | status = AcpiGetHandle(device->handle, "_EJ0", &temp); |
224 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
418 | if (ACPI_SUCCESS(status)) |
225 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
419 | device->flags.ejectable = 1; |
226 | status = AcpiResourceToAddress64(resource, addr); |
Line 420... | Line -... | ||
420 | } |
- | |
421 | - | ||
422 | /* Presence of _LCK indicates 'lockable' */ |
227 | if (ACPI_SUCCESS(status) && |
423 | status = AcpiGetHandle(device->handle, "_LCK", &temp); |
228 | (addr->ResourceType == ACPI_MEMORY_RANGE || |
424 | if (ACPI_SUCCESS(status)) |
229 | addr->ResourceType == ACPI_IO_RANGE) && |
Line 425... | Line 230... | ||
425 | device->flags.lockable = 1; |
230 | addr->AddressLength > 0) { |
- | 231 | return AE_OK; |
|
- | 232 | } |
|
- | 233 | break; |
|
426 | 234 | } |
|
427 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ |
235 | return AE_ERROR; |
- | 236 | } |
|
428 | status = AcpiGetHandle(device->handle, "_PS0", &temp); |
237 | |
- | 238 | ||
- | 239 | static ACPI_STATUS |
|
- | 240 | count_resource(ACPI_RESOURCE *acpi_res, void *data) |
|
- | 241 | { |
|
429 | if (ACPI_FAILURE(status)) |
242 | struct pci_root_info *info = data; |
Line 430... | Line 243... | ||
430 | status = AcpiGetHandle(device->handle, "_PR0", &temp); |
243 | ACPI_RESOURCE_ADDRESS64 addr; |
431 | if (ACPI_SUCCESS(status)) |
244 | ACPI_STATUS status; |
Line 432... | Line 245... | ||
432 | device->flags.power_manageable = 1; |
245 | |
433 | 246 | status = resource_to_addr(acpi_res, &addr); |
|
434 | /* Presence of _PRW indicates wake capable */ |
247 | if (ACPI_SUCCESS(status)) |
435 | status = AcpiGetHandle(device->handle, "_PRW", &temp); |
248 | info->res_num++; |
436 | if (ACPI_SUCCESS(status)) |
249 | return AE_OK; |
- | 250 | } |
|
Line -... | Line 251... | ||
- | 251 | ||
- | 252 | ||
437 | device->flags.wake_capable = 1; |
253 | static ACPI_STATUS setup_resource(ACPI_RESOURCE *acpi_res, void *data) |
438 | 254 | { |
|
Line 439... | Line 255... | ||
439 | /* TBD: Performance management */ |
255 | struct pci_root_info *info = data; |
440 | 256 | struct resource *res; |
|
441 | return 0; |
257 | struct acpi_resource_address64 addr; |
- | 258 | ACPI_STATUS status; |
|
- | 259 | unsigned long flags; |
|
- | 260 | struct resource *root, *conflict; |
|
442 | } |
261 | u64 start, end; |
443 | 262 | ||
- | 263 | status = resource_to_addr(acpi_res, &addr); |
|
444 | /* |
264 | if (!ACPI_SUCCESS(status)) |
- | 265 | return AE_OK; |
|
- | 266 | ||
- | 267 | if (addr.ResourceType == ACPI_MEMORY_RANGE) |
|
- | 268 | { |
|
- | 269 | root = &iomem_resource; |
|
- | 270 | flags = IORESOURCE_MEM; |
|
- | 271 | if (addr.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY) |
|
445 | * acpi_bay_match - see if a device is an ejectable driver bay |
272 | flags |= IORESOURCE_PREFETCH; |
446 | * |
273 | } |
447 | * If an acpi object is ejectable and has one of the ACPI ATA methods defined, |
- | |
448 | * then we can safely call it an ejectable drive bay |
- | |
449 | */ |
- | |
450 | static int acpi_bay_match(struct acpi_device *device){ |
274 | else if (addr.ResourceType == ACPI_IO_RANGE) |
451 | ACPI_STATUS status; |
- | |
452 | ACPI_HANDLE handle; |
- | |
453 | ACPI_HANDLE tmp; |
275 | { |
454 | ACPI_HANDLE phandle; |
276 | root = &ioport_resource; |
Line -... | Line 277... | ||
- | 277 | flags = IORESOURCE_IO; |
|
455 | 278 | } else |
|
- | 279 | return AE_OK; |
|
456 | handle = device->handle; |
280 | |
457 | 281 | start = addr.Minimum + addr.TranslationOffset; |
|
- | 282 | end = addr.Maximum + addr.TranslationOffset; |
|
Line -... | Line 283... | ||
- | 283 | ||
- | 284 | res = &info->res[info->res_num]; |
|
- | 285 | res->name = info->name; |
|
458 | status = AcpiGetHandle(handle, "_EJ0", &tmp); |
286 | res->flags = flags; |
- | 287 | res->start = start; |
|
- | 288 | res->end = end; |
|
459 | if (ACPI_FAILURE(status)) |
289 | res->child = NULL; |
460 | return -ENODEV; |
290 | |
- | 291 | if (!pci_use_crs) { |
|
- | 292 | printk("host bridge window %pR (ignored)\n", res); |
|
- | 293 | return AE_OK; |
|
461 | 294 | } |
|
462 | if ((ACPI_SUCCESS(AcpiGetHandle(handle, "_GTF", &tmp))) || |
- | |
Line -... | Line 295... | ||
- | 295 | ||
- | 296 | #if 0 |
|
- | 297 | conflict = insert_resource_conflict(root, res); |
|
- | 298 | if (conflict) { |
|
- | 299 | dev_err(&info->bridge->dev, |
|
- | 300 | "address space collision: host bridge window %pR " |
|
463 | (ACPI_SUCCESS(AcpiGetHandle(handle, "_GTM", &tmp))) || |
301 | "conflicts with %s %pR\n", |
- | 302 | res, conflict->name, conflict); |
|
- | 303 | } else { |
|
- | 304 | pci_bus_add_resource(info->bus, res, 0); |
|
- | 305 | info->res_num++; |
|
- | 306 | if (addr.translation_offset) |
|
- | 307 | dev_info(&info->bridge->dev, "host bridge window %pR " |
|
- | 308 | "(PCI address [%#llx-%#llx])\n", |
|
Line 464... | Line -... | ||
464 | (ACPI_SUCCESS(AcpiGetHandle(handle, "_STM", &tmp))) || |
- | |
465 | (ACPI_SUCCESS(AcpiGetHandle(handle, "_SDD", &tmp)))) |
- | |
466 | return 0; |
- | |
467 | 309 | res, res->start - addr.translation_offset, |
|
468 | if (AcpiGetParent(handle, &phandle)) |
- | |
469 | return -ENODEV; |
- | |
470 | - | ||
Line -... | Line 310... | ||
- | 310 | res->end - addr.translation_offset); |
|
471 | if ((ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTF", &tmp))) || |
311 | else |
- | 312 | dev_info(&info->bridge->dev, |
|
- | 313 | "host bridge window %pR\n", res); |
|
472 | (ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTM", &tmp))) || |
314 | } |
Line 473... | Line -... | ||
473 | (ACPI_SUCCESS(AcpiGetHandle(phandle, "_STM", &tmp))) || |
- | |
474 | (ACPI_SUCCESS(AcpiGetHandle(phandle, "_SDD", &tmp)))) |
- | |
475 | return 0; |
- | |
476 | - | ||
477 | return -ENODEV; |
- | |
478 | } |
- | |
479 | - | ||
480 | /* |
- | |
481 | * acpi_dock_match - see if a device has a _DCK method |
- | |
482 | */ |
- | |
483 | static int acpi_dock_match(struct acpi_device *device) |
- | |
484 | { |
- | |
Line 485... | Line -... | ||
485 | ACPI_HANDLE tmp; |
- | |
486 | return AcpiGetHandle(device->handle, "_DCK", &tmp); |
- | |
487 | } |
- | |
488 | - | ||
489 | char *acpi_device_hid(struct acpi_device *device) |
- | |
490 | { |
- | |
491 | struct acpi_hardware_id *hid; |
- | |
492 | - | ||
493 | hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); |
- | |
494 | return hid->id; |
- | |
495 | } |
- | |
496 | - | ||
497 | - | ||
498 | - | ||
499 | static void acpi_add_id(struct acpi_device *device, const char *dev_id) |
- | |
500 | { |
- | |
501 | struct acpi_hardware_id *id; |
- | |
502 | - | ||
503 | id = kmalloc(sizeof(*id), GFP_KERNEL); |
- | |
504 | if (!id) |
- | |
505 | { |
- | |
506 | return; |
- | |
507 | }; |
- | |
508 | - | ||
509 | INIT_LIST_HEAD(&id->list); |
- | |
Line -... | Line 315... | ||
- | 315 | return AE_OK; |
|
- | 316 | #endif |
|
- | 317 | } |
|
- | 318 | ||
Line 510... | Line -... | ||
510 | - | ||
511 | id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL); |
- | |
512 | if (!id->id) { |
- | |
513 | kfree(id); |
- | |
514 | return; |
- | |
515 | } |
- | |
Line 516... | Line -... | ||
516 | - | ||
517 | strcpy(id->id, dev_id); |
- | |
518 | - | ||
519 | list_add_tail(&id->list, &device->pnp.ids); |
319 | |
520 | } |
320 | |
521 | 321 | static void |
|
- | 322 | get_current_resources(struct acpi_device *device, int busnum, |
|
- | 323 | int domain, struct pci_bus *bus) |
|
522 | #define ACPI_VIDEO_OUTPUT_SWITCHING 0x0001 |
324 | { |
- | 325 | struct pci_root_info info; |
|
523 | #define ACPI_VIDEO_DEVICE_POSTING 0x0002 |
326 | size_t size; |
Line 524... | Line 327... | ||
524 | #define ACPI_VIDEO_ROM_AVAILABLE 0x0004 |
327 | |
525 | #define ACPI_VIDEO_BACKLIGHT 0x0008 |
328 | char buf[64]; |
526 | #define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR 0x0010 |
329 | |
527 | #define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO 0x0020 |
330 | // if (pci_use_crs) |
- | 331 | // pci_bus_remove_resources(bus); |
|
528 | #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR 0x0040 |
332 | |
Line 529... | Line 333... | ||
529 | #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO 0x0080 |
333 | info.bridge = device; |
530 | #define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR 0x0100 |
334 | info.bus = bus; |
531 | #define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200 |
335 | info.res_num = 0; |
532 | #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400 |
336 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, count_resource, |
533 | #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800 |
337 | &info); |
534 | - | ||
535 | - | ||
536 | long acpi_is_video_device(struct acpi_device *device) |
338 | if (!info.res_num) |
537 | { |
339 | return; |
538 | ACPI_HANDLE h_dummy; |
340 | |
539 | long video_caps = 0; |
341 | size = sizeof(*info.res) * info.res_num; |
540 | 342 | info.res = kmalloc(size, GFP_KERNEL); |
|
Line -... | Line 343... | ||
- | 343 | if (!info.res) |
|
541 | if (!device) |
344 | goto res_alloc_fail; |
542 | return 0; |
- | |
543 | 345 | ||
544 | /* Is this device able to support video switching ? */ |
346 | vsprintf(buf,"PCI Bus %04x:%02x", domain, busnum); |
545 | if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOD", &h_dummy)) || |
347 | info.name = strdup(buf); |
546 | ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOS", &h_dummy))) |
348 | |
547 | video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; |
- | |
548 | - | ||
549 | /* Is this device able to retrieve a video ROM ? */ |
- | |
550 | if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_ROM", &h_dummy))) |
349 | if (!info.name) |
551 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; |
- | |
552 | - | ||
553 | /* Is this device able to configure which video head to be POSTed ? */ |
- | |
554 | if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_VPO", &h_dummy)) && |
- | |
555 | ACPI_SUCCESS(AcpiGetHandle(device->handle, "_GPD", &h_dummy)) && |
- | |
556 | ACPI_SUCCESS(AcpiGetHandle(device->handle, "_SPD", &h_dummy))) |
- | |
557 | video_caps |= ACPI_VIDEO_DEVICE_POSTING; |
- | |
558 | - | ||
559 | return video_caps; |
- | |
560 | } |
- | |
561 | - | ||
562 | - | ||
563 | static void acpi_device_set_id(struct acpi_device *device) |
- | |
564 | { |
- | |
565 | ACPI_STATUS status; |
- | |
566 | ACPI_DEVICE_INFO *info; |
- | |
567 | ACPI_DEVICE_ID_LIST *cid_list; |
- | |
568 | int i; |
- | |
569 | - | ||
570 | switch (device->device_type) |
- | |
571 | { |
- | |
572 | case ACPI_BUS_TYPE_DEVICE: |
- | |
573 | if (ACPI_IS_ROOT_DEVICE(device)) |
- | |
574 | { |
- | |
575 | acpi_add_id(device, ACPI_SYSTEM_HID); |
350 | goto name_alloc_fail; |
576 | break; |
- | |
577 | } |
- | |
578 | 351 | ||
579 | status = AcpiGetObjectInfo(device->handle, &info); |
- | |
580 | if (ACPI_FAILURE(status)) { |
352 | info.res_num = 0; |
581 | printk(KERN_ERR "%s: Error reading device info\n", __func__); |
- | |
582 | return; |
- | |
583 | } |
353 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, setup_resource, |
584 | 354 | &info); |
|
585 | if (info->Valid & ACPI_VALID_HID) |
355 | |
- | 356 | return; |
|
- | 357 | ||
- | 358 | name_alloc_fail: |
|
- | 359 | kfree(info.res); |
|
586 | acpi_add_id(device, info->HardwareId.String); |
360 | res_alloc_fail: |
- | 361 | return; |
|
- | 362 | } |
|
587 | if (info->Valid & ACPI_VALID_CID) |
363 | |
Line -... | Line 364... | ||
- | 364 | ||
- | 365 | ||
Line 588... | Line -... | ||
588 | { |
- | |
589 | cid_list = &info->CompatibleIdList; |
- | |
590 | for (i = 0; i < cid_list->Count; i++) |
366 | |
591 | acpi_add_id(device, cid_list->Ids[i].String); |
- | |
592 | } |
- | |
593 | if (info->Valid & ACPI_VALID_ADR) { |
- | |
594 | device->pnp.bus_address = info->Address; |
- | |
595 | device->flags.bus_address = 1; |
- | |
596 | } |
- | |
597 | 367 | struct pci_ops pci_root_ops = { |
|
598 | kfree(info); |
368 | .read = NULL, |
599 | - | ||
600 | /* |
- | |
601 | * Some devices don't reliably have _HIDs & _CIDs, so add |
- | |
602 | * synthetic HIDs to make sure drivers can find them. |
- | |
603 | */ |
- | |
604 | if (acpi_is_video_device(device)) |
- | |
605 | acpi_add_id(device, ACPI_VIDEO_HID); |
- | |
Line 606... | Line -... | ||
606 | else if (ACPI_SUCCESS(acpi_bay_match(device))) |
- | |
607 | acpi_add_id(device, ACPI_BAY_HID); |
369 | .write = NULL, |
608 | else if (ACPI_SUCCESS(acpi_dock_match(device))) |
370 | }; |
Line -... | Line 371... | ||
- | 371 | ||
609 | acpi_add_id(device, ACPI_DOCK_HID); |
372 | |
610 | else if (!acpi_device_hid(device) && |
373 | struct pci_bus* pci_acpi_scan_root(struct acpi_pci_root *root) |
- | 374 | { |
|
- | 375 | struct acpi_device *device = root->device; |
|
611 | ACPI_IS_ROOT_DEVICE(device->parent)) { |
376 | int domain = root->segment; |
612 | acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ |
377 | int busnum = root->secondary.start; |
613 | strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); |
378 | struct pci_bus *bus; |
614 | strcpy(device->pnp.device_class, ACPI_BUS_CLASS); |
- | |
615 | } |
- | |
616 | - | ||
617 | break; |
- | |
618 | case ACPI_BUS_TYPE_POWER: |
- | |
619 | acpi_add_id(device, ACPI_POWER_HID); |
- | |
620 | break; |
379 | struct pci_sysdata *sd; |
621 | case ACPI_BUS_TYPE_PROCESSOR: |
380 | int node = 0; |
Line 622... | Line 381... | ||
622 | acpi_add_id(device, ACPI_PROCESSOR_OBJECT_HID); |
381 | |
623 | break; |
382 | if (domain ) { |
624 | case ACPI_BUS_TYPE_THERMAL: |
- | |
625 | acpi_add_id(device, ACPI_THERMAL_HID); |
383 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
- | 384 | "ignored (multiple domains not supported)\n", |
|
- | 385 | domain, busnum); |
|
- | 386 | return NULL; |
|
- | 387 | } |
|
- | 388 | ||
- | 389 | /* Allocate per-root-bus (not per bus) arch-specific data. |
|
- | 390 | * TODO: leak; this memory is never freed. |
|
- | 391 | * It's arguable whether it's worth the trouble to care. |
|
626 | break; |
392 | */ |
Line -... | Line 393... | ||
- | 393 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
|
627 | case ACPI_BUS_TYPE_POWER_BUTTON: |
394 | if (!sd) { |
- | 395 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
|
- | 396 | "ignored (out of memory)\n", domain, busnum); |
|
- | 397 | return NULL; |
|
628 | acpi_add_id(device, ACPI_BUTTON_HID_POWERF); |
398 | } |
629 | break; |
399 | |
- | 400 | sd->domain = domain; |
|
630 | case ACPI_BUS_TYPE_SLEEP_BUTTON: |
401 | sd->node = node; |
- | 402 | /* |
|
631 | acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF); |
403 | * Maybe the desired pci bus has been already scanned. In such case |
632 | break; |
404 | * it is unnecessary to scan the pci bus with the given domain,busnum. |
633 | } |
405 | */ |
634 | 406 | bus = pci_find_bus(domain, busnum); |
|
635 | /* |
- | |
- | 407 | if (bus) { |
|
636 | * We build acpi_devices for some objects that don't have _HID or _CID, |
408 | /* |
637 | * e.g., PCI bridges and slots. Drivers can't bind to these objects, |
409 | * If the desired bus exits, the content of bus->sysdata will |
638 | * but we do use them indirectly by traversing the acpi_device tree. |
410 | * be replaced by sd. |
639 | * This generic ID isn't useful for driver binding, but it provides |
411 | */ |
640 | * the useful property that "every acpi_device has an ID." |
412 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
641 | */ |
- | |
642 | if (list_empty(&device->pnp.ids)) |
- | |
643 | acpi_add_id(device, "device"); |
- | |
644 | } |
- | |
645 | 413 | kfree(sd); |
|
646 | 414 | } else { |
|
647 | static int acpi_device_set_context(struct acpi_device *device) |
415 | bus = pci_create_bus(busnum, &pci_root_ops, sd); |
648 | { |
416 | if (bus) { |
649 | ACPI_STATUS status; |
- | |
650 | - | ||
651 | /* |
- | |
652 | * Context |
- | |
653 | * ------- |
- | |
654 | * Attach this 'struct acpi_device' to the ACPI object. This makes |
- | |
655 | * resolutions from handle->device very efficient. Fixed hardware |
- | |
656 | * devices have no handles, so we skip them. |
- | |
657 | */ |
- | |
658 | if (!device->handle) |
- | |
659 | return 0; |
- | |
660 | - | ||
661 | status = AcpiAttachData(device->handle, |
- | |
662 | acpi_bus_data_handler, device); |
- | |
663 | if (ACPI_SUCCESS(status)) |
- | |
664 | return 0; |
- | |
665 | - | ||
666 | dbgprintf(KERN_ERR "Error attaching device data\n"); |
- | |
667 | return -ENODEV; |
- | |
668 | } |
- | |
669 | - | ||
670 | - | ||
671 | static int acpi_device_register(struct acpi_device *device) |
- | |
672 | { |
- | |
673 | int result; |
- | |
674 | struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; |
417 | get_current_resources(device, busnum, domain, bus); |
Line 675... | Line -... | ||
675 | int found = 0; |
- | |
676 | - | ||
677 | /* |
- | |
678 | * Linkage |
- | |
679 | * ------- |
- | |
680 | * Link this device to its parent and siblings. |
- | |
681 | */ |
- | |
682 | INIT_LIST_HEAD(&device->children); |
- | |
683 | INIT_LIST_HEAD(&device->node); |
- | |
684 | - | ||
685 | new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); |
- | |
686 | if (!new_bus_id) { |
- | |
687 | dbgprintf(KERN_ERR "Memory allocation error\n"); |
- | |
688 | return -ENOMEM; |
- | |
689 | } |
- | |
690 | - | ||
691 | mutex_lock(&acpi_device_lock); |
- | |
692 | /* |
418 | // bus->subordinate = pci_scan_child_bus(bus); |
693 | * Find suitable bus_id and instance number in acpi_bus_id_list |
419 | } |
694 | * If failed, create one and link it into acpi_bus_id_list |
- | |
695 | */ |
420 | } |
696 | list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) |
421 | |
697 | { |
422 | if (!bus) |
698 | if (!strcmp(acpi_device_bus_id->bus_id, acpi_device_hid(device))) |
- | |
699 | { |
423 | kfree(sd); |
Line 700... | Line 424... | ||
700 | acpi_device_bus_id->instance_no++; |
424 | |
701 | found = 1; |
- | |
702 | kfree(new_bus_id); |
- | |
703 | break; |
425 | if (bus && node != -1) { |
704 | } |
426 | printk("on NUMA node %d\n", node); |
705 | } |
427 | } |
706 | if (!found) |
428 | |
707 | { |
- | |
708 | acpi_device_bus_id = new_bus_id; |
429 | return bus; |
Line 709... | Line 430... | ||
709 | strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); |
430 | } |
710 | acpi_device_bus_id->instance_no = 0; |
- | |
711 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
- | |
712 | } |
431 | |
713 | 432 | ||
714 | // dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); |
- | |
Line -... | Line 433... | ||
- | 433 | ||
- | 434 | static int acpi_pci_root_add(struct acpi_device *device) |
|
Line 715... | Line 435... | ||
715 | 435 | { |
|
716 | if (device->parent) |
436 | unsigned long long segment, bus; |
717 | list_add_tail(&device->node, &device->parent->children); |
- | |
718 | 437 | ACPI_STATUS status; |
|
Line 719... | Line 438... | ||
719 | mutex_unlock(&acpi_device_lock); |
438 | int result; |
- | 439 | struct acpi_pci_root *root; |
|
- | 440 | ACPI_HANDLE handle; |
|
- | 441 | struct acpi_device *child; |
|
- | 442 | u32 flags, base_flags; |
|
720 | 443 | ||
721 | // device->dev.bus = &acpi_bus_type; |
444 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
722 | // device->dev.release = &acpi_device_release; |
- | |
723 | // result = device_register(&device->dev); |
- | |
724 | // if (result) { |
- | |
725 | // dev_err(&device->dev, "Error registering device\n"); |
- | |
Line 726... | Line -... | ||
726 | // goto end; |
- | |
- | 445 | if (!root) |
|
727 | // } |
446 | return -ENOMEM; |
728 | 447 | ||
729 | 448 | segment = 0; |
|
730 | // device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
449 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, |
731 | return 0; |
450 | &segment); |
732 | end: |
- | |
733 | mutex_lock(&acpi_device_lock); |
451 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
734 | if (device->parent) |
452 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); |
Line 735... | Line -... | ||
735 | list_del(&device->node); |
- | |
736 | mutex_unlock(&acpi_device_lock); |
- | |
737 | return result; |
- | |
738 | } |
- | |
739 | - | ||
740 | - | ||
741 | - | ||
742 | static int acpi_add_single_object(struct acpi_device **child, |
- | |
743 | ACPI_HANDLE handle, int type, |
- | |
744 | unsigned long long sta, |
- | |
745 | struct acpi_bus_ops *ops) |
- | |
746 | { |
- | |
747 | int result; |
- | |
748 | struct acpi_device *device; |
- | |
749 | ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
- | |
750 | - | ||
751 | device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); |
- | |
752 | if (!device) { |
- | |
753 | dbgprintf("%s: Memory allocation error\n", __FUNCTION__); |
- | |
754 | return -ENOMEM; |
- | |
755 | } |
- | |
756 | - | ||
757 | INIT_LIST_HEAD(&device->pnp.ids); |
- | |
758 | device->device_type = type; |
- | |
759 | device->handle = handle; |
- | |
760 | device->parent = acpi_bus_get_parent(handle); |
- | |
761 | device->bus_ops = *ops; /* workround for not call .start */ |
453 | result = -ENODEV; |
762 | STRUCT_TO_INT(device->status) = sta; |
454 | goto end; |
- | 455 | } |
|
763 | 456 | ||
764 | acpi_device_get_busid(device); |
457 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ |
765 | - | ||
766 | /* |
458 | root->secondary.flags = IORESOURCE_BUS; |
767 | * Flags |
459 | status = try_get_root_bridge_busnr(device->handle, &root->secondary); |
768 | * ----- |
460 | if (ACPI_FAILURE(status)) |
Line 769... | Line -... | ||
769 | * Note that we only look for object handles -- cannot evaluate objects |
- | |
770 | * until we know the device is present and properly initialized. |
- | |
771 | */ |
- | |
772 | result = acpi_bus_get_flags(device); |
- | |
773 | if (result) |
461 | { |
774 | goto end; |
- | |
775 | 462 | /* |
|
776 | /* |
463 | * We need both the start and end of the downstream bus range |
777 | * Initialize Device |
464 | * to interpret _CBA (MMCONFIG base address), so it really is |
778 | * ----------------- |
- | |
779 | * TBD: Synch with Core's enumeration/initialization process. |
465 | * supposed to be in _CRS. If we don't find it there, all we |
780 | */ |
- | |
781 | acpi_device_set_id(device); |
- | |
782 | - | ||
783 | - | ||
784 | if ((result = acpi_device_set_context(device))) |
- | |
785 | goto end; |
- | |
786 | - | ||
787 | result = acpi_device_register(device); |
- | |
788 | - | ||
789 | /* |
- | |
790 | * Bind _ADR-Based Devices when hot add |
- | |
791 | */ |
- | |
792 | // if (device->flags.bus_address) { |
- | |
793 | // if (device->parent && device->parent->ops.bind) |
- | |
794 | // device->parent->ops.bind(device); |
- | |
795 | // } |
- | |
796 | - | ||
797 | end: |
466 | * can do is assume [_BBN-0xFF] or [0-0xFF]. |
798 | if (!result) { |
- | |
799 | AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer); |
467 | */ |
800 | dbgprintf("Adding [%s]\n", (char *)buffer.Pointer); |
- | |
801 | kfree(buffer.Pointer); |
468 | root->secondary.end = 0xFF; |
802 | *child = device; |
- | |
803 | }; |
- | |
804 | return result; |
- | |
Line -... | Line 469... | ||
- | 469 | printk(KERN_WARNING PREFIX |
|
- | 470 | "no secondary bus range in _CRS\n"); |
|
805 | } |
471 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); |
- | 472 | if (ACPI_SUCCESS(status)) |
|
- | 473 | root->secondary.start = bus; |
|
Line 806... | Line -... | ||
806 | - | ||
807 | 474 | else if (status == AE_NOT_FOUND) |
|
808 | - | ||
809 | - | ||
810 | static ACPI_STATUS acpi_bus_check_add(ACPI_HANDLE handle, u32 lvl, |
- | |
811 | void *context, void **return_value) |
- | |
812 | { |
- | |
813 | struct acpi_bus_ops *ops = context; |
- | |
814 | int type; |
- | |
815 | unsigned long long sta; |
- | |
816 | struct acpi_device *device; |
- | |
817 | ACPI_STATUS status; |
- | |
818 | int result; |
- | |
819 | - | ||
820 | result = acpi_bus_type_and_status(handle, &type, &sta); |
- | |
821 | - | ||
822 | if (result) |
- | |
823 | { |
- | |
Line -... | Line 475... | ||
- | 475 | root->secondary.start = 0; |
|
- | 476 | else { |
|
- | 477 | printk(KERN_ERR PREFIX "can't evaluate _BBN\n"); |
|
- | 478 | result = -ENODEV; |
|
824 | return AE_OK; |
479 | goto end; |
825 | }; |
480 | } |
Line 826... | Line 481... | ||
826 | 481 | } |
|
827 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && |
482 | |
828 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) |
483 | INIT_LIST_HEAD(&root->node); |
829 | { |
484 | root->device = device; |
830 | return AE_CTRL_DEPTH; |
485 | root->segment = segment & 0xFFFF; |
Line 831... | Line -... | ||
831 | }; |
- | |
832 | - | ||
833 | /* |
- | |
834 | * We may already have an acpi_device from a previous enumeration. If |
- | |
835 | * so, we needn't add it again, but we may still have to start it. |
- | |
836 | */ |
- | |
837 | device = NULL; |
- | |
838 | acpi_bus_get_device(handle, &device); |
- | |
839 | if (ops->acpi_op_add && !device) |
- | |
840 | acpi_add_single_object(&device, handle, type, sta, ops); |
- | |
841 | - | ||
842 | if (!device) |
- | |
843 | { |
- | |
844 | return AE_CTRL_DEPTH; |
- | |
845 | }; |
- | |
846 | /* |
- | |
847 | if (ops->acpi_op_start && !(ops->acpi_op_add)) { |
- | |
848 | status = acpi_start_single_object(device); |
- | |
849 | if (ACPI_FAILURE(status)) |
- | |
850 | return AE_CTRL_DEPTH; |
- | |
851 | } |
486 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
852 | */ |
487 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
853 | 488 | device->driver_data = root; |
|
Line -... | Line 489... | ||
- | 489 | ||
- | 490 | /* |
|
854 | if (!*return_value) |
491 | * All supported architectures that use ACPI have support for |
- | 492 | * PCI domains, so we indicate this in _OSC support capabilities. |
|
- | 493 | */ |
|
Line 855... | Line 494... | ||
855 | *return_value = device; |
494 | // flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
856 | 495 | // acpi_pci_osc_support(root, flags); |
|
857 | return AE_OK; |
496 | |
858 | } |
497 | /* |
- | 498 | * TBD: Need PCI interface for enumeration/configuration of roots. |
|
859 | 499 | */ |
|
Line -... | Line 500... | ||
- | 500 | ||
860 | 501 | /* TBD: Locking */ |
|
861 | 502 | list_add_tail(&root->node, &acpi_pci_roots); |
|
862 | static int acpi_bus_scan(ACPI_HANDLE handle, struct acpi_bus_ops *ops, |
503 | |
Line 863... | Line 504... | ||
863 | struct acpi_device **child) |
504 | printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", |
Line 1002... | Line 643... | ||
1002 | 643 | ||
Line 1003... | Line 644... | ||
1003 | 644 | ||
Line 1004... | Line -... | ||
1004 | set_pic_mode(IO_APIC); |
- | |
1005 | - | ||
1006 | #if 0 |
- | |
1007 | scan_devices(); |
- | |
1008 | - | ||
1009 | { |
- | |
1010 | bool retval = false; |
- | |
1011 | u32_t bus, last_bus; |
- | |
1012 | - | ||
1013 | if( (last_bus = PciApi(1))==-1) |
- | |
1014 | return retval; |
- | |
1015 | - | ||
1016 | dbgprintf("last bus %x\n", last_bus); |
- | |
1017 | - | ||
1018 | for(bus=0; bus <= last_bus; bus++) |
- | |
1019 | { |
- | |
1020 | u32_t dev; |
- | |
1021 | - | ||
1022 | for(dev = 0; dev < 32; dev++) |
- | |
1023 | { |
- | |
1024 | u32_t fn; |
- | |
1025 | - | ||
1026 | for(fn = 0; fn < 8; fn++) |
- | |
1027 | { |
- | |
1028 | - | ||
1029 | u32_t id; |
- | |
1030 | u32_t irq_bios, irq_acpi; |
- | |
1031 | u32_t irq_pin; |
- | |
1032 | u16_t pcicmd; |
- | |
1033 | u32_t tmp; |
- | |
1034 | - | ||
1035 | u32_t devfn = (dev<<3 )|fn; |
- | |
1036 | - | ||
1037 | id = PciRead32(bus,devfn, PCI_VENDOR_ID); |
- | |
1038 | - | ||
1039 | /* some broken boards return 0 or ~0 if a slot is empty: */ |
- | |
1040 | if (id == 0xffffffff || id == 0x00000000 || |
- | |
1041 | id == 0x0000ffff || id == 0xffff0000) |
- | |
1042 | continue; |
- | |
1043 | - | ||
1044 | pcicmd = PciRead16(bus,devfn, PCI_COMMAND); |
- | |
1045 | if (! pcicmd & PCI_COMMAND_IO) |
- | |
1046 | continue; |
- | |
1047 | - | ||
1048 | tmp = PciRead32(bus,devfn, 0x3C); |
- | |
1049 | - | ||
1050 | irq_bios = tmp & 0xFF; |
- | |
1051 | irq_pin = (tmp >> 8) & 0xFF; |
- | |
1052 | - | ||
1053 | int slot = (fn >> 3) & 0x1f; |
- | |
1054 | - | ||
1055 | irq_acpi = irqtable[ dev * PCI_MAX_PINS +(irq_pin-1) ]; |
- | |
1056 | - | ||
1057 | if( irq_acpi < 0) |
- | |
1058 | dbgprintf("PCI: no ACPI IRQ routing for " |
- | |
1059 | "device %d.%d.%d INT%c\n",bus,dev,fn,'A'+irq_pin-1); |
- | |
1060 | - | ||
1061 | dbgprintf("pci device %x_%x bus %d dev %d fn %d," |
- | |
1062 | "IRQ PIN %d BIOS IRQ %d ACPI IRQ %d\n", |
- | |
1063 | id & 0xFFFF, id>>16, bus, dev, fn, irq_pin, irq_bios, irq_acpi); |
- | |
1064 | }; |
- | |
1065 | } |
- | |
1066 | }; |
- | |
1067 | }; |
- | |
1068 | #endif |
645 | set_pic_mode(IO_APIC); |
Line 1069... | Line 646... | ||
1069 | 646 | ||
- | 647 | acpi_scan(); |
|
- | 648 | ||
Line 1070... | Line 649... | ||
1070 | acpi_scan(); |
649 | // print_device_tree(acpi_root); |
1071 | 650 | ||
1072 | print_device_tree(acpi_root); |
651 | acpi_init_pci(acpi_root); |
Line 1180... | Line 759... | ||
1180 | return 0; |
759 | return 0; |
Line 1181... | Line 760... | ||
1181 | 760 | ||
Line -... | Line 761... | ||
- | 761 | }; |
|
- | 762 | ||
- | 763 | #if 0 |
|
- | 764 | scan_devices(); |
|
- | 765 | ||
- | 766 | { |
|
- | 767 | bool retval = false; |
|
- | 768 | u32_t bus, last_bus; |
|
- | 769 | ||
- | 770 | if( (last_bus = PciApi(1))==-1) |
|
- | 771 | return retval; |
|
- | 772 | ||
- | 773 | dbgprintf("last bus %x\n", last_bus); |
|
- | 774 | ||
- | 775 | for(bus=0; bus <= last_bus; bus++) |
|
- | 776 | { |
|
- | 777 | u32_t dev; |
|
- | 778 | ||
- | 779 | for(dev = 0; dev < 32; dev++) |
|
- | 780 | { |
|
- | 781 | u32_t fn; |
|
- | 782 | ||
- | 783 | for(fn = 0; fn < 8; fn++) |
|
- | 784 | { |
|
- | 785 | ||
- | 786 | u32_t id; |
|
- | 787 | u32_t irq_bios, irq_acpi; |
|
- | 788 | u32_t irq_pin; |
|
- | 789 | u16_t pcicmd; |
|
- | 790 | u32_t tmp; |
|
- | 791 | ||
- | 792 | u32_t devfn = (dev<<3 )|fn; |
|
- | 793 | ||
- | 794 | id = PciRead32(bus,devfn, PCI_VENDOR_ID); |
|
- | 795 | ||
- | 796 | /* some broken boards return 0 or ~0 if a slot is empty: */ |
|
- | 797 | if (id == 0xffffffff || id == 0x00000000 || |
|
- | 798 | id == 0x0000ffff || id == 0xffff0000) |
|
- | 799 | continue; |
|
- | 800 | ||
- | 801 | pcicmd = PciRead16(bus,devfn, PCI_COMMAND); |
|
- | 802 | if (! pcicmd & PCI_COMMAND_IO) |
|
- | 803 | continue; |
|
- | 804 | ||
- | 805 | tmp = PciRead32(bus,devfn, 0x3C); |
|
- | 806 | ||
- | 807 | irq_bios = tmp & 0xFF; |
|
- | 808 | irq_pin = (tmp >> 8) & 0xFF; |
|
- | 809 | ||
- | 810 | int slot = (fn >> 3) & 0x1f; |
|
- | 811 | ||
- | 812 | irq_acpi = irqtable[ dev * PCI_MAX_PINS +(irq_pin-1) ]; |
|
- | 813 | ||
- | 814 | if( irq_acpi < 0) |
|
- | 815 | dbgprintf("PCI: no ACPI IRQ routing for " |
|
- | 816 | "device %d.%d.%d INT%c\n",bus,dev,fn,'A'+irq_pin-1); |
|
- | 817 | ||
- | 818 | dbgprintf("pci device %x_%x bus %d dev %d fn %d," |
|
- | 819 | "IRQ PIN %d BIOS IRQ %d ACPI IRQ %d\n", |
|
- | 820 | id & 0xFFFF, id>>16, bus, dev, fn, irq_pin, irq_bios, irq_acpi); |
|
- | 821 | }; |
|
- | 822 | } |
|
- | 823 | }; |
|
- | 824 | }; |
|
Line 1182... | Line 825... | ||
1182 | }; |
825 | #endif |
Line 1183... | Line 826... | ||
1183 | 826 | ||
1184 | 827 | ||
Line 1377... | Line 1020... | ||
1377 | // assert(ACPI_SUCCESS(status)); |
1020 | // assert(ACPI_SUCCESS(status)); |
1378 | } |
1021 | } |
1379 | 1022 | ||
Line 1380... | Line 1023... | ||
1380 | #endif>>>3)><3)>3)><3)>3)><3)>3)><3)>3)><3)>3)><3)>3)><3)>>3><3>>>=>> |
1023 | #endif |
- | 1024 | ||
- | 1025 | char* strdup(const char *str) |
|
- | 1026 | { |
|
- | 1027 | size_t len = strlen (str) + 1; |
|
- | 1028 | char *copy = malloc(len); |
|
- | 1029 | if (copy) |
|
- | 1030 | { |
|
- | 1031 | memcpy (copy, str, len); |
|
- | 1032 | } |
|
- | 1033 | return copy; |
|
- | 1034 | }>>>>3><3>>>=>3)><3)>3)><3)>3)><3)>3)><3)>3)><3)>3)><3)>3)><3)> |
|
- | 1035 |