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