msgqueue.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. #include "msgqueue.h"
  14. /*
  15. * Function: struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
  16. * Purpose : Allocate a message queue entry
  17. * Params : msgq - message queue to claim entry for
  18. * Returns : message queue entry or NULL.
  19. */
  20. static struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
  21. {
  22. struct msgqueue_entry *mq;
  23. if ((mq = msgq->free) != NULL)
  24. msgq->free = mq->next;
  25. return mq;
  26. }
  27. /*
  28. * Function: void mqe_free(MsgQueue_t *msgq, struct msgqueue_entry *mq)
  29. * Purpose : free a message queue entry
  30. * Params : msgq - message queue to free entry from
  31. * mq - message queue entry to free
  32. */
  33. static void mqe_free(MsgQueue_t *msgq, struct msgqueue_entry *mq)
  34. {
  35. if (mq) {
  36. mq->next = msgq->free;
  37. msgq->free = mq;
  38. }
  39. }
  40. /*
  41. * Function: void msgqueue_initialise(MsgQueue_t *msgq)
  42. * Purpose : initialise a message queue
  43. * Params : msgq - queue to initialise
  44. */
  45. void msgqueue_initialise(MsgQueue_t *msgq)
  46. {
  47. int i;
  48. msgq->qe = NULL;
  49. msgq->free = &msgq->entries[0];
  50. for (i = 0; i < NR_MESSAGES; i++)
  51. msgq->entries[i].next = &msgq->entries[i + 1];
  52. msgq->entries[NR_MESSAGES - 1].next = NULL;
  53. }
  54. /*
  55. * Function: void msgqueue_free(MsgQueue_t *msgq)
  56. * Purpose : free a queue
  57. * Params : msgq - queue to free
  58. */
  59. void msgqueue_free(MsgQueue_t *msgq)
  60. {
  61. }
  62. /*
  63. * Function: int msgqueue_msglength(MsgQueue_t *msgq)
  64. * Purpose : calculate the total length of all messages on the message queue
  65. * Params : msgq - queue to examine
  66. * Returns : number of bytes of messages in queue
  67. */
  68. int msgqueue_msglength(MsgQueue_t *msgq)
  69. {
  70. struct msgqueue_entry *mq = msgq->qe;
  71. int length = 0;
  72. for (mq = msgq->qe; mq; mq = mq->next)
  73. length += mq->msg.length;
  74. return length;
  75. }
  76. /*
  77. * Function: struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno)
  78. * Purpose : return a message
  79. * Params : msgq - queue to obtain message from
  80. * : msgno - message number
  81. * Returns : pointer to message string, or NULL
  82. */
  83. struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno)
  84. {
  85. struct msgqueue_entry *mq;
  86. for (mq = msgq->qe; mq && msgno; mq = mq->next, msgno--);
  87. return mq ? &mq->msg : NULL;
  88. }
  89. /*
  90. * Function: int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...)
  91. * Purpose : add a message onto a message queue
  92. * Params : msgq - queue to add message on
  93. * length - length of message
  94. * ... - message bytes
  95. * Returns : != 0 if successful
  96. */
  97. int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...)
  98. {
  99. struct msgqueue_entry *mq = mqe_alloc(msgq);
  100. va_list ap;
  101. if (mq) {
  102. struct msgqueue_entry **mqp;
  103. int i;
  104. va_start(ap, length);
  105. for (i = 0; i < length; i++)
  106. mq->msg.msg[i] = va_arg(ap, unsigned int);
  107. va_end(ap);
  108. mq->msg.length = length;
  109. mq->msg.fifo = 0;
  110. mq->next = NULL;
  111. mqp = &msgq->qe;
  112. while (*mqp)
  113. mqp = &(*mqp)->next;
  114. *mqp = mq;
  115. }
  116. return mq != NULL;
  117. }
  118. /*
  119. * Function: void msgqueue_flush(MsgQueue_t *msgq)
  120. * Purpose : flush all messages from message queue
  121. * Params : msgq - queue to flush
  122. */
  123. void msgqueue_flush(MsgQueue_t *msgq)
  124. {
  125. struct msgqueue_entry *mq, *mqnext;
  126. for (mq = msgq->qe; mq; mq = mqnext) {
  127. mqnext = mq->next;
  128. mqe_free(msgq, mq);
  129. }
  130. msgq->qe = NULL;
  131. }
  132. EXPORT_SYMBOL(msgqueue_initialise);
  133. EXPORT_SYMBOL(msgqueue_free);
  134. EXPORT_SYMBOL(msgqueue_msglength);
  135. EXPORT_SYMBOL(msgqueue_getmsg);
  136. EXPORT_SYMBOL(msgqueue_addmsg);
  137. EXPORT_SYMBOL(msgqueue_flush);
  138. MODULE_AUTHOR("Russell King");
  139. MODULE_DESCRIPTION("SCSI message queue handling");
  140. MODULE_LICENSE("GPL");