amr: remove

Belatedly remove amr(4). It was slated to depart before 13.0 but was
overlooked until now.

Sponsored by:		Netflix
Relnotes:		yes
Reviewed by:		scottl
Differential Revision:	https://reviews.freebsd.org/D33113
This commit is contained in:
Warner Losh 2021-11-25 00:20:51 -07:00
parent 399188a2c6
commit 60de2867c9
19 changed files with 0 additions and 5752 deletions

View File

@ -1,246 +0,0 @@
.\"
.\" Copyright (c) 2000 Jeroen Ruigrok van der Werven
.\" 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. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd March 29, 2006
.Dt AMR 4
.Os
.Sh NAME
.Nm amr
.Nd MegaRAID SCSI/ATA/SATA RAID driver
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following lines in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device pci"
.Cd "device scbus"
.Cd "device amr"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
amr_load="YES"
.Ed
.Sh DEPRECATION NOTICE
The
.Nm
driver is not present in
.Fx 13.0 .
.Sh DESCRIPTION
The
.Nm
driver provides support for LSI Logic MegaRAID SCSI, ATA and SATA
RAID controllers and legacy American Megatrends MegaRAID
SCSI RAID controllers, including models relabeled
and sold by Dell and Hewlett-Packard.
.Pp
LSI MegaRAID SAS controllers are supported by
.Xr mfi 4
and will not work with this driver.
.Sh HARDWARE
Controllers supported by the
.Nm
driver include:
.Pp
.Bl -bullet -compact
.It
MegaRAID SATA 150-4
.It
MegaRAID SATA 150-6
.It
MegaRAID SATA 300-4X
.It
MegaRAID SATA 300-8X
.It
MegaRAID SCSI 320-1E
.It
MegaRAID SCSI 320-2E
.It
MegaRAID SCSI 320-4E
.It
MegaRAID SCSI 320-0X
.It
MegaRAID SCSI 320-2X
.It
MegaRAID SCSI 320-4X
.It
MegaRAID SCSI 320-0
.It
MegaRAID SCSI 320-1
.It
MegaRAID SCSI 320-2
.It
MegaRAID SCSI 320-4
.It
MegaRAID Series 418
.It
MegaRAID i4 133 RAID
.It
MegaRAID Elite 1500 (Series 467)
.It
MegaRAID Elite 1600 (Series 493)
.It
MegaRAID Elite 1650 (Series 4xx)
.It
MegaRAID Enterprise 1200 (Series 428)
.It
MegaRAID Enterprise 1300 (Series 434)
.It
MegaRAID Enterprise 1400 (Series 438)
.It
MegaRAID Enterprise 1500 (Series 467)
.It
MegaRAID Enterprise 1600 (Series 471)
.It
MegaRAID Express 100 (Series 466WS)
.It
MegaRAID Express 200 (Series 466)
.It
MegaRAID Express 300 (Series 490)
.It
MegaRAID Express 500 (Series 475)
.It
Dell PERC
.It
Dell PERC 2/SC
.It
Dell PERC 2/DC
.It
Dell PERC 3/DCL
.It
Dell PERC 3/QC
.It
Dell PERC 4/DC
.It
Dell PERC 4/IM
.It
Dell PERC 4/SC
.It
Dell PERC 4/Di
.It
Dell PERC 4e/DC
.It
Dell PERC 4e/Di
.It
Dell PERC 4e/Si
.It
Dell PERC 4ei
.It
HP NetRAID-1/Si
.It
HP NetRAID-3/Si (D4943A)
.It
HP Embedded NetRAID
.It
Intel RAID Controller SRCS16
.It
Intel RAID Controller SRCU42X
.El
.Sh DIAGNOSTICS
.Ss Driver initialisation/shutdown phase
.Bl -diag
.It amr%d: memory window not available
.It amr%d: I/O window not available
.Pp
The PCI BIOS did not allocate resources necessary for the correct operation of
the controller.
The driver cannot attach to this controller.
.It amr%d: busmaster bit not set, enabling
.Pp
The PCI BIOS did not enable busmaster DMA,
which is required for the correct operation of the controller.
The driver has enabled this bit and initialisation will proceed.
.It amr%d: can't allocate register window
.It amr%d: can't allocate interrupt
.It amr%d: can't set up interrupt
.It amr%d: can't allocate parent DMA tag
.It amr%d: can't allocate buffer DMA tag
.It amr%d: can't allocate scatter/gather DMA tag
.It amr%d: can't allocate s/g table
.It amr%d: can't allocate mailbox tag
.It amr%d: can't allocate mailbox memory
.Pp
A resource allocation error occurred while initialising the driver;
initialisation has failed and the driver will not attach to this controller.
.It amr%d: can't obtain configuration data from controller
.It amr%d: can't obtain product data from controller
.Pp
The driver was unable to obtain vital configuration data from the controller.
Initialisation has failed and the driver will not attach to this controller.
.It amr%d: can't establish configuration hook
.It amr%d: can't scan controller for drives
.Pp
The scan for logical drives managed by the controller failed.
No drives will be attached.
.It amr%d: device_add_child failed
.It amr%d: bus_generic_attach returned %d
.Pp
Creation of the logical drive instances failed;
attachment of one or more logical drives may have been aborted.
.It amr%d: flushing cache...
.Pp
The controller cache is being flushed prior to shutdown or detach.
.El
.Ss Operational diagnostics
.Bl -diag
.It amr%d: I/O beyond end of unit (%u,%d > %u)
.Pp
A partitioning error or disk corruption has caused an I/O request
beyond the end of the logical drive.
This may also occur if FlexRAID Virtual Sizing is enabled and
an I/O operation is attempted on a portion of the virtual drive
beyond the actual capacity available.
.It amr%d: polled command timeout
.Pp
An initialisation command timed out.
The initialisation process may fail as a result.
.It amr%d: bad slot %d completed
.Pp
The controller reported completion of a command that the driver did not issue.
This may result in data corruption,
and suggests a hardware or firmware problem with the system or controller.
.It amr%d: I/O error - %x
.Pp
An I/O error has occurred.
.El
.Sh SEE ALSO
.Xr cd 4 ,
.Xr da 4 ,
.Xr mfi 4 ,
.Xr sa 4 ,
.Xr scsi 4
.Sh AUTHORS
.An -nosplit
The
.Nm
driver was written by
.An Mike Smith Aq Mt msmith@FreeBSD.org .
.Pp
This manual page was written by
.An Mike Smith Aq Mt msmith@FreeBSD.org
and
.An Jeroen Ruigrok van der Werven Aq Mt asmodai@FreeBSD.org .

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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);
}

View File

@ -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

View File

@ -38,7 +38,6 @@ SUBDIR= \
${_amdsbwd} \
${_amdsmn} \
${_amdtemp} \
amr \
${_aout} \
${_arcmsr} \
${_allwinner} \

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -1,21 +0,0 @@
# Doxyfile 1.5.2
# $FreeBSD$
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = "FreeBSD kernel AMR device code"
OUTPUT_DIRECTORY = $(DOXYGEN_DEST_PATH)/dev_amr/
EXTRACT_ALL = YES # for undocumented src, no warnings enabled
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = $(DOXYGEN_SRC_PATH)/dev/amr/ \
$(NOTREVIEWED)
GENERATE_TAGFILE = dev_amr/dev_amr.tag
@INCLUDE_PATH = $(DOXYGEN_INCLUDE_PATH)
@INCLUDE = common-Doxyfile