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