1114902Sscottl/*-
2114902Sscottl * Copyright (c) 2002 Adaptec Inc.
3114902Sscottl * All rights reserved.
4114902Sscottl *
5114902Sscottl * Written by: David Jeffery
6114902Sscottl *
7114902Sscottl * Redistribution and use in source and binary forms, with or without
8114902Sscottl * modification, are permitted provided that the following conditions
9114902Sscottl * are met:
10114902Sscottl * 1. Redistributions of source code must retain the above copyright
11114902Sscottl *    notice, this list of conditions and the following disclaimer.
12114902Sscottl * 2. Redistributions in binary form must reproduce the above copyright
13114902Sscottl *    notice, this list of conditions and the following disclaimer in the
14114902Sscottl *    documentation and/or other materials provided with the distribution.
15114902Sscottl *
16114902Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17114902Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18114902Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19114902Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20114902Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21114902Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22114902Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23114902Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24114902Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25114902Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26114902Sscottl * SUCH DAMAGE.
27114902Sscottl *
28114902Sscottl * $FreeBSD$
29114902Sscottl */
30152919Sscottl#ifndef _IPS_H
31152919Sscottl#define _IPS_H
32114902Sscottl
33152919Sscottl#ifdef _KERNEL
34114902Sscottl
35114902Sscottl#include <sys/param.h>
36114902Sscottl#include <sys/systm.h>
37114902Sscottl#include <sys/kernel.h>
38129879Sphk#include <sys/module.h>
39114902Sscottl#include <sys/bus.h>
40114902Sscottl#include <sys/conf.h>
41114902Sscottl#include <sys/types.h>
42114902Sscottl#include <sys/queue.h>
43114902Sscottl#include <sys/bio.h>
44114902Sscottl#include <sys/malloc.h>
45114902Sscottl#include <sys/mutex.h>
46126364Sscottl#include <sys/sema.h>
47122999Smbr#include <sys/time.h>
48114902Sscottl
49114902Sscottl#include <machine/bus.h>
50114902Sscottl#include <sys/rman.h>
51114902Sscottl#include <machine/resource.h>
52114902Sscottl
53129859SscottlMALLOC_DECLARE(M_IPSBUF);
54129859Sscottl
55114902Sscottl/*
56114902Sscottl *  IPS MACROS
57114902Sscottl */
58114902Sscottl
59114902Sscottl#define ips_read_1(sc,offset)		bus_space_read_1(sc->bustag, sc->bushandle, offset)
60114902Sscottl#define ips_read_2(sc,offset) 		bus_space_read_2(sc->bustag, sc->bushandle, offset)
61114902Sscottl#define ips_read_4(sc,offset)		bus_space_read_4(sc->bustag, sc->bushandle, offset)
62114902Sscottl
63114902Sscottl#define ips_write_1(sc,offset,value)	bus_space_write_1(sc->bustag, sc->bushandle, offset, value)
64114902Sscottl#define ips_write_2(sc,offset,value) 	bus_space_write_2(sc->bustag, sc->bushandle, offset, value)
65114902Sscottl#define ips_write_4(sc,offset,value)	bus_space_write_4(sc->bustag, sc->bushandle, offset, value)
66114902Sscottl
67114902Sscottl/* this is ugly.  It zeros the end elements in an ips_command_t struct starting with the status element */
68114902Sscottl#define clear_ips_command(command)	bzero(&((command)->status), (unsigned long)(&(command)[1])-(unsigned long)&((command)->status))
69114902Sscottl
70114902Sscottl#define ips_read_request(iobuf)		((iobuf)->bio_cmd == BIO_READ)
71114902Sscottl
72150535Sscottl#define COMMAND_ERROR(command)		(((command)->status.fields.basic_status & IPS_GSC_STATUS_MASK) >= IPS_MIN_ERROR)
73114902Sscottl
74150535Sscottl#define ips_set_error(command, error)	do {				\
75150535Sscottl	(command)->status.fields.basic_status = IPS_DRV_ERROR;		\
76150535Sscottl	(command)->status.fields.reserved = ((error) & 0x0f);		\
77161425Simp} while (0)
78150535Sscottl
79114902Sscottl#ifndef IPS_DEBUG
80114902Sscottl#define DEVICE_PRINTF(x...)
81114902Sscottl#define PRINTF(x...)
82114902Sscottl#else
83114902Sscottl#define DEVICE_PRINTF(level,x...)	if(IPS_DEBUG >= level)device_printf(x)
84114902Sscottl#define PRINTF(level,x...)		if(IPS_DEBUG >= level)printf(x)
85114902Sscottl#endif
86150535Sscottl
87114902Sscottlstruct ips_softc;
88114902Sscottl
89114902Sscottltypedef struct {
90114902Sscottl	u_int32_t 	status[IPS_MAX_CMD_NUM];
91114902Sscottl	u_int32_t 	base_phys_addr;
92114902Sscottl	int 		nextstatus;
93114902Sscottl	bus_dma_tag_t	dmatag;
94114902Sscottl	bus_dmamap_t	dmamap;
95114902Sscottl} ips_copper_queue_t;
96114902Sscottl
97114902Sscottl/* used to keep track of current commands to the card */
98114902Sscottltypedef struct ips_command{
99114902Sscottl	u_int8_t		command_number;
100114902Sscottl	u_int8_t 		id;
101114902Sscottl	u_int8_t		timeout;
102114902Sscottl	struct ips_softc *	sc;
103140923Sscottl	bus_dma_tag_t		data_dmatag;
104140923Sscottl	bus_dmamap_t		data_dmamap;
105114902Sscottl	bus_dmamap_t		command_dmamap;
106114902Sscottl	void *			command_buffer;
107114902Sscottl	u_int32_t		command_phys_addr;/*WARNING! must be changed if 64bit addressing ever used*/
108114902Sscottl	ips_cmd_status_t	status;
109114902Sscottl	SLIST_ENTRY(ips_command)	next;
110114902Sscottl	void *			data_buffer;
111140923Sscottl	void *			arg;
112114902Sscottl	void			(* callback)(struct ips_command *command);
113114902Sscottl}ips_command_t;
114114902Sscottl
115114902Sscottltypedef struct ips_softc{
116114902Sscottl        struct resource *       iores;
117114902Sscottl        struct resource *       irqres;
118119997Sps        struct intr_config_hook ips_ich;
119116852Sscottl        int                     configured;
120116852Sscottl        int                     state;
121114902Sscottl        int                     iotype;
122114902Sscottl        int                     rid;
123114902Sscottl        int                     irqrid;
124114902Sscottl        void *                  irqcookie;
125114902Sscottl        bus_space_tag_t	        bustag;
126114902Sscottl	bus_space_handle_t      bushandle;
127114902Sscottl	bus_dma_tag_t	        adapter_dmatag;
128114902Sscottl	bus_dma_tag_t		command_dmatag;
129114902Sscottl	bus_dma_tag_t		sg_dmatag;
130114902Sscottl        device_t                dev;
131130585Sphk        struct cdev *device_file;
132114902Sscottl	struct callout_handle	timer;
133122999Smbr	u_int16_t		adapter_type;
134114902Sscottl	ips_adapter_info_t	adapter_info;
135114902Sscottl	device_t		diskdev[IPS_MAX_NUM_DRIVES];
136114902Sscottl	ips_drive_t		drives[IPS_MAX_NUM_DRIVES];
137114902Sscottl	u_int8_t		drivecount;
138122999Smbr	u_int16_t		ffdc_resetcount;
139122999Smbr	struct timeval		ffdc_resettime;
140114902Sscottl	u_int8_t		next_drive;
141114902Sscottl	u_int8_t		max_cmds;
142114902Sscottl	volatile u_int8_t	used_commands;
143140923Sscottl	ips_command_t		*commandarray;
144140923Sscottl	ips_command_t		*staticcmd;
145114902Sscottl	SLIST_HEAD(command_list, ips_command) free_cmd_list;
146114902Sscottl	int			(* ips_adapter_reinit)(struct ips_softc *sc,
147114902Sscottl						       int force);
148114902Sscottl        void                    (* ips_adapter_intr)(void *sc);
149114902Sscottl	void			(* ips_issue_cmd)(ips_command_t *command);
150141062Sscottl	void			(* ips_poll_cmd)(ips_command_t *command);
151114902Sscottl	ips_copper_queue_t *	copper_queue;
152126364Sscottl	struct mtx		queue_mtx;
153126364Sscottl	struct bio_queue_head	queue;
154140923Sscottl	struct sema		cmd_sema;
155126364Sscottl
156114902Sscottl}ips_softc_t;
157114902Sscottl
158114902Sscottl/* function defines from ips_ioctl.c */
159114902Sscottlextern int ips_ioctl_request(ips_softc_t *sc, u_long ioctl_cmd, caddr_t addr,
160114902Sscottl				int32_t flags);
161114902Sscottl/* function defines from ips_disk.c */
162114902Sscottlextern void ipsd_finish(struct bio *iobuf);
163114902Sscottl
164114902Sscottl/* function defines from ips_commands.c */
165114902Sscottlextern int ips_flush_cache(ips_softc_t *sc);
166126364Sscottlextern void ips_start_io_request(ips_softc_t *sc);
167114902Sscottlextern int ips_get_drive_info(ips_softc_t *sc);
168114902Sscottlextern int ips_get_adapter_info(ips_softc_t *sc);
169122999Smbrextern int ips_ffdc_reset(ips_softc_t *sc);
170114902Sscottlextern int ips_update_nvram(ips_softc_t *sc);
171114902Sscottlextern int ips_clear_adapter(ips_softc_t *sc);
172114902Sscottl
173114902Sscottl/* function defines from ips.c */
174140923Sscottlextern int ips_get_free_cmd(ips_softc_t *sc, ips_command_t **command, unsigned long flags);
175114902Sscottlextern void ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command);
176114902Sscottlextern int ips_adapter_init(ips_softc_t *sc);
177114902Sscottlextern int ips_morpheus_reinit(ips_softc_t *sc, int force);
178114902Sscottlextern int ips_adapter_free(ips_softc_t *sc);
179114902Sscottlextern void ips_morpheus_intr(void *sc);
180114902Sscottlextern void ips_issue_morpheus_cmd(ips_command_t *command);
181141062Sscottlextern void ips_morpheus_poll(ips_command_t *command);
182114902Sscottlextern int ips_copperhead_reinit(ips_softc_t *sc, int force);
183114902Sscottlextern void ips_copperhead_intr(void *sc);
184114902Sscottlextern void ips_issue_copperhead_cmd(ips_command_t *command);
185141062Sscottlextern void ips_copperhead_poll(ips_command_t *command);
186114902Sscottl
187152919Sscottl#endif
188152919Sscottl#endif
189