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