1 /* $NetBSD: mesh.c,v 1.7 2000/10/31 16:57:07 tsubai 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 484 DPRINTF("mesh_select\n"); 485 486 mesh_setsync(sc, ti); 487 MESH_SET_XFER(sc, 0); 488 489 /* arbitration */ 490 491 /* 492 * MESH mistakenly asserts TARGET ID bit along with its own ID bit 493 * in arbitration phase (like selection). So we should load 494 * initiator ID to DestID register temporarily. 495 */ 496 mesh_set_reg(sc, MESH_DEST_ID, sc->sc_id); 497 mesh_set_reg(sc, MESH_INTR_MASK, 0); /* disable intr. */ 498 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_ARBITRATE); 499 500 while (mesh_read_reg(sc, MESH_INTERRUPT) == 0); 501 mesh_set_reg(sc, MESH_INTERRUPT, 1); 502 mesh_set_reg(sc, MESH_INTR_MASK, 7); 503 504 /* selection */ 505 mesh_set_reg(sc, MESH_DEST_ID, scb->target); 506 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_SELECT | MESH_SEQ_ATN); 507 508 sc->sc_prevphase = MESH_SELECTING; 509 sc->sc_nextstate = MESH_IDENTIFY; 510 511 callout_reset(&scb->xs->xs_callout, 10 * hz, mesh_timeout, scb); 512 } 513 514 void 515 mesh_identify(sc, scb) 516 struct mesh_softc *sc; 517 struct mesh_scb *scb; 518 { 519 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 520 521 DPRINTF("mesh_identify\n"); 522 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 523 524 if ((ti->flags & T_SYNCNEGO) == 0) { 525 ti->period = sc->sc_minsync; 526 ti->offset = 15; 527 mesh_msgout(sc, SEND_IDENTIFY | SEND_SDTR); 528 sc->sc_nextstate = MESH_MSGIN; 529 } else { 530 mesh_msgout(sc, SEND_IDENTIFY); 531 sc->sc_nextstate = MESH_COMMAND; 532 } 533 } 534 535 void 536 mesh_command(sc, scb) 537 struct mesh_softc *sc; 538 struct mesh_scb *scb; 539 { 540 int i; 541 char *cmdp; 542 543 #ifdef MESH_DEBUG 544 printf("mesh_command cdb = %02x", scb->cmd.opcode); 545 for (i = 0; i < 5; i++) 546 printf(" %02x", scb->cmd.bytes[i]); 547 printf("\n"); 548 #endif 549 550 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 551 552 MESH_SET_XFER(sc, scb->cmdlen); 553 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_COMMAND); 554 555 cmdp = (char *)&scb->cmd; 556 for (i = 0; i < scb->cmdlen; i++) 557 mesh_set_reg(sc, MESH_FIFO, *cmdp++); 558 559 if (scb->resid == 0) 560 sc->sc_nextstate = MESH_STATUS; /* no data xfer */ 561 else 562 sc->sc_nextstate = MESH_DATAIN; 563 } 564 565 void 566 mesh_dma_setup(sc, scb) 567 struct mesh_softc *sc; 568 struct mesh_scb *scb; 569 { 570 int datain = scb->flags & MESH_READ; 571 dbdma_command_t *cmdp; 572 u_int cmd; 573 vaddr_t va; 574 int count, offset; 575 576 cmdp = sc->sc_dmacmd; 577 cmd = datain ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE; 578 579 count = scb->dlen; 580 581 if (count / NBPG > 32) 582 panic("mesh: transfer size >= 128k"); 583 584 va = scb->daddr; 585 offset = va & PGOFSET; 586 587 /* if va is not page-aligned, setup the first page */ 588 if (offset != 0) { 589 int rest = NBPG - offset; /* the rest in the page */ 590 591 if (count > rest) { /* if continues to next page */ 592 DBDMA_BUILD(cmdp, cmd, 0, rest, vtophys(va), 593 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, 594 DBDMA_BRANCH_NEVER); 595 count -= rest; 596 va += rest; 597 cmdp++; 598 } 599 } 600 601 /* now va is page-aligned */ 602 while (count > NBPG) { 603 DBDMA_BUILD(cmdp, cmd, 0, NBPG, vtophys(va), 604 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 605 count -= NBPG; 606 va += NBPG; 607 cmdp++; 608 } 609 610 /* the last page (count <= NBPG here) */ 611 cmd = datain ? DBDMA_CMD_IN_LAST : DBDMA_CMD_OUT_LAST; 612 DBDMA_BUILD(cmdp, cmd , 0, count, vtophys(va), 613 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 614 cmdp++; 615 616 DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, 617 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 618 } 619 620 void 621 mesh_dataio(sc, scb) 622 struct mesh_softc *sc; 623 struct mesh_scb *scb; 624 { 625 DPRINTF("mesh_dataio len = %ld (%s)\n", scb->dlen, 626 scb->flags & MESH_READ ? "read" : "write"); 627 628 mesh_dma_setup(sc, scb); 629 630 if (scb->dlen == 65536) 631 MESH_SET_XFER(sc, 0); /* TC = 0 means 64KB transfer */ 632 else 633 MESH_SET_XFER(sc, scb->dlen); 634 635 if (scb->flags & MESH_READ) 636 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_DATAIN | MESH_SEQ_DMA); 637 else 638 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_DATAOUT | MESH_SEQ_DMA); 639 dbdma_start(sc->sc_dmareg, sc->sc_dmacmd); 640 sc->sc_flags |= MESH_DMA_ACTIVE; 641 sc->sc_nextstate = MESH_STATUS; 642 } 643 644 void 645 mesh_status(sc, scb) 646 struct mesh_softc *sc; 647 struct mesh_scb *scb; 648 { 649 if (mesh_read_reg(sc, MESH_FIFO_COUNT) == 0) { /* XXX cheat */ 650 DPRINTF("mesh_status(0)\n"); 651 MESH_SET_XFER(sc, 1); 652 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_STATUS); 653 sc->sc_nextstate = MESH_STATUS; 654 return; 655 } 656 657 scb->status = mesh_read_reg(sc, MESH_FIFO); 658 DPRINTF("mesh_status(1): status = 0x%x\n", scb->status); 659 if (mesh_read_reg(sc, MESH_FIFO_COUNT) != 0) 660 DPRINTF("FIFO_COUNT=%d\n", mesh_read_reg(sc, MESH_FIFO_COUNT)); 661 662 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_FLUSH_FIFO); 663 MESH_SET_XFER(sc, 1); 664 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 665 666 sc->sc_nextstate = MESH_MSGIN; 667 } 668 669 #define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80) 670 #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20) 671 #define ISEXTMSG(m) ((m) == 1) 672 673 void 674 mesh_msgin(sc, scb) 675 struct mesh_softc *sc; 676 struct mesh_scb *scb; 677 { 678 int i; 679 680 DPRINTF("mesh_msgin\n"); 681 682 if (mesh_read_reg(sc, MESH_FIFO_COUNT) == 0) { /* XXX cheat */ 683 MESH_SET_XFER(sc, 1); 684 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 685 sc->sc_imsglen = 0; 686 sc->sc_nextstate = MESH_MSGIN; 687 return; 688 } 689 690 sc->sc_imsg[sc->sc_imsglen++] = mesh_read_reg(sc, MESH_FIFO); 691 692 if (sc->sc_imsglen == 1 && IS1BYTEMSG(sc->sc_imsg[0])) 693 goto gotit; 694 if (sc->sc_imsglen == 2 && IS2BYTEMSG(sc->sc_imsg[0])) 695 goto gotit; 696 if (sc->sc_imsglen >= 3 && ISEXTMSG(sc->sc_imsg[0]) && 697 sc->sc_imsglen == sc->sc_imsg[1] + 2) 698 goto gotit; 699 700 sc->sc_nextstate = MESH_MSGIN; 701 MESH_SET_XFER(sc, 1); 702 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGIN); 703 return; 704 705 gotit: 706 #ifdef MESH_DEBUG 707 printf("msgin:"); 708 for (i = 0; i < sc->sc_imsglen; i++) 709 printf(" 0x%02x", sc->sc_imsg[i]); 710 printf("\n"); 711 #endif 712 713 switch (sc->sc_imsg[0]) { 714 case MSG_CMDCOMPLETE: 715 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); 716 sc->sc_nextstate = MESH_COMPLETE; 717 sc->sc_imsglen = 0; 718 return; 719 720 case MSG_MESSAGE_REJECT: 721 if (sc->sc_msgout & SEND_SDTR) { 722 printf("SDTR rejected\n"); 723 printf("using async mode\n"); 724 sc->sc_tinfo[scb->target].period = 0; 725 sc->sc_tinfo[scb->target].offset = 0; 726 mesh_setsync(sc, &sc->sc_tinfo[scb->target]); 727 break; 728 } 729 break; 730 731 case MSG_NOOP: 732 break; 733 734 case MSG_EXTENDED: 735 goto extended_msg; 736 737 default: 738 scsi_print_addr(scb->xs->sc_link); 739 printf("unrecognized MESSAGE(0x%02x); sending REJECT\n", 740 sc->sc_imsg[0]); 741 742 reject: 743 mesh_msgout(sc, SEND_REJECT); 744 return; 745 } 746 goto done; 747 748 extended_msg: 749 /* process an extended message */ 750 switch (sc->sc_imsg[2]) { 751 case MSG_EXT_SDTR: 752 { 753 struct mesh_tinfo *ti = &sc->sc_tinfo[scb->target]; 754 int period = sc->sc_imsg[3]; 755 int offset = sc->sc_imsg[4]; 756 int r = 250 / period; 757 int s = (100*250) / period - 100 * r; 758 759 if (period < sc->sc_minsync) { 760 ti->period = sc->sc_minsync; 761 ti->offset = 15; 762 mesh_msgout(sc, SEND_SDTR); 763 return; 764 } 765 scsi_print_addr(scb->xs->sc_link); 766 /* XXX if (offset != 0) ... */ 767 printf("max sync rate %d.%02dMb/s\n", r, s); 768 ti->period = period; 769 ti->offset = offset; 770 ti->flags |= T_SYNCNEGO; 771 ti->flags |= T_SYNCMODE; 772 mesh_setsync(sc, ti); 773 goto done; 774 } 775 default: 776 printf("%s target %d: rejecting extended message 0x%x\n", 777 sc->sc_dev.dv_xname, scb->target, sc->sc_imsg[0]); 778 goto reject; 779 } 780 781 done: 782 sc->sc_imsglen = 0; 783 sc->sc_nextstate = MESH_UNKNOWN; 784 785 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); /* XXX really? */ 786 } 787 788 void 789 mesh_msgout(sc, msg) 790 struct mesh_softc *sc; 791 int msg; 792 { 793 struct mesh_scb *scb = sc->sc_nexus; 794 struct mesh_tinfo *ti; 795 int lun, len, i; 796 797 DPRINTF("mesh_msgout: sending"); 798 799 sc->sc_msgout = msg; 800 len = 0; 801 802 if (msg & SEND_REJECT) { 803 DPRINTF(" REJECT"); 804 sc->sc_omsg[len++] = MSG_MESSAGE_REJECT; 805 } 806 if (msg & SEND_IDENTIFY) { 807 DPRINTF(" IDENTIFY"); 808 lun = scb->xs->sc_link->scsipi_scsi.lun; 809 sc->sc_omsg[len++] = MSG_IDENTIFY(lun, 0); 810 } 811 if (msg & SEND_SDTR) { 812 DPRINTF(" SDTR"); 813 ti = &sc->sc_tinfo[scb->target]; 814 sc->sc_omsg[len++] = MSG_EXTENDED; 815 sc->sc_omsg[len++] = 3; 816 sc->sc_omsg[len++] = MSG_EXT_SDTR; 817 sc->sc_omsg[len++] = ti->period; 818 sc->sc_omsg[len++] = ti->offset; 819 } 820 DPRINTF("\n"); 821 822 MESH_SET_XFER(sc, len); 823 if (len == 1) { 824 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGOUT); 825 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[0]); 826 } else { 827 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_MSGOUT | MESH_SEQ_ATN); 828 829 for (i = 0; i < len - 1; i++) 830 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[i]); 831 832 /* Wait for the FIFO empty... */ 833 while (mesh_read_reg(sc, MESH_FIFO_COUNT) > 0); 834 835 /* ...then write the last byte. */ 836 mesh_set_reg(sc, MESH_FIFO, sc->sc_omsg[i]); 837 } 838 sc->sc_nextstate = MESH_UNKNOWN; 839 } 840 841 void 842 mesh_bus_reset(sc) 843 struct mesh_softc *sc; 844 { 845 DPRINTF("mesh_bus_reset\n"); 846 847 /* Disable interrupts. */ 848 mesh_set_reg(sc, MESH_INTR_MASK, 0); 849 850 /* Assert RST line. */ 851 mesh_set_reg(sc, MESH_BUS_STATUS1, MESH_STATUS1_RST); 852 delay(50); 853 mesh_set_reg(sc, MESH_BUS_STATUS1, 0); 854 855 mesh_reset(sc); 856 } 857 858 void 859 mesh_reset(sc) 860 struct mesh_softc *sc; 861 { 862 int i; 863 864 DPRINTF("mesh_reset\n"); 865 866 /* Reset DMA first. */ 867 dbdma_reset(sc->sc_dmareg); 868 869 /* Disable interrupts. */ 870 mesh_set_reg(sc, MESH_INTR_MASK, 0); 871 872 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_RESET_MESH); 873 delay(1); 874 875 /* Wait for reset done. */ 876 while (mesh_read_reg(sc, MESH_INTERRUPT) == 0); 877 878 /* Clear interrupts */ 879 mesh_set_reg(sc, MESH_INTERRUPT, 0x7); 880 881 /* Set SCSI ID */ 882 mesh_set_reg(sc, MESH_SOURCE_ID, sc->sc_id); 883 884 /* Set to async mode by default. */ 885 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 886 887 /* Set selection timeout to 250ms. */ 888 mesh_set_reg(sc, MESH_SEL_TIMEOUT, 250 * sc->sc_freq / 500); 889 890 /* Enable parity check. */ 891 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_ENABLE_PARITY); 892 893 /* Enable all interrupts. */ 894 mesh_set_reg(sc, MESH_INTR_MASK, 0x7); 895 896 for (i = 0; i < 7; i++) { 897 struct mesh_tinfo *ti = &sc->sc_tinfo[i]; 898 899 ti->flags = 0; 900 ti->period = ti->offset = 0; 901 if (sc->sc_cfflags & (0x100 << i)) 902 ti->flags |= T_SYNCNEGO; 903 } 904 sc->sc_nexus = NULL; 905 } 906 907 int 908 mesh_stp(sc, v) 909 struct mesh_softc *sc; 910 int v; 911 { 912 /* 913 * stp(v) = 5 * clock_period (v == 0) 914 * = (v + 2) * 2 clock_period (v > 0) 915 */ 916 917 if (v == 0) 918 return 5 * 250 / sc->sc_freq; 919 else 920 return (v + 2) * 2 * 250 / sc->sc_freq; 921 } 922 923 void 924 mesh_setsync(sc, ti) 925 struct mesh_softc *sc; 926 struct mesh_tinfo *ti; 927 { 928 int period = ti->period; 929 int offset = ti->offset; 930 int v; 931 932 if ((ti->flags & T_SYNCMODE) == 0) 933 offset = 0; 934 935 if (offset == 0) { /* async mode */ 936 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 937 return; 938 } 939 940 v = period * sc->sc_freq / 250 / 2 - 2; 941 if (v < 0) 942 v = 0; 943 if (mesh_stp(sc, v) < period) 944 v++; 945 if (v > 15) 946 v = 15; 947 mesh_set_reg(sc, MESH_SYNC_PARAM, (offset << 4) | v); 948 } 949 950 struct mesh_scb * 951 mesh_get_scb(sc) 952 struct mesh_softc *sc; 953 { 954 struct mesh_scb *scb; 955 int s; 956 957 s = splbio(); 958 if ((scb = sc->free_scb.tqh_first) != NULL) 959 TAILQ_REMOVE(&sc->free_scb, scb, chain); 960 splx(s); 961 962 return scb; 963 } 964 965 void 966 mesh_free_scb(sc, scb) 967 struct mesh_softc *sc; 968 struct mesh_scb *scb; 969 { 970 int s; 971 972 s = splbio(); 973 TAILQ_INSERT_HEAD(&sc->free_scb, scb, chain); 974 splx(s); 975 } 976 977 int 978 mesh_scsi_cmd(xs) 979 struct scsipi_xfer *xs; 980 { 981 struct scsipi_link *sc_link = xs->sc_link; 982 struct mesh_softc *sc = sc_link->adapter_softc; 983 struct mesh_scb *scb; 984 u_int flags = xs->xs_control; 985 int s; 986 987 if ((scb = mesh_get_scb(sc)) == NULL) 988 return TRY_AGAIN_LATER; 989 scb->xs = xs; 990 scb->flags = 0; 991 scb->status = 0; 992 scb->daddr = (vaddr_t)xs->data; 993 scb->dlen = xs->datalen; 994 scb->resid = xs->datalen; 995 bcopy(xs->cmd, &scb->cmd, xs->cmdlen); 996 scb->cmdlen = xs->cmdlen; 997 scb->target = sc_link->scsipi_scsi.target; 998 sc->sc_imsglen = 0; /* XXX ? */ 999 1000 #ifdef MESH_DEBUG 1001 { 1002 int i; 1003 printf("mesh_scsi_cmd: target = %d, cdb = %02x", 1004 scb->target, scb->cmd.opcode); 1005 for (i = 0; i < 5; i++) 1006 printf(" %02x", scb->cmd.bytes[i]); 1007 printf("\n"); 1008 } 1009 #endif 1010 1011 if (flags & XS_CTL_POLL) 1012 scb->flags |= MESH_POLL; 1013 #if 0 1014 if (flags & XS_CTL_DATA_OUT) 1015 scb->flags &= ~MESH_READ; 1016 #endif 1017 if (flags & XS_CTL_DATA_IN) 1018 scb->flags |= MESH_READ; 1019 1020 s = splbio(); 1021 1022 TAILQ_INSERT_TAIL(&sc->ready_scb, scb, chain); 1023 1024 if (sc->sc_nexus == NULL) /* IDLE */ 1025 mesh_sched(sc); 1026 1027 splx(s); 1028 1029 if ((flags & XS_CTL_POLL) == 0) 1030 return SUCCESSFULLY_QUEUED; 1031 1032 if (mesh_poll(sc, xs)) { 1033 printf("%s: timeout\n", sc->sc_dev.dv_xname); 1034 if (mesh_poll(sc, xs)) 1035 printf("%s: timeout again\n", sc->sc_dev.dv_xname); 1036 } 1037 return COMPLETE; 1038 } 1039 1040 void 1041 mesh_sched(sc) 1042 struct mesh_softc *sc; 1043 { 1044 struct scsipi_xfer *xs; 1045 struct mesh_scb *scb; 1046 1047 scb = sc->ready_scb.tqh_first; 1048 start: 1049 if (scb == NULL) 1050 return; 1051 1052 xs = scb->xs; 1053 1054 if (sc->sc_nexus == NULL) { 1055 TAILQ_REMOVE(&sc->ready_scb, scb, chain); 1056 sc->sc_nexus = scb; 1057 mesh_select(sc, scb); 1058 return; 1059 } 1060 1061 scb = scb->chain.tqe_next; 1062 goto start; 1063 } 1064 1065 int 1066 mesh_poll(sc, xs) 1067 struct mesh_softc *sc; 1068 struct scsipi_xfer *xs; 1069 { 1070 int count = xs->timeout; 1071 1072 while (count) { 1073 if (mesh_read_reg(sc, MESH_INTERRUPT)) 1074 mesh_intr(sc); 1075 1076 if (xs->xs_status & XS_STS_DONE) 1077 return 0; 1078 delay(1000); 1079 count--; 1080 }; 1081 return 1; 1082 } 1083 1084 void 1085 mesh_done(sc, scb) 1086 struct mesh_softc *sc; 1087 struct mesh_scb *scb; 1088 { 1089 struct scsipi_xfer *xs = scb->xs; 1090 1091 DPRINTF("mesh_done\n"); 1092 1093 sc->sc_nextstate = MESH_BUSFREE; 1094 sc->sc_nexus = NULL; 1095 1096 callout_stop(&scb->xs->xs_callout); 1097 1098 if (scb->status == SCSI_BUSY) { 1099 xs->error = XS_BUSY; 1100 printf("Target busy\n"); 1101 } 1102 1103 if (scb->status == SCSI_CHECK) { 1104 DPRINTF("mesh_done: CHECK CONDITION\n"); 1105 if (scb->flags & MESH_SENSE) { 1106 printf("mesh: SCSI_CHECK && MESH_SENSE?\n"); 1107 xs->xs_status |= XS_STS_DONE; 1108 xs->error = XS_DRIVER_STUFFUP; 1109 scsipi_done(xs); 1110 mesh_free_scb(sc, scb); 1111 return; 1112 } 1113 xs->resid = scb->resid; 1114 mesh_sense(sc, scb); 1115 return; 1116 } 1117 1118 if (xs->error == XS_NOERROR) { 1119 xs->status = scb->status; 1120 if (scb->flags & MESH_SENSE) 1121 xs->error = XS_SENSE; 1122 else 1123 xs->resid = scb->resid; 1124 } 1125 1126 #ifdef MESH_DEBUG 1127 if (scb->flags & MESH_SENSE) { 1128 struct scsipi_sense_data *sp = &xs->sense.scsi_sense; 1129 printf("sense: 0x%02x 0x%02x 0x%02x\n", 1130 sp->error_code, sp->segment, sp->flags); 1131 } 1132 #endif 1133 1134 xs->xs_status |= XS_STS_DONE; 1135 1136 mesh_set_reg(sc, MESH_SYNC_PARAM, 2); 1137 1138 if ((xs->xs_control & XS_CTL_POLL) == 0) 1139 mesh_sched(sc); 1140 1141 scsipi_done(xs); 1142 mesh_free_scb(sc, scb); 1143 } 1144 1145 void 1146 mesh_timeout(arg) 1147 void *arg; 1148 { 1149 struct mesh_scb *scb = arg; 1150 struct mesh_softc *sc = scb->xs->sc_link->adapter_softc; 1151 int s; 1152 int status0, status1; 1153 int intr, error, exception; 1154 1155 printf("%s: timeout state %d\n", sc->sc_dev.dv_xname, sc->sc_nextstate); 1156 1157 intr = mesh_read_reg(sc, MESH_INTERRUPT); 1158 exception = mesh_read_reg(sc, MESH_EXCEPTION); 1159 error = mesh_read_reg(sc, MESH_ERROR); 1160 status0 = mesh_read_reg(sc, MESH_BUS_STATUS0); 1161 status1 = mesh_read_reg(sc, MESH_BUS_STATUS1); 1162 1163 s = splbio(); 1164 if (sc->sc_flags & MESH_DMA_ACTIVE) { 1165 printf("mesh: resetting dma\n"); 1166 dbdma_reset(sc->sc_dmareg); 1167 } 1168 scb->xs->error = XS_TIMEOUT; 1169 1170 mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE); 1171 sc->sc_nextstate = MESH_COMPLETE; 1172 1173 splx(s); 1174 } 1175 1176 void 1177 mesh_sense(sc, scb) 1178 struct mesh_softc *sc; 1179 struct mesh_scb *scb; 1180 { 1181 struct scsipi_xfer *xs = scb->xs; 1182 struct scsipi_link *sc_link = xs->sc_link; 1183 struct scsipi_sense *ss = (void *)&scb->cmd; 1184 1185 DPRINTF("mesh_sense\n"); 1186 bzero(ss, sizeof(*ss)); 1187 ss->opcode = REQUEST_SENSE; 1188 ss->byte2 = sc_link->scsipi_scsi.lun << 5; 1189 ss->length = sizeof(struct scsipi_sense_data); 1190 scb->cmdlen = sizeof(*ss); 1191 scb->daddr = (vaddr_t)&xs->sense.scsi_sense; 1192 scb->dlen = sizeof(struct scsipi_sense_data); 1193 scb->resid = scb->dlen; 1194 bzero((void *)scb->daddr, scb->dlen); 1195 1196 scb->flags |= MESH_SENSE | MESH_READ; 1197 1198 TAILQ_INSERT_HEAD(&sc->ready_scb, scb, chain); 1199 if (sc->sc_nexus == NULL) 1200 mesh_sched(sc); 1201 } 1202 1203 void 1204 mesh_minphys(bp) 1205 struct buf *bp; 1206 { 1207 if (bp->b_bcount > 64*1024) 1208 bp->b_bcount = 64*1024; 1209 1210 minphys(bp); 1211 } 1212