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
95struct 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
107static int	esp_probe(device_t);
108static int	esp_dma_attach(device_t);
109static int	esp_dma_detach(device_t);
110static int	esp_sbus_attach(device_t);
111static int	esp_sbus_detach(device_t);
112static int	esp_suspend(device_t);
113static int	esp_resume(device_t);
114
115static 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
125static driver_t esp_dma_driver = {
126	"esp",
127	esp_dma_methods,
128	sizeof(struct esp_softc)
129};
130
131DRIVER_MODULE(esp, dma, esp_dma_driver, esp_devclass, 0, 0);
132MODULE_DEPEND(esp, dma, 1, 1, 1);
133
134static 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
144static driver_t esp_sbus_driver = {
145	"esp",
146	esp_sbus_methods,
147	sizeof(struct esp_softc)
148};
149
150DRIVER_MODULE(esp, sbus, esp_sbus_driver, esp_devclass, 0, 0);
151MODULE_DEPEND(esp, sbus, 1, 1, 1);
152
153/*
154 * Functions and the switch for the MI code
155 */
156static uint8_t	esp_read_reg(struct ncr53c9x_softc *sc, int reg);
157static void	esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v);
158static int	esp_dma_isintr(struct ncr53c9x_softc *sc);
159static void	esp_dma_reset(struct ncr53c9x_softc *sc);
160static int	esp_dma_intr(struct ncr53c9x_softc *sc);
161static int	esp_dma_setup(struct ncr53c9x_softc *sc, void **addr,
162		    size_t *len, int datain, size_t *dmasize);
163static void	esp_dma_go(struct ncr53c9x_softc *sc);
164static void	esp_dma_stop(struct ncr53c9x_softc *sc);
165static int	esp_dma_isactive(struct ncr53c9x_softc *sc);
166static int	espattach(struct esp_softc *esc,
167		    const struct ncr53c9x_glue *gluep);
168static int	espdetach(struct esp_softc *esc);
169
170static 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
182static int
183esp_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
199static int
200esp_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
348static int
349esp_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
373static int
374esp_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
419static int
420esp_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
436static int
437esp_suspend(device_t dev)
438{
439
440	return (ENXIO);
441}
442
443static int
444esp_resume(device_t dev)
445{
446
447	return (ENXIO);
448}
449
450static int
451espattach(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
688static int
689espdetach(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
713static int esp_sbus_debug = 0;
714
715static 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
737static 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
760static uint8_t
761esp_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
777static void
778esp_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
791static int
792esp_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
799static void
800esp_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
807static int
808esp_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
815static int
816esp_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
824static void
825esp_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
832static void
833esp_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
840static int
841esp_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}
847