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