aic79xx_osm.h revision 199260
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 199260 2009-11-13 22:57:20Z attilio $ 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> 54199260Sattilio#include <sys/sysctl.h> 5597883Sgibbs 56123579Sgibbs#define AIC_PCI_CONFIG 1 5797883Sgibbs#include <machine/bus.h> 5897883Sgibbs#include <machine/endian.h> 5997883Sgibbs#include <machine/resource.h> 6097883Sgibbs 6197883Sgibbs#include <sys/rman.h> 6297883Sgibbs 63119277Simp#if __FreeBSD_version >= 500000 64119277Simp#include <dev/pci/pcireg.h> 65119277Simp#include <dev/pci/pcivar.h> 66119277Simp#else 6797883Sgibbs#include <pci/pcireg.h> 6897883Sgibbs#include <pci/pcivar.h> 69119277Simp#endif 7097883Sgibbs 7197883Sgibbs#include <cam/cam.h> 7297883Sgibbs#include <cam/cam_ccb.h> 7397883Sgibbs#include <cam/cam_debug.h> 7497883Sgibbs#include <cam/cam_sim.h> 7597883Sgibbs#include <cam/cam_xpt_sim.h> 7697883Sgibbs 7797883Sgibbs#include <cam/scsi/scsi_all.h> 7897883Sgibbs#include <cam/scsi/scsi_message.h> 7997883Sgibbs#include <cam/scsi/scsi_iu.h> 8097883Sgibbs 8197883Sgibbs/****************************** Platform Macros *******************************/ 8297883Sgibbs#define SIM_IS_SCSIBUS_B(ahd, sim) \ 8397883Sgibbs (0) 8497883Sgibbs#define SIM_CHANNEL(ahd, sim) \ 8597883Sgibbs ('A') 8697883Sgibbs#define SIM_SCSI_ID(ahd, sim) \ 8797883Sgibbs (ahd->our_id) 8897883Sgibbs#define SIM_PATH(ahd, sim) \ 8997883Sgibbs (ahd->platform_data->path) 9097883Sgibbs#define BUILD_SCSIID(ahd, sim, target_id, our_id) \ 9197883Sgibbs ((((target_id) << TID_SHIFT) & TID) | (our_id)) 9297883Sgibbs 9397883Sgibbs 9497883Sgibbs#define SCB_GET_SIM(ahd, scb) \ 9597883Sgibbs ((ahd)->platform_data->sim) 9697883Sgibbs 9797883Sgibbs#ifndef offsetof 9897883Sgibbs#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 9997883Sgibbs#endif 10097883Sgibbs 10197883Sgibbs/************************ Tunable Driver Parameters **************************/ 10297883Sgibbs/* 10397883Sgibbs * The number of dma segments supported. The sequencer can handle any number 10497883Sgibbs * of physically contiguous S/G entrys. To reduce the driver's memory 10597883Sgibbs * consumption, we limit the number supported to be sufficient to handle 106195534Sscottl * the largest mapping supported by the the legacy kernel MAXPHYS setting of 107195534Sscottl * 128K. This can be increased once some testing is done. Assuming the 10897883Sgibbs * transfer is as fragmented as possible and unaligned, this turns out to 10997883Sgibbs * be the number of paged sized transfers in MAXPHYS plus an extra element 11097883Sgibbs * to handle any unaligned residual. The sequencer fetches SG elements 11197883Sgibbs * in cacheline sized chucks, so make the number per-transaction an even 11297883Sgibbs * multiple of 16 which should align us on even the largest of cacheline 11397883Sgibbs * boundaries. 11497883Sgibbs */ 115195534Sscottl#define AHD_MAXPHYS (128 * 1024) 116195534Sscottl#define AHD_NSEG (roundup(btoc(AHD_MAXPHYS) + 1, 16)) 11797883Sgibbs 11897883Sgibbs/* This driver supports target mode */ 119153072Sru#ifdef NOT_YET 12097883Sgibbs#define AHD_TARGET_MODE 1 12197883Sgibbs#endif 12297883Sgibbs 12397883Sgibbs/************************** Softc/SCB Platform Data ***************************/ 12497883Sgibbsstruct ahd_platform_data { 12597883Sgibbs /* 12697883Sgibbs * Hooks into the XPT. 12797883Sgibbs */ 12897883Sgibbs struct cam_sim *sim; 12997883Sgibbs struct cam_path *path; 13097883Sgibbs 13197883Sgibbs int regs_res_type[2]; 13297883Sgibbs int regs_res_id[2]; 13397883Sgibbs int irq_res_type; 13497883Sgibbs struct resource *regs[2]; 13597883Sgibbs struct resource *irq; 13697883Sgibbs void *ih; 13797883Sgibbs eventhandler_tag eh; 138123579Sgibbs struct proc *recovery_thread; 139168807Sscottl struct mtx mtx; 14097883Sgibbs}; 14197883Sgibbs 14297883Sgibbsstruct scb_platform_data { 14397883Sgibbs}; 14497883Sgibbs 14597883Sgibbs/***************************** Core Includes **********************************/ 146153165Sru#ifdef AHD_REG_PRETTY_PRINT 147102685Sgibbs#define AIC_DEBUG_REGISTERS 1 148102685Sgibbs#else 149102685Sgibbs#define AIC_DEBUG_REGISTERS 0 150102685Sgibbs#endif 151123579Sgibbs#define AIC_CORE_INCLUDE <dev/aic7xxx/aic79xx.h> 152123579Sgibbs#define AIC_LIB_PREFIX ahd 153123579Sgibbs#define AIC_CONST_PREFIX AHD 154123579Sgibbs#include <dev/aic7xxx/aic_osm_lib.h> 15597883Sgibbs 15697883Sgibbs/*************************** Device Access ************************************/ 15797883Sgibbs#define ahd_inb(ahd, port) \ 15897883Sgibbs bus_space_read_1((ahd)->tags[(port) >> 8], \ 15997883Sgibbs (ahd)->bshs[(port) >> 8], (port) & 0xFF) 16097883Sgibbs 16197883Sgibbs#define ahd_outb(ahd, port, value) \ 16297883Sgibbs bus_space_write_1((ahd)->tags[(port) >> 8], \ 16397883Sgibbs (ahd)->bshs[(port) >> 8], (port) & 0xFF, value) 16497883Sgibbs 16597883Sgibbs#define ahd_inw_atomic(ahd, port) \ 166123579Sgibbs aic_le16toh(bus_space_read_2((ahd)->tags[(port) >> 8], \ 16797883Sgibbs (ahd)->bshs[(port) >> 8], (port) & 0xFF)) 16897883Sgibbs 16997883Sgibbs#define ahd_outw_atomic(ahd, port, value) \ 17097883Sgibbs bus_space_write_2((ahd)->tags[(port) >> 8], \ 17197883Sgibbs (ahd)->bshs[(port) >> 8], \ 172123579Sgibbs (port & 0xFF), aic_htole16(value)) 17397883Sgibbs 17497883Sgibbs#define ahd_outsb(ahd, port, valp, count) \ 17597883Sgibbs bus_space_write_multi_1((ahd)->tags[(port) >> 8], \ 17697883Sgibbs (ahd)->bshs[(port) >> 8], \ 17797883Sgibbs (port & 0xFF), valp, count) 17897883Sgibbs 17997883Sgibbs#define ahd_insb(ahd, port, valp, count) \ 18097883Sgibbs bus_space_read_multi_1((ahd)->tags[(port) >> 8], \ 18197883Sgibbs (ahd)->bshs[(port) >> 8], \ 18297883Sgibbs (port & 0xFF), valp, count) 18397883Sgibbs 18497883Sgibbsstatic __inline void ahd_flush_device_writes(struct ahd_softc *); 18597883Sgibbs 18697883Sgibbsstatic __inline void 18797883Sgibbsahd_flush_device_writes(struct ahd_softc *ahd) 18897883Sgibbs{ 18997883Sgibbs /* XXX Is this sufficient for all architectures??? */ 19097883Sgibbs ahd_inb(ahd, INTSTAT); 19197883Sgibbs} 19297883Sgibbs 19397883Sgibbs/**************************** Locking Primitives ******************************/ 19497883Sgibbs/* Lock protecting internal data structures */ 19597883Sgibbsstatic __inline void ahd_lockinit(struct ahd_softc *); 196168807Sscottlstatic __inline void ahd_lock(struct ahd_softc *); 197168807Sscottlstatic __inline void ahd_unlock(struct ahd_softc *); 19897883Sgibbs 19997883Sgibbsstatic __inline void 20097883Sgibbsahd_lockinit(struct ahd_softc *ahd) 20197883Sgibbs{ 202168807Sscottl mtx_init(&ahd->platform_data->mtx, "ahd_lock", NULL, MTX_DEF); 20397883Sgibbs} 20497883Sgibbs 20597883Sgibbsstatic __inline void 206168807Sscottlahd_lock(struct ahd_softc *ahd) 20797883Sgibbs{ 208168807Sscottl mtx_lock(&ahd->platform_data->mtx); 20997883Sgibbs} 21097883Sgibbs 21197883Sgibbsstatic __inline void 212168807Sscottlahd_unlock(struct ahd_softc *ahd) 21397883Sgibbs{ 214168807Sscottl mtx_unlock(&ahd->platform_data->mtx); 21597883Sgibbs} 21697883Sgibbs 217123579Sgibbs/********************************** PCI ***************************************/ 218123579Sgibbsint ahd_pci_map_registers(struct ahd_softc *ahd); 219123579Sgibbsint ahd_pci_map_int(struct ahd_softc *ahd); 220123579Sgibbs 22197883Sgibbs/************************** Transaction Operations ****************************/ 222123579Sgibbsstatic __inline void aic_freeze_simq(struct aic_softc*); 223123579Sgibbsstatic __inline void aic_release_simq(struct aic_softc*); 22497883Sgibbs 22597883Sgibbsstatic __inline void 226123579Sgibbsaic_freeze_simq(struct aic_softc *aic) 22797883Sgibbs{ 228123579Sgibbs xpt_freeze_simq(aic->platform_data->sim, /*count*/1); 22997883Sgibbs} 23097883Sgibbs 23197883Sgibbsstatic __inline void 232123579Sgibbsaic_release_simq(struct aic_softc *aic) 23397883Sgibbs{ 234123579Sgibbs xpt_release_simq(aic->platform_data->sim, /*run queue*/TRUE); 23597883Sgibbs} 23697883Sgibbs/********************************* Debug **************************************/ 23797883Sgibbsstatic __inline void ahd_print_path(struct ahd_softc *, struct scb *); 23897883Sgibbsstatic __inline void ahd_platform_dump_card_state(struct ahd_softc *ahd); 23997883Sgibbs 24097883Sgibbsstatic __inline void 24197883Sgibbsahd_print_path(struct ahd_softc *ahd, struct scb *scb) 24297883Sgibbs{ 24397883Sgibbs xpt_print_path(scb->io_ctx->ccb_h.path); 24497883Sgibbs} 24597883Sgibbs 24697883Sgibbsstatic __inline void 24797883Sgibbsahd_platform_dump_card_state(struct ahd_softc *ahd) 24897883Sgibbs{ 24997883Sgibbs /* Nothing to do here for FreeBSD */ 25097883Sgibbs} 25197883Sgibbs/**************************** Transfer Settings *******************************/ 25297883Sgibbsvoid ahd_notify_xfer_settings_change(struct ahd_softc *, 25397883Sgibbs struct ahd_devinfo *); 25497883Sgibbsvoid ahd_platform_set_tags(struct ahd_softc *, struct ahd_devinfo *, 25597883Sgibbs int /*enable*/); 25697883Sgibbs 25797883Sgibbs/************************* Initialization/Teardown ****************************/ 25897883Sgibbsint ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); 25997883Sgibbsvoid ahd_platform_free(struct ahd_softc *ahd); 26097883Sgibbsint ahd_map_int(struct ahd_softc *ahd); 26197883Sgibbsint ahd_attach(struct ahd_softc *); 26297883Sgibbsint ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd); 263199260Sattiliovoid ahd_sysctl(struct ahd_softc *ahd); 26497883Sgibbsint ahd_detach(device_t); 265107437Sscottl#define ahd_platform_init(arg) 26697883Sgibbs 267107437Sscottl 26897883Sgibbs/****************************** Interrupts ************************************/ 26997883Sgibbsvoid ahd_platform_intr(void *); 27097883Sgibbsstatic __inline void ahd_platform_flushwork(struct ahd_softc *ahd); 27197883Sgibbsstatic __inline void 27297883Sgibbsahd_platform_flushwork(struct ahd_softc *ahd) 27397883Sgibbs{ 27497883Sgibbs} 27597883Sgibbs 27697883Sgibbs/************************ Misc Function Declarations **************************/ 27797883Sgibbsvoid ahd_done(struct ahd_softc *ahd, struct scb *scb); 27897883Sgibbsvoid ahd_send_async(struct ahd_softc *, char /*channel*/, 27997883Sgibbs u_int /*target*/, u_int /*lun*/, ac_code, void *arg); 28097883Sgibbs#endif /* _AIC79XX_FREEBSD_H_ */ 281