This source file includes following definitions.
- tcds_lookup
- tcdsmatch
- tcdsattach
- tcdssubmatch
- tcdsprint
- tcds_intr_establish
- tcds_intr_disestablish
- tcds_intrnull
- tcds_scsi_reset
- tcds_scsi_enable
- tcds_dma_enable
- tcds_scsi_isintr
- tcds_scsi_iserr
- tcds_intr
- tcds_params
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 #include <sys/param.h>
69 #include <sys/kernel.h>
70 #include <sys/systm.h>
71 #include <sys/device.h>
72 #include <sys/malloc.h>
73
74 #ifdef __alpha__
75 #include <machine/rpb.h>
76 #endif
77
78 #include <scsi/scsi_all.h>
79 #include <scsi/scsiconf.h>
80
81 #include <dev/ic/ncr53c9xvar.h>
82
83 #include <machine/bus.h>
84
85 #include <dev/tc/tcvar.h>
86 #include <dev/tc/tcdsreg.h>
87 #include <dev/tc/tcdsvar.h>
88
89 struct tcds_softc {
90 struct device sc_dv;
91 bus_space_tag_t sc_bst;
92 bus_space_handle_t sc_bsh;
93 bus_dma_tag_t sc_dmat;
94 void *sc_cookie;
95 int sc_flags;
96 struct tcds_slotconfig sc_slots[2];
97 };
98
99
100 #define TCDSF_BASEBOARD 0x01
101 #define TCDSF_FASTSCSI 0x02
102
103
104 int tcdsmatch(struct device *, void *, void *);
105 void tcdsattach(struct device *, struct device *, void *);
106 int tcdsprint(void *, const char *);
107 int tcdssubmatch(struct device *, void *, void *);
108
109 struct cfattach tcds_ca = {
110 sizeof(struct tcds_softc), tcdsmatch, tcdsattach,
111 };
112
113 struct cfdriver tcds_cd = {
114 NULL, "tcds", DV_DULL,
115 };
116
117 int tcds_intr(void *);
118 int tcds_intrnull(void *);
119
120 struct tcds_device {
121 const char *td_name;
122 int td_flags;
123 } tcds_devices[] = {
124 #ifdef __alpha__
125 { "PMAZ-DS ", TCDSF_BASEBOARD },
126 { "PMAZ-FS ", TCDSF_BASEBOARD|TCDSF_FASTSCSI },
127 #endif
128 { "PMAZB-AA", 0 },
129 { "PMAZC-AA", TCDSF_FASTSCSI },
130 { NULL, 0 },
131 };
132
133 struct tcds_device *tcds_lookup(const char *);
134 void tcds_params(struct tcds_softc *, int, int *, int *);
135
136 struct tcds_device *
137 tcds_lookup(modname)
138 const char *modname;
139 {
140 struct tcds_device *td;
141
142 for (td = tcds_devices; td->td_name != NULL; td++)
143 if (strncmp(td->td_name, modname, TC_ROM_LLEN) == 0)
144 return (td);
145
146 return (NULL);
147 }
148
149 int
150 tcdsmatch(parent, cfdata, aux)
151 struct device *parent;
152 void *cfdata, *aux;
153 {
154 struct tc_attach_args *ta = aux;
155
156 return (tcds_lookup(ta->ta_modname) != NULL);
157 }
158
159 void
160 tcdsattach(parent, self, aux)
161 struct device *parent, *self;
162 void *aux;
163 {
164 struct tcds_softc *sc = (struct tcds_softc *)self;
165 struct tc_attach_args *ta = aux;
166 struct tcdsdev_attach_args tcdsdev;
167 struct tcds_slotconfig *slotc;
168 struct tcds_device *td;
169 bus_space_handle_t sbsh[2];
170 int i, gpi2;
171
172 td = tcds_lookup(ta->ta_modname);
173 if (td == NULL)
174 panic("tcdsattach: impossible");
175
176 printf(": TurboChannel Dual SCSI");
177 if (td->td_flags & TCDSF_BASEBOARD)
178 printf(" (baseboard)");
179 printf("\n");
180
181 sc->sc_flags = td->td_flags;
182
183 sc->sc_bst = ta->ta_memt;
184 sc->sc_dmat = ta->ta_dmat;
185
186
187
188
189 if (bus_space_map(sc->sc_bst, ta->ta_addr,
190 (TCDS_SCSI1_OFFSET + 0x100), 0, &sc->sc_bsh)) {
191 printf("%s: unable to map device\n", sc->sc_dv.dv_xname);
192 return;
193 }
194
195
196
197
198 if (bus_space_subregion(sc->sc_bst, sc->sc_bsh, TCDS_SCSI0_OFFSET,
199 0x100, &sbsh[0]) ||
200 bus_space_subregion(sc->sc_bst, sc->sc_bsh, TCDS_SCSI1_OFFSET,
201 0x100, &sbsh[1])) {
202 printf("%s: unable to subregion SCSI chip space\n",
203 sc->sc_dv.dv_xname);
204 return;
205 }
206
207 sc->sc_cookie = ta->ta_cookie;
208
209 tc_intr_establish(parent, sc->sc_cookie, TC_IPL_BIO, tcds_intr, sc);
210
211
212
213
214
215
216 bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_IMER, 0);
217
218
219
220
221
222
223 gpi2 = (bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR) &
224 TCDS_CIR_GPI_2) != 0;
225
226
227
228
229
230
231 for (i = 0; i < 2; i++) {
232 slotc = &sc->sc_slots[i];
233 bzero(slotc, sizeof *slotc);
234
235 evcount_attach(&slotc->sc_count, sc->sc_dv.dv_xname, NULL,
236 &evcount_intr);
237
238 slotc->sc_slot = i;
239 slotc->sc_bst = sc->sc_bst;
240 slotc->sc_bsh = sc->sc_bsh;
241 slotc->sc_intrhand = tcds_intrnull;
242 slotc->sc_intrarg = (void *)(long)i;
243 }
244
245
246 slotc = &sc->sc_slots[0];
247 slotc->sc_resetbits = TCDS_CIR_SCSI0_RESET;
248 slotc->sc_intrmaskbits =
249 TCDS_IMER_SCSI0_MASK | TCDS_IMER_SCSI0_ENB;
250 slotc->sc_intrbits = TCDS_CIR_SCSI0_INT;
251 slotc->sc_dmabits = TCDS_CIR_SCSI0_DMAENA;
252 slotc->sc_errorbits = 0;
253 slotc->sc_sda = TCDS_SCSI0_DMA_ADDR;
254 slotc->sc_dic = TCDS_SCSI0_DMA_INTR;
255 slotc->sc_dud0 = TCDS_SCSI0_DMA_DUD0;
256 slotc->sc_dud1 = TCDS_SCSI0_DMA_DUD1;
257
258
259 slotc = &sc->sc_slots[1];
260 slotc->sc_resetbits = TCDS_CIR_SCSI1_RESET;
261 slotc->sc_intrmaskbits =
262 TCDS_IMER_SCSI1_MASK | TCDS_IMER_SCSI1_ENB;
263 slotc->sc_intrbits = TCDS_CIR_SCSI1_INT;
264 slotc->sc_dmabits = TCDS_CIR_SCSI1_DMAENA;
265 slotc->sc_errorbits = 0;
266 slotc->sc_sda = TCDS_SCSI1_DMA_ADDR;
267 slotc->sc_dic = TCDS_SCSI1_DMA_INTR;
268 slotc->sc_dud0 = TCDS_SCSI1_DMA_DUD0;
269 slotc->sc_dud1 = TCDS_SCSI1_DMA_DUD1;
270
271
272 for (i = 0; i < 2; i++) {
273 tcds_params(sc, i, &tcdsdev.tcdsda_id,
274 &tcdsdev.tcdsda_fast);
275
276 tcdsdev.tcdsda_bst = sc->sc_bst;
277 tcdsdev.tcdsda_bsh = sbsh[i];
278 tcdsdev.tcdsda_dmat = sc->sc_dmat;
279 tcdsdev.tcdsda_chip = i;
280 tcdsdev.tcdsda_sc = &sc->sc_slots[i];
281
282
283
284
285
286 if ((sc->sc_flags & TCDSF_BASEBOARD && gpi2 == 0) ||
287 sc->sc_flags & TCDSF_FASTSCSI) {
288 tcdsdev.tcdsda_freq = 40000000;
289 tcdsdev.tcdsda_period = tcdsdev.tcdsda_fast ? 4 : 8;
290 } else {
291 tcdsdev.tcdsda_freq = 25000000;
292 tcdsdev.tcdsda_period = 5;
293 }
294 if (sc->sc_flags & TCDSF_BASEBOARD)
295 tcdsdev.tcdsda_variant = NCR_VARIANT_NCR53C94;
296 else
297 tcdsdev.tcdsda_variant = NCR_VARIANT_NCR53C96;
298
299 tcds_scsi_reset(tcdsdev.tcdsda_sc);
300
301 config_found_sm(self, &tcdsdev, tcdsprint, tcdssubmatch);
302 #ifdef __alpha__
303
304
305
306
307 if (sc->sc_flags & TCDSF_BASEBOARD &&
308 cputype == ST_DEC_3000_300)
309 break;
310 #endif
311 }
312 }
313
314 int
315 tcdssubmatch(parent, vcf, aux)
316 struct device *parent;
317 void *vcf, *aux;
318 {
319 struct tcdsdev_attach_args *tcdsdev = aux;
320 struct cfdata *cf = vcf;
321
322 if (cf->cf_loc[0] != -1 &&
323 cf->cf_loc[0] != tcdsdev->tcdsda_chip)
324 return (0);
325
326 return ((*cf->cf_attach->ca_match)(parent, vcf, aux));
327 }
328
329 int
330 tcdsprint(aux, pnp)
331 void *aux;
332 const char *pnp;
333 {
334 struct tcdsdev_attach_args *tcdsdev = aux;
335
336
337 if (pnp)
338 printf("asc at %s", pnp);
339
340 printf(" chip %d", tcdsdev->tcdsda_chip);
341
342 return (UNCONF);
343 }
344
345 void
346 tcds_intr_establish(tcds, slot, func, arg)
347 struct device *tcds;
348 int slot;
349 int (*func)(void *);
350 void *arg;
351 {
352 struct tcds_softc *sc = (struct tcds_softc *)tcds;
353
354 if (sc->sc_slots[slot].sc_intrhand != tcds_intrnull)
355 panic("tcds_intr_establish: chip %d twice", slot);
356
357 sc->sc_slots[slot].sc_intrhand = func;
358 sc->sc_slots[slot].sc_intrarg = arg;
359 tcds_scsi_reset(&sc->sc_slots[slot]);
360 }
361
362 void
363 tcds_intr_disestablish(tcds, slot)
364 struct device *tcds;
365 int slot;
366 {
367 struct tcds_softc *sc = (struct tcds_softc *)tcds;
368
369 if (sc->sc_slots[slot].sc_intrhand == tcds_intrnull)
370 panic("tcds_intr_disestablish: chip %d missing intr",
371 slot);
372
373 sc->sc_slots[slot].sc_intrhand = tcds_intrnull;
374 sc->sc_slots[slot].sc_intrarg = (void *)(u_long)slot;
375
376 tcds_dma_enable(&sc->sc_slots[slot], 0);
377 tcds_scsi_enable(&sc->sc_slots[slot], 0);
378 }
379
380 int
381 tcds_intrnull(val)
382 void *val;
383 {
384
385 panic("tcds_intrnull: uncaught TCDS intr for chip %lu",
386 (u_long)val);
387 }
388
389 void
390 tcds_scsi_reset(sc)
391 struct tcds_slotconfig *sc;
392 {
393 u_int32_t cir;
394
395 tcds_dma_enable(sc, 0);
396 tcds_scsi_enable(sc, 0);
397
398 cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
399 TCDS_CIR_CLR(cir, sc->sc_resetbits);
400 bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, cir);
401
402 DELAY(1);
403
404 cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
405 TCDS_CIR_SET(cir, sc->sc_resetbits);
406 bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, cir);
407
408 tcds_scsi_enable(sc, 1);
409 tcds_dma_enable(sc, 1);
410 }
411
412 void
413 tcds_scsi_enable(sc, on)
414 struct tcds_slotconfig *sc;
415 int on;
416 {
417 u_int32_t imer;
418
419 imer = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_IMER);
420
421 if (on)
422 imer |= sc->sc_intrmaskbits;
423 else
424 imer &= ~sc->sc_intrmaskbits;
425
426 bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_IMER, imer);
427 }
428
429 void
430 tcds_dma_enable(sc, on)
431 struct tcds_slotconfig *sc;
432 int on;
433 {
434 u_int32_t cir;
435
436 cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
437
438
439 if (on)
440 TCDS_CIR_SET(cir, sc->sc_dmabits);
441 else
442 TCDS_CIR_CLR(cir, sc->sc_dmabits);
443
444 bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, cir);
445 }
446
447 int
448 tcds_scsi_isintr(sc, clear)
449 struct tcds_slotconfig *sc;
450 int clear;
451 {
452 u_int32_t cir;
453
454 cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
455
456 if ((cir & sc->sc_intrbits) != 0) {
457 if (clear) {
458 TCDS_CIR_CLR(cir, sc->sc_intrbits);
459 bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR,
460 cir);
461 }
462 return (1);
463 } else
464 return (0);
465 }
466
467 int
468 tcds_scsi_iserr(sc)
469 struct tcds_slotconfig *sc;
470 {
471 u_int32_t cir;
472
473 cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
474 return ((cir & sc->sc_errorbits) != 0);
475 }
476
477 int
478 tcds_intr(arg)
479 void *arg;
480 {
481 struct tcds_softc *sc = arg;
482 u_int32_t ir, ir0;
483
484
485
486
487
488 ir = ir0 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
489 TCDS_CIR_CLR(ir0, TCDS_CIR_ALLINTR);
490 bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, ir0);
491 tc_syncbus();
492
493 #define CHECKINTR(slot) \
494 if (ir & sc->sc_slots[slot].sc_intrbits) { \
495 sc->sc_slots[slot].sc_count.ec_count++; \
496 (void)(*sc->sc_slots[slot].sc_intrhand) \
497 (sc->sc_slots[slot].sc_intrarg); \
498 }
499 CHECKINTR(0);
500 CHECKINTR(1);
501 #undef CHECKINTR
502
503 #ifdef DIAGNOSTIC
504
505
506
507
508
509
510
511
512 #define PRINTINTR(msg, bits) \
513 if (ir & bits) \
514 printf("%s: %s", sc->sc_dv.dv_xname, msg);
515 PRINTINTR("SCSI0 DREQ interrupt.\n", TCDS_CIR_SCSI0_DREQ);
516 PRINTINTR("SCSI1 DREQ interrupt.\n", TCDS_CIR_SCSI1_DREQ);
517 PRINTINTR("SCSI0 prefetch interrupt.\n", TCDS_CIR_SCSI0_PREFETCH);
518 PRINTINTR("SCSI1 prefetch interrupt.\n", TCDS_CIR_SCSI1_PREFETCH);
519 PRINTINTR("SCSI0 DMA error.\n", TCDS_CIR_SCSI0_DMA);
520 PRINTINTR("SCSI1 DMA error.\n", TCDS_CIR_SCSI1_DMA);
521 PRINTINTR("SCSI0 DB parity error.\n", TCDS_CIR_SCSI0_DB);
522 PRINTINTR("SCSI1 DB parity error.\n", TCDS_CIR_SCSI1_DB);
523 PRINTINTR("SCSI0 DMA buffer parity error.\n", TCDS_CIR_SCSI0_DMAB_PAR);
524 PRINTINTR("SCSI1 DMA buffer parity error.\n", TCDS_CIR_SCSI1_DMAB_PAR);
525 PRINTINTR("SCSI0 DMA read parity error.\n", TCDS_CIR_SCSI0_DMAR_PAR);
526 PRINTINTR("SCSI1 DMA read parity error.\n", TCDS_CIR_SCSI1_DMAR_PAR);
527 PRINTINTR("TC write parity error.\n", TCDS_CIR_TCIOW_PAR);
528 PRINTINTR("TC I/O address parity error.\n", TCDS_CIR_TCIOA_PAR);
529 #undef PRINTINTR
530 #endif
531
532
533
534
535
536
537 DELAY(1);
538
539 return (1);
540 }
541
542 void
543 tcds_params(sc, chip, idp, fastp)
544 struct tcds_softc *sc;
545 int chip, *idp, *fastp;
546 {
547 int id, fast;
548 u_int32_t ids;
549
550 #ifdef __alpha__
551 if (sc->sc_flags & TCDSF_BASEBOARD) {
552 extern u_int8_t dec_3000_scsiid[], dec_3000_scsifast[];
553
554 id = dec_3000_scsiid[chip];
555 fast = dec_3000_scsifast[chip];
556 } else
557 #endif
558 {
559
560
561
562
563
564 ids = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_EEPROM_IDS);
565 if (chip == 0)
566 ids >>= 4;
567
568 id = ids & 0x7;
569 fast = ids & 0x8;
570 }
571
572 if (id < 0 || id > 7) {
573 printf("%s: WARNING: bad SCSI ID %d for chip %d, using 7\n",
574 sc->sc_dv.dv_xname, id, chip);
575 id = 7;
576 }
577
578 if (fast)
579 printf("%s: fast mode set for chip %d\n",
580 sc->sc_dv.dv_xname, chip);
581
582 *idp = id;
583 *fastp = fast;
584 }