| 
 |  | 
The following example is a listing of a kernel module that uses the EELS API. The module provides an ioctl interface so that messages can be sent directly from a test application to the kernel driver.
   /*
    * EELS test driver - provides an ioctl() interface to
    * enable the user to connect and submit log messages
    * as though originating from a normal kernel driver
    */
   
   #ifdef _KERNEL_HEADERS
   #include <util/types.h>
   #include <svc/errno.h>
   #include <io/conf.h>
   #include <util/debug.h>
   #include <io/eels/sys/eels_inf.h>
   #include <io/eels/eels_test/eels_drvr/eels_edt.h>
   #include <mem/kmem.h>
   #include <util/ksynch.h>
   #include <util/mod/moddefs.h>
   #include <io/ddi.h>
   #else
   #include <sys/types.h>
   #include <sys/errno.h>
   #include <sys/conf.h>
   #include <sys/debug.h>
   #include <sys/eels_inf.h>
   #include <sys/eels_edt.h>
   #include <sys/kmem.h>
   #include <sys/ksynch.h>
   #include <sys/moddefs.h>
   #include <sys/ddi.h>
   #endif
   
   int   edt_load(void);
   int   edt_unload(void);
   int   edtopen(dev_t *, int, int, cred_t *);
   int   edtclose(dev_t , int, int, cred_t *);
   int   edtioctl(dev_t , int, void *, int, cred_t *, int *);
   
   int   edtdevflag = D_MP;
   
   MOD_DRV_WRAPPER(edt, edt_load, edt_unload, NULL, "eels test driver");
   
   
   edt_load()
   {
      return 0;
   }
   
   edt_unload()
   {
      return 0;
   }
   
   
   /*
    * Open the edt device.
    */
   int
   edtopen(dev_t *devp, int oflags, int otyp, cred_t *crp)
   {
      return 0;
   }
   
   /*
    * Close the edt device.
    */
   int
   edtclose(dev_t dev, int oflags, int otyp, cred_t *crp)
   {
      return 0;
   }
   
   /*
    * The main guts of the driver. Stage user supplied requests
    * to the EELS driver and configure the stream as required.
    */
   int
   edtioctl(dev_t dev, int cmd, void *arg, int mode, cred_t *crp, int *rvalp)
   {
      eels_handle_t   handle = 0;
      edt_i_log_t     log, *logp;
      edt_i_connect_t con, *conp;
      size_t          size;
      int             retval;
   
      switch(cmd) {
      case I_EDT_LOG:
         /* Issue an eels_log() call using supplied parameters */
         if (copyin(arg, &log, sizeof(log))) {
            return EFAULT;
         }
         if (log.strlen == 0) {
            return EINVAL;
         }
         size = log.strlen + sizeof(log) - 1;
         logp = kmem_zalloc(size, KM_NOSLEEP);
         if (logp == NULL) {
            return EFAULT;
         }
         if (copyin(arg, logp, size)) {
            return EFAULT;
         }
         eels_log(logp->handle, logp->level, &logp->str);
         kmem_free(logp, size);
         break;
      case I_EDT_CONNECT:
         /* Issue an eels_initialise() call using supplied parameters */
         if (copyin(arg, &con, sizeof(con))) {
            return EFAULT;
         }
         if (con.desclen == 0) {
            return EINVAL;
         }
         size = con.desclen + sizeof(con) - 1;
         conp = kmem_zalloc(size, KM_NOSLEEP);
         if (conp == NULL) {
            return EFAULT;
         }
         if (copyin(arg, conp, size)) {
            kmem_free(conp, size);
            return EFAULT;
         }
         /* Now pass the description to the eels_initialise() call */
         retval = eels_initialise(&handle, &conp->desc);
         kmem_free(conp, size);
         if (retval) {
            return retval;
         } else {
            con.handle = handle;
            if (copyout(&con, arg, sizeof(con))) {
               return EFAULT;
            }
         }
         break;
      case I_EDT_TERMINATE:
         /* Issue an eels_terminate() call using supplied parameters */
         handle = (eels_handle_t )arg;
         return eels_terminate( handle );
      default:
         return EINVAL;
      }
      return 0;
   }