Exemplo n.º 1
0
int ahci_write_prdt(struct hba_memory *abar, struct hba_port *port, struct ahci_device *dev, int slot, int offset, int length, addr_t virt_buffer)
{
	int num_entries = ((length-1) / PRDT_MAX_COUNT) + 1;
	struct hba_command_table *tbl = (struct hba_command_table *)(dev->ch[slot]);
	int i;
	struct hba_prdt_entry *prd;
	for(i=0;i<num_entries-1;i++)
	{
		/* TODO: do we need to do this? */
		addr_t phys_buffer;
		mm_virtual_getmap(virt_buffer, &phys_buffer, 0);
		prd = &tbl->prdt_entries[i+offset];
		prd->byte_count = PRDT_MAX_COUNT-1;
		prd->data_base_l = LOWER32(phys_buffer);
		prd->data_base_h = UPPER32(phys_buffer);
		prd->interrupt_on_complete=0;
		
		length -= PRDT_MAX_COUNT;
		virt_buffer += PRDT_MAX_COUNT;
	}
	addr_t phys_buffer;
	mm_virtual_getmap(virt_buffer, &phys_buffer, 0);
	prd = &tbl->prdt_entries[i+offset];
	prd->byte_count = length-1;
	prd->data_base_l = LOWER32(phys_buffer);
	prd->data_base_h = UPPER32(phys_buffer);
	prd->interrupt_on_complete=0;
	
	return num_entries;
}
Exemplo n.º 2
0
/** Compare a key with hashed item.
 *
 * @param key  Array of keys.
 * @param keys Must be less than or equal to 2.
 * @param item Pointer to a hash table item.
 *
 * @return Non-zero if the key matches the item, zero otherwise.
 *
 */
static int task_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
	assert(key);
	assert(keys <= 2);
	assert(item);
	
	hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link);
	
	if (keys == 2)
		return ((LOWER32(key[1]) == UPPER32(ht->id))
		    && (LOWER32(key[0]) == LOWER32(ht->id)));
	else
		return (LOWER32(key[0]) == LOWER32(ht->id));
}
Exemplo n.º 3
0
/** Process pending wait requests */
void process_pending_wait(void)
{
	task_exit_t texit;
	
loop:
	list_foreach(pending_wait, cur) {
		pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link);
		
		unsigned long keys[2] = {
			LOWER32(pr->id),
			UPPER32(pr->id)
		};
		
		link_t *link = hash_table_find(&task_hash_table, keys);
		if (!link)
			continue;
		
		hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link);
		if (!ht->finished)
			continue;
		
		if (!(pr->callid & IPC_CALLID_NOTIFICATION)) {
			texit = ht->have_rval ? TASK_EXIT_NORMAL :
			    TASK_EXIT_UNEXPECTED;
			ipc_answer_2(pr->callid, EOK, texit,
			    ht->retval);
		}
		
		hash_table_remove(&task_hash_table, keys, 2);
		list_remove(cur);
		free(pr);
		goto loop;
	}
Exemplo n.º 4
0
static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
{
	int rc = EOK;

	if (!IPC_GET_RETVAL(answer->data)) {
		/* The recipient authorized the change of state. */
		phone_t *recipient_phone;
		task_t *other_task_s;
		task_t *other_task_r;

		rc = phone_get(IPC_GET_ARG1(answer->data),
		    &recipient_phone);
		if (rc != EOK) {
			IPC_SET_RETVAL(answer->data, ENOENT);
			return ENOENT;
		}

		mutex_lock(&recipient_phone->lock);
		if (recipient_phone->state != IPC_PHONE_CONNECTED) {
			mutex_unlock(&recipient_phone->lock);
			IPC_SET_RETVAL(answer->data, EINVAL);
			return EINVAL;
		}

		other_task_r = recipient_phone->callee->task;
		other_task_s = (task_t *) IPC_GET_ARG5(*olddata);

		/*
		 * See if both the sender and the recipient meant the
		 * same third party task.
		 */
		if (other_task_r != other_task_s) {
			IPC_SET_RETVAL(answer->data, EINVAL);
			rc = EINVAL;
		} else {
			rc = event_task_notify_5(other_task_r,
			    EVENT_TASK_STATE_CHANGE, false,
			    IPC_GET_ARG1(*olddata),
			    IPC_GET_ARG2(*olddata),
			    IPC_GET_ARG3(*olddata),
			    LOWER32(olddata->task_id),
			    UPPER32(olddata->task_id));
			IPC_SET_RETVAL(answer->data, rc);
		}

		mutex_unlock(&recipient_phone->lock);
	}

	return rc;
}
Exemplo n.º 5
0
int bd_read_blocks(bd_t *bd, aoff64_t ba, size_t cnt, void *data, size_t size)
{
	async_exch_t *exch = async_exchange_begin(bd->sess);

	ipc_call_t answer;
	aid_t req = async_send_3(exch, BD_READ_BLOCKS, LOWER32(ba),
	    UPPER32(ba), cnt, &answer);
	int rc = async_data_read_start(exch, data, size);
	async_exchange_end(exch);

	if (rc != EOK) {
		async_forget(req);
		return rc;
	}

	sysarg_t retval;
	async_wait_for(req, &retval);

	if (retval != EOK)
		return retval;

	return EOK;
}
Exemplo n.º 6
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);
	}
}
Exemplo n.º 7
0
/** Compute hash index into task hash table.
 *
 * @param key Pointer keys. However, only the first key (i.e. truncated task
 *            number) is used to compute the hash index.
 *
 * @return Hash index corresponding to key[0].
 *
 */
static hash_index_t task_hash(unsigned long key[])
{
	assert(key);
	return (LOWER32(key[0]) % TASK_HASH_TABLE_CHAINS);
}