aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/conf/GENERIC1
-rw-r--r--sys/conf/NOTES2
-rw-r--r--sys/conf/files4
-rw-r--r--sys/dev/amr/amr.c2446
-rw-r--r--sys/dev/amr/amr_cam.c627
-rw-r--r--sys/dev/amr/amr_disk.c267
-rw-r--r--sys/dev/amr/amr_linux.c87
-rw-r--r--sys/dev/amr/amr_pci.c705
-rw-r--r--sys/dev/amr/amr_tables.h141
-rw-r--r--sys/dev/amr/amrio.h124
-rw-r--r--sys/dev/amr/amrreg.h657
-rw-r--r--sys/dev/amr/amrvar.h384
-rw-r--r--sys/i386/conf/GENERIC1
-rw-r--r--sys/modules/Makefile1
-rw-r--r--sys/modules/amr/Makefile21
-rw-r--r--sys/modules/amr/amr_cam/Makefile9
-rw-r--r--sys/modules/amr/amr_linux/Makefile8
17 files changed, 0 insertions, 5485 deletions
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index afd386f5913e..9d15833e472a 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -180,7 +180,6 @@ device ses # Enclosure Services (SES and SAF-TE)
#device ctl # CAM Target Layer
# RAID controllers interfaced to the SCSI subsystem
-device amr # AMI MegaRAID
device arcmsr # Areca SATA II RAID
device ciss # Compaq Smart RAID 5*
device ips # IBM (Adaptec) ServeRAID
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 2221f8feb7dd..f0546dfca101 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1642,8 +1642,6 @@ device ciss
#
device ida # Compaq Smart RAID
device mlx # Mylex DAC960
-device amr # AMI MegaRAID
-device amrp # SCSI Passthrough interface (optional, CAM req.)
device mfi # LSI MegaRAID SAS
device mfip # LSI MegaRAID SAS passthrough, requires CAM
options MFI_DEBUG
diff --git a/sys/conf/files b/sys/conf/files
index 637aed6bfb9c..650887cf54e6 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -890,10 +890,6 @@ dev/altera/pio/pio.c optional altera_pio
dev/altera/pio/pio_if.m optional altera_pio
dev/amdpm/amdpm.c optional amdpm pci | nfpm pci
dev/amdsmb/amdsmb.c optional amdsmb pci
-dev/amr/amr.c optional amr
-dev/amr/amr_cam.c optional amrp amr
-dev/amr/amr_disk.c optional amr
-dev/amr/amr_pci.c optional amr pci
#
dev/ata/ata_if.m optional ata | atacore
dev/ata/ata-all.c optional ata | atacore
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
deleted file mode 100644
index 1c4f252345e9..000000000000
--- a/sys/dev/amr/amr.c
+++ /dev/null
@@ -1,2446 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 1999,2000 Michael Smith
- * Copyright (c) 2000 BSDi
- * Copyright (c) 2005 Scott Long
- * 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.
- */
-/*-
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002, 2004 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Driver for the AMI MegaRaid family of controllers.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/stat.h>
-
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-#include <dev/amr/amrio.h>
-#include <dev/amr/amrreg.h>
-#include <dev/amr/amrvar.h>
-#define AMR_DEFINE_TABLES
-#include <dev/amr/amr_tables.h>
-
-SYSCTL_NODE(_hw, OID_AUTO, amr, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
- "AMR driver parameters");
-
-static d_open_t amr_open;
-static d_close_t amr_close;
-static d_ioctl_t amr_ioctl;
-
-static struct cdevsw amr_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = amr_open,
- .d_close = amr_close,
- .d_ioctl = amr_ioctl,
- .d_name = "amr",
-};
-
-int linux_no_adapter = 0;
-/*
- * Initialisation, bus interface.
- */
-static void amr_startup(void *arg);
-
-/*
- * Command wrappers
- */
-static int amr_query_controller(struct amr_softc *sc);
-static void *amr_enquiry(struct amr_softc *sc, size_t bufsize,
- u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual, int *status);
-static void amr_completeio(struct amr_command *ac);
-static int amr_support_ext_cdb(struct amr_softc *sc);
-
-/*
- * Command buffer allocation.
- */
-static void amr_alloccmd_cluster(struct amr_softc *sc);
-static void amr_freecmd_cluster(struct amr_command_cluster *acc);
-
-/*
- * Command processing.
- */
-static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
-static int amr_wait_command(struct amr_command *ac) __unused;
-static int amr_mapcmd(struct amr_command *ac);
-static void amr_unmapcmd(struct amr_command *ac);
-static int amr_start(struct amr_command *ac);
-static void amr_complete(void *context, ac_qhead_t *head);
-static void amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
-static void amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
-static void amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
-static void amr_abort_load(struct amr_command *ac);
-
-/*
- * Interface-specific shims
- */
-static int amr_quartz_submit_command(struct amr_command *ac);
-static int amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
-static int amr_quartz_poll_command(struct amr_command *ac);
-static int amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac);
-
-static int amr_std_submit_command(struct amr_command *ac);
-static int amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
-static int amr_std_poll_command(struct amr_command *ac);
-static void amr_std_attach_mailbox(struct amr_softc *sc);
-
-#ifdef AMR_BOARD_INIT
-static int amr_quartz_init(struct amr_softc *sc);
-static int amr_std_init(struct amr_softc *sc);
-#endif
-
-/*
- * Debugging
- */
-static void amr_describe_controller(struct amr_softc *sc);
-#ifdef AMR_DEBUG
-#if 0
-static void amr_printcommand(struct amr_command *ac);
-#endif
-#endif
-
-static void amr_init_sysctl(struct amr_softc *sc);
-static int amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr,
- int32_t flag, struct thread *td);
-
-static MALLOC_DEFINE(M_AMR, "amr", "AMR memory");
-
-/********************************************************************************
- ********************************************************************************
- Inline Glue
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- ********************************************************************************
- Public Interfaces
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Initialise the controller and softc.
- */
-int
-amr_attach(struct amr_softc *sc)
-{
- device_t child;
-
- debug_called(1);
-
- /*
- * Initialise per-controller queues.
- */
- amr_init_qhead(&sc->amr_freecmds);
- amr_init_qhead(&sc->amr_ready);
- TAILQ_INIT(&sc->amr_cmd_clusters);
- bioq_init(&sc->amr_bioq);
-
- debug(2, "queue init done");
-
- /*
- * Configure for this controller type.
- */
- if (AMR_IS_QUARTZ(sc)) {
- sc->amr_submit_command = amr_quartz_submit_command;
- sc->amr_get_work = amr_quartz_get_work;
- sc->amr_poll_command = amr_quartz_poll_command;
- sc->amr_poll_command1 = amr_quartz_poll_command1;
- } else {
- sc->amr_submit_command = amr_std_submit_command;
- sc->amr_get_work = amr_std_get_work;
- sc->amr_poll_command = amr_std_poll_command;
- amr_std_attach_mailbox(sc);
- }
-
-#ifdef AMR_BOARD_INIT
- if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc)))
- return(ENXIO);
-#endif
-
- /*
- * Allocate initial commands.
- */
- amr_alloccmd_cluster(sc);
-
- /*
- * Quiz controller for features and limits.
- */
- if (amr_query_controller(sc))
- return(ENXIO);
-
- debug(2, "controller query complete");
-
- /*
- * preallocate the remaining commands.
- */
- while (sc->amr_nextslot < sc->amr_maxio)
- amr_alloccmd_cluster(sc);
-
- /*
- * Setup sysctls.
- */
- amr_init_sysctl(sc);
-
- /*
- * Attach our 'real' SCSI channels to CAM.
- */
- child = device_add_child(sc->amr_dev, "amrp", -1);
- sc->amr_pass = child;
- if (child != NULL) {
- device_set_softc(child, sc);
- device_set_desc(child, "SCSI Passthrough Bus");
- bus_generic_attach(sc->amr_dev);
- }
-
- /*
- * Create the control device.
- */
- sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR,
- S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev));
- sc->amr_dev_t->si_drv1 = sc;
- linux_no_adapter++;
- if (device_get_unit(sc->amr_dev) == 0)
- make_dev_alias(sc->amr_dev_t, "megadev0");
-
- /*
- * Schedule ourselves to bring the controller up once interrupts are
- * available.
- */
- bzero(&sc->amr_ich, sizeof(struct intr_config_hook));
- sc->amr_ich.ich_func = amr_startup;
- sc->amr_ich.ich_arg = sc;
- if (config_intrhook_establish(&sc->amr_ich) != 0) {
- device_printf(sc->amr_dev, "can't establish configuration hook\n");
- return(ENOMEM);
- }
-
- /*
- * Print a little information about the controller.
- */
- amr_describe_controller(sc);
-
- debug(2, "attach complete");
- return(0);
-}
-
-/********************************************************************************
- * Locate disk resources and attach children to them.
- */
-static void
-amr_startup(void *arg)
-{
- struct amr_softc *sc = (struct amr_softc *)arg;
- struct amr_logdrive *dr;
- int i, error;
-
- debug_called(1);
-
- /* get up-to-date drive information */
- if (amr_query_controller(sc)) {
- device_printf(sc->amr_dev, "can't scan controller for drives\n");
- return;
- }
-
- /* iterate over available drives */
- for (i = 0, dr = &sc->amr_drive[0]; (i < AMR_MAXLD) && (dr->al_size != 0xffffffff); i++, dr++) {
- /* are we already attached to this drive? */
- if (dr->al_disk == 0) {
- /* generate geometry information */
- if (dr->al_size > 0x200000) { /* extended translation? */
- dr->al_heads = 255;
- dr->al_sectors = 63;
- } else {
- dr->al_heads = 64;
- dr->al_sectors = 32;
- }
- dr->al_cylinders = dr->al_size / (dr->al_heads * dr->al_sectors);
-
- dr->al_disk = device_add_child(sc->amr_dev, NULL, -1);
- if (dr->al_disk == 0)
- device_printf(sc->amr_dev, "device_add_child failed\n");
- device_set_ivars(dr->al_disk, dr);
- }
- }
-
- if ((error = bus_generic_attach(sc->amr_dev)) != 0)
- device_printf(sc->amr_dev, "bus_generic_attach returned %d\n", error);
-
- /* mark controller back up */
- sc->amr_state &= ~AMR_STATE_SHUTDOWN;
-
- /* interrupts will be enabled before we do anything more */
- sc->amr_state |= AMR_STATE_INTEN;
-
- /* pull ourselves off the intrhook chain */
- if (sc->amr_ich.ich_func)
- config_intrhook_disestablish(&sc->amr_ich);
- sc->amr_ich.ich_func = NULL;
-
- return;
-}
-
-static void
-amr_init_sysctl(struct amr_softc *sc)
-{
-
- SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
- OID_AUTO, "allow_volume_configure", CTLFLAG_RW, &sc->amr_allow_vol_config, 0,
- "");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
- OID_AUTO, "nextslot", CTLFLAG_RD, &sc->amr_nextslot, 0,
- "");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
- OID_AUTO, "busyslots", CTLFLAG_RD, &sc->amr_busyslots, 0,
- "");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
- OID_AUTO, "maxio", CTLFLAG_RD, &sc->amr_maxio, 0,
- "");
-}
-
-/*******************************************************************************
- * Free resources associated with a controller instance
- */
-void
-amr_free(struct amr_softc *sc)
-{
- struct amr_command_cluster *acc;
-
- /* detach from CAM */
- if (sc->amr_pass != NULL)
- device_delete_child(sc->amr_dev, sc->amr_pass);
-
- /* throw away any command buffers */
- while ((acc = TAILQ_FIRST(&sc->amr_cmd_clusters)) != NULL) {
- TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link);
- amr_freecmd_cluster(acc);
- }
-
- /* destroy control device */
- if( sc->amr_dev_t != (struct cdev *)NULL)
- destroy_dev(sc->amr_dev_t);
-
- if (mtx_initialized(&sc->amr_hw_lock))
- mtx_destroy(&sc->amr_hw_lock);
-
- if (mtx_initialized(&sc->amr_list_lock))
- mtx_destroy(&sc->amr_list_lock);
-}
-
-/*******************************************************************************
- * Receive a bio structure from a child device and queue it on a particular
- * disk resource, then poke the disk resource to start as much work as it can.
- */
-int
-amr_submit_bio(struct amr_softc *sc, struct bio *bio)
-{
- debug_called(2);
-
- mtx_lock(&sc->amr_list_lock);
- amr_enqueue_bio(sc, bio);
- amr_startio(sc);
- mtx_unlock(&sc->amr_list_lock);
- return(0);
-}
-
-/********************************************************************************
- * Accept an open operation on the control device.
- */
-static int
-amr_open(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
- int unit = dev2unit(dev);
- struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
-
- debug_called(1);
-
- sc->amr_state |= AMR_STATE_OPEN;
- return(0);
-}
-
-#ifdef LSI
-static int
-amr_del_ld(struct amr_softc *sc, int drv_no, int status)
-{
-
- debug_called(1);
-
- sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
- sc->amr_state &= ~AMR_STATE_LD_DELETE;
- sc->amr_state |= AMR_STATE_REMAP_LD;
- debug(1, "State Set");
-
- if (!status) {
- debug(1, "disk begin destroyed %d",drv_no);
- if (--amr_disks_registered == 0)
- cdevsw_remove(&amrddisk_cdevsw);
- debug(1, "disk begin destroyed success");
- }
- return 0;
-}
-
-static int
-amr_prepare_ld_delete(struct amr_softc *sc)
-{
-
- debug_called(1);
- if (sc->ld_del_supported == 0)
- return(ENOIOCTL);
-
- sc->amr_state |= AMR_STATE_QUEUE_FRZN;
- sc->amr_state |= AMR_STATE_LD_DELETE;
-
- /* 5 minutes for the all the commands to be flushed.*/
- tsleep((void *)&sc->ld_del_supported, PCATCH | PRIBIO,"delete_logical_drv",hz * 60 * 1);
- if ( sc->amr_busyslots )
- return(ENOIOCTL);
-
- return 0;
-}
-#endif
-
-/********************************************************************************
- * Accept the last close on the control device.
- */
-static int
-amr_close(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
- int unit = dev2unit(dev);
- struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
-
- debug_called(1);
-
- sc->amr_state &= ~AMR_STATE_OPEN;
- return (0);
-}
-
-/********************************************************************************
- * Handle controller-specific control operations.
- */
-static void
-amr_rescan_drives(struct cdev *dev)
-{
- struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
- int i, error = 0;
-
- sc->amr_state |= AMR_STATE_REMAP_LD;
- while (sc->amr_busyslots) {
- device_printf(sc->amr_dev, "idle controller\n");
- amr_done(sc);
- }
-
- /* mark ourselves as in-shutdown */
- sc->amr_state |= AMR_STATE_SHUTDOWN;
-
- /* flush controller */
- device_printf(sc->amr_dev, "flushing cache...");
- printf("%s\n", amr_flush(sc) ? "failed" : "done");
-
- /* delete all our child devices */
- for(i = 0 ; i < AMR_MAXLD; i++) {
- if(sc->amr_drive[i].al_disk != 0) {
- if((error = device_delete_child(sc->amr_dev,
- sc->amr_drive[i].al_disk)) != 0)
- goto shutdown_out;
-
- sc->amr_drive[i].al_disk = 0;
- }
- }
-
-shutdown_out:
- amr_startup(sc);
-}
-
-/*
- * Bug-for-bug compatibility with Linux!
- * Some apps will send commands with inlen and outlen set to 0,
- * even though they expect data to be transferred to them from the
- * card. Linux accidentally allows this by allocating a 4KB
- * buffer for the transfer anyways, but it then throws it away
- * without copying it back to the app.
- *
- * The amr(4) firmware relies on this feature. In fact, it assumes
- * the buffer is always a power of 2 up to a max of 64k. There is
- * also at least one case where it assumes a buffer less than 16k is
- * greater than 16k. However, forcing all buffers to a size of 32k
- * causes stalls in the firmware. Force each command smaller than
- * 64k up to the next power of two except that commands between 8k
- * and 16k are rounded up to 32k instead of 16k.
- */
-static unsigned long
-amr_ioctl_buffer_length(unsigned long len)
-{
-
- if (len <= 4 * 1024)
- return (4 * 1024);
- if (len <= 8 * 1024)
- return (8 * 1024);
- if (len <= 32 * 1024)
- return (32 * 1024);
- if (len <= 64 * 1024)
- return (64 * 1024);
- return (len);
-}
-
-int
-amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag,
- struct thread *td)
-{
- struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
- struct amr_command *ac;
- struct amr_mailbox *mb;
- struct amr_linux_ioctl ali;
- void *dp, *temp;
- int error;
- int len, ac_flags = 0;
- int logical_drives_changed = 0;
- u_int32_t linux_version = 0x02100000;
- u_int8_t status;
- struct amr_passthrough *ap; /* 60 bytes */
-
- error = 0;
- dp = NULL;
- ac = NULL;
- ap = NULL;
-
- if ((error = copyin(addr, &ali, sizeof(ali))) != 0)
- return (error);
- switch (ali.ui.fcs.opcode) {
- case 0x82:
- switch(ali.ui.fcs.subopcode) {
- case 'e':
- copyout(&linux_version, (void *)(uintptr_t)ali.data,
- sizeof(linux_version));
- error = 0;
- break;
-
- case 'm':
- copyout(&linux_no_adapter, (void *)(uintptr_t)ali.data,
- sizeof(linux_no_adapter));
- td->td_retval[0] = linux_no_adapter;
- error = 0;
- break;
-
- default:
- printf("Unknown subopcode\n");
- error = ENOIOCTL;
- break;
- }
- break;
-
- case 0x80:
- case 0x81:
- if (ali.ui.fcs.opcode == 0x80)
- len = max(ali.outlen, ali.inlen);
- else
- len = ali.ui.fcs.length;
-
- mb = (void *)&ali.mbox[0];
-
- if ((ali.mbox[0] == FC_DEL_LOGDRV && ali.mbox[2] == OP_DEL_LOGDRV) || /* delete */
- (ali.mbox[0] == AMR_CMD_CONFIG && ali.mbox[2] == 0x0d)) { /* create */
- if (sc->amr_allow_vol_config == 0) {
- error = EPERM;
- break;
- }
- logical_drives_changed = 1;
- }
-
- if (ali.mbox[0] == AMR_CMD_PASS) {
- mtx_lock(&sc->amr_list_lock);
- while ((ac = amr_alloccmd(sc)) == NULL)
- msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
- mtx_unlock(&sc->amr_list_lock);
- ap = &ac->ac_ccb->ccb_pthru;
-
- error = copyin((void *)(uintptr_t)mb->mb_physaddr, ap,
- sizeof(struct amr_passthrough));
- if (error)
- break;
-
- if (ap->ap_data_transfer_length)
- dp = malloc(ap->ap_data_transfer_length, M_AMR,
- M_WAITOK | M_ZERO);
-
- if (ali.inlen) {
- error = copyin((void *)(uintptr_t)ap->ap_data_transfer_address,
- dp, ap->ap_data_transfer_length);
- if (error)
- break;
- }
-
- ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB;
- bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox));
- ac->ac_mailbox.mb_command = AMR_CMD_PASS;
- ac->ac_flags = ac_flags;
-
- ac->ac_data = dp;
- ac->ac_length = ap->ap_data_transfer_length;
- temp = (void *)(uintptr_t)ap->ap_data_transfer_address;
-
- mtx_lock(&sc->amr_list_lock);
- error = amr_wait_command(ac);
- mtx_unlock(&sc->amr_list_lock);
- if (error)
- break;
-
- status = ac->ac_status;
- error = copyout(&status, &((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_scsi_status, sizeof(status));
- if (error)
- break;
-
- if (ali.outlen) {
- error = copyout(dp, temp, ap->ap_data_transfer_length);
- if (error)
- break;
- }
- error = copyout(ap->ap_request_sense_area, ((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_request_sense_area, ap->ap_request_sense_length);
- if (error)
- break;
-
- error = 0;
- break;
- } else if (ali.mbox[0] == AMR_CMD_PASS_64) {
- printf("No AMR_CMD_PASS_64\n");
- error = ENOIOCTL;
- break;
- } else if (ali.mbox[0] == AMR_CMD_EXTPASS) {
- printf("No AMR_CMD_EXTPASS\n");
- error = ENOIOCTL;
- break;
- } else {
- len = amr_ioctl_buffer_length(imax(ali.inlen, ali.outlen));
-
- dp = malloc(len, M_AMR, M_WAITOK | M_ZERO);
-
- if (ali.inlen) {
- error = copyin((void *)(uintptr_t)mb->mb_physaddr, dp, len);
- if (error)
- break;
- }
-
- mtx_lock(&sc->amr_list_lock);
- while ((ac = amr_alloccmd(sc)) == NULL)
- msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
-
- ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
- bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox));
- bcopy(&ali.mbox[0], &ac->ac_mailbox, sizeof(ali.mbox));
-
- ac->ac_length = len;
- ac->ac_data = dp;
- ac->ac_flags = ac_flags;
-
- error = amr_wait_command(ac);
- mtx_unlock(&sc->amr_list_lock);
- if (error)
- break;
-
- status = ac->ac_status;
- error = copyout(&status, &((struct amr_mailbox *)&((struct amr_linux_ioctl *)addr)->mbox[0])->mb_status, sizeof(status));
- if (ali.outlen) {
- error = copyout(dp, (void *)(uintptr_t)mb->mb_physaddr, ali.outlen);
- if (error)
- break;
- }
-
- error = 0;
- if (logical_drives_changed)
- amr_rescan_drives(dev);
- break;
- }
- break;
-
- default:
- debug(1, "unknown linux ioctl 0x%lx", cmd);
- printf("unknown linux ioctl 0x%lx\n", cmd);
- error = ENOIOCTL;
- break;
- }
-
- /*
- * At this point, we know that there is a lock held and that these
- * objects have been allocated.
- */
- mtx_lock(&sc->amr_list_lock);
- if (ac != NULL)
- amr_releasecmd(ac);
- mtx_unlock(&sc->amr_list_lock);
- if (dp != NULL)
- free(dp, M_AMR);
- return(error);
-}
-
-static int
-amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td)
-{
- struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
- union {
- void *_p;
- struct amr_user_ioctl *au;
-#ifdef AMR_IO_COMMAND32
- struct amr_user_ioctl32 *au32;
-#endif
- int *result;
- } arg;
- struct amr_command *ac;
- struct amr_mailbox_ioctl *mbi;
- void *dp, *au_buffer;
- unsigned long au_length, real_length;
- unsigned char *au_cmd;
- int *au_statusp;
- int error;
- struct amr_passthrough *ap; /* 60 bytes */
- int logical_drives_changed = 0;
-
- debug_called(1);
-
- arg._p = (void *)addr;
-
- error = 0;
- dp = NULL;
- ac = NULL;
- ap = NULL;
-
- switch(cmd) {
- case AMR_IO_VERSION:
- debug(1, "AMR_IO_VERSION");
- *arg.result = AMR_IO_VERSION_NUMBER;
- return(0);
-
-#ifdef AMR_IO_COMMAND32
- /*
- * Accept ioctl-s from 32-bit binaries on non-32-bit
- * platforms, such as AMD. LSI's MEGAMGR utility is
- * the only example known today... -mi
- */
- case AMR_IO_COMMAND32:
- debug(1, "AMR_IO_COMMAND32 0x%x", arg.au32->au_cmd[0]);
- au_cmd = arg.au32->au_cmd;
- au_buffer = (void *)(u_int64_t)arg.au32->au_buffer;
- au_length = arg.au32->au_length;
- au_statusp = &arg.au32->au_status;
- break;
-#endif
-
- case AMR_IO_COMMAND:
- debug(1, "AMR_IO_COMMAND 0x%x", arg.au->au_cmd[0]);
- au_cmd = arg.au->au_cmd;
- au_buffer = (void *)arg.au->au_buffer;
- au_length = arg.au->au_length;
- au_statusp = &arg.au->au_status;
- break;
-
- case 0xc0046d00:
- case 0xc06e6d00: /* Linux emulation */
- {
- devclass_t devclass;
- struct amr_linux_ioctl ali;
- int adapter, error;
-
- devclass = devclass_find("amr");
- if (devclass == NULL)
- return (ENOENT);
-
- error = copyin(addr, &ali, sizeof(ali));
- if (error)
- return (error);
- if (ali.ui.fcs.opcode == 0x82)
- adapter = 0;
- else
- adapter = (ali.ui.fcs.adapno) ^ 'm' << 8;
-
- sc = devclass_get_softc(devclass, adapter);
- if (sc == NULL)
- return (ENOENT);
-
- return (amr_linux_ioctl_int(sc->amr_dev_t, cmd, addr, 0, td));
- }
- default:
- debug(1, "unknown ioctl 0x%lx", cmd);
- return(ENOIOCTL);
- }
-
- if ((au_cmd[0] == FC_DEL_LOGDRV && au_cmd[1] == OP_DEL_LOGDRV) || /* delete */
- (au_cmd[0] == AMR_CMD_CONFIG && au_cmd[1] == 0x0d)) { /* create */
- if (sc->amr_allow_vol_config == 0) {
- error = EPERM;
- goto out;
- }
- logical_drives_changed = 1;
-#ifdef LSI
- if ((error = amr_prepare_ld_delete(sc)) != 0)
- return (error);
-#endif
- }
-
- /* handle inbound data buffer */
- real_length = amr_ioctl_buffer_length(au_length);
- dp = malloc(real_length, M_AMR, M_WAITOK|M_ZERO);
- if (au_length != 0 && au_cmd[0] != 0x06) {
- if ((error = copyin(au_buffer, dp, au_length)) != 0) {
- free(dp, M_AMR);
- return (error);
- }
- debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp);
- }
-
- /* Allocate this now before the mutex gets held */
-
- mtx_lock(&sc->amr_list_lock);
- while ((ac = amr_alloccmd(sc)) == NULL)
- msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
-
- /* handle SCSI passthrough command */
- if (au_cmd[0] == AMR_CMD_PASS) {
- int len;
-
- ap = &ac->ac_ccb->ccb_pthru;
- bzero(ap, sizeof(struct amr_passthrough));
-
- /* copy cdb */
- len = au_cmd[2];
- ap->ap_cdb_length = len;
- bcopy(au_cmd + 3, ap->ap_cdb, len);
-
- /* build passthrough */
- ap->ap_timeout = au_cmd[len + 3] & 0x07;
- ap->ap_ars = (au_cmd[len + 3] & 0x08) ? 1 : 0;
- ap->ap_islogical = (au_cmd[len + 3] & 0x80) ? 1 : 0;
- ap->ap_logical_drive_no = au_cmd[len + 4];
- ap->ap_channel = au_cmd[len + 5];
- ap->ap_scsi_id = au_cmd[len + 6];
- ap->ap_request_sense_length = 14;
- ap->ap_data_transfer_length = au_length;
- /* XXX what about the request-sense area? does the caller want it? */
-
- /* build command */
- ac->ac_mailbox.mb_command = AMR_CMD_PASS;
- ac->ac_flags = AMR_CMD_CCB;
-
- } else {
- /* direct command to controller */
- mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox;
-
- /* copy pertinent mailbox items */
- mbi->mb_command = au_cmd[0];
- mbi->mb_channel = au_cmd[1];
- mbi->mb_param = au_cmd[2];
- mbi->mb_pad[0] = au_cmd[3];
- mbi->mb_drive = au_cmd[4];
- ac->ac_flags = 0;
- }
-
- /* build the command */
- ac->ac_data = dp;
- ac->ac_length = real_length;
- ac->ac_flags |= AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
-
- /* run the command */
- error = amr_wait_command(ac);
- mtx_unlock(&sc->amr_list_lock);
- if (error)
- goto out;
-
- /* copy out data and set status */
- if (au_length != 0) {
- error = copyout(dp, au_buffer, au_length);
- }
- debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer);
- debug(2, "%p status 0x%x", dp, ac->ac_status);
- *au_statusp = ac->ac_status;
-
-out:
- /*
- * At this point, we know that there is a lock held and that these
- * objects have been allocated.
- */
- mtx_lock(&sc->amr_list_lock);
- if (ac != NULL)
- amr_releasecmd(ac);
- mtx_unlock(&sc->amr_list_lock);
- if (dp != NULL)
- free(dp, M_AMR);
-
-#ifndef LSI
- if (logical_drives_changed)
- amr_rescan_drives(dev);
-#endif
-
- return(error);
-}
-
-/********************************************************************************
- ********************************************************************************
- Command Wrappers
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Interrogate the controller for the operational parameters we require.
- */
-static int
-amr_query_controller(struct amr_softc *sc)
-{
- struct amr_enquiry3 *aex;
- struct amr_prodinfo *ap;
- struct amr_enquiry *ae;
- int ldrv;
- int status;
-
- /*
- * Greater than 10 byte cdb support
- */
- sc->support_ext_cdb = amr_support_ext_cdb(sc);
-
- if(sc->support_ext_cdb) {
- debug(2,"supports extended CDBs.");
- }
-
- /*
- * Try to issue an ENQUIRY3 command
- */
- if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
- AMR_CONFIG_ENQ3_SOLICITED_FULL, &status)) != NULL) {
- /*
- * Fetch current state of logical drives.
- */
- for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
- sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv];
- sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv];
- sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv];
- debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
- sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
- }
- free(aex, M_AMR);
-
- /*
- * Get product info for channel count.
- */
- if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0, &status)) == NULL) {
- device_printf(sc->amr_dev, "can't obtain product data from controller\n");
- return(1);
- }
- sc->amr_maxdrives = 40;
- sc->amr_maxchan = ap->ap_nschan;
- sc->amr_maxio = ap->ap_maxio;
- sc->amr_type |= AMR_TYPE_40LD;
- free(ap, M_AMR);
-
- ap = amr_enquiry(sc, 0, FC_DEL_LOGDRV, OP_SUP_DEL_LOGDRV, 0, &status);
- if (ap != NULL)
- free(ap, M_AMR);
- if (!status) {
- sc->amr_ld_del_supported = 1;
- device_printf(sc->amr_dev, "delete logical drives supported by controller\n");
- }
- } else {
- /* failed, try the 8LD ENQUIRY commands */
- if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0, &status)) == NULL) {
- if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0, &status)) == NULL) {
- device_printf(sc->amr_dev, "can't obtain configuration data from controller\n");
- return(1);
- }
- ae->ae_signature = 0;
- }
-
- /*
- * Fetch current state of logical drives.
- */
- for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) {
- sc->amr_drive[ldrv].al_size = ae->ae_ldrv.al_size[ldrv];
- sc->amr_drive[ldrv].al_state = ae->ae_ldrv.al_state[ldrv];
- sc->amr_drive[ldrv].al_properties = ae->ae_ldrv.al_properties[ldrv];
- debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
- sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
- }
-
- sc->amr_maxdrives = 8;
- sc->amr_maxchan = ae->ae_adapter.aa_channels;
- sc->amr_maxio = ae->ae_adapter.aa_maxio;
- free(ae, M_AMR);
- }
-
- /*
- * Mark remaining drives as unused.
- */
- for (; ldrv < AMR_MAXLD; ldrv++)
- sc->amr_drive[ldrv].al_size = 0xffffffff;
-
- /*
- * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust
- * the controller's reported value, and lockups have been seen when we do.
- */
- sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);
-
- return(0);
-}
-
-/********************************************************************************
- * Run a generic enquiry-style command.
- */
-static void *
-amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual, int *status)
-{
- struct amr_command *ac;
- void *result;
- u_int8_t *mbox;
- int error;
-
- debug_called(1);
-
- error = 1;
- result = NULL;
-
- /* get ourselves a command buffer */
- mtx_lock(&sc->amr_list_lock);
- ac = amr_alloccmd(sc);
- mtx_unlock(&sc->amr_list_lock);
- if (ac == NULL)
- goto out;
- /* allocate the response structure */
- if ((result = malloc(bufsize, M_AMR, M_ZERO|M_NOWAIT)) == NULL)
- goto out;
- /* set command flags */
-
- ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN;
-
- /* point the command at our data */
- ac->ac_data = result;
- ac->ac_length = bufsize;
-
- /* build the command proper */
- mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
- mbox[0] = cmd;
- mbox[2] = cmdsub;
- mbox[3] = cmdqual;
- *status = 0;
-
- /* can't assume that interrupts are going to work here, so play it safe */
- if (sc->amr_poll_command(ac))
- goto out;
- error = ac->ac_status;
- *status = ac->ac_status;
-
- out:
- mtx_lock(&sc->amr_list_lock);
- if (ac != NULL)
- amr_releasecmd(ac);
- mtx_unlock(&sc->amr_list_lock);
- if ((error != 0) && (result != NULL)) {
- free(result, M_AMR);
- result = NULL;
- }
- return(result);
-}
-
-/********************************************************************************
- * Flush the controller's internal cache, return status.
- */
-int
-amr_flush(struct amr_softc *sc)
-{
- struct amr_command *ac;
- int error;
-
- /* get ourselves a command buffer */
- error = 1;
- mtx_lock(&sc->amr_list_lock);
- ac = amr_alloccmd(sc);
- mtx_unlock(&sc->amr_list_lock);
- if (ac == NULL)
- goto out;
- /* set command flags */
- ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
-
- /* build the command proper */
- ac->ac_mailbox.mb_command = AMR_CMD_FLUSH;
-
- /* we have to poll, as the system may be going down or otherwise damaged */
- if (sc->amr_poll_command(ac))
- goto out;
- error = ac->ac_status;
-
- out:
- mtx_lock(&sc->amr_list_lock);
- if (ac != NULL)
- amr_releasecmd(ac);
- mtx_unlock(&sc->amr_list_lock);
- return(error);
-}
-
-/********************************************************************************
- * Detect extented cdb >> greater than 10 byte cdb support
- * returns '1' means this support exist
- * returns '0' means this support doesn't exist
- */
-static int
-amr_support_ext_cdb(struct amr_softc *sc)
-{
- struct amr_command *ac;
- u_int8_t *mbox;
- int error;
-
- /* get ourselves a command buffer */
- error = 0;
- mtx_lock(&sc->amr_list_lock);
- ac = amr_alloccmd(sc);
- mtx_unlock(&sc->amr_list_lock);
- if (ac == NULL)
- goto out;
- /* set command flags */
- ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
-
- /* build the command proper */
- mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
- mbox[0] = 0xA4;
- mbox[2] = 0x16;
-
- /* we have to poll, as the system may be going down or otherwise damaged */
- if (sc->amr_poll_command(ac))
- goto out;
- if( ac->ac_status == AMR_STATUS_SUCCESS ) {
- error = 1;
- }
-
-out:
- mtx_lock(&sc->amr_list_lock);
- if (ac != NULL)
- amr_releasecmd(ac);
- mtx_unlock(&sc->amr_list_lock);
- return(error);
-}
-
-/********************************************************************************
- * Try to find I/O work for the controller from one or more of the work queues.
- *
- * We make the assumption that if the controller is not ready to take a command
- * at some given time, it will generate an interrupt at some later time when
- * it is.
- */
-void
-amr_startio(struct amr_softc *sc)
-{
- struct amr_command *ac;
-
- /* spin until something prevents us from doing any work */
- for (;;) {
- /* Don't bother to queue commands no bounce buffers are available. */
- if (sc->amr_state & AMR_STATE_QUEUE_FRZN)
- break;
-
- /* try to get a ready command */
- ac = amr_dequeue_ready(sc);
-
- /* if that failed, build a command from a bio */
- if (ac == NULL)
- (void)amr_bio_command(sc, &ac);
-
- /* if that failed, build a command from a ccb */
- if ((ac == NULL) && (sc->amr_cam_command != NULL))
- sc->amr_cam_command(sc, &ac);
-
- /* if we don't have anything to do, give up */
- if (ac == NULL)
- break;
-
- /* try to give the command to the controller; if this fails save it for later and give up */
- if (amr_start(ac)) {
- debug(2, "controller busy, command deferred");
- amr_requeue_ready(ac); /* XXX schedule retry very soon? */
- break;
- }
- }
-}
-
-/********************************************************************************
- * Handle completion of an I/O command.
- */
-static void
-amr_completeio(struct amr_command *ac)
-{
- struct amrd_softc *sc = ac->ac_bio->bio_disk->d_drv1;
- static struct timeval lastfail;
- static int curfail;
-
- if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */
- ac->ac_bio->bio_error = EIO;
- ac->ac_bio->bio_flags |= BIO_ERROR;
-
- if (ppsratecheck(&lastfail, &curfail, 1))
- device_printf(sc->amrd_dev, "I/O error - 0x%x\n", ac->ac_status);
-/* amr_printcommand(ac);*/
- }
- amrd_intr(ac->ac_bio);
- mtx_lock(&ac->ac_sc->amr_list_lock);
- amr_releasecmd(ac);
- mtx_unlock(&ac->ac_sc->amr_list_lock);
-}
-
-/********************************************************************************
- ********************************************************************************
- Command Processing
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Convert a bio off the top of the bio queue into a command.
- */
-static int
-amr_bio_command(struct amr_softc *sc, struct amr_command **acp)
-{
- struct amr_command *ac;
- struct amrd_softc *amrd;
- struct bio *bio;
- int error;
- int blkcount;
- int driveno;
- int cmd;
-
- ac = NULL;
- error = 0;
-
- /* get a command */
- if ((ac = amr_alloccmd(sc)) == NULL)
- return (ENOMEM);
-
- /* get a bio to work on */
- if ((bio = amr_dequeue_bio(sc)) == NULL) {
- amr_releasecmd(ac);
- return (0);
- }
-
- /* connect the bio to the command */
- ac->ac_complete = amr_completeio;
- ac->ac_bio = bio;
- ac->ac_data = bio->bio_data;
- ac->ac_length = bio->bio_bcount;
- cmd = 0;
- switch (bio->bio_cmd) {
- case BIO_READ:
- ac->ac_flags |= AMR_CMD_DATAIN;
- if (AMR_IS_SG64(sc)) {
- cmd = AMR_CMD_LREAD64;
- ac->ac_flags |= AMR_CMD_SG64;
- } else
- cmd = AMR_CMD_LREAD;
- break;
- case BIO_WRITE:
- ac->ac_flags |= AMR_CMD_DATAOUT;
- if (AMR_IS_SG64(sc)) {
- cmd = AMR_CMD_LWRITE64;
- ac->ac_flags |= AMR_CMD_SG64;
- } else
- cmd = AMR_CMD_LWRITE;
- break;
- case BIO_FLUSH:
- ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
- cmd = AMR_CMD_FLUSH;
- break;
- default:
- biofinish(bio, NULL, EOPNOTSUPP);
- amr_releasecmd(ac);
- return (0);
- }
- amrd = (struct amrd_softc *)bio->bio_disk->d_drv1;
- driveno = amrd->amrd_drive - sc->amr_drive;
- blkcount = howmany(bio->bio_bcount, AMR_BLKSIZE);
-
- ac->ac_mailbox.mb_command = cmd;
- if (bio->bio_cmd == BIO_READ || bio->bio_cmd == BIO_WRITE) {
- ac->ac_mailbox.mb_blkcount = blkcount;
- ac->ac_mailbox.mb_lba = bio->bio_pblkno;
- if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size) {
- device_printf(sc->amr_dev,
- "I/O beyond end of unit (%lld,%d > %lu)\n",
- (long long)bio->bio_pblkno, blkcount,
- (u_long)sc->amr_drive[driveno].al_size);
- }
- }
- ac->ac_mailbox.mb_drive = driveno;
- if (sc->amr_state & AMR_STATE_REMAP_LD)
- ac->ac_mailbox.mb_drive |= 0x80;
-
- /* we fill in the s/g related data when the command is mapped */
-
- *acp = ac;
- return(error);
-}
-
-/********************************************************************************
- * Take a command, submit it to the controller and sleep until it completes
- * or fails. Interrupts must be enabled, returns nonzero on error.
- */
-static int
-amr_wait_command(struct amr_command *ac)
-{
- int error = 0;
- struct amr_softc *sc = ac->ac_sc;
-
- debug_called(1);
-
- ac->ac_complete = NULL;
- ac->ac_flags |= AMR_CMD_SLEEP;
- if ((error = amr_start(ac)) != 0) {
- return(error);
- }
-
- while ((ac->ac_flags & AMR_CMD_BUSY) && (error != EWOULDBLOCK)) {
- error = msleep(ac,&sc->amr_list_lock, PRIBIO, "amrwcmd", 0);
- }
-
- return(error);
-}
-
-/********************************************************************************
- * Take a command, submit it to the controller and busy-wait for it to return.
- * Returns nonzero on error. Can be safely called with interrupts enabled.
- */
-static int
-amr_std_poll_command(struct amr_command *ac)
-{
- struct amr_softc *sc = ac->ac_sc;
- int error, count;
-
- debug_called(2);
-
- ac->ac_complete = NULL;
- if ((error = amr_start(ac)) != 0)
- return(error);
-
- count = 0;
- do {
- /*
- * Poll for completion, although the interrupt handler may beat us to it.
- * Note that the timeout here is somewhat arbitrary.
- */
- amr_done(sc);
- DELAY(1000);
- } while ((ac->ac_flags & AMR_CMD_BUSY) && (count++ < 1000));
- if (!(ac->ac_flags & AMR_CMD_BUSY)) {
- error = 0;
- } else {
- /* XXX the slot is now marked permanently busy */
- error = EIO;
- device_printf(sc->amr_dev, "polled command timeout\n");
- }
- return(error);
-}
-
-static void
-amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
-{
- struct amr_command *ac = arg;
- struct amr_softc *sc = ac->ac_sc;
- int mb_channel;
-
- if (err) {
- device_printf(sc->amr_dev, "error %d in %s", err, __FUNCTION__);
- ac->ac_status = AMR_STATUS_ABORTED;
- return;
- }
-
- amr_setup_sg(arg, segs, nsegs, err);
-
- /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
- mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel;
- if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG &&
- ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) ||
- (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)))
- ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments;
-
- ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments;
- ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr;
- if (AC_IS_SG64(ac)) {
- ac->ac_sg64_hi = 0;
- ac->ac_sg64_lo = ac->ac_sgbusaddr;
- }
-
- sc->amr_poll_command1(sc, ac);
-}
-
-/********************************************************************************
- * Take a command, submit it to the controller and busy-wait for it to return.
- * Returns nonzero on error. Can be safely called with interrupts enabled.
- */
-static int
-amr_quartz_poll_command(struct amr_command *ac)
-{
- struct amr_softc *sc = ac->ac_sc;
- int error;
-
- debug_called(2);
-
- error = 0;
-
- if (AC_IS_SG64(ac)) {
- ac->ac_tag = sc->amr_buffer64_dmat;
- ac->ac_datamap = ac->ac_dma64map;
- } else {
- ac->ac_tag = sc->amr_buffer_dmat;
- ac->ac_datamap = ac->ac_dmamap;
- }
-
- /* now we have a slot, we can map the command (unmapped in amr_complete) */
- if (ac->ac_data != 0) {
- if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data,
- ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
- error = 1;
- }
- } else {
- error = amr_quartz_poll_command1(sc, ac);
- }
-
- return (error);
-}
-
-static int
-amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac)
-{
- int count, error;
-
- mtx_lock(&sc->amr_hw_lock);
- if ((sc->amr_state & AMR_STATE_INTEN) == 0) {
- count=0;
- while (sc->amr_busyslots) {
- msleep(sc, &sc->amr_hw_lock, PRIBIO | PCATCH, "amrpoll", hz);
- if(count++>10) {
- break;
- }
- }
-
- if(sc->amr_busyslots) {
- device_printf(sc->amr_dev, "adapter is busy\n");
- mtx_unlock(&sc->amr_hw_lock);
- if (ac->ac_data != NULL) {
- bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
- }
- ac->ac_status=0;
- return(1);
- }
- }
-
- bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
-
- /* clear the poll/ack fields in the mailbox */
- sc->amr_mailbox->mb_ident = 0xFE;
- sc->amr_mailbox->mb_nstatus = 0xFF;
- sc->amr_mailbox->mb_status = 0xFF;
- sc->amr_mailbox->mb_poll = 0;
- sc->amr_mailbox->mb_ack = 0;
- sc->amr_mailbox->mb_busy = 1;
-
- AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
-
- while(sc->amr_mailbox->mb_nstatus == 0xFF)
- DELAY(1);
- while(sc->amr_mailbox->mb_status == 0xFF)
- DELAY(1);
- ac->ac_status=sc->amr_mailbox->mb_status;
- error = (ac->ac_status !=AMR_STATUS_SUCCESS) ? 1:0;
- while(sc->amr_mailbox->mb_poll != 0x77)
- DELAY(1);
- sc->amr_mailbox->mb_poll = 0;
- sc->amr_mailbox->mb_ack = 0x77;
-
- /* acknowledge that we have the commands */
- AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
- while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
- DELAY(1);
- mtx_unlock(&sc->amr_hw_lock);
-
- /* unmap the command's data buffer */
- if (ac->ac_flags & AMR_CMD_DATAIN) {
- bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTREAD);
- }
- if (ac->ac_flags & AMR_CMD_DATAOUT) {
- bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTWRITE);
- }
- bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
-
- return(error);
-}
-
-static __inline int
-amr_freeslot(struct amr_command *ac)
-{
- struct amr_softc *sc = ac->ac_sc;
- int slot;
-
- debug_called(3);
-
- slot = ac->ac_slot;
- if (sc->amr_busycmd[slot] == NULL)
- panic("amr: slot %d not busy?\n", slot);
-
- sc->amr_busycmd[slot] = NULL;
- atomic_subtract_int(&sc->amr_busyslots, 1);
-
- return (0);
-}
-
-/********************************************************************************
- * Map/unmap (ac)'s data in the controller's addressable space as required.
- *
- * These functions may be safely called multiple times on a given command.
- */
-static void
-amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
-{
- struct amr_command *ac = (struct amr_command *)arg;
- struct amr_sgentry *sg;
- struct amr_sg64entry *sg64;
- int flags, i;
-
- debug_called(3);
-
- /* get base address of s/g table */
- sg = ac->ac_sg.sg32;
- sg64 = ac->ac_sg.sg64;
-
- if (AC_IS_SG64(ac)) {
- ac->ac_nsegments = nsegments;
- ac->ac_mb_physaddr = 0xffffffff;
- for (i = 0; i < nsegments; i++, sg64++) {
- sg64->sg_addr = segs[i].ds_addr;
- sg64->sg_count = segs[i].ds_len;
- }
- } else {
- /* decide whether we need to populate the s/g table */
- if (nsegments < 2) {
- ac->ac_nsegments = 0;
- ac->ac_mb_physaddr = segs[0].ds_addr;
- } else {
- ac->ac_nsegments = nsegments;
- ac->ac_mb_physaddr = ac->ac_sgbusaddr;
- for (i = 0; i < nsegments; i++, sg++) {
- sg->sg_addr = segs[i].ds_addr;
- sg->sg_count = segs[i].ds_len;
- }
- }
- }
-
- flags = 0;
- if (ac->ac_flags & AMR_CMD_DATAIN)
- flags |= BUS_DMASYNC_PREREAD;
- if (ac->ac_flags & AMR_CMD_DATAOUT)
- flags |= BUS_DMASYNC_PREWRITE;
- bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flags);
- ac->ac_flags |= AMR_CMD_MAPPED;
-}
-
-static void
-amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
-{
- struct amr_command *ac = arg;
- struct amr_softc *sc = ac->ac_sc;
- int mb_channel;
-
- if (err) {
- device_printf(sc->amr_dev, "error %d in %s", err, __FUNCTION__);
- amr_abort_load(ac);
- return;
- }
-
- amr_setup_sg(arg, segs, nsegs, err);
-
- /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
- mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel;
- if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG &&
- ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) ||
- (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)))
- ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments;
-
- ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments;
- ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr;
- if (AC_IS_SG64(ac)) {
- ac->ac_sg64_hi = 0;
- ac->ac_sg64_lo = ac->ac_sgbusaddr;
- }
-
- if (sc->amr_submit_command(ac) == EBUSY) {
- amr_freeslot(ac);
- amr_requeue_ready(ac);
- }
-}
-
-static void
-amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
-{
- struct amr_command *ac = arg;
- struct amr_softc *sc = ac->ac_sc;
- struct amr_passthrough *ap = &ac->ac_ccb->ccb_pthru;
- struct amr_ext_passthrough *aep = &ac->ac_ccb->ccb_epthru;
-
- if (err) {
- device_printf(sc->amr_dev, "error %d in %s", err, __FUNCTION__);
- amr_abort_load(ac);
- return;
- }
-
- /* Set up the mailbox portion of the command to point at the ccb */
- ac->ac_mailbox.mb_nsgelem = 0;
- ac->ac_mailbox.mb_physaddr = ac->ac_ccb_busaddr;
-
- amr_setup_sg(arg, segs, nsegs, err);
-
- switch (ac->ac_mailbox.mb_command) {
- case AMR_CMD_EXTPASS:
- aep->ap_no_sg_elements = ac->ac_nsegments;
- aep->ap_data_transfer_address = ac->ac_mb_physaddr;
- break;
- case AMR_CMD_PASS:
- ap->ap_no_sg_elements = ac->ac_nsegments;
- ap->ap_data_transfer_address = ac->ac_mb_physaddr;
- break;
- default:
- panic("Unknown ccb command");
- }
-
- if (sc->amr_submit_command(ac) == EBUSY) {
- amr_freeslot(ac);
- amr_requeue_ready(ac);
- }
-}
-
-static int
-amr_mapcmd(struct amr_command *ac)
-{
- bus_dmamap_callback_t *cb;
- struct amr_softc *sc = ac->ac_sc;
-
- debug_called(3);
-
- if (AC_IS_SG64(ac)) {
- ac->ac_tag = sc->amr_buffer64_dmat;
- ac->ac_datamap = ac->ac_dma64map;
- } else {
- ac->ac_tag = sc->amr_buffer_dmat;
- ac->ac_datamap = ac->ac_dmamap;
- }
-
- if (ac->ac_flags & AMR_CMD_CCB)
- cb = amr_setup_ccb;
- else
- cb = amr_setup_data;
-
- /* if the command involves data at all, and hasn't been mapped */
- if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) {
- /* map the data buffers into bus space and build the s/g list */
- if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data,
- ac->ac_length, cb, ac, 0) == EINPROGRESS) {
- sc->amr_state |= AMR_STATE_QUEUE_FRZN;
- }
- } else {
- if (sc->amr_submit_command(ac) == EBUSY) {
- amr_freeslot(ac);
- amr_requeue_ready(ac);
- }
- }
-
- return (0);
-}
-
-static void
-amr_unmapcmd(struct amr_command *ac)
-{
- int flag;
-
- debug_called(3);
-
- /* if the command involved data at all and was mapped */
- if (ac->ac_flags & AMR_CMD_MAPPED) {
- if (ac->ac_data != NULL) {
- flag = 0;
- if (ac->ac_flags & AMR_CMD_DATAIN)
- flag |= BUS_DMASYNC_POSTREAD;
- if (ac->ac_flags & AMR_CMD_DATAOUT)
- flag |= BUS_DMASYNC_POSTWRITE;
-
- bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flag);
- bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
- }
-
- ac->ac_flags &= ~AMR_CMD_MAPPED;
- }
-}
-
-static void
-amr_abort_load(struct amr_command *ac)
-{
- ac_qhead_t head;
- struct amr_softc *sc = ac->ac_sc;
-
- mtx_assert(&sc->amr_list_lock, MA_OWNED);
-
- ac->ac_status = AMR_STATUS_ABORTED;
- amr_init_qhead(&head);
- amr_enqueue_completed(ac, &head);
-
- mtx_unlock(&sc->amr_list_lock);
- amr_complete(sc, &head);
- mtx_lock(&sc->amr_list_lock);
-}
-
-/********************************************************************************
- * Take a command and give it to the controller, returns 0 if successful, or
- * EBUSY if the command should be retried later.
- */
-static int
-amr_start(struct amr_command *ac)
-{
- struct amr_softc *sc;
- int error = 0;
- int slot;
-
- debug_called(3);
-
- /* mark command as busy so that polling consumer can tell */
- sc = ac->ac_sc;
- ac->ac_flags |= AMR_CMD_BUSY;
-
- /* get a command slot (freed in amr_done) */
- slot = ac->ac_slot;
- if (sc->amr_busycmd[slot] != NULL)
- panic("amr: slot %d busy?\n", slot);
- sc->amr_busycmd[slot] = ac;
- atomic_add_int(&sc->amr_busyslots, 1);
-
- /* Now we have a slot, we can map the command (unmapped in amr_complete). */
- if ((error = amr_mapcmd(ac)) == ENOMEM) {
- /*
- * Memory resources are short, so free the slot and let this be tried
- * later.
- */
- amr_freeslot(ac);
- }
-
- return (error);
-}
-
-/********************************************************************************
- * Extract one or more completed commands from the controller (sc)
- *
- * Returns nonzero if any commands on the work queue were marked as completed.
- */
-
-int
-amr_done(struct amr_softc *sc)
-{
- ac_qhead_t head;
- struct amr_command *ac;
- struct amr_mailbox mbox;
- int i, idx, result;
-
- debug_called(3);
-
- /* See if there's anything for us to do */
- result = 0;
- amr_init_qhead(&head);
-
- /* loop collecting completed commands */
- for (;;) {
- /* poll for a completed command's identifier and status */
- if (sc->amr_get_work(sc, &mbox)) {
- result = 1;
-
- /* iterate over completed commands in this result */
- for (i = 0; i < mbox.mb_nstatus; i++) {
- /* get pointer to busy command */
- idx = mbox.mb_completed[i] - 1;
- ac = sc->amr_busycmd[idx];
-
- /* really a busy command? */
- if (ac != NULL) {
- /* pull the command from the busy index */
- amr_freeslot(ac);
-
- /* save status for later use */
- ac->ac_status = mbox.mb_status;
- amr_enqueue_completed(ac, &head);
- debug(3, "completed command with status %x", mbox.mb_status);
- } else {
- device_printf(sc->amr_dev, "bad slot %d completed\n", idx);
- }
- }
- } else
- break; /* no work */
- }
-
- /* handle completion and timeouts */
- amr_complete(sc, &head);
-
- return(result);
-}
-
-/********************************************************************************
- * Do completion processing on done commands on (sc)
- */
-
-static void
-amr_complete(void *context, ac_qhead_t *head)
-{
- struct amr_softc *sc = (struct amr_softc *)context;
- struct amr_command *ac;
-
- debug_called(3);
-
- /* pull completed commands off the queue */
- for (;;) {
- ac = amr_dequeue_completed(sc, head);
- if (ac == NULL)
- break;
-
- /* unmap the command's data buffer */
- amr_unmapcmd(ac);
-
- /*
- * Is there a completion handler?
- */
- if (ac->ac_complete != NULL) {
- /* unbusy the command */
- ac->ac_flags &= ~AMR_CMD_BUSY;
- ac->ac_complete(ac);
-
- /*
- * Is someone sleeping on this one?
- */
- } else {
- mtx_lock(&sc->amr_list_lock);
- ac->ac_flags &= ~AMR_CMD_BUSY;
- if (ac->ac_flags & AMR_CMD_SLEEP) {
- /* unbusy the command */
- wakeup(ac);
- }
- mtx_unlock(&sc->amr_list_lock);
- }
-
- if(!sc->amr_busyslots) {
- wakeup(sc);
- }
- }
-
- mtx_lock(&sc->amr_list_lock);
- sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
- amr_startio(sc);
- mtx_unlock(&sc->amr_list_lock);
-}
-
-/********************************************************************************
- ********************************************************************************
- Command Buffer Management
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Get a new command buffer.
- *
- * This may return NULL in low-memory cases.
- *
- * If possible, we recycle a command buffer that's been used before.
- */
-struct amr_command *
-amr_alloccmd(struct amr_softc *sc)
-{
- struct amr_command *ac;
-
- debug_called(3);
-
- ac = amr_dequeue_free(sc);
- if (ac == NULL) {
- sc->amr_state |= AMR_STATE_QUEUE_FRZN;
- return(NULL);
- }
-
- /* clear out significant fields */
- ac->ac_status = 0;
- bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox));
- ac->ac_flags = 0;
- ac->ac_bio = NULL;
- ac->ac_data = NULL;
- ac->ac_complete = NULL;
- ac->ac_retries = 0;
- ac->ac_tag = NULL;
- ac->ac_datamap = NULL;
- return(ac);
-}
-
-/********************************************************************************
- * Release a command buffer for recycling.
- */
-void
-amr_releasecmd(struct amr_command *ac)
-{
- debug_called(3);
-
- amr_enqueue_free(ac);
-}
-
-/********************************************************************************
- * Allocate a new command cluster and initialise it.
- */
-static void
-amr_alloccmd_cluster(struct amr_softc *sc)
-{
- struct amr_command_cluster *acc;
- struct amr_command *ac;
- int i, nextslot;
-
- /*
- * If we haven't found the real limit yet, let us have a couple of
- * commands in order to be able to probe.
- */
- if (sc->amr_maxio == 0)
- sc->amr_maxio = 2;
-
- if (sc->amr_nextslot > sc->amr_maxio)
- return;
- acc = malloc(AMR_CMD_CLUSTERSIZE, M_AMR, M_NOWAIT | M_ZERO);
- if (acc != NULL) {
- nextslot = sc->amr_nextslot;
- mtx_lock(&sc->amr_list_lock);
- TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link);
- mtx_unlock(&sc->amr_list_lock);
- for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
- ac = &acc->acc_command[i];
- ac->ac_sc = sc;
- ac->ac_slot = nextslot;
-
- /*
- * The SG table for each slot is a fixed size and is assumed to
- * to hold 64-bit s/g objects when the driver is configured to do
- * 64-bit DMA. 32-bit DMA commands still use the same table, but
- * cast down to 32-bit objects.
- */
- if (AMR_IS_SG64(sc)) {
- ac->ac_sgbusaddr = sc->amr_sgbusaddr +
- (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sg64entry));
- ac->ac_sg.sg64 = sc->amr_sg64table + (ac->ac_slot * AMR_NSEG);
- } else {
- ac->ac_sgbusaddr = sc->amr_sgbusaddr +
- (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
- ac->ac_sg.sg32 = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
- }
-
- ac->ac_ccb = sc->amr_ccb + ac->ac_slot;
- ac->ac_ccb_busaddr = sc->amr_ccb_busaddr +
- (ac->ac_slot * sizeof(union amr_ccb));
-
- if (bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap))
- break;
- if (AMR_IS_SG64(sc) &&
- (bus_dmamap_create(sc->amr_buffer64_dmat, 0,&ac->ac_dma64map)))
- break;
- amr_releasecmd(ac);
- if (++nextslot > sc->amr_maxio)
- break;
- }
- sc->amr_nextslot = nextslot;
- }
-}
-
-/********************************************************************************
- * Free a command cluster
- */
-static void
-amr_freecmd_cluster(struct amr_command_cluster *acc)
-{
- struct amr_softc *sc = acc->acc_command[0].ac_sc;
- int i;
-
- for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
- if (acc->acc_command[i].ac_sc == NULL)
- break;
- bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
- if (AMR_IS_SG64(sc))
- bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_dma64map);
- }
- free(acc, M_AMR);
-}
-
-/********************************************************************************
- ********************************************************************************
- Interface-specific Shims
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Tell the controller that the mailbox contains a valid command
- */
-static int
-amr_quartz_submit_command(struct amr_command *ac)
-{
- struct amr_softc *sc = ac->ac_sc;
- static struct timeval lastfail;
- static int curfail;
- int i = 0;
-
- mtx_lock(&sc->amr_hw_lock);
- while (sc->amr_mailbox->mb_busy && (i++ < 10)) {
- DELAY(1);
- /* This is a no-op read that flushes pending mailbox updates */
- AMR_QGET_ODB(sc);
- }
- if (sc->amr_mailbox->mb_busy) {
- mtx_unlock(&sc->amr_hw_lock);
- if (ac->ac_retries++ > 1000) {
- if (ppsratecheck(&lastfail, &curfail, 1))
- device_printf(sc->amr_dev, "Too many retries on command %p. "
- "Controller is likely dead\n", ac);
- ac->ac_retries = 0;
- }
- return (EBUSY);
- }
-
- /*
- * Save the slot number so that we can locate this command when complete.
- * Note that ident = 0 seems to be special, so we don't use it.
- */
- ac->ac_mailbox.mb_ident = ac->ac_slot + 1; /* will be coppied into mbox */
- bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, 14);
- sc->amr_mailbox->mb_busy = 1;
- sc->amr_mailbox->mb_poll = 0;
- sc->amr_mailbox->mb_ack = 0;
- sc->amr_mailbox64->sg64_hi = ac->ac_sg64_hi;
- sc->amr_mailbox64->sg64_lo = ac->ac_sg64_lo;
-
- AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
- mtx_unlock(&sc->amr_hw_lock);
- return(0);
-}
-
-static int
-amr_std_submit_command(struct amr_command *ac)
-{
- struct amr_softc *sc = ac->ac_sc;
- static struct timeval lastfail;
- static int curfail;
-
- mtx_lock(&sc->amr_hw_lock);
- if (AMR_SGET_MBSTAT(sc) & AMR_SMBOX_BUSYFLAG) {
- mtx_unlock(&sc->amr_hw_lock);
- if (ac->ac_retries++ > 1000) {
- if (ppsratecheck(&lastfail, &curfail, 1))
- device_printf(sc->amr_dev, "Too many retries on command %p. "
- "Controller is likely dead\n", ac);
- ac->ac_retries = 0;
- }
- return (EBUSY);
- }
-
- /*
- * Save the slot number so that we can locate this command when complete.
- * Note that ident = 0 seems to be special, so we don't use it.
- */
- ac->ac_mailbox.mb_ident = ac->ac_slot + 1; /* will be coppied into mbox */
- bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, 14);
- sc->amr_mailbox->mb_busy = 1;
- sc->amr_mailbox->mb_poll = 0;
- sc->amr_mailbox->mb_ack = 0;
-
- AMR_SPOST_COMMAND(sc);
- mtx_unlock(&sc->amr_hw_lock);
- return(0);
-}
-
-/********************************************************************************
- * Claim any work that the controller has completed; acknowledge completion,
- * save details of the completion in (mbsave)
- */
-static int
-amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
-{
- int worked, i;
- u_int32_t outd;
- u_int8_t nstatus;
- u_int8_t completed[46];
-
- debug_called(3);
-
- worked = 0;
-
- /* work waiting for us? */
- if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) {
- /* acknowledge interrupt */
- AMR_QPUT_ODB(sc, AMR_QODB_READY);
-
- while ((nstatus = sc->amr_mailbox->mb_nstatus) == 0xff)
- DELAY(1);
- sc->amr_mailbox->mb_nstatus = 0xff;
-
- /* wait until fw wrote out all completions */
- for (i = 0; i < nstatus; i++) {
- while ((completed[i] = sc->amr_mailbox->mb_completed[i]) == 0xff)
- DELAY(1);
- sc->amr_mailbox->mb_completed[i] = 0xff;
- }
-
- /* Save information for later processing */
- mbsave->mb_nstatus = nstatus;
- mbsave->mb_status = sc->amr_mailbox->mb_status;
- sc->amr_mailbox->mb_status = 0xff;
-
- for (i = 0; i < nstatus; i++)
- mbsave->mb_completed[i] = completed[i];
-
- /* acknowledge that we have the commands */
- AMR_QPUT_IDB(sc, AMR_QIDB_ACK);
-
-#if 0
-#ifndef AMR_QUARTZ_GOFASTER
- /*
- * This waits for the controller to notice that we've taken the
- * command from it. It's very inefficient, and we shouldn't do it,
- * but if we remove this code, we stop completing commands under
- * load.
- *
- * Peter J says we shouldn't do this. The documentation says we
- * should. Who is right?
- */
- while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
- ; /* XXX aiee! what if it dies? */
-#endif
-#endif
-
- worked = 1; /* got some work */
- }
-
- return(worked);
-}
-
-static int
-amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
-{
- int worked;
- u_int8_t istat;
-
- debug_called(3);
-
- worked = 0;
-
- /* check for valid interrupt status */
- istat = AMR_SGET_ISTAT(sc);
- if ((istat & AMR_SINTR_VALID) != 0) {
- AMR_SPUT_ISTAT(sc, istat); /* ack interrupt status */
-
- /* save mailbox, which contains a list of completed commands */
- bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
-
- AMR_SACK_INTERRUPT(sc); /* acknowledge we have the mailbox */
- worked = 1;
- }
-
- return(worked);
-}
-
-/********************************************************************************
- * Notify the controller of the mailbox location.
- */
-static void
-amr_std_attach_mailbox(struct amr_softc *sc)
-{
-
- /* program the mailbox physical address */
- AMR_SBYTE_SET(sc, AMR_SMBOX_0, sc->amr_mailboxphys & 0xff);
- AMR_SBYTE_SET(sc, AMR_SMBOX_1, (sc->amr_mailboxphys >> 8) & 0xff);
- AMR_SBYTE_SET(sc, AMR_SMBOX_2, (sc->amr_mailboxphys >> 16) & 0xff);
- AMR_SBYTE_SET(sc, AMR_SMBOX_3, (sc->amr_mailboxphys >> 24) & 0xff);
- AMR_SBYTE_SET(sc, AMR_SMBOX_ENABLE, AMR_SMBOX_ADDR);
-
- /* clear any outstanding interrupt and enable interrupts proper */
- AMR_SACK_INTERRUPT(sc);
- AMR_SENABLE_INTR(sc);
-}
-
-#ifdef AMR_BOARD_INIT
-/********************************************************************************
- * Initialise the controller
- */
-static int
-amr_quartz_init(struct amr_softc *sc)
-{
- int status, ostatus;
-
- device_printf(sc->amr_dev, "initial init status %x\n", AMR_QGET_INITSTATUS(sc));
-
- AMR_QRESET(sc);
-
- ostatus = 0xff;
- while ((status = AMR_QGET_INITSTATUS(sc)) != AMR_QINIT_DONE) {
- if (status != ostatus) {
- device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_qinit, status));
- ostatus = status;
- }
- switch (status) {
- case AMR_QINIT_NOMEM:
- return(ENOMEM);
-
- case AMR_QINIT_SCAN:
- /* XXX we could print channel/target here */
- break;
- }
- }
- return(0);
-}
-
-static int
-amr_std_init(struct amr_softc *sc)
-{
- int status, ostatus;
-
- device_printf(sc->amr_dev, "initial init status %x\n", AMR_SGET_INITSTATUS(sc));
-
- AMR_SRESET(sc);
-
- ostatus = 0xff;
- while ((status = AMR_SGET_INITSTATUS(sc)) != AMR_SINIT_DONE) {
- if (status != ostatus) {
- device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_sinit, status));
- ostatus = status;
- }
- switch (status) {
- case AMR_SINIT_NOMEM:
- return(ENOMEM);
-
- case AMR_SINIT_INPROG:
- /* XXX we could print channel/target here? */
- break;
- }
- }
- return(0);
-}
-#endif
-
-/********************************************************************************
- ********************************************************************************
- Debugging
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Identify the controller and print some information about it.
- */
-static void
-amr_describe_controller(struct amr_softc *sc)
-{
- struct amr_prodinfo *ap;
- struct amr_enquiry *ae;
- char *prod;
- int status;
-
- /*
- * Try to get 40LD product info, which tells us what the card is labelled as.
- */
- if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0, &status)) != NULL) {
- device_printf(sc->amr_dev, "<LSILogic %.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n",
- ap->ap_product, ap->ap_firmware, ap->ap_bios,
- ap->ap_memsize);
-
- free(ap, M_AMR);
- return;
- }
-
- /*
- * Try 8LD extended ENQUIRY to get controller signature, and use lookup table.
- */
- if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0, &status)) != NULL) {
- prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature);
-
- } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0, &status)) != NULL) {
- /*
- * Try to work it out based on the PCI signatures.
- */
- switch (pci_get_device(sc->amr_dev)) {
- case 0x9010:
- prod = "Series 428";
- break;
- case 0x9060:
- prod = "Series 434";
- break;
- default:
- prod = "unknown controller";
- break;
- }
- } else {
- device_printf(sc->amr_dev, "<unsupported controller>\n");
- return;
- }
-
- /*
- * HP NetRaid controllers have a special encoding of the firmware and
- * BIOS versions. The AMI version seems to have it as strings whereas
- * the HP version does it with a leading uppercase character and two
- * binary numbers.
- */
-
- if(ae->ae_adapter.aa_firmware[2] >= 'A' &&
- ae->ae_adapter.aa_firmware[2] <= 'Z' &&
- ae->ae_adapter.aa_firmware[1] < ' ' &&
- ae->ae_adapter.aa_firmware[0] < ' ' &&
- ae->ae_adapter.aa_bios[2] >= 'A' &&
- ae->ae_adapter.aa_bios[2] <= 'Z' &&
- ae->ae_adapter.aa_bios[1] < ' ' &&
- ae->ae_adapter.aa_bios[0] < ' ') {
- /* this looks like we have an HP NetRaid version of the MegaRaid */
-
- if(ae->ae_signature == AMR_SIG_438) {
- /* the AMI 438 is a NetRaid 3si in HP-land */
- prod = "HP NetRaid 3si";
- }
-
- device_printf(sc->amr_dev, "<%s> Firmware %c.%02d.%02d, BIOS %c.%02d.%02d, %dMB RAM\n",
- prod, ae->ae_adapter.aa_firmware[2],
- ae->ae_adapter.aa_firmware[1],
- ae->ae_adapter.aa_firmware[0],
- ae->ae_adapter.aa_bios[2],
- ae->ae_adapter.aa_bios[1],
- ae->ae_adapter.aa_bios[0],
- ae->ae_adapter.aa_memorysize);
- } else {
- device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n",
- prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios,
- ae->ae_adapter.aa_memorysize);
- }
- free(ae, M_AMR);
-}
-
-int
-amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks)
-{
- struct amr_command *ac;
- int error = EIO;
-
- debug_called(1);
-
- sc->amr_state |= AMR_STATE_INTEN;
-
- /* get ourselves a command buffer */
- if ((ac = amr_alloccmd(sc)) == NULL)
- goto out;
- /* set command flags */
- ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
-
- /* point the command at our data */
- ac->ac_data = data;
- ac->ac_length = blks * AMR_BLKSIZE;
-
- /* build the command proper */
- ac->ac_mailbox.mb_command = AMR_CMD_LWRITE;
- ac->ac_mailbox.mb_blkcount = blks;
- ac->ac_mailbox.mb_lba = lba;
- ac->ac_mailbox.mb_drive = unit;
-
- /* can't assume that interrupts are going to work here, so play it safe */
- if (sc->amr_poll_command(ac))
- goto out;
- error = ac->ac_status;
-
- out:
- if (ac != NULL)
- amr_releasecmd(ac);
-
- sc->amr_state &= ~AMR_STATE_INTEN;
- return (error);
-}
-
-#ifdef AMR_DEBUG
-/********************************************************************************
- * Print the command (ac) in human-readable format
- */
-#if 0
-static void
-amr_printcommand(struct amr_command *ac)
-{
- struct amr_softc *sc = ac->ac_sc;
- struct amr_sgentry *sg;
- int i;
-
- device_printf(sc->amr_dev, "cmd %x ident %d drive %d\n",
- ac->ac_mailbox.mb_command, ac->ac_mailbox.mb_ident, ac->ac_mailbox.mb_drive);
- device_printf(sc->amr_dev, "blkcount %d lba %d\n",
- ac->ac_mailbox.mb_blkcount, ac->ac_mailbox.mb_lba);
- device_printf(sc->amr_dev, "virtaddr %p length %lu\n", ac->ac_data, (unsigned long)ac->ac_length);
- device_printf(sc->amr_dev, "sg physaddr %08x nsg %d\n",
- ac->ac_mailbox.mb_physaddr, ac->ac_mailbox.mb_nsgelem);
- device_printf(sc->amr_dev, "ccb %p bio %p\n", ac->ac_ccb_data, ac->ac_bio);
-
- /* get base address of s/g table */
- sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
- for (i = 0; i < ac->ac_mailbox.mb_nsgelem; i++, sg++)
- device_printf(sc->amr_dev, " %x/%d\n", sg->sg_addr, sg->sg_count);
-}
-#endif
-#endif
diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c
deleted file mode 100644
index a8dd9def064a..000000000000
--- a/sys/dev/amr/amr_cam.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2000 Michael Smith
- * Copyright (c) 2000 BSDi
- * 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.
- */
-/*-
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/stat.h>
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_sim.h>
-#include <cam/cam_xpt.h>
-#include <cam/cam_xpt_sim.h>
-#include <cam/cam_debug.h>
-#include <cam/scsi/scsi_all.h>
-#include <cam/scsi/scsi_message.h>
-
-#include <machine/resource.h>
-#include <machine/bus.h>
-
-#include <dev/amr/amrreg.h>
-#include <dev/amr/amrvar.h>
-
-static int amr_cam_probe(device_t dev);
-static int amr_cam_attach(device_t dev);
-static int amr_cam_detach(device_t dev);
-static void amr_cam_action(struct cam_sim *sim, union ccb *ccb);
-static void amr_cam_poll(struct cam_sim *sim);
-static void amr_cam_complete(struct amr_command *ac);
-static int amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
-
-static devclass_t amr_pass_devclass;
-
-static device_method_t amr_pass_methods[] = {
- DEVMETHOD(device_probe, amr_cam_probe),
- DEVMETHOD(device_attach, amr_cam_attach),
- DEVMETHOD(device_detach, amr_cam_detach),
- { 0, 0 }
-};
-
-static driver_t amr_pass_driver = {
- "amrp",
- amr_pass_methods,
- 0
-};
-
-DRIVER_MODULE(amrp, amr, amr_pass_driver, amr_pass_devclass, 0, 0);
-MODULE_DEPEND(amrp, cam, 1, 1, 1);
-
-static MALLOC_DEFINE(M_AMRCAM, "amrcam", "AMR CAM memory");
-
-/***********************************************************************
- * Enqueue/dequeue functions
- */
-static __inline void
-amr_enqueue_ccb(struct amr_softc *sc, union ccb *ccb)
-{
-
- TAILQ_INSERT_TAIL(&sc->amr_cam_ccbq, &ccb->ccb_h, sim_links.tqe);
-}
-
-static __inline void
-amr_requeue_ccb(struct amr_softc *sc, union ccb *ccb)
-{
-
- TAILQ_INSERT_HEAD(&sc->amr_cam_ccbq, &ccb->ccb_h, sim_links.tqe);
-}
-
-static __inline union ccb *
-amr_dequeue_ccb(struct amr_softc *sc)
-{
- union ccb *ccb;
-
- if ((ccb = (union ccb *)TAILQ_FIRST(&sc->amr_cam_ccbq)) != NULL)
- TAILQ_REMOVE(&sc->amr_cam_ccbq, &ccb->ccb_h, sim_links.tqe);
- return(ccb);
-}
-
-static int
-amr_cam_probe(device_t dev)
-{
- return (0);
-}
-
-/********************************************************************************
- * Attach our 'real' SCSI channels to CAM
- */
-static int
-amr_cam_attach(device_t dev)
-{
- struct amr_softc *sc;
- struct cam_devq *devq;
- int chn, error;
-
- sc = device_get_softc(dev);
-
- /* initialise the ccb queue */
- TAILQ_INIT(&sc->amr_cam_ccbq);
-
- /*
- * Allocate a devq for all our channels combined. This should
- * allow for the maximum number of SCSI commands we will accept
- * at one time. Save the pointer in the softc so we can find it later
- * during detach.
- */
- if ((devq = cam_simq_alloc(AMR_MAX_SCSI_CMDS)) == NULL)
- return(ENOMEM);
- sc->amr_cam_devq = devq;
-
- /*
- * Iterate over our channels, registering them with CAM
- */
- for (chn = 0; chn < sc->amr_maxchan; chn++) {
- /* allocate a sim */
- if ((sc->amr_cam_sim[chn] = cam_sim_alloc(amr_cam_action,
- amr_cam_poll, "amr", sc, device_get_unit(sc->amr_dev),
- &sc->amr_list_lock, 1, AMR_MAX_SCSI_CMDS, devq)) == NULL) {
- cam_simq_free(devq);
- device_printf(sc->amr_dev, "CAM SIM attach failed\n");
- return(ENOMEM);
- }
-
- /* register the bus ID so we can get it later */
- mtx_lock(&sc->amr_list_lock);
- error = xpt_bus_register(sc->amr_cam_sim[chn], sc->amr_dev,chn);
- mtx_unlock(&sc->amr_list_lock);
- if (error) {
- device_printf(sc->amr_dev,
- "CAM XPT bus registration failed\n");
- return(ENXIO);
- }
- }
- /*
- * XXX we should scan the config and work out which devices are
- * actually protected.
- */
- sc->amr_cam_command = amr_cam_command;
- return(0);
-}
-
-/********************************************************************************
- * Disconnect ourselves from CAM
- */
-static int
-amr_cam_detach(device_t dev)
-{
- struct amr_softc *sc;
- int chn;
-
- sc = device_get_softc(dev);
- mtx_lock(&sc->amr_list_lock);
- for (chn = 0; chn < sc->amr_maxchan; chn++) {
- /*
- * If a sim was allocated for this channel, free it
- */
- if (sc->amr_cam_sim[chn] != NULL) {
- xpt_bus_deregister(cam_sim_path(sc->amr_cam_sim[chn]));
- cam_sim_free(sc->amr_cam_sim[chn], FALSE);
- }
- }
- mtx_unlock(&sc->amr_list_lock);
-
- /* Now free the devq */
- if (sc->amr_cam_devq != NULL)
- cam_simq_free(sc->amr_cam_devq);
-
- return (0);
-}
-
-/***********************************************************************
- ***********************************************************************
- CAM passthrough interface
- ***********************************************************************
- ***********************************************************************/
-
-/***********************************************************************
- * Handle a request for action from CAM
- */
-static void
-amr_cam_action(struct cam_sim *sim, union ccb *ccb)
-{
- struct amr_softc *sc = cam_sim_softc(sim);
-
- switch(ccb->ccb_h.func_code) {
- /*
- * Perform SCSI I/O to a physical device.
- */
- case XPT_SCSI_IO:
- {
- struct ccb_hdr *ccbh = &ccb->ccb_h;
- struct ccb_scsiio *csio = &ccb->csio;
-
- /* Validate the CCB */
- ccbh->status = CAM_REQ_INPROG;
-
- /* check the CDB length */
- if (csio->cdb_len > AMR_MAX_EXTCDB_LEN)
- ccbh->status = CAM_REQ_INVALID;
-
- if ((csio->cdb_len > AMR_MAX_CDB_LEN) &&
- (sc->support_ext_cdb == 0))
- ccbh->status = CAM_REQ_INVALID;
-
- /* check that the CDB pointer is not to a physical address */
- if ((ccbh->flags & CAM_CDB_POINTER) &&
- (ccbh->flags & CAM_CDB_PHYS))
- ccbh->status = CAM_REQ_INVALID;
- /*
- * if there is data transfer, it must be to/from a virtual
- * address
- */
- if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
- if ((ccbh->flags & CAM_DATA_MASK) != CAM_DATA_VADDR)
- /* we can't map it */
- ccbh->status = CAM_REQ_INVALID;
- }
-
- /*
- * If the command is to a LUN other than 0, fail it.
- * This is probably incorrect, but during testing the
- * firmware did not seem to respect the LUN field, and thus
- * devices appear echoed.
- */
- if (csio->ccb_h.target_lun != 0)
- ccbh->status = CAM_DEV_NOT_THERE;
-
- /* if we're happy with the request, queue it for attention */
- if (ccbh->status == CAM_REQ_INPROG) {
- /* save the channel number in the ccb */
- csio->ccb_h.sim_priv.entries[0].field= cam_sim_bus(sim);
-
- amr_enqueue_ccb(sc, ccb);
- amr_startio(sc);
- return;
- }
- break;
- }
-
- case XPT_CALC_GEOMETRY:
- {
- cam_calc_geometry(&ccb->ccg, /*extended*/1);
- break;
- }
-
- /*
- * Return path stats. Some of these should probably be amended.
- */
- case XPT_PATH_INQ:
- {
- struct ccb_pathinq *cpi = & ccb->cpi;
-
- debug(3, "XPT_PATH_INQ");
- cpi->version_num = 1; /* XXX??? */
- cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
- cpi->target_sprt = 0;
- cpi->hba_misc = PIM_NOBUSRESET|PIM_SEQSCAN;
- cpi->hba_eng_cnt = 0;
- cpi->max_target = AMR_MAX_TARGETS;
- cpi->max_lun = 0 /* AMR_MAX_LUNS*/;
- cpi->initiator_id = 7; /* XXX variable? */
- strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strlcpy(cpi->hba_vid, "LSI", HBA_IDLEN);
- strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
- cpi->unit_number = cam_sim_unit(sim);
- cpi->bus_id = cam_sim_bus(sim);
- cpi->base_transfer_speed = 132 * 1024; /* XXX */
- cpi->transport = XPORT_SPI;
- cpi->transport_version = 2;
- cpi->protocol = PROTO_SCSI;
- cpi->protocol_version = SCSI_REV_2;
- cpi->ccb_h.status = CAM_REQ_CMP;
-
- break;
- }
-
- case XPT_RESET_BUS:
- {
- struct ccb_pathinq *cpi = & ccb->cpi;
-
- debug(1, "XPT_RESET_BUS");
- cpi->ccb_h.status = CAM_REQ_CMP;
- break;
- }
-
- case XPT_RESET_DEV:
- {
- debug(1, "XPT_RESET_DEV");
- ccb->ccb_h.status = CAM_REQ_CMP;
- break;
- }
-
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &(ccb->cts);
-
- debug(3, "XPT_GET_TRAN_SETTINGS");
-
- struct ccb_trans_settings_scsi *scsi;
- struct ccb_trans_settings_spi *spi;
-
- 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_USER_SETTINGS) {
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- break;
- }
-
- spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- spi->bus_width = MSG_EXT_WDTR_BUS_32_BIT;
- spi->sync_period = 6; /* 40MHz how wide is this bus? */
- spi->sync_offset = 31; /* How to extract this from board? */
-
- spi->valid = CTS_SPI_VALID_SYNC_RATE
- | CTS_SPI_VALID_SYNC_OFFSET
- | CTS_SPI_VALID_BUS_WIDTH
- | CTS_SPI_VALID_DISC;
- scsi->valid = CTS_SCSI_VALID_TQ;
- ccb->ccb_h.status = CAM_REQ_CMP;
- break;
- }
-
- case XPT_SET_TRAN_SETTINGS:
- debug(3, "XPT_SET_TRAN_SETTINGS");
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- break;
-
- /*
- * Reject anything else as unsupported.
- */
- default:
- /* we can't do this */
- ccb->ccb_h.status = CAM_REQ_INVALID;
- break;
- }
-
- mtx_assert(&sc->amr_list_lock, MA_OWNED);
- xpt_done(ccb);
-}
-
-/***********************************************************************
- * Convert a CAM CCB off the top of the CCB queue to a passthrough SCSI
- * command.
- */
-static int
-amr_cam_command(struct amr_softc *sc, struct amr_command **acp)
-{
- struct amr_command *ac;
- struct amr_passthrough *ap;
- struct amr_ext_passthrough *aep;
- struct ccb_scsiio *csio;
- int bus, target, error;
-
- error = 0;
- ac = NULL;
- ap = NULL;
- aep = NULL;
-
- /* check to see if there is a ccb for us to work with */
- if ((csio = (struct ccb_scsiio *)amr_dequeue_ccb(sc)) == NULL)
- goto out;
-
- /* get bus/target, XXX validate against protected devices? */
- bus = csio->ccb_h.sim_priv.entries[0].field;
- target = csio->ccb_h.target_id;
-
- /*
- * Build a passthrough command.
- */
-
- /* construct command */
- if ((ac = amr_alloccmd(sc)) == NULL) {
- error = ENOMEM;
- goto out;
- }
-
- /* construct passthrough */
- if (sc->support_ext_cdb ) {
- aep = &ac->ac_ccb->ccb_epthru;
- aep->ap_timeout = 2;
- aep->ap_ars = 1;
- aep->ap_request_sense_length = 14;
- aep->ap_islogical = 0;
- aep->ap_channel = bus;
- aep->ap_scsi_id = target;
- aep->ap_logical_drive_no = csio->ccb_h.target_lun;
- aep->ap_cdb_length = csio->cdb_len;
- aep->ap_data_transfer_length = csio->dxfer_len;
- if (csio->ccb_h.flags & CAM_CDB_POINTER) {
- bcopy(csio->cdb_io.cdb_ptr, aep->ap_cdb, csio->cdb_len);
- } else {
- bcopy(csio->cdb_io.cdb_bytes, aep->ap_cdb,
- csio->cdb_len);
- }
- /*
- * we leave the data s/g list and s/g count to the map routine
- * later
- */
-
- debug(2, " COMMAND %x/%d+%d to %d:%d:%d", aep->ap_cdb[0],
- aep->ap_cdb_length, csio->dxfer_len, aep->ap_channel,
- aep->ap_scsi_id, aep->ap_logical_drive_no);
-
- } else {
- ap = &ac->ac_ccb->ccb_pthru;
- ap->ap_timeout = 0;
- ap->ap_ars = 1;
- ap->ap_request_sense_length = 14;
- ap->ap_islogical = 0;
- ap->ap_channel = bus;
- ap->ap_scsi_id = target;
- ap->ap_logical_drive_no = csio->ccb_h.target_lun;
- ap->ap_cdb_length = csio->cdb_len;
- ap->ap_data_transfer_length = csio->dxfer_len;
- if (csio->ccb_h.flags & CAM_CDB_POINTER) {
- bcopy(csio->cdb_io.cdb_ptr, ap->ap_cdb, csio->cdb_len);
- } else {
- bcopy(csio->cdb_io.cdb_bytes, ap->ap_cdb,
- csio->cdb_len);
- }
- /*
- * we leave the data s/g list and s/g count to the map routine
- * later
- */
-
- debug(2, " COMMAND %x/%d+%d to %d:%d:%d", ap->ap_cdb[0],
- ap->ap_cdb_length, csio->dxfer_len, ap->ap_channel,
- ap->ap_scsi_id, ap->ap_logical_drive_no);
- }
-
- ac->ac_flags |= AMR_CMD_CCB;
-
- ac->ac_data = csio->data_ptr;
- ac->ac_length = csio->dxfer_len;
- if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
- ac->ac_flags |= AMR_CMD_DATAIN;
- if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
- ac->ac_flags |= AMR_CMD_DATAOUT;
-
- ac->ac_private = csio;
- ac->ac_complete = amr_cam_complete;
- if ( sc->support_ext_cdb ) {
- ac->ac_mailbox.mb_command = AMR_CMD_EXTPASS;
- } else {
- ac->ac_mailbox.mb_command = AMR_CMD_PASS;
- }
-
-out:
- if (error != 0) {
- if (ac != NULL)
- amr_releasecmd(ac);
- if (csio != NULL)
- /* put it back and try again later */
- amr_requeue_ccb(sc, (union ccb *)csio);
- }
- *acp = ac;
- return(error);
-}
-
-/***********************************************************************
- * Check for interrupt status
- */
-static void
-amr_cam_poll(struct cam_sim *sim)
-{
-
- amr_done(cam_sim_softc(sim));
-}
-
- /**********************************************************************
- * Handle completion of a command submitted via CAM.
- */
-static void
-amr_cam_complete(struct amr_command *ac)
-{
- struct amr_passthrough *ap;
- struct amr_ext_passthrough *aep;
- struct ccb_scsiio *csio;
- struct scsi_inquiry_data *inq;
- int scsi_status, cdb0;
-
- ap = &ac->ac_ccb->ccb_pthru;
- aep = &ac->ac_ccb->ccb_epthru;
- csio = (struct ccb_scsiio *)ac->ac_private;
- inq = (struct scsi_inquiry_data *)csio->data_ptr;
-
- if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
- scsi_status = aep->ap_scsi_status;
- else
- scsi_status = ap->ap_scsi_status;
- debug(1, "status 0x%x AP scsi_status 0x%x", ac->ac_status,
- scsi_status);
-
- /* Make sure the status is sane */
- if ((ac->ac_status != AMR_STATUS_SUCCESS) && (scsi_status == 0)) {
- csio->ccb_h.status = CAM_REQ_CMP_ERR;
- goto out;
- }
-
- /*
- * Hide disks from CAM so that they're not picked up and treated as
- * 'normal' disks.
- *
- * If the configuration provides a mechanism to mark a disk a "not
- * managed", we could add handling for that to allow disks to be
- * selectively visible.
- */
-
- /* handle passthrough SCSI status */
- switch(scsi_status) {
- case 0: /* completed OK */
- if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
- cdb0 = aep->ap_cdb[0];
- else
- cdb0 = ap->ap_cdb[0];
- if ((cdb0 == INQUIRY) && (SID_TYPE(inq) == T_DIRECT))
- inq->device = (inq->device & 0xe0) | T_NODEVICE;
- csio->ccb_h.status = CAM_REQ_CMP;
- break;
-
- case 0x02:
- csio->ccb_h.status = CAM_SCSI_STATUS_ERROR;
- csio->scsi_status = SCSI_STATUS_CHECK_COND;
- if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
- bcopy(aep->ap_request_sense_area, &csio->sense_data,
- AMR_MAX_REQ_SENSE_LEN);
- else
- bcopy(ap->ap_request_sense_area, &csio->sense_data,
- AMR_MAX_REQ_SENSE_LEN);
- csio->sense_len = AMR_MAX_REQ_SENSE_LEN;
- csio->ccb_h.status |= CAM_AUTOSNS_VALID;
- break;
-
- case 0x08:
- csio->ccb_h.status = CAM_SCSI_BUSY;
- break;
-
- case 0xf0:
- case 0xf4:
- default:
- /*
- * Non-zero LUNs are already filtered, so there's no need
- * to return CAM_DEV_NOT_THERE.
- */
- csio->ccb_h.status = CAM_SEL_TIMEOUT;
- break;
- }
-
-out:
- if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
- debug(2, "%*D\n", imin(csio->dxfer_len, 16), csio->data_ptr,
- " ");
-
- mtx_lock(&ac->ac_sc->amr_list_lock);
- xpt_done((union ccb *)csio);
- amr_releasecmd(ac);
- mtx_unlock(&ac->ac_sc->amr_list_lock);
-}
diff --git a/sys/dev/amr/amr_disk.c b/sys/dev/amr/amr_disk.c
deleted file mode 100644
index 4eee088345f8..000000000000
--- a/sys/dev/amr/amr_disk.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 1999 Jonathan Lemon
- * Copyright (c) 1999, 2000 Michael Smith
- * Copyright (c) 2000 BSDi
- * 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.
- */
-/*-
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Disk driver for AMI MegaRaid controllers
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-
-#include <machine/bus.h>
-#include <sys/rman.h>
-
-#include <dev/amr/amrio.h>
-#include <dev/amr/amrreg.h>
-#include <dev/amr/amrvar.h>
-#include <dev/amr/amr_tables.h>
-
-/* prototypes */
-static int amrd_probe(device_t dev);
-static int amrd_attach(device_t dev);
-static int amrd_detach(device_t dev);
-
-static disk_open_t amrd_open;
-static disk_strategy_t amrd_strategy;
-
-static devclass_t amrd_devclass;
-#ifdef FREEBSD_4
-int amr_disks_registered = 0;
-#endif
-
-static device_method_t amrd_methods[] = {
- DEVMETHOD(device_probe, amrd_probe),
- DEVMETHOD(device_attach, amrd_attach),
- DEVMETHOD(device_detach, amrd_detach),
- { 0, 0 }
-};
-
-static driver_t amrd_driver = {
- "amrd",
- amrd_methods,
- sizeof(struct amrd_softc)
-};
-
-DRIVER_MODULE(amrd, amr, amrd_driver, amrd_devclass, 0, 0);
-
-static int
-amrd_open(struct disk *dp)
-{
- struct amrd_softc *sc = (struct amrd_softc *)dp->d_drv1;
-
- debug_called(1);
-
- if (sc == NULL)
- return (ENXIO);
-
- /* controller not active? */
- if (sc->amrd_controller->amr_state & AMR_STATE_SHUTDOWN)
- return(ENXIO);
-
- return (0);
-}
-/********************************************************************************
- * System crashdump support
- */
-
-static int
-amrd_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
-{
-
- struct amrd_softc *amrd_sc;
- struct amr_softc *amr_sc;
- int error;
- struct disk *dp;
-
- dp = arg;
- amrd_sc = (struct amrd_softc *)dp->d_drv1;
- if (amrd_sc == NULL)
- return(ENXIO);
- amr_sc = (struct amr_softc *)amrd_sc->amrd_controller;
-
- if (length > 0) {
- int driveno = amrd_sc->amrd_drive - amr_sc->amr_drive;
- if ((error = amr_dump_blocks(amr_sc,driveno,offset / AMR_BLKSIZE ,(void *)virtual,(int) length / AMR_BLKSIZE )) != 0)
- return(error);
- }
- return(0);
-}
-
-/*
- * Read/write routine for a buffer. Finds the proper unit, range checks
- * arguments, and schedules the transfer. Does not wait for the transfer
- * to complete. Multi-page transfers are supported. All I/O requests must
- * be a multiple of a sector in length.
- */
-static void
-amrd_strategy(struct bio *bio)
-{
- struct amrd_softc *sc = (struct amrd_softc *)bio->bio_disk->d_drv1;
-
- /* bogus disk? */
- if (sc == NULL) {
- bio->bio_error = EINVAL;
- goto bad;
- }
-
- amr_submit_bio(sc->amrd_controller, bio);
- return;
-
- bad:
- bio->bio_flags |= BIO_ERROR;
-
- /*
- * Correctly set the buf to indicate a completed transfer
- */
- bio->bio_resid = bio->bio_bcount;
- biodone(bio);
- return;
-}
-
-void
-amrd_intr(void *data)
-{
- struct bio *bio = (struct bio *)data;
-
- debug_called(2);
-
- if (bio->bio_flags & BIO_ERROR) {
- bio->bio_error = EIO;
- debug(1, "i/o error\n");
- } else {
- bio->bio_resid = 0;
- }
-
- biodone(bio);
-}
-
-static int
-amrd_probe(device_t dev)
-{
-
- debug_called(1);
-
- device_set_desc(dev, "LSILogic MegaRAID logical drive");
- return (0);
-}
-
-static int
-amrd_attach(device_t dev)
-{
- struct amrd_softc *sc = (struct amrd_softc *)device_get_softc(dev);
- device_t parent;
-
- debug_called(1);
-
- parent = device_get_parent(dev);
- sc->amrd_controller = (struct amr_softc *)device_get_softc(parent);
- sc->amrd_unit = device_get_unit(dev);
- sc->amrd_drive = device_get_ivars(dev);
- sc->amrd_dev = dev;
-
- device_printf(dev, "%uMB (%u sectors) RAID %d (%s)\n",
- sc->amrd_drive->al_size / ((1024 * 1024) / AMR_BLKSIZE),
- sc->amrd_drive->al_size, sc->amrd_drive->al_properties & AMR_DRV_RAID_MASK,
- amr_describe_code(amr_table_drvstate, AMR_DRV_CURSTATE(sc->amrd_drive->al_state)));
-
- sc->amrd_disk = disk_alloc();
- sc->amrd_disk->d_drv1 = sc;
- sc->amrd_disk->d_maxsize = (AMR_NSEG - 1) * PAGE_SIZE;
- sc->amrd_disk->d_open = amrd_open;
- sc->amrd_disk->d_strategy = amrd_strategy;
- sc->amrd_disk->d_name = "amrd";
- sc->amrd_disk->d_dump = (dumper_t *)amrd_dump;
- sc->amrd_disk->d_unit = sc->amrd_unit;
- sc->amrd_disk->d_flags = DISKFLAG_CANFLUSHCACHE;
- sc->amrd_disk->d_sectorsize = AMR_BLKSIZE;
- sc->amrd_disk->d_mediasize = (off_t)sc->amrd_drive->al_size * AMR_BLKSIZE;
- sc->amrd_disk->d_fwsectors = sc->amrd_drive->al_sectors;
- sc->amrd_disk->d_fwheads = sc->amrd_drive->al_heads;
- disk_create(sc->amrd_disk, DISK_VERSION);
-
- return (0);
-}
-
-static int
-amrd_detach(device_t dev)
-{
- struct amrd_softc *sc = (struct amrd_softc *)device_get_softc(dev);
-
- debug_called(1);
-
- if (sc->amrd_disk->d_flags & DISKFLAG_OPEN)
- return(EBUSY);
-
-#ifdef FREEBSD_4
- if (--amr_disks_registered == 0)
- cdevsw_remove(&amrddisk_cdevsw);
-#else
- disk_destroy(sc->amrd_disk);
-#endif
- return(0);
-}
diff --git a/sys/dev/amr/amr_linux.c b/sys/dev/amr/amr_linux.c
deleted file mode 100644
index 9e0a5cac693e..000000000000
--- a/sys/dev/amr/amr_linux.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2005 Paul Saab
- * 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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/capsicum.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/file.h>
-#include <sys/proc.h>
-
-#if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */
-#include <machine/../linux32/linux.h>
-#include <machine/../linux32/linux32_proto.h>
-#else
-#include <machine/../linux/linux.h>
-#include <machine/../linux/linux_proto.h>
-#endif
-#include <compat/linux/linux_ioctl.h>
-
-/* There are multiple ioctl number ranges that need to be handled */
-#define AMR_LINUX_IOCTL_MIN 0x6d00
-#define AMR_LINUX_IOCTL_MAX 0x6d01
-
-static linux_ioctl_function_t amr_linux_ioctl;
-static struct linux_ioctl_handler amr_linux_handler = {amr_linux_ioctl,
- AMR_LINUX_IOCTL_MIN,
- AMR_LINUX_IOCTL_MAX};
-
-SYSINIT (amr_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_register_handler, &amr_linux_handler);
-SYSUNINIT(amr_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_unregister_handler, &amr_linux_handler);
-
-static int
-amr_linux_modevent(module_t mod, int cmd, void *data)
-{
- return (0);
-}
-
-DEV_MODULE(amr_linux, amr_linux_modevent, NULL);
-MODULE_DEPEND(amr, linux, 1, 1, 1);
-
-static int
-amr_linux_ioctl(struct thread *p, struct linux_ioctl_args *args)
-{
- cap_rights_t rights;
- struct file *fp;
- int error;
-
- error = fget(p, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), &fp);
- if (error != 0)
- return (error);
- error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p);
- fdrop(fp, p);
- return (error);
-}
diff --git a/sys/dev/amr/amr_pci.c b/sys/dev/amr/amr_pci.c
deleted file mode 100644
index dd7128e372ef..000000000000
--- a/sys/dev/amr/amr_pci.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*-
- * Copyright (c) 1999,2000 Michael Smith
- * Copyright (c) 2000 BSDi
- * 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.
- */
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002, 2004 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-#include <dev/amr/amrio.h>
-#include <dev/amr/amrreg.h>
-#include <dev/amr/amrvar.h>
-
-static int amr_pci_probe(device_t dev);
-static int amr_pci_attach(device_t dev);
-static int amr_pci_detach(device_t dev);
-static int amr_pci_shutdown(device_t dev);
-static int amr_pci_suspend(device_t dev);
-static int amr_pci_resume(device_t dev);
-static void amr_pci_intr(void *arg);
-static void amr_pci_free(struct amr_softc *sc);
-static void amr_sglist_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
-static int amr_sglist_map(struct amr_softc *sc);
-static int amr_setup_mbox(struct amr_softc *sc);
-static int amr_ccb_map(struct amr_softc *sc);
-
-static u_int amr_force_sg32 = 0;
-SYSCTL_DECL(_hw_amr);
-SYSCTL_UINT(_hw_amr, OID_AUTO, force_sg32, CTLFLAG_RDTUN, &amr_force_sg32, 0,
- "Force the AMR driver to use 32bit scatter gather");
-
-static device_method_t amr_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, amr_pci_probe),
- DEVMETHOD(device_attach, amr_pci_attach),
- DEVMETHOD(device_detach, amr_pci_detach),
- DEVMETHOD(device_shutdown, amr_pci_shutdown),
- DEVMETHOD(device_suspend, amr_pci_suspend),
- DEVMETHOD(device_resume, amr_pci_resume),
-
- DEVMETHOD_END
-};
-
-static driver_t amr_pci_driver = {
- "amr",
- amr_methods,
- sizeof(struct amr_softc)
-};
-
-static struct amr_ident
-{
- uint16_t vendor;
- uint16_t device;
- int flags;
-#define AMR_ID_PROBE_SIG (1<<0) /* generic i960RD, check signature */
-#define AMR_ID_DO_SG64 (1<<1)
-#define AMR_ID_QUARTZ (1<<2)
-} amr_device_ids[] = {
- {0x101e, 0x9010, 0},
- {0x101e, 0x9060, 0},
- {0x8086, 0x1960, AMR_ID_QUARTZ | AMR_ID_PROBE_SIG},
- {0x101e, 0x1960, AMR_ID_QUARTZ},
- {0x1000, 0x1960, AMR_ID_QUARTZ | AMR_ID_DO_SG64 | AMR_ID_PROBE_SIG},
- {0x1000, 0x0407, AMR_ID_QUARTZ | AMR_ID_DO_SG64},
- {0x1000, 0x0408, AMR_ID_QUARTZ | AMR_ID_DO_SG64},
- {0x1000, 0x0409, AMR_ID_QUARTZ | AMR_ID_DO_SG64},
- {0x1028, 0x000e, AMR_ID_QUARTZ | AMR_ID_DO_SG64 | AMR_ID_PROBE_SIG}, /* perc4/di i960 */
- {0x1028, 0x000f, AMR_ID_QUARTZ | AMR_ID_DO_SG64}, /* perc4/di Verde*/
- {0x1028, 0x0013, AMR_ID_QUARTZ | AMR_ID_DO_SG64}, /* perc4/di */
- {0, 0, 0}
-};
-
-static devclass_t amr_devclass;
-DRIVER_MODULE(amr, pci, amr_pci_driver, amr_devclass, 0, 0);
-MODULE_PNP_INFO("U16:vendor;U16:device", pci, amr, amr_device_ids,
- nitems(amr_device_ids) - 1);
-MODULE_DEPEND(amr, pci, 1, 1, 1);
-MODULE_DEPEND(amr, cam, 1, 1, 1);
-
-static struct amr_ident *
-amr_find_ident(device_t dev)
-{
- struct amr_ident *id;
- int sig;
-
- for (id = amr_device_ids; id->vendor != 0; id++) {
- if ((pci_get_vendor(dev) == id->vendor) &&
- (pci_get_device(dev) == id->device)) {
- /* do we need to test for a signature? */
- if (id->flags & AMR_ID_PROBE_SIG) {
- sig = pci_read_config(dev, AMR_CFG_SIG, 2);
- if ((sig != AMR_SIGNATURE_1) && (sig != AMR_SIGNATURE_2))
- continue;
- }
- return (id);
- }
- }
- return (NULL);
-}
-
-static int
-amr_pci_probe(device_t dev)
-{
-
- debug_called(1);
-
- if (amr_find_ident(dev) != NULL) {
- device_set_desc(dev, LSI_DESC_PCI);
- return(BUS_PROBE_DEFAULT);
- }
- return(ENXIO);
-}
-
-static int
-amr_pci_attach(device_t dev)
-{
- struct amr_softc *sc;
- struct amr_ident *id;
- int rid, rtype, error;
-
- debug_called(1);
-
- /*
- * Initialise softc.
- */
- sc = device_get_softc(dev);
- bzero(sc, sizeof(*sc));
- sc->amr_dev = dev;
-
- /* assume failure is 'not configured' */
- error = ENXIO;
-
- /*
- * Determine board type.
- */
- if ((id = amr_find_ident(dev)) == NULL)
- return (ENXIO);
-
- if (id->flags & AMR_ID_QUARTZ) {
- sc->amr_type |= AMR_TYPE_QUARTZ;
- }
-
- if ((amr_force_sg32 == 0) && (id->flags & AMR_ID_DO_SG64) &&
- (sizeof(vm_paddr_t) > 4)) {
- device_printf(dev, "Using 64-bit DMA\n");
- sc->amr_type |= AMR_TYPE_SG64;
- }
-
- /* force the busmaster enable bit on */
- pci_enable_busmaster(dev);
-
- /*
- * Allocate the PCI register window.
- */
- rid = PCIR_BAR(0);
- rtype = AMR_IS_QUARTZ(sc) ? SYS_RES_MEMORY : SYS_RES_IOPORT;
- sc->amr_reg = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE);
- if (sc->amr_reg == NULL) {
- device_printf(sc->amr_dev, "can't allocate register window\n");
- goto out;
- }
- sc->amr_btag = rman_get_bustag(sc->amr_reg);
- sc->amr_bhandle = rman_get_bushandle(sc->amr_reg);
-
- /*
- * Allocate and connect our interrupt.
- */
- rid = 0;
- sc->amr_irq = bus_alloc_resource_any(sc->amr_dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->amr_irq == NULL) {
- device_printf(sc->amr_dev, "can't allocate interrupt\n");
- goto out;
- }
- if (bus_setup_intr(sc->amr_dev, sc->amr_irq,
- INTR_TYPE_BIO | INTR_ENTROPY | INTR_MPSAFE, NULL, amr_pci_intr,
- sc, &sc->amr_intr)) {
- device_printf(sc->amr_dev, "can't set up interrupt\n");
- goto out;
- }
-
- debug(2, "interrupt attached");
-
- /* assume failure is 'out of memory' */
- error = ENOMEM;
-
- /*
- * Allocate the parent bus DMA tag appropriate for PCI.
- */
- if (bus_dma_tag_create(bus_get_dma_tag(dev), /* PCI parent */
- 1, 0, /* alignment,boundary */
- AMR_IS_SG64(sc) ?
- BUS_SPACE_MAXADDR :
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- BUS_SPACE_MAXSIZE, /* maxsize */
- BUS_SPACE_UNRESTRICTED, /* nsegments */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->amr_parent_dmat)) {
- device_printf(dev, "can't allocate parent DMA tag\n");
- goto out;
- }
-
- /*
- * Create DMA tag for mapping buffers into controller-addressable space.
- */
- if (bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
- 1, 0, /* alignment,boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- DFLTPHYS, /* maxsize */
- AMR_NSEG, /* nsegments */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
- busdma_lock_mutex, /* lockfunc */
- &sc->amr_list_lock, /* lockarg */
- &sc->amr_buffer_dmat)) {
- device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
- goto out;
- }
-
- if (bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
- 1, 0, /* alignment,boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- DFLTPHYS, /* maxsize */
- AMR_NSEG, /* nsegments */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
- busdma_lock_mutex, /* lockfunc */
- &sc->amr_list_lock, /* lockarg */
- &sc->amr_buffer64_dmat)) {
- device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
- goto out;
- }
-
- debug(2, "dma tag done");
-
- /*
- * Allocate and set up mailbox in a bus-visible fashion.
- */
- mtx_init(&sc->amr_list_lock, "AMR List Lock", NULL, MTX_DEF);
- mtx_init(&sc->amr_hw_lock, "AMR HW Lock", NULL, MTX_DEF);
- if ((error = amr_setup_mbox(sc)) != 0)
- goto out;
-
- debug(2, "mailbox setup");
-
- /*
- * Build the scatter/gather buffers.
- */
- if ((error = amr_sglist_map(sc)) != 0)
- goto out;
- debug(2, "s/g list mapped");
-
- if ((error = amr_ccb_map(sc)) != 0)
- goto out;
- debug(2, "ccb mapped");
-
- /*
- * Do bus-independant initialisation, bring controller online.
- */
- error = amr_attach(sc);
-
-out:
- if (error)
- amr_pci_free(sc);
- else
- gone_in_dev(dev, 13, "amr(4) driver");
- return(error);
-}
-
-/********************************************************************************
- * Disconnect from the controller completely, in preparation for unload.
- */
-static int
-amr_pci_detach(device_t dev)
-{
- struct amr_softc *sc = device_get_softc(dev);
- int error;
-
- debug_called(1);
-
- if (sc->amr_state & AMR_STATE_OPEN)
- return(EBUSY);
-
- if ((error = amr_pci_shutdown(dev)))
- return(error);
-
- amr_pci_free(sc);
-
- return(0);
-}
-
-/********************************************************************************
- * Bring the controller down to a dormant state and detach all child devices.
- *
- * This function is called before detach, system shutdown, or before performing
- * an operation which may add or delete system disks. (Call amr_startup to
- * resume normal operation.)
- *
- * Note that we can assume that the bioq on the controller is empty, as we won't
- * allow shutdown if any device is open.
- */
-static int
-amr_pci_shutdown(device_t dev)
-{
- struct amr_softc *sc = device_get_softc(dev);
- int i,error;
-
- debug_called(1);
-
- /* mark ourselves as in-shutdown */
- sc->amr_state |= AMR_STATE_SHUTDOWN;
-
- /* flush controller */
- device_printf(sc->amr_dev, "flushing cache...");
- printf("%s\n", amr_flush(sc) ? "failed" : "done");
-
- error = 0;
-
- /* delete all our child devices */
- for(i = 0 ; i < AMR_MAXLD; i++) {
- if( sc->amr_drive[i].al_disk != 0) {
- if((error = device_delete_child(sc->amr_dev,sc->amr_drive[i].al_disk)) != 0)
- goto shutdown_out;
- sc->amr_drive[i].al_disk = 0;
- }
- }
-
- /* XXX disable interrupts? */
-
-shutdown_out:
- return(error);
-}
-
-/********************************************************************************
- * Bring the controller to a quiescent state, ready for system suspend.
- */
-static int
-amr_pci_suspend(device_t dev)
-{
- struct amr_softc *sc = device_get_softc(dev);
-
- debug_called(1);
-
- sc->amr_state |= AMR_STATE_SUSPEND;
-
- /* flush controller */
- device_printf(sc->amr_dev, "flushing cache...");
- printf("%s\n", amr_flush(sc) ? "failed" : "done");
-
- /* XXX disable interrupts? */
-
- return(0);
-}
-
-/********************************************************************************
- * Bring the controller back to a state ready for operation.
- */
-static int
-amr_pci_resume(device_t dev)
-{
- struct amr_softc *sc = device_get_softc(dev);
-
- debug_called(1);
-
- sc->amr_state &= ~AMR_STATE_SUSPEND;
-
- /* XXX enable interrupts? */
-
- return(0);
-}
-
-/*******************************************************************************
- * Take an interrupt, or be poked by other code to look for interrupt-worthy
- * status.
- */
-static void
-amr_pci_intr(void *arg)
-{
- struct amr_softc *sc = (struct amr_softc *)arg;
-
- debug_called(3);
-
- /* collect finished commands, queue anything waiting */
- amr_done(sc);
-}
-
-/********************************************************************************
- * Free all of the resources associated with (sc)
- *
- * Should not be called if the controller is active.
- */
-static void
-amr_pci_free(struct amr_softc *sc)
-{
- void *p;
-
- debug_called(1);
-
- amr_free(sc);
-
- /* destroy data-transfer DMA tag */
- if (sc->amr_buffer_dmat)
- bus_dma_tag_destroy(sc->amr_buffer_dmat);
- if (sc->amr_buffer64_dmat)
- bus_dma_tag_destroy(sc->amr_buffer64_dmat);
-
- /* free and destroy DMA memory and tag for passthrough pool */
- if (sc->amr_ccb) {
- bus_dmamap_unload(sc->amr_ccb_dmat, sc->amr_ccb_dmamap);
- bus_dmamem_free(sc->amr_ccb_dmat, sc->amr_ccb, sc->amr_ccb_dmamap);
- }
- if (sc->amr_ccb_dmat)
- bus_dma_tag_destroy(sc->amr_ccb_dmat);
-
- /* free and destroy DMA memory and tag for s/g lists */
- if (sc->amr_sgtable) {
- bus_dmamap_unload(sc->amr_sg_dmat, sc->amr_sg_dmamap);
- bus_dmamem_free(sc->amr_sg_dmat, sc->amr_sgtable, sc->amr_sg_dmamap);
- }
- if (sc->amr_sg_dmat)
- bus_dma_tag_destroy(sc->amr_sg_dmat);
-
- /* free and destroy DMA memory and tag for mailbox */
- p = (void *)(uintptr_t)(volatile void *)sc->amr_mailbox64;
- if (sc->amr_mailbox) {
- bus_dmamap_unload(sc->amr_mailbox_dmat, sc->amr_mailbox_dmamap);
- bus_dmamem_free(sc->amr_mailbox_dmat, p, sc->amr_mailbox_dmamap);
- }
- if (sc->amr_mailbox_dmat)
- bus_dma_tag_destroy(sc->amr_mailbox_dmat);
-
- /* disconnect the interrupt handler */
- if (sc->amr_intr)
- bus_teardown_intr(sc->amr_dev, sc->amr_irq, sc->amr_intr);
- if (sc->amr_irq != NULL)
- bus_release_resource(sc->amr_dev, SYS_RES_IRQ, 0, sc->amr_irq);
-
- /* destroy the parent DMA tag */
- if (sc->amr_parent_dmat)
- bus_dma_tag_destroy(sc->amr_parent_dmat);
-
- /* release the register window mapping */
- if (sc->amr_reg != NULL)
- bus_release_resource(sc->amr_dev,
- AMR_IS_QUARTZ(sc) ? SYS_RES_MEMORY : SYS_RES_IOPORT,
- PCIR_BAR(0), sc->amr_reg);
-}
-
-/********************************************************************************
- * Allocate and map the scatter/gather table in bus space.
- */
-static void
-amr_sglist_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- uint32_t *addr;
-
- debug_called(1);
-
- addr = arg;
- *addr = segs[0].ds_addr;
-}
-
-static int
-amr_sglist_map(struct amr_softc *sc)
-{
- size_t segsize;
- void *p;
- int error;
-
- debug_called(1);
-
- /*
- * Create a single tag describing a region large enough to hold all of
- * the s/g lists we will need.
- *
- * Note that we could probably use AMR_LIMITCMD here, but that may become
- * tunable.
- */
- if (AMR_IS_SG64(sc))
- segsize = sizeof(struct amr_sg64entry) * AMR_NSEG * AMR_MAXCMD;
- else
- segsize = sizeof(struct amr_sgentry) * AMR_NSEG * AMR_MAXCMD;
-
- error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
- 512, 0, /* alignment,boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- segsize, 1, /* maxsize, nsegments */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->amr_sg_dmat);
- if (error != 0) {
- device_printf(sc->amr_dev, "can't allocate scatter/gather DMA tag\n");
- return(ENOMEM);
- }
-
- /*
- * Allocate enough s/g maps for all commands and permanently map them into
- * controller-visible space.
- *
- * XXX this assumes we can get enough space for all the s/g maps in one
- * contiguous slab. We may need to switch to a more complex arrangement
- * where we allocate in smaller chunks and keep a lookup table from slot
- * to bus address.
- *
- * XXX HACK ALERT: at least some controllers don't like the s/g memory
- * being allocated below 0x2000. We leak some memory if
- * we get some below this mark and allocate again. We
- * should be able to avoid this with the tag setup, but
- * that does't seem to work.
- */
-retry:
- error = bus_dmamem_alloc(sc->amr_sg_dmat, (void **)&p, BUS_DMA_NOWAIT, &sc->amr_sg_dmamap);
- if (error) {
- device_printf(sc->amr_dev, "can't allocate s/g table\n");
- return(ENOMEM);
- }
- bus_dmamap_load(sc->amr_sg_dmat, sc->amr_sg_dmamap, p, segsize, amr_sglist_helper, &sc->amr_sgbusaddr, 0);
- if (sc->amr_sgbusaddr < 0x2000) {
- debug(1, "s/g table too low (0x%x), reallocating\n", sc->amr_sgbusaddr);
- goto retry;
- }
-
- if (AMR_IS_SG64(sc))
- sc->amr_sg64table = (struct amr_sg64entry *)p;
- sc->amr_sgtable = (struct amr_sgentry *)p;
-
- return(0);
-}
-
-/********************************************************************************
- * Allocate and set up mailbox areas for the controller (sc)
- *
- * The basic mailbox structure should be 16-byte aligned.
- */
-static int
-amr_setup_mbox(struct amr_softc *sc)
-{
- int error;
- void *p;
- uint32_t baddr;
-
- debug_called(1);
-
- /*
- * Create a single tag describing a region large enough to hold the entire
- * mailbox.
- */
- error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
- 16, 0, /* alignment,boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- sizeof(struct amr_mailbox64), /* maxsize */
- 1, /* nsegments */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->amr_mailbox_dmat);
- if (error != 0) {
- device_printf(sc->amr_dev, "can't allocate mailbox tag\n");
- return(ENOMEM);
- }
-
- /*
- * Allocate the mailbox structure and permanently map it into
- * controller-visible space.
- */
- error = bus_dmamem_alloc(sc->amr_mailbox_dmat, (void **)&p, BUS_DMA_NOWAIT,
- &sc->amr_mailbox_dmamap);
- if (error) {
- device_printf(sc->amr_dev, "can't allocate mailbox memory\n");
- return(ENOMEM);
- }
- bus_dmamap_load(sc->amr_mailbox_dmat, sc->amr_mailbox_dmamap, p,
- sizeof(struct amr_mailbox64), amr_sglist_helper, &baddr, 0);
- /*
- * Conventional mailbox is inside the mailbox64 region.
- */
- /* save physical base of the basic mailbox structure */
- sc->amr_mailboxphys = baddr + offsetof(struct amr_mailbox64, mb);
- bzero(p, sizeof(struct amr_mailbox64));
- sc->amr_mailbox64 = (struct amr_mailbox64 *)p;
- sc->amr_mailbox = &sc->amr_mailbox64->mb;
-
- return(0);
-}
-
-static int
-amr_ccb_map(struct amr_softc *sc)
-{
- int ccbsize, error;
-
- /*
- * Passthrough and Extended passthrough structures will share the same
- * memory.
- */
- ccbsize = sizeof(union amr_ccb) * AMR_MAXCMD;
- error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
- 128, 0, /* alignment,boundary */
- BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- ccbsize, /* maxsize */
- 1, /* nsegments */
- ccbsize, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->amr_ccb_dmat);
- if (error != 0) {
- device_printf(sc->amr_dev, "can't allocate ccb tag\n");
- return (ENOMEM);
- }
-
- error = bus_dmamem_alloc(sc->amr_ccb_dmat, (void **)&sc->amr_ccb,
- BUS_DMA_NOWAIT, &sc->amr_ccb_dmamap);
- if (error) {
- device_printf(sc->amr_dev, "can't allocate ccb memory\n");
- return (ENOMEM);
- }
- bus_dmamap_load(sc->amr_ccb_dmat, sc->amr_ccb_dmamap, sc->amr_ccb,
- ccbsize, amr_sglist_helper, &sc->amr_ccb_busaddr, 0);
- bzero(sc->amr_ccb, ccbsize);
-
- return (0);
-}
diff --git a/sys/dev/amr/amr_tables.h b/sys/dev/amr/amr_tables.h
deleted file mode 100644
index 8cc114178a6d..000000000000
--- a/sys/dev/amr/amr_tables.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-3-Clause
- *
- * Copyright (c) 2000 Michael Smith
- * Copyright (c) 2000 BSDi
- * 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.
- *
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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$
- */
-
-/*
- * Lookup table for code-to-text translations.
- */
-struct amr_code_lookup {
- char *string;
- u_int32_t code;
-};
-
-extern char *amr_describe_code(struct amr_code_lookup *table, u_int32_t code);
-
-#ifndef AMR_DEFINE_TABLES
-extern struct amr_code_lookup amr_table_qinit[];
-extern struct amr_code_lookup amr_table_sinit[];
-extern struct amr_code_lookup amr_table_drvstate[];
-
-#else /* AMR_DEFINE_TABLES */
-
-/********************************************************************************
- * Look up a text description of a numeric code and return a pointer to same.
- */
-char *
-amr_describe_code(struct amr_code_lookup *table, u_int32_t code)
-{
- int i;
-
- for (i = 0; table[i].string != NULL; i++)
- if (table[i].code == code)
- return(table[i].string);
- return(table[i+1].string);
-}
-
-struct amr_code_lookup amr_table_qinit[] = {
- {"init scanning drives", AMR_QINIT_SCAN},
- {"init scanning initialising", AMR_QINIT_SCANINIT},
- {"init firmware initing", AMR_QINIT_FIRMWARE},
- {"init in progress", AMR_QINIT_INPROG},
- {"init spinning drives", AMR_QINIT_SPINUP},
- {"insufficient memory", AMR_QINIT_NOMEM},
- {"init flushing cache", AMR_QINIT_CACHEFLUSH},
- {"init successfully done", AMR_QINIT_DONE},
- {NULL, 0},
- {"unknown init code", 0}
-};
-
-struct amr_code_lookup amr_table_sinit[] = {
- {"init abnormal terminated", AMR_SINIT_ABEND},
- {"insufficient memory", AMR_SINIT_NOMEM},
- {"firmware flushing cache", AMR_SINIT_CACHEFLUSH},
- {"init in progress", AMR_SINIT_INPROG},
- {"firmware spinning drives", AMR_SINIT_SPINUP},
- {"init successfully done", AMR_SINIT_DONE},
- {NULL, 0},
- {"unknown init code", 0}
-};
-
-struct amr_code_lookup amr_table_drvstate[] = {
- {"offline", AMR_DRV_OFFLINE},
- {"degraded", AMR_DRV_DEGRADED},
- {"optimal", AMR_DRV_OPTIMAL},
- {"online", AMR_DRV_ONLINE},
- {"failed", AMR_DRV_FAILED},
- {"rebuild", AMR_DRV_REBUILD},
- {"hot spare", AMR_DRV_HOTSPARE},
- {NULL, 0},
- {"unknown", 0}
-};
-
-struct amr_code_lookup amr_table_adaptertype[] = {
- {"Series 431", AMR_SIG_431},
- {"Series 438", AMR_SIG_438},
- {"Series 762", AMR_SIG_762},
- {"Integrated HP NetRAID (T5)", AMR_SIG_T5},
- {"Series 466", AMR_SIG_466},
- {"Series 467", AMR_SIG_467},
- {"Integrated HP NetRAID (T7)", AMR_SIG_T7},
- {"Series 490", AMR_SIG_490},
- {NULL, 0},
- {"unknown adapter", 0}
-};
-
-#endif
diff --git a/sys/dev/amr/amrio.h b/sys/dev/amr/amrio.h
deleted file mode 100644
index c069555b7e18..000000000000
--- a/sys/dev/amr/amrio.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-3-Clause
- *
- * Copyright (c) 1999 Michael Smith
- * 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.
- *
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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$
- */
-
-/*
- * ioctl interface
- */
-
-#include <sys/ioccom.h>
-#include <sys/param.h>
-
-/*
- * Fetch the driver's interface version.
- */
-#define AMR_IO_VERSION_NUMBER 153
-#define AMR_IO_VERSION _IOR('A', 0x200, int)
-
-/*
- * Pass a command from userspace through to the adapter.
- *
- * Note that in order to be code-compatible with the Linux
- * interface where possible, the formatting of the au_cmd field is
- * somewhat Interesting.
- *
- * For normal commands, the layout is (fields from struct amr_mailbox_ioctl):
- *
- * 0 mb_command
- * 1 mb_channel
- * 2 mb_param
- * 3 mb_pad[0]
- * 4 mb_drive
- *
- * For SCSI passthrough commands, the layout is:
- *
- * 0 AMR_CMD_PASS (0x3)
- * 1 reserved, 0
- * 2 cdb length
- * 3 cdb data
- * 3+cdb_len passthrough control byte (timeout, ars, islogical)
- * 4+cdb_len reserved, 0
- * 5+cdb_len channel
- * 6+cdb_len target
- */
-
-struct amr_user_ioctl {
- unsigned char au_cmd[32]; /* command text from userspace */
- void *au_buffer; /* data buffer in userspace */
- unsigned long au_length; /* data buffer size (0 == no data) */
- int au_direction; /* data transfer direction */
-#define AMR_IO_NODATA 0
-#define AMR_IO_READ 1
-#define AMR_IO_WRITE 2
- int au_status; /* command status returned by adapter */
-};
-
-#define AMR_IO_COMMAND _IOWR('A', 0x201, struct amr_user_ioctl)
-
-#if defined(__amd64__)
-
-struct amr_user_ioctl32 {
- unsigned char au_cmd[32]; /* command text from userspace */
- u_int32_t au_buffer; /* 32-bit pointer to uspace buf */
- u_int32_t au_length; /* length of the uspace buffer */
- int32_t au_direction; /* data transfer direction */
- int32_t au_status; /* command status returned by adapter */
-};
-
-# define AMR_IO_COMMAND32 _IOWR('A', 0x201, struct amr_user_ioctl32)
-#endif
diff --git a/sys/dev/amr/amrreg.h b/sys/dev/amr/amrreg.h
deleted file mode 100644
index 1ec6c5e56d6d..000000000000
--- a/sys/dev/amr/amrreg.h
+++ /dev/null
@@ -1,657 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-3-Clause
- *
- * Copyright (c) 1999,2000 Michael Smith
- * Copyright (c) 2000 BSDi
- * 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.
- *
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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$
- */
-
-/********************************************************************************
- ********************************************************************************
- Driver parameters
- ********************************************************************************
- ********************************************************************************/
-
-/*
- * We could actually use all 17 segments, but using only 16 means that
- * each scatter/gather map is 128 bytes in size, and thus we don't have to worry about
- * maps crossing page boundaries.
- *
- * The AMI documentation says that the limit is 26. Unfortunately, there's no way to
- * cleanly fit more than 16 entries in without a page boundary. But is this a concern,
- * since we allocate the s/g maps contiguously anyway?
- */
-/*
- * emoore - Oct 21, 2002
- * firmware doesn't have sglist boundary restrictions.
- * The sgelem can be set to 26
- */
-#define AMR_NSEG 26
-
-#define AMR_MAXCMD 255 /* ident = 0 not allowed */
-#define AMR_LIMITCMD 120 /* maximum count of outstanding commands */
-#define AMR_MAXLD 40
-
-#define AMR_MAX_CHANNELS 8
-#define AMR_MAX_TARGETS 15
-#define AMR_MAX_LUNS 7
-#define AMR_MAX_SCSI_CMDS (15 * AMR_MAX_CHANNELS) /* one for every target? */
-
-#define AMR_MAX_CDB_LEN 0x0a
-#define AMR_MAX_EXTCDB_LEN 0x10
-#define AMR_MAX_REQ_SENSE_LEN 0x20
-
-#define AMR_BLKSIZE 512 /* constant for all controllers */
-
-/*
- * Perform at-startup board initialisation.
- * At this point in time, this code doesn't work correctly, so leave it disabled.
- */
-/*#define AMR_BOARD_INIT*/
-
-/********************************************************************************
- ********************************************************************************
- Interface Magic Numbers
- ********************************************************************************
- ********************************************************************************/
-
-/*
- * Mailbox commands
- */
-#define AMR_CMD_LREAD 0x01
-#define AMR_CMD_LWRITE 0x02
-#define AMR_CMD_PASS 0x03
-#define AMR_CMD_EXT_ENQUIRY 0x04
-#define AMR_CMD_ENQUIRY 0x05
-#define AMR_CMD_FLUSH 0x0a
-#define AMR_CMD_EXT_ENQUIRY2 0x0c
-#define AMR_CONFIG_PRODINFO 0x0e
-#define AMR_CMD_GET_MACHINEID 0x36
-#define AMR_CMD_GET_INITIATOR 0x7d /* returns one byte */
-#define AMR_CMD_CONFIG 0xa1
-#define AMR_CMD_LREAD64 0xa7
-#define AMR_CMD_LWRITE64 0xa8
-#define AMR_CMD_PASS_64 0xc3
-#define AMR_CMD_EXTPASS 0xe3
-
-#define AMR_CONFIG_READ_NVRAM_CONFIG 0x04
-#define AMR_CONFIG_WRITE_NVRAM_CONFIG 0x0d
-#define AMR_CONFIG_PRODUCT_INFO 0x0e
-#define AMR_CONFIG_ENQ3 0x0f
-#define AMR_CONFIG_ENQ3_SOLICITED_NOTIFY 0x01
-#define AMR_CONFIG_ENQ3_SOLICITED_FULL 0x02
-#define AMR_CONFIG_ENQ3_UNSOLICITED 0x03
-
-/*
- * Command for random deletion of logical drives
- */
-#define FC_DEL_LOGDRV 0xA4
-#define OP_SUP_DEL_LOGDRV 0x2A
-#define OP_GET_LDID_MAP 0x18
-#define OP_DEL_LOGDRV 0x1C
-
-/*
- * Command for random deletion of logical drives
- */
-#define FC_DEL_LOGDRV 0xA4
-#define OP_SUP_DEL_LOGDRV 0x2A
-#define OP_GET_LDID_MAP 0x18
-#define OP_DEL_LOGDRV 0x1C
-
-/*
- * Command results
- */
-#define AMR_STATUS_SUCCESS 0x00
-#define AMR_STATUS_ABORTED 0x02
-#define AMR_STATUS_FAILED 0x80
-
-/*
- * Physical/logical drive states
- */
-#define AMR_DRV_CURSTATE(x) ((x) & 0x0f)
-#define AMR_DRV_PREVSTATE(x) (((x) >> 4) & 0x0f)
-#define AMR_DRV_OFFLINE 0x00
-#define AMR_DRV_DEGRADED 0x01
-#define AMR_DRV_OPTIMAL 0x02
-#define AMR_DRV_ONLINE 0x03
-#define AMR_DRV_FAILED 0x04
-#define AMR_DRV_REBUILD 0x05
-#define AMR_DRV_HOTSPARE 0x06
-
-/*
- * Logical drive properties
- */
-#define AMR_DRV_RAID_MASK 0x0f /* RAID level 0, 1, 3, 5, etc. */
-#define AMR_DRV_WRITEBACK 0x10 /* write-back enabled */
-#define AMR_DRV_READHEAD 0x20 /* readhead policy enabled */
-#define AMR_DRV_ADAPTIVE 0x40 /* adaptive I/O policy enabled */
-
-/*
- * Battery status
- */
-#define AMR_BATT_MODULE_MISSING 0x01
-#define AMR_BATT_LOW_VOLTAGE 0x02
-#define AMR_BATT_TEMP_HIGH 0x04
-#define AMR_BATT_PACK_MISSING 0x08
-#define AMR_BATT_CHARGE_MASK 0x30
-#define AMR_BATT_CHARGE_DONE 0x00
-#define AMR_BATT_CHARGE_INPROG 0x10
-#define AMR_BATT_CHARGE_FAIL 0x20
-#define AMR_BATT_CYCLES_EXCEEDED 0x40
-
-/********************************************************************************
- ********************************************************************************
- 8LD Firmware Interface
- ********************************************************************************
- ********************************************************************************/
-
-/*
- * Array constraints
- */
-#define AMR_8LD_MAXDRIVES 8
-#define AMR_8LD_MAXCHAN 5
-#define AMR_8LD_MAXTARG 15
-#define AMR_8LD_MAXPHYSDRIVES (AMR_8LD_MAXCHAN * AMR_8LD_MAXTARG)
-
-/*
- * Adapter Info structure
- */
-struct amr_adapter_info
-{
- u_int8_t aa_maxio;
- u_int8_t aa_rebuild_rate;
- u_int8_t aa_maxtargchan;
- u_int8_t aa_channels;
- u_int8_t aa_firmware[4];
- u_int16_t aa_flashage;
- u_int8_t aa_chipsetvalue;
- u_int8_t aa_memorysize;
- u_int8_t aa_cacheflush;
- u_int8_t aa_bios[4];
- u_int8_t aa_boardtype;
- u_int8_t aa_scsisensealert;
- u_int8_t aa_writeconfigcount;
- u_int8_t aa_driveinsertioncount;
- u_int8_t aa_inserteddrive;
- u_int8_t aa_batterystatus;
- u_int8_t res1;
-} __packed;
-
-/*
- * Logical Drive info structure
- */
-struct amr_logdrive_info
-{
- u_int8_t al_numdrives;
- u_int8_t res1[3];
- u_int32_t al_size[AMR_8LD_MAXDRIVES];
- u_int8_t al_properties[AMR_8LD_MAXDRIVES];
- u_int8_t al_state[AMR_8LD_MAXDRIVES];
-} __packed;
-
-/*
- * Physical Drive info structure
- */
-struct amr_physdrive_info
-{
- u_int8_t ap_state[AMR_8LD_MAXPHYSDRIVES]; /* low nibble current state, high nibble previous state */
- u_int8_t ap_predictivefailure;
-} __packed;
-
-/*
- * Enquiry response structure for AMR_CMD_ENQUIRY, AMR_CMD_EXT_ENQUIRY and
- * AMR_CMD_EXT_ENQUIRY2.
- * ENQUIRY EXT_ENQUIRY EXT_ENQUIRY2
- */
-struct amr_enquiry
-{
- struct amr_adapter_info ae_adapter; /* X X X */
- struct amr_logdrive_info ae_ldrv; /* X X X */
- struct amr_physdrive_info ae_pdrv; /* X X X */
- u_int8_t ae_formatting[AMR_8LD_MAXDRIVES];/* X X */
- u_int8_t res1[AMR_8LD_MAXDRIVES]; /* X X */
- u_int32_t ae_extlen; /* X */
- u_int16_t ae_subsystem; /* X */
- u_int16_t ae_subvendor; /* X */
- u_int32_t ae_signature; /* X */
-#define AMR_SIG_431 0xfffe0001
-#define AMR_SIG_438 0xfffd0002
-#define AMR_SIG_762 0xfffc0003
-#define AMR_SIG_T5 0xfffb0004
-#define AMR_SIG_466 0xfffa0005
-#define AMR_SIG_467 0xfff90006
-#define AMR_SIG_T7 0xfff80007
-#define AMR_SIG_490 0xfff70008
- u_int8_t res2[844]; /* X */
-} __packed;
-
-/********************************************************************************
- ********************************************************************************
- 40LD Firmware Interface
- ********************************************************************************
- ********************************************************************************/
-
-/*
- * Array constraints
- */
-#define AMR_40LD_MAXDRIVES 40
-#define AMR_40LD_MAXCHAN 16
-#define AMR_40LD_MAXTARG 16
-#define AMR_40LD_MAXPHYSDRIVES 256
-
-/*
- * Product Info structure
- */
-struct amr_prodinfo
-{
- u_int32_t ap_size; /* current size in bytes (not including resvd) */
- u_int32_t ap_configsig; /* default is 0x00282008, indicating 0x28 maximum
- * logical drives, 0x20 maximum stripes and 0x08
- * maximum spans */
- u_int8_t ap_firmware[16]; /* printable identifiers */
- u_int8_t ap_bios[16];
- u_int8_t ap_product[80];
- u_int8_t ap_maxio; /* maximum number of concurrent commands supported */
- u_int8_t ap_nschan; /* number of SCSI channels present */
- u_int8_t ap_fcloops; /* number of fibre loops present */
- u_int8_t ap_memtype; /* memory type */
- u_int32_t ap_signature;
- u_int16_t ap_memsize; /* onboard memory in MB */
- u_int16_t ap_subsystem; /* subsystem identifier */
- u_int16_t ap_subvendor; /* subsystem vendor ID */
- u_int8_t ap_numnotifyctr; /* number of notify counters */
-} __packed;
-
-/*
- * Notify structure
- */
-struct amr_notify
-{
- u_int32_t an_globalcounter; /* change counter */
-
- u_int8_t an_paramcounter; /* parameter change counter */
- u_int8_t an_paramid;
-#define AMR_PARAM_REBUILD_RATE 0x01 /* value = new rebuild rate */
-#define AMR_PARAM_FLUSH_INTERVAL 0x02 /* value = new flush interval */
-#define AMR_PARAM_SENSE_ALERT 0x03 /* value = last physical drive with check condition set */
-#define AMR_PARAM_DRIVE_INSERTED 0x04 /* value = last physical drive inserted */
-#define AMR_PARAM_BATTERY_STATUS 0x05 /* value = battery status */
- u_int16_t an_paramval;
-
- u_int8_t an_writeconfigcounter; /* write config occurred */
- u_int8_t res1[3];
-
- u_int8_t an_ldrvopcounter; /* logical drive operation started/completed */
- u_int8_t an_ldrvopid;
- u_int8_t an_ldrvopcmd;
-#define AMR_LDRVOP_CHECK 0x01
-#define AMR_LDRVOP_INIT 0x02
-#define AMR_LDRVOP_REBUILD 0x03
- u_int8_t an_ldrvopstatus;
-#define AMR_LDRVOP_SUCCESS 0x00
-#define AMR_LDRVOP_FAILED 0x01
-#define AMR_LDRVOP_ABORTED 0x02
-#define AMR_LDRVOP_CORRECTED 0x03
-#define AMR_LDRVOP_STARTED 0x04
-
- u_int8_t an_ldrvstatecounter; /* logical drive state change occurred */
- u_int8_t an_ldrvstateid;
- u_int8_t an_ldrvstatenew;
- u_int8_t an_ldrvstateold;
-
- u_int8_t an_pdrvstatecounter; /* physical drive state change occurred */
- u_int8_t an_pdrvstateid;
- u_int8_t an_pdrvstatenew;
- u_int8_t an_pdrvstateold;
-
- u_int8_t an_pdrvfmtcounter;
- u_int8_t an_pdrvfmtid;
- u_int8_t an_pdrvfmtval;
-#define AMR_FORMAT_START 0x01
-#define AMR_FORMAT_COMPLETE 0x02
- u_int8_t res2;
-
- u_int8_t an_targxfercounter; /* scsi xfer rate change */
- u_int8_t an_targxferid;
- u_int8_t an_targxferval;
- u_int8_t res3;
-
- u_int8_t an_fcloopidcounter; /* FC/AL loop ID changed */
- u_int8_t an_fcloopidpdrvid;
- u_int8_t an_fcloopid0;
- u_int8_t an_fcloopid1;
-
- u_int8_t an_fcloopstatecounter; /* FC/AL loop status changed */
- u_int8_t an_fcloopstate0;
- u_int8_t an_fcloopstate1;
- u_int8_t res4;
-} __packed;
-
-/*
- * Enquiry3 structure
- */
-struct amr_enquiry3
-{
- u_int32_t ae_datasize; /* valid data size in this structure */
- union { /* event notify structure */
- struct amr_notify n;
- u_int8_t pad[0x80];
- } ae_notify;
- u_int8_t ae_rebuildrate; /* current rebuild rate in % */
- u_int8_t ae_cacheflush; /* flush interval in seconds */
- u_int8_t ae_sensealert;
- u_int8_t ae_driveinsertcount; /* count of inserted drives */
- u_int8_t ae_batterystatus;
- u_int8_t ae_numldrives;
- u_int8_t ae_reconstate[AMR_40LD_MAXDRIVES / 8]; /* reconstruction state */
- u_int16_t ae_opstatus[AMR_40LD_MAXDRIVES / 8]; /* operation status per drive */
- u_int32_t ae_drivesize[AMR_40LD_MAXDRIVES]; /* logical drive size */
- u_int8_t ae_driveprop[AMR_40LD_MAXDRIVES]; /* logical drive properties */
- u_int8_t ae_drivestate[AMR_40LD_MAXDRIVES]; /* logical drive state */
- u_int8_t ae_pdrivestate[AMR_40LD_MAXPHYSDRIVES]; /* physical drive state */
- u_int16_t ae_pdriveformat[AMR_40LD_MAXPHYSDRIVES / 16];
- u_int8_t ae_targxfer[80]; /* physical drive transfer rates */
-
- u_int8_t res1[263]; /* pad to 1024 bytes */
-} __packed;
-
-/********************************************************************************
- ********************************************************************************
- Mailbox and Command Structures
- ********************************************************************************
- ********************************************************************************/
-
-#define AMR_MBOX_CMDSIZE 0x10 /* portion worth copying for controller */
-
-struct amr_mailbox
-{
- u_int8_t mb_command;
- u_int8_t mb_ident;
- u_int16_t mb_blkcount; /* u_int8_t opcode */
- /* u_int8_t subopcode */
- u_int32_t mb_lba;
- u_int32_t mb_physaddr;
- u_int8_t mb_drive;
- u_int8_t mb_nsgelem; /* u_int8_t rserv[0] */
- u_int8_t res1; /* u_int8_t rserv[1] */
- u_int8_t mb_busy; /* u_int8_t rserv[2] */
- u_int8_t mb_nstatus;
- u_int8_t mb_status;
- u_int8_t mb_completed[46];
- u_int8_t mb_poll;
- u_int8_t mb_ack;
- u_int8_t res2[16];
-} __packed;
-
-struct amr_mailbox64
-{
- u_int8_t pad[8]; /* Needed for alignment */
- u_int32_t sg64_lo; /* S/G pointer for 64-bit commands */
- u_int32_t sg64_hi; /* S/G pointer for 64-bit commands */
- struct amr_mailbox mb;
-} __packed;
-
-struct amr_mailbox_ioctl
-{
- u_int8_t mb_command;
- u_int8_t mb_ident;
- u_int8_t mb_channel;
- u_int8_t mb_param;
- u_int8_t mb_pad[4];
- u_int32_t mb_physaddr;
- u_int8_t mb_drive;
- u_int8_t mb_nsgelem;
- u_int8_t res1;
- u_int8_t mb_busy;
- u_int8_t mb_nstatus;
- u_int8_t mb_completed[46];
- u_int8_t mb_poll;
- u_int8_t mb_ack;
- u_int8_t res4[16];
-} __packed;
-
-struct amr_sgentry
-{
- u_int32_t sg_addr;
- u_int32_t sg_count;
-} __packed;
-
-struct amr_sg64entry
-{
- u_int64_t sg_addr;
- u_int32_t sg_count;
-} __packed;
-
-struct amr_passthrough
-{
- u_int8_t ap_timeout:3;
- u_int8_t ap_ars:1;
- u_int8_t ap_dummy:3;
- u_int8_t ap_islogical:1;
- u_int8_t ap_logical_drive_no;
- u_int8_t ap_channel;
- u_int8_t ap_scsi_id;
- u_int8_t ap_queue_tag;
- u_int8_t ap_queue_action;
- u_int8_t ap_cdb[AMR_MAX_CDB_LEN];
- u_int8_t ap_cdb_length;
- u_int8_t ap_request_sense_length;
- u_int8_t ap_request_sense_area[AMR_MAX_REQ_SENSE_LEN];
- u_int8_t ap_no_sg_elements;
- u_int8_t ap_scsi_status;
- u_int32_t ap_data_transfer_address;
- u_int32_t ap_data_transfer_length;
-} __packed;
-
-struct amr_ext_passthrough
-{
- u_int8_t ap_timeout:3;
- u_int8_t ap_ars:1;
- u_int8_t ap_rsvd1:1;
- u_int8_t ap_cd_rom:1;
- u_int8_t ap_rsvd2:1;
- u_int8_t ap_islogical:1;
- u_int8_t ap_logical_drive_no;
- u_int8_t ap_channel;
- u_int8_t ap_scsi_id;
- u_int8_t ap_queue_tag;
- u_int8_t ap_queue_action;
- u_int8_t ap_cdb_length;
- u_int8_t ap_rsvd3;
- u_int8_t ap_cdb[AMR_MAX_EXTCDB_LEN];
- u_int8_t ap_no_sg_elements;
- u_int8_t ap_scsi_status;
- u_int8_t ap_request_sense_length;
- u_int8_t ap_request_sense_area[AMR_MAX_REQ_SENSE_LEN];
- u_int8_t ap_rsvd4;
- u_int32_t ap_data_transfer_address;
- u_int32_t ap_data_transfer_length;
-} __packed;
-
-struct amr_linux_ioctl {
- u_int32_t inlen;
- u_int32_t outlen;
- union {
- u_int8_t fca[16];
- struct {
- u_int8_t opcode;
- u_int8_t subopcode;
- u_int16_t adapno;
- u_int32_t buffer;
- u_int8_t pad[4];
- u_int32_t length;
- } __packed fcs;
- } __packed ui;
- u_int8_t mbox[18];
- struct amr_passthrough pthru;
- u_int32_t data;
- u_int8_t pad[4];
-} __packed;
-
-#ifdef _KERNEL
-/********************************************************************************
- ********************************************************************************
- "Quartz" i960 PCI bridge interface
- ********************************************************************************
- ********************************************************************************/
-
-#define AMR_CFG_SIG 0xa0 /* PCI config register for signature */
-#define AMR_SIGNATURE_1 0xCCCC /* i960 signature (older adapters) */
-#define AMR_SIGNATURE_2 0x3344 /* i960 signature (newer adapters) */
-
-/*
- * Doorbell registers
- */
-#define AMR_QIDB 0x20
-#define AMR_QODB 0x2c
-#define AMR_QIDB_SUBMIT 0x00000001 /* mailbox ready for work */
-#define AMR_QIDB_ACK 0x00000002 /* mailbox done */
-#define AMR_QODB_READY 0x10001234 /* work ready to be processed */
-
-/*
- * Initialisation status
- */
-#define AMR_QINIT_SCAN 0x01 /* init scanning drives */
-#define AMR_QINIT_SCANINIT 0x02 /* init scanning initialising */
-#define AMR_QINIT_FIRMWARE 0x03 /* init firmware initing */
-#define AMR_QINIT_INPROG 0xdc /* init in progress */
-#define AMR_QINIT_SPINUP 0x2c /* init spinning drives */
-#define AMR_QINIT_NOMEM 0xac /* insufficient memory */
-#define AMR_QINIT_CACHEFLUSH 0xbc /* init flushing cache */
-#define AMR_QINIT_DONE 0x9c /* init successfully done */
-
-/*
- * I/O primitives
- */
-#define AMR_QPUT_IDB(sc, val) bus_space_write_4(sc->amr_btag, sc->amr_bhandle, AMR_QIDB, val)
-#define AMR_QGET_IDB(sc) bus_space_read_4 (sc->amr_btag, sc->amr_bhandle, AMR_QIDB)
-#define AMR_QPUT_ODB(sc, val) bus_space_write_4(sc->amr_btag, sc->amr_bhandle, AMR_QODB, val)
-#define AMR_QGET_ODB(sc) bus_space_read_4 (sc->amr_btag, sc->amr_bhandle, AMR_QODB)
-
-#ifdef AMR_BOARD_INIT
-#define AMR_QRESET(sc) \
- do { \
- pci_write_config((sc)->amr_dev, 0x40, pci_read_config((sc)->amr_dev, 0x40, 1) | 0x20, 1); \
- pci_write_config((sc)->amr_dev, 0x64, 0x1122, 1); \
- } while (0)
-#define AMR_QGET_INITSTATUS(sc) pci_read_config((sc)->amr_dev, 0x9c, 1)
-#define AMR_QGET_INITCHAN(sc) pci_read_config((sc)->amr_dev, 0x9f, 1)
-#define AMR_QGET_INITTARG(sc) pci_read_config((sc)->amr_dev, 0x9e, 1)
-#endif
-
-/********************************************************************************
- ********************************************************************************
- "Standard" old-style ASIC bridge interface
- ********************************************************************************
- ********************************************************************************/
-
-/*
- * I/O registers
- */
-#define AMR_SCMD 0x10 /* command/ack register (write) */
-#define AMR_SMBOX_BUSY 0x10 /* mailbox status (read) */
-#define AMR_STOGGLE 0x11 /* interrupt enable bit here */
-#define AMR_SMBOX_0 0x14 /* mailbox physical address low byte */
-#define AMR_SMBOX_1 0x15
-#define AMR_SMBOX_2 0x16
-#define AMR_SMBOX_3 0x17 /* high byte */
-#define AMR_SMBOX_ENABLE 0x18 /* atomic mailbox address enable */
-#define AMR_SINTR 0x1a /* interrupt status */
-
-/*
- * I/O magic numbers
- */
-#define AMR_SCMD_POST 0x10 /* -> SCMD to initiate action on mailbox */
-#define AMR_SCMD_ACKINTR 0x08 /* -> SCMD to ack mailbox retrieved */
-#define AMR_STOGL_IENABLE 0xc0 /* in STOGGLE */
-#define AMR_SINTR_VALID 0x40 /* in SINTR */
-#define AMR_SMBOX_BUSYFLAG 0x10 /* in SMBOX_BUSY */
-#define AMR_SMBOX_ADDR 0x00 /* -> SMBOX_ENABLE */
-
-/*
- * Initialisation status
- */
-#define AMR_SINIT_ABEND 0xee /* init abnormal terminated */
-#define AMR_SINIT_NOMEM 0xca /* insufficient memory */
-#define AMR_SINIT_CACHEFLUSH 0xbb /* firmware flushing cache */
-#define AMR_SINIT_INPROG 0x11 /* init in progress */
-#define AMR_SINIT_SPINUP 0x22 /* firmware spinning drives */
-#define AMR_SINIT_DONE 0x99 /* init successfully done */
-
-/*
- * I/O primitives
- */
-#define AMR_SPUT_ISTAT(sc, val) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SINTR, val)
-#define AMR_SGET_ISTAT(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SINTR)
-#define AMR_SACK_INTERRUPT(sc) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SCMD, AMR_SCMD_ACKINTR)
-#define AMR_SPOST_COMMAND(sc) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SCMD, AMR_SCMD_POST)
-#define AMR_SGET_MBSTAT(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SMBOX_BUSY)
-#define AMR_SENABLE_INTR(sc) \
- bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE, \
- bus_space_read_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE) | AMR_STOGL_IENABLE)
-#define AMR_SDISABLE_INTR(sc) \
- bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE, \
- bus_space_read_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE) & ~AMR_STOGL_IENABLE)
-#define AMR_SBYTE_SET(sc, reg, val) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, reg, val)
-
-#ifdef AMR_BOARD_INIT
-#define AMR_SRESET(sc) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, 0, 0x80)
-#define AMR_SGET_INITSTATUS(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SMBOX_ENABLE)
-#define AMR_SGET_FAILDRIVE(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SMBOX_ENABLE + 1)
-#define AMR_SGET_INITCHAN(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SMBOX_ENABLE + 2)
-#define AMR_SGET_INITTARG(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SMBOX_ENABLE + 3)
-#endif
-
-#endif /* _KERNEL */
diff --git a/sys/dev/amr/amrvar.h b/sys/dev/amr/amrvar.h
deleted file mode 100644
index ae1a4acbc892..000000000000
--- a/sys/dev/amr/amrvar.h
+++ /dev/null
@@ -1,384 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-3-Clause
- *
- * Copyright (c) 1999,2000 Michael Smith
- * Copyright (c) 2000 BSDi
- * 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.
- *
- * Copyright (c) 2002 Eric Moore
- * Copyright (c) 2002 LSI Logic Corporation
- * 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. The party using or redistributing the source code and binary forms
- * agrees to the disclaimer below and the terms and conditions set forth
- * herein.
- *
- * 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$
- */
-
-#include <geom/geom_disk.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-
-#define LSI_DESC_PCI "LSILogic MegaRAID 1.53"
-
-#ifdef AMR_DEBUG
-# define debug(level, fmt, args...) do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
-# define debug_called(level) do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
-#else
-# define debug(level, fmt, args...) do {} while (0)
-# define debug_called(level) do {} while (0)
-#endif
-#define xdebug(fmt, args...) printf("%s: " fmt "\n", __func__ , ##args)
-
-/*
- * Per-logical-drive datastructure
- */
-struct amr_logdrive
-{
- u_int32_t al_size;
- int al_state;
- int al_properties;
-
- /* synthetic geometry */
- int al_cylinders;
- int al_heads;
- int al_sectors;
-
- /* driver */
- device_t al_disk;
-};
-
-/*
- * Due to the difficulty of using the zone allocator to create a new
- * zone from within a module, we use our own clustering to reduce
- * memory wastage due to allocating lots of these small structures.
- *
- * 16k gives us a little under 200 command structures, which should
- * normally be plenty. We will grab more if we need them.
- */
-
-#define AMR_CMD_CLUSTERSIZE (16 * 1024)
-
-typedef STAILQ_HEAD(, amr_command) ac_qhead_t;
-typedef STAILQ_ENTRY(amr_command) ac_link_t;
-
-union amr_ccb {
- struct amr_passthrough ccb_pthru;
- struct amr_ext_passthrough ccb_epthru;
- uint8_t bytes[128];
-};
-
-/*
- * Per-command control structure.
- */
-struct amr_command
-{
- ac_link_t ac_link;
-
- struct amr_softc *ac_sc;
- u_int8_t ac_slot;
- int ac_status; /* command completion status */
- union {
- struct amr_sgentry *sg32;
- struct amr_sg64entry *sg64;
- } ac_sg;
- u_int32_t ac_sgbusaddr;
- u_int32_t ac_sg64_lo;
- u_int32_t ac_sg64_hi;
- struct amr_mailbox ac_mailbox;
- int ac_flags;
-#define AMR_CMD_DATAIN (1<<0)
-#define AMR_CMD_DATAOUT (1<<1)
-#define AMR_CMD_CCB (1<<2)
-#define AMR_CMD_PRIORITY (1<<4)
-#define AMR_CMD_MAPPED (1<<5)
-#define AMR_CMD_SLEEP (1<<6)
-#define AMR_CMD_BUSY (1<<7)
-#define AMR_CMD_SG64 (1<<8)
-#define AC_IS_SG64(ac) ((ac)->ac_flags & AMR_CMD_SG64)
- u_int ac_retries;
-
- struct bio *ac_bio;
- void (* ac_complete)(struct amr_command *ac);
- void *ac_private;
-
- void *ac_data;
- size_t ac_length;
- bus_dmamap_t ac_dmamap;
- bus_dmamap_t ac_dma64map;
-
- bus_dma_tag_t ac_tag;
- bus_dmamap_t ac_datamap;
- int ac_nsegments;
- uint32_t ac_mb_physaddr;
-
- union amr_ccb *ac_ccb;
- uint32_t ac_ccb_busaddr;
-};
-
-struct amr_command_cluster
-{
- TAILQ_ENTRY(amr_command_cluster) acc_link;
- struct amr_command acc_command[0];
-};
-
-#define AMR_CMD_CLUSTERCOUNT ((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) / \
- sizeof(struct amr_command))
-
-/*
- * Per-controller-instance data
- */
-struct amr_softc
-{
- /* bus attachments */
- device_t amr_dev;
- struct resource *amr_reg; /* control registers */
- bus_space_handle_t amr_bhandle;
- bus_space_tag_t amr_btag;
- bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */
- bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */
- bus_dma_tag_t amr_buffer64_dmat;
- struct resource *amr_irq; /* interrupt */
- void *amr_intr;
-
- /* mailbox */
- volatile struct amr_mailbox *amr_mailbox;
- volatile struct amr_mailbox64 *amr_mailbox64;
- u_int32_t amr_mailboxphys;
- bus_dma_tag_t amr_mailbox_dmat;
- bus_dmamap_t amr_mailbox_dmamap;
-
- /* scatter/gather lists and their controller-visible mappings */
- struct amr_sgentry *amr_sgtable; /* s/g lists */
- struct amr_sg64entry *amr_sg64table; /* 64bit s/g lists */
- u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */
- bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */
- bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */
-
- union amr_ccb *amr_ccb;
- uint32_t amr_ccb_busaddr;
- bus_dma_tag_t amr_ccb_dmat;
- bus_dmamap_t amr_ccb_dmamap;
-
- /* controller limits and features */
- int amr_nextslot; /* Next slot to use for newly allocated commands */
- int amr_maxio; /* maximum number of I/O transactions */
- int amr_maxdrives; /* max number of logical drives */
- int amr_maxchan; /* count of SCSI channels */
-
- /* connected logical drives */
- struct amr_logdrive amr_drive[AMR_MAXLD];
-
- /* controller state */
- int amr_state;
-#define AMR_STATE_OPEN (1<<0)
-#define AMR_STATE_SUSPEND (1<<1)
-#define AMR_STATE_INTEN (1<<2)
-#define AMR_STATE_SHUTDOWN (1<<3)
-#define AMR_STATE_CRASHDUMP (1<<4)
-#define AMR_STATE_QUEUE_FRZN (1<<5)
-#define AMR_STATE_LD_DELETE (1<<6)
-#define AMR_STATE_REMAP_LD (1<<7)
-
- /* per-controller queues */
- struct bio_queue_head amr_bioq; /* pending I/O with no commands */
- ac_qhead_t amr_ready; /* commands ready to be submitted */
- struct amr_command *amr_busycmd[AMR_MAXCMD];
- int amr_busyslots;
- ac_qhead_t amr_freecmds;
- TAILQ_HEAD(,amr_command_cluster) amr_cmd_clusters;
-
- /* CAM attachments for passthrough */
- struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS];
- TAILQ_HEAD(, ccb_hdr) amr_cam_ccbq;
- struct cam_devq *amr_cam_devq;
-
- /* control device */
- struct cdev *amr_dev_t;
- struct mtx amr_list_lock;
-
- /* controller type-specific support */
- int amr_type;
-#define AMR_TYPE_QUARTZ (1<<0)
-#define AMR_IS_QUARTZ(sc) ((sc)->amr_type & AMR_TYPE_QUARTZ)
-#define AMR_TYPE_40LD (1<<1)
-#define AMR_IS_40LD(sc) ((sc)->amr_type & AMR_TYPE_40LD)
-#define AMR_TYPE_SG64 (1<<2)
-#define AMR_IS_SG64(sc) ((sc)->amr_type & AMR_TYPE_SG64)
- int (* amr_submit_command)(struct amr_command *ac);
- int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
- int (*amr_poll_command)(struct amr_command *ac);
- int (*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
- int support_ext_cdb; /* greater than 10 byte cdb support */
-
- /* misc glue */
- device_t amr_pass;
- int (*amr_cam_command)(struct amr_softc *sc, struct amr_command **acp);
- struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */
- int amr_allow_vol_config;
- int amr_linux_no_adapters;
- int amr_ld_del_supported;
- struct mtx amr_hw_lock;
-};
-
-/*
- * Interface between bus connections and driver core.
- */
-extern int amr_attach(struct amr_softc *sc);
-extern void amr_free(struct amr_softc *sc);
-extern int amr_flush(struct amr_softc *sc);
-extern int amr_done(struct amr_softc *sc);
-extern void amr_startio(struct amr_softc *sc);
-
-/*
- * Command buffer allocation.
- */
-extern struct amr_command *amr_alloccmd(struct amr_softc *sc);
-extern void amr_releasecmd(struct amr_command *ac);
-
-/*
- * MegaRAID logical disk driver
- */
-struct amrd_softc
-{
- device_t amrd_dev;
- struct amr_softc *amrd_controller;
- struct amr_logdrive *amrd_drive;
- struct disk *amrd_disk;
- int amrd_unit;
-};
-
-/*
- * Interface between driver core and disk driver (should be using a bus?)
- */
-extern int amr_submit_bio(struct amr_softc *sc, struct bio *bio);
-extern int amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
-extern void amrd_intr(void *data);
-
-/********************************************************************************
- * Enqueue/dequeue functions
- */
-static __inline void
-amr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
-{
-
- bioq_insert_tail(&sc->amr_bioq, bio);
-}
-
-static __inline struct bio *
-amr_dequeue_bio(struct amr_softc *sc)
-{
- struct bio *bio;
-
- if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
- bioq_remove(&sc->amr_bioq, bio);
- return(bio);
-}
-
-static __inline void
-amr_init_qhead(ac_qhead_t *head)
-{
-
- STAILQ_INIT(head);
-}
-
-static __inline void
-amr_enqueue_ready(struct amr_command *ac)
-{
-
- STAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
-}
-
-static __inline void
-amr_requeue_ready(struct amr_command *ac)
-{
-
- STAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
-}
-
-static __inline struct amr_command *
-amr_dequeue_ready(struct amr_softc *sc)
-{
- struct amr_command *ac;
-
- if ((ac = STAILQ_FIRST(&sc->amr_ready)) != NULL)
- STAILQ_REMOVE_HEAD(&sc->amr_ready, ac_link);
- return(ac);
-}
-
-static __inline void
-amr_enqueue_completed(struct amr_command *ac, ac_qhead_t *head)
-{
-
- STAILQ_INSERT_TAIL(head, ac, ac_link);
-}
-
-static __inline struct amr_command *
-amr_dequeue_completed(struct amr_softc *sc, ac_qhead_t *head)
-{
- struct amr_command *ac;
-
- if ((ac = STAILQ_FIRST(head)) != NULL)
- STAILQ_REMOVE_HEAD(head, ac_link);
- return(ac);
-}
-
-static __inline void
-amr_enqueue_free(struct amr_command *ac)
-{
-
- STAILQ_INSERT_HEAD(&ac->ac_sc->amr_freecmds, ac, ac_link);
-}
-
-static __inline struct amr_command *
-amr_dequeue_free(struct amr_softc *sc)
-{
- struct amr_command *ac;
-
- if ((ac = STAILQ_FIRST(&sc->amr_freecmds)) != NULL)
- STAILQ_REMOVE_HEAD(&sc->amr_freecmds, ac_link);
- return(ac);
-}
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index b82193b6eb59..b97036f324cd 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -154,7 +154,6 @@ device ses # Enclosure Services (SES and SAF-TE)
#device ctl # CAM Target Layer
# RAID controllers interfaced to the SCSI subsystem
-device amr # AMI MegaRAID
device arcmsr # Areca SATA II RAID
device ciss # Compaq Smart RAID 5*
device ips # IBM (Adaptec) ServeRAID
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index f34bc403f86e..594c837168bf 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -38,7 +38,6 @@ SUBDIR= \
${_amdsbwd} \
${_amdsmn} \
${_amdtemp} \
- amr \
${_aout} \
${_arcmsr} \
${_allwinner} \
diff --git a/sys/modules/amr/Makefile b/sys/modules/amr/Makefile
deleted file mode 100644
index a17ed246b8c7..000000000000
--- a/sys/modules/amr/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${SRCTOP}/sys/dev/amr
-
-SUBDIR= amr_cam
-.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
-SUBDIR+= amr_linux
-.endif
-
-KMOD= amr
-SRCS= amr.c amr_pci.c amr_disk.c device_if.h bus_if.h pci_if.h
-
-# Enable a questionable optimisation for newer adapters
-#CFLAGS+= -DAMR_QUARTZ_GOFASTER
-
-# Debugging
-#CFLAGS+= -DAMR_DEBUG=3
-
-EXPORT_SYMS= YES
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/amr/amr_cam/Makefile b/sys/modules/amr/amr_cam/Makefile
deleted file mode 100644
index ab7da0a331ec..000000000000
--- a/sys/modules/amr/amr_cam/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${SRCTOP}/sys/dev/amr
-
-KMOD= amr_cam
-SRCS= amr_cam.c device_if.h bus_if.h
-SRCS+= opt_cam.h opt_scsi.h
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/amr/amr_linux/Makefile b/sys/modules/amr/amr_linux/Makefile
deleted file mode 100644
index b5cf493098d9..000000000000
--- a/sys/modules/amr/amr_linux/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${SRCTOP}/sys/dev/amr
-
-KMOD= amr_linux
-SRCS= amr_linux.c device_if.h bus_if.h
-
-.include <bsd.kmod.mk>