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