# Watchdog support



## BennTech (Feb 15, 2011)

I'm looking for which watchdog chips FreeBSD supports, specifically regarding the Jetway NC9C-550-LF with a Fintek F71869 SuperIO chip, but at this point I'll take anything.  I have found a few patches for Linux, even one specific to the NC9C, but absolutely nothing for FreeBSD.

Can someone point me in the right direction for watchdog support in FreeBSD?


----------



## gordon@ (Feb 15, 2011)

Here's what I was able to dig up. If you have an ICH chipset, you should be good to go: http://koitsu.wordpress.com/2010/07/13/freebsd-and-hardwaresoftware-watchdogs/


----------



## BennTech (Feb 16, 2011)

gordon@ said:
			
		

> Here's what I was able to dig up. If you have an ICH chipset, you should be good to go: http://koitsu.wordpress.com/2010/07/13/freebsd-and-hardwaresoftware-watchdogs/



I came across that one in my search.  While it's an excellent description of how watchdogs work, the only hardware mentioned is Intel ICHxx and a single mention about the author's abandoned Winbond project, bsdhwmon.  And unfortunately, I have neither--mine's a Fintek.

I was hoping for a list of supported watchdog hardware, similar to FreeBSD's Hardware Notes, and ideally the location of the corresponding FreeBSD drivers that I could peruse and hopefully patch with a port from Linux, e.g., Michael A's Troll Blog.  I'm a relative n00b to FreeBSD, but the watchdog is important enough to me to that I'm willing to learn to do it myself if I can find the place to start.


----------



## plamaiziere (Feb 16, 2011)

BennTech said:
			
		

> I'm a relative n00b to FreeBSD, but the watchdog is important enough to me to that I'm willing to learn to do it myself if I can find the place to start.



See watchdog(9), watchdogs use the "watchdog" kernel facility. You have to register your watchdog to this facility by providing a C function. This function should handle a command in argument (stop, start, set the timeout).

You will find several examples of watchdog functions in /usr/src/sys/i386/i386/geode.c (functions xxxx_watchdog)


----------



## BennTech (Feb 17, 2011)

Thanks, plamaiziere.

I looked at geode.c.  Seems a good starting point, but it raises more questions than it answers.  The Geode pats the dog by writing to a port?  Where does the port come from?  Looks like it's based on the specific Geode chipset, which is determined in geode_probe(), but where does that get called from?  But I'm not sure how much of this is even relevant, since I haven't seen the Fintek code where the Fintek actually pats the dog.  Might be completely different.

I was hoping there was already Fintek support in FreeBSD that I could just patch with some new chip IDs.  Unfortunately, it looks like I'll have to borrow some Fintek code from Linux and port it to FreeBSD.  Since this will be my first real programming effort in *nix, I can see so many potential problems...figuring out Linux, figuring out the Fintek code, how do I patch in the F71869, is the Fintek code I picked even compatible with the F71869, figuring out FreeBSD, where do I put my code, how do I get FreeBSD to call it, all the repeated watchdog reboots of my system because of failed tests.  Every step is going to take days to figure out, and if (when) I screw up any step, it could take days just to figure out which step is broken and more to figure out how to fix it.  Sounds like _a lot_ of frustration followed by that euphoric "Eureka!" moment when it works...typical programming.  

LOL...well, it's never easy, is it?  I'll have to wait until late March before I start a project this big.  Again, thanks for getting me started.


----------



## aragon (Feb 18, 2011)

AFAIK, the dog gets patted via /dev/fido by watchdogd(8).


----------



## BennTech (Feb 18, 2011)

aragon said:
			
		

> AFAIK, the dog gets patted via /dev/fido by watchdogd(8).



Right.  The missing link for me is how watchdogd makes the jump from WDIOCPATPAT to the hardware watchdog pat like that in geode.c.  Here's my understanding so far of geode.c that I assume I'll have to duplicate after I find some Fintek code to port:


geode_watchdog(...), which does the actual patting of the Geode hardware watchdog, is added to a watchdog list by
EVENTHANDLER_REGISTER(watchdog_list, geode_watchdog, NULL, 0).  I can't find watchdog_list, but I ass-u-me that this is how the hardware patting ties into watchdogd and that I can just make the same call with my function.  This is done in
geode_probe(...), which is in
DEVMETHOD(device_probe, geode_probe), which ultimately is in
DRIVER_MODULE(geode, pci, geode_driver, geode_devclass, 0, 0), which is a series of macros,
at which point the trail runs dry for me.  I don't know enough about FreeBSD drivers to understand how any of this gets FreeBSD to magically call geode.c in the first place.
The first goal for me is to port some Fintek code and get it patting the Fintek watchdog on its own (then at the very least I can cron it), and after that try to integrate it as a FreeBSD driver like geode.c.  I'll definitely need help on the latter, but like I said, I can't start a project this big until March.


----------



## rstone@ (Feb 27, 2011)

How your device methods get called aren't really an important detail -- the newbus abstraction handles all of that for you.  The important things to understand are when they're called.

(note that I may get some details wrong here -- I'm not intimately familiar with newbus.  Sorry in advance if I make a mistake)

- device_identify is called first when your driver is loaded.  The method is called once for each parent device in the system.  The intent of the identify method is for it to discover any non-standard devices on the bus and notify newbus of their existence by creating a device_t for each of them via BUS_ADD_CHILD.  This method isn't used all that often.  Usually newbus is able to detect all of the devices on a bus itself.

- device_probe is called for each device on the bus.  If your driver can handle the device, return 0.  Otherwise return an error code (typically ENXIO).

- device_attach is called for each device for which the device_probe method matched.  At this stage your softc has been allocated and you should start doing whatever magic is necessary to start bringing the device up.  You don't necessary want to bring the device all of the way up at this point.  In your case, for example, you probably wouldn't want to start the watchdog timer until you get the first kick from watchdogd (otherwise you run the risk of triggering the watchdog before you're ready to kick it).  On the other hand, you should definitely call EVENTHANDLER_REGISTER so that you start getting kicked once watchdogd is running

- device_detach is used when your driver should stop.  Typically this happens because your KLD module has been unloaded or the system is shutting down.  At this point you need to release any resources and clean up any callbacks/event handlers/anything that could try to call back into the driver after it's been unloaded

- device_suspend is called when the system is going into a suspend state.  If you care about supporting suspend, you'd want to disable the watchdog timer at this point.  Depending on your application you may well never suspend the system.  If that's the case you probably don't have to worry about implementing this one.

- device_resume is called after the system is resuming from a suspend state.  Reinitialize the hardware here.  If you didn't implement suspend, there's not much point in implementing resume.


----------

