1 /* $NetBSD: mesh.c,v 1.18 2003/05/03 18:10:51 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 CFATTACH_DECL(mesh, sizeof(struct mesh_softc), 180 mesh_match, mesh_attach, NULL, NULL); 181 182 int 183 mesh_match(parent, cf, aux) 184 struct device *parent; 185 struct cfdata *cf; 186 void *aux; 187 { 188 struct confargs *ca = aux; 189 char compat[32]; 190 191 if (strcmp(ca->ca_name, "mesh") == 0) 192 return 1; 193 194 memset(compat, 0, sizeof(compat)); 195 OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat)); 196 if (strcmp(compat, "chrp,mesh0") == 0) 197 return 1; 198 199 return 0; 200 } 201 202 void 203 mesh_attach(parent, self, aux) 204 struct device *parent, *self; 205 void *aux; 206 { 207 struct mesh_softc *sc = (void *)self; 208 struct confargs *ca = aux; 209 int i; 210 u_int *reg; 211 212 reg = ca->ca_reg; 213 reg[0] += ca->ca_baseaddr; 214 reg[2] += ca->ca_baseaddr; 215 sc->sc_reg = mapiodev(reg[0], reg[1]); 216 sc->sc_irq = ca->ca_intr[0]; 217 sc->sc_dmareg = mapiodev(reg[2], reg[3]); 218 219 sc->sc_cfflags = self->dv_cfdata->cf_flags; 220 sc->sc_meshid = mesh_read_reg(sc, MESH_MESH_ID) & 0x1f; 221 #if 0 222 if (sc->sc_meshid != (MESH_SIGNATURE & 0x1f) { 223 printf(": unknown MESH ID (0x%x)\n", sc->sc_meshid); 224 return; 225 } 226 #endif 227 if (OF_getprop(ca->ca_node, "clock-frequency", &sc->sc_freq, 4) != 4) { 228 printf(": cannot get clock-frequency\n"); 229 return; 230 } 231 sc->sc_freq /= 1000000; /* in MHz */ 232 sc->sc_minsync = 25; /* maximum sync rate = 10MB/sec */ 233 sc->sc_id = 7; 234 235 TAILQ_INIT(&sc->free_scb); 236 TAILQ_INIT(&sc->ready_scb); 237 for (i = 0; i < sizeof(sc->sc_scb)/sizeof(sc->sc_scb[0]); i++) 238 TAILQ_INSERT_TAIL(&sc->free_scb, &sc->sc_scb[i], chain); 239 240 sc->sc_dmacmd = dbdma_alloc(sizeof(dbdma_command_t) * 20); 241 242 mesh_reset(sc); 243 mesh_bus_reset(sc); 244 245 printf(" irq %d: %dMHz, SCSI ID %d\n", 246 sc->sc_irq, sc->sc_freq, sc->sc_id); 247 248 sc->sc_adapter.adapt_dev = &sc->sc_dev; 249 sc->sc_adapter.adapt_nchannels = 1; 250 sc->sc_adapter.adapt_openings = 7; 251 sc->sc_adapter.adapt_max_periph = 1; 252 sc->sc_adapter.adapt_ioctl = NULL; 253 sc->sc_adapter.adapt_minphys = mesh_minphys; 254 sc->sc_adapter.adapt_request = mesh_scsi_request; 255 256 sc->sc_channel.chan_adapter = &sc->sc_adapter; 257 sc->sc_channel.chan_bustype = &scsi_bustype; 258 sc->sc_channel.chan_channel = 0; 259 sc->sc_channel.chan_ntargets = 8; 260 sc->sc_channel.chan_nluns = 8; 261 sc->sc_channel.chan_id = sc->sc_id; 262 263 config_found(&sc->sc_dev, &sc->sc_channel, scsiprint); 264 265 intr_establish(sc->sc_irq, IST_LEVEL, IPL_BIO, mesh_intr, sc); 266 267 /* Reset SCSI bus when halt. */ 268 shutdownhook_establish(mesh_shutdownhook, sc); 269 } 270 271 #define MESH_SET_XFER(sc, count) do { \ 272 mesh_set_reg(sc, MESH_XFER_COUNT0, count); \ 273 mesh_set_reg(sc, MESH_XFER_COUNT1, count >> 8); \ 274 } while (0) 275 276 #define MESH_GET_XFER(sc) ((mesh_read_reg(sc, MESH_XFER_COUNT1) << 8) | \ 277 mesh_read_reg(sc, MESH_XFER_COUNT0)) 278 279 int 280 mesh_read_reg(sc, reg) 281 struct mesh_softc *sc; 282 int reg; 283 { 284 return in8(sc->sc_reg + reg); 285 } 286 287 void 288 mesh_set_reg(sc, reg, val) 289 struct mesh_softc *sc; 290 int reg, val; 291 { 292 out8(sc->sc_reg + reg, val); 293 } 294 295 void 296 mesh_shutdownhook(arg) 297 void *arg; 298 { 299 struct mesh_softc *sc = arg; 300 301 /* Set to async mode. */ 302 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 303 } 304 305 #ifdef MESH_DEBUG 306 static char scsi_phase[][8] = { 307 "DATAOUT", 308 "DATAIN", 309 "COMMAND", 310 "STATUS", 311 "", 312 "", 313 "MSGOUT", 314 "MSGIN" 315 }; 316 #endif 317 318 int 319 mesh_intr(arg) 320 void *arg; 321 { 322 struct mesh_softc *sc = arg; 323 struct mesh_scb *scb; 324 int fifocnt; 325 u_char intr, exception, error, status0, status1; 326 327 intr = mesh_read_reg(sc, MESH_INTERRUPT); 328 if (intr == 0) { 329 DPRINTF("%s: stray interrupt\n", sc->sc_dev.dv_xname); 330 return 0; 331 } 332 333 exception = mesh_read_reg(sc, MESH_EXCEPTION); 334 error = mesh_read_reg(sc, MESH_ERROR); 335 status0 = mesh_read_reg(sc, MESH_BUS_STATUS0); 336 status1 = mesh_read_reg(sc, MESH_BUS_STATUS1); 337 338 /* clear interrupt */ 339 mesh_set_reg(sc, MESH_INTERRUPT, intr); 340 341 #ifdef MESH_DEBUG 342 { 343 char buf1[64], buf2[64]; 344 345 bitmask_snprintf(status0, MESH_STATUS0_BITMASK, buf1, sizeof buf1); 346 bitmask_snprintf(exception, MESH_EXC_BITMASK, buf2, sizeof buf2); 347 printf("mesh_intr status0 = 0x%s (%s), exc = 0x%s\n", 348 buf1, scsi_phase[status0 & 7], buf2); 349 } 350 #endif 351 352 scb = sc->sc_nexus; 353 if (scb == NULL) { 354 DPRINTF("%s: NULL nexus\n", sc->sc_dev.dv_xname); 355 return 1; 356 } 357 358 if (sc->sc_flags & MESH_DMA_ACTIVE) { 359 dbdma_stop(sc->sc_dmareg); 360 361 sc->sc_flags &= ~MESH_DMA_ACTIVE; 362 scb->resid = MESH_GET_XFER(sc); 363 364 fifocnt = mesh_read_reg(sc, MESH_FIFO_COUNT); 365 if (fifocnt != 0 && (scb->flags & MESH_READ)) { 366 char *cp = (char *)scb->daddr + scb->dlen - fifocnt; 367 368 DPRINTF("fifocnt = %d, resid = %d\n", fifocnt, 369 scb->resid); 370 while (fifocnt > 0) { 371 *cp++ = mesh_read_reg(sc, MESH_FIFO); 372 fifocnt--; 373 } 374 } else 375 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 376 } 377 378 if (intr & MESH_INTR_ERROR) { 379 mesh_error(sc, scb, error, 0); 380 return 1; 381 } 382 383 if (intr & MESH_INTR_EXCEPTION) { 384 /* selection timeout */ 385 if (exception & MESH_EXC_SELTO) { 386 mesh_error(sc, scb, 0, exception); 387 return 1; 388 } 389 390 /* phase mismatch */ 391 if (exception & MESH_EXC_PHASEMM) { 392 DPRINTF("%s: PHASE MISMATCH; nextstate = %d -> ", 393 sc->sc_dev.dv_xname, sc->sc_nextstate); 394 sc->sc_nextstate = status0 & MESH_PHASE_MASK; 395 396 DPRINTF("%d, resid = %d\n", 397 sc->sc_nextstate, scb->resid); 398 } 399 } 400 401 if (sc->sc_nextstate == MESH_UNKNOWN) 402 sc->sc_nextstate = status0 & MESH_PHASE_MASK; 403 404 switch (sc->sc_nextstate) { 405 406 case MESH_IDENTIFY: 407 mesh_identify(sc, scb); 408 break; 409 case MESH_COMMAND: 410 mesh_command(sc, scb); 411 break; 412 case MESH_DATAIN: 413 case MESH_DATAOUT: 414 mesh_dataio(sc, scb); 415 break; 416 case MESH_STATUS: 417 mesh_status(sc, scb); 418 break; 419 case MESH_MSGIN: 420 mesh_msgin(sc, scb); 421 break; 422 case MESH_COMPLETE: 423 mesh_done(sc, scb); 424 break; 425 426 default: 427 printf("%s: unknown state (%d)\n", sc->sc_dev.dv_xname, 428 sc->sc_nextstate); 429 scb->xs->error = XS_DRIVER_STUFFUP; 430 mesh_done(sc, scb); 431 } 432 433 return 1; 434 } 435 436 void 437 mesh_error(sc, scb, error, exception) 438 struct mesh_softc *sc; 439 struct mesh_scb *scb; 440 int error, exception; 441 { 442 if (error & MESH_ERR_SCSI_RESET) { 443 printf("%s: SCSI RESET\n", sc->sc_dev.dv_xname); 444 445 /* Wait until the RST signal is deasserted. */ 446 while (mesh_read_reg(sc, MESH_BUS_STATUS1) & MESH_STATUS1_RST); 447 mesh_reset(sc); 448 return; 449 } 450 451 if (error & MESH_ERR_PARITY_ERR0) { 452 printf("%s: parity error\n", sc->sc_dev.dv_xname); 453 scb->xs->error = XS_DRIVER_STUFFUP; 454 } 455 456 if (error & MESH_ERR_DISCONNECT) { 457 printf("%s: unexpected disconnect\n", sc->sc_dev.dv_xname); 458 if (sc->sc_nextstate != MESH_COMPLETE) 459 scb->xs->error = XS_DRIVER_STUFFUP; 460 } 461 462 if (exception & MESH_EXC_SELTO) { 463 /* XXX should reset bus here? */ 464 scb->xs->error = XS_SELTIMEOUT; 465 } 466 467 mesh_done(sc, scb); 468 } 469 470 void 471 mesh_select(sc, scb) 472 struct mesh_softc *sc; 473 struct mesh_scb *scb; 474 { 475 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 476 int timeout; 477 478 DPRINTF("mesh_select\n"); 479 480 mesh_setsync(sc, ti); 481 MESH_SET_XFER(sc, 0); 482 483 /* arbitration */ 484 485 /* 486 * MESH mistakenly asserts TARGET ID bit along with its own ID bit 487 * in arbitration phase (like selection). So we should load 488 * initiator ID to DestID register temporarily. 489 */ 490 mesh_set_reg(sc, MESH_DEST_ID, sc->sc_id); 491 mesh_set_reg(sc, MESH_INTR_MASK, 0); /* disable intr. */ 492 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_ARBITRATE); 493 494 while (mesh_read_reg(sc, MESH_INTERRUPT) == 0); 495 mesh_set_reg(sc, MESH_INTERRUPT, 1); 496 mesh_set_reg(sc, MESH_INTR_MASK, 7); 497 498 /* selection */ 499 mesh_set_reg(sc, MESH_DEST_ID, scb->target); 500 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_SELECT | MESH_SEQ_ATN); 501 502 sc->sc_prevphase = MESH_SELECTING; 503 sc->sc_nextstate = MESH_IDENTIFY; 504 505 timeout = mstohz(scb->xs->timeout); 506 if (timeout == 0) 507 timeout = 1; 508 509 callout_reset(&scb->xs->xs_callout, timeout, mesh_timeout, scb); 510 } 511 512 void 513 mesh_identify(sc, scb) 514 struct mesh_softc *sc; 515 struct mesh_scb *scb; 516 { 517 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 518 519 DPRINTF("mesh_identify\n"); 520 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 521 522 if ((ti->flags & T_SYNCNEGO) == 0) { 523 ti->period = sc->sc_minsync; 524 ti->offset = 15; 525 mesh_msgout(sc, SEND_IDENTIFY | SEND_SDTR); 526 sc->sc_nextstate = MESH_MSGIN; 527 } else { 528 mesh_msgout(sc, SEND_IDENTIFY); 529 sc->sc_nextstate = MESH_COMMAND; 530 } 531 } 532 533 void 534 mesh_command(sc, scb) 535 struct mesh_softc *sc; 536 struct mesh_scb *scb; 537 { 538 int i; 539 char *cmdp; 540 541 #ifdef MESH_DEBUG 542 printf("mesh_command cdb = %02x", scb->cmd.opcode); 543 for (i = 0; i < 5; i++) 544 printf(" %02x", scb->cmd.bytes[i]); 545 printf("\n"); 546 #endif 547 548 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 549 550 MESH_SET_XFER(sc, scb->cmdlen); 551 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_COMMAND); 552 553 cmdp = (char *)&scb->cmd; 554 for (i = 0; i < scb->cmdlen; i++) 555 mesh_set_reg(sc, MESH_FIFO, *cmdp++); 556 557 if (scb->resid == 0) 558 sc->sc_nextstate = MESH_STATUS; /* no data xfer */ 559 else 560 sc->sc_nextstate = MESH_DATAIN; 561 } 562 563 void 564 mesh_dma_setup(sc, scb) 565 struct mesh_softc *sc; 566 struct mesh_scb *scb; 567 { 568 int datain = scb->flags & MESH_READ; 569 dbdma_command_t *cmdp; 570 u_int cmd; 571 vaddr_t va; 572 int count, offset; 573 574 cmdp = sc->sc_dmacmd; 575 cmd = datain ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE; 576 577 count = scb->dlen; 578 579 if (count / PAGE_SIZE > 32) 580 panic("mesh: transfer size >= 128k"); 581 582 va = scb->daddr; 583 offset = va & PGOFSET; 584 585 /* if va is not page-aligned, setup the first page */ 586 if (offset != 0) { 587 int rest = PAGE_SIZE - offset; /* the rest in the page */ 588 589 if (count > rest) { /* if continues to next page */ 590 DBDMA_BUILD(cmdp, cmd, 0, rest, vtophys(va), 591 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, 592 DBDMA_BRANCH_NEVER); 593 count -= rest; 594 va += rest; 595 cmdp++; 596 } 597 } 598 599 /* now va is page-aligned */ 600 while (count > PAGE_SIZE) { 601 DBDMA_BUILD(cmdp, cmd, 0, PAGE_SIZE, vtophys(va), 602 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 603 count -= PAGE_SIZE; 604 va += PAGE_SIZE; 605 cmdp++; 606 } 607 608 /* the last page (count <= PAGE_SIZE here) */ 609 cmd = datain ? DBDMA_CMD_IN_LAST : DBDMA_CMD_OUT_LAST; 610 DBDMA_BUILD(cmdp, cmd , 0, count, vtophys(va), 611 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 612 cmdp++; 613 614 DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, 615 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 616 } 617 618 void 619 mesh_dataio(sc, scb) 620 struct mesh_softc *sc; 621 struct mesh_scb *scb; 622 { 623 DPRINTF("mesh_dataio len = %ld (%s)\n", scb->dlen, 624 scb->flags & MESH_READ ? "read" : "write"); 625 626 mesh_dma_setup(sc, scb); 627 628 if (scb->dlen == 65536) 629 MESH_SET_XFER(sc, 0); /* TC = 0 means 64KB transfer */ 630 else 631 MESH_SET_XFER(sc, scb->dlen); 632 633 if (scb->flags & MESH_READ) 634 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_DATAIN | MESH_SEQ_DMA); 635 else 636 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_DATAOUT | MESH_SEQ_DMA); 637 dbdma_start(sc->sc_dmareg, sc->sc_dmacmd); 638 sc->sc_flags |= MESH_DMA_ACTIVE; 639 sc->sc_nextstate = MESH_STATUS; 640 } 641 642 void 643 mesh_status(sc, scb) 644 struct mesh_softc *sc; 645 struct mesh_scb *scb; 646 { 647 if (mesh_read_reg(sc, MESH_FIFO_COUNT) == 0) { /* XXX cheat */ 648 DPRINTF("mesh_status(0)\n"); 649 MESH_SET_XFER(sc, 1); 650 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_STATUS); 651 sc->sc_nextstate = MESH_STATUS; 652 return; 653 } 654 655 scb->status = mesh_read_reg(sc, MESH_FIFO); 656 DPRINTF("mesh_status(1): status = 0x%x\n", scb->status); 657 if (mesh_read_reg(sc, MESH_FIFO_COUNT) != 0) 658 DPRINTF("FIFO_COUNT=%d\n", mesh_read_reg(sc, MESH_FIFO_COUNT)); 659 660 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 661 MESH_SET_XFER(sc, 1); 662 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 663 664 sc->sc_nextstate = MESH_MSGIN; 665 } 666 667 void 668 mesh_msgin(sc, scb) 669 struct mesh_softc *sc; 670 struct mesh_scb *scb; 671 { 672 DPRINTF("mesh_msgin\n"); 673 674 if (mesh_read_reg(sc, MESH_FIFO_COUNT) == 0) { /* XXX cheat */ 675 MESH_SET_XFER(sc, 1); 676 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 677 sc->sc_imsglen = 0; 678 sc->sc_nextstate = MESH_MSGIN; 679 return; 680 } 681 682 sc->sc_imsg[sc->sc_imsglen++] = mesh_read_reg(sc, MESH_FIFO); 683 684 if (sc->sc_imsglen == 1 && MSG_IS1BYTE(sc->sc_imsg[0])) 685 goto gotit; 686 if (sc->sc_imsglen == 2 && MSG_IS2BYTE(sc->sc_imsg[0])) 687 goto gotit; 688 if (sc->sc_imsglen >= 3 && MSG_ISEXTENDED(sc->sc_imsg[0]) && 689 sc->sc_imsglen == sc->sc_imsg[1] + 2) 690 goto gotit; 691 692 sc->sc_nextstate = MESH_MSGIN; 693 MESH_SET_XFER(sc, 1); 694 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 695 return; 696 697 gotit: 698 #ifdef MESH_DEBUG 699 printf("msgin:"); 700 for (i = 0; i < sc->sc_imsglen; i++) 701 printf(" 0x%02x", sc->sc_imsg[i]); 702 printf("\n"); 703 #endif 704 705 switch (sc->sc_imsg[0]) { 706 case MSG_CMDCOMPLETE: 707 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); 708 sc->sc_nextstate = MESH_COMPLETE; 709 sc->sc_imsglen = 0; 710 return; 711 712 case MSG_MESSAGE_REJECT: 713 if (sc->sc_msgout & SEND_SDTR) { 714 printf("SDTR rejected\n"); 715 printf("using async mode\n"); 716 sc->sc_tinfo[scb->target].period = 0; 717 sc->sc_tinfo[scb->target].offset = 0; 718 mesh_setsync(sc, &sc->sc_tinfo[scb->target]); 719 break; 720 } 721 break; 722 723 case MSG_NOOP: 724 break; 725 726 case MSG_EXTENDED: 727 goto extended_msg; 728 729 default: 730 scsipi_printaddr(scb->xs->xs_periph); 731 printf("unrecognized MESSAGE(0x%02x); sending REJECT\n", 732 sc->sc_imsg[0]); 733 734 reject: 735 mesh_msgout(sc, SEND_REJECT); 736 return; 737 } 738 goto done; 739 740 extended_msg: 741 /* process an extended message */ 742 switch (sc->sc_imsg[2]) { 743 case MSG_EXT_SDTR: 744 { 745 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 746 int period = sc->sc_imsg[3]; 747 int offset = sc->sc_imsg[4]; 748 int r = 250 / period; 749 int s = (100*250) / period - 100 * r; 750 751 if (period < sc->sc_minsync) { 752 ti->period = sc->sc_minsync; 753 ti->offset = 15; 754 mesh_msgout(sc, SEND_SDTR); 755 return; 756 } 757 scsipi_printaddr(scb->xs->xs_periph); 758 /* XXX if (offset != 0) ... */ 759 printf("max sync rate %d.%02dMb/s\n", r, s); 760 ti->period = period; 761 ti->offset = offset; 762 ti->flags |= T_SYNCNEGO; 763 ti->flags |= T_SYNCMODE; 764 mesh_setsync(sc, ti); 765 goto done; 766 } 767 default: 768 printf("%s target %d: rejecting extended message 0x%x\n", 769 sc->sc_dev.dv_xname, scb->target, sc->sc_imsg[0]); 770 goto reject; 771 } 772 773 done: 774 sc->sc_imsglen = 0; 775 sc->sc_nextstate = MESH_UNKNOWN; 776 777 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); /* XXX really? */ 778 } 779 780 void 781 mesh_msgout(sc, msg) 782 struct mesh_softc *sc; 783 int msg; 784 { 785 struct mesh_scb *scb = sc->sc_nexus; 786 struct mesh_tinfo *ti; 787 int lun, len, i; 788 789 DPRINTF("mesh_msgout: sending"); 790 791 sc->sc_msgout = msg; 792 len = 0; 793 794 if (msg & SEND_REJECT) { 795 DPRINTF(" REJECT"); 796 sc->sc_omsg[len++] = MSG_MESSAGE_REJECT; 797 } 798 if (msg & SEND_IDENTIFY) { 799 DPRINTF(" IDENTIFY"); 800 lun = scb->xs->xs_periph->periph_lun; 801 sc->sc_omsg[len++] = MSG_IDENTIFY(lun, 0); 802 } 803 if (msg & SEND_SDTR) { 804 DPRINTF(" SDTR"); 805 ti = &sc->sc_tinfo[scb->target]; 806 sc->sc_omsg[len++] = MSG_EXTENDED; 807 sc->sc_omsg[len++] = 3; 808 sc->sc_omsg[len++] = MSG_EXT_SDTR; 809 sc->sc_omsg[len++] = ti->period; 810 sc->sc_omsg[len++] = ti->offset; 811 } 812 DPRINTF("\n"); 813 814 MESH_SET_XFER(sc, len); 815 if (len == 1) { 816 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGOUT); 817 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[0]); 818 } else { 819 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGOUT | MESH_SEQ_ATN); 820 821 for (i = 0; i < len - 1; i++) 822 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[i]); 823 824 /* Wait for the FIFO empty... */ 825 while (mesh_read_reg(sc, MESH_FIFO_COUNT) > 0); 826 827 /* ...then write the last byte. */ 828 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[i]); 829 } 830 sc->sc_nextstate = MESH_UNKNOWN; 831 } 832 833 void 834 mesh_bus_reset(sc) 835 struct mesh_softc *sc; 836 { 837 DPRINTF("mesh_bus_reset\n"); 838 839 /* Disable interrupts. */ 840 mesh_set_reg(sc, MESH_INTR_MASK, 0); 841 842 /* Assert RST line. */ 843 mesh_set_reg(sc, MESH_BUS_STATUS1, MESH_STATUS1_RST); 844 delay(50); 845 mesh_set_reg(sc, MESH_BUS_STATUS1, 0); 846 847 mesh_reset(sc); 848 } 849 850 void 851 mesh_reset(sc) 852 struct mesh_softc *sc; 853 { 854 int i; 855 856 DPRINTF("mesh_reset\n"); 857 858 /* Reset DMA first. */ 859 dbdma_reset(sc->sc_dmareg); 860 861 /* Disable interrupts. */ 862 mesh_set_reg(sc, MESH_INTR_MASK, 0); 863 864 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_RESET_MESH); 865 delay(1); 866 867 /* Wait for reset done. */ 868 while (mesh_read_reg(sc, MESH_INTERRUPT) == 0); 869 870 /* Clear interrupts */ 871 mesh_set_reg(sc, MESH_INTERRUPT, 0x7); 872 873 /* Set SCSI ID */ 874 mesh_set_reg(sc, MESH_SOURCE_ID, sc->sc_id); 875 876 /* Set to async mode by default. */ 877 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 878 879 /* Set selection timeout to 250ms. */ 880 mesh_set_reg(sc, MESH_SEL_TIMEOUT, 250 * sc->sc_freq / 500); 881 882 /* Enable parity check. */ 883 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_ENABLE_PARITY); 884 885 /* Enable all interrupts. */ 886 mesh_set_reg(sc, MESH_INTR_MASK, 0x7); 887 888 for (i = 0; i < 7; i++) { 889 struct mesh_tinfo *ti = &sc->sc_tinfo[i]; 890 891 ti->flags = 0; 892 ti->period = ti->offset = 0; 893 if (sc->sc_cfflags & (0x100 << i)) 894 ti->flags |= T_SYNCNEGO; 895 } 896 sc->sc_nexus = NULL; 897 } 898 899 int 900 mesh_stp(sc, v) 901 struct mesh_softc *sc; 902 int v; 903 { 904 /* 905 * stp(v) = 5 * clock_period (v == 0) 906 * = (v + 2) * 2 clock_period (v > 0) 907 */ 908 909 if (v == 0) 910 return 5 * 250 / sc->sc_freq; 911 else 912 return (v + 2) * 2 * 250 / sc->sc_freq; 913 } 914 915 void 916 mesh_setsync(sc, ti) 917 struct mesh_softc *sc; 918 struct mesh_tinfo *ti; 919 { 920 int period = ti->period; 921 int offset = ti->offset; 922 int v; 923 924 if ((ti->flags & T_SYNCMODE) == 0) 925 offset = 0; 926 927 if (offset == 0) { /* async mode */ 928 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 929 return; 930 } 931 932 v = period * sc->sc_freq / 250 / 2 - 2; 933 if (v < 0) 934 v = 0; 935 if (mesh_stp(sc, v) < period) 936 v++; 937 if (v > 15) 938 v = 15; 939 mesh_set_reg(sc, MESH_SYNC_PARAM, (offset << 4) | v); 940 } 941 942 struct mesh_scb * 943 mesh_get_scb(sc) 944 struct mesh_softc *sc; 945 { 946 struct mesh_scb *scb; 947 int s; 948 949 s = splbio(); 950 if ((scb = sc->free_scb.tqh_first) != NULL) 951 TAILQ_REMOVE(&sc->free_scb, scb, chain); 952 splx(s); 953 954 return scb; 955 } 956 957 void 958 mesh_free_scb(sc, scb) 959 struct mesh_softc *sc; 960 struct mesh_scb *scb; 961 { 962 int s; 963 964 s = splbio(); 965 TAILQ_INSERT_HEAD(&sc->free_scb, scb, chain); 966 splx(s); 967 } 968 969 void 970 mesh_scsi_request(chan, req, arg) 971 struct scsipi_channel *chan; 972 scsipi_adapter_req_t req; 973 void *arg; 974 { 975 struct scsipi_xfer *xs; 976 struct scsipi_periph *periph; 977 struct mesh_softc *sc = (void *)chan->chan_adapter->adapt_dev; 978 struct mesh_scb *scb; 979 u_int flags; 980 int s; 981 982 switch (req) { 983 case ADAPTER_REQ_RUN_XFER: 984 xs = arg; 985 periph = xs->xs_periph; 986 flags = xs->xs_control; 987 988 989 if ((scb = mesh_get_scb(sc)) == NULL) { 990 xs->error = XS_RESOURCE_SHORTAGE; 991 scsipi_done(xs); 992 return; 993 } 994 scb->xs = xs; 995 scb->flags = 0; 996 scb->status = 0; 997 scb->daddr = (vaddr_t)xs->data; 998 scb->dlen = xs->datalen; 999 scb->resid = xs->datalen; 1000 memcpy(&scb->cmd, xs->cmd, xs->cmdlen); 1001 scb->cmdlen = xs->cmdlen; 1002 scb->target = periph->periph_target; 1003 sc->sc_imsglen = 0; /* XXX ? */ 1004 1005 #ifdef MESH_DEBUG 1006 { 1007 int i; 1008 printf("mesh_scsi_cmd: target = %d, cdb = %02x", 1009 scb->target, scb->cmd.opcode); 1010 for (i = 0; i < 5; i++) 1011 printf(" %02x", scb->cmd.bytes[i]); 1012 printf("\n"); 1013 } 1014 #endif 1015 1016 if (flags & XS_CTL_POLL) 1017 scb->flags |= MESH_POLL; 1018 #if 0 1019 if (flags & XS_CTL_DATA_OUT) 1020 scb->flags &= ~MESH_READ; 1021 #endif 1022 if (flags & XS_CTL_DATA_IN) 1023 scb->flags |= MESH_READ; 1024 1025 s = splbio(); 1026 1027 TAILQ_INSERT_TAIL(&sc->ready_scb, scb, chain); 1028 1029 if (sc->sc_nexus == NULL) /* IDLE */ 1030 mesh_sched(sc); 1031 1032 splx(s); 1033 1034 if ((flags & XS_CTL_POLL) == 0) 1035 return; 1036 1037 if (mesh_poll(sc, xs)) { 1038 printf("%s: timeout\n", sc->sc_dev.dv_xname); 1039 if (mesh_poll(sc, xs)) 1040 printf("%s: timeout again\n", sc->sc_dev.dv_xname); 1041 } 1042 return; 1043 1044 case ADAPTER_REQ_GROW_RESOURCES: 1045 /* XXX Not supported. */ 1046 return; 1047 1048 case ADAPTER_REQ_SET_XFER_MODE: 1049 /* XXX Not supported. */ 1050 return; 1051 } 1052 1053 } 1054 1055 void 1056 mesh_sched(sc) 1057 struct mesh_softc *sc; 1058 { 1059 struct scsipi_xfer *xs; 1060 struct mesh_scb *scb; 1061 1062 scb = sc->ready_scb.tqh_first; 1063 start: 1064 if (scb == NULL) 1065 return; 1066 1067 xs = scb->xs; 1068 1069 if (sc->sc_nexus == NULL) { 1070 TAILQ_REMOVE(&sc->ready_scb, scb, chain); 1071 sc->sc_nexus = scb; 1072 mesh_select(sc, scb); 1073 return; 1074 } 1075 1076 scb = scb->chain.tqe_next; 1077 goto start; 1078 } 1079 1080 int 1081 mesh_poll(sc, xs) 1082 struct mesh_softc *sc; 1083 struct scsipi_xfer *xs; 1084 { 1085 int count = xs->timeout; 1086 1087 while (count) { 1088 if (mesh_read_reg(sc, MESH_INTERRUPT)) 1089 mesh_intr(sc); 1090 1091 if (xs->xs_status & XS_STS_DONE) 1092 return 0; 1093 delay(1000); 1094 count--; 1095 }; 1096 return 1; 1097 } 1098 1099 void 1100 mesh_done(sc, scb) 1101 struct mesh_softc *sc; 1102 struct mesh_scb *scb; 1103 { 1104 struct scsipi_xfer *xs = scb->xs; 1105 1106 DPRINTF("mesh_done\n"); 1107 1108 sc->sc_nextstate = MESH_BUSFREE; 1109 sc->sc_nexus = NULL; 1110 1111 callout_stop(&scb->xs->xs_callout); 1112 1113 if (scb->status == SCSI_BUSY) { 1114 xs->error = XS_BUSY; 1115 printf("Target busy\n"); 1116 } 1117 1118 xs->xs_status = scb->status; 1119 xs->resid = scb->resid; 1120 if (scb->status == SCSI_CHECK) { 1121 xs->error = XS_BUSY; 1122 } 1123 1124 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 1125 1126 if ((xs->xs_control & XS_CTL_POLL) == 0) 1127 mesh_sched(sc); 1128 1129 scsipi_done(xs); 1130 mesh_free_scb(sc, scb); 1131 } 1132 1133 void 1134 mesh_timeout(arg) 1135 void *arg; 1136 { 1137 struct mesh_scb *scb = arg; 1138 struct mesh_softc *sc = 1139 (void *)scb->xs->xs_periph->periph_channel->chan_adapter->adapt_dev; 1140 int s; 1141 int status0, status1; 1142 int intr, error, exception; 1143 1144 printf("%s: timeout state %d\n", sc->sc_dev.dv_xname, sc->sc_nextstate); 1145 1146 intr = mesh_read_reg(sc, MESH_INTERRUPT); 1147 exception = mesh_read_reg(sc, MESH_EXCEPTION); 1148 error = mesh_read_reg(sc, MESH_ERROR); 1149 status0 = mesh_read_reg(sc, MESH_BUS_STATUS0); 1150 status1 = mesh_read_reg(sc, MESH_BUS_STATUS1); 1151 1152 s = splbio(); 1153 if (sc->sc_flags & MESH_DMA_ACTIVE) { 1154 printf("mesh: resetting DMA\n"); 1155 dbdma_reset(sc->sc_dmareg); 1156 } 1157 scb->xs->error = XS_TIMEOUT; 1158 1159 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); 1160 sc->sc_nextstate = MESH_COMPLETE; 1161 1162 splx(s); 1163 } 1164 1165 void 1166 mesh_minphys(bp) 1167 struct buf *bp; 1168 { 1169 if (bp->b_bcount > 64*1024) 1170 bp->b_bcount = 64*1024; 1171 1172 minphys(bp); 1173 } 1174