1 /* $NetBSD: adv_isa.c,v 1.18 2009/05/12 09:10:15 cegger Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
6 * Author: Baldassare Dante Profeta <dante@mclink.it>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
30 * Device probe and attach routines for the following
31 * Advanced Systems Inc. SCSI controllers:
33 * Connectivity Products:
34 * ABP510/5150 - Bus-Master ISA (240 CDB) (Footnote 1)
35 * ABP5140 - Bus-Master ISA (16 CDB) (Footnote 1) (Footnote 2)
36 * ABP5142 - Bus-Master ISA with floppy (16 CDB) (Footnote 3)
38 * Single Channel Products:
39 * ABP542 - Bus-Master ISA with floppy (240 CDB)
40 * ABP842 - Bus-Master VL (240 CDB)
42 * Dual Channel Products:
43 * ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
46 * 1. This board has been shipped by HP with the 4020i CD-R drive.
47 * The board has no BIOS so it cannot control a boot device, but
48 * it can control any secondary SCSI device.
49 * 2. This board has been sold by SIIG as the i540 SpeedMaster.
50 * 3. This board has been sold by SIIG as the i542 SpeedMaster.
53 #include <sys/cdefs.h>
54 __KERNEL_RCSID(0, "$NetBSD: adv_isa.c,v 1.18 2009/05/12 09:10:15 cegger Exp $");
56 #include <sys/param.h>
57 #include <sys/systm.h>
58 #include <sys/kernel.h>
59 #include <sys/errno.h>
60 #include <sys/ioctl.h>
61 #include <sys/device.h>
64 #include <sys/queue.h>
68 #include <dev/scsipi/scsi_all.h>
69 #include <dev/scsipi/scsipi_all.h>
70 #include <dev/scsipi/scsiconf.h>
72 #include <dev/isa/isavar.h>
74 #include <dev/ic/advlib.h>
75 #include <dev/ic/adv.h>
78 /* Possible port addresses an ISA or VL adapter can live at */
79 static int asc_ioport
[ASC_IOADR_TABLE_MAX_IX
] =
82 ASC_IOADR_1
, /* First selection in BIOS setup */
84 ASC_IOADR_2
, /* Second selection in BIOS setup */
86 ASC_IOADR_3
, /* Third selection in BIOS setup */
87 ASC_IOADR_4
, /* Fourth selection in BIOS setup */
88 ASC_IOADR_5
, /* Fifth selection in BIOS setup */
89 ASC_IOADR_6
, /* Sixth selection in BIOS setup */
90 ASC_IOADR_7
, /* Seventh selection in BIOS setup */
91 ASC_IOADR_8
/* Eighth and default selection in BIOS setup */
94 /******************************************************************************/
96 int adv_isa_probe(device_t
, cfdata_t
, void *);
97 void adv_isa_attach(device_t
, device_t
, void *);
99 CFATTACH_DECL(adv_isa
, sizeof(ASC_SOFTC
),
100 adv_isa_probe
, adv_isa_attach
, NULL
, NULL
);
102 /******************************************************************************/
105 adv_isa_probe(device_t parent
, cfdata_t match
, void *aux
)
107 struct isa_attach_args
*ia
= aux
;
108 bus_space_tag_t iot
= ia
->ia_iot
;
109 bus_space_handle_t ioh
;
111 int iobase
, irq
, drq
;
121 if (ISA_DIRECT_CONFIG(ia
))
125 * If the I/O address is wildcarded, look for boards
126 * in ascending order.
128 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
) {
129 for (port_index
= 0; port_index
< ASC_IOADR_TABLE_MAX_IX
;
131 iobase
= asc_ioport
[port_index
];
134 if (bus_space_map(iot
, iobase
, ASC_IOADR_GAP
,
138 rv
= AscFindSignature(iot
, ioh
);
141 ia
->ia_io
[0].ir_addr
= iobase
;
145 bus_space_unmap(iot
, ioh
, ASC_IOADR_GAP
);
151 iobase
= ia
->ia_io
[0].ir_addr
;
152 if (bus_space_map(iot
, iobase
, ASC_IOADR_GAP
, 0, &ioh
))
155 rv
= AscFindSignature(iot
, ioh
);
158 bus_space_unmap(iot
, ioh
, ASC_IOADR_GAP
);
163 /* XXXJRT Probe routines should not have side-effects!! */
164 ASC_SET_CHIP_CONTROL(iot
, ioh
, ASC_CC_HALT
);
165 ASC_SET_CHIP_STATUS(iot
, ioh
, 0);
167 irq
= AscGetChipIRQ(iot
, ioh
, ASC_IS_ISA
);
168 drq
= AscGetIsaDmaChannel(iot
, ioh
);
170 /* Verify that the IRQ/DRQ match (or are wildcarded). */
171 if (ia
->ia_irq
[0].ir_irq
!= ISA_UNKNOWN_IRQ
&&
172 ia
->ia_irq
[0].ir_irq
!= irq
) {
176 if (ia
->ia_drq
[0].ir_drq
!= ISA_UNKNOWN_DRQ
&&
177 ia
->ia_drq
[0].ir_drq
!= drq
) {
183 ia
->ia_io
[0].ir_addr
= iobase
;
184 ia
->ia_io
[0].ir_size
= ASC_IOADR_GAP
;
187 ia
->ia_irq
[0].ir_irq
= irq
;
190 ia
->ia_drq
[0].ir_drq
= drq
;
195 bus_space_unmap(iot
, ioh
, ASC_IOADR_GAP
);
201 adv_isa_attach(device_t parent
, device_t self
, void *aux
)
203 struct isa_attach_args
*ia
= aux
;
204 ASC_SOFTC
*sc
= (void *) self
;
205 bus_space_tag_t iot
= ia
->ia_iot
;
206 bus_space_handle_t ioh
;
207 isa_chipset_tag_t ic
= ia
->ia_ic
;
214 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
, ASC_IOADR_GAP
, 0, &ioh
)) {
215 aprint_error_dev(&sc
->sc_dev
, "can't map i/o space\n");
221 sc
->sc_dmat
= ia
->ia_dmat
;
222 sc
->bus_type
= ASC_IS_ISA
;
223 sc
->chip_version
= ASC_GET_CHIP_VER_NO(iot
, ioh
);
227 * sc->chip_version = (ASC_CHIP_MIN_VER_EISA - 1) + ea->ea_pid[1];
231 * Initialize the board
234 aprint_error_dev(&sc
->sc_dev
, "adv_init failed\n");
238 if ((error
= isa_dmacascade(ic
, ia
->ia_drq
[0].ir_drq
)) != 0) {
239 aprint_error_dev(&sc
->sc_dev
, "unable to cascade DRQ, error = %d\n", error
);
243 sc
->sc_ih
= isa_intr_establish(ic
, ia
->ia_irq
[0].ir_irq
, IST_EDGE
,
244 IPL_BIO
, adv_intr
, sc
);
245 if (sc
->sc_ih
== NULL
) {
246 aprint_error_dev(&sc
->sc_dev
, "couldn't establish interrupt\n");