This source file includes following definitions.
- asc_tcds_match
- asc_tcds_attach
- tcds_dma_reset
- tcds_dma_setup
- tcds_dma_go
- tcds_dma_stop
- tcds_dma_intr
- tcds_dma_isintr
- tcds_dma_isactive
- tcds_clear_latched_intr
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 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/device.h>
68 #include <sys/buf.h>
69
70 #include <scsi/scsi_all.h>
71 #include <scsi/scsiconf.h>
72
73 #include <dev/ic/ncr53c9xreg.h>
74 #include <dev/ic/ncr53c9xvar.h>
75 #include <dev/tc/ascvar.h>
76
77 #include <machine/bus.h>
78
79 #include <dev/tc/tcvar.h>
80 #include <dev/tc/tcdsreg.h>
81 #include <dev/tc/tcdsvar.h>
82
83 struct asc_tcds_softc {
84 struct asc_softc asc;
85
86 struct tcds_slotconfig *sc_tcds;
87 };
88
89 int asc_tcds_match (struct device *, void *, void *);
90 void asc_tcds_attach(struct device *, struct device *, void *);
91
92
93 struct cfattach asc_tcds_ca = {
94 sizeof(struct asc_tcds_softc), asc_tcds_match, asc_tcds_attach
95 };
96
97
98
99
100 int tcds_dma_isintr(struct ncr53c9x_softc *);
101 void tcds_dma_reset(struct ncr53c9x_softc *);
102 int tcds_dma_intr(struct ncr53c9x_softc *);
103 int tcds_dma_setup(struct ncr53c9x_softc *, caddr_t *,
104 size_t *, int, size_t *);
105 void tcds_dma_go(struct ncr53c9x_softc *);
106 void tcds_dma_stop(struct ncr53c9x_softc *);
107 int tcds_dma_isactive(struct ncr53c9x_softc *);
108 void tcds_clear_latched_intr(struct ncr53c9x_softc *);
109
110 struct ncr53c9x_glue asc_tcds_glue = {
111 asc_read_reg,
112 asc_write_reg,
113 tcds_dma_isintr,
114 tcds_dma_reset,
115 tcds_dma_intr,
116 tcds_dma_setup,
117 tcds_dma_go,
118 tcds_dma_stop,
119 tcds_dma_isactive,
120 tcds_clear_latched_intr,
121 };
122
123 extern struct scsi_adapter asc_switch;
124 extern struct scsi_device asc_dev;
125
126 int
127 asc_tcds_match(parent, cf, aux)
128 struct device *parent;
129 void *cf, *aux;
130 {
131
132
133 return 1;
134 }
135
136 #define DMAMAX(a) (NBPG - ((a) & (NBPG - 1)))
137
138
139
140
141 void
142 asc_tcds_attach(parent, self, aux)
143 struct device *parent, *self;
144 void *aux;
145 {
146 struct tcdsdev_attach_args *tcdsdev = aux;
147 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)self;
148 struct ncr53c9x_softc *sc = &asc->asc.sc_ncr53c9x;
149 int error;
150
151
152
153
154 sc->sc_glue = &asc_tcds_glue;
155
156 asc->asc.sc_bst = tcdsdev->tcdsda_bst;
157 asc->asc.sc_bsh = tcdsdev->tcdsda_bsh;
158 asc->sc_tcds = tcdsdev->tcdsda_sc;
159
160
161
162
163
164
165
166 asc->asc.sc_dmat = tcdsdev->tcdsda_dmat;
167 if ((error = bus_dmamap_create(asc->asc.sc_dmat, NBPG, 1, NBPG,
168 NBPG, BUS_DMA_NOWAIT, &asc->asc.sc_dmamap)) < 0) {
169 printf("failed to create dma map, error = %d\n", error);
170 }
171
172 sc->sc_id = tcdsdev->tcdsda_id;
173 sc->sc_freq = tcdsdev->tcdsda_freq;
174
175
176 sc->sc_freq /= 1000000;
177
178 tcds_intr_establish(parent, tcdsdev->tcdsda_chip, ncr53c9x_intr, sc);
179
180
181
182
183
184
185
186
187
188
189 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
190 sc->sc_cfg2 = NCRCFG2_SCSI2;
191 sc->sc_cfg3 = NCRCFG3_CDB;
192 if (sc->sc_freq > 25)
193 sc->sc_cfg3 |= NCRF9XCFG3_FCLK;
194 sc->sc_rev = tcdsdev->tcdsda_variant;
195 if (tcdsdev->tcdsda_fast) {
196 sc->sc_features |= NCR_F_FASTSCSI;
197 sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI;
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215 sc->sc_minsync = (1000 / sc->sc_freq) * tcdsdev->tcdsda_period / 4;
216
217 sc->sc_maxxfer = 64 * 1024;
218
219
220 ncr53c9x_attach(sc, &asc_switch, &asc_dev);
221 }
222
223 void
224 tcds_dma_reset(sc)
225 struct ncr53c9x_softc *sc;
226 {
227 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
228
229
230 tcds_scsi_reset(asc->sc_tcds);
231
232 if (asc->asc.sc_flags & ASC_MAPLOADED)
233 bus_dmamap_unload(asc->asc.sc_dmat, asc->asc.sc_dmamap);
234 asc->asc.sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
235 }
236
237
238
239
240 int
241 tcds_dma_setup(sc, addr, len, ispullup, dmasize)
242 struct ncr53c9x_softc *sc;
243 caddr_t *addr;
244 size_t *len, *dmasize;
245 int ispullup;
246 {
247 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
248 struct tcds_slotconfig *tcds = asc->sc_tcds;
249 size_t size;
250 u_int32_t dic;
251
252 NCR_DMA(("tcds_dma %d: start %d@%p,%s\n", tcds->sc_slot,
253 (int)*asc->asc.sc_dmalen, *asc->asc.sc_dmaaddr,
254 (ispullup) ? "IN" : "OUT"));
255
256
257
258
259
260 size = min(*dmasize, DMAMAX((size_t)*addr));
261 asc->asc.sc_dmaaddr = addr;
262 asc->asc.sc_dmalen = len;
263 asc->asc.sc_flags = (ispullup) ? ASC_ISPULLUP : 0;
264 *dmasize = asc->asc.sc_dmasize = size;
265
266 NCR_DMA(("dma_start: dmasize = %d\n", (int)size));
267
268 if (size == 0)
269 return 0;
270
271 if (bus_dmamap_load(asc->asc.sc_dmat, asc->asc.sc_dmamap, *addr, size,
272 NULL, BUS_DMA_NOWAIT | (ispullup ? BUS_DMA_READ : BUS_DMA_WRITE))) {
273
274
275
276
277 panic("tcds_dma_setup: dmamap load failed");
278 }
279
280
281 bus_dmamap_sync(asc->asc.sc_dmat, asc->asc.sc_dmamap, 0, size,
282 (ispullup) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
283
284
285 bus_space_write_4(tcds->sc_bst, tcds->sc_bsh, tcds->sc_sda,
286 asc->asc.sc_dmamap->dm_segs[0].ds_addr >> 2);
287 dic = bus_space_read_4(tcds->sc_bst, tcds->sc_bsh, tcds->sc_dic);
288 dic &= ~TCDS_DIC_ADDRMASK;
289 dic |= asc->asc.sc_dmamap->dm_segs[0].ds_addr & TCDS_DIC_ADDRMASK;
290 if (ispullup)
291 dic |= TCDS_DIC_WRITE;
292 else
293 dic &= ~TCDS_DIC_WRITE;
294 bus_space_write_4(tcds->sc_bst, tcds->sc_bsh, tcds->sc_dic, dic);
295
296 asc->asc.sc_flags |= ASC_MAPLOADED;
297 return 0;
298 }
299
300 void
301 tcds_dma_go(sc)
302 struct ncr53c9x_softc *sc;
303 {
304 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
305
306
307 asc->asc.sc_flags |= ASC_DMAACTIVE;
308
309
310 tcds_dma_enable(asc->sc_tcds, 1);
311 }
312
313 void
314 tcds_dma_stop(sc)
315 struct ncr53c9x_softc *sc;
316 {
317 #if 0
318 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
319 #endif
320
321
322
323
324 }
325
326
327
328
329
330
331
332
333 int
334 tcds_dma_intr(sc)
335 struct ncr53c9x_softc *sc;
336 {
337 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
338 struct tcds_slotconfig *tcds = asc->sc_tcds;
339 int trans, resid;
340 u_int32_t tcl, tcm;
341 u_int32_t dud, dudmask, *addr;
342 bus_addr_t pa;
343
344 NCR_DMA(("tcds_dma %d: intr", tcds->sc_slot));
345
346 if (tcds_scsi_iserr(tcds))
347 return 0;
348
349
350 if ((asc->asc.sc_flags & ASC_DMAACTIVE) == 0)
351 panic("tcds_dma_intr: DMA wasn't active");
352
353
354 tcds_dma_enable(tcds, 0);
355 asc->asc.sc_flags &= ~ASC_DMAACTIVE;
356
357 if (asc->asc.sc_dmasize == 0) {
358
359 tcl = NCR_READ_REG(sc, NCR_TCL);
360 tcm = NCR_READ_REG(sc, NCR_TCM);
361 NCR_DMA(("dma_intr: discarded %d bytes (tcl=%d, tcm=%d)\n",
362 tcl | (tcm << 8), tcl, tcm));
363 return 0;
364 }
365
366 resid = 0;
367 if ((asc->asc.sc_flags & ASC_ISPULLUP) == 0 &&
368 (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
369 NCR_DMA(("dma_intr: empty esp FIFO of %d ", resid));
370 DELAY(1);
371 }
372
373 resid += (tcl = NCR_READ_REG(sc, NCR_TCL));
374 resid += (tcm = NCR_READ_REG(sc, NCR_TCM)) << 8;
375
376 trans = asc->asc.sc_dmasize - resid;
377 if (trans < 0) {
378 printf("tcds_dma %d: xfer (%d) > req (%d)\n",
379 tcds->sc_slot, trans, (int)asc->asc.sc_dmasize);
380 trans = asc->asc.sc_dmasize;
381 }
382
383 NCR_DMA(("dma_intr: tcl=%d, tcm=%d; trans=%d, resid=%d\n",
384 tcl, tcm, trans, resid));
385
386 *asc->asc.sc_dmalen -= trans;
387 *asc->asc.sc_dmaaddr += trans;
388
389 bus_dmamap_sync(asc->asc.sc_dmat, asc->asc.sc_dmamap,
390 0, asc->asc.sc_dmamap->dm_mapsize,
391 (asc->asc.sc_flags & ASC_ISPULLUP)
392 ? BUS_DMASYNC_POSTREAD
393 : BUS_DMASYNC_POSTWRITE);
394
395
396
397
398 if (asc->asc.sc_flags & ASC_ISPULLUP) {
399
400 dud = bus_space_read_4(tcds->sc_bst,
401 tcds->sc_bsh, tcds->sc_dud0);
402 if ((dud & TCDS_DUD0_VALIDBITS) != 0) {
403 addr = (u_int32_t *)
404 ((paddr_t)*asc->asc.sc_dmaaddr & ~0x3);
405 dudmask = 0;
406 if (dud & TCDS_DUD0_VALID00)
407 panic("tcds_dma: dud0 byte 0 valid");
408 if (dud & TCDS_DUD0_VALID01)
409 dudmask |= TCDS_DUD_BYTE01;
410 if (dud & TCDS_DUD0_VALID10)
411 dudmask |= TCDS_DUD_BYTE10;
412 #ifdef DIAGNOSTIC
413 if (dud & TCDS_DUD0_VALID11)
414 dudmask |= TCDS_DUD_BYTE11;
415 #endif
416 NCR_DMA(("dud0 at %p dudmask 0x%x\n",
417 addr, dudmask));
418 *addr = (*addr & ~dudmask) | (dud & dudmask);
419 }
420 dud = bus_space_read_4(tcds->sc_bst,
421 tcds->sc_bsh, tcds->sc_dud1);
422 if ((dud & TCDS_DUD1_VALIDBITS) != 0) {
423 pa = bus_space_read_4(tcds->sc_bst, tcds->sc_bsh,
424 tcds->sc_sda) << 2;
425 dudmask = 0;
426 if (dud & TCDS_DUD1_VALID00)
427 dudmask |= TCDS_DUD_BYTE00;
428 if (dud & TCDS_DUD1_VALID01)
429 dudmask |= TCDS_DUD_BYTE01;
430 if (dud & TCDS_DUD1_VALID10)
431 dudmask |= TCDS_DUD_BYTE10;
432 #ifdef DIAGNOSTIC
433 if (dud & TCDS_DUD1_VALID11)
434 panic("tcds_dma: dud1 byte 3 valid");
435 #endif
436 NCR_DMA(("dud1 at 0x%lx dudmask 0x%x\n",
437 pa, dudmask));
438
439 #if defined(__alpha__)
440 addr = (u_int32_t *)ALPHA_PHYS_TO_K0SEG(pa);
441 #elif defined(__mips__)
442 addr = (u_int32_t *)MIPS_PHYS_TO_KSEG1(pa);
443 #else
444 #error TURBOchannel only exists on DECs, folks...
445 #endif
446 *addr = (*addr & ~dudmask) | (dud & dudmask);
447 }
448
449 }
450
451 bus_dmamap_unload(asc->asc.sc_dmat, asc->asc.sc_dmamap);
452 asc->asc.sc_flags &= ~ASC_MAPLOADED;
453
454 return 0;
455 }
456
457
458
459
460 int
461 tcds_dma_isintr(sc)
462 struct ncr53c9x_softc *sc;
463 {
464 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
465 int x;
466
467 x = tcds_scsi_isintr(asc->sc_tcds, 1);
468
469
470 return x;
471 }
472
473 int
474 tcds_dma_isactive(sc)
475 struct ncr53c9x_softc *sc;
476 {
477 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
478
479 return !!(asc->asc.sc_flags & ASC_DMAACTIVE);
480 }
481
482 void
483 tcds_clear_latched_intr(sc)
484 struct ncr53c9x_softc *sc;
485 {
486 struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
487
488
489 (void)tcds_scsi_isintr(asc->sc_tcds, 1);
490 }