root/sys/dev/pci/amrreg.h
/*      $NetBSD: amrreg.h,v 1.6 2023/08/15 04:04:10 mrg Exp $   */

/*-
 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Andrew Doran.
 *
 * 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 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.
 */

/*-
 * Copyright (c) 1999,2000 Michael Smith
 * Copyright (c) 2000 BSDi
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * from FreeBSD: amrreg.h,v 1.2 2000/08/30 07:52:40 msmith Exp
 */

#ifndef _PCI_AMRREG_H_
#define _PCI_AMRREG_H_

#ifdef AMR_CRASH_ME
#define AMR_MAX_CMDS            255             /* ident = 0 not allowed */
#else
#define AMR_MAX_CMDS            120
#endif
#define AMR_MAXLD               40

#define AMR_MAX_CMDS_PU         63

#define AMR_MAX_SEGS            26
#define AMR_MAX_CHANNEL         3
#define AMR_MAX_TARGET          15
#define AMR_MAX_LUN             7

#define AMR_MAX_CDB_LEN         0x0a
#define AMR_MAX_REQ_SENSE_LEN   0x20

#define AMR_SECTOR_SIZE         512

/* Mailbox commands.*/
#define AMR_CMD_LREAD           0x01
#define AMR_CMD_LWRITE          0x02
#define AMR_CMD_PASS            0x03
#define AMR_CMD_EXT_ENQUIRY     0x04
#define AMR_CMD_ENQUIRY         0x05
#define AMR_CMD_FLUSH           0x0a
#define AMR_CMD_EXT_ENQUIRY2    0x0c
#define AMR_CMD_GET_MACHINEID   0x36
#define AMR_CMD_GET_INITIATOR   0x7d    /* returns one byte */
#define AMR_CMD_CONFIG          0xa1
#define AMR_CONFIG_PRODUCT_INFO                 0x0e
#define AMR_CONFIG_ENQ3                         0x0f
#define AMR_CONFIG_ENQ3_SOLICITED_NOTIFY        0x01
#define AMR_CONFIG_ENQ3_SOLICITED_FULL          0x02
#define AMR_CONFIG_ENQ3_UNSOLICITED             0x03

/* Command completion status. */
#define AMR_STATUS_SUCCESS      0x00
#define AMR_STATUS_ABORTED      0x02
#define AMR_STATUS_FAILED       0x80

/* Physical/logical drive states. */
#define AMR_DRV_CURSTATE(x)     ((x) & 0x0f)
#define AMR_DRV_PREVSTATE(x)    (((x) >> 4) & 0x0f)
#define AMR_DRV_OFFLINE         0x00
#define AMR_DRV_DEGRADED        0x01
#define AMR_DRV_OPTIMAL         0x02
#define AMR_DRV_ONLINE          0x03
#define AMR_DRV_FAILED          0x04
#define AMR_DRV_REBUILD         0x05
#define AMR_DRV_HOTSPARE        0x06

/* Logical drive properties. */
#define AMR_DRV_RAID_MASK       0x0f    /* RAID level 0, 1, 3, 5, etc. */
#define AMR_DRV_WRITEBACK       0x10    /* write-back enabled */
#define AMR_DRV_READHEAD        0x20    /* readhead policy enabled */
#define AMR_DRV_ADAPTIVE        0x40    /* adaptive I/O policy enabled */

/* Battery status. */
#define AMR_BATT_MODULE_MISSING         0x01
#define AMR_BATT_LOW_VOLTAGE            0x02
#define AMR_BATT_TEMP_HIGH              0x04
#define AMR_BATT_PACK_MISSING           0x08
#define AMR_BATT_CHARGE_MASK            0x30
#define AMR_BATT_CHARGE_DONE            0x00
#define AMR_BATT_CHARGE_INPROG          0x10
#define AMR_BATT_CHARGE_FAIL            0x20
#define AMR_BATT_CYCLES_EXCEEDED        0x40

/*
 * 8LD firmware interface.
 */

/* Array constraints. */
#define AMR_8LD_MAXDRIVES       8
#define AMR_8LD_MAXCHAN         5
#define AMR_8LD_MAXTARG         15
#define AMR_8LD_MAXPHYSDRIVES   (AMR_8LD_MAXCHAN * AMR_8LD_MAXTARG)

