Rev 1500 | Rev 1627 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1500 | Rev 1625 | ||
---|---|---|---|
Line -... | Line 1... | ||
- | 1 | #include |
|
- | 2 | #include |
|
1 | #include |
3 | #include |
- | 4 | #include |
|
2 | #include |
5 | #include |
Line 3... | Line 6... | ||
3 | 6 | ||
Line -... | Line 7... | ||
- | 7 | #include "acpi.h" |
|
- | 8 | ||
- | 9 | #define ACPI_BUS_CLASS "system_bus" |
|
- | 10 | #define ACPI_BUS_HID "KLBSYBUS" |
|
- | 11 | #define ACPI_BUS_DEVICE_NAME "System Bus" |
|
- | 12 | ||
- | 13 | ||
- | 14 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
|
- | 15 | ||
- | 16 | static LIST_HEAD(acpi_device_list); |
|
- | 17 | static LIST_HEAD(acpi_bus_id_list); |
|
- | 18 | DEFINE_MUTEX(acpi_device_lock); |
|
- | 19 | ||
- | 20 | struct acpi_device_bus_id |
|
- | 21 | { |
|
- | 22 | char bus_id[15]; |
|
- | 23 | unsigned int instance_no; |
|
- | 24 | struct list_head node; |
|
- | 25 | }; |
|
4 | #include "acpi.h" |
26 | |
5 | 27 | ||
Line 6... | Line 28... | ||
6 | #define ACPI_NS_ROOT_PATH "\\" |
28 | #define ACPI_NS_ROOT_PATH "\\" |
7 | #define ACPI_NS_SYSTEM_BUS "_SB_" |
29 | #define ACPI_NS_SYSTEM_BUS "_SB_" |
Line 13... | Line 35... | ||
13 | ACPI_IRQ_MODEL_PLATFORM, |
35 | ACPI_IRQ_MODEL_PLATFORM, |
14 | ACPI_IRQ_MODEL_COUNT |
36 | ACPI_IRQ_MODEL_COUNT |
15 | }; |
37 | }; |
16 | 38 | ||
Line -... | Line 39... | ||
- | 39 | enum acpi_bus_removal_type { |
|
- | 40 | ACPI_BUS_REMOVAL_NORMAL = 0, |
|
- | 41 | ACPI_BUS_REMOVAL_EJECT, |
|
- | 42 | ACPI_BUS_REMOVAL_SUPRISE, |
|
- | 43 | ACPI_BUS_REMOVAL_TYPE_COUNT |
|
- | 44 | }; |
|
- | 45 | ||
- | 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) |
|
- | 79 | ||
- | 80 | #define PCI_MAX_DEVICES 32 |
|
- | 81 | #define PCI_MAX_PINS 4 |
|
- | 82 | ||
- | 83 | #define IRQ_TABLE_ENTRIES (PCI_MAX_DEVICES * PCI_MAX_PINS) |
|
- | 84 | ||
- | 85 | static int irqtable[IRQ_TABLE_ENTRIES]; |
|
- | 86 | static ACPI_HANDLE pci_root_handle; |
|
- | 87 | ||
Line 17... | Line 88... | ||
17 | 88 | ||
18 | #define addr_offset(addr, off) \ |
89 | #define addr_offset(addr, off) \ |
Line 19... | Line 90... | ||
19 | (addr_t)((addr_t)(addr) + (addr_t)(off)) |
90 | (addr_t)((addr_t)(addr) + (addr_t)(off)) |
20 | 91 | ||
Line 21... | Line 92... | ||
21 | //#define acpi_remap( addr ) \ |
92 | //#define acpi_remap( addr ) \ |
Line -... | Line 93... | ||
- | 93 | // (addr_t)((addr_t)(addr) + OS_BASE) |
|
- | 94 | ||
- | 95 | #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01) |
|
- | 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 | }; |
|
- | 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; |
|
- | 125 | }; |
|
- | 126 | ||
- | 127 | ||
- | 128 | typedef char acpi_bus_id[8]; |
|
- | 129 | typedef unsigned long acpi_bus_address; |
|
- | 130 | typedef char acpi_device_name[40]; |
|
- | 131 | typedef char acpi_device_class[20]; |
|
- | 132 | ||
- | 133 | struct acpi_hardware_id { |
|
- | 134 | struct list_head list; |
|
- | 135 | char *id; |
|
- | 136 | }; |
|
- | 137 | ||
- | 138 | struct acpi_device_pnp |
|
- | 139 | { |
|
- | 140 | acpi_bus_id bus_id; /* Object name */ |
|
- | 141 | acpi_bus_address bus_address; /* _ADR */ |
|
- | 142 | char *unique_id; /* _UID */ |
|
- | 143 | struct list_head ids; /* _HID and _CIDs */ |
|
- | 144 | acpi_device_name device_name; /* Driver-determined */ |
|
- | 145 | acpi_device_class device_class; /* " */ |
|
- | 146 | }; |
|
- | 147 | ||
- | 148 | ||
- | 149 | struct acpi_device |
|
- | 150 | { |
|
- | 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; |
|
- | 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; |
|
- | 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 */ |
|
- | 170 | }; |
|
- | 171 | ||
- | 172 | struct acpi_device *acpi_root; |
|
- | 173 | ||
- | 174 | ||
- | 175 | static void |
|
- | 176 | acpi_util_eval_error(ACPI_HANDLE h, ACPI_STRING p, ACPI_STATUS s) |
|
- | 177 | { |
|
- | 178 | #ifdef ACPI_DEBUG_OUTPUT |
|
- | 179 | char prefix[80] = {'\0'}; |
|
- | 180 | ACPI_BUFFER buffer = {sizeof(prefix), prefix}; |
|
- | 181 | AcpiGetName(h, ACPI_FULL_PATHNAME, &buffer); |
|
- | 182 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n", |
|
- | 183 | (char *) prefix, p, AcpiFormatException(s))); |
|
- | 184 | #else |
|
22 | // (addr_t)((addr_t)(addr) + OS_BASE) |
185 | return; |
23 | 186 | #endif |
|
24 | #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01) |
187 | } |
25 | 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; |
|
- | 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)) { |
|
- | 204 | acpi_util_eval_error(handle, pathname, status); |
|
- | 205 | return status; |
|
- | 206 | } |
|
- | 207 | ||
- | 208 | if (element.Type != ACPI_TYPE_INTEGER) { |
|
26 | ACPI_STATUS |
209 | acpi_util_eval_error(handle, pathname, AE_BAD_DATA); |
- | 210 | return AE_BAD_DATA; |
|
- | 211 | } |
|
- | 212 | ||
- | 213 | *data = element.Integer.Value; |
|
- | 214 | ||
- | 215 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); |
|
- | 216 | ||
- | 217 | return AE_OK; |
|
- | 218 | } |
|
- | 219 | ||
- | 220 | void acpi_bus_data_handler(ACPI_HANDLE handle, void *context) |
|
- | 221 | { |
|
- | 222 | ||
- | 223 | /* TBD */ |
|
- | 224 | ||
- | 225 | return; |
|
- | 226 | } |
|
- | 227 | ||
- | 228 | ||
- | 229 | int acpi_bus_get_device(ACPI_HANDLE handle, struct acpi_device **device) |
|
- | 230 | { |
|
27 | get_device_by_hid_callback(ACPI_HANDLE obj, u32_t depth, void* context, |
231 | ACPI_STATUS status = AE_OK; |
- | 232 | ||
- | 233 | if (!device) |
|
- | 234 | { |
|
Line -... | Line 235... | ||
- | 235 | return -EINVAL; |
|
- | 236 | }; |
|
- | 237 | ||
- | 238 | /* TBD: Support fixed-feature devices */ |
|
- | 239 | ||
- | 240 | status = AcpiGetData(handle, acpi_bus_data_handler, (void **)device); |
|
- | 241 | if (ACPI_FAILURE(status) || !*device) { |
|
- | 242 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", |
|
- | 243 | handle)); |
|
- | 244 | return -ENODEV; |
|
- | 245 | } |
|
- | 246 | return 0; |
|
- | 247 | } |
|
28 | void** retval) |
248 | |
Line -... | Line 249... | ||
- | 249 | ||
29 | { |
250 | ACPI_STATUS acpi_bus_get_status_handle(ACPI_HANDLE handle, |
- | 251 | unsigned long long *sta) |
|
- | 252 | { |
|
- | 253 | ACPI_STATUS status; |
|
Line 30... | Line 254... | ||
30 | static u32_t counter = 0; |
254 | |
- | 255 | status = acpi_evaluate_integer(handle, "_STA", NULL, sta); |
|
- | 256 | if (ACPI_SUCCESS(status)) |
|
- | 257 | { |
|
- | 258 | return AE_OK; |
|
- | 259 | }; |
|
- | 260 | ||
- | 261 | if (status == AE_NOT_FOUND) |
|
Line 31... | Line -... | ||
31 | static char buff[256]; |
- | |
Line 32... | Line -... | ||
32 | - | ||
33 | ACPI_STATUS status; |
- | |
Line -... | Line 262... | ||
- | 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; |
|
34 | 268 | } |
|
- | 269 | ||
- | 270 | ||
35 | ACPI_BUFFER buffer; |
271 | |
- | 272 | static int acpi_bus_type_and_status(ACPI_HANDLE handle, int *type, |
|
- | 273 | unsigned long long *sta) |
|
- | 274 | { |
|
- | 275 | ACPI_STATUS status; |
|
- | 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: |
|
- | 288 | *type = ACPI_BUS_TYPE_DEVICE; |
|
- | 289 | status = acpi_bus_get_status_handle(handle, sta); |
|
- | 290 | if (ACPI_FAILURE(status)) |
|
- | 291 | { |
|
- | 292 | return -ENODEV; |
|
- | 293 | }; |
|
36 | 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; |
|
37 | ACPI_DEVICE_INFO *info; |
304 | case ACPI_TYPE_THERMAL: |
Line 38... | Line 305... | ||
38 | 305 | *type = ACPI_BUS_TYPE_THERMAL; |
|
- | 306 | *sta = ACPI_STA_DEFAULT; |
|
Line -... | Line 307... | ||
- | 307 | break; |
|
- | 308 | case ACPI_TYPE_POWER: |
|
- | 309 | *type = ACPI_BUS_TYPE_POWER; |
|
39 | // *retval = NULL; |
310 | *sta = ACPI_STA_DEFAULT; |
- | 311 | break; |
|
Line -... | Line 312... | ||
- | 312 | default: |
|
- | 313 | return -ENODEV; |
|
- | 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; |
|
40 | 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; |
|
- | 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)) |
|
- | 343 | { |
|
- | 344 | return acpi_root; |
|
- | 345 | }; |
|
- | 346 | ||
- | 347 | ret = acpi_bus_get_device(handle, &device); |
|
- | 348 | if (ret == 0) |
|
- | 349 | { |
|
- | 350 | return device; |
|
- | 351 | }; |
|
- | 352 | } while (1); |
|
- | 353 | } |
|
- | 354 | ||
- | 355 | ||
- | 356 | static void acpi_device_get_busid(struct acpi_device *device) |
|
- | 357 | { |
|
- | 358 | char bus_id[5] = { '?', 0 }; |
|
- | 359 | struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; |
|
- | 360 | int i = 0; |
|
- | 361 | ||
- | 362 | /* |
|
- | 363 | * Bus ID |
|
- | 364 | * ------ |
|
- | 365 | * The device's Bus ID is simply the object name. |
|
- | 366 | * TBD: Shouldn't this value be unique (within the ACPI namespace)? |
|
- | 367 | */ |
|
- | 368 | if (ACPI_IS_ROOT_DEVICE(device)) { |
|
- | 369 | strcpy(device->pnp.bus_id, "ACPI"); |
|
- | 370 | return; |
|
- | 371 | } |
|
- | 372 | ||
- | 373 | switch (device->device_type) |
|
- | 374 | { |
|
- | 375 | case ACPI_BUS_TYPE_POWER_BUTTON: |
|
- | 376 | strcpy(device->pnp.bus_id, "PWRF"); |
|
- | 377 | break; |
|
- | 378 | case ACPI_BUS_TYPE_SLEEP_BUTTON: |
|
- | 379 | strcpy(device->pnp.bus_id, "SLPF"); |
|
- | 380 | break; |
|
- | 381 | default: |
|
Line -... | Line 382... | ||
- | 382 | AcpiGetName(device->handle, ACPI_SINGLE_NAME, &buffer); |
|
- | 383 | /* Clean up trailing underscores (if any) */ |
|
- | 384 | for (i = 3; i > 1; i--) |
|
- | 385 | { |
|
- | 386 | if (bus_id[i] == '_') |
|
- | 387 | bus_id[i] = '\0'; |
|
- | 388 | else |
|
- | 389 | break; |
|
41 | buffer.Length = 255; |
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); |
|
- | 409 | if (ACPI_SUCCESS(status)) |
|
- | 410 | device->flags.removable = 1; |
|
- | 411 | ||
- | 412 | /* Presence of _EJD|_EJ0 indicates 'ejectable' */ |
|
- | 413 | status = AcpiGetHandle(device->handle, "_EJD", &temp); |
|
- | 414 | if (ACPI_SUCCESS(status)) |
|
- | 415 | device->flags.ejectable = 1; |
|
- | 416 | else { |
|
- | 417 | status = AcpiGetHandle(device->handle, "_EJ0", &temp); |
|
- | 418 | if (ACPI_SUCCESS(status)) |
|
- | 419 | device->flags.ejectable = 1; |
|
- | 420 | } |
|
- | 421 | ||
- | 422 | /* Presence of _LCK indicates 'lockable' */ |
|
- | 423 | status = AcpiGetHandle(device->handle, "_LCK", &temp); |
|
- | 424 | if (ACPI_SUCCESS(status)) |
|
- | 425 | device->flags.lockable = 1; |
|
- | 426 | ||
- | 427 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ |
|
- | 428 | status = AcpiGetHandle(device->handle, "_PS0", &temp); |
|
- | 429 | if (ACPI_FAILURE(status)) |
|
- | 430 | status = AcpiGetHandle(device->handle, "_PR0", &temp); |
|
- | 431 | if (ACPI_SUCCESS(status)) |
|
- | 432 | device->flags.power_manageable = 1; |
|
- | 433 | ||
- | 434 | /* Presence of _PRW indicates wake capable */ |
|
- | 435 | status = AcpiGetHandle(device->handle, "_PRW", &temp); |
|
- | 436 | if (ACPI_SUCCESS(status)) |
|
- | 437 | device->flags.wake_capable = 1; |
|
- | 438 | ||
- | 439 | /* TBD: Performance management */ |
|
- | 440 | ||
- | 441 | return 0; |
|
- | 442 | } |
|
- | 443 | ||
- | 444 | /* |
|
- | 445 | * acpi_bay_match - see if a device is an ejectable driver bay |
|
- | 446 | * |
|
- | 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){ |
|
- | 451 | ACPI_STATUS status; |
|
- | 452 | ACPI_HANDLE handle; |
|
- | 453 | ACPI_HANDLE tmp; |
|
- | 454 | ACPI_HANDLE phandle; |
|
- | 455 | ||
- | 456 | handle = device->handle; |
|
- | 457 | ||
- | 458 | status = AcpiGetHandle(handle, "_EJ0", &tmp); |
|
- | 459 | if (ACPI_FAILURE(status)) |
|
- | 460 | return -ENODEV; |
|
- | 461 | ||
- | 462 | if ((ACPI_SUCCESS(AcpiGetHandle(handle, "_GTF", &tmp))) || |
|
- | 463 | (ACPI_SUCCESS(AcpiGetHandle(handle, "_GTM", &tmp))) || |
|
- | 464 | (ACPI_SUCCESS(AcpiGetHandle(handle, "_STM", &tmp))) || |
|
- | 465 | (ACPI_SUCCESS(AcpiGetHandle(handle, "_SDD", &tmp)))) |
|
- | 466 | return 0; |
|
- | 467 | ||
- | 468 | if (AcpiGetParent(handle, &phandle)) |
|
- | 469 | return -ENODEV; |
|
42 | buffer.Pointer = buff; |
470 | |
- | 471 | if ((ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTF", &tmp))) || |
|
- | 472 | (ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTM", &tmp))) || |
|
- | 473 | (ACPI_SUCCESS(AcpiGetHandle(phandle, "_STM", &tmp))) || |
|
- | 474 | (ACPI_SUCCESS(AcpiGetHandle(phandle, "_SDD", &tmp)))) |
|
- | 475 | return 0; |
|
- | 476 | ||
43 | 477 | return -ENODEV; |
|
- | 478 | } |
|
44 | status = AcpiGetName(obj, ACPI_FULL_PATHNAME, &buffer); |
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 | { |
|
- | 485 | ACPI_HANDLE tmp; |
|
- | 486 | return AcpiGetHandle(device->handle, "_DCK", &tmp); |
|
- | 487 | } |
|
Line -... | Line 488... | ||
- | 488 | ||
- | 489 | char *acpi_device_hid(struct acpi_device *device) |
|
- | 490 | { |
|
- | 491 | struct acpi_hardware_id *hid; |
|
45 | if (status != AE_OK) { |
492 | |
Line 46... | Line 493... | ||
46 | return AE_CTRL_TERMINATE; |
493 | hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); |
47 | } |
- | |
Line -... | Line 494... | ||
- | 494 | return hid->id; |
|
- | 495 | } |
|
- | 496 | ||
48 | 497 | ||
49 | buff[buffer.Length] = '\0'; |
498 | |
Line -... | Line 499... | ||
- | 499 | static void acpi_add_id(struct acpi_device *device, const char *dev_id) |
|
- | 500 | { |
|
50 | 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); |
|
- | 510 | ||
- | 511 | id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL); |
|
- | 512 | if (!id->id) { |
|
- | 513 | kfree(id); |
|
- | 514 | return; |
|
- | 515 | } |
|
- | 516 | ||
- | 517 | strcpy(id->id, dev_id); |
|
- | 518 | ||
51 | dbgprintf("device %d %s ", counter, buff); |
519 | list_add_tail(&id->list, &device->pnp.ids); |
52 | 520 | } |
|
53 | status = AcpiGetObjectInfo(obj, &info); |
521 | |
Line -... | Line 522... | ||
- | 522 | #define ACPI_VIDEO_OUTPUT_SWITCHING 0x0001 |
|
- | 523 | #define ACPI_VIDEO_DEVICE_POSTING 0x0002 |
|
- | 524 | #define ACPI_VIDEO_ROM_AVAILABLE 0x0004 |
|
- | 525 | #define ACPI_VIDEO_BACKLIGHT 0x0008 |
|
- | 526 | #define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR 0x0010 |
|
- | 527 | #define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO 0x0020 |
|
- | 528 | #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR 0x0040 |
|
- | 529 | #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO 0x0080 |
|
54 | 530 | #define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR 0x0100 |
|
- | 531 | #define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200 |
|
- | 532 | #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400 |
|
- | 533 | #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800 |
|
- | 534 | ||
- | 535 | ||
- | 536 | long acpi_is_video_device(struct acpi_device *device) |
|
- | 537 | { |
|
- | 538 | ACPI_HANDLE h_dummy; |
|
- | 539 | long video_caps = 0; |
|
- | 540 | ||
- | 541 | if (!device) |
|
- | 542 | return 0; |
|
- | 543 | ||
- | 544 | /* Is this device able to support video switching ? */ |
|
- | 545 | if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOD", &h_dummy)) || |
|
- | 546 | ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOS", &h_dummy))) |
|
- | 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))) |
|
- | 551 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; |
|
- | 552 | ||
- | 553 | /* Is this device able to configure which video head to be POSTed ? */ |
|
55 | if (ACPI_SUCCESS (status)) |
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 | ||
56 | { |
563 | static void acpi_device_set_id(struct acpi_device *device) |
- | 564 | { |
|
Line 57... | Line 565... | ||
57 | if (info->Valid & ACPI_VALID_HID) |
565 | ACPI_STATUS status; |
58 | dbgprintf (" HID: %s", info->HardwareId.String); |
- | |
59 | 566 | ACPI_DEVICE_INFO *info; |
|
60 | }; |
567 | ACPI_DEVICE_ID_LIST *cid_list; |
61 | 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); |
|
- | 576 | break; |
|
Line 62... | Line -... | ||
62 | dbgprintf("\n"); |
- | |
63 | counter++; |
- | |
64 | - | ||
65 | return AE_OK; |
- | |
66 | } |
- | |
67 | 577 | } |
|
Line -... | Line 578... | ||
- | 578 | ||
- | 579 | status = AcpiGetObjectInfo(device->handle, &info); |
|
- | 580 | if (ACPI_FAILURE(status)) { |
|
- | 581 | printk(KERN_ERR "%s: Error reading device info\n", __func__); |
|
- | 582 | return; |
|
- | 583 | } |
|
- | 584 | ||
- | 585 | if (info->Valid & ACPI_VALID_HID) |
|
- | 586 | acpi_add_id(device, info->HardwareId.String); |
|
- | 587 | if (info->Valid & ACPI_VALID_CID) |
|
- | 588 | { |
|
- | 589 | cid_list = &info->CompatibleIdList; |
|
- | 590 | for (i = 0; i < cid_list->Count; i++) |
|
- | 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 | ||
- | 598 | kfree(info); |
|
- | 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); |
|
- | 606 | else if (ACPI_SUCCESS(acpi_bay_match(device))) |
|
- | 607 | acpi_add_id(device, ACPI_BAY_HID); |
|
- | 608 | else if (ACPI_SUCCESS(acpi_dock_match(device))) |
|
- | 609 | acpi_add_id(device, ACPI_DOCK_HID); |
|
- | 610 | else if (!acpi_device_hid(device) && |
|
- | 611 | ACPI_IS_ROOT_DEVICE(device->parent)) { |
|
- | 612 | acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ |
|
- | 613 | strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); |
|
- | 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; |
|
68 | prt_walk_table(ACPI_BUFFER *prt) |
621 | case ACPI_BUS_TYPE_PROCESSOR: |
- | 622 | acpi_add_id(device, ACPI_PROCESSOR_OBJECT_HID); |
|
- | 623 | break; |
|
- | 624 | case ACPI_BUS_TYPE_THERMAL: |
|
- | 625 | acpi_add_id(device, ACPI_THERMAL_HID); |
|
- | 626 | break; |
|
- | 627 | case ACPI_BUS_TYPE_POWER_BUTTON: |
|
- | 628 | acpi_add_id(device, ACPI_BUTTON_HID_POWERF); |
|
- | 629 | break; |
|
- | 630 | case ACPI_BUS_TYPE_SLEEP_BUTTON: |
|
- | 631 | acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF); |
|
- | 632 | break; |
|
- | 633 | } |
|
- | 634 | ||
- | 635 | /* |
|
- | 636 | * We build acpi_devices for some objects that don't have _HID or _CID, |
|
- | 637 | * e.g., PCI bridges and slots. Drivers can't bind to these objects, |
|
- | 638 | * but we do use them indirectly by traversing the acpi_device tree. |
|
- | 639 | * This generic ID isn't useful for driver binding, but it provides |
|
- | 640 | * the useful property that "every acpi_device has an ID." |
|
- | 641 | */ |
|
- | 642 | if (list_empty(&device->pnp.ids)) |
|
- | 643 | acpi_add_id(device, "device"); |
|
- | 644 | } |
|
- | 645 | ||
- | 646 | ||
- | 647 | static int acpi_device_set_context(struct acpi_device *device) |
|
- | 648 | { |
|
- | 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 | ||
69 | { |
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; |
|
- | 675 | int found = 0; |
|
- | 676 | ||
- | 677 | /* |
|
70 | ACPI_PCI_ROUTING_TABLE *entry; |
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 | /* |
|
- | 693 | * Find suitable bus_id and instance number in acpi_bus_id_list |
|
- | 694 | * If failed, create one and link it into acpi_bus_id_list |
|
- | 695 | */ |
|
- | 696 | list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) |
|
- | 697 | { |
|
- | 698 | if (!strcmp(acpi_device_bus_id->bus_id, acpi_device_hid(device))) |
|
- | 699 | { |
|
- | 700 | acpi_device_bus_id->instance_no++; |
|
- | 701 | found = 1; |
|
- | 702 | kfree(new_bus_id); |
|
- | 703 | break; |
|
- | 704 | } |
|
- | 705 | } |
|
- | 706 | if (!found) |
|
- | 707 | { |
|
- | 708 | acpi_device_bus_id = new_bus_id; |
|
- | 709 | strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); |
|
- | 710 | acpi_device_bus_id->instance_no = 0; |
|
- | 711 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
|
- | 712 | } |
|
- | 713 | ||
- | 714 | // dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); |
|
- | 715 | ||
71 | char *prtptr; |
716 | if (device->parent) |
- | 717 | list_add_tail(&device->node, &device->parent->children); |
|
- | 718 | ||
- | 719 | mutex_unlock(&acpi_device_lock); |
|
- | 720 | ||
- | 721 | // device->dev.bus = &acpi_bus_type; |
|
- | 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"); |
|
- | 726 | // goto end; |
|
- | 727 | // } |
|
- | 728 | ||
- | 729 | ||
- | 730 | // device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
|
- | 731 | return 0; |
|
- | 732 | end: |
|
- | 733 | mutex_lock(&acpi_device_lock); |
|
- | 734 | if (device->parent) |
|
- | 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 */ |
|
- | 762 | STRUCT_TO_INT(device->status) = sta; |
|
- | 763 | ||
- | 764 | acpi_device_get_busid(device); |
|
- | 765 | ||
- | 766 | /* |
|
- | 767 | * Flags |
|
- | 768 | * ----- |
|
- | 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) |
|
- | 774 | goto end; |
|
- | 775 | ||
- | 776 | /* |
|
- | 777 | * Initialize Device |
|
- | 778 | * ----------------- |
|
- | 779 | * TBD: Synch with Core's enumeration/initialization process. |
|
- | 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: |
|
- | 798 | if (!result) { |
|
- | 799 | AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer); |
|
- | 800 | dbgprintf("Adding [%s]\n", (char *)buffer.Pointer); |
|
- | 801 | kfree(buffer.Pointer); |
|
- | 802 | *child = device; |
|
- | 803 | }; |
|
- | 804 | return result; |
|
- | 805 | } |
|
- | 806 | ||
- | 807 | ||
- | 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 | { |
|
- | 824 | return AE_OK; |
|
- | 825 | }; |
|
- | 826 | ||
- | 827 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && |
|
- | 828 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) |
|
- | 829 | { |
|
- | 830 | return AE_CTRL_DEPTH; |
|
- | 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. |
|
72 | 836 | */ |
|
Line -... | Line 837... | ||
- | 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 | } |
|
- | 852 | */ |
|
- | 853 | ||
- | 854 | if (!*return_value) |
|
- | 855 | *return_value = device; |
|
- | 856 | ||
- | 857 | return AE_OK; |
|
- | 858 | } |
|
- | 859 | ||
- | 860 | ||
- | 861 | ||
- | 862 | static int acpi_bus_scan(ACPI_HANDLE handle, struct acpi_bus_ops *ops, |
|
- | 863 | struct acpi_device **child) |
|
- | 864 | { |
|
- | 865 | ACPI_STATUS status; |
|
- | 866 | void *device = NULL; |
|
- | 867 | ||
- | 868 | ENTER(); |
|
- | 869 | ||
- | 870 | status = acpi_bus_check_add(handle, 0, ops, &device); |
|
- | 871 | ||
- | 872 | if (ACPI_SUCCESS(status)) |
|
- | 873 | AcpiWalkNamespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
|
- | 874 | acpi_bus_check_add, NULL, ops, &device); |
|
- | 875 | ||
- | 876 | if (child) |
|
- | 877 | *child = device; |
|
- | 878 | ||
- | 879 | LEAVE(); |
|
- | 880 | ||
- | 881 | if (device) |
|
- | 882 | return 0; |
|
- | 883 | else |
|
- | 884 | return -ENODEV; |
|
- | 885 | } |
|
- | 886 | ||
- | 887 | ||
- | 888 | ||
- | 889 | int acpi_scan() |
|
- | 890 | { |
|
- | 891 | int err; |
|
- | 892 | struct acpi_bus_ops ops; |
|
- | 893 | ||
- | 894 | memset(&ops, 0, sizeof(ops)); |
|
- | 895 | ops.acpi_op_add = 1; |
|
- | 896 | ops.acpi_op_start = 1; |
|
- | 897 | ||
- | 898 | err = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root); |
|
- | 899 | ||
- | 900 | return err; |
|
- | 901 | }; |
|
- | 902 | ||
- | 903 | ||
- | 904 | enum pic_mode |
|
- | 905 | { |
|
- | 906 | IO_PIC = 0, |
|
- | 907 | IO_APIC |
|
- | 908 | }; |
|
- | 909 | ||
- | 910 | static void set_pic_mode(enum pic_mode mode) |
|
- | 911 | { |
|
- | 912 | ACPI_OBJECT arg1; |
|
- | 913 | ACPI_OBJECT_LIST args; |
|
- | 914 | ACPI_STATUS as; |
|
- | 915 | ||
- | 916 | arg1.Type = ACPI_TYPE_INTEGER; |
|
- | 917 | arg1.Integer.Value = mode; |
|
73 | /* First check to see if there is a table to walk. */ |
918 | args.Count = 1; |
74 | if (prt == NULL || prt->Pointer == NULL) |
919 | args.Pointer = &arg1; |
75 | return; |
920 | |
Line 76... | Line 921... | ||
76 | 921 | as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL); |
|
Line 104... | Line 949... | ||
104 | 949 | ||
Line 105... | Line 950... | ||
105 | if(action != 1) |
950 | if(action != 1) |
106 | return 0; |
951 | return 0; |
Line -... | Line 952... | ||
- | 952 | ||
- | 953 | if( !dbg_open("/rd/1/drivers/acpi.log") ) |
|
- | 954 | { |
|
- | 955 | printf("Can't open /rd/1/drivers/acpi.log\nExit\n"); |
|
- | 956 | return 0; |
|
- | 957 | } |
|
107 | 958 | ||
108 | status = AcpiReallocateRootTable(); |
959 | status = AcpiReallocateRootTable(); |
109 | if (ACPI_FAILURE(status)) { |
960 | if (ACPI_FAILURE(status)) { |
110 | dbgprintf("Unable to reallocate ACPI tables\n"); |
961 | dbgprintf("Unable to reallocate ACPI tables\n"); |
111 | goto err; |
962 | goto err; |
Line 131... | Line 982... | ||
131 | AcpiFormatException(status)); |
982 | AcpiFormatException(status)); |
132 | goto err; |
983 | goto err; |
133 | } |
984 | } |
134 | 985 | ||
Line 135... | Line 986... | ||
135 | u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE; |
986 | // u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE; |
Line 136... | Line 987... | ||
136 | 987 | ||
137 | status = AcpiEnableSubsystem(mode); |
988 | status = AcpiEnableSubsystem(0); |
138 | if (status != AE_OK) { |
989 | if (status != AE_OK) { |
139 | dbgprintf("AcpiEnableSubsystem failed (%s)\n", |
990 | dbgprintf("AcpiEnableSubsystem failed (%s)\n", |
140 | AcpiFormatException(status)); |
991 | AcpiFormatException(status)); |
141 | goto err; |
992 | goto err; |
Line 142... | Line 993... | ||
142 | } |
993 | } |
143 | 994 | ||
144 | status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION); |
995 | status = AcpiInitializeObjects (0); |
145 | if (ACPI_FAILURE (status)) |
996 | if (ACPI_FAILURE (status)) |
146 | { |
997 | { |
147 | dbgprintf("AcpiInitializeObjects failed (%s)\n", |
998 | dbgprintf("AcpiInitializeObjects failed (%s)\n", |
148 | AcpiFormatException(status)); |
999 | AcpiFormatException(status)); |
Line -... | Line 1000... | ||
- | 1000 | goto err; |
|
- | 1001 | } |
|
- | 1002 | ||
- | 1003 | ||
- | 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 |
|
- | 1069 | ||
- | 1070 | acpi_scan(); |
|
- | 1071 | ||
- | 1072 | print_device_tree(acpi_root); |
|
- | 1073 | ||
- | 1074 | /* |
|
- | 1075 | ACPI_HANDLE bus_handle; |
|
- | 1076 | ACPI_HANDLE pci_root; |
|
- | 1077 | ||
- | 1078 | status = AcpiGetHandle(0, "\\_SB_", &bus_handle); |
|
- | 1079 | dbgprintf("system bus handle %x\n", bus_handle); |
|
- | 1080 | ||
- | 1081 | status = AcpiGetHandle(bus_handle, "PCI0", &pci_root); |
|
- | 1082 | if (status != AE_OK) { |
|
- | 1083 | dbgprintf("AcpiGetHandle failed (%s)\n", |
|
- | 1084 | AcpiFormatException(status)); |
|
149 | goto err; |
1085 | goto err; |
150 | } |
1086 | } |
- | 1087 | ||
Line 151... | Line 1088... | ||
151 | 1088 | AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 100, |
|
Line -... | Line 1089... | ||
- | 1089 | get_device_by_hid_callback, NULL, NULL, NULL); |
|
- | 1090 | */ |
|
- | 1091 | ||
152 | AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 4, |
1092 | #if 0 |
153 | get_device_by_hid_callback, NULL, NULL, NULL); |
1093 | |
154 | 1094 | AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 4, |
|
Line 155... | Line 1095... | ||
155 | #if 0 |
1095 | get_device_by_hid_callback, NULL, NULL, NULL); |
Line 240... | Line 1180... | ||
240 | return 0; |
1180 | return 0; |
Line 241... | Line 1181... | ||
241 | 1181 | ||
Line -... | Line 1182... | ||
- | 1182 | }; |
|
- | 1183 | ||
- | 1184 | ||
- | 1185 | #if 0 |
|
- | 1186 | ||
- | 1187 | ACPI_STATUS |
|
- | 1188 | get_device_by_hid_callback(ACPI_HANDLE obj, u32_t depth, void* context, |
|
- | 1189 | void** retval) |
|
- | 1190 | { |
|
- | 1191 | static u32_t counter = 0; |
|
- | 1192 | static char buff[256]; |
|
- | 1193 | ||
- | 1194 | ACPI_STATUS status; |
|
- | 1195 | ||
- | 1196 | ACPI_BUFFER buffer; |
|
- | 1197 | ||
- | 1198 | ACPI_DEVICE_INFO *info; |
|
- | 1199 | ||
- | 1200 | // *retval = NULL; |
|
- | 1201 | ||
- | 1202 | buffer.Length = 255; |
|
- | 1203 | buffer.Pointer = buff; |
|
- | 1204 | ||
- | 1205 | status = AcpiGetName(obj, ACPI_FULL_PATHNAME, &buffer); |
|
- | 1206 | if (status != AE_OK) { |
|
- | 1207 | return AE_CTRL_TERMINATE; |
|
- | 1208 | } |
|
- | 1209 | ||
- | 1210 | buff[buffer.Length] = '\0'; |
|
- | 1211 | ||
- | 1212 | dbgprintf("device %d %s ", counter, buff); |
|
- | 1213 | ||
- | 1214 | status = AcpiGetObjectInfo(obj, &info); |
|
- | 1215 | ||
- | 1216 | if (ACPI_SUCCESS (status)) |
|
- | 1217 | { |
|
- | 1218 | if (info->Valid & ACPI_VALID_HID) |
|
- | 1219 | dbgprintf (" HID: %s", info->HardwareId.String); |
|
- | 1220 | ||
- | 1221 | }; |
|
- | 1222 | ||
- | 1223 | dbgprintf("\n"); |
|
- | 1224 | counter++; |
|
- | 1225 | ||
- | 1226 | return AE_OK; |
|
- | 1227 | } |
|
- | 1228 | ||
- | 1229 | prt_walk_table(ACPI_BUFFER *prt) |
|
- | 1230 | { |
|
- | 1231 | ACPI_PCI_ROUTING_TABLE *entry; |
|
- | 1232 | char *prtptr; |
|
- | 1233 | ||
- | 1234 | /* First check to see if there is a table to walk. */ |
|
- | 1235 | if (prt == NULL || prt->Pointer == NULL) |
|
- | 1236 | return; |
|
- | 1237 | ||
- | 1238 | /* Walk the table executing the handler function for each entry. */ |
|
- | 1239 | prtptr = prt->Pointer; |
|
- | 1240 | entry = (ACPI_PCI_ROUTING_TABLE *)prtptr; |
|
- | 1241 | while (entry->Length != 0) |
|
- | 1242 | { |
|
- | 1243 | ||
- | 1244 | dbgprintf("adress: %x %x ", (u32_t)(entry->Address>>32), |
|
- | 1245 | (u32_t)entry->Address); |
|
- | 1246 | dbgprintf("pin: %d index: %d source: %s\n", |
|
- | 1247 | entry->Pin, |
|
- | 1248 | entry->SourceIndex, |
|
- | 1249 | entry->Source); |
|
- | 1250 | ||
- | 1251 | // handler(entry, arg); |
|
- | 1252 | prtptr += entry->Length; |
|
- | 1253 | entry = (ACPI_PCI_ROUTING_TABLE *)prtptr; |
|
- | 1254 | } |
|
- | 1255 | } |
|
- | 1256 | ||
- | 1257 | ||
- | 1258 | static void add_irq(unsigned dev, unsigned pin, u8_t irq) |
|
- | 1259 | { |
|
- | 1260 | // assert(dev < PCI_MAX_DEVICES && pin < PCI_MAX_PINS); |
|
- | 1261 | ||
- | 1262 | irqtable[dev * PCI_MAX_PINS + pin] = irq; |
|
- | 1263 | } |
|
- | 1264 | ||
- | 1265 | static ACPI_STATUS get_irq_resource(ACPI_RESOURCE *res, void *context) |
|
- | 1266 | { |
|
- | 1267 | ACPI_PCI_ROUTING_TABLE *tbl = (ACPI_PCI_ROUTING_TABLE *) context; |
|
- | 1268 | ||
- | 1269 | if (res->Type == ACPI_RESOURCE_TYPE_IRQ) |
|
- | 1270 | { |
|
- | 1271 | ACPI_RESOURCE_IRQ *irq; |
|
- | 1272 | ||
- | 1273 | irq = &res->Data.Irq; |
|
- | 1274 | add_irq(tbl->Address >> 16, tbl->Pin, |
|
- | 1275 | irq->Interrupts[tbl->SourceIndex]); |
|
- | 1276 | } else if (res->Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) |
|
- | 1277 | { |
|
- | 1278 | ACPI_RESOURCE_EXTENDED_IRQ *irq; |
|
- | 1279 | ||
- | 1280 | add_irq(tbl->Address >> 16, tbl->Pin, |
|
- | 1281 | irq->Interrupts[tbl->SourceIndex]); |
|
- | 1282 | } |
|
- | 1283 | ||
- | 1284 | return AE_OK; |
|
- | 1285 | } |
|
- | 1286 | ||
- | 1287 | char buff[4096]; |
|
- | 1288 | ||
- | 1289 | static ACPI_STATUS get_pci_irq_routing(ACPI_HANDLE handle) |
|
- | 1290 | { |
|
- | 1291 | ACPI_STATUS status; |
|
- | 1292 | ACPI_BUFFER abuff; |
|
- | 1293 | ACPI_PCI_ROUTING_TABLE *tbl; |
|
- | 1294 | ||
- | 1295 | abuff.Length = sizeof(buff); |
|
- | 1296 | abuff.Pointer = buff; |
|
- | 1297 | ||
- | 1298 | status = AcpiGetIrqRoutingTable(handle, &abuff); |
|
- | 1299 | if (ACPI_FAILURE(status)) { |
|
- | 1300 | return AE_OK; |
|
- | 1301 | } |
|
- | 1302 | ||
- | 1303 | for (tbl = (ACPI_PCI_ROUTING_TABLE *)abuff.Pointer; tbl->Length; |
|
- | 1304 | tbl = (ACPI_PCI_ROUTING_TABLE *) |
|
- | 1305 | ((char *)tbl + tbl->Length)) |
|
- | 1306 | { |
|
- | 1307 | ACPI_HANDLE src_handle; |
|
- | 1308 | ||
- | 1309 | if (*(char*)tbl->Source == '\0') { |
|
- | 1310 | add_irq(tbl->Address >> 16, tbl->Pin, tbl->SourceIndex); |
|
- | 1311 | continue; |
|
- | 1312 | } |
|
- | 1313 | ||
- | 1314 | status = AcpiGetHandle(handle, tbl->Source, &src_handle); |
|
- | 1315 | if (ACPI_FAILURE(status)) { |
|
- | 1316 | printf("Failed AcpiGetHandle\n"); |
|
- | 1317 | continue; |
|
- | 1318 | } |
|
- | 1319 | status = AcpiWalkResources(src_handle, METHOD_NAME__CRS, |
|
- | 1320 | get_irq_resource, tbl); |
|
- | 1321 | if (ACPI_FAILURE(status)) { |
|
- | 1322 | printf("Failed IRQ resource\n"); |
|
- | 1323 | continue; |
|
- | 1324 | } |
|
- | 1325 | } |
|
- | 1326 | ||
- | 1327 | return AE_OK; |
|
- | 1328 | } |
|
- | 1329 | ||
- | 1330 | static ACPI_STATUS add_pci_root_dev(ACPI_HANDLE handle, |
|
- | 1331 | UINT32 level, |
|
- | 1332 | void *context, |
|
- | 1333 | void **retval) |
|
- | 1334 | { |
|
- | 1335 | int i; |
|
- | 1336 | static unsigned called; |
|
- | 1337 | ||
- | 1338 | if (++called > 1) { |
|
- | 1339 | dbgprintf("ACPI: Warning! Multi rooted PCI is not supported!\n"); |
|
- | 1340 | return AE_OK; |
|
- | 1341 | } |
|
- | 1342 | ||
- | 1343 | for (i = 0; i < IRQ_TABLE_ENTRIES; i++) |
|
- | 1344 | irqtable[i] = -1; |
|
- | 1345 | ||
- | 1346 | return get_pci_irq_routing(handle); |
|
- | 1347 | } |
|
- | 1348 | ||
- | 1349 | static ACPI_STATUS add_pci_dev(ACPI_HANDLE handle, |
|
- | 1350 | UINT32 level, |
|
- | 1351 | void *context, |
|
- | 1352 | void **retval) |
|
- | 1353 | { |
|
- | 1354 | /* skip pci root when we get to it again */ |
|
- | 1355 | if (handle == pci_root_handle) |
|
- | 1356 | return AE_OK; |
|
- | 1357 | ||
- | 1358 | return get_pci_irq_routing(handle); |
|
- | 1359 | } |
|
- | 1360 | ||
- | 1361 | static void scan_devices(void) |
|
- | 1362 | { |
|
- | 1363 | ACPI_STATUS status; |
|
- | 1364 | ||
- | 1365 | /* get the root first */ |
|
- | 1366 | status = AcpiGetDevices("PNP0A03", add_pci_root_dev, NULL, NULL); |
|
- | 1367 | if (status != AE_OK) { |
|
- | 1368 | dbgprintf("scan_devices failed (%s)\n", |
|
- | 1369 | AcpiFormatException(status)); |
|
- | 1370 | return; |
|
- | 1371 | } |
|
- | 1372 | ||
- | 1373 | // assert(ACPI_SUCCESS(status)); |
|
- | 1374 | ||
- | 1375 | /* get the rest of the devices that implement _PRT */ |
|
- | 1376 | status = AcpiGetDevices(NULL, add_pci_dev, NULL, NULL); |
|
- | 1377 | // assert(ACPI_SUCCESS(status)); |
|
- | 1378 | } |