/** 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;
}
Example #2
0
static int cuda_init(void)
{
	if (sysinfo_get_value("cuda.address.physical", &(instance->cuda_physical)) != EOK)
		return -1;
	
	void *vaddr;
	if (pio_enable((void *) instance->cuda_physical, sizeof(cuda_t), &vaddr) != 0)
		return -1;
	
	dev = vaddr;

	instance->cuda = dev;
	instance->xstate = cx_listen;
	instance->bidx = 0;
	instance->snd_bytes = 0;

	fibril_mutex_initialize(&instance->dev_lock);

	/* Disable all interrupts from CUDA. */
	pio_write_8(&dev->ier, IER_CLR | ALL_INT);

	cuda_irq_code.ranges[0].base = (uintptr_t) instance->cuda_physical;
	cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_physical)->ifr;
	async_set_interrupt_received(cuda_irq_handler);
	irq_register(10, device_assign_devno(), 0, &cuda_irq_code);

	/* Enable SR interrupt. */
	pio_write_8(&dev->ier, TIP | TREQ);
	pio_write_8(&dev->ier, IER_SET | SR_INT);

	/* Enable ADB autopolling. */
	cuda_autopoll_set(true);

	return 0;
}
Example #3
0
/** Create new association structure.
 *
 * @param lsock		Local socket (will be deeply copied)
 * @param fsock		Foreign socket (will be deeply copied)
 * @return		New association or NULL
 */
udp_assoc_t *udp_assoc_new(udp_sock_t *lsock, udp_sock_t *fsock)
{
	udp_assoc_t *assoc = NULL;

	/* Allocate association structure */
	assoc = calloc(1, sizeof(udp_assoc_t));
	if (assoc == NULL)
		goto error;

	fibril_mutex_initialize(&assoc->lock);

	/* One for the user */
	atomic_set(&assoc->refcnt, 1);

	/* Initialize receive queue */
	list_initialize(&assoc->rcv_queue);
	fibril_condvar_initialize(&assoc->rcv_queue_cv);

	if (lsock != NULL)
		assoc->ident.local = *lsock;
	if (fsock != NULL)
		assoc->ident.foreign = *fsock;

	return assoc;
error:
	return NULL;
}
Example #4
0
static int file_bd_init(const char *fname)
{
	bd_srvs_init(&bd_srvs);
	bd_srvs.ops = &file_bd_ops;
	
	async_set_fallback_port_handler(file_bd_connection, NULL);
	int rc = loc_server_register(NAME);
	if (rc != EOK) {
		printf("%s: Unable to register driver.\n", NAME);
		return rc;
	}
	
	img = fopen(fname, "rb+");
	if (img == NULL)
		return EINVAL;
	
	if (fseek(img, 0, SEEK_END) != 0) {
		fclose(img);
		return EIO;
	}
	
	off64_t img_size = ftell(img);
	if (img_size < 0) {
		fclose(img);
		return EIO;
	}
	
	num_blocks = img_size / block_size;
	
	fibril_mutex_initialize(&dev_lock);
	
	return EOK;
}
Example #5
0
/**
 * Initialize audio pipe structure.
 * @param pipe The pipe structure to initialize.
 */
void audio_pipe_init(audio_pipe_t *pipe)
{
	assert(pipe);
	list_initialize(&pipe->list);
	fibril_mutex_initialize(&pipe->guard);
	pipe->frames = 0;
	pipe->bytes = 0;
}
Example #6
0
void iplink_srv_init(iplink_srv_t *srv)
{
	fibril_mutex_initialize(&srv->lock);
	srv->connected = false;
	srv->ops = NULL;
	srv->arg = NULL;
	srv->client_sess = NULL;
}
Example #7
0
/**
 * Initializes libraries required for NIC framework - logger
 *
 * @param name	Name of the device/driver (used in logging)
 */
