ttuttle.net

The ttuttle.net blog

Categories

Fri, 24 Nov 2006

Dell Inspiron e1405 with BIOS A05 + Linux: Brightness hotkey fix

I have a Dell Inspiron e1405, and I just upgraded it to the latest BIOS version, A05. It went well (Dell has a Linux BIOS bootdisk tool that can create a physical floppy or a bootable kernel + ramdisk for GRUB that will update your BIOS!), but I found that when I loaded the video kernel module, which implements ACPI Video support, the brightness hotkeys stopped working.

I eventually tracked the problem down to the following pieces of code:

#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS      0x82
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x83
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS        0x84
#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS       0x85
#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF           0x86

and

static int
acpi_video_get_next_level(struct acpi_video_device *device,
                          u32 level_current, u32 event)
{
        /*Fix me */
        return level_current;
}

both in drivers/acpi/video.c. Basically, acpi_video_get_next_level is supposed to take the current brightness level and the ACPI video event number as parameters, and return the next brightness level that should be used, but nobody implemented it.

So I did. Here's the patch:

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 56666a9..2fc78ca 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2004 Luming Yu 
  *  Copyright (C) 2004 Bruno Ducrot 
+ *  Copyright (C) 2006 Thomas Tuttle 
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -47,11 +48,11 @@ #define ACPI_VIDEO_NOTIFY_CYCLE             0x82
 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT  0x83
 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT  0x84

-#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS     0x82
-#define        ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x83
-#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS       0x84
-#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS      0x85
-#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF          0x86
+#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS     0x85
+#define        ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x86
+#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS       0x87
+#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS      0x88
+#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF          0x89

 #define ACPI_VIDEO_HEAD_INVALID                (~0u - 1)
 #define ACPI_VIDEO_HEAD_END            (~0u)
@@ -1509,8 +1510,30 @@ static int
 acpi_video_get_next_level(struct acpi_video_device *device,
                          u32 level_current, u32 event)
 {
-       /*Fix me */
-       return level_current;
+       int min, max, min_above, max_below, i, l;
+       max = max_below = 0;
+       min = min_above = 255;
+       for (i = 0; i < device->brightness->count; i++) {
+               l = device->brightness->levels[i];
+               if (l < min) min = l;
+               if (l > max) max = l;
+               if (l < min_above && l > level_current) min_above = l;
+               if (l > max_below && l < level_current) max_below = l;
+       }
+
+       switch (event) {
+       case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
+               return (level_current < max) ? min_above : min;
+       case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
+               return (level_current < max) ? min_above : max;
+       case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
+               return (level_current > min) ? max_below : min;
+       case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
+       case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
+               return 0;
+       default:
+               return level_current;
+       }
 }

 static void

I've submitted it to all the mailing lists I can find, so it should be in the kernel eventually. It works on my laptop, but I imagine few others actually use ACPI video hotkey events if nobody's bothered to implement them fully yet.

posted on Nov 24, 2006 at 20:27 in /computers/software | permalink

Thu, 16 Nov 2006

Don't Trust S.M.A.R.T.!

A lot of people depend on S.M.A.R.T. (Self-Monitoring Analysis and Reporting Technology--probably a backronym) statistics to see when their hard drives are going to die.

Let this be a warning to those people!

My older laptop, phoenix, had a 60 GB drive with SMART. I ran smartd, and occasionally took a look at the statistics with smartctl, to make sure nothing was going wrong. I had a few reallocated sectors, but nothing to cause concern.

Then, suddenly, the drive started making a whining noise, and wouldn't read data unless I was rocking the laptop's case back and forth. I'm pretty sure the motor was stalling, since it eventually recovered. Then, a few months later, it stalled again, for another few days. Each time, I managed to back up all of my data with rsync. If I ran SMART tests, they would take forever, and then return with no errors. If I ran the Hitachi Drive Fitness Test that PC's for Everyone had me run when I called service, it returned the message "low performance", but didn't say the drive was broken.

Then, one last time, it finally stopped working. Rocking the case no longer worked; I had to smack it pretty hard to get it to finish the last backup it would ever run. Then, when I tried turning it on a few days later (to see if maybe the drive had recovered), I finally got the BIOS error: "SMART status: Drive failed. BACKUP and REPLACE!".

So let this be a lesson: back up your data now, and don't depend on SMART to warn you when the hard drive is going to fail.

posted on Nov 16, 2006 at 16:54 in /computers/hardware | permalink