Example #1
0
int get_match_score(driver_t *drv, dev_node_t *dev)
{
	link_t *drv_head = &drv->match_ids.ids.head;
	link_t *dev_head = &dev->pfun->match_ids.ids.head;
	
	if (list_empty(&drv->match_ids.ids) ||
	    list_empty(&dev->pfun->match_ids.ids)) {
		return 0;
	}
	
	/*
	 * Go through all pairs, return the highest score obtained.
	 */
	int highest_score = 0;
	
	link_t *drv_link = drv->match_ids.ids.head.next;
	while (drv_link != drv_head) {
		link_t *dev_link = dev_head->next;
		while (dev_link != dev_head) {
			match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link);
			match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link);
			
			int score = compute_match_score(drv_id, dev_id);
			if (score > highest_score) {
				highest_score = score;
			}

			dev_link = dev_link->next;
		}
		
		drv_link = drv_link->next;
	}
	
	return highest_score;
}
Example #2
0
/** Get next ready segment from incoming queue.
 *
 * Return the segment with the earliest sequence number if it is ready.
 * A segment is ready if its SEG.SEQ is earlier or equal to RCV.NXT.
 *
 * @param iqueue	Incoming queue
 * @param seg		Place to store pointer to segment
 * @return		EOK on success, ENOENT if no segment is ready
 */
int tcp_iqueue_get_ready_seg(tcp_iqueue_t *iqueue, tcp_segment_t **seg)
{
	tcp_iqueue_entry_t *iqe;
	link_t *link;

	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_get_ready_seg()");

	link = list_first(&iqueue->list);
	if (link == NULL) {
		log_msg(LOG_DEFAULT, LVL_DEBUG, "iqueue is empty");
		return ENOENT;
	}

	iqe = list_get_instance(link, tcp_iqueue_entry_t, link);

	while (!seq_no_segment_acceptable(iqueue->conn, iqe->seg)) {
		log_msg(LOG_DEFAULT, LVL_DEBUG, "Skipping unacceptable segment (RCV.NXT=%"
		    PRIu32 ", RCV.NXT+RCV.WND=%" PRIu32 ", SEG.SEQ=%" PRIu32
		    ", SEG.LEN=%" PRIu32 ")", iqueue->conn->rcv_nxt,
		    iqueue->conn->rcv_nxt + iqueue->conn->rcv_wnd,
		    iqe->seg->seq, iqe->seg->len);

		list_remove(&iqe->link);
		tcp_segment_delete(iqe->seg);

         	link = list_first(&iqueue->list);
		if (link == NULL) {
			log_msg(LOG_DEFAULT, LVL_DEBUG, "iqueue is empty");
			return ENOENT;
		}

		iqe = list_get_instance(link, tcp_iqueue_entry_t, link);
	}

	/* Do not return segments that are not ready for processing */
	if (!seq_no_segment_ready(iqueue->conn, iqe->seg)) {
		log_msg(LOG_DEFAULT, LVL_DEBUG, "Next segment not ready: SEG.SEQ=%u, "
		    "RCV.NXT=%u, SEG.LEN=%u", iqe->seg->seq,
		    iqueue->conn->rcv_nxt, iqe->seg->len);
		return ENOENT;
	}

	log_msg(LOG_DEFAULT, LVL_DEBUG, "Returning ready segment %p", iqe->seg);
	list_remove(&iqe->link);
	*seg = iqe->seg;
	free(iqe);

	return EOK;
}
Example #3
0
/** Cleanup the table of open files. */
static void vfs_files_done(vfs_client_data_t *vfs_data)
{
	int i;

	if (!vfs_data->files)
		return;

	for (i = 0; i < MAX_OPEN_FILES; i++) {
		if (vfs_data->files[i])
			(void) _vfs_fd_free(vfs_data, i);
	}
	
	free(vfs_data->files);

	while (!list_empty(&vfs_data->passed_handles)) {
		link_t *lnk;
		vfs_boxed_handle_t *bh;
		
		lnk = list_first(&vfs_data->passed_handles);
		list_remove(lnk);

		bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
		free(bh);
	}
}
Example #4
0
/** Insert segment into incoming queue.
 *
 * @param iqueue	Incoming queue
 * @param seg		Segment
 */