int nic_driver_init(const char *name)
{
	list_initialize(&nic_globals.frame_list_cache);
	nic_globals.frame_list_cache_size = 0;
	list_initialize(&nic_globals.frame_cache);
	nic_globals.frame_cache_size = 0;
	fibril_mutex_initialize(&nic_globals.lock);
	
	char buffer[256];
	snprintf(buffer, 256, "drv/" DEVICE_CATEGORY_NIC "/%s", name);
	
	return EOK;
}
Example #8
0
static int tcp_sock_create(tcp_client_t *client, tcp_sockdata_t **rsock)
{
	tcp_sockdata_t *sock;

	log_msg(LVL_DEBUG, "tcp_sock_create()");
	*rsock = NULL;

	sock = calloc(sizeof(tcp_sockdata_t), 1);
	if (sock == NULL)
		return ENOMEM;

	fibril_mutex_initialize(&sock->lock);
	sock->client = client;

	sock->recv_buffer_used = 0;
	sock->recv_error = TCP_EOK;
	fibril_mutex_initialize(&sock->recv_buffer_lock);
	fibril_condvar_initialize(&sock->recv_buffer_cv);
	list_initialize(&sock->ready);

	*rsock = sock;
	return EOK;
}
Example #9
0
void *vfs_client_data_create(void)
{
	vfs_client_data_t *vfs_data;

	vfs_data = malloc(sizeof(vfs_client_data_t));
	if (vfs_data) {
		fibril_mutex_initialize(&vfs_data->lock);
		fibril_condvar_initialize(&vfs_data->cv);
		list_initialize(&vfs_data->passed_handles);
		vfs_data->files = NULL;
	}
	
	return vfs_data;
}
Example #10
0
static vhc_virtdev_t *vhc_virtdev_create(void)
{
	vhc_virtdev_t *dev = malloc(sizeof(vhc_virtdev_t));
	if (dev == NULL) {
		return NULL;
	}
	dev->address = 0;
	dev->dev_sess = NULL;
	dev->dev_local = NULL;
	dev->plugged = true;
	link_initialize(&dev->link);
	fibril_mutex_initialize(&dev->guard);
	list_initialize(&dev->transfer_queue);

	return dev;
}
Example #11
0
/*
 * Helper functions.
 */
static void fat_node_initialize(fat_node_t *node)
{
	fibril_mutex_initialize(&node->lock);
	node->bp = NULL;
	node->idx = NULL;
	node->type = 0;
	link_initialize(&node->ffn_link);
	node->size = 0;
	node->lnkcnt = 0;
	node->refcnt = 0;
	node->dirty = false;
	node->lastc_cached_valid = false;
	node->lastc_cached_value = 0;
	node->currc_cached_valid = false;
	node->currc_cached_bn = 0;
	node->currc_cached_value = 0;
}
Example #12
0
/** Initialize transfer list structures.
 *
 * @param[in] instance Memory place to use.
 * @param[in] name Name of the new list.
 * @return Error code
 *
 * Allocates memory for internal ed_t structure.
 */
int endpoint_list_init(endpoint_list_t *instance, const char *name)
{
	assert(instance);
	instance->name = name;
	instance->list_head = malloc32(sizeof(ed_t));
	if (!instance->list_head) {
		usb_log_error("Failed to allocate list head.\n");
		return ENOMEM;
	}
	instance->list_head_pa = addr_to_phys(instance->list_head);
	usb_log_debug2("Transfer list %s setup with ED: %p(0x%0" PRIx32 ")).\n",
	    name, instance->list_head, instance->list_head_pa);

	ed_init(instance->list_head, NULL, NULL);
	list_initialize(&instance->endpoint_list);
	fibril_mutex_initialize(&instance->guard);
	return EOK;
}
Example #13
0
static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc)
{
	if (!vfs_files_init(vfs_data))
		return ENOMEM;
	
	unsigned int i;
	if (desc)
		i = MAX_OPEN_FILES - 1;
	else
		i = 0;
	
	fibril_mutex_lock(&vfs_data->lock);
	while (true) {
		if (!vfs_data->files[i]) {
			vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
			if (!vfs_data->files[i]) {
				fibril_mutex_unlock(&vfs_data->lock);
				return ENOMEM;
			}
			
			memset(vfs_data->files[i], 0, sizeof(vfs_file_t));
			fibril_mutex_initialize(&vfs_data->files[i]->lock);
			vfs_file_addref(vfs_data, vfs_data->files[i]);
			fibril_mutex_unlock(&vfs_data->lock);
			return (int) i;
		}
		
		if (desc) {
			if (i == 0)
				break;
			
			i--;
		} else {
			if (i == MAX_OPEN_FILES - 1)
				break;
			
			i++;
		}
	}
	fibril_mutex_unlock(&vfs_data->lock);
	
	return EMFILE;
}
Example #14
0
/** Create UDP client instance.
 *
 * @param  rudp Place to store pointer to new UDP client
 * @return EOK on success, ENOMEM if out of memory, EIO if service
 *         cannot be contacted
 */
