msgqueue.c (3735B)
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 */ 22static 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 */ 38static 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 */ 51void 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 */ 70void 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 */ 80int 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 */ 98struct 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 */ 115int 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 */ 148void 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 159EXPORT_SYMBOL(msgqueue_initialise); 160EXPORT_SYMBOL(msgqueue_free); 161EXPORT_SYMBOL(msgqueue_msglength); 162EXPORT_SYMBOL(msgqueue_getmsg); 163EXPORT_SYMBOL(msgqueue_addmsg); 164EXPORT_SYMBOL(msgqueue_flush); 165 166MODULE_AUTHOR("Russell King"); 167MODULE_DESCRIPTION("SCSI message queue handling"); 168MODULE_LICENSE("GPL");