aic79xx_osm.h revision 168807
1139749Simp/*-
297883Sgibbs * FreeBSD platform specific driver option settings, data structures,
397883Sgibbs * function declarations and includes.
497883Sgibbs *
597883Sgibbs * Copyright (c) 1994-2001 Justin T. Gibbs.
6102685Sgibbs * Copyright (c) 2001-2002 Adaptec Inc.
797883Sgibbs * All rights reserved.
897883Sgibbs *
997883Sgibbs * Redistribution and use in source and binary forms, with or without
1097883Sgibbs * modification, are permitted provided that the following conditions
1197883Sgibbs * are met:
1297883Sgibbs * 1. Redistributions of source code must retain the above copyright
1397883Sgibbs *    notice, this list of conditions, and the following disclaimer,
1497883Sgibbs *    without modification.
1597883Sgibbs * 2. The name of the author may not be used to endorse or promote products
1697883Sgibbs *    derived from this software without specific prior written permission.
1797883Sgibbs *
1897883Sgibbs * Alternatively, this software may be distributed under the terms of the
1997883Sgibbs * GNU Public License ("GPL").
2097883Sgibbs *
2197883Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2297883Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2397883Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2497883Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2597883Sgibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2697883Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2797883Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2897883Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2997883Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3097883Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3197883Sgibbs * SUCH DAMAGE.
3297883Sgibbs *
33123579Sgibbs * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#23 $
3497883Sgibbs *
3597883Sgibbs * $FreeBSD: head/sys/dev/aic7xxx/aic79xx_osm.h 168807 2007-04-17 06:26:25Z scottl $
3697883Sgibbs */
3797883Sgibbs
3897883Sgibbs#ifndef _AIC79XX_FREEBSD_H_
3997883Sgibbs#define _AIC79XX_FREEBSD_H_
4097883Sgibbs
4197883Sgibbs#include <opt_aic79xx.h>	/* for config options */
4297883Sgibbs
4397883Sgibbs#include <sys/param.h>
4497883Sgibbs#include <sys/systm.h>
4597883Sgibbs#include <sys/bus.h>		/* For device_t */
46102685Sgibbs#if __FreeBSD_version >= 500000
47102685Sgibbs#include <sys/endian.h>
48102685Sgibbs#endif
4997883Sgibbs#include <sys/eventhandler.h>
5097883Sgibbs#include <sys/kernel.h>
5197883Sgibbs#include <sys/malloc.h>
52129879Sphk#include <sys/module.h>
5397883Sgibbs#include <sys/queue.h>
5497883Sgibbs
55123579Sgibbs#define AIC_PCI_CONFIG 1
5697883Sgibbs#include <machine/bus.h>
5797883Sgibbs#include <machine/endian.h>
5897883Sgibbs#include <machine/resource.h>
5997883Sgibbs
6097883Sgibbs#include <sys/rman.h>
6197883Sgibbs
62119277Simp#if __FreeBSD_version >= 500000
63119277Simp#include <dev/pci/pcireg.h>
64119277Simp#include <dev/pci/pcivar.h>
65119277Simp#else
6697883Sgibbs#include <pci/pcireg.h>
6797883Sgibbs#include <pci/pcivar.h>
68119277Simp#endif
6997883Sgibbs
7097883Sgibbs#include <cam/cam.h>
7197883Sgibbs#include <cam/cam_ccb.h>
7297883Sgibbs#include <cam/cam_debug.h>
7397883Sgibbs#include <cam/cam_sim.h>
7497883Sgibbs#include <cam/cam_xpt_sim.h>
7597883Sgibbs
7697883Sgibbs#include <cam/scsi/scsi_all.h>
7797883Sgibbs#include <cam/scsi/scsi_message.h>
7897883Sgibbs#include <cam/scsi/scsi_iu.h>
7997883Sgibbs
8097883Sgibbs/****************************** Platform Macros *******************************/
8197883Sgibbs#define	SIM_IS_SCSIBUS_B(ahd, sim)	\
8297883Sgibbs	(0)
8397883Sgibbs#define	SIM_CHANNEL(ahd, sim)	\
8497883Sgibbs	('A')
8597883Sgibbs#define	SIM_SCSI_ID(ahd, sim)	\
8697883Sgibbs	(ahd->our_id)
8797883Sgibbs#define	SIM_PATH(ahd, sim)	\
8897883Sgibbs	(ahd->platform_data->path)
8997883Sgibbs#define BUILD_SCSIID(ahd, sim, target_id, our_id) \
9097883Sgibbs        ((((target_id) << TID_SHIFT) & TID) | (our_id))
9197883Sgibbs
9297883Sgibbs
9397883Sgibbs#define SCB_GET_SIM(ahd, scb) \
9497883Sgibbs	((ahd)->platform_data->sim)
9597883Sgibbs
9697883Sgibbs#ifndef offsetof
9797883Sgibbs#define offsetof(type, member)  ((size_t)(&((type *)0)->member))
9897883Sgibbs#endif
9997883Sgibbs
10097883Sgibbs/************************ Tunable Driver Parameters  **************************/
10197883Sgibbs/*
10297883Sgibbs * The number of dma segments supported.  The sequencer can handle any number
10397883Sgibbs * of physically contiguous S/G entrys.  To reduce the driver's memory
10497883Sgibbs * consumption, we limit the number supported to be sufficient to handle
10597883Sgibbs * the largest mapping supported by the kernel, MAXPHYS.  Assuming the
10697883Sgibbs * transfer is as fragmented as possible and unaligned, this turns out to
10797883Sgibbs * be the number of paged sized transfers in MAXPHYS plus an extra element
10897883Sgibbs * to handle any unaligned residual.  The sequencer fetches SG elements
10997883Sgibbs * in cacheline sized chucks, so make the number per-transaction an even
11097883Sgibbs * multiple of 16 which should align us on even the largest of cacheline
11197883Sgibbs * boundaries.
11297883Sgibbs */
11397883Sgibbs#define AHD_NSEG (roundup(btoc(MAXPHYS) + 1, 16))
11497883Sgibbs
11597883Sgibbs/* This driver supports target mode */
116153072Sru#ifdef NOT_YET
11797883Sgibbs#define AHD_TARGET_MODE 1
11897883Sgibbs#endif
11997883Sgibbs
12097883Sgibbs/************************** Softc/SCB Platform Data ***************************/
12197883Sgibbsstruct ahd_platform_data {
12297883Sgibbs	/*
12397883Sgibbs	 * Hooks into the XPT.
12497883Sgibbs	 */
12597883Sgibbs	struct	cam_sim		*sim;
12697883Sgibbs	struct	cam_path	*path;
12797883Sgibbs
12897883Sgibbs	int			 regs_res_type[2];
12997883Sgibbs	int			 regs_res_id[2];
13097883Sgibbs	int			 irq_res_type;
13197883Sgibbs	struct resource		*regs[2];
13297883Sgibbs	struct resource		*irq;
13397883Sgibbs	void			*ih;
13497883Sgibbs	eventhandler_tag	 eh;
135123579Sgibbs	struct proc		*recovery_thread;
136168807Sscottl	struct mtx		mtx;
13797883Sgibbs};
13897883Sgibbs
13997883Sgibbsstruct scb_platform_data {
14097883Sgibbs};
14197883Sgibbs
14297883Sgibbs/***************************** Core Includes **********************************/
143153165Sru#ifdef AHD_REG_PRETTY_PRINT
144102685Sgibbs#define AIC_DEBUG_REGISTERS 1
145102685Sgibbs#else
146102685Sgibbs#define AIC_DEBUG_REGISTERS 0
147102685Sgibbs#endif
148123579Sgibbs#define AIC_CORE_INCLUDE <dev/aic7xxx/aic79xx.h>
149123579Sgibbs#define	AIC_LIB_PREFIX ahd
150123579Sgibbs#define	AIC_CONST_PREFIX AHD
151123579Sgibbs#include <dev/aic7xxx/aic_osm_lib.h>
15297883Sgibbs
15397883Sgibbs/*************************** Device Access ************************************/
15497883Sgibbs#define ahd_inb(ahd, port)					\
15597883Sgibbs	bus_space_read_1((ahd)->tags[(port) >> 8],		\
15697883Sgibbs			 (ahd)->bshs[(port) >> 8], (port) & 0xFF)
15797883Sgibbs
15897883Sgibbs#define ahd_outb(ahd, port, value)				\
15997883Sgibbs	bus_space_write_1((ahd)->tags[(port) >> 8],		\
16097883Sgibbs			  (ahd)->bshs[(port) >> 8], (port) & 0xFF, value)
16197883Sgibbs
16297883Sgibbs#define ahd_inw_atomic(ahd, port)				\
163123579Sgibbs	aic_le16toh(bus_space_read_2((ahd)->tags[(port) >> 8],	\
16497883Sgibbs				     (ahd)->bshs[(port) >> 8], (port) & 0xFF))
16597883Sgibbs
16697883Sgibbs#define ahd_outw_atomic(ahd, port, value)			\
16797883Sgibbs	bus_space_write_2((ahd)->tags[(port) >> 8],		\
16897883Sgibbs			  (ahd)->bshs[(port) >> 8],		\
169123579Sgibbs			  (port & 0xFF), aic_htole16(value))
17097883Sgibbs
17197883Sgibbs#define ahd_outsb(ahd, port, valp, count)			\
17297883Sgibbs	bus_space_write_multi_1((ahd)->tags[(port) >> 8],	\
17397883Sgibbs				(ahd)->bshs[(port) >> 8],	\
17497883Sgibbs				(port & 0xFF), valp, count)
17597883Sgibbs
17697883Sgibbs#define ahd_insb(ahd, port, valp, count)			\
17797883Sgibbs	bus_space_read_multi_1((ahd)->tags[(port) >> 8],	\
17897883Sgibbs			       (ahd)->bshs[(port) >> 8],	\
17997883Sgibbs			       (port & 0xFF), valp, count)
18097883Sgibbs
18197883Sgibbsstatic __inline void ahd_flush_device_writes(struct ahd_softc *);
18297883Sgibbs
18397883Sgibbsstatic __inline void
18497883Sgibbsahd_flush_device_writes(struct ahd_softc *ahd)
18597883Sgibbs{
18697883Sgibbs	/* XXX Is this sufficient for all architectures??? */
18797883Sgibbs	ahd_inb(ahd, INTSTAT);
18897883Sgibbs}
18997883Sgibbs
19097883Sgibbs/**************************** Locking Primitives ******************************/
19197883Sgibbs/* Lock protecting internal data structures */
19297883Sgibbsstatic __inline void ahd_lockinit(struct ahd_softc *);
193168807Sscottlstatic __inline void ahd_lock(struct ahd_softc *);
194168807Sscottlstatic __inline void ahd_unlock(struct ahd_softc *);
19597883Sgibbs
19697883Sgibbsstatic __inline void
19797883Sgibbsahd_lockinit(struct ahd_softc *ahd)
19897883Sgibbs{
199168807Sscottl	mtx_init(&ahd->platform_data->mtx, "ahd_lock", NULL, MTX_DEF);
20097883Sgibbs}
20197883Sgibbs
20297883Sgibbsstatic __inline void
203168807Sscottlahd_lock(struct ahd_softc *ahd)
20497883Sgibbs{
205168807Sscottl	mtx_lock(&ahd->platform_data->mtx);
20697883Sgibbs}
20797883Sgibbs
20897883Sgibbsstatic __inline void
209168807Sscottlahd_unlock(struct ahd_softc *ahd)
21097883Sgibbs{
211168807Sscottl	mtx_unlock(&ahd->platform_data->mtx);
21297883Sgibbs}
21397883Sgibbs
214123579Sgibbs/********************************** PCI ***************************************/
215123579Sgibbsint ahd_pci_map_registers(struct ahd_softc *ahd);
216123579Sgibbsint ahd_pci_map_int(struct ahd_softc *ahd);
217123579Sgibbs
21897883Sgibbs/************************** Transaction Operations ****************************/
219123579Sgibbsstatic __inline void aic_freeze_simq(struct aic_softc*);
220123579Sgibbsstatic __inline void aic_release_simq(struct aic_softc*);
22197883Sgibbs
22297883Sgibbsstatic __inline void
223123579Sgibbsaic_freeze_simq(struct aic_softc *aic)
22497883Sgibbs{
225123579Sgibbs	xpt_freeze_simq(aic->platform_data->sim, /*count*/1);
22697883Sgibbs}
22797883Sgibbs
22897883Sgibbsstatic __inline void
229123579Sgibbsaic_release_simq(struct aic_softc *aic)
23097883Sgibbs{
231123579Sgibbs	xpt_release_simq(aic->platform_data->sim, /*run queue*/TRUE);
23297883Sgibbs}
23397883Sgibbs/********************************* Debug **************************************/
23497883Sgibbsstatic __inline void	ahd_print_path(struct ahd_softc *, struct scb *);
23597883Sgibbsstatic __inline void	ahd_platform_dump_card_state(struct ahd_softc *ahd);
23697883Sgibbs
23797883Sgibbsstatic __inline void
23897883Sgibbsahd_print_path(struct ahd_softc *ahd, struct scb *scb)
23997883Sgibbs{
24097883Sgibbs	xpt_print_path(scb->io_ctx->ccb_h.path);
24197883Sgibbs}
24297883Sgibbs
24397883Sgibbsstatic __inline void
24497883Sgibbsahd_platform_dump_card_state(struct ahd_softc *ahd)
24597883Sgibbs{
24697883Sgibbs	/* Nothing to do here for FreeBSD */
24797883Sgibbs}
24897883Sgibbs/**************************** Transfer Settings *******************************/
24997883Sgibbsvoid	  ahd_notify_xfer_settings_change(struct ahd_softc *,
25097883Sgibbs					  struct ahd_devinfo *);
25197883Sgibbsvoid	  ahd_platform_set_tags(struct ahd_softc *, struct ahd_devinfo *,
25297883Sgibbs				int /*enable*/);
25397883Sgibbs
25497883Sgibbs/************************* Initialization/Teardown ****************************/
25597883Sgibbsint	  ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg);
25697883Sgibbsvoid	  ahd_platform_free(struct ahd_softc *ahd);
25797883Sgibbsint	  ahd_map_int(struct ahd_softc *ahd);
25897883Sgibbsint	  ahd_attach(struct ahd_softc *);
25997883Sgibbsint	  ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd);
26097883Sgibbsint	  ahd_detach(device_t);
261107437Sscottl#define	ahd_platform_init(arg)
26297883Sgibbs
263107437Sscottl
26497883Sgibbs/****************************** Interrupts ************************************/
26597883Sgibbsvoid			ahd_platform_intr(void *);
26697883Sgibbsstatic __inline void	ahd_platform_flushwork(struct ahd_softc *ahd);
26797883Sgibbsstatic __inline void
26897883Sgibbsahd_platform_flushwork(struct ahd_softc *ahd)
26997883Sgibbs{
27097883Sgibbs}
27197883Sgibbs
27297883Sgibbs/************************ Misc Function Declarations **************************/
27397883Sgibbsvoid	  ahd_done(struct ahd_softc *ahd, struct scb *scb);
27497883Sgibbsvoid	  ahd_send_async(struct ahd_softc *, char /*channel*/,
27597883Sgibbs			 u_int /*target*/, u_int /*lun*/, ac_code, void *arg);
27697883Sgibbs#endif  /* _AIC79XX_FREEBSD_H_ */
277