/** 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); }
/** * 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); }
/** * 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); }
/* 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); }
__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); }
/** * 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; }
/** * 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; }