Example #1
0
void c2_mq_produce(struct c2_mq *q)
{
	BUG_ON(q->magic != C2_MQ_MAGIC);
	BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);

	if (!c2_mq_full(q)) {
		q->priv = (q->priv + 1) % q->q_size;
		q->hint_count++;
		/* Update peer's offset. */
		__raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared);
	}
}
int vq_send_wr(struct c2_dev *c2dev, union c2wr *wr)
{
	void *msg;
	wait_queue_t __wait;

	spin_lock(&c2dev->vqlock);

	msg = c2_mq_alloc(&c2dev->req_vq);

	while (msg == NULL) {
		pr_debug("%s:%d no available msg in VQ, waiting...\n",
		       __func__, __LINE__);
		init_waitqueue_entry(&__wait, current);
		add_wait_queue(&c2dev->req_vq_wo, &__wait);
		spin_unlock(&c2dev->vqlock);
		for (;;) {
			set_current_state(TASK_INTERRUPTIBLE);
			if (!c2_mq_full(&c2dev->req_vq)) {
				break;
			}
			if (!signal_pending(current)) {
				schedule_timeout(1 * HZ);	
				continue;
			}
			set_current_state(TASK_RUNNING);
			remove_wait_queue(&c2dev->req_vq_wo, &__wait);
			return -EINTR;
		}
		set_current_state(TASK_RUNNING);
		remove_wait_queue(&c2dev->req_vq_wo, &__wait);
		spin_lock(&c2dev->vqlock);
		msg = c2_mq_alloc(&c2dev->req_vq);
	}

	memcpy(msg, wr, c2dev->req_vq.msg_size);

	c2_mq_produce(&c2dev->req_vq);

	spin_unlock(&c2dev->vqlock);
	return 0;
}
Example #3
0
void *c2_mq_alloc(struct c2_mq *q)
{
	BUG_ON(q->magic != C2_MQ_MAGIC);
	BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);

	if (c2_mq_full(q)) {
		return NULL;
	} else {
#ifdef DEBUG
		struct c2wr_hdr *m =
		    (struct c2wr_hdr *) (q->msg_pool.host + q->priv * q->msg_size);
#ifdef CCMSGMAGIC
		BUG_ON(m->magic != be32_to_cpu(~CCWR_MAGIC));
		m->magic = cpu_to_be32(CCWR_MAGIC);
#endif
		return m;
#else
		return q->msg_pool.host + q->priv * q->msg_size;
#endif
	}
}
Example #4
0
File: c2_vq.c Project: 274914765/C
/*
 * vq_send_wr - post a verbs request message to the Verbs Request Queue.
 * If a message is not available in the MQ, then block until one is available.
 * NOTE: handle_mq() on the interrupt context will wake up threads blocked here.
 * When the adapter drains the Verbs Request Queue,
 * it inserts MQ index 0 in to the
 * adapter->host activity fifo and interrupts the host.
 */
int vq_send_wr(struct c2_dev *c2dev, union c2wr *wr)
{
    void *msg;
    wait_queue_t __wait;

    /*
     * grab adapter vq lock
     */
    spin_lock(&c2dev->vqlock);

    /*
     * allocate msg
     */
    msg = c2_mq_alloc(&c2dev->req_vq);

    /*
     * If we cannot get a msg, then we'll wait
     * When a messages are available, the int handler will wake_up()
     * any waiters.
     */
    while (msg == NULL) {
        pr_debug("%s:%d no available msg in VQ, waiting...\n",
               __func__, __LINE__);
        init_waitqueue_entry(&__wait, current);
        add_wait_queue(&c2dev->req_vq_wo, &__wait);
        spin_unlock(&c2dev->vqlock);
        for (;;) {
            set_current_state(TASK_INTERRUPTIBLE);
            if (!c2_mq_full(&c2dev->req_vq)) {
                break;
            }
            if (!signal_pending(current)) {
                schedule_timeout(1 * HZ);    /* 1 second... */
                continue;
            }
            set_current_state(TASK_RUNNING);
            remove_wait_queue(&c2dev->req_vq_wo, &__wait);
            return -EINTR;
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&c2dev->req_vq_wo, &__wait);
        spin_lock(&c2dev->vqlock);
        msg = c2_mq_alloc(&c2dev->req_vq);
    }

    /*
     * copy wr into adapter msg
     */
    memcpy(msg, wr, c2dev->req_vq.msg_size);

    /*
     * post msg
     */
    c2_mq_produce(&c2dev->req_vq);

    /*
     * release adapter vq lock
     */
    spin_unlock(&c2dev->vqlock);
    return 0;
}