/* Adapter information. */
struct amr_adapter_info {
        u_int8_t        aa_maxio;
        u_int8_t        aa_rebuild_rate;
        u_int8_t        aa_maxtargchan;
        u_int8_t        aa_channels;
        u_int8_t        aa_firmware[4];
        u_int16_t       aa_flashage;
        u_int8_t        aa_chipsetvalue;
        u_int8_t        aa_memorysize;
        u_int8_t        aa_cacheflush;
        u_int8_t        aa_bios[4];
        u_int8_t        aa_boardtype;
        u_int8_t        aa_scsisensealert;
        u_int8_t        aa_writeconfigcount;
        u_int8_t        aa_driveinsertioncount;
        u_int8_t        aa_inserteddrive;
        u_int8_t        aa_batterystatus;
        u_int8_t        aa_res1;
} __packed;

/* Logical drive information. */
struct amr_logdrive_info {
        u_int8_t        al_numdrives;
        u_int8_t        al_res1[3];
        u_int32_t       al_size[AMR_8LD_MAXDRIVES];
        u_int8_t        al_properties[AMR_8LD_MAXDRIVES];
        u_int8_t        al_state[AMR_8LD_MAXDRIVES];
} __packed;

/* Physical drive information. */
struct amr_physdrive_info {
        /* Low nybble is current state, high nybble is previous state. */
        u_int8_t        ap_state[AMR_8LD_MAXPHYSDRIVES];
        u_int8_t        ap_predictivefailure;
} __packed;

/*
 * Enquiry response structure for AMR_CMD_ENQUIRY (e), AMR_CMD_EXT_ENQUIRY (x)
 * and AMR_CMD_EXT_ENQUIRY2 (2).
 */
struct amr_enquiry {
        struct          amr_adapter_info ae_adapter;            /* e x 2 */
        struct          amr_logdrive_info ae_ldrv;              /* e x 2 */
        struct          amr_physdrive_info ae_pdrv;             /* e x 2 */
        u_int8_t        ae_formatting[AMR_8LD_MAXDRIVES];       /*   x 2 */
        u_int8_t        res1[AMR_8LD_MAXDRIVES];                /*   x 2 */
        u_int32_t       ae_extlen;                              /*     2 */
        u_int16_t       ae_subsystem;                           /*     2 */
        u_int16_t       ae_subvendor;                           /*     2 */
        u_int32_t       ae_signature;                           /*     2 */
#define AMR_SIG_431     0xfffe0001
#define AMR_SIG_438     0xfffd0002
#define AMR_SIG_762     0xfffc0003
#define AMR_SIG_T5      0xfffb0004
#define AMR_SIG_466     0xfffa0005
#define AMR_SIG_467     0xfff90006
#define AMR_SIG_T7      0xfff80007
#define AMR_SIG_490     0xfff70008
        u_int8_t        res2[844];                              /*     2 */
} __packed;

/*
 * 40LD firmware interface.
 */

/* Array constraints. */
#define AMR_40LD_MAXDRIVES      40
#define AMR_40LD_MAXCHAN        16
#define AMR_40LD_MAXTARG        16
#define AMR_40LD_MAXPHYSDRIVES  256

/* Product information structure. */
struct amr_prodinfo {
        u_int32_t       ap_size;                /* current size in bytes (not including resvd) */
        u_int32_t       ap_configsig;           /* default is 0x00282008, indicating 0x28 maximum
                                         * logical drives, 0x20 maximum stripes and 0x08
                                         * maximum spans */
        u_int8_t        ap_firmware[16];        /* printable identifiers */
        u_int8_t        ap_bios[16];
        u_int8_t        ap_product[80];
        u_int8_t        ap_maxio;               /* maximum number of concurrent commands supported */
        u_int8_t        ap_nschan;              /* number of SCSI channels present */
        u_int8_t        ap_fcloops;             /* number of fibre loops present */
        u_int8_t        ap_memtype;             /* memory type */
        u_int32_t       ap_signature;
        u_int16_t       ap_memsize;             /* onboard memory in MB */
        u_int16_t       ap_subsystem;           /* subsystem identifier */
        u_int16_t       ap_subvendor;           /* subsystem vendor ID */
        u_int8_t        ap_numnotifyctr;        /* number of notify counters */
} __packed;

/* Notify structure. */
struct amr_notify {
        u_int32_t       an_globalcounter;       /* change counter */

