Browse Source

[efi] Raise TPL within EFI_SIMPLE_NETWORK_PROTOCOL entry points

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
a272b7ce57
1 changed files with 81 additions and 12 deletions
  1. 81
    12
      src/interface/efi/efi_snp.c

+ 81
- 12
src/interface/efi/efi_snp.c View File

@@ -233,8 +233,10 @@ efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
233 233
 static EFI_STATUS EFIAPI
234 234
 efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
235 235
 		     UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
236
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
236 237
 	struct efi_snp_device *snpdev =
237 238
 		container_of ( snp, struct efi_snp_device, snp );
239
+	EFI_TPL saved_tpl;
238 240
 	int rc;
239 241
 
240 242
 	DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
@@ -242,17 +244,26 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
242 244
 	       ( ( unsigned long ) extra_tx_bufsize ) );
243 245
 
244 246
 	/* Fail if net device is currently claimed for use by iPXE */
245
-	if ( efi_snp_claimed )
246
-		return EFI_NOT_READY;
247
+	if ( efi_snp_claimed ) {
248
+		rc = -EAGAIN;
249
+		goto err_claimed;
250
+	}
247 251
 
252
+	/* Raise TPL */
253
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
254
+
255
+	/* Open network device */
248 256
 	if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
249 257
 		DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
250 258
 		       snpdev, snpdev->netdev->name, strerror ( rc ) );
251
-		return EFIRC ( rc );
259
+		goto err_open;
252 260
 	}
253 261
 	efi_snp_set_state ( snpdev );
254 262
 
255
-	return 0;
263
+ err_open:
264
+	bs->RestoreTPL ( saved_tpl );
265
+ err_claimed:
266
+	return EFIRC ( rc );
256 267
 }
257 268
 
258 269
 /**
@@ -264,29 +275,41 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
264 275
  */
265 276
 static EFI_STATUS EFIAPI
266 277
 efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
278
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
267 279
 	struct efi_snp_device *snpdev =
268 280
 		container_of ( snp, struct efi_snp_device, snp );
281
+	EFI_TPL saved_tpl;
269 282
 	int rc;
270 283
 
271 284
 	DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
272 285
 	       snpdev, ( ext_verify ? "with" : "without" ) );
273 286
 
274 287
 	/* Fail if net device is currently claimed for use by iPXE */
275
-	if ( efi_snp_claimed )
276
-		return EFI_NOT_READY;
288
+	if ( efi_snp_claimed ) {
289
+		rc = -EAGAIN;
290
+		goto err_claimed;
291
+	}
292
+
293
+	/* Raise TPL */
294
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
277 295
 
296
+	/* Close network device */
278 297
 	netdev_close ( snpdev->netdev );
279 298
 	efi_snp_set_state ( snpdev );
280 299
 	efi_snp_flush ( snpdev );
281 300
 
301
+	/* Reopen network device */
282 302
 	if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
283 303
 		DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
284 304
 		       snpdev, snpdev->netdev->name, strerror ( rc ) );
285
-		return EFIRC ( rc );
305
+		goto err_open;
286 306
 	}
287 307
 	efi_snp_set_state ( snpdev );
288 308
 
289
-	return 0;
309
+ err_open:
310
+	bs->RestoreTPL ( saved_tpl );
311
+ err_claimed:
312
+	return EFIRC ( rc );
290 313
 }
291 314
 
292 315
 /**
@@ -297,8 +320,10 @@ efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
297 320
  */
298 321
 static EFI_STATUS EFIAPI
299 322
 efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
323
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
300 324
 	struct efi_snp_device *snpdev =
301 325
 		container_of ( snp, struct efi_snp_device, snp );
326
+	EFI_TPL saved_tpl;
302 327
 
303 328
 	DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
304 329
 
@@ -306,10 +331,17 @@ efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
306 331
 	if ( efi_snp_claimed )
307 332
 		return EFI_NOT_READY;
308 333
 
334
+	/* Raise TPL */
335
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
336
+
337
+	/* Close network device */
309 338
 	netdev_close ( snpdev->netdev );
310 339
 	efi_snp_set_state ( snpdev );
311 340
 	efi_snp_flush ( snpdev );
312 341
 
342
+	/* Restore TPL */
343
+	bs->RestoreTPL ( saved_tpl );
344
+
313 345
 	return 0;
314 346
 }
315 347
 
@@ -512,8 +544,10 @@ efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
512 544
 static EFI_STATUS EFIAPI
513 545
 efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
514 546
 		     UINT32 *interrupts, VOID **txbuf ) {
547
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
515 548
 	struct efi_snp_device *snpdev =
516 549
 		container_of ( snp, struct efi_snp_device, snp );
550
+	EFI_TPL saved_tpl;
517 551
 
518 552
 	DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
519 553
 
@@ -523,6 +557,9 @@ efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
523 557
 		return EFI_NOT_READY;
524 558
 	}
