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