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