You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
2.5 KiB
63 lines
2.5 KiB
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
|
From: Josef Bacik <jbacik@fb.com> |
|
Date: Thu, 6 Aug 2015 10:49:46 -0700 |
|
Subject: [PATCH] efinet: handle get_status() on buggy firmware properly |
|
|
|
The EFI spec indicates that get_status() should return the address of the buffer |
|
we passed into transmit to indicate the the buffer was transmitted. However we |
|
have boxes where the firmware returns some arbitrary address instead, which |
|
makes grub think that we've not sent anything. So since we have the SNP stuff |
|
opened in exclusive mode just assume any non-NULL txbuf means that our transmit |
|
occurred properly. This makes grub able to do its networking stuff properly on |
|
our broken firmware. Thanks, |
|
|
|
cc: Peter Jones <pjones@redhat.com> |
|
Signed-off-by: Josef Bacik <jbacik@fb.com> |
|
--- |
|
grub-core/net/drivers/efi/efinet.c | 21 +++++++++++---------- |
|
1 file changed, 11 insertions(+), 10 deletions(-) |
|
|
|
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c |
|
index 7b8c4a59d10..ea0e0ca360e 100644 |
|
--- a/grub-core/net/drivers/efi/efinet.c |
|
+++ b/grub-core/net/drivers/efi/efinet.c |
|
@@ -47,19 +47,19 @@ send_card_buffer (struct grub_net_card *dev, |
|
if (st != GRUB_EFI_SUCCESS) |
|
return grub_error (GRUB_ERR_IO, |
|
N_("couldn't send network packet")); |
|
- if (txbuf == dev->txbuf) |
|
+ /* |
|
+ Some buggy firmware could return an arbitrary address instead of the |
|
+ txbuf address we trasmitted, so just check that txbuf is non NULL |
|
+ for success. This is ok because we open the SNP protocol in |
|
+ exclusive mode so we know we're the only ones transmitting on this |
|
+ box and since we only transmit one packet at a time we know our |
|
+ transmit was successfull. |
|
+ */ |
|
+ if (txbuf) |
|
{ |
|
dev->txbusy = 0; |
|
break; |
|
} |
|
- if (txbuf) |
|
- { |
|
- st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size, |
|
- dev->txbuf, NULL, NULL, NULL); |
|
- if (st != GRUB_EFI_SUCCESS) |
|
- return grub_error (GRUB_ERR_IO, |
|
- N_("couldn't send network packet")); |
|
- } |
|
if (limit_time < grub_get_time_ms ()) |
|
return grub_error (GRUB_ERR_TIMEOUT, |
|
N_("couldn't send network packet")); |
|
@@ -84,8 +84,9 @@ send_card_buffer (struct grub_net_card *dev, |
|
we run in the GRUB_ERR_TIMEOUT case above. |
|
Perhaps a timeout in the FW has discarded the recycle buffer. |
|
*/ |
|
+ txbuf = NULL; |
|
st = efi_call_3 (net->get_status, net, 0, &txbuf); |
|
- dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf); |
|
+ dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf); |
|
|
|
return GRUB_ERR_NONE; |
|
}
|
|
|