Hello,

I am facing with a weired problem. The user level ioctl on my device file does 
not reach the ioctl handler in my module at all. I have a simple character 
device driver called dummy (just pulled from a device driver manual 'hello 
world' example).

[root@/]modinfo | grep dummy
227 fa2f9a20    634 220   1  dummy (dummy driver)
[root@/]ls -l /devices/pseudo/dum...@0\:0 
c-wxrw--wx   1 root     sys      220,  0 Dec  3 15:13 /devices/pseudo/dummy at 
0:0

The open on the device file works well. But when I call ioctl, the message in 
the ioctl handler does not print. Niether does the ioctl call appear in the 
DTrace probes. perror from user program returns :

: Invalid argument

My DTrace output is attached as dtrace-output
and dtrace script is attached as dtrace-script (it tarces all kernel probes)

Let me know of any probable cause of ioctls not getting executed.

Thanks in advance
->Shreyas

My driver code is as follows :
   /*
    * Minimalist pseudo-device.
    * Writes a message whenever a routine is entered.
    *
    * Build the driver:
    *         cc -D_KERNEL -c dummy.c
    *         ld -r -o dummy dummy.o
    * Copy the driver and the configuration file to /usr/kernel/drv:
    *         cp dummy.conf /usr/kernel/drv
    *         cp dummy /tmp
    *         ln -s /tmp/dummy /usr/kernel/drv/dummy
    * Add the driver:
    *         add_drv dummy
    * Test (1) read from driver (2) write to driver:
    *         cat /devices/pseudo/du...@*
              echo hello > ?ls /devices/pseudo/du...@*?
    *
    * Verify the tests in another window:
    *         tail -f /var/adm/messages
    * Remove the driver:
    *         rem_drv dummy
    */
#define SOLARIS
#include <sys/devops.h> /* used by dev_ops */
#include <sys/conf.h>               /* used by dev_ops and cb_ops */
#include <sys/modctl.h> /* used by modlinkage, modldrv, _init, _info, */
                                       /* and _fini */
#include <sys/types.h> /* used by open, close, read, write, prop_op, */
                                       /* and ddi_prop_op */
#include <sys/file.h>               /* used by open, close */
#include <sys/errno.h> /* used by open, close, read, write */
#include    <sys/open.h>         /* used by open, close, read, write */
#include    <sys/cred.h>         /* used by open, close, read */
#include    <sys/uio.h>          /* used by read */
#include    <sys/stat.h>         /* defines S_IFCHR used by 
ddi_create_minor_node */
#include    <sys/cmn_err.h>      /* used by all entry points for this driver */
#include    <sys/ddi.h>          /* used by all entry points for this driver */
                                 /* also used by cb_ops, ddi_get_instance, and 
*/
                                 /* ddi_prop_op */
#include <sys/sunddi.h> /*          used by all entry points for this driver */
                                 /* also used by cb_ops, ddi_create_minor_node, 
*/
                                 /* ddi_get_instance, and ddi_prop_op */
#include "vmci_defs.h"
#include "vmciDatagram.h"

char _depends_on[]="vmci";

static int dummy_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
static int dummy_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
static int dummy_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
     void **resultp);
static int dummy_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
     int flags, char *name, caddr_t valuep, int *lengthp);
static int dummy_open(dev_t *devp, int flag, int otyp, cred_t *cred);
static int dummy_close(dev_t dev, int flag, int otyp, cred_t *cred);
static int dummy_read(dev_t dev, struct uio *uiop, cred_t *credp);
static int dummy_write(dev_t dev, struct uio *uiop, cred_t *credp);
static int dummy_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
                      cred_t *credp, int *rval);
static int dummy_poll(dev_t dev, short events, int anyyet,
                      short *reventsp, struct pollhead **phpp);

/* cb_ops structure */
static struct cb_ops dummy_cb_ops = {
     dummy_open,
     dummy_close,
     nodev,                     /* no strategy - nodev returns ENXIO */
     nodev,                     /* no print */
     nodev,                     /* no dump */
     dummy_read,
     dummy_write,
     dummy_ioctl,
     nodev,                     /* no devmap */
     nodev,                     /* no mmap */
     nodev,                     /* no segmap */
     dummy_poll,                /* returns ENXIO for non-pollable devices */
     dummy_prop_op,
     NULL,                      /* streamtab struct; if not NULL, all above */
                                /* fields are ignored */
     D_NEW | D_MP,              /* compatibility flags: see conf.h */
     CB_REV,                    /* cb_ops revision number */
     nodev,                     /* no aread */
     nodev                      /* no awrite */
};
/* dev_ops structure */
static struct dev_ops dummy_dev_ops = {
     DEVO_REV,
     0,                            /* reference count */
     ddi_no_info,
     //dummy_getinfo,
     nulldev,                      /* no identify - nulldev returns 0 */
     nulldev,                      /* no probe */
     dummy_attach,
     dummy_detach,
     nodev,                        /* no reset - nodev returns ENXIO */
     &dummy_cb_ops,
     (struct bus_ops *)NULL,
     NULL                         /* no power */
};
/* modldrv structure */
static struct modldrv md = {
     &mod_driverops,               /* Type of module. This is a driver. */
     "dummy driver",              /* Name of the module. */
     &dummy_dev_ops
};

