Driver 'aacraid' added. Supports Adaptec by PMC RAID controller families Series 6, 7, 8 and upcoming products. Older Adaptec RAID controller families are supported by the 'aac' driver.
Approved by: scottl (mentor)
This commit is contained in:
parent
3f61f926ea
commit
dce93cd06d
@ -4,6 +4,7 @@
|
||||
.include <bsd.own.mk>
|
||||
|
||||
MAN= aac.4 \
|
||||
aacraid.4 \
|
||||
acpi.4 \
|
||||
${_acpi_asus.4} \
|
||||
${_acpi_asus_wmi.4} \
|
||||
|
139
share/man/man4/aacraid.4
Normal file
139
share/man/man4/aacraid.4
Normal file
@ -0,0 +1,139 @@
|
||||
.\" Copyright (c) 2013 Achim Leubner
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd April 09, 2013
|
||||
.Dt AACRAID 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm aacraid
|
||||
.Nd Adaptec AACRAID Controller 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 aacraid
|
||||
.Pp
|
||||
To compile in debugging code:
|
||||
.Cd options AACRAID_DEBUG=N
|
||||
.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
|
||||
aacraid_load="YES"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for the Adaptec by PMC RAID controllers,
|
||||
including Series 6/7/8 and upcoming families.
|
||||
.Pp
|
||||
The RAID containers are handled via the
|
||||
.Nm aacraidp0
|
||||
bus.
|
||||
The physical buses are represented by the
|
||||
.Nm aacraidp?
|
||||
devices (beginning with aacraidp1). These devices enable the
|
||||
SCSI pass-thru interface and allows devices connected
|
||||
to the card such as CD-ROMs to be available via the CAM
|
||||
.Xr scsi 4
|
||||
subsystem.
|
||||
Note that not all cards allow this interface to be enabled.
|
||||
.Pp
|
||||
The
|
||||
.Pa /dev/aacraid?
|
||||
device nodes provide access to the management interface of the controller.
|
||||
One node exists per installed card.
|
||||
If the kernel is compiled with the
|
||||
.Dv COMPAT_LINUX
|
||||
option, or the
|
||||
.Pa aacraid_linux.ko
|
||||
and
|
||||
.Pa linux.ko
|
||||
modules are loaded, the
|
||||
Linux-compatible
|
||||
.Xr ioctl 2
|
||||
interface for the management device will be enabled and will allow
|
||||
Linux-based management applications to control the card.
|
||||
.Sh HARDWARE
|
||||
Controllers supported by the
|
||||
.Nm
|
||||
driver include:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
Adaptec ASR-6405(T|E)
|
||||
.It
|
||||
Adaptec ASR-6445
|
||||
.It
|
||||
Adaptec ASR-6805(T|E|Q|TQ)
|
||||
.It
|
||||
Adaptec ASR-7085
|
||||
.It
|
||||
Adaptec ASR-7805(Q)
|
||||
.It
|
||||
Adaptec ASR-70165
|
||||
.It
|
||||
Adaptec ASR-71605(E|Q)
|
||||
.It
|
||||
Adaptec ASR-71685
|
||||
.It
|
||||
Adaptec ASR-72405
|
||||
.It
|
||||
Adaptec Series 8 cards
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /boot/kernel/aacraid.ko -compact
|
||||
.It Pa /dev/aacraid?
|
||||
aacraid management interface
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
Compiling with
|
||||
.Dv AACRAID_DEBUG
|
||||
set to a number between 0 and 3
|
||||
will enable increasingly verbose debug messages.
|
||||
.Pp
|
||||
The adapter can send status and alert messages asynchronously
|
||||
to the driver.
|
||||
These messages are printed on the system console,
|
||||
and are also queued for retrieval by a management application.
|
||||
.Sh SEE ALSO
|
||||
.Xr kld 4 ,
|
||||
.Xr linux 4 ,
|
||||
.Xr scsi 4 ,
|
||||
.Xr kldload 8
|
||||
.Sh AUTHORS
|
||||
.An Achim Leubner
|
||||
.Aq achim@FreeBSD.org
|
||||
.An Ed Maste
|
||||
.Aq emaste@FreeBSD.org
|
||||
.An Scott Long
|
||||
.Aq scottl@FreeBSD.org
|
||||
.Sh BUGS
|
||||
.Pp
|
||||
The controller is not actually paused on suspend/resume.
|
@ -158,6 +158,7 @@ device tws # LSI 3ware 9750 SATA+SAS 6Gb/s RAID controller
|
||||
# RAID controllers
|
||||
device aac # Adaptec FSA RAID
|
||||
device aacp # SCSI passthrough for aac (requires CAM)
|
||||
device aacraid # Adaptec by PMC RAID
|
||||
device ida # Compaq Smart RAID
|
||||
device mfi # LSI MegaRAID SAS
|
||||
device mlx # Mylex DAC960 family
|
||||
|
@ -405,6 +405,10 @@ device stg
|
||||
device aac
|
||||
device aacp # SCSI Passthrough interface (optional, CAM required)
|
||||
|
||||
#
|
||||
# Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming families
|
||||
device aacraid # Container interface, CAM required
|
||||
|
||||
#
|
||||
# Highpoint RocketRAID 27xx.
|
||||
device hpt27xx
|
||||
|
@ -573,6 +573,11 @@ dev/aac/aac_debug.c optional aac
|
||||
dev/aac/aac_disk.c optional aac
|
||||
dev/aac/aac_linux.c optional aac compat_linux
|
||||
dev/aac/aac_pci.c optional aac pci
|
||||
dev/aacraid/aacraid.c optional aacraid
|
||||
dev/aacraid/aacraid_cam.c optional aacraid scbus
|
||||
dev/aacraid/aacraid_debug.c optional aacraid
|
||||
dev/aacraid/aacraid_linux.c optional aacraid compat_linux
|
||||
dev/aacraid/aacraid_pci.c optional aacraid pci
|
||||
dev/acpi_support/acpi_wmi.c optional acpi_wmi acpi
|
||||
dev/acpi_support/acpi_asus.c optional acpi_asus acpi
|
||||
dev/acpi_support/acpi_asus_wmi.c optional acpi_asus_wmi acpi
|
||||
|
@ -31,6 +31,7 @@
|
||||
# opt_<name-of-option-in-lower-case>.h
|
||||
|
||||
AAC_DEBUG opt_aac.h
|
||||
AACRAID_DEBUG opt_aacraid.h
|
||||
AHC_ALLOW_MEMIO opt_aic7xxx.h
|
||||
AHC_TMODE_ENABLE opt_aic7xxx.h
|
||||
AHC_DUMP_EEPROM opt_aic7xxx.h
|
||||
|
3501
sys/dev/aacraid/aacraid.c
Normal file
3501
sys/dev/aacraid/aacraid.c
Normal file
File diff suppressed because it is too large
Load Diff
1400
sys/dev/aacraid/aacraid_cam.c
Normal file
1400
sys/dev/aacraid/aacraid_cam.c
Normal file
File diff suppressed because it is too large
Load Diff
715
sys/dev/aacraid/aacraid_debug.c
Normal file
715
sys/dev/aacraid/aacraid_debug.c
Normal file
@ -0,0 +1,715 @@
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006-2010 Adaptec, Inc.
|
||||
* Copyright (c) 2010-2012 PMC-Sierra, Inc.
|
||||
* 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$");
|
||||
|
||||
/*
|
||||
* Debugging support.
|
||||
*/
|
||||
#include "opt_aacraid.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <machine/resource.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/aacraid/aacraid_reg.h>
|
||||
#include <sys/aac_ioctl.h>
|
||||
#include <dev/aacraid/aacraid_var.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/resource.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#include <dev/aacraid/aacraid_debug.h>
|
||||
|
||||
#ifdef AACRAID_DEBUG
|
||||
/*
|
||||
* Dump the command queue indices
|
||||
*/
|
||||
void
|
||||
aacraid_print_queues(struct aac_softc *sc)
|
||||
{
|
||||
device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
|
||||
sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
|
||||
device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
|
||||
sc->aac_qstat[AACQ_READY].q_length,
|
||||
sc->aac_qstat[AACQ_READY].q_max);
|
||||
device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
|
||||
sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a FIB
|
||||
*/
|
||||
void
|
||||
aacraid_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
|
||||
{
|
||||
if (fib == NULL) {
|
||||
device_printf(sc->aac_dev,
|
||||
"aac_print_fib called with NULL fib\n");
|
||||
return;
|
||||
}
|
||||
device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib);
|
||||
device_printf(sc->aac_dev, " XferState %b\n", fib->Header.XferState,
|
||||
"\20"
|
||||
"\1HOSTOWNED"
|
||||
"\2ADAPTEROWNED"
|
||||
"\3INITIALISED"
|
||||
"\4EMPTY"
|
||||
"\5FROMPOOL"
|
||||
"\6FROMHOST"
|
||||
"\7FROMADAP"
|
||||
"\10REXPECTED"
|
||||
"\11RNOTEXPECTED"
|
||||
"\12DONEADAP"
|
||||
"\13DONEHOST"
|
||||
"\14HIGH"
|
||||
"\15NORM"
|
||||
"\16ASYNC"
|
||||
"\17PAGEFILEIO"
|
||||
"\20SHUTDOWN"
|
||||
"\21LAZYWRITE"
|
||||
"\22ADAPMICROFIB"
|
||||
"\23BIOSFIB"
|
||||
"\24FAST_RESPONSE"
|
||||
"\25APIFIB\n");
|
||||
device_printf(sc->aac_dev, " Command %d\n", fib->Header.Command);
|
||||
device_printf(sc->aac_dev, " StructType %d\n",
|
||||
fib->Header.StructType);
|
||||
device_printf(sc->aac_dev, " Size %d\n", fib->Header.Size);
|
||||
device_printf(sc->aac_dev, " SenderSize %d\n",
|
||||
fib->Header.SenderSize);
|
||||
device_printf(sc->aac_dev, " SenderAddress 0x%x\n",
|
||||
fib->Header.SenderFibAddress);
|
||||
device_printf(sc->aac_dev, " RcvrAddress 0x%x\n",
|
||||
fib->Header.u.ReceiverFibAddress);
|
||||
device_printf(sc->aac_dev, " Handle 0x%x\n",
|
||||
fib->Header.Handle);
|
||||
switch(fib->Header.Command) {
|
||||
case ContainerCommand:
|
||||
{
|
||||
struct aac_blockread *br;
|
||||
struct aac_blockwrite *bw;
|
||||
struct aac_sg_table *sg;
|
||||
int i;
|
||||
|
||||
br = (struct aac_blockread*)fib->data;
|
||||
bw = (struct aac_blockwrite*)fib->data;
|
||||
sg = NULL;
|
||||
|
||||
if (br->Command == VM_CtBlockRead) {
|
||||
device_printf(sc->aac_dev,
|
||||
" BlockRead: container %d 0x%x/%d\n",
|
||||
br->ContainerId, br->BlockNumber,
|
||||
br->ByteCount);
|
||||
sg = &br->SgMap;
|
||||
}
|
||||
if (bw->Command == VM_CtBlockWrite) {
|
||||
device_printf(sc->aac_dev,
|
||||
" BlockWrite: container %d 0x%x/%d "
|
||||
"(%s)\n", bw->ContainerId,
|
||||
bw->BlockNumber, bw->ByteCount,
|
||||
bw->Stable == CSTABLE ? "stable" :
|
||||
"unstable");
|
||||
sg = &bw->SgMap;
|
||||
}
|
||||
if (sg != NULL) {
|
||||
device_printf(sc->aac_dev,
|
||||
" %d s/g entries\n", sg->SgCount);
|
||||
for (i = 0; i < sg->SgCount; i++)
|
||||
device_printf(sc->aac_dev, " 0x%08x/%d\n",
|
||||
sg->SgEntry[i].SgAddress,
|
||||
sg->SgEntry[i].SgByteCount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
device_printf(sc->aac_dev, " %16D\n", fib->data, " ");
|
||||
device_printf(sc->aac_dev, " %16D\n", fib->data + 16, " ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Describe an AIF we have received.
|
||||
*/
|
||||
void
|
||||
aacraid_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
|
||||
{
|
||||
switch(aif->command) {
|
||||
case AifCmdEventNotify:
|
||||
device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
|
||||
switch(aif->data.EN.type) {
|
||||
case AifEnGeneric: /* Generic notification */
|
||||
device_printf(sc->aac_dev, "(Generic) %.*s\n",
|
||||
(int)sizeof(aif->data.EN.data.EG),
|
||||
aif->data.EN.data.EG.text);
|
||||
break;
|
||||
case AifEnTaskComplete: /* Task has completed */
|
||||
device_printf(sc->aac_dev, "(TaskComplete)\n");
|
||||
break;
|
||||
case AifEnConfigChange: /* Adapter configuration change
|
||||
* occurred */
|
||||
device_printf(sc->aac_dev, "(ConfigChange)\n");
|
||||
break;
|
||||
case AifEnContainerChange: /* Adapter specific container
|
||||
* configuration change */
|
||||
device_printf(sc->aac_dev, "(ContainerChange) "
|
||||
"container %d,%d\n",
|
||||
aif->data.EN.data.ECC.container[0],
|
||||
aif->data.EN.data.ECC.container[1]);
|
||||
break;
|
||||
case AifEnDeviceFailure: /* SCSI device failed */
|
||||
device_printf(sc->aac_dev, "(DeviceFailure) "
|
||||
"handle %d\n",
|
||||
aif->data.EN.data.EDF.deviceHandle);
|
||||
break;
|
||||
case AifEnMirrorFailover: /* Mirror failover started */
|
||||
device_printf(sc->aac_dev, "(MirrorFailover) "
|
||||
"container %d failed, "
|
||||
"migrating from slice %d to %d\n",
|
||||
aif->data.EN.data.EMF.container,
|
||||
aif->data.EN.data.EMF.failedSlice,
|
||||
aif->data.EN.data.EMF.creatingSlice);
|
||||
break;
|
||||
case AifEnContainerEvent: /* Significant container
|
||||
* event */
|
||||
device_printf(sc->aac_dev, "(ContainerEvent) "
|
||||
"container %d event "
|
||||
"%d\n", aif->data.EN.data.ECE.container,
|
||||
aif->data.EN.data.ECE.eventType);
|
||||
break;
|
||||
case AifEnFileSystemChange: /* File system changed */
|
||||
device_printf(sc->aac_dev, "(FileSystemChange)\n");
|
||||
break;
|
||||
case AifEnConfigPause: /* Container pause event */
|
||||
device_printf(sc->aac_dev, "(ConfigPause)\n");
|
||||
break;
|
||||
case AifEnConfigResume: /* Container resume event */
|
||||
device_printf(sc->aac_dev, "(ConfigResume)\n");
|
||||
break;
|
||||
case AifEnFailoverChange: /* Failover space assignment
|
||||
* changed */
|
||||
device_printf(sc->aac_dev, "(FailoverChange)\n");
|
||||
break;
|
||||
case AifEnRAID5RebuildDone: /* RAID5 rebuild finished */
|
||||
device_printf(sc->aac_dev, "(RAID5RebuildDone)\n");
|
||||
break;
|
||||
case AifEnEnclosureManagement: /* Enclosure management event */
|
||||
device_printf(sc->aac_dev, "(EnclosureManagement) "
|
||||
"EMPID %d unit %d "
|
||||
"event %d\n", aif->data.EN.data.EEE.empID,
|
||||
aif->data.EN.data.EEE.unitID,
|
||||
aif->data.EN.data.EEE.eventType);
|
||||
break;
|
||||
case AifEnBatteryEvent: /* Significant NV battery
|
||||
* event */
|
||||
device_printf(sc->aac_dev, "(BatteryEvent) %d "
|
||||
"(state was %d, is %d\n",
|
||||
aif->data.EN.data.EBE.transition_type,
|
||||
aif->data.EN.data.EBE.current_state,
|
||||
aif->data.EN.data.EBE.prior_state);
|
||||
break;
|
||||
case AifEnAddContainer: /* A new container was
|
||||
* created. */
|
||||
device_printf(sc->aac_dev, "(AddContainer)\n");
|
||||
break;
|
||||
case AifEnDeleteContainer: /* A container was deleted. */
|
||||
device_printf(sc->aac_dev, "(DeleteContainer)\n");
|
||||
break;
|
||||
case AifEnBatteryNeedsRecond: /* The battery needs
|
||||
* reconditioning */
|
||||
device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
|
||||
break;
|
||||
case AifEnClusterEvent: /* Some cluster event */
|
||||
device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
|
||||
aif->data.EN.data.ECLE.eventType);
|
||||
break;
|
||||
case AifEnDiskSetEvent: /* A disk set event occured. */
|
||||
device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
|
||||
"diskset %jd creator %jd\n",
|
||||
aif->data.EN.data.EDS.eventType,
|
||||
(intmax_t)aif->data.EN.data.EDS.DsNum,
|
||||
(intmax_t)aif->data.EN.data.EDS.CreatorId);
|
||||
break;
|
||||
case AifDenMorphComplete: /* A morph operation
|
||||
* completed */
|
||||
device_printf(sc->aac_dev, "(MorphComplete)\n");
|
||||
break;
|
||||
case AifDenVolumeExtendComplete: /* A volume expand operation
|
||||
* completed */
|
||||
device_printf(sc->aac_dev, "(VolumeExtendComplete)\n");
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->aac_dev, "(%d)\n", aif->data.EN.type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AifCmdJobProgress:
|
||||
{
|
||||
char *status;
|
||||
switch(aif->data.PR[0].status) {
|
||||
case AifJobStsSuccess:
|
||||
status = "success"; break;
|
||||
case AifJobStsFinished:
|
||||
status = "finished"; break;
|
||||
case AifJobStsAborted:
|
||||
status = "aborted"; break;
|
||||
case AifJobStsFailed:
|
||||
status = "failed"; break;
|
||||
case AifJobStsSuspended:
|
||||
status = "suspended"; break;
|
||||
case AifJobStsRunning:
|
||||
status = "running"; break;
|
||||
default:
|
||||
status = "unknown status"; break;
|
||||
}
|
||||
|
||||
device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
|
||||
aif->seqNumber, status,
|
||||
aif->data.PR[0].currentTick,
|
||||
aif->data.PR[0].finalTick);
|
||||
switch(aif->data.PR[0].jd.type) {
|
||||
case AifJobScsiZero: /* SCSI dev clear operation */
|
||||
device_printf(sc->aac_dev, "(ScsiZero) handle %d\n",
|
||||
aif->data.PR[0].jd.client.scsi_dh);
|
||||
break;
|
||||
case AifJobScsiVerify: /* SCSI device Verify operation
|
||||
* NO REPAIR */
|
||||
device_printf(sc->aac_dev, "(ScsiVerify) handle %d\n",
|
||||
aif->data.PR[0].jd.client.scsi_dh);
|
||||
break;
|
||||
case AifJobScsiExercise: /* SCSI device Exercise
|
||||
* operation */
|
||||
device_printf(sc->aac_dev, "(ScsiExercise) handle %d\n",
|
||||
aif->data.PR[0].jd.client.scsi_dh);
|
||||
break;
|
||||
case AifJobScsiVerifyRepair: /* SCSI device Verify operation
|
||||
* WITH repair */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ScsiVerifyRepair) handle %d\n",
|
||||
aif->data.PR[0].jd.client.scsi_dh);
|
||||
break;
|
||||
case AifJobCtrZero: /* Container clear operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerZero) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrCopy: /* Container copy operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerCopy) container %d to %d\n",
|
||||
aif->data.PR[0].jd.client.container.src,
|
||||
aif->data.PR[0].jd.client.container.dst);
|
||||
break;
|
||||
case AifJobCtrCreateMirror: /* Container Create Mirror
|
||||
* operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerCreateMirror) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
/* XXX two containers? */
|
||||
break;
|
||||
case AifJobCtrMergeMirror: /* Container Merge Mirror
|
||||
* operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerMergeMirror) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
/* XXX two containers? */
|
||||
break;
|
||||
case AifJobCtrScrubMirror: /* Container Scrub Mirror
|
||||
* operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerScrubMirror) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrRebuildRaid5: /* Container Rebuild Raid5
|
||||
* operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerRebuildRaid5) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrScrubRaid5: /* Container Scrub Raid5
|
||||
* operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerScrubRaid5) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrMorph: /* Container morph operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerMorph) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
/* XXX two containers? */
|
||||
break;
|
||||
case AifJobCtrPartCopy: /* Container Partition copy
|
||||
* operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerPartCopy) container %d to "
|
||||
"%d\n",
|
||||
aif->data.PR[0].jd.client.container.src,
|
||||
aif->data.PR[0].jd.client.container.dst);
|
||||
break;
|
||||
case AifJobCtrRebuildMirror: /* Container Rebuild Mirror
|
||||
* operation */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerRebuildMirror) container "
|
||||
"%d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrCrazyCache: /* crazy cache */
|
||||
device_printf(sc->aac_dev,
|
||||
"(ContainerCrazyCache) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
/* XXX two containers? */
|
||||
break;
|
||||
case AifJobFsCreate: /* File System Create
|
||||
* operation */
|
||||
device_printf(sc->aac_dev, "(FsCreate)\n");
|
||||
break;
|
||||
case AifJobFsVerify: /* File System Verify
|
||||
* operation */
|
||||
device_printf(sc->aac_dev, "(FsVerivy)\n");
|
||||
break;
|
||||
case AifJobFsExtend: /* File System Extend
|
||||
* operation */
|
||||
device_printf(sc->aac_dev, "(FsExtend)\n");
|
||||
break;
|
||||
case AifJobApiFormatNTFS: /* Format a drive to NTFS */
|
||||
device_printf(sc->aac_dev, "(FormatNTFS)\n");
|
||||
break;
|
||||
case AifJobApiFormatFAT: /* Format a drive to FAT */
|
||||
device_printf(sc->aac_dev, "(FormatFAT)\n");
|
||||
break;
|
||||
case AifJobApiUpdateSnapshot: /* update the read/write half
|
||||
* of a snapshot */
|
||||
device_printf(sc->aac_dev, "(UpdateSnapshot)\n");
|
||||
break;
|
||||
case AifJobApiFormatFAT32: /* Format a drive to FAT32 */
|
||||
device_printf(sc->aac_dev, "(FormatFAT32)\n");
|
||||
break;
|
||||
case AifJobCtlContinuousCtrVerify: /* Adapter operation */
|
||||
device_printf(sc->aac_dev, "(ContinuousCtrVerify)\n");
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->aac_dev, "(%d)\n",
|
||||
aif->data.PR[0].jd.type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AifCmdAPIReport:
|
||||
device_printf(sc->aac_dev, "APIReport (%d)\n", aif->seqNumber);
|
||||
break;
|
||||
case AifCmdDriverNotify:
|
||||
device_printf(sc->aac_dev, "DriverNotify (%d)\n",
|
||||
aif->seqNumber);
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->aac_dev, "AIF %d (%d)\n", aif->command,
|
||||
aif->seqNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* AACRAID_DEBUG */
|
||||
|
||||
/*
|
||||
* Debug flags to be put into the HBA flags field when initialized
|
||||
*/
|
||||
const unsigned long aacraid_debug_flags = /* Variable to setup with above flags. */
|
||||
/* HBA_FLAGS_DBG_KERNEL_PRINT_B | */
|
||||
HBA_FLAGS_DBG_FW_PRINT_B |
|
||||
/* HBA_FLAGS_DBG_FUNCTION_ENTRY_B | */
|
||||
HBA_FLAGS_DBG_FUNCTION_EXIT_B |
|
||||
HBA_FLAGS_DBG_ERROR_B |
|
||||
HBA_FLAGS_DBG_INIT_B |
|
||||
/* HBA_FLAGS_DBG_OS_COMMANDS_B | */
|
||||
/* HBA_FLAGS_DBG_SCAN_B | */
|
||||
/* HBA_FLAGS_DBG_COALESCE_B | */
|
||||
/* HBA_FLAGS_DBG_IOCTL_COMMANDS_B | */
|
||||
/* HBA_FLAGS_DBG_SYNC_COMMANDS_B | */
|
||||
HBA_FLAGS_DBG_COMM_B |
|
||||
/* HBA_FLAGS_DBG_AIF_B | */
|
||||
/* HBA_FLAGS_DBG_CSMI_COMMANDS_B | */
|
||||
HBA_FLAGS_DBG_DEBUG_B |
|
||||
/* HBA_FLAGS_DBG_FLAGS_MASK | */
|
||||
0;
|
||||
|
||||
int aacraid_get_fw_debug_buffer(struct aac_softc *sc)
|
||||
{
|
||||
u_int32_t MonDriverBufferPhysAddrLow = 0;
|
||||
u_int32_t MonDriverBufferPhysAddrHigh = 0;
|
||||
u_int32_t MonDriverBufferSize = 0;
|
||||
u_int32_t MonDriverHeaderSize = 0;
|
||||
|
||||
/*
|
||||
* Get the firmware print buffer parameters from the firmware
|
||||
* If the command was successful map in the address.
|
||||
*/
|
||||
if (!aacraid_sync_command(sc, AAC_MONKER_GETDRVPROP, 0, 0, 0, 0, NULL, NULL)) {
|
||||
MonDriverBufferPhysAddrLow = AAC_GET_MAILBOX(sc, 1);
|
||||
MonDriverBufferPhysAddrHigh = AAC_GET_MAILBOX(sc, 2);
|
||||
MonDriverBufferSize = AAC_GET_MAILBOX(sc, 3);
|
||||
MonDriverHeaderSize = AAC_GET_MAILBOX(sc, 4);
|
||||
if (MonDriverBufferSize) {
|
||||
unsigned long Offset = MonDriverBufferPhysAddrLow
|
||||
- rman_get_start(sc->aac_regs_res1);
|
||||
|
||||
/*
|
||||
* See if the address is already mapped in and if so set it up
|
||||
* from the base address
|
||||
*/
|
||||
if ((MonDriverBufferPhysAddrHigh == 0) &&
|
||||
(Offset + MonDriverBufferSize <
|
||||
rman_get_size(sc->aac_regs_res1))) {
|
||||
sc->DebugOffset = Offset;
|
||||
sc->DebugHeaderSize = MonDriverHeaderSize;
|
||||
sc->FwDebugBufferSize = MonDriverBufferSize;
|
||||
sc->FwDebugFlags = 0;
|
||||
sc->DebugFlags = aacraid_debug_flags;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The GET_DRIVER_BUFFER_PROPERTIES command failed
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PRINT_TIMEOUT 250000 /* 1/4 second */
|
||||
|
||||
void aacraid_fw_printf(struct aac_softc *sc, unsigned long PrintFlags, const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
u_int32_t Count, i;
|
||||
char PrintBuffer_P[PRINT_BUFFER_SIZE];
|
||||
unsigned long PrintType;
|
||||
|
||||
PrintType = PrintFlags &
|
||||
~(HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B);
|
||||
if (((PrintType!=0) && (sc!=NULL) && ((sc->DebugFlags & PrintType)==0))
|
||||
|| ((sc!=NULL) && (sc->DebugFlags
|
||||
& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B)) == 0))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Set up parameters and call sprintf function to format the data
|
||||
*/
|
||||
va_start(args, fmt);
|
||||
vsprintf(PrintBuffer_P, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
/*
|
||||
* Make sure the HBA structure has been passed in for this section
|
||||
*/
|
||||
if ((sc != NULL) && (sc->FwDebugBufferSize)) {
|
||||
/*
|
||||
* If we are set up for a Firmware print
|
||||
*/
|
||||
if ((sc->DebugFlags & HBA_FLAGS_DBG_FW_PRINT_B)
|
||||
&& ((PrintFlags
|
||||
& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
|
||||
!= HBA_FLAGS_DBG_KERNEL_PRINT_B)) {
|
||||
/*
|
||||
* Make sure the string size is within boundaries
|
||||
*/
|
||||
Count = strlen(PrintBuffer_P);
|
||||
if (Count > sc->FwDebugBufferSize)
|
||||
Count = (u_int16_t)sc->FwDebugBufferSize;
|
||||
|
||||
/*
|
||||
* Wait for no more than PRINT_TIMEOUT for the previous
|
||||
* message length to clear (the handshake).
|
||||
*/
|
||||
for (i = 0; i < PRINT_TIMEOUT; ++i) {
|
||||
if (!AAC_MEM1_GETREG4(sc,
|
||||
sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
|
||||
break;
|
||||
}
|
||||
DELAY(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the Length is clear, copy over the message, the
|
||||
* flags, and the length. Make sure the length is the
|
||||
* last because that is the signal for the Firmware to
|
||||
* pick it up.
|
||||
*/
|
||||
if (!AAC_MEM1_GETREG4(sc,
|
||||
sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
|
||||
for (i = 0; i < Count; ++i) {
|
||||
AAC_MEM1_SETREG1(sc, sc->DebugOffset + sc->DebugHeaderSize + i,
|
||||
PrintBuffer_P[i]);
|
||||
}
|
||||
AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_FLAGS_OFFSET,
|
||||
sc->FwDebugFlags);
|
||||
AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET,
|
||||
Count);
|
||||
} else
|
||||
sc->DebugFlags &= ~HBA_FLAGS_DBG_FW_PRINT_B;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the Kernel Debug Print flag is set, send it off to the
|
||||
* Kernel debugger
|
||||
*/
|
||||
if ((sc->DebugFlags & HBA_FLAGS_DBG_KERNEL_PRINT_B)
|
||||
&& ((PrintFlags
|
||||
& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
|
||||
!= HBA_FLAGS_DBG_FW_PRINT_B)) {
|
||||
if (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B)
|
||||
printf ("%s\n", PrintBuffer_P);
|
||||
else
|
||||
device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
* No HBA structure passed in so it has to be for the Kernel Debugger
|
||||
*/
|
||||
if ((sc != NULL) && (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B))
|
||||
printf ("%s\n", PrintBuffer_P);
|
||||
else if (sc != NULL)
|
||||
device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
|
||||
else
|
||||
printf("%s\n", PrintBuffer_P);
|
||||
}
|
||||
}
|
||||
|
||||
void aacraid_fw_print_mem(struct aac_softc *sc, unsigned long PrintFlags, u_int8_t *Addr, int Count)
|
||||
{
|
||||
int Offset, i;
|
||||
u_int32_t DebugFlags = 0;
|
||||
char Buffer[100];
|
||||
char *LineBuffer_P;
|
||||
|
||||
/*
|
||||
* If we have an HBA structure, save off the flags and set the no
|
||||
* headers flag so we don't have garbage between our lines of data
|
||||
*/
|
||||
if (sc != NULL) {
|
||||
DebugFlags = sc->FwDebugFlags;
|
||||
sc->FwDebugFlags |= FW_DEBUG_FLAGS_NO_HEADERS_B;
|
||||
}
|
||||
|
||||
Offset = 0;
|
||||
|
||||
/*
|
||||
* Loop through all the data
|
||||
*/
|
||||
while (Offset < Count) {
|
||||
/*
|
||||
* We will format each line into a buffer and then print out
|
||||
* the entire line so set the pointer to the beginning of the
|
||||
* buffer
|
||||
*/
|
||||
LineBuffer_P = Buffer;
|
||||
|
||||
/*
|
||||
* Set up the address in HEX
|
||||
*/
|
||||
sprintf(LineBuffer_P, "\n%04x ", Offset);
|
||||
LineBuffer_P += 6;
|
||||
|
||||
/*
|
||||
* Set up 16 bytes in HEX format
|
||||
*/
|
||||
for (i = 0; i < 16; ++i) {
|
||||
/*
|
||||
* If we are past the count of data bytes to output,
|
||||
* pad with blanks
|
||||
*/
|
||||
if ((Offset + i) >= Count)
|
||||
sprintf (LineBuffer_P, " ");
|
||||
else
|
||||
sprintf (LineBuffer_P, "%02x ", Addr[Offset+i]);
|
||||
LineBuffer_P += 3;
|
||||
|
||||
/*
|
||||
* At the mid point we will put in a divider
|
||||
*/
|
||||
if (i == 7) {
|
||||
sprintf (LineBuffer_P, "- ");
|
||||
LineBuffer_P += 2;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now do the same 16 bytes at the end of the line in ASCII
|
||||
* format
|
||||
*/
|
||||
sprintf (LineBuffer_P, " ");
|
||||
LineBuffer_P += 2;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
/*
|
||||
* If all data processed, OUT-O-HERE
|
||||
*/
|
||||
if ((Offset + i) >= Count)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If this is a printable ASCII character, convert it
|
||||
*/
|
||||
if ((Addr[Offset+i] > 0x1F) && (Addr[Offset+i] < 0x7F))
|
||||
sprintf (LineBuffer_P, "%c", Addr[Offset+i]);
|
||||
else
|
||||
sprintf (LineBuffer_P, ".");
|
||||
++LineBuffer_P;
|
||||
}
|
||||
/*
|
||||
* The line is now formatted, so print it out
|
||||
*/
|
||||
aacraid_fw_printf(sc, PrintFlags, "%s", Buffer);
|
||||
|
||||
/*
|
||||
* Bump the offset by 16 for the next line
|
||||
*/
|
||||
Offset += 16;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the saved off flags
|
||||
*/
|
||||
if (sc != NULL)
|
||||
sc->FwDebugFlags = DebugFlags;
|
||||
}
|
||||
|
64
sys/dev/aacraid/aacraid_debug.h
Normal file
64
sys/dev/aacraid/aacraid_debug.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*-
|
||||
* Copyright (c) 2010 Adaptec, Inc.
|
||||
* Copyright (c) 2010-2012 PMC-Sierra, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef PRINT_BUFFER_SIZE
|
||||
|
||||
#define PRINT_BUFFER_SIZE 512
|
||||
|
||||
#define HBA_FLAGS_DBG_FLAGS_MASK 0x0000ffff
|
||||
#define HBA_FLAGS_DBG_KERNEL_PRINT_B 0x00000001
|
||||
#define HBA_FLAGS_DBG_FW_PRINT_B 0x00000002
|
||||
#define HBA_FLAGS_DBG_FUNCTION_ENTRY_B 0x00000004
|
||||
#define HBA_FLAGS_DBG_FUNCTION_EXIT_B 0x00000008
|
||||
#define HBA_FLAGS_DBG_ERROR_B 0x00000010
|
||||
#define HBA_FLAGS_DBG_INIT_B 0x00000020
|
||||
#define HBA_FLAGS_DBG_OS_COMMANDS_B 0x00000040
|
||||
#define HBA_FLAGS_DBG_SCAN_B 0x00000080
|
||||
#define HBA_FLAGS_DBG_COALESCE_B 0x00000100
|
||||
#define HBA_FLAGS_DBG_IOCTL_COMMANDS_B 0x00000200
|
||||
#define HBA_FLAGS_DBG_SYNC_COMMANDS_B 0x00000400
|
||||
#define HBA_FLAGS_DBG_COMM_B 0x00000800
|
||||
#define HBA_FLAGS_DBG_CSMI_COMMANDS_B 0x00001000
|
||||
#define HBA_FLAGS_DBG_AIF_B 0x00001000
|
||||
#define HBA_FLAGS_DBG_DEBUG_B 0x00002000
|
||||
|
||||
#define FW_DEBUG_STR_LENGTH_OFFSET 0x00
|
||||
#define FW_DEBUG_FLAGS_OFFSET 0x04
|
||||
#define FW_DEBUG_BLED_OFFSET 0x08
|
||||
#define FW_DEBUG_FLAGS_NO_HEADERS_B 0x01
|
||||
|
||||
struct aac_softc;
|
||||
extern int aacraid_get_fw_debug_buffer(struct aac_softc *);
|
||||
extern void aacraid_fw_printf(struct aac_softc *, unsigned long, const char *, ...);
|
||||
extern void aacraid_fw_print_mem(struct aac_softc *, unsigned long, u_int8_t *,int);
|
||||
extern int aacraid_sync_command(struct aac_softc *sc, u_int32_t command,
|
||||
u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
|
||||
u_int32_t arg3, u_int32_t *sp, u_int32_t *r1);
|
||||
|
||||
#endif
|
97
sys/dev/aacraid/aacraid_linux.c
Normal file
97
sys/dev/aacraid/aacraid_linux.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*-
|
||||
* Copyright (c) 2002 Scott Long
|
||||
* Copyright (c) 2002-2010 Adaptec, Inc.
|
||||
* Copyright (c) 2010-2012 PMC-Sierra, Inc.
|
||||
* 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$");
|
||||
|
||||
/*
|
||||
* Linux ioctl handler for the aac device driver
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/proc.h>
|
||||
#ifdef __amd64__
|
||||
#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 AAC_LINUX_IOCTL_MIN 0x0000
|
||||
#define AAC_LINUX_IOCTL_MAX 0x21ff
|
||||
|
||||
static linux_ioctl_function_t aacraid_linux_ioctl;
|
||||
static struct linux_ioctl_handler aacraid_linux_handler = {aacraid_linux_ioctl,
|
||||
AAC_LINUX_IOCTL_MIN,
|
||||
AAC_LINUX_IOCTL_MAX};
|
||||
|
||||
SYSINIT (aacraid_linux_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
|
||||
linux_ioctl_register_handler, &aacraid_linux_handler);
|
||||
SYSUNINIT(aacraid_linux_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
|
||||
linux_ioctl_unregister_handler, &aacraid_linux_handler);
|
||||
|
||||
static int
|
||||
aacraid_linux_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
/* Do we care about any specific load/unload actions? */
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEV_MODULE(aacraid_linux, aacraid_linux_modevent, NULL);
|
||||
MODULE_DEPEND(aacraid_linux, linux, 1, 1, 1);
|
||||
|
||||
static int
|
||||
aacraid_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
|
||||
{
|
||||
struct file *fp;
|
||||
u_long cmd;
|
||||
int error;
|
||||
|
||||
#if __FreeBSD_version >= 900000
|
||||
if ((error = fget(td, args->fd, 0, &fp)) != 0)
|
||||
#else
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
#endif
|
||||
return (error);
|
||||
cmd = args->cmd;
|
||||
|
||||
/*
|
||||
* Pass the ioctl off to our standard handler.
|
||||
*/
|
||||
error = (fo_ioctl(fp, cmd, (caddr_t)args->arg, td->td_ucred, td));
|
||||
fdrop(fp, td);
|
||||
return (error);
|
||||
}
|
265
sys/dev/aacraid/aacraid_pci.c
Normal file
265
sys/dev/aacraid/aacraid_pci.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Michael Smith
|
||||
* Copyright (c) 2001 Scott Long
|
||||
* Copyright (c) 2000 BSDi
|
||||
* Copyright (c) 2001-2010 Adaptec, Inc.
|
||||
* Copyright (c) 2010-2012 PMC-Sierra, Inc.
|
||||
* 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$");
|
||||
|
||||
/*
|
||||
* PCI bus interface and resource allocation.
|
||||
*/
|
||||
|
||||
#include "opt_aacraid.h"
|
||||
|
||||
#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 <sys/disk.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/aacraid/aacraid_reg.h>
|
||||
#include <sys/aac_ioctl.h>
|
||||
#include <dev/aacraid/aacraid_debug.h>
|
||||
#include <dev/aacraid/aacraid_var.h>
|
||||
|
||||
static int aacraid_pci_probe(device_t dev);
|
||||
static int aacraid_pci_attach(device_t dev);
|
||||
|
||||
static device_method_t aacraid_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, aacraid_pci_probe),
|
||||
DEVMETHOD(device_attach, aacraid_pci_attach),
|
||||
DEVMETHOD(device_detach, aacraid_detach),
|
||||
DEVMETHOD(device_suspend, aacraid_suspend),
|
||||
DEVMETHOD(device_resume, aacraid_resume),
|
||||
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t aacraid_pci_driver = {
|
||||
"aacraid",
|
||||
aacraid_methods,
|
||||
sizeof(struct aac_softc)
|
||||
};
|
||||
|
||||
static devclass_t aacraid_devclass;
|
||||
|
||||
DRIVER_MODULE(aacraid, pci, aacraid_pci_driver, aacraid_devclass, 0, 0);
|
||||
MODULE_DEPEND(aacraid, pci, 1, 1, 1);
|
||||
|
||||
struct aac_ident
|
||||
{
|
||||
u_int16_t vendor;
|
||||
u_int16_t device;
|
||||
u_int16_t subvendor;
|
||||
u_int16_t subdevice;
|
||||
int hwif;
|
||||
int quirks;
|
||||
char *desc;
|
||||
} aacraid_family_identifiers[] = {
|
||||
{0x9005, 0x028b, 0, 0, AAC_HWIF_SRC, 0,
|
||||
"Adaptec RAID Controller"},
|
||||
{0x9005, 0x028c, 0, 0, AAC_HWIF_SRCV, 0,
|
||||
"Adaptec RAID Controller"},
|
||||
{0x9005, 0x028d, 0, 0, AAC_HWIF_SRCV, 0,
|
||||
"Adaptec RAID Controller"},
|
||||
{0x9005, 0x028f, 0, 0, AAC_HWIF_SRCV, 0,
|
||||
"Adaptec RAID Controller"},
|
||||
{0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct aac_ident *
|
||||
aac_find_ident(device_t dev)
|
||||
{
|
||||
struct aac_ident *m;
|
||||
u_int16_t vendid, devid, sub_vendid, sub_devid;
|
||||
|
||||
vendid = pci_get_vendor(dev);
|
||||
devid = pci_get_device(dev);
|
||||
sub_vendid = pci_get_subvendor(dev);
|
||||
sub_devid = pci_get_subdevice(dev);
|
||||
|
||||
for (m = aacraid_family_identifiers; m->vendor != 0; m++) {
|
||||
if ((m->vendor == vendid) && (m->device == devid))
|
||||
return (m);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether this is one of our supported adapters.
|
||||
*/
|
||||
static int
|
||||
aacraid_pci_probe(device_t dev)
|
||||
{
|
||||
struct aac_ident *id;
|
||||
|
||||
fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
|
||||
|
||||
if ((id = aac_find_ident(dev)) != NULL) {
|
||||
device_set_desc(dev, id->desc);
|
||||
return(BUS_PROBE_DEFAULT);
|
||||
}
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate resources for our device, set up the bus interface.
|
||||
*/
|
||||
static int
|
||||
aacraid_pci_attach(device_t dev)
|
||||
{
|
||||
struct aac_softc *sc;
|
||||
struct aac_ident *id;
|
||||
int error;
|
||||
u_int32_t command;
|
||||
|
||||
fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
|
||||
|
||||
/*
|
||||
* Initialise softc.
|
||||
*/
|
||||
sc = device_get_softc(dev);
|
||||
bzero(sc, sizeof(*sc));
|
||||
sc->aac_dev = dev;
|
||||
|
||||
/* assume failure is 'not configured' */
|
||||
error = ENXIO;
|
||||
|
||||
/*
|
||||
* Verify that the adapter is correctly set up in PCI space.
|
||||
*/
|
||||
command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
|
||||
command |= PCIM_CMD_BUSMASTEREN;
|
||||
pci_write_config(dev, PCIR_COMMAND, command, 2);
|
||||
command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
|
||||
if (!(command & PCIM_CMD_BUSMASTEREN)) {
|
||||
device_printf(sc->aac_dev, "can't enable bus-master feature\n");
|
||||
goto out;
|
||||
}
|
||||
if ((command & PCIM_CMD_MEMEN) == 0) {
|
||||
device_printf(sc->aac_dev, "memory window not available\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect the hardware interface version, set up the bus interface
|
||||
* indirection.
|
||||
*/
|
||||
id = aac_find_ident(dev);
|
||||
sc->aac_hwif = id->hwif;
|
||||
switch(sc->aac_hwif) {
|
||||
case AAC_HWIF_SRC:
|
||||
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for PMC SRC");
|
||||
sc->aac_if = aacraid_src_interface;
|
||||
break;
|
||||
case AAC_HWIF_SRCV:
|
||||
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for PMC SRCv");
|
||||
sc->aac_if = aacraid_srcv_interface;
|
||||
break;
|
||||
default:
|
||||
sc->aac_hwif = AAC_HWIF_UNKNOWN;
|
||||
device_printf(sc->aac_dev, "unknown hardware type\n");
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* assume failure is 'out of memory' */
|
||||
error = ENOMEM;
|
||||
|
||||
/*
|
||||
* Allocate the PCI register window.
|
||||
*/
|
||||
sc->aac_regs_rid0 = PCIR_BAR(0);
|
||||
if ((sc->aac_regs_res0 = bus_alloc_resource_any(sc->aac_dev,
|
||||
SYS_RES_MEMORY, &sc->aac_regs_rid0, RF_ACTIVE)) == NULL) {
|
||||
device_printf(sc->aac_dev,
|
||||
"couldn't allocate register window 0\n");
|
||||
goto out;
|
||||
}
|
||||
sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
|
||||
sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
|
||||
|
||||
sc->aac_regs_rid1 = PCIR_BAR(2);
|
||||
if ((sc->aac_regs_res1 = bus_alloc_resource_any(sc->aac_dev,
|
||||
SYS_RES_MEMORY, &sc->aac_regs_rid1, RF_ACTIVE)) == NULL) {
|
||||
device_printf(sc->aac_dev,
|
||||
"couldn't allocate register window 1\n");
|
||||
goto out;
|
||||
}
|
||||
sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
|
||||
sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
|
||||
|
||||
/*
|
||||
* Allocate the parent bus DMA tag appropriate for our PCI interface.
|
||||
*
|
||||
* Note that some of these controllers are 64-bit capable.
|
||||
*/
|
||||
if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
|
||||
PAGE_SIZE, 0, /* algnmnt, boundary */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
|
||||
BUS_SPACE_UNRESTRICTED, /* nsegments */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
|
||||
0, /* flags */
|
||||
NULL, NULL, /* No locking needed */
|
||||
&sc->aac_parent_dmat)) {
|
||||
device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set up quirks */
|
||||
sc->flags = id->quirks;
|
||||
|
||||
/*
|
||||
* Do bus-independent initialisation.
|
||||
*/
|
||||
error = aacraid_attach(sc);
|
||||
|
||||
out:
|
||||
if (error)
|
||||
aacraid_free(sc);
|
||||
return(error);
|
||||
}
|
1598
sys/dev/aacraid/aacraid_reg.h
Normal file
1598
sys/dev/aacraid/aacraid_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
663
sys/dev/aacraid/aacraid_var.h
Normal file
663
sys/dev/aacraid/aacraid_var.h
Normal file
@ -0,0 +1,663 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Michael Smith
|
||||
* Copyright (c) 2001 Scott Long
|
||||
* Copyright (c) 2000 BSDi
|
||||
* Copyright (c) 2001-2010 Adaptec, Inc.
|
||||
* Copyright (c) 2010-2012 PMC-Sierra, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/bio.h>
|
||||
#if __FreeBSD_version >= 800000
|
||||
#include <sys/callout.h>
|
||||
#endif
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/selinfo.h>
|
||||
#include <geom/geom_disk.h>
|
||||
|
||||
#define AAC_TYPE_DEVO 1
|
||||
#define AAC_TYPE_ALPHA 2
|
||||
#define AAC_TYPE_BETA 3
|
||||
#define AAC_TYPE_RELEASE 4
|
||||
|
||||
#define AAC_DRIVER_MAJOR_VERSION 3
|
||||
#define AAC_DRIVER_MINOR_VERSION 1
|
||||
#define AAC_DRIVER_BUGFIX_LEVEL 1
|
||||
#define AAC_DRIVER_TYPE AAC_TYPE_RELEASE
|
||||
|
||||
#ifndef AAC_DRIVER_BUILD
|
||||
# define AAC_DRIVER_BUILD 1
|
||||
#endif
|
||||
|
||||
#if __FreeBSD_version <= 601000
|
||||
#define bus_get_dma_tag(x) NULL
|
||||
#endif
|
||||
|
||||
/* **************************** NewBUS interrupt Crock ************************/
|
||||
#if __FreeBSD_version < 700031
|
||||
#define aac_bus_setup_intr(d, i, f, U, if, ifa, hp) \
|
||||
bus_setup_intr(d, i, f, if, ifa, hp)
|
||||
#else
|
||||
#define aac_bus_setup_intr bus_setup_intr
|
||||
#endif
|
||||
|
||||
/* **************************** NewBUS CAM Support ****************************/
|
||||
#if __FreeBSD_version < 700049
|
||||
#define aac_xpt_bus_register(sim, parent, bus) \
|
||||
xpt_bus_register(sim, bus)
|
||||
#else
|
||||
#define aac_xpt_bus_register xpt_bus_register
|
||||
#endif
|
||||
|
||||
/**************************** Kernel Thread Support ***************************/
|
||||
#if __FreeBSD_version > 800001
|
||||
#define aac_kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \
|
||||
kproc_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg)
|
||||
#define aac_kthread_exit(status) \
|
||||
kproc_exit(status)
|
||||
#else
|
||||
#define aac_kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg) \
|
||||
kthread_create(func, farg, proc_ptr, flags, stackpgs, fmtstr, arg)
|
||||
#define aac_kthread_exit(status) \
|
||||
kthread_exit(status)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Driver Parameter Definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* We allocate a small set of FIBs for the adapter to use to send us messages.
|
||||
*/
|
||||
#define AAC_ADAPTER_FIBS 8
|
||||
|
||||
/*
|
||||
* The controller reports status events in AIFs. We hang on to a number of
|
||||
* these in order to pass them out to user-space management tools.
|
||||
*/
|
||||
#define AAC_AIFQ_LENGTH 64
|
||||
|
||||
/*
|
||||
* Firmware messages are passed in the printf buffer.
|
||||
*/
|
||||
#define AAC_PRINTF_BUFSIZE 256
|
||||
|
||||
/*
|
||||
* We wait this many seconds for the adapter to come ready if it is still
|
||||
* booting
|
||||
*/
|
||||
#define AAC_BOOT_TIMEOUT (3 * 60)
|
||||
|
||||
/*
|
||||
* Timeout for immediate commands.
|
||||
*/
|
||||
#define AAC_IMMEDIATE_TIMEOUT 30 /* seconds */
|
||||
|
||||
/*
|
||||
* Timeout for normal commands
|
||||
*/
|
||||
#define AAC_CMD_TIMEOUT 120 /* seconds */
|
||||
|
||||
/*
|
||||
* Rate at which we periodically check for timed out commands and kick the
|
||||
* controller.
|
||||
*/
|
||||
#define AAC_PERIODIC_INTERVAL 20 /* seconds */
|
||||
|
||||
#define PASSTHROUGH_BUS 0
|
||||
#define CONTAINER_BUS 1
|
||||
/*
|
||||
* Per-container data structure
|
||||
*/
|
||||
struct aac_container
|
||||
{
|
||||
struct aac_mntobj co_mntobj;
|
||||
int co_found;
|
||||
u_int32_t co_uid;
|
||||
TAILQ_ENTRY(aac_container) co_link;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-SIM data structure
|
||||
*/
|
||||
struct aac_cam;
|
||||
struct aac_sim
|
||||
{
|
||||
device_t sim_dev;
|
||||
int TargetsPerBus;
|
||||
int BusNumber;
|
||||
int BusType;
|
||||
int InitiatorBusId;
|
||||
struct aac_softc *aac_sc;
|
||||
struct aac_cam *aac_cam;
|
||||
TAILQ_ENTRY(aac_sim) sim_link;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-disk structure
|
||||
*/
|
||||
struct aac_disk
|
||||
{
|
||||
device_t ad_dev;
|
||||
struct aac_softc *ad_controller;
|
||||
struct aac_container *ad_container;
|
||||
struct disk *ad_disk;
|
||||
int ad_flags;
|
||||
#define AAC_DISK_OPEN (1<<0)
|
||||
int ad_cylinders;
|
||||
int ad_heads;
|
||||
int ad_sectors;
|
||||
u_int64_t ad_size;
|
||||
int unit;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-command control structure.
|
||||
*/
|
||||
struct aac_command
|
||||
{
|
||||
TAILQ_ENTRY(aac_command) cm_link; /* list linkage */
|
||||
|
||||
struct aac_softc *cm_sc; /* controller that owns us */
|
||||
|
||||
struct aac_fib *cm_fib; /* FIB associated with this
|
||||
* command */
|
||||
u_int64_t cm_fibphys; /* bus address of the FIB */
|
||||
struct bio *cm_data; /* pointer to data in kernel
|
||||
* space */
|
||||
u_int32_t cm_datalen; /* data length */
|
||||
bus_dmamap_t cm_datamap; /* DMA map for bio data */
|
||||
struct aac_sg_table *cm_sgtable; /* pointer to s/g table in
|
||||
* command */
|
||||
int cm_flags;
|
||||
#define AAC_CMD_MAPPED (1<<0) /* command has had its data
|
||||
* mapped */
|
||||
#define AAC_CMD_DATAIN (1<<1) /* command involves data moving
|
||||
* from controller to host */
|
||||
#define AAC_CMD_DATAOUT (1<<2) /* command involves data moving
|
||||
* from host to controller */
|
||||
#define AAC_CMD_COMPLETED (1<<3) /* command has been completed */
|
||||
#define AAC_CMD_TIMEDOUT (1<<4) /* command taken too long */
|
||||
#define AAC_ON_AACQ_FREE (1<<5)
|
||||
#define AAC_ON_AACQ_READY (1<<6)
|
||||
#define AAC_ON_AACQ_BUSY (1<<7)
|
||||
#define AAC_ON_AACQ_AIF (1<<8)
|
||||
#define AAC_ON_AACQ_NORM (1<<10)
|
||||
#define AAC_ON_AACQ_MASK ((1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10))
|
||||
#define AAC_CMD_RESET (1<<9)
|
||||
#define AAC_CMD_FASTRESP (1<<11)
|
||||
#define AAC_CMD_WAIT (1<<12)
|
||||
|
||||
void (* cm_complete)(struct aac_command *cm);
|
||||
union ccb *cm_ccb;
|
||||
time_t cm_timestamp; /* command creation time */
|
||||
int cm_index;
|
||||
bus_dma_tag_t cm_passthr_dmat; /* passthrough buffer/command
|
||||
* DMA tag */
|
||||
};
|
||||
|
||||
struct aac_fibmap {
|
||||
TAILQ_ENTRY(aac_fibmap) fm_link; /* list linkage */
|
||||
struct aac_fib *aac_fibs;
|
||||
bus_dmamap_t aac_fibmap;
|
||||
struct aac_command *aac_commands;
|
||||
};
|
||||
|
||||
/*
|
||||
* We gather a number of adapter-visible items into a single structure.
|
||||
*
|
||||
* The ordering of this strucure may be important; we copy the Linux driver:
|
||||
*
|
||||
* Adapter FIBs
|
||||
* Init struct
|
||||
* Queue headers (Comm Area)
|
||||
* Printf buffer
|
||||
*
|
||||
* In addition, we add:
|
||||
* Sync Fib
|
||||
*/
|
||||
struct aac_common {
|
||||
/* fibs for the controller to send us messages */
|
||||
struct aac_fib ac_fibs[AAC_ADAPTER_FIBS];
|
||||
|
||||
/* the init structure */
|
||||
struct aac_adapter_init ac_init;
|
||||
|
||||
/* buffer for text messages from the controller */
|
||||
char ac_printf[AAC_PRINTF_BUFSIZE];
|
||||
|
||||
/* fib for synchronous commands */
|
||||
struct aac_fib ac_sync_fib;
|
||||
|
||||
/* response buffer for SRC (new comm. type1) - must be last element */
|
||||
u_int32_t ac_host_rrq[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface operations
|
||||
*/
|
||||
struct aac_interface
|
||||
{
|
||||
int (*aif_get_fwstatus)(struct aac_softc *sc);
|
||||
void (*aif_qnotify)(struct aac_softc *sc, int qbit);
|
||||
int (*aif_get_istatus)(struct aac_softc *sc);
|
||||
void (*aif_clr_istatus)(struct aac_softc *sc, int mask);
|
||||
void (*aif_set_mailbox)(struct aac_softc *sc, u_int32_t command,
|
||||
u_int32_t arg0, u_int32_t arg1,
|
||||
u_int32_t arg2, u_int32_t arg3);
|
||||
int (*aif_get_mailbox)(struct aac_softc *sc, int mb);
|
||||
void (*aif_set_interrupts)(struct aac_softc *sc, int enable);
|
||||
int (*aif_send_command)(struct aac_softc *sc, struct aac_command *cm);
|
||||
int (*aif_get_outb_queue)(struct aac_softc *sc);
|
||||
void (*aif_set_outb_queue)(struct aac_softc *sc, int index);
|
||||
};
|
||||
extern struct aac_interface aacraid_src_interface;
|
||||
extern struct aac_interface aacraid_srcv_interface;
|
||||
|
||||
#define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus((sc)))
|
||||
#define AAC_QNOTIFY(sc, qbit) ((sc)->aac_if.aif_qnotify((sc), (qbit)))
|
||||
#define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus((sc)))
|
||||
#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if.aif_clr_istatus((sc), \
|
||||
(mask)))
|
||||
#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
|
||||
((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), \
|
||||
(arg3)))
|
||||
#define AAC_GET_MAILBOX(sc, mb) ((sc)->aac_if.aif_get_mailbox((sc), \
|
||||
(mb)))
|
||||
#define AAC_MASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), \
|
||||
0))
|
||||
#define AAC_UNMASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), \
|
||||
1))
|
||||
#define AAC_SEND_COMMAND(sc, cm) ((sc)->aac_if.aif_send_command((sc), (cm)))
|
||||
#define AAC_GET_OUTB_QUEUE(sc) ((sc)->aac_if.aif_get_outb_queue((sc)))
|
||||
#define AAC_SET_OUTB_QUEUE(sc, idx) ((sc)->aac_if.aif_set_outb_queue((sc), (idx)))
|
||||
|
||||
#define AAC_MEM0_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag0, \
|
||||
sc->aac_bhandle0, reg, val)
|
||||
#define AAC_MEM0_GETREG4(sc, reg) bus_space_read_4(sc->aac_btag0, \
|
||||
sc->aac_bhandle0, reg)
|
||||
#define AAC_MEM0_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag0, \
|
||||
sc->aac_bhandle0, reg, val)
|
||||
#define AAC_MEM0_GETREG2(sc, reg) bus_space_read_2(sc->aac_btag0, \
|
||||
sc->aac_bhandle0, reg)
|
||||
#define AAC_MEM0_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag0, \
|
||||
sc->aac_bhandle0, reg, val)
|
||||
#define AAC_MEM0_GETREG1(sc, reg) bus_space_read_1(sc->aac_btag0, \
|
||||
sc->aac_bhandle0, reg)
|
||||
|
||||
#define AAC_MEM1_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag1, \
|
||||
sc->aac_bhandle1, reg, val)
|
||||
#define AAC_MEM1_GETREG4(sc, reg) bus_space_read_4(sc->aac_btag1, \
|
||||
sc->aac_bhandle1, reg)
|
||||
#define AAC_MEM1_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag1, \
|
||||
sc->aac_bhandle1, reg, val)
|
||||
#define AAC_MEM1_GETREG2(sc, reg) bus_space_read_2(sc->aac_btag1, \
|
||||
sc->aac_bhandle1, reg)
|
||||
#define AAC_MEM1_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag1, \
|
||||
sc->aac_bhandle1, reg, val)
|
||||
#define AAC_MEM1_GETREG1(sc, reg) bus_space_read_1(sc->aac_btag1, \
|
||||
sc->aac_bhandle1, reg)
|
||||
|
||||
/* fib context (IOCTL) */
|
||||
struct aac_fib_context {
|
||||
u_int32_t unique;
|
||||
int ctx_idx;
|
||||
int ctx_wrap;
|
||||
struct aac_fib_context *next, *prev;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-controller structure.
|
||||
*/
|
||||
struct aac_softc
|
||||
{
|
||||
/* bus connections */
|
||||
device_t aac_dev;
|
||||
struct resource *aac_regs_res0, *aac_regs_res1; /* reg. if. window */
|
||||
int aac_regs_rid0, aac_regs_rid1; /* resource ID */
|
||||
bus_space_handle_t aac_bhandle0, aac_bhandle1; /* bus space handle */
|
||||
bus_space_tag_t aac_btag0, aac_btag1; /* bus space tag */
|
||||
bus_dma_tag_t aac_parent_dmat; /* parent DMA tag */
|
||||
bus_dma_tag_t aac_buffer_dmat; /* data buffer/command
|
||||
* DMA tag */
|
||||
struct resource *aac_irq; /* interrupt */
|
||||
int aac_irq_rid;
|
||||
void *aac_intr; /* interrupt handle */
|
||||
eventhandler_tag eh;
|
||||
#if __FreeBSD_version >= 800000
|
||||
struct callout aac_daemontime; /* clock daemon callout */
|
||||
#else
|
||||
struct callout_handle timeout_id; /* timeout handle */
|
||||
#endif
|
||||
|
||||
/* controller features, limits and status */
|
||||
int aac_state;
|
||||
#define AAC_STATE_SUSPEND (1<<0)
|
||||
#define AAC_STATE_UNUSED0 (1<<1)
|
||||
#define AAC_STATE_INTERRUPTS_ON (1<<2)
|
||||
#define AAC_STATE_AIF_SLEEPER (1<<3)
|
||||
#define AAC_STATE_RESET (1<<4)
|
||||
struct FsaRevision aac_revision;
|
||||
|
||||
/* controller hardware interface */
|
||||
int aac_hwif;
|
||||
#define AAC_HWIF_SRC 5
|
||||
#define AAC_HWIF_SRCV 6
|
||||
#define AAC_HWIF_UNKNOWN -1
|
||||
bus_dma_tag_t aac_common_dmat; /* common structure
|
||||
* DMA tag */
|
||||
bus_dmamap_t aac_common_dmamap; /* common structure
|
||||
* DMA map */
|
||||
struct aac_common *aac_common;
|
||||
u_int32_t aac_common_busaddr;
|
||||
u_int32_t aac_host_rrq_idx;
|
||||
struct aac_interface aac_if;
|
||||
|
||||
/* command/fib resources */
|
||||
bus_dma_tag_t aac_fib_dmat; /* DMA tag for allocing FIBs */
|
||||
TAILQ_HEAD(,aac_fibmap) aac_fibmap_tqh;
|
||||
u_int total_fibs;
|
||||
struct aac_command *aac_commands;
|
||||
|
||||
/* command management */
|
||||
TAILQ_HEAD(,aac_command) aac_free; /* command structures
|
||||
* available for reuse */
|
||||
TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for
|
||||
* controller resources */
|
||||
TAILQ_HEAD(,aac_command) aac_busy;
|
||||
TAILQ_HEAD(,aac_event) aac_ev_cmfree;
|
||||
struct bio_queue_head aac_bioq;
|
||||
|
||||
struct aac_qstat aac_qstat[AACQ_COUNT]; /* queue statistics */
|
||||
|
||||
/* connected containters */
|
||||
TAILQ_HEAD(,aac_container) aac_container_tqh;
|
||||
struct mtx aac_container_lock;
|
||||
|
||||
/*
|
||||
* The general I/O lock. This protects the sync fib, the lists, the
|
||||
* queues, and the registers.
|
||||
*/
|
||||
struct mtx aac_io_lock;
|
||||
|
||||
struct intr_config_hook aac_ich;
|
||||
|
||||
/* sync. transfer mode */
|
||||
struct aac_command *aac_sync_cm;
|
||||
|
||||
/* management interface */
|
||||
struct cdev *aac_dev_t;
|
||||
struct mtx aac_aifq_lock;
|
||||
struct aac_fib aac_aifq[AAC_AIFQ_LENGTH];
|
||||
int aifq_idx;
|
||||
int aifq_filled;
|
||||
int aif_pending;
|
||||
struct aac_fib_context *fibctx;
|
||||
struct selinfo rcv_select;
|
||||
struct proc *aifthread;
|
||||
int aifflags;
|
||||
#define AAC_AIFFLAGS_RUNNING (1 << 0)
|
||||
#define AAC_AIFFLAGS_AIF (1 << 1)
|
||||
#define AAC_AIFFLAGS_EXIT (1 << 2)
|
||||
#define AAC_AIFFLAGS_EXITED (1 << 3)
|
||||
#define AAC_AIFFLAGS_PRINTF (1 << 4)
|
||||
#define AAC_AIFFLAGS_ALLOCFIBS (1 << 5)
|
||||
#define AAC_AIFFLAGS_PENDING (AAC_AIFFLAGS_AIF | AAC_AIFFLAGS_PRINTF | \
|
||||
AAC_AIFFLAGS_ALLOCFIBS)
|
||||
u_int32_t flags;
|
||||
#define AAC_FLAGS_PERC2QC (1 << 0)
|
||||
#define AAC_FLAGS_ENABLE_CAM (1 << 1) /* No SCSI passthrough */
|
||||
#define AAC_FLAGS_CAM_NORESET (1 << 2) /* Fake SCSI resets */
|
||||
#define AAC_FLAGS_CAM_PASSONLY (1 << 3) /* Only create pass devices */
|
||||
#define AAC_FLAGS_SG_64BIT (1 << 4) /* Use 64-bit S/G addresses */
|
||||
#define AAC_FLAGS_4GB_WINDOW (1 << 5) /* Device can access host mem
|
||||
* 2GB-4GB range */
|
||||
#define AAC_FLAGS_NO4GB (1 << 6) /* Can't access host mem >2GB */
|
||||
#define AAC_FLAGS_256FIBS (1 << 7) /* Can only do 256 commands */
|
||||
#define AAC_FLAGS_BROKEN_MEMMAP (1 << 8) /* Broken HostPhysMemPages */
|
||||
#define AAC_FLAGS_SLAVE (1 << 9)
|
||||
#define AAC_FLAGS_MASTER (1 << 10)
|
||||
#define AAC_FLAGS_NEW_COMM (1 << 11) /* New comm. interface supported */
|
||||
#define AAC_FLAGS_RAW_IO (1 << 12) /* Raw I/O interface */
|
||||
#define AAC_FLAGS_ARRAY_64BIT (1 << 13) /* 64-bit array size */
|
||||
#define AAC_FLAGS_LBA_64BIT (1 << 14) /* 64-bit LBA support */
|
||||
#define AAC_QUEUE_FRZN (1 << 15) /* Freeze the processing of
|
||||
* commands on the queue. */
|
||||
#define AAC_FLAGS_NEW_COMM_TYPE1 (1 << 16) /* New comm. type1 supported */
|
||||
#define AAC_FLAGS_NEW_COMM_TYPE2 (1 << 17) /* New comm. type2 supported */
|
||||
#define AAC_FLAGS_NEW_COMM_TYPE34 (1 << 18) /* New comm. type3/4 */
|
||||
#define AAC_FLAGS_SYNC_MODE (1 << 18) /* Sync. transfer mode */
|
||||
u_int32_t hint_flags; /* driver parameters */
|
||||
int sim_freezed; /* flag for sim_freeze/release */
|
||||
u_int32_t supported_options;
|
||||
u_int32_t scsi_method_id;
|
||||
TAILQ_HEAD(,aac_sim) aac_sim_tqh;
|
||||
|
||||
u_int32_t aac_max_fibs; /* max. FIB count */
|
||||
u_int32_t aac_max_fibs_alloc; /* max. alloc. per alloc_commands() */
|
||||
u_int32_t aac_max_fib_size; /* max. FIB size */
|
||||
u_int32_t aac_sg_tablesize; /* max. sg count from host */
|
||||
u_int32_t aac_max_sectors; /* max. I/O size from host (blocks) */
|
||||
u_int32_t aac_feature_bits; /* feature bits from suppl. info */
|
||||
u_int32_t aac_support_opt2; /* supp. options from suppl. info */
|
||||
u_int32_t aac_max_aif; /* max. AIF count */
|
||||
#define AAC_CAM_TARGET_WILDCARD ~0
|
||||
void (*cam_rescan_cb)(struct aac_softc *, uint32_t,
|
||||
uint32_t);
|
||||
u_int32_t DebugFlags; /* Debug print flags bitmap */
|
||||
u_int32_t DebugOffset; /* Offset from DPMEM start */
|
||||
u_int32_t DebugHeaderSize; /* Size of debug header */
|
||||
u_int32_t FwDebugFlags; /* FW Debug Flags */
|
||||
u_int32_t FwDebugBufferSize; /* FW Debug Buffer size */
|
||||
};
|
||||
|
||||
/*
|
||||
* Event callback mechanism for the driver
|
||||
*/
|
||||
#define AAC_EVENT_NONE 0x00
|
||||
#define AAC_EVENT_CMFREE 0x01
|
||||
#define AAC_EVENT_MASK 0xff
|
||||
#define AAC_EVENT_REPEAT 0x100
|
||||
|
||||
typedef void aac_event_cb_t(struct aac_softc *sc, struct aac_event *event,
|
||||
void *arg);
|
||||
struct aac_event {
|
||||
TAILQ_ENTRY(aac_event) ev_links;
|
||||
int ev_type;
|
||||
aac_event_cb_t *ev_callback;
|
||||
void *ev_arg;
|
||||
};
|
||||
|
||||
/*
|
||||
* Public functions
|
||||
*/
|
||||
extern void aacraid_free(struct aac_softc *sc);
|
||||
extern int aacraid_attach(struct aac_softc *sc);
|
||||
extern int aacraid_detach(device_t dev);
|
||||
extern int aacraid_shutdown(device_t dev);
|
||||
extern int aacraid_suspend(device_t dev);
|
||||
extern int aacraid_resume(device_t dev);
|
||||
extern void aacraid_new_intr_type1(void *arg);
|
||||
extern void aacraid_submit_bio(struct bio *bp);
|
||||
extern void aacraid_biodone(struct bio *bp);
|
||||
extern void aacraid_startio(struct aac_softc *sc);
|
||||
extern int aacraid_alloc_command(struct aac_softc *sc,
|
||||
struct aac_command **cmp);
|
||||
extern void aacraid_release_command(struct aac_command *cm);
|
||||
extern void aacraid_add_event(struct aac_softc *sc, struct aac_event
|
||||
*event);
|
||||
extern void aacraid_map_command_sg(void *arg, bus_dma_segment_t *segs,
|
||||
int nseg, int error);
|
||||
extern int aacraid_wait_command(struct aac_command *cmp);
|
||||
|
||||
/* #define AACRAID_DEBUG */
|
||||
|
||||
#ifdef AACRAID_DEBUG
|
||||
# define fwprintf(sc, flags, fmt, args...) \
|
||||
aacraid_fw_printf(sc, flags, "%s: " fmt, __func__, ##args);
|
||||
|
||||
extern void aacraid_print_queues(struct aac_softc *sc);
|
||||
extern void aacraid_print_fib(struct aac_softc *sc, struct aac_fib *fib,
|
||||
const char *caller);
|
||||
extern void aacraid_print_aif(struct aac_softc *sc,
|
||||
struct aac_aif_command *aif);
|
||||
|
||||
#define AAC_PRINT_FIB(sc, fib) aacraid_print_fib(sc, fib, __func__)
|
||||
|
||||
#else
|
||||
# define fwprintf(sc, flags, fmt, args...)
|
||||
|
||||
# define aacraid_print_queues(sc)
|
||||
|
||||
# define AAC_PRINT_FIB(sc, fib)
|
||||
# define aacraid_print_aif(sc, aac_aif_command)
|
||||
#endif
|
||||
|
||||
struct aac_code_lookup {
|
||||
char *string;
|
||||
u_int32_t code;
|
||||
};
|
||||
|
||||
/*
|
||||
* Queue primitives for driver queues.
|
||||
*/
|
||||
#define AACQ_ADD(sc, qname) \
|
||||
do { \
|
||||
struct aac_qstat *qs; \
|
||||
\
|
||||
qs = &(sc)->aac_qstat[qname]; \
|
||||
\
|
||||
qs->q_length++; \
|
||||
if (qs->q_length > qs->q_max) \
|
||||
qs->q_max = qs->q_length; \
|
||||
} while (0)
|
||||
|
||||
#define AACQ_REMOVE(sc, qname) (sc)->aac_qstat[qname].q_length--
|
||||
#define AACQ_INIT(sc, qname) \
|
||||
do { \
|
||||
sc->aac_qstat[qname].q_length = 0; \
|
||||
sc->aac_qstat[qname].q_max = 0; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define AACQ_COMMAND_QUEUE(name, index) \
|
||||
static __inline void \
|
||||
aac_initq_ ## name (struct aac_softc *sc) \
|
||||
{ \
|
||||
TAILQ_INIT(&sc->aac_ ## name); \
|
||||
AACQ_INIT(sc, index); \
|
||||
} \
|
||||
static __inline void \
|
||||
aac_enqueue_ ## name (struct aac_command *cm) \
|
||||
{ \
|
||||
if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \
|
||||
printf("command %p is on another queue, flags = %#x\n", \
|
||||
cm, cm->cm_flags); \
|
||||
panic("command is on another queue"); \
|
||||
} \
|
||||
TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link); \
|
||||
cm->cm_flags |= AAC_ON_ ## index; \
|
||||
AACQ_ADD(cm->cm_sc, index); \
|
||||
} \
|
||||
static __inline void \
|
||||
aac_requeue_ ## name (struct aac_command *cm) \
|
||||
{ \
|
||||
if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \
|
||||
printf("command %p is on another queue, flags = %#x\n", \
|
||||
cm, cm->cm_flags); \
|
||||
panic("command is on another queue"); \
|
||||
} \
|
||||
TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link); \
|
||||
cm->cm_flags |= AAC_ON_ ## index; \
|
||||
AACQ_ADD(cm->cm_sc, index); \
|
||||
} \
|
||||
static __inline struct aac_command * \
|
||||
aac_dequeue_ ## name (struct aac_softc *sc) \
|
||||
{ \
|
||||
struct aac_command *cm; \
|
||||
\
|
||||
if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \
|
||||
if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
|
||||
printf("command %p not in queue, flags = %#x, " \
|
||||
"bit = %#x\n", cm, cm->cm_flags, \
|
||||
AAC_ON_ ## index); \
|
||||
panic("command not in queue"); \
|
||||
} \
|
||||
TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link); \
|
||||
cm->cm_flags &= ~AAC_ON_ ## index; \
|
||||
AACQ_REMOVE(sc, index); \
|
||||
} \
|
||||
return(cm); \
|
||||
} \
|
||||
static __inline void \
|
||||
aac_remove_ ## name (struct aac_command *cm) \
|
||||
{ \
|
||||
if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
|
||||
printf("command %p not in queue, flags = %#x, " \
|
||||
"bit = %#x\n", cm, cm->cm_flags, \
|
||||
AAC_ON_ ## index); \
|
||||
panic("command not in queue"); \
|
||||
} \
|
||||
TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link); \
|
||||
cm->cm_flags &= ~AAC_ON_ ## index; \
|
||||
AACQ_REMOVE(cm->cm_sc, index); \
|
||||
} \
|
||||
struct hack
|
||||
|
||||
AACQ_COMMAND_QUEUE(free, AACQ_FREE);
|
||||
AACQ_COMMAND_QUEUE(ready, AACQ_READY);
|
||||
AACQ_COMMAND_QUEUE(busy, AACQ_BUSY);
|
||||
|
||||
static __inline void
|
||||
aac_print_printf(struct aac_softc *sc)
|
||||
{
|
||||
/*
|
||||
* XXX We have the ability to read the length of the printf string
|
||||
* from out of the mailboxes.
|
||||
*/
|
||||
device_printf(sc->aac_dev, "**Monitor** %.*s", AAC_PRINTF_BUFSIZE,
|
||||
sc->aac_common->ac_printf);
|
||||
sc->aac_common->ac_printf[0] = 0;
|
||||
AAC_QNOTIFY(sc, AAC_DB_PRINTF);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib)
|
||||
{
|
||||
|
||||
mtx_assert(&sc->aac_io_lock, MA_OWNED);
|
||||
*fib = &sc->aac_common->ac_sync_fib;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
aac_release_sync_fib(struct aac_softc *sc)
|
||||
{
|
||||
|
||||
mtx_assert(&sc->aac_io_lock, MA_OWNED);
|
||||
}
|
@ -165,6 +165,7 @@ device tws # LSI 3ware 9750 SATA+SAS 6Gb/s RAID controller
|
||||
# RAID controllers
|
||||
device aac # Adaptec FSA RAID
|
||||
device aacp # SCSI passthrough for aac (requires CAM)
|
||||
device aacraid # Adaptec by PMC RAID
|
||||
device ida # Compaq Smart RAID
|
||||
device mfi # LSI MegaRAID SAS
|
||||
device mlx # Mylex DAC960 family
|
||||
|
@ -714,6 +714,10 @@ hint.stg.0.port="11"
|
||||
device aac
|
||||
device aacp # SCSI Passthrough interface (optional, CAM required)
|
||||
|
||||
#
|
||||
# Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming families
|
||||
device aacraid # Container interface, CAM required
|
||||
|
||||
# The 'asr' driver provides support for current DPT/Adaptec SCSI RAID
|
||||
# controllers (SmartRAID V and VI and later).
|
||||
# These controllers require the CAM infrastructure.
|
||||
|
@ -118,6 +118,7 @@ device ses # Enclosure Services (SES and SAF-TE)
|
||||
# RAID controllers
|
||||
device aac # Adaptec FSA RAID
|
||||
device aacp # SCSI passthrough for aac (requires CAM)
|
||||
device aacraid # Adaptec by PMC RAID
|
||||
device ida # Compaq Smart RAID
|
||||
device mlx # Mylex DAC960 family
|
||||
|
||||
|
@ -9,6 +9,7 @@ SUBDIR= \
|
||||
${_3dfx} \
|
||||
${_3dfx_linux} \
|
||||
${_aac} \
|
||||
${_aacraid} \
|
||||
accf_data \
|
||||
accf_dns \
|
||||
accf_http \
|
||||
@ -534,6 +535,7 @@ _zfs= zfs
|
||||
.endif
|
||||
.if ${MACHINE} == "i386"
|
||||
_aac= aac
|
||||
_aacraid= aacraid
|
||||
_acpi= acpi
|
||||
.if ${MK_CRYPT} != "no" || defined(ALL_MODULES)
|
||||
_aesni= aesni
|
||||
@ -616,6 +618,7 @@ _snc= snc
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64"
|
||||
_aac= aac
|
||||
_aacraid= aacraid
|
||||
_aout= aout
|
||||
_acpi= acpi
|
||||
.if ${MK_CRYPT} != "no" || defined(ALL_MODULES)
|
||||
@ -747,6 +750,7 @@ _cpsw= cpsw
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "ia64"
|
||||
_aac= aac
|
||||
_aacraid= aacraid
|
||||
_aic= aic
|
||||
_an= an
|
||||
_arcnet= arcnet
|
||||
|
18
sys/modules/aacraid/Makefile
Normal file
18
sys/modules/aacraid/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/aacraid
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "i386"
|
||||
SUBDIR= aacraid_linux
|
||||
.endif
|
||||
|
||||
KMOD= aacraid
|
||||
SRCS= aacraid.c aacraid_pci.c aacraid_cam.c
|
||||
SRCS+= opt_scsi.h opt_cam.h opt_aacraid.h
|
||||
SRCS+= device_if.h bus_if.h pci_if.h
|
||||
|
||||
# To enable debug output from the driver, uncomment these two lines.
|
||||
#CFLAGS+= -DAACRAID_DEBUG=2
|
||||
#SRCS+= aacraid_debug.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
3
sys/modules/aacraid/Makefile.inc
Normal file
3
sys/modules/aacraid/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include "../Makefile.inc"
|
8
sys/modules/aacraid/aacraid_linux/Makefile
Normal file
8
sys/modules/aacraid/aacraid_linux/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/aacraid
|
||||
|
||||
KMOD= aacraid_linux
|
||||
SRCS= aacraid_linux.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
Loading…
Reference in New Issue
Block a user