dpt_eisa.c revision 170872
1180740Sdes/*-
2180740Sdes * Copyright (c) 1997, 2000 Matthew N. Dodd <winter@jurai.net>
3180740Sdes * All rights reserved.
4180740Sdes *
5180740Sdes * Redistribution and use in source and binary forms, with or without
6180740Sdes * modification, are permitted provided that the following conditions
7180740Sdes * are met:
8180740Sdes * 1. Redistributions of source code must retain the above copyright
9180740Sdes *    notice, this list of conditions and the following disclaimer.
10180746Sdes * 2. Redistributions in binary form must reproduce the above copyright
11180746Sdes *    notice, this list of conditions and the following disclaimer in the
12180746Sdes *    documentation and/or other materials provided with the distribution.
13180740Sdes *
14180740Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15180740Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16180740Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17180740Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18180740Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19180740Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20180740Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21180740Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22180740Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23180740Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24180740Sdes * SUCH DAMAGE.
25180746Sdes *
26180746Sdes */
27180746Sdes
28180740Sdes#include <sys/cdefs.h>
29180740Sdes__FBSDID("$FreeBSD: head/sys/dev/dpt/dpt_eisa.c 170872 2007-06-17 05:55:54Z scottl $");
30180740Sdes
31180740Sdes#include "opt_eisa.h"
32180740Sdes
33180740Sdes#include <sys/param.h>
34180740Sdes#include <sys/systm.h>
35180740Sdes#include <sys/kernel.h>
36180740Sdes#include <sys/module.h>
37180740Sdes#include <sys/lock.h>
38180740Sdes#include <sys/mutex.h>
39180740Sdes#include <sys/bus.h>
40180740Sdes
41180740Sdes#include <machine/bus.h>
42180740Sdes#include <machine/resource.h>
43180740Sdes#include <sys/rman.h>
44180740Sdes
45180740Sdes#include <dev/eisa/eisaconf.h>
46180740Sdes
47180740Sdes#include <cam/scsi/scsi_all.h>
48180740Sdes
49180740Sdes#include <dev/dpt/dpt.h>
50180740Sdes
51180740Sdes#define DPT_EISA_IOSIZE			0x9
52180740Sdes#define DPT_EISA_SLOT_OFFSET		0x0c00
53180740Sdes#define DPT_EISA_EATA_REG_OFFSET	0x0088
54180740Sdes
55180740Sdes#define	DPT_EISA_DPT2402	0x12142402	/* DPT PM2012A/9X	*/
56180740Sdes#define	DPT_EISA_DPTA401	0x1214A401	/* DPT PM2012B/9X	*/
57180740Sdes#define	DPT_EISA_DPTA402	0x1214A402	/* DPT PM2012B2/9X	*/
58180740Sdes#define	DPT_EISA_DPTA410	0x1214A410	/* DPT PM2x22A/9X	*/
59180740Sdes#define	DPT_EISA_DPTA411	0x1214A411	/* DPT Spectre		*/
60180740Sdes#define	DPT_EISA_DPTA412	0x1214A412	/* DPT PM2021A/9X	*/
61180740Sdes#define	DPT_EISA_DPTA420	0x1214A420	/* DPT Smart Cache IV (PM2042) */
62180746Sdes#define	DPT_EISA_DPTA501	0x1214A501	/* DPT PM2012B1/9X"	*/
63180746Sdes#define	DPT_EISA_DPTA502	0x1214A502	/* DPT PM2012Bx/9X	*/
64180746Sdes#define	DPT_EISA_DPTA701	0x1214A701	/* DPT PM2011B1/9X	*/
65180740Sdes#define	DPT_EISA_DPTBC01	0x1214BC01	/* DPT PM3011/7X ESDI	*/
66180740Sdes#define	DPT_EISA_DPT8200	0x12148200	/* NEC EATA SCSI	*/
67180740Sdes#define	DPT_EISA_DPT2408	0x12142408	/* ATT EATA SCSI	*/
68180740Sdes
69180740Sdes/* Function Prototypes */
70180740Sdes
71180740Sdesstatic const char *	dpt_eisa_match	(eisa_id_t);
72180740Sdesstatic int		dpt_eisa_probe	(device_t);
73180740Sdesstatic int		dpt_eisa_attach	(device_t);
74180740Sdes
75180740Sdesstatic int
76180740Sdesdpt_eisa_probe (device_t dev)
77180740Sdes{
78180740Sdes	const char *	desc;
79180740Sdes	u_int32_t	io_base;
80180740Sdes	dpt_conf_t *	conf;
81180740Sdes
82180740Sdes	desc = dpt_eisa_match(eisa_get_id(dev));
83180740Sdes	if (!desc)
84180740Sdes		return (ENXIO);
85180740Sdes	device_set_desc(dev, desc);
86180740Sdes
87180740Sdes	io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) +
88180740Sdes		DPT_EISA_SLOT_OFFSET +
89180740Sdes		DPT_EISA_EATA_REG_OFFSET;
90180740Sdes
91180740Sdes	conf = dpt_pio_get_conf(io_base);
92180740Sdes	if (!conf) {
93180740Sdes		printf("dpt: dpt_pio_get_conf() failed.\n");
94180740Sdes		return (ENXIO);
95180740Sdes	}
96180740Sdes
97180740Sdes	eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE);
98180740Sdes	eisa_add_intr(dev, conf->IRQ,
99180740Sdes		      (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE));
100180740Sdes
101180740Sdes	return 0;
102180740Sdes}
103180740Sdes
104180740Sdesstatic int
105180740Sdesdpt_eisa_attach (device_t dev)
106180740Sdes{
107180740Sdes	dpt_softc_t *	dpt;
108180740Sdes	int		s;
109180740Sdes	int		error = 0;
110180740Sdes
111180740Sdes	dpt = device_get_softc(dev);
112180740Sdes	dpt->dev = dev;
113180740Sdes
114180740Sdes	dpt->io_rid = 0;
115180740Sdes	dpt->io_type = SYS_RES_IOPORT;
116180740Sdes	dpt->irq_rid = 0;
117180740Sdes
118180740Sdes	error = dpt_alloc_resources(dev);
119180740Sdes	if (error) {
120180740Sdes		goto bad;
121180740Sdes	}
122180740Sdes
123180740Sdes	dpt_alloc(dev);
124180740Sdes
125180740Sdes	/* Allocate a dmatag representing the capabilities of this attachment */
126180740Sdes	/* XXX Should be a child of the EISA bus dma tag */
127180740Sdes	if (bus_dma_tag_create(	/* parent    */	NULL,
128180740Sdes				/* alignemnt */	1,
129180740Sdes				/* boundary  */	0,
130180740Sdes				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
131180740Sdes				/* highaddr  */	BUS_SPACE_MAXADDR,
132180740Sdes				/* filter    */	NULL,
133180740Sdes				/* filterarg */	NULL,
134180740Sdes				/* maxsize   */	BUS_SPACE_MAXSIZE_32BIT,
135180740Sdes				/* nsegments */	~0,
136180740Sdes				/* maxsegsz  */	BUS_SPACE_MAXSIZE_32BIT,
137180740Sdes				/* flags     */ 0,
138180740Sdes				/* lockfunc  */ busdma_lock_mutex,
139180740Sdes				/* lockarg   */ &Giant,
140180740Sdes				&dpt->parent_dmat) != 0) {
141180740Sdes		error = ENXIO;
142180740Sdes		goto bad;
143180740Sdes	}
144180740Sdes
145180740Sdes	s = splcam();
146180740Sdes
147180740Sdes	if (dpt_init(dpt) != 0) {
148180740Sdes		splx(s);
149180740Sdes		error = ENXIO;
150180740Sdes		goto bad;
151180740Sdes	}
152180740Sdes
153180740Sdes	/* Register with the XPT */
154180740Sdes	dpt_attach(dpt);
155180740Sdes
156180740Sdes	splx(s);
157180740Sdes
158180740Sdes	if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
159180740Sdes			   NULL, dpt_intr, dpt, &dpt->ih)) {
160180740Sdes		device_printf(dev, "Unable to register interrupt handler\n");
161180740Sdes		error = ENXIO;
162180740Sdes		goto bad;
163180740Sdes	}
164180740Sdes
165180740Sdes	return (error);
166180740Sdes
167180744Sdes bad:
168180744Sdes	dpt_release_resources(dev);
169180744Sdes
170180740Sdes	dpt_free(dpt);
171180740Sdes
172180740Sdes	return (error);
173180746Sdes}
174180746Sdes
175180746Sdesstatic const char	*
176180740Sdesdpt_eisa_match(type)
177180740Sdes	eisa_id_t	type;
178180740Sdes{
179180740Sdes	switch (type) {
180180740Sdes		case DPT_EISA_DPT2402:
181180740Sdes		case DPT_EISA_DPTA401:
182180740Sdes		case DPT_EISA_DPTA402:
183180740Sdes		case DPT_EISA_DPTA410:
184180740Sdes		case DPT_EISA_DPTA411:
185180740Sdes		case DPT_EISA_DPTA412:
186180740Sdes		case DPT_EISA_DPTA420:
187180740Sdes		case DPT_EISA_DPTA501:
188180740Sdes		case DPT_EISA_DPTA502:
189180740Sdes		case DPT_EISA_DPTA701:
190180740Sdes		case DPT_EISA_DPTBC01:
191180740Sdes		case DPT_EISA_DPT8200:
192180740Sdes		case DPT_EISA_DPT2408:
193180740Sdes			return ("DPT SCSI Host Bus Adapter");
194180740Sdes			break;
195180740Sdes		default:
196180740Sdes			break;
197180740Sdes	}
198180740Sdes
199180740Sdes	return (NULL);
200180740Sdes}
201180740Sdes
202180740Sdesstatic device_method_t dpt_eisa_methods[] = {
203180740Sdes	/* Device interface */
204180740Sdes	DEVMETHOD(device_probe,		dpt_eisa_probe),
205180740Sdes	DEVMETHOD(device_attach,	dpt_eisa_attach),
206180740Sdes	DEVMETHOD(device_detach,	dpt_detach),
207180740Sdes
208180740Sdes	{ 0, 0 }
209180740Sdes};
210180740Sdes
211180740Sdesstatic driver_t dpt_eisa_driver = {
212180740Sdes	"dpt",
213180740Sdes	dpt_eisa_methods,
214180740Sdes	sizeof(dpt_softc_t),
215180740Sdes};
216180740Sdes
217180740SdesDRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0);
218180740SdesMODULE_DEPEND(dpt, eisa, 1, 1, 1);
219180740SdesMODULE_DEPEND(dpt, cam, 1, 1, 1);
220180740Sdes