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