1 /* $OpenBSD: esp.c,v 1.21 2003/06/05 12:27:02 deraadt Exp $ */
2 /* $NetBSD: esp.c,v 1.69 1997/08/27 11:24:18 bouyer 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) 1996 Charles M. Hannum. All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by Charles M. Hannum.
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 /*
65 * Copyright (c) 1994 Peter Galbavy
66 * Copyright (c) 1995 Paul Kranenburg
67 * All rights reserved.
68 *
69 * Redistribution and use in source and binary forms, with or without
70 * modification, are permitted provided that the following conditions
71 * are met:
72 * 1. Redistributions of source code must retain the above copyright
73 * notice, this list of conditions and the following disclaimer.
74 * 2. Redistributions in binary form must reproduce the above copyright
75 * notice, this list of conditions and the following disclaimer in the
76 * documentation and/or other materials provided with the distribution.
77 *
78 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
79 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
81 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
82 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
83 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
84 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
86 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
87 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
88 * POSSIBILITY OF SUCH DAMAGE.
89 */
90
91 /*
92 * Based on aic6360 by Jarle Greipsland
93 *
94 * Acknowledgements: Many of the algorithms used in this driver are
95 * inspired by the work of Julian Elischer (julian@tfs.com) and
96 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
97 */
98
99 #include <sys/types.h>
100 #include <sys/param.h>
101 #include <sys/systm.h>
102 #include <sys/kernel.h>
103 #include <sys/errno.h>
104 #include <sys/ioctl.h>
105 #include <sys/device.h>
106 #include <sys/buf.h>
107 #include <sys/proc.h>
108 #include <sys/user.h>
109 #include <sys/queue.h>
110
111 #include <scsi/scsi_all.h>
112 #include <scsi/scsiconf.h>
113 #include <scsi/scsi_message.h>
114
115 #include <machine/cpu.h>
116 #include <machine/autoconf.h>
117
118 #include <dev/ic/ncr53c9xreg.h>
119 #include <dev/ic/ncr53c9xvar.h>
120
121 #include <sparc/dev/sbusvar.h>
122 #include <sparc/dev/dmareg.h>
123 #include <sparc/dev/dmavar.h>
124 #include <sparc/dev/espvar.h>
125
126 void espattach(struct device *, struct device *, void *);
127 int espmatch(struct device *, void *, void *);
128
129 /* Linkup to the rest of the kernel */
130 struct cfattach esp_ca = {
131 sizeof(struct esp_softc), espmatch, espattach
132 };
133
134 struct scsi_adapter esp_switch = {
135 ncr53c9x_scsi_cmd,
136 minphys, /* no max at this level; handled by DMA code */
137 NULL,
138 NULL,
139 };
140
141 struct scsi_device esp_dev = {
142 NULL, /* Use default error handler */
143 NULL, /* have a queue, served by this */
144 NULL, /* have no async handler */
145 NULL, /* Use default 'done' routine */
146 };
147
148 /*
149 * Functions and the switch for the MI code.
150 */
151 u_char esp_read_reg(struct ncr53c9x_softc *, int);
152 void esp_write_reg(struct ncr53c9x_softc *, int, u_char);
153 int esp_dma_isintr(struct ncr53c9x_softc *);
154 void esp_dma_reset(struct ncr53c9x_softc *);
155 int esp_dma_intr(struct ncr53c9x_softc *);
156 int esp_dma_setup(struct ncr53c9x_softc *, caddr_t *,
157 size_t *, int, size_t *);
158 void esp_dma_go(struct ncr53c9x_softc *);
159 void esp_dma_stop(struct ncr53c9x_softc *);
160 int esp_dma_isactive(struct ncr53c9x_softc *);
161
162 struct ncr53c9x_glue esp_glue = {
163 esp_read_reg,
164 esp_write_reg,
165 esp_dma_isintr,
166 esp_dma_reset,
167 esp_dma_intr,
168 esp_dma_setup,
169 esp_dma_go,
170 esp_dma_stop,
171 esp_dma_isactive,
172 NULL, /* gl_clear_latched_intr */
173 };
174
175 int
espmatch(parent,vcf,aux)176 espmatch(parent, vcf, aux)
177 struct device *parent;
178 void *vcf, *aux;
179 {
180 register struct cfdata *cf = vcf;
181 register struct confargs *ca = aux;
182 register struct romaux *ra = &ca->ca_ra;
183
184 if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
185 return (0);
186 #if defined(SUN4C) || defined(SUN4M)
187 if (ca->ca_bustype == BUS_SBUS) {
188 if (!sbus_testdma((struct sbus_softc *)parent, ca))
189 return (0);
190 return (1);
191 }
192 #endif
193 ra->ra_len = NBPG;
194 return (probeget(ra->ra_vaddr, 1) != -1);
195 }
196
197 /*
198 * Attach this instance, and then all the sub-devices
199 */
200 void
espattach(parent,self,aux)201 espattach(parent, self, aux)
202 struct device *parent, *self;
203 void *aux;
204 {
205 register struct confargs *ca = aux;
206 struct esp_softc *esc = (void *)self;
207 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
208 struct bootpath *bp;
209 int dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
210
211 /*
212 * Set up glue for MI code early; we use some of it here.
213 */
214 sc->sc_glue = &esp_glue;
215
216 /*
217 * Make sure things are sane. I don't know if this is ever
218 * necessary, but it seem to be in all of Torek's code.
219 */
220 if (ca->ca_ra.ra_nintr != 1) {
221 printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
222 return;
223 }
224
225 esc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
226 printf(" pri %d", esc->sc_pri);
227
228 /*
229 * Map my registers in, if they aren't already in virtual
230 * address space.
231 */
232 if (ca->ca_ra.ra_vaddr)
233 esc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
234 else {
235 esc->sc_reg = (volatile u_char *)
236 mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
237 }
238
239 /* Other settings */
240 esc->sc_node = ca->ca_ra.ra_node;
241 if (ca->ca_bustype == BUS_SBUS) {
242 sc->sc_id = getpropint(esc->sc_node, "initiator-id", 7);
243 sc->sc_freq = getpropint(esc->sc_node, "clock-frequency", -1);
244 } else {
245 sc->sc_id = 7;
246 sc->sc_freq = 24000000;
247 }
248 if (sc->sc_freq < 0)
249 sc->sc_freq = ((struct sbus_softc *)
250 sc->sc_dev.dv_parent)->sc_clockfreq;
251
252 /* gimme MHz */
253 sc->sc_freq /= 1000000;
254
255 if (dmachild) {
256 esc->sc_dma = (struct dma_softc *)parent;
257 esc->sc_dma->sc_esp = esc;
258 } else {
259 /*
260 * find the DMA by poking around the dma device structures
261 *
262 * What happens here is that if the dma driver has not been
263 * configured, then this returns a NULL pointer. Then when the
264 * dma actually gets configured, it does the opposing test, and
265 * if the sc->sc_esp field in it's softc is NULL, then tries to
266 * find the matching esp driver.
267 */
268 esc->sc_dma = (struct dma_softc *)
269 getdevunit("dma", sc->sc_dev.dv_unit);
270
271 /*
272 * and a back pointer to us, for DMA
273 */
274 if (esc->sc_dma)
275 esc->sc_dma->sc_esp = esc;
276 else {
277 printf("\n");
278 panic("espattach: no dma found");
279 }
280 }
281
282 /*
283 * XXX More of this should be in ncr53c9x_attach(), but
284 * XXX should we really poke around the chip that much in
285 * XXX the MI code? Think about this more...
286 */
287
288 /*
289 * It is necessary to try to load the 2nd config register here,
290 * to find out what rev the esp chip is, else the ncr53c9x_reset
291 * will not set up the defaults correctly.
292 */
293 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
294 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
295 sc->sc_cfg3 = NCRCFG3_CDB;
296 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
297
298 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
299 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
300 sc->sc_rev = NCR_VARIANT_ESP100;
301 } else {
302 sc->sc_cfg2 = NCRCFG2_SCSI2;
303 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
304 sc->sc_cfg3 = 0;
305 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
306 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
307 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
308 if (NCR_READ_REG(sc, NCR_CFG3) !=
309 (NCRCFG3_CDB | NCRCFG3_FCLK)) {
310 sc->sc_rev = NCR_VARIANT_ESP100A;
311 } else {
312 /* NCRCFG2_FE enables > 64K transfers */
313 sc->sc_cfg2 |= NCRCFG2_FE;
314 sc->sc_cfg3 = 0;
315 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
316 sc->sc_rev = NCR_VARIANT_ESP200;
317 }
318 }
319
320 /*
321 * XXX minsync and maxxfer _should_ be set up in MI code,
322 * XXX but it appears to have some dependency on what sort
323 * XXX of DMA we're hooked up to, etc.
324 */
325
326 /*
327 * This is the value used to start sync negotiations
328 * Note that the NCR register "SYNCTP" is programmed
329 * in "clocks per byte", and has a minimum value of 4.
330 * The SCSI period used in negotiation is one-fourth
331 * of the time (in nanoseconds) needed to transfer one byte.
332 * Since the chip's clock is given in MHz, we have the following
333 * formula: 4 * period = (1000 / freq) * 4
334 */
335 sc->sc_minsync = 1000 / sc->sc_freq;
336
337 /*
338 * Alas, we must now modify the value a bit, because it's
339 * only valid when can switch on FASTCLK and FASTSCSI bits
340 * in config register 3...
341 */
342 switch (sc->sc_rev) {
343 case NCR_VARIANT_ESP100:
344 sc->sc_maxxfer = 64 * 1024;
345 sc->sc_minsync = 0; /* No synch on old chip? */
346 break;
347
348 case NCR_VARIANT_ESP100A:
349 sc->sc_maxxfer = 64 * 1024;
350 /* Min clocks/byte is 5 */
351 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
352 break;
353
354 case NCR_VARIANT_ESP200:
355 sc->sc_maxxfer = 16 * 1024 * 1024;
356 /* XXX - do actually set FAST* bits */
357 break;
358 }
359
360 /* add me to the sbus structures */
361 esc->sc_sd.sd_reset = (void *) ncr53c9x_reset;
362 #if defined(SUN4C) || defined(SUN4M)
363 if (ca->ca_bustype == BUS_SBUS) {
364 if (dmachild)
365 sbus_establish(&esc->sc_sd, sc->sc_dev.dv_parent);
366 else
367 sbus_establish(&esc->sc_sd, &sc->sc_dev);
368 }
369 #endif /* SUN4C || SUN4M */
370
371 /* and the interuppts */
372 esc->sc_ih.ih_fun = (void *) ncr53c9x_intr;
373 esc->sc_ih.ih_arg = sc;
374 intr_establish(esc->sc_pri, &esc->sc_ih, IPL_BIO);
375 evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
376
377 /*
378 * If the boot path is "esp" at the moment and it's me, then
379 * walk our pointer to the sub-device, ready for the config
380 * below.
381 */
382 bp = ca->ca_ra.ra_bp;
383 switch (ca->ca_bustype) {
384 case BUS_SBUS:
385 if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
386 SAME_ESP(sc, bp, ca))
387 bootpath_store(1, bp + 1);
388 break;
389 default:
390 if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
391 bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit)
392 bootpath_store(1, bp + 1);
393 break;
394 }
395
396 /* Do the common parts of attachment. */
397 ncr53c9x_attach(sc, &esp_switch, &esp_dev);
398
399 /* Turn on target selection using the `dma' method */
400 sc->sc_features |= NCR_F_DMASELECT;
401
402 bootpath_store(1, NULL);
403 }
404
405 /*
406 * Glue functions.
407 */
408
409 u_char
esp_read_reg(sc,reg)410 esp_read_reg(sc, reg)
411 struct ncr53c9x_softc *sc;
412 int reg;
413 {
414 struct esp_softc *esc = (struct esp_softc *)sc;
415
416 return (esc->sc_reg[reg * 4]);
417 }
418
419 void
esp_write_reg(sc,reg,val)420 esp_write_reg(sc, reg, val)
421 struct ncr53c9x_softc *sc;
422 int reg;
423 u_char val;
424 {
425 struct esp_softc *esc = (struct esp_softc *)sc;
426 u_char v = val;
427
428 esc->sc_reg[reg * 4] = v;
429 }
430
431 int
esp_dma_isintr(sc)432 esp_dma_isintr(sc)
433 struct ncr53c9x_softc *sc;
434 {
435 struct esp_softc *esc = (struct esp_softc *)sc;
436
437 return (DMA_ISINTR(esc->sc_dma));
438 }
439
440 void
esp_dma_reset(sc)441 esp_dma_reset(sc)
442 struct ncr53c9x_softc *sc;
443 {
444 struct esp_softc *esc = (struct esp_softc *)sc;
445
446 DMA_RESET(esc->sc_dma);
447 }
448
449 int
esp_dma_intr(sc)450 esp_dma_intr(sc)
451 struct ncr53c9x_softc *sc;
452 {
453 struct esp_softc *esc = (struct esp_softc *)sc;
454
455 return (DMA_INTR(esc->sc_dma));
456 }
457
458 int
esp_dma_setup(sc,addr,len,datain,dmasize)459 esp_dma_setup(sc, addr, len, datain, dmasize)
460 struct ncr53c9x_softc *sc;
461 caddr_t *addr;
462 size_t *len;
463 int datain;
464 size_t *dmasize;
465 {
466 struct esp_softc *esc = (struct esp_softc *)sc;
467
468 return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
469 }
470
471 void
esp_dma_go(sc)472 esp_dma_go(sc)
473 struct ncr53c9x_softc *sc;
474 {
475 struct esp_softc *esc = (struct esp_softc *)sc;
476
477 DMA_GO(esc->sc_dma);
478 }
479
480 void
esp_dma_stop(sc)481 esp_dma_stop(sc)
482 struct ncr53c9x_softc *sc;
483 {
484 struct esp_softc *esc = (struct esp_softc *)sc;
485
486 DMACSR(esc->sc_dma) &= ~D_EN_DMA;
487 }
488
489 int
esp_dma_isactive(sc)490 esp_dma_isactive(sc)
491 struct ncr53c9x_softc *sc;
492 {
493 struct esp_softc *esc = (struct esp_softc *)sc;
494
495 return (DMA_ISACTIVE(esc->sc_dma));
496 }
497