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