#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <pxe.h>
#include <realmode.h>
#include <undirom.h>
Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static | LIST_HEAD (undiroms) |
| List of all UNDI ROMs. | |
| static int | undirom_parse_pxeromid (struct undi_rom *undirom, unsigned int pxeromid) |
| Parse PXE ROM ID structure. | |
| static int | undirom_parse_pcirheader (struct undi_rom *undirom, unsigned int pcirheader) |
| Parse PCI expansion header. | |
| static int | undirom_probe (unsigned int rom_segment) |
| Probe UNDI ROM. | |
| static void | undirom_probe_all_roms (void) |
| Create UNDI ROMs for all possible expansion ROMs. | |
| struct undi_rom * | undirom_find_pci (unsigned int vendor_id, unsigned int device_id, unsigned int rombase) |
| Find UNDI ROM for PCI device. | |
Definition in file undirom.c.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static LIST_HEAD | ( | undiroms | ) | [static] |
List of all UNDI ROMs.
| static int undirom_parse_pxeromid | ( | struct undi_rom * | undirom, | |
| unsigned int | pxeromid | |||
| ) | [static] |
Parse PXE ROM ID structure.
| undirom | UNDI ROM | |
| pxeromid | Offset within ROM to PXE ROM ID structure |
| rc | Return status code |
Definition at line 44 of file undirom.c.
References undi_rom::code_size, undi_rom_id::CodeSize, copy_from_real, undi_rom::data_size, undi_rom_id::DataSize, DBGC, EINVAL, undi_rom::loader_entry, s_SEGOFF16::offset, undi_rom::rom_segment, s_SEGOFF16::segment, undi_rom_id::Signature, UNDI_ROM_ID_SIGNATURE, and undi_rom_id::UNDILoader.
Referenced by undirom_probe().
00045 { 00046 struct undi_rom_id undi_rom_id; 00047 unsigned int undiloader; 00048 00049 DBGC ( undirom, "UNDIROM %p has PXE ROM ID at %04x:%04x\n", undirom, 00050 undirom->rom_segment, pxeromid ); 00051 00052 /* Read PXE ROM ID structure and verify */ 00053 copy_from_real ( &undi_rom_id, undirom->rom_segment, pxeromid, 00054 sizeof ( undi_rom_id ) ); 00055 if ( undi_rom_id.Signature != UNDI_ROM_ID_SIGNATURE ) { 00056 DBGC ( undirom, "UNDIROM %p has bad PXE ROM ID signature " 00057 "%08x\n", undirom, undi_rom_id.Signature ); 00058 return -EINVAL; 00059 } 00060 00061 /* Check for UNDI loader */ 00062 undiloader = undi_rom_id.UNDILoader; 00063 if ( ! undiloader ) { 00064 DBGC ( undirom, "UNDIROM %p has no UNDI loader\n", undirom ); 00065 return -EINVAL; 00066 } 00067 00068 /* Fill in UNDI ROM loader fields */ 00069 undirom->loader_entry.segment = undirom->rom_segment; 00070 undirom->loader_entry.offset = undiloader; 00071 undirom->code_size = undi_rom_id.CodeSize; 00072 undirom->data_size = undi_rom_id.DataSize; 00073 00074 DBGC ( undirom, "UNDIROM %p has UNDI loader at %04x:%04x " 00075 "(code %04zx data %04zx)\n", undirom, 00076 undirom->loader_entry.segment, undirom->loader_entry.offset, 00077 undirom->code_size, undirom->data_size ); 00078 return 0; 00079 }
| static int undirom_parse_pcirheader | ( | struct undi_rom * | undirom, | |
| unsigned int | pcirheader | |||
| ) | [static] |
Parse PCI expansion header.
| undirom | UNDI ROM | |
| pcirheader | Offset within ROM to PCI expansion header |
Definition at line 87 of file undirom.c.
References undi_rom::bus_id, undi_rom::bus_type, copy_from_real, DBGC, pcir_header::device_id, undi_pci_device_id::device_id, EINVAL, undi_device_id::pci, PCI_NIC, PCIR_SIGNATURE, undi_rom::rom_segment, pcir_header::signature, pcir_header::vendor_id, and undi_pci_device_id::vendor_id.
Referenced by undirom_probe().
00088 { 00089 struct pcir_header pcir_header; 00090 00091 DBGC ( undirom, "UNDIROM %p has PCI expansion header at %04x:%04x\n", 00092 undirom, undirom->rom_segment, pcirheader ); 00093 00094 /* Read PCI expansion header and verify */ 00095 copy_from_real ( &pcir_header, undirom->rom_segment, pcirheader, 00096 sizeof ( pcir_header ) ); 00097 if ( pcir_header.signature != PCIR_SIGNATURE ) { 00098 DBGC ( undirom, "UNDIROM %p has bad PCI expansion header " 00099 "signature %08x\n", undirom, pcir_header.signature ); 00100 return -EINVAL; 00101 } 00102 00103 /* Fill in UNDI ROM PCI device fields */ 00104 undirom->bus_type = PCI_NIC; 00105 undirom->bus_id.pci.vendor_id = pcir_header.vendor_id; 00106 undirom->bus_id.pci.device_id = pcir_header.device_id; 00107 00108 DBGC ( undirom, "UNDIROM %p is for PCI devices %04x:%04x\n", undirom, 00109 undirom->bus_id.pci.vendor_id, undirom->bus_id.pci.device_id ); 00110 return 0; 00111 00112 }
| static int undirom_probe | ( | unsigned int | rom_segment | ) | [static] |
Probe UNDI ROM.
| rom_segment | ROM segment address |
| rc | Return status code |
Definition at line 120 of file undirom.c.
References copy_from_real, DBG, DBGC, EINVAL, ENOMEM, free(), undi_rom::list, list_add, NULL, undi_rom_header::PCIRHeader, undi_rom_header::PXEROMID, undi_rom::rom_segment, ROM_SIGNATURE, undi_rom_header::ROMLength, undi_rom_header::Signature, undirom_parse_pcirheader(), undirom_parse_pxeromid(), and zalloc().
Referenced by undirom_probe_all_roms().
00120 { 00121 struct undi_rom *undirom = NULL; 00122 struct undi_rom_header romheader; 00123 size_t rom_len; 00124 unsigned int pxeromid; 00125 unsigned int pcirheader; 00126 int rc; 00127 00128 /* Read expansion ROM header and verify */ 00129 copy_from_real ( &romheader, rom_segment, 0, sizeof ( romheader ) ); 00130 if ( romheader.Signature != ROM_SIGNATURE ) { 00131 rc = -EINVAL; 00132 goto err; 00133 } 00134 rom_len = ( romheader.ROMLength * 512 ); 00135 00136 /* Allocate memory for UNDI ROM */ 00137 undirom = zalloc ( sizeof ( *undirom ) ); 00138 if ( ! undirom ) { 00139 DBG ( "Could not allocate UNDI ROM structure\n" ); 00140 rc = -ENOMEM; 00141 goto err; 00142 } 00143 DBGC ( undirom, "UNDIROM %p trying expansion ROM at %04x:0000 " 00144 "(%zdkB)\n", undirom, rom_segment, ( rom_len / 1024 ) ); 00145 undirom->rom_segment = rom_segment; 00146 00147 /* Check for and parse PXE ROM ID */ 00148 pxeromid = romheader.PXEROMID; 00149 if ( ! pxeromid ) { 00150 DBGC ( undirom, "UNDIROM %p has no PXE ROM ID\n", undirom ); 00151 rc = -EINVAL; 00152 goto err; 00153 } 00154 if ( pxeromid > rom_len ) { 00155 DBGC ( undirom, "UNDIROM %p PXE ROM ID outside ROM\n", 00156 undirom ); 00157 rc = -EINVAL; 00158 goto err; 00159 } 00160 if ( ( rc = undirom_parse_pxeromid ( undirom, pxeromid ) ) != 0 ) 00161 goto err; 00162 00163 /* Parse PCIR header, if present */ 00164 pcirheader = romheader.PCIRHeader; 00165 if ( pcirheader ) 00166 undirom_parse_pcirheader ( undirom, pcirheader ); 00167 00168 /* Add to UNDI ROM list and return */ 00169 DBGC ( undirom, "UNDIROM %p registered\n", undirom ); 00170 list_add ( &undirom->list, &undiroms ); 00171 return 0; 00172 00173 err: 00174 free ( undirom ); 00175 return rc; 00176 }
| static void undirom_probe_all_roms | ( | void | ) | [static] |
Create UNDI ROMs for all possible expansion ROMs.
Definition at line 183 of file undirom.c.
References DBG, and undirom_probe().
Referenced by undirom_find_pci().
00183 { 00184 static int probed = 0; 00185 unsigned int rom_segment; 00186 00187 /* Perform probe only once */ 00188 if ( probed ) 00189 return; 00190 00191 DBG ( "Scanning for PXE expansion ROMs\n" ); 00192 00193 /* Scan through expansion ROM region at 512 byte intervals */ 00194 for ( rom_segment = 0xc000 ; rom_segment < 0x10000 ; 00195 rom_segment += 0x20 ) { 00196 undirom_probe ( rom_segment ); 00197 } 00198 00199 probed = 1; 00200 }
| struct undi_rom* undirom_find_pci | ( | unsigned int | vendor_id, | |
| unsigned int | device_id, | |||
| unsigned int | rombase | |||
| ) | [read] |
Find UNDI ROM for PCI device.
| vendor_id | PCI vendor ID | |
| device_id | PCI device ID | |
| rombase | ROM base address, or 0 for any |
| undirom | UNDI ROM, or NULL |
Definition at line 210 of file undirom.c.
References undi_rom::bus_id, undi_rom::bus_type, DBG, DBGC, undi_pci_device_id::device_id, undi_rom::list, list_for_each_entry, NULL, undi_device_id::pci, PCI_NIC, undi_rom::rom_segment, undirom_probe_all_roms(), and undi_pci_device_id::vendor_id.
Referenced by undipci_find_rom().
00212 { 00213 struct undi_rom *undirom; 00214 00215 undirom_probe_all_roms(); 00216 00217 list_for_each_entry ( undirom, &undiroms, list ) { 00218 if ( undirom->bus_type != PCI_NIC ) 00219 continue; 00220 if ( undirom->bus_id.pci.vendor_id != vendor_id ) 00221 continue; 00222 if ( undirom->bus_id.pci.device_id != device_id ) 00223 continue; 00224 if ( rombase && ( ( undirom->rom_segment << 4 ) != rombase ) ) 00225 continue; 00226 DBGC ( undirom, "UNDIROM %p matched PCI %04x:%04x (%08x)\n", 00227 undirom, vendor_id, device_id, rombase ); 00228 return undirom; 00229 } 00230 00231 DBG ( "No UNDI ROM matched PCI %04x:%04x (%08x)\n", 00232 vendor_id, device_id, rombase ); 00233 return NULL; 00234 }
1.5.7.1