[PATCH] leds: separate read/write ide-disk triggers

From: Michal Bozon
Date: Mon May 17 2010 - 19:10:10 EST


here is a humble extension of leds module, adding separate
"ide-disk-read" and "ide-disk-write" triggers to existing "ide-disk"
one.

tested on pc engines ALIX.3c3 board, kernel 2.6.32, patches smoothly
current 2.6.34 as well

following scenario configures the three leds on ALIX board as
heartbeat, ide-read and ide-write indicators, respectively:

modprobe leds-alix2 force=1
modprobe ledtrig-heartbeat # not relevant to this patch
echo heartbeat > /sys/class/leds/"alix:1"/
trigger # not relevant to this patch
echo ide-disk-read > /sys/class/leds/"alix:2"/trigger
echo ide-disk-write > /sys/class/leds/"alix:3"/trigger
--- linux-source-2.6.32/drivers/ide/ide-disk.c_orig_ 2010-05-17 22:11:07.000000000 +0200
+++ linux-source-2.6.32/drivers/ide/ide-disk.c 2010-05-17 22:33:41.000000000 +0200
@@ -188,6 +188,12 @@ static ide_startstop_t ide_do_rw_disk(id

ledtrig_ide_activity();

+ if (rq_data_dir(rq) == READ) {
+ ledtrig_ide_read_activity();
+ } else {
+ ledtrig_ide_write_activity();
+ }
+
pr_debug("%s: %sing: block=%llu, sectors=%u, buffer=0x%08lx\n",
drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
(unsigned long long)block, blk_rq_sectors(rq),
--- linux-source-2.6.32/include/linux/leds.h_orig_ 2010-05-17 22:29:02.000000000 +0200
+++ linux-source-2.6.32/include/linux/leds.h 2010-05-17 22:30:05.000000000 +0200
@@ -121,8 +121,12 @@ extern void led_trigger_event(struct led
/* Trigger specific functions */
#ifdef CONFIG_LEDS_TRIGGER_IDE_DISK
extern void ledtrig_ide_activity(void);
+extern void ledtrig_ide_read_activity(void);
+extern void ledtrig_ide_write_activity(void);
#else
#define ledtrig_ide_activity() do {} while(0)
+#define ledtrig_ide_read_activity() do {} while(0)
+#define ledtrig_ide_write_activity() do {} while(0)
#endif

/*
--- linux-source-2.6.32/drivers/leds/ledtrig-ide-disk.c_orig_ 2010-05-17 22:15:52.000000000 +0200
+++ linux-source-2.6.32/drivers/leds/ledtrig-ide-disk.c 2010-05-17 22:35:27.000000000 +0200
@@ -19,11 +19,21 @@
#include <linux/leds.h>

static void ledtrig_ide_timerfunc(unsigned long data);
+static void ledtrig_ide_read_timerfunc(unsigned long data);
+static void ledtrig_ide_write_timerfunc(unsigned long data);

DEFINE_LED_TRIGGER(ledtrig_ide);
+DEFINE_LED_TRIGGER(ledtrig_ide_read);
+DEFINE_LED_TRIGGER(ledtrig_ide_write);
static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0);
+static DEFINE_TIMER(ledtrig_ide_read_timer, ledtrig_ide_read_timerfunc, 0, 0);
+static DEFINE_TIMER(ledtrig_ide_write_timer, ledtrig_ide_write_timerfunc, 0, 0);
static int ide_activity;
static int ide_lastactivity;
+static int ide_read_activity;
+static int ide_read_lastactivity;
+static int ide_write_activity;
+static int ide_write_lastactivity;

void ledtrig_ide_activity(void)
{
@@ -33,6 +43,22 @@ void ledtrig_ide_activity(void)
}
EXPORT_SYMBOL(ledtrig_ide_activity);

+void ledtrig_ide_read_activity(void)
+{
+ ide_read_activity++;
+ if (!timer_pending(&ledtrig_ide_read_timer))
+ mod_timer(&ledtrig_ide_read_timer, jiffies + msecs_to_jiffies(10));
+}
+EXPORT_SYMBOL(ledtrig_ide_read_activity);
+
+void ledtrig_ide_write_activity(void)
+{
+ ide_write_activity++;
+ if (!timer_pending(&ledtrig_ide_write_timer))
+ mod_timer(&ledtrig_ide_write_timer, jiffies + msecs_to_jiffies(10));
+}
+EXPORT_SYMBOL(ledtrig_ide_write_activity);
+
static void ledtrig_ide_timerfunc(unsigned long data)
{
if (ide_lastactivity != ide_activity) {
@@ -45,9 +71,35 @@ static void ledtrig_ide_timerfunc(unsign
}
}

+static void ledtrig_ide_read_timerfunc(unsigned long data)
+{
+ if (ide_read_lastactivity != ide_read_activity) {
+ ide_read_lastactivity = ide_read_activity;
+ /* INT_MAX will set each LED to its maximum brightness */
+ led_trigger_event(ledtrig_ide_read, INT_MAX);
+ mod_timer(&ledtrig_ide_read_timer, jiffies + msecs_to_jiffies(10));
+ } else {
+ led_trigger_event(ledtrig_ide_read, LED_OFF);
+ }
+}
+
+static void ledtrig_ide_write_timerfunc(unsigned long data)
+{
+ if (ide_write_lastactivity != ide_write_activity) {
+ ide_write_lastactivity = ide_write_activity;
+ /* INT_MAX will set each LED to its maximum brightness */
+ led_trigger_event(ledtrig_ide_write, INT_MAX);
+ mod_timer(&ledtrig_ide_write_timer, jiffies + msecs_to_jiffies(10));
+ } else {
+ led_trigger_event(ledtrig_ide_write, LED_OFF);
+ }
+}
+
static int __init ledtrig_ide_init(void)
{
led_trigger_register_simple("ide-disk", &ledtrig_ide);
+ led_trigger_register_simple("ide-disk-read", &ledtrig_ide_read);
+ led_trigger_register_simple("ide-disk-write", &ledtrig_ide_write);
return 0;
}