amrvar.h revision 58883
151974Smsmith/*- 251974Smsmith * Copyright (c) 1999 Michael Smith 351974Smsmith * All rights reserved. 451974Smsmith * 551974Smsmith * Redistribution and use in source and binary forms, with or without 651974Smsmith * modification, are permitted provided that the following conditions 751974Smsmith * are met: 851974Smsmith * 1. Redistributions of source code must retain the above copyright 951974Smsmith * notice, this list of conditions and the following disclaimer. 1051974Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1151974Smsmith * notice, this list of conditions and the following disclaimer in the 1251974Smsmith * documentation and/or other materials provided with the distribution. 1351974Smsmith * 1451974Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1551974Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1651974Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1751974Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1851974Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1951974Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2051974Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2151974Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2251974Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2351974Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2451974Smsmith * SUCH DAMAGE. 2551974Smsmith * 2651974Smsmith * $FreeBSD: head/sys/dev/amr/amrvar.h 58883 2000-04-01 00:35:15Z msmith $ 2751974Smsmith */ 2851974Smsmith 2951974Smsmith/* 3051974Smsmith * We could actually use all 17 segments, but using only 16 means that 3151974Smsmith * each scatter/gather map is 128 bytes in size, and thus we don't have to worry about 3251974Smsmith * maps crossing page boundaries. 3351974Smsmith */ 3451974Smsmith#define AMR_NSEG 16 3551974Smsmith 3651974Smsmith#define AMR_CFG_BASE 0x10 3751974Smsmith#define AMR_CFG_SIG 0xa0 3851974Smsmith#define AMR_SIGNATURE 0x3344 3951974Smsmith 4051974Smsmith#define AMR_MAXCMD 255 /* ident = 0 not allowed */ 4158883Smsmith#define AMR_LIMITCMD 120 /* maximum count of outstanding commands */ 4251974Smsmith#define AMR_MAXLD 40 4351974Smsmith 4451974Smsmith#define AMR_BLKSIZE 512 4551974Smsmith 4651974Smsmithstruct amr_softc; 4751974Smsmith 4851974Smsmith/* 4951974Smsmith * Per-logical-drive datastructure 5051974Smsmith */ 5151974Smsmithstruct amr_logdrive 5251974Smsmith{ 5351974Smsmith u_int32_t al_size; 5451974Smsmith int al_state; 5551974Smsmith int al_properties; 5651974Smsmith 5751974Smsmith /* synthetic geometry */ 5851974Smsmith int al_cylinders; 5951974Smsmith int al_heads; 6051974Smsmith int al_sectors; 6151974Smsmith 6251974Smsmith /* driver */ 6351974Smsmith device_t al_disk; 6451974Smsmith}; 6551974Smsmith 6651974Smsmith 6751974Smsmith/* 6851974Smsmith * Per-command control structure. 6951974Smsmith */ 7051974Smsmithstruct amr_command 7151974Smsmith{ 7251974Smsmith TAILQ_ENTRY(amr_command) ac_link; 7351974Smsmith 7451974Smsmith struct amr_softc *ac_sc; 7551974Smsmith u_int8_t ac_slot; 7651974Smsmith int ac_status; 7751974Smsmith#define AMR_STATUS_BUSY 0xffff 7851974Smsmith#define AMR_STATUS_WEDGED 0xdead 7958883Smsmith#define AMR_STATUS_LATE 0xdeed 8051974Smsmith struct amr_mailbox ac_mailbox; 8151974Smsmith u_int32_t ac_sgphys; 8251974Smsmith int ac_nsgent; 8351974Smsmith int ac_flags; 8451974Smsmith#define AMR_CMD_DATAIN (1<<0) 8551974Smsmith#define AMR_CMD_DATAOUT (1<<1) 8651974Smsmith#define AMR_CMD_PRIORITY (1<<2) 8751974Smsmith time_t ac_stamp; 8851974Smsmith 8951974Smsmith void *ac_data; 9051974Smsmith size_t ac_length; 9151974Smsmith bus_dmamap_t ac_dmamap; 9251974Smsmith u_int32_t ac_dataphys; 9351974Smsmith 9451974Smsmith void (* ac_complete)(struct amr_command *ac); 9551974Smsmith void *ac_private; 9651974Smsmith}; 9751974Smsmith 9851974Smsmithstruct amr_softc 9951974Smsmith{ 10051974Smsmith /* bus attachments */ 10151974Smsmith device_t amr_dev; 10251974Smsmith struct resource *amr_reg; /* control registers */ 10351974Smsmith bus_space_handle_t amr_bhandle; 10451974Smsmith bus_space_tag_t amr_btag; 10551974Smsmith bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */ 10651974Smsmith bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */ 10751974Smsmith struct resource *amr_irq; /* interrupt */ 10851974Smsmith void *amr_intr; 10951974Smsmith 11051974Smsmith /* mailbox */ 11158496Smsmith volatile struct amr_mailbox *amr_mailbox; 11258496Smsmith volatile struct amr_mailbox64 *amr_mailbox64; 11351974Smsmith u_int32_t amr_mailboxphys; 11451974Smsmith bus_dma_tag_t amr_mailbox_dmat; 11551974Smsmith bus_dmamap_t amr_mailbox_dmamap; 11651974Smsmith 11751974Smsmith /* scatter/gather lists and their controller-visible mappings */ 11851974Smsmith struct amr_sgentry *amr_sgtable; /* s/g lists */ 11951974Smsmith u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */ 12051974Smsmith bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */ 12151974Smsmith bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */ 12251974Smsmith 12351974Smsmith /* controller limits and features */ 12451974Smsmith int amr_maxio; /* maximum number of I/O transactions */ 12551974Smsmith int amr_maxdrives; /* max number of logical drives */ 12651974Smsmith 12751974Smsmith /* connected logical drives */ 12851974Smsmith struct amr_logdrive amr_drive[AMR_MAXLD]; 12951974Smsmith 13051974Smsmith /* controller status */ 13151974Smsmith int amr_state; 13251974Smsmith#define AMR_STATE_OPEN (1<<0) 13351974Smsmith#define AMR_STATE_SUSPEND (1<<1) 13451974Smsmith#define AMR_STATE_INTEN (1<<2) 13551974Smsmith#define AMR_STATE_SHUTDOWN (1<<3) 13658883Smsmith struct callout_handle amr_timeout; /* periodic status check */ 13751974Smsmith 13851974Smsmith /* per-controller queues */ 13951974Smsmith struct buf_queue_head amr_bufq; /* pending I/O */ 14051974Smsmith int amr_waitbufs; 14151974Smsmith struct amr_command *amr_busycmd[AMR_MAXCMD]; 14251974Smsmith int amr_busycmdcount; 14352543Smsmith TAILQ_HEAD(,amr_command) amr_work; 14452543Smsmith int amr_workcount; 14551974Smsmith TAILQ_HEAD(,amr_command) amr_freecmds; 14651974Smsmith 14758883Smsmith int amr_locks; /* reentrancy avoidance */ 14858883Smsmith 14951974Smsmith /* controller type-specific support */ 15051974Smsmith int amr_type; 15151974Smsmith#define AMR_TYPE_STD 0 15251974Smsmith#define AMR_TYPE_QUARTZ 1 15351974Smsmith void (* amr_submit_command)(struct amr_softc *sc); 15451974Smsmith int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); 15551974Smsmith void (* amr_attach_mailbox)(struct amr_softc *sc); 15651974Smsmith}; 15751974Smsmith 15851974Smsmith/* 15958883Smsmith * Simple (stupid) locks. 16058883Smsmith * 16158883Smsmith * Note that these are designed to avoid reentrancy, not concurrency, and will 16258883Smsmith * need to be replaced with something better. 16358883Smsmith */ 16458883Smsmith#define AMR_LOCK_COMPLETING (1<<0) 16558883Smsmith#define AMR_LOCK_STARTING (1<<1) 16658883Smsmith 16758883Smsmithstatic __inline int 16858883Smsmithamr_lock_tas(struct amr_softc *sc, int lock) 16958883Smsmith{ 17058883Smsmith if ((sc)->amr_locks & (lock)) 17158883Smsmith return(1); 17258883Smsmith atomic_set_int(&sc->amr_locks, lock); 17358883Smsmith return(0); 17458883Smsmith} 17558883Smsmith 17658883Smsmithstatic __inline void 17758883Smsmithamr_lock_clr(struct amr_softc *sc, int lock) 17858883Smsmith{ 17958883Smsmith atomic_clear_int(&sc->amr_locks, lock); 18058883Smsmith} 18158883Smsmith 18258883Smsmith/* 18351974Smsmith * I/O primitives 18451974Smsmith */ 18551974Smsmith/* Quartz */ 18651974Smsmith#define AMR_QPUT_IDB(sc, val) bus_space_write_4(sc->amr_btag, sc->amr_bhandle, AMR_QIDB, val) 18751974Smsmith#define AMR_QGET_IDB(sc) bus_space_read_4 (sc->amr_btag, sc->amr_bhandle, AMR_QIDB) 18851974Smsmith#define AMR_QPUT_ODB(sc, val) bus_space_write_4(sc->amr_btag, sc->amr_bhandle, AMR_QODB, val) 18951974Smsmith#define AMR_QGET_ODB(sc) bus_space_read_4 (sc->amr_btag, sc->amr_bhandle, AMR_QODB) 19051974Smsmith 19151974Smsmith/* Standard */ 19251974Smsmith#define AMR_SPUT_ISTAT(sc, val) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SINTR, val) 19351974Smsmith#define AMR_SGET_ISTAT(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SINTR) 19451974Smsmith#define AMR_SACK_INTERRUPT(sc) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SCMD, AMR_SCMD_ACKINTR) 19551974Smsmith#define AMR_SPOST_COMMAND(sc) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_SCMD, AMR_SCMD_POST) 19651974Smsmith#define AMR_SGET_MBSTAT(sc) bus_space_read_1 (sc->amr_btag, sc->amr_bhandle, AMR_SMBOX_BUSY) 19751974Smsmith#define AMR_SENABLE_INTR(sc) \ 19851974Smsmith bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE, \ 19951974Smsmith bus_space_read_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE) | AMR_STOGL_IENABLE) 20051974Smsmith#define AMR_SDISABLE_INTR(sc) \ 20151974Smsmith bus_space_write_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE, \ 20251974Smsmith bus_space_read_1(sc->amr_btag, sc->amr_bhandle, AMR_STOGGLE) & ~AMR_STOGL_IENABLE) 20351974Smsmith#define AMR_SBYTE_SET(sc, reg, val) bus_space_write_1(sc->amr_btag, sc->amr_bhandle, reg, val) 20451974Smsmith 20551974Smsmith/* 20651974Smsmith * Interface between bus connections and driver core. 20751974Smsmith */ 20851974Smsmithextern void amr_free(struct amr_softc *sc); 20951974Smsmithextern int amr_attach(struct amr_softc *sc); 21051974Smsmithextern void amr_startup(struct amr_softc *sc); 21151974Smsmithextern void amr_intr(void *data); 21251974Smsmithextern int amr_detach(device_t dev); 21351974Smsmithextern int amr_shutdown(device_t dev); 21451974Smsmithextern int amr_suspend(device_t dev); 21551974Smsmithextern int amr_resume(device_t dev); 21651974Smsmithextern d_open_t amr_open; 21751974Smsmithextern d_close_t amr_close; 21851974Smsmithextern d_ioctl_t amr_ioctl; 21951974Smsmith 22051974Smsmithextern devclass_t amr_devclass; 22151974Smsmith 22251974Smsmith/* 22351974Smsmith * MegaRAID logical disk driver 22451974Smsmith */ 22551974Smsmithstruct amrd_softc 22651974Smsmith{ 22751974Smsmith device_t amrd_dev; 22858883Smsmith dev_t amrd_dev_t; 22951974Smsmith struct amr_softc *amrd_controller; 23051974Smsmith struct amr_logdrive *amrd_drive; 23151974Smsmith struct disk amrd_disk; 23251974Smsmith struct devstat amrd_stats; 23351974Smsmith struct disklabel amrd_label; 23451974Smsmith int amrd_unit; 23551974Smsmith int amrd_flags; 23651974Smsmith#define AMRD_OPEN (1<<0) /* drive is open (can't shut down) */ 23751974Smsmith}; 23851974Smsmith 23951974Smsmith/* 24051974Smsmith * Interface between driver core and disk driver (should be using a bus?) 24151974Smsmith */ 24251974Smsmithextern int amr_submit_buf(struct amr_softc *sc, struct buf *bp); 24351974Smsmithextern int amr_submit_ioctl(struct amr_softc *sc, struct amr_logdrive *drive, u_long cmd, 24451974Smsmith caddr_t addr, int32_t flag, struct proc *p); 24551974Smsmithextern void amrd_intr(void *data); 24651974Smsmith 24758883Smsmithextern void amr_report(void); 248