static EFI_STATUS EFIAPI
efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
+ EFI_TPL saved_tpl;
int rc;
DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
( ( unsigned long ) extra_tx_bufsize ) );
/* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
+ if ( efi_snp_claimed ) {
+ rc = -EAGAIN;
+ goto err_claimed;
+ }
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+
+ /* Open network device */
if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
snpdev, snpdev->netdev->name, strerror ( rc ) );
- return EFIRC ( rc );
+ goto err_open;
}
efi_snp_set_state ( snpdev );
- return 0;
+ err_open:
+ bs->RestoreTPL ( saved_tpl );
+ err_claimed:
+ return EFIRC ( rc );
}
/**
*/
static EFI_STATUS EFIAPI
efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
+ EFI_TPL saved_tpl;
int rc;
DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
snpdev, ( ext_verify ? "with" : "without" ) );
/* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
+ if ( efi_snp_claimed ) {
+ rc = -EAGAIN;
+ goto err_claimed;
+ }
+
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ /* Close network device */
netdev_close ( snpdev->netdev );
efi_snp_set_state ( snpdev );
efi_snp_flush ( snpdev );
+ /* Reopen network device */
if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
snpdev, snpdev->netdev->name, strerror ( rc ) );
- return EFIRC ( rc );
+ goto err_open;
}
efi_snp_set_state ( snpdev );
- return 0;
+ err_open:
+ bs->RestoreTPL ( saved_tpl );
+ err_claimed:
+ return EFIRC ( rc );
}
/**
*/
static EFI_STATUS EFIAPI
efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
+ EFI_TPL saved_tpl;
DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
if ( efi_snp_claimed )
return EFI_NOT_READY;
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+
+ /* Close network device */
netdev_close ( snpdev->netdev );
efi_snp_set_state ( snpdev );
efi_snp_flush ( snpdev );
+ /* Restore TPL */
+ bs->RestoreTPL ( saved_tpl );
+
return 0;
}
static EFI_STATUS EFIAPI
efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
UINT32 *interrupts, VOID **txbuf ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
+ EFI_TPL saved_tpl;
DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
return EFI_NOT_READY;
}
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+
/* Poll the network device */
efi_snp_poll ( snpdev );
DBGC2 ( snpdev, " TX:%p", *txbuf );
}
+ /* Restore TPL */
+ bs->RestoreTPL ( saved_tpl );
+
DBGC2 ( snpdev, "\n" );
return 0;
}
UINTN ll_header_len, UINTN len, VOID *data,
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
UINT16 *net_proto ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
struct io_buffer *iobuf;
size_t payload_len;
unsigned int tx_fill;
+ EFI_TPL saved_tpl;
int rc;
DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
DBGC2 ( snpdev, "\n" );
/* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
+ if ( efi_snp_claimed ) {
+ rc = -EAGAIN;
+ goto err_claimed;
+ }
+
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
/* Sanity checks */
if ( ll_header_len ) {
snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
+ /* Restore TPL */
+ bs->RestoreTPL ( saved_tpl );
+
return 0;
err_ring_full:
free_iob ( iobuf );
err_alloc_iob:
err_sanity:
+ bs->RestoreTPL ( saved_tpl );
+ err_claimed:
return EFIRC ( rc );
}
UINTN *ll_header_len, UINTN *len, VOID *data,
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
UINT16 *net_proto ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
uint16_t iob_net_proto;
unsigned int iob_flags;
size_t copy_len;
+ EFI_TPL saved_tpl;
int rc;
DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
( ( unsigned long ) *len ) );
/* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
+ if ( efi_snp_claimed ) {
+ rc = -EAGAIN;
+ goto err_claimed;
+ }
+
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
/* Poll the network device */
efi_snp_poll ( snpdev );
out_bad_ll_header:
free_iob ( iobuf );
out_no_packet:
+ bs->RestoreTPL ( saved_tpl );
+ err_claimed:
return EFIRC ( rc );
}
*/
static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
VOID *context ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev = context;
+ EFI_TPL saved_tpl;
DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
if ( efi_snp_claimed )
return;
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+
/* Poll the network device */
efi_snp_poll ( snpdev );
+
+ /* Restore TPL */
+ bs->RestoreTPL ( saved_tpl );
}
/** SNP interface */