148156Sjlemon/*-
257828Sjlemon * Copyright (c) 1999,2000 Jonathan Lemon
348156Sjlemon * All rights reserved.
448156Sjlemon *
548156Sjlemon * Redistribution and use in source and binary forms, with or without
648156Sjlemon * modification, are permitted provided that the following conditions
748156Sjlemon * are met:
848156Sjlemon * 1. Redistributions of source code must retain the above copyright
948156Sjlemon *    notice, this list of conditions and the following disclaimer.
1048156Sjlemon * 2. Redistributions in binary form must reproduce the above copyright
1148156Sjlemon *    notice, this list of conditions and the following disclaimer in the
1248156Sjlemon *    documentation and/or other materials provided with the distribution.
1348156Sjlemon *
1448156Sjlemon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1548156Sjlemon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1648156Sjlemon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1748156Sjlemon * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1848156Sjlemon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1948156Sjlemon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2048156Sjlemon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2148156Sjlemon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2248156Sjlemon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2348156Sjlemon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2448156Sjlemon * SUCH DAMAGE.
2548156Sjlemon *
2650477Speter * $FreeBSD$
2748156Sjlemon */
2848156Sjlemon
2948156Sjlemon/*
3048156Sjlemon * software structures for the Compaq RAID controller
3148156Sjlemon */
3248156Sjlemon
3348156Sjlemon#ifndef _IDAVAR_H
34124471Smdodd#define	_IDAVAR_H
3548156Sjlemon
36124471Smdodd#define	ida_inb(ida, port) \
3757828Sjlemon	bus_space_read_1((ida)->tag, (ida)->bsh, port)
38124471Smdodd#define	ida_inw(ida, port) \
3957828Sjlemon	bus_space_read_2((ida)->tag, (ida)->bsh, port)
40124471Smdodd#define	ida_inl(ida, port) \
4157828Sjlemon	bus_space_read_4((ida)->tag, (ida)->bsh, port)
4257828Sjlemon
43124471Smdodd#define	ida_outb(ida, port, val) \
4457828Sjlemon	bus_space_write_1((ida)->tag, (ida)->bsh, port, val)
45124471Smdodd#define	ida_outw(ida, port, val) \
4657828Sjlemon	bus_space_write_2((ida)->tag, (ida)->bsh, port, val)
47124471Smdodd#define	ida_outl(ida, port, val) \
4857828Sjlemon	bus_space_write_4((ida)->tag, (ida)->bsh, port, val)
4957828Sjlemon
5048156Sjlemonstruct ida_hdr {
5148156Sjlemon	u_int8_t	drive;		/* logical drive */
5248156Sjlemon	u_int8_t	priority;	/* block priority */
5348156Sjlemon	u_int16_t	size;		/* size of request, in words */
5448156Sjlemon};
5548156Sjlemon
5648156Sjlemonstruct ida_req {
5748156Sjlemon	u_int16_t	next;		/* offset of next request */
5848156Sjlemon	u_int8_t	command;	/* command */
5948156Sjlemon	u_int8_t	error;		/* return error code */
6048156Sjlemon	u_int32_t	blkno;		/* block number */
6148156Sjlemon	u_int16_t	bcount;		/* block count */
6248156Sjlemon	u_int8_t	sgcount;	/* number of scatter/gather entries */
6348156Sjlemon	u_int8_t	spare;		/* reserved */
6448156Sjlemon};
6548156Sjlemon
6648156Sjlemonstruct ida_sgb {
6748156Sjlemon	u_int32_t	length;		/* length of S/G segment */
6848156Sjlemon	u_int32_t	addr;		/* physical address of block */
6948156Sjlemon};
7048156Sjlemon
71124471Smdodd#define	IDA_NSEG	32		/* maximum number of segments */
7248156Sjlemon
7348156Sjlemon/*
7448156Sjlemon * right now, this structure totals 276 bytes.
7548156Sjlemon */
7648156Sjlemonstruct ida_hardware_qcb {
7748156Sjlemon	struct 	ida_hdr hdr;			/*   4 */
7848156Sjlemon	struct 	ida_req req;			/*  12 */
7948156Sjlemon	struct 	ida_sgb seg[IDA_NSEG];		/* 256 */
80144991Smdodd	struct	ida_qcb *qcb;			/*   4 - qcb backpointer */
8148156Sjlemon};
8248156Sjlemon
8348156Sjlemontypedef enum {
8448156Sjlemon	QCB_FREE		= 0x0000,
8548156Sjlemon	QCB_ACTIVE		= 0x0001,	/* waiting for completion */
8648156Sjlemon} qcb_state;
8748156Sjlemon
8848156Sjlemon#define	DMA_DATA_IN	0x0001
8948156Sjlemon#define	DMA_DATA_OUT	0x0002
90124471Smdodd#define	IDA_COMMAND	0x0004
91124471Smdodd#define	DMA_DATA_TRANSFER	(DMA_DATA_IN | DMA_DATA_OUT)
9248156Sjlemon
93124471Smdodd#define	IDA_QCB_MAX	256
94124471Smdodd#define	IDA_CONTROLLER	0		/* drive "number" for controller */
9548156Sjlemon
9648156Sjlemonstruct ida_qcb {
9748156Sjlemon	struct		ida_hardware_qcb *hwqcb;
9848156Sjlemon	qcb_state	state;
9948156Sjlemon	short		flags;
10048156Sjlemon	union {
10160938Sjake		STAILQ_ENTRY(ida_qcb) stqe;
10260938Sjake		SLIST_ENTRY(ida_qcb) sle;
10348156Sjlemon	} link;
10448156Sjlemon	bus_dmamap_t	dmamap;
10557828Sjlemon	bus_addr_t	hwqcb_busaddr;
10659249Sphk	struct		bio *buf;		/* bio associated with qcb */
10748156Sjlemon};
10848156Sjlemon
10957828Sjlemonstruct ida_softc;
11057828Sjlemon
11157828Sjlemonstruct ida_access {
11257828Sjlemon	int		(*fifo_full)(struct ida_softc *);
11357828Sjlemon	void		(*submit)(struct ida_softc *, struct ida_qcb *);
11457828Sjlemon	bus_addr_t	(*done)(struct ida_softc *);
11557828Sjlemon	int		(*int_pending)(struct ida_softc *);
11657828Sjlemon	void		(*int_enable)(struct ida_softc *, int);
11757828Sjlemon};
11857828Sjlemon
11948156Sjlemon/*
120144991Smdodd * flags for the controller
12148156Sjlemon */
122124471Smdodd#define	IDA_ATTACHED	0x01		/* attached */
123124471Smdodd#define	IDA_FIRMWARE	0x02		/* firmware must be started */
124124471Smdodd#define	IDA_INTERRUPTS	0x04		/* interrupts enabled */
12548156Sjlemon
12648156Sjlemonstruct ida_softc {
12748156Sjlemon	device_t	dev;
12848156Sjlemon	int		unit;
129138853Smdodd
130138853Smdodd	struct callout	ch;
131130585Sphk	struct cdev *ida_dev_t;
13248156Sjlemon
13348156Sjlemon	int		regs_res_type;
13448156Sjlemon	int		regs_res_id;
13548156Sjlemon	struct 		resource *regs;
13648156Sjlemon
13748156Sjlemon	int		irq_res_type;
13848156Sjlemon	struct		resource *irq;
13948156Sjlemon	void		*ih;
14048156Sjlemon
14148156Sjlemon	bus_space_tag_t		tag;
14248156Sjlemon	bus_space_handle_t	bsh;
14348156Sjlemon
14448156Sjlemon	/* various DMA tags */
14548156Sjlemon	bus_dma_tag_t	parent_dmat;
14648156Sjlemon	bus_dma_tag_t	buffer_dmat;
14748156Sjlemon
14848156Sjlemon	bus_dma_tag_t	hwqcb_dmat;
14948156Sjlemon	bus_dmamap_t	hwqcb_dmamap;
15048156Sjlemon	bus_addr_t	hwqcb_busaddr;
15148156Sjlemon
15248156Sjlemon	bus_dma_tag_t	sg_dmat;
15348156Sjlemon
15448156Sjlemon	int		num_drives;
15548156Sjlemon	int		num_qcbs;
15648156Sjlemon	int		flags;
15748156Sjlemon
158138853Smdodd	int		qactive;
159138853Smdodd
16048156Sjlemon	struct		ida_hardware_qcb *hwqcbs;	/* HW QCB array */
16148156Sjlemon	struct		ida_qcb *qcbs;			/* kernel QCB array */
16260938Sjake	SLIST_HEAD(, ida_qcb)	free_qcbs;
16360938Sjake	STAILQ_HEAD(, ida_qcb) 	qcb_queue;
16459249Sphk	struct		bio_queue_head bio_queue;
16557828Sjlemon
16657828Sjlemon	struct		ida_access cmd;
16748156Sjlemon};
16848156Sjlemon
16948156Sjlemon/*
17048156Sjlemon * drive flags
17148156Sjlemon */
172124471Smdodd#define	DRV_WRITEPROT		0x0001
17348156Sjlemon
17459485Smdoddstruct idad_softc {
17548156Sjlemon	device_t	dev;
17648156Sjlemon	struct 		ida_softc *controller;
177125975Sphk	struct		disk *disk;
17863934Sjlemon	int		drive;			/* per controller */
17963934Sjlemon	int		unit;			/* global */
18048156Sjlemon	int		cylinders;
18148156Sjlemon	int		heads;
18248156Sjlemon	int		sectors;
18348156Sjlemon	int		secsize;
18448156Sjlemon	int		secperunit;
18548156Sjlemon	int		flags;
18648156Sjlemon};
18748156Sjlemon
18857828Sjlemonstruct ida_board {
18957828Sjlemon	u_int32_t	board;
19057828Sjlemon	char 		*desc;
19157828Sjlemon	struct		ida_access *accessor;
19270845Sjlemon	int		flags;
19357828Sjlemon};
19457828Sjlemon
19557828Sjlemonextern int ida_detach(device_t dev);
19648156Sjlemonextern struct ida_softc *ida_alloc(device_t dev, struct resource *regs,
19748156Sjlemon	int regs_type, int regs_id, bus_dma_tag_t parent_dmat);
19848156Sjlemonextern void ida_free(struct ida_softc *ida);
19948156Sjlemonextern int ida_init(struct ida_softc *ida);
200144991Smdoddextern void ida_attach(struct ida_softc *ida);
20148156Sjlemonextern int ida_command(struct ida_softc *ida, int command, void *data,
20273113Sjlemon	int datasize, int drive, u_int32_t pblkno, int flags);
20359249Sphkextern void ida_submit_buf(struct ida_softc *ida, struct bio *bp);
20448156Sjlemonextern void ida_intr(void *data);
20548156Sjlemon
20659485Smdoddextern void idad_intr(struct bio *bp);
20748156Sjlemon
20848156Sjlemon#endif /* _IDAVAR_H */
209