This source file includes following definitions.
- espmatch_sbus
- espattach_sbus
- espattach_dma
- espattach
- esp_read_reg
- esp_write_reg
- esp_rdreg1
- esp_wrreg1
- esp_dma_isintr
- esp_dma_reset
- esp_dma_intr
- esp_dma_setup
- esp_dma_go
- esp_dma_stop
- esp_dma_isactive
- db_esp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 #include <sys/types.h>
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/device.h>
45 #include <sys/buf.h>
46 #include <sys/malloc.h>
47
48 #include <scsi/scsi_all.h>
49 #include <scsi/scsiconf.h>
50 #include <scsi/scsi_message.h>
51
52 #include <machine/bus.h>
53 #include <machine/intr.h>
54 #include <machine/autoconf.h>
55
56 #include <dev/ic/lsi64854reg.h>
57 #include <dev/ic/lsi64854var.h>
58
59 #include <dev/ic/ncr53c9xreg.h>
60 #include <dev/ic/ncr53c9xvar.h>
61
62 #include <dev/sbus/sbusvar.h>
63
64 struct scsi_adapter esp_switch = {
65 ncr53c9x_scsi_cmd,
66 minphys,
67 NULL,
68 NULL,
69 };
70
71 struct scsi_device esp_dev = {
72 NULL,
73 NULL,
74 NULL,
75 NULL,
76 };
77
78
79
80 static int esp_unit_offset;
81
82 struct esp_softc {
83 struct ncr53c9x_softc sc_ncr53c9x;
84
85 bus_space_tag_t sc_bustag;
86 bus_dma_tag_t sc_dmatag;
87
88 bus_space_handle_t sc_reg;
89 struct lsi64854_softc *sc_dma;
90
91 int sc_pri;
92 };
93
94 void espattach_sbus(struct device *, struct device *, void *);
95 void espattach_dma(struct device *, struct device *, void *);
96 int espmatch_sbus(struct device *, void *, void *);
97
98
99
100 struct cfattach esp_sbus_ca = {
101 sizeof(struct esp_softc), espmatch_sbus, espattach_sbus
102 };
103 struct cfattach esp_dma_ca = {
104 sizeof(struct esp_softc), espmatch_sbus, espattach_dma
105 };
106
107
108
109
110 static u_char esp_read_reg(struct ncr53c9x_softc *, int);
111 static void esp_write_reg(struct ncr53c9x_softc *, int, u_char);
112 static u_char esp_rdreg1(struct ncr53c9x_softc *, int);
113 static void esp_wrreg1(struct ncr53c9x_softc *, int, u_char);
114 static int esp_dma_isintr(struct ncr53c9x_softc *);
115 static void esp_dma_reset(struct ncr53c9x_softc *);
116 static int esp_dma_intr(struct ncr53c9x_softc *);
117 static int esp_dma_setup(struct ncr53c9x_softc *, caddr_t *,
118 size_t *, int, size_t *);
119 static void esp_dma_go(struct ncr53c9x_softc *);
120 static void esp_dma_stop(struct ncr53c9x_softc *);
121 static int esp_dma_isactive(struct ncr53c9x_softc *);
122
123 static struct ncr53c9x_glue esp_sbus_glue = {
124 esp_read_reg,
125 esp_write_reg,
126 esp_dma_isintr,
127 esp_dma_reset,
128 esp_dma_intr,
129 esp_dma_setup,
130 esp_dma_go,
131 esp_dma_stop,
132 esp_dma_isactive,
133 NULL,
134 };
135
136 static struct ncr53c9x_glue esp_sbus_glue1 = {
137 esp_rdreg1,
138 esp_wrreg1,
139 esp_dma_isintr,
140 esp_dma_reset,
141 esp_dma_intr,
142 esp_dma_setup,
143 esp_dma_go,
144 esp_dma_stop,
145 esp_dma_isactive,
146 NULL,
147 };
148
149 static void espattach(struct esp_softc *, struct ncr53c9x_glue *);
150
151 int
152 espmatch_sbus(struct device *parent, void *vcf, void *aux)
153 {
154 struct cfdata *cf = vcf;
155 int rv;
156 struct sbus_attach_args *sa = aux;
157
158 if (strcmp("SUNW,fas", sa->sa_name) == 0)
159 return 1;
160
161 rv = (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0 ||
162 strcmp("ptscII", sa->sa_name) == 0);
163 return (rv);
164 }
165
166 void
167 espattach_sbus(struct device *parent, struct device *self, void *aux)
168 {
169 struct esp_softc *esc = (void *)self;
170 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
171 struct sbus_attach_args *sa = aux;
172 struct lsi64854_softc *lsc;
173 int burst, sbusburst;
174
175 esc->sc_bustag = sa->sa_bustag;
176 esc->sc_dmatag = sa->sa_dmatag;
177
178 sc->sc_id = getpropint(sa->sa_node, "initiator-id", 7);
179 sc->sc_freq = getpropint(sa->sa_node, "clock-frequency", -1);
180 if (sc->sc_freq < 0)
181 sc->sc_freq = sa->sa_frequency;
182
183 #ifdef ESP_SBUS_DEBUG
184 printf("%s: espattach_sbus: sc_id %d, freq %d\n",
185 self->dv_xname, sc->sc_id, sc->sc_freq);
186 #endif
187
188 if (strcmp("SUNW,fas", sa->sa_name) == 0) {
189
190
191
192 esp_unit_offset++;
193
194
195
196
197 if (sa->sa_nreg != 2) {
198 printf("%s: %d register spaces\n", self->dv_xname, sa->sa_nreg);
199 return;
200 }
201
202
203
204
205
206 lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF, M_NOWAIT);
207
208 if (lsc == NULL) {
209 printf("%s: out of memory (lsi64854_softc)\n",
210 self->dv_xname);
211 return;
212 }
213 esc->sc_dma = lsc;
214
215 lsc->sc_bustag = sa->sa_bustag;
216 lsc->sc_dmatag = sa->sa_dmatag;
217
218 bcopy(sc->sc_dev.dv_xname, lsc->sc_dev.dv_xname,
219 sizeof (lsc->sc_dev.dv_xname));
220
221
222 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
223 sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size,
224 0, 0, &lsc->sc_regs) != 0) {
225 printf("%s: cannot map dma registers\n", self->dv_xname);
226 return;
227 }
228
229
230
231
232
233
234
235
236 sbusburst = ((struct sbus_softc *)parent)->sc_burst;
237 if (sbusburst == 0)
238 sbusburst = SBUS_BURST_32 - 1;
239
240 burst = getpropint(sa->sa_node, "burst-sizes", -1);
241
242 #ifdef ESP_SBUS_DEBUG
243 printf("espattach_sbus: burst 0x%x, sbus 0x%x\n",
244 burst, sbusburst);
245 #endif
246
247 if (burst == -1)
248
249 burst = sbusburst;
250
251
252 burst &= sbusburst;
253 lsc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
254 (burst & SBUS_BURST_16) ? 16 : 0;
255
256 lsc->sc_channel = L64854_CHANNEL_SCSI;
257 lsc->sc_client = sc;
258
259 lsi64854_attach(lsc);
260
261
262
263
264 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[1].sbr_slot,
265 sa->sa_reg[1].sbr_offset, sa->sa_reg[1].sbr_size,
266 0, 0, &esc->sc_reg) != 0) {
267 printf("%s: cannot map scsi core registers\n",
268 self->dv_xname);
269 return;
270 }
271
272 if (sa->sa_nintr == 0) {
273 printf("%s: no interrupt property\n", self->dv_xname);
274 return;
275 }
276
277 esc->sc_pri = sa->sa_pri;
278
279 printf("%s", self->dv_xname);
280 espattach(esc, &esp_sbus_glue);
281
282 return;
283 }
284
285
286
287
288
289
290
291
292
293
294 esc->sc_dma = (struct lsi64854_softc *)
295 getdevunit("dma", sc->sc_dev.dv_unit - esp_unit_offset);
296
297
298
299
300 if (esc->sc_dma)
301 esc->sc_dma->sc_client = sc;
302 else {
303 printf("\n");
304 panic("espattach: no dma found");
305 }
306
307
308
309
310
311 if (esc->sc_dma->sc_rev == DMAREV_ESC)
312 DMA_RESET(esc->sc_dma);
313
314
315
316
317
318 if (sa->sa_npromvaddrs) {
319 if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0],
320 sa->sa_size, BUS_SPACE_MAP_PROMADDRESS,
321 &esc->sc_reg) != 0) {
322 printf("%s @ sbus: cannot map registers\n",
323 self->dv_xname);
324 return;
325 }
326 } else {
327 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
328 sa->sa_offset, sa->sa_size, 0, 0, &esc->sc_reg) != 0) {
329 printf("%s @ sbus: cannot map registers\n",
330 self->dv_xname);
331 return;
332 }
333 }
334
335 if (sa->sa_nintr == 0) {
336
337
338
339
340 printf("\n%s: no interrupt property\n", self->dv_xname);
341 return;
342 }
343
344 esc->sc_pri = sa->sa_pri;
345
346 if (strcmp("ptscII", sa->sa_name) == 0) {
347 espattach(esc, &esp_sbus_glue1);
348 } else {
349 espattach(esc, &esp_sbus_glue);
350 }
351 }
352
353 void
354 espattach_dma(struct device *parent, struct device *self, void *aux)
355 {
356 struct esp_softc *esc = (void *)self;
357 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
358 struct sbus_attach_args *sa = aux;
359
360 if (strcmp("ptscII", sa->sa_name) == 0) {
361 return;
362 }
363
364 esc->sc_bustag = sa->sa_bustag;
365 esc->sc_dmatag = sa->sa_dmatag;
366
367 sc->sc_id = getpropint(sa->sa_node, "initiator-id", 7);
368 sc->sc_freq = getpropint(sa->sa_node, "clock-frequency", -1);
369
370 esc->sc_dma = (struct lsi64854_softc *)parent;
371 esc->sc_dma->sc_client = sc;
372
373
374
375
376
377 if (sa->sa_npromvaddrs) {
378 if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0],
379 sa->sa_size , BUS_SPACE_MAP_PROMADDRESS,
380 &esc->sc_reg) != 0) {
381 printf("%s @ dma: cannot map registers\n",
382 self->dv_xname);
383 return;
384 }
385 } else {
386 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset,
387 sa->sa_size, 0, 0, &esc->sc_reg) != 0) {
388 printf("%s @ dma: cannot map registers\n",
389 self->dv_xname);
390 return;
391 }
392 }
393
394 if (sa->sa_nintr == 0) {
395
396
397
398
399 printf("\n%s: no interrupt property\n", self->dv_xname);
400 return;
401 }
402
403 esc->sc_pri = sa->sa_pri;
404
405 espattach(esc, &esp_sbus_glue);
406 }
407
408
409
410
411
412 void
413 espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
414 {
415 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
416 void *icookie;
417 unsigned int uid = 0;
418
419
420
421
422 sc->sc_glue = gluep;
423
424
425 sc->sc_freq /= 1000000;
426
427
428
429
430
431
432
433
434
435
436
437
438 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
439 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
440 sc->sc_cfg3 = NCRCFG3_CDB;
441 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
442
443 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
444 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
445 sc->sc_rev = NCR_VARIANT_ESP100;
446 } else {
447 sc->sc_cfg2 = NCRCFG2_SCSI2;
448 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
449 sc->sc_cfg3 = 0;
450 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
451 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
452 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
453 if (NCR_READ_REG(sc, NCR_CFG3) !=
454 (NCRCFG3_CDB | NCRCFG3_FCLK)) {
455 sc->sc_rev = NCR_VARIANT_ESP100A;
456 } else {
457
458 sc->sc_cfg2 |= NCRCFG2_FE;
459 sc->sc_cfg3 = 0;
460 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
461 sc->sc_rev = NCR_VARIANT_ESP200;
462
463
464 uid = NCR_READ_REG(sc, NCR_UID);
465 if (((uid & 0xf8) >> 3) == 0x0a)
466 sc->sc_rev = NCR_VARIANT_FAS366;
467 }
468 }
469
470 #ifdef ESP_SBUS_DEBUG
471 printf("espattach: revision %d, uid 0x%x\n", sc->sc_rev, uid);
472 #endif
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489 sc->sc_minsync = 1000 / sc->sc_freq;
490
491
492
493
494
495
496 switch (sc->sc_rev) {
497 case NCR_VARIANT_ESP100:
498 sc->sc_maxxfer = 64 * 1024;
499 sc->sc_minsync = 0;
500 break;
501
502 case NCR_VARIANT_ESP100A:
503 sc->sc_maxxfer = 64 * 1024;
504
505 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
506 break;
507
508 case NCR_VARIANT_ESP200:
509 case NCR_VARIANT_FAS366:
510 sc->sc_maxxfer = 16 * 1024 * 1024;
511
512 break;
513 }
514
515
516 icookie = bus_intr_establish(esc->sc_bustag, esc->sc_pri, IPL_BIO, 0,
517 ncr53c9x_intr, sc, sc->sc_dev.dv_xname);
518
519
520 if (sc->sc_rev != NCR_VARIANT_FAS366)
521 sc->sc_features |= NCR_F_DMASELECT;
522
523
524 ncr53c9x_attach(sc, &esp_switch, &esp_dev);
525 }
526
527
528
529
530
531 #ifdef ESP_SBUS_DEBUG
532 int esp_sbus_debug = 0;
533
534 static struct {
535 char *r_name;
536 int r_flag;
537 } esp__read_regnames [] = {
538 { "TCL", 0},
539 { "TCM", 0},
540 { "FIFO", 0},
541 { "CMD", 0},
542 { "STAT", 0},
543 { "INTR", 0},
544 { "STEP", 0},
545 { "FFLAGS", 1},
546 { "CFG1", 1},
547 { "STAT2", 0},
548 { "CFG4", 1},
549 { "CFG2", 1},
550 { "CFG3", 1},
551 { "-none", 1},
552 { "TCH", 1},
553 { "TCX", 1},
554 };
555
556 static struct {
557 char *r_name;
558 int r_flag;
559 } esp__write_regnames[] = {
560 { "TCL", 1},
561 { "TCM", 1},
562 { "FIFO", 0},
563 { "CMD", 0},
564 { "SELID", 1},
565 { "TIMEOUT", 1},
566 { "SYNCTP", 1},
567 { "SYNCOFF", 1},
568 { "CFG1", 1},
569 { "CCF", 1},
570 { "TEST", 1},
571 { "CFG2", 1},
572 { "CFG3", 1},
573 { "-none", 1},
574 { "TCH", 1},
575 { "TCX", 1},
576 };
577 #endif
578
579 u_char
580 esp_read_reg(struct ncr53c9x_softc *sc, int reg)
581 {
582 struct esp_softc *esc = (struct esp_softc *)sc;
583 u_char v;
584
585 v = bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg * 4);
586 #ifdef ESP_SBUS_DEBUG
587 if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag)
588 printf("RD:%x <%s> %x\n", reg * 4,
589 ((unsigned)reg < 0x10) ? esp__read_regnames[reg].r_name : "<***>", v);
590 #endif
591 return v;
592 }
593
594 void
595 esp_write_reg(struct ncr53c9x_softc *sc, int reg, u_char v)
596 {
597 struct esp_softc *esc = (struct esp_softc *)sc;
598
599 #ifdef ESP_SBUS_DEBUG
600 if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag)
601 printf("WR:%x <%s> %x\n", reg * 4,
602 ((unsigned)reg < 0x10) ? esp__write_regnames[reg].r_name : "<***>", v);
603 #endif
604 bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg * 4, v);
605 }
606
607 u_char
608 esp_rdreg1(struct ncr53c9x_softc *sc, int reg)
609 {
610 struct esp_softc *esc = (struct esp_softc *)sc;
611
612 return (bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg));
613 }
614
615 void
616 esp_wrreg1(struct ncr53c9x_softc *sc, int reg, u_char v)
617 {
618 struct esp_softc *esc = (struct esp_softc *)sc;
619
620 bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg, v);
621 }
622
623 int
624 esp_dma_isintr(struct ncr53c9x_softc *sc)
625 {
626 struct esp_softc *esc = (struct esp_softc *)sc;
627
628 return (DMA_ISINTR(esc->sc_dma));
629 }
630
631 void
632 esp_dma_reset(struct ncr53c9x_softc *sc)
633 {
634 struct esp_softc *esc = (struct esp_softc *)sc;
635
636 DMA_RESET(esc->sc_dma);
637 }
638
639 int
640 esp_dma_intr(struct ncr53c9x_softc *sc)
641 {
642 struct esp_softc *esc = (struct esp_softc *)sc;
643
644 return (DMA_INTR(esc->sc_dma));
645 }
646
647 int
648 esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len,
649 int datain, size_t *dmasize)
650 {
651 struct esp_softc *esc = (struct esp_softc *)sc;
652
653 return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
654 }
655
656 void
657 esp_dma_go(struct ncr53c9x_softc *sc)
658 {
659 struct esp_softc *esc = (struct esp_softc *)sc;
660
661 DMA_GO(esc->sc_dma);
662 }
663
664 void
665 esp_dma_stop(struct ncr53c9x_softc *sc)
666 {
667 struct esp_softc *esc = (struct esp_softc *)sc;
668 u_int32_t csr;
669
670 csr = L64854_GCSR(esc->sc_dma);
671 csr &= ~D_EN_DMA;
672 L64854_SCSR(esc->sc_dma, csr);
673 }
674
675 int
676 esp_dma_isactive(struct ncr53c9x_softc *sc)
677 {
678 struct esp_softc *esc = (struct esp_softc *)sc;
679
680 return (DMA_ISACTIVE(esc->sc_dma));
681 }
682
683 #if defined(DDB) && defined(notyet)
684 #include <machine/db_machdep.h>
685 #include <ddb/db_output.h>
686
687 void db_esp(db_expr_t, int, db_expr_t, char *);
688
689 void
690 db_esp(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
691 {
692 struct ncr53c9x_softc *sc;
693 struct ncr53c9x_ecb *ecb;
694 struct ncr53c9x_linfo *li;
695 int u, t, i;
696
697 for (u=0; u<10; u++) {
698 sc = (struct ncr53c9x_softc *)
699 getdevunit("esp", u);
700 if (!sc) continue;
701
702 db_printf("esp%d: nexus %p phase %x prev %x dp %p dleft %lx ify %x\n",
703 u, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
704 sc->sc_dp, sc->sc_dleft, sc->sc_msgify);
705 db_printf("\tmsgout %x msgpriq %x msgin %x:%x:%x:%x:%x\n",
706 sc->sc_msgout, sc->sc_msgpriq, sc->sc_imess[0],
707 sc->sc_imess[1], sc->sc_imess[2], sc->sc_imess[3],
708 sc->sc_imess[0]);
709 db_printf("ready: ");
710 TAILQ_FOREACH(ecb, &sc->ready_list, chain) {
711 db_printf("ecb %p ", ecb);
712 if (ecb == TAILQ_NEXT(ecb, chain)) {
713 db_printf("\nWARNING: tailq loop on ecb %p", ecb);
714 break;
715 }
716 }
717 db_printf("\n");
718
719 for (t=0; t<NCR_NTARG; t++) {
720 LIST_FOREACH(li, &sc->sc_tinfo[t].luns, link) {
721 db_printf("t%d lun %d untagged %p busy %d used %x\n",
722 t, (int)li->lun, li->untagged, li->busy,
723 li->used);
724 for (i=0; i<256; i++)
725 if ((ecb = li->queued[i])) {
726 db_printf("ecb %p tag %x\n", ecb, i);
727 }
728 }
729 }
730 }
731 }
732 #endif
733