dpt_eisa.c revision 52042
1/*
2 *       Copyright (c) 1997 by Matthew N. Dodd <winter@jurai.net>
3 *       All Rights Reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions, and the following disclaimer,
10 *    without modification, immediately at the beginning of the file.
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 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
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 FOR
21 * 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 * Credits:  Based on and part of the DPT driver for FreeBSD written and
32 *           maintained by Simon Shapiro <shimon@simon-shapiro.org>
33 */
34
35/*
36 * $FreeBSD: head/sys/dev/dpt/dpt_eisa.c 52042 1999-10-09 03:39:47Z mdodd $
37 */
38
39#include "eisa.h"
40#if NEISA > 0
41#include "opt_dpt.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/malloc.h>
46#include <sys/buf.h>
47#include <sys/proc.h>
48#include <sys/kernel.h>
49#include <sys/module.h>
50#include <sys/bus.h>
51
52#include <machine/bus_pio.h>
53#include <machine/bus.h>
54#include <machine/resource.h>
55#include <sys/rman.h>
56
57#include <cam/scsi/scsi_all.h>
58
59#include <dev/dpt/dpt.h>
60
61#include <i386/eisa/eisaconf.h>
62
63#include <machine/clock.h>
64
65#include <vm/vm.h>
66#include <vm/vm_param.h>
67#include <vm/pmap.h>
68
69#define DPT_EISA_IOSIZE			0x100
70#define DPT_EISA_SLOT_OFFSET		0x0c00
71#define DPT_EISA_EATA_REG_OFFSET	0x0088
72
73#define	DPT_EISA_DPT2402		0x12142402
74#define	DPT_EISA_DPTA401		0x1214A401
75#define	DPT_EISA_DPTA402		0x1214A402
76#define	DPT_EISA_DPTA410		0x1214A410
77#define	DPT_EISA_DPTA411		0x1214A411
78#define	DPT_EISA_DPTA412		0x1214A412
79#define	DPT_EISA_DPTA420		0x1214A420
80#define	DPT_EISA_DPTA501		0x1214A501
81#define	DPT_EISA_DPTA502		0x1214A502
82#define	DPT_EISA_DPTA701		0x1214A701
83#define	DPT_EISA_DPTBC01		0x1214BC01
84#define	DPT_EISA_NEC8200		0x12148200
85#define	DPT_EISA_ATT2408		0x12142408
86
87/* Function Prototypes */
88
89static const char	*dpt_eisa_match(eisa_id_t);
90
91static int
92dpt_eisa_probe(device_t dev)
93{
94	const char *	desc;
95	u_int32_t	io_base;
96	dpt_conf_t *	conf;
97
98	desc = dpt_eisa_match(eisa_get_id(dev));
99	if (!desc)
100		return (ENXIO);
101	device_set_desc(dev, desc);
102
103	io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + DPT_EISA_SLOT_OFFSET;
104
105	conf = dpt_pio_get_conf(io_base + DPT_EISA_EATA_REG_OFFSET);
106	if (!conf) {
107		printf("dpt: dpt_pio_get_conf() failed.\n");
108		return (ENXIO);
109	}
110
111	eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE);
112	eisa_add_intr(dev, conf->IRQ,
113		      (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE));
114
115	return 0;
116}
117
118static int
119dpt_eisa_attach(device_t dev)
120{
121	dpt_softc_t	*dpt;
122	struct resource *io = 0;
123	struct resource *irq = 0;
124        int		unit = device_get_unit(dev);
125	int		s;
126	int		rid;
127	void		*ih;
128
129	rid = 0;
130	io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
131				0, ~0, 1, RF_ACTIVE);
132	if (!io) {
133		device_printf(dev, "No I/O space?!\n");
134		return ENOMEM;
135	}
136
137	dpt = dpt_alloc(unit, rman_get_bustag(io),
138			rman_get_bushandle(io) + DPT_EISA_EATA_REG_OFFSET);
139	if (dpt == NULL)
140		goto bad;
141
142	/* Allocate a dmatag representing the capabilities of this attachment */
143	/* XXX Should be a child of the EISA bus dma tag */
144	if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0,
145			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
146			       /*highaddr*/BUS_SPACE_MAXADDR,
147			       /*filter*/NULL, /*filterarg*/NULL,
148			       /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
149			       /*nsegments*/BUS_SPACE_UNRESTRICTED,
150			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
151			       /*flags*/0, &dpt->parent_dmat) != 0) {
152		dpt_free(dpt);
153		goto bad;
154	}
155
156	rid = 0;
157	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
158				 0, ~0, 1, RF_ACTIVE);
159	if (!irq) {
160		device_printf(dev, "No irq?!\n");
161		goto bad;
162	}
163
164	s = splcam();
165	if (dpt_init(dpt) != 0) {
166		dpt_free(dpt);
167		goto bad;
168	}
169
170	/* Register with the XPT */
171	dpt_attach(dpt);
172	bus_setup_intr(dev, irq, INTR_TYPE_CAM, dpt_intr, dpt, &ih);
173
174	splx(s);
175
176	return 0;
177
178 bad:
179	if (io)
180		bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
181	if (irq)
182		bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
183	return -1;
184}
185
186static const char	*
187dpt_eisa_match(type)
188	eisa_id_t	type;
189{
190	switch (type) {
191		case DPT_EISA_DPT2402 :
192			return ("DPT PM2012A/9X");
193			break;
194		case DPT_EISA_DPTA401 :
195			return ("DPT PM2012B/9X");
196			break;
197		case DPT_EISA_DPTA402 :
198			return ("DPT PM2012B2/9X");
199			break;
200		case DPT_EISA_DPTA410 :
201			return ("DPT PM2x22A/9X");
202			break;
203		case DPT_EISA_DPTA411 :
204			return ("DPT Spectre");
205			break;
206		case DPT_EISA_DPTA412 :
207			return ("DPT PM2021A/9X");
208			break;
209		case DPT_EISA_DPTA420 :
210			return ("DPT Smart Cache IV (PM2042)");
211			break;
212		case DPT_EISA_DPTA501 :
213			return ("DPT PM2012B1/9X");
214			break;
215		case DPT_EISA_DPTA502 :
216			return ("DPT PM2012Bx/9X");
217			break;
218		case DPT_EISA_DPTA701 :
219			return ("DPT PM2011B1/9X");
220			break;
221		case DPT_EISA_DPTBC01 :
222			return ("DPT PM3011/7X ESDI");
223			break;
224		case DPT_EISA_NEC8200 :
225			return ("NEC EATA SCSI");
226			break;
227		case DPT_EISA_ATT2408 :
228			return ("ATT EATA SCSI");
229			break;
230		default:
231			break;
232	}
233
234	return (NULL);
235}
236
237static device_method_t dpt_eisa_methods[] = {
238	/* Device interface */
239	DEVMETHOD(device_probe,		dpt_eisa_probe),
240	DEVMETHOD(device_attach,	dpt_eisa_attach),
241
242	{ 0, 0 }
243};
244
245static driver_t dpt_eisa_driver = {
246	"dpt",
247	dpt_eisa_methods,
248	1,			/* unused */
249};
250
251static devclass_t dpt_devclass;
252
253DRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0);
254
255#endif /* NEISA > 0 */
256