1f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* 2f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * Copyright (c) 2005 Ammasso, Inc. All rights reserved. 3f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. 4f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 5f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * This software is available to you under a choice of one of two 6f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * licenses. You may choose to be licensed under the terms of the GNU 7f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * General Public License (GPL) Version 2, available from the file 8f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * COPYING in the main directory of this source tree, or the 9f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * OpenIB.org BSD license below: 10f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 11f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * Redistribution and use in source and binary forms, with or 12f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * without modification, are permitted provided that the following 13f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * conditions are met: 14f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 15f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * - Redistributions of source code must retain the above 16f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * copyright notice, this list of conditions and the following 17f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * disclaimer. 18f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 19f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * - Redistributions in binary form must reproduce the above 20f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * copyright notice, this list of conditions and the following 21f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * disclaimer in the documentation and/or other materials 22f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * provided with the distribution. 23f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 24f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * SOFTWARE. 32f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 33f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker#include <linux/slab.h> 34f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker#include <linux/spinlock.h> 35f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 36f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker#include "c2_vq.h" 37f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker#include "c2_provider.h" 38f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 39f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* 40f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * Verbs Request Objects: 41f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 42f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * VQ Request Objects are allocated by the kernel verbs handlers. 43f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * They contain a wait object, a refcnt, an atomic bool indicating that the 44f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * adapter has replied, and a copy of the verb reply work request. 45f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * A pointer to the VQ Request Object is passed down in the context 46f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * field of the work request message, and reflected back by the adapter 47f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * in the verbs reply message. The function handle_vq() in the interrupt 48f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * path will use this pointer to: 49f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 1) append a copy of the verbs reply message 50f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 2) mark that the reply is ready 51f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 3) wake up the kernel verbs handler blocked awaiting the reply. 52f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 53f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 54f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * The kernel verbs handlers do a "get" to put a 2nd reference on the 55f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * VQ Request object. If the kernel verbs handler exits before the adapter 56f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * can respond, this extra reference will keep the VQ Request object around 57f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * until the adapter's reply can be processed. The reason we need this is 58f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * because a pointer to this object is stuffed into the context field of 59f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * the verbs work request message, and reflected back in the reply message. 60f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * It is used in the interrupt handler (handle_vq()) to wake up the appropriate 61f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * kernel verb handler that is blocked awaiting the verb reply. 62f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * So handle_vq() will do a "put" on the object when it's done accessing it. 63f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * NOTE: If we guarantee that the kernel verb handler will never bail before 64f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * getting the reply, then we don't need these refcnts. 65f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 66f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 67f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * VQ Request objects are freed by the kernel verbs handlers only 68f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * after the verb has been processed, or when the adapter fails and 69f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * does not reply. 70f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 71f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 72f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * Verbs Reply Buffers: 73f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 74f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * VQ Reply bufs are local host memory copies of a 75f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * outstanding Verb Request reply 76f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * message. The are always allocated by the kernel verbs handlers, and _may_ be 77f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * freed by either the kernel verbs handler -or- the interrupt handler. The 78f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * kernel verbs handler _must_ free the repbuf, then free the vq request object 79f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * in that order. 80f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 81f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 82f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckerint vq_init(struct c2_dev *c2dev) 83f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 84f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker sprintf(c2dev->vq_cache_name, "c2-vq:dev%c", 85f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker (char) ('0' + c2dev->devnum)); 86f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker c2dev->host_msg_cache = 87f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker kmem_cache_create(c2dev->vq_cache_name, c2dev->rep_vq.msg_size, 0, 8820c2df83d25c6a95affe6157a4c9cac4cf5ffaacPaul Mundt SLAB_HWCACHE_ALIGN, NULL); 89f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker if (c2dev->host_msg_cache == NULL) { 90f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker return -ENOMEM; 91f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 92f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker return 0; 93f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 94f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 95f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckervoid vq_term(struct c2_dev *c2dev) 96f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 97f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker kmem_cache_destroy(c2dev->host_msg_cache); 98f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 99f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 100f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* vq_req_alloc - allocate a VQ Request Object and initialize it. 101f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * The refcnt is set to 1. 102f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 103f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckerstruct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev) 104f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 105f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker struct c2_vq_req *r; 106f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 107f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker r = kmalloc(sizeof(struct c2_vq_req), GFP_KERNEL); 108f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker if (r) { 109f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker init_waitqueue_head(&r->wait_object); 110f9a4f6dcdd3f9b6d938484c2c394f39007c14f38Ralf Thielow r->reply_msg = 0; 111f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker r->event = 0; 112f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker r->cm_id = NULL; 113f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker r->qp = NULL; 114f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker atomic_set(&r->refcnt, 1); 115f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker atomic_set(&r->reply_ready, 0); 116f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 117f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker return r; 118f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 119f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 120f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 121f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* vq_req_free - free the VQ Request Object. It is assumed the verbs handler 122f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * has already free the VQ Reply Buffer if it existed. 123f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 124f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckervoid vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *r) 125f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 126f9a4f6dcdd3f9b6d938484c2c394f39007c14f38Ralf Thielow r->reply_msg = 0; 127f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker if (atomic_dec_and_test(&r->refcnt)) { 128f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker kfree(r); 129f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 130f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 131f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 132f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* vq_req_get - reference a VQ Request Object. Done 133f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * only in the kernel verbs handlers. 134f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 135f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckervoid vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *r) 136f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 137f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker atomic_inc(&r->refcnt); 138f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 139f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 140f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 141f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* vq_req_put - dereference and potentially free a VQ Request Object. 142f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * 143f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * This is only called by handle_vq() on the 144f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * interrupt when it is done processing 145f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * a verb reply message. If the associated 146f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * kernel verbs handler has already bailed, 147f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * then this put will actually free the VQ 148f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * Request object _and_ the VQ Reply Buffer 149f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * if it exists. 150f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 151f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckervoid vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *r) 152f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 153f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker if (atomic_dec_and_test(&r->refcnt)) { 154f9a4f6dcdd3f9b6d938484c2c394f39007c14f38Ralf Thielow if (r->reply_msg != 0) 155f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker vq_repbuf_free(c2dev, 156f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker (void *) (unsigned long) r->reply_msg); 157f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker kfree(r); 158f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 159f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 160f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 161f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 162f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* 163f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * vq_repbuf_alloc - allocate a VQ Reply Buffer. 164f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 165f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckervoid *vq_repbuf_alloc(struct c2_dev *c2dev) 166f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 16754e6ecb23951b195d02433a741c7f7cb0b796c78Christoph Lameter return kmem_cache_alloc(c2dev->host_msg_cache, GFP_ATOMIC); 168f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 169f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 170f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* 171f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * vq_send_wr - post a verbs request message to the Verbs Request Queue. 172f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * If a message is not available in the MQ, then block until one is available. 173f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * NOTE: handle_mq() on the interrupt context will wake up threads blocked here. 174f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * When the adapter drains the Verbs Request Queue, 175f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * it inserts MQ index 0 in to the 176f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * adapter->host activity fifo and interrupts the host. 177f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 178f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckerint vq_send_wr(struct c2_dev *c2dev, union c2wr *wr) 179f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 180f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker void *msg; 181f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker wait_queue_t __wait; 182f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 183f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker /* 184f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * grab adapter vq lock 185f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 186f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker spin_lock(&c2dev->vqlock); 187f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 188f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker /* 189f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * allocate msg 190f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 191f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker msg = c2_mq_alloc(&c2dev->req_vq); 192f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 193f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker /* 194f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * If we cannot get a msg, then we'll wait 195f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * When a messages are available, the int handler will wake_up() 196f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * any waiters. 197f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 198f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker while (msg == NULL) { 199f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker pr_debug("%s:%d no available msg in VQ, waiting...\n", 2003371836383d63b627b228875f5ac63023cbf11d2Harvey Harrison __func__, __LINE__); 201f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker init_waitqueue_entry(&__wait, current); 202f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker add_wait_queue(&c2dev->req_vq_wo, &__wait); 203f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker spin_unlock(&c2dev->vqlock); 204f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker for (;;) { 205f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker set_current_state(TASK_INTERRUPTIBLE); 206f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker if (!c2_mq_full(&c2dev->req_vq)) { 207f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker break; 208f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 209f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker if (!signal_pending(current)) { 210f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker schedule_timeout(1 * HZ); /* 1 second... */ 211f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker continue; 212f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 213f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker set_current_state(TASK_RUNNING); 214f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker remove_wait_queue(&c2dev->req_vq_wo, &__wait); 215f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker return -EINTR; 216f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 217f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker set_current_state(TASK_RUNNING); 218f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker remove_wait_queue(&c2dev->req_vq_wo, &__wait); 219f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker spin_lock(&c2dev->vqlock); 220f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker msg = c2_mq_alloc(&c2dev->req_vq); 221f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker } 222f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 223f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker /* 224f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * copy wr into adapter msg 225f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 226f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker memcpy(msg, wr, c2dev->req_vq.msg_size); 227f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 228f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker /* 229f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * post msg 230f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 231f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker c2_mq_produce(&c2dev->req_vq); 232f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 233f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker /* 234f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * release adapter vq lock 235f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 236f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker spin_unlock(&c2dev->vqlock); 237f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker return 0; 238f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 239f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 240f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 241f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* 242f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * vq_wait_for_reply - block until the adapter posts a Verb Reply Message. 243f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 244f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckerint vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req) 245f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 246f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker if (!wait_event_timeout(req->wait_object, 247f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker atomic_read(&req->reply_ready), 248f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 60*HZ)) 249f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker return -ETIMEDOUT; 250f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 251f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker return 0; 252f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 253f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker 254f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker/* 255f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker * vq_repbuf_free - Free a Verbs Reply Buffer. 256f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker */ 257f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tuckervoid vq_repbuf_free(struct c2_dev *c2dev, void *reply) 258f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker{ 259f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker kmem_cache_free(c2dev->host_msg_cache, reply); 260f94b533d091a42da92d908eb7b3f9ade1923f90dTom Tucker} 261