PERFORCE change 109943 for review
John Baldwin
jhb at FreeBSD.org
Tue Nov 14 17:19:12 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=109943
Change 109943 by jhb at 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 at 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 at 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 at 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) <<<
More information about the p4-projects
mailing list