|
@@ -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 */
|