amrvar.h revision 58883
1/*- 2 * Copyright (c) 1999 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/dev/amr/amrvar.h 58883 2000-04-01 00:35:15Z msmith $ 27 */ 28 29/* 30 * We could actually use all 17 segments, but using only 16 means that 31 * each scatter/gather map is 128 bytes in size, and thus we don't have to worry about 32 * maps crossing page boundaries. 33 */ 34#define AMR_NSEG 16 35 36#define AMR_CFG_BASE 0x10 37#define AMR_CFG_SIG 0xa0 38#define AMR_SIGNATURE 0x3344 39 40#define AMR_MAXCMD 255 /* ident = 0 not allowed */ 41#define AMR_LIMITCMD 120 /* maximum count of outstanding commands */ 42#define AMR_MAXLD 40 43 44#define AMR_BLKSIZE 512 45 46struct amr_softc; 47 48/* 49 * Per-logical-drive datastructure 50 */ 51struct amr_logdrive 52{ 53 u_int32_t al_size; 54 int al_state; 55 int al_properties; 56 57 /* synthetic geometry */ 58 int al_cylinders; 59 int al_heads; 60 int al_sectors; 61 62 /* driver */ 63 device_t al_disk; 64}; 65 66 67/* 68 * Per-command control structure. 69 */ 70struct amr_command 71{ 72 TAILQ_ENTRY(amr_command) ac_link; 73 74 struct amr_softc *ac_sc; 75 u_int8_t ac_slot; 76 int ac_status; 77#define AMR_STATUS_BUSY 0xffff 78#define AMR_STATUS_WEDGED 0xdead 79#define AMR_STATUS_LATE 0xdeed 80 struct amr_mailbox ac_mailbox; 81 u_int32_t ac_sgphys; 82 int ac_nsgent; 83 int ac_flags; 84#define AMR_CMD_DATAIN (1<<0) 85#define AMR_CMD_DATAOUT (1<<1) 86#define AMR_CMD_PRIORITY (1<<2) 87 time_t ac_stamp; 88 89 void *ac_data; 90 size_t ac_length; 91 bus_dmamap_t ac_dmamap; 92 u_int32_t ac_dataphys; 93 94 void (* ac_complete)(struct amr_command *ac); 95 void *ac_private; 96}; 97 98struct amr_softc 99{ 100 /* bus attachments */ 101 device_t amr_dev; 102 struct resource *amr_reg; /* control registers */ 103 bus_space_handle_t amr_bhandle; 104 bus_space_tag_t amr_btag; 105 bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */ 106 bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */ 107 struct resource *amr_irq; /* interrupt */ 108 void *amr_intr; 109 110 /* mailbox */ 111 volatile struct amr_mailbox *amr_mailbox; 112 volatile struct amr_mailbox64 *amr_mailbox64; 113 u_int32_t amr_mailboxphys; 114 bus_dma_tag_t amr_mailbox_dmat; 115 bus_dmamap_t amr_mailbox_dmamap; 116 117 /* scatter/gather lists and their controller-visible mappings */ 118 struct amr_sgentry *amr_sgtable; /* s/g lists */ 119 u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */ 120 bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */ 121 bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */ 122 123 /* controller limits and features */ 124 int amr_maxio; /* maximum number of I/O transactions */ 125 int amr_maxdrives; /* max number of logical drives */ 126 127 /* connected logical drives */ 128 struct amr_logdrive amr_drive[AMR_MAXLD]; 129 130 /* controller status */ 131 int amr_state; 132#define AMR_STATE_OPEN (1<<0) 133#define AMR_STATE_SUSPEND (1<<1) 134#define AMR_STATE_INTEN (1<<2) 135#define AMR_STATE_SHUTDOWN (1<<3) 136 struct callout_handle amr_timeout; /* periodic status check */ 137 138 /* per-controller queues */ 139 struct buf_queue_head amr_bufq; /* pending I/O */ 140 int amr_waitbufs; 141 struct amr_command *amr_busycmd[AMR_MAXCMD]; 142 int amr_busycmdcount; 143 TAILQ_HEAD(,amr_command) amr_work; 144 int amr_workcount; 145 TAILQ_HEAD(,amr_command) amr_freecmds; 146 147 int amr_locks; /* reentrancy avoidance */ 148 149 /* controller type-specific support */ 150 int amr_type; 151#define AMR_TYPE_STD 0 152#define AMR_TYPE_QUARTZ 1 153 void (* amr_submit_command)(struct amr_softc *sc); 154 int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); 155 void (* amr_attach_mailbox)(struct amr_softc *sc); 156}; 157 158/* 159 * Simple (stupid) locks. 160 * 161 * Note that these are designed to avoid reentrancy, not concurrency, and will 162 * need to be replaced with something better. 163 */ 164#define AMR_LOCK_COMPLETING (1<<0) 165#define AMR_LOCK_STARTING (1<<1) 166 167static __inline int 168amr_lock_tas(struct amr_softc *sc, int lock) 169{ 170 if ((sc)->amr_locks & (lock)) 171 return(1); 172 atomic_set_int(&sc->amr_locks, lock); 173 return(0); 174} 175 176static __inline void 177amr_lock_clr(struct amr_softc *sc, int lock) 178{ 179 atomic_clear_int(&sc->amr_locks, lock); 180} 181 182/* 183 * I/O primitives 184 */ 185/* Quartz */ 186#define AMR_QPUT_IDB(sc, val) bus_space_write_4(sc->amr_btag, sc->amr_bhandle, AMR_QIDB, val) 187#define AMR_QGET_IDB(sc) bus_space_read_4 (sc->amr_btag, sc->amr_bhandle, AMR_QIDB) 188#define AMR_QPUT_ODB(sc, val) bus_space_write_4(sc->amr_btag, sc->amr_bhandle, AMR_QODB, val) 189#define AMR_QGET_ODB(sc) bus_space_read_4 (sc->amr_btag, sc->amr_bhandle, AMR_QODB) 190 191/* Standard */ 192#define AMR_SPUT_ISTAT(sc, val) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SINTR, val) 193#define AMR_SGET_ISTAT(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SINTR) 194#define AMR_SACK_INTERRUPT(sc) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SCMD, AMR_SCMD_ACKINTR) 195#define AMR_SPOST_COMMAND(sc) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SCMD, AMR_SCMD_POST) 196#define AMR_SGET_MBSTAT(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SMBOX_BUSY) 197#define AMR_SENABLE_INTR(sc) \ 198 bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE, \ 199 bus_space_read_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE) | AMR_STOGL_IENABLE) 200#define AMR_SDISABLE_INTR(sc) \ 201 bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE, \ 202 bus_space_read_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE) & ~AMR_STOGL_IENABLE) 203#define AMR_SBYTE_SET(sc, reg, val) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, reg, val) 204 205/* 206 * Interface between bus connections and driver core. 207 */ 208extern void amr_free(struct amr_softc *sc); 209extern int amr_attach(struct amr_softc *sc); 210extern void amr_startup(struct amr_softc *sc); 211extern void amr_intr(void *data); 212extern int amr_detach(device_t dev); 213extern int amr_shutdown(device_t dev); 214extern int amr_suspend(device_t dev); 215extern int amr_resume(device_t dev); 216extern d_open_t amr_open; 217extern d_close_t amr_close; 218extern d_ioctl_t amr_ioctl; 219 220extern devclass_t amr_devclass; 221 222/* 223 * MegaRAID logical disk driver 224 */ 225struct amrd_softc 226{ 227 device_t amrd_dev; 228 dev_t amrd_dev_t; 229 struct amr_softc *amrd_controller; 230 struct amr_logdrive *amrd_drive; 231 struct disk amrd_disk; 232 struct devstat amrd_stats; 233 struct disklabel amrd_label; 234 int amrd_unit; 235 int amrd_flags; 236#define AMRD_OPEN (1<<0) /* drive is open (can't shut down) */ 237}; 238 239/* 240 * Interface between driver core and disk driver (should be using a bus?) 241 */ 242extern int amr_submit_buf(struct amr_softc *sc, struct buf *bp); 243extern int amr_submit_ioctl(struct amr_softc *sc, struct amr_logdrive *drive, u_long cmd, 244 caddr_t addr, int32_t flag, struct proc *p); 245extern void amrd_intr(void *data); 246 247extern void amr_report(void); 248