2 * Copyright (c) 1999 Luoqi Chen.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/dev/aic/aic_isa.c,v 1.3 2000/01/14 23:42:35 imp Exp $
27 * $DragonFly: src/sys/dev/disk/aic/aic_isa.c,v 1.8 2008/01/05 07:27:09 pavalos Exp $
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/module.h>
36 #include <bus/isa/isavar.h>
37 #include "aic6360reg.h"
40 struct aic_isa_softc
{
41 struct aic_softc sc_aic
;
42 struct resource
*sc_port
;
43 struct resource
*sc_irq
;
44 struct resource
*sc_drq
;
48 static int aic_isa_alloc_resources (device_t
);
49 static void aic_isa_release_resources (device_t
);
50 static int aic_isa_probe (device_t
);
51 static int aic_isa_attach (device_t
);
53 static u_int aic_isa_ports
[] = { 0x340, 0x140 };
54 #define AIC_ISA_NUMPORTS (sizeof(aic_isa_ports) / sizeof(aic_isa_ports[0]))
55 #define AIC_ISA_PORTSIZE 0x20
57 static struct isa_pnp_id aic_ids
[] = {
58 { 0x15309004, "Adaptec AHA-1530P" },
59 { 0x15209004, "Adaptec AHA-1520P" },
64 aic_isa_alloc_resources(device_t dev
)
66 struct aic_isa_softc
*sc
= device_get_softc(dev
);
69 sc
->sc_port
= sc
->sc_irq
= sc
->sc_drq
= 0;
72 sc
->sc_port
= bus_alloc_resource(dev
, SYS_RES_IOPORT
, &rid
,
73 0ul, ~0ul, AIC_ISA_PORTSIZE
, RF_ACTIVE
);
75 device_printf(dev
, "I/O port allocation failed\n");
79 if (isa_get_irq(dev
) != -1) {
81 sc
->sc_irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
,
84 device_printf(dev
, "IRQ allocation failed\n");
85 aic_isa_release_resources(dev
);
90 if (isa_get_drq(dev
) != -1) {
92 sc
->sc_drq
= bus_alloc_resource_any(dev
, SYS_RES_DRQ
, &rid
,
95 device_printf(dev
, "DRQ allocation failed\n");
96 aic_isa_release_resources(dev
);
101 sc
->sc_aic
.unit
= device_get_unit(dev
);
102 sc
->sc_aic
.tag
= rman_get_bustag(sc
->sc_port
);
103 sc
->sc_aic
.bsh
= rman_get_bushandle(sc
->sc_port
);
108 aic_isa_release_resources(device_t dev
)
110 struct aic_isa_softc
*sc
= device_get_softc(dev
);
113 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, sc
->sc_port
);
115 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->sc_irq
);
117 bus_release_resource(dev
, SYS_RES_DRQ
, 0, sc
->sc_drq
);
118 sc
->sc_port
= sc
->sc_irq
= sc
->sc_drq
= 0;
122 aic_isa_probe(device_t dev
)
124 struct aic_isa_softc
*sc
= device_get_softc(dev
);
125 struct aic_softc
*aic
= &sc
->sc_aic
;
130 if (ISA_PNP_PROBE(device_get_parent(dev
), dev
, aic_ids
) == ENXIO
)
133 port
= isa_get_port(dev
);
138 ports
= aic_isa_ports
;
139 numports
= AIC_ISA_NUMPORTS
;
142 for (i
= 0; i
< numports
; i
++) {
143 if (bus_set_resource(dev
, SYS_RES_IOPORT
, 0, ports
[i
],
146 if (aic_isa_alloc_resources(dev
))
148 if (!aic_probe(aic
)) {
149 aic_isa_release_resources(dev
);
152 aic_isa_release_resources(dev
);
158 porta
= aic_inb(aic
, PORTA
);
159 if (isa_get_irq(dev
) == -1)
160 bus_set_resource(dev
, SYS_RES_IRQ
, 0, PORTA_IRQ(porta
), 1);
161 if ((aic
->flags
& AIC_DMA_ENABLE
) && isa_get_drq(dev
) == -1)
162 bus_set_resource(dev
, SYS_RES_DRQ
, 0, PORTA_DRQ(porta
), 1);
163 device_set_desc(dev
, "Adaptec 6260/6360 SCSI controller");
168 aic_isa_attach(device_t dev
)
170 struct aic_isa_softc
*sc
= device_get_softc(dev
);
171 struct aic_softc
*aic
= &sc
->sc_aic
;
174 error
= aic_isa_alloc_resources(dev
);
176 device_printf(dev
, "resource allocation failed\n");
180 error
= aic_attach(aic
);
182 device_printf(dev
, "attach failed\n");
183 aic_isa_release_resources(dev
);
187 error
= bus_setup_intr(dev
, sc
->sc_irq
, 0, aic_intr
,
188 aic
, &sc
->sc_ih
, NULL
);
190 device_printf(dev
, "failed to register interrupt handler\n");
191 aic_isa_release_resources(dev
);
198 aic_isa_detach(device_t dev
)
200 struct aic_isa_softc
*sc
= device_get_softc(dev
);
201 struct aic_softc
*aic
= &sc
->sc_aic
;
204 error
= aic_detach(aic
);
206 device_printf(dev
, "detach failed\n");
210 error
= bus_teardown_intr(dev
, sc
->sc_irq
, sc
->sc_ih
);
212 device_printf(dev
, "failed to unregister interrupt handler\n");
215 aic_isa_release_resources(dev
);
219 static device_method_t aic_isa_methods
[] = {
220 /* Device interface */
221 DEVMETHOD(device_probe
, aic_isa_probe
),
222 DEVMETHOD(device_attach
, aic_isa_attach
),
223 DEVMETHOD(device_detach
, aic_isa_detach
),
227 static driver_t aic_isa_driver
= {
229 aic_isa_methods
, sizeof(struct aic_isa_softc
),
232 extern devclass_t aic_devclass
;
234 MODULE_DEPEND(aic
, cam
, 1,1,1);
235 DRIVER_MODULE(aic
, isa
, aic_isa_driver
, aic_devclass
, 0, 0);