Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
/* 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);

}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}