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