1 /* $NetBSD: ninjascsi32.c,v 1.28 2021/08/07 16:19:12 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2004, 2006, 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by ITOH Yasufumi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: ninjascsi32.c,v 1.28 2021/08/07 16:19:12 thorpej Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/callout.h> 38 #include <sys/device.h> 39 #include <sys/kernel.h> 40 #include <sys/buf.h> 41 #include <sys/scsiio.h> 42 #include <sys/proc.h> 43 44 #include <sys/bus.h> 45 #include <sys/intr.h> 46 47 #include <dev/scsipi/scsi_all.h> 48 #include <dev/scsipi/scsipi_all.h> 49 #include <dev/scsipi/scsiconf.h> 50 #include <dev/scsipi/scsi_message.h> 51 52 /* 53 * DualEdge transfer support 54 */ 55 /* #define NJSC32_DUALEDGE */ /* XXX untested */ 56 57 /* 58 * Auto param loading does not work properly (it partially works (works on 59 * start, doesn't on restart) on rev 0x54, it doesn't work at all on rev 0x51), 60 * and it doesn't improve the performance so much, 61 * forget about it. 62 */ 63 #undef NJSC32_AUTOPARAM 64 65 #include <dev/ic/ninjascsi32reg.h> 66 #include <dev/ic/ninjascsi32var.h> 67 68 /* #define NJSC32_DEBUG */ 69 /* #define NJSC32_TRACE */ 70 71 #ifdef NJSC32_DEBUG 72 #define DPRINTF(x) printf x 73 #define DPRINTC(cmd, x) PRINTC(cmd, x) 74 #else 75 #define DPRINTF(x) 76 #define DPRINTC(cmd, x) 77 #endif 78 #ifdef NJSC32_TRACE 79 #define TPRINTF(x) printf x 80 #define TPRINTC(cmd, x) PRINTC(cmd, x) 81 #else 82 #define TPRINTF(x) 83 #define TPRINTC(cmd, x) 84 #endif 85 86 #define PRINTC(cmd, x) do { \ 87 scsi_print_addr((cmd)->c_xs->xs_periph); \ 88 printf x; \ 89 } while (/* CONSTCOND */ 0) 90 91 static void njsc32_scsipi_request(struct scsipi_channel *, 92 scsipi_adapter_req_t, void *); 93 static void njsc32_scsipi_minphys(struct buf *); 94 static int njsc32_scsipi_ioctl(struct scsipi_channel *, u_long, void *, 95 int, struct proc *); 96 97 static void njsc32_init(struct njsc32_softc *, int nosleep); 98 static int njsc32_init_cmds(struct njsc32_softc *); 99 static void njsc32_target_async(struct njsc32_softc *, 100 struct njsc32_target *); 101 static void njsc32_init_targets(struct njsc32_softc *); 102 static void njsc32_add_msgout(struct njsc32_softc *, int); 103 static u_int32_t njsc32_get_auto_msgout(struct njsc32_softc *); 104 #ifdef NJSC32_DUALEDGE 105 static void njsc32_msgout_wdtr(struct njsc32_softc *, int); 106 #endif 107 static void njsc32_msgout_sdtr(struct njsc32_softc *, int period, 108 int offset); 109 static void njsc32_negotiate_xfer(struct njsc32_softc *, 110 struct njsc32_target *); 111 static void njsc32_arbitration_failed(struct njsc32_softc *); 112 static void njsc32_start(struct njsc32_softc *); 113 static void njsc32_run_xfer(struct njsc32_softc *, struct scsipi_xfer *); 114 static void njsc32_end_cmd(struct njsc32_softc *, struct njsc32_cmd *, 115 scsipi_xfer_result_t); 116 static void njsc32_wait_reset_release(void *); 117 static void njsc32_reset_bus(struct njsc32_softc *); 118 static void njsc32_clear_cmds(struct njsc32_softc *, 119 scsipi_xfer_result_t); 120 static void njsc32_set_ptr(struct njsc32_softc *, struct njsc32_cmd *, 121 u_int32_t); 122 static void njsc32_assert_ack(struct njsc32_softc *); 123 static void njsc32_negate_ack(struct njsc32_softc *); 124 static void njsc32_wait_req_negate(struct njsc32_softc *); 125 static void njsc32_reconnect(struct njsc32_softc *, struct njsc32_cmd *); 126 enum njsc32_reselstat { 127 NJSC32_RESEL_ERROR, /* to be rejected */ 128 NJSC32_RESEL_COMPLETE, /* reselection is just complete */ 129 NJSC32_RESEL_THROUGH /* this message is OK (no reply) */ 130 }; 131 static enum njsc32_reselstat njsc32_resel_identify(struct njsc32_softc *, 132 int lun, struct njsc32_cmd **); 133 static enum njsc32_reselstat njsc32_resel_tag(struct njsc32_softc *, 134 int tag, struct njsc32_cmd **); 135 static void njsc32_cmd_reload(struct njsc32_softc *, struct njsc32_cmd *, 136 int); 137 static void njsc32_update_xfer_mode(struct njsc32_softc *, 138 struct njsc32_target *); 139 static void njsc32_msgin(struct njsc32_softc *); 140 static void njsc32_msgout(struct njsc32_softc *); 141 static void njsc32_cmdtimeout(void *); 142 static void njsc32_reseltimeout(void *); 143 144 static inline unsigned 145 njsc32_read_1(struct njsc32_softc *sc, int no) 146 { 147 148 return bus_space_read_1(sc->sc_regt, sc->sc_regh, no); 149 } 150 151 static inline unsigned 152 njsc32_read_2(struct njsc32_softc *sc, int no) 153 { 154 155 return bus_space_read_2(sc->sc_regt, sc->sc_regh, no); 156 } 157 158 static inline u_int32_t 159 njsc32_read_4(struct njsc32_softc *sc, int no) 160 { 161 162 return bus_space_read_4(sc->sc_regt, sc->sc_regh, no); 163 } 164 165 static inline void 166 njsc32_write_1(struct njsc32_softc *sc, int no, int val) 167 { 168 169 bus_space_write_1(sc->sc_regt, sc->sc_regh, no, val); 170 } 171 172 static inline void 173 njsc32_write_2(struct njsc32_softc *sc, int no, int val) 174 { 175 176 bus_space_write_2(sc->sc_regt, sc->sc_regh, no, val); 177 } 178 179 static inline void 180 njsc32_write_4(struct njsc32_softc *sc, int no, u_int32_t val) 181 { 182 183 bus_space_write_4(sc->sc_regt, sc->sc_regh, no, val); 184 } 185 186 static inline unsigned 187 njsc32_ireg_read_1(struct njsc32_softc *sc, int no) 188 { 189 190 bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no); 191 return bus_space_read_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW); 192 } 193 194 static inline void 195 njsc32_ireg_write_1(struct njsc32_softc *sc, int no, int val) 196 { 197 198 bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no); 199 bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW, val); 200 } 201 202 static inline void 203 njsc32_ireg_write_2(struct njsc32_softc *sc, int no, int val) 204 { 205 206 bus_space_write_1(sc->sc_regt, sc->sc_regh, NJSC32_REG_INDEX, no); 207 bus_space_write_2(sc->sc_regt, sc->sc_regh, NJSC32_REG_DATA_LOW, val); 208 } 209 210 #define NS(ns) ((ns) / 4) /* nanosecond (>= 50) -> sync value */ 211 #ifdef __STDC__ 212 # define ACKW(n) NJSC32_ACK_WIDTH_ ## n ## CLK 213 # define SMPL(n) (NJSC32_SREQ_SAMPLING_ ## n ## CLK | \ 214 NJSC32_SREQ_SAMPLING_ENABLE) 215 #else 216 # define ACKW(n) NJSC32_ACK_WIDTH_/**/n/**/CLK 217 # define SMPL(n) (NJSC32_SREQ_SAMPLING_/**/n/**/CLK | \ 218 NJSC32_SREQ_SAMPLING_ENABLE) 219 #endif 220 221 #define NJSC32_NSYNCT_MAXSYNC 1 222 #define NJSC32_NSYNCT 16 223 224 /* 40MHz (25ns) */ 225 static const struct njsc32_sync_param njsc32_synct_40M[NJSC32_NSYNCT] = { 226 { 0, 0, 0 }, /* dummy for async */ 227 { NS( 50), ACKW(1), 0 }, /* 20.0 : 50ns, 25ns */ 228 { NS( 75), ACKW(1), SMPL(1) }, /* 13.3 : 75ns, 25ns */ 229 { NS(100), ACKW(2), SMPL(1) }, /* 10.0 : 100ns, 50ns */ 230 { NS(125), ACKW(2), SMPL(2) }, /* 8.0 : 125ns, 50ns */ 231 { NS(150), ACKW(3), SMPL(2) }, /* 6.7 : 150ns, 75ns */ 232 { NS(175), ACKW(3), SMPL(2) }, /* 5.7 : 175ns, 75ns */ 233 { NS(200), ACKW(4), SMPL(2) }, /* 5.0 : 200ns, 100ns */ 234 { NS(225), ACKW(4), SMPL(4) }, /* 4.4 : 225ns, 100ns */ 235 { NS(250), ACKW(4), SMPL(4) }, /* 4.0 : 250ns, 100ns */ 236 { NS(275), ACKW(4), SMPL(4) }, /* 3.64: 275ns, 100ns */ 237 { NS(300), ACKW(4), SMPL(4) }, /* 3.33: 300ns, 100ns */ 238 { NS(325), ACKW(4), SMPL(4) }, /* 3.01: 325ns, 100ns */ 239 { NS(350), ACKW(4), SMPL(4) }, /* 2.86: 350ns, 100ns */ 240 { NS(375), ACKW(4), SMPL(4) }, /* 2.67: 375ns, 100ns */ 241 { NS(400), ACKW(4), SMPL(4) } /* 2.50: 400ns, 100ns */ 242 }; 243 244 #ifdef NJSC32_SUPPORT_OTHER_CLOCKS 245 /* 20MHz (50ns) */ 246 static const struct njsc32_sync_param njsc32_synct_20M[NJSC32_NSYNCT] = { 247 { 0, 0, 0 }, /* dummy for async */ 248 { NS(100), ACKW(1), 0 }, /* 10.0 : 100ns, 50ns */ 249 { NS(150), ACKW(1), SMPL(2) }, /* 6.7 : 150ns, 50ns */ 250 { NS(200), ACKW(2), SMPL(2) }, /* 5.0 : 200ns, 100ns */ 251 { NS(250), ACKW(2), SMPL(4) }, /* 4.0 : 250ns, 100ns */ 252 { NS(300), ACKW(3), SMPL(4) }, /* 3.3 : 300ns, 150ns */ 253 { NS(350), ACKW(3), SMPL(4) }, /* 2.8 : 350ns, 150ns */ 254 { NS(400), ACKW(4), SMPL(4) }, /* 2.5 : 400ns, 200ns */ 255 { NS(450), ACKW(4), SMPL(4) }, /* 2.2 : 450ns, 200ns */ 256 { NS(500), ACKW(4), SMPL(4) }, /* 2.0 : 500ns, 200ns */ 257 { NS(550), ACKW(4), SMPL(4) }, /* 1.82: 550ns, 200ns */ 258 { NS(600), ACKW(4), SMPL(4) }, /* 1.67: 600ns, 200ns */ 259 { NS(650), ACKW(4), SMPL(4) }, /* 1.54: 650ns, 200ns */ 260 { NS(700), ACKW(4), SMPL(4) }, /* 1.43: 700ns, 200ns */ 261 { NS(750), ACKW(4), SMPL(4) }, /* 1.33: 750ns, 200ns */ 262 { NS(800), ACKW(4), SMPL(4) } /* 1.25: 800ns, 200ns */ 263 }; 264 265 /* 33.3MHz (30ns) */ 266 static const struct njsc32_sync_param njsc32_synct_pci[NJSC32_NSYNCT] = { 267 { 0, 0, 0 }, /* dummy for async */ 268 { NS( 60), ACKW(1), 0 }, /* 16.6 : 60ns, 30ns */ 269 { NS( 90), ACKW(1), SMPL(1) }, /* 11.1 : 90ns, 30ns */ 270 { NS(120), ACKW(2), SMPL(2) }, /* 8.3 : 120ns, 60ns */ 271 { NS(150), ACKW(2), SMPL(2) }, /* 6.7 : 150ns, 60ns */ 272 { NS(180), ACKW(3), SMPL(2) }, /* 5.6 : 180ns, 90ns */ 273 { NS(210), ACKW(3), SMPL(4) }, /* 4.8 : 210ns, 90ns */ 274 { NS(240), ACKW(4), SMPL(4) }, /* 4.2 : 240ns, 120ns */ 275 { NS(270), ACKW(4), SMPL(4) }, /* 3.7 : 270ns, 120ns */ 276 { NS(300), ACKW(4), SMPL(4) }, /* 3.3 : 300ns, 120ns */ 277 { NS(330), ACKW(4), SMPL(4) }, /* 3.0 : 330ns, 120ns */ 278 { NS(360), ACKW(4), SMPL(4) }, /* 2.8 : 360ns, 120ns */ 279 { NS(390), ACKW(4), SMPL(4) }, /* 2.6 : 390ns, 120ns */ 280 { NS(420), ACKW(4), SMPL(4) }, /* 2.4 : 420ns, 120ns */ 281 { NS(450), ACKW(4), SMPL(4) }, /* 2.2 : 450ns, 120ns */ 282 { NS(480), ACKW(4), SMPL(4) } /* 2.1 : 480ns, 120ns */ 283 }; 284 #endif /* NJSC32_SUPPORT_OTHER_CLOCKS */ 285 286 #undef NS 287 #undef ACKW 288 #undef SMPL 289 290 /* initialize device */ 291 static void 292 njsc32_init(struct njsc32_softc *sc, int nosleep) 293 { 294 u_int16_t intstat; 295 int i; 296 297 /* block all interrupts */ 298 njsc32_write_2(sc, NJSC32_REG_IRQ, NJSC32_IRQ_MASK_ALL); 299 300 /* clear transfer */ 301 njsc32_write_2(sc, NJSC32_REG_TRANSFER, 0); 302 njsc32_write_4(sc, NJSC32_REG_BM_CNT, 0); 303 304 /* make sure interrupts are cleared */ 305 for (i = 0; ((intstat = njsc32_read_2(sc, NJSC32_REG_IRQ)) 306 & NJSC32_IRQ_INTR_PENDING) && i < 5 /* just not forever */; i++) { 307 DPRINTF(("%s: njsc32_init: intr pending: %#x\n", 308 device_xname(sc->sc_dev), intstat)); 309 } 310 311 /* FIFO threshold */ 312 njsc32_ireg_write_1(sc, NJSC32_IREG_FIFO_THRESHOLD_FULL, 313 NJSC32_FIFO_FULL_BUSMASTER); 314 njsc32_ireg_write_1(sc, NJSC32_IREG_FIFO_THRESHOLD_EMPTY, 315 NJSC32_FIFO_EMPTY_BUSMASTER); 316 317 /* clock source */ 318 njsc32_ireg_write_1(sc, NJSC32_IREG_CLOCK, sc->sc_clk); 319 320 /* memory read multiple */ 321 njsc32_ireg_write_1(sc, NJSC32_IREG_BM, 322 NJSC32_BM_MEMRD_CMD1 | NJSC32_BM_SGT_AUTO_PARA_MEMRD_CMD); 323 324 /* clear parity error and enable parity detection */ 325 njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL, 326 NJSC32_PARITYCTL_CHECK_ENABLE | NJSC32_PARITYCTL_CLEAR_ERROR); 327 328 /* misc configuration */ 329 njsc32_ireg_write_2(sc, NJSC32_IREG_MISC, 330 NJSC32_MISC_SCSI_DIRECTION_DETECTOR_SELECT | 331 NJSC32_MISC_DELAYED_BMSTART | 332 NJSC32_MISC_MASTER_TERMINATION_SELECT | 333 NJSC32_MISC_BMREQ_NEGATE_TIMING_SEL | 334 NJSC32_MISC_AUTOSEL_TIMING_SEL | 335 NJSC32_MISC_BMSTOP_CHANGE2_NONDATA_PHASE); 336 337 /* 338 * Check for termination power (32Bi and some versions of 32UDE). 339 */ 340 if (!nosleep || cold) { 341 DPRINTF(("%s: njsc32_init: checking TERMPWR\n", 342 device_xname(sc->sc_dev))); 343 344 /* First, turn termination power off */ 345 njsc32_ireg_write_1(sc, NJSC32_IREG_TERM_PWR, 0); 346 347 /* give 0.5s to settle */ 348 if (nosleep) 349 delay(500000); 350 else 351 tsleep(sc, PWAIT, "njs_t1", hz / 2); 352 } 353 354 /* supply termination power if not supplied by other devices */ 355 if ((njsc32_ireg_read_1(sc, NJSC32_IREG_TERM_PWR) & 356 NJSC32_TERMPWR_SENSE) == 0) { 357 /* termination power is not present on the bus */ 358 if (sc->sc_flags & NJSC32_CANNOT_SUPPLY_TERMPWR) { 359 /* 360 * CardBus device must not supply termination power 361 * to avoid excessive power consumption. 362 */ 363 printf("%s: no termination power present\n", 364 device_xname(sc->sc_dev)); 365 } else { 366 /* supply termination power */ 367 njsc32_ireg_write_1(sc, NJSC32_IREG_TERM_PWR, 368 NJSC32_TERMPWR_BPWR); 369 370 DPRINTF(("%s: supplying termination power\n", 371 device_xname(sc->sc_dev))); 372 373 /* give 0.5s to settle */ 374 if (!nosleep) 375 tsleep(sc, PWAIT, "njs_t2", hz / 2); 376 } 377 } 378 379 /* stop timer */ 380 njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_TIMER_STOP); 381 njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_TIMER_STOP); 382 383 /* default transfer parameter */ 384 njsc32_write_1(sc, NJSC32_REG_SYNC, 0); 385 njsc32_write_1(sc, NJSC32_REG_ACK_WIDTH, NJSC32_ACK_WIDTH_1CLK); 386 njsc32_write_2(sc, NJSC32_REG_SEL_TIMEOUT, 387 NJSC32_SEL_TIMEOUT_TIME); 388 389 /* select interrupt source */ 390 njsc32_ireg_write_2(sc, NJSC32_IREG_IRQ_SELECT, 391 NJSC32_IRQSEL_RESELECT | 392 NJSC32_IRQSEL_PHASE_CHANGE | 393 NJSC32_IRQSEL_SCSIRESET | 394 NJSC32_IRQSEL_TIMER | 395 NJSC32_IRQSEL_FIFO_THRESHOLD | 396 NJSC32_IRQSEL_TARGET_ABORT | 397 NJSC32_IRQSEL_MASTER_ABORT | 398 /* XXX not yet 399 NJSC32_IRQSEL_SERR | 400 NJSC32_IRQSEL_PERR | 401 NJSC32_IRQSEL_BMCNTERR | 402 */ 403 NJSC32_IRQSEL_AUTO_SCSI_SEQ); 404 405 /* interrupts will be unblocked later after bus reset */ 406 407 /* turn LED off */ 408 njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT_DDR, 409 NJSC32_EXTPORT_LED_OFF); 410 njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT, 411 NJSC32_EXTPORT_LED_OFF); 412 413 /* reset SCSI bus so the targets become known state */ 414 njsc32_reset_bus(sc); 415 } 416 417 static int 418 njsc32_init_cmds(struct njsc32_softc *sc) 419 { 420 struct njsc32_cmd *cmd; 421 bus_addr_t dmaaddr; 422 int i, error; 423 424 /* 425 * allocate DMA area for command 426 */ 427 if ((error = bus_dmamem_alloc(sc->sc_dmat, 428 sizeof(struct njsc32_dma_page), PAGE_SIZE, 0, 429 &sc->sc_cmdpg_seg, 1, &sc->sc_cmdpg_nsegs, BUS_DMA_NOWAIT)) != 0) { 430 aprint_error_dev(sc->sc_dev, 431 "unable to allocate cmd page, error = %d\n", 432 error); 433 return 0; 434 } 435 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmdpg_seg, 436 sc->sc_cmdpg_nsegs, sizeof(struct njsc32_dma_page), 437 (void **)&sc->sc_cmdpg, 438 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 439 aprint_error_dev(sc->sc_dev, 440 "unable to map cmd page, error = %d\n", 441 error); 442 goto fail1; 443 } 444 if ((error = bus_dmamap_create(sc->sc_dmat, 445 sizeof(struct njsc32_dma_page), 1, 446 sizeof(struct njsc32_dma_page), 0, BUS_DMA_NOWAIT, 447 &sc->sc_dmamap_cmdpg)) != 0) { 448 aprint_error_dev(sc->sc_dev, 449 "unable to create cmd DMA map, error = %d\n", 450 error); 451 goto fail2; 452 } 453 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_cmdpg, 454 sc->sc_cmdpg, sizeof(struct njsc32_dma_page), 455 NULL, BUS_DMA_NOWAIT)) != 0) { 456 aprint_error_dev(sc->sc_dev, 457 "unable to load cmd DMA map, error = %d\n", 458 error); 459 goto fail3; 460 } 461 462 memset(sc->sc_cmdpg, 0, sizeof(struct njsc32_dma_page)); 463 dmaaddr = sc->sc_dmamap_cmdpg->dm_segs[0].ds_addr; 464 465 #ifdef NJSC32_AUTOPARAM 466 sc->sc_ap_dma = dmaaddr + offsetof(struct njsc32_dma_page, dp_ap); 467 #endif 468 469 for (i = 0; i < NJSC32_NUM_CMD; i++) { 470 cmd = &sc->sc_cmds[i]; 471 cmd->c_sc = sc; 472 cmd->c_sgt = sc->sc_cmdpg->dp_sg[i]; 473 cmd->c_sgt_dma = dmaaddr + 474 offsetof(struct njsc32_dma_page, dp_sg[i]); 475 cmd->c_flags = 0; 476 477 error = bus_dmamap_create(sc->sc_dmat, 478 NJSC32_MAX_XFER, /* max total map size */ 479 NJSC32_NUM_SG, /* max number of segments */ 480 NJSC32_SGT_MAXSEGLEN, /* max size of a segment */ 481 0, /* boundary */ 482 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &cmd->c_dmamap_xfer); 483 if (error) { 484 aprint_error_dev(sc->sc_dev, 485 "only %d cmd descs available (error = %d)\n", 486 i, error); 487 break; 488 } 489 TAILQ_INSERT_TAIL(&sc->sc_freecmd, cmd, c_q); 490 } 491 492 if (i > 0) 493 return i; 494 495 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_cmdpg); 496 fail3: bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_cmdpg); 497 fail2: bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_cmdpg, 498 sizeof(struct njsc32_dma_page)); 499 fail1: bus_dmamem_free(sc->sc_dmat, &sc->sc_cmdpg_seg, sc->sc_cmdpg_nsegs); 500 501 return 0; 502 } 503 504 static void 505 njsc32_target_async(struct njsc32_softc *sc, struct njsc32_target *target) 506 { 507 508 target->t_sync = 509 NJSC32_SYNC_VAL(sc->sc_sync_max, NJSC32_SYNCOFFSET_ASYNC); 510 target->t_ackwidth = NJSC32_ACK_WIDTH_1CLK; 511 target->t_sample = 0; /* disable */ 512 target->t_syncoffset = NJSC32_SYNCOFFSET_ASYNC; 513 target->t_syncperiod = NJSC32_SYNCPERIOD_ASYNC; 514 } 515 516 static void 517 njsc32_init_targets(struct njsc32_softc *sc) 518 { 519 int id, lun; 520 struct njsc32_lu *lu; 521 522 for (id = 0; id <= NJSC32_MAX_TARGET_ID; id++) { 523 /* cancel negotiation status */ 524 sc->sc_targets[id].t_state = NJSC32_TARST_INIT; 525 526 /* default to async mode */ 527 njsc32_target_async(sc, &sc->sc_targets[id]); 528 529 #ifdef NJSC32_DUALEDGE 530 sc->sc_targets[id].t_xferctl = 0; 531 #endif 532 533 sc->sc_targets[id].t_targetid = 534 (1 << id) | (1 << NJSC32_INITIATOR_ID); 535 536 /* init logical units */ 537 for (lun = 0; lun < NJSC32_NLU; lun++) { 538 lu = &sc->sc_targets[id].t_lus[lun]; 539 lu->lu_cmd = NULL; 540 TAILQ_INIT(&lu->lu_q); 541 } 542 } 543 } 544 545 void 546 njsc32_attach(struct njsc32_softc *sc) 547 { 548 const char *str; 549 #if 1 /* test */ 550 int reg; 551 njsc32_model_t detected_model; 552 #endif 553 554 /* init */ 555 TAILQ_INIT(&sc->sc_freecmd); 556 TAILQ_INIT(&sc->sc_reqcmd); 557 callout_init(&sc->sc_callout, 0); 558 559 #if 1 /* test */ 560 /* 561 * try to distinguish 32Bi and 32UDE 562 */ 563 /* try to set DualEdge bit (exists on 32UDE only) and read it back */ 564 njsc32_write_2(sc, NJSC32_REG_TRANSFER, NJSC32_XFR_DUALEDGE_ENABLE); 565 if ((reg = njsc32_read_2(sc, NJSC32_REG_TRANSFER)) == 0xffff) { 566 /* device was removed? */ 567 aprint_error_dev(sc->sc_dev, "attach failed\n"); 568 return; 569 } else if (reg & NJSC32_XFR_DUALEDGE_ENABLE) { 570 detected_model = NJSC32_MODEL_32UDE | NJSC32_FLAG_DUALEDGE; 571 } else { 572 detected_model = NJSC32_MODEL_32BI; 573 } 574 njsc32_write_2(sc, NJSC32_REG_TRANSFER, 0); /* restore */ 575 576 #if 1/*def DIAGNOSTIC*/ 577 /* compare what is configured with what is detected */ 578 if ((sc->sc_model & NJSC32_MODEL_MASK) != 579 (detected_model & NJSC32_MODEL_MASK)) { 580 /* 581 * Please report this error if it happens. 582 */ 583 aprint_error_dev(sc->sc_dev, "model mismatch: %#x vs %#x\n", 584 sc->sc_model, detected_model); 585 return; 586 } 587 #endif 588 #endif 589 590 /* check model */ 591 switch (sc->sc_model & NJSC32_MODEL_MASK) { 592 case NJSC32_MODEL_32BI: 593 str = "Bi"; 594 /* 32Bi doesn't support DualEdge transfer */ 595 KASSERT((sc->sc_model & NJSC32_FLAG_DUALEDGE) == 0); 596 break; 597 case NJSC32_MODEL_32UDE: 598 str = "UDE"; 599 break; 600 default: 601 aprint_error_dev(sc->sc_dev, "unknown model!\n"); 602 return; 603 } 604 aprint_normal_dev(sc->sc_dev, "NJSC-32%s", str); 605 606 switch (sc->sc_clk) { 607 default: 608 #ifdef DIAGNOSTIC 609 panic("njsc32_attach: unknown clk %d", sc->sc_clk); 610 #endif 611 case NJSC32_CLOCK_DIV_4: 612 sc->sc_synct = njsc32_synct_40M; 613 str = "40MHz"; 614 break; 615 #ifdef NJSC32_SUPPORT_OTHER_CLOCKS 616 case NJSC32_CLOCK_DIV_2: 617 sc->sc_synct = njsc32_synct_20M; 618 str = "20MHz"; 619 break; 620 case NJSC32_CLOCK_PCICLK: 621 sc->sc_synct = njsc32_synct_pci; 622 str = "PCI"; 623 break; 624 #endif 625 } 626 aprint_normal(", G/A rev %#x, clk %s%s\n", 627 NJSC32_INDEX_GAREV(njsc32_read_2(sc, NJSC32_REG_INDEX)), str, 628 (sc->sc_model & NJSC32_FLAG_DUALEDGE) ? 629 #ifdef NJSC32_DUALEDGE 630 ", DualEdge" 631 #else 632 ", DualEdge (no driver support)" 633 #endif 634 : ""); 635 636 /* allocate DMA resource */ 637 if ((sc->sc_ncmd = njsc32_init_cmds(sc)) == 0) { 638 aprint_error_dev(sc->sc_dev, "no usable DMA map\n"); 639 return; 640 } 641 sc->sc_flags |= NJSC32_CMDPG_MAPPED; 642 643 sc->sc_curcmd = NULL; 644 sc->sc_nusedcmds = 0; 645 646 sc->sc_sync_max = 1; /* XXX look up EEPROM configuration? */ 647 648 /* initialize hardware and target structure */ 649 njsc32_init(sc, cold); 650 651 /* setup adapter */ 652 sc->sc_adapter.adapt_dev = sc->sc_dev; 653 sc->sc_adapter.adapt_nchannels = 1; 654 sc->sc_adapter.adapt_request = njsc32_scsipi_request; 655 sc->sc_adapter.adapt_minphys = njsc32_scsipi_minphys; 656 sc->sc_adapter.adapt_ioctl = njsc32_scsipi_ioctl; 657 658 sc->sc_adapter.adapt_max_periph = sc->sc_adapter.adapt_openings = 659 sc->sc_ncmd; 660 661 /* setup channel */ 662 sc->sc_channel.chan_adapter = &sc->sc_adapter; 663 sc->sc_channel.chan_bustype = &scsi_bustype; 664 sc->sc_channel.chan_channel = 0; 665 sc->sc_channel.chan_ntargets = NJSC32_NTARGET; 666 sc->sc_channel.chan_nluns = NJSC32_NLU; 667 sc->sc_channel.chan_id = NJSC32_INITIATOR_ID; 668 669 sc->sc_scsi = config_found(sc->sc_dev, &sc->sc_channel, scsiprint, 670 CFARGS_NONE); 671 } 672 673 int 674 njsc32_detach(struct njsc32_softc *sc, int flags) 675 { 676 int rv = 0; 677 int i, s; 678 struct njsc32_cmd *cmd; 679 680 callout_stop(&sc->sc_callout); 681 682 s = splbio(); 683 684 /* clear running/disconnected commands */ 685 njsc32_clear_cmds(sc, XS_DRIVER_STUFFUP); 686 687 sc->sc_stat = NJSC32_STAT_DETACH; 688 689 /* clear pending commands */ 690 while ((cmd = TAILQ_FIRST(&sc->sc_reqcmd)) != NULL) { 691 TAILQ_REMOVE(&sc->sc_reqcmd, cmd, c_q); 692 njsc32_end_cmd(sc, cmd, XS_RESET); 693 } 694 695 if (sc->sc_scsi != NULL) 696 rv = config_detach(sc->sc_scsi, flags); 697 698 splx(s); 699 700 /* free DMA resource */ 701 if (sc->sc_flags & NJSC32_CMDPG_MAPPED) { 702 for (i = 0; i < sc->sc_ncmd; i++) { 703 cmd = &sc->sc_cmds[i]; 704 if (cmd->c_flags & NJSC32_CMD_DMA_MAPPED) 705 bus_dmamap_unload(sc->sc_dmat, 706 cmd->c_dmamap_xfer); 707 bus_dmamap_destroy(sc->sc_dmat, cmd->c_dmamap_xfer); 708 } 709 710 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_cmdpg); 711 bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_cmdpg); 712 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_cmdpg, 713 sizeof(struct njsc32_dma_page)); 714 bus_dmamem_free(sc->sc_dmat, &sc->sc_cmdpg_seg, 715 sc->sc_cmdpg_nsegs); 716 } 717 718 return rv; 719 } 720 721 static inline void 722 njsc32_cmd_init(struct njsc32_cmd *cmd) 723 { 724 725 cmd->c_flags = 0; 726 727 /* scatter/gather table */ 728 cmd->c_sgtdmaaddr = NJSC32_CMD_DMAADDR_SGT(cmd, 0); 729 cmd->c_sgoffset = 0; 730 cmd->c_sgfixcnt = 0; 731 732 /* data pointer */ 733 cmd->c_dp_cur = cmd->c_dp_saved = cmd->c_dp_max = 0; 734 } 735 736 static inline void 737 njsc32_init_msgout(struct njsc32_softc *sc) 738 { 739 740 sc->sc_msgoutlen = 0; 741 sc->sc_msgoutidx = 0; 742 } 743 744 static void 745 njsc32_add_msgout(struct njsc32_softc *sc, int byte) 746 { 747 748 if (sc->sc_msgoutlen >= NJSC32_MSGOUT_LEN) { 749 printf("njsc32_add_msgout: too many\n"); 750 return; 751 } 752 sc->sc_msgout[sc->sc_msgoutlen++] = byte; 753 } 754 755 static u_int32_t 756 njsc32_get_auto_msgout(struct njsc32_softc *sc) 757 { 758 u_int32_t val; 759 u_int8_t *p; 760 761 val = 0; 762 p = sc->sc_msgout; 763 switch (sc->sc_msgoutlen) { 764 /* 31-24 23-16 15-8 7 ... 1 0 */ 765 case 3: /* MSG3 MSG2 MSG1 V --- cnt */ 766 val |= *p++ << NJSC32_MSGOUT_MSG1_SHIFT; 767 /* FALLTHROUGH */ 768 769 case 2: /* MSG2 MSG1 --- V --- cnt */ 770 val |= *p++ << NJSC32_MSGOUT_MSG2_SHIFT; 771 /* FALLTHROUGH */ 772 773 case 1: /* MSG1 --- --- V --- cnt */ 774 val |= *p++ << NJSC32_MSGOUT_MSG3_SHIFT; 775 val |= NJSC32_MSGOUT_VALID | sc->sc_msgoutlen; 776 break; 777 778 default: 779 break; 780 } 781 return val; 782 } 783 784 #ifdef NJSC32_DUALEDGE 785 /* add Wide Data Transfer Request to the next Message Out */ 786 static void 787 njsc32_msgout_wdtr(struct njsc32_softc *sc, int width) 788 { 789 790 njsc32_add_msgout(sc, MSG_EXTENDED); 791 njsc32_add_msgout(sc, MSG_EXT_WDTR_LEN); 792 njsc32_add_msgout(sc, MSG_EXT_WDTR); 793 njsc32_add_msgout(sc, width); 794 } 795 #endif 796 797 /* add Synchronous Data Transfer Request to the next Message Out */ 798 static void 799 njsc32_msgout_sdtr(struct njsc32_softc *sc, int period, int offset) 800 { 801 802 njsc32_add_msgout(sc, MSG_EXTENDED); 803 njsc32_add_msgout(sc, MSG_EXT_SDTR_LEN); 804 njsc32_add_msgout(sc, MSG_EXT_SDTR); 805 njsc32_add_msgout(sc, period); 806 njsc32_add_msgout(sc, offset); 807 } 808 809 static void 810 njsc32_negotiate_xfer(struct njsc32_softc *sc, struct njsc32_target *target) 811 { 812 813 /* initial negotiation state */ 814 if (target->t_state == NJSC32_TARST_INIT) { 815 #ifdef NJSC32_DUALEDGE 816 if (target->t_flags & NJSC32_TARF_DE) 817 target->t_state = NJSC32_TARST_DE; 818 else 819 #endif 820 if (target->t_flags & NJSC32_TARF_SYNC) 821 target->t_state = NJSC32_TARST_SDTR; 822 else 823 target->t_state = NJSC32_TARST_DONE; 824 } 825 826 switch (target->t_state) { 827 default: 828 case NJSC32_TARST_INIT: 829 #ifdef DIAGNOSTIC 830 panic("njsc32_negotiate_xfer"); 831 /* NOTREACHED */ 832 #endif 833 /* FALLTHROUGH */ 834 case NJSC32_TARST_DONE: 835 /* no more work */ 836 break; 837 838 #ifdef NJSC32_DUALEDGE 839 case NJSC32_TARST_DE: 840 njsc32_msgout_wdtr(sc, 0xde /* XXX? */); 841 break; 842 843 case NJSC32_TARST_WDTR: 844 njsc32_msgout_wdtr(sc, MSG_EXT_WDTR_BUS_8_BIT); 845 break; 846 #endif 847 848 case NJSC32_TARST_SDTR: 849 njsc32_msgout_sdtr(sc, sc->sc_synct[sc->sc_sync_max].sp_period, 850 NJSC32_SYNCOFFSET_MAX); 851 break; 852 853 case NJSC32_TARST_ASYNC: 854 njsc32_msgout_sdtr(sc, NJSC32_SYNCPERIOD_ASYNC, 855 NJSC32_SYNCOFFSET_ASYNC); 856 break; 857 } 858 } 859 860 /* turn LED on */ 861 static inline void 862 njsc32_led_on(struct njsc32_softc *sc) 863 { 864 865 njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT, NJSC32_EXTPORT_LED_ON); 866 } 867 868 /* turn LED off */ 869 static inline void 870 njsc32_led_off(struct njsc32_softc *sc) 871 { 872 873 njsc32_ireg_write_1(sc, NJSC32_IREG_EXT_PORT, NJSC32_EXTPORT_LED_OFF); 874 } 875 876 static void 877 njsc32_arbitration_failed(struct njsc32_softc *sc) 878 { 879 struct njsc32_cmd *cmd; 880 881 if ((cmd = sc->sc_curcmd) == NULL || sc->sc_stat != NJSC32_STAT_ARBIT) 882 return; 883 884 if ((cmd->c_xs->xs_control & XS_CTL_POLL) == 0) 885 callout_stop(&cmd->c_xs->xs_callout); 886 887 sc->sc_stat = NJSC32_STAT_IDLE; 888 sc->sc_curcmd = NULL; 889 890 /* the command is no longer active */ 891 if (--sc->sc_nusedcmds == 0) 892 njsc32_led_off(sc); 893 } 894 895 static inline void 896 njsc32_cmd_load(struct njsc32_softc *sc, struct njsc32_cmd *cmd) 897 { 898 struct njsc32_target *target; 899 struct scsipi_xfer *xs; 900 int i, control, lun; 901 u_int32_t msgoutreg; 902 #ifdef NJSC32_AUTOPARAM 903 struct njsc32_autoparam *ap; 904 #endif 905 906 xs = cmd->c_xs; 907 #ifdef NJSC32_AUTOPARAM 908 ap = &sc->sc_cmdpg->dp_ap; 909 #else 910 /* reset CDB pointer */ 911 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, NJSC32_CMD_CLEAR_CDB_FIFO_PTR); 912 #endif 913 914 /* CDB */ 915 TPRINTC(cmd, ("njsc32_cmd_load: CDB")); 916 for (i = 0; i < xs->cmdlen; i++) { 917 #ifdef NJSC32_AUTOPARAM 918 ap->ap_cdb[i].cdb_data = ((u_int8_t *)xs->cmd)[i]; 919 #else 920 njsc32_write_1(sc, NJSC32_REG_COMMAND_DATA, 921 ((u_int8_t *)xs->cmd)[i]); 922 #endif 923 TPRINTF((" %02x", ((u_int8_t *)cmd->c_xs->cmd)[i])); 924 } 925 #ifdef NJSC32_AUTOPARAM /* XXX needed? */ 926 for ( ; i < NJSC32_AUTOPARAM_CDBLEN; i++) 927 ap->ap_cdb[i].cdb_data = 0; 928 #endif 929 930 control = xs->xs_control; 931 932 /* 933 * Message Out 934 */ 935 njsc32_init_msgout(sc); 936 937 /* Identify */ 938 lun = xs->xs_periph->periph_lun; 939 njsc32_add_msgout(sc, (control & XS_CTL_REQSENSE) ? 940 MSG_IDENTIFY(lun, 0) : MSG_IDENTIFY(lun, 1)); 941 942 /* tagged queueing */ 943 if (control & XS_CTL_TAGMASK) { 944 njsc32_add_msgout(sc, xs->xs_tag_type); 945 njsc32_add_msgout(sc, xs->xs_tag_id); 946 TPRINTF((" (tag %#x %#x)\n", xs->xs_tag_type, xs->xs_tag_id)); 947 } 948 TPRINTF(("\n")); 949 950 target = cmd->c_target; 951 952 /* transfer negotiation */ 953 if (control & XS_CTL_REQSENSE) 954 target->t_state = NJSC32_TARST_INIT; 955 njsc32_negotiate_xfer(sc, target); 956 957 msgoutreg = njsc32_get_auto_msgout(sc); 958 959 #ifdef NJSC32_AUTOPARAM 960 ap->ap_msgout = htole32(msgoutreg); 961 962 ap->ap_sync = target->t_sync; 963 ap->ap_ackwidth = target->t_ackwidth; 964 ap->ap_targetid = target->t_targetid; 965 ap->ap_sample = target->t_sample; 966 967 ap->ap_cmdctl = htole16(NJSC32_CMD_CLEAR_CDB_FIFO_PTR | 968 NJSC32_CMD_AUTO_COMMAND_PHASE | 969 NJSC32_CMD_AUTO_SCSI_START | NJSC32_CMD_AUTO_ATN | 970 NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02); 971 #ifdef NJSC32_DUALEDGE 972 ap->ap_xferctl = htole16(cmd->c_xferctl | target->t_xferctl); 973 #else 974 ap->ap_xferctl = htole16(cmd->c_xferctl); 975 #endif 976 ap->ap_sgtdmaaddr = htole32(cmd->c_sgtdmaaddr); 977 978 /* sync njsc32_autoparam */ 979 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg, 980 offsetof(struct njsc32_dma_page, dp_ap), /* offset */ 981 sizeof(struct njsc32_autoparam), 982 BUS_DMASYNC_PREWRITE); 983 984 /* autoparam DMA address */ 985 njsc32_write_4(sc, NJSC32_REG_SGT_ADR, sc->sc_ap_dma); 986 987 /* start command (autoparam) */ 988 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, 989 NJSC32_CMD_CLEAR_CDB_FIFO_PTR | NJSC32_CMD_AUTO_PARAMETER); 990 991 #else /* not NJSC32_AUTOPARAM */ 992 993 njsc32_write_4(sc, NJSC32_REG_SCSI_MSG_OUT, msgoutreg); 994 995 /* load parameters */ 996 njsc32_write_1(sc, NJSC32_REG_TARGET_ID, target->t_targetid); 997 njsc32_write_1(sc, NJSC32_REG_SYNC, target->t_sync); 998 njsc32_write_1(sc, NJSC32_REG_ACK_WIDTH, target->t_ackwidth); 999 njsc32_write_1(sc, NJSC32_REG_SREQ_SAMPLING, target->t_sample); 1000 njsc32_write_4(sc, NJSC32_REG_SGT_ADR, cmd->c_sgtdmaaddr); 1001 #ifdef NJSC32_DUALEDGE 1002 njsc32_write_2(sc, NJSC32_REG_TRANSFER, 1003 cmd->c_xferctl | target->t_xferctl); 1004 #else 1005 njsc32_write_2(sc, NJSC32_REG_TRANSFER, cmd->c_xferctl); 1006 #endif 1007 /* start AutoSCSI */ 1008 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, 1009 NJSC32_CMD_CLEAR_CDB_FIFO_PTR | NJSC32_CMD_AUTO_COMMAND_PHASE | 1010 NJSC32_CMD_AUTO_SCSI_START | NJSC32_CMD_AUTO_ATN | 1011 NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02); 1012 #endif /* not NJSC32_AUTOPARAM */ 1013 } 1014 1015 /* Note: must be called at splbio() */ 1016 static void 1017 njsc32_start(struct njsc32_softc *sc) 1018 { 1019 struct njsc32_cmd *cmd; 1020 1021 /* get a command to issue */ 1022 TAILQ_FOREACH(cmd, &sc->sc_reqcmd, c_q) { 1023 if (cmd->c_lu->lu_cmd == NULL && 1024 ((cmd->c_flags & NJSC32_CMD_TAGGED) || 1025 TAILQ_EMPTY(&cmd->c_lu->lu_q))) 1026 break; /* OK, the logical unit is free */ 1027 } 1028 if (!cmd) 1029 goto out; /* no work to do */ 1030 1031 /* request will always fail if not in bus free phase */ 1032 if (njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR) != 1033 NJSC32_BUSMON_BUSFREE) 1034 goto busy; 1035 1036 /* clear parity error and enable parity detection */ 1037 njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL, 1038 NJSC32_PARITYCTL_CHECK_ENABLE | NJSC32_PARITYCTL_CLEAR_ERROR); 1039 1040 njsc32_cmd_load(sc, cmd); 1041 1042 if (sc->sc_nusedcmds++ == 0) 1043 njsc32_led_on(sc); 1044 1045 sc->sc_curcmd = cmd; 1046 sc->sc_stat = NJSC32_STAT_ARBIT; 1047 1048 if ((cmd->c_xs->xs_control & XS_CTL_POLL) == 0) { 1049 callout_reset(&cmd->c_xs->xs_callout, 1050 mstohz(cmd->c_xs->timeout), 1051 njsc32_cmdtimeout, cmd); 1052 } 1053 1054 return; 1055 1056 busy: /* XXX retry counter */ 1057 TPRINTF(("%s: njsc32_start: busy\n", device_xname(sc->sc_dev))); 1058 njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_ARBITRATION_RETRY_TIME); 1059 out: njsc32_write_2(sc, NJSC32_REG_TRANSFER, 0); 1060 } 1061 1062 static void 1063 njsc32_run_xfer(struct njsc32_softc *sc, struct scsipi_xfer *xs) 1064 { 1065 struct scsipi_periph *periph; 1066 int control; 1067 int lun; 1068 struct njsc32_cmd *cmd; 1069 int s, i, error; 1070 1071 periph = xs->xs_periph; 1072 KASSERT((unsigned)periph->periph_target <= NJSC32_MAX_TARGET_ID); 1073 1074 control = xs->xs_control; 1075 lun = periph->periph_lun; 1076 1077 /* 1078 * get a free cmd 1079 * (scsipi layer knows the number of cmds, so this shall never fail) 1080 */ 1081 s = splbio(); 1082 cmd = TAILQ_FIRST(&sc->sc_freecmd); 1083 KASSERT(cmd); 1084 TAILQ_REMOVE(&sc->sc_freecmd, cmd, c_q); 1085 splx(s); 1086 1087 /* 1088 * build a request 1089 */ 1090 njsc32_cmd_init(cmd); 1091 cmd->c_xs = xs; 1092 cmd->c_target = &sc->sc_targets[periph->periph_target]; 1093 cmd->c_lu = &cmd->c_target->t_lus[lun]; 1094 1095 /* tagged queueing */ 1096 if (control & XS_CTL_TAGMASK) { 1097 cmd->c_flags |= NJSC32_CMD_TAGGED; 1098 if (control & XS_CTL_HEAD_TAG) 1099 cmd->c_flags |= NJSC32_CMD_TAGGED_HEAD; 1100 } 1101 1102 /* map DMA buffer */ 1103 cmd->c_datacnt = xs->datalen; 1104 if (xs->datalen) { 1105 /* Is XS_CTL_DATA_UIO ever used anywhere? */ 1106 KASSERT((control & XS_CTL_DATA_UIO) == 0); 1107 1108 error = bus_dmamap_load(sc->sc_dmat, cmd->c_dmamap_xfer, 1109 xs->data, xs->datalen, NULL, 1110 ((control & XS_CTL_NOSLEEP) ? 1111 BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | 1112 BUS_DMA_STREAMING | 1113 ((control & XS_CTL_DATA_IN) ? 1114 BUS_DMA_READ : BUS_DMA_WRITE)); 1115 1116 switch (error) { 1117 case 0: 1118 break; 1119 case ENOMEM: 1120 case EAGAIN: 1121 xs->error = XS_RESOURCE_SHORTAGE; 1122 goto map_failed; 1123 default: 1124 xs->error = XS_DRIVER_STUFFUP; 1125 map_failed: 1126 printf("%s: njsc32_run_xfer: map failed, error %d\n", 1127 device_xname(sc->sc_dev), error); 1128 /* put it back to free command list */ 1129 s = splbio(); 1130 TAILQ_INSERT_HEAD(&sc->sc_freecmd, cmd, c_q); 1131 splx(s); 1132 /* abort this transfer */ 1133 scsipi_done(xs); 1134 return; 1135 } 1136 1137 bus_dmamap_sync(sc->sc_dmat, cmd->c_dmamap_xfer, 1138 0, cmd->c_dmamap_xfer->dm_mapsize, 1139 (control & XS_CTL_DATA_IN) ? 1140 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 1141 1142 for (i = 0; i < cmd->c_dmamap_xfer->dm_nsegs; i++) { 1143 cmd->c_sgt[i].sg_addr = 1144 htole32(cmd->c_dmamap_xfer->dm_segs[i].ds_addr); 1145 cmd->c_sgt[i].sg_len = 1146 htole32(cmd->c_dmamap_xfer->dm_segs[i].ds_len); 1147 } 1148 /* end mark */ 1149 cmd->c_sgt[i - 1].sg_len |= htole32(NJSC32_SGT_ENDMARK); 1150 1151 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg, 1152 (char *)cmd->c_sgt - (char *)sc->sc_cmdpg, /* offset */ 1153 NJSC32_SIZE_SGT, 1154 BUS_DMASYNC_PREWRITE); 1155 1156 cmd->c_flags |= NJSC32_CMD_DMA_MAPPED; 1157 1158 /* enable transfer */ 1159 cmd->c_xferctl = 1160 NJSC32_XFR_TRANSFER_GO | NJSC32_XFR_BM_START | 1161 NJSC32_XFR_ALL_COUNT_CLR; 1162 1163 /* XXX How can we specify the DMA direction? */ 1164 1165 #if 0 /* faster write mode? (doesn't work) */ 1166 if ((control & XS_CTL_DATA_IN) == 0) 1167 cmd->c_xferctl |= NJSC32_XFR_ADVANCED_BM_WRITE; 1168 #endif 1169 } else { 1170 /* no data transfer */ 1171 cmd->c_xferctl = 0; 1172 } 1173 1174 /* queue request */ 1175 s = splbio(); 1176 TAILQ_INSERT_TAIL(&sc->sc_reqcmd, cmd, c_q); 1177 1178 /* start the controller if idle */ 1179 if (sc->sc_stat == NJSC32_STAT_IDLE) 1180 njsc32_start(sc); 1181 1182 splx(s); 1183 1184 if (control & XS_CTL_POLL) { 1185 /* wait for completion */ 1186 /* XXX should handle timeout? */ 1187 while ((xs->xs_status & XS_STS_DONE) == 0) { 1188 delay(1000); 1189 njsc32_intr(sc); 1190 } 1191 } 1192 } 1193 1194 static void 1195 njsc32_end_cmd(struct njsc32_softc *sc, struct njsc32_cmd *cmd, 1196 scsipi_xfer_result_t result) 1197 { 1198 struct scsipi_xfer *xs; 1199 int s; 1200 #ifdef DIAGNOSTIC 1201 struct njsc32_cmd *c; 1202 #endif 1203 1204 KASSERT(cmd); 1205 1206 #ifdef DIAGNOSTIC 1207 s = splbio(); 1208 TAILQ_FOREACH(c, &sc->sc_freecmd, c_q) { 1209 if (cmd == c) 1210 panic("njsc32_end_cmd: already in free list"); 1211 } 1212 splx(s); 1213 #endif 1214 xs = cmd->c_xs; 1215 1216 if (cmd->c_flags & NJSC32_CMD_DMA_MAPPED) { 1217 if (cmd->c_datacnt) { 1218 bus_dmamap_sync(sc->sc_dmat, cmd->c_dmamap_xfer, 1219 0, cmd->c_dmamap_xfer->dm_mapsize, 1220 (xs->xs_control & XS_CTL_DATA_IN) ? 1221 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1222 1223 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg, 1224 (char *)cmd->c_sgt - (char *)sc->sc_cmdpg, 1225 NJSC32_SIZE_SGT, BUS_DMASYNC_POSTWRITE); 1226 } 1227 1228 bus_dmamap_unload(sc->sc_dmat, cmd->c_dmamap_xfer); 1229 cmd->c_flags &= ~NJSC32_CMD_DMA_MAPPED; 1230 } 1231 1232 s = splbio(); 1233 if ((xs->xs_control & XS_CTL_POLL) == 0) 1234 callout_stop(&xs->xs_callout); 1235 1236 TAILQ_INSERT_HEAD(&sc->sc_freecmd, cmd, c_q); 1237 splx(s); 1238 1239 xs->error = result; 1240 scsipi_done(xs); 1241 1242 if (--sc->sc_nusedcmds == 0) 1243 njsc32_led_off(sc); 1244 } 1245 1246 /* 1247 * request from scsipi layer 1248 */ 1249 static void 1250 njsc32_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 1251 void *arg) 1252 { 1253 struct njsc32_softc *sc; 1254 struct scsipi_xfer_mode *xm; 1255 struct njsc32_target *target; 1256 1257 sc = device_private(chan->chan_adapter->adapt_dev); 1258 1259 switch (req) { 1260 case ADAPTER_REQ_RUN_XFER: 1261 njsc32_run_xfer(sc, arg); 1262 break; 1263 1264 case ADAPTER_REQ_GROW_RESOURCES: 1265 /* not supported */ 1266 break; 1267 1268 case ADAPTER_REQ_SET_XFER_MODE: 1269 xm = arg; 1270 target = &sc->sc_targets[xm->xm_target]; 1271 1272 target->t_flags = 0; 1273 if (xm->xm_mode & PERIPH_CAP_TQING) 1274 target->t_flags |= NJSC32_TARF_TAG; 1275 if (xm->xm_mode & PERIPH_CAP_SYNC) { 1276 target->t_flags |= NJSC32_TARF_SYNC; 1277 #ifdef NJSC32_DUALEDGE 1278 if (sc->sc_model & NJSC32_FLAG_DUALEDGE) 1279 target->t_flags |= NJSC32_TARF_DE; 1280 #endif 1281 } 1282 #ifdef NJSC32_DUALEDGE 1283 target->t_xferctl = 0; 1284 #endif 1285 target->t_state = NJSC32_TARST_INIT; 1286 njsc32_target_async(sc, target); 1287 1288 break; 1289 default: 1290 break; 1291 } 1292 } 1293 1294 static void 1295 njsc32_scsipi_minphys(struct buf *bp) 1296 { 1297 1298 if (bp->b_bcount > NJSC32_MAX_XFER) 1299 bp->b_bcount = NJSC32_MAX_XFER; 1300 minphys(bp); 1301 } 1302 1303 /* 1304 * On some versions of 32UDE (probably the earlier ones), the controller 1305 * detects continuous bus reset when the termination power is absent. 1306 * Make sure the system won't hang on such situation. 1307 */ 1308 static void 1309 njsc32_wait_reset_release(void *arg) 1310 { 1311 struct njsc32_softc *sc = arg; 1312 struct njsc32_cmd *cmd; 1313 1314 /* clear pending commands */ 1315 while ((cmd = TAILQ_FIRST(&sc->sc_reqcmd)) != NULL) { 1316 TAILQ_REMOVE(&sc->sc_reqcmd, cmd, c_q); 1317 njsc32_end_cmd(sc, cmd, XS_RESET); 1318 } 1319 1320 /* If Bus Reset is not released yet, schedule recheck. */ 1321 if (njsc32_read_2(sc, NJSC32_REG_IRQ) & NJSC32_IRQ_SCSIRESET) { 1322 switch (sc->sc_stat) { 1323 case NJSC32_STAT_RESET: 1324 sc->sc_stat = NJSC32_STAT_RESET1; 1325 break; 1326 case NJSC32_STAT_RESET1: 1327 /* print message if Bus Reset is detected twice */ 1328 sc->sc_stat = NJSC32_STAT_RESET2; 1329 printf("%s: detected excessive bus reset " 1330 "--- missing termination power?\n", 1331 device_xname(sc->sc_dev)); 1332 break; 1333 default: 1334 break; 1335 } 1336 callout_reset(&sc->sc_callout, 1337 hz * 2 /* poll every 2s */, 1338 njsc32_wait_reset_release, sc); 1339 return; 1340 } 1341 1342 if (sc->sc_stat == NJSC32_STAT_RESET2) 1343 printf("%s: bus reset is released\n", device_xname(sc->sc_dev)); 1344 1345 /* unblock interrupts */ 1346 njsc32_write_2(sc, NJSC32_REG_IRQ, 0); 1347 1348 sc->sc_stat = NJSC32_STAT_IDLE; 1349 } 1350 1351 static void 1352 njsc32_reset_bus(struct njsc32_softc *sc) 1353 { 1354 int s; 1355 1356 DPRINTF(("%s: njsc32_reset_bus:\n", device_xname(sc->sc_dev))); 1357 1358 /* block interrupts */ 1359 njsc32_write_2(sc, NJSC32_REG_IRQ, NJSC32_IRQ_MASK_ALL); 1360 1361 sc->sc_stat = NJSC32_STAT_RESET; 1362 1363 /* hold SCSI bus reset */ 1364 njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, NJSC32_SBCTL_RST); 1365 delay(NJSC32_RESET_HOLD_TIME); 1366 1367 /* clear transfer */ 1368 njsc32_clear_cmds(sc, XS_RESET); 1369 1370 /* initialize target structure */ 1371 njsc32_init_targets(sc); 1372 1373 if (sc->sc_scsi != NULL) { 1374 /* XXXSMP scsipi */ 1375 KERNEL_LOCK(1, curlwp); 1376 s = splbio(); 1377 scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_RESET, NULL); 1378 splx(s); 1379 /* XXXSMP scsipi */ 1380 KERNEL_UNLOCK_ONE(curlwp); 1381 } 1382 1383 /* release SCSI bus reset */ 1384 njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, 0); 1385 1386 njsc32_wait_reset_release(sc); 1387 } 1388 1389 /* 1390 * clear running/disconnected commands 1391 */ 1392 static void 1393 njsc32_clear_cmds(struct njsc32_softc *sc, scsipi_xfer_result_t cmdresult) 1394 { 1395 struct njsc32_cmd *cmd; 1396 int id, lun; 1397 struct njsc32_lu *lu; 1398 1399 njsc32_arbitration_failed(sc); 1400 1401 /* clear current transfer */ 1402 if ((cmd = sc->sc_curcmd) != NULL) { 1403 sc->sc_curcmd = NULL; 1404 njsc32_end_cmd(sc, cmd, cmdresult); 1405 } 1406 1407 /* clear disconnected transfers */ 1408 for (id = 0; id <= NJSC32_MAX_TARGET_ID; id++) { 1409 for (lun = 0; lun < NJSC32_NLU; lun++) { 1410 lu = &sc->sc_targets[id].t_lus[lun]; 1411 1412 if ((cmd = lu->lu_cmd) != NULL) { 1413 lu->lu_cmd = NULL; 1414 njsc32_end_cmd(sc, cmd, cmdresult); 1415 } 1416 while ((cmd = TAILQ_FIRST(&lu->lu_q)) != NULL) { 1417 TAILQ_REMOVE(&lu->lu_q, cmd, c_q); 1418 njsc32_end_cmd(sc, cmd, cmdresult); 1419 } 1420 } 1421 } 1422 } 1423 1424 static int 1425 njsc32_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd, 1426 void *addr, int flag, struct proc *p) 1427 { 1428 struct njsc32_softc *sc; 1429 1430 sc = device_private(chan->chan_adapter->adapt_dev); 1431 1432 switch (cmd) { 1433 case SCBUSIORESET: 1434 njsc32_init(sc, 0); 1435 return 0; 1436 default: 1437 break; 1438 } 1439 1440 return ENOTTY; 1441 } 1442 1443 /* 1444 * set current data pointer 1445 */ 1446 static inline void 1447 njsc32_set_cur_ptr(struct njsc32_cmd *cmd, u_int32_t pos) 1448 { 1449 1450 /* new current data pointer */ 1451 cmd->c_dp_cur = pos; 1452 1453 /* update number of bytes transferred */ 1454 if (pos > cmd->c_dp_max) 1455 cmd->c_dp_max = pos; 1456 } 1457 1458 /* 1459 * set data pointer for the next transfer 1460 */ 1461 static void 1462 njsc32_set_ptr(struct njsc32_softc *sc, struct njsc32_cmd *cmd, u_int32_t pos) 1463 { 1464 struct njsc32_sgtable *sg; 1465 unsigned sgte; 1466 u_int32_t len; 1467 1468 /* set current pointer */ 1469 njsc32_set_cur_ptr(cmd, pos); 1470 1471 /* undo previous fix if any */ 1472 if (cmd->c_sgfixcnt != 0) { 1473 sg = &cmd->c_sgt[cmd->c_sgoffset]; 1474 sg->sg_addr = htole32(le32toh(sg->sg_addr) - cmd->c_sgfixcnt); 1475 sg->sg_len = htole32(le32toh(sg->sg_len) + cmd->c_sgfixcnt); 1476 cmd->c_sgfixcnt = 0; 1477 } 1478 1479 if (pos >= cmd->c_datacnt) { 1480 /* transfer done */ 1481 #if 1 /*def DIAGNOSTIC*/ 1482 if (pos > cmd->c_datacnt) 1483 printf("%s: pos %u too large\n", 1484 device_xname(sc->sc_dev), pos - cmd->c_datacnt); 1485 #endif 1486 cmd->c_xferctl = 0; /* XXX correct? */ 1487 1488 return; 1489 } 1490 1491 for (sgte = 0, sg = cmd->c_sgt; 1492 sgte < NJSC32_NUM_SG && pos > 0; sgte++, sg++) { 1493 len = le32toh(sg->sg_len) & ~NJSC32_SGT_ENDMARK; 1494 if (pos < len) { 1495 sg->sg_addr = htole32(le32toh(sg->sg_addr) + pos); 1496 sg->sg_len = htole32(le32toh(sg->sg_len) - pos); 1497 cmd->c_sgfixcnt = pos; 1498 break; 1499 } 1500 pos -= len; 1501 #ifdef DIAGNOSTIC 1502 if (sg->sg_len & htole32(NJSC32_SGT_ENDMARK)) { 1503 panic("njsc32_set_ptr: bad pos"); 1504 } 1505 #endif 1506 } 1507 #ifdef DIAGNOSTIC 1508 if (sgte >= NJSC32_NUM_SG) 1509 panic("njsc32_set_ptr: bad sg"); 1510 #endif 1511 if (cmd->c_sgoffset != sgte) { 1512 cmd->c_sgoffset = sgte; 1513 cmd->c_sgtdmaaddr = NJSC32_CMD_DMAADDR_SGT(cmd, sgte); 1514 } 1515 1516 /* XXX overkill */ 1517 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_cmdpg, 1518 (char *)cmd->c_sgt - (char *)sc->sc_cmdpg, /* offset */ 1519 NJSC32_SIZE_SGT, 1520 BUS_DMASYNC_PREWRITE); 1521 } 1522 1523 /* 1524 * save data pointer 1525 */ 1526 static inline void 1527 njsc32_save_ptr(struct njsc32_cmd *cmd) 1528 { 1529 1530 cmd->c_dp_saved = cmd->c_dp_cur; 1531 } 1532 1533 static void 1534 njsc32_assert_ack(struct njsc32_softc *sc) 1535 { 1536 u_int8_t reg; 1537 1538 reg = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_CONTROL); 1539 reg |= NJSC32_SBCTL_ACK | NJSC32_SBCTL_ACK_ENABLE; 1540 #if 0 /* needed? */ 1541 reg |= NJSC32_SBCTL_AUTODIRECTION; 1542 #endif 1543 njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, reg); 1544 } 1545 1546 static void 1547 njsc32_negate_ack(struct njsc32_softc *sc) 1548 { 1549 u_int8_t reg; 1550 1551 reg = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_CONTROL); 1552 #if 0 /* needed? */ 1553 reg |= NJSC32_SBCTL_ACK_ENABLE; 1554 reg |= NJSC32_SBCTL_AUTODIRECTION; 1555 #endif 1556 reg &= ~NJSC32_SBCTL_ACK; 1557 njsc32_write_1(sc, NJSC32_REG_SCSI_BUS_CONTROL, reg); 1558 } 1559 1560 static void 1561 njsc32_wait_req_negate(struct njsc32_softc *sc) 1562 { 1563 int cnt; 1564 1565 for (cnt = 0; cnt < NJSC32_REQ_TIMEOUT; cnt++) { 1566 if ((njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR) & 1567 NJSC32_BUSMON_REQ) == 0) 1568 return; 1569 delay(1); 1570 } 1571 printf("%s: njsc32_wait_req_negate: timed out\n", 1572 device_xname(sc->sc_dev)); 1573 } 1574 1575 static void 1576 njsc32_reconnect(struct njsc32_softc *sc, struct njsc32_cmd *cmd) 1577 { 1578 struct scsipi_xfer *xs; 1579 1580 xs = cmd->c_xs; 1581 if ((xs->xs_control & XS_CTL_POLL) == 0) { 1582 callout_stop(&xs->xs_callout); 1583 callout_reset(&xs->xs_callout, 1584 mstohz(xs->timeout), 1585 njsc32_cmdtimeout, cmd); 1586 } 1587 1588 /* Reconnection implies Restore Pointers */ 1589 njsc32_set_ptr(sc, cmd, cmd->c_dp_saved); 1590 } 1591 1592 static enum njsc32_reselstat 1593 njsc32_resel_identify(struct njsc32_softc *sc, int lun, 1594 struct njsc32_cmd **pcmd) 1595 { 1596 int targetid; 1597 struct njsc32_lu *plu; 1598 struct njsc32_cmd *cmd; 1599 1600 switch (sc->sc_stat) { 1601 case NJSC32_STAT_RESEL: 1602 break; /* OK */ 1603 1604 case NJSC32_STAT_RESEL_LUN: 1605 case NJSC32_STAT_RECONNECT: 1606 /* 1607 * accept and ignore if the LUN is the same as the current one, 1608 * reject otherwise. 1609 */ 1610 return sc->sc_resellun == lun ? 1611 NJSC32_RESEL_THROUGH : NJSC32_RESEL_ERROR; 1612 1613 default: 1614 printf("%s: njsc32_resel_identify: not in reselection\n", 1615 device_xname(sc->sc_dev)); 1616 return NJSC32_RESEL_ERROR; 1617 } 1618 1619 targetid = sc->sc_reselid; 1620 TPRINTF(("%s: njsc32_resel_identify: reselection lun %d\n", 1621 device_xname(sc->sc_dev), lun)); 1622 1623 if (targetid > NJSC32_MAX_TARGET_ID || lun >= NJSC32_NLU) 1624 return NJSC32_RESEL_ERROR; 1625 1626 sc->sc_resellun = lun; 1627 plu = &sc->sc_targets[targetid].t_lus[lun]; 1628 1629 if ((cmd = plu->lu_cmd) != NULL) { 1630 sc->sc_stat = NJSC32_STAT_RECONNECT; 1631 plu->lu_cmd = NULL; 1632 *pcmd = cmd; 1633 TPRINTC(cmd, ("njsc32_resel_identify: I_T_L nexus\n")); 1634 njsc32_reconnect(sc, cmd); 1635 return NJSC32_RESEL_COMPLETE; 1636 } else if (!TAILQ_EMPTY(&plu->lu_q)) { 1637 /* wait for tag */ 1638 sc->sc_stat = NJSC32_STAT_RESEL_LUN; 1639 return NJSC32_RESEL_THROUGH; 1640 } 1641 1642 /* no disconnected commands */ 1643 return NJSC32_RESEL_ERROR; 1644 } 1645 1646 static enum njsc32_reselstat 1647 njsc32_resel_tag(struct njsc32_softc *sc, int tag, struct njsc32_cmd **pcmd) 1648 { 1649 struct njsc32_cmd_head *head; 1650 struct njsc32_cmd *cmd; 1651 1652 TPRINTF(("%s: njsc32_resel_tag: reselection tag %d\n", 1653 device_xname(sc->sc_dev), tag)); 1654 if (sc->sc_stat != NJSC32_STAT_RESEL_LUN) 1655 return NJSC32_RESEL_ERROR; 1656 1657 head = &sc->sc_targets[sc->sc_reselid].t_lus[sc->sc_resellun].lu_q; 1658 1659 /* XXX slow? */ 1660 /* search for the command of the tag */ 1661 TAILQ_FOREACH(cmd, head, c_q) { 1662 if (cmd->c_xs->xs_tag_id == tag) { 1663 sc->sc_stat = NJSC32_STAT_RECONNECT; 1664 TAILQ_REMOVE(head, cmd, c_q); 1665 *pcmd = cmd; 1666 TPRINTC(cmd, ("njsc32_resel_tag: I_T_L_Q nexus\n")); 1667 njsc32_reconnect(sc, cmd); 1668 return NJSC32_RESEL_COMPLETE; 1669 } 1670 } 1671 1672 /* no disconnected commands */ 1673 return NJSC32_RESEL_ERROR; 1674 } 1675 1676 /* 1677 * Reload parameters and restart AutoSCSI. 1678 * 1679 * XXX autoparam doesn't work as expected and we can't use it here. 1680 */ 1681 static void 1682 njsc32_cmd_reload(struct njsc32_softc *sc, struct njsc32_cmd *cmd, int cctl) 1683 { 1684 struct njsc32_target *target; 1685 1686 target = cmd->c_target; 1687 1688 /* clear parity error and enable parity detection */ 1689 njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL, 1690 NJSC32_PARITYCTL_CHECK_ENABLE | NJSC32_PARITYCTL_CLEAR_ERROR); 1691 1692 /* load parameters */ 1693 njsc32_write_1(sc, NJSC32_REG_SYNC, target->t_sync); 1694 njsc32_write_1(sc, NJSC32_REG_ACK_WIDTH, target->t_ackwidth); 1695 njsc32_write_1(sc, NJSC32_REG_SREQ_SAMPLING, target->t_sample); 1696 njsc32_write_4(sc, NJSC32_REG_SGT_ADR, cmd->c_sgtdmaaddr); 1697 #ifdef NJSC32_DUALEDGE 1698 njsc32_write_2(sc, NJSC32_REG_TRANSFER, 1699 cmd->c_xferctl | target->t_xferctl); 1700 #else 1701 njsc32_write_2(sc, NJSC32_REG_TRANSFER, cmd->c_xferctl); 1702 #endif 1703 /* start AutoSCSI */ 1704 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl); 1705 1706 sc->sc_curcmd = cmd; 1707 } 1708 1709 static void 1710 njsc32_update_xfer_mode(struct njsc32_softc *sc, struct njsc32_target *target) 1711 { 1712 struct scsipi_xfer_mode xm; 1713 1714 xm.xm_target = target - sc->sc_targets; /* target ID */ 1715 xm.xm_mode = 0; 1716 xm.xm_period = target->t_syncperiod; 1717 xm.xm_offset = target->t_syncoffset; 1718 if (xm.xm_offset != 0) 1719 xm.xm_mode |= PERIPH_CAP_SYNC; 1720 if (target->t_flags & NJSC32_TARF_TAG) 1721 xm.xm_mode |= PERIPH_CAP_TQING; 1722 1723 scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm); 1724 } 1725 1726 static void 1727 njsc32_msgin(struct njsc32_softc *sc) 1728 { 1729 u_int8_t msg0, msg; 1730 int msgcnt; 1731 struct njsc32_cmd *cmd; 1732 enum njsc32_reselstat rstat; 1733 int cctl = 0; 1734 u_int32_t ptr; /* unsigned type ensures 2-complement calculation */ 1735 u_int32_t msgout = 0; 1736 bool reload_params = FALSE; 1737 struct njsc32_target *target; 1738 int idx, period, offset; 1739 1740 /* 1741 * we are in Message In, so the previous Message Out should have 1742 * been done. 1743 */ 1744 njsc32_init_msgout(sc); 1745 1746 /* get a byte of Message In */ 1747 msg = njsc32_read_1(sc, NJSC32_REG_DATA_IN); 1748 TPRINTF(("%s: njsc32_msgin: got %#x\n", device_xname(sc->sc_dev), msg)); 1749 if ((msgcnt = sc->sc_msgincnt) < NJSC32_MSGIN_LEN) 1750 sc->sc_msginbuf[sc->sc_msgincnt] = msg; 1751 1752 njsc32_assert_ack(sc); 1753 1754 msg0 = sc->sc_msginbuf[0]; 1755 cmd = sc->sc_curcmd; 1756 1757 /* check for parity error */ 1758 if (njsc32_read_1(sc, NJSC32_REG_PARITY_STATUS) & 1759 NJSC32_PARITYSTATUS_ERROR_LSB) { 1760 1761 printf("%s: msgin: parity error\n", device_xname(sc->sc_dev)); 1762 1763 /* clear parity error */ 1764 njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL, 1765 NJSC32_PARITYCTL_CHECK_ENABLE | 1766 NJSC32_PARITYCTL_CLEAR_ERROR); 1767 1768 /* respond as Message Parity Error */ 1769 njsc32_add_msgout(sc, MSG_PARITY_ERROR); 1770 1771 /* clear Message In */ 1772 sc->sc_msgincnt = 0; 1773 goto reply; 1774 } 1775 1776 #define WAITNEXTMSG do { sc->sc_msgincnt++; goto restart; } while (0) 1777 #define MSGCOMPLETE do { sc->sc_msgincnt = 0; goto restart; } while (0) 1778 if (MSG_ISIDENTIFY(msg0)) { 1779 /* 1780 * Got Identify message from target. 1781 */ 1782 if ((msg0 & ~MSG_IDENTIFY_LUNMASK) != MSG_IDENTIFYFLAG || 1783 (rstat = njsc32_resel_identify(sc, msg0 & 1784 MSG_IDENTIFY_LUNMASK, &cmd)) == NJSC32_RESEL_ERROR) { 1785 /* 1786 * invalid Identify -> Reject 1787 */ 1788 goto reject; 1789 } 1790 if (rstat == NJSC32_RESEL_COMPLETE) 1791 reload_params = TRUE; 1792 MSGCOMPLETE; 1793 } 1794 1795 if (msg0 == MSG_SIMPLE_Q_TAG) { 1796 if (msgcnt == 0) 1797 WAITNEXTMSG; 1798 1799 /* got whole message */ 1800 sc->sc_msgincnt = 0; 1801 1802 if ((rstat = njsc32_resel_tag(sc, sc->sc_msginbuf[1], &cmd)) 1803 == NJSC32_RESEL_ERROR) { 1804 /* 1805 * invalid Simple Queue Tag -> Abort Tag 1806 */ 1807 printf("%s: msgin: invalid tag\n", 1808 device_xname(sc->sc_dev)); 1809 njsc32_add_msgout(sc, MSG_ABORT_TAG); 1810 goto reply; 1811 } 1812 if (rstat == NJSC32_RESEL_COMPLETE) 1813 reload_params = TRUE; 1814 MSGCOMPLETE; 1815 } 1816 1817 /* I_T_L or I_T_L_Q nexus should be established now */ 1818 if (cmd == NULL) { 1819 printf("%s: msgin %#x without nexus -- sending abort\n", 1820 device_xname(sc->sc_dev), msg0); 1821 njsc32_add_msgout(sc, MSG_ABORT); 1822 goto reply; 1823 } 1824 1825 /* 1826 * extended message 1827 * 0x01 <length (0 stands for 256)> <length bytes> 1828 * (<code> [<parameter> ...]) 1829 */ 1830 #define EXTLENOFF 1 1831 #define EXTCODEOFF 2 1832 if (msg0 == MSG_EXTENDED) { 1833 if (msgcnt < EXTLENOFF || 1834 msgcnt < EXTLENOFF + 1 + 1835 (u_int8_t)(sc->sc_msginbuf[EXTLENOFF] - 1)) 1836 WAITNEXTMSG; 1837 1838 /* got whole message */ 1839 sc->sc_msgincnt = 0; 1840 1841 switch (sc->sc_msginbuf[EXTCODEOFF]) { 1842 case 0: /* Modify Data Pointer */ 1843 if (msgcnt != 5 + EXTCODEOFF - 1) 1844 break; 1845 /* 1846 * parameter is 32bit big-endian signed (2-complement) 1847 * value 1848 */ 1849 ptr = (sc->sc_msginbuf[EXTCODEOFF + 1] << 24) | 1850 (sc->sc_msginbuf[EXTCODEOFF + 2] << 16) | 1851 (sc->sc_msginbuf[EXTCODEOFF + 3] << 8) | 1852 sc->sc_msginbuf[EXTCODEOFF + 4]; 1853 1854 /* new pointer */ 1855 ptr += cmd->c_dp_cur; /* ignore overflow */ 1856 1857 /* reject if ptr is not in data buffer */ 1858 if (ptr > cmd->c_datacnt) 1859 break; 1860 1861 njsc32_set_ptr(sc, cmd, ptr); 1862 goto restart; 1863 1864 case MSG_EXT_SDTR: /* Synchronous Data Transfer Request */ 1865 DPRINTC(cmd, ("SDTR %#x %#x\n", 1866 sc->sc_msginbuf[EXTCODEOFF + 1], 1867 sc->sc_msginbuf[EXTCODEOFF + 2])); 1868 if (msgcnt != MSG_EXT_SDTR_LEN + EXTCODEOFF-1) 1869 break; /* reject */ 1870 1871 target = cmd->c_target; 1872 1873 /* lookup sync period parameters */ 1874 period = sc->sc_msginbuf[EXTCODEOFF + 1]; 1875 for (idx = sc->sc_sync_max; idx < NJSC32_NSYNCT; idx++) 1876 if (sc->sc_synct[idx].sp_period >= period) { 1877 period = sc->sc_synct[idx].sp_period; 1878 break; 1879 } 1880 if (idx >= NJSC32_NSYNCT) { 1881 /* 1882 * We can't meet the timing condition that 1883 * the target requests -- use async. 1884 */ 1885 njsc32_target_async(sc, target); 1886 njsc32_update_xfer_mode(sc, target); 1887 if (target->t_state == NJSC32_TARST_SDTR) { 1888 /* 1889 * We started SDTR exchange -- start 1890 * negotiation again and request async. 1891 */ 1892 target->t_state = NJSC32_TARST_ASYNC; 1893 njsc32_negotiate_xfer(sc, target); 1894 goto reply; 1895 } else { 1896 /* 1897 * The target started SDTR exchange 1898 * -- just reject and fallback 1899 * to async. 1900 */ 1901 goto reject; 1902 } 1903 } 1904 1905 /* check sync offset */ 1906 offset = sc->sc_msginbuf[EXTCODEOFF + 2]; 1907 if (offset > NJSC32_SYNCOFFSET_MAX) { 1908 if (target->t_state == NJSC32_TARST_SDTR) { 1909 printf("%s: wrong sync offset: %d\n", 1910 device_xname(sc->sc_dev), offset); 1911 /* XXX what to do? */ 1912 } 1913 offset = NJSC32_SYNCOFFSET_MAX; 1914 } 1915 1916 target->t_ackwidth = sc->sc_synct[idx].sp_ackw; 1917 target->t_sample = sc->sc_synct[idx].sp_sample; 1918 target->t_syncperiod = period; 1919 target->t_syncoffset = offset; 1920 target->t_sync = NJSC32_SYNC_VAL(idx, offset); 1921 njsc32_update_xfer_mode(sc, target); 1922 1923 if (target->t_state == NJSC32_TARST_SDTR) { 1924 target->t_state = NJSC32_TARST_DONE; 1925 } else { 1926 njsc32_msgout_sdtr(sc, period, offset); 1927 goto reply; 1928 } 1929 goto restart; 1930 1931 case MSG_EXT_WDTR: /* Wide Data Transfer Request */ 1932 DPRINTC(cmd, 1933 ("WDTR %#x\n", sc->sc_msginbuf[EXTCODEOFF + 1])); 1934 #ifdef NJSC32_DUALEDGE 1935 if (msgcnt != MSG_EXT_WDTR_LEN + EXTCODEOFF-1) 1936 break; /* reject */ 1937 1938 /* 1939 * T->I of this message is not used for 1940 * DualEdge negotiation, so the device 1941 * must not be a DualEdge device. 1942 * 1943 * XXX correct? 1944 */ 1945 target = cmd->c_target; 1946 target->t_xferctl = 0; 1947 1948 switch (target->t_state) { 1949 case NJSC32_TARST_DE: 1950 if (sc->sc_msginbuf[EXTCODEOFF + 1] != 1951 MSG_EXT_WDTR_BUS_8_BIT) { 1952 /* 1953 * Oops, we got unexpected WDTR. 1954 * Negotiate for 8bit. 1955 */ 1956 target->t_state = NJSC32_TARST_WDTR; 1957 } else { 1958 target->t_state = NJSC32_TARST_SDTR; 1959 } 1960 njsc32_negotiate_xfer(sc, target); 1961 goto reply; 1962 1963 case NJSC32_TARST_WDTR: 1964 if (sc->sc_msginbuf[EXTCODEOFF + 1] != 1965 MSG_EXT_WDTR_BUS_8_BIT) { 1966 printf("%s: unexpected transfer width:" 1967 " %#x\n", device_xname(sc->sc_dev), 1968 sc->sc_msginbuf[EXTCODEOFF + 1]); 1969 /* XXX what to do? */ 1970 } 1971 target->t_state = NJSC32_TARST_SDTR; 1972 njsc32_negotiate_xfer(sc, target); 1973 goto reply; 1974 1975 default: 1976 /* the target started WDTR exchange */ 1977 DPRINTC(cmd, ("WDTR from target\n")); 1978 1979 target->t_state = NJSC32_TARST_SDTR; 1980 njsc32_target_async(sc, target); 1981 1982 break; /* reject the WDTR (8bit transfer) */ 1983 } 1984 #endif /* NJSC32_DUALEDGE */ 1985 break; /* reject */ 1986 } 1987 DPRINTC(cmd, ("njsc32_msgin: reject ext msg %#x msgincnt %d\n", 1988 sc->sc_msginbuf[EXTCODEOFF], msgcnt)); 1989 goto reject; 1990 } 1991 1992 /* 2byte messages */ 1993 if (MSG_IS2BYTE(msg0)) { 1994 if (msgcnt == 0) 1995 WAITNEXTMSG; 1996 1997 /* got whole message */ 1998 sc->sc_msgincnt = 0; 1999 } 2000 2001 switch (msg0) { 2002 case MSG_CMDCOMPLETE: /* 0x00 */ 2003 case MSG_SAVEDATAPOINTER: /* 0x02 */ 2004 case MSG_DISCONNECT: /* 0x04 */ 2005 /* handled by AutoSCSI */ 2006 PRINTC(cmd, ("msgin: unexpected msg: %#x\n", msg0)); 2007 break; 2008 2009 case MSG_RESTOREPOINTERS: /* 0x03 */ 2010 /* restore data pointer to what was saved */ 2011 DPRINTC(cmd, ("njsc32_msgin: Restore Pointers\n")); 2012 njsc32_set_ptr(sc, cmd, cmd->c_dp_saved); 2013 reload_params = TRUE; 2014 MSGCOMPLETE; 2015 /* NOTREACHED */ 2016 break; 2017 2018 #if 0 /* handled above */ 2019 case MSG_EXTENDED: /* 0x01 */ 2020 #endif 2021 case MSG_MESSAGE_REJECT: /* 0x07 */ 2022 target = cmd->c_target; 2023 DPRINTC(cmd, ("Reject tarst %d\n", target->t_state)); 2024 switch (target->t_state) { 2025 #ifdef NJSC32_DUALEDGE 2026 case NJSC32_TARST_WDTR: 2027 case NJSC32_TARST_DE: 2028 target->t_xferctl = 0; 2029 target->t_state = NJSC32_TARST_SDTR; 2030 njsc32_negotiate_xfer(sc, target); 2031 goto reply; 2032 #endif 2033 case NJSC32_TARST_SDTR: 2034 case NJSC32_TARST_ASYNC: 2035 njsc32_target_async(sc, target); 2036 target->t_state = NJSC32_TARST_DONE; 2037 njsc32_update_xfer_mode(sc, target); 2038 break; 2039 default: 2040 break; 2041 } 2042 goto restart; 2043 2044 case MSG_NOOP: /* 0x08 */ 2045 #ifdef NJSC32_DUALEDGE 2046 target = cmd->c_target; 2047 if (target->t_state == NJSC32_TARST_DE) { 2048 printf("%s: DualEdge transfer\n", 2049 device_xname(sc->sc_dev)); 2050 target->t_xferctl = NJSC32_XFR_DUALEDGE_ENABLE; 2051 /* go to next negotiation */ 2052 target->t_state = NJSC32_TARST_SDTR; 2053 njsc32_negotiate_xfer(sc, target); 2054 goto reply; 2055 } 2056 #endif 2057 goto restart; 2058 2059 case MSG_INITIATOR_DET_ERR: /* 0x05 I->T only */ 2060 case MSG_ABORT: /* 0x06 I->T only */ 2061 case MSG_PARITY_ERROR: /* 0x09 I->T only */ 2062 case MSG_LINK_CMD_COMPLETE: /* 0x0a */ 2063 case MSG_LINK_CMD_COMPLETEF: /* 0x0b */ 2064 case MSG_BUS_DEV_RESET: /* 0x0c I->T only */ 2065 case MSG_ABORT_TAG: /* 0x0d I->T only */ 2066 case MSG_CLEAR_QUEUE: /* 0x0e I->T only */ 2067 2068 #if 0 /* handled above */ 2069 case MSG_SIMPLE_Q_TAG: /* 0x20 */ 2070 #endif 2071 case MSG_HEAD_OF_Q_TAG: /* 0x21 I->T only */ 2072 case MSG_ORDERED_Q_TAG: /* 0x22 I->T only */ 2073 case MSG_IGN_WIDE_RESIDUE: /* 0x23 */ 2074 2075 default: 2076 #ifdef NJSC32_DEBUG 2077 PRINTC(cmd, ("msgin: unsupported msg: %#x", msg0)); 2078 if (MSG_IS2BYTE(msg0)) 2079 printf(" %#x", msg); 2080 printf("\n"); 2081 #endif 2082 break; 2083 } 2084 2085 reject: 2086 njsc32_add_msgout(sc, MSG_MESSAGE_REJECT); 2087 2088 reply: 2089 msgout = njsc32_get_auto_msgout(sc); 2090 2091 restart: 2092 cctl = NJSC32_CMD_CLEAR_CDB_FIFO_PTR | 2093 NJSC32_CMD_AUTO_COMMAND_PHASE | 2094 NJSC32_CMD_AUTO_SCSI_RESTART; 2095 2096 /* 2097 * Be careful the second and latter bytes of Message In 2098 * shall not be absorbed by AutoSCSI. 2099 */ 2100 if (sc->sc_msgincnt == 0) 2101 cctl |= NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02; 2102 2103 if (sc->sc_msgoutlen != 0) 2104 cctl |= NJSC32_CMD_AUTO_ATN; 2105 2106 njsc32_write_4(sc, NJSC32_REG_SCSI_MSG_OUT, msgout); 2107 2108 /* (re)start AutoSCSI (may assert ATN) */ 2109 if (reload_params) { 2110 njsc32_cmd_reload(sc, cmd, cctl); 2111 } else { 2112 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl); 2113 } 2114 2115 /* +ATN -> -REQ: need 90ns delay? */ 2116 2117 njsc32_wait_req_negate(sc); /* wait for REQ negation */ 2118 2119 njsc32_negate_ack(sc); 2120 2121 return; 2122 } 2123 2124 static void 2125 njsc32_msgout(struct njsc32_softc *sc) 2126 { 2127 int cctl; 2128 u_int8_t bus; 2129 unsigned n; 2130 2131 if (sc->sc_msgoutlen == 0) { 2132 /* target entered to Message Out on unexpected timing */ 2133 njsc32_add_msgout(sc, MSG_NOOP); 2134 } 2135 2136 cctl = NJSC32_CMD_CLEAR_CDB_FIFO_PTR | 2137 NJSC32_CMD_AUTO_COMMAND_PHASE | NJSC32_CMD_AUTO_SCSI_RESTART | 2138 NJSC32_CMD_AUTO_MSGIN_00_04 | NJSC32_CMD_AUTO_MSGIN_02; 2139 2140 /* make sure target is in Message Out phase */ 2141 bus = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR); 2142 if ((bus & NJSC32_BUSMON_PHASE_MASK) != NJSC32_PHASE_MESSAGE_OUT) { 2143 /* 2144 * Message Out is aborted by target. 2145 */ 2146 printf("%s: njsc32_msgout: phase change %#x\n", 2147 device_xname(sc->sc_dev), bus); 2148 2149 /* XXX what to do? */ 2150 2151 /* restart AutoSCSI (negate ATN) */ 2152 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl); 2153 2154 sc->sc_msgoutidx = 0; 2155 return; 2156 } 2157 2158 n = sc->sc_msgoutidx; 2159 if (n == sc->sc_msgoutlen - 1) { 2160 /* 2161 * negate ATN before sending ACK 2162 */ 2163 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, 0); 2164 2165 sc->sc_msgoutidx = 0; /* target may retry Message Out */ 2166 } else { 2167 cctl |= NJSC32_CMD_AUTO_ATN; 2168 sc->sc_msgoutidx++; 2169 } 2170 2171 /* Send Message Out */ 2172 njsc32_write_1(sc, NJSC32_REG_SCSI_OUT_LATCH, sc->sc_msgout[n]); 2173 2174 /* DBn -> +ACK: need 55ns delay? */ 2175 2176 njsc32_assert_ack(sc); 2177 njsc32_wait_req_negate(sc); /* wait for REQ negation */ 2178 2179 /* restart AutoSCSI */ 2180 njsc32_write_2(sc, NJSC32_REG_COMMAND_CONTROL, cctl); 2181 2182 njsc32_negate_ack(sc); 2183 2184 /* 2185 * do not reset sc->sc_msgoutlen so the target 2186 * can retry Message Out phase 2187 */ 2188 } 2189 2190 static void 2191 njsc32_cmdtimeout(void *arg) 2192 { 2193 struct njsc32_cmd *cmd = arg; 2194 struct njsc32_softc *sc; 2195 int s; 2196 2197 PRINTC(cmd, ("command timeout\n")); 2198 2199 sc = cmd->c_sc; 2200 2201 s = splbio(); 2202 2203 if (sc->sc_stat == NJSC32_STAT_ARBIT) 2204 njsc32_arbitration_failed(sc); 2205 else { 2206 sc->sc_curcmd = NULL; 2207 sc->sc_stat = NJSC32_STAT_IDLE; 2208 njsc32_end_cmd(sc, cmd, XS_TIMEOUT); 2209 } 2210 2211 /* XXX? */ 2212 njsc32_init(sc, 1); /* bus reset */ 2213 2214 splx(s); 2215 } 2216 2217 static void 2218 njsc32_reseltimeout(void *arg) 2219 { 2220 struct njsc32_cmd *cmd = arg; 2221 struct njsc32_softc *sc; 2222 int s; 2223 2224 PRINTC(cmd, ("reselection timeout\n")); 2225 2226 sc = cmd->c_sc; 2227 2228 s = splbio(); 2229 2230 /* remove from disconnected list */ 2231 if (cmd->c_flags & NJSC32_CMD_TAGGED) { 2232 /* I_T_L_Q */ 2233 KASSERT(cmd->c_lu->lu_cmd == NULL); 2234 TAILQ_REMOVE(&cmd->c_lu->lu_q, cmd, c_q); 2235 } else { 2236 /* I_T_L */ 2237 KASSERT(cmd->c_lu->lu_cmd == cmd); 2238 cmd->c_lu->lu_cmd = NULL; 2239 } 2240 2241 njsc32_end_cmd(sc, cmd, XS_TIMEOUT); 2242 2243 /* XXX? */ 2244 njsc32_init(sc, 1); /* bus reset */ 2245 2246 splx(s); 2247 } 2248 2249 static inline void 2250 njsc32_end_auto(struct njsc32_softc *sc, struct njsc32_cmd *cmd, int auto_phase) 2251 { 2252 struct scsipi_xfer *xs; 2253 2254 if (auto_phase & NJSC32_XPHASE_MSGIN_02) { 2255 /* Message In: 0x02 Save Data Pointer */ 2256 2257 /* 2258 * Adjust saved data pointer 2259 * if the command is not completed yet. 2260 */ 2261 if ((auto_phase & NJSC32_XPHASE_MSGIN_00) == 0 && 2262 (auto_phase & 2263 (NJSC32_XPHASE_DATA_IN | NJSC32_XPHASE_DATA_OUT)) != 0) { 2264 njsc32_save_ptr(cmd); 2265 } 2266 TPRINTF(("BM %u, SGT %u, SACK %u, SAVED_ACK %u\n", 2267 njsc32_read_4(sc, NJSC32_REG_BM_CNT), 2268 njsc32_read_4(sc, NJSC32_REG_SGT_ADR), 2269 njsc32_read_4(sc, NJSC32_REG_SACK_CNT), 2270 njsc32_read_4(sc, NJSC32_REG_SAVED_ACK_CNT))); 2271 } 2272 2273 xs = cmd->c_xs; 2274 2275 if (auto_phase & NJSC32_XPHASE_MSGIN_00) { 2276 /* Command Complete */ 2277 TPRINTC(cmd, ("njsc32_intr: Command Complete\n")); 2278 switch (xs->status) { 2279 case SCSI_CHECK: case SCSI_QUEUE_FULL: case SCSI_BUSY: 2280 /* 2281 * scsipi layer will automatically handle the error 2282 */ 2283 njsc32_end_cmd(sc, cmd, XS_BUSY); 2284 break; 2285 default: 2286 xs->resid -= cmd->c_dp_max; 2287 njsc32_end_cmd(sc, cmd, XS_NOERROR); 2288 break; 2289 } 2290 } else if (auto_phase & NJSC32_XPHASE_MSGIN_04) { 2291 /* Disconnect */ 2292 TPRINTC(cmd, ("njsc32_intr: Disconnect\n")); 2293 2294 /* for ill-designed devices */ 2295 if ((xs->xs_periph->periph_quirks & PQUIRK_AUTOSAVE) != 0) 2296 njsc32_save_ptr(cmd); 2297 2298 /* 2299 * move current cmd to disconnected list 2300 */ 2301 if (cmd->c_flags & NJSC32_CMD_TAGGED) { 2302 /* I_T_L_Q */ 2303 if (cmd->c_flags & NJSC32_CMD_TAGGED_HEAD) 2304 TAILQ_INSERT_HEAD(&cmd->c_lu->lu_q, cmd, c_q); 2305 else 2306 TAILQ_INSERT_TAIL(&cmd->c_lu->lu_q, cmd, c_q); 2307 } else { 2308 /* I_T_L */ 2309 cmd->c_lu->lu_cmd = cmd; 2310 } 2311 2312 /* 2313 * schedule timeout -- avoid being 2314 * disconnected forever 2315 */ 2316 if ((xs->xs_control & XS_CTL_POLL) == 0) { 2317 callout_stop(&xs->xs_callout); 2318 callout_reset(&xs->xs_callout, mstohz(xs->timeout), 2319 njsc32_reseltimeout, cmd); 2320 } 2321 2322 } else { 2323 /* 2324 * target has come to Bus Free phase 2325 * probably to notify an error 2326 */ 2327 PRINTC(cmd, ("njsc32_intr: unexpected bus free\n")); 2328 /* try Request Sense */ 2329 xs->status = SCSI_CHECK; 2330 njsc32_end_cmd(sc, cmd, XS_BUSY); 2331 } 2332 } 2333 2334 int 2335 njsc32_intr(void *arg) 2336 { 2337 struct njsc32_softc *sc = arg; 2338 u_int16_t intr; 2339 u_int8_t arbstat, bus_phase; 2340 int auto_phase; 2341 int idbit; 2342 struct njsc32_cmd *cmd; 2343 2344 intr = njsc32_read_2(sc, NJSC32_REG_IRQ); 2345 if ((intr & NJSC32_IRQ_INTR_PENDING) == 0) 2346 return 0; /* not mine */ 2347 2348 TPRINTF(("%s: njsc32_intr: %#x\n", device_xname(sc->sc_dev), intr)); 2349 2350 #if 0 /* I don't think this is required */ 2351 /* mask interrupts */ 2352 njsc32_write_2(sc, NJSC32_REG_IRQ, NJSC32_IRQ_MASK_ALL); 2353 #endif 2354 2355 /* we got an interrupt, so stop the timer */ 2356 njsc32_write_2(sc, NJSC32_REG_TIMER, NJSC32_TIMER_STOP); 2357 2358 if (intr & NJSC32_IRQ_SCSIRESET) { 2359 printf("%s: detected bus reset\n", device_xname(sc->sc_dev)); 2360 /* make sure all devices on the bus are certainly reset */ 2361 njsc32_reset_bus(sc); 2362 goto out; 2363 } 2364 2365 if (sc->sc_stat == NJSC32_STAT_ARBIT) { 2366 cmd = sc->sc_curcmd; 2367 KASSERT(cmd); 2368 arbstat = njsc32_read_1(sc, NJSC32_REG_ARBITRATION_STAT); 2369 if (arbstat & (NJSC32_ARBSTAT_WIN | NJSC32_ARBSTAT_FAIL)) { 2370 /* 2371 * arbitration done 2372 */ 2373 /* clear arbitration status */ 2374 njsc32_write_1(sc, NJSC32_REG_SET_ARBITRATION, 2375 NJSC32_SETARB_CLEAR); 2376 2377 if (arbstat & NJSC32_ARBSTAT_WIN) { 2378 TPRINTC(cmd, 2379 ("njsc32_intr: arbitration won\n")); 2380 2381 TAILQ_REMOVE(&sc->sc_reqcmd, cmd, c_q); 2382 2383 sc->sc_stat = NJSC32_STAT_CONNECT; 2384 } else { 2385 TPRINTC(cmd, 2386 ("njsc32_intr: arbitration failed\n")); 2387 2388 njsc32_arbitration_failed(sc); 2389 2390 /* XXX delay */ 2391 /* XXX retry counter */ 2392 } 2393 } 2394 } 2395 2396 if (intr & NJSC32_IRQ_TIMER) { 2397 TPRINTF(("%s: njsc32_intr: timer interrupt\n", 2398 device_xname(sc->sc_dev))); 2399 } 2400 2401 if (intr & NJSC32_IRQ_RESELECT) { 2402 /* Reselection from a target */ 2403 njsc32_arbitration_failed(sc); /* just in case */ 2404 if ((cmd = sc->sc_curcmd) != NULL) { 2405 /* ? */ 2406 printf("%s: unexpected reselection\n", 2407 device_xname(sc->sc_dev)); 2408 sc->sc_curcmd = NULL; 2409 sc->sc_stat = NJSC32_STAT_IDLE; 2410 njsc32_end_cmd(sc, cmd, XS_DRIVER_STUFFUP); 2411 } 2412 2413 idbit = njsc32_read_1(sc, NJSC32_REG_RESELECT_ID); 2414 if ((idbit & (1 << NJSC32_INITIATOR_ID)) == 0 || 2415 (sc->sc_reselid = 2416 ffs(idbit & ~(1 << NJSC32_INITIATOR_ID)) - 1) < 0) { 2417 printf("%s: invalid reselection (id: %#x)\n", 2418 device_xname(sc->sc_dev), idbit); 2419 sc->sc_stat = NJSC32_STAT_IDLE; /* XXX ? */ 2420 } else { 2421 sc->sc_stat = NJSC32_STAT_RESEL; 2422 TPRINTF(("%s: njsc32_intr: reselection from %d\n", 2423 device_xname(sc->sc_dev), sc->sc_reselid)); 2424 } 2425 } 2426 2427 if (intr & NJSC32_IRQ_PHASE_CHANGE) { 2428 #if 1 /* XXX probably not needed */ 2429 if (sc->sc_stat == NJSC32_STAT_ARBIT) 2430 PRINTC(sc->sc_curcmd, 2431 ("njsc32_intr: cancel arbitration phase\n")); 2432 njsc32_arbitration_failed(sc); 2433 #endif 2434 /* current bus phase */ 2435 bus_phase = njsc32_read_1(sc, NJSC32_REG_SCSI_BUS_MONITOR) & 2436 NJSC32_BUSMON_PHASE_MASK; 2437 2438 switch (bus_phase) { 2439 case NJSC32_PHASE_MESSAGE_IN: 2440 njsc32_msgin(sc); 2441 break; 2442 2443 /* 2444 * target may suddenly become Status / Bus Free phase 2445 * to notify an error condition 2446 */ 2447 case NJSC32_PHASE_STATUS: 2448 printf("%s: unexpected bus phase: Status\n", 2449 device_xname(sc->sc_dev)); 2450 if ((cmd = sc->sc_curcmd) != NULL) { 2451 cmd->c_xs->status = 2452 njsc32_read_1(sc, NJSC32_REG_SCSI_CSB_IN); 2453 TPRINTC(cmd, ("njsc32_intr: Status %d\n", 2454 cmd->c_xs->status)); 2455 } 2456 break; 2457 case NJSC32_PHASE_BUSFREE: 2458 printf("%s: unexpected bus phase: Bus Free\n", 2459 device_xname(sc->sc_dev)); 2460 if ((cmd = sc->sc_curcmd) != NULL) { 2461 sc->sc_curcmd = NULL; 2462 sc->sc_stat = NJSC32_STAT_IDLE; 2463 if (cmd->c_xs->status != SCSI_QUEUE_FULL && 2464 cmd->c_xs->status != SCSI_BUSY) 2465 cmd->c_xs->status = SCSI_CHECK;/* XXX */ 2466 njsc32_end_cmd(sc, cmd, XS_BUSY); 2467 } 2468 goto out; 2469 default: 2470 #ifdef NJSC32_DEBUG 2471 printf("%s: unexpected bus phase: ", 2472 device_xname(sc->sc_dev)); 2473 switch (bus_phase) { 2474 case NJSC32_PHASE_COMMAND: 2475 printf("Command\n"); 2476 break; 2477 case NJSC32_PHASE_MESSAGE_OUT: 2478 printf("Message Out\n"); 2479 break; 2480 case NJSC32_PHASE_DATA_IN: 2481 printf("Data In\n"); 2482 break; 2483 case NJSC32_PHASE_DATA_OUT: 2484 printf("Data Out\n"); 2485 break; 2486 case NJSC32_PHASE_RESELECT: 2487 printf("Reselect\n"); 2488 break; 2489 default: 2490 printf("%#x\n", bus_phase); 2491 break; 2492 } 2493 #else 2494 printf("%s: unexpected bus phase: %#x", 2495 device_xname(sc->sc_dev), bus_phase); 2496 #endif 2497 break; 2498 } 2499 } 2500 2501 if (intr & NJSC32_IRQ_AUTOSCSI) { 2502 /* 2503 * AutoSCSI interrupt 2504 */ 2505 auto_phase = njsc32_read_2(sc, NJSC32_REG_EXECUTE_PHASE); 2506 TPRINTF(("%s: njsc32_intr: AutoSCSI: %#x\n", 2507 device_xname(sc->sc_dev), auto_phase)); 2508 njsc32_write_2(sc, NJSC32_REG_EXECUTE_PHASE, 0); 2509 2510 if (auto_phase & NJSC32_XPHASE_SEL_TIMEOUT) { 2511 cmd = sc->sc_curcmd; 2512 if (cmd == NULL) { 2513 printf("%s: sel no cmd\n", 2514 device_xname(sc->sc_dev)); 2515 goto out; 2516 } 2517 DPRINTC(cmd, ("njsc32_intr: selection timeout\n")); 2518 2519 sc->sc_curcmd = NULL; 2520 sc->sc_stat = NJSC32_STAT_IDLE; 2521 njsc32_end_cmd(sc, cmd, XS_SELTIMEOUT); 2522 2523 goto out; 2524 } 2525 2526 #ifdef NJSC32_TRACE 2527 if (auto_phase & NJSC32_XPHASE_COMMAND) { 2528 /* Command phase has been automatically processed */ 2529 TPRINTF(("%s: njsc32_intr: Command\n", 2530 device_xname(sc->sc_dev))); 2531 } 2532 #endif 2533 #ifdef NJSC32_DEBUG 2534 if (auto_phase & NJSC32_XPHASE_ILLEGAL) { 2535 printf("%s: njsc32_intr: Illegal phase\n", 2536 device_xname(sc->sc_dev)); 2537 } 2538 #endif 2539 2540 if (auto_phase & NJSC32_XPHASE_PAUSED_MSG_IN) { 2541 TPRINTF(("%s: njsc32_intr: Process Message In\n", 2542 device_xname(sc->sc_dev))); 2543 njsc32_msgin(sc); 2544 } 2545 2546 if (auto_phase & NJSC32_XPHASE_PAUSED_MSG_OUT) { 2547 TPRINTF(("%s: njsc32_intr: Process Message Out\n", 2548 device_xname(sc->sc_dev))); 2549 njsc32_msgout(sc); 2550 } 2551 2552 cmd = sc->sc_curcmd; 2553 if (cmd == NULL) { 2554 TPRINTF(("%s: njsc32_intr: no cmd\n", 2555 device_xname(sc->sc_dev))); 2556 goto out; 2557 } 2558 2559 if (auto_phase & 2560 (NJSC32_XPHASE_DATA_IN | NJSC32_XPHASE_DATA_OUT)) { 2561 u_int32_t sackcnt, cntoffset; 2562 2563 #ifdef NJSC32_TRACE 2564 if (auto_phase & NJSC32_XPHASE_DATA_IN) 2565 PRINTC(cmd, ("njsc32_intr: data in done\n")); 2566 if (auto_phase & NJSC32_XPHASE_DATA_OUT) 2567 PRINTC(cmd, ("njsc32_intr: data out done\n")); 2568 printf("BM %u, SGT %u, SACK %u, SAVED_ACK %u\n", 2569 njsc32_read_4(sc, NJSC32_REG_BM_CNT), 2570 njsc32_read_4(sc, NJSC32_REG_SGT_ADR), 2571 njsc32_read_4(sc, NJSC32_REG_SACK_CNT), 2572 njsc32_read_4(sc, NJSC32_REG_SAVED_ACK_CNT)); 2573 #endif 2574 2575 /* 2576 * detected parity error on data transfer? 2577 */ 2578 if (njsc32_read_1(sc, NJSC32_REG_PARITY_STATUS) & 2579 (NJSC32_PARITYSTATUS_ERROR_LSB| 2580 NJSC32_PARITYSTATUS_ERROR_MSB)) { 2581 2582 PRINTC(cmd, ("datain: parity error\n")); 2583 2584 /* clear parity error */ 2585 njsc32_write_1(sc, NJSC32_REG_PARITY_CONTROL, 2586 NJSC32_PARITYCTL_CHECK_ENABLE | 2587 NJSC32_PARITYCTL_CLEAR_ERROR); 2588 2589 if (auto_phase & NJSC32_XPHASE_BUS_FREE) { 2590 /* 2591 * XXX command has already finished 2592 * -- what can we do? 2593 * 2594 * It is not clear current command 2595 * caused the error -- reset everything. 2596 */ 2597 njsc32_init(sc, 1); /* XXX */ 2598 } else { 2599 /* XXX does this case occur? */ 2600 #if 1 2601 printf("%s: datain: parity error\n", 2602 device_xname(sc->sc_dev)); 2603 #endif 2604 /* 2605 * Make attention condition and try 2606 * to send Initiator Detected Error 2607 * message. 2608 */ 2609 njsc32_init_msgout(sc); 2610 njsc32_add_msgout(sc, 2611 MSG_INITIATOR_DET_ERR); 2612 njsc32_write_4(sc, 2613 NJSC32_REG_SCSI_MSG_OUT, 2614 njsc32_get_auto_msgout(sc)); 2615 /* restart autoscsi with ATN */ 2616 njsc32_write_2(sc, 2617 NJSC32_REG_COMMAND_CONTROL, 2618 NJSC32_CMD_CLEAR_CDB_FIFO_PTR | 2619 NJSC32_CMD_AUTO_COMMAND_PHASE | 2620 NJSC32_CMD_AUTO_SCSI_RESTART | 2621 NJSC32_CMD_AUTO_MSGIN_00_04 | 2622 NJSC32_CMD_AUTO_MSGIN_02 | 2623 NJSC32_CMD_AUTO_ATN); 2624 } 2625 goto out; 2626 } 2627 2628 /* 2629 * data has been transferred, and current pointer 2630 * is changed 2631 */ 2632 sackcnt = njsc32_read_4(sc, NJSC32_REG_SACK_CNT); 2633 2634 /* 2635 * The controller returns extra ACK count 2636 * if the DMA buffer is not 4byte aligned. 2637 */ 2638 cntoffset = le32toh(cmd->c_sgt[0].sg_addr) & 3; 2639 #ifdef NJSC32_DEBUG 2640 if (cntoffset != 0) { 2641 printf("sackcnt %u, cntoffset %u\n", 2642 sackcnt, cntoffset); 2643 } 2644 #endif 2645 /* advance SCSI pointer */ 2646 njsc32_set_cur_ptr(cmd, 2647 cmd->c_dp_cur + sackcnt - cntoffset); 2648 } 2649 2650 if (auto_phase & NJSC32_XPHASE_MSGOUT) { 2651 /* Message Out phase has been automatically processed */ 2652 TPRINTC(cmd, ("njsc32_intr: Message Out\n")); 2653 if ((auto_phase & NJSC32_XPHASE_PAUSED_MSG_IN) == 0 && 2654 sc->sc_msgoutlen <= NJSC32_MSGOUT_MAX_AUTO) { 2655 njsc32_init_msgout(sc); 2656 } 2657 } 2658 2659 if (auto_phase & NJSC32_XPHASE_STATUS) { 2660 /* Status phase has been automatically processed */ 2661 cmd->c_xs->status = 2662 njsc32_read_1(sc, NJSC32_REG_SCSI_CSB_IN); 2663 TPRINTC(cmd, ("njsc32_intr: Status %#x\n", 2664 cmd->c_xs->status)); 2665 } 2666 2667 if (auto_phase & NJSC32_XPHASE_BUS_FREE) { 2668 /* AutoSCSI is finished */ 2669 2670 TPRINTC(cmd, ("njsc32_intr: Bus Free\n")); 2671 2672 sc->sc_stat = NJSC32_STAT_IDLE; 2673 sc->sc_curcmd = NULL; 2674 2675 njsc32_end_auto(sc, cmd, auto_phase); 2676 } 2677 goto out; 2678 } 2679 2680 if (intr & NJSC32_IRQ_FIFO_THRESHOLD) { 2681 /* XXX We use DMA, and this shouldn't happen */ 2682 printf("%s: njsc32_intr: FIFO\n", device_xname(sc->sc_dev)); 2683 njsc32_init(sc, 1); 2684 goto out; 2685 } 2686 if (intr & NJSC32_IRQ_PCI) { 2687 /* XXX? */ 2688 printf("%s: njsc32_intr: PCI\n", device_xname(sc->sc_dev)); 2689 } 2690 if (intr & NJSC32_IRQ_BMCNTERR) { 2691 /* XXX? */ 2692 printf("%s: njsc32_intr: BM\n", device_xname(sc->sc_dev)); 2693 } 2694 2695 out: 2696 /* go next command if controller is idle */ 2697 if (sc->sc_stat == NJSC32_STAT_IDLE) 2698 njsc32_start(sc); 2699 2700 #if 0 2701 /* enable interrupts */ 2702 njsc32_write_2(sc, NJSC32_REG_IRQ, 0); 2703 #endif 2704 2705 return 1; /* processed */ 2706 } 2707