sbc.c revision 1.15 1 /* $NetBSD: sbc.c,v 1.15 1996/12/16 16:17:12 scottr Exp $ */
2
3 /*
4 * Copyright (c) 1996 Scott Reynolds
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. The name of the authors may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 * 4. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgements:
19 * This product includes software developed by Scott Reynolds.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * This file contains only the machine-dependent parts of the mac68k
35 * NCR 5380 SCSI driver. (Autoconfig stuff and PDMA functions.)
36 * The machine-independent parts are in ncr5380sbc.c
37 *
38 * Supported hardware includes:
39 * Macintosh II family 5380-based controller
40 *
41 * Credits, history:
42 *
43 * Scott Reynolds wrote this module, based on work by Allen Briggs
44 * (mac68k), Gordon W. Ross and David Jones (sun3), and Leo Weppelman
45 * (atari). Thanks to Allen for supplying crucial interpretation of the
46 * NetBSD/mac68k 1.1 'ncrscsi' driver. Also, Allen, Gordon, and Jason
47 * Thorpe all helped to refine this code, and were considerable sources
48 * of moral support.
49 */
50
51 #include <sys/types.h>
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/errno.h>
56 #include <sys/device.h>
57 #include <sys/buf.h>
58 #include <sys/proc.h>
59 #include <sys/user.h>
60
61 #include <scsi/scsi_all.h>
62 #include <scsi/scsi_debug.h>
63 #include <scsi/scsiconf.h>
64
65 #include <dev/ic/ncr5380reg.h>
66 #include <dev/ic/ncr5380var.h>
67
68 #include <machine/cpu.h>
69 #include <machine/viareg.h>
70
71 #include "sbcreg.h"
72
73 /*
74 * Transfers smaller than this are done using PIO
75 * (on assumption they're not worth PDMA overhead)
76 */
77 #define MIN_DMA_LEN 128
78
79 /*
80 * Transfers larger than 8192 bytes need to be split up
81 * due to the size of the PDMA space.
82 */
83 #define MAX_DMA_LEN 0x2000
84
85 /*
86 * From Guide to the Macintosh Family Hardware, pp. 137-143
87 * These are offsets from SCSIBase (see pmap_bootstrap.c)
88 */
89 #define SBC_REG_OFS 0x10000
90 #define SBC_HSK_OFS 0x06000
91 #define SBC_DMA_OFS 0x12000
92
93 #define SBC_DMA_OFS_PB500 0x06000
94
95 #define SBC_REG_OFS_IIFX 0x08000 /* Just guessing... */
96 #define SBC_HSK_OFS_IIFX 0x0e000
97 #define SBC_DMA_OFS_IIFX 0x0c000
98
99 #ifdef SBC_DEBUG
100 # define SBC_DB_INTR 0x01
101 # define SBC_DB_DMA 0x02
102 # define SBC_DB_REG 0x04
103 # define SBC_DB_BREAK 0x08
104
105 int sbc_debug = 0 /* | SBC_DB_INTR | SBC_DB_DMA */;
106 int sbc_link_flags = 0 /* | SDEV_DB2 */;
107
108 # ifndef DDB
109 # define Debugger() printf("Debug: sbc.c:%d\n", __LINE__)
110 # endif
111 # define SBC_BREAK \
112 do { if (sbc_debug & SBC_DB_BREAK) Debugger(); } while (0)
113 #else
114 # define SBC_BREAK
115 #endif
116
117 /*
118 * This structure is used to keep track of PDMA requests.
119 */
120 struct sbc_pdma_handle {
121 int dh_flags; /* flags */
122 #define SBC_DH_BUSY 0x01 /* This handle is in use */
123 #define SBC_DH_OUT 0x02 /* PDMA data out (write) */
124 #define SBC_DH_DONE 0x04 /* PDMA transfer is complete */
125 u_char *dh_addr; /* data buffer */
126 int dh_len; /* length of data buffer */
127 };
128
129 /*
130 * The first structure member has to be the ncr5380_softc
131 * so we can just cast to go back and forth between them.
132 */
133 struct sbc_softc {
134 struct ncr5380_softc ncr_sc;
135 volatile struct sbc_regs *sc_regs;
136 volatile vm_offset_t sc_drq_addr;
137 volatile vm_offset_t sc_nodrq_addr;
138 volatile u_int8_t *sc_ienable;
139 volatile u_int8_t *sc_iflag;
140 int sc_options; /* options for this instance. */
141 struct sbc_pdma_handle sc_pdma[SCI_OPENINGS];
142 };
143
144 /*
145 * Options. By default, SCSI interrupts and reselect are disabled.
146 * You may enable either of these features with the `flags' directive
147 * in your kernel's configuration file.
148 *
149 * Alternatively, you can patch your kernel with DDB or some other
150 * mechanism. The sc_options member of the softc is OR'd with
151 * the value in sbc_options.
152 *
153 * The options code is based on the sparc 'si' driver's version of
154 * the same.
155 */
156 #define SBC_PDMA 0x01 /* Use PDMA for polled transfers */
157 #define SBC_INTR 0x02 /* Allow SCSI IRQ/DRQ interrupts */
158 #define SBC_RESELECT 0x04 /* Allow disconnect/reselect */
159 #define SBC_OPTIONS_MASK (SBC_RESELECT|SBC_INTR|SBC_PDMA)
160 #define SBC_OPTIONS_BITS "\10\3RESELECT\2INTR\1PDMA"
161 int sbc_options = SBC_PDMA;
162
163 static int sbc_match __P((struct device *, struct cfdata *, void *));
164 static void sbc_attach __P((struct device *, struct device *, void *));
165 static void sbc_minphys __P((struct buf *bp));
166
167 static int sbc_wait_busy __P((struct ncr5380_softc *));
168 static int sbc_ready __P((struct ncr5380_softc *));
169 static int sbc_wait_dreq __P((struct ncr5380_softc *));
170 static int sbc_pdma_in __P((struct ncr5380_softc *, int, int, u_char *));
171 static int sbc_pdma_out __P((struct ncr5380_softc *, int, int, u_char *));
172 #ifdef SBC_DEBUG
173 static void decode_5380_intr __P((struct ncr5380_softc *));
174 #endif
175
176 void sbc_intr_enable __P((struct ncr5380_softc *));
177 void sbc_intr_disable __P((struct ncr5380_softc *));
178 void sbc_irq_intr __P((void *));
179 void sbc_drq_intr __P((void *));
180 void sbc_dma_alloc __P((struct ncr5380_softc *));
181 void sbc_dma_free __P((struct ncr5380_softc *));
182 void sbc_dma_poll __P((struct ncr5380_softc *));
183 void sbc_dma_setup __P((struct ncr5380_softc *));
184 void sbc_dma_start __P((struct ncr5380_softc *));
185 void sbc_dma_eop __P((struct ncr5380_softc *));
186 void sbc_dma_stop __P((struct ncr5380_softc *));
187
188 static struct scsi_adapter sbc_ops = {
189 ncr5380_scsi_cmd, /* scsi_cmd() */
190 sbc_minphys, /* scsi_minphys() */
191 NULL, /* open_target_lu() */
192 NULL, /* close_target_lu() */
193 };
194
195 /* This is copied from julian's bt driver */
196 /* "so we have a default dev struct for our link struct." */
197 static struct scsi_device sbc_dev = {
198 NULL, /* Use default error handler. */
199 NULL, /* Use default start handler. */
200 NULL, /* Use default async handler. */
201 NULL, /* Use default "done" routine. */
202 };
203
204 struct cfattach sbc_ca = {
205 sizeof(struct sbc_softc), sbc_match, sbc_attach
206 };
207
208 struct cfdriver sbc_cd = {
209 NULL, "sbc", DV_DULL
210 };
211
212
213 static int
214 sbc_match(parent, cf, args)
215 struct device *parent;
216 struct cfdata *cf;
217 void *args;
218 {
219 if (!mac68k_machine.scsi80)
220 return 0;
221 return 1;
222 }
223
224 static void
225 sbc_attach(parent, self, args)
226 struct device *parent, *self;
227 void *args;
228 {
229 struct sbc_softc *sc = (struct sbc_softc *) self;
230 struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *) sc;
231 char bits[64];
232 extern vm_offset_t SCSIBase;
233
234 /* Pull in the options flags. */
235 sc->sc_options = ((ncr_sc->sc_dev.dv_cfdata->cf_flags | sbc_options)
236 & SBC_OPTIONS_MASK);
237
238 /*
239 * Set up offsets to 5380 registers and GLUE I/O space, and turn
240 * off options we know we can't support on certain models.
241 */
242 switch (current_mac_model->machineid) {
243 case MACH_MACIIFX: /* Note: the IIfx isn't (yet) supported. */
244 sc->sc_regs = (struct sbc_regs *)(SCSIBase + SBC_REG_OFS_IIFX);
245 sc->sc_drq_addr = (vm_offset_t)(SCSIBase + SBC_HSK_OFS_IIFX);
246 sc->sc_nodrq_addr = (vm_offset_t)(SCSIBase + SBC_DMA_OFS_IIFX);
247 sc->sc_options &= ~(SBC_INTR | SBC_RESELECT);
248 break;
249 case MACH_MACPB500:
250 sc->sc_regs = (struct sbc_regs *)(SCSIBase + SBC_REG_OFS);
251 sc->sc_drq_addr = (vm_offset_t)(SCSIBase + SBC_HSK_OFS); /*??*/
252 sc->sc_nodrq_addr = (vm_offset_t)(SCSIBase + SBC_DMA_OFS_PB500);
253 sc->sc_options &= ~(SBC_INTR | SBC_RESELECT);
254 break;
255 default:
256 sc->sc_regs = (struct sbc_regs *)(SCSIBase + SBC_REG_OFS);
257 sc->sc_drq_addr = (vm_offset_t)(SCSIBase + SBC_HSK_OFS);
258 sc->sc_nodrq_addr = (vm_offset_t)(SCSIBase + SBC_DMA_OFS);
259 break;
260 }
261
262 /*
263 * Fill in the prototype scsi_link.
264 */
265 ncr_sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
266 ncr_sc->sc_link.adapter_softc = sc;
267 ncr_sc->sc_link.adapter_target = 7;
268 ncr_sc->sc_link.adapter = &sbc_ops;
269 ncr_sc->sc_link.device = &sbc_dev;
270
271 /*
272 * Initialize fields used by the MI code
273 */
274 ncr_sc->sci_r0 = &sc->sc_regs->sci_pr0.sci_reg;
275 ncr_sc->sci_r1 = &sc->sc_regs->sci_pr1.sci_reg;
276 ncr_sc->sci_r2 = &sc->sc_regs->sci_pr2.sci_reg;
277 ncr_sc->sci_r3 = &sc->sc_regs->sci_pr3.sci_reg;
278 ncr_sc->sci_r4 = &sc->sc_regs->sci_pr4.sci_reg;
279 ncr_sc->sci_r5 = &sc->sc_regs->sci_pr5.sci_reg;
280 ncr_sc->sci_r6 = &sc->sc_regs->sci_pr6.sci_reg;
281 ncr_sc->sci_r7 = &sc->sc_regs->sci_pr7.sci_reg;
282
283 /*
284 * MD function pointers used by the MI code.
285 */
286 if (sc->sc_options & SBC_PDMA) {
287 ncr_sc->sc_pio_out = sbc_pdma_out;
288 ncr_sc->sc_pio_in = sbc_pdma_in;
289 } else {
290 ncr_sc->sc_pio_out = ncr5380_pio_out;
291 ncr_sc->sc_pio_in = ncr5380_pio_in;
292 }
293 ncr_sc->sc_dma_alloc = NULL;
294 ncr_sc->sc_dma_free = NULL;
295 ncr_sc->sc_dma_poll = NULL;
296 ncr_sc->sc_intr_on = NULL;
297 ncr_sc->sc_intr_off = NULL;
298 ncr_sc->sc_dma_setup = NULL;
299 ncr_sc->sc_dma_start = NULL;
300 ncr_sc->sc_dma_eop = NULL;
301 ncr_sc->sc_dma_stop = NULL;
302 ncr_sc->sc_flags = 0;
303 ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
304
305 if (sc->sc_options & SBC_INTR) {
306 if (sc->sc_options & SBC_RESELECT)
307 ncr_sc->sc_flags |= NCR5380_PERMIT_RESELECT;
308 ncr_sc->sc_dma_alloc = sbc_dma_alloc;
309 ncr_sc->sc_dma_free = sbc_dma_free;
310 ncr_sc->sc_dma_poll = sbc_dma_poll;
311 ncr_sc->sc_dma_setup = sbc_dma_setup;
312 ncr_sc->sc_dma_start = sbc_dma_start;
313 ncr_sc->sc_dma_eop = sbc_dma_eop;
314 ncr_sc->sc_dma_stop = sbc_dma_stop;
315 mac68k_register_scsi_drq(sbc_drq_intr, ncr_sc);
316 mac68k_register_scsi_irq(sbc_irq_intr, ncr_sc);
317 } else
318 ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
319
320 /*
321 * Initialize fields used only here in the MD code.
322 */
323 if (VIA2 == VIA2OFF) {
324 sc->sc_ienable = Via1Base + VIA2 * 0x2000 + vIER;
325 sc->sc_iflag = Via1Base + VIA2 * 0x2000 + vIFR;
326 } else {
327 sc->sc_ienable = Via1Base + VIA2 * 0x2000 + rIER;
328 sc->sc_iflag = Via1Base + VIA2 * 0x2000 + rIFR;
329 }
330
331 if (sc->sc_options)
332 printf(": options=%s", bitmask_snprintf(sc->sc_options,
333 SBC_OPTIONS_BITS, bits, sizeof(bits)));
334 printf("\n");
335
336 /* Now enable SCSI interrupts through VIA2, if appropriate */
337 if (sc->sc_options & SBC_INTR)
338 sbc_intr_enable(ncr_sc);
339
340 #ifdef SBC_DEBUG
341 if (sbc_debug)
342 printf("%s: softc=%p regs=%p\n", ncr_sc->sc_dev.dv_xname,
343 sc, sc->sc_regs);
344 ncr_sc->sc_link.flags |= sbc_link_flags;
345 #endif
346
347 /*
348 * Initialize the SCSI controller itself.
349 */
350 ncr5380_init(ncr_sc);
351 ncr5380_reset_scsibus(ncr_sc);
352 config_found(self, &(ncr_sc->sc_link), scsiprint);
353 }
354
355 static void
356 sbc_minphys(struct buf *bp)
357 {
358 if (bp->b_bcount > MAX_DMA_LEN)
359 bp->b_bcount = MAX_DMA_LEN;
360 return (minphys(bp));
361 }
362
363
364 /***
365 * General support for Mac-specific SCSI logic.
366 ***/
367
368 /* These are used in the following inline functions. */
369 int sbc_wait_busy_timo = 1000 * 5000; /* X2 = 10 S. */
370 int sbc_ready_timo = 1000 * 5000; /* X2 = 10 S. */
371 int sbc_wait_dreq_timo = 1000 * 5000; /* X2 = 10 S. */
372
373 /* Return zero on success. */
374 static __inline__ int
375 sbc_wait_busy(sc)
376 struct ncr5380_softc *sc;
377 {
378 register int timo = sbc_wait_busy_timo;
379 for (;;) {
380 if (SCI_BUSY(sc)) {
381 timo = 0; /* return 0 */
382 break;
383 }
384 if (--timo < 0)
385 break; /* return -1 */
386 delay(2);
387 }
388 return (timo);
389 }
390
391 static __inline__ int
392 sbc_ready(sc)
393 struct ncr5380_softc *sc;
394 {
395 register int timo = sbc_ready_timo;
396
397 for (;;) {
398 if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
399 == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
400 timo = 0;
401 break;
402 }
403 if (((*sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0)
404 || (SCI_BUSY(sc) == 0)) {
405 timo = -1;
406 break;
407 }
408 if (--timo < 0)
409 break; /* return -1 */
410 delay(2);
411 }
412 return (timo);
413 }
414
415 static __inline__ int
416 sbc_wait_dreq(sc)
417 struct ncr5380_softc *sc;
418 {
419 register int timo = sbc_wait_dreq_timo;
420
421 for (;;) {
422 if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
423 == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
424 timo = 0;
425 break;
426 }
427 if (--timo < 0)
428 break; /* return -1 */
429 delay(2);
430 }
431 return (timo);
432 }
433
434
435 /***
436 * Macintosh SCSI interrupt support routines.
437 ***/
438
439 void
440 sbc_intr_enable(ncr_sc)
441 struct ncr5380_softc *ncr_sc;
442 {
443 register struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
444 int s;
445
446 s = splhigh();
447 *sc->sc_ienable = 0x80 | (V2IF_SCSIIRQ | V2IF_SCSIDRQ);
448 splx(s);
449 }
450
451 void
452 sbc_intr_disable(ncr_sc)
453 struct ncr5380_softc *ncr_sc;
454 {
455 register struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
456 int s;
457
458 s = splhigh();
459 *sc->sc_ienable = (V2IF_SCSIIRQ | V2IF_SCSIDRQ);
460 splx(s);
461 }
462
463 void
464 sbc_irq_intr(p)
465 void *p;
466 {
467 register struct ncr5380_softc *ncr_sc = p;
468 register int claimed = 0;
469
470 /* How we ever arrive here without IRQ set is a mystery... */
471 if (*ncr_sc->sci_csr & SCI_CSR_INT) {
472 #ifdef SBC_DEBUG
473 if (sbc_debug & SBC_DB_INTR)
474 decode_5380_intr(ncr_sc);
475 #endif
476 claimed = ncr5380_intr(ncr_sc);
477 if (!claimed) {
478 if (((*ncr_sc->sci_csr & ~SCI_CSR_PHASE_MATCH) == SCI_CSR_INT)
479 && ((*ncr_sc->sci_bus_csr & ~SCI_BUS_RST) == 0))
480 SCI_CLR_INTR(ncr_sc); /* RST interrupt */
481 #ifdef SBC_DEBUG
482 else {
483 printf("%s: spurious intr\n",
484 ncr_sc->sc_dev.dv_xname);
485 SBC_BREAK;
486 }
487 #endif
488 }
489 }
490 }
491
492 #ifdef SBC_DEBUG
493 void
494 decode_5380_intr(ncr_sc)
495 struct ncr5380_softc *ncr_sc;
496 {
497 register u_char csr = *ncr_sc->sci_csr;
498 register u_char bus_csr = *ncr_sc->sci_bus_csr;
499
500 if (((csr & ~(SCI_CSR_PHASE_MATCH | SCI_CSR_ATN)) == SCI_CSR_INT) &&
501 ((bus_csr & ~(SCI_BUS_MSG | SCI_BUS_CD | SCI_BUS_IO | SCI_BUS_DBP)) == SCI_BUS_SEL)) {
502 if (csr & SCI_BUS_IO)
503 printf("%s: reselect\n", ncr_sc->sc_dev.dv_xname);
504 else
505 printf("%s: select\n", ncr_sc->sc_dev.dv_xname);
506 } else if (((csr & ~SCI_CSR_ACK) == (SCI_CSR_DONE | SCI_CSR_INT)) &&
507 ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_SEL)) == SCI_BUS_BSY))
508 printf("%s: dma eop\n", ncr_sc->sc_dev.dv_xname);
509 else if (((csr & ~SCI_CSR_PHASE_MATCH) == SCI_CSR_INT) &&
510 ((bus_csr & ~SCI_BUS_RST) == 0))
511 printf("%s: bus reset\n", ncr_sc->sc_dev.dv_xname);
512 else if (((csr & ~(SCI_CSR_DREQ | SCI_CSR_ATN | SCI_CSR_ACK)) == (SCI_CSR_PERR | SCI_CSR_INT | SCI_CSR_PHASE_MATCH)) &&
513 ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_SEL)) == SCI_BUS_BSY))
514 printf("%s: parity error\n", ncr_sc->sc_dev.dv_xname);
515 else if (((csr & ~SCI_CSR_ATN) == SCI_CSR_INT) &&
516 ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_REQ | SCI_BUS_SEL)) == (SCI_BUS_BSY | SCI_BUS_REQ)))
517 printf("%s: phase mismatch\n", ncr_sc->sc_dev.dv_xname);
518 else if (((csr & ~SCI_CSR_PHASE_MATCH) == (SCI_CSR_INT | SCI_CSR_DISC)) &&
519 (bus_csr == 0))
520 printf("%s: disconnect\n", ncr_sc->sc_dev.dv_xname);
521 else
522 printf("%s: unknown intr: csr=%x, bus_csr=%x\n",
523 ncr_sc->sc_dev.dv_xname, csr, bus_csr);
524 }
525 #endif
526
527
528 /***
529 * The following code implements polled PDMA.
530 ***/
531
532 static int
533 sbc_pdma_out(ncr_sc, phase, count, data)
534 struct ncr5380_softc *ncr_sc;
535 int phase;
536 int count;
537 u_char *data;
538 {
539 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
540 register volatile long *long_data = (long *) sc->sc_drq_addr;
541 register volatile u_char *byte_data = (u_char *) sc->sc_nodrq_addr;
542 register int len = count;
543
544 if (count < ncr_sc->sc_min_dma_len || (sc->sc_options & SBC_PDMA) == 0)
545 return ncr5380_pio_out(ncr_sc, phase, count, data);
546
547 if (sbc_wait_busy(ncr_sc) == 0) {
548 *ncr_sc->sci_mode |= SCI_MODE_DMA;
549 *ncr_sc->sci_icmd |= SCI_ICMD_DATA;
550 *ncr_sc->sci_dma_send = 0;
551
552 #define W1 *byte_data = *data++
553 #define W4 *long_data = *((long*)data)++
554 while (len >= 64) {
555 if (sbc_ready(ncr_sc))
556 goto timeout;
557 W1;
558 if (sbc_ready(ncr_sc))
559 goto timeout;
560 W1;
561 if (sbc_ready(ncr_sc))
562 goto timeout;
563 W1;
564 if (sbc_ready(ncr_sc))
565 goto timeout;
566 W1;
567 if (sbc_ready(ncr_sc))
568 goto timeout;
569 W4; W4; W4; W4;
570 W4; W4; W4; W4;
571 W4; W4; W4; W4;
572 W4; W4; W4;
573 len -= 64;
574 }
575 while (len) {
576 if (sbc_ready(ncr_sc))
577 goto timeout;
578 W1;
579 len--;
580 }
581 #undef W1
582 #undef W4
583 if (sbc_wait_dreq(ncr_sc))
584 printf("%s: timeout waiting for DREQ.\n",
585 ncr_sc->sc_dev.dv_xname);
586
587 *byte_data = 0;
588
589 SCI_CLR_INTR(ncr_sc);
590 *ncr_sc->sci_mode &= ~SCI_MODE_DMA;
591 *ncr_sc->sci_icmd = 0;
592 }
593 return count - len;
594
595 timeout:
596 printf("%s: pdma_out: timeout len=%d count=%d\n",
597 ncr_sc->sc_dev.dv_xname, len, count);
598 if ((*ncr_sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0) {
599 *ncr_sc->sci_icmd &= ~SCI_ICMD_DATA;
600 --len;
601 }
602
603 SCI_CLR_INTR(ncr_sc);
604 *ncr_sc->sci_mode &= ~SCI_MODE_DMA;
605 *ncr_sc->sci_icmd = 0;
606 return count - len;
607 }
608
609 static int
610 sbc_pdma_in(ncr_sc, phase, count, data)
611 struct ncr5380_softc *ncr_sc;
612 int phase;
613 int count;
614 u_char *data;
615 {
616 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc;
617 register volatile long *long_data = (long *) sc->sc_drq_addr;
618 register volatile u_char *byte_data = (u_char *) sc->sc_nodrq_addr;
619 register int len = count;
620
621 if (count < ncr_sc->sc_min_dma_len || (sc->sc_options & SBC_PDMA) == 0)
622 return ncr5380_pio_in(ncr_sc, phase, count, data);
623
624 if (sbc_wait_busy(ncr_sc) == 0) {
625 *ncr_sc->sci_mode |= SCI_MODE_DMA;
626 *ncr_sc->sci_icmd |= SCI_ICMD_DATA;
627 *ncr_sc->sci_irecv = 0;
628
629 #define R4 *((long *)data)++ = *long_data
630 #define R1 *data++ = *byte_data
631 while (len >= 1024) {
632 if (sbc_ready(ncr_sc))
633 goto timeout;
634 R4; R4; R4; R4; R4; R4; R4; R4;
635 R4; R4; R4; R4; R4; R4; R4; R4;
636 R4; R4; R4; R4; R4; R4; R4; R4;
637 R4; R4; R4; R4; R4; R4; R4; R4; /* 128 */
638 if (sbc_ready(ncr_sc))
639 goto timeout;
640 R4; R4; R4; R4; R4; R4; R4; R4;
641 R4; R4; R4; R4; R4; R4; R4; R4;
642 R4; R4; R4; R4; R4; R4; R4; R4;
643 R4; R4; R4; R4; R4; R4; R4; R4; /* 256 */
644 if (sbc_ready(ncr_sc))
645 goto timeout;
646 R4; R4; R4; R4; R4; R4; R4; R4;
647 R4; R4; R4; R4; R4; R4; R4; R4;
648 R4; R4; R4; R4; R4; R4; R4; R4;
649 R4; R4; R4; R4; R4; R4; R4; R4; /* 384 */
650 if (sbc_ready(ncr_sc))
651 goto timeout;
652 R4; R4; R4; R4; R4; R4; R4; R4;
653 R4; R4; R4; R4; R4; R4; R4; R4;
654 R4; R4; R4; R4; R4; R4; R4; R4;
655 R4; R4; R4; R4; R4; R4; R4; R4; /* 512 */
656 if (sbc_ready(ncr_sc))
657 goto timeout;
658 R4; R4; R4; R4; R4; R4; R4; R4;
659 R4; R4; R4; R4; R4; R4; R4; R4;
660 R4; R4; R4; R4; R4; R4; R4; R4;
661 R4; R4; R4; R4; R4; R4; R4; R4; /* 640 */
662 if (sbc_ready(ncr_sc))
663 goto timeout;
664 R4; R4; R4; R4; R4; R4; R4; R4;
665 R4; R4; R4; R4; R4; R4; R4; R4;
666 R4; R4; R4; R4; R4; R4; R4; R4;
667 R4; R4; R4; R4; R4; R4; R4; R4; /* 768 */
668 if (sbc_ready(ncr_sc))
669 goto timeout;
670 R4; R4; R4; R4; R4; R4; R4; R4;
671 R4; R4; R4; R4; R4; R4; R4; R4;
672 R4; R4; R4; R4; R4; R4; R4; R4;
673 R4; R4; R4; R4; R4; R4; R4; R4; /* 896 */
674 if (sbc_ready(ncr_sc))
675 goto timeout;
676 R4; R4; R4; R4; R4; R4; R4; R4;
677 R4; R4; R4; R4; R4; R4; R4; R4;
678 R4; R4; R4; R4; R4; R4; R4; R4;
679 R4; R4; R4; R4; R4; R4; R4; R4; /* 1024 */
680 len -= 1024;
681 }
682 while (len >= 128) {
683 if (sbc_ready(ncr_sc))
684 goto timeout;
685 R4; R4; R4; R4; R4; R4; R4; R4;
686 R4; R4; R4; R4; R4; R4; R4; R4;
687 R4; R4; R4; R4; R4; R4; R4; R4;
688 R4; R4; R4; R4; R4; R4; R4; R4; /* 128 */
689 len -= 128;
690 }
691 while (len) {
692 if (sbc_ready(ncr_sc))
693 goto timeout;
694 R1;
695 len--;
696 }
697 #undef R4
698 #undef R1
699 SCI_CLR_INTR(ncr_sc);
700 *ncr_sc->sci_mode &= ~SCI_MODE_DMA;
701 *ncr_sc->sci_icmd = 0;
702 }
703 return count - len;
704
705 timeout:
706 printf("%s: pdma_in: timeout len=%d count=%d\n",
707 ncr_sc->sc_dev.dv_xname, len, count);
708
709 SCI_CLR_INTR(ncr_sc);
710 *ncr_sc->sci_mode &= ~SCI_MODE_DMA;
711 *ncr_sc->sci_icmd = 0;
712 return count - len;
713 }
714
715
716 /***
717 * The following code implements interrupt-driven PDMA.
718 ***/
719
720 /*
721 * This is the meat of the PDMA transfer.
722 * When we get here, we shove data as fast as the mac can take it.
723 * We depend on several things:
724 * * All macs after the Mac Plus that have a 5380 chip should have a general
725 * logic IC that handshakes data for blind transfers.
726 * * If the SCSI controller finishes sending/receiving data before we do,
727 * the same general logic IC will generate a /BERR for us in short order.
728 * * The fault address for said /BERR minus the base address for the
729 * transfer will be the amount of data that was actually written.
730 *
731 * We use the nofault flag and the setjmp/longjmp in locore.s so we can
732 * detect and handle the bus error for early termination of a command.
733 * This is usually caused by a disconnecting target.
734 */
735 void
736 sbc_drq_intr(p)
737 void *p;
738 {
739 extern int *nofault, mac68k_buserr_addr;
740 register struct sbc_softc *sc = (struct sbc_softc *) p;
741 register struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *) p;
742 register struct sci_req *sr = ncr_sc->sc_current;
743 register struct sbc_pdma_handle *dh = sr->sr_dma_hand;
744 label_t faultbuf;
745 volatile u_int32_t *long_drq;
746 u_int32_t *long_data;
747 volatile u_int8_t *drq;
748 u_int8_t *data;
749 register int count;
750 int dcount, resid;
751 u_int8_t tmp;
752
753 /*
754 * If we're not ready to xfer data, or have no more, just return.
755 */
756 if ((*ncr_sc->sci_csr & SCI_CSR_DREQ) == 0 || dh->dh_len == 0)
757 return;
758
759 #ifdef SBC_DEBUG
760 if (sbc_debug & SBC_DB_INTR)
761 printf("%s: drq intr, dh_len=0x%x, dh_flags=0x%x\n",
762 ncr_sc->sc_dev.dv_xname, dh->dh_len, dh->dh_flags);
763 #endif
764
765 /*
766 * Setup for a possible bus error caused by SCSI controller
767 * switching out of DATA-IN/OUT before we're done with the
768 * current transfer.
769 */
770 nofault = (int *) &faultbuf;
771
772 if (setjmp((label_t *) nofault)) {
773 nofault = (int *) 0;
774 if ((dh->dh_flags & SBC_DH_DONE) == 0) {
775 count = (( (u_long) mac68k_buserr_addr
776 - (u_long) sc->sc_drq_addr));
777
778 if ((count < 0) || (count > dh->dh_len)) {
779 printf("%s: complete=0x%x (pending 0x%x)\n",
780 ncr_sc->sc_dev.dv_xname, count, dh->dh_len);
781 panic("something is wrong");
782 }
783
784 dh->dh_addr += count;
785 dh->dh_len -= count;
786 }
787
788 #ifdef SBC_DEBUG
789 if (sbc_debug & SBC_DB_INTR)
790 printf("%s: drq /berr, complete=0x%x (pending 0x%x)\n",
791 ncr_sc->sc_dev.dv_xname, count, dh->dh_len);
792 #endif
793 mac68k_buserr_addr = 0;
794
795 return;
796 }
797
798 if (dh->dh_flags & SBC_DH_OUT) { /* Data Out */
799 #if notyet /* XXX */
800 /*
801 * Get the source address aligned.
802 */
803 resid =
804 count = min(dh->dh_len, 4 - (((int) dh->dh_addr) & 0x3));
805 if (count && count < 4) {
806 drq = (volatile u_int8_t *) sc->sc_drq_addr;
807 data = (u_int8_t *) dh->dh_addr;
808
809 #define W1 *drq++ = *data++
810 while (count) {
811 W1; count--;
812 }
813 #undef W1
814 dh->dh_addr += resid;
815 dh->dh_len -= resid;
816 }
817
818 /*
819 * Start the transfer.
820 */
821 while (dh->dh_len) {
822 dcount = count = min(dh->dh_len, MAX_DMA_LEN);
823 long_drq = (volatile u_int32_t *) sc->sc_drq_addr;
824 long_data = (u_int32_t *) dh->dh_addr;
825
826 #define W4 *long_drq++ = *long_data++
827 while (count >= 64) {
828 W4; W4; W4; W4; W4; W4; W4; W4;
829 W4; W4; W4; W4; W4; W4; W4; W4; /* 64 */
830 count -= 64;
831 }
832 while (count >= 4) {
833 W4; count -= 4;
834 }
835 #undef W4
836 data = (u_int8_t *) long_data;
837 drq = (u_int8_t *) long_drq;
838 #else /* notyet */
839 /*
840 * Start the transfer.
841 */
842 while (dh->dh_len) {
843 dcount = count = min(dh->dh_len, MAX_DMA_LEN);
844 drq = (volatile u_int8_t *) sc->sc_drq_addr;
845 data = (u_int8_t *) dh->dh_addr;
846 #endif /* notyet */
847
848 #define W1 *drq++ = *data++
849 while (count) {
850 W1; count--;
851 }
852 #undef W1
853 dh->dh_len -= dcount;
854 dh->dh_addr += dcount;
855 }
856 dh->dh_flags |= SBC_DH_DONE;
857
858 /*
859 * XXX -- Read a byte from the SBC to trigger a /BERR.
860 * This seems to be necessary for us to notice that
861 * the target has disconnected. Ick. 06 jun 1996 (sr)
862 */
863 if (dcount >= MAX_DMA_LEN) {
864 #if 0
865 while ((*ncr_sc->sci_csr & SCI_CSR_ACK) == 0)
866 ;
867 #endif
868 drq = (volatile u_int8_t *) sc->sc_drq_addr;
869 }
870 tmp = *drq;
871 } else { /* Data In */
872 /*
873 * Get the dest address aligned.
874 */
875 resid =
876 count = min(dh->dh_len, 4 - (((int) dh->dh_addr) & 0x3));
877 if (count && count < 4) {
878 data = (u_int8_t *) dh->dh_addr;
879 drq = (volatile u_int8_t *) sc->sc_drq_addr;
880
881 #define R1 *data++ = *drq++
882 while (count) {
883 R1; count--;
884 }
885 #undef R1
886 dh->dh_addr += resid;
887 dh->dh_len -= resid;
888 }
889
890 /*
891 * Start the transfer.
892 */
893 while (dh->dh_len) {
894 dcount = count = min(dh->dh_len, MAX_DMA_LEN);
895 long_data = (u_int32_t *) dh->dh_addr;
896 long_drq = (volatile u_int32_t *) sc->sc_drq_addr;
897
898 #define R4 *long_data++ = *long_drq++
899 while (count >= 64) {
900 R4; R4; R4; R4; R4; R4; R4; R4;
901 R4; R4; R4; R4; R4; R4; R4; R4; /* 64 */
902 count -= 64;
903 }
904 while (count >= 4) {
905 R4; count -= 4;
906 }
907 #undef R4
908 data = (u_int8_t *) long_data;
909 drq = (volatile u_int8_t *) long_drq;
910
911 #define R1 *data++ = *drq++
912 while (count) {
913 R1; count--;
914 }
915 #undef R1
916 dh->dh_len -= dcount;
917 dh->dh_addr += dcount;
918 }
919 dh->dh_flags |= SBC_DH_DONE;
920 }
921
922 /*
923 * OK. No bus error occurred above. Clear the nofault flag
924 * so we no longer short-circuit bus errors.
925 */
926 nofault = (int *) 0;
927
928 #ifdef SBC_DEBUG
929 if (sbc_debug & (SBC_DB_REG | SBC_DB_INTR))
930 printf("%s: drq intr complete: csr=0x%x, bus_csr=0x%x\n",
931 ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr,
932 *ncr_sc->sci_bus_csr);
933 #endif
934 }
935
936 void
937 sbc_dma_alloc(ncr_sc)
938 struct ncr5380_softc *ncr_sc;
939 {
940 struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
941 struct sci_req *sr = ncr_sc->sc_current;
942 struct scsi_xfer *xs = sr->sr_xs;
943 struct sbc_pdma_handle *dh;
944 int i, xlen;
945
946 #ifdef DIAGNOSTIC
947 if (sr->sr_dma_hand != NULL)
948 panic("sbc_dma_alloc: already have PDMA handle");
949 #endif
950
951 /* Polled transfers shouldn't allocate a PDMA handle. */
952 if (sr->sr_flags & SR_IMMED)
953 return;
954
955 xlen = ncr_sc->sc_datalen;
956
957 /* Make sure our caller checked sc_min_dma_len. */
958 if (xlen < MIN_DMA_LEN)
959 panic("sbc_dma_alloc: len=0x%x\n", xlen);
960
961 /*
962 * Find free PDMA handle. Guaranteed to find one since we
963 * have as many PDMA handles as the driver has processes.
964 * (instances?)
965 */
966 for (i = 0; i < SCI_OPENINGS; i++) {
967 if ((sc->sc_pdma[i].dh_flags & SBC_DH_BUSY) == 0)
968 goto found;
969 }
970 panic("sbc: no free PDMA handles");
971 found:
972 dh = &sc->sc_pdma[i];
973 dh->dh_flags = SBC_DH_BUSY;
974 dh->dh_addr = ncr_sc->sc_dataptr;
975 dh->dh_len = xlen;
976
977 /* Copy the 'write' flag for convenience. */
978 if (xs->flags & SCSI_DATA_OUT)
979 dh->dh_flags |= SBC_DH_OUT;
980
981 sr->sr_dma_hand = dh;
982 }
983
984 void
985 sbc_dma_free(ncr_sc)
986 struct ncr5380_softc *ncr_sc;
987 {
988 struct sci_req *sr = ncr_sc->sc_current;
989 struct sbc_pdma_handle *dh = sr->sr_dma_hand;
990
991 #ifdef DIAGNOSTIC
992 if (sr->sr_dma_hand == NULL)
993 panic("sbc_dma_free: no DMA handle");
994 #endif
995
996 if (ncr_sc->sc_state & NCR_DOINGDMA)
997 panic("sbc_dma_free: free while in progress");
998
999 if (dh->dh_flags & SBC_DH_BUSY) {
1000 dh->dh_flags = 0;
1001 dh->dh_addr = NULL;
1002 dh->dh_len = 0;
1003 }
1004 sr->sr_dma_hand = NULL;
1005 }
1006
1007 void
1008 sbc_dma_poll(ncr_sc)
1009 struct ncr5380_softc *ncr_sc;
1010 {
1011 struct sci_req *sr = ncr_sc->sc_current;
1012
1013 /*
1014 * We shouldn't arrive here; if SR_IMMED is set, then
1015 * dma_alloc() should have refused to allocate a handle
1016 * for the transfer. This forces the polled PDMA code
1017 * to handle the request...
1018 */
1019 #ifdef SBC_DEBUG
1020 if (sbc_debug & SBC_DB_DMA)
1021 printf("%s: lost DRQ interrupt?\n", ncr_sc->sc_dev.dv_xname);
1022 #endif
1023 sr->sr_flags |= SR_OVERDUE;
1024 }
1025
1026 void
1027 sbc_dma_setup(ncr_sc)
1028 struct ncr5380_softc *ncr_sc;
1029 {
1030 /* Not needed; we don't have real DMA */
1031 }
1032
1033 void
1034 sbc_dma_start(ncr_sc)
1035 struct ncr5380_softc *ncr_sc;
1036 {
1037 register struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
1038 struct sci_req *sr = ncr_sc->sc_current;
1039 struct sbc_pdma_handle *dh = sr->sr_dma_hand;
1040
1041 /*
1042 * Match bus phase, clear pending interrupts, set DMA mode, and
1043 * assert data bus (for writing only), then start the transfer.
1044 */
1045 if (dh->dh_flags & SBC_DH_OUT) {
1046 *ncr_sc->sci_tcmd = PHASE_DATA_OUT;
1047 SCI_CLR_INTR(ncr_sc);
1048 *sc->sc_iflag = 0x80 | (V2IF_SCSIIRQ | V2IF_SCSIDRQ);
1049 *ncr_sc->sci_mode |= SCI_MODE_DMA;
1050 *ncr_sc->sci_icmd = SCI_ICMD_DATA;
1051 *ncr_sc->sci_dma_send = 0;
1052 } else {
1053 *ncr_sc->sci_tcmd = PHASE_DATA_IN;
1054 SCI_CLR_INTR(ncr_sc);
1055 *sc->sc_iflag = 0x80 | (V2IF_SCSIIRQ | V2IF_SCSIDRQ);
1056 *ncr_sc->sci_mode |= SCI_MODE_DMA;
1057 *ncr_sc->sci_icmd = 0;
1058 *ncr_sc->sci_irecv = 0;
1059 }
1060 ncr_sc->sc_state |= NCR_DOINGDMA;
1061
1062 #ifdef SBC_DEBUG
1063 if (sbc_debug & SBC_DB_DMA)
1064 printf("%s: PDMA started, va=%p, len=0x%x\n",
1065 ncr_sc->sc_dev.dv_xname, dh->dh_addr, dh->dh_len);
1066 #endif
1067 }
1068
1069 void
1070 sbc_dma_eop(ncr_sc)
1071 struct ncr5380_softc *ncr_sc;
1072 {
1073 /* Not used; the EOP pin is wired high (GMFH, pp. 389-390) */
1074 }
1075
1076 void
1077 sbc_dma_stop(ncr_sc)
1078 struct ncr5380_softc *ncr_sc;
1079 {
1080 register struct sbc_softc *sc = (struct sbc_softc *) ncr_sc;
1081 struct sci_req *sr = ncr_sc->sc_current;
1082 struct sbc_pdma_handle *dh = sr->sr_dma_hand;
1083 register int ntrans;
1084
1085 if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) {
1086 #ifdef SBC_DEBUG
1087 if (sbc_debug & SBC_DB_DMA)
1088 printf("%s: dma_stop: DMA not running\n",
1089 ncr_sc->sc_dev.dv_xname);
1090 #endif
1091 return;
1092 }
1093 ncr_sc->sc_state &= ~NCR_DOINGDMA;
1094
1095 if ((ncr_sc->sc_state & NCR_ABORTING) == 0) {
1096 ntrans = ncr_sc->sc_datalen - dh->dh_len;
1097
1098 #ifdef SBC_DEBUG
1099 if (sbc_debug & SBC_DB_DMA)
1100 printf("%s: dma_stop: ntrans=0x%x\n",
1101 ncr_sc->sc_dev.dv_xname, ntrans);
1102 #endif
1103
1104 if (ntrans > ncr_sc->sc_datalen)
1105 panic("sbc_dma_stop: excess transfer\n");
1106
1107 /* Adjust data pointer */
1108 ncr_sc->sc_dataptr += ntrans;
1109 ncr_sc->sc_datalen -= ntrans;
1110
1111 /* Clear any pending interrupts. */
1112 SCI_CLR_INTR(ncr_sc);
1113 *sc->sc_iflag = 0x80 | V2IF_SCSIIRQ;
1114 }
1115
1116 /* Put SBIC back into PIO mode. */
1117 *ncr_sc->sci_mode &= ~SCI_MODE_DMA;
1118 *ncr_sc->sci_icmd = 0;
1119
1120 #ifdef SBC_DEBUG
1121 if (sbc_debug & SBC_DB_REG)
1122 printf("%s: dma_stop: csr=0x%x, bus_csr=0x%x\n",
1123 ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr,
1124 *ncr_sc->sci_bus_csr);
1125 #endif
1126 }
1127