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