diff --git a/docs/files/led/libata_leds_trigger_mvebu.patch b/docs/files/led/libata_leds_trigger_mvebu.patch new file mode 100644 index 0000000..bed08d8 --- /dev/null +++ b/docs/files/led/libata_leds_trigger_mvebu.patch @@ -0,0 +1,222 @@ +From 7c0053bae4a4e7dbab69402c47eb84e33143a176 Mon Sep 17 00:00:00 2001 +Message-Id: <7c0053bae4a4e7dbab69402c47eb84e33143a176.1544101943.git.aditya@kobol.io> +From: Daniel Golle +Date: Sat, 13 Dec 2014 01:07:20 +0100 +Subject: [PATCH] libata: add ledtrig support + +This adds a LED trigger for each ATA port indicating disk activity. + +As this is needed only on specific platforms (NAS SoCs and such), +these platforms should define ARCH_WANTS_LIBATA_LEDS if there +are boards with LED(s) intended to indicate ATA disk activity and +need the OS to take care of that. +In that way, if not selected, LED trigger support not will be +included in libata-core and both, codepaths and structures remain +untouched. + +I'm currently deploying this for the oxnas target in OpenWrt +https://dev.openwrt.org/changeset/43675/ + +v2: rebased to kernel/git/tj/libata.git + plus small corrections and comments added + +Signed-off-by: Daniel Golle +URL: https://patchwork.ozlabs.org/patch/420733/ +[Aditya Prayoga: +* Port forward +* Change ATA_LEDS default to no +* Reduce performance impact by moving ata_led_act() call from + ata_qc_new() to ata_qc_complete()] +Signed-off-by: Aditya Prayoga + +ARM: mvebu: Enable ARCH_WANT_LIBATA_LEDS in Armada 38x + +Enable hidden symbol ARCH_WANT_LIBATA_LEDS so CONFIG_ATA_LEDS can be +used in kernel configuration. + +URL: https://lists.openwrt.org/pipermail/openwrt- +devel/2017-March/006582.html + +Signed-off-by: Aditya Prayoga +--- + arch/arm/configs/mvebu_v7_defconfig | 1 + + arch/arm/mach-mvebu/Kconfig | 1 + + drivers/ata/Kconfig | 16 +++++++++++ + drivers/ata/libata-core.c | 56 +++++++++++++++++++++++++++++++++++++ + include/linux/libata.h | 7 +++++ + 5 files changed, 81 insertions(+) + +diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig +index 5514021..3d39ab2 100644 +--- a/arch/arm/configs/mvebu_v7_defconfig ++++ b/arch/arm/configs/mvebu_v7_defconfig +@@ -59,6 +59,7 @@ CONFIG_MTD_UBI=y + CONFIG_EEPROM_AT24=y + CONFIG_BLK_DEV_SD=y + CONFIG_ATA=y ++CONFIG_ATA_LEDS=y + CONFIG_SATA_AHCI=y + CONFIG_AHCI_MVEBU=y + CONFIG_SATA_MV=y +diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig +index 2c20599..51f3256 100644 +--- a/arch/arm/mach-mvebu/Kconfig ++++ b/arch/arm/mach-mvebu/Kconfig +@@ -68,6 +68,7 @@ config MACH_ARMADA_38X + select HAVE_SMP + select MACH_MVEBU_V7 + select PINCTRL_ARMADA_38X ++ select ARCH_WANT_LIBATA_LEDS + help + Say 'Y' here if you want your kernel to support boards based + on the Marvell Armada 380/385 SoC with device tree. +diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig +index 39b181d..143bbd5 100644 +--- a/drivers/ata/Kconfig ++++ b/drivers/ata/Kconfig +@@ -46,6 +46,22 @@ config ATA_VERBOSE_ERROR + + If unsure, say Y. + ++config ARCH_WANT_LIBATA_LEDS ++ bool ++ ++config ATA_LEDS ++ bool "support ATA port LED triggers" ++ depends on ARCH_WANT_LIBATA_LEDS ++ select NEW_LEDS ++ select LEDS_CLASS ++ select LEDS_TRIGGERS ++ default y ++ help ++ This option adds a LED trigger for each registered ATA port. ++ It is used to drive disk activity leds connected via GPIO. ++ ++ If unsure, say N. ++ + config ATA_ACPI + bool "ATA ACPI Support" + depends on ACPI +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 599e01b..65228f5 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -5105,6 +5105,30 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) + } + + /** ++ * ata_led_act - Trigger port activity LED ++ * @ap: indicating port ++ * ++ * Blinks any LEDs registered to the trigger. ++ * Commonly used with leds-gpio on NAS systems with disk activity ++ * indicator LEDs. ++ * ++ * LOCKING: ++ * None. ++ */ ++static inline void ata_led_act(struct ata_port *ap) ++{ ++#ifdef CONFIG_ATA_LEDS ++#define LIBATA_BLINK_DELAY 20 /* ms */ ++ unsigned long led_delay = LIBATA_BLINK_DELAY; ++ ++ if (unlikely(!ap->ledtrig)) ++ return; ++ ++ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); ++#endif /* CONFIG_ATA_LEDS */ ++} ++ ++/** + * ata_qc_new_init - Request an available ATA command, and initialize it + * @dev: Device from whom we request an available command structure + * @tag: tag +@@ -5249,6 +5273,10 @@ void ata_qc_complete(struct ata_queued_cmd *qc) + /* Trigger the LED (if available) */ + ledtrig_disk_activity(!!(qc->tf.flags & ATA_TFLAG_WRITE)); + ++#ifdef CONFIG_ATA_LEDS ++ ata_led_act(ap); ++#endif ++ + /* XXX: New EH and old EH use different mechanisms to + * synchronize EH with regular execution path. + * +@@ -6028,6 +6056,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host) + ap->stats.unhandled_irq = 1; + ap->stats.idle_irq = 1; + #endif ++#ifdef CONFIG_ATA_LEDS ++ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); ++#endif + ata_sff_port_init(ap); + + return ap; +@@ -6063,6 +6094,12 @@ static void ata_host_release(struct kref *kref) + + kfree(ap->pmp_link); + kfree(ap->slave_link); ++#ifdef CONFIG_ATA_LEDS ++ if (ap->ledtrig) { ++ led_trigger_unregister(ap->ledtrig); ++ kfree(ap->ledtrig); ++ }; ++#endif + kfree(ap); + host->ports[i] = NULL; + } +@@ -6527,6 +6564,25 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) + host->ports[i]->local_port_no = i + 1; + } + ++#ifdef CONFIG_ATA_LEDS ++ /* register LED triggers for all ports */ ++ for (i = 0; i < host->n_ports; i++) { ++ if (unlikely(!host->ports[i]->ledtrig)) ++ continue; ++ ++ snprintf(host->ports[i]->ledtrig_name, ++ sizeof(host->ports[i]->ledtrig_name), "ata%u", ++ host->ports[i]->print_id); ++ ++ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; ++ ++ if (led_trigger_register(host->ports[i]->ledtrig)) { ++ kfree(host->ports[i]->ledtrig); ++ host->ports[i]->ledtrig = NULL; ++ } ++ } ++#endif ++ + /* Create associated sysfs transport objects */ + for (i = 0; i < host->n_ports; i++) { + rc = ata_tport_add(host->dev,host->ports[i]); +diff --git a/include/linux/libata.h b/include/linux/libata.h +index 38c95d6..3cc5f63 100644 +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + /* + * Define if arch has non-standard setup. This is a _PCI_ standard +@@ -893,6 +894,12 @@ struct ata_port { + #ifdef CONFIG_ATA_ACPI + struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ + #endif ++ ++#ifdef CONFIG_ATA_LEDS ++ struct led_trigger *ledtrig; ++ char ledtrig_name[8]; ++#endif ++ + /* owned by EH */ + u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; + }; +-- +2.7.4 + diff --git a/docs/img/led/led_expansion_wiring_diagram.png b/docs/img/led/led_expansion_wiring_diagram.png new file mode 100755 index 0000000..72b522c Binary files /dev/null and b/docs/img/led/led_expansion_wiring_diagram.png differ diff --git a/docs/img/led/led_location.png b/docs/img/led/led_location.png new file mode 100644 index 0000000..015669a Binary files /dev/null and b/docs/img/led/led_location.png differ diff --git a/docs/led.md b/docs/led.md index a209d64..7daae18 100644 --- a/docs/led.md +++ b/docs/led.md @@ -1,6 +1,25 @@ +![LED location](/img/led/led_location.png) + +## On-Board LEDs + +| LED number | Color | Software control | Remarks | +|------------|-------|------------------|---------| +| LED1 | Green | Yes | Active-low | +| LED2 | Red | Yes | Active-low | +| LED3 | Green | Yes | Active-low | +| LED4 | Green | Yes | Active-low | +| LED5 | Green | Yes | Active-low | +| LED6 | Green | Yes | Active-low | +| LED7 | Green | Yes | Active-low | +| LED8 | Green | No | Power indicator | + +!!! info + LED1 - LED7 is preconfigured for certain indicator under Linux, see [LED under Linux](#led-under-linux) + ## Expansion Panel (J18) -Helios4 board was designed to either use the on-board LEDs or use a custom expansion panel (not-available). If you wish to use the header insure to switch to OFF the DIP switch SW2. +Helios4 board was designed to either use the on-board LEDs or use a custom expansion panel (not-available). +If you wish to use the header insure to switch to OFF the DIP switch SW2. ![Dipswitch LED](/img/led/dipswitch_led_off.png) @@ -9,14 +28,146 @@ Helios4 board was designed to either use the on-board LEDs or use a custom expan ![J18 Pinout](/img/led/gpio_pinout_j18.png) | Pin | LED number | Remarks | -|------------|----------|---------| -| 1 | - | 3.3V supply | -| 2 | - | Not connected | -| 3 | LED1 | Heartbeat LED | -| 4 | LED2 | System Fault LED | -| 5 | LED3 | SATA port 1 LED | -| 6 | LED4 | SATA port 2 LED | -| 7 | LED5 | SATA port 3 LED | -| 8 | LED6 | SATA port 4 LED | -| 9 | LED7 | USB activity LED | -| 10 | - | GND | +|-----|------------|---------| +| 1 | - | 3.3V supply | +| 2 | - | Not connected | +| 3 | LED1 | Active-low | +| 4 | LED2 | Active-low | +| 5 | LED3 | Active-low | +| 6 | LED4 | Active-low | +| 7 | LED5 | Active-low | +| 8 | LED6 | Active-low | +| 9 | LED7 | Active-low | +| 10 | - | GND | + +!!! info + LED1 - LED7 is preconfigured for certain indicator under Linux, see [LED under Linux](#led-under-linux) + +### Wiring Diagram + +Since the signals to control the LEDs are active low, connect the pin to LED's cathode. +Below is example of the wiring diagram. + +![Wiring Example](/img/led/led_expansion_wiring_diagram.png) + + +## LED under Linux + +| LED | Name | Default Trigger | Remarks | +|------|----------------------|-----------------|---------| +| LED1 | helios4:green:status | heartbeat | Blinking periodically | +| LED2 | helios4:red:fault | none | See [Configuring Fault LED](#configuring-fault-led) | +| LED3 | helios4:green:ata1 | ata1 | Blinking on SATA1 activity | +| LED4 | helios4:green:ata2 | ata2 | Blinking on SATA2 activity | +| LED5 | helios4:green:ata3 | ata3 | Blinking on SATA3 activity | +| LED6 | helios4:green:ata4 | ata4 | Blinking on SATA4 activity | +| LED7 | helios4:green:usb | usb-host | Blinking on USB activity, any port | + +!!! note + **ata* ** trigger requires additional patch to mainline kernel. The patch can be found from + [here](/files/led/libata_leds_trigger_mvebu.patch) and is not needed for Armbian. + +The LEDs can be accessed under leds class in sysfs. + +``` +root@helios4:~/# ls -l /sys/class/leds/ + +lrwxrwxrwx 1 root root 0 Dec 4 06:57 helios4:green:ata1 -> ../../devices/platform/io-leds/leds/helios4:green:ata1 +lrwxrwxrwx 1 root root 0 Dec 4 06:57 helios4:green:ata2 -> ../../devices/platform/io-leds/leds/helios4:green:ata2 +lrwxrwxrwx 1 root root 0 Dec 4 06:57 helios4:green:ata3 -> ../../devices/platform/io-leds/leds/helios4:green:ata3 +lrwxrwxrwx 1 root root 0 Dec 4 06:57 helios4:green:ata4 -> ../../devices/platform/io-leds/leds/helios4:green:ata4 +lrwxrwxrwx 1 root root 0 Dec 4 06:57 helios4:green:status -> ../../devices/platform/system-leds/leds/helios4:green:status +lrwxrwxrwx 1 root root 0 Dec 4 06:57 helios4:green:usb -> ../../devices/platform/io-leds/leds/helios4:green:usb +lrwxrwxrwx 1 root root 0 Dec 4 06:57 helios4:red:fault -> ../../devices/platform/system-leds/leds/helios4:red:fault + +``` + +### LEDs Trigger + +- none + +No automatic trigger. Manually control the LED by manipulating "brightness". +More info see [Configuring LED trigger](#configuring-led-trigger). + +- heartbeat + +LED "double" flashes at a load average based rate. The interval might changed during high load. +If the LED no longer blink, that is mean the system lock-up or hung and has to be reset'd. + +- ataN + +LED blink on any read/write activity at specific SATA port. + +- usb-host + +LED blink on USB activity at any port. + +- panic + +This trigger allows LEDs to be configured to blink on a kernel panic. + +- timer + +This allows LEDs to be controlled by a programmable timer via sysfs. delay_on to set how long +the led turned on and delay_off to set how long the led turned off. + + +### Configuring LED trigger + +To configure, simply set the trigger type. For example to set status led triggered by timer + +``` +echo timer | sudo tee -a /sys/class/leds/helios4\:green\:status/trigger +``` + +and done. + +Some of the trigger may exposed additional parameter than can be configured further. + +On **none** trigger, to turn on the LED set the brightness bigger than 0. + +``` +echo 1 | sudo tee -a /sys/class/leds/helios4\:green\:status/brightness +``` + +and to turn off the LED set the brightness to 0. + +``` +echo 0 | sudo tee -a /sys/class/leds/helios4\:green\:status/brightness +``` + +On **timer** trigger, it will exposed *delay_on* and *delay_off* with default value both 0.5 seconds. +To change the delay, set the respective parameter (value in milliseconds) + +``` +echo 1000 | sudo tee -a /sys/class/leds/helios4\:green\:status/delay_on +echo 200 | sudo tee -a /sys/class/leds/helios4\:green\:status/delay_off +``` + +!!! note + The changes is not retained across reboot. Use startup script or udev rules to make it permanent. + +### Configuring Fault LED + +While other LEDs are preconfigured, the fault LED remains unconfigured (trigger:**none**). + +#### 1. As Kernel Panic Indicator + +To configure the LED as Kernel panic indicator, set the trigger to **panic**. +However, this functionality might be redundant with status LED. If the status LED no longer blinking, +that mean the system is hung which can be translated into kernel panic occurred. + +To trigger kernel panic to test the LED, run +``` +echo c > /proc/sysrq-trigger +``` + +!!! warning + Triggering kernel panic can lead to data loss. Use with caution! + +#### 2. As MDADM Fault Indicator + +To configure the LED as MDADM fault indicator, please refer to [MDADM: Configure Fault LED](/mdadm/#configure-fault-led) + +!!! info + On Armbian, this is the default setting for fault LED.