1 /* $NetBSD: ahc_eisa.c,v 1.37 2009/05/05 09:51:23 cegger Exp $ */
4 * Product specific probe and attach routines for:
5 * 274X and aic7770 motherboard SCSI controllers
7 * Copyright (c) 1994, 1995, 1996, 1997, 1998 Justin T. Gibbs.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice immediately at the beginning of the file, without modification,
15 * this list of conditions, and the following disclaimer.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * $FreeBSD: src/sys/dev/aic7xxx/ahc_eisa.c,v 1.15 2000/01/29 14:22:19 peter Exp $
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: ahc_eisa.c,v 1.37 2009/05/05 09:51:23 cegger Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/device.h>
41 #include <sys/reboot.h>
46 #include <dev/scsipi/scsi_all.h>
47 #include <dev/scsipi/scsipi_all.h>
48 #include <dev/scsipi/scsiconf.h>
50 #include <dev/eisa/eisareg.h>
51 #include <dev/eisa/eisavar.h>
52 #include <dev/eisa/eisadevs.h>
54 #include <dev/ic/aic7xxx_osm.h>
55 #include <dev/ic/aic7xxx_inline.h>
56 #include <dev/ic/aic77xxreg.h>
57 #include <dev/ic/aic77xxvar.h>
59 static int ahc_eisa_match(device_t
, cfdata_t
, void *);
60 static void ahc_eisa_attach(device_t
, device_t
, void *);
63 CFATTACH_DECL_NEW(ahc_eisa
, sizeof(struct ahc_softc
),
64 ahc_eisa_match
, ahc_eisa_attach
, NULL
, NULL
);
67 * Check the slots looking for a board we recognise
68 * If we find one, note it's address (slot) and call
69 * the actual probe routine to check it out.
72 ahc_eisa_match(device_t parent
, cfdata_t match
, void *aux
)
74 struct eisa_attach_args
*ea
= aux
;
75 bus_space_tag_t iot
= ea
->ea_iot
;
76 bus_space_handle_t ioh
;
79 /* must match one of our known ID strings */
80 if (strcmp(ea
->ea_idstring
, "ADP7770") &&
81 strcmp(ea
->ea_idstring
, "ADP7771"))
84 if (bus_space_map(iot
, EISA_SLOT_ADDR(ea
->ea_slot
) +
85 AHC_EISA_SLOT_OFFSET
, AHC_EISA_IOSIZE
, 0, &ioh
))
88 irq
= ahc_aic77xx_irq(iot
, ioh
);
90 bus_space_unmap(iot
, ioh
, AHC_EISA_IOSIZE
);
96 ahc_eisa_attach(device_t parent
, device_t self
, void *aux
)
98 struct ahc_softc
*ahc
= device_private(self
);
99 struct eisa_attach_args
*ea
= aux
;
100 eisa_chipset_tag_t ec
= ea
->ea_ec
;
101 eisa_intr_handle_t ih
;
102 bus_space_tag_t iot
= ea
->ea_iot
;
103 bus_space_handle_t ioh
;
105 const char *intrstr
, *intrtypestr
;
116 if (bus_space_map(iot
, EISA_SLOT_ADDR(ea
->ea_slot
) +
117 AHC_EISA_SLOT_OFFSET
, AHC_EISA_IOSIZE
, 0, &ioh
)) {
118 aprint_error_dev(ahc
->sc_dev
, "could not map I/O addresses");
121 if ((irq
= ahc_aic77xx_irq(iot
, ioh
)) < 0) {
122 aprint_error_dev(ahc
->sc_dev
, "ahc_aic77xx_irq failed!");
126 if (strcmp(ea
->ea_idstring
, "ADP7770") == 0) {
127 printf(": %s\n", EISA_PRODUCT_ADP7770
);
128 } else if (strcmp(ea
->ea_idstring
, "ADP7771") == 0) {
129 printf(": %s\n", EISA_PRODUCT_ADP7771
);
131 printf(": Unknown device type %s", ea
->ea_idstring
);
135 ahc_set_name(ahc
, device_xname(ahc
->sc_dev
));
136 ahc
->parent_dmat
= ea
->ea_dmat
;
137 ahc
->chip
= AHC_AIC7770
|AHC_EISA
;
138 ahc
->features
= AHC_AIC7770_FE
;
139 ahc
->flags
= AHC_PAGESCBS
;
140 ahc
->bugs
= AHC_TMODE_WIDEODD_BUG
;
145 if (ahc_softc_init(ahc
) != 0)
148 ahc_intr_enable(ahc
, FALSE
);
150 if (ahc_reset(ahc
) != 0)
153 if (eisa_intr_map(ec
, irq
, &ih
)) {
154 aprint_error_dev(ahc
->sc_dev
, "couldn't map interrupt (%d)\n",
159 intdef
= bus_space_read_1(iot
, ioh
, INTDEF
);
161 if (intdef
& EDGE_TRIG
) {
163 intrtypestr
= "edge triggered";
165 intrtype
= IST_LEVEL
;
166 intrtypestr
= "level sensitive";
168 intrstr
= eisa_intr_string(ec
, ih
);
169 ahc
->ih
= eisa_intr_establish(ec
, ih
,
170 intrtype
, IPL_BIO
, ahc_intr
, ahc
);
171 if (ahc
->ih
== NULL
) {
172 aprint_error_dev(ahc
->sc_dev
, "couldn't establish %s interrupt",
175 aprint_error(" at %s", intrstr
);
180 aprint_normal_dev(ahc
->sc_dev
, "%s interrupting at %s\n",
181 intrtypestr
, intrstr
);
184 * Now that we know we own the resources we need, do the
185 * card initialization.
187 * First, the aic7770 card specific setup.
189 biosctrl
= ahc_inb(ahc
, HA_274_BIOSCTRL
);
190 scsiconf
= ahc_inb(ahc
, SCSICONF
);
191 scsiconf1
= ahc_inb(ahc
, SCSICONF
+ 1);
194 for (i
= TARG_SCSIRATE
; i
<= HA_274_BIOSCTRL
; i
+=8) {
195 printf("0x%x, 0x%x, 0x%x, 0x%x, "
196 "0x%x, 0x%x, 0x%x, 0x%x\n",
208 /* Get the primary channel information */
209 if ((biosctrl
& CHANNEL_B_PRIMARY
) != 0)
210 ahc
->flags
|= AHC_PRIMARY_CHANNEL
;
212 if ((biosctrl
& BIOSMODE
) == BIOSDISABLED
) {
213 ahc
->flags
|= AHC_USEDEFAULTS
;
214 } else if ((ahc
->features
& AHC_WIDE
) != 0) {
215 ahc
->our_id
= scsiconf1
& HWSCSIID
;
216 if (scsiconf
& TERM_ENB
)
217 ahc
->flags
|= AHC_TERM_ENB_A
;
219 ahc
->our_id
= scsiconf
& HSCSIID
;
220 ahc
->our_id_b
= scsiconf1
& HSCSIID
;
221 if (scsiconf
& TERM_ENB
)
222 ahc
->flags
|= AHC_TERM_ENB_A
;
223 if (scsiconf1
& TERM_ENB
)
224 ahc
->flags
|= AHC_TERM_ENB_B
;
226 if ((ahc_inb(ahc
, HA_274_BIOSGLOBAL
) & HA_274_EXTENDED_TRANS
))
227 ahc
->flags
|= AHC_EXTENDED_TRANS_A
|AHC_EXTENDED_TRANS_B
;
229 /* Attach sub-devices */
230 if (ahc_aic77xx_attach(ahc
) == 0)
231 return; /* succeed */
234 eisa_intr_disestablish(ec
, ahc
->ih
);
236 bus_space_unmap(iot
, ioh
, AHC_EISA_IOSIZE
);