3ware 9000 driver, contributed by Wasabi Systems and written
by Jordan Rhody (based on the FreeBSD driver). Contributed in NetBSD PR 33364.
This commit is contained in:
parent
aecdec648e
commit
a4dd1e2635
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.pci,v 1.253 2006/05/07 01:32:43 jmcneill Exp $
|
||||
# $NetBSD: files.pci,v 1.254 2006/05/24 23:44:28 wrstuden Exp $
|
||||
#
|
||||
# Config file and device description for machine-independent PCI code.
|
||||
# Included by ports that need it. Requires that the SCSI files be
|
||||
|
@ -59,6 +59,13 @@ file dev/pci/twe.c twe
|
|||
attach ld at twe with ld_twe
|
||||
file dev/pci/ld_twe.c ld_twe
|
||||
|
||||
device twa {unit = -1}
|
||||
attach twa at pci
|
||||
file dev/pci/twa.c twa
|
||||
|
||||
attach ld at twa with ld_twa
|
||||
file dev/pci/ld_twa.c ld_twa
|
||||
|
||||
# AMI RAID controllers
|
||||
device amr {unit = -1}
|
||||
attach amr at pci
|
||||
|
|
|
@ -0,0 +1,315 @@
|
|||
/* $wasabi: ld_twa.c,v 1.9 2006/02/14 18:44:37 jordanr Exp $ */
|
||||
/* $netbsd: $ */
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jordan Rhody of Wasabi Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 3ware "Apache" RAID controller front-end for ld(4) driver.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$wasabi: ld_twa.c,v 1.9 2006/02/14 18:44:37 jordanr Exp $");
|
||||
|
||||
#include "rnd.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/bufq.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/dkio.h>
|
||||
#include <sys/disk.h>
|
||||
#if NRND > 0
|
||||
#include <sys/rnd.h>
|
||||
#endif
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <dev/ldvar.h>
|
||||
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsipi_disk.h>
|
||||
#include <dev/scsipi/scsipiconf.h>
|
||||
#include <dev/scsipi/scsi_disk.h>
|
||||
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/twareg.h>
|
||||
#include <dev/pci/twavar.h>
|
||||
|
||||
struct ld_twa_softc {
|
||||
struct ld_softc sc_ld;
|
||||
int sc_hwunit;
|
||||
};
|
||||
|
||||
static void ld_twa_attach(struct device *, struct device *, void *);
|
||||
static int ld_twa_detach(struct device *, int);
|
||||
static int ld_twa_dobio(struct ld_twa_softc *, void *, int, int,
|
||||
struct buf *);
|
||||
static int ld_twa_dump(struct ld_softc *, void *, int, int);
|
||||
static int ld_twa_flush(struct ld_softc *);
|
||||
static void ld_twa_handler(struct twa_request *);
|
||||
static int ld_twa_match(struct device *, struct cfdata *, void *);
|
||||
static int ld_twa_start(struct ld_softc *, struct buf *);
|
||||
|
||||
static void ld_twa_adjqparam(struct device *, int);
|
||||
|
||||
static int ld_twa_scsicmd(struct ld_twa_softc *,
|
||||
struct twa_request *, struct buf *);
|
||||
|
||||
CFATTACH_DECL(ld_twa, sizeof(struct ld_twa_softc),
|
||||
ld_twa_match, ld_twa_attach, ld_twa_detach, NULL);
|
||||
|
||||
static const struct twa_callbacks ld_twa_callbacks = {
|
||||
ld_twa_adjqparam,
|
||||
};
|
||||
|
||||
static int
|
||||
ld_twa_match(struct device *parent, struct cfdata *match, void *aux)
|
||||
{
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
ld_twa_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct twa_attach_args *twa_args;
|
||||
struct ld_twa_softc *sc;
|
||||
struct ld_softc *ld;
|
||||
struct twa_softc *twa;
|
||||
|
||||
sc = (struct ld_twa_softc *)self;
|
||||
ld = &sc->sc_ld;
|
||||
twa = (struct twa_softc *)parent;
|
||||
twa_args = aux;
|
||||
|
||||
twa_register_callbacks(twa, twa_args->twaa_unit, &ld_twa_callbacks);
|
||||
|
||||
sc->sc_hwunit = twa_args->twaa_unit;
|
||||
ld->sc_maxxfer = twa_get_maxxfer(twa_get_maxsegs());
|
||||
ld->sc_secperunit = twa->sc_units[sc->sc_hwunit].td_size;
|
||||
ld->sc_flags = LDF_ENABLED;
|
||||
ld->sc_secsize = TWA_SECTOR_SIZE;
|
||||
ld->sc_maxqueuecnt = twa->sc_openings;
|
||||
ld->sc_start = ld_twa_start;
|
||||
ld->sc_dump = ld_twa_dump;
|
||||
ld->sc_flush = ld_twa_flush;
|
||||
ldattach(ld);
|
||||
}
|
||||
|
||||
static int
|
||||
ld_twa_detach(struct device *self, int flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = ldbegindetach((struct ld_softc *)self, flags)) != 0)
|
||||
return (error);
|
||||
ldenddetach((struct ld_softc *)self);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ld_twa_dobio(struct ld_twa_softc *sc, void *data, int datasize, int blkno,
|
||||
struct buf *bp)
|
||||
{
|
||||
int rv;
|
||||
struct twa_request *tr;
|
||||
struct twa_softc *twa;
|
||||
|
||||
twa = (struct twa_softc *)sc->sc_ld.sc_dv.dv_parent;
|
||||
|
||||
if ((tr = twa_get_request(twa, 0)) == NULL) {
|
||||
return (EAGAIN);
|
||||
}
|
||||
if (bp->b_flags & B_READ) {
|
||||
tr->tr_flags = TWA_CMD_DATA_OUT;
|
||||
} else {
|
||||
tr->tr_flags = TWA_CMD_DATA_IN;
|
||||
}
|
||||
|
||||
tr->tr_data = data;
|
||||
tr->tr_length = datasize;
|
||||
tr->tr_cmd_pkt_type =
|
||||
(TWA_CMD_PKT_TYPE_9K | TWA_CMD_PKT_TYPE_EXTERNAL);
|
||||
|
||||
tr->tr_command->cmd_hdr.header_desc.size_header = 128;
|
||||
|
||||
tr->tr_command->command.cmd_pkt_9k.command.opcode =
|
||||
TWA_OP_EXECUTE_SCSI_COMMAND;
|
||||
tr->tr_command->command.cmd_pkt_9k.unit =
|
||||
sc->sc_hwunit;
|
||||
tr->tr_command->command.cmd_pkt_9k.request_id =
|
||||
tr->tr_request_id;
|
||||
tr->tr_command->command.cmd_pkt_9k.status = 0;
|
||||
tr->tr_command->command.cmd_pkt_9k.sgl_entries = 1;
|
||||
tr->tr_command->command.cmd_pkt_9k.sgl_offset = 16;
|
||||
|
||||
/* offset from end of hdr = max cdb len */
|
||||
ld_twa_scsicmd(sc, tr, bp);
|
||||
|
||||
tr->tr_callback = ld_twa_handler;
|
||||
tr->tr_ld_sc = sc;
|
||||
|
||||
tr->bp = bp;
|
||||
|
||||
rv = twa_map_request(tr);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
ld_twa_start(struct ld_softc *ld, struct buf *bp)
|
||||
{
|
||||
|
||||
return (ld_twa_dobio((struct ld_twa_softc *)ld, bp->b_data,
|
||||
bp->b_bcount, bp->b_rawblkno, bp));
|
||||
}
|
||||
|
||||
static void
|
||||
ld_twa_handler(struct twa_request *tr)
|
||||
{
|
||||
uint8_t status;
|
||||
struct buf *bp;
|
||||
struct ld_twa_softc *sc;
|
||||
struct twa_softc *twa;
|
||||
|
||||
bp = tr->bp;
|
||||
sc = (struct ld_twa_softc *)tr->tr_ld_sc;
|
||||
twa = (struct twa_softc *)sc->sc_ld.sc_dv.dv_parent;
|
||||
|
||||
status = tr->tr_command->command.cmd_pkt_9k.status;
|
||||
|
||||
if (status != 0) {
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = EIO;
|
||||
bp->b_resid = bp->b_bcount;
|
||||
} else {
|
||||
bp->b_resid = 0;
|
||||
bp->b_error = 0;
|
||||
}
|
||||
twa_release_request(tr);
|
||||
|
||||
lddone(&sc->sc_ld, bp);
|
||||
}
|
||||
|
||||
static int
|
||||
ld_twa_dump(struct ld_softc *ld, void *data, int blkno, int blkcnt)
|
||||
{
|
||||
|
||||
return (ld_twa_dobio((struct ld_twa_softc *)ld, data,
|
||||
blkcnt * ld->sc_secsize, blkno, NULL));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ld_twa_flush(struct ld_softc *ld)
|
||||
{
|
||||
int s, rv = 0;
|
||||
struct twa_request *tr;
|
||||
struct twa_softc *twa = (void *)ld->sc_dv.dv_parent;
|
||||
struct ld_twa_softc *sc = (void *)ld;
|
||||
struct twa_command_generic *generic_cmd;
|
||||
|
||||
/* Get a request packet. */
|
||||
tr = twa_get_request_wait(twa, 0);
|
||||
KASSERT(tr != NULL);
|
||||
|
||||
tr->tr_cmd_pkt_type =
|
||||
(TWA_CMD_PKT_TYPE_9K | TWA_CMD_PKT_TYPE_EXTERNAL);
|
||||
|
||||
tr->tr_callback = twa_request_wait_handler;
|
||||
tr->tr_ld_sc = sc;
|
||||
|
||||
tr->tr_command->cmd_hdr.header_desc.size_header = 128;
|
||||
|
||||
generic_cmd = &(tr->tr_command->command.cmd_pkt_7k.generic);
|
||||
generic_cmd->opcode = TWA_OP_FLUSH;
|
||||
generic_cmd->size = 2;
|
||||
generic_cmd->unit = sc->sc_hwunit;
|
||||
generic_cmd->request_id = tr->tr_request_id;
|
||||
generic_cmd->sgl_offset = 0;
|
||||
generic_cmd->host_id = 0;
|
||||
generic_cmd->status = 0;
|
||||
generic_cmd->flags = 0;
|
||||
generic_cmd->count = 0;
|
||||
rv = twa_map_request(tr);
|
||||
s = splbio();
|
||||
while (tr->tr_status != TWA_CMD_COMPLETE)
|
||||
if ((rv = tsleep(tr, PRIBIO, "twaflush", 60 * hz)) != 0)
|
||||
break;
|
||||
twa_release_request(tr);
|
||||
splx(s);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static void
|
||||
ld_twa_adjqparam(struct device *self, int openings)
|
||||
{
|
||||
|
||||
ldadjqparam((struct ld_softc *)self, openings);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ld_twa_scsicmd(struct ld_twa_softc *sc,
|
||||
struct twa_request *tr, struct buf *bp)
|
||||
{
|
||||
if (tr->tr_flags == TWA_CMD_DATA_IN) {
|
||||
tr->tr_command->command.cmd_pkt_9k.cdb[0] = WRITE_16;
|
||||
} else {
|
||||
tr->tr_command->command.cmd_pkt_9k.cdb[0] = READ_16;
|
||||
}
|
||||
tr->tr_command->command.cmd_pkt_9k.cdb[1] =
|
||||
(sc->sc_hwunit << 5); /* lun for CDB */
|
||||
|
||||
_lto8b(htole64(bp->b_rawblkno),
|
||||
&tr->tr_command->command.cmd_pkt_9k.cdb[2]);
|
||||
_lto4b(htole32((bp->b_bcount / TWA_SECTOR_SIZE)),
|
||||
&tr->tr_command->command.cmd_pkt_9k.cdb[10]);
|
||||
|
||||
tr->tr_command->command.cmd_pkt_9k.cdb[14] = 0;
|
||||
tr->tr_command->command.cmd_pkt_9k.cdb[15] = 0;
|
||||
|
||||
return (0);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,155 @@
|
|||
/* $wasabi: twaio.h,v 1.8 2006/04/27 17:12:39 wrstuden Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2005-2006 Wasabi Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Your Wasabi Systems License Agreement specifies the terms and
|
||||
* conditions for use and redistribution.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003-04 3ware, 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: src/sys/dev/twa/twa_ioctl.h,v 1.1 2004/03/30 03:45:59 vkashyap Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* 3ware driver for 9000 series storage controllers.
|
||||
*
|
||||
* Author: Vinod Kashyap
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _DEV_PCI_TWAIO_H_
|
||||
#define _DEV_PCI_TWAIO_H_
|
||||
|
||||
#define TWA_AEN_NOT_RETRIEVED 0x1
|
||||
#define TWA_AEN_RETRIEVED 0x2
|
||||
|
||||
#define TWA_ERROR_AEN_NO_EVENTS 0x1003 /* No more events */
|
||||
#define TWA_ERROR_AEN_OVERFLOW 0x1004 /* AEN clobber occurred */
|
||||
|
||||
#define TWA_ERROR_IOCTL_LOCK_NOT_HELD 0x1001 /* Not locked */
|
||||
#define TWA_ERROR_IOCTL_LOCK_ALREADY_HELD 0x1002 /* Already locked */
|
||||
|
||||
|
||||
struct twa_scan_bus_packet {
|
||||
uint32_t unit;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tw_cl_event_packet {
|
||||
uint32_t sequence_id;
|
||||
uint32_t time_stamp_sec;
|
||||
uint16_t aen_code;
|
||||
uint8_t severity;
|
||||
uint8_t retrieved;
|
||||
uint8_t repeat_count;
|
||||
uint8_t parameter_len;
|
||||
uint8_t parameter_data[98];
|
||||
uint32_t event_src;
|
||||
uint8_t severity_str[20];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tw_cl_lock_packet {
|
||||
uint32_t timeout_msec;
|
||||
uint32_t time_remaining_msec;
|
||||
uint32_t force_flag;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct tw_cl_compatibility_packet {
|
||||
uint8_t driver_version[32];/* driver version */
|
||||
uint16_t working_srl; /* driver & firmware negotiated srl */
|
||||
uint16_t working_branch; /* branch # of the firmware that the driver is compatible with */
|
||||
uint16_t working_build; /* build # of the firmware that the driver is compatible with */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_driver_packet {
|
||||
uint32_t control_code;
|
||||
uint32_t status;
|
||||
uint32_t unique_id;
|
||||
uint32_t sequence_id;
|
||||
uint32_t os_status;
|
||||
uint32_t buffer_length;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Account for differences between 32/64 bit system. Offsets into memory
|
||||
* are anticipated for driver/firmware command packets and having a
|
||||
* variable sized pointer depending on architecture add 4 bytes to any offset
|
||||
* after the pdata declaration
|
||||
*/
|
||||
#define TW_SIZEOF_VOIDPTR (sizeof(void *))
|
||||
|
||||
struct twa_ioctl_9k {
|
||||
struct twa_driver_packet twa_drvr_pkt;
|
||||
void *pdata; /* points to data_buf */
|
||||
int8_t padding[488 - TW_SIZEOF_VOIDPTR];
|
||||
struct twa_command_packet twa_cmd_pkt;
|
||||
int8_t data_buf[1];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/*
|
||||
* We need the structure below to ensure that the first byte of
|
||||
* data_buf is not overwritten by the kernel, after we return
|
||||
* from the ioctl call. Note that twa_cmd_pkt has been reduced
|
||||
* to an array of 1024 bytes even though it's actually 2048 bytes
|
||||
* in size. This is because, we don't expect requests from user
|
||||
* land requiring 2048 (273 sg elements) byte cmd pkts.
|
||||
*/
|
||||
typedef struct twa_ioctl_no_data_buf {
|
||||
struct twa_driver_packet twa_drvr_pkt;
|
||||
void *pdata; /* points to data_buf */
|
||||
int8_t padding[484];
|
||||
struct twa_command_packet twa_cmd_pkt;
|
||||
} __attribute__ ((packed)) TWA_IOCTL_NO_DATA_BUF;
|
||||
|
||||
/*
|
||||
* Get the device external name of the specified array unit.
|
||||
*/
|
||||
/* WASABI */
|
||||
struct twa_unitname {
|
||||
int tn_unit;
|
||||
char tn_name[16]; /* XXX sizeof(dev->dv_xname) */
|
||||
};
|
||||
|
||||
#define TW_OSL_IOCTL_SCAN_BUS _IO ('T', 200)
|
||||
|
||||
#define TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH \
|
||||
_IOWR('T', 202, TWA_IOCTL_NO_DATA_BUF)
|
||||
|
||||
#define TW_CL_IOCTL_GET_FIRST_EVENT _IOWR('T', 203, TWA_IOCTL_NO_DATA_BUF)
|
||||
#define TW_CL_IOCTL_GET_LAST_EVENT _IOWR('T', 204, TWA_IOCTL_NO_DATA_BUF)
|
||||
#define TW_CL_IOCTL_GET_NEXT_EVENT _IOWR('T', 205, TWA_IOCTL_NO_DATA_BUF)
|
||||
#define TW_CL_IOCTL_GET_PREVIOUS_EVENT _IOWR('T', 206, TWA_IOCTL_NO_DATA_BUF)
|
||||
#define TW_CL_IOCTL_GET_LOCK _IOWR('T', 207, TWA_IOCTL_NO_DATA_BUF)
|
||||
#define TW_CL_IOCTL_RELEASE_LOCK _IOWR('T', 208, TWA_IOCTL_NO_DATA_BUF)
|
||||
#define TW_CL_IOCTL_GET_COMPATIBILITY_INFO \
|
||||
_IOWR('T', 209, TWA_IOCTL_NO_DATA_BUF)
|
||||
/* WASABI */
|
||||
#define TWA_IOCTL_GET_UNITNAME _IOWR('T', 220, struct twa_unitname)
|
||||
|
||||
#endif /* _DEV_PCI_TWAIO_H_ */
|
|
@ -0,0 +1,510 @@
|
|||
/* $wasabi: twareg.h,v 1.11 2006/04/27 17:12:39 wrstuden Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2005-2006 Wasabi Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Your Wasabi Systems License Agreement specifies the terms and
|
||||
* conditions for use and redistribution.
|
||||
*/
|
||||
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003-04 3ware, 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: src/sys/dev/twa/twa_reg.h,v 1.2 2004/08/18 16:14:44 vkashyap Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* 3ware driver for 9000 series storage controllers.
|
||||
*
|
||||
* Author: Vinod Kashyap
|
||||
*/
|
||||
|
||||
#ifndef _PCI_TWAREG_H_
|
||||
#define _PCI_TWAREG_H_
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#include <machine/bus.h>
|
||||
|
||||
/*
|
||||
* The following macro has no business being in twa_reg.h. It should probably
|
||||
* be defined in twa_includes.h, before the #include twa_reg.h.... But that
|
||||
* causes the API to run into build errors. Will leave it here for now...
|
||||
*/
|
||||
#define TWA_64BIT_ADDRESSES ((sizeof(bus_addr_t) == 8) ? 1 : 0)
|
||||
|
||||
/*
|
||||
* Define the following here since it relies on TWA_64BIT_ADDRESSES which
|
||||
* depends on sizeof(bus_addr_t), which is not exported to userland.
|
||||
* The userland API shouldn't care about the kernel's bus_addr_t.
|
||||
* For the userland API, use the array size that we would use for 32-bit
|
||||
* addresses since that's what we use in the sg structure definition.
|
||||
* The userland API does not actually appear to use the array, but it
|
||||
* does include the array in various command structures.
|
||||
*/
|
||||
#define TWA_MAX_SG_ELEMENTS (TWA_64BIT_ADDRESSES ? 70 : 105)
|
||||
#else
|
||||
#define TWA_MAX_SG_ELEMENTS 105
|
||||
#endif
|
||||
|
||||
#define TWAQ_FREE 0
|
||||
#define TWAQ_BUSY 1
|
||||
#define TWAQ_PENDING 2
|
||||
#define TWAQ_COMPLETE 3
|
||||
#define TWAQ_IO_PENDING 4
|
||||
#define TWAQ_COUNT 5 /* total number of queues */
|
||||
|
||||
#define TWA_DRIVER_VERSION_STRING "1.00.00.000"
|
||||
|
||||
#define TWA_REQUEST_TIMEOUT_PERIOD 60 /* seconds */
|
||||
|
||||
#define TWA_MESSAGE_SOURCE_CONTROLLER_ERROR 3
|
||||
|
||||
/* Register offsets from base address. */
|
||||
#define TWA_CONTROL_REGISTER_OFFSET 0x0
|
||||
#define TWA_STATUS_REGISTER_OFFSET 0x4
|
||||
#define TWA_COMMAND_QUEUE_OFFSET 0x8
|
||||
#define TWA_RESPONSE_QUEUE_OFFSET 0xC
|
||||
#define TWA_COMMAND_QUEUE_OFFSET_LOW 0x20
|
||||
#define TWA_COMMAND_QUEUE_OFFSET_HIGH 0x24
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#define TWA_WRITE_REGISTER(sc, offset, val) \
|
||||
bus_space_write_4(sc->twa_bus_iot, sc->twa_bus_ioh, offset, (u_int32_t)val)
|
||||
|
||||
#define TWA_WRITE_COMMAND_QUEUE(sc, val) \
|
||||
do { \
|
||||
if (TWA_64BIT_ADDRESSES) { \
|
||||
/* First write the low 4 bytes, then the high 4. */ \
|
||||
TWA_WRITE_REGISTER(sc, TWA_COMMAND_QUEUE_OFFSET_LOW, \
|
||||
(u_int32_t)(val)); \
|
||||
TWA_WRITE_REGISTER(sc, TWA_COMMAND_QUEUE_OFFSET_HIGH,\
|
||||
(u_int32_t)(((u_int64_t)val)>>32)); \
|
||||
} else \
|
||||
TWA_WRITE_REGISTER(sc, TWA_COMMAND_QUEUE_OFFSET,\
|
||||
(u_int32_t)(val)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* Control register bit definitions. */
|
||||
#define TWA_CONTROL_CLEAR_SBUF_WRITE_ERROR 0x00000008
|
||||
#define TWA_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020
|
||||
#define TWA_CONTROL_DISABLE_INTERRUPTS 0x00000040
|
||||
#define TWA_CONTROL_ENABLE_INTERRUPTS 0x00000080
|
||||
#define TWA_CONTROL_ISSUE_SOFT_RESET 0x00000100
|
||||
#define TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT 0x00004000
|
||||
#define TWA_CONTROL_UNMASK_COMMAND_INTERRUPT 0x00008000
|
||||
#define TWA_CONTROL_MASK_RESPONSE_INTERRUPT 0x00010000
|
||||
#define TWA_CONTROL_MASK_COMMAND_INTERRUPT 0x00020000
|
||||
#define TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT 0x00040000
|
||||
#define TWA_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000
|
||||
#define TWA_CONTROL_CLEAR_PCI_ABORT 0x00100000
|
||||
#define TWA_CONTROL_CLEAR_QUEUE_ERROR 0x00400000
|
||||
#define TWA_CONTROL_CLEAR_PARITY_ERROR 0x00800000
|
||||
|
||||
/* Status register bit definitions. */
|
||||
#define TWA_STATUS_ROM_BIOS_IN_SBUF 0x00000002
|
||||
#define TWA_STATUS_SBUF_WRITE_ERROR 0x00000008
|
||||
#define TWA_STATUS_COMMAND_QUEUE_EMPTY 0x00001000
|
||||
#define TWA_STATUS_MICROCONTROLLER_READY 0x00002000
|
||||
#define TWA_STATUS_RESPONSE_QUEUE_EMPTY 0x00004000
|
||||
#define TWA_STATUS_COMMAND_QUEUE_FULL 0x00008000
|
||||
#define TWA_STATUS_RESPONSE_INTERRUPT 0x00010000
|
||||
#define TWA_STATUS_COMMAND_INTERRUPT 0x00020000
|
||||
#define TWA_STATUS_ATTENTION_INTERRUPT 0x00040000
|
||||
#define TWA_STATUS_HOST_INTERRUPT 0x00080000
|
||||
#define TWA_STATUS_PCI_ABORT_INTERRUPT 0x00100000
|
||||
#define TWA_STATUS_MICROCONTROLLER_ERROR 0x00200000
|
||||
#define TWA_STATUS_QUEUE_ERROR_INTERRUPT 0x00400000
|
||||
#define TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT 0x00800000
|
||||
#define TWA_STATUS_MINOR_VERSION_MASK 0x0F000000
|
||||
#define TWA_STATUS_MAJOR_VERSION_MASK 0xF0000000
|
||||
|
||||
#define TWA_STATUS_EXPECTED_BITS 0x00002000
|
||||
#define TWA_STATUS_UNEXPECTED_BITS 0x00F00000
|
||||
|
||||
/* For use with the %b printf format. */
|
||||
#define TWA_STATUS_BITS_DESCRIPTION \
|
||||
"\20\15CMD_Q_EMPTY\16MC_RDY\17RESP_Q_EMPTY\20CMD_Q_FULL\21RESP_INTR\22CMD_INTR\23ATTN_INTR\24HOST_INTR\25PCI_ABRT\26MC_ERR\27Q_ERR\30PCI_PERR\n"
|
||||
|
||||
/* Detect inconsistencies in the status register. */
|
||||
#define TWA_STATUS_ERRORS(x) \
|
||||
((x & TWA_STATUS_UNEXPECTED_BITS) && \
|
||||
(x & TWA_STATUS_MICROCONTROLLER_READY))
|
||||
|
||||
/* PCI related defines. */
|
||||
#define TWA_IO_CONFIG_REG 0x10
|
||||
#define TWA_DEVICE_NAME "3ware 9000 series Storage Controller"
|
||||
#define TWA_VENDOR_ID 0x13C1
|
||||
#define TWA_DEVICE_ID_9K 0x1002
|
||||
|
||||
#define TWA_PCI_CONFIG_CLEAR_PARITY_ERROR 0xc100
|
||||
#define TWA_PCI_CONFIG_CLEAR_PCI_ABORT 0x2000
|
||||
|
||||
/* Command packet opcodes. */
|
||||
#define TWA_OP_NOP 0x00
|
||||
#define TWA_OP_INIT_CONNECTION 0x01
|
||||
#define TWA_OP_READ 0x02
|
||||
#define TWA_OP_WRITE 0x03
|
||||
#define TWA_OP_READVERIFY 0x04
|
||||
#define TWA_OP_VERIFY 0x05
|
||||
#define TWA_OP_ZEROUNIT 0x08
|
||||
#define TWA_OP_REPLACEUNIT 0x09
|
||||
#define TWA_OP_HOTSWAP 0x0A
|
||||
#define TWA_OP_SELFTESTS 0x0B
|
||||
#define TWA_OP_SYNC_PARAM 0x0C
|
||||
#define TWA_OP_REORDER_UNITS 0x0D
|
||||
#define TWA_OP_FLUSH 0x0E
|
||||
#define TWA_OP_EXECUTE_SCSI_COMMAND 0x10
|
||||
#define TWA_OP_ATA_PASSTHROUGH 0x11
|
||||
#define TWA_OP_GET_PARAM 0x12
|
||||
#define TWA_OP_SET_PARAM 0x13
|
||||
#define TWA_OP_CREATEUNIT 0x14
|
||||
#define TWA_OP_DELETEUNIT 0x15
|
||||
#define TWA_OP_DOWNLOAD_FIRMWARE 0x16
|
||||
#define TWA_OP_REBUILDUNIT 0x17
|
||||
#define TWA_OP_POWER_MANAGEMENT 0x18
|
||||
|
||||
#define TWA_OP_REMOTE_PRINT 0x1B
|
||||
#define TWA_OP_RESET_FIRMWARE 0x1C
|
||||
#define TWA_OP_DEBUG 0x1D
|
||||
|
||||
#define TWA_OP_DIAGNOSTICS 0x1F
|
||||
|
||||
/* Misc defines. */
|
||||
#define TWA_ALIGNMENT 0x4
|
||||
#define TWA_MAX_UNITS 16
|
||||
#define TWA_INIT_MESSAGE_CREDITS 0x100
|
||||
#define TWA_SHUTDOWN_MESSAGE_CREDITS 0x001
|
||||
#define TWA_64BIT_SG_ADDRESSES 0x00000001
|
||||
#define TWA_EXTENDED_INIT_CONNECT 0x00000002
|
||||
#define TWA_BASE_MODE 1
|
||||
#define TWA_BASE_FW_SRL 24
|
||||
#define TWA_BASE_FW_BRANCH 0
|
||||
#define TWA_BASE_FW_BUILD 1
|
||||
#define TWA_CURRENT_FW_SRL 28
|
||||
#define TWA_CURRENT_FW_BRANCH 4
|
||||
#define TWA_CURRENT_FW_BUILD 9
|
||||
#define TWA_9000_ARCH_ID 0x5 /* 9000 series controllers */
|
||||
#define TWA_CTLR_FW_SAME_OR_NEWER 0x00000001
|
||||
#define TWA_CTLR_FW_COMPATIBLE 0x00000002
|
||||
#define TWA_BUNDLED_FW_SAFE_TO_FLASH 0x00000004
|
||||
#define TWA_CTLR_FW_RECOMMENDS_FLASH 0x00000008
|
||||
#define NUM_FW_IMAGE_CHUNKS 5
|
||||
#define TWA_MAX_IO_SIZE 0x20000 /* 128K */
|
||||
/* #define TWA_MAX_SG_ELEMENTS defined above */
|
||||
#define TWA_MAX_ATA_SG_ELEMENTS 60
|
||||
#define TWA_Q_LENGTH TWA_INIT_MESSAGE_CREDITS
|
||||
#define TWA_MAX_RESET_TRIES 3
|
||||
#define TWA_SECTOR_SIZE 0x200 /* generic I/O bufffer */
|
||||
#define TWA_SENSE_DATA_LENGTH 18
|
||||
|
||||
#define TWA_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x010a
|
||||
#define TWA_ERROR_UNIT_OFFLINE 0x0128
|
||||
#define TWA_ERROR_MORE_DATA 0x0231
|
||||
|
||||
/* Scatter/Gather list entry. */
|
||||
struct twa_sg {
|
||||
#if defined(_KERNEL)
|
||||
bus_addr_t address;
|
||||
#else
|
||||
u_int32_t xx_address_xx; /* Fail if userland tries to use this */
|
||||
#endif
|
||||
u_int32_t length;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* 7000 structures. */
|
||||
struct twa_command_init_connect {
|
||||
u_int8_t opcode:5; /* TWA_OP_INITCONNECTION */
|
||||
u_int8_t res1:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t res2;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int16_t message_credits;
|
||||
u_int32_t features;
|
||||
u_int16_t fw_srl;
|
||||
u_int16_t fw_arch_id;
|
||||
u_int16_t fw_branch;
|
||||
u_int16_t fw_build;
|
||||
u_int32_t result;
|
||||
}__attribute__ ((packed));
|
||||
|
||||
struct twa_command_download_firmware {
|
||||
u_int8_t opcode:5; /* TWA_DOWNLOAD_FIRMWARE */
|
||||
u_int8_t sgl_offset:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t unit;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int16_t param;
|
||||
struct twa_sg sgl[TWA_MAX_SG_ELEMENTS];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_command_reset_firmware {
|
||||
u_int8_t opcode:5; /* TWA_OP_RESET_FIRMWARE */
|
||||
u_int8_t res1:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t unit;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int8_t res2;
|
||||
u_int8_t param;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_command_io {
|
||||
u_int8_t opcode:5; /* TWA_OP_READ/TWA_OP_WRITE */
|
||||
u_int8_t sgl_offset:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t unit:4;
|
||||
u_int8_t host_id:4;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int16_t block_count;
|
||||
u_int32_t lba;
|
||||
struct twa_sg sgl[TWA_MAX_SG_ELEMENTS];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_command_hotswap {
|
||||
u_int8_t opcode:5; /* TWA_OP_HOTSWAP */
|
||||
u_int8_t res1:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t unit:4;
|
||||
u_int8_t host_id:4;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int8_t action;
|
||||
#define TWA_OP_HOTSWAP_REMOVE 0x00 /* remove assumed-degraded unit */
|
||||
#define TWA_OP_HOTSWAP_ADD_CBOD 0x01 /* add CBOD to empty port */
|
||||
#define TWA_OP_HOTSWAP_ADD_SPARE 0x02 /* add spare to empty port */
|
||||
u_int8_t aport;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_command_param {
|
||||
u_int8_t opcode:5; /* TWA_OP_GETPARAM, TWA_OP_SETPARAM */
|
||||
u_int8_t sgl_offset:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t unit:4;
|
||||
u_int8_t host_id:4;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int16_t param_count;
|
||||
struct twa_sg sgl[TWA_MAX_SG_ELEMENTS];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_command_rebuildunit {
|
||||
u_int8_t opcode:5; /* TWA_OP_REBUILDUNIT */
|
||||
u_int8_t res1:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t src_unit:4;
|
||||
u_int8_t host_id:4;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int8_t action:7;
|
||||
#define TWA_OP_REBUILDUNIT_NOP 0
|
||||
#define TWA_OP_REBUILDUNIT_STOP 2 /* stop all rebuilds */
|
||||
#define TWA_OP_REBUILDUNIT_START 4 /* start rebuild with lowest unit */
|
||||
#define TWA_OP_REBUILDUNIT_STARTUNIT 5 /* rebuild src_unit (not supported) */
|
||||
u_int8_t cs:1; /* request state change on src_unit */
|
||||
u_int8_t logical_subunit; /* for RAID10 rebuild of logical subunit */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_command_ata {
|
||||
u_int8_t opcode:5; /* TWA_OP_ATA_PASSTHROUGH */
|
||||
u_int8_t sgl_offset:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t unit:4;
|
||||
u_int8_t host_id:4;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
u_int16_t param;
|
||||
u_int16_t features;
|
||||
u_int16_t sector_count;
|
||||
u_int16_t sector_num;
|
||||
u_int16_t cylinder_lo;
|
||||
u_int16_t cylinder_hi;
|
||||
u_int8_t drive_head;
|
||||
u_int8_t command;
|
||||
struct twa_sg sgl[TWA_MAX_ATA_SG_ELEMENTS];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct twa_command_generic {
|
||||
u_int8_t opcode:5;
|
||||
u_int8_t sgl_offset:3;
|
||||
u_int8_t size;
|
||||
u_int8_t request_id;
|
||||
u_int8_t unit:4;
|
||||
u_int8_t host_id:4;
|
||||
u_int8_t status;
|
||||
u_int8_t flags;
|
||||
#define TWA_FLAGS_SUCCESS 0x00
|
||||
#define TWA_FLAGS_INFORMATIONAL 0x01
|
||||
#define TWA_FLAGS_WARNING 0x02
|
||||
#define TWA_FLAGS_FATAL 0x03
|
||||
#define TWA_FLAGS_PERCENTAGE (1<<8) /* bits 0-6 indicate completion percentage */
|
||||
u_int16_t count; /* block count, parameter count, message credits */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Command packet - must be TWA_ALIGNMENT aligned. */
|
||||
union twa_command_7k {
|
||||
struct twa_command_init_connect init_connect;
|
||||
struct twa_command_download_firmware download_fw;
|
||||
struct twa_command_reset_firmware reset_fw;
|
||||
struct twa_command_io io;
|
||||
struct twa_command_hotswap hotswap;
|
||||
struct twa_command_param param;
|
||||
struct twa_command_rebuildunit rebuildunit;
|
||||
struct twa_command_ata ata;
|
||||
struct twa_command_generic generic;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* 9000 structures. */
|
||||
|
||||
/* Command Packet. */
|
||||
struct twa_command_9k {
|
||||
struct {
|
||||
u_int8_t opcode:5;
|
||||
u_int8_t reserved:3;
|
||||
} command;
|
||||
u_int8_t unit;
|
||||
u_int16_t request_id;
|
||||
u_int8_t status;
|
||||
u_int8_t sgl_offset; /* offset (in bytes) to sg_list, from the end of sgl_entries */
|
||||
u_int16_t sgl_entries;
|
||||
u_int8_t cdb[16];
|
||||
struct twa_sg sg_list[TWA_MAX_SG_ELEMENTS];
|
||||
u_int8_t padding[32];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Command packet header. */
|
||||
struct twa_command_header {
|
||||
u_int8_t sense_data[TWA_SENSE_DATA_LENGTH];
|
||||
struct {
|
||||
int8_t reserved[4];
|
||||
u_int16_t error;
|
||||
u_int8_t padding;
|
||||
struct {
|
||||
u_int8_t severity:3;
|
||||
u_int8_t reserved:5;
|
||||
} substatus_block;
|
||||
} status_block;
|
||||
u_int8_t err_specific_desc[98];
|
||||
struct {
|
||||
u_int8_t size_header;
|
||||
u_int16_t reserved;
|
||||
u_int8_t size_sense;
|
||||
} header_desc;
|
||||
u_int8_t reserved[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Full command packet. */
|
||||
struct twa_command_packet {
|
||||
struct twa_command_header cmd_hdr;
|
||||
union {
|
||||
union twa_command_7k cmd_pkt_7k;
|
||||
struct twa_command_9k cmd_pkt_9k;
|
||||
} command;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Response queue entry. */
|
||||
union twa_response_queue {
|
||||
struct {
|
||||
u_int32_t undefined_1:4;
|
||||
u_int32_t response_id:8;
|
||||
u_int32_t undefined_2:20;
|
||||
} u;
|
||||
u_int32_t value;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
#define TWA_AEN_QUEUE_EMPTY 0x00
|
||||
#define TWA_AEN_SOFT_RESET 0x01
|
||||
#define TWA_AEN_SYNC_TIME_WITH_HOST 0x31
|
||||
#define TWA_AEN_SEVERITY_ERROR 0x1
|
||||
#define TWA_AEN_SEVERITY_WARNING 0x1
|
||||
#define TWA_AEN_SEVERITY_INFO 0x1
|
||||
#define TWA_AEN_SEVERITY_DEBUG 0x4
|
||||
|
||||
#define TWA_PARAM_DRIVESUMMARY 0x0002
|
||||
#define TWA_PARAM_DRIVESTATUS 3
|
||||
|
||||
#define TWA_DRIVE_DETECTED 0x80
|
||||
|
||||
#define TWA_PARAM_DRIVE_TABLE 0x0200
|
||||
#define TWA_PARAM_DRIVESIZEINDEX 2
|
||||
#define TWA_PARAM_DRIVEMODELINDEX 3
|
||||
|
||||
#define TWA_PARAM_DRIVESIZE_LENGTH 4
|
||||
#define TWA_PARAM_DRIVEMODEL_LENGTH 40
|
||||
|
||||
|
||||
#define TWA_PARAM_VERSION 0x0402
|
||||
#define TWA_PARAM_VERSION_Mon 2 /* monitor version [16] */
|
||||
#define TWA_PARAM_VERSION_FW 3 /* firmware version [16] */
|
||||
#define TWA_PARAM_VERSION_BIOS 4 /* BIOSs version [16] */
|
||||
#define TWA_PARAM_VERSION_PCBA 5 /* PCB version [8] */
|
||||
#define TWA_PARAM_VERSION_ATA 6 /* A-chip version [8] */
|
||||
#define TWA_PARAM_VERSION_PCI 7 /* P-chip version [8] */
|
||||
|
||||
#define TWA_PARAM_CONTROLLER 0x0403
|
||||
#define TWA_PARAM_CONTROLLER_PortCount 3 /* number of ports [1] */
|
||||
|
||||
#define TWA_PARAM_TIME_TABLE 0x40A
|
||||
#define TWA_PARAM_TIME_SchedulerTime 0x3
|
||||
|
||||
#define TWA_9K_PARAM_DESCRIPTOR 0x8000
|
||||
|
||||
|
||||
struct twa_param_9k {
|
||||
u_int16_t table_id;
|
||||
u_int8_t parameter_id;
|
||||
u_int8_t reserved;
|
||||
u_int16_t parameter_size_bytes;
|
||||
u_int16_t parameter_actual_size_bytes;
|
||||
u_int8_t data[1];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* !_PCI_TWAREG_H_ */
|
|
@ -0,0 +1,228 @@
|
|||
/* $wasabi: twavar.h,v 1.11 2006/04/27 17:12:39 wrstuden Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2005-2006 Wasabi Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Your Wasabi Systems License Agreement specifies the terms and
|
||||
* conditions for use and redistribution.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003-04 3ware, Inc.
|
||||
* 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: src/sys/dev/twa/twa.h,v 1.4 2004/06/16 09:47:00 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* 3ware driver for 9000 series storage controllers.
|
||||
*
|
||||
* Author: Vinod Kashyap
|
||||
*/
|
||||
#ifndef _PCI_TWAVAR_H_
|
||||
#define _PCI_TWAVAR_H_
|
||||
|
||||
#include "locators.h"
|
||||
|
||||
struct twa_callbacks {
|
||||
void (*tcb_openings)(struct device *, int);
|
||||
};
|
||||
|
||||
struct twa_drive {
|
||||
uint32_t td_id;
|
||||
uint64_t td_size;
|
||||
struct device *td_dev;
|
||||
const struct twa_callbacks *td_callbacks;
|
||||
};
|
||||
|
||||
/* Per-controller structure. */
|
||||
struct twa_softc {
|
||||
struct device twa_dv;
|
||||
bus_space_tag_t twa_bus_iot; /* bus space tag */
|
||||
bus_space_handle_t twa_bus_ioh; /* bus space handle */
|
||||
bus_dma_tag_t twa_dma_tag; /* data buffer DMA tag */
|
||||
bus_dmamap_t twa_cmd_map; /* DMA map for the array of cmd pkts */
|
||||
void *twa_ih; /* interrupt handle cookie */
|
||||
caddr_t twa_cmds;
|
||||
bus_addr_t twa_cmd_pkt_phys;/* phys addr of first of array of cmd pkts */
|
||||
|
||||
pci_chipset_tag_t pc;
|
||||
pcitag_t tag;
|
||||
/* Request queues and arrays. */
|
||||
TAILQ_HEAD(, twa_request) twa_free; /* free request packets */
|
||||
TAILQ_HEAD(, twa_request) twa_busy; /* requests busy in the controller */
|
||||
TAILQ_HEAD(, twa_request) twa_pending; /* internal requests pending */
|
||||
|
||||
struct twa_request *twa_lookup[TWA_Q_LENGTH];/* requests indexed by request_id */
|
||||
|
||||
struct twa_request *twa_req_buf;
|
||||
struct twa_command_packet *twa_cmd_pkt_buf;
|
||||
|
||||
struct twa_drive sc_units[TWA_MAX_UNITS];
|
||||
/* AEN handler fields. */
|
||||
struct tw_cl_event_packet *twa_aen_queue[TWA_Q_LENGTH];/* circular queue of AENs from firmware */
|
||||
uint16_t working_srl; /* driver & firmware negotiated srl */
|
||||
uint16_t working_branch; /* branch # of the firmware that the driver is compatible with */
|
||||
uint16_t working_build; /* build # of the firmware that the driver is compatible with */
|
||||
u_int32_t twa_operating_mode; /* base mode/current mode */
|
||||
u_int32_t twa_aen_head; /* AEN queue head */
|
||||
u_int32_t twa_aen_tail; /* AEN queue tail */
|
||||
u_int32_t twa_current_sequence_id;/* index of the last event + 1 */
|
||||
u_int32_t twa_aen_queue_overflow; /* indicates if unretrieved events were overwritten */
|
||||
u_int32_t twa_aen_queue_wrapped; /* indicates if AEN queue ever wrapped */
|
||||
/* Controller state. */
|
||||
u_int32_t twa_state;
|
||||
u_int32_t twa_sc_flags;
|
||||
#ifdef TWA_DEBUG
|
||||
struct twa_q_statistics twa_qstats[TWAQ_COUNT]; /* queue statistics */
|
||||
#endif /* TWA_DEBUG */
|
||||
|
||||
struct _twa_ioctl_lock{
|
||||
u_int32_t lock; /* lock state */
|
||||
u_int32_t timeout; /* time at which the lock
|
||||
* will become available,
|
||||
* even if not released
|
||||
*/
|
||||
} twa_ioctl_lock; /* lock for use by user
|
||||
* applications,
|
||||
* for synchronization between
|
||||
* ioctl calls
|
||||
*/
|
||||
int sc_openings;
|
||||
int sc_nunits;
|
||||
|
||||
struct twa_request *sc_twa_request;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Possible values of tr->tr_status. */
|
||||
#define TWA_CMD_SETUP 0x0 /* being assembled */
|
||||
#define TWA_CMD_BUSY 0x1 /* submitted to controller */
|
||||
#define TWA_CMD_PENDING 0x2 /* in pending queue */
|
||||
#define TWA_CMD_COMPLETE 0x3 /* completed by controller */
|
||||
|
||||
/* Possible values of tr->tr_flags. */
|
||||
#define TWA_CMD_DATA_IN (1 << 0)
|
||||
#define TWA_CMD_DATA_OUT (1 << 1)
|
||||
#define TWA_CMD_DATA_COPY_NEEDED (1 << 2)
|
||||
#define TWA_CMD_SLEEP_ON_REQUEST (1 << 3)
|
||||
#define TWA_CMD_IN_PROGRESS (1 << 4)
|
||||
#define TWA_CMD_AEN (1 << 5)
|
||||
#define TWA_CMD_AEN_BUSY (1 << 6)
|
||||
|
||||
/* Possible values of tr->tr_cmd_pkt_type. */
|
||||
#define TWA_CMD_PKT_TYPE_7K (1<<0)
|
||||
#define TWA_CMD_PKT_TYPE_9K (1<<1)
|
||||
#define TWA_CMD_PKT_TYPE_INTERNAL (1<<2)
|
||||
#define TWA_CMD_PKT_TYPE_IOCTL (1<<3)
|
||||
#define TWA_CMD_PKT_TYPE_EXTERNAL (1<<4)
|
||||
|
||||
/* Possible values of sc->twa_state. */
|
||||
#define TWA_STATE_INTR_ENABLED (1<<0) /* interrupts have been enabled */
|
||||
#define TWA_STATE_SHUTDOWN (1<<1) /* controller is shut down */
|
||||
#define TWA_STATE_OPEN (1<<2) /* control device is open */
|
||||
#define TWA_STATE_SIMQ_FROZEN (1<<3) /* simq frozen */
|
||||
#define TWA_STATE_REQUEST_WAIT (1<<4)
|
||||
|
||||
/* Possible values of sc->twa_ioctl_lock.lock. */
|
||||
#define TWA_LOCK_FREE 0x0 /* lock is free */
|
||||
#define TWA_LOCK_HELD 0x1 /* lock is held */
|
||||
|
||||
/* Driver's request packet. */
|
||||
struct twa_request {
|
||||
struct twa_command_packet *tr_command;
|
||||
/* ptr to cmd pkt submitted to controller */
|
||||
u_int32_t tr_request_id;
|
||||
/* request id for tracking with firmware */
|
||||
void *tr_data;
|
||||
/* ptr to data being passed to firmware */
|
||||
size_t tr_length;
|
||||
/* length of buffer being passed to firmware */
|
||||
void *tr_real_data;
|
||||
/* ptr to, and length of data passed */
|
||||
size_t tr_real_length;
|
||||
/* to us from above, in case a buffer copy
|
||||
* was done due to non-compliance to
|
||||
* alignment requirements
|
||||
*/
|
||||
TAILQ_ENTRY(twa_request) tr_link;
|
||||
/* to link this request in a list */
|
||||
struct twa_softc *tr_sc;
|
||||
/* controller that owns us */
|
||||
u_int32_t tr_status;
|
||||
/* command status */
|
||||
u_int32_t tr_flags;
|
||||
/* request flags */
|
||||
u_int32_t tr_error;
|
||||
/* error encountered before request submission */
|
||||
u_int32_t tr_cmd_pkt_type;
|
||||
/* request specific data to use during callback */
|
||||
void (*tr_callback)(struct twa_request *tr);
|
||||
/* callback handler */
|
||||
bus_addr_t tr_cmd_phys;
|
||||
/* physical address of command in controller space */
|
||||
bus_dmamap_t tr_dma_map;
|
||||
/* DMA map for data */
|
||||
struct buf *bp;
|
||||
|
||||
struct ld_twa_softc *tr_ld_sc;
|
||||
};
|
||||
|
||||
static __inline__ size_t twa_get_maxsegs(void) {
|
||||
size_t max_segs = ((MAXPHYS + PAGE_SIZE - 1) / PAGE_SIZE) + 1;
|
||||
#ifdef TWA_SG_SIZE
|
||||
if (TWA_MAX_SG_ELEMENTS < max_segs)
|
||||
max_segs = TWA_MAX_SG_ELEMENTS;
|
||||
#endif
|
||||
return max_segs;
|
||||
}
|
||||
|
||||
static __inline__ size_t twa_get_maxxfer(size_t maxsegs) {
|
||||
return (maxsegs - 1) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
struct twa_attach_args {
|
||||
int twaa_unit;
|
||||
};
|
||||
|
||||
#define twaacf_unit cf_loc[TWACF_UNIT]
|
||||
|
||||
struct twa_request *twa_get_request(struct twa_softc *, int);
|
||||
struct twa_request *twa_get_request_wait(struct twa_softc *, int);
|
||||
int twa_map_request(struct twa_request *);
|
||||
void twa_register_callbacks(struct twa_softc *sc, int unit,
|
||||
const struct twa_callbacks *);
|
||||
void twa_request_wait_handler(struct twa_request *);
|
||||
void twa_release_request(struct twa_request *);
|
||||
|
||||
/* Error/AEN message structure. */
|
||||
struct twa_message {
|
||||
u_int32_t code;
|
||||
const char *message;
|
||||
};
|
||||
|
||||
#endif /* !_PCI_TWAVAR_H_ */
|
Loading…
Reference in New Issue