A new driver for PCI:SCSI RAID controllers based on the Adaptec FSA
design. This includes integrated Dell RAID controllers, the Dell PERC 2/QC and the HP NetRAID-4M.
This commit is contained in:
parent
553427fc01
commit
358637397e
@ -112,6 +112,7 @@ device cd # CD
|
||||
device pass # Passthrough device (direct SCSI access)
|
||||
|
||||
# RAID controllers
|
||||
device aac # Adaptec FSA RAID
|
||||
device ida # Compaq Smart RAID
|
||||
device amr # AMI MegaRAID
|
||||
device mlx # Mylex DAC960 family
|
||||
|
@ -1330,6 +1330,11 @@ options DPT_ALLOW_MEMIO
|
||||
#
|
||||
device mly
|
||||
|
||||
#
|
||||
# Adaptec FSA RAID controllers, including integrated DELL controllers,
|
||||
# the Dell PERC 2/QC and the HP NetRAID-4M
|
||||
device aac
|
||||
|
||||
#
|
||||
# Compaq Smart RAID, Mylex DAC960 and AMI MegaRAID controllers. Only
|
||||
# one entry is needed; the code will find and configure all supported
|
||||
|
@ -71,6 +71,7 @@ ddb/db_trap.c optional ddb
|
||||
ddb/db_variables.c optional ddb
|
||||
ddb/db_watch.c optional ddb
|
||||
ddb/db_write_cmd.c optional ddb
|
||||
dev/aac/aac.c optional aac
|
||||
dev/acpi/acpi.c count acpi
|
||||
dev/acpi/acpi_powerres.c optional acpi
|
||||
dev/acpi/aml/aml_amlmem.c optional acpi
|
||||
|
1896
sys/dev/aac/aac.c
Normal file
1896
sys/dev/aac/aac.c
Normal file
File diff suppressed because it is too large
Load Diff
64
sys/dev/aac/aac_compat.h
Normal file
64
sys/dev/aac/aac_compat.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Backwards compatibility support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Handle the new/old bio/buf changeover
|
||||
*/
|
||||
|
||||
#if __FreeBSD_version < 500003 /* old buf style */
|
||||
# include <sys/buf.h>
|
||||
# define FREEBSD_4
|
||||
# define bio buf
|
||||
# define bioq_init(x) bufq_init(x)
|
||||
# define bioq_insert_tail(x, y) bufq_insert_tail(x, y)
|
||||
# define bioq_remove(x, y) bufq_remove(x, y)
|
||||
# define bioq_first(x) bufq_first(x)
|
||||
# define bio_queue_head buf_queue_head
|
||||
# define bio_bcount b_bcount
|
||||
# define bio_blkno b_blkno
|
||||
# define bio_caller1 b_caller1
|
||||
# define bio_data b_data
|
||||
# define bio_dev b_dev
|
||||
# define bio_driver1 b_driver1
|
||||
# define bio_driver2 b_driver2
|
||||
# define bio_error b_error
|
||||
# define bio_flags b_flags
|
||||
# define bio_pblkno b_pblkno
|
||||
# define bio_resid b_resid
|
||||
# define BIO_ERROR B_ERROR
|
||||
# define devstat_end_transaction_bio(x, y) devstat_end_transaction_buf(x, y)
|
||||
# define BIO_IS_READ(x) ((x)->b_flags & B_READ)
|
||||
|
||||
#else /* new bio style */
|
||||
# include <sys/bio.h>
|
||||
#define BIO_IS_READ(x) ((x)->bio_cmd == BIO_READ)
|
||||
#endif
|
426
sys/dev/aac/aac_debug.c
Normal file
426
sys/dev/aac/aac_debug.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Debugging support.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <dev/aac/aac_compat.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/devicestat.h>
|
||||
#include <sys/disk.h>
|
||||
|
||||
#include <machine/resource.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/aac/aacreg.h>
|
||||
#include <dev/aac/aacvar.h>
|
||||
|
||||
void aac_printstate0(void);
|
||||
void aac_intr0(void);
|
||||
|
||||
/********************************************************************************
|
||||
* Dump the command queue indices
|
||||
*/
|
||||
void
|
||||
aac_print_queues(struct aac_softc *sc)
|
||||
{
|
||||
device_printf(sc->aac_dev, "FIB queue header at %p queues at %p\n",
|
||||
&sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
|
||||
&sc->aac_queues->qt_HostNormCmdQueue[0]);
|
||||
device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_HOST_NORM_CMD_ENTRIES);
|
||||
device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_HOST_HIGH_CMD_ENTRIES);
|
||||
device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_ADAP_NORM_CMD_ENTRIES);
|
||||
device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_ADAP_HIGH_CMD_ENTRIES);
|
||||
device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_HOST_NORM_RESP_ENTRIES);
|
||||
device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_HOST_HIGH_RESP_ENTRIES);
|
||||
device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_ADAP_NORM_RESP_ENTRIES);
|
||||
device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX],
|
||||
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX],
|
||||
AAC_ADAP_HIGH_RESP_ENTRIES);
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Print the command queue states for controller 0 (callable from DDB)
|
||||
*/
|
||||
void
|
||||
aac_printstate0(void)
|
||||
{
|
||||
struct aac_softc *sc = devclass_get_softc(aac_devclass, 0);
|
||||
|
||||
aac_print_queues(sc);
|
||||
switch (sc->aac_hwif) {
|
||||
case AAC_HWIF_I960RX:
|
||||
device_printf(sc->aac_dev, "IDBR 0x%08x IIMR 0x%08x IISR 0x%08x\n",
|
||||
AAC_GETREG4(sc, AAC_RX_IDBR), AAC_GETREG4(sc, AAC_RX_IIMR), AAC_GETREG4(sc, AAC_RX_IISR));
|
||||
device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x OISR 0x%08x\n",
|
||||
AAC_GETREG4(sc, AAC_RX_ODBR), AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
|
||||
AAC_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY | AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
|
||||
device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x OISR 0x%08x\n",
|
||||
AAC_GETREG4(sc, AAC_RX_ODBR), AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
|
||||
break;
|
||||
case AAC_HWIF_STRONGARM:
|
||||
/* XXX implement */
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* simulate an interrupt for controller 0
|
||||
*/
|
||||
void
|
||||
aac_intr0(void)
|
||||
{
|
||||
struct aac_softc *sc = devclass_get_softc(aac_devclass, 0);
|
||||
|
||||
aac_intr(sc);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Panic in a slightly informative fashion
|
||||
*/
|
||||
void
|
||||
aac_panic(struct aac_softc *sc, char *reason)
|
||||
{
|
||||
aac_print_queues(sc);
|
||||
panic(reason);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Print a FIB
|
||||
*/
|
||||
void
|
||||
aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller)
|
||||
{
|
||||
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, " Flags 0x%x\n", fib->Header.Flags);
|
||||
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, " ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress);
|
||||
device_printf(sc->aac_dev, " SenderData 0x%x\n", fib->Header.SenderData);
|
||||
switch(fib->Header.Command) {
|
||||
case ContainerCommand:
|
||||
{
|
||||
struct aac_blockread *br = (struct aac_blockread *)fib->data;
|
||||
struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data;
|
||||
struct aac_sg_table *sg = NULL;
|
||||
int i;
|
||||
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
|
||||
aac_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); /* XXX interpret */
|
||||
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); /* XXX interpret? */
|
||||
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, /* XXX interpret */
|
||||
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 %lld creator %lld\n",
|
||||
aif->data.EN.data.EDS.eventType,
|
||||
aif->data.EN.data.EDS.DsNum,
|
||||
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 device 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, "(ConatainerZero) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrCopy: /* Container copy operation */
|
||||
device_printf(sc->aac_dev, "(ConatainerCopy) 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, "(ConatainerCreateMirror) 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, "(ConatainerMergeMirror) 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, "(ConatainerScrubMirror) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrRebuildRaid5: /* Container Rebuild Raid5 operation */
|
||||
device_printf(sc->aac_dev, "(ConatainerRebuildRaid5) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrScrubRaid5: /* Container Scrub Raid5 operation */
|
||||
device_printf(sc->aac_dev, "(ConatainerScrubRaid5) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrMorph: /* Container morph operation */
|
||||
device_printf(sc->aac_dev, "(ConatainerMorph) 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, "(ConatainerPartCopy) 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, "(ConatainerRebuildMirror) container %d\n",
|
||||
aif->data.PR[0].jd.client.container.src);
|
||||
break;
|
||||
case AifJobCtrCrazyCache: /* crazy cache */
|
||||
device_printf(sc->aac_dev, "(ConatainerCrazyCache) 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;
|
||||
}
|
||||
}
|
296
sys/dev/aac/aac_disk.c
Normal file
296
sys/dev/aac/aac_disk.c
Normal file
@ -0,0 +1,296 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <dev/aac/aac_compat.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/devicestat.h>
|
||||
#include <sys/disk.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/clock.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/aac/aacreg.h>
|
||||
#include <dev/aac/aacvar.h>
|
||||
|
||||
/*
|
||||
* Interface to parent.
|
||||
*/
|
||||
static int aac_disk_probe(device_t dev);
|
||||
static int aac_disk_attach(device_t dev);
|
||||
static int aac_disk_detach(device_t dev);
|
||||
|
||||
/*
|
||||
* Interface to the device switch.
|
||||
*/
|
||||
static d_open_t aac_disk_open;
|
||||
static d_close_t aac_disk_close;
|
||||
static d_strategy_t aac_disk_strategy;
|
||||
|
||||
#define AAC_DISK_CDEV_MAJOR 151
|
||||
|
||||
static struct cdevsw aac_disk_cdevsw = {
|
||||
/* open */ aac_disk_open,
|
||||
/* close */ aac_disk_close,
|
||||
/* read */ physread,
|
||||
/* write */ physwrite,
|
||||
/* ioctl */ noioctl,
|
||||
/* poll */ nopoll,
|
||||
/* mmap */ nommap,
|
||||
/* strategy */ aac_disk_strategy,
|
||||
/* name */ "aacd",
|
||||
/* maj */ AAC_DISK_CDEV_MAJOR,
|
||||
/* dump */ nodump,
|
||||
/* psize */ nopsize,
|
||||
/* flags */ D_DISK,
|
||||
/* bmaj */ -1
|
||||
};
|
||||
|
||||
devclass_t aac_disk_devclass;
|
||||
static struct cdevsw aac_disk_disk_cdevsw;
|
||||
#ifdef FREEBSD_4
|
||||
static int disks_registered = 0;
|
||||
#endif
|
||||
|
||||
static device_method_t aac_disk_methods[] = {
|
||||
DEVMETHOD(device_probe, aac_disk_probe),
|
||||
DEVMETHOD(device_attach, aac_disk_attach),
|
||||
DEVMETHOD(device_detach, aac_disk_detach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t aac_disk_driver = {
|
||||
"aacd",
|
||||
aac_disk_methods,
|
||||
sizeof(struct aac_disk)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0);
|
||||
|
||||
/********************************************************************************
|
||||
* Handle open from generic layer.
|
||||
*
|
||||
* This is called by the diskslice code on first open in order to get the
|
||||
* basic device geometry paramters.
|
||||
*/
|
||||
static int
|
||||
aac_disk_open(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
struct aac_disk *sc = (struct aac_disk *)dev->si_drv1;
|
||||
struct disklabel *label;
|
||||
|
||||
debug_called(4);
|
||||
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/* check that the controller is up and running */
|
||||
if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND)
|
||||
return(ENXIO);
|
||||
|
||||
/* build synthetic label */
|
||||
label = &sc->ad_disk.d_label;
|
||||
bzero(label, sizeof(*label));
|
||||
label->d_type = DTYPE_ESDI;
|
||||
label->d_secsize = AAC_BLOCK_SIZE;
|
||||
label->d_nsectors = sc->ad_sectors;
|
||||
label->d_ntracks = sc->ad_heads;
|
||||
label->d_ncylinders = sc->ad_cylinders;
|
||||
label->d_secpercyl = sc->ad_sectors * sc->ad_heads;
|
||||
label->d_secperunit = sc->ad_size;
|
||||
|
||||
sc->ad_flags |= AAC_DISK_OPEN;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Handle last close of the disk device.
|
||||
*/
|
||||
static int
|
||||
aac_disk_close(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
struct aac_disk *sc = (struct aac_disk *)dev->si_drv1;
|
||||
|
||||
debug_called(4);
|
||||
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
sc->ad_flags &= ~AAC_DISK_OPEN;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Handle an I/O request.
|
||||
*/
|
||||
static void
|
||||
aac_disk_strategy(struct bio *bp)
|
||||
{
|
||||
struct aac_disk *sc = (struct aac_disk *)bp->bio_dev->si_drv1;
|
||||
|
||||
debug_called(4);
|
||||
|
||||
/* bogus disk? */
|
||||
if (sc == NULL) {
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
bp->bio_error = EINVAL;
|
||||
biodone(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do-nothing operation? */
|
||||
if (bp->bio_bcount == 0) {
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
biodone(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* perform accounting */
|
||||
devstat_start_transaction(&sc->ad_stats);
|
||||
|
||||
/* pass the bio to the controller - it can work out who we are */
|
||||
aac_submit_bio(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Handle completion of an I/O request.
|
||||
*/
|
||||
void
|
||||
aac_complete_bio(struct bio *bp)
|
||||
{
|
||||
struct aac_disk *sc = (struct aac_disk *)bp->bio_dev->si_drv1;
|
||||
|
||||
debug_called(4);
|
||||
|
||||
devstat_end_transaction_bio(&sc->ad_stats, bp);
|
||||
biodone(bp);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Stub only.
|
||||
*/
|
||||
static int
|
||||
aac_disk_probe(device_t dev)
|
||||
{
|
||||
|
||||
debug_called(4);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Attach a unit to the controller.
|
||||
*/
|
||||
static int
|
||||
aac_disk_attach(device_t dev)
|
||||
{
|
||||
struct aac_disk *sc = (struct aac_disk *)device_get_softc(dev);
|
||||
int sgspace;
|
||||
int maxsg;
|
||||
|
||||
debug_called(4);
|
||||
|
||||
/* initialise our softc */
|
||||
sc->ad_controller = (struct aac_softc *)device_get_softc(device_get_parent(dev));
|
||||
sc->ad_container = device_get_ivars(dev);
|
||||
sc->ad_dev = dev;
|
||||
|
||||
/* require that extended translation be enabled XXX document! */
|
||||
sc->ad_size = sc->ad_container->co_mntobj.Capacity;
|
||||
if (sc->ad_size >= (2 * 1024 * 1024)) { /* 2GB */
|
||||
sc->ad_heads = 255;
|
||||
sc->ad_sectors = 63;
|
||||
} else if (sc->ad_size >= (2 * 1024 * 1024)) { /* 1GB */
|
||||
sc->ad_heads = 128;
|
||||
sc->ad_sectors = 32;
|
||||
} else {
|
||||
sc->ad_heads = 64;
|
||||
sc->ad_sectors = 32;
|
||||
}
|
||||
sc->ad_cylinders = (sc->ad_size / (sc->ad_heads * sc->ad_sectors));
|
||||
|
||||
device_printf(dev, "%uMB (%u sectors)\n",
|
||||
sc->ad_size / ((1024 * 1024) / AAC_BLOCK_SIZE), sc->ad_size);
|
||||
|
||||
devstat_add_entry(&sc->ad_stats, "aacd", device_get_unit(dev), AAC_BLOCK_SIZE,
|
||||
DEVSTAT_NO_ORDERED_TAGS,
|
||||
DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER,
|
||||
DEVSTAT_PRIORITY_ARRAY);
|
||||
|
||||
/* attach a generic disk device to ourselves */
|
||||
sc->ad_dev_t = disk_create(device_get_unit(dev), &sc->ad_disk, 0, &aac_disk_cdevsw, &aac_disk_disk_cdevsw);
|
||||
sc->ad_dev_t->si_drv1 = sc;
|
||||
#ifdef FREEBSD_4
|
||||
disks_registered++;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We can calculate the maximum number of s/g entries based on the size of the
|
||||
* FIB and the command structures packed within it.
|
||||
*/
|
||||
sgspace = (sizeof(struct aac_fib) - sizeof(struct aac_fib_header) -
|
||||
imax(sizeof(struct aac_blockwrite), sizeof(struct aac_blockread)));
|
||||
maxsg = (sgspace - sizeof(struct aac_sg_table)) / sizeof(struct aac_sg_entry);
|
||||
|
||||
/* set the maximum I/O size to the theoretical worst maximum allowed by the S/G list size */
|
||||
sc->ad_dev_t->si_iosize_max = (maxsg - 1) * PAGE_SIZE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Disconnect ourselves from the system.
|
||||
*/
|
||||
static int
|
||||
aac_disk_detach(device_t dev)
|
||||
{
|
||||
struct aac_disk *sc = (struct aac_disk *)device_get_softc(dev);
|
||||
|
||||
debug_called(4);
|
||||
|
||||
if (sc->ad_flags & AAC_DISK_OPEN)
|
||||
return(EBUSY);
|
||||
|
||||
devstat_remove_entry(&sc->ad_stats);
|
||||
#ifdef FREEBSD_4
|
||||
if (--disks_registered == 0)
|
||||
cdevsw_remove(&aac_disk_disk_cdevsw);
|
||||
#else
|
||||
disk_destroy(sc->ad_dev_t);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
78
sys/dev/aac/aac_ioctl.h
Normal file
78
sys/dev/aac/aac_ioctl.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Michael Smith
|
||||
* Copyright (c) 2000 Scott Long
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifdef AAC_COMPAT_LINUX
|
||||
|
||||
/*
|
||||
* Ioctl commands likely to be submitted from a Linux management application.
|
||||
* These bit encodings are actually descended from Windows NT. Ick.
|
||||
*/
|
||||
|
||||
#define CTL_CODE(devType, func, meth, acc) (((devType) << 16) | ((acc) << 14) | ((func) << 2) | (meth))
|
||||
#define METHOD_BUFFERED 0
|
||||
#define METHOD_IN_DIRECT 1
|
||||
#define METHOD_OUT_DIRECT 2
|
||||
#define METHOD_NEITHER 3
|
||||
#define FILE_ANY_ACCESS 0
|
||||
#define FILE_READ_ACCESS ( 0x0001 )
|
||||
#define FILE_WRITE_ACCESS ( 0x0002 )
|
||||
#define FILE_DEVICE_CONTROLLER 0x00000004
|
||||
|
||||
#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
/*
|
||||
* Support for faking the "miniport" version.
|
||||
*/
|
||||
struct aac_rev_check {
|
||||
RevComponent callingComponent;
|
||||
struct FsaRevision callingRevision;
|
||||
};
|
||||
|
||||
struct aac_rev_check_resp {
|
||||
int possiblyCompatible;
|
||||
struct FsaRevision adapterSWRevision;
|
||||
};
|
||||
|
||||
/*
|
||||
* Context passed in by a consumer looking to collect an AIF.
|
||||
*/
|
||||
#define AAC_AIF_SILLYMAGIC 0xdeadbeef
|
||||
struct get_adapter_fib_ioctl {
|
||||
u_int32_t AdapterFibContext;
|
||||
int Wait;
|
||||
caddr_t AifFib;
|
||||
};
|
||||
|
||||
#endif
|
272
sys/dev/aac/aac_pci.c
Normal file
272
sys/dev/aac/aac_pci.c
Normal file
@ -0,0 +1,272 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* PCI bus interface and resource allocation.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <dev/aac/aac_compat.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/devicestat.h>
|
||||
#include <sys/disk.h>
|
||||
|
||||
#include <machine/bus_memio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <pci/pcireg.h>
|
||||
#include <pci/pcivar.h>
|
||||
|
||||
#include <dev/aac/aacreg.h>
|
||||
#include <dev/aac/aacvar.h>
|
||||
|
||||
static int aac_pci_probe(device_t dev);
|
||||
static int aac_pci_attach(device_t dev);
|
||||
|
||||
static device_method_t aac_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, aac_pci_probe),
|
||||
DEVMETHOD(device_attach, aac_pci_attach),
|
||||
DEVMETHOD(device_detach, aac_detach),
|
||||
DEVMETHOD(device_shutdown, aac_shutdown),
|
||||
DEVMETHOD(device_suspend, aac_suspend),
|
||||
DEVMETHOD(device_resume, aac_resume),
|
||||
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t aac_pci_driver = {
|
||||
"aac",
|
||||
aac_methods,
|
||||
sizeof(struct aac_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
|
||||
|
||||
struct aac_ident
|
||||
{
|
||||
u_int16_t vendor;
|
||||
u_int16_t device;
|
||||
u_int16_t subvendor;
|
||||
u_int16_t subdevice;
|
||||
int hwif;
|
||||
char *desc;
|
||||
} aac_identifiers[] = {
|
||||
{0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, "Dell PERC 2/Si"},
|
||||
{0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, "Dell PERC 3/Di"},
|
||||
{0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, "Dell PERC 3/Si"},
|
||||
{0x9005, 0x0282, 0x9005, 0x0282, AAC_HWIF_I960RX, "Adaptec AAC-2622"},
|
||||
{0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, "Adaptec AAC-364"},
|
||||
{0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM, "Adaptec AAC-3642"},
|
||||
{0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, "Dell PERC 2/QC"},
|
||||
{0x1011, 0x0046, 0x9005, 0x1365, AAC_HWIF_STRONGARM, "Dell PERC 3/QC"}, /* XXX guess */
|
||||
{0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, "HP NetRaid-4M"},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/********************************************************************************
|
||||
* Determine whether this is one of our supported adapters.
|
||||
*/
|
||||
static int
|
||||
aac_pci_probe(device_t dev)
|
||||
{
|
||||
struct aac_ident *m;
|
||||
|
||||
debug_called(1);
|
||||
|
||||
for (m = aac_identifiers; m->vendor != 0; m++) {
|
||||
if ((m->vendor == pci_get_vendor(dev)) &&
|
||||
(m->device == pci_get_device(dev)) &&
|
||||
((m->subvendor == 0) || (m->subvendor == pci_get_subvendor(dev))) &&
|
||||
((m->subdevice == 0) || ((m->subdevice == pci_get_subdevice(dev))))) {
|
||||
|
||||
device_set_desc(dev, m->desc);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Allocate resources for our device, set up the bus interface.
|
||||
*/
|
||||
static int
|
||||
aac_pci_attach(device_t dev)
|
||||
{
|
||||
struct aac_softc *sc;
|
||||
int i, error;
|
||||
u_int32_t command;
|
||||
|
||||
debug_called(1);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the PCI register window.
|
||||
*/
|
||||
sc->aac_regs_rid = 0x10; /* first base address register */
|
||||
if ((sc->aac_regs_resource = bus_alloc_resource(sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid,
|
||||
0, ~0, 1, RF_ACTIVE)) == NULL) {
|
||||
device_printf(sc->aac_dev, "couldn't allocate register window\n");
|
||||
goto out;
|
||||
}
|
||||
sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
|
||||
sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
|
||||
|
||||
/*
|
||||
* Allocate and connect our interrupt.
|
||||
*/
|
||||
sc->aac_irq_rid = 0;
|
||||
if ((sc->aac_irq = bus_alloc_resource(sc->aac_dev, SYS_RES_IRQ, &sc->aac_irq_rid,
|
||||
0, ~0, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
|
||||
device_printf(sc->aac_dev, "can't allocate interrupt\n");
|
||||
goto out;
|
||||
}
|
||||
if (bus_setup_intr(sc->aac_dev, sc->aac_irq, INTR_TYPE_BIO, aac_intr, sc, &sc->aac_intr)) {
|
||||
device_printf(sc->aac_dev, "can't set up interrupt\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* assume failure is 'out of memory' */
|
||||
error = ENOMEM;
|
||||
|
||||
/*
|
||||
* 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(NULL, /* parent */
|
||||
1, 0, /* alignment, boundary */
|
||||
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
MAXBSIZE, AAC_MAXSGENTRIES, /* maxsize, nsegments */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
|
||||
BUS_DMA_ALLOCNOW, /* flags */
|
||||
&sc->aac_parent_dmat)) {
|
||||
device_printf(sc->aac_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->aac_parent_dmat, /* parent */
|
||||
1, 0, /* alignment, boundary */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
MAXBSIZE, AAC_MAXSGENTRIES, /* maxsize, nsegments */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
|
||||
0, /* flags */
|
||||
&sc->aac_buffer_dmat)) {
|
||||
device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create DMA tag for mapping FIBs into controller-addressable space..
|
||||
*/
|
||||
if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
|
||||
1, 0, /* alignment, boundary */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
AAC_CLUSTER_COUNT * sizeof(struct aac_fib), 1,/* maxsize, nsegments */
|
||||
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
|
||||
0, /* flags */
|
||||
&sc->aac_fib_dmat)) {
|
||||
device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect the hardware interface version, set up the bus interface indirection.
|
||||
*/
|
||||
for (i = 0; aac_identifiers[i].vendor != 0; i++) {
|
||||
if ((aac_identifiers[i].vendor == pci_get_vendor(dev)) &&
|
||||
(aac_identifiers[i].device == pci_get_device(dev))) {
|
||||
sc->aac_hwif = aac_identifiers[i].hwif;
|
||||
switch(sc->aac_hwif) {
|
||||
case AAC_HWIF_I960RX:
|
||||
debug(2, "set hardware up for i960Rx");
|
||||
sc->aac_if = aac_rx_interface;
|
||||
break;
|
||||
|
||||
case AAC_HWIF_STRONGARM:
|
||||
debug(2, "set hardware up for StrongARM");
|
||||
sc->aac_if = aac_sa_interface;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do bus-independent initialisation.
|
||||
*/
|
||||
error = aac_attach(sc);
|
||||
|
||||
out:
|
||||
if (error)
|
||||
aac_free(sc);
|
||||
return(error);
|
||||
}
|
117
sys/dev/aac/aac_tables.h
Normal file
117
sys/dev/aac/aac_tables.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Status codes for block read/write commands, etc.
|
||||
*
|
||||
* XXX many of these would not normally be returned, as they are
|
||||
* relevant only to FSA operations.
|
||||
*/
|
||||
static struct aac_code_lookup aac_command_status_table[] = {
|
||||
{"OK", 0},
|
||||
{"operation not permitted", 1},
|
||||
{"not found", 2},
|
||||
{"I/O error", 5},
|
||||
{"device not configured", 6},
|
||||
{"too big", 7},
|
||||
{"permission denoed", 13},
|
||||
{"file exists", 17},
|
||||
{"cross-device link", 18},
|
||||
{"operation not supported by device", 19},
|
||||
{"not a directory", 20},
|
||||
{"is a directory", 21},
|
||||
{"invalid argument", 22},
|
||||
{"file too large", 27},
|
||||
{"no space on device", 28},
|
||||
{"readonly filesystem", 30},
|
||||
{"too many links", 31},
|
||||
{"operation would block", 35},
|
||||
{"file name too long", 63},
|
||||
{"directory not empty", 66},
|
||||
{"quota exceeded", 69},
|
||||
{"stale file handle", 70},
|
||||
{"too many levels of remote in path", 71},
|
||||
{"bad file handle", 10001},
|
||||
{"not sync", 10002},
|
||||
{"bad cookie", 10003},
|
||||
{"operation not supported", 10004},
|
||||
{"too small", 10005},
|
||||
{"server fault", 10006},
|
||||
{"bad type", 10007},
|
||||
{"jukebox", 10008},
|
||||
{"not mounted", 10009},
|
||||
{"in maintenace mode", 10010},
|
||||
{"stale ACL", 10011},
|
||||
{NULL, 0},
|
||||
{"unknown command status", 0}
|
||||
};
|
||||
|
||||
#define AAC_COMMAND_STATUS(x) aac_describe_code(aac_command_status_table, x)
|
||||
|
||||
static struct aac_code_lookup aac_cpu_variant[] = {
|
||||
{"i960JX", CPUI960_JX},
|
||||
{"i960CX", CPUI960_CX},
|
||||
{"i960HX", CPUI960_HX},
|
||||
{"i960RX", CPUI960_RX},
|
||||
{"StrongARM SA110", CPUARM_SA110},
|
||||
{"PowerPC 603e", CPUPPC_603e},
|
||||
{"Unknown StrongARM", CPUARM_xxx},
|
||||
{"Unknown PowerPC", CPUPPC_xxx},
|
||||
{NULL, 0},
|
||||
{"Unknown processor", 0}
|
||||
};
|
||||
|
||||
static struct aac_code_lookup aac_battery_platform[] = {
|
||||
{"required battery present", PLATFORM_BAT_REQ_PRESENT},
|
||||
{"REQUIRED BATTERY NOT PRESENT", PLATFORM_BAT_REQ_NOTPRESENT},
|
||||
{"optional battery present", PLATFORM_BAT_OPT_PRESENT},
|
||||
{"optional battery not installed", PLATFORM_BAT_OPT_NOTPRESENT},
|
||||
{"no battery support", PLATFORM_BAT_NOT_SUPPORTED},
|
||||
{NULL, 0},
|
||||
{"unknown battery platform", 0}
|
||||
};
|
||||
|
||||
static struct aac_code_lookup aac_container_types[] = {
|
||||
{"Volume", CT_VOLUME},
|
||||
{"RAID 1 (Mirror)", CT_MIRROR},
|
||||
{"RAID 0 (Stripe)", CT_STRIPE},
|
||||
{"RAID 5", CT_RAID5},
|
||||
{"SSRW", CT_SSRW},
|
||||
{"SSRO", CT_SSRO},
|
||||
{"Morph", CT_MORPH},
|
||||
{"Passthrough", CT_PASSTHRU},
|
||||
{"RAID 4", CT_RAID4},
|
||||
{"RAID 10", CT_RAID10},
|
||||
{"RAID 00", CT_RAID00},
|
||||
{"Volume of Mirrors", CT_VOLUME_OF_MIRRORS},
|
||||
{"Pseudo RAID 3", CT_PSEUDO_RAID3},
|
||||
{NULL, 0},
|
||||
{"unknown", 0}
|
||||
};
|
||||
|
1082
sys/dev/aac/aacreg.h
Normal file
1082
sys/dev/aac/aacreg.h
Normal file
File diff suppressed because it is too large
Load Diff
451
sys/dev/aac/aacvar.h
Normal file
451
sys/dev/aac/aacvar.h
Normal file
@ -0,0 +1,451 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/********************************************************************************
|
||||
********************************************************************************
|
||||
Driver Parameter Definitions
|
||||
********************************************************************************
|
||||
********************************************************************************/
|
||||
|
||||
/*
|
||||
* The firmware interface allows for a 16-bit s/g list length. We limit
|
||||
* ourselves to a reasonable maximum and ensure alignment.
|
||||
*/
|
||||
#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */
|
||||
|
||||
/*
|
||||
* We allocate a small set of FIBs for the adapter to use to send us messages.
|
||||
*/
|
||||
#define AAC_ADAPTER_FIBS 8
|
||||
|
||||
/*
|
||||
* FIBs are allocated in clusters as we need them; each cluster must be physically
|
||||
* contiguous. Set the number of FIBs to try to allocate in a cluster.
|
||||
* Setting this value too high may result in FIBs not being available in conditions
|
||||
* of high load with fragmented physical memory. The value must be a multiple of
|
||||
* (PAGE_SIZE / 512).
|
||||
*/
|
||||
#define AAC_CLUSTER_COUNT 64
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Character device major numbers.
|
||||
*/
|
||||
#define AAC_DISK_MAJOR 200
|
||||
|
||||
/********************************************************************************
|
||||
********************************************************************************
|
||||
Driver Variable Definitions
|
||||
********************************************************************************
|
||||
********************************************************************************/
|
||||
|
||||
#if __FreeBSD_version >= 500005
|
||||
# include <sys/taskqueue.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Per-container data structure
|
||||
*/
|
||||
struct aac_container
|
||||
{
|
||||
struct aac_mntobj co_mntobj;
|
||||
device_t co_disk;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-disk structure
|
||||
*/
|
||||
struct aac_disk
|
||||
{
|
||||
device_t ad_dev;
|
||||
dev_t ad_dev_t;
|
||||
struct aac_softc *ad_controller;
|
||||
struct aac_container *ad_container;
|
||||
struct disk ad_disk;
|
||||
struct devstat ad_stats;
|
||||
struct disklabel ad_label;
|
||||
int ad_flags;
|
||||
#define AAC_DISK_OPEN (1<<0)
|
||||
int ad_cylinders;
|
||||
int ad_heads;
|
||||
int ad_sectors;
|
||||
u_int32_t ad_size;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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_int32_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 */
|
||||
|
||||
void (* cm_complete)(struct aac_command *cm);
|
||||
void *cm_private;
|
||||
};
|
||||
|
||||
/*
|
||||
* Command/command packet cluster.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
struct aac_command_cluster
|
||||
{
|
||||
TAILQ_ENTRY(aac_command_cluster) cmc_link;
|
||||
struct aac_fib *cmc_fibs;
|
||||
bus_dmamap_t cmc_fibmap;
|
||||
u_int32_t cmc_fibphys;
|
||||
struct aac_command cmc_command[AAC_CLUSTER_COUNT];
|
||||
};
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/* arena within which the queue structures are kept */
|
||||
u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
|
||||
|
||||
/* buffer for text messages from the controller */
|
||||
char ac_printf[AAC_PRINTF_BUFSIZE];
|
||||
|
||||
/* fib for synchronous commands */
|
||||
struct aac_fib ac_sync_fib;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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_set_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_mailboxstatus)(struct aac_softc *sc);
|
||||
void (* aif_set_interrupts)(struct aac_softc *sc, int enable);
|
||||
};
|
||||
extern struct aac_interface aac_rx_interface;
|
||||
extern struct aac_interface aac_sa_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_set_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_MAILBOXSTATUS(sc) ((sc)->aac_if.aif_get_mailboxstatus((sc)))
|
||||
#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_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag, sc->aac_bhandle, reg, val)
|
||||
#define AAC_GETREG4(sc, reg) bus_space_read_4 (sc->aac_btag, sc->aac_bhandle, reg)
|
||||
#define AAC_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag, sc->aac_bhandle, reg, val)
|
||||
#define AAC_GETREG2(sc, reg) bus_space_read_2 (sc->aac_btag, sc->aac_bhandle, reg)
|
||||
#define AAC_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag, sc->aac_bhandle, reg, val)
|
||||
#define AAC_GETREG1(sc, reg) bus_space_read_1 (sc->aac_btag, sc->aac_bhandle, reg)
|
||||
|
||||
/*
|
||||
* Per-controller structure.
|
||||
*/
|
||||
struct aac_softc
|
||||
{
|
||||
/* bus connections */
|
||||
device_t aac_dev;
|
||||
struct resource *aac_regs_resource; /* register interface window */
|
||||
int aac_regs_rid; /* resource ID */
|
||||
bus_space_handle_t aac_bhandle; /* bus space handle */
|
||||
bus_space_tag_t aac_btag; /* 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 */
|
||||
|
||||
/* controller features, limits and status */
|
||||
int aac_state;
|
||||
#define AAC_STATE_SUSPEND (1<<0)
|
||||
#define AAC_STATE_OPEN (1<<1)
|
||||
#define AAC_STATE_INTERRUPTS_ON (1<<2)
|
||||
#define AAC_STATE_AIF_SLEEPER (1<<3)
|
||||
struct FsaRevision aac_revision;
|
||||
|
||||
/* controller hardware interface */
|
||||
int aac_hwif;
|
||||
#define AAC_HWIF_I960RX 0
|
||||
#define AAC_HWIF_STRONGARM 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;
|
||||
struct aac_interface aac_if;
|
||||
|
||||
/* command/fib resources */
|
||||
TAILQ_HEAD(,aac_command_cluster) aac_clusters; /* command memory blocks */
|
||||
bus_dma_tag_t aac_fib_dmat; /* DMA tag for allocating FIBs */
|
||||
|
||||
/* command management */
|
||||
TAILQ_HEAD(,aac_command) aac_freecmds; /* command structures available for reuse */
|
||||
TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for controller resources */
|
||||
TAILQ_HEAD(,aac_command) aac_completed; /* commands which have been returned by the controller */
|
||||
struct bio_queue_head aac_bioq;
|
||||
struct aac_queue_table *aac_queues;
|
||||
struct aac_queue_entry *aac_qentries[AAC_QUEUE_COUNT];
|
||||
|
||||
/* connected containters */
|
||||
struct aac_container aac_container[AAC_MAX_CONTAINERS];
|
||||
|
||||
/* delayed activity infrastructure */
|
||||
#if __FreeBSD_version >= 500005
|
||||
struct task aac_task_complete; /* deferred-completion task */
|
||||
#endif
|
||||
struct intr_config_hook aac_ich;
|
||||
|
||||
/* management interface */
|
||||
dev_t aac_dev_t;
|
||||
struct aac_aif_command aac_aifq[AAC_AIFQ_LENGTH];
|
||||
int aac_aifq_head;
|
||||
int aac_aifq_tail;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Public functions
|
||||
*/
|
||||
extern void aac_free(struct aac_softc *sc);
|
||||
extern int aac_attach(struct aac_softc *sc);
|
||||
extern int aac_detach(device_t dev);
|
||||
extern int aac_shutdown(device_t dev);
|
||||
extern int aac_suspend(device_t dev);
|
||||
extern int aac_resume(device_t dev);
|
||||
extern void aac_intr(void *arg);
|
||||
extern devclass_t aac_devclass;
|
||||
extern void aac_submit_bio(struct bio *bp);
|
||||
extern void aac_complete_bio(struct bio *bp);
|
||||
|
||||
/*
|
||||
* Debugging levels:
|
||||
* 0 - quiet, only emit warnings
|
||||
* 1 - noisy, emit major function points and things done
|
||||
* 2 - extremely noisy, emit trace items in loops, etc.
|
||||
*/
|
||||
#ifdef AAC_DEBUG
|
||||
#define debug(level, fmt, args...) do { if (level <= AAC_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args); } while(0)
|
||||
#define debug_called(level) do { if (level <= AAC_DEBUG) printf(__FUNCTION__ ": called\n"); } while(0)
|
||||
|
||||
extern void aac_print_queues(struct aac_softc *sc);
|
||||
extern void aac_panic(struct aac_softc *sc, char *reason);
|
||||
extern void aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller);
|
||||
extern void aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif);
|
||||
|
||||
#define AAC_PRINT_FIB(sc, fib) aac_print_fib(sc, fib, __FUNCTION__)
|
||||
|
||||
#else
|
||||
#define debug(level, fmt, args...)
|
||||
#define debug_called(level)
|
||||
|
||||
#define aac_print_queues(sc)
|
||||
#define aac_panic(sc, reason)
|
||||
#define aac_print_aif(sc, aif)
|
||||
|
||||
#define AAC_PRINT_FIB(sc, fib)
|
||||
#endif
|
||||
|
||||
struct aac_code_lookup {
|
||||
char *string;
|
||||
u_int32_t code;
|
||||
};
|
||||
|
||||
/*
|
||||
* Borrowed from <struct.h>
|
||||
*/
|
||||
/* Offset of the field in the structure. */
|
||||
#define fldoff(name, field) \
|
||||
((int)&(((struct name *)0)->field))
|
||||
|
||||
/********************************************************************************
|
||||
* Queue primitives
|
||||
*
|
||||
* These are broken out individually to make statistics gathering easier.
|
||||
*/
|
||||
|
||||
static __inline void
|
||||
aac_enqueue_ready(struct aac_command *cm)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ready, cm, cm_link);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
aac_requeue_ready(struct aac_command *cm)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ready, cm, cm_link);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static __inline struct aac_command *
|
||||
aac_dequeue_ready(struct aac_softc *sc)
|
||||
{
|
||||
struct aac_command *cm;
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
if ((cm = TAILQ_FIRST(&sc->aac_ready)) != NULL)
|
||||
TAILQ_REMOVE(&sc->aac_ready, cm, cm_link);
|
||||
splx(s);
|
||||
return(cm);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
aac_enqueue_completed(struct aac_command *cm)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
TAILQ_INSERT_TAIL(&cm->cm_sc->aac_completed, cm, cm_link);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static __inline struct aac_command *
|
||||
aac_dequeue_completed(struct aac_softc *sc)
|
||||
{
|
||||
struct aac_command *cm;
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
if ((cm = TAILQ_FIRST(&sc->aac_completed)) != NULL)
|
||||
TAILQ_REMOVE(&sc->aac_completed, cm, cm_link);
|
||||
splx(s);
|
||||
return(cm);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
aac_enqueue_free(struct aac_command *cm)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
TAILQ_INSERT_HEAD(&cm->cm_sc->aac_freecmds, cm, cm_link);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static __inline struct aac_command *
|
||||
aac_dequeue_free(struct aac_softc *sc)
|
||||
{
|
||||
struct aac_command *cm;
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
if ((cm = TAILQ_FIRST(&sc->aac_freecmds)) != NULL)
|
||||
TAILQ_REMOVE(&sc->aac_freecmds, cm, cm_link);
|
||||
splx(s);
|
||||
return(cm);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
aac_enqueue_cluster(struct aac_softc *sc, struct aac_command_cluster *cmc)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
TAILQ_INSERT_HEAD(&sc->aac_clusters, cmc, cmc_link);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static __inline struct aac_command_cluster *
|
||||
aac_dequeue_cluster(struct aac_softc *sc)
|
||||
{
|
||||
struct aac_command_cluster *cmc;
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
if ((cmc = TAILQ_FIRST(&sc->aac_clusters)) != NULL)
|
||||
TAILQ_REMOVE(&sc->aac_clusters, cmc, cmc_link);
|
||||
splx(s);
|
||||
return(cmc);
|
||||
}
|
@ -112,6 +112,7 @@ device cd # CD
|
||||
device pass # Passthrough device (direct SCSI access)
|
||||
|
||||
# RAID controllers
|
||||
device aac # Adaptec FSA RAID
|
||||
device ida # Compaq Smart RAID
|
||||
device amr # AMI MegaRAID
|
||||
device mlx # Mylex DAC960 family
|
||||
|
@ -1330,6 +1330,11 @@ options DPT_ALLOW_MEMIO
|
||||
#
|
||||
device mly
|
||||
|
||||
#
|
||||
# Adaptec FSA RAID controllers, including integrated DELL controllers,
|
||||
# the Dell PERC 2/QC and the HP NetRAID-4M
|
||||
device aac
|
||||
|
||||
#
|
||||
# Compaq Smart RAID, Mylex DAC960 and AMI MegaRAID controllers. Only
|
||||
# one entry is needed; the code will find and configure all supported
|
||||
|
@ -17,7 +17,7 @@ SUBDIR= 3dfx accf_data accf_http agp aha amr an aue \
|
||||
|
||||
# XXX some of these can move to the general case when de-i386'ed
|
||||
.if ${MACHINE_ARCH} == "i386"
|
||||
SUBDIR+=asr bktr coff fpu gnufpu ibcs2 linprocfs linux mly splash streams \
|
||||
SUBDIR+=aac asr bktr coff fpu gnufpu ibcs2 linprocfs linux mly splash streams \
|
||||
svr4 vesa wi
|
||||
.endif
|
||||
|
||||
|
13
sys/modules/aac/Makefile
Normal file
13
sys/modules/aac/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/aac
|
||||
KMOD = aac
|
||||
SRCS = aac.c aac_pci.c aac_disk.c
|
||||
SRCS += device_if.h bus_if.h pci_if.h
|
||||
|
||||
CFLAGS+= -DAAC_COMPAT_LINUX
|
||||
|
||||
#CFLAGS+= -DAAC_DEBUG=2
|
||||
#SRCS += aac_debug.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
78
sys/sys/aac_ioctl.h
Normal file
78
sys/sys/aac_ioctl.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Michael Smith
|
||||
* Copyright (c) 2000 Scott Long
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifdef AAC_COMPAT_LINUX
|
||||
|
||||
/*
|
||||
* Ioctl commands likely to be submitted from a Linux management application.
|
||||
* These bit encodings are actually descended from Windows NT. Ick.
|
||||
*/
|
||||
|
||||
#define CTL_CODE(devType, func, meth, acc) (((devType) << 16) | ((acc) << 14) | ((func) << 2) | (meth))
|
||||
#define METHOD_BUFFERED 0
|
||||
#define METHOD_IN_DIRECT 1
|
||||
#define METHOD_OUT_DIRECT 2
|
||||
#define METHOD_NEITHER 3
|
||||
#define FILE_ANY_ACCESS 0
|
||||
#define FILE_READ_ACCESS ( 0x0001 )
|
||||
#define FILE_WRITE_ACCESS ( 0x0002 )
|
||||
#define FILE_DEVICE_CONTROLLER 0x00000004
|
||||
|
||||
#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
/*
|
||||
* Support for faking the "miniport" version.
|
||||
*/
|
||||
struct aac_rev_check {
|
||||
RevComponent callingComponent;
|
||||
struct FsaRevision callingRevision;
|
||||
};
|
||||
|
||||
struct aac_rev_check_resp {
|
||||
int possiblyCompatible;
|
||||
struct FsaRevision adapterSWRevision;
|
||||
};
|
||||
|
||||
/*
|
||||
* Context passed in by a consumer looking to collect an AIF.
|
||||
*/
|
||||
#define AAC_AIF_SILLYMAGIC 0xdeadbeef
|
||||
struct get_adapter_fib_ioctl {
|
||||
u_int32_t AdapterFibContext;
|
||||
int Wait;
|
||||
caddr_t AifFib;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user