Exemple #1
0
/*
 * Function: qp_wr_post
 *
 * Description:
 * This in-line function allocates a MQ msg, then moves the host-copy of
 * the completed WR into msg.  Then it posts the message.
 *
 * IN:
 * q        - ptr to user MQ.
 * wr        - ptr to host-copy of the WR.
 * qp        - ptr to user qp
 * size        - Number of bytes to post.  Assumed to be divisible by 4.
 *
 * OUT: none
 *
 * Return:
 * CCIL status codes.
 */
static int qp_wr_post(struct c2_mq *q, union c2wr * wr, struct c2_qp *qp, u32 size)
{
    union c2wr *msg;

    msg = c2_mq_alloc(q);
    if (msg == NULL) {
        return -EINVAL;
    }
#ifdef CCMSGMAGIC
    ((c2wr_hdr_t *) wr)->magic = cpu_to_be32(CCWR_MAGIC);
#endif

    /*
     * Since all header fields in the WR are the same as the
     * CQE, set the following so the adapter need not.
     */
    c2_wr_set_result(wr, CCERR_PENDING);

    /*
     * Copy the wr down to the adapter
     */
    memcpy((void *) msg, (void *) wr, size);

    c2_mq_produce(q);
    return 0;
}
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;
}
Exemple #3
0
/*
 * 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;
}