Problems with uptime() and pause() at system boot time

Hi,

I'm currently working on a FreeBSD device driver for some PCI cards manufactured by our company (Meinberg).

One of the PCI cards needs a certain time interval to become ready to be accessed after power-up, i.e. the card's driver must not access such card before a required uptime has been reached (I know this is ugly, but there's no way to avoid this).

So my idea was to use a code sequence like this in the initialization function for this type of PCI card, before the card is actually accessed by the driver:

Code:
while (1)
{
  struct timeval tv = { 0 };
  struct bintime bt;

  binuptime(&bt);

  if ( bt.sec > required_uptime )
    break;

  // we must wait, so sleep 1 second, then try again
  tv.tv_sec = 1;
  pause( "pause", tvtohz( &tv ) );
}

When the system is already up and running and then my driver module is loaded manually by the kldload command then everything works fine, i.e. binuptime returns reasonable values and pause() delays execution for about 1 second, as expected.

However, if my kernel module is loaded automatically at boot time (I have added a line *_load="YES" for my module to /boot/loader.conf) to probe the PCI devices the binuptime() call always returns 1 for the seconds and a few fractions which increase slowly between calls, and the pause() call does not delay execution at all, so the driver loops forever at this point (or at least for a very long time).

Thus I'm looking for a for an alternate way to implement this, or to delay automatical loading of my module until the uptime() and pause() calls work as expected. Is it possible to define a module/driver dependency under FreeBSD so that my module is only loaded after some other module which handles the uptime()/pause() stuff?

This has been tested under FreeBSD 8.2-RELEASE for amd64, in case this matters.

Thanks in advance for any hints.

Martin
 
Back
Top