asc_tc.c revision 1.7 1 1.7 mhitch /* $NetBSD: asc_tc.c,v 1.7 1997/07/28 19:39:26 mhitch Exp $ */
2 1.1 jonathan
3 1.1 jonathan /*
4 1.1 jonathan * Copyright 1996 The Board of Trustees of The Leland Stanford
5 1.1 jonathan * Junior University. All Rights Reserved.
6 1.1 jonathan *
7 1.1 jonathan * Permission to use, copy, modify, and distribute this
8 1.1 jonathan * software and its documentation for any purpose and without
9 1.1 jonathan * fee is hereby granted, provided that the above copyright
10 1.1 jonathan * notice appear in all copies. Stanford University
11 1.1 jonathan * makes no representations about the suitability of this
12 1.1 jonathan * software for any purpose. It is provided "as is" without
13 1.1 jonathan * express or implied warranty.
14 1.1 jonathan *
15 1.1 jonathan */
16 1.1 jonathan
17 1.1 jonathan #include <sys/param.h>
18 1.1 jonathan #include <sys/systm.h>
19 1.1 jonathan #include <sys/types.h>
20 1.1 jonathan #include <sys/device.h>
21 1.1 jonathan #include <dev/tc/tcvar.h>
22 1.1 jonathan #include <machine/autoconf.h>
23 1.1 jonathan #include <dev/tc/ioasicvar.h>
24 1.1 jonathan
25 1.1 jonathan #include <pmax/dev/device.h> /* XXX */
26 1.1 jonathan #include <pmax/dev/scsi.h> /* XXX */
27 1.1 jonathan
28 1.1 jonathan #include <pmax/dev/ascreg.h> /* XXX */
29 1.1 jonathan #include <dev/tc/ascvar.h>
30 1.1 jonathan
31 1.1 jonathan /*XXX*/
32 1.1 jonathan
33 1.1 jonathan
34 1.1 jonathan /*
35 1.1 jonathan * Autoconfiguration data for config.
36 1.1 jonathan */
37 1.6 jonathan int asc_tc_match __P((struct device *, struct cfdata *, void *));
38 1.1 jonathan void asc_tc_attach __P((struct device *, struct device *, void *));
39 1.1 jonathan
40 1.1 jonathan struct cfattach asc_tc_ca = {
41 1.1 jonathan sizeof(struct asc_softc), asc_tc_match, asc_tc_attach
42 1.1 jonathan };
43 1.1 jonathan
44 1.1 jonathan /*
45 1.1 jonathan * DMA callbacks
46 1.1 jonathan */
47 1.1 jonathan
48 1.7 mhitch static int
49 1.1 jonathan tc_dma_start __P((struct asc_softc *asc, struct scsi_state *state,
50 1.7 mhitch caddr_t cp, int flag, int len, int off));
51 1.1 jonathan
52 1.1 jonathan static void
53 1.1 jonathan tc_dma_end __P((struct asc_softc *asc, struct scsi_state *state,
54 1.1 jonathan int flag));
55 1.1 jonathan
56 1.1 jonathan
57 1.1 jonathan int
58 1.1 jonathan asc_tc_match(parent, match, aux)
59 1.1 jonathan struct device *parent;
60 1.6 jonathan struct cfdata *match;
61 1.1 jonathan void *aux;
62 1.1 jonathan {
63 1.1 jonathan struct tc_attach_args *t = aux;
64 1.1 jonathan void *ascaddr;
65 1.1 jonathan
66 1.1 jonathan if (strncmp(t->ta_modname, "PMAZ-AA ", TC_ROM_LLEN))
67 1.1 jonathan return (0);
68 1.1 jonathan
69 1.1 jonathan ascaddr = (void*)t->ta_addr;
70 1.1 jonathan
71 1.1 jonathan if (tc_badaddr(ascaddr + ASC_OFFSET_53C94))
72 1.1 jonathan return (0);
73 1.1 jonathan
74 1.1 jonathan return (1);
75 1.1 jonathan }
76 1.1 jonathan
77 1.1 jonathan
78 1.1 jonathan
79 1.1 jonathan void
80 1.1 jonathan asc_tc_attach(parent, self, aux)
81 1.1 jonathan struct device *parent;
82 1.1 jonathan struct device *self;
83 1.1 jonathan void *aux;
84 1.1 jonathan {
85 1.1 jonathan register struct tc_attach_args *t = aux;
86 1.1 jonathan register asc_softc_t asc = (asc_softc_t) self;
87 1.7 mhitch u_char *buff;
88 1.7 mhitch int i, speed;
89 1.1 jonathan
90 1.1 jonathan void *ascaddr;
91 1.1 jonathan int unit;
92 1.1 jonathan
93 1.5 jonathan /* Use uncached address for chip registers. */
94 1.5 jonathan ascaddr = (void*)MIPS_PHYS_TO_KSEG1(t->ta_addr);
95 1.1 jonathan unit = asc->sc_dev.dv_unit;
96 1.1 jonathan
97 1.1 jonathan /*
98 1.1 jonathan * Initialize hw descriptor, cache some pointers
99 1.1 jonathan */
100 1.1 jonathan asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
101 1.1 jonathan
102 1.1 jonathan /*
103 1.1 jonathan * Set up machine dependencies.
104 1.1 jonathan * (1) how to do dma
105 1.1 jonathan * (2) timing based on turbochannel frequency
106 1.1 jonathan */
107 1.1 jonathan
108 1.1 jonathan /*
109 1.1 jonathan * Fall through for turbochannel option.
110 1.1 jonathan */
111 1.1 jonathan asc->dmar = (volatile int *)(ascaddr + ASC_OFFSET_DMAR);
112 1.7 mhitch buff = (u_char *)(ascaddr + ASC_OFFSET_RAM);
113 1.7 mhitch
114 1.7 mhitch /*
115 1.7 mhitch * Statically partition the DMA buffer between targets.
116 1.7 mhitch * This way we will eventually be able to attach/detach
117 1.7 mhitch * drives on-fly. And 18k/target is plenty for normal use.
118 1.7 mhitch */
119 1.7 mhitch
120 1.7 mhitch /*
121 1.7 mhitch * Give each target its own DMA buffer region.
122 1.7 mhitch * We may want to try ping ponging buffers later.
123 1.7 mhitch */
124 1.7 mhitch for (i = 0; i < ASC_NCMD; i++)
125 1.7 mhitch asc->st[i].dmaBufAddr = buff + PER_TGT_DMA_SIZE * i;
126 1.7 mhitch
127 1.1 jonathan asc->dma_start = tc_dma_start;
128 1.1 jonathan asc->dma_end = tc_dma_end;
129 1.1 jonathan
130 1.1 jonathan /*
131 1.1 jonathan * Now for timing. The 3max has a 25Mhz tb whereas the 3min and
132 1.1 jonathan * maxine are 12.5Mhz.
133 1.1 jonathan */
134 1.4 christos printf(" (bus speed: %d) ", t->ta_busspeed);
135 1.1 jonathan
136 1.1 jonathan switch (t->ta_busspeed) {
137 1.1 jonathan case TC_SPEED_25_MHZ:
138 1.1 jonathan speed = ASC_SPEED_25_MHZ;
139 1.1 jonathan break;
140 1.1 jonathan
141 1.1 jonathan default:
142 1.4 christos printf(" (unknown TC speed, assuming 12.5MHz) ");
143 1.1 jonathan /* FALLTHROUGH*/
144 1.1 jonathan case TC_SPEED_12_5_MHZ:
145 1.1 jonathan speed = ASC_SPEED_12_5_MHZ;
146 1.1 jonathan break;
147 1.1 jonathan };
148 1.1 jonathan
149 1.7 mhitch ascattach(asc, speed);
150 1.1 jonathan
151 1.1 jonathan /* tie pseudo-slot to device */
152 1.1 jonathan tc_intr_establish(parent, t->ta_cookie, TC_IPL_BIO,
153 1.1 jonathan asc_intr, asc);
154 1.1 jonathan }
155 1.1 jonathan
156 1.1 jonathan
157 1.1 jonathan /*
158 1.1 jonathan * DMA handling routines. For a turbochannel device, just set the dmar.
159 1.1 jonathan * For the I/O ASIC, handle the actual DMA interface.
160 1.1 jonathan */
161 1.7 mhitch static int
162 1.7 mhitch tc_dma_start(asc, state, cp, flag, len, off)
163 1.1 jonathan asc_softc_t asc;
164 1.1 jonathan State *state;
165 1.1 jonathan caddr_t cp;
166 1.1 jonathan int flag;
167 1.7 mhitch int len;
168 1.7 mhitch int off;
169 1.1 jonathan {
170 1.1 jonathan
171 1.7 mhitch if (len > PER_TGT_DMA_SIZE)
172 1.7 mhitch len = PER_TGT_DMA_SIZE;
173 1.1 jonathan if (flag == ASCDMA_WRITE)
174 1.7 mhitch bcopy(cp, state->dmaBufAddr + off, len);
175 1.7 mhitch if (flag == ASCDMA_WRITE)
176 1.7 mhitch *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(state->dmaBufAddr + off);
177 1.1 jonathan else
178 1.7 mhitch *asc->dmar = ASC_DMA_ADDR(state->dmaBufAddr + off);
179 1.7 mhitch return (len);
180 1.1 jonathan }
181 1.1 jonathan
182 1.1 jonathan static void
183 1.1 jonathan tc_dma_end(asc, state, flag)
184 1.1 jonathan asc_softc_t asc;
185 1.1 jonathan State *state;
186 1.1 jonathan int flag;
187 1.1 jonathan {
188 1.7 mhitch if (flag == ASCDMA_READ)
189 1.7 mhitch bcopy(state->dmaBufAddr, state->buf, state->dmalen);
190 1.1 jonathan }
191