1139749Simp/*-
259743Sgroudier *  Device driver optimized for the Symbios/LSI 53C896/53C895A/53C1010
359743Sgroudier *  PCI-SCSI controllers.
459743Sgroudier *
586266Sgroudier *  Copyright (C) 1999-2001  Gerard Roudier <groudier@free.fr>
659743Sgroudier *
759743Sgroudier *  This driver also supports the following Symbios/LSI PCI-SCSI chips:
859743Sgroudier *	53C810A, 53C825A, 53C860, 53C875, 53C876, 53C885, 53C895,
959743Sgroudier *	53C810,  53C815,  53C825 and the 53C1510D is 53C8XX mode.
1059743Sgroudier *
1159743Sgroudier *
1259743Sgroudier *  This driver for FreeBSD-CAM is derived from the Linux sym53c8xx driver.
1359743Sgroudier *  Copyright (C) 1998-1999  Gerard Roudier
1459743Sgroudier *
1559743Sgroudier *  The sym53c8xx driver is derived from the ncr53c8xx driver that had been
1659743Sgroudier *  a port of the FreeBSD ncr driver to Linux-1.2.13.
1759743Sgroudier *
1859743Sgroudier *  The original ncr driver has been written for 386bsd and FreeBSD by
1959743Sgroudier *          Wolfgang Stanglmeier        <wolf@cologne.de>
2059743Sgroudier *          Stefan Esser                <se@mi.Uni-Koeln.de>
2159743Sgroudier *  Copyright (C) 1994  Wolfgang Stanglmeier
2259743Sgroudier *
2359743Sgroudier *  The initialisation code, and part of the code that addresses
2459743Sgroudier *  FreeBSD-CAM services is based on the aic7xxx driver for FreeBSD-CAM
2559743Sgroudier *  written by Justin T. Gibbs.
2659743Sgroudier *
2759743Sgroudier *  Other major contributions:
2859743Sgroudier *
2959743Sgroudier *  NVRAM detection and reading.
3059743Sgroudier *  Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
3159743Sgroudier *
3259743Sgroudier *-----------------------------------------------------------------------------
3359743Sgroudier *
3459743Sgroudier * Redistribution and use in source and binary forms, with or without
3559743Sgroudier * modification, are permitted provided that the following conditions
3659743Sgroudier * are met:
3759743Sgroudier * 1. Redistributions of source code must retain the above copyright
3859743Sgroudier *    notice, this list of conditions and the following disclaimer.
3959743Sgroudier * 2. Redistributions in binary form must reproduce the above copyright
4059743Sgroudier *    notice, this list of conditions and the following disclaimer in the
4159743Sgroudier *    documentation and/or other materials provided with the distribution.
4259743Sgroudier * 3. The name of the author may not be used to endorse or promote products
4359743Sgroudier *    derived from this software without specific prior written permission.
4459743Sgroudier *
4559743Sgroudier * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
4659743Sgroudier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4759743Sgroudier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4859743Sgroudier * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
4959743Sgroudier * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5059743Sgroudier * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5159743Sgroudier * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5259743Sgroudier * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5359743Sgroudier * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5459743Sgroudier * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5559743Sgroudier * SUCH DAMAGE.
5659743Sgroudier */
5759743Sgroudier
5859743Sgroudier/* $FreeBSD$ */
5959743Sgroudier
6059743Sgroudier#ifndef	SYM_FW_H
6159743Sgroudier#define	SYM_FW_H
6259743Sgroudier/*
6359743Sgroudier *  Macro used to generate interfaces for script A.
6459743Sgroudier */
6559743Sgroudier#define SYM_GEN_FW_A(s)							\
6659743Sgroudier	SYM_GEN_A(s, start)		SYM_GEN_A(s, getjob_begin)	\
6759743Sgroudier	SYM_GEN_A(s, getjob_end)					\
6859743Sgroudier	SYM_GEN_A(s, select)		SYM_GEN_A(s, wf_sel_done)	\
6959743Sgroudier	SYM_GEN_A(s, send_ident)					\
7059743Sgroudier	SYM_GEN_A(s, dispatch)		SYM_GEN_A(s, init)		\
7159743Sgroudier	SYM_GEN_A(s, clrack)		SYM_GEN_A(s, complete_error)	\
7259743Sgroudier	SYM_GEN_A(s, done)		SYM_GEN_A(s, done_end)		\
7359743Sgroudier	SYM_GEN_A(s, idle)		SYM_GEN_A(s, ungetjob)		\
7459743Sgroudier	SYM_GEN_A(s, reselect)						\
7559743Sgroudier	SYM_GEN_A(s, resel_tag)		SYM_GEN_A(s, resel_dsa)		\
7659743Sgroudier	SYM_GEN_A(s, resel_no_tag)					\
7759743Sgroudier	SYM_GEN_A(s, data_in)		SYM_GEN_A(s, data_in2)		\
7859743Sgroudier	SYM_GEN_A(s, data_out)		SYM_GEN_A(s, data_out2)		\
7959743Sgroudier	SYM_GEN_A(s, pm0_data)		SYM_GEN_A(s, pm1_data)
8059743Sgroudier
8159743Sgroudier/*
8259743Sgroudier *  Macro used to generate interfaces for script B.
8359743Sgroudier */
8459743Sgroudier#define SYM_GEN_FW_B(s)							\
8559743Sgroudier	SYM_GEN_B(s, no_data)						\
8659743Sgroudier	SYM_GEN_B(s, sel_for_abort)	SYM_GEN_B(s, sel_for_abort_1)	\
8759743Sgroudier	SYM_GEN_B(s, msg_bad)		SYM_GEN_B(s, msg_weird)		\
8859743Sgroudier	SYM_GEN_B(s, wdtr_resp)		SYM_GEN_B(s, send_wdtr)		\
8959743Sgroudier	SYM_GEN_B(s, sdtr_resp)		SYM_GEN_B(s, send_sdtr)		\
9059743Sgroudier	SYM_GEN_B(s, ppr_resp)		SYM_GEN_B(s, send_ppr)		\
9159743Sgroudier	SYM_GEN_B(s, nego_bad_phase)					\
9259743Sgroudier	SYM_GEN_B(s, ident_break) 	SYM_GEN_B(s, ident_break_atn)	\
9359743Sgroudier	SYM_GEN_B(s, sdata_in)		SYM_GEN_B(s, resel_bad_lun)	\
9459743Sgroudier	SYM_GEN_B(s, bad_i_t_l)		SYM_GEN_B(s, bad_i_t_l_q)	\
9559743Sgroudier	SYM_GEN_B(s, wsr_ma_helper)					\
9659743Sgroudier	SYM_GEN_B(s, snooptest)		SYM_GEN_B(s, snoopend)
9759743Sgroudier
9859743Sgroudier/*
9959743Sgroudier *  Generates structure interface that contains
10059743Sgroudier *  offsets within script A and script B.
10159743Sgroudier */
10259743Sgroudier#define	SYM_GEN_A(s, label)	s label;
10359743Sgroudier#define	SYM_GEN_B(s, label)	s label;
10459743Sgroudierstruct sym_fwa_ofs {
10559743Sgroudier	SYM_GEN_FW_A(u_short)
10659743Sgroudier};
10759743Sgroudierstruct sym_fwb_ofs {
10859743Sgroudier	SYM_GEN_FW_B(u_short)
109118472Sdds	SYM_GEN_B(u_short, start64)
110118472Sdds	SYM_GEN_B(u_short, pm_handle)
11159743Sgroudier};
11259743Sgroudier
11359743Sgroudier/*
11459743Sgroudier *  Generates structure interface that contains
11559743Sgroudier *  bus addresses within script A and script B.
11659743Sgroudier */
11759743Sgroudierstruct sym_fwa_ba {
11859743Sgroudier	SYM_GEN_FW_A(u32)
11959743Sgroudier};
12059743Sgroudierstruct sym_fwb_ba {
12159743Sgroudier	SYM_GEN_FW_B(u32)
122118472Sdds	SYM_GEN_B(u32, start64)
123118472Sdds	SYM_GEN_B(u32, pm_handle)
12459743Sgroudier};
12559743Sgroudier#undef	SYM_GEN_A
12659743Sgroudier#undef	SYM_GEN_B
12759743Sgroudier
12859743Sgroudier/*
12959743Sgroudier *  Let cc know about the name of the controller data structure.
13059743Sgroudier *  We need this for function prototype declarations just below.
13159743Sgroudier */
13259743Sgroudierstruct sym_hcb;
13359743Sgroudier
13459743Sgroudier/*
13559743Sgroudier *  Generic structure that defines a firmware.
13659743Sgroudier */
13759743Sgroudierstruct sym_fw {
138179029Smarius	const char	*name;	/* Name we want to print out	*/
139179029Smarius	const u32	*a_base;/* Pointer to script A template	*/
14059743Sgroudier	int	a_size;		/* Size of script A		*/
141179029Smarius	const struct	sym_fwa_ofs
14259743Sgroudier		*a_ofs;		/* Useful offsets in script A	*/
143179029Smarius	const u32	*b_base;/* Pointer to script B template	*/
14459743Sgroudier	int	b_size;		/* Size of script B		*/
145179029Smarius	const struct	sym_fwb_ofs
14659743Sgroudier		*b_ofs;		/* Useful offsets in script B	*/
14759743Sgroudier	/* Setup and patch methods for this firmware */
148179029Smarius	void	(*setup)(struct sym_hcb *, const struct sym_fw *);
14959743Sgroudier	void	(*patch)(struct sym_hcb *);
15059743Sgroudier};
15159743Sgroudier
15259743Sgroudier/*
15359743Sgroudier *  Macro used to declare a firmware.
15459743Sgroudier */
15559743Sgroudier#define SYM_FW_ENTRY(fw, name)					\
15659743Sgroudier{								\
15759743Sgroudier	name,							\
158179029Smarius	(const u32 *) &fw##a_scr, sizeof(fw##a_scr), &fw##a_ofs,\
159179029Smarius	(const u32 *) &fw##b_scr, sizeof(fw##b_scr), &fw##b_ofs,\
16059743Sgroudier	fw##_setup, fw##_patch					\
16159743Sgroudier}
16259743Sgroudier
16359743Sgroudier/*
16459743Sgroudier *  Macros used from the C code to get useful
16559743Sgroudier *  SCRIPTS bus addresses.
16659743Sgroudier */
16759743Sgroudier#define SCRIPTA_BA(np, label)	(np->fwa_bas.label)
16859743Sgroudier#define SCRIPTB_BA(np, label)	(np->fwb_bas.label)
16959743Sgroudier#define SCRIPTB0_BA(np,label)	\
17059743Sgroudier	(np->scriptb0_ba + (np->fwb_bas.label - np->scriptb_ba))
17159743Sgroudier
17259743Sgroudier/*
17359743Sgroudier *  Macros used by scripts definitions.
17459743Sgroudier *
17559743Sgroudier *  HADDR_1 generates a reference to a field of the controller data.
17659743Sgroudier *  HADDR_2 generates a reference to a field of the controller data
17759743Sgroudier *          with offset.
17859743Sgroudier *  RADDR_1 generates a reference to a script processor register.
17959743Sgroudier *  RADDR_2 generates a reference to a script processor register
18059743Sgroudier *          with offset.
18159743Sgroudier *  PADDR_A generates a reference to another part of script A.
18259743Sgroudier *  PADDR_B generates a reference to another part of script B.
18359743Sgroudier *
18459743Sgroudier *  SYM_GEN_PADDR_A and SYM_GEN_PADDR_B are used to define respectively
18559743Sgroudier *  the PADDR_A and PADDR_B macros for each firmware by setting argument
18659743Sgroudier *  `s' to the name of the corresponding structure.
18759743Sgroudier *
18859743Sgroudier *  SCR_DATA_ZERO is used to allocate a DWORD of data in scripts areas.
18959743Sgroudier */
19059743Sgroudier
19159743Sgroudier#define	RELOC_SOFTC	0x40000000
19259743Sgroudier#define	RELOC_LABEL_A	0x50000000
19359743Sgroudier#define	RELOC_REGISTER	0x60000000
19459743Sgroudier#define	RELOC_LABEL_B	0x80000000
19559743Sgroudier#define	RELOC_MASK	0xf0000000
19659743Sgroudier
19759743Sgroudier#define	HADDR_1(label)	   (RELOC_SOFTC    | offsetof(struct sym_hcb, label))
19859743Sgroudier#define	HADDR_2(label,ofs) (RELOC_SOFTC    | \
19959743Sgroudier				(offsetof(struct sym_hcb, label)+(ofs)))
20059743Sgroudier#define	RADDR_1(label)	   (RELOC_REGISTER | REG(label))
20159743Sgroudier#define	RADDR_2(label,ofs) (RELOC_REGISTER | ((REG(label))+(ofs)))
20259743Sgroudier
20359743Sgroudier#define SYM_GEN_PADDR_A(s, label) (RELOC_LABEL_A  | offsetof(s, label))
20459743Sgroudier#define SYM_GEN_PADDR_B(s, label) (RELOC_LABEL_B  | offsetof(s, label))
20559743Sgroudier
20659743Sgroudier#define SCR_DATA_ZERO	0xf00ff00f
20759743Sgroudier
20859743Sgroudier#endif	/* SYM_FW_H */
209