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