On Tue, 2007-09-11 at 10:22 -0400, Daniel Corbe wrote:
> You guys are extremely patient with answering these questions, thank
> you. 
> 
> 
> I've run into another issue.
> 
> 
> Running add_drv causes my system to reboot.  I assume it's something
> I'm doing wrong.  I figured it had something to do with either the
> attach or getinfo procedures in my driver, and in fact the getinfo
> procedure is using an uninitialized pointer. 


I don't think getinfo() is the problem... its more likely to be
attach().  (getinfo() is normally only called as part of Dynamic
Reconfiguration operation, IIRC.)

        -- Garrett
> 
> 
> So what I did was I commented out the code in both procedures and now
> I'm simply returning DDI_SUCCESS.
> 
> 
> When the machine comes back up I usually need to do a svcadm
> clear /system/boot-archive and the machine boots normally again, with
> the driver "installed".
> 
> 
> I then go to modload the driver, and the machine reboots again
> 
> 
> Here's the source:
> 
> 
> 
> 
> #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);
> 
> cmn_err(CE_WARN, "Solaris called ATTACH" );
> 
> return (DDI_SUCCESS);
> 
> }
> 
> 
> int testdriver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
> 
> {
> 
> //ddi_remove_minor_node(dip, NULL);
> 
> cmn_err(CE_WARN, "Solaris called DETACH" );
> 
> 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_SUCCESS;
> 
> 
> /*
> 
> 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;
> 
> }
> 
> */
> 
> cmn_err(CE_WARN, "Solaris called GETINFO" );
> 
> 
> 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/10/07, Garrett D'Amore <[EMAIL PROTECTED]> wrote:
>         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