1/* 2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved. 3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33#include "c2.h" 34#include "c2_mq.h" 35 36void *c2_mq_alloc(struct c2_mq *q) 37{ 38 BUG_ON(q->magic != C2_MQ_MAGIC); 39 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); 40 41 if (c2_mq_full(q)) { 42 return NULL; 43 } else { 44#ifdef DEBUG 45 struct c2wr_hdr *m = 46 (struct c2wr_hdr *) (q->msg_pool.host + q->priv * q->msg_size); 47#ifdef CCMSGMAGIC 48 BUG_ON(m->magic != be32_to_cpu(~CCWR_MAGIC)); 49 m->magic = cpu_to_be32(CCWR_MAGIC); 50#endif 51 return m; 52#else 53 return q->msg_pool.host + q->priv * q->msg_size; 54#endif 55 } 56} 57 58void c2_mq_produce(struct c2_mq *q) 59{ 60 BUG_ON(q->magic != C2_MQ_MAGIC); 61 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); 62 63 if (!c2_mq_full(q)) { 64 q->priv = (q->priv + 1) % q->q_size; 65 q->hint_count++; 66 /* Update peer's offset. */ 67 __raw_writew(cpu_to_be16(q->priv), &q->peer->shared); 68 } 69} 70 71void *c2_mq_consume(struct c2_mq *q) 72{ 73 BUG_ON(q->magic != C2_MQ_MAGIC); 74 BUG_ON(q->type != C2_MQ_HOST_TARGET); 75 76 if (c2_mq_empty(q)) { 77 return NULL; 78 } else { 79#ifdef DEBUG 80 struct c2wr_hdr *m = (struct c2wr_hdr *) 81 (q->msg_pool.host + q->priv * q->msg_size); 82#ifdef CCMSGMAGIC 83 BUG_ON(m->magic != be32_to_cpu(CCWR_MAGIC)); 84#endif 85 return m; 86#else 87 return q->msg_pool.host + q->priv * q->msg_size; 88#endif 89 } 90} 91 92void c2_mq_free(struct c2_mq *q) 93{ 94 BUG_ON(q->magic != C2_MQ_MAGIC); 95 BUG_ON(q->type != C2_MQ_HOST_TARGET); 96 97 if (!c2_mq_empty(q)) { 98 99#ifdef CCMSGMAGIC 100 { 101 struct c2wr_hdr __iomem *m = (struct c2wr_hdr __iomem *) 102 (q->msg_pool.adapter + q->priv * q->msg_size); 103 __raw_writel(cpu_to_be32(~CCWR_MAGIC), &m->magic); 104 } 105#endif 106 q->priv = (q->priv + 1) % q->q_size; 107 /* Update peer's offset. */ 108 __raw_writew(cpu_to_be16(q->priv), &q->peer->shared); 109 } 110} 111 112 113void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count) 114{ 115 BUG_ON(q->magic != C2_MQ_MAGIC); 116 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); 117 118 while (wqe_count--) { 119 BUG_ON(c2_mq_empty(q)); 120 *q->shared = cpu_to_be16((be16_to_cpu(*q->shared)+1) % q->q_size); 121 } 122} 123 124 125void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, 126 u8 __iomem *pool_start, u16 __iomem *peer, u32 type) 127{ 128 BUG_ON(!q->shared); 129 130 /* This code assumes the byte swapping has already been done! */ 131 q->index = index; 132 q->q_size = q_size; 133 q->msg_size = msg_size; 134 q->msg_pool.adapter = pool_start; 135 q->peer = (struct c2_mq_shared __iomem *) peer; 136 q->magic = C2_MQ_MAGIC; 137 q->type = type; 138 q->priv = 0; 139 q->hint_count = 0; 140 return; 141} 142void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, 143 u8 *pool_start, u16 __iomem *peer, u32 type) 144{ 145 BUG_ON(!q->shared); 146 147 /* This code assumes the byte swapping has already been done! */ 148 q->index = index; 149 q->q_size = q_size; 150 q->msg_size = msg_size; 151 q->msg_pool.host = pool_start; 152 q->peer = (struct c2_mq_shared __iomem *) peer; 153 q->magic = C2_MQ_MAGIC; 154 q->type = type; 155 q->priv = 0; 156 q->hint_count = 0; 157 return; 158} 159