        u_int8_t        an_paramcounter;        /* parameter change counter */
        u_int8_t        an_paramid;
#define AMR_PARAM_REBUILD_RATE          0x01    /* value = new rebuild rate */
#define AMR_PARAM_FLUSH_INTERVAL        0x02    /* value = new flush interval */
#define AMR_PARAM_SENSE_ALERT           0x03    /* value = last physical drive with check condition set */
#define AMR_PARAM_DRIVE_INSERTED        0x04    /* value = last physical drive inserted */
#define AMR_PARAM_BATTERY_STATUS        0x05    /* value = battery status */
        u_int16_t       an_paramval;

        u_int8_t        an_writeconfigcounter;  /* write config occurred */
        u_int8_t        res1[3];

        u_int8_t        an_ldrvopcounter;       /* logical drive operation started/completed */
        u_int8_t        an_ldrvopid;
        u_int8_t        an_ldrvopcmd;
#define AMR_LDRVOP_CHECK        0x01
#define AMR_LDRVOP_INIT         0x02
#define AMR_LDRVOP_REBUILD      0x03
        u_int8_t        an_ldrvopstatus;
#define AMR_LDRVOP_SUCCESS      0x00
#define AMR_LDRVOP_FAILED       0x01
#define AMR_LDRVOP_ABORTED      0x02
#define AMR_LDRVOP_CORRECTED    0x03
#define AMR_LDRVOP_STARTED      0x04

        u_int8_t        an_ldrvstatecounter;    /* logical drive state change occurred */
        u_int8_t        an_ldrvstateid;
        u_int8_t        an_ldrvstatenew;
        u_int8_t        an_ldrvstateold;

        u_int8_t        an_pdrvstatecounter;    /* physical drive state change occurred */
        u_int8_t        an_pdrvstateid;
        u_int8_t        an_pdrvstatenew;
        u_int8_t        an_pdrvstateold;

        u_int8_t        an_pdrvfmtcounter;
        u_int8_t        an_pdrvfmtid;
        u_int8_t        an_pdrvfmtval;
#define AMR_FORMAT_START        0x01
#define AMR_FORMAT_COMPLETE     0x02
        u_int8_t        res2;

        u_int8_t        an_targxfercounter;     /* scsi xfer rate change */
        u_int8_t        an_targxferid;
        u_int8_t        an_targxferval;
        u_int8_t        res3;

        u_int8_t        an_fcloopidcounter;     /* FC/AL loop ID changed */
        u_int8_t        an_fcloopidpdrvid;
        u_int8_t        an_fcloopid0;
        u_int8_t        an_fcloopid1;

        u_int8_t        an_fcloopstatecounter;  /* FC/AL loop status changed */
        u_int8_t        an_fcloopstate0;
        u_int8_t        an_fcloopstate1;
        u_int8_t        res4;
} __packed;

/* Enquiry3 structure. */
struct amr_enquiry3 {
        u_int32_t       ae_datasize;            /* valid data size in this structure */
        union {                         /* event notify structure */
        struct amr_notify       n;
        u_int8_t                pad[0x80];
        }               ae_notify;
        u_int8_t        ae_rebuildrate;         /* current rebuild rate in % */
        u_int8_t        ae_cacheflush;          /* flush interval in seconds */
        u_int8_t        ae_sensealert;
        u_int8_t        ae_driveinsertcount;    /* count of inserted drives */
        u_int8_t        ae_batterystatus;
        u_int8_t        ae_numldrives;
        u_int8_t        ae_reconstate[AMR_40LD_MAXDRIVES / 8];  /* reconstruction state */
        u_int16_t       ae_opstatus[AMR_40LD_MAXDRIVES / 8];    /* operation status per drive */
        u_int32_t       ae_drivesize[AMR_40LD_MAXDRIVES];       /* logical drive size */
        u_int8_t        ae_driveprop[AMR_40LD_MAXDRIVES];       /* logical drive properties */
        u_int8_t        ae_drivestate[AMR_40LD_MAXDRIVES];      /* physical drive state */
        u_int8_t        ae_pdrivestate[AMR_40LD_MAXPHYSDRIVES]; /* physical drive state */
        u_int16_t       ae_driveformat[AMR_40LD_MAXPHYSDRIVES / 16];
        u_int8_t        ae_targxfer[80];                        /* physical drive transfer rates */

        u_int8_t        res1[263];              /* pad to 1024 bytes */
} __packed;

/*
 * Mailbox and command structures.
 */

