int mux_ipc_sdio_read(char *buf, size_t count) { int ret = 0; wait_event_interruptible(s_mux_read_rts, !kfifo_is_empty(&s_mipc_rx_cache_kfifo) || s_mux_ipc_event_flags); if(s_mux_ipc_event_flags & MUX_IPC_READ_DISABLE) { printk("[mipc] mux ipc read disable!\r\n"); return -1; } IPC_DBG("[mipc]mux_ipc_sdio_read read len:%d\r\n", count); ret = kfifo_out(&s_mipc_rx_cache_kfifo,buf,count); ipc_info_mux_read(ret); ipc_info_sdio_read_saved_count(kfifo_len(&s_mipc_rx_cache_kfifo)); return ret; }
void ath10k_htt_tx_free(struct ath10k_htt *htt) { int size; tasklet_kill(&htt->txrx_compl_task); idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); idr_destroy(&htt->pending_tx); if (htt->txbuf.vaddr) { size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf); dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr, htt->txbuf.paddr); } ath10k_htt_tx_free_txq(htt); ath10k_htt_tx_free_cont_frag_desc(htt); WARN_ON(!kfifo_is_empty(&htt->txdone_fifo)); kfifo_free(&htt->txdone_fifo); }
static void delayed_work_cb(struct work_struct *work) { struct hidpp_device *hidpp_device = container_of(work, struct hidpp_device, work); unsigned long flags; int count; enum delayed_work_type work_type; dbg_hid("%s\n", __func__); spin_lock_irqsave(&hidpp_device->lock, flags); count = kfifo_out(&hidpp_device->delayed_work_fifo, &work_type, sizeof(enum delayed_work_type)); if (count != sizeof(enum delayed_work_type)) { dev_err(&hidpp_device->hid_dev->dev, "%s: workitem triggered without " "notifications available\n", __func__); spin_unlock_irqrestore(&hidpp_device->lock, flags); return; } if (!kfifo_is_empty(&hidpp_device->delayed_work_fifo)) { if (schedule_work(&hidpp_device->work) == 0) { dbg_hid("%s: did not schedule the work item, was " "already queued\n", __func__); } } spin_unlock_irqrestore(&hidpp_device->lock, flags); switch (work_type) { case HIDPP_INIT: hidpp_delayed_init(hidpp_device); break; default: dbg_hid("%s: unexpected report type\n", __func__); } }
/***************************************************************************** * FUNCTION * hal_btif_is_tx_complete * DESCRIPTION * get tx complete flag * PARAMETERS * p_base [IN] BTIF module's base address * RETURNS * true means tx complete, false means tx in process *****************************************************************************/ bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif) { /*Chaozhong: To be implement*/ bool b_ret = false; unsigned int lsr = 0; unsigned long flags = 0; unsigned int base = p_btif->base; unsigned int tx_empty = 0; unsigned int rx_dr = 0; unsigned int tx_irq_disable = 0; /*3 conditions allow clock to be disable 1. if TEMT is set or not 2. if DR is set or not 3. Tx IRQ is disabled or not*/ lsr = BTIF_READ32(BTIF_LSR(base)); tx_empty = lsr & BTIF_LSR_TEMT_BIT; rx_dr = lsr & BTIF_LSR_DR_BIT; tx_irq_disable = BTIF_READ32(BTIF_IER(base)) & BTIF_IER_TXEEN; b_ret = (tx_empty && (0 == tx_irq_disable) && (0 == rx_dr)) ? true : false; if (!b_ret) { BTIF_DBG_FUNC ("BTIF flag, tx_empty:%d, rx_dr:%d, tx_irq_disable:%d\n", tx_empty, rx_dr, tx_irq_disable); } #if NEW_TX_HANDLING_SUPPORT spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); /*clear Tx enable flag if necessary*/ if (!(kfifo_is_empty(p_btif->p_tx_fifo))) { BTIF_DBG_FUNC("BTIF tx FIFO is not empty\n"); b_ret = false; } spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); #endif return b_ret; }
static void stp_uart_rx_worker (struct work_struct *work) { unsigned int read; if (unlikely(!g_stp_uart_rx_fifo)) { UART_ERR_FUNC("NULL rx fifo!\n"); return; } if (unlikely(!g_stp_uart_rx_buf)) { UART_ERR_FUNC("NULL rx buf!\n"); return; } /* run until fifo becomes empty */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) while (kfifo_len(g_stp_uart_rx_fifo)) { read = kfifo_get(g_stp_uart_rx_fifo, g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE); //UART_LOUD_FUNC("kfifo_get(%d)\n", read); if (likely(read)) { mtk_wcn_stp_parser_data((UINT8 *)g_stp_uart_rx_buf, read); } } #else while (!kfifo_is_empty(g_stp_uart_rx_fifo)) { read = kfifo_out(g_stp_uart_rx_fifo, g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE); UART_DBG_FUNC("kfifo_out(%d)\n", read); //printk("rx_work:%d\n\r",read); if (likely(read)) { //UART_LOUD_FUNC("->%d\n", read); mtk_wcn_stp_parser_data((UINT8 *)g_stp_uart_rx_buf, read); //UART_LOUD_FUNC("<-\n", read); } } #endif return; }
static int __init queue_init(void) { int i; unsigned int ret; unsigned int val; printk(KERN_INFO "FIFO start\n"); if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) { printk(KERN_WARNING "error kfifo\n"); return -ENOMEM; } printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo)); kfifo_in(&fifo, "test", 4); for (i = 0; i < 4; i++) kfifo_in(&fifo, &i, sizeof(i)); ret = kfifo_out(&fifo, buffer, 4); if (ret != 4) return -EINVAL; printk(KERN_INFO "%s\n", buffer); printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); while (!kfifo_is_empty(&fifo)) { ret = kfifo_out(&fifo, &val, sizeof(val)); if (ret != sizeof(val)) return -EINVAL; printk(KERN_INFO "%u\n", val); } return 0; }
static ssize_t emd_dev_read(struct file *file, char *buf, size_t count, loff_t *ppos) { emd_dev_client_t *client=(emd_dev_client_t *)file->private_data; int ret=0,size, data; WARN_ON(client==NULL); do{ size=pop_data(client,&data); if( sizeof(int) == size){ EMD_MSG_INF("chr","client%d get data:%08x, ret=%d\n", client->sub_dev_id, data, ret); if( copy_to_user(buf,&data,sizeof(int)) ){ EMD_MSG_INF("chr","copy_to_user fialed\n"); ret = -EFAULT; goto _OUT; }else{ ret = size; goto _OUT; } }else{ if (file->f_flags & O_NONBLOCK){ ret = -EAGAIN; goto _OUT; }else{ ret = wait_event_interruptible(client->wait_q, !kfifo_is_empty(&client->fifo)); if(ret == -ERESTARTSYS) { EMD_MSG_INF("chr","Interrupted syscall.signal_pend=0x%llx\n", *(long long *)current->pending.signal.sig); ret = -EINTR; goto _OUT; } } } }while(ret==0); _OUT: return ret; }
/***************************************************************************** Syntax: void voice_buf_set_data_in_rtp_stream1 Remarks: set data on input RTP packet to FIFO buffer *******************************************************************************/ unsigned short voice_buf_get_data_in_rtp_stream1 (unsigned char *in_buf , int *in_size) { unsigned short j=0; //signed short empty; signed short state=0; // empty=kfifo_is_empty(&test); // printk(KERN_INFO "emty=%d\n\r",empty); if(kfifo_is_empty(&test)==1) { //printk("++++FIFO is EMPTY++++\n\r"); return 0;//FIFO is EMPTY } else { //get values into the fifo берём 4000 и если и сможем for (j = 0; j != in_size; j++) { state=kfifo_get(&test, &in_buf[j]); if(state==0) { return j; } //Добавлю ещё кусок работы по подсчёту раземера колчества байтов которые мы полуаем //printk("{%d|%d}",state,j); } return j; } }
static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, int urb_status, u32 tx_status) { if (urb_status) { WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); return false; } /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) { if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) { WARNING(rt2x00dev, "TX status FIFO overrun, " "drop tx status report.\n"); queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); } else return true; } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); } else if (rt2800usb_txstatus_pending(rt2x00dev)) { mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); } return false; }
static void delayedwork_callback(struct work_struct *work) { struct dj_receiver_dev *djrcv_dev = container_of(work, struct dj_receiver_dev, work); struct dj_report dj_report; unsigned long flags; int count; int retval; dbg_hid("%s\n", __func__); spin_lock_irqsave(&djrcv_dev->lock, flags); count = kfifo_out(&djrcv_dev->notif_fifo, &dj_report, sizeof(struct dj_report)); if (count != sizeof(struct dj_report)) { dev_err(&djrcv_dev->hdev->dev, "%s: workitem triggered without " "notifications available\n", __func__); spin_unlock_irqrestore(&djrcv_dev->lock, flags); return; } if (!kfifo_is_empty(&djrcv_dev->notif_fifo)) { if (schedule_work(&djrcv_dev->work) == 0) { dbg_hid("%s: did not schedule the work item, was " "already queued\n", __func__); } } spin_unlock_irqrestore(&djrcv_dev->lock, flags); switch (dj_report.report_type) { case REPORT_TYPE_NOTIF_DEVICE_PAIRED: logi_dj_recv_add_djhid_device(djrcv_dev, &dj_report); break; case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED: logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report); break; default: /* A normal report (i. e. not belonging to a pair/unpair notification) * arriving here, means that the report arrived but we did not have a * paired dj_device associated to the report's device_index, this * means that the original "device paired" notification corresponding * to this dj_device never arrived to this driver. The reason is that * hid-core discards all packets coming from a device while probe() is * executing. */ if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) { /* ok, we don't know the device, just re-ask the * receiver for the list of connected devices. */ retval = logi_dj_recv_query_paired_devices(djrcv_dev); if (!retval) { /* everything went fine, so just leave */ break; } dev_err(&djrcv_dev->hdev->dev, "%s:logi_dj_recv_query_paired_devices " "error:%d\n", __func__, retval); } dbg_hid("%s: unexpected report type\n", __func__); } }
/* * gs_start_tx * * This function finds available write requests, calls * gs_send_packet to fill these packets with data, and * continues until either there are no more write requests * available or no more data to send. This function is * run whenever data arrives or write requests are available. * * Context: caller owns port_lock; port_usb is non-null. */ static int gs_start_tx(struct gs_port *port) /* __releases(&port->port_lock) __acquires(&port->port_lock) */ { struct list_head *pool = &port->write_pool; struct usb_ep *in; int status = 0; bool do_tty_wake = false; if (!port->port_usb) return status; in = port->port_usb->in; while (!port->write_busy && !list_empty(pool)) { struct usb_request *req; int len; if (port->write_started >= QUEUE_SIZE) break; req = list_entry(pool->next, struct usb_request, list); len = gs_send_packet(port, req->buf, in->maxpacket); if (len == 0) { wake_up_interruptible(&port->drain_wait); break; } do_tty_wake = true; req->length = len; list_del(&req->list); req->zero = kfifo_is_empty(&port->port_write_buf); pr_vdebug("ttyGS%d: tx len=%d, 0x%02x 0x%02x 0x%02x ...\n", port->port_num, len, *((u8 *)req->buf), *((u8 *)req->buf+1), *((u8 *)req->buf+2)); /* Drop lock while we call out of driver; completions * could be issued while we do so. Disconnection may * happen too; maybe immediately before we queue this! * * NOTE that we may keep sending data for a while after * the TTY closed (dev->ioport->port_tty is NULL). */ port->write_busy = true; spin_unlock(&port->port_lock); status = usb_ep_queue(in, req, GFP_ATOMIC); spin_lock(&port->port_lock); port->write_busy = false; if (status) { pr_debug("%s: %s %s err %d\n", __func__, "queue", in->name, status); list_add(&req->list, pool); break; } port->write_started++; /* abort immediately after disconnect */ if (!port->port_usb) break; } if (do_tty_wake && port->port.tty) tty_wakeup(port->port.tty); return status; }
irqreturn_t interrupt_handler(int irq_no, void *data) { int device_status; uint32_t device_port = 0x0; /* * TODO: Write the code that handles a hardware interrupt. * TODO: Populate device_port with the port of the correct device. */ int ret = IRQ_HANDLED; if(irq_no == COM1_IRQ) { device_port = COM1_BASEPORT; } else if(irq_no == COM2_IRQ) { device_port = COM2_BASEPORT; } if(device_port) { disable_irq(irq_no); device_status = uart16550_hw_get_device_status(device_port); struct task_struct **task_user_get_data = ftask_user_get_data(data); struct task_struct **task_user_push_data = ftask_user_push_data(data); struct kfifo * data_from_user = fdata_from_user (data); struct kfifo * data_from_device = fdata_from_device (data); while (uart16550_hw_device_can_send(device_status) && !kfifo_is_empty(data_from_user)) { uint8_t byte_value; /* * TODO: Populate byte_value with the next value * from the kernel device outgoing buffer. */ kfifo_get(data_from_user,&byte_value); if(*task_user_push_data) wake_up_process(*task_user_push_data); uart16550_hw_write_to_device(device_port, byte_value); device_status = uart16550_hw_get_device_status(device_port); } while (uart16550_hw_device_has_data(device_status) && !kfifo_is_full(data_from_device)) { uint8_t byte_value; byte_value = uart16550_hw_read_from_device(device_port); /* * TODO: Store the read byte_value in the kernel device * incoming buffer. */ kfifo_put(data_from_device,byte_value); if(*task_user_get_data) wake_up_process(*task_user_get_data); device_status = uart16550_hw_get_device_status(device_port); } enable_irq(irq_no); } else { ret = -1; } return ret; }
/* * uart_device_read() - used for reading from the device buffer * to the userspace buffer */ static ssize_t uart_device_read(struct file *file, char __user *user_buffer, size_t size, loff_t *offset) { int bytes; unsigned char byte; unsigned long flags; size_t to_read; struct uart_device_data *dev_data = (struct uart_device_data *)file->private_data; size_t rb_len = kfifo_len(&dev_data->read_buffer); if (rb_len == 0) { /* * no dev_data available right now, try again later */ if (file->f_flags & O_NONBLOCK) { return -EAGAIN; } else { /* * enable Received dev_data Available Interrupt */ byte = inb(dev_data->base_addr + IER) | 1; outb(byte, dev_data->base_addr + IER); /* * wait until read buffer is not empty */ if (wait_event_interruptible(dev_data->read_wq, !kfifo_is_empty(&dev_data->read_buffer))) { return -ERESTARTSYS; } } } /* * save interrupts */ spin_lock_irqsave(&dev_data->read_lock, flags); /* * don't read more than read_buffer length */ rb_len = kfifo_len(&dev_data->read_buffer); if (size > rb_len) to_read = rb_len; else to_read = size; /* * copy dev_data in userspace buffer */ bytes = 0; while (bytes < to_read) { if (kfifo_get(&dev_data->read_buffer, &byte)) { if (put_user(byte, &user_buffer[bytes])) { spin_unlock_irqrestore(&dev_data->read_lock, flags); return -EFAULT; } bytes++; } } /* * restore interrupts */ spin_unlock_irqrestore(&dev_data->read_lock, flags); return to_read; }
/* * Interrupt functions. */ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) { struct ieee80211_conf conf = { .flags = 0 }; struct rt2x00lib_conf libconf = { .conf = &conf }; rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; struct queue_entry *entry; u32 status; u8 qid; int max_tx_done = 16; while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { /* Now remove the tx status from the FIFO */ if (kfifo_out(&rt2x00dev->txstatus_fifo, &status, sizeof(status)) != sizeof(status)) { WARN_ON(1); break; } qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); if (unlikely(qid >= QID_RX)) { /* * Unknown queue, this shouldn't happen. Just drop * this tx status. */ WARNING(rt2x00dev, "Got TX status report with " "unexpected pid %u, dropping\n", qid); break; } queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); if (unlikely(queue == NULL)) { /* * The queue is NULL, this shouldn't happen. Stop * processing here and drop the tx status */ WARNING(rt2x00dev, "Got TX status for an unavailable " "queue %u, dropping\n", qid); break; } if (unlikely(rt2x00queue_empty(queue))) { /* * The queue is empty. Stop processing here * and drop the tx status. */ WARNING(rt2x00dev, "Got TX status for an empty " "queue %u, dropping\n", qid); break; } entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); rt2800_txdone_entry(entry, status, rt2800pci_get_txwi(entry)); if (--max_tx_done == 0) break; } return !max_tx_done; } static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { u32 reg; /* * Enable a single interrupt. The interrupt mask register * access needs locking. */ spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 1); rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); }
static bool can_read(struct kfifo *queue){ return !kfifo_is_empty(queue);}
/** * drm_flip_work_cleanup - cleans up flip-work * @work: the flip-work to cleanup * * Destroy resources allocated for the flip-work */ void drm_flip_work_cleanup(struct drm_flip_work *work) { WARN_ON(!kfifo_is_empty(&work->fifo)); kfifo_free(&work->fifo); }
static int pi433_tx_thread(void *data) { struct pi433_device *device = data; struct spi_device *spi = device->spi; struct pi433_tx_cfg tx_cfg; size_t size; bool rx_interrupted = false; int position, repetitions; int retval; while (1) { /* wait for fifo to be populated or for request to terminate*/ dev_dbg(device->dev, "thread: going to wait for new messages"); wait_event_interruptible(device->tx_wait_queue, (!kfifo_is_empty(&device->tx_fifo) || kthread_should_stop())); if (kthread_should_stop()) return 0; /* * get data from fifo in the following order: * - tx_cfg * - size of message * - message */ retval = kfifo_out(&device->tx_fifo, &tx_cfg, sizeof(tx_cfg)); if (retval != sizeof(tx_cfg)) { dev_dbg(device->dev, "reading tx_cfg from fifo failed: got %d byte(s), expected %d", retval, (unsigned int)sizeof(tx_cfg)); continue; } retval = kfifo_out(&device->tx_fifo, &size, sizeof(size_t)); if (retval != sizeof(size_t)) { dev_dbg(device->dev, "reading msg size from fifo failed: got %d, expected %d", retval, (unsigned int)sizeof(size_t)); continue; } /* use fixed message length, if requested */ if (tx_cfg.fixed_message_length != 0) size = tx_cfg.fixed_message_length; /* increase size, if len byte is requested */ if (tx_cfg.enable_length_byte == OPTION_ON) size++; /* increase size, if adr byte is requested */ if (tx_cfg.enable_address_byte == OPTION_ON) size++; /* prime buffer */ memset(device->buffer, 0, size); position = 0; /* add length byte, if requested */ if (tx_cfg.enable_length_byte == OPTION_ON) /* * according to spec, length byte itself must be * excluded from the length calculation */ device->buffer[position++] = size - 1; /* add adr byte, if requested */ if (tx_cfg.enable_address_byte == OPTION_ON) device->buffer[position++] = tx_cfg.address_byte; /* finally get message data from fifo */ retval = kfifo_out(&device->tx_fifo, &device->buffer[position], sizeof(device->buffer) - position); dev_dbg(device->dev, "read %d message byte(s) from fifo queue.", retval); /* * if rx is active, we need to interrupt the waiting for * incoming telegrams, to be able to send something. * We are only allowed, if currently no reception takes * place otherwise we need to wait for the incoming telegram * to finish */ wait_event_interruptible(device->tx_wait_queue, !device->rx_active || device->interrupt_rx_allowed); /* * prevent race conditions * irq will be reenabled after tx config is set */ disable_irq(device->irq_num[DIO0]); device->tx_active = true; /* clear fifo, set fifo threshold, set payload length */ retval = rf69_set_mode(spi, standby); /* this clears the fifo */ if (retval < 0) return retval; if (device->rx_active && !rx_interrupted) { /* * rx is currently waiting for a telegram; * we need to set the radio module to standby */ rx_interrupted = true; } retval = rf69_set_fifo_threshold(spi, FIFO_THRESHOLD); if (retval < 0) return retval; if (tx_cfg.enable_length_byte == OPTION_ON) { retval = rf69_set_payload_length(spi, size * tx_cfg.repetitions); if (retval < 0) return retval; } else { retval = rf69_set_payload_length(spi, 0); if (retval < 0) return retval; } /* configure the rf chip */ retval = rf69_set_tx_cfg(device, &tx_cfg); if (retval < 0) return retval; /* enable fifo level interrupt */ retval = rf69_set_dio_mapping(spi, DIO1, DIO_FIFO_LEVEL); if (retval < 0) return retval; device->irq_state[DIO1] = DIO_FIFO_LEVEL; irq_set_irq_type(device->irq_num[DIO1], IRQ_TYPE_EDGE_FALLING); /* enable packet sent interrupt */ retval = rf69_set_dio_mapping(spi, DIO0, DIO_PACKET_SENT); if (retval < 0) return retval; device->irq_state[DIO0] = DIO_PACKET_SENT; irq_set_irq_type(device->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); enable_irq(device->irq_num[DIO0]); /* was disabled by rx active check */ /* enable transmission */ retval = rf69_set_mode(spi, transmit); if (retval < 0) return retval; /* transfer this msg (and repetitions) to chip fifo */ device->free_in_fifo = FIFO_SIZE; position = 0; repetitions = tx_cfg.repetitions; while ((repetitions > 0) && (size > position)) { if ((size - position) > device->free_in_fifo) { /* msg to big for fifo - take a part */ int write_size = device->free_in_fifo; device->free_in_fifo = 0; rf69_write_fifo(spi, &device->buffer[position], write_size); position += write_size; } else { /* msg fits into fifo - take all */ device->free_in_fifo -= size; repetitions--; rf69_write_fifo(spi, &device->buffer[position], (size - position)); position = 0; /* reset for next repetition */ } retval = wait_event_interruptible(device->fifo_wait_queue, device->free_in_fifo > 0); if (retval) { dev_dbg(device->dev, "ABORT\n"); goto abort; } } /* we are done. Wait for packet to get sent */ dev_dbg(device->dev, "thread: wait for packet to get sent/fifo to be empty"); wait_event_interruptible(device->fifo_wait_queue, device->free_in_fifo == FIFO_SIZE || kthread_should_stop()); if (kthread_should_stop()) return 0; /* STOP_TRANSMISSION */ dev_dbg(device->dev, "thread: Packet sent. Set mode to stby."); retval = rf69_set_mode(spi, standby); if (retval < 0) return retval; /* everything sent? */ if (kfifo_is_empty(&device->tx_fifo)) { abort: if (rx_interrupted) { rx_interrupted = false; pi433_start_rx(device); } device->tx_active = false; wake_up_interruptible(&device->rx_wait_queue); } } }