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: nsp_ioctl.c,v 1.1 2008/10/30 12:02:14 darran Exp $";
36 /*****************************************************************************/
38 * @brief NSP2000 Device Driver IOCtl Handler.
40 * This file implements the common IOCtl handler for the NSP2000 device driver.
42 *****************************************************************************/
44 /*****************************************************************************
46 * 05/06/03 brr Pass back the status returned by N8_WaitOnRequest.
47 * 05/08/03 brr Added support for multiple user pools.
48 * 04/21/03 brr Added support for multiple memory banks.
49 * 04/01/03 brr Reverted N8_WaitOnRequest to accept timeout parameter.
50 * 03/20/03 brr Modified nspdebug to display QMgr statistics.
51 * 03/19/03 brr Modified nspdebug to display interrupt statistics.
52 * 03/19/03 brr Modified N8_WaitOnRequest to post on a specific request.
53 * 03/10/03 brr Set userSpace flag in API requests.
54 * 10/25/02 brr Clean up function prototypes & include files.
55 * 10/22/02 brr Verify driver mode in NSP_IOCTL_GET_DEVICE_RESOURCES.
56 * 10/10/02 brr Modified diagnostic ioctl to accept chip number.
57 * 09/18/02 brr Added ioctls for diagnostics & wait on request.
58 * 07/24/02 jpw Added NSP_IOCTL_QMGR_QUEUE ioctl again which QMgrQueue
59 * needs to avoid performance problems under Linux 2.2 with
61 * 07/08/02 brr Moved QMgrQueue operation to a write call.
62 * 07/02/02 brr Added ioctl to retrieve memory statistics.
63 * 06/26/02 brr Remove bank parameter from calls to N8_PhysToVirt.
64 * 06/25/02 brr Rework user pool allocation to only mmap portion used by
65 * the individule process.
66 * 06/14/02 hml Set requestPoolSize to 0 if we fail to allocate the
68 * 06/12/02 hml N8_PhysToVirt calls now get an additional parameter.
69 * 06/10/02 hml NSP_IOCTL_GET_DEVICE_RESOURCES now allocates the user
71 * 05/30/02 brr Removed obsolete HALT_ON_BUS_ERRORS.
72 * 05/22/02 hml Passed memCtlBank parameter to call to n8_pmalloc
74 * 05/15/02 brr Reworked RNG Ioctls to remove KMALLOC requirements.
75 * 04/11/02 brr Pass parameter to waitOnInterrupt to indicate whether
76 * sleep should be interruptable.
77 * 04/03/02 spm Removed remnants of the reverse-ioctl that the daemon
78 * formerly used (start, finish, shutdown). Removed #include
79 * of n8_daemon_internals.h
80 * 04/02/02 spm SKS re-architecture. Modified DAEMON_SYS_INIT ioctl so that
81 * SKS initialization is accomplished by a single forward
82 * ioctl, making the daemon unnecessary.
83 * 03/29/02 brr Added support to display the NSP 2000 register set.
84 * 03/29/02 hml Added handle of NSP_IOCTL_VALIDATE_CONTEXT (BUGS 657 658).
85 * 03/26/02 hml n8_contextfree/n8_contextalloc return a status code. (BUG 637)
86 * 03/22/02 hml NSP_IOCTL_ALLOCATE_CONTEXT now calls the correct function
87 * and NSP_IOCTL_DEBUG_MESSAGES prints the context
88 * debugging information.
89 * 03/21/02 mmd Implemented NSP_IOCTL_QUERY_QUEUE_STATS.
90 * 03/21/02 brr Removed unneeded api include file.
91 * 03/18/02 brr Reduce parameters & pass sessionID to resource allocation
93 * 03/01/02 msz Don't copy RN requests, they too are now KMALLOCed
94 * 02/25/02 brr Fix daemon start/stop. Do not copy API requests since they
96 * 02/27/02 msz Fixes in N8_WaitOnInterrupt call
97 * 02/25/02 brr Removed copying of all parameters TO/FROM user space on every
98 * call. Also deleted obsolete IOCTL's.
99 * 02/22/02 spm Converted printk's to DBG's.
100 * 02/25/02 msz Added SKS ioctl's.
101 * 02/19/02 msz Added RNG ioctl's.
102 * 02/18/02 brr Added QMgr ioctl's.
103 * 02/15/02 brr Removed FPGA specific ioctl's.
104 * 02/13/02 brr Only use DAEMON IOCTLS's if not VxWorks.
105 * 01/21/02 spm Added NSP_IOCTL_N8_DAEMON_SYS_INIT ioctl to handle
106 * any initialization that requires the N8 daemon to
107 * be running already (like SKS initialization using
109 * 01/19/02 spm Changed n8_daemon_kernel.h to n8_daemon_internals.h
110 * 01/17/02 spm Added NSP_IOCTL_N8_DAEMON_SHUTDOWN ioctl to handle shutdown
111 * requests from userspace (uninstall script).
112 * 01/17/02 brr Support new memory allocation scheme.
113 * 01/16/02 brr Removed obsolete include file.
114 * 01/16/02 spm Added NSP_IOCTL_N8_DAEMON_START, NSP_IOCTL_N8_DAEMON_FINISH
115 * ioctls for N8 daemon support.
116 * 01/02/02 hml Changed to use N8_API_Parms_t instead of API_PARMS_t.
117 * 12/18/01 brr Added display of kernal memory structures.
118 * 12/14/01 brr Support memory management performance improvements.
119 * 11/27/01 mmd Eliminated NSP_IOCTL_ENABLE_IRQ.
120 * 11/29/01 brr Added n8_dispatchAPI
121 * 11/15/01 mmd Moved admxrc_set_clock calls to admxrc_load_fpga.
122 * 11/14/01 mmd Updated NSP_IOCTL_DEBUG_MESSAGES to allow applications to
123 * force the driver to release or re-allocate static resources.
124 * Mainly for diags to release resources and use the memory
125 * pool as they see fit.
126 * 11/10/01 brr Modified to support static allocations of persistant data
128 * 11/06/01 mmd Migrated ADMXRC_PLX_EEPROM_RD into NSP_IOCTL_GET_FPGA_INFO,
129 * and ADMXRC_FPGA_LOAD into NSP_IOCTL_PROGRAM_FPGA. Eliminated
130 * NSP_IOCTL_FPGA_LOCK, NSP_IOCTL_FPGA_UNLOCK, and
132 * 10/26/01 mmd Updated call to n8_DeallocateBuffer.
133 * 10/16/01 mmd Revised debug info to a single parm - debug. Revised all
134 * branches accordingly, and added new branch for
135 * NSP_IOCTL_DEBUG_MESSAGES.
136 * 10/12/01 mmd Renamed Atomic*() routines to N8_Atomic*().
137 * 10/12/01 mmd Now only returns -EINVAL in case of failure.
138 * 10/02/01 mmd Modified NSP_IOCTL_FPGA_LOCK to return a busy indicator
139 * instead of doing a while loop, to eliminate the potential
140 * for a nasty kernel hang.
141 * 09/26/01 mmd Fixed segfault in N8_IOCtlHandler where the FPGAflag field
142 * of NspInstance_t was always getting referenced even if
143 * a pseudo device was being used.
144 * 09/25/01 mmd Added NSP_IOCTL_GET_CONFIG_ITEM branch. Eliminated FPGAflag
145 * as a parameter - now using the IsFPGA field of
147 * 09/24/01 mmd Fixed bug in NSP_IOCTL_WAIT_ON_INTERRUPT - not returning
148 * the correct sampled control/status register value, and added
149 * support for blocking on AMBA interrupts, and corrected
151 * 09/19/01 mmd Creation.
152 ****************************************************************************/
153 /** @defgroup NSP2000Driver NSP2000 Device Driver IOCtl Handler.
158 #include "n8_driver_main.h"
159 #include "n8_driver_parms.h"
160 #include "n8_malloc_common.h"
162 #include "displayRegs.h"
164 #include "nsp_ioctl.h"
165 #include "n8_daemon_common.h"
166 #include "n8_sksInit.h"
167 #include "n8_memory.h"
168 #include "n8_enqueue_common.h"
169 #include "n8_SKSManager.h"
171 #include "RN_Queue.h"
172 #include "QMgrInit.h"
174 #include "n8_pub_common.h"
175 #include "userPool.h"
176 #include "n8_driver_api.h"
179 /* Instance, indexed by minor number */
180 extern NspInstance_t NSPDeviceTable_g
[DEF_MAX_SIMON_INSTANCES
];
181 extern int driverMode
;
183 int n8_ioctlHandler( unsigned int cmd
,
184 NspInstance_t
*NSPinstance_p
,
185 unsigned long SessionID
,
186 unsigned char *debug
,
188 /*****************************************************************************
190 *****************************************************************************/
191 /** @ingroup NSP2000Driver
192 * @brief ioctl handler.
194 * This routine is the entry point for ioctl requests made to the driver. The
195 * handler is basically a large switch statement that branches on the specified
196 * IOCTL code. See nsp_ioctl.h for a list of all currently-supported ioctl
199 * Note that some branches use N8_FROM_USER and N8_TO_USER upon entry and
200 * exit, for access to the user data being passed between the user process and
201 * this ioctl handler. In these cases, a user-space pointer is being passed
202 * into the handler as the 4th parameter (arg). After typecasting it as a
203 * caddr_t, these two copy operations allow us to copy contents from a
204 * user-space pointer to a local kernel-space pointer, to actually use the
205 * data. Upon exiting, if data is to be returned to the calling user process,
206 * the data is copied back to the space pointed to by the user-space pointer.
208 * @param cmd RO: Standard parameter for an ioctl handler, containing the
209 * ioctl code specified in the user-space ioctl system call.
210 * @param NSPinstance_p RO: Pointer to the data structure for this instance.
211 * @param SessionID RO: The PID of the calling process.
212 * @param debug RO: The value of the debug flag.
213 * @param arg RW: Standard parameter for an ioctl handler, and is a
214 * user-defined entity. The NSP2000 driver interprets it as a
215 * pointer to a parameter structure, and typecasts it to a
216 * pointer before copying to or from it, allowing user
217 * processes to pass parameters on the ioctl call, and allowing
218 * the driver to return result data to the user process.
221 * N8_Debug_g RO: #define - If general debug messages are not <BR>
222 * enabled, this routine immediately exits, <BR>
223 * because it's a debug routine. <BR>
224 * NSPcount_g RO: Number of detected hardware instances. <BR>
225 * NSPDeviceTable_g RO: Array of information structures, one per <BR>
229 * -EINVAL General failure
233 * See return section for error information.
234 *****************************************************************************/
236 int n8_ioctlHandler( unsigned int cmd
,
237 NspInstance_t
*NSPinstance_p
,
238 unsigned long SessionID
,
239 unsigned char *debug
,
244 /* Branch on command code */
247 case NSP_IOCTL_DEBUG_MESSAGES
:
249 /* Apply debug message related bits */
251 n8_memoryDebug(arg
& N8_DBG_BIGALLOC
);
253 if (arg
& N8_DBG_DISPLAY_MEMORY
)
255 /* Display hardware memory resources */
256 n8_memoryDisplay(N8_MEMBANK_QUEUE
);
257 n8_memoryDisplay(N8_MEMBANK_EA
);
258 n8_memoryDisplay(N8_MEMBANK_PK
);
262 if (arg
& N8_DBG_DISPLAY_CONTEXT
)
264 /* Display hardware context resources */
267 if (arg
& N8_DBG_DISPLAY_REGISTERS
)
269 /* Display NSP2000 control register set in kernel log */
270 N8_DisplayRegisters();
272 if (arg
& N8_DBG_IRQ
)
274 /* Display NSP2000 IRQ Statistics in the kernel log */
277 if (arg
& N8_DBG_DISPLAY_QMGR
)
279 /* Display QMgr information in kernel log */
286 case NSP_IOCTL_GET_DEVICE_RESOURCES
:
288 NSPdriverInfo_t driverInfo
;
291 N8_FROM_USER(&driverInfo
, (void *)arg
, sizeof(NSPdriverInfo_t
));
292 mode
= driverInfo
.mode
;
294 /* Get the existing config */
295 N8_GetConfig(&driverInfo
);
297 if ((mode
!= N8_OPEN_UTIL
) && (mode
!= driverInfo
.mode
))
299 if (driverInfo
.mode
== N8_OPEN_UTIL
)
305 retval
= N8_INCOMPATIBLE_OPEN
;
309 /* Copy device info struct to user-space buffer */
310 N8_TO_USER((void *)arg
, &driverInfo
, sizeof(NSPdriverInfo_t
));
315 case NSP_IOCTL_ALLOCATE_BUFFER
:
317 /* Make call to n8_AllocateBuffer */
318 retval
= n8_pmalloc(N8_MEMBANK_EA
, arg
, SessionID
);
321 case NSP_IOCTL_ALLOCATE_BUFFER_PK
:
323 /* MAKE CALL TO n8_AllocateBuffer */
324 retval
= n8_pmalloc(N8_MEMBANK_PK
, arg
, SessionID
);
327 case NSP_IOCTL_FREE_BUFFER
:
328 n8_pfree(N8_MEMBANK_EA
, (void *)arg
);
331 case NSP_IOCTL_FREE_BUFFER_PK
:
332 n8_pfree(N8_MEMBANK_PK
, (void *)arg
);
335 case NSP_IOCTL_ALLOCATE_USER_POOL
:
337 NSPrequestPool_t requestPoolInfo
;
339 retval
= N8_MALLOC_FAILED
;
341 /* Allocate the user pool for the process */
342 requestPoolInfo
.requestPoolSize
= (DEF_USER_POOL_SIZE
* N8_ONE_MEGABYTE
);
343 requestPoolInfo
.requestPoolBase
= userPoolAlloc(SessionID
);
345 if (requestPoolInfo
.requestPoolBase
)
347 retval
= N8_STATUS_OK
;
350 /* Copy device info struct to user-space buffer */
351 N8_TO_USER((void *)arg
, &requestPoolInfo
, sizeof(NSPrequestPool_t
));
355 case NSP_IOCTL_WAIT_ON_INTERRUPT
: /* REAL-ONLY */
359 N8_FROM_USER(&parms
, (void *)arg
, sizeof(PARMSTRUCT_t
));
361 /* Block for notification of specified interrupts */
362 parms
.invalid_handle
= 0;
363 retval
= waitOnInterrupt( parms
.chip
,
370 /* Successful irq receipt */
374 else if (retval
== 0)
382 /* Invalid core type */
383 parms
.invalid_handle
= 1;
386 /* Return receipt or timeout to caller */
388 if (parms
.coretype
== N8_DAPI_PKE
)
390 parms
.irqstatus
= NSPinstance_p
->PKHirqstatus
;
392 else if (parms
.coretype
== N8_DAPI_RNG
)
394 parms
.irqstatus
= NSPinstance_p
->RNHirqstatus
;
396 else if (parms
.coretype
== N8_DAPI_EA
)
398 parms
.irqstatus
= NSPinstance_p
->CCHirqstatus
;
400 else if (parms
.coretype
== N8_DAPI_AMBA
)
402 parms
.irqstatus
= NSPinstance_p
->AMBAirqstatus
;
404 N8_TO_USER((void *)arg
, &parms
, sizeof(PARMSTRUCT_t
));
408 case NSP_IOCTL_N8_DAEMON_SYS_INIT
:
410 n8_DaemonMsg_t parms
;
412 /* This is where we do any system
413 * initialization that requires
414 * the N8 userspace daemon to
415 * be already running. This
416 * ioctl is triggered by a
417 * second userspace program.
420 /* currently, all we do here is
421 * initialize the SKS PROM allocation
422 * units using data on the file
426 N8_FROM_USER(&parms
, (void *)arg
, sizeof(n8_DaemonMsg_t
));
428 n8_SKSInitialize(&parms
);
433 case NSP_IOCTL_ALLOCATE_CONTEXT
:
437 N8_FROM_USER(&parms
, (void *)arg
, sizeof(PARMSTRUCT_t
));
439 /* Allocate a context entry */
441 n8_contextalloc(&parms
.chip
,
443 (unsigned int *)&parms
.contextIndex
);
444 N8_TO_USER((void *)arg
, &parms
, sizeof(PARMSTRUCT_t
));
448 case NSP_IOCTL_FREE_CONTEXT
:
452 N8_FROM_USER(&parms
, (void *)arg
, sizeof(PARMSTRUCT_t
));
454 /* Free the context entry */
455 retval
= n8_contextfree(parms
.chip
, SessionID
, parms
.contextIndex
);
459 case NSP_IOCTL_VALIDATE_CONTEXT
:
463 N8_FROM_USER(&parms
, (void *)arg
, sizeof(PARMSTRUCT_t
));
465 /* Free the context entry */
466 retval
= n8_contextvalidate(parms
.chip
, SessionID
, parms
.contextIndex
);
470 case NSP_IOCTL_QMGR_QUEUE
:
472 API_Request_t
*apiRequest_p
;
474 /* Convert physical address to kernel virtual address. */
475 apiRequest_p
= N8_PhysToVirt(arg
);
476 apiRequest_p
->userSpace
= N8_TRUE
;
477 retval
= N8_QMgrQueue(apiRequest_p
);
481 case NSP_IOCTL_RN_QUEUE
:
483 RN_Request_t rn_request
;
485 /* Copy request parameters to kernel space. */
486 N8_FROM_USER(&rn_request
, (void *)arg
, sizeof(RN_Request_t
));
487 rn_request
.userRequest
= N8_TRUE
;
488 retval
= Queue_RN_request(&rn_request
);
492 case NSP_IOCTL_RN_SET_PARMS
:
494 N8_RNG_Parameter_t
*parms_p
;
496 retval
= N8_MALLOC_FAILED
;
498 /* Allocate and copy the request to kernel space */
499 parms_p
= N8_UMALLOC(sizeof(N8_RNG_Parameter_t
));
502 N8_FROM_USER(parms_p
,
504 sizeof(N8_RNG_Parameter_t
));
506 /* Queue the request */
507 retval
= RN_SetParameters(parms_p
,N8_RNG_UNIT
);
513 case NSP_IOCTL_RN_GET_PARMS
:
515 N8_RNG_Parameter_t
*parms_p
;
517 retval
= N8_MALLOC_FAILED
;
519 /* Allocate and copy the request to kernel space */
520 parms_p
= N8_UMALLOC(sizeof(N8_RNG_Parameter_t
));
523 /* Queue the request */
524 retval
= RN_GetParameters(parms_p
,N8_RNG_UNIT
);
525 N8_TO_USER((void *)arg
,
527 sizeof(N8_RNG_Parameter_t
));
533 case NSP_IOCTL_SKS_WRITE
:
536 n8_SKSWriteParams_t params
;
538 /* Get the parameters from the user. */
539 N8_FROM_USER(¶ms
,
541 sizeof(n8_SKSWriteParams_t
));
543 /* At this point we know that we need to do a copy in */
544 /* of data_p data, so set fromUser to TRUE in the call */
545 /* to n8_SKSWrite. */
546 retval
= n8_SKSWrite(params
.targetSKS
,
554 case NSP_IOCTL_SKS_RESET_UNIT
:
556 /* No parameters are changed, and we are only passing */
557 /* a single parameter (targetSKS, which is equivalent */
558 /* to an int. This makes the call pretty trivial. */
559 const N8_Unit_t targetSKS
= (N8_Unit_t
) arg
;
560 retval
= n8_SKSResetUnit(targetSKS
);
564 case NSP_IOCTL_SKS_ALLOCATE
:
566 N8_SKSKeyHandle_t keyHandle
;
568 /* Copy in the key handle. */
569 N8_FROM_USER(&keyHandle
,
571 sizeof(N8_SKSKeyHandle_t
));
573 /* Do the SKS Allocate. */
574 retval
= n8_SKSAllocate(&keyHandle
);
576 /* Copy out any changes to the key handle. */
577 N8_TO_USER((void *)arg
,
579 sizeof(N8_SKSKeyHandle_t
));
583 case NSP_IOCTL_SKS_SET_STATUS
:
586 n8_setStatusParams_t params
;
587 N8_SKSKeyHandle_t keyHandle
;
589 /* Get the parameters from the user. */
590 N8_FROM_USER(¶ms
,
592 sizeof(n8_setStatusParams_t
));
593 N8_FROM_USER(&keyHandle
,
594 (void *)params
.keyHandle_p
,
595 sizeof(N8_SKSKeyHandle_t
));
597 retval
= n8_SKSsetStatus(&keyHandle
,
600 /* KeyHandle land status are not changed by the */
601 /* call to set status. Therefore no copy out is */
606 case NSP_IOCTL_QUERY_QUEUE_STATS
:
608 N8_QueueStatistics_t stats
;
610 N8_FROM_USER(&stats
, (void *)arg
, sizeof(N8_QueueStatistics_t
));
612 retval
= N8_QMgrQueryStatistics(&stats
);
614 N8_TO_USER((void *)arg
, &stats
, sizeof(N8_QueueStatistics_t
));
619 case NSP_IOCTL_MEMORY_STATS
:
621 MemStats_t memStats
[N8_MEMBANK_MAX
+DEF_USER_POOL_BANKS
];
623 retval
= N8_QueryMemStatistics(&memStats
[0]);
624 if (retval
== N8_STATUS_OK
)
626 userPoolStats(&memStats
[N8_MEMBANK_USERPOOL
]);
629 N8_TO_USER((void *)arg
, &memStats
,
630 sizeof(MemStats_t
) * (N8_MEMBANK_USERPOOL
+userPoolCount()));
635 case NSP_IOCTL_DIAGNOSTIC
:
637 NSPdiagInfo_t diagInfo
;
640 N8_FROM_USER(&diagInfo
, (void *)arg
, sizeof(NSPdiagInfo_t
));
641 chip
= diagInfo
.chip
;
643 /* Get the existing config */
644 diagInfo
.registerBase
= NSPDeviceTable_g
[chip
].NSPregs_base
;
645 diagInfo
.registerSize
= NSPDeviceTable_g
[chip
].PCIinfo
.base_range
[0];
646 diagInfo
.eaQueueBase
= NSPDeviceTable_g
[chip
].EAqueue_base
;
647 diagInfo
.eaQueueSize
= NSPDeviceTable_g
[chip
].EAqueue_size
;
648 diagInfo
.pkQueueBase
= NSPDeviceTable_g
[chip
].PKqueue_base
;
649 diagInfo
.pkQueueSize
= NSPDeviceTable_g
[chip
].PKqueue_size
;
650 diagInfo
.rnQueueBase
= NSPDeviceTable_g
[chip
].RNqueue_base
;
651 diagInfo
.rnQueueSize
= NSPDeviceTable_g
[chip
].RNqueue_size
;
653 /* Copy diag info struct to user-space buffer */
654 N8_TO_USER((void *)arg
, &diagInfo
, sizeof(NSPdiagInfo_t
));
658 case NSP_IOCTL_WAIT_ON_REQUEST
:
660 retval
= N8_WaitOnRequest(arg
);
663 default: retval
= -EINVAL
;
666 } /* n8_ioctlHandler */