/* * message sender */ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) { struct omap_mbox_queue *mq = mbox->txq; int ret = 0, len; spin_lock_bh(&mq->lock); if ((FIFO_SIZE - (__kfifo_len(mq->fifo))) < sizeof(msg)) { ret = -ENOMEM; goto out; } if (!__kfifo_len(mq->fifo)) { if (!mbox_fifo_full(mbox)) { if (mbox->txq->callback) ret = mbox->txq->callback(NULL); mbox_fifo_write(mbox, msg); goto out; } } len = __kfifo_put(mq->fifo, (unsigned char *)&msg, sizeof(msg)); if (unlikely(len != sizeof(msg))) { pr_err("%s: __kfifo_put anomaly detected\n", __func__); ret = -ENOMEM; } tasklet_schedule(&mbox->txq->tasklet); out: spin_unlock_bh(&mq->lock); return ret; }
/** * iscsi_tcp_task_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands * @conn: iscsi connection * @task: scsi command task * @sc: scsi command */ int iscsi_tcp_task_init(struct iscsi_task *task) { struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_conn *conn = task->conn; struct scsi_cmnd *sc = task->sc; int err; if (!sc) { /* * mgmt tasks do not have a scatterlist since they come * in from the iscsi interface. */ ISCSI_DBG_TCP(conn, "mtask deq [itt 0x%x]\n", task->itt); return conn->session->tt->init_pdu(task, 0, task->data_count); } BUG_ON(__kfifo_len(tcp_task->r2tqueue)); tcp_task->exp_datasn = 0; /* Prepare PDU, optionally w/ immediate data */ ISCSI_DBG_TCP(conn, "task deq [itt 0x%x imm %d unsol %d]\n", task->itt, task->imm_count, task->unsol_r2t.data_length); err = conn->session->tt->init_pdu(task, 0, task->imm_count); if (err) return err; task->imm_count = 0; return 0; }
static ssize_t tcpprobe_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { int error = 0, cnt = 0; unsigned char *tbuf; if (!buf || len < 0) return -EINVAL; if (len == 0) return 0; tbuf = vmalloc(len); if (!tbuf) return -ENOMEM; error = wait_event_interruptible(tcpw.wait, __kfifo_len(tcpw.fifo) != 0); if (error) goto out_free; cnt = kfifo_get(tcpw.fifo, tbuf, len); error = copy_to_user(buf, tbuf, cnt); out_free: vfree(tbuf); return error ? error : cnt; }
static void rfbi_push_cmd(struct update_param *p) { int ret; while (1) { unsigned long flags; int available; spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); available = RFBI_CMD_FIFO_LEN_BYTES - __kfifo_len(rfbi.cmd_fifo); /* DSSDBG("%d bytes left in fifo\n", available); */ if (available < sizeof(struct update_param)) { DSSDBG("Going to wait because FIFO FULL..\n"); spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); atomic_inc(&rfbi.cmd_fifo_full); wait_for_completion(&rfbi.cmd_done); /*DSSDBG("Woke up because fifo not full anymore\n");*/ continue; } ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p, sizeof(struct update_param)); /* DSSDBG("pushed %d bytes\n", ret);*/ spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); BUG_ON(ret != sizeof(struct update_param)); break; } }
static void __mbox_rx_interrupt(struct omap_mbox *mbox) { struct omap_mbox_queue *mq = mbox->rxq; mbox_msg_t msg; int len; while (!mbox_fifo_empty(mbox)) { if (unlikely(__kfifo_len(mq->fifo) >= FIFO_SIZE - sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); rq_full = true; goto nomem; } msg = mbox_fifo_read(mbox); len = __kfifo_put(mq->fifo, (unsigned char *)&msg, sizeof(msg)); if (unlikely(len != sizeof(msg))) pr_err("%s: __kfifo_put anomaly detected\n", __func__); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; } /* no more messages in the fifo. clear IRQ source. */ ack_mbox_irq(mbox, IRQ_RX); nomem: queue_work(mboxd, &mbox->rxq->work); }
/** * usb_serial_generic_write_start - kick off an URB write * @port: Pointer to the &struct usb_serial_port data * * Returns the number of bytes queued on success. This will be zero if there * was nothing to send. Otherwise, it returns a negative errno value */ static int usb_serial_generic_write_start(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; unsigned char *data; int result; int count; unsigned long flags; bool start_io; /* Atomically determine whether we can and need to start a USB * operation. */ spin_lock_irqsave(&port->lock, flags); if (port->write_urb_busy) start_io = false; else { start_io = (__kfifo_len(port->write_fifo) != 0); port->write_urb_busy = start_io; } spin_unlock_irqrestore(&port->lock, flags); if (!start_io) return 0; data = port->write_urb->transfer_buffer; count = kfifo_get(port->write_fifo, data, port->bulk_out_size); usb_serial_debug_data(debug, &port->dev, __func__, count, data); /* set up our urb */ usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, count, ((serial->type->write_bulk_callback) ? serial->type->write_bulk_callback : usb_serial_generic_write_bulk_callback), port); /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); /* don't have to grab the lock here, as we will retry if != 0 */ port->write_urb_busy = 0; } else result = count; return result; }
int usb_serial_generic_write_room(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; unsigned long flags; int room = 0; dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&port->lock, flags); if (serial->type->max_in_flight_urbs) { if (port->urbs_in_flight < serial->type->max_in_flight_urbs) room = port->bulk_out_size * (serial->type->max_in_flight_urbs - port->urbs_in_flight); } else if (serial->num_bulk_out) room = port->write_fifo->size - __kfifo_len(port->write_fifo); spin_unlock_irqrestore(&port->lock, flags); dbg("%s - returns %d", __func__, room); return room; }
static void mbox_tx_tasklet(unsigned long tx_data) { struct omap_mbox *mbox = (struct omap_mbox *)tx_data; struct omap_mbox_queue *mq = mbox->txq; mbox_msg_t msg; int ret; while (__kfifo_len(mq->fifo)) { if (mbox_fifo_full(mbox)) { omap_mbox_enable_irq(mbox, IRQ_TX); break; } ret = __kfifo_get(mq->fifo, (unsigned char *)&msg, sizeof(msg)); if (unlikely(ret != sizeof(msg))) pr_err("%s: __kfifo_get anomaly\n", __func__); if (mbox->txq->callback) ret = mbox->txq->callback(NULL); mbox_fifo_write(mbox, msg); } }
/* * 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 = 0; struct omap_mbox *mbox = mq->mbox; while (__kfifo_len(mq->fifo) >= sizeof(msg)) { len = __kfifo_get(mq->fifo, (unsigned char *)&msg, sizeof(msg)); if (unlikely(len != sizeof(msg))) pr_err("%s: __kfifo_get anomaly detected\n", __func__); if (mq->callback) mq->callback((void *)msg); } if ((rq_full) && (len == sizeof(msg))) { rq_full = false; omap_mbox_enable_irq(mbox, IRQ_RX); } }