dpt_eisa.c revision 165102
1342084Smw/*-
2342084Smw * Copyright (c) 1997, 2000 Matthew N. Dodd <winter@jurai.net>
3342084Smw * All rights reserved.
4342084Smw *
5342084Smw * Redistribution and use in source and binary forms, with or without
6342084Smw * modification, are permitted provided that the following conditions
7342084Smw * are met:
8342084Smw * 1. Redistributions of source code must retain the above copyright
9342084Smw *    notice, this list of conditions and the following disclaimer.
10342084Smw * 2. Redistributions in binary form must reproduce the above copyright
11342084Smw *    notice, this list of conditions and the following disclaimer in the
12342084Smw *    documentation and/or other materials provided with the distribution.
13342084Smw *
14342084Smw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15342084Smw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16342084Smw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17342084Smw * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18342084Smw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19342084Smw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20342084Smw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21342084Smw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22342084Smw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23342084Smw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24342084Smw * SUCH DAMAGE.
25342084Smw *
26342084Smw */
27342084Smw
28342084Smw#include <sys/cdefs.h>
29342084Smw__FBSDID("$FreeBSD: head/sys/dev/dpt/dpt_eisa.c 165102 2006-12-11 18:28:31Z mjacob $");
30342084Smw
31342084Smw#include <sys/param.h>
32342084Smw#include <sys/systm.h>
33342084Smw#include <sys/kernel.h>
34342084Smw#include <sys/module.h>
35342084Smw#include <sys/lock.h>
36342084Smw#include <sys/mutex.h>
37342084Smw#include <sys/bus.h>
38342084Smw
39342084Smw#include <machine/bus.h>
40342084Smw#include <machine/resource.h>
41342084Smw#include <sys/rman.h>
42342084Smw
43342084Smw#include <dev/eisa/eisaconf.h>
44342084Smw
45342084Smw#include <cam/scsi/scsi_all.h>
46342084Smw
47342084Smw#include <dev/dpt/dpt.h>
48342084Smw
49342084Smw#define DPT_EISA_IOSIZE			0x9
50342084Smw#define DPT_EISA_SLOT_OFFSET		0x0c00
51342084Smw#define DPT_EISA_EATA_REG_OFFSET	0x0088
52342084Smw
53342084Smw#define	DPT_EISA_DPT2402	0x12142402	/* DPT PM2012A/9X	*/
54342084Smw#define	DPT_EISA_DPTA401	0x1214A401	/* DPT PM2012B/9X	*/
55342084Smw#define	DPT_EISA_DPTA402	0x1214A402	/* DPT PM2012B2/9X	*/
56342084Smw#define	DPT_EISA_DPTA410	0x1214A410	/* DPT PM2x22A/9X	*/
57342084Smw#define	DPT_EISA_DPTA411	0x1214A411	/* DPT Spectre		*/
58342084Smw#define	DPT_EISA_DPTA412	0x1214A412	/* DPT PM2021A/9X	*/
59342084Smw#define	DPT_EISA_DPTA420	0x1214A420	/* DPT Smart Cache IV (PM2042) */
60342084Smw#define	DPT_EISA_DPTA501	0x1214A501	/* DPT PM2012B1/9X"	*/
61342084Smw#define	DPT_EISA_DPTA502	0x1214A502	/* DPT PM2012Bx/9X	*/
62342084Smw#define	DPT_EISA_DPTA701	0x1214A701	/* DPT PM2011B1/9X	*/
63342084Smw#define	DPT_EISA_DPTBC01	0x1214BC01	/* DPT PM3011/7X ESDI	*/
64342084Smw#define	DPT_EISA_DPT8200	0x12148200	/* NEC EATA SCSI	*/
65342084Smw#define	DPT_EISA_DPT2408	0x12142408	/* ATT EATA SCSI	*/
66342084Smw
67342084Smw/* Function Prototypes */
68342084Smw
69342084Smwstatic const char *	dpt_eisa_match	(eisa_id_t);
70342084Smwstatic int		dpt_eisa_probe	(device_t);
71342084Smwstatic int		dpt_eisa_attach	(device_t);
72342084Smw
73342084Smwstatic int
74342084Smwdpt_eisa_probe (device_t dev)
75342084Smw{
76342084Smw	const char *	desc;
77342084Smw	u_int32_t	io_base;
78342084Smw	dpt_conf_t *	conf;
79342084Smw
80342084Smw	desc = dpt_eisa_match(eisa_get_id(dev));
81342084Smw	if (!desc)
82342084Smw		return (ENXIO);
83342084Smw	device_set_desc(dev, desc);
84342084Smw
85342084Smw	io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) +
86342084Smw		DPT_EISA_SLOT_OFFSET +
87342084Smw		DPT_EISA_EATA_REG_OFFSET;
88342084Smw
89342084Smw	conf = dpt_pio_get_conf(io_base);
90342084Smw	if (!conf) {
91342084Smw		printf("dpt: dpt_pio_get_conf() failed.\n");
92342084Smw		return (ENXIO);
93342084Smw	}
94342084Smw
95342084Smw	eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE);
96342084Smw	eisa_add_intr(dev, conf->IRQ,
97342084Smw		      (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE));
98342084Smw
99342084Smw	return 0;
100342084Smw}
101342084Smw
102342084Smwstatic int
103346722Smwdpt_eisa_attach (device_t dev)
104346722Smw{
105346722Smw	dpt_softc_t *	dpt;
106342084Smw	int		s;
107342084Smw	int		error = 0;
108342084Smw
109342084Smw	dpt = device_get_softc(dev);
110346722Smw
111346722Smw	dpt->io_rid = 0;
112346722Smw	dpt->io_type = SYS_RES_IOPORT;
113346722Smw	dpt->irq_rid = 0;
114346722Smw
115342084Smw	error = dpt_alloc_resources(dev);
116342084Smw	if (error) {
117346722Smw		goto bad;
118342084Smw	}
119342084Smw
120342084Smw	dpt_alloc(dev);
121342084Smw
122342084Smw	/* Allocate a dmatag representing the capabilities of this attachment */
123342084Smw	/* XXX Should be a child of the EISA bus dma tag */
124342084Smw	if (bus_dma_tag_create(	/* parent    */	NULL,
125342084Smw				/* alignemnt */	1,
126342084Smw				/* boundary  */	0,
127342084Smw				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
128342084Smw				/* highaddr  */	BUS_SPACE_MAXADDR,
129342084Smw				/* filter    */	NULL,
130342084Smw				/* filterarg */	NULL,
131342084Smw				/* maxsize   */	BUS_SPACE_MAXSIZE_32BIT,
132342084Smw				/* nsegments */	~0,
133342084Smw				/* maxsegsz  */	BUS_SPACE_MAXSIZE_32BIT,
134342084Smw				/* flags     */ 0,
135342084Smw				/* lockfunc  */ busdma_lock_mutex,
136342084Smw				/* lockarg   */ &Giant,
137342084Smw				&dpt->parent_dmat) != 0) {
138342084Smw		error = ENXIO;
139342084Smw		goto bad;
140342084Smw	}
141342084Smw
142342084Smw	s = splcam();
143342084Smw
144342084Smw	if (dpt_init(dpt) != 0) {
145342084Smw		splx(s);
146342084Smw		error = ENXIO;
147342084Smw		goto bad;
148342084Smw	}
149342084Smw
150342084Smw	/* Register with the XPT */
151342084Smw	dpt_attach(dpt);
152342084Smw
153342084Smw	splx(s);
154342084Smw
155342084Smw	if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
156342084Smw			   dpt_intr, dpt, &dpt->ih)) {
157342084Smw		device_printf(dev, "Unable to register interrupt handler\n");
158342084Smw		error = ENXIO;
159342084Smw		goto bad;
160342084Smw	}
161342084Smw
162342084Smw	return (error);
163342084Smw
164342084Smw bad:
165342084Smw	dpt_release_resources(dev);
166342084Smw
167342084Smw	dpt_free(dpt);
168342084Smw
169342084Smw	return (error);
170342084Smw}
171342084Smw
172342084Smwstatic const char	*
173342084Smwdpt_eisa_match(type)
174342084Smw	eisa_id_t	type;
175342084Smw{
176342084Smw	switch (type) {
177342084Smw		case DPT_EISA_DPT2402:
178342084Smw		case DPT_EISA_DPTA401:
179342084Smw		case DPT_EISA_DPTA402:
180342084Smw		case DPT_EISA_DPTA410:
181342084Smw		case DPT_EISA_DPTA411:
182342084Smw		case DPT_EISA_DPTA412:
183342084Smw		case DPT_EISA_DPTA420:
184342084Smw		case DPT_EISA_DPTA501:
185342084Smw		case DPT_EISA_DPTA502:
186342084Smw		case DPT_EISA_DPTA701:
187342084Smw		case DPT_EISA_DPTBC01:
188342084Smw		case DPT_EISA_DPT8200:
189342084Smw		case DPT_EISA_DPT2408:
190342084Smw			return ("DPT SCSI Host Bus Adapter");
191342084Smw			break;
192342084Smw		default:
193342084Smw			break;
194342084Smw	}
195342084Smw
196342084Smw	return (NULL);
197342084Smw}
198342084Smw
199342084Smwstatic device_method_t dpt_eisa_methods[] = {
200342084Smw	/* Device interface */
201342084Smw	DEVMETHOD(device_probe,		dpt_eisa_probe),
202342084Smw	DEVMETHOD(device_attach,	dpt_eisa_attach),
203342084Smw	DEVMETHOD(device_detach,	dpt_detach),
204342084Smw
205342084Smw	{ 0, 0 }
206342084Smw};
207342084Smw
208342084Smwstatic driver_t dpt_eisa_driver = {
209342084Smw	"dpt",
210342084Smw	dpt_eisa_methods,
211342084Smw	sizeof(dpt_softc_t),
212342084Smw};
213342084Smw
214342084SmwDRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0);
215342084SmwMODULE_DEPEND(dpt, eisa, 1, 1, 1);
216342084SmwMODULE_DEPEND(dpt, cam, 1, 1, 1);
217342084Smw