/* * Copyright (C) 2018 AVM GmbH * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include "wdt.h" #include "wdt-private.h" #include #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) #define MISC_MAJOR 10 static const char *wdt_devicename[] = { #ifdef USE_AVM_DEVICE_NAMESPACE "/dev/avm_watchdog", #endif "/dev/watchdog" /* Fallback device name, shared with mainline watchdog driver */ }; const char *watchdog_device_name(void) { struct stat statbuf; unsigned i; int ret; for (i = 0; i < ARRAY_SIZE(wdt_devicename); ++i) { /* * The avm watchdog registers its device with a dynamic major id, * whereas the standard /dev/watchdog is a misc device. Assume we're * ok if our device is a char device, and not a misc device. * * We can't open+fstat, since opening the device starts watchdogs * with mainline drivers, and that may be a one-way ticket. */ ret = stat(wdt_devicename[i], &statbuf); if (ret == 0 && S_ISCHR(statbuf.st_mode) && major(statbuf.st_rdev) != MISC_MAJOR) return wdt_devicename[i]; } errno = ENODEV; return NULL; } int watchdog_open_device(void) { const char *devname; int fd; devname = watchdog_device_name(); if (!devname) return WDT_UNKNOWN_HANDLE; fd = open(devname, O_RDWR); if (fd < 0) return WDT_ALREADY_REGISTERED; return fd; }