Home | History | Annotate | Line # | Download | only in dev
      1 /*	$NetBSD: mesh.c,v 1.44 2023/12/20 15:29:04 thorpej 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.44 2023/12/20 15:29:04 thorpej 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/queue.h>
     44 #include <sys/systm.h>
     45 
     46 #include <uvm/uvm_extern.h>
     47 
     48 #include <dev/scsipi/scsi_all.h>
     49 #include <dev/scsipi/scsipi_all.h>
     50 #include <dev/scsipi/scsiconf.h>
     51 #include <dev/scsipi/scsi_message.h>
     52 
     53 #include <dev/ofw/openfirm.h>
     54 
     55 #include <machine/autoconf.h>
     56 #include <machine/cpu.h>
     57 #include <machine/pio.h>
     58 
     59 #include <macppc/dev/dbdma.h>
     60 #include <macppc/dev/meshreg.h>
     61 
     62 #ifdef MESH_DEBUG
     63 # define DPRINTF printf
     64 #else
     65 # define DPRINTF while (0) printf
     66 #endif
     67 
     68 #define T_SYNCMODE 0x01		/* target uses sync mode */
     69 #define T_SYNCNEGO 0x02		/* sync negotiation done */
     70 
     71 struct mesh_tinfo {
     72 	int flags;
     73 	int period;
     74 	int offset;
     75 };
     76 
     77 /* scb flags */
     78 #define MESH_POLL	0x01
     79 #define MESH_CHECK	0x02
     80 #define MESH_READ	0x80
     81 
     82 struct mesh_scb {
     83 	TAILQ_ENTRY(mesh_scb) chain;
     84 	int flags;
     85 	struct scsipi_xfer *xs;
     86 	struct scsipi_generic cmd;
     87 	int cmdlen;
     88 	int target;			/* target SCSI ID */
     89 	int resid;
     90 	vaddr_t daddr;
     91 	vsize_t dlen;
     92 	int status;
     93 };
     94 
     95 /* sc_flags value */
     96 #define MESH_DMA_ACTIVE	0x01
     97 
     98 struct mesh_softc {
     99 	device_t sc_dev;		/* us as a device */
    100 	struct scsipi_channel sc_channel;
    101 	struct scsipi_adapter sc_adapter;
    102 
    103 	u_char *sc_reg;			/* MESH base address */
    104 	dbdma_regmap_t *sc_dmareg;	/* DMA register address */
    105 	dbdma_command_t *sc_dmacmd;	/* DMA command area */
    106 
    107 	int sc_flags;
    108 	int sc_cfflags;			/* copy of config flags */
    109 	int sc_meshid;			/* MESH version */
    110 	int sc_minsync;			/* minimum sync period */
    111 	int sc_irq;
    112 	int sc_freq;			/* SCSI bus frequency in MHz */
    113 	int sc_id;			/* our SCSI ID */
    114 	struct mesh_tinfo sc_tinfo[8];	/* target information */
    115 
    116 	int sc_nextstate;
    117 	int sc_prevphase;
    118 	struct mesh_scb *sc_nexus;	/* current command */
    119 
    120 	int sc_msgout;
    121 	int sc_imsglen;
    122 	u_char sc_imsg[16];
    123 	u_char sc_omsg[16];
    124 
    125 	TAILQ_HEAD(, mesh_scb) free_scb;
    126 	TAILQ_HEAD(, mesh_scb) ready_scb;
    127 	struct mesh_scb sc_scb[16];
    128 };
    129 
    130 /* mesh_msgout() values */
    131 #define SEND_REJECT	1
    132 #define SEND_IDENTIFY	2
    133 #define SEND_SDTR	4
    134 
    135 static inline int mesh_read_reg(struct mesh_softc *, int);
    136 static inline void mesh_set_reg(struct mesh_softc *, int, int);
    137 
    138 static int mesh_match(device_t, cfdata_t, void *);
    139 static void mesh_attach(device_t, device_t, void *);
    140 static bool mesh_shutdown(device_t, int);
    141 static int mesh_intr(void *);
    142 static void mesh_error(struct mesh_softc *, struct mesh_scb *, int, int);
    143 static void mesh_select(struct mesh_softc *, struct mesh_scb *);
    144 static void mesh_identify(struct mesh_softc *, struct mesh_scb *);
    145 static void mesh_command(struct mesh_softc *, struct mesh_scb *);
    146 static void mesh_dma_setup(struct mesh_softc *, struct mesh_scb *);
    147 static void mesh_dataio(struct mesh_softc *, struct mesh_scb *);
    148 static void mesh_status(struct mesh_softc *, struct mesh_scb *);
    149 static void mesh_msgin(struct mesh_softc *, struct mesh_scb *);
    150 static void mesh_msgout(struct mesh_softc *, int);
    151 static void mesh_bus_reset(struct mesh_softc *);
    152 static void mesh_reset(struct mesh_softc *);
    153 static int mesh_stp(struct mesh_softc *, int);
    154 static void mesh_setsync(struct mesh_softc *, struct mesh_tinfo *);
    155 static struct mesh_scb *mesh_get_scb(struct mesh_softc *);
    156 static void mesh_free_scb(struct mesh_softc *, struct mesh_scb *);
    157 static void mesh_scsi_request(struct scsipi_channel *,
    158 				scsipi_adapter_req_t, void *);
    159 static void mesh_sched(struct mesh_softc *);
    160 static int mesh_poll(struct mesh_softc *, struct scsipi_xfer *);
    161 static void mesh_done(struct mesh_softc *, struct mesh_scb *);
    162 static void mesh_timeout(void *);
    163 static void mesh_minphys(struct buf *);
    164 
    165 
    166 #define MESH_DATAOUT	0
    167 #define MESH_DATAIN	MESH_STATUS0_IO
    168 #define MESH_COMMAND	MESH_STATUS0_CD
    169 #define MESH_STATUS	(MESH_STATUS0_CD | MESH_STATUS0_IO)
    170 #define MESH_MSGOUT	(MESH_STATUS0_MSG | MESH_STATUS0_CD)
    171 #define MESH_MSGIN	(MESH_STATUS0_MSG | MESH_STATUS0_CD | MESH_STATUS0_IO)
    172 
    173 #define MESH_SELECTING	8
    174 #define MESH_IDENTIFY	9
    175 #define MESH_COMPLETE	10
    176 #define MESH_BUSFREE	11
    177 #define MESH_UNKNOWN	-1
    178 
    179 #define MESH_PHASE_MASK	(MESH_STATUS0_MSG | MESH_STATUS0_CD | MESH_STATUS0_IO)
    180 
    181 CFATTACH_DECL_NEW(mesh, sizeof(struct mesh_softc),
    182     mesh_match, mesh_attach, NULL, NULL);
    183 
    184 int
    185 mesh_match(device_t parent, cfdata_t cf, void *aux)
    186 {
    187 	struct confargs *ca = aux;
    188 	char compat[32];
    189 
    190 	if (strcmp(ca->ca_name, "mesh") == 0)
    191 		return 1;
    192 
    193 	memset(compat, 0, sizeof(compat));
    194 	OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat));
    195 	if (strcmp(compat, "chrp,mesh0") == 0)
    196 		return 1;
    197 
    198 	return 0;
    199 }
    200 
    201 void
    202 mesh_attach(device_t parent, device_t self, void *aux)
    203 {
    204 	struct mesh_softc *sc = device_private(self);
    205 	struct confargs *ca = aux;
    206 	int i;
    207 	u_int *reg;
    208 
    209 	sc->sc_dev = self;
    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], false);
    214 	sc->sc_irq = ca->ca_intr[0];
    215 	sc->sc_dmareg = mapiodev(reg[2], reg[3], false);
    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, NULL);
    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, CFARGS_NONE);
    262 
    263 	intr_establish_xname(sc->sc_irq, IST_EDGE, IPL_BIO, mesh_intr, sc,
    264 	    device_xname(self));
    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;
    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 	(void)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 = %s (%s), exc = %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 (int 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 mesh_scb *scb;
   1042 
   1043 	scb = sc->ready_scb.tqh_first;
   1044 start:
   1045 	if (scb == NULL)
   1046 		return;
   1047 
   1048 	if (sc->sc_nexus == NULL) {
   1049 		TAILQ_REMOVE(&sc->ready_scb, scb, chain);
   1050 		sc->sc_nexus = scb;
   1051 		mesh_select(sc, scb);
   1052 		return;
   1053 	}
   1054 
   1055 	scb = scb->chain.tqe_next;
   1056 	goto start;
   1057 }
   1058 
   1059 int
   1060 mesh_poll(struct mesh_softc *sc, struct scsipi_xfer *xs)
   1061 {
   1062 	int count = xs->timeout;
   1063 
   1064 	while (count) {
   1065 		if (mesh_read_reg(sc, MESH_INTERRUPT))
   1066 			mesh_intr(sc);
   1067 
   1068 		if (xs->xs_status & XS_STS_DONE)
   1069 			return 0;
   1070 		delay(1000);
   1071 		count--;
   1072 	};
   1073 	return 1;
   1074 }
   1075 
   1076 void
   1077 mesh_done(struct mesh_softc *sc, struct mesh_scb *scb)
   1078 {
   1079 	struct scsipi_xfer *xs = scb->xs;
   1080 
   1081 	DPRINTF("mesh_done\n");
   1082 
   1083 	sc->sc_nextstate = MESH_BUSFREE;
   1084 	sc->sc_nexus = NULL;
   1085 
   1086 	callout_stop(&scb->xs->xs_callout);
   1087 
   1088 	if (scb->status == SCSI_BUSY) {
   1089 		xs->error = XS_BUSY;
   1090 		printf("Target busy\n");
   1091 	}
   1092 
   1093 	xs->status = scb->status;
   1094 	xs->resid = scb->resid;
   1095 	if (scb->status == SCSI_CHECK) {
   1096 		xs->error = XS_BUSY;
   1097 	}
   1098 
   1099 	mesh_set_reg(sc, MESH_SYNC_PARAM, 2);
   1100 
   1101 	if ((xs->xs_control & XS_CTL_POLL) == 0)
   1102 		mesh_sched(sc);
   1103 
   1104 	scsipi_done(xs);
   1105 	mesh_free_scb(sc, scb);
   1106 }
   1107 
   1108 void
   1109 mesh_timeout(void *arg)
   1110 {
   1111 	struct mesh_scb *scb = arg;
   1112 	struct mesh_softc *sc =
   1113 	    device_private(scb->xs->xs_periph->periph_channel->chan_adapter->adapt_dev);
   1114 	int s;
   1115 	int status0, status1;
   1116 	int intr, error, exception, imsk;
   1117 
   1118 	printf("%s: timeout state %d\n", device_xname(sc->sc_dev),
   1119 	    sc->sc_nextstate);
   1120 
   1121 	intr = mesh_read_reg(sc, MESH_INTERRUPT);
   1122 	imsk = mesh_read_reg(sc, MESH_INTR_MASK);
   1123 	exception = mesh_read_reg(sc, MESH_EXCEPTION);
   1124 	error = mesh_read_reg(sc, MESH_ERROR);
   1125 	status0 = mesh_read_reg(sc, MESH_BUS_STATUS0);
   1126 	status1 = mesh_read_reg(sc, MESH_BUS_STATUS1);
   1127 
   1128 	printf("%s: intr/msk %02x/%02x, exc %02x, err %02x, st0/1 %02x/%02x\n",
   1129 		device_xname(sc->sc_dev),
   1130 		intr, imsk, exception, error, status0, status1);
   1131 
   1132 	s = splbio();
   1133 	if (sc->sc_flags & MESH_DMA_ACTIVE) {
   1134 		printf("mesh: resetting DMA\n");
   1135 		dbdma_reset(sc->sc_dmareg);
   1136 	}
   1137 	scb->xs->error = XS_TIMEOUT;
   1138 
   1139 	mesh_set_reg(sc, MESH_SEQUENCE, MESH_CMD_BUSFREE);
   1140 	sc->sc_nextstate = MESH_COMPLETE;
   1141 
   1142 	splx(s);
   1143 }
   1144 
   1145 void
   1146 mesh_minphys(struct buf *bp)
   1147 {
   1148 	if (bp->b_bcount > 64*1024)
   1149 		bp->b_bcount = 64*1024;
   1150 
   1151 	minphys(bp);
   1152 }
   1153