Thanks for the thorough reply.  Now the module compiles cleanly and I get an
error loading:
# modload ./testdriver
can't load module: No such device or address

However at least as far as I can tell my _init is being called because when
I look at dmesg I see this:

Sep 10 17:00:19 sol10 testdriver: [ID 751645 kern.warning] WARNING: Solaris
has arrived

Here's the code:

# cat testdriver.c
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/errno.h>
#include <fcntl.h>
#include <inet/sctp_itf.h>
#include <sys/modctl.h>
#include <sys/cmn_err.h>
#include <sys/stream.h>
#include <sys/conf.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/devops.h>
#include <sys/stat.h>

/* Function prototypes */
int _init(void);
int _fini(void);
int _info(struct modinfo *modinfop);
int testdriver_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
int testdriver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
int testdriver_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
void **resultp);
int testdriver_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t
*credp);
int testdriver_close(queue_t *rq, int flag, cred_t *credp);
int testdriver_wput(queue_t *wq, mblk_t *mp);
int testdriver_wsrv(queue_t *wq);
int testdriver_tick(caddr_t arg);

/* Streams specific stuff */
static struct module_info testdriver_info =
{
        99,                     /* mi_idnum */
        "testdriver",           /* mi_idname */
        0,                      /* mi_minpsz */
        INFPSZ,                 /* mi_maxpsz */
        0,                      /* mi_hiwat */
        0                       /* mi_lowat */
};

static struct qinit testdriver_rinit = {
                NULL,                   /* qi_putp */
                NULL,                   /* qi_srvp */
                testdriver_open,        /* qi_qopen */
                testdriver_close,       /* qi_qclose */
                NULL,                   /* qi_qadmin */
                &testdriver_info,       /* qi_minfo */
                NULL                    /* qi_mstat */
};

static struct qinit testdriver_winit = {
                testdriver_wput,        /* qi_putp */
                testdriver_wsrv,        /* qi_srvp */
                NULL,                   /* qi_qopen */
                NULL,                   /* qi_qclose */
                NULL,                   /* qi_qadmin */
                &testdriver_info,       /* qi_minfo */
                NULL                    /* qi_mstat */
};

static struct streamtab testdriver_strtab =
{
                &testdriver_rinit,      /* st_rdinit */
                &testdriver_winit,      /* st_wrinit */
                NULL,                   /* st_muxrinit */
                NULL                    /* st_muxwrinit */
};

typedef struct devstate
{
        dev_info_t *devi;
} devstate_t;

/* Character device specific stuff */
static struct cb_ops cb_testdriver_ops =
{
                nodev,                          /* cb_open */
                nodev,                          /* cb_close */
                nodev,                          /* cb_strategy */
                nodev,                          /* cb_print */
                nodev,                          /* cb_dump */
                nodev,                          /* cb_read */
                nodev,                          /* cb_write */
                nodev,                          /* cb_ioctl */
                nodev,                          /* cb_devmap */
                nodev,                          /* cb_mmap */
                nodev,                          /* cb_segmap */
                nochpoll,                       /* cb_chpoll */
                ddi_prop_op,                    /* cb_prop_op */
                &testdriver_strtab,             /* cb_stream */
                (D_NEW | D_MP|D_MTPERMOD)       /* cb_flag */
};

static struct dev_ops testdriver_ops =
{
                DEVO_REV,                       /* devo_rev */
                0,                              /* devo_refcnt */
                testdriver_getinfo,             /* devo_getinfo */
                nodev,                          /* devo_identify */
                nodev,                          /* devo_probe */
                testdriver_attach,              /* devo_attach */
                testdriver_detach,              /* devo_detach */
                nodev,                          /* devo_reset */
                &cb_testdriver_ops,             /* devo_cb_ops */
                (struct bus_ops *)NULL          /* devo_bus_ops */
};

/* Module specific (kernel linkage for the kernel*/
static struct modldrv modldrv =
{
        &mod_driverops,
        "sctp_cd (SCTP Character Driver)",
        NULL
};

static struct modlinkage modlinkage =
{
        MODREV_1,
        &modldrv,
        NULL
};


/* Module load entry pointes */
int _init(void)
{
        cmn_err(CE_WARN, "Solaris has arrived");
        //if (sctp_itf_ver(1))
        //{
        //      cmn_err(CE_WARN, "Version supported\n");
        //}

        return (mod_install(&modlinkage));
}

int _fini(void)
{
        cmn_err(CE_WARN, "Solaris has left the building");
        return (mod_remove(&modlinkage));
}

int _info(struct modinfo *modinfop)
{
        return (mod_info(&modlinkage, modinfop));
}

/* Attach and detatch a device */
int testdriver_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
        /* This creates the device node. */
        if (ddi_create_minor_node(dip, "testdriver", S_IFCHR,
ddi_get_instance(dip), DDI_PSEUDO, CLONE_DEV) == DDI_FAILURE)
        {
                return (DDI_FAILURE);
        }

        ddi_report_dev(dip);
        return (DDI_SUCCESS);
}

int testdriver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
{
          ddi_remove_minor_node(dip, NULL);
          return (DDI_SUCCESS);
}

int testdriver_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
void **resultp)
{
        dev_t dev = (dev_t)arg;
        int instance, ret = DDI_FAILURE;

        devstate_t *sp;
        static void *statep;
        instance = getminor(dev);

        switch (infocmd)
        {
                case DDI_INFO_DEVT2DEVINFO:
                        if ((sp = ddi_get_soft_state(statep,
getminor((dev_t) arg))) != NULL)
                        {
                                *resultp = sp->devi;
                                ret = DDI_SUCCESS;
                        }
                        else
                        {
                                *resultp = NULL;
                        }
                        break;
                case DDI_INFO_DEVT2INSTANCE:
                        *resultp = (void *)instance;
                        ret = DDI_SUCCESS;
                        break;
                default:
                        break;
        }

        return (ret);
}

int testdriver_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t
*credp)
{
          return (0);
}

int testdriver_close(queue_t *rq, int flag, cred_t *credp)
{
          return (0);
}

int testdriver_wput(queue_t *wq, mblk_t *mp)
{
        return(0);
}

int testdriver_wsrv(queue_t *wq)
{
        return(0);
}

int testdriver_tick(caddr_t arg)
{
        //struct xxstr *xxp = (struct xxstr *)arg;
        //xxp->xx_timeoutid = 0;      /* timeout has run */
        return(0);
}

On 9/9/07, Artem Kachitchkine <[EMAIL PROTECTED]> wrote:
>
>
> > and two things missing are:
> >
> > - a call to ddi_soft_state_init() in _init()
> > - a call to ddi_soft_state_fini() in _fini()
>
> ddi_soft_state_zalloc(9F) in attach(9E) is also missing.
>
> -Artem
>
_______________________________________________
driver-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/driver-discuss

Reply via email to