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