Example #1
0
/*
 * 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;
}
Example #3
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;
}
Example #4
0
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;
	}
}
Example #5
0
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);
}
Example #6
0
/**
 * 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;
}
Example #7
0
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;
}
Example #8
0
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);
	}
}
Example #9
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 = 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);
	}
}