1 /* $OpenBSD: bha_pci.c,v 1.8 2007/04/10 17:47:55 miod Exp $ */
2 /* $NetBSD: bha_pci.c,v 1.16 1998/08/15 10:10:53 mycroft Exp $ */
3
4 /*-
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Charles M. Hannum.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/device.h>
44
45 #include <machine/bus.h>
46 #include <machine/intr.h>
47
48 #include <scsi/scsi_all.h>
49 #include <scsi/scsiconf.h>
50
51 #include <dev/pci/pcivar.h>
52 #include <dev/pci/pcidevs.h>
53
54 #include <dev/ic/bhareg.h>
55 #include <dev/ic/bhavar.h>
56
57 #define PCI_CBIO 0x10
58
59 int bha_pci_match(struct device *, void *, void *);
60 void bha_pci_attach(struct device *, struct device *, void *);
61
62 struct cfattach bha_pci_ca = {
63 sizeof(struct bha_softc), bha_pci_match, bha_pci_attach
64 };
65
66 const struct pci_matchid bha_pci_devices[] = {
67 { PCI_VENDOR_BUSLOGIC, PCI_PRODUCT_BUSLOGIC_MULTIMASTER_NC },
68 { PCI_VENDOR_BUSLOGIC, PCI_PRODUCT_BUSLOGIC_MULTIMASTER },
69 };
70
71 /*
72 * Check the slots looking for a board we recognise
73 * If we find one, note its address (slot) and call
74 * the actual probe routine to check it out.
75 */
76 int
77 bha_pci_match(parent, match, aux)
78 struct device *parent;
79 void *match, *aux;
80 {
81 struct pci_attach_args *pa = aux;
82 bus_space_tag_t iot;
83 bus_space_handle_t ioh;
84 bus_size_t iosize;
85 int rv;
86
87 if (pci_matchbyid(pa, bha_pci_devices,
88 sizeof(bha_pci_devices)/sizeof(bha_pci_devices[0])) == 0)
89 return (0);
90
91 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh,
92 NULL, &iosize, 0))
93 return (0);
94
95 rv = bha_find(iot, ioh, NULL);
96 bus_space_unmap(iot, ioh, iosize);
97
98 return (rv);
99 }
100
101 /*
102 * Attach all the sub-devices we can find
103 */
104 void
105 bha_pci_attach(parent, self, aux)
106 struct device *parent, *self;
107 void *aux;
108 {
109 struct pci_attach_args *pa = aux;
110 struct bha_softc *sc = (void *)self;
111 bus_space_tag_t iot;
112 bus_space_handle_t ioh;
113 bus_size_t iosize;
114 struct bha_probe_data bpd;
115 pci_chipset_tag_t pc = pa->pa_pc;
116 pci_intr_handle_t ih;
117 const char *model, *intrstr;
118
119 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BUSLOGIC_MULTIMASTER_NC)
120 model = "BusLogic 9xxC SCSI";
121 else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BUSLOGIC_MULTIMASTER)
122 model = "BusLogic 9xxC SCSI";
123 else
124 model = "unknown model!";
125
126 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh,
127 NULL, &iosize, 0)) {
128 printf(": unable to map I/O space\n");
129 return;
130 }
131
132 sc->sc_iot = iot;
133 sc->sc_ioh = ioh;
134 sc->sc_dmat = pa->pa_dmat;
135 if (!bha_find(iot, ioh, &bpd)) {
136 printf(": bha_find failed\n");
137 bus_space_unmap(iot, ioh, iosize);
138 return;
139 }
140
141 sc->sc_dmaflags = 0;
142
143 if (pci_intr_map(pa, &ih)) {
144 printf(": couldn't map interrupt\n");
145 bus_space_unmap(iot, ioh, iosize);
146 return;
147 }
148 intrstr = pci_intr_string(pc, ih);
149 sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, bha_intr, sc,
150 sc->sc_dev.dv_xname);
151 if (sc->sc_ih == NULL) {
152 printf(": couldn't establish interrupt");
153 if (intrstr != NULL)
154 printf(" at %s", intrstr);
155 printf("\n");
156 bus_space_unmap(iot, ioh, iosize);
157 return;
158 }
159 printf(": %s, %s\n", intrstr, model);
160
161 bha_attach(sc, &bpd);
162
163 bha_disable_isacompat(sc);
164 }