On Mon, 2007-09-10 at 17:02 -0400, Daniel Corbe wrote:
> 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
If it is a real driver, you have to use "add_drv" first to arrange to
allocate a major number for it.
>
>
> 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
Sure, but mod_install() is failing, because there is no major number
yet.
-- Garrett
>
>
> 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
_______________________________________________
driver-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/driver-discuss