Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136934306
D17131.id47949.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D17131.id47949.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D17131: loader: create bio_alloc and bio_free for bios bounce buffer
Attached
Detach File
Event Timeline
Log In to Comment