From ceba6ecb756418f7976b3d88d168c790b7a40e21 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 16 May 2006 14:10:21 +0000 Subject: [PATCH] Added generic device model. --- src/core/device.c | 97 +++++++++++++++++++++++++++++++++++++++ src/include/gpxe/device.h | 70 ++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 src/core/device.c create mode 100644 src/include/gpxe/device.h diff --git a/src/core/device.c b/src/core/device.c new file mode 100644 index 00000000..e54ab297 --- /dev/null +++ b/src/core/device.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2006 Michael Brown . + * + * 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 any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +/** + * @file + * + * Device model + * + */ + +static struct root_device root_devices[0] __table_start ( root_devices ); +static struct root_device root_devices_end[0] __table_end ( root_devices ); + +/** Registered root devices */ +static LIST_HEAD ( devices ); + +/** + * Register a root device + * + * @v rootdev Root device + * @ret rc Return status code + * + * Calls the root device driver's probe() method, and adds it to the + * list of registered root devices if successful. + */ +static int register_rootdev ( struct root_device *rootdev ) { + int rc; + + DBG ( "Registering %s root bus\n", rootdev->name ); + + if ( ( rc = rootdev->driver->probe ( rootdev ) ) != 0 ) + return rc; + + list_add ( &rootdev->dev.siblings, &devices ); + return 0; +} + +/** + * Unregister a root device + * + * @v rootdev Root device + */ +static void unregister_rootdev ( struct root_device *rootdev ) { + rootdev->driver->remove ( rootdev ); + list_del ( &rootdev->dev.siblings ); + DBG ( "Unregistered %s root bus\n", rootdev->name ); +} + +/** + * Probe all devices + * + * @ret rc Return status code + * + * This initiates probing for all devices in the system. After this + * call, the device hierarchy will be populated, and all hardware + * should be ready to use. + */ +int probe_devices ( void ) { + struct root_device *rootdev; + + for ( rootdev = root_devices; rootdev < root_devices_end; rootdev++ ) { + register_rootdev ( rootdev ); + } + return 0; +} + +/** + * Remove all devices + * + */ +void remove_devices ( void ) { + struct root_device *rootdev; + struct root_device *tmp; + + list_for_each_entry_safe ( rootdev, tmp, &devices, dev.siblings ) { + unregister_rootdev ( rootdev ); + } +} diff --git a/src/include/gpxe/device.h b/src/include/gpxe/device.h new file mode 100644 index 00000000..43bbf604 --- /dev/null +++ b/src/include/gpxe/device.h @@ -0,0 +1,70 @@ +#ifndef _GPXE_DEVICE_H +#define _GPXE_DEVICE_H + +/** + * @file + * + * Device model + * + */ + +#include +#include + +/** A hardware device */ +struct device { + /** Devices on the same bus */ + struct list_head siblings; + /** Devices attached to this device */ + struct list_head children; + /** Bus device */ + struct device *parent; +}; + +/** + * A root device + * + * Root devices are system buses such as PCI, EISA, etc. + * + */ +struct root_device { + /** Name */ + const char *name; + /** Device chain + * + * A root device has a NULL parent field. + */ + struct device dev; + /** Root device driver */ + struct root_driver *driver; +}; + +/** A root device driver */ +struct root_driver { + /** + * Add root device + * + * @v rootdev Root device + * @ret rc Return status code + * + * Called from probe_devices() for all root devices in the build. + */ + int ( * probe ) ( struct root_device *rootdev ); + /** + * Remove root device + * + * @v rootdev Root device + * + * Called from remove_device() for all successfully-probed + * root devices. + */ + void ( * remove ) ( struct root_device *rootdev ); +}; + +/** Declare a root device */ +#define __root_device __table ( root_devices, 01 ) + +extern int probe_devices ( void ); +extern void remove_devices ( void ); + +#endif /* _GPXE_DEVICE_H */