1 /* $NetBSD: mha.c,v 1.52 2009/11/23 00:11:45 rmind Exp $ */ 2 3 /*- 4 * Copyright (c) 1996-1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum, Masaru Oki, Takumi Nakamura, Masanobu Saitoh and 9 * Minoura Makoto. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /*- 34 * Copyright (c) 1994 Jarle Greipsland 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. The name of the author may not be used to endorse or promote products 46 * derived from this software without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 51 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 52 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 57 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61 #include <sys/cdefs.h> 62 __KERNEL_RCSID(0, "$NetBSD: mha.c,v 1.52 2009/11/23 00:11:45 rmind Exp $"); 63 64 #include "opt_ddb.h" 65 66 /* Synchronous data transfers? */ 67 #define SPC_USE_SYNCHRONOUS 0 68 #define SPC_SYNC_REQ_ACK_OFS 8 69 70 /* Default DMA mode? */ 71 #define MHA_DMA_LIMIT_XFER 1 72 #define MHA_DMA_BURST_XFER 1 73 #define MHA_DMA_SHORT_BUS_CYCLE 1 74 75 #define MHA_DMA_DATAIN (0 | (MHA_DMA_LIMIT_XFER << 1) \ 76 | (MHA_DMA_BURST_XFER << 2) \ 77 | (MHA_DMA_SHORT_BUS_CYCLE << 3)) 78 #define MHA_DMA_DATAOUT (1 | (MHA_DMA_LIMIT_XFER << 1) \ 79 | (MHA_DMA_BURST_XFER << 2) \ 80 | (MHA_DMA_SHORT_BUS_CYCLE << 3)) 81 82 /* Include debug functions? At the end of this file there are a bunch of 83 * functions that will print out various information regarding queued SCSI 84 * commands, driver state and chip contents. You can call them from the 85 * kernel debugger. If you set SPC_DEBUG to 0 they are not included (the 86 * kernel uses less memory) but you lose the debugging facilities. 87 */ 88 #define SPC_DEBUG 0 89 90 /* End of customizable parameters */ 91 92 /* 93 * MB86601A SCSI Protocol Controller (SPC) routines for MANKAI Mach-2 94 */ 95 96 #include <sys/types.h> 97 #include <sys/param.h> 98 #include <sys/systm.h> 99 #include <sys/kernel.h> 100 #include <sys/errno.h> 101 #include <sys/ioctl.h> 102 #include <sys/device.h> 103 #include <sys/buf.h> 104 #include <sys/proc.h> 105 #include <sys/queue.h> 106 107 #include <machine/bus.h> 108 109 #include <dev/scsipi/scsi_spc.h> 110 #include <dev/scsipi/scsi_all.h> 111 #include <dev/scsipi/scsipi_all.h> 112 #include <dev/scsipi/scsi_message.h> 113 #include <dev/scsipi/scsiconf.h> 114 115 #include <x68k/x68k/iodevice.h> 116 #include <x68k/dev/mb86601reg.h> 117 #include <x68k/dev/mhavar.h> 118 #include <x68k/dev/intiovar.h> 119 #include <x68k/dev/scsiromvar.h> 120 121 #if 0 122 #define WAIT {if (sc->sc_pc[2]) {printf("[W_%d", __LINE__); while (sc->sc_pc[2] & 0x40);printf("]");}} 123 #else 124 #define WAIT {while (sc->sc_pc[2] & 0x40);} 125 #endif 126 127 #define SSR (sc->sc_pc[2]) 128 #define SS_IREQUEST 0x80 129 #define SS_BUSY 0x40 130 #define SS_DREG_FULL 0x02 131 132 #define NSR (sc->sc_pc[3]) 133 134 #define SIR (sc->sc_pc[4]) 135 136 #define CMR (sc->sc_pc[5]) 137 #define CMD_SEL_AND_CMD 0x00 138 #define CMD_SELECT 0x09 139 #define CMD_SET_ATN 0x0a 140 #define CMD_RESET_ATN 0x0b 141 #define CMD_RESET_ACK 0x0d 142 #define CMD_SEND_FROM_MPU 0x10 143 #define CMD_SEND_FROM_DMA 0x11 144 #define CMD_RECEIVE_TO_MPU 0x12 145 #define CMD_RECEIVE_TO_DMA 0x13 146 #define CMD_RECEIVE_MSG 0x1a 147 #define CMD_RECEIVE_STS 0x1c 148 #define CMD_SOFT_RESET 0x40 149 #define CMD_SCSI_RESET 0x42 150 #define CMD_SET_UP_REG 0x43 151 152 #define SCR (sc->sc_pc[11]) 153 154 #define TMR (sc->sc_pc[12]) 155 #define TM_SYNC 0x80 156 #define TM_ASYNC 0x00 157 158 #define WAR (sc->sc_pc[15]) 159 #define WA_MCSBUFWIN 0x00 160 #define WA_UPMWIN 0x80 161 #define WA_INITWIN 0xc0 162 163 #define MBR (sc->sc_pc[15]) 164 165 #define ISCSR (sc->sc_ps[2]) 166 167 #define CCR (sc->sc_pcx[0]) 168 #define OIR (sc->sc_pcx[1]) 169 #define AMR (sc->sc_pcx[2]) 170 #define SMR (sc->sc_pcx[3]) 171 #define SRR (sc->sc_pcx[4]) 172 #define STR (sc->sc_pcx[5]) 173 #define RTR (sc->sc_pcx[6]) 174 #define ATR (sc->sc_pcx[7]) 175 #define PER (sc->sc_pcx[8]) 176 #define IER (sc->sc_pcx[9]) 177 #define IE_ALL 0xBF 178 179 #define GLR (sc->sc_pcx[10]) 180 #define DMR (sc->sc_pcx[11]) 181 #define IMR (sc->sc_pcx[12]) 182 183 #ifndef DDB 184 #define Debugger() panic("should call debugger here (mha.c)") 185 #endif /* ! DDB */ 186 187 188 #if SPC_DEBUG 189 #define SPC_SHOWACBS 0x01 190 #define SPC_SHOWINTS 0x02 191 #define SPC_SHOWCMDS 0x04 192 #define SPC_SHOWMISC 0x08 193 #define SPC_SHOWTRAC 0x10 194 #define SPC_SHOWSTART 0x20 195 #define SPC_SHOWPHASE 0x40 196 #define SPC_SHOWDMA 0x80 197 #define SPC_SHOWCCMDS 0x100 198 #define SPC_SHOWMSGS 0x200 199 #define SPC_DOBREAK 0x400 200 201 int mha_debug = 202 #if 0 203 0x7FF; 204 #else 205 SPC_SHOWSTART|SPC_SHOWTRAC; 206 #endif 207 208 209 #define SPC_ACBS(str) do {if (mha_debug & SPC_SHOWACBS) printf str;} while (0) 210 #define SPC_MISC(str) do {if (mha_debug & SPC_SHOWMISC) printf str;} while (0) 211 #define SPC_INTS(str) do {if (mha_debug & SPC_SHOWINTS) printf str;} while (0) 212 #define SPC_TRACE(str) do {if (mha_debug & SPC_SHOWTRAC) printf str;} while (0) 213 #define SPC_CMDS(str) do {if (mha_debug & SPC_SHOWCMDS) printf str;} while (0) 214 #define SPC_START(str) do {if (mha_debug & SPC_SHOWSTART) printf str;}while (0) 215 #define SPC_PHASE(str) do {if (mha_debug & SPC_SHOWPHASE) printf str;}while (0) 216 #define SPC_DMA(str) do {if (mha_debug & SPC_SHOWDMA) printf str;}while (0) 217 #define SPC_MSGS(str) do {if (mha_debug & SPC_SHOWMSGS) printf str;}while (0) 218 #define SPC_BREAK() do {if ((mha_debug & SPC_DOBREAK) != 0) Debugger();} while (0) 219 #define SPC_ASSERT(x) do {if (x) {} else {printf("%s at line %d: assertion failed\n", device_xname(sc->sc_dev), __LINE__); Debugger();}} while (0) 220 #else 221 #define SPC_ACBS(str) 222 #define SPC_MISC(str) 223 #define SPC_INTS(str) 224 #define SPC_TRACE(str) 225 #define SPC_CMDS(str) 226 #define SPC_START(str) 227 #define SPC_PHASE(str) 228 #define SPC_DMA(str) 229 #define SPC_MSGS(str) 230 #define SPC_BREAK() 231 #define SPC_ASSERT(x) 232 #endif 233 234 int mhamatch(device_t, cfdata_t, void *); 235 void mhaattach(device_t, device_t, void *); 236 void mhaselect(struct mha_softc *, u_char, u_char, u_char *, u_char); 237 void mha_scsi_reset(struct mha_softc *); 238 void mha_reset(struct mha_softc *); 239 void mha_free_acb(struct mha_softc *, struct acb *, int); 240 void mha_sense(struct mha_softc *, struct acb *); 241 void mha_msgin(struct mha_softc *); 242 void mha_msgout(struct mha_softc *); 243 int mha_dataout_pio(struct mha_softc *, u_char *, int); 244 int mha_datain_pio(struct mha_softc *, u_char *, int); 245 int mha_dataout(struct mha_softc *, u_char *, int); 246 int mha_datain(struct mha_softc *, u_char *, int); 247 void mha_abort(struct mha_softc *, struct acb *); 248 void mha_init(struct mha_softc *); 249 void mha_scsi_request(struct scsipi_channel *, scsipi_adapter_req_t, void *); 250 void mha_poll(struct mha_softc *, struct acb *); 251 void mha_sched(struct mha_softc *); 252 void mha_done(struct mha_softc *, struct acb *); 253 int mhaintr(void *); 254 void mha_timeout(void *); 255 void mha_minphys(struct buf *); 256 void mha_dequeue(struct mha_softc *, struct acb *); 257 inline void mha_setsync(struct mha_softc *, struct spc_tinfo *); 258 #if SPC_DEBUG 259 void mha_print_acb(struct acb *); 260 void mha_show_scsi_cmd(struct acb *); 261 void mha_print_active_acb(void); 262 void mha_dump_driver(struct mha_softc *); 263 #endif 264 265 static int mha_dataio_dma(int, int, struct mha_softc *, u_char *, int); 266 267 CFATTACH_DECL_NEW(mha, sizeof(struct mha_softc), 268 mhamatch, mhaattach, NULL, NULL); 269 270 extern struct cfdriver mha_cd; 271 272 /* 273 * returns non-zero value if a controller is found. 274 */ 275 int 276 mhamatch(device_t parent, cfdata_t cf, void *aux) 277 { 278 struct intio_attach_args *ia = aux; 279 bus_space_tag_t iot = ia->ia_bst; 280 bus_space_handle_t ioh; 281 282 ia->ia_size=0x20; 283 if (ia->ia_addr != 0xea0000) 284 return 0; 285 286 if (intio_map_allocate_region(device_parent(parent), ia, 287 INTIO_MAP_TESTONLY) < 0) /* FAKE */ 288 return 0; 289 290 if (bus_space_map(iot, ia->ia_addr, 0x20, BUS_SPACE_MAP_SHIFTED, 291 &ioh) < 0) 292 return 0; 293 if (!badaddr((void *)IIOV(ia->ia_addr + 0))) 294 return 0; 295 bus_space_unmap(iot, ioh, 0x20); 296 297 return 1; 298 } 299 300 /* 301 */ 302 303 struct mha_softc *tmpsc; 304 305 void 306 mhaattach(device_t parent, device_t self, void *aux) 307 { 308 struct mha_softc *sc = device_private(self); 309 struct intio_attach_args *ia = aux; 310 311 tmpsc = sc; /* XXX */ 312 sc->sc_dev = self; 313 314 aprint_normal(": Mankai Mach-2 Fast SCSI Host Adaptor\n"); 315 316 SPC_TRACE(("mhaattach ")); 317 sc->sc_state = SPC_INIT; 318 sc->sc_iobase = (void *)IIOV(ia->ia_addr + 0x80); /* XXX */ 319 intio_map_allocate_region(device_parent(parent), ia, INTIO_MAP_ALLOCATE); 320 /* XXX: FAKE */ 321 sc->sc_dmat = ia->ia_dmat; 322 323 sc->sc_pc = (volatile u_char *)sc->sc_iobase; 324 sc->sc_ps = (volatile u_short *)sc->sc_iobase; 325 sc->sc_pcx = &sc->sc_pc[0x10]; 326 327 sc->sc_id = IODEVbase->io_sram[0x70] & 0x7; /* XXX */ 328 329 intio_intr_establish(ia->ia_intr, "mha", mhaintr, sc); 330 331 mha_init(sc); /* Init chip and driver */ 332 333 mha_scsi_reset(sc); /* XXX: some devices need this. */ 334 335 sc->sc_phase = BUSFREE_PHASE; 336 337 /* 338 * Fill in the adapter. 339 */ 340 sc->sc_adapter.adapt_dev = sc->sc_dev; 341 sc->sc_adapter.adapt_nchannels = 1; 342 sc->sc_adapter.adapt_openings = 7; 343 sc->sc_adapter.adapt_max_periph = 1; 344 sc->sc_adapter.adapt_ioctl = NULL; 345 sc->sc_adapter.adapt_minphys = mha_minphys; 346 sc->sc_adapter.adapt_request = mha_scsi_request; 347 348 sc->sc_channel.chan_adapter = &sc->sc_adapter; 349 sc->sc_channel.chan_bustype = &scsi_bustype; 350 sc->sc_channel.chan_channel = 0; 351 sc->sc_channel.chan_ntargets = 8; 352 sc->sc_channel.chan_nluns = 8; 353 sc->sc_channel.chan_id = sc->sc_id; 354 355 sc->sc_spcinitialized = 0; 356 WAR = WA_INITWIN; 357 #if 1 358 CCR = 0x14; 359 OIR = sc->sc_id; 360 AMR = 0x00; 361 SMR = 0x00; 362 SRR = 0x00; 363 STR = 0x20; 364 RTR = 0x40; 365 ATR = 0x01; 366 PER = 0xc9; 367 #endif 368 IER = IE_ALL; /* $B$9$Y$F$N3d$j9~$_$r5v2D(B */ 369 #if 1 370 GLR = 0x00; 371 DMR = 0x30; 372 IMR = 0x00; 373 #endif 374 WAR = WA_MCSBUFWIN; 375 376 /* drop off */ 377 while (SSR & SS_IREQUEST) { 378 (void) ISCSR; 379 } 380 381 CMR = CMD_SET_UP_REG; /* setup reg cmd. */ 382 383 SPC_TRACE(("waiting for intr...")); 384 while (!(SSR & SS_IREQUEST)) 385 delay(10); 386 mhaintr(sc); 387 388 tmpsc = NULL; 389 390 config_found(self, &sc->sc_channel, scsiprint); 391 } 392 393 #if 0 394 void 395 mha_reset(struct mha_softc *sc) 396 { 397 u_short dummy; 398 printf("reset..."); 399 CMR = CMD_SOFT_RESET; 400 __asm volatile ("nop"); /* XXX wait (4clk in 20 MHz) ??? */ 401 dummy = sc->sc_ps[-1]; 402 dummy = sc->sc_ps[-1]; 403 dummy = sc->sc_ps[-1]; 404 dummy = sc->sc_ps[-1]; 405 __asm volatile ("nop"); 406 CMR = CMD_SOFT_RESET; 407 sc->sc_spcinitialized = 0; 408 CMR = CMD_SET_UP_REG; /* setup reg cmd. */ 409 while(!sc->sc_spcinitialized); 410 411 sc->sc_id = IODEVbase->io_sram[0x70] & 0x7; /* XXX */ 412 printf("done.\n"); 413 } 414 #endif 415 416 /* 417 * Pull the SCSI RST line for 500us. 418 */ 419 void 420 mha_scsi_reset(struct mha_softc *sc) 421 { 422 423 CMR = CMD_SCSI_RESET; /* SCSI RESET */ 424 while (!(SSR&SS_IREQUEST)) 425 delay(10); 426 } 427 428 /* 429 * Initialize mha SCSI driver. 430 */ 431 void 432 mha_init(struct mha_softc *sc) 433 { 434 struct acb *acb; 435 int r; 436 437 if (sc->sc_state == SPC_INIT) { 438 /* First time through; initialize. */ 439 TAILQ_INIT(&sc->ready_list); 440 TAILQ_INIT(&sc->nexus_list); 441 TAILQ_INIT(&sc->free_list); 442 sc->sc_nexus = NULL; 443 acb = sc->sc_acb; 444 memset(acb, 0, sizeof(sc->sc_acb)); 445 for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) { 446 TAILQ_INSERT_TAIL(&sc->free_list, acb, chain); 447 acb++; 448 } 449 memset(&sc->sc_tinfo, 0, sizeof(sc->sc_tinfo)); 450 451 r = bus_dmamem_alloc(sc->sc_dmat, MAXBSIZE, 0, 0, 452 sc->sc_dmaseg, 1, &sc->sc_ndmasegs, 453 BUS_DMA_NOWAIT); 454 if (r) 455 panic("mha_init: cannot allocate DMA memory"); 456 if (sc->sc_ndmasegs != 1) 457 panic("mha_init: number of segment > 1??"); 458 r = bus_dmamem_map(sc->sc_dmat, sc->sc_dmaseg, sc->sc_ndmasegs, 459 MAXBSIZE, &sc->sc_dmabuf, BUS_DMA_NOWAIT); 460 if (r) 461 panic("mha_init: cannot map DMA memory"); 462 r = bus_dmamap_create(sc->sc_dmat, MAXBSIZE, 1, 463 MAXBSIZE, 0, BUS_DMA_NOWAIT, 464 &sc->sc_dmamap); 465 if (r) 466 panic("mha_init: cannot create dmamap structure"); 467 r = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, 468 sc->sc_dmabuf, MAXBSIZE, NULL, 469 BUS_DMA_NOWAIT); 470 if (r) 471 panic("mha_init: cannot load DMA buffer into dmamap"); 472 sc->sc_p = 0; 473 } else { 474 /* Cancel any active commands. */ 475 sc->sc_flags |= SPC_ABORTING; 476 sc->sc_state = SPC_IDLE; 477 if ((acb = sc->sc_nexus) != NULL) { 478 acb->xs->error = XS_DRIVER_STUFFUP; 479 mha_done(sc, acb); 480 } 481 while ((acb = TAILQ_FIRST(&sc->nexus_list)) != NULL) { 482 acb->xs->error = XS_DRIVER_STUFFUP; 483 mha_done(sc, acb); 484 } 485 } 486 487 sc->sc_phase = sc->sc_prevphase = INVALID_PHASE; 488 for (r = 0; r < 8; r++) { 489 struct spc_tinfo *ti = &sc->sc_tinfo[r]; 490 491 ti->flags = 0; 492 #if SPC_USE_SYNCHRONOUS 493 ti->flags |= T_SYNCMODE; 494 ti->period = sc->sc_minsync; 495 ti->offset = SPC_SYNC_REQ_ACK_OFS; 496 #else 497 ti->period = ti->offset = 0; 498 #endif 499 ti->width = 0; 500 } 501 502 sc->sc_state = SPC_IDLE; 503 } 504 505 void 506 mha_free_acb(struct mha_softc *sc, struct acb *acb, int flags) 507 { 508 int s; 509 510 s = splbio(); 511 512 acb->flags = 0; 513 TAILQ_INSERT_HEAD(&sc->free_list, acb, chain); 514 515 /* 516 * If there were none, wake anybody waiting for one to come free, 517 * starting with queued entries. 518 */ 519 if (TAILQ_NEXT(acb, chain) == NULL) 520 wakeup(&sc->free_list); 521 522 splx(s); 523 } 524 525 /* 526 * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS 527 */ 528 529 /* 530 * Expected sequence: 531 * 1) Command inserted into ready list 532 * 2) Command selected for execution 533 * 3) Command won arbitration and has selected target device 534 * 4) Send message out (identify message, eventually also sync.negotiations) 535 * 5) Send command 536 * 5a) Receive disconnect message, disconnect. 537 * 5b) Reselected by target 538 * 5c) Receive identify message from target. 539 * 6) Send or receive data 540 * 7) Receive status 541 * 8) Receive message (command complete etc.) 542 * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd. 543 * Repeat 2-8 (no disconnects please...) 544 */ 545 546 /* 547 * Start a selection. This is used by mha_sched() to select an idle target, 548 * and by mha_done() to immediately reselect a target to get sense information. 549 */ 550 void 551 mhaselect(struct mha_softc *sc, u_char target, u_char lun, u_char *cmd, 552 u_char clen) 553 { 554 int i; 555 int s; 556 557 s = splbio(); /* XXX */ 558 559 SPC_TRACE(("[mhaselect(t%d,l%d,cmd:%x)] ", target, lun, *(u_char *)cmd)); 560 561 /* CDB $B$r(B SPC $B$N(B MCS REG $B$K%;%C%H$9$k(B */ 562 /* Now the command into the FIFO */ 563 WAIT; 564 #if 1 565 SPC_MISC(("[cmd:")); 566 for (i = 0; i < clen; i++) { 567 unsigned c = cmd[i]; 568 if (i == 1) 569 c |= lun << 5; 570 SPC_MISC((" %02x", c)); 571 sc->sc_pcx[i] = c; 572 } 573 SPC_MISC(("], target=%d\n", target)); 574 #else 575 memcpy(sc->sc_pcx, cmd, clen); 576 #endif 577 if (NSR & 0x80) 578 panic("scsistart: already selected..."); 579 sc->sc_phase = COMMAND_PHASE; 580 581 /* new state ASP_SELECTING */ 582 sc->sc_state = SPC_SELECTING; 583 584 SIR = target; 585 #if 0 586 CMR = CMD_SELECT; 587 #else 588 CMR = CMD_SEL_AND_CMD; /* select & cmd */ 589 #endif 590 splx(s); 591 } 592 593 #if 0 594 int 595 mha_reselect(struct mha_softc *sc, u_char message) 596 { 597 u_char selid, target, lun; 598 struct acb *acb; 599 struct scsipi_periph *periph; 600 struct spc_tinfo *ti; 601 602 /* 603 * The SCSI chip made a snapshot of the data bus while the reselection 604 * was being negotiated. This enables us to determine which target did 605 * the reselect. 606 */ 607 selid = sc->sc_selid & ~(1 << sc->sc_id); 608 if (selid & (selid - 1)) { 609 printf("%s: reselect with invalid selid %02x; sending DEVICE RESET\n", 610 device_xname(sc->sc_dev), selid); 611 SPC_BREAK(); 612 goto reset; 613 } 614 615 /* 616 * Search wait queue for disconnected cmd 617 * The list should be short, so I haven't bothered with 618 * any more sophisticated structures than a simple 619 * singly linked list. 620 */ 621 target = ffs(selid) - 1; 622 lun = message & 0x07; 623 TAILQ_FOREACH(acb, &sc->nexus_list, chain) { 624 periph = acb->xs->xs_periph; 625 if (periph->periph_target == target && 626 periph->periph_lun == lun) 627 break; 628 } 629 if (acb == NULL) { 630 printf("%s: reselect from target %d lun %d with no nexus; sending ABORT\n", 631 device_xname(sc->sc_dev), target, lun); 632 SPC_BREAK(); 633 goto abort; 634 } 635 636 /* Make this nexus active again. */ 637 TAILQ_REMOVE(&sc->nexus_list, acb, chain); 638 sc->sc_state = SPC_HASNEXUS; 639 sc->sc_nexus = acb; 640 ti = &sc->sc_tinfo[target]; 641 ti->lubusy |= (1 << lun); 642 mha_setsync(sc, ti); 643 644 if (acb->flags & ACB_RESET) 645 mha_sched_msgout(sc, SEND_DEV_RESET); 646 else if (acb->flags & ACB_ABORTED) 647 mha_sched_msgout(sc, SEND_ABORT); 648 649 /* Do an implicit RESTORE POINTERS. */ 650 sc->sc_dp = acb->daddr; 651 sc->sc_dleft = acb->dleft; 652 sc->sc_cp = (u_char *)&acb->cmd; 653 sc->sc_cleft = acb->clen; 654 655 return (0); 656 657 reset: 658 mha_sched_msgout(sc, SEND_DEV_RESET); 659 return (1); 660 661 abort: 662 mha_sched_msgout(sc, SEND_ABORT); 663 return (1); 664 } 665 #endif 666 /* 667 * Start a SCSI-command 668 * This function is called by the higher level SCSI-driver to queue/run 669 * SCSI-commands. 670 */ 671 void 672 mha_scsi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 673 void *arg) 674 { 675 struct scsipi_xfer *xs; 676 struct scsipi_periph *periph; 677 struct mha_softc *sc = (void *)chan->chan_adapter->adapt_dev; 678 struct acb *acb; 679 int s, flags; 680 681 switch (req) { 682 case ADAPTER_REQ_RUN_XFER: 683 xs = arg; 684 periph = xs->xs_periph; 685 686 SPC_TRACE(("[mha_scsi_cmd] ")); 687 SPC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen, 688 periph->periph_target)); 689 690 flags = xs->xs_control; 691 692 /* Get a mha command block */ 693 s = splbio(); 694 acb = TAILQ_FIRST(&sc->free_list); 695 if (acb) { 696 TAILQ_REMOVE(&sc->free_list, acb, chain); 697 ACB_SETQ(acb, ACB_QNONE); 698 } 699 700 if (acb == NULL) { 701 xs->error = XS_RESOURCE_SHORTAGE; 702 scsipi_done(xs); 703 splx(s); 704 return; 705 } 706 splx(s); 707 708 /* Initialize acb */ 709 acb->xs = xs; 710 memcpy(&acb->cmd, xs->cmd, xs->cmdlen); 711 acb->clen = xs->cmdlen; 712 acb->daddr = xs->data; 713 acb->dleft = xs->datalen; 714 acb->stat = 0; 715 716 s = splbio(); 717 ACB_SETQ(acb, ACB_QREADY); 718 TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain); 719 #if 1 720 callout_reset(&acb->xs->xs_callout, 721 mstohz(xs->timeout), mha_timeout, acb); 722 #endif 723 724 /* 725 * $B%-%e!<$N=hM}Cf$G$J$1$l$P!"%9%1%8%e!<%j%s%03+;O$9$k(B 726 */ 727 if (sc->sc_state == SPC_IDLE) 728 mha_sched(sc); 729 730 splx(s); 731 732 if (flags & XS_CTL_POLL) { 733 /* Not allowed to use interrupts, use polling instead */ 734 mha_poll(sc, acb); 735 } 736 737 SPC_MISC(("SUCCESSFULLY_QUEUED")); 738 return; 739 740 case ADAPTER_REQ_GROW_RESOURCES: 741 /* XXX Not supported. */ 742 return; 743 744 case ADAPTER_REQ_SET_XFER_MODE: 745 /* XXX Not supported. */ 746 return; 747 } 748 } 749 750 /* 751 * Adjust transfer size in buffer structure 752 */ 753 void 754 mha_minphys(struct buf *bp) 755 { 756 757 SPC_TRACE(("mha_minphys ")); 758 minphys(bp); 759 } 760 761 /* 762 * Used when interrupt driven I/O isn't allowed, e.g. during boot. 763 */ 764 void 765 mha_poll(struct mha_softc *sc, struct acb *acb) 766 { 767 struct scsipi_xfer *xs = acb->xs; 768 int count = xs->timeout * 100; 769 int s; 770 771 s = splbio(); 772 773 SPC_TRACE(("[mha_poll] ")); 774 775 while (count) { 776 /* 777 * If we had interrupts enabled, would we 778 * have got an interrupt? 779 */ 780 if (SSR & SS_IREQUEST) 781 mhaintr(sc); 782 if ((xs->xs_status & XS_STS_DONE) != 0) 783 break; 784 DELAY(10); 785 #if 1 786 if (sc->sc_state == SPC_IDLE) { 787 SPC_TRACE(("[mha_poll: rescheduling] ")); 788 mha_sched(sc); 789 } 790 #endif 791 count--; 792 } 793 794 if (count == 0) { 795 SPC_MISC(("mha_poll: timeout")); 796 mha_timeout((void *)acb); 797 } 798 splx(s); 799 scsipi_done(xs); 800 } 801 802 /* 803 * LOW LEVEL SCSI UTILITIES 804 */ 805 806 /* 807 * Set synchronous transfer offset and period. 808 */ 809 inline void 810 mha_setsync(struct mha_softc *sc, struct spc_tinfo *ti) 811 { 812 } 813 814 /* 815 * Schedule a SCSI operation. This has now been pulled out of the interrupt 816 * handler so that we may call it from mha_scsi_cmd and mha_done. This may 817 * save us an unecessary interrupt just to get things going. Should only be 818 * called when state == SPC_IDLE and at bio pl. 819 */ 820 void 821 mha_sched(struct mha_softc *sc) 822 { 823 struct scsipi_periph *periph; 824 struct acb *acb; 825 int t; 826 827 SPC_TRACE(("[mha_sched] ")); 828 if (sc->sc_state != SPC_IDLE) 829 panic("mha_sched: not IDLE (state=%d)", sc->sc_state); 830 831 if (sc->sc_flags & SPC_ABORTING) 832 return; 833 834 /* 835 * Find first acb in ready queue that is for a target/lunit 836 * combinations that is not busy. 837 */ 838 TAILQ_FOREACH(acb, &sc->ready_list, chain) { 839 struct spc_tinfo *ti; 840 periph = acb->xs->xs_periph; 841 t = periph->periph_target; 842 ti = &sc->sc_tinfo[t]; 843 if (!(ti->lubusy & (1 << periph->periph_lun))) { 844 if ((acb->flags & ACB_QBITS) != ACB_QREADY) 845 panic("mha: busy entry on ready list"); 846 TAILQ_REMOVE(&sc->ready_list, acb, chain); 847 ACB_SETQ(acb, ACB_QNONE); 848 sc->sc_nexus = acb; 849 sc->sc_flags = 0; 850 sc->sc_prevphase = INVALID_PHASE; 851 sc->sc_dp = acb->daddr; 852 sc->sc_dleft = acb->dleft; 853 ti->lubusy |= (1<<periph->periph_lun); 854 mhaselect(sc, t, periph->periph_lun, 855 (u_char *)&acb->cmd, acb->clen); 856 break; 857 } else { 858 SPC_MISC(("%d:%d busy\n", 859 periph->periph_target, 860 periph->periph_lun)); 861 } 862 } 863 } 864 865 /* 866 * POST PROCESSING OF SCSI_CMD (usually current) 867 */ 868 void 869 mha_done(struct mha_softc *sc, struct acb *acb) 870 { 871 struct scsipi_xfer *xs = acb->xs; 872 struct scsipi_periph *periph = xs->xs_periph; 873 struct spc_tinfo *ti = &sc->sc_tinfo[periph->periph_target]; 874 875 SPC_TRACE(("[mha_done(error:%x)] ", xs->error)); 876 877 #if 1 878 callout_stop(&acb->xs->xs_callout); 879 #endif 880 881 /* 882 * Now, if we've come here with no error code, i.e. we've kept the 883 * initial XS_NOERROR, and the status code signals that we should 884 * check sense, we'll need to set up a request sense cmd block and 885 * push the command back into the ready queue *before* any other 886 * commands for this target/lunit, else we lose the sense info. 887 * We don't support chk sense conditions for the request sense cmd. 888 */ 889 if (xs->error == XS_NOERROR) { 890 if ((acb->flags & ACB_ABORTED) != 0) { 891 xs->error = XS_TIMEOUT; 892 } else if (acb->flags & ACB_CHKSENSE) { 893 xs->error = XS_SENSE; 894 } else { 895 xs->status = acb->stat & ST_MASK; 896 switch (xs->status) { 897 case SCSI_CHECK: 898 xs->resid = acb->dleft; 899 /* FALLTHROUGH */ 900 case SCSI_BUSY: 901 xs->error = XS_BUSY; 902 break; 903 case SCSI_OK: 904 xs->resid = acb->dleft; 905 break; 906 default: 907 xs->error = XS_DRIVER_STUFFUP; 908 #if SPC_DEBUG 909 printf("%s: mha_done: bad stat 0x%x\n", 910 device_xname(sc->sc_dev), acb->stat); 911 #endif 912 break; 913 } 914 } 915 } 916 917 #if SPC_DEBUG 918 if ((mha_debug & SPC_SHOWMISC) != 0) { 919 if (xs->resid != 0) 920 printf("resid=%d ", xs->resid); 921 if (xs->error == XS_SENSE) 922 printf("sense=0x%02x\n", xs->sense.scsi_sense.response_code); 923 else 924 printf("error=%d\n", xs->error); 925 } 926 #endif 927 928 /* 929 * Remove the ACB from whatever queue it's on. 930 */ 931 switch (acb->flags & ACB_QBITS) { 932 case ACB_QNONE: 933 if (acb != sc->sc_nexus) { 934 panic("%s: floating acb", device_xname(sc->sc_dev)); 935 } 936 sc->sc_nexus = NULL; 937 sc->sc_state = SPC_IDLE; 938 ti->lubusy &= ~(1<<periph->periph_lun); 939 mha_sched(sc); 940 break; 941 case ACB_QREADY: 942 TAILQ_REMOVE(&sc->ready_list, acb, chain); 943 break; 944 case ACB_QNEXUS: 945 TAILQ_REMOVE(&sc->nexus_list, acb, chain); 946 ti->lubusy &= ~(1<<periph->periph_lun); 947 break; 948 case ACB_QFREE: 949 panic("%s: dequeue: busy acb on free list", 950 device_xname(sc->sc_dev)); 951 break; 952 default: 953 panic("%s: dequeue: unknown queue %d", 954 device_xname(sc->sc_dev), acb->flags & ACB_QBITS); 955 } 956 957 /* Put it on the free list, and clear flags. */ 958 #if 0 959 TAILQ_INSERT_HEAD(&sc->free_list, acb, chain); 960 acb->flags = ACB_QFREE; 961 #else 962 mha_free_acb(sc, acb, xs->xs_control); 963 #endif 964 965 ti->cmds++; 966 scsipi_done(xs); 967 } 968 969 void 970 mha_dequeue(struct mha_softc *sc, struct acb *acb) 971 { 972 973 if (acb->flags & ACB_QNEXUS) { 974 TAILQ_REMOVE(&sc->nexus_list, acb, chain); 975 } else { 976 TAILQ_REMOVE(&sc->ready_list, acb, chain); 977 } 978 } 979 980 /* 981 * INTERRUPT/PROTOCOL ENGINE 982 */ 983 984 /* 985 * Schedule an outgoing message by prioritizing it, and asserting 986 * attention on the bus. We can only do this when we are the initiator 987 * else there will be an illegal command interrupt. 988 */ 989 #define mha_sched_msgout(m) \ 990 do { \ 991 SPC_MISC(("mha_sched_msgout %d ", m)); \ 992 CMR = CMD_SET_ATN; \ 993 sc->sc_msgpriq |= (m); \ 994 } while (0) 995 996 /* 997 * Precondition: 998 * The SCSI bus is already in the MSGI phase and there is a message byte 999 * on the bus, along with an asserted REQ signal. 1000 */ 1001 void 1002 mha_msgin(struct mha_softc *sc) 1003 { 1004 int v; 1005 1006 SPC_TRACE(("[mha_msgin(curmsglen:%d)] ", sc->sc_imlen)); 1007 1008 /* 1009 * Prepare for a new message. A message should (according 1010 * to the SCSI standard) be transmitted in one single 1011 * MESSAGE_IN_PHASE. If we have been in some other phase, 1012 * then this is a new message. 1013 */ 1014 if (sc->sc_prevphase != MESSAGE_IN_PHASE) { 1015 sc->sc_flags &= ~SPC_DROP_MSGI; 1016 sc->sc_imlen = 0; 1017 } 1018 1019 WAIT; 1020 1021 v = MBR; /* modified byte */ 1022 v = sc->sc_pcx[0]; 1023 1024 sc->sc_imess[sc->sc_imlen] = v; 1025 1026 /* 1027 * If we're going to reject the message, don't bother storing 1028 * the incoming bytes. But still, we need to ACK them. 1029 */ 1030 1031 if ((sc->sc_flags & SPC_DROP_MSGI)) { 1032 CMR = CMD_SET_ATN; 1033 /* ESPCMD(sc, ESPCMD_MSGOK);*/ 1034 printf("<dropping msg byte %x>", 1035 sc->sc_imess[sc->sc_imlen]); 1036 return; 1037 } 1038 1039 if (sc->sc_imlen >= SPC_MAX_MSG_LEN) { 1040 mha_sched_msgout(SEND_REJECT); 1041 sc->sc_flags |= SPC_DROP_MSGI; 1042 } else { 1043 sc->sc_imlen++; 1044 /* 1045 * This testing is suboptimal, but most 1046 * messages will be of the one byte variety, so 1047 * it should not effect performance 1048 * significantly. 1049 */ 1050 if (sc->sc_imlen == 1 && MSG_IS1BYTE(sc->sc_imess[0])) 1051 goto gotit; 1052 if (sc->sc_imlen == 2 && MSG_IS2BYTE(sc->sc_imess[0])) 1053 goto gotit; 1054 if (sc->sc_imlen >= 3 && MSG_ISEXTENDED(sc->sc_imess[0]) && 1055 sc->sc_imlen == sc->sc_imess[1] + 2) 1056 goto gotit; 1057 } 1058 #if 0 1059 /* Ack what we have so far */ 1060 ESPCMD(sc, ESPCMD_MSGOK); 1061 #endif 1062 return; 1063 1064 gotit: 1065 SPC_MSGS(("gotmsg(%x)", sc->sc_imess[0])); 1066 /* 1067 * Now we should have a complete message (1 byte, 2 byte 1068 * and moderately long extended messages). We only handle 1069 * extended messages which total length is shorter than 1070 * SPC_MAX_MSG_LEN. Longer messages will be amputated. 1071 */ 1072 if (sc->sc_state == SPC_HASNEXUS) { 1073 struct acb *acb = sc->sc_nexus; 1074 struct spc_tinfo *ti = 1075 &sc->sc_tinfo[acb->xs->xs_periph->periph_target]; 1076 1077 switch (sc->sc_imess[0]) { 1078 case MSG_CMDCOMPLETE: 1079 SPC_MSGS(("cmdcomplete ")); 1080 if (sc->sc_dleft < 0) { 1081 struct scsipi_periph *periph = acb->xs->xs_periph; 1082 printf("mha: %d extra bytes from %d:%d\n", 1083 -sc->sc_dleft, 1084 periph->periph_target, 1085 periph->periph_lun); 1086 sc->sc_dleft = 0; 1087 } 1088 acb->xs->resid = acb->dleft = sc->sc_dleft; 1089 sc->sc_flags |= SPC_BUSFREE_OK; 1090 break; 1091 1092 case MSG_MESSAGE_REJECT: 1093 #if SPC_DEBUG 1094 if (mha_debug & SPC_SHOWMSGS) 1095 printf("%s: our msg rejected by target\n", 1096 device_xname(sc->sc_dev)); 1097 #endif 1098 #if 1 /* XXX - must remember last message */ 1099 scsipi_printaddr(acb->xs->xs_periph); 1100 printf("MSG_MESSAGE_REJECT>>"); 1101 #endif 1102 if (sc->sc_flags & SPC_SYNCHNEGO) { 1103 ti->period = ti->offset = 0; 1104 sc->sc_flags &= ~SPC_SYNCHNEGO; 1105 ti->flags &= ~T_NEGOTIATE; 1106 } 1107 /* Not all targets understand INITIATOR_DETECTED_ERR */ 1108 if (sc->sc_msgout == SEND_INIT_DET_ERR) 1109 mha_sched_msgout(SEND_ABORT); 1110 break; 1111 case MSG_NOOP: 1112 SPC_MSGS(("noop ")); 1113 break; 1114 case MSG_DISCONNECT: 1115 SPC_MSGS(("disconnect ")); 1116 ti->dconns++; 1117 sc->sc_flags |= SPC_DISCON; 1118 sc->sc_flags |= SPC_BUSFREE_OK; 1119 if ((acb->xs->xs_periph->periph_quirks & PQUIRK_AUTOSAVE) == 0) 1120 break; 1121 /*FALLTHROUGH*/ 1122 case MSG_SAVEDATAPOINTER: 1123 SPC_MSGS(("save datapointer ")); 1124 acb->dleft = sc->sc_dleft; 1125 acb->daddr = sc->sc_dp; 1126 break; 1127 case MSG_RESTOREPOINTERS: 1128 SPC_MSGS(("restore datapointer ")); 1129 if (!acb) { 1130 mha_sched_msgout(SEND_ABORT); 1131 printf("%s: no DATAPOINTERs to restore\n", 1132 device_xname(sc->sc_dev)); 1133 break; 1134 } 1135 sc->sc_dp = acb->daddr; 1136 sc->sc_dleft = acb->dleft; 1137 break; 1138 case MSG_PARITY_ERROR: 1139 printf("%s:target%d: MSG_PARITY_ERROR\n", 1140 device_xname(sc->sc_dev), 1141 acb->xs->xs_periph->periph_target); 1142 break; 1143 case MSG_EXTENDED: 1144 SPC_MSGS(("extended(%x) ", sc->sc_imess[2])); 1145 switch (sc->sc_imess[2]) { 1146 case MSG_EXT_SDTR: 1147 SPC_MSGS(("SDTR period %d, offset %d ", 1148 sc->sc_imess[3], sc->sc_imess[4])); 1149 ti->period = sc->sc_imess[3]; 1150 ti->offset = sc->sc_imess[4]; 1151 if (sc->sc_minsync == 0) { 1152 /* We won't do synch */ 1153 ti->offset = 0; 1154 mha_sched_msgout(SEND_SDTR); 1155 } else if (ti->offset == 0) { 1156 printf("%s:%d: async\n", "mha", 1157 acb->xs->xs_periph->periph_target); 1158 ti->offset = 0; 1159 sc->sc_flags &= ~SPC_SYNCHNEGO; 1160 } else if (ti->period > 124) { 1161 printf("%s:%d: async\n", "mha", 1162 acb->xs->xs_periph->periph_target); 1163 ti->offset = 0; 1164 mha_sched_msgout(SEND_SDTR); 1165 } else { 1166 #if 0 1167 int p; 1168 p = mha_stp2cpb(sc, ti->period); 1169 ti->period = mha_cpb2stp(sc, p); 1170 #endif 1171 1172 #if SPC_DEBUG 1173 scsipi_printaddr(acb->xs->xs_periph); 1174 #endif 1175 if ((sc->sc_flags&SPC_SYNCHNEGO) == 0) { 1176 /* Target initiated negotiation */ 1177 if (ti->flags & T_SYNCMODE) { 1178 ti->flags &= ~T_SYNCMODE; 1179 #if SPC_DEBUG 1180 printf("renegotiated "); 1181 #endif 1182 } 1183 TMR=TM_ASYNC; 1184 /* Clamp to our maxima */ 1185 if (ti->period < sc->sc_minsync) 1186 ti->period = sc->sc_minsync; 1187 if (ti->offset > 15) 1188 ti->offset = 15; 1189 mha_sched_msgout(SEND_SDTR); 1190 } else { 1191 /* we are sync */ 1192 sc->sc_flags &= ~SPC_SYNCHNEGO; 1193 TMR = TM_SYNC; 1194 ti->flags |= T_SYNCMODE; 1195 } 1196 } 1197 ti->flags &= ~T_NEGOTIATE; 1198 break; 1199 default: /* Extended messages we don't handle */ 1200 CMR = CMD_SET_ATN; /* XXX? */ 1201 break; 1202 } 1203 break; 1204 default: 1205 SPC_MSGS(("ident ")); 1206 /* thanks for that ident... */ 1207 if (!MSG_ISIDENTIFY(sc->sc_imess[0])) { 1208 SPC_MISC(("unknown ")); 1209 printf("%s: unimplemented message: %d\n", device_xname(sc->sc_dev), sc->sc_imess[0]); 1210 CMR = CMD_SET_ATN; /* XXX? */ 1211 } 1212 break; 1213 } 1214 } else if (sc->sc_state == SPC_RESELECTED) { 1215 struct scsipi_periph *periph = NULL; 1216 struct acb *acb; 1217 struct spc_tinfo *ti; 1218 u_char lunit; 1219 1220 if (MSG_ISIDENTIFY(sc->sc_imess[0])) { /* Identify? */ 1221 SPC_MISC(("searching ")); 1222 /* 1223 * Search wait queue for disconnected cmd 1224 * The list should be short, so I haven't bothered with 1225 * any more sophisticated structures than a simple 1226 * singly linked list. 1227 */ 1228 lunit = sc->sc_imess[0] & 0x07; 1229 TAILQ_FOREACH(acb, &sc->nexus_list, chain) { 1230 periph = acb->xs->xs_periph; 1231 if (periph->periph_lun == lunit && 1232 sc->sc_selid == (1<<periph->periph_target)) { 1233 TAILQ_REMOVE(&sc->nexus_list, acb, 1234 chain); 1235 ACB_SETQ(acb, ACB_QNONE); 1236 break; 1237 } 1238 } 1239 1240 if (!acb) { /* Invalid reselection! */ 1241 mha_sched_msgout(SEND_ABORT); 1242 printf("mha: invalid reselect (idbit=0x%2x)\n", 1243 sc->sc_selid); 1244 } else { /* Reestablish nexus */ 1245 /* 1246 * Setup driver data structures and 1247 * do an implicit RESTORE POINTERS 1248 */ 1249 ti = &sc->sc_tinfo[periph->periph_target]; 1250 sc->sc_nexus = acb; 1251 sc->sc_dp = acb->daddr; 1252 sc->sc_dleft = acb->dleft; 1253 sc->sc_tinfo[periph->periph_target].lubusy 1254 |= (1<<periph->periph_lun); 1255 if (ti->flags & T_SYNCMODE) { 1256 TMR = TM_SYNC; /* XXX */ 1257 } else { 1258 TMR = TM_ASYNC; 1259 } 1260 SPC_MISC(("... found acb")); 1261 sc->sc_state = SPC_HASNEXUS; 1262 } 1263 } else { 1264 printf("%s: bogus reselect (no IDENTIFY) %0x2x\n", 1265 device_xname(sc->sc_dev), sc->sc_selid); 1266 mha_sched_msgout(SEND_DEV_RESET); 1267 } 1268 } else { /* Neither SPC_HASNEXUS nor SPC_RESELECTED! */ 1269 printf("%s: unexpected message in; will send DEV_RESET\n", 1270 device_xname(sc->sc_dev)); 1271 mha_sched_msgout(SEND_DEV_RESET); 1272 } 1273 1274 /* Ack last message byte */ 1275 #if 0 1276 ESPCMD(sc, ESPCMD_MSGOK); 1277 #endif 1278 1279 /* Done, reset message pointer. */ 1280 sc->sc_flags &= ~SPC_DROP_MSGI; 1281 sc->sc_imlen = 0; 1282 } 1283 1284 /* 1285 * Send the highest priority, scheduled message. 1286 */ 1287 void 1288 mha_msgout(struct mha_softc *sc) 1289 { 1290 #if (SPC_USE_SYNCHRONOUS || SPC_USE_WIDE) 1291 struct spc_tinfo *ti; 1292 #endif 1293 int n; 1294 1295 SPC_TRACE(("mha_msgout ")); 1296 1297 if (sc->sc_prevphase == MESSAGE_OUT_PHASE) { 1298 if (sc->sc_omp == sc->sc_omess) { 1299 /* 1300 * This is a retransmission. 1301 * 1302 * We get here if the target stayed in MESSAGE OUT 1303 * phase. Section 5.1.9.2 of the SCSI 2 spec indicates 1304 * that all of the previously transmitted messages must 1305 * be sent again, in the same order. Therefore, we 1306 * requeue all the previously transmitted messages, and 1307 * start again from the top. Our simple priority 1308 * scheme keeps the messages in the right order. 1309 */ 1310 SPC_MISC(("retransmitting ")); 1311 sc->sc_msgpriq |= sc->sc_msgoutq; 1312 /* 1313 * Set ATN. If we're just sending a trivial 1-byte 1314 * message, we'll clear ATN later on anyway. 1315 */ 1316 CMR = CMD_SET_ATN; /* XXX? */ 1317 } else { 1318 /* This is a continuation of the previous message. */ 1319 n = sc->sc_omp - sc->sc_omess; 1320 goto nextbyte; 1321 } 1322 } 1323 1324 /* No messages transmitted so far. */ 1325 sc->sc_msgoutq = 0; 1326 sc->sc_lastmsg = 0; 1327 1328 nextmsg: 1329 /* Pick up highest priority message. */ 1330 sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq; 1331 sc->sc_msgpriq &= ~sc->sc_currmsg; 1332 sc->sc_msgoutq |= sc->sc_currmsg; 1333 1334 /* Build the outgoing message data. */ 1335 switch (sc->sc_currmsg) { 1336 case SEND_IDENTIFY: 1337 SPC_ASSERT(sc->sc_nexus != NULL); 1338 sc->sc_omess[0] = 1339 MSG_IDENTIFY(sc->sc_nexus->xs->xs_periph->periph_lun, 1); 1340 n = 1; 1341 break; 1342 1343 #if SPC_USE_SYNCHRONOUS 1344 case SEND_SDTR: 1345 SPC_ASSERT(sc->sc_nexus != NULL); 1346 ti = &sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target]; 1347 sc->sc_omess[4] = MSG_EXTENDED; 1348 sc->sc_omess[3] = 3; 1349 sc->sc_omess[2] = MSG_EXT_SDTR; 1350 sc->sc_omess[1] = ti->period >> 2; 1351 sc->sc_omess[0] = ti->offset; 1352 n = 5; 1353 break; 1354 #endif 1355 1356 #if SPC_USE_WIDE 1357 case SEND_WDTR: 1358 SPC_ASSERT(sc->sc_nexus != NULL); 1359 ti = &sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target]; 1360 sc->sc_omess[3] = MSG_EXTENDED; 1361 sc->sc_omess[2] = 2; 1362 sc->sc_omess[1] = MSG_EXT_WDTR; 1363 sc->sc_omess[0] = ti->width; 1364 n = 4; 1365 break; 1366 #endif 1367 1368 case SEND_DEV_RESET: 1369 sc->sc_flags |= SPC_ABORTING; 1370 sc->sc_omess[0] = MSG_BUS_DEV_RESET; 1371 n = 1; 1372 break; 1373 1374 case SEND_REJECT: 1375 sc->sc_omess[0] = MSG_MESSAGE_REJECT; 1376 n = 1; 1377 break; 1378 1379 case SEND_PARITY_ERROR: 1380 sc->sc_omess[0] = MSG_PARITY_ERROR; 1381 n = 1; 1382 break; 1383 1384 case SEND_INIT_DET_ERR: 1385 sc->sc_omess[0] = MSG_INITIATOR_DET_ERR; 1386 n = 1; 1387 break; 1388 1389 case SEND_ABORT: 1390 sc->sc_flags |= SPC_ABORTING; 1391 sc->sc_omess[0] = MSG_ABORT; 1392 n = 1; 1393 break; 1394 1395 default: 1396 printf("%s: unexpected MESSAGE OUT; sending NOOP\n", 1397 device_xname(sc->sc_dev)); 1398 SPC_BREAK(); 1399 sc->sc_omess[0] = MSG_NOOP; 1400 n = 1; 1401 break; 1402 } 1403 sc->sc_omp = &sc->sc_omess[n]; 1404 1405 nextbyte: 1406 /* Send message bytes. */ 1407 /* send TRANSFER command. */ 1408 sc->sc_ps[3] = 1; 1409 sc->sc_ps[4] = n >> 8; 1410 sc->sc_pc[10] = n; 1411 sc->sc_ps[-1] = 0x000F; /* burst */ 1412 __asm volatile ("nop"); 1413 CMR = CMD_SEND_FROM_DMA; /* send from DMA */ 1414 for (;;) { 1415 if ((SSR & SS_BUSY) != 0) 1416 break; 1417 if (SSR & SS_IREQUEST) 1418 goto out; 1419 } 1420 for (;;) { 1421 #if 0 1422 for (;;) { 1423 if ((PSNS & PSNS_REQ) != 0) 1424 break; 1425 /* Wait for REQINIT. XXX Need timeout. */ 1426 } 1427 #endif 1428 if (SSR & SS_IREQUEST) { 1429 /* 1430 * Target left MESSAGE OUT, possibly to reject 1431 * our message. 1432 * 1433 * If this is the last message being sent, then we 1434 * deassert ATN, since either the target is going to 1435 * ignore this message, or it's going to ask for a 1436 * retransmission via MESSAGE PARITY ERROR (in which 1437 * case we reassert ATN anyway). 1438 */ 1439 #if 0 1440 if (sc->sc_msgpriq == 0) 1441 CMR = CMD_RESET_ATN; 1442 #endif 1443 goto out; 1444 } 1445 1446 #if 0 1447 /* Clear ATN before last byte if this is the last message. */ 1448 if (n == 1 && sc->sc_msgpriq == 0) 1449 CMR = CMD_RESET_ATN; 1450 #endif 1451 1452 while ((SSR & SS_DREG_FULL) != 0) 1453 ; 1454 /* Send message byte. */ 1455 sc->sc_pc[0] = *--sc->sc_omp; 1456 --n; 1457 /* Keep track of the last message we've sent any bytes of. */ 1458 sc->sc_lastmsg = sc->sc_currmsg; 1459 1460 if (n == 0) 1461 break; 1462 } 1463 1464 /* We get here only if the entire message has been transmitted. */ 1465 if (sc->sc_msgpriq != 0) { 1466 /* There are more outgoing messages. */ 1467 goto nextmsg; 1468 } 1469 1470 /* 1471 * The last message has been transmitted. We need to remember the last 1472 * message transmitted (in case the target switches to MESSAGE IN phase 1473 * and sends a MESSAGE REJECT), and the list of messages transmitted 1474 * this time around (in case the target stays in MESSAGE OUT phase to 1475 * request a retransmit). 1476 */ 1477 1478 out: 1479 /* Disable REQ/ACK protocol. */ 1480 return; 1481 } 1482 1483 /*************************************************************** 1484 * 1485 * datain/dataout 1486 * 1487 */ 1488 1489 int 1490 mha_datain_pio(struct mha_softc *sc, u_char *p, int n) 1491 { 1492 u_short d; 1493 int a; 1494 int total_n = n; 1495 1496 SPC_TRACE(("[mha_datain_pio(%p,%d)", p, n)); 1497 1498 WAIT; 1499 sc->sc_ps[3] = 1; 1500 sc->sc_ps[4] = n >> 8; 1501 sc->sc_pc[10] = n; 1502 /* $BHa$7$-%=%U%HE>Aw(B */ 1503 CMR = CMD_RECEIVE_TO_MPU; 1504 for (;;) { 1505 a = SSR; 1506 if (a & 0x04) { 1507 d = sc->sc_ps[0]; 1508 *p++ = d >> 8; 1509 if (--n > 0) { 1510 *p++ = d; 1511 --n; 1512 } 1513 a = SSR; 1514 } 1515 if (a & 0x40) 1516 continue; 1517 if (a & 0x80) 1518 break; 1519 } 1520 SPC_TRACE(("...%d resd]", n)); 1521 return total_n - n; 1522 } 1523 1524 int 1525 mha_dataout_pio(struct mha_softc *sc, u_char *p, int n) 1526 { 1527 u_short d; 1528 int a; 1529 int total_n = n; 1530 1531 SPC_TRACE(("[mha_dataout_pio(%p,%d)", p, n)); 1532 1533 WAIT; 1534 sc->sc_ps[3] = 1; 1535 sc->sc_ps[4] = n >> 8; 1536 sc->sc_pc[10] = n; 1537 /* $BHa$7$-%=%U%HE>Aw(B */ 1538 CMR = CMD_SEND_FROM_MPU; 1539 for (;;) { 1540 a = SSR; 1541 if (a & 0x04) { 1542 d = *p++ << 8; 1543 if (--n > 0) { 1544 d |= *p++; 1545 --n; 1546 } 1547 sc->sc_ps[0] = d; 1548 a = SSR; 1549 } 1550 if (a & 0x40) 1551 continue; 1552 if (a & 0x80) 1553 break; 1554 } 1555 SPC_TRACE(("...%d resd]", n)); 1556 return total_n - n; 1557 } 1558 1559 /* 1560 * dw: DMA word 1561 * cw: CMR word 1562 */ 1563 static int 1564 mha_dataio_dma(int dw, int cw, struct mha_softc *sc, u_char *p, int n) 1565 { 1566 char *paddr; 1567 1568 if (n > MAXBSIZE) 1569 panic("transfer size exceeds MAXBSIZE"); 1570 if (sc->sc_dmasize > 0) 1571 panic("DMA request while another DMA transfer is in pregress"); 1572 1573 if (cw == CMD_SEND_FROM_DMA) { 1574 memcpy(sc->sc_dmabuf, p, n); 1575 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, n, BUS_DMASYNC_PREWRITE); 1576 } else { 1577 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, n, BUS_DMASYNC_PREREAD); 1578 } 1579 sc->sc_p = p; 1580 sc->sc_dmasize = n; 1581 1582 paddr = (char *)sc->sc_dmaseg[0].ds_addr; 1583 #if MHA_DMA_SHORT_BUS_CYCLE == 1 1584 if ((*(volatile int *)&IODEVbase->io_sram[0xac]) & 1585 (1 << ((paddr_t)paddr >> 19))) 1586 dw &= ~(1 << 3); 1587 #endif 1588 sc->sc_pc[0x80 + (((long)paddr >> 16) & 0xFF)] = 0; 1589 sc->sc_pc[0x180 + (((long)paddr >> 8) & 0xFF)] = 0; 1590 sc->sc_pc[0x280 + (((long)paddr >> 0) & 0xFF)] = 0; 1591 WAIT; 1592 sc->sc_ps[3] = 1; 1593 sc->sc_ps[4] = n >> 8; 1594 sc->sc_pc[10] = n; 1595 /* DMA $BE>Aw@)8f$O0J2<$NDL$j!#(B 1596 3 ... short bus cycle 1597 2 ... MAXIMUM XFER. 1598 1 ... BURST XFER. 1599 0 ... R/W */ 1600 sc->sc_ps[-1] = dw; /* burst */ 1601 __asm volatile ("nop"); 1602 CMR = cw; /* receive to DMA */ 1603 return n; 1604 } 1605 1606 int 1607 mha_dataout(struct mha_softc *sc, u_char *p, int n) 1608 { 1609 if (n == 0) 1610 return n; 1611 1612 if (n & 1) 1613 return mha_dataout_pio(sc, p, n); 1614 return mha_dataio_dma(MHA_DMA_DATAOUT, CMD_SEND_FROM_DMA, sc, p, n); 1615 } 1616 1617 int 1618 mha_datain(struct mha_softc *sc, u_char *p, int n) 1619 { 1620 struct acb *acb = sc->sc_nexus; 1621 1622 if (n == 0) 1623 return n; 1624 if (acb->cmd.opcode == SCSI_REQUEST_SENSE || (n & 1)) 1625 return mha_datain_pio(sc, p, n); 1626 return mha_dataio_dma(MHA_DMA_DATAIN, CMD_RECEIVE_TO_DMA, sc, p, n); 1627 } 1628 1629 /* 1630 * Catch an interrupt from the adaptor 1631 */ 1632 /* 1633 * This is the workhorse routine of the driver. 1634 * Deficiencies (for now): 1635 * 1) always uses programmed I/O 1636 */ 1637 int 1638 mhaintr(void *arg) 1639 { 1640 struct mha_softc *sc = arg; 1641 #if 0 1642 u_char ints; 1643 #endif 1644 struct acb *acb; 1645 u_char ph; 1646 u_short r; 1647 int n; 1648 1649 #if 1 /* XXX called during attach? */ 1650 if (tmpsc != NULL) { 1651 SPC_MISC(("[%p %p]\n", mha_cd.cd_devs, sc)); 1652 sc = tmpsc; 1653 } else { 1654 #endif 1655 1656 #if 1 /* XXX */ 1657 } 1658 #endif 1659 1660 #if 0 1661 /* 1662 * $B3d$j9~$_6X;_$K$9$k(B 1663 */ 1664 SCTL &= ~SCTL_INTR_ENAB; 1665 #endif 1666 1667 SPC_TRACE(("[mhaintr]")); 1668 1669 /* 1670 * $BA4E>Aw$,40A4$K=*N;$9$k$^$G%k!<%W$9$k(B 1671 */ 1672 /* 1673 * First check for abnormal conditions, such as reset. 1674 */ 1675 #if 0 1676 #if 1 /* XXX? */ 1677 while (((ints = SSR) & SS_IREQUEST) == 0) 1678 delay(1); 1679 SPC_MISC(("ints = 0x%x ", ints)); 1680 #else /* usually? */ 1681 ints = SSR; 1682 #endif 1683 #endif 1684 while (SSR & SS_IREQUEST) { 1685 acb = sc->sc_nexus; 1686 r = ISCSR; 1687 SPC_MISC(("[r=0x%x]", r)); 1688 switch (r >> 8) { 1689 default: 1690 printf("[addr=%p\n" 1691 "result=0x%x\n" 1692 "cmd=0x%x\n" 1693 "ph=0x%x(ought to be %d)]\n", 1694 &ISCSR, 1695 r, 1696 acb->xs->cmd->opcode, 1697 SCR, sc->sc_phase); 1698 panic("unexpected result."); 1699 case 0x82: /* selection timeout */ 1700 SPC_MISC(("selection timeout ")); 1701 sc->sc_phase = BUSFREE_PHASE; 1702 SPC_ASSERT(sc->sc_nexus != NULL); 1703 acb = sc->sc_nexus; 1704 delay(250); 1705 acb->xs->error = XS_SELTIMEOUT; 1706 mha_done(sc, acb); 1707 continue; /* XXX ??? msaitoh */ 1708 case 0x60: /* command completed */ 1709 sc->sc_spcinitialized++; 1710 if (sc->sc_phase == BUSFREE_PHASE) 1711 continue; 1712 ph = SCR; 1713 if (ph & PSNS_ACK) { 1714 int s; 1715 /* $B$U$D!<$N%3%^%s%I$,=*N;$7$?$i$7$$(B */ 1716 SPC_MISC(("0x60)phase = %x(ought to be %x)\n", 1717 ph & PHASE_MASK, sc->sc_phase)); 1718 #if 0 1719 /* switch (sc->sc_phase) {*/ 1720 #else 1721 switch (ph & PHASE_MASK) { 1722 #endif 1723 case STATUS_PHASE: 1724 if (sc->sc_state != SPC_HASNEXUS) 1725 printf("stsin: !SPC_HASNEXUS->(%d)\n", 1726 sc->sc_state); 1727 SPC_ASSERT(sc->sc_nexus != NULL); 1728 acb = sc->sc_nexus; 1729 WAIT; 1730 s = MBR; 1731 SPC_ASSERT(s == 1); 1732 acb->stat = sc->sc_pcx[0]; /* XXX */ 1733 SPC_MISC(("stat=0x%02x ", acb->stat)); 1734 sc->sc_prevphase = STATUS_PHASE; 1735 break; 1736 case MESSAGE_IN_PHASE: 1737 mha_msgin(sc); 1738 sc->sc_prevphase = MESSAGE_IN_PHASE; 1739 /* thru */ 1740 case DATA_IN_PHASE: 1741 if (sc->sc_dmasize == 0) 1742 break; 1743 bus_dmamap_sync(sc->sc_dmat, 1744 sc->sc_dmamap, 1745 0, sc->sc_dmasize, 1746 BUS_DMASYNC_POSTREAD); 1747 memcpy(sc->sc_p, sc->sc_dmabuf, 1748 sc->sc_dmasize); 1749 sc->sc_dmasize = 0; 1750 break; 1751 case DATA_OUT_PHASE: 1752 if (sc->sc_dmasize == 0) 1753 break; 1754 bus_dmamap_sync(sc->sc_dmat, 1755 sc->sc_dmamap, 1756 0, sc->sc_dmasize, 1757 BUS_DMASYNC_POSTWRITE); 1758 sc->sc_dmasize = 0; 1759 break; 1760 } 1761 WAIT; 1762 CMR = CMD_RESET_ACK; /* reset ack */ 1763 /*mha_done(sc, acb); XXX */ 1764 continue; 1765 } else if (NSR & 0x80) { /* nexus */ 1766 #if 1 1767 if (sc->sc_state == SPC_SELECTING) /* XXX msaitoh */ 1768 sc->sc_state = SPC_HASNEXUS; 1769 /* $B%U%'!<%:$N7h$aBG$A$r$9$k(B 1770 $B30$l$?$i!"(Binitial-phase error(0x54) $B$,(B 1771 $BJV$C$F$/$k$s$GCm0U$7$?$^$(!#(B 1772 $B$G$b$J$<$+(B 0x65 $B$,JV$C$F$-$?$j$7$F$M!<$+(B? */ 1773 WAIT; 1774 if (SSR & SS_IREQUEST) 1775 continue; 1776 switch (sc->sc_phase) { 1777 default: 1778 panic("$B8+CN$i$L(B phase $B$,Mh$A$^$C$?$@$h(B"); 1779 case MESSAGE_IN_PHASE: 1780 /* $B2?$b$7$J$$(B */ 1781 continue; 1782 case STATUS_PHASE: 1783 sc->sc_phase = MESSAGE_IN_PHASE; 1784 CMR = CMD_RECEIVE_MSG; /* receive msg */ 1785 continue; 1786 case DATA_IN_PHASE: 1787 sc->sc_prevphase = DATA_IN_PHASE; 1788 if (sc->sc_dleft == 0) { 1789 /* $BE>Aw%G!<%?$O$b$&$J$$$N$G(B 1790 $B%9%F!<%?%9%U%'!<%:$r4|BT$7$h$&(B */ 1791 sc->sc_phase = STATUS_PHASE; 1792 CMR = CMD_RECEIVE_STS; /* receive sts */ 1793 continue; 1794 } 1795 n = mha_datain(sc, sc->sc_dp, 1796 sc->sc_dleft); 1797 sc->sc_dp += n; 1798 sc->sc_dleft -= n; 1799 continue; 1800 case DATA_OUT_PHASE: 1801 sc->sc_prevphase = DATA_OUT_PHASE; 1802 if (sc->sc_dleft == 0) { 1803 /* $BE>Aw%G!<%?$O$b$&$J$$$N$G(B 1804 $B%9%F!<%?%9%U%'!<%:$r4|BT$7$h$&(B */ 1805 sc->sc_phase = STATUS_PHASE; 1806 CMR = CMD_RECEIVE_STS; /* receive sts */ 1807 continue; 1808 } 1809 /* data phase $B$NB3$-$r$d$m$&(B */ 1810 n = mha_dataout(sc, sc->sc_dp, sc->sc_dleft); 1811 sc->sc_dp += n; 1812 sc->sc_dleft -= n; 1813 continue; 1814 case COMMAND_PHASE: 1815 /* $B:G=i$O(B CMD PHASE $B$H$$$&$3$H$i$7$$(B */ 1816 if (acb->dleft) { 1817 /* $B%G!<%?E>Aw$,$"$j$&$k>l9g(B */ 1818 if (acb->xs->xs_control & XS_CTL_DATA_IN) { 1819 sc->sc_phase = DATA_IN_PHASE; 1820 n = mha_datain(sc, sc->sc_dp, sc->sc_dleft); 1821 sc->sc_dp += n; 1822 sc->sc_dleft -= n; 1823 } 1824 else if (acb->xs->xs_control & XS_CTL_DATA_OUT) { 1825 sc->sc_phase = DATA_OUT_PHASE; 1826 n = mha_dataout(sc, sc->sc_dp, sc->sc_dleft); 1827 sc->sc_dp += n; 1828 sc->sc_dleft -= n; 1829 } 1830 continue; 1831 } 1832 else { 1833 /* $B%G!<%?E>Aw$O$J$$$i$7$$(B?! */ 1834 WAIT; 1835 sc->sc_phase = STATUS_PHASE; 1836 CMR = CMD_RECEIVE_STS; /* receive sts */ 1837 continue; 1838 } 1839 } 1840 #endif 1841 } 1842 continue; 1843 case 0x31: /* disconnected in xfer progress. */ 1844 SPC_MISC(("[0x31]")); 1845 case 0x70: /* disconnected. */ 1846 SPC_ASSERT(sc->sc_flags & SPC_BUSFREE_OK); 1847 sc->sc_phase = BUSFREE_PHASE; 1848 sc->sc_state = SPC_IDLE; 1849 #if 1 1850 acb = sc->sc_nexus; 1851 SPC_ASSERT(sc->sc_nexus != NULL); 1852 acb->xs->error = XS_NOERROR; 1853 mha_done(sc, acb); 1854 #else 1855 TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain); 1856 mha_sched(sc); 1857 #endif 1858 continue; 1859 case 0x32: /* phase error in xfer progress. */ 1860 SPC_MISC(("[0x32]")); 1861 #if 0 1862 case 0x65: /* invalid command. 1863 $B$J$<$3$s$J$b$N$,=P$k$N$+(B 1864 $B26$K$OA4$/M}2r$G$-$J$$(B */ 1865 #if 1 1866 SPC_MISC(("[0x%04x]", r)); 1867 #endif 1868 #endif 1869 case 0x54: /* initial-phase error. */ 1870 SPC_MISC(("[0x54, ns=%x, ph=%x(ought to be %x)]", 1871 NSR, 1872 SCR, sc->sc_phase)); 1873 /* thru */ 1874 case 0x71: /* assert req */ 1875 WAIT; 1876 if (SSR & 0x40) { 1877 printf("SPC sts=%2x, r=%04x, ns=%x, ph=%x\n", 1878 SSR, r, NSR, SCR); 1879 WAIT; 1880 } 1881 ph = SCR; 1882 if (sc->sc_state == SPC_SELECTING) { /* XXX msaitoh */ 1883 sc->sc_state = SPC_HASNEXUS; 1884 } 1885 if (ph & 0x80) { 1886 switch (ph & PHASE_MASK) { 1887 default: 1888 printf("phase = %x\n", ph); 1889 panic("assert req: the phase I don't know!"); 1890 case DATA_IN_PHASE: 1891 sc->sc_prevphase = DATA_IN_PHASE; 1892 SPC_MISC(("DATAIN(%d)...", sc->sc_dleft)); 1893 n = mha_datain(sc, sc->sc_dp, sc->sc_dleft); 1894 sc->sc_dp += n; 1895 sc->sc_dleft -= n; 1896 SPC_MISC(("done\n")); 1897 continue; 1898 case DATA_OUT_PHASE: 1899 sc->sc_prevphase = DATA_OUT_PHASE; 1900 SPC_MISC(("DATAOUT\n")); 1901 n = mha_dataout(sc, sc->sc_dp, sc->sc_dleft); 1902 sc->sc_dp += n; 1903 sc->sc_dleft -= n; 1904 continue; 1905 case STATUS_PHASE: 1906 sc->sc_phase = STATUS_PHASE; 1907 SPC_MISC(("[RECV_STS]")); 1908 WAIT; 1909 CMR = CMD_RECEIVE_STS; /* receive sts */ 1910 continue; 1911 case MESSAGE_IN_PHASE: 1912 sc->sc_phase = MESSAGE_IN_PHASE; 1913 WAIT; 1914 CMR = CMD_RECEIVE_MSG; 1915 continue; 1916 } 1917 } 1918 continue; 1919 } 1920 } 1921 1922 return 1; 1923 } 1924 1925 void 1926 mha_abort(struct mha_softc *sc, struct acb *acb) 1927 { 1928 acb->flags |= ACB_ABORTED; 1929 1930 if (acb == sc->sc_nexus) { 1931 /* 1932 * If we're still selecting, the message will be scheduled 1933 * after selection is complete. 1934 */ 1935 if (sc->sc_state == SPC_HASNEXUS) { 1936 sc->sc_flags |= SPC_ABORTING; 1937 mha_sched_msgout(SEND_ABORT); 1938 } 1939 } else { 1940 if (sc->sc_state == SPC_IDLE) 1941 mha_sched(sc); 1942 } 1943 } 1944 1945 void 1946 mha_timeout(void *arg) 1947 { 1948 struct acb *acb = (struct acb *)arg; 1949 struct scsipi_xfer *xs = acb->xs; 1950 struct scsipi_periph *periph = xs->xs_periph; 1951 struct mha_softc *sc = 1952 (void *)periph->periph_channel->chan_adapter->adapt_dev; 1953 int s; 1954 1955 s = splbio(); 1956 1957 scsipi_printaddr(periph); 1958 printf("%s: timed out [acb %p (flags 0x%x, dleft %x, stat %x)], " 1959 "<state %d, nexus %p, phase(c %x, p %x), resid %x, msg(q %x,o %x) >", 1960 device_xname(sc->sc_dev), 1961 acb, acb->flags, acb->dleft, acb->stat, 1962 sc->sc_state, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase, 1963 sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout 1964 ); 1965 printf("[%04x %02x]\n", sc->sc_ps[1], SCR); 1966 panic("timeout, ouch!"); 1967 1968 if (acb->flags & ACB_ABORTED) { 1969 /* abort timed out */ 1970 printf(" AGAIN\n"); 1971 #if 0 1972 mha_init(sc, 1); /* XXX 1?*/ 1973 #endif 1974 } else { 1975 /* abort the operation that has timed out */ 1976 printf("\n"); 1977 xs->error = XS_TIMEOUT; 1978 mha_abort(sc, acb); 1979 } 1980 1981 splx(s); 1982 } 1983 1984 #if SPC_DEBUG 1985 /* 1986 * The following functions are mostly used for debugging purposes, either 1987 * directly called from the driver or from the kernel debugger. 1988 */ 1989 1990 void 1991 mha_show_scsi_cmd(struct acb *acb) 1992 { 1993 u_char *b = (u_char *)&acb->cmd; 1994 struct scsipi_periph *periph = acb->xs->xs_periph; 1995 int i; 1996 1997 scsipi_printaddr(periph); 1998 if ((acb->xs->xs_control & XS_CTL_RESET) == 0) { 1999 for (i = 0; i < acb->clen; i++) { 2000 if (i) 2001 printf(","); 2002 printf("%x", b[i]); 2003 } 2004 printf("\n"); 2005 } else 2006 printf("RESET\n"); 2007 } 2008 2009 void 2010 mha_print_acb(struct acb *acb) 2011 { 2012 2013 printf("acb@%p xs=%p flags=%x", acb, acb->xs, acb->flags); 2014 printf(" dp=%p dleft=%d stat=%x\n", 2015 acb->daddr, acb->dleft, acb->stat); 2016 mha_show_scsi_cmd(acb); 2017 } 2018 2019 void 2020 mha_print_active_acb(void) 2021 { 2022 struct acb *acb; 2023 struct mha_softc *sc = device_lookup_private(&mha_cd, 0); /* XXX */ 2024 2025 printf("ready list:\n"); 2026 TAILQ_FOREACH(acb, &sc->ready_list, chain) 2027 mha_print_acb(acb); 2028 printf("nexus:\n"); 2029 if (sc->sc_nexus != NULL) 2030 mha_print_acb(sc->sc_nexus); 2031 printf("nexus list:\n"); 2032 TAILQ_FOREACH(acb, &sc->nexus_list, chain) 2033 mha_print_acb(acb); 2034 } 2035 2036 void 2037 mha_dump_driver(struct mha_softc *sc) 2038 { 2039 struct spc_tinfo *ti; 2040 int i; 2041 2042 printf("nexus=%p prevphase=%x\n", sc->sc_nexus, sc->sc_prevphase); 2043 printf("state=%x msgin=%x msgpriq=%x msgoutq=%x lastmsg=%x currmsg=%x\n", 2044 sc->sc_state, sc->sc_imess[0], 2045 sc->sc_msgpriq, sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg); 2046 for (i = 0; i < 7; i++) { 2047 ti = &sc->sc_tinfo[i]; 2048 printf("tinfo%d: %d cmds %d disconnects %d timeouts", 2049 i, ti->cmds, ti->dconns, ti->touts); 2050 printf(" %d senses flags=%x\n", ti->senses, ti->flags); 2051 } 2052 } 2053 #endif 2054