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