Beispiel #1
0
/** Write to the data manager file */
__EXPORT ssize_t
dm_write(dm_item_t item, unsigned char index, dm_persitence_t persistence, const void *buf, size_t count)
{
	work_q_item_t *work;

	/* Make sure data manager has been started and is not shutting down */
	if ((g_fd < 0) || g_task_should_exit) {
		return -1;
	}

	/* get a work item and queue up a write request */
	if ((work = create_work_item()) == NULL) {
		return -1;
	}

	work->func = dm_write_func;
	work->write_params.item = item;
	work->write_params.index = index;
	work->write_params.persistence = persistence;
	work->write_params.buf = buf;
	work->write_params.count = count;

	/* Enqueue the item on the work queue and wait for the worker thread to complete processing it */
	return (ssize_t)enqueue_work_item_and_wait_for_result(work);
}
Beispiel #2
0
/**
 * uart_tty_wakeup() - Callback function for transmit wake up.
 * @tty:	Pointer to associated TTY instance data.
 *
 * The uart_tty_wakeup() callback function is called when low level
 * device driver can accept more send data.
 */
static void uart_tty_wakeup(struct tty_struct *tty)
{
	int err;

	CG2900_INFO("uart_tty_wakeup");

	/*
	 * Clear the TTY_DO_WRITE_WAKEUP bit that is set in
	 * work_do_transmit().
	 */
	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

	if (tty != uart_info->tty)
		return;

#ifdef BAUD_RATE_FIX
	/* Delete sleep timer. */
	(void)del_timer(&uart_info->timer);
#endif /* BAUD_RATE_FIX */
	/* Start TX operation */
	err = create_work_item(uart_info->wq, work_do_transmit, NULL);
	if (err)
		CG2900_ERR("Failed to create work item (%d) uart_tty_wakeup",
			   err);
}
Beispiel #3
0
/**
 * uart_tty_close() - Close UART tty.
 * @tty:	Pointer to associated TTY instance data.
 *
 * The uart_tty_close() function is called when the line discipline is changed
 * to something else, the TTY is closed, or the TTY detects a hangup.
 */
static void uart_tty_close(struct tty_struct *tty)
{
	int err;

	CG2900_INFO("uart_tty_close");

	BUG_ON(!uart_info);
	BUG_ON(!uart_info->wq);

	err = create_work_item(uart_info->wq, work_hw_deregistered, NULL);
	if (err)
		CG2900_ERR("Failed to create work item (%d) "
			   "work_hw_deregistered", err);
}
Beispiel #4
0
/* Tell the data manager about the type of the last reset */
__EXPORT int
dm_restart(dm_reset_reason reason)
{
	work_q_item_t *work;

	/* Make sure data manager has been started and is not shutting down */
	if ((g_fd < 0) || g_task_should_exit)
		return -1;

	/* get a work item and queue up a restart request */
	if ((work = create_work_item()) == NULL)
		return -1;

	work->func = dm_restart_func;
	work->restart_params.reason = reason;

	/* Enqueue the item on the work queue and wait for the worker thread to complete processing it */
	return enqueue_work_item_and_wait_for_result(work);
}
Beispiel #5
0
__EXPORT int
dm_clear(dm_item_t item)
{
	work_q_item_t *work;

	/* Make sure data manager has been started and is not shutting down */
	if ((g_fd < 0) || g_task_should_exit) {
		return -1;
	}

	/* get a work item and queue up a clear request */
	if ((work = create_work_item()) == NULL) {
		return -1;
	}

	work->func = dm_clear_func;
	work->clear_params.item = item;

	/* Enqueue the item on the work queue and wait for the worker thread to complete processing it */
	return enqueue_work_item_and_wait_for_result(work);
}
Beispiel #6
0
/**
 * uart_write() - Transmit data to CG2900 over UART.
 * @dev:	Transport device information.
 * @skb:	SK buffer to transmit.
 *
 * Returns:
 *   0 if there is no error.
 *   Errors from create_work_item.
 */
