summaryrefslogtreecommitdiffstats
path: root/sys/boot/efi/libefi
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-03-29 23:10:15 +0000
committermarcel <marcel@FreeBSD.org>2002-03-29 23:10:15 +0000
commitfa19ce884443dfe0d2d7c96eacffb976590b2dbb (patch)
treef0c9e5f305733f9762565d7050fc5568aa6953b8 /sys/boot/efi/libefi
parent080662695bfe38eb9a8349d05bd9147260be43f1 (diff)
downloadFreeBSD-src-fa19ce884443dfe0d2d7c96eacffb976590b2dbb.zip
FreeBSD-src-fa19ce884443dfe0d2d7c96eacffb976590b2dbb.tar.gz
o Make efinet_put a blocking call by waiting for the protocol
layer to signal transmission of the packet. This resolves the problem I'm seeing that an immediate call to net->Receive after calling net->Transmit returns EFI_DEVICE_ERROR. This condition seems to be sufficiently persistent that BOOTP and RARP fail. o While here, unify all functions to have 'nif' defined. Some have it as arguments. The others now have them as locals. We now always get the protocol interface by using the 'nif' var. The current status of netbooting is that even though we now reliably have BOOTP working (again), opening a file (ie loading a kernel) across the network causes the loader to hang. I'm working on that now.
Diffstat (limited to 'sys/boot/efi/libefi')
-rw-r--r--sys/boot/efi/libefi/efinet.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c
index d729981..0b27fc7 100644
--- a/sys/boot/efi/libefi/efinet.c
+++ b/sys/boot/efi/libefi/efinet.c
@@ -56,26 +56,39 @@ efinet_probe(struct netif *nif, void *machdep_hint)
int
efinet_put(struct iodesc *desc, void *pkt, size_t len)
{
- EFI_SIMPLE_NETWORK *net = desc->io_netif->nif_devdata;
+ struct netif *nif = desc->io_netif;
+ EFI_SIMPLE_NETWORK *net;
EFI_STATUS status;
- int i;
+ void *buf;
+
+ net = nif->nif_devdata;
status = net->Transmit(net, 0, len, pkt, 0, 0, 0);
- if (!EFI_ERROR(status))
- return len;
- else
+ if (status != EFI_SUCCESS)
return -1;
+
+ /* Wait for the buffer to be transmitted */
+ buf = 0; /* XXX Is this needed? */
+ do {
+ status = net->GetStatus(net, 0, &buf);
+ } while (status == EFI_SUCCESS && buf != pkt);
+
+ /* XXX How do we deal with status != EFI_SUCCESS now? */
+ return (status == EFI_SUCCESS) ? len : -1;
}
int
efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
- EFI_SIMPLE_NETWORK *net = desc->io_netif->nif_devdata;
+ struct netif *nif = desc->io_netif;
+ EFI_SIMPLE_NETWORK *net;
EFI_STATUS status;
UINTN bufsz;
time_t t;
+ net = nif->nif_devdata;
+
t = time(0);
while ((time(0) - t) < timeout) {
bufsz = len;
@@ -92,13 +105,11 @@ efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
void
efinet_init(struct iodesc *desc, void *machdep_hint)
{
- struct netif *nif;
- EFI_SIMPLE_NETWORK *net;
- int i;
+ struct netif *nif = desc->io_netif;
+ EFI_SIMPLE_NETWORK *net;
- nif = desc->io_netif;
net = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private;
- desc->io_netif->nif_devdata = net;
+ nif->nif_devdata = net;
net->Start(net);
net->Initialize(net, 0, 0);
@@ -145,7 +156,6 @@ efinet_init_driver()
dif->dif_unit = i;
dif->dif_nsel = 1;
dif->dif_stats = &stats[i];
- dif->dif_private = handles[i];
BS->HandleProtocol(handles[i], &netid,
(VOID**) &dif->dif_private);
OpenPOWER on IntegriCloud