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

Loading…
Cancel
Save