mirror of
https://github.com/ipxe/ipxe
synced 2026-05-23 20:00:12 +03:00
[efi] Support the EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE operation
Support getting the size of a TFTP file via the EFI PXE API, as required for booting OpenBSD. Debugged-by: Eric Radman <ericshane@eradman.com> Tested-by: Eric Radman <ericshane@eradman.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -96,6 +96,8 @@ struct efi_pxe {
|
|||||||
|
|
||||||
/** (M)TFTP download interface */
|
/** (M)TFTP download interface */
|
||||||
struct interface tftp;
|
struct interface tftp;
|
||||||
|
/** Opcode */
|
||||||
|
unsigned int opcode;
|
||||||
/** Block size (for TFTP) */
|
/** Block size (for TFTP) */
|
||||||
size_t blksize;
|
size_t blksize;
|
||||||
/** Overall return status */
|
/** Overall return status */
|
||||||
@@ -354,11 +356,17 @@ static int efi_pxe_tftp_deliver ( struct efi_pxe *pxe,
|
|||||||
/* Deliver to data transfer buffer */
|
/* Deliver to data transfer buffer */
|
||||||
if ( ( rc = xferbuf_deliver ( &pxe->buf, iob_disown ( iobuf ),
|
if ( ( rc = xferbuf_deliver ( &pxe->buf, iob_disown ( iobuf ),
|
||||||
meta ) ) != 0 )
|
meta ) ) != 0 )
|
||||||
goto err_deliver;
|
goto done;
|
||||||
|
|
||||||
|
/* Stop when filesize is known, if applicable */
|
||||||
|
if ( ( pxe->opcode == EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE ) &&
|
||||||
|
( meta->flags & XFER_FL_ABS_OFFSET ) ) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_deliver:
|
done:
|
||||||
efi_pxe_tftp_close ( pxe, rc );
|
efi_pxe_tftp_close ( pxe, rc );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -908,7 +916,8 @@ efi_pxe_mtftp ( EFI_PXE_BASE_CODE_PROTOCOL *base,
|
|||||||
|
|
||||||
/* Fail unless operation is supported */
|
/* Fail unless operation is supported */
|
||||||
if ( ! ( ( opcode == EFI_PXE_BASE_CODE_TFTP_READ_FILE ) ||
|
if ( ! ( ( opcode == EFI_PXE_BASE_CODE_TFTP_READ_FILE ) ||
|
||||||
( opcode == EFI_PXE_BASE_CODE_MTFTP_READ_FILE ) ) ) {
|
( opcode == EFI_PXE_BASE_CODE_MTFTP_READ_FILE ) ||
|
||||||
|
( opcode == EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE ) ) ) {
|
||||||
DBGC ( pxe, "PXE %s unsupported MTFTP opcode %d\n",
|
DBGC ( pxe, "PXE %s unsupported MTFTP opcode %d\n",
|
||||||
pxe->name, opcode );
|
pxe->name, opcode );
|
||||||
rc = -ENOTSUP;
|
rc = -ENOTSUP;
|
||||||
@@ -925,7 +934,12 @@ efi_pxe_mtftp ( EFI_PXE_BASE_CODE_PROTOCOL *base,
|
|||||||
pxe->blksize = ( ( callback && blksize ) ? *blksize : -1UL );
|
pxe->blksize = ( ( callback && blksize ) ? *blksize : -1UL );
|
||||||
|
|
||||||
/* Initialise data transfer buffer */
|
/* Initialise data transfer buffer */
|
||||||
xferbuf_fixed_init ( &pxe->buf, data, *len );
|
memset ( &pxe->buf, 0, sizeof ( pxe->buf ) );
|
||||||
|
if ( opcode == EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE ) {
|
||||||
|
xferbuf_void_init ( &pxe->buf );
|
||||||
|
} else {
|
||||||
|
xferbuf_fixed_init ( &pxe->buf, data, *len );
|
||||||
|
}
|
||||||
|
|
||||||
/* Open download */
|
/* Open download */
|
||||||
if ( ( rc = efi_pxe_tftp_open ( pxe, ip,
|
if ( ( rc = efi_pxe_tftp_open ( pxe, ip,
|
||||||
@@ -933,14 +947,18 @@ efi_pxe_mtftp ( EFI_PXE_BASE_CODE_PROTOCOL *base,
|
|||||||
goto err_open;
|
goto err_open;
|
||||||
|
|
||||||
/* Wait for download to complete */
|
/* Wait for download to complete */
|
||||||
|
pxe->opcode = opcode;
|
||||||
pxe->rc = -EINPROGRESS;
|
pxe->rc = -EINPROGRESS;
|
||||||
while ( pxe->rc == -EINPROGRESS )
|
while ( pxe->rc == -EINPROGRESS )
|
||||||
step();
|
step();
|
||||||
|
*len = pxe->buf.max;
|
||||||
if ( ( rc = pxe->rc ) != 0 ) {
|
if ( ( rc = pxe->rc ) != 0 ) {
|
||||||
DBGC ( pxe, "PXE %s download failed: %s\n",
|
DBGC ( pxe, "PXE %s MTFTP %d failed: %s\n",
|
||||||
pxe->name, strerror ( rc ) );
|
pxe->name, opcode, strerror ( rc ) );
|
||||||
goto err_download;
|
goto err_download;
|
||||||
}
|
}
|
||||||
|
DBGC ( pxe, "PXE %s MTFTP %d %p+%llx complete\n",
|
||||||
|
pxe->name, opcode, data, *len );
|
||||||
|
|
||||||
err_download:
|
err_download:
|
||||||
efi_pxe_tftp_close ( pxe, rc );
|
efi_pxe_tftp_close ( pxe, rc );
|
||||||
|
|||||||
Reference in New Issue
Block a user