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 * Copyright (c) 2001-2002 Adaptec Inc. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions, and the following disclaimer, 14 * without modification. 15 * 2. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * Alternatively, this software may be distributed under the terms of the 19 * GNU Public License ("GPL"). 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#23 $ 34 * 35 * $FreeBSD$ 36 */ 37 38 #ifndef _AIC79XX_FREEBSD_H_ 39 #define _AIC79XX_FREEBSD_H_ 40 41 #include "opt_aic79xx.h" /* for config options */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/bus.h> /* For device_t */ 46 #include <sys/endian.h> 47 #include <sys/eventhandler.h> 48 #include <sys/kernel.h> 49 #include <sys/malloc.h> 50 #include <sys/module.h> 51 #include <sys/queue.h> 52 #include <sys/sysctl.h> 53 54 #define AIC_PCI_CONFIG 1 55 #include <machine/bus.h> 56 #include <machine/endian.h> 57 #include <machine/resource.h> 58 59 #include <sys/rman.h> 60 61 #include <dev/pci/pcireg.h> 62 #include <dev/pci/pcivar.h> 63 64 #include <cam/cam.h> 65 #include <cam/cam_ccb.h> 66 #include <cam/cam_debug.h> 67 #include <cam/cam_sim.h> 68 #include <cam/cam_xpt_sim.h> 69 70 #include <cam/scsi/scsi_all.h> 71 #include <cam/scsi/scsi_message.h> 72 #include <cam/scsi/scsi_iu.h> 73 74 /****************************** Platform Macros *******************************/ 75 #define SIM_IS_SCSIBUS_B(ahd, sim) \ 76 (0) 77 #define SIM_CHANNEL(ahd, sim) \ 78 ('A') 79 #define SIM_SCSI_ID(ahd, sim) \ 80 (ahd->our_id) 81 #define SIM_PATH(ahd, sim) \ 82 (ahd->platform_data->path) 83 #define BUILD_SCSIID(ahd, sim, target_id, our_id) \ 84 ((((target_id) << TID_SHIFT) & TID) | (our_id)) 85 86 87 #define SCB_GET_SIM(ahd, scb) \ 88 ((ahd)->platform_data->sim) 89 90 #ifndef offsetof 91 #define offsetof(type, member) ((size_t)(&((type *)0)->member)) 92 #endif 93 94 /************************ Tunable Driver Parameters **************************/ 95 /* 96 * The number of dma segments supported. The sequencer can handle any number 97 * of physically contiguous S/G entrys. To reduce the driver's memory 98 * consumption, we limit the number supported to be sufficient to handle 99 * the largest mapping supported by the legacy kernel MAXPHYS setting of 100 * 128K. This can be increased once some testing is done. Assuming the 101 * transfer is as fragmented as possible and unaligned, this turns out to 102 * be the number of paged sized transfers in MAXPHYS plus an extra element 103 * to handle any unaligned residual. The sequencer fetches SG elements 104 * in cacheline sized chucks, so make the number per-transaction an even 105 * multiple of 16 which should align us on even the largest of cacheline 106 * boundaries. 107 */ 108 #define AHD_MAXPHYS (128 * 1024) 109 #define AHD_NSEG (roundup(btoc(AHD_MAXPHYS) + 1, 16)) 110 111 /* This driver supports target mode */ 112 #ifdef NOT_YET 113 #define AHD_TARGET_MODE 1 114 #endif 115 116 /************************** Softc/SCB Platform Data ***************************/ 117 struct ahd_platform_data { 118 /* 119 * Hooks into the XPT. 120 */ 121 struct cam_sim *sim; 122 struct cam_path *path; 123 124 int regs_res_type[2]; 125 int regs_res_id[2]; 126 int irq_res_type; 127 struct resource *regs[2]; 128 struct resource *irq; 129 void *ih; 130 eventhandler_tag eh; 131 struct proc *recovery_thread; 132 struct mtx mtx; 133 }; 134 135 struct scb_platform_data { 136 }; 137 138 /***************************** Core Includes **********************************/ 139 #ifdef AHD_REG_PRETTY_PRINT 140 #define AIC_DEBUG_REGISTERS 1 141 #else 142 #define AIC_DEBUG_REGISTERS 0 143 #endif 144 #define AIC_CORE_INCLUDE <dev/aic7xxx/aic79xx.h> 145 #define AIC_LIB_PREFIX ahd 146 #define AIC_CONST_PREFIX AHD 147 #include <dev/aic7xxx/aic_osm_lib.h> 148 149 /*************************** Device Access ************************************/ 150 #define ahd_inb(ahd, port) \ 151 bus_space_read_1((ahd)->tags[(port) >> 8], \ 152 (ahd)->bshs[(port) >> 8], (port) & 0xFF) 153 154 #define ahd_outb(ahd, port, value) \ 155 bus_space_write_1((ahd)->tags[(port) >> 8], \ 156 (ahd)->bshs[(port) >> 8], (port) & 0xFF, value) 157 158 #define ahd_inw_atomic(ahd, port) \ 159 aic_le16toh(bus_space_read_2((ahd)->tags[(port) >> 8], \ 160 (ahd)->bshs[(port) >> 8], (port) & 0xFF)) 161 162 #define ahd_outw_atomic(ahd, port, value) \ 163 bus_space_write_2((ahd)->tags[(port) >> 8], \ 164 (ahd)->bshs[(port) >> 8], \ 165 (port & 0xFF), aic_htole16(value)) 166 167 #define ahd_outsb(ahd, port, valp, count) \ 168 bus_space_write_multi_1((ahd)->tags[(port) >> 8], \ 169 (ahd)->bshs[(port) >> 8], \ 170 (port & 0xFF), valp, count) 171 172 #define ahd_insb(ahd, port, valp, count) \ 173 bus_space_read_multi_1((ahd)->tags[(port) >> 8], \ 174 (ahd)->bshs[(port) >> 8], \ 175 (port & 0xFF), valp, count) 176 177 static __inline void ahd_flush_device_writes(struct ahd_softc *); 178 179 static __inline void 180 ahd_flush_device_writes(struct ahd_softc *ahd) 181 { 182 /* XXX Is this sufficient for all architectures??? */ 183 ahd_inb(ahd, INTSTAT); 184 } 185 186 /**************************** Locking Primitives ******************************/ 187 /* Lock protecting internal data structures */ 188 static __inline void ahd_lockinit(struct ahd_softc *); 189 static __inline void ahd_lock(struct ahd_softc *); 190 static __inline void ahd_unlock(struct ahd_softc *); 191 192 static __inline void 193 ahd_lockinit(struct ahd_softc *ahd) 194 { 195 mtx_init(&ahd->platform_data->mtx, "ahd_lock", NULL, MTX_DEF); 196 } 197 198 static __inline void 199 ahd_lock(struct ahd_softc *ahd) 200 { 201 mtx_lock(&ahd->platform_data->mtx); 202 } 203 204 static __inline void 205 ahd_unlock(struct ahd_softc *ahd) 206 { 207 mtx_unlock(&ahd->platform_data->mtx); 208 } 209 210 /********************************** PCI ***************************************/ 211 int ahd_pci_map_registers(struct ahd_softc *ahd); 212 int ahd_pci_map_int(struct ahd_softc *ahd); 213 214 /************************** Transaction Operations ****************************/ 215 static __inline void aic_freeze_simq(struct aic_softc*); 216 static __inline void aic_release_simq(struct aic_softc*); 217 218 static __inline void 219 aic_freeze_simq(struct aic_softc *aic) 220 { 221 xpt_freeze_simq(aic->platform_data->sim, /*count*/1); 222 } 223 224 static __inline void 225 aic_release_simq(struct aic_softc *aic) 226 { 227 xpt_release_simq(aic->platform_data->sim, /*run queue*/TRUE); 228 } 229 /********************************* Debug **************************************/ 230 static __inline void ahd_print_path(struct ahd_softc *, struct scb *); 231 static __inline void ahd_platform_dump_card_state(struct ahd_softc *ahd); 232 233 static __inline void 234 ahd_print_path(struct ahd_softc *ahd, struct scb *scb) 235 { 236 xpt_print_path(scb->io_ctx->ccb_h.path); 237 } 238 239 static __inline void 240 ahd_platform_dump_card_state(struct ahd_softc *ahd) 241 { 242 /* Nothing to do here for FreeBSD */ 243 } 244 /**************************** Transfer Settings *******************************/ 245 void ahd_notify_xfer_settings_change(struct ahd_softc *, 246 struct ahd_devinfo *); 247 void ahd_platform_set_tags(struct ahd_softc *, struct ahd_devinfo *, 248 int /*enable*/); 249 250 /************************* Initialization/Teardown ****************************/ 251 int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); 252 void ahd_platform_free(struct ahd_softc *ahd); 253 int ahd_map_int(struct ahd_softc *ahd); 254 int ahd_attach(struct ahd_softc *); 255 int ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd); 256 void ahd_sysctl(struct ahd_softc *ahd); 257 int ahd_detach(device_t); 258 #define ahd_platform_init(arg) 259 260 261 /****************************** Interrupts ************************************/ 262 void ahd_platform_intr(void *); 263 static __inline void ahd_platform_flushwork(struct ahd_softc *ahd); 264 static __inline void 265 ahd_platform_flushwork(struct ahd_softc *ahd) 266 { 267 } 268 269 /************************ Misc Function Declarations **************************/ 270 void ahd_done(struct ahd_softc *ahd, struct scb *scb); 271 void ahd_send_async(struct ahd_softc *, char /*channel*/, 272 u_int /*target*/, u_int /*lun*/, ac_code, void *arg); 273 #endif /* _AIC79XX_FREEBSD_H_ */ 274