cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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");