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