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