summaryrefslogtreecommitdiffstats
path: root/sys/boot/efi/libefi/efinet.c
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2006-11-05 22:03:04 +0000
committermarcel <marcel@FreeBSD.org>2006-11-05 22:03:04 +0000
commit9ef7e5e3afc0c9daef60848d3b4b44df597298c1 (patch)
tree36bde112cc1780aa7082179e805aad052645807b /sys/boot/efi/libefi/efinet.c
parenta74874add4b6735fe168a33b970b50a6e9d6024a (diff)
downloadFreeBSD-src-9ef7e5e3afc0c9daef60848d3b4b44df597298c1.zip
FreeBSD-src-9ef7e5e3afc0c9daef60848d3b4b44df597298c1.tar.gz
Major rework of the ia64 loaders. The two primary objectives are:
1. Make libefi portable by removing ia64 specific code and build it on i386 and amd64 by default to prevent regressions. These changes include fixes and improvements over previous code to establish or improve APIs where none existed or when the amount of kluging was unacceptably high. 2. Increase the amount of sharing between the efi and ski loaders to improve maintainability of the loaders and simplify making changes to the loader-kernel handshaking in the future. The version of the efi and ski loaders are now both changed to 1.2 as user visible improvements and changes have been made.
Diffstat (limited to 'sys/boot/efi/libefi/efinet.c')
-rw-r--r--sys/boot/efi/libefi/efinet.c171
1 files changed, 106 insertions, 65 deletions
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c
index c6fc523..1eea860 100644
--- a/sys/boot/efi/libefi/efinet.c
+++ b/sys/boot/efi/libefi/efinet.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2001 Doug Rabson
+ * Copyright (c) 2002, 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,10 +36,31 @@ __FBSDID("$FreeBSD$");
#include <net.h>
#include <netif.h>
+#include <dev_net.c>
+
#include <efi.h>
#include <efilib.h>
-extern struct netif_driver efi_net;
+static EFI_GUID sn_guid = EFI_SIMPLE_NETWORK_PROTOCOL;
+
+static void efinet_end(struct netif *);
+static int efinet_get(struct iodesc *, void *, size_t, time_t);
+static void efinet_init(struct iodesc *, void *);
+static int efinet_match(struct netif *, void *);
+static int efinet_probe(struct netif *, void *);
+static int efinet_put(struct iodesc *, void *, size_t);
+
+struct netif_driver efinetif = {
+ .netif_bname = "efinet",
+ .netif_match = efinet_match,
+ .netif_probe = efinet_probe,
+ .netif_init = efinet_init,
+ .netif_get = efinet_get,
+ .netif_put = efinet_put,
+ .netif_end = efinet_end,
+ .netif_ifs = NULL,
+ .netif_nifs = 0
+};
#ifdef EFINET_DEBUG
static void
@@ -74,21 +96,21 @@ dump_mode(EFI_SIMPLE_NETWORK_MODE *mode)
}
#endif
-int
+static int
efinet_match(struct netif *nif, void *machdep_hint)
{
return (1);
}
-int
+static int
efinet_probe(struct netif *nif, void *machdep_hint)
{
return (0);
}
-int
+static int
efinet_put(struct iodesc *desc, void *pkt, size_t len)
{
struct netif *nif = desc->io_netif;
@@ -100,7 +122,7 @@ efinet_put(struct iodesc *desc, void *pkt, size_t len)
status = net->Transmit(net, 0, len, pkt, 0, 0, 0);
if (status != EFI_SUCCESS)
- return -1;
+ return (-1);
/* Wait for the buffer to be transmitted */
do {
@@ -113,11 +135,10 @@ efinet_put(struct iodesc *desc, void *pkt, size_t len)
} while (status == EFI_SUCCESS && buf == 0);
/* XXX How do we deal with status != EFI_SUCCESS now? */
- return (status == EFI_SUCCESS) ? len : -1;
+ return ((status == EFI_SUCCESS) ? len : -1);
}
-
-int
+static int
efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
struct netif *nif = desc->io_netif;
@@ -143,30 +164,37 @@ efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
if (bufsz > len)
bufsz = len;
bcopy(buf, pkt, bufsz);
- return bufsz;
+ return (bufsz);
}
if (status != EFI_NOT_READY)
- return 0;
+ return (0);
}
- return 0;
+ return (0);
}
-void
+static void
efinet_init(struct iodesc *desc, void *machdep_hint)
{
struct netif *nif = desc->io_netif;
EFI_SIMPLE_NETWORK *net;
+ EFI_HANDLE h;
EFI_STATUS status;
- net = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private;
- nif->nif_devdata = net;
+ h = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private;
+ status = BS->HandleProtocol(h, &sn_guid, (VOID **)&nif->nif_devdata);
+ if (status != EFI_SUCCESS) {
+ printf("net%d: cannot start interface (status=%ld)\n",
+ nif->nif_unit, (long)status);
+ return;
+ }
+ net = nif->nif_devdata;
if (net->Mode->State == EfiSimpleNetworkStopped) {
status = net->Start(net);
if (status != EFI_SUCCESS) {
printf("net%d: cannot start interface (status=%ld)\n",
- nif->nif_unit, status);
+ nif->nif_unit, (long)status);
return;
}
}
@@ -175,7 +203,7 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
status = net->Initialize(net, 0, 0);
if (status != EFI_SUCCESS) {
printf("net%d: cannot init. interface (status=%ld)\n",
- nif->nif_unit, status);
+ nif->nif_unit, (long)status);
return;
}
}
@@ -187,7 +215,7 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
status = net->ReceiveFilters(net, mask, 0, FALSE, 0, 0);
if (status != EFI_SUCCESS) {
printf("net%d: cannot set rx. filters (status=%ld)\n",
- nif->nif_unit, status);
+ nif->nif_unit, (long)status);
return;
}
}
@@ -198,71 +226,84 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6);
desc->xid = 1;
+}
+
+static void
+efinet_end(struct netif *nif)
+{
+ EFI_SIMPLE_NETWORK *net = nif->nif_devdata;
- return;
+ net->Shutdown(net);
}
-void
-efinet_init_driver()
+static int efinet_dev_init(void);
+static void efinet_dev_print(int);
+
+struct devsw efinet_dev = {
+ .dv_name = "net",
+ .dv_type = DEVT_NET,
+ .dv_init = efinet_dev_init,
+ .dv_strategy = net_strategy,
+ .dv_open = net_open,
+ .dv_close = net_close,
+ .dv_ioctl = noioctl,
+ .dv_print = efinet_dev_print,
+ .dv_cleanup = NULL
+};
+
+static int
+efinet_dev_init()
{
- EFI_STATUS status;
- UINTN sz;
- static EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
- EFI_HANDLE *handles;
- int nifs, i;
-#define MAX_INTERFACES 4
- static struct netif_dif difs[MAX_INTERFACES];
- static struct netif_stats stats[MAX_INTERFACES];
+ struct netif_dif *dif;
+ struct netif_stats *stats;
+ EFI_HANDLE *handles;
+ EFI_STATUS status;
+ UINTN sz;
+ int err, i, nifs;
sz = 0;
- status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, 0);
- if (status != EFI_BUFFER_TOO_SMALL)
- return;
- handles = (EFI_HANDLE *) malloc(sz);
- status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, handles);
- if (EFI_ERROR(status)) {
- free(handles);
- return;
+ status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz, 0);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ handles = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz,
+ handles);
+ if (EFI_ERROR(status))
+ free(handles);
}
-
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
nifs = sz / sizeof(EFI_HANDLE);
- if (nifs > MAX_INTERFACES)
- nifs = MAX_INTERFACES;
+ err = efi_register_handles(&efinet_dev, handles, nifs);
+ free(handles);
+ if (err != 0)
+ return (err);
- efi_net.netif_nifs = nifs;
- efi_net.netif_ifs = difs;
+ efinetif.netif_nifs = nifs;
+ efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));
+
+ stats = calloc(nifs, sizeof(struct netif_stats));
- bzero(stats, sizeof(stats));
for (i = 0; i < nifs; i++) {
- struct netif_dif *dif = &efi_net.netif_ifs[i];
+ dif = &efinetif.netif_ifs[i];
dif->dif_unit = i;
dif->dif_nsel = 1;
dif->dif_stats = &stats[i];
-
- BS->HandleProtocol(handles[i], &netid,
- (VOID**) &dif->dif_private);
+ dif->dif_private = efi_find_handle(&efinet_dev, i);
}
- return;
+ return (0);
}
-void
-efinet_end(struct netif *nif)
+static void
+efinet_dev_print(int verbose)
{
- EFI_SIMPLE_NETWORK *net = nif->nif_devdata;
-
- net->Shutdown(net);
+ char line[80];
+ EFI_HANDLE h;
+ int unit;
+
+ for (unit = 0, h = efi_find_handle(&efinet_dev, 0);
+ h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) {
+ sprintf(line, " %s%d:\n", efinet_dev.dv_name, unit);
+ pager_output(line);
+ }
}
-
-struct netif_driver efi_net = {
- "net", /* netif_bname */
- efinet_match, /* netif_match */
- efinet_probe, /* netif_probe */
- efinet_init, /* netif_init */
- efinet_get, /* netif_get */
- efinet_put, /* netif_put */
- efinet_end, /* netif_end */
- 0, /* netif_ifs */
- 0 /* netif_nifs */
-};
-
OpenPOWER on IntegriCloud