/* modlinkage structure */
static struct modlinkage ml = {
     MODREV_1,
     &md,
     NULL
};

/* dev_info structure */
dev_info_t *dummy_dip; /* keep track of one instance */

/* Loadable module configuration entry points */
int
_init(void)
{
     cmn_err(CE_NOTE, "Inside _init");
     return(mod_install(&ml));
}
int
_info(struct modinfo *modinfop)
{
     cmn_err(CE_NOTE, "Inside _info");
     return(mod_info(&ml, modinfop));
}
int
_fini(void)
{
     cmn_err(CE_NOTE, "Inside _fini");
     return(mod_remove(&ml));
}
/* Device configuration entry points */
static int
dummy_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
     cmn_err(CE_NOTE, "Inside dummy_attach");
     switch(cmd) {
     case DDI_ATTACH:
           dummy_dip = dip;
           if (ddi_create_minor_node(dip, "0", S_IFCHR,
               ddi_get_instance(dip), DDI_PSEUDO,0)
               != DDI_SUCCESS) {
               cmn_err(CE_NOTE,
                     "%s%d: attach: could not add character node.",
                     "dummy", 0);
               return(DDI_FAILURE);
           } else
               return DDI_SUCCESS;
     default:
           return DDI_FAILURE;
     }
}
static int
dummy_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
{
     cmn_err(CE_NOTE, "Inside dummy_detach");
     switch(cmd) {
     case DDI_DETACH:
           dummy_dip = 0;
           ddi_remove_minor_node(dip, NULL);
           return DDI_SUCCESS;
     default:
           return DDI_FAILURE;
     }
}
static int
dummy_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
     void **resultp)
{
     cmn_err(CE_NOTE, "Inside dummy_getinfo");
     switch(cmd) {
     case DDI_INFO_DEVT2DEVINFO:
                                 *resultp = dummy_dip;
                                 return DDI_SUCCESS;
                             case DDI_INFO_DEVT2INSTANCE:
                                 *resultp = 0;
                                 return DDI_SUCCESS;
                             default:
                                 return DDI_FAILURE;
                             }
                        }
/* Main entry points */
static int
dummy_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
  int flags, char *name, caddr_t valuep, int *lengthp)
{
  cmn_err(CE_NOTE, "Inside dummy_prop_op");
//  return DDI_SUCCESS;
  return(ddi_prop_op(dev,dip,prop_op,flags,name,valuep,lengthp));
}

static int
dummy_open(dev_t *devp, int flag, int otyp, cred_t *cred)
{
   int status;

   cmn_err(CE_NOTE, "Inside dummy_open");

    return DDI_SUCCESS;
}
static int
dummy_close(dev_t dev, int flag, int otyp, cred_t *cred)
{
    cmn_err(CE_NOTE, "Inside dummy_close");
    return DDI_SUCCESS;
}

static int
dummy_read(dev_t dev, struct uio *uiop, cred_t *credp)
{
     cmn_err(CE_NOTE, "Inside dummy_read");
     return DDI_SUCCESS;

}
static int
dummy_write(dev_t dev, struct uio *uiop, cred_t *credp)
{
     cmn_err(CE_NOTE, "Inside dummy_write");
     return DDI_SUCCESS;
}

static int
dummy_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
                      cred_t *credp, int *rval)
{
        cmn_err(CE_WARN, "%s(%d) Received function : %d\n", __FUNCTION__, 
__LINE__, cmd);
        return(0);
}


static int
dummy_poll(dev_t dev,                // IN: Device number.
           short events,             // IN: Requested events.
           int anyyet,               // IN: Whether other fds have had events.
           short *reventsp,          // OUT: Mask of satisfied events.  
           struct pollhead **phpp) { // OUT: Set to a pollhead if necessary.
        cmn_err(CE_WARN, "%s(%d) \n", __FUNCTION__, __LINE__);
   
   return 0;
}
-- 
This message posted from opensolaris.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dtrace-script
Type: application/octet-stream
Size: 549 bytes
Desc: not available
URL: 
<http://mail.opensolaris.org/pipermail/opensolaris-help/attachments/20081203/81eef8cc/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dtrace-output
Type: application/octet-stream
Size: 712042 bytes
Desc: not available
URL: 
<http://mail.opensolaris.org/pipermail/opensolaris-help/attachments/20081203/81eef8cc/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dtrace-output-part2
Type: application/octet-stream
Size: 719151 bytes
Desc: not available
URL: 
<http://mail.opensolaris.org/pipermail/opensolaris-help/attachments/20081203/81eef8cc/attachment-0002.obj>

Reply via email to