From 5ddc96811a57e97ed35d4ca1ae8da321717f1712 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Sun, 9 Dec 2012 11:17:50 +0100 Subject: [PATCH] working version --- diskwatch.c | 119 +++++++++++++++++++++++++++++----------------------- lcd.c | 6 ++- 2 files changed, 71 insertions(+), 54 deletions(-) diff --git a/diskwatch.c b/diskwatch.c index 9888636..963cb2a 100644 --- a/diskwatch.c +++ b/diskwatch.c @@ -62,6 +62,8 @@ struct diskwatch { static struct diskwatch diskwatch_glob; +static int diskwatch_check_standby(struct disk_entry *entry); + static int lcdpage_diskwatch(struct lcddev *lcd, int event, void *privdata) { static struct disk_entry *entry; @@ -104,6 +106,8 @@ static int lcdpage_diskwatch(struct lcddev *lcd, int event, void *privdata) snprintf(line1, sizeof(line1), "DISK(%s):", entry->device); if (entry->flags & F_PRESENT) { + diskwatch_check_standby(entry); + if (entry->flags & F_STANDBY) { snprintf(line2, sizeof(line2), "STANDBY"); } else { @@ -125,7 +129,64 @@ static int lcdpage_diskwatch(struct lcddev *lcd, int event, void *privdata) return 1000; } -static int diskwatch_check_cb(int timerid, void *privdata) +static int diskwatch_check_standby(struct disk_entry *entry) +{ + if (!(entry->flags & F_PRESENT)) + return 0; + + int fd = open(entry->device, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + log_print(LOG_ERROR, "%s(): failed to open %s", __FUNCTION__, entry->device); + return -1; + } + + unsigned char args[4] = { ATA_OP_CHECKPOWERMODE1, 0, 0, 0 }; + if (do_drive_cmd(fd, args)) { + args[0] = ATA_OP_CHECKPOWERMODE2; + if (do_drive_cmd(fd, args)) { + log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_CHECKPOWERMODEx) failed on %s", __FUNCTION__, entry->device); + close(fd); + return -1; + } + } + + time_t now = time(NULL); + + /* args[2]: + * 0x00 - standby + * 0x40 - NVcache_spindown + * 0x41 - NVcache_spinup + * 0x80 - idle + * 0xFF - active/idle + */ + /* drive is in standby */ + if (args[2] == 0x00) { + entry->flags |= F_STANDBY; + + /* drive was in standby, and is now active */ + } else if (entry->flags & F_STANDBY) { + entry->flags &= ~(F_STANDBY); + entry->standby_timeout = now + entry->timeout_sec; + + /* drive is active, and timeout is up */ + } else if (now >= entry->standby_timeout) { + unsigned char args[4] = { ATA_OP_STANDBYNOW1, 0, 0, 0}; + if (do_drive_cmd(fd, args)) { + args[0] = ATA_OP_STANDBYNOW2; + if (do_drive_cmd(fd, args)) { + log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_STANDBYNOWx) failed on %s", __FUNCTION__, entry->device); + close(fd); + return -1; + } + } + entry->flags |= F_STANDBY; + } + + close(fd); + return 0; +} + +static int diskwatch_check_stats(int timerid, void *privdata) { struct diskwatch *dwatch = (struct diskwatch *)privdata; @@ -189,6 +250,7 @@ static int diskwatch_check_cb(int timerid, void *privdata) if (entry->sectors_rd == val[2] && entry->sectors_wr == val[6]) continue; + /* sector counts changed, disk is not in standby */ entry->flags &= ~(F_STANDBY); entry->sectors_rd = val[2]; entry->sectors_wr = val[6]; @@ -199,56 +261,7 @@ static int diskwatch_check_cb(int timerid, void *privdata) fclose(fp); list_for_each_entry(entry, &dwatch->disk_list, list) { - if (!(entry->flags & F_PRESENT)) - continue; - - int fd = open(entry->device, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - log_print(LOG_ERROR, "%s(): failed to open %s", __FUNCTION__, entry->device); - continue; - } - - unsigned char args[4] = { ATA_OP_CHECKPOWERMODE1, 0, 0, 0 }; - if (do_drive_cmd(fd, args)) { - args[0] = ATA_OP_CHECKPOWERMODE2; - if (do_drive_cmd(fd, args)) { - log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_CHECKPOWERMODEx) failed on %s", __FUNCTION__, entry->device); - close(fd); - continue; - } - } - - /* args[2]: - * 0x00 - standby - * 0x40 - NVcache_spindown - * 0x41 - NVcache_spinup - * 0x80 - idle - * 0xFF - active/idle - */ - /* drive is in standby */ - if (args[2] == 0x00) { - entry->flags |= F_STANDBY; - - /* drive was in standby, and is now active (without change in sector counts */ - } else if (entry->flags & F_STANDBY) { - entry->flags &= ~(F_STANDBY); - entry->standby_timeout = now + entry->timeout_sec; - - /* drive is active, and timeout is up */ - } else if (now >= entry->standby_timeout) { - unsigned char args[4] = { ATA_OP_STANDBYNOW1, 0, 0, 0}; - if (do_drive_cmd(fd, args)) { - args[0] = ATA_OP_STANDBYNOW2; - if (do_drive_cmd(fd, args)) { - log_print(LOG_WARN, "%s: do_drive_cmd(ATA_OP_STANDBYNOWx) failed on %s", __FUNCTION__, entry->device); - close(fd); - continue; - } - } - entry->flags |= F_STANDBY; - } - - close(fd); + diskwatch_check_standby(entry); } return 0; @@ -312,11 +325,11 @@ int diskwatch_init(struct lcddev *lcd) if (diskcount <= 0) return 0; - diskwatch_check_cb(0, dwatch); + diskwatch_check_stats(0, dwatch); int check_interval = 0; config_get_int("diskwatch", "check_interval", &check_interval, 60); - dwatch->check_timeout = event_add_timeout_ms(check_interval * 1000, diskwatch_check_cb, 0, dwatch); + dwatch->check_timeout = event_add_timeout_ms(check_interval * 1000, diskwatch_check_stats, 0, dwatch); dwatch->lcd = lcd; if (dwatch->lcd != NULL) { diff --git a/lcd.c b/lcd.c index a8463bc..48d739d 100644 --- a/lcd.c +++ b/lcd.c @@ -33,7 +33,7 @@ #include "list.h" #include "logging.h" -#define _LCD_DEBUG 1 +#define _LCD_DEBUG 0 #define _LCD_DUMMY 1 #define LCD_SCROLL_SPEED 750 /* 750ms */ @@ -582,9 +582,13 @@ static void lcd_pagecallback(struct lcddev *dev, int event) int next; do { +#if (_LCD_DEBUG > 0) log_print(LOG_DEBUG, "%s: cb(%p, 0x%x)", __FUNCTION__, dev->current_page, event); +#endif int retval = dev->current_page->callback(dev, event, dev->current_page->privdata); +#if (_LCD_DEBUG > 0) log_print(LOG_DEBUG, "%s: cb(%p, 0x%x) => 0x%x", __FUNCTION__, dev->current_page, event, retval); +#endif next = (retval == LCDPAGE_COMMAND_NEXT); if (next) {