working version

This commit is contained in:
Olaf Rempel 2012-12-09 11:17:50 +01:00
parent 606a3306c5
commit 5ddc96811a
2 changed files with 71 additions and 54 deletions

View File

@ -62,6 +62,8 @@ struct diskwatch {
static struct diskwatch diskwatch_glob; 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 int lcdpage_diskwatch(struct lcddev *lcd, int event, void *privdata)
{ {
static struct disk_entry *entry; 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); snprintf(line1, sizeof(line1), "DISK(%s):", entry->device);
if (entry->flags & F_PRESENT) { if (entry->flags & F_PRESENT) {
diskwatch_check_standby(entry);
if (entry->flags & F_STANDBY) { if (entry->flags & F_STANDBY) {
snprintf(line2, sizeof(line2), "STANDBY"); snprintf(line2, sizeof(line2), "STANDBY");
} else { } else {
@ -125,7 +129,64 @@ static int lcdpage_diskwatch(struct lcddev *lcd, int event, void *privdata)
return 1000; 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; 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]) if (entry->sectors_rd == val[2] && entry->sectors_wr == val[6])
continue; continue;
/* sector counts changed, disk is not in standby */
entry->flags &= ~(F_STANDBY); entry->flags &= ~(F_STANDBY);
entry->sectors_rd = val[2]; entry->sectors_rd = val[2];
entry->sectors_wr = val[6]; entry->sectors_wr = val[6];
@ -199,56 +261,7 @@ static int diskwatch_check_cb(int timerid, void *privdata)
fclose(fp); fclose(fp);
list_for_each_entry(entry, &dwatch->disk_list, list) { list_for_each_entry(entry, &dwatch->disk_list, list) {
if (!(entry->flags & F_PRESENT)) diskwatch_check_standby(entry);
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);
} }
return 0; return 0;
@ -312,11 +325,11 @@ int diskwatch_init(struct lcddev *lcd)
if (diskcount <= 0) if (diskcount <= 0)
return 0; return 0;
diskwatch_check_cb(0, dwatch); diskwatch_check_stats(0, dwatch);
int check_interval = 0; int check_interval = 0;
config_get_int("diskwatch", "check_interval", &check_interval, 60); 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; dwatch->lcd = lcd;
if (dwatch->lcd != NULL) { if (dwatch->lcd != NULL) {

6
lcd.c
View File

@ -33,7 +33,7 @@
#include "list.h" #include "list.h"
#include "logging.h" #include "logging.h"
#define _LCD_DEBUG 1 #define _LCD_DEBUG 0
#define _LCD_DUMMY 1 #define _LCD_DUMMY 1
#define LCD_SCROLL_SPEED 750 /* 750ms */ #define LCD_SCROLL_SPEED 750 /* 750ms */
@ -582,9 +582,13 @@ static void lcd_pagecallback(struct lcddev *dev, int event)
int next; int next;
do { do {
#if (_LCD_DEBUG > 0)
log_print(LOG_DEBUG, "%s: cb(%p, 0x%x)", __FUNCTION__, dev->current_page, event); 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); 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); log_print(LOG_DEBUG, "%s: cb(%p, 0x%x) => 0x%x", __FUNCTION__, dev->current_page, event, retval);
#endif
next = (retval == LCDPAGE_COMMAND_NEXT); next = (retval == LCDPAGE_COMMAND_NEXT);
if (next) { if (next) {