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