<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Abort, Retry, Hack? &#187; Linux</title>
	<atom:link href="http://marcansoft.com/blog/category/linuxstuff/feed/" rel="self" type="application/rss+xml" />
	<link>http://marcansoft.com/blog</link>
	<description>[ marcan&#039;s blog ]</description>
	<lastBuildDate>Tue, 22 Dec 2009 16:26:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Making Firefox play nicely with Laptop Mode</title>
		<link>http://marcansoft.com/blog/2009/12/making-firefox-play-nicely-with-laptop-mode/</link>
		<comments>http://marcansoft.com/blog/2009/12/making-firefox-play-nicely-with-laptop-mode/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 04:58:08 +0000</pubDate>
		<dc:creator>marcan</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://marcansoft.com/blog/?p=202</guid>
		<description><![CDATA[Linux has a tweakable knob called laptop_mode which is meant as an energy saving tool for laptop users on battery: it basically says &#8220;try not to touch the disk for X minutes at a time, unless you really need to, and once you do, do everything that you&#8217;ve been piling up all at once&#8221;. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Linux has a tweakable knob called <a href="http://samwel.tk/laptop_mode/">laptop_mode</a> which is meant as an energy saving tool for laptop users on battery: it basically says &#8220;try not to touch the disk for X minutes at a time, unless you really need to, and once you do, do everything that you&#8217;ve been piling up all at once&#8221;. It&#8217;s great for laptop users, and doubly so for things like my <a href="http://marcansoft.com/transf/eee_vs_aspire.jpg">huge</a> laptop with two 7200RPM HDDs. Seriously.</p>
<p>Now, there are two things that mean you &#8220;really need to&#8221; hit the disc: reading data that isn&#8217;t already cached (duh), and the fsync() and fdatasync() calls. The latter are requests by an application to ensure that all of the data written to far has hit the disc, and they cause the disk to spin up in laptop mode.</p>
<p>Unfortunately, Firefox has a habit of randomly issuing fdatasync() calls. It does this as part of the SQLite backend for its various databases (especially places.sqlite), in order to avoid data corruption. Now, data corruption isn&#8217;t terribly likely on a laptop with a battery (which is essentially a built-in UPS), so this is a terrible annoyance with little benefit anyway. There has been <a href="https://bugs.launchpad.net/ubuntu/+source/firefox-3.0/+bug/221009">talk</a> about this problem, but apparently it&#8217;s still around (and the toolkit.storage.synchronous about:config property didn&#8217;t work for me). Most of the reports appear to claim that this happens while browsing, but I&#8217;ve seen it happen periodically even when Firefox is left idle. Maybe it&#8217;s caused by some extension or AJAX webapp? Who knows.</p>
<p><span id="more-202"></span><br />
Ideally this problem would be <a href="http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/">fixed in laptop_mode itself</a>, but that doesn&#8217;t appear to be the case and I&#8217;m not going to poke this part of my kernel just yet, so here&#8217;s a simpler userspace solution: we can preload a library into Firefox that intercepts fsync() and fdatasync() and ignores them. Even better, we can make it do that only if we&#8217;re in laptop_mode. All it takes is a little C code:</p>
<pre>#define _GNU_SOURCE
#include &lt;unistd.h&gt;
#include &lt;dlfcn.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;

static int in_laptop_mode(void)
{
	char buf[2];
	int fd;
	int l;
	fd = open("/proc/sys/vm/laptop_mode", O_RDONLY);
	if (fd &lt; 0)
		return 0;
	l = read(fd, buf, 2);
	close(fd);
	if (l == 2 &#038;&#038; buf[0] == '0' &#038;&#038; buf[1] == '\n')
		return 0;
	else
		return 1;
}

int fsync(int fd)
{
	static int (*_fsync)(int);
	if (!_fsync)
		_fsync = dlsym(RTLD_NEXT, "fsync");
	if (!in_laptop_mode())
		return _fsync(fd);
	else
		return 0;
}

int fdatasync(int fd)
{
	static int (*_fdatasync)(int);
	if (!_fdatasync)
		_fdatasync = dlsym(RTLD_NEXT, "fdatasync");
	if (!in_laptop_mode())
		return _fdatasync(fd);
	else
		return 0;
}
</pre>
<p>To compile and use it:</p>
<pre>$ gcc -O2 -Wall -shared -fPIC -o killsync.so killsync.c -ldl
$ LD_PRELOAD=`pwd`/killsync.so firefox</pre>
<p>Et voilà, firefox no longer wakes up the hard drive(s). You can confirm that the fsync/fdatasync calls no longer make it to the kernel by running <code>strace -f -p `pidof firefox`</code>, but only in laptop_mode.</p>
<p>I&#8217;ve been typing this blog post with this hack applied and so far HDD spinups have been few, far in between, and fairly short. I still have a few offenders to nail (mostly KDE related), but Firefox was one of the worst ones and it&#8217;s now history. <a href="www.lesswatts.org/projects/powertop">PowerTOP</a> says I&#8217;m saving 3-4W of power. Huzzah! Now I just need to get a kernel with timer stats built so I can fix my insane wakeups-from-idle per second&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://marcansoft.com/blog/2009/12/making-firefox-play-nicely-with-laptop-mode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Acer Aspire 8930G Linux audio support</title>
		<link>http://marcansoft.com/blog/2009/06/acer-aspire-8930g-linux-audio-support/</link>
		<comments>http://marcansoft.com/blog/2009/06/acer-aspire-8930g-linux-audio-support/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 05:30:28 +0000</pubDate>
		<dc:creator>marcan</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[acer]]></category>
		<category><![CDATA[alsa]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[reveng]]></category>

		<guid isPermaLink="false">http://marcansoft.com/blog/?p=40</guid>
		<description><![CDATA[I&#8217;ll eventually write a longer post about how different bits and pieces of this laptop&#8217;s hardware fare under Linux. For now, I&#8217;ve managed to strike one of the more annoying issues: proper audio. Scroll down if you&#8217;re impatient and want the code; read on if you want the full story. This laptop is peculiar because [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll eventually write a longer post about how different bits and pieces of this laptop&#8217;s hardware fare under Linux. For now, I&#8217;ve managed to strike one of the more annoying issues: proper audio. Scroll down if you&#8217;re impatient and want the code; read on if you want the full story.</p>
<p>This laptop is peculiar because it has built-in &#8220;5.1&#8243; audio. Yes, it does really have 6 speakers, though you&#8217;d be hard pressed to get much spatial separation out of them (and they aren&#8217;t even placed around symmetrically). However, the speakers do end up making a very decent multiway audio system, by laptop standards: the &#8220;rear&#8221; pair (which is actually between the keyboard and the screen; the mind boggles) is good with the high end, the &#8220;front&#8221; and center speakers (front edge of the laptop) are your average mediocre speakers that can handle mid-end, and the &#8220;Tuba&#8221; not-so-&#8221;sub&#8221; woofer fills in enough low-end to equal a decent overall speaker, although of course with zero stereo/spatial separation since there&#8217;s only one of it (actual subwoofers can pull off mono because the human ear can&#8217;t really hear spatial position at <b>low</b> frequencies, but the Tuba is more like the only non-sucky speaker in the entire laptop).</p>
<p>What this boils down to is that you <b>really</b> want good audio support for all 6 speakers if you want to take advantage of the audio capabilities at all. Most importantly, stereo needs to be upmixed and a good portion of the normal audio needs to be routed to the Tuba. ALSA&#8217;s asound.conf makes this easy, assuming the actual hardware works fine. Of course, that&#8217;s not the case.<br />
<span id="more-40"></span><br />
This thing uses (of course) Intel HDA audio with a Realtek ALC889 codec. This codec is fairly new and support is of course still a bit sketchy. There are two parts to getting things to work: the software needs to know how to talk to the ALC889 codec, and it also needs to know how to configure it to work with the laptop&#8217;s hardware design (i.e. how the chip&#8217;s outputs connect to the actual speakers and jacks, which varies). After reading up on HDA audio codec specs and looking for examples, the latter part wasn&#8217;t very hard. There&#8217;s even a tool called <a href="http://git.alsa-project.org/?p=alsa.git;a=tree;f=hda-analyzer">hda-analyzer</a> which lets you tweak most HDA configuration on the fly with a nifty GUI. I also rendered a <a href="http://marcansoft.com/transf/codec.png">graph</a> (warning: large image) of the codec&#8217;s internal audio routing.</p>
<p>Unfortunately, after verifying that I had mapped all of the connections properly and could get individual output through any one of the speakers and audio jacks, I hit a showstopper. The codec has 5 stereo DACs (10 channels total, nominally 7.1 plus an extra stereo connection) but only the first two DACs worked, which gave me 4.0 audio. They rest just appeared to be completely dead. I knew the problem was with the DACs because I could remap the audio outputs to use one of the first two DACs and that worked, and I could tell the first two DACs to play other channels from the input stream and that worked fine too. Audio was getting to the chip, and audio could get out from the chip, but somewhere during the digital-to-analog conversion for DACs 3-5 it was just disappearing. I searched the Realtek datasheet and ALC specs for info on how to turn DACs off or on but found no such thing. Of course, a standard wouldn&#8217;t be complete without a mechanism for vendor-specified proprietary extensions (and those standards that don&#8217;t have them are abused anyway). HDA has these things called coefficient registers, which is just a dumb name for vendor proprietary registers. ALSA already has some code to tweak these on other Realtek codecs, though nothing related to turning DACs on or off. At this point this was clearly Realtek&#8217;s fault for not documenting how to turn on DACs that are <b>turned off by default</b>. So I e-mailed them describing the issue in clear terms, and, in response, got treated like a clueless end-user. They kept sending me patched/modified versions of the realtek support for ALSA with useless changes like support for new laptops and the like and no actual changes to fix the DAC issue. Of course, none of it was helpful, and I gave up on playing along after a couple weeks of wasted time.</p>
<p>Eventually this annoyed me enough that I just desperately tried flipping every bit in every coefficient register. After about 45 minutes of mind-numbing tones (I made a little multichannel test tone using a pentatonic scale which looped a couple thousand times until I was done) I didn&#8217;t find the magic bit to turn on the DACs, but I found <b>two</b> registers able to kill the already-working DACs, guessed a bit, and found out that you need to clear <b>both</b> of them to enable the broken DACs. Success.</p>
<p>Long story short, this, along with proper support for the laptop&#8217;s hardware and such, should be in the next version of ALSA. If you&#8217;re impatient, grab <a href="http://git.alsa-project.org/?p=alsa-kernel.git;a=commitdiff_plain;h=7082fef37ca21ba0b52a7ae2cae9aa3b5bcc888c;hp=bf939f4cb618f9b10b673f22005196b89c6cc108">this patch</a> and apply it. The one thing that&#8217;s missing is internal mic support (it&#8217;s in there but I don&#8217;t think it works) &#8211; I tried a few things and came up dry, but I don&#8217;t really plan on using it anyway. You&#8217;ll also want an asound.conf to do the upmixing: <a href="http://marcansoft.com/transf/asound.conf">this</a> is what I use. Just place it in /etc (back up / merge your distro&#8217;s version, if any, before you overwrite it!).</p>
<p>Lastly, if you have another Acer laptop with similar audio capabilities, the code will probably work for you but it won&#8217;t autodetect the laptop. You&#8217;ll want to use the option &#8220;model=acer-aspire-8930g&#8221; when loading the snd-hda-intel module to force it. For example, it&#8217;s very likely that it will work with the 8920G. If it works, send the output of &#8220;lspci -v&#8221; or &#8220;sudo lspci -v&#8221; to <a href="mailto:hector@marcansoft.com">me</a> or an ALSA developer so it can be added to the list.</p>
<p><b>Update</b>: I submitted another patch to fix input issues. This gives you the full 3 capture devices, one of which can capture the internal front microphone (the others can&#8217;t; that&#8217;s a chip limitation). The microphone is stereo but due to the weird sum/difference format I&#8217;ve hacked it to just output mono to the device. The stereo is useless anyway, since the mics are too close together. Grab the patch <a href="http://git.alsa-project.org/?p=alsa-kernel.git;a=commitdiff_plain;h=6f387d0412952ba0a3ae0578b7a98ff622c39215">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://marcansoft.com/blog/2009/06/acer-aspire-8930g-linux-audio-support/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
