#include <pxe_types.h>Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| int | pxeparent_call (SEGOFF16_t entry, unsigned int function, void *params, size_t params_len) |
| Issue parent PXE API call. | |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| int pxeparent_call | ( | SEGOFF16_t | entry, | |
| unsigned int | function, | |||
| void * | params, | |||
| size_t | params_len | |||
| ) |
Issue parent PXE API call.
| entry | Parent PXE stack entry point | |
| function | API call number | |
| params | PXE parameter block | |
| params_len | Length of PXE parameter block |
| rc | Return status code |
Definition at line 125 of file pxeparent.c.
References __asm__(), __from_data16, assert, DBG, DBG_HDA, EIO, gateA20_set(), memcpy, s_SEGOFF16::offset, PXENV_EXIT_SUCCESS, pxeparent_entry_point, pxeparent_function_name(), pxeparent_params, REAL_CODE, rm_ds, s_SEGOFF16::segment, and strerror().
Referenced by get_cached_dhcpack(), undinet_close(), undinet_open(), undinet_poll(), undinet_probe(), undinet_remove(), and undinet_transmit().
00126 { 00127 PXENV_EXIT_t exit; 00128 int discard_b, discard_D; 00129 int rc; 00130 00131 /* Copy parameter block and entry point */ 00132 assert ( params_len <= sizeof ( pxeparent_params ) ); 00133 memcpy ( &pxeparent_params, params, params_len ); 00134 memcpy ( &pxeparent_entry_point, &entry, sizeof ( entry ) ); 00135 00136 /* Call real-mode entry point. This calling convention will 00137 * work with both the !PXE and the PXENV+ entry points. 00138 */ 00139 __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t" 00140 "pushw %%di\n\t" 00141 "pushw %%bx\n\t" 00142 "lcall *pxeparent_entry_point\n\t" 00143 "addw $6, %%sp\n\t" ) 00144 : "=a" ( exit ), "=b" ( discard_b ), 00145 "=D" ( discard_D ) 00146 : "b" ( function ), 00147 "D" ( __from_data16 ( &pxeparent_params ) ) 00148 : "ecx", "edx", "esi", "ebp" ); 00149 00150 /* PXE API calls may rudely change the status of A20 and not 00151 * bother to restore it afterwards. Intel is known to be 00152 * guilty of this. 00153 * 00154 * Note that we will return to this point even if A20 gets 00155 * screwed up by the parent PXE stack, because Etherboot always 00156 * resides in an even megabyte of RAM. 00157 */ 00158 gateA20_set(); 00159 00160 /* Determine return status code based on PXENV_EXIT and 00161 * PXENV_STATUS 00162 */ 00163 if ( exit == PXENV_EXIT_SUCCESS ) { 00164 rc = 0; 00165 } else { 00166 rc = -pxeparent_params.Status; 00167 /* Paranoia; don't return success for the combination 00168 * of PXENV_EXIT_FAILURE but PXENV_STATUS_SUCCESS 00169 */ 00170 if ( rc == 0 ) 00171 rc = -EIO; 00172 } 00173 00174 /* If anything goes wrong, print as much debug information as 00175 * it's possible to give. 00176 */ 00177 if ( rc != 0 ) { 00178 SEGOFF16_t rm_params = { 00179 .segment = rm_ds, 00180 .offset = __from_data16 ( &pxeparent_params ), 00181 }; 00182 00183 DBG ( "PXEPARENT %s failed: %s\n", 00184 pxeparent_function_name ( function ), strerror ( rc ) ); 00185 DBG ( "PXEPARENT parameters at %04x:%04x length " 00186 "%#02zx, entry point at %04x:%04x\n", 00187 rm_params.segment, rm_params.offset, params_len, 00188 pxeparent_entry_point.segment, 00189 pxeparent_entry_point.offset ); 00190 DBG ( "PXEPARENT parameters provided:\n" ); 00191 DBG_HDA ( rm_params, params, params_len ); 00192 DBG ( "PXEPARENT parameters returned:\n" ); 00193 DBG_HDA ( rm_params, &pxeparent_params, params_len ); 00194 } 00195 00196 /* Copy parameter block back */ 00197 memcpy ( params, &pxeparent_params, params_len ); 00198 00199 return rc; 00200 }
1.5.7.1