1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1999,2000 Jonathan Lemon
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31/*
32 * software structures for the Compaq RAID controller
33 */
34
35#ifndef _IDAVAR_H
36#define	_IDAVAR_H
37
38#define	ida_inb(ida, port) \
39	bus_read_1((ida)->regs, port)
40#define	ida_inw(ida, port) \
41	bus_read_2((ida)->regs, port)
42#define	ida_inl(ida, port) \
43	bus_read_4((ida)->regs, port)
44
45#define	ida_outb(ida, port, val) \
46	bus_write_1((ida)->regs, port, val)
47#define	ida_outw(ida, port, val) \
48	bus_write_2((ida)->regs, port, val)
49#define	ida_outl(ida, port, val) \
50	bus_write_4((ida)->regs, port, val)
51
52struct ida_hdr {
53	u_int8_t	drive;		/* logical drive */
54	u_int8_t	priority;	/* block priority */
55	u_int16_t	size;		/* size of request, in words */
56};
57
58struct ida_req {
59	u_int16_t	next;		/* offset of next request */
60	u_int8_t	command;	/* command */
61	u_int8_t	error;		/* return error code */
62	u_int32_t	blkno;		/* block number */
63	u_int16_t	bcount;		/* block count */
64	u_int8_t	sgcount;	/* number of scatter/gather entries */
65	u_int8_t	spare;		/* reserved */
66};
67
68struct ida_sgb {
69	u_int32_t	length;		/* length of S/G segment */
70	u_int32_t	addr;		/* physical address of block */
71};
72
73#define	IDA_NSEG	32		/* maximum number of segments */
74
75/*
76 * right now, this structure totals 276 bytes.
77 */
78struct ida_hardware_qcb {
79	struct 	ida_hdr hdr;			/*   4 */
80	struct 	ida_req req;			/*  12 */
81	struct 	ida_sgb seg[IDA_NSEG];		/* 256 */
82	struct	ida_qcb *qcb;			/*   4 - qcb backpointer */
83};
84
85typedef enum {
86	QCB_FREE		= 0x0000,
87	QCB_ACTIVE		= 0x0001,	/* waiting for completion */
88	QCB_TIMEDOUT		= 0x0002,
89} qcb_state;
90
91#define	DMA_DATA_IN	0x0001
92#define	DMA_DATA_OUT	0x0002
93#define	IDA_COMMAND	0x0004
94#define	DMA_DATA_TRANSFER	(DMA_DATA_IN | DMA_DATA_OUT)
95
96#define	IDA_QCB_MAX	256
97#define	IDA_CONTROLLER	0		/* drive "number" for controller */
98
99struct ida_softc;
100
101struct ida_qcb {
102	struct		ida_hardware_qcb *hwqcb;
103	struct		ida_softc *ida;
104	qcb_state	state;
105	short		flags;
106	union {
107		STAILQ_ENTRY(ida_qcb) stqe;
108		SLIST_ENTRY(ida_qcb) sle;
109	} link;
110	bus_dmamap_t	dmamap;
111	bus_addr_t	hwqcb_busaddr;
112	struct		bio *buf;		/* bio associated with qcb */
113	int		error;
114};
115
116struct ida_access {
117	int		(*fifo_full)(struct ida_softc *);
118	void		(*submit)(struct ida_softc *, struct ida_qcb *);
119	bus_addr_t	(*done)(struct ida_softc *);
120	int		(*int_pending)(struct ida_softc *);
121	void		(*int_enable)(struct ida_softc *, int);
122};
123
124/*
125 * flags for the controller
126 */
127#define	IDA_ATTACHED	0x01		/* attached */
128#define	IDA_FIRMWARE	0x02		/* firmware must be started */
129#define	IDA_INTERRUPTS	0x04		/* interrupts enabled */
130#define	IDA_QFROZEN	0x08		/* request queue frozen */
131
132struct ida_softc {
133	device_t	dev;
134
135	struct callout	ch;
136	struct cdev *ida_dev_t;
137
138	int		regs_res_type;
139	int		regs_res_id;
140	struct 		resource *regs;
141
142	int		irq_res_type;
143	struct		resource *irq;
144	void		*ih;
145
146	struct mtx	lock;
147	struct intr_config_hook ich;
148
149	/* various DMA tags */
150	bus_dma_tag_t	parent_dmat;
151	bus_dma_tag_t	buffer_dmat;
152
153	bus_dma_tag_t	hwqcb_dmat;
154	bus_dmamap_t	hwqcb_dmamap;
155	bus_addr_t	hwqcb_busaddr;
156
157	bus_dma_tag_t	sg_dmat;
158
159	int		flags;
160
161	int		qactive;
162
163	struct		ida_hardware_qcb *hwqcbs;	/* HW QCB array */
164	struct		ida_qcb *qcbs;			/* kernel QCB array */
165	SLIST_HEAD(, ida_qcb)	free_qcbs;
166	STAILQ_HEAD(, ida_qcb) 	qcb_queue;
167	struct		bio_queue_head bio_queue;
168
169	struct		ida_access cmd;
170};
171
172/*
173 * drive flags
174 */
175#define	DRV_WRITEPROT		0x0001
176
177struct idad_softc {
178	device_t	dev;
179	struct 		ida_softc *controller;
180	struct		disk *disk;
181	int		drive;			/* per controller */
182	int		unit;			/* global */
183	int		cylinders;
184	int		heads;
185	int		sectors;
186	int		secsize;
187	int		secperunit;
188	int		flags;
189};
190
191struct ida_board {
192	u_int32_t	board;
193	char 		*desc;
194	struct		ida_access *accessor;
195	int		flags;
196};
197
198extern int ida_detach(device_t dev);
199extern struct ida_softc *ida_alloc(device_t dev, struct resource *regs,
200	int regs_type, int regs_id, bus_dma_tag_t parent_dmat);
201extern void ida_free(struct ida_softc *ida);
202extern int ida_setup(struct ida_softc *ida);
203extern int ida_command(struct ida_softc *ida, int command, void *data,
204	int datasize, int drive, u_int32_t pblkno, int flags);
205extern void ida_submit_buf(struct ida_softc *ida, struct bio *bp);
206extern void ida_intr(void *data);
207
208extern void idad_intr(struct bio *bp);
209
210#endif /* _IDAVAR_H */
211