Annotation of sys/arch/mac68k/dev/esp.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: esp.c,v 1.27 2007/07/29 21:24:02 miod Exp $ */
2: /* $NetBSD: esp.c,v 1.17 1998/09/05 15:15:35 pk Exp $ */
3:
4: /*
5: * Copyright (c) 1997 Jason R. Thorpe.
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed for the NetBSD Project
19: * by Jason R. Thorpe.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33: */
34:
35: /*
36: * Copyright (c) 1994 Peter Galbavy
37: * All rights reserved.
38: *
39: * Redistribution and use in source and binary forms, with or without
40: * modification, are permitted provided that the following conditions
41: * are met:
42: * 1. Redistributions of source code must retain the above copyright
43: * notice, this list of conditions and the following disclaimer.
44: * 2. Redistributions in binary form must reproduce the above copyright
45: * notice, this list of conditions and the following disclaimer in the
46: * documentation and/or other materials provided with the distribution.
47: *
48: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
49: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
52: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
54: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
57: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58: * POSSIBILITY OF SUCH DAMAGE.
59: */
60:
61: /*
62: * Based on aic6360 by Jarle Greipsland
63: *
64: * Acknowledgements: Many of the algorithms used in this driver are
65: * inspired by the work of Julian Elischer (julian@tfs.com) and
66: * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
67: */
68:
69: /*
70: * Initial m68k mac support from Allen Briggs <briggs@macbsd.com>
71: * (basically consisting of the match, a bit of the attach, and the
72: * "DMA" glue functions).
73: */
74:
75: #include <sys/types.h>
76: #include <sys/param.h>
77: #include <sys/systm.h>
78: #include <sys/kernel.h>
79: #include <sys/errno.h>
80: #include <sys/ioctl.h>
81: #include <sys/device.h>
82: #include <sys/buf.h>
83: #include <sys/proc.h>
84: #include <sys/user.h>
85: #include <sys/queue.h>
86:
87: #include <scsi/scsi_all.h>
88: #include <scsi/scsiconf.h>
89: #include <scsi/scsi_message.h>
90:
91: #include <machine/cpu.h>
92: #include <machine/bus.h>
93: #include <machine/param.h>
94:
95: #include <dev/ic/ncr53c9xreg.h>
96: #include <dev/ic/ncr53c9xvar.h>
97:
98: #include <machine/viareg.h>
99:
100: #include <mac68k/dev/espvar.h>
101: #include <mac68k/dev/obiovar.h>
102:
103: void espattach(struct device *, struct device *, void *);
104: int espmatch(struct device *, void *, void *);
105:
106: /* Linkup to the rest of the kernel */
107: struct cfattach esp_ca = {
108: sizeof(struct esp_softc), espmatch, espattach
109: };
110:
111: struct scsi_adapter esp_switch = {
112: ncr53c9x_scsi_cmd,
113: minphys, /* no max at this level; handled by DMA code */
114: NULL,
115: NULL,
116: };
117:
118: struct scsi_device esp_dev = {
119: NULL, /* Use default error handler */
120: NULL, /* have a queue, served by this */
121: NULL, /* have no async handler */
122: NULL, /* Use default 'done' routine */
123: };
124:
125: /*
126: * Functions and the switch for the MI code.
127: */
128: u_char esp_read_reg(struct ncr53c9x_softc *, int);
129: void esp_write_reg(struct ncr53c9x_softc *, int, u_char);
130: int esp_dma_isintr(struct ncr53c9x_softc *);
131: void esp_dma_reset(struct ncr53c9x_softc *);
132: int esp_dma_intr(struct ncr53c9x_softc *);
133: int esp_dma_setup(struct ncr53c9x_softc *, caddr_t *,
134: size_t *, int, size_t *);
135: void esp_dma_go(struct ncr53c9x_softc *);
136: void esp_dma_stop(struct ncr53c9x_softc *);
137: int esp_dma_isactive(struct ncr53c9x_softc *);
138: void esp_quick_write_reg(struct ncr53c9x_softc *, int, u_char);
139: int esp_quick_dma_intr(struct ncr53c9x_softc *);
140: int esp_quick_dma_setup(struct ncr53c9x_softc *, caddr_t *,
141: size_t *, int, size_t *);
142: void esp_quick_dma_go(struct ncr53c9x_softc *);
143: int esp_intr(void *);
144:
145: static __inline__ int esp_dafb_have_dreq(struct esp_softc *esc);
146: static __inline__ int esp_iosb_have_dreq(struct esp_softc *esc);
147: int (*esp_have_dreq) (struct esp_softc *esc);
148:
149: struct ncr53c9x_glue esp_glue = {
150: esp_read_reg,
151: esp_write_reg,
152: esp_dma_isintr,
153: esp_dma_reset,
154: esp_dma_intr,
155: esp_dma_setup,
156: esp_dma_go,
157: esp_dma_stop,
158: esp_dma_isactive,
159: NULL, /* gl_clear_latched_intr */
160: };
161:
162: int
163: espmatch(parent, vcf, aux)
164: struct device *parent;
165: void *vcf, *aux;
166: {
167: struct cfdata *cf = vcf;
168:
169: if ((cf->cf_unit == 0) && mac68k_machine.scsi96) {
170: return 1;
171: }
172: if ((cf->cf_unit == 1) && mac68k_machine.scsi96_2) {
173: return 1;
174: }
175: return 0;
176: }
177:
178: /*
179: * Attach this instance, and then all the sub-devices
180: */
181: void
182: espattach(parent, self, aux)
183: struct device *parent, *self;
184: void *aux;
185: {
186: struct obio_attach_args *oa = (struct obio_attach_args *)aux;
187: extern vaddr_t SCSIBase;
188: struct esp_softc *esc = (void *)self;
189: struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
190: int quick = 0;
191: unsigned long reg_offset;
192:
193: reg_offset = SCSIBase - IOBase;
194: esc->sc_tag = oa->oa_tag;
195:
196: /*
197: * For Wombat, Primus and Optimus motherboards, DREQ is
198: * visible on bit 0 of the IOSB's emulated VIA2 vIFR (and
199: * the SCSI registers are offset 0x1000 bytes from IOBase).
200: *
201: * For the Q700/900/950 it's at f9800024 for bus 0 and
202: * f9800028 for bus 1 (900/950). For these machines, that is also
203: * a (12-bit) configuration register for DAFB's control of the
204: * pseudo-DMA timing. The default value is 0x1d1.
205: */
206: esp_have_dreq = esp_dafb_have_dreq;
207: if (sc->sc_dev.dv_unit == 0) {
208: if (reg_offset == 0x10000) {
209: quick = 1;
210: esp_have_dreq = esp_iosb_have_dreq;
211: } else if (reg_offset == 0x18000) {
212: quick = 0;
213: } else {
214: if (bus_space_map(esc->sc_tag, 0xf9800024,
215: 4, 0, &esc->sc_bsh)) {
216: printf("failed to map 4 at 0xf9800024.\n");
217: } else {
218: quick = 1;
219: bus_space_write_4(esc->sc_tag,
220: esc->sc_bsh, 0, 0x1d1);
221: }
222: }
223: } else {
224: if (bus_space_map(esc->sc_tag, 0xf9800028, 4, 0,
225: &esc->sc_bsh)) {
226: printf("failed to map 4 at 0xf9800028.\n");
227: } else {
228: quick = 1;
229: bus_space_write_4(esc->sc_tag, esc->sc_bsh, 0, 0x1d1);
230: }
231: }
232: if (quick) {
233: esp_glue.gl_write_reg = esp_quick_write_reg;
234: esp_glue.gl_dma_intr = esp_quick_dma_intr;
235: esp_glue.gl_dma_setup = esp_quick_dma_setup;
236: esp_glue.gl_dma_go = esp_quick_dma_go;
237: }
238:
239: /*
240: * Set up the glue for MI code early; we use some of it here.
241: */
242: sc->sc_glue = &esp_glue;
243:
244: esc->sc_ih.vh_fn = esp_intr;
245: esc->sc_ih.vh_arg = esc;
246: esc->sc_ih.vh_ipl = VIA2_SCSIIRQ;
247:
248: /*
249: * Save the regs
250: */
251: if (sc->sc_dev.dv_unit == 0) {
252: esc->sc_reg = (volatile u_char *) SCSIBase;
253: via2_register_irq(&esc->sc_ih, self->dv_xname);
254: esc->irq_mask = V2IF_SCSIIRQ;
255: if (reg_offset == 0x10000) {
256: /* From the Q650 developer's note */
257: sc->sc_freq = 16500000;
258: } else {
259: sc->sc_freq = 25000000;
260: }
261: } else {
262: esc->sc_reg = (volatile u_char *) SCSIBase + 0x402;
263: via2_register_irq(&esc->sc_ih, self->dv_xname);
264: esc->irq_mask = 0;
265: sc->sc_freq = 25000000;
266: }
267:
268: if (quick) {
269: printf(" (pseudo-DMA)");
270: }
271:
272: #ifdef DEBUG
273: printf(" address %p", esc->sc_reg);
274: #endif
275:
276: sc->sc_id = 7;
277:
278: /*
279: * It is necessary to try to load the 2nd config register here,
280: * to find out what rev the esp chip is, else the esp_reset
281: * will not set up the defaults correctly.
282: */
283: sc->sc_cfg1 = sc->sc_id; /* | NCRCFG1_PARENB; */
284: sc->sc_cfg2 = NCRCFG2_SCSI2;
285: sc->sc_cfg3 = 0;
286: sc->sc_rev = NCR_VARIANT_NCR53C96;
287:
288: /*
289: * This is the value used to start sync negotiations
290: * Note that the NCR register "SYNCTP" is programmed
291: * in "clocks per byte", and has a minimum value of 4.
292: * The SCSI period used in negotiation is one-fourth
293: * of the time (in nanoseconds) needed to transfer one byte.
294: * Since the chip's clock is given in MHz, we have the following
295: * formula: 4 * period = (1000 / freq) * 4
296: */
297: sc->sc_minsync = (1000 * 1000000) / sc->sc_freq;
298:
299: /* We need this to fit into the TCR... */
300: sc->sc_maxxfer = 64 * 1024;
301:
302: if (quick == 0) {
303: sc->sc_minsync = 0; /* No synchronous xfers w/o DMA */
304: sc->sc_maxxfer = 8 * 1024;
305: }
306:
307: /* gimme MHz */
308: sc->sc_freq /= 1000000;
309:
310: /*
311: * Configure interrupts.
312: */
313: if (esc->irq_mask) {
314: via2_reg(vPCR) = 0x22;
315: via2_reg(vIFR) = esc->irq_mask;
316: via2_reg(vIER) = 0x80 | esc->irq_mask;
317: }
318:
319: /*
320: * Now try to attach all the sub-devices
321: */
322: ncr53c9x_attach(sc, &esp_switch, &esp_dev);
323: }
324:
325: /*
326: * Glue functions.
327: */
328:
329: u_char
330: esp_read_reg(sc, reg)
331: struct ncr53c9x_softc *sc;
332: int reg;
333: {
334: struct esp_softc *esc = (struct esp_softc *)sc;
335:
336: return esc->sc_reg[reg * 16];
337: }
338:
339: void
340: esp_write_reg(sc, reg, val)
341: struct ncr53c9x_softc *sc;
342: int reg;
343: u_char val;
344: {
345: struct esp_softc *esc = (struct esp_softc *)sc;
346: u_char v = val;
347:
348: if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) {
349: v = NCRCMD_TRANS;
350: }
351: esc->sc_reg[reg * 16] = v;
352: }
353:
354: void
355: esp_dma_stop(sc)
356: struct ncr53c9x_softc *sc;
357: {
358: }
359:
360: int
361: esp_dma_isactive(sc)
362: struct ncr53c9x_softc *sc;
363: {
364: struct esp_softc *esc = (struct esp_softc *)sc;
365:
366: return esc->sc_active;
367: }
368:
369: int
370: esp_dma_isintr(sc)
371: struct ncr53c9x_softc *sc;
372: {
373: struct esp_softc *esc = (struct esp_softc *)sc;
374:
375: return esc->sc_reg[NCR_STAT * 16] & 0x80;
376: }
377:
378: void
379: esp_dma_reset(sc)
380: struct ncr53c9x_softc *sc;
381: {
382: struct esp_softc *esc = (struct esp_softc *)sc;
383:
384: esc->sc_active = 0;
385: esc->sc_tc = 0;
386: }
387:
388: int
389: esp_dma_intr(sc)
390: struct ncr53c9x_softc *sc;
391: {
392: struct esp_softc *esc = (struct esp_softc *)sc;
393: volatile u_char *cmdreg, *intrreg, *statreg, *fiforeg;
394: u_char *p;
395: u_int espphase, espstat, espintr;
396: int cnt;
397:
398: if (esc->sc_active == 0) {
399: printf("dma_intr--inactive DMA\n");
400: return -1;
401: }
402:
403: if ((sc->sc_espintr & NCRINTR_BS) == 0) {
404: esc->sc_active = 0;
405: return 0;
406: }
407:
408: cnt = *esc->sc_dmalen;
409: if (*esc->sc_dmalen == 0) {
410: printf("data interrupt, but no count left.");
411: }
412:
413: p = *esc->sc_dmaaddr;
414: espphase = sc->sc_phase;
415: espstat = (u_int) sc->sc_espstat;
416: espintr = (u_int) sc->sc_espintr;
417: cmdreg = esc->sc_reg + NCR_CMD * 16;
418: fiforeg = esc->sc_reg + NCR_FIFO * 16;
419: statreg = esc->sc_reg + NCR_STAT * 16;
420: intrreg = esc->sc_reg + NCR_INTR * 16;
421: do {
422: if (esc->sc_datain) {
423: *p++ = *fiforeg;
424: cnt--;
425: if (espphase == DATA_IN_PHASE) {
426: *cmdreg = NCRCMD_TRANS;
427: } else {
428: esc->sc_active = 0;
429: }
430: } else {
431: if ( (espphase == DATA_OUT_PHASE)
432: || (espphase == MESSAGE_OUT_PHASE)) {
433: *fiforeg = *p++;
434: cnt--;
435: *cmdreg = NCRCMD_TRANS;
436: } else {
437: esc->sc_active = 0;
438: }
439: }
440:
441: if (esc->sc_active) {
442: while (!(*statreg & 0x80));
443: espstat = *statreg;
444: espintr = *intrreg;
445: espphase = (espintr & NCRINTR_DIS)
446: ? /* Disconnected */ BUSFREE_PHASE
447: : espstat & PHASE_MASK;
448: }
449: } while (esc->sc_active && (espintr & NCRINTR_BS));
450: sc->sc_phase = espphase;
451: sc->sc_espstat = (u_char) espstat;
452: sc->sc_espintr = (u_char) espintr;
453: *esc->sc_dmaaddr = p;
454: *esc->sc_dmalen = cnt;
455:
456: if (*esc->sc_dmalen == 0) {
457: esc->sc_tc = NCRSTAT_TC;
458: }
459: sc->sc_espstat |= esc->sc_tc;
460: return 0;
461: }
462:
463: int
464: esp_dma_setup(sc, addr, len, datain, dmasize)
465: struct ncr53c9x_softc *sc;
466: caddr_t *addr;
467: size_t *len;
468: int datain;
469: size_t *dmasize;
470: {
471: struct esp_softc *esc = (struct esp_softc *)sc;
472:
473: esc->sc_dmaaddr = addr;
474: esc->sc_dmalen = len;
475: esc->sc_datain = datain;
476: esc->sc_dmasize = *dmasize;
477: esc->sc_tc = 0;
478:
479: return 0;
480: }
481:
482: void
483: esp_dma_go(sc)
484: struct ncr53c9x_softc *sc;
485: {
486: struct esp_softc *esc = (struct esp_softc *)sc;
487:
488: if (esc->sc_datain == 0) {
489: esc->sc_reg[NCR_FIFO * 16] = **esc->sc_dmaaddr;
490: (*esc->sc_dmalen)--;
491: (*esc->sc_dmaaddr)++;
492: }
493: esc->sc_active = 1;
494: }
495:
496: void
497: esp_quick_write_reg(sc, reg, val)
498: struct ncr53c9x_softc *sc;
499: int reg;
500: u_char val;
501: {
502: struct esp_softc *esc = (struct esp_softc *)sc;
503: u_char v = val;
504:
505: esc->sc_reg[reg * 16] = v;
506: }
507:
508: int
509: esp_quick_dma_intr(sc)
510: struct ncr53c9x_softc *sc;
511: {
512: struct esp_softc *esc = (struct esp_softc *)sc;
513: int trans=0, resid=0;
514:
515: if (esc->sc_active == 0)
516: panic("dma_intr--inactive DMA");
517:
518: esc->sc_active = 0;
519:
520: if (esc->sc_dmasize == 0) {
521: int res;
522:
523: res = 65536;
524: res -= NCR_READ_REG(sc, NCR_TCL);
525: res -= NCR_READ_REG(sc, NCR_TCM) << 8;
526: printf("dmaintr: discarded %d b (last transfer was %d b).\n",
527: res, esc->sc_prevdmasize);
528: return 0;
529: }
530:
531: if (esc->sc_datain &&
532: (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
533: printf("dmaintr: empty FIFO of %d\n", resid);
534: DELAY(1);
535: }
536:
537: if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
538: resid += NCR_READ_REG(sc, NCR_TCL);
539: resid += NCR_READ_REG(sc, NCR_TCM) << 8;
540:
541: if (resid == 0)
542: resid = 65536;
543: }
544:
545: trans = esc->sc_dmasize - resid;
546: if (trans < 0) {
547: printf("dmaintr: trans < 0????");
548: trans = esc->sc_dmasize;
549: }
550:
551: NCR_DMA(("dmaintr: trans %d, resid %d.\n", trans, resid));
552: *esc->sc_dmaaddr += trans;
553: *esc->sc_dmalen -= trans;
554:
555: return 0;
556: }
557:
558: int
559: esp_quick_dma_setup(sc, addr, len, datain, dmasize)
560: struct ncr53c9x_softc *sc;
561: caddr_t *addr;
562: size_t *len;
563: int datain;
564: size_t *dmasize;
565: {
566: struct esp_softc *esc = (struct esp_softc *)sc;
567:
568: esc->sc_dmaaddr = addr;
569: esc->sc_dmalen = len;
570:
571: esc->sc_pdmaddr = (u_int16_t *) *addr;
572: esc->sc_pdmalen = *len;
573:
574: if (esc->sc_pdmalen & 1) {
575: esc->sc_pdmalen--;
576: esc->sc_pad = 1;
577: } else {
578: esc->sc_pad = 0;
579: }
580:
581: esc->sc_datain = datain;
582: esc->sc_prevdmasize = esc->sc_dmasize;
583: esc->sc_dmasize = *dmasize;
584:
585: return 0;
586: }
587:
588: static __inline__ int
589: esp_dafb_have_dreq(esc)
590: struct esp_softc *esc;
591: {
592: return (*(volatile u_int32_t *)
593: bus_space_vaddr(esc->sc_tag, esc->sc_bsh) & 0x200);
594: }
595:
596: static __inline__ int
597: esp_iosb_have_dreq(esc)
598: struct esp_softc *esc;
599: {
600: return (via2_reg(vIFR) & V2IF_SCSIDRQ);
601: }
602:
603: /* Faster spl constructs, without saving old values */
604: #define __splx(s) __asm __volatile ("movew %0,sr" : : "di" (s));
605: #define __splvm() __splx(mac68k_vmipl)
606: #define __splbio() __splx(PSL_S | PSL_IPL2)
607:
608: void
609: esp_quick_dma_go(sc)
610: struct ncr53c9x_softc *sc;
611: {
612: struct esp_softc *esc = (struct esp_softc *)sc;
613: extern int *nofault;
614: label_t faultbuf;
615: u_int16_t volatile *pdma;
616: u_char volatile *statreg;
617: int espspl;
618:
619: esc->sc_active = 1;
620:
621: espspl = splbio();
622:
623: restart_dmago:
624: nofault = (int *) &faultbuf;
625: if (setjmp((label_t *) nofault)) {
626: int i=0;
627:
628: nofault = (int *) 0;
629: statreg = esc->sc_reg + NCR_STAT * 16;
630: for (;;) {
631: if (*statreg & 0x80) {
632: goto gotintr;
633: }
634:
635: if (esp_have_dreq(esc)) {
636: break;
637: }
638:
639: DELAY(1);
640: if (i++ > 10000)
641: panic("esp_dma_go: Argh!");
642: }
643: goto restart_dmago;
644: }
645:
646: statreg = esc->sc_reg + NCR_STAT * 16;
647: pdma = (u_int16_t *) (esc->sc_reg + 0x100);
648:
649: #define WAIT while (!esp_have_dreq(esc)) if (*statreg & 0x80) goto gotintr
650:
651: if (esc->sc_datain == 0) {
652: while (esc->sc_pdmalen) {
653: WAIT;
654: __splvm(); *pdma = *(esc->sc_pdmaddr)++; __splbio();
655: esc->sc_pdmalen -= 2;
656: }
657: if (esc->sc_pad) {
658: unsigned short us;
659: unsigned char *c;
660: c = (unsigned char *) esc->sc_pdmaddr;
661: us = *c;
662: WAIT;
663: __splvm(); *pdma = us; __splbio();
664: }
665: } else {
666: while (esc->sc_pdmalen) {
667: WAIT;
668: __splvm(); *(esc->sc_pdmaddr)++ = *pdma; __splbio();
669: esc->sc_pdmalen -= 2;
670: }
671: if (esc->sc_pad) {
672: unsigned short us;
673: unsigned char *c;
674: WAIT;
675: __splvm(); us = *pdma; __splbio();
676: c = (unsigned char *) esc->sc_pdmaddr;
677: *c = us & 0xff;
678: }
679: }
680: #undef WAIT
681: nofault = (int *) 0;
682:
683: if ((*statreg & 0x80) == 0) {
684: splx(espspl);
685: return;
686: }
687:
688: gotintr:
689: ncr53c9x_intr(sc);
690: splx(espspl);
691: }
692:
693: int
694: esp_intr(void *v)
695: {
696: struct esp_softc *esc = (struct esp_softc *)v;
697:
698: if (esc->sc_reg[NCR_STAT * 16] & NCRSTAT_INT)
699: return (ncr53c9x_intr(v));
700:
701: return (0);
702: }
CVSweb