Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/drivers/acorn/scsi/msgqueue.c
0004  *
0005  *  Copyright (C) 1997-1998 Russell King
0006  *
0007  *  message queue handling
0008  */
0009 #include <linux/module.h>
0010 #include <linux/kernel.h>
0011 #include <linux/stddef.h>
0012 #include <linux/init.h>
0013 
0014 #include "msgqueue.h"
0015 
0016 /*
0017  * Function: struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
0018  * Purpose : Allocate a message queue entry
0019  * Params  : msgq - message queue to claim entry for
0020  * Returns : message queue entry or NULL.
0021  */
0022 static struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
0023 {
0024     struct msgqueue_entry *mq;
0025 
0026     if ((mq = msgq->free) != NULL)
0027         msgq->free = mq->next;
0028 
0029     return mq;
0030 }
0031 
0032 /*
0033  * Function: void mqe_free(MsgQueue_t *msgq, struct msgqueue_entry *mq)
0034  * Purpose : free a message queue entry
0035  * Params  : msgq - message queue to free entry from
0036  *       mq   - message queue entry to free
0037  */
0038 static void mqe_free(MsgQueue_t *msgq, struct msgqueue_entry *mq)
0039 {
0040     if (mq) {
0041         mq->next = msgq->free;
0042         msgq->free = mq;
0043     }
0044 }
0045 
0046 /*
0047  * Function: void msgqueue_initialise(MsgQueue_t *msgq)
0048  * Purpose : initialise a message queue
0049  * Params  : msgq - queue to initialise
0050  */
0051 void msgqueue_initialise(MsgQueue_t *msgq)
0052 {
0053     int i;
0054 
0055     msgq->qe = NULL;
0056     msgq->free = &msgq->entries[0];
0057 
0058     for (i = 0; i < NR_MESSAGES; i++)
0059         msgq->entries[i].next = &msgq->entries[i + 1];
0060 
0061     msgq->entries[NR_MESSAGES - 1].next = NULL;
0062 }
0063 
0064 
0065 /*
0066  * Function: void msgqueue_free(MsgQueue_t *msgq)
0067  * Purpose : free a queue
0068  * Params  : msgq - queue to free
0069  */
0070 void msgqueue_free(MsgQueue_t *msgq)
0071 {
0072 }
0073 
0074 /*
0075  * Function: int msgqueue_msglength(MsgQueue_t *msgq)
0076  * Purpose : calculate the total length of all messages on the message queue
0077  * Params  : msgq - queue to examine
0078  * Returns : number of bytes of messages in queue
0079  */
0080 int msgqueue_msglength(MsgQueue_t *msgq)
0081 {
0082     struct msgqueue_entry *mq = msgq->qe;
0083     int length = 0;
0084 
0085     for (mq = msgq->qe; mq; mq = mq->next)
0086         length += mq->msg.length;
0087 
0088     return length;
0089 }
0090 
0091 /*
0092  * Function: struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno)
0093  * Purpose : return a message
0094  * Params  : msgq   - queue to obtain message from
0095  *     : msgno  - message number
0096  * Returns : pointer to message string, or NULL
0097  */
0098 struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno)
0099 {
0100     struct msgqueue_entry *mq;
0101 
0102     for (mq = msgq->qe; mq && msgno; mq = mq->next, msgno--);
0103 
0104     return mq ? &mq->msg : NULL;
0105 }
0106 
0107 /*
0108  * Function: int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...)
0109  * Purpose : add a message onto a message queue
0110  * Params  : msgq   - queue to add message on
0111  *       length - length of message
0112  *       ...    - message bytes
0113  * Returns : != 0 if successful
0114  */
0115 int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...)
0116 {
0117     struct msgqueue_entry *mq = mqe_alloc(msgq);
0118     va_list ap;
0119 
0120     if (mq) {
0121         struct msgqueue_entry **mqp;
0122         int i;
0123 
0124         va_start(ap, length);
0125         for (i = 0; i < length; i++)
0126             mq->msg.msg[i] = va_arg(ap, unsigned int);
0127         va_end(ap);
0128 
0129         mq->msg.length = length;
0130         mq->msg.fifo = 0;
0131         mq->next = NULL;
0132 
0133         mqp = &msgq->qe;
0134         while (*mqp)
0135             mqp = &(*mqp)->next;
0136 
0137         *mqp = mq;
0138     }
0139 
0140     return mq != NULL;
0141 }
0142 
0143 /*
0144  * Function: void msgqueue_flush(MsgQueue_t *msgq)
0145  * Purpose : flush all messages from message queue
0146  * Params  : msgq - queue to flush
0147  */
0148 void msgqueue_flush(MsgQueue_t *msgq)
0149 {
0150     struct msgqueue_entry *mq, *mqnext;
0151 
0152     for (mq = msgq->qe; mq; mq = mqnext) {
0153         mqnext = mq->next;
0154         mqe_free(msgq, mq);
0155     }
0156     msgq->qe = NULL;
0157 }
0158 
0159 EXPORT_SYMBOL(msgqueue_initialise);
0160 EXPORT_SYMBOL(msgqueue_free);
0161 EXPORT_SYMBOL(msgqueue_msglength);
0162 EXPORT_SYMBOL(msgqueue_getmsg);
0163 EXPORT_SYMBOL(msgqueue_addmsg);
0164 EXPORT_SYMBOL(msgqueue_flush);
0165 
0166 MODULE_AUTHOR("Russell King");
0167 MODULE_DESCRIPTION("SCSI message queue handling");
0168 MODULE_LICENSE("GPL");