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