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