summaryrefslogtreecommitdiff
path: root/gpxe
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-10-01 11:47:20 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-10-01 11:48:48 -0700
commita40e933b79efe6349151092b3080d2547a9f69b9 (patch)
tree2ebb6aa6d095b738d5f73a8fd0e7ba7d25034d9d /gpxe
parenta009dceedaedb930dc3458202274d534baeabaf4 (diff)
downloadsyslinux-a40e933b79efe6349151092b3080d2547a9f69b9.tar.gz
gPXE: merge gPXE 0.9.5
Merge gPXE 0.9.5 gpxe 8c3e95ce420c21e612dbed58fd74dbb01025643f gpxe-for-syslinux 1982e507d0159d83a542224d4203e964bbd16f7d Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'gpxe')
-rw-r--r--gpxe/VERSION2
-rw-r--r--gpxe/src/Makefile4
-rw-r--r--gpxe/src/Makefile.housekeeping12
-rw-r--r--gpxe/src/arch/i386/core/dumpregs.c23
-rw-r--r--gpxe/src/arch/i386/core/gdbmach.c4
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/e820mangler.S61
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/memmap.c46
-rw-r--r--gpxe/src/drivers/infiniband/arbel.c8
-rw-r--r--gpxe/src/drivers/infiniband/hermon.c117
-rw-r--r--gpxe/src/drivers/net/tg3.c1
-rw-r--r--gpxe/src/net/tcp/iscsi.c25
11 files changed, 209 insertions, 94 deletions
diff --git a/gpxe/VERSION b/gpxe/VERSION
index 02f4fc9b..010605b1 100644
--- a/gpxe/VERSION
+++ b/gpxe/VERSION
@@ -1 +1 @@
-0.9.4 2008-09-26
+0.9.5 2008-10-01
diff --git a/gpxe/src/Makefile b/gpxe/src/Makefile
index 474e8cfd..6c42da6a 100644
--- a/gpxe/src/Makefile
+++ b/gpxe/src/Makefile
@@ -71,7 +71,7 @@ noargs : blib $(BIN)/NIC $(BIN)/gpxe.dsk $(BIN)/gpxe.iso $(BIN)/gpxe.usb $(BIN)/
# If no architecture is specified in Config or on the command-line,
# use that of the build machine.
#
-ARCH ?= $(shell uname -m | sed -e s,i[3456789]86,i386,)
+ARCH := $(shell uname -m | sed -e 's,i[3456789]86,i386,')
# handle x86_64 like i386, but set -m32 option for 32bit code only
ifeq ($(ARCH),x86_64)
@@ -98,7 +98,7 @@ LDFLAGS += $(EXTRA_LDFLAGS)
# Embedded image, if present
#
-EMBEDDED_IMAGE ?= /dev/null
+EMBEDDED_IMAGE = /dev/null
ifneq ($(NO_WERROR),1)
CFLAGS += -Werror
diff --git a/gpxe/src/Makefile.housekeeping b/gpxe/src/Makefile.housekeeping
index 17df25f1..9e11ceb4 100644
--- a/gpxe/src/Makefile.housekeeping
+++ b/gpxe/src/Makefile.housekeeping
@@ -11,8 +11,8 @@ CLEANUP := $(BIN)/*.* # *.* to avoid catching the "CVS" directory
#
VERSION_MAJOR = 0
VERSION_MINOR = 9
-VERSION_PATCH = 4
-EXTRAVERSION =
+VERSION_PATCH = 5
+EXTRAVERSION =
MM_VERSION = $(VERSION_MAJOR).$(VERSION_MINOR)
VERSION = $(MM_VERSION).$(VERSION_PATCH)$(EXTRAVERSION)
CFLAGS += -DVERSION_MAJOR=$(VERSION_MAJOR) \
@@ -58,16 +58,16 @@ ECHO_E_BIN_ECHO_TAB := $(shell $(ECHO_E_BIN_ECHO) '\t')
ECHO_E_BIN_ECHO_E_TAB := $(shell $(ECHO_E_BIN_ECHO_E) '\t')
ifeq ($(ECHO_E_ECHO_TAB),$(TAB))
-ECHO_E ?= $(ECHO_E_ECHO)
+ECHO_E := $(ECHO_E_ECHO)
endif
ifeq ($(ECHO_E_ECHO_E_TAB),$(TAB))
-ECHO_E ?= $(ECHO_E_ECHO_E)
+ECHO_E := $(ECHO_E_ECHO_E)
endif
ifeq ($(ECHO_E_BIN_ECHO_TAB),$(TAB))
-ECHO_E ?= $(ECHO_E_BIN_ECHO)
+ECHO_E := $(ECHO_E_BIN_ECHO)
endif
ifeq ($(ECHO_E_BIN_ECHO_E_TAB),$(TAB))
-ECHO_E ?= $(ECHO_E_BIN_ECHO_E)
+ECHO_E := $(ECHO_E_BIN_ECHO_E)
endif
.echocheck :
diff --git a/gpxe/src/arch/i386/core/dumpregs.c b/gpxe/src/arch/i386/core/dumpregs.c
new file mode 100644
index 00000000..89426d58
--- /dev/null
+++ b/gpxe/src/arch/i386/core/dumpregs.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <realmode.h>
+
+void __cdecl _dump_regs ( struct i386_all_regs *ix86 ) {
+
+ __asm__ __volatile__ (
+ TEXT16_CODE ( ".globl dump_regs\n\t"
+ "\ndump_regs:\n\t"
+ "pushl $_dump_regs\n\t"
+ "pushw %%cs\n\t"
+ "call prot_call\n\t"
+ "addr32 leal 4(%%esp), %%esp\n\t"
+ "ret\n\t" ) : : );
+
+ printf ( "EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
+ "ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n"
+ "CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x\n",
+ ix86->regs.eax, ix86->regs.ebx, ix86->regs.ecx,
+ ix86->regs.edx, ix86->regs.esi, ix86->regs.edi,
+ ix86->regs.ebp, ix86->regs.esp,
+ ix86->segs.cs, ix86->segs.ss, ix86->segs.ds,
+ ix86->segs.es, ix86->segs.fs, ix86->segs.gs );
+}
diff --git a/gpxe/src/arch/i386/core/gdbmach.c b/gpxe/src/arch/i386/core/gdbmach.c
index 26fab609..5e72e4d0 100644
--- a/gpxe/src/arch/i386/core/gdbmach.c
+++ b/gpxe/src/arch/i386/core/gdbmach.c
@@ -60,10 +60,10 @@ static struct hwbp *gdbmach_find_hwbp ( int type, unsigned long addr, size_t len
}
static void gdbmach_commit_hwbp ( struct hwbp *bp ) {
- int regnum = bp - hwbps;
+ unsigned int regnum = bp - hwbps;
/* Set breakpoint address */
- assert ( regnum >= 0 && regnum < sizeof hwbps / sizeof hwbps [ 0 ] );
+ assert ( regnum < ( sizeof hwbps / sizeof hwbps [ 0 ] ) );
switch ( regnum ) {
case 0:
__asm__ __volatile__ ( "movl %0, %%dr0\n" : : "r" ( bp->addr ) );
diff --git a/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S b/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
index ad773f74..4fbd6563 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
+++ b/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
@@ -25,6 +25,26 @@
#define SMAP 0x534d4150
+/* Most documentation refers to the E820 buffer as being 20 bytes, and
+ * the API makes it perfectly legitimate to pass only a 20-byte buffer
+ * and expect to get valid data. However, some morons at ACPI decided
+ * to extend the data structure by adding an extra "extended
+ * attributes" field and by including critical information within this
+ * field, such as whether or not the region is enabled. A caller who
+ * passes in only a 20-byte buffer therefore risks getting very, very
+ * misleading information.
+ *
+ * I have personally witnessed an HP BIOS that returns a value of
+ * 0x0009 in the extended attributes field. If we don't pass this
+ * value through to the caller, 32-bit WinPE will die, usually with a
+ * PAGE_FAULT_IN_NONPAGED_AREA blue screen of death.
+ *
+ * Allow a ridiculously large maximum value (64 bytes) for the E820
+ * buffer as a guard against insufficiently creative idiots in the
+ * future.
+ */
+#define E820MAXSIZE 64
+
/****************************************************************************
*
* Allowed memory windows
@@ -204,19 +224,22 @@ get_underlying_e820:
/* If the requested region is in the cache, return it */
cmpw %bx, underlying_e820_index
- jne 1f
+ jne 2f
pushw %di
pushw %si
movw $underlying_e820_cache, %si
- movw $20, %cx
+ cmpl underlying_e820_cache_size, %ecx
+ jbe 1f
+ movl underlying_e820_cache_size, %ecx
+1: pushl %ecx
rep movsb
+ popl %ecx
popw %si
popw %di
- movw $20, %cx
incw %bx
movl %edx, %eax
ret
-1:
+2:
/* If the requested region is earlier than the cached region,
* invalidate the cache.
*/
@@ -250,23 +273,26 @@ get_underlying_e820:
pushw %ds
popw %es
movw $underlying_e820_cache, %di
- movl $20, %ecx
- movl underlying_e820_ebx, %ebx
+ cmpl $E820MAXSIZE, %ecx
+ jbe 1f
+ movl $E820MAXSIZE, %ecx
+1: movl underlying_e820_ebx, %ebx
stc
pushfw
lcall *%cs:int15_vector
popw %di
popw %es
/* Check for error return from underlying e820 call */
- jc 1f /* CF set: error */
+ jc 2f /* CF set: error */
cmpl $SMAP, %eax
- je 2f /* 'SMAP' missing: error */
-1: /* An error occurred: return values returned by underlying e820 call */
+ je 3f /* 'SMAP' missing: error */
+2: /* An error occurred: return values returned by underlying e820 call */
stc /* Force CF set if SMAP was missing */
addr32 leal 16(%esp), %esp /* avoid changing other flags */
ret
-2: /* No error occurred */
+3: /* No error occurred */
movl %ebx, underlying_e820_ebx
+ movl %ecx, underlying_e820_cache_size
popl %edx
popl %ecx
popl %ebx
@@ -290,9 +316,14 @@ underlying_e820_ebx:
.section ".bss16"
underlying_e820_cache:
- .space 20
+ .space E820MAXSIZE
.size underlying_e820_cache, . - underlying_e820_cache
+ .section ".bss16"
+underlying_e820_cache_size:
+ .long 0
+ .size underlying_e820_cache_size, . - underlying_e820_cache_size
+
/****************************************************************************
* Get windowed e820 region, without empty region stripping
*
@@ -436,15 +467,17 @@ get_mangled_e820:
/* Peek ahead to see if there are any further nonempty regions */
pushal
- subw $20, %sp
+ pushw %es
+ movw %sp, %bp
+ subw %cx, %sp
movl $0xe820, %eax
movl $SMAP, %edx
- movl $20, %ecx
pushw %ss
popw %es
movw %sp, %di
call get_nonempty_e820
- addr32 leal 20(%esp), %esp /* avoid changing flags */
+ movw %bp, %sp
+ popw %es
popal
jnc 99f /* There are further nonempty regions */
diff --git a/gpxe/src/arch/i386/firmware/pcbios/memmap.c b/gpxe/src/arch/i386/firmware/pcbios/memmap.c
index e6d6428e..9de10a7a 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/memmap.c
+++ b/gpxe/src/arch/i386/firmware/pcbios/memmap.c
@@ -41,6 +41,8 @@ struct e820_entry {
uint64_t len;
/** Type of region */
uint32_t type;
+ /** Extended attributes (optional) */
+ uint32_t attrs;
} __attribute__ (( packed ));
#define E820_TYPE_RAM 1 /**< Normal memory */
@@ -48,6 +50,12 @@ struct e820_entry {
#define E820_TYPE_ACPI 3 /**< ACPI reclaim memory */
#define E820_TYPE_NVS 4 /**< ACPI NVS memory */
+#define E820_ATTR_ENABLED 0x00000001UL
+#define E820_ATTR_NONVOLATILE 0x00000002UL
+#define E820_ATTR_UNKNOWN 0xfffffffcUL
+
+#define E820_MIN_SIZE 20
+
/** Buffer for INT 15,e820 calls */
static struct e820_entry __bss16 ( e820buf );
#define e820buf __use_data16 ( e820buf )
@@ -148,8 +156,15 @@ static int meme820 ( struct memory_map *memmap ) {
struct memory_region *region = memmap->regions;
uint32_t next = 0;
uint32_t smap;
+ size_t size;
unsigned int flags;
- unsigned int discard_c, discard_d, discard_D;
+ unsigned int discard_d, discard_D;
+
+ /* Clear the E820 buffer. Do this once before starting,
+ * rather than on each call; some BIOSes rely on the contents
+ * being preserved between calls.
+ */
+ memset ( &e820buf, 0, sizeof ( e820buf ) );
do {
__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
@@ -158,7 +173,7 @@ static int meme820 ( struct memory_map *memmap ) {
"popw %w0\n\t" )
: "=r" ( flags ), "=a" ( smap ),
"=b" ( next ), "=D" ( discard_D ),
- "=c" ( discard_c ), "=d" ( discard_d )
+ "=c" ( size ), "=d" ( discard_d )
: "a" ( 0xe820 ), "b" ( next ),
"D" ( __from_data16 ( &e820buf ) ),
"c" ( sizeof ( e820buf ) ),
@@ -170,17 +185,42 @@ static int meme820 ( struct memory_map *memmap ) {
return -ENOTSUP;
}
+ if ( size < E820_MIN_SIZE ) {
+ DBG ( "INT 15,e820 returned only %zd bytes\n", size );
+ return -EINVAL;
+ }
+
if ( flags & CF ) {
DBG ( "INT 15,e820 terminated on CF set\n" );
break;
}
- DBG ( "INT 15,e820 region [%llx,%llx) type %d\n",
+ DBG ( "INT 15,e820 region [%llx,%llx) type %d",
e820buf.start, ( e820buf.start + e820buf.len ),
( int ) e820buf.type );
+ if ( size > offsetof ( typeof ( e820buf ), attrs ) ) {
+ DBG ( " (%s", ( ( e820buf.attrs & E820_ATTR_ENABLED )
+ ? "enabled" : "disabled" ) );
+ if ( e820buf.attrs & E820_ATTR_NONVOLATILE )
+ DBG ( ", non-volatile" );
+ if ( e820buf.attrs & E820_ATTR_UNKNOWN )
+ DBG ( ", other [%08lx]", e820buf.attrs );
+ DBG ( ")" );
+ }
+ DBG ( "\n" );
+
+ /* Discard non-RAM regions */
if ( e820buf.type != E820_TYPE_RAM )
continue;
+ /* Check extended attributes, if present */
+ if ( size > offsetof ( typeof ( e820buf ), attrs ) ) {
+ if ( ! ( e820buf.attrs & E820_ATTR_ENABLED ) )
+ continue;
+ if ( e820buf.attrs & E820_ATTR_NONVOLATILE )
+ continue;
+ }
+
region->start = e820buf.start;
region->end = e820buf.start + e820buf.len;
region++;
diff --git a/gpxe/src/drivers/infiniband/arbel.c b/gpxe/src/drivers/infiniband/arbel.c
index 0c180833..1b55131b 100644
--- a/gpxe/src/drivers/infiniband/arbel.c
+++ b/gpxe/src/drivers/infiniband/arbel.c
@@ -2183,9 +2183,9 @@ static int arbel_probe ( struct pci_device *pci,
return 0;
- i = ( ARBEL_NUM_PORTS - 1 );
+ i = ARBEL_NUM_PORTS;
err_register_ibdev:
- for ( ; i >= 0 ; i-- )
+ for ( i-- ; i >= 0 ; i-- )
unregister_ibdev ( arbel->ibdev[i] );
arbel_destroy_eq ( arbel );
err_create_eq:
@@ -2201,9 +2201,9 @@ static int arbel_probe ( struct pci_device *pci,
err_mailbox_out:
free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
err_mailbox_in:
- i = ( ARBEL_NUM_PORTS - 1 );
+ i = ARBEL_NUM_PORTS;
err_alloc_ibdev:
- for ( ; i >= 0 ; i-- )
+ for ( i-- ; i >= 0 ; i-- )
ibdev_put ( arbel->ibdev[i] );
free ( arbel );
err_alloc_arbel:
diff --git a/gpxe/src/drivers/infiniband/hermon.c b/gpxe/src/drivers/infiniband/hermon.c
index 9716aba9..3ca60033 100644
--- a/gpxe/src/drivers/infiniband/hermon.c
+++ b/gpxe/src/drivers/infiniband/hermon.c
@@ -1653,6 +1653,47 @@ static struct ib_device_operations hermon_ib_operations = {
*/
/**
+ * Map virtual to physical address for firmware usage
+ *
+ * @v hermon Hermon device
+ * @v map Mapping function
+ * @v va Virtual address
+ * @v pa Physical address
+ * @v len Length of region
+ * @ret rc Return status code
+ */
+static int hermon_map_vpm ( struct hermon *hermon,
+ int ( *map ) ( struct hermon *hermon,
+ const struct hermonprm_virtual_physical_mapping* ),
+ uint64_t va, physaddr_t pa, size_t len ) {
+ struct hermonprm_virtual_physical_mapping mapping;
+ int rc;
+
+ assert ( ( va & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
+ assert ( ( pa & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
+ assert ( ( len & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
+
+ while ( len ) {
+ memset ( &mapping, 0, sizeof ( mapping ) );
+ MLX_FILL_1 ( &mapping, 0, va_h, ( va >> 32 ) );
+ MLX_FILL_1 ( &mapping, 1, va_l, ( va >> 12 ) );
+ MLX_FILL_2 ( &mapping, 3,
+ log2size, 0,
+ pa_l, ( pa >> 12 ) );
+ if ( ( rc = map ( hermon, &mapping ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p could not map %llx => %lx: "
+ "%s\n", hermon, va, pa, strerror ( rc ) );
+ return rc;
+ }
+ pa += HERMON_PAGE_SIZE;
+ va += HERMON_PAGE_SIZE;
+ len -= HERMON_PAGE_SIZE;
+ }
+
+ return 0;
+}
+
+/**
* Start firmware running
*
* @v hermon Hermon device
@@ -1660,9 +1701,7 @@ static struct ib_device_operations hermon_ib_operations = {
*/
static int hermon_start_firmware ( struct hermon *hermon ) {
struct hermonprm_query_fw fw;
- struct hermonprm_virtual_physical_mapping map_fa;
unsigned int fw_pages;
- unsigned int log2_fw_pages;
size_t fw_size;
physaddr_t fw_base;
int rc;
@@ -1677,27 +1716,21 @@ static int hermon_start_firmware ( struct hermon *hermon ) {
MLX_GET ( &fw, fw_rev_major ), MLX_GET ( &fw, fw_rev_minor ),
MLX_GET ( &fw, fw_rev_subminor ) );
fw_pages = MLX_GET ( &fw, fw_pages );
- log2_fw_pages = fls ( fw_pages - 1 );
- fw_pages = ( 1 << log2_fw_pages );
- DBGC ( hermon, "Hermon %p requires %d kB for firmware\n",
- hermon, ( fw_pages * 4 ) );
+ DBGC ( hermon, "Hermon %p requires %d pages (%d kB) for firmware\n",
+ hermon, fw_pages, ( fw_pages * ( HERMON_PAGE_SIZE / 1024 ) ) );
/* Allocate firmware pages and map firmware area */
fw_size = ( fw_pages * HERMON_PAGE_SIZE );
- hermon->firmware_area = umalloc ( fw_size * 2 );
+ hermon->firmware_area = umalloc ( fw_size );
if ( ! hermon->firmware_area ) {
rc = -ENOMEM;
goto err_alloc_fa;
}
- fw_base = ( user_to_phys ( hermon->firmware_area, fw_size ) &
- ~( fw_size - 1 ) );
+ fw_base = user_to_phys ( hermon->firmware_area, 0 );
DBGC ( hermon, "Hermon %p firmware area at physical [%lx,%lx)\n",
hermon, fw_base, ( fw_base + fw_size ) );
- memset ( &map_fa, 0, sizeof ( map_fa ) );
- MLX_FILL_2 ( &map_fa, 3,
- log2size, log2_fw_pages,
- pa_l, ( fw_base >> 12 ) );
- if ( ( rc = hermon_cmd_map_fa ( hermon, &map_fa ) ) != 0 ) {
+ if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_fa,
+ 0, fw_base, fw_size ) ) != 0 ) {
DBGC ( hermon, "Hermon %p could not map firmware: %s\n",
hermon, strerror ( rc ) );
goto err_map_fa;
@@ -1714,8 +1747,8 @@ static int hermon_start_firmware ( struct hermon *hermon ) {
return 0;
err_run_fw:
- hermon_cmd_unmap_fa ( hermon );
err_map_fa:
+ hermon_cmd_unmap_fa ( hermon );
ufree ( hermon->firmware_area );
hermon->firmware_area = UNULL;
err_alloc_fa:
@@ -1816,8 +1849,6 @@ static int hermon_alloc_icm ( struct hermon *hermon,
struct hermonprm_init_hca *init_hca ) {
struct hermonprm_scalar_parameter icm_size;
struct hermonprm_scalar_parameter icm_aux_size;
- struct hermonprm_virtual_physical_mapping map_icm_aux;
- struct hermonprm_virtual_physical_mapping map_icm;
uint64_t icm_offset = 0;
unsigned int log_num_qps, log_num_srqs, log_num_cqs, log_num_eqs;
unsigned int log_num_mtts, log_num_mpts;
@@ -2000,13 +2031,11 @@ static int hermon_alloc_icm ( struct hermon *hermon,
goto err_set_icm_size;
}
icm_aux_len = ( MLX_GET ( &icm_aux_size, value ) * HERMON_PAGE_SIZE );
- /* Must round up to nearest power of two :( */
- icm_aux_len = ( 1 << fls ( icm_aux_len - 1 ) );
/* Allocate ICM data and auxiliary area */
DBGC ( hermon, "Hermon %p requires %zd kB ICM and %zd kB AUX ICM\n",
hermon, ( icm_len / 1024 ), ( icm_aux_len / 1024 ) );
- hermon->icm = umalloc ( 2 * icm_aux_len + icm_len );
+ hermon->icm = umalloc ( icm_aux_len + icm_len );
if ( ! hermon->icm ) {
rc = -ENOMEM;
goto err_alloc;
@@ -2014,39 +2043,25 @@ static int hermon_alloc_icm ( struct hermon *hermon,
icm_phys = user_to_phys ( hermon->icm, 0 );
/* Map ICM auxiliary area */
- icm_phys = ( ( icm_phys + icm_aux_len - 1 ) & ~( icm_aux_len - 1 ) );
- memset ( &map_icm_aux, 0, sizeof ( map_icm_aux ) );
- MLX_FILL_2 ( &map_icm_aux, 3,
- log2size, fls ( ( icm_aux_len / HERMON_PAGE_SIZE ) - 1 ),
- pa_l, ( icm_phys >> 12 ) );
- DBGC ( hermon, "Hermon %p mapping ICM AUX (2^%d pages) => %08lx\n",
- hermon, fls ( ( icm_aux_len / HERMON_PAGE_SIZE ) - 1 ),
- icm_phys );
- if ( ( rc = hermon_cmd_map_icm_aux ( hermon, &map_icm_aux ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p mapping ICM AUX => %08lx\n",
+ hermon, icm_phys );
+ if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_icm_aux,
+ 0, icm_phys, icm_aux_len ) ) != 0 ) {
DBGC ( hermon, "Hermon %p could not map AUX ICM: %s\n",
- hermon, strerror ( rc ) );
+ hermon, strerror ( rc ) );
goto err_map_icm_aux;
}
icm_phys += icm_aux_len;
/* MAP ICM area */
for ( i = 0 ; i < HERMON_ICM_NUM_REGIONS ; i++ ) {
- memset ( &map_icm, 0, sizeof ( map_icm ) );
- MLX_FILL_1 ( &map_icm, 0,
- va_h, ( hermon->icm_map[i].offset >> 32 ) );
- MLX_FILL_1 ( &map_icm, 1,
- va_l, ( hermon->icm_map[i].offset >> 12 ) );
- MLX_FILL_2 ( &map_icm, 3,
- log2size,
- fls ( ( hermon->icm_map[i].len /
- HERMON_PAGE_SIZE ) - 1 ),
- pa_l, ( icm_phys >> 12 ) );
- DBGC ( hermon, "Hermon %p mapping ICM %llx+%zx (2^%d pages) "
- "=> %08lx\n", hermon, hermon->icm_map[i].offset,
- hermon->icm_map[i].len,
- fls ( ( hermon->icm_map[i].len /
- HERMON_PAGE_SIZE ) - 1 ), icm_phys );
- if ( ( rc = hermon_cmd_map_icm ( hermon, &map_icm ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p mapping ICM %llx+%zx => %08lx\n",
+ hermon, hermon->icm_map[i].offset,
+ hermon->icm_map[i].len, icm_phys );
+ if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_icm,
+ hermon->icm_map[i].offset,
+ icm_phys,
+ hermon->icm_map[i].len ) ) != 0 ){
DBGC ( hermon, "Hermon %p could not map ICM: %s\n",
hermon, strerror ( rc ) );
goto err_map_icm;
@@ -2058,8 +2073,8 @@ static int hermon_alloc_icm ( struct hermon *hermon,
err_map_icm:
assert ( i == 0 ); /* We don't handle partial failure at present */
- hermon_cmd_unmap_icm_aux ( hermon );
err_map_icm_aux:
+ hermon_cmd_unmap_icm_aux ( hermon );
ufree ( hermon->icm );
hermon->icm = UNULL;
err_alloc:
@@ -2237,9 +2252,9 @@ static int hermon_probe ( struct pci_device *pci,
return 0;
- i = ( HERMON_NUM_PORTS - 1 );
+ i = HERMON_NUM_PORTS;
err_register_ibdev:
- for ( ; i >= 0 ; i-- )
+ for ( i-- ; i >= 0 ; i-- )
unregister_ibdev ( hermon->ibdev[i] );
hermon_destroy_eq ( hermon );
err_create_eq:
@@ -2255,9 +2270,9 @@ static int hermon_probe ( struct pci_device *pci,
err_mailbox_out:
free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
err_mailbox_in:
- i = ( HERMON_NUM_PORTS - 1 );
+ i = HERMON_NUM_PORTS;
err_alloc_ibdev:
- for ( ; i >= 0 ; i-- )
+ for ( i-- ; i >= 0 ; i-- )
ibdev_put ( hermon->ibdev[i] );
free ( hermon );
err_alloc_hermon:
diff --git a/gpxe/src/drivers/net/tg3.c b/gpxe/src/drivers/net/tg3.c
index 82b37fab..bda832e8 100644
--- a/gpxe/src/drivers/net/tg3.c
+++ b/gpxe/src/drivers/net/tg3.c
@@ -3397,6 +3397,7 @@ PCI_ROM(0x14e4, 0x165d, "tg3-5705M", "Broadcom Tigon 3 5705M"),
PCI_ROM(0x14e4, 0x165e, "tg3-5705M_2", "Broadcom Tigon 3 5705M_2"),
PCI_ROM(0x14e4, 0x1677, "tg3-5751", "Broadcom Tigon 3 5751"),
PCI_ROM(0x14e4, 0x167a, "tg3-5754", "Broadcom Tigon 3 5754"),
+PCI_ROM(0x14e4, 0x1693, "tg3-5787", "Broadcom Tigon 3 5787"),
PCI_ROM(0x14e4, 0x1696, "tg3-5782", "Broadcom Tigon 3 5782"),
PCI_ROM(0x14e4, 0x169c, "tg3-5788", "Broadcom Tigon 3 5788"),
PCI_ROM(0x14e4, 0x169d, "tg3-5789", "Broadcom Tigon 3 5789"),
diff --git a/gpxe/src/net/tcp/iscsi.c b/gpxe/src/net/tcp/iscsi.c
index 01a46584..e9e36449 100644
--- a/gpxe/src/net/tcp/iscsi.c
+++ b/gpxe/src/net/tcp/iscsi.c
@@ -1625,25 +1625,28 @@ enum iscsi_root_path_component {
*/
static int iscsi_parse_lun ( struct iscsi_session *iscsi,
const char *lun_string ) {
- char *p = ( char * ) lun_string;
union {
uint64_t u64;
uint16_t u16[4];
} lun;
+ char *p;
int i;
- /* Empty LUN; assume LUN 0 */
- if ( ! *lun_string )
- return 0;
-
- for ( i = 0 ; i < 4 ; i++ ) {
- lun.u16[i] = strtoul ( p, &p, 16 );
- if ( *p != '-' )
+ memset ( &lun, 0, sizeof ( lun ) );
+ if ( lun_string ) {
+ p = ( char * ) lun_string;
+
+ for ( i = 0 ; i < 4 ; i++ ) {
+ lun.u16[i] = htons ( strtoul ( p, &p, 16 ) );
+ if ( *p == '\0' )
+ break;
+ if ( *p != '-' )
+ return -EINVAL;
+ p++;
+ }
+ if ( *p )
return -EINVAL;
- p++;
}
- if ( *p )
- return -EINVAL;
iscsi->lun = lun.u64;
return 0;