mirror of https://github.com/ipxe/ipxe.git
[efi] Raise TPL within EFI_SIMPLE_NETWORK_PROTOCOL entry points
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/68/merge
parent
c89a446cf0
commit
a272b7ce57
|
@ -233,8 +233,10 @@ efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
|
||||||
static EFI_STATUS EFIAPI
|
static EFI_STATUS EFIAPI
|
||||||
efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
|
UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_snp_device *snpdev =
|
struct efi_snp_device *snpdev =
|
||||||
container_of ( snp, struct efi_snp_device, snp );
|
container_of ( snp, struct efi_snp_device, snp );
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
|
DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
|
||||||
|
@ -242,17 +244,26 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
( ( unsigned long ) extra_tx_bufsize ) );
|
( ( unsigned long ) extra_tx_bufsize ) );
|
||||||
|
|
||||||
/* Fail if net device is currently claimed for use by iPXE */
|
/* Fail if net device is currently claimed for use by iPXE */
|
||||||
if ( efi_snp_claimed )
|
if ( efi_snp_claimed ) {
|
||||||
return EFI_NOT_READY;
|
rc = -EAGAIN;
|
||||||
|
goto err_claimed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
|
/* Open network device */
|
||||||
if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
|
if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
|
||||||
DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
|
DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
|
||||||
snpdev, snpdev->netdev->name, strerror ( rc ) );
|
snpdev, snpdev->netdev->name, strerror ( rc ) );
|
||||||
return EFIRC ( rc );
|
goto err_open;
|
||||||
}
|
}
|
||||||
efi_snp_set_state ( snpdev );
|
efi_snp_set_state ( snpdev );
|
||||||
|
|
||||||
return 0;
|
err_open:
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
|
err_claimed:
|
||||||
|
return EFIRC ( rc );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -264,29 +275,41 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
*/
|
*/
|
||||||
static EFI_STATUS EFIAPI
|
static EFI_STATUS EFIAPI
|
||||||
efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
|
efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_snp_device *snpdev =
|
struct efi_snp_device *snpdev =
|
||||||
container_of ( snp, struct efi_snp_device, snp );
|
container_of ( snp, struct efi_snp_device, snp );
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
|
DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
|
||||||
snpdev, ( ext_verify ? "with" : "without" ) );
|
snpdev, ( ext_verify ? "with" : "without" ) );
|
||||||
|
|
||||||
/* Fail if net device is currently claimed for use by iPXE */
|
/* Fail if net device is currently claimed for use by iPXE */
|
||||||
if ( efi_snp_claimed )
|
if ( efi_snp_claimed ) {
|
||||||
return EFI_NOT_READY;
|
rc = -EAGAIN;
|
||||||
|
goto err_claimed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
|
/* Close network device */
|
||||||
netdev_close ( snpdev->netdev );
|
netdev_close ( snpdev->netdev );
|
||||||
efi_snp_set_state ( snpdev );
|
efi_snp_set_state ( snpdev );
|
||||||
efi_snp_flush ( snpdev );
|
efi_snp_flush ( snpdev );
|
||||||
|
|
||||||
|
/* Reopen network device */
|
||||||
if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
|
if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
|
||||||
DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
|
DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
|
||||||
snpdev, snpdev->netdev->name, strerror ( rc ) );
|
snpdev, snpdev->netdev->name, strerror ( rc ) );
|
||||||
return EFIRC ( rc );
|
goto err_open;
|
||||||
}
|
}
|
||||||
efi_snp_set_state ( snpdev );
|
efi_snp_set_state ( snpdev );
|
||||||
|
|
||||||
return 0;
|
err_open:
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
|
err_claimed:
|
||||||
|
return EFIRC ( rc );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -297,8 +320,10 @@ efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
|
||||||
*/
|
*/
|
||||||
static EFI_STATUS EFIAPI
|
static EFI_STATUS EFIAPI
|
||||||
efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
|
efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_snp_device *snpdev =
|
struct efi_snp_device *snpdev =
|
||||||
container_of ( snp, struct efi_snp_device, snp );
|
container_of ( snp, struct efi_snp_device, snp );
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
|
|
||||||
DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
|
DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
|
||||||
|
|
||||||
|
@ -306,10 +331,17 @@ efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
|
||||||
if ( efi_snp_claimed )
|
if ( efi_snp_claimed )
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
|
/* Close network device */
|
||||||
netdev_close ( snpdev->netdev );
|
netdev_close ( snpdev->netdev );
|
||||||
efi_snp_set_state ( snpdev );
|
efi_snp_set_state ( snpdev );
|
||||||
efi_snp_flush ( snpdev );
|
efi_snp_flush ( snpdev );
|
||||||
|
|
||||||
|
/* Restore TPL */
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,8 +544,10 @@ efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
|
||||||
static EFI_STATUS EFIAPI
|
static EFI_STATUS EFIAPI
|
||||||
efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
UINT32 *interrupts, VOID **txbuf ) {
|
UINT32 *interrupts, VOID **txbuf ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_snp_device *snpdev =
|
struct efi_snp_device *snpdev =
|
||||||
container_of ( snp, struct efi_snp_device, snp );
|
container_of ( snp, struct efi_snp_device, snp );
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
|
|
||||||
DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
|
DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
|
||||||
|
|
||||||
|
@ -523,6 +557,9 @@ efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
/* Poll the network device */
|
/* Poll the network device */
|
||||||
efi_snp_poll ( snpdev );
|
efi_snp_poll ( snpdev );
|
||||||
|
|
||||||
|
@ -545,6 +582,9 @@ efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
DBGC2 ( snpdev, " TX:%p", *txbuf );
|
DBGC2 ( snpdev, " TX:%p", *txbuf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore TPL */
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
|
|
||||||
DBGC2 ( snpdev, "\n" );
|
DBGC2 ( snpdev, "\n" );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -566,12 +606,14 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
UINTN ll_header_len, UINTN len, VOID *data,
|
UINTN ll_header_len, UINTN len, VOID *data,
|
||||||
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
|
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
|
||||||
UINT16 *net_proto ) {
|
UINT16 *net_proto ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_snp_device *snpdev =
|
struct efi_snp_device *snpdev =
|
||||||
container_of ( snp, struct efi_snp_device, snp );
|
container_of ( snp, struct efi_snp_device, snp );
|
||||||
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
|
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
|
||||||
struct io_buffer *iobuf;
|
struct io_buffer *iobuf;
|
||||||
size_t payload_len;
|
size_t payload_len;
|
||||||
unsigned int tx_fill;
|
unsigned int tx_fill;
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
|
DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
|
||||||
|
@ -592,8 +634,13 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
DBGC2 ( snpdev, "\n" );
|
DBGC2 ( snpdev, "\n" );
|
||||||
|
|
||||||
/* Fail if net device is currently claimed for use by iPXE */
|
/* Fail if net device is currently claimed for use by iPXE */
|
||||||
if ( efi_snp_claimed )
|
if ( efi_snp_claimed ) {
|
||||||
return EFI_NOT_READY;
|
rc = -EAGAIN;
|
||||||
|
goto err_claimed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
if ( ll_header_len ) {
|
if ( ll_header_len ) {
|
||||||
|
@ -677,6 +724,9 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
|
snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
|
||||||
snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
|
snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
|
||||||
|
|
||||||
|
/* Restore TPL */
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_ring_full:
|
err_ring_full:
|
||||||
|
@ -685,6 +735,8 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
free_iob ( iobuf );
|
free_iob ( iobuf );
|
||||||
err_alloc_iob:
|
err_alloc_iob:
|
||||||
err_sanity:
|
err_sanity:
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
|
err_claimed:
|
||||||
return EFIRC ( rc );
|
return EFIRC ( rc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,6 +757,7 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
UINTN *ll_header_len, UINTN *len, VOID *data,
|
UINTN *ll_header_len, UINTN *len, VOID *data,
|
||||||
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
|
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
|
||||||
UINT16 *net_proto ) {
|
UINT16 *net_proto ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_snp_device *snpdev =
|
struct efi_snp_device *snpdev =
|
||||||
container_of ( snp, struct efi_snp_device, snp );
|
container_of ( snp, struct efi_snp_device, snp );
|
||||||
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
|
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
|
||||||
|
@ -714,14 +767,20 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
uint16_t iob_net_proto;
|
uint16_t iob_net_proto;
|
||||||
unsigned int iob_flags;
|
unsigned int iob_flags;
|
||||||
size_t copy_len;
|
size_t copy_len;
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
|
DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
|
||||||
( ( unsigned long ) *len ) );
|
( ( unsigned long ) *len ) );
|
||||||
|
|
||||||
/* Fail if net device is currently claimed for use by iPXE */
|
/* Fail if net device is currently claimed for use by iPXE */
|
||||||
if ( efi_snp_claimed )
|
if ( efi_snp_claimed ) {
|
||||||
return EFI_NOT_READY;
|
rc = -EAGAIN;
|
||||||
|
goto err_claimed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
/* Poll the network device */
|
/* Poll the network device */
|
||||||
efi_snp_poll ( snpdev );
|
efi_snp_poll ( snpdev );
|
||||||
|
@ -770,6 +829,8 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
out_bad_ll_header:
|
out_bad_ll_header:
|
||||||
free_iob ( iobuf );
|
free_iob ( iobuf );
|
||||||
out_no_packet:
|
out_no_packet:
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
|
err_claimed:
|
||||||
return EFIRC ( rc );
|
return EFIRC ( rc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +842,9 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
*/
|
*/
|
||||||
static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
|
static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
|
||||||
VOID *context ) {
|
VOID *context ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_snp_device *snpdev = context;
|
struct efi_snp_device *snpdev = context;
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
|
|
||||||
DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
|
DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
|
||||||
|
|
||||||
|
@ -793,8 +856,14 @@ static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
|
||||||
if ( efi_snp_claimed )
|
if ( efi_snp_claimed )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
/* Poll the network device */
|
/* Poll the network device */
|
||||||
efi_snp_poll ( snpdev );
|
efi_snp_poll ( snpdev );
|
||||||
|
|
||||||
|
/* Restore TPL */
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** SNP interface */
|
/** SNP interface */
|
||||||
|
|
Loading…
Reference in New Issue