525 559
 
560
+	/* Raise TPL */
561
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
562
+
526 563
 	/* Poll the network device */
527 564
 	efi_snp_poll ( snpdev );
528 565
 
@@ -545,6 +582,9 @@ efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
545 582
 		DBGC2 ( snpdev, " TX:%p", *txbuf );
546 583
 	}
547 584
 
585
+	/* Restore TPL */
586
+	bs->RestoreTPL ( saved_tpl );
587
+
548 588
 	DBGC2 ( snpdev, "\n" );
549 589
 	return 0;
550 590
 }
@@ -566,12 +606,14 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
566 606
 		   UINTN ll_header_len, UINTN len, VOID *data,
567 607
 		   EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
568 608
 		   UINT16 *net_proto ) {
609
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
569 610
 	struct efi_snp_device *snpdev =
570 611
 		container_of ( snp, struct efi_snp_device, snp );
571 612
 	struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
572 613
 	struct io_buffer *iobuf;
573 614
 	size_t payload_len;
574 615
 	unsigned int tx_fill;
616
+	EFI_TPL saved_tpl;
575 617
 	int rc;
576 618
 
577 619
 	DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
@@ -592,8 +634,13 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
592 634
 	DBGC2 ( snpdev, "\n" );
593 635
 
594 636
 	/* Fail if net device is currently claimed for use by iPXE */
595
-	if ( efi_snp_claimed )
596
-		return EFI_NOT_READY;
637
+	if ( efi_snp_claimed ) {
638
+		rc = -EAGAIN;
639
+		goto err_claimed;
640
+	}
641
+
642
+	/* Raise TPL */
643
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
597 644
 
598 645
 	/* Sanity checks */
599 646
 	if ( ll_header_len ) {
@@ -677,6 +724,9 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
677 724
 	snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
678 725
 	snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
679 726
 
727
+	/* Restore TPL */
728
+	bs->RestoreTPL ( saved_tpl );
729
+
680 730
 	return 0;
681 731
 
682 732
  err_ring_full:
@@ -685,6 +735,8 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
685 735
 	free_iob ( iobuf );
686 736
  err_alloc_iob:
687 737
  err_sanity:
738
+	bs->RestoreTPL ( saved_tpl );
739
+ err_claimed:
688 740
 	return EFIRC ( rc );
689 741
 }
690 742
 
@@ -705,6 +757,7 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
705 757
 		  UINTN *ll_header_len, UINTN *len, VOID *data,
706 758
 		  EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
707 759
 		  UINT16 *net_proto ) {
760
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
708 761
 	struct efi_snp_device *snpdev =
709 762
 		container_of ( snp, struct efi_snp_device, snp );
710 763
 	struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
@@ -714,14 +767,20 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
714 767
 	uint16_t iob_net_proto;
715 768
 	unsigned int iob_flags;
716 769
 	size_t copy_len;
770
+	EFI_TPL saved_tpl;
717 771
 	int rc;
718 772
 
719 773
 	DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
720 774
 		( ( unsigned long ) *len ) );
721 775
 
722 776
 	/* Fail if net device is currently claimed for use by iPXE */
723
-	if ( efi_snp_claimed )
724
-		return EFI_NOT_READY;
777
+	if ( efi_snp_claimed ) {
778
+		rc = -EAGAIN;
779
+		goto err_claimed;
780
+	}
781
+
782
+	/* Raise TPL */
783
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
725 784
 
726 785
 	/* Poll the network device */
727 786
 	efi_snp_poll ( snpdev );
@@ -770,6 +829,8 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
770 829
  out_bad_ll_header:
771 830
 	free_iob ( iobuf );
772 831
  out_no_packet:
832
+	bs->RestoreTPL ( saved_tpl );
833
+ err_claimed:
773 834
 	return EFIRC ( rc );
774 835
 }
775 836
 
@@ -781,7 +842,9 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
781 842
  */
782 843
 static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
783 844
 					     VOID *context ) {
845
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
784 846
 	struct efi_snp_device *snpdev = context;
847
+	EFI_TPL saved_tpl;
785 848
 
786 849
 	DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
787 850
 
@@ -793,8 +856,14 @@ static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
793 856
 	if ( efi_snp_claimed )
794 857
 		return;
795 858
 
859
+	/* Raise TPL */
860
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
861
+
796 862
 	/* Poll the network device */
797 863
 	efi_snp_poll ( snpdev );
864
+
865
+	/* Restore TPL */
866
+	bs->RestoreTPL ( saved_tpl );
798 867
 }
799 868
 
800 869
 /** SNP interface */

Loading…
Cancel
Save