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 */ 25 static 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 */ 41 static 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 */ 54 void 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 */ 73 void 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 */ 83 int 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 */ 101 struct 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 */ 118 int 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 */ 151 void 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 162 EXPORT_SYMBOL(msgqueue_initialise); 163 EXPORT_SYMBOL(msgqueue_free); 164 EXPORT_SYMBOL(msgqueue_msglength); 165 EXPORT_SYMBOL(msgqueue_getmsg); 166 EXPORT_SYMBOL(msgqueue_addmsg); 167 EXPORT_SYMBOL(msgqueue_flush); 168 169 MODULE_AUTHOR("Russell King"); 170 MODULE_DESCRIPTION("SCSI message queue handling"); 171 MODULE_LICENSE("GPL"); 172