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