1/*-
2 * Copyright (c) 1999,2000 Jonathan Lemon
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$
27 */
28
29/*
30 * software structures for the Compaq RAID controller
31 */
32
33#ifndef _IDAVAR_H
34#define	_IDAVAR_H
35
36#define	ida_inb(ida, port) \
37	bus_space_read_1((ida)->tag, (ida)->bsh, port)
38#define	ida_inw(ida, port) \
39	bus_space_read_2((ida)->tag, (ida)->bsh, port)
40#define	ida_inl(ida, port) \
41	bus_space_read_4((ida)->tag, (ida)->bsh, port)
42
43#define	ida_outb(ida, port, val) \
44	bus_space_write_1((ida)->tag, (ida)->bsh, port, val)
45#define	ida_outw(ida, port, val) \
46	bus_space_write_2((ida)->tag, (ida)->bsh, port, val)
47#define	ida_outl(ida, port, val) \
48	bus_space_write_4((ida)->tag, (ida)->bsh, port, val)
49
50struct ida_hdr {
51	u_int8_t	drive;		/* logical drive */
52	u_int8_t	priority;	/* block priority */
53	u_int16_t	size;		/* size of request, in words */
54};
55
56struct ida_req {
57	u_int16_t	next;		/* offset of next request */
58	u_int8_t	command;	/* command */
59	u_int8_t	error;		/* return error code */
60	u_int32_t	blkno;		/* block number */
61	u_int16_t	bcount;		/* block count */
62	u_int8_t	sgcount;	/* number of scatter/gather entries */
63	u_int8_t	spare;		/* reserved */
64};
65
66struct ida_sgb {
67	u_int32_t	length;		/* length of S/G segment */
68	u_int32_t	addr;		/* physical address of block */
69};
70
71#define	IDA_NSEG	32		/* maximum number of segments */
72
73/*
74 * right now, this structure totals 276 bytes.
75 */
76struct ida_hardware_qcb {
77	struct 	ida_hdr hdr;			/*   4 */
78	struct 	ida_req req;			/*  12 */
79	struct 	ida_sgb seg[IDA_NSEG];		/* 256 */
80	struct	ida_qcb *qcb;			/*   4 - qcb backpointer */
81};
82
83typedef enum {
84	QCB_FREE		= 0x0000,
85	QCB_ACTIVE		= 0x0001,	/* waiting for completion */
86} qcb_state;
87
88#define	DMA_DATA_IN	0x0001
89#define	DMA_DATA_OUT	0x0002
90#define	IDA_COMMAND	0x0004
91#define	DMA_DATA_TRANSFER	(DMA_DATA_IN | DMA_DATA_OUT)
92
93#define	IDA_QCB_MAX	256
94#define	IDA_CONTROLLER	0		/* drive "number" for controller */
95
96struct ida_qcb {
97	struct		ida_hardware_qcb *hwqcb;
98	qcb_state	state;
99	short		flags;
100	union {
101		STAILQ_ENTRY(ida_qcb) stqe;
102		SLIST_ENTRY(ida_qcb) sle;
103	} link;
104	bus_dmamap_t	dmamap;
105	bus_addr_t	hwqcb_busaddr;
106	struct		bio *buf;		/* bio associated with qcb */
107};
108
109struct ida_softc;
110
111struct ida_access {
112	int		(*fifo_full)(struct ida_softc *);
113	void		(*submit)(struct ida_softc *, struct ida_qcb *);
114	bus_addr_t	(*done)(struct ida_softc *);
115	int		(*int_pending)(struct ida_softc *);
116	void		(*int_enable)(struct ida_softc *, int);
117};
118
119/*
120 * flags for the controller
121 */
122#define	IDA_ATTACHED	0x01		/* attached */
123#define	IDA_FIRMWARE	0x02		/* firmware must be started */
124#define	IDA_INTERRUPTS	0x04		/* interrupts enabled */
125
126struct ida_softc {
127	device_t	dev;
128	int		unit;
129
130	struct callout	ch;
131	struct cdev *ida_dev_t;
132
133	int		regs_res_type;
134	int		regs_res_id;
135	struct 		resource *regs;
136
137	int		irq_res_type;
138	struct		resource *irq;
139	void		*ih;
140
141	bus_space_tag_t		tag;
142	bus_space_handle_t	bsh;
143
144	/* various DMA tags */
145	bus_dma_tag_t	parent_dmat;
146	bus_dma_tag_t	buffer_dmat;
147
148	bus_dma_tag_t	hwqcb_dmat;
149	bus_dmamap_t	hwqcb_dmamap;
150	bus_addr_t	hwqcb_busaddr;
151
152	bus_dma_tag_t	sg_dmat;
153
154	int		num_drives;
155	int		num_qcbs;
156	int		flags;
157
158	int		qactive;
159
160	struct		ida_hardware_qcb *hwqcbs;	/* HW QCB array */
161	struct		ida_qcb *qcbs;			/* kernel QCB array */
162	SLIST_HEAD(, ida_qcb)	free_qcbs;
163	STAILQ_HEAD(, ida_qcb) 	qcb_queue;
164	struct		bio_queue_head bio_queue;
165
166	struct		ida_access cmd;
167};
168
169/*
170 * drive flags
171 */
172#define	DRV_WRITEPROT		0x0001
173
174struct idad_softc {
175	device_t	dev;
176	struct 		ida_softc *controller;
177	struct		disk *disk;
178	int		drive;			/* per controller */
179	int		unit;			/* global */
180	int		cylinders;
181	int		heads;
182	int		sectors;
183	int		secsize;
184	int		secperunit;
185	int		flags;
186};
187
188struct ida_board {
189	u_int32_t	board;
190	char 		*desc;
191	struct		ida_access *accessor;
192	int		flags;
193};
194
195extern int ida_detach(device_t dev);
196extern struct ida_softc *ida_alloc(device_t dev, struct resource *regs,
197	int regs_type, int regs_id, bus_dma_tag_t parent_dmat);
198extern void ida_free(struct ida_softc *ida);
199extern int ida_init(struct ida_softc *ida);
200extern void ida_attach(struct ida_softc *ida);
201extern int ida_command(struct ida_softc *ida, int command, void *data,
202	int datasize, int drive, u_int32_t pblkno, int flags);
203extern void ida_submit_buf(struct ida_softc *ida, struct bio *bp);
204extern void ida_intr(void *data);
205
206extern void idad_intr(struct bio *bp);
207
208#endif /* _IDAVAR_H */
209