/* Command 0x80000008 */ static void _request_end(SifRpcRendPkt_t *request, void *data) { SifRpcClientData_t *client = request->client; if (request->cid == 0x8000000a) { if (client->end_function) client->end_function(client->end_param); } else if (request->cid == 0x80000009) { client->server = request->server; client->buff = request->buff; client->cbuff = request->cbuff; } if (client->hdr.sema_id >= 0) iSignalSema(client->hdr.sema_id); rpc_packet_free(client->hdr.pkt_addr); client->hdr.pkt_addr = NULL; }
/* Command 0x80000008 */ static void _request_end(SifRpcRendPkt_t *request, void *data) { SifRpcClientData_t *client = request->client; void *pkt_addr; SifRpcEndFunc_t volatile end_function; void * volatile end_param; u32 status; data = data; /* Interrupts may not be disabled on Linux 2.6. */ core_save_disable(&status); pkt_addr = client->hdr.pkt_addr; client->hdr.sema_id++; if (request->cid == 0x8000000a) { /* Response to RPC call. */ end_function = client->end_function; end_param = client->end_param; } else if (request->cid == 0x80000009) { /* Response to Bind call. */ client->server = request->server; client->buff = request->buff; client->cbuff = request->cbuff; /* Callback is not part of PS2SDK, but is required for linux. */ end_function = client->end_function; end_param = client->end_param; } else { /* No callback. */ end_function = NULL; end_param = NULL; } /* Set client free for use by next calls. */ client->hdr.pkt_addr = NULL; core_restore(status); #if defined(SBIOS_DEBUG) if (request->cid == 0x8000000a) { SifRpcCallPkt_t *call = pkt_addr; printf("request_end: client 0x%x cid 0x%x pkt_addr 0x%x rpc_number 0x%x\n", (uint32_t) client, (uint32_t) request->cid, (uint32_t) pkt_addr, call->rpc_number); } else if (request->cid == 0x80000009) { SifRpcBindPkt_t *bind = pkt_addr; printf("request_end: client 0x%x cid 0x%x pkt_addr 0x%x sid 0x%x\n", (uint32_t) client, (uint32_t) request->cid, (uint32_t) pkt_addr, bind->sid); } else { printf("request_end: client 0x%x cid 0x%x pkt_addr 0x%x\n", (uint32_t) client, (uint32_t) request->cid, (uint32_t) pkt_addr); } #endif if (end_function != NULL) { #if defined(SBIOS_DEBUG) printf("Calling 0x%x\n", (uint32_t) end_function); #endif end_function(end_param); } rpc_packet_free(pkt_addr); }
int SifCallRpc(SifRpcClientData_t *cd, int rpc_number, int mode, void *sendbuf, int ssize, void *recvbuf, int rsize, SifRpcEndFunc_t endfunc, void *efarg) { SifRpcCallPkt_t *call; u32 status; if ((((u32) recvbuf) & 0x0f) != 0) { /* This is fatal and will lead to write accesses on wrong memory addresses. */ printf("SifCallRpc 0x%x is not aligned (cd 0x%08x rpc nr 0x%x).\n", (uint32_t) recvbuf, (uint32_t) cd, rpc_number); return -E_LIB_INVALID_ARG; } call = (SifRpcCallPkt_t *)_rpc_get_packet(&_sif_rpc_data); if (!call) { return -E_SIF_PKT_ALLOC; } core_save_disable(&status); if (cd->hdr.pkt_addr != 0) { core_restore(status); rpc_packet_free(call); printf("SifCallRpc: Client 0x%x rpc_number 0x%x is already in use.\n", (uint32_t) cd, rpc_number); return -E_SIF_PKT_ALLOC; } cd->end_function = endfunc; cd->end_param = efarg; cd->hdr.pkt_addr = call; cd->hdr.rpc_id = call->rpc_id; cd->hdr.sema_id = 0; core_restore(status); call->rpc_number = rpc_number; call->send_size = ssize; call->receive = recvbuf; call->recv_size = rsize; call->rmode = 1; call->pkt_addr = call; call->client = cd; call->server = cd->server; if (!(mode & SIF_RPC_M_NOWBDC)) { if (ssize > 0) SifWriteBackDCache(sendbuf, ssize); if (rsize > 0) SifWriteBackDCache(recvbuf, rsize); } if (mode & SIF_RPC_M_NOWAIT) { if (!endfunc) call->rmode = 0; if (!SifSendCmd(0x8000000a, call, RPC_PACKET_SIZE, sendbuf, cd->buff, ssize)) { rpc_packet_free(call); return -E_SIF_PKT_SEND; } return 0; } /* The following code is normally not executed. */ if (!SifSendCmd(0x8000000a, call, RPC_PACKET_SIZE, sendbuf, cd->buff, ssize)) { rpc_packet_free(call); return -E_SIF_PKT_SEND; } core_save_disable(&status); while(cd->hdr.sema_id == 0) { /* Wait until something is received. */ core_restore(status); /* Preemption point. */ core_save_disable(&status); } cd->hdr.sema_id--; core_restore(status); return 0; }
int SifBindRpc(SifRpcClientData_t *cd, int sid, int mode, SifRpcEndFunc_t endfunc, void *efarg) { SifRpcBindPkt_t *bind; u32 status; bind = (SifRpcBindPkt_t *)_rpc_get_packet(&_sif_rpc_data); if (!bind) { return -E_SIF_PKT_ALLOC; } /* Callback is required by linux. */ core_save_disable(&status); if (cd->hdr.pkt_addr != NULL) { core_restore(status); rpc_packet_free(bind); printf("SifBindRpc: Client 0x%x sid 0x%x is already in use.\n", (uint32_t) cd, sid); return -E_SIF_PKT_ALLOC; } cd->end_function = endfunc; cd->end_param = efarg; cd->command = 0; cd->server = NULL; cd->hdr.pkt_addr = bind; cd->hdr.rpc_id = bind->rpc_id; cd->hdr.sema_id = 0; core_restore(status); bind->sid = sid; bind->pkt_addr = bind; bind->client = cd; if (mode & SIF_RPC_M_NOWAIT) { if (!SifSendCmd(0x80000009, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) { rpc_packet_free(bind); return -E_SIF_PKT_SEND; } return 0; } /* The following code is normally not executed. */ if (!SifSendCmd(0x80000009, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) { rpc_packet_free(bind); return -E_SIF_PKT_SEND; } core_save_disable(&status); while(cd->hdr.sema_id == 0) { /* Wait until something is received. */ core_restore(status); /* Preemption point. */ core_save_disable(&status); } cd->hdr.sema_id--; core_restore(status); return 0; }