Sync usage with man page.
[netbsd-mini2440.git] / sys / dev / pci / n8 / common / api / n8_util.c
blob35de1828bbcdfd0666d7460b3b791eedb6dcc773
1 /*-
2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
3 * All rights reserved.
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>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met:
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_util.c,v 1.1 2008/10/30 12:02:15 darran Exp $";
36 /*****************************************************************************/
37 /** @file n8_util.c
38 * @brief N8 utilities
40 * Loose collection of utility functions used across the N8 methods.
42 *****************************************************************************/
44 /*****************************************************************************
45 * Revision history:
46 * 08/18/03 brr Eliminate duplicate assignments & unused parameter passage.
47 * 05/19/03 brr Eliminate obsolete functions freeRequest & addBlockToFree.
48 * 05/15/03 brr Eliminate RNG error codes since they are not propigated to
49 * user space.
50 * 04/25/03 brr Queue callback events if either the usrData or usrCallback
51 * is not NULL so events without callbacks can N8_EventPoll.
52 * 04/21/03 brr Allocate PK requests from seperate pool.
53 * 03/10/03 brr Added support for API callbacks.
54 * 08/05/02 bac Fixed n8_printBuffer to line wrap correctly.
55 * 07/14/02 bac Modified freeRequest to only free those requests that were not
56 * allocated using N8_RequestAllocate.
57 * 07/08/02 brr Conditionally perform N8_QMgrDequeue to support device
58 * polling.
59 * 06/10/02 hml Added initializeEARequestBuffer.
60 * 05/15/02 brr Removed functions that handled chained requests.
61 * 05/09/02 bac Moved N8_CreateSizedBufferFromATTR, N8_CreateBuffer, and
62 * N8_CreateSizedBufferFromString elsewhere.
63 * 05/07/02 msz Handle a pend on synchronous requests.
64 * 04/20/02 brr Clear the API request & cmd blocks with memset.
65 * 03/26/02 hml Added n8_validateUnit.
66 * 03/26/02 brr Allocate the data buffer as part of the API request.
67 * 03/25/02 brr Moved N8_CreateSizedBufferFromATTR from n8_test_util.c
68 * 03/22/02 brr Do not zero command blocks since KMALLOC now does so.
69 * 03/08/02 brr Zero command blocks since KMALLOC no longer zero's memory.
70 * 03/06/02 brr Fix print functions to compile in user & kernel space.
71 * 02/28/02 brr Do not include any QMgr include files.
72 * 02/26/02 brr KMALLOC API requests.
73 * 02/25/02 brr Removed last references to the queue pointer.
74 * 02/22/02 spm Converted printk's to DBG's.
75 * 01/31/02 brr Removed separate memory allocation for the command blocks.
76 * 01/23/02 brr Removed obsolete addBlockToFree & removeBlockFromFreeList.
77 * 01/23/02 brr Modified functions to reduce the number if memory allocations.
78 * 01/12/02 bac Fixed a bug in _addBlockToFree to correctly mark entries if
79 * they are KERNEL. Also changed n8_handleEvent to scan for the
80 * last request in the list.
81 * 11/27/01 bac Added n8_handleEvent method.
82 * 11/11/01 bac Added n8_sizedBufferCmp prototype.
83 * 11/06/01 dkm Added check for error ret from QMgr_get_control_struct.
84 * 10/30/01 bac Added n8_incrLength64 and n8_decrLength64
85 * 10/11/01 hml Added n8_strdup.
86 * 10/08/01 hml Added printHWError
87 * 09/20/01 bac Cleaned up signatures w.r.t. unsigned and const modifiers.
88 * 09/18/01 bac Modified createEARequestBuffer to accept the number of
89 * commands, allocate the command buffer, and set the numNewCmds
90 * field.
91 * 09/14/01 bac Support for command block printing.
92 * 08/30/01 msz Eliminated numCmdBlksProcessed from API_req_t
93 * 08/27/01 msz Renamed FcnCalledOnRequestCompletionOrError to callback
94 * 08/24/01 bac Modified createPKRequestBuffer to accept the number of
95 * commands, allocate the command buffer, and set the numNewCmds
96 * field.
97 * 07/30/01 bac Set the queue_p in the [PK|EA]RequestBuffer.
98 * 07/20/01 bac Added chip id to calls to create[PK|EA]RequestBuffer.
99 * 07/02/01 mel Fixed comments.
100 * 06/25/01 bac Bug fixes to free list management.
101 * 06/19/01 bac Added prototype for addMemoryStructToFree and updated
102 * freeRequest to handle N8_MemoryHandle_t entries
103 * 06/17/01 bac Added removeBlockFromFreeList
104 * 05/19/01 bac Removed free of postProcessingData. Decision should live in
105 * the handler.
106 * 05/19/01 bac Fixed memory leak by freeing the free list when done
107 * and freeing postProcessingData_p when done.
108 * 05/18/01 bac Converted to N8_xMALLOC and N8_xFREE
109 * 05/03/01 bac Added include for string.h
110 * 04/30/01 bac Fixed a comment.
111 * 04/26/01 bac Added test to freeRequest to ensure the pointer is
112 * not null.
113 * 04/24/01 bac Original version.
114 ****************************************************************************/
115 /** @defgroup api_util API Utility Functions
117 #include "n8_pub_buffer.h"
118 #include "n8_pub_request.h"
119 #include "n8_util.h"
120 #include "n8_driver_api.h"
121 #include <opencrypto/cryptodev.h>
123 extern NSPdriverInfo_t nspDriverInfo;
124 extern N8_Status_t N8_EventWait(N8_Event_t *events_p, const int count, int *ready_p);
126 /*****************************************************************************
127 * printN8Buffer
128 *****************************************************************************/
129 /** @ingroup api_util
130 * @brief Prints N8_Buffer_t
132 * Given an N8_Buffer_t and the size, print the buffer as hex digits.
134 * @param p RW: pointer to buffer to print
135 * @param size RW: size of buffer
137 * @par Externals
138 * None
141 * @par Errors
142 * None
144 * @par Assumptions
145 * None
146 *****************************************************************************/
147 void printN8Buffer(N8_Buffer_t *p, const unsigned int size)
149 int i;
150 unsigned char *ptr = p;
152 for (i=0; i < size; i++)
154 N8_PRINT( "%02x", (*ptr++) & 0xff);
155 if (((i+1) % PK_Bytes_Per_BigNum_Digit) == 0)
157 N8_PRINT( "\n");
160 N8_PRINT( "\n");
161 } /* printN8Buffer */
163 /*****************************************************************************
164 * n8_displayBuffer
165 *****************************************************************************/
166 /** @ingroup n8_bn
167 * @brief Display a big number.
169 * Print a readable big number representation to STDOUT.
171 * @param buf_p RO: the big number to display.
172 * @param length RO: length of big number in bytes.
173 * @param name RO: name to identify the big number.
175 * @par Externals
176 * None
178 * @par Errors
179 * None
181 * @par Assumptions
182 * Name is not null.
183 *****************************************************************************/
184 void n8_displayBuffer(N8_Buffer_t *buf_p, const uint32_t length, const char *name)
186 if (length != 0 && buf_p != NULL)
188 N8_PRINT( "%s length=%d mem=0x%x\n", name, length, (unsigned int) buf_p);
189 printN8Buffer(buf_p, length);
191 } /* n8_displayBuffer */
192 /*****************************************************************************
193 * createPKRequestBuffer
194 *****************************************************************************/
195 /** @ingroup api_util
196 * @brief Allocate and initialize request buffer
198 * Initialize a PK Request Buffer before use.
200 * @param req_pp RW: Pointer-to-pointer of structure to be initialized
201 * @param numCmds RO: number of commands in this request
202 * @param callbackFcn RO: pointer to callback function
203 * @param dataBytes RO: number of bytes to allocate for data
205 * @par Externals
206 * gRequestIndex RW: counter is incremented
208 * @par Errors
209 * None<br>
211 * @par Assumptions
212 * Allocated space will be freed by the caller.
213 *****************************************************************************/
214 N8_Status_t createPKRequestBuffer(API_Request_t **req_pp,
215 const N8_Unit_t chip,
216 const unsigned int numCmds,
217 const void *callbackFcn,
218 const unsigned int dataBytes)
220 N8_Status_t ret = N8_STATUS_OK;
221 API_Request_t *req_p;
222 N8_MemoryHandle_t *kmem_p;
225 kmem_p = N8_AllocateBufferPK(sizeof(API_Request_t) +
226 (numCmds * sizeof(PK_CMD_BLOCK_t)) + dataBytes);
228 if (kmem_p == NULL)
230 ret = N8_MALLOC_FAILED;
231 break;
233 req_p = (API_Request_t *)kmem_p->VirtualAddress;
234 *req_pp = req_p;
235 memset(*req_pp, 0x0, sizeof(API_Request_t) + (numCmds * sizeof(PK_CMD_BLOCK_t)) + dataBytes);
236 (*req_pp)->qr.requestStatus = N8_QUEUE_REQUEST_SENT_FROM_API;
237 (*req_pp)->qr.requestError = N8_QUEUE_REQUEST_OK;
238 (*req_pp)->qr.unit = N8_PKP;
239 (*req_pp)->qr.chip = chip;
240 (*req_pp)->qr.callback = callbackFcn;
241 (*req_pp)->qr.physicalAddress = kmem_p->PhysicalAddress;
242 (*req_pp)->qr.synchronous = N8_FALSE;
244 /* set ALL nonzero values in the API Request */
245 (*req_pp)->numNewCmds = numCmds;
246 (*req_pp)->copyBackCommandBlock = N8_FALSE;
247 (*req_pp)->PK_CommandBlock_ptr = (PK_CMD_BLOCK_t *)
248 ((int)(*req_pp) + sizeof(API_Request_t));
249 (*req_pp)->dataoffset = sizeof(API_Request_t) +
250 (numCmds * sizeof(PK_CMD_BLOCK_t));
252 while (FALSE);
253 return ret;
254 } /* createPKRequestBuffer */
256 /*****************************************************************************
257 * initializeEARequestBuffer
258 *****************************************************************************/
259 /** @ingroup api_util
260 * @brief Initialize request buffer
262 * Initialize a EA Request Buffer before use.
264 * @param req_p RW: Pointer of structure to be initialized
265 * @param numCmds RO: number of commands in this request
266 * @param callbackFcn RO: pointer to callback function
267 * @param dataBytes RO: number of bytes to allocate for data
269 * @par Externals
270 * None
272 * @par Errors
273 * None<br>
275 * @par Assumptions
276 * Allocated space will be freed by the caller.
277 *****************************************************************************/
279 void initializeEARequestBuffer(API_Request_t *req_p,
280 N8_MemoryHandle_t *kmem_p,
281 const N8_Unit_t chip,
282 const unsigned int numCmds,
283 const void *callbackFcn,
284 N8_Boolean_t userRequest)
286 memset(req_p, 0x0, sizeof(API_Request_t) + (numCmds * sizeof(EA_CMD_BLOCK_t)));
287 req_p->qr.requestStatus = N8_QUEUE_REQUEST_SENT_FROM_API;
288 req_p->qr.requestError = N8_QUEUE_REQUEST_OK;
289 req_p->qr.unit = N8_EA;
290 req_p->qr.chip = chip;
291 req_p->qr.callback = callbackFcn;
292 req_p->qr.physicalAddress = kmem_p->PhysicalAddress;
293 /* req_p->qr.synchronous = N8_FALSE; */
294 req_p->userRequest = userRequest;
296 /* set ALL nonzero values in the API Request */
297 req_p->EA_CommandBlock_ptr = (EA_CMD_BLOCK_t *)
298 ((int)(req_p) + sizeof(API_Request_t));
299 req_p->numNewCmds = numCmds;
300 /* req_p->copyBackCommandBlock = N8_FALSE; */
301 if (userRequest == N8_TRUE)
303 req_p->dataoffset = sizeof(API_Request_t) +
304 N8_COMMAND_BLOCK_BYTES + N8_CTX_BYTES;
306 else
308 req_p->dataoffset = sizeof(API_Request_t) +
309 (numCmds * sizeof(EA_CMD_BLOCK_t));
311 } /* initializeEARequestBuffer */
313 /*****************************************************************************
314 * createEARequestBuffer
315 *****************************************************************************/
316 /** @ingroup api_util
317 * @brief Allocate and initialize request buffer
319 * Initialize a EA Request Buffer before use.
321 * @param req_pp RW: Pointer-to-pointer of structure to be initialized
322 * @param numCmds RO: number of commands in this request
323 * @param callbackFcn RO: pointer to callback function
324 * @param dataBytes RO: number of bytes to allocate for data
326 * @par Externals
327 * None
329 * @par Errors
330 * None<br>
332 * @par Assumptions
333 * Allocated space will be freed by the caller.
334 *****************************************************************************/
336 N8_Status_t createEARequestBuffer(API_Request_t **req_pp,
337 const N8_Unit_t chip,
338 const unsigned int numCmds,
339 const void *callbackFcn,
340 const unsigned int dataBytes)
342 N8_Status_t ret = N8_STATUS_OK;
343 N8_MemoryHandle_t *kmem_p;
346 kmem_p = N8_KMALLOC(sizeof(API_Request_t) +
347 (numCmds * sizeof(EA_CMD_BLOCK_t)) + dataBytes);
349 if (kmem_p == NULL)
351 ret = N8_MALLOC_FAILED;
352 break;
354 *req_pp = (API_Request_t *)kmem_p->VirtualAddress;
356 initializeEARequestBuffer(*req_pp,
357 kmem_p,
358 chip,
359 numCmds,
360 callbackFcn,
361 N8_FALSE);
363 while (FALSE);
364 return ret;
365 } /* createEARequestBuffer */
367 N8_Status_t n8_handleEvent(N8_Event_t *e_p,
368 void *hReq_p,
369 N8_Unit_t unit,
370 N8_QueueStatusCodes_t requestStatus)
372 N8_Status_t ret = N8_STATUS_OK;
373 QMgrRequest_t *req_p;
375 req_p = (QMgrRequest_t *)hReq_p;
377 if (e_p != NULL)
379 /* This is an asynchronous request */
380 e_p->state = (void *) req_p;
381 e_p->status = requestStatus;
382 e_p->unit = unit;
383 #ifdef SUPPORT_CALLBACK_THREAD
384 if ((e_p->usrCallback != NULL) ||
385 (e_p->usrData != NULL))
387 ret = queueEvent(e_p);
389 #endif
391 else
393 /* This is an synchronous request. Therefore we don't need an */
394 /* event, we know that the request has completed. */
395 #ifdef SUPPORT_DEVICE_POLL
396 N8_QMgrDequeue();
397 #endif
398 if ( req_p->requestError != N8_QUEUE_REQUEST_ERROR )
400 /* Do the callback if needed. */
401 if ( req_p->callback != NULL )
403 req_p->callback( req_p );
405 /* Free the request if the event has completed successfully. */
406 /* If not the error handling should free the request. */
407 if (((API_Request_t *)req_p)->userRequest != N8_TRUE)
409 /* Don't delete "user allocated/ pooled" requests */
410 freeRequest( (API_Request_t *)req_p );
413 else
415 ret = N8_HARDWARE_ERROR;
418 return ret;
419 } /* n8_handleEvent */
421 void printCommandBlock(uint32_t *u, unsigned int size)
423 int k;
424 int num = size / 4;
425 for (k = 0; k < num; k++)
427 N8_PRINT( "%08x", u[k]);
428 if ((k+1) % 8)
430 N8_PRINT( "|");
432 else
434 if (k < (num - 1))
436 N8_PRINT(( "\n "));
438 else
440 N8_PRINT(( "\n"));
444 } /* printCommandBlock */
446 void printPKCommandBlocks(const char *title, PK_CMD_BLOCK_t *block_p, uint32_t num_blocks)
448 int i = 0;
449 char * ptr;
451 N8_PRINT( "%s\n", title);
452 for(i = 0; i < num_blocks; i++)
454 ptr = (char *) &block_p[i];
455 N8_PRINT( "%3d: ", i+1);
456 printCommandBlock((uint32_t *) &block_p[i], sizeof(PK_CMD_BLOCK_t));
458 } /* printPKCommandBlocks */
460 void printEACommandBlocks(const char *title, EA_CMD_BLOCK_t *block_p, uint32_t num_blocks)
462 int i = 0;
463 char * ptr;
465 N8_PRINT( "%s\n", title);
466 for(i = 0; i < num_blocks; i++)
468 ptr = (char *) &block_p[i];
469 N8_PRINT( "%3d: ", i+1);
470 printCommandBlock((uint32_t *) &block_p[i], sizeof(EA_CMD_BLOCK_t));
472 } /* printEACommandBlocks */
474 static void printErrorCode(uint32_t errorCode, uint32_t errors[], const char *errorNames[], unsigned int num)
476 int i;
477 for (i = 0; i < num; i++)
479 if (errorCode & errors[i])
481 N8_PRINT( " %s\n", errorNames[i]);
484 } /* printError */
486 void printHWError(uint32_t errCode, N8_Component_t unit)
488 uint32_t PKErrors[] =
490 PK_Status_SKS_Offset_Error,
491 PK_Status_Length_Error,
492 PK_Status_Opcode_Error,
493 PK_Status_Q_Align_Error,
494 PK_Status_Read_Data_Error,
495 PK_Status_Write_Data_Error,
496 PK_Status_Read_Opcode_Error,
497 PK_Status_Access_Error,
498 PK_Status_Reserved_Error,
499 PK_Status_Timer_Error,
500 PK_Status_Prime_Error,
501 PK_Status_Invalid_B_Error,
502 PK_Status_Invalid_A_Error,
503 PK_Status_Invalid_M_Error,
504 PK_Status_Invalid_R_Error,
505 PK_Status_PKE_Opcode_Error
507 const char *PKErrorNames[] =
509 "PK_Status_SKS_Offset_Error",
510 "PK_Status_Length_Error",
511 "PK_Status_Opcode_Error",
512 "PK_Status_Q_Align_Error",
513 "PK_Status_Read_Data_Error",
514 "PK_Status_Write_Data_Error",
515 "PK_Status_Read_Opcode_Error",
516 "PK_Status_Access_Error",
517 "PK_Status_Reserved_Error",
518 "PK_Status_Timer_Error",
519 "PK_Status_Prime_Error",
520 "PK_Status_Invalid_B_Error",
521 "PK_Status_Invalid_A_Error",
522 "PK_Status_Invalid_M_Error",
523 "PK_Status_Invalid_R_Error",
524 "PK_Status_PKE_Opcode_Error"
526 uint32_t EAErrors[] =
528 EA_Status_Q_Align_Error,
529 EA_Status_Cmd_Complete,
530 EA_Status_Opcode_Error,
531 EA_Status_CMD_Read_Error,
532 EA_Status_CMD_Write_Error,
533 EA_Status_Data_Read_Error,
534 EA_Status_Data_Write_Error,
535 EA_Status_EA_Length_Error,
536 EA_Status_Data_Length_Error,
537 EA_Status_EA_DES_Error,
538 EA_Status_DES_Size_Error,
539 EA_Status_DES_Parity_Error,
540 EA_Status_ARC4_Error,
541 EA_Status_MD5_Error,
542 EA_Status_SHA1_Error,
543 EA_Status_Access_Error
545 const char *EAErrorNames[] =
547 "EA_Status_Q_Align_Error",
548 "EA_Status_Cmd_Complete",
549 "EA_Status_Opcode_Error",
550 "EA_Status_CMD_Read_Error",
551 "EA_Status_CMD_Write_Error",
552 "EA_Status_Data_Read_Error",
553 "EA_Status_Data_Write_Error",
554 "EA_Status_EA_Length_Error",
555 "EA_Status_Data_Length_Error",
556 "EA_Status_EA_DES_Error",
557 "EA_Status_DES_Size_Error",
558 "EA_Status_DES_Parity_Error",
559 "EA_Status_ARC4_Error",
560 "EA_Status_MD5_Error",
561 "EA_Status_SHA1_Error",
562 "EA_Status_Access_Error"
565 switch (unit)
567 case N8_PKP:
568 DBG(( "PK Errors encountered:\n"));
569 printErrorCode(errCode, PKErrors, PKErrorNames,
570 sizeof(PKErrors) / sizeof(uint32_t));
571 break;
572 case N8_RNG:
573 DBG(( "RNG Errors encountered:\n"));
574 break;
575 case N8_EA:
576 DBG(( "EA Errors encountered:\n"));
577 printErrorCode(errCode, EAErrors, EAErrorNames,
578 sizeof(EAErrors) / sizeof(uint32_t));
579 default:
580 break;
583 } /* printHWError */
585 /*****************************************************************************
586 * n8_strdup
587 *****************************************************************************/
588 /** @ingroup api_util
589 * @brief Net Octave portable implementation of strdup
591 * Some compilers don't see strdup as an ansi function, so we wrote
592 * our own.
594 * @param str_p RO: The string to duplicate.
596 * @par Externals:
597 * None.
599 * @return
600 * This function returns a pointer to the newly allocated copy of
601 * the string, or NULL if the input pointer is NULL or the
602 * N8_UMALLOC fails.
604 * @par Errors:
605 * See above.
607 * @par Locks:
608 * None.
610 * @par Assumptions:
611 * The caller of this function takes the responsibility of
612 * freeing the string.
613 *****************************************************************************/
614 char *n8_strdup(const char *str_p)
616 char *ret_p;
617 int nBytes;
619 if (str_p == NULL)
621 return(NULL);
624 nBytes = strlen(str_p);
626 ret_p = N8_UMALLOC(nBytes + 1);
628 if (ret_p == NULL)
630 return(NULL);
633 memcpy(ret_p, str_p, nBytes + 1);
634 return(ret_p);
635 } /* n8_strdup */
637 /*****************************************************************************
638 * n8_incrLength64
639 *****************************************************************************/
640 /** @ingroup api_util
641 * @brief Given a 64 bit length field, split across two 32 bit quantities,
642 * properly increment by a given length.
644 * @param hi_word_p RW: pointer to higher order word of length
645 * @param lo_word_p RW: pointer to lower order word of length
646 * @param length RO: increment amount
648 * @par Externals
649 * None
651 * @par Errors
652 * None
654 * @par Assumptions
655 * None
656 *****************************************************************************/
657 void n8_incrLength64(uint32_t *hi_word_p,
658 uint32_t *lo_word_p,
659 const uint32_t length)
661 uint32_t incrementLength;
662 /* accumulate the length */
663 incrementLength = *lo_word_p + length;
664 if (incrementLength < *lo_word_p)
666 (*hi_word_p)++;
668 *lo_word_p = incrementLength;
669 } /* n8_incrLength64 */
671 /*****************************************************************************
672 * n8_decrLength64
673 *****************************************************************************/
674 /** @ingroup api_util
675 * @brief Given a 64 bit length field, split across two 32 bit quantities,
676 * properly decrement by a given length.
678 * @param hi_word_p RW: pointer to higher order word of length
679 * @param lo_word_p RW: pointer to lower order word of length
680 * @param length RO: decrement amount
682 * @par Externals
683 * None
685 * @par Errors
686 * None
688 * @par Assumptions
689 * None
690 *****************************************************************************/
691 void n8_decrLength64(uint32_t *hi_word_p,
692 uint32_t *lo_word_p,
693 const uint32_t length)
695 uint32_t decrementLength;
696 /* accumulate the length */
697 decrementLength = *lo_word_p - length;
698 if (decrementLength > *lo_word_p)
700 (*hi_word_p)--;
702 *lo_word_p = decrementLength;
703 } /* n8_decrLength64 */
705 /*****************************************************************************
706 * n8_sizedBufferCmp
707 *****************************************************************************/
708 /** @ingroup api_util
709 * @brief Performs comparison between two N8_SizedBuffer_t.
711 * Compare the values of a and b. Return<br>
713 * @param a_p RO: pointer to first N8_SizedBuffer_t
714 * @param b_p RO: pointer to second N8_SizedBuffer_t
716 * @par Externals
717 * None
719 * @return
720 * -1: if a < b <br>
721 * 0: if a == b <br>
722 * 1: if a > b <br>
724 * @par Errors
725 * None
727 * @par Assumptions
728 * None
729 *****************************************************************************/
730 int n8_sizedBufferCmp(const N8_SizedBuffer_t *a_p,
731 const N8_SizedBuffer_t *b_p)
733 if ((a_p == NULL) || (b_p == NULL))
735 if (a_p != NULL)
737 return -1;
739 else if (b_p != NULL)
741 return 1;
743 else
745 return 0;
749 if (a_p->lengthBytes == b_p->lengthBytes)
751 int cmp;
752 cmp = memcmp(a_p->value_p, b_p->value_p, a_p->lengthBytes);
753 if (cmp == 0)
755 return 0;
757 else if (cmp > 0)
759 return 1;
761 else
763 return -1;
766 else if (a_p->lengthBytes < b_p->lengthBytes)
768 return -1;
770 else
772 return 1;
774 } /* n8_sizeBufferCmp */
776 /**********************************************************************
777 * resultHandlerHashEnd
779 * Description:
780 * This function is called by the Public Key Request Queue handler when
781 * either the request is completed successfully and all the commands
782 * copied back to the command blocks allocated by the API, or when
783 * the Simon has encountered an error with one of the commands such
784 * that the Simon has locked up.
786 * Copy the results from the kernel buffer to the buffer originally
787 * supplied by the user. The kernel buffer must be the virtual address
788 * of the N8_MemoryHandle_t.
790 * Note this function will have to be NON-BLOCKING or it will lock up the
791 * queue handler!
793 * NOTE: This function is also used by N8_HashCompleteMessage.
796 **********************************************************************/
797 /*****************************************************************************
798 * resultHandlerGeneric
799 *****************************************************************************/
800 /** @ingroup api_util
801 * @brief Generic result handler -- a callback function for API requests.
803 * This function is called by the Queue Manager when either the request is
804 * completed successfully or terminated upon an error. This generic version
805 * checks for success and if found will copy results back to the user space
806 * using the generic mechanism copyBackFrom_p -> copyBackTo_p a length of
807 * copyBackSize bytes.
809 * @param req_p RW: API request structure for the request which
810 * has just completed.
812 * @par Externals
813 * None
815 * @par Errors
816 * None
818 * @par Assumptions
819 * The request is freed elsewhere. No unusual processing must be done. If
820 * such processing is required, a custom result handler must be written.
821 *****************************************************************************/
822 void resultHandlerGeneric(API_Request_t* req_p)
824 const char *title = "resultHandlerGeneric";
825 if (req_p->qr.requestError == N8_QUEUE_REQUEST_OK)
827 DBG(("%s call-back with success\n", title));
828 /* perform the copy back if necessary */
829 if (req_p->copyBackSize != 0 &&
830 req_p->copyBackFrom_p != NULL &&
831 (req_p->copyBackTo_p != NULL || req_p->copyBackTo_uio != NULL))
833 if (req_p->copyBackTo_p != NULL) {
834 #if N8DEBUG
835 int size = req_p->copyBackSize;
836 int i;
837 if (size > 20) size=20;
838 DBG(("memcpy %d bytes\n",req_p->copyBackSize));
839 printf("result: ");
840 for (i=0; i<size; i+=4) {
841 printf("%08x ", *(uint32_t *)
842 (&req_p->copyBackFrom_p[i]));
844 printf("\n");
845 #endif
846 memcpy(req_p->copyBackTo_p, req_p->copyBackFrom_p,
847 req_p->copyBackSize);
848 } else {
849 #if N8DEBUG
850 DBG(("cuio_copyback %d bytes\n",req_p->copyBackSize));
851 DBG(("result: %08x|%08x|%08x|%08x\n",
852 *(((uint32_t *)req_p->copyBackFrom_p)),
853 *(((uint32_t *)req_p->copyBackFrom_p)+1),
854 *(((uint32_t *)req_p->copyBackFrom_p)+2),
855 *(((uint32_t *)req_p->copyBackFrom_p)+3)));
856 #endif
857 cuio_copydata(req_p->copyBackTo_uio, 0, req_p->copyBackSize,
858 req_p->copyBackFrom_p);
862 else
864 RESULT_HANDLER_WARNING(title, req_p);
866 /* do not free the request here */
867 } /* resultHandlerGeneric */
869 /*****************************************************************************
870 * n8_verifyunit
871 *****************************************************************************/
872 /** @ingroup util
873 * @brief Check to see if a specified unit ID is valid. Does not resolve
874 * N8_ANY_UNIT, but will allow it.
876 * @param chip RO: Chip number to verify.
879 * @return
880 * An N8_Boolean_t indicating whether or not the unit is valid.
882 * @par Errors
883 * N8_STATUS_OK, N8_MALLOC_FAILED
885 * @par Assumptions
886 * None
887 *****************************************************************************/
888 N8_Boolean_t n8_validateUnit(N8_Unit_t chip)
890 if (chip == N8_ANY_UNIT || chip < nspDriverInfo.numChips)
892 return (N8_TRUE);
894 else
896 return (N8_FALSE);
898 } /* n8_validateUnit */