2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
5 * NBMK Encryption Technologies provides no support of any kind for
6 * this software. Questions or concerns about it may be addressed to
7 * the members of the relevant open-source community at
8 * <tech-crypto@netbsd.org>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided
20 * with the distribution.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 static char const n8_id
[] = "$Id: n8_event.c,v 1.1 2008/10/30 12:02:14 darran Exp $";
36 /*****************************************************************************/
38 * @brief Routines for processing asynchronous events.
40 * When select API calls are made asynchronously, indicated by passing a
41 * non-null pointer to a N8_Event_t structure, the calling routine needs to be
42 * able to inquire as to the progress of the call and retrieve results. This
43 * module provides the following functions to that end:<br>
47 *****************************************************************************/
49 /*****************************************************************************
52 * 05/19/03 brr Clean up include files.
53 * 04/01/03 brr Modified N8_EventWait to pass timeout to N8_WaitOnRequest.
54 * 03/19/03 brr Modified N8_EventWait to pass specific event to
56 * 03/10/03 brr Added support for API callbacks.
57 * 09/18/02 brr Replaced InternalEventWait with N8_WaitOnRequest.
58 * 7/01/02 arh Fixed Bug #813: N8_EventCheck returns N8_EVENT_NONE_READY
59 * unless last event complete. Removed extraneous assignment
60 * of N8_EVENT_NONE_READY to *ready_p inside inner for loop.
61 * 05/15/02 brr Removed obsolete chained request functions. Also support RNG
62 * modifications to return random bytes in the queue ioctl.
63 * 05/01/02 brr Removed redundant call to n8_preamble in N8_EventWait. Modified
64 * N8_EventCheck to only call QMgrCheckRequests for RNG events.
65 * 04/06/02 brr Validate events_p and ready_p in N8_EventCheck.
66 * 03/29/02 brr Modified InternalEventWait to use N8_AMBA_TIMER_CHIP.
67 * 03/26/02 hml Modified N8_EventCheck for Bug 635 to again return
68 * N8_EVENT_NONE_READY, but not spin forever.
69 * 03/22/02 brr Modified N8_EventCheck to return N8_EVENT_NONE_AVAILABLE if
70 * the event pointer is NULL and count > 0. (Bug 635)
71 * 03/07/02 brr Fix race condition in EventCheck.
72 * 03/04/02 brr Set event status when event is not complete.
73 * 02/28/02 brr Do not include any QMgr include files.
74 * 02/26/02 brr Removed queue references.
75 * 02/27/02 msz Fixes for N8_WaitOnInterrupt support.
76 * 02/22/02 spm Converted printf's to DBG's and n8_udelay's to n8_usleeps.
77 * 02/20/02 msz N8_CheckEvent simplifications.
78 * 02/19/02 brr Perform callback processing in N8_CheckEvent.
79 * 01/21/02 msz Added support for configurable event wait.
80 * 01/16/02 bac Fixed Bug #478: the state in an event could be NULL if
81 * previously processed. Set traps to catch this condition.
82 * 01/11/02 msz Use timer of first nsp only.
83 * 01/02/02 msz Don't use usleep or n8_usleep if hardware is present in
85 * 12/05/01 msz Simplification of status codes in preparation for chaining
87 * 11/28/01 mel Fixed bug #376: n8_event.c uses usleep.
88 * 11/24/01 brr Removed include of obsolete EA & PK specifice Queue files.
89 * 10/19/01 hml Fixed compiler warnings.
90 * 10/02/01 bac Added a comment to clear up the use of the return code from
92 * 09/10/01 msz Minor change to correct a return type.
93 * 08/07/01 mel Deleted unnecessary includes.
94 * 07/31/01 bac Added call to N8_preamble for all public interfaces.
95 * 07/09/01 hml Check for rnreq_p == NULL before we try to free the request
96 * in CheckEvent (BUG #117?)
97 * 07/09/01 hml Set pointer to NULL after a freeRequest and do a break
98 * when the request is null in CheckEvent.
99 * 07/06/01 hml Don't call CheckRequest in N8_EventCheck if the request
100 * is already completed or caused an error (BUG #113).
101 * 07/11/01 mel Porting to VxWorks.
102 * 07/02/01 bac Fixed comments.
103 * 06/28/01 bac Added correct request freeing for RNG events.
104 * 06/25/01 bac More changes for QMgr v.1.0.1
105 * 06/19/01 bac Fleshed out N8_EventCheck and N8_EventWait
106 * 05/31/01 bac Original version.
107 ****************************************************************************/
108 /** @defgroup n8_event Event processing
112 #include "n8_common.h"
113 #include "n8_enqueue_common.h"
114 #include "n8_API_Initialize.h"
115 #include "n8_OS_intf.h"
116 #include "nsp_ioctl.h"
117 #include "n8_device_info.h"
118 #include "n8_driver_api.h"
120 /*****************************************************************************
122 *****************************************************************************/
123 /** @ingroup n8_event
124 * @brief Check a list of events for completion status.
126 * Given a list of events, check each one for its completion status. Each event
127 * will be updated to reflect its current status.
129 * @param events_p RW: Array of events to be checked.
130 * @param count RO: Number of events.
131 * @param ready_p RW: Status of event.
137 * N8_STATUS_OK - all's well.<br>
138 * N8_INVALID_OBJECT - one or more of the events is not valid.<br>
139 * N8_INVALID_VALUE - count < 0 or count > max.
142 * <description of possible errors><br>
145 * <description of assumptions><br>
146 *****************************************************************************/
147 N8_Status_t
N8_EventCheck(N8_Event_t
*events_p
, const int count
, int *ready_p
)
150 N8_Status_t ret
= N8_STATUS_OK
;
151 N8_Boolean_t checkCalled
;
152 QMgrRequest_t
*qreq_p
= NULL
;
153 N8_QueueStatusCodes_t status
;
154 N8_Status_t usrStatus
;
158 CHECK_OBJECT(events_p
, ret
);
159 CHECK_OBJECT(ready_p
, ret
);
161 if (count
< 1 || count
> N8_EVENT_MAX
)
163 ret
= N8_INVALID_VALUE
;
170 *ready_p
= N8_EVENT_NONE_READY
;
172 /* Per invocation of N8_EventCheck, the _CheckQueue method will only be
173 * called once per execution unit. We set up an array of booleans to see
174 * if the execution unit has been called yet or not. */
175 checkCalled
= N8_FALSE
;
176 for (i
= 0; i
< count
; i
++)
178 qreq_p
= (QMgrRequest_t
*) events_p
[i
].state
;
180 /* If the request was previously checked and found
181 to be completed or to have caused an error, then
182 the request struct would have been freed. So we
183 want to skip the processing. */
186 /* Note we don't call the CheckRequest for any case
187 if the request is already finished or caused an error */
189 status
= qreq_p
->requestStatus
;
191 if ( status
== N8_QUEUE_REQUEST_FINISHED
)
193 #ifdef SUPPORT_DEVICE_POLL
196 if ( qreq_p
->requestError
!= N8_QUEUE_REQUEST_ERROR
)
198 /* Do the callback if needed. */
199 if ( qreq_p
->callback
!= NULL
)
201 qreq_p
->callback( qreq_p
);
203 events_p
[i
].status
= N8_QUEUE_REQUEST_FINISHED
;
204 usrStatus
= N8_STATUS_OK
;
208 events_p
[i
].status
= N8_QUEUE_REQUEST_COMMAND_ERROR
;
209 usrStatus
= N8_HARDWARE_ERROR
;
212 /* free the request. */
213 freeRequest((API_Request_t
*)qreq_p
);
214 events_p
[i
].state
= NULL
;
216 #ifdef SUPPORT_CALLBACKS
217 /* Perform the user's callback. */
218 if (events_p
[i
].usrCallback
)
220 events_p
[i
].usrCallback( events_p
[i
].usrData
, usrStatus
);
224 if (*ready_p
== N8_EVENT_NONE_READY
)
230 } /* qreq_p != NULL */
233 /* qreq_p is NULL, but if the request status is
234 N8_QUEUE_REQUEST_FINISHED, we still want to consider
235 setting ready_p. This means the USER would be well served
236 to remove finished requests from the list they send in. */
237 if (events_p
[i
].status
== N8_QUEUE_REQUEST_FINISHED
)
239 /* The request is finished */
240 if (*ready_p
== N8_EVENT_NONE_READY
)
250 } /* N8_EventCheck */
253 /*****************************************************************************
255 *****************************************************************************/
256 /** @ingroup n8_event
257 * @brief Wait on an event to become ready.
259 * A <b>blocking</b> call to wait for at least one event to complete.
261 * @param events_p RW: Array of events to complete.
262 * @param count RO: Number of events.
263 * @param ready_p RW: Status of event.
269 * N8_STATUS_OK - all's well.<br>
270 * N8_INVALID_OBJECT - one or more of the events is not valid.<br>
271 * N8_INVALID_VALUE - count < 0 or count > max.
277 * Multiple events may become ready. An arbitrary one of those events will
278 * be marked as completed. The others may be complete but their statuses will
279 * not be updated to reflect this.
280 *****************************************************************************/
281 N8_Status_t
N8_EventWait(N8_Event_t
*events_p
, const int count
, int *ready_p
)
287 /* This is guarenteed to be redundant since N8_EventCheck */
288 /* will perform this same check. */
289 /* ret = N8_preamble(); */
290 /* CHECK_RETURN(ret); */
292 ret
= N8_EventCheck(events_p
, count
, ready_p
);
293 while ((ret
== N8_STATUS_OK
) &&
294 (*ready_p
== N8_EVENT_NONE_READY
))
298 ret
= N8_EventCheck(events_p
, count
, ready_p
);