2 * Device probe and attach routines for the following
3 * Advanced Systems Inc. SCSI controllers:
5 * Connectivity Products:
6 * ABP510/5150 - Bus-Master ISA (240 CDB) *
7 * ABP5140 - Bus-Master ISA PnP (16 CDB) * **
8 * ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) ***
10 * Single Channel Products:
11 * ABP542 - Bus-Master ISA with floppy (240 CDB)
12 * ABP842 - Bus-Master VL (240 CDB)
14 * Dual Channel Products:
15 * ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
17 * * This board has been shipped by HP with the 4020i CD-R drive.
18 * The board has no BIOS so it cannot control a boot device, but
19 * it can control any secondary SCSI device.
20 * ** This board has been sold by SIIG as the i540 SpeedMaster.
21 * *** This board has been sold by SIIG as the i542 SpeedMaster.
23 * Copyright (c) 1996, 1997 Justin T. Gibbs.
24 * All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions, and the following disclaimer,
31 * without modification, immediately at the beginning of the file.
32 * 2. The name of the author may not be used to endorse or promote products
33 * derived from this software without specific prior written permission.
35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
39 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * $FreeBSD: src/sys/dev/advansys/adv_isa.c,v 1.14.2.5 2002/01/06 21:21:42 dwmalone Exp $
48 * $DragonFly: src/sys/dev/disk/advansys/adv_isa.c,v 1.7 2006/12/22 23:26:15 swildner Exp $
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
57 #include <bus/isa/isavar.h>
61 #include <bus/cam/scsi/scsi_all.h>
63 #define ADV_ISA_MAX_DMA_ADDR (0x00FFFFFFL)
64 #define ADV_ISA_MAX_DMA_COUNT (0x00FFFFFFL)
66 #define ADV_VL_MAX_DMA_ADDR (0x07FFFFFFL)
67 #define ADV_VL_MAX_DMA_COUNT (0x07FFFFFFL)
70 * The overrun buffer shared amongst all ISA/VL adapters.
72 static u_int8_t
* overrun_buf
;
73 static bus_dma_tag_t overrun_dmat
;
74 static bus_dmamap_t overrun_dmamap
;
75 static bus_addr_t overrun_physbase
;
77 /* Possible port addresses an ISA or VL adapter can live at */
78 static u_int16_t adv_isa_ioports
[] =
81 0x110, /* First selection in BIOS setup */
83 0x130, /* Second selection in BIOS setup */
85 0x150, /* Third selection in BIOS setup */
86 0x190, /* Fourth selection in BIOS setup */
87 0x210, /* Fifth selection in BIOS setup */
88 0x230, /* Sixth selection in BIOS setup */
89 0x250, /* Seventh selection in BIOS setup */
90 0x330 /* Eighth and default selection in BIOS setup */
93 #define MAX_ISA_IOPORT_INDEX (sizeof(adv_isa_ioports)/sizeof(u_int16_t) - 1)
95 static int adv_isa_probe(device_t dev
);
96 static int adv_isa_attach(device_t dev
);
97 static void adv_set_isapnp_wait_for_key(void);
98 static int adv_get_isa_dma_channel(struct adv_softc
*adv
);
99 static int adv_set_isa_dma_settings(struct adv_softc
*adv
);
102 adv_isa_probe(device_t dev
)
106 u_long iobase
, iocount
, irq
;
110 struct resource
*iores
, *irqres
;
113 * Default to scanning all possible device locations.
116 max_port_index
= MAX_ISA_IOPORT_INDEX
;
118 if (bus_get_resource(dev
, SYS_RES_IOPORT
, 0, &iobase
, &iocount
) == 0) {
120 for (;port_index
<= max_port_index
; port_index
++)
121 if (iobase
<= adv_isa_ioports
[port_index
])
123 if ((port_index
> max_port_index
)
124 || (iobase
!= adv_isa_ioports
[port_index
])) {
126 kprintf("adv%d: Invalid baseport of 0x%lx specified. "
127 "Nearest valid baseport is 0x%x. Failing "
128 "probe.\n", device_get_unit(dev
), iobase
,
129 (port_index
<= max_port_index
) ?
130 adv_isa_ioports
[port_index
] :
131 adv_isa_ioports
[max_port_index
]);
134 max_port_index
= port_index
;
137 /* Perform the actual probing */
138 adv_set_isapnp_wait_for_key();
139 for (;port_index
<= max_port_index
; port_index
++) {
140 u_int16_t port_addr
= adv_isa_ioports
[port_index
];
145 struct adv_softc
*adv
;
148 /* Already been attached */
151 if (bus_set_resource(dev
, SYS_RES_IOPORT
, 0, port_addr
, 1))
154 /* XXX what is the real portsize? */
155 iores
= bus_alloc_resource(dev
, SYS_RES_IOPORT
, &rid
, 0, ~0, 1,
160 if (adv_find_signature(rman_get_bustag(iores
),
161 rman_get_bushandle(iores
)) == 0) {
162 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, iores
);
167 * Got one. Now allocate our softc
168 * and see if we can initialize the card.
170 adv
= adv_alloc(dev
, rman_get_bustag(iores
),
171 rman_get_bushandle(iores
));
173 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, iores
);
180 ADV_OUTB(adv
, ADV_CHIP_CTRL
, ADV_CC_HALT
);
181 ADV_OUTW(adv
, ADV_CHIP_STATUS
, 0);
183 * Determine the chip version.
185 adv
->chip_version
= ADV_INB(adv
, ADV_NONEISA_CHIP_REVISION
);
186 if ((adv
->chip_version
>= ADV_CHIP_MIN_VER_VL
)
187 && (adv
->chip_version
<= ADV_CHIP_MAX_VER_VL
)) {
189 maxsegsz
= ADV_VL_MAX_DMA_COUNT
;
190 maxsize
= BUS_SPACE_MAXSIZE_32BIT
;
191 lowaddr
= ADV_VL_MAX_DMA_ADDR
;
192 bus_delete_resource(dev
, SYS_RES_DRQ
, 0);
193 } else if ((adv
->chip_version
>= ADV_CHIP_MIN_VER_ISA
)
194 && (adv
->chip_version
<= ADV_CHIP_MAX_VER_ISA
)) {
195 if (adv
->chip_version
>= ADV_CHIP_MIN_VER_ISA_PNP
) {
196 adv
->type
= ADV_ISAPNP
;
197 ADV_OUTB(adv
, ADV_REG_IFC
,
198 ADV_IFC_INIT_DEFAULT
);
202 maxsegsz
= ADV_ISA_MAX_DMA_COUNT
;
203 maxsize
= BUS_SPACE_MAXSIZE_24BIT
;
204 lowaddr
= ADV_ISA_MAX_DMA_ADDR
;
205 adv
->isa_dma_speed
= ADV_DEF_ISA_DMA_SPEED
;
206 adv
->isa_dma_channel
= adv_get_isa_dma_channel(adv
);
207 bus_set_resource(dev
, SYS_RES_DRQ
, 0,
208 adv
->isa_dma_channel
, 1);
210 panic("advisaprobe: Unknown card revision\n");
214 * Allocate a parent dmatag for all tags created
215 * by the MI portions of the advansys driver
217 /* XXX Should be a child of the ISA bus dma tag */
218 error
= bus_dma_tag_create(/*parent*/NULL
,
222 /*highaddr*/BUS_SPACE_MAXADDR
,
226 /*nsegs*/BUS_SPACE_UNRESTRICTED
,
232 kprintf("%s: Could not allocate DMA tag - error %d\n",
233 adv_name(adv
), error
);
235 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, iores
);
239 adv
->init_level
+= 2;
241 if (overrun_buf
== NULL
) {
242 /* Need to allocate our overrun buffer */
243 if (bus_dma_tag_create(adv
->parent_dmat
,
246 ADV_ISA_MAX_DMA_ADDR
,
252 BUS_SPACE_MAXSIZE_32BIT
,
254 &overrun_dmat
) != 0) {
256 bus_release_resource(dev
, SYS_RES_IOPORT
, 0,
260 if (bus_dmamem_alloc(overrun_dmat
,
261 (void **)&overrun_buf
,
263 &overrun_dmamap
) != 0) {
264 bus_dma_tag_destroy(overrun_dmat
);
266 bus_release_resource(dev
, SYS_RES_IOPORT
, 0,
270 /* And permanently map it in */
271 bus_dmamap_load(overrun_dmat
, overrun_dmamap
,
272 overrun_buf
, ADV_OVERRUN_BSIZE
,
273 adv_map
, &overrun_physbase
,
277 adv
->overrun_physbase
= overrun_physbase
;
279 if (adv_init(adv
) != 0) {
280 bus_dmamap_unload(overrun_dmat
, overrun_dmamap
);
281 bus_dmamem_free(overrun_dmat
, overrun_buf
,
283 bus_dma_tag_destroy(overrun_dmat
);
285 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, iores
);
291 if (adv
->chip_version
== ADV_CHIP_VER_ASYN_BUG
) {
293 |= ADV_BUG_FIX_ASYN_USE_SYN
;
294 adv
->fix_asyn_xfer
= ~0;
298 adv
->max_dma_count
= ADV_ISA_MAX_DMA_COUNT
;
299 adv
->max_dma_addr
= ADV_ISA_MAX_DMA_ADDR
;
300 adv_set_isa_dma_settings(adv
);
304 adv
->max_dma_count
= ADV_VL_MAX_DMA_COUNT
;
305 adv
->max_dma_addr
= ADV_VL_MAX_DMA_ADDR
;
308 panic("advisaprobe: Invalid card type\n");
311 /* Determine our IRQ */
312 if (bus_get_resource(dev
, SYS_RES_IRQ
, 0, &irq
, NULL
))
313 bus_set_resource(dev
, SYS_RES_IRQ
, 0,
314 adv_get_chip_irq(adv
), 1);
316 adv_set_chip_irq(adv
, irq
);
318 irqres
= bus_alloc_resource(dev
, SYS_RES_IRQ
, &rid
, 0, ~0, 1,
320 if (irqres
== NULL
||
321 bus_setup_intr(dev
, irqres
, 0, adv_intr
, adv
,
323 bus_dmamap_unload(overrun_dmat
, overrun_dmamap
);
324 bus_dmamem_free(overrun_dmat
, overrun_buf
,
326 bus_dma_tag_destroy(overrun_dmat
);
328 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, iores
);
333 adv_isa_ioports
[port_index
] = 0;
338 bus_set_resource(dev
, SYS_RES_IOPORT
, 0, iobase
, iocount
);
340 bus_delete_resource(dev
, SYS_RES_IOPORT
, 0);
346 adv_isa_attach(device_t dev
)
348 struct adv_softc
*adv
= device_get_softc(dev
);
350 return (adv_attach(adv
));
354 adv_get_isa_dma_channel(struct adv_softc
*adv
)
358 channel
= ADV_INW(adv
, ADV_CONFIG_LSW
) & ADV_CFG_LSW_ISA_DMA_CHANNEL
;
361 else if (channel
== 0x00)
363 return (channel
+ 4);
367 adv_set_isa_dma_settings(struct adv_softc
*adv
)
372 if ((adv
->isa_dma_channel
>= 5) && (adv
->isa_dma_channel
<= 7)) {
373 if (adv
->isa_dma_channel
== 7)
376 value
= adv
->isa_dma_channel
- 4;
377 cfg_lsw
= ADV_INW(adv
, ADV_CONFIG_LSW
)
378 & ~ADV_CFG_LSW_ISA_DMA_CHANNEL
;
380 ADV_OUTW(adv
, ADV_CONFIG_LSW
, cfg_lsw
);
382 adv
->isa_dma_speed
&= 0x07;
383 adv_set_bank(adv
, 1);
384 ADV_OUTB(adv
, ADV_DMA_SPEED
, adv
->isa_dma_speed
);
385 adv_set_bank(adv
, 0);
386 isa_dmacascade(adv
->isa_dma_channel
);
392 adv_set_isapnp_wait_for_key(void)
394 static int isapnp_wait_set
= 0;
395 if (isapnp_wait_set
== 0) {
396 outb(ADV_ISA_PNP_PORT_ADDR
, 0x02);
397 outb(ADV_ISA_PNP_PORT_WRITE
, 0x02);
402 static device_method_t adv_isa_methods
[] = {
403 /* Device interface */
404 DEVMETHOD(device_probe
, adv_isa_probe
),
405 DEVMETHOD(device_attach
, adv_isa_attach
),
409 static driver_t adv_isa_driver
= {
410 "adv", adv_isa_methods
, sizeof(struct adv_softc
)
413 static devclass_t adv_isa_devclass
;
414 DRIVER_MODULE(adv
, isa
, adv_isa_driver
, adv_isa_devclass
, 0, 0);