static int __init testfunc(void) { unsigned char buf[6]; unsigned char i, j; unsigned int ret; printk(KERN_INFO "[fifo]byte stream fifo test start\n"); /* put string into the fifo */ kfifo_in(&test, "hello", 5); /* put values into the fifo */ for (i = 0; i != 10; i++) kfifo_put(&test, &i); /* show the number of used elements */ printk(KERN_INFO "[fifo]fifo len: %u\n", kfifo_len(&test)); /* get max of 5 bytes from the fifo */ i = kfifo_out(&test, buf, 5); printk(KERN_INFO "[fifo]buf: %.*s\n", i, buf); /* get max of 2 elements from the fifo */ ret = kfifo_out(&test, buf, 2); printk(KERN_INFO "[fifo]ret: %d\n", ret); /* and put it back to the end of the fifo */ ret = kfifo_in(&test, buf, ret); printk(KERN_INFO "[fifo]ret: %d\n", ret); /* skip first element of the fifo */ printk(KERN_INFO "[fifo]skip 1st element\n"); kfifo_skip(&test); /* put values into the fifo until is full */ for (i = 20; kfifo_put(&test, &i); i++) ; printk(KERN_INFO "[fifo]queue len: %u\n", kfifo_len(&test)); /* show the first value without removing from the fifo */ if (kfifo_peek(&test, &i)) printk(KERN_INFO "[fifo]%d\n", i); /* check the correctness of all values in the fifo */ j = 0; while (kfifo_get(&test, &i)) { printk(KERN_INFO "item = %d\n", i); if (i != expected_result[j++]) { printk(KERN_WARNING "value mismatch: test failed\n"); return -EIO; } } if (j != ARRAY_SIZE(expected_result)) { printk(KERN_WARNING "size mismatch: test failed\n"); return -EIO; } printk(KERN_INFO "[fifo]test passed\n"); return 0; }
/* * Read a fifo in 4 bytes chunks. * If input doesn't fit the buffer, it places bytes of last dword in spill * buffer, so that they don't get lost on last read, just throw these away. */ static void r592_read_fifo_pio(struct r592_device *dev, unsigned char *buffer, int len) { u8 tmp[4]; /* Read from last spill */ if (!kfifo_is_empty(&dev->pio_fifo)) { int bytes_copied = kfifo_out(&dev->pio_fifo, buffer, min(4, len)); buffer += bytes_copied; len -= bytes_copied; if (!kfifo_is_empty(&dev->pio_fifo)) return; } /* Reads dwords from FIFO */ while (len >= 4) { *(u32 *)buffer = r592_read_reg_raw_be(dev, R592_FIFO_PIO); buffer += 4; len -= 4; } if (len) { *(u32 *)tmp = r592_read_reg_raw_be(dev, R592_FIFO_PIO); kfifo_in(&dev->pio_fifo, tmp, 4); len -= kfifo_out(&dev->pio_fifo, buffer, len); } WARN_ON(len); return; }
static int __init testfunc(void) { char buf[100]; unsigned int i; unsigned int ret; struct { unsigned char buf[6]; } hello = { "hello" }; printk(KERN_INFO "record fifo test start\n"); kfifo_in(&test, &hello, sizeof(hello)); /* show the size of the next record in the fifo */ printk(KERN_INFO "fifo peek len: %u\n", kfifo_peek_len(&test)); /* put in variable length data */ for (i = 0; i < 10; i++) { memset(buf, 'a' + i, i + 1); kfifo_in(&test, buf, i + 1); } printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); /* show the first record without removing from the fifo */ ret = kfifo_out_peek(&test, buf, sizeof(buf)); if (ret) printk(KERN_INFO "%.*s\n", ret, buf); /* print out all records in the fifo */ while (!kfifo_is_empty(&test)) { ret = kfifo_out(&test, buf, sizeof(buf)); printk(KERN_INFO "%.*s\n", ret, buf); } return 0; }
/*----------------------------------------------------------------------------*/ static ssize_t bow_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos) { UINT_8 aucBuffer[MAX_BUFFER_SIZE]; ssize_t retval; P_GLUE_INFO_T prGlueInfo; prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ASSERT(prGlueInfo); if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->u4Flag & GLUE_FLAG_HALT)) { return -EFAULT; } /* size check */ /* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size) retval = size; else retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); /* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */ /* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ /* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) retval = -EIO; if (copy_to_user(buf, aucBuffer, retval)) retval = -EIO; return retval; }
static int ir_raw_event_thread(void *data) { struct ir_raw_event ev; struct ir_raw_handler *handler; struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; int retval; while (!kthread_should_stop()) { spin_lock_irq(&raw->lock); retval = kfifo_len(&raw->kfifo); if (retval < sizeof(ev)) { set_current_state(TASK_INTERRUPTIBLE); if (kthread_should_stop()) set_current_state(TASK_RUNNING); spin_unlock_irq(&raw->lock); schedule(); continue; } retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); spin_unlock_irq(&raw->lock); mutex_lock(&ir_raw_handler_lock); list_for_each_entry(handler, &ir_raw_handler_list, list) handler->decode(raw->dev, ev); raw->prev_ev = ev; mutex_unlock(&ir_raw_handler_lock); } return 0; }
int test(void) { struct kfifo fifo; int ret, tam; char *buf; /* Inicializo la cola y compruebo errores */ ret = kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL); if (ret) { printk(KERN_ERR "error kfifo_alloc\n"); return ret; } /* Introduzco la cadena Hello en la cola */ kfifo_in(&fifo, "Hello", 5); /* Introduzco la cadena LIN de la cola */ kfifo_in(&fifo, "LIN", 3); /* Extraigo la cadena Hello de la cola */ tam = kfifo_out(&fifo, buf, 5); printk(KERN_INFO "%s", buf); /* Devuelvo la cadena LIN sin extraerla de la cola */ if (kfifo_peek(&test, buf)) printk(KERN_INFO " %s\n", buf); /* Elimino la cola */ kfifo_free(&test); return 0; }
static int ir_raw_event_thread(void *data) { struct ir_raw_event ev; struct ir_raw_handler *handler; struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; while (!kthread_should_stop()) { try_to_freeze(); mutex_lock(&ir_raw_handler_lock); while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) { list_for_each_entry(handler, &ir_raw_handler_list, list) handler->decode(raw->input_dev, ev); raw->prev_ev = ev; } mutex_unlock(&ir_raw_handler_lock); set_current_state(TASK_INTERRUPTIBLE); schedule(); } return 0; }
int get_logic_ch_data(logic_channel_info_t *ch_info, ccci_msg_t *msg) { if (unlikely(ch_info == NULL)){ CCCI_MSG("%s fail: get invalid ch info\n", __FUNCTION__); return -CCCI_ERR_GET_NULL_POINTER; } if (unlikely(ch_info->m_attrs&L_CH_ATTR_TX)){ CCCI_MSG_INF(ch_info->m_md_id, "cci", "%s fail: %s(ch%d) is tx \n", \ __FUNCTION__, ch_info->m_ch_name, msg->channel); return -CCCI_ERR_GET_RX_DATA_FROM_TX_CHANNEL; } // check whether fifo is ready if (unlikely(!ch_info->m_kfifo_ready)){ CCCI_MSG_INF(ch_info->m_md_id, "cci", "%s fail: %s(ch%d) kfifo not ready\n", \ __FUNCTION__, ch_info->m_ch_name, msg->channel); return -CCCI_ERR_KFIFO_IS_NOT_READY; } // Check fifo if has data if (kfifo_is_empty(&ch_info->m_kfifo)) { return 0; } // Pop data return kfifo_out(&ch_info->m_kfifo, msg, sizeof(ccif_msg_t)); }
int main(void) { struct kfifo fck; struct kfifo *fifo = &fck; int tmp, array[256]; int out[256]; int i; tmp = kfifo_alloc(fifo, 256, sizeof(int)); printf("\nkfifo_alloc ret = %d\n", tmp); kfifo_disp_info(fifo); for(i = 0; i < ARRAY_SIZE(array); i++) array[i] = i; // for(i = 0; i < 100; i++) tmp = kfifo_in(fifo, array, 100); printf("\nkfifo_in ret = %d\n", tmp); kfifo_disp_info(fifo); tmp = kfifo_out(fifo, out, 10); printf("\nkfifo_out ret = %d\n", tmp); kfifo_disp_info(fifo); for(i = 0; i < 10; i++) printf("out[%d]= %d\n", i, out[i]); kfifo_free(fifo); return 0; }
/** * iscsi_tcp_cleanup_task - free tcp_task resources * @task: iscsi task * * must be called with session back_lock */ void iscsi_tcp_cleanup_task(struct iscsi_task *task) { struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_r2t_info *r2t; /* nothing to do for mgmt */ if (!task->sc) return; spin_lock_bh(&tcp_task->queue2pool); /* flush task's r2t queues */ while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); } r2t = tcp_task->r2t; if (r2t != NULL) { kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); tcp_task->r2t = NULL; } spin_unlock_bh(&tcp_task->queue2pool); }
/* * Return 1 - send buffer to card and ack. * Return 0 - don't ack, don't send buffer to card. */ static int send_data(enum port_type index, struct nozomi *dc) { u32 size = 0; struct port *port = &dc->port[index]; const u8 toggle = port->toggle_ul; void __iomem *addr = port->ul_addr[toggle]; const u32 ul_size = port->ul_size[toggle]; /* Get data from tty and place in buf for now */ size = kfifo_out(&port->fifo_ul, dc->send_buf, ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); if (size == 0) { DBG4("No more data to send, disable link:"); return 0; } /* DUMP(buf, size); */ /* Write length + data */ write_mem32(addr, (u32 *) &size, 4); write_mem32(addr + 4, (u32 *) dc->send_buf, size); tty_port_tty_wakeup(&port->port); return 1; }
static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) { struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_r2t_info *r2t = NULL; if (iscsi_task_has_unsol_data(task)) r2t = &task->unsol_r2t; else { spin_lock_bh(&tcp_task->queue2pool); if (tcp_task->r2t) { r2t = tcp_task->r2t; /* Continue with this R2T? */ if (r2t->data_length <= r2t->sent) { ISCSI_DBG_TCP(task->conn, " done with r2t %p\n", r2t); kfifo_in(&tcp_task->r2tpool.queue, (void *)&tcp_task->r2t, sizeof(void *)); tcp_task->r2t = r2t = NULL; } } if (r2t == NULL) { if (kfifo_out(&tcp_task->r2tqueue, (void *)&tcp_task->r2t, sizeof(void *)) != sizeof(void *)) r2t = NULL; else r2t = tcp_task->r2t; } spin_unlock_bh(&tcp_task->queue2pool); } return r2t; }
static void stp_uart_rx_handling(unsigned long func_data){ unsigned int how_much_get = 0; unsigned int how_much_to_get = 0; unsigned int flag = 0; // read_lock(&g_stp_uart_rx_handling_lock); how_much_to_get = kfifo_len(g_stp_uart_rx_fifo); if (how_much_to_get >= RX_BUFFER_LEN) { flag = 1; UART_INFO_FUNC ("fifolen(%d)\n", how_much_to_get); } do{ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) how_much_get= kfifo_get(g_stp_uart_rx_fifo, g_rx_data, RX_BUFFER_LEN); #else how_much_get= kfifo_out(g_stp_uart_rx_fifo, g_rx_data, RX_BUFFER_LEN); #endif //UART_INFO_FUNC ("fifoget(%d)\n", how_much_get); mtk_wcn_stp_parser_data((UINT8 *)g_rx_data, how_much_get); how_much_to_get = kfifo_len(g_stp_uart_rx_fifo); }while(how_much_to_get > 0); // read_unlock(&g_stp_uart_rx_handling_lock); if (1 == flag) { UART_INFO_FUNC ("finish, fifolen(%d)\n", kfifo_len(g_stp_uart_rx_fifo)); } }
/* * Writes the FIFO in 4 byte chunks. * If length isn't 4 byte aligned, rest of the data if put to a fifo * to be written later * Use r592_flush_fifo_write to flush that fifo when writing for the * last time */ static void r592_write_fifo_pio(struct r592_device *dev, unsigned char *buffer, int len) { /* flush spill from former write */ if (!kfifo_is_empty(&dev->pio_fifo)) { u8 tmp[4] = {0}; int copy_len = kfifo_in(&dev->pio_fifo, buffer, len); if (!kfifo_is_full(&dev->pio_fifo)) return; len -= copy_len; buffer += copy_len; copy_len = kfifo_out(&dev->pio_fifo, tmp, 4); WARN_ON(copy_len != 4); r592_write_reg_raw_be(dev, R592_FIFO_PIO, *(u32 *)tmp); } WARN_ON(!kfifo_is_empty(&dev->pio_fifo)); /* write full dwords */ while (len >= 4) { r592_write_reg_raw_be(dev, R592_FIFO_PIO, *(u32 *)buffer); buffer += 4; len -= 4; } /* put remaining bytes to the spill */ if (len) kfifo_in(&dev->pio_fifo, buffer, len); }
static int ir_raw_event_thread(void *data) { struct ir_raw_event ev; struct ir_raw_handler *handler; struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; while (1) { mutex_lock(&ir_raw_handler_lock); while (kfifo_out(&raw->kfifo, &ev, 1)) { list_for_each_entry(handler, &ir_raw_handler_list, list) if (raw->dev->enabled_protocols & handler->protocols || !handler->protocols) handler->decode(raw->dev, ev); raw->prev_ev = ev; } mutex_unlock(&ir_raw_handler_lock); set_current_state(TASK_INTERRUPTIBLE); if (kthread_should_stop()) { __set_current_state(TASK_RUNNING); break; } else if (!kfifo_is_empty(&raw->kfifo)) set_current_state(TASK_RUNNING); schedule(); } return 0; }
/* * Message receiver(workqueue) */ static void mbox_rx_work(struct work_struct *work) { struct omap_mbox_queue *mq = container_of(work, struct omap_mbox_queue, work); mbox_msg_t msg; int len; while (kfifo_len(&mq->fifo) >= sizeof(msg)) { len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); blocking_notifier_call_chain(&mq->mbox->notifier, len, (void *)msg); spin_lock_irq(&mq->lock); if (mq->full) { mq->full = false; if (!mbox_fifo_empty(mq->mbox)) { msg = mbox_fifo_read(mq->mbox); len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); /* WARN_ON(len != sizeof(msg));*/ } omap_mbox_enable_irq(mq->mbox, IRQ_RX); } spin_unlock_irq(&mq->lock); } }
int u2k_read(void) { int ret, count; spin_lock_irqsave(&fifo_k2u_lock, flags_k2u); count = kfifo_out(&u2k_fifo, &ret, sizeof(int)); spin_unlock_irqrestore(&fifo_k2u_lock, flags_k2u); return ret; }
static ssize_t ssp_sensorhub_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { struct ssp_sensorhub_data *hub_data = container_of(file->private_data, struct ssp_sensorhub_data, sensorhub_device); struct sensorhub_event *event; int retries = MAX_DATA_COPY_TRY; int length = 0; int ret = 0; spin_lock_bh(&hub_data->sensorhub_lock); if (unlikely(kfifo_is_empty(&hub_data->fifo))) { sensorhub_info("no library data"); goto err; } /* first in first out */ ret = kfifo_out_peek(&hub_data->fifo, &event, sizeof(void *)); if (unlikely(!ret)) { sensorhub_err("kfifo out peek err(%d)", ret); ret = EIO; goto err; } length = event->library_length; while (retries--) { ret = copy_to_user(buf, event->library_data, event->library_length); if (likely(!ret)) break; } if (unlikely(ret)) { sensorhub_err("read library data err(%d)", ret); goto err; } ssp_sensorhub_log(__func__, event->library_data, event->library_length); /* remove first event from the list */ ret = kfifo_out(&hub_data->fifo, &event, sizeof(void *)); if (unlikely(ret != sizeof(void *))) { sensorhub_err("kfifo out err(%d)", ret); ret = EIO; goto err; } complete(&hub_data->read_done); spin_unlock_bh(&hub_data->sensorhub_lock); return length; err: spin_unlock_bh(&hub_data->sensorhub_lock); return ret ? -ret : 0; }
/***************************************************************************** * FUNCTION * btif_tx_irq_handler * DESCRIPTION * lower level tx interrupt handler * PARAMETERS * p_base [IN] BTIF module's base address * p_buf [IN/OUT] pointer to rx data buffer * max_len [IN] max length of rx buffer * RETURNS * 0 means success, negative means fail *****************************************************************************/ static int btif_tx_irq_handler (P_MTK_BTIF_INFO_STR p_btif) { int i_ret = -1; #if NEW_TX_HANDLING_SUPPORT int how_many = 0; unsigned int lsr; unsigned int ava_len = 0; unsigned int base = p_btif->base; char local_buf[BTIF_TX_FIFO_SIZE]; char *p_data = local_buf; unsigned long flag = 0; struct kfifo *p_tx_fifo = p_btif->p_tx_fifo; /*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ lsr = BTIF_READ32(BTIF_LSR(base)); if (lsr & BTIF_LSR_TEMT_BIT) { /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ ava_len = BTIF_TX_FIFO_SIZE; } else if (lsr & BTIF_LSR_THRE_BIT) { /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; }else { /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ ava_len = 0; goto ret; } spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); how_many = kfifo_out(p_tx_fifo, local_buf, ava_len); spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); BTIF_DBG_FUNC("BTIF tx size %d done, left:%d\n", how_many, kfifo_avail(p_tx_fifo)); while (how_many--) { btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); } spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); /*clear Tx enable flag if necessary*/ if (kfifo_is_empty(p_tx_fifo)){ hal_btif_tx_ier_ctrl(p_btif, false); BTIF_DBG_FUNC("BTIF tx FIFO is empty\n"); } spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); ret: #else /*clear Tx enable flag*/ hal_btif_tx_ier_ctrl(p_btif, false); #endif i_ret = 0; return i_ret; }
/** * KFIFO에서 TCP/IP데이터를 반환하는 함수.(심볼로 선언해서 다른 Kernel Module에서 호출하여 사용함) */ int get_kfifo(char *msg) { if(kfifo_len(&fifo) <= 0) { msg = 0; return 0; } kfifo_out(&fifo, msg, SIZE); return 1; }
static int __init testfunc(void) { unsigned char buf[6]; unsigned char i; unsigned int ret; printk(KERN_INFO "byte stream fifo test start\n"); /* put string into the fifo */ kfifo_in(&test, "hello", 5); /* put values into the fifo */ for (i = 0; i != 10; i++) kfifo_put(&test, &i); /* show the number of used elements */ printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); /* get max of 5 bytes from the fifo */ i = kfifo_out(&test, buf, 5); printk(KERN_INFO "buf: %.*s\n", i, buf); /* get max of 2 elements from the fifo */ ret = kfifo_out(&test, buf, 2); printk(KERN_INFO "ret: %d\n", ret); /* and put it back to the end of the fifo */ ret = kfifo_in(&test, buf, ret); printk(KERN_INFO "ret: %d\n", ret); /* put values into the fifo until is full */ for (i = 20; kfifo_put(&test, &i); i++) ; printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); /* print out all values in the fifo */ while (kfifo_get(&test, &i)) printk("%d ", i); printk("\n"); return 0; }
/* Flushes the temporary FIFO used to make aligned DWORD writes */ static void r592_flush_fifo_write(struct r592_device *dev) { u8 buffer[4] = { 0 }; int len; if (kfifo_is_empty(&dev->pio_fifo)) return; len = kfifo_out(&dev->pio_fifo, buffer, 4); r592_write_reg_raw_be(dev, R592_FIFO_PIO, *(u32 *)buffer); }
static int pop_data(emd_dev_client_t *client, int *buf) { int ret = 0; if(!kfifo_is_empty(&client->fifo)) { ret = kfifo_out(&client->fifo, buf, sizeof(int)); EMD_MSG_INF("chr","pop data=0x%08x from sub_dev%d kfifo.\n",*buf,client->sub_dev_id); } return ret; }
static int __init testfunc(void) { int buf[6]; int i, j; unsigned int ret; printk(KERN_INFO "int fifo test start\n"); for (i = 0; i != 10; i++) kfifo_put(&test, &i); printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); ret = kfifo_out(&test, buf, 2); printk(KERN_INFO "ret: %d\n", ret); ret = kfifo_in(&test, buf, ret); printk(KERN_INFO "ret: %d\n", ret); printk(KERN_INFO "skip 1st element\n"); kfifo_skip(&test); for (i = 20; kfifo_put(&test, &i); i++) ; printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); if (kfifo_peek(&test, &i)) printk(KERN_INFO "%d\n", i); j = 0; while (kfifo_get(&test, &i)) { printk(KERN_INFO "item = %d\n", i); if (i != expected_result[j++]) { printk(KERN_WARNING "value mismatch: test failed\n"); return -EIO; } } if (j != ARRAY_SIZE(expected_result)) { printk(KERN_WARNING "size mismatch: test failed\n"); return -EIO; } printk(KERN_INFO "test passed\n"); return 0; }
/* * gs_send_packet * * If there is data to send, a packet is built in the given * buffer and the size is returned. If there is no data to * send, 0 is returned. * * Called with port_lock held. */ static unsigned gs_send_packet(struct gs_port *port, char *packet, unsigned size) { unsigned len; len = kfifo_len(&port->port_write_buf); if (len < size) size = len; if (size != 0) size = kfifo_out(&port->port_write_buf, packet, size); return size; }
static int rk3190_mbox_msg_get(struct ipc_mbox* imb, u32 *msg) { struct rk3190_mbox *pmb = (struct rk3190_mbox *)imb; int len; if (kfifo_len(&pmb->in_fifo) >= sizeof(u32)) { len = kfifo_out((&pmb->in_fifo), (unsigned char*)msg, sizeof(u32)); WARN_ON(len != sizeof(u32)); return 0; } return -1; }
static int gs_console_thread(void *data) { struct gscons_info *info = &gscons_info; struct gs_port *port; struct usb_request *req; struct usb_ep *ep; int xfer, ret, count, size; do { port = info->port; set_current_state(TASK_INTERRUPTIBLE); if (!port || !port->port_usb || !port->port_usb->in || !info->console_req) goto sched; req = info->console_req; ep = port->port_usb->in; spin_lock_irq(&info->con_lock); count = kfifo_len(&info->con_buf); size = ep->maxpacket; if (count > 0 && !info->req_busy) { set_current_state(TASK_RUNNING); if (count < size) size = count; xfer = kfifo_out(&info->con_buf, req->buf, size); req->length = xfer; spin_unlock(&info->con_lock); ret = usb_ep_queue(ep, req, GFP_ATOMIC); spin_lock(&info->con_lock); if (ret < 0) info->req_busy = 0; else info->req_busy = 1; spin_unlock_irq(&info->con_lock); } else { spin_unlock_irq(&info->con_lock); sched: if (kthread_should_stop()) { set_current_state(TASK_RUNNING); break; } schedule(); } } while (1); return 0; }
static int ssp_sensorhub_list(struct ssp_sensorhub_data *hub_data, char *dataframe, int length) { struct sensorhub_event *event; int ret = 0; if (unlikely(length <= 0 || length >= PAGE_SIZE)) { sensorhub_err("library length err(%d)", length); return -EINVAL; } ssp_sensorhub_log(__func__, dataframe, length); /* overwrite new event if list is full */ if (unlikely(kfifo_is_full(&hub_data->fifo))) { ret = kfifo_out(&hub_data->fifo, &event, sizeof(void *)); if (unlikely(ret != sizeof(void *))) { sensorhub_err("kfifo out err(%d)", ret); return -EIO; } sensorhub_info("overwrite event"); } /* allocate memory for new event */ kfree(hub_data->events[hub_data->event_number].library_data); hub_data->events[hub_data->event_number].library_data = kzalloc(length * sizeof(char), GFP_ATOMIC); if (unlikely(!hub_data->events[hub_data->event_number].library_data)) { sensorhub_err("allocate memory for library err"); return -ENOMEM; } /* copy new event into memory */ memcpy(hub_data->events[hub_data->event_number].library_data, dataframe, length); hub_data->events[hub_data->event_number].library_length = length; /* add new event into the end of list */ event = &hub_data->events[hub_data->event_number]; ret = kfifo_in(&hub_data->fifo, &event, sizeof(void *)); if (unlikely(ret != sizeof(void *))) { sensorhub_err("kfifo in err(%d)", ret); return -EIO; } /* not to overflow max list capacity */ if (hub_data->event_number++ >= LIST_SIZE - 1) hub_data->event_number = 0; return kfifo_len(&hub_data->fifo) / sizeof(void *); }
/* * Message receiver(workqueue) */ static void mbox_rx_work(struct work_struct *work) { struct omap_mbox_queue *mq = container_of(work, struct omap_mbox_queue, work); mbox_msg_t msg; int len; while (kfifo_len(&mq->fifo) >= sizeof(msg)) { len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); if (mq->callback) mq->callback((void *)msg); } }
// read from kernel to user int k2u_read(void) { int ret, count; spin_lock_irqsave(&fifo_k2u_lock, flags_k2u); if(kfifo_is_empty(&k2u_fifo)) { ret = SERVICER_DONOTHING; } else { count = kfifo_out(&k2u_fifo, &ret, sizeof(int)); } spin_unlock_irqrestore(&fifo_k2u_lock, flags_k2u); return ret; }