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

Reply via email to