Home | History | Annotate | Line # | Download | only in dev
mesh.c revision 1.3
      1 /*	$NetBSD: mesh.c,v 1.3 1999/12/28 13:49:20 tsubai 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 <vm/vm.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 	timeout(mesh_timeout, scb, 10*hz);
    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 	untimeout(mesh_timeout, scb);
   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