xref: /freebsd/sys/dev/aic7xxx/aic7xxx_osm.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1098ca2bdSWarner Losh /*-
2717d4247SJustin T. Gibbs  * FreeBSD platform specific driver option settings, data structures,
3717d4247SJustin T. Gibbs  * function declarations and includes.
4717d4247SJustin T. Gibbs  *
564a3876fSJustin T. Gibbs  * Copyright (c) 1994-2001 Justin T. Gibbs.
6717d4247SJustin T. Gibbs  * All rights reserved.
7717d4247SJustin T. Gibbs  *
8717d4247SJustin T. Gibbs  * Redistribution and use in source and binary forms, with or without
9717d4247SJustin T. Gibbs  * modification, are permitted provided that the following conditions
10717d4247SJustin T. Gibbs  * are met:
11717d4247SJustin T. Gibbs  * 1. Redistributions of source code must retain the above copyright
12717d4247SJustin T. Gibbs  *    notice, this list of conditions, and the following disclaimer,
13717d4247SJustin T. Gibbs  *    without modification.
14717d4247SJustin T. Gibbs  * 2. The name of the author may not be used to endorse or promote products
15717d4247SJustin T. Gibbs  *    derived from this software without specific prior written permission.
16717d4247SJustin T. Gibbs  *
17717d4247SJustin T. Gibbs  * Alternatively, this software may be distributed under the terms of the
18717d4247SJustin T. Gibbs  * GNU Public License ("GPL").
19717d4247SJustin T. Gibbs  *
20717d4247SJustin T. Gibbs  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21717d4247SJustin T. Gibbs  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22717d4247SJustin T. Gibbs  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23717d4247SJustin T. Gibbs  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24717d4247SJustin T. Gibbs  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25717d4247SJustin T. Gibbs  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26717d4247SJustin T. Gibbs  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27717d4247SJustin T. Gibbs  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28717d4247SJustin T. Gibbs  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29717d4247SJustin T. Gibbs  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30717d4247SJustin T. Gibbs  * SUCH DAMAGE.
31717d4247SJustin T. Gibbs  *
32b3b25f2cSJustin T. Gibbs  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#18 $
33717d4247SJustin T. Gibbs  */
34717d4247SJustin T. Gibbs 
35717d4247SJustin T. Gibbs #ifndef _AIC7XXX_FREEBSD_H_
36717d4247SJustin T. Gibbs #define _AIC7XXX_FREEBSD_H_
37717d4247SJustin T. Gibbs 
38*4e38d895SWarner Losh #include "opt_aic7xxx.h"	/* for config options */
39717d4247SJustin T. Gibbs 
40717d4247SJustin T. Gibbs #include <sys/param.h>
41717d4247SJustin T. Gibbs #include <sys/systm.h>
42717d4247SJustin T. Gibbs #include <sys/bus.h>		/* For device_t */
43a30d4b32SMike Barcroft #include <sys/endian.h>
4456a7c4a8SJustin T. Gibbs #include <sys/eventhandler.h>
45717d4247SJustin T. Gibbs #include <sys/kernel.h>
46717d4247SJustin T. Gibbs #include <sys/malloc.h>
47fe12f24bSPoul-Henning Kamp #include <sys/module.h>
48717d4247SJustin T. Gibbs #include <sys/queue.h>
49717d4247SJustin T. Gibbs 
50b3b25f2cSJustin T. Gibbs #define AIC_PCI_CONFIG 1
51717d4247SJustin T. Gibbs #include <machine/bus.h>
528f214efcSJustin T. Gibbs #include <machine/endian.h>
53717d4247SJustin T. Gibbs #include <machine/resource.h>
54717d4247SJustin T. Gibbs 
55717d4247SJustin T. Gibbs #include <sys/rman.h>
56717d4247SJustin T. Gibbs 
574fbd232cSWarner Losh #include <dev/pci/pcireg.h>
584fbd232cSWarner Losh #include <dev/pci/pcivar.h>
59717d4247SJustin T. Gibbs 
60717d4247SJustin T. Gibbs #include <cam/cam.h>
61717d4247SJustin T. Gibbs #include <cam/cam_ccb.h>
62717d4247SJustin T. Gibbs #include <cam/cam_debug.h>
63717d4247SJustin T. Gibbs #include <cam/cam_sim.h>
64717d4247SJustin T. Gibbs #include <cam/cam_xpt_sim.h>
65717d4247SJustin T. Gibbs 
66717d4247SJustin T. Gibbs #include <cam/scsi/scsi_all.h>
67717d4247SJustin T. Gibbs #include <cam/scsi/scsi_message.h>
68717d4247SJustin T. Gibbs 
69717d4247SJustin T. Gibbs /****************************** Platform Macros *******************************/
70717d4247SJustin T. Gibbs #define	SIM_IS_SCSIBUS_B(ahc, sim)	\
71717d4247SJustin T. Gibbs 	((sim) == ahc->platform_data->sim_b)
72717d4247SJustin T. Gibbs #define	SIM_CHANNEL(ahc, sim)	\
73717d4247SJustin T. Gibbs 	(((sim) == ahc->platform_data->sim_b) ? 'B' : 'A')
74717d4247SJustin T. Gibbs #define	SIM_SCSI_ID(ahc, sim)	\
75717d4247SJustin T. Gibbs 	(((sim) == ahc->platform_data->sim_b) ? ahc->our_id_b : ahc->our_id)
76717d4247SJustin T. Gibbs #define	SIM_PATH(ahc, sim)	\
77717d4247SJustin T. Gibbs 	(((sim) == ahc->platform_data->sim_b) ? ahc->platform_data->path_b \
78717d4247SJustin T. Gibbs 					      : ahc->platform_data->path)
79717d4247SJustin T. Gibbs #define BUILD_SCSIID(ahc, sim, target_id, our_id) \
80717d4247SJustin T. Gibbs         ((((target_id) << TID_SHIFT) & TID) | (our_id) \
81717d4247SJustin T. Gibbs         | (SIM_IS_SCSIBUS_B(ahc, sim) ? TWIN_CHNLB : 0))
82717d4247SJustin T. Gibbs 
83717d4247SJustin T. Gibbs #define SCB_GET_SIM(ahc, scb) \
84717d4247SJustin T. Gibbs 	(SCB_GET_CHANNEL(ahc, scb) == 'A' ? (ahc)->platform_data->sim \
85717d4247SJustin T. Gibbs 					  : (ahc)->platform_data->sim_b)
86717d4247SJustin T. Gibbs 
8758fb7d8eSJustin T. Gibbs #ifndef offsetof
8858fb7d8eSJustin T. Gibbs #define offsetof(type, member)  ((size_t)(&((type *)0)->member))
8958fb7d8eSJustin T. Gibbs #endif
90717d4247SJustin T. Gibbs 
91717d4247SJustin T. Gibbs /************************ Tunable Driver Parameters  **************************/
92717d4247SJustin T. Gibbs /*
93717d4247SJustin T. Gibbs  * The number of dma segments supported.  The sequencer can handle any number
94717d4247SJustin T. Gibbs  * of physically contiguous S/G entrys.  To reduce the driver's memory
95717d4247SJustin T. Gibbs  * consumption, we limit the number supported to be sufficient to handle
966bccea7cSRebecca Cran  * the largest mapping supported by the legacy kernel MAXPHYS setting of
9752c9ce25SScott Long  * 128K.  This can be increased once some testing is done.  Assuming the
98717d4247SJustin T. Gibbs  * be the number of paged sized transfers in MAXPHYS plus an extra element
99717d4247SJustin T. Gibbs  * to handle any unaligned residual.  The sequencer fetches SG elements
10058fb7d8eSJustin T. Gibbs  * in cacheline sized chucks, so make the number per-transaction an even
10158fb7d8eSJustin T. Gibbs  * multiple of 16 which should align us on even the largest of cacheline
10258fb7d8eSJustin T. Gibbs  * boundaries.
103717d4247SJustin T. Gibbs  */
10452c9ce25SScott Long #define AHC_MAXPHYS (128 * 1024)
10552c9ce25SScott Long #define AHC_NSEG (roundup(btoc(AHC_MAXPHYS) + 1, 16))
106717d4247SJustin T. Gibbs 
107717d4247SJustin T. Gibbs /* This driver supports target mode */
108717d4247SJustin T. Gibbs #define AHC_TARGET_MODE 1
109717d4247SJustin T. Gibbs 
110717d4247SJustin T. Gibbs /************************** Softc/SCB Platform Data ***************************/
111717d4247SJustin T. Gibbs struct ahc_platform_data {
112717d4247SJustin T. Gibbs 	/*
113717d4247SJustin T. Gibbs 	 * Hooks into the XPT.
114717d4247SJustin T. Gibbs 	 */
115717d4247SJustin T. Gibbs 	struct	cam_sim		*sim;
116717d4247SJustin T. Gibbs 	struct	cam_sim		*sim_b;
117717d4247SJustin T. Gibbs 	struct	cam_path	*path;
118717d4247SJustin T. Gibbs 	struct	cam_path	*path_b;
119717d4247SJustin T. Gibbs 
120717d4247SJustin T. Gibbs 	int			 regs_res_type;
121717d4247SJustin T. Gibbs 	int			 regs_res_id;
122717d4247SJustin T. Gibbs 	int			 irq_res_type;
123717d4247SJustin T. Gibbs 	struct resource		*regs;
124717d4247SJustin T. Gibbs 	struct resource		*irq;
125717d4247SJustin T. Gibbs 	void			*ih;
12656a7c4a8SJustin T. Gibbs 	eventhandler_tag	 eh;
127b3b25f2cSJustin T. Gibbs 	struct proc		*recovery_thread;
128032b0a17SScott Long 	struct mtx		mtx;
129717d4247SJustin T. Gibbs };
130717d4247SJustin T. Gibbs 
131717d4247SJustin T. Gibbs struct scb_platform_data {
132717d4247SJustin T. Gibbs };
133717d4247SJustin T. Gibbs 
134717d4247SJustin T. Gibbs /***************************** Core Includes **********************************/
135342ed5d9SRuslan Ermilov #ifdef AHC_REG_PRETTY_PRINT
1364c4797e6SJustin T. Gibbs #define AIC_DEBUG_REGISTERS 1
1374c4797e6SJustin T. Gibbs #else
1384c4797e6SJustin T. Gibbs #define AIC_DEBUG_REGISTERS 0
1394c4797e6SJustin T. Gibbs #endif
140b3b25f2cSJustin T. Gibbs #define AIC_CORE_INCLUDE <dev/aic7xxx/aic7xxx.h>
141b3b25f2cSJustin T. Gibbs #define	AIC_LIB_PREFIX ahc
142b3b25f2cSJustin T. Gibbs #define	AIC_CONST_PREFIX AHC
143b3b25f2cSJustin T. Gibbs #include <dev/aic7xxx/aic_osm_lib.h>
1443cb8be93SScott Long 
145717d4247SJustin T. Gibbs /*************************** Device Access ************************************/
146717d4247SJustin T. Gibbs #define ahc_inb(ahc, port)				\
147717d4247SJustin T. Gibbs 	bus_space_read_1((ahc)->tag, (ahc)->bsh, port)
148717d4247SJustin T. Gibbs 
149717d4247SJustin T. Gibbs #define ahc_outb(ahc, port, value)			\
150717d4247SJustin T. Gibbs 	bus_space_write_1((ahc)->tag, (ahc)->bsh, port, value)
151717d4247SJustin T. Gibbs 
152717d4247SJustin T. Gibbs #define ahc_outsb(ahc, port, valp, count)		\
153717d4247SJustin T. Gibbs 	bus_space_write_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
154717d4247SJustin T. Gibbs 
155717d4247SJustin T. Gibbs #define ahc_insb(ahc, port, valp, count)		\
156717d4247SJustin T. Gibbs 	bus_space_read_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
157717d4247SJustin T. Gibbs 
158717d4247SJustin T. Gibbs static __inline void ahc_flush_device_writes(struct ahc_softc *);
159717d4247SJustin T. Gibbs 
160717d4247SJustin T. Gibbs static __inline void
ahc_flush_device_writes(struct ahc_softc * ahc)161717d4247SJustin T. Gibbs ahc_flush_device_writes(struct ahc_softc *ahc)
162717d4247SJustin T. Gibbs {
163717d4247SJustin T. Gibbs 	/* XXX Is this sufficient for all architectures??? */
164717d4247SJustin T. Gibbs 	ahc_inb(ahc, INTSTAT);
165717d4247SJustin T. Gibbs }
166717d4247SJustin T. Gibbs 
167717d4247SJustin T. Gibbs /**************************** Locking Primitives ******************************/
168717d4247SJustin T. Gibbs /* Lock protecting internal data structures */
169717d4247SJustin T. Gibbs static __inline void ahc_lockinit(struct ahc_softc *);
170032b0a17SScott Long static __inline void ahc_lock(struct ahc_softc *);
171032b0a17SScott Long static __inline void ahc_unlock(struct ahc_softc *);
1724c4797e6SJustin T. Gibbs 
173717d4247SJustin T. Gibbs static __inline void
ahc_lockinit(struct ahc_softc * ahc)174717d4247SJustin T. Gibbs ahc_lockinit(struct ahc_softc *ahc)
175717d4247SJustin T. Gibbs {
176032b0a17SScott Long 	mtx_init(&ahc->platform_data->mtx, "ahc_lock", NULL, MTX_DEF);
177717d4247SJustin T. Gibbs }
178717d4247SJustin T. Gibbs 
179717d4247SJustin T. Gibbs static __inline void
ahc_lock(struct ahc_softc * ahc)180032b0a17SScott Long ahc_lock(struct ahc_softc *ahc)
181717d4247SJustin T. Gibbs {
182032b0a17SScott Long 	mtx_lock(&ahc->platform_data->mtx);
183717d4247SJustin T. Gibbs }
184717d4247SJustin T. Gibbs 
185717d4247SJustin T. Gibbs static __inline void
ahc_unlock(struct ahc_softc * ahc)186032b0a17SScott Long ahc_unlock(struct ahc_softc *ahc)
187717d4247SJustin T. Gibbs {
188032b0a17SScott Long 	mtx_unlock(&ahc->platform_data->mtx);
1894c4797e6SJustin T. Gibbs }
190a49630acSJustin T. Gibbs 
1917afc0218SJustin T. Gibbs /************************* Initialization/Teardown ****************************/
1927afc0218SJustin T. Gibbs int	  ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
1937afc0218SJustin T. Gibbs void	  ahc_platform_free(struct ahc_softc *ahc);
1947afc0218SJustin T. Gibbs int	  ahc_map_int(struct ahc_softc *ahc);
1957afc0218SJustin T. Gibbs int	  ahc_attach(struct ahc_softc *);
1967afc0218SJustin T. Gibbs int	  ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc);
1977afc0218SJustin T. Gibbs int	  ahc_detach(device_t);
1987afc0218SJustin T. Gibbs 
199717d4247SJustin T. Gibbs /********************************** PCI ***************************************/
200b3b25f2cSJustin T. Gibbs #ifdef AIC_PCI_CONFIG
201717d4247SJustin T. Gibbs int ahc_pci_map_registers(struct ahc_softc *ahc);
2027afc0218SJustin T. Gibbs #define ahc_pci_map_int ahc_map_int
203b3b25f2cSJustin T. Gibbs #endif /*AIC_PCI_CONFIG*/
204717d4247SJustin T. Gibbs 
205a4e4cebfSWarner Losh /******************************** VL/EISA/ISA *********************************/
2068f214efcSJustin T. Gibbs int aic7770_map_registers(struct ahc_softc *ahc, u_int port);
2077afc0218SJustin T. Gibbs static __inline int aic7770_map_int(struct ahc_softc *, int);
2087afc0218SJustin T. Gibbs 
2097afc0218SJustin T. Gibbs static __inline int
aic7770_map_int(struct ahc_softc * ahc,int irq)2107afc0218SJustin T. Gibbs aic7770_map_int(struct ahc_softc *ahc, int irq)
2117afc0218SJustin T. Gibbs {
2127afc0218SJustin T. Gibbs 	/*
2137afc0218SJustin T. Gibbs 	 * The IRQ is unused in the FreeBSD
214a4e4cebfSWarner Losh 	 * implementation since the ISA attachment
215a4e4cebfSWarner Losh 	 * registers the IRQ with newbus before
216a4e4cebfSWarner Losh 	 * the core is called.
2177afc0218SJustin T. Gibbs 	 */
2187afc0218SJustin T. Gibbs 	return ahc_map_int(ahc);
2197afc0218SJustin T. Gibbs }
220717d4247SJustin T. Gibbs 
221717d4247SJustin T. Gibbs /********************************* Debug **************************************/
222717d4247SJustin T. Gibbs static __inline void	ahc_print_path(struct ahc_softc *, struct scb *);
223717d4247SJustin T. Gibbs static __inline void	ahc_platform_dump_card_state(struct ahc_softc *ahc);
224717d4247SJustin T. Gibbs 
225717d4247SJustin T. Gibbs static __inline void
ahc_print_path(struct ahc_softc * ahc,struct scb * scb)226717d4247SJustin T. Gibbs ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
227717d4247SJustin T. Gibbs {
228717d4247SJustin T. Gibbs 	xpt_print_path(scb->io_ctx->ccb_h.path);
229717d4247SJustin T. Gibbs }
230717d4247SJustin T. Gibbs 
231717d4247SJustin T. Gibbs static __inline void
ahc_platform_dump_card_state(struct ahc_softc * ahc)232717d4247SJustin T. Gibbs ahc_platform_dump_card_state(struct ahc_softc *ahc)
233717d4247SJustin T. Gibbs {
234717d4247SJustin T. Gibbs 	/* Nothing to do here for FreeBSD */
235717d4247SJustin T. Gibbs }
236717d4247SJustin T. Gibbs /**************************** Transfer Settings *******************************/
237717d4247SJustin T. Gibbs void	  ahc_notify_xfer_settings_change(struct ahc_softc *,
238717d4247SJustin T. Gibbs 					  struct ahc_devinfo *);
239717d4247SJustin T. Gibbs void	  ahc_platform_set_tags(struct ahc_softc *, struct ahc_devinfo *,
240717d4247SJustin T. Gibbs 				int /*enable*/);
241717d4247SJustin T. Gibbs 
24256a7c4a8SJustin T. Gibbs /****************************** Interrupts ************************************/
24356a7c4a8SJustin T. Gibbs void			ahc_platform_intr(void *);
24456a7c4a8SJustin T. Gibbs static __inline void	ahc_platform_flushwork(struct ahc_softc *ahc);
24556a7c4a8SJustin T. Gibbs static __inline void
ahc_platform_flushwork(struct ahc_softc * ahc)24656a7c4a8SJustin T. Gibbs ahc_platform_flushwork(struct ahc_softc *ahc)
24756a7c4a8SJustin T. Gibbs {
24856a7c4a8SJustin T. Gibbs }
249717d4247SJustin T. Gibbs 
250717d4247SJustin T. Gibbs /************************ Misc Function Declarations **************************/
251717d4247SJustin T. Gibbs void	  ahc_done(struct ahc_softc *ahc, struct scb *scb);
252c498406dSJustin T. Gibbs void	  ahc_send_async(struct ahc_softc *, char /*channel*/,
25358fb7d8eSJustin T. Gibbs 			 u_int /*target*/, u_int /*lun*/, ac_code, void *arg);
254717d4247SJustin T. Gibbs #endif  /* _AIC7XXX_FREEBSD_H_ */
255