void spi_tty_write_worker(struct work_struct *work) { int c; int crc; unsigned long flags; unsigned long start_t = 0; spi_msg_header header; struct spi_tty_s *spi_tty = container_of(work, struct spi_tty_s, write_work); start_t = jiffies; SPI_IPC_INFO("%s Enter\n", __func__); mutex_lock(&(spi_tty->work_lock)); spin_lock_irqsave(&(spi_tty->port_lock), flags); while( ((c = spi_tty_buf_data_avail(spi_tty->write_buf)) || (spi_tty->tx_null)) && (!spi_tty->throttle) && (!spi_tty->spi_slave_dev->peer_is_dead)) { if (spi_tty->tx_null) spi_tty->tx_null = 0; // initiate spi_big_trans memset(spi_big_trans.tx_buf, 0x0, SPI_TRANSACTION_LEN*2); spi_big_msg.actual_length = 0; c = MIN(c, SPI_MTU); spi_tty_buf_get(spi_tty->write_buf, spi_big_trans.tx_buf+SPI_MSG_HEADER_LEN, c); if (spi_tty->tty && spi_tty->open_count) tty_wakeup(spi_tty->tty); spin_unlock_irqrestore(&(spi_tty->port_lock), flags); header.type = 1; header.len = c; header.dtr = spi_tty->dtr; crc = spi_msg_cal_crc(&header); header.fcs = crc; spi_msg_set_header(spi_big_trans.tx_buf, &header); spi_big_trans.len = c + SPI_MSG_HEADER_LEN; spi_ipc_buf_dump("tx header: ", spi_big_trans.tx_buf, SPI_MSG_HEADER_LEN); spi_ipc_buf_dump_ascii("tx data: ", spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN, (c>16?16:c)); spi_slave_sync(mdm6600_spi_dev.spi, &spi_big_msg); if (spi_big_msg.actual_length == SPI_TRANSACTION_LEN) { tx_count++; tx_size += spi_big_trans.len - SPI_MSG_HEADER_LEN; spi_tty_handle_data(spi_tty, spi_big_trans.rx_buf, SPI_TRANSACTION_LEN); }else { pr_err("%s: spi_slave_sync() failed to transfer data!\n", __func__); } // wake up writes wait on queue wake_up_interruptible(&spi_tty->write_wait); spin_lock_irqsave(&(spi_tty->port_lock), flags); } spin_unlock_irqrestore(&(spi_tty->port_lock), flags); mutex_unlock(&(spi_tty->work_lock)); SPI_IPC_INFO("%s Exit\n", __func__); tx_time += jiffies_to_msecs(jiffies - start_t); }
static void spi_tty_write_worker(struct work_struct *work) { int c; int crc; unsigned long flags; unsigned long start_t = 0; spi_msg_header header; struct spi_tty_s *spi_tty = container_of(work, struct spi_tty_s, write_work); start_t = jiffies; SPI_IPC_INFO("%s\n", __func__); mutex_lock(&(spi_tty->work_lock)); spin_lock_irqsave(&(spi_tty->port_lock), flags); while(((c = spi_tty_buf_data_avail(spi_tty->write_buf)) || (spi_tty->tx_null)) && (!spi_tty->throttle) && (!(spi_tty_dev && spi_tty_dev->peer_is_dead))) { SPI_IPC_INFO("%s: %d outgoing bytes\n", __func__, c); if (spi_tty->tx_null) spi_tty->tx_null = 0; // initiate spi_big_trans memset((char*)spi_big_trans.tx_buf, 0x0, SPI_TRANSACTION_LEN * 2); spi_big_msg.actual_length = 0; c = MIN(c, SPI_MTU); spi_tty_buf_get(spi_tty->write_buf, (char*)spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN, c); if (spi_tty->tty && spi_tty->open_count) tty_wakeup(spi_tty->tty); spin_unlock_irqrestore(&(spi_tty->port_lock), flags); header.type = 1; header.len = c; header.dtr = spi_tty->dtr; crc = spi_msg_cal_crc(&header); header.fcs = crc; spi_msg_set_header((u8*)spi_big_trans.tx_buf, &header); #if SPI_TTY_FORCE_FULL_TRANSACTION spi_big_trans.len = SPI_TRANSACTION_LEN; #else spi_big_trans.len = c + SPI_MSG_HEADER_LEN; #endif spi_big_trans.speed_hz = SPI_SPEED_HZ; spi_big_trans.bits_per_word = 32; spi_ipc_buf_dump("tx header: ", spi_big_trans.tx_buf, SPI_MSG_HEADER_LEN); spi_ipc_buf_dump_ascii("tx data: ", spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN, (c>16?16:c)); if (spi_tty_dev) spi_sync(spi_tty_dev->spi, &spi_big_msg); else pr_warning("%s: dropping data: no spi device " "registered", __func__); if (spi_big_msg.actual_length == SPI_TRANSACTION_LEN) { tx_count++; tx_size += spi_big_trans.len - SPI_MSG_HEADER_LEN; spi_tty_handle_data(spi_tty, spi_big_trans.rx_buf, SPI_TRANSACTION_LEN); }else { pr_err("%s: spi data transfer failed\n", __func__); } // wake up writes wait on queue wake_up_interruptible(&spi_tty->write_wait); spin_lock_irqsave(&(spi_tty->port_lock), flags); } spin_unlock_irqrestore(&(spi_tty->port_lock), flags); mutex_unlock(&(spi_tty->work_lock)); SPI_IPC_INFO("%s: done\n", __func__); tx_time += jiffies_to_msecs(jiffies - start_t); }