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_util.c,v 1.1 2008/10/30 12:02:15 darran Exp $";
36 /*****************************************************************************/
40 * Loose collection of utility functions used across the N8 methods.
42 *****************************************************************************/
44 /*****************************************************************************
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
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
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
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
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
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
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"
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 /*****************************************************************************
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
146 *****************************************************************************/
147 void printN8Buffer(N8_Buffer_t
*p
, const unsigned int size
)
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)
161 } /* printN8Buffer */
163 /*****************************************************************************
165 *****************************************************************************/
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.
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
206 * gRequestIndex RW: counter is incremented
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
);
230 ret
= N8_MALLOC_FAILED
;
233 req_p
= (API_Request_t
*)kmem_p
->VirtualAddress
;
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
));
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
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
;
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
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
);
351 ret
= N8_MALLOC_FAILED
;
354 *req_pp
= (API_Request_t
*)kmem_p
->VirtualAddress
;
356 initializeEARequestBuffer(*req_pp
,
365 } /* createEARequestBuffer */
367 N8_Status_t
n8_handleEvent(N8_Event_t
*e_p
,
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
;
379 /* This is an asynchronous request */
380 e_p
->state
= (void *) req_p
;
381 e_p
->status
= requestStatus
;
383 #ifdef SUPPORT_CALLBACK_THREAD
384 if ((e_p
->usrCallback
!= NULL
) ||
385 (e_p
->usrData
!= NULL
))
387 ret
= queueEvent(e_p
);
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
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
);
415 ret
= N8_HARDWARE_ERROR
;
419 } /* n8_handleEvent */
421 void printCommandBlock(uint32_t *u
, unsigned int size
)
425 for (k
= 0; k
< num
; k
++)
427 N8_PRINT( "%08x", u
[k
]);
444 } /* printCommandBlock */
446 void printPKCommandBlocks(const char *title
, PK_CMD_BLOCK_t
*block_p
, uint32_t num_blocks
)
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
)
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
)
477 for (i
= 0; i
< num
; i
++)
479 if (errorCode
& errors
[i
])
481 N8_PRINT( " %s\n", errorNames
[i
]);
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
,
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"
568 DBG(( "PK Errors encountered:\n"));
569 printErrorCode(errCode
, PKErrors
, PKErrorNames
,
570 sizeof(PKErrors
) / sizeof(uint32_t));
573 DBG(( "RNG Errors encountered:\n"));
576 DBG(( "EA Errors encountered:\n"));
577 printErrorCode(errCode
, EAErrors
, EAErrorNames
,
578 sizeof(EAErrors
) / sizeof(uint32_t));
585 /*****************************************************************************
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
594 * @param str_p RO: The string to duplicate.
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
611 * The caller of this function takes the responsibility of
612 * freeing the string.
613 *****************************************************************************/
614 char *n8_strdup(const char *str_p
)
624 nBytes
= strlen(str_p
);
626 ret_p
= N8_UMALLOC(nBytes
+ 1);
633 memcpy(ret_p
, str_p
, nBytes
+ 1);
637 /*****************************************************************************
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
656 *****************************************************************************/
657 void n8_incrLength64(uint32_t *hi_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
)
668 *lo_word_p
= incrementLength
;
669 } /* n8_incrLength64 */
671 /*****************************************************************************
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
690 *****************************************************************************/
691 void n8_decrLength64(uint32_t *hi_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
)
702 *lo_word_p
= decrementLength
;
703 } /* n8_decrLength64 */
705 /*****************************************************************************
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
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
))
739 else if (b_p
!= NULL
)
749 if (a_p
->lengthBytes
== b_p
->lengthBytes
)
752 cmp
= memcmp(a_p
->value_p
, b_p
->value_p
, a_p
->lengthBytes
);
766 else if (a_p
->lengthBytes
< b_p
->lengthBytes
)
774 } /* n8_sizeBufferCmp */
776 /**********************************************************************
777 * resultHandlerHashEnd
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
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.
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
) {
835 int size
= req_p
->copyBackSize
;
837 if (size
> 20) size
=20;
838 DBG(("memcpy %d bytes\n",req_p
->copyBackSize
));
840 for (i
=0; i
<size
; i
+=4) {
841 printf("%08x ", *(uint32_t *)
842 (&req_p
->copyBackFrom_p
[i
]));
846 memcpy(req_p
->copyBackTo_p
, req_p
->copyBackFrom_p
,
847 req_p
->copyBackSize
);
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)));
857 cuio_copydata(req_p
->copyBackTo_uio
, 0, req_p
->copyBackSize
,
858 req_p
->copyBackFrom_p
);
864 RESULT_HANDLER_WARNING(title
, req_p
);
866 /* do not free the request here */
867 } /* resultHandlerGeneric */
869 /*****************************************************************************
871 *****************************************************************************/
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.
880 * An N8_Boolean_t indicating whether or not the unit is valid.
883 * N8_STATUS_OK, N8_MALLOC_FAILED
887 *****************************************************************************/
888 N8_Boolean_t
n8_validateUnit(N8_Unit_t chip
)
890 if (chip
== N8_ANY_UNIT
|| chip
< nspDriverInfo
.numChips
)
898 } /* n8_validateUnit */