| 312 | } |
| 313 | |
| 314 | static ACPI_STATUS |
| 315 | atrtc_acpi_cmos_handler(UINT32 func, ACPI_PHYSICAL_ADDRESS addr, |
| 316 | UINT32 bitwidth, UINT64 *value, void *context, void *region_context) |
| 317 | { |
| 318 | device_t dev = context; |
| 319 | UINT32 bytewidth = howmany(bitwidth, 8); |
| 320 | bool is_read = func == ACPI_READ; |
| 321 | |
| 322 | /* ACPICA is very verbose on CMOS handler failures, so we, too */ |
| 323 | #define CMOS_HANDLER_ERR(fmt, ...) \ |
| 324 | device_printf(dev, "ACPI [SystemCMOS] handler: " fmt, ##__VA_ARGS__) |
| 325 | |
| 326 | ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); |
| 327 | |
| 328 | if (value == NULL) { |
| 329 | CMOS_HANDLER_ERR("NULL parameter\n"); |
| 330 | return (AE_BAD_PARAMETER); |
| 331 | } |
| 332 | if (bitwidth == 0 || (bitwidth & 0x07) != 0) { |
| 333 | CMOS_HANDLER_ERR("Invalid bitwidth: %u\n", bitwidth); |
| 334 | return (AE_BAD_PARAMETER); |
| 335 | } |
| 336 | if (!atrtc_check_cmos_access(is_read, addr, bytewidth)) { |
| 337 | CMOS_HANDLER_ERR("%s access rejected: addr=%#04jx, len=%u\n", |
| 338 | is_read ? "Read" : "Write", (uintmax_t)addr, bytewidth); |
| 339 | return (AE_BAD_PARAMETER); |
| 340 | } |
| 341 | |
| 342 | switch (func) { |
| 343 | case ACPI_READ: |
| 344 | rtcin_region(addr, value, bytewidth); |
| 345 | break; |
| 346 | case ACPI_WRITE: |
| 347 | rtcout_region(addr, value, bytewidth); |
| 348 | break; |
| 349 | default: |
| 350 | CMOS_HANDLER_ERR("Invalid function: %u\n", func); |
| 351 | return (AE_BAD_PARAMETER); |
| 352 | } |
| 353 | |
| 354 | ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), |
| 355 | "ACPI RTC CMOS %s access: addr=%#04x, len=%u, val=%*D\n", |
| 356 | is_read ? "read" : "write", (unsigned)addr, bytewidth, |
| 357 | bytewidth, value, " "); |
| 358 | |
| 359 | return (AE_OK); |
| 360 | } |
| 361 | |
| 362 | static int |
| 363 | atrtc_reg_acpi_cmos_handler(device_t dev) |
nothing calls this directly
no test coverage detected