1 /* $NetBSD: mesh.c,v 1.12 2001/07/22 11:29:46 wiz Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 Tsubai Masanari. 5 * Copyright (c) 1999 Internet Research Institute, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by 19 * Internet Research Institute, Inc. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/buf.h> 37 #include <sys/device.h> 38 #include <sys/errno.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/queue.h> 42 #include <sys/systm.h> 43 44 #include <uvm/uvm_extern.h> 45 46 #include <dev/scsipi/scsi_all.h> 47 #include <dev/scsipi/scsipi_all.h> 48 #include <dev/scsipi/scsiconf.h> 49 #include <dev/scsipi/scsi_message.h> 50 51 #include <dev/ofw/openfirm.h> 52 53 #include <machine/autoconf.h> 54 #include <machine/cpu.h> 55 #include <machine/pio.h> 56 57 #include <macppc/dev/dbdma.h> 58 #include <macppc/dev/meshreg.h> 59 60 #ifdef MESH_DEBUG 61 # define DPRINTF printf 62 #else 63 # define DPRINTF while (0) printf 64 #endif 65 66 #define T_SYNCMODE 0x01 /* target uses sync mode */ 67 #define T_SYNCNEGO 0x02 /* sync negotiation done */ 68 69 struct mesh_tinfo { 70 int flags; 71 int period; 72 int offset; 73 }; 74 75 /* scb flags */ 76 #define MESH_POLL 0x01 77 #define MESH_CHECK 0x02 78 #define MESH_READ 0x80 79 80 struct mesh_scb { 81 TAILQ_ENTRY(mesh_scb) chain; 82 int flags; 83 struct scsipi_xfer *xs; 84 struct scsi_generic cmd; 85 int cmdlen; 86 int target; /* target SCSI ID */ 87 int resid; 88 vaddr_t daddr; 89 vsize_t dlen; 90 int status; 91 }; 92 93 /* sc_flags value */ 94 #define MESH_DMA_ACTIVE 0x01 95 96 struct mesh_softc { 97 struct device sc_dev; /* us as a device */ 98 struct scsipi_channel sc_channel; 99 struct scsipi_adapter sc_adapter; 100 101 u_char *sc_reg; /* MESH base address */ 102 dbdma_regmap_t *sc_dmareg; /* DMA register address */ 103 dbdma_command_t *sc_dmacmd; /* DMA command area */ 104 105 int sc_flags; 106 int sc_cfflags; /* copy of config flags */ 107 int sc_meshid; /* MESH version */ 108 int sc_minsync; /* minimum sync period */ 109 int sc_irq; 110 int sc_freq; /* SCSI bus frequency in MHz */ 111 int sc_id; /* our SCSI ID */ 112 struct mesh_tinfo sc_tinfo[8]; /* target information */ 113 114 int sc_nextstate; 115 int sc_prevphase; 116 struct mesh_scb *sc_nexus; /* current command */ 117 118 int sc_msgout; 119 int sc_imsglen; 120 u_char sc_imsg[16]; 121 u_char sc_omsg[16]; 122 123 TAILQ_HEAD(, mesh_scb) free_scb; 124 TAILQ_HEAD(, mesh_scb) ready_scb; 125 struct mesh_scb sc_scb[16]; 126 }; 127 128 /* mesh_msgout() values */ 129 #define SEND_REJECT 1 130 #define SEND_IDENTIFY 2 131 #define SEND_SDTR 4 132 133 static __inline int mesh_read_reg __P((struct mesh_softc *, int)); 134 static __inline void mesh_set_reg __P((struct mesh_softc *, int, int)); 135 136 int mesh_match __P((struct device *, struct cfdata *, void *)); 137 void mesh_attach __P((struct device *, struct device *, void *)); 138 void mesh_shutdownhook __P((void *)); 139 int mesh_intr __P((void *)); 140 void mesh_error __P((struct mesh_softc *, struct mesh_scb *, int, int)); 141 void mesh_select __P((struct mesh_softc *, struct mesh_scb *)); 142 void mesh_identify __P((struct mesh_softc *, struct mesh_scb *)); 143 void mesh_command __P((struct mesh_softc *, struct mesh_scb *)); 144 void mesh_dma_setup __P((struct mesh_softc *, struct mesh_scb *)); 145 void mesh_dataio __P((struct mesh_softc *, struct mesh_scb *)); 146 void mesh_status __P((struct mesh_softc *, struct mesh_scb *)); 147 void mesh_msgin __P((struct mesh_softc *, struct mesh_scb *)); 148 void mesh_msgout __P((struct mesh_softc *, int)); 149 void mesh_bus_reset __P((struct mesh_softc *)); 150 void mesh_reset __P((struct mesh_softc *)); 151 int mesh_stp __P((struct mesh_softc *, int)); 152 void mesh_setsync __P((struct mesh_softc *, struct mesh_tinfo *)); 153 struct mesh_scb *mesh_get_scb __P((struct mesh_softc *)); 154 void mesh_free_scb __P((struct mesh_softc *, struct mesh_scb *)); 155 void mesh_scsi_request __P((struct scsipi_channel *, 156 scsipi_adapter_req_t, void *)); 157 void mesh_sched __P((struct mesh_softc *)); 158 int mesh_poll __P((struct mesh_softc *, struct scsipi_xfer *)); 159 void mesh_done __P((struct mesh_softc *, struct mesh_scb *)); 160 void mesh_timeout __P((void *)); 161 void mesh_minphys __P((struct buf *)); 162 163 164 #define MESH_DATAOUT 0 165 #define MESH_DATAIN MESH_STATUS0_IO 166 #define MESH_COMMAND MESH_STATUS0_CD 167 #define MESH_STATUS (MESH_STATUS0_CD | MESH_STATUS0_IO) 168 #define MESH_MSGOUT (MESH_STATUS0_MSG | MESH_STATUS0_CD) 169 #define MESH_MSGIN (MESH_STATUS0_MSG | MESH_STATUS0_CD | MESH_STATUS0_IO) 170 171 #define MESH_SELECTING 8 172 #define MESH_IDENTIFY 9 173 #define MESH_COMPLETE 10 174 #define MESH_BUSFREE 11 175 #define MESH_UNKNOWN -1 176 177 #define MESH_PHASE_MASK (MESH_STATUS0_MSG | MESH_STATUS0_CD | MESH_STATUS0_IO) 178 179 struct cfattach mesh_ca = { 180 sizeof(struct mesh_softc), mesh_match, mesh_attach 181 }; 182 183 int 184 mesh_match(parent, cf, aux) 185 struct device *parent; 186 struct cfdata *cf; 187 void *aux; 188 { 189 struct confargs *ca = aux; 190 char compat[32]; 191 192 if (strcmp(ca->ca_name, "mesh") == 0) 193 return 1; 194 195 memset(compat, 0, sizeof(compat)); 196 OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat)); 197 if (strcmp(compat, "chrp,mesh0") == 0) 198 return 1; 199 200 return 0; 201 } 202 203 void 204 mesh_attach(parent, self, aux) 205 struct device *parent, *self; 206 void *aux; 207 { 208 struct mesh_softc *sc = (void *)self; 209 struct confargs *ca = aux; 210 int i; 211 u_int *reg; 212 213 reg = ca->ca_reg; 214 reg[0] += ca->ca_baseaddr; 215 reg[2] += ca->ca_baseaddr; 216 sc->sc_reg = mapiodev(reg[0], reg[1]); 217 sc->sc_irq = ca->ca_intr[0]; 218 sc->sc_dmareg = mapiodev(reg[2], reg[3]); 219 220 sc->sc_cfflags = self->dv_cfdata->cf_flags; 221 sc->sc_meshid = mesh_read_reg(sc, MESH_MESH_ID) & 0x1f; 222 #if 0 223 if (sc->sc_meshid != (MESH_SIGNATURE & 0x1f) { 224 printf(": unknown MESH ID (0x%x)\n", sc->sc_meshid); 225 return; 226 } 227 #endif 228 if (OF_getprop(ca->ca_node, "clock-frequency", &sc->sc_freq, 4) != 4) { 229 printf(": cannot get clock-frequency\n"); 230 return; 231 } 232 sc->sc_freq /= 1000000; /* in MHz */ 233 sc->sc_minsync = 25; /* maximum sync rate = 10MB/sec */ 234 sc->sc_id = 7; 235 236 TAILQ_INIT(&sc->free_scb); 237 TAILQ_INIT(&sc->ready_scb); 238 for (i = 0; i < sizeof(sc->sc_scb)/sizeof(sc->sc_scb[0]); i++) 239 TAILQ_INSERT_TAIL(&sc->free_scb, &sc->sc_scb[i], chain); 240 241 sc->sc_dmacmd = dbdma_alloc(sizeof(dbdma_command_t) * 20); 242 243 mesh_reset(sc); 244 mesh_bus_reset(sc); 245 246 printf(" irq %d: %dMHz, SCSI ID %d\n", 247 sc->sc_irq, sc->sc_freq, sc->sc_id); 248 249 sc->sc_adapter.adapt_dev = &sc->sc_dev; 250 sc->sc_adapter.adapt_nchannels = 1; 251 sc->sc_adapter.adapt_openings = 7; 252 sc->sc_adapter.adapt_max_periph = 1; 253 sc->sc_adapter.adapt_ioctl = NULL; 254 sc->sc_adapter.adapt_minphys = mesh_minphys; 255 sc->sc_adapter.adapt_request = mesh_scsi_request; 256 257 sc->sc_channel.chan_adapter = &sc->sc_adapter; 258 sc->sc_channel.chan_bustype = &scsi_bustype; 259 sc->sc_channel.chan_channel = 0; 260 sc->sc_channel.chan_ntargets = 8; 261 sc->sc_channel.chan_nluns = 8; 262 sc->sc_channel.chan_id = sc->sc_id; 263 264 config_found(&sc->sc_dev, &sc->sc_channel, scsiprint); 265 266 intr_establish(sc->sc_irq, IST_LEVEL, IPL_BIO, mesh_intr, sc); 267 268 /* Reset SCSI bus when halt. */ 269 shutdownhook_establish(mesh_shutdownhook, sc); 270 } 271 272 #define MESH_SET_XFER(sc, count) do { \ 273 mesh_set_reg(sc, MESH_XFER_COUNT0, count); \ 274 mesh_set_reg(sc, MESH_XFER_COUNT1, count >> 8); \ 275 } while (0) 276 277 #define MESH_GET_XFER(sc) ((mesh_read_reg(sc, MESH_XFER_COUNT1) << 8) | \ 278 mesh_read_reg(sc, MESH_XFER_COUNT0)) 279 280 int 281 mesh_read_reg(sc, reg) 282 struct mesh_softc *sc; 283 int reg; 284 { 285 return in8(sc->sc_reg + reg); 286 } 287 288 void 289 mesh_set_reg(sc, reg, val) 290 struct mesh_softc *sc; 291 int reg, val; 292 { 293 out8(sc->sc_reg + reg, val); 294 } 295 296 void 297 mesh_shutdownhook(arg) 298 void *arg; 299 { 300 struct mesh_softc *sc = arg; 301 302 /* Set to async mode. */ 303 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 304 } 305 306 #ifdef MESH_DEBUG 307 static char scsi_phase[][8] = { 308 "DATAOUT", 309 "DATAIN", 310 "COMMAND", 311 "STATUS", 312 "", 313 "", 314 "MSGOUT", 315 "MSGIN" 316 }; 317 #endif 318 319 int 320 mesh_intr(arg) 321 void *arg; 322 { 323 struct mesh_softc *sc = arg; 324 struct mesh_scb *scb; 325 int fifocnt; 326 u_char intr, exception, error, status0, status1; 327 328 intr = mesh_read_reg(sc, MESH_INTERRUPT); 329 if (intr == 0) { 330 DPRINTF("%s: stray interrupt\n", sc->sc_dev.dv_xname); 331 return 0; 332 } 333 334 exception = mesh_read_reg(sc, MESH_EXCEPTION); 335 error = mesh_read_reg(sc, MESH_ERROR); 336 status0 = mesh_read_reg(sc, MESH_BUS_STATUS0); 337 status1 = mesh_read_reg(sc, MESH_BUS_STATUS1); 338 339 /* clear interrupt */ 340 mesh_set_reg(sc, MESH_INTERRUPT, intr); 341 342 #ifdef MESH_DEBUG 343 { 344 char buf1[64], buf2[64]; 345 346 bitmask_snprintf(status0, MESH_STATUS0_BITMASK, buf1, sizeof buf1); 347 bitmask_snprintf(exception, MESH_EXC_BITMASK, buf2, sizeof buf2); 348 printf("mesh_intr status0 = 0x%s (%s), exc = 0x%s\n", 349 buf1, scsi_phase[status0 & 7], buf2); 350 } 351 #endif 352 353 scb = sc->sc_nexus; 354 if (scb == NULL) { 355 DPRINTF("%s: NULL nexus\n", sc->sc_dev.dv_xname); 356 return 1; 357 } 358 359 if (sc->sc_flags & MESH_DMA_ACTIVE) { 360 dbdma_stop(sc->sc_dmareg); 361 362 sc->sc_flags &= ~MESH_DMA_ACTIVE; 363 scb->resid = MESH_GET_XFER(sc); 364 365 fifocnt = mesh_read_reg(sc, MESH_FIFO_COUNT); 366 if (fifocnt != 0 && (scb->flags & MESH_READ)) { 367 char *cp = (char *)scb->daddr + scb->dlen - fifocnt; 368 369 DPRINTF("fifocnt = %d, resid = %d\n", fifocnt, 370 scb->resid); 371 while (fifocnt > 0) { 372 *cp++ = mesh_read_reg(sc, MESH_FIFO); 373 fifocnt--; 374 } 375 } else 376 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 377 } 378 379 if (intr & MESH_INTR_ERROR) { 380 mesh_error(sc, scb, error, 0); 381 return 1; 382 } 383 384 if (intr & MESH_INTR_EXCEPTION) { 385 /* selection timeout */ 386 if (exception & MESH_EXC_SELTO) { 387 mesh_error(sc, scb, 0, exception); 388 return 1; 389 } 390 391 /* phase mismatch */ 392 if (exception & MESH_EXC_PHASEMM) { 393 DPRINTF("%s: PHASE MISMATCH; nextstate = %d -> ", 394 sc->sc_dev.dv_xname, sc->sc_nextstate); 395 sc->sc_nextstate = status0 & MESH_PHASE_MASK; 396 397 DPRINTF("%d, resid = %d\n", 398 sc->sc_nextstate, scb->resid); 399 } 400 } 401 402 if (sc->sc_nextstate == MESH_UNKNOWN) 403 sc->sc_nextstate = status0 & MESH_PHASE_MASK; 404 405 switch (sc->sc_nextstate) { 406 407 case MESH_IDENTIFY: 408 mesh_identify(sc, scb); 409 break; 410 case MESH_COMMAND: 411 mesh_command(sc, scb); 412 break; 413 case MESH_DATAIN: 414 case MESH_DATAOUT: 415 mesh_dataio(sc, scb); 416 break; 417 case MESH_STATUS: 418 mesh_status(sc, scb); 419 break; 420 case MESH_MSGIN: 421 mesh_msgin(sc, scb); 422 break; 423 case MESH_COMPLETE: 424 mesh_done(sc, scb); 425 break; 426 427 default: 428 printf("%s: unknown state (%d)\n", sc->sc_dev.dv_xname, 429 sc->sc_nextstate); 430 scb->xs->error = XS_DRIVER_STUFFUP; 431 mesh_done(sc, scb); 432 } 433 434 return 1; 435 } 436 437 void 438 mesh_error(sc, scb, error, exception) 439 struct mesh_softc *sc; 440 struct mesh_scb *scb; 441 int error, exception; 442 { 443 if (error & MESH_ERR_SCSI_RESET) { 444 printf("%s: SCSI RESET\n", sc->sc_dev.dv_xname); 445 446 /* Wait until the RST signal is deasserted. */ 447 while (mesh_read_reg(sc, MESH_BUS_STATUS1) & MESH_STATUS1_RST); 448 mesh_reset(sc); 449 return; 450 } 451 452 if (error & MESH_ERR_PARITY_ERR0) { 453 printf("%s: parity error\n", sc->sc_dev.dv_xname); 454 scb->xs->error = XS_DRIVER_STUFFUP; 455 } 456 457 if (error & MESH_ERR_DISCONNECT) { 458 printf("%s: unexpected disconnect\n", sc->sc_dev.dv_xname); 459 if (sc->sc_nextstate != MESH_COMPLETE) 460 scb->xs->error = XS_DRIVER_STUFFUP; 461 } 462 463 if (exception & MESH_EXC_SELTO) { 464 /* XXX should reset bus here? */ 465 scb->xs->error = XS_SELTIMEOUT; 466 } 467 468 mesh_done(sc, scb); 469 } 470 471 void 472 mesh_select(sc, scb) 473 struct mesh_softc *sc; 474 struct mesh_scb *scb; 475 { 476 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 477 int timeout; 478 479 DPRINTF("mesh_select\n"); 480 481 mesh_setsync(sc, ti); 482 MESH_SET_XFER(sc, 0); 483 484 /* arbitration */ 485 486 /* 487 * MESH mistakenly asserts TARGET ID bit along with its own ID bit 488 * in arbitration phase (like selection). So we should load 489 * initiator ID to DestID register temporarily. 490 */ 491 mesh_set_reg(sc, MESH_DEST_ID, sc->sc_id); 492 mesh_set_reg(sc, MESH_INTR_MASK, 0); /* disable intr. */ 493 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_ARBITRATE); 494 495 while (mesh_read_reg(sc, MESH_INTERRUPT) == 0); 496 mesh_set_reg(sc, MESH_INTERRUPT, 1); 497 mesh_set_reg(sc, MESH_INTR_MASK, 7); 498 499 /* selection */ 500 mesh_set_reg(sc, MESH_DEST_ID, scb->target); 501 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_SELECT | MESH_SEQ_ATN); 502 503 sc->sc_prevphase = MESH_SELECTING; 504 sc->sc_nextstate = MESH_IDENTIFY; 505 506 timeout = (u_int64_t)scb->xs->timeout * (u_int64_t)hz / 1000; 507 if (timeout == 0) 508 timeout = 1; 509 510 callout_reset(&scb->xs->xs_callout, timeout, mesh_timeout, scb); 511 } 512 513 void 514 mesh_identify(sc, scb) 515 struct mesh_softc *sc; 516 struct mesh_scb *scb; 517 { 518 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 519 520 DPRINTF("mesh_identify\n"); 521 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 522 523 if ((ti->flags & T_SYNCNEGO) == 0) { 524 ti->period = sc->sc_minsync; 525 ti->offset = 15; 526 mesh_msgout(sc, SEND_IDENTIFY | SEND_SDTR); 527 sc->sc_nextstate = MESH_MSGIN; 528 } else { 529 mesh_msgout(sc, SEND_IDENTIFY); 530 sc->sc_nextstate = MESH_COMMAND; 531 } 532 } 533 534 void 535 mesh_command(sc, scb) 536 struct mesh_softc *sc; 537 struct mesh_scb *scb; 538 { 539 int i; 540 char *cmdp; 541 542 #ifdef MESH_DEBUG 543 printf("mesh_command cdb = %02x", scb->cmd.opcode); 544 for (i = 0; i < 5; i++) 545 printf(" %02x", scb->cmd.bytes[i]); 546 printf("\n"); 547 #endif 548 549 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 550 551 MESH_SET_XFER(sc, scb->cmdlen); 552 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_COMMAND); 553 554 cmdp = (char *)&scb->cmd; 555 for (i = 0; i < scb->cmdlen; i++) 556 mesh_set_reg(sc, MESH_FIFO, *cmdp++); 557 558 if (scb->resid == 0) 559 sc->sc_nextstate = MESH_STATUS; /* no data xfer */ 560 else 561 sc->sc_nextstate = MESH_DATAIN; 562 } 563 564 void 565 mesh_dma_setup(sc, scb) 566 struct mesh_softc *sc; 567 struct mesh_scb *scb; 568 { 569 int datain = scb->flags & MESH_READ; 570 dbdma_command_t *cmdp; 571 u_int cmd; 572 vaddr_t va; 573 int count, offset; 574 575 cmdp = sc->sc_dmacmd; 576 cmd = datain ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE; 577 578 count = scb->dlen; 579 580 if (count / NBPG > 32) 581 panic("mesh: transfer size >= 128k"); 582 583 va = scb->daddr; 584 offset = va & PGOFSET; 585 586 /* if va is not page-aligned, setup the first page */ 587 if (offset != 0) { 588 int rest = NBPG - offset; /* the rest in the page */ 589 590 if (count > rest) { /* if continues to next page */ 591 DBDMA_BUILD(cmdp, cmd, 0, rest, vtophys(va), 592 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, 593 DBDMA_BRANCH_NEVER); 594 count -= rest; 595 va += rest; 596 cmdp++; 597 } 598 } 599 600 /* now va is page-aligned */ 601 while (count > NBPG) { 602 DBDMA_BUILD(cmdp, cmd, 0, NBPG, vtophys(va), 603 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 604 count -= NBPG; 605 va += NBPG; 606 cmdp++; 607 } 608 609 /* the last page (count <= NBPG here) */ 610 cmd = datain ? DBDMA_CMD_IN_LAST : DBDMA_CMD_OUT_LAST; 611 DBDMA_BUILD(cmdp, cmd , 0, count, vtophys(va), 612 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 613 cmdp++; 614 615 DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, 616 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 617 } 618 619 void 620 mesh_dataio(sc, scb) 621 struct mesh_softc *sc; 622 struct mesh_scb *scb; 623 { 624 DPRINTF("mesh_dataio len = %ld (%s)\n", scb->dlen, 625 scb->flags & MESH_READ ? "read" : "write"); 626 627 mesh_dma_setup(sc, scb); 628 629 if (scb->dlen == 65536) 630 MESH_SET_XFER(sc, 0); /* TC = 0 means 64KB transfer */ 631 else 632 MESH_SET_XFER(sc, scb->dlen); 633 634 if (scb->flags & MESH_READ) 635 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_DATAIN | MESH_SEQ_DMA); 636 else 637 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_DATAOUT | MESH_SEQ_DMA); 638 dbdma_start(sc->sc_dmareg, sc->sc_dmacmd); 639 sc->sc_flags |= MESH_DMA_ACTIVE; 640 sc->sc_nextstate = MESH_STATUS; 641 } 642 643 void 644 mesh_status(sc, scb) 645 struct mesh_softc *sc; 646 struct mesh_scb *scb; 647 { 648 if (mesh_read_reg(sc, MESH_FIFO_COUNT) == 0) { /* XXX cheat */ 649 DPRINTF("mesh_status(0)\n"); 650 MESH_SET_XFER(sc, 1); 651 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_STATUS); 652 sc->sc_nextstate = MESH_STATUS; 653 return; 654 } 655 656 scb->status = mesh_read_reg(sc, MESH_FIFO); 657 DPRINTF("mesh_status(1): status = 0x%x\n", scb->status); 658 if (mesh_read_reg(sc, MESH_FIFO_COUNT) != 0) 659 DPRINTF("FIFO_COUNT=%d\n", mesh_read_reg(sc, MESH_FIFO_COUNT)); 660 661 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 662 MESH_SET_XFER(sc, 1); 663 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 664 665 sc->sc_nextstate = MESH_MSGIN; 666 } 667 668 #define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80) 669 #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20) 670 #define ISEXTMSG(m) ((m) == 1) 671 672 void 673 mesh_msgin(sc, scb) 674 struct mesh_softc *sc; 675 struct mesh_scb *scb; 676 { 677 DPRINTF("mesh_msgin\n"); 678 679 if (mesh_read_reg(sc, MESH_FIFO_COUNT) == 0) { /* XXX cheat */ 680 MESH_SET_XFER(sc, 1); 681 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 682 sc->sc_imsglen = 0; 683 sc->sc_nextstate = MESH_MSGIN; 684 return; 685 } 686 687 sc->sc_imsg[sc->sc_imsglen++] = mesh_read_reg(sc, MESH_FIFO); 688 689 if (sc->sc_imsglen == 1 && IS1BYTEMSG(sc->sc_imsg[0])) 690 goto gotit; 691 if (sc->sc_imsglen == 2 && IS2BYTEMSG(sc->sc_imsg[0])) 692 goto gotit; 693 if (sc->sc_imsglen >= 3 && ISEXTMSG(sc->sc_imsg[0]) && 694 sc->sc_imsglen == sc->sc_imsg[1] + 2) 695 goto gotit; 696 697 sc->sc_nextstate = MESH_MSGIN; 698 MESH_SET_XFER(sc, 1); 699 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 700 return; 701 702 gotit: 703 #ifdef MESH_DEBUG 704 printf("msgin:"); 705 for (i = 0; i < sc->sc_imsglen; i++) 706 printf(" 0x%02x", sc->sc_imsg[i]); 707 printf("\n"); 708 #endif 709 710 switch (sc->sc_imsg[0]) { 711 case MSG_CMDCOMPLETE: 712 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); 713 sc->sc_nextstate = MESH_COMPLETE; 714 sc->sc_imsglen = 0; 715 return; 716 717 case MSG_MESSAGE_REJECT: 718 if (sc->sc_msgout & SEND_SDTR) { 719 printf("SDTR rejected\n"); 720 printf("using async mode\n"); 721 sc->sc_tinfo[scb->target].period = 0; 722 sc->sc_tinfo[scb->target].offset = 0; 723 mesh_setsync(sc, &sc->sc_tinfo[scb->target]); 724 break; 725 } 726 break; 727 728 case MSG_NOOP: 729 break; 730 731 case MSG_EXTENDED: 732 goto extended_msg; 733 734 default: 735 scsipi_printaddr(scb->xs->xs_periph); 736 printf("unrecognized MESSAGE(0x%02x); sending REJECT\n", 737 sc->sc_imsg[0]); 738 739 reject: 740 mesh_msgout(sc, SEND_REJECT); 741 return; 742 } 743 goto done; 744 745 extended_msg: 746 /* process an extended message */ 747 switch (sc->sc_imsg[2]) { 748 case MSG_EXT_SDTR: 749 { 750 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 751 int period = sc->sc_imsg[3]; 752 int offset = sc->sc_imsg[4]; 753 int r = 250 / period; 754 int s = (100*250) / period - 100 * r; 755 756 if (period < sc->sc_minsync) { 757 ti->period = sc->sc_minsync; 758 ti->offset = 15; 759 mesh_msgout(sc, SEND_SDTR); 760 return; 761 } 762 scsipi_printaddr(scb->xs->xs_periph); 763 /* XXX if (offset != 0) ... */ 764 printf("max sync rate %d.%02dMb/s\n", r, s); 765 ti->period = period; 766 ti->offset = offset; 767 ti->flags |= T_SYNCNEGO; 768 ti->flags |= T_SYNCMODE; 769 mesh_setsync(sc, ti); 770 goto done; 771 } 772 default: 773 printf("%s target %d: rejecting extended message 0x%x\n", 774 sc->sc_dev.dv_xname, scb->target, sc->sc_imsg[0]); 775 goto reject; 776 } 777 778 done: 779 sc->sc_imsglen = 0; 780 sc->sc_nextstate = MESH_UNKNOWN; 781 782 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); /* XXX really? */ 783 } 784 785 void 786 mesh_msgout(sc, msg) 787 struct mesh_softc *sc; 788 int msg; 789 { 790 struct mesh_scb *scb = sc->sc_nexus; 791 struct mesh_tinfo *ti; 792 int lun, len, i; 793 794 DPRINTF("mesh_msgout: sending"); 795 796 sc->sc_msgout = msg; 797 len = 0; 798 799 if (msg & SEND_REJECT) { 800 DPRINTF(" REJECT"); 801 sc->sc_omsg[len++] = MSG_MESSAGE_REJECT; 802 } 803 if (msg & SEND_IDENTIFY) { 804 DPRINTF(" IDENTIFY"); 805 lun = scb->xs->xs_periph->periph_lun; 806 sc->sc_omsg[len++] = MSG_IDENTIFY(lun, 0); 807 } 808 if (msg & SEND_SDTR) { 809 DPRINTF(" SDTR"); 810 ti = &sc->sc_tinfo[scb->target]; 811 sc->sc_omsg[len++] = MSG_EXTENDED; 812 sc->sc_omsg[len++] = 3; 813 sc->sc_omsg[len++] = MSG_EXT_SDTR; 814 sc->sc_omsg[len++] = ti->period; 815 sc->sc_omsg[len++] = ti->offset; 816 } 817 DPRINTF("\n"); 818 819 MESH_SET_XFER(sc, len); 820 if (len == 1) { 821 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGOUT); 822 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[0]); 823 } else { 824 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGOUT | MESH_SEQ_ATN); 825 826 for (i = 0; i < len - 1; i++) 827 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[i]); 828 829 /* Wait for the FIFO empty... */ 830 while (mesh_read_reg(sc, MESH_FIFO_COUNT) > 0); 831 832 /* ...then write the last byte. */ 833 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[i]); 834 } 835 sc->sc_nextstate = MESH_UNKNOWN; 836 } 837 838 void 839 mesh_bus_reset(sc) 840 struct mesh_softc *sc; 841 { 842 DPRINTF("mesh_bus_reset\n"); 843 844 /* Disable interrupts. */ 845 mesh_set_reg(sc, MESH_INTR_MASK, 0); 846 847 /* Assert RST line. */ 848 mesh_set_reg(sc, MESH_BUS_STATUS1, MESH_STATUS1_RST); 849 delay(50); 850 mesh_set_reg(sc, MESH_BUS_STATUS1, 0); 851 852 mesh_reset(sc); 853 } 854 855 void 856 mesh_reset(sc) 857 struct mesh_softc *sc; 858 { 859 int i; 860 861 DPRINTF("mesh_reset\n"); 862 863 /* Reset DMA first. */ 864 dbdma_reset(sc->sc_dmareg); 865 866 /* Disable interrupts. */ 867 mesh_set_reg(sc, MESH_INTR_MASK, 0); 868 869 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_RESET_MESH); 870 delay(1); 871 872 /* Wait for reset done. */ 873 while (mesh_read_reg(sc, MESH_INTERRUPT) == 0); 874 875 /* Clear interrupts */ 876 mesh_set_reg(sc, MESH_INTERRUPT, 0x7); 877 878 /* Set SCSI ID */ 879 mesh_set_reg(sc, MESH_SOURCE_ID, sc->sc_id); 880 881 /* Set to async mode by default. */ 882 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 883 884 /* Set selection timeout to 250ms. */ 885 mesh_set_reg(sc, MESH_SEL_TIMEOUT, 250 * sc->sc_freq / 500); 886 887 /* Enable parity check. */ 888 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_ENABLE_PARITY); 889 890 /* Enable all interrupts. */ 891 mesh_set_reg(sc, MESH_INTR_MASK, 0x7); 892 893 for (i = 0; i < 7; i++) { 894 struct mesh_tinfo *ti = &sc->sc_tinfo[i]; 895 896 ti->flags = 0; 897 ti->period = ti->offset = 0; 898 if (sc->sc_cfflags & (0x100 << i)) 899 ti->flags |= T_SYNCNEGO; 900 } 901 sc->sc_nexus = NULL; 902 } 903 904 int 905 mesh_stp(sc, v) 906 struct mesh_softc *sc; 907 int v; 908 { 909 /* 910 * stp(v) = 5 * clock_period (v == 0) 911 * = (v + 2) * 2 clock_period (v > 0) 912 */ 913 914 if (v == 0) 915 return 5 * 250 / sc->sc_freq; 916 else 917 return (v + 2) * 2 * 250 / sc->sc_freq; 918 } 919 920 void 921 mesh_setsync(sc, ti) 922 struct mesh_softc *sc; 923 struct mesh_tinfo *ti; 924 { 925 int period = ti->period; 926 int offset = ti->offset; 927 int v; 928 929 if ((ti->flags & T_SYNCMODE) == 0) 930 offset = 0; 931 932 if (offset == 0) { /* async mode */ 933 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 934 return; 935 } 936 937 v = period * sc->sc_freq / 250 / 2 - 2; 938 if (v < 0) 939 v = 0; 940 if (mesh_stp(sc, v) < period) 941 v++; 942 if (v > 15) 943 v = 15; 944 mesh_set_reg(sc, MESH_SYNC_PARAM, (offset << 4) | v); 945 } 946 947 struct mesh_scb * 948 mesh_get_scb(sc) 949 struct mesh_softc *sc; 950 { 951 struct mesh_scb *scb; 952 int s; 953 954 s = splbio(); 955 if ((scb = sc->free_scb.tqh_first) != NULL) 956 TAILQ_REMOVE(&sc->free_scb, scb, chain); 957 splx(s); 958 959 return scb; 960 } 961 962 void 963 mesh_free_scb(sc, scb) 964 struct mesh_softc *sc; 965 struct mesh_scb *scb; 966 { 967 int s; 968 969 s = splbio(); 970 TAILQ_INSERT_HEAD(&sc->free_scb, scb, chain); 971 splx(s); 972 } 973 974 void 975 mesh_scsi_request(chan, req, arg) 976 struct scsipi_channel *chan; 977 scsipi_adapter_req_t req; 978 void *arg; 979 { 980 struct scsipi_xfer *xs; 981 struct scsipi_periph *periph; 982 struct mesh_softc *sc = (void *)chan->chan_adapter->adapt_dev; 983 struct mesh_scb *scb; 984 u_int flags; 985 int s; 986 987 switch (req) { 988 case ADAPTER_REQ_RUN_XFER: 989 xs = arg; 990 periph = xs->xs_periph; 991 flags = xs->xs_control; 992 993 994 if ((scb = mesh_get_scb(sc)) == NULL) { 995 xs->error = XS_RESOURCE_SHORTAGE; 996 scsipi_done(xs); 997 return; 998 } 999 scb->xs = xs; 1000 scb->flags = 0; 1001 scb->status = 0; 1002 scb->daddr = (vaddr_t)xs->data; 1003 scb->dlen = xs->datalen; 1004 scb->resid = xs->datalen; 1005 memcpy(&scb->cmd, xs->cmd, xs->cmdlen); 1006 scb->cmdlen = xs->cmdlen; 1007 scb->target = periph->periph_target; 1008 sc->sc_imsglen = 0; /* XXX ? */ 1009 1010 #ifdef MESH_DEBUG 1011 { 1012 int i; 1013 printf("mesh_scsi_cmd: target = %d, cdb = %02x", 1014 scb->target, scb->cmd.opcode); 1015 for (i = 0; i < 5; i++) 1016 printf(" %02x", scb->cmd.bytes[i]); 1017 printf("\n"); 1018 } 1019 #endif 1020 1021 if (flags & XS_CTL_POLL) 1022 scb->flags |= MESH_POLL; 1023 #if 0 1024 if (flags & XS_CTL_DATA_OUT) 1025 scb->flags &= ~MESH_READ; 1026 #endif 1027 if (flags & XS_CTL_DATA_IN) 1028 scb->flags |= MESH_READ; 1029 1030 s = splbio(); 1031 1032 TAILQ_INSERT_TAIL(&sc->ready_scb, scb, chain); 1033 1034 if (sc->sc_nexus == NULL) /* IDLE */ 1035 mesh_sched(sc); 1036 1037 splx(s); 1038 1039 if ((flags & XS_CTL_POLL) == 0) 1040 return; 1041 1042 if (mesh_poll(sc, xs)) { 1043 printf("%s: timeout\n", sc->sc_dev.dv_xname); 1044 if (mesh_poll(sc, xs)) 1045 printf("%s: timeout again\n", sc->sc_dev.dv_xname); 1046 } 1047 return; 1048 1049 case ADAPTER_REQ_GROW_RESOURCES: 1050 /* XXX Not supported. */ 1051 return; 1052 1053 case ADAPTER_REQ_SET_XFER_MODE: 1054 /* XXX Not supported. */ 1055 return; 1056 } 1057 1058 } 1059 1060 void 1061 mesh_sched(sc) 1062 struct mesh_softc *sc; 1063 { 1064 struct scsipi_xfer *xs; 1065 struct mesh_scb *scb; 1066 1067 scb = sc->ready_scb.tqh_first; 1068 start: 1069 if (scb == NULL) 1070 return; 1071 1072 xs = scb->xs; 1073 1074 if (sc->sc_nexus == NULL) { 1075 TAILQ_REMOVE(&sc->ready_scb, scb, chain); 1076 sc->sc_nexus = scb; 1077 mesh_select(sc, scb); 1078 return; 1079 } 1080 1081 scb = scb->chain.tqe_next; 1082 goto start; 1083 } 1084 1085 int 1086 mesh_poll(sc, xs) 1087 struct mesh_softc *sc; 1088 struct scsipi_xfer *xs; 1089 { 1090 int count = xs->timeout; 1091 1092 while (count) { 1093 if (mesh_read_reg(sc, MESH_INTERRUPT)) 1094 mesh_intr(sc); 1095 1096 if (xs->xs_status & XS_STS_DONE) 1097 return 0; 1098 delay(1000); 1099 count--; 1100 }; 1101 return 1; 1102 } 1103 1104 void 1105 mesh_done(sc, scb) 1106 struct mesh_softc *sc; 1107 struct mesh_scb *scb; 1108 { 1109 struct scsipi_xfer *xs = scb->xs; 1110 1111 DPRINTF("mesh_done\n"); 1112 1113 sc->sc_nextstate = MESH_BUSFREE; 1114 sc->sc_nexus = NULL; 1115 1116 callout_stop(&scb->xs->xs_callout); 1117 1118 if (scb->status == SCSI_BUSY) { 1119 xs->error = XS_BUSY; 1120 printf("Target busy\n"); 1121 } 1122 1123 xs->xs_status = scb->status; 1124 xs->resid = scb->resid; 1125 if (scb->status == SCSI_CHECK) { 1126 xs->error = XS_BUSY; 1127 } 1128 1129 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 1130 1131 if ((xs->xs_control & XS_CTL_POLL) == 0) 1132 mesh_sched(sc); 1133 1134 scsipi_done(xs); 1135 mesh_free_scb(sc, scb); 1136 } 1137 1138 void 1139 mesh_timeout(arg) 1140 void *arg; 1141 { 1142 struct mesh_scb *scb = arg; 1143 struct mesh_softc *sc = 1144 (void *)scb->xs->xs_periph->periph_channel->chan_adapter->adapt_dev; 1145 int s; 1146 int status0, status1; 1147 int intr, error, exception; 1148 1149 printf("%s: timeout state %d\n", sc->sc_dev.dv_xname, sc->sc_nextstate); 1150 1151 intr = mesh_read_reg(sc, MESH_INTERRUPT); 1152 exception = mesh_read_reg(sc, MESH_EXCEPTION); 1153 error = mesh_read_reg(sc, MESH_ERROR); 1154 status0 = mesh_read_reg(sc, MESH_BUS_STATUS0); 1155 status1 = mesh_read_reg(sc, MESH_BUS_STATUS1); 1156 1157 s = splbio(); 1158 if (sc->sc_flags & MESH_DMA_ACTIVE) { 1159 printf("mesh: resetting dma\n"); 1160 dbdma_reset(sc->sc_dmareg); 1161 } 1162 scb->xs->error = XS_TIMEOUT; 1163 1164 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); 1165 sc->sc_nextstate = MESH_COMPLETE; 1166 1167 splx(s); 1168 } 1169 1170 void 1171 mesh_minphys(bp) 1172 struct buf *bp; 1173 { 1174 if (bp->b_bcount > 64*1024) 1175 bp->b_bcount = 64*1024; 1176 1177 minphys(bp); 1178 } 1179