Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142931031
D33115.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
150 KB
Referenced Files
None
Subscribers
None
D33115.diff
View Options
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -142,7 +142,6 @@
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
--- 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
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -157,7 +157,6 @@
# 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
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1522,9 +1522,6 @@
# 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 @@
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
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1680,8 +1680,6 @@
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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -132,7 +132,6 @@
# 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
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -109,7 +109,6 @@
${_em} \
${_ena} \
${_enetc} \
- esp \
${_et} \
evdev \
${_exca} \
diff --git a/sys/modules/esp/Makefile b/sys/modules/esp/Makefile
deleted file mode 100644
--- 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
--- 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
-
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 25, 6:58 PM (20 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27961605
Default Alt Text
D33115.diff (150 KB)
Attached To
Mode
D33115: esp: Remove
Attached
Detach File
Event Timeline
Log In to Comment