MPSAFE locking for the ahc/ahd drivers using lockmgr locks.
[dragonfly.git] / sys / dev / disk / aic7xxx / aic7xxx_osm.h
CommitLineData
984263bc
MD
1/*
2 * FreeBSD platform specific driver option settings, data structures,
3 * function declarations and includes.
4 *
5 * Copyright (c) 1994-2001 Justin T. Gibbs.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU Public License ("GPL").
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
750f3593 32 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#18 $
984263bc 33 *
96ca467d 34 * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_osm.h,v 1.30 2005/12/05 11:58:32 ru Exp $
ef8ef949 35 * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_osm.h,v 1.13 2008/02/09 18:13:13 pavalos Exp $
984263bc
MD
36 */
37
38#ifndef _AIC7XXX_FREEBSD_H_
39#define _AIC7XXX_FREEBSD_H_
40
41#include <opt_aic7xxx.h> /* for config options */
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/bus.h> /* For device_t */
84754cd0 46#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
984263bc
MD
47#include <sys/endian.h>
48#endif
49#include <sys/eventhandler.h>
50#include <sys/kernel.h>
51#include <sys/malloc.h>
52#include <sys/queue.h>
1f7ab7c9 53#include <sys/rman.h>
c1139c5e 54#include <sys/thread2.h>
984263bc 55
84754cd0 56#if defined(__DragonFly__) || __FreeBSD_version < 500000
1f2de5d4 57#include <use_pci.h>
984263bc
MD
58#else
59#define NPCI 1
60#endif
61
62#if NPCI > 0
750f3593 63#define AIC_PCI_CONFIG 1
984263bc 64#endif
984263bc
MD
65#include <machine/endian.h>
66#include <machine/clock.h>
984263bc
MD
67
68#if NPCI > 0
1f2de5d4
MD
69#include <bus/pci/pcireg.h>
70#include <bus/pci/pcivar.h>
984263bc
MD
71#endif
72
1f2de5d4
MD
73#include <bus/cam/cam.h>
74#include <bus/cam/cam_ccb.h>
75#include <bus/cam/cam_debug.h>
76#include <bus/cam/cam_sim.h>
77#include <bus/cam/cam_xpt_sim.h>
984263bc 78
1f2de5d4
MD
79#include <bus/cam/scsi/scsi_all.h>
80#include <bus/cam/scsi/scsi_message.h>
984263bc
MD
81
82#ifdef CAM_NEW_TRAN_CODE
83#define AHC_NEW_TRAN_SETTINGS
84#endif /* CAM_NEW_TRAN_CODE */
85
86/*************************** Attachment Bookkeeping ***************************/
87extern devclass_t ahc_devclass;
88
89/****************************** Platform Macros *******************************/
90#define SIM_IS_SCSIBUS_B(ahc, sim) \
91 ((sim) == ahc->platform_data->sim_b)
92#define SIM_CHANNEL(ahc, sim) \
93 (((sim) == ahc->platform_data->sim_b) ? 'B' : 'A')
94#define SIM_SCSI_ID(ahc, sim) \
95 (((sim) == ahc->platform_data->sim_b) ? ahc->our_id_b : ahc->our_id)
96#define SIM_PATH(ahc, sim) \
97 (((sim) == ahc->platform_data->sim_b) ? ahc->platform_data->path_b \
98 : ahc->platform_data->path)
99#define BUILD_SCSIID(ahc, sim, target_id, our_id) \
100 ((((target_id) << TID_SHIFT) & TID) | (our_id) \
101 | (SIM_IS_SCSIBUS_B(ahc, sim) ? TWIN_CHNLB : 0))
102
103#define SCB_GET_SIM(ahc, scb) \
104 (SCB_GET_CHANNEL(ahc, scb) == 'A' ? (ahc)->platform_data->sim \
105 : (ahc)->platform_data->sim_b)
106
107#ifndef offsetof
108#define offsetof(type, member) ((size_t)(&((type *)0)->member))
109#endif
984263bc
MD
110
111/************************ Tunable Driver Parameters **************************/
112/*
113 * The number of dma segments supported. The sequencer can handle any number
114 * of physically contiguous S/G entrys. To reduce the driver's memory
115 * consumption, we limit the number supported to be sufficient to handle
116 * the largest mapping supported by the kernel, MAXPHYS. Assuming the
117 * transfer is as fragmented as possible and unaligned, this turns out to
118 * be the number of paged sized transfers in MAXPHYS plus an extra element
119 * to handle any unaligned residual. The sequencer fetches SG elements
120 * in cacheline sized chucks, so make the number per-transaction an even
121 * multiple of 16 which should align us on even the largest of cacheline
122 * boundaries.
123 */
124#define AHC_NSEG (roundup(btoc(MAXPHYS) + 1, 16))
125
126/* This driver supports target mode */
127#define AHC_TARGET_MODE 1
128
ef8ef949
PA
129/***************************** Core Includes **********************************/
130#ifdef AHC_REG_PRETTY_PRINT
131#define AIC_DEBUG_REGISTERS 1
132#else
133#define AIC_DEBUG_REGISTERS 0
134#endif
135#define AIC_CORE_INCLUDE "aic7xxx.h"
136#define AIC_LIB_PREFIX ahc
137#define AIC_CONST_PREFIX AHC
138#include "aic_osm_lib.h"
139
984263bc
MD
140/************************** Softc/SCB Platform Data ***************************/
141struct ahc_platform_data {
142 /*
143 * Hooks into the XPT.
144 */
145 struct cam_sim *sim;
146 struct cam_sim *sim_b;
147 struct cam_path *path;
148 struct cam_path *path_b;
149
150 int regs_res_type;
151 int regs_res_id;
152 int irq_res_type;
153 struct resource *regs;
154 struct resource *irq;
155 void *ih;
156 eventhandler_tag eh;
750f3593 157 struct thread *recovery_thread;
ef8ef949 158 struct lock lock;
984263bc
MD
159};
160
161struct scb_platform_data {
162};
163
984263bc
MD
164/*************************** Device Access ************************************/
165#define ahc_inb(ahc, port) \
166 bus_space_read_1((ahc)->tag, (ahc)->bsh, port)
167
168#define ahc_outb(ahc, port, value) \
169 bus_space_write_1((ahc)->tag, (ahc)->bsh, port, value)
170
171#define ahc_outsb(ahc, port, valp, count) \
172 bus_space_write_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
173
174#define ahc_insb(ahc, port, valp, count) \
175 bus_space_read_multi_1((ahc)->tag, (ahc)->bsh, port, valp, count)
176
177static __inline void ahc_flush_device_writes(struct ahc_softc *);
178
179static __inline void
180ahc_flush_device_writes(struct ahc_softc *ahc)
181{
182 /* XXX Is this sufficient for all architectures??? */
183 ahc_inb(ahc, INTSTAT);
184}
185
186/**************************** Locking Primitives ******************************/
187/* Lock protecting internal data structures */
ef8ef949
PA
188static __inline void ahc_lockinit(struct ahc_softc *);
189static __inline void ahc_lock(struct ahc_softc *);
190static __inline void ahc_unlock(struct ahc_softc *);
191
192static __inline void
193ahc_lockinit(struct ahc_softc *ahc)
194{
195 lockinit(&ahc->platform_data->lock, "ahc_lock", 0, LK_EXCLUSIVE|LK_CANRECURSE);
196}
984263bc
MD
197
198static __inline void
ef8ef949 199ahc_lock(struct ahc_softc *ahc)
984263bc 200{
ef8ef949 201 lockmgr(&ahc->platform_data->lock, LK_EXCLUSIVE);
984263bc
MD
202}
203
204static __inline void
ef8ef949 205ahc_unlock(struct ahc_softc *ahc)
984263bc 206{
ef8ef949 207 lockmgr(&ahc->platform_data->lock, LK_RELEASE);
984263bc
MD
208}
209
dff3fb2d
PA
210/************************* Initialization/Teardown ****************************/
211int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
212void ahc_platform_free(struct ahc_softc *ahc);
213int ahc_map_int(struct ahc_softc *ahc);
214int ahc_attach(struct ahc_softc *);
215int ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc);
216int ahc_detach(device_t);
217
984263bc 218/********************************** PCI ***************************************/
750f3593
PA
219#ifdef AIC_PCI_CONFIG
220int ahc_pci_map_registers(struct ahc_softc *ahc);
dff3fb2d 221#define ahc_pci_map_int ahc_map_int
750f3593 222#endif /*AIC_PCI_CONFIG*/
984263bc 223
984263bc
MD
224/******************************** VL/EISA *************************************/
225int aic7770_map_registers(struct ahc_softc *ahc, u_int port);
dff3fb2d
PA
226static __inline int aic7770_map_int(struct ahc_softc *, int);
227
228static __inline int
229aic7770_map_int(struct ahc_softc *ahc, int irq)
230{
231 /*
232 * The IRQ is unused in the FreeBSD
233 * implementation since the EISA and
234 * ISA attachments register the IRQ
235 * with newbus before the core is called.
236 */
237 return ahc_map_int(ahc);
238}
984263bc
MD
239
240/********************************* Debug **************************************/
241static __inline void ahc_print_path(struct ahc_softc *, struct scb *);
242static __inline void ahc_platform_dump_card_state(struct ahc_softc *ahc);
243
244static __inline void
245ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
246{
247 xpt_print_path(scb->io_ctx->ccb_h.path);
248}
249
250static __inline void
251ahc_platform_dump_card_state(struct ahc_softc *ahc)
252{
253 /* Nothing to do here for FreeBSD */
254}
255/**************************** Transfer Settings *******************************/
256void ahc_notify_xfer_settings_change(struct ahc_softc *,
257 struct ahc_devinfo *);
258void ahc_platform_set_tags(struct ahc_softc *, struct ahc_devinfo *,
259 int /*enable*/);
260
984263bc
MD
261/****************************** Interrupts ************************************/
262void ahc_platform_intr(void *);
263static __inline void ahc_platform_flushwork(struct ahc_softc *ahc);
264static __inline void
265ahc_platform_flushwork(struct ahc_softc *ahc)
266{
267}
268
269/************************ Misc Function Declarations **************************/
270void ahc_done(struct ahc_softc *ahc, struct scb *scb);
271void ahc_send_async(struct ahc_softc *, char /*channel*/,
272 u_int /*target*/, u_int /*lun*/, ac_code, void *arg);
273#endif /* _AIC7XXX_FREEBSD_H_ */