undionly.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <stdint.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <gpxe/device.h>
00025 #include <gpxe/init.h>
00026 #include <undi.h>
00027 #include <undinet.h>
00028 #include <undipreload.h>
00029 
00030 /** @file
00031  *
00032  * "Pure" UNDI driver
00033  *
00034  * This is the UNDI driver without explicit support for PCI or any
00035  * other bus type.  It is capable only of using the preloaded UNDI
00036  * device.  It must not be combined in an image with any other
00037  * drivers.
00038  *
00039  * If you want a PXE-loadable image that contains only the UNDI
00040  * driver, build "bin/undionly.kpxe".
00041  *
00042  * If you want any other image format, or any other drivers in
00043  * addition to the UNDI driver, build e.g. "bin/undi.dsk".
00044  */
00045 
00046 /**
00047  * Probe UNDI root bus
00048  *
00049  * @v rootdev           UNDI bus root device
00050  *
00051  * Scans the UNDI bus for devices and registers all devices it can
00052  * find.
00053  */
00054 static int undibus_probe ( struct root_device *rootdev ) {
00055         struct undi_device *undi = &preloaded_undi;
00056         int rc;
00057 
00058         /* Check for a valie preloaded UNDI device */
00059         if ( ! undi->entry.segment ) {
00060                 DBG ( "No preloaded UNDI device found!\n" );
00061                 return -ENODEV;
00062         }
00063 
00064         /* Add to device hierarchy */
00065         strncpy ( undi->dev.name, "UNDI",
00066                   ( sizeof ( undi->dev.name ) - 1 ) );
00067         if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
00068                 undi->dev.desc.bus_type = BUS_TYPE_PCI;
00069                 undi->dev.desc.location = undi->pci_busdevfn;
00070                 undi->dev.desc.vendor = undi->pci_vendor;
00071                 undi->dev.desc.device = undi->pci_device;
00072         } else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
00073                 undi->dev.desc.bus_type = BUS_TYPE_ISAPNP;
00074         }
00075         undi->dev.parent = &rootdev->dev;
00076         list_add ( &undi->dev.siblings, &rootdev->dev.children);
00077         INIT_LIST_HEAD ( &undi->dev.children );
00078 
00079         /* Create network device */
00080         if ( ( rc = undinet_probe ( undi ) ) != 0 )
00081                 goto err;
00082 
00083         return 0;
00084 
00085  err:
00086         list_del ( &undi->dev.siblings );
00087         return rc;
00088 }
00089 
00090 /**
00091  * Remove UNDI root bus
00092  *
00093  * @v rootdev           UNDI bus root device
00094  */
00095 static void undibus_remove ( struct root_device *rootdev __unused ) {
00096         struct undi_device *undi = &preloaded_undi;
00097 
00098         undinet_remove ( undi );
00099         list_del ( &undi->dev.siblings );
00100 }
00101 
00102 /** UNDI bus root device driver */
00103 static struct root_driver undi_root_driver = {
00104         .probe = undibus_probe,
00105         .remove = undibus_remove,
00106 };
00107 
00108 /** UNDI bus root device */
00109 struct root_device undi_root_device __root_device = {
00110         .dev = { .name = "UNDI" },
00111         .driver = &undi_root_driver,
00112 };
00113 
00114 /**
00115  * Prepare for exit
00116  *
00117  * @v flags             Shutdown flags
00118  */
00119 static void undionly_shutdown ( int flags ) {
00120         /* If we are shutting down to boot an OS, clear the "keep PXE
00121          * stack" flag.
00122          */
00123         if ( flags & SHUTDOWN_BOOT )
00124                 preloaded_undi.flags &= ~UNDI_FL_KEEP_ALL;
00125 }
00126 
00127 struct startup_fn startup_undionly __startup_fn ( STARTUP_LATE ) = {
00128         .shutdown = undionly_shutdown,
00129 };

Generated on Tue Apr 6 20:00:49 2010 for gPXE by  doxygen 1.5.7.1