| 401 | return uwrite(result, 0u); |
| 402 | } |
| 403 | orbis::SysResult orbis::sysIpmiClientInvokeAsyncMethod(Thread *thread, |
| 404 | ptr<uint> result, |
| 405 | uint kid, |
| 406 | ptr<void> params, |
| 407 | uint64_t paramsSz) { |
| 408 | struct IpmiAsyncCallParams { |
| 409 | uint32_t method; |
| 410 | uint32_t evfIndex; |
| 411 | uint64_t evfValue; |
| 412 | uint32_t numInData; |
| 413 | uint32_t padding1; |
| 414 | ptr<IpmiDataInfo> pInData; |
| 415 | ptr<sint> pResult; |
| 416 | uint32_t flags; |
| 417 | }; |
| 418 | |
| 419 | static_assert(sizeof(IpmiAsyncCallParams) == 0x30); |
| 420 | |
| 421 | if (paramsSz != sizeof(IpmiAsyncCallParams)) { |
| 422 | return ErrorCode::INVAL; |
| 423 | } |
| 424 | |
| 425 | auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>(); |
| 426 | |
| 427 | if (client == nullptr) { |
| 428 | return ErrorCode::INVAL; |
| 429 | } |
| 430 | |
| 431 | IpmiAsyncCallParams _params; |
| 432 | ORBIS_RET_ON_ERROR(uread(_params, (ptr<IpmiAsyncCallParams>)params)); |
| 433 | |
| 434 | if (_params.flags > 1) { |
| 435 | return ErrorCode::INVAL; |
| 436 | } |
| 437 | |
| 438 | std::lock_guard clientLock(client->mutex); |
| 439 | auto session = client->session; |
| 440 | |
| 441 | if (session == nullptr) { |
| 442 | return ErrorCode::INVAL; |
| 443 | } |
| 444 | |
| 445 | std::lock_guard sessionLock(session->mutex); |
| 446 | auto server = session->server; |
| 447 | |
| 448 | if (server == nullptr) { |
| 449 | return ErrorCode::INVAL; |
| 450 | } |
| 451 | |
| 452 | { |
| 453 | std::lock_guard serverLock(server->mutex); |
| 454 | |
| 455 | std::size_t inSize = 0; |
| 456 | for (auto &data : std::span(_params.pInData, _params.numInData)) { |
| 457 | inSize += data.size; |
| 458 | } |
| 459 | |
| 460 | auto size = sizeof(IpmiAsyncMessageHeader) + inSize + |