void tcp_iqueue_insert_seg(tcp_iqueue_t *iqueue, tcp_segment_t *seg)
{
	tcp_iqueue_entry_t *iqe;
	tcp_iqueue_entry_t *qe;
	link_t *link;
	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_iqueue_insert_seg()");

	iqe = calloc(1, sizeof(tcp_iqueue_entry_t));
	if (iqe == NULL) {
		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating IQE.");
		return;
	}

	iqe->seg = seg;

	/* Sort by sequence number */

	link = list_first(&iqueue->list);
	while (link != NULL) {
		qe = list_get_instance(link,
		    tcp_iqueue_entry_t, link);

		if (seq_no_seg_cmp(iqueue->conn, iqe->seg, qe->seg) >= 0)
			break;
	}

	if (link != NULL)
		list_insert_before(&iqe->link, &qe->link);
	else
		list_append(&iqe->link, &iqueue->list);
}
Example #5
0
void __stdio_done(void)
{
	while (!list_empty(&files)) {
		FILE *file = list_get_instance(list_first(&files), FILE, link);
		fclose(file);
	}
}
Example #6
0
/** Get a received message.
 *
 * Pull one message from the association's receive queue.
 */
int udp_assoc_recv(udp_assoc_t *assoc, udp_msg_t **msg, udp_sock_t *fsock)
{
	link_t *link;
	udp_rcv_queue_entry_t *rqe;

	log_msg(LVL_DEBUG, "udp_assoc_recv()");

	fibril_mutex_lock(&assoc->lock);
	while (list_empty(&assoc->rcv_queue)) {
		log_msg(LVL_DEBUG, "udp_assoc_recv() - waiting");
		fibril_condvar_wait(&assoc->rcv_queue_cv, &assoc->lock);
	}

	log_msg(LVL_DEBUG, "udp_assoc_recv() - got a message");
	link = list_first(&assoc->rcv_queue);
	rqe = list_get_instance(link, udp_rcv_queue_entry_t, link);
	list_remove(link);
	fibril_mutex_unlock(&assoc->lock);

	*msg = rqe->msg;
	*fsock = rqe->sp.foreign;
	free(rqe);

	return EOK;
}
Example #7
0
/** Register clonable service.
 *
 * @param service Service to be registered.
 * @param phone   Phone to be used for connections to the service.
 * @param call    Pointer to call structure.
 *
 */
void register_clonable(sysarg_t service, sysarg_t phone, ipc_call_t *call,
    ipc_callid_t callid)
{
	link_t *req_link;

	req_link = list_first(&cs_req);
	if (req_link == NULL) {
		/* There was no pending connection request. */
		printf("%s: Unexpected clonable server.\n", NAME);
		ipc_answer_0(callid, EBUSY);
		return;
	}
	
	cs_req_t *csr = list_get_instance(req_link, cs_req_t, link);
	list_remove(req_link);
	
	/* Currently we can only handle a single type of clonable service. */
	assert(csr->service == SERVICE_LOAD);
	
	ipc_answer_0(callid, EOK);
	
	ipc_forward_fast(csr->callid, phone, IPC_GET_ARG2(csr->call),
	    IPC_GET_ARG3(csr->call), 0, IPC_FF_NONE);
	
	free(csr);
	ipc_hangup(phone);
}
Example #8
0
/** Allocate frame
 *
 *  @param nic_data 	The NIC driver data
 *  @param size	        Frame size in bytes
 *  @return pointer to allocated frame if success, NULL otherwise
 */
nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)
{
	nic_frame_t *frame;
	fibril_mutex_lock(&nic_globals.lock);
	if (nic_globals.frame_cache_size > 0) {
		link_t *first = list_first(&nic_globals.frame_cache);
		list_remove(first);
		nic_globals.frame_cache_size--;
		frame = list_get_instance(first, nic_frame_t, link);
		fibril_mutex_unlock(&nic_globals.lock);
	} else {
		fibril_mutex_unlock(&nic_globals.lock);
		frame = malloc(sizeof(nic_frame_t));
		if (!frame)
			return NULL;
		
		link_initialize(&frame->link);
	}

	frame->data = malloc(size);
	if (frame->data == NULL) {
		free(frame);
		return NULL;
	}

	frame->size = size;
	return frame;
}
Example #9
0
/** Try to find a command beginning with prefix */
const char *cmdtab_enum(const char *name, const char **h, void **ctx)
{
	link_t **startpos = (link_t**) ctx;
	size_t namelen = str_length(name);
	
	spinlock_lock(&cmd_lock);
	
	if (*startpos == NULL)
		*startpos = cmd_list.head.next;
	
	for (; *startpos != &cmd_list.head; *startpos = (*startpos)->next) {
		cmd_info_t *hlp = list_get_instance(*startpos, cmd_info_t, link);
		
		const char *curname = hlp->name;
		if (str_length(curname) < namelen)
			continue;
		
		if (str_lcmp(curname, name, namelen) == 0) {
			*startpos = (*startpos)->next;
			if (h)
				*h = hlp->description;
			
			spinlock_unlock(&cmd_lock);
			return (curname + str_lsize(curname, namelen));
		}
	}
	
	spinlock_unlock(&cmd_lock);
	return NULL;
}
Example #10
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;
	}
Example #11
0
	/* For each keyboard device */
	list_foreach(kbd_devs, kdev_link) {
		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
		    kbd_devs);
		
		/* Yield port */
		if (kdev->port_ops != NULL)
			(*kdev->port_ops->yield)();
	}
Example #12
0
static slab_cache_t * slab_cache_alloc()
{
    slab_t *slab;
    void *obj;
    u32_t *p;

    DBG("%s\n", __FUNCTION__);

    if (list_empty(&slab_cache_cache.partial_slabs))
    {
//    spinlock_unlock(&cache->slablock);
//    slab = slab_create();

        void *data;
        unsigned int i;

        data = (void*)(PA2KA(alloc_page()));
        if (!data) {
            return NULL;
        }

        slab = (slab_t*)((u32_t)data + PAGE_SIZE - sizeof(slab_t));

    /* Fill in slab structures */
        frame_set_parent(ADDR2PFN(KA2PA(data)), slab);

        slab->start = data;
        slab->available = slab_cache_cache.objects;
        slab->nextavail = (void*)data;
        slab->cache = &slab_cache_cache;

        for (i = 0,p = (u32_t*)slab->start;i < slab_cache_cache.objects; i++)
        {
            *p = (u32_t)p+slab_cache_cache.size;
            p = (u32_t*)((u32_t)p+slab_cache_cache.size);
        };


        atomic_inc(&slab_cache_cache.allocated_slabs);
//    spinlock_lock(&cache->slablock);
    }
    else {
        slab = list_get_instance(slab_cache_cache.partial_slabs.next, slab_t, link);
        list_remove(&slab->link);
    }
    obj = slab->nextavail;
    slab->nextavail = *((void**)obj);
    slab->available--;

    if (!slab->available)
        list_prepend(&slab->link, &slab_cache_cache.full_slabs);
    else
        list_prepend(&slab->link, &slab_cache_cache.partial_slabs);

//  spinlock_unlock(&cache->slablock);

    return (slab_cache_t*)obj;
}
Example #13
0
/** Disconnects all phones connected to an answerbox.
 *
 * @param box        Answerbox to disconnect phones from.
 * @param notify_box If true, the answerbox will get a hangup message for
 *                   each disconnected phone.
 *
 */
