dpt_isa.c revision 73280
1168404Spjd/*-
2168404Spjd * Copyright (c) 2000 Matthew N. Dodd <winter@jurai.net>
3168404Spjd * All rights reserved.
4168404Spjd *
5168404Spjd * Redistribution and use in source and binary forms, with or without
6168404Spjd * modification, are permitted provided that the following conditions
7168404Spjd * are met:
8168404Spjd * 1. Redistributions of source code must retain the above copyright
9168404Spjd *    notice, this list of conditions and the following disclaimer.
10168404Spjd * 2. Redistributions in binary form must reproduce the above copyright
11168404Spjd *    notice, this list of conditions and the following disclaimer in the
12168404Spjd *    documentation and/or other materials provided with the distribution.
13168404Spjd *
14168404Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15168404Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16168404Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17168404Spjd * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18168404Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19168404Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20168404Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21168404Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22168404Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23219089Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24168404Spjd * SUCH DAMAGE.
25168404Spjd *
26168404Spjd *	$FreeBSD: head/sys/dev/dpt/dpt_isa.c 73280 2001-03-01 17:09:09Z markm $
27168404Spjd */
28168404Spjd
29168404Spjd#include <sys/param.h>
30168404Spjd#include <sys/systm.h>
31168404Spjd#include <sys/kernel.h>
32168404Spjd#include <sys/module.h>
33168404Spjd#include <sys/bus.h>
34185029Spjd
35168404Spjd#include <machine/bus_pio.h>
36168404Spjd#include <machine/bus.h>
37185029Spjd#include <machine/resource.h>
38185029Spjd#include <sys/rman.h>
39219089Spjd
40168404Spjd#include <isa/isavar.h>
41168404Spjd
42168404Spjd#include <cam/scsi/scsi_all.h>
43185029Spjd
44168404Spjd#include <dev/dpt/dpt.h>
45185029Spjd
46168404Spjdstatic int	dpt_isa_probe		(device_t);
47168404Spjdstatic int	dpt_isa_attach		(device_t);
48168404Spjd
49168404Spjdstatic int
50168404Spjddpt_isa_probe (device_t dev)
51168404Spjd{
52168404Spjd	dpt_conf_t *	conf;
53168404Spjd	u_int32_t	io_base;
54168404Spjd
55168404Spjd	/* No pnp support */
56168404Spjd	if (isa_get_vendorid(dev))
57168404Spjd		return (ENXIO);
58168404Spjd
59168404Spjd	if ((io_base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0)
60168404Spjd		return (ENXIO);
61168404Spjd
62168404Spjd	conf = dpt_pio_get_conf(io_base);
63168404Spjd        if (!conf) {
64168404Spjd                printf("dpt: dpt_pio_get_conf() failed.\n");
65168404Spjd                return (ENXIO);
66168404Spjd        }
67168404Spjd
68168404Spjd	device_set_desc(dev, "ISA DPT SCSI controller");
69168404Spjd	bus_set_resource(dev, SYS_RES_IRQ, 0, conf->IRQ, 1);
70168404Spjd	bus_set_resource(dev, SYS_RES_DRQ, 0, ((8 - conf->DMA_channel) & 7), 1);
71168404Spjd
72168404Spjd	return 0;
73168404Spjd}
74168404Spjd
75168404Spjdstatic int
76168404Spjddpt_isa_attach (device_t dev)
77168404Spjd{
78168404Spjd	dpt_softc_t *	dpt = NULL;
79168404Spjd	struct resource *io = 0;
80168404Spjd	struct resource *irq = 0;
81168404Spjd	struct resource *drq = 0;
82168404Spjd	int		s;
83168404Spjd	int		rid;
84168404Spjd	void *		ih;
85168404Spjd	int		error = 0;
86168404Spjd
87168404Spjd	rid = 0;
88168404Spjd	io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
89168404Spjd	if (!io) {
90168404Spjd		device_printf(dev, "No I/O space?!\n");
91168404Spjd		error = ENOMEM;
92168404Spjd		goto bad;
93168404Spjd	}
94168404Spjd
95168404Spjd	rid = 0;
96168404Spjd	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE);
97168404Spjd	if (!irq) {
98168404Spjd		device_printf(dev, "No IRQ!\n");
99168404Spjd		error = ENOMEM;
100168404Spjd		goto bad;
101168404Spjd	}
102168404Spjd
103168404Spjd	rid = 0;
104168404Spjd	drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid, 0, ~0, 1, RF_ACTIVE);
105168404Spjd	if (!drq) {
106168404Spjd		device_printf(dev, "No DRQ?!\n");
107168404Spjd		error = ENOMEM;
108168404Spjd		goto bad;
109168404Spjd	}
110168404Spjd
111168404Spjd	dpt = dpt_alloc(dev, rman_get_bustag(io), rman_get_bushandle(io));
112168404Spjd	if (dpt == NULL) {
113168404Spjd		error = ENXIO;
114168404Spjd		goto bad;
115168404Spjd	}
116168404Spjd
117168404Spjd	isa_dmacascade(rman_get_start(drq));
118168404Spjd
119168404Spjd	/* Allocate a dmatag representing the capabilities of this attachment */
120168404Spjd	if (bus_dma_tag_create( /* parent    */	NULL,
121168404Spjd				/* alignemnt */	1,
122168404Spjd				/* boundary  */	0,
123168404Spjd				/* lowaddr   */	BUS_SPACE_MAXADDR_24BIT,
124168404Spjd				/* highaddr  */	BUS_SPACE_MAXADDR,
125168404Spjd				/* filter    */	NULL,
126168404Spjd				/* filterarg */	NULL,
127168404Spjd				/* maxsize   */	BUS_SPACE_MAXSIZE_32BIT,
128168404Spjd				/* nsegments */	BUS_SPACE_UNRESTRICTED,
129168404Spjd				/* maxsegsz  */	BUS_SPACE_MAXSIZE_32BIT,
130168404Spjd				/* flags     */	0,
131168404Spjd				&dpt->parent_dmat) != 0) {
132168404Spjd		error = ENXIO;
133168404Spjd		goto bad;
134168404Spjd	}
135168404Spjd
136168404Spjd	s = splcam();
137168404Spjd
138168404Spjd	if (dpt_init(dpt) != 0) {
139168404Spjd		splx(s);
140168404Spjd		error = ENXIO;
141168404Spjd		goto bad;
142168404Spjd	}
143168404Spjd
144168404Spjd	/* Register with the XPT */
145168404Spjd	dpt_attach(dpt);
146168404Spjd
147168404Spjd	splx(s);
148168404Spjd
149168404Spjd	if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_ENTROPY, dpt_intr,
150168404Spjd			   dpt, &ih)) {
151168404Spjd		device_printf(dev, "Unable to register interrupt handler\n");
152168404Spjd		error = ENXIO;
153168404Spjd		goto bad;
154168404Spjd	}
155168404Spjd
156168404Spjd	return (error);
157168404Spjd
158168404Spjd bad:
159168404Spjd	if (dpt)
160168404Spjd		dpt_free(dpt);
161168404Spjd	if (io)
162168404Spjd		bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
163168404Spjd	if (irq)
164168404Spjd		bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
165168404Spjd	if (drq)
166168404Spjd		bus_release_resource(dev, SYS_RES_DRQ, 0, drq);
167168404Spjd
168168404Spjd	return (error);
169168404Spjd}
170168404Spjd
171168404Spjdstatic device_method_t dpt_isa_methods[] = {
172168404Spjd	/* Device interface */
173168404Spjd	DEVMETHOD(device_probe,		dpt_isa_probe),
174168404Spjd	DEVMETHOD(device_attach,	dpt_isa_attach),
175168404Spjd
176168404Spjd	{ 0, 0 }
177168404Spjd};
178168404Spjd
179168404Spjdstatic driver_t dpt_isa_driver = {
180168404Spjd	"dpt",
181168404Spjd	dpt_isa_methods,
182168404Spjd	sizeof(dpt_softc_t),
183168404Spjd};
184168404Spjd
185168404Spjdstatic devclass_t dpt_devclass;
186168404Spjd
187168404SpjdDRIVER_MODULE(dpt, isa, dpt_isa_driver, dpt_devclass, 0, 0);
188168404Spjd