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