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