1/* 2 * linux/drivers/acorn/scsi/msgqueue.c 3 * 4 * Copyright (C) 1997-1998 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * message queue handling 11 */ 12#include <linux/module.h> 13#include <linux/kernel.h> 14#include <linux/stddef.h> 15#include <linux/init.h> 16 17#include "msgqueue.h" 18 19/* 20 * Function: struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq) 21 * Purpose : Allocate a message queue entry 22 * Params : msgq - message queue to claim entry for 23 * Returns : message queue entry or NULL. 24 */ 25static struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq) 26{ 27 struct msgqueue_entry *mq; 28 29 if ((mq = msgq->free) != NULL) 30 msgq->free = mq->next; 31 32 return mq; 33} 34 35/* 36 * Function: void mqe_free(MsgQueue_t *msgq, struct msgqueue_entry *mq) 37 * Purpose : free a message queue entry 38 * Params : msgq - message queue to free entry from 39 * mq - message queue entry to free 40 */ 41static void mqe_free(MsgQueue_t *msgq, struct msgqueue_entry *mq) 42{ 43 if (mq) { 44 mq->next = msgq->free; 45 msgq->free = mq; 46 } 47} 48 49/* 50 * Function: void msgqueue_initialise(MsgQueue_t *msgq) 51 * Purpose : initialise a message queue 52 * Params : msgq - queue to initialise 53 */ 54void msgqueue_initialise(MsgQueue_t *msgq) 55{ 56 int i; 57 58 msgq->qe = NULL; 59 msgq->free = &msgq->entries[0]; 60 61 for (i = 0; i < NR_MESSAGES; i++) 62 msgq->entries[i].next = &msgq->entries[i + 1]; 63 64 msgq->entries[NR_MESSAGES - 1].next = NULL; 65} 66 67 68/* 69 * Function: void msgqueue_free(MsgQueue_t *msgq) 70 * Purpose : free a queue 71 * Params : msgq - queue to free 72 */ 73void msgqueue_free(MsgQueue_t *msgq) 74{ 75} 76 77/* 78 * Function: int msgqueue_msglength(MsgQueue_t *msgq) 79 * Purpose : calculate the total length of all messages on the message queue 80 * Params : msgq - queue to examine 81 * Returns : number of bytes of messages in queue 82 */ 83int msgqueue_msglength(MsgQueue_t *msgq) 84{ 85 struct msgqueue_entry *mq = msgq->qe; 86 int length = 0; 87 88 for (mq = msgq->qe; mq; mq = mq->next) 89 length += mq->msg.length; 90 91 return length; 92} 93 94/* 95 * Function: struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno) 96 * Purpose : return a message 97 * Params : msgq - queue to obtain message from 98 * : msgno - message number 99 * Returns : pointer to message string, or NULL 100 */ 101struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno) 102{ 103 struct msgqueue_entry *mq; 104 105 for (mq = msgq->qe; mq && msgno; mq = mq->next, msgno--); 106 107 return mq ? &mq->msg : NULL; 108} 109 110/* 111 * Function: int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...) 112 * Purpose : add a message onto a message queue 113 * Params : msgq - queue to add message on 114 * length - length of message 115 * ... - message bytes 116 * Returns : != 0 if successful 117 */ 118int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...) 119{ 120 struct msgqueue_entry *mq = mqe_alloc(msgq); 121 va_list ap; 122 123 if (mq) { 124 struct msgqueue_entry **mqp; 125 int i; 126 127 va_start(ap, length); 128 for (i = 0; i < length; i++) 129 mq->msg.msg[i] = va_arg(ap, unsigned int); 130 va_end(ap); 131 132 mq->msg.length = length; 133 mq->msg.fifo = 0; 134 mq->next = NULL; 135 136 mqp = &msgq->qe; 137 while (*mqp) 138 mqp = &(*mqp)->next; 139 140 *mqp = mq; 141 } 142 143 return mq != NULL; 144} 145 146/* 147 * Function: void msgqueue_flush(MsgQueue_t *msgq) 148 * Purpose : flush all messages from message queue 149 * Params : msgq - queue to flush 150 */ 151void msgqueue_flush(MsgQueue_t *msgq) 152{ 153 struct msgqueue_entry *mq, *mqnext; 154 155 for (mq = msgq->qe; mq; mq = mqnext) { 156 mqnext = mq->next; 157 mqe_free(msgq, mq); 158 } 159 msgq->qe = NULL; 160} 161 162EXPORT_SYMBOL(msgqueue_initialise); 163EXPORT_SYMBOL(msgqueue_free); 164EXPORT_SYMBOL(msgqueue_msglength); 165EXPORT_SYMBOL(msgqueue_getmsg); 166EXPORT_SYMBOL(msgqueue_addmsg); 167EXPORT_SYMBOL(msgqueue_flush); 168 169MODULE_AUTHOR("Russell King"); 170MODULE_DESCRIPTION("SCSI message queue handling"); 171MODULE_LICENSE("GPL"); 172