예제 #1
0
void remote_ahci_write_blocks(ddf_fun_t *fun, void *iface, ipc_callid_t callid,
    ipc_call_t *call)
{
	const ahci_iface_t *ahci_iface = (ahci_iface_t *) iface;
	
	if (ahci_iface->read_blocks == NULL) {
		async_answer_0(callid, ENOTSUP);
		return;
	}
	
	size_t maxblock_size;
	unsigned int flags;
	
	ipc_callid_t cid;
	async_share_out_receive(&cid, &maxblock_size, &flags);
	
	void *buf;
	async_share_out_finalize(cid, &buf);
	
	const uint64_t blocknum =
	    (((uint64_t)(DEV_IPC_GET_ARG1(*call))) << 32) |
	    (((uint64_t)(DEV_IPC_GET_ARG2(*call))) & 0xffffffff);
	const size_t cnt = (size_t) DEV_IPC_GET_ARG3(*call);
	
	const int ret = ahci_iface->write_blocks(fun, blocknum, cnt, buf);
	
	async_answer_0(callid, ret);
}
예제 #2
0
static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	void *fs_va = NULL;
	ipc_callid_t callid;
	ipc_call_t call;
	sysarg_t method;
	size_t comm_size;
	unsigned int flags;
	int retval;
	uint64_t ba;
	size_t cnt;

	/* Answer the IPC_M_CONNECT_ME_TO call. */
	async_answer_0(iid, EOK);

	if (!async_share_out_receive(&callid, &comm_size, &flags)) {
		async_answer_0(callid, EHANGUP);
		return;
	}

	(void) async_share_out_finalize(callid, &fs_va);
	if (fs_va == AS_MAP_FAILED) {
		async_answer_0(callid, EHANGUP);
		return;
	}

	while (true) {
		callid = async_get_call(&call);
		method = IPC_GET_IMETHOD(call);
		
		if (!method) {
			/* The other side has hung up. */
			async_answer_0(callid, EOK);
			return;
		}
		
		switch (method) {
		case BD_READ_BLOCKS:
			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
			    IPC_GET_ARG2(call));
			cnt = IPC_GET_ARG3(call);
			if (cnt * block_size > comm_size) {
				retval = ELIMIT;
				break;
			}
			retval = file_bd_read_blocks(ba, cnt, fs_va);
			break;
		case BD_WRITE_BLOCKS:
			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
			    IPC_GET_ARG2(call));
			cnt = IPC_GET_ARG3(call);
			if (cnt * block_size > comm_size) {
				retval = ELIMIT;
				break;
			}
			retval = file_bd_write_blocks(ba, cnt, fs_va);
			break;
		case BD_GET_BLOCK_SIZE:
			async_answer_1(callid, EOK, block_size);
			continue;
		case BD_GET_NUM_BLOCKS:
			async_answer_2(callid, EOK, LOWER32(num_blocks),
			    UPPER32(num_blocks));
			continue;
		default:
			retval = EINVAL;
			break;
		}
		async_answer_0(callid, retval);
	}
}