int udp_create(udp_t **rudp)
{
	udp_t *udp;
	service_id_t udp_svcid;
	int rc;

	udp = calloc(1, sizeof(udp_t));
	if (udp == NULL) {
		rc = ENOMEM;
		goto error;
	}

	list_initialize(&udp->assoc);
	fibril_mutex_initialize(&udp->lock);
	fibril_condvar_initialize(&udp->cv);

	rc = loc_service_get_id(SERVICE_NAME_UDP, &udp_svcid,
	    IPC_FLAG_BLOCKING);
	if (rc != EOK) {
		rc = EIO;
		goto error;
	}

	udp->sess = loc_service_connect(udp_svcid, INTERFACE_UDP,
	    IPC_FLAG_BLOCKING);
	if (udp->sess == NULL) {
		rc = EIO;
		goto error;
	}

	rc = udp_callback_create(udp);
	if (rc != EOK) {
		rc = EIO;
		goto error;
	}

	*rudp = udp;
	return EOK;
error:
	free(udp);
	return rc;
}
Example #15
0
/** Allocate ad initialize endpoint_t structure.
 * @param address USB address.
 * @param endpoint USB endpoint number.
 * @param direction Communication direction.
 * @param type USB transfer type.
 * @param speed Communication speed.
 * @param max_packet_size Maximum size of data packets.
 * @param bw Required bandwidth.
 * @return Pointer to initialized endpoint_t structure, NULL on failure.
 */
endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
    usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
    size_t max_packet_size, size_t bw)
{
	endpoint_t *instance = malloc(sizeof(endpoint_t));
	if (instance) {
		instance->address = address;
		instance->endpoint = endpoint;
		instance->direction = direction;
		instance->transfer_type = type;
		instance->speed = speed;
		instance->max_packet_size = max_packet_size;
		instance->bandwidth = bw;
		instance->toggle = 0;
		instance->active = false;
		instance->hc_data.data = NULL;
		instance->hc_data.toggle_get = NULL;
		instance->hc_data.toggle_set = NULL;
		link_initialize(&instance->link);
		fibril_mutex_initialize(&instance->guard);
		fibril_condvar_initialize(&instance->avail);
	}
	return instance;
}
Example #16
0
void prodcons_initialize(prodcons_t *pc)
{
	list_initialize(&pc->list);
	fibril_mutex_initialize(&pc->mtx);
	fibril_condvar_initialize(&pc->cv);
}
Example #17
0
/** Root Hub driver structure initialization.
 *
 * Reads info registers and prepares descriptors. Sets power mode.
 */
void rh_init(rh_t *instance, ohci_regs_t *regs)
{
	assert(instance);
	assert(regs);

	instance->registers = regs;
	instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK;
	usb_log_debug2("rh_desc_a: %x.\n", OHCI_RD(regs->rh_desc_a));
	if (instance->port_count > 15) {
		usb_log_warning("OHCI specification does not allow more than 15"
		    " ports. Max 15 ports will be used");
		instance->port_count = 15;
	}

	/* Don't forget the hub status bit and round up */
	instance->interrupt_mask_size = 1 + (instance->port_count / 8);
	instance->unfinished_interrupt_transfer = NULL;

#if defined OHCI_POWER_SWITCH_no
	usb_log_debug("OHCI rh: Set power mode to no power switching.\n");
	/* Set port power mode to no power-switching. (always on) */
	OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG);

	/* Set to no over-current reporting */
	OHCI_SET(regs->rh_desc_a, RHDA_NOCP_FLAG);

#elif defined OHCI_POWER_SWITCH_ganged
	usb_log_debug("OHCI rh: Set power mode to ganged power switching.\n");
	/* Set port power mode to ganged power-switching. */
	OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
	OHCI_CLR(regs->rh_desc_a, RHDA_PSM_FLAG);

	/* Turn off power (hub driver will turn this back on)*/
	OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);

	/* Set to global over-current */
	OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG);
	OHCI_CLR(regs->rh_desc_a, RHDA_OCPM_FLAG);
