1 1.75 christos /* $NetBSD: sbic.c,v 1.75 2016/03/09 20:11:41 christos Exp $ */ 2 1.6 cgd 3 1.1 chopps /* 4 1.1 chopps * Copyright (c) 1990 The Regents of the University of California. 5 1.1 chopps * All rights reserved. 6 1.1 chopps * 7 1.1 chopps * This code is derived from software contributed to Berkeley by 8 1.1 chopps * Van Jacobson of Lawrence Berkeley Laboratory. 9 1.1 chopps * 10 1.1 chopps * Redistribution and use in source and binary forms, with or without 11 1.1 chopps * modification, are permitted provided that the following conditions 12 1.1 chopps * are met: 13 1.1 chopps * 1. Redistributions of source code must retain the above copyright 14 1.1 chopps * notice, this list of conditions and the following disclaimer. 15 1.1 chopps * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 chopps * notice, this list of conditions and the following disclaimer in the 17 1.1 chopps * documentation and/or other materials provided with the distribution. 18 1.53 agc * 3. Neither the name of the University nor the names of its contributors 19 1.53 agc * may be used to endorse or promote products derived from this software 20 1.53 agc * without specific prior written permission. 21 1.53 agc * 22 1.53 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.53 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.53 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.53 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.53 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.53 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.53 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.53 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.53 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.53 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.53 agc * SUCH DAMAGE. 33 1.53 agc * 34 1.53 agc * @(#)scsi.c 7.5 (Berkeley) 5/4/91 35 1.53 agc */ 36 1.53 agc 37 1.53 agc /* 38 1.53 agc * Copyright (c) 1994 Christian E. Hopps 39 1.53 agc * 40 1.53 agc * This code is derived from software contributed to Berkeley by 41 1.53 agc * Van Jacobson of Lawrence Berkeley Laboratory. 42 1.53 agc * 43 1.53 agc * Redistribution and use in source and binary forms, with or without 44 1.53 agc * modification, are permitted provided that the following conditions 45 1.53 agc * are met: 46 1.53 agc * 1. Redistributions of source code must retain the above copyright 47 1.53 agc * notice, this list of conditions and the following disclaimer. 48 1.53 agc * 2. Redistributions in binary form must reproduce the above copyright 49 1.53 agc * notice, this list of conditions and the following disclaimer in the 50 1.53 agc * documentation and/or other materials provided with the distribution. 51 1.1 chopps * 3. All advertising materials mentioning features or use of this software 52 1.1 chopps * must display the following acknowledgement: 53 1.1 chopps * This product includes software developed by the University of 54 1.1 chopps * California, Berkeley and its contributors. 55 1.1 chopps * 4. Neither the name of the University nor the names of its contributors 56 1.1 chopps * may be used to endorse or promote products derived from this software 57 1.1 chopps * without specific prior written permission. 58 1.1 chopps * 59 1.1 chopps * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 1.1 chopps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 1.1 chopps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 1.1 chopps * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 1.1 chopps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 1.1 chopps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 1.1 chopps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 1.1 chopps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 1.1 chopps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 1.1 chopps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 1.1 chopps * SUCH DAMAGE. 70 1.1 chopps * 71 1.1 chopps * @(#)scsi.c 7.5 (Berkeley) 5/4/91 72 1.1 chopps */ 73 1.1 chopps 74 1.1 chopps /* 75 1.1 chopps * AMIGA AMD 33C93 scsi adaptor driver 76 1.1 chopps */ 77 1.32 jonathan 78 1.32 jonathan #include "opt_ddb.h" 79 1.68 phx #ifdef __m68k__ 80 1.67 mrg #include "opt_m68k_arch.h" 81 1.68 phx #endif 82 1.46 aymeric 83 1.46 aymeric #include <sys/cdefs.h> 84 1.75 christos __KERNEL_RCSID(0, "$NetBSD: sbic.c,v 1.75 2016/03/09 20:11:41 christos Exp $"); 85 1.1 chopps 86 1.1 chopps #include <sys/param.h> 87 1.1 chopps #include <sys/systm.h> 88 1.1 chopps #include <sys/device.h> 89 1.14 chopps #include <sys/kernel.h> /* For hz */ 90 1.10 chopps #include <sys/disklabel.h> 91 1.1 chopps #include <sys/buf.h> 92 1.29 bouyer #include <dev/scsipi/scsi_all.h> 93 1.29 bouyer #include <dev/scsipi/scsipi_all.h> 94 1.29 bouyer #include <dev/scsipi/scsiconf.h> 95 1.1 chopps #include <machine/cpu.h> 96 1.1 chopps #include <amiga/amiga/device.h> 97 1.1 chopps #include <amiga/amiga/custom.h> 98 1.10 chopps #include <amiga/amiga/isr.h> 99 1.1 chopps #include <amiga/dev/dmavar.h> 100 1.1 chopps #include <amiga/dev/sbicreg.h> 101 1.1 chopps #include <amiga/dev/sbicvar.h> 102 1.1 chopps 103 1.14 chopps /* These are for bounce buffers */ 104 1.14 chopps #include <amiga/amiga/cc.h> 105 1.14 chopps #include <amiga/dev/zbusvar.h> 106 1.14 chopps 107 1.14 chopps /* Since I can't find this in any other header files */ 108 1.14 chopps #define SCSI_PHASE(reg) (reg&0x07) 109 1.14 chopps 110 1.1 chopps /* 111 1.1 chopps * SCSI delays 112 1.1 chopps * In u-seconds, primarily for state changes on the SPC. 113 1.1 chopps */ 114 1.1 chopps #define SBIC_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */ 115 1.1 chopps #define SBIC_DATA_WAIT 50000 /* wait per data in/out step */ 116 1.1 chopps #define SBIC_INIT_WAIT 50000 /* wait per step (both) during init */ 117 1.1 chopps 118 1.1 chopps #define SBIC_WAIT(regs, until, timeo) sbicwait(regs, until, timeo, __LINE__) 119 1.1 chopps 120 1.45 aymeric int sbicicmd(struct sbic_softc *, int, int, void *, int, void *, int); 121 1.45 aymeric int sbicgo(struct sbic_softc *, struct scsipi_xfer *); 122 1.45 aymeric int sbicdmaok(struct sbic_softc *, struct scsipi_xfer *); 123 1.45 aymeric int sbicwait(sbic_regmap_t, char, int , int); 124 1.45 aymeric int sbiccheckdmap(void *, u_long, u_long); 125 1.45 aymeric int sbicselectbus(struct sbic_softc *, sbic_regmap_t, u_char, u_char, u_char); 126 1.45 aymeric int sbicxfstart(sbic_regmap_t, int, u_char, int); 127 1.45 aymeric int sbicxfout(sbic_regmap_t regs, int, void *, int); 128 1.45 aymeric int sbicfromscsiperiod(struct sbic_softc *, sbic_regmap_t, int); 129 1.45 aymeric int sbictoscsiperiod(struct sbic_softc *, sbic_regmap_t, int); 130 1.45 aymeric int sbicpoll(struct sbic_softc *); 131 1.45 aymeric int sbicnextstate(struct sbic_softc *, u_char, u_char); 132 1.45 aymeric int sbicmsgin(struct sbic_softc *); 133 1.45 aymeric int sbicxfin(sbic_regmap_t regs, int, void *); 134 1.55 jmc int sbicabort(struct sbic_softc *, sbic_regmap_t, const char *); 135 1.45 aymeric void sbicxfdone(struct sbic_softc *, sbic_regmap_t, int); 136 1.45 aymeric void sbicerror(struct sbic_softc *, sbic_regmap_t, u_char); 137 1.45 aymeric void sbicstart(struct sbic_softc *); 138 1.45 aymeric void sbicreset(struct sbic_softc *); 139 1.45 aymeric void sbic_scsidone(struct sbic_acb *, int); 140 1.45 aymeric void sbic_sched(struct sbic_softc *); 141 1.45 aymeric void sbic_save_ptrs(struct sbic_softc *, sbic_regmap_t,int,int); 142 1.45 aymeric void sbic_load_ptrs(struct sbic_softc *, sbic_regmap_t,int,int); 143 1.23 veego #ifdef DEBUG 144 1.45 aymeric void sbicdumpstate(void); 145 1.45 aymeric void sbic_dump_acb(struct sbic_acb *); 146 1.23 veego #endif 147 1.1 chopps 148 1.1 chopps /* 149 1.1 chopps * Synch xfer parameters, and timing conversions 150 1.1 chopps */ 151 1.1 chopps int sbic_min_period = SBIC_SYN_MIN_PERIOD; /* in cycles = f(ICLK,FSn) */ 152 1.1 chopps int sbic_max_offset = SBIC_SYN_MAX_OFFSET; /* pure number */ 153 1.1 chopps 154 1.1 chopps int sbic_cmd_wait = SBIC_CMD_WAIT; 155 1.1 chopps int sbic_data_wait = SBIC_DATA_WAIT; 156 1.1 chopps int sbic_init_wait = SBIC_INIT_WAIT; 157 1.1 chopps 158 1.1 chopps /* 159 1.1 chopps * was broken before.. now if you want this you get it for all drives 160 1.1 chopps * on sbic controllers. 161 1.1 chopps */ 162 1.20 jtc u_char sbic_inhibit_sync[8]; 163 1.14 chopps int sbic_enable_reselect = 1; 164 1.1 chopps int sbic_clock_override = 0; 165 1.1 chopps int sbic_no_dma = 0; 166 1.14 chopps int sbic_parallel_operations = 1; 167 1.1 chopps 168 1.1 chopps #ifdef DEBUG 169 1.33 is sbic_regmap_t debug_sbic_regs; 170 1.10 chopps int sbicdma_ops = 0; /* total DMA operations */ 171 1.10 chopps int sbicdma_bounces = 0; /* number operations using bounce buffer */ 172 1.10 chopps int sbicdma_hits = 0; /* number of DMA chains that were contiguous */ 173 1.10 chopps int sbicdma_misses = 0; /* number of DMA chains that were not contiguous */ 174 1.14 chopps int sbicdma_saves = 0; 175 1.28 christos #define QPRINTF(a) if (sbic_debug > 1) printf a 176 1.1 chopps int sbic_debug = 0; 177 1.1 chopps int sync_debug = 0; 178 1.1 chopps int sbic_dma_debug = 0; 179 1.14 chopps int reselect_debug = 0; 180 1.14 chopps int data_pointer_debug = 0; 181 1.16 chopps u_char debug_asr, debug_csr, routine; 182 1.45 aymeric void sbictimeout(struct sbic_softc *dev); 183 1.16 chopps 184 1.17 chopps #define CSR_TRACE_SIZE 32 185 1.16 chopps #if CSR_TRACE_SIZE 186 1.16 chopps #define CSR_TRACE(w,c,a,x) do { \ 187 1.58 spz int s_csr_trace = splbio(); \ 188 1.16 chopps csr_trace[csr_traceptr].whr = (w); csr_trace[csr_traceptr].csr = (c); \ 189 1.16 chopps csr_trace[csr_traceptr].asr = (a); csr_trace[csr_traceptr].xtn = (x); \ 190 1.59 christos dma_cachectl((void *)&csr_trace[csr_traceptr], sizeof(csr_trace[0])); \ 191 1.16 chopps csr_traceptr = (csr_traceptr + 1) & (CSR_TRACE_SIZE - 1); \ 192 1.59 christos /* dma_cachectl((void *)&csr_traceptr, sizeof(csr_traceptr));*/ \ 193 1.58 spz splx(s_csr_trace); \ 194 1.16 chopps } while (0) 195 1.16 chopps int csr_traceptr; 196 1.16 chopps int csr_tracesize = CSR_TRACE_SIZE; 197 1.16 chopps struct { 198 1.16 chopps u_char whr; 199 1.16 chopps u_char csr; 200 1.16 chopps u_char asr; 201 1.16 chopps u_char xtn; 202 1.16 chopps } csr_trace[CSR_TRACE_SIZE]; 203 1.16 chopps #else 204 1.23 veego #define CSR_TRACE(w,c,a,x) 205 1.16 chopps #endif 206 1.16 chopps 207 1.16 chopps #define SBIC_TRACE_SIZE 0 208 1.16 chopps #if SBIC_TRACE_SIZE 209 1.16 chopps #define SBIC_TRACE(dev) do { \ 210 1.16 chopps int s = splbio(); \ 211 1.16 chopps sbic_trace[sbic_traceptr].sp = &s; \ 212 1.16 chopps sbic_trace[sbic_traceptr].line = __LINE__; \ 213 1.16 chopps sbic_trace[sbic_traceptr].sr = s; \ 214 1.16 chopps sbic_trace[sbic_traceptr].csr = csr_traceptr; \ 215 1.16 chopps dma_cachectl(&sbic_trace[sbic_traceptr], sizeof(sbic_trace[0])); \ 216 1.16 chopps sbic_traceptr = (sbic_traceptr + 1) & (SBIC_TRACE_SIZE - 1); \ 217 1.16 chopps dma_cachectl(&sbic_traceptr, sizeof(sbic_traceptr)); \ 218 1.16 chopps if (dev) dma_cachectl(dev, sizeof(*dev)); \ 219 1.16 chopps splx(s); \ 220 1.16 chopps } while (0) 221 1.16 chopps int sbic_traceptr; 222 1.16 chopps int sbic_tracesize = SBIC_TRACE_SIZE; 223 1.16 chopps struct { 224 1.16 chopps void *sp; 225 1.16 chopps u_short line; 226 1.16 chopps u_short sr; 227 1.16 chopps int csr; 228 1.16 chopps } sbic_trace[SBIC_TRACE_SIZE]; 229 1.16 chopps #else 230 1.23 veego #define SBIC_TRACE(dev) 231 1.16 chopps #endif 232 1.16 chopps 233 1.23 veego #else /* DEBUG */ 234 1.23 veego #define QPRINTF(a) 235 1.23 veego #define CSR_TRACE(w,c,a,x) 236 1.23 veego #define SBIC_TRACE(dev) 237 1.23 veego #endif /* DEBUG */ 238 1.1 chopps 239 1.1 chopps /* 240 1.1 chopps * default minphys routine for sbic based controllers 241 1.1 chopps */ 242 1.13 mycroft void 243 1.45 aymeric sbic_minphys(struct buf *bp) 244 1.1 chopps { 245 1.13 mycroft 246 1.1 chopps /* 247 1.13 mycroft * No max transfer at this level. 248 1.1 chopps */ 249 1.13 mycroft minphys(bp); 250 1.1 chopps } 251 1.1 chopps 252 1.1 chopps /* 253 1.14 chopps * Save DMA pointers. Take into account partial transfer. Shut down DMA. 254 1.14 chopps */ 255 1.14 chopps void 256 1.45 aymeric sbic_save_ptrs(struct sbic_softc *dev, sbic_regmap_t regs, int target, int lun) 257 1.14 chopps { 258 1.23 veego int count, asr, s; 259 1.14 chopps struct sbic_acb* acb; 260 1.14 chopps 261 1.16 chopps SBIC_TRACE(dev); 262 1.75 christos if (!dev->sc_cur) return; 263 1.75 christos if (!(dev->sc_flags & SBICF_INDMA)) return; /* DMA not active */ 264 1.14 chopps 265 1.14 chopps s = splbio(); 266 1.14 chopps 267 1.14 chopps acb = dev->sc_nexus; 268 1.14 chopps count = -1; 269 1.14 chopps do { 270 1.14 chopps GET_SBIC_asr(regs, asr); 271 1.75 christos if (asr & SBIC_ASR_DBR) { 272 1.28 christos printf("sbic_save_ptrs: asr %02x canceled!\n", asr); 273 1.14 chopps splx(s); 274 1.16 chopps SBIC_TRACE(dev); 275 1.14 chopps return; 276 1.14 chopps } 277 1.75 christos } while (asr & (SBIC_ASR_BSY|SBIC_ASR_CIP)); 278 1.14 chopps 279 1.14 chopps /* Save important state */ 280 1.14 chopps /* must be done before dmastop */ 281 1.14 chopps acb->sc_dmacmd = dev->sc_dmacmd; 282 1.14 chopps SBIC_TC_GET(regs, count); 283 1.14 chopps 284 1.14 chopps /* Shut down DMA ====CAREFUL==== */ 285 1.14 chopps dev->sc_dmastop(dev); 286 1.14 chopps dev->sc_flags &= ~SBICF_INDMA; 287 1.14 chopps SBIC_TC_PUT(regs, 0); 288 1.14 chopps 289 1.14 chopps #ifdef DEBUG 290 1.75 christos if (!count && sbic_debug) printf("%dcount0",target); 291 1.75 christos if (data_pointer_debug == -1) 292 1.28 christos printf("SBIC saving target %d data pointers from (%p,%x)%xASR:%02x", 293 1.14 chopps target, dev->sc_cur->dc_addr, dev->sc_cur->dc_count, 294 1.14 chopps acb->sc_dmacmd, asr); 295 1.14 chopps #endif 296 1.14 chopps 297 1.14 chopps /* Fixup partial xfers */ 298 1.14 chopps acb->sc_kv.dc_addr += (dev->sc_tcnt - count); 299 1.14 chopps acb->sc_kv.dc_count -= (dev->sc_tcnt - count); 300 1.14 chopps acb->sc_pa.dc_addr += (dev->sc_tcnt - count); 301 1.14 chopps acb->sc_pa.dc_count -= ((dev->sc_tcnt - count)>>1); 302 1.14 chopps 303 1.14 chopps acb->sc_tcnt = dev->sc_tcnt = count; 304 1.14 chopps #ifdef DEBUG 305 1.75 christos if (data_pointer_debug) 306 1.28 christos printf(" at (%p,%x):%x\n", 307 1.14 chopps dev->sc_cur->dc_addr, dev->sc_cur->dc_count,count); 308 1.14 chopps sbicdma_saves++; 309 1.14 chopps #endif 310 1.14 chopps splx(s); 311 1.16 chopps SBIC_TRACE(dev); 312 1.14 chopps } 313 1.14 chopps 314 1.14 chopps 315 1.14 chopps /* 316 1.14 chopps * DOES NOT RESTART DMA!!! 317 1.14 chopps */ 318 1.45 aymeric void 319 1.45 aymeric sbic_load_ptrs(struct sbic_softc *dev, sbic_regmap_t regs, int target, int lun) 320 1.14 chopps { 321 1.23 veego int s, count; 322 1.14 chopps char* vaddr, * paddr; 323 1.14 chopps struct sbic_acb *acb; 324 1.14 chopps 325 1.16 chopps SBIC_TRACE(dev); 326 1.14 chopps acb = dev->sc_nexus; 327 1.75 christos if (!acb->sc_kv.dc_count) { 328 1.14 chopps /* No data to xfer */ 329 1.16 chopps SBIC_TRACE(dev); 330 1.14 chopps return; 331 1.16 chopps } 332 1.14 chopps 333 1.14 chopps s = splbio(); 334 1.14 chopps 335 1.14 chopps dev->sc_last = dev->sc_cur = &acb->sc_pa; 336 1.14 chopps dev->sc_tcnt = acb->sc_tcnt; 337 1.14 chopps dev->sc_dmacmd = acb->sc_dmacmd; 338 1.14 chopps 339 1.14 chopps #ifdef DEBUG 340 1.14 chopps sbicdma_ops++; 341 1.14 chopps #endif 342 1.75 christos if (!dev->sc_tcnt) { 343 1.14 chopps /* sc_tcnt == 0 implies end of segment */ 344 1.14 chopps 345 1.14 chopps /* do kvm to pa mappings */ 346 1.14 chopps paddr = acb->sc_pa.dc_addr = 347 1.14 chopps (char *) kvtop(acb->sc_kv.dc_addr); 348 1.14 chopps 349 1.14 chopps vaddr = acb->sc_kv.dc_addr; 350 1.14 chopps count = acb->sc_kv.dc_count; 351 1.75 christos for (count = (PAGE_SIZE - ((int)vaddr & PGOFSET)); 352 1.14 chopps count < acb->sc_kv.dc_count 353 1.14 chopps && (char*)kvtop(vaddr + count + 4) == paddr + count + 4; 354 1.50 thorpej count += PAGE_SIZE); 355 1.14 chopps /* If it's all contiguous... */ 356 1.75 christos if (count > acb->sc_kv.dc_count) { 357 1.14 chopps count = acb->sc_kv.dc_count; 358 1.14 chopps #ifdef DEBUG 359 1.14 chopps sbicdma_hits++; 360 1.14 chopps #endif 361 1.14 chopps } else { 362 1.14 chopps #ifdef DEBUG 363 1.14 chopps sbicdma_misses++; 364 1.14 chopps #endif 365 1.14 chopps } 366 1.14 chopps acb->sc_tcnt = count; 367 1.14 chopps acb->sc_pa.dc_count = count >> 1; 368 1.14 chopps 369 1.14 chopps #ifdef DEBUG 370 1.75 christos if (data_pointer_debug) 371 1.28 christos printf("DMA recalc:kv(%p,%x)pa(%p,%lx)\n", 372 1.14 chopps acb->sc_kv.dc_addr, 373 1.14 chopps acb->sc_kv.dc_count, 374 1.14 chopps acb->sc_pa.dc_addr, 375 1.14 chopps acb->sc_tcnt); 376 1.14 chopps #endif 377 1.14 chopps } 378 1.14 chopps splx(s); 379 1.14 chopps #ifdef DEBUG 380 1.75 christos if (data_pointer_debug) 381 1.28 christos printf("SBIC restoring target %d data pointers at (%p,%x)%x\n", 382 1.14 chopps target, dev->sc_cur->dc_addr, dev->sc_cur->dc_count, 383 1.14 chopps dev->sc_dmacmd); 384 1.14 chopps #endif 385 1.16 chopps SBIC_TRACE(dev); 386 1.14 chopps } 387 1.14 chopps 388 1.14 chopps /* 389 1.1 chopps * used by specific sbic controller 390 1.1 chopps * 391 1.1 chopps * it appears that the higher level code does nothing with LUN's 392 1.1 chopps * so I will too. I could plug it in, however so could they 393 1.29 bouyer * in scsi_scsipi_cmd(). 394 1.1 chopps */ 395 1.43 bouyer void 396 1.45 aymeric sbic_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 397 1.45 aymeric void *arg) 398 1.43 bouyer { 399 1.29 bouyer struct scsipi_xfer *xs; 400 1.43 bouyer struct scsipi_periph *periph; 401 1.14 chopps struct sbic_acb *acb; 402 1.71 chs struct sbic_softc *dev = device_private(chan->chan_adapter->adapt_dev); 403 1.14 chopps int flags, s, stat; 404 1.1 chopps 405 1.43 bouyer switch (req) { 406 1.43 bouyer case ADAPTER_REQ_RUN_XFER: 407 1.43 bouyer xs = arg; 408 1.43 bouyer periph = xs->xs_periph; 409 1.1 chopps 410 1.43 bouyer SBIC_TRACE(dev); 411 1.43 bouyer flags = xs->xs_control; 412 1.13 mycroft 413 1.43 bouyer if (flags & XS_CTL_DATA_UIO) 414 1.43 bouyer panic("sbic: scsi data uio requested"); 415 1.1 chopps 416 1.43 bouyer if (dev->sc_nexus && flags & XS_CTL_POLL) 417 1.43 bouyer panic("sbic_scsipi_request: busy"); 418 1.14 chopps 419 1.43 bouyer s = splbio(); 420 1.43 bouyer acb = dev->free_list.tqh_first; 421 1.43 bouyer if (acb) 422 1.43 bouyer TAILQ_REMOVE(&dev->free_list, acb, chain); 423 1.43 bouyer splx(s); 424 1.14 chopps 425 1.43 bouyer #ifdef DIAGNOSTIC 426 1.43 bouyer if (acb == NULL) { 427 1.43 bouyer scsipi_printaddr(periph); 428 1.43 bouyer printf("unable to allocate acb\n"); 429 1.43 bouyer panic("sbic_scsipi_request"); 430 1.43 bouyer } 431 1.43 bouyer #endif 432 1.43 bouyer acb->flags = ACB_ACTIVE; 433 1.43 bouyer if (flags & XS_CTL_DATA_IN) 434 1.43 bouyer acb->flags |= ACB_DATAIN; 435 1.43 bouyer acb->xs = xs; 436 1.65 cegger memcpy(&acb->cmd, xs->cmd, xs->cmdlen); 437 1.43 bouyer acb->clen = xs->cmdlen; 438 1.43 bouyer acb->sc_kv.dc_addr = xs->data; 439 1.43 bouyer acb->sc_kv.dc_count = xs->datalen; 440 1.43 bouyer acb->pa_addr = xs->data ? (char *)kvtop(xs->data) : 0; /* XXXX check */ 441 1.14 chopps 442 1.43 bouyer if (flags & XS_CTL_POLL) { 443 1.43 bouyer s = splbio(); 444 1.43 bouyer /* 445 1.43 bouyer * This has major side effects - it locks up the machine 446 1.43 bouyer */ 447 1.14 chopps 448 1.43 bouyer dev->sc_flags |= SBICF_ICMD; 449 1.43 bouyer do { 450 1.75 christos while (dev->sc_nexus) 451 1.43 bouyer sbicpoll(dev); 452 1.43 bouyer dev->sc_nexus = acb; 453 1.43 bouyer dev->sc_stat[0] = -1; 454 1.43 bouyer dev->sc_xs = xs; 455 1.43 bouyer dev->target = periph->periph_target; 456 1.43 bouyer dev->lun = periph->periph_lun; 457 1.43 bouyer stat = sbicicmd(dev, dev->target, dev->lun, 458 1.14 chopps &acb->cmd, acb->clen, 459 1.14 chopps acb->sc_kv.dc_addr, acb->sc_kv.dc_count); 460 1.43 bouyer } while (dev->sc_nexus != acb); 461 1.43 bouyer sbic_scsidone(acb, stat); 462 1.14 chopps 463 1.43 bouyer splx(s); 464 1.43 bouyer SBIC_TRACE(dev); 465 1.43 bouyer return; 466 1.43 bouyer } 467 1.43 bouyer 468 1.43 bouyer s = splbio(); 469 1.43 bouyer TAILQ_INSERT_TAIL(&dev->ready_list, acb, chain); 470 1.1 chopps 471 1.43 bouyer if (dev->sc_nexus) { 472 1.43 bouyer splx(s); 473 1.43 bouyer SBIC_TRACE(dev); 474 1.43 bouyer return; 475 1.43 bouyer } 476 1.14 chopps 477 1.43 bouyer /* 478 1.43 bouyer * nothing is active, try to start it now. 479 1.43 bouyer */ 480 1.43 bouyer sbic_sched(dev); 481 1.1 chopps splx(s); 482 1.43 bouyer 483 1.16 chopps SBIC_TRACE(dev); 484 1.35 thorpej /* TODO: add sbic_poll to do XS_CTL_POLL operations */ 485 1.14 chopps #if 0 486 1.43 bouyer if (flags & XS_CTL_POLL) 487 1.43 bouyer return(COMPLETE); 488 1.14 chopps #endif 489 1.43 bouyer return; 490 1.43 bouyer 491 1.43 bouyer case ADAPTER_REQ_GROW_RESOURCES: 492 1.43 bouyer return; 493 1.43 bouyer 494 1.43 bouyer case ADAPTER_REQ_SET_XFER_MODE: 495 1.43 bouyer return; 496 1.43 bouyer } 497 1.1 chopps } 498 1.1 chopps 499 1.1 chopps /* 500 1.14 chopps * attempt to start the next available command 501 1.1 chopps */ 502 1.1 chopps void 503 1.45 aymeric sbic_sched(struct sbic_softc *dev) 504 1.1 chopps { 505 1.29 bouyer struct scsipi_xfer *xs; 506 1.43 bouyer struct scsipi_periph *periph; 507 1.14 chopps struct sbic_acb *acb; 508 1.14 chopps int flags, /*phase,*/ stat, i; 509 1.14 chopps 510 1.16 chopps SBIC_TRACE(dev); 511 1.14 chopps if (dev->sc_nexus) 512 1.14 chopps return; /* a command is current active */ 513 1.14 chopps 514 1.16 chopps SBIC_TRACE(dev); 515 1.14 chopps for (acb = dev->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) { 516 1.43 bouyer periph = acb->xs->xs_periph; 517 1.43 bouyer i = periph->periph_target; 518 1.43 bouyer if (!(dev->sc_tinfo[i].lubusy & (1 << periph->periph_lun))) { 519 1.14 chopps struct sbic_tinfo *ti = &dev->sc_tinfo[i]; 520 1.14 chopps 521 1.14 chopps TAILQ_REMOVE(&dev->ready_list, acb, chain); 522 1.14 chopps dev->sc_nexus = acb; 523 1.43 bouyer ti = &dev->sc_tinfo[periph->periph_target]; 524 1.43 bouyer ti->lubusy |= (1 << periph->periph_lun); 525 1.14 chopps acb->sc_pa.dc_addr = acb->pa_addr; /* XXXX check */ 526 1.14 chopps break; 527 1.14 chopps } 528 1.14 chopps } 529 1.14 chopps 530 1.16 chopps SBIC_TRACE(dev); 531 1.14 chopps if (acb == NULL) 532 1.14 chopps return; /* did not find an available command */ 533 1.1 chopps 534 1.14 chopps dev->sc_xs = xs = acb->xs; 535 1.43 bouyer periph = xs->xs_periph; 536 1.35 thorpej flags = xs->xs_control; 537 1.1 chopps 538 1.35 thorpej if (flags & XS_CTL_RESET) 539 1.1 chopps sbicreset(dev); 540 1.1 chopps 541 1.14 chopps #ifdef DEBUG 542 1.75 christos if (data_pointer_debug > 1) 543 1.43 bouyer printf("sbic_sched(%d,%d)\n", periph->periph_target, 544 1.43 bouyer periph->periph_lun); 545 1.14 chopps #endif 546 1.1 chopps dev->sc_stat[0] = -1; 547 1.43 bouyer dev->target = periph->periph_target; 548 1.43 bouyer dev->lun = periph->periph_lun; 549 1.75 christos if (flags & XS_CTL_POLL || (!sbic_parallel_operations 550 1.37 is && (sbicdmaok(dev, xs) == 0))) 551 1.43 bouyer stat = sbicicmd(dev, periph->periph_target, 552 1.43 bouyer periph->periph_lun, &acb->cmd, 553 1.14 chopps acb->clen, acb->sc_kv.dc_addr, acb->sc_kv.dc_count); 554 1.37 is else if (sbicgo(dev, xs) == 0 && xs->error != XS_SELTIMEOUT) { 555 1.16 chopps SBIC_TRACE(dev); 556 1.1 chopps return; 557 1.16 chopps } else 558 1.1 chopps stat = dev->sc_stat[0]; 559 1.13 mycroft 560 1.14 chopps sbic_scsidone(acb, stat); 561 1.16 chopps SBIC_TRACE(dev); 562 1.1 chopps } 563 1.1 chopps 564 1.1 chopps void 565 1.45 aymeric sbic_scsidone(struct sbic_acb *acb, int stat) 566 1.1 chopps { 567 1.29 bouyer struct scsipi_xfer *xs; 568 1.43 bouyer struct scsipi_periph *periph; 569 1.14 chopps struct sbic_softc *dev; 570 1.23 veego int dosched = 0; 571 1.1 chopps 572 1.14 chopps xs = acb->xs; 573 1.43 bouyer periph = xs->xs_periph; 574 1.71 chs dev = device_private(periph->periph_channel->chan_adapter->adapt_dev); 575 1.16 chopps SBIC_TRACE(dev); 576 1.1 chopps #ifdef DIAGNOSTIC 577 1.14 chopps if (acb == NULL || xs == NULL) { 578 1.28 christos printf("sbic_scsidone -- (%d,%d) no scsi_xfer\n", 579 1.14 chopps dev->target, dev->lun); 580 1.14 chopps #ifdef DDB 581 1.14 chopps Debugger(); 582 1.14 chopps #endif 583 1.14 chopps return; 584 1.14 chopps } 585 1.1 chopps #endif 586 1.43 bouyer 587 1.1 chopps xs->status = stat; 588 1.43 bouyer xs->resid = 0; /* XXXX */ 589 1.14 chopps #ifdef DEBUG 590 1.75 christos if (data_pointer_debug > 1) 591 1.28 christos printf("scsidone: (%d,%d)->(%d,%d)%02x\n", 592 1.43 bouyer periph->periph_target, periph->periph_lun, 593 1.14 chopps dev->target, dev->lun, stat); 594 1.75 christos if (periph->periph_target == 595 1.43 bouyer periph->periph_channel->chan_id) 596 1.14 chopps panic("target == hostid"); 597 1.14 chopps #endif 598 1.14 chopps 599 1.43 bouyer if (xs->error == XS_NOERROR) { 600 1.43 bouyer if (stat == SCSI_CHECK || stat == SCSI_BUSY) 601 1.43 bouyer xs->error = XS_BUSY; 602 1.14 chopps } 603 1.1 chopps 604 1.1 chopps /* 605 1.14 chopps * Remove the ACB from whatever queue it's on. We have to do a bit of 606 1.14 chopps * a hack to figure out which queue it's on. Note that it is *not* 607 1.14 chopps * necessary to cdr down the ready queue, but we must cdr down the 608 1.14 chopps * nexus queue and see if it's there, so we can mark the unit as no 609 1.14 chopps * longer busy. This code is sickening, but it works. 610 1.14 chopps */ 611 1.14 chopps if (acb == dev->sc_nexus) { 612 1.14 chopps dev->sc_nexus = NULL; 613 1.16 chopps dev->sc_xs = NULL; 614 1.43 bouyer dev->sc_tinfo[periph->periph_target].lubusy &= 615 1.43 bouyer ~(1<<periph->periph_lun); 616 1.14 chopps if (dev->ready_list.tqh_first) 617 1.14 chopps dosched = 1; /* start next command */ 618 1.14 chopps } else if (dev->ready_list.tqh_last == &acb->chain.tqe_next) { 619 1.14 chopps TAILQ_REMOVE(&dev->ready_list, acb, chain); 620 1.1 chopps } else { 621 1.14 chopps register struct sbic_acb *acb2; 622 1.14 chopps for (acb2 = dev->nexus_list.tqh_first; acb2; 623 1.16 chopps acb2 = acb2->chain.tqe_next) { 624 1.14 chopps if (acb2 == acb) { 625 1.14 chopps TAILQ_REMOVE(&dev->nexus_list, acb, chain); 626 1.43 bouyer dev->sc_tinfo[periph->periph_target].lubusy 627 1.43 bouyer &= ~(1<<periph->periph_lun); 628 1.14 chopps break; 629 1.14 chopps } 630 1.16 chopps } 631 1.14 chopps if (acb2) 632 1.14 chopps ; 633 1.14 chopps else if (acb->chain.tqe_next) { 634 1.14 chopps TAILQ_REMOVE(&dev->ready_list, acb, chain); 635 1.14 chopps } else { 636 1.28 christos printf("%s: can't find matching acb\n", 637 1.71 chs device_xname(dev->sc_dev)); 638 1.14 chopps #ifdef DDB 639 1.14 chopps Debugger(); 640 1.14 chopps #endif 641 1.14 chopps } 642 1.1 chopps } 643 1.14 chopps /* Put it on the free list. */ 644 1.14 chopps acb->flags = ACB_FREE; 645 1.14 chopps TAILQ_INSERT_HEAD(&dev->free_list, acb, chain); 646 1.1 chopps 647 1.43 bouyer dev->sc_tinfo[periph->periph_target].cmds++; 648 1.1 chopps 649 1.29 bouyer scsipi_done(xs); 650 1.13 mycroft 651 1.14 chopps if (dosched) 652 1.14 chopps sbic_sched(dev); 653 1.16 chopps SBIC_TRACE(dev); 654 1.1 chopps } 655 1.1 chopps 656 1.1 chopps int 657 1.45 aymeric sbicdmaok(struct sbic_softc *dev, struct scsipi_xfer *xs) 658 1.1 chopps { 659 1.37 is if (sbic_no_dma || !xs->datalen || xs->datalen & 0x1 || 660 1.37 is (u_int)xs->data & 0x3) 661 1.1 chopps return(0); 662 1.1 chopps /* 663 1.1 chopps * controller supports dma to any addresses? 664 1.1 chopps */ 665 1.13 mycroft else if ((dev->sc_flags & SBICF_BADDMA) == 0) 666 1.1 chopps return(1); 667 1.1 chopps /* 668 1.51 wiz * this address is ok for DMA? 669 1.1 chopps */ 670 1.1 chopps else if (sbiccheckdmap(xs->data, xs->datalen, dev->sc_dmamask) == 0) 671 1.1 chopps return(1); 672 1.1 chopps /* 673 1.1 chopps * we have a bounce buffer? 674 1.1 chopps */ 675 1.43 bouyer else if (dev->sc_tinfo[xs->xs_periph->periph_target].bounce) 676 1.14 chopps return(1); 677 1.14 chopps /* 678 1.14 chopps * try to get one 679 1.14 chopps */ 680 1.43 bouyer else if ((dev->sc_tinfo[xs->xs_periph->periph_target].bounce 681 1.23 veego = (char *)alloc_z2mem(MAXPHYS))) { 682 1.43 bouyer if (isztwomem(dev->sc_tinfo[xs->xs_periph->periph_target].bounce)) 683 1.28 christos printf("alloc ZII target %d bounce pa 0x%x\n", 684 1.43 bouyer xs->xs_periph->periph_target, 685 1.61 is (unsigned)kvtop(dev->sc_tinfo[xs->xs_periph->periph_target].bounce)); 686 1.43 bouyer else if (dev->sc_tinfo[xs->xs_periph->periph_target].bounce) 687 1.54 christos printf("alloc CHIP target %d bounce pa %p\n", 688 1.43 bouyer xs->xs_periph->periph_target, 689 1.43 bouyer PREP_DMA_MEM(dev->sc_tinfo[xs->xs_periph->periph_target].bounce)); 690 1.1 chopps return(1); 691 1.14 chopps } 692 1.14 chopps 693 1.1 chopps return(0); 694 1.1 chopps } 695 1.1 chopps 696 1.1 chopps 697 1.1 chopps int 698 1.45 aymeric sbicwait(sbic_regmap_t regs, char until, int timeo, int line) 699 1.1 chopps { 700 1.1 chopps u_char val; 701 1.1 chopps int csr; 702 1.1 chopps 703 1.16 chopps SBIC_TRACE((struct sbic_softc *)0); 704 1.1 chopps if (timeo == 0) 705 1.1 chopps timeo = 1000000; /* some large value.. */ 706 1.1 chopps 707 1.1 chopps GET_SBIC_asr(regs,val); 708 1.1 chopps while ((val & until) == 0) { 709 1.1 chopps if (timeo-- == 0) { 710 1.1 chopps GET_SBIC_csr(regs, csr); 711 1.28 christos printf("sbicwait TIMEO @%d with asr=x%x csr=x%x\n", 712 1.1 chopps line, val, csr); 713 1.14 chopps #if defined(DDB) && defined(DEBUG) 714 1.14 chopps Debugger(); 715 1.14 chopps #endif 716 1.14 chopps return(val); /* Maybe I should abort */ 717 1.1 chopps break; 718 1.1 chopps } 719 1.1 chopps DELAY(1); 720 1.1 chopps GET_SBIC_asr(regs,val); 721 1.1 chopps } 722 1.16 chopps SBIC_TRACE((struct sbic_softc *)0); 723 1.1 chopps return(val); 724 1.1 chopps } 725 1.1 chopps 726 1.14 chopps int 727 1.55 jmc sbicabort(struct sbic_softc *dev, sbic_regmap_t regs, const char *where) 728 1.1 chopps { 729 1.1 chopps u_char csr, asr; 730 1.13 mycroft 731 1.16 chopps GET_SBIC_asr(regs, asr); 732 1.1 chopps GET_SBIC_csr(regs, csr); 733 1.1 chopps 734 1.28 christos printf ("%s: abort %s: csr = 0x%02x, asr = 0x%02x\n", 735 1.71 chs device_xname(dev->sc_dev), where, csr, asr); 736 1.1 chopps 737 1.14 chopps 738 1.14 chopps #if 0 739 1.14 chopps /* Clean up running command */ 740 1.14 chopps if (dev->sc_nexus != NULL) { 741 1.14 chopps dev->sc_nexus->xs->error = XS_DRIVER_STUFFUP; 742 1.14 chopps sbic_scsidone(dev->sc_nexus, dev->sc_stat[0]); 743 1.14 chopps } 744 1.14 chopps while (acb = dev->nexus_list.tqh_first) { 745 1.14 chopps acb->xs->error = XS_DRIVER_STUFFUP; 746 1.14 chopps sbic_scsidone(acb, -1 /*acb->stat[0]*/); 747 1.14 chopps } 748 1.14 chopps #endif 749 1.14 chopps 750 1.14 chopps /* Clean up chip itself */ 751 1.1 chopps if (dev->sc_flags & SBICF_SELECTED) { 752 1.75 christos while (asr & SBIC_ASR_DBR) { 753 1.14 chopps /* sbic is jammed w/data. need to clear it */ 754 1.14 chopps /* But we don't know what direction it needs to go */ 755 1.14 chopps GET_SBIC_data(regs, asr); 756 1.28 christos printf("%s: abort %s: clearing data buffer 0x%02x\n", 757 1.71 chs device_xname(dev->sc_dev), where, asr); 758 1.14 chopps GET_SBIC_asr(regs, asr); 759 1.75 christos if (asr & SBIC_ASR_DBR) /* Not the read direction, then */ 760 1.14 chopps SET_SBIC_data(regs, asr); 761 1.14 chopps GET_SBIC_asr(regs, asr); 762 1.14 chopps } 763 1.14 chopps WAIT_CIP(regs); 764 1.71 chs printf("%s: sbicabort - sending ABORT command\n", device_xname(dev->sc_dev)); 765 1.1 chopps SET_SBIC_cmd(regs, SBIC_CMD_ABORT); 766 1.1 chopps WAIT_CIP(regs); 767 1.1 chopps 768 1.1 chopps GET_SBIC_asr(regs, asr); 769 1.1 chopps if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI)) { 770 1.1 chopps /* ok, get more drastic.. */ 771 1.13 mycroft 772 1.71 chs printf("%s: sbicabort - asr %x, trying to reset\n", device_xname(dev->sc_dev), asr); 773 1.14 chopps sbicreset(dev); 774 1.1 chopps dev->sc_flags &= ~SBICF_SELECTED; 775 1.14 chopps return -1; 776 1.1 chopps } 777 1.71 chs printf("%s: sbicabort - sending DISC command\n", device_xname(dev->sc_dev)); 778 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_DISC); 779 1.1 chopps 780 1.1 chopps do { 781 1.16 chopps asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0); 782 1.1 chopps GET_SBIC_csr (regs, csr); 783 1.16 chopps CSR_TRACE('a',csr,asr,0); 784 1.1 chopps } while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) 785 1.1 chopps && (csr != SBIC_CSR_CMD_INVALID)); 786 1.1 chopps 787 1.1 chopps /* lets just hope it worked.. */ 788 1.1 chopps dev->sc_flags &= ~SBICF_SELECTED; 789 1.1 chopps } 790 1.14 chopps return -1; 791 1.1 chopps } 792 1.1 chopps 793 1.14 chopps 794 1.1 chopps /* 795 1.14 chopps * Initialize driver-private structures 796 1.1 chopps */ 797 1.14 chopps 798 1.1 chopps void 799 1.45 aymeric sbicinit(struct sbic_softc *dev) 800 1.1 chopps { 801 1.23 veego u_int i; 802 1.14 chopps struct sbic_acb *acb; 803 1.20 jtc u_int inhibit_sync; 804 1.20 jtc 805 1.20 jtc extern u_long scsi_nosync; 806 1.20 jtc extern int shift_nosync; 807 1.14 chopps 808 1.14 chopps if ((dev->sc_flags & SBICF_ALIVE) == 0) { 809 1.14 chopps TAILQ_INIT(&dev->ready_list); 810 1.14 chopps TAILQ_INIT(&dev->nexus_list); 811 1.14 chopps TAILQ_INIT(&dev->free_list); 812 1.60 ad callout_init(&dev->sc_timo_ch, 0); 813 1.14 chopps dev->sc_nexus = NULL; 814 1.14 chopps dev->sc_xs = NULL; 815 1.14 chopps acb = dev->sc_acb; 816 1.63 cegger memset(acb, 0, sizeof(dev->sc_acb)); 817 1.14 chopps for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) { 818 1.14 chopps TAILQ_INSERT_TAIL(&dev->free_list, acb, chain); 819 1.14 chopps acb++; 820 1.14 chopps } 821 1.63 cegger memset(dev->sc_tinfo, 0, sizeof(dev->sc_tinfo)); 822 1.16 chopps #ifdef DEBUG 823 1.16 chopps /* make sure timeout is really not needed */ 824 1.39 thorpej callout_reset(&dev->sc_timo_ch, 30 * hz, 825 1.39 thorpej (void *)sbictimeout, dev); 826 1.16 chopps #endif 827 1.16 chopps 828 1.14 chopps } else panic("sbic: reinitializing driver!"); 829 1.14 chopps 830 1.14 chopps dev->sc_flags |= SBICF_ALIVE; 831 1.14 chopps dev->sc_flags &= ~SBICF_SELECTED; 832 1.14 chopps 833 1.20 jtc /* initialize inhibit array */ 834 1.20 jtc if (scsi_nosync) { 835 1.20 jtc inhibit_sync = (scsi_nosync >> shift_nosync) & 0xff; 836 1.20 jtc shift_nosync += 8; 837 1.20 jtc #ifdef DEBUG 838 1.20 jtc if (inhibit_sync) 839 1.28 christos printf("%s: Inhibiting synchronous transfer %02x\n", 840 1.71 chs device_xname(dev->sc_dev), inhibit_sync); 841 1.20 jtc #endif 842 1.20 jtc for (i = 0; i < 8; ++i) 843 1.20 jtc if (inhibit_sync & (1 << i)) 844 1.20 jtc sbic_inhibit_sync[i] = 1; 845 1.20 jtc } 846 1.20 jtc 847 1.14 chopps sbicreset(dev); 848 1.1 chopps } 849 1.1 chopps 850 1.1 chopps void 851 1.45 aymeric sbicreset(struct sbic_softc *dev) 852 1.1 chopps { 853 1.33 is sbic_regmap_t regs; 854 1.23 veego u_int my_id, s; 855 1.14 chopps u_char csr; 856 1.23 veego #if 0 857 1.23 veego u_int i; 858 1.14 chopps struct sbic_acb *acb; 859 1.23 veego #endif 860 1.13 mycroft 861 1.33 is regs = dev->sc_sbic; 862 1.14 chopps #if 0 863 1.14 chopps if (dev->sc_flags & SBICF_ALIVE) { 864 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_ABORT); 865 1.14 chopps WAIT_CIP(regs); 866 1.14 chopps } 867 1.14 chopps #else 868 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_ABORT); 869 1.14 chopps WAIT_CIP(regs); 870 1.14 chopps #endif 871 1.1 chopps s = splbio(); 872 1.43 bouyer my_id = dev->sc_channel.chan_id & SBIC_ID_MASK; 873 1.1 chopps 874 1.14 chopps /* Enable advanced mode */ 875 1.1 chopps my_id |= SBIC_ID_EAF /*| SBIC_ID_EHP*/ ; 876 1.1 chopps SET_SBIC_myid(regs, my_id); 877 1.1 chopps 878 1.1 chopps /* 879 1.1 chopps * Disable interrupts (in dmainit) then reset the chip 880 1.1 chopps */ 881 1.1 chopps SET_SBIC_cmd(regs, SBIC_CMD_RESET); 882 1.1 chopps DELAY(25); 883 1.1 chopps SBIC_WAIT(regs, SBIC_ASR_INT, 0); 884 1.1 chopps GET_SBIC_csr(regs, csr); /* clears interrupt also */ 885 1.72 christos __USE(csr); 886 1.1 chopps 887 1.14 chopps if (dev->sc_clkfreq < 110) 888 1.14 chopps my_id |= SBIC_ID_FS_8_10; 889 1.14 chopps else if (dev->sc_clkfreq < 160) 890 1.14 chopps my_id |= SBIC_ID_FS_12_15; 891 1.14 chopps else if (dev->sc_clkfreq < 210) 892 1.14 chopps my_id |= SBIC_ID_FS_16_20; 893 1.14 chopps 894 1.14 chopps SET_SBIC_myid(regs, my_id); 895 1.14 chopps 896 1.1 chopps /* 897 1.1 chopps * Set up various chip parameters 898 1.1 chopps */ 899 1.14 chopps SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI /* | SBIC_CTL_HSP */ 900 1.1 chopps | SBIC_MACHINE_DMA_MODE); 901 1.1 chopps /* 902 1.1 chopps * don't allow (re)selection (SBIC_RID_ES) 903 1.1 chopps * until we can handle target mode!! 904 1.1 chopps */ 905 1.14 chopps SET_SBIC_rselid(regs, SBIC_RID_ER); 906 1.1 chopps SET_SBIC_syn(regs, 0); /* asynch for now */ 907 1.1 chopps 908 1.1 chopps /* 909 1.1 chopps * anything else was zeroed by reset 910 1.1 chopps */ 911 1.1 chopps splx(s); 912 1.1 chopps 913 1.14 chopps #if 0 914 1.14 chopps if ((dev->sc_flags & SBICF_ALIVE) == 0) { 915 1.14 chopps TAILQ_INIT(&dev->ready_list); 916 1.14 chopps TAILQ_INIT(&dev->nexus_list); 917 1.14 chopps TAILQ_INIT(&dev->free_list); 918 1.14 chopps dev->sc_nexus = NULL; 919 1.14 chopps dev->sc_xs = NULL; 920 1.14 chopps acb = dev->sc_acb; 921 1.63 cegger memset(acb, 0, sizeof(dev->sc_acb)); 922 1.14 chopps for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) { 923 1.14 chopps TAILQ_INSERT_TAIL(&dev->free_list, acb, chain); 924 1.14 chopps acb++; 925 1.14 chopps } 926 1.63 cegger memset(dev->sc_tinfo, 0, sizeof(dev->sc_tinfo)); 927 1.14 chopps } else { 928 1.14 chopps if (dev->sc_nexus != NULL) { 929 1.14 chopps dev->sc_nexus->xs->error = XS_DRIVER_STUFFUP; 930 1.14 chopps sbic_scsidone(dev->sc_nexus, dev->sc_stat[0]); 931 1.14 chopps } 932 1.14 chopps while (acb = dev->nexus_list.tqh_first) { 933 1.14 chopps acb->xs->error = XS_DRIVER_STUFFUP; 934 1.14 chopps sbic_scsidone(acb, -1 /*acb->stat[0]*/); 935 1.14 chopps } 936 1.14 chopps } 937 1.14 chopps 938 1.1 chopps dev->sc_flags |= SBICF_ALIVE; 939 1.14 chopps #endif 940 1.1 chopps dev->sc_flags &= ~SBICF_SELECTED; 941 1.1 chopps } 942 1.1 chopps 943 1.1 chopps void 944 1.45 aymeric sbicerror(struct sbic_softc *dev, sbic_regmap_t regs, u_char csr) 945 1.1 chopps { 946 1.29 bouyer struct scsipi_xfer *xs; 947 1.1 chopps 948 1.1 chopps xs = dev->sc_xs; 949 1.1 chopps 950 1.1 chopps #ifdef DIAGNOSTIC 951 1.1 chopps if (xs == NULL) 952 1.1 chopps panic("sbicerror"); 953 1.1 chopps #endif 954 1.35 thorpej if (xs->xs_control & XS_CTL_SILENT) 955 1.1 chopps return; 956 1.1 chopps 957 1.71 chs printf("%s: ", device_xname(dev->sc_dev)); 958 1.28 christos printf("csr == 0x%02x\n", csr); /* XXX */ 959 1.1 chopps } 960 1.1 chopps 961 1.1 chopps /* 962 1.1 chopps * select the bus, return when selected or error. 963 1.1 chopps */ 964 1.1 chopps int 965 1.45 aymeric sbicselectbus(struct sbic_softc *dev, sbic_regmap_t regs, u_char target, 966 1.45 aymeric u_char lun, u_char our_addr) 967 1.1 chopps { 968 1.1 chopps u_char asr, csr, id; 969 1.1 chopps 970 1.16 chopps SBIC_TRACE(dev); 971 1.1 chopps QPRINTF(("sbicselectbus %d\n", target)); 972 1.1 chopps 973 1.13 mycroft /* 974 1.1 chopps * if we're already selected, return (XXXX panic maybe?) 975 1.1 chopps */ 976 1.16 chopps if (dev->sc_flags & SBICF_SELECTED) { 977 1.16 chopps SBIC_TRACE(dev); 978 1.1 chopps return(1); 979 1.16 chopps } 980 1.1 chopps 981 1.1 chopps /* 982 1.1 chopps * issue select 983 1.1 chopps */ 984 1.1 chopps SBIC_TC_PUT(regs, 0); 985 1.1 chopps SET_SBIC_selid(regs, target); 986 1.1 chopps SET_SBIC_timeo(regs, SBIC_TIMEOUT(250,dev->sc_clkfreq)); 987 1.1 chopps 988 1.1 chopps /* 989 1.1 chopps * set sync or async 990 1.1 chopps */ 991 1.1 chopps if (dev->sc_sync[target].state == SYNC_DONE) 992 1.13 mycroft SET_SBIC_syn(regs, SBIC_SYN (dev->sc_sync[target].offset, 993 1.1 chopps dev->sc_sync[target].period)); 994 1.1 chopps else 995 1.1 chopps SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period)); 996 1.13 mycroft 997 1.14 chopps GET_SBIC_asr(regs, asr); 998 1.75 christos if (asr & (SBIC_ASR_INT|SBIC_ASR_BSY)) { 999 1.14 chopps /* This means we got ourselves reselected upon */ 1000 1.28 christos /* printf("sbicselectbus: INT/BSY asr %02x\n", asr);*/ 1001 1.14 chopps #ifdef DDB 1002 1.14 chopps /* Debugger();*/ 1003 1.14 chopps #endif 1004 1.16 chopps SBIC_TRACE(dev); 1005 1.14 chopps return 1; 1006 1.14 chopps } 1007 1.14 chopps 1008 1.1 chopps SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN); 1009 1.1 chopps 1010 1.1 chopps /* 1011 1.44 wiz * wait for select (merged from separate function may need 1012 1.1 chopps * cleanup) 1013 1.1 chopps */ 1014 1.1 chopps WAIT_CIP(regs); 1015 1.1 chopps do { 1016 1.14 chopps asr = SBIC_WAIT(regs, SBIC_ASR_INT | SBIC_ASR_LCI, 0); 1017 1.14 chopps if (asr & SBIC_ASR_LCI) { 1018 1.14 chopps #ifdef DEBUG 1019 1.14 chopps if (reselect_debug) 1020 1.28 christos printf("sbicselectbus: late LCI asr %02x\n", asr); 1021 1.14 chopps #endif 1022 1.16 chopps SBIC_TRACE(dev); 1023 1.14 chopps return 1; 1024 1.14 chopps } 1025 1.1 chopps GET_SBIC_csr (regs, csr); 1026 1.16 chopps CSR_TRACE('s',csr,asr,target); 1027 1.1 chopps QPRINTF(("%02x ", csr)); 1028 1.75 christos if (csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY) { 1029 1.14 chopps #ifdef DEBUG 1030 1.75 christos if (reselect_debug) 1031 1.28 christos printf("sbicselectbus: reselected asr %02x\n", asr); 1032 1.14 chopps #endif 1033 1.15 chopps /* We need to handle this now so we don't lock up later */ 1034 1.15 chopps sbicnextstate(dev, csr, asr); 1035 1.16 chopps SBIC_TRACE(dev); 1036 1.14 chopps return 1; 1037 1.14 chopps } 1038 1.75 christos if (csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN) { 1039 1.14 chopps panic("sbicselectbus: target issued select!"); 1040 1.14 chopps return 1; 1041 1.14 chopps } 1042 1.1 chopps } while (csr != (SBIC_CSR_MIS_2|MESG_OUT_PHASE) 1043 1.1 chopps && csr != (SBIC_CSR_MIS_2|CMD_PHASE) && csr != SBIC_CSR_SEL_TIMEO); 1044 1.1 chopps 1045 1.14 chopps /* Enable (or not) reselection */ 1046 1.75 christos if (!sbic_enable_reselect && dev->nexus_list.tqh_first == NULL) 1047 1.14 chopps SET_SBIC_rselid (regs, 0); 1048 1.14 chopps else 1049 1.14 chopps SET_SBIC_rselid (regs, SBIC_RID_ER); 1050 1.14 chopps 1051 1.14 chopps if (csr == (SBIC_CSR_MIS_2|CMD_PHASE)) { 1052 1.1 chopps dev->sc_flags |= SBICF_SELECTED; /* device ignored ATN */ 1053 1.14 chopps GET_SBIC_selid(regs, id); 1054 1.14 chopps dev->target = id; 1055 1.14 chopps GET_SBIC_tlun(regs,dev->lun); 1056 1.75 christos if (dev->lun & SBIC_TLUN_VALID) 1057 1.14 chopps dev->lun &= SBIC_TLUN_MASK; 1058 1.14 chopps else 1059 1.14 chopps dev->lun = lun; 1060 1.14 chopps } else if (csr == (SBIC_CSR_MIS_2|MESG_OUT_PHASE)) { 1061 1.1 chopps /* 1062 1.1 chopps * Send identify message 1063 1.1 chopps * (SCSI-2 requires an identify msg (?)) 1064 1.1 chopps */ 1065 1.1 chopps GET_SBIC_selid(regs, id); 1066 1.14 chopps dev->target = id; 1067 1.14 chopps GET_SBIC_tlun(regs,dev->lun); 1068 1.75 christos if (dev->lun & SBIC_TLUN_VALID) 1069 1.14 chopps dev->lun &= SBIC_TLUN_MASK; 1070 1.14 chopps else 1071 1.14 chopps dev->lun = lun; 1072 1.13 mycroft /* 1073 1.13 mycroft * handle drives that don't want to be asked 1074 1.1 chopps * whether to go sync at all. 1075 1.1 chopps */ 1076 1.20 jtc if (sbic_inhibit_sync[id] 1077 1.20 jtc && dev->sc_sync[id].state == SYNC_START) { 1078 1.1 chopps #ifdef DEBUG 1079 1.1 chopps if (sync_debug) 1080 1.28 christos printf("Forcing target %d asynchronous.\n", id); 1081 1.1 chopps #endif 1082 1.1 chopps dev->sc_sync[id].offset = 0; 1083 1.1 chopps dev->sc_sync[id].period = sbic_min_period; 1084 1.1 chopps dev->sc_sync[id].state = SYNC_DONE; 1085 1.1 chopps } 1086 1.13 mycroft 1087 1.1 chopps 1088 1.14 chopps if (dev->sc_sync[id].state != SYNC_START){ 1089 1.75 christos if (dev->sc_xs->xs_control & XS_CTL_POLL 1090 1.14 chopps || (dev->sc_flags & SBICF_ICMD) 1091 1.75 christos || !sbic_enable_reselect) 1092 1.14 chopps SEND_BYTE (regs, MSG_IDENTIFY | lun); 1093 1.14 chopps else 1094 1.14 chopps SEND_BYTE (regs, MSG_IDENTIFY_DR | lun); 1095 1.14 chopps } else { 1096 1.1 chopps /* 1097 1.1 chopps * try to initiate a sync transfer. 1098 1.13 mycroft * So compose the sync message we're going 1099 1.1 chopps * to send to the target 1100 1.1 chopps */ 1101 1.1 chopps 1102 1.1 chopps #ifdef DEBUG 1103 1.1 chopps if (sync_debug) 1104 1.28 christos printf("Sending sync request to target %d ... ", 1105 1.1 chopps id); 1106 1.1 chopps #endif 1107 1.1 chopps /* 1108 1.1 chopps * setup scsi message sync message request 1109 1.1 chopps */ 1110 1.7 chopps dev->sc_msg[0] = MSG_IDENTIFY | lun; 1111 1.1 chopps dev->sc_msg[1] = MSG_EXT_MESSAGE; 1112 1.1 chopps dev->sc_msg[2] = 3; 1113 1.1 chopps dev->sc_msg[3] = MSG_SYNC_REQ; 1114 1.1 chopps dev->sc_msg[4] = sbictoscsiperiod(dev, regs, 1115 1.1 chopps sbic_min_period); 1116 1.1 chopps dev->sc_msg[5] = sbic_max_offset; 1117 1.1 chopps 1118 1.1 chopps if (sbicxfstart(regs, 6, MESG_OUT_PHASE, sbic_cmd_wait)) 1119 1.1 chopps sbicxfout(regs, 6, dev->sc_msg, MESG_OUT_PHASE); 1120 1.1 chopps 1121 1.1 chopps dev->sc_sync[id].state = SYNC_SENT; 1122 1.1 chopps #ifdef DEBUG 1123 1.1 chopps if (sync_debug) 1124 1.28 christos printf ("sent\n"); 1125 1.1 chopps #endif 1126 1.1 chopps } 1127 1.1 chopps 1128 1.16 chopps asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0); 1129 1.1 chopps GET_SBIC_csr (regs, csr); 1130 1.16 chopps CSR_TRACE('y',csr,asr,target); 1131 1.1 chopps QPRINTF(("[%02x]", csr)); 1132 1.1 chopps #ifdef DEBUG 1133 1.1 chopps if (sync_debug && dev->sc_sync[id].state == SYNC_SENT) 1134 1.28 christos printf("csr-result of last msgout: 0x%x\n", csr); 1135 1.1 chopps #endif 1136 1.1 chopps 1137 1.1 chopps if (csr != SBIC_CSR_SEL_TIMEO) 1138 1.1 chopps dev->sc_flags |= SBICF_SELECTED; 1139 1.1 chopps } 1140 1.14 chopps if (csr == SBIC_CSR_SEL_TIMEO) 1141 1.14 chopps dev->sc_xs->error = XS_SELTIMEOUT; 1142 1.13 mycroft 1143 1.1 chopps QPRINTF(("\n")); 1144 1.1 chopps 1145 1.16 chopps SBIC_TRACE(dev); 1146 1.1 chopps return(csr == SBIC_CSR_SEL_TIMEO); 1147 1.1 chopps } 1148 1.1 chopps 1149 1.1 chopps int 1150 1.45 aymeric sbicxfstart(sbic_regmap_t regs, int len, u_char phase, int wait) 1151 1.1 chopps { 1152 1.1 chopps u_char id; 1153 1.1 chopps 1154 1.14 chopps switch (phase) { 1155 1.14 chopps case DATA_IN_PHASE: 1156 1.14 chopps case MESG_IN_PHASE: 1157 1.1 chopps GET_SBIC_selid (regs, id); 1158 1.1 chopps id |= SBIC_SID_FROM_SCSI; 1159 1.1 chopps SET_SBIC_selid (regs, id); 1160 1.1 chopps SBIC_TC_PUT (regs, (unsigned)len); 1161 1.14 chopps break; 1162 1.14 chopps case DATA_OUT_PHASE: 1163 1.14 chopps case MESG_OUT_PHASE: 1164 1.14 chopps case CMD_PHASE: 1165 1.14 chopps GET_SBIC_selid (regs, id); 1166 1.14 chopps id &= ~SBIC_SID_FROM_SCSI; 1167 1.14 chopps SET_SBIC_selid (regs, id); 1168 1.1 chopps SBIC_TC_PUT (regs, (unsigned)len); 1169 1.14 chopps break; 1170 1.14 chopps default: 1171 1.1 chopps SBIC_TC_PUT (regs, 0); 1172 1.14 chopps } 1173 1.1 chopps QPRINTF(("sbicxfstart %d, %d, %d\n", len, phase, wait)); 1174 1.1 chopps 1175 1.1 chopps return(1); 1176 1.1 chopps } 1177 1.1 chopps 1178 1.1 chopps int 1179 1.45 aymeric sbicxfout(sbic_regmap_t regs, int len, void *bp, int phase) 1180 1.1 chopps { 1181 1.23 veego u_char orig_csr, asr, *buf; 1182 1.1 chopps int wait; 1183 1.13 mycroft 1184 1.1 chopps buf = bp; 1185 1.1 chopps wait = sbic_data_wait; 1186 1.1 chopps 1187 1.1 chopps QPRINTF(("sbicxfout {%d} %02x %02x %02x %02x %02x " 1188 1.13 mycroft "%02x %02x %02x %02x %02x\n", len, buf[0], buf[1], buf[2], 1189 1.1 chopps buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9])); 1190 1.1 chopps 1191 1.1 chopps GET_SBIC_csr (regs, orig_csr); 1192 1.72 christos __USE(orig_csr); 1193 1.16 chopps CSR_TRACE('>',orig_csr,0,0); 1194 1.1 chopps 1195 1.13 mycroft /* 1196 1.1 chopps * sigh.. WD-PROTO strikes again.. sending the command in one go 1197 1.1 chopps * causes the chip to lock up if talking to certain (misbehaving?) 1198 1.1 chopps * targets. Anyway, this procedure should work for all targets, but 1199 1.1 chopps * it's slightly slower due to the overhead 1200 1.1 chopps */ 1201 1.1 chopps WAIT_CIP (regs); 1202 1.1 chopps SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); 1203 1.1 chopps for (;len > 0; len--) { 1204 1.1 chopps GET_SBIC_asr (regs, asr); 1205 1.1 chopps while ((asr & SBIC_ASR_DBR) == 0) { 1206 1.1 chopps if ((asr & SBIC_ASR_INT) || --wait < 0) { 1207 1.1 chopps #ifdef DEBUG 1208 1.1 chopps if (sbic_debug) 1209 1.28 christos printf("sbicxfout fail: l%d i%x w%d\n", 1210 1.1 chopps len, asr, wait); 1211 1.1 chopps #endif 1212 1.1 chopps return (len); 1213 1.1 chopps } 1214 1.14 chopps /* DELAY(1);*/ 1215 1.1 chopps GET_SBIC_asr (regs, asr); 1216 1.1 chopps } 1217 1.1 chopps 1218 1.1 chopps SET_SBIC_data (regs, *buf); 1219 1.1 chopps buf++; 1220 1.1 chopps } 1221 1.14 chopps SBIC_TC_GET(regs, len); 1222 1.14 chopps QPRINTF(("sbicxfout done %d bytes\n", len)); 1223 1.1 chopps /* 1224 1.1 chopps * this leaves with one csr to be read 1225 1.1 chopps */ 1226 1.1 chopps return(0); 1227 1.1 chopps } 1228 1.1 chopps 1229 1.14 chopps /* returns # bytes left to read */ 1230 1.14 chopps int 1231 1.45 aymeric sbicxfin(sbic_regmap_t regs, int len, void *bp) 1232 1.1 chopps { 1233 1.23 veego int wait; 1234 1.74 phx u_char orig_csr, csr, asr; 1235 1.72 christos u_char *buf; 1236 1.74 phx #ifdef DEBUG 1237 1.74 phx u_char *obp; 1238 1.74 phx #endif 1239 1.13 mycroft 1240 1.1 chopps wait = sbic_data_wait; 1241 1.1 chopps buf = bp; 1242 1.74 phx #ifdef DEBUG 1243 1.74 phx obp = bp; 1244 1.74 phx #endif 1245 1.1 chopps 1246 1.1 chopps GET_SBIC_csr (regs, orig_csr); 1247 1.72 christos __USE(orig_csr); 1248 1.16 chopps CSR_TRACE('<',orig_csr,0,0); 1249 1.1 chopps 1250 1.1 chopps QPRINTF(("sbicxfin %d, csr=%02x\n", len, orig_csr)); 1251 1.1 chopps 1252 1.1 chopps WAIT_CIP (regs); 1253 1.1 chopps SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); 1254 1.1 chopps for (;len > 0; len--) { 1255 1.1 chopps GET_SBIC_asr (regs, asr); 1256 1.75 christos if ((asr & SBIC_ASR_PE)) { 1257 1.14 chopps #ifdef DEBUG 1258 1.28 christos printf("sbicxfin parity error: l%d i%x w%d\n", 1259 1.14 chopps len, asr, wait); 1260 1.14 chopps /* return ((unsigned long)buf - (unsigned long)bp); */ 1261 1.14 chopps #ifdef DDB 1262 1.14 chopps Debugger(); 1263 1.14 chopps #endif 1264 1.14 chopps #endif 1265 1.14 chopps } 1266 1.1 chopps while ((asr & SBIC_ASR_DBR) == 0) { 1267 1.1 chopps if ((asr & SBIC_ASR_INT) || --wait < 0) { 1268 1.1 chopps #ifdef DEBUG 1269 1.14 chopps if (sbic_debug) { 1270 1.14 chopps QPRINTF(("sbicxfin fail:{%d} %02x %02x %02x %02x %02x %02x " 1271 1.14 chopps "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2], 1272 1.14 chopps obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9])); 1273 1.28 christos printf("sbicxfin fail: l%d i%x w%d\n", 1274 1.1 chopps len, asr, wait); 1275 1.14 chopps } 1276 1.1 chopps #endif 1277 1.14 chopps return len; 1278 1.14 chopps } 1279 1.14 chopps 1280 1.70 mrg if (!(asr & SBIC_ASR_BSY)) { 1281 1.14 chopps GET_SBIC_csr(regs, csr); 1282 1.72 christos __USE(csr); 1283 1.16 chopps CSR_TRACE('<',csr,asr,len); 1284 1.14 chopps QPRINTF(("[CSR%02xASR%02x]", csr, asr)); 1285 1.1 chopps } 1286 1.1 chopps 1287 1.14 chopps /* DELAY(1);*/ 1288 1.1 chopps GET_SBIC_asr (regs, asr); 1289 1.1 chopps } 1290 1.1 chopps 1291 1.1 chopps GET_SBIC_data (regs, *buf); 1292 1.14 chopps /* QPRINTF(("asr=%02x, csr=%02x, data=%02x\n", asr, csr, *buf));*/ 1293 1.1 chopps buf++; 1294 1.1 chopps } 1295 1.1 chopps 1296 1.1 chopps QPRINTF(("sbicxfin {%d} %02x %02x %02x %02x %02x %02x " 1297 1.13 mycroft "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2], 1298 1.1 chopps obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9])); 1299 1.1 chopps 1300 1.1 chopps /* this leaves with one csr to be read */ 1301 1.14 chopps return len; 1302 1.1 chopps } 1303 1.1 chopps 1304 1.1 chopps /* 1305 1.1 chopps * SCSI 'immediate' command: issue a command to some SCSI device 1306 1.1 chopps * and get back an 'immediate' response (i.e., do programmed xfer 1307 1.1 chopps * to get the response data). 'cbuf' is a buffer containing a scsi 1308 1.1 chopps * command of length clen bytes. 'buf' is a buffer of length 'len' 1309 1.1 chopps * bytes for data. The transfer direction is determined by the device 1310 1.1 chopps * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 1311 1.14 chopps * command must supply no data. 1312 1.1 chopps */ 1313 1.1 chopps int 1314 1.45 aymeric sbicicmd(struct sbic_softc *dev, int target, int lun, void *cbuf, int clen, 1315 1.45 aymeric void *buf, int len) 1316 1.1 chopps { 1317 1.33 is sbic_regmap_t regs; 1318 1.1 chopps u_char phase, csr, asr; 1319 1.23 veego int wait, i; 1320 1.14 chopps struct sbic_acb *acb; 1321 1.14 chopps 1322 1.14 chopps #define CSR_LOG_BUF_SIZE 0 1323 1.14 chopps #if CSR_LOG_BUF_SIZE 1324 1.14 chopps int bufptr; 1325 1.14 chopps int csrbuf[CSR_LOG_BUF_SIZE]; 1326 1.14 chopps bufptr=0; 1327 1.14 chopps #endif 1328 1.1 chopps 1329 1.16 chopps SBIC_TRACE(dev); 1330 1.33 is regs = dev->sc_sbic; 1331 1.14 chopps acb = dev->sc_nexus; 1332 1.14 chopps 1333 1.14 chopps /* Make sure pointers are OK */ 1334 1.14 chopps dev->sc_last = dev->sc_cur = &acb->sc_pa; 1335 1.14 chopps dev->sc_tcnt = acb->sc_tcnt = 0; 1336 1.14 chopps acb->sc_pa.dc_count = 0; /* No DMA */ 1337 1.14 chopps acb->sc_kv.dc_addr = buf; 1338 1.14 chopps acb->sc_kv.dc_count = len; 1339 1.14 chopps 1340 1.14 chopps #ifdef DEBUG 1341 1.14 chopps routine = 3; 1342 1.14 chopps debug_sbic_regs = regs; /* store this to allow debug calls */ 1343 1.75 christos if (data_pointer_debug > 1) 1344 1.28 christos printf("sbicicmd(%d,%d):%d\n", target, lun, 1345 1.14 chopps acb->sc_kv.dc_count); 1346 1.14 chopps #endif 1347 1.1 chopps 1348 1.13 mycroft /* 1349 1.1 chopps * set the sbic into non-DMA mode 1350 1.1 chopps */ 1351 1.14 chopps SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI /*| SBIC_CTL_HSP*/); 1352 1.1 chopps 1353 1.1 chopps dev->sc_stat[0] = 0xff; 1354 1.1 chopps dev->sc_msg[0] = 0xff; 1355 1.14 chopps i = 1; /* pre-load */ 1356 1.1 chopps 1357 1.14 chopps /* We're stealing the SCSI bus */ 1358 1.14 chopps dev->sc_flags |= SBICF_ICMD; 1359 1.1 chopps 1360 1.14 chopps do { 1361 1.14 chopps /* 1362 1.14 chopps * select the SCSI bus (it's an error if bus isn't free) 1363 1.14 chopps */ 1364 1.75 christos if (!(dev->sc_flags & SBICF_SELECTED) 1365 1.14 chopps && sbicselectbus(dev, regs, target, lun, dev->sc_scsiaddr)) { 1366 1.37 is /* printf("sbicicmd: trying to select busy bus!\n"); */ 1367 1.14 chopps dev->sc_flags &= ~SBICF_ICMD; 1368 1.1 chopps return(-1); 1369 1.14 chopps } 1370 1.1 chopps 1371 1.1 chopps /* 1372 1.14 chopps * Wait for a phase change (or error) then let the device sequence 1373 1.14 chopps * us through the various SCSI phases. 1374 1.1 chopps */ 1375 1.14 chopps 1376 1.14 chopps wait = sbic_cmd_wait; 1377 1.14 chopps 1378 1.48 thorpej GET_SBIC_asr (regs, asr); 1379 1.14 chopps GET_SBIC_csr (regs, csr); 1380 1.16 chopps CSR_TRACE('I',csr,asr,target); 1381 1.14 chopps QPRINTF((">ASR:%02xCSR:%02x<", asr, csr)); 1382 1.14 chopps 1383 1.14 chopps #if CSR_LOG_BUF_SIZE 1384 1.14 chopps csrbuf[bufptr++] = csr; 1385 1.14 chopps #endif 1386 1.14 chopps 1387 1.14 chopps 1388 1.14 chopps switch (csr) { 1389 1.14 chopps case SBIC_CSR_S_XFERRED: 1390 1.14 chopps case SBIC_CSR_DISC: 1391 1.14 chopps case SBIC_CSR_DISC_1: 1392 1.14 chopps dev->sc_flags &= ~SBICF_SELECTED; 1393 1.14 chopps GET_SBIC_cmd_phase (regs, phase); 1394 1.14 chopps if (phase == 0x60) { 1395 1.14 chopps GET_SBIC_tlun (regs, dev->sc_stat[0]); 1396 1.14 chopps i = 0; /* done */ 1397 1.23 veego /* break; */ /* Bypass all the state gobldygook */ 1398 1.14 chopps } else { 1399 1.1 chopps #ifdef DEBUG 1400 1.75 christos if (reselect_debug>1) 1401 1.28 christos printf("sbicicmd: handling disconnect\n"); 1402 1.1 chopps #endif 1403 1.14 chopps i = SBIC_STATE_DISCONNECT; 1404 1.14 chopps } 1405 1.14 chopps break; 1406 1.1 chopps 1407 1.14 chopps case SBIC_CSR_XFERRED|CMD_PHASE: 1408 1.14 chopps case SBIC_CSR_MIS|CMD_PHASE: 1409 1.14 chopps case SBIC_CSR_MIS_1|CMD_PHASE: 1410 1.14 chopps case SBIC_CSR_MIS_2|CMD_PHASE: 1411 1.14 chopps if (sbicxfstart(regs, clen, CMD_PHASE, sbic_cmd_wait)) 1412 1.14 chopps if (sbicxfout(regs, clen, 1413 1.14 chopps cbuf, CMD_PHASE)) 1414 1.55 jmc i = sbicabort(dev, regs, "icmd sending cmd"); 1415 1.14 chopps #if 0 1416 1.14 chopps GET_SBIC_csr(regs, csr); /* Lets us reload tcount */ 1417 1.1 chopps WAIT_CIP(regs); 1418 1.14 chopps GET_SBIC_asr(regs, asr); 1419 1.16 chopps CSR_TRACE('I',csr,asr,target); 1420 1.75 christos if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI|SBIC_ASR_CIP)) 1421 1.28 christos printf("next: cmd sent asr %02x, csr %02x\n", 1422 1.14 chopps asr, csr); 1423 1.14 chopps #endif 1424 1.14 chopps break; 1425 1.14 chopps 1426 1.14 chopps #if 0 1427 1.14 chopps case SBIC_CSR_XFERRED|DATA_OUT_PHASE: 1428 1.14 chopps case SBIC_CSR_XFERRED|DATA_IN_PHASE: 1429 1.14 chopps case SBIC_CSR_MIS|DATA_OUT_PHASE: 1430 1.14 chopps case SBIC_CSR_MIS|DATA_IN_PHASE: 1431 1.14 chopps case SBIC_CSR_MIS_1|DATA_OUT_PHASE: 1432 1.14 chopps case SBIC_CSR_MIS_1|DATA_IN_PHASE: 1433 1.14 chopps case SBIC_CSR_MIS_2|DATA_OUT_PHASE: 1434 1.14 chopps case SBIC_CSR_MIS_2|DATA_IN_PHASE: 1435 1.14 chopps if (acb->sc_kv.dc_count <= 0) 1436 1.14 chopps i = sbicabort(dev, regs, "icmd out of data"); 1437 1.14 chopps else { 1438 1.14 chopps wait = sbic_data_wait; 1439 1.14 chopps if (sbicxfstart(regs, 1440 1.14 chopps acb->sc_kv.dc_count, 1441 1.14 chopps SBIC_PHASE(csr), wait)) 1442 1.14 chopps if (csr & 0x01) 1443 1.14 chopps /* data in? */ 1444 1.14 chopps i=sbicxfin(regs, 1445 1.14 chopps acb->sc_kv.dc_count, 1446 1.14 chopps acb->sc_kv.dc_addr); 1447 1.14 chopps else 1448 1.14 chopps i=sbicxfout(regs, 1449 1.14 chopps acb->sc_kv.dc_count, 1450 1.14 chopps acb->sc_kv.dc_addr, 1451 1.14 chopps SBIC_PHASE(csr)); 1452 1.14 chopps acb->sc_kv.dc_addr += 1453 1.14 chopps (acb->sc_kv.dc_count - i); 1454 1.14 chopps acb->sc_kv.dc_count = i; 1455 1.14 chopps i = 1; 1456 1.14 chopps } 1457 1.14 chopps break; 1458 1.14 chopps 1459 1.1 chopps #endif 1460 1.14 chopps case SBIC_CSR_XFERRED|STATUS_PHASE: 1461 1.14 chopps case SBIC_CSR_MIS|STATUS_PHASE: 1462 1.14 chopps case SBIC_CSR_MIS_1|STATUS_PHASE: 1463 1.14 chopps case SBIC_CSR_MIS_2|STATUS_PHASE: 1464 1.1 chopps /* 1465 1.14 chopps * the sbic does the status/cmd-complete reading ok, 1466 1.14 chopps * so do this with its hi-level commands. 1467 1.1 chopps */ 1468 1.14 chopps #ifdef DEBUG 1469 1.75 christos if (sbic_debug) 1470 1.28 christos printf("SBICICMD status phase\n"); 1471 1.14 chopps #endif 1472 1.14 chopps SBIC_TC_PUT(regs, 0); 1473 1.14 chopps SET_SBIC_cmd_phase(regs, 0x46); 1474 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER); 1475 1.14 chopps break; 1476 1.1 chopps 1477 1.14 chopps #if THIS_IS_A_RESERVED_STATE 1478 1.14 chopps case BUS_FREE_PHASE: /* This is not legal */ 1479 1.75 christos if (dev->sc_stat[0] != 0xff) 1480 1.14 chopps goto out; 1481 1.14 chopps break; 1482 1.1 chopps #endif 1483 1.1 chopps 1484 1.14 chopps default: 1485 1.14 chopps i = sbicnextstate(dev, csr, asr); 1486 1.14 chopps } 1487 1.14 chopps 1488 1.14 chopps /* 1489 1.14 chopps * make sure the last command was taken, 1490 1.14 chopps * ie. we're not hunting after an ignored command.. 1491 1.14 chopps */ 1492 1.14 chopps GET_SBIC_asr(regs, asr); 1493 1.14 chopps 1494 1.14 chopps /* tapes may take a loooong time.. */ 1495 1.14 chopps while (asr & SBIC_ASR_BSY){ 1496 1.75 christos if (asr & SBIC_ASR_DBR) { 1497 1.28 christos printf("sbicicmd: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n", 1498 1.14 chopps csr,asr); 1499 1.14 chopps #ifdef DDB 1500 1.14 chopps Debugger(); 1501 1.14 chopps #endif 1502 1.14 chopps /* SBIC is jammed */ 1503 1.14 chopps /* DUNNO which direction */ 1504 1.14 chopps /* Try old direction */ 1505 1.14 chopps GET_SBIC_data(regs,i); 1506 1.14 chopps GET_SBIC_asr(regs, asr); 1507 1.75 christos if (asr & SBIC_ASR_DBR) /* Wants us to write */ 1508 1.14 chopps SET_SBIC_data(regs,i); 1509 1.1 chopps } 1510 1.14 chopps GET_SBIC_asr(regs, asr); 1511 1.1 chopps } 1512 1.1 chopps 1513 1.1 chopps /* 1514 1.14 chopps * wait for last command to complete 1515 1.1 chopps */ 1516 1.14 chopps if (asr & SBIC_ASR_LCI) { 1517 1.28 christos printf("sbicicmd: last command ignored\n"); 1518 1.14 chopps } 1519 1.75 christos else if (i == 1) /* Bsy */ 1520 1.14 chopps SBIC_WAIT (regs, SBIC_ASR_INT, wait); 1521 1.14 chopps 1522 1.13 mycroft /* 1523 1.14 chopps * do it again 1524 1.1 chopps */ 1525 1.75 christos } while (i > 0 && dev->sc_stat[0] == 0xff); 1526 1.1 chopps 1527 1.14 chopps /* Sometimes we need to do an extra read of the CSR */ 1528 1.14 chopps GET_SBIC_csr(regs, csr); 1529 1.16 chopps CSR_TRACE('I',csr,asr,0xff); 1530 1.1 chopps 1531 1.14 chopps #if CSR_LOG_BUF_SIZE 1532 1.75 christos if (reselect_debug>1) 1533 1.75 christos for (i=0; i<bufptr; i++) 1534 1.28 christos printf("CSR:%02x", csrbuf[i]); 1535 1.14 chopps #endif 1536 1.1 chopps 1537 1.14 chopps #ifdef DEBUG 1538 1.75 christos if (data_pointer_debug > 1) 1539 1.28 christos printf("sbicicmd done(%d,%d):%d =%d=\n", 1540 1.14 chopps dev->target, lun, 1541 1.14 chopps acb->sc_kv.dc_count, 1542 1.14 chopps dev->sc_stat[0]); 1543 1.14 chopps #endif 1544 1.1 chopps 1545 1.1 chopps QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 1546 1.14 chopps dev->sc_flags &= ~SBICF_ICMD; 1547 1.14 chopps 1548 1.16 chopps SBIC_TRACE(dev); 1549 1.1 chopps return(dev->sc_stat[0]); 1550 1.1 chopps } 1551 1.1 chopps 1552 1.1 chopps /* 1553 1.1 chopps * Finish SCSI xfer command: After the completion interrupt from 1554 1.1 chopps * a read/write operation, sequence through the final phases in 1555 1.1 chopps * programmed i/o. This routine is a lot like sbicicmd except we 1556 1.1 chopps * skip (and don't allow) the select, cmd out and data in/out phases. 1557 1.1 chopps */ 1558 1.1 chopps void 1559 1.45 aymeric sbicxfdone(struct sbic_softc *dev, sbic_regmap_t regs, int target) 1560 1.1 chopps { 1561 1.16 chopps u_char phase, asr, csr; 1562 1.1 chopps int s; 1563 1.1 chopps 1564 1.16 chopps SBIC_TRACE(dev); 1565 1.1 chopps QPRINTF(("{")); 1566 1.1 chopps s = splbio(); 1567 1.1 chopps 1568 1.1 chopps /* 1569 1.1 chopps * have the sbic complete on its own 1570 1.1 chopps */ 1571 1.1 chopps SBIC_TC_PUT(regs, 0); 1572 1.1 chopps SET_SBIC_cmd_phase(regs, 0x46); 1573 1.1 chopps SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER); 1574 1.1 chopps 1575 1.1 chopps do { 1576 1.16 chopps asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0); 1577 1.72 christos __USE(asr); 1578 1.1 chopps GET_SBIC_csr (regs, csr); 1579 1.16 chopps CSR_TRACE('f',csr,asr,target); 1580 1.1 chopps QPRINTF(("%02x:", csr)); 1581 1.1 chopps } while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) 1582 1.1 chopps && (csr != SBIC_CSR_S_XFERRED)); 1583 1.1 chopps 1584 1.1 chopps dev->sc_flags &= ~SBICF_SELECTED; 1585 1.1 chopps 1586 1.1 chopps GET_SBIC_cmd_phase (regs, phase); 1587 1.1 chopps QPRINTF(("}%02x", phase)); 1588 1.1 chopps if (phase == 0x60) 1589 1.1 chopps GET_SBIC_tlun(regs, dev->sc_stat[0]); 1590 1.1 chopps else 1591 1.1 chopps sbicerror(dev, regs, csr); 1592 1.1 chopps 1593 1.1 chopps QPRINTF(("=STS:%02x=\n", dev->sc_stat[0])); 1594 1.1 chopps splx(s); 1595 1.16 chopps SBIC_TRACE(dev); 1596 1.1 chopps } 1597 1.1 chopps 1598 1.14 chopps /* 1599 1.14 chopps * No DMA chains 1600 1.14 chopps */ 1601 1.14 chopps 1602 1.1 chopps int 1603 1.45 aymeric sbicgo(struct sbic_softc *dev, struct scsipi_xfer *xs) 1604 1.1 chopps { 1605 1.23 veego int i, dmaflags, count, usedma; 1606 1.23 veego u_char csr, asr, *addr; 1607 1.33 is sbic_regmap_t regs; 1608 1.14 chopps struct sbic_acb *acb; 1609 1.1 chopps 1610 1.16 chopps SBIC_TRACE(dev); 1611 1.43 bouyer dev->target = xs->xs_periph->periph_target; 1612 1.43 bouyer dev->lun = xs->xs_periph->periph_lun; 1613 1.14 chopps acb = dev->sc_nexus; 1614 1.33 is regs = dev->sc_sbic; 1615 1.14 chopps 1616 1.14 chopps usedma = sbicdmaok(dev, xs); 1617 1.14 chopps #ifdef DEBUG 1618 1.14 chopps routine = 1; 1619 1.14 chopps debug_sbic_regs = regs; /* store this to allow debug calls */ 1620 1.75 christos if (data_pointer_debug > 1) 1621 1.28 christos printf("sbicgo(%d,%d)\n", dev->target, dev->lun); 1622 1.14 chopps #endif 1623 1.1 chopps 1624 1.1 chopps /* 1625 1.1 chopps * set the sbic into DMA mode 1626 1.1 chopps */ 1627 1.75 christos if (usedma) 1628 1.14 chopps SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI | 1629 1.14 chopps SBIC_MACHINE_DMA_MODE); 1630 1.14 chopps else 1631 1.14 chopps SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI); 1632 1.14 chopps 1633 1.1 chopps 1634 1.1 chopps /* 1635 1.1 chopps * select the SCSI bus (it's an error if bus isn't free) 1636 1.1 chopps */ 1637 1.14 chopps if (sbicselectbus(dev, regs, dev->target, dev->lun, 1638 1.7 chopps dev->sc_scsiaddr)) { 1639 1.37 is /* printf("sbicgo: Trying to select busy bus!\n"); */ 1640 1.16 chopps SBIC_TRACE(dev); 1641 1.14 chopps return(0); /* Not done: needs to be rescheduled */ 1642 1.1 chopps } 1643 1.14 chopps dev->sc_stat[0] = 0xff; 1644 1.1 chopps 1645 1.1 chopps /* 1646 1.14 chopps * Calculate DMA chains now 1647 1.1 chopps */ 1648 1.1 chopps 1649 1.14 chopps dmaflags = 0; 1650 1.14 chopps if (acb->flags & ACB_DATAIN) 1651 1.14 chopps dmaflags |= DMAGO_READ; 1652 1.1 chopps 1653 1.1 chopps 1654 1.1 chopps /* 1655 1.14 chopps * Deal w/bounce buffers. 1656 1.1 chopps */ 1657 1.1 chopps 1658 1.14 chopps addr = acb->sc_kv.dc_addr; 1659 1.14 chopps count = acb->sc_kv.dc_count; 1660 1.14 chopps if (count && (char *)kvtop(addr) != acb->sc_pa.dc_addr) { /* XXXX check */ 1661 1.28 christos printf("sbic: DMA buffer mapping changed %p->%x\n", 1662 1.61 is acb->sc_pa.dc_addr, (unsigned)kvtop(addr)); 1663 1.14 chopps #ifdef DDB 1664 1.14 chopps Debugger(); 1665 1.14 chopps #endif 1666 1.1 chopps } 1667 1.1 chopps 1668 1.10 chopps #ifdef DEBUG 1669 1.10 chopps ++sbicdma_ops; /* count total DMA operations */ 1670 1.10 chopps #endif 1671 1.14 chopps if (count && usedma && dev->sc_flags & SBICF_BADDMA && 1672 1.1 chopps sbiccheckdmap(addr, count, dev->sc_dmamask)) { 1673 1.1 chopps /* 1674 1.51 wiz * need to bounce the DMA. 1675 1.1 chopps */ 1676 1.1 chopps if (dmaflags & DMAGO_READ) { 1677 1.14 chopps acb->flags |= ACB_BBUF; 1678 1.14 chopps acb->sc_dmausrbuf = addr; 1679 1.14 chopps acb->sc_dmausrlen = count; 1680 1.14 chopps acb->sc_usrbufpa = (u_char *)kvtop(addr); 1681 1.75 christos if (!dev->sc_tinfo[dev->target].bounce) { 1682 1.28 christos printf("sbicgo: HELP! no bounce allocated for %d\n", 1683 1.14 chopps dev->target); 1684 1.28 christos printf("xfer: (%p->%p,%lx)\n", acb->sc_dmausrbuf, 1685 1.14 chopps acb->sc_usrbufpa, acb->sc_dmausrlen); 1686 1.43 bouyer dev->sc_tinfo[xs->xs_periph->periph_target].bounce 1687 1.14 chopps = (char *)alloc_z2mem(MAXPHYS); 1688 1.43 bouyer if (isztwomem(dev->sc_tinfo[xs->xs_periph->periph_target].bounce)) 1689 1.28 christos printf("alloc ZII target %d bounce pa 0x%x\n", 1690 1.43 bouyer xs->xs_periph->periph_target, 1691 1.61 is (unsigned)kvtop(dev->sc_tinfo[xs->xs_periph->periph_target].bounce)); 1692 1.43 bouyer else if (dev->sc_tinfo[xs->xs_periph->periph_target].bounce) 1693 1.54 christos printf("alloc CHIP target %d bounce pa %p\n", 1694 1.43 bouyer xs->xs_periph->periph_target, 1695 1.43 bouyer PREP_DMA_MEM(dev->sc_tinfo[xs->xs_periph->periph_target].bounce)); 1696 1.14 chopps 1697 1.28 christos printf("Allocating %d bounce at %x\n", 1698 1.14 chopps dev->target, 1699 1.61 is (unsigned)kvtop(dev->sc_tinfo[dev->target].bounce)); 1700 1.14 chopps } 1701 1.51 wiz } else { /* write: copy to DMA buffer */ 1702 1.14 chopps #ifdef DEBUG 1703 1.75 christos if (data_pointer_debug) 1704 1.28 christos printf("sbicgo: copying %x bytes to target %d bounce %x\n", 1705 1.14 chopps count, dev->target, 1706 1.61 is (unsigned)kvtop(dev->sc_tinfo[dev->target].bounce)); 1707 1.14 chopps #endif 1708 1.14 chopps bcopy (addr, dev->sc_tinfo[dev->target].bounce, count); 1709 1.1 chopps } 1710 1.51 wiz addr = dev->sc_tinfo[dev->target].bounce;/* and use DMA buffer */ 1711 1.14 chopps acb->sc_kv.dc_addr = addr; 1712 1.10 chopps #ifdef DEBUG 1713 1.10 chopps ++sbicdma_bounces; /* count number of bounced */ 1714 1.10 chopps #endif 1715 1.1 chopps } 1716 1.1 chopps 1717 1.14 chopps /* 1718 1.14 chopps * Allocate the DMA chain 1719 1.14 chopps */ 1720 1.14 chopps 1721 1.14 chopps /* Set start KVM addresses */ 1722 1.14 chopps #if 0 1723 1.14 chopps acb->sc_kv.dc_addr = addr; 1724 1.14 chopps acb->sc_kv.dc_count = count; 1725 1.10 chopps #endif 1726 1.1 chopps 1727 1.14 chopps /* Mark end of segment */ 1728 1.14 chopps acb->sc_tcnt = dev->sc_tcnt = 0; 1729 1.14 chopps acb->sc_pa.dc_count = 0; 1730 1.14 chopps 1731 1.14 chopps sbic_load_ptrs(dev, regs, dev->target, dev->lun); 1732 1.16 chopps SBIC_TRACE(dev); 1733 1.14 chopps /* Enable interrupts but don't do any DMA */ 1734 1.16 chopps dev->sc_enintr(dev); 1735 1.16 chopps if (usedma) { 1736 1.16 chopps dev->sc_tcnt = dev->sc_dmago(dev, acb->sc_pa.dc_addr, 1737 1.16 chopps acb->sc_pa.dc_count, 1738 1.16 chopps dmaflags); 1739 1.16 chopps #ifdef DEBUG 1740 1.19 chopps dev->sc_dmatimo = dev->sc_tcnt ? 1 : 0; 1741 1.16 chopps #endif 1742 1.16 chopps } else 1743 1.16 chopps dev->sc_dmacmd = 0; /* Don't use DMA */ 1744 1.14 chopps dev->sc_flags |= SBICF_INDMA; 1745 1.23 veego /* SBIC_TC_PUT(regs, dev->sc_tcnt); */ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ 1746 1.16 chopps SBIC_TRACE(dev); 1747 1.14 chopps sbic_save_ptrs(dev, regs, dev->target, dev->lun); 1748 1.14 chopps 1749 1.14 chopps /* 1750 1.75 christos * push the data cache (I think this won't work (EH)) 1751 1.14 chopps */ 1752 1.26 is #if defined(M68040) || defined(M68060) 1753 1.14 chopps if (mmutype == MMU_68040 && usedma && count) { 1754 1.14 chopps dma_cachectl(addr, count); 1755 1.14 chopps if (((u_int)addr & 0xF) || (((u_int)addr + count) & 0xF)) 1756 1.14 chopps dev->sc_flags |= SBICF_DCFLUSH; 1757 1.1 chopps } 1758 1.1 chopps #endif 1759 1.66 phx #ifdef __powerpc__ 1760 1.66 phx dma_cachectl(addr, count); 1761 1.66 phx #endif 1762 1.1 chopps 1763 1.1 chopps /* 1764 1.16 chopps * enintr() also enables interrupts for the sbic 1765 1.1 chopps */ 1766 1.14 chopps #ifdef DEBUG 1767 1.75 christos if (data_pointer_debug > 1) 1768 1.28 christos printf("sbicgo dmago:%d(%p:%lx)\n", 1769 1.14 chopps dev->target,dev->sc_cur->dc_addr,dev->sc_tcnt); 1770 1.24 mhitch #if 0 1771 1.24 mhitch /* 1772 1.24 mhitch * Hmm - this isn't right: asr and csr haven't been set yet. 1773 1.24 mhitch */ 1774 1.14 chopps debug_asr = asr; 1775 1.14 chopps debug_csr = csr; 1776 1.3 chopps #endif 1777 1.24 mhitch #endif 1778 1.1 chopps 1779 1.1 chopps /* 1780 1.14 chopps * Lets cycle a while then let the interrupt handler take over 1781 1.1 chopps */ 1782 1.1 chopps 1783 1.48 thorpej GET_SBIC_asr(regs, asr); 1784 1.14 chopps do { 1785 1.14 chopps GET_SBIC_csr(regs, csr); 1786 1.16 chopps CSR_TRACE('g',csr,asr,dev->target); 1787 1.14 chopps #ifdef DEBUG 1788 1.14 chopps debug_csr = csr; 1789 1.14 chopps routine = 1; 1790 1.14 chopps #endif 1791 1.14 chopps QPRINTF(("go[0x%x]", csr)); 1792 1.1 chopps 1793 1.14 chopps i = sbicnextstate(dev, csr, asr); 1794 1.1 chopps 1795 1.14 chopps WAIT_CIP(regs); 1796 1.14 chopps GET_SBIC_asr(regs, asr); 1797 1.14 chopps #ifdef DEBUG 1798 1.14 chopps debug_asr = asr; 1799 1.14 chopps #endif 1800 1.75 christos if (asr & SBIC_ASR_LCI) printf("sbicgo: LCI asr:%02x csr:%02x\n", 1801 1.14 chopps asr,csr); 1802 1.75 christos } while (i == SBIC_STATE_RUNNING 1803 1.75 christos && asr & (SBIC_ASR_INT|SBIC_ASR_LCI)); 1804 1.14 chopps 1805 1.16 chopps CSR_TRACE('g',csr,asr,i<<4); 1806 1.16 chopps SBIC_TRACE(dev); 1807 1.28 christos if (i == SBIC_STATE_DONE && dev->sc_stat[0] == 0xff) printf("sbicgo: done & stat = 0xff\n"); 1808 1.16 chopps if (i == SBIC_STATE_DONE && dev->sc_stat[0] != 0xff) { 1809 1.75 christos /* if (i == SBIC_STATE_DONE && dev->sc_stat[0]) { */ 1810 1.14 chopps /* Did we really finish that fast? */ 1811 1.14 chopps return 1; 1812 1.14 chopps } 1813 1.14 chopps return 0; 1814 1.1 chopps } 1815 1.1 chopps 1816 1.1 chopps 1817 1.1 chopps int 1818 1.45 aymeric sbicintr(struct sbic_softc *dev) 1819 1.1 chopps { 1820 1.33 is sbic_regmap_t regs; 1821 1.23 veego u_char asr, csr; 1822 1.23 veego int i; 1823 1.1 chopps 1824 1.33 is regs = dev->sc_sbic; 1825 1.1 chopps 1826 1.1 chopps /* 1827 1.1 chopps * pending interrupt? 1828 1.1 chopps */ 1829 1.1 chopps GET_SBIC_asr (regs, asr); 1830 1.1 chopps if ((asr & SBIC_ASR_INT) == 0) 1831 1.1 chopps return(0); 1832 1.1 chopps 1833 1.16 chopps SBIC_TRACE(dev); 1834 1.14 chopps do { 1835 1.14 chopps GET_SBIC_csr(regs, csr); 1836 1.16 chopps CSR_TRACE('i',csr,asr,dev->target); 1837 1.14 chopps #ifdef DEBUG 1838 1.14 chopps debug_csr = csr; 1839 1.14 chopps routine = 2; 1840 1.14 chopps #endif 1841 1.14 chopps QPRINTF(("intr[0x%x]", csr)); 1842 1.14 chopps 1843 1.14 chopps i = sbicnextstate(dev, csr, asr); 1844 1.14 chopps 1845 1.14 chopps WAIT_CIP(regs); 1846 1.14 chopps GET_SBIC_asr(regs, asr); 1847 1.14 chopps #ifdef DEBUG 1848 1.14 chopps debug_asr = asr; 1849 1.14 chopps #endif 1850 1.14 chopps #if 0 1851 1.75 christos if (asr & SBIC_ASR_LCI) printf("sbicintr: LCI asr:%02x csr:%02x\n", 1852 1.14 chopps asr,csr); 1853 1.14 chopps #endif 1854 1.75 christos } while (i == SBIC_STATE_RUNNING && 1855 1.14 chopps asr & (SBIC_ASR_INT|SBIC_ASR_LCI)); 1856 1.16 chopps CSR_TRACE('i',csr,asr,i<<4); 1857 1.16 chopps SBIC_TRACE(dev); 1858 1.14 chopps return(1); 1859 1.14 chopps } 1860 1.14 chopps 1861 1.14 chopps /* 1862 1.14 chopps * Run commands and wait for disconnect 1863 1.14 chopps */ 1864 1.14 chopps int 1865 1.45 aymeric sbicpoll(struct sbic_softc *dev) 1866 1.14 chopps { 1867 1.33 is sbic_regmap_t regs; 1868 1.14 chopps u_char asr, csr; 1869 1.14 chopps int i; 1870 1.14 chopps 1871 1.16 chopps SBIC_TRACE(dev); 1872 1.33 is regs = dev->sc_sbic; 1873 1.14 chopps 1874 1.14 chopps do { 1875 1.14 chopps GET_SBIC_asr (regs, asr); 1876 1.14 chopps #ifdef DEBUG 1877 1.14 chopps debug_asr = asr; 1878 1.14 chopps #endif 1879 1.14 chopps GET_SBIC_csr(regs, csr); 1880 1.16 chopps CSR_TRACE('p',csr,asr,dev->target); 1881 1.14 chopps #ifdef DEBUG 1882 1.14 chopps debug_csr = csr; 1883 1.14 chopps routine = 2; 1884 1.14 chopps #endif 1885 1.14 chopps QPRINTF(("poll[0x%x]", csr)); 1886 1.14 chopps 1887 1.14 chopps i = sbicnextstate(dev, csr, asr); 1888 1.14 chopps 1889 1.14 chopps WAIT_CIP(regs); 1890 1.14 chopps GET_SBIC_asr(regs, asr); 1891 1.14 chopps /* tapes may take a loooong time.. */ 1892 1.14 chopps while (asr & SBIC_ASR_BSY){ 1893 1.75 christos if (asr & SBIC_ASR_DBR) { 1894 1.28 christos printf("sbipoll: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n", 1895 1.14 chopps csr,asr); 1896 1.14 chopps #ifdef DDB 1897 1.14 chopps Debugger(); 1898 1.14 chopps #endif 1899 1.14 chopps /* SBIC is jammed */ 1900 1.14 chopps /* DUNNO which direction */ 1901 1.14 chopps /* Try old direction */ 1902 1.14 chopps GET_SBIC_data(regs,i); 1903 1.14 chopps GET_SBIC_asr(regs, asr); 1904 1.75 christos if (asr & SBIC_ASR_DBR) /* Wants us to write */ 1905 1.14 chopps SET_SBIC_data(regs,i); 1906 1.14 chopps } 1907 1.14 chopps GET_SBIC_asr(regs, asr); 1908 1.14 chopps } 1909 1.14 chopps 1910 1.75 christos if (asr & SBIC_ASR_LCI) printf("sbicpoll: LCI asr:%02x csr:%02x\n", 1911 1.14 chopps asr,csr); 1912 1.75 christos else if (i == 1) /* BSY */ 1913 1.14 chopps SBIC_WAIT(regs, SBIC_ASR_INT, sbic_cmd_wait); 1914 1.75 christos } while (i == SBIC_STATE_RUNNING); 1915 1.16 chopps CSR_TRACE('p',csr,asr,i<<4); 1916 1.16 chopps SBIC_TRACE(dev); 1917 1.14 chopps return(1); 1918 1.14 chopps } 1919 1.14 chopps 1920 1.14 chopps /* 1921 1.14 chopps * Handle a single msgin 1922 1.14 chopps */ 1923 1.14 chopps 1924 1.14 chopps int 1925 1.45 aymeric sbicmsgin(struct sbic_softc *dev) 1926 1.14 chopps { 1927 1.33 is sbic_regmap_t regs; 1928 1.14 chopps int recvlen; 1929 1.14 chopps u_char asr, csr, *tmpaddr; 1930 1.14 chopps 1931 1.33 is regs = dev->sc_sbic; 1932 1.14 chopps 1933 1.14 chopps dev->sc_msg[0] = 0xff; 1934 1.14 chopps dev->sc_msg[1] = 0xff; 1935 1.14 chopps 1936 1.14 chopps GET_SBIC_asr(regs, asr); 1937 1.14 chopps #ifdef DEBUG 1938 1.75 christos if (reselect_debug>1) 1939 1.28 christos printf("sbicmsgin asr=%02x\n", asr); 1940 1.14 chopps #endif 1941 1.14 chopps 1942 1.14 chopps sbic_save_ptrs(dev, regs, dev->target, dev->lun); 1943 1.14 chopps 1944 1.14 chopps GET_SBIC_selid (regs, csr); 1945 1.14 chopps SET_SBIC_selid (regs, csr | SBIC_SID_FROM_SCSI); 1946 1.14 chopps 1947 1.14 chopps SBIC_TC_PUT(regs, 0); 1948 1.14 chopps tmpaddr = dev->sc_msg; 1949 1.14 chopps recvlen = 1; 1950 1.14 chopps do { 1951 1.75 christos while (recvlen--) { 1952 1.48 thorpej GET_SBIC_asr(regs, asr); 1953 1.14 chopps GET_SBIC_csr(regs, csr); 1954 1.14 chopps QPRINTF(("sbicmsgin ready to go (csr,asr)=(%02x,%02x)\n", 1955 1.14 chopps csr, asr)); 1956 1.14 chopps 1957 1.14 chopps RECV_BYTE(regs, *tmpaddr); 1958 1.16 chopps CSR_TRACE('m',csr,asr,*tmpaddr); 1959 1.14 chopps #if 1 1960 1.14 chopps /* 1961 1.14 chopps * get the command completion interrupt, or we 1962 1.14 chopps * can't send a new command (LCI) 1963 1.14 chopps */ 1964 1.14 chopps SBIC_WAIT(regs, SBIC_ASR_INT, 0); 1965 1.14 chopps GET_SBIC_csr(regs, csr); 1966 1.16 chopps CSR_TRACE('X',csr,asr,dev->target); 1967 1.14 chopps #else 1968 1.14 chopps WAIT_CIP(regs); 1969 1.14 chopps do { 1970 1.14 chopps GET_SBIC_asr(regs, asr); 1971 1.14 chopps csr = 0xff; 1972 1.14 chopps GET_SBIC_csr(regs, csr); 1973 1.16 chopps CSR_TRACE('X',csr,asr,dev->target); 1974 1.75 christos if (csr == 0xff) 1975 1.28 christos printf("sbicmsgin waiting: csr %02x asr %02x\n", csr, asr); 1976 1.75 christos } while (csr == 0xff); 1977 1.14 chopps #endif 1978 1.14 chopps #ifdef DEBUG 1979 1.75 christos if (reselect_debug>1) 1980 1.28 christos printf("sbicmsgin: got %02x csr %02x asr %02x\n", 1981 1.14 chopps *tmpaddr, csr, asr); 1982 1.14 chopps #endif 1983 1.14 chopps #if do_parity_check 1984 1.75 christos if (asr & SBIC_ASR_PE) { 1985 1.28 christos printf ("Parity error"); 1986 1.14 chopps /* This code simply does not work. */ 1987 1.14 chopps WAIT_CIP(regs); 1988 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN); 1989 1.14 chopps WAIT_CIP(regs); 1990 1.14 chopps GET_SBIC_asr(regs, asr); 1991 1.14 chopps WAIT_CIP(regs); 1992 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 1993 1.14 chopps WAIT_CIP(regs); 1994 1.75 christos if (!(asr & SBIC_ASR_LCI)) 1995 1.14 chopps /* Target wants to send garbled msg*/ 1996 1.14 chopps continue; 1997 1.28 christos printf("--fixing\n"); 1998 1.14 chopps /* loop until a msgout phase occurs on target */ 1999 1.75 christos while ((csr & 0x07) != MESG_OUT_PHASE) { 2000 1.75 christos while ((asr & SBIC_ASR_BSY) && 2001 1.75 christos !(asr & SBIC_ASR_DBR|SBIC_ASR_INT)) 2002 1.14 chopps GET_SBIC_asr(regs, asr); 2003 1.75 christos if (asr & SBIC_ASR_DBR) 2004 1.49 provos panic("msgin: jammed again!"); 2005 1.14 chopps GET_SBIC_csr(regs, csr); 2006 1.16 chopps CSR_TRACE('e',csr,asr,dev->target); 2007 1.75 christos if ((csr & 0x07) != MESG_OUT_PHASE) { 2008 1.14 chopps sbicnextstate(dev, csr, asr); 2009 1.14 chopps sbic_save_ptrs(dev, regs, 2010 1.14 chopps dev->target, 2011 1.14 chopps dev->lun); 2012 1.14 chopps } 2013 1.14 chopps } 2014 1.14 chopps /* Should be msg out by now */ 2015 1.14 chopps SEND_BYTE(regs, MSG_PARITY_ERROR); 2016 1.14 chopps } 2017 1.14 chopps else 2018 1.14 chopps #endif 2019 1.14 chopps tmpaddr++; 2020 1.14 chopps 2021 1.75 christos if (recvlen) { 2022 1.14 chopps /* Clear ACK */ 2023 1.14 chopps WAIT_CIP(regs); 2024 1.14 chopps GET_SBIC_asr(regs, asr); 2025 1.14 chopps GET_SBIC_csr(regs, csr); 2026 1.16 chopps CSR_TRACE('X',csr,asr,dev->target); 2027 1.14 chopps QPRINTF(("sbicmsgin pre byte CLR_ACK (csr,asr)=(%02x,%02x)\n", 2028 1.14 chopps csr, asr)); 2029 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 2030 1.14 chopps SBIC_WAIT(regs, SBIC_ASR_INT, 0); 2031 1.14 chopps } 2032 1.14 chopps 2033 1.14 chopps }; 2034 1.14 chopps 2035 1.75 christos if (dev->sc_msg[0] == 0xff) { 2036 1.28 christos printf("sbicmsgin: sbic swallowed our message\n"); 2037 1.14 chopps break; 2038 1.14 chopps } 2039 1.14 chopps #ifdef DEBUG 2040 1.14 chopps if (sync_debug) 2041 1.28 christos printf("msgin done csr 0x%x asr 0x%x msg 0x%x\n", 2042 1.14 chopps csr, asr, dev->sc_msg[0]); 2043 1.14 chopps #endif 2044 1.14 chopps /* 2045 1.14 chopps * test whether this is a reply to our sync 2046 1.14 chopps * request 2047 1.14 chopps */ 2048 1.14 chopps if (MSG_ISIDENTIFY(dev->sc_msg[0])) { 2049 1.14 chopps QPRINTF(("IFFY")); 2050 1.14 chopps #if 0 2051 1.14 chopps /* There is an implied load-ptrs here */ 2052 1.14 chopps sbic_load_ptrs(dev, regs, dev->target, dev->lun); 2053 1.14 chopps #endif 2054 1.14 chopps /* Got IFFY msg -- ack it */ 2055 1.14 chopps } else if (dev->sc_msg[0] == MSG_REJECT 2056 1.14 chopps && dev->sc_sync[dev->target].state == SYNC_SENT) { 2057 1.14 chopps QPRINTF(("REJECT of SYN")); 2058 1.14 chopps #ifdef DEBUG 2059 1.14 chopps if (sync_debug) 2060 1.28 christos printf("target %d rejected sync, going async\n", 2061 1.14 chopps dev->target); 2062 1.14 chopps #endif 2063 1.14 chopps dev->sc_sync[dev->target].period = sbic_min_period; 2064 1.14 chopps dev->sc_sync[dev->target].offset = 0; 2065 1.14 chopps dev->sc_sync[dev->target].state = SYNC_DONE; 2066 1.14 chopps SET_SBIC_syn(regs, 2067 1.14 chopps SBIC_SYN(dev->sc_sync[dev->target].offset, 2068 1.14 chopps dev->sc_sync[dev->target].period)); 2069 1.73 joerg } else if (dev->sc_msg[0] == MSG_REJECT) { 2070 1.14 chopps QPRINTF(("REJECT")); 2071 1.14 chopps /* 2072 1.14 chopps * we'll never REJECt a REJECT message.. 2073 1.14 chopps */ 2074 1.73 joerg } else if (dev->sc_msg[0] == MSG_SAVE_DATA_PTR) { 2075 1.14 chopps QPRINTF(("MSG_SAVE_DATA_PTR")); 2076 1.14 chopps /* 2077 1.14 chopps * don't reject this either. 2078 1.14 chopps */ 2079 1.73 joerg } else if (dev->sc_msg[0] == MSG_DISCONNECT) { 2080 1.14 chopps QPRINTF(("DISCONNECT")); 2081 1.14 chopps #ifdef DEBUG 2082 1.75 christos if (reselect_debug>1 && dev->sc_msg[0] == MSG_DISCONNECT) 2083 1.28 christos printf("sbicmsgin: got disconnect msg %s\n", 2084 1.14 chopps (dev->sc_flags & SBICF_ICMD)?"rejecting":""); 2085 1.14 chopps #endif 2086 1.75 christos if (dev->sc_flags & SBICF_ICMD) { 2087 1.14 chopps /* We're in immediate mode. Prevent disconnects. */ 2088 1.14 chopps /* prepare to reject the message, NACK */ 2089 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN); 2090 1.14 chopps WAIT_CIP(regs); 2091 1.14 chopps } 2092 1.75 christos } else if (dev->sc_msg[0] == MSG_CMD_COMPLETE) { 2093 1.14 chopps QPRINTF(("CMD_COMPLETE")); 2094 1.14 chopps /* !! KLUDGE ALERT !! quite a few drives don't seem to 2095 1.14 chopps * really like the current way of sending the 2096 1.14 chopps * sync-handshake together with the ident-message, and 2097 1.14 chopps * they react by sending command-complete and 2098 1.14 chopps * disconnecting right after returning the valid sync 2099 1.14 chopps * handshake. So, all I can do is reselect the drive, 2100 1.14 chopps * and hope it won't disconnect again. I don't think 2101 1.14 chopps * this is valid behavior, but I can't help fixing a 2102 1.14 chopps * problem that apparently exists. 2103 1.14 chopps * 2104 1.14 chopps * Note: we should not get here on `normal' command 2105 1.14 chopps * completion, as that condition is handled by the 2106 1.14 chopps * high-level sel&xfer resume command used to walk 2107 1.14 chopps * thru status/cc-phase. 2108 1.14 chopps */ 2109 1.14 chopps 2110 1.14 chopps #ifdef DEBUG 2111 1.14 chopps if (sync_debug) 2112 1.28 christos printf ("GOT MSG %d! target %d acting weird.." 2113 1.14 chopps " waiting for disconnect...\n", 2114 1.14 chopps dev->sc_msg[0], dev->target); 2115 1.14 chopps #endif 2116 1.14 chopps /* Check to see if sbic is handling this */ 2117 1.14 chopps GET_SBIC_asr(regs, asr); 2118 1.75 christos if (asr & SBIC_ASR_BSY) 2119 1.14 chopps return SBIC_STATE_RUNNING; 2120 1.14 chopps 2121 1.14 chopps /* Let's try this: Assume it works and set status to 00 */ 2122 1.14 chopps dev->sc_stat[0] = 0; 2123 1.14 chopps } else if (dev->sc_msg[0] == MSG_EXT_MESSAGE 2124 1.14 chopps && tmpaddr == &dev->sc_msg[1]) { 2125 1.14 chopps QPRINTF(("ExtMSG\n")); 2126 1.14 chopps /* Read in whole extended message */ 2127 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 2128 1.14 chopps SBIC_WAIT(regs, SBIC_ASR_INT, 0); 2129 1.14 chopps GET_SBIC_asr(regs, asr); 2130 1.14 chopps GET_SBIC_csr(regs, csr); 2131 1.14 chopps QPRINTF(("CLR ACK asr %02x, csr %02x\n", asr, csr)); 2132 1.14 chopps RECV_BYTE(regs, *tmpaddr); 2133 1.16 chopps CSR_TRACE('x',csr,asr,*tmpaddr); 2134 1.14 chopps /* Wait for command completion IRQ */ 2135 1.14 chopps SBIC_WAIT(regs, SBIC_ASR_INT, 0); 2136 1.14 chopps recvlen = *tmpaddr++; 2137 1.14 chopps QPRINTF(("Recving ext msg, asr %02x csr %02x len %02x\n", 2138 1.14 chopps asr, csr, recvlen)); 2139 1.14 chopps } else if (dev->sc_msg[0] == MSG_EXT_MESSAGE && dev->sc_msg[1] == 3 2140 1.14 chopps && dev->sc_msg[2] == MSG_SYNC_REQ) { 2141 1.14 chopps QPRINTF(("SYN")); 2142 1.14 chopps dev->sc_sync[dev->target].period = 2143 1.14 chopps sbicfromscsiperiod(dev, 2144 1.14 chopps regs, dev->sc_msg[3]); 2145 1.14 chopps dev->sc_sync[dev->target].offset = dev->sc_msg[4]; 2146 1.14 chopps dev->sc_sync[dev->target].state = SYNC_DONE; 2147 1.14 chopps SET_SBIC_syn(regs, 2148 1.14 chopps SBIC_SYN(dev->sc_sync[dev->target].offset, 2149 1.14 chopps dev->sc_sync[dev->target].period)); 2150 1.28 christos printf("%s: target %d now synchronous," 2151 1.14 chopps " period=%dns, offset=%d.\n", 2152 1.71 chs device_xname(dev->sc_dev), dev->target, 2153 1.14 chopps dev->sc_msg[3] * 4, dev->sc_msg[4]); 2154 1.14 chopps } else { 2155 1.14 chopps #ifdef DEBUG 2156 1.14 chopps if (sbic_debug || sync_debug) 2157 1.28 christos printf ("sbicmsgin: Rejecting message 0x%02x\n", 2158 1.14 chopps dev->sc_msg[0]); 2159 1.14 chopps #endif 2160 1.14 chopps /* prepare to reject the message, NACK */ 2161 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN); 2162 1.14 chopps WAIT_CIP(regs); 2163 1.14 chopps } 2164 1.14 chopps /* Clear ACK */ 2165 1.14 chopps WAIT_CIP(regs); 2166 1.14 chopps GET_SBIC_asr(regs, asr); 2167 1.14 chopps GET_SBIC_csr(regs, csr); 2168 1.16 chopps CSR_TRACE('X',csr,asr,dev->target); 2169 1.14 chopps QPRINTF(("sbicmsgin pre CLR_ACK (csr,asr)=(%02x,%02x)%d\n", 2170 1.14 chopps csr, asr, recvlen)); 2171 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 2172 1.14 chopps SBIC_WAIT(regs, SBIC_ASR_INT, 0); 2173 1.14 chopps } 2174 1.14 chopps #if 0 2175 1.75 christos while ((csr == SBIC_CSR_MSGIN_W_ACK) 2176 1.14 chopps || (SBIC_PHASE(csr) == MESG_IN_PHASE)); 2177 1.14 chopps #else 2178 1.14 chopps while (recvlen>0); 2179 1.14 chopps #endif 2180 1.14 chopps 2181 1.14 chopps QPRINTF(("sbicmsgin finished: csr %02x, asr %02x\n",csr, asr)); 2182 1.14 chopps 2183 1.14 chopps /* Should still have one CSR to read */ 2184 1.14 chopps return SBIC_STATE_RUNNING; 2185 1.14 chopps } 2186 1.14 chopps 2187 1.14 chopps 2188 1.14 chopps /* 2189 1.14 chopps * sbicnextstate() 2190 1.14 chopps * return: 2191 1.14 chopps * 0 == done 2192 1.14 chopps * 1 == working 2193 1.14 chopps * 2 == disconnected 2194 1.14 chopps * -1 == error 2195 1.14 chopps */ 2196 1.14 chopps int 2197 1.45 aymeric sbicnextstate(struct sbic_softc *dev, u_char csr, u_char asr) 2198 1.14 chopps { 2199 1.33 is sbic_regmap_t regs; 2200 1.14 chopps struct sbic_acb *acb; 2201 1.14 chopps int i, newtarget, newlun, wait; 2202 1.23 veego #if 0 2203 1.14 chopps unsigned tcnt; 2204 1.23 veego #endif 2205 1.14 chopps 2206 1.23 veego i = 0; 2207 1.16 chopps SBIC_TRACE(dev); 2208 1.33 is regs = dev->sc_sbic; 2209 1.14 chopps acb = dev->sc_nexus; 2210 1.14 chopps 2211 1.14 chopps QPRINTF(("next[%02x,%02x]",asr,csr)); 2212 1.14 chopps 2213 1.14 chopps switch (csr) { 2214 1.14 chopps case SBIC_CSR_XFERRED|CMD_PHASE: 2215 1.14 chopps case SBIC_CSR_MIS|CMD_PHASE: 2216 1.14 chopps case SBIC_CSR_MIS_1|CMD_PHASE: 2217 1.14 chopps case SBIC_CSR_MIS_2|CMD_PHASE: 2218 1.14 chopps sbic_save_ptrs(dev, regs, dev->target, dev->lun); 2219 1.14 chopps if (sbicxfstart(regs, acb->clen, CMD_PHASE, sbic_cmd_wait)) 2220 1.14 chopps if (sbicxfout(regs, acb->clen, 2221 1.14 chopps &acb->cmd, CMD_PHASE)) 2222 1.14 chopps goto abort; 2223 1.14 chopps break; 2224 1.1 chopps 2225 1.14 chopps case SBIC_CSR_XFERRED|STATUS_PHASE: 2226 1.14 chopps case SBIC_CSR_MIS|STATUS_PHASE: 2227 1.14 chopps case SBIC_CSR_MIS_1|STATUS_PHASE: 2228 1.14 chopps case SBIC_CSR_MIS_2|STATUS_PHASE: 2229 1.1 chopps /* 2230 1.1 chopps * this should be the normal i/o completion case. 2231 1.1 chopps * get the status & cmd complete msg then let the 2232 1.1 chopps * device driver look at what happened. 2233 1.1 chopps */ 2234 1.14 chopps sbicxfdone(dev,regs,dev->target); 2235 1.3 chopps /* 2236 1.3 chopps * check for overlapping cache line, flush if so 2237 1.3 chopps */ 2238 1.26 is #if defined(M68040) || defined(M68060) 2239 1.3 chopps if (dev->sc_flags & SBICF_DCFLUSH) { 2240 1.14 chopps #if 0 2241 1.28 christos printf("sbic: 68040/68060 DMA cache flush needs" 2242 1.26 is "fixing? %x:%x\n", 2243 1.14 chopps dev->sc_xs->data, dev->sc_xs->datalen); 2244 1.14 chopps #endif 2245 1.3 chopps } 2246 1.4 chopps #endif 2247 1.14 chopps #ifdef DEBUG 2248 1.75 christos if (data_pointer_debug > 1) 2249 1.28 christos printf("next dmastop: %d(%p:%lx)\n", 2250 1.14 chopps dev->target,dev->sc_cur->dc_addr,dev->sc_tcnt); 2251 1.16 chopps dev->sc_dmatimo = 0; 2252 1.14 chopps #endif 2253 1.14 chopps dev->sc_dmastop(dev); /* was dmafree */ 2254 1.14 chopps if (acb->flags & ACB_BBUF) { 2255 1.14 chopps if ((u_char *)kvtop(acb->sc_dmausrbuf) != acb->sc_usrbufpa) 2256 1.28 christos printf("%s: WARNING - buffer mapping changed %p->%x\n", 2257 1.71 chs device_xname(dev->sc_dev), acb->sc_usrbufpa, 2258 1.61 is (unsigned)kvtop(acb->sc_dmausrbuf)); 2259 1.14 chopps #ifdef DEBUG 2260 1.75 christos if (data_pointer_debug) 2261 1.28 christos printf("sbicgo:copying %lx bytes from target %d bounce %x\n", 2262 1.14 chopps acb->sc_dmausrlen, 2263 1.14 chopps dev->target, 2264 1.61 is (unsigned)kvtop(dev->sc_tinfo[dev->target].bounce)); 2265 1.14 chopps #endif 2266 1.14 chopps bcopy(dev->sc_tinfo[dev->target].bounce, 2267 1.14 chopps acb->sc_dmausrbuf, 2268 1.14 chopps acb->sc_dmausrlen); 2269 1.14 chopps } 2270 1.14 chopps dev->sc_flags &= ~(SBICF_INDMA | SBICF_DCFLUSH); 2271 1.14 chopps sbic_scsidone(acb, dev->sc_stat[0]); 2272 1.16 chopps SBIC_TRACE(dev); 2273 1.14 chopps return SBIC_STATE_DONE; 2274 1.14 chopps 2275 1.14 chopps case SBIC_CSR_XFERRED|DATA_OUT_PHASE: 2276 1.14 chopps case SBIC_CSR_XFERRED|DATA_IN_PHASE: 2277 1.14 chopps case SBIC_CSR_MIS|DATA_OUT_PHASE: 2278 1.14 chopps case SBIC_CSR_MIS|DATA_IN_PHASE: 2279 1.14 chopps case SBIC_CSR_MIS_1|DATA_OUT_PHASE: 2280 1.14 chopps case SBIC_CSR_MIS_1|DATA_IN_PHASE: 2281 1.14 chopps case SBIC_CSR_MIS_2|DATA_OUT_PHASE: 2282 1.14 chopps case SBIC_CSR_MIS_2|DATA_IN_PHASE: 2283 1.75 christos if ((dev->sc_xs->xs_control & XS_CTL_POLL) || 2284 1.75 christos (dev->sc_flags & SBICF_ICMD) || acb->sc_dmacmd == 0) { 2285 1.14 chopps /* Do PIO */ 2286 1.14 chopps SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI); 2287 1.14 chopps if (acb->sc_kv.dc_count <= 0) { 2288 1.28 christos printf("sbicnextstate:xfer count %d asr%x csr%x\n", 2289 1.14 chopps acb->sc_kv.dc_count, asr, csr); 2290 1.14 chopps goto abort; 2291 1.11 chopps } 2292 1.14 chopps wait = sbic_data_wait; 2293 1.75 christos if (sbicxfstart(regs, 2294 1.14 chopps acb->sc_kv.dc_count, 2295 1.34 frueauf SBIC_PHASE(csr), wait)) { 2296 1.75 christos if (SBIC_PHASE(csr) == DATA_IN_PHASE) 2297 1.14 chopps /* data in? */ 2298 1.14 chopps i=sbicxfin(regs, 2299 1.14 chopps acb->sc_kv.dc_count, 2300 1.14 chopps acb->sc_kv.dc_addr); 2301 1.14 chopps else 2302 1.14 chopps i=sbicxfout(regs, 2303 1.14 chopps acb->sc_kv.dc_count, 2304 1.14 chopps acb->sc_kv.dc_addr, 2305 1.14 chopps SBIC_PHASE(csr)); 2306 1.34 frueauf } 2307 1.14 chopps acb->sc_kv.dc_addr += 2308 1.14 chopps (acb->sc_kv.dc_count - i); 2309 1.14 chopps acb->sc_kv.dc_count = i; 2310 1.14 chopps } else { 2311 1.16 chopps if (acb->sc_kv.dc_count <= 0) { 2312 1.28 christos printf("sbicnextstate:xfer count %d asr%x csr%x\n", 2313 1.16 chopps acb->sc_kv.dc_count, asr, csr); 2314 1.16 chopps goto abort; 2315 1.16 chopps } 2316 1.14 chopps /* 2317 1.51 wiz * do scatter-gather DMA 2318 1.14 chopps * hacking the controller chip, ouch.. 2319 1.14 chopps */ 2320 1.14 chopps SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI | 2321 1.14 chopps SBIC_MACHINE_DMA_MODE); 2322 1.14 chopps /* 2323 1.51 wiz * set next DMA addr and dec count 2324 1.14 chopps */ 2325 1.14 chopps #if 0 2326 1.14 chopps SBIC_TC_GET(regs, tcnt); 2327 1.14 chopps dev->sc_cur->dc_count -= ((dev->sc_tcnt - tcnt) >> 1); 2328 1.14 chopps dev->sc_cur->dc_addr += (dev->sc_tcnt - tcnt); 2329 1.14 chopps dev->sc_tcnt = acb->sc_tcnt = tcnt; 2330 1.14 chopps #else 2331 1.14 chopps sbic_save_ptrs(dev, regs, dev->target, dev->lun); 2332 1.14 chopps sbic_load_ptrs(dev, regs, dev->target, dev->lun); 2333 1.14 chopps #endif 2334 1.14 chopps #ifdef DEBUG 2335 1.75 christos if (data_pointer_debug > 1) 2336 1.28 christos printf("next dmanext: %d(%p:%lx)\n", 2337 1.14 chopps dev->target,dev->sc_cur->dc_addr, 2338 1.14 chopps dev->sc_tcnt); 2339 1.16 chopps dev->sc_dmatimo = 1; 2340 1.14 chopps #endif 2341 1.14 chopps dev->sc_tcnt = dev->sc_dmanext(dev); 2342 1.14 chopps SBIC_TC_PUT(regs, (unsigned)dev->sc_tcnt); 2343 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_XFER_INFO); 2344 1.14 chopps dev->sc_flags |= SBICF_INDMA; 2345 1.14 chopps } 2346 1.14 chopps break; 2347 1.14 chopps 2348 1.14 chopps case SBIC_CSR_XFERRED|MESG_IN_PHASE: 2349 1.14 chopps case SBIC_CSR_MIS|MESG_IN_PHASE: 2350 1.14 chopps case SBIC_CSR_MIS_1|MESG_IN_PHASE: 2351 1.14 chopps case SBIC_CSR_MIS_2|MESG_IN_PHASE: 2352 1.16 chopps SBIC_TRACE(dev); 2353 1.14 chopps return sbicmsgin(dev); 2354 1.14 chopps 2355 1.14 chopps case SBIC_CSR_MSGIN_W_ACK: 2356 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); /* Dunno what I'm ACKing */ 2357 1.28 christos printf("Acking unknown msgin CSR:%02x",csr); 2358 1.14 chopps break; 2359 1.14 chopps 2360 1.14 chopps case SBIC_CSR_XFERRED|MESG_OUT_PHASE: 2361 1.14 chopps case SBIC_CSR_MIS|MESG_OUT_PHASE: 2362 1.14 chopps case SBIC_CSR_MIS_1|MESG_OUT_PHASE: 2363 1.14 chopps case SBIC_CSR_MIS_2|MESG_OUT_PHASE: 2364 1.14 chopps #ifdef DEBUG 2365 1.14 chopps if (sync_debug) 2366 1.28 christos printf ("sending REJECT msg to last msg.\n"); 2367 1.14 chopps #endif 2368 1.14 chopps 2369 1.14 chopps sbic_save_ptrs(dev, regs, dev->target, dev->lun); 2370 1.1 chopps /* 2371 1.14 chopps * should only get here on reject, 2372 1.14 chopps * since it's always US that 2373 1.14 chopps * initiate a sync transfer 2374 1.1 chopps */ 2375 1.14 chopps SEND_BYTE(regs, MSG_REJECT); 2376 1.14 chopps WAIT_CIP(regs); 2377 1.75 christos if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI|SBIC_ASR_CIP)) 2378 1.28 christos printf("next: REJECT sent asr %02x\n", asr); 2379 1.16 chopps SBIC_TRACE(dev); 2380 1.14 chopps return SBIC_STATE_RUNNING; 2381 1.14 chopps 2382 1.14 chopps case SBIC_CSR_DISC: 2383 1.14 chopps case SBIC_CSR_DISC_1: 2384 1.14 chopps dev->sc_flags &= ~(SBICF_INDMA|SBICF_SELECTED); 2385 1.14 chopps 2386 1.14 chopps /* Try to schedule another target */ 2387 1.14 chopps #ifdef DEBUG 2388 1.75 christos if (reselect_debug>1) 2389 1.28 christos printf("sbicnext target %d disconnected\n", dev->target); 2390 1.14 chopps #endif 2391 1.14 chopps TAILQ_INSERT_HEAD(&dev->nexus_list, acb, chain); 2392 1.14 chopps ++dev->sc_tinfo[dev->target].dconns; 2393 1.14 chopps dev->sc_nexus = NULL; 2394 1.14 chopps dev->sc_xs = NULL; 2395 1.1 chopps 2396 1.75 christos if ((acb->xs->xs_control & XS_CTL_POLL) 2397 1.14 chopps || (dev->sc_flags & SBICF_ICMD) 2398 1.75 christos || !sbic_parallel_operations) { 2399 1.16 chopps SBIC_TRACE(dev); 2400 1.14 chopps return SBIC_STATE_DISCONNECT; 2401 1.16 chopps } 2402 1.14 chopps sbic_sched(dev); 2403 1.16 chopps SBIC_TRACE(dev); 2404 1.14 chopps return SBIC_STATE_DISCONNECT; 2405 1.14 chopps 2406 1.14 chopps case SBIC_CSR_RSLT_NI: 2407 1.14 chopps case SBIC_CSR_RSLT_IFY: 2408 1.14 chopps GET_SBIC_rselid(regs, newtarget); 2409 1.14 chopps /* check SBIC_RID_SIV? */ 2410 1.14 chopps newtarget &= SBIC_RID_MASK; 2411 1.14 chopps if (csr == SBIC_CSR_RSLT_IFY) { 2412 1.14 chopps /* Read IFY msg to avoid lockup */ 2413 1.14 chopps GET_SBIC_data(regs, newlun); 2414 1.14 chopps WAIT_CIP(regs); 2415 1.14 chopps newlun &= SBIC_TLUN_MASK; 2416 1.16 chopps CSR_TRACE('r',csr,asr,newtarget); 2417 1.14 chopps } else { 2418 1.14 chopps /* Need to get IFY message */ 2419 1.14 chopps for (newlun = 256; newlun; --newlun) { 2420 1.14 chopps GET_SBIC_asr(regs, asr); 2421 1.14 chopps if (asr & SBIC_ASR_INT) 2422 1.14 chopps break; 2423 1.14 chopps delay(1); 2424 1.14 chopps } 2425 1.14 chopps newlun = 0; /* XXXX */ 2426 1.14 chopps if ((asr & SBIC_ASR_INT) == 0) { 2427 1.14 chopps #ifdef DEBUG 2428 1.14 chopps if (reselect_debug) 2429 1.28 christos printf("RSLT_NI - no IFFY message? asr %x\n", asr); 2430 1.14 chopps #endif 2431 1.14 chopps } else { 2432 1.14 chopps GET_SBIC_csr(regs,csr); 2433 1.16 chopps CSR_TRACE('n',csr,asr,newtarget); 2434 1.23 veego if (csr == (SBIC_CSR_MIS | MESG_IN_PHASE) || 2435 1.23 veego csr == (SBIC_CSR_MIS_1 | MESG_IN_PHASE) || 2436 1.23 veego csr == (SBIC_CSR_MIS_2 | MESG_IN_PHASE)) { 2437 1.14 chopps sbicmsgin(dev); 2438 1.14 chopps newlun = dev->sc_msg[0] & 7; 2439 1.14 chopps } else { 2440 1.28 christos printf("RSLT_NI - not MESG_IN_PHASE %x\n", 2441 1.14 chopps csr); 2442 1.14 chopps } 2443 1.14 chopps } 2444 1.14 chopps } 2445 1.14 chopps #ifdef DEBUG 2446 1.75 christos if (reselect_debug>1 || (reselect_debug && csr==SBIC_CSR_RSLT_NI)) 2447 1.28 christos printf("sbicnext: reselect %s from targ %d lun %d\n", 2448 1.14 chopps csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", 2449 1.14 chopps newtarget, newlun); 2450 1.14 chopps #endif 2451 1.14 chopps if (dev->sc_nexus) { 2452 1.14 chopps #ifdef DEBUG 2453 1.14 chopps if (reselect_debug > 1) 2454 1.28 christos printf("%s: reselect %s with active command\n", 2455 1.71 chs device_xname(dev->sc_dev), 2456 1.14 chopps csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY"); 2457 1.14 chopps #ifdef DDB 2458 1.14 chopps /* Debugger();*/ 2459 1.14 chopps #endif 2460 1.14 chopps #endif 2461 1.14 chopps TAILQ_INSERT_HEAD(&dev->ready_list, dev->sc_nexus, chain); 2462 1.14 chopps dev->sc_tinfo[dev->target].lubusy &= ~(1 << dev->lun); 2463 1.16 chopps dev->sc_nexus = NULL; 2464 1.16 chopps dev->sc_xs = NULL; 2465 1.14 chopps } 2466 1.15 chopps /* Reload sync values for this target */ 2467 1.15 chopps if (dev->sc_sync[newtarget].state == SYNC_DONE) 2468 1.15 chopps SET_SBIC_syn(regs, SBIC_SYN (dev->sc_sync[newtarget].offset, 2469 1.15 chopps dev->sc_sync[newtarget].period)); 2470 1.15 chopps else 2471 1.15 chopps SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period)); 2472 1.14 chopps for (acb = dev->nexus_list.tqh_first; acb; 2473 1.14 chopps acb = acb->chain.tqe_next) { 2474 1.43 bouyer if (acb->xs->xs_periph->periph_target != newtarget || 2475 1.43 bouyer acb->xs->xs_periph->periph_lun != newlun) 2476 1.14 chopps continue; 2477 1.14 chopps TAILQ_REMOVE(&dev->nexus_list, acb, chain); 2478 1.14 chopps dev->sc_nexus = acb; 2479 1.14 chopps dev->sc_xs = acb->xs; 2480 1.14 chopps dev->sc_flags |= SBICF_SELECTED; 2481 1.14 chopps dev->target = newtarget; 2482 1.14 chopps dev->lun = newlun; 2483 1.14 chopps break; 2484 1.14 chopps } 2485 1.14 chopps if (acb == NULL) { 2486 1.28 christos printf("%s: reselect %s targ %d not in nexus_list %p\n", 2487 1.71 chs device_xname(dev->sc_dev), 2488 1.14 chopps csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", newtarget, 2489 1.14 chopps &dev->nexus_list.tqh_first); 2490 1.14 chopps panic("bad reselect in sbic"); 2491 1.14 chopps } 2492 1.14 chopps if (csr == SBIC_CSR_RSLT_IFY) 2493 1.14 chopps SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 2494 1.14 chopps break; 2495 1.1 chopps 2496 1.14 chopps default: 2497 1.14 chopps abort: 2498 1.1 chopps /* 2499 1.1 chopps * Something unexpected happened -- deal with it. 2500 1.1 chopps */ 2501 1.28 christos printf("sbicnextstate: aborting csr %02x asr %02x\n", csr, asr); 2502 1.14 chopps #ifdef DDB 2503 1.14 chopps Debugger(); 2504 1.14 chopps #endif 2505 1.14 chopps #ifdef DEBUG 2506 1.75 christos if (data_pointer_debug > 1) 2507 1.28 christos printf("next dmastop: %d(%p:%lx)\n", 2508 1.14 chopps dev->target,dev->sc_cur->dc_addr,dev->sc_tcnt); 2509 1.16 chopps dev->sc_dmatimo = 0; 2510 1.14 chopps #endif 2511 1.1 chopps dev->sc_dmastop(dev); 2512 1.16 chopps SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI); 2513 1.1 chopps sbicerror(dev, regs, csr); 2514 1.14 chopps sbicabort(dev, regs, "next"); 2515 1.1 chopps if (dev->sc_flags & SBICF_INDMA) { 2516 1.3 chopps /* 2517 1.3 chopps * check for overlapping cache line, flush if so 2518 1.3 chopps */ 2519 1.26 is #if defined(M68040) || defined(M68060) 2520 1.3 chopps if (dev->sc_flags & SBICF_DCFLUSH) { 2521 1.14 chopps #if 0 2522 1.28 christos printf("sbic: 68040/060 DMA cache flush needs" 2523 1.26 is "fixing? %x:%x\n", 2524 1.14 chopps dev->sc_xs->data, dev->sc_xs->datalen); 2525 1.14 chopps #endif 2526 1.3 chopps } 2527 1.4 chopps #endif 2528 1.13 mycroft dev->sc_flags &= 2529 1.14 chopps ~(SBICF_INDMA | SBICF_DCFLUSH); 2530 1.14 chopps #ifdef DEBUG 2531 1.75 christos if (data_pointer_debug > 1) 2532 1.28 christos printf("next dmastop: %d(%p:%lx)\n", 2533 1.16 chopps dev->target,dev->sc_cur->dc_addr,dev->sc_tcnt); 2534 1.16 chopps dev->sc_dmatimo = 0; 2535 1.14 chopps #endif 2536 1.14 chopps dev->sc_dmastop(dev); 2537 1.14 chopps sbic_scsidone(acb, -1); 2538 1.1 chopps } 2539 1.16 chopps SBIC_TRACE(dev); 2540 1.14 chopps return SBIC_STATE_ERROR; 2541 1.1 chopps } 2542 1.14 chopps 2543 1.16 chopps SBIC_TRACE(dev); 2544 1.14 chopps return(SBIC_STATE_RUNNING); 2545 1.1 chopps } 2546 1.1 chopps 2547 1.14 chopps 2548 1.1 chopps /* 2549 1.1 chopps * Check if DMA can not be used with specified buffer 2550 1.1 chopps */ 2551 1.1 chopps 2552 1.1 chopps int 2553 1.45 aymeric sbiccheckdmap(void *bp, u_long len, u_long mask) 2554 1.1 chopps { 2555 1.1 chopps u_char *buffer; 2556 1.1 chopps u_long phy_buf; 2557 1.1 chopps u_long phy_len; 2558 1.1 chopps 2559 1.1 chopps buffer = bp; 2560 1.1 chopps 2561 1.1 chopps if (len == 0) 2562 1.1 chopps return(0); 2563 1.1 chopps 2564 1.1 chopps while (len) { 2565 1.1 chopps phy_buf = kvtop(buffer); 2566 1.50 thorpej if (len < (phy_len = PAGE_SIZE - ((int) buffer & PGOFSET))) 2567 1.1 chopps phy_len = len; 2568 1.1 chopps if (phy_buf & mask) 2569 1.1 chopps return(1); 2570 1.1 chopps buffer += phy_len; 2571 1.1 chopps len -= phy_len; 2572 1.1 chopps } 2573 1.1 chopps return(0); 2574 1.1 chopps } 2575 1.1 chopps 2576 1.13 mycroft int 2577 1.45 aymeric sbictoscsiperiod(struct sbic_softc *dev, sbic_regmap_t regs, int a) 2578 1.1 chopps { 2579 1.1 chopps unsigned int fs; 2580 1.13 mycroft 2581 1.1 chopps /* 2582 1.1 chopps * cycle = DIV / (2*CLK) 2583 1.1 chopps * DIV = FS+2 2584 1.57 lukem * best we can do is 200ns at 20 MHz, 2 cycles 2585 1.1 chopps */ 2586 1.13 mycroft 2587 1.1 chopps GET_SBIC_myid(regs,fs); 2588 1.1 chopps fs = (fs >>6) + 2; /* DIV */ 2589 1.1 chopps fs = (fs * 10000) / (dev->sc_clkfreq<<1); /* Cycle, in ns */ 2590 1.1 chopps if (a < 2) a = 8; /* map to Cycles */ 2591 1.1 chopps return ((fs*a)>>2); /* in 4 ns units */ 2592 1.1 chopps } 2593 1.1 chopps 2594 1.13 mycroft int 2595 1.45 aymeric sbicfromscsiperiod(struct sbic_softc *dev, sbic_regmap_t regs, int p) 2596 1.1 chopps { 2597 1.1 chopps register unsigned int fs, ret; 2598 1.13 mycroft 2599 1.1 chopps /* Just the inverse of the above */ 2600 1.13 mycroft 2601 1.1 chopps GET_SBIC_myid(regs,fs); 2602 1.1 chopps fs = (fs >>6) + 2; /* DIV */ 2603 1.1 chopps fs = (fs * 10000) / (dev->sc_clkfreq<<1); /* Cycle, in ns */ 2604 1.13 mycroft 2605 1.1 chopps ret = p << 2; /* in ns units */ 2606 1.1 chopps ret = ret / fs; /* in Cycles */ 2607 1.1 chopps if (ret < sbic_min_period) 2608 1.1 chopps return(sbic_min_period); 2609 1.1 chopps 2610 1.1 chopps /* verify rounding */ 2611 1.1 chopps if (sbictoscsiperiod(dev, regs, ret) < p) 2612 1.1 chopps ret++; 2613 1.1 chopps return (ret >= 8) ? 0 : ret; 2614 1.1 chopps } 2615 1.1 chopps 2616 1.14 chopps #ifdef DEBUG 2617 1.14 chopps 2618 1.23 veego void 2619 1.45 aymeric sbicdumpstate(void) 2620 1.14 chopps { 2621 1.14 chopps u_char csr, asr; 2622 1.14 chopps 2623 1.14 chopps GET_SBIC_asr(debug_sbic_regs,asr); 2624 1.14 chopps GET_SBIC_csr(debug_sbic_regs,csr); 2625 1.28 christos printf("%s: asr:csr(%02x:%02x)->(%02x:%02x)\n", 2626 1.14 chopps (routine==1)?"sbicgo": 2627 1.14 chopps (routine==2)?"sbicintr": 2628 1.14 chopps (routine==3)?"sbicicmd": 2629 1.14 chopps (routine==4)?"sbicnext":"unknown", 2630 1.14 chopps debug_asr, debug_csr, asr, csr); 2631 1.14 chopps 2632 1.14 chopps } 2633 1.14 chopps 2634 1.23 veego void 2635 1.45 aymeric sbictimeout(struct sbic_softc *dev) 2636 1.14 chopps { 2637 1.14 chopps int s, asr; 2638 1.14 chopps 2639 1.16 chopps s = splbio(); 2640 1.16 chopps if (dev->sc_dmatimo) { 2641 1.16 chopps if (dev->sc_dmatimo > 1) { 2642 1.51 wiz printf("%s: DMA timeout #%d\n", 2643 1.71 chs device_xname(dev->sc_dev), dev->sc_dmatimo - 1); 2644 1.33 is GET_SBIC_asr(dev->sc_sbic, asr); 2645 1.75 christos if (asr & SBIC_ASR_INT) { 2646 1.16 chopps /* We need to service a missed IRQ */ 2647 1.47 thorpej printf("Servicing a missed int:(%02x,%02x)->(%02x,?)\n", 2648 1.16 chopps debug_asr, debug_csr, asr); 2649 1.16 chopps sbicintr(dev); 2650 1.16 chopps } 2651 1.16 chopps sbicdumpstate(); 2652 1.16 chopps } 2653 1.16 chopps dev->sc_dmatimo++; 2654 1.16 chopps } 2655 1.16 chopps splx(s); 2656 1.39 thorpej callout_reset(&dev->sc_timo_ch, 30 * hz, 2657 1.39 thorpej (void *)sbictimeout, dev); 2658 1.16 chopps } 2659 1.16 chopps 2660 1.16 chopps void 2661 1.45 aymeric sbic_dump_acb(struct sbic_acb *acb) 2662 1.16 chopps { 2663 1.16 chopps u_char *b = (u_char *) &acb->cmd; 2664 1.16 chopps int i; 2665 1.16 chopps 2666 1.28 christos printf("acb@%p ", acb); 2667 1.16 chopps if (acb->xs == NULL) { 2668 1.28 christos printf("<unused>\n"); 2669 1.16 chopps return; 2670 1.16 chopps } 2671 1.29 bouyer printf("(%d:%d) flags %2x clen %2d cmd ", 2672 1.43 bouyer acb->xs->xs_periph->periph_target, 2673 1.43 bouyer acb->xs->xs_periph->periph_lun, acb->flags, acb->clen); 2674 1.16 chopps for (i = acb->clen; i; --i) 2675 1.28 christos printf(" %02x", *b++); 2676 1.28 christos printf("\n"); 2677 1.28 christos printf(" xs: %8p data %8p:%04x ", acb->xs, acb->xs->data, 2678 1.16 chopps acb->xs->datalen); 2679 1.28 christos printf("va %8p:%04x ", acb->sc_kv.dc_addr, acb->sc_kv.dc_count); 2680 1.28 christos printf("pa %8p:%04x tcnt %lx\n", acb->sc_pa.dc_addr, acb->sc_pa.dc_count, 2681 1.16 chopps acb->sc_tcnt); 2682 1.16 chopps } 2683 1.16 chopps 2684 1.16 chopps void 2685 1.45 aymeric sbic_dump(struct sbic_softc *dev) 2686 1.16 chopps { 2687 1.33 is sbic_regmap_t regs; 2688 1.16 chopps u_char csr, asr; 2689 1.16 chopps struct sbic_acb *acb; 2690 1.16 chopps int s; 2691 1.16 chopps int i; 2692 1.16 chopps 2693 1.16 chopps s = splbio(); 2694 1.33 is regs = dev->sc_sbic; 2695 1.16 chopps #if CSR_TRACE_SIZE 2696 1.28 christos printf("csr trace: "); 2697 1.16 chopps i = csr_traceptr; 2698 1.16 chopps do { 2699 1.28 christos printf("%c%02x%02x%02x ", csr_trace[i].whr, 2700 1.16 chopps csr_trace[i].csr, csr_trace[i].asr, csr_trace[i].xtn); 2701 1.16 chopps switch(csr_trace[i].whr) { 2702 1.16 chopps case 'g': 2703 1.28 christos printf("go "); break; 2704 1.16 chopps case 's': 2705 1.28 christos printf("select "); break; 2706 1.16 chopps case 'y': 2707 1.28 christos printf("select+ "); break; 2708 1.16 chopps case 'i': 2709 1.28 christos printf("intr "); break; 2710 1.16 chopps case 'f': 2711 1.28 christos printf("finish "); break; 2712 1.16 chopps case '>': 2713 1.28 christos printf("out "); break; 2714 1.16 chopps case '<': 2715 1.28 christos printf("in "); break; 2716 1.16 chopps case 'm': 2717 1.28 christos printf("msgin "); break; 2718 1.16 chopps case 'x': 2719 1.28 christos printf("msginx "); break; 2720 1.16 chopps case 'X': 2721 1.28 christos printf("msginX "); break; 2722 1.16 chopps case 'r': 2723 1.28 christos printf("reselect "); break; 2724 1.16 chopps case 'I': 2725 1.28 christos printf("icmd "); break; 2726 1.16 chopps case 'a': 2727 1.28 christos printf("abort "); break; 2728 1.16 chopps default: 2729 1.28 christos printf("? "); 2730 1.16 chopps } 2731 1.16 chopps switch(csr_trace[i].csr) { 2732 1.16 chopps case 0x11: 2733 1.28 christos printf("INITIATOR"); break; 2734 1.16 chopps case 0x16: 2735 1.28 christos printf("S_XFERRED"); break; 2736 1.16 chopps case 0x20: 2737 1.28 christos printf("MSGIN_ACK"); break; 2738 1.16 chopps case 0x41: 2739 1.28 christos printf("DISC"); break; 2740 1.16 chopps case 0x42: 2741 1.28 christos printf("SEL_TIMEO"); break; 2742 1.16 chopps case 0x80: 2743 1.28 christos printf("RSLT_NI"); break; 2744 1.16 chopps case 0x81: 2745 1.28 christos printf("RSLT_IFY"); break; 2746 1.16 chopps case 0x85: 2747 1.28 christos printf("DISC_1"); break; 2748 1.16 chopps case 0x18: case 0x19: case 0x1a: 2749 1.16 chopps case 0x1b: case 0x1e: case 0x1f: 2750 1.16 chopps case 0x28: case 0x29: case 0x2a: 2751 1.16 chopps case 0x2b: case 0x2e: case 0x2f: 2752 1.16 chopps case 0x48: case 0x49: case 0x4a: 2753 1.16 chopps case 0x4b: case 0x4e: case 0x4f: 2754 1.16 chopps case 0x88: case 0x89: case 0x8a: 2755 1.16 chopps case 0x8b: case 0x8e: case 0x8f: 2756 1.16 chopps switch(csr_trace[i].csr & 0xf0) { 2757 1.16 chopps case 0x10: 2758 1.28 christos printf("DONE_"); break; 2759 1.16 chopps case 0x20: 2760 1.28 christos printf("STOP_"); break; 2761 1.16 chopps case 0x40: 2762 1.28 christos printf("ERR_"); break; 2763 1.16 chopps case 0x80: 2764 1.28 christos printf("REQ_"); break; 2765 1.16 chopps } 2766 1.16 chopps switch(csr_trace[i].csr & 7) { 2767 1.16 chopps case 0: 2768 1.28 christos printf("DATA_OUT"); break; 2769 1.16 chopps case 1: 2770 1.28 christos printf("DATA_IN"); break; 2771 1.16 chopps case 2: 2772 1.28 christos printf("CMD"); break; 2773 1.16 chopps case 3: 2774 1.28 christos printf("STATUS"); break; 2775 1.16 chopps case 6: 2776 1.28 christos printf("MSG_OUT"); break; 2777 1.16 chopps case 7: 2778 1.28 christos printf("MSG_IN"); break; 2779 1.16 chopps default: 2780 1.28 christos printf("invld phs"); 2781 1.16 chopps } 2782 1.16 chopps break; 2783 1.28 christos default: printf("****"); break; 2784 1.16 chopps } 2785 1.16 chopps if (csr_trace[i].asr & SBIC_ASR_INT) 2786 1.28 christos printf(" ASR_INT"); 2787 1.16 chopps if (csr_trace[i].asr & SBIC_ASR_LCI) 2788 1.28 christos printf(" ASR_LCI"); 2789 1.16 chopps if (csr_trace[i].asr & SBIC_ASR_BSY) 2790 1.28 christos printf(" ASR_BSY"); 2791 1.16 chopps if (csr_trace[i].asr & SBIC_ASR_CIP) 2792 1.28 christos printf(" ASR_CIP"); 2793 1.28 christos printf("\n"); 2794 1.16 chopps i = (i + 1) & (CSR_TRACE_SIZE - 1); 2795 1.16 chopps } while (i != csr_traceptr); 2796 1.16 chopps #endif 2797 1.16 chopps GET_SBIC_asr(regs, asr); 2798 1.16 chopps if ((asr & SBIC_ASR_INT) == 0) 2799 1.16 chopps GET_SBIC_csr(regs, csr); 2800 1.16 chopps else 2801 1.16 chopps csr = 0; 2802 1.71 chs printf("%s@%p regs %p/%p asr %x csr %x\n", device_xname(dev->sc_dev), 2803 1.36 is dev, regs.sbic_asr_p, regs.sbic_value_p, asr, csr); 2804 1.23 veego if ((acb = dev->free_list.tqh_first)) { 2805 1.28 christos printf("Free list:\n"); 2806 1.16 chopps while (acb) { 2807 1.16 chopps sbic_dump_acb(acb); 2808 1.16 chopps acb = acb->chain.tqe_next; 2809 1.16 chopps } 2810 1.16 chopps } 2811 1.23 veego if ((acb = dev->ready_list.tqh_first)) { 2812 1.28 christos printf("Ready list:\n"); 2813 1.16 chopps while (acb) { 2814 1.16 chopps sbic_dump_acb(acb); 2815 1.16 chopps acb = acb->chain.tqe_next; 2816 1.16 chopps } 2817 1.16 chopps } 2818 1.23 veego if ((acb = dev->nexus_list.tqh_first)) { 2819 1.28 christos printf("Nexus list:\n"); 2820 1.16 chopps while (acb) { 2821 1.16 chopps sbic_dump_acb(acb); 2822 1.16 chopps acb = acb->chain.tqe_next; 2823 1.16 chopps } 2824 1.16 chopps } 2825 1.16 chopps if (dev->sc_nexus) { 2826 1.28 christos printf("nexus:\n"); 2827 1.16 chopps sbic_dump_acb(dev->sc_nexus); 2828 1.16 chopps } 2829 1.28 christos printf("sc_xs %p targ %d lun %d flags %x tcnt %lx dmacmd %x mask %lx\n", 2830 1.16 chopps dev->sc_xs, dev->target, dev->lun, dev->sc_flags, dev->sc_tcnt, 2831 1.16 chopps dev->sc_dmacmd, dev->sc_dmamask); 2832 1.16 chopps for (i = 0; i < 8; ++i) { 2833 1.16 chopps if (dev->sc_tinfo[i].cmds > 2) { 2834 1.43 bouyer printf("tgt %d: cmds %d disc %d lubusy %x\n", 2835 1.16 chopps i, dev->sc_tinfo[i].cmds, 2836 1.16 chopps dev->sc_tinfo[i].dconns, 2837 1.16 chopps dev->sc_tinfo[i].lubusy); 2838 1.14 chopps } 2839 1.16 chopps } 2840 1.16 chopps splx(s); 2841 1.14 chopps } 2842 1.14 chopps 2843 1.14 chopps #endif 2844