struct amr_mailbox_cmd {
        u_int8_t        mb_command;
        u_int8_t        mb_ident;
        u_int16_t       mb_blkcount;
        u_int32_t       mb_lba;
        u_int32_t       mb_physaddr;
        u_int8_t        mb_drive;
        u_int8_t        mb_nsgelem;
        u_int8_t        res1;
        u_int8_t        mb_busy;
} __packed;

struct amr_mailbox_resp {
        u_int8_t        mb_nstatus;
        u_int8_t        mb_status;
        u_int8_t        mb_completed[46];
}  __packed;

struct amr_mailbox {
        u_int32_t       mb_res1[3];
        u_int32_t       mb_segment;
        struct          amr_mailbox_cmd mb_cmd;
        struct          amr_mailbox_resp mb_resp;
        u_int8_t        mb_poll;
        u_int8_t        mb_ack;
        u_int8_t        res2[62];               /* Pad to 128+16 bytes. */
} __packed;

struct amr_mailbox_ioctl {
        u_int8_t        mb_command;
        u_int8_t        mb_ident;
        u_int8_t        mb_channel;
        u_int8_t        mb_param;
        u_int8_t        mb_pad[4];
        u_int32_t       mb_physaddr;
        u_int8_t        mb_drive;
        u_int8_t        mb_nsgelem;
        u_int8_t        res1;
        u_int8_t        mb_busy;
        u_int8_t        mb_nstatus;
        u_int8_t        mb_completed[46];
        u_int8_t        mb_poll;
        u_int8_t        mb_ack;
        u_int8_t        res4[16];
} __packed;

struct amr_sgentry {
        u_int32_t       sge_addr;
        u_int32_t       sge_count;
} __packed;

struct amr_passthrough {
        u_int8_t        ap_timeout:3;
        u_int8_t        ap_ars:1;
        u_int8_t        ap_dummy:3;
        u_int8_t        ap_islogical:1;
        u_int8_t        ap_logical_drive_no;
        u_int8_t        ap_channel;
        u_int8_t        ap_scsi_id;
        u_int8_t        ap_queue_tag;
        u_int8_t        ap_queue_action;
        u_int8_t        ap_cdb[AMR_MAX_CDB_LEN];
        u_int8_t        ap_cdb_length;
        u_int8_t        ap_request_sense_length;
        u_int8_t        ap_request_sense_area[AMR_MAX_REQ_SENSE_LEN];
        u_int8_t        ap_no_sg_elements;
        u_int8_t        ap_scsi_status;
        u_int32_t       ap_data_transfer_address;
        u_int32_t       ap_data_transfer_length;
} __packed;

/*
 * "Quartz" i960 PCI bridge interface.
 */

#define AMR_QUARTZ_SIG_REG      0xa0
#define AMR_QUARTZ_SIG0         0xcccc
#define AMR_QUARTZ_SIG1         0x3344

/* Doorbell registers. */
#define AMR_QREG_IDB            0x20
#define AMR_QREG_ODB            0x2c

#define AMR_QIDB_SUBMIT         0x00000001      /* mailbox ready for work */
#define AMR_QIDB_ACK            0x00000002      /* mailbox done */
#define AMR_QODB_READY          0x10001234      /* work ready to be processed */

/*
 * Old-style ("standard") ASIC bridge interface.
 */

/* I/O registers. */
#define AMR_SREG_CMD            0x10    /* Command/ack register (w) */
#define AMR_SREG_MBOX_BUSY      0x10    /* Mailbox status (r) */
#define AMR_SREG_TOGL           0x11    /* Interrupt enable */
#define AMR_SREG_MBOX           0x14    /* Mailbox physical address */
#define AMR_SREG_MBOX_ENABLE    0x18    /* Atomic mailbox address enable */
#define AMR_SREG_INTR           0x1a    /* Interrupt status */

/* I/O magic numbers. */
#define AMR_SCMD_POST           0x10    /* in SCMD to initiate action on mailbox */
#define AMR_SCMD_ACKINTR        0x08    /* in SCMD to ack mailbox retrieved */
#define AMR_STOGL_ENABLE        0xc0    /* in STOGL */
#define AMR_SINTR_VALID         0x40    /* in SINTR */
#define AMR_SMBOX_BUSY_FLAG     0x10    /* in SMBOX_BUSY */
#define AMR_SMBOX_ENABLE_ADDR   0x00    /* in SMBOX_ENABLE */

#endif  /* !_PCI_AMRREG_H_ */