void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box)
{
	phone_t *phone;
	DEADLOCK_PROBE_INIT(p_phonelck);
	
	call_t *call = notify_box ? ipc_call_alloc(0) : NULL;
	
	/* Disconnect all phones connected to our answerbox */
restart_phones:
	irq_spinlock_lock(&box->lock, true);
	while (!list_empty(&box->connected_phones)) {
		phone = list_get_instance(list_first(&box->connected_phones),
		    phone_t, link);
		if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
			irq_spinlock_unlock(&box->lock, true);
			DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
			goto restart_phones;
		}
		
		/* Disconnect phone */
		ASSERT(phone->state == IPC_PHONE_CONNECTED);
		
		list_remove(&phone->link);
		phone->state = IPC_PHONE_SLAMMED;
		
		if (notify_box) {
			mutex_unlock(&phone->lock);
			irq_spinlock_unlock(&box->lock, true);

			// FIXME: phone can become deallocated at any time now

			/*
			 * Send one message to the answerbox for each
			 * phone. Used to make sure the kbox thread
			 * wakes up after the last phone has been
			 * disconnected.
			 */
			IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
			call->request_method = IPC_M_PHONE_HUNGUP;
			call->flags |= IPC_CALL_DISCARD_ANSWER;
			_ipc_call(phone, box, call);
			
			/* Allocate another call in advance */
			call = ipc_call_alloc(0);
			
			/* Must start again */
			goto restart_phones;
		}
		
		mutex_unlock(&phone->lock);
	}
	
	irq_spinlock_unlock(&box->lock, true);
	
	/* Free unused call */
	if (call)
		ipc_call_free(call);
}
Example #14
0
/** Add endpoint to the list and queue.
 *
 * @param[in] instance List to use.
 * @param[in] endpoint Endpoint to add.
 *
 * The endpoint is added to the end of the list and queue.
 */
