amrvar.h revision 60833
1214571Sdim/*- 2214571Sdim * Copyright (c) 1999 Michael Smith 3214571Sdim * All rights reserved. 4214571Sdim * 5214571Sdim * Redistribution and use in source and binary forms, with or without 6214571Sdim * modification, are permitted provided that the following conditions 7214571Sdim * are met: 8214571Sdim * 1. Redistributions of source code must retain the above copyright 9214571Sdim * notice, this list of conditions and the following disclaimer. 10214571Sdim * 2. Redistributions in binary form must reproduce the above copyright 11214571Sdim * notice, this list of conditions and the following disclaimer in the 12214571Sdim * documentation and/or other materials provided with the distribution. 13214571Sdim * 14214571Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15214571Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16214571Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17214571Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18214571Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19214571Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20214571Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21214571Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22214571Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23214571Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24214571Sdim * SUCH DAMAGE. 25214571Sdim * 26214571Sdim * $FreeBSD: head/sys/dev/amr/amrvar.h 60833 2000-05-23 20:41:01Z jake $ 27214571Sdim */ 28214571Sdim 29214571Sdim/* 30214571Sdim * We could actually use all 17 segments, but using only 16 means that 31214571Sdim * each scatter/gather map is 128 bytes in size, and thus we don't have to worry about 32214571Sdim * maps crossing page boundaries. 33214571Sdim */ 34214571Sdim#define AMR_NSEG 16 35214571Sdim 36214571Sdim#define AMR_CFG_BASE 0x10 37214571Sdim#define AMR_CFG_SIG 0xa0 38214571Sdim#define AMR_SIGNATURE 0x3344 39214571Sdim 40214571Sdim#define AMR_MAXCMD 255 /* ident = 0 not allowed */ 41214571Sdim#define AMR_LIMITCMD 120 /* maximum count of outstanding commands */ 42214571Sdim#define AMR_MAXLD 40 43214571Sdim 44214571Sdim#define AMR_BLKSIZE 512 45214571Sdim 46214571Sdimstruct amr_softc; 47214571Sdim 48214571Sdim/* 49214571Sdim * Per-logical-drive datastructure 50214571Sdim */ 51214571Sdimstruct amr_logdrive 52214571Sdim{ 53214571Sdim u_int32_t al_size; 54214571Sdim int al_state; 55214571Sdim int al_properties; 56214571Sdim 57214571Sdim /* synthetic geometry */ 58214571Sdim int al_cylinders; 59214571Sdim int al_heads; 60214571Sdim int al_sectors; 61214571Sdim 62214571Sdim /* driver */ 63214571Sdim device_t al_disk; 64214571Sdim}; 65214571Sdim 66214571Sdim 67214571Sdim/* 68214571Sdim * Per-command control structure. 69214571Sdim */ 70214571Sdimstruct amr_command 71214571Sdim{ 72214571Sdim TAILQ_ENTRY(struct amr_command) ac_link; 73214571Sdim 74214571Sdim struct amr_softc *ac_sc; 75214571Sdim u_int8_t ac_slot; 76214571Sdim int ac_status; 77214571Sdim#define AMR_STATUS_BUSY 0xffff 78214571Sdim#define AMR_STATUS_WEDGED 0xdead 79214571Sdim#define AMR_STATUS_LATE 0xdeed 80214571Sdim struct amr_mailbox ac_mailbox; 81214571Sdim u_int32_t ac_sgphys; 82214571Sdim int ac_nsgent; 83214571Sdim int ac_flags; 84214571Sdim#define AMR_CMD_DATAIN (1<<0) 85214571Sdim#define AMR_CMD_DATAOUT (1<<1) 86214571Sdim#define AMR_CMD_PRIORITY (1<<2) 87214571Sdim time_t ac_stamp; 88214571Sdim 89214571Sdim void *ac_data; 90214571Sdim size_t ac_length; 91214571Sdim bus_dmamap_t ac_dmamap; 92214571Sdim u_int32_t ac_dataphys; 93214571Sdim 94214571Sdim void (* ac_complete)(struct amr_command *ac); 95214571Sdim void *ac_private; 96214571Sdim}; 97214571Sdim 98214571Sdimstruct amr_softc 99214571Sdim{ 100214571Sdim /* bus attachments */ 101214571Sdim device_t amr_dev; 102214571Sdim struct resource *amr_reg; /* control registers */ 103214571Sdim bus_space_handle_t amr_bhandle; 104214571Sdim bus_space_tag_t amr_btag; 105214571Sdim bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */ 106214571Sdim bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */ 107214571Sdim struct resource *amr_irq; /* interrupt */ 108214571Sdim void *amr_intr; 109214571Sdim 110214571Sdim /* mailbox */ 111214571Sdim volatile struct amr_mailbox *amr_mailbox; 112214571Sdim volatile struct amr_mailbox64 *amr_mailbox64; 113214571Sdim u_int32_t amr_mailboxphys; 114214571Sdim bus_dma_tag_t amr_mailbox_dmat; 115214571Sdim bus_dmamap_t amr_mailbox_dmamap; 116214571Sdim 117214571Sdim /* scatter/gather lists and their controller-visible mappings */ 118214571Sdim struct amr_sgentry *amr_sgtable; /* s/g lists */ 119214571Sdim u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */ 120214571Sdim bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */ 121214571Sdim bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */ 122214571Sdim 123214571Sdim /* controller limits and features */ 124214571Sdim int amr_maxio; /* maximum number of I/O transactions */ 125214571Sdim int amr_maxdrives; /* max number of logical drives */ 126214571Sdim 127214571Sdim /* connected logical drives */ 128214571Sdim struct amr_logdrive amr_drive[AMR_MAXLD]; 129214571Sdim 130214571Sdim /* controller status */ 131214571Sdim int amr_state; 132214571Sdim#define AMR_STATE_OPEN (1<<0) 133214571Sdim#define AMR_STATE_SUSPEND (1<<1) 134214571Sdim#define AMR_STATE_INTEN (1<<2) 135214571Sdim#define AMR_STATE_SHUTDOWN (1<<3) 136214571Sdim struct callout_handle amr_timeout; /* periodic status check */ 137214571Sdim 138214571Sdim /* per-controller queues */ 139214571Sdim struct bio_queue_head amr_bioq; /* pending I/O */ 140214571Sdim int amr_waitbufs; 141214571Sdim struct amr_command *amr_busycmd[AMR_MAXCMD]; 142214571Sdim int amr_busycmdcount; 143214571Sdim TAILQ_HEAD(, struct amr_command) amr_work; 144214571Sdim int amr_workcount; 145214571Sdim TAILQ_HEAD(, struct amr_command) amr_freecmds; 146214571Sdim 147214571Sdim int amr_locks; /* reentrancy avoidance */ 148214571Sdim 149214571Sdim /* controller type-specific support */ 150214571Sdim int amr_type; 151214571Sdim#define AMR_TYPE_STD 0 152214571Sdim#define AMR_TYPE_QUARTZ 1 153214571Sdim void (* amr_submit_command)(struct amr_softc *sc); 154214571Sdim int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); 155214571Sdim void (* amr_attach_mailbox)(struct amr_softc *sc); 156214571Sdim}; 157214571Sdim 158214571Sdim/* 159214571Sdim * Simple (stupid) locks. 160214571Sdim * 161214571Sdim * Note that these are designed to avoid reentrancy, not concurrency, and will 162214571Sdim * need to be replaced with something better. 163214571Sdim */ 164214571Sdim#define AMR_LOCK_COMPLETING (1<<0) 165214571Sdim#define AMR_LOCK_STARTING (1<<1) 166214571Sdim 167214571Sdimstatic __inline int 168214571Sdimamr_lock_tas(struct amr_softc *sc, int lock) 169214571Sdim{ 170214571Sdim if ((sc)->amr_locks & (lock)) 171214571Sdim return(1); 172214571Sdim atomic_set_int(&sc->amr_locks, lock); 173214571Sdim return(0); 174214571Sdim} 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 bio *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