Page MenuHomeFreeBSD

D31512.id94150.diff
No OneTemporary

D31512.id94150.diff

Index: stand/i386/libi386/pxe.c
===================================================================
--- stand/i386/libi386/pxe.c
+++ stand/i386/libi386/pxe.c
@@ -30,6 +30,7 @@
__FBSDID("$FreeBSD$");
#include <stand.h>
+#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
@@ -434,14 +435,26 @@
static int
pxe_netif_receive(void **pkt)
{
+ static bool data_pending;
t_PXENV_UNDI_ISR *isr;
char *buf, *ptr, *frame;
size_t size, rsize;
+ buf = NULL;
+ rsize = 0;
isr = bio_alloc(sizeof(*isr));
if (isr == NULL)
return (-1);
+ /*
+ * We can save ourselves the next two pxe calls because we already know
+ * we weren't done grabbing everything.
+ */
+ if (data_pending) {
+ data_pending = false;
+ goto nextbuf;
+ }
+
bzero(isr, sizeof(*isr));
isr->FuncFlag = PXENV_UNDI_ISR_IN_START;
pxe_call(PXENV_UNDI_ISR, isr);
@@ -458,47 +471,43 @@
return (-1);
}
- while (isr->FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {
- /*
- * Wait till transmit is done.
- */
- bzero(isr, sizeof(*isr));
- isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
- pxe_call(PXENV_UNDI_ISR, isr);
- if (isr->Status != 0 ||
- isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE) {
- bio_free(isr, sizeof(*isr));
- return (-1);
- }
- }
-
- while (isr->FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE) {
- if (isr->Status != 0 ||
- isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE) {
- bio_free(isr, sizeof(*isr));
- return (-1);
+ while (isr->Status == 0 &&
+ isr->FuncFlag != PXENV_UNDI_ISR_OUT_DONE) {
+ if (isr->FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE)
+ goto nextbuf;
+
+ if (buf == NULL) {
+ /*
+ * Grab size from the first frame,
+ * allocate rx buf
+ */
+ size = isr->FrameLength;
+ buf = malloc(size + ETHER_ALIGN);
+ if (buf == NULL) {
+ bio_free(isr, sizeof(*isr));
+ return (-1);
+ }
+ ptr = buf + ETHER_ALIGN;
}
- bzero(isr, sizeof(*isr));
- isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
- pxe_call(PXENV_UNDI_ISR, isr);
- }
-
- size = isr->FrameLength;
- buf = malloc(size + ETHER_ALIGN);
- if (buf == NULL) {
- bio_free(isr, sizeof(*isr));
- return (-1);
- }
- ptr = buf + ETHER_ALIGN;
- rsize = 0;
- while (rsize < size) {
frame = (char *)((uintptr_t)isr->Frame.segment << 4);
frame += isr->Frame.offset;
bcopy(PTOV(frame), ptr, isr->BufferLength);
ptr += isr->BufferLength;
rsize += isr->BufferLength;
+ /*
+ * We may have caught an additional frame, just drop it on the
+ * floor for our next call into here. It'd perhaps be nice to
+ * be able to chain packets, but our network stack in libsa is
+ * just not ready for that.
+ */
+ if (rsize >= size) {
+ data_pending = true;
+ break;
+ }
+
+nextbuf:
bzero(isr, sizeof(*isr));
isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
pxe_call(PXENV_UNDI_ISR, isr);
@@ -507,11 +516,6 @@
free(buf);
return (-1);
}
-
- /* Did we got another update? */
- if (isr->FuncFlag == PXENV_UNDI_ISR_OUT_RECEIVE)
- continue;
- break;
}
*pkt = buf;

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 24, 9:12 AM (17 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37179718
Default Alt Text
D31512.id94150.diff (2 KB)

Event Timeline