void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep)
{
	assert(instance);
	assert(ep);
	usb_log_debug2("Queue %s: Adding endpoint(%p).\n", instance->name, ep);

	fibril_mutex_lock(&instance->guard);

	ed_t *last_ed = NULL;
	/* Add to the hardware queue. */
	if (list_empty(&instance->endpoint_list)) {
		/* There are no active EDs */
		last_ed = instance->list_head;
	} else {
		/* There are active EDs, get the last one */
		ohci_endpoint_t *last = list_get_instance(
		    list_last(&instance->endpoint_list), ohci_endpoint_t, link);
		last_ed = last->ed;
	}
	/* Keep link */
	ep->ed->next = last_ed->next;
	/* Make sure ED is written to the memory */
	write_barrier();

	/* Add ed to the hw queue */
	ed_append_ed(last_ed, ep->ed);
	/* Make sure ED is updated */
	write_barrier();

	/* Add to the sw list */
	list_append(&ep->link, &instance->endpoint_list);

	ohci_endpoint_t *first = list_get_instance(
	    list_first(&instance->endpoint_list), ohci_endpoint_t, link);
	usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n",
		ep, instance->name, first, first->ed);
	if (last_ed == instance->list_head) {
		usb_log_debug2("%s head ED(%p-0x%0" PRIx32 "): %x:%x:%x:%x.\n",
		    instance->name, last_ed, instance->list_head_pa,
		    last_ed->status, last_ed->td_tail, last_ed->td_head,
		    last_ed->next);
	}
	fibril_mutex_unlock(&instance->guard);
}
Example #15
0
static void ipc_forget_all_active_calls(void)
{
	call_t *call;

restart:
	spinlock_lock(&TASK->active_calls_lock);
	if (list_empty(&TASK->active_calls)) {
		/*
		 * We are done, there are no more active calls.
		 * Nota bene: there may still be answers waiting for pick up.
		 */
		spinlock_unlock(&TASK->active_calls_lock);	
		return;	
	}
	
	call = list_get_instance(list_first(&TASK->active_calls), call_t,
	    ta_link);

	if (!spinlock_trylock(&call->forget_lock)) {
		/*
		 * Avoid deadlock and let async_answer() or
		 *  _ipc_answer_free_call() win the race to dequeue the first
		 * call on the list.
		 */
		spinlock_unlock(&TASK->active_calls_lock);	
		goto restart;
	}

	/*
	 * Forget the call and donate it to the task which holds up the answer.
	 */

	call->forget = true;
	call->sender = NULL;
	list_remove(&call->ta_link);

	/*
	 * The call may be freed by _ipc_answer_free_call() before we are done
	 * with it; to avoid working with a destroyed call_t structure, we
	 * must hold a reference to it.
	 */
	ipc_call_hold(call);

	spinlock_unlock(&call->forget_lock);
	spinlock_unlock(&TASK->active_calls_lock);

	atomic_dec(&call->caller_phone->active_calls);

	SYSIPC_OP(request_forget, call);

	ipc_call_release(call);

	goto restart;
}
Example #16
0
static unused_t *unused_find(service_id_t service_id, bool lock)
{
	unused_t *u;

	if (lock)
		fibril_mutex_lock(&unused_lock);

	list_foreach(unused_list, l) {
		u = list_get_instance(l, unused_t, link);
		if (u->service_id == service_id) 
			return u;
	}
Example #17
0
static int fat_node_fini_by_service_id(service_id_t service_id)
{
	fat_node_t *nodep;
	int rc;

	/*
	 * We are called from fat_unmounted() and assume that there are already
	 * no nodes belonging to this instance with non-zero refcount. Therefore
	 * it is sufficient to clean up only the FAT free node list.
	 */

restart:
	fibril_mutex_lock(&ffn_mutex);
	list_foreach(ffn_list, lnk) {
		nodep = list_get_instance(lnk, fat_node_t, ffn_link);
		if (!fibril_mutex_trylock(&nodep->lock)) {
			fibril_mutex_unlock(&ffn_mutex);
			goto restart;
		}
		if (!fibril_mutex_trylock(&nodep->idx->lock)) {
			fibril_mutex_unlock(&nodep->lock);
			fibril_mutex_unlock(&ffn_mutex);
			goto restart;
		}
		if (nodep->idx->service_id != service_id) {
			fibril_mutex_unlock(&nodep->idx->lock);
			fibril_mutex_unlock(&nodep->lock);
			continue;
		}

		list_remove(&nodep->ffn_link);
		fibril_mutex_unlock(&ffn_mutex);

		/*
		 * We can unlock the node and its index structure because we are
		 * the last player on this playground and VFS is preventing new
		 * players from entering.
		 */
		fibril_mutex_unlock(&nodep->idx->lock);
		fibril_mutex_unlock(&nodep->lock);

		if (nodep->dirty) {
			rc = fat_node_sync(nodep);
			if (rc != EOK)
				return rc;
		}
		nodep->idx->nodep = NULL;
		free(nodep->bp);
		free(nodep);

		/* Need to restart because we changed ffn_list. */
		goto restart;
	}
Example #18
0
void sig_connect(signal_t *signal, widget_t *widget, slot_t slot)
{
	fibril_rwlock_write_lock(&connection_guard);

	signal_node_t *sig_node = NULL;
	list_foreach(connection_list, link) {
		signal_node_t *cur = list_get_instance(link, signal_node_t, link);
		if (cur->signal == signal) {
			sig_node = cur;
			break;
		}
	}
Example #19
0
/**
 * Some NICs can receive multiple frames during single interrupt. These can
 * send them in whole list of frames (actually nic_frame_t structures), then
 * the list is deallocated and each frame is passed to the
 * nic_received_packet function.
 *
 * @param nic_data
 * @param frames		List of received frames
 */
void nic_received_frame_list(nic_t *nic_data, nic_frame_list_t *frames)
{
	if (frames == NULL)
		return;
	while (!list_empty(frames)) {
		nic_frame_t *frame =
			list_get_instance(list_first(frames), nic_frame_t, link);

		list_remove(&frame->link);
		nic_received_frame(nic_data, frame);
	}
	nic_driver_release_frame_list(frames);
}
Example #20
0
static void srv_yield(ipc_callid_t iid, ipc_call_t *icall)
{
	int ret = EOK;
	
	list_foreach(outdevs, link) {
		outdev_t *dev = list_get_instance(link, outdev_t, link);
		
		assert(dev->ops.yield);
		
		int rc = dev->ops.yield(dev);
		if (rc != EOK)
			ret = rc;
	}
Example #21
0
/** List supported commands.
 *
 * @param argv Argument vector.
 *
 * @return 0 on failure, 1 on success.
 */
int cmd_help(cmd_arg_t *argv)
{
	spinlock_lock(&cmd_lock);
	
	size_t len = 0;
	list_foreach(cmd_list, cur) {
		cmd_info_t *hlp;
		hlp = list_get_instance(cur, cmd_info_t, link);
		
		spinlock_lock(&hlp->lock);
		if (str_length(hlp->name) > len)
			len = str_length(hlp->name);
		spinlock_unlock(&hlp->lock);
	}
Example #22
0
/** Destroy association structure.
 *
 * Association structure should be destroyed when the folowing conditions
 * are met:
 * (1) user has deleted the association
 * (2) nobody is holding references to the association
 *
 * This happens when @a assoc->refcnt is zero as we count (1)
 * as an extra reference.
 *
 * @param assoc		Association
 */
static void udp_assoc_free(udp_assoc_t *assoc)
{
	log_msg(LVL_DEBUG, "%s: udp_assoc_free(%p)", assoc->name, assoc);

	while (!list_empty(&assoc->rcv_queue)) {
		link_t *link = list_first(&assoc->rcv_queue);
		udp_rcv_queue_entry_t *rqe = list_get_instance(link,
		    udp_rcv_queue_entry_t, link);
		list_remove(link);

		udp_msg_delete(rqe->msg);
		free(rqe);
	}

	free(assoc);
}
Example #23
0
/** Receive queue handler fibril. */
static int tcp_rqueue_fibril(void *arg)
{
	link_t *link;
	tcp_rqueue_entry_t *rqe;

	log_msg(LVL_DEBUG, "tcp_rqueue_fibril()");

	while (true) {
		link = prodcons_consume(&rqueue);
		rqe = list_get_instance(link, tcp_rqueue_entry_t, link);

		tcp_as_segment_arrived(&rqe->sp, rqe->seg);
	}

	/* Not reached */
	return 0;
}
Example #24
0
int vfs_wait_handle_internal(void)
{
	vfs_client_data_t *vfs_data = VFS_DATA;	
	int fd;
	
	fibril_mutex_lock(&vfs_data->lock);
	while (list_empty(&vfs_data->passed_handles))
		fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock);
	link_t *lnk = list_first(&vfs_data->passed_handles);
	list_remove(lnk);
	fibril_mutex_unlock(&vfs_data->lock);

	vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
	fd = bh->handle;
	free(bh);

	return fd;
}
Example #25
0
static int inet_link_check_new(void)
{
	bool already_known;
	category_id_t iplink_cat;
	service_id_t *svcs;
	size_t count, i;
	int rc;

	fibril_mutex_lock(&inet_discovery_lock);

	rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
	if (rc != EOK) {
		log_msg(LVL_ERROR, "Failed resolving category 'iplink'.");
		fibril_mutex_unlock(&inet_discovery_lock);
		return ENOENT;
	}

	rc = loc_category_get_svcs(iplink_cat, &svcs, &count);
	if (rc != EOK) {
		log_msg(LVL_ERROR, "Failed getting list of IP links.");
		fibril_mutex_unlock(&inet_discovery_lock);
		return EIO;
	}

	for (i = 0; i < count; i++) {
		already_known = false;

		list_foreach(inet_link_list, ilink_link) {
			inet_link_t *ilink = list_get_instance(ilink_link,
			    inet_link_t, link_list);
			if (ilink->svc_id == svcs[i]) {
				already_known = true;
				break;
			}
		}

		if (!already_known) {
			log_msg(LVL_DEBUG, "Found IP link '%lu'",
			    (unsigned long) svcs[i]);
			rc = inet_link_open(svcs[i]);
			if (rc != EOK)
				log_msg(LVL_ERROR, "Could not open IP link.");
		}
	}
Example #26
0
/** Get instance from internal table by service_id.
 *
 * @param service_id Device identifier
 * @param inst       Output instance if successful operation
 *
 * @return Error code
 *
 */
int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
{
	fibril_mutex_lock(&instance_list_mutex);
	
	if (list_empty(&instance_list)) {
		fibril_mutex_unlock(&instance_list_mutex);
		return EINVAL;
	}
	
	list_foreach(instance_list, link) {
		ext4fs_instance_t *tmp =
		    list_get_instance(link, ext4fs_instance_t, link);
		
		if (tmp->service_id == service_id) {
			*inst = tmp;
			fibril_mutex_unlock(&instance_list_mutex);
			return EOK;
		}
	}
Example #27
0
/** Find address object matching address @a addr.
 *
 * @param addr	Address
 * @oaram find	iaf_net to find network (using mask),
 *		iaf_addr to find local address (exact match)
 */
inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr, inet_addrobj_find_t find)
{
	uint32_t mask;

	log_msg(LVL_DEBUG, "inet_addrobj_find(%x)", (unsigned)addr->ipv4);

	fibril_mutex_lock(&addr_list_lock);

	list_foreach(addr_list, link) {
		inet_addrobj_t *naddr = list_get_instance(link,
		    inet_addrobj_t, addr_list);

		mask = inet_netmask(naddr->naddr.bits);
		if ((naddr->naddr.ipv4 & mask) == (addr->ipv4 & mask)) {
			fibril_mutex_unlock(&addr_list_lock);
			log_msg(LVL_DEBUG, "inet_addrobj_find: found %p",
			    naddr);
			return naddr;
		}
	}
Example #28
0
static void nodes_remove_callback(link_t *item)
{
	tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
	    nh_link);

	while (!list_empty(&nodep->cs_list)) {
		tmpfs_dentry_t *dentryp = list_get_instance(
		    list_first(&nodep->cs_list), tmpfs_dentry_t, link);

		assert(nodep->type == TMPFS_DIRECTORY);
		list_remove(&dentryp->link);
		free(dentryp);
	}

	if (nodep->data) {
		assert(nodep->type == TMPFS_FILE);
		free(nodep->data);
	}
	free(nodep->bp);
	free(nodep);
}
static void _fibril_condvar_wakeup_common(fibril_condvar_t *fcv, bool once)
{
	link_t *tmp;
	awaiter_t *wdp;

	futex_down(&async_futex);
	while (!list_empty(&fcv->waiters)) {
		tmp = list_first(&fcv->waiters);
		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
		list_remove(&wdp->wu_event.link);
		wdp->wu_event.inlist = false;
		if (!wdp->active) {
			wdp->active = true;
			fibril_add_ready(wdp->fid);
			optimize_execution_power();
			if (once)
				break;
		}
	}
	futex_up(&async_futex);
}
Example #30
0
/** Compare hash table element with a key.
 *
 * There are two things to note about this function.
 * First, it is used for the less complex architecture setup
 * in which there are not too many interrupt numbers (i.e. inr's)
 * to arrange the hash table so that collisions occur only
 * among same inrs of different devnos. So the explicit check
 * for inr match is not done.
 * Second, if devno is -1, the second key (i.e. devno) is not
 * used for the match and the result of the claim() function
 * is used instead.
 *
 * This function assumes interrupts are already disabled.
 *
 * @param key  Keys (i.e. inr and devno).
 * @param keys This is 2.
 * @param item The item to compare the key with.
 *
 * @return True on match or false otherwise.
 *
 */
bool irq_lin_compare(sysarg_t key[], size_t keys, link_t *item)
{
	irq_t *irq = list_get_instance(item, irq_t, link);
	devno_t devno = (devno_t) key[KEY_DEVNO];
	bool rv;
	
	irq_spinlock_lock(&irq->lock, false);
	if (devno == -1) {
		/* Invoked by irq_dispatch_and_lock() */
		rv = (irq->claim(irq) == IRQ_ACCEPT);
	} else {
		/* Invoked by irq_find_and_lock() */
		rv = (irq->devno == devno);
	}
	
	/* unlock only on non-match */
	if (!rv)
		irq_spinlock_unlock(&irq->lock, false);
	
	return rv;
}