Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Aug 2019 09:10:28 -0600
From:      Ian Lepore <ian@freebsd.org>
To:        Yuri Pankov <yuripv@yuripv.net>, Hans Petter Selasky <hps@selasky.org>, freebsd-hackers@freebsd.org
Subject:   Re: ichsmb(4) and msleep()
Message-ID:  <197d072dc73ec3b0426f3c4d4db8c1fdd9b124c8.camel@freebsd.org>
In-Reply-To: <311a21e3-ed61-8679-b416-b2a4c255c6e7@yuripv.net>
References:  <7dfebbd3-85d6-c7b7-b83b-fae8b644649e@yuripv.net> <478965aa-5256-e356-5339-de6fb82c3459@selasky.org> <63daa36a-5c22-6b08-3cd7-562fa961ab61@yuripv.net> <7f6de96d-8b56-e242-8950-04a20b197bce@selasky.org> <311a21e3-ed61-8679-b416-b2a4c255c6e7@yuripv.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 2019-08-28 at 14:41 +0300, Yuri Pankov wrote:
> Hans Petter Selasky wrote:
> > On 2019-08-28 11:44, Yuri Pankov wrote:
> > > Hans Petter Selasky wrote:
> > > > On 2019-08-28 11:07, Yuri Pankov wrote:
> > > > > I have a "timed sleep before timers are working" panic in
> > > > > ichsmb_readb()
> > > > > calling ichsmb_wait() which uses msleep().  That is trying to
> > > > > jedec_dimm(4) module so it's trying to attach pretty early in
> > > > > boot.
> > > > > What would be the correct replacement for msleep() here?
> > > > > 
> > > > 
> > > > If you only need a sleep-delay, pause() is the right one. It
> > > > handles
> > > > cold-boot.
> > > 
> > > I guess that won't work here as we need to be waked up by
> > > interrupt
> > > handler on command completion, and pause() seems to sleep
> > > unconditionally for the given time in 'cold' case (if I'm reading
> > > the
> > > code correctly).
> > 
> > If you are too early inside a SYSINIT() path, then you cannot use 
> > sleeping. You will have to use polling in a loop with a fixed
> > DELAY() to 
> > know the timeout.
> 
> Thanks for the help.
> 
> Something like the following (it seems to work)?
> 

Do you actually need to communicate with these i2c slave devices as
part of making the system usable early in boot?  That sometimes happens
on embedded systems where you need to communicate with a power-
management system via i2c to bring up other devices.  In that case you
need to do polling until interrupts are available.

If not, then this is probably fallout from a historic freebsd glitch
where almost all i2c controller drivers attach the iicbus child before
interrupts are available, and then rely on all the slave device drivers
to not do any IO until interrupts are available.  IMO, that's insane...
a driver shouldn't attach children until it's in a state where it's
able to service the IO requests from them.

The simple fix is usually to change the last few lines of the
controller's attach() code.  Usually it's something like

  return bus_generic_attach(dev);

and you can just change it to

  config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
  return (0);

-- Ian




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?197d072dc73ec3b0426f3c4d4db8c1fdd9b124c8.camel>