From a40e933b79efe6349151092b3080d2547a9f69b9 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 1 Oct 2008 11:47:20 -0700 Subject: [PATCH] gPXE: merge gPXE 0.9.5 Merge gPXE 0.9.5 gpxe 8c3e95ce420c21e612dbed58fd74dbb01025643f gpxe-for-syslinux 1982e507d0159d83a542224d4203e964bbd16f7d Signed-off-by: H. Peter Anvin --- gpxe/VERSION | 2 +- gpxe/src/Makefile | 4 +- gpxe/src/Makefile.housekeeping | 12 +-- gpxe/src/arch/i386/core/dumpregs.c | 23 +++++ gpxe/src/arch/i386/core/gdbmach.c | 4 +- gpxe/src/arch/i386/firmware/pcbios/e820mangler.S | 61 +++++++++--- gpxe/src/arch/i386/firmware/pcbios/memmap.c | 46 ++++++++- gpxe/src/drivers/infiniband/arbel.c | 8 +- gpxe/src/drivers/infiniband/hermon.c | 117 +++++++++++++---------- gpxe/src/drivers/net/tg3.c | 1 + gpxe/src/net/tcp/iscsi.c | 25 ++--- 11 files changed, 209 insertions(+), 94 deletions(-) create mode 100644 gpxe/src/arch/i386/core/dumpregs.c diff --git a/gpxe/VERSION b/gpxe/VERSION index 02f4fc9..010605b 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 474e8cf..6c42da6 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 17df25f..9e11ceb 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 0000000..89426d5 --- /dev/null +++ b/gpxe/src/arch/i386/core/dumpregs.c @@ -0,0 +1,23 @@ +#include +#include + +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 26fab60..5e72e4d 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 ad773f7..4fbd656 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 e6d6428..9de10a7 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 0c18083..1b55131 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 9716aba..3ca6003 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 82b37fa..bda832e 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 01a4658..e9e3644 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; -- 2.7.4