From 646415b0770c04e6e38399129a24815e0e4175f7 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 20 Jul 2002 03:51:53 +0000 Subject: [PATCH] Work around some nasty bugs on the [beta] Itanium2's E1000 UNDI driver. Bug#1: The GetStatus() function returns radically different pointers that do not match any packets we transmitted. I think it might be pointing to a copy of the packet or something. Since we do not transmit more than one packet at a time, just wait for "anything". Bug#2: The Receive() function takes a pointer and a length. However, it either ignores the length or otherwise does bad things and writes outside of ptr[0] through ptr[len-1]. This is bad and causes massive stack corruption for us since we are receiving packets into small buffers on the stack. Instead, Receive() into a large enough buffer and bcopy the data to the requested area. --- sys/boot/efi/libefi/efinet.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c index 10b172181681..f2a6ac40a88a 100644 --- a/sys/boot/efi/libefi/efinet.c +++ b/sys/boot/efi/libefi/efinet.c @@ -102,10 +102,14 @@ efinet_put(struct iodesc *desc, void *pkt, size_t len) return -1; /* Wait for the buffer to be transmitted */ - buf = 0; /* XXX Is this needed? */ do { + buf = 0; /* XXX Is this needed? */ status = net->GetStatus(net, 0, &buf); - } while (status == EFI_SUCCESS && buf != pkt); + /* + * XXX EFI1.1 and the E1000 card returns a different + * address than we gave. Sigh. + */ + } while (status == EFI_SUCCESS && buf == 0); /* XXX How do we deal with status != EFI_SUCCESS now? */ return (status == EFI_SUCCESS) ? len : -1; @@ -120,15 +124,26 @@ efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) EFI_STATUS status; UINTN bufsz; time_t t; + char buf[2048]; net = nif->nif_devdata; t = time(0); while ((time(0) - t) < timeout) { - bufsz = len; - status = net->Receive(net, 0, &bufsz, pkt, 0, 0, 0); - if (status == EFI_SUCCESS) + bufsz = sizeof(buf); + status = net->Receive(net, 0, &bufsz, buf, 0, 0, 0); + if (status == EFI_SUCCESS) { + /* + * XXX EFI1.1 and the E1000 card trash our + * workspace if we do not do this silly copy. + * Either they are not respecting the len + * value or do not like the alignment. + */ + if (bufsz > len) + bufsz = len; + bcopy(buf, pkt, bufsz); return bufsz; + } if (status != EFI_NOT_READY) return 0; }