mesh.c revision 1.3 1 /* $NetBSD: mesh.c,v 1.3 1999/12/28 13:49:20 tsubai 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 timeout(mesh_timeout, scb, 10*hz);
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 untimeout(mesh_timeout, scb);
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