All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <syrjala@sci.fi>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-fbdev-devel@lists.sourceforge.net
Subject: Re: [PATCH] atyfb: Fix HP OmniBook 500 reboot hang
Date: Wed, 27 May 2009 01:08:35 +0300	[thread overview]
Message-ID: <20090526220834.GO6520@sci.fi> (raw)
In-Reply-To: <20090526134918.096d49c4.akpm@linux-foundation.org>

On Tue, May 26, 2009 at 01:49:18PM -0700, Andrew Morton wrote:
> On Tue, 26 May 2009 02:05:14 +0300
> Ville Syrjala <syrjala@sci.fi> wrote:
> 
> > Apparently HP OmniBook 500's BIOS doesn't like the way atyfb reprograms
> > the hardware. The BIOS will simply hang after a reboot. Fix the problem
> > by restoring the hardware to it's original state on reboot.
> > 
> >
> > ...
> >
> > @@ -3502,6 +3503,11 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
> >  	par->mmap_map[1].prot_flag = _PAGE_E;
> >  #endif /* __sparc__ */
> >  
> > +	mutex_lock(&reboot_lock);
> > +	if (!reboot_info)
> > +		reboot_info = info;
> > +	mutex_unlock(&reboot_lock);
> 
> This looks risky to me.  We save away a pointer to a structure which
> was created by framebuffer_alloc().  What guarantee is there that this
> memory is still valid when the reboot happens later on?

atyfb_remove() will clear the pointer before freeing the memory. The
mutex is supposed to make sure that the structure won't be freed while 
the reboot notifier is executing.

Hmm. I suppose I might have to grab the fb_info lock there too to
protect against other fb activity happening at the same time.

I also noticed that I managed to misplace reboot_info pointer clearing
a bit. It should really be in atyfb_pci_remove() instead of
atyfb_remove() since it's set in atyfb_pci_probe().

> >  	return 0;
> >  
> >  err_release_io:
> > @@ -3613,9 +3619,14 @@ static void __devexit atyfb_remove(struct fb_info *info)
> >  {
> >  	struct atyfb_par *par = (struct atyfb_par *) info->par;
> >  
> > +	mutex_lock(&reboot_lock);
> > +	if (reboot_info == info)
> > +		reboot_info = NULL;
> > +	mutex_unlock(&reboot_lock);
> > +
> >  	/* restore video mode */
> > -	aty_set_crtc(par, &saved_crtc);
> > -	par->pll_ops->set_pll(info, &saved_pll);
> > +	aty_set_crtc(par, &par->saved_crtc);
> > +	par->pll_ops->set_pll(info, &par->saved_pll);
> >  
> >  	unregister_framebuffer(info);
> >  
> > @@ -3808,6 +3819,39 @@ static int __init atyfb_setup(char *options)
> >  }
> >  #endif  /*  MODULE  */
> >  
> > +static int atyfb_reboot_notify(struct notifier_block *nb,
> > +			       unsigned long code, void *unused)
> > +{
> > +	struct atyfb_par *par;
> > +
> > +	if (code != SYS_RESTART)
> > +		return NOTIFY_DONE;
> > +
> > +	mutex_lock(&reboot_lock);
> > +
> > +	if (!reboot_info)
> > +		goto out;
> > +
> > +	par = reboot_info->par;
> > +
> > +	/*
> > +	 * HP OmniBook 500's BIOS doesn't like the state of the
> > +	 * hardware after atyfb has been used. Restore the hardware
> > +	 * to the original state to allow succesful reboots.
> 
> "successful" ;)

Right.

> > +	 */
> > +	aty_set_crtc(par, &par->saved_crtc);
> > +	par->pll_ops->set_pll(reboot_info, &par->saved_pll);
> > +
> > + out:
> > +	mutex_unlock(&reboot_lock);
> > +
> > +	return NOTIFY_DONE;
> > +}
> > +
> > +static struct notifier_block atyfb_reboot_notifier = {
> > +	.notifier_call = atyfb_reboot_notify,
> > +};
> > +
> >  static int __init atyfb_init(void)
> >  {
> >      int err1 = 1, err2 = 1;
> > @@ -3826,11 +3870,18 @@ static int __init atyfb_init(void)
> >      err2 = atyfb_atari_probe();
> >  #endif
> >  
> > -    return (err1 && err2) ? -ENODEV : 0;
> > +    if (err1 && err2)
> > +	return -ENODEV;
> > +
> > +    register_reboot_notifier(&atyfb_reboot_notifier);
> > +
> > +    return 0;
> >  }
> 
> ick.  Please feel free to repair the indenting in atyfb_init().

The indentation is broken in other parts of the driver too. I'll make
a separate cosmetics patch to clean it all up.

> >  static void __exit atyfb_exit(void)
> >  {
> > +	unregister_reboot_notifier(&atyfb_reboot_notifier);
> > +
> >  #ifdef CONFIG_PCI
> >  	pci_unregister_driver(&atyfb_driver);
> >  #endif
> 
> So we do the restoration for all supported devices on all machines,
> even though it's only known to be needed on one card on one machine.
> 
> Hopefully that's safe, but a more cautious approach would use a
> whitelist of some form.  I don't have enough experience with these
> things to be able to judge the risk.

It should be safe in theory :) If the restoration breaks on some system
then the probe error handling and remove handling are also broken since
they do the same stuff. But to be honest I didn't test it on other
systems. I could do a DMI match but I'm not sure the extra complexity
is actually warranted. I'll give it a spin on a few other systems in
any case.

-- 
Ville Syrjälä
syrjala@sci.fi
http://www.sci.fi/~syrjala/

------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT 
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp as they present alongside digital heavyweights like Barbarian 
Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com 

      reply	other threads:[~2009-05-26 22:08 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-25 23:05 [PATCH] atyfb: Fix HP OmniBook 500 reboot hang Ville Syrjala
2009-05-26 20:49 ` Andrew Morton
2009-05-26 22:08   ` Ville Syrjälä [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090526220834.GO6520@sci.fi \
    --to=syrjala@sci.fi \
    --cc=akpm@linux-foundation.org \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.