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