]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/esp/esp_sbus.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / dev / esp / esp_sbus.c
1 /*-
2  * Copyright (c) 2004 Scott Long
3  * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  */
28
29 /*      $NetBSD: esp_sbus.c,v 1.31 2005/02/27 00:27:48 perry Exp $      */
30
31 /*-
32  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
33  * All rights reserved.
34  *
35  * This code is derived from software contributed to The NetBSD Foundation
36  * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
37  * Simulation Facility, NASA Ames Research Center; Paul Kranenburg.
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  * 3. All advertising materials mentioning features or use of this software
48  *    must display the following acknowledgement:
49  *      This product includes software developed by the NetBSD
50  *      Foundation, Inc. and its contributors.
51  * 4. Neither the name of The NetBSD Foundation nor the names of its
52  *    contributors may be used to endorse or promote products derived
53  *    from this software without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
56  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
57  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
59  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
60  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
61  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
62  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
65  * POSSIBILITY OF SUCH DAMAGE.
66  */
67
68 #include <sys/cdefs.h>
69 __FBSDID("$FreeBSD$");
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/bus.h>
74 #include <sys/kernel.h>
75 #include <sys/lock.h>
76 #include <sys/module.h>
77 #include <sys/mutex.h>
78
79 #include <dev/ofw/ofw_bus.h>
80 #include <dev/ofw/openfirm.h>
81 #include <machine/bus.h>
82 #include <machine/resource.h>
83 #include <sys/rman.h>
84
85 #include <cam/cam.h>
86 #include <cam/cam_ccb.h>
87 #include <cam/scsi/scsi_all.h>
88 #include <cam/scsi/scsi_message.h>
89
90 #include <sparc64/sbus/lsi64854reg.h>
91 #include <sparc64/sbus/lsi64854var.h>
92 #include <sparc64/sbus/sbusvar.h>
93
94 #include <dev/esp/ncr53c9xreg.h>
95 #include <dev/esp/ncr53c9xvar.h>
96
97 /* #define ESP_SBUS_DEBUG */
98
99 struct esp_softc {
100         struct ncr53c9x_softc   sc_ncr53c9x;    /* glue to MI code */
101         struct device           *sc_dev;
102
103         struct resource         *sc_res;
104
105         struct resource         *sc_irqres;
106         void                    *sc_irq;
107
108         struct lsi64854_softc   *sc_dma;        /* pointer to my DMA */
109 };
110
111 static devclass_t       esp_devclass;
112
113 static int      esp_probe(device_t);
114 static int      esp_dma_attach(device_t);
115 static int      esp_dma_detach(device_t);
116 static int      esp_sbus_attach(device_t);
117 static int      esp_sbus_detach(device_t);
118 static int      esp_suspend(device_t);
119 static int      esp_resume(device_t);
120
121 static device_method_t esp_dma_methods[] = {
122         DEVMETHOD(device_probe,         esp_probe),
123         DEVMETHOD(device_attach,        esp_dma_attach),
124         DEVMETHOD(device_detach,        esp_dma_detach),
125         DEVMETHOD(device_suspend,       esp_suspend),
126         DEVMETHOD(device_resume,        esp_resume),
127         {0, 0}
128 };
129
130 static driver_t esp_dma_driver = {
131         "esp",
132         esp_dma_methods,
133         sizeof(struct esp_softc)
134 };
135
136 DRIVER_MODULE(esp, dma, esp_dma_driver, esp_devclass, 0, 0);
137 MODULE_DEPEND(esp, dma, 1, 1, 1);
138
139 static device_method_t esp_sbus_methods[] = {
140         DEVMETHOD(device_probe,         esp_probe),
141         DEVMETHOD(device_attach,        esp_sbus_attach),
142         DEVMETHOD(device_detach,        esp_sbus_detach),
143         DEVMETHOD(device_suspend,       esp_suspend),
144         DEVMETHOD(device_resume,        esp_resume),
145         {0, 0}
146 };
147
148 static driver_t esp_sbus_driver = {
149         "esp",
150         esp_sbus_methods,
151         sizeof(struct esp_softc)
152 };
153
154 DRIVER_MODULE(esp, sbus, esp_sbus_driver, esp_devclass, 0, 0);
155 MODULE_DEPEND(esp, sbus, 1, 1, 1);
156
157 /*
158  * Functions and the switch for the MI code
159  */
160 static u_char   esp_read_reg(struct ncr53c9x_softc *sc, int reg);
161 static void     esp_write_reg(struct ncr53c9x_softc *sc, int reg, u_char v);
162 static int      esp_dma_isintr(struct ncr53c9x_softc *sc);
163 static void     esp_dma_reset(struct ncr53c9x_softc *sc);
164 static int      esp_dma_intr(struct ncr53c9x_softc *sc);
165 static int      esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr,
166                     size_t *len, int datain, size_t *dmasize);
167 static void     esp_dma_go(struct ncr53c9x_softc *sc);
168 static void     esp_dma_stop(struct ncr53c9x_softc *sc);
169 static int      esp_dma_isactive(struct ncr53c9x_softc *sc);
170 static int      espattach(struct esp_softc *esc,
171                     const struct ncr53c9x_glue *gluep);
172 static int      espdetach(struct esp_softc *esc);
173
174 static const struct ncr53c9x_glue esp_sbus_glue = {
175         esp_read_reg,
176         esp_write_reg,
177         esp_dma_isintr,
178         esp_dma_reset,
179         esp_dma_intr,
180         esp_dma_setup,
181         esp_dma_go,
182         esp_dma_stop,
183         esp_dma_isactive,
184         NULL,                   /* gl_clear_latched_intr */
185 };
186
187 static int
188 esp_probe(device_t dev)
189 {
190         const char *name;
191
192         name = ofw_bus_get_name(dev);
193         if (strcmp("SUNW,fas", name) == 0) {
194                 device_set_desc(dev, "Sun FAS366 Fast-Wide SCSI");
195                 return (BUS_PROBE_DEFAULT);
196         } else if (strcmp("esp", name) == 0) {
197                 device_set_desc(dev, "Sun ESP SCSI/Sun FAS Fast-SCSI");
198                 return (BUS_PROBE_DEFAULT);
199         }
200
201         return (ENXIO);
202 }
203
204 static int
205 esp_sbus_attach(device_t dev)
206 {
207         struct esp_softc *esc;
208         struct ncr53c9x_softc *sc;
209         struct lsi64854_softc *lsc;
210         device_t *children;
211         int error, i, nchildren;
212
213         esc = device_get_softc(dev);
214         sc = &esc->sc_ncr53c9x;
215
216         lsc = NULL;
217         esc->sc_dev = dev;
218         sc->sc_freq = sbus_get_clockfreq(dev);
219
220         if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") == 0) {
221                 /*
222                  * Allocate space for DMA, in SUNW,fas there are no
223                  * separate DMA devices.
224                  */
225                 lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF,
226                     M_NOWAIT | M_ZERO);
227                 if (lsc == NULL) {
228                         device_printf(dev, "out of memory (lsi64854_softc)\n");
229                         return (ENOMEM);
230                 }
231                 esc->sc_dma = lsc;
232
233                 /*
234                  * SUNW,fas have 2 register spaces: DMA (lsi64854) and
235                  * SCSI core (ncr53c9x).
236                  */
237
238                 /* Allocate DMA registers. */
239                 i = 0;
240                 if ((lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
241                     &i, RF_ACTIVE)) == NULL) {
242                         device_printf(dev, "cannot allocate DMA registers\n");
243                         error = ENXIO;
244                         goto fail_sbus_lsc;
245                 }
246
247                 /* Create a parent DMA tag based on this bus. */
248                 error = bus_dma_tag_create(
249                     bus_get_dma_tag(dev),       /* parent */
250                     1, 0,                       /* alignment, boundary */
251                     BUS_SPACE_MAXADDR,          /* lowaddr */
252                     BUS_SPACE_MAXADDR,          /* highaddr */
253                     NULL, NULL,                 /* filter, filterarg */
254                     BUS_SPACE_MAXSIZE_32BIT,    /* maxsize */
255                     0,                          /* nsegments */
256                     BUS_SPACE_MAXSIZE_32BIT,    /* maxsegsize */
257                     0,                          /* flags */
258                     NULL, NULL,                 /* no locking */
259                     &lsc->sc_parent_dmat);
260                 if (error != 0) {
261                         device_printf(dev, "cannot allocate parent DMA tag\n");
262                         goto fail_sbus_lres;
263                 }
264
265                 i = sbus_get_burstsz(dev);
266
267 #ifdef ESP_SBUS_DEBUG
268                 printf("%s: burst 0x%x\n", __func__, i);
269 #endif
270
271                 lsc->sc_burst = (i & SBUS_BURST_32) ? 32 :
272                     (i & SBUS_BURST_16) ? 16 : 0;
273
274                 lsc->sc_channel = L64854_CHANNEL_SCSI;
275                 lsc->sc_client = sc;
276                 lsc->sc_dev = dev;
277
278                 /*
279                  * Allocate SCSI core registers.
280                  */
281                 i = 1;
282                 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
283                     &i, RF_ACTIVE)) == NULL) {
284                         device_printf(dev,
285                             "cannot allocate SCSI core registers\n");
286                         error = ENXIO;
287                         goto fail_sbus_lpdma;
288                 }
289         } else {
290                 /*
291                  * Search accompanying DMA engine.  It should have been
292                  * already attached otherwise there isn't much we can do.
293                  */
294                 if (device_get_children(device_get_parent(dev), &children,
295                     &nchildren) != 0) {
296                         device_printf(dev, "cannot determine siblings\n");
297                         return (ENXIO);
298                 }
299                 for (i = 0; i < nchildren; i++) {
300                         if (device_is_attached(children[i]) &&
301                             sbus_get_slot(children[i]) == sbus_get_slot(dev) &&
302                             strcmp(ofw_bus_get_name(children[i]), "dma") == 0) {
303                                 /* XXX hackery */
304                                 esc->sc_dma = (struct lsi64854_softc *)
305                                     device_get_softc(children[i]);
306                                 break;
307                         }
308                 }
309                 free(children, M_TEMP);
310                 if (esc->sc_dma == NULL) {
311                         device_printf(dev, "cannot find DMA engine\n");
312                         return (ENXIO);
313                 }
314                 esc->sc_dma->sc_client = sc;
315
316                 /*
317                  * Allocate SCSI core registers.
318                  */
319                 i = 0;
320                 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
321                     &i, RF_ACTIVE)) == NULL) {
322                         device_printf(dev,
323                             "cannot allocate SCSI core registers\n");
324                         return (ENXIO);
325                 }
326         }
327
328         error = espattach(esc, &esp_sbus_glue);
329         if (error != 0) {
330                 device_printf(dev, "espattach failed\n");
331                 goto fail_sbus_eres;
332         }
333
334         return (0);
335
336  fail_sbus_eres:
337         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
338             esc->sc_res);
339         if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0)
340                 return (error);
341  fail_sbus_lpdma:
342         bus_dma_tag_destroy(lsc->sc_parent_dmat);
343  fail_sbus_lres:
344         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res),
345             lsc->sc_res);
346  fail_sbus_lsc:
347         free(lsc, M_DEVBUF);
348         return (error);
349 }
350
351 static int
352 esp_sbus_detach(device_t dev)
353 {
354         struct esp_softc *esc;
355         struct lsi64854_softc *lsc;
356         int error;
357
358         esc = device_get_softc(dev);
359         lsc = esc->sc_dma;
360
361         error = espdetach(esc);
362         if (error != 0)
363                 return (error);
364         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
365                 esc->sc_res);
366         if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0)
367                 return (0);
368         bus_dma_tag_destroy(lsc->sc_parent_dmat);
369         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res),
370             lsc->sc_res);
371         free(lsc, M_DEVBUF);
372
373         return (0);
374 }
375
376 static int
377 esp_dma_attach(device_t dev)
378 {
379         struct esp_softc *esc;
380         struct ncr53c9x_softc *sc;
381         int error, i;
382
383         esc = device_get_softc(dev);
384         sc = &esc->sc_ncr53c9x;
385
386         esc->sc_dev = dev;
387         if (OF_getprop(ofw_bus_get_node(dev), "clock-frequency",
388             &sc->sc_freq, sizeof(sc->sc_freq)) == -1) {
389                 printf("failed to query OFW for clock-frequency\n");
390                 return (ENXIO);
391         }
392
393         /* XXX hackery */
394         esc->sc_dma = (struct lsi64854_softc *)
395             device_get_softc(device_get_parent(dev));
396         esc->sc_dma->sc_client = sc;
397
398         /*
399          * Allocate SCSI core registers.
400          */
401         i = 0;
402         if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
403             &i, RF_ACTIVE)) == NULL) {
404                 device_printf(dev, "cannot allocate SCSI core registers\n");
405                 return (ENXIO);
406         }
407
408         error = espattach(esc, &esp_sbus_glue);
409         if (error != 0) {
410                 device_printf(dev, "espattach failed\n");
411                 goto fail_dma_eres;
412         }
413
414         return (0);
415
416  fail_dma_eres:
417         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
418             esc->sc_res);
419         return (error);
420 }
421
422 static int
423 esp_dma_detach(device_t dev)
424 {
425         struct esp_softc *esc;
426         int error;
427
428         esc = device_get_softc(dev);
429
430         error = espdetach(esc);
431         if (error != 0)
432                 return (error);
433         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
434             esc->sc_res);
435
436         return (0);
437 }
438
439 static int
440 esp_suspend(device_t dev)
441 {
442
443         return (ENXIO);
444 }
445
446 static int
447 esp_resume(device_t dev)
448 {
449
450         return (ENXIO);
451 }
452
453 static int
454 espattach(struct esp_softc *esc, const struct ncr53c9x_glue *gluep)
455 {
456         struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
457         unsigned int uid = 0;
458         int error, i;
459
460         NCR_LOCK_INIT(sc);
461
462         /* Attach the DMA engine. */
463         error = lsi64854_attach(esc->sc_dma);
464         if (error != 0) {
465                 device_printf(esc->sc_dev, "lsi64854_attach failed\n");
466                 goto fail_lock;
467         }
468
469         if (OF_getprop(ofw_bus_get_node(esc->sc_dev), "scsi-initiator-id",
470             &sc->sc_id, sizeof(sc->sc_id)) == -1)
471                 sc->sc_id = 7;
472
473 #ifdef ESP_SBUS_DEBUG
474         device_printf(esc->sc_dev, "%s: sc_id %d, freq %d\n",
475             __func__, sc->sc_id, sc->sc_freq);
476 #endif
477
478         /*
479          * The `ESC' DMA chip must be reset before we can access
480          * the ESP registers.
481          */
482         if (esc->sc_dma->sc_rev == DMAREV_ESC)
483                 DMA_RESET(esc->sc_dma);
484
485         /*
486          * Set up glue for MI code early; we use some of it here.
487          */
488         sc->sc_glue = gluep;
489
490         /* gimme MHz */
491         sc->sc_freq /= 1000000;
492
493         /*
494          * XXX More of this should be in ncr53c9x_attach(), but
495          * XXX should we really poke around the chip that much in
496          * XXX the MI code?  Think about this more...
497          */
498
499         /*
500          * Read the part-unique ID code of the SCSI chip.  The contained
501          * value is only valid if all of the following conditions are met:
502          * - After power-up or chip reset.
503          * - Before any value is written to this register.
504          * - The NCRCFG2_FE bit is set.
505          * - A (NCRCMD_NOP | NCRCMD_DMA) command has been issued.
506          */
507         NCRCMD(sc, NCRCMD_RSTCHIP);
508         NCRCMD(sc, NCRCMD_NOP);
509         sc->sc_cfg2 = NCRCFG2_FE;
510         NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
511         NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA);
512         uid = NCR_READ_REG(sc, NCR_UID);
513
514         /*
515          * It is necessary to try to load the 2nd config register here,
516          * to find out what rev the esp chip is, else the ncr53c9x_reset
517          * will not set up the defaults correctly.
518          */
519         sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
520         NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
521         sc->sc_cfg2 = 0;
522         NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
523         sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
524         NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
525
526         if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
527             (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
528                 sc->sc_rev = NCR_VARIANT_ESP100;
529         } else {
530                 sc->sc_cfg2 = NCRCFG2_SCSI2;
531                 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
532                 sc->sc_cfg3 = 0;
533                 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
534                 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
535                 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
536                 if (NCR_READ_REG(sc, NCR_CFG3) !=
537                     (NCRCFG3_CDB | NCRCFG3_FCLK)) {
538                         sc->sc_rev = NCR_VARIANT_ESP100A;
539                 } else {
540                         /* NCRCFG2_FE enables > 64K transfers. */
541                         sc->sc_cfg2 |= NCRCFG2_FE;
542                         sc->sc_cfg3 = 0;
543                         NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
544                         if (sc->sc_freq <= 25)
545                                 sc->sc_rev = NCR_VARIANT_ESP200;
546                         else {
547                                 switch ((uid & 0xf8) >> 3) {
548                                 case 0x00:
549                                         sc->sc_rev = NCR_VARIANT_FAS100A;
550                                         break;
551
552                                 case 0x02:
553                                         if ((uid & 0x07) == 0x02)
554                                                 sc->sc_rev = NCR_VARIANT_FAS216;
555                                         else
556                                                 sc->sc_rev = NCR_VARIANT_FAS236;
557                                         break;
558
559                                 case 0x0a:
560                                         sc->sc_rev = NCR_VARIANT_FAS366;
561                                         break;
562
563                                 default:
564                                         /*
565                                          * We could just treat unknown chips
566                                          * as ESP200 but then we would most
567                                          * likely drive them out of specs.
568                                          */
569                                         device_printf(esc->sc_dev,
570                                             "Unknown chip\n");
571                                         goto fail_lsi;
572                                 }
573                         }
574                 }
575         }
576
577 #ifdef ESP_SBUS_DEBUG
578         printf("%s: revision %d, uid 0x%x\n", __func__, sc->sc_rev, uid);
579 #endif
580
581         /*
582          * XXX minsync and maxxfer _should_ be set up in MI code,
583          * XXX but it appears to have some dependency on what sort
584          * XXX of DMA we're hooked up to, etc.
585          */
586
587         /*
588          * This is the value used to start sync negotiations
589          * Note that the NCR register "SYNCTP" is programmed
590          * in "clocks per byte", and has a minimum value of 4.
591          * The SCSI period used in negotiation is one-fourth
592          * of the time (in nanoseconds) needed to transfer one byte.
593          * Since the chip's clock is given in MHz, we have the following
594          * formula: 4 * period = (1000 / freq) * 4
595          */
596         sc->sc_minsync = 1000 / sc->sc_freq;
597
598         sc->sc_maxoffset = 15;
599         sc->sc_extended_geom = 1;
600
601         /*
602          * Alas, we must now modify the value a bit, because it's
603          * only valid when can switch on FASTCLK and FASTSCSI bits
604          * in config register 3...
605          */
606         switch (sc->sc_rev) {
607         case NCR_VARIANT_ESP100:
608                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
609                 sc->sc_maxxfer = 64 * 1024;
610                 sc->sc_minsync = 0;     /* No synch on old chip? */
611                 break;
612
613         case NCR_VARIANT_ESP100A:
614                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
615                 sc->sc_maxxfer = 64 * 1024;
616                 /* Min clocks/byte is 5 */
617                 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
618                 break;
619
620         case NCR_VARIANT_ESP200:
621                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
622                 sc->sc_maxxfer = 16 * 1024 * 1024;
623                 /* Min clocks/byte is 5 */
624                 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
625                 break;
626
627         case NCR_VARIANT_FAS100A:
628         case NCR_VARIANT_FAS216:
629         case NCR_VARIANT_FAS236:
630                 /*
631                  * The onboard SCSI chips in Sun Ultra 1 are actually
632                  * documented to be NCR53C9X which use NCRCFG3_FCLK and
633                  * NCRCFG3_FSCSI.  BSD/OS however probes these chips as
634                  * FAS100A and uses NCRF9XCFG3_FCLK and NCRF9XCFG3_FSCSI
635                  * instead which seems to be correct as otherwise sync
636                  * negotiation just doesn't work.  Using NCRF9XCFG3_FCLK
637                  * and NCRF9XCFG3_FSCSI with these chips in fact also
638                  * yields Fast-SCSI speed.
639                  */
640                 sc->sc_features = NCR_F_FASTSCSI;
641                 sc->sc_cfg3 = NCRF9XCFG3_FCLK;
642                 sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI;
643                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
644                 sc->sc_maxxfer = 16 * 1024 * 1024;
645                 break;
646
647         case NCR_VARIANT_FAS366:
648                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_16_BIT;
649                 sc->sc_maxxfer = 16 * 1024 * 1024;
650                 break;
651         }
652
653         /* Establish interrupt channel. */
654         i = 0;
655         if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ,
656             &i, RF_SHAREABLE|RF_ACTIVE)) == NULL) {
657                 device_printf(esc->sc_dev, "cannot allocate interrupt\n");
658                 goto fail_lsi;
659         }
660         if (bus_setup_intr(esc->sc_dev, esc->sc_irqres,
661             INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc,
662             &esc->sc_irq)) {
663                 device_printf(esc->sc_dev, "cannot set up interrupt\n");
664                 error = ENXIO;
665                 goto fail_ires;
666         }
667
668         /* Turn on target selection using the `DMA' method. */
669         if (sc->sc_rev != NCR_VARIANT_FAS366)
670                 sc->sc_features |= NCR_F_DMASELECT;
671
672         /* Do the common parts of attachment. */
673         sc->sc_dev = esc->sc_dev;
674         error = ncr53c9x_attach(sc);
675         if (error != 0) {
676                 device_printf(esc->sc_dev, "ncr53c9x_attach failed\n");
677                 goto fail_intr;
678         }
679
680         return (0);
681
682  fail_intr:
683         bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
684  fail_ires:
685         bus_release_resource(esc->sc_dev, SYS_RES_IRQ,
686             rman_get_rid(esc->sc_irqres), esc->sc_irqres);
687  fail_lsi:
688         lsi64854_detach(esc->sc_dma);
689  fail_lock:
690         NCR_LOCK_DESTROY(sc);
691         return (error);
692 }
693
694 static int
695 espdetach(struct esp_softc *esc)
696 {
697         struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
698         int error;
699
700         bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
701         error = ncr53c9x_detach(sc);
702         if (error != 0)
703                 return (error);
704         error = lsi64854_detach(esc->sc_dma);
705         if (error != 0)
706                 return (error);
707         NCR_LOCK_DESTROY(sc);
708         bus_release_resource(esc->sc_dev, SYS_RES_IRQ,
709             rman_get_rid(esc->sc_irqres), esc->sc_irqres);
710
711         return (0);
712 }
713
714 /*
715  * Glue functions
716  */
717
718 #ifdef ESP_SBUS_DEBUG
719 static int esp_sbus_debug = 0;
720
721 static const struct {
722         char *r_name;
723         int   r_flag;
724 } esp__read_regnames [] = {
725         { "TCL", 0},                    /* 0/00 */
726         { "TCM", 0},                    /* 1/04 */
727         { "FIFO", 0},                   /* 2/08 */
728         { "CMD", 0},                    /* 3/0c */
729         { "STAT", 0},                   /* 4/10 */
730         { "INTR", 0},                   /* 5/14 */
731         { "STEP", 0},                   /* 6/18 */
732         { "FFLAGS", 1},                 /* 7/1c */
733         { "CFG1", 1},                   /* 8/20 */
734         { "STAT2", 0},                  /* 9/24 */
735         { "CFG4", 1},                   /* a/28 */
736         { "CFG2", 1},                   /* b/2c */
737         { "CFG3", 1},                   /* c/30 */
738         { "-none", 1},                  /* d/34 */
739         { "TCH", 1},                    /* e/38 */
740         { "TCX", 1},                    /* f/3c */
741 };
742
743 static const struct {
744         char *r_name;
745         int   r_flag;
746 } esp__write_regnames[] = {
747         { "TCL", 1},                    /* 0/00 */
748         { "TCM", 1},                    /* 1/04 */
749         { "FIFO", 0},                   /* 2/08 */
750         { "CMD", 0},                    /* 3/0c */
751         { "SELID", 1},                  /* 4/10 */
752         { "TIMEOUT", 1},                /* 5/14 */
753         { "SYNCTP", 1},                 /* 6/18 */
754         { "SYNCOFF", 1},                /* 7/1c */
755         { "CFG1", 1},                   /* 8/20 */
756         { "CCF", 1},                    /* 9/24 */
757         { "TEST", 1},                   /* a/28 */
758         { "CFG2", 1},                   /* b/2c */
759         { "CFG3", 1},                   /* c/30 */
760         { "-none", 1},                  /* d/34 */
761         { "TCH", 1},                    /* e/38 */
762         { "TCX", 1},                    /* f/3c */
763 };
764 #endif
765
766 static u_char
767 esp_read_reg(struct ncr53c9x_softc *sc, int reg)
768 {
769         struct esp_softc *esc = (struct esp_softc *)sc;
770         u_char v;
771
772         v = bus_read_1(esc->sc_res, reg * 4);
773
774 #ifdef ESP_SBUS_DEBUG
775         if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag)
776                 printf("RD:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ?
777                     esp__read_regnames[reg].r_name : "<***>", v);
778 #endif
779
780         return (v);
781 }
782
783 static void
784 esp_write_reg(struct ncr53c9x_softc *sc, int reg, u_char v)
785 {
786         struct esp_softc *esc = (struct esp_softc *)sc;
787
788 #ifdef ESP_SBUS_DEBUG
789         if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag)
790                 printf("WR:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ?
791                     esp__write_regnames[reg].r_name : "<***>", v);
792 #endif
793
794         bus_write_1(esc->sc_res, reg * 4, v);
795 }
796
797 static int
798 esp_dma_isintr(struct ncr53c9x_softc *sc)
799 {
800         struct esp_softc *esc = (struct esp_softc *)sc;
801
802         return (DMA_ISINTR(esc->sc_dma));
803 }
804
805 static void
806 esp_dma_reset(struct ncr53c9x_softc *sc)
807 {
808         struct esp_softc *esc = (struct esp_softc *)sc;
809
810         DMA_RESET(esc->sc_dma);
811 }
812
813 static int
814 esp_dma_intr(struct ncr53c9x_softc *sc)
815 {
816         struct esp_softc *esc = (struct esp_softc *)sc;
817
818         return (DMA_INTR(esc->sc_dma));
819 }
820
821 static int
822 esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len,
823               int datain, size_t *dmasize)
824 {
825         struct esp_softc *esc = (struct esp_softc *)sc;
826
827         return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
828 }
829
830 static void
831 esp_dma_go(struct ncr53c9x_softc *sc)
832 {
833         struct esp_softc *esc = (struct esp_softc *)sc;
834
835         DMA_GO(esc->sc_dma);
836 }
837
838 static void
839 esp_dma_stop(struct ncr53c9x_softc *sc)
840 {
841         struct esp_softc *esc = (struct esp_softc *)sc;
842
843         L64854_SCSR(esc->sc_dma, L64854_GCSR(esc->sc_dma) & ~D_EN_DMA);
844 }
845
846 static int
847 esp_dma_isactive(struct ncr53c9x_softc *sc)
848 {
849         struct esp_softc *esc = (struct esp_softc *)sc;
850
851         return (DMA_ISACTIVE(esc->sc_dma));
852 }