static int vhc_virtdev_plug_generic(vhc_data_t *vhc, async_sess_t *sess, usbvirt_device_t *virtdev, uintptr_t *handle, bool connect, usb_address_t address) { vhc_virtdev_t *dev = vhc_virtdev_create(); if (dev == NULL) { return ENOMEM; } dev->dev_sess = sess; dev->dev_local = virtdev; dev->address = address; fibril_mutex_lock(&vhc->guard); list_append(&dev->link, &vhc->devices); fibril_mutex_unlock(&vhc->guard); fid_t fibril = fibril_create(vhc_transfer_queue_processor, dev); if (fibril == 0) { free(dev); return ENOMEM; } fibril_add_ready(fibril); if (handle != NULL) { *handle = (uintptr_t) dev; } if (connect) { // FIXME: check status (void) virthub_connect_device(&vhc->hub, dev); } return EOK; }
/** Create new timer. * * @return New timer on success, @c NULL if out of memory. */ fibril_timer_t *fibril_timer_create(void) { fid_t fid; fibril_timer_t *timer; timer = calloc(1, sizeof(fibril_timer_t)); if (timer == NULL) return NULL; fid = fibril_create(fibril_timer_func, (void *) timer); if (fid == 0) { free(timer); return NULL; } fibril_mutex_initialize(&timer->lock); fibril_condvar_initialize(&timer->cv); timer->fibril = fid; timer->state = fts_not_set; fibril_add_ready(fid); return timer; }
static int test2_dev_add(ddf_dev_t *dev) { test2_t *test2; ddf_msg(LVL_DEBUG, "test2_dev_add(name=\"%s\", handle=%d)", dev->name, (int) dev->handle); test2 = ddf_dev_data_alloc(dev, sizeof(test2_t)); if (test2 == NULL) { ddf_msg(LVL_ERROR, "Failed allocating soft state."); return ENOMEM; } test2->dev = dev; if (str_cmp(dev->name, "child") != 0) { fid_t postpone = fibril_create(plug_unplug, test2); if (postpone == 0) { ddf_msg(LVL_ERROR, "fibril_create() failed."); return ENOMEM; } fibril_add_ready(postpone); } else { (void) register_fun_verbose(dev, "child without available driver", "ERROR", "non-existent.match.id", 10, &test2->fun_err); } return EOK; }
/** Start receive queue handler fibril. */ void tcp_rqueue_fibril_start(void) { fid_t fid; log_msg(LVL_DEBUG, "tcp_rqueue_fibril_start()"); fid = fibril_create(tcp_rqueue_fibril, NULL); if (fid == 0) { log_msg(LVL_ERROR, "Failed creating rqueue fibril."); return; } fibril_add_ready(fid); }
/** Initialize keyboard driver structure. * * @param kbd Keyboard driver structure to initialize. * @param dev DDF device structure. * * Connects to parent, creates keyboard function, starts polling fibril. * */ int at_kbd_init(at_kbd_t *kbd, ddf_dev_t *dev) { assert(kbd); assert(dev); kbd->client_sess = NULL; kbd->parent_sess = ddf_dev_parent_sess_create(dev); if (!kbd->parent_sess) { ddf_msg(LVL_ERROR, "Failed creating parent session."); return EIO; } kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd"); if (!kbd->kbd_fun) { ddf_msg(LVL_ERROR, "Failed creating function 'kbd'."); return ENOMEM; } ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops); int ret = ddf_fun_bind(kbd->kbd_fun); if (ret != EOK) { ddf_msg(LVL_ERROR, "Failed binding function 'kbd'."); ddf_fun_destroy(kbd->kbd_fun); return EEXIST; } ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard"); if (ret != EOK) { ddf_msg(LVL_ERROR, "Failed adding function 'kbd' to category " "'keyboard'."); ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } kbd->polling_fibril = fibril_create(polling, kbd); if (!kbd->polling_fibril) { ddf_msg(LVL_ERROR, "Failed creating polling fibril."); ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } fibril_add_ready(kbd->polling_fibril); return EOK; }
/** Initialize UHCI hc driver structure * * @param[in] instance Memory place to initialize. * @param[in] regs Address of I/O control registers. * @param[in] reg_size Size of I/O control registers. * @param[in] interrupts True if hw interrupts should be used. * @return Error code. * @note Should be called only once on any structure. * * Initializes memory structures, starts up hw, and launches debugger and * interrupt fibrils. */ int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts) { assert(reg_size >= sizeof(uhci_regs_t)); int ret; #define CHECK_RET_RETURN(ret, message...) \ if (ret != EOK) { \ usb_log_error(message); \ return ret; \ } else (void) 0 instance->hw_interrupts = interrupts; instance->hw_failures = 0; /* allow access to hc control registers */ uhci_regs_t *io; ret = pio_enable(regs, reg_size, (void **)&io); CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n", io, str_error(ret)); instance->registers = io; usb_log_debug( "Device registers at %p (%zuB) accessible.\n", io, reg_size); ret = hc_init_mem_structures(instance); CHECK_RET_RETURN(ret, "Failed to initialize UHCI memory structures: %s.\n", str_error(ret)); #undef CHECK_RET_RETURN hcd_init(&instance->generic, USB_SPEED_FULL, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); instance->generic.private_data = instance; instance->generic.schedule = hc_schedule; instance->generic.ep_add_hook = NULL; hc_init_hw(instance); if (!interrupts) { instance->interrupt_emulator = fibril_create(hc_interrupt_emulator, instance); fibril_add_ready(instance->interrupt_emulator); } (void)hc_debug_checker; return EOK; }
/** Fibril for each accepted socket. * * @param arg Corresponding @c telnet_user_t structure. */ static int network_user_fibril(void *arg) { telnet_user_t *user = arg; int rc = loc_service_register(user->service_name, &user->service_id); if (rc != EOK) { telnet_user_error(user, "Unable to register %s with loc: %s.", user->service_name, str_error(rc)); return EOK; } telnet_user_log(user, "Service %s registerd with id %" PRIun ".", user->service_name, user->service_id); fid_t spawn_fibril = fibril_create(spawn_task_fibril, user); assert(spawn_fibril); fibril_add_ready(spawn_fibril); /* Wait for all clients to exit. */ fibril_mutex_lock(&user->guard); while (!user_can_be_destroyed_no_lock(user)) { if (user->task_finished) { closesocket(user->socket); user->socket_closed = true; user->srvs.aborted = true; continue; } else if (user->socket_closed) { if (user->task_id != 0) { task_kill(user->task_id); } } fibril_condvar_wait_timeout(&user->refcount_cv, &user->guard, 1000); } fibril_mutex_unlock(&user->guard); rc = loc_service_unregister(user->service_id); if (rc != EOK) { telnet_user_error(user, "Unable to unregister %s from loc: %s (ignored).", user->service_name, str_error(rc)); } telnet_user_log(user, "Destroying..."); telnet_user_destroy(user); return EOK; }
/** Starts software periodic polling * * Reset to new period if the original period was running * * @param nic_data Nic data structure */ void nic_sw_period_start(nic_t *nic_data) { /* Create the fibril if it is not crated */ if (nic_data->sw_poll_info.fibril == 0) { nic_data->sw_poll_info.fibril = fibril_create(period_fibril_fun, nic_data); nic_data->sw_poll_info.running = 0; nic_data->sw_poll_info.run = 0; /* Start fibril */ fibril_add_ready(nic_data->sw_poll_info.fibril); } /* Inform fibril about running with new period */ nic_data->sw_poll_info.run = (nic_data->sw_poll_info.run + 1) % 100; nic_data->sw_poll_info.running = 1; }
void virtual_hub_device_init(ddf_fun_t *hc_dev) { virthub_init(&virtual_hub_device); /* * We need to register the root hub. * This must be done in separate fibril because the device * we are connecting to are ourselves and we cannot connect * before leaving the add_device() function. */ fid_t root_hub_registration = fibril_create(hub_register_in_devman_fibril, hc_dev); if (root_hub_registration == 0) { usb_log_fatal("Failed to create hub registration fibril.\n"); return; } fibril_add_ready(root_hub_registration); }
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); }
/** Initialize keyboard driver structure. * @param kbd Keyboard driver structure to initialize. * @param dev DDF device structure. * * Connects to parent, creates mouse function, starts polling fibril. */ int xt_kbd_init(xt_kbd_t *kbd, ddf_dev_t *dev) { assert(kbd); assert(dev); kbd->client_sess = NULL; kbd->parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE); if (!kbd->parent_sess) return ENOMEM; kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd"); if (!kbd->kbd_fun) { return ENOMEM; } ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops); int ret = ddf_fun_bind(kbd->kbd_fun); if (ret != EOK) { ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard"); if (ret != EOK) { ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } kbd->polling_fibril = fibril_create(polling, kbd); if (!kbd->polling_fibril) { ddf_fun_unbind(kbd->kbd_fun); ddf_fun_destroy(kbd->kbd_fun); return ENOMEM; } fibril_add_ready(kbd->polling_fibril); return EOK; }
static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm) { if (fm->counter++ < 0) { link_t *tmp; awaiter_t *wdp; fibril_t *f; tmp = list_first(&fm->waiters); assert(tmp != NULL); wdp = list_get_instance(tmp, awaiter_t, wu_event.link); wdp->active = true; wdp->wu_event.inlist = false; f = (fibril_t *) wdp->fid; fm->oi.owned_by = f; f->waits_for = NULL; list_remove(&wdp->wu_event.link); fibril_add_ready(wdp->fid); optimize_execution_power(); } else { fm->oi.owned_by = NULL; } }
/** Start automatic device polling over interrupt in pipe. * * @warning It is up to the callback to produce delays between individual * requests. * * @warning There is no guarantee when the request to the device * will be sent for the first time (it is possible that this * first request would be executed prior to return from this function). * * @param dev Device to be periodically polled. * @param pipe_index Index of the endpoint pipe used for polling. * @param callback Callback when data are available. * @param request_size How many bytes to ask for in each request. * @param terminated_callback Callback when polling is terminated. * @param arg Custom argument (passed as is to the callbacks). * @return Error code. * @retval EOK New fibril polling the device was already started. */ int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index, usb_polling_callback_t callback, size_t request_size, usb_polling_terminted_callback_t terminated_callback, void *arg) { const usb_device_auto_polling_t auto_polling = { .debug = 1, .auto_clear_halt = true, .delay = 0, .max_failures = MAX_FAILED_ATTEMPTS, .on_data = callback, .on_polling_end = terminated_callback, .on_error = NULL, .arg = arg, }; return usb_device_auto_polling(dev, pipe_index, &auto_polling, request_size); } /** Start automatic device polling over interrupt in pipe. * * The polling settings is copied thus it is okay to destroy the structure * after this function returns. * * @warning There is no guarantee when the request to the device * will be sent for the first time (it is possible that this * first request would be executed prior to return from this function). * * @param dev Device to be periodically polled. * @param pipe_index Index of the endpoint pipe used for polling. * @param polling Polling settings. * @param request_size How many bytes to ask for in each request. * @param arg Custom argument (passed as is to the callbacks). * @return Error code. * @retval EOK New fibril polling the device was already started. */ int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index, const usb_device_auto_polling_t *polling, size_t request_size) { if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) { return EBADMEM; } if (pipe_index >= dev->pipes_count || request_size == 0) { return EINVAL; } if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT) || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) { return EINVAL; } polling_data_t *polling_data = malloc(sizeof(polling_data_t)); if (polling_data == NULL) { return ENOMEM; } /* Fill-in the data. */ polling_data->buffer = malloc(sizeof(request_size)); if (polling_data->buffer == NULL) { free(polling_data); return ENOMEM; } polling_data->request_size = request_size; polling_data->dev = dev; polling_data->pipe_index = pipe_index; /* Copy provided settings. */ polling_data->auto_polling = *polling; /* Negative value means use descriptor provided value. */ if (polling->delay < 0) { polling_data->auto_polling.delay = (int) dev->pipes[pipe_index].descriptor->poll_interval; } fid_t fibril = fibril_create(polling_fibril, polling_data); if (fibril == 0) { free(polling_data->buffer); free(polling_data); return ENOMEM; } fibril_add_ready(fibril); /* Fibril launched. That fibril will free the allocated data. */ return EOK; }
static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw) { futex_down(&async_futex); if (frw->readers) { if (--frw->readers) { if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) { /* * If this reader firbril was considered the * owner of this rwlock, clear the ownership * information even if there are still more * readers. * * This is the limitation of the detection * mechanism rooted in the fact that tracking * all readers would require dynamically * allocated memory for keeping linkage info. */ frw->oi.owned_by = NULL; } goto out; } } else { frw->writers--; } assert(!frw->readers && !frw->writers); frw->oi.owned_by = NULL; while (!list_empty(&frw->waiters)) { link_t *tmp = list_first(&frw->waiters); awaiter_t *wdp; fibril_t *f; wdp = list_get_instance(tmp, awaiter_t, wu_event.link); f = (fibril_t *) wdp->fid; f->waits_for = NULL; if (f->flags & FIBRIL_WRITER) { if (frw->readers) break; wdp->active = true; wdp->wu_event.inlist = false; list_remove(&wdp->wu_event.link); fibril_add_ready(wdp->fid); frw->writers++; frw->oi.owned_by = f; optimize_execution_power(); break; } else { wdp->active = true; wdp->wu_event.inlist = false; list_remove(&wdp->wu_event.link); fibril_add_ready(wdp->fid); if (frw->readers++ == 0) { /* Consider the first reader the owner. */ frw->oi.owned_by = f; } optimize_execution_power(); } } out: futex_up(&async_futex); }
int main(int argc, char *argv[]) { int port = 2223; async_set_client_connection(client_connection); int rc = loc_server_register(NAME); if (rc != EOK) { fprintf(stderr, "%s: Unable to register server\n", NAME); return rc; } struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); rc = inet_pton(AF_INET, "127.0.0.1", (void *) &addr.sin_addr.s_addr); if (rc != EOK) { fprintf(stderr, "Error parsing network address: %s.\n", str_error(rc)); return 2; } int listen_sd = socket(PF_INET, SOCK_STREAM, 0); if (listen_sd < 0) { fprintf(stderr, "Error creating listening socket: %s.\n", str_error(listen_sd)); return 3; } rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr)); if (rc != EOK) { fprintf(stderr, "Error binding socket: %s.\n", str_error(rc)); return 4; } rc = listen(listen_sd, BACKLOG_SIZE); if (rc != EOK) { fprintf(stderr, "listen() failed: %s.\n", str_error(rc)); return 5; } printf("%s: HelenOS Remote console service\n", NAME); task_retval(0); while (true) { struct sockaddr_in raddr; socklen_t raddr_len = sizeof(raddr); int conn_sd = accept(listen_sd, (struct sockaddr *) &raddr, &raddr_len); if (conn_sd < 0) { fprintf(stderr, "accept() failed: %s.\n", str_error(rc)); continue; } telnet_user_t *user = telnet_user_create(conn_sd); assert(user); con_srvs_init(&user->srvs); user->srvs.ops = &con_ops; user->srvs.sarg = user; user->srvs.abort_timeout = 1000; telnet_user_add(user); fid_t fid = fibril_create(network_user_fibril, user); assert(fid); fibril_add_ready(fid); } return 0; }
static void tcp_sock_accept(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) { ipc_call_t answer; int socket_id; int asock_id; socket_core_t *sock_core; tcp_sockdata_t *socket; tcp_sockdata_t *asocket; tcp_error_t trc; tcp_sock_t lsocket; tcp_sock_t fsocket; tcp_conn_t *conn; tcp_conn_t *rconn; tcp_sock_lconn_t *lconn; int rc; log_msg(LVL_DEBUG, "tcp_sock_accept()"); socket_id = SOCKET_GET_SOCKET_ID(call); asock_id = SOCKET_GET_NEW_SOCKET_ID(call); sock_core = socket_cores_find(&client->sockets, socket_id); if (sock_core == NULL) { async_answer_0(callid, ENOTSOCK); return; } socket = (tcp_sockdata_t *)sock_core->specific_data; fibril_mutex_lock(&socket->lock); log_msg(LVL_DEBUG, " - verify socket->conn"); if (socket->conn != NULL) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, EINVAL); return; } if (list_empty(&socket->ready)) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, ENOENT); return; } lconn = list_get_instance(list_first(&socket->ready), tcp_sock_lconn_t, ready_list); list_remove(&lconn->ready_list); conn = lconn->conn; tcp_uc_set_cstate_cb(conn, NULL, NULL); /* Replenish listening connection */ lsocket.addr.ipv4 = TCP_IPV4_ANY; lsocket.port = sock_core->port; fsocket.addr.ipv4 = TCP_IPV4_ANY; fsocket.port = TCP_PORT_ANY; trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, tcp_open_nonblock, &rconn); if (rconn == NULL) { /* XXX Clean up */ fibril_mutex_unlock(&socket->lock); async_answer_0(callid, ENOMEM); return; } tcp_uc_set_cstate_cb(rconn, tcp_sock_cstate_cb, lconn); assert(trc == TCP_EOK); rconn->name = (char *)"S"; lconn->conn = rconn; /* Allocate socket for accepted connection */ rc = tcp_sock_create(client, &asocket); if (rc != EOK) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); return; } asocket->conn = conn; log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n"); rc = tcp_sock_finish_setup(asocket, &asock_id); if (rc != EOK) { tcp_sock_uncreate(asocket); fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); return; } fibril_add_ready(asocket->recv_fibril); log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n"); SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE); SOCKET_SET_SOCKET_ID(answer, asock_id); SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in)); async_answer_3(callid, asocket->sock_core->socket_id, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); /* Push one fragment notification to client's queue */ log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n"); fibril_mutex_unlock(&socket->lock); }
static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) { int rc; struct sockaddr_in *addr; int socket_id; size_t addr_len; socket_core_t *sock_core; tcp_sockdata_t *socket; tcp_error_t trc; tcp_sock_t lsocket; tcp_sock_t fsocket; log_msg(LVL_DEBUG, "tcp_sock_connect()"); rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len); if (rc != EOK || addr_len != sizeof(struct sockaddr_in)) { async_answer_0(callid, rc); return; } socket_id = SOCKET_GET_SOCKET_ID(call); sock_core = socket_cores_find(&client->sockets, socket_id); if (sock_core == NULL) { async_answer_0(callid, ENOTSOCK); return; } socket = (tcp_sockdata_t *)sock_core->specific_data; if (sock_core->port <= 0) { rc = socket_bind_free_port(&gsock, sock_core, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, last_used_port); if (rc != EOK) { async_answer_0(callid, rc); return; } last_used_port = sock_core->port; } fibril_mutex_lock(&socket->lock); if (socket->laddr.ipv4 == TCP_IPV4_ANY) { /* Determine local IP address */ inet_addr_t loc_addr, rem_addr; rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr); if (rc != EOK) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to " "determine local address."); return; } socket->laddr.ipv4 = loc_addr.ipv4; log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4); } lsocket.addr.ipv4 = socket->laddr.ipv4; lsocket.port = sock_core->port; fsocket.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); fsocket.port = uint16_t_be2host(addr->sin_port); trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn); if (socket->conn != NULL) socket->conn->name = (char *)"C"; fibril_mutex_unlock(&socket->lock); switch (trc) { case TCP_EOK: rc = EOK; break; case TCP_ERESET: rc = ECONNREFUSED; break; default: assert(false); } if (rc == EOK) fibril_add_ready(socket->recv_fibril); async_answer_0(callid, rc); }
int main(int argc, char *argv[]) { int rc; int argi; rc = inetping_init(&ev_ops); if (rc != EOK) { printf(NAME ": Failed connecting to internet ping service " "(%d).\n", rc); return 1; } argi = 1; if (argi < argc && str_cmp(argv[argi], "-r") == 0) { ping_repeat = true; ++argi; } else { ping_repeat = false; } if (argc - argi != 1) { print_syntax(); return 1; } /* Parse destination address */ rc = addr_parse(argv[argi], &dest_addr); if (rc != EOK) { printf(NAME ": Invalid address format.\n"); print_syntax(); return 1; } /* Determine source address */ rc = inetping_get_srcaddr(&dest_addr, &src_addr); if (rc != EOK) { printf(NAME ": Failed determining source address.\n"); return 1; } fid_t fid; if (ping_repeat) { fid = fibril_create(transmit_fibril, NULL); if (fid == 0) { printf(NAME ": Failed creating transmit fibril.\n"); return 1; } fibril_add_ready(fid); fid = fibril_create(input_fibril, NULL); if (fid == 0) { printf(NAME ": Failed creating input fibril.\n"); return 1; } fibril_add_ready(fid); } else { ping_send(1); } fibril_mutex_lock(&done_lock); rc = EOK; while (!done && rc != ETIMEOUT) { rc = fibril_condvar_wait_timeout(&done_cv, &done_lock, ping_repeat ? 0 : PING_TIMEOUT); } fibril_mutex_unlock(&done_lock); if (rc == ETIMEOUT) { printf(NAME ": Echo request timed out.\n"); return 1; } return 0; }
int main(int argc, char **argv) { sysarg_t baud = 38400; service_id_t svc_id; char *serial_port_name = NULL; int arg = 1; int rc; isdv4_event_fn event_fn = emit_event; if (argc > arg && str_test_prefix(argv[arg], "--baud=")) { size_t arg_offset = str_lsize(argv[arg], 7); char* arg_str = argv[arg] + arg_offset; if (str_length(arg_str) == 0) { fprintf(stderr, "--baud requires an argument\n"); syntax_print(); return 1; } char *endptr; baud = strtol(arg_str, &endptr, 10); if (*endptr != '\0') { fprintf(stderr, "Invalid value for baud\n"); syntax_print(); return 1; } arg++; } if (argc > arg && str_cmp(argv[arg], "--print-events") == 0) { event_fn = print_and_emit_event; arg++; } if (argc > arg) { serial_port_name = argv[arg]; rc = loc_service_get_id(serial_port_name, &svc_id, 0); if (rc != EOK) { fprintf(stderr, "Cannot find device service %s\n", argv[arg]); return 1; } arg++; } else { category_id_t serial_cat_id; rc = loc_category_get_id("serial", &serial_cat_id, 0); if (rc != EOK) { fprintf(stderr, "Failed getting id of category " "'serial'\n"); return 1; } service_id_t *svc_ids; size_t svc_count; rc = loc_category_get_svcs(serial_cat_id, &svc_ids, &svc_count); if (rc != EOK) { fprintf(stderr, "Failed getting list of services\n"); return 1; } if (svc_count == 0) { fprintf(stderr, "No service in category 'serial'\n"); free(svc_ids); return 1; } svc_id = svc_ids[0]; rc = loc_service_get_name(svc_id, &serial_port_name); if (rc != EOK) { fprintf(stderr, "Failed getting name of serial service\n"); return 1; } free(svc_ids); } if (argc > arg) { fprintf(stderr, "Too many arguments\n"); syntax_print(); return 1; } fibril_mutex_initialize(&client_mutex); printf(NAME ": Using serial port %s\n", serial_port_name); async_sess_t *sess = loc_service_connect(svc_id, INTERFACE_DDF, IPC_FLAG_BLOCKING); if (!sess) { fprintf(stderr, "Failed connecting to service\n"); } async_exch_t *exch = async_exchange_begin(sess); rc = async_req_4_0(exch, SERIAL_SET_COM_PROPS, baud, SERIAL_NO_PARITY, 8, 1); async_exchange_end(exch); if (rc != EOK) { fprintf(stderr, "Failed setting serial properties\n"); return 2; } rc = isdv4_init(&state, sess, event_fn); if (rc != EOK) { fprintf(stderr, "Failed initializing isdv4 state"); return 2; } rc = isdv4_init_tablet(&state); if (rc != EOK) { fprintf(stderr, "Failed initializing tablet"); return 2; } printf("Tablet information:\n"); printf(" Stylus: %ux%u pressure: %u tilt: ", state.stylus_max_x, state.stylus_max_y, state.stylus_max_pressure); if (state.stylus_tilt_supported) { printf("%ux%u\n", state.stylus_max_xtilt, state.stylus_max_ytilt); } else { printf("not supported\n"); } printf(" Touch: %ux%u type: %s\n", state.touch_max_x, state.touch_max_y, touch_type(state.touch_type)); fid_t fibril = fibril_create(read_fibril, NULL); /* From this on, state is to be used only by read_fibril */ fibril_add_ready(fibril); async_set_fallback_port_handler(mouse_connection, NULL); rc = loc_server_register(NAME); if (rc != EOK) { printf("%s: Unable to register driver.\n", NAME); return rc; } service_id_t service_id; char *service_name; rc = asprintf(&service_name, "mouse/isdv4-%" PRIun, svc_id); if (rc < 0) { printf(NAME ": Unable to create service name\n"); return rc; } rc = loc_service_register(service_name, &service_id); if (rc != EOK) { printf(NAME ": Unable to register service %s.\n", service_name); return rc; } category_id_t mouse_category; rc = loc_category_get_id("mouse", &mouse_category, IPC_FLAG_BLOCKING); if (rc != EOK) { printf(NAME ": Unable to get mouse category id.\n"); } else { rc = loc_service_add_to_cat(service_id, mouse_category); if (rc != EOK) { printf(NAME ": Unable to add device to mouse category.\n"); } } printf("%s: Accepting connections\n", NAME); task_retval(0); async_manager(); /* Not reached */ return 0; }
static void udp_sock_socket(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) { udp_sockdata_t *sock; socket_core_t *sock_core; int sock_id; int rc; ipc_call_t answer; log_msg(LVL_DEBUG, "udp_sock_socket()"); sock = calloc(sizeof(udp_sockdata_t), 1); if (sock == NULL) { async_answer_0(callid, ENOMEM); return; } fibril_mutex_initialize(&sock->lock); sock->client = client; sock->recv_buffer_used = 0; sock->recv_error = UDP_EOK; fibril_mutex_initialize(&sock->recv_buffer_lock); fibril_condvar_initialize(&sock->recv_buffer_cv); rc = udp_uc_create(&sock->assoc); if (rc != EOK) { free(sock); async_answer_0(callid, rc); return; } sock->recv_fibril = fibril_create(udp_sock_recv_fibril, sock); if (sock->recv_fibril == 0) { udp_uc_destroy(sock->assoc); free(sock); async_answer_0(callid, ENOMEM); return; } sock_id = SOCKET_GET_SOCKET_ID(call); rc = socket_create(&client->sockets, client->sess, sock, &sock_id); if (rc != EOK) { fibril_destroy(sock->recv_fibril); udp_uc_destroy(sock->assoc); free(sock); async_answer_0(callid, rc); return; } fibril_add_ready(sock->recv_fibril); sock_core = socket_cores_find(&client->sockets, sock_id); assert(sock_core != NULL); sock->sock_core = sock_core; SOCKET_SET_SOCKET_ID(answer, sock_id); SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE); SOCKET_SET_HEADER_SIZE(answer, sizeof(udp_header_t)); async_answer_3(callid, EOK, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); }