static int uart_write(struct cg2900_trans_dev *dev, struct sk_buff *skb)
{
	int err;

#ifdef BAUD_RATE_FIX
	/* Delete sleep timer. */
	(void)del_timer(&uart_info->timer);
#else /* BAUD_RATE_FIX */
	update_timer();
#endif /* BAUD_RATE_FIX */

	/* Queue the sk_buffer... */
	skb_queue_tail(&uart_info->tx_queue, skb);

	CG2900_DBG_DATA_CONTENT("uart_write", skb->data, skb->len);
	/* ...and start TX operation */
	err = create_work_item(uart_info->wq, work_do_transmit, NULL);
	if (err)
		CG2900_ERR("Failed to create work item (%d) uart_tty_wakeup",
			   err);

	return err;
}
Beispiel #7
0
/**
 * set_baud_rate() - Sets new baud rate for the UART.
 * @baud:	New baud rate.
 *
 * This function first sends the HCI command
 * Hci_Cmd_ST_Set_Uart_Baud_Rate. It then changes the baud rate in HW, and
 * finally it waits for the Command Complete event for the
 * Hci_Cmd_ST_Set_Uart_Baud_Rate command.
 *
 * Returns:
 *   0 if there is no error.
 *   -EALREADY if baud rate change is already in progress.
 *   -EFAULT if one or more of the UART related structs is not allocated.
 *   -ENOMEM if skb allocation has failed.
 *   -EPERM if setting the new baud rate has failed.
 *   Error codes generated by create_work_item.
 */
static int set_baud_rate(int baud)
{
	struct tty_struct *tty = NULL;
	int err = 0;
	struct sk_buff *skb;
	int old_baud_rate;

	CG2900_INFO("set_baud_rate (%d baud)", baud);

	if (uart_info->baud_rate_state != BAUD_IDLE) {
		CG2900_ERR("Trying to set new baud rate before old setting "
			   "is finished");
		return -EALREADY;
	}

	if (uart_info->tty)
		tty = uart_info->tty;
	else {
		CG2900_ERR("Important structs not allocated!");
		return -EFAULT;
	}

#ifdef BAUD_RATE_FIX	
	/* Disable the RTS Flow */
	//tty_throttle(tty); // Not supported by Host
	//cg29xx_rts_gpio_control(0);
/* ++Hemant: Baudrate Workaround */
	cg29xx_rts_gpio_control(0);
/* --Hemant: Baudrate Workaround */
#endif /* BAUD_RATE_FIX */
	/*
	 * Store old baud rate so that we can restore it if something goes
	 * wrong.
	 */
	old_baud_rate = uart_info->baud_rate;

	skb = alloc_set_baud_rate_cmd(&baud);
	if (!skb) {
		CG2900_ERR("alloc_set_baud_rate_cmd failed");
		return -ENOMEM;
	}

	SET_BAUD_STATE(BAUD_START);
	uart_info->baud_rate = baud;

	/* Queue the sk_buffer... */
	skb_queue_tail(&uart_info->tx_queue, skb);

	/* ... and call the common UART TX function */
	CG2900_DBG_DATA_CONTENT("set_baud_rate", skb->data, skb->len);
	err = create_work_item(uart_info->wq, work_do_transmit, NULL);
	if (err) {
		CG2900_ERR("Failed to send change baud rate cmd, freeing "
			   "skb.");
		skb = skb_dequeue_tail(&uart_info->tx_queue);
		SET_BAUD_STATE(BAUD_IDLE);
		uart_info->baud_rate = old_baud_rate;
		kfree_skb(skb);
		return err;
	}

	CG2900_DBG("Set baud rate cmd scheduled for sending.");
	printk(KERN_ERR "Set baud rate cmd scheduled for sending.");

	/*
	 * Now wait for the command complete.
	 * It will come at the new baudrate.
	 */
	wait_event_interruptible_timeout(uart_wait_queue,
				((BAUD_SUCCESS == uart_info->baud_rate_state) ||
				 (BAUD_FAIL    == uart_info->baud_rate_state)),
				 msecs_to_jiffies(UART_RESP_TIMEOUT/50));/* ++ daniel - port fail recovery */
				 

	if (BAUD_SUCCESS == uart_info->baud_rate_state)
		//CG2900_DBG("Baudrate changed to %d baud", baud);
		printk(KERN_ERR "Baudrate changed to %d baud", baud);
		
	else {
		//CG2900_ERR("Failed to set new baudrate (%d)",
		//	   uart_info->baud_rate_state);
      printk(KERN_ERR "Failed to set new baudrate (%d)",
			   uart_info->baud_rate_state);			   
		err = -EPERM;
	}

	/* Finally flush the TTY so we are sure that is no bad data there */
	if (tty->ops->flush_buffer) {
		CG2900_DBG("Flushing TTY after baud rate change");
		tty->ops->flush_buffer(tty);
	}

	/* Finished. Set state to IDLE */
	SET_BAUD_STATE(BAUD_IDLE);

	return err;
}