diff options
Diffstat (limited to 'drivers/scsi/arm/msgqueue.c')
-rw-r--r-- | drivers/scsi/arm/msgqueue.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/drivers/scsi/arm/msgqueue.c b/drivers/scsi/arm/msgqueue.c new file mode 100644 index 000000000000..7c95c7582b29 --- /dev/null +++ b/drivers/scsi/arm/msgqueue.c | |||
@@ -0,0 +1,171 @@ | |||
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 | */ | ||
25 | static 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 | */ | ||
41 | static 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 | */ | ||
54 | void 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 | */ | ||
73 | void 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 | */ | ||
83 | int 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 | */ | ||
101 | struct 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 | */ | ||
118 | int 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 | */ | ||
151 | void 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 | |||
162 | EXPORT_SYMBOL(msgqueue_initialise); | ||
163 | EXPORT_SYMBOL(msgqueue_free); | ||
164 | EXPORT_SYMBOL(msgqueue_msglength); | ||
165 | EXPORT_SYMBOL(msgqueue_getmsg); | ||
166 | EXPORT_SYMBOL(msgqueue_addmsg); | ||
167 | EXPORT_SYMBOL(msgqueue_flush); | ||
168 | |||
169 | MODULE_AUTHOR("Russell King"); | ||
170 | MODULE_DESCRIPTION("SCSI message queue handling"); | ||
171 | MODULE_LICENSE("GPL"); | ||