#else
	usb_log_debug("OHCI rh: Set power mode to per-port power switching.\n");
	/* Set port power mode to per port power-switching. */
	OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
	OHCI_SET(regs->rh_desc_a, RHDA_PSM_FLAG);

	/* Control all ports by global switch and turn them off */
	OHCI_CLR(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);
	OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);

	/* Return control to per port state */
	OHCI_SET(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);

	/* Set per port over-current */
	OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG);
	OHCI_SET(regs->rh_desc_a, RHDA_OCPM_FLAG);
#endif

	fibril_mutex_initialize(&instance->guard);
	rh_init_descriptors(instance);

	usb_log_info("Root hub (%zu ports) initialized.\n",
	    instance->port_count);
}
Example #18
0
/**
 * Initialize hub device driver structure.
 *
 * Creates hub representation and fibril that periodically checks hub's status.
 * Hub representation is passed to the fibril.
 * @param usb_dev generic usb device information
 * @return error code
 */
int usb_hub_device_add(usb_device_t *usb_dev)
{
	assert(usb_dev);
	/* Create driver soft-state structure */
	usb_hub_dev_t *hub_dev =
	    usb_device_data_alloc(usb_dev, sizeof(usb_hub_dev_t));
	if (hub_dev == NULL) {
		usb_log_error("Failed to create hub driver structure.\n");
		return ENOMEM;
	}
	hub_dev->usb_device = usb_dev;
	hub_dev->pending_ops_count = 0;
	hub_dev->running = false;
	fibril_mutex_initialize(&hub_dev->pending_ops_mutex);
	fibril_condvar_initialize(&hub_dev->pending_ops_cv);


	int opResult = usb_pipe_start_long_transfer(&usb_dev->ctrl_pipe);
	if (opResult != EOK) {
		usb_log_error("Failed to start long ctrl pipe transfer: %s\n",
		    str_error(opResult));
		return opResult;
	}

	/* Set hub's first configuration. (There should be only one) */
	opResult = usb_set_first_configuration(usb_dev);
	if (opResult != EOK) {
		usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
		usb_log_error("Could not set hub configuration: %s\n",
		    str_error(opResult));
		return opResult;
	}

	/* Get port count and create attached_devices. */
	opResult = usb_hub_process_hub_specific_info(hub_dev);
	if (opResult != EOK) {
		usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
		usb_log_error("Could process hub specific info, %s\n",
		    str_error(opResult));
		return opResult;
	}

	/* Create hub control function. */
	usb_log_debug("Creating DDF function '" HUB_FNC_NAME "'.\n");
	hub_dev->hub_fun = ddf_fun_create(hub_dev->usb_device->ddf_dev,
	    fun_exposed, HUB_FNC_NAME);
	if (hub_dev->hub_fun == NULL) {
		usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
		usb_log_error("Failed to create hub function.\n");
		return ENOMEM;
	}

	/* Bind hub control function. */
	opResult = ddf_fun_bind(hub_dev->hub_fun);
	if (opResult != EOK) {
		usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
		usb_log_error("Failed to bind hub function: %s.\n",
		   str_error(opResult));
		ddf_fun_destroy(hub_dev->hub_fun);
		return opResult;
	}

	/* Start hub operation. */
	opResult = usb_device_auto_poll(hub_dev->usb_device, 0,
	    hub_port_changes_callback, ((hub_dev->port_count + 1 + 8) / 8),
	    usb_hub_polling_terminated_callback, hub_dev);
	if (opResult != EOK) {
		usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
		/* Function is already bound */
		ddf_fun_unbind(hub_dev->hub_fun);
		ddf_fun_destroy(hub_dev->hub_fun);
		usb_log_error("Failed to create polling fibril: %s.\n",
		    str_error(opResult));
		return opResult;
	}
	hub_dev->running = true;
	usb_log_info("Controlling hub '%s' (%zu ports).\n",
	    hub_dev->usb_device->ddf_dev->name, hub_dev->port_count);

	usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
	return EOK;
}
Example #19
0
/** Create new connection structure.
 *
 * @param epp		Endpoint pair (will be deeply copied)
 * @return		New connection or NULL
 */
tcp_conn_t *tcp_conn_new(inet_ep2_t *epp)
{
	tcp_conn_t *conn = NULL;
	bool tqueue_inited = false;

	/* Allocate connection structure */
	conn = calloc(1, sizeof(tcp_conn_t));
	if (conn == NULL)
		goto error;

	fibril_mutex_initialize(&conn->lock);

	conn->tw_timer = fibril_timer_create(&conn->lock);
	if (conn->tw_timer == NULL)
		goto error;

	/* One for the user, one for not being in closed state */
	atomic_set(&conn->refcnt, 2);

	/* Allocate receive buffer */
	fibril_condvar_initialize(&conn->rcv_buf_cv);
	conn->rcv_buf_size = RCV_BUF_SIZE;
	conn->rcv_buf_used = 0;
	conn->rcv_buf_fin = false;

	conn->rcv_buf = calloc(1, conn->rcv_buf_size);
	if (conn->rcv_buf == NULL)
		goto error;

	/** Allocate send buffer */
	fibril_condvar_initialize(&conn->snd_buf_cv);
	conn->snd_buf_size = SND_BUF_SIZE;
	conn->snd_buf_used = 0;
	conn->snd_buf_fin = false;
	conn->snd_buf = calloc(1, conn->snd_buf_size);
	if (conn->snd_buf == NULL)
		goto error;

	/* Set up receive window. */
	conn->rcv_wnd = conn->rcv_buf_size;

	/* Initialize incoming segment queue */
	tcp_iqueue_init(&conn->incoming, conn);

	/* Initialize retransmission queue */
	if (tcp_tqueue_init(&conn->retransmit, conn) != EOK)
		goto error;

	tqueue_inited = true;

	/* Connection state change signalling */
	fibril_condvar_initialize(&conn->cstate_cv);

	conn->cb = NULL;

	conn->cstate = st_listen;
	conn->reset = false;
	conn->deleted = false;
	conn->ap = ap_passive;
	conn->fin_is_acked = false;
	if (epp != NULL)
		conn->ident = *epp;

	return conn;

error:
	if (tqueue_inited)
		tcp_tqueue_fini(&conn->retransmit);
	if (conn != NULL && conn->rcv_buf != NULL)
		free(conn->rcv_buf);
	if (conn != NULL && conn->snd_buf != NULL)
		free(conn->snd_buf);
	if (conn != NULL && conn->tw_timer != NULL)
		fibril_timer_destroy(conn->tw_timer);
	if (conn != NULL)
		free(conn);

	return NULL;
}
Example #20
0
/** Initialize i8042 driver structure.
 *
 * @param dev       Driver structure to initialize.
 * @param regs      I/O address of registers.
 * @param reg_size  size of the reserved I/O address space.
 * @param irq_kbd   IRQ for primary port.
 * @param irq_mouse IRQ for aux port.
 * @param ddf_dev   DDF device structure of the device.
 *
 * @return Error code.
 *
 */
int i8042_init(i8042_t *dev, void *regs, size_t reg_size, int irq_kbd,
               int irq_mouse, ddf_dev_t *ddf_dev)
{
    const size_t range_count = sizeof(i8042_ranges) /
                               sizeof(irq_pio_range_t);
    irq_pio_range_t ranges[range_count];
    const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    irq_cmd_t cmds[cmd_count];

    int rc;
    bool kbd_bound = false;
    bool aux_bound = false;

    dev->kbd_fun = NULL;
    dev->aux_fun = NULL;

    if (reg_size < sizeof(i8042_regs_t)) {
        rc = EINVAL;
        goto error;
    }

    if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0) {
        rc = EIO;
        goto error;
    }

    dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    if (dev->kbd_fun == NULL) {
        rc = ENOMEM;
        goto error;
    };

    rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
    if (rc != EOK)
        goto error;

    dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    if (dev->aux_fun == NULL) {
        rc = ENOMEM;
        goto error;
    }

    rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
    if (rc != EOK)
        goto error;

    ddf_fun_set_ops(dev->kbd_fun, &ops);
    ddf_fun_set_ops(dev->aux_fun, &ops);

    buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
    buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE);
    fibril_mutex_initialize(&dev->write_guard);

    rc = ddf_fun_bind(dev->kbd_fun);
    if (rc != EOK) {
        ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.",
                ddf_fun_get_name(dev->kbd_fun));
        goto error;
    }
    kbd_bound = true;

    rc = ddf_fun_bind(dev->aux_fun);
    if (rc != EOK) {
        ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.",
                ddf_fun_get_name(dev->aux_fun));
        goto error;
    }
    aux_bound = true;

    /* Disable kbd and aux */
    wait_ready(dev);
    pio_write_8(&dev->regs->status, i8042_CMD_WRITE_CMDB);
    wait_ready(dev);
    pio_write_8(&dev->regs->data, i8042_KBD_DISABLE | i8042_AUX_DISABLE);

    /* Flush all current IO */
    while (pio_read_8(&dev->regs->status) & i8042_OUTPUT_FULL)
        (void) pio_read_8(&dev->regs->data);

    memcpy(ranges, i8042_ranges, sizeof(i8042_ranges));
    ranges[0].base = (uintptr_t) regs;

    memcpy(cmds, i8042_cmds, sizeof(i8042_cmds));
    cmds[0].addr = (void *) &(((i8042_regs_t *) regs)->status);
    cmds[3].addr = (void *) &(((i8042_regs_t *) regs)->data);

    irq_code_t irq_code = {
        .rangecount = range_count,
        .ranges = ranges,
        .cmdcount = cmd_count,
        .cmds = cmds
    };

    rc = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
                                    &irq_code);
    if (rc != EOK) {
        ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.",
                ddf_dev_get_name(ddf_dev));
        goto error;
    }

    rc = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
                                    &irq_code);
    if (rc != EOK) {
        ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.",
                ddf_dev_get_name(ddf_dev));
        goto error;
    }

    /* Enable interrupts */
    async_sess_t *parent_sess = ddf_dev_parent_sess_get(ddf_dev);
    assert(parent_sess != NULL);

    const bool enabled = hw_res_enable_interrupt(parent_sess);
    if (!enabled) {
        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to enable interrupts: %s.",
                ddf_dev_get_name(ddf_dev));
        rc = EIO;
        goto error;
    }

    /* Enable port interrupts. */
    wait_ready(dev);
    pio_write_8(&dev->regs->status, i8042_CMD_WRITE_CMDB);
    wait_ready(dev);
    pio_write_8(&dev->regs->data, i8042_KBD_IE | i8042_KBD_TRANSLATE |
                i8042_AUX_IE);

    return EOK;
error:
    if (kbd_bound)
        ddf_fun_unbind(dev->kbd_fun);
    if (aux_bound)
        ddf_fun_unbind(dev->aux_fun);
    if (dev->kbd_fun != NULL)
        ddf_fun_destroy(dev->kbd_fun);
    if (dev->aux_fun != NULL)
        ddf_fun_destroy(dev->aux_fun);

    return rc;
}
Example #21
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;
}
Example #22
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));
}
Example #23
0
static int vhc_dev_add(ddf_dev_t *dev)
{
    static int vhc_count = 0;
    int rc;

    if (vhc_count > 0) {
        return ELIMIT;
    }

    vhc_data_t *data = ddf_dev_data_alloc(dev, sizeof(vhc_data_t));
    if (data == NULL) {
        usb_log_fatal("Failed to allocate memory.\n");
        return ENOMEM;
    }
    data->magic = 0xDEADBEEF;
    rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1,
                                   bandwidth_count_usb11);
    if (rc != EOK) {
        usb_log_fatal("Failed to initialize endpoint manager.\n");
        free(data);
        return rc;
    }
    usb_device_manager_init(&data->dev_manager, USB_SPEED_MAX);

    ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
    if (hc == NULL) {
        usb_log_fatal("Failed to create device function.\n");
        free(data);
        return ENOMEM;
    }

    ddf_fun_set_ops(hc, &vhc_ops);
    list_initialize(&data->devices);
    fibril_mutex_initialize(&data->guard);
    data->hub = &virtual_hub_device;
    data->hc_fun = hc;

    rc = ddf_fun_bind(hc);
    if (rc != EOK) {
        usb_log_fatal("Failed to bind HC function: %s.\n",
                      str_error(rc));
        free(data);
        return rc;
    }

    rc = ddf_fun_add_to_category(hc, USB_HC_CATEGORY);
    if (rc != EOK) {
        usb_log_fatal("Failed to add function to HC class: %s.\n",
                      str_error(rc));
        free(data);
        return rc;
    }

    virtual_hub_device_init(hc);

    usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
                 (size_t) ddf_dev_get_handle(dev), (size_t) ddf_fun_get_handle(hc));

    rc = vhc_virtdev_plug_hub(data, data->hub, NULL);
    if (rc != EOK) {
        usb_log_fatal("Failed to plug root hub: %s.\n", str_error(rc));
        free(data);
        return rc;
    }

    return EOK;
}