|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2010 VMware, Inc. All Rights Reserved. ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ! 17: */ ! 18: ! 19: FILE_LICENCE ( GPL2_OR_LATER ); ! 20: ! 21: #include <string.h> ! 22: #include <errno.h> ! 23: #include <ipxe/device.h> ! 24: #include <ipxe/init.h> ! 25: #include <ipxe/efi/efi.h> ! 26: #include <ipxe/efi/Protocol/SimpleNetwork.h> ! 27: #include "snp.h" ! 28: #include "snpnet.h" ! 29: ! 30: /** @file ! 31: * ! 32: * Chain-loading Simple Network Protocol Bus Driver ! 33: * ! 34: * This bus driver allows iPXE to use the EFI Simple Network Protocol provided ! 35: * by the platform to transmit and receive packets. It attaches to only the ! 36: * device handle that iPXE was loaded from, that is, it will only use the ! 37: * Simple Network Protocol on the current loaded image's device handle. ! 38: * ! 39: * Eseentially, this driver provides the EFI equivalent of the "undionly" ! 40: * driver. ! 41: */ ! 42: ! 43: /** The one and only SNP network device */ ! 44: static struct snp_device snponly_dev; ! 45: ! 46: /** EFI simple network protocol GUID */ ! 47: static EFI_GUID efi_simple_network_protocol_guid ! 48: = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; ! 49: ! 50: /** ! 51: * Probe SNP root bus ! 52: * ! 53: * @v rootdev SNP bus root device ! 54: * ! 55: * Look at the loaded image's device handle and see if the simple network ! 56: * protocol exists. If so, register a driver for it. ! 57: */ ! 58: static int snpbus_probe ( struct root_device *rootdev ) { ! 59: EFI_BOOT_SERVICES *bs = efi_systab->BootServices; ! 60: EFI_STATUS efirc; ! 61: int rc; ! 62: void *snp; ! 63: ! 64: efirc = bs->OpenProtocol ( efi_loaded_image->DeviceHandle, ! 65: &efi_simple_network_protocol_guid, ! 66: &snp, efi_image_handle, NULL, ! 67: EFI_OPEN_PROTOCOL_GET_PROTOCOL ); ! 68: if ( efirc ) { ! 69: DBG ( "Could not find Simple Network Protocol!\n" ); ! 70: return -ENODEV; ! 71: } ! 72: snponly_dev.snp = snp; ! 73: ! 74: /* Add to device hierarchy */ ! 75: strncpy ( snponly_dev.dev.name, "EFI SNP", ! 76: ( sizeof ( snponly_dev.dev.name ) - 1 ) ); ! 77: snponly_dev.dev.parent = &rootdev->dev; ! 78: list_add ( &snponly_dev.dev.siblings, &rootdev->dev.children); ! 79: INIT_LIST_HEAD ( &snponly_dev.dev.children ); ! 80: ! 81: /* Create network device */ ! 82: if ( ( rc = snpnet_probe ( &snponly_dev ) ) != 0 ) ! 83: goto err; ! 84: ! 85: return 0; ! 86: ! 87: err: ! 88: list_del ( &snponly_dev.dev.siblings ); ! 89: return rc; ! 90: } ! 91: ! 92: /** ! 93: * Remove SNP root bus ! 94: * ! 95: * @v rootdev SNP bus root device ! 96: */ ! 97: static void snpbus_remove ( struct root_device *rootdev __unused ) { ! 98: snpnet_remove ( &snponly_dev ); ! 99: list_del ( &snponly_dev.dev.siblings ); ! 100: } ! 101: ! 102: /** SNP bus root device driver */ ! 103: static struct root_driver snp_root_driver = { ! 104: .probe = snpbus_probe, ! 105: .remove = snpbus_remove, ! 106: }; ! 107: ! 108: /** SNP bus root device */ ! 109: struct root_device snp_root_device __root_device = { ! 110: .dev = { .name = "EFI SNP" }, ! 111: .driver = &snp_root_driver, ! 112: }; ! 113: ! 114: /** ! 115: * Prepare for exit ! 116: * ! 117: * @v booting System is shutting down for OS boot ! 118: */ ! 119: static void snponly_shutdown ( int booting ) { ! 120: /* If we are shutting down to boot an OS, make sure the SNP does not ! 121: * stay active. ! 122: */ ! 123: if ( booting ) ! 124: snponly_dev.removal_state = EfiSimpleNetworkStopped; ! 125: } ! 126: ! 127: struct startup_fn startup_snponly __startup_fn ( STARTUP_LATE ) = { ! 128: .shutdown = snponly_shutdown, ! 129: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.