aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2013-11-27 16:48:55 -0500
committerGene Cumm <gene.cumm@gmail.com>2014-01-29 11:55:14 -0500
commit5bf9bdcf0b2e3b4b9161c55713d8004ce6924900 (patch)
tree3eb0dcf215a128573568a4c369ae9dccaa109d20
parent1264f6ac132e9b399bfb846358ae1f055a42c23a (diff)
downloadsyslinux-5bf9bdcf0b2e3b4b9161c55713d8004ce6924900.tar.gz
syslinux-5bf9bdcf0b2e3b4b9161c55713d8004ce6924900.tar.xz
syslinux-5bf9bdcf0b2e3b4b9161c55713d8004ce6924900.zip
efi: Loop on Configure when EFI_NO_MAPPING in udp.c/tcp.c
This should help hardware that doesn't return EFI_SUCCESS immediately. Reported-by: Jason Matthews <jason.david.matthews@gmail.com> Signed-off-by: Gene Cumm <gene.cumm@gmail.com>
-rw-r--r--efi/efi.h5
-rw-r--r--efi/tcp.c19
-rw-r--r--efi/udp.c46
3 files changed, 62 insertions, 8 deletions
diff --git a/efi/efi.h b/efi/efi.h
index 9e4a4432..ef5bacb3 100644
--- a/efi/efi.h
+++ b/efi/efi.h
@@ -24,6 +24,11 @@
#include <efilib.h>
#include <efistdarg.h>
+/* Delay for 100 ms */
+#define EFI_NOMAP_PRINT_DELAY 100
+/* We should keep EFI_NOMAP_PRINT_COUNT at 10 to limit flooding the console */
+#define EFI_NOMAP_PRINT_COUNT 10
+
struct efi_disk_private {
EFI_HANDLE dev_handle;
EFI_BLOCK_IO *bio;
diff --git a/efi/tcp.c b/efi/tcp.c
index 274456d0..f4dfc7e8 100644
--- a/efi/tcp.c
+++ b/efi/tcp.c
@@ -52,6 +52,8 @@ int core_tcp_connect(struct pxe_pvt_inode *socket, uint32_t ip, uint16_t port)
EFI_STATUS status;
EFI_TCP4 *tcp = (EFI_TCP4 *)b->this;
int rv = -1;
+ int unmapped = 1;
+ jiffies_t start, last, cur;
memset(&tdata, 0, sizeof(tdata));
@@ -63,7 +65,22 @@ int core_tcp_connect(struct pxe_pvt_inode *socket, uint32_t ip, uint16_t port)
tdata.TimeToLive = 64;
- status = uefi_call_wrapper(tcp->Configure, 2, tcp, &tdata);
+ last = start = jiffies();
+ while (unmapped){
+ status = uefi_call_wrapper(tcp->Configure, 2, tcp, &tdata);
+ if (status != EFI_NO_MAPPING)
+ unmapped = 0;
+ else {
+ cur = jiffies();
+ if ( (cur - last) >= EFI_NOMAP_PRINT_DELAY ) {
+ last = cur;
+ Print(L"core_tcp_connect: stalling on configure with no mapping\n");
+ } else if ( (cur - start) > EFI_NOMAP_PRINT_DELAY * EFI_NOMAP_PRINT_COUNT) {
+ Print(L"core_tcp_connect: aborting on no mapping\n");
+ unmapped = 0;
+ }
+ }
+ }
if (status != EFI_SUCCESS)
return -1;
diff --git a/efi/udp.c b/efi/udp.c
index 744ff0f6..30a8c777 100644
--- a/efi/udp.c
+++ b/efi/udp.c
@@ -14,6 +14,42 @@ extern EFI_GUID Udp4ServiceBindingProtocol, Udp4Protocol;
*/
static struct efi_binding *udp_reader;
+/**
+ * Try to configure this UDP socket
+ *
+ * @param:udp, the EFI_UDP4 socket to configure
+ * @param:udata, the EFI_UDP4_CONFIG_DATA to use
+ * @param:f, the name of the function as a wide string.
+ *
+ * @out: status as EFI_STATUS
+ */
+
+EFI_STATUS core_udp_configure(EFI_UDP4 *udp, EFI_UDP4_CONFIG_DATA *udata,
+ short unsigned int *f)
+{
+ EFI_STATUS status;
+ int unmapped = 1;
+ jiffies_t start, last, cur;
+
+ last = start = jiffies();
+ while (unmapped){
+ status = uefi_call_wrapper(udp->Configure, 2, udp, udata);
+ if (status != EFI_NO_MAPPING)
+ unmapped = 0;
+ else {
+ cur = jiffies();
+ if ( (cur - last) >= EFI_NOMAP_PRINT_DELAY ) {
+ last = cur;
+ Print(L"%s: stalling on configure with no mapping\n", f);
+ } else if ( (cur - start) > EFI_NOMAP_PRINT_DELAY * EFI_NOMAP_PRINT_COUNT) {
+ Print(L"%s: aborting on no mapping\n", f);
+ unmapped = 0;
+ }
+ }
+ }
+ return status;
+}
+
/**
* Open a socket
*
@@ -42,7 +78,7 @@ int core_udp_open(struct pxe_pvt_inode *socket)
memset(&udata, 0, sizeof(udata));
- status = uefi_call_wrapper(udp->Configure, 2, udp, &udata);
+ status = core_udp_configure(udp, &udata, L"core_udp_open");
if (status != EFI_SUCCESS)
goto bail;
@@ -116,7 +152,7 @@ void core_udp_connect(struct pxe_pvt_inode *socket, uint32_t ip,
udata.AcceptPromiscuous = TRUE;
udata.TimeToLive = 64;
- status = uefi_call_wrapper(udp->Configure, 2, udp, &udata);
+ status = core_udp_configure(udp, &udata, L"core_udp_connect");
if (status != EFI_SUCCESS) {
Print(L"Failed to configure UDP: %d\n", status);
return;
@@ -263,8 +299,6 @@ void core_udp_send(struct pxe_pvt_inode *socket, const void *data, size_t len)
if (status != EFI_SUCCESS)
goto bail;
- txdata->UdpSessionData = NULL;
- txdata->GatewayAddress = NULL;
txdata->DataLength = len;
txdata->FragmentCount = 1;
frag = &txdata->FragmentTable[0];
@@ -339,7 +373,7 @@ void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data,
udata.AcceptPromiscuous = TRUE;
udata.TimeToLive = 64;
- status = uefi_call_wrapper(udp->Configure, 2, udp, &udata);
+ status = core_udp_configure(udp, &udata, L"core_udp_sendto");
if (status != EFI_SUCCESS)
goto bail;
@@ -348,8 +382,6 @@ void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data,
if (status != EFI_SUCCESS)
goto bail;
- txdata->UdpSessionData = NULL;
- txdata->GatewayAddress = NULL;
txdata->DataLength = len;
txdata->FragmentCount = 1;
frag = &txdata->FragmentTable[0];