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.
This commit is contained in:
parent
296c758b66
commit
914ecdc8ea
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user