1 /* $NetBSD: mlyvar.h,v 1.5 2008/04/28 20:23:55 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran, Thor Lancelot Simon, and Eric Haszlakiewicz. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 2000, 2001 Michael Smith 34 * Copyright (c) 2000 BSDi 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 * 58 * from FreeBSD: mlyvar.h,v 1.3 2001/07/14 00:12:22 msmith Exp 59 */ 60 61 #ifndef _PCI_MLYVAR_H_ 62 #define _PCI_MLYVAR_H_ 63 64 /* 65 * The firmware interface allows for a 16-bit command identifier. We cap 66 * ourselves at a reasonable limit. Note that we reserve a small number of 67 * CCBs for control operations. 68 */ 69 #define MLY_MAX_CCBS 256 70 #define MLY_CCBS_RESV 4 71 72 /* 73 * The firmware interface allows for a 16-bit s/g list length. We limit 74 * ourselves to a reasonable maximum. 75 */ 76 #define MLY_MAX_SEGS 17 77 #define MLY_SGL_SIZE (MLY_MAX_SEGS * sizeof(struct mly_sg_entry)) 78 79 #define MLY_MAX_XFER ((MLY_MAX_SEGS - 1) * PAGE_SIZE) 80 81 /* 82 * The interval at which we poke the controller for status updates (in 83 * seconds). 84 */ 85 #define MLY_PERIODIC_INTERVAL 5 86 87 /* 88 * Command slot regulation. We can't use slot 0 due to the memory mailbox 89 * implementation. 90 */ 91 #define MLY_SLOT_START 1 92 #define MLY_SLOT_MAX (MLY_SLOT_START + MLY_MAX_CCBS) 93 94 /* 95 * Per-device structure, used to save persistent state on devices. 96 * 97 * Note that this isn't really Bus/Target/Lun since we don't support lun != 98 * 0 at this time. 99 */ 100 struct mly_btl { 101 int mb_flags; 102 int mb_state; /* See 8.1 */ 103 int mb_type; /* See 8.2 */ 104 105 /* Physical devices only. */ 106 int mb_speed; /* Interface transfer rate */ 107 int mb_width; /* Interface width */ 108 }; 109 #define MLY_BTL_PHYSICAL 0x01 /* physical device */ 110 #define MLY_BTL_LOGICAL 0x02 /* logical device */ 111 #define MLY_BTL_PROTECTED 0x04 /* I/O not allowed */ 112 #define MLY_BTL_TQING 0x08 /* tagged queueing */ 113 #define MLY_BTL_SCANNING 0x10 /* scan in progress */ 114 #define MLY_BTL_RESCAN 0x20 /* need to re-scan */ 115 116 /* 117 * Per-command context. 118 */ 119 struct mly_softc; 120 121 struct mly_ccb { 122 union { 123 SLIST_ENTRY(mly_ccb) slist; 124 SIMPLEQ_ENTRY(mly_ccb) simpleq; 125 } mc_link; /* list linkage */ 126 127 u_int mc_slot; /* command slot we occupy */ 128 u_int mc_flags; /* status flags */ 129 u_int mc_status; /* command completion status */ 130 u_int mc_sense; /* sense data length */ 131 int32_t mc_resid; /* I/O residual count */ 132 133 union mly_cmd_packet *mc_packet;/* our controller command */ 134 bus_addr_t mc_packetphys; /* physical address of the mapped packet */ 135 136 void *mc_data; /* data buffer */ 137 size_t mc_length; /* data length */ 138 bus_dmamap_t mc_datamap; /* DMA map for data */ 139 u_int mc_sgoff; /* S/G list offset */ 140 141 void (*mc_complete)(struct mly_softc *, struct mly_ccb *); 142 void *mc_private; 143 }; 144 #define MLY_CCB_DATAIN 0x01 145 #define MLY_CCB_DATAOUT 0x02 146 #define MLY_CCB_MAPPED 0x04 147 #define MLY_CCB_COMPLETE 0x08 148 149 /* 150 * Per-controller context. 151 */ 152 struct mly_softc { 153 /* Generic device info. */ 154 struct device mly_dv; 155 bus_space_handle_t mly_ioh; 156 bus_space_tag_t mly_iot; 157 bus_dma_tag_t mly_dmat; 158 void *mly_ih; 159 160 /* Scatter-gather lists. */ 161 struct mly_sg_entry *mly_sg; 162 bus_addr_t mly_sg_busaddr; 163 bus_dma_tag_t mly_sg_dmat; 164 bus_dmamap_t mly_sg_dmamap; 165 bus_dma_segment_t mly_sg_seg; 166 167 /* Memory mailbox. */ 168 struct mly_mmbox *mly_mmbox; 169 bus_addr_t mly_mmbox_busaddr; 170 bus_dma_tag_t mly_mmbox_dmat; 171 bus_dmamap_t mly_mmbox_dmamap; 172 bus_dma_segment_t mly_mmbox_seg; 173 u_int mly_mmbox_cmd_idx; 174 u_int mly_mmbox_sts_idx; 175 176 /* Command packets. */ 177 union mly_cmd_packet *mly_pkt; 178 bus_addr_t mly_pkt_busaddr; 179 bus_dma_tag_t mly_pkt_dmat; 180 bus_dmamap_t mly_pkt_dmamap; 181 bus_dma_segment_t mly_pkt_seg; 182 183 /* Command management. */ 184 struct mly_ccb *mly_ccbs; 185 SLIST_HEAD(,mly_ccb) mly_ccb_free; 186 SIMPLEQ_HEAD(,mly_ccb) mly_ccb_queue; 187 u_int mly_ncmds; 188 189 /* Controller hardware interface. */ 190 u_int mly_hwif; 191 u_int mly_doorbell_true; 192 u_int mly_cmd_mailbox; 193 u_int mly_status_mailbox; 194 u_int mly_idbr; 195 u_int mly_odbr; 196 u_int mly_error_status; 197 u_int mly_interrupt_status; 198 u_int mly_interrupt_mask; 199 200 /* Controller features, limits and status. */ 201 u_int mly_state; 202 struct mly_ioctl_getcontrollerinfo *mly_controllerinfo; 203 struct mly_param_controller *mly_controllerparam; 204 struct mly_btl mly_btl[MLY_MAX_CHANNELS][MLY_MAX_TARGETS]; 205 206 /* Health monitoring. */ 207 u_int mly_event_change; 208 u_int mly_event_counter; 209 u_int mly_event_waiting; 210 struct lwp *mly_thread; 211 212 /* SCSI mid-layer connection. */ 213 struct scsipi_adapter mly_adapt; 214 struct scsipi_channel mly_chans[MLY_MAX_CHANNELS]; 215 u_int mly_nchans; 216 }; 217 #define MLY_HWIF_I960RX 0 218 #define MLY_HWIF_STRONGARM 1 219 220 #define MLY_STATE_OPEN 0x01 221 #define MLY_STATE_MMBOX_ACTIVE 0x02 222 #define MLY_STATE_INITOK 0x04 223 224 /* 225 * Register access helpers. 226 */ 227 228 static __inline u_int8_t mly_inb(struct mly_softc *, int); 229 static __inline u_int16_t mly_inw(struct mly_softc *, int); 230 static __inline u_int32_t mly_inl(struct mly_softc *, int); 231 static __inline void mly_outb(struct mly_softc *, int, u_int8_t); 232 static __inline void mly_outw(struct mly_softc *, int, u_int16_t); 233 static __inline void mly_outl(struct mly_softc *, int, u_int32_t); 234 static __inline int mly_idbr_true(struct mly_softc *, u_int8_t); 235 static __inline int mly_odbr_true(struct mly_softc *, u_int8_t); 236 static __inline int mly_error_valid(struct mly_softc *); 237 238 static __inline u_int8_t 239 mly_inb(struct mly_softc *mly, int off) 240 { 241 242 bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 1, 243 BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ); 244 return (bus_space_read_1(mly->mly_iot, mly->mly_ioh, off)); 245 } 246 247 static __inline u_int16_t 248 mly_inw(struct mly_softc *mly, int off) 249 { 250 251 bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 2, 252 BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ); 253 return (bus_space_read_2(mly->mly_iot, mly->mly_ioh, off)); 254 } 255 256 static __inline u_int32_t 257 mly_inl(struct mly_softc *mly, int off) 258 { 259 260 bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 4, 261 BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ); 262 return (bus_space_read_4(mly->mly_iot, mly->mly_ioh, off)); 263 } 264 265 static __inline void 266 mly_outb(struct mly_softc *mly, int off, u_int8_t val) 267 { 268 269 bus_space_write_1(mly->mly_iot, mly->mly_ioh, off, val); 270 bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 1, 271 BUS_SPACE_BARRIER_WRITE); 272 } 273 274 static __inline void 275 mly_outw(struct mly_softc *mly, int off, u_int16_t val) 276 { 277 278 bus_space_write_2(mly->mly_iot, mly->mly_ioh, off, val); 279 bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 2, 280 BUS_SPACE_BARRIER_WRITE); 281 } 282 283 static __inline void 284 mly_outl(struct mly_softc *mly, int off, u_int32_t val) 285 { 286 287 bus_space_write_4(mly->mly_iot, mly->mly_ioh, off, val); 288 bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 4, 289 BUS_SPACE_BARRIER_WRITE); 290 } 291 292 static __inline int 293 mly_idbr_true(struct mly_softc *mly, u_int8_t mask) 294 { 295 u_int8_t val; 296 297 val = mly_inb(mly, mly->mly_idbr) ^ mly->mly_doorbell_true; 298 return ((val & mask) == mask); 299 } 300 301 static __inline int 302 mly_odbr_true(struct mly_softc *mly, u_int8_t mask) 303 { 304 305 return ((mly_inb(mly, mly->mly_odbr) & mask) == mask); 306 } 307 308 static __inline int 309 mly_error_valid(struct mly_softc *mly) 310 { 311 u_int8_t val; 312 313 val = mly_inb(mly, mly->mly_error_status) ^ mly->mly_doorbell_true; 314 return ((val & MLY_MSG_EMPTY) == 0); 315 } 316 317 /* 318 * Bus/target/logical ID-related macros. 319 */ 320 321 #define MLY_LOGDEV_ID(mly, bus, target) \ 322 (((bus) - (mly)->mly_controllerinfo->physical_channels_present) * \ 323 MLY_MAX_TARGETS + (target)) 324 325 #define MLY_LOGDEV_BUS(mly, logdev) \ 326 (((logdev) / MLY_MAX_TARGETS) + \ 327 (mly)->mly_controllerinfo->physical_channels_present) 328 329 #define MLY_LOGDEV_TARGET(mly, logdev) \ 330 ((logdev) % MLY_MAX_TARGETS) 331 332 #define MLY_BUS_IS_VIRTUAL(mly, bus) \ 333 ((bus) >= (mly)->mly_controllerinfo->physical_channels_present) 334 335 #define MLY_BUS_IS_VALID(mly, bus) \ 336 (((bus) < (mly)->mly_nchans)) 337 338 #endif /* !defined _PCI_MLYVAR_H_ */ 339