aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2021-11-25 07:21:24 +0000
committerWarner Losh <imp@FreeBSD.org>2021-11-25 07:45:12 +0000
commit0d5935af8f2ea7675760af234723f472240c386f (patch)
tree97e464f8dd94ba9f1367b8cfd9059a78ba5bcaf6
parent60de2867c9fccac5ee3782fcc64fea6f0ae3ef06 (diff)
downloadsrc-0d5935af8f2ea7675760af234723f472240c386f.tar.gz
src-0d5935af8f2ea7675760af234723f472240c386f.zip
esp: Remove
Belatedly remove esp(4). It was tagged as gone in 13, but was overlooked until now. Sponsored by: Netflix Reviewed by: scottl Differential Revision: https://reviews.freebsd.org/D33115
-rw-r--r--share/man/man4/Makefile1
-rw-r--r--share/man/man4/esp.4111
-rw-r--r--sys/amd64/conf/GENERIC1
-rw-r--r--sys/conf/NOTES4
-rw-r--r--sys/conf/files2
-rw-r--r--sys/dev/esp/am53c974reg.h74
-rw-r--r--sys/dev/esp/esp_pci.c656
-rw-r--r--sys/dev/esp/ncr53c9x.c3260
-rw-r--r--sys/dev/esp/ncr53c9xreg.h296
-rw-r--r--sys/dev/esp/ncr53c9xvar.h501
-rw-r--r--sys/dev/ic/esp.h79
-rw-r--r--sys/i386/conf/GENERIC1
-rw-r--r--sys/modules/Makefile1
-rw-r--r--sys/modules/esp/Makefile9
-rw-r--r--tools/kerneldoc/subsys/Doxyfile-dev_esp21
15 files changed, 0 insertions, 5017 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 3eac0d1b3a39..ce2ce1ec8640 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -142,7 +142,6 @@ MAN= aac.4 \
ena.4 \
enc.4 \
epair.4 \
- esp.4 \
est.4 \
et.4 \
etherswitch.4 \
diff --git a/share/man/man4/esp.4 b/share/man/man4/esp.4
deleted file mode 100644
index 7fb426a02573..000000000000
--- a/share/man/man4/esp.4
+++ /dev/null
@@ -1,111 +0,0 @@
-.\"
-.\" Copyright (c) 2011 Marius Strobl <marius@FreeBSD.org>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd December 26, 2020
-.Dt ESP 4
-.Os
-.Sh NAME
-.Nm esp
-.Nd Emulex ESP, NCR 53C9x and QLogic FAS families based SCSI controllers
-.Sh SYNOPSIS
-To compile this driver into the kernel, place the following lines in your
-kernel configuration file:
-.Bd -ragged -offset indent
-.Cd "device scbus"
-.Cd "device esp"
-.Ed
-.Pp
-Alternatively, to load the driver as a module at boot time, place the
-following line in
-.Xr loader.conf 5 :
-.Bd -literal -offset indent
-if_esp_load="YES"
-.Ed
-.Sh DEPRECATION NOTICE
-The
-.Nm
-driver is not present in
-.Fx 13.0 .
-.Sh DESCRIPTION
-The
-.Nm
-driver provides support for the
-.Tn AMD
-Am53C974, the
-.Tn Emulex
-ESP100, ESP100A, ESP200 and ESP406, the
-.Tn NCR
-53C90, 53C94 and 53C96 as well as the
-.Tn QLogic
-FAS100A, FAS216, FAS366 and FAS408
-.Tn SCSI
-controller chips found in a wide variety of systems and peripheral boards.
-.Sh HARDWARE
-Controllers supported by the
-.Nm
-driver include:
-.Pp
-.Bl -bullet -compact
-.It
-Tekram DC390
-.It
-Tekram DC390T
-.El
-.Sh SEE ALSO
-.Xr cd 4 ,
-.Xr ch 4 ,
-.Xr da 4 ,
-.Xr intro 4 ,
-.Xr pci 4 ,
-.Xr sa 4 ,
-.Xr scsi 4 ,
-.Xr camcontrol 8
-.Sh HISTORY
-The
-.Nm
-driver first appeared in
-.Nx 1.3 .
-The first
-.Fx
-version to include it was
-.Fx 5.3 .
-.Sh AUTHORS
-.An -nosplit
-The
-.Nm
-driver was ported to
-.Fx
-by
-.An Scott Long Aq Mt scottl@FreeBSD.org
-and later on considerably improved by
-.An Marius Strobl Aq Mt marius@FreeBSD.org .
-.Sh BUGS
-The
-.Nm
-driver should read the EEPROM settings of
-.Tn Tekram
-controllers.
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 9d15833e472a..f0bc090e376e 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -157,7 +157,6 @@ device siis # SiliconImage SiI3124/SiI3132/SiI3531 SATA
# SCSI Controllers
device ahc # AHA2940 and onboard AIC7xxx devices
device ahd # AHA39320/29320 and onboard AIC79xx devices
-device esp # AMD Am53C974 (Tekram DC-390(T))
device hptiop # Highpoint RocketRaid 3xxx series
device isp # Qlogic family
#device ispfw # Firmware for QLogic HBAs- normally a module
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index f0546dfca101..c5baff1c9307 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1522,9 +1522,6 @@ options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK)
# ahc: Adaptec 274x/284x/2910/293x/294x/394x/3950x/3960x/398X/4944/
# 19160x/29160x, aic7770/aic78xx
# ahd: Adaptec 29320/39320 Controllers.
-# esp: Emulex ESP, NCR 53C9x and QLogic FAS families based controllers
-# including the AMD Am53C974 (found on devices such as the Tekram
-# DC-390(T)) and the Sun ESP and FAS families of controllers
# isp: Qlogic ISP 1020, 1040 and 1040B PCI SCSI host adapters,
# ISP 1240 Dual Ultra SCSI, ISP 1080 and 1280 (Dual) Ultra2,
# ISP 12160 Ultra3 SCSI,
@@ -1544,7 +1541,6 @@ options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK)
device aacraid
device ahc
device ahd
-device esp
device isp
envvar hint.isp.0.disable="1"
envvar hint.isp.0.role="3"
diff --git a/sys/conf/files b/sys/conf/files
index 650887cf54e6..4f084a2733a7 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1680,8 +1680,6 @@ dev/ena/ena_sysctl.c optional ena \
compile-with "${NORMAL_C} -I$S/contrib"
contrib/ena-com/ena_com.c optional ena
contrib/ena-com/ena_eth_com.c optional ena
-dev/esp/esp_pci.c optional esp pci
-dev/esp/ncr53c9x.c optional esp
dev/etherswitch/arswitch/arswitch.c optional arswitch
dev/etherswitch/arswitch/arswitch_reg.c optional arswitch
dev/etherswitch/arswitch/arswitch_phy.c optional arswitch
diff --git a/sys/dev/esp/am53c974reg.h b/sys/dev/esp/am53c974reg.h
deleted file mode 100644
index 795aa88d1668..000000000000
--- a/sys/dev/esp/am53c974reg.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $NetBSD: pcscpreg.h,v 1.2 2008/04/28 20:23:55 martin Exp $ */
-
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-NetBSD
- *
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Izumi Tsutsui.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* $FreeBSD$ */
-
-#ifndef _AM53C974_H_
-#define _AM53C974_H_
-
-/*
- * Am53c974 DMA engine registers
- */
-
-#define DMA_CMD 0x40 /* Command */
-#define DMACMD_RSVD 0xFFFFFF28 /* reserved */
-#define DMACMD_DIR 0x00000080 /* Transfer Direction (read:1) */
-#define DMACMD_INTE 0x00000040 /* DMA Interrupt Enable */
-#define DMACMD_MDL 0x00000010 /* Map to Memory Description List */
-#define DMACMD_DIAG 0x00000004 /* Diagnostic */
-#define DMACMD_CMD 0x00000003 /* Command Code Bit */
-#define DMACMD_IDLE 0x00000000 /* Idle */
-#define DMACMD_BLAST 0x00000001 /* Blast */
-#define DMACMD_ABORT 0x00000002 /* Abort */
-#define DMACMD_START 0x00000003 /* Start */
-
-#define DMA_STC 0x44 /* Start Transfer Count */
-#define DMA_SPA 0x48 /* Start Physical Address */
-#define DMA_WBC 0x4C /* Working Byte Counter */
-#define DMA_WAC 0x50 /* Working Address Counter */
-
-#define DMA_STAT 0x54 /* Status Register */
-#define DMASTAT_RSVD 0xFFFFFF80 /* reserved */
-#define DMASTAT_PABT 0x00000040 /* PCI master/target Abort */
-#define DMASTAT_BCMP 0x00000020 /* BLAST Complete */
-#define DMASTAT_SINT 0x00000010 /* SCSI Interrupt */
-#define DMASTAT_DONE 0x00000008 /* DMA Transfer Terminated */
-#define DMASTAT_ABT 0x00000004 /* DMA Transfer Aborted */
-#define DMASTAT_ERR 0x00000002 /* DMA Transfer Error */
-#define DMASTAT_PWDN 0x00000001 /* Power Down Indicator */
-
-#define DMA_SMDLA 0x58 /* Starting Memory Descpritor List Address */
-#define DMA_WMAC 0x5C /* Working MDL Counter */
-#define DMA_SBAC 0x70 /* SCSI Bus and Control */
-
-#endif /* _AM53C974_H_ */
diff --git a/sys/dev/esp/esp_pci.c b/sys/dev/esp/esp_pci.c
deleted file mode 100644
index 1e484b29415e..000000000000
--- a/sys/dev/esp/esp_pci.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-2-Clause-NetBSD
- *
- * Copyright (c) 2011 Marius Strobl <marius@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* $NetBSD: pcscp.c,v 1.45 2010/11/13 13:52:08 uebayasi Exp $ */
-
-/*-
- * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
- * NASA Ames Research Center; Izumi Tsutsui.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * esp_pci.c: device dependent code for AMD Am53c974 (PCscsi-PCI)
- * written by Izumi Tsutsui <tsutsui@NetBSD.org>
- *
- * Technical manual available at
- * http://www.amd.com/files/connectivitysolutions/networking/archivednetworking/19113.pdf
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/resource.h>
-#include <sys/rman.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/scsi/scsi_all.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-#include <dev/esp/ncr53c9xreg.h>
-#include <dev/esp/ncr53c9xvar.h>
-
-#include <dev/esp/am53c974reg.h>
-
-#define PCI_DEVICE_ID_AMD53C974 0x20201022
-
-struct esp_pci_softc {
- struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
- device_t sc_dev;
-
- struct resource *sc_res[2];
-#define ESP_PCI_RES_INTR 0
-#define ESP_PCI_RES_IO 1
-
- bus_dma_tag_t sc_pdmat;
-
- bus_dma_tag_t sc_xferdmat; /* DMA tag for transfers */
- bus_dmamap_t sc_xferdmam; /* DMA map for transfers */
-
- void *sc_ih; /* interrupt handler */
-
- size_t sc_dmasize; /* DMA size */
- void **sc_dmaaddr; /* DMA address */
- size_t *sc_dmalen; /* DMA length */
- int sc_active; /* DMA state */
- int sc_datain; /* DMA Data Direction */
-};
-
-static struct resource_spec esp_pci_res_spec[] = {
- { SYS_RES_IRQ, 0, RF_SHAREABLE | RF_ACTIVE }, /* ESP_PCI_RES_INTR */
- { SYS_RES_IOPORT, PCIR_BAR(0), RF_ACTIVE }, /* ESP_PCI_RES_IO */
- { -1, 0 }
-};
-
-#define READ_DMAREG(sc, reg) \
- bus_read_4((sc)->sc_res[ESP_PCI_RES_IO], (reg))
-#define WRITE_DMAREG(sc, reg, var) \
- bus_write_4((sc)->sc_res[ESP_PCI_RES_IO], (reg), (var))
-
-#define READ_ESPREG(sc, reg) \
- bus_read_1((sc)->sc_res[ESP_PCI_RES_IO], (reg) << 2)
-#define WRITE_ESPREG(sc, reg, val) \
- bus_write_1((sc)->sc_res[ESP_PCI_RES_IO], (reg) << 2, (val))
-
-static int esp_pci_probe(device_t);
-static int esp_pci_attach(device_t);
-static int esp_pci_detach(device_t);
-static int esp_pci_suspend(device_t);
-static int esp_pci_resume(device_t);
-
-static device_method_t esp_pci_methods[] = {
- DEVMETHOD(device_probe, esp_pci_probe),
- DEVMETHOD(device_attach, esp_pci_attach),
- DEVMETHOD(device_detach, esp_pci_detach),
- DEVMETHOD(device_suspend, esp_pci_suspend),
- DEVMETHOD(device_resume, esp_pci_resume),
-
- DEVMETHOD_END
-};
-
-static driver_t esp_pci_driver = {
- "esp",
- esp_pci_methods,
- sizeof(struct esp_pci_softc)
-};
-
-DRIVER_MODULE(esp, pci, esp_pci_driver, esp_devclass, 0, 0);
-MODULE_DEPEND(esp, pci, 1, 1, 1);
-
-/*
- * Functions and the switch for the MI code
- */
-static void esp_pci_dma_go(struct ncr53c9x_softc *);
-static int esp_pci_dma_intr(struct ncr53c9x_softc *);
-static int esp_pci_dma_isactive(struct ncr53c9x_softc *);
-
-static int esp_pci_dma_isintr(struct ncr53c9x_softc *);
-static void esp_pci_dma_reset(struct ncr53c9x_softc *);
-static int esp_pci_dma_setup(struct ncr53c9x_softc *, void **, size_t *,
- int, size_t *);
-static void esp_pci_dma_stop(struct ncr53c9x_softc *);
-static void esp_pci_write_reg(struct ncr53c9x_softc *, int, uint8_t);
-static uint8_t esp_pci_read_reg(struct ncr53c9x_softc *, int);
-static void esp_pci_xfermap(void *arg, bus_dma_segment_t *segs, int nseg,
- int error);
-
-static struct ncr53c9x_glue esp_pci_glue = {
- esp_pci_read_reg,
- esp_pci_write_reg,
- esp_pci_dma_isintr,
- esp_pci_dma_reset,
- esp_pci_dma_intr,
- esp_pci_dma_setup,
- esp_pci_dma_go,
- esp_pci_dma_stop,
- esp_pci_dma_isactive,
-};
-
-static int
-esp_pci_probe(device_t dev)
-{
-
- if (pci_get_devid(dev) == PCI_DEVICE_ID_AMD53C974) {
- device_set_desc(dev, "AMD Am53C974 Fast-SCSI");
- return (BUS_PROBE_DEFAULT);
- }
-
- return (ENXIO);
-}
-
-/*
- * Attach this instance, and then all the sub-devices
- */
-static int
-esp_pci_attach(device_t dev)
-{
- struct esp_pci_softc *esc;
- struct ncr53c9x_softc *sc;
- int error;
-
- esc = device_get_softc(dev);
- sc = &esc->sc_ncr53c9x;
-
- NCR_LOCK_INIT(sc);
-
- esc->sc_dev = dev;
- sc->sc_glue = &esp_pci_glue;
-
- pci_enable_busmaster(dev);
-
- error = bus_alloc_resources(dev, esp_pci_res_spec, esc->sc_res);
- if (error != 0) {
- device_printf(dev, "failed to allocate resources\n");
- bus_release_resources(dev, esp_pci_res_spec, esc->sc_res);
- return (error);
- }
-
- error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED,
- BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &esc->sc_pdmat);
- if (error != 0) {
- device_printf(dev, "cannot create parent DMA tag\n");
- goto fail_res;
- }
-
- /*
- * XXX More of this should be in ncr53c9x_attach(), but
- * XXX should we really poke around the chip that much in
- * XXX the MI code? Think about this more...
- */
-
- /*
- * Set up static configuration info.
- *
- * XXX we should read the configuration from the EEPROM.
- */
- sc->sc_id = 7;
- sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
- sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE;
- sc->sc_cfg3 = NCRAMDCFG3_IDM | NCRAMDCFG3_FCLK;
- sc->sc_cfg4 = NCRAMDCFG4_GE12NS | NCRAMDCFG4_RADE;
- sc->sc_rev = NCR_VARIANT_AM53C974;
- sc->sc_features = NCR_F_FASTSCSI | NCR_F_DMASELECT;
- sc->sc_cfg3_fscsi = NCRAMDCFG3_FSCSI;
- sc->sc_freq = 40; /* MHz */
-
- /*
- * This is the value used to start sync negotiations
- * Note that the NCR register "SYNCTP" is programmed
- * in "clocks per byte", and has a minimum value of 4.
- * The SCSI period used in negotiation is one-fourth
- * of the time (in nanoseconds) needed to transfer one byte.
- * Since the chip's clock is given in MHz, we have the following
- * formula: 4 * period = (1000 / freq) * 4
- */
- sc->sc_minsync = 1000 / sc->sc_freq;
-
- sc->sc_maxxfer = DFLTPHYS; /* see below */
- sc->sc_maxoffset = 15;
- sc->sc_extended_geom = 1;
-
-#define MDL_SEG_SIZE 0x1000 /* 4kbyte per segment */
-
- /*
- * Create the DMA tag and map for the data transfers.
- *
- * Note: given that bus_dma(9) only adheres to the requested alignment
- * for the first segment (and that also only for bus_dmamem_alloc()ed
- * DMA maps) we can't use the Memory Descriptor List. However, also
- * when not using the MDL, the maximum transfer size apparently is
- * limited to 4k so we have to split transfers up, which plain sucks.
- */
- error = bus_dma_tag_create(esc->sc_pdmat, PAGE_SIZE, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- MDL_SEG_SIZE, 1, MDL_SEG_SIZE, BUS_DMA_ALLOCNOW,
- busdma_lock_mutex, &sc->sc_lock, &esc->sc_xferdmat);
- if (error != 0) {
- device_printf(dev, "cannot create transfer DMA tag\n");
- goto fail_pdmat;
- }
- error = bus_dmamap_create(esc->sc_xferdmat, 0, &esc->sc_xferdmam);
- if (error != 0) {
- device_printf(dev, "cannot create transfer DMA map\n");
- goto fail_xferdmat;
- }
-
- error = bus_setup_intr(dev, esc->sc_res[ESP_PCI_RES_INTR],
- INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc,
- &esc->sc_ih);
- if (error != 0) {
- device_printf(dev, "cannot set up interrupt\n");
- goto fail_xferdmam;
- }
-
- /* Do the common parts of attachment. */
- sc->sc_dev = esc->sc_dev;
- error = ncr53c9x_attach(sc);
- if (error != 0) {
- device_printf(esc->sc_dev, "ncr53c9x_attach failed\n");
- goto fail_intr;
- }
-
- return (0);
-
- fail_intr:
- bus_teardown_intr(esc->sc_dev, esc->sc_res[ESP_PCI_RES_INTR],
- esc->sc_ih);
- fail_xferdmam:
- bus_dmamap_destroy(esc->sc_xferdmat, esc->sc_xferdmam);
- fail_xferdmat:
- bus_dma_tag_destroy(esc->sc_xferdmat);
- fail_pdmat:
- bus_dma_tag_destroy(esc->sc_pdmat);
- fail_res:
- bus_release_resources(dev, esp_pci_res_spec, esc->sc_res);
- NCR_LOCK_DESTROY(sc);
-
- return (error);
-}
-
-static int
-esp_pci_detach(device_t dev)
-{
- struct ncr53c9x_softc *sc;
- struct esp_pci_softc *esc;
- int error;
-
- esc = device_get_softc(dev);
- sc = &esc->sc_ncr53c9x;
-
- bus_teardown_intr(esc->sc_dev, esc->sc_res[ESP_PCI_RES_INTR],
- esc->sc_ih);
- error = ncr53c9x_detach(sc);
- if (error != 0)
- return (error);
- bus_dmamap_destroy(esc->sc_xferdmat, esc->sc_xferdmam);
- bus_dma_tag_destroy(esc->sc_xferdmat);
- bus_dma_tag_destroy(esc->sc_pdmat);
- bus_release_resources(dev, esp_pci_res_spec, esc->sc_res);
- NCR_LOCK_DESTROY(sc);
-
- return (0);
-}
-
-static int
-esp_pci_suspend(device_t dev)
-{
-
- return (ENXIO);
-}
-
-static int
-esp_pci_resume(device_t dev)
-{
-
- return (ENXIO);
-}
-
-static void
-esp_pci_xfermap(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)arg;
-
- if (error != 0)
- return;
-
- KASSERT(nsegs == 1, ("%s: bad transfer segment count %d", __func__,
- nsegs));
- KASSERT(segs[0].ds_len <= MDL_SEG_SIZE,
- ("%s: bad transfer segment length %ld", __func__,
- (long)segs[0].ds_len));
-
- /* Program the DMA Starting Physical Address. */
- WRITE_DMAREG(esc, DMA_SPA, segs[0].ds_addr);
-}
-
-/*
- * Glue functions
- */
-
-static uint8_t
-esp_pci_read_reg(struct ncr53c9x_softc *sc, int reg)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
-
- return (READ_ESPREG(esc, reg));
-}
-
-static void
-esp_pci_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
-
- WRITE_ESPREG(esc, reg, v);
-}
-
-static int
-esp_pci_dma_isintr(struct ncr53c9x_softc *sc)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
-
- return (READ_ESPREG(esc, NCR_STAT) & NCRSTAT_INT) != 0;
-}
-
-static void
-esp_pci_dma_reset(struct ncr53c9x_softc *sc)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
-
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_IDLE);
-
- esc->sc_active = 0;
-}
-
-static int
-esp_pci_dma_intr(struct ncr53c9x_softc *sc)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
- bus_dma_tag_t xferdmat;
- bus_dmamap_t xferdmam;
- size_t dmasize;
- int datain, i, resid, trans;
- uint32_t dmastat;
- char *p = NULL;
-
- xferdmat = esc->sc_xferdmat;
- xferdmam = esc->sc_xferdmam;
- datain = esc->sc_datain;
-
- dmastat = READ_DMAREG(esc, DMA_STAT);
-
- if ((dmastat & DMASTAT_ERR) != 0) {
- /* XXX not tested... */
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_ABORT | (datain != 0 ?
- DMACMD_DIR : 0));
-
- device_printf(esc->sc_dev, "DMA error detected; Aborting.\n");
- bus_dmamap_sync(xferdmat, xferdmam, datain != 0 ?
- BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(xferdmat, xferdmam);
- return (-1);
- }
-
- if ((dmastat & DMASTAT_ABT) != 0) {
- /* XXX what should be done? */
- device_printf(esc->sc_dev, "DMA aborted.\n");
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_IDLE | (datain != 0 ?
- DMACMD_DIR : 0));
- esc->sc_active = 0;
- return (0);
- }
-
- KASSERT(esc->sc_active != 0, ("%s: DMA wasn't active", __func__));
-
- /* DMA has stopped. */
-
- esc->sc_active = 0;
-
- dmasize = esc->sc_dmasize;
- if (dmasize == 0) {
- /* A "Transfer Pad" operation completed. */
- NCR_DMA(("%s: discarded %d bytes (tcl=%d, tcm=%d)\n",
- __func__, READ_ESPREG(esc, NCR_TCL) |
- (READ_ESPREG(esc, NCR_TCM) << 8),
- READ_ESPREG(esc, NCR_TCL), READ_ESPREG(esc, NCR_TCM)));
- return (0);
- }
-
- resid = 0;
- /*
- * If a transfer onto the SCSI bus gets interrupted by the device
- * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
- * as residual since the ESP counter registers get decremented as
- * bytes are clocked into the FIFO.
- */
- if (datain == 0 &&
- (resid = (READ_ESPREG(esc, NCR_FFLAG) & NCRFIFO_FF)) != 0)
- NCR_DMA(("%s: empty esp FIFO of %d ", __func__, resid));
-
- if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
- /*
- * "Terminal count" is off, so read the residue
- * out of the ESP counter registers.
- */
- if (datain != 0) {
- resid = READ_ESPREG(esc, NCR_FFLAG) & NCRFIFO_FF;
- while (resid > 1)
- resid =
- READ_ESPREG(esc, NCR_FFLAG) & NCRFIFO_FF;
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_BLAST | DMACMD_DIR);
-
- for (i = 0; i < 0x8000; i++) /* XXX 0x8000 ? */
- if ((READ_DMAREG(esc, DMA_STAT) &
- DMASTAT_BCMP) != 0)
- break;
-
- /* See the below comments... */
- if (resid != 0)
- p = *esc->sc_dmaaddr;
- }
-
- resid += READ_ESPREG(esc, NCR_TCL) |
- (READ_ESPREG(esc, NCR_TCM) << 8) |
- (READ_ESPREG(esc, NCR_TCH) << 16);
- } else
- while ((dmastat & DMASTAT_DONE) == 0)
- dmastat = READ_DMAREG(esc, DMA_STAT);
-
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_IDLE | (datain != 0 ?
- DMACMD_DIR : 0));
-
- /* Sync the transfer buffer. */
- bus_dmamap_sync(xferdmat, xferdmam, datain != 0 ?
- BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(xferdmat, xferdmam);
-
- trans = dmasize - resid;
-
- /*
- * From the technical manual notes:
- *
- * "In some odd byte conditions, one residual byte will be left
- * in the SCSI FIFO, and the FIFO flags will never count to 0.
- * When this happens, the residual byte should be retrieved
- * via PIO following completion of the BLAST operation."
- */
- if (p != NULL) {
- p += trans;
- *p = READ_ESPREG(esc, NCR_FIFO);
- trans++;
- }
-
- if (trans < 0) { /* transferred < 0 ? */
-#if 0
- /*
- * This situation can happen in perfectly normal operation
- * if the ESP is reselected while using DMA to select
- * another target. As such, don't print the warning.
- */
- device_printf(dev, "xfer (%d) > req (%d)\n", trans, dmasize);
-#endif
- trans = dmasize;
- }
-
- NCR_DMA(("%s: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n", __func__,
- READ_ESPREG(esc, NCR_TCL), READ_ESPREG(esc, NCR_TCM),
- READ_ESPREG(esc, NCR_TCH), trans, resid));
-
- *esc->sc_dmalen -= trans;
- *esc->sc_dmaaddr = (char *)*esc->sc_dmaaddr + trans;
-
- return (0);
-}
-
-static int
-esp_pci_dma_setup(struct ncr53c9x_softc *sc, void **addr, size_t *len,
- int datain, size_t *dmasize)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
- int error;
-
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_IDLE | (datain != 0 ? DMACMD_DIR :
- 0));
-
- *dmasize = esc->sc_dmasize = ulmin(*dmasize, MDL_SEG_SIZE);
- esc->sc_dmaaddr = addr;
- esc->sc_dmalen = len;
- esc->sc_datain = datain;
-
- /*
- * There's no need to set up DMA for a "Transfer Pad" operation.
- */
- if (*dmasize == 0)
- return (0);
-
- /* Set the transfer length. */
- WRITE_DMAREG(esc, DMA_STC, *dmasize);
-
- /*
- * Load the transfer buffer and program the DMA address.
- * Note that the NCR53C9x core can't handle EINPROGRESS so we set
- * BUS_DMA_NOWAIT.
- */
- error = bus_dmamap_load(esc->sc_xferdmat, esc->sc_xferdmam,
- *esc->sc_dmaaddr, *dmasize, esp_pci_xfermap, sc, BUS_DMA_NOWAIT);
-
- return (error);
-}
-
-static void
-esp_pci_dma_go(struct ncr53c9x_softc *sc)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
- int datain;
-
- datain = esc->sc_datain;
-
- /* No DMA transfer for a "Transfer Pad" operation */
- if (esc->sc_dmasize == 0)
- return;
-
- /* Sync the transfer buffer. */
- bus_dmamap_sync(esc->sc_xferdmat, esc->sc_xferdmam, datain != 0 ?
- BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
-
- /* Set the DMA engine to the IDLE state. */
- /* XXX DMA Transfer Interrupt Enable bit is broken? */
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_IDLE | /* DMACMD_INTE | */
- (datain != 0 ? DMACMD_DIR : 0));
-
- /* Issue a DMA start command. */
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_START | /* DMACMD_INTE | */
- (datain != 0 ? DMACMD_DIR : 0));
-
- esc->sc_active = 1;
-}
-
-static void
-esp_pci_dma_stop(struct ncr53c9x_softc *sc)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
-
- /* DMA stop */
- /* XXX what should we do here ? */
- WRITE_DMAREG(esc, DMA_CMD,
- DMACMD_ABORT | (esc->sc_datain != 0 ? DMACMD_DIR : 0));
- bus_dmamap_unload(esc->sc_xferdmat, esc->sc_xferdmam);
-
- esc->sc_active = 0;
-}
-
-static int
-esp_pci_dma_isactive(struct ncr53c9x_softc *sc)
-{
- struct esp_pci_softc *esc = (struct esp_pci_softc *)sc;
-
- /* XXX should we check esc->sc_active? */
- if ((READ_DMAREG(esc, DMA_CMD) & DMACMD_CMD) != DMACMD_IDLE)
- return (1);
-
- return (0);
-}
diff --git a/sys/dev/esp/ncr53c9x.c b/sys/dev/esp/ncr53c9x.c
deleted file mode 100644
index 35ce9a4dbf2c..000000000000
--- a/sys/dev/esp/ncr53c9x.c
+++ /dev/null
@@ -1,3260 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-2-Clause NetBSD
- *
- * Copyright (c) 2004 Scott Long
- * Copyright (c) 2005, 2008 Marius Strobl <marius@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-/* $NetBSD: ncr53c9x.c,v 1.145 2012/06/18 21:23:56 martin Exp $ */
-
-/*-
- * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Charles M. Hannum.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 1994 Peter Galbavy
- * Copyright (c) 1995 Paul Kranenburg
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Peter Galbavy
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Based on aic6360 by Jarle Greipsland
- *
- * Acknowledgements: Many of the algorithms used in this driver are
- * inspired by the work of Julian Elischer (julian@FreeBSD.org) and
- * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-#include <sys/callout.h>
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_debug.h>
-#include <cam/cam_sim.h>
-#include <cam/cam_xpt_sim.h>
-#include <cam/scsi/scsi_all.h>
-#include <cam/scsi/scsi_message.h>
-
-#include <dev/esp/ncr53c9xreg.h>
-#include <dev/esp/ncr53c9xvar.h>
-
-devclass_t esp_devclass;
-
-MODULE_DEPEND(esp, cam, 1, 1, 1);
-
-#ifdef NCR53C9X_DEBUG
-int ncr53c9x_debug =
- NCR_SHOWMISC /* | NCR_SHOWPHASE | NCR_SHOWTRAC | NCR_SHOWCMDS */;
-#endif
-
-static void ncr53c9x_abort(struct ncr53c9x_softc *sc,
- struct ncr53c9x_ecb *ecb);
-static void ncr53c9x_action(struct cam_sim *sim, union ccb *ccb);
-static void ncr53c9x_async(void *cbarg, uint32_t code,
- struct cam_path *path, void *arg);
-static void ncr53c9x_callout(void *arg);
-static void ncr53c9x_clear(struct ncr53c9x_softc *sc, cam_status result);
-static void ncr53c9x_clear_target(struct ncr53c9x_softc *sc, int target,
- cam_status result);
-static void ncr53c9x_dequeue(struct ncr53c9x_softc *sc,
- struct ncr53c9x_ecb *ecb);
-static void ncr53c9x_done(struct ncr53c9x_softc *sc,
- struct ncr53c9x_ecb *ecb);
-static void ncr53c9x_free_ecb(struct ncr53c9x_softc *sc,
- struct ncr53c9x_ecb *ecb);
-static void ncr53c9x_msgin(struct ncr53c9x_softc *sc);
-static void ncr53c9x_msgout(struct ncr53c9x_softc *sc);
-static void ncr53c9x_init(struct ncr53c9x_softc *sc, int doreset);
-static void ncr53c9x_intr1(struct ncr53c9x_softc *sc);
-static void ncr53c9x_poll(struct cam_sim *sim);
-static int ncr53c9x_rdfifo(struct ncr53c9x_softc *sc, int how);
-static int ncr53c9x_reselect(struct ncr53c9x_softc *sc, int message,
- int tagtype, int tagid);
-static void ncr53c9x_reset(struct ncr53c9x_softc *sc);
-static void ncr53c9x_sense(struct ncr53c9x_softc *sc,
- struct ncr53c9x_ecb *ecb);
-static void ncr53c9x_sched(struct ncr53c9x_softc *sc);
-static void ncr53c9x_select(struct ncr53c9x_softc *sc,
- struct ncr53c9x_ecb *ecb);
-static void ncr53c9x_watch(void *arg);
-static void ncr53c9x_wrfifo(struct ncr53c9x_softc *sc, uint8_t *p,
- int len);
-
-static struct ncr53c9x_ecb *ncr53c9x_get_ecb(struct ncr53c9x_softc *sc);
-static struct ncr53c9x_linfo *ncr53c9x_lunsearch(struct ncr53c9x_tinfo *sc,
- int64_t lun);
-
-static inline void ncr53c9x_readregs(struct ncr53c9x_softc *sc);
-static inline void ncr53c9x_setsync(struct ncr53c9x_softc *sc,
- struct ncr53c9x_tinfo *ti);
-static inline int ncr53c9x_stp2cpb(struct ncr53c9x_softc *sc,
- int period);
-
-#define NCR_RDFIFO_START 0
-#define NCR_RDFIFO_CONTINUE 1
-
-#define NCR_SET_COUNT(sc, size) do { \
- NCR_WRITE_REG((sc), NCR_TCL, (size)); \
- NCR_WRITE_REG((sc), NCR_TCM, (size) >> 8); \
- if ((sc->sc_features & NCR_F_LARGEXFER) != 0) \
- NCR_WRITE_REG((sc), NCR_TCH, (size) >> 16); \
- if (sc->sc_rev == NCR_VARIANT_FAS366) \
- NCR_WRITE_REG(sc, NCR_RCH, 0); \
-} while (/* CONSTCOND */0)
-
-#ifndef mstohz
-#define mstohz(ms) \
- (((ms) < 0x20000) ? \
- ((ms +0u) / 1000u) * hz : \
- ((ms +0u) * hz) /1000u)
-#endif
-
-/*
- * Names for the NCR53c9x variants, corresponding to the variant tags
- * in ncr53c9xvar.h.
- */
-static const char *ncr53c9x_variant_names[] = {
- "ESP100",
- "ESP100A",
- "ESP200",
- "NCR53C94",
- "NCR53C96",
- "ESP406",
- "FAS408",
- "FAS216",
- "AM53C974",
- "FAS366/HME",
- "NCR53C90 (86C01)",
- "FAS100A",
- "FAS236",
-};
-
-/*
- * Search linked list for LUN info by LUN id.
- */
-static struct ncr53c9x_linfo *
-ncr53c9x_lunsearch(struct ncr53c9x_tinfo *ti, int64_t lun)
-{
- struct ncr53c9x_linfo *li;
-
- LIST_FOREACH(li, &ti->luns, link)
- if (li->lun == lun)
- return (li);
- return (NULL);
-}
-
-/*
- * Attach this instance, and then all the sub-devices.
- */
-int
-ncr53c9x_attach(struct ncr53c9x_softc *sc)
-{
- struct cam_devq *devq;
- struct cam_sim *sim;
- struct cam_path *path;
- struct ncr53c9x_ecb *ecb;
- int error, i;
-
- if (NCR_LOCK_INITIALIZED(sc) == 0) {
- device_printf(sc->sc_dev, "mutex not initialized\n");
- return (ENXIO);
- }
-
- callout_init_mtx(&sc->sc_watchdog, &sc->sc_lock, 0);
-
- /*
- * Note, the front-end has set us up to print the chip variation.
- */
- if (sc->sc_rev >= NCR_VARIANT_MAX) {
- device_printf(sc->sc_dev, "unknown variant %d, devices not "
- "attached\n", sc->sc_rev);
- return (EINVAL);
- }
-
- device_printf(sc->sc_dev, "%s, %d MHz, SCSI ID %d\n",
- ncr53c9x_variant_names[sc->sc_rev], sc->sc_freq, sc->sc_id);
-
- sc->sc_ntarg = (sc->sc_rev == NCR_VARIANT_FAS366) ? 16 : 8;
-
- /*
- * Allocate SCSI message buffers.
- * Front-ends can override allocation to avoid alignment
- * handling in the DMA engines. Note that ncr53c9x_msgout()
- * can request a 1 byte DMA transfer.
- */
- if (sc->sc_omess == NULL) {
- sc->sc_omess_self = 1;
- sc->sc_omess = malloc(NCR_MAX_MSG_LEN, M_DEVBUF, M_NOWAIT);
- if (sc->sc_omess == NULL) {
- device_printf(sc->sc_dev,
- "cannot allocate MSGOUT buffer\n");
- return (ENOMEM);
- }
- } else
- sc->sc_omess_self = 0;
-
- if (sc->sc_imess == NULL) {
- sc->sc_imess_self = 1;
- sc->sc_imess = malloc(NCR_MAX_MSG_LEN + 1, M_DEVBUF, M_NOWAIT);
- if (sc->sc_imess == NULL) {
- device_printf(sc->sc_dev,
- "cannot allocate MSGIN buffer\n");
- error = ENOMEM;
- goto fail_omess;
- }
- } else
- sc->sc_imess_self = 0;
-
- sc->sc_tinfo = malloc(sc->sc_ntarg * sizeof(sc->sc_tinfo[0]),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- if (sc->sc_tinfo == NULL) {
- device_printf(sc->sc_dev,
- "cannot allocate target info buffer\n");
- error = ENOMEM;
- goto fail_imess;
- }
-
- /*
- * Treat NCR53C90 with the 86C01 DMA chip exactly as ESP100
- * from now on.
- */
- if (sc->sc_rev == NCR_VARIANT_NCR53C90_86C01)
- sc->sc_rev = NCR_VARIANT_ESP100;
-
- sc->sc_ccf = FREQTOCCF(sc->sc_freq);
-
- /* The value *must not* be == 1. Make it 2. */
- if (sc->sc_ccf == 1)
- sc->sc_ccf = 2;
-
- /*
- * The recommended timeout is 250ms. This register is loaded
- * with a value calculated as follows, from the docs:
- *
- * (timeout period) x (CLK frequency)
- * reg = -------------------------------------
- * 8192 x (Clock Conversion Factor)
- *
- * Since CCF has a linear relation to CLK, this generally computes
- * to the constant of 153.
- */
- sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);
-
- /* The CCF register only has 3 bits; 0 is actually 8. */
- sc->sc_ccf &= 7;
-
- /*
- * Register with CAM.
- */
- devq = cam_simq_alloc(sc->sc_ntarg);
- if (devq == NULL) {
- device_printf(sc->sc_dev, "cannot allocate device queue\n");
- error = ENOMEM;
- goto fail_tinfo;
- }
-
- sim = cam_sim_alloc(ncr53c9x_action, ncr53c9x_poll, "esp", sc,
- device_get_unit(sc->sc_dev), &sc->sc_lock, 1, NCR_TAG_DEPTH, devq);
- if (sim == NULL) {
- device_printf(sc->sc_dev, "cannot allocate SIM entry\n");
- error = ENOMEM;
- goto fail_devq;
- }
-
- NCR_LOCK(sc);
-
- if (xpt_bus_register(sim, sc->sc_dev, 0) != CAM_SUCCESS) {
- device_printf(sc->sc_dev, "cannot register bus\n");
- error = EIO;
- goto fail_lock;
- }
-
- if (xpt_create_path(&path, NULL, cam_sim_path(sim),
- CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
- device_printf(sc->sc_dev, "cannot create path\n");
- error = EIO;
- goto fail_bus;
- }
-
- if (xpt_register_async(AC_LOST_DEVICE, ncr53c9x_async, sim, path) !=
- CAM_REQ_CMP) {
- device_printf(sc->sc_dev, "cannot register async handler\n");
- error = EIO;
- goto fail_path;
- }
-
- sc->sc_sim = sim;
- sc->sc_path = path;
-
- /* Reset state and bus. */
-#if 0
- sc->sc_cfflags = sc->sc_dev.dv_cfdata->cf_flags;
-#else
- sc->sc_cfflags = 0;
-#endif
- sc->sc_state = 0;
- ncr53c9x_init(sc, 1);
-
- TAILQ_INIT(&sc->free_list);
- if ((sc->ecb_array =
- malloc(sizeof(struct ncr53c9x_ecb) * NCR_TAG_DEPTH, M_DEVBUF,
- M_NOWAIT | M_ZERO)) == NULL) {
- device_printf(sc->sc_dev, "cannot allocate ECB array\n");
- error = ENOMEM;
- goto fail_async;
- }
- for (i = 0; i < NCR_TAG_DEPTH; i++) {
- ecb = &sc->ecb_array[i];
- ecb->sc = sc;
- ecb->tag_id = i;
- callout_init_mtx(&ecb->ch, &sc->sc_lock, 0);
- TAILQ_INSERT_HEAD(&sc->free_list, ecb, free_links);
- }
-
- callout_reset(&sc->sc_watchdog, 60 * hz, ncr53c9x_watch, sc);
-
- NCR_UNLOCK(sc);
-
- gone_in_dev(sc->sc_dev, 13, "esp(4) driver");
- return (0);
-
-fail_async:
- xpt_register_async(0, ncr53c9x_async, sim, path);
-fail_path:
- xpt_free_path(path);
-fail_bus:
- xpt_bus_deregister(cam_sim_path(sim));
-fail_lock:
- NCR_UNLOCK(sc);
- cam_sim_free(sim, TRUE);
-fail_devq:
- cam_simq_free(devq);
-fail_tinfo:
- free(sc->sc_tinfo, M_DEVBUF);
-fail_imess:
- if (sc->sc_imess_self)
- free(sc->sc_imess, M_DEVBUF);
-fail_omess:
- if (sc->sc_omess_self)
- free(sc->sc_omess, M_DEVBUF);
- return (error);
-}
-
-int
-ncr53c9x_detach(struct ncr53c9x_softc *sc)
-{
- struct ncr53c9x_linfo *li, *nextli;
- int t;
-
- callout_drain(&sc->sc_watchdog);
-
- NCR_LOCK(sc);
-
- if (sc->sc_tinfo) {
- /* Cancel all commands. */
- ncr53c9x_clear(sc, CAM_REQ_ABORTED);
-
- /* Free logical units. */
- for (t = 0; t < sc->sc_ntarg; t++) {
- for (li = LIST_FIRST(&sc->sc_tinfo[t].luns); li;
- li = nextli) {
- nextli = LIST_NEXT(li, link);
- free(li, M_DEVBUF);
- }
- }
- }
-
- xpt_register_async(0, ncr53c9x_async, sc->sc_sim, sc->sc_path);
- xpt_free_path(sc->sc_path);
- xpt_bus_deregister(cam_sim_path(sc->sc_sim));
- cam_sim_free(sc->sc_sim, TRUE);
-
- NCR_UNLOCK(sc);
-
- free(sc->ecb_array, M_DEVBUF);
- free(sc->sc_tinfo, M_DEVBUF);
- if (sc->sc_imess_self)
- free(sc->sc_imess, M_DEVBUF);
- if (sc->sc_omess_self)
- free(sc->sc_omess, M_DEVBUF);
-
- return (0);
-}
-
-/*
- * This is the generic ncr53c9x reset function. It does not reset the SCSI
- * bus, only this controller, but kills any on-going commands, and also stops
- * and resets the DMA.
- *
- * After reset, registers are loaded with the defaults from the attach
- * routine above.
- */
-static void
-ncr53c9x_reset(struct ncr53c9x_softc *sc)
-{
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- /* Reset DMA first. */
- NCRDMA_RESET(sc);
-
- /* Reset SCSI chip. */
- NCRCMD(sc, NCRCMD_RSTCHIP);
- NCRCMD(sc, NCRCMD_NOP);
- DELAY(500);
-
- /* Do these backwards, and fall through. */
- switch (sc->sc_rev) {
- case NCR_VARIANT_ESP406:
- case NCR_VARIANT_FAS408:
- NCR_WRITE_REG(sc, NCR_CFG5, sc->sc_cfg5 | NCRCFG5_SINT);
- NCR_WRITE_REG(sc, NCR_CFG4, sc->sc_cfg4);
- /* FALLTHROUGH */
- case NCR_VARIANT_AM53C974:
- case NCR_VARIANT_FAS100A:
- case NCR_VARIANT_FAS216:
- case NCR_VARIANT_FAS236:
- case NCR_VARIANT_NCR53C94:
- case NCR_VARIANT_NCR53C96:
- case NCR_VARIANT_ESP200:
- sc->sc_features |= NCR_F_HASCFG3;
- NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
- /* FALLTHROUGH */
- case NCR_VARIANT_ESP100A:
- sc->sc_features |= NCR_F_SELATN3;
- if ((sc->sc_cfg2 & NCRCFG2_FE) != 0)
- sc->sc_features |= NCR_F_LARGEXFER;
- NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
- /* FALLTHROUGH */
- case NCR_VARIANT_ESP100:
- NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
- NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);
- NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);
- NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);
- break;
-
- case NCR_VARIANT_FAS366:
- sc->sc_features |= NCR_F_HASCFG3 | NCR_F_FASTSCSI |
- NCR_F_SELATN3 | NCR_F_LARGEXFER;
- sc->sc_cfg3 = NCRFASCFG3_FASTCLK | NCRFASCFG3_OBAUTO;
- if (sc->sc_id > 7)
- sc->sc_cfg3 |= NCRFASCFG3_IDBIT3;
- sc->sc_cfg3_fscsi = NCRFASCFG3_FASTSCSI;
- NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
- sc->sc_cfg2 = NCRCFG2_HMEFE | NCRCFG2_HME32;
- NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
- NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
- NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);
- NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);
- NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);
- break;
-
- default:
- device_printf(sc->sc_dev,
- "unknown revision code, assuming ESP100\n");
- NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
- NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf);
- NCR_WRITE_REG(sc, NCR_SYNCOFF, 0);
- NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout);
- }
-
- if (sc->sc_rev == NCR_VARIANT_AM53C974)
- NCR_WRITE_REG(sc, NCR_AMDCFG4, sc->sc_cfg4);
-
-#if 0
- device_printf(sc->sc_dev, "%s: revision %d\n", __func__, sc->sc_rev);
- device_printf(sc->sc_dev, "%s: cfg1 0x%x, cfg2 0x%x, cfg3 0x%x, ccf "
- "0x%x, timeout 0x%x\n", __func__, sc->sc_cfg1, sc->sc_cfg2,
- sc->sc_cfg3, sc->sc_ccf, sc->sc_timeout);
-#endif
-}
-
-/*
- * Clear all commands.
- */
-static void
-ncr53c9x_clear(struct ncr53c9x_softc *sc, cam_status result)
-{
- struct ncr53c9x_ecb *ecb;
- int r;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- /* Cancel any active commands. */
- sc->sc_state = NCR_CLEANING;
- sc->sc_msgify = 0;
- ecb = sc->sc_nexus;
- if (ecb != NULL) {
- ecb->ccb->ccb_h.status = result;
- ncr53c9x_done(sc, ecb);
- }
- /* Cancel outstanding disconnected commands. */
- for (r = 0; r < sc->sc_ntarg; r++)
- ncr53c9x_clear_target(sc, r, result);
-}
-
-/*
- * Clear all commands for a specific target.
- */
-static void
-ncr53c9x_clear_target(struct ncr53c9x_softc *sc, int target,
- cam_status result)
-{
- struct ncr53c9x_ecb *ecb;
- struct ncr53c9x_linfo *li;
- int i;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- /* Cancel outstanding disconnected commands on each LUN. */
- LIST_FOREACH(li, &sc->sc_tinfo[target].luns, link) {
- ecb = li->untagged;
- if (ecb != NULL) {
- li->untagged = NULL;
- /*
- * XXX should we terminate a command
- * that never reached the disk?
- */
- li->busy = 0;
- ecb->ccb->ccb_h.status = result;
- ncr53c9x_done(sc, ecb);
- }
- for (i = 0; i < NCR_TAG_DEPTH; i++) {
- ecb = li->queued[i];
- if (ecb != NULL) {
- li->queued[i] = NULL;
- ecb->ccb->ccb_h.status = result;
- ncr53c9x_done(sc, ecb);
- }
- }
- li->used = 0;
- }
-}
-
-/*
- * Initialize ncr53c9x state machine.
- */
-static void
-ncr53c9x_init(struct ncr53c9x_softc *sc, int doreset)
-{
- struct ncr53c9x_tinfo *ti;
- int r;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_MISC(("[NCR_INIT(%d) %d] ", doreset, sc->sc_state));
-
- if (sc->sc_state == 0) {
- /* First time through; initialize. */
-
- TAILQ_INIT(&sc->ready_list);
- sc->sc_nexus = NULL;
- memset(sc->sc_tinfo, 0, sizeof(*sc->sc_tinfo));
- for (r = 0; r < sc->sc_ntarg; r++) {
- LIST_INIT(&sc->sc_tinfo[r].luns);
- }
- } else
- ncr53c9x_clear(sc, CAM_CMD_TIMEOUT);
-
- /*
- * Reset the chip to a known state.
- */
- ncr53c9x_reset(sc);
-
- sc->sc_flags = 0;
- sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0;
- sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
-
- /*
- * If we're the first time through, set the default parameters
- * for all targets. Otherwise we only clear their current transfer
- * settings so we'll renegotiate their goal settings with the next
- * command.
- */
- if (sc->sc_state == 0) {
- for (r = 0; r < sc->sc_ntarg; r++) {
- ti = &sc->sc_tinfo[r];
-/* XXX - config flags per target: low bits: no reselect; high bits: no synch */
-
- ti->flags = ((sc->sc_minsync != 0 &&
- (sc->sc_cfflags & (1 << ((r & 7) + 8))) == 0) ?
- 0 : T_SYNCHOFF) |
- ((sc->sc_cfflags & (1 << (r & 7))) == 0 ?
- 0 : T_RSELECTOFF);
- ti->curr.period = ti->goal.period = 0;
- ti->curr.offset = ti->goal.offset = 0;
- ti->curr.width = ti->goal.width =
- MSG_EXT_WDTR_BUS_8_BIT;
- }
- } else {
- for (r = 0; r < sc->sc_ntarg; r++) {
- ti = &sc->sc_tinfo[r];
- ti->flags &= ~(T_SDTRSENT | T_WDTRSENT);
- ti->curr.period = 0;
- ti->curr.offset = 0;
- ti->curr.width = MSG_EXT_WDTR_BUS_8_BIT;
- }
- }
-
- if (doreset) {
- sc->sc_state = NCR_SBR;
- NCRCMD(sc, NCRCMD_RSTSCSI);
- /* Give the bus a fighting chance to settle. */
- DELAY(250000);
- } else {
- sc->sc_state = NCR_IDLE;
- ncr53c9x_sched(sc);
- }
-}
-
-/*
- * Read the NCR registers, and save their contents for later use.
- * NCR_STAT, NCR_STEP & NCR_INTR are mostly zeroed out when reading
- * NCR_INTR - so make sure it is the last read.
- *
- * I think that (from reading the docs) most bits in these registers
- * only make sense when the DMA CSR has an interrupt showing. Call only
- * if an interrupt is pending.
- */
-static inline void
-ncr53c9x_readregs(struct ncr53c9x_softc *sc)
-{
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- sc->sc_espstat = NCR_READ_REG(sc, NCR_STAT);
- /* Only the step bits are of interest. */
- sc->sc_espstep = NCR_READ_REG(sc, NCR_STEP) & NCRSTEP_MASK;
-
- if (sc->sc_rev == NCR_VARIANT_FAS366)
- sc->sc_espstat2 = NCR_READ_REG(sc, NCR_STAT2);
-
- sc->sc_espintr = NCR_READ_REG(sc, NCR_INTR);
-
- /*
- * Determine the SCSI bus phase, return either a real SCSI bus phase
- * or some pseudo phase we use to detect certain exceptions.
- */
- sc->sc_phase = (sc->sc_espintr & NCRINTR_DIS) ?
- BUSFREE_PHASE : sc->sc_espstat & NCRSTAT_PHASE;
-
- NCR_INTS(("regs[intr=%02x,stat=%02x,step=%02x,stat2=%02x] ",
- sc->sc_espintr, sc->sc_espstat, sc->sc_espstep, sc->sc_espstat2));
-}
-
-/*
- * Convert Synchronous Transfer Period to chip register Clock Per Byte value.
- */
-static inline int
-ncr53c9x_stp2cpb(struct ncr53c9x_softc *sc, int period)
-{
- int v;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- v = (sc->sc_freq * period) / 250;
- if (ncr53c9x_cpb2stp(sc, v) < period)
- /* Correct round-down error. */
- v++;
- return (v);
-}
-
-static inline void
-ncr53c9x_setsync(struct ncr53c9x_softc *sc, struct ncr53c9x_tinfo *ti)
-{
- uint8_t cfg3, syncoff, synctp;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- cfg3 = sc->sc_cfg3;
- if (ti->curr.offset != 0) {
- syncoff = ti->curr.offset;
- synctp = ncr53c9x_stp2cpb(sc, ti->curr.period);
- if (sc->sc_features & NCR_F_FASTSCSI) {
- /*
- * If the period is 200ns or less (ti->period <= 50),
- * put the chip in Fast SCSI mode.
- */
- if (ti->curr.period <= 50)
- /*
- * There are (at least) 4 variations of the
- * configuration 3 register. The drive attach
- * routine sets the appropriate bit to put the
- * chip into Fast SCSI mode so that it doesn't
- * have to be figured out here each time.
- */
- cfg3 |= sc->sc_cfg3_fscsi;
- }
-
- /*
- * Am53c974 requires different SYNCTP values when the
- * FSCSI bit is off.
- */
- if (sc->sc_rev == NCR_VARIANT_AM53C974 &&
- (cfg3 & NCRAMDCFG3_FSCSI) == 0)
- synctp--;
- } else {
- syncoff = 0;
- synctp = 0;
- }
-
- if (ti->curr.width != MSG_EXT_WDTR_BUS_8_BIT) {
- if (sc->sc_rev == NCR_VARIANT_FAS366)
- cfg3 |= NCRFASCFG3_EWIDE;
- }
-
- if (sc->sc_features & NCR_F_HASCFG3)
- NCR_WRITE_REG(sc, NCR_CFG3, cfg3);
-
- NCR_WRITE_REG(sc, NCR_SYNCOFF, syncoff);
- NCR_WRITE_REG(sc, NCR_SYNCTP, synctp);
-}
-
-/*
- * Send a command to a target, set the driver state to NCR_SELECTING
- * and let the caller take care of the rest.
- *
- * Keeping this as a function allows me to say that this may be done
- * by DMA instead of programmed I/O soon.
- */
-static void
-ncr53c9x_select(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
-{
- struct ncr53c9x_tinfo *ti;
- uint8_t *cmd;
- size_t dmasize;
- int clen, error, selatn3, selatns;
- int lun = ecb->ccb->ccb_h.target_lun;
- int target = ecb->ccb->ccb_h.target_id;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s(t%d,l%d,cmd:%x,tag:%x,%x)] ", __func__, target, lun,
- ecb->cmd.cmd.opcode, ecb->tag[0], ecb->tag[1]));
-
- ti = &sc->sc_tinfo[target];
- sc->sc_state = NCR_SELECTING;
- /*
- * Schedule the callout now, the first time we will go away
- * expecting to come back due to an interrupt, because it is
- * always possible that the interrupt may never happen.
- */
- callout_reset(&ecb->ch, mstohz(ecb->timeout), ncr53c9x_callout, ecb);
-
- /*
- * The docs say the target register is never reset, and I
- * can't think of a better place to set it.
- */
- if (sc->sc_rev == NCR_VARIANT_FAS366) {
- NCRCMD(sc, NCRCMD_FLUSH);
- NCR_WRITE_REG(sc, NCR_SELID, target | NCR_BUSID_HMEXC32 |
- NCR_BUSID_HMEENCID);
- } else
- NCR_WRITE_REG(sc, NCR_SELID, target);
-
- /*
- * If we are requesting sense, force a renegotiation if we are
- * currently using anything different from asynchronous at 8 bit
- * as the target might have lost our transfer negotiations.
- */
- if ((ecb->flags & ECB_SENSE) != 0 && (ti->curr.offset != 0 ||
- ti->curr.width != MSG_EXT_WDTR_BUS_8_BIT)) {
- ti->curr.period = 0;
- ti->curr.offset = 0;
- ti->curr.width = MSG_EXT_WDTR_BUS_8_BIT;
- }
- ncr53c9x_setsync(sc, ti);
-
- selatn3 = selatns = 0;
- if (ecb->tag[0] != 0) {
- if (sc->sc_features & NCR_F_SELATN3)
- /* Use SELATN3 to send tag messages. */
- selatn3 = 1;
- else
- /* We don't have SELATN3; use SELATNS to send tags. */
- selatns = 1;
- }
-
- if (ti->curr.period != ti->goal.period ||
- ti->curr.offset != ti->goal.offset ||
- ti->curr.width != ti->goal.width) {
- /* We have to use SELATNS to send sync/wide messages. */
- selatn3 = 0;
- selatns = 1;
- }
-
- cmd = (uint8_t *)&ecb->cmd.cmd;
-
- if (selatn3) {
- /* We'll use tags with SELATN3. */
- clen = ecb->clen + 3;
- cmd -= 3;
- cmd[0] = MSG_IDENTIFY(lun, 1); /* msg[0] */
- cmd[1] = ecb->tag[0]; /* msg[1] */
- cmd[2] = ecb->tag[1]; /* msg[2] */
- } else {
- /* We don't have tags, or will send messages with SELATNS. */
- clen = ecb->clen + 1;
- cmd -= 1;
- cmd[0] = MSG_IDENTIFY(lun, (ti->flags & T_RSELECTOFF) == 0);
- }
-
- if ((sc->sc_features & NCR_F_DMASELECT) && !selatns) {
- /* Setup DMA transfer for command. */
- dmasize = clen;
- sc->sc_cmdlen = clen;
- sc->sc_cmdp = cmd;
- error = NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0,
- &dmasize);
- if (error != 0)
- goto cmd;
-
- /* Program the SCSI counter. */
- NCR_SET_COUNT(sc, dmasize);
-
- /* Load the count in. */
- NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA);
-
- /* And get the target's attention. */
- if (selatn3) {
- sc->sc_msgout = SEND_TAG;
- sc->sc_flags |= NCR_ATN;
- NCRCMD(sc, NCRCMD_SELATN3 | NCRCMD_DMA);
- } else
- NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA);
- NCRDMA_GO(sc);
- return;
- }
-
-cmd:
- /*
- * Who am I? This is where we tell the target that we are
- * happy for it to disconnect etc.
- */
-
- /* Now get the command into the FIFO. */
- sc->sc_cmdlen = 0;
- ncr53c9x_wrfifo(sc, cmd, clen);
-
- /* And get the target's attention. */
- if (selatns) {
- NCR_MSGS(("SELATNS \n"));
- /* Arbitrate, select and stop after IDENTIFY message. */
- NCRCMD(sc, NCRCMD_SELATNS);
- } else if (selatn3) {
- sc->sc_msgout = SEND_TAG;
- sc->sc_flags |= NCR_ATN;
- NCRCMD(sc, NCRCMD_SELATN3);
- } else
- NCRCMD(sc, NCRCMD_SELATN);
-}
-
-static void
-ncr53c9x_free_ecb(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
-{
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- ecb->flags = 0;
- TAILQ_INSERT_TAIL(&sc->free_list, ecb, free_links);
-}
-
-static struct ncr53c9x_ecb *
-ncr53c9x_get_ecb(struct ncr53c9x_softc *sc)
-{
- struct ncr53c9x_ecb *ecb;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- ecb = TAILQ_FIRST(&sc->free_list);
- if (ecb) {
- if (ecb->flags != 0)
- panic("%s: ecb flags not cleared", __func__);
- TAILQ_REMOVE(&sc->free_list, ecb, free_links);
- ecb->flags = ECB_ALLOC;
- bzero(&ecb->ccb, sizeof(struct ncr53c9x_ecb) -
- offsetof(struct ncr53c9x_ecb, ccb));
- }
- return (ecb);
-}
-
-/*
- * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS:
- */
-
-/*
- * Start a SCSI-command.
- * This function is called by the higher level SCSI-driver to queue/run
- * SCSI-commands.
- */
-
-static void
-ncr53c9x_action(struct cam_sim *sim, union ccb *ccb)
-{
- struct ccb_pathinq *cpi;
- struct ccb_scsiio *csio;
- struct ccb_trans_settings *cts;
- struct ccb_trans_settings_scsi *scsi;
- struct ccb_trans_settings_spi *spi;
- struct ncr53c9x_ecb *ecb;
- struct ncr53c9x_softc *sc;
- struct ncr53c9x_tinfo *ti;
- int target;
-
- sc = cam_sim_softc(sim);
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s %d]", __func__, ccb->ccb_h.func_code));
-
- switch (ccb->ccb_h.func_code) {
- case XPT_RESET_BUS:
- ncr53c9x_init(sc, 1);
- ccb->ccb_h.status = CAM_REQ_CMP;
- break;
-
- case XPT_CALC_GEOMETRY:
- cam_calc_geometry(&ccb->ccg, sc->sc_extended_geom);
- break;
-
- case XPT_PATH_INQ:
- cpi = &ccb->cpi;
- cpi->version_num = 1;
- cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
- cpi->hba_inquiry |=
- (sc->sc_rev == NCR_VARIANT_FAS366) ? PI_WIDE_16 : 0;
- cpi->target_sprt = 0;
- cpi->hba_misc = 0;
- cpi->hba_eng_cnt = 0;
- cpi->max_target = sc->sc_ntarg - 1;
- cpi->max_lun = 7;
- cpi->initiator_id = sc->sc_id;
- strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strlcpy(cpi->hba_vid, "NCR", HBA_IDLEN);
- strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
- cpi->unit_number = cam_sim_unit(sim);
- cpi->bus_id = 0;
- cpi->base_transfer_speed = 3300;
- cpi->protocol = PROTO_SCSI;
- cpi->protocol_version = SCSI_REV_2;
- cpi->transport = XPORT_SPI;
- cpi->transport_version = 2;
- cpi->maxio = sc->sc_maxxfer;
- ccb->ccb_h.status = CAM_REQ_CMP;
- break;
-
- case XPT_GET_TRAN_SETTINGS:
- cts = &ccb->cts;
- ti = &sc->sc_tinfo[ccb->ccb_h.target_id];
- scsi = &cts->proto_specific.scsi;
- spi = &cts->xport_specific.spi;
-
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_SPI;
- cts->transport_version = 2;
-
- if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
- spi->sync_period = ti->curr.period;
- spi->sync_offset = ti->curr.offset;
- spi->bus_width = ti->curr.width;
- if ((ti->flags & T_TAG) != 0) {
- spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
- scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
- } else {
- spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
- scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
- }
- } else {
- if ((ti->flags & T_SYNCHOFF) != 0) {
- spi->sync_period = 0;
- spi->sync_offset = 0;
- } else {
- spi->sync_period = sc->sc_minsync;
- spi->sync_offset = sc->sc_maxoffset;
- }
- spi->bus_width = sc->sc_maxwidth;
- spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
- scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
- }
- spi->valid =
- CTS_SPI_VALID_BUS_WIDTH |
- CTS_SPI_VALID_SYNC_RATE |
- CTS_SPI_VALID_SYNC_OFFSET |
- CTS_SPI_VALID_DISC;
- scsi->valid = CTS_SCSI_VALID_TQ;
- ccb->ccb_h.status = CAM_REQ_CMP;
- break;
-
- case XPT_ABORT:
- device_printf(sc->sc_dev, "XPT_ABORT called\n");
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- break;
-
- case XPT_TERM_IO:
- device_printf(sc->sc_dev, "XPT_TERM_IO called\n");
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- break;
-
- case XPT_RESET_DEV:
- case XPT_SCSI_IO:
- if (ccb->ccb_h.target_id >= sc->sc_ntarg) {
- ccb->ccb_h.status = CAM_PATH_INVALID;
- goto done;
- }
- /* Get an ECB to use. */
- ecb = ncr53c9x_get_ecb(sc);
- /*
- * This should never happen as we track resources
- * in the mid-layer.
- */
- if (ecb == NULL) {
- xpt_freeze_simq(sim, 1);
- ccb->ccb_h.status = CAM_REQUEUE_REQ;
- device_printf(sc->sc_dev, "unable to allocate ecb\n");
- goto done;
- }
-
- /* Initialize ecb. */
- ecb->ccb = ccb;
- ecb->timeout = ccb->ccb_h.timeout;
-
- if (ccb->ccb_h.func_code == XPT_RESET_DEV) {
- ecb->flags |= ECB_RESET;
- ecb->clen = 0;
- ecb->dleft = 0;
- } else {
- csio = &ccb->csio;
- if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0)
- bcopy(csio->cdb_io.cdb_ptr, &ecb->cmd.cmd,
- csio->cdb_len);
- else
- bcopy(csio->cdb_io.cdb_bytes, &ecb->cmd.cmd,
- csio->cdb_len);
- ecb->clen = csio->cdb_len;
- ecb->daddr = csio->data_ptr;
- ecb->dleft = csio->dxfer_len;
- }
- ecb->stat = 0;
-
- TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
- ecb->flags |= ECB_READY;
- if (sc->sc_state == NCR_IDLE)
- ncr53c9x_sched(sc);
- return;
-
- case XPT_SET_TRAN_SETTINGS:
- cts = &ccb->cts;
- target = ccb->ccb_h.target_id;
- ti = &sc->sc_tinfo[target];
- scsi = &cts->proto_specific.scsi;
- spi = &cts->xport_specific.spi;
-
- if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
- if ((sc->sc_cfflags & (1<<((target & 7) + 16))) == 0 &&
- (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB)) {
- NCR_MISC(("%s: target %d: tagged queuing\n",
- device_get_nameunit(sc->sc_dev), target));
- ti->flags |= T_TAG;
- } else
- ti->flags &= ~T_TAG;
- }
-
- if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
- NCR_MISC(("%s: target %d: wide negotiation\n",
- device_get_nameunit(sc->sc_dev), target));
- ti->goal.width = spi->bus_width;
- }
-
- if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
- NCR_MISC(("%s: target %d: sync period negotiation\n",
- device_get_nameunit(sc->sc_dev), target));
- ti->goal.period = spi->sync_period;
- }
-
- if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) {
- NCR_MISC(("%s: target %d: sync offset negotiation\n",
- device_get_nameunit(sc->sc_dev), target));
- ti->goal.offset = spi->sync_offset;
- }
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- break;
-
- default:
- device_printf(sc->sc_dev, "Unhandled function code %d\n",
- ccb->ccb_h.func_code);
- ccb->ccb_h.status = CAM_PROVIDE_FAIL;
- }
-
-done:
- xpt_done(ccb);
-}
-
-/*
- * Used when interrupt driven I/O is not allowed, e.g. during boot.
- */
-static void
-ncr53c9x_poll(struct cam_sim *sim)
-{
- struct ncr53c9x_softc *sc;
-
- sc = cam_sim_softc(sim);
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s] ", __func__));
-
- if (NCRDMA_ISINTR(sc))
- ncr53c9x_intr1(sc);
-}
-
-/*
- * Asynchronous notification handler
- */
-static void
-ncr53c9x_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
-{
- struct ncr53c9x_softc *sc;
- struct ncr53c9x_tinfo *ti;
- int target;
-
- sc = cam_sim_softc(cbarg);
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- switch (code) {
- case AC_LOST_DEVICE:
- target = xpt_path_target_id(path);
- if (target < 0 || target >= sc->sc_ntarg)
- break;
-
- /* Cancel outstanding disconnected commands. */
- ncr53c9x_clear_target(sc, target, CAM_REQ_ABORTED);
-
- /* Set the default parameters for the target. */
- ti = &sc->sc_tinfo[target];
-/* XXX - config flags per target: low bits: no reselect; high bits: no synch */
- ti->flags = ((sc->sc_minsync != 0 &&
- (sc->sc_cfflags & (1 << ((target & 7) + 8))) == 0) ?
- 0 : T_SYNCHOFF) |
- ((sc->sc_cfflags & (1 << (target & 7))) == 0 ?
- 0 : T_RSELECTOFF);
- ti->curr.period = ti->goal.period = 0;
- ti->curr.offset = ti->goal.offset = 0;
- ti->curr.width = ti->goal.width = MSG_EXT_WDTR_BUS_8_BIT;
- break;
- }
-}
-
-/*
- * LOW LEVEL SCSI UTILITIES
- */
-
-/*
- * Schedule a SCSI operation. This has now been pulled out of the interrupt
- * handler so that we may call it from ncr53c9x_action and ncr53c9x_done.
- * This may save us an unnecessary interrupt just to get things going.
- * Should only be called when state == NCR_IDLE and with sc_lock held.
- */
-static void
-ncr53c9x_sched(struct ncr53c9x_softc *sc)
-{
- struct ncr53c9x_ecb *ecb;
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- int lun, tag;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s] ", __func__));
-
- if (sc->sc_state != NCR_IDLE)
- panic("%s: not IDLE (state=%d)", __func__, sc->sc_state);
-
- /*
- * Find first ecb in ready queue that is for a target/lunit
- * combinations that is not busy.
- */
- TAILQ_FOREACH(ecb, &sc->ready_list, chain) {
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
- lun = ecb->ccb->ccb_h.target_lun;
-
- /* Select type of tag for this command */
- if ((ti->flags & (T_RSELECTOFF | T_TAG)) != T_TAG)
- tag = 0;
- else if ((ecb->flags & ECB_SENSE) != 0)
- tag = 0;
- else if ((ecb->ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) == 0)
- tag = 0;
- else if (ecb->ccb->csio.tag_action == CAM_TAG_ACTION_NONE)
- tag = 0;
- else
- tag = ecb->ccb->csio.tag_action;
-
- li = TINFO_LUN(ti, lun);
- if (li == NULL) {
- /* Initialize LUN info and add to list. */
- li = malloc(sizeof(*li), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (li == NULL)
- continue;
- li->lun = lun;
-
- LIST_INSERT_HEAD(&ti->luns, li, link);
- if (lun < NCR_NLUN)
- ti->lun[lun] = li;
- }
- li->last_used = time_second;
- if (tag == 0) {
- /* Try to issue this as an untagged command. */
- if (li->untagged == NULL)
- li->untagged = ecb;
- }
- if (li->untagged != NULL) {
- tag = 0;
- if ((li->busy != 1) && li->used == 0) {
- /*
- * We need to issue this untagged command
- * now.
- */
- ecb = li->untagged;
- } else {
- /* not ready, yet */
- continue;
- }
- }
- ecb->tag[0] = tag;
- if (tag != 0) {
- li->queued[ecb->tag_id] = ecb;
- ecb->tag[1] = ecb->tag_id;
- li->used++;
- }
- if (li->untagged != NULL && (li->busy != 1)) {
- li->busy = 1;
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- ecb->flags &= ~ECB_READY;
- sc->sc_nexus = ecb;
- ncr53c9x_select(sc, ecb);
- break;
- }
- if (li->untagged == NULL && tag != 0) {
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- ecb->flags &= ~ECB_READY;
- sc->sc_nexus = ecb;
- ncr53c9x_select(sc, ecb);
- break;
- } else
- NCR_TRACE(("[%s %d:%d busy] \n", __func__,
- ecb->ccb->ccb_h.target_id,
- ecb->ccb->ccb_h.target_lun));
- }
-}
-
-static void
-ncr53c9x_sense(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
-{
- union ccb *ccb = ecb->ccb;
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- struct scsi_request_sense *ss = (void *)&ecb->cmd.cmd;
- int lun;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s] ", __func__));
-
- lun = ccb->ccb_h.target_lun;
- ti = &sc->sc_tinfo[ccb->ccb_h.target_id];
-
- /* Next, setup a REQUEST SENSE command block. */
- memset(ss, 0, sizeof(*ss));
- ss->opcode = REQUEST_SENSE;
- ss->byte2 = ccb->ccb_h.target_lun << SCSI_CMD_LUN_SHIFT;
- ss->length = sizeof(struct scsi_sense_data);
- ecb->clen = sizeof(*ss);
- memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
- ecb->daddr = (uint8_t *)&ccb->csio.sense_data;
- ecb->dleft = sizeof(struct scsi_sense_data);
- ecb->flags |= ECB_SENSE;
- ecb->timeout = NCR_SENSE_TIMEOUT;
- ti->senses++;
- li = TINFO_LUN(ti, lun);
- if (li->busy)
- li->busy = 0;
- ncr53c9x_dequeue(sc, ecb);
- li->untagged = ecb; /* Must be executed first to fix C/A. */
- li->busy = 2;
- if (ecb == sc->sc_nexus)
- ncr53c9x_select(sc, ecb);
- else {
- TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
- ecb->flags |= ECB_READY;
- if (sc->sc_state == NCR_IDLE)
- ncr53c9x_sched(sc);
- }
-}
-
-/*
- * POST PROCESSING OF SCSI_CMD (usually current)
- */
-static void
-ncr53c9x_done(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
-{
- union ccb *ccb = ecb->ccb;
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- int lun, sense_returned;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s(status:%x)] ", __func__, ccb->ccb_h.status));
-
- ti = &sc->sc_tinfo[ccb->ccb_h.target_id];
- lun = ccb->ccb_h.target_lun;
- li = TINFO_LUN(ti, lun);
-
- callout_stop(&ecb->ch);
-
- /*
- * Now, if we've come here with no error code, i.e. we've kept the
- * initial CAM_REQ_CMP, and the status code signals that we should
- * check sense, we'll need to set up a request sense cmd block and
- * push the command back into the ready queue *before* any other
- * commands for this target/lunit, else we lose the sense info.
- * We don't support chk sense conditions for the request sense cmd.
- */
- if (ccb->ccb_h.status == CAM_REQ_CMP) {
- ccb->csio.scsi_status = ecb->stat;
- if ((ecb->flags & ECB_ABORT) != 0)
- ccb->ccb_h.status = CAM_CMD_TIMEOUT;
- else if ((ecb->flags & ECB_SENSE) != 0 &&
- (ecb->stat != SCSI_STATUS_CHECK_COND)) {
- ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR |
- CAM_AUTOSNS_VALID;
- sense_returned = sizeof(ccb->csio.sense_data) -
- ecb->dleft;
- if (sense_returned < ccb->csio.sense_len)
- ccb->csio.sense_resid = ccb->csio.sense_len -
- sense_returned;
- else
- ccb->csio.sense_resid = 0;
- } else if (ecb->stat == SCSI_STATUS_CHECK_COND) {
- if ((ecb->flags & ECB_SENSE) != 0)
- ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
- else {
- /* First, save the return values. */
- ccb->csio.resid = ecb->dleft;
- if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) ==
- 0) {
- ncr53c9x_sense(sc, ecb);
- return;
- }
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
- }
- } else
- ccb->csio.resid = ecb->dleft;
- if (ecb->stat == SCSI_STATUS_QUEUE_FULL)
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
- else if (ecb->stat == SCSI_STATUS_BUSY)
- ccb->ccb_h.status = CAM_SCSI_BUSY;
- } else if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
- ccb->ccb_h.status |= CAM_DEV_QFRZN;
- xpt_freeze_devq(ccb->ccb_h.path, 1);
- }
-
-#ifdef NCR53C9X_DEBUG
- if ((ncr53c9x_debug & NCR_SHOWTRAC) != 0) {
- if (ccb->csio.resid != 0)
- printf("resid=%d ", ccb->csio.resid);
- if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
- printf("sense=0x%02x\n",
- ccb->csio.sense_data.error_code);
- else
- printf("status SCSI=0x%x CAM=0x%x\n",
- ccb->csio.scsi_status, ccb->ccb_h.status);
- }
-#endif
-
- /*
- * Remove the ECB from whatever queue it's on.
- */
- ncr53c9x_dequeue(sc, ecb);
- if (ecb == sc->sc_nexus) {
- sc->sc_nexus = NULL;
- if (sc->sc_state != NCR_CLEANING) {
- sc->sc_state = NCR_IDLE;
- ncr53c9x_sched(sc);
- }
- }
-
- if ((ccb->ccb_h.status & CAM_SEL_TIMEOUT) != 0) {
- /* Selection timeout -- discard this LUN if empty. */
- if (li->untagged == NULL && li->used == 0) {
- if (lun < NCR_NLUN)
- ti->lun[lun] = NULL;
- LIST_REMOVE(li, link);
- free(li, M_DEVBUF);
- }
- }
-
- ncr53c9x_free_ecb(sc, ecb);
- ti->cmds++;
- xpt_done(ccb);
-}
-
-static void
-ncr53c9x_dequeue(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
-{
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- int64_t lun;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
- lun = ecb->ccb->ccb_h.target_lun;
- li = TINFO_LUN(ti, lun);
-#ifdef DIAGNOSTIC
- if (li == NULL || li->lun != lun)
- panic("%s: lun %llx for ecb %p does not exist", __func__,
- (long long)lun, ecb);
-#endif
- if (li->untagged == ecb) {
- li->busy = 0;
- li->untagged = NULL;
- }
- if (ecb->tag[0] && li->queued[ecb->tag[1]] != NULL) {
-#ifdef DIAGNOSTIC
- if (li->queued[ecb->tag[1]] != NULL &&
- (li->queued[ecb->tag[1]] != ecb))
- panic("%s: slot %d for lun %llx has %p instead of ecb "
- "%p", __func__, ecb->tag[1], (long long)lun,
- li->queued[ecb->tag[1]], ecb);
-#endif
- li->queued[ecb->tag[1]] = NULL;
- li->used--;
- }
- ecb->tag[0] = ecb->tag[1] = 0;
-
- if ((ecb->flags & ECB_READY) != 0) {
- ecb->flags &= ~ECB_READY;
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- }
-}
-
-/*
- * INTERRUPT/PROTOCOL ENGINE
- */
-
-/*
- * Schedule an outgoing message by prioritizing it, and asserting
- * attention on the bus. We can only do this when we are the initiator
- * else there will be an illegal command interrupt.
- */
-#define ncr53c9x_sched_msgout(m) do { \
- NCR_MSGS(("ncr53c9x_sched_msgout %x %d", m, __LINE__)); \
- NCRCMD(sc, NCRCMD_SETATN); \
- sc->sc_flags |= NCR_ATN; \
- sc->sc_msgpriq |= (m); \
-} while (/* CONSTCOND */0)
-
-static void
-ncr53c9x_flushfifo(struct ncr53c9x_softc *sc)
-{
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s] ", __func__));
-
- NCRCMD(sc, NCRCMD_FLUSH);
-
- if (sc->sc_phase == COMMAND_PHASE ||
- sc->sc_phase == MESSAGE_OUT_PHASE)
- DELAY(2);
-}
-
-static int
-ncr53c9x_rdfifo(struct ncr53c9x_softc *sc, int how)
-{
- int i, n;
- uint8_t *ibuf;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- switch (how) {
- case NCR_RDFIFO_START:
- ibuf = sc->sc_imess;
- sc->sc_imlen = 0;
- break;
-
- case NCR_RDFIFO_CONTINUE:
- ibuf = sc->sc_imess + sc->sc_imlen;
- break;
-
- default:
- panic("%s: bad flag", __func__);
- /* NOTREACHED */
- }
-
- /*
- * XXX buffer (sc_imess) size for message
- */
-
- n = NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF;
-
- if (sc->sc_rev == NCR_VARIANT_FAS366) {
- n *= 2;
-
- for (i = 0; i < n; i++)
- ibuf[i] = NCR_READ_REG(sc, NCR_FIFO);
-
- if (sc->sc_espstat2 & NCRFAS_STAT2_ISHUTTLE) {
-
- NCR_WRITE_REG(sc, NCR_FIFO, 0);
- ibuf[i++] = NCR_READ_REG(sc, NCR_FIFO);
-
- NCR_READ_REG(sc, NCR_FIFO);
-
- ncr53c9x_flushfifo(sc);
- }
- } else
- for (i = 0; i < n; i++)
- ibuf[i] = NCR_READ_REG(sc, NCR_FIFO);
-
- sc->sc_imlen += i;
-
-#if 0
-#ifdef NCR53C9X_DEBUG
- NCR_TRACE(("\n[rdfifo %s (%d):",
- (how == NCR_RDFIFO_START) ? "start" : "cont", (int)sc->sc_imlen));
- if ((ncr53c9x_debug & NCR_SHOWTRAC) != 0) {
- for (i = 0; i < sc->sc_imlen; i++)
- printf(" %02x", sc->sc_imess[i]);
- printf("]\n");
- }
-#endif
-#endif
- return (sc->sc_imlen);
-}
-
-static void
-ncr53c9x_wrfifo(struct ncr53c9x_softc *sc, uint8_t *p, int len)
-{
- int i;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
-#ifdef NCR53C9X_DEBUG
- NCR_MSGS(("[wrfifo(%d):", len));
- if ((ncr53c9x_debug & NCR_SHOWMSGS) != 0) {
- for (i = 0; i < len; i++)
- printf(" %02x", p[i]);
- printf("]\n");
- }
-#endif
-
- for (i = 0; i < len; i++) {
- NCR_WRITE_REG(sc, NCR_FIFO, p[i]);
-
- if (sc->sc_rev == NCR_VARIANT_FAS366)
- NCR_WRITE_REG(sc, NCR_FIFO, 0);
- }
-}
-
-static int
-ncr53c9x_reselect(struct ncr53c9x_softc *sc, int message, int tagtype,
- int tagid)
-{
- struct ncr53c9x_ecb *ecb = NULL;
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- uint8_t lun, selid, target;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- if (sc->sc_rev == NCR_VARIANT_FAS366)
- target = sc->sc_selid;
- else {
- /*
- * The SCSI chip made a snapshot of the data bus
- * while the reselection was being negotiated.
- * This enables us to determine which target did
- * the reselect.
- */
- selid = sc->sc_selid & ~(1 << sc->sc_id);
- if (selid & (selid - 1)) {
- device_printf(sc->sc_dev, "reselect with invalid "
- "selid %02x; sending DEVICE RESET\n", selid);
- goto reset;
- }
-
- target = ffs(selid) - 1;
- }
- lun = message & 0x07;
-
- /*
- * Search wait queue for disconnected command.
- * The list should be short, so I haven't bothered with
- * any more sophisticated structures than a simple
- * singly linked list.
- */
- ti = &sc->sc_tinfo[target];
- li = TINFO_LUN(ti, lun);
-
- /*
- * We can get as far as the LUN with the IDENTIFY
- * message. Check to see if we're running an
- * untagged command. Otherwise ack the IDENTIFY
- * and wait for a tag message.
- */
- if (li != NULL) {
- if (li->untagged != NULL && li->busy)
- ecb = li->untagged;
- else if (tagtype != MSG_SIMPLE_Q_TAG) {
- /* Wait for tag to come by. */
- sc->sc_state = NCR_IDENTIFIED;
- return (0);
- } else if (tagtype)
- ecb = li->queued[tagid];
- }
- if (ecb == NULL) {
- device_printf(sc->sc_dev, "reselect from target %d lun %d "
- "tag %x:%x with no nexus; sending ABORT\n",
- target, lun, tagtype, tagid);
- goto abort;
- }
-
- /* Make this nexus active again. */
- sc->sc_state = NCR_CONNECTED;
- sc->sc_nexus = ecb;
- ncr53c9x_setsync(sc, ti);
-
- if (ecb->flags & ECB_RESET)
- ncr53c9x_sched_msgout(SEND_DEV_RESET);
- else if (ecb->flags & ECB_ABORT)
- ncr53c9x_sched_msgout(SEND_ABORT);
-
- /* Do an implicit RESTORE POINTERS. */
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
-
- return (0);
-
-reset:
- ncr53c9x_sched_msgout(SEND_DEV_RESET);
- return (1);
-
-abort:
- ncr53c9x_sched_msgout(SEND_ABORT);
- return (1);
-}
-
-/* From NetBSD; these should go into CAM at some point. */
-#define MSG_ISEXTENDED(m) ((m) == MSG_EXTENDED)
-#define MSG_IS1BYTE(m) \
- ((!MSG_ISEXTENDED(m) && (m) < 0x20) || MSG_ISIDENTIFY(m))
-#define MSG_IS2BYTE(m) (((m) & 0xf0) == 0x20)
-
-static inline int
-__verify_msg_format(uint8_t *p, int len)
-{
-
- if (len == 1 && MSG_IS1BYTE(p[0]))
- return (1);
- if (len == 2 && MSG_IS2BYTE(p[0]))
- return (1);
- if (len >= 3 && MSG_ISEXTENDED(p[0]) &&
- len == p[1] + 2)
- return (1);
-
- return (0);
-}
-
-/*
- * Get an incoming message as initiator.
- *
- * The SCSI bus must already be in MESSAGE_IN_PHASE and there is a
- * byte in the FIFO.
- */
-static void
-ncr53c9x_msgin(struct ncr53c9x_softc *sc)
-{
- struct ncr53c9x_ecb *ecb;
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- uint8_t *pb;
- int len, lun;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s(curmsglen:%ld)] ", __func__, (long)sc->sc_imlen));
-
- if (sc->sc_imlen == 0) {
- device_printf(sc->sc_dev, "msgin: no msg byte available\n");
- return;
- }
-
- /*
- * Prepare for a new message. A message should (according
- * to the SCSI standard) be transmitted in one single
- * MESSAGE_IN_PHASE. If we have been in some other phase,
- * then this is a new message.
- */
- if (sc->sc_prevphase != MESSAGE_IN_PHASE &&
- sc->sc_state != NCR_RESELECTED) {
- device_printf(sc->sc_dev, "phase change, dropping message, "
- "prev %d, state %d\n", sc->sc_prevphase, sc->sc_state);
- sc->sc_flags &= ~NCR_DROP_MSGI;
- sc->sc_imlen = 0;
- }
-
- /*
- * If we're going to reject the message, don't bother storing
- * the incoming bytes. But still, we need to ACK them.
- */
- if ((sc->sc_flags & NCR_DROP_MSGI) != 0) {
- NCRCMD(sc, NCRCMD_MSGOK);
- device_printf(sc->sc_dev, "<dropping msg byte %x>",
- sc->sc_imess[sc->sc_imlen]);
- return;
- }
-
- if (sc->sc_imlen >= NCR_MAX_MSG_LEN) {
- ncr53c9x_sched_msgout(SEND_REJECT);
- sc->sc_flags |= NCR_DROP_MSGI;
- } else {
- switch (sc->sc_state) {
- /*
- * if received message is the first of reselection
- * then first byte is selid, and then message
- */
- case NCR_RESELECTED:
- pb = sc->sc_imess + 1;
- len = sc->sc_imlen - 1;
- break;
-
- default:
- pb = sc->sc_imess;
- len = sc->sc_imlen;
- }
-
- if (__verify_msg_format(pb, len))
- goto gotit;
- }
-
- /* Acknowledge what we have so far. */
- NCRCMD(sc, NCRCMD_MSGOK);
- return;
-
-gotit:
- NCR_MSGS(("gotmsg(%x) state %d", sc->sc_imess[0], sc->sc_state));
- /*
- * We got a complete message, flush the imess.
- * XXX nobody uses imlen below.
- */
- sc->sc_imlen = 0;
- /*
- * Now we should have a complete message (1 byte, 2 byte
- * and moderately long extended messages). We only handle
- * extended messages which total length is shorter than
- * NCR_MAX_MSG_LEN. Longer messages will be amputated.
- */
- switch (sc->sc_state) {
- case NCR_CONNECTED:
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
-
- switch (sc->sc_imess[0]) {
- case MSG_CMDCOMPLETE:
- NCR_MSGS(("cmdcomplete "));
- if (sc->sc_dleft < 0) {
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("got %ld extra bytes\n",
- -(long)sc->sc_dleft);
- sc->sc_dleft = 0;
- }
- ecb->dleft = (ecb->flags & ECB_TENTATIVE_DONE) ?
- 0 : sc->sc_dleft;
- if ((ecb->flags & ECB_SENSE) == 0)
- ecb->ccb->csio.resid = ecb->dleft;
- sc->sc_state = NCR_CMDCOMPLETE;
- break;
-
- case MSG_MESSAGE_REJECT:
- NCR_MSGS(("msg reject (msgout=%x) ", sc->sc_msgout));
- switch (sc->sc_msgout) {
- case SEND_TAG:
- /*
- * Target does not like tagged queuing.
- * - Flush the command queue
- * - Disable tagged queuing for the target
- * - Dequeue ecb from the queued array.
- */
- device_printf(sc->sc_dev, "tagged queuing "
- "rejected: target %d\n",
- ecb->ccb->ccb_h.target_id);
-
- NCR_MSGS(("(rejected sent tag)"));
- NCRCMD(sc, NCRCMD_FLUSH);
- DELAY(1);
- ti->flags &= ~T_TAG;
- lun = ecb->ccb->ccb_h.target_lun;
- li = TINFO_LUN(ti, lun);
- if (ecb->tag[0] &&
- li->queued[ecb->tag[1]] != NULL) {
- li->queued[ecb->tag[1]] = NULL;
- li->used--;
- }
- ecb->tag[0] = ecb->tag[1] = 0;
- li->untagged = ecb;
- li->busy = 1;
- break;
-
- case SEND_SDTR:
- device_printf(sc->sc_dev, "sync transfer "
- "rejected: target %d\n",
- ecb->ccb->ccb_h.target_id);
-
- ti->flags &= ~T_SDTRSENT;
- ti->curr.period = ti->goal.period = 0;
- ti->curr.offset = ti->goal.offset = 0;
- ncr53c9x_setsync(sc, ti);
- break;
-
- case SEND_WDTR:
- device_printf(sc->sc_dev, "wide transfer "
- "rejected: target %d\n",
- ecb->ccb->ccb_h.target_id);
-
- ti->flags &= ~T_WDTRSENT;
- ti->curr.width = ti->goal.width =
- MSG_EXT_WDTR_BUS_8_BIT;
- ncr53c9x_setsync(sc, ti);
- break;
-
- case SEND_INIT_DET_ERR:
- goto abort;
- }
- break;
-
- case MSG_NOOP:
- NCR_MSGS(("noop "));
- break;
-
- case MSG_HEAD_OF_Q_TAG:
- case MSG_SIMPLE_Q_TAG:
- case MSG_ORDERED_Q_TAG:
- NCR_MSGS(("TAG %x:%x",
- sc->sc_imess[0], sc->sc_imess[1]));
- break;
-
- case MSG_DISCONNECT:
- NCR_MSGS(("disconnect "));
- ti->dconns++;
- sc->sc_state = NCR_DISCONNECT;
-
- /*
- * Mark the fact that all bytes have moved. The
- * target may not bother to do a SAVE POINTERS
- * at this stage. This flag will set the residual
- * count to zero on MSG COMPLETE.
- */
- if (sc->sc_dleft == 0)
- ecb->flags |= ECB_TENTATIVE_DONE;
- break;
-
- case MSG_SAVEDATAPOINTER:
- NCR_MSGS(("save datapointer "));
- ecb->daddr = sc->sc_dp;
- ecb->dleft = sc->sc_dleft;
- break;
-
- case MSG_RESTOREPOINTERS:
- NCR_MSGS(("restore datapointer "));
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- break;
-
- case MSG_IGN_WIDE_RESIDUE:
- NCR_MSGS(("ignore wide residue (%d bytes)",
- sc->sc_imess[1]));
- if (sc->sc_imess[1] != 1) {
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("unexpected MESSAGE IGNORE WIDE "
- "RESIDUE (%d bytes); sending REJECT\n",
- sc->sc_imess[1]);
- goto reject;
- }
- /*
- * If there was a last transfer of an even number of
- * bytes, wipe the "done" memory and adjust by one
- * byte (sc->sc_imess[1]).
- */
- len = sc->sc_dleft - ecb->dleft;
- if (len != 0 && (len & 1) == 0) {
- ecb->flags &= ~ECB_TENTATIVE_DONE;
- sc->sc_dp = (char *)sc->sc_dp - 1;
- sc->sc_dleft--;
- }
- break;
-
- case MSG_EXTENDED:
- NCR_MSGS(("extended(%x) ", sc->sc_imess[2]));
- switch (sc->sc_imess[2]) {
- case MSG_EXT_SDTR:
- NCR_MSGS(("SDTR period %d, offset %d ",
- sc->sc_imess[3], sc->sc_imess[4]));
- if (sc->sc_imess[1] != 3)
- goto reject;
- ti->curr.period = sc->sc_imess[3];
- ti->curr.offset = sc->sc_imess[4];
- if (sc->sc_minsync == 0 ||
- ti->curr.offset == 0 ||
- ti->curr.period > 124) {
-#if 0
-#ifdef NCR53C9X_DEBUG
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("async mode\n");
-#endif
-#endif
- if ((ti->flags & T_SDTRSENT) == 0) {
- /*
- * target initiated negotiation
- */
- ti->curr.offset = 0;
- ncr53c9x_sched_msgout(
- SEND_SDTR);
- }
- } else {
- ti->curr.period =
- ncr53c9x_cpb2stp(sc,
- ncr53c9x_stp2cpb(sc,
- ti->curr.period));
- if ((ti->flags & T_SDTRSENT) == 0) {
- /*
- * target initiated negotiation
- */
- if (ti->curr.period <
- sc->sc_minsync)
- ti->curr.period =
- sc->sc_minsync;
- if (ti->curr.offset >
- sc->sc_maxoffset)
- ti->curr.offset =
- sc->sc_maxoffset;
- ncr53c9x_sched_msgout(
- SEND_SDTR);
- }
- }
- ti->flags &= ~T_SDTRSENT;
- ti->goal.period = ti->curr.period;
- ti->goal.offset = ti->curr.offset;
- ncr53c9x_setsync(sc, ti);
- break;
-
- case MSG_EXT_WDTR:
- NCR_MSGS(("wide mode %d ", sc->sc_imess[3]));
- ti->curr.width = sc->sc_imess[3];
- if (!(ti->flags & T_WDTRSENT))
- /*
- * target initiated negotiation
- */
- ncr53c9x_sched_msgout(SEND_WDTR);
- ti->flags &= ~T_WDTRSENT;
- ti->goal.width = ti->curr.width;
- ncr53c9x_setsync(sc, ti);
- break;
-
- default:
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("unrecognized MESSAGE EXTENDED 0x%x;"
- " sending REJECT\n", sc->sc_imess[2]);
- goto reject;
- }
- break;
-
- default:
- NCR_MSGS(("ident "));
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("unrecognized MESSAGE 0x%x; sending REJECT\n",
- sc->sc_imess[0]);
- /* FALLTHROUGH */
- reject:
- ncr53c9x_sched_msgout(SEND_REJECT);
- break;
- }
- break;
-
- case NCR_IDENTIFIED:
- /*
- * IDENTIFY message was received and queue tag is expected
- * now.
- */
- if ((sc->sc_imess[0] != MSG_SIMPLE_Q_TAG) ||
- (sc->sc_msgify == 0)) {
- device_printf(sc->sc_dev, "TAG reselect without "
- "IDENTIFY; MSG %x; sending DEVICE RESET\n",
- sc->sc_imess[0]);
- goto reset;
- }
- (void)ncr53c9x_reselect(sc, sc->sc_msgify,
- sc->sc_imess[0], sc->sc_imess[1]);
- break;
-
- case NCR_RESELECTED:
- if (MSG_ISIDENTIFY(sc->sc_imess[1]))
- sc->sc_msgify = sc->sc_imess[1];
- else {
- device_printf(sc->sc_dev, "reselect without IDENTIFY;"
- " MSG %x; sending DEVICE RESET\n", sc->sc_imess[1]);
- goto reset;
- }
- (void)ncr53c9x_reselect(sc, sc->sc_msgify, 0, 0);
- break;
-
- default:
- device_printf(sc->sc_dev, "unexpected MESSAGE IN; "
- "sending DEVICE RESET\n");
- /* FALLTHROUGH */
- reset:
- ncr53c9x_sched_msgout(SEND_DEV_RESET);
- break;
-
- abort:
- ncr53c9x_sched_msgout(SEND_ABORT);
- }
-
- /* If we have more messages to send set ATN. */
- if (sc->sc_msgpriq) {
- NCRCMD(sc, NCRCMD_SETATN);
- sc->sc_flags |= NCR_ATN;
- }
-
- /* Acknowledge last message byte. */
- NCRCMD(sc, NCRCMD_MSGOK);
-
- /* Done, reset message pointer. */
- sc->sc_flags &= ~NCR_DROP_MSGI;
- sc->sc_imlen = 0;
-}
-
-/*
- * Send the highest priority, scheduled message.
- */
-static void
-ncr53c9x_msgout(struct ncr53c9x_softc *sc)
-{
- struct ncr53c9x_tinfo *ti;
- struct ncr53c9x_ecb *ecb;
- size_t size;
- int error;
-#ifdef NCR53C9X_DEBUG
- int i;
-#endif
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_TRACE(("[%s(priq:%x, prevphase:%x)]", __func__, sc->sc_msgpriq,
- sc->sc_prevphase));
-
- /*
- * XXX - the NCR_ATN flag is not in sync with the actual ATN
- * condition on the SCSI bus. The 53c9x chip
- * automatically turns off ATN before sending the
- * message byte. (See also the comment below in the
- * default case when picking out a message to send.)
- */
- if (sc->sc_flags & NCR_ATN) {
- if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
- new:
- NCRCMD(sc, NCRCMD_FLUSH);
-#if 0
- DELAY(1);
-#endif
- sc->sc_msgoutq = 0;
- sc->sc_omlen = 0;
- }
- } else {
- if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
- ncr53c9x_sched_msgout(sc->sc_msgoutq);
- goto new;
- } else
- device_printf(sc->sc_dev, "at line %d: unexpected "
- "MESSAGE OUT phase\n", __LINE__);
- }
-
- if (sc->sc_omlen == 0) {
- /* Pick up highest priority message. */
- sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
- sc->sc_msgoutq |= sc->sc_msgout;
- sc->sc_msgpriq &= ~sc->sc_msgout;
- sc->sc_omlen = 1; /* "Default" message len */
- switch (sc->sc_msgout) {
- case SEND_SDTR:
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
- sc->sc_omess[0] = MSG_EXTENDED;
- sc->sc_omess[1] = MSG_EXT_SDTR_LEN;
- sc->sc_omess[2] = MSG_EXT_SDTR;
- sc->sc_omess[3] = ti->goal.period;
- sc->sc_omess[4] = ti->goal.offset;
- sc->sc_omlen = 5;
- break;
-
- case SEND_WDTR:
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
- sc->sc_omess[0] = MSG_EXTENDED;
- sc->sc_omess[1] = MSG_EXT_WDTR_LEN;
- sc->sc_omess[2] = MSG_EXT_WDTR;
- sc->sc_omess[3] = ti->goal.width;
- sc->sc_omlen = 4;
- break;
-
- case SEND_IDENTIFY:
- if (sc->sc_state != NCR_CONNECTED)
- device_printf(sc->sc_dev, "at line %d: no "
- "nexus\n", __LINE__);
- ecb = sc->sc_nexus;
- sc->sc_omess[0] =
- MSG_IDENTIFY(ecb->ccb->ccb_h.target_lun, 0);
- break;
-
- case SEND_TAG:
- if (sc->sc_state != NCR_CONNECTED)
- device_printf(sc->sc_dev, "at line %d: no "
- "nexus\n", __LINE__);
- ecb = sc->sc_nexus;
- sc->sc_omess[0] = ecb->tag[0];
- sc->sc_omess[1] = ecb->tag[1];
- sc->sc_omlen = 2;
- break;
-
- case SEND_DEV_RESET:
- sc->sc_flags |= NCR_ABORTING;
- sc->sc_omess[0] = MSG_BUS_DEV_RESET;
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
- ti->curr.period = 0;
- ti->curr.offset = 0;
- ti->curr.width = MSG_EXT_WDTR_BUS_8_BIT;
- break;
-
- case SEND_PARITY_ERROR:
- sc->sc_omess[0] = MSG_PARITY_ERROR;
- break;
-
- case SEND_ABORT:
- sc->sc_flags |= NCR_ABORTING;
- sc->sc_omess[0] = MSG_ABORT;
- break;
-
- case SEND_INIT_DET_ERR:
- sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
- break;
-
- case SEND_REJECT:
- sc->sc_omess[0] = MSG_MESSAGE_REJECT;
- break;
-
- default:
- /*
- * We normally do not get here, since the chip
- * automatically turns off ATN before the last
- * byte of a message is sent to the target.
- * However, if the target rejects our (multi-byte)
- * message early by switching to MSG IN phase
- * ATN remains on, so the target may return to
- * MSG OUT phase. If there are no scheduled messages
- * left we send a NO-OP.
- *
- * XXX - Note that this leaves no useful purpose for
- * the NCR_ATN flag.
- */
- sc->sc_flags &= ~NCR_ATN;
- sc->sc_omess[0] = MSG_NOOP;
- }
- sc->sc_omp = sc->sc_omess;
- }
-
-#ifdef NCR53C9X_DEBUG
- if ((ncr53c9x_debug & NCR_SHOWMSGS) != 0) {
- NCR_MSGS(("<msgout:"));
- for (i = 0; i < sc->sc_omlen; i++)
- NCR_MSGS((" %02x", sc->sc_omess[i]));
- NCR_MSGS(("> "));
- }
-#endif
-
- if (sc->sc_rev != NCR_VARIANT_FAS366) {
- /* (Re)send the message. */
- size = ulmin(sc->sc_omlen, sc->sc_maxxfer);
- error = NCRDMA_SETUP(sc, &sc->sc_omp, &sc->sc_omlen, 0, &size);
- if (error != 0)
- goto cmd;
-
- /* Program the SCSI counter. */
- NCR_SET_COUNT(sc, size);
-
- /* Load the count in and start the message-out transfer. */
- NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA);
- NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA);
- NCRDMA_GO(sc);
- return;
- }
-
-cmd:
- /*
- * XXX FIFO size
- */
- sc->sc_cmdlen = 0;
- ncr53c9x_flushfifo(sc);
- ncr53c9x_wrfifo(sc, sc->sc_omp, sc->sc_omlen);
- NCRCMD(sc, NCRCMD_TRANS);
-}
-
-void
-ncr53c9x_intr(void *arg)
-{
- struct ncr53c9x_softc *sc = arg;
-
- if (!NCRDMA_ISINTR(sc))
- return;
-
- NCR_LOCK(sc);
-
- ncr53c9x_intr1(sc);
-
- NCR_UNLOCK(sc);
-}
-
-/*
- * This is the most critical part of the driver, and has to know
- * how to deal with *all* error conditions and phases from the SCSI
- * bus. If there are no errors and the DMA was active, then call the
- * DMA pseudo-interrupt handler. If this returns 1, then that was it
- * and we can return from here without further processing.
- *
- * Most of this needs verifying.
- */
-static void
-ncr53c9x_intr1(struct ncr53c9x_softc *sc)
-{
- struct ncr53c9x_ecb *ecb;
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- struct timeval cur, wait;
- size_t size;
- int error, i, nfifo;
- uint8_t msg;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- NCR_INTS(("[ncr53c9x_intr: state %d]", sc->sc_state));
-
-again:
- /* and what do the registers say... */
- ncr53c9x_readregs(sc);
-
- /*
- * At the moment, only a SCSI Bus Reset or Illegal
- * Command are classed as errors. A disconnect is a
- * valid condition, and we let the code check is the
- * "NCR_BUSFREE_OK" flag was set before declaring it
- * and error.
- *
- * Also, the status register tells us about "Gross
- * Errors" and "Parity errors". Only the Gross Error
- * is really bad, and the parity errors are dealt
- * with later.
- *
- * TODO
- * If there are too many parity error, go to slow
- * cable mode?
- */
-
- if ((sc->sc_espintr & NCRINTR_SBR) != 0) {
- if ((NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) != 0) {
- NCRCMD(sc, NCRCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state != NCR_SBR) {
- device_printf(sc->sc_dev, "SCSI bus reset\n");
- ncr53c9x_init(sc, 0); /* Restart everything. */
- return;
- }
-#if 0
-/*XXX*/ device_printf(sc->sc_dev, "<expected bus reset: "
- "[intr %x, stat %x, step %d]>\n",
- sc->sc_espintr, sc->sc_espstat, sc->sc_espstep);
-#endif
- if (sc->sc_nexus != NULL)
- panic("%s: nexus in reset state",
- device_get_nameunit(sc->sc_dev));
- goto sched;
- }
-
- ecb = sc->sc_nexus;
-
-#define NCRINTR_ERR (NCRINTR_SBR | NCRINTR_ILL)
- if (sc->sc_espintr & NCRINTR_ERR ||
- sc->sc_espstat & NCRSTAT_GE) {
- if ((sc->sc_espstat & NCRSTAT_GE) != 0) {
- /* Gross Error; no target? */
- if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
- NCRCMD(sc, NCRCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state == NCR_CONNECTED ||
- sc->sc_state == NCR_SELECTING) {
- ecb->ccb->ccb_h.status = CAM_SEL_TIMEOUT;
- ncr53c9x_done(sc, ecb);
- }
- return;
- }
-
- if ((sc->sc_espintr & NCRINTR_ILL) != 0) {
- if ((sc->sc_flags & NCR_EXPECT_ILLCMD) != 0) {
- /*
- * Eat away "Illegal command" interrupt
- * on a ESP100 caused by a re-selection
- * while we were trying to select
- * another target.
- */
-#ifdef NCR53C9X_DEBUG
- device_printf(sc->sc_dev, "ESP100 work-around "
- "activated\n");
-#endif
- sc->sc_flags &= ~NCR_EXPECT_ILLCMD;
- return;
- }
- /* Illegal command, out of sync? */
- device_printf(sc->sc_dev, "illegal command: 0x%x "
- "(state %d, phase %x, prevphase %x)\n",
- sc->sc_lastcmd,
- sc->sc_state, sc->sc_phase, sc->sc_prevphase);
- if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
- NCRCMD(sc, NCRCMD_FLUSH);
- DELAY(1);
- }
- goto reset;
- }
- }
- sc->sc_flags &= ~NCR_EXPECT_ILLCMD;
-
- /*
- * Call if DMA is active.
- *
- * If DMA_INTR returns true, then maybe go 'round the loop
- * again in case there is no more DMA queued, but a phase
- * change is expected.
- */
- if (NCRDMA_ISACTIVE(sc)) {
- if (NCRDMA_INTR(sc) == -1) {
- device_printf(sc->sc_dev, "DMA error; resetting\n");
- goto reset;
- }
- /* If DMA active here, then go back to work... */
- if (NCRDMA_ISACTIVE(sc))
- return;
-
- if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
- /*
- * DMA not completed. If we can not find a
- * acceptable explanation, print a diagnostic.
- */
- if (sc->sc_state == NCR_SELECTING)
- /*
- * This can happen if we are reselected
- * while using DMA to select a target.
- */
- /*void*/;
- else if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
- /*
- * Our (multi-byte) message (eg SDTR) was
- * interrupted by the target to send
- * a MSG REJECT.
- * Print diagnostic if current phase
- * is not MESSAGE IN.
- */
- if (sc->sc_phase != MESSAGE_IN_PHASE)
- device_printf(sc->sc_dev,"!TC on MSGOUT"
- " [intr %x, stat %x, step %d]"
- " prevphase %x, resid %lx\n",
- sc->sc_espintr,
- sc->sc_espstat,
- sc->sc_espstep,
- sc->sc_prevphase,
- (u_long)sc->sc_omlen);
- } else if (sc->sc_dleft == 0) {
- /*
- * The DMA operation was started for
- * a DATA transfer. Print a diagnostic
- * if the DMA counter and TC bit
- * appear to be out of sync.
- *
- * XXX This is fatal and usually means that
- * the DMA engine is hopelessly out of
- * sync with reality. A disk is likely
- * getting spammed at this point.
- */
- device_printf(sc->sc_dev, "!TC on DATA XFER"
- " [intr %x, stat %x, step %d]"
- " prevphase %x, resid %x\n",
- sc->sc_espintr,
- sc->sc_espstat,
- sc->sc_espstep,
- sc->sc_prevphase,
- ecb ? ecb->dleft : -1);
- goto reset;
- }
- }
- }
-
- /*
- * Check for less serious errors.
- */
- if ((sc->sc_espstat & NCRSTAT_PE) != 0) {
- device_printf(sc->sc_dev, "SCSI bus parity error\n");
- if (sc->sc_prevphase == MESSAGE_IN_PHASE)
- ncr53c9x_sched_msgout(SEND_PARITY_ERROR);
- else
- ncr53c9x_sched_msgout(SEND_INIT_DET_ERR);
- }
-
- if ((sc->sc_espintr & NCRINTR_DIS) != 0) {
- sc->sc_msgify = 0;
- NCR_INTS(("<DISC [intr %x, stat %x, step %d]>",
- sc->sc_espintr,sc->sc_espstat,sc->sc_espstep));
- if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
- NCRCMD(sc, NCRCMD_FLUSH);
-#if 0
- DELAY(1);
-#endif
- }
- /*
- * This command must (apparently) be issued within
- * 250mS of a disconnect. So here you are...
- */
- NCRCMD(sc, NCRCMD_ENSEL);
-
- switch (sc->sc_state) {
- case NCR_RESELECTED:
- goto sched;
-
- case NCR_SELECTING:
- ecb->ccb->ccb_h.status = CAM_SEL_TIMEOUT;
-
- /* Selection timeout -- discard all LUNs if empty. */
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
- li = LIST_FIRST(&ti->luns);
- while (li != NULL) {
- if (li->untagged == NULL && li->used == 0) {
- if (li->lun < NCR_NLUN)
- ti->lun[li->lun] = NULL;
- LIST_REMOVE(li, link);
- free(li, M_DEVBUF);
- /*
- * Restart the search at the beginning.
- */
- li = LIST_FIRST(&ti->luns);
- continue;
- }
- li = LIST_NEXT(li, link);
- }
- goto finish;
-
- case NCR_CONNECTED:
- if (ecb != NULL) {
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
- if ((ti->flags & T_SDTRSENT) != 0) {
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("sync nego not completed!\n");
- ti->flags &= ~T_SDTRSENT;
- ti->curr.period = ti->goal.period = 0;
- ti->curr.offset = ti->goal.offset = 0;
- ncr53c9x_setsync(sc, ti);
- }
- if ((ti->flags & T_WDTRSENT) != 0) {
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("wide nego not completed!\n");
- ti->flags &= ~T_WDTRSENT;
- ti->curr.width = ti->goal.width =
- MSG_EXT_WDTR_BUS_8_BIT;
- ncr53c9x_setsync(sc, ti);
- }
- }
-
- /* It may be OK to disconnect. */
- if ((sc->sc_flags & NCR_ABORTING) == 0) {
- /*
- * Section 5.1.1 of the SCSI 2 spec
- * suggests issuing a REQUEST SENSE
- * following an unexpected disconnect.
- * Some devices go into a contingent
- * allegiance condition when
- * disconnecting, and this is necessary
- * to clean up their state.
- */
- device_printf(sc->sc_dev, "unexpected "
- "disconnect [state %d, intr %x, stat %x, "
- "phase(c %x, p %x)]; ", sc->sc_state,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_phase, sc->sc_prevphase);
-
- /*
- * XXX This will cause a chip reset and will
- * prevent us from finding out the real
- * problem with the device. However, it's
- * necessary until a way can be found to
- * safely cancel the DMA that is in
- * progress.
- */
- if (1 || (ecb->flags & ECB_SENSE) != 0) {
- printf("resetting\n");
- goto reset;
- }
- printf("sending REQUEST SENSE\n");
- callout_stop(&ecb->ch);
- ncr53c9x_sense(sc, ecb);
- return;
- } else if (ecb != NULL &&
- (ecb->flags & ECB_RESET) != 0) {
- ecb->ccb->ccb_h.status = CAM_REQ_CMP;
- goto finish;
- }
-
- ecb->ccb->ccb_h.status = CAM_CMD_TIMEOUT;
- goto finish;
-
- case NCR_DISCONNECT:
- sc->sc_nexus = NULL;
- goto sched;
-
- case NCR_CMDCOMPLETE:
- ecb->ccb->ccb_h.status = CAM_REQ_CMP;
- goto finish;
- }
- }
-
- switch (sc->sc_state) {
- case NCR_SBR:
- device_printf(sc->sc_dev, "waiting for Bus Reset to happen\n");
- return;
-
- case NCR_RESELECTED:
- /*
- * We must be continuing a message?
- */
- device_printf(sc->sc_dev, "unhandled reselect continuation, "
- "state %d, intr %02x\n", sc->sc_state, sc->sc_espintr);
- goto reset;
- break;
-
- case NCR_IDENTIFIED:
- ecb = sc->sc_nexus;
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- i = NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF;
- /*
- * Things are seriously screwed up.
- * Pull the brakes, i.e. reset.
- */
- device_printf(sc->sc_dev, "target didn't send tag: %d "
- "bytes in FIFO\n", i);
- /* Drain and display FIFO. */
- while (i-- > 0)
- printf("[%d] ", NCR_READ_REG(sc, NCR_FIFO));
-
- goto reset;
- } else
- goto msgin;
-
- case NCR_IDLE:
- case NCR_SELECTING:
- ecb = sc->sc_nexus;
- if (sc->sc_espintr & NCRINTR_RESEL) {
- sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0;
- sc->sc_flags = 0;
- /*
- * If we're trying to select a
- * target ourselves, push our command
- * back into the ready list.
- */
- if (sc->sc_state == NCR_SELECTING) {
- NCR_INTS(("backoff selector "));
- callout_stop(&ecb->ch);
- ncr53c9x_dequeue(sc, ecb);
- TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
- ecb->flags |= ECB_READY;
- ecb = sc->sc_nexus = NULL;
- }
- sc->sc_state = NCR_RESELECTED;
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- /*
- * Things are seriously screwed up.
- * Pull the brakes, i.e. reset
- */
- device_printf(sc->sc_dev, "target didn't "
- "identify\n");
- goto reset;
- }
- /*
- * The C90 only inhibits FIFO writes until reselection
- * is complete instead of waiting until the interrupt
- * status register has been read. So, if the reselect
- * happens while we were entering command bytes (for
- * another target) some of those bytes can appear in
- * the FIFO here, after the interrupt is taken.
- *
- * To remedy this situation, pull the Selection ID
- * and Identify message from the FIFO directly, and
- * ignore any extraneous FIFO contents. Also, set
- * a flag that allows one Illegal Command Interrupt
- * to occur which the chip also generates as a result
- * of writing to the FIFO during a reselect.
- */
- if (sc->sc_rev == NCR_VARIANT_ESP100) {
- nfifo =
- NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF;
- sc->sc_imess[0] = NCR_READ_REG(sc, NCR_FIFO);
- sc->sc_imess[1] = NCR_READ_REG(sc, NCR_FIFO);
- sc->sc_imlen = 2;
- if (nfifo != 2) {
- /* Flush the rest. */
- NCRCMD(sc, NCRCMD_FLUSH);
- }
- sc->sc_flags |= NCR_EXPECT_ILLCMD;
- if (nfifo > 2)
- nfifo = 2; /* We fixed it... */
- } else
- nfifo = ncr53c9x_rdfifo(sc, NCR_RDFIFO_START);
-
- if (nfifo != 2) {
- device_printf(sc->sc_dev, "RESELECT: %d bytes "
- "in FIFO! [intr %x, stat %x, step %d, "
- "prevphase %x]\n",
- nfifo,
- sc->sc_espintr,
- sc->sc_espstat,
- sc->sc_espstep,
- sc->sc_prevphase);
- goto reset;
- }
- sc->sc_selid = sc->sc_imess[0];
- NCR_INTS(("selid=%02x ", sc->sc_selid));
-
- /* Handle IDENTIFY message. */
- ncr53c9x_msgin(sc);
-
- if (sc->sc_state != NCR_CONNECTED &&
- sc->sc_state != NCR_IDENTIFIED) {
- /* IDENTIFY fail?! */
- device_printf(sc->sc_dev, "identify failed, "
- "state %d, intr %02x\n", sc->sc_state,
- sc->sc_espintr);
- goto reset;
- }
- goto shortcut; /* i.e. next phase expected soon */
- }
-
-#define NCRINTR_DONE (NCRINTR_FC | NCRINTR_BS)
- if ((sc->sc_espintr & NCRINTR_DONE) == NCRINTR_DONE) {
- /*
- * Arbitration won; examine the `step' register
- * to determine how far the selection could progress.
- */
- if (ecb == NULL) {
- /*
- * When doing path inquiry during boot
- * FAS100A trigger a stray interrupt which
- * we just ignore instead of panicing.
- */
- if (sc->sc_state == NCR_IDLE &&
- sc->sc_espstep == 0)
- return;
- panic("%s: no nexus", __func__);
- }
-
- ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id];
-
- switch (sc->sc_espstep) {
- case 0:
- /*
- * The target did not respond with a
- * message out phase - probably an old
- * device that doesn't recognize ATN.
- * Clear ATN and just continue, the
- * target should be in the command
- * phase.
- * XXX check for command phase?
- */
- NCRCMD(sc, NCRCMD_RSTATN);
- break;
-
- case 1:
- if (ti->curr.period == ti->goal.period &&
- ti->curr.offset == ti->goal.offset &&
- ti->curr.width == ti->goal.width &&
- ecb->tag[0] == 0) {
- device_printf(sc->sc_dev, "step 1 "
- "and no negotiation to perform "
- "or tag to send\n");
- goto reset;
- }
- if (sc->sc_phase != MESSAGE_OUT_PHASE) {
- device_printf(sc->sc_dev, "step 1 "
- "but not in MESSAGE_OUT_PHASE\n");
- goto reset;
- }
- sc->sc_prevphase = MESSAGE_OUT_PHASE; /* XXX */
- if (ecb->flags & ECB_RESET) {
- /*
- * A DEVICE RESET was scheduled and
- * ATNS used. As SEND_DEV_RESET has
- * the highest priority, the target
- * will reset and disconnect and we
- * will end up in ncr53c9x_done w/o
- * negotiating or sending a TAG. So
- * we just break here in order to
- * avoid warnings about negotiation
- * not having completed.
- */
- ncr53c9x_sched_msgout(SEND_DEV_RESET);
- break;
- }
- if (ti->curr.width != ti->goal.width) {
- ti->flags |= T_WDTRSENT | T_SDTRSENT;
- ncr53c9x_sched_msgout(SEND_WDTR |
- SEND_SDTR);
- }
- if (ti->curr.period != ti->goal.period ||
- ti->curr.offset != ti->goal.offset) {
- ti->flags |= T_SDTRSENT;
- ncr53c9x_sched_msgout(SEND_SDTR);
- }
- if (ecb->tag[0] != 0)
- /* Could not do ATN3 so send TAG. */
- ncr53c9x_sched_msgout(SEND_TAG);
- break;
-
- case 3:
- /*
- * Grr, this is supposed to mean
- * "target left command phase prematurely".
- * It seems to happen regularly when
- * sync mode is on.
- * Look at FIFO to see if command went out.
- * (Timing problems?)
- */
- if (sc->sc_features & NCR_F_DMASELECT) {
- if (sc->sc_cmdlen == 0) {
- /* Hope for the best... */
- break;
- }
- } else if ((NCR_READ_REG(sc, NCR_FFLAG) &
- NCRFIFO_FF) == 0) {
- /* Hope for the best... */
- break;
- }
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("selection failed; %d left in FIFO "
- "[intr %x, stat %x, step %d]\n",
- NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- NCRCMD(sc, NCRCMD_FLUSH);
- ncr53c9x_sched_msgout(SEND_ABORT);
- return;
-
- case 2:
- /* Select stuck at Command Phase. */
- NCRCMD(sc, NCRCMD_FLUSH);
- break;
-
- case 4:
- if (sc->sc_features & NCR_F_DMASELECT &&
- sc->sc_cmdlen != 0) {
- xpt_print_path(ecb->ccb->ccb_h.path);
- printf("select; %lu left in DMA buffer "
- "[intr %x, stat %x, step %d]\n",
- (u_long)sc->sc_cmdlen,
- sc->sc_espintr,
- sc->sc_espstat,
- sc->sc_espstep);
- }
- /* So far, everything went fine. */
- break;
- }
-
- sc->sc_prevphase = INVALID_PHASE; /* ??? */
- /* Do an implicit RESTORE POINTERS. */
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- sc->sc_state = NCR_CONNECTED;
- break;
- } else {
- device_printf(sc->sc_dev, "unexpected status after "
- "select: [intr %x, stat %x, step %x]\n",
- sc->sc_espintr, sc->sc_espstat, sc->sc_espstep);
- NCRCMD(sc, NCRCMD_FLUSH);
- DELAY(1);
- goto reset;
- }
- if (sc->sc_state == NCR_IDLE) {
- device_printf(sc->sc_dev, "stray interrupt\n");
- return;
- }
- break;
-
- case NCR_CONNECTED:
- if ((sc->sc_flags & NCR_ICCS) != 0) {
- /* "Initiate Command Complete Steps" in progress */
- sc->sc_flags &= ~NCR_ICCS;
-
- if ((sc->sc_espintr & NCRINTR_DONE) == 0) {
- device_printf(sc->sc_dev, "ICCS: "
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- ncr53c9x_rdfifo(sc, NCR_RDFIFO_START);
- if (sc->sc_imlen < 2)
- device_printf(sc->sc_dev, "can't get status, "
- "only %d bytes\n", (int)sc->sc_imlen);
- ecb->stat = sc->sc_imess[sc->sc_imlen - 2];
- msg = sc->sc_imess[sc->sc_imlen - 1];
- NCR_PHASE(("<stat:(%x,%x)>", ecb->stat, msg));
- if (msg == MSG_CMDCOMPLETE) {
- ecb->dleft =
- (ecb->flags & ECB_TENTATIVE_DONE) ?
- 0 : sc->sc_dleft;
- if ((ecb->flags & ECB_SENSE) == 0)
- ecb->ccb->csio.resid = ecb->dleft;
- sc->sc_state = NCR_CMDCOMPLETE;
- } else
- device_printf(sc->sc_dev, "STATUS_PHASE: "
- "msg %d\n", msg);
- sc->sc_imlen = 0;
- NCRCMD(sc, NCRCMD_MSGOK);
- goto shortcut; /* i.e. wait for disconnect */
- }
- break;
-
- default:
- device_printf(sc->sc_dev, "invalid state: %d [intr %x, "
- "phase(c %x, p %x)]\n", sc->sc_state,
- sc->sc_espintr, sc->sc_phase, sc->sc_prevphase);
- goto reset;
- }
-
- /*
- * Driver is now in state NCR_CONNECTED, i.e. we
- * have a current command working the SCSI bus.
- */
- if (sc->sc_state != NCR_CONNECTED || ecb == NULL)
- panic("%s: no nexus", __func__);
-
- switch (sc->sc_phase) {
- case MESSAGE_OUT_PHASE:
- NCR_PHASE(("MESSAGE_OUT_PHASE "));
- ncr53c9x_msgout(sc);
- sc->sc_prevphase = MESSAGE_OUT_PHASE;
- break;
-
- case MESSAGE_IN_PHASE:
-msgin:
- NCR_PHASE(("MESSAGE_IN_PHASE "));
- if ((sc->sc_espintr & NCRINTR_BS) != 0) {
- if ((sc->sc_rev != NCR_VARIANT_FAS366) ||
- (sc->sc_espstat2 & NCRFAS_STAT2_EMPTY) == 0) {
- NCRCMD(sc, NCRCMD_FLUSH);
- }
- sc->sc_flags |= NCR_WAITI;
- NCRCMD(sc, NCRCMD_TRANS);
- } else if ((sc->sc_espintr & NCRINTR_FC) != 0) {
- if ((sc->sc_flags & NCR_WAITI) == 0) {
- device_printf(sc->sc_dev, "MSGIN: unexpected "
- "FC bit: [intr %x, stat %x, step %x]\n",
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- sc->sc_flags &= ~NCR_WAITI;
- ncr53c9x_rdfifo(sc,
- (sc->sc_prevphase == sc->sc_phase) ?
- NCR_RDFIFO_CONTINUE : NCR_RDFIFO_START);
- ncr53c9x_msgin(sc);
- } else
- device_printf(sc->sc_dev, "MSGIN: weird bits: "
- "[intr %x, stat %x, step %x]\n",
- sc->sc_espintr, sc->sc_espstat, sc->sc_espstep);
- sc->sc_prevphase = MESSAGE_IN_PHASE;
- goto shortcut; /* i.e. expect data to be ready */
-
- case COMMAND_PHASE:
- /*
- * Send the command block. Normally we don't see this
- * phase because the SEL_ATN command takes care of
- * all this. However, we end up here if either the
- * target or we wanted to exchange some more messages
- * first (e.g. to start negotiations).
- */
-
- NCR_PHASE(("COMMAND_PHASE 0x%02x (%d) ",
- ecb->cmd.cmd.opcode, ecb->clen));
- if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) {
- NCRCMD(sc, NCRCMD_FLUSH);
-#if 0
- DELAY(1);
-#endif
- }
- /*
- * If we have more messages to send, e.g. WDTR or SDTR
- * after we've sent a TAG, set ATN so we'll go back to
- * MESSAGE_OUT_PHASE.
- */
- if (sc->sc_msgpriq) {
- NCRCMD(sc, NCRCMD_SETATN);
- sc->sc_flags |= NCR_ATN;
- }
- if (sc->sc_features & NCR_F_DMASELECT) {
- /* Setup DMA transfer for command. */
- size = ecb->clen;
- sc->sc_cmdlen = size;
- sc->sc_cmdp = (void *)&ecb->cmd.cmd;
- error = NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen,
- 0, &size);
- if (error != 0)
- goto cmd;
-
- /* Program the SCSI counter. */
- NCR_SET_COUNT(sc, size);
-
- /* Load the count in. */
- NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA);
-
- /* Start the command transfer. */
- NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA);
- NCRDMA_GO(sc);
- sc->sc_prevphase = COMMAND_PHASE;
- break;
- }
-cmd:
- sc->sc_cmdlen = 0;
- ncr53c9x_wrfifo(sc, (uint8_t *)&ecb->cmd.cmd, ecb->clen);
- NCRCMD(sc, NCRCMD_TRANS);
- sc->sc_prevphase = COMMAND_PHASE;
- break;
-
- case DATA_OUT_PHASE:
- NCR_PHASE(("DATA_OUT_PHASE [%ld] ", (long)sc->sc_dleft));
- sc->sc_prevphase = DATA_OUT_PHASE;
- NCRCMD(sc, NCRCMD_FLUSH);
- size = ulmin(sc->sc_dleft, sc->sc_maxxfer);
- error = NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft, 0, &size);
- goto setup_xfer;
-
- case DATA_IN_PHASE:
- NCR_PHASE(("DATA_IN_PHASE "));
- sc->sc_prevphase = DATA_IN_PHASE;
- if (sc->sc_rev == NCR_VARIANT_ESP100)
- NCRCMD(sc, NCRCMD_FLUSH);
- size = ulmin(sc->sc_dleft, sc->sc_maxxfer);
- error = NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft, 1, &size);
-setup_xfer:
- if (error != 0) {
- switch (error) {
- case EFBIG:
- ecb->ccb->ccb_h.status |= CAM_REQ_TOO_BIG;
- break;
- case EINPROGRESS:
- panic("%s: cannot deal with deferred DMA",
- __func__);
- case EINVAL:
- ecb->ccb->ccb_h.status |= CAM_REQ_INVALID;
- break;
- case ENOMEM:
- ecb->ccb->ccb_h.status |= CAM_REQUEUE_REQ;
- break;
- default:
- ecb->ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
- }
- goto finish;
- }
-
- /* Target returned to data phase: wipe "done" memory. */
- ecb->flags &= ~ECB_TENTATIVE_DONE;
-
- /* Program the SCSI counter. */
- NCR_SET_COUNT(sc, size);
-
- /* Load the count in. */
- NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA);
-
- /*
- * Note that if `size' is 0, we've already transceived
- * all the bytes we want but we're still in DATA PHASE.
- * Apparently, the device needs padding. Also, a
- * transfer size of 0 means "maximum" to the chip
- * DMA logic.
- */
- NCRCMD(sc,
- (size == 0 ? NCRCMD_TRPAD : NCRCMD_TRANS) | NCRCMD_DMA);
- NCRDMA_GO(sc);
- return;
-
- case STATUS_PHASE:
- NCR_PHASE(("STATUS_PHASE "));
- sc->sc_flags |= NCR_ICCS;
- NCRCMD(sc, NCRCMD_ICCS);
- sc->sc_prevphase = STATUS_PHASE;
- goto shortcut; /* i.e. expect status results soon */
-
- case INVALID_PHASE:
- break;
-
- default:
- device_printf(sc->sc_dev,
- "unexpected bus phase; resetting\n");
- goto reset;
- }
-
- return;
-
-reset:
- ncr53c9x_init(sc, 1);
- return;
-
-finish:
- ncr53c9x_done(sc, ecb);
- return;
-
-sched:
- sc->sc_state = NCR_IDLE;
- ncr53c9x_sched(sc);
- return;
-
-shortcut:
- /*
- * The idea is that many of the SCSI operations take very little
- * time, and going away and getting interrupted is too high an
- * overhead to pay. For example, selecting, sending a message
- * and command and then doing some work can be done in one "pass".
- *
- * The delay is a heuristic. It is 2 when at 20 MHz, 2 at 25 MHz and
- * 1 at 40 MHz. This needs testing.
- */
- microtime(&wait);
- wait.tv_usec += 50 / sc->sc_freq;
- if (wait.tv_usec > 1000000) {
- wait.tv_sec++;
- wait.tv_usec -= 1000000;
- }
- do {
- if (NCRDMA_ISINTR(sc))
- goto again;
- microtime(&cur);
- } while (cur.tv_sec <= wait.tv_sec && cur.tv_usec <= wait.tv_usec);
-}
-
-static void
-ncr53c9x_abort(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
-{
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- /* 2 secs for the abort */
- ecb->timeout = NCR_ABORT_TIMEOUT;
- ecb->flags |= ECB_ABORT;
-
- if (ecb == sc->sc_nexus) {
- /*
- * If we're still selecting, the message will be scheduled
- * after selection is complete.
- */
- if (sc->sc_state == NCR_CONNECTED)
- ncr53c9x_sched_msgout(SEND_ABORT);
-
- /*
- * Reschedule callout.
- */
- callout_reset(&ecb->ch, mstohz(ecb->timeout),
- ncr53c9x_callout, ecb);
- } else {
- /*
- * Just leave the command where it is.
- * XXX - what choice do we have but to reset the SCSI
- * eventually?
- */
- if (sc->sc_state == NCR_IDLE)
- ncr53c9x_sched(sc);
- }
-}
-
-static void
-ncr53c9x_callout(void *arg)
-{
- struct ncr53c9x_ecb *ecb = arg;
- union ccb *ccb = ecb->ccb;
- struct ncr53c9x_softc *sc = ecb->sc;
- struct ncr53c9x_tinfo *ti;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- ti = &sc->sc_tinfo[ccb->ccb_h.target_id];
- xpt_print_path(ccb->ccb_h.path);
- device_printf(sc->sc_dev, "timed out [ecb %p (flags 0x%x, dleft %x, "
- "stat %x)], <state %d, nexus %p, phase(l %x, c %x, p %x), "
- "resid %lx, msg(q %x,o %x) %s>",
- ecb, ecb->flags, ecb->dleft, ecb->stat,
- sc->sc_state, sc->sc_nexus,
- NCR_READ_REG(sc, NCR_STAT),
- sc->sc_phase, sc->sc_prevphase,
- (long)sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
- NCRDMA_ISACTIVE(sc) ? "DMA active" : "");
-#if defined(NCR53C9X_DEBUG) && NCR53C9X_DEBUG > 1
- printf("TRACE: %s.", ecb->trace);
-#endif
-
- if (ecb->flags & ECB_ABORT) {
- /* Abort timed out. */
- printf(" AGAIN\n");
- ncr53c9x_init(sc, 1);
- } else {
- /* Abort the operation that has timed out. */
- printf("\n");
- ccb->ccb_h.status = CAM_CMD_TIMEOUT;
- ncr53c9x_abort(sc, ecb);
-
- /* Disable sync mode if stuck in a data phase. */
- if (ecb == sc->sc_nexus && ti->curr.offset != 0 &&
- (sc->sc_phase & (MSGI | CDI)) == 0) {
- /* XXX ASYNC CALLBACK! */
- ti->goal.offset = 0;
- xpt_print_path(ccb->ccb_h.path);
- printf("sync negotiation disabled\n");
- }
- }
-}
-
-static void
-ncr53c9x_watch(void *arg)
-{
- struct ncr53c9x_softc *sc = arg;
- struct ncr53c9x_linfo *li;
- struct ncr53c9x_tinfo *ti;
- time_t old;
- int t;
-
- NCR_LOCK_ASSERT(sc, MA_OWNED);
-
- /* Delete any structures that have not been used in 10min. */
- old = time_second - (10 * 60);
-
- for (t = 0; t < sc->sc_ntarg; t++) {
- ti = &sc->sc_tinfo[t];
- li = LIST_FIRST(&ti->luns);
- while (li) {
- if (li->last_used < old &&
- li->untagged == NULL &&
- li->used == 0) {
- if (li->lun < NCR_NLUN)
- ti->lun[li->lun] = NULL;
- LIST_REMOVE(li, link);
- free(li, M_DEVBUF);
- /* Restart the search at the beginning. */
- li = LIST_FIRST(&ti->luns);
- continue;
- }
- li = LIST_NEXT(li, link);
- }
- }
- callout_reset(&sc->sc_watchdog, 60 * hz, ncr53c9x_watch, sc);
-}
diff --git a/sys/dev/esp/ncr53c9xreg.h b/sys/dev/esp/ncr53c9xreg.h
deleted file mode 100644
index 557ae59ae720..000000000000
--- a/sys/dev/esp/ncr53c9xreg.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/* $NetBSD: ncr53c9xreg.h,v 1.16 2009/09/07 13:31:44 tsutsui Exp $ */
-
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) 1994 Peter Galbavy. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Peter Galbavy.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* $FreeBSD$ */
-
-#ifndef _NCR53C9XREG_H_
-#define _NCR53C9XREG_H_
-
-/*
- * Register addresses, relative to some base address
- */
-
-#define NCR_TCL 0x00 /* RW - Transfer Count Low */
-#define NCR_TCM 0x01 /* RW - Transfer Count Mid */
-#define NCR_TCH 0x0e /* RW - Transfer Count High */
- /* NOT on 53C90 */
-
-#define NCR_FIFO 0x02 /* RW - FIFO data */
-
-#define NCR_CMD 0x03 /* RW - Command (2 deep) */
-#define NCRCMD_DMA 0x80 /* DMA Bit */
-#define NCRCMD_NOP 0x00 /* No Operation */
-#define NCRCMD_FLUSH 0x01 /* Flush FIFO */
-#define NCRCMD_RSTCHIP 0x02 /* Reset Chip */
-#define NCRCMD_RSTSCSI 0x03 /* Reset SCSI Bus */
-#define NCRCMD_RESEL 0x40 /* Reselect Sequence */
-#define NCRCMD_SELNATN 0x41 /* Select without ATN */
-#define NCRCMD_SELATN 0x42 /* Select with ATN */
-#define NCRCMD_SELATNS 0x43 /* Select with ATN & Stop */
-#define NCRCMD_ENSEL 0x44 /* Enable (Re)Selection */
-#define NCRCMD_DISSEL 0x45 /* Disable (Re)Selection */
-#define NCRCMD_SELATN3 0x46 /* Select with ATN3 */
-#define NCRCMD_RESEL3 0x47 /* Reselect3 Sequence */
-#define NCRCMD_SNDMSG 0x20 /* Send Message */
-#define NCRCMD_SNDSTAT 0x21 /* Send Status */
-#define NCRCMD_SNDDATA 0x22 /* Send Data */
-#define NCRCMD_DISCSEQ 0x23 /* Disconnect Sequence */
-#define NCRCMD_TERMSEQ 0x24 /* Terminate Sequence */
-#define NCRCMD_TCCS 0x25 /* Target Command Comp Seq */
-#define NCRCMD_DISC 0x27 /* Disconnect */
-#define NCRCMD_RECMSG 0x28 /* Receive Message */
-#define NCRCMD_RECCMD 0x29 /* Receive Command */
-#define NCRCMD_RECDATA 0x2a /* Receive Data */
-#define NCRCMD_RECCSEQ 0x2b /* Receive Command Sequence*/
-#define NCRCMD_ABORT 0x04 /* Target Abort DMA */
-#define NCRCMD_TRANS 0x10 /* Transfer Information */
-#define NCRCMD_ICCS 0x11 /* Initiator Cmd Comp Seq */
-#define NCRCMD_MSGOK 0x12 /* Message Accepted */
-#define NCRCMD_TRPAD 0x18 /* Transfer Pad */
-#define NCRCMD_SETATN 0x1a /* Set ATN */
-#define NCRCMD_RSTATN 0x1b /* Reset ATN */
-
-#define NCR_STAT 0x04 /* RO - Status */
-#define NCRSTAT_INT 0x80 /* Interrupt */
-#define NCRSTAT_GE 0x40 /* Gross Error */
-#define NCRSTAT_PE 0x20 /* Parity Error */
-#define NCRSTAT_TC 0x10 /* Terminal Count */
-#define NCRSTAT_VGC 0x08 /* Valid Group Code */
-#define NCRSTAT_PHASE 0x07 /* Phase bits */
-
-#define NCR_SELID 0x04 /* WO - Select/Reselect Bus ID */
-#define NCR_BUSID_HMEXC32 0x40 /* HME xfer counter is 32bit */
-#define NCR_BUSID_HMEENCID 0x10 /* HME encode reselection ID */
-
-#define NCR_INTR 0x05 /* RO - Interrupt */
-#define NCRINTR_SBR 0x80 /* SCSI Bus Reset */
-#define NCRINTR_ILL 0x40 /* Illegal Command */
-#define NCRINTR_DIS 0x20 /* Disconnect */
-#define NCRINTR_BS 0x10 /* Bus Service */
-#define NCRINTR_FC 0x08 /* Function Complete */
-#define NCRINTR_RESEL 0x04 /* Reselected */
-#define NCRINTR_SELATN 0x02 /* Select with ATN */
-#define NCRINTR_SEL 0x01 /* Selected */
-
-#define NCR_TIMEOUT 0x05 /* WO - Select/Reselect Timeout */
-
-#define NCR_STEP 0x06 /* RO - Sequence Step */
-#define NCRSTEP_MASK 0x07 /* the last 3 bits */
-#define NCRSTEP_DONE 0x04 /* command went out */
-
-#define NCR_SYNCTP 0x06 /* WO - Synch Transfer Period */
- /* Default 5 (53C9X) */
-
-#define NCR_FFLAG 0x07 /* RO - FIFO Flags */
-#define NCRFIFO_SS 0xe0 /* Sequence Step (Dup) */
-#define NCRFIFO_FF 0x1f /* Bytes in FIFO */
-
-#define NCR_SYNCOFF 0x07 /* WO - Synch Offset */
- /* 0 = ASYNC */
- /* 1 - 15 = SYNC bytes */
-
-#define NCR_CFG1 0x08 /* RW - Configuration #1 */
-#define NCRCFG1_SLOW 0x80 /* Slow Cable Mode */
-#define NCRCFG1_SRR 0x40 /* SCSI Reset Rep Int Dis */
-#define NCRCFG1_PTEST 0x20 /* Parity Test Mod */
-#define NCRCFG1_PARENB 0x10 /* Enable Parity Check */
-#define NCRCFG1_CTEST 0x08 /* Enable Chip Test */
-#define NCRCFG1_BUSID 0x07 /* Bus ID */
-
-#define NCR_CCF 0x09 /* WO - Clock Conversion Factor */
- /* 0 = 35.01 - 40MHz */
- /* NEVER SET TO 1 */
- /* 2 = 10MHz */
- /* 3 = 10.01 - 15MHz */
- /* 4 = 15.01 - 20MHz */
- /* 5 = 20.01 - 25MHz */
- /* 6 = 25.01 - 30MHz */
- /* 7 = 30.01 - 35MHz */
-
-#define NCR_TEST 0x0a /* WO - Test (Chip Test Only) */
-
-#define NCR_CFG2 0x0b /* RW - Configuration #2 */
-#define NCRCFG2_RSVD 0xa0 /* reserved */
-#define NCRCFG2_FE 0x40 /* Features Enable */
-#define NCRCFG2_DREQ 0x10 /* DREQ High Impedance */
-#define NCRCFG2_SCSI2 0x08 /* SCSI-2 Enable */
-#define NCRCFG2_BPA 0x04 /* Target Bad Parity Abort */
-#define NCRCFG2_RPE 0x02 /* Register Parity Error */
-#define NCRCFG2_DPE 0x01 /* DMA Parity Error */
-
-#define NCRCFG2_HMEFE 0x10 /* HME feature enable */
-#define NCRCFG2_HME32 0x80 /* HME 32 extended */
-
-/* Config #3 only on 53C9X */
-#define NCR_CFG3 0x0c /* RW - Configuration #3 */
-#define NCRCFG3_RSVD 0xe0 /* reserved */
-#define NCRCFG3_IDM 0x10 /* ID Message Res Check */
-#define NCRCFG3_QTE 0x08 /* Queue Tag Enable */
-#define NCRCFG3_CDB 0x04 /* CDB 10-bytes OK */
-#define NCRCFG3_FSCSI 0x02 /* Fast SCSI */
-#define NCRCFG3_FCLK 0x01 /* Fast Clock (>25MHz) */
-
-/*
- * For some unknown reason, the ESP406/FAS408 looks like every
- * other ncr53c9x, except for configuration #3 register. At any
- * rate, if you're dealing with these chips, you need to use these
- * defines instead.
- */
-
-/* Config #3 different on ESP406/FAS408 */
-#define NCR_ESPCFG3 0x0c /* RW - Configuration #3 */
-#define NCRESPCFG3_IDM 0x80 /* ID Message Res Check */
-#define NCRESPCFG3_QTE 0x40 /* Queue Tag Enable */
-#define NCRESPCFG3_CDB 0x20 /* CDB 10-bytes OK */
-#define NCRESPCFG3_FSCSI 0x10 /* Fast SCSI */
-#define NCRESPCFG3_SRESB 0x08 /* Save Residual Byte */
-#define NCRESPCFG3_FCLK 0x04 /* Fast Clock (>25MHz) */
-#define NCRESPCFG3_ADMA 0x02 /* Alternate DMA Mode */
-#define NCRESPCFG3_T8M 0x01 /* Threshold 8 Mode */
-
-/* Config #3 also different on NCR53CF9x/FAS100A/FAS216/FAS236 */
-#define NCR_F9XCFG3 0x0c /* RW - Configuration #3 */
-#define NCRF9XCFG3_IDM 0x80 /* ID Message Res Check */
-#define NCRF9XCFG3_QTE 0x40 /* Queue Tag Enable */
-#define NCRF9XCFG3_CDB 0x20 /* CDB 10-bytes OK */
-#define NCRF9XCFG3_FSCSI 0x10 /* Fast SCSI */
-#define NCRF9XCFG3_FCLK 0x08 /* Fast Clock (>25MHz) */
-#define NCRF9XCFG3_SRESB 0x04 /* Save Residual Byte */
-#define NCRF9XCFG3_ADMA 0x02 /* Alternate DMA Mode */
-#define NCRF9XCFG3_T8M 0x01 /* Threshold 8 Mode */
-
-/* Config #3 on FAS366 */
-#define NCRFASCFG3_OBAUTO 0x80 /* auto push odd-byte to DMA */
-#define NCRFASCFG3_EWIDE 0x40 /* Enable Wide-SCSI */
-#define NCRFASCFG3_IDBIT3 0x20 /* Bit 3 of HME SCSI-ID */
-#define NCRFASCFG3_IDRESCHK 0x10 /* ID message checking */
-#define NCRFASCFG3_QUENB 0x08 /* 3-byte msg support */
-#define NCRFASCFG3_CDB10 0x04 /* group 2 scsi-2 support */
-#define NCRFASCFG3_FASTSCSI 0x02 /* 10 MB/S fast scsi mode */
-#define NCRFASCFG3_FASTCLK 0x01 /* fast clock mode */
-
-/* Config #4 only on ESP406/FAS408 */
-#define NCR_CFG4 0x0d /* RW - Configuration #4 */
-#define NCRCFG4_CRS1 0x80 /* Select register set #1 */
-#define NCRCFG4_RSVD 0x7b /* reserved */
-#define NCRCFG4_ACTNEG 0x04 /* Active negation */
-
-/*
- The following registers are only on the ESP406/FAS408. The
- documentation refers to them as "Control Register Set #1".
- These are the registers that are visible when bit 7 of
- register 0x0d is set. This bit is common to both register sets.
-*/
-
-#define NCR_JMP 0x00 /* RO - Jumper Sense Register */
-#define NCRJMP_RSVD 0xc0 /* reserved */
-#define NCRJMP_ROMSZ 0x20 /* ROM Size 1=16K, 0=32K */
-#define NCRJMP_J4 0x10 /* Jumper #4 */
-#define NCRJMP_J3 0x08 /* Jumper #3 */
-#define NCRJMP_J2 0x04 /* Jumper #2 */
-#define NCRJMP_J1 0x02 /* Jumper #1 */
-#define NCRJMP_J0 0x01 /* Jumper #0 */
-
-#define NCR_PIOFIFO 0x04 /* WO - PIO FIFO, 4 bytes deep */
-
-#define NCR_PSTAT 0x08 /* RW - PIO Status Register */
-#define NCRPSTAT_PERR 0x80 /* PIO Error */
-#define NCRPSTAT_SIRQ 0x40 /* Active High of SCSI IRQ */
-#define NCRPSTAT_ATAI 0x20 /* ATA IRQ */
-#define NCRPSTAT_FEMPT 0x10 /* PIO FIFO Empty */
-#define NCRPSTAT_F13 0x08 /* PIO FIFO 1/3 */
-#define NCRPSTAT_F23 0x04 /* PIO FIFO 2/3 */
-#define NCRPSTAT_FFULL 0x02 /* PIO FIFO Full */
-#define NCRPSTAT_PIOM 0x01 /* PIO/DMA Mode */
-
-#define NCR_PIOI 0x0b /* RW - PIO Interrupt Enable */
-#define NCRPIOI_RSVD 0xe0 /* reserved */
-#define NCRPIOI_EMPTY 0x10 /* IRQ When Empty */
-#define NCRPIOI_13 0x08 /* IRQ When 1/3 */
-#define NCRPIOI_23 0x04 /* IRQ When 2/3 */
-#define NCRPIOI_FULL 0x02 /* IRQ When Full */
-#define NCRPIOI_FINV 0x01 /* Flag Invert */
-
-#define NCR_CFG5 0x0d /* RW - Configuration #5 */
-#define NCRCFG5_CRS1 0x80 /* Select Register Set #1 */
-#define NCRCFG5_SRAM 0x40 /* SRAM Memory Map */
-#define NCRCFG5_AADDR 0x20 /* Auto Address */
-#define NCRCFG5_PTRINC 0x10 /* Pointer Increment */
-#define NCRCFG5_LOWPWR 0x08 /* Low Power Mode */
-#define NCRCFG5_SINT 0x04 /* SCSI Interrupt Enable */
-#define NCRCFG5_INTP 0x02 /* INT Polarity */
-#define NCRCFG5_AINT 0x01 /* ATA Interrupt Enable */
-
-#define NCR_SIGNTR 0x0e /* RO - Signature */
-
-/* Am53c974 Config #3 */
-#define NCR_AMDCFG3 0x0c /* RW - Configuration #3 */
-#define NCRAMDCFG3_IDM 0x80 /* ID Message Res Check */
-#define NCRAMDCFG3_QTE 0x40 /* Queue Tag Enable */
-#define NCRAMDCFG3_CDB 0x20 /* CDB 10-bytes OK */
-#define NCRAMDCFG3_FSCSI 0x10 /* Fast SCSI */
-#define NCRAMDCFG3_FCLK 0x08 /* Fast Clock (40MHz) */
-#define NCRAMDCFG3_RSVD 0x07 /* Reserved */
-
-/* Am53c974 Config #4 */
-#define NCR_AMDCFG4 0x0d /* RW - Configuration #4 */
-#define NCRAMDCFG4_GE 0xc0 /* Glitch Eater */
-#define NCRAMDCFG4_GE12NS 0x00 /* Signal window 12ns */
-#define NCRAMDCFG4_GE25NS 0x80 /* Signal window 25ns */
-#define NCRAMDCFG4_GE35NS 0x40 /* Signal window 35ns */
-#define NCRAMDCFG4_GE0NS 0xc0 /* Signal window 0ns */
-#define NCRAMDCFG4_PWD 0x20 /* Reduced power feature */
-#define NCRAMDCFG4_RSVD 0x13 /* Reserved */
-#define NCRAMDCFG4_RAE 0x08 /* Active neg. REQ/ACK */
-#define NCRAMDCFG4_RADE 0x04 /* Active neg. REQ/ACK/DAT */
-
-/*
- * FAS366
- */
-#define NCR_RCL NCR_TCH /* Recommand counter low */
-#define NCR_RCH 0xf /* Recommand counter high */
-#define NCR_UID NCR_RCL /* fas366 part-uniq id */
-
-
-/* status register #2 definitions (read only) */
-#define NCR_STAT2 NCR_CCF
-#define NCRFAS_STAT2_SEQCNT 0x01 /* Sequence counter bit 7-3 enabled */
-#define NCRFAS_STAT2_FLATCHED 0x02 /* FIFO flags register latched */
-#define NCRFAS_STAT2_CLATCHED 0x04 /* Xfer cntr & recommand ctr latched */
-#define NCRFAS_STAT2_CACTIVE 0x08 /* Command register is active */
-#define NCRFAS_STAT2_SCSI16 0x10 /* SCSI interface is wide */
-#define NCRFAS_STAT2_ISHUTTLE 0x20 /* FIFO Top register contains 1 byte */
-#define NCRFAS_STAT2_OSHUTTLE 0x40 /* next byte from FIFO is MSB */
-#define NCRFAS_STAT2_EMPTY 0x80 /* FIFO is empty */
-
-#endif /* _NCR53C9XREG_H_ */
diff --git a/sys/dev/esp/ncr53c9xvar.h b/sys/dev/esp/ncr53c9xvar.h
deleted file mode 100644
index cebb214df369..000000000000
--- a/sys/dev/esp/ncr53c9xvar.h
+++ /dev/null
@@ -1,501 +0,0 @@
-/* $NetBSD: ncr53c9xvar.h,v 1.55 2011/07/31 18:39:00 jakllsch Exp $ */
-
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-NetBSD AND BSD-4-Clause
- *
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
- * NASA Ames Research Center.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 1994 Peter Galbavy. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Peter Galbavy.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* $FreeBSD$ */
-
-#ifndef _NCR53C9XVAR_H_
-#define _NCR53C9XVAR_H_
-
-#include <sys/lock.h>
-
-/* Set this to 1 for normal debug, or 2 for per-target tracing. */
-/* #define NCR53C9X_DEBUG 2 */
-
-/* Wide or differential can have 16 targets */
-#define NCR_NLUN 8
-
-#define NCR_ABORT_TIMEOUT 2000 /* time to wait for abort */
-#define NCR_SENSE_TIMEOUT 1000 /* time to wait for sense */
-
-#define FREQTOCCF(freq) (((freq + 4) / 5))
-
-/*
- * NCR 53c9x variants. Note these values are used as indexes into
- * a table; do not modify them unless you know what you are doing.
- */
-#define NCR_VARIANT_ESP100 0
-#define NCR_VARIANT_ESP100A 1
-#define NCR_VARIANT_ESP200 2
-#define NCR_VARIANT_NCR53C94 3
-#define NCR_VARIANT_NCR53C96 4
-#define NCR_VARIANT_ESP406 5
-#define NCR_VARIANT_FAS408 6
-#define NCR_VARIANT_FAS216 7
-#define NCR_VARIANT_AM53C974 8
-#define NCR_VARIANT_FAS366 9
-#define NCR_VARIANT_NCR53C90_86C01 10
-#define NCR_VARIANT_FAS100A 11
-#define NCR_VARIANT_FAS236 12
-#define NCR_VARIANT_MAX 13
-
-/* XXX Max tag depth. Should this be defined in the register header? */
-#define NCR_TAG_DEPTH 256
-
-/*
- * ECB. Holds additional information for each SCSI command Comments: We
- * need a separate scsi command block because we may need to overwrite it
- * with a request sense command. Basically, we refrain from fiddling with
- * the ccb union (except do the expected updating of return values).
- * We'll generally update: ccb->ccb_h.status and ccb->csio.{resid,
- * scsi_status,sense_data}.
- */
-struct ncr53c9x_ecb {
- /* These fields are preserved between alloc and free. */
- struct callout ch;
- struct ncr53c9x_softc *sc;
- int tag_id;
- int flags;
-
- union ccb *ccb; /* SCSI xfer ctrl block from above */
- TAILQ_ENTRY(ncr53c9x_ecb) free_links;
- TAILQ_ENTRY(ncr53c9x_ecb) chain;
-#define ECB_ALLOC 0x01
-#define ECB_READY 0x02
-#define ECB_SENSE 0x04
-#define ECB_ABORT 0x40
-#define ECB_RESET 0x80
-#define ECB_TENTATIVE_DONE 0x100
- int timeout;
-
- struct {
- uint8_t msg[3]; /* Selection Id msg and tags */
- struct scsi_generic cmd; /* SCSI command block */
- } cmd;
- uint8_t *daddr; /* Saved data pointer */
- int clen; /* Size of command in cmd.cmd */
- int dleft; /* Residue */
- uint8_t stat; /* SCSI status byte */
- uint8_t tag[2]; /* TAG bytes */
- uint8_t pad[1];
-
-#if defined(NCR53C9X_DEBUG) && NCR53C9X_DEBUG > 1
- char trace[1000];
-#endif
-};
-#if defined(NCR53C9X_DEBUG) && NCR53C9X_DEBUG > 1
-#define ECB_TRACE(ecb, msg, a, b) do { \
- const char *f = "[" msg "]"; \
- int n = strlen((ecb)->trace); \
- if (n < (sizeof((ecb)->trace)-100)) \
- sprintf((ecb)->trace + n, f, a, b); \
-} while (/* CONSTCOND */0)
-#else
-#define ECB_TRACE(ecb, msg, a, b)
-#endif
-
-/*
- * Some info about each (possible) target and LUN on the SCSI bus.
- *
- * SCSI I and II devices can have up to 8 LUNs, each with up to 256
- * outstanding tags. SCSI III devices have 64-bit LUN identifiers
- * that can be sparsely allocated.
- *
- * Since SCSI II devices can have up to 8 LUNs, we use an array
- * of 8 pointers to ncr53c9x_linfo structures for fast lookup.
- * Longer LUNs need to traverse the linked list.
- */
-
-struct ncr53c9x_linfo {
- int64_t lun;
- LIST_ENTRY(ncr53c9x_linfo) link;
- time_t last_used;
- uint8_t used; /* # slots in use */
- uint8_t avail; /* where to start scanning */
- uint8_t busy;
- struct ncr53c9x_ecb *untagged;
- struct ncr53c9x_ecb *queued[NCR_TAG_DEPTH];
-};
-
-struct ncr53c9x_xinfo {
- uint8_t period;
- uint8_t offset;
- uint8_t width;
-};
-
-struct ncr53c9x_tinfo {
- int cmds; /* # of commands processed */
- int dconns; /* # of disconnects */
- int touts; /* # of timeouts */
- int perrs; /* # of parity errors */
- int senses; /* # of request sense commands sent */
- uint8_t flags;
-#define T_SYNCHOFF 0x01 /* SYNC mode is permanently off */
-#define T_RSELECTOFF 0x02 /* RE-SELECT mode is off */
-#define T_TAG 0x04 /* Turn on TAG QUEUEs */
-#define T_SDTRSENT 0x08 /* SDTR message has been sent to */
-#define T_WDTRSENT 0x10 /* WDTR message has been sent to */
- struct ncr53c9x_xinfo curr;
- struct ncr53c9x_xinfo goal;
- LIST_HEAD(lun_list, ncr53c9x_linfo) luns;
- struct ncr53c9x_linfo *lun[NCR_NLUN]; /* For speedy lookups */
-};
-
-/* Look up a lun in a tinfo */
-#define TINFO_LUN(t, l) ( \
- (((l) < NCR_NLUN) && (((t)->lun[(l)]) != NULL)) \
- ? ((t)->lun[(l)]) \
- : ncr53c9x_lunsearch((t), (int64_t)(l)) \
-)
-
-/* Register a linenumber (for debugging). */
-#define LOGLINE(p)
-
-#define NCR_SHOWECBS 0x01
-#define NCR_SHOWINTS 0x02
-#define NCR_SHOWCMDS 0x04
-#define NCR_SHOWMISC 0x08
-#define NCR_SHOWTRAC 0x10
-#define NCR_SHOWSTART 0x20
-#define NCR_SHOWPHASE 0x40
-#define NCR_SHOWDMA 0x80
-#define NCR_SHOWCCMDS 0x100
-#define NCR_SHOWMSGS 0x200
-
-#ifdef NCR53C9X_DEBUG
-extern int ncr53c9x_debug;
-#define NCR_ECBS(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWECBS) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_MISC(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWMISC) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_INTS(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWINTS) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_TRACE(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWTRAC) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_CMDS(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWCMDS) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_START(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWSTART) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_PHASE(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWPHASE) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_DMA(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWDMA) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#define NCR_MSGS(str) \
- do { \
- if ((ncr53c9x_debug & NCR_SHOWMSGS) != 0) \
- printf str; \
- } while (/* CONSTCOND */0)
-#else
-#define NCR_ECBS(str)
-#define NCR_MISC(str)
-#define NCR_INTS(str)
-#define NCR_TRACE(str)
-#define NCR_CMDS(str)
-#define NCR_START(str)
-#define NCR_PHASE(str)
-#define NCR_DMA(str)
-#define NCR_MSGS(str)
-#endif
-
-#define NCR_MAX_MSG_LEN 8
-
-struct ncr53c9x_softc;
-
-/*
- * Function switch used as glue to MD code
- */
-struct ncr53c9x_glue {
- /* Mandatory entry points. */
- uint8_t (*gl_read_reg)(struct ncr53c9x_softc *, int);
- void (*gl_write_reg)(struct ncr53c9x_softc *, int, uint8_t);
- int (*gl_dma_isintr)(struct ncr53c9x_softc *);
- void (*gl_dma_reset)(struct ncr53c9x_softc *);
- int (*gl_dma_intr)(struct ncr53c9x_softc *);
- int (*gl_dma_setup)(struct ncr53c9x_softc *, void **, size_t *,
- int, size_t *);
- void (*gl_dma_go)(struct ncr53c9x_softc *);
- void (*gl_dma_stop)(struct ncr53c9x_softc *);
- int (*gl_dma_isactive)(struct ncr53c9x_softc *);
-};
-
-struct ncr53c9x_softc {
- device_t sc_dev; /* us as a device */
-
- struct cam_sim *sc_sim; /* our scsi adapter */
- struct cam_path *sc_path; /* our scsi channel */
- struct callout sc_watchdog; /* periodic timer */
-
- const struct ncr53c9x_glue *sc_glue; /* glue to MD code */
-
- int sc_cfflags; /* Copy of config flags */
-
- /* register defaults */
- uint8_t sc_cfg1; /* Config 1 */
- uint8_t sc_cfg2; /* Config 2, not ESP100 */
- uint8_t sc_cfg3; /* Config 3, ESP200,FAS */
- uint8_t sc_cfg3_fscsi; /* Chip-specific FSCSI bit */
- uint8_t sc_cfg4; /* Config 4, only ESP200 */
- uint8_t sc_cfg5; /* Config 5, only ESP200 */
- uint8_t sc_ccf; /* Clock Conversion */
- uint8_t sc_timeout;
-
- /* register copies, see ncr53c9x_readregs() */
- uint8_t sc_espintr;
- uint8_t sc_espstat;
- uint8_t sc_espstep;
- uint8_t sc_espstat2;
- uint8_t sc_espfflags;
-
- /* Lists of command blocks */
- TAILQ_HEAD(ecb_list, ncr53c9x_ecb) ready_list;
-
- struct ncr53c9x_ecb *sc_nexus; /* Current command */
- int sc_ntarg;
- struct ncr53c9x_tinfo *sc_tinfo;
-
- /* Data about the current nexus (updated for every cmd switch) */
- void *sc_dp; /* Current data pointer */
- ssize_t sc_dleft; /* Data left to transfer */
-
- /* Adapter state */
- int sc_phase; /* Copy of what bus phase we are in */
- int sc_prevphase; /* Copy of what bus phase we were in */
- uint8_t sc_state; /* State applicable to the adapter */
- uint8_t sc_flags; /* See below */
- uint8_t sc_selid;
- uint8_t sc_lastcmd;
-
- /* Message stuff */
- uint16_t sc_msgify; /* IDENTIFY message associated with nexus */
- uint16_t sc_msgout; /* What message is on its way out? */
- uint16_t sc_msgpriq; /* One or more messages to send (encoded) */
- uint16_t sc_msgoutq; /* What messages have been sent so far? */
-
- uint8_t *sc_omess; /* MSGOUT buffer */
- int sc_omess_self; /* MSGOUT buffer is self-allocated */
- void *sc_omp; /* Message pointer (for multibyte messages) */
- size_t sc_omlen;
- uint8_t *sc_imess; /* MSGIN buffer */
- int sc_imess_self; /* MSGIN buffer is self-allocated */
- void *sc_imp; /* Message pointer (for multibyte messages) */
- size_t sc_imlen;
-
- void *sc_cmdp; /* Command pointer (for DMAed commands) */
- size_t sc_cmdlen; /* Size of command in transit */
-
- /* Hardware attributes */
- int sc_freq; /* SCSI bus frequency in MHz */
- int sc_id; /* Our SCSI id */
- int sc_rev; /* Chip revision */
- int sc_features; /* Chip features */
- int sc_minsync; /* Minimum sync period / 4 */
- int sc_maxxfer; /* Maximum transfer size */
- int sc_maxoffset; /* Maximum offset */
- int sc_maxwidth; /* Maximum width */
- int sc_extended_geom; /* Should we return extended geometry */
-
- struct mtx sc_lock; /* driver mutex */
-
- struct ncr53c9x_ecb *ecb_array;
- TAILQ_HEAD(,ncr53c9x_ecb) free_list;
-};
-
-/* values for sc_state */
-#define NCR_IDLE 1 /* Waiting for something to do */
-#define NCR_SELECTING 2 /* SCSI command is arbiting */
-#define NCR_RESELECTED 3 /* Has been reselected */
-#define NCR_IDENTIFIED 4 /* Has gotten IFY but not TAG */
-#define NCR_CONNECTED 5 /* Actively using the SCSI bus */
-#define NCR_DISCONNECT 6 /* MSG_DISCONNECT received */
-#define NCR_CMDCOMPLETE 7 /* MSG_CMDCOMPLETE received */
-#define NCR_CLEANING 8
-#define NCR_SBR 9 /* Expect a SCSI RST because we commanded it */
-
-/* values for sc_flags */
-#define NCR_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */
-#define NCR_ABORTING 0x02 /* Bailing out */
-#define NCR_ICCS 0x04 /* Expect status phase results */
-#define NCR_WAITI 0x08 /* Waiting for non-DMA data to arrive */
-#define NCR_ATN 0x10 /* ATN asserted */
-#define NCR_EXPECT_ILLCMD 0x20 /* Expect Illegal Command Interrupt */
-
-/* values for sc_features */
-#define NCR_F_HASCFG3 0x01 /* chip has CFG3 register */
-#define NCR_F_FASTSCSI 0x02 /* chip supports Fast mode */
-#define NCR_F_DMASELECT 0x04 /* can do dmaselect */
-#define NCR_F_SELATN3 0x08 /* chip supports SELATN3 command */
-#define NCR_F_LARGEXFER 0x10 /* chip supports transfers > 64k */
-
-/* values for sc_msgout */
-#define SEND_DEV_RESET 0x0001
-#define SEND_PARITY_ERROR 0x0002
-#define SEND_INIT_DET_ERR 0x0004
-#define SEND_REJECT 0x0008
-#define SEND_IDENTIFY 0x0010
-#define SEND_ABORT 0x0020
-#define SEND_TAG 0x0040
-#define SEND_WDTR 0x0080
-#define SEND_SDTR 0x0100
-
-/* SCSI Status codes */
-#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
-
-/* phase bits */
-#define IOI 0x01
-#define CDI 0x02
-#define MSGI 0x04
-
-/* Information transfer phases */
-#define DATA_OUT_PHASE (0)
-#define DATA_IN_PHASE (IOI)
-#define COMMAND_PHASE (CDI)
-#define STATUS_PHASE (CDI | IOI)
-#define MESSAGE_OUT_PHASE (MSGI | CDI)
-#define MESSAGE_IN_PHASE (MSGI | CDI | IOI)
-
-#define PHASE_MASK (MSGI | CDI | IOI)
-
-/* Some pseudo phases for getphase()*/
-#define BUSFREE_PHASE 0x100 /* Re/Selection no longer valid */
-#define INVALID_PHASE 0x101 /* Re/Selection valid, but no REQ yet */
-#define PSEUDO_PHASE 0x100 /* "pseudo" bit */
-
-/*
- * Macros to read and write the chip's registers.
- */
-#define NCR_READ_REG(sc, reg) \
- (*(sc)->sc_glue->gl_read_reg)((sc), (reg))
-#define NCR_WRITE_REG(sc, reg, val) \
- (*(sc)->sc_glue->gl_write_reg)((sc), (reg), (val))
-
-#ifdef NCR53C9X_DEBUG
-#define NCRCMD(sc, cmd) do { \
- if ((ncr53c9x_debug & NCR_SHOWCCMDS) != 0) \
- printf("<CMD:0x%x %d>", (unsigned int)cmd, __LINE__); \
- sc->sc_lastcmd = cmd; \
- NCR_WRITE_REG(sc, NCR_CMD, cmd); \
-} while (/* CONSTCOND */ 0)
-#else
-#define NCRCMD(sc, cmd) NCR_WRITE_REG(sc, NCR_CMD, cmd)
-#endif
-
-/*
- * Macros for locking
- */
-#define NCR_LOCK_INIT(_sc) \
- mtx_init(&(_sc)->sc_lock, "ncr", "ncr53c9x lock", MTX_DEF);
-#define NCR_LOCK_INITIALIZED(_sc) mtx_initialized(&(_sc)->sc_lock)
-#define NCR_LOCK(_sc) mtx_lock(&(_sc)->sc_lock)
-#define NCR_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_lock)
-#define NCR_LOCK_ASSERT(_sc, _what) mtx_assert(&(_sc)->sc_lock, (_what))
-#define NCR_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_lock)
-
-/*
- * DMA macros for NCR53c9x
- */
-#define NCRDMA_ISINTR(sc) (*(sc)->sc_glue->gl_dma_isintr)((sc))
-#define NCRDMA_RESET(sc) (*(sc)->sc_glue->gl_dma_reset)((sc))
-#define NCRDMA_INTR(sc) (*(sc)->sc_glue->gl_dma_intr)((sc))
-#define NCRDMA_SETUP(sc, addr, len, datain, dmasize) \
- (*(sc)->sc_glue->gl_dma_setup)((sc), (addr), (len), (datain), (dmasize))
-#define NCRDMA_GO(sc) (*(sc)->sc_glue->gl_dma_go)((sc))
-#define NCRDMA_STOP(sc) (*(sc)->sc_glue->gl_dma_stop)((sc))
-#define NCRDMA_ISACTIVE(sc) (*(sc)->sc_glue->gl_dma_isactive)((sc))
-
-/*
- * Macro to convert the chip register Clock Per Byte value to
- * Synchronous Transfer Period.
- */
-#define ncr53c9x_cpb2stp(sc, cpb) \
- ((250 * (cpb)) / (sc)->sc_freq)
-
-extern devclass_t esp_devclass;
-
-int ncr53c9x_attach(struct ncr53c9x_softc *sc);
-int ncr53c9x_detach(struct ncr53c9x_softc *sc);
-void ncr53c9x_intr(void *arg);
-
-#endif /* _NCR53C9XVAR_H_ */
diff --git a/sys/dev/ic/esp.h b/sys/dev/ic/esp.h
deleted file mode 100644
index cf5447d6025c..000000000000
--- a/sys/dev/ic/esp.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1995 Sean Eric Fagan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _IC_ESP_H_
-#define _IC_ESP_H_
-
-/*
- * Definitions for Hayes ESP serial cards.
- */
-
-/*
- * CMD1 and CMD2 are the command ports, offsets from <esp_iobase>.
- */
-#define ESP_CMD1 4
-#define ESP_CMD2 5
-
-/*
- * STAT1 and STAT2 are to get return values and status bytes;
- * they overload CMD1 and CMD2.
- */
-#define ESP_STATUS1 ESP_CMD1
-#define ESP_STATUS2 ESP_CMD2
-
-/*
- * Commands. Commands are given by writing the command value to
- * ESP_CMD1 and then writing or reading some number of bytes from
- * ESP_CMD2 or ESP_STATUS2.
- */
-#define ESP_GETTEST 0x01 /* self-test command (1 byte + extras) */
-#define ESP_GETDIPS 0x02 /* get on-board DIP switches (1 byte) */
-#define ESP_SETFLOWTYPE 0x08 /* set type of flow-control (2 bytes) */
-#define ESP_SETRXFLOW 0x0a /* set Rx FIFO flow control levels (4 bytes) */
-#define ESP_SETMODE 0x10 /* set board mode (1 byte) */
-#define ESP_SETCLOCK 0x23 /* set UART clock prescaler */
-
-/* Mode bits (ESP_SETMODE). */
-#define ESP_MODE_FIFO 0x02 /* act like a 16550 (compatibility mode) */
-#define ESP_MODE_RTS 0x04 /* use RTS hardware flow control */
-#define ESP_MODE_SCALE 0x80 /* scale FIFO trigger levels */
-
-/* Flow control type bits (ESP_SETFLOWTYPE). */
-#define ESP_FLOW_RTS 0x04 /* cmd1: local Rx sends RTS flow control */
-#define ESP_FLOW_CTS 0x10 /* cmd2: local transmitter responds to CTS */
-
-/* Used by ESP_SETRXFLOW. */
-#define HIBYTE(w) (((w) >> 8) & 0xff)
-#define LOBYTE(w) ((w) & 0xff)
-
-#endif /* !_IC_ESP_H_ */
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index b97036f324cd..6dc819e998b2 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -132,7 +132,6 @@ device siis # SiliconImage SiI3124/SiI3132/SiI3531 SATA
# SCSI Controllers
device ahc # AHA2940 and onboard AIC7xxx devices
-device esp # AMD Am53C974 (Tekram DC-390(T))
device hptiop # Highpoint RocketRaid 3xxx series
device isp # Qlogic family
#device ispfw # Firmware for QLogic HBAs- normally a module
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 594c837168bf..7683343c9120 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -109,7 +109,6 @@ SUBDIR= \
${_em} \
${_ena} \
${_enetc} \
- esp \
${_et} \
evdev \
${_exca} \
diff --git a/sys/modules/esp/Makefile b/sys/modules/esp/Makefile
deleted file mode 100644
index 8540b4434ae3..000000000000
--- a/sys/modules/esp/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${SRCTOP}/sys/dev/esp
-
-KMOD= esp
-SRCS= device_if.h esp_pci.c bus_if.h ncr53c9x.c
-SRCS+= opt_cam.h pci_if.h
-
-.include <bsd.kmod.mk>
diff --git a/tools/kerneldoc/subsys/Doxyfile-dev_esp b/tools/kerneldoc/subsys/Doxyfile-dev_esp
deleted file mode 100644
index c66d8f99d9cb..000000000000
--- a/tools/kerneldoc/subsys/Doxyfile-dev_esp
+++ /dev/null
@@ -1,21 +0,0 @@
-# Doxyfile 1.5.2
-
-# $FreeBSD$
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-PROJECT_NAME = "FreeBSD kernel ESP device code"
-OUTPUT_DIRECTORY = $(DOXYGEN_DEST_PATH)/dev_esp/
-EXTRACT_ALL = YES # for undocumented src, no warnings enabled
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-INPUT = $(DOXYGEN_SRC_PATH)/dev/esp/ \
- $(NOTREVIEWED)
-
-GENERATE_TAGFILE = dev_esp/dev_esp.tag
-
-@INCLUDE_PATH = $(DOXYGEN_INCLUDE_PATH)
-@INCLUDE = common-Doxyfile
-