2 * FreeBSD, VLB/ISA product support functions
4 * Copyright (c) 2004 Justin T. Gibbs.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGES.
37 * $FreeBSD: src/sys/dev/aic7xxx/ahc_isa.c,v 1.5 2004/10/15 23:39:52 gibbs Exp $
38 * $DragonFly: src/sys/dev/disk/aic7xxx/ahc_isa.c,v 1.4 2008/05/18 20:30:21 pavalos Exp $
41 #include "aic7xxx_osm.h"
43 #include <machine/limits.h> /* For CHAR_BIT */
44 #include <bus/isa/isavar.h> /* For ISA attach glue */
47 static struct aic7770_identity
*ahc_isa_find_device(bus_space_tag_t tag
,
48 bus_space_handle_t bsh
);
49 static void ahc_isa_identify(driver_t
*driver
,
51 static int ahc_isa_probe(device_t dev
);
52 static int ahc_isa_attach(device_t dev
);
55 * Perform an EISA probe of the address with the addition
56 * of a "priming" step. The 284X requires priming (a write
57 * to offset 0x80, the first EISA ID register) to ensure it
58 * is not mistaken as an EISA card. Once we have the ID,
59 * lookup the controller in the aic7770 table of supported
62 static struct aic7770_identity
*
63 ahc_isa_find_device(bus_space_tag_t tag
, bus_space_handle_t bsh
) {
70 for (i
= 0; i
< id_size
; i
++) {
71 bus_space_write_1(tag
, bsh
, 0x80, 0x80 + i
);
72 id
|= bus_space_read_1(tag
, bsh
, 0x80 + i
)
73 << ((id_size
- i
- 1) * CHAR_BIT
);
76 return (aic7770_find_device(id
));
80 ahc_isa_identify(driver_t
*driver
, device_t parent
)
86 for (slot
= 0; slot
<= max_slot
; slot
++) {
87 struct aic7770_identity
*entry
;
89 bus_space_handle_t bsh
;
90 struct resource
*regs
;
95 iobase
= (slot
* AHC_EISA_SLOT_SIZE
) + AHC_EISA_SLOT_OFFSET
;
96 regs
= bus_alloc_resource(parent
, SYS_RES_IOPORT
, &rid
,
97 iobase
, iobase
, AHC_EISA_IOSIZE
,
101 kprintf("ahc_isa_probe %d: ioport 0x%x "
102 "alloc failed\n", slot
, iobase
);
106 tag
= rman_get_bustag(regs
);
107 bsh
= rman_get_bushandle(regs
);
109 entry
= ahc_isa_find_device(tag
, bsh
);
113 child
= BUS_ADD_CHILD(parent
, parent
, ISA_ORDER_SPECULATIVE
,
116 device_set_driver(child
, driver
);
117 bus_set_resource(child
, SYS_RES_IOPORT
,
118 0, iobase
, AHC_EISA_IOSIZE
);
121 bus_release_resource(parent
, SYS_RES_IOPORT
, rid
, regs
);
126 ahc_isa_probe(device_t dev
)
128 struct aic7770_identity
*entry
;
130 bus_space_handle_t bsh
;
131 struct resource
*regs
;
132 struct resource
*irq
;
145 /* Skip probes for ISA PnP devices */
146 if (isa_get_logicalid(dev
) != 0)
149 regs
= bus_alloc_resource_any(dev
, SYS_RES_IOPORT
, &zero
, RF_ACTIVE
);
151 device_printf(dev
, "No resources allocated.\n");
155 iobase
= rman_get_start(regs
);
156 tag
= rman_get_bustag(regs
);
157 bsh
= rman_get_bushandle(regs
);
159 entry
= ahc_isa_find_device(tag
, bsh
);
163 /* Pause the card preseving the IRQ type */
164 hcntrl
= bus_space_read_1(tag
, bsh
, HCNTRL
) & IRQMS
;
165 bus_space_write_1(tag
, bsh
, HCNTRL
, hcntrl
| PAUSE
);
166 while ((bus_space_read_1(tag
, bsh
, HCNTRL
) & PAUSE
) == 0)
169 /* Make sure we have a valid interrupt vector */
170 intdef
= bus_space_read_1(tag
, bsh
, INTDEF
);
171 irq_num
= intdef
& VECTOR
;
181 device_printf(dev
, "@0x%x: illegal irq setting %d\n",
186 if (bus_set_resource(dev
, SYS_RES_IRQ
, zero
, irq_num
, 1) != 0)
190 * The 284X only supports edge triggered interrupts,
191 * so do not claim RF_SHAREABLE.
193 irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &zero
,
194 0 /*!(RF_ACTIVE|RF_SHAREABLE)*/);
197 device_set_desc(dev
, entry
->name
);
199 device_printf(dev
, "@0x%x: irq %d allocation failed\n",
204 bus_release_resource(dev
, SYS_RES_IOPORT
, zero
, regs
);
209 bus_release_resource(dev
, SYS_RES_IRQ
, zero
, irq
);
217 ahc_isa_attach(device_t dev
)
219 struct aic7770_identity
*entry
;
221 bus_space_handle_t bsh
;
222 struct resource
*regs
;
223 struct ahc_softc
*ahc
;
229 regs
= bus_alloc_resource_any(dev
, SYS_RES_IOPORT
, &zero
, RF_ACTIVE
);
233 tag
= rman_get_bustag(regs
);
234 bsh
= rman_get_bushandle(regs
);
235 entry
= ahc_isa_find_device(tag
, bsh
);
236 bus_release_resource(dev
, SYS_RES_IOPORT
, zero
, regs
);
241 * Allocate a softc for this card and
242 * set it up for attachment by our
243 * common detect routine.
245 name
= kmalloc(strlen(device_get_nameunit(dev
)) + 1, M_DEVBUF
, M_INTWAIT
);
246 strcpy(name
, device_get_nameunit(dev
));
247 ahc
= ahc_alloc(dev
, name
);
251 ahc_set_unit(ahc
, device_get_unit(dev
));
253 /* Allocate a dmatag for our SCB DMA maps */
254 /* XXX Should be a child of the VLB/ISA bus dma tag */
255 error
= aic_dma_tag_create(ahc
, /*parent*/NULL
, /*alignment*/1,
257 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT
,
258 /*highaddr*/BUS_SPACE_MAXADDR
,
259 /*filter*/NULL
, /*filterarg*/NULL
,
260 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT
,
261 /*nsegments*/AHC_NSEG
,
262 /*maxsegsz*/AHC_MAXTRANSFER_SIZE
,
267 kprintf("ahc_isa_attach: Could not allocate DMA tag "
268 "- error %d\n", error
);
272 ahc
->dev_softc
= dev
;
273 error
= aic7770_config(ahc
, entry
, /*unused ioport arg*/0);
283 static device_method_t ahc_isa_device_methods
[] = {
284 /* Device interface */
285 DEVMETHOD(device_identify
, ahc_isa_identify
),
286 DEVMETHOD(device_probe
, ahc_isa_probe
),
287 DEVMETHOD(device_attach
, ahc_isa_attach
),
288 DEVMETHOD(device_detach
, ahc_detach
),
292 static driver_t ahc_isa_driver
= {
294 ahc_isa_device_methods
,
295 sizeof(struct ahc_softc
)
298 DRIVER_MODULE(ahc_isa
, isa
, ahc_isa_driver
, ahc_devclass
, 0, 0);
299 MODULE_DEPEND(ahc_isa
, ahc
, 1, 1, 1);
300 MODULE_VERSION(ahc_isa
, 1);