Page MenuHomeFreeBSD

D17131.id47949.diff
No OneTemporary

D17131.id47949.diff

Index: stand/i386/libi386/Makefile
===================================================================
--- stand/i386/libi386/Makefile
+++ stand/i386/libi386/Makefile
@@ -4,7 +4,7 @@
LIB= i386
-SRCS= biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \
+SRCS= bio.c biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \
biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \
comconsole.c devicename.c elf32_freebsd.c \
elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \
Index: stand/i386/libi386/bio.c
===================================================================
--- /dev/null
+++ stand/i386/libi386/bio.c
@@ -0,0 +1,61 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <stand.h>
+
+/*
+ * The idea is borrowed from pxe.c and zfsimpl.c. The original buffer
+ * space in pxe.c was 2x 0x2000. Allocating it from BSS will give us needed
+ * memory below 1MB and usable for real mode calls.
+ */
+
+#define BIO_BUFFER_SIZE 0x4000
+static char bio_buffer[BIO_BUFFER_SIZE];
+static char *bio_buffer_end = bio_buffer + BIO_BUFFER_SIZE;
+static char *bio_buffer_ptr = bio_buffer;
+
+void *
+bio_alloc(size_t size)
+{
+ char *ptr;
+
+ ptr = bio_buffer_ptr;
+ if (ptr + size > bio_buffer_end)
+ return (NULL);
+ bio_buffer_ptr += size;
+
+ return (ptr);
+}
+
+void
+bio_free(void *ptr, size_t size)
+{
+
+ if (ptr == NULL)
+ return;
+
+ bio_buffer_ptr -= size;
+ if (bio_buffer_ptr != ptr)
+ panic("bio_alloc()/bio_free() mismatch\n");
+}
Index: stand/i386/libi386/biosdisk.c
===================================================================
--- stand/i386/libi386/biosdisk.c
+++ stand/i386/libi386/biosdisk.c
@@ -448,16 +448,29 @@
char *buf, size_t *rsize)
{
struct disk_devdesc *dev = (struct disk_devdesc *)devdata;
- uint64_t disk_blocks;
- int blks, rc;
+ uint64_t disk_blocks, offset;
+ size_t blks, blkoff, bsize, bio_size, rest;
+ caddr_t bbuf;
+ int rc;
- if (size % BD(dev).bd_sectorsize) {
- panic("bd_strategy: %d bytes I/O not multiple of block size",
- size);
+ /*
+ * First make sure the IO size is a multiple of 512 bytes. While we do
+ * process partial reads below, the strategy mechanism is built
+ * assuming IO is a multiple of 512B blocks. If the request is not
+ * a multiple of 512B blocks, it has to be some sort of bug.
+ */
+ if (size == 0 || (size % BIOSDISK_SECSIZE) != 0) {
+ printf("bd_strategy: %d bytes I/O not multiple of %d\n",
+ size, BIOSDISK_SECSIZE);
+ return (EIO);
}
DEBUG("open_disk %p", dev);
+ offset = dblk * BIOSDISK_SECSIZE;
+ dblk = offset / BD(dev).bd_sectorsize;
+ blkoff = offset % BD(dev).bd_sectorsize;
+
/*
* Check the value of the size argument. We do have quite small
* heap (64MB), but we do not know good upper limit, so we check against
@@ -465,11 +478,14 @@
* while translating block count to bytes.
*/
if (size > INT_MAX) {
- DEBUG("too large read: %zu bytes", size);
+ DEBUG("too large I/O: %zu bytes", size);
return (EIO);
}
blks = size / BD(dev).bd_sectorsize;
+ if (blks == 0 || (size % BD(dev).bd_sectorsize) != 0)
+ blks++;
+
if (dblk > dblk + blks)
return (EIO);
@@ -498,38 +514,96 @@
if (dblk + blks >= dev->d_offset + disk_blocks) {
blks = dev->d_offset + disk_blocks - dblk;
size = blks * BD(dev).bd_sectorsize;
- DEBUG("short read %d", blks);
+ DEBUG("short I/O %d", blks);
}
- switch (rw & F_MASK) {
- case F_READ:
- DEBUG("read %d from %lld to %p", blks, dblk, buf);
+ bio_size = min(BIO_BUFFER_SIZE, size);
+ while (bio_size > BD(dev).bd_sectorsize) {
+ bbuf = bio_alloc(bio_size);
+ if (bbuf != NULL)
+ break;
+ bio_size -= BD(dev).bd_sectorsize;
+ }
+ if (bbuf == NULL) {
+ bio_size = V86_IO_BUFFER_SIZE;
+ if (bio_size / BD(dev).bd_sectorsize == 0)
+ panic("BUG: Real mode buffer is too small\n");
- if (blks && (rc = bd_io(dev, dblk, blks, buf, BD_RD))) {
- /* Filter out floppy controller errors */
- if (BD(dev).bd_flags != BD_FLOPPY || rc != 0x20) {
- printf("read %d from %lld to %p, error: 0x%x\n",
- blks, dblk, buf, rc);
+ /* Use alternate 4k buffer */
+ bbuf = PTOV(V86_IO_BUFFER);
+ }
+ rest = size;
+ rc = 0;
+ while (blks > 0) {
+ int x = min(blks, bio_size / BD(dev).bd_sectorsize);
+
+ switch (rw & F_MASK) {
+ case F_READ:
+ DEBUG("read %d from %lld to %p", x, dblk, buf);
+ bsize = BD(dev).bd_sectorsize * x - blkoff;
+ if (rest < bsize)
+ bsize = rest;
+
+ if ((rc = bd_io(dev, dblk, x, bbuf, BD_RD)) != 0) {
+ rc = EIO;
+ goto error;
}
- return (EIO);
- }
- break;
- case F_WRITE :
- DEBUG("write %d from %lld to %p", blks, dblk, buf);
- if (blks && bd_io(dev, dblk, blks, buf, BD_WR)) {
- DEBUG("write error");
- return (EIO);
+ bcopy(bbuf + blkoff, buf, bsize);
+ break;
+ case F_WRITE :
+ DEBUG("write %d from %lld to %p", x, dblk, buf);
+ if (blkoff != 0) {
+ /*
+ * We got offset to sector, read 1 sector to
+ * bbuf.
+ */
+ x = 1;
+ bsize = BD(dev).bd_sectorsize - blkoff;
+ bsize = min(bsize, rest);
+ rc = bd_io(dev, dblk, x, bbuf, BD_RD);
+ } else if (rest < BD(dev).bd_sectorsize) {
+ /*
+ * The remaining block is not full
+ * sector. Read 1 sector to bbuf.
+ */
+ x = 1;
+ bsize = rest;
+ rc = bd_io(dev, dblk, x, bbuf, BD_RD);
+ } else {
+ /* We can write full sector(s). */
+ bsize = BD(dev).bd_sectorsize * x;
+ }
+ /*
+ * Put your Data In, Put your Data out,
+ * Put your Data In, and shake it all about
+ */
+ bcopy(buf, bbuf + blkoff, bsize);
+ if ((rc = bd_io(dev, dblk, x, bbuf, BD_WR)) != 0) {
+ rc = EIO;
+ goto error;
+ }
+
+ break;
+ default:
+ /* DO NOTHING */
+ rc = EROFS;
+ goto error;
}
- break;
- default:
- /* DO NOTHING */
- return (EROFS);
+
+ blkoff = 0;
+ buf += bsize;
+ rest -= bsize;
+ blks -= x;
+ dblk += x;
}
- if (rsize)
+ if (rsize != NULL)
*rsize = size;
- return (0);
+error:
+ if (bbuf != PTOV(V86_IO_BUFFER))
+ bio_free(bbuf, bio_size);
+ return (rc);
}
static int
@@ -604,21 +678,16 @@
bd_edd_io(dev, 0xffffffff, 1, (caddr_t)buf, BD_RD);
}
-
static int
bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
int dowrite)
{
- u_int x, sec, result, resid, retry, maxfer;
- caddr_t p, xp, bbuf;
-
+ int result, retry;
+
/* Just in case some idiot actually tries to read/write -1 blocks... */
if (blks < 0)
return (-1);
- resid = blks;
- p = dest;
-
/*
* Workaround for a problem with some HP ProLiant BIOS failing to work
* out the boot disk after installation. hrs and kuriyama discovered
@@ -627,91 +696,49 @@
* the bios. The problem is alleviated by doing an extra read before
* the buggy read. It is not immediately known whether other models
* are similarly affected.
+ * Loop retrying the operation a couple of times. The BIOS
+ * may also retry.
*/
if (dowrite == BD_RD && dblk >= 0x100000000)
bd_io_workaround(dev);
+ for (retry = 0; retry < 3; retry++) {
+ /* if retrying, reset the drive */
+ if (retry > 0) {
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0;
+ v86.edx = BD(dev).bd_unit;
+ v86int();
+ }
- /* Decide whether we have to bounce */
- if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 &&
- (VTOP(dest) >> 16) !=
- (VTOP(dest + blks * BD(dev).bd_sectorsize) >> 16))) {
+ if (BD(dev).bd_flags & BD_MODEEDD1)
+ result = bd_edd_io(dev, dblk, blks, dest, dowrite);
+ else
+ result = bd_chs_io(dev, dblk, blks, dest, dowrite);
- /*
- * There is a 64k physical boundary somewhere in the
- * destination buffer, or the destination buffer is above
- * first 1MB of physical memory so we have to arrange a
- * suitable bounce buffer. Allocate a buffer twice as large
- * as we need to. Use the bottom half unless there is a break
- * there, in which case we use the top half.
- */
- x = V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize;
- x = min(x, (unsigned)blks);
- bbuf = PTOV(V86_IO_BUFFER);
- maxfer = x; /* limit transfers to bounce region size */
- } else {
- bbuf = NULL;
- maxfer = 0;
+ if (result == 0)
+ break;
}
-
- while (resid > 0) {
- /*
- * Play it safe and don't cross track boundaries.
- * (XXX this is probably unnecessary)
- */
- sec = dblk % BD(dev).bd_sec; /* offset into track */
- x = min(BD(dev).bd_sec - sec, resid);
- if (maxfer > 0)
- x = min(x, maxfer); /* fit bounce buffer */
- /* where do we transfer to? */
- xp = bbuf == NULL ? p : bbuf;
-
- /*
- * Put your Data In, Put your Data out,
- * Put your Data In, and shake it all about
- */
- if (dowrite == BD_WR && bbuf != NULL)
- bcopy(p, bbuf, x * BD(dev).bd_sectorsize);
-
- /*
- * Loop retrying the operation a couple of times. The BIOS
- * may also retry.
- */
- for (retry = 0; retry < 3; retry++) {
- /* if retrying, reset the drive */
- if (retry > 0) {
- v86.ctl = V86_FLAGS;
- v86.addr = 0x13;
- v86.eax = 0;
- v86.edx = BD(dev).bd_unit;
- v86int();
- }
-
- if (BD(dev).bd_flags & BD_MODEEDD1)
- result = bd_edd_io(dev, dblk, x, xp, dowrite);
- else
- result = bd_chs_io(dev, dblk, x, xp, dowrite);
- if (result == 0)
- break;
+ /*
+ * 0x20 - Controller failure. This is common error when the
+ * media is not present.
+ */
+ if (result != 0 && result != 0x20) {
+ if (dowrite == BD_WR) {
+ printf("%s%d: Write %d sector(s) from %p (0x%x) "
+ "to %lld: 0x%x\n", dev->dd.d_dev->dv_name,
+ dev->dd.d_unit, blks, dest, VTOP(dest), dblk,
+ result);
+ } else {
+ printf("%s%d: Read %d sector(s) from %lld to %p "
+ "(0x%x): 0x%x\n", dev->dd.d_dev->dv_name,
+ dev->dd.d_unit, blks, dblk, dest, VTOP(dest),
+ result);
}
-
- if (dowrite == BD_WR)
- DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x,
- p, VTOP(p), dblk, result ? "failed" : "ok");
- else
- DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x,
- dblk, p, VTOP(p), result ? "failed" : "ok");
- if (result) {
- return (result);
- }
- if (dowrite == BD_RD && bbuf != NULL)
- bcopy(bbuf, p, x * BD(dev).bd_sectorsize);
- p += (x * BD(dev).bd_sectorsize);
- dblk += x;
- resid -= x;
}
- return (0);
+ return (result);
}
/*
Index: stand/i386/libi386/libi386.h
===================================================================
--- stand/i386/libi386/libi386.h
+++ stand/i386/libi386/libi386.h
@@ -123,6 +123,11 @@
extern uint32_t high_heap_size; /* extended memory region available */
extern vm_offset_t high_heap_base; /* for use as the heap */
+/* 16KB buffer space for real mode data transfers. */
+#define BIO_BUFFER_SIZE 0x4000
+void *bio_alloc(size_t size);
+void bio_free(void *ptr, size_t size);
+
/*
* Values for width parameter to biospci_{read,write}_config
*/
Index: stand/i386/libi386/pxe.c
===================================================================
--- stand/i386/libi386/pxe.c
+++ stand/i386/libi386/pxe.c
@@ -48,18 +48,10 @@
#include <bootp.h>
#include <bootstrap.h>
+#include "libi386.h"
#include "btxv86.h"
#include "pxe.h"
-/*
- * Allocate the PXE buffers statically instead of sticking grimy fingers into
- * BTX's private data area. The scratch buffer is used to send information to
- * the PXE BIOS, and the data buffer is used to receive data from the PXE BIOS.
- */
-#define PXE_BUFFER_SIZE 0x2000
-static char scratch_buffer[PXE_BUFFER_SIZE];
-static char data_buffer[PXE_BUFFER_SIZE];
-
static pxenv_t *pxenv_p = NULL; /* PXENV+ */
static pxe_t *pxe_p = NULL; /* !PXE */
@@ -68,9 +60,9 @@
#endif
void pxe_enable(void *pxeinfo);
-static void (*pxe_call)(int func);
-static void pxenv_call(int func);
-static void bangpxe_call(int func);
+static void (*pxe_call)(int func, void *ptr);
+static void pxenv_call(int func, void *ptr);
+static void bangpxe_call(int func, void *ptr);
static int pxe_init(void);
static int pxe_print(int verbose);
@@ -225,12 +217,17 @@
printf("@%04x:%04x\n",
pxenv_p->RMEntry.segment, pxenv_p->RMEntry.offset);
- gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
+ gci_p = bio_alloc(sizeof(*gci_p));
+ if (gci_p == NULL) {
+ pxe_p = NULL;
+ return (0);
+ }
bzero(gci_p, sizeof(*gci_p));
gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY;
- pxe_call(PXENV_GET_CACHED_INFO);
+ pxe_call(PXENV_GET_CACHED_INFO, gci_p);
if (gci_p->Status != 0) {
pxe_perror(gci_p->Status);
+ bio_free(gci_p, sizeof(*gci_p));
pxe_p = NULL;
return (0);
}
@@ -240,6 +237,7 @@
bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
bootp_response, bootp_response_size);
}
+ bio_free(gci_p, sizeof(*gci_p));
return (1);
}
@@ -262,31 +260,37 @@
static void
pxe_cleanup(void)
{
-#ifdef PXE_DEBUG
- t_PXENV_UNLOAD_STACK *unload_stack_p =
- (t_PXENV_UNLOAD_STACK *)scratch_buffer;
- t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p =
- (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer;
-#endif
+ t_PXENV_UNLOAD_STACK *unload_stack_p;
+ t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p;
if (pxe_call == NULL)
return;
- pxe_call(PXENV_UNDI_SHUTDOWN);
+ undi_shutdown_p = bio_alloc(sizeof(*undi_shutdown_p));
+ if (undi_shutdown_p != NULL) {
+ bzero(undi_shutdown_p, sizeof(*undi_shutdown_p));
+ pxe_call(PXENV_UNDI_SHUTDOWN, undi_shutdown_p);
#ifdef PXE_DEBUG
- if (pxe_debug && undi_shutdown_p->Status != 0)
- printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n",
- undi_shutdown_p->Status);
+ if (pxe_debug && undi_shutdown_p->Status != 0)
+ printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n",
+ undi_shutdown_p->Status);
#endif
+ bio_free(undi_shutdown_p, sizeof(*undi_shutdown_p));
+ }
- pxe_call(PXENV_UNLOAD_STACK);
+ unload_stack_p = bio_alloc(sizeof(*unload_stack_p));
+ if (unload_stack_p != NULL) {
+ bzero(unload_stack_p, sizeof(*unload_stack_p));
+ pxe_call(PXENV_UNLOAD_STACK, unload_stack_p);
#ifdef PXE_DEBUG
- if (pxe_debug && unload_stack_p->Status != 0)
- printf("pxe_cleanup: UNLOAD_STACK failed %x\n",
- unload_stack_p->Status);
+ if (pxe_debug && unload_stack_p->Status != 0)
+ printf("pxe_cleanup: UNLOAD_STACK failed %x\n",
+ unload_stack_p->Status);
#endif
+ bio_free(unload_stack_p, sizeof(*unload_stack_p));
+ }
}
void
@@ -296,7 +300,7 @@
}
void
-pxenv_call(int func)
+pxenv_call(int func, void *ptr)
{
#ifdef PXE_DEBUG
if (pxe_debug)
@@ -304,14 +308,13 @@
#endif
bzero(&v86, sizeof(v86));
- bzero(data_buffer, sizeof(data_buffer));
__pxenvseg = pxenv_p->RMEntry.segment;
__pxenvoff = pxenv_p->RMEntry.offset;
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
- v86.es = VTOPSEG(scratch_buffer);
- v86.edi = VTOPOFF(scratch_buffer);
+ v86.es = VTOPSEG(ptr);
+ v86.edi = VTOPOFF(ptr);
v86.addr = (VTOPSEG(__pxenventry) << 16) | VTOPOFF(__pxenventry);
v86.ebx = func;
v86int();
@@ -319,7 +322,7 @@
}
void
-bangpxe_call(int func)
+bangpxe_call(int func, void *ptr)
{
#ifdef PXE_DEBUG
if (pxe_debug)
@@ -327,14 +330,13 @@
#endif
bzero(&v86, sizeof(v86));
- bzero(data_buffer, sizeof(data_buffer));
__bangpxeseg = pxe_p->EntryPointSP.segment;
__bangpxeoff = pxe_p->EntryPointSP.offset;
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
- v86.edx = VTOPSEG(scratch_buffer);
- v86.eax = VTOPOFF(scratch_buffer);
+ v86.edx = VTOPSEG(ptr);
+ v86.eax = VTOPOFF(ptr);
v86.addr = (VTOPSEG(__bangpxeentry) << 16) | VTOPOFF(__bangpxeentry);
v86.ebx = func;
v86int();
@@ -362,11 +364,14 @@
{
t_PXENV_UNDI_CLOSE *undi_close_p;
- undi_close_p = (t_PXENV_UNDI_CLOSE *)scratch_buffer;
- bzero(undi_close_p, sizeof(*undi_close_p));
- pxe_call(PXENV_UNDI_CLOSE);
- if (undi_close_p->Status != 0)
- printf("undi close failed: %x\n", undi_close_p->Status);
+ undi_close_p = bio_alloc(sizeof(*undi_close_p));
+ if (undi_close_p != NULL) {
+ bzero(undi_close_p, sizeof(*undi_close_p));
+ pxe_call(PXENV_UNDI_CLOSE, undi_close_p);
+ if (undi_close_p->Status != 0)
+ printf("undi close failed: %x\n", undi_close_p->Status);
+ bio_free(undi_close_p, sizeof(*undi_close_p));
+ }
}
static void
@@ -377,11 +382,15 @@
uint8_t *mac;
int i, len;
- undi_info_p = (t_PXENV_UNDI_GET_INFORMATION *)scratch_buffer;
+ undi_info_p = bio_alloc(sizeof(*undi_info_p));
+ if (undi_info_p == NULL)
+ return;
+
bzero(undi_info_p, sizeof(*undi_info_p));
- pxe_call(PXENV_UNDI_GET_INFORMATION);
+ pxe_call(PXENV_UNDI_GET_INFORMATION, undi_info_p);
if (undi_info_p->Status != 0) {
printf("undi get info failed: %x\n", undi_info_p->Status);
+ bio_free(undi_info_p, sizeof(*undi_info_p));
return;
}
@@ -410,32 +419,44 @@
else
desc->xid = 0;
- undi_open_p = (t_PXENV_UNDI_OPEN *)scratch_buffer;
+ bio_free(undi_info_p, sizeof(*undi_info_p));
+ undi_open_p = bio_alloc(sizeof(*undi_open_p));
+ if (undi_open_p == NULL)
+ return;
bzero(undi_open_p, sizeof(*undi_open_p));
undi_open_p->PktFilter = FLTR_DIRECTED | FLTR_BRDCST;
- pxe_call(PXENV_UNDI_OPEN);
+ pxe_call(PXENV_UNDI_OPEN, undi_open_p);
if (undi_open_p->Status != 0)
printf("undi open failed: %x\n", undi_open_p->Status);
+ bio_free(undi_open_p, sizeof(*undi_open_p));
}
static int
pxe_netif_receive(void **pkt)
{
- t_PXENV_UNDI_ISR *isr = (t_PXENV_UNDI_ISR *)scratch_buffer;
+ t_PXENV_UNDI_ISR *isr;
char *buf, *ptr, *frame;
size_t size, rsize;
+ isr = bio_alloc(sizeof(*isr));
+ if (isr == NULL)
+ return (-1);
+
bzero(isr, sizeof(*isr));
isr->FuncFlag = PXENV_UNDI_ISR_IN_START;
- pxe_call(PXENV_UNDI_ISR);
- if (isr->Status != 0)
+ pxe_call(PXENV_UNDI_ISR, isr);
+ if (isr->Status != 0) {
+ bio_free(isr, sizeof(*isr));
return (-1);
+ }
bzero(isr, sizeof(*isr));
isr->FuncFlag = PXENV_UNDI_ISR_IN_PROCESS;
- pxe_call(PXENV_UNDI_ISR);
- if (isr->Status != 0)
+ pxe_call(PXENV_UNDI_ISR, isr);
+ if (isr->Status != 0) {
+ bio_free(isr, sizeof(*isr));
return (-1);
+ }
while (isr->FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {
/*
@@ -443,26 +464,31 @@
*/
bzero(isr, sizeof(*isr));
isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
- pxe_call(PXENV_UNDI_ISR);
+ pxe_call(PXENV_UNDI_ISR, isr);
if (isr->Status != 0 ||
- isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE)
+ 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);
}
bzero(isr, sizeof(*isr));
isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
- pxe_call(PXENV_UNDI_ISR);
+ pxe_call(PXENV_UNDI_ISR, isr);
}
size = isr->FrameLength;
buf = malloc(size + ETHER_ALIGN);
- if (buf == NULL)
+ if (buf == NULL) {
+ bio_free(isr, sizeof(*isr));
return (-1);
+ }
ptr = buf + ETHER_ALIGN;
rsize = 0;
@@ -475,8 +501,9 @@
bzero(isr, sizeof(*isr));
isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
- pxe_call(PXENV_UNDI_ISR);
+ pxe_call(PXENV_UNDI_ISR, isr);
if (isr->Status != 0) {
+ bio_free(isr, sizeof(*isr));
free(buf);
return (-1);
}
@@ -488,6 +515,7 @@
}
*pkt = buf;
+ bio_free(isr, sizeof(*isr));
return (rsize);
}
@@ -515,26 +543,31 @@
t_PXENV_UNDI_TRANSMIT *trans_p;
t_PXENV_UNDI_TBD *tbd_p;
char *data;
+ ssize_t rv = -1;
- trans_p = (t_PXENV_UNDI_TRANSMIT *)scratch_buffer;
- bzero(trans_p, sizeof(*trans_p));
- tbd_p = (t_PXENV_UNDI_TBD *)(scratch_buffer + sizeof(*trans_p));
- bzero(tbd_p, sizeof(*tbd_p));
+ trans_p = bio_alloc(sizeof(*trans_p));
+ tbd_p = bio_alloc(sizeof(*tbd_p));
+ data = bio_alloc(len);
- data = scratch_buffer + sizeof(*trans_p) + sizeof(*tbd_p);
+ if (trans_p != NULL && tbd_p != NULL && data != NULL) {
+ bzero(trans_p, sizeof(*trans_p));
+ bzero(tbd_p, sizeof(*tbd_p));
- trans_p->TBD.segment = VTOPSEG(tbd_p);
- trans_p->TBD.offset = VTOPOFF(tbd_p);
+ trans_p->TBD.segment = VTOPSEG(tbd_p);
+ trans_p->TBD.offset = VTOPOFF(tbd_p);
- tbd_p->ImmedLength = len;
- tbd_p->Xmit.segment = VTOPSEG(data);
- tbd_p->Xmit.offset = VTOPOFF(data);
- bcopy(pkt, data, len);
+ tbd_p->ImmedLength = len;
+ tbd_p->Xmit.segment = VTOPSEG(data);
+ tbd_p->Xmit.offset = VTOPOFF(data);
+ bcopy(pkt, data, len);
- pxe_call(PXENV_UNDI_TRANSMIT);
- if (trans_p->Status != 0) {
- return (-1);
+ pxe_call(PXENV_UNDI_TRANSMIT, trans_p);
+ if (trans_p->Status == 0)
+ rv = len;
}
- return (len);
+ bio_free(data, len);
+ bio_free(tbd_p, sizeof(*tbd_p));
+ bio_free(trans_p, sizeof(*trans_p));
+ return (rv);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 21, 5:53 PM (4 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25784073
Default Alt Text
D17131.id47949.diff (21 KB)

Event Timeline