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 };
1.5.7.1