aic79xx_osm.h revision 123579
197883Sgibbs/* 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 123579 2003-12-17 00:02:10Z gibbs $ 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> 5297883Sgibbs#include <sys/queue.h> 5397883Sgibbs 54123579Sgibbs#define AIC_PCI_CONFIG 1 5597883Sgibbs#include <machine/bus_memio.h> 5697883Sgibbs#include <machine/bus_pio.h> 5797883Sgibbs#include <machine/bus.h> 5897883Sgibbs#include <machine/endian.h> 5997883Sgibbs#include <machine/clock.h> 6097883Sgibbs#include <machine/resource.h> 6197883Sgibbs 6297883Sgibbs#include <sys/rman.h> 6397883Sgibbs 64119277Simp#if __FreeBSD_version >= 500000 65119277Simp#include <dev/pci/pcireg.h> 66119277Simp#include <dev/pci/pcivar.h> 67119277Simp#else 6897883Sgibbs#include <pci/pcireg.h> 6997883Sgibbs#include <pci/pcivar.h> 70119277Simp#endif 7197883Sgibbs 7297883Sgibbs#include <cam/cam.h> 7397883Sgibbs#include <cam/cam_ccb.h> 7497883Sgibbs#include <cam/cam_debug.h> 7597883Sgibbs#include <cam/cam_sim.h> 7697883Sgibbs#include <cam/cam_xpt_sim.h> 7797883Sgibbs 7897883Sgibbs#include <cam/scsi/scsi_all.h> 7997883Sgibbs#include <cam/scsi/scsi_message.h> 8097883Sgibbs#include <cam/scsi/scsi_iu.h> 8197883Sgibbs 8297883Sgibbs#ifdef CAM_NEW_TRAN_CODE 8397883Sgibbs#define AHD_NEW_TRAN_SETTINGS 8497883Sgibbs#endif /* CAM_NEW_TRAN_CODE */ 8597883Sgibbs 8697883Sgibbs/****************************** Platform Macros *******************************/ 8797883Sgibbs#define SIM_IS_SCSIBUS_B(ahd, sim) \ 8897883Sgibbs (0) 8997883Sgibbs#define SIM_CHANNEL(ahd, sim) \ 9097883Sgibbs ('A') 9197883Sgibbs#define SIM_SCSI_ID(ahd, sim) \ 9297883Sgibbs (ahd->our_id) 9397883Sgibbs#define SIM_PATH(ahd, sim) \ 9497883Sgibbs (ahd->platform_data->path) 9597883Sgibbs#define BUILD_SCSIID(ahd, sim, target_id, our_id) \ 9697883Sgibbs ((((target_id) << TID_SHIFT) & TID) | (our_id)) 9797883Sgibbs 9897883Sgibbs 9997883Sgibbs#define SCB_GET_SIM(ahd, scb) \ 10097883Sgibbs ((ahd)->platform_data->sim) 10197883Sgibbs 10297883Sgibbs#ifndef offsetof 10397883Sgibbs#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 10497883Sgibbs#endif 10597883Sgibbs 10697883Sgibbs/************************ Tunable Driver Parameters **************************/ 10797883Sgibbs/* 10897883Sgibbs * The number of dma segments supported. The sequencer can handle any number 10997883Sgibbs * of physically contiguous S/G entrys. To reduce the driver's memory 11097883Sgibbs * consumption, we limit the number supported to be sufficient to handle 11197883Sgibbs * the largest mapping supported by the kernel, MAXPHYS. Assuming the 11297883Sgibbs * transfer is as fragmented as possible and unaligned, this turns out to 11397883Sgibbs * be the number of paged sized transfers in MAXPHYS plus an extra element 11497883Sgibbs * to handle any unaligned residual. The sequencer fetches SG elements 11597883Sgibbs * in cacheline sized chucks, so make the number per-transaction an even 11697883Sgibbs * multiple of 16 which should align us on even the largest of cacheline 11797883Sgibbs * boundaries. 11897883Sgibbs */ 11997883Sgibbs#define AHD_NSEG (roundup(btoc(MAXPHYS) + 1, 16)) 12097883Sgibbs 12197883Sgibbs/* This driver supports target mode */ 12297883Sgibbs#if NOT_YET 12397883Sgibbs#define AHD_TARGET_MODE 1 12497883Sgibbs#endif 12597883Sgibbs 12697883Sgibbs/************************** Softc/SCB Platform Data ***************************/ 12797883Sgibbsstruct ahd_platform_data { 12897883Sgibbs /* 12997883Sgibbs * Hooks into the XPT. 13097883Sgibbs */ 13197883Sgibbs struct cam_sim *sim; 13297883Sgibbs struct cam_path *path; 13397883Sgibbs 13497883Sgibbs int regs_res_type[2]; 13597883Sgibbs int regs_res_id[2]; 13697883Sgibbs int irq_res_type; 13797883Sgibbs struct resource *regs[2]; 13897883Sgibbs struct resource *irq; 13997883Sgibbs void *ih; 14097883Sgibbs eventhandler_tag eh; 141123579Sgibbs struct proc *recovery_thread; 14297883Sgibbs}; 14397883Sgibbs 14497883Sgibbsstruct scb_platform_data { 14597883Sgibbs}; 14697883Sgibbs 14797883Sgibbs/***************************** Core Includes **********************************/ 148102685Sgibbs#if AHD_REG_PRETTY_PRINT 149102685Sgibbs#define AIC_DEBUG_REGISTERS 1 150102685Sgibbs#else 151102685Sgibbs#define AIC_DEBUG_REGISTERS 0 152102685Sgibbs#endif 153123579Sgibbs#define AIC_CORE_INCLUDE <dev/aic7xxx/aic79xx.h> 154123579Sgibbs#define AIC_LIB_PREFIX ahd 155123579Sgibbs#define AIC_CONST_PREFIX AHD 156123579Sgibbs#include <dev/aic7xxx/aic_osm_lib.h> 15797883Sgibbs 15897883Sgibbs/*************************** Device Access ************************************/ 15997883Sgibbs#define ahd_inb(ahd, port) \ 16097883Sgibbs bus_space_read_1((ahd)->tags[(port) >> 8], \ 16197883Sgibbs (ahd)->bshs[(port) >> 8], (port) & 0xFF) 16297883Sgibbs 16397883Sgibbs#define ahd_outb(ahd, port, value) \ 16497883Sgibbs bus_space_write_1((ahd)->tags[(port) >> 8], \ 16597883Sgibbs (ahd)->bshs[(port) >> 8], (port) & 0xFF, value) 16697883Sgibbs 16797883Sgibbs#define ahd_inw_atomic(ahd, port) \ 168123579Sgibbs aic_le16toh(bus_space_read_2((ahd)->tags[(port) >> 8], \ 16997883Sgibbs (ahd)->bshs[(port) >> 8], (port) & 0xFF)) 17097883Sgibbs 17197883Sgibbs#define ahd_outw_atomic(ahd, port, value) \ 17297883Sgibbs bus_space_write_2((ahd)->tags[(port) >> 8], \ 17397883Sgibbs (ahd)->bshs[(port) >> 8], \ 174123579Sgibbs (port & 0xFF), aic_htole16(value)) 17597883Sgibbs 17697883Sgibbs#define ahd_outsb(ahd, port, valp, count) \ 17797883Sgibbs bus_space_write_multi_1((ahd)->tags[(port) >> 8], \ 17897883Sgibbs (ahd)->bshs[(port) >> 8], \ 17997883Sgibbs (port & 0xFF), valp, count) 18097883Sgibbs 18197883Sgibbs#define ahd_insb(ahd, port, valp, count) \ 18297883Sgibbs bus_space_read_multi_1((ahd)->tags[(port) >> 8], \ 18397883Sgibbs (ahd)->bshs[(port) >> 8], \ 18497883Sgibbs (port & 0xFF), valp, count) 18597883Sgibbs 18697883Sgibbsstatic __inline void ahd_flush_device_writes(struct ahd_softc *); 18797883Sgibbs 18897883Sgibbsstatic __inline void 18997883Sgibbsahd_flush_device_writes(struct ahd_softc *ahd) 19097883Sgibbs{ 19197883Sgibbs /* XXX Is this sufficient for all architectures??? */ 19297883Sgibbs ahd_inb(ahd, INTSTAT); 19397883Sgibbs} 19497883Sgibbs 19597883Sgibbs/**************************** Locking Primitives ******************************/ 19697883Sgibbs/* Lock protecting internal data structures */ 19797883Sgibbsstatic __inline void ahd_lockinit(struct ahd_softc *); 19897883Sgibbsstatic __inline void ahd_lock(struct ahd_softc *, unsigned long *flags); 19997883Sgibbsstatic __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags); 20097883Sgibbs 20197883Sgibbs/* Lock held during command compeletion to the upper layer */ 20297883Sgibbsstatic __inline void ahd_done_lockinit(struct ahd_softc *); 20397883Sgibbsstatic __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags); 20497883Sgibbsstatic __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags); 20597883Sgibbs 206102685Sgibbs/* Lock held during ahd_list manipulation and ahd softc frees */ 20797883Sgibbsstatic __inline void ahd_list_lockinit(void); 20897883Sgibbsstatic __inline void ahd_list_lock(unsigned long *flags); 20997883Sgibbsstatic __inline void ahd_list_unlock(unsigned long *flags); 21097883Sgibbs 21197883Sgibbsstatic __inline void 21297883Sgibbsahd_lockinit(struct ahd_softc *ahd) 21397883Sgibbs{ 21497883Sgibbs} 21597883Sgibbs 21697883Sgibbsstatic __inline void 21797883Sgibbsahd_lock(struct ahd_softc *ahd, unsigned long *flags) 21897883Sgibbs{ 21997883Sgibbs *flags = splcam(); 22097883Sgibbs} 22197883Sgibbs 22297883Sgibbsstatic __inline void 22397883Sgibbsahd_unlock(struct ahd_softc *ahd, unsigned long *flags) 22497883Sgibbs{ 22597883Sgibbs splx(*flags); 22697883Sgibbs} 22797883Sgibbs 22897883Sgibbs/* Lock held during command compeletion to the upper layer */ 22997883Sgibbsstatic __inline void 23097883Sgibbsahd_done_lockinit(struct ahd_softc *ahd) 23197883Sgibbs{ 23297883Sgibbs} 23397883Sgibbs 23497883Sgibbsstatic __inline void 23597883Sgibbsahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) 23697883Sgibbs{ 23797883Sgibbs} 23897883Sgibbs 23997883Sgibbsstatic __inline void 24097883Sgibbsahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) 24197883Sgibbs{ 24297883Sgibbs} 24397883Sgibbs 244102685Sgibbs/* Lock held during ahd_list manipulation and ahd softc frees */ 24597883Sgibbsstatic __inline void 246115336Sgibbsahd_list_lockinit(void) 24797883Sgibbs{ 24897883Sgibbs} 24997883Sgibbs 25097883Sgibbsstatic __inline void 25197883Sgibbsahd_list_lock(unsigned long *flags) 25297883Sgibbs{ 25397883Sgibbs} 25497883Sgibbs 25597883Sgibbsstatic __inline void 25697883Sgibbsahd_list_unlock(unsigned long *flags) 25797883Sgibbs{ 25897883Sgibbs} 25997883Sgibbs 260123579Sgibbs/********************************** PCI ***************************************/ 261123579Sgibbsint ahd_pci_map_registers(struct ahd_softc *ahd); 262123579Sgibbsint ahd_pci_map_int(struct ahd_softc *ahd); 263123579Sgibbs 26497883Sgibbs/************************** Transaction Operations ****************************/ 265123579Sgibbsstatic __inline void aic_freeze_simq(struct aic_softc*); 266123579Sgibbsstatic __inline void aic_release_simq(struct aic_softc*); 26797883Sgibbs 26897883Sgibbsstatic __inline void 269123579Sgibbsaic_freeze_simq(struct aic_softc *aic) 27097883Sgibbs{ 271123579Sgibbs xpt_freeze_simq(aic->platform_data->sim, /*count*/1); 27297883Sgibbs} 27397883Sgibbs 27497883Sgibbsstatic __inline void 275123579Sgibbsaic_release_simq(struct aic_softc *aic) 27697883Sgibbs{ 277123579Sgibbs xpt_release_simq(aic->platform_data->sim, /*run queue*/TRUE); 27897883Sgibbs} 27997883Sgibbs/********************************* Debug **************************************/ 28097883Sgibbsstatic __inline void ahd_print_path(struct ahd_softc *, struct scb *); 28197883Sgibbsstatic __inline void ahd_platform_dump_card_state(struct ahd_softc *ahd); 28297883Sgibbs 28397883Sgibbsstatic __inline void 28497883Sgibbsahd_print_path(struct ahd_softc *ahd, struct scb *scb) 28597883Sgibbs{ 28697883Sgibbs xpt_print_path(scb->io_ctx->ccb_h.path); 28797883Sgibbs} 28897883Sgibbs 28997883Sgibbsstatic __inline void 29097883Sgibbsahd_platform_dump_card_state(struct ahd_softc *ahd) 29197883Sgibbs{ 29297883Sgibbs /* Nothing to do here for FreeBSD */ 29397883Sgibbs} 29497883Sgibbs/**************************** Transfer Settings *******************************/ 29597883Sgibbsvoid ahd_notify_xfer_settings_change(struct ahd_softc *, 29697883Sgibbs struct ahd_devinfo *); 29797883Sgibbsvoid ahd_platform_set_tags(struct ahd_softc *, struct ahd_devinfo *, 29897883Sgibbs int /*enable*/); 29997883Sgibbs 30097883Sgibbs/************************* Initialization/Teardown ****************************/ 30197883Sgibbsint ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); 30297883Sgibbsvoid ahd_platform_free(struct ahd_softc *ahd); 30397883Sgibbsint ahd_map_int(struct ahd_softc *ahd); 30497883Sgibbsint ahd_attach(struct ahd_softc *); 30597883Sgibbsint ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd); 30697883Sgibbsint ahd_detach(device_t); 307107437Sscottl#define ahd_platform_init(arg) 30897883Sgibbs 309107437Sscottl 31097883Sgibbs/****************************** Interrupts ************************************/ 31197883Sgibbsvoid ahd_platform_intr(void *); 31297883Sgibbsstatic __inline void ahd_platform_flushwork(struct ahd_softc *ahd); 31397883Sgibbsstatic __inline void 31497883Sgibbsahd_platform_flushwork(struct ahd_softc *ahd) 31597883Sgibbs{ 31697883Sgibbs} 31797883Sgibbs 31897883Sgibbs/************************ Misc Function Declarations **************************/ 31997883Sgibbsvoid ahd_done(struct ahd_softc *ahd, struct scb *scb); 32097883Sgibbsvoid ahd_send_async(struct ahd_softc *, char /*channel*/, 32197883Sgibbs u_int /*target*/, u_int /*lun*/, ac_code, void *arg); 32297883Sgibbs#endif /* _AIC79XX_FREEBSD_H_ */ 323