diff --git a/src/gopheros/device/driver.go b/src/gopheros/device/driver.go index 15a6316..4effec1 100644 --- a/src/gopheros/device/driver.go +++ b/src/gopheros/device/driver.go @@ -22,3 +22,68 @@ type Driver interface { // ProbeFn is a function that scans for the presence of a particular // piece of hardware and returns a driver for it. type ProbeFn func() Driver + +// DetectOrder specifies when each driver's probe function will be invoked +// by the hal package. +type DetectOrder int8 + +const ( + // DetectOrderEarly specifies that the driver's probe function should + // be executed at the beginning of the HW detection phase. It is used + // by some of the console and TTY device drivers. + DetectOrderEarly DetectOrder = -128 + + // DetectOrderBeforeACPI specifies that the driver's probe function + // should be executed before attempting any ACPI-based HW detection but + // after any drivers with DetectOrderEarly. + DetectOrderBeforeACPI = -127 + + // DetectOrderACPI specifies that the driver's probe function should + // be executed after parsing the ACPI tables. This is the default (zero + // value) for all drivers. + DetectOrderACPI = 0 + + // DetectOrderLast specifies that the driver's probe function should + // be executed at the end of the HW detection phase. + DetectOrderLast = 127 +) + +// DriverInfo is a driver-defined struct that is passed to calls to RegisterDriver. +type DriverInfo struct { + // Order specifies at which stage of the HW detection step should + // the probe function be invoked. + Order DetectOrder + + // Probe is a function that checks for the presence of a particular + // piece of hardware and returns back a driver for it. + Probe ProbeFn +} + +// DriverInfoList is a list of registered drivers that implements sort.Sort. +type DriverInfoList []*DriverInfo + +// Len returns the length of the driver info list. +func (l DriverInfoList) Len() int { return len(l) } + +// Swap exchanges 2 elements in the driver info list. +func (l DriverInfoList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } + +// Less compares 2 elements of the driver info list. +func (l DriverInfoList) Less(i, j int) bool { return l[i].Order < l[j].Order } + +var ( + // registeredDrivers tracks the drivers registered via a call to + // RegisterDriver. + registeredDrivers DriverInfoList +) + +// RegisterDriver adds the supplied driver info to the list of registered +// drivers. The list can be retrieved by a call to DriverList(). +func RegisterDriver(info *DriverInfo) { + registeredDrivers = append(registeredDrivers, info) +} + +// DriverList returns the list of registered drivers. +func DriverList() DriverInfoList { + return registeredDrivers +} diff --git a/src/gopheros/device/driver_test.go b/src/gopheros/device/driver_test.go new file mode 100644 index 0000000..13f4a3f --- /dev/null +++ b/src/gopheros/device/driver_test.go @@ -0,0 +1,36 @@ +package device + +import ( + "sort" + "testing" +) + +func TestDriverInfoListSorting(t *testing.T) { + defer func() { + registeredDrivers = nil + }() + + origlist := []*DriverInfo{ + &DriverInfo{Order: DetectOrderACPI}, + &DriverInfo{Order: DetectOrderLast}, + &DriverInfo{Order: DetectOrderBeforeACPI}, + &DriverInfo{Order: DetectOrderEarly}, + } + + for _, drv := range origlist { + RegisterDriver(drv) + } + + registeredList := DriverList() + if exp, got := len(origlist), len(registeredList); got != exp { + t.Fatalf("expected DriverList() to return %d entries; got %d", exp, got) + } + + sort.Sort(registeredList) + expOrder := []int{3, 2, 0, 1} + for i, exp := range expOrder { + if registeredList[i] != origlist[exp] { + t.Errorf("expected sorted entry %d to be %v; got %v", i, registeredList[exp], origlist[i]) + } + } +}