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