From owner-p4-projects@FreeBSD.ORG Tue Nov 14 17:19:11 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C002416A412; Tue, 14 Nov 2006 17:19:11 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7AC0E16A403 for ; Tue, 14 Nov 2006 17:19:11 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 46AFD43D53 for ; Tue, 14 Nov 2006 17:19:11 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kAEHJBm6093112 for ; Tue, 14 Nov 2006 17:19:11 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kAEHJAxh093109 for perforce@freebsd.org; Tue, 14 Nov 2006 17:19:10 GMT (envelope-from jhb@freebsd.org) Date: Tue, 14 Nov 2006 17:19:10 GMT Message-Id: <200611141719.kAEHJAxh093109@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 109943 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Nov 2006 17:19:12 -0000 http://perforce.freebsd.org/chv.cgi?CH=109943 Change 109943 by jhb@jhb_mutex on 2006/11/14 17:18:19 IFC @109941. Affected files ... .. //depot/projects/smpng/sys/amd64/amd64/local_apic.c#25 integrate .. //depot/projects/smpng/sys/amd64/amd64/mptable_pci.c#5 integrate .. //depot/projects/smpng/sys/amd64/amd64/msi.c#1 branch .. //depot/projects/smpng/sys/amd64/amd64/nexus.c#20 integrate .. //depot/projects/smpng/sys/amd64/include/apicvar.h#14 integrate .. //depot/projects/smpng/sys/amd64/include/intr_machdep.h#10 integrate .. //depot/projects/smpng/sys/amd64/pci/pci_bus.c#17 integrate .. //depot/projects/smpng/sys/conf/files.amd64#49 integrate .. //depot/projects/smpng/sys/conf/files.i386#104 integrate .. //depot/projects/smpng/sys/conf/files.pc98#86 integrate .. //depot/projects/smpng/sys/dev/isp/isp.c#46 integrate .. //depot/projects/smpng/sys/dev/isp/isp_freebsd.c#48 integrate .. //depot/projects/smpng/sys/dev/isp/isp_freebsd.h#34 integrate .. //depot/projects/smpng/sys/dev/isp/isp_library.c#6 integrate .. //depot/projects/smpng/sys/dev/isp/isp_library.h#3 integrate .. //depot/projects/smpng/sys/dev/isp/isp_pci.c#42 integrate .. //depot/projects/smpng/sys/dev/isp/isp_stds.h#2 integrate .. //depot/projects/smpng/sys/dev/isp/ispvar.h#33 integrate .. //depot/projects/smpng/sys/dev/mfi/mfi.c#12 integrate .. //depot/projects/smpng/sys/dev/mfi/mfi_ioctl.h#3 integrate .. //depot/projects/smpng/sys/dev/mfi/mfi_linux.c#2 integrate .. //depot/projects/smpng/sys/i386/i386/local_apic.c#46 integrate .. //depot/projects/smpng/sys/i386/i386/mptable_pci.c#5 integrate .. //depot/projects/smpng/sys/i386/i386/msi.c#1 branch .. //depot/projects/smpng/sys/i386/i386/nexus.c#21 integrate .. //depot/projects/smpng/sys/i386/include/apicvar.h#23 integrate .. //depot/projects/smpng/sys/i386/include/intr_machdep.h#12 integrate .. //depot/projects/smpng/sys/i386/pci/pci_bus.c#30 integrate .. //depot/projects/smpng/sys/kern/sched_4bsd.c#63 integrate .. //depot/projects/smpng/sys/sys/elf_common.h#9 integrate .. //depot/projects/smpng/sys/sys/lock_profile.h#2 integrate .. //depot/projects/smpng/sys/sys/mbuf.h#66 integrate Differences ... ==== //depot/projects/smpng/sys/amd64/amd64/local_apic.c#25 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.32 2006/10/10 23:23:11 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.33 2006/11/13 22:23:32 jhb Exp $"); #include "opt_hwpmc_hooks.h" @@ -744,6 +744,65 @@ panic("Couldn't find an APIC vector for IRQ %u", irq); } +/* + * Request 'count' free contiguous IDT vectors to be used by 'count' + * IRQs. 'count' must be a power of two and the vectors will be + * aligned on a boundary of 'align'. If the request cannot be + * satisfied, 0 is returned. + */ +u_int +apic_alloc_vectors(u_int *irqs, u_int count, u_int align) +{ + u_int first, run, vector; + + KASSERT(powerof2(count), ("bad count")); + KASSERT(powerof2(align), ("bad align")); + KASSERT(align >= count, ("align < count")); +#ifdef INVARIANTS + for (run = 0; run < count; run++) + KASSERT(irqs[run] < NUM_IO_INTS, ("Invalid IRQ %u at index %u", + irqs[run], run)); +#endif + + /* + * Search for 'count' free vectors. As with apic_alloc_vector(), + * this just uses a simple first fit algorithm. + */ + run = 0; + first = 0; + mtx_lock_spin(&icu_lock); + for (vector = 0; vector < APIC_NUM_IOINTS; vector++) { + + /* Vector is in use, end run. */ + if (ioint_irqs[vector] != 0) { + run = 0; + first = 0; + continue; + } + + /* Start a new run if run == 0 and vector is aligned. */ + if (run == 0) { + if ((vector & (align - 1)) != 0) + continue; + first = vector; + } + run++; + + /* Keep looping if the run isn't long enough yet. */ + if (run < count) + continue; + + /* Found a run, assign IRQs and return the first vector. */ + for (vector = 0; vector < count; vector++) + ioint_irqs[first + vector] = irqs[vector]; + mtx_unlock_spin(&icu_lock); + return (first + APIC_IO_INTS); + } + mtx_unlock_spin(&icu_lock); + printf("APIC: Couldn't find APIC vectors for %u IRQs\n", count); + return (0); +} + void apic_enable_vector(u_int vector) { @@ -1002,6 +1061,9 @@ intr_register_pic(&lapic_pic); if (bootverbose) lapic_dump("BSP"); + + /* Enable the MSI "pic". */ + msi_init(); } SYSINIT(apic_setup_io, SI_SUB_INTR, SI_ORDER_SECOND, apic_setup_io, NULL) ==== //depot/projects/smpng/sys/amd64/amd64/mptable_pci.c#5 (text+ko) ==== @@ -33,7 +33,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable_pci.c,v 1.4 2006/01/06 19:22:18 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable_pci.c,v 1.5 2006/11/13 22:23:32 jhb Exp $"); #include #include @@ -96,6 +96,10 @@ DEVMETHOD(pcib_read_config, legacy_pcib_read_config), DEVMETHOD(pcib_write_config, legacy_pcib_write_config), DEVMETHOD(pcib_route_interrupt, mptable_pci_route_interrupt), + DEVMETHOD(pcib_alloc_msi, pcib_alloc_msi), + DEVMETHOD(pcib_release_msi, pcib_release_msi), + DEVMETHOD(pcib_alloc_msix, pcib_alloc_msix), + DEVMETHOD(pcib_release_msix, pcib_release_msix), { 0, 0 } }; @@ -148,6 +152,10 @@ DEVMETHOD(pcib_read_config, pcib_read_config), DEVMETHOD(pcib_write_config, pcib_write_config), DEVMETHOD(pcib_route_interrupt, mptable_pci_route_interrupt), + DEVMETHOD(pcib_alloc_msi, pcib_alloc_msi), + DEVMETHOD(pcib_release_msi, pcib_release_msi), + DEVMETHOD(pcib_alloc_msix, pcib_alloc_msix), + DEVMETHOD(pcib_release_msix, pcib_release_msix), {0, 0} }; ==== //depot/projects/smpng/sys/amd64/amd64/nexus.c#20 (text+ko) ==== @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/nexus.c,v 1.69 2006/09/11 19:31:51 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/nexus.c,v 1.70 2006/11/13 22:23:32 jhb Exp $"); /* * This code implements a `root nexus' for Intel Architecture @@ -61,6 +61,8 @@ #include +#include "pcib_if.h" + #ifdef DEV_ISA #include #include @@ -100,6 +102,10 @@ static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); static void nexus_delete_resource(device_t, device_t, int, int); +static int nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs); +static int nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs); +static int nexus_alloc_msix(device_t pcib, device_t dev, int index, int *irq); +static int nexus_release_msix(device_t pcib, device_t dev, int irq); static device_method_t nexus_methods[] = { /* Device interface */ @@ -125,6 +131,12 @@ DEVMETHOD(bus_get_resource, nexus_get_resource), DEVMETHOD(bus_delete_resource, nexus_delete_resource), + /* pcib interface */ + DEVMETHOD(pcib_alloc_msi, nexus_alloc_msi), + DEVMETHOD(pcib_release_msi, nexus_release_msi), + DEVMETHOD(pcib_alloc_msix, nexus_alloc_msix), + DEVMETHOD(pcib_release_msix, nexus_release_msix), + { 0, 0 } }; @@ -504,6 +516,47 @@ resource_list_delete(rl, type, rid); } +static int +nexus_alloc_msix(device_t pcib, device_t dev, int index, int *irq) +{ + int error, new; + + error = msix_alloc(dev, index, irq, &new); + if (new) + rman_manage_region(&irq_rman, *irq, *irq); + return (error); +} + +static int +nexus_release_msix(device_t pcib, device_t dev, int irq) +{ + + return (msix_release(irq)); +} + +static int +nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) +{ + int error, i, newirq, newcount; + + /* First alloc the messages. */ + error = msi_alloc(dev, count, maxcount, irqs, &newirq, &newcount); + + /* Always add any new IRQs to the rman, even on failure. */ + for (i = 0; i < newcount; i++) + rman_manage_region(&irq_rman, irqs[newirq + i], + irqs[newirq + i]); + + return (error); +} + +static int +nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs) +{ + + return (msi_release(irqs, count)); +} + #ifdef DEV_ISA /* * Placeholder which claims PnP 'devices' which describe system ==== //depot/projects/smpng/sys/amd64/include/apicvar.h#14 (text+ko) ==== @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/include/apicvar.h,v 1.19 2006/10/10 23:23:11 jhb Exp $ + * $FreeBSD: src/sys/amd64/include/apicvar.h,v 1.20 2006/11/13 22:23:33 jhb Exp $ */ #ifndef _MACHINE_APICVAR_H_ @@ -175,6 +175,7 @@ IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint); u_int apic_alloc_vector(u_int irq); +u_int apic_alloc_vectors(u_int *irqs, u_int count, u_int align); void apic_enable_vector(u_int vector); void apic_free_vector(u_int vector, u_int irq); u_int apic_idt_to_irq(u_int vector); ==== //depot/projects/smpng/sys/amd64/include/intr_machdep.h#10 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/include/intr_machdep.h,v 1.11 2006/10/10 23:23:11 jhb Exp $ + * $FreeBSD: src/sys/amd64/include/intr_machdep.h,v 1.12 2006/11/13 22:23:33 jhb Exp $ */ #ifndef __MACHINE_INTR_MACHDEP_H__ @@ -43,11 +43,18 @@ * 191 and still be safe since only interrupt sources in actual use will * allocate IDT vectors. * - * For now we stick with 255 as ISA IRQs and PCI intline IRQs only allow - * for IRQs in the range 0 - 254. When MSI support is added this number - * will likely increase. + * The first 255 IRQs (0 - 254) are reserved for ISA IRQs and PCI intline IRQs. + * IRQ values beyond 256 are used by MSI. We leave 255 unused to avoid + * confusion since 255 is used in PCI to indicate an invalid IRQ. + */ +#define NUM_MSI_INTS 128 +#define FIRST_MSI_INT 256 +#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS) + +/* + * Default base address for MSI messages on x86 platforms. */ -#define NUM_IO_INTS 255 +#define MSI_INTEL_ADDR_BASE 0xfee00000 /* * - 1 ??? dummy counter. @@ -140,6 +147,12 @@ void intr_resume(void); void intr_suspend(void); void intrcnt_add(const char *name, u_long **countp); +void msi_init(void); +int msi_alloc(device_t dev, int count, int maxcount, int *irqs, int *newirq, + int *newcount); +int msi_release(int *irqs, int count); +int msix_alloc(device_t dev, int index, int *irq, int *new); +int msix_release(int irq); #endif /* !LOCORE */ #endif /* _KERNEL */ ==== //depot/projects/smpng/sys/amd64/pci/pci_bus.c#17 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/pci/pci_bus.c,v 1.117 2006/03/13 23:58:40 peter Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/pci/pci_bus.c,v 1.118 2006/11/13 22:23:33 jhb Exp $"); #include "opt_cpu.h" @@ -322,6 +322,10 @@ DEVMETHOD(pcib_read_config, legacy_pcib_read_config), DEVMETHOD(pcib_write_config, legacy_pcib_write_config), DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt), + DEVMETHOD(pcib_alloc_msi, pcib_alloc_msi), + DEVMETHOD(pcib_release_msi, pcib_release_msi), + DEVMETHOD(pcib_alloc_msix, pcib_alloc_msix), + DEVMETHOD(pcib_release_msix, pcib_release_msix), { 0, 0 } }; ==== //depot/projects/smpng/sys/conf/files.amd64#49 (text+ko) ==== @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $FreeBSD: src/sys/conf/files.amd64,v 1.98 2006/10/29 14:02:39 netchild Exp $ +# $FreeBSD: src/sys/conf/files.amd64,v 1.99 2006/11/13 22:23:33 jhb Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -114,6 +114,7 @@ amd64/amd64/mpboot.S optional smp amd64/amd64/mptable.c optional mptable amd64/amd64/mptable_pci.c optional mptable pci +amd64/amd64/msi.c optional pci amd64/amd64/nexus.c standard amd64/amd64/pmap.c standard amd64/amd64/prof_machdep.c optional profiling-routine ==== //depot/projects/smpng/sys/conf/files.i386#104 (text+ko) ==== @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $FreeBSD: src/sys/conf/files.i386,v 1.570 2006/10/29 14:02:39 netchild Exp $ +# $FreeBSD: src/sys/conf/files.i386,v 1.571 2006/11/13 22:23:33 jhb Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -294,6 +294,7 @@ i386/i386/mpboot.s optional smp i386/i386/mptable.c optional apic i386/i386/mptable_pci.c optional apic pci +i386/i386/msi.c optional apic pci i386/i386/nexus.c standard i386/i386/perfmon.c optional perfmon i386/i386/pmap.c standard ==== //depot/projects/smpng/sys/conf/files.pc98#86 (text+ko) ==== @@ -3,7 +3,7 @@ # # modified for PC-9801/PC-9821 # -# $FreeBSD: src/sys/conf/files.pc98,v 1.349 2006/10/29 14:02:39 netchild Exp $ +# $FreeBSD: src/sys/conf/files.pc98,v 1.350 2006/11/14 14:28:09 ru Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -176,6 +176,7 @@ i386/i386/mpboot.s optional smp i386/i386/mptable.c optional apic i386/i386/mptable_pci.c optional apic pci +i386/i386/msi.c optional apic pci i386/i386/nexus.c standard i386/i386/perfmon.c optional perfmon i386/i386/pmap.c standard ==== //depot/projects/smpng/sys/dev/isp/isp.c#46 (text+ko) ==== @@ -42,7 +42,7 @@ #endif #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: src/sys/dev/isp/isp.c,v 1.128 2006/11/02 03:21:30 mjacob Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/isp/isp.c,v 1.129 2006/11/14 08:45:47 mjacob Exp $"); #include #endif #ifdef __OpenBSD__ @@ -60,6 +60,9 @@ */ #define MBOX_DELAY_COUNT 1000000 / 100 +#define ISP_MARK_PORTDB(a, b) \ + isp_prt(isp, ISP_LOGSANCFG, "line %d: markportdb", __LINE__); \ + isp_mark_portdb(a, b) /* * Local static data @@ -109,7 +112,6 @@ static void isp_scsi_channel_init(ispsoftc_t *, int); static void isp_fibre_init(ispsoftc_t *); static void isp_fibre_init_2400(ispsoftc_t *); -static void isp_dump_portdb(ispsoftc_t *); static void isp_mark_portdb(ispsoftc_t *, int); static void isp_plogx_24xx(ispsoftc_t *, uint16_t, uint32_t, int *); static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t); @@ -117,7 +119,7 @@ static int isp_getpdb(ispsoftc_t *, uint16_t, isp_pdb_t *, int); static uint64_t isp_get_portname(ispsoftc_t *, int, int); static int isp_fclink_test(ispsoftc_t *, int); -static const char *isp2100_fw_statename(int); +static const char *ispfc_fw_statename(int); static int isp_pdb_sync(ispsoftc_t *); static int isp_scan_loop(ispsoftc_t *); static int isp_gid_ft_sns(ispsoftc_t *); @@ -1173,7 +1175,7 @@ /* * Do this *before* initializing the firmware. */ - isp_mark_portdb(isp, 0); + ISP_MARK_PORTDB(isp, 0); FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; FCPARAM(isp)->isp_loopstate = LOOP_NIL; @@ -2047,53 +2049,6 @@ isp->isp_state = ISP_INITSTATE; } -/* - * Fibre Channel Support- get the port database for the id. - */ -static void -isp_dump_portdb(ispsoftc_t *isp) -{ - fcparam *fcp = (fcparam *) isp->isp_param; - int i; - - for (i = 0; i < MAX_FC_TARG; i++) { - char mb[4]; - const char *dbs[8] = { - "NIL ", - "PROB", - "DEAD", - "CHGD", - "NEW ", - "PVLD", - "????", - "VLD " - }; - const char *roles[4] = { - " UNK", " TGT", " INI", "TINI" - }; - fcportdb_t *lp = &fcp->portdb[i]; - - if (lp->state == FC_PORTDB_STATE_NIL) { - continue; - } - if (lp->ini_map_idx) { - SNPRINTF(mb, sizeof (mb), "%3d", - ((int) lp->ini_map_idx) - 1); - } else { - SNPRINTF(mb, sizeof (mb), "---"); - } - isp_prt(isp, ISP_LOGALL, "%d: %s al%d tgt %s %s 0x%06x =>%s" - " 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x", i, - dbs[lp->state], lp->autologin, mb, - roles[lp->roles], lp->portid, - roles[lp->new_roles], lp->new_portid, - (uint32_t) (lp->node_wwn >> 32), - (uint32_t) (lp->node_wwn), - (uint32_t) (lp->port_wwn >> 32), - (uint32_t) (lp->port_wwn)); - } -} - static void isp_mark_portdb(ispsoftc_t *isp, int onprobation) { @@ -2101,7 +2056,6 @@ int i; for (i = 0; i < MAX_FC_TARG; i++) { - fcp->isp_ini_map[i] = 0; if (onprobation == 0) { MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); } else { @@ -2113,6 +2067,8 @@ fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL; break; + case FC_PORTDB_STATE_ZOMBIE: + break; case FC_PORTDB_STATE_NIL: default: MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); @@ -2167,6 +2123,7 @@ mbs.param[6] = DMA_WD3(FCPARAM(isp)->isp_scdma); mbs.param[7] = DMA_WD2(FCPARAM(isp)->isp_scdma); mbs.logval = MBLOGALL; + mbs.timeout = 250000; MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -2276,6 +2233,7 @@ mbs.param[3] = portid; mbs.logval = MBLOGNONE; + mbs.timeout = 250000; isp_mboxcmd(isp, &mbs); switch (mbs.param[0]) { @@ -2463,8 +2421,8 @@ fcp = isp->isp_param; - isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Entry"); - isp_mark_portdb(isp, 1); + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Entry"); + ISP_MARK_PORTDB(isp, 1); /* * Wait up to N microseconds for F/W to go to a ready state. @@ -2479,9 +2437,10 @@ GET_NANOTIME(&hra); isp_fw_state(isp); if (lwfs != fcp->isp_fwstate) { - isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>", - isp2100_fw_statename((int)lwfs), - isp2100_fw_statename((int)fcp->isp_fwstate)); + isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG, + "Firmware State <%s->%s>", + ispfc_fw_statename((int)lwfs), + ispfc_fw_statename((int)fcp->isp_fwstate)); lwfs = fcp->isp_fwstate; } if (fcp->isp_fwstate == FW_READY) { @@ -2533,7 +2492,7 @@ * If we haven't gone to 'ready' state, return. */ if (fcp->isp_fwstate != FW_READY) { - isp_prt(isp, ISP_LOGDEBUG0, + isp_prt(isp, ISP_LOGSANCFG, "isp_fclink_test: not at FW_READY state"); return (-1); } @@ -2645,19 +2604,19 @@ /* * Announce ourselves, too. */ - isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_portid, + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, fcp->isp_portid, fcp->isp_loopid, toponames[fcp->isp_topo]); - isp_prt(isp, ISP_LOGCONFIG, ourwwn, + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, ourwwn, (uint32_t) (ISP_NODEWWN(isp) >> 32), (uint32_t) ISP_NODEWWN(isp), (uint32_t) (ISP_PORTWWN(isp) >> 32), (uint32_t) ISP_PORTWWN(isp)); - isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Complete"); + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Complete"); return (0); } static const char * -isp2100_fw_statename(int state) +ispfc_fw_statename(int state) { switch(state) { case FW_CONFIG_WAIT: return "Config Wait"; @@ -2736,6 +2695,8 @@ } } + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Synchronizing PDBs"); + fcp->isp_loopstate = LOOP_SYNCING_PDB; for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { @@ -2757,12 +2718,11 @@ switch (lp->state) { case FC_PORTDB_STATE_PROBATIONAL: case FC_PORTDB_STATE_DEAD: + /* + * It's up to the outer layers to clear isp_ini_map. + */ + lp->state = FC_PORTDB_STATE_NIL; isp_async(isp, ISPASYNC_DEV_GONE, lp); - if (lp->ini_map_idx) { - fcp->isp_ini_map[lp->ini_map_idx-1] = 0; - lp->ini_map_idx = 0; - } - lp->state = FC_PORTDB_STATE_NIL; if (lp->autologin == 0) { if (IS_24XX(isp)) { int action = @@ -2782,68 +2742,57 @@ } lp->new_roles = 0; lp->new_portid = 0; + /* + * Note that we might come out of this with our state + * set to FC_PORTDB_STATE_ZOMBIE. + */ break; case FC_PORTDB_STATE_NEW: /* - * If *we* have a new target dole and *it* has a target - * role, assign a new target id to it. + * It's up to the outer layers to assign a virtual + * target id in isp_ini_map (if any). */ lp->portid = lp->new_portid; lp->roles = lp->new_roles; lp->state = FC_PORTDB_STATE_VALID; - if ((isp->isp_role & ISP_ROLE_INITIATOR) && - (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) { - int i, t = dbidx; - for (i = 0; i < MAX_FC_TARG; i++) { - if (i < FL_ID || i > SNS_ID) { - if (fcp->isp_ini_map[t] == 0) { - break; - } - } - if (++t == MAX_FC_TARG) { - t = 0; - } - } - if (i < MAX_FC_TARG) { - fcp->isp_ini_map[t] = dbidx + 1; - lp->ini_map_idx = t + 1; - } else { - isp_prt(isp, ISP_LOGWARN, - "out of target ids"); - } - } isp_async(isp, ISPASYNC_DEV_ARRIVED, lp); lp->new_roles = 0; lp->new_portid = 0; + lp->reserved = 0; + lp->new_reserved = 0; break; case FC_PORTDB_STATE_CHANGED: - lp->portid = lp->new_portid; - lp->roles = lp->new_roles; +/* + * XXXX FIX THIS + */ lp->state = FC_PORTDB_STATE_VALID; - if (lp->ini_map_idx) { - int t = lp->ini_map_idx - 1; - fcp->isp_ini_map[t] = dbidx + 1; - } isp_async(isp, ISPASYNC_DEV_CHANGED, lp); lp->new_roles = 0; lp->new_portid = 0; + lp->reserved = 0; + lp->new_reserved = 0; break; case FC_PORTDB_STATE_PENDING_VALID: lp->portid = lp->new_portid; lp->roles = lp->new_roles; - lp->state = FC_PORTDB_STATE_VALID; if (lp->ini_map_idx) { int t = lp->ini_map_idx - 1; fcp->isp_ini_map[t] = dbidx + 1; } + lp->state = FC_PORTDB_STATE_VALID; isp_async(isp, ISPASYNC_DEV_STAYED, lp); if (dbidx != FL_ID) { lp->new_roles = 0; lp->new_portid = 0; } + lp->reserved = 0; + lp->new_reserved = 0; + break; + case FC_PORTDB_STATE_ZOMBIE: break; default: - isp_prt(isp, ISP_LOGERR, "eh? state %d for idx %d", + isp_prt(isp, ISP_LOGWARN, + "isp_scan_loop: state %d for idx %d", lp->state, dbidx); isp_dump_portdb(isp); } @@ -2869,7 +2818,7 @@ fcparam *fcp = isp->isp_param; int i; isp_pdb_t pdb; - uint16_t dbidx, lim = 0; + uint16_t handle, lim = 0; if (fcp->isp_fwstate < FW_READY || fcp->isp_loopstate < LOOP_PDB_RCVD) { @@ -2906,17 +2855,18 @@ } fcp->isp_loopstate = LOOP_SCANNING_LOOP; - isp_prt(isp, ISP_LOGDEBUG0, "scanning loop 0..%d", lim-1); + + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC scan loop 0..%d", lim-1); /* * Run through the list and get the port database info for each one. */ - for (dbidx = 0; dbidx < lim; dbidx++) { + for (handle = 0; handle < lim; handle++) { /* * But don't even try for ourselves... */ - if (dbidx == fcp->isp_loopid) { + if (handle == fcp->isp_loopid) { continue; } @@ -2925,7 +2875,7 @@ * known to hang. This trick gets around that problem. */ if (IS_2100(isp) || IS_2200(isp)) { - uint64_t node_wwn = isp_get_portname(isp, dbidx, 1); + uint64_t node_wwn = isp_get_portname(isp, handle, 1); if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { return (-1); } @@ -2937,29 +2887,29 @@ /* * Get the port database entity for this index. */ - if (isp_getpdb(isp, dbidx, &pdb, 1) != 0) { + if (isp_getpdb(isp, handle, &pdb, 1) != 0) { if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { - isp_mark_portdb(isp, 1); + ISP_MARK_PORTDB(isp, 1); return (-1); } continue; } if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { - isp_mark_portdb(isp, 1); + ISP_MARK_PORTDB(isp, 1); return (-1); } /* * On *very* old 2100 firmware we would end up sometimes * with the firmware returning the port database entry - * for something else. We used to restart locally, but - * now we punt. + * for something else. We used to restart this, but + * now we just punt. */ - if (IS_2100(isp) && pdb.handle != dbidx) { + if (IS_2100(isp) && pdb.handle != handle) { isp_prt(isp, ISP_LOGWARN, "giving up on synchronizing the port database"); - isp_mark_portdb(isp, 1); + ISP_MARK_PORTDB(isp, 1); return (-1); } @@ -2978,8 +2928,7 @@ * which shift on a loop. */ if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) { - isp_prt(isp, ISP_LOGWARN, - "bad pdb entry at loop %d", dbidx); + isp_prt(isp, ISP_LOGWARN, "bad pdb @ loop %d", handle); isp_dump_portdb(isp); continue; } @@ -3002,22 +2951,27 @@ /* * Okay- we've found a non-nil entry that matches. - * Check to make sure it's probational. + * Check to make sure it's probational or a zombie. */ - if (lp->state != FC_PORTDB_STATE_PROBATIONAL) { + if (lp->state != FC_PORTDB_STATE_PROBATIONAL && + lp->state != FC_PORTDB_STATE_ZOMBIE) { isp_prt(isp, ISP_LOGERR, - "portdb entry %d not probational (0x%x)", + "[%d] not probational/zombie (0x%x)", i, lp->state); isp_dump_portdb(isp); - isp_mark_portdb(isp, 1); + ISP_MARK_PORTDB(isp, 1); return (-1); } + /* + * Mark the device as something the f/w logs into + * automatically. + */ lp->autologin = 1; + /* - * Check to make sure it's really the same - * device and update the initiator map before - * we mark it as pending valid. + * Check to make see if really still the same + * device. If it is, we mark it pending valid. */ if (lp->portid == tmp.portid && lp->handle == tmp.handle && @@ -3025,12 +2979,15 @@ lp->new_portid = tmp.portid; lp->new_roles = tmp.roles; lp->state = FC_PORTDB_STATE_PENDING_VALID; + isp_prt(isp, ISP_LOGSANCFG, + "Loop Port 0x%06x@0x%x Pending Valid", + tmp.portid, tmp.handle); break; } /* - * We can wipe out the old handle value here because - * it's no longer valid. + * We can wipe out the old handle value + * here because it's no longer valid. */ lp->handle = tmp.handle; @@ -3038,6 +2995,9 @@ * Claim that this has changed and let somebody else * decide what to do. */ + isp_prt(isp, ISP_LOGSANCFG, + "Loop Port 0x%06x@0x%x changed", + tmp.portid, tmp.handle); lp->state = FC_PORTDB_STATE_CHANGED; lp->new_portid = tmp.portid; lp->new_roles = tmp.roles; @@ -3061,23 +3021,23 @@ } } if (i == MAX_FC_TARG) { - isp_prt(isp, ISP_LOGERR, - "could not find slot for new entry"); + isp_prt(isp, ISP_LOGERR, "out of portdb entries"); continue; } lp = &fcp->portdb[i]; + MEMZERO(lp, sizeof (fcportdb_t)); lp->autologin = 1; lp->state = FC_PORTDB_STATE_NEW; - lp->portid = 0; - lp->roles = 0; lp->new_portid = tmp.portid; lp->new_roles = tmp.roles; lp->handle = tmp.handle; lp->port_wwn = tmp.port_wwn; lp->node_wwn = tmp.node_wwn; + isp_prt(isp, ISP_LOGSANCFG, + "Loop Port 0x%06x@0x%x is New Entry", + tmp.portid, tmp.handle); } - fcp->isp_loopstate = LOOP_LSCAN_DONE; return (0); } @@ -3258,7 +3218,7 @@ int portidx, portlim, r; sns_gid_ft_rsp_t *rs0, *rs1; - isp_prt(isp, ISP_LOGDEBUG0, "FC Scan Fabric"); + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Scan Fabric"); if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate < LOOP_LSCAN_DONE) { return (-1); @@ -3268,7 +3228,8 @@ } if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) { fcp->isp_loopstate = LOOP_FSCAN_DONE; - isp_prt(isp, ISP_LOGDEBUG0, "FC Scan Fabric Done (no fabric)"); + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, + "FC Scan Fabric Done (no fabric)"); return (0); } @@ -3303,7 +3264,7 @@ int level; if (rs1->snscb_cthdr.ct_reason == 9 && rs1->snscb_cthdr.ct_explanation == 7) { - level = ISP_LOGDEBUG0; + level = ISP_LOGSANCFG|ISP_LOGDEBUG0; } else { level = ISP_LOGWARN; } @@ -3348,8 +3309,8 @@ "fabric too big for scratch area: increase ISP2100_SCRLEN"); } portlim = portidx + 1; - isp_prt(isp, ISP_LOGDEBUG0, "got %d ports back from name server", - portlim); + isp_prt(isp, ISP_LOGSANCFG, + "got %d ports back from name server", portlim); for (portidx = 0; portidx < portlim; portidx++) { int npidx; @@ -3373,7 +3334,7 @@ rs1->snscb_ports[npidx].portid[0] = 0; rs1->snscb_ports[npidx].portid[1] = 0; rs1->snscb_ports[npidx].portid[2] = 0; - isp_prt(isp, ISP_LOGDEBUG0, + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "removing duplicate PortID 0x%x entry from list", portid); } @@ -3406,7 +3367,7 @@ ((rs1->snscb_ports[portidx].portid[2])); if (portid == 0) { - isp_prt(isp, ISP_LOGDEBUG0, + isp_prt(isp, ISP_LOGSANCFG, "skipping null PortID at idx %d", portidx); continue; } @@ -3415,15 +3376,18 @@ * Skip ourselves... */ if (portid == fcp->isp_portid) { - isp_prt(isp, ISP_LOGDEBUG0, + isp_prt(isp, ISP_LOGSANCFG, "skip ourselves @ PortID 0x%06x", portid); continue; } - isp_prt(isp, ISP_LOGDEBUG0, "Fabric Port 0x%06x", portid); + isp_prt(isp, ISP_LOGSANCFG, + "Checking Fabric Port 0x%06x", portid); /* * We now search our Port Database for any - * probational entries with this PortID. + * probational entries with this PortID. We don't + * look for zombies here- only probational + * entries (we've already logged out of zombies). */ for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { lp = &fcp->portdb[dbidx]; @@ -3464,12 +3428,15 @@ r = isp_getpdb(isp, lp->handle, &pdb, 0); if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { FC_SCRATCH_RELEASE(isp); - isp_mark_portdb(isp, 1); + ISP_MARK_PORTDB(isp, 1); return (-1); } if (r != 0) { lp->new_portid = portid; lp->state = FC_PORTDB_STATE_DEAD; + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, + "Fabric Port 0x%06x considered dead", + portid); continue; } @@ -3486,8 +3453,8 @@ pdb.portid != portid || wwpn != lp->port_wwn || wwnn != lp->node_wwn) { - isp_prt(isp, ISP_LOGDEBUG0, fconf, dbidx, - pdb.handle, pdb.portid, + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, + fconf, dbidx, pdb.handle, pdb.portid, (uint32_t) (wwnn >> 32), (uint32_t) wwnn, (uint32_t) (wwpn >> 32), (uint32_t) wwpn, lp->handle, portid, >>> TRUNCATED FOR MAIL (1000 lines) <<<