Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Jul 2002 02:50:56 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 14417 for review
Message-ID:  <200207180950.g6I9ouDH018692@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=14417

Change 14417 by peter@peter_ia64 on 2002/07/18 02:50:11

	Somebody shoot me please.  This cost me weeks of debugging time.
	
	First:
	net->Transmit() takes an address that net->GetStatus() is supposed
	to return when the buffer is no longer needed.  However, somebody
	decided to make the E1000 UNDI driver return a *different* address
	for some unknown reason.  Maybe it is a copy, who knows.
	
	Second:
	net->Receive() takes a buffer pointer and length.  The same E1000
	driver feels that it is quite OK to trash memory outside of this
	buffer.  I do not know if it doesn't respect the length, or just
	simply trashes things.  Trashing your stack on IA64 can really
	ruin your day.  So, provide a temporary buffer (also on the
	stack, urgh) that is "big enough" to hopefully survive and then
	bcopy the results that we expect without trashing our RPC client.

Affected files ...

.. //depot/projects/ia64/sys/boot/efi/libefi/efinet.c#3 edit

Differences ...

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

@@ -102,10 +102,14 @@
 		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 @@
 	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;
 	}

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




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