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