Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Nov 2006 17:19:10 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 109943 for review
Message-ID:  <200611141719.kAEHJAxh093109@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/cdefs.h>
-__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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -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 <sys/cdefs.h>
-__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 <machine/resource.h>
 
+#include "pcib_if.h"
+
 #ifdef DEV_ISA
 #include <isa/isavar.h>
 #include <amd64/isa/isa.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/cdefs.h>
-__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 <dev/isp/isp_freebsd.h>
 #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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611141719.kAEHJAxh093109>