Copying data from Kernel memory space to User memory space

Use ddi_copyout(9F), which enables us to copy some data in the kernel memory space to our application program. For example, when we want to obtain the configuration data within the device driver, ddi_copyout(9F) is useful. The sample program is shown below. This is the extention of the skelton driver for Character Driver Skelton Program (skelton.c). 1) The user application program opens the device and call ioctl(2).
 #include 
 #include 
 #include 

 #include "skelton.h"

 main() {
  int fd;
  struct my_skelton_info skelton_info_copy;

  fd = open ("/devices/pseudo/skelton@0:0", O_RDONLY);
  if (fd == -1) {
   perror ("open");
   exit (errno);
  }

  if (ioctl(fd,SKELTON_DUMMY,NULL) == -1) {
   perror("ioctl");
   exit(errno);
  }

  if (ioctl(fd,SKELTON_GETINFO,&skelton_info_copy) == -1) {
   perror("ioctl");
   exit(errno);
  }

  printf("my_skelton_info venid = %d\n",skelton_info_copy.venid);
  printf("my_skelton_info devid = %d\n",skelton_info_copy.devid);
  printf("my_skelton_info revid = %d\n",skelton_info_copy.revid);
 }

2) The following sample driver will respond to the application.
o header file (skelton.h)

#ifndef SKELTON_H
#define SKELTON_H

#define SKELTON_DUMMY           _IO('m',1)
#define SKELTON_GETINFO         _IO('m',2)

struct my_skelton_info {
 int     venid;   /* Let's suppose this is the vendor id. */
 int     devid;   /* Let's suppose this is the device id. */
 short   revid;   /* Let's suppose this is the revision id. */
};

#endif SKELTON_H

o extended skelton driver (skelton.c)
        :
        :
#include "skelton.h"
        :
        :
struct skel_state {
 int instance;                   /* instance number */
 dev_info_t *dip;                /* dev_info structure */
 struct my_skelton_info info;    /* additional info */
};
        :
        :
static int
skel_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
 int instance;
 struct skel_state *bs;
 int     flags;

 switch(cmd) {
 case DDI_ATTACH:
         :
         :
  bs = ddi_get_soft_state(statep, instance);
         :
         :
  /* SET VALUE IN THE KERNEL SPACE */
  bs->info.venid = 1234; /* Let's suppose this is the vendor id value. */
  bs->info.devid = 5678; /* Let's suppose this is the device id value. */
  bs->info.revid = 99;   /* Let's suppose this is the revision id value. */

  return DDI_SUCCESS;
 default:
  return DDI_FAILURE;
 }
        :
        :
}

static int
skel_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp)
{
 int instance;
 struct skel_state *rs;

 instance = getminor(dev);
 rs = ddi_get_soft_state(statep, instance);
 if(rs == NULL) {
  return ENXIO;
 };

 switch (cmd) {
 case SKELTON_GETINFO:
  /* COPY DATA FROM KERNEL SPACE TO USER SPACE */
  if(ddi_copyout((void *)&rs->info, (void *)arg, sizeof(struct my_skelton_info), mode) != 0) {
   return EFAULT;
  }
  return 0;

 case SKELTON_DUMMY:
  cmn_err(CE_NOTE, "_ioctl called (SKELTON_TEST)\n");
  return 0;

 default:
  return ENOTTY;
 }
}


3) The result will be as follows.
    # ./skelApp
    my_skelton_info venid = 1234
    my_skelton_info devid = 5678
    my_skelton_info revid = 99
Source: http://developers.sun.com/solaris/developer/support/driver/faqs.html

Stumble
Delicious
Technorati
Twitter
Facebook

Bookmark and Share

0 comments

Post a Comment