Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Nov 2006 22:37:28 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 108976 for review
Message-ID:  <200611012237.kA1MbSBe063654@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=108976

Change 108976 by marcel@marcel_cluster on 2006/11/01 22:37:13

	o  Create a devsw for the EFI network interface so that lsdev
	   will actually show the network devices.
	
	o  Create a "repository" of handles so that we can map from
	   handle to (dev,unit) and vice versa. This eliminates the
	   kluge in main(). It also avoids having each device keep
	   their own books in this regard...

Affected files ...

.. //depot/projects/ia64/sys/boot/efi/include/efilib.h#9 edit
.. //depot/projects/ia64/sys/boot/efi/libefi/Makefile#16 edit
.. //depot/projects/ia64/sys/boot/efi/libefi/efifs.c#15 edit
.. //depot/projects/ia64/sys/boot/efi/libefi/efinet.c#9 edit
.. //depot/projects/ia64/sys/boot/efi/libefi/handles.c#1 add
.. //depot/projects/ia64/sys/boot/ia64/efi/conf.c#5 edit
.. //depot/projects/ia64/sys/boot/ia64/efi/main.c#5 edit

Differences ...

==== //depot/projects/ia64/sys/boot/efi/include/efilib.h#9 (text+ko) ====

@@ -43,6 +43,10 @@
 void *efi_get_table(EFI_GUID *tbl);
 void efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
 
+int efi_register_handles(struct devsw *, EFI_HANDLE *, int);
+EFI_HANDLE efi_find_handle(struct devsw *, int);
+int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *);
+
 int efi_status_to_errno(EFI_STATUS);
 time_t efi_time(EFI_TIME *);
 

==== //depot/projects/ia64/sys/boot/efi/libefi/Makefile#16 (text+ko) ====

@@ -3,7 +3,8 @@
 LIB=	efi
 INTERNALLIB=
 
-SRCS=	delay.c efi_console.c efifs.c efinet.c errno.c libefi.c time.c
+SRCS=	delay.c efi_console.c efifs.c efinet.c errno.c handles.c libefi.c \
+	time.c
 
 CFLAGS+= -I${.CURDIR}/../include
 CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH:S/amd64/i386/}

==== //depot/projects/ia64/sys/boot/efi/libefi/efifs.c#15 (text+ko) ====

@@ -51,24 +51,24 @@
 static EFI_GUID fs_guid = EFI_FILE_SYSTEM_INFO_ID;
 static EFI_GUID fi_guid = EFI_FILE_INFO_ID;
 
-static EFI_HANDLE *fs_handles;
-static int fs_handle_count;
-
 static int
 efifs_open(const char *upath, struct open_file *f)
 {
 	struct devdesc *dev = f->f_devdata;
 	EFI_FILE_IO_INTERFACE *fsif;
 	EFI_FILE *file, *root;
+	EFI_HANDLE h;
 	EFI_STATUS status;
 	CHAR16 *cp, *path;
 
-	if (f->f_dev != &efifs_dev || dev->d_unit < 0 ||
-	    dev->d_unit >= fs_handle_count)
+	if (f->f_dev != &efifs_dev || dev->d_unit < 0)
+		return (EINVAL);
+
+	h = efi_find_handle(f->f_dev, dev->d_unit);
+	if (h == NULL)
 		return (EINVAL);
 
-	status = BS->HandleProtocol(fs_handles[dev->d_unit], &sfs_guid,
-	    (VOID **)&fsif);
+	status = BS->HandleProtocol(h, &sfs_guid, (VOID **)&fsif);
 	if (EFI_ERROR(status))
 		return (efi_status_to_errno(status));
 
@@ -296,7 +296,7 @@
 }
 
 struct fs_ops efifs_fsops = {
-	.fs_name = "fs",
+	.fs_name = "efifs",
 	.fo_open = efifs_open,
 	.fo_close = efifs_close,
 	.fo_read = efifs_read,
@@ -306,38 +306,29 @@
 	.fo_readdir = efifs_readdir
 };
 
-int
-efifs_get_unit(EFI_HANDLE h)
-{
-	int u;
-
-	u = 0;
-	while (u < fs_handle_count && fs_handles[u] != h)
-		u++;
-	return ((u < fs_handle_count) ? u : -1);
-}
-
 static int
 efifs_dev_init(void) 
 {
-	EFI_STATUS	status;
-	UINTN		sz;
+	EFI_HANDLE *handles;
+	EFI_STATUS status;
+	UINTN sz;
+	int err;
 
 	sz = 0;
 	status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz, 0);
 	if (status == EFI_BUFFER_TOO_SMALL) {
-		fs_handles = (EFI_HANDLE *)malloc(sz);
+		handles = (EFI_HANDLE *)malloc(sz);
 		status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz,
-		    fs_handles);
-		if (EFI_ERROR(status)) {
-			free(fs_handles);
-			fs_handles = NULL;
-		}
+		    handles);
+		if (EFI_ERROR(status))
+			free(handles);
 	}
 	if (EFI_ERROR(status))
 		return (efi_status_to_errno(status));
-	fs_handle_count = sz / sizeof(EFI_HANDLE);
-	return (0);
+	err = efi_register_handles(&efifs_dev, handles,
+	    sz / sizeof(EFI_HANDLE));
+	free(handles);
+	return (err);
 }
 
 /*
@@ -353,16 +344,17 @@
 	char line[80];
 	EFI_FILE_IO_INTERFACE *fsif;
 	EFI_FILE *volume;
+	EFI_HANDLE h;
 	EFI_STATUS status;
 	UINTN sz;
-	int h, i;
+	int i, unit;
 
-	for (h = 0; h < fs_handle_count; h++) {
-		sprintf(line, "    fs%d: ", h);
+	for (unit = 0, h = efi_find_handle(&efifs_dev, 0);
+	    h != NULL; h = efi_find_handle(&efifs_dev, ++unit)) {
+		sprintf(line, "    %s%d: ", efifs_dev.dv_name, unit);
 		pager_output(line);
 
-		status = BS->HandleProtocol(fs_handles[h], &sfs_guid,
-		    (VOID **)&fsif);
+		status = BS->HandleProtocol(h, &sfs_guid, (VOID **)&fsif);
 		if (EFI_ERROR(status))
 			goto err;
 
@@ -417,7 +409,7 @@
 	dev = va_arg(args, struct devdesc*);
 	va_end(args);
 
-	if (dev->d_unit < 0 || dev->d_unit >= fs_handle_count)
+	if (dev->d_unit < 0)
 		return(ENXIO);
 	return (0);
 }

==== //depot/projects/ia64/sys/boot/efi/libefi/efinet.c#9 (text+ko) ====

@@ -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,9 +36,13 @@
 #include <net.h>
 #include <netif.h>
 
+#include <dev_net.c>
+
 #include <efi.h>
 #include <efilib.h>
 
+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 *);
@@ -46,7 +51,7 @@
 static int efinet_put(struct iodesc *, void *, size_t);
 
 struct netif_driver efinetif = {   
-	.netif_bname = "net",
+	.netif_bname = "efinet",
 	.netif_match = efinet_match,
 	.netif_probe = efinet_probe,
 	.netif_init = efinet_init,
@@ -117,7 +122,7 @@
 
 	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 {
@@ -130,7 +135,7 @@
 	} 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);
 }
 
 static int
@@ -159,13 +164,13 @@
 			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);
 }
 
 static void
@@ -173,11 +178,18 @@
 {
 	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) {
@@ -214,58 +226,84 @@
 
 	bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6);
 	desc->xid = 1;
+}
 
-	return;
+static void
+efinet_end(struct netif *nif)
+{
+	EFI_SIMPLE_NETWORK *net = nif->nif_devdata; 
+
+	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);
 
 	efinetif.netif_nifs = nifs;
-	efinetif.netif_ifs = difs;
+	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 = &efinetif.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);
 }
 
 static void
-efinet_end(struct netif *nif)
+efinet_dev_print(int verbose)
 {
-	EFI_SIMPLE_NETWORK *net = nif->nif_devdata;
+	char line[80];
+	EFI_HANDLE h;
+	int unit;
 
-	net->Shutdown(net);
+	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);
+	}
 }

==== //depot/projects/ia64/sys/boot/ia64/efi/conf.c#5 (text+ko) ====

@@ -50,17 +50,23 @@
 /* Exported for libstand */
 struct devsw *devsw[] = {
 	&efifs_dev,
+	&efinet_dev,
 	NULL
 };
 
 struct fs_ops *file_system[] = {
 	&efifs_fsops,
+	&nfs_fsops,
 	&ufs_fsops,
 	&gzipfs_fsops,
 	NULL
 };
 
-/* Exported for ia64 only */
+struct netif_driver *netif_drivers[] = {
+	&efinetif,
+	NULL
+};
+
 /* 
  * Sort formats so that those that can detect based on arguments
  * rather than reading the file go first.

==== //depot/projects/ia64/sys/boot/ia64/efi/main.c#5 (text+ko) ====

@@ -124,8 +124,6 @@
 		if (devsw[i]->dv_init != NULL)
 			(devsw[i]->dv_init)();
 
-	efinet_init_driver();
-
 	/* Get our loaded image protocol interface structure. */
 	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
 
@@ -135,14 +133,7 @@
 	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
 	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
 
-	i = efifs_get_unit(img->DeviceHandle);
-	if (i >= 0) {
-		currdev.d_dev = devsw[0];		/* XXX disk */
-		currdev.d_unit = i;
-	} else {
-		currdev.d_dev = devsw[1];		/* XXX net */
-		currdev.d_unit = 0;			/* XXX */
-	}
+	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
 	currdev.d_type = currdev.d_dev->dv_type;
 
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611012237.